• R/O
  • HTTP
  • SSH
  • HTTPS

HeavyOSECPU: Commit


Commit MetaInfo

Revisión4290c48188d4ccb377996de3c585471fb171e9d9 (tree)
Tiempo2014-03-12 18:20:29
Autorttwilb <ttwilb@user...>
Commiterttwilb

Log Message

Visual Studioでコンパイルが通るように

Cambiar Resumen

Diferencia incremental

--- a/comlib.c
+++ b/comlib.c
@@ -1,4 +1,4 @@
1-#include "osecpu.h"
1+#include "osecpu.h"
22
33 struct ComLib_Str {
44 const unsigned char *p;
--- a/dpndenv.c
+++ b/dpndenv.c
@@ -1,4 +1,4 @@
1-#include "osecpu.h"
1+#include "osecpu.h"
22
33
44 #if (DRV_OSNUM == 0x0002)
--- a/fontdata.c
+++ b/fontdata.c
@@ -1,4 +1,4 @@
1-
1+
22 unsigned char fontdata[] = {
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,
--- a/function.c
+++ b/function.c
@@ -1,4 +1,4 @@
1-#include "osecpu.h"
1+#include "osecpu.h"
22
33 extern unsigned char fontdata[]; // @fontdata.c
44
--- a/jitc.c
+++ b/jitc.c
@@ -29,47 +29,47 @@ void errorHandler(HOSECPU_RuntimeEnvironment *r)
2929
3030 int jitCompCmdLen(const unsigned char *src)
3131 {
32- //BCode命令長を取得する
32+ //BCode命令長を取得する
3333 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+ }
7373
7474 return i;
7575 }
@@ -133,7 +133,7 @@ void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n)
133133 disp -= jitCompA0001_EBP128;
134134 if (-128 <= disp && disp <= 127) {
135135 jitCompPutByte2(w->dst, 0x45 | (n << 3), disp & 0xff);
136- } else {
136+ } else {
137137 jitCompPutByte1(w->dst, 0x85 | (n << 3));
138138 jitCompPutImm32(w, disp);
139139 }
@@ -164,8 +164,8 @@ void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)
164164 }
165165 #endif
166166 if (rxx >= 0x40 || rxx < 0){
167- w->err = JITC_ERR_REGNUM;
168- }
167+ w->err = JITC_ERR_REGNUM;
168+ }
169169 jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, rxx * 4); /* MOV(EAX, [EBP+?]); */
170170 return;
171171 }
@@ -173,8 +173,8 @@ void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)
173173 void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx)
174174 {
175175 if (rxx >= 0x40 || rxx < 0){
176- w->err = JITC_ERR_REGNUM;
177- }
176+ w->err = JITC_ERR_REGNUM;
177+ }
178178 jitCompA0001_movEbpDispReg32(w, rxx * 4, 0 /* EAX */); /* MOV([EBP+?], EAX); */
179179 return;
180180 }
@@ -183,8 +183,8 @@ void jitCompA0001_fixPrefix(struct JitCompWork *w)
183183 {
184184 if (w->prefix != 0) {
185185 if (w->dst - w->dst0 > 127){
186- w->err = JITC_ERR_REGNUM;
187- }
186+ w->err = JITC_ERR_REGNUM;
187+ }
188188 w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff);
189189 }
190190 return;
@@ -193,11 +193,11 @@ void jitCompA0001_fixPrefix(struct JitCompWork *w)
193193 void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1)
194194 {
195195 if (p0 >= 0x3f || p0 < 0){
196- w->err = JITC_ERR_PREGNUM;
197- }
196+ w->err = JITC_ERR_PREGNUM;
197+ }
198198 if (p1 >= 0x3f || p1 < 0){
199- w->err = JITC_ERR_PREGNUM;
200- }
199+ w->err = JITC_ERR_PREGNUM;
200+ }
201201 /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */
202202 return;
203203 }
@@ -244,21 +244,21 @@ void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)
244244
245245 int jitCompA000_selectRegCache(int rxx, int reg)
246246 {
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;
262262 }
263263
264264 void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)
@@ -280,33 +280,33 @@ void jitCompA000_storePRegCacheAll(struct JitCompWork *w)
280280 int jitCompA000_selectPRegCache(int pxx, int reg)
281281 {
282282 // 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;
295295 }
296296
297297 int jitCompA000_convTyp(int t)
298298 {
299299 int r = -1;
300-
300+
301301 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+ }
310310 return r;
311311 }
312312
@@ -385,14 +385,14 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
385385 {
386386 struct JitCompWork w;
387387 unsigned char *dst00 = dst, *enter0 = NULL, *tmp_ucp;
388- char *errmsg = "";
388+ char *errmsg = "";
389389 const unsigned char *oldsrc;
390390 int timecount = 0, i, j = 0, lastlabel = -1, debugInfo0 = -1;
391391 int reg0, reg1, reg2, cmp0reg = -1, cmp0lev = 0;
392392 w.dst = w.dst0 = dst;
393393 w.err = 0;
394394 w.maxLabels = maxLabels;
395-
395+
396396 if ((flags & JITC_NOSTARTUP) == 0) {
397397 jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */
398398 jitCompA000_loadRegCacheAll(&w); /* start-up */
@@ -415,1082 +415,1082 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
415415 }
416416 prefix_continue: // CND命令実行後ここに戻る
417417 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);
458458 #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+ }
463463 #endif
464- }
464+ }
465465 #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+ }
478478 #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+
516516 #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+ }
521521 #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+
527527 #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+ }
533533 #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 命令のアドレス部を記述
587587 #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+ }
601601 #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; }
828828 #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;
831831 #if (jitCompA0001_USE_R3F_IMM8 != 0)
832- if (-0x80 <= j && j <= 0x7f) {
832+ if (-0x80 <= j && j <= 0x7f) {
833833 #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 */
836836 #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+ }
840840 #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+ }
850850 #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+ }
875875 #if (jitCompA0001_USE_R3F_IMM32 != 0)
876- padd1:
876+ padd1:
877877 #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 */);
918918 #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+ }
932932 #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)) {
948948 #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+ }
956956 #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+ }
969969 #endif
970970 #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+ }
983983 #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+ }
10031003 #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;
10351035 #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+ }
10551055 #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+?]); */
10581058 #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+ }
10661066 #else
1067- jitCompA0001_movEaxRxx(&w, src[2]);
1067+ jitCompA0001_movEaxRxx(&w, src[2]);
10681068 #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); // 手抜き.
10831083 #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+ }
10981098 #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+?]); */
11011101 #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]);
12231223 #if (jitCompA0001_USE_R3F_IMM32 != 0)
1224- if (src[3] == 0x3f) {
1224+ if (src[3] == 0x3f) {
12251225 #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+ }
12411241 #endif
12421242 #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+ }
12471247 #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+ }
12591259 #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+ };
12761276 #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);
12901290 #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+ }
12961296 #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+ }
13011301 #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;
14941494 }
14951495 if (w.err != 0) goto err_w;
14961496 jitCompA0001_fixPrefix(&w);
@@ -1512,7 +1512,7 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
15121512 if ((flags & JITC_PHASE1) != 0)
15131513 return w.dst - dst00;
15141514 return 0;
1515-
1515+
15161516 err_w:
15171517 if ((w.err & JITC_ERR_PHASE0ONLY) != 0) {
15181518 if ((flags & JITC_PHASE1) == 0)
@@ -1561,10 +1561,10 @@ unsigned char *jitCompCallFunc(unsigned char *dst, void *func)
15611561 jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */
15621562 jitCompPutByte1(w.dst, 0xe8); /* CALL(func); */
15631563 int j = ((unsigned char *)func) - (w.dst + 4);
1564-
1564+
15651565 //この関数の中では結局w->dstしか参照していない
15661566 jitCompPutImm32(&w, j);
1567-
1567+
15681568 jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */ /* (win32では不要なのだけど、MacOSには必要らしい) */
15691569 jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */
15701570 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
16101610 int i;
16111611 r->junkStack -= 4;
16121612 r->junkStack -= 32;
1613- HOSECPU_PointerRegisterEntry *pp = (void *)r->junkStack;
1613+ HOSECPU_PointerRegisterEntry *pp = (void *)r->junkStack;
16141614 r->preg[0x30] = *pp;
16151615 r->junkStack -= p1 * 32; pp = (void *)r->junkStack;
16161616 for (i = 0; i < p1; i++)
@@ -1712,24 +1712,24 @@ int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const
17121712 unsigned char *q = *qq;
17131713 if (p0[0] != 0x05 || p0[1] != SIGN1) // OSECPUのヘッダ (05E1) を確認
17141714 return 1;
1715-
1715+
17161716 *q++ = 0x55; /* PUSH(EBP); */
17171717 *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */
1718-
1718+
17191719 int i;
17201720 for (i = 0; i < JITC_MAXLABELS; i++)
17211721 label[i].opt = 0;
1722-
1722+
17231723 // 以下のjitCompile()呼び出しでは第二引数をq1-2にした方がよいのではないか?
17241724 i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, 0);
17251725 if (i != 0) return 2;
17261726 i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, JITC_PHASE1 + 0);
17271727 if (i < 0) return 2;
17281728 q += i;
1729-
1729+
17301730 *q++ = 0x5d; /* POP(EBP); */
17311731 *q++ = 0xc3; /* RET(); */
1732-
1732+
17331733 *qq = q;
17341734 return 0;
17351735 }
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
1-#include "osecpu.h"
1+#include "osecpu.h"
22
33 int *keybuf, keybuf_r, keybuf_w, keybuf_c;
44 HOSECPU_Device_Window mainWindow;
--- a/osecpu.h
+++ b/osecpu.h
@@ -1,4 +1,4 @@
1-#ifndef _HDLOAD_OSECPU
1+#ifndef _HDLOAD_OSECPU
22 #define _HDLOAD_OSECPU 1
33
44 /* Visual Studio で fopen()やsprintf() などの古い関数を使用する時に出る警告を抑止する*/
--- a/randmt.c
+++ b/randmt.c
@@ -1,4 +1,4 @@
1-
1+
22 #include "osecpu.h"
33
44 static struct {
--- a/screen.c
+++ b/screen.c
@@ -1,4 +1,4 @@
1-#include "osecpu.h"
1+#include "osecpu.h"
22
33 void putOsaskChar(int c, HOSECPU_RuntimeEnvironment *r)
44 {
Show on old repository browser