//\r
// for x86-32bit\r
//\r
-int jitCompGetImm32(const unsigned char *src)\r
-{\r
- return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];\r
-}\r
-\r
-int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src)\r
-{\r
- int i = jitCompGetImm32(src);\r
- if (i < 0 || i >= w->maxLabels) {\r
- w->err = JITC_ERR_LABELNUM;\r
- i = 0;\r
- }\r
- return i;\r
-}\r
-\r
-void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n)\r
-{\r
- disp -= jitCompA0001_EBP128;\r
- if (-128 <= disp && disp <= 127) {\r
- jitCompPutByte2(w->dst, 0x45 | (n << 3), disp & 0xff);\r
- } else {\r
- // 10 + reg + 101 + disp\r
- jitCompPutByte1(w->dst, 0x85 | (n << 3));\r
- jitCompPutImm32(w->dst, disp);\r
- }\r
- return;\r
-}\r
-\r
-void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32)\r
-{\r
- // MOV Ev, Gv\r
- // MOV + ModR/M(2Mod + 3Reg + 3R/M)\r
- jitCompPutByte1(w->dst, 0x89); /* 1000 1001 MOV(mem, reg32); */\r
- jitCompA0001_85DispN(w, disp, reg32);\r
- return;\r
-}\r
-\r
-void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp)\r
-{\r
- jitCompPutByte1(w->dst, 0x8b); /* MOV(reg32, mem); */\r
- jitCompA0001_85DispN(w, disp, reg32);\r
- return;\r
-}\r
-\r
-void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)\r
-{\r
-#if (jitCompA0001_USE_R3F_IMM32 != 0)\r
- if (rxx == 0x3f) {\r
- jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */\r
- jitCompPutImm32(w->dst, w->r3f);\r
- return;\r
- }\r
-#endif\r
- if (rxx >= 0x40 || rxx < 0){\r
- w->err = JITC_ERR_REGNUM;\r
- }\r
- jitCompA0001_movReg32EbpDisp(w, IA32_REG0_EAX, rxx * 4); /* MOV(EAX, [EBP+?]); */\r
- return;\r
-}\r
-\r
-void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx)\r
-{\r
- if (rxx >= 0x40 || rxx < 0){\r
- w->err = JITC_ERR_REGNUM;\r
- }\r
- jitCompA0001_movEbpDispReg32(w, rxx * 4, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */\r
- return;\r
-}\r
-\r
-void jitCompA0001_fixPrefix(struct JitCompWork *w)\r
-{\r
- if (w->prefix != 0) {\r
- if (w->dst - w->dst0 > 127){\r
- w->err = JITC_ERR_REGNUM;\r
- }\r
- w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff);\r
- }\r
- return;\r
-}\r
-\r
-void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1)\r
-{\r
- if (p0 >= 0x3f || p0 < 0){\r
- w->err = JITC_ERR_PREGNUM;\r
- }\r
- if (p1 >= 0x3f || p1 < 0){\r
- w->err = JITC_ERR_PREGNUM;\r
- }\r
- /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */\r
- return;\r
-}\r
-\r
-void jitCompA000_loadRegCacheAll(struct JitCompWork *w)\r
-{\r
- jitCompA0001_movReg32EbpDisp(w, 3 /* EBX */, 0 * 4); /* EBX = R00; */\r
- jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */\r
- jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */\r
- return;\r
-}\r
-\r
-void jitCompA000_storeRegCacheAll(struct JitCompWork *w)\r
-{\r
- jitCompA0001_movEbpDispReg32(w, 0 * 4, 3 /* EBX */); /* R00 = EBX; */\r
- jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */\r
- jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */\r
- return;\r
-}\r
-\r
-void jitCompA000_loadRegCacheEcx(struct JitCompWork *w)\r
-{\r
- jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */\r
- return;\r
-}\r
-\r
-void jitCompA000_storeRegCacheEcx(struct JitCompWork *w)\r
-{\r
- jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */\r
- return;\r
-}\r
-\r
-void jitCompA000_loadRegCacheEdx(struct JitCompWork *w)\r
-{\r
- jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */\r
- return;\r
-}\r
-\r
-void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)\r
-{\r
- jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */\r
- return;\r
-}\r
-\r
-int jitCompA000_selectRegCache(int rxx, int reg)\r
-{\r
- switch (rxx) {\r
- case 0:\r
- //EBX\r
- reg = 3;\r
- break;\r
- case 1:\r
- //ECX\r
- reg = 1;\r
- break;\r
- case 2:\r
- //EDX\r
- reg = 2;\r
- break;\r
- }\r
- return reg;\r
-}\r
-\r
-void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)\r
-{\r
- // jitCompA0001_movReg32EbpDisp(w, 5 /* EBP */, 256 + 0 * 32 + 0); /* EBP = P00; */\r
- jitCompA0001_movReg32EbpDisp(w, 6 /* ESI */, 256 + 1 * 32 + 0); /* ESI = P01; */\r
- jitCompA0001_movReg32EbpDisp(w, 7 /* EDI */, 256 + 2 * 32 + 0); /* EDI = P02; */\r
- return;\r
-}\r
-\r
-void jitCompA000_storePRegCacheAll(struct JitCompWork *w)\r
-{\r
- // jitCompA0001_movEbpDispReg32(w, 256 + 0 * 32 + 0, 5 /* EBP */); /* P00 = EBP; */\r
- jitCompA0001_movEbpDispReg32(w, 256 + 1 * 32 + 0, 6 /* ESI */); /* P01 = ESI; */\r
- jitCompA0001_movEbpDispReg32(w, 256 + 2 * 32 + 0, 7 /* EDI */); /* P02 = EDI; */\r
- return;\r
-}\r
-\r
-int jitCompA000_selectPRegCache(int pxx, int reg)\r
-{\r
- // if (pxx == 0) reg = 5; /* EBP */\r
- switch (pxx) {\r
- case 1:\r
- //ESI\r
- reg = 6;\r
- break;\r
- \r
- case 2:\r
- //EDI\r
- reg = 7;\r
- break;\r
- }\r
- return reg;\r
-}\r
-\r
-int jitCompA000_convTyp(int t)\r
-{\r
- int r = -1;\r
- \r
- if (1 <= t && t <= 7){\r
- r = t;\r
- } else if (8 <= t && t <= 13){\r
- r = 2 | (t & 1);\r
- } else if (14 <= t && t <= 15){\r
- r = 4 | (t & 1);\r
- } else if (16 <= t && t <= 21){\r
- r = 6 | (t & 1);\r
- }\r
- return r;\r
-}\r
-\r
-int jitCompA000_dataWidth(int t)\r
-{\r
- int r = -1;\r
- if (t == 0x0001) r = 256;\r
- t >>= 1;\r
- if (t == 0x0002 / 2) r = 8;\r
- if (t == 0x0004 / 2) r = 16;\r
- if (t == 0x0006 / 2) r = 32;\r
- if (t == 0x0008 / 2) r = 4;\r
- if (t == 0x000a / 2) r = 2;\r
- if (t == 0x000c / 2) r = 1;\r
- if (t == 0x000e / 2) r = 12;\r
- if (t == 0x0010 / 2) r = 20;\r
- if (t == 0x0012 / 2) r = 24;\r
- if (t == 0x0014 / 2) r = 28;\r
- return r;\r
-}\r
-\r
-static unsigned char *errfnc;\r
-\r
-void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac)\r
-{\r
- if (typ <= 0) { w->err = JITC_ERR_BADTYPE; }\r
- if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; }\r
- jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, 256 + pxx * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */\r
- jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */\r
- jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */\r
- jitCompPutImm32(w->dst, errfnc - (w->dst + 4));\r
- return;\r
-}\r
-\r
-void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac)\r
-// data用.\r
-// 将来的にはaliveやアクセス権チェックも入れる\r
-{\r
- jitCompA0001_checkType0(w, pxx, typ, ac);\r
- return;\r
-}\r
-\r
-void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx)\r
-{\r
- jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */\r
- jitCompA0001_85DispN(w, 256 + pxx * 32 + 8, reg); /* p0 */\r
- jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */\r
- jitCompPutImm32(w->dst, errfnc - (w->dst + 4));\r
- jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */\r
- jitCompA0001_85DispN(w, 256 + pxx * 32 + 12, reg); /* p1 */\r
- jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */\r
- jitCompPutImm32(w->dst, errfnc - (w->dst + 4));\r
- return;\r
-}\r
\r
// F5の場合、decoderが対応するalloc-freeを結びつけるのが簡単で、typやlenを指定必須にしてもフロントエンドコードに影響はない.\r
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)\r
jitCompA000_loadPRegCacheAll(&w);\r
}\r
if (level <= JITC_LV_SLOWER) {\r
- // XOR(EAX, EAX);\r
- jitCompPutByte2(w.dst, 0x31, 0xc0);\r
+ // debugInfo0 <- 0;\r
+ // \r
+ jitCompPutOp_MOV_EAX_ZERO(w.dst);\r
// MOV(debugInfo0, EAX);\r
jitCompA0001_movEbpDispReg32(&w, envOffset_DBGINFO0, IA32_REG0_EAX);\r
- // MOV(EAX, ?);\r
- jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, imm32); */\r
- jitCompPutImm32(w.dst, debugInfo1);\r
+ jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1);\r
jitCompA0001_movEbpDispReg32(&w, envOffset_DBGINFO1, IA32_REG0_EAX); /* MOV(debugInfo1, EAX); */\r
}\r
while (src < src1) {\r
w.prefix = 0; //0x04 CND 命令で変更される\r
- if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; goto err_w; } // 書き込み領域が残り256バイト未満ならエラー\r
+ if (w.dst + 256 > dst1) {\r
+ // 書き込み領域が残り256バイト未満ならエラー\r
+ w.err = JITC_ERR_DST1; goto err_w;\r
+ }\r
timecount++;\r
if (timecount >= 64) {\r
timecount -= 64;\r
/* 未完成(timeoutチェックコードを入れる) */\r
}\r
- prefix_continue: // CND命令実行後ここに戻る\r
+ prefix_continue:\r
+ // CND命令コンパイル後ここに戻る\r
switch (*src) {\r
- \r
- case 0x00: /* NOP */\r
- if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } // 「条件付きでNOPを実行」するなんて、矛盾している!\r
+ case 0x00:\r
+ // NOP\r
+ if (w.prefix != 0) {\r
+ // 「条件付きでNOPを実行」するなんて、矛盾している!\r
+ w.err = JITC_ERR_PREFIX; goto err_w;\r
+ }\r
break;\r
\r
- case 0x01: /* LB */\r
- \r
- /*\r
- * LB : ラベル設置命令。(6byte)\r
- * ・prefex = 1にする\r
- * ・timecount++し、timecountのチェックをする。\r
- * ・ラベル位置を登録する。\r
- * ・割り込みがある場合、このタイミングで割り込みを発生させる。\r
- *\r
- * 1 2 3 456\r
- * LB 01 opt imm32\r
- *\r
- */\r
- \r
+ case 0x01:\r
+ // LB : ラベル設置命令。(6byte)\r
+ // ・prefex = 1にする\r
+ // ・timecount++し、timecountのチェックをする。\r
+ // ・ラベル位置を登録する。\r
+ // ・割り込みがある場合、このタイミングで割り込みを発生させる。\r
+ //\r
+ // 1 2 3 456\r
+ // LB 01 opt imm32\r
+ //\r
if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) { //beginFunc()中のLB\r
// LB命令の後に0x3C命令・・・beginFunc()\r
jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする\r
enter0 = w.dst;\r
jitCompPutImm32(w.dst, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ??\r
}\r
- if (src[6] == 0x34) { // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令\r
+ if (src[6] == 0x34) {\r
+ // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令\r
tmp_ucp = w.dst;\r
jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする\r
i = jitCompGetImm32(&src[7]); // type32 を取得\r
if (i != 1) {\r
i = jitCompA000_convTyp(i);\r
j = 0;\r
- if (i == 2 || i == 3) { j = 1; }\r
- if (i == 4 || i == 5) { j = 2; }\r
- if (i == 6 || i == 7) { j = 4; }\r
+ switch (i) {\r
+ case 2:\r
+ case 3:\r
+ j = 1;\r
+ break;\r
+ case 4:\r
+ case 5:\r
+ j = 2;\r
+ break;\r
+ case 6:\r
+ case 7:\r
+ j = 4;\r
+ break;\r
+ }\r
}\r
j *= jitCompGetImm32(&src[11]);\r
if (j <= 0) w.err = JITC_ERR_BADTYPE;\r
}\r
if ((flags & JITC_PHASE1) == 0) {\r
i = jitCompGetLabelNum(&w, src + 2);\r
- //printf("i=%06X %06X\n", i, src-src0);\r
- if (label[i].opt != 0 && w.err == 0) { w.err = JITC_ERR_LABELREDEF; goto err_w; }\r
- if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }\r
+ if (label[i].opt != 0 && w.err == 0) {\r
+ w.err = JITC_ERR_LABELREDEF;\r
+ goto err_w;\r
+ }\r
+ if (w.prefix != 0) {\r
+ w.err = JITC_ERR_PREFIX;\r
+ goto err_w;\r
+ }\r
label[i].opt = src[1] + 1;\r
label[i].typ = 0; /* TYP_CODE */\r
label[i].p = w.dst;\r
/* 未完成(timeoutチェックコードを入れる) */\r
break;\r
\r
- case 0x02: /* LIMM */\r
- \r
- /*\r
- * LIMM : 定数即値代入命令(6byte)\r
- *\r
- * 1 2 3456\r
- * 02 reg0R imm32\r
- *\r
- * ・reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。\r
- */\r
+ case 0x02:\r
+ // LIMM : 定数即値代入命令(6byte)\r
+ // 1 2 3456\r
+ // 02 reg0R imm32\r
+ //\r
+ // reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。\r
\r
- if (src[1] == 0x3f && w.prefix != 0) w.err = JITC_ERR_PREFIX; // CND命令の直後でR3Fを書き換えるなんて変だよね\r
+ if (src[1] == 0x3f && w.prefix != 0){\r
+ // CND命令の直後でR3Fを書き換えるなんて変だよね\r
+ w.err = JITC_ERR_PREFIX;\r
+ }\r
\r
#if (jitCompA0001_USE_R3F_IMM32 != 0)\r
- if (src[1] == 0x3f) { // R3Fへの代入は例外敵に、 w.r3f を使用\r
+ if (src[1] == 0x3f) {\r
+ // R3Fへの代入は例外で、 w.r3f を使用\r
w.r3f = jitCompGetImm32(src + 2);\r
break;\r
}\r
#endif\r
i = jitCompGetImm32(src + 2); // 与えられた即値(第二引数)を取得\r
- \r
/* R00-R02 なら EBX, ECX, EDX 、それ以外なら EAX のレジスタIDを reg0 に代入 */\r
reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);\r
- \r
+\r
#if (jitCompA0001_OPTIMIZE_MOV != 0)\r
+ // size optimization\r
+ // MOV reg, 0 -> XOR reg, reg\r
if (i == 0) {\r
- jitCompPutByte2(w.dst, 0x31, 0xc0 | reg0 << 3 | reg0); /* XOR(reg0, reg0); */\r
+ jitCompPutOp_XOR_GReg_GReg(w.dst, reg0, reg0);\r
jitCompA0001_movRxxEax(&w, src[1]);\r
break;\r
}\r
#endif\r
- \r
/* reg0 のレジスタに対応したMOV命令を発行 */\r
- jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); == 10111000b+wr imm32 */\r
- jitCompPutImm32(w.dst, i);\r
+ jitCompPutOp_MOV_GReg_Imm32(w.dst, reg0, i);\r
\r
- if (reg0 == 0) // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合\r
- \r
+ if (reg0 == 0){\r
+ // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合\r
jitCompA0001_movRxxEax(&w, src[1]);\r
- break;\r
+ }\r
\r
- case 0x03: /* PLIMM */ /* 未完成(plsまで対応) */\r
+ break;\r
\r
- /*\r
- * PLIMM : ラベル番号代入命令(6byte)\r
- *\r
- * 1 2 3456\r
- * 03 PXX imm32\r
- *\r
- * ・P28 はAPI用\r
- * ・P30 はリターンアドレス\r
- * ・P3F はプログラムカウンタ\r
- */\r
+ case 0x03: /* 未完成(plsまで対応) */\r
+ // PLIMM : ラベル番号代入命令(6byte)\r
+ //\r
+ // 1 2 3456\r
+ // 03 PXX imm32\r
+ //\r
+ // ・P28 はAPI用\r
+ // ・P30 はリターンアドレス\r
+ // ・P3F はプログラムカウンタ\r
+ //\r
\r
i = jitCompGetLabelNum(&w, src + 2); // Pxxに代入するラベルの番号(第二引数)\r
- if ((flags & JITC_PHASE1) != 0 && w.err == 0) { // Phase 1であるならば\r
- if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } // 指定されたラベル番号は存在しない\r
- if (src[1] != 0x3f && label[i].opt != 2) { w.err = JITC_ERR_LABELTYP; goto err_w; } //\r
- if (src[1] == 0x3f && label[i].typ != 0) { w.err = JITC_ERR_LABELTYP; goto err_w; } // プログラムカウンタに TYP_CODEでない値は代入できない\r
+ if ((flags & JITC_PHASE1) != 0 && w.err == 0) {\r
+ // Phase 1であるならば\r
+ if (label[i].opt == 0) {\r
+ // 指定されたラベル番号は存在しない\r
+ w.err = JITC_ERR_LABELNODEF;\r
+ goto err_w;\r
+ }\r
+ if (src[1] != 0x3f && label[i].opt != 2) {\r
+ // ?\r
+ w.err = JITC_ERR_LABELTYP;\r
+ goto err_w;\r
+ }\r
+ if (src[1] == 0x3f && label[i].typ != 0) {\r
+ // プログラムカウンタに TYP_CODEでない値は代入できない\r
+ w.err = JITC_ERR_LABELTYP;\r
+ goto err_w;\r
+ }\r
}\r
- if (src[1] == 0x3f) { // プログラムカウンタへの代入なら\r
- if (w.prefix == 0) { // CND命令による条件付きでなければ、即座に移動\r
+ if (src[1] == 0x3f) {\r
+ // プログラムカウンタへの代入\r
+ if (w.prefix == 0) {\r
+ // CND命令による条件付きでなければ、即座に移動\r
jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */\r
- }\r
- else { // 直前はCND命令。\r
+ } else {\r
+ // 直前はCND命令。\r
\r
/*\r
* CND命令\r
* いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd\r
*/\r
\r
- // JZのとび先アドレスの書き換え?\r
+ // Jccの条件変更\r
+ // 0F 75\r
w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */\r
w.dst[-2] = 0x0f;\r
\r
jitCompPutByte1(w.dst, j & 0xff);\r
}\r
#endif\r
- }\r
- else { // プログラムカウンタ以外への代入\r
+ } else { // プログラムカウンタ以外への代入\r
\r
// 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定\r
reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX);\r
}\r
break;\r
\r
- case 0x04: /* CND (prefix) */\r
- \r
- /*\r
- * CND命令\r
- * 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。\r
- */\r
- \r
- if (src[1] >= 0x40) w.err = JITC_ERR_REGNUM; // R00-R3F 以外のレジスタは比較対象にできない\r
+ case 0x04:\r
+ // CND (prefix)\r
+ // 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。\r
+ //\r
+ if (src[1] >= 0x40){\r
+ // R00-R3F 以外のレジスタは比較対象にできない\r
+ w.err = JITC_ERR_REGNUM;\r
+ goto err_w;\r
+ }\r
\r
// 比較対象のレジスタがメモリ上にあれば-1, それ以外なら適切なレジスタ番号を返す\r
reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */);\r
--- /dev/null
+#include "osecpu.h"\r
+#include "jitc.h"\r
+\r
+#if (JITC_ARCNUM == 0x0001)\r
+//\r
+// for x86-32bit\r
+//\r
+int jitCompGetImm32(const unsigned char *src)\r
+{\r
+ return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];\r
+}\r
+\r
+int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src)\r
+{\r
+ int i = jitCompGetImm32(src);\r
+ if (i < 0 || i >= w->maxLabels) {\r
+ w->err = JITC_ERR_LABELNUM;\r
+ i = 0;\r
+ }\r
+ return i;\r
+}\r
+\r
+void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n)\r
+{\r
+ disp -= jitCompA0001_EBP128;\r
+ if (-128 <= disp && disp <= 127) {\r
+ jitCompPutByte2(w->dst, 0x45 | (n << 3), disp & 0xff);\r
+ } else {\r
+ // 10 + reg + 101 + disp\r
+ jitCompPutByte1(w->dst, 0x85 | (n << 3));\r
+ jitCompPutImm32(w->dst, disp);\r
+ }\r
+ return;\r
+}\r
+\r
+void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32)\r
+{\r
+ // MOV Ev, Gv\r
+ // MOV + ModR/M(2Mod + 3Reg + 3R/M)\r
+ jitCompPutByte1(w->dst, 0x89); /* 1000 1001 MOV(mem, reg32); */\r
+ jitCompA0001_85DispN(w, disp, reg32);\r
+ return;\r
+}\r
+\r
+void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp)\r
+{\r
+ jitCompPutByte1(w->dst, 0x8b); /* MOV(reg32, mem); */\r
+ jitCompA0001_85DispN(w, disp, reg32);\r
+ return;\r
+}\r
+\r
+void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)\r
+{\r
+#if (jitCompA0001_USE_R3F_IMM32 != 0)\r
+ if (rxx == 0x3f) {\r
+ jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */\r
+ jitCompPutImm32(w->dst, w->r3f);\r
+ return;\r
+ }\r
+#endif\r
+ if (rxx >= 0x40 || rxx < 0){\r
+ w->err = JITC_ERR_REGNUM;\r
+ }\r
+ jitCompA0001_movReg32EbpDisp(w, IA32_REG0_EAX, rxx * 4); /* MOV(EAX, [EBP+?]); */\r
+ return;\r
+}\r
+\r
+void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx)\r
+{\r
+ if (rxx >= 0x40 || rxx < 0){\r
+ w->err = JITC_ERR_REGNUM;\r
+ }\r
+ jitCompA0001_movEbpDispReg32(w, rxx * 4, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */\r
+ return;\r
+}\r
+\r
+void jitCompA0001_fixPrefix(struct JitCompWork *w)\r
+{\r
+ if (w->prefix != 0) {\r
+ if (w->dst - w->dst0 > 127){\r
+ w->err = JITC_ERR_REGNUM;\r
+ }\r
+ w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff);\r
+ }\r
+ return;\r
+}\r
+\r
+void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1)\r
+{\r
+ if (p0 >= 0x3f || p0 < 0){\r
+ w->err = JITC_ERR_PREGNUM;\r
+ }\r
+ if (p1 >= 0x3f || p1 < 0){\r
+ w->err = JITC_ERR_PREGNUM;\r
+ }\r
+ /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */\r
+ return;\r
+}\r
+\r
+void jitCompA000_loadRegCacheAll(struct JitCompWork *w)\r
+{\r
+ jitCompA0001_movReg32EbpDisp(w, 3 /* EBX */, 0 * 4); /* EBX = R00; */\r
+ jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */\r
+ jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_storeRegCacheAll(struct JitCompWork *w)\r
+{\r
+ jitCompA0001_movEbpDispReg32(w, 0 * 4, 3 /* EBX */); /* R00 = EBX; */\r
+ jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */\r
+ jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_loadRegCacheEcx(struct JitCompWork *w)\r
+{\r
+ jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_storeRegCacheEcx(struct JitCompWork *w)\r
+{\r
+ jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_loadRegCacheEdx(struct JitCompWork *w)\r
+{\r
+ jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)\r
+{\r
+ jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */\r
+ return;\r
+}\r
+\r
+int jitCompA000_selectRegCache(int rxx, int reg)\r
+{\r
+ switch (rxx) {\r
+ case 0:\r
+ //EBX\r
+ reg = 3;\r
+ break;\r
+ case 1:\r
+ //ECX\r
+ reg = 1;\r
+ break;\r
+ case 2:\r
+ //EDX\r
+ reg = 2;\r
+ break;\r
+ }\r
+ return reg;\r
+}\r
+\r
+void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)\r
+{\r
+ // jitCompA0001_movReg32EbpDisp(w, 5 /* EBP */, 256 + 0 * 32 + 0); /* EBP = P00; */\r
+ jitCompA0001_movReg32EbpDisp(w, 6 /* ESI */, 256 + 1 * 32 + 0); /* ESI = P01; */\r
+ jitCompA0001_movReg32EbpDisp(w, 7 /* EDI */, 256 + 2 * 32 + 0); /* EDI = P02; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_storePRegCacheAll(struct JitCompWork *w)\r
+{\r
+ // jitCompA0001_movEbpDispReg32(w, 256 + 0 * 32 + 0, 5 /* EBP */); /* P00 = EBP; */\r
+ jitCompA0001_movEbpDispReg32(w, 256 + 1 * 32 + 0, 6 /* ESI */); /* P01 = ESI; */\r
+ jitCompA0001_movEbpDispReg32(w, 256 + 2 * 32 + 0, 7 /* EDI */); /* P02 = EDI; */\r
+ return;\r
+}\r
+\r
+int jitCompA000_selectPRegCache(int pxx, int reg)\r
+{\r
+ // if (pxx == 0) reg = 5; /* EBP */\r
+ switch (pxx) {\r
+ case 1:\r
+ //ESI\r
+ reg = 6;\r
+ break;\r
+ \r
+ case 2:\r
+ //EDI\r
+ reg = 7;\r
+ break;\r
+ }\r
+ return reg;\r
+}\r
+\r
+int jitCompA000_convTyp(int t)\r
+{\r
+ int r = -1;\r
+ \r
+ if (1 <= t && t <= 7){\r
+ r = t;\r
+ } else if (8 <= t && t <= 13){\r
+ r = 2 | (t & 1);\r
+ } else if (14 <= t && t <= 15){\r
+ r = 4 | (t & 1);\r
+ } else if (16 <= t && t <= 21){\r
+ r = 6 | (t & 1);\r
+ }\r
+ return r;\r
+}\r
+\r
+int jitCompA000_dataWidth(int t)\r
+{\r
+ int r = -1;\r
+ if (t == 0x0001) r = 256;\r
+ t >>= 1;\r
+ if (t == 0x0002 / 2) r = 8;\r
+ if (t == 0x0004 / 2) r = 16;\r
+ if (t == 0x0006 / 2) r = 32;\r
+ if (t == 0x0008 / 2) r = 4;\r
+ if (t == 0x000a / 2) r = 2;\r
+ if (t == 0x000c / 2) r = 1;\r
+ if (t == 0x000e / 2) r = 12;\r
+ if (t == 0x0010 / 2) r = 20;\r
+ if (t == 0x0012 / 2) r = 24;\r
+ if (t == 0x0014 / 2) r = 28;\r
+ return r;\r
+}\r
+\r
+unsigned char *errfnc;\r
+\r
+void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac)\r
+{\r
+ if (typ <= 0) { w->err = JITC_ERR_BADTYPE; }\r
+ if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; }\r
+ jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, 256 + pxx * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */\r
+ jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */\r
+ jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */\r
+ jitCompPutImm32(w->dst, errfnc - (w->dst + 4));\r
+ return;\r
+}\r
+\r
+void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac)\r
+// data用.\r
+// 将来的にはaliveやアクセス権チェックも入れる\r
+{\r
+ jitCompA0001_checkType0(w, pxx, typ, ac);\r
+ return;\r
+}\r
+\r
+void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx)\r
+{\r
+ jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */\r
+ jitCompA0001_85DispN(w, 256 + pxx * 32 + 8, reg); /* p0 */\r
+ jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */\r
+ jitCompPutImm32(w->dst, errfnc - (w->dst + 4));\r
+ jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */\r
+ jitCompA0001_85DispN(w, 256 + pxx * 32 + 12, reg); /* p1 */\r
+ jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */\r
+ jitCompPutImm32(w->dst, errfnc - (w->dst + 4));\r
+ return;\r
+}\r
+\r
+#endif\r