X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=jitc.c;h=210e3dd57226331a37a0424477ae4801e1c10d52;hb=152bd3574280c5c7754983964bfd2eabc8fe0205;hp=98c4ec8b8cf66cde955abb2aa08c4463b47288c4;hpb=53a2ae5571cc5991f74e3f18144e32a7b0d88606;p=heavyosecpu%2FHeavyOSECPU.git diff --git a/jitc.c b/jitc.c index 98c4ec8..210e3dd 100644 --- a/jitc.c +++ b/jitc.c @@ -1,1667 +1,84 @@ -#include "osecpu.h" - -#define JITC_ERR_MASK 255 -#define JITC_ERR_PHASE0ONLY 256 -#define JITC_ERR_REGNUM (1 | JITC_ERR_PHASE0ONLY) -#define JITC_ERR_DST1 (2 | JITC_ERR_PHASE0ONLY) -#define JITC_ERR_OPECODE (3 | JITC_ERR_PHASE0ONLY) -#define JITC_ERR_LABELNUM (4 | JITC_ERR_PHASE0ONLY) -#define JITC_ERR_LABELREDEF (5 | JITC_ERR_PHASE0ONLY) -#define JITC_ERR_PREFIX (6 | JITC_ERR_PHASE0ONLY) -#define JITC_ERR_LABELNODEF 7 -#define JITC_ERR_LABELTYP 8 -#define JITC_ERR_IDIOM 9 -#define JITC_ERR_PREGNUM (10 | JITC_ERR_PHASE0ONLY) -#define JITC_ERR_SRC1 (11 | JITC_ERR_PHASE0ONLY) -#define JITC_ERR_BADTYPE (12 | JITC_ERR_PHASE0ONLY) -#define JITC_ERR_PREFIXFAR (13 | JITC_ERR_PHASE0ONLY) -#define JITC_ERR_INTERNAL 99 - -void errorHandler(struct Regs *r) -{ - puts("security error! abort..."); - printf("debugInfo0=%d, debugInfo1=%d¥n", r->debugInfo0, r->debugInfo1); -#if (USE_DEBUGGER != 0) - dbgrMain(r); -#endif - exit(1); -} - -int jitCompCmdLen(const unsigned char *src) -{ - int i = 1; - if (0x01 <= *src && *src < 0x04) i = 6; - if (*src == 0x04) i = 2; - if (0x08 <= *src && *src < 0x0d) i = 8 + src[7] * 4; - if (0x0e <= *src && *src < 0x10) i = 8; - if (0x10 <= *src && *src < 0x2e) i = 4; - if (0x1c <= *src && *src < 0x1f) i = 3; - if (*src == 0x1f) i = 11; - if (*src == 0x2f) i = 4 + src[1]; - if (0x30 <= *src && *src <= 0x33) i = 4; - if (0x3c <= *src && *src <= 0x3d) i = 7; - if (*src == 0xfe) i = 2 + src[1]; - return i; -} -#if (JITC_ARCNUM == 0x0001) /* x86-32bit */ - -/* 他のCPUへ移植する人へ: -以下は最適化のためのものなので、すべて0として簡単に移植しても問題ありません */ -#define jitCompA0001_USE_R3F_CMPJMP 1*1 -#define jitCompA0001_USE_R3F_IMM32 1*1 -#define jitCompA0001_USE_R3F_IMM8 1*1 -#define jitCompA0001_USE_R3F_INCDEC 1*1 -#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_EBP128 128*1 - -struct JitCompWork { - unsigned char *dst, *dst0; - int err, maxLabels; -#if (jitCompA0001_USE_R3F_IMM32 != 0) - int r3f; -#endif - char prefix; -}; - -#define jitCompPutByte1(p, c0) *p++ = c0 -#define jitCompPutByte2(p, c0, c1) *p++ = c0; *p++ = c1 -#define jitCompPutByte3(p, c0, c1, c2) *p++ = c0; *p++ = c1; *p++ = c2 -#define jitCompPutByte4(p, c0, c1, c2, c3) *p++ = c0; *p++ = c1; *p++ = c2; *p++ = c3 - -static void jitCompPutImm32(struct JitCompWork *w, int i) -{ - jitCompPutByte1(w->dst, i & 0xff); - jitCompPutByte1(w->dst, (i >> 8) & 0xff); - jitCompPutByte1(w->dst, (i >> 16) & 0xff); - jitCompPutByte1(w->dst, (i >> 24) & 0xff); - return; -} - -int jitCompGetImm32(const unsigned char *src) -{ - return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; -} - -int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src) -{ - int i = jitCompGetImm32(src); - if (i < 0 || i >= w->maxLabels) { - w->err = JITC_ERR_LABELNUM; - i = 0; - } - return i; -} - -void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n) -{ - disp -= jitCompA0001_EBP128; - if (-128 <= disp && disp <= 127) { - jitCompPutByte2(w->dst, 0x45 | (n << 3), disp & 0xff); - } - else { - jitCompPutByte1(w->dst, 0x85 | (n << 3)); - jitCompPutImm32(w, disp); - } - return; -} - -void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32) -{ - jitCompPutByte1(w->dst, 0x89); /* MOV(mem, reg32); */ - jitCompA0001_85DispN(w, disp, reg32); - return; -} - -void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp) -{ - jitCompPutByte1(w->dst, 0x8b); /* MOV(reg32, mem); */ - jitCompA0001_85DispN(w, disp, reg32); - return; -} - -void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx) -{ -#if (jitCompA0001_USE_R3F_IMM32 != 0) - if (rxx == 0x3f) { - jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(w, w->r3f); - return; - } -#endif - if (rxx >= 0x40 || rxx < 0) w->err = JITC_ERR_REGNUM; - jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, rxx * 4); /* MOV(EAX, [EBP+?]); */ - return; -} - -void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx) -{ - if (rxx >= 0x40 || rxx < 0) w->err = JITC_ERR_REGNUM; - jitCompA0001_movEbpDispReg32(w, rxx * 4, 0 /* EAX */); /* MOV([EBP+?], EAX); */ - return; -} - -void jitCompA0001_fixPrefix(struct JitCompWork *w) -{ - if (w->prefix != 0) { - if (w->dst - w->dst0 > 127) w->err = JITC_ERR_REGNUM; - w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff); - } - return; -} - -void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1) -{ - if (p0 >= 0x3f || p0 < 0) w->err = JITC_ERR_PREGNUM; - if (p1 >= 0x3f || p1 < 0) w->err = JITC_ERR_PREGNUM; - /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */ - return; -} - -void jitCompA000_loadRegCacheAll(struct JitCompWork *w) -{ - jitCompA0001_movReg32EbpDisp(w, 3 /* EBX */, 0 * 4); /* EBX = R00; */ - jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */ - jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */ - return; -} - -void jitCompA000_storeRegCacheAll(struct JitCompWork *w) -{ - jitCompA0001_movEbpDispReg32(w, 0 * 4, 3 /* EBX */); /* R00 = EBX; */ - jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */ - jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */ - return; -} - -void jitCompA000_loadRegCacheEcx(struct JitCompWork *w) -{ - jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */ - return; -} - -void jitCompA000_storeRegCacheEcx(struct JitCompWork *w) -{ - jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */ - return; -} - -void jitCompA000_loadRegCacheEdx(struct JitCompWork *w) -{ - jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */ - return; -} - -void jitCompA000_storeRegCacheEdx(struct JitCompWork *w) -{ - jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */ - return; -} - -int jitCompA000_selectRegCache(int rxx, int reg) -{ - if (rxx == 0) reg = 3; /* EBX */ - if (rxx == 1) reg = 1; /* ECX */ - if (rxx == 2) reg = 2; /* EDX */ - return reg; -} - -void jitCompA000_loadPRegCacheAll(struct JitCompWork *w) -{ - // jitCompA0001_movReg32EbpDisp(w, 5 /* EBP */, 256 + 0 * 32 + 0); /* EBP = P00; */ - jitCompA0001_movReg32EbpDisp(w, 6 /* ESI */, 256 + 1 * 32 + 0); /* ESI = P01; */ - jitCompA0001_movReg32EbpDisp(w, 7 /* EDI */, 256 + 2 * 32 + 0); /* EDI = P02; */ - return; -} - -void jitCompA000_storePRegCacheAll(struct JitCompWork *w) -{ - // jitCompA0001_movEbpDispReg32(w, 256 + 0 * 32 + 0, 5 /* EBP */); /* P00 = EBP; */ - jitCompA0001_movEbpDispReg32(w, 256 + 1 * 32 + 0, 6 /* ESI */); /* P01 = ESI; */ - jitCompA0001_movEbpDispReg32(w, 256 + 2 * 32 + 0, 7 /* EDI */); /* P02 = EDI; */ - return; -} - -int jitCompA000_selectPRegCache(int pxx, int reg) -{ - // if (pxx == 0) reg = 5; /* EBP */ - if (pxx == 1) reg = 6; /* ESI */ - if (pxx == 2) reg = 7; /* EDI */ - return reg; -} - -int jitCompA000_convTyp(int t) -{ - int r = -1; - if (1 <= t && t <= 7) r = t; - if (8 <= t && t <= 13) r = 2 | (t & 1); - if (14 <= t && t <= 15) r = 4 | (t & 1); - if (16 <= t && t <= 21) r = 6 | (t & 1); - return r; -} - -int jitCompA000_dataWidth(int t) -{ - int r = -1; - if (t == 0x0001) r = 256; - t >>= 1; - if (t == 0x0002 / 2) r = 8; - if (t == 0x0004 / 2) r = 16; - if (t == 0x0006 / 2) r = 32; - if (t == 0x0008 / 2) r = 4; - if (t == 0x000a / 2) r = 2; - if (t == 0x000c / 2) r = 1; - if (t == 0x000e / 2) r = 12; - if (t == 0x0010 / 2) r = 20; - if (t == 0x0012 / 2) r = 24; - if (t == 0x0014 / 2) r = 28; - return r; -} - -static unsigned char *errfnc; - -void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac) -{ - if (typ <= 0) { w->err = JITC_ERR_BADTYPE; } - if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; } - jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, 256 + pxx * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ - jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */ - jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */ - jitCompPutImm32(w, errfnc - (w->dst + 4)); - return; -} - -void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac) -// data用. -// 将来的にはaliveやアクセス権チェックも入れる -{ - jitCompA0001_checkType0(w, pxx, typ, ac); - return; -} - -void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx) -{ - jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ - jitCompA0001_85DispN(w, 256 + pxx * 32 + 8, reg); /* p0 */ - jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */ - jitCompPutImm32(w, errfnc - (w->dst + 4)); - jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ - jitCompA0001_85DispN(w, 256 + pxx * 32 + 12, reg); /* p1 */ - jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */ - jitCompPutImm32(w, errfnc - (w->dst + 4)); - return; -} - -void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0); -void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0); -void funcf4(char *ebp, int pxx, int typ, int len); -void funcf5(char *ebp, int pxx, int typ, int len); // pxxはダミーで参照されない. -void funcf6(char *ebp, int pxx, int typ, int len); -void funcf7(char *ebp, int pxx, int typ, int len); // typとlenはダミーで参照されない. -// F5の場合、decoderが対応するalloc-freeを結びつけるのが簡単で、typやlenを指定必須にしてもフロントエンドコードに影響はない. - -void errHndl(struct Regs *r); - -int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *src, const unsigned char *src1, const unsigned char *src0, struct LabelTable *label, int maxLabels, int level, int debugInfo1, int flags) -/* IA-32用 */ -/* 本来ならこのレイヤでは文法チェックしない */ -{ - struct JitCompWork w; - unsigned char *dst00 = dst, *errmsg = "", *enter0 = NULL, *tmp_ucp; - const unsigned char *oldsrc; - int timecount = 0, i, j = 0, lastlabel = -1, debugInfo0 = -1; - int reg0, reg1, reg2, cmp0reg = -1, cmp0lev = 0; - w.dst = w.dst0 = dst; - w.err = 0; - w.maxLabels = maxLabels; - if ((flags & JITC_NOSTARTUP) == 0) { - jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */ - jitCompA000_loadRegCacheAll(&w); /* start-up */ - jitCompA000_loadPRegCacheAll(&w); - } - if (level <= JITC_LV_SLOWER) { - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */ - jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */ - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, debugInfo1); - jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ - } - while (src < src1) { - w.prefix = 0; - if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; goto err_w; } - timecount++; - if (timecount >= 64) { - timecount -= 64; - /* 未完成(timeoutチェックコードを入れる) */ - } - prefix_continue: - switch (*src) { - - case 0x00: /* NOP */ - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } - break; - - case 0x01: /* LB */ - if (enter0 == NULL && (src[6] == 0x3c || (src[6] == 0xfe && src[7] == 0x01 && src[9] == 0x3c))) { - jitCompPutByte1(w.dst, 0xe9); - enter0 = w.dst; - jitCompPutImm32(&w, 0); - } - if (src[6] == 0x34) { - tmp_ucp = w.dst; - jitCompPutByte1(w.dst, 0xe9); - i = jitCompGetImm32(&src[7]); - j = 32; - if (i != 1) { - i = jitCompA000_convTyp(i); - j = 0; - if (i == 2 || i == 3) { j = 1; } - if (i == 4 || i == 5) { j = 2; } - if (i == 6 || i == 7) { j = 4; } - } - j *= jitCompGetImm32(&src[11]); - if (j <= 0) w.err = JITC_ERR_BADTYPE; - jitCompPutImm32(&w, j); -#if (jitCompA0001_OPTIMIZE_JMP != 0) - if (j <= 127 - jitCompA0001_OPTIMIZE_ALIGN) { - w.dst -= 5; - jitCompPutByte2(w.dst, 0xeb, j); - } -#endif - } -#if (jitCompA0001_OPTIMIZE_ALIGN != 0) - for (;;) { - i = ((int)w.dst) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */ - if (i == 0) break; - i = jitCompA0001_OPTIMIZE_ALIGN - i; - if (i == 1) { jitCompPutByte1(w.dst, 0x90); j += i; } /* NOP(); */ - if (i == 2) { jitCompPutByte2(w.dst, 0x89, 0xc0); j += i; } /* MOV(EAX, EAX); */ - if (i == 3) { jitCompPutByte3(w.dst, 0x8d, 0x76, 0x00); j += i; } /* LEA(ESI, [ESI+0]); */ - if (i == 4) { jitCompPutByte4(w.dst, 0x8d, 0x74, 0x26, 0x00); j += i; } /* LEA(ESI, [ESI*1+0]); */ - if (i == 5) { jitCompPutByte1(w.dst, 0x0d); jitCompPutImm32(&w, 0); j += i; } /* OR(EAX, 0); */ - if (i == 6) { jitCompPutByte2(w.dst, 0x8d, 0xb6); jitCompPutImm32(&w, 0); j += i; } /* LEA(ESI, [ESI+0]); */ - if (i >= 7) { jitCompPutByte3(w.dst, 0x8d, 0xb4, 0x26); jitCompPutImm32(&w, 0); j += 7; } /* LEA(ESI, [ESI*1+0]); */ - } -#endif - if (src[6] == 0x34) { - tmp_ucp[1] = j & 0xff; - if (*tmp_ucp == 0xe9) { - tmp_ucp[2] = (j >> 8) & 0xff; - tmp_ucp[3] = (j >> 16) & 0xff; - tmp_ucp[4] = (j >> 24) & 0xff; - } - } - if ((flags & JITC_PHASE1) == 0) { - i = jitCompGetLabelNum(&w, src + 2); - //printf("i=%06X %06X¥n", i, src-src0); - if (label[i].opt != 0 && w.err == 0) { w.err = JITC_ERR_LABELREDEF; goto err_w; } - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } - label[i].opt = src[1] + 1; - label[i].typ = 0; /* TYP_CODE */ - label[i].p = w.dst; - label[i].p1 = w.dst + 1; - lastlabel = i; - } - cmp0reg = -1; - timecount = 0; - /* 未完成(timeoutチェックコードを入れる) */ - break; - - case 0x02: /* LIMM */ - if (src[1] == 0x3f && w.prefix != 0) w.err = JITC_ERR_PREFIX; -#if (jitCompA0001_USE_R3F_IMM32 != 0) - if (src[1] == 0x3f) { - w.r3f = jitCompGetImm32(src + 2); - break; - } -#endif - i = jitCompGetImm32(src + 2); - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); -#if (jitCompA0001_OPTIMIZE_MOV != 0) - if (i == 0) { - jitCompPutByte2(w.dst, 0x31, 0xc0 | reg0 << 3 | reg0); /* XOR(reg0, reg0); */ - jitCompA0001_movRxxEax(&w, src[1]); - break; - } -#endif - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ - jitCompPutImm32(&w, i); - if (reg0 == 0) - jitCompA0001_movRxxEax(&w, src[1]); - break; - - case 0x03: /* PLIMM */ /* 未完成(plsまで対応) */ - 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 (src[1] != 0x3f && label[i].opt != 2) { w.err = JITC_ERR_LABELTYP; goto err_w; } - if (src[1] == 0x3f && label[i].typ != 0) { w.err = JITC_ERR_LABELTYP; goto err_w; } - } - if (src[1] == 0x3f) { - if (w.prefix == 0) { - jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */ - } - else { - w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */ - w.dst[-2] = 0x0f; - w.prefix = 0; - } - j = 0; - if ((flags & JITC_PHASE1) != 0 || ((flags & JITC_PHASE1) == 0) && label[i].opt != 0) - j = label[i].p - (w.dst + 4); - jitCompPutImm32(&w, j); -#if (jitCompA0001_OPTIMIZE_JMP != 0) - if (-128 - 3 <= j && j < 0) { - if (w.dst[-5] == 0xe9) { - j += 3; - w.dst -= 5; - jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */ - } - else { - j += 4; - w.dst -= 6; - jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0); - } - jitCompPutByte1(w.dst, j & 0xff); - } -#endif - } - else { - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ - jitCompPutImm32(&w, (int)label[i].p); - if (reg0 == 0) - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32, 0); /* MOV([EBP+?], EAX); */ - if (level < JITC_LV_FASTEST) { - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 8, reg0); /* MOV([EBP+?], reg0); */ /* p0 */ - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, label[i].typ); - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 4, 0); /* MOV([EBP+?], EAX); */ /* typ */ - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, (int)label[i].p1); - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 12, 0); /* MOV([EBP+?], EAX); */ /* p1 */ - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 16, 0); /* MOV([EBP+?], EAX); */ /* liveSign */ - jitCompA0001_movReg32EbpDisp(&w, 0, 2320); /* MOV(EAX, ptrCtrl); */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 20, 0); /* MOV([EBP+?], EAX); */ /* pls */ - } - } - break; - - case 0x04: /* CND (prefix) */ - if (src[1] >= 0x40) w.err = JITC_ERR_REGNUM; - reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */); - if (reg0 < 0) { - jitCompPutByte1(w.dst, 0xf7); /* TEST([EBP+?],1); */ - jitCompA0001_85DispN(&w, src[1] * 4, 0); - } - else { - jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST(reg0,1); */ - } - jitCompPutImm32(&w, 1); - jitCompPutByte2(w.dst, 0x74, 0x00); /* JZ($+2) */ - cmp0reg = -1; - if (w.err != 0) goto err_w; - src += 2; - w.prefix = 1; - w.dst0 = w.dst; - goto prefix_continue; - - case 0x08: /* LMEM */ /* 完成 */ - i = jitCompGetImm32(src + 2); - if (i == 0x0001) w.err = JITC_ERR_BADTYPE; - if (level < JITC_LV_FASTER) { - jitCompA0001_checkType(&w, src[6], i, 0); // read - cmp0reg = -1; - } - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); - if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) - reg1 = 0; /* EAX */ - if (reg1 == 2 /* EDX */) - jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ - if (level < JITC_LV_FASTER) - jitCompA0001_checkLimit(&w, reg1, src[6]); - i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); - switch (i) { - case 0x0002: - jitCompPutByte3(w.dst, 0x0f, 0xbe, reg0 << 3 | reg1); /* MOVSX(reg0,BYTE [reg1]); */ - break; - case 0x0003: - jitCompPutByte3(w.dst, 0x0f, 0xb6, reg0 << 3 | reg1); /* MOVZX(reg0,BYTE [reg1]); */ - break; - case 0x0004: - jitCompPutByte3(w.dst, 0x0f, 0xbf, reg0 << 3 | reg1); /* MOVSX(reg0,WORD [reg1]); */ - break; - case 0x0005: - jitCompPutByte3(w.dst, 0x0f, 0xb7, reg0 << 3 | reg1); /* MOVZX(reg0,WORD [reg1]); */ - break; - case 0x0006: - case 0x0007: - jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */ - break; - default: - w.err = JITC_ERR_BADTYPE; - } - if (reg0 == 0 /* EAX */) - jitCompA0001_movRxxEax(&w, src[1]); - if (reg1 == 2 /* EDX */) - jitCompA000_loadRegCacheEdx(&w); - break; - - case 0x09: /* SMEM */ /* 完成 */ - i = jitCompGetImm32(src + 2); - if (i == 0x0001) w.err = JITC_ERR_BADTYPE; - if (level < JITC_LV_FASTER) { - jitCompA0001_checkType(&w, src[6], i, 1); // write - cmp0reg = -1; - } - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); - if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) - reg1 = 0; /* EAX */ - if (reg1 == 2 /* EDX */) - jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ - if (level < JITC_LV_FASTER) - jitCompA0001_checkLimit(&w, reg1, src[6]); - if (reg0 == 0 /* EAX */) - jitCompA0001_movEaxRxx(&w, src[1]); - /* 値の範囲チェック */ - i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); - switch (i) { - case 0x0002: - case 0x0003: - jitCompPutByte2(w.dst, 0x88, reg0 << 3 | reg1); /* MOV([reg1], BYTE(reg0)); */ - break; - case 0x0004: - case 0x0005: - jitCompPutByte3(w.dst, 0x66, 0x89, reg0 << 3 | reg1); /* MOV([reg1], WORD(reg0)); */ - break; - case 0x0006: - case 0x0007: - jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */ - break; - default: - w.err = JITC_ERR_BADTYPE; - } - if (reg1 == 2 /* EDX */) - jitCompA000_loadRegCacheEdx(&w); - break; - - case 0x0a: /* PLMEM */ /* 完成 */ - i = jitCompGetImm32(src + 2); - if (i != 0x0001) w.err = JITC_ERR_BADTYPE; - if (level < JITC_LV_FASTER) { - jitCompA0001_checkType(&w, src[6], i, 0); // read - cmp0reg = -1; - } - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); - // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */ - // reg1 = 0; /* EAX */ - if (reg0 == reg1 && reg0 != 0) { // bugfix: hinted by yao, 2013.09.14. thanks! - jitCompA000_storePRegCacheAll(&w); - reg1 = 2; /* EDX */ - } - if (reg1 == 2 /* EDX */) - jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ - if (level < JITC_LV_FASTER) - jitCompA0001_checkLimit(&w, reg1, src[6]); - jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */ - if (reg0 == 0 /* EAX */) - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0); /* MOV([EBP+?], EAX); */ - for (i = 4; i < 32; i += 4) { - jitCompPutByte3(w.dst, 0x8b, 0x40 | reg1, i); /* MOV(EAX, [reg1+?]); */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ - } - if (reg1 == 2 /* EDX */) - jitCompA000_loadRegCacheEdx(&w); - break; - - case 0x0b: /* PSMEM */ /* 完成 */ - i = jitCompGetImm32(src + 2); - 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_selectPRegCache(src[1], 0 /* EAX */); - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); - // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */ - // reg1 = 0; /* EAX */ - if (reg1 == 2 /* EDX */) - jitCompA000_storeRegCacheEdx(&w); - if (reg1 <= 3 /* EAX, EDX */) - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ - if (level < JITC_LV_FASTER) - jitCompA0001_checkLimit(&w, reg1, src[6]); - if (reg0 == 0 /* EAX */) - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[1] * 32 + 0); /* MOV(reg0, [EBP+?]); */ - jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */ - for (i = 4; i < 32; i += 4) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[1] * 32 + i); /* MOV(EAX, [EBP+?]); */ - jitCompPutByte3(w.dst, 0x89, 0x40 | reg1, i); /* MOV([reg1+?], EAX); */ - } - if (reg1 == 2 /* EDX */) - jitCompA000_loadRegCacheEdx(&w); - break; - - case 0x0e: /* PADD */ /* 完成 */ - if (level < JITC_LV_FASTER) { - jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 2), 2); // other, aliveテストはとりあえずしない. - cmp0reg = -1; - } - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); - reg1 = jitCompA000_selectPRegCache(src[6], -1 /* mem */); - if (reg1 < 0 /* mem */) - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ - if (reg1 >= 0 && reg0 != reg1) { - jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ - } - i = jitCompGetImm32(src + 2); - j = -1; - if (i == 1) - j = 5; /* 32 */ - else { - i = jitCompA000_convTyp(i); - if (0x0002 <= i && i <= 0x0007) - j = (i - 0x0002) >> 1; - } - 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 */ -#endif - jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff); /* ADD(reg0, im8); */ - goto padd1; - } -#endif - if (reg0 == 0) { - jitCompPutByte1(w.dst, 0x05); /* ADD(reg0, ?); */ - } - else { - jitCompPutByte2(w.dst, 0x81, 0xc0 | reg0); /* ADD(reg0, ?); */ - } - jitCompPutImm32(&w, j); - goto padd1; - } -#endif - 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 { - jitCompPutByte1(w.dst, 0x03); /* ADD(reg0, [EBP+?]); */ - jitCompA0001_85DispN(&w, src[7] * 4, reg0); - } - } - else { - reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */); - reg2 = 2; /* EDX */ - jitCompA000_storeRegCacheEdx(&w); - if (reg1 < 0) - jitCompA0001_movReg32EbpDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */ - if (reg1 >= 0 && reg1 != reg2) { - jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg2); /* MOV(reg2, reg1); */ - } - jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg2, j); /* SHL(reg2, ?); */ - jitCompPutByte2(w.dst, 0x01, 0xc0 | reg2 << 3 | reg0); /* ADD(reg0, reg2); */ - jitCompA000_loadRegCacheEdx(&w); - } -#if (jitCompA0001_USE_R3F_IMM32 != 0) - padd1: -#endif - if (reg0 == 0 /* EAX */) - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, reg0); /* MOV([EBP+?], reg0); */ - if (src[1] != src[6]) { - for (i = 4; i < 32; i += 4) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ - } - } - cmp0reg = -1; - break; - - case 0x0f: /* PDIF */ /* 未完成 */ - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); - jitCompA000_storePRegCacheAll(&w); // 手抜き. - jitCompA0001_checkCompPtr(&w, src[6], src[7]); - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ - jitCompPutByte1(w.dst, 0x2b); /* SUB(EAX, [EBP+?]); */ - jitCompA0001_85DispN(&w, 256 + src[7] * 32 + 0, reg0); - i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); - j = -1; - if (0x0002 <= i && i <= 0x0007) - j = (i - 0x0002) >> 1; - 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 */) - jitCompA0001_movRxxEax(&w, src[1]); - cmp0reg = src[1]; cmp0lev = 1; - break; - - case 0x10: /* OR */ - case 0x11: /* XOR */ - case 0x12: /* AND */ - case 0x14: /* ADD */ - case 0x15: /* SUB */ - case 0x16: /* MUL */ - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); - 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; - reg2 = jitCompA000_selectRegCache(src[3], -1 /* mem */); - if (reg2 >= 0) - jitCompA000_storeRegCacheAll(&w); - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ - jitCompPutImm32(&w, w.r3f); - jitCompPutByte1(w.dst, 0x2b); - jitCompA0001_85DispN(&w, src[3] * 4, reg0); - if (reg0 == 0) - jitCompA0001_movRxxEax(&w, src[1]); - break; - } -#endif - if (reg1 < 0) { - jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg0, [EBP+?]); */ - } - if (reg1 >= 0 && reg0 != reg1) { - jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ - } - if (!(src[0] == 0x10 && src[3] == 0xff)) { // bugfix: hinted by Iris, 2013.06.26. thanks! - cmp0reg = src[1]; - cmp0lev = 1; - if (src[0] < 0x14) - cmp0lev = 2; - 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) - 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) - 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) - jitCompA0001_movRxxEax(&w, src[1]); - break; - } -#endif -#if (jitCompA0001_USE_R3F_IMM8 != 0) - if (-0x80 <= w.r3f && w.r3f <= 0x7f) { - 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 { - jitCompPutByte3(w.dst, 0x6b, 0xc0 | reg0 << 3 | reg0, w.r3f & 0xff); - } - if (reg0 == 0) - jitCompA0001_movRxxEax(&w, src[1]); - break; - } -#endif - if (reg0 == 0 /* EAX */) { - static unsigned char basic_op_table_im32_eax[] = { 0x0d, 0x35, 0x25, 0, 0x05, 0x2d, 0xc0 }; - if (*src == 0x16) { jitCompPutByte1(w.dst, 0x69); } - jitCompPutByte1(w.dst, basic_op_table_im32_eax[*src - 0x10]); - } - 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); - } - else { - jitCompPutByte2(w.dst, 0x69, 0xc0 | reg0 << 3 | reg0); - } - } - jitCompPutImm32(&w, w.r3f); - if (reg0 == 0) - jitCompA0001_movRxxEax(&w, src[1]); - break; - } -#endif - reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; - if (*src != 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 { - static unsigned char basic_op_table_rm[] = { 0x0b, 0x33, 0x23, 0, 0x03, 0x2b, 0xaf }; /* op(reg,mem); */ - jitCompPutByte1(w.dst, basic_op_table_rm[*src - 0x10]); - jitCompA0001_85DispN(&w, src[3] * 4, reg0); - } - } - else { - if (reg1 >= 0) { - jitCompPutByte3(w.dst, 0x0f, 0xaf, 0xc0 | reg0 << 3 | reg1); - } - else { - jitCompPutByte2(w.dst, 0x0f, 0xaf); - jitCompA0001_85DispN(&w, src[3] * 4, reg0); - } - } - } - 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 (jitCompA0001_USE_R3F_IMM32 != 0) - if (src[3] == 0x3f) { - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); - reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; - if (reg1 == -1) - jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg1, [EBP+?]); */ - else { - if (reg0 != reg1) { - jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ - } - } - if (*src == 0x18) { jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f); } /* SHL(reg0, im8); */ - if (*src == 0x19) { jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f); } /* SAR(reg0, im8); */ - if (reg0 == 0 /* EAX */) - jitCompA0001_movRxxEax(&w, src[1]); - cmp0reg = src[1]; - cmp0lev = 1; - break; - } -#endif - jitCompA000_storeRegCacheAll(&w); // 手抜き. - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ -#if (jitCompA0001_USE_R3F_IMM32 != 0) - if (src[2] == 0x3f) { - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, w.r3f); - } - else { - jitCompA0001_movEaxRxx(&w, src[2]); - } -#else - jitCompA0001_movEaxRxx(&w, src[2]); -#endif - if (*src == 0x18) { jitCompPutByte2(w.dst, 0xd3, 0xe0); } /* SHL(EAX, CL); */ - if (*src == 0x19) { jitCompPutByte2(w.dst, 0xd3, 0xf8); } /* SAR(EAX, CL); */ - jitCompA0001_movRxxEax(&w, src[1]); - jitCompA000_loadRegCacheAll(&w); // 手抜き. - cmp0reg = src[1]; - cmp0lev = 1; - break; - - 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; - jitCompA000_storeRegCacheAll(&w); // 手抜き. -#if (jitCompA0001_USE_R3F_IMM32 != 0) - if (src[3] == 0x3f) { - jitCompPutByte1(w.dst, 0xb8 | 1); /* MOV(ECX, ?); */ - jitCompPutImm32(&w, w.r3f); - } - else { - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ - } - if (src[2] == 0x3f) { - jitCompPutByte1(w.dst, 0xb8 | 0); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, w.r3f); - } - else { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */ - } -#else - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */ -#endif - jitCompPutByte1(w.dst, 0x99); /* CDQ(); */ - /* ECXがゼロではないことを確認すべき */ - jitCompPutByte2(w.dst, 0xf7, 0xf9); /* IDIV(ECX); */ - if (*src == 0x1a) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 0 /* EAX */); } - if (*src == 0x1b) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 2 /* EDX */); } - 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 (level < JITC_LV_FASTEST) { - cmp0reg = -1; - if (level < JITC_LV_FASTER) { - // typ が一致していることを確認. - // plsとliveSignが一致していることを確認. - - // preg1はp0 <= p <= p1 を満たしているか?. - // 新しいp0/p1は古いp0〜p1に適合しているか?. - - } - } - - case 0x1e: /* PCP */ /* 未完成(p1まで完成) */ - if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; - if (src[2] == 0x3f) w.err = JITC_ERR_PREGNUM; - if (src[1] != 0x3f) { - /* src[2] == 0xff の場合に対応できてない */ - jitCompA000_storePRegCacheAll(&w); // 手抜き. - for (i = 0; i < 32; i += 4) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + i); /* MOV(EAX, [EBP+?]); */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ - } - jitCompA000_loadPRegCacheAll(&w); // 手抜き. - } - else { - if (level < JITC_LV_FASTER) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ - jitCompPutByte3(w.dst, 0x83, 0xf8, 0); /* CMP(EAX, 0); */ - jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ - jitCompPutImm32(&w, errfnc - (w.dst + 4)); - /* セキュリティチェックが足りてない!(aliveとか) */ - } - reg0 = 0; /* EAX */ - jitCompA000_storePRegCacheAll(&w); // 手抜き. - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ - if (level < JITC_LV_FASTER) { - jitCompPutByte1(w.dst, 0x3b); /* CMP(reg0, [EBP+?]); */ - jitCompA0001_85DispN(&w, 256 + src[2] * 32 + 8, reg0); /* p0 */ - jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ - jitCompPutImm32(&w, errfnc - (w.dst + 4)); - } - jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */ - } - break; - - case 0x1f: /* PCST */ - if (jitCompGetImm32(src + 2) == 0) { - if (level < JITC_LV_FASTER) - jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 7), 2); - jitCompA000_storePRegCacheAll(&w); // 手抜き. - for (i = 0; i < 32 - 4; i += 4) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ - if (i == 4) { - jitCompPutByte1(w.dst, 0x0d); /* OR(EAX, ?); */ - jitCompPutImm32(&w, 0x80000000); - } - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ - } - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, debugInfo1); - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 28, 0 /* EAX */); /* MOV([EBP+?], EAX); */ - jitCompA000_loadPRegCacheAll(&w); // 手抜き. - cmp0reg = -1; - break; - } - if (jitCompGetImm32(src + 7) == 0) { - jitCompA000_storePRegCacheAll(&w); // 手抜き. - for (i = 0; i < 32 - 4; i += 4) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ - if (i == 4) { - jitCompPutByte1(w.dst, 0x25); /* AND(EAX, ?); */ - jitCompPutImm32(&w, 0x7fffffff); - } - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ - } - if (level < JITC_LV_FASTER) { - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + 28); /* MOV(EAX, [EBP+?]); */ - jitCompPutByte1(w.dst, 0x3d); /* CMP(EAX, ?); */ - jitCompPutImm32(&w, debugInfo1); - jitCompPutByte2(w.dst, 0x74, 8); /* JE */ - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); (2) */ - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0 /* EAX */); /* MOV([EBP+?], EAX); (1+1+4) */ - } - jitCompA000_loadPRegCacheAll(&w); // 手抜き. - cmp0reg = -1; - break; - } - w.err = JITC_ERR_OPECODE; - goto err_w; - - case 0x20: /* CMPE */ - case 0x21: /* CMPNE */ - case 0x22: /* CMPL */ - case 0x23: /* CMPGE */ - case 0x24: /* CMPLE */ - case 0x25: /* CMPG */ - case 0x26: /* TSTZ */ - case 0x27: /* TSTNZ */ - reg0 = jitCompA000_selectRegCache(src[2], 0 /* EAX */); - reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); - if (src[1] == 0x3f) { - /* 特殊構文チェック */ - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } - if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) { - w.err = JITC_ERR_IDIOM; goto err_w; - } - } - if (reg0 == 0) - jitCompA0001_movEaxRxx(&w, src[2]); -#if (jitCompA0001_USE_R3F_IMM32 != 0) - if (src[3] == 0x3f) { -#if (jitCompA0001_OPTIMIZE_CMP != 0) - 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)) - i = 1; - 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); */ - } - cmp0reg = src[2]; - cmp0lev = 2; - goto cmpcc1; - } -#endif -#if (jitCompA0001_USE_R3F_IMM8 != 0) - if (-0x80 <= w.r3f && w.r3f <= 0x7f && *src <= 0x25) { - jitCompPutByte3(w.dst, 0x83, 0xf8 | reg0, w.r3f); - goto cmpcc1; - } -#endif - if (reg0 == 0) { - 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); } - } - jitCompPutImm32(&w, 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); } - } - else { - if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3b); } - if (*src >= 0x26) { jitCompPutByte1(w.dst, 0x85); } - jitCompA0001_85DispN(&w, src[3] * 4, reg0); - } - cmpcc1: - 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 */ - }; -#if (jitCompA0001_USE_R3F_CMPJMP != 0) - if (src[1] == 0x3f) { - /* 特殊構文を利用した最適化 */ - jitCompPutByte2(w.dst, 0x0f, 0x80 | cmpcc_table0[*src - 0x20]); - 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].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) - j = label[i].p - (w.dst + 4); - jitCompPutImm32(&w, j); -#if (jitCompA0001_OPTIMIZE_JMP != 0) - if (-128 - 4 <= j && j < 0) { - j += 4; - w.dst -= 6; - jitCompPutByte2(w.dst, w.dst[1] ^ 0xf0, j & 0xff); - } -#endif - src += 6; - if (w.err != 0) goto err_w; - continue; - } -#endif - /* 一般的なJITC */ - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); - jitCompPutByte3(w.dst, 0x0f, 0x90 | cmpcc_table0[*src - 0x20], 0xc0 | reg0); /* SETcc(BYTE(reg0)); */ - jitCompPutByte3(w.dst, 0x0f, 0xb6, 0xc0 | reg0 << 3 | reg0); /* MOVZX(reg0, BYTE(reg0)); */ - jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */ - if (reg0 == 0) - jitCompA0001_movRxxEax(&w, src[1]); - cmp0reg = src[2]; - cmp0lev = 1; - break; - - case 0x28: /* PCMPE */ - case 0x29: /* PCMPNE */ - case 0x2a: /* PCMPL */ - case 0x2b: /* PCMPGE */ - case 0x2c: /* PCMPLE */ - case 0x2d: /* PCMPG */ - if (src[1] == 0x3f) { - /* 特殊構文チェック */ - 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; - } - } - if (src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; - jitCompA000_storePRegCacheAll(&w); // 手抜き. - if (src[3] != 0xff) - jitCompA0001_checkCompPtr(&w, src[2], src[3]); - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ - if (src[3] != 0xff) { - jitCompPutByte1(w.dst, 0x3b); /* CMP(EAX, [EBP+?]); */ - jitCompA0001_85DispN(&w, 256 + src[3] * 32 + 0, 0); - } - else { - /* ヌルポインタとの比較はこれでいいのか?たぶんよくない */ - jitCompPutByte3(w.dst, 0x83, 0xf8, 0x00); /* CMP(EAX, 0); */ - } - cmp0reg = -1; - goto cmpcc1; - - case 0x30: /* talloc(old:F4) */ - case 0x31: /* tfree(old:F5) */ - case 0x32: /* malloc(old:F6) */ - case 0x33: /* mfree(old:F7) */ - jitCompA000_storeRegCacheAll(&w); // 手抜き. - jitCompA000_storePRegCacheAll(&w); // 手抜き. - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ - jitCompPutByte1(w.dst, 0xe8); - if (*src == 0x30) j = ((unsigned char *)&funcf4) - (w.dst + 4); - if (*src == 0x31) j = ((unsigned char *)&funcf5) - (w.dst + 4); - if (*src == 0x32) j = ((unsigned char *)&funcf6) - (w.dst + 4); - if (*src == 0x33) j = ((unsigned char *)&funcf7) - (w.dst + 4); - jitCompPutImm32(&w, j); - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x10); /* ADD(ESP,16); */ - jitCompA000_loadRegCacheAll(&w); // 手抜き. - jitCompA000_loadPRegCacheAll(&w); // 手抜き. - cmp0reg = -1; - break; - - case 0x34: /* data (暫定) */ - cmp0reg = -1; - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } - int k = jitCompGetImm32(&src[1]), tmpData, bitCount, dataWidth = jitCompA000_dataWidth(k); - if (lastlabel >= 0 && label[lastlabel].typ == 0) - label[lastlabel].typ = k; - if (k != 1) { - i = jitCompA000_convTyp(k); - if (i < 2 || i > 7) { w.err = JITC_ERR_BADTYPE; goto err_w; } - } - j = jitCompGetImm32(&src[5]); - oldsrc = src; - src += 9; - 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; } - tmpData = 0; - for (k = 0; k < dataWidth; k++) { - tmpData = tmpData << 1 | ((*src >> bitCount) & 1); - bitCount--; - if (bitCount < 0) { - bitCount = 7; - src++; - } - } - 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); } - j--; - } - } - 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; } - 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; } - } - jitCompPutImm32(&w, (int)label[i].p); - jitCompPutImm32(&w, label[i].typ); - jitCompPutImm32(&w, (int)label[i].p); - jitCompPutImm32(&w, (int)label[i].p1); - jitCompPutImm32(&w, 0); /* liveSign */ - jitCompPutImm32(&w, 2320); /* pls */ - jitCompPutImm32(&w, 0); - jitCompPutImm32(&w, 0); - j--; - } - } - if (lastlabel >= 0 && label[lastlabel].p1 < w.dst) - label[lastlabel].p1 = w.dst; - continue; - - case 0x3c: /* ENTER */ - jitCompA000_storeRegCacheAll(&w); // 手抜き. - jitCompA000_storePRegCacheAll(&w); // 手抜き. - jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ - jitCompPutByte1(w.dst, 0xe8); - j = ((unsigned char *)&func3c) - (w.dst + 4); - jitCompPutImm32(&w, j); - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */ - jitCompA000_loadRegCacheAll(&w); // 手抜き. - jitCompA000_loadPRegCacheAll(&w); // 手抜き. - cmp0reg = -1; - break; - - case 0x3d: /* LEAVE */ - jitCompA000_storeRegCacheAll(&w); // 手抜き. - jitCompA000_storePRegCacheAll(&w); // 手抜き. - jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ - jitCompPutByte1(w.dst, 0xe8); - j = ((unsigned char *)&func3d) - (w.dst + 4); - jitCompPutImm32(&w, j); - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */ - jitCompA000_loadRegCacheAll(&w); // 手抜き. - jitCompA000_loadPRegCacheAll(&w); // 手抜き. - cmp0reg = -1; - break; - - case 0xfe: /* remark */ - if (src[1] == 0x01 && src[2] == 0x00) { // DBGINFO1 - if (level <= JITC_LV_SLOWER) { - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, debugInfo1); - jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ - } - } - if (src[1] == 0x01 && src[2] == 0x03) { // DBGINFO1CLR - if (level <= JITC_LV_SLOWER) { - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, -1); - jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ - } - } - if (src[1] == 0x05 && src[2] == 0x00) { // DBGINFO0 - if (level <= JITC_LV_SLOWEST) { - debugInfo0 = jitCompGetImm32(src + 3); - // jitCompPutByte1(w.dst, 0xbf); /* MOV(EDI, ?); */ - // jitCompPutImm32(&w, debugInfo0); - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ - jitCompPutImm32(&w, debugInfo0); - jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */ - } - } - break; - - default: - w.err = JITC_ERR_OPECODE; - goto err_w; - } - if (w.err != 0) goto err_w; - jitCompA0001_fixPrefix(&w); - if (w.err != 0) goto err_w; - src += jitCompCmdLen(src); - } - if (enter0 != NULL) { - j = w.dst - (enter0 + 4); - enter0[0] = j & 0xff; - enter0[1] = (j >> 8) & 0xff; - enter0[2] = (j >> 16) & 0xff; - enter0[3] = (j >> 24) & 0xff; - } - if ((flags & JITC_NOSTARTUP) == 0) { - jitCompA000_storeRegCacheAll(&w); - jitCompA000_storePRegCacheAll(&w); - jitCompPutByte1(w.dst, 0x61); /* POPAD(); */ - } - 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) - 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"; - if (w.err == (JITC_ERR_MASK & JITC_ERR_OPECODE)) errmsg = "opecode error"; - if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELNUM)) errmsg = "label number too large"; - if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELREDEF)) errmsg = "label redefine"; - if (w.err == (JITC_ERR_MASK & JITC_ERR_PREFIX)) { errmsg = "prefix redefine"; w.dst -= 2; } - if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELNODEF)) errmsg = "label not defined"; - if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELTYP)) errmsg = "label type error"; - if (w.err == (JITC_ERR_MASK & JITC_ERR_IDIOM)) errmsg = "idiom error"; - if (w.err == (JITC_ERR_MASK & JITC_ERR_PREGNUM)) errmsg = "preg-number error"; - if (w.err == (JITC_ERR_MASK & JITC_ERR_SRC1)) errmsg = "src1 error"; - if (w.err == (JITC_ERR_MASK & JITC_ERR_BADTYPE)) errmsg = "bad type code"; - if (w.err == (JITC_ERR_MASK & JITC_ERR_PREFIXFAR)) errmsg = "prefix internal error"; - if (w.err == (JITC_ERR_MASK & JITC_ERR_INTERNAL)) errmsg = "general internal error"; - if (*errmsg != '¥0') { - fprintf(stderr, "JITC: %s at %06X (debugInfo0=%d)¥n ", errmsg, src - src0, debugInfo0); - for (i = 0; i < 16; i++) - fprintf(stderr, "%02X ", src[i]); - static char *table[0x30] = { - "NOP", "LB", "LIMM", "PLIMM", "CND", "??", "??", "??", - "LMEM", "SMEM", "PLMEM", "PSMEM", "LEA", "??", "PADD", "PDIF", - "CP/OR", "XOR", "AND", "??", "ADD", "SUB", "MUL", "??", - "SHL", "SAR", "DIV", "MOD", "PLMT0", "PLMT1", "PCP", "PCST", - "CMPE", "CMPNE", "CMPL", "CMPGE", "CMPLE", "CMPG", "TSTZ", "TSTNZ", - "PCMPE", "PCMPNE", "PCMPL", "PCMPGE", "PCMPLE", "PCMPG", "??", "EXT" }; - errmsg = "??"; - if (*src < 0x30) errmsg = table[*src]; - fprintf(stderr, "(%s)¥n", errmsg); - } - return -1; -} - -unsigned char *jitCompCallFunc(unsigned char *dst, void *func) -{ - struct JitCompWork w; - w.dst = dst; - jitCompA000_storeRegCacheAll(&w); - jitCompA000_storePRegCacheAll(&w); - jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */ - jitCompPutByte1(w.dst, 0x50); /* PUSH(EAX); */ /* for 16byte-align(win32では不要なのだけど、MacOSには必要らしい) */ - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ - jitCompPutByte1(w.dst, 0xe8); /* CALL(func); */ - int j = ((unsigned char *)func) - (w.dst + 4); - - //この関数の中では結局w->dstしか参照していない - jitCompPutImm32(&w, j); - - jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */ /* (win32では不要なのだけど、MacOSには必要らしい) */ - jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */ - jitCompPutByte1(w.dst, 0x61); /* POPAD(); */ - jitCompA000_loadRegCacheAll(&w); - jitCompA000_loadPRegCacheAll(&w); - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + 0x30 * 32 + 0); /* MOV(EAX, [EBP+?]); */ - jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */ - return w.dst; -} - -unsigned char *jitCompInit(unsigned char *dst) -{ - errfnc = dst; - return jitCompCallFunc(dst, &errHndl); -} - -void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0) -{ - struct Regs *r = (struct Regs *) (ebp - jitCompA0001_EBP128); - int i, *pi; - struct Ptr *pp; - if (r->junkStack + 2048 > r->junkStack1) (*(r->errHndl))(r); - pi = (void *)r->junkStack; r->junkStack += r1 * 4; - for (i = 0; i < r1; i++) - pi[i] = r->ireg[i]; - pp = (void *)r->junkStack; r->junkStack += p1 * 32; - for (i = 0; i < p1; i++) - pp[i] = r->preg[i]; - pp = (void *)r->junkStack; r->junkStack += 32; - *pp = r->preg[0x30]; - pi = (void *)r->junkStack; r->junkStack += 4; - *pi = opt << 16 | r1 << 8 | p1; - for (i = 0; i < lenR; i++) - r->ireg[r0 + i] = r->ireg[0x30 + i]; - for (i = 0; i < lenP; i++) - r->preg[p0 + i] = r->preg[0x31 + i]; - return; -} - -void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0) -{ - struct Regs *r = (struct Regs *) (ebp - jitCompA0001_EBP128); - int i; - r->junkStack -= 4; - r->junkStack -= 32; struct Ptr *pp = (void *)r->junkStack; - r->preg[0x30] = *pp; - r->junkStack -= p1 * 32; pp = (void *)r->junkStack; - for (i = 0; i < p1; i++) - r->preg[i] = pp[i]; - r->junkStack -= r1 * 4; int *pi = (void *)r->junkStack; - for (i = 0; i < r1; i++) - r->ireg[i] = pi[i]; - return; -} - -void funcf4(char *ebp, int pxx, int typ, int len) -{ - struct Regs *r = (struct Regs *) (ebp - jitCompA0001_EBP128); - int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3; - 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); - r->junkStack += width * r->ireg[len]; - r->preg[pxx].p = p; - r->preg[pxx].typ = r->ireg[typ]; - r->preg[pxx].p0 = p; - r->preg[pxx].p1 = (void *)r->junkStack; - int *pi = (int *)r->junkStack; - *pi = width * r->ireg[len]; - r->junkStack += sizeof (int); - if (r->ireg[typ] == 1) { - int i, i1 = (width * r->ireg[len]) >> 2; - pi = p; - for (i = 0; i < i1; i++) - pi[i] = 0; - } - return; -} - -void funcf5(char *ebp, int pxx, int typ, int len) -{ - struct Regs *r = (struct Regs *) (ebp - jitCompA0001_EBP128); - r->junkStack -= sizeof (int); - int *pi = (int *)r->junkStack; - r->junkStack -= *pi; -#if 0 - int width = jitCompA000_dataWidth(r->ireg[typ]); - void *p = r->junkStack; - r->junkStack -= width * r->ireg[len]; -#endif - return; -} - -void funcf6(char *ebp, int pxx, int typ, int len) -{ - struct Regs *r = (struct Regs *) (ebp - jitCompA0001_EBP128); - int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3; - 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]; - r->preg[pxx].p0 = p; - r->preg[pxx].p1 = (unsigned char *)p + width * r->ireg[len]; - if (r->ireg[typ] == 1) { - int i, i1 = (width * r->ireg[len]) >> 2, *pi; - pi = p; - for (i = 0; i < i1; i++) - pi[i] = 0; - for (i = 1; i < i1; i += 8) - pi[i] |= -1; - } - return; -} - -void funcf7(char *ebp, int pxx, int typ, int len) -{ - struct Regs *r = (struct Regs *) (ebp - jitCompA0001_EBP128); - free(r->preg[pxx].p); - return; -} - -void errHndl(struct Regs *r) -{ - r = (struct Regs *) (((char *)r) - jitCompA0001_EBP128); - (*(r->errHndl))(r); - // ここに帰ってきてはいけない. -} - -/* - * qq : 出力バイナリの書き込み位置のアドレスへの参照(書き込み位置を呼び出しに反映させるため参照渡しにする) - * q1 : 出力バイナリの書き込み位置のアドレスの最大値 - * p0 : (*.ose)バイナリの読み込み位置のアドレス(ヘッダ部除去済) - * p1 : (*.ose)バイナリの読み込み位置の取りうる最大値 - * (ただし、「確保したメモリ」の最大値なのでこれより手前にゴミデータが入っているかもしれない) - * ret=1 : ヘッダのエラー - * ret=2 : jitコンパイルエラー - */ -int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, struct LabelTable *label) -{ - unsigned char *q = *qq; - if (p0[0] != 0x05 || p0[1] != SIGN1) - return 1; - - *q++ = 0x55; /* PUSH(EBP); */ - *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */ - - int i; - for (i = 0; i < JITC_MAXLABELS; i++) - label[i].opt = 0; - - i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, 0); - if (i != 0) return 2; - i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, JITC_PHASE1 + 0); - if (i < 0) return 2; - q += i; - - *q++ = 0x5d; /* POP(EBP); */ - *q++ = 0xc3; /* RET(); */ - - *qq = q; - return 0; -} - -#if (USE_DEBUGGER != 0) - -int dbgrGetRegNum(const unsigned char *p) -{ - int i, j, r = -1; - 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) - r = i << 4 | j; - } - return r; -} - -void dbgrMain(struct Regs *r) -{ - if (r->dbgr == 0) return; - for (;;) { - unsigned 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 (cmd[0] == 'p' && cmd[1] <= ' ' && cmd[1] != '¥0') { - p = &cmd[2]; - 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 - puts("register name error"); - continue; - } - if (*p == 'P') { - i = dbgrGetRegNum(p + 1); - if (0 <= i && i <= 0x3f) { - p = "invalid"; - if (0 <= r->preg[i].typ && r->preg[i].typ <= 0x15) { - static unsigned char *typName[] = { - "T_CODE", "T_VPTR", "T_SINT8", "T_UINT8", - "T_SINT16", "T_UINT16", "T_SINT32", "T_UINT32", - "T_SINT4", "T_UINT4", "T_SINT2", "T_UINT2", - "T_SINT1", "T_UINT1", "T_SINT12", "T_UINT12", - "T_SINT20", "T_UINT20", "T_SINT24", "T_UINT24", - "T_SINT28", "T_UINT28" - }; - p = typName[r->preg[i].typ]; - } - printf("P%02X:¥n type = %s(%04X), (origin-ptr) = 0x%08X¥n", i, p, r->preg[i].typ, 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; - 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; - printf(" pos = 0x%08X = %d¥n", k, k); - } - else { - puts(" null pointer"); - } - } - else - puts("register name error"); - continue; - } - } - puts("command error"); - } - return; -} - -#endif - - -#endif - - - +#include "osecpu.h" +#include "jitc.h" + +// +// JITC common functions (architecture not dependent) +// + +void errorHandler(HOSECPU_RuntimeEnvironment *r) +{ + puts("security error! abort..."); + printf("debugInfo0=%d, debugInfo1=%d\n", r->debugInfo0, r->debugInfo1); +#if (ENABLE_DEBUG_CODE != 0) + printf("Last opcode may be 0x%02X (Backend).\n", r->dbg_currentCode); +#endif + +#if (ENABLE_DEBUG_CODE_ADDR != 0) + printf("At backend code bin +0x%04X.\n", r->dbg_currentCodeAddress); +#endif + +#if (USE_DEBUGGER != 0) + dbgrMain(r); +#endif + exit(1); +} + +int jitCompCmdLen(const unsigned char *src) +{ + //BCode命令長を取得する + int i = 1; + + if (0x01 <= *src && *src < 0x04){ + // LB, LIMM, PLIMM + i = 6; + } else if (*src == 0x04){ + // CND + i = 2; + } else if (0x08 <= *src && *src < 0x0d){ + // LMEM, SMEM, ??, ??, ?? + i = 8 + src[7] * 4; + } else if (0x0e <= *src && *src < 0x10){ + // PADD, PDIF + i = 8; + } else if (0x10 <= *src && *src < 0x1c){ + // CP/OR, XOR, AND, ADD, SUB, MUL, SHL, SAR, DIV, MOD, + i = 4; + } else if (0x1c <= *src && *src < 0x1f){ + // ??, ??, PCP + i = 3; + } else if (*src == 0x1f){ + // ?? + i = 11; + } else if(0x20 <= *src && *src < 0x2e){ + // CMPE, CMPNE, CMPL, CMPGE, CMPLE, CMPG, TSTZ, TSTNZ, + // PCMPE, PCMPNE, PCMPL, PCMPGE, PCMPLE, PCMPG, + i = 4; + } else if (*src == 0x2f){ + // ?? + i = 4 + src[1]; + } else if (0x30 <= *src && *src < 0x34){ + // ??, ??, MALLOC, ?? + i = 4; + } else if (0x3c <= *src && *src < 0x3e){ + // ??, ?? + i = 7; + } else if (*src == 0xfe){ + // REMARK + i = 2 + src[1]; + } + + return i; +} + +void PRegCopy(HOSECPU_PointerRegisterEntry *dst, HOSECPU_PointerRegisterEntry *src) +{ + // 以下の方法で代入するとMacではアライメントエラーで落ちるのです... + // *dst = *src; + // ということで、memcpyによる実装に変更しました。 + + memcpy(dst, src, sizeof(HOSECPU_PointerRegisterEntry)); +} + + + +