From 0adf6a795f229e7fcb65a2bbbce31f5813a820b4 Mon Sep 17 00:00:00 2001 From: hikarupsp Date: Sun, 16 Mar 2014 16:23:48 +0900 Subject: [PATCH] =?utf8?q?JITC=E3=81=AE=E3=82=BD=E3=83=BC=E3=82=B9?= =?utf8?q?=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- jitc.h | 8 +- jitcx86.c | 697 +++++++++++++++++++++++++++++++++++++++---------------------- jitcx86a.c | 16 +- main.c | 686 ++++++++++++++++++++++++++++++------------------------------ osecpu.h | 8 +- 5 files changed, 812 insertions(+), 603 deletions(-) diff --git a/jitc.h b/jitc.h index b45308d..59e3360 100644 --- a/jitc.h +++ b/jitc.h @@ -61,6 +61,8 @@ int jitCompCmdLen(const unsigned char *src); // #define envOffset_DBGINFO0 (2304 + 0) #define envOffset_DBGINFO1 (2304 + 4) +#define envOffset_PTRCTRL (2320) +#define PRegOffset(regid) (256 + 32 * regid) // #define jitCompPutImm32(p, i) jitCompPutByte4(p, ((i) & 0xff), (((i) >> 8) & 0xff), (((i) >> 16) & 0xff), (((i) >> 24) & 0xff)) // @@ -72,7 +74,9 @@ int jitCompCmdLen(const unsigned char *src); #define jitCompPutOp_PUSH_GReg(p, reg) jitCompPutByte1(p, 0x50 | (reg)); #define jitCompPutOp_PUSH_Imm8(p, i) jitCompPutByte2(p, 0x6a, i); #define jitCompPutOp_POP_GReg(p, reg) jitCompPutByte1(p, 0x58 | (reg)); -#define jitCompPutOp_CALL_Relative(p, diff) jitCompPutByte1(p, 0xe8); jitCompPutImm32(p, j); +#define jitCompPutOp_CALL_Relative(p, diff) jitCompPutByte1(p, 0xe8); jitCompPutImm32(p, diff); /*次の命令との相対オフセットだけ相対コールする*/ +#define jitCompPutOp_JMPnear(p, diff) jitCompPutByte1(p, 0xe9); jitCompPutImm32(p, diff); /*次の命令との相対オフセットだけ相対ジャンプする*/ +#define jitCompPutOp_JMPshort(p, diff) jitCompPutByte2(p, 0xeb, diff & 0xff);/*次の命令との相対オフセットだけ相対ジャンプする*/ // #define jitCompPutOp_MOV_EAX_ZERO(p) jitCompPutOp_XOR_GReg_GReg(p, IA32_REG0_EAX, IA32_REG0_EAX); @@ -86,7 +90,7 @@ int jitCompCmdLen(const unsigned char *src); #define jitCompA0001_OPTIMIZE_JMP 1*1 #define jitCompA0001_OPTIMIZE_MOV 1*1 /* 1にすると速度低下する? */ #define jitCompA0001_OPTIMIZE_CMP 1*1 -#define jitCompA0001_OPTIMIZE_ALIGN 4*1 /* 0-8を想定 */ +#define jitCompA0001_OPTIMIZE_ALIGN 8 /* 0-8を想定 */ #define jitCompA0001_EBP128 128*1 struct JitCompWork { diff --git a/jitcx86.c b/jitcx86.c index b916500..f9a4ee5 100644 --- a/jitcx86.c +++ b/jitcx86.c @@ -23,6 +23,7 @@ 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; @@ -77,14 +78,12 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr // 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.dst, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ?? + enter0 = w.dst + 1; + 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 を取得 j = 32; if (i != 1) { @@ -106,19 +105,27 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr } } j *= jitCompGetImm32(&src[11]); - if (j <= 0) w.err = JITC_ERR_BADTYPE; - jitCompPutImm32(w.dst, j); + if (j <= 0){ + w.err = JITC_ERR_BADTYPE; + } + jitCompPutOp_JMPnear(w.dst, j); #if (jitCompA0001_OPTIMIZE_JMP != 0) 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) + // アラインを jitCompA0001_OPTIMIZE_ALIGNにそろえる for (;;) { i = ((int)w.dst) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */ - if (i == 0) break; + if (i == 0){ + // Already alligned. + 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); */ @@ -263,8 +270,7 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr j += 3; w.dst -= 5; jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */ - } - else { + } else { j += 4; w.dst -= 6; jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0); @@ -273,28 +279,25 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr } #endif } else { // プログラムカウンタ以外への代入 - // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定 reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX); - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ - jitCompPutImm32(w.dst, (int)label[i].p); // ラベルのパスを各レジスタに代入 - - // レジスタへの代入をメモリでエミュレーションする場合は、スタックに積む。 - if (reg0 == 0) - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32, IA32_REG0_EAX); /* MOV([EBP+?], 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) { - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 8, reg0); /* MOV([EBP+?], reg0); */ /* p0 */ - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(w.dst, label[i].typ); - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 4, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ /* typ */ - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(w.dst, (int)label[i].p1); - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 12, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ /* p1 */ + 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, 256 + src[1] * 32 + 16, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ /* liveSign */ - jitCompPutOp_MOV_GReg_EBPDisp(&w, 0, 2320); /* MOV(EAX, ptrCtrl); */ - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 20, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ /* pls */ + 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; @@ -313,19 +316,22 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */); /* TEST命令を発行 */ - if (reg0 < 0) { //比較対象のレジスタはメモリ上にある - jitCompPutByte1(w.dst, 0xf7); /* TEST([EBP+?],1); */ + 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(reg0,1); */ + } else { + // 比較対象はキャッシュレジスタ上にある + jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST = 1111 011w : 11 000 reg : immediate data */ } 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; @@ -333,21 +339,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], IA32_REG0_EAX); reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX); - if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX) + if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX){ reg1 = IA32_REG0_EAX; - if (reg1 == IA32_REG2_EDX) + } + if (reg1 == IA32_REG2_EDX){ jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompPutOp_MOV_GReg_EBPDisp(&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: @@ -369,31 +381,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], IA32_REG0_EAX); reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX); - if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX) + if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX){ reg1 = IA32_REG0_EAX; - if (reg1 == IA32_REG2_EDX) + } + if (reg1 == IA32_REG2_EDX){ jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompPutOp_MOV_GReg_EBPDisp(&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) { @@ -412,13 +433,16 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr default: w.err = JITC_ERR_BADTYPE; } - if (reg1 == IA32_REG2_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; @@ -432,21 +456,26 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr jitCompA000_storePRegCacheAll(&w); reg1 = IA32_REG2_EDX; } - if (reg1 == IA32_REG2_EDX) + if (reg1 == IA32_REG2_EDX){ jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompPutOp_MOV_GReg_EBPDisp(&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 == IA32_REG0_EAX) - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 0, IA32_REG0_EAX); /* 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+?]); */ - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ } - if (reg1 == IA32_REG2_EDX) + if (reg1 == IA32_REG2_EDX){ jitCompA000_loadRegCacheEdx(&w); + } break; case 0x0b: /* PSMEM */ /* 完成 */ @@ -461,17 +490,21 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr /* これをやってはいけない!(by K, 2013.08.02) */ // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) // reg1 = 0; /* EAX */ - if (reg1 == IA32_REG2_EDX) + if (reg1 == IA32_REG2_EDX){ jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompPutOp_MOV_GReg_EBPDisp(&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 == IA32_REG0_EAX) - jitCompPutOp_MOV_GReg_EBPDisp(&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) { - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_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 == IA32_REG2_EDX) @@ -485,61 +518,76 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr } reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX); reg1 = jitCompA000_selectPRegCache(src[6], -1 /* mem */); - if (reg1 < 0 /* mem */) - jitCompPutOp_MOV_GReg_EBPDisp(&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.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+?]); */ 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) + 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); */ } @@ -550,12 +598,13 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr #if (jitCompA0001_USE_R3F_IMM32 != 0) padd1: #endif - if (reg0 == IA32_REG0_EAX) - jitCompPutOp_MOV_EBPDisp_GReg(&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) { - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ - jitCompPutOp_MOV_EBPDisp_GReg(&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; @@ -565,20 +614,26 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); jitCompA000_storePRegCacheAll(&w); // 手抜き. jitCompA0001_checkCompPtr(&w, src[6], src[7]); - jitCompPutOp_MOV_GReg_EBPDisp(&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+?]); */ - jitCompPutModRM_Disp_BaseEBP(&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 */ @@ -587,21 +642,27 @@ 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; + 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.dst, w.r3f); jitCompPutByte1(w.dst, 0x2b); jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); - if (reg0 == 0) + if (reg0 == 0){ jitCompA0001_movRxxEax(&w, src[1]); + } break; } #endif @@ -615,31 +676,36 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr // 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 @@ -648,21 +714,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 == 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); @@ -672,58 +739,72 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr } } jitCompPutImm32(w.dst, w.r3f); - if (reg0 == 0) + 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]); 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); 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], IA32_REG0_EAX); reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; - if (reg1 == -1) + 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 { + } 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 == IA32_REG0_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; @@ -735,15 +816,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr if (src[2] == 0x3f) { jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ jitCompPutImm32(w.dst, w.r3f); - } - else { + } 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]; @@ -752,23 +838,21 @@ 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.dst, w.r3f); - } - else { + } 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.dst, w.r3f); - } - else { + } else{ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, src[2] * 4); /* MOV(EAX, [EBP+?]); */ } #else @@ -778,15 +862,21 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr jitCompPutByte1(w.dst, 0x99); /* CDQ(); */ /* ECXがゼロではないことを確認すべき */ jitCompPutByte2(w.dst, 0xf7, 0xf9); /* IDIV(ECX); */ - 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); } + 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) { @@ -800,20 +890,23 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr } 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) { - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, 256 + src[2] * 32 + i); /* MOV(EAX, [EBP+?]); */ - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + i, IA32_REG0_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) { - jitCompPutOp_MOV_GReg_EBPDisp(&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.dst, errfnc - (w.dst + 4)); @@ -821,10 +914,10 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr } reg0 = IA32_REG0_EAX; jitCompA000_storePRegCacheAll(&w); // 手抜き. - jitCompPutOp_MOV_GReg_EBPDisp(&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+?]); */ - jitCompPutModRM_Disp_BaseEBP(&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.dst, errfnc - (w.dst + 4)); } @@ -834,20 +927,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) { - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_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.dst, 0x80000000); } - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + i, IA32_REG0_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.dst, debugInfo1); - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 28, IA32_REG0_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; @@ -855,20 +948,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) { - jitCompPutOp_MOV_GReg_EBPDisp(&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.dst, 0x7fffffff); } - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ } if (level < JITC_LV_FASTER) { - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_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.dst, debugInfo1); jitCompPutByte2(w.dst, 0x74, 8); /* JE */ - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); (2) */ - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 0, IA32_REG0_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; @@ -889,9 +982,13 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr 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) @@ -902,10 +999,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); */ @@ -922,29 +1021,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.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); } + 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 */ @@ -956,12 +1074,16 @@ 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.dst, j); #if (jitCompA0001_OPTIMIZE_JMP != 0) if (-128 - 4 <= j && j < 0) { @@ -971,7 +1093,9 @@ 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 @@ -980,8 +1104,9 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr 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; @@ -994,21 +1119,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]); - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_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+?]); */ - jitCompPutModRM_Disp_BaseEBP(&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); */ } @@ -1051,13 +1182,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr case 0x34: /* data (暫定) */ cmp0reg = -1; - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } + 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 (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 = jitCompGetImm32(&src[5]); oldsrc = src; @@ -1065,8 +1203,16 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr 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) { + w.err = JITC_ERR_DST1; + src = oldsrc; + goto err_w; + } tmpData = 0; for (k = 0; k < dataWidth; k++) { tmpData = tmpData << 1 | ((*src >> bitCount) & 1); @@ -1079,34 +1225,51 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr if ((i & 1) == 0 && dataWidth <= 31 && (tmpData >> (dataWidth - 1)) != 0) { 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) { + 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); + } j--; } - } - else { + } else{ 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) { + 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; } + if (label[i].opt == 0) { + w.err = JITC_ERR_LABELNODEF; + goto err_w; + } } 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, 2320); /* pls */ + 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 */ @@ -1148,28 +1311,26 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr 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.dst, debugInfo1); - jitCompPutOp_MOV_EBPDisp_GReg(&w, 2304 + 4, IA32_REG0_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.dst, -1); - jitCompPutOp_MOV_EBPDisp_GReg(&w, 2304 + 4, IA32_REG0_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.dst, debugInfo0); - jitCompPutOp_MOV_EBPDisp_GReg(&w, 2304 + 0, IA32_REG0_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; @@ -1178,9 +1339,13 @@ 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; + } src += jitCompCmdLen(src); } if (enter0 != NULL) { @@ -1193,16 +1358,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"; @@ -1255,7 +1422,8 @@ unsigned char *jitCompCallFunc(unsigned char *dst, void *func) jitCompPutOp_POPAD(w.dst); jitCompA000_loadRegCacheAll(&w); jitCompA000_loadPRegCacheAll(&w); - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_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; } @@ -1271,21 +1439,32 @@ void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int 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 = (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 = (void *)r->junkStack; + r->junkStack += 32; *pp = r->preg[0x30]; - pi = (void *)r->junkStack; r->junkStack += 4; + 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; } @@ -1310,10 +1489,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]; @@ -1325,8 +1507,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; } @@ -1350,8 +1533,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]; @@ -1360,10 +1544,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; } @@ -1405,6 +1591,7 @@ int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const } jitCompPutOp_PUSH_GReg(q, IA32_REG5_EBP); + *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */ for (i = 0; i < JITC_MAXLABELS; i++){ @@ -1436,35 +1623,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') { @@ -1485,7 +1688,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; diff --git a/jitcx86a.c b/jitcx86a.c index 4044493..ef06215 100644 --- a/jitcx86a.c +++ b/jitcx86a.c @@ -166,17 +166,15 @@ int jitCompA000_selectRegCache(int rxx, int reg) void jitCompA000_loadPRegCacheAll(struct JitCompWork *w) { - // jitCompPutOp_MOV_GReg_EBPDisp(w, 5 /* EBP */, 256 + 0 * 32 + 0); /* EBP = P00; */ - jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG6_ESI, 256 + 1 * 32 + 0); /* ESI = P01; */ - jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG7_EDI, 256 + 2 * 32 + 0); /* EDI = P02; */ + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG6_ESI, PRegOffset(0x01) + 0); /* ESI = P01; */ + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG7_EDI, PRegOffset(0x02) + 0); /* EDI = P02; */ return; } void jitCompA000_storePRegCacheAll(struct JitCompWork *w) { - // jitCompPutOp_MOV_EBPDisp_GReg(w, 256 + 0 * 32 + 0, 5 /* EBP */); /* P00 = EBP; */ - jitCompPutOp_MOV_EBPDisp_GReg(w, 256 + 1 * 32 + 0, IA32_REG6_ESI); /* P01 = ESI; */ - jitCompPutOp_MOV_EBPDisp_GReg(w, 256 + 2 * 32 + 0, IA32_REG7_EDI); /* P02 = EDI; */ + jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x01) + 0, IA32_REG6_ESI); /* P01 = ESI; */ + jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x02) + 0, IA32_REG7_EDI); /* P02 = EDI; */ return; } @@ -237,7 +235,7 @@ 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; } - jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, 256 + pxx * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, PRegOffset(pxx) + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */ jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */ jitCompPutImm32(w->dst, errfnc - (w->dst + 4)); @@ -255,11 +253,11 @@ void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac) void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx) { jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ - jitCompPutModRM_Disp_BaseEBP(w, 256 + pxx * 32 + 8, reg); /* p0 */ + jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 8, reg); /* p0 */ jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */ jitCompPutImm32(w->dst, errfnc - (w->dst + 4)); jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ - jitCompPutModRM_Disp_BaseEBP(w, 256 + pxx * 32 + 12, reg); /* p1 */ + jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 12, reg); /* p1 */ jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */ jitCompPutImm32(w->dst, errfnc - (w->dst + 4)); return; diff --git a/main.c b/main.c index 722b546..785bf03 100644 --- a/main.c +++ b/main.c @@ -1,343 +1,343 @@ -#include "osecpu.h" - -int *keybuf, keybuf_r, keybuf_w, keybuf_c; -HOSECPU_Device_Window mainWindow; -//デバッグ用。プログラム中の随所で加算される変数 -int di1_serial; - - - -unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory); -void LoadAppBin(HOSECPU_RuntimeEnvironment *env); - -void putKeybuf(int i) -{ - if (keybuf_c < KEYBUFSIZ) { - keybuf[keybuf_w] = i; - keybuf_c++; - keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1); - } - return; -} - -int HeavyOSECPUMain(int argc, char **argv) -{ - FILE *fp; - unsigned char *jitbuf, *sysjit00, *sysjit; - unsigned char *systmp0, *systmp1, *systmp2; - unsigned char *opTbl; - HOSECPU_LabelListTag *label; - int tmpsiz, i; - double tm0, tm1, tm2; - HOSECPU_PointerControlTag *ptrCtrl; - unsigned char *syslib; - int argDebug = 0, stacksiz = 1; - const char *cp; - HOSECPU_RuntimeEnvironment env; - void(*jitfunc)(char *); - unsigned char *jp; - - //Initialize mainWindow - mainWindow.vram = NULL; - mainWindow.xsize = 0; - mainWindow.ysize = 0; - di1_serial = 0; - - //実行環境初期化 - env.mainArgc = argc; - env.mainArgv = (const char **)argv; - env.appBin = malloc(APPSIZ1); - env.executionLevel = JITC_LV_SLOWEST; - jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */ - //unsigned char *sysjit0 = mallocRWE(SJITSIZ1), *sysjit1 = sysjit0, *sysjit00 = sysjit0; - // syslib.oseのjitc結果を格納する領域を確保。 - sysjit00 = mallocRWE(SJITSIZ1); - sysjit = sysjit00; - // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス - // sysjit: 現在のjitc書き込み位置 - // sysjit00: jitc結果の先頭 - //ワークメモリを三つくらいもらう - systmp0 = malloc(SYSTMP0SIZ); /* syslibのjitc用 */ - systmp1 = malloc(SYSTMP1SIZ); - systmp2 = malloc(1024 * 1024); - - opTbl = malloc(256); - label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag)); - keybuf = malloc(KEYBUFSIZ * sizeof (int)); - keybuf_r = keybuf_w = keybuf_c = 0; - ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag)); - - randStatInit((unsigned int)time(NULL)); - for (i = 0; i < PTRCTRLSIZ; i++) { - ptrCtrl[i].liveSign = 0; - ptrCtrl[i].size = -1; - } - ptrCtrl[0].size = -2; - - /* syslibの読み込み */ - syslib = Init_LoadSysLib(argv[0], systmp0); - - sysjit = jitCompInit(sysjit); - sysjit00 = sysjit; - // labelはjitc0()内で初期化される。 - i = jitc0(&sysjit, sysjit00 + SJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label); - if (i != 0){ - fputs("syslib-file JITC error.\n", stderr); - return 1; - } - - // エラー時にデバッグ用に表示する変数を加算 - di1_serial++; - - /* アプリバイナリの読み込み */ - LoadAppBin(&env); - - /* クロック初期化 */ - tm0 = clock() / (double)CLOCKS_PER_SEC; - - if (env.appBin[2] == 0xf0) { - // tek5圧縮がかかっている -#if (USE_TEK5 != 0) - env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0); - env.appSize1 += 2; -#else - env.appSize1 = -9; -#endif - if (env.appSize1 < 0) { - fputs("unsupported-format(tek5)\n", stderr); - return 1; - } - } - //デバッグモード指定 - cp = searchArg(argc, (const char **)argv, "debug:", 0); - if (cp != NULL){ - argDebug = *cp - '0'; - } - //スタックサイズ指定(MiB単位) - cp = searchArg(argc, (const char **)argv, "stack:", 0); - if (cp != NULL){ - stacksiz = strtol(cp, NULL, 0); - } - - // jitbufは先頭。 jpは現在位置 - jp = jitbuf; /* JIT-pointer */ - - /* フロントエンドコードをバックエンドコードに変換する */ - if ((env.appBin[2] & 0xf0) != 0) { // 3バイト目が00なら処理しない - systmp0[0] = env.appBin[0]; - systmp0[1] = env.appBin[1]; - env.preg[2].p = systmp0 + 2; - env.preg[3].p = systmp0 + SYSTMP0SIZ; - env.preg[4].p = env.appBin + 2; - env.preg[5].p = env.appBin + env.appSize1; - env.preg[6].p = systmp1; - env.preg[7].p = systmp1 + SYSTMP1SIZ; - env.preg[10].p = systmp2; - int pxxFlag[64], typLabel[4096]; - env.preg[0x0b].p = (void *)pxxFlag; - env.preg[0x0c].p = (void *)typLabel; - env.preg[0x0d].p = opTbl; - jitfunc = (void *)sysjit00; - (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ - if (env.ireg[0] != 0) { - jp = env.preg[2].p - 1; - fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]); - if ((argDebug & 2) != 0) { - fp = fopen("debug2.bin", "wb"); - fwrite(systmp0, 1, jp - systmp0 + 16, fp); - fclose(fp); - } - exit(1); - } - tmpsiz = env.preg[2].p - systmp0; - } else{ - memcpy(systmp0, env.appBin, env.appSize1); - tmpsiz = env.appSize1; - } - - if ((argDebug & 2) != 0) { - /*変換後のバックエンドコードをファイルへ保存*/ - fp = fopen("debug2.bin", "wb"); - fwrite(systmp0, 1, tmpsiz, fp); - fclose(fp); - } - - //JITコンパイル - i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label); - if (i == 1){ - fputs("app-file header error.\n", stderr); - return 1; - } - if (i != 0){ - return 1; - } - di1_serial++; - - int appsiz2 = jp - jitbuf; - - unsigned char *p28 = jp; - jp = jitCompCallFunc(jp, &devFunc); - - tm1 = clock() / (double)CLOCKS_PER_SEC; - - /* レジスタ初期化 */ - for (i = 0; i < 64; i++){ - env.ireg[i] = 0; - } - for (i = 0; i < 64; i++) { - env.preg[i].p = NULL; - env.preg[i].typ = -1; - env.preg[i].p0 = NULL; - env.preg[i].p1 = NULL; - } - - env.buf0 = env.buf1 = NULL; - - // p28にapiをコールするアドレスを設定 - env.preg[0x28].p = p28; // p28には、devFuncをコールするコードが書かれている - env.preg[0x28].typ = 0; // TYP_CODE - env.preg[0x28].p0 = p28; // アドレス演算できる範囲を制限 - env.preg[0x28].p1 = p28 + 1; // アドレス演算できる範囲を制限 - - //env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32); - env.junkStack = malloc(stacksiz << 20); - env.junkStack1 = env.junkStack + (stacksiz << 20); - env.winClosed = 0; - env.autoSleep = 0; - env.lastConsoleChar = '\n'; - - env.label = label; - env.maxLabels = JITC_MAXLABELS; - env.jitbuf = jp; - env.jitbuf1 = jitbuf + 1024 * 1024; - env.errHndl = &errorHandler; - env.appReturnCode = 0; - - env.dbgr = 0; - if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){ - env.dbgr = 1; - } - - if ((argDebug & 1) != 0) { - fp = fopen("debug1.bin", "wb"); - fwrite(jitbuf, 1, jp - jitbuf, fp); - fclose(fp); - } - - /* JITコード実行 */ - jitfunc = (void *)jitbuf; - if (setjmp(env.setjmpEnv) == 0){ - (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ - } - if (env.autoSleep != 0) { - if (mainWindow.vram != NULL){ - drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0); - } - while (env.winClosed == 0){ - drv_sleep(100); - } - } - if (env.lastConsoleChar != '\n'){ - putchar('\n'); - } - - tm2 = clock() / (double)CLOCKS_PER_SEC; - - /* 実行結果確認のためのレジスタダンプ */ - if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) { - printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1); - printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2); - printf("result:\n"); - printf("R00:0x%08X R01:0x%08X R02:0x%08X R03:0x%08X\n", env.ireg[0], env.ireg[1], env.ireg[2], env.ireg[3]); - } -#if (USE_DEBUGGER != 0) - dbgrMain(&env); -#endif - return env.appReturnCode; -} - -unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory) -{ - unsigned char *syslib; - FILE *fp; - unsigned char *up; - int appsize; - - /* syslibの読み込み */ - syslib = malloc(SYSLIBSIZ1); - fp = fopen(SYSLIB_OSE, "rb"); - if (fp == NULL) { - syslib[0] = '/'; - strcpy((char *)syslib + 1, argv0); - up = syslib + 1; - while (*up != '\0'){ - up++; - } - while (*up != '/' && *up != 0x5c){ - up--; - } - up++; - strcpy((char *)up, SYSLIB_OSE); - fp = fopen((char *)syslib + 1, "rb"); - } - if (fp == NULL) { - fputs("syslib-file fopen error.\n", stderr); - exit(EXIT_FAILURE); - } - appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp); - fclose(fp); - if (appsize >= SYSLIBSIZ1 - 4) { - fputs("syslib-file too large.\n", stderr); - exit(EXIT_FAILURE); - } - if (syslib[0] == 0x05 && syslib[1] == 0xc1) { - // maklib のライブラリ形式である。 - memcpy(tmpWorkMemory, syslib, appsize); - ComLib_main(tmpWorkMemory + 2, syslib + 2); - syslib[0] = 0x05; - syslib[1] = 0x1b; - } - - fp = fopen("syslib_dbg.ose", "wb"); - fwrite(syslib, 1, SYSLIBSIZ1, fp); - fclose(fp); - return syslib; -} - -void LoadAppBin(HOSECPU_RuntimeEnvironment *env) -{ - FILE *fp; - const char *fileName; - /* アプリバイナリの読み込み */ - if (env->mainArgc <= 1) { - //アプリ名未指定なので何事もなく終了 - exit(EXIT_SUCCESS); - } - fileName = env->mainArgv[1]; - //アプリ名先頭に:n:をつけることでレベルnでの実行が可能? - if (fileName[0] == ':' && fileName[2] == ':') { - env->executionLevel = fileName[1] - '0'; - if (env->executionLevel < 0 || env->executionLevel > 9){ - env->executionLevel = JITC_LV_SLOWEST; - } - fileName += 3; - } - - fp = fopen(fileName, "rb"); - if (fp == NULL) { - fputs("app-file load error.\n", stderr); - exit(EXIT_FAILURE); - } - env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp); - env->appSize1 = env->appSize0; - fclose(fp); - - if (env->appSize0 >= APPSIZ1 - 4) { - fputs("app-file too large.\n", stderr); - exit(EXIT_FAILURE); - } - if (env->appSize0 < 3) { - fputs("app-file header error.\n", stderr); - exit(EXIT_FAILURE); - } -} +#include "osecpu.h" + +int *keybuf, keybuf_r, keybuf_w, keybuf_c; +HOSECPU_Device_Window mainWindow; +//デバッグ用。プログラム中の随所で加算される変数 +int di1_serial; + + + +unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory); +void LoadAppBin(HOSECPU_RuntimeEnvironment *env); + +void putKeybuf(int i) +{ + if (keybuf_c < KEYBUFSIZ) { + keybuf[keybuf_w] = i; + keybuf_c++; + keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1); + } + return; +} + +int HeavyOSECPUMain(int argc, char **argv) +{ + FILE *fp; + unsigned char *jitbuf, *sysjit00, *sysjit; + unsigned char *systmp0, *systmp1, *systmp2; + unsigned char *opTbl; + HOSECPU_LabelListTag *label; + int tmpsiz, i; + double tm0, tm1, tm2; + HOSECPU_PointerControlTag *ptrCtrl; + unsigned char *syslib; + int argDebug = 0, stacksiz = 1; + const char *cp; + HOSECPU_RuntimeEnvironment env; + void(*jitfunc)(char *); + unsigned char *jp; + + //Initialize mainWindow + mainWindow.vram = NULL; + mainWindow.xsize = 0; + mainWindow.ysize = 0; + di1_serial = 0; + + //実行環境初期化 + env.mainArgc = argc; + env.mainArgv = (const char **)argv; + env.appBin = malloc(APPSIZ1); + env.executionLevel = JITC_LV_SLOWEST; + jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */ + //unsigned char *sysjit0 = mallocRWE(SJITSIZ1), *sysjit1 = sysjit0, *sysjit00 = sysjit0; + // syslib.oseのjitc結果を格納する領域を確保。 + sysjit00 = mallocRWE(SJITSIZ1); + sysjit = sysjit00; + // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス + // sysjit: 現在のjitc書き込み位置 + // sysjit00: jitc結果の先頭 + //ワークメモリを三つくらいもらう + systmp0 = malloc(SYSTMP0SIZ); /* syslibのjitc用 */ + systmp1 = malloc(SYSTMP1SIZ); + systmp2 = malloc(1024 * 1024); + + opTbl = malloc(256); + label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag)); + keybuf = malloc(KEYBUFSIZ * sizeof (int)); + keybuf_r = keybuf_w = keybuf_c = 0; + ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag)); + + randStatInit((unsigned int)time(NULL)); + for (i = 0; i < PTRCTRLSIZ; i++) { + ptrCtrl[i].liveSign = 0; + ptrCtrl[i].size = -1; + } + ptrCtrl[0].size = -2; + + /* syslibの読み込み */ + syslib = Init_LoadSysLib(argv[0], systmp0); + + sysjit = jitCompInit(sysjit); + sysjit00 = sysjit; + // labelはjitc0()内で初期化される。 + i = jitc0(&sysjit, sysjit00 + SJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label); + if (i != 0){ + fputs("syslib-file JITC error.\n", stderr); + return 1; + } + + // エラー時にデバッグ用に表示する変数を加算 + di1_serial++; + + /* アプリバイナリの読み込み */ + LoadAppBin(&env); + + /* クロック初期化 */ + tm0 = clock() / (double)CLOCKS_PER_SEC; + + if (env.appBin[2] == 0xf0) { + // tek5圧縮がかかっている +#if (USE_TEK5 != 0) + env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0); + env.appSize1 += 2; +#else + env.appSize1 = -9; +#endif + if (env.appSize1 < 0) { + fputs("unsupported-format(tek5)\n", stderr); + return 1; + } + } + //デバッグモード指定 + cp = searchArg(argc, (const char **)argv, "debug:", 0); + if (cp != NULL){ + argDebug = *cp - '0'; + } + //スタックサイズ指定(MiB単位) + cp = searchArg(argc, (const char **)argv, "stack:", 0); + if (cp != NULL){ + stacksiz = strtol(cp, NULL, 0); + } + + // jitbufは先頭。 jpは現在位置 + jp = jitbuf; /* JIT-pointer */ + + /* フロントエンドコードをバックエンドコードに変換する */ + if ((env.appBin[2] & 0xf0) != 0) { // 3バイト目が00なら処理しない + systmp0[0] = env.appBin[0]; + systmp0[1] = env.appBin[1]; + env.preg[2].p = systmp0 + 2; + env.preg[3].p = systmp0 + SYSTMP0SIZ; + env.preg[4].p = env.appBin + 2; + env.preg[5].p = env.appBin + env.appSize1; + env.preg[6].p = systmp1; + env.preg[7].p = systmp1 + SYSTMP1SIZ; + env.preg[10].p = systmp2; + int pxxFlag[64], typLabel[4096]; + env.preg[0x0b].p = (void *)pxxFlag; + env.preg[0x0c].p = (void *)typLabel; + env.preg[0x0d].p = opTbl; + jitfunc = (void *)sysjit00; + (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ + if (env.ireg[0] != 0) { + jp = env.preg[2].p - 1; + fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]); + if ((argDebug & 2) != 0) { + fp = fopen("debug2.bin", "wb"); + fwrite(systmp0, 1, jp - systmp0 + 16, fp); + fclose(fp); + } + exit(1); + } + tmpsiz = env.preg[2].p - systmp0; + } else{ + memcpy(systmp0, env.appBin, env.appSize1); + tmpsiz = env.appSize1; + } + + if ((argDebug & 2) != 0) { + /*変換後のバックエンドコードをファイルへ保存*/ + fp = fopen("debug2.bin", "wb"); + fwrite(systmp0, 1, tmpsiz, fp); + fclose(fp); + } + + //JITコンパイル + i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label); + if (i == 1){ + fputs("app-file header error.\n", stderr); + return 1; + } + if (i != 0){ + return 1; + } + di1_serial++; + + int appsiz2 = jp - jitbuf; + + unsigned char *p28 = jp; + jp = jitCompCallFunc(jp, &devFunc); + + tm1 = clock() / (double)CLOCKS_PER_SEC; + + /* レジスタ初期化 */ + for (i = 0; i < 64; i++){ + env.ireg[i] = 0; + } + for (i = 0; i < 64; i++) { + env.preg[i].p = NULL; + env.preg[i].typ = -1; + env.preg[i].p0 = NULL; + env.preg[i].p1 = NULL; + } + + env.buf0 = env.buf1 = NULL; + + // p28にapiをコールするアドレスを設定 + env.preg[0x28].p = p28; // p28には、devFuncをコールするコードが書かれている + env.preg[0x28].typ = 0; // TYP_CODE + env.preg[0x28].p0 = p28; // アドレス演算できる範囲を制限 + env.preg[0x28].p1 = p28 + 1; // アドレス演算できる範囲を制限 + + //env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32); + env.junkStack = malloc(stacksiz << 20); + env.junkStack1 = env.junkStack + (stacksiz << 20); + env.winClosed = 0; + env.autoSleep = 0; + env.lastConsoleChar = '\n'; + + env.label = label; + env.maxLabels = JITC_MAXLABELS; + env.jitbuf = jp; + env.jitbuf1 = jitbuf + 1024 * 1024; + env.errHndl = &errorHandler; + env.appReturnCode = 0; + + env.dbgr = 0; + if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){ + env.dbgr = 1; + } + + if ((argDebug & 1) != 0) { + fp = fopen("debug1.bin", "wb"); + fwrite(jitbuf, 1, jp - jitbuf, fp); + fclose(fp); + } + + /* JITコード実行 */ + jitfunc = (void *)jitbuf; + if (setjmp(env.setjmpEnv) == 0){ + (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ + } + if (env.autoSleep != 0) { + if (mainWindow.vram != NULL){ + drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0); + } + while (env.winClosed == 0){ + drv_sleep(100); + } + } + if (env.lastConsoleChar != '\n'){ + putchar('\n'); + } + + tm2 = clock() / (double)CLOCKS_PER_SEC; + + /* 実行結果確認のためのレジスタダンプ */ + if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) { + printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1); + printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2); + printf("result:\n"); + printf("R00:0x%08X R01:0x%08X R02:0x%08X R03:0x%08X\n", env.ireg[0], env.ireg[1], env.ireg[2], env.ireg[3]); + } +#if (USE_DEBUGGER != 0) + dbgrMain(&env); +#endif + return env.appReturnCode; +} + +unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory) +{ + unsigned char *syslib; + FILE *fp; + unsigned char *up; + int appsize; + + /* syslibの読み込み */ + syslib = malloc(SYSLIBSIZ1); + fp = fopen(SYSLIB_OSE, "rb"); + if (fp == NULL) { + syslib[0] = '/'; + strcpy((char *)syslib + 1, argv0); + up = syslib + 1; + while (*up != '\0'){ + up++; + } + while (*up != '/' && *up != 0x5c){ + up--; + } + up++; + strcpy((char *)up, SYSLIB_OSE); + fp = fopen((char *)syslib + 1, "rb"); + } + if (fp == NULL) { + fputs("syslib-file fopen error.\n", stderr); + exit(EXIT_FAILURE); + } + appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp); + fclose(fp); + if (appsize >= SYSLIBSIZ1 - 4) { + fputs("syslib-file too large.\n", stderr); + exit(EXIT_FAILURE); + } + if (syslib[0] == 0x05 && syslib[1] == 0xc1) { + // maklib のライブラリ形式である。 + memcpy(tmpWorkMemory, syslib, appsize); + ComLib_main(tmpWorkMemory + 2, syslib + 2); + syslib[0] = 0x05; + syslib[1] = 0x1b; + } + + fp = fopen("syslib_dbg.ose", "wb"); + fwrite(syslib, 1, SYSLIBSIZ1, fp); + fclose(fp); + return syslib; +} + +void LoadAppBin(HOSECPU_RuntimeEnvironment *env) +{ + FILE *fp; + const char *fileName; + /* アプリバイナリの読み込み */ + if (env->mainArgc <= 1) { + //アプリ名未指定なので何事もなく終了 + exit(EXIT_SUCCESS); + } + fileName = env->mainArgv[1]; + //アプリ名先頭に:n:をつけることでレベルnでの実行が可能? + if (fileName[0] == ':' && fileName[2] == ':') { + env->executionLevel = fileName[1] - '0'; + if (env->executionLevel < 0 || env->executionLevel > 9){ + env->executionLevel = JITC_LV_SLOWEST; + } + fileName += 3; + } + + fp = fopen(fileName, "rb"); + if (fp == NULL) { + fputs("app-file load error.\n", stderr); + exit(EXIT_FAILURE); + } + env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp); + env->appSize1 = env->appSize0; + fclose(fp); + + if (env->appSize0 >= APPSIZ1 - 4) { + fputs("app-file too large.\n", stderr); + exit(EXIT_FAILURE); + } + if (env->appSize0 < 3) { + fputs("app-file header error.\n", stderr); + exit(EXIT_FAILURE); + } +} diff --git a/osecpu.h b/osecpu.h index 23844af..f0969b8 100644 --- a/osecpu.h +++ b/osecpu.h @@ -138,9 +138,9 @@ struct Regs { // int debugInfo0; // 2304 int debugInfo1; // 2308 - int dmy[2]; // 4 * 2 = 8 + int dmy[2]; // 2312, 2316 // - HOSECPU_PointerControlTag *ptrCtrl; + HOSECPU_PointerControlTag *ptrCtrl; // 2320 char winClosed, autoSleep; jmp_buf setjmpEnv; int appReturnCode; // アプリ自体の終了コード @@ -196,11 +196,13 @@ const char *searchArg(int argc, const char **argv, const char *tag, int i); // void devFunc(HOSECPU_RuntimeEnvironment *r); // junkApiを処理する関数 // @jitc.c +void errorHandler(HOSECPU_RuntimeEnvironment *r); + +// @jitcx86.c int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label); 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); unsigned char *jitCompCallFunc(unsigned char *dst, void *func); unsigned char *jitCompInit(unsigned char *dst); -void errorHandler(HOSECPU_RuntimeEnvironment *r); // @randmt.c void randStatInit(unsigned int seed); -- 2.11.0