Revisión | 0adf6a795f229e7fcb65a2bbbce31f5813a820b4 (tree) |
---|---|
Tiempo | 2014-03-16 16:23:48 |
Autor | hikarupsp <hikarupsp@user...> |
Commiter | hikarupsp |
JITCのソース整理
@@ -61,6 +61,8 @@ int jitCompCmdLen(const unsigned char *src); | ||
61 | 61 | // |
62 | 62 | #define envOffset_DBGINFO0 (2304 + 0) |
63 | 63 | #define envOffset_DBGINFO1 (2304 + 4) |
64 | +#define envOffset_PTRCTRL (2320) | |
65 | +#define PRegOffset(regid) (256 + 32 * regid) | |
64 | 66 | // |
65 | 67 | #define jitCompPutImm32(p, i) jitCompPutByte4(p, ((i) & 0xff), (((i) >> 8) & 0xff), (((i) >> 16) & 0xff), (((i) >> 24) & 0xff)) |
66 | 68 | // |
@@ -72,7 +74,9 @@ int jitCompCmdLen(const unsigned char *src); | ||
72 | 74 | #define jitCompPutOp_PUSH_GReg(p, reg) jitCompPutByte1(p, 0x50 | (reg)); |
73 | 75 | #define jitCompPutOp_PUSH_Imm8(p, i) jitCompPutByte2(p, 0x6a, i); |
74 | 76 | #define jitCompPutOp_POP_GReg(p, reg) jitCompPutByte1(p, 0x58 | (reg)); |
75 | -#define jitCompPutOp_CALL_Relative(p, diff) jitCompPutByte1(p, 0xe8); jitCompPutImm32(p, j); | |
77 | +#define jitCompPutOp_CALL_Relative(p, diff) jitCompPutByte1(p, 0xe8); jitCompPutImm32(p, diff); /*次の命令との相対オフセットだけ相対コールする*/ | |
78 | +#define jitCompPutOp_JMPnear(p, diff) jitCompPutByte1(p, 0xe9); jitCompPutImm32(p, diff); /*次の命令との相対オフセットだけ相対ジャンプする*/ | |
79 | +#define jitCompPutOp_JMPshort(p, diff) jitCompPutByte2(p, 0xeb, diff & 0xff);/*次の命令との相対オフセットだけ相対ジャンプする*/ | |
76 | 80 | // |
77 | 81 | #define jitCompPutOp_MOV_EAX_ZERO(p) jitCompPutOp_XOR_GReg_GReg(p, IA32_REG0_EAX, IA32_REG0_EAX); |
78 | 82 |
@@ -86,7 +90,7 @@ int jitCompCmdLen(const unsigned char *src); | ||
86 | 90 | #define jitCompA0001_OPTIMIZE_JMP 1*1 |
87 | 91 | #define jitCompA0001_OPTIMIZE_MOV 1*1 /* 1にすると速度低下する? */ |
88 | 92 | #define jitCompA0001_OPTIMIZE_CMP 1*1 |
89 | -#define jitCompA0001_OPTIMIZE_ALIGN 4*1 /* 0-8を想定 */ | |
93 | +#define jitCompA0001_OPTIMIZE_ALIGN 8 /* 0-8を想定 */ | |
90 | 94 | #define jitCompA0001_EBP128 128*1 |
91 | 95 | |
92 | 96 | struct JitCompWork { |
@@ -23,6 +23,7 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
23 | 23 | const unsigned char *oldsrc; |
24 | 24 | int timecount = 0, i, j = 0, lastlabel = -1, debugInfo0 = -1; |
25 | 25 | int reg0, reg1, reg2, cmp0reg = -1, cmp0lev = 0; |
26 | + | |
26 | 27 | w.dst = w.dst0 = dst; |
27 | 28 | w.err = 0; |
28 | 29 | w.maxLabels = maxLabels; |
@@ -77,14 +78,12 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
77 | 78 | // |
78 | 79 | if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) { //beginFunc()中のLB |
79 | 80 | // LB命令の後に0x3C命令・・・beginFunc() |
80 | - jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする | |
81 | - enter0 = w.dst; | |
82 | - jitCompPutImm32(w.dst, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ?? | |
81 | + enter0 = w.dst + 1; | |
82 | + jitCompPutOp_JMPnear(w.dst, 0); | |
83 | 83 | } |
84 | 84 | if (src[6] == 0x34) { |
85 | 85 | // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令 |
86 | 86 | tmp_ucp = w.dst; |
87 | - jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする | |
88 | 87 | i = jitCompGetImm32(&src[7]); // type32 を取得 |
89 | 88 | j = 32; |
90 | 89 | if (i != 1) { |
@@ -106,19 +105,27 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
106 | 105 | } |
107 | 106 | } |
108 | 107 | j *= jitCompGetImm32(&src[11]); |
109 | - if (j <= 0) w.err = JITC_ERR_BADTYPE; | |
110 | - jitCompPutImm32(w.dst, j); | |
108 | + if (j <= 0){ | |
109 | + w.err = JITC_ERR_BADTYPE; | |
110 | + } | |
111 | + jitCompPutOp_JMPnear(w.dst, j); | |
111 | 112 | #if (jitCompA0001_OPTIMIZE_JMP != 0) |
112 | 113 | if (j <= 127 - jitCompA0001_OPTIMIZE_ALIGN) { |
114 | + // 今書いたのはなかったことにして、 | |
113 | 115 | w.dst -= 5; |
114 | - jitCompPutByte2(w.dst, 0xeb, j); | |
116 | + // よりサイズの小さな書き方にする | |
117 | + jitCompPutOp_JMPshort(w.dst, j); | |
115 | 118 | } |
116 | 119 | #endif |
117 | 120 | } |
118 | 121 | #if (jitCompA0001_OPTIMIZE_ALIGN != 0) |
122 | + // アラインを jitCompA0001_OPTIMIZE_ALIGNにそろえる | |
119 | 123 | for (;;) { |
120 | 124 | i = ((int)w.dst) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */ |
121 | - if (i == 0) break; | |
125 | + if (i == 0){ | |
126 | + // Already alligned. | |
127 | + break; | |
128 | + } | |
122 | 129 | i = jitCompA0001_OPTIMIZE_ALIGN - i; |
123 | 130 | if (i == 1) { jitCompPutByte1(w.dst, 0x90); j += i; } /* NOP(); */ |
124 | 131 | if (i == 2) { jitCompPutByte2(w.dst, 0x89, 0xc0); j += i; } /* MOV(EAX, EAX); */ |
@@ -263,8 +270,7 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
263 | 270 | j += 3; |
264 | 271 | w.dst -= 5; |
265 | 272 | jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */ |
266 | - } | |
267 | - else { | |
273 | + } else { | |
268 | 274 | j += 4; |
269 | 275 | w.dst -= 6; |
270 | 276 | jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0); |
@@ -273,28 +279,25 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
273 | 279 | } |
274 | 280 | #endif |
275 | 281 | } else { // プログラムカウンタ以外への代入 |
276 | - | |
277 | 282 | // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定 |
278 | 283 | reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX); |
279 | - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ | |
280 | - jitCompPutImm32(w.dst, (int)label[i].p); // ラベルのパスを各レジスタに代入 | |
281 | - | |
282 | - // レジスタへの代入をメモリでエミュレーションする場合は、スタックに積む。 | |
283 | - if (reg0 == 0) | |
284 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
284 | + // ラベルのパスを各レジスタに代入 | |
285 | + jitCompPutOp_MOV_GReg_Imm32(w.dst, reg0, (int)label[i].p); | |
286 | + // レジスタへの代入をメモリでエミュレーションする場合は、スタックに書き込む。 | |
287 | + if (reg0 == 0){ | |
288 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 0, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
289 | + } | |
285 | 290 | |
286 | 291 | if (level < JITC_LV_FASTEST) { |
287 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 8, reg0); /* MOV([EBP+?], reg0); */ /* p0 */ | |
288 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
289 | - jitCompPutImm32(w.dst, label[i].typ); | |
290 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 4, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ /* typ */ | |
291 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
292 | - jitCompPutImm32(w.dst, (int)label[i].p1); | |
293 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 12, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ /* p1 */ | |
292 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 8, reg0); /* p0 */ | |
293 | + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, label[i].typ); | |
294 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 4, IA32_REG0_EAX); /* typ */ | |
295 | + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, (int)label[i].p1); | |
296 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 12, IA32_REG0_EAX); /* p1 */ | |
294 | 297 | jitCompPutOp_MOV_EAX_ZERO(w.dst); |
295 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 16, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ /* liveSign */ | |
296 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, 0, 2320); /* MOV(EAX, ptrCtrl); */ | |
297 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 20, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ /* pls */ | |
298 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 16, IA32_REG0_EAX); /* liveSign */ | |
299 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, envOffset_PTRCTRL); | |
300 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 20, IA32_REG0_EAX); /* pls */ | |
298 | 301 | } |
299 | 302 | } |
300 | 303 | break; |
@@ -313,19 +316,22 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
313 | 316 | reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */); |
314 | 317 | |
315 | 318 | /* TEST命令を発行 */ |
316 | - if (reg0 < 0) { //比較対象のレジスタはメモリ上にある | |
317 | - jitCompPutByte1(w.dst, 0xf7); /* TEST([EBP+?],1); */ | |
319 | + if (reg0 < 0) { | |
320 | + // 比較対象のレジスタはメモリ上にある | |
321 | + jitCompPutByte1(w.dst, 0xf7); /* TEST = 1111 011w : mod 000 r/m : immediate data */ | |
318 | 322 | jitCompPutModRM_Disp_BaseEBP(&w, src[1] * 4, 0); |
319 | - } | |
320 | - else { | |
321 | - jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST(reg0,1); */ | |
323 | + } else { | |
324 | + // 比較対象はキャッシュレジスタ上にある | |
325 | + jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST = 1111 011w : 11 000 reg : immediate data */ | |
322 | 326 | } |
323 | 327 | jitCompPutImm32(w.dst, 1); |
324 | 328 | |
325 | 329 | /* JZ命令を発行 */ |
326 | 330 | jitCompPutByte2(w.dst, 0x74, 0x00); /* JZ($+2) */ |
327 | 331 | cmp0reg = -1; |
328 | - if (w.err != 0) goto err_w; | |
332 | + if (w.err != 0){ | |
333 | + goto err_w; | |
334 | + } | |
329 | 335 | src += 2; |
330 | 336 | w.prefix = 1; // プリフィックスをセット |
331 | 337 | w.dst0 = w.dst; |
@@ -333,21 +339,27 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
333 | 339 | |
334 | 340 | case 0x08: /* LMEM */ /* 完成 */ |
335 | 341 | i = jitCompGetImm32(src + 2); |
336 | - if (i == 0x0001) w.err = JITC_ERR_BADTYPE; | |
342 | + if (i == 0x0001){ | |
343 | + w.err = JITC_ERR_BADTYPE; | |
344 | + } | |
337 | 345 | if (level < JITC_LV_FASTER) { |
338 | 346 | jitCompA0001_checkType(&w, src[6], i, 0); // read |
339 | 347 | cmp0reg = -1; |
340 | 348 | } |
341 | 349 | reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); |
342 | 350 | reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX); |
343 | - if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX) | |
351 | + if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX){ | |
344 | 352 | reg1 = IA32_REG0_EAX; |
345 | - if (reg1 == IA32_REG2_EDX) | |
353 | + } | |
354 | + if (reg1 == IA32_REG2_EDX){ | |
346 | 355 | jitCompA000_storeRegCacheEdx(&w); |
347 | - if (reg1 <= 3 /* EAX, EDX */) | |
348 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
349 | - if (level < JITC_LV_FASTER) | |
356 | + } | |
357 | + if (reg1 <= 3 /* EAX, EDX */){ | |
358 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6])); | |
359 | + } | |
360 | + if (level < JITC_LV_FASTER){ | |
350 | 361 | jitCompA0001_checkLimit(&w, reg1, src[6]); |
362 | + } | |
351 | 363 | i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); |
352 | 364 | switch (i) { |
353 | 365 | case 0x0002: |
@@ -369,31 +381,40 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
369 | 381 | default: |
370 | 382 | w.err = JITC_ERR_BADTYPE; |
371 | 383 | } |
372 | - if (reg0 == 0 /* EAX */) | |
384 | + if (reg0 == IA32_REG0_EAX){ | |
373 | 385 | jitCompA0001_movRxxEax(&w, src[1]); |
374 | - if (reg1 == 2 /* EDX */) | |
386 | + } | |
387 | + if (reg1 == IA32_REG2_EDX){ | |
375 | 388 | jitCompA000_loadRegCacheEdx(&w); |
389 | + } | |
376 | 390 | break; |
377 | 391 | |
378 | 392 | case 0x09: /* SMEM */ /* 完成 */ |
379 | 393 | i = jitCompGetImm32(src + 2); |
380 | - if (i == 0x0001) w.err = JITC_ERR_BADTYPE; | |
394 | + if (i == 0x0001){ | |
395 | + w.err = JITC_ERR_BADTYPE; | |
396 | + } | |
381 | 397 | if (level < JITC_LV_FASTER) { |
382 | 398 | jitCompA0001_checkType(&w, src[6], i, 1); // write |
383 | 399 | cmp0reg = -1; |
384 | 400 | } |
385 | 401 | reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); |
386 | 402 | reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX); |
387 | - if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX) | |
403 | + if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX){ | |
388 | 404 | reg1 = IA32_REG0_EAX; |
389 | - if (reg1 == IA32_REG2_EDX) | |
405 | + } | |
406 | + if (reg1 == IA32_REG2_EDX){ | |
390 | 407 | jitCompA000_storeRegCacheEdx(&w); |
391 | - if (reg1 <= 3 /* EAX, EDX */) | |
392 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
393 | - if (level < JITC_LV_FASTER) | |
408 | + } | |
409 | + if (reg1 <= 3 /* EAX, EDX */){ | |
410 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6]) + 0); /* MOV(reg1, [EBP+?]); */ | |
411 | + } | |
412 | + if (level < JITC_LV_FASTER){ | |
394 | 413 | jitCompA0001_checkLimit(&w, reg1, src[6]); |
395 | - if (reg0 == 0 /* EAX */) | |
414 | + } | |
415 | + if (reg0 == IA32_REG0_EAX){ | |
396 | 416 | jitCompA0001_movEaxRxx(&w, src[1]); |
417 | + } | |
397 | 418 | /* 値の範囲チェック */ |
398 | 419 | i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); |
399 | 420 | switch (i) { |
@@ -412,13 +433,16 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
412 | 433 | default: |
413 | 434 | w.err = JITC_ERR_BADTYPE; |
414 | 435 | } |
415 | - if (reg1 == IA32_REG2_EDX) | |
436 | + if (reg1 == IA32_REG2_EDX){ | |
416 | 437 | jitCompA000_loadRegCacheEdx(&w); |
438 | + } | |
417 | 439 | break; |
418 | 440 | |
419 | 441 | case 0x0a: /* PLMEM */ /* 完成 */ |
420 | 442 | i = jitCompGetImm32(src + 2); |
421 | - if (i != 0x0001) w.err = JITC_ERR_BADTYPE; | |
443 | + if (i != 0x0001){ | |
444 | + w.err = JITC_ERR_BADTYPE; | |
445 | + } | |
422 | 446 | if (level < JITC_LV_FASTER) { |
423 | 447 | jitCompA0001_checkType(&w, src[6], i, 0); // read |
424 | 448 | cmp0reg = -1; |
@@ -432,21 +456,26 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
432 | 456 | jitCompA000_storePRegCacheAll(&w); |
433 | 457 | reg1 = IA32_REG2_EDX; |
434 | 458 | } |
435 | - if (reg1 == IA32_REG2_EDX) | |
459 | + if (reg1 == IA32_REG2_EDX){ | |
436 | 460 | jitCompA000_storeRegCacheEdx(&w); |
437 | - if (reg1 <= 3 /* EAX, EDX */) | |
438 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
439 | - if (level < JITC_LV_FASTER) | |
461 | + } | |
462 | + if (reg1 <= 3 /* EAX, EDX */){ | |
463 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6])); /* MOV(reg1, [EBP+?]); */ | |
464 | + } | |
465 | + if (level < JITC_LV_FASTER){ | |
440 | 466 | jitCompA0001_checkLimit(&w, reg1, src[6]); |
467 | + } | |
441 | 468 | jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */ |
442 | - if (reg0 == IA32_REG0_EAX) | |
443 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 0, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
469 | + if (reg0 == IA32_REG0_EAX){ | |
470 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]), IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
471 | + } | |
444 | 472 | for (i = 4; i < 32; i += 4) { |
445 | 473 | jitCompPutByte3(w.dst, 0x8b, 0x40 | reg1, i); /* MOV(EAX, [reg1+?]); */ |
446 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
474 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
447 | 475 | } |
448 | - if (reg1 == IA32_REG2_EDX) | |
476 | + if (reg1 == IA32_REG2_EDX){ | |
449 | 477 | jitCompA000_loadRegCacheEdx(&w); |
478 | + } | |
450 | 479 | break; |
451 | 480 | |
452 | 481 | case 0x0b: /* PSMEM */ /* 完成 */ |
@@ -461,17 +490,21 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
461 | 490 | /* これをやってはいけない!(by K, 2013.08.02) */ |
462 | 491 | // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) |
463 | 492 | // reg1 = 0; /* EAX */ |
464 | - if (reg1 == IA32_REG2_EDX) | |
493 | + if (reg1 == IA32_REG2_EDX){ | |
465 | 494 | jitCompA000_storeRegCacheEdx(&w); |
466 | - if (reg1 <= 3 /* EAX, EDX */) | |
467 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
468 | - if (level < JITC_LV_FASTER) | |
495 | + } | |
496 | + if (reg1 <= 3 /* EAX, EDX */){ | |
497 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6])); /* MOV(reg1, [EBP+?]); */ | |
498 | + } | |
499 | + if (level < JITC_LV_FASTER){ | |
469 | 500 | jitCompA0001_checkLimit(&w, reg1, src[6]); |
470 | - if (reg0 == IA32_REG0_EAX) | |
471 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, 256 + src[1] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
501 | + } | |
502 | + if (reg0 == IA32_REG0_EAX){ | |
503 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[1])); /* MOV(reg0, [EBP+?]); */ | |
504 | + } | |
472 | 505 | jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */ |
473 | 506 | for (i = 4; i < 32; i += 4) { |
474 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, 256 + src[1] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
507 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[1]) + i); /* MOV(EAX, [EBP+?]); */ | |
475 | 508 | jitCompPutByte3(w.dst, 0x89, 0x40 | reg1, i); /* MOV([reg1+?], EAX); */ |
476 | 509 | } |
477 | 510 | if (reg1 == IA32_REG2_EDX) |
@@ -485,61 +518,76 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
485 | 518 | } |
486 | 519 | reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX); |
487 | 520 | reg1 = jitCompA000_selectPRegCache(src[6], -1 /* mem */); |
488 | - if (reg1 < 0 /* mem */) | |
489 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
521 | + if (reg1 < 0 /* mem */){ | |
522 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[6])); /* MOV(reg0, [EBP+?]); */ | |
523 | + } | |
490 | 524 | if (reg1 >= 0 && reg0 != reg1) { |
491 | 525 | jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ |
492 | 526 | } |
493 | 527 | i = jitCompGetImm32(src + 2); |
494 | 528 | j = -1; |
495 | - if (i == 1) | |
529 | + if (i == 1){ | |
496 | 530 | j = 5; /* 32 */ |
497 | - else { | |
531 | + } else { | |
498 | 532 | i = jitCompA000_convTyp(i); |
499 | - if (0x0002 <= i && i <= 0x0007) | |
533 | + if (0x0002 <= i && i <= 0x0007){ | |
500 | 534 | j = (i - 0x0002) >> 1; |
535 | + } | |
536 | + } | |
537 | + if (j < 0) { | |
538 | + w.err = JITC_ERR_BADTYPE; | |
539 | + goto err_w; | |
501 | 540 | } |
502 | - if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
503 | 541 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
504 | 542 | if (src[7] == 0x3f) { |
505 | 543 | j = w.r3f << j; |
506 | 544 | #if (jitCompA0001_USE_R3F_IMM8 != 0) |
507 | 545 | if (-0x80 <= j && j <= 0x7f) { |
508 | 546 | #if (jitCompA0001_USE_R3F_INCDEC != 0) |
509 | - if (j == 1) { jitCompPutByte1(w.dst, 0x40 | reg0); goto padd1; } /* INC */ | |
510 | - if (j == -1) { jitCompPutByte1(w.dst, 0x48 | reg0); goto padd1; } /* DEC */ | |
547 | + if (j == 1) { | |
548 | + /* INC */ | |
549 | + jitCompPutByte1(w.dst, 0x40 | reg0); | |
550 | + goto padd1; | |
551 | + } | |
552 | + if (j == -1) { | |
553 | + /* DEC */ | |
554 | + jitCompPutByte1(w.dst, 0x48 | reg0); | |
555 | + goto padd1; | |
556 | + } | |
511 | 557 | #endif |
512 | - jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff); /* ADD(reg0, im8); */ | |
558 | + /* ADD(reg0, im8); */ | |
559 | + jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff); | |
513 | 560 | goto padd1; |
514 | 561 | } |
515 | 562 | #endif |
516 | 563 | if (reg0 == 0) { |
517 | 564 | jitCompPutByte1(w.dst, 0x05); /* ADD(reg0, ?); */ |
518 | - } | |
519 | - else { | |
565 | + } else { | |
520 | 566 | jitCompPutByte2(w.dst, 0x81, 0xc0 | reg0); /* ADD(reg0, ?); */ |
521 | 567 | } |
522 | 568 | jitCompPutImm32(w.dst, j); |
523 | 569 | goto padd1; |
524 | 570 | } |
525 | 571 | #endif |
526 | - if (src[7] >= 0x40) w.err = JITC_ERR_REGNUM; | |
572 | + if (src[7] >= 0x40){ | |
573 | + w.err = JITC_ERR_REGNUM; | |
574 | + } | |
527 | 575 | if (j == 0) { |
528 | 576 | reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */); |
529 | 577 | if (reg1 >= 0) { |
530 | 578 | jitCompPutByte2(w.dst, 0x01, 0xc0 | reg1 << 3 | reg0); /* ADD(reg0, reg1); */ |
531 | - } | |
532 | - else { | |
579 | + } else { | |
533 | 580 | jitCompPutByte1(w.dst, 0x03); /* ADD(reg0, [EBP+?]); */ |
534 | 581 | jitCompPutModRM_Disp_BaseEBP(&w, src[7] * 4, reg0); |
535 | 582 | } |
536 | 583 | } |
537 | 584 | else { |
538 | 585 | reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */); |
539 | - reg2 = 2; /* EDX */ | |
586 | + reg2 = IA32_REG2_EDX; | |
540 | 587 | jitCompA000_storeRegCacheEdx(&w); |
541 | - if (reg1 < 0) | |
588 | + if (reg1 < 0){ | |
542 | 589 | jitCompPutOp_MOV_GReg_EBPDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */ |
590 | + } | |
543 | 591 | if (reg1 >= 0 && reg1 != reg2) { |
544 | 592 | jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg2); /* MOV(reg2, reg1); */ |
545 | 593 | } |
@@ -550,12 +598,13 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
550 | 598 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
551 | 599 | padd1: |
552 | 600 | #endif |
553 | - if (reg0 == IA32_REG0_EAX) | |
554 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 0, reg0); /* MOV([EBP+?], reg0); */ | |
601 | + if (reg0 == IA32_REG0_EAX){ | |
602 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]), reg0); /* MOV([EBP+?], reg0); */ | |
603 | + } | |
555 | 604 | if (src[1] != src[6]) { |
556 | 605 | for (i = 4; i < 32; i += 4) { |
557 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
558 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
606 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */ | |
607 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
559 | 608 | } |
560 | 609 | } |
561 | 610 | cmp0reg = -1; |
@@ -565,20 +614,26 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
565 | 614 | reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); |
566 | 615 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
567 | 616 | jitCompA0001_checkCompPtr(&w, src[6], src[7]); |
568 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
617 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[6])); /* MOV(reg0, [EBP+?]); */ | |
569 | 618 | jitCompPutByte1(w.dst, 0x2b); /* SUB(EAX, [EBP+?]); */ |
570 | - jitCompPutModRM_Disp_BaseEBP(&w, 256 + src[7] * 32 + 0, reg0); | |
619 | + jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[7]) + 0, reg0); | |
571 | 620 | i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); |
572 | 621 | j = -1; |
573 | - if (0x0002 <= i && i <= 0x0007) | |
622 | + if (0x0002 <= i && i <= 0x0007){ | |
574 | 623 | j = (i - 0x0002) >> 1; |
575 | - if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
624 | + } | |
625 | + if (j < 0) { | |
626 | + w.err = JITC_ERR_BADTYPE; | |
627 | + goto err_w; | |
628 | + } | |
576 | 629 | if (j > 0) { |
577 | 630 | jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, j); /* SAR(reg0,?); */ |
578 | 631 | } |
579 | - if (reg0 == 0 /* EAX */) | |
632 | + if (reg0 == IA32_REG0_EAX){ | |
580 | 633 | jitCompA0001_movRxxEax(&w, src[1]); |
581 | - cmp0reg = src[1]; cmp0lev = 1; | |
634 | + } | |
635 | + cmp0reg = src[1]; | |
636 | + cmp0lev = 1; | |
582 | 637 | break; |
583 | 638 | |
584 | 639 | case 0x10: /* OR */ |
@@ -587,21 +642,27 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
587 | 642 | case 0x14: /* ADD */ |
588 | 643 | case 0x15: /* SUB */ |
589 | 644 | case 0x16: /* MUL */ |
590 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
645 | + if (src[1] >= 0x3f){ | |
646 | + w.err = JITC_ERR_REGNUM; | |
647 | + } | |
591 | 648 | reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); |
592 | 649 | reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); |
593 | 650 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
594 | 651 | if (src[2] == 0x3f) { // SUBのみ該当. |
595 | - if (*src != 0x15) w.err = JITC_ERR_REGNUM; | |
652 | + if (*src != 0x15){ | |
653 | + w.err = JITC_ERR_REGNUM; | |
654 | + } | |
596 | 655 | reg2 = jitCompA000_selectRegCache(src[3], -1 /* mem */); |
597 | - if (reg2 >= 0) | |
656 | + if (reg2 >= 0){ | |
598 | 657 | jitCompA000_storeRegCacheAll(&w); |
658 | + } | |
599 | 659 | jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ |
600 | 660 | jitCompPutImm32(w.dst, w.r3f); |
601 | 661 | jitCompPutByte1(w.dst, 0x2b); |
602 | 662 | jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); |
603 | - if (reg0 == 0) | |
663 | + if (reg0 == 0){ | |
604 | 664 | jitCompA0001_movRxxEax(&w, src[1]); |
665 | + } | |
605 | 666 | break; |
606 | 667 | } |
607 | 668 | #endif |
@@ -615,31 +676,36 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
615 | 676 | // bugfix: hinted by Iris, 2013.06.26. thanks! |
616 | 677 | cmp0reg = src[1]; |
617 | 678 | cmp0lev = 1; |
618 | - if (src[0] < 0x14) | |
679 | + if (src[0] < 0x14){ | |
619 | 680 | cmp0lev = 2; |
620 | - if (src[0] == 0x16) | |
681 | + } | |
682 | + if (src[0] == 0x16){ | |
621 | 683 | cmp0reg = -1; |
684 | + } | |
622 | 685 | } |
623 | 686 | if (!(src[0] == 0x10 && src[3] == 0xff)) { |
624 | 687 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
625 | 688 | if (src[3] == 0x3f) { |
626 | 689 | if (*src == 0x16 && w.r3f == -1) { |
627 | 690 | jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */ |
628 | - if (reg0 == 0) | |
691 | + if (reg0 == 0){ | |
629 | 692 | jitCompA0001_movRxxEax(&w, src[1]); |
693 | + } | |
630 | 694 | break; |
631 | 695 | } |
632 | 696 | #if (jitCompA0001_USE_R3F_INCDEC != 0) |
633 | 697 | if ((*src == 0x14 && w.r3f == 1) || (*src == 0x15 && w.r3f == -1)) { |
634 | 698 | jitCompPutByte1(w.dst, 0x40 | reg0); /* INC(reg0); */ |
635 | - if (reg0 == 0) | |
699 | + if (reg0 == 0){ | |
636 | 700 | jitCompA0001_movRxxEax(&w, src[1]); |
701 | + } | |
637 | 702 | break; |
638 | 703 | } |
639 | 704 | if ((*src == 0x15 && w.r3f == 1) || (*src == 0x14 && w.r3f == -1)) { |
640 | 705 | jitCompPutByte1(w.dst, 0x48 | reg0); /* DEC(reg0); */ |
641 | - if (reg0 == 0) | |
706 | + if (reg0 == 0){ | |
642 | 707 | jitCompA0001_movRxxEax(&w, src[1]); |
708 | + } | |
643 | 709 | break; |
644 | 710 | } |
645 | 711 | #endif |
@@ -648,21 +714,22 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
648 | 714 | if (*src != 0x16) { |
649 | 715 | static unsigned char basic_op_table_im8[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 }; |
650 | 716 | jitCompPutByte3(w.dst, 0x83, basic_op_table_im8[*src - 0x10] | reg0, w.r3f & 0xff); |
651 | - } | |
652 | - else { | |
717 | + } else{ | |
653 | 718 | jitCompPutByte3(w.dst, 0x6b, 0xc0 | reg0 << 3 | reg0, w.r3f & 0xff); |
654 | 719 | } |
655 | - if (reg0 == 0) | |
720 | + if (reg0 == 0){ | |
656 | 721 | jitCompA0001_movRxxEax(&w, src[1]); |
722 | + } | |
657 | 723 | break; |
658 | 724 | } |
659 | 725 | #endif |
660 | 726 | if (reg0 == IA32_REG0_EAX) { |
661 | 727 | static unsigned char basic_op_table_im32_eax[] = { 0x0d, 0x35, 0x25, 0, 0x05, 0x2d, 0xc0 }; |
662 | - if (*src == 0x16) { jitCompPutByte1(w.dst, 0x69); } | |
728 | + if (*src == 0x16) { | |
729 | + jitCompPutByte1(w.dst, 0x69); | |
730 | + } | |
663 | 731 | jitCompPutByte1(w.dst, basic_op_table_im32_eax[*src - 0x10]); |
664 | - } | |
665 | - else { | |
732 | + } else{ | |
666 | 733 | if (*src != 0x16) { |
667 | 734 | static unsigned char basic_op_table_im32_reg[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 }; |
668 | 735 | jitCompPutByte2(w.dst, 0x81, basic_op_table_im32_reg[*src - 0x10] | reg0); |
@@ -672,58 +739,72 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
672 | 739 | } |
673 | 740 | } |
674 | 741 | jitCompPutImm32(w.dst, w.r3f); |
675 | - if (reg0 == 0) | |
742 | + if (reg0 == 0){ | |
676 | 743 | jitCompA0001_movRxxEax(&w, src[1]); |
744 | + } | |
677 | 745 | break; |
678 | 746 | } |
679 | 747 | #endif |
680 | 748 | reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); |
681 | - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
749 | + if (src[3] >= 0x40){ | |
750 | + w.err = JITC_ERR_REGNUM; | |
751 | + } | |
682 | 752 | if (*src != 0x16) { |
683 | 753 | if (reg1 >= 0) { |
684 | 754 | static unsigned char basic_op_table_rr[] = { 0x09, 0x31, 0x21, 0, 0x01, 0x29 }; /* op(reg,reg); */ |
685 | 755 | jitCompPutByte2(w.dst, basic_op_table_rr[*src - 0x10], 0xc0 | reg1 << 3 | reg0); |
686 | - } | |
687 | - else { | |
756 | + } else{ | |
688 | 757 | static unsigned char basic_op_table_rm[] = { 0x0b, 0x33, 0x23, 0, 0x03, 0x2b, 0xaf }; /* op(reg,mem); */ |
689 | 758 | jitCompPutByte1(w.dst, basic_op_table_rm[*src - 0x10]); |
690 | 759 | jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); |
691 | 760 | } |
692 | - } | |
693 | - else { | |
761 | + } else{ | |
694 | 762 | if (reg1 >= 0) { |
695 | 763 | jitCompPutByte3(w.dst, 0x0f, 0xaf, 0xc0 | reg0 << 3 | reg1); |
696 | - } | |
697 | - else { | |
764 | + } else{ | |
698 | 765 | jitCompPutByte2(w.dst, 0x0f, 0xaf); |
699 | 766 | jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); |
700 | 767 | } |
701 | 768 | } |
702 | 769 | } |
703 | - if (reg0 == 0) | |
770 | + if (reg0 == 0){ | |
704 | 771 | jitCompA0001_movRxxEax(&w, src[1]); |
772 | + } | |
705 | 773 | break; |
706 | 774 | |
707 | 775 | case 0x18: /* SHL */ |
708 | 776 | case 0x19: /* SAR */ |
709 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
710 | - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
777 | + if (src[1] >= 0x3f){ | |
778 | + w.err = JITC_ERR_REGNUM; | |
779 | + } | |
780 | + if (src[3] >= 0x40){ | |
781 | + w.err = JITC_ERR_REGNUM; | |
782 | + } | |
711 | 783 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
712 | 784 | if (src[3] == 0x3f) { |
713 | 785 | reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); |
714 | 786 | reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); |
715 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
716 | - if (reg1 == -1) | |
787 | + if (src[1] >= 0x3f){ | |
788 | + w.err = JITC_ERR_REGNUM; | |
789 | + } | |
790 | + if (reg1 == -1){ | |
717 | 791 | jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, src[2] * 4); /* MOV(reg1, [EBP+?]); */ |
718 | - else { | |
792 | + } else{ | |
719 | 793 | if (reg0 != reg1) { |
720 | 794 | jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ |
721 | 795 | } |
722 | 796 | } |
723 | - if (*src == 0x18) { jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f); } /* SHL(reg0, im8); */ | |
724 | - if (*src == 0x19) { jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f); } /* SAR(reg0, im8); */ | |
725 | - if (reg0 == IA32_REG0_EAX) | |
797 | + if (*src == 0x18) { | |
798 | + /* SHL(reg0, im8); */ | |
799 | + jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f); | |
800 | + } | |
801 | + if (*src == 0x19) { | |
802 | + /* SAR(reg0, im8); */ | |
803 | + jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f); | |
804 | + } | |
805 | + if (reg0 == IA32_REG0_EAX){ | |
726 | 806 | jitCompA0001_movRxxEax(&w, src[1]); |
807 | + } | |
727 | 808 | cmp0reg = src[1]; |
728 | 809 | cmp0lev = 1; |
729 | 810 | break; |
@@ -735,15 +816,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
735 | 816 | if (src[2] == 0x3f) { |
736 | 817 | jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ |
737 | 818 | jitCompPutImm32(w.dst, w.r3f); |
738 | - } | |
739 | - else { | |
819 | + } else{ | |
740 | 820 | jitCompA0001_movEaxRxx(&w, src[2]); |
741 | 821 | } |
742 | 822 | #else |
743 | 823 | jitCompA0001_movEaxRxx(&w, src[2]); |
744 | 824 | #endif |
745 | - if (*src == 0x18) { jitCompPutByte2(w.dst, 0xd3, 0xe0); } /* SHL(EAX, CL); */ | |
746 | - if (*src == 0x19) { jitCompPutByte2(w.dst, 0xd3, 0xf8); } /* SAR(EAX, CL); */ | |
825 | + if (*src == 0x18) { | |
826 | + /* SHL(EAX, CL); */ | |
827 | + jitCompPutByte2(w.dst, 0xd3, 0xe0); | |
828 | + } | |
829 | + if (*src == 0x19) { | |
830 | + /* SAR(EAX, CL); */ | |
831 | + jitCompPutByte2(w.dst, 0xd3, 0xf8); | |
832 | + } | |
747 | 833 | jitCompA0001_movRxxEax(&w, src[1]); |
748 | 834 | jitCompA000_loadRegCacheAll(&w); // 手抜き. |
749 | 835 | cmp0reg = src[1]; |
@@ -752,23 +838,21 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
752 | 838 | |
753 | 839 | case 0x1a: /* DIV */ |
754 | 840 | case 0x1b: /* MOD */ |
755 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
756 | - if (src[2] >= 0x40) w.err = JITC_ERR_REGNUM; | |
757 | - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
841 | + if (src[1] >= 0x3f || src[2] >= 0x40 || src[3] >= 0x40){ | |
842 | + w.err = JITC_ERR_REGNUM; | |
843 | + } | |
758 | 844 | jitCompA000_storeRegCacheAll(&w); // 手抜き. |
759 | 845 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
760 | 846 | if (src[3] == 0x3f) { |
761 | 847 | jitCompPutByte1(w.dst, 0xb8 | 1); /* MOV(ECX, ?); */ |
762 | 848 | jitCompPutImm32(w.dst, w.r3f); |
763 | - } | |
764 | - else { | |
849 | + } else{ | |
765 | 850 | jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */ |
766 | 851 | } |
767 | 852 | if (src[2] == 0x3f) { |
768 | 853 | jitCompPutByte1(w.dst, 0xb8 | 0); /* MOV(EAX, ?); */ |
769 | 854 | jitCompPutImm32(w.dst, w.r3f); |
770 | - } | |
771 | - else { | |
855 | + } else{ | |
772 | 856 | jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, src[2] * 4); /* MOV(EAX, [EBP+?]); */ |
773 | 857 | } |
774 | 858 | #else |
@@ -778,15 +862,21 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
778 | 862 | jitCompPutByte1(w.dst, 0x99); /* CDQ(); */ |
779 | 863 | /* ECXがゼロではないことを確認すべき */ |
780 | 864 | jitCompPutByte2(w.dst, 0xf7, 0xf9); /* IDIV(ECX); */ |
781 | - if (*src == 0x1a) { jitCompPutOp_MOV_EBPDisp_GReg(&w, src[1] * 4, IA32_REG0_EAX); } | |
782 | - if (*src == 0x1b) { jitCompPutOp_MOV_EBPDisp_GReg(&w, src[1] * 4, IA32_REG2_EDX); } | |
865 | + if (*src == 0x1a) { | |
866 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, src[1] * 4, IA32_REG0_EAX); | |
867 | + } | |
868 | + if (*src == 0x1b) { | |
869 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, src[1] * 4, IA32_REG2_EDX); | |
870 | + } | |
783 | 871 | jitCompA000_loadRegCacheAll(&w); // 手抜き. |
784 | 872 | cmp0reg = -1; |
785 | 873 | break; |
786 | 874 | |
787 | 875 | case 0x1c: /* PLMT0 */ |
788 | 876 | case 0x1d: /* PLMT1 */ |
789 | - if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
877 | + if (src[1] >= 0x40 || src[2] >= 0x40){ | |
878 | + w.err = JITC_ERR_PREGNUM; | |
879 | + } | |
790 | 880 | if (level < JITC_LV_FASTEST) { |
791 | 881 | cmp0reg = -1; |
792 | 882 | if (level < JITC_LV_FASTER) { |
@@ -800,20 +890,23 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
800 | 890 | } |
801 | 891 | |
802 | 892 | case 0x1e: /* PCP */ /* 未完成(p1まで完成) */ |
803 | - if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
804 | - if (src[2] == 0x3f) w.err = JITC_ERR_PREGNUM; | |
893 | + if (src[1] >= 0x40 || src[2] >= 0x40){ | |
894 | + w.err = JITC_ERR_PREGNUM; | |
895 | + } | |
896 | + if (src[2] == 0x3f){ | |
897 | + w.err = JITC_ERR_PREGNUM; | |
898 | + } | |
805 | 899 | if (src[1] != 0x3f) { |
806 | 900 | /* src[2] == 0xff の場合に対応できてない */ |
807 | 901 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
808 | 902 | for (i = 0; i < 32; i += 4) { |
809 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, 256 + src[2] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
810 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
903 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + i); /* MOV(EAX, [EBP+?]); */ | |
904 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
811 | 905 | } |
812 | 906 | jitCompA000_loadPRegCacheAll(&w); // 手抜き. |
813 | - } | |
814 | - else { | |
907 | + } else { | |
815 | 908 | if (level < JITC_LV_FASTER) { |
816 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ | |
909 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ | |
817 | 910 | jitCompPutByte3(w.dst, 0x83, 0xf8, 0); /* CMP(EAX, 0); */ |
818 | 911 | jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ |
819 | 912 | jitCompPutImm32(w.dst, errfnc - (w.dst + 4)); |
@@ -821,10 +914,10 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
821 | 914 | } |
822 | 915 | reg0 = IA32_REG0_EAX; |
823 | 916 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
824 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ | |
917 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[2]) + 0); /* MOV(EAX, [EBP+?]); */ | |
825 | 918 | if (level < JITC_LV_FASTER) { |
826 | 919 | jitCompPutByte1(w.dst, 0x3b); /* CMP(reg0, [EBP+?]); */ |
827 | - jitCompPutModRM_Disp_BaseEBP(&w, 256 + src[2] * 32 + 8, reg0); /* p0 */ | |
920 | + jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[2]) + 8, reg0); /* p0 */ | |
828 | 921 | jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ |
829 | 922 | jitCompPutImm32(w.dst, errfnc - (w.dst + 4)); |
830 | 923 | } |
@@ -834,20 +927,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
834 | 927 | |
835 | 928 | case 0x1f: /* PCST */ |
836 | 929 | if (jitCompGetImm32(src + 2) == 0) { |
837 | - if (level < JITC_LV_FASTER) | |
930 | + if (level < JITC_LV_FASTER){ | |
838 | 931 | jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 7), 2); |
932 | + } | |
839 | 933 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
840 | 934 | for (i = 0; i < 32 - 4; i += 4) { |
841 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
935 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */ | |
842 | 936 | if (i == 4) { |
843 | 937 | jitCompPutByte1(w.dst, 0x0d); /* OR(EAX, ?); */ |
844 | 938 | jitCompPutImm32(w.dst, 0x80000000); |
845 | 939 | } |
846 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
940 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
847 | 941 | } |
848 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
849 | - jitCompPutImm32(w.dst, debugInfo1); | |
850 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 28, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
942 | + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1); | |
943 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 28, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
851 | 944 | jitCompA000_loadPRegCacheAll(&w); // 手抜き. |
852 | 945 | cmp0reg = -1; |
853 | 946 | break; |
@@ -855,20 +948,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
855 | 948 | if (jitCompGetImm32(src + 7) == 0) { |
856 | 949 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
857 | 950 | for (i = 0; i < 32 - 4; i += 4) { |
858 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
951 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */ | |
859 | 952 | if (i == 4) { |
860 | 953 | jitCompPutByte1(w.dst, 0x25); /* AND(EAX, ?); */ |
861 | 954 | jitCompPutImm32(w.dst, 0x7fffffff); |
862 | 955 | } |
863 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
956 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
864 | 957 | } |
865 | 958 | if (level < JITC_LV_FASTER) { |
866 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, 256 + src[6] * 32 + 28); /* MOV(EAX, [EBP+?]); */ | |
959 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + 28); /* MOV(EAX, [EBP+?]); */ | |
867 | 960 | jitCompPutByte1(w.dst, 0x3d); /* CMP(EAX, ?); */ |
868 | 961 | jitCompPutImm32(w.dst, debugInfo1); |
869 | 962 | jitCompPutByte2(w.dst, 0x74, 8); /* JE */ |
870 | - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); (2) */ | |
871 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 256 + src[1] * 32 + 0, IA32_REG0_EAX); /* MOV([EBP+?], EAX); (1+1+4) */ | |
963 | + jitCompPutOp_MOV_EAX_ZERO(w.dst); | |
964 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 0, IA32_REG0_EAX); /* MOV([EBP+?], EAX); (1+1+4) */ | |
872 | 965 | } |
873 | 966 | jitCompA000_loadPRegCacheAll(&w); // 手抜き. |
874 | 967 | cmp0reg = -1; |
@@ -889,9 +982,13 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
889 | 982 | reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); |
890 | 983 | if (src[1] == 0x3f) { |
891 | 984 | /* 特殊構文チェック */ |
892 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
985 | + if (w.prefix != 0) { | |
986 | + w.err = JITC_ERR_PREFIX; | |
987 | + goto err_w; | |
988 | + } | |
893 | 989 | if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) { |
894 | - w.err = JITC_ERR_IDIOM; goto err_w; | |
990 | + w.err = JITC_ERR_IDIOM; | |
991 | + goto err_w; | |
895 | 992 | } |
896 | 993 | } |
897 | 994 | if (reg0 == 0) |
@@ -902,10 +999,12 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
902 | 999 | if ((*src <= 0x25 && w.r3f == 0) || (*src >= 0x26 && w.r3f == -1)) { |
903 | 1000 | i = 0; |
904 | 1001 | if (cmp0reg == src[2]) { |
905 | - if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27)) | |
1002 | + if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27)){ | |
906 | 1003 | i = 1; |
907 | - if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25)) | |
1004 | + } | |
1005 | + if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25)){ | |
908 | 1006 | i = 1; |
1007 | + } | |
909 | 1008 | } |
910 | 1009 | if (i == 0) { |
911 | 1010 | jitCompPutByte2(w.dst, 0x85, 0xc0 | reg0 << 3 | reg0); /* TEST(reg0, reg0); */ |
@@ -922,29 +1021,48 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
922 | 1021 | } |
923 | 1022 | #endif |
924 | 1023 | if (reg0 == 0) { |
925 | - if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3d); } | |
926 | - if (*src >= 0x26) { jitCompPutByte1(w.dst, 0xa9); } | |
1024 | + if (*src <= 0x25) { | |
1025 | + jitCompPutByte1(w.dst, 0x3d); | |
1026 | + } | |
1027 | + if (*src >= 0x26) { | |
1028 | + jitCompPutByte1(w.dst, 0xa9); | |
1029 | + } | |
927 | 1030 | } |
928 | 1031 | else { |
929 | - if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0); } | |
930 | - if (*src >= 0x26) { jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); } | |
1032 | + if (*src <= 0x25) { | |
1033 | + jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0); | |
1034 | + } | |
1035 | + if (*src >= 0x26) { | |
1036 | + jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); | |
1037 | + } | |
931 | 1038 | } |
932 | 1039 | jitCompPutImm32(w.dst, w.r3f); |
933 | 1040 | goto cmpcc1; |
934 | 1041 | } |
935 | 1042 | #endif |
936 | - if (src[3] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
937 | - if (reg1 >= 0) { | |
938 | - if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x39, 0xc0 | reg1 << 3 | reg0); } | |
939 | - if (*src >= 0x26) { jitCompPutByte2(w.dst, 0x85, 0xc0 | reg1 << 3 | reg0); } | |
1043 | + if (src[3] >= 0x40){ | |
1044 | + w.err = JITC_ERR_PREGNUM; | |
940 | 1045 | } |
941 | - else { | |
942 | - if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3b); } | |
943 | - if (*src >= 0x26) { jitCompPutByte1(w.dst, 0x85); } | |
1046 | + if (reg1 >= 0) { | |
1047 | + if (*src <= 0x25) { | |
1048 | + jitCompPutByte2(w.dst, 0x39, 0xc0 | reg1 << 3 | reg0); | |
1049 | + } | |
1050 | + if (*src >= 0x26) { | |
1051 | + jitCompPutByte2(w.dst, 0x85, 0xc0 | reg1 << 3 | reg0); | |
1052 | + } | |
1053 | + } else{ | |
1054 | + if (*src <= 0x25) { | |
1055 | + jitCompPutByte1(w.dst, 0x3b); | |
1056 | + } | |
1057 | + if (*src >= 0x26) { | |
1058 | + jitCompPutByte1(w.dst, 0x85); | |
1059 | + } | |
944 | 1060 | jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); |
945 | 1061 | } |
946 | 1062 | cmpcc1: |
947 | - if (w.err != 0) goto err_w; | |
1063 | + if (w.err != 0){ | |
1064 | + goto err_w; | |
1065 | + } | |
948 | 1066 | static unsigned char cmpcc_table0[] = { |
949 | 1067 | 0x04, 0x05, 0x0c, 0x0d, 0x0e, 0x0f, 0x04, 0x05, /* CMPcc, TSTcc */ |
950 | 1068 | 0x04, 0x05, 0x02, 0x03, 0x06, 0x07 /* PCMPcc */ |
@@ -956,12 +1074,16 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
956 | 1074 | src += 6; |
957 | 1075 | i = jitCompGetLabelNum(&w, src + 2); |
958 | 1076 | if ((flags & JITC_PHASE1) != 0 && w.err != 0) { |
959 | - if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } | |
1077 | + if (label[i].opt == 0) { | |
1078 | + w.err = JITC_ERR_LABELNODEF; | |
1079 | + goto err_w; | |
1080 | + } | |
960 | 1081 | // if (label[i].typ != 1) { w.err = JITC_ERR_LABELTYP; goto err_w; } |
961 | 1082 | } |
962 | 1083 | j = 0; |
963 | - if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) | |
1084 | + if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)){ | |
964 | 1085 | j = label[i].p - (w.dst + 4); |
1086 | + } | |
965 | 1087 | jitCompPutImm32(w.dst, j); |
966 | 1088 | #if (jitCompA0001_OPTIMIZE_JMP != 0) |
967 | 1089 | if (-128 - 4 <= j && j < 0) { |
@@ -971,7 +1093,9 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
971 | 1093 | } |
972 | 1094 | #endif |
973 | 1095 | src += 6; |
974 | - if (w.err != 0) goto err_w; | |
1096 | + if (w.err != 0){ | |
1097 | + goto err_w; | |
1098 | + } | |
975 | 1099 | continue; |
976 | 1100 | } |
977 | 1101 | #endif |
@@ -980,8 +1104,9 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
980 | 1104 | jitCompPutByte3(w.dst, 0x0f, 0x90 | cmpcc_table0[*src - 0x20], 0xc0 | reg0); /* SETcc(BYTE(reg0)); */ |
981 | 1105 | jitCompPutByte3(w.dst, 0x0f, 0xb6, 0xc0 | reg0 << 3 | reg0); /* MOVZX(reg0, BYTE(reg0)); */ |
982 | 1106 | jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */ |
983 | - if (reg0 == 0) | |
1107 | + if (reg0 == 0){ | |
984 | 1108 | jitCompA0001_movRxxEax(&w, src[1]); |
1109 | + } | |
985 | 1110 | cmp0reg = src[2]; |
986 | 1111 | cmp0lev = 1; |
987 | 1112 | break; |
@@ -994,21 +1119,27 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
994 | 1119 | case 0x2d: /* PCMPG */ |
995 | 1120 | if (src[1] == 0x3f) { |
996 | 1121 | /* 特殊構文チェック */ |
997 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
1122 | + if (w.prefix != 0) { | |
1123 | + w.err = JITC_ERR_PREFIX; | |
1124 | + goto err_w; | |
1125 | + } | |
998 | 1126 | if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) { |
999 | - w.err = JITC_ERR_IDIOM; goto err_w; | |
1127 | + w.err = JITC_ERR_IDIOM; | |
1128 | + goto err_w; | |
1000 | 1129 | } |
1001 | 1130 | } |
1002 | - if (src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1131 | + if (src[2] >= 0x40) { | |
1132 | + w.err = JITC_ERR_PREGNUM; | |
1133 | + } | |
1003 | 1134 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
1004 | - if (src[3] != 0xff) | |
1135 | + if (src[3] != 0xff){ | |
1005 | 1136 | jitCompA0001_checkCompPtr(&w, src[2], src[3]); |
1006 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ | |
1137 | + } | |
1138 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + 0); /* MOV(EAX, [EBP+?]); */ | |
1007 | 1139 | if (src[3] != 0xff) { |
1008 | 1140 | jitCompPutByte1(w.dst, 0x3b); /* CMP(EAX, [EBP+?]); */ |
1009 | - jitCompPutModRM_Disp_BaseEBP(&w, 256 + src[3] * 32 + 0, 0); | |
1010 | - } | |
1011 | - else { | |
1141 | + jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[3]) + 0, 0); | |
1142 | + } else{ | |
1012 | 1143 | /* ヌルポインタとの比較はこれでいいのか?たぶんよくない */ |
1013 | 1144 | jitCompPutByte3(w.dst, 0x83, 0xf8, 0x00); /* CMP(EAX, 0); */ |
1014 | 1145 | } |
@@ -1051,13 +1182,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1051 | 1182 | |
1052 | 1183 | case 0x34: /* data (暫定) */ |
1053 | 1184 | cmp0reg = -1; |
1054 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
1185 | + if (w.prefix != 0) { | |
1186 | + w.err = JITC_ERR_PREFIX; | |
1187 | + goto err_w; | |
1188 | + } | |
1055 | 1189 | int k = jitCompGetImm32(&src[1]), tmpData, bitCount, dataWidth = jitCompA000_dataWidth(k); |
1056 | - if (lastlabel >= 0 && label[lastlabel].typ == 0) | |
1190 | + if (lastlabel >= 0 && label[lastlabel].typ == 0){ | |
1057 | 1191 | label[lastlabel].typ = k; |
1192 | + } | |
1058 | 1193 | if (k != 1) { |
1059 | 1194 | i = jitCompA000_convTyp(k); |
1060 | - if (i < 2 || i > 7) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
1195 | + if (i < 2 || i > 7) { | |
1196 | + w.err = JITC_ERR_BADTYPE; | |
1197 | + goto err_w; | |
1198 | + } | |
1061 | 1199 | } |
1062 | 1200 | j = jitCompGetImm32(&src[5]); |
1063 | 1201 | oldsrc = src; |
@@ -1065,8 +1203,16 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1065 | 1203 | if (k != 1) { |
1066 | 1204 | bitCount = 7; |
1067 | 1205 | while (j > 0) { |
1068 | - if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; } | |
1069 | - if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; } | |
1206 | + if (src >= src1) { | |
1207 | + w.err = JITC_ERR_SRC1; | |
1208 | + src = oldsrc; | |
1209 | + goto err_w; | |
1210 | + } | |
1211 | + if (w.dst + 256 > dst1) { | |
1212 | + w.err = JITC_ERR_DST1; | |
1213 | + src = oldsrc; | |
1214 | + goto err_w; | |
1215 | + } | |
1070 | 1216 | tmpData = 0; |
1071 | 1217 | for (k = 0; k < dataWidth; k++) { |
1072 | 1218 | tmpData = tmpData << 1 | ((*src >> bitCount) & 1); |
@@ -1079,34 +1225,51 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1079 | 1225 | if ((i & 1) == 0 && dataWidth <= 31 && (tmpData >> (dataWidth - 1)) != 0) { |
1080 | 1226 | tmpData -= 1 << dataWidth; |
1081 | 1227 | } |
1082 | - if (i == 2 || i == 3) { jitCompPutByte1(w.dst, tmpData & 0xff); } | |
1083 | - if (i == 4 || i == 5) { jitCompPutByte2(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff); } | |
1084 | - if (i == 6 || i == 7) { jitCompPutByte4(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff, (tmpData >> 16) & 0xff, (tmpData >> 24) & 0xff); } | |
1228 | + if (i == 2 || i == 3) { | |
1229 | + jitCompPutByte1(w.dst, tmpData & 0xff); | |
1230 | + } | |
1231 | + if (i == 4 || i == 5) { | |
1232 | + jitCompPutByte2(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff); | |
1233 | + } | |
1234 | + if (i == 6 || i == 7) { | |
1235 | + jitCompPutByte4(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff, (tmpData >> 16) & 0xff, (tmpData >> 24) & 0xff); | |
1236 | + } | |
1085 | 1237 | j--; |
1086 | 1238 | } |
1087 | - } | |
1088 | - else { | |
1239 | + } else{ | |
1089 | 1240 | while (j > 0) { |
1090 | - if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; } | |
1091 | - if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; } | |
1241 | + if (src >= src1) { | |
1242 | + w.err = JITC_ERR_SRC1; | |
1243 | + src = oldsrc; | |
1244 | + goto err_w; | |
1245 | + } | |
1246 | + if (w.dst + 256 > dst1) { | |
1247 | + w.err = JITC_ERR_DST1; | |
1248 | + src = oldsrc; | |
1249 | + goto err_w; | |
1250 | + } | |
1092 | 1251 | i = jitCompGetImm32(src); |
1093 | 1252 | src += 4; |
1094 | 1253 | if ((flags & JITC_PHASE1) != 0 && w.err == 0) { |
1095 | - if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } | |
1254 | + if (label[i].opt == 0) { | |
1255 | + w.err = JITC_ERR_LABELNODEF; | |
1256 | + goto err_w; | |
1257 | + } | |
1096 | 1258 | } |
1097 | 1259 | jitCompPutImm32(w.dst, (int)label[i].p); |
1098 | 1260 | jitCompPutImm32(w.dst, label[i].typ); |
1099 | 1261 | jitCompPutImm32(w.dst, (int)label[i].p); |
1100 | 1262 | jitCompPutImm32(w.dst, (int)label[i].p1); |
1101 | 1263 | jitCompPutImm32(w.dst, 0); /* liveSign */ |
1102 | - jitCompPutImm32(w.dst, 2320); /* pls */ | |
1264 | + jitCompPutImm32(w.dst, envOffset_PTRCTRL); /* pls */ | |
1103 | 1265 | jitCompPutImm32(w.dst, 0); |
1104 | 1266 | jitCompPutImm32(w.dst, 0); |
1105 | 1267 | j--; |
1106 | 1268 | } |
1107 | 1269 | } |
1108 | - if (lastlabel >= 0 && label[lastlabel].p1 < w.dst) | |
1270 | + if (lastlabel >= 0 && label[lastlabel].p1 < w.dst){ | |
1109 | 1271 | label[lastlabel].p1 = w.dst; |
1272 | + } | |
1110 | 1273 | continue; |
1111 | 1274 | |
1112 | 1275 | case 0x3c: /* ENTER */ |
@@ -1148,28 +1311,26 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1148 | 1311 | break; |
1149 | 1312 | |
1150 | 1313 | case 0xfe: /* remark */ |
1151 | - if (src[1] == 0x01 && src[2] == 0x00) { // DBGINFO1 | |
1314 | + if (src[1] == 0x01 && src[2] == 0x00) { | |
1315 | + // DBGINFO1 | |
1152 | 1316 | if (level <= JITC_LV_SLOWER) { |
1153 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1154 | - jitCompPutImm32(w.dst, debugInfo1); | |
1155 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 2304 + 4, IA32_REG0_EAX); /* MOV(debugInfo1, EAX); */ | |
1317 | + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1); | |
1318 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX); | |
1156 | 1319 | } |
1157 | 1320 | } |
1158 | - if (src[1] == 0x01 && src[2] == 0x03) { // DBGINFO1CLR | |
1321 | + if (src[1] == 0x01 && src[2] == 0x03) { | |
1322 | + // DBGINFO1CLR | |
1159 | 1323 | if (level <= JITC_LV_SLOWER) { |
1160 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1161 | - jitCompPutImm32(w.dst, -1); | |
1162 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 2304 + 4, IA32_REG0_EAX); /* MOV(debugInfo1, EAX); */ | |
1324 | + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, -1); | |
1325 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX); | |
1163 | 1326 | } |
1164 | 1327 | } |
1165 | - if (src[1] == 0x05 && src[2] == 0x00) { // DBGINFO0 | |
1328 | + if (src[1] == 0x05 && src[2] == 0x00) { | |
1329 | + // DBGINFO0 | |
1166 | 1330 | if (level <= JITC_LV_SLOWEST) { |
1167 | 1331 | debugInfo0 = jitCompGetImm32(src + 3); |
1168 | - // jitCompPutByte1(w.dst, 0xbf); /* MOV(EDI, ?); */ | |
1169 | - // jitCompPutImm32(&w, debugInfo0); | |
1170 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1171 | - jitCompPutImm32(w.dst, debugInfo0); | |
1172 | - jitCompPutOp_MOV_EBPDisp_GReg(&w, 2304 + 0, IA32_REG0_EAX); /* MOV(debugInfo0, EAX); */ | |
1332 | + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo0); | |
1333 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO0, IA32_REG0_EAX); | |
1173 | 1334 | } |
1174 | 1335 | } |
1175 | 1336 | break; |
@@ -1178,9 +1339,13 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1178 | 1339 | w.err = JITC_ERR_OPECODE; |
1179 | 1340 | goto err_w; |
1180 | 1341 | } |
1181 | - if (w.err != 0) goto err_w; | |
1342 | + if (w.err != 0){ | |
1343 | + goto err_w; | |
1344 | + } | |
1182 | 1345 | jitCompA0001_fixPrefix(&w); |
1183 | - if (w.err != 0) goto err_w; | |
1346 | + if (w.err != 0) { | |
1347 | + goto err_w; | |
1348 | + } | |
1184 | 1349 | src += jitCompCmdLen(src); |
1185 | 1350 | } |
1186 | 1351 | if (enter0 != NULL) { |
@@ -1193,16 +1358,18 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1193 | 1358 | if ((flags & JITC_NOSTARTUP) == 0) { |
1194 | 1359 | jitCompA000_storeRegCacheAll(&w); |
1195 | 1360 | jitCompA000_storePRegCacheAll(&w); |
1196 | - jitCompPutByte1(w.dst, 0x61); /* POPAD(); */ | |
1361 | + jitCompPutOp_POPAD(w.dst); | |
1197 | 1362 | } |
1198 | - if ((flags & JITC_PHASE1) != 0) | |
1363 | + if ((flags & JITC_PHASE1) != 0){ | |
1199 | 1364 | return w.dst - dst00; |
1365 | + } | |
1200 | 1366 | return 0; |
1201 | 1367 | |
1202 | 1368 | err_w: |
1203 | 1369 | if ((w.err & JITC_ERR_PHASE0ONLY) != 0) { |
1204 | - if ((flags & JITC_PHASE1) == 0) | |
1370 | + if ((flags & JITC_PHASE1) == 0){ | |
1205 | 1371 | w.err &= ~JITC_ERR_PHASE0ONLY; |
1372 | + } | |
1206 | 1373 | } |
1207 | 1374 | if (w.err == (JITC_ERR_MASK & JITC_ERR_REGNUM)) errmsg = "reg-number error"; |
1208 | 1375 | if (w.err == (JITC_ERR_MASK & JITC_ERR_DST1)) errmsg = "dst1 error"; |
@@ -1255,7 +1422,8 @@ unsigned char *jitCompCallFunc(unsigned char *dst, void *func) | ||
1255 | 1422 | jitCompPutOp_POPAD(w.dst); |
1256 | 1423 | jitCompA000_loadRegCacheAll(&w); |
1257 | 1424 | jitCompA000_loadPRegCacheAll(&w); |
1258 | - jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, 256 + 0x30 * 32 + 0); /* MOV(EAX, [EBP+?]); */ | |
1425 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(0x30) + 0); | |
1426 | + | |
1259 | 1427 | jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */ |
1260 | 1428 | return w.dst; |
1261 | 1429 | } |
@@ -1271,21 +1439,32 @@ void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int | ||
1271 | 1439 | HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128); |
1272 | 1440 | int i, *pi; |
1273 | 1441 | HOSECPU_PointerRegisterEntry *pp; |
1274 | - if (r->junkStack + 2048 > r->junkStack1) (*(r->errHndl))(r); | |
1275 | - pi = (void *)r->junkStack; r->junkStack += r1 * 4; | |
1276 | - for (i = 0; i < r1; i++) | |
1442 | + | |
1443 | + if (r->junkStack + 2048 > r->junkStack1) { | |
1444 | + (*(r->errHndl))(r); | |
1445 | + } | |
1446 | + pi = (void *)r->junkStack; | |
1447 | + r->junkStack += r1 * 4; | |
1448 | + for (i = 0; i < r1; i++){ | |
1277 | 1449 | pi[i] = r->ireg[i]; |
1278 | - pp = (void *)r->junkStack; r->junkStack += p1 * 32; | |
1279 | - for (i = 0; i < p1; i++) | |
1450 | + } | |
1451 | + pp = (void *)r->junkStack; | |
1452 | + r->junkStack += p1 * 32; | |
1453 | + for (i = 0; i < p1; i++){ | |
1280 | 1454 | pp[i] = r->preg[i]; |
1281 | - pp = (void *)r->junkStack; r->junkStack += 32; | |
1455 | + } | |
1456 | + pp = (void *)r->junkStack; | |
1457 | + r->junkStack += 32; | |
1282 | 1458 | *pp = r->preg[0x30]; |
1283 | - pi = (void *)r->junkStack; r->junkStack += 4; | |
1459 | + pi = (void *)r->junkStack; | |
1460 | + r->junkStack += 4; | |
1284 | 1461 | *pi = opt << 16 | r1 << 8 | p1; |
1285 | - for (i = 0; i < lenR; i++) | |
1462 | + for (i = 0; i < lenR; i++){ | |
1286 | 1463 | r->ireg[r0 + i] = r->ireg[0x30 + i]; |
1287 | - for (i = 0; i < lenP; i++) | |
1464 | + } | |
1465 | + for (i = 0; i < lenP; i++){ | |
1288 | 1466 | r->preg[p0 + i] = r->preg[0x31 + i]; |
1467 | + } | |
1289 | 1468 | return; |
1290 | 1469 | } |
1291 | 1470 |
@@ -1310,10 +1489,13 @@ void funcf4(char *ebp, int pxx, int typ, int len) | ||
1310 | 1489 | { |
1311 | 1490 | HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128); |
1312 | 1491 | int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3; |
1313 | - if (width < 0 || r->ireg[len] < 0) | |
1492 | + if (width < 0 || r->ireg[len] < 0){ | |
1314 | 1493 | (*(r->errHndl))(r); |
1494 | + } | |
1315 | 1495 | void *p = r->junkStack; |
1316 | - if (r->junkStack + width * r->ireg[len] + 256 > r->junkStack1) (*(r->errHndl))(r); | |
1496 | + if (r->junkStack + width * r->ireg[len] + 256 > r->junkStack1){ | |
1497 | + (*(r->errHndl))(r); | |
1498 | + } | |
1317 | 1499 | r->junkStack += width * r->ireg[len]; |
1318 | 1500 | r->preg[pxx].p = p; |
1319 | 1501 | r->preg[pxx].typ = r->ireg[typ]; |
@@ -1325,8 +1507,9 @@ void funcf4(char *ebp, int pxx, int typ, int len) | ||
1325 | 1507 | if (r->ireg[typ] == 1) { |
1326 | 1508 | int i, i1 = (width * r->ireg[len]) >> 2; |
1327 | 1509 | pi = p; |
1328 | - for (i = 0; i < i1; i++) | |
1510 | + for (i = 0; i < i1; i++){ | |
1329 | 1511 | pi[i] = 0; |
1512 | + } | |
1330 | 1513 | } |
1331 | 1514 | return; |
1332 | 1515 | } |
@@ -1350,8 +1533,9 @@ void funcf6(char *ebp, int pxx, int typ, int len) | ||
1350 | 1533 | { |
1351 | 1534 | HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128); |
1352 | 1535 | int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3; |
1353 | - if (width < 0 || r->ireg[len] < 0) | |
1536 | + if (width < 0 || r->ireg[len] < 0){ | |
1354 | 1537 | (*(r->errHndl))(r); |
1538 | + } | |
1355 | 1539 | void *p = malloc(width * r->ireg[len]); |
1356 | 1540 | r->preg[pxx].p = p; |
1357 | 1541 | r->preg[pxx].typ = r->ireg[typ]; |
@@ -1360,10 +1544,12 @@ void funcf6(char *ebp, int pxx, int typ, int len) | ||
1360 | 1544 | if (r->ireg[typ] == 1) { |
1361 | 1545 | int i, i1 = (width * r->ireg[len]) >> 2, *pi; |
1362 | 1546 | pi = p; |
1363 | - for (i = 0; i < i1; i++) | |
1547 | + for (i = 0; i < i1; i++){ | |
1364 | 1548 | pi[i] = 0; |
1365 | - for (i = 1; i < i1; i += 8) | |
1549 | + } | |
1550 | + for (i = 1; i < i1; i += 8){ | |
1366 | 1551 | pi[i] |= -1; |
1552 | + } | |
1367 | 1553 | } |
1368 | 1554 | return; |
1369 | 1555 | } |
@@ -1405,6 +1591,7 @@ int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const | ||
1405 | 1591 | } |
1406 | 1592 | |
1407 | 1593 | jitCompPutOp_PUSH_GReg(q, IA32_REG5_EBP); |
1594 | + | |
1408 | 1595 | *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */ |
1409 | 1596 | |
1410 | 1597 | for (i = 0; i < JITC_MAXLABELS; i++){ |
@@ -1436,35 +1623,51 @@ int dbgrGetRegNum(const char *p) | ||
1436 | 1623 | if (p[2] <= ' ') { |
1437 | 1624 | i = p[0] - '0'; |
1438 | 1625 | j = p[1] - '0'; |
1439 | - if (i > 9) i -= 'A' - '0' - 10; | |
1440 | - if (j > 9) j -= 'A' - '0' - 10; | |
1441 | - if (0 <= i && i <= 15 && 0 <= j && j <= 15) | |
1626 | + if (i > 9){ | |
1627 | + i -= 'A' - '0' - 10; | |
1628 | + } | |
1629 | + if (j > 9){ | |
1630 | + j -= 'A' - '0' - 10; | |
1631 | + } | |
1632 | + if (0 <= i && i <= 15 && 0 <= j && j <= 15){ | |
1442 | 1633 | r = i << 4 | j; |
1634 | + } | |
1443 | 1635 | } |
1444 | 1636 | return r; |
1445 | 1637 | } |
1446 | 1638 | |
1447 | 1639 | void dbgrMain(HOSECPU_RuntimeEnvironment *r) |
1448 | 1640 | { |
1449 | - if (r->dbgr == 0) return; | |
1641 | + if (r->dbgr == 0){ | |
1642 | + return; | |
1643 | + } | |
1450 | 1644 | for (;;) { |
1451 | 1645 | char cmd[64], *p; |
1452 | 1646 | int i, j, k; |
1647 | + | |
1453 | 1648 | printf("\ndbgr>"); |
1454 | 1649 | p = fgets(cmd, 64, stdin); |
1455 | - if (p == NULL) break; | |
1456 | - if (cmd[0] == '\0') continue; | |
1457 | - if (cmd[0] == 'q' && cmd[1] <= ' ') break; | |
1650 | + if (p == NULL){ | |
1651 | + break; | |
1652 | + } | |
1653 | + if (cmd[0] == '\0'){ | |
1654 | + continue; | |
1655 | + } | |
1656 | + if (cmd[0] == 'q' && cmd[1] <= ' '){ | |
1657 | + break; | |
1658 | + } | |
1458 | 1659 | if (cmd[0] == 'p' && cmd[1] <= ' ' && cmd[1] != '\0') { |
1459 | 1660 | p = &cmd[2]; |
1460 | - while (*p <= ' ' && *p != '\0') p++; | |
1661 | + while (*p <= ' ' && *p != '\0'){ | |
1662 | + p++; | |
1663 | + } | |
1461 | 1664 | if (*p == 'R') { |
1462 | 1665 | i = dbgrGetRegNum(p + 1); |
1463 | 1666 | if (0 <= i && i <= 0x3f) { |
1464 | 1667 | printf("R%02X = 0x%08X = %d\n", i, r->ireg[i], r->ireg[i]); |
1465 | - } | |
1466 | - else | |
1668 | + } else{ | |
1467 | 1669 | puts("register name error"); |
1670 | + } | |
1468 | 1671 | continue; |
1469 | 1672 | } |
1470 | 1673 | if (*p == 'P') { |
@@ -1485,7 +1688,9 @@ void dbgrMain(HOSECPU_RuntimeEnvironment *r) | ||
1485 | 1688 | printf("P%02X:\n type = %s(%04X), (origin-ptr) = 0x%08X\n", i, p, r->preg[i].typ, (unsigned int)(r->preg[i].p0)); |
1486 | 1689 | if (r->preg[i].p != NULL && r->preg[i].p0 != NULL) { |
1487 | 1690 | j = jitCompA000_dataWidth(jitCompA000_convTyp(r->preg[i].typ)) >> 3; |
1488 | - if (j <= 0) j = 1; | |
1691 | + if (j <= 0){ | |
1692 | + j = 1; | |
1693 | + } | |
1489 | 1694 | k = (r->preg[i].p1 - r->preg[i].p0) / j; |
1490 | 1695 | printf(" size = 0x%08X = %d\n", k, k); |
1491 | 1696 | k = (r->preg[i].p - r->preg[i].p0) / j; |
@@ -166,17 +166,15 @@ int jitCompA000_selectRegCache(int rxx, int reg) | ||
166 | 166 | |
167 | 167 | void jitCompA000_loadPRegCacheAll(struct JitCompWork *w) |
168 | 168 | { |
169 | - // jitCompPutOp_MOV_GReg_EBPDisp(w, 5 /* EBP */, 256 + 0 * 32 + 0); /* EBP = P00; */ | |
170 | - jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG6_ESI, 256 + 1 * 32 + 0); /* ESI = P01; */ | |
171 | - jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG7_EDI, 256 + 2 * 32 + 0); /* EDI = P02; */ | |
169 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG6_ESI, PRegOffset(0x01) + 0); /* ESI = P01; */ | |
170 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG7_EDI, PRegOffset(0x02) + 0); /* EDI = P02; */ | |
172 | 171 | return; |
173 | 172 | } |
174 | 173 | |
175 | 174 | void jitCompA000_storePRegCacheAll(struct JitCompWork *w) |
176 | 175 | { |
177 | - // jitCompPutOp_MOV_EBPDisp_GReg(w, 256 + 0 * 32 + 0, 5 /* EBP */); /* P00 = EBP; */ | |
178 | - jitCompPutOp_MOV_EBPDisp_GReg(w, 256 + 1 * 32 + 0, IA32_REG6_ESI); /* P01 = ESI; */ | |
179 | - jitCompPutOp_MOV_EBPDisp_GReg(w, 256 + 2 * 32 + 0, IA32_REG7_EDI); /* P02 = EDI; */ | |
176 | + jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x01) + 0, IA32_REG6_ESI); /* P01 = ESI; */ | |
177 | + jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x02) + 0, IA32_REG7_EDI); /* P02 = EDI; */ | |
180 | 178 | return; |
181 | 179 | } |
182 | 180 |
@@ -237,7 +235,7 @@ void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac) | ||
237 | 235 | { |
238 | 236 | if (typ <= 0) { w->err = JITC_ERR_BADTYPE; } |
239 | 237 | if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; } |
240 | - jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, 256 + pxx * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ | |
238 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, PRegOffset(pxx) + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ | |
241 | 239 | jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */ |
242 | 240 | jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */ |
243 | 241 | jitCompPutImm32(w->dst, errfnc - (w->dst + 4)); |
@@ -255,11 +253,11 @@ void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac) | ||
255 | 253 | void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx) |
256 | 254 | { |
257 | 255 | jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ |
258 | - jitCompPutModRM_Disp_BaseEBP(w, 256 + pxx * 32 + 8, reg); /* p0 */ | |
256 | + jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 8, reg); /* p0 */ | |
259 | 257 | jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */ |
260 | 258 | jitCompPutImm32(w->dst, errfnc - (w->dst + 4)); |
261 | 259 | jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ |
262 | - jitCompPutModRM_Disp_BaseEBP(w, 256 + pxx * 32 + 12, reg); /* p1 */ | |
260 | + jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 12, reg); /* p1 */ | |
263 | 261 | jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */ |
264 | 262 | jitCompPutImm32(w->dst, errfnc - (w->dst + 4)); |
265 | 263 | return; |
@@ -1,343 +1,343 @@ | ||
1 | -#include "osecpu.h" | |
2 | - | |
3 | -int *keybuf, keybuf_r, keybuf_w, keybuf_c; | |
4 | -HOSECPU_Device_Window mainWindow; | |
5 | -//デバッグ用。プログラム中の随所で加算される変数 | |
6 | -int di1_serial; | |
7 | - | |
8 | - | |
9 | - | |
10 | -unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory); | |
11 | -void LoadAppBin(HOSECPU_RuntimeEnvironment *env); | |
12 | - | |
13 | -void putKeybuf(int i) | |
14 | -{ | |
15 | - if (keybuf_c < KEYBUFSIZ) { | |
16 | - keybuf[keybuf_w] = i; | |
17 | - keybuf_c++; | |
18 | - keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1); | |
19 | - } | |
20 | - return; | |
21 | -} | |
22 | - | |
23 | -int HeavyOSECPUMain(int argc, char **argv) | |
24 | -{ | |
25 | - FILE *fp; | |
26 | - unsigned char *jitbuf, *sysjit00, *sysjit; | |
27 | - unsigned char *systmp0, *systmp1, *systmp2; | |
28 | - unsigned char *opTbl; | |
29 | - HOSECPU_LabelListTag *label; | |
30 | - int tmpsiz, i; | |
31 | - double tm0, tm1, tm2; | |
32 | - HOSECPU_PointerControlTag *ptrCtrl; | |
33 | - unsigned char *syslib; | |
34 | - int argDebug = 0, stacksiz = 1; | |
35 | - const char *cp; | |
36 | - HOSECPU_RuntimeEnvironment env; | |
37 | - void(*jitfunc)(char *); | |
38 | - unsigned char *jp; | |
39 | - | |
40 | - //Initialize mainWindow | |
41 | - mainWindow.vram = NULL; | |
42 | - mainWindow.xsize = 0; | |
43 | - mainWindow.ysize = 0; | |
44 | - di1_serial = 0; | |
45 | - | |
46 | - //実行環境初期化 | |
47 | - env.mainArgc = argc; | |
48 | - env.mainArgv = (const char **)argv; | |
49 | - env.appBin = malloc(APPSIZ1); | |
50 | - env.executionLevel = JITC_LV_SLOWEST; | |
51 | - jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */ | |
52 | - //unsigned char *sysjit0 = mallocRWE(SJITSIZ1), *sysjit1 = sysjit0, *sysjit00 = sysjit0; | |
53 | - // syslib.oseのjitc結果を格納する領域を確保。 | |
54 | - sysjit00 = mallocRWE(SJITSIZ1); | |
55 | - sysjit = sysjit00; | |
56 | - // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス | |
57 | - // sysjit: 現在のjitc書き込み位置 | |
58 | - // sysjit00: jitc結果の先頭 | |
59 | - //ワークメモリを三つくらいもらう | |
60 | - systmp0 = malloc(SYSTMP0SIZ); /* syslibのjitc用 */ | |
61 | - systmp1 = malloc(SYSTMP1SIZ); | |
62 | - systmp2 = malloc(1024 * 1024); | |
63 | - | |
64 | - opTbl = malloc(256); | |
65 | - label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag)); | |
66 | - keybuf = malloc(KEYBUFSIZ * sizeof (int)); | |
67 | - keybuf_r = keybuf_w = keybuf_c = 0; | |
68 | - ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag)); | |
69 | - | |
70 | - randStatInit((unsigned int)time(NULL)); | |
71 | - for (i = 0; i < PTRCTRLSIZ; i++) { | |
72 | - ptrCtrl[i].liveSign = 0; | |
73 | - ptrCtrl[i].size = -1; | |
74 | - } | |
75 | - ptrCtrl[0].size = -2; | |
76 | - | |
77 | - /* syslibの読み込み */ | |
78 | - syslib = Init_LoadSysLib(argv[0], systmp0); | |
79 | - | |
80 | - sysjit = jitCompInit(sysjit); | |
81 | - sysjit00 = sysjit; | |
82 | - // labelはjitc0()内で初期化される。 | |
83 | - i = jitc0(&sysjit, sysjit00 + SJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label); | |
84 | - if (i != 0){ | |
85 | - fputs("syslib-file JITC error.\n", stderr); | |
86 | - return 1; | |
87 | - } | |
88 | - | |
89 | - // エラー時にデバッグ用に表示する変数を加算 | |
90 | - di1_serial++; | |
91 | - | |
92 | - /* アプリバイナリの読み込み */ | |
93 | - LoadAppBin(&env); | |
94 | - | |
95 | - /* クロック初期化 */ | |
96 | - tm0 = clock() / (double)CLOCKS_PER_SEC; | |
97 | - | |
98 | - if (env.appBin[2] == 0xf0) { | |
99 | - // tek5圧縮がかかっている | |
100 | -#if (USE_TEK5 != 0) | |
101 | - env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0); | |
102 | - env.appSize1 += 2; | |
103 | -#else | |
104 | - env.appSize1 = -9; | |
105 | -#endif | |
106 | - if (env.appSize1 < 0) { | |
107 | - fputs("unsupported-format(tek5)\n", stderr); | |
108 | - return 1; | |
109 | - } | |
110 | - } | |
111 | - //デバッグモード指定 | |
112 | - cp = searchArg(argc, (const char **)argv, "debug:", 0); | |
113 | - if (cp != NULL){ | |
114 | - argDebug = *cp - '0'; | |
115 | - } | |
116 | - //スタックサイズ指定(MiB単位) | |
117 | - cp = searchArg(argc, (const char **)argv, "stack:", 0); | |
118 | - if (cp != NULL){ | |
119 | - stacksiz = strtol(cp, NULL, 0); | |
120 | - } | |
121 | - | |
122 | - // jitbufは先頭。 jpは現在位置 | |
123 | - jp = jitbuf; /* JIT-pointer */ | |
124 | - | |
125 | - /* フロントエンドコードをバックエンドコードに変換する */ | |
126 | - if ((env.appBin[2] & 0xf0) != 0) { // 3バイト目が00なら処理しない | |
127 | - systmp0[0] = env.appBin[0]; | |
128 | - systmp0[1] = env.appBin[1]; | |
129 | - env.preg[2].p = systmp0 + 2; | |
130 | - env.preg[3].p = systmp0 + SYSTMP0SIZ; | |
131 | - env.preg[4].p = env.appBin + 2; | |
132 | - env.preg[5].p = env.appBin + env.appSize1; | |
133 | - env.preg[6].p = systmp1; | |
134 | - env.preg[7].p = systmp1 + SYSTMP1SIZ; | |
135 | - env.preg[10].p = systmp2; | |
136 | - int pxxFlag[64], typLabel[4096]; | |
137 | - env.preg[0x0b].p = (void *)pxxFlag; | |
138 | - env.preg[0x0c].p = (void *)typLabel; | |
139 | - env.preg[0x0d].p = opTbl; | |
140 | - jitfunc = (void *)sysjit00; | |
141 | - (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ | |
142 | - if (env.ireg[0] != 0) { | |
143 | - jp = env.preg[2].p - 1; | |
144 | - fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]); | |
145 | - if ((argDebug & 2) != 0) { | |
146 | - fp = fopen("debug2.bin", "wb"); | |
147 | - fwrite(systmp0, 1, jp - systmp0 + 16, fp); | |
148 | - fclose(fp); | |
149 | - } | |
150 | - exit(1); | |
151 | - } | |
152 | - tmpsiz = env.preg[2].p - systmp0; | |
153 | - } else{ | |
154 | - memcpy(systmp0, env.appBin, env.appSize1); | |
155 | - tmpsiz = env.appSize1; | |
156 | - } | |
157 | - | |
158 | - if ((argDebug & 2) != 0) { | |
159 | - /*変換後のバックエンドコードをファイルへ保存*/ | |
160 | - fp = fopen("debug2.bin", "wb"); | |
161 | - fwrite(systmp0, 1, tmpsiz, fp); | |
162 | - fclose(fp); | |
163 | - } | |
164 | - | |
165 | - //JITコンパイル | |
166 | - i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label); | |
167 | - if (i == 1){ | |
168 | - fputs("app-file header error.\n", stderr); | |
169 | - return 1; | |
170 | - } | |
171 | - if (i != 0){ | |
172 | - return 1; | |
173 | - } | |
174 | - di1_serial++; | |
175 | - | |
176 | - int appsiz2 = jp - jitbuf; | |
177 | - | |
178 | - unsigned char *p28 = jp; | |
179 | - jp = jitCompCallFunc(jp, &devFunc); | |
180 | - | |
181 | - tm1 = clock() / (double)CLOCKS_PER_SEC; | |
182 | - | |
183 | - /* レジスタ初期化 */ | |
184 | - for (i = 0; i < 64; i++){ | |
185 | - env.ireg[i] = 0; | |
186 | - } | |
187 | - for (i = 0; i < 64; i++) { | |
188 | - env.preg[i].p = NULL; | |
189 | - env.preg[i].typ = -1; | |
190 | - env.preg[i].p0 = NULL; | |
191 | - env.preg[i].p1 = NULL; | |
192 | - } | |
193 | - | |
194 | - env.buf0 = env.buf1 = NULL; | |
195 | - | |
196 | - // p28にapiをコールするアドレスを設定 | |
197 | - env.preg[0x28].p = p28; // p28には、devFuncをコールするコードが書かれている | |
198 | - env.preg[0x28].typ = 0; // TYP_CODE | |
199 | - env.preg[0x28].p0 = p28; // アドレス演算できる範囲を制限 | |
200 | - env.preg[0x28].p1 = p28 + 1; // アドレス演算できる範囲を制限 | |
201 | - | |
202 | - //env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32); | |
203 | - env.junkStack = malloc(stacksiz << 20); | |
204 | - env.junkStack1 = env.junkStack + (stacksiz << 20); | |
205 | - env.winClosed = 0; | |
206 | - env.autoSleep = 0; | |
207 | - env.lastConsoleChar = '\n'; | |
208 | - | |
209 | - env.label = label; | |
210 | - env.maxLabels = JITC_MAXLABELS; | |
211 | - env.jitbuf = jp; | |
212 | - env.jitbuf1 = jitbuf + 1024 * 1024; | |
213 | - env.errHndl = &errorHandler; | |
214 | - env.appReturnCode = 0; | |
215 | - | |
216 | - env.dbgr = 0; | |
217 | - if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){ | |
218 | - env.dbgr = 1; | |
219 | - } | |
220 | - | |
221 | - if ((argDebug & 1) != 0) { | |
222 | - fp = fopen("debug1.bin", "wb"); | |
223 | - fwrite(jitbuf, 1, jp - jitbuf, fp); | |
224 | - fclose(fp); | |
225 | - } | |
226 | - | |
227 | - /* JITコード実行 */ | |
228 | - jitfunc = (void *)jitbuf; | |
229 | - if (setjmp(env.setjmpEnv) == 0){ | |
230 | - (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ | |
231 | - } | |
232 | - if (env.autoSleep != 0) { | |
233 | - if (mainWindow.vram != NULL){ | |
234 | - drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0); | |
235 | - } | |
236 | - while (env.winClosed == 0){ | |
237 | - drv_sleep(100); | |
238 | - } | |
239 | - } | |
240 | - if (env.lastConsoleChar != '\n'){ | |
241 | - putchar('\n'); | |
242 | - } | |
243 | - | |
244 | - tm2 = clock() / (double)CLOCKS_PER_SEC; | |
245 | - | |
246 | - /* 実行結果確認のためのレジスタダンプ */ | |
247 | - if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) { | |
248 | - printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1); | |
249 | - printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2); | |
250 | - printf("result:\n"); | |
251 | - printf("R00:0x%08X R01:0x%08X R02:0x%08X R03:0x%08X\n", env.ireg[0], env.ireg[1], env.ireg[2], env.ireg[3]); | |
252 | - } | |
253 | -#if (USE_DEBUGGER != 0) | |
254 | - dbgrMain(&env); | |
255 | -#endif | |
256 | - return env.appReturnCode; | |
257 | -} | |
258 | - | |
259 | -unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory) | |
260 | -{ | |
261 | - unsigned char *syslib; | |
262 | - FILE *fp; | |
263 | - unsigned char *up; | |
264 | - int appsize; | |
265 | - | |
266 | - /* syslibの読み込み */ | |
267 | - syslib = malloc(SYSLIBSIZ1); | |
268 | - fp = fopen(SYSLIB_OSE, "rb"); | |
269 | - if (fp == NULL) { | |
270 | - syslib[0] = '/'; | |
271 | - strcpy((char *)syslib + 1, argv0); | |
272 | - up = syslib + 1; | |
273 | - while (*up != '\0'){ | |
274 | - up++; | |
275 | - } | |
276 | - while (*up != '/' && *up != 0x5c){ | |
277 | - up--; | |
278 | - } | |
279 | - up++; | |
280 | - strcpy((char *)up, SYSLIB_OSE); | |
281 | - fp = fopen((char *)syslib + 1, "rb"); | |
282 | - } | |
283 | - if (fp == NULL) { | |
284 | - fputs("syslib-file fopen error.\n", stderr); | |
285 | - exit(EXIT_FAILURE); | |
286 | - } | |
287 | - appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp); | |
288 | - fclose(fp); | |
289 | - if (appsize >= SYSLIBSIZ1 - 4) { | |
290 | - fputs("syslib-file too large.\n", stderr); | |
291 | - exit(EXIT_FAILURE); | |
292 | - } | |
293 | - if (syslib[0] == 0x05 && syslib[1] == 0xc1) { | |
294 | - // maklib のライブラリ形式である。 | |
295 | - memcpy(tmpWorkMemory, syslib, appsize); | |
296 | - ComLib_main(tmpWorkMemory + 2, syslib + 2); | |
297 | - syslib[0] = 0x05; | |
298 | - syslib[1] = 0x1b; | |
299 | - } | |
300 | - | |
301 | - fp = fopen("syslib_dbg.ose", "wb"); | |
302 | - fwrite(syslib, 1, SYSLIBSIZ1, fp); | |
303 | - fclose(fp); | |
304 | - return syslib; | |
305 | -} | |
306 | - | |
307 | -void LoadAppBin(HOSECPU_RuntimeEnvironment *env) | |
308 | -{ | |
309 | - FILE *fp; | |
310 | - const char *fileName; | |
311 | - /* アプリバイナリの読み込み */ | |
312 | - if (env->mainArgc <= 1) { | |
313 | - //アプリ名未指定なので何事もなく終了 | |
314 | - exit(EXIT_SUCCESS); | |
315 | - } | |
316 | - fileName = env->mainArgv[1]; | |
317 | - //アプリ名先頭に:n:をつけることでレベルnでの実行が可能? | |
318 | - if (fileName[0] == ':' && fileName[2] == ':') { | |
319 | - env->executionLevel = fileName[1] - '0'; | |
320 | - if (env->executionLevel < 0 || env->executionLevel > 9){ | |
321 | - env->executionLevel = JITC_LV_SLOWEST; | |
322 | - } | |
323 | - fileName += 3; | |
324 | - } | |
325 | - | |
326 | - fp = fopen(fileName, "rb"); | |
327 | - if (fp == NULL) { | |
328 | - fputs("app-file load error.\n", stderr); | |
329 | - exit(EXIT_FAILURE); | |
330 | - } | |
331 | - env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp); | |
332 | - env->appSize1 = env->appSize0; | |
333 | - fclose(fp); | |
334 | - | |
335 | - if (env->appSize0 >= APPSIZ1 - 4) { | |
336 | - fputs("app-file too large.\n", stderr); | |
337 | - exit(EXIT_FAILURE); | |
338 | - } | |
339 | - if (env->appSize0 < 3) { | |
340 | - fputs("app-file header error.\n", stderr); | |
341 | - exit(EXIT_FAILURE); | |
342 | - } | |
343 | -} | |
1 | +#include "osecpu.h" | |
2 | + | |
3 | +int *keybuf, keybuf_r, keybuf_w, keybuf_c; | |
4 | +HOSECPU_Device_Window mainWindow; | |
5 | +//デバッグ用。プログラム中の随所で加算される変数 | |
6 | +int di1_serial; | |
7 | + | |
8 | + | |
9 | + | |
10 | +unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory); | |
11 | +void LoadAppBin(HOSECPU_RuntimeEnvironment *env); | |
12 | + | |
13 | +void putKeybuf(int i) | |
14 | +{ | |
15 | + if (keybuf_c < KEYBUFSIZ) { | |
16 | + keybuf[keybuf_w] = i; | |
17 | + keybuf_c++; | |
18 | + keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1); | |
19 | + } | |
20 | + return; | |
21 | +} | |
22 | + | |
23 | +int HeavyOSECPUMain(int argc, char **argv) | |
24 | +{ | |
25 | + FILE *fp; | |
26 | + unsigned char *jitbuf, *sysjit00, *sysjit; | |
27 | + unsigned char *systmp0, *systmp1, *systmp2; | |
28 | + unsigned char *opTbl; | |
29 | + HOSECPU_LabelListTag *label; | |
30 | + int tmpsiz, i; | |
31 | + double tm0, tm1, tm2; | |
32 | + HOSECPU_PointerControlTag *ptrCtrl; | |
33 | + unsigned char *syslib; | |
34 | + int argDebug = 0, stacksiz = 1; | |
35 | + const char *cp; | |
36 | + HOSECPU_RuntimeEnvironment env; | |
37 | + void(*jitfunc)(char *); | |
38 | + unsigned char *jp; | |
39 | + | |
40 | + //Initialize mainWindow | |
41 | + mainWindow.vram = NULL; | |
42 | + mainWindow.xsize = 0; | |
43 | + mainWindow.ysize = 0; | |
44 | + di1_serial = 0; | |
45 | + | |
46 | + //実行環境初期化 | |
47 | + env.mainArgc = argc; | |
48 | + env.mainArgv = (const char **)argv; | |
49 | + env.appBin = malloc(APPSIZ1); | |
50 | + env.executionLevel = JITC_LV_SLOWEST; | |
51 | + jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */ | |
52 | + //unsigned char *sysjit0 = mallocRWE(SJITSIZ1), *sysjit1 = sysjit0, *sysjit00 = sysjit0; | |
53 | + // syslib.oseのjitc結果を格納する領域を確保。 | |
54 | + sysjit00 = mallocRWE(SJITSIZ1); | |
55 | + sysjit = sysjit00; | |
56 | + // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス | |
57 | + // sysjit: 現在のjitc書き込み位置 | |
58 | + // sysjit00: jitc結果の先頭 | |
59 | + //ワークメモリを三つくらいもらう | |
60 | + systmp0 = malloc(SYSTMP0SIZ); /* syslibのjitc用 */ | |
61 | + systmp1 = malloc(SYSTMP1SIZ); | |
62 | + systmp2 = malloc(1024 * 1024); | |
63 | + | |
64 | + opTbl = malloc(256); | |
65 | + label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag)); | |
66 | + keybuf = malloc(KEYBUFSIZ * sizeof (int)); | |
67 | + keybuf_r = keybuf_w = keybuf_c = 0; | |
68 | + ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag)); | |
69 | + | |
70 | + randStatInit((unsigned int)time(NULL)); | |
71 | + for (i = 0; i < PTRCTRLSIZ; i++) { | |
72 | + ptrCtrl[i].liveSign = 0; | |
73 | + ptrCtrl[i].size = -1; | |
74 | + } | |
75 | + ptrCtrl[0].size = -2; | |
76 | + | |
77 | + /* syslibの読み込み */ | |
78 | + syslib = Init_LoadSysLib(argv[0], systmp0); | |
79 | + | |
80 | + sysjit = jitCompInit(sysjit); | |
81 | + sysjit00 = sysjit; | |
82 | + // labelはjitc0()内で初期化される。 | |
83 | + i = jitc0(&sysjit, sysjit00 + SJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label); | |
84 | + if (i != 0){ | |
85 | + fputs("syslib-file JITC error.\n", stderr); | |
86 | + return 1; | |
87 | + } | |
88 | + | |
89 | + // エラー時にデバッグ用に表示する変数を加算 | |
90 | + di1_serial++; | |
91 | + | |
92 | + /* アプリバイナリの読み込み */ | |
93 | + LoadAppBin(&env); | |
94 | + | |
95 | + /* クロック初期化 */ | |
96 | + tm0 = clock() / (double)CLOCKS_PER_SEC; | |
97 | + | |
98 | + if (env.appBin[2] == 0xf0) { | |
99 | + // tek5圧縮がかかっている | |
100 | +#if (USE_TEK5 != 0) | |
101 | + env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0); | |
102 | + env.appSize1 += 2; | |
103 | +#else | |
104 | + env.appSize1 = -9; | |
105 | +#endif | |
106 | + if (env.appSize1 < 0) { | |
107 | + fputs("unsupported-format(tek5)\n", stderr); | |
108 | + return 1; | |
109 | + } | |
110 | + } | |
111 | + //デバッグモード指定 | |
112 | + cp = searchArg(argc, (const char **)argv, "debug:", 0); | |
113 | + if (cp != NULL){ | |
114 | + argDebug = *cp - '0'; | |
115 | + } | |
116 | + //スタックサイズ指定(MiB単位) | |
117 | + cp = searchArg(argc, (const char **)argv, "stack:", 0); | |
118 | + if (cp != NULL){ | |
119 | + stacksiz = strtol(cp, NULL, 0); | |
120 | + } | |
121 | + | |
122 | + // jitbufは先頭。 jpは現在位置 | |
123 | + jp = jitbuf; /* JIT-pointer */ | |
124 | + | |
125 | + /* フロントエンドコードをバックエンドコードに変換する */ | |
126 | + if ((env.appBin[2] & 0xf0) != 0) { // 3バイト目が00なら処理しない | |
127 | + systmp0[0] = env.appBin[0]; | |
128 | + systmp0[1] = env.appBin[1]; | |
129 | + env.preg[2].p = systmp0 + 2; | |
130 | + env.preg[3].p = systmp0 + SYSTMP0SIZ; | |
131 | + env.preg[4].p = env.appBin + 2; | |
132 | + env.preg[5].p = env.appBin + env.appSize1; | |
133 | + env.preg[6].p = systmp1; | |
134 | + env.preg[7].p = systmp1 + SYSTMP1SIZ; | |
135 | + env.preg[10].p = systmp2; | |
136 | + int pxxFlag[64], typLabel[4096]; | |
137 | + env.preg[0x0b].p = (void *)pxxFlag; | |
138 | + env.preg[0x0c].p = (void *)typLabel; | |
139 | + env.preg[0x0d].p = opTbl; | |
140 | + jitfunc = (void *)sysjit00; | |
141 | + (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ | |
142 | + if (env.ireg[0] != 0) { | |
143 | + jp = env.preg[2].p - 1; | |
144 | + fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]); | |
145 | + if ((argDebug & 2) != 0) { | |
146 | + fp = fopen("debug2.bin", "wb"); | |
147 | + fwrite(systmp0, 1, jp - systmp0 + 16, fp); | |
148 | + fclose(fp); | |
149 | + } | |
150 | + exit(1); | |
151 | + } | |
152 | + tmpsiz = env.preg[2].p - systmp0; | |
153 | + } else{ | |
154 | + memcpy(systmp0, env.appBin, env.appSize1); | |
155 | + tmpsiz = env.appSize1; | |
156 | + } | |
157 | + | |
158 | + if ((argDebug & 2) != 0) { | |
159 | + /*変換後のバックエンドコードをファイルへ保存*/ | |
160 | + fp = fopen("debug2.bin", "wb"); | |
161 | + fwrite(systmp0, 1, tmpsiz, fp); | |
162 | + fclose(fp); | |
163 | + } | |
164 | + | |
165 | + //JITコンパイル | |
166 | + i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label); | |
167 | + if (i == 1){ | |
168 | + fputs("app-file header error.\n", stderr); | |
169 | + return 1; | |
170 | + } | |
171 | + if (i != 0){ | |
172 | + return 1; | |
173 | + } | |
174 | + di1_serial++; | |
175 | + | |
176 | + int appsiz2 = jp - jitbuf; | |
177 | + | |
178 | + unsigned char *p28 = jp; | |
179 | + jp = jitCompCallFunc(jp, &devFunc); | |
180 | + | |
181 | + tm1 = clock() / (double)CLOCKS_PER_SEC; | |
182 | + | |
183 | + /* レジスタ初期化 */ | |
184 | + for (i = 0; i < 64; i++){ | |
185 | + env.ireg[i] = 0; | |
186 | + } | |
187 | + for (i = 0; i < 64; i++) { | |
188 | + env.preg[i].p = NULL; | |
189 | + env.preg[i].typ = -1; | |
190 | + env.preg[i].p0 = NULL; | |
191 | + env.preg[i].p1 = NULL; | |
192 | + } | |
193 | + | |
194 | + env.buf0 = env.buf1 = NULL; | |
195 | + | |
196 | + // p28にapiをコールするアドレスを設定 | |
197 | + env.preg[0x28].p = p28; // p28には、devFuncをコールするコードが書かれている | |
198 | + env.preg[0x28].typ = 0; // TYP_CODE | |
199 | + env.preg[0x28].p0 = p28; // アドレス演算できる範囲を制限 | |
200 | + env.preg[0x28].p1 = p28 + 1; // アドレス演算できる範囲を制限 | |
201 | + | |
202 | + //env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32); | |
203 | + env.junkStack = malloc(stacksiz << 20); | |
204 | + env.junkStack1 = env.junkStack + (stacksiz << 20); | |
205 | + env.winClosed = 0; | |
206 | + env.autoSleep = 0; | |
207 | + env.lastConsoleChar = '\n'; | |
208 | + | |
209 | + env.label = label; | |
210 | + env.maxLabels = JITC_MAXLABELS; | |
211 | + env.jitbuf = jp; | |
212 | + env.jitbuf1 = jitbuf + 1024 * 1024; | |
213 | + env.errHndl = &errorHandler; | |
214 | + env.appReturnCode = 0; | |
215 | + | |
216 | + env.dbgr = 0; | |
217 | + if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){ | |
218 | + env.dbgr = 1; | |
219 | + } | |
220 | + | |
221 | + if ((argDebug & 1) != 0) { | |
222 | + fp = fopen("debug1.bin", "wb"); | |
223 | + fwrite(jitbuf, 1, jp - jitbuf, fp); | |
224 | + fclose(fp); | |
225 | + } | |
226 | + | |
227 | + /* JITコード実行 */ | |
228 | + jitfunc = (void *)jitbuf; | |
229 | + if (setjmp(env.setjmpEnv) == 0){ | |
230 | + (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ | |
231 | + } | |
232 | + if (env.autoSleep != 0) { | |
233 | + if (mainWindow.vram != NULL){ | |
234 | + drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0); | |
235 | + } | |
236 | + while (env.winClosed == 0){ | |
237 | + drv_sleep(100); | |
238 | + } | |
239 | + } | |
240 | + if (env.lastConsoleChar != '\n'){ | |
241 | + putchar('\n'); | |
242 | + } | |
243 | + | |
244 | + tm2 = clock() / (double)CLOCKS_PER_SEC; | |
245 | + | |
246 | + /* 実行結果確認のためのレジスタダンプ */ | |
247 | + if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) { | |
248 | + printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1); | |
249 | + printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2); | |
250 | + printf("result:\n"); | |
251 | + printf("R00:0x%08X R01:0x%08X R02:0x%08X R03:0x%08X\n", env.ireg[0], env.ireg[1], env.ireg[2], env.ireg[3]); | |
252 | + } | |
253 | +#if (USE_DEBUGGER != 0) | |
254 | + dbgrMain(&env); | |
255 | +#endif | |
256 | + return env.appReturnCode; | |
257 | +} | |
258 | + | |
259 | +unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory) | |
260 | +{ | |
261 | + unsigned char *syslib; | |
262 | + FILE *fp; | |
263 | + unsigned char *up; | |
264 | + int appsize; | |
265 | + | |
266 | + /* syslibの読み込み */ | |
267 | + syslib = malloc(SYSLIBSIZ1); | |
268 | + fp = fopen(SYSLIB_OSE, "rb"); | |
269 | + if (fp == NULL) { | |
270 | + syslib[0] = '/'; | |
271 | + strcpy((char *)syslib + 1, argv0); | |
272 | + up = syslib + 1; | |
273 | + while (*up != '\0'){ | |
274 | + up++; | |
275 | + } | |
276 | + while (*up != '/' && *up != 0x5c){ | |
277 | + up--; | |
278 | + } | |
279 | + up++; | |
280 | + strcpy((char *)up, SYSLIB_OSE); | |
281 | + fp = fopen((char *)syslib + 1, "rb"); | |
282 | + } | |
283 | + if (fp == NULL) { | |
284 | + fputs("syslib-file fopen error.\n", stderr); | |
285 | + exit(EXIT_FAILURE); | |
286 | + } | |
287 | + appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp); | |
288 | + fclose(fp); | |
289 | + if (appsize >= SYSLIBSIZ1 - 4) { | |
290 | + fputs("syslib-file too large.\n", stderr); | |
291 | + exit(EXIT_FAILURE); | |
292 | + } | |
293 | + if (syslib[0] == 0x05 && syslib[1] == 0xc1) { | |
294 | + // maklib のライブラリ形式である。 | |
295 | + memcpy(tmpWorkMemory, syslib, appsize); | |
296 | + ComLib_main(tmpWorkMemory + 2, syslib + 2); | |
297 | + syslib[0] = 0x05; | |
298 | + syslib[1] = 0x1b; | |
299 | + } | |
300 | + | |
301 | + fp = fopen("syslib_dbg.ose", "wb"); | |
302 | + fwrite(syslib, 1, SYSLIBSIZ1, fp); | |
303 | + fclose(fp); | |
304 | + return syslib; | |
305 | +} | |
306 | + | |
307 | +void LoadAppBin(HOSECPU_RuntimeEnvironment *env) | |
308 | +{ | |
309 | + FILE *fp; | |
310 | + const char *fileName; | |
311 | + /* アプリバイナリの読み込み */ | |
312 | + if (env->mainArgc <= 1) { | |
313 | + //アプリ名未指定なので何事もなく終了 | |
314 | + exit(EXIT_SUCCESS); | |
315 | + } | |
316 | + fileName = env->mainArgv[1]; | |
317 | + //アプリ名先頭に:n:をつけることでレベルnでの実行が可能? | |
318 | + if (fileName[0] == ':' && fileName[2] == ':') { | |
319 | + env->executionLevel = fileName[1] - '0'; | |
320 | + if (env->executionLevel < 0 || env->executionLevel > 9){ | |
321 | + env->executionLevel = JITC_LV_SLOWEST; | |
322 | + } | |
323 | + fileName += 3; | |
324 | + } | |
325 | + | |
326 | + fp = fopen(fileName, "rb"); | |
327 | + if (fp == NULL) { | |
328 | + fputs("app-file load error.\n", stderr); | |
329 | + exit(EXIT_FAILURE); | |
330 | + } | |
331 | + env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp); | |
332 | + env->appSize1 = env->appSize0; | |
333 | + fclose(fp); | |
334 | + | |
335 | + if (env->appSize0 >= APPSIZ1 - 4) { | |
336 | + fputs("app-file too large.\n", stderr); | |
337 | + exit(EXIT_FAILURE); | |
338 | + } | |
339 | + if (env->appSize0 < 3) { | |
340 | + fputs("app-file header error.\n", stderr); | |
341 | + exit(EXIT_FAILURE); | |
342 | + } | |
343 | +} |
@@ -138,9 +138,9 @@ struct Regs { | ||
138 | 138 | // |
139 | 139 | int debugInfo0; // 2304 |
140 | 140 | int debugInfo1; // 2308 |
141 | - int dmy[2]; // 4 * 2 = 8 | |
141 | + int dmy[2]; // 2312, 2316 | |
142 | 142 | // |
143 | - HOSECPU_PointerControlTag *ptrCtrl; | |
143 | + HOSECPU_PointerControlTag *ptrCtrl; // 2320 | |
144 | 144 | char winClosed, autoSleep; |
145 | 145 | jmp_buf setjmpEnv; |
146 | 146 | int appReturnCode; // アプリ自体の終了コード |
@@ -196,11 +196,13 @@ const char *searchArg(int argc, const char **argv, const char *tag, int i); // | ||
196 | 196 | void devFunc(HOSECPU_RuntimeEnvironment *r); // junkApiを処理する関数 |
197 | 197 | |
198 | 198 | // @jitc.c |
199 | +void errorHandler(HOSECPU_RuntimeEnvironment *r); | |
200 | + | |
201 | +// @jitcx86.c | |
199 | 202 | int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label); |
200 | 203 | int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *src, const unsigned char *src1, const unsigned char *src0, HOSECPU_LabelListTag *label, int maxLabels, int level, int debugInfo1, int flags); |
201 | 204 | unsigned char *jitCompCallFunc(unsigned char *dst, void *func); |
202 | 205 | unsigned char *jitCompInit(unsigned char *dst); |
203 | -void errorHandler(HOSECPU_RuntimeEnvironment *r); | |
204 | 206 | |
205 | 207 | // @randmt.c |
206 | 208 | void randStatInit(unsigned int seed); |