Revisión | 4290c48188d4ccb377996de3c585471fb171e9d9 (tree) |
---|---|
Tiempo | 2014-03-12 18:20:29 |
Autor | ttwilb <ttwilb@user...> |
Commiter | ttwilb |
Visual Studioでコンパイルが通るように
@@ -1,4 +1,4 @@ | ||
1 | -#include "osecpu.h" | |
1 | +#include "osecpu.h" | |
2 | 2 | |
3 | 3 | struct ComLib_Str { |
4 | 4 | const unsigned char *p; |
@@ -1,4 +1,4 @@ | ||
1 | -#include "osecpu.h" | |
1 | +#include "osecpu.h" | |
2 | 2 | |
3 | 3 | |
4 | 4 | #if (DRV_OSNUM == 0x0002) |
@@ -1,4 +1,4 @@ | ||
1 | - | |
1 | + | |
2 | 2 | unsigned char fontdata[] = { |
3 | 3 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
4 | 4 | 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, |
@@ -1,4 +1,4 @@ | ||
1 | -#include "osecpu.h" | |
1 | +#include "osecpu.h" | |
2 | 2 | |
3 | 3 | extern unsigned char fontdata[]; // @fontdata.c |
4 | 4 |
@@ -29,47 +29,47 @@ void errorHandler(HOSECPU_RuntimeEnvironment *r) | ||
29 | 29 | |
30 | 30 | int jitCompCmdLen(const unsigned char *src) |
31 | 31 | { |
32 | - //BCode命令長を取得する | |
32 | + //BCode命令長を取得する | |
33 | 33 | int i = 1; |
34 | - | |
35 | - if (0x01 <= *src && *src < 0x04){ | |
36 | - // LB, LIMM, PLIMM | |
37 | - i = 6; | |
38 | - } else if (*src == 0x04){ | |
39 | - // CND | |
40 | - i = 2; | |
41 | - } else if (0x08 <= *src && *src < 0x0d){ | |
42 | - // LMEM, SMEM, ??, ??, ?? | |
43 | - i = 8 + src[7] * 4; | |
44 | - } else if (0x0e <= *src && *src < 0x10){ | |
45 | - // PADD, PDIF | |
46 | - i = 8; | |
47 | - } else if (0x10 <= *src && *src < 0x1c){ | |
48 | - // CP/OR, XOR, AND, ADD, SUB, MUL, SHL, SAR, DIV, MOD, | |
49 | - i = 4; | |
50 | - } else if (0x1c <= *src && *src < 0x1f){ | |
51 | - // ??, ??, PCP | |
52 | - i = 3; | |
53 | - } else if (*src == 0x1f){ | |
54 | - // ?? | |
55 | - i = 11; | |
56 | - } else if(0x20 <= *src && *src < 0x2e){ | |
57 | - // CMPE, CMPNE, CMPL, CMPGE, CMPLE, CMPG, TSTZ, TSTNZ, | |
58 | - // PCMPE, PCMPNE, PCMPL, PCMPGE, PCMPLE, PCMPG, | |
59 | - i = 4; | |
60 | - } else if (*src == 0x2f){ | |
61 | - // ?? | |
62 | - i = 4 + src[1]; | |
63 | - } else if (0x30 <= *src && *src < 0x34){ | |
64 | - // ??, ??, MALLOC, ?? | |
65 | - i = 4; | |
66 | - } else if (0x3c <= *src && *src < 0x3e){ | |
67 | - // ??, ?? | |
68 | - i = 7; | |
69 | - } else if (*src == 0xfe){ | |
70 | - // REMARK | |
71 | - i = 2 + src[1]; | |
72 | - } | |
34 | + | |
35 | + if (0x01 <= *src && *src < 0x04){ | |
36 | + // LB, LIMM, PLIMM | |
37 | + i = 6; | |
38 | + } else if (*src == 0x04){ | |
39 | + // CND | |
40 | + i = 2; | |
41 | + } else if (0x08 <= *src && *src < 0x0d){ | |
42 | + // LMEM, SMEM, ??, ??, ?? | |
43 | + i = 8 + src[7] * 4; | |
44 | + } else if (0x0e <= *src && *src < 0x10){ | |
45 | + // PADD, PDIF | |
46 | + i = 8; | |
47 | + } else if (0x10 <= *src && *src < 0x1c){ | |
48 | + // CP/OR, XOR, AND, ADD, SUB, MUL, SHL, SAR, DIV, MOD, | |
49 | + i = 4; | |
50 | + } else if (0x1c <= *src && *src < 0x1f){ | |
51 | + // ??, ??, PCP | |
52 | + i = 3; | |
53 | + } else if (*src == 0x1f){ | |
54 | + // ?? | |
55 | + i = 11; | |
56 | + } else if(0x20 <= *src && *src < 0x2e){ | |
57 | + // CMPE, CMPNE, CMPL, CMPGE, CMPLE, CMPG, TSTZ, TSTNZ, | |
58 | + // PCMPE, PCMPNE, PCMPL, PCMPGE, PCMPLE, PCMPG, | |
59 | + i = 4; | |
60 | + } else if (*src == 0x2f){ | |
61 | + // ?? | |
62 | + i = 4 + src[1]; | |
63 | + } else if (0x30 <= *src && *src < 0x34){ | |
64 | + // ??, ??, MALLOC, ?? | |
65 | + i = 4; | |
66 | + } else if (0x3c <= *src && *src < 0x3e){ | |
67 | + // ??, ?? | |
68 | + i = 7; | |
69 | + } else if (*src == 0xfe){ | |
70 | + // REMARK | |
71 | + i = 2 + src[1]; | |
72 | + } | |
73 | 73 | |
74 | 74 | return i; |
75 | 75 | } |
@@ -133,7 +133,7 @@ void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n) | ||
133 | 133 | disp -= jitCompA0001_EBP128; |
134 | 134 | if (-128 <= disp && disp <= 127) { |
135 | 135 | jitCompPutByte2(w->dst, 0x45 | (n << 3), disp & 0xff); |
136 | - } else { | |
136 | + } else { | |
137 | 137 | jitCompPutByte1(w->dst, 0x85 | (n << 3)); |
138 | 138 | jitCompPutImm32(w, disp); |
139 | 139 | } |
@@ -164,8 +164,8 @@ void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx) | ||
164 | 164 | } |
165 | 165 | #endif |
166 | 166 | if (rxx >= 0x40 || rxx < 0){ |
167 | - w->err = JITC_ERR_REGNUM; | |
168 | - } | |
167 | + w->err = JITC_ERR_REGNUM; | |
168 | + } | |
169 | 169 | jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, rxx * 4); /* MOV(EAX, [EBP+?]); */ |
170 | 170 | return; |
171 | 171 | } |
@@ -173,8 +173,8 @@ void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx) | ||
173 | 173 | void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx) |
174 | 174 | { |
175 | 175 | if (rxx >= 0x40 || rxx < 0){ |
176 | - w->err = JITC_ERR_REGNUM; | |
177 | - } | |
176 | + w->err = JITC_ERR_REGNUM; | |
177 | + } | |
178 | 178 | jitCompA0001_movEbpDispReg32(w, rxx * 4, 0 /* EAX */); /* MOV([EBP+?], EAX); */ |
179 | 179 | return; |
180 | 180 | } |
@@ -183,8 +183,8 @@ void jitCompA0001_fixPrefix(struct JitCompWork *w) | ||
183 | 183 | { |
184 | 184 | if (w->prefix != 0) { |
185 | 185 | if (w->dst - w->dst0 > 127){ |
186 | - w->err = JITC_ERR_REGNUM; | |
187 | - } | |
186 | + w->err = JITC_ERR_REGNUM; | |
187 | + } | |
188 | 188 | w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff); |
189 | 189 | } |
190 | 190 | return; |
@@ -193,11 +193,11 @@ void jitCompA0001_fixPrefix(struct JitCompWork *w) | ||
193 | 193 | void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1) |
194 | 194 | { |
195 | 195 | if (p0 >= 0x3f || p0 < 0){ |
196 | - w->err = JITC_ERR_PREGNUM; | |
197 | - } | |
196 | + w->err = JITC_ERR_PREGNUM; | |
197 | + } | |
198 | 198 | if (p1 >= 0x3f || p1 < 0){ |
199 | - w->err = JITC_ERR_PREGNUM; | |
200 | - } | |
199 | + w->err = JITC_ERR_PREGNUM; | |
200 | + } | |
201 | 201 | /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */ |
202 | 202 | return; |
203 | 203 | } |
@@ -244,21 +244,21 @@ void jitCompA000_storeRegCacheEdx(struct JitCompWork *w) | ||
244 | 244 | |
245 | 245 | int jitCompA000_selectRegCache(int rxx, int reg) |
246 | 246 | { |
247 | - switch (rxx) { | |
248 | - case 0: | |
249 | - //EBX | |
250 | - reg = 3; | |
251 | - break; | |
252 | - case 1: | |
253 | - //ECX | |
254 | - reg = 1; | |
255 | - break; | |
256 | - case 2: | |
257 | - //EDX | |
258 | - reg = 2; | |
259 | - break; | |
260 | - } | |
261 | - return reg; | |
247 | + switch (rxx) { | |
248 | + case 0: | |
249 | + //EBX | |
250 | + reg = 3; | |
251 | + break; | |
252 | + case 1: | |
253 | + //ECX | |
254 | + reg = 1; | |
255 | + break; | |
256 | + case 2: | |
257 | + //EDX | |
258 | + reg = 2; | |
259 | + break; | |
260 | + } | |
261 | + return reg; | |
262 | 262 | } |
263 | 263 | |
264 | 264 | void jitCompA000_loadPRegCacheAll(struct JitCompWork *w) |
@@ -280,33 +280,33 @@ void jitCompA000_storePRegCacheAll(struct JitCompWork *w) | ||
280 | 280 | int jitCompA000_selectPRegCache(int pxx, int reg) |
281 | 281 | { |
282 | 282 | // if (pxx == 0) reg = 5; /* EBP */ |
283 | - switch (pxx) { | |
284 | - case 1: | |
285 | - //ESI | |
286 | - reg = 6; | |
287 | - break; | |
288 | - | |
289 | - case 2: | |
290 | - //EDI | |
291 | - reg = 7; | |
292 | - break; | |
293 | - } | |
294 | - return reg; | |
283 | + switch (pxx) { | |
284 | + case 1: | |
285 | + //ESI | |
286 | + reg = 6; | |
287 | + break; | |
288 | + | |
289 | + case 2: | |
290 | + //EDI | |
291 | + reg = 7; | |
292 | + break; | |
293 | + } | |
294 | + return reg; | |
295 | 295 | } |
296 | 296 | |
297 | 297 | int jitCompA000_convTyp(int t) |
298 | 298 | { |
299 | 299 | int r = -1; |
300 | - | |
300 | + | |
301 | 301 | if (1 <= t && t <= 7){ |
302 | - r = t; | |
303 | - } else if (8 <= t && t <= 13){ | |
304 | - r = 2 | (t & 1); | |
305 | - } else if (14 <= t && t <= 15){ | |
306 | - r = 4 | (t & 1); | |
307 | - } else if (16 <= t && t <= 21){ | |
308 | - r = 6 | (t & 1); | |
309 | - } | |
302 | + r = t; | |
303 | + } else if (8 <= t && t <= 13){ | |
304 | + r = 2 | (t & 1); | |
305 | + } else if (14 <= t && t <= 15){ | |
306 | + r = 4 | (t & 1); | |
307 | + } else if (16 <= t && t <= 21){ | |
308 | + r = 6 | (t & 1); | |
309 | + } | |
310 | 310 | return r; |
311 | 311 | } |
312 | 312 |
@@ -385,14 +385,14 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
385 | 385 | { |
386 | 386 | struct JitCompWork w; |
387 | 387 | unsigned char *dst00 = dst, *enter0 = NULL, *tmp_ucp; |
388 | - char *errmsg = ""; | |
388 | + char *errmsg = ""; | |
389 | 389 | const unsigned char *oldsrc; |
390 | 390 | int timecount = 0, i, j = 0, lastlabel = -1, debugInfo0 = -1; |
391 | 391 | int reg0, reg1, reg2, cmp0reg = -1, cmp0lev = 0; |
392 | 392 | w.dst = w.dst0 = dst; |
393 | 393 | w.err = 0; |
394 | 394 | w.maxLabels = maxLabels; |
395 | - | |
395 | + | |
396 | 396 | if ((flags & JITC_NOSTARTUP) == 0) { |
397 | 397 | jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */ |
398 | 398 | jitCompA000_loadRegCacheAll(&w); /* start-up */ |
@@ -415,1082 +415,1082 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
415 | 415 | } |
416 | 416 | prefix_continue: // CND命令実行後ここに戻る |
417 | 417 | switch (*src) { |
418 | - | |
419 | - case 0x00: /* NOP */ | |
420 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } // 「条件付きでNOPを実行」するなんて、矛盾している! | |
421 | - break; | |
422 | - | |
423 | - case 0x01: /* LB */ | |
424 | - | |
425 | - /* | |
426 | - * LB : ラベル設置命令。(6byte) | |
427 | - * ・prefex = 1にする | |
428 | - * ・timecount++し、timecountのチェックをする。 | |
429 | - * ・ラベル位置を登録する。 | |
430 | - * ・割り込みがある場合、このタイミングで割り込みを発生させる。 | |
431 | - * | |
432 | - * 1 2 3 456 | |
433 | - * LB 01 opt imm32 | |
434 | - * | |
435 | - */ | |
436 | - | |
437 | - if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) { //beginFunc()中のLB | |
438 | - // LB命令の後に0x3C命令・・・beginFunc() | |
439 | - jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする | |
440 | - enter0 = w.dst; | |
441 | - jitCompPutImm32(&w, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ?? | |
442 | - } | |
443 | - if (src[6] == 0x34) { // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令 | |
444 | - tmp_ucp = w.dst; | |
445 | - jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする | |
446 | - i = jitCompGetImm32(&src[7]); // type32 を取得 | |
447 | - j = 32; | |
448 | - if (i != 1) { | |
449 | - i = jitCompA000_convTyp(i); | |
450 | - j = 0; | |
451 | - if (i == 2 || i == 3) { j = 1; } | |
452 | - if (i == 4 || i == 5) { j = 2; } | |
453 | - if (i == 6 || i == 7) { j = 4; } | |
454 | - } | |
455 | - j *= jitCompGetImm32(&src[11]); | |
456 | - if (j <= 0) w.err = JITC_ERR_BADTYPE; | |
457 | - jitCompPutImm32(&w, j); | |
418 | + | |
419 | + case 0x00: /* NOP */ | |
420 | + if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } // 「条件付きでNOPを実行」するなんて、矛盾している! | |
421 | + break; | |
422 | + | |
423 | + case 0x01: /* LB */ | |
424 | + | |
425 | + /* | |
426 | + * LB : ラベル設置命令。(6byte) | |
427 | + * ・prefex = 1にする | |
428 | + * ・timecount++し、timecountのチェックをする。 | |
429 | + * ・ラベル位置を登録する。 | |
430 | + * ・割り込みがある場合、このタイミングで割り込みを発生させる。 | |
431 | + * | |
432 | + * 1 2 3 456 | |
433 | + * LB 01 opt imm32 | |
434 | + * | |
435 | + */ | |
436 | + | |
437 | + if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) { //beginFunc()中のLB | |
438 | + // LB命令の後に0x3C命令・・・beginFunc() | |
439 | + jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする | |
440 | + enter0 = w.dst; | |
441 | + jitCompPutImm32(&w, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ?? | |
442 | + } | |
443 | + if (src[6] == 0x34) { // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令 | |
444 | + tmp_ucp = w.dst; | |
445 | + jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする | |
446 | + i = jitCompGetImm32(&src[7]); // type32 を取得 | |
447 | + j = 32; | |
448 | + if (i != 1) { | |
449 | + i = jitCompA000_convTyp(i); | |
450 | + j = 0; | |
451 | + if (i == 2 || i == 3) { j = 1; } | |
452 | + if (i == 4 || i == 5) { j = 2; } | |
453 | + if (i == 6 || i == 7) { j = 4; } | |
454 | + } | |
455 | + j *= jitCompGetImm32(&src[11]); | |
456 | + if (j <= 0) w.err = JITC_ERR_BADTYPE; | |
457 | + jitCompPutImm32(&w, j); | |
458 | 458 | #if (jitCompA0001_OPTIMIZE_JMP != 0) |
459 | - if (j <= 127 - jitCompA0001_OPTIMIZE_ALIGN) { | |
460 | - w.dst -= 5; | |
461 | - jitCompPutByte2(w.dst, 0xeb, j); | |
462 | - } | |
459 | + if (j <= 127 - jitCompA0001_OPTIMIZE_ALIGN) { | |
460 | + w.dst -= 5; | |
461 | + jitCompPutByte2(w.dst, 0xeb, j); | |
462 | + } | |
463 | 463 | #endif |
464 | - } | |
464 | + } | |
465 | 465 | #if (jitCompA0001_OPTIMIZE_ALIGN != 0) |
466 | - for (;;) { | |
467 | - i = ((int)w.dst) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */ | |
468 | - if (i == 0) break; | |
469 | - i = jitCompA0001_OPTIMIZE_ALIGN - i; | |
470 | - if (i == 1) { jitCompPutByte1(w.dst, 0x90); j += i; } /* NOP(); */ | |
471 | - if (i == 2) { jitCompPutByte2(w.dst, 0x89, 0xc0); j += i; } /* MOV(EAX, EAX); */ | |
472 | - if (i == 3) { jitCompPutByte3(w.dst, 0x8d, 0x76, 0x00); j += i; } /* LEA(ESI, [ESI+0]); */ | |
473 | - if (i == 4) { jitCompPutByte4(w.dst, 0x8d, 0x74, 0x26, 0x00); j += i; } /* LEA(ESI, [ESI*1+0]); */ | |
474 | - if (i == 5) { jitCompPutByte1(w.dst, 0x0d); jitCompPutImm32(&w, 0); j += i; } /* OR(EAX, 0); */ | |
475 | - if (i == 6) { jitCompPutByte2(w.dst, 0x8d, 0xb6); jitCompPutImm32(&w, 0); j += i; } /* LEA(ESI, [ESI+0]); */ | |
476 | - if (i >= 7) { jitCompPutByte3(w.dst, 0x8d, 0xb4, 0x26); jitCompPutImm32(&w, 0); j += 7; } /* LEA(ESI, [ESI*1+0]); */ | |
477 | - } | |
466 | + for (;;) { | |
467 | + i = ((int)w.dst) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */ | |
468 | + if (i == 0) break; | |
469 | + i = jitCompA0001_OPTIMIZE_ALIGN - i; | |
470 | + if (i == 1) { jitCompPutByte1(w.dst, 0x90); j += i; } /* NOP(); */ | |
471 | + if (i == 2) { jitCompPutByte2(w.dst, 0x89, 0xc0); j += i; } /* MOV(EAX, EAX); */ | |
472 | + if (i == 3) { jitCompPutByte3(w.dst, 0x8d, 0x76, 0x00); j += i; } /* LEA(ESI, [ESI+0]); */ | |
473 | + if (i == 4) { jitCompPutByte4(w.dst, 0x8d, 0x74, 0x26, 0x00); j += i; } /* LEA(ESI, [ESI*1+0]); */ | |
474 | + if (i == 5) { jitCompPutByte1(w.dst, 0x0d); jitCompPutImm32(&w, 0); j += i; } /* OR(EAX, 0); */ | |
475 | + if (i == 6) { jitCompPutByte2(w.dst, 0x8d, 0xb6); jitCompPutImm32(&w, 0); j += i; } /* LEA(ESI, [ESI+0]); */ | |
476 | + if (i >= 7) { jitCompPutByte3(w.dst, 0x8d, 0xb4, 0x26); jitCompPutImm32(&w, 0); j += 7; } /* LEA(ESI, [ESI*1+0]); */ | |
477 | + } | |
478 | 478 | #endif |
479 | - if (src[6] == 0x34) { | |
480 | - tmp_ucp[1] = j & 0xff; | |
481 | - if (*tmp_ucp == 0xe9) { | |
482 | - tmp_ucp[2] = (j >> 8) & 0xff; | |
483 | - tmp_ucp[3] = (j >> 16) & 0xff; | |
484 | - tmp_ucp[4] = (j >> 24) & 0xff; | |
485 | - } | |
486 | - } | |
487 | - if ((flags & JITC_PHASE1) == 0) { | |
488 | - i = jitCompGetLabelNum(&w, src + 2); | |
489 | - //printf("i=%06X %06X\n", i, src-src0); | |
490 | - if (label[i].opt != 0 && w.err == 0) { w.err = JITC_ERR_LABELREDEF; goto err_w; } | |
491 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
492 | - label[i].opt = src[1] + 1; | |
493 | - label[i].typ = 0; /* TYP_CODE */ | |
494 | - label[i].p = w.dst; | |
495 | - label[i].p1 = w.dst + 1; | |
496 | - lastlabel = i; | |
497 | - } | |
498 | - cmp0reg = -1; | |
499 | - timecount = 0; | |
500 | - /* 未完成(timeoutチェックコードを入れる) */ | |
501 | - break; | |
502 | - | |
503 | - case 0x02: /* LIMM */ | |
504 | - | |
505 | - /* | |
506 | - * LIMM : 定数即値代入命令(6byte) | |
507 | - * | |
508 | - * 1 2 3456 | |
509 | - * 02 reg0R imm32 | |
510 | - * | |
511 | - * ・reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。 | |
512 | - */ | |
513 | - | |
514 | - if (src[1] == 0x3f && w.prefix != 0) w.err = JITC_ERR_PREFIX; // CND命令の直後でR3Fを書き換えるなんて変だよね | |
515 | - | |
479 | + if (src[6] == 0x34) { | |
480 | + tmp_ucp[1] = j & 0xff; | |
481 | + if (*tmp_ucp == 0xe9) { | |
482 | + tmp_ucp[2] = (j >> 8) & 0xff; | |
483 | + tmp_ucp[3] = (j >> 16) & 0xff; | |
484 | + tmp_ucp[4] = (j >> 24) & 0xff; | |
485 | + } | |
486 | + } | |
487 | + if ((flags & JITC_PHASE1) == 0) { | |
488 | + i = jitCompGetLabelNum(&w, src + 2); | |
489 | + //printf("i=%06X %06X\n", i, src-src0); | |
490 | + if (label[i].opt != 0 && w.err == 0) { w.err = JITC_ERR_LABELREDEF; goto err_w; } | |
491 | + if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
492 | + label[i].opt = src[1] + 1; | |
493 | + label[i].typ = 0; /* TYP_CODE */ | |
494 | + label[i].p = w.dst; | |
495 | + label[i].p1 = w.dst + 1; | |
496 | + lastlabel = i; | |
497 | + } | |
498 | + cmp0reg = -1; | |
499 | + timecount = 0; | |
500 | + /* 未完成(timeoutチェックコードを入れる) */ | |
501 | + break; | |
502 | + | |
503 | + case 0x02: /* LIMM */ | |
504 | + | |
505 | + /* | |
506 | + * LIMM : 定数即値代入命令(6byte) | |
507 | + * | |
508 | + * 1 2 3456 | |
509 | + * 02 reg0R imm32 | |
510 | + * | |
511 | + * ・reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。 | |
512 | + */ | |
513 | + | |
514 | + if (src[1] == 0x3f && w.prefix != 0) w.err = JITC_ERR_PREFIX; // CND命令の直後でR3Fを書き換えるなんて変だよね | |
515 | + | |
516 | 516 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
517 | - if (src[1] == 0x3f) { // R3Fへの代入は例外敵に、 w.r3f を使用 | |
518 | - w.r3f = jitCompGetImm32(src + 2); | |
519 | - break; | |
520 | - } | |
517 | + if (src[1] == 0x3f) { // R3Fへの代入は例外敵に、 w.r3f を使用 | |
518 | + w.r3f = jitCompGetImm32(src + 2); | |
519 | + break; | |
520 | + } | |
521 | 521 | #endif |
522 | - i = jitCompGetImm32(src + 2); // 与えられた即値(第二引数)を取得 | |
523 | - | |
524 | - /* R00-R02 なら EBX, ECX, EDX 、それ以外なら EAX のレジスタIDを reg0 に代入 */ | |
525 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
526 | - | |
522 | + i = jitCompGetImm32(src + 2); // 与えられた即値(第二引数)を取得 | |
523 | + | |
524 | + /* R00-R02 なら EBX, ECX, EDX 、それ以外なら EAX のレジスタIDを reg0 に代入 */ | |
525 | + reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
526 | + | |
527 | 527 | #if (jitCompA0001_OPTIMIZE_MOV != 0) |
528 | - if (i == 0) { | |
529 | - jitCompPutByte2(w.dst, 0x31, 0xc0 | reg0 << 3 | reg0); /* XOR(reg0, reg0); */ | |
530 | - jitCompA0001_movRxxEax(&w, src[1]); | |
531 | - break; | |
532 | - } | |
528 | + if (i == 0) { | |
529 | + jitCompPutByte2(w.dst, 0x31, 0xc0 | reg0 << 3 | reg0); /* XOR(reg0, reg0); */ | |
530 | + jitCompA0001_movRxxEax(&w, src[1]); | |
531 | + break; | |
532 | + } | |
533 | 533 | #endif |
534 | - | |
535 | - /* reg0 のレジスタに対応したMOV命令を発行 */ | |
536 | - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); == 10111000b+wr imm32 */ | |
537 | - jitCompPutImm32(&w, i); | |
538 | - | |
539 | - if (reg0 == 0) // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合 | |
540 | - | |
541 | - jitCompA0001_movRxxEax(&w, src[1]); | |
542 | - break; | |
543 | - | |
544 | - case 0x03: /* PLIMM */ /* 未完成(plsまで対応) */ | |
545 | - | |
546 | - /* | |
547 | - * PLIMM : ラベル番号代入命令(6byte) | |
548 | - * | |
549 | - * 1 2 3456 | |
550 | - * 03 PXX imm32 | |
551 | - * | |
552 | - * ・P28 はAPI用 | |
553 | - * ・P30 はリターンアドレス | |
554 | - * ・P3F はプログラムカウンタ | |
555 | - */ | |
556 | - | |
557 | - i = jitCompGetLabelNum(&w, src + 2); // Pxxに代入するラベルの番号(第二引数) | |
558 | - if ((flags & JITC_PHASE1) != 0 && w.err == 0) { // Phase 1であるならば | |
559 | - if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } // 指定されたラベル番号は存在しない | |
560 | - if (src[1] != 0x3f && label[i].opt != 2) { w.err = JITC_ERR_LABELTYP; goto err_w; } // | |
561 | - if (src[1] == 0x3f && label[i].typ != 0) { w.err = JITC_ERR_LABELTYP; goto err_w; } // プログラムカウンタに TYP_CODEでない値は代入できない | |
562 | - } | |
563 | - if (src[1] == 0x3f) { // プログラムカウンタへの代入なら | |
564 | - if (w.prefix == 0) { // CND命令による条件付きでなければ、即座に移動 | |
565 | - jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */ | |
566 | - } | |
567 | - else { // 直前はCND命令。 | |
568 | - | |
569 | - /* | |
570 | - * CND命令 | |
571 | - * 1 2 | |
572 | - * 04 reg0R | |
573 | - * | |
574 | - * いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd | |
575 | - */ | |
576 | - | |
577 | - // JZのとび先アドレスの書き換え? | |
578 | - w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */ | |
579 | - w.dst[-2] = 0x0f; | |
580 | - | |
581 | - w.prefix = 0; | |
582 | - } | |
583 | - j = 0; | |
584 | - if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) // label番号iが確保されていれば (このif文は意味をなさない) | |
585 | - j = label[i].p - (w.dst + 4); // j はとび先の相対番地 | |
586 | - jitCompPutImm32(&w, j); // JMP もしくは JZ 命令のアドレス部を記述 | |
534 | + | |
535 | + /* reg0 のレジスタに対応したMOV命令を発行 */ | |
536 | + jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); == 10111000b+wr imm32 */ | |
537 | + jitCompPutImm32(&w, i); | |
538 | + | |
539 | + if (reg0 == 0) // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合 | |
540 | + | |
541 | + jitCompA0001_movRxxEax(&w, src[1]); | |
542 | + break; | |
543 | + | |
544 | + case 0x03: /* PLIMM */ /* 未完成(plsまで対応) */ | |
545 | + | |
546 | + /* | |
547 | + * PLIMM : ラベル番号代入命令(6byte) | |
548 | + * | |
549 | + * 1 2 3456 | |
550 | + * 03 PXX imm32 | |
551 | + * | |
552 | + * ・P28 はAPI用 | |
553 | + * ・P30 はリターンアドレス | |
554 | + * ・P3F はプログラムカウンタ | |
555 | + */ | |
556 | + | |
557 | + i = jitCompGetLabelNum(&w, src + 2); // Pxxに代入するラベルの番号(第二引数) | |
558 | + if ((flags & JITC_PHASE1) != 0 && w.err == 0) { // Phase 1であるならば | |
559 | + if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } // 指定されたラベル番号は存在しない | |
560 | + if (src[1] != 0x3f && label[i].opt != 2) { w.err = JITC_ERR_LABELTYP; goto err_w; } // | |
561 | + if (src[1] == 0x3f && label[i].typ != 0) { w.err = JITC_ERR_LABELTYP; goto err_w; } // プログラムカウンタに TYP_CODEでない値は代入できない | |
562 | + } | |
563 | + if (src[1] == 0x3f) { // プログラムカウンタへの代入なら | |
564 | + if (w.prefix == 0) { // CND命令による条件付きでなければ、即座に移動 | |
565 | + jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */ | |
566 | + } | |
567 | + else { // 直前はCND命令。 | |
568 | + | |
569 | + /* | |
570 | + * CND命令 | |
571 | + * 1 2 | |
572 | + * 04 reg0R | |
573 | + * | |
574 | + * いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd | |
575 | + */ | |
576 | + | |
577 | + // JZのとび先アドレスの書き換え? | |
578 | + w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */ | |
579 | + w.dst[-2] = 0x0f; | |
580 | + | |
581 | + w.prefix = 0; | |
582 | + } | |
583 | + j = 0; | |
584 | + if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) // label番号iが確保されていれば (このif文は意味をなさない) | |
585 | + j = label[i].p - (w.dst + 4); // j はとび先の相対番地 | |
586 | + jitCompPutImm32(&w, j); // JMP もしくは JZ 命令のアドレス部を記述 | |
587 | 587 | #if (jitCompA0001_OPTIMIZE_JMP != 0) |
588 | - if (-128 - 3 <= j && j < 0) { | |
589 | - if (w.dst[-5] == 0xe9) { | |
590 | - j += 3; | |
591 | - w.dst -= 5; | |
592 | - jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */ | |
593 | - } | |
594 | - else { | |
595 | - j += 4; | |
596 | - w.dst -= 6; | |
597 | - jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0); | |
598 | - } | |
599 | - jitCompPutByte1(w.dst, j & 0xff); | |
600 | - } | |
588 | + if (-128 - 3 <= j && j < 0) { | |
589 | + if (w.dst[-5] == 0xe9) { | |
590 | + j += 3; | |
591 | + w.dst -= 5; | |
592 | + jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */ | |
593 | + } | |
594 | + else { | |
595 | + j += 4; | |
596 | + w.dst -= 6; | |
597 | + jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0); | |
598 | + } | |
599 | + jitCompPutByte1(w.dst, j & 0xff); | |
600 | + } | |
601 | 601 | #endif |
602 | - } | |
603 | - else { // プログラムカウンタ以外への代入 | |
604 | - | |
605 | - // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定 | |
606 | - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
607 | - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ | |
608 | - jitCompPutImm32(&w, (int)label[i].p); // ラベルのパスを各レジスタに代入 | |
609 | - | |
610 | - // レジスタへの代入をメモリでエミュレーションする場合は、スタックに積む。 | |
611 | - if (reg0 == 0) | |
612 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32, 0); /* MOV([EBP+?], EAX); */ | |
613 | - | |
614 | - if (level < JITC_LV_FASTEST) { | |
615 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 8, reg0); /* MOV([EBP+?], reg0); */ /* p0 */ | |
616 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
617 | - jitCompPutImm32(&w, label[i].typ); | |
618 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 4, 0); /* MOV([EBP+?], EAX); */ /* typ */ | |
619 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
620 | - jitCompPutImm32(&w, (int)label[i].p1); | |
621 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 12, 0); /* MOV([EBP+?], EAX); */ /* p1 */ | |
622 | - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */ | |
623 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 16, 0); /* MOV([EBP+?], EAX); */ /* liveSign */ | |
624 | - jitCompA0001_movReg32EbpDisp(&w, 0, 2320); /* MOV(EAX, ptrCtrl); */ | |
625 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 20, 0); /* MOV([EBP+?], EAX); */ /* pls */ | |
626 | - } | |
627 | - } | |
628 | - break; | |
629 | - | |
630 | - case 0x04: /* CND (prefix) */ | |
631 | - | |
632 | - /* | |
633 | - * CND命令 | |
634 | - * 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。 | |
635 | - */ | |
636 | - | |
637 | - if (src[1] >= 0x40) w.err = JITC_ERR_REGNUM; // R00-R3F 以外のレジスタは比較対象にできない | |
638 | - | |
639 | - // 比較対象のレジスタがメモリ上にあれば-1, それ以外なら適切なレジスタ番号を返す | |
640 | - reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */); | |
641 | - | |
642 | - /* TEST命令を発行 */ | |
643 | - if (reg0 < 0) { //比較対象のレジスタはメモリ上にある | |
644 | - jitCompPutByte1(w.dst, 0xf7); /* TEST([EBP+?],1); */ | |
645 | - jitCompA0001_85DispN(&w, src[1] * 4, 0); | |
646 | - } | |
647 | - else { | |
648 | - jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST(reg0,1); */ | |
649 | - } | |
650 | - jitCompPutImm32(&w, 1); | |
651 | - | |
652 | - /* JZ命令を発行 */ | |
653 | - jitCompPutByte2(w.dst, 0x74, 0x00); /* JZ($+2) */ | |
654 | - cmp0reg = -1; | |
655 | - if (w.err != 0) goto err_w; | |
656 | - src += 2; | |
657 | - w.prefix = 1; // プリフィックスをセット | |
658 | - w.dst0 = w.dst; | |
659 | - goto prefix_continue; | |
660 | - | |
661 | - case 0x08: /* LMEM */ /* 完成 */ | |
662 | - i = jitCompGetImm32(src + 2); | |
663 | - if (i == 0x0001) w.err = JITC_ERR_BADTYPE; | |
664 | - if (level < JITC_LV_FASTER) { | |
665 | - jitCompA0001_checkType(&w, src[6], i, 0); // read | |
666 | - cmp0reg = -1; | |
667 | - } | |
668 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
669 | - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
670 | - if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) | |
671 | - reg1 = 0; /* EAX */ | |
672 | - if (reg1 == 2 /* EDX */) | |
673 | - jitCompA000_storeRegCacheEdx(&w); | |
674 | - if (reg1 <= 3 /* EAX, EDX */) | |
675 | - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
676 | - if (level < JITC_LV_FASTER) | |
677 | - jitCompA0001_checkLimit(&w, reg1, src[6]); | |
678 | - i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); | |
679 | - switch (i) { | |
680 | - case 0x0002: | |
681 | - jitCompPutByte3(w.dst, 0x0f, 0xbe, reg0 << 3 | reg1); /* MOVSX(reg0,BYTE [reg1]); */ | |
682 | - break; | |
683 | - case 0x0003: | |
684 | - jitCompPutByte3(w.dst, 0x0f, 0xb6, reg0 << 3 | reg1); /* MOVZX(reg0,BYTE [reg1]); */ | |
685 | - break; | |
686 | - case 0x0004: | |
687 | - jitCompPutByte3(w.dst, 0x0f, 0xbf, reg0 << 3 | reg1); /* MOVSX(reg0,WORD [reg1]); */ | |
688 | - break; | |
689 | - case 0x0005: | |
690 | - jitCompPutByte3(w.dst, 0x0f, 0xb7, reg0 << 3 | reg1); /* MOVZX(reg0,WORD [reg1]); */ | |
691 | - break; | |
692 | - case 0x0006: | |
693 | - case 0x0007: | |
694 | - jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */ | |
695 | - break; | |
696 | - default: | |
697 | - w.err = JITC_ERR_BADTYPE; | |
698 | - } | |
699 | - if (reg0 == 0 /* EAX */) | |
700 | - jitCompA0001_movRxxEax(&w, src[1]); | |
701 | - if (reg1 == 2 /* EDX */) | |
702 | - jitCompA000_loadRegCacheEdx(&w); | |
703 | - break; | |
704 | - | |
705 | - case 0x09: /* SMEM */ /* 完成 */ | |
706 | - i = jitCompGetImm32(src + 2); | |
707 | - if (i == 0x0001) w.err = JITC_ERR_BADTYPE; | |
708 | - if (level < JITC_LV_FASTER) { | |
709 | - jitCompA0001_checkType(&w, src[6], i, 1); // write | |
710 | - cmp0reg = -1; | |
711 | - } | |
712 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
713 | - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
714 | - if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) | |
715 | - reg1 = 0; /* EAX */ | |
716 | - if (reg1 == 2 /* EDX */) | |
717 | - jitCompA000_storeRegCacheEdx(&w); | |
718 | - if (reg1 <= 3 /* EAX, EDX */) | |
719 | - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
720 | - if (level < JITC_LV_FASTER) | |
721 | - jitCompA0001_checkLimit(&w, reg1, src[6]); | |
722 | - if (reg0 == 0 /* EAX */) | |
723 | - jitCompA0001_movEaxRxx(&w, src[1]); | |
724 | - /* 値の範囲チェック */ | |
725 | - i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); | |
726 | - switch (i) { | |
727 | - case 0x0002: | |
728 | - case 0x0003: | |
729 | - jitCompPutByte2(w.dst, 0x88, reg0 << 3 | reg1); /* MOV([reg1], BYTE(reg0)); */ | |
730 | - break; | |
731 | - case 0x0004: | |
732 | - case 0x0005: | |
733 | - jitCompPutByte3(w.dst, 0x66, 0x89, reg0 << 3 | reg1); /* MOV([reg1], WORD(reg0)); */ | |
734 | - break; | |
735 | - case 0x0006: | |
736 | - case 0x0007: | |
737 | - jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */ | |
738 | - break; | |
739 | - default: | |
740 | - w.err = JITC_ERR_BADTYPE; | |
741 | - } | |
742 | - if (reg1 == 2 /* EDX */) | |
743 | - jitCompA000_loadRegCacheEdx(&w); | |
744 | - break; | |
745 | - | |
746 | - case 0x0a: /* PLMEM */ /* 完成 */ | |
747 | - i = jitCompGetImm32(src + 2); | |
748 | - if (i != 0x0001) w.err = JITC_ERR_BADTYPE; | |
749 | - if (level < JITC_LV_FASTER) { | |
750 | - jitCompA0001_checkType(&w, src[6], i, 0); // read | |
751 | - cmp0reg = -1; | |
752 | - } | |
753 | - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
754 | - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
755 | - // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */ | |
756 | - // reg1 = 0; /* EAX */ | |
757 | - if (reg0 == reg1 && reg0 != 0) { // bugfix: hinted by yao, 2013.09.14. thanks! | |
758 | - jitCompA000_storePRegCacheAll(&w); | |
759 | - reg1 = 2; /* EDX */ | |
760 | - } | |
761 | - if (reg1 == 2 /* EDX */) | |
762 | - jitCompA000_storeRegCacheEdx(&w); | |
763 | - if (reg1 <= 3 /* EAX, EDX */) | |
764 | - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
765 | - if (level < JITC_LV_FASTER) | |
766 | - jitCompA0001_checkLimit(&w, reg1, src[6]); | |
767 | - jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */ | |
768 | - if (reg0 == 0 /* EAX */) | |
769 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0); /* MOV([EBP+?], EAX); */ | |
770 | - for (i = 4; i < 32; i += 4) { | |
771 | - jitCompPutByte3(w.dst, 0x8b, 0x40 | reg1, i); /* MOV(EAX, [reg1+?]); */ | |
772 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
773 | - } | |
774 | - if (reg1 == 2 /* EDX */) | |
775 | - jitCompA000_loadRegCacheEdx(&w); | |
776 | - break; | |
777 | - | |
778 | - case 0x0b: /* PSMEM */ /* 完成 */ | |
779 | - i = jitCompGetImm32(src + 2); | |
780 | - if (i != 0x0001) w.err = JITC_ERR_BADTYPE; | |
781 | - if (level < JITC_LV_FASTER) { | |
782 | - jitCompA0001_checkType(&w, src[6], i, 1); // write | |
783 | - cmp0reg = -1; | |
784 | - } | |
785 | - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
786 | - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
787 | - // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */ | |
788 | - // reg1 = 0; /* EAX */ | |
789 | - if (reg1 == 2 /* EDX */) | |
790 | - jitCompA000_storeRegCacheEdx(&w); | |
791 | - if (reg1 <= 3 /* EAX, EDX */) | |
792 | - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
793 | - if (level < JITC_LV_FASTER) | |
794 | - jitCompA0001_checkLimit(&w, reg1, src[6]); | |
795 | - if (reg0 == 0 /* EAX */) | |
796 | - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[1] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
797 | - jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */ | |
798 | - for (i = 4; i < 32; i += 4) { | |
799 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[1] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
800 | - jitCompPutByte3(w.dst, 0x89, 0x40 | reg1, i); /* MOV([reg1+?], EAX); */ | |
801 | - } | |
802 | - if (reg1 == 2 /* EDX */) | |
803 | - jitCompA000_loadRegCacheEdx(&w); | |
804 | - break; | |
805 | - | |
806 | - case 0x0e: /* PADD */ /* 完成 */ | |
807 | - if (level < JITC_LV_FASTER) { | |
808 | - jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 2), 2); // other, aliveテストはとりあえずしない. | |
809 | - cmp0reg = -1; | |
810 | - } | |
811 | - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
812 | - reg1 = jitCompA000_selectPRegCache(src[6], -1 /* mem */); | |
813 | - if (reg1 < 0 /* mem */) | |
814 | - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
815 | - if (reg1 >= 0 && reg0 != reg1) { | |
816 | - jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ | |
817 | - } | |
818 | - i = jitCompGetImm32(src + 2); | |
819 | - j = -1; | |
820 | - if (i == 1) | |
821 | - j = 5; /* 32 */ | |
822 | - else { | |
823 | - i = jitCompA000_convTyp(i); | |
824 | - if (0x0002 <= i && i <= 0x0007) | |
825 | - j = (i - 0x0002) >> 1; | |
826 | - } | |
827 | - if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
602 | + } | |
603 | + else { // プログラムカウンタ以外への代入 | |
604 | + | |
605 | + // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定 | |
606 | + reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
607 | + jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ | |
608 | + jitCompPutImm32(&w, (int)label[i].p); // ラベルのパスを各レジスタに代入 | |
609 | + | |
610 | + // レジスタへの代入をメモリでエミュレーションする場合は、スタックに積む。 | |
611 | + if (reg0 == 0) | |
612 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32, 0); /* MOV([EBP+?], EAX); */ | |
613 | + | |
614 | + if (level < JITC_LV_FASTEST) { | |
615 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 8, reg0); /* MOV([EBP+?], reg0); */ /* p0 */ | |
616 | + jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
617 | + jitCompPutImm32(&w, label[i].typ); | |
618 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 4, 0); /* MOV([EBP+?], EAX); */ /* typ */ | |
619 | + jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
620 | + jitCompPutImm32(&w, (int)label[i].p1); | |
621 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 12, 0); /* MOV([EBP+?], EAX); */ /* p1 */ | |
622 | + jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */ | |
623 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 16, 0); /* MOV([EBP+?], EAX); */ /* liveSign */ | |
624 | + jitCompA0001_movReg32EbpDisp(&w, 0, 2320); /* MOV(EAX, ptrCtrl); */ | |
625 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 20, 0); /* MOV([EBP+?], EAX); */ /* pls */ | |
626 | + } | |
627 | + } | |
628 | + break; | |
629 | + | |
630 | + case 0x04: /* CND (prefix) */ | |
631 | + | |
632 | + /* | |
633 | + * CND命令 | |
634 | + * 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。 | |
635 | + */ | |
636 | + | |
637 | + if (src[1] >= 0x40) w.err = JITC_ERR_REGNUM; // R00-R3F 以外のレジスタは比較対象にできない | |
638 | + | |
639 | + // 比較対象のレジスタがメモリ上にあれば-1, それ以外なら適切なレジスタ番号を返す | |
640 | + reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */); | |
641 | + | |
642 | + /* TEST命令を発行 */ | |
643 | + if (reg0 < 0) { //比較対象のレジスタはメモリ上にある | |
644 | + jitCompPutByte1(w.dst, 0xf7); /* TEST([EBP+?],1); */ | |
645 | + jitCompA0001_85DispN(&w, src[1] * 4, 0); | |
646 | + } | |
647 | + else { | |
648 | + jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST(reg0,1); */ | |
649 | + } | |
650 | + jitCompPutImm32(&w, 1); | |
651 | + | |
652 | + /* JZ命令を発行 */ | |
653 | + jitCompPutByte2(w.dst, 0x74, 0x00); /* JZ($+2) */ | |
654 | + cmp0reg = -1; | |
655 | + if (w.err != 0) goto err_w; | |
656 | + src += 2; | |
657 | + w.prefix = 1; // プリフィックスをセット | |
658 | + w.dst0 = w.dst; | |
659 | + goto prefix_continue; | |
660 | + | |
661 | + case 0x08: /* LMEM */ /* 完成 */ | |
662 | + i = jitCompGetImm32(src + 2); | |
663 | + if (i == 0x0001) w.err = JITC_ERR_BADTYPE; | |
664 | + if (level < JITC_LV_FASTER) { | |
665 | + jitCompA0001_checkType(&w, src[6], i, 0); // read | |
666 | + cmp0reg = -1; | |
667 | + } | |
668 | + reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
669 | + reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
670 | + if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) | |
671 | + reg1 = 0; /* EAX */ | |
672 | + if (reg1 == 2 /* EDX */) | |
673 | + jitCompA000_storeRegCacheEdx(&w); | |
674 | + if (reg1 <= 3 /* EAX, EDX */) | |
675 | + jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
676 | + if (level < JITC_LV_FASTER) | |
677 | + jitCompA0001_checkLimit(&w, reg1, src[6]); | |
678 | + i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); | |
679 | + switch (i) { | |
680 | + case 0x0002: | |
681 | + jitCompPutByte3(w.dst, 0x0f, 0xbe, reg0 << 3 | reg1); /* MOVSX(reg0,BYTE [reg1]); */ | |
682 | + break; | |
683 | + case 0x0003: | |
684 | + jitCompPutByte3(w.dst, 0x0f, 0xb6, reg0 << 3 | reg1); /* MOVZX(reg0,BYTE [reg1]); */ | |
685 | + break; | |
686 | + case 0x0004: | |
687 | + jitCompPutByte3(w.dst, 0x0f, 0xbf, reg0 << 3 | reg1); /* MOVSX(reg0,WORD [reg1]); */ | |
688 | + break; | |
689 | + case 0x0005: | |
690 | + jitCompPutByte3(w.dst, 0x0f, 0xb7, reg0 << 3 | reg1); /* MOVZX(reg0,WORD [reg1]); */ | |
691 | + break; | |
692 | + case 0x0006: | |
693 | + case 0x0007: | |
694 | + jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */ | |
695 | + break; | |
696 | + default: | |
697 | + w.err = JITC_ERR_BADTYPE; | |
698 | + } | |
699 | + if (reg0 == 0 /* EAX */) | |
700 | + jitCompA0001_movRxxEax(&w, src[1]); | |
701 | + if (reg1 == 2 /* EDX */) | |
702 | + jitCompA000_loadRegCacheEdx(&w); | |
703 | + break; | |
704 | + | |
705 | + case 0x09: /* SMEM */ /* 完成 */ | |
706 | + i = jitCompGetImm32(src + 2); | |
707 | + if (i == 0x0001) w.err = JITC_ERR_BADTYPE; | |
708 | + if (level < JITC_LV_FASTER) { | |
709 | + jitCompA0001_checkType(&w, src[6], i, 1); // write | |
710 | + cmp0reg = -1; | |
711 | + } | |
712 | + reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
713 | + reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
714 | + if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) | |
715 | + reg1 = 0; /* EAX */ | |
716 | + if (reg1 == 2 /* EDX */) | |
717 | + jitCompA000_storeRegCacheEdx(&w); | |
718 | + if (reg1 <= 3 /* EAX, EDX */) | |
719 | + jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
720 | + if (level < JITC_LV_FASTER) | |
721 | + jitCompA0001_checkLimit(&w, reg1, src[6]); | |
722 | + if (reg0 == 0 /* EAX */) | |
723 | + jitCompA0001_movEaxRxx(&w, src[1]); | |
724 | + /* 値の範囲チェック */ | |
725 | + i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); | |
726 | + switch (i) { | |
727 | + case 0x0002: | |
728 | + case 0x0003: | |
729 | + jitCompPutByte2(w.dst, 0x88, reg0 << 3 | reg1); /* MOV([reg1], BYTE(reg0)); */ | |
730 | + break; | |
731 | + case 0x0004: | |
732 | + case 0x0005: | |
733 | + jitCompPutByte3(w.dst, 0x66, 0x89, reg0 << 3 | reg1); /* MOV([reg1], WORD(reg0)); */ | |
734 | + break; | |
735 | + case 0x0006: | |
736 | + case 0x0007: | |
737 | + jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */ | |
738 | + break; | |
739 | + default: | |
740 | + w.err = JITC_ERR_BADTYPE; | |
741 | + } | |
742 | + if (reg1 == 2 /* EDX */) | |
743 | + jitCompA000_loadRegCacheEdx(&w); | |
744 | + break; | |
745 | + | |
746 | + case 0x0a: /* PLMEM */ /* 完成 */ | |
747 | + i = jitCompGetImm32(src + 2); | |
748 | + if (i != 0x0001) w.err = JITC_ERR_BADTYPE; | |
749 | + if (level < JITC_LV_FASTER) { | |
750 | + jitCompA0001_checkType(&w, src[6], i, 0); // read | |
751 | + cmp0reg = -1; | |
752 | + } | |
753 | + reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
754 | + reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
755 | + // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */ | |
756 | + // reg1 = 0; /* EAX */ | |
757 | + if (reg0 == reg1 && reg0 != 0) { // bugfix: hinted by yao, 2013.09.14. thanks! | |
758 | + jitCompA000_storePRegCacheAll(&w); | |
759 | + reg1 = 2; /* EDX */ | |
760 | + } | |
761 | + if (reg1 == 2 /* EDX */) | |
762 | + jitCompA000_storeRegCacheEdx(&w); | |
763 | + if (reg1 <= 3 /* EAX, EDX */) | |
764 | + jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
765 | + if (level < JITC_LV_FASTER) | |
766 | + jitCompA0001_checkLimit(&w, reg1, src[6]); | |
767 | + jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */ | |
768 | + if (reg0 == 0 /* EAX */) | |
769 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0); /* MOV([EBP+?], EAX); */ | |
770 | + for (i = 4; i < 32; i += 4) { | |
771 | + jitCompPutByte3(w.dst, 0x8b, 0x40 | reg1, i); /* MOV(EAX, [reg1+?]); */ | |
772 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
773 | + } | |
774 | + if (reg1 == 2 /* EDX */) | |
775 | + jitCompA000_loadRegCacheEdx(&w); | |
776 | + break; | |
777 | + | |
778 | + case 0x0b: /* PSMEM */ /* 完成 */ | |
779 | + i = jitCompGetImm32(src + 2); | |
780 | + if (i != 0x0001) w.err = JITC_ERR_BADTYPE; | |
781 | + if (level < JITC_LV_FASTER) { | |
782 | + jitCompA0001_checkType(&w, src[6], i, 1); // write | |
783 | + cmp0reg = -1; | |
784 | + } | |
785 | + reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
786 | + reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
787 | + // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */ | |
788 | + // reg1 = 0; /* EAX */ | |
789 | + if (reg1 == 2 /* EDX */) | |
790 | + jitCompA000_storeRegCacheEdx(&w); | |
791 | + if (reg1 <= 3 /* EAX, EDX */) | |
792 | + jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
793 | + if (level < JITC_LV_FASTER) | |
794 | + jitCompA0001_checkLimit(&w, reg1, src[6]); | |
795 | + if (reg0 == 0 /* EAX */) | |
796 | + jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[1] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
797 | + jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */ | |
798 | + for (i = 4; i < 32; i += 4) { | |
799 | + jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[1] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
800 | + jitCompPutByte3(w.dst, 0x89, 0x40 | reg1, i); /* MOV([reg1+?], EAX); */ | |
801 | + } | |
802 | + if (reg1 == 2 /* EDX */) | |
803 | + jitCompA000_loadRegCacheEdx(&w); | |
804 | + break; | |
805 | + | |
806 | + case 0x0e: /* PADD */ /* 完成 */ | |
807 | + if (level < JITC_LV_FASTER) { | |
808 | + jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 2), 2); // other, aliveテストはとりあえずしない. | |
809 | + cmp0reg = -1; | |
810 | + } | |
811 | + reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
812 | + reg1 = jitCompA000_selectPRegCache(src[6], -1 /* mem */); | |
813 | + if (reg1 < 0 /* mem */) | |
814 | + jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
815 | + if (reg1 >= 0 && reg0 != reg1) { | |
816 | + jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ | |
817 | + } | |
818 | + i = jitCompGetImm32(src + 2); | |
819 | + j = -1; | |
820 | + if (i == 1) | |
821 | + j = 5; /* 32 */ | |
822 | + else { | |
823 | + i = jitCompA000_convTyp(i); | |
824 | + if (0x0002 <= i && i <= 0x0007) | |
825 | + j = (i - 0x0002) >> 1; | |
826 | + } | |
827 | + if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
828 | 828 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
829 | - if (src[7] == 0x3f) { | |
830 | - j = w.r3f << j; | |
829 | + if (src[7] == 0x3f) { | |
830 | + j = w.r3f << j; | |
831 | 831 | #if (jitCompA0001_USE_R3F_IMM8 != 0) |
832 | - if (-0x80 <= j && j <= 0x7f) { | |
832 | + if (-0x80 <= j && j <= 0x7f) { | |
833 | 833 | #if (jitCompA0001_USE_R3F_INCDEC != 0) |
834 | - if (j == 1) { jitCompPutByte1(w.dst, 0x40 | reg0); goto padd1; } /* INC */ | |
835 | - if (j == -1) { jitCompPutByte1(w.dst, 0x48 | reg0); goto padd1; } /* DEC */ | |
834 | + if (j == 1) { jitCompPutByte1(w.dst, 0x40 | reg0); goto padd1; } /* INC */ | |
835 | + if (j == -1) { jitCompPutByte1(w.dst, 0x48 | reg0); goto padd1; } /* DEC */ | |
836 | 836 | #endif |
837 | - jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff); /* ADD(reg0, im8); */ | |
838 | - goto padd1; | |
839 | - } | |
837 | + jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff); /* ADD(reg0, im8); */ | |
838 | + goto padd1; | |
839 | + } | |
840 | 840 | #endif |
841 | - if (reg0 == 0) { | |
842 | - jitCompPutByte1(w.dst, 0x05); /* ADD(reg0, ?); */ | |
843 | - } | |
844 | - else { | |
845 | - jitCompPutByte2(w.dst, 0x81, 0xc0 | reg0); /* ADD(reg0, ?); */ | |
846 | - } | |
847 | - jitCompPutImm32(&w, j); | |
848 | - goto padd1; | |
849 | - } | |
841 | + if (reg0 == 0) { | |
842 | + jitCompPutByte1(w.dst, 0x05); /* ADD(reg0, ?); */ | |
843 | + } | |
844 | + else { | |
845 | + jitCompPutByte2(w.dst, 0x81, 0xc0 | reg0); /* ADD(reg0, ?); */ | |
846 | + } | |
847 | + jitCompPutImm32(&w, j); | |
848 | + goto padd1; | |
849 | + } | |
850 | 850 | #endif |
851 | - if (src[7] >= 0x40) w.err = JITC_ERR_REGNUM; | |
852 | - if (j == 0) { | |
853 | - reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */); | |
854 | - if (reg1 >= 0) { | |
855 | - jitCompPutByte2(w.dst, 0x01, 0xc0 | reg1 << 3 | reg0); /* ADD(reg0, reg1); */ | |
856 | - } | |
857 | - else { | |
858 | - jitCompPutByte1(w.dst, 0x03); /* ADD(reg0, [EBP+?]); */ | |
859 | - jitCompA0001_85DispN(&w, src[7] * 4, reg0); | |
860 | - } | |
861 | - } | |
862 | - else { | |
863 | - reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */); | |
864 | - reg2 = 2; /* EDX */ | |
865 | - jitCompA000_storeRegCacheEdx(&w); | |
866 | - if (reg1 < 0) | |
867 | - jitCompA0001_movReg32EbpDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */ | |
868 | - if (reg1 >= 0 && reg1 != reg2) { | |
869 | - jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg2); /* MOV(reg2, reg1); */ | |
870 | - } | |
871 | - jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg2, j); /* SHL(reg2, ?); */ | |
872 | - jitCompPutByte2(w.dst, 0x01, 0xc0 | reg2 << 3 | reg0); /* ADD(reg0, reg2); */ | |
873 | - jitCompA000_loadRegCacheEdx(&w); | |
874 | - } | |
851 | + if (src[7] >= 0x40) w.err = JITC_ERR_REGNUM; | |
852 | + if (j == 0) { | |
853 | + reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */); | |
854 | + if (reg1 >= 0) { | |
855 | + jitCompPutByte2(w.dst, 0x01, 0xc0 | reg1 << 3 | reg0); /* ADD(reg0, reg1); */ | |
856 | + } | |
857 | + else { | |
858 | + jitCompPutByte1(w.dst, 0x03); /* ADD(reg0, [EBP+?]); */ | |
859 | + jitCompA0001_85DispN(&w, src[7] * 4, reg0); | |
860 | + } | |
861 | + } | |
862 | + else { | |
863 | + reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */); | |
864 | + reg2 = 2; /* EDX */ | |
865 | + jitCompA000_storeRegCacheEdx(&w); | |
866 | + if (reg1 < 0) | |
867 | + jitCompA0001_movReg32EbpDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */ | |
868 | + if (reg1 >= 0 && reg1 != reg2) { | |
869 | + jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg2); /* MOV(reg2, reg1); */ | |
870 | + } | |
871 | + jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg2, j); /* SHL(reg2, ?); */ | |
872 | + jitCompPutByte2(w.dst, 0x01, 0xc0 | reg2 << 3 | reg0); /* ADD(reg0, reg2); */ | |
873 | + jitCompA000_loadRegCacheEdx(&w); | |
874 | + } | |
875 | 875 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
876 | - padd1: | |
876 | + padd1: | |
877 | 877 | #endif |
878 | - if (reg0 == 0 /* EAX */) | |
879 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, reg0); /* MOV([EBP+?], reg0); */ | |
880 | - if (src[1] != src[6]) { | |
881 | - for (i = 4; i < 32; i += 4) { | |
882 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
883 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
884 | - } | |
885 | - } | |
886 | - cmp0reg = -1; | |
887 | - break; | |
888 | - | |
889 | - case 0x0f: /* PDIF */ /* 未完成 */ | |
890 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
891 | - jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
892 | - jitCompA0001_checkCompPtr(&w, src[6], src[7]); | |
893 | - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
894 | - jitCompPutByte1(w.dst, 0x2b); /* SUB(EAX, [EBP+?]); */ | |
895 | - jitCompA0001_85DispN(&w, 256 + src[7] * 32 + 0, reg0); | |
896 | - i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); | |
897 | - j = -1; | |
898 | - if (0x0002 <= i && i <= 0x0007) | |
899 | - j = (i - 0x0002) >> 1; | |
900 | - if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
901 | - if (j > 0) { | |
902 | - jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, j); /* SAR(reg0,?); */ | |
903 | - } | |
904 | - if (reg0 == 0 /* EAX */) | |
905 | - jitCompA0001_movRxxEax(&w, src[1]); | |
906 | - cmp0reg = src[1]; cmp0lev = 1; | |
907 | - break; | |
908 | - | |
909 | - case 0x10: /* OR */ | |
910 | - case 0x11: /* XOR */ | |
911 | - case 0x12: /* AND */ | |
912 | - case 0x14: /* ADD */ | |
913 | - case 0x15: /* SUB */ | |
914 | - case 0x16: /* MUL */ | |
915 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
916 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
917 | - reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); | |
878 | + if (reg0 == 0 /* EAX */) | |
879 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, reg0); /* MOV([EBP+?], reg0); */ | |
880 | + if (src[1] != src[6]) { | |
881 | + for (i = 4; i < 32; i += 4) { | |
882 | + jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
883 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
884 | + } | |
885 | + } | |
886 | + cmp0reg = -1; | |
887 | + break; | |
888 | + | |
889 | + case 0x0f: /* PDIF */ /* 未完成 */ | |
890 | + reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
891 | + jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
892 | + jitCompA0001_checkCompPtr(&w, src[6], src[7]); | |
893 | + jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
894 | + jitCompPutByte1(w.dst, 0x2b); /* SUB(EAX, [EBP+?]); */ | |
895 | + jitCompA0001_85DispN(&w, 256 + src[7] * 32 + 0, reg0); | |
896 | + i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); | |
897 | + j = -1; | |
898 | + if (0x0002 <= i && i <= 0x0007) | |
899 | + j = (i - 0x0002) >> 1; | |
900 | + if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
901 | + if (j > 0) { | |
902 | + jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, j); /* SAR(reg0,?); */ | |
903 | + } | |
904 | + if (reg0 == 0 /* EAX */) | |
905 | + jitCompA0001_movRxxEax(&w, src[1]); | |
906 | + cmp0reg = src[1]; cmp0lev = 1; | |
907 | + break; | |
908 | + | |
909 | + case 0x10: /* OR */ | |
910 | + case 0x11: /* XOR */ | |
911 | + case 0x12: /* AND */ | |
912 | + case 0x14: /* ADD */ | |
913 | + case 0x15: /* SUB */ | |
914 | + case 0x16: /* MUL */ | |
915 | + if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
916 | + reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
917 | + reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); | |
918 | 918 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
919 | - if (src[2] == 0x3f) { // SUBのみ該当. | |
920 | - if (*src != 0x15) w.err = JITC_ERR_REGNUM; | |
921 | - reg2 = jitCompA000_selectRegCache(src[3], -1 /* mem */); | |
922 | - if (reg2 >= 0) | |
923 | - jitCompA000_storeRegCacheAll(&w); | |
924 | - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ | |
925 | - jitCompPutImm32(&w, w.r3f); | |
926 | - jitCompPutByte1(w.dst, 0x2b); | |
927 | - jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
928 | - if (reg0 == 0) | |
929 | - jitCompA0001_movRxxEax(&w, src[1]); | |
930 | - break; | |
931 | - } | |
919 | + if (src[2] == 0x3f) { // SUBのみ該当. | |
920 | + if (*src != 0x15) w.err = JITC_ERR_REGNUM; | |
921 | + reg2 = jitCompA000_selectRegCache(src[3], -1 /* mem */); | |
922 | + if (reg2 >= 0) | |
923 | + jitCompA000_storeRegCacheAll(&w); | |
924 | + jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ | |
925 | + jitCompPutImm32(&w, w.r3f); | |
926 | + jitCompPutByte1(w.dst, 0x2b); | |
927 | + jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
928 | + if (reg0 == 0) | |
929 | + jitCompA0001_movRxxEax(&w, src[1]); | |
930 | + break; | |
931 | + } | |
932 | 932 | #endif |
933 | - if (reg1 < 0) { | |
934 | - jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg0, [EBP+?]); */ | |
935 | - } | |
936 | - if (reg1 >= 0 && reg0 != reg1) { | |
937 | - jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ | |
938 | - } | |
939 | - if (!(src[0] == 0x10 && src[3] == 0xff)) { // bugfix: hinted by Iris, 2013.06.26. thanks! | |
940 | - cmp0reg = src[1]; | |
941 | - cmp0lev = 1; | |
942 | - if (src[0] < 0x14) | |
943 | - cmp0lev = 2; | |
944 | - if (src[0] == 0x16) | |
945 | - cmp0reg = -1; | |
946 | - } | |
947 | - if (!(src[0] == 0x10 && src[3] == 0xff)) { | |
933 | + if (reg1 < 0) { | |
934 | + jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg0, [EBP+?]); */ | |
935 | + } | |
936 | + if (reg1 >= 0 && reg0 != reg1) { | |
937 | + jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ | |
938 | + } | |
939 | + if (!(src[0] == 0x10 && src[3] == 0xff)) { // bugfix: hinted by Iris, 2013.06.26. thanks! | |
940 | + cmp0reg = src[1]; | |
941 | + cmp0lev = 1; | |
942 | + if (src[0] < 0x14) | |
943 | + cmp0lev = 2; | |
944 | + if (src[0] == 0x16) | |
945 | + cmp0reg = -1; | |
946 | + } | |
947 | + if (!(src[0] == 0x10 && src[3] == 0xff)) { | |
948 | 948 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
949 | - if (src[3] == 0x3f) { | |
950 | - if (*src == 0x16 && w.r3f == -1) { | |
951 | - jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */ | |
952 | - if (reg0 == 0) | |
953 | - jitCompA0001_movRxxEax(&w, src[1]); | |
954 | - break; | |
955 | - } | |
949 | + if (src[3] == 0x3f) { | |
950 | + if (*src == 0x16 && w.r3f == -1) { | |
951 | + jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */ | |
952 | + if (reg0 == 0) | |
953 | + jitCompA0001_movRxxEax(&w, src[1]); | |
954 | + break; | |
955 | + } | |
956 | 956 | #if (jitCompA0001_USE_R3F_INCDEC != 0) |
957 | - if ((*src == 0x14 && w.r3f == 1) || (*src == 0x15 && w.r3f == -1)) { | |
958 | - jitCompPutByte1(w.dst, 0x40 | reg0); /* INC(reg0); */ | |
959 | - if (reg0 == 0) | |
960 | - jitCompA0001_movRxxEax(&w, src[1]); | |
961 | - break; | |
962 | - } | |
963 | - if ((*src == 0x15 && w.r3f == 1) || (*src == 0x14 && w.r3f == -1)) { | |
964 | - jitCompPutByte1(w.dst, 0x48 | reg0); /* DEC(reg0); */ | |
965 | - if (reg0 == 0) | |
966 | - jitCompA0001_movRxxEax(&w, src[1]); | |
967 | - break; | |
968 | - } | |
957 | + if ((*src == 0x14 && w.r3f == 1) || (*src == 0x15 && w.r3f == -1)) { | |
958 | + jitCompPutByte1(w.dst, 0x40 | reg0); /* INC(reg0); */ | |
959 | + if (reg0 == 0) | |
960 | + jitCompA0001_movRxxEax(&w, src[1]); | |
961 | + break; | |
962 | + } | |
963 | + if ((*src == 0x15 && w.r3f == 1) || (*src == 0x14 && w.r3f == -1)) { | |
964 | + jitCompPutByte1(w.dst, 0x48 | reg0); /* DEC(reg0); */ | |
965 | + if (reg0 == 0) | |
966 | + jitCompA0001_movRxxEax(&w, src[1]); | |
967 | + break; | |
968 | + } | |
969 | 969 | #endif |
970 | 970 | #if (jitCompA0001_USE_R3F_IMM8 != 0) |
971 | - if (-0x80 <= w.r3f && w.r3f <= 0x7f) { | |
972 | - if (*src != 0x16) { | |
973 | - static unsigned char basic_op_table_im8[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 }; | |
974 | - jitCompPutByte3(w.dst, 0x83, basic_op_table_im8[*src - 0x10] | reg0, w.r3f & 0xff); | |
975 | - } | |
976 | - else { | |
977 | - jitCompPutByte3(w.dst, 0x6b, 0xc0 | reg0 << 3 | reg0, w.r3f & 0xff); | |
978 | - } | |
979 | - if (reg0 == 0) | |
980 | - jitCompA0001_movRxxEax(&w, src[1]); | |
981 | - break; | |
982 | - } | |
971 | + if (-0x80 <= w.r3f && w.r3f <= 0x7f) { | |
972 | + if (*src != 0x16) { | |
973 | + static unsigned char basic_op_table_im8[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 }; | |
974 | + jitCompPutByte3(w.dst, 0x83, basic_op_table_im8[*src - 0x10] | reg0, w.r3f & 0xff); | |
975 | + } | |
976 | + else { | |
977 | + jitCompPutByte3(w.dst, 0x6b, 0xc0 | reg0 << 3 | reg0, w.r3f & 0xff); | |
978 | + } | |
979 | + if (reg0 == 0) | |
980 | + jitCompA0001_movRxxEax(&w, src[1]); | |
981 | + break; | |
982 | + } | |
983 | 983 | #endif |
984 | - if (reg0 == 0 /* EAX */) { | |
985 | - static unsigned char basic_op_table_im32_eax[] = { 0x0d, 0x35, 0x25, 0, 0x05, 0x2d, 0xc0 }; | |
986 | - if (*src == 0x16) { jitCompPutByte1(w.dst, 0x69); } | |
987 | - jitCompPutByte1(w.dst, basic_op_table_im32_eax[*src - 0x10]); | |
988 | - } | |
989 | - else { | |
990 | - if (*src != 0x16) { | |
991 | - static unsigned char basic_op_table_im32_reg[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 }; | |
992 | - jitCompPutByte2(w.dst, 0x81, basic_op_table_im32_reg[*src - 0x10] | reg0); | |
993 | - } | |
994 | - else { | |
995 | - jitCompPutByte2(w.dst, 0x69, 0xc0 | reg0 << 3 | reg0); | |
996 | - } | |
997 | - } | |
998 | - jitCompPutImm32(&w, w.r3f); | |
999 | - if (reg0 == 0) | |
1000 | - jitCompA0001_movRxxEax(&w, src[1]); | |
1001 | - break; | |
1002 | - } | |
984 | + if (reg0 == 0 /* EAX */) { | |
985 | + static unsigned char basic_op_table_im32_eax[] = { 0x0d, 0x35, 0x25, 0, 0x05, 0x2d, 0xc0 }; | |
986 | + if (*src == 0x16) { jitCompPutByte1(w.dst, 0x69); } | |
987 | + jitCompPutByte1(w.dst, basic_op_table_im32_eax[*src - 0x10]); | |
988 | + } | |
989 | + else { | |
990 | + if (*src != 0x16) { | |
991 | + static unsigned char basic_op_table_im32_reg[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 }; | |
992 | + jitCompPutByte2(w.dst, 0x81, basic_op_table_im32_reg[*src - 0x10] | reg0); | |
993 | + } | |
994 | + else { | |
995 | + jitCompPutByte2(w.dst, 0x69, 0xc0 | reg0 << 3 | reg0); | |
996 | + } | |
997 | + } | |
998 | + jitCompPutImm32(&w, w.r3f); | |
999 | + if (reg0 == 0) | |
1000 | + jitCompA0001_movRxxEax(&w, src[1]); | |
1001 | + break; | |
1002 | + } | |
1003 | 1003 | #endif |
1004 | - reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); | |
1005 | - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
1006 | - if (*src != 0x16) { | |
1007 | - if (reg1 >= 0) { | |
1008 | - static unsigned char basic_op_table_rr[] = { 0x09, 0x31, 0x21, 0, 0x01, 0x29 }; /* op(reg,reg); */ | |
1009 | - jitCompPutByte2(w.dst, basic_op_table_rr[*src - 0x10], 0xc0 | reg1 << 3 | reg0); | |
1010 | - } | |
1011 | - else { | |
1012 | - static unsigned char basic_op_table_rm[] = { 0x0b, 0x33, 0x23, 0, 0x03, 0x2b, 0xaf }; /* op(reg,mem); */ | |
1013 | - jitCompPutByte1(w.dst, basic_op_table_rm[*src - 0x10]); | |
1014 | - jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
1015 | - } | |
1016 | - } | |
1017 | - else { | |
1018 | - if (reg1 >= 0) { | |
1019 | - jitCompPutByte3(w.dst, 0x0f, 0xaf, 0xc0 | reg0 << 3 | reg1); | |
1020 | - } | |
1021 | - else { | |
1022 | - jitCompPutByte2(w.dst, 0x0f, 0xaf); | |
1023 | - jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
1024 | - } | |
1025 | - } | |
1026 | - } | |
1027 | - if (reg0 == 0) | |
1028 | - jitCompA0001_movRxxEax(&w, src[1]); | |
1029 | - break; | |
1030 | - | |
1031 | - case 0x18: /* SHL */ | |
1032 | - case 0x19: /* SAR */ | |
1033 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
1034 | - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
1004 | + reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); | |
1005 | + if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
1006 | + if (*src != 0x16) { | |
1007 | + if (reg1 >= 0) { | |
1008 | + static unsigned char basic_op_table_rr[] = { 0x09, 0x31, 0x21, 0, 0x01, 0x29 }; /* op(reg,reg); */ | |
1009 | + jitCompPutByte2(w.dst, basic_op_table_rr[*src - 0x10], 0xc0 | reg1 << 3 | reg0); | |
1010 | + } | |
1011 | + else { | |
1012 | + static unsigned char basic_op_table_rm[] = { 0x0b, 0x33, 0x23, 0, 0x03, 0x2b, 0xaf }; /* op(reg,mem); */ | |
1013 | + jitCompPutByte1(w.dst, basic_op_table_rm[*src - 0x10]); | |
1014 | + jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
1015 | + } | |
1016 | + } | |
1017 | + else { | |
1018 | + if (reg1 >= 0) { | |
1019 | + jitCompPutByte3(w.dst, 0x0f, 0xaf, 0xc0 | reg0 << 3 | reg1); | |
1020 | + } | |
1021 | + else { | |
1022 | + jitCompPutByte2(w.dst, 0x0f, 0xaf); | |
1023 | + jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
1024 | + } | |
1025 | + } | |
1026 | + } | |
1027 | + if (reg0 == 0) | |
1028 | + jitCompA0001_movRxxEax(&w, src[1]); | |
1029 | + break; | |
1030 | + | |
1031 | + case 0x18: /* SHL */ | |
1032 | + case 0x19: /* SAR */ | |
1033 | + if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
1034 | + if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
1035 | 1035 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
1036 | - if (src[3] == 0x3f) { | |
1037 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
1038 | - reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); | |
1039 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
1040 | - if (reg1 == -1) | |
1041 | - jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg1, [EBP+?]); */ | |
1042 | - else { | |
1043 | - if (reg0 != reg1) { | |
1044 | - jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ | |
1045 | - } | |
1046 | - } | |
1047 | - if (*src == 0x18) { jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f); } /* SHL(reg0, im8); */ | |
1048 | - if (*src == 0x19) { jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f); } /* SAR(reg0, im8); */ | |
1049 | - if (reg0 == 0 /* EAX */) | |
1050 | - jitCompA0001_movRxxEax(&w, src[1]); | |
1051 | - cmp0reg = src[1]; | |
1052 | - cmp0lev = 1; | |
1053 | - break; | |
1054 | - } | |
1036 | + if (src[3] == 0x3f) { | |
1037 | + reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
1038 | + reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); | |
1039 | + if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
1040 | + if (reg1 == -1) | |
1041 | + jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg1, [EBP+?]); */ | |
1042 | + else { | |
1043 | + if (reg0 != reg1) { | |
1044 | + jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ | |
1045 | + } | |
1046 | + } | |
1047 | + if (*src == 0x18) { jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f); } /* SHL(reg0, im8); */ | |
1048 | + if (*src == 0x19) { jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f); } /* SAR(reg0, im8); */ | |
1049 | + if (reg0 == 0 /* EAX */) | |
1050 | + jitCompA0001_movRxxEax(&w, src[1]); | |
1051 | + cmp0reg = src[1]; | |
1052 | + cmp0lev = 1; | |
1053 | + break; | |
1054 | + } | |
1055 | 1055 | #endif |
1056 | - jitCompA000_storeRegCacheAll(&w); // 手抜き. | |
1057 | - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ | |
1056 | + jitCompA000_storeRegCacheAll(&w); // 手抜き. | |
1057 | + jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ | |
1058 | 1058 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
1059 | - if (src[2] == 0x3f) { | |
1060 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1061 | - jitCompPutImm32(&w, w.r3f); | |
1062 | - } | |
1063 | - else { | |
1064 | - jitCompA0001_movEaxRxx(&w, src[2]); | |
1065 | - } | |
1059 | + if (src[2] == 0x3f) { | |
1060 | + jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1061 | + jitCompPutImm32(&w, w.r3f); | |
1062 | + } | |
1063 | + else { | |
1064 | + jitCompA0001_movEaxRxx(&w, src[2]); | |
1065 | + } | |
1066 | 1066 | #else |
1067 | - jitCompA0001_movEaxRxx(&w, src[2]); | |
1067 | + jitCompA0001_movEaxRxx(&w, src[2]); | |
1068 | 1068 | #endif |
1069 | - if (*src == 0x18) { jitCompPutByte2(w.dst, 0xd3, 0xe0); } /* SHL(EAX, CL); */ | |
1070 | - if (*src == 0x19) { jitCompPutByte2(w.dst, 0xd3, 0xf8); } /* SAR(EAX, CL); */ | |
1071 | - jitCompA0001_movRxxEax(&w, src[1]); | |
1072 | - jitCompA000_loadRegCacheAll(&w); // 手抜き. | |
1073 | - cmp0reg = src[1]; | |
1074 | - cmp0lev = 1; | |
1075 | - break; | |
1076 | - | |
1077 | - case 0x1a: /* DIV */ | |
1078 | - case 0x1b: /* MOD */ | |
1079 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
1080 | - if (src[2] >= 0x40) w.err = JITC_ERR_REGNUM; | |
1081 | - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
1082 | - jitCompA000_storeRegCacheAll(&w); // 手抜き. | |
1069 | + if (*src == 0x18) { jitCompPutByte2(w.dst, 0xd3, 0xe0); } /* SHL(EAX, CL); */ | |
1070 | + if (*src == 0x19) { jitCompPutByte2(w.dst, 0xd3, 0xf8); } /* SAR(EAX, CL); */ | |
1071 | + jitCompA0001_movRxxEax(&w, src[1]); | |
1072 | + jitCompA000_loadRegCacheAll(&w); // 手抜き. | |
1073 | + cmp0reg = src[1]; | |
1074 | + cmp0lev = 1; | |
1075 | + break; | |
1076 | + | |
1077 | + case 0x1a: /* DIV */ | |
1078 | + case 0x1b: /* MOD */ | |
1079 | + if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
1080 | + if (src[2] >= 0x40) w.err = JITC_ERR_REGNUM; | |
1081 | + if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
1082 | + jitCompA000_storeRegCacheAll(&w); // 手抜き. | |
1083 | 1083 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
1084 | - if (src[3] == 0x3f) { | |
1085 | - jitCompPutByte1(w.dst, 0xb8 | 1); /* MOV(ECX, ?); */ | |
1086 | - jitCompPutImm32(&w, w.r3f); | |
1087 | - } | |
1088 | - else { | |
1089 | - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ | |
1090 | - } | |
1091 | - if (src[2] == 0x3f) { | |
1092 | - jitCompPutByte1(w.dst, 0xb8 | 0); /* MOV(EAX, ?); */ | |
1093 | - jitCompPutImm32(&w, w.r3f); | |
1094 | - } | |
1095 | - else { | |
1096 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */ | |
1097 | - } | |
1084 | + if (src[3] == 0x3f) { | |
1085 | + jitCompPutByte1(w.dst, 0xb8 | 1); /* MOV(ECX, ?); */ | |
1086 | + jitCompPutImm32(&w, w.r3f); | |
1087 | + } | |
1088 | + else { | |
1089 | + jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ | |
1090 | + } | |
1091 | + if (src[2] == 0x3f) { | |
1092 | + jitCompPutByte1(w.dst, 0xb8 | 0); /* MOV(EAX, ?); */ | |
1093 | + jitCompPutImm32(&w, w.r3f); | |
1094 | + } | |
1095 | + else { | |
1096 | + jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */ | |
1097 | + } | |
1098 | 1098 | #else |
1099 | - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ | |
1100 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */ | |
1099 | + jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ | |
1100 | + jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */ | |
1101 | 1101 | #endif |
1102 | - jitCompPutByte1(w.dst, 0x99); /* CDQ(); */ | |
1103 | - /* ECXがゼロではないことを確認すべき */ | |
1104 | - jitCompPutByte2(w.dst, 0xf7, 0xf9); /* IDIV(ECX); */ | |
1105 | - if (*src == 0x1a) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 0 /* EAX */); } | |
1106 | - if (*src == 0x1b) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 2 /* EDX */); } | |
1107 | - jitCompA000_loadRegCacheAll(&w); // 手抜き. | |
1108 | - cmp0reg = -1; | |
1109 | - break; | |
1110 | - | |
1111 | - case 0x1c: /* PLMT0 */ | |
1112 | - case 0x1d: /* PLMT1 */ | |
1113 | - if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1114 | - if (level < JITC_LV_FASTEST) { | |
1115 | - cmp0reg = -1; | |
1116 | - if (level < JITC_LV_FASTER) { | |
1117 | - // typ が一致していることを確認. | |
1118 | - // plsとliveSignが一致していることを確認. | |
1119 | - | |
1120 | - // preg1はp0 <= p <= p1 を満たしているか?. | |
1121 | - // 新しいp0/p1は古いp0〜p1に適合しているか?. | |
1122 | - | |
1123 | - } | |
1124 | - } | |
1125 | - | |
1126 | - case 0x1e: /* PCP */ /* 未完成(p1まで完成) */ | |
1127 | - if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1128 | - if (src[2] == 0x3f) w.err = JITC_ERR_PREGNUM; | |
1129 | - if (src[1] != 0x3f) { | |
1130 | - /* src[2] == 0xff の場合に対応できてない */ | |
1131 | - jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1132 | - for (i = 0; i < 32; i += 4) { | |
1133 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
1134 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
1135 | - } | |
1136 | - jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1137 | - } | |
1138 | - else { | |
1139 | - if (level < JITC_LV_FASTER) { | |
1140 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ | |
1141 | - jitCompPutByte3(w.dst, 0x83, 0xf8, 0); /* CMP(EAX, 0); */ | |
1142 | - jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ | |
1143 | - jitCompPutImm32(&w, errfnc - (w.dst + 4)); | |
1144 | - /* セキュリティチェックが足りてない!(aliveとか) */ | |
1145 | - } | |
1146 | - reg0 = 0; /* EAX */ | |
1147 | - jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1148 | - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ | |
1149 | - if (level < JITC_LV_FASTER) { | |
1150 | - jitCompPutByte1(w.dst, 0x3b); /* CMP(reg0, [EBP+?]); */ | |
1151 | - jitCompA0001_85DispN(&w, 256 + src[2] * 32 + 8, reg0); /* p0 */ | |
1152 | - jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ | |
1153 | - jitCompPutImm32(&w, errfnc - (w.dst + 4)); | |
1154 | - } | |
1155 | - jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */ | |
1156 | - } | |
1157 | - break; | |
1158 | - | |
1159 | - case 0x1f: /* PCST */ | |
1160 | - if (jitCompGetImm32(src + 2) == 0) { | |
1161 | - if (level < JITC_LV_FASTER) | |
1162 | - jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 7), 2); | |
1163 | - jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1164 | - for (i = 0; i < 32 - 4; i += 4) { | |
1165 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
1166 | - if (i == 4) { | |
1167 | - jitCompPutByte1(w.dst, 0x0d); /* OR(EAX, ?); */ | |
1168 | - jitCompPutImm32(&w, 0x80000000); | |
1169 | - } | |
1170 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
1171 | - } | |
1172 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1173 | - jitCompPutImm32(&w, debugInfo1); | |
1174 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 28, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
1175 | - jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1176 | - cmp0reg = -1; | |
1177 | - break; | |
1178 | - } | |
1179 | - if (jitCompGetImm32(src + 7) == 0) { | |
1180 | - jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1181 | - for (i = 0; i < 32 - 4; i += 4) { | |
1182 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
1183 | - if (i == 4) { | |
1184 | - jitCompPutByte1(w.dst, 0x25); /* AND(EAX, ?); */ | |
1185 | - jitCompPutImm32(&w, 0x7fffffff); | |
1186 | - } | |
1187 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
1188 | - } | |
1189 | - if (level < JITC_LV_FASTER) { | |
1190 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + 28); /* MOV(EAX, [EBP+?]); */ | |
1191 | - jitCompPutByte1(w.dst, 0x3d); /* CMP(EAX, ?); */ | |
1192 | - jitCompPutImm32(&w, debugInfo1); | |
1193 | - jitCompPutByte2(w.dst, 0x74, 8); /* JE */ | |
1194 | - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); (2) */ | |
1195 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0 /* EAX */); /* MOV([EBP+?], EAX); (1+1+4) */ | |
1196 | - } | |
1197 | - jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1198 | - cmp0reg = -1; | |
1199 | - break; | |
1200 | - } | |
1201 | - w.err = JITC_ERR_OPECODE; | |
1202 | - goto err_w; | |
1203 | - | |
1204 | - case 0x20: /* CMPE */ | |
1205 | - case 0x21: /* CMPNE */ | |
1206 | - case 0x22: /* CMPL */ | |
1207 | - case 0x23: /* CMPGE */ | |
1208 | - case 0x24: /* CMPLE */ | |
1209 | - case 0x25: /* CMPG */ | |
1210 | - case 0x26: /* TSTZ */ | |
1211 | - case 0x27: /* TSTNZ */ | |
1212 | - reg0 = jitCompA000_selectRegCache(src[2], 0 /* EAX */); | |
1213 | - reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); | |
1214 | - if (src[1] == 0x3f) { | |
1215 | - /* 特殊構文チェック */ | |
1216 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
1217 | - if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) { | |
1218 | - w.err = JITC_ERR_IDIOM; goto err_w; | |
1219 | - } | |
1220 | - } | |
1221 | - if (reg0 == 0) | |
1222 | - jitCompA0001_movEaxRxx(&w, src[2]); | |
1102 | + jitCompPutByte1(w.dst, 0x99); /* CDQ(); */ | |
1103 | + /* ECXがゼロではないことを確認すべき */ | |
1104 | + jitCompPutByte2(w.dst, 0xf7, 0xf9); /* IDIV(ECX); */ | |
1105 | + if (*src == 0x1a) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 0 /* EAX */); } | |
1106 | + if (*src == 0x1b) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 2 /* EDX */); } | |
1107 | + jitCompA000_loadRegCacheAll(&w); // 手抜き. | |
1108 | + cmp0reg = -1; | |
1109 | + break; | |
1110 | + | |
1111 | + case 0x1c: /* PLMT0 */ | |
1112 | + case 0x1d: /* PLMT1 */ | |
1113 | + if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1114 | + if (level < JITC_LV_FASTEST) { | |
1115 | + cmp0reg = -1; | |
1116 | + if (level < JITC_LV_FASTER) { | |
1117 | + // typ が一致していることを確認. | |
1118 | + // plsとliveSignが一致していることを確認. | |
1119 | + | |
1120 | + // preg1はp0 <= p <= p1 を満たしているか?. | |
1121 | + // 新しいp0/p1は古いp0〜p1に適合しているか?. | |
1122 | + | |
1123 | + } | |
1124 | + } | |
1125 | + | |
1126 | + case 0x1e: /* PCP */ /* 未完成(p1まで完成) */ | |
1127 | + if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1128 | + if (src[2] == 0x3f) w.err = JITC_ERR_PREGNUM; | |
1129 | + if (src[1] != 0x3f) { | |
1130 | + /* src[2] == 0xff の場合に対応できてない */ | |
1131 | + jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1132 | + for (i = 0; i < 32; i += 4) { | |
1133 | + jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
1134 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
1135 | + } | |
1136 | + jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1137 | + } | |
1138 | + else { | |
1139 | + if (level < JITC_LV_FASTER) { | |
1140 | + jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ | |
1141 | + jitCompPutByte3(w.dst, 0x83, 0xf8, 0); /* CMP(EAX, 0); */ | |
1142 | + jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ | |
1143 | + jitCompPutImm32(&w, errfnc - (w.dst + 4)); | |
1144 | + /* セキュリティチェックが足りてない!(aliveとか) */ | |
1145 | + } | |
1146 | + reg0 = 0; /* EAX */ | |
1147 | + jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1148 | + jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ | |
1149 | + if (level < JITC_LV_FASTER) { | |
1150 | + jitCompPutByte1(w.dst, 0x3b); /* CMP(reg0, [EBP+?]); */ | |
1151 | + jitCompA0001_85DispN(&w, 256 + src[2] * 32 + 8, reg0); /* p0 */ | |
1152 | + jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ | |
1153 | + jitCompPutImm32(&w, errfnc - (w.dst + 4)); | |
1154 | + } | |
1155 | + jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */ | |
1156 | + } | |
1157 | + break; | |
1158 | + | |
1159 | + case 0x1f: /* PCST */ | |
1160 | + if (jitCompGetImm32(src + 2) == 0) { | |
1161 | + if (level < JITC_LV_FASTER) | |
1162 | + jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 7), 2); | |
1163 | + jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1164 | + for (i = 0; i < 32 - 4; i += 4) { | |
1165 | + jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
1166 | + if (i == 4) { | |
1167 | + jitCompPutByte1(w.dst, 0x0d); /* OR(EAX, ?); */ | |
1168 | + jitCompPutImm32(&w, 0x80000000); | |
1169 | + } | |
1170 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
1171 | + } | |
1172 | + jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1173 | + jitCompPutImm32(&w, debugInfo1); | |
1174 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 28, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
1175 | + jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1176 | + cmp0reg = -1; | |
1177 | + break; | |
1178 | + } | |
1179 | + if (jitCompGetImm32(src + 7) == 0) { | |
1180 | + jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1181 | + for (i = 0; i < 32 - 4; i += 4) { | |
1182 | + jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
1183 | + if (i == 4) { | |
1184 | + jitCompPutByte1(w.dst, 0x25); /* AND(EAX, ?); */ | |
1185 | + jitCompPutImm32(&w, 0x7fffffff); | |
1186 | + } | |
1187 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
1188 | + } | |
1189 | + if (level < JITC_LV_FASTER) { | |
1190 | + jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + 28); /* MOV(EAX, [EBP+?]); */ | |
1191 | + jitCompPutByte1(w.dst, 0x3d); /* CMP(EAX, ?); */ | |
1192 | + jitCompPutImm32(&w, debugInfo1); | |
1193 | + jitCompPutByte2(w.dst, 0x74, 8); /* JE */ | |
1194 | + jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); (2) */ | |
1195 | + jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0 /* EAX */); /* MOV([EBP+?], EAX); (1+1+4) */ | |
1196 | + } | |
1197 | + jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1198 | + cmp0reg = -1; | |
1199 | + break; | |
1200 | + } | |
1201 | + w.err = JITC_ERR_OPECODE; | |
1202 | + goto err_w; | |
1203 | + | |
1204 | + case 0x20: /* CMPE */ | |
1205 | + case 0x21: /* CMPNE */ | |
1206 | + case 0x22: /* CMPL */ | |
1207 | + case 0x23: /* CMPGE */ | |
1208 | + case 0x24: /* CMPLE */ | |
1209 | + case 0x25: /* CMPG */ | |
1210 | + case 0x26: /* TSTZ */ | |
1211 | + case 0x27: /* TSTNZ */ | |
1212 | + reg0 = jitCompA000_selectRegCache(src[2], 0 /* EAX */); | |
1213 | + reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); | |
1214 | + if (src[1] == 0x3f) { | |
1215 | + /* 特殊構文チェック */ | |
1216 | + if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
1217 | + if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) { | |
1218 | + w.err = JITC_ERR_IDIOM; goto err_w; | |
1219 | + } | |
1220 | + } | |
1221 | + if (reg0 == 0) | |
1222 | + jitCompA0001_movEaxRxx(&w, src[2]); | |
1223 | 1223 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
1224 | - if (src[3] == 0x3f) { | |
1224 | + if (src[3] == 0x3f) { | |
1225 | 1225 | #if (jitCompA0001_OPTIMIZE_CMP != 0) |
1226 | - if ((*src <= 0x25 && w.r3f == 0) || (*src >= 0x26 && w.r3f == -1)) { | |
1227 | - i = 0; | |
1228 | - if (cmp0reg == src[2]) { | |
1229 | - if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27)) | |
1230 | - i = 1; | |
1231 | - if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25)) | |
1232 | - i = 1; | |
1233 | - } | |
1234 | - if (i == 0) { | |
1235 | - jitCompPutByte2(w.dst, 0x85, 0xc0 | reg0 << 3 | reg0); /* TEST(reg0, reg0); */ | |
1236 | - } | |
1237 | - cmp0reg = src[2]; | |
1238 | - cmp0lev = 2; | |
1239 | - goto cmpcc1; | |
1240 | - } | |
1226 | + if ((*src <= 0x25 && w.r3f == 0) || (*src >= 0x26 && w.r3f == -1)) { | |
1227 | + i = 0; | |
1228 | + if (cmp0reg == src[2]) { | |
1229 | + if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27)) | |
1230 | + i = 1; | |
1231 | + if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25)) | |
1232 | + i = 1; | |
1233 | + } | |
1234 | + if (i == 0) { | |
1235 | + jitCompPutByte2(w.dst, 0x85, 0xc0 | reg0 << 3 | reg0); /* TEST(reg0, reg0); */ | |
1236 | + } | |
1237 | + cmp0reg = src[2]; | |
1238 | + cmp0lev = 2; | |
1239 | + goto cmpcc1; | |
1240 | + } | |
1241 | 1241 | #endif |
1242 | 1242 | #if (jitCompA0001_USE_R3F_IMM8 != 0) |
1243 | - if (-0x80 <= w.r3f && w.r3f <= 0x7f && *src <= 0x25) { | |
1244 | - jitCompPutByte3(w.dst, 0x83, 0xf8 | reg0, w.r3f); | |
1245 | - goto cmpcc1; | |
1246 | - } | |
1243 | + if (-0x80 <= w.r3f && w.r3f <= 0x7f && *src <= 0x25) { | |
1244 | + jitCompPutByte3(w.dst, 0x83, 0xf8 | reg0, w.r3f); | |
1245 | + goto cmpcc1; | |
1246 | + } | |
1247 | 1247 | #endif |
1248 | - if (reg0 == 0) { | |
1249 | - if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3d); } | |
1250 | - if (*src >= 0x26) { jitCompPutByte1(w.dst, 0xa9); } | |
1251 | - } | |
1252 | - else { | |
1253 | - if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0); } | |
1254 | - if (*src >= 0x26) { jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); } | |
1255 | - } | |
1256 | - jitCompPutImm32(&w, w.r3f); | |
1257 | - goto cmpcc1; | |
1258 | - } | |
1248 | + if (reg0 == 0) { | |
1249 | + if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3d); } | |
1250 | + if (*src >= 0x26) { jitCompPutByte1(w.dst, 0xa9); } | |
1251 | + } | |
1252 | + else { | |
1253 | + if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0); } | |
1254 | + if (*src >= 0x26) { jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); } | |
1255 | + } | |
1256 | + jitCompPutImm32(&w, w.r3f); | |
1257 | + goto cmpcc1; | |
1258 | + } | |
1259 | 1259 | #endif |
1260 | - if (src[3] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1261 | - if (reg1 >= 0) { | |
1262 | - if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x39, 0xc0 | reg1 << 3 | reg0); } | |
1263 | - if (*src >= 0x26) { jitCompPutByte2(w.dst, 0x85, 0xc0 | reg1 << 3 | reg0); } | |
1264 | - } | |
1265 | - else { | |
1266 | - if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3b); } | |
1267 | - if (*src >= 0x26) { jitCompPutByte1(w.dst, 0x85); } | |
1268 | - jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
1269 | - } | |
1270 | - cmpcc1: | |
1271 | - if (w.err != 0) goto err_w; | |
1272 | - static unsigned char cmpcc_table0[] = { | |
1273 | - 0x04, 0x05, 0x0c, 0x0d, 0x0e, 0x0f, 0x04, 0x05, /* CMPcc, TSTcc */ | |
1274 | - 0x04, 0x05, 0x02, 0x03, 0x06, 0x07 /* PCMPcc */ | |
1275 | - }; | |
1260 | + if (src[3] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1261 | + if (reg1 >= 0) { | |
1262 | + if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x39, 0xc0 | reg1 << 3 | reg0); } | |
1263 | + if (*src >= 0x26) { jitCompPutByte2(w.dst, 0x85, 0xc0 | reg1 << 3 | reg0); } | |
1264 | + } | |
1265 | + else { | |
1266 | + if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3b); } | |
1267 | + if (*src >= 0x26) { jitCompPutByte1(w.dst, 0x85); } | |
1268 | + jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
1269 | + } | |
1270 | + cmpcc1: | |
1271 | + if (w.err != 0) goto err_w; | |
1272 | + static unsigned char cmpcc_table0[] = { | |
1273 | + 0x04, 0x05, 0x0c, 0x0d, 0x0e, 0x0f, 0x04, 0x05, /* CMPcc, TSTcc */ | |
1274 | + 0x04, 0x05, 0x02, 0x03, 0x06, 0x07 /* PCMPcc */ | |
1275 | + }; | |
1276 | 1276 | #if (jitCompA0001_USE_R3F_CMPJMP != 0) |
1277 | - if (src[1] == 0x3f) { | |
1278 | - /* 特殊構文を利用した最適化 */ | |
1279 | - jitCompPutByte2(w.dst, 0x0f, 0x80 | cmpcc_table0[*src - 0x20]); | |
1280 | - src += 6; | |
1281 | - i = jitCompGetLabelNum(&w, src + 2); | |
1282 | - if ((flags & JITC_PHASE1) != 0 && w.err != 0) { | |
1283 | - if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } | |
1284 | - // if (label[i].typ != 1) { w.err = JITC_ERR_LABELTYP; goto err_w; } | |
1285 | - } | |
1286 | - j = 0; | |
1287 | - if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) | |
1288 | - j = label[i].p - (w.dst + 4); | |
1289 | - jitCompPutImm32(&w, j); | |
1277 | + if (src[1] == 0x3f) { | |
1278 | + /* 特殊構文を利用した最適化 */ | |
1279 | + jitCompPutByte2(w.dst, 0x0f, 0x80 | cmpcc_table0[*src - 0x20]); | |
1280 | + src += 6; | |
1281 | + i = jitCompGetLabelNum(&w, src + 2); | |
1282 | + if ((flags & JITC_PHASE1) != 0 && w.err != 0) { | |
1283 | + if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } | |
1284 | + // if (label[i].typ != 1) { w.err = JITC_ERR_LABELTYP; goto err_w; } | |
1285 | + } | |
1286 | + j = 0; | |
1287 | + if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) | |
1288 | + j = label[i].p - (w.dst + 4); | |
1289 | + jitCompPutImm32(&w, j); | |
1290 | 1290 | #if (jitCompA0001_OPTIMIZE_JMP != 0) |
1291 | - if (-128 - 4 <= j && j < 0) { | |
1292 | - j += 4; | |
1293 | - w.dst -= 6; | |
1294 | - jitCompPutByte2(w.dst, w.dst[1] ^ 0xf0, j & 0xff); | |
1295 | - } | |
1291 | + if (-128 - 4 <= j && j < 0) { | |
1292 | + j += 4; | |
1293 | + w.dst -= 6; | |
1294 | + jitCompPutByte2(w.dst, w.dst[1] ^ 0xf0, j & 0xff); | |
1295 | + } | |
1296 | 1296 | #endif |
1297 | - src += 6; | |
1298 | - if (w.err != 0) goto err_w; | |
1299 | - continue; | |
1300 | - } | |
1297 | + src += 6; | |
1298 | + if (w.err != 0) goto err_w; | |
1299 | + continue; | |
1300 | + } | |
1301 | 1301 | #endif |
1302 | - /* 一般的なJITC */ | |
1303 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
1304 | - jitCompPutByte3(w.dst, 0x0f, 0x90 | cmpcc_table0[*src - 0x20], 0xc0 | reg0); /* SETcc(BYTE(reg0)); */ | |
1305 | - jitCompPutByte3(w.dst, 0x0f, 0xb6, 0xc0 | reg0 << 3 | reg0); /* MOVZX(reg0, BYTE(reg0)); */ | |
1306 | - jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */ | |
1307 | - if (reg0 == 0) | |
1308 | - jitCompA0001_movRxxEax(&w, src[1]); | |
1309 | - cmp0reg = src[2]; | |
1310 | - cmp0lev = 1; | |
1311 | - break; | |
1312 | - | |
1313 | - case 0x28: /* PCMPE */ | |
1314 | - case 0x29: /* PCMPNE */ | |
1315 | - case 0x2a: /* PCMPL */ | |
1316 | - case 0x2b: /* PCMPGE */ | |
1317 | - case 0x2c: /* PCMPLE */ | |
1318 | - case 0x2d: /* PCMPG */ | |
1319 | - if (src[1] == 0x3f) { | |
1320 | - /* 特殊構文チェック */ | |
1321 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
1322 | - if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) { | |
1323 | - w.err = JITC_ERR_IDIOM; goto err_w; | |
1324 | - } | |
1325 | - } | |
1326 | - if (src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1327 | - jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1328 | - if (src[3] != 0xff) | |
1329 | - jitCompA0001_checkCompPtr(&w, src[2], src[3]); | |
1330 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ | |
1331 | - if (src[3] != 0xff) { | |
1332 | - jitCompPutByte1(w.dst, 0x3b); /* CMP(EAX, [EBP+?]); */ | |
1333 | - jitCompA0001_85DispN(&w, 256 + src[3] * 32 + 0, 0); | |
1334 | - } | |
1335 | - else { | |
1336 | - /* ヌルポインタとの比較はこれでいいのか?たぶんよくない */ | |
1337 | - jitCompPutByte3(w.dst, 0x83, 0xf8, 0x00); /* CMP(EAX, 0); */ | |
1338 | - } | |
1339 | - cmp0reg = -1; | |
1340 | - goto cmpcc1; | |
1341 | - | |
1342 | - case 0x30: /* talloc(old:F4) */ | |
1343 | - case 0x31: /* tfree(old:F5) */ | |
1344 | - case 0x32: /* malloc(old:F6) */ | |
1345 | - case 0x33: /* mfree(old:F7) */ | |
1346 | - jitCompA000_storeRegCacheAll(&w); // 手抜き. | |
1347 | - jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1348 | - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ | |
1349 | - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ | |
1350 | - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ | |
1351 | - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ | |
1352 | - jitCompPutByte1(w.dst, 0xe8); | |
1353 | - if (*src == 0x30) j = ((unsigned char *)&funcf4) - (w.dst + 4); | |
1354 | - if (*src == 0x31) j = ((unsigned char *)&funcf5) - (w.dst + 4); | |
1355 | - if (*src == 0x32) j = ((unsigned char *)&funcf6) - (w.dst + 4); | |
1356 | - if (*src == 0x33) j = ((unsigned char *)&funcf7) - (w.dst + 4); | |
1357 | - jitCompPutImm32(&w, j); | |
1358 | - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x10); /* ADD(ESP,16); */ | |
1359 | - jitCompA000_loadRegCacheAll(&w); // 手抜き. | |
1360 | - jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1361 | - cmp0reg = -1; | |
1362 | - break; | |
1363 | - | |
1364 | - case 0x34: /* data (暫定) */ | |
1365 | - cmp0reg = -1; | |
1366 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
1367 | - int k = jitCompGetImm32(&src[1]), tmpData, bitCount, dataWidth = jitCompA000_dataWidth(k); | |
1368 | - if (lastlabel >= 0 && label[lastlabel].typ == 0) | |
1369 | - label[lastlabel].typ = k; | |
1370 | - if (k != 1) { | |
1371 | - i = jitCompA000_convTyp(k); | |
1372 | - if (i < 2 || i > 7) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
1373 | - } | |
1374 | - j = jitCompGetImm32(&src[5]); | |
1375 | - oldsrc = src; | |
1376 | - src += 9; | |
1377 | - if (k != 1) { | |
1378 | - bitCount = 7; | |
1379 | - while (j > 0) { | |
1380 | - if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; } | |
1381 | - if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; } | |
1382 | - tmpData = 0; | |
1383 | - for (k = 0; k < dataWidth; k++) { | |
1384 | - tmpData = tmpData << 1 | ((*src >> bitCount) & 1); | |
1385 | - bitCount--; | |
1386 | - if (bitCount < 0) { | |
1387 | - bitCount = 7; | |
1388 | - src++; | |
1389 | - } | |
1390 | - } | |
1391 | - if ((i & 1) == 0 && dataWidth <= 31 && (tmpData >> (dataWidth - 1)) != 0) { | |
1392 | - tmpData -= 1 << dataWidth; | |
1393 | - } | |
1394 | - if (i == 2 || i == 3) { jitCompPutByte1(w.dst, tmpData & 0xff); } | |
1395 | - if (i == 4 || i == 5) { jitCompPutByte2(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff); } | |
1396 | - if (i == 6 || i == 7) { jitCompPutByte4(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff, (tmpData >> 16) & 0xff, (tmpData >> 24) & 0xff); } | |
1397 | - j--; | |
1398 | - } | |
1399 | - } | |
1400 | - else { | |
1401 | - while (j > 0) { | |
1402 | - if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; } | |
1403 | - if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; } | |
1404 | - i = jitCompGetImm32(src); | |
1405 | - src += 4; | |
1406 | - if ((flags & JITC_PHASE1) != 0 && w.err == 0) { | |
1407 | - if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } | |
1408 | - } | |
1409 | - jitCompPutImm32(&w, (int)label[i].p); | |
1410 | - jitCompPutImm32(&w, label[i].typ); | |
1411 | - jitCompPutImm32(&w, (int)label[i].p); | |
1412 | - jitCompPutImm32(&w, (int)label[i].p1); | |
1413 | - jitCompPutImm32(&w, 0); /* liveSign */ | |
1414 | - jitCompPutImm32(&w, 2320); /* pls */ | |
1415 | - jitCompPutImm32(&w, 0); | |
1416 | - jitCompPutImm32(&w, 0); | |
1417 | - j--; | |
1418 | - } | |
1419 | - } | |
1420 | - if (lastlabel >= 0 && label[lastlabel].p1 < w.dst) | |
1421 | - label[lastlabel].p1 = w.dst; | |
1422 | - continue; | |
1423 | - | |
1424 | - case 0x3c: /* ENTER */ | |
1425 | - jitCompA000_storeRegCacheAll(&w); // 手抜き. | |
1426 | - jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1427 | - jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */ | |
1428 | - jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */ | |
1429 | - jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */ | |
1430 | - jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */ | |
1431 | - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ | |
1432 | - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ | |
1433 | - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ | |
1434 | - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ | |
1435 | - jitCompPutByte1(w.dst, 0xe8); | |
1436 | - j = ((unsigned char *)&func3c) - (w.dst + 4); | |
1437 | - jitCompPutImm32(&w, j); | |
1438 | - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */ | |
1439 | - jitCompA000_loadRegCacheAll(&w); // 手抜き. | |
1440 | - jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1441 | - cmp0reg = -1; | |
1442 | - break; | |
1443 | - | |
1444 | - case 0x3d: /* LEAVE */ | |
1445 | - jitCompA000_storeRegCacheAll(&w); // 手抜き. | |
1446 | - jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1447 | - jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */ | |
1448 | - jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */ | |
1449 | - jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */ | |
1450 | - jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */ | |
1451 | - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ | |
1452 | - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ | |
1453 | - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ | |
1454 | - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ | |
1455 | - jitCompPutByte1(w.dst, 0xe8); | |
1456 | - j = ((unsigned char *)&func3d) - (w.dst + 4); | |
1457 | - jitCompPutImm32(&w, j); | |
1458 | - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */ | |
1459 | - jitCompA000_loadRegCacheAll(&w); // 手抜き. | |
1460 | - jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1461 | - cmp0reg = -1; | |
1462 | - break; | |
1463 | - | |
1464 | - case 0xfe: /* remark */ | |
1465 | - if (src[1] == 0x01 && src[2] == 0x00) { // DBGINFO1 | |
1466 | - if (level <= JITC_LV_SLOWER) { | |
1467 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1468 | - jitCompPutImm32(&w, debugInfo1); | |
1469 | - jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ | |
1470 | - } | |
1471 | - } | |
1472 | - if (src[1] == 0x01 && src[2] == 0x03) { // DBGINFO1CLR | |
1473 | - if (level <= JITC_LV_SLOWER) { | |
1474 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1475 | - jitCompPutImm32(&w, -1); | |
1476 | - jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ | |
1477 | - } | |
1478 | - } | |
1479 | - if (src[1] == 0x05 && src[2] == 0x00) { // DBGINFO0 | |
1480 | - if (level <= JITC_LV_SLOWEST) { | |
1481 | - debugInfo0 = jitCompGetImm32(src + 3); | |
1482 | - // jitCompPutByte1(w.dst, 0xbf); /* MOV(EDI, ?); */ | |
1483 | - // jitCompPutImm32(&w, debugInfo0); | |
1484 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1485 | - jitCompPutImm32(&w, debugInfo0); | |
1486 | - jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */ | |
1487 | - } | |
1488 | - } | |
1489 | - break; | |
1490 | - | |
1491 | - default: | |
1492 | - w.err = JITC_ERR_OPECODE; | |
1493 | - goto err_w; | |
1302 | + /* 一般的なJITC */ | |
1303 | + reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
1304 | + jitCompPutByte3(w.dst, 0x0f, 0x90 | cmpcc_table0[*src - 0x20], 0xc0 | reg0); /* SETcc(BYTE(reg0)); */ | |
1305 | + jitCompPutByte3(w.dst, 0x0f, 0xb6, 0xc0 | reg0 << 3 | reg0); /* MOVZX(reg0, BYTE(reg0)); */ | |
1306 | + jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */ | |
1307 | + if (reg0 == 0) | |
1308 | + jitCompA0001_movRxxEax(&w, src[1]); | |
1309 | + cmp0reg = src[2]; | |
1310 | + cmp0lev = 1; | |
1311 | + break; | |
1312 | + | |
1313 | + case 0x28: /* PCMPE */ | |
1314 | + case 0x29: /* PCMPNE */ | |
1315 | + case 0x2a: /* PCMPL */ | |
1316 | + case 0x2b: /* PCMPGE */ | |
1317 | + case 0x2c: /* PCMPLE */ | |
1318 | + case 0x2d: /* PCMPG */ | |
1319 | + if (src[1] == 0x3f) { | |
1320 | + /* 特殊構文チェック */ | |
1321 | + if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
1322 | + if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) { | |
1323 | + w.err = JITC_ERR_IDIOM; goto err_w; | |
1324 | + } | |
1325 | + } | |
1326 | + if (src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1327 | + jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1328 | + if (src[3] != 0xff) | |
1329 | + jitCompA0001_checkCompPtr(&w, src[2], src[3]); | |
1330 | + jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ | |
1331 | + if (src[3] != 0xff) { | |
1332 | + jitCompPutByte1(w.dst, 0x3b); /* CMP(EAX, [EBP+?]); */ | |
1333 | + jitCompA0001_85DispN(&w, 256 + src[3] * 32 + 0, 0); | |
1334 | + } | |
1335 | + else { | |
1336 | + /* ヌルポインタとの比較はこれでいいのか?たぶんよくない */ | |
1337 | + jitCompPutByte3(w.dst, 0x83, 0xf8, 0x00); /* CMP(EAX, 0); */ | |
1338 | + } | |
1339 | + cmp0reg = -1; | |
1340 | + goto cmpcc1; | |
1341 | + | |
1342 | + case 0x30: /* talloc(old:F4) */ | |
1343 | + case 0x31: /* tfree(old:F5) */ | |
1344 | + case 0x32: /* malloc(old:F6) */ | |
1345 | + case 0x33: /* mfree(old:F7) */ | |
1346 | + jitCompA000_storeRegCacheAll(&w); // 手抜き. | |
1347 | + jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1348 | + jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ | |
1349 | + jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ | |
1350 | + jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ | |
1351 | + jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ | |
1352 | + jitCompPutByte1(w.dst, 0xe8); | |
1353 | + if (*src == 0x30) j = ((unsigned char *)&funcf4) - (w.dst + 4); | |
1354 | + if (*src == 0x31) j = ((unsigned char *)&funcf5) - (w.dst + 4); | |
1355 | + if (*src == 0x32) j = ((unsigned char *)&funcf6) - (w.dst + 4); | |
1356 | + if (*src == 0x33) j = ((unsigned char *)&funcf7) - (w.dst + 4); | |
1357 | + jitCompPutImm32(&w, j); | |
1358 | + jitCompPutByte3(w.dst, 0x83, 0xc4, 0x10); /* ADD(ESP,16); */ | |
1359 | + jitCompA000_loadRegCacheAll(&w); // 手抜き. | |
1360 | + jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1361 | + cmp0reg = -1; | |
1362 | + break; | |
1363 | + | |
1364 | + case 0x34: /* data (暫定) */ | |
1365 | + cmp0reg = -1; | |
1366 | + if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
1367 | + int k = jitCompGetImm32(&src[1]), tmpData, bitCount, dataWidth = jitCompA000_dataWidth(k); | |
1368 | + if (lastlabel >= 0 && label[lastlabel].typ == 0) | |
1369 | + label[lastlabel].typ = k; | |
1370 | + if (k != 1) { | |
1371 | + i = jitCompA000_convTyp(k); | |
1372 | + if (i < 2 || i > 7) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
1373 | + } | |
1374 | + j = jitCompGetImm32(&src[5]); | |
1375 | + oldsrc = src; | |
1376 | + src += 9; | |
1377 | + if (k != 1) { | |
1378 | + bitCount = 7; | |
1379 | + while (j > 0) { | |
1380 | + if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; } | |
1381 | + if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; } | |
1382 | + tmpData = 0; | |
1383 | + for (k = 0; k < dataWidth; k++) { | |
1384 | + tmpData = tmpData << 1 | ((*src >> bitCount) & 1); | |
1385 | + bitCount--; | |
1386 | + if (bitCount < 0) { | |
1387 | + bitCount = 7; | |
1388 | + src++; | |
1389 | + } | |
1390 | + } | |
1391 | + if ((i & 1) == 0 && dataWidth <= 31 && (tmpData >> (dataWidth - 1)) != 0) { | |
1392 | + tmpData -= 1 << dataWidth; | |
1393 | + } | |
1394 | + if (i == 2 || i == 3) { jitCompPutByte1(w.dst, tmpData & 0xff); } | |
1395 | + if (i == 4 || i == 5) { jitCompPutByte2(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff); } | |
1396 | + if (i == 6 || i == 7) { jitCompPutByte4(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff, (tmpData >> 16) & 0xff, (tmpData >> 24) & 0xff); } | |
1397 | + j--; | |
1398 | + } | |
1399 | + } | |
1400 | + else { | |
1401 | + while (j > 0) { | |
1402 | + if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; } | |
1403 | + if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; } | |
1404 | + i = jitCompGetImm32(src); | |
1405 | + src += 4; | |
1406 | + if ((flags & JITC_PHASE1) != 0 && w.err == 0) { | |
1407 | + if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } | |
1408 | + } | |
1409 | + jitCompPutImm32(&w, (int)label[i].p); | |
1410 | + jitCompPutImm32(&w, label[i].typ); | |
1411 | + jitCompPutImm32(&w, (int)label[i].p); | |
1412 | + jitCompPutImm32(&w, (int)label[i].p1); | |
1413 | + jitCompPutImm32(&w, 0); /* liveSign */ | |
1414 | + jitCompPutImm32(&w, 2320); /* pls */ | |
1415 | + jitCompPutImm32(&w, 0); | |
1416 | + jitCompPutImm32(&w, 0); | |
1417 | + j--; | |
1418 | + } | |
1419 | + } | |
1420 | + if (lastlabel >= 0 && label[lastlabel].p1 < w.dst) | |
1421 | + label[lastlabel].p1 = w.dst; | |
1422 | + continue; | |
1423 | + | |
1424 | + case 0x3c: /* ENTER */ | |
1425 | + jitCompA000_storeRegCacheAll(&w); // 手抜き. | |
1426 | + jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1427 | + jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */ | |
1428 | + jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */ | |
1429 | + jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */ | |
1430 | + jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */ | |
1431 | + jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ | |
1432 | + jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ | |
1433 | + jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ | |
1434 | + jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ | |
1435 | + jitCompPutByte1(w.dst, 0xe8); | |
1436 | + j = ((unsigned char *)&func3c) - (w.dst + 4); | |
1437 | + jitCompPutImm32(&w, j); | |
1438 | + jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */ | |
1439 | + jitCompA000_loadRegCacheAll(&w); // 手抜き. | |
1440 | + jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1441 | + cmp0reg = -1; | |
1442 | + break; | |
1443 | + | |
1444 | + case 0x3d: /* LEAVE */ | |
1445 | + jitCompA000_storeRegCacheAll(&w); // 手抜き. | |
1446 | + jitCompA000_storePRegCacheAll(&w); // 手抜き. | |
1447 | + jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */ | |
1448 | + jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */ | |
1449 | + jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */ | |
1450 | + jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */ | |
1451 | + jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ | |
1452 | + jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ | |
1453 | + jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ | |
1454 | + jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ | |
1455 | + jitCompPutByte1(w.dst, 0xe8); | |
1456 | + j = ((unsigned char *)&func3d) - (w.dst + 4); | |
1457 | + jitCompPutImm32(&w, j); | |
1458 | + jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */ | |
1459 | + jitCompA000_loadRegCacheAll(&w); // 手抜き. | |
1460 | + jitCompA000_loadPRegCacheAll(&w); // 手抜き. | |
1461 | + cmp0reg = -1; | |
1462 | + break; | |
1463 | + | |
1464 | + case 0xfe: /* remark */ | |
1465 | + if (src[1] == 0x01 && src[2] == 0x00) { // DBGINFO1 | |
1466 | + if (level <= JITC_LV_SLOWER) { | |
1467 | + jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1468 | + jitCompPutImm32(&w, debugInfo1); | |
1469 | + jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ | |
1470 | + } | |
1471 | + } | |
1472 | + if (src[1] == 0x01 && src[2] == 0x03) { // DBGINFO1CLR | |
1473 | + if (level <= JITC_LV_SLOWER) { | |
1474 | + jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1475 | + jitCompPutImm32(&w, -1); | |
1476 | + jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ | |
1477 | + } | |
1478 | + } | |
1479 | + if (src[1] == 0x05 && src[2] == 0x00) { // DBGINFO0 | |
1480 | + if (level <= JITC_LV_SLOWEST) { | |
1481 | + debugInfo0 = jitCompGetImm32(src + 3); | |
1482 | + // jitCompPutByte1(w.dst, 0xbf); /* MOV(EDI, ?); */ | |
1483 | + // jitCompPutImm32(&w, debugInfo0); | |
1484 | + jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1485 | + jitCompPutImm32(&w, debugInfo0); | |
1486 | + jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */ | |
1487 | + } | |
1488 | + } | |
1489 | + break; | |
1490 | + | |
1491 | + default: | |
1492 | + w.err = JITC_ERR_OPECODE; | |
1493 | + goto err_w; | |
1494 | 1494 | } |
1495 | 1495 | if (w.err != 0) goto err_w; |
1496 | 1496 | jitCompA0001_fixPrefix(&w); |
@@ -1512,7 +1512,7 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1512 | 1512 | if ((flags & JITC_PHASE1) != 0) |
1513 | 1513 | return w.dst - dst00; |
1514 | 1514 | return 0; |
1515 | - | |
1515 | + | |
1516 | 1516 | err_w: |
1517 | 1517 | if ((w.err & JITC_ERR_PHASE0ONLY) != 0) { |
1518 | 1518 | if ((flags & JITC_PHASE1) == 0) |
@@ -1561,10 +1561,10 @@ unsigned char *jitCompCallFunc(unsigned char *dst, void *func) | ||
1561 | 1561 | jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ |
1562 | 1562 | jitCompPutByte1(w.dst, 0xe8); /* CALL(func); */ |
1563 | 1563 | int j = ((unsigned char *)func) - (w.dst + 4); |
1564 | - | |
1564 | + | |
1565 | 1565 | //この関数の中では結局w->dstしか参照していない |
1566 | 1566 | jitCompPutImm32(&w, j); |
1567 | - | |
1567 | + | |
1568 | 1568 | jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */ /* (win32では不要なのだけど、MacOSには必要らしい) */ |
1569 | 1569 | jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */ |
1570 | 1570 | jitCompPutByte1(w.dst, 0x61); /* POPAD(); */ |
@@ -1610,7 +1610,7 @@ void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int | ||
1610 | 1610 | int i; |
1611 | 1611 | r->junkStack -= 4; |
1612 | 1612 | r->junkStack -= 32; |
1613 | - HOSECPU_PointerRegisterEntry *pp = (void *)r->junkStack; | |
1613 | + HOSECPU_PointerRegisterEntry *pp = (void *)r->junkStack; | |
1614 | 1614 | r->preg[0x30] = *pp; |
1615 | 1615 | r->junkStack -= p1 * 32; pp = (void *)r->junkStack; |
1616 | 1616 | for (i = 0; i < p1; i++) |
@@ -1712,24 +1712,24 @@ int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const | ||
1712 | 1712 | unsigned char *q = *qq; |
1713 | 1713 | if (p0[0] != 0x05 || p0[1] != SIGN1) // OSECPUのヘッダ (05E1) を確認 |
1714 | 1714 | return 1; |
1715 | - | |
1715 | + | |
1716 | 1716 | *q++ = 0x55; /* PUSH(EBP); */ |
1717 | 1717 | *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */ |
1718 | - | |
1718 | + | |
1719 | 1719 | int i; |
1720 | 1720 | for (i = 0; i < JITC_MAXLABELS; i++) |
1721 | 1721 | label[i].opt = 0; |
1722 | - | |
1722 | + | |
1723 | 1723 | // 以下のjitCompile()呼び出しでは第二引数をq1-2にした方がよいのではないか? |
1724 | 1724 | i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, 0); |
1725 | 1725 | if (i != 0) return 2; |
1726 | 1726 | i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, JITC_PHASE1 + 0); |
1727 | 1727 | if (i < 0) return 2; |
1728 | 1728 | q += i; |
1729 | - | |
1729 | + | |
1730 | 1730 | *q++ = 0x5d; /* POP(EBP); */ |
1731 | 1731 | *q++ = 0xc3; /* RET(); */ |
1732 | - | |
1732 | + | |
1733 | 1733 | *qq = q; |
1734 | 1734 | return 0; |
1735 | 1735 | } |
@@ -1,4 +1,4 @@ | ||
1 | -#include "osecpu.h" | |
1 | +#include "osecpu.h" | |
2 | 2 | |
3 | 3 | int *keybuf, keybuf_r, keybuf_w, keybuf_c; |
4 | 4 | HOSECPU_Device_Window mainWindow; |
@@ -1,4 +1,4 @@ | ||
1 | -#ifndef _HDLOAD_OSECPU | |
1 | +#ifndef _HDLOAD_OSECPU | |
2 | 2 | #define _HDLOAD_OSECPU 1 |
3 | 3 | |
4 | 4 | /* Visual Studio で fopen()やsprintf() などの古い関数を使用する時に出る警告を抑止する*/ |
@@ -1,4 +1,4 @@ | ||
1 | - | |
1 | + | |
2 | 2 | #include "osecpu.h" |
3 | 3 | |
4 | 4 | static struct { |
@@ -1,4 +1,4 @@ | ||
1 | -#include "osecpu.h" | |
1 | +#include "osecpu.h" | |
2 | 2 | |
3 | 3 | void putOsaskChar(int c, HOSECPU_RuntimeEnvironment *r) |
4 | 4 | { |