X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=jitcx86.c;h=d4f8e4a160bad45bd7e4eee338fce232f4b05a77;hb=c7fbdf64e053179a13205f7c607ae113a83648eb;hp=1c9c77425a07f15af9c50566f3ad810433055a84;hpb=2e0345718c2ca229802f1ab71bce94e41f79e889;p=heavyosecpu%2FHeavyOSECPU.git diff --git a/jitcx86.c b/jitcx86.c index 1c9c774..d4f8e4a 100644 --- a/jitcx86.c +++ b/jitcx86.c @@ -6,264 +6,6 @@ // for x86-32bit // -void jitCompPutImm32(struct JitCompWork *w, int i) -{ - jitCompPutByte1(w->dst, i & 0xff); - jitCompPutByte1(w->dst, (i >> 8) & 0xff); - jitCompPutByte1(w->dst, (i >> 16) & 0xff); - jitCompPutByte1(w->dst, (i >> 24) & 0xff); - return; -} - -int jitCompGetImm32(const unsigned char *src) -{ - return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; -} - -int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src) -{ - int i = jitCompGetImm32(src); - if (i < 0 || i >= w->maxLabels) { - w->err = JITC_ERR_LABELNUM; - i = 0; - } - return i; -} - -void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n) -{ - disp -= jitCompA0001_EBP128; - if (-128 <= disp && disp <= 127) { - jitCompPutByte2(w->dst, 0x45 | (n << 3), disp & 0xff); - } else { - jitCompPutByte1(w->dst, 0x85 | (n << 3)); - jitCompPutImm32(w, disp); - } - return; -} - -void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32) -{ - jitCompPutByte1(w->dst, 0x89); /* MOV(mem, reg32); */ - jitCompA0001_85DispN(w, disp, reg32); - return; -} - -void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp) -{ - jitCompPutByte1(w->dst, 0x8b); /* MOV(reg32, mem); */ - jitCompA0001_85DispN(w, disp, reg32); - return; -} - -void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx) -{ -#if (jitCompA0001_USE_R3F_IMM32 != 0) - if (rxx == 0x3f) { - jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(w, w->r3f); - return; - } -#endif - if (rxx >= 0x40 || rxx < 0){ - w->err = JITC_ERR_REGNUM; - } - jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, rxx * 4); /* MOV(EAX, [EBP+?]); */ - return; -} - -void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx) -{ - if (rxx >= 0x40 || rxx < 0){ - w->err = JITC_ERR_REGNUM; - } - jitCompA0001_movEbpDispReg32(w, rxx * 4, 0 /* EAX */); /* MOV([EBP+?], EAX); */ - return; -} - -void jitCompA0001_fixPrefix(struct JitCompWork *w) -{ - if (w->prefix != 0) { - if (w->dst - w->dst0 > 127){ - w->err = JITC_ERR_REGNUM; - } - w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff); - } - return; -} - -void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1) -{ - if (p0 >= 0x3f || p0 < 0){ - w->err = JITC_ERR_PREGNUM; - } - if (p1 >= 0x3f || p1 < 0){ - w->err = JITC_ERR_PREGNUM; - } - /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */ - return; -} - -void jitCompA000_loadRegCacheAll(struct JitCompWork *w) -{ - jitCompA0001_movReg32EbpDisp(w, 3 /* EBX */, 0 * 4); /* EBX = R00; */ - jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */ - jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */ - return; -} - -void jitCompA000_storeRegCacheAll(struct JitCompWork *w) -{ - jitCompA0001_movEbpDispReg32(w, 0 * 4, 3 /* EBX */); /* R00 = EBX; */ - jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */ - jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */ - return; -} - -void jitCompA000_loadRegCacheEcx(struct JitCompWork *w) -{ - jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */ - return; -} - -void jitCompA000_storeRegCacheEcx(struct JitCompWork *w) -{ - jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */ - return; -} - -void jitCompA000_loadRegCacheEdx(struct JitCompWork *w) -{ - jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */ - return; -} - -void jitCompA000_storeRegCacheEdx(struct JitCompWork *w) -{ - jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */ - return; -} - -int jitCompA000_selectRegCache(int rxx, int reg) -{ - switch (rxx) { - case 0: - //EBX - reg = 3; - break; - case 1: - //ECX - reg = 1; - break; - case 2: - //EDX - reg = 2; - break; - } - return reg; -} - -void jitCompA000_loadPRegCacheAll(struct JitCompWork *w) -{ - // jitCompA0001_movReg32EbpDisp(w, 5 /* EBP */, 256 + 0 * 32 + 0); /* EBP = P00; */ - jitCompA0001_movReg32EbpDisp(w, 6 /* ESI */, 256 + 1 * 32 + 0); /* ESI = P01; */ - jitCompA0001_movReg32EbpDisp(w, 7 /* EDI */, 256 + 2 * 32 + 0); /* EDI = P02; */ - return; -} - -void jitCompA000_storePRegCacheAll(struct JitCompWork *w) -{ - // jitCompA0001_movEbpDispReg32(w, 256 + 0 * 32 + 0, 5 /* EBP */); /* P00 = EBP; */ - jitCompA0001_movEbpDispReg32(w, 256 + 1 * 32 + 0, 6 /* ESI */); /* P01 = ESI; */ - jitCompA0001_movEbpDispReg32(w, 256 + 2 * 32 + 0, 7 /* EDI */); /* P02 = EDI; */ - return; -} - -int jitCompA000_selectPRegCache(int pxx, int reg) -{ - // if (pxx == 0) reg = 5; /* EBP */ - switch (pxx) { - case 1: - //ESI - reg = 6; - break; - - case 2: - //EDI - reg = 7; - break; - } - return reg; -} - -int jitCompA000_convTyp(int t) -{ - int r = -1; - - if (1 <= t && t <= 7){ - r = t; - } else if (8 <= t && t <= 13){ - r = 2 | (t & 1); - } else if (14 <= t && t <= 15){ - r = 4 | (t & 1); - } else if (16 <= t && t <= 21){ - r = 6 | (t & 1); - } - return r; -} - -int jitCompA000_dataWidth(int t) -{ - int r = -1; - if (t == 0x0001) r = 256; - t >>= 1; - if (t == 0x0002 / 2) r = 8; - if (t == 0x0004 / 2) r = 16; - if (t == 0x0006 / 2) r = 32; - if (t == 0x0008 / 2) r = 4; - if (t == 0x000a / 2) r = 2; - if (t == 0x000c / 2) r = 1; - if (t == 0x000e / 2) r = 12; - if (t == 0x0010 / 2) r = 20; - if (t == 0x0012 / 2) r = 24; - if (t == 0x0014 / 2) r = 28; - return r; -} - -static unsigned char *errfnc; - -void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac) -{ - if (typ <= 0) { w->err = JITC_ERR_BADTYPE; } - if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; } - jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, 256 + pxx * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ - jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */ - jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */ - jitCompPutImm32(w, errfnc - (w->dst + 4)); - return; -} - -void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac) -// data用. -// 将来的にはaliveやアクセス権チェックも入れる -{ - jitCompA0001_checkType0(w, pxx, typ, ac); - return; -} - -void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx) -{ - jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ - jitCompA0001_85DispN(w, 256 + pxx * 32 + 8, reg); /* p0 */ - jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */ - jitCompPutImm32(w, errfnc - (w->dst + 4)); - jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ - jitCompA0001_85DispN(w, 256 + pxx * 32 + 12, reg); /* p1 */ - jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */ - jitCompPutImm32(w, errfnc - (w->dst + 4)); - return; -} - // F5の場合、decoderが対応するalloc-freeを結びつけるのが簡単で、typやlenを指定必須にしてもフロントエンドコードに影響はない. int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *src, const unsigned char *src1, const unsigned char *src0, HOSECPU_LabelListTag *label, int maxLabels, int level, int debugInfo1, int flags) { @@ -281,96 +23,130 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr const unsigned char *oldsrc; int timecount = 0, i, j = 0, lastlabel = -1, debugInfo0 = -1; int reg0, reg1, reg2, cmp0reg = -1, cmp0lev = 0; + w.dst = w.dst0 = dst; w.err = 0; w.maxLabels = maxLabels; if ((flags & JITC_NOSTARTUP) == 0) { - jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */ - jitCompA000_loadRegCacheAll(&w); /* start-up */ + jitCompPutOp_PUSHAD(w.dst); + // Load cache + jitCompA000_loadRegCacheAll(&w); jitCompA000_loadPRegCacheAll(&w); } if (level <= JITC_LV_SLOWER) { - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */ - jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */ - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, debugInfo1); - jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ + // env.debugInfo0 <- 0; + // env.debugInfo1 <- debugInfo1; + jitCompPutOp_MOV_EAX_ZERO(w.dst); + jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO0, IA32_REG0_EAX); + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1); + jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX); } while (src < src1) { w.prefix = 0; //0x04 CND 命令で変更される - if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; goto err_w; } // 書き込み領域が残り256バイト未満ならエラー + if (w.dst + 256 > dst1) { + // 書き込み領域が残り256バイト未満ならエラー + w.err = JITC_ERR_DST1; + goto err_w; + } timecount++; if (timecount >= 64) { timecount -= 64; /* 未完成(timeoutチェックコードを入れる) */ } - prefix_continue: // CND命令実行後ここに戻る + if(*src != 0x00 && *src != 0x01 && *src != 0x34){ + DEBUGCode(&w, *src); + } + prefix_continue: + // CND命令コンパイル後ここに戻る switch (*src) { - - case 0x00: /* NOP */ - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } // 「条件付きでNOPを実行」するなんて、矛盾している! + case 0x00: + // NOP + if (w.prefix != 0) { + // 「条件付きでNOPを実行」するなんて、矛盾している! + w.err = JITC_ERR_PREFIX; + goto err_w; + } break; - case 0x01: /* LB */ - - /* - * LB : ラベル設置命令。(6byte) - * ・prefex = 1にする - * ・timecount++し、timecountのチェックをする。 - * ・ラベル位置を登録する。 - * ・割り込みがある場合、このタイミングで割り込みを発生させる。 - * - * 1 2 3 456 - * LB 01 opt imm32 - * - */ - - if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) { //beginFunc()中のLB + case 0x01: + // LB : ラベル設置命令。(6byte) + // ・prefex = 1にする + // ・timecount++し、timecountのチェックをする。 + // ・ラベル位置を登録する。 + // ・割り込みがある場合、このタイミングで割り込みを発生させる。 + // Encode: + // 0 1 2345 + // 01 opt imm32 + // + if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) { + //beginFunc()中のLB // LB命令の後に0x3C命令・・・beginFunc() - jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする enter0 = w.dst; - jitCompPutImm32(&w, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ?? + jitCompPutOp_JMPnear(w.dst, 0); } - if (src[6] == 0x34) { // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令 - tmp_ucp = w.dst; - jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする - i = jitCompGetImm32(&src[7]); // type32 を取得 + + if (src[6] == 0x34) { + // 後続命令はDATA + // なので、DATA部分をJMPですっとばすコードを生成 + // DAT_SA0(label, typ32, length) ・・・メモリ確保命令 + + i = jitCompGetImm32(&src[6 + 1]); // type32 を取得 j = 32; + if (i != 1) { i = jitCompA000_convTyp(i); j = 0; - if (i == 2 || i == 3) { j = 1; } - if (i == 4 || i == 5) { j = 2; } - if (i == 6 || i == 7) { j = 4; } + switch (i >> 1) { + case 1: + j = 1; + break; + case 2: + j = 2; + break; + case 3: + j = 4; + break; + } } - j *= jitCompGetImm32(&src[11]); - if (j <= 0) w.err = JITC_ERR_BADTYPE; - jitCompPutImm32(&w, j); + // jはデータサイズになる + j *= jitCompGetImm32(&src[6 + 5]); // len32 + if (j <= 0){ + w.err = JITC_ERR_BADTYPE; + } + // DATA部分を飛び越すジャンプ + tmp_ucp = w.dst; + jitCompPutOp_JMPnear(w.dst, j); + #if (jitCompA0001_OPTIMIZE_JMP != 0) - if (j <= 127 - jitCompA0001_OPTIMIZE_ALIGN) { + if (j < 127 - jitCompA0001_OPTIMIZE_ALIGN) { + //飛び先が十分近いので + // 今書いたのはなかったことにして、 w.dst -= 5; - jitCompPutByte2(w.dst, 0xeb, j); + // よりサイズの小さな書き方にする + jitCompPutOp_JMPshort(w.dst, j); } #endif } #if (jitCompA0001_OPTIMIZE_ALIGN != 0) - for (;;) { - i = ((int)w.dst) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */ - if (i == 0) break; - i = jitCompA0001_OPTIMIZE_ALIGN - i; - if (i == 1) { jitCompPutByte1(w.dst, 0x90); j += i; } /* NOP(); */ - if (i == 2) { jitCompPutByte2(w.dst, 0x89, 0xc0); j += i; } /* MOV(EAX, EAX); */ - if (i == 3) { jitCompPutByte3(w.dst, 0x8d, 0x76, 0x00); j += i; } /* LEA(ESI, [ESI+0]); */ - if (i == 4) { jitCompPutByte4(w.dst, 0x8d, 0x74, 0x26, 0x00); j += i; } /* LEA(ESI, [ESI*1+0]); */ - if (i == 5) { jitCompPutByte1(w.dst, 0x0d); jitCompPutImm32(&w, 0); j += i; } /* OR(EAX, 0); */ - if (i == 6) { jitCompPutByte2(w.dst, 0x8d, 0xb6); jitCompPutImm32(&w, 0); j += i; } /* LEA(ESI, [ESI+0]); */ - if (i >= 7) { jitCompPutByte3(w.dst, 0x8d, 0xb4, 0x26); jitCompPutImm32(&w, 0); j += 7; } /* LEA(ESI, [ESI*1+0]); */ - } + // アラインを jitCompA0001_OPTIMIZE_ALIGNにそろえる + + i = ((int)w.dst + 1) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */ + i = jitCompA0001_OPTIMIZE_ALIGN - i; + if (i == 1) { jitCompPutByte1(w.dst, 0x90); j += i; } /* NOP(); */ + if (i == 2) { jitCompPutByte2(w.dst, 0x89, 0xc0); j += i; } /* MOV(EAX, EAX); */ + if (i == 3) { jitCompPutByte3(w.dst, 0x8d, 0x76, 0x00); j += i; } /* LEA(ESI, [ESI+0]); */ + if (i == 4) { jitCompPutByte4(w.dst, 0x8d, 0x74, 0x26, 0x00); j += i; } /* LEA(ESI, [ESI*1+0]); */ + if (i == 5) { jitCompPutByte1(w.dst, 0x0d); jitCompPutImm32(w.dst, 0); j += i; } /* OR(EAX, 0); */ + if (i == 6) { jitCompPutByte2(w.dst, 0x8d, 0xb6); jitCompPutImm32(w.dst, 0); j += i; } /* LEA(ESI, [ESI+0]); */ + if (i == 7) { jitCompPutByte3(w.dst, 0x8d, 0xb4, 0x26); jitCompPutImm32(w.dst, 0); j += 7; } /* LEA(ESI, [ESI*1+0]); */ #endif if (src[6] == 0x34) { + // 後続命令はDATA + // パディングに合わせて一個前の相対ジャンプを修正 tmp_ucp[1] = j & 0xff; if (*tmp_ucp == 0xe9) { + // Near jump so imm is DWORD tmp_ucp[2] = (j >> 8) & 0xff; tmp_ucp[3] = (j >> 16) & 0xff; tmp_ucp[4] = (j >> 24) & 0xff; @@ -378,9 +154,14 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr } if ((flags & JITC_PHASE1) == 0) { i = jitCompGetLabelNum(&w, src + 2); - //printf("i=%06X %06X\n", i, src-src0); - if (label[i].opt != 0 && w.err == 0) { w.err = JITC_ERR_LABELREDEF; goto err_w; } - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } + if (label[i].opt != 0 && w.err == 0) { + w.err = JITC_ERR_LABELREDEF; + goto err_w; + } + if (w.prefix != 0) { + w.err = JITC_ERR_PREFIX; + goto err_w; + } label[i].opt = src[1] + 1; label[i].typ = 0; /* TYP_CODE */ label[i].p = w.dst; @@ -392,71 +173,86 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr /* 未完成(timeoutチェックコードを入れる) */ break; - case 0x02: /* LIMM */ - - /* - * LIMM : 定数即値代入命令(6byte) - * - * 1 2 3456 - * 02 reg0R imm32 - * - * ・reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。 - */ + case 0x02: + // LIMM : 定数即値代入命令(6byte) + // Encode: + // 0 1 2345 + // 02 reg0R imm32 + // + // reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。 - if (src[1] == 0x3f && w.prefix != 0) w.err = JITC_ERR_PREFIX; // CND命令の直後でR3Fを書き換えるなんて変だよね + if (src[1] == 0x3f && w.prefix != 0){ + // CND命令の直後でR3Fを書き換えるなんて変だよね + w.err = JITC_ERR_PREFIX; + } #if (jitCompA0001_USE_R3F_IMM32 != 0) - if (src[1] == 0x3f) { // R3Fへの代入は例外敵に、 w.r3f を使用 + if (src[1] == 0x3f) { + // R3Fへの代入は例外で、 w.r3f を使用 w.r3f = jitCompGetImm32(src + 2); break; } #endif i = jitCompGetImm32(src + 2); // 与えられた即値(第二引数)を取得 - /* R00-R02 なら EBX, ECX, EDX 、それ以外なら EAX のレジスタIDを reg0 に代入 */ - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); - + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); + #if (jitCompA0001_OPTIMIZE_MOV != 0) + // size optimization + // MOV reg, 0 -> XOR reg, reg if (i == 0) { - jitCompPutByte2(w.dst, 0x31, 0xc0 | reg0 << 3 | reg0); /* XOR(reg0, reg0); */ + jitCompPutOp_XOR_GReg_GReg(w.dst, reg0, reg0); jitCompA0001_movRxxEax(&w, src[1]); break; } #endif - /* reg0 のレジスタに対応したMOV命令を発行 */ - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); == 10111000b+wr imm32 */ - jitCompPutImm32(&w, i); + jitCompPutOp_MOV_GReg_Imm32(w.dst, reg0, i); - if (reg0 == 0) // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合 - + if (reg0 == 0){ + // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合 jitCompA0001_movRxxEax(&w, src[1]); - break; + } - case 0x03: /* PLIMM */ /* 未完成(plsまで対応) */ + break; - /* - * PLIMM : ラベル番号代入命令(6byte) - * - * 1 2 3456 - * 03 PXX imm32 - * - * ・P28 はAPI用 - * ・P30 はリターンアドレス - * ・P3F はプログラムカウンタ - */ + case 0x03: /* 未完成(plsまで対応) */ + // PLIMM : ラベル番号代入命令(6byte) + // Encode: + // 0 1 2345 + // 03 PXX imm32 + // + // ・P28 はAPI用 + // ・P30 はリターンアドレス + // ・P3F はプログラムカウンタ + // i = jitCompGetLabelNum(&w, src + 2); // Pxxに代入するラベルの番号(第二引数) - if ((flags & JITC_PHASE1) != 0 && w.err == 0) { // Phase 1であるならば - if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } // 指定されたラベル番号は存在しない - if (src[1] != 0x3f && label[i].opt != 2) { w.err = JITC_ERR_LABELTYP; goto err_w; } // - if (src[1] == 0x3f && label[i].typ != 0) { w.err = JITC_ERR_LABELTYP; goto err_w; } // プログラムカウンタに TYP_CODEでない値は代入できない + if ((flags & JITC_PHASE1) != 0 && w.err == 0) { + // Phase 1であるならば + if (label[i].opt == 0) { + // 指定されたラベル番号は存在しない + w.err = JITC_ERR_LABELNODEF; + goto err_w; + } + if (src[1] != 0x3f && label[i].opt != 2) { + // ? + w.err = JITC_ERR_LABELTYP; + goto err_w; + } + if (src[1] == 0x3f && label[i].typ != 0) { + // プログラムカウンタに TYP_CODEでない値は代入できない + w.err = JITC_ERR_LABELTYP; + goto err_w; + } } - if (src[1] == 0x3f) { // プログラムカウンタへの代入なら - if (w.prefix == 0) { // CND命令による条件付きでなければ、即座に移動 + if (src[1] == 0x3f) { + // プログラムカウンタへの代入 + if (w.prefix == 0) { + // CND命令による条件付きでなければ、即座に移動 jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */ - } - else { // 直前はCND命令。 + } else { + // 直前はCND命令。 /* * CND命令 @@ -466,7 +262,8 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr * いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd */ - // JZのとび先アドレスの書き換え? + // Jccの条件変更 + // 0F 75 w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */ w.dst[-2] = 0x0f; @@ -475,15 +272,14 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr j = 0; if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) // label番号iが確保されていれば (このif文は意味をなさない) j = label[i].p - (w.dst + 4); // j はとび先の相対番地 - jitCompPutImm32(&w, j); // JMP もしくは JZ 命令のアドレス部を記述 + jitCompPutImm32(w.dst, j); // JMP もしくは JZ 命令のアドレス部を記述 #if (jitCompA0001_OPTIMIZE_JMP != 0) if (-128 - 3 <= j && j < 0) { if (w.dst[-5] == 0xe9) { j += 3; w.dst -= 5; jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */ - } - else { + } else { j += 4; w.dst -= 6; jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0); @@ -491,60 +287,60 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr jitCompPutByte1(w.dst, j & 0xff); } #endif - } - else { // プログラムカウンタ以外への代入 - + } else { // プログラムカウンタ以外への代入 // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定 - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ - jitCompPutImm32(&w, (int)label[i].p); // ラベルのパスを各レジスタに代入 - - // レジスタへの代入をメモリでエミュレーションする場合は、スタックに積む。 - if (reg0 == 0) - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32, 0); /* MOV([EBP+?], EAX); */ + reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX); + // ラベルのパスを各レジスタに代入 + jitCompPutOp_MOV_GReg_Imm32(w.dst, reg0, (int)label[i].p); + // レジスタへの代入をメモリでエミュレーションする場合は、スタックに書き込む。 + if (reg0 == 0){ + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 0, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ + } if (level < JITC_LV_FASTEST) { - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 8, reg0); /* MOV([EBP+?], reg0); */ /* p0 */ - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, label[i].typ); - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 4, 0); /* MOV([EBP+?], EAX); */ /* typ */ - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, (int)label[i].p1); - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 12, 0); /* MOV([EBP+?], EAX); */ /* p1 */ - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 16, 0); /* MOV([EBP+?], EAX); */ /* liveSign */ - jitCompA0001_movReg32EbpDisp(&w, 0, 2320); /* MOV(EAX, ptrCtrl); */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 20, 0); /* MOV([EBP+?], EAX); */ /* pls */ + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 8, reg0); /* p0 */ + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, label[i].typ); + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 4, IA32_REG0_EAX); /* typ */ + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, (int)label[i].p1); + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 12, IA32_REG0_EAX); /* p1 */ + jitCompPutOp_MOV_EAX_ZERO(w.dst); + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 16, IA32_REG0_EAX); /* liveSign */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, envOffset_PTRCTRL); + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 20, IA32_REG0_EAX); /* pls */ } } break; - case 0x04: /* CND (prefix) */ - - /* - * CND命令 - * 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。 - */ + case 0x04: + // CND (prefix) + // 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。 - if (src[1] >= 0x40) w.err = JITC_ERR_REGNUM; // R00-R3F 以外のレジスタは比較対象にできない + if (src[1] >= 0x40){ + // R00-R3F 以外のレジスタは比較対象にできない + w.err = JITC_ERR_REGNUM; + goto err_w; + } // 比較対象のレジスタがメモリ上にあれば-1, それ以外なら適切なレジスタ番号を返す reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */); /* TEST命令を発行 */ - if (reg0 < 0) { //比較対象のレジスタはメモリ上にある - jitCompPutByte1(w.dst, 0xf7); /* TEST([EBP+?],1); */ - jitCompA0001_85DispN(&w, src[1] * 4, 0); + if (reg0 < 0) { + // 比較対象のレジスタはメモリ上にある + jitCompPutByte1(w.dst, 0xf7); /* TEST = 1111 011w : mod 000 r/m : immediate data */ + jitCompPutModRM_Disp_BaseEBP(&w, src[1] * 4, 0); + } else { + // 比較対象はキャッシュレジスタ上にある + jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST = 1111 011w : 11 000 reg : immediate data */ } - else { - jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST(reg0,1); */ - } - jitCompPutImm32(&w, 1); + jitCompPutImm32(w.dst, 1); /* JZ命令を発行 */ jitCompPutByte2(w.dst, 0x74, 0x00); /* JZ($+2) */ cmp0reg = -1; - if (w.err != 0) goto err_w; + if (w.err != 0){ + goto err_w; + } src += 2; w.prefix = 1; // プリフィックスをセット w.dst0 = w.dst; @@ -552,21 +348,27 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr case 0x08: /* LMEM */ /* 完成 */ i = jitCompGetImm32(src + 2); - if (i == 0x0001) w.err = JITC_ERR_BADTYPE; + if (i == 0x0001){ + w.err = JITC_ERR_BADTYPE; + } if (level < JITC_LV_FASTER) { jitCompA0001_checkType(&w, src[6], i, 0); // read cmp0reg = -1; } - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); - if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) - reg1 = 0; /* EAX */ - if (reg1 == 2 /* EDX */) + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); + reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX); + if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX){ + reg1 = IA32_REG0_EAX; + } + if (reg1 == IA32_REG2_EDX){ jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ - if (level < JITC_LV_FASTER) + } + if (reg1 <= 3 /* EAX, EDX */){ + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6])); + } + if (level < JITC_LV_FASTER){ jitCompA0001_checkLimit(&w, reg1, src[6]); + } i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); switch (i) { case 0x0002: @@ -588,31 +390,40 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr default: w.err = JITC_ERR_BADTYPE; } - if (reg0 == 0 /* EAX */) + if (reg0 == IA32_REG0_EAX){ jitCompA0001_movRxxEax(&w, src[1]); - if (reg1 == 2 /* EDX */) + } + if (reg1 == IA32_REG2_EDX){ jitCompA000_loadRegCacheEdx(&w); + } break; case 0x09: /* SMEM */ /* 完成 */ i = jitCompGetImm32(src + 2); - if (i == 0x0001) w.err = JITC_ERR_BADTYPE; + if (i == 0x0001){ + w.err = JITC_ERR_BADTYPE; + } if (level < JITC_LV_FASTER) { jitCompA0001_checkType(&w, src[6], i, 1); // write cmp0reg = -1; } - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); - if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) - reg1 = 0; /* EAX */ - if (reg1 == 2 /* EDX */) + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); + reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX); + if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX){ + reg1 = IA32_REG0_EAX; + } + if (reg1 == IA32_REG2_EDX){ jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ - if (level < JITC_LV_FASTER) + } + if (reg1 <= 3 /* EAX, EDX */){ + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6]) + 0); /* MOV(reg1, [EBP+?]); */ + } + if (level < JITC_LV_FASTER){ jitCompA0001_checkLimit(&w, reg1, src[6]); - if (reg0 == 0 /* EAX */) + } + if (reg0 == IA32_REG0_EAX){ jitCompA0001_movEaxRxx(&w, src[1]); + } /* 値の範囲チェック */ i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); switch (i) { @@ -631,40 +442,49 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr default: w.err = JITC_ERR_BADTYPE; } - if (reg1 == 2 /* EDX */) + if (reg1 == IA32_REG2_EDX){ jitCompA000_loadRegCacheEdx(&w); + } break; case 0x0a: /* PLMEM */ /* 完成 */ i = jitCompGetImm32(src + 2); - if (i != 0x0001) w.err = JITC_ERR_BADTYPE; + if (i != 0x0001){ + w.err = JITC_ERR_BADTYPE; + } if (level < JITC_LV_FASTER) { jitCompA0001_checkType(&w, src[6], i, 0); // read cmp0reg = -1; } - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); + reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX); + reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX); // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */ // reg1 = 0; /* EAX */ - if (reg0 == reg1 && reg0 != 0) { // bugfix: hinted by yao, 2013.09.14. thanks! + if (reg0 == reg1 && reg0 != 0) { + // bugfix: hinted by yao, 2013.09.14. thanks! jitCompA000_storePRegCacheAll(&w); - reg1 = 2; /* EDX */ + reg1 = IA32_REG2_EDX; } - if (reg1 == 2 /* EDX */) + if (reg1 == IA32_REG2_EDX){ jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ - if (level < JITC_LV_FASTER) + } + if (reg1 <= 3 /* EAX, EDX */){ + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6])); /* MOV(reg1, [EBP+?]); */ + } + if (level < JITC_LV_FASTER){ jitCompA0001_checkLimit(&w, reg1, src[6]); + } jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */ - if (reg0 == 0 /* EAX */) - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0); /* MOV([EBP+?], EAX); */ + if (reg0 == IA32_REG0_EAX){ + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]), IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ + } for (i = 4; i < 32; i += 4) { jitCompPutByte3(w.dst, 0x8b, 0x40 | reg1, i); /* MOV(EAX, [reg1+?]); */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ } - if (reg1 == 2 /* EDX */) + if (reg1 == IA32_REG2_EDX){ jitCompA000_loadRegCacheEdx(&w); + } break; case 0x0b: /* PSMEM */ /* 完成 */ @@ -674,24 +494,29 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr jitCompA0001_checkType(&w, src[6], i, 1); // write cmp0reg = -1; } - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); - // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */ + reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX); + reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX); + /* これをやってはいけない!(by K, 2013.08.02) */ + // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) // reg1 = 0; /* EAX */ - if (reg1 == 2 /* EDX */) + if (reg1 == IA32_REG2_EDX){ jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ - if (level < JITC_LV_FASTER) + } + if (reg1 <= 3 /* EAX, EDX */){ + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6])); /* MOV(reg1, [EBP+?]); */ + } + if (level < JITC_LV_FASTER){ jitCompA0001_checkLimit(&w, reg1, src[6]); - if (reg0 == 0 /* EAX */) - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[1] * 32 + 0); /* MOV(reg0, [EBP+?]); */ + } + if (reg0 == IA32_REG0_EAX){ + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[1])); /* MOV(reg0, [EBP+?]); */ + } jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */ for (i = 4; i < 32; i += 4) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[1] * 32 + i); /* MOV(EAX, [EBP+?]); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[1]) + i); /* MOV(EAX, [EBP+?]); */ jitCompPutByte3(w.dst, 0x89, 0x40 | reg1, i); /* MOV([reg1+?], EAX); */ } - if (reg1 == 2 /* EDX */) + if (reg1 == IA32_REG2_EDX) jitCompA000_loadRegCacheEdx(&w); break; @@ -700,63 +525,78 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 2), 2); // other, aliveテストはとりあえずしない. cmp0reg = -1; } - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); + reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX); reg1 = jitCompA000_selectPRegCache(src[6], -1 /* mem */); - if (reg1 < 0 /* mem */) - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ + if (reg1 < 0 /* mem */){ + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[6])); /* MOV(reg0, [EBP+?]); */ + } if (reg1 >= 0 && reg0 != reg1) { jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ } i = jitCompGetImm32(src + 2); j = -1; - if (i == 1) + if (i == 1){ j = 5; /* 32 */ - else { + } else { i = jitCompA000_convTyp(i); - if (0x0002 <= i && i <= 0x0007) + if (0x0002 <= i && i <= 0x0007){ j = (i - 0x0002) >> 1; + } + } + if (j < 0) { + w.err = JITC_ERR_BADTYPE; + goto err_w; } - if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; } #if (jitCompA0001_USE_R3F_IMM32 != 0) if (src[7] == 0x3f) { j = w.r3f << j; #if (jitCompA0001_USE_R3F_IMM8 != 0) if (-0x80 <= j && j <= 0x7f) { #if (jitCompA0001_USE_R3F_INCDEC != 0) - if (j == 1) { jitCompPutByte1(w.dst, 0x40 | reg0); goto padd1; } /* INC */ - if (j == -1) { jitCompPutByte1(w.dst, 0x48 | reg0); goto padd1; } /* DEC */ + if (j == 1) { + /* INC */ + jitCompPutByte1(w.dst, 0x40 | reg0); + goto padd1; + } + if (j == -1) { + /* DEC */ + jitCompPutByte1(w.dst, 0x48 | reg0); + goto padd1; + } #endif - jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff); /* ADD(reg0, im8); */ + /* ADD(reg0, im8); */ + jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff); goto padd1; } #endif if (reg0 == 0) { jitCompPutByte1(w.dst, 0x05); /* ADD(reg0, ?); */ - } - else { + } else { jitCompPutByte2(w.dst, 0x81, 0xc0 | reg0); /* ADD(reg0, ?); */ } - jitCompPutImm32(&w, j); + jitCompPutImm32(w.dst, j); goto padd1; } #endif - if (src[7] >= 0x40) w.err = JITC_ERR_REGNUM; + if (src[7] >= 0x40){ + w.err = JITC_ERR_REGNUM; + } if (j == 0) { reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */); if (reg1 >= 0) { jitCompPutByte2(w.dst, 0x01, 0xc0 | reg1 << 3 | reg0); /* ADD(reg0, reg1); */ - } - else { + } else { jitCompPutByte1(w.dst, 0x03); /* ADD(reg0, [EBP+?]); */ - jitCompA0001_85DispN(&w, src[7] * 4, reg0); + jitCompPutModRM_Disp_BaseEBP(&w, src[7] * 4, reg0); } } else { reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */); - reg2 = 2; /* EDX */ + reg2 = IA32_REG2_EDX; jitCompA000_storeRegCacheEdx(&w); - if (reg1 < 0) - jitCompA0001_movReg32EbpDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */ + if (reg1 < 0){ + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */ + } if (reg1 >= 0 && reg1 != reg2) { jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg2); /* MOV(reg2, reg1); */ } @@ -767,35 +607,42 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr #if (jitCompA0001_USE_R3F_IMM32 != 0) padd1: #endif - if (reg0 == 0 /* EAX */) - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, reg0); /* MOV([EBP+?], reg0); */ + if (reg0 == IA32_REG0_EAX){ + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]), reg0); /* MOV([EBP+?], reg0); */ + } if (src[1] != src[6]) { for (i = 4; i < 32; i += 4) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */ + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ } } cmp0reg = -1; break; case 0x0f: /* PDIF */ /* 未完成 */ - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); jitCompA000_storePRegCacheAll(&w); // 手抜き. jitCompA0001_checkCompPtr(&w, src[6], src[7]); - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[6])); /* MOV(reg0, [EBP+?]); */ jitCompPutByte1(w.dst, 0x2b); /* SUB(EAX, [EBP+?]); */ - jitCompA0001_85DispN(&w, 256 + src[7] * 32 + 0, reg0); + jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[7]) + 0, reg0); i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); j = -1; - if (0x0002 <= i && i <= 0x0007) + if (0x0002 <= i && i <= 0x0007){ j = (i - 0x0002) >> 1; - if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; } + } + if (j < 0) { + w.err = JITC_ERR_BADTYPE; + goto err_w; + } if (j > 0) { jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, j); /* SAR(reg0,?); */ } - if (reg0 == 0 /* EAX */) + if (reg0 == IA32_REG0_EAX){ jitCompA0001_movRxxEax(&w, src[1]); - cmp0reg = src[1]; cmp0lev = 1; + } + cmp0reg = src[1]; + cmp0lev = 1; break; case 0x10: /* OR */ @@ -804,58 +651,70 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr case 0x14: /* ADD */ case 0x15: /* SUB */ case 0x16: /* MUL */ - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); + if (src[1] >= 0x3f){ + w.err = JITC_ERR_REGNUM; + } + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); #if (jitCompA0001_USE_R3F_IMM32 != 0) if (src[2] == 0x3f) { // SUBのみ該当. - if (*src != 0x15) w.err = JITC_ERR_REGNUM; + if (*src != 0x15){ + w.err = JITC_ERR_REGNUM; + } reg2 = jitCompA000_selectRegCache(src[3], -1 /* mem */); - if (reg2 >= 0) + if (reg2 >= 0){ jitCompA000_storeRegCacheAll(&w); + } jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ - jitCompPutImm32(&w, w.r3f); + jitCompPutImm32(w.dst, w.r3f); jitCompPutByte1(w.dst, 0x2b); - jitCompA0001_85DispN(&w, src[3] * 4, reg0); - if (reg0 == 0) + jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); + if (reg0 == 0){ jitCompA0001_movRxxEax(&w, src[1]); + } break; } #endif if (reg1 < 0) { - jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg0, [EBP+?]); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, src[2] * 4); /* MOV(reg0, [EBP+?]); */ } if (reg1 >= 0 && reg0 != reg1) { jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ } - if (!(src[0] == 0x10 && src[3] == 0xff)) { // bugfix: hinted by Iris, 2013.06.26. thanks! + if (!(src[0] == 0x10 && src[3] == 0xff)) { + // bugfix: hinted by Iris, 2013.06.26. thanks! cmp0reg = src[1]; cmp0lev = 1; - if (src[0] < 0x14) + if (src[0] < 0x14){ cmp0lev = 2; - if (src[0] == 0x16) + } + if (src[0] == 0x16){ cmp0reg = -1; + } } if (!(src[0] == 0x10 && src[3] == 0xff)) { #if (jitCompA0001_USE_R3F_IMM32 != 0) if (src[3] == 0x3f) { if (*src == 0x16 && w.r3f == -1) { jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */ - if (reg0 == 0) + if (reg0 == 0){ jitCompA0001_movRxxEax(&w, src[1]); + } break; } #if (jitCompA0001_USE_R3F_INCDEC != 0) if ((*src == 0x14 && w.r3f == 1) || (*src == 0x15 && w.r3f == -1)) { jitCompPutByte1(w.dst, 0x40 | reg0); /* INC(reg0); */ - if (reg0 == 0) + if (reg0 == 0){ jitCompA0001_movRxxEax(&w, src[1]); + } break; } if ((*src == 0x15 && w.r3f == 1) || (*src == 0x14 && w.r3f == -1)) { jitCompPutByte1(w.dst, 0x48 | reg0); /* DEC(reg0); */ - if (reg0 == 0) + if (reg0 == 0){ jitCompA0001_movRxxEax(&w, src[1]); + } break; } #endif @@ -864,21 +723,22 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr if (*src != 0x16) { static unsigned char basic_op_table_im8[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 }; jitCompPutByte3(w.dst, 0x83, basic_op_table_im8[*src - 0x10] | reg0, w.r3f & 0xff); - } - else { + } else{ jitCompPutByte3(w.dst, 0x6b, 0xc0 | reg0 << 3 | reg0, w.r3f & 0xff); } - if (reg0 == 0) + if (reg0 == 0){ jitCompA0001_movRxxEax(&w, src[1]); + } break; } #endif - if (reg0 == 0 /* EAX */) { + if (reg0 == IA32_REG0_EAX) { static unsigned char basic_op_table_im32_eax[] = { 0x0d, 0x35, 0x25, 0, 0x05, 0x2d, 0xc0 }; - if (*src == 0x16) { jitCompPutByte1(w.dst, 0x69); } + if (*src == 0x16) { + jitCompPutByte1(w.dst, 0x69); + } jitCompPutByte1(w.dst, basic_op_table_im32_eax[*src - 0x10]); - } - else { + } else{ if (*src != 0x16) { static unsigned char basic_op_table_im32_reg[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 }; jitCompPutByte2(w.dst, 0x81, basic_op_table_im32_reg[*src - 0x10] | reg0); @@ -887,79 +747,98 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr jitCompPutByte2(w.dst, 0x69, 0xc0 | reg0 << 3 | reg0); } } - jitCompPutImm32(&w, w.r3f); - if (reg0 == 0) + jitCompPutImm32(w.dst, w.r3f); + if (reg0 == 0){ jitCompA0001_movRxxEax(&w, src[1]); + } break; } #endif reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; + if (src[3] >= 0x40){ + w.err = JITC_ERR_REGNUM; + } if (*src != 0x16) { if (reg1 >= 0) { static unsigned char basic_op_table_rr[] = { 0x09, 0x31, 0x21, 0, 0x01, 0x29 }; /* op(reg,reg); */ jitCompPutByte2(w.dst, basic_op_table_rr[*src - 0x10], 0xc0 | reg1 << 3 | reg0); - } - else { + } else{ static unsigned char basic_op_table_rm[] = { 0x0b, 0x33, 0x23, 0, 0x03, 0x2b, 0xaf }; /* op(reg,mem); */ jitCompPutByte1(w.dst, basic_op_table_rm[*src - 0x10]); - jitCompA0001_85DispN(&w, src[3] * 4, reg0); + jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); } - } - else { + } else{ if (reg1 >= 0) { jitCompPutByte3(w.dst, 0x0f, 0xaf, 0xc0 | reg0 << 3 | reg1); - } - else { + } else{ jitCompPutByte2(w.dst, 0x0f, 0xaf); - jitCompA0001_85DispN(&w, src[3] * 4, reg0); + jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); } } } - if (reg0 == 0) + if (reg0 == 0){ jitCompA0001_movRxxEax(&w, src[1]); + } break; case 0x18: /* SHL */ case 0x19: /* SAR */ - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; + if (src[1] >= 0x3f){ + w.err = JITC_ERR_REGNUM; + } + if (src[3] >= 0x40){ + w.err = JITC_ERR_REGNUM; + } #if (jitCompA0001_USE_R3F_IMM32 != 0) if (src[3] == 0x3f) { - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; - if (reg1 == -1) - jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg1, [EBP+?]); */ - else { + if (src[1] >= 0x3f){ + w.err = JITC_ERR_REGNUM; + } + if (reg1 == -1){ + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, src[2] * 4); /* MOV(reg1, [EBP+?]); */ + } else{ if (reg0 != reg1) { jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ } } - if (*src == 0x18) { jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f); } /* SHL(reg0, im8); */ - if (*src == 0x19) { jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f); } /* SAR(reg0, im8); */ - if (reg0 == 0 /* EAX */) + if (*src == 0x18) { + /* SHL(reg0, im8); */ + jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f); + } + if (*src == 0x19) { + /* SAR(reg0, im8); */ + jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f); + } + if (reg0 == IA32_REG0_EAX){ jitCompA0001_movRxxEax(&w, src[1]); + } cmp0reg = src[1]; cmp0lev = 1; break; } #endif jitCompA000_storeRegCacheAll(&w); // 手抜き. - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */ #if (jitCompA0001_USE_R3F_IMM32 != 0) if (src[2] == 0x3f) { jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, w.r3f); - } - else { + jitCompPutImm32(w.dst, w.r3f); + } else{ jitCompA0001_movEaxRxx(&w, src[2]); } #else jitCompA0001_movEaxRxx(&w, src[2]); #endif - if (*src == 0x18) { jitCompPutByte2(w.dst, 0xd3, 0xe0); } /* SHL(EAX, CL); */ - if (*src == 0x19) { jitCompPutByte2(w.dst, 0xd3, 0xf8); } /* SAR(EAX, CL); */ + if (*src == 0x18) { + /* SHL(EAX, CL); */ + jitCompPutByte2(w.dst, 0xd3, 0xe0); + } + if (*src == 0x19) { + /* SAR(EAX, CL); */ + jitCompPutByte2(w.dst, 0xd3, 0xf8); + } jitCompA0001_movRxxEax(&w, src[1]); jitCompA000_loadRegCacheAll(&w); // 手抜き. cmp0reg = src[1]; @@ -968,41 +847,45 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr case 0x1a: /* DIV */ case 0x1b: /* MOD */ - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; - if (src[2] >= 0x40) w.err = JITC_ERR_REGNUM; - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; + if (src[1] >= 0x3f || src[2] >= 0x40 || src[3] >= 0x40){ + w.err = JITC_ERR_REGNUM; + } jitCompA000_storeRegCacheAll(&w); // 手抜き. #if (jitCompA0001_USE_R3F_IMM32 != 0) if (src[3] == 0x3f) { jitCompPutByte1(w.dst, 0xb8 | 1); /* MOV(ECX, ?); */ - jitCompPutImm32(&w, w.r3f); - } - else { - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ + jitCompPutImm32(w.dst, w.r3f); + } else{ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */ } if (src[2] == 0x3f) { jitCompPutByte1(w.dst, 0xb8 | 0); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, w.r3f); - } - else { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */ + jitCompPutImm32(w.dst, w.r3f); + } else{ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, src[2] * 4); /* MOV(EAX, [EBP+?]); */ } #else - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, src[2] * 4); /* MOV(EAX, [EBP+?]); */ #endif jitCompPutByte1(w.dst, 0x99); /* CDQ(); */ /* ECXがゼロではないことを確認すべき */ jitCompPutByte2(w.dst, 0xf7, 0xf9); /* IDIV(ECX); */ - if (*src == 0x1a) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 0 /* EAX */); } - if (*src == 0x1b) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 2 /* EDX */); } + if (*src == 0x1a) { + jitCompPutOp_MOV_EBPDisp_GReg(&w, src[1] * 4, IA32_REG0_EAX); + } + if (*src == 0x1b) { + jitCompPutOp_MOV_EBPDisp_GReg(&w, src[1] * 4, IA32_REG2_EDX); + } jitCompA000_loadRegCacheAll(&w); // 手抜き. cmp0reg = -1; break; case 0x1c: /* PLMT0 */ case 0x1d: /* PLMT1 */ - if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; + if (src[1] >= 0x40 || src[2] >= 0x40){ + w.err = JITC_ERR_PREGNUM; + } if (level < JITC_LV_FASTEST) { cmp0reg = -1; if (level < JITC_LV_FASTER) { @@ -1010,39 +893,42 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr // plsとliveSignが一致していることを確認. // preg1はp0 <= p <= p1 を満たしているか?. - // 新しいp0/p1は古いp0〜p1に適合しているか?. + // 新しいp0/p1は古いp0?p1に適合しているか?. } } case 0x1e: /* PCP */ /* 未完成(p1まで完成) */ - if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; - if (src[2] == 0x3f) w.err = JITC_ERR_PREGNUM; + if (src[1] >= 0x40 || src[2] >= 0x40){ + w.err = JITC_ERR_PREGNUM; + } + if (src[2] == 0x3f){ + w.err = JITC_ERR_PREGNUM; + } if (src[1] != 0x3f) { /* src[2] == 0xff の場合に対応できてない */ jitCompA000_storePRegCacheAll(&w); // 手抜き. for (i = 0; i < 32; i += 4) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + i); /* MOV(EAX, [EBP+?]); */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + i); /* MOV(EAX, [EBP+?]); */ + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ } jitCompA000_loadPRegCacheAll(&w); // 手抜き. - } - else { + } else { if (level < JITC_LV_FASTER) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ jitCompPutByte3(w.dst, 0x83, 0xf8, 0); /* CMP(EAX, 0); */ jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ - jitCompPutImm32(&w, errfnc - (w.dst + 4)); + jitCompPutImm32(w.dst, errfnc - (w.dst + 4)); /* セキュリティチェックが足りてない!(aliveとか) */ } - reg0 = 0; /* EAX */ + reg0 = IA32_REG0_EAX; jitCompA000_storePRegCacheAll(&w); // 手抜き. - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[2]) + 0); /* MOV(EAX, [EBP+?]); */ if (level < JITC_LV_FASTER) { jitCompPutByte1(w.dst, 0x3b); /* CMP(reg0, [EBP+?]); */ - jitCompA0001_85DispN(&w, 256 + src[2] * 32 + 8, reg0); /* p0 */ + jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[2]) + 8, reg0); /* p0 */ jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ - jitCompPutImm32(&w, errfnc - (w.dst + 4)); + jitCompPutImm32(w.dst, errfnc - (w.dst + 4)); } jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */ } @@ -1050,20 +936,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr case 0x1f: /* PCST */ if (jitCompGetImm32(src + 2) == 0) { - if (level < JITC_LV_FASTER) + if (level < JITC_LV_FASTER){ jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 7), 2); + } jitCompA000_storePRegCacheAll(&w); // 手抜き. for (i = 0; i < 32 - 4; i += 4) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */ if (i == 4) { jitCompPutByte1(w.dst, 0x0d); /* OR(EAX, ?); */ - jitCompPutImm32(&w, 0x80000000); + jitCompPutImm32(w.dst, 0x80000000); } - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ } - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, debugInfo1); - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 28, 0 /* EAX */); /* MOV([EBP+?], EAX); */ + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1); + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 28, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ jitCompA000_loadPRegCacheAll(&w); // 手抜き. cmp0reg = -1; break; @@ -1071,20 +957,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr if (jitCompGetImm32(src + 7) == 0) { jitCompA000_storePRegCacheAll(&w); // 手抜き. for (i = 0; i < 32 - 4; i += 4) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */ if (i == 4) { jitCompPutByte1(w.dst, 0x25); /* AND(EAX, ?); */ - jitCompPutImm32(&w, 0x7fffffff); + jitCompPutImm32(w.dst, 0x7fffffff); } - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ } if (level < JITC_LV_FASTER) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + 28); /* MOV(EAX, [EBP+?]); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + 28); /* MOV(EAX, [EBP+?]); */ jitCompPutByte1(w.dst, 0x3d); /* CMP(EAX, ?); */ - jitCompPutImm32(&w, debugInfo1); + jitCompPutImm32(w.dst, debugInfo1); jitCompPutByte2(w.dst, 0x74, 8); /* JE */ - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); (2) */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0 /* EAX */); /* MOV([EBP+?], EAX); (1+1+4) */ + jitCompPutOp_MOV_EAX_ZERO(w.dst); + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 0, IA32_REG0_EAX); /* MOV([EBP+?], EAX); (1+1+4) */ } jitCompA000_loadPRegCacheAll(&w); // 手抜き. cmp0reg = -1; @@ -1101,13 +987,17 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr case 0x25: /* CMPG */ case 0x26: /* TSTZ */ case 0x27: /* TSTNZ */ - reg0 = jitCompA000_selectRegCache(src[2], 0 /* EAX */); + reg0 = jitCompA000_selectRegCache(src[2], IA32_REG0_EAX); reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); if (src[1] == 0x3f) { /* 特殊構文チェック */ - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } + if (w.prefix != 0) { + w.err = JITC_ERR_PREFIX; + goto err_w; + } if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) { - w.err = JITC_ERR_IDIOM; goto err_w; + w.err = JITC_ERR_IDIOM; + goto err_w; } } if (reg0 == 0) @@ -1118,10 +1008,12 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr if ((*src <= 0x25 && w.r3f == 0) || (*src >= 0x26 && w.r3f == -1)) { i = 0; if (cmp0reg == src[2]) { - if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27)) + if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27)){ i = 1; - if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25)) + } + if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25)){ i = 1; + } } if (i == 0) { jitCompPutByte2(w.dst, 0x85, 0xc0 | reg0 << 3 | reg0); /* TEST(reg0, reg0); */ @@ -1138,29 +1030,48 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr } #endif if (reg0 == 0) { - if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3d); } - if (*src >= 0x26) { jitCompPutByte1(w.dst, 0xa9); } + if (*src <= 0x25) { + jitCompPutByte1(w.dst, 0x3d); + } + if (*src >= 0x26) { + jitCompPutByte1(w.dst, 0xa9); + } } else { - if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0); } - if (*src >= 0x26) { jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); } + if (*src <= 0x25) { + jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0); + } + if (*src >= 0x26) { + jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); + } } - jitCompPutImm32(&w, w.r3f); + jitCompPutImm32(w.dst, w.r3f); goto cmpcc1; } #endif - if (src[3] >= 0x40) w.err = JITC_ERR_PREGNUM; - if (reg1 >= 0) { - if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x39, 0xc0 | reg1 << 3 | reg0); } - if (*src >= 0x26) { jitCompPutByte2(w.dst, 0x85, 0xc0 | reg1 << 3 | reg0); } + if (src[3] >= 0x40){ + w.err = JITC_ERR_PREGNUM; } - else { - if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3b); } - if (*src >= 0x26) { jitCompPutByte1(w.dst, 0x85); } - jitCompA0001_85DispN(&w, src[3] * 4, reg0); + if (reg1 >= 0) { + if (*src <= 0x25) { + jitCompPutByte2(w.dst, 0x39, 0xc0 | reg1 << 3 | reg0); + } + if (*src >= 0x26) { + jitCompPutByte2(w.dst, 0x85, 0xc0 | reg1 << 3 | reg0); + } + } else{ + if (*src <= 0x25) { + jitCompPutByte1(w.dst, 0x3b); + } + if (*src >= 0x26) { + jitCompPutByte1(w.dst, 0x85); + } + jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); } cmpcc1: - if (w.err != 0) goto err_w; + if (w.err != 0){ + goto err_w; + } static unsigned char cmpcc_table0[] = { 0x04, 0x05, 0x0c, 0x0d, 0x0e, 0x0f, 0x04, 0x05, /* CMPcc, TSTcc */ 0x04, 0x05, 0x02, 0x03, 0x06, 0x07 /* PCMPcc */ @@ -1172,13 +1083,17 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr src += 6; i = jitCompGetLabelNum(&w, src + 2); if ((flags & JITC_PHASE1) != 0 && w.err != 0) { - if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } + if (label[i].opt == 0) { + w.err = JITC_ERR_LABELNODEF; + goto err_w; + } // if (label[i].typ != 1) { w.err = JITC_ERR_LABELTYP; goto err_w; } } j = 0; - if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) + if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)){ j = label[i].p - (w.dst + 4); - jitCompPutImm32(&w, j); + } + jitCompPutImm32(w.dst, j); #if (jitCompA0001_OPTIMIZE_JMP != 0) if (-128 - 4 <= j && j < 0) { j += 4; @@ -1187,17 +1102,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr } #endif src += 6; - if (w.err != 0) goto err_w; + if (w.err != 0){ + goto err_w; + } continue; } #endif /* 一般的なJITC */ - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); jitCompPutByte3(w.dst, 0x0f, 0x90 | cmpcc_table0[*src - 0x20], 0xc0 | reg0); /* SETcc(BYTE(reg0)); */ jitCompPutByte3(w.dst, 0x0f, 0xb6, 0xc0 | reg0 << 3 | reg0); /* MOVZX(reg0, BYTE(reg0)); */ jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */ - if (reg0 == 0) + if (reg0 == 0){ jitCompA0001_movRxxEax(&w, src[1]); + } cmp0reg = src[2]; cmp0lev = 1; break; @@ -1210,21 +1128,27 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr case 0x2d: /* PCMPG */ if (src[1] == 0x3f) { /* 特殊構文チェック */ - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } + if (w.prefix != 0) { + w.err = JITC_ERR_PREFIX; + goto err_w; + } if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) { - w.err = JITC_ERR_IDIOM; goto err_w; + w.err = JITC_ERR_IDIOM; + goto err_w; } } - if (src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; + if (src[2] >= 0x40) { + w.err = JITC_ERR_PREGNUM; + } jitCompA000_storePRegCacheAll(&w); // 手抜き. - if (src[3] != 0xff) + if (src[3] != 0xff){ jitCompA0001_checkCompPtr(&w, src[2], src[3]); - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ + } + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + 0); /* MOV(EAX, [EBP+?]); */ if (src[3] != 0xff) { jitCompPutByte1(w.dst, 0x3b); /* CMP(EAX, [EBP+?]); */ - jitCompA0001_85DispN(&w, 256 + src[3] * 32 + 0, 0); - } - else { + jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[3]) + 0, 0); + } else{ /* ヌルポインタとの比較はこれでいいのか?たぶんよくない */ jitCompPutByte3(w.dst, 0x83, 0xf8, 0x00); /* CMP(EAX, 0); */ } @@ -1237,42 +1161,84 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr case 0x33: /* mfree(old:F7) */ jitCompA000_storeRegCacheAll(&w); // 手抜き. jitCompA000_storePRegCacheAll(&w); // 手抜き. - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ - jitCompPutByte1(w.dst, 0xe8); - if (*src == 0x30) j = ((unsigned char *)&funcf4) - (w.dst + 4); - if (*src == 0x31) j = ((unsigned char *)&funcf5) - (w.dst + 4); - if (*src == 0x32) j = ((unsigned char *)&funcf6) - (w.dst + 4); - if (*src == 0x33) j = ((unsigned char *)&funcf7) - (w.dst + 4); - jitCompPutImm32(&w, j); - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x10); /* ADD(ESP,16); */ + + jitCompPutOp_PUSH_Imm8(w.dst, src[3]); + jitCompPutOp_PUSH_Imm8(w.dst, src[2]); + jitCompPutOp_PUSH_Imm8(w.dst, src[1]); + jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP); + + switch (*src) { + case 0x30: + j = ((unsigned char *)&funcf4) - (w.dst + 1 + 4); + break; + case 0x31: + j = ((unsigned char *)&funcf5) - (w.dst + 1 + 4); + break; + case 0x32: + j = ((unsigned char *)&funcf6) - (w.dst + 1 + 4); + break; + case 0x33: + j = ((unsigned char *)&funcf7) - (w.dst + 1 + 4); + break; + } + jitCompPutOp_CALL_Relative(w.dst, j); + jitCompPutOp_ADD_GReg_Imm8(w.dst, IA32_REG4_ESP, 16); + jitCompA000_loadRegCacheAll(&w); // 手抜き. jitCompA000_loadPRegCacheAll(&w); // 手抜き. cmp0reg = -1; break; case 0x34: /* data (暫定) */ + // 0 1234 5678 9 + // 34 typ32 len32 data... + // len32 is NOT byte size! + cmp0reg = -1; - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } - int k = jitCompGetImm32(&src[1]), tmpData, bitCount, dataWidth = jitCompA000_dataWidth(k); - if (lastlabel >= 0 && label[lastlabel].typ == 0) + if (w.prefix != 0) { + w.err = JITC_ERR_PREFIX; + goto err_w; + } + int k, tmpData, bitCount, dataWidth; + // kはtyp32 + k = jitCompGetImm32(&src[1]); + dataWidth = jitCompA000_dataWidth(k); + if (lastlabel >= 0 && label[lastlabel].typ == 0){ + //直前のラベルタイプを設定 label[lastlabel].typ = k; + } if (k != 1) { i = jitCompA000_convTyp(k); - if (i < 2 || i > 7) { w.err = JITC_ERR_BADTYPE; goto err_w; } + if (i < 2 || i > 7) { + w.err = JITC_ERR_BADTYPE; + goto err_w; + } } + // jはlen32 j = jitCompGetImm32(&src[5]); oldsrc = src; src += 9; + + // srcはdata本体を指す if (k != 1) { + // 一般データ bitCount = 7; while (j > 0) { - if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; } - if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; } + if (src >= src1) { + // バイトコードを末端を超えて読もうとした + w.err = JITC_ERR_SRC1; + src = oldsrc; + goto err_w; + } + if (w.dst + 256 > dst1) { + // 書き込み先の残り容量が256Bytesを切った + w.err = JITC_ERR_DST1; + src = oldsrc; + goto err_w; + } tmpData = 0; for (k = 0; k < dataWidth; k++) { + // dataWidthビットごとに切り出してtmpDataに入れる tmpData = tmpData << 1 | ((*src >> bitCount) & 1); bitCount--; if (bitCount < 0) { @@ -1281,53 +1247,78 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr } } if ((i & 1) == 0 && dataWidth <= 31 && (tmpData >> (dataWidth - 1)) != 0) { + // 符号あり型で、かつtmpDataの符号ビットが1なので、マイナスにする tmpData -= 1 << dataWidth; } - if (i == 2 || i == 3) { jitCompPutByte1(w.dst, tmpData & 0xff); } - if (i == 4 || i == 5) { jitCompPutByte2(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff); } - if (i == 6 || i == 7) { jitCompPutByte4(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff, (tmpData >> 16) & 0xff, (tmpData >> 24) & 0xff); } + if (i == 2 || i == 3) { + // BYTE + jitCompPutByte1(w.dst, tmpData & 0xff); + } + if (i == 4 || i == 5) { + // WORD + jitCompPutByte2(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff); + } + if (i == 6 || i == 7) { + // DWORD + jitCompPutByte4(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff, (tmpData >> 16) & 0xff, (tmpData >> 24) & 0xff); + } j--; } - } - else { + } else{ + // VPtr型 while (j > 0) { - if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; } - if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; } + if (src >= src1) { + // バイトコードを末端を超えて読もうとした + w.err = JITC_ERR_SRC1; + src = oldsrc; + goto err_w; + } + if (w.dst + 256 > dst1) { + // 書き込み先の残り容量が256Bytesを切った + w.err = JITC_ERR_DST1; + src = oldsrc; + goto err_w; + } i = jitCompGetImm32(src); src += 4; if ((flags & JITC_PHASE1) != 0 && w.err == 0) { - if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } + // Only in phase1 + if (label[i].opt == 0) { + // ローカルラベルはだめです... + w.err = JITC_ERR_LABELNODEF; + goto err_w; + } } - jitCompPutImm32(&w, (int)label[i].p); - jitCompPutImm32(&w, label[i].typ); - jitCompPutImm32(&w, (int)label[i].p); - jitCompPutImm32(&w, (int)label[i].p1); - jitCompPutImm32(&w, 0); /* liveSign */ - jitCompPutImm32(&w, 2320); /* pls */ - jitCompPutImm32(&w, 0); - jitCompPutImm32(&w, 0); + jitCompPutImm32(w.dst, (int)label[i].p); + jitCompPutImm32(w.dst, label[i].typ); + jitCompPutImm32(w.dst, (int)label[i].p); + jitCompPutImm32(w.dst, (int)label[i].p1); + jitCompPutImm32(w.dst, 0); /* liveSign */ + jitCompPutImm32(w.dst, envOffset_PTRCTRL); /* pls */ + jitCompPutImm32(w.dst, 0); + jitCompPutImm32(w.dst, 0); j--; } } - if (lastlabel >= 0 && label[lastlabel].p1 < w.dst) + if (lastlabel >= 0 && label[lastlabel].p1 < w.dst){ label[lastlabel].p1 = w.dst; + } continue; case 0x3c: /* ENTER */ jitCompA000_storeRegCacheAll(&w); // 手抜き. jitCompA000_storePRegCacheAll(&w); // 手抜き. - jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ - jitCompPutByte1(w.dst, 0xe8); - j = ((unsigned char *)&func3c) - (w.dst + 4); - jitCompPutImm32(&w, j); - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */ + jitCompPutOp_PUSH_Imm8(w.dst, src[6]); + jitCompPutOp_PUSH_Imm8(w.dst, src[5]); + jitCompPutOp_PUSH_Imm8(w.dst, src[4] & 0x0f); + jitCompPutOp_PUSH_Imm8(w.dst, (src[4] >> 4) & 0x0f); + jitCompPutOp_PUSH_Imm8(w.dst, src[3]); + jitCompPutOp_PUSH_Imm8(w.dst, src[2]); + jitCompPutOp_PUSH_Imm8(w.dst, src[1]); + jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP); + j = ((unsigned char *)&func3c) - (w.dst + 1 + 4); + jitCompPutOp_CALL_Relative(w.dst, j) + jitCompPutOp_ADD_GReg_Imm8(w.dst, IA32_REG4_ESP, 32); jitCompA000_loadRegCacheAll(&w); // 手抜き. jitCompA000_loadPRegCacheAll(&w); // 手抜き. cmp0reg = -1; @@ -1336,46 +1327,43 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr case 0x3d: /* LEAVE */ jitCompA000_storeRegCacheAll(&w); // 手抜き. jitCompA000_storePRegCacheAll(&w); // 手抜き. - jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ - jitCompPutByte1(w.dst, 0xe8); - j = ((unsigned char *)&func3d) - (w.dst + 4); - jitCompPutImm32(&w, j); - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */ + jitCompPutOp_PUSH_Imm8(w.dst, src[6]); + jitCompPutOp_PUSH_Imm8(w.dst, src[5]); + jitCompPutOp_PUSH_Imm8(w.dst, src[4] & 0x0f); + jitCompPutOp_PUSH_Imm8(w.dst, (src[4] >> 4) & 0x0f); + jitCompPutOp_PUSH_Imm8(w.dst, src[3]); + jitCompPutOp_PUSH_Imm8(w.dst, src[2]); + jitCompPutOp_PUSH_Imm8(w.dst, src[1]); + jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP); + j = ((unsigned char *)&func3d) - (w.dst + 1 + 4); + jitCompPutOp_CALL_Relative(w.dst, j) + jitCompPutOp_ADD_GReg_Imm8(w.dst, IA32_REG4_ESP, 32); jitCompA000_loadRegCacheAll(&w); // 手抜き. jitCompA000_loadPRegCacheAll(&w); // 手抜き. cmp0reg = -1; break; case 0xfe: /* remark */ - if (src[1] == 0x01 && src[2] == 0x00) { // DBGINFO1 + if (src[1] == 0x01 && src[2] == 0x00) { + // DBGINFO1 if (level <= JITC_LV_SLOWER) { - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, debugInfo1); - jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1); + jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX); } } - if (src[1] == 0x01 && src[2] == 0x03) { // DBGINFO1CLR + if (src[1] == 0x01 && src[2] == 0x03) { + // DBGINFO1CLR if (level <= JITC_LV_SLOWER) { - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, -1); - jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, -1); + jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX); } } - if (src[1] == 0x05 && src[2] == 0x00) { // DBGINFO0 + if (src[1] == 0x05 && src[2] == 0x00) { + // DBGINFO0 if (level <= JITC_LV_SLOWEST) { debugInfo0 = jitCompGetImm32(src + 3); - // jitCompPutByte1(w.dst, 0xbf); /* MOV(EDI, ?); */ - // jitCompPutImm32(&w, debugInfo0); - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, debugInfo0); - jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */ + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo0); + jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO0, IA32_REG0_EAX); } } break; @@ -1384,9 +1372,18 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr w.err = JITC_ERR_OPECODE; goto err_w; } - if (w.err != 0) goto err_w; + if (w.err != 0){ + goto err_w; + } jitCompA0001_fixPrefix(&w); - if (w.err != 0) goto err_w; + if (w.err != 0) { + goto err_w; + } + + if(*src != 0x00 && *src != 0x01 && *src != 0x34){ + DEBUGCode(&w, 315315); + } + src += jitCompCmdLen(src); } if (enter0 != NULL) { @@ -1399,16 +1396,18 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr if ((flags & JITC_NOSTARTUP) == 0) { jitCompA000_storeRegCacheAll(&w); jitCompA000_storePRegCacheAll(&w); - jitCompPutByte1(w.dst, 0x61); /* POPAD(); */ + jitCompPutOp_POPAD(w.dst); } - if ((flags & JITC_PHASE1) != 0) + if ((flags & JITC_PHASE1) != 0){ return w.dst - dst00; + } return 0; err_w: if ((w.err & JITC_ERR_PHASE0ONLY) != 0) { - if ((flags & JITC_PHASE1) == 0) + if ((flags & JITC_PHASE1) == 0){ w.err &= ~JITC_ERR_PHASE0ONLY; + } } if (w.err == (JITC_ERR_MASK & JITC_ERR_REGNUM)) errmsg = "reg-number error"; if (w.err == (JITC_ERR_MASK & JITC_ERR_DST1)) errmsg = "dst1 error"; @@ -1444,25 +1443,25 @@ err_w: unsigned char *jitCompCallFunc(unsigned char *dst, void *func) { + //この関数の中では結局w->dstしか参照していない struct JitCompWork w; w.dst = dst; jitCompA000_storeRegCacheAll(&w); jitCompA000_storePRegCacheAll(&w); - jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */ - jitCompPutByte1(w.dst, 0x50); /* PUSH(EAX); */ /* for 16byte-align(win32では不要なのだけど、MacOSには必要らしい) */ - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ - jitCompPutByte1(w.dst, 0xe8); /* CALL(func); */ - int j = ((unsigned char *)func) - (w.dst + 4); + jitCompPutOp_PUSHAD(w.dst); + jitCompPutOp_PUSH_GReg(w.dst, IA32_REG0_EAX); /* for 16Byte-align(Mac OSX) */ + jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP); - //この関数の中では結局w->dstしか参照していない - jitCompPutImm32(&w, j); + int j = ((unsigned char *)func) - (w.dst + 1 + 4); + jitCompPutOp_CALL_Relative(w.dst, j); - jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */ /* (win32では不要なのだけど、MacOSには必要らしい) */ - jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */ - jitCompPutByte1(w.dst, 0x61); /* POPAD(); */ + jitCompPutOp_POP_GReg(w.dst, IA32_REG0_EAX); + jitCompPutOp_POP_GReg(w.dst, IA32_REG0_EAX); /* for 16Byte-align (Mac OSX) */ + jitCompPutOp_POPAD(w.dst); jitCompA000_loadRegCacheAll(&w); jitCompA000_loadPRegCacheAll(&w); - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + 0x30 * 32 + 0); /* MOV(EAX, [EBP+?]); */ + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(0x30) + 0); + jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */ return w.dst; } @@ -1473,26 +1472,47 @@ unsigned char *jitCompInit(unsigned char *dst) return jitCompCallFunc(dst, &errHndl); } +void jitcRunBinary(void (*bin)(char *), HOSECPU_RuntimeEnvironment *env) +{ + (*bin)(((char *)env) + jitCompA0001_EBP128); /* サイズを節約するためにEBPをjitCompA0001_EBP128バイトずらす */ + return; +} + void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0) { HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128); int i, *pi; HOSECPU_PointerRegisterEntry *pp; - if (r->junkStack + 2048 > r->junkStack1) (*(r->errHndl))(r); - pi = (void *)r->junkStack; r->junkStack += r1 * 4; - for (i = 0; i < r1; i++) + + if (r->junkStack + 2048 > r->junkStack1) { + (*(r->errHndl))(r); + } + pi = (void *)r->junkStack; + r->junkStack += r1 * 4; + for (i = 0; i < r1; i++){ pi[i] = r->ireg[i]; - pp = (void *)r->junkStack; r->junkStack += p1 * 32; - for (i = 0; i < p1; i++) - pp[i] = r->preg[i]; - pp = (void *)r->junkStack; r->junkStack += 32; - *pp = r->preg[0x30]; - pi = (void *)r->junkStack; r->junkStack += 4; + } + pp = (void *)r->junkStack; + r->junkStack += p1 * 32; + for (i = 0; i < p1; i++){ + //pp[i] = r->preg[i]; + PRegCopy(&pp[i], &r->preg[i]); + // + } + pp = (void *)r->junkStack; + r->junkStack += 32; + //*pp = r->preg[0x30]; + PRegCopy(pp, &r->preg[0x30]); + // + pi = (void *)r->junkStack; + r->junkStack += 4; *pi = opt << 16 | r1 << 8 | p1; - for (i = 0; i < lenR; i++) + for (i = 0; i < lenR; i++){ r->ireg[r0 + i] = r->ireg[0x30 + i]; - for (i = 0; i < lenP; i++) + } + for (i = 0; i < lenP; i++){ r->preg[p0 + i] = r->preg[0x31 + i]; + } return; } @@ -1503,13 +1523,20 @@ void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int r->junkStack -= 4; r->junkStack -= 32; HOSECPU_PointerRegisterEntry *pp = (void *)r->junkStack; - r->preg[0x30] = *pp; + + //r->preg[0x30] = *pp; + PRegCopy(&r->preg[0x30], pp); + // r->junkStack -= p1 * 32; pp = (void *)r->junkStack; - for (i = 0; i < p1; i++) - r->preg[i] = pp[i]; + for (i = 0; i < p1; i++){ + //r->preg[i] = pp[i]; + PRegCopy(&r->preg[i], &pp[i]); + // + } r->junkStack -= r1 * 4; int *pi = (void *)r->junkStack; - for (i = 0; i < r1; i++) + for (i = 0; i < r1; i++){ r->ireg[i] = pi[i]; + } return; } @@ -1517,10 +1544,13 @@ void funcf4(char *ebp, int pxx, int typ, int len) { HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128); int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3; - if (width < 0 || r->ireg[len] < 0) + if (width < 0 || r->ireg[len] < 0){ (*(r->errHndl))(r); + } void *p = r->junkStack; - if (r->junkStack + width * r->ireg[len] + 256 > r->junkStack1) (*(r->errHndl))(r); + if (r->junkStack + width * r->ireg[len] + 256 > r->junkStack1){ + (*(r->errHndl))(r); + } r->junkStack += width * r->ireg[len]; r->preg[pxx].p = p; r->preg[pxx].typ = r->ireg[typ]; @@ -1532,8 +1562,9 @@ void funcf4(char *ebp, int pxx, int typ, int len) if (r->ireg[typ] == 1) { int i, i1 = (width * r->ireg[len]) >> 2; pi = p; - for (i = 0; i < i1; i++) + for (i = 0; i < i1; i++){ pi[i] = 0; + } } return; } @@ -1557,8 +1588,9 @@ void funcf6(char *ebp, int pxx, int typ, int len) { HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128); int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3; - if (width < 0 || r->ireg[len] < 0) + if (width < 0 || r->ireg[len] < 0){ (*(r->errHndl))(r); + } void *p = malloc(width * r->ireg[len]); r->preg[pxx].p = p; r->preg[pxx].typ = r->ireg[typ]; @@ -1567,10 +1599,12 @@ void funcf6(char *ebp, int pxx, int typ, int len) if (r->ireg[typ] == 1) { int i, i1 = (width * r->ireg[len]) >> 2, *pi; pi = p; - for (i = 0; i < i1; i++) + for (i = 0; i < i1; i++){ pi[i] = 0; - for (i = 1; i < i1; i += 8) + } + for (i = 1; i < i1; i += 8){ pi[i] |= -1; + } } return; } @@ -1604,26 +1638,34 @@ void errHndl(HOSECPU_RuntimeEnvironment *r) int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label) { unsigned char *q = *qq; - if (p0[0] != 0x05 || p0[1] != SIGN1) // OSECPUのヘッダ (05E1) を確認 + int i; + + if (p0[0] != 0x05 || p0[1] != SIGN1){ + // OSECPUのヘッダ (05E1) を確認 return 1; + } + + jitCompPutOp_PUSH_GReg(q, IA32_REG5_EBP); - *q++ = 0x55; /* PUSH(EBP); */ *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */ - int i; - for (i = 0; i < JITC_MAXLABELS; i++) + for (i = 0; i < JITC_MAXLABELS; i++){ label[i].opt = 0; + } // 以下のjitCompile()呼び出しでは第二引数をq1-2にした方がよいのではないか? i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, 0); - if (i != 0) return 2; + if (i != 0){ + return 2; + } i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, JITC_PHASE1 + 0); - if (i < 0) return 2; + if (i < 0){ + return 2; + } q += i; - *q++ = 0x5d; /* POP(EBP); */ + jitCompPutOp_POP_GReg(q, IA32_REG5_EBP); *q++ = 0xc3; /* RET(); */ - *qq = q; return 0; } @@ -1636,35 +1678,51 @@ int dbgrGetRegNum(const char *p) if (p[2] <= ' ') { i = p[0] - '0'; j = p[1] - '0'; - if (i > 9) i -= 'A' - '0' - 10; - if (j > 9) j -= 'A' - '0' - 10; - if (0 <= i && i <= 15 && 0 <= j && j <= 15) + if (i > 9){ + i -= 'A' - '0' - 10; + } + if (j > 9){ + j -= 'A' - '0' - 10; + } + if (0 <= i && i <= 15 && 0 <= j && j <= 15){ r = i << 4 | j; + } } return r; } void dbgrMain(HOSECPU_RuntimeEnvironment *r) { - if (r->dbgr == 0) return; + if (r->dbgr == 0){ + return; + } for (;;) { char cmd[64], *p; int i, j, k; + printf("\ndbgr>"); p = fgets(cmd, 64, stdin); - if (p == NULL) break; - if (cmd[0] == '\0') continue; - if (cmd[0] == 'q' && cmd[1] <= ' ') break; + if (p == NULL){ + break; + } + if (cmd[0] == '\0'){ + continue; + } + if (cmd[0] == 'q' && cmd[1] <= ' '){ + break; + } if (cmd[0] == 'p' && cmd[1] <= ' ' && cmd[1] != '\0') { p = &cmd[2]; - while (*p <= ' ' && *p != '\0') p++; + while (*p <= ' ' && *p != '\0'){ + p++; + } if (*p == 'R') { i = dbgrGetRegNum(p + 1); if (0 <= i && i <= 0x3f) { printf("R%02X = 0x%08X = %d\n", i, r->ireg[i], r->ireg[i]); - } - else + } else{ puts("register name error"); + } continue; } if (*p == 'P') { @@ -1685,7 +1743,9 @@ void dbgrMain(HOSECPU_RuntimeEnvironment *r) printf("P%02X:\n type = %s(%04X), (origin-ptr) = 0x%08X\n", i, p, r->preg[i].typ, (unsigned int)(r->preg[i].p0)); if (r->preg[i].p != NULL && r->preg[i].p0 != NULL) { j = jitCompA000_dataWidth(jitCompA000_convTyp(r->preg[i].typ)) >> 3; - if (j <= 0) j = 1; + if (j <= 0){ + j = 1; + } k = (r->preg[i].p1 - r->preg[i].p0) / j; printf(" size = 0x%08X = %d\n", k, k); k = (r->preg[i].p - r->preg[i].p0) / j;