OSDN Git Service

jitcx86.cを分割した。
authorhikarupsp <hikarupsp@users.sourceforge.jp>
Sat, 15 Mar 2014 06:32:33 +0000 (15:32 +0900)
committerhikarupsp <hikarupsp@users.sourceforge.jp>
Sat, 15 Mar 2014 06:32:33 +0000 (15:32 +0900)
jitc.h
jitcx86.c
jitcx86a.c [new file with mode: 0644]

diff --git a/jitc.h b/jitc.h
index 1ddcae8..7fc937a 100644 (file)
--- a/jitc.h
+++ b/jitc.h
@@ -2,6 +2,8 @@
 #ifndef HeavyOSECPU_jitc_h\r
 #define HeavyOSECPU_jitc_h\r
 \r
+\r
+\r
 // Error flags\r
 #define JITC_ERR_MASK                  255\r
 #define        JITC_ERR_PHASE0ONLY             256\r
@@ -52,12 +54,15 @@ int jitCompCmdLen(const unsigned char *src);
 #define envOffset_DBGINFO1             (2304 + 4)\r
 //\r
 #define jitCompPutImm32(p, i)                                  jitCompPutByte4(p, ((i) & 0xff), (((i) >> 8) & 0xff), (((i) >> 16) & 0xff), (((i) >> 24) & 0xff))\r
+#define jitCompPutOp_XOR_GReg_GReg(p, d, s)            jitCompPutByte2(w.dst, 0x31, 0xc0 | (s) << 3 | (d));\r
+#define jitCompPutOp_MOV_GReg_Imm32(p, dReg, i)        jitCompPutByte1(p, 0xb8 | dReg); jitCompPutImm32(p, i); /* MOV(reg0, ?);  == [1011 1 reg] imm32 */\r
 #define jitCompPutOp_PUSHAD(p)                                 jitCompPutByte1(p, 0x60);\r
 #define jitCompPutOp_POPAD(p)                                  jitCompPutByte1(p, 0x61);\r
 #define jitCompPutOp_PUSH_GReg(p, reg)                 jitCompPutByte1(p, 0x50 | (reg));\r
 #define jitCompPutOp_POP_GReg(p, reg)                  jitCompPutByte1(p, 0x58 | (reg));\r
 #define jitCompPutOp_CALL_Relative(p, diff)            jitCompPutByte1(w.dst, 0xe8); jitCompPutImm32(&w, j);\r
-\r
+//\r
+#define jitCompPutOp_MOV_EAX_ZERO(p)                           jitCompPutOp_XOR_GReg_GReg(p, IA32_REG0_EAX, IA32_REG0_EAX);\r
 \r
 // Optimization settings\r
 // 他のCPUへ移植する人へ:\r
@@ -81,6 +86,7 @@ struct JitCompWork {
        char prefix;    //CND命令の値を記録(初期値=0)\r
 };\r
 \r
+// @jitcx86a.c\r
 int jitCompGetImm32(const unsigned char *src);\r
 int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src);\r
 void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n);\r
@@ -105,6 +111,9 @@ int jitCompA000_dataWidth(int t);
 void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac);\r
 void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac);\r
 void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx);\r
+\r
+// @jitcx86.c\r
+extern unsigned char *errfnc;\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
 unsigned char *jitCompCallFunc(unsigned char *dst, void *func);\r
 unsigned char *jitCompInit(unsigned char *dst);\r
@@ -124,14 +133,6 @@ void dbgrMain(HOSECPU_RuntimeEnvironment *r);
 \r
 \r
 \r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
 #endif\r
 \r
 #endif\r
index 5c849af..3012629 100644 (file)
--- a/jitcx86.c
+++ b/jitcx86.c
@@ -5,257 +5,6 @@
 //\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
@@ -285,51 +34,54 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
                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
@@ -337,9 +89,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
                                        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
@@ -375,9 +138,14 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
                                }\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
@@ -389,71 +157,85 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
                                /* 未完成(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
@@ -463,7 +245,8 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
                                                 * いま、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
@@ -488,8 +271,7 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
                                                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
@@ -516,14 +298,15 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
                                }\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
diff --git a/jitcx86a.c b/jitcx86a.c
new file mode 100644 (file)
index 0000000..c33131c
--- /dev/null
@@ -0,0 +1,260 @@
+#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