-#include "osecpu.h"
-#include "jitc.h"
-
-#if (JITC_ARCNUM == 0x0001)
-//
-// for x86-32bit
-//
-int jitCompGetImm32(const unsigned char *src)
-{
- return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
-}
-
-int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src)
-{
- int i = jitCompGetImm32(src);
- if (i < 0 || i >= w->maxLabels) {
- w->err = JITC_ERR_LABELNUM;
- i = 0;
- }
- return i;
-}
-
-void jitCompPutModRM_Disp_BaseEBP(struct JitCompWork *w, int disp, int opReg)
-{
- // EBPをベースとするアドレスオペランドとレジスタオペランドを出力する
- disp -= jitCompA0001_EBP128;
- if (-128 <= disp && disp <= 127) {
- // [EBP + Disp08]
- jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_BYTE, opReg, IA32_REG5_EBP));
- jitCompPutByte1(w->dst, disp & 0xff);
- } else {
- // [EBP + Disp32]
- jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_FULL, opReg, IA32_REG5_EBP));
- jitCompPutImm32(w->dst, disp);
- }
- return;
-}
-
-void jitCompPutOp_MOV_EBPDisp_GReg(struct JitCompWork *w, int disp, int reg32)
-{
- // MOV([EBP + disp] <- reg32);
- // MOV Ev, Gv
- // [1000 100 1] [mod reg r/m]
- jitCompPutByte1(w->dst, 0x89);
- jitCompPutModRM_Disp_BaseEBP(w, disp, reg32);
- return;
-}
-
-void jitCompPutOp_MOV_GReg_EBPDisp(struct JitCompWork *w, int reg32, int disp)
-{
- // MOV (reg32 <- [EBP + disp])
- // MOV Gv, Ev
- // [1000 101 1] [mod reg r/m]
- jitCompPutByte1(w->dst, 0x8b);
- jitCompPutModRM_Disp_BaseEBP(w, disp, reg32);
- return;
-}
-
-void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)
-{
-#if (jitCompA0001_USE_R3F_IMM32 != 0)
- if (rxx == 0x3f) {
- jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */
- jitCompPutImm32(w->dst, w->r3f);
- return;
- }
-#endif
- if (rxx >= 0x40 || rxx < 0){
- w->err = JITC_ERR_REGNUM;
- }
- jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, rxx * 4);
- return;
-}
-
-void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx)
-{
- if (rxx >= 0x40 || rxx < 0){
- w->err = JITC_ERR_REGNUM;
- }
- jitCompPutOp_MOV_EBPDisp_GReg(w, rxx * 4, IA32_REG0_EAX);
- return;
-}
-
-void jitCompA0001_fixPrefix(struct JitCompWork *w)
-{
- if (w->prefix != 0) {
- if (w->dst - w->dst0 > 127){
- w->err = JITC_ERR_REGNUM;
- }
- w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff);
- }
- return;
-}
-
-void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1)
-{
- if (p0 >= 0x3f || p0 < 0){
- w->err = JITC_ERR_PREGNUM;
- }
- if (p1 >= 0x3f || p1 < 0){
- w->err = JITC_ERR_PREGNUM;
- }
- /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */
- return;
-}
-
-void jitCompA000_loadRegCacheAll(struct JitCompWork *w)
-{
- //保存されたレジスタキャッシュをメモリからロード
- jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG3_EBX, 4 * 0); /* EBX = R00; */
- jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 4 * 1); /* ECX = R01; */
- jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 4 * 2); /* EDX = R02; */
- return;
-}
-
-void jitCompA000_storeRegCacheAll(struct JitCompWork *w)
-{
- //レジスタキャッシュをメモリに退避
- jitCompPutOp_MOV_EBPDisp_GReg(w, 0 * 4, IA32_REG3_EBX); /* R00 = EBX; */
- jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */
- jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */
- return;
-}
-
-void jitCompA000_loadRegCacheEcx(struct JitCompWork *w)
-{
- jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 1 * 4); /* ECX = R01; */
- return;
-}
-
-void jitCompA000_storeRegCacheEcx(struct JitCompWork *w)
-{
- jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */
- return;
-}
-
-void jitCompA000_loadRegCacheEdx(struct JitCompWork *w)
-{
- jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 2 * 4); /* EDX = R02; */
- return;
-}
-
-void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)
-{
- jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */
- return;
-}
-
-int jitCompA000_selectRegCache(int rxx, int reg)
-{
- // OSECPUレジスタ番号をIA32レジスタ番号へ変換
- // 対応するキャッシュレジスタがない場合regが返る
- switch (rxx) {
- case 0:
- reg = IA32_REG3_EBX;
- break;
- case 1:
- reg = IA32_REG1_ECX;
- break;
- case 2:
- reg = IA32_REG2_EDX;
- break;
- }
- return reg;
-}
-
-void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)
-{
- 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, PRegOffset(0x01) + 0, IA32_REG6_ESI); /* P01 = ESI; */
- jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x02) + 0, IA32_REG7_EDI); /* P02 = EDI; */
- return;
-}
-
-int jitCompA000_selectPRegCache(int pxx, int reg)
-{
- // if (pxx == 0) reg = 5; /* EBP */
- switch (pxx) {
- case 1:
- //ESI
- reg = 6;
- break;
-
- case 2:
- //EDI
- reg = 7;
- break;
- }
- return reg;
-}
-
-int jitCompA000_convTyp(int t)
-{
- // 指定されたタイプのデータ幅を返す。
- // unsigned なら奇数(1bit目がOn)
- // retv = 1 : VPtr
- // retv = 2 or 3: BYTE ( 8, 4, 2, 1 bit)
- // retv = 4 or 5: WORD (16, 12 bit)
- // retv = 6 or 7: DWORD(32, 20, 24, 28 bit)
- // -1はエラー
- int r = -1;
-
- if (1 <= t && t <= 7){
- // 1 - 7はそのままでOK
- r = t;
- } else if (8 <= t && t <= 13){
- r = 2 | (t & 1);
- } else if (14 <= t && t <= 15){
- r = 4 | (t & 1);
- } else if (16 <= t && t <= 21){
- r = 6 | (t & 1);
- }
- return r;
-}
-
-int jitCompA000_dataWidth(int t)
-{
- // 指定されたタイプのビット数を返す
- int r = -1;
- if (t == 0x0001) r = 256;
- t >>= 1;
- if (t == 0x0002 / 2) r = 8;
- if (t == 0x0004 / 2) r = 16;
- if (t == 0x0006 / 2) r = 32;
- if (t == 0x0008 / 2) r = 4;
- if (t == 0x000a / 2) r = 2;
- if (t == 0x000c / 2) r = 1;
- if (t == 0x000e / 2) r = 12;
- if (t == 0x0010 / 2) r = 20;
- if (t == 0x0012 / 2) r = 24;
- if (t == 0x0014 / 2) r = 28;
- return r;
-}
-
-unsigned char *errfnc;
-
-void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac)
-{
- if (typ <= 0) { w->err = JITC_ERR_BADTYPE; }
- if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; }
- 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));
- return;
-}
-
-void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac)
-{
- // data用.
- // 将来的にはaliveやアクセス権チェックも入れる
- jitCompA0001_checkType0(w, pxx, typ, ac);
- return;
-}
-
-void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx)
-{
- jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */
- 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, PRegOffset(pxx) + 12, reg); /* p1 */
- jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */
- jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
- return;
-}
-
-#endif
+#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 jitCompPutModRM_Disp_BaseEBP(struct JitCompWork *w, int disp, int opReg)\r
+{\r
+ // EBPをベースとするアドレスオペランドとレジスタオペランドを出力する\r
+ disp -= jitCompA0001_EBP128;\r
+ if (-128 <= disp && disp <= 127) {\r
+ // [EBP + Disp08]\r
+ jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_BYTE, opReg, IA32_REG5_EBP));\r
+ jitCompPutByte1(w->dst, disp & 0xff);\r
+ } else {\r
+ // [EBP + Disp32]\r
+ jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_FULL, opReg, IA32_REG5_EBP));\r
+ jitCompPutImm32(w->dst, disp);\r
+ }\r
+ return;\r
+}\r
+\r
+void jitCompPutOp_MOV_EBPDisp_GReg(struct JitCompWork *w, int disp, int reg32)\r
+{\r
+ // MOV([EBP + disp] <- reg32);\r
+ // MOV Ev, Gv\r
+ // [1000 100 1] [mod reg r/m]\r
+ jitCompPutByte1(w->dst, 0x89);\r
+ jitCompPutModRM_Disp_BaseEBP(w, disp, reg32);\r
+ return;\r
+}\r
+\r
+void jitCompPutOp_MOV_GReg_EBPDisp(struct JitCompWork *w, int reg32, int disp)\r
+{\r
+ // MOV (reg32 <- [EBP + disp])\r
+ // MOV Gv, Ev\r
+ // [1000 101 1] [mod reg r/m]\r
+ jitCompPutByte1(w->dst, 0x8b);\r
+ jitCompPutModRM_Disp_BaseEBP(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
+ jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, rxx * 4);\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
+ jitCompPutOp_MOV_EBPDisp_GReg(w, rxx * 4, IA32_REG0_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
+ //保存されたレジスタキャッシュをメモリからロード\r
+ jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG3_EBX, 4 * 0); /* EBX = R00; */\r
+ jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 4 * 1); /* ECX = R01; */\r
+ jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 4 * 2); /* EDX = R02; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_storeRegCacheAll(struct JitCompWork *w)\r
+{\r
+ //レジスタキャッシュをメモリに退避\r
+ jitCompPutOp_MOV_EBPDisp_GReg(w, 0 * 4, IA32_REG3_EBX); /* R00 = EBX; */\r
+ jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */\r
+ jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_loadRegCacheEcx(struct JitCompWork *w)\r
+{\r
+ jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 1 * 4); /* ECX = R01; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_storeRegCacheEcx(struct JitCompWork *w)\r
+{\r
+ jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_loadRegCacheEdx(struct JitCompWork *w)\r
+{\r
+ jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 2 * 4); /* EDX = R02; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)\r
+{\r
+ jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */\r
+ return;\r
+}\r
+\r
+int jitCompA000_selectRegCache(int rxx, int reg)\r
+{\r
+ // OSECPUレジスタ番号をIA32レジスタ番号へ変換\r
+ // 対応するキャッシュレジスタがない場合regが返る\r
+ switch (rxx) {\r
+ case 0:\r
+ reg = IA32_REG3_EBX;\r
+ break;\r
+ case 1:\r
+ reg = IA32_REG1_ECX;\r
+ break;\r
+ case 2:\r
+ reg = IA32_REG2_EDX;\r
+ break;\r
+ }\r
+ return reg;\r
+}\r
+\r
+void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)\r
+{\r
+ jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG6_ESI, PRegOffset(0x01) + 0); /* ESI = P01; */\r
+ jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG7_EDI, PRegOffset(0x02) + 0); /* EDI = P02; */\r
+ return;\r
+}\r
+\r
+void jitCompA000_storePRegCacheAll(struct JitCompWork *w)\r
+{\r
+ jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x01) + 0, IA32_REG6_ESI); /* P01 = ESI; */\r
+ jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x02) + 0, IA32_REG7_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
+ // 指定されたタイプのデータ幅を返す。\r
+ // unsigned なら奇数(1bit目がOn)\r
+ // retv = 1 : VPtr\r
+ // retv = 2 or 3: BYTE ( 8, 4, 2, 1 bit)\r
+ // retv = 4 or 5: WORD (16, 12 bit)\r
+ // retv = 6 or 7: DWORD(32, 20, 24, 28 bit)\r
+ // -1はエラー\r
+ int r = -1;\r
+ \r
+ if (1 <= t && t <= 7){\r
+ // 1 - 7はそのままでOK\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
+ // 指定されたタイプのビット数を返す\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) {\r
+ w->err = JITC_ERR_BADTYPE;\r
+ }\r
+ if (typ > 0x7f) {\r
+ w->err = JITC_ERR_INTERNAL;\r
+ }\r
+ jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, PRegOffset(pxx) + 4); /* MOV(EAX, pReg[pxx].typ); */\r
+ jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, typ); */\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
+{\r
+ // data用.\r
+ // 将来的にはaliveやアクセス権チェックも入れる\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
+ jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 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
+ jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 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