コミットメタ情報

リビジョン43603aff869e2ba0a09d100523210f1f8cfc08b7 (tree)
日時2014-03-20 18:24:21
作者hikarupsp <hikarupsp@user...>
コミッターhikarupsp

ログメッセージ

キーボード関連の修正

変更サマリ

差分

--- a/dpndenv.c
+++ b/dpndenv.c
@@ -79,6 +79,9 @@
7979 if (kc == NSDownArrowFunctionKey) i = KEY_DOWN;
8080 if (kc == NSInsertFunctionKey) i = KEY_INS;
8181 if (kc == NSDeleteFunctionKey) i = KEY_DEL;
82+ if (i == KEY_EMPTY && isascii(kc)){
83+ i = kc;
84+ }
8285 // 修飾キー
8386 // TODO : 下の方の右辺、iとjが混ざっているのは修正すべき?
8487 j = 0;
@@ -93,11 +96,7 @@
9396 if ((GetKeyState(VK_CAPITAL) & (1 << 0)) != 0) i |= KEY_MODIFIER_CAPITAL;
9497 */
9598
96- NSLog(@"%X", kc);
97- if (isascii(kc)){
98- i = kc;
99- }
100-
99+ // NSLog(@"%X", i);
101100 if (i != -1) {
102101 putKeybuf(i | j);
103102 }
--- a/jitcx86.c
+++ b/jitcx86.c
@@ -1,1771 +1,1774 @@
1-#include "osecpu.h"
2-#include "jitc.h"
3-
4-#if (JITC_ARCNUM == 0x0001)
5-//
6-// for x86-32bit
7-//
8-
9-// F5の場合、decoderが対応するalloc-freeを結びつけるのが簡単で、typやlenを指定必須にしてもフロントエンドコードに影響はない.
10-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)
11-{
12- // For IA-32 (x86, 32-bit)
13- // 本来ならこのレイヤでは文法チェックしない
14- //
15- // dst : 現在の書き込みアドレス。
16- // dst1 : 書き込みアドレスの最大値
17- // src : 現在の読み込みアドレス(ヘッダ部は飛ばしてある
18- // src1 : 読み込みアドレスの最大値
19- // src0 : 読み込みバイナリのアドレス
20- struct JitCompWork w;
21- unsigned char *dst00 = dst, *enter0 = NULL, *tmp_ucp;
22- char *errmsg = "";
23- const unsigned char *oldsrc;
24- int timecount = 0, i, j = 0, lastlabel = -1, debugInfo0 = -1;
25- int reg0, reg1, reg2, cmp0reg = -1, cmp0lev = 0;
26-
27- w.dst = w.dst0 = dst;
28- w.err = 0;
29- w.maxLabels = maxLabels;
30-
31- if ((flags & JITC_NOSTARTUP) == 0) {
32- jitCompPutOp_PUSHAD(w.dst);
33- // Load cache
34- jitCompA000_loadRegCacheAll(&w);
35- jitCompA000_loadPRegCacheAll(&w);
36- }
37- if (level <= JITC_LV_SLOWER) {
38- // env.debugInfo0 <- 0;
39- // env.debugInfo1 <- debugInfo1;
40- jitCompPutOp_MOV_EAX_ZERO(w.dst);
41- jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO0, IA32_REG0_EAX);
42- jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1);
43- jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX);
44- }
45- while (src < src1) {
46- w.prefix = 0; //0x04 CND 命令で変更される
47- if (w.dst + 256 > dst1) {
48- // 書き込み領域が残り256バイト未満ならエラー
49- w.err = JITC_ERR_DST1;
50- goto err_w;
51- }
52- timecount++;
53- if (timecount >= 64) {
54- timecount -= 64;
55- /* 未完成(timeoutチェックコードを入れる) */
56- }
57- if(*src != 0x00 && *src != 0x01 && *src != 0x34){
58- DEBUGCode(&w, *src);
59- }
60- prefix_continue:
61- // CND命令コンパイル後ここに戻る
62- switch (*src) {
63- case 0x00:
64- // NOP
65- if (w.prefix != 0) {
66- // 「条件付きでNOPを実行」するなんて、矛盾している!
67- w.err = JITC_ERR_PREFIX;
68- goto err_w;
69- }
70- break;
71-
72- case 0x01:
73- // LB : ラベル設置命令。(6byte)
74- // ・prefex = 1にする
75- // ・timecount++し、timecountのチェックをする。
76- // ・ラベル位置を登録する。
77- // ・割り込みがある場合、このタイミングで割り込みを発生させる。
78- // Encode:
79- // 0 1 2345
80- // 01 opt imm32
81- //
82- if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) {
83- //beginFunc()中のLB
84- // LB命令の後に0x3C命令・・・beginFunc()
85- enter0 = w.dst;
86- jitCompPutOp_JMPnear(w.dst, 0);
87- }
88-
89- if (src[6] == 0x34) {
90- // 後続命令はDATA
91- // なので、DATA部分をJMPですっとばすコードを生成
92- // DAT_SA0(label, typ32, length) ・・・メモリ確保命令
93-
94- i = jitCompGetImm32(&src[6 + 1]); // type32 を取得
95- j = 32;
96-
97- if (i != 1) {
98- i = jitCompA000_convTyp(i);
99- j = 0;
100- switch (i >> 1) {
101- case 1:
102- j = 1;
103- break;
104- case 2:
105- j = 2;
106- break;
107- case 3:
108- j = 4;
109- break;
110- }
111- }
112- // jはデータサイズになる
113- j *= jitCompGetImm32(&src[6 + 5]); // len32
114- if (j <= 0){
115- w.err = JITC_ERR_BADTYPE;
116- }
117- // DATA部分を飛び越すジャンプ
118- tmp_ucp = w.dst;
119- jitCompPutOp_JMPnear(w.dst, j);
120-
121-#if (jitCompA0001_OPTIMIZE_JMP != 0)
122- if (j < 127 - jitCompA0001_OPTIMIZE_ALIGN) {
123- //飛び先が十分近いので
124- // 今書いたのはなかったことにして、
125- w.dst -= 5;
126- // よりサイズの小さな書き方にする
127- jitCompPutOp_JMPshort(w.dst, j);
128- }
129-#endif
130- }
131-#if (jitCompA0001_OPTIMIZE_ALIGN != 0)
132- // アラインを jitCompA0001_OPTIMIZE_ALIGNにそろえる
133-
134- i = ((int)w.dst + 1) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */
135- i = jitCompA0001_OPTIMIZE_ALIGN - i;
136- if (i == 1) { jitCompPutByte1(w.dst, 0x90); j += i; } /* NOP(); */
137- if (i == 2) { jitCompPutByte2(w.dst, 0x89, 0xc0); j += i; } /* MOV(EAX, EAX); */
138- if (i == 3) { jitCompPutByte3(w.dst, 0x8d, 0x76, 0x00); j += i; } /* LEA(ESI, [ESI+0]); */
139- if (i == 4) { jitCompPutByte4(w.dst, 0x8d, 0x74, 0x26, 0x00); j += i; } /* LEA(ESI, [ESI*1+0]); */
140- if (i == 5) { jitCompPutByte1(w.dst, 0x0d); jitCompPutImm32(w.dst, 0); j += i; } /* OR(EAX, 0); */
141- if (i == 6) { jitCompPutByte2(w.dst, 0x8d, 0xb6); jitCompPutImm32(w.dst, 0); j += i; } /* LEA(ESI, [ESI+0]); */
142- if (i == 7) { jitCompPutByte3(w.dst, 0x8d, 0xb4, 0x26); jitCompPutImm32(w.dst, 0); j += 7; } /* LEA(ESI, [ESI*1+0]); */
143-#endif
144- if (src[6] == 0x34) {
145- // 後続命令はDATA
146- // パディングに合わせて一個前の相対ジャンプを修正
147- tmp_ucp[1] = j & 0xff;
148- if (*tmp_ucp == 0xe9) {
149- // Near jump so imm is DWORD
150- tmp_ucp[2] = (j >> 8) & 0xff;
151- tmp_ucp[3] = (j >> 16) & 0xff;
152- tmp_ucp[4] = (j >> 24) & 0xff;
153- }
154- }
155- if ((flags & JITC_PHASE1) == 0) { // Phase 0ならば
156- i = jitCompGetLabelNum(&w, src + 2);
157- if (label[i].opt != 0 && w.err == 0) {
158- w.err = JITC_ERR_LABELREDEF; // すでに同じ値のラベルがあればエラー
159- goto err_w;
160- }
161- if (w.prefix != 0) { // CND命令の直後にラベルは設置できない
162- w.err = JITC_ERR_PREFIX;
163- goto err_w;
164- }
165- label[i].opt = src[1] + 1;
166- label[i].typ = 0; /* TYP_CODE */
167- label[i].p = w.dst;
168- label[i].p1 = w.dst + 1;
169- lastlabel = i;
170- }
171- cmp0reg = -1;
172- timecount = 0;
173- /* 未完成(timeoutチェックコードを入れる) */
174- break;
175-
176- case 0x02:
177- // LIMM : 定数即値代入命令(6byte)
178- // Encode:
179- // 0 1 2345
180- // 02 reg0R imm32
181- //
182- // reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。
183-
184- if (src[1] == 0x3f && w.prefix != 0){
185- // CND命令の直後でR3Fを書き換えるなんて変だよね
186- w.err = JITC_ERR_PREFIX;
187- }
188-
189-#if (jitCompA0001_USE_R3F_IMM32 != 0)
190- if (src[1] == 0x3f) {
191- // R3Fへの代入は例外で、 w.r3f を使用
192- w.r3f = jitCompGetImm32(src + 2);
193- break;
194- }
195-#endif
196- i = jitCompGetImm32(src + 2); // 与えられた即値(第二引数)を取得
197- /* R00-R02 なら EBX, ECX, EDX 、それ以外なら EAX のレジスタIDを reg0 に代入 */
198- reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
199-
200-#if (jitCompA0001_OPTIMIZE_MOV != 0)
201- // size optimization
202- // MOV reg, 0 -> XOR reg, reg
203- if (i == 0) {
204- jitCompPutOp_XOR_GReg_GReg(w.dst, reg0, reg0);
205- jitCompA0001_movRxxEax(&w, src[1]);
206- break;
207- }
208-#endif
209- /* reg0 のレジスタに対応したMOV命令を発行 */
210- jitCompPutOp_MOV_GReg_Imm32(w.dst, reg0, i);
211-
212- if (reg0 == 0){
213- // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合
214- jitCompA0001_movRxxEax(&w, src[1]);
215- }
216-
217- break;
218-
219- case 0x03: /* 未完成(plsまで対応) */
220- // PLIMM : ラベル番号代入命令(6byte)
221- // Encode:
222- // 0 1 2345
223- // 03 PXX imm32
224- //
225- // ・P28 はAPI用
226- // ・P30 はリターンアドレス
227- // ・P3F はプログラムカウンタ
228- //
229-
230- i = jitCompGetLabelNum(&w, src + 2); // Pxxに代入するラベルの番号(第二引数)
231- if ((flags & JITC_PHASE1) != 0 && w.err == 0) {
232- // Phase 1であるならば
233- if (label[i].opt == 0) {
234- // 指定されたラベル番号は存在しない
235- w.err = JITC_ERR_LABELNODEF;
236- goto err_w;
237- }
238- if (src[1] != 0x3f && label[i].opt != 2) {
239- // ?
240- w.err = JITC_ERR_LABELTYP;
241- goto err_w;
242- }
243- if (src[1] == 0x3f && label[i].typ != 0) {
244- // プログラムカウンタに TYP_CODEでない値は代入できない
245- w.err = JITC_ERR_LABELTYP;
246- goto err_w;
247- }
248- }
249- if (src[1] == 0x3f) {
250- // プログラムカウンタへの代入
251- if (w.prefix == 0) {
252- // CND命令による条件付きでなければ、即座に移動
253- jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */
254- } else {
255- // 直前はCND命令。
256-
257- /*
258- * CND命令
259- * 1 2
260- * 04 reg0R
261- *
262- * いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd
263- */
264-
265- // Jccの条件変更
266- // 0F 75
267- w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */
268- w.dst[-2] = 0x0f;
269-
270- w.prefix = 0;
271- }
272- j = 0;
273- if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) // label番号iが確保されているか、Phase 1なら
274- j = label[i].p - (w.dst + 4); // j はとび先の相対番地
275- jitCompPutImm32(w.dst, j); // JMP もしくは JZ 命令のアドレス部を記述
276-#if (jitCompA0001_OPTIMIZE_JMP != 0)
277- if (-128 - 3 <= j && j < 0) {
278- if (w.dst[-5] == 0xe9) {
279- j += 3;
280- w.dst -= 5;
281- jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */
282- } else {
283- j += 4;
284- w.dst -= 6;
285- jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0);
286- }
287- jitCompPutByte1(w.dst, j & 0xff);
288- }
289-#endif
290- } else { // プログラムカウンタ以外への代入
291- // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定
292- reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX);
293- // ラベルのパスを各レジスタに代入
294- jitCompPutOp_MOV_GReg_Imm32(w.dst, reg0, (int)label[i].p);
295- // レジスタへの代入をメモリでエミュレーションする場合は、スタックに書き込む。
296- if (reg0 == 0){
297- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 0, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
298- }
299-
300- if (level < JITC_LV_FASTEST) {
301- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 8, reg0); /* p0 */
302- jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, label[i].typ);
303- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 4, IA32_REG0_EAX); /* typ */
304- jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, (int)label[i].p1);
305- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 12, IA32_REG0_EAX); /* p1 */
306- jitCompPutOp_MOV_EAX_ZERO(w.dst);
307- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 16, IA32_REG0_EAX); /* liveSign */
308- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, envOffset_PTRCTRL);
309- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 20, IA32_REG0_EAX); /* pls */
310- }
311- }
312- break;
313-
314- case 0x04:
315- // CND (prefix)
316- // 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。
317-
318- if (src[1] >= 0x40){
319- // R00-R3F 以外のレジスタは比較対象にできない
320- w.err = JITC_ERR_REGNUM;
321- goto err_w;
322- }
323-
324- // 比較対象のレジスタがメモリ上にあれば-1, それ以外なら適切なレジスタ番号を返す
325- reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */);
326-
327- /* TEST命令を発行 */
328- if (reg0 < 0) {
329- // 比較対象のレジスタはメモリ上にある
330- jitCompPutByte1(w.dst, 0xf7); /* TEST = 1111 011w : mod 000 r/m : immediate data */
331- jitCompPutModRM_Disp_BaseEBP(&w, src[1] * 4, 0);
332- } else {
333- // 比較対象はキャッシュレジスタ上にある
334- jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST = 1111 011w : 11 000 reg : immediate data */
335- }
336- jitCompPutImm32(w.dst, 1);
337-
338- /* JZ命令を発行 */
339- jitCompPutByte2(w.dst, 0x74, 0x00); /* JZ($+2) */
340- cmp0reg = -1;
341- if (w.err != 0){
342- goto err_w;
343- }
344- src += 2;
345- w.prefix = 1; // プリフィックスをセット
346- w.dst0 = w.dst;
347- goto prefix_continue;
348-
349- case 0x08: /* LMEM */ /* 完成 */
350- i = jitCompGetImm32(src + 2);
351- if (i == 0x0001){
352- w.err = JITC_ERR_BADTYPE;
353- }
354- if (level < JITC_LV_FASTER) {
355- jitCompA0001_checkType(&w, src[6], i, 0); // read
356- cmp0reg = -1;
357- }
358- reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
359- reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX);
360- if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX){
361- reg1 = IA32_REG0_EAX;
362- }
363- if (reg1 == IA32_REG2_EDX){
364- jitCompA000_storeRegCacheEdx(&w);
365- }
366- if (reg1 <= 3 /* EAX, EDX */){
367- jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6]));
368- }
369- if (level < JITC_LV_FASTER){
370- jitCompA0001_checkLimit(&w, reg1, src[6]);
371- }
372- i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
373- switch (i) {
374- case 0x0002:
375- jitCompPutByte3(w.dst, 0x0f, 0xbe, reg0 << 3 | reg1); /* MOVSX(reg0,BYTE [reg1]); */
376- break;
377- case 0x0003:
378- jitCompPutByte3(w.dst, 0x0f, 0xb6, reg0 << 3 | reg1); /* MOVZX(reg0,BYTE [reg1]); */
379- break;
380- case 0x0004:
381- jitCompPutByte3(w.dst, 0x0f, 0xbf, reg0 << 3 | reg1); /* MOVSX(reg0,WORD [reg1]); */
382- break;
383- case 0x0005:
384- jitCompPutByte3(w.dst, 0x0f, 0xb7, reg0 << 3 | reg1); /* MOVZX(reg0,WORD [reg1]); */
385- break;
386- case 0x0006:
387- case 0x0007:
388- jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */
389- break;
390- default:
391- w.err = JITC_ERR_BADTYPE;
392- }
393- if (reg0 == IA32_REG0_EAX){
394- jitCompA0001_movRxxEax(&w, src[1]);
395- }
396- if (reg1 == IA32_REG2_EDX){
397- jitCompA000_loadRegCacheEdx(&w);
398- }
399- break;
400-
401- case 0x09: /* SMEM */ /* 完成 */
402- i = jitCompGetImm32(src + 2);
403- if (i == 0x0001){
404- w.err = JITC_ERR_BADTYPE;
405- }
406- if (level < JITC_LV_FASTER) {
407- jitCompA0001_checkType(&w, src[6], i, 1); // write
408- cmp0reg = -1;
409- }
410- reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
411- reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX);
412- if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX){
413- reg1 = IA32_REG0_EAX;
414- }
415- if (reg1 == IA32_REG2_EDX){
416- jitCompA000_storeRegCacheEdx(&w);
417- }
418- if (reg1 <= 3 /* EAX, EDX */){
419- jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6]) + 0); /* MOV(reg1, [EBP+?]); */
420- }
421- if (level < JITC_LV_FASTER){
422- jitCompA0001_checkLimit(&w, reg1, src[6]);
423- }
424- if (reg0 == IA32_REG0_EAX){
425- jitCompA0001_movEaxRxx(&w, src[1]);
426- }
427- /* 値の範囲チェック */
428- i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
429- switch (i) {
430- case 0x0002:
431- case 0x0003:
432- jitCompPutByte2(w.dst, 0x88, reg0 << 3 | reg1); /* MOV([reg1], BYTE(reg0)); */
433- break;
434- case 0x0004:
435- case 0x0005:
436- jitCompPutByte3(w.dst, 0x66, 0x89, reg0 << 3 | reg1); /* MOV([reg1], WORD(reg0)); */
437- break;
438- case 0x0006:
439- case 0x0007:
440- jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */
441- break;
442- default:
443- w.err = JITC_ERR_BADTYPE;
444- }
445- if (reg1 == IA32_REG2_EDX){
446- jitCompA000_loadRegCacheEdx(&w);
447- }
448- break;
449-
450- case 0x0a: /* PLMEM */ /* 完成 */
451- i = jitCompGetImm32(src + 2);
452- if (i != 0x0001){
453- w.err = JITC_ERR_BADTYPE;
454- }
455- if (level < JITC_LV_FASTER) {
456- jitCompA0001_checkType(&w, src[6], i, 0); // read
457- cmp0reg = -1;
458- }
459- reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX);
460- reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX);
461- // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */
462- // reg1 = 0; /* EAX */
463- if (reg0 == reg1 && reg0 != 0) {
464- // bugfix: hinted by yao, 2013.09.14. thanks!
465- jitCompA000_storePRegCacheAll(&w);
466- reg1 = IA32_REG2_EDX;
467- }
468- if (reg1 == IA32_REG2_EDX){
469- jitCompA000_storeRegCacheEdx(&w);
470- }
471- if (reg1 <= 3 /* EAX, EDX */){
472- jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6])); /* MOV(reg1, [EBP+?]); */
473- }
474- if (level < JITC_LV_FASTER){
475- jitCompA0001_checkLimit(&w, reg1, src[6]);
476- }
477- jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */
478- if (reg0 == IA32_REG0_EAX){
479- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]), IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
480- }
481- for (i = 4; i < 32; i += 4) {
482- jitCompPutByte3(w.dst, 0x8b, 0x40 | reg1, i); /* MOV(EAX, [reg1+?]); */
483- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
484- }
485- if (reg1 == IA32_REG2_EDX){
486- jitCompA000_loadRegCacheEdx(&w);
487- }
488- break;
489-
490- case 0x0b: /* PSMEM */ /* 完成 */
491- i = jitCompGetImm32(src + 2);
492- if (i != 0x0001) w.err = JITC_ERR_BADTYPE;
493- if (level < JITC_LV_FASTER) {
494- jitCompA0001_checkType(&w, src[6], i, 1); // write
495- cmp0reg = -1;
496- }
497- reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX);
498- reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX);
499- /* これをやってはいけない!(by K, 2013.08.02) */
500- // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */)
501- // reg1 = 0; /* EAX */
502- if (reg1 == IA32_REG2_EDX){
503- jitCompA000_storeRegCacheEdx(&w);
504- }
505- if (reg1 <= 3 /* EAX, EDX */){
506- jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6])); /* MOV(reg1, [EBP+?]); */
507- }
508- if (level < JITC_LV_FASTER){
509- jitCompA0001_checkLimit(&w, reg1, src[6]);
510- }
511- if (reg0 == IA32_REG0_EAX){
512- jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[1])); /* MOV(reg0, [EBP+?]); */
513- }
514- jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */
515- for (i = 4; i < 32; i += 4) {
516- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[1]) + i); /* MOV(EAX, [EBP+?]); */
517- jitCompPutByte3(w.dst, 0x89, 0x40 | reg1, i); /* MOV([reg1+?], EAX); */
518- }
519- if (reg1 == IA32_REG2_EDX)
520- jitCompA000_loadRegCacheEdx(&w);
521- break;
522-
523- case 0x0e: /* PADD */ /* 完成 */
524- if (level < JITC_LV_FASTER) {
525- jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 2), 2); // other, aliveテストはとりあえずしない.
526- cmp0reg = -1;
527- }
528- reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX);
529- reg1 = jitCompA000_selectPRegCache(src[6], -1 /* mem */);
530- if (reg1 < 0 /* mem */){
531- jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[6])); /* MOV(reg0, [EBP+?]); */
532- }
533- if (reg1 >= 0 && reg0 != reg1) {
534- jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
535- }
536- i = jitCompGetImm32(src + 2);
537- j = -1;
538- if (i == 1){
539- j = 5; /* 32 */
540- } else {
541- i = jitCompA000_convTyp(i);
542- if (0x0002 <= i && i <= 0x0007){
543- j = (i - 0x0002) >> 1;
544- }
545- }
546- if (j < 0) {
547- w.err = JITC_ERR_BADTYPE;
548- goto err_w;
549- }
550-#if (jitCompA0001_USE_R3F_IMM32 != 0)
551- if (src[7] == 0x3f) {
552- j = w.r3f << j;
553-#if (jitCompA0001_USE_R3F_IMM8 != 0)
554- if (-0x80 <= j && j <= 0x7f) {
555-#if (jitCompA0001_USE_R3F_INCDEC != 0)
556- if (j == 1) {
557- /* INC */
558- jitCompPutByte1(w.dst, 0x40 | reg0);
559- goto padd1;
560- }
561- if (j == -1) {
562- /* DEC */
563- jitCompPutByte1(w.dst, 0x48 | reg0);
564- goto padd1;
565- }
566-#endif
567- /* ADD(reg0, im8); */
568- jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff);
569- goto padd1;
570- }
571-#endif
572- if (reg0 == 0) {
573- jitCompPutByte1(w.dst, 0x05); /* ADD(reg0, ?); */
574- } else {
575- jitCompPutByte2(w.dst, 0x81, 0xc0 | reg0); /* ADD(reg0, ?); */
576- }
577- jitCompPutImm32(w.dst, j);
578- goto padd1;
579- }
580-#endif
581- if (src[7] >= 0x40){
582- w.err = JITC_ERR_REGNUM;
583- }
584- if (j == 0) {
585- reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */);
586- if (reg1 >= 0) {
587- jitCompPutByte2(w.dst, 0x01, 0xc0 | reg1 << 3 | reg0); /* ADD(reg0, reg1); */
588- } else {
589- jitCompPutByte1(w.dst, 0x03); /* ADD(reg0, [EBP+?]); */
590- jitCompPutModRM_Disp_BaseEBP(&w, src[7] * 4, reg0);
591- }
592- }
593- else {
594- reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */);
595- reg2 = IA32_REG2_EDX;
596- jitCompA000_storeRegCacheEdx(&w);
597- if (reg1 < 0){
598- jitCompPutOp_MOV_GReg_EBPDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */
599- }
600- if (reg1 >= 0 && reg1 != reg2) {
601- jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg2); /* MOV(reg2, reg1); */
602- }
603- jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg2, j); /* SHL(reg2, ?); */
604- jitCompPutByte2(w.dst, 0x01, 0xc0 | reg2 << 3 | reg0); /* ADD(reg0, reg2); */
605- jitCompA000_loadRegCacheEdx(&w);
606- }
607-#if (jitCompA0001_USE_R3F_IMM32 != 0)
608- padd1:
609-#endif
610- if (reg0 == IA32_REG0_EAX){
611- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]), reg0); /* MOV([EBP+?], reg0); */
612- }
613- if (src[1] != src[6]) {
614- for (i = 4; i < 32; i += 4) {
615- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */
616- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
617- }
618- }
619- cmp0reg = -1;
620- break;
621-
622- case 0x0f: /* PDIF */ /* 未完成 */
623- reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
624- jitCompA000_storePRegCacheAll(&w); // 手抜き.
625- jitCompA0001_checkCompPtr(&w, src[6], src[7]);
626- jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[6])); /* MOV(reg0, [EBP+?]); */
627- jitCompPutByte1(w.dst, 0x2b); /* SUB(EAX, [EBP+?]); */
628- jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[7]) + 0, reg0);
629- i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
630- j = -1;
631- if (0x0002 <= i && i <= 0x0007){
632- j = (i - 0x0002) >> 1;
633- }
634- if (j < 0) {
635- w.err = JITC_ERR_BADTYPE;
636- goto err_w;
637- }
638- if (j > 0) {
639- jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, j); /* SAR(reg0,?); */
640- }
641- if (reg0 == IA32_REG0_EAX){
642- jitCompA0001_movRxxEax(&w, src[1]);
643- }
644- cmp0reg = src[1];
645- cmp0lev = 1;
646- break;
647-
648- case 0x10: /* OR */
649- case 0x11: /* XOR */
650- case 0x12: /* AND */
651- case 0x14: /* ADD */
652- case 0x15: /* SUB */
653- case 0x16: /* MUL */
654- if (src[1] >= 0x3f){
655- w.err = JITC_ERR_REGNUM;
656- }
657- reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
658- reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */);
659-#if (jitCompA0001_USE_R3F_IMM32 != 0)
660- if (src[2] == 0x3f) { // SUBのみ該当.
661- if (*src != 0x15){
662- w.err = JITC_ERR_REGNUM;
663- }
664- reg2 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
665- if (reg2 >= 0){
666- jitCompA000_storeRegCacheAll(&w);
667- }
668- jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */
669- jitCompPutImm32(w.dst, w.r3f);
670- jitCompPutByte1(w.dst, 0x2b);
671- jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0);
672- if (reg0 == 0){
673- jitCompA0001_movRxxEax(&w, src[1]);
674- }
675- break;
676- }
677-#endif
678- if (reg1 < 0) {
679- jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, src[2] * 4); /* MOV(reg0, [EBP+?]); */
680- }
681- if (reg1 >= 0 && reg0 != reg1) {
682- jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
683- }
684- if (!(src[0] == 0x10 && src[3] == 0xff)) {
685- // bugfix: hinted by Iris, 2013.06.26. thanks!
686- cmp0reg = src[1];
687- cmp0lev = 1;
688- if (src[0] < 0x14){
689- cmp0lev = 2;
690- }
691- if (src[0] == 0x16){
692- cmp0reg = -1;
693- }
694- }
695- if (!(src[0] == 0x10 && src[3] == 0xff)) {
696-#if (jitCompA0001_USE_R3F_IMM32 != 0)
697- if (src[3] == 0x3f) {
698- if (*src == 0x16 && w.r3f == -1) {
699- jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */
700- if (reg0 == 0){
701- jitCompA0001_movRxxEax(&w, src[1]);
702- }
703- break;
704- }
705-#if (jitCompA0001_USE_R3F_INCDEC != 0)
706- if ((*src == 0x14 && w.r3f == 1) || (*src == 0x15 && w.r3f == -1)) {
707- jitCompPutByte1(w.dst, 0x40 | reg0); /* INC(reg0); */
708- if (reg0 == 0){
709- jitCompA0001_movRxxEax(&w, src[1]);
710- }
711- break;
712- }
713- if ((*src == 0x15 && w.r3f == 1) || (*src == 0x14 && w.r3f == -1)) {
714- jitCompPutByte1(w.dst, 0x48 | reg0); /* DEC(reg0); */
715- if (reg0 == 0){
716- jitCompA0001_movRxxEax(&w, src[1]);
717- }
718- break;
719- }
720-#endif
721-#if (jitCompA0001_USE_R3F_IMM8 != 0)
722- if (-0x80 <= w.r3f && w.r3f <= 0x7f) {
723- if (*src != 0x16) {
724- static unsigned char basic_op_table_im8[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 };
725- jitCompPutByte3(w.dst, 0x83, basic_op_table_im8[*src - 0x10] | reg0, w.r3f & 0xff);
726- } else{
727- jitCompPutByte3(w.dst, 0x6b, 0xc0 | reg0 << 3 | reg0, w.r3f & 0xff);
728- }
729- if (reg0 == 0){
730- jitCompA0001_movRxxEax(&w, src[1]);
731- }
732- break;
733- }
734-#endif
735- if (reg0 == IA32_REG0_EAX) {
736- static unsigned char basic_op_table_im32_eax[] = { 0x0d, 0x35, 0x25, 0, 0x05, 0x2d, 0xc0 };
737- if (*src == 0x16) {
738- jitCompPutByte1(w.dst, 0x69);
739- }
740- jitCompPutByte1(w.dst, basic_op_table_im32_eax[*src - 0x10]);
741- } else{
742- if (*src != 0x16) {
743- static unsigned char basic_op_table_im32_reg[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 };
744- jitCompPutByte2(w.dst, 0x81, basic_op_table_im32_reg[*src - 0x10] | reg0);
745- }
746- else {
747- jitCompPutByte2(w.dst, 0x69, 0xc0 | reg0 << 3 | reg0);
748- }
749- }
750- jitCompPutImm32(w.dst, w.r3f);
751- if (reg0 == 0){
752- jitCompA0001_movRxxEax(&w, src[1]);
753- }
754- break;
755- }
756-#endif
757- reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
758- if (src[3] >= 0x40){
759- w.err = JITC_ERR_REGNUM;
760- }
761- if (*src != 0x16) {
762- if (reg1 >= 0) {
763- static unsigned char basic_op_table_rr[] = { 0x09, 0x31, 0x21, 0, 0x01, 0x29 }; /* op(reg,reg); */
764- jitCompPutByte2(w.dst, basic_op_table_rr[*src - 0x10], 0xc0 | reg1 << 3 | reg0);
765- } else{
766- static unsigned char basic_op_table_rm[] = { 0x0b, 0x33, 0x23, 0, 0x03, 0x2b, 0xaf }; /* op(reg,mem); */
767- jitCompPutByte1(w.dst, basic_op_table_rm[*src - 0x10]);
768- jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0);
769- }
770- } else{
771- if (reg1 >= 0) {
772- jitCompPutByte3(w.dst, 0x0f, 0xaf, 0xc0 | reg0 << 3 | reg1);
773- } else{
774- jitCompPutByte2(w.dst, 0x0f, 0xaf);
775- jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0);
776- }
777- }
778- }
779- if (reg0 == 0){
780- jitCompA0001_movRxxEax(&w, src[1]);
781- }
782- break;
783-
784- case 0x18: /* SHL */
785- case 0x19: /* SAR */
786- if (src[1] >= 0x3f){
787- w.err = JITC_ERR_REGNUM;
788- }
789- if (src[3] >= 0x40){
790- w.err = JITC_ERR_REGNUM;
791- }
792-#if (jitCompA0001_USE_R3F_IMM32 != 0)
793- if (src[3] == 0x3f) {
794- reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
795- reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */);
796- if (src[1] >= 0x3f){
797- w.err = JITC_ERR_REGNUM;
798- }
799- if (reg1 == -1){
800- jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, src[2] * 4); /* MOV(reg1, [EBP+?]); */
801- } else{
802- if (reg0 != reg1) {
803- jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
804- }
805- }
806- if (*src == 0x18) {
807- /* SHL(reg0, im8); */
808- jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f);
809- }
810- if (*src == 0x19) {
811- /* SAR(reg0, im8); */
812- jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f);
813- }
814- if (reg0 == IA32_REG0_EAX){
815- jitCompA0001_movRxxEax(&w, src[1]);
816- }
817- cmp0reg = src[1];
818- cmp0lev = 1;
819- break;
820- }
821-#endif
822- jitCompA000_storeRegCacheAll(&w); // 手抜き.
823- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */
824-#if (jitCompA0001_USE_R3F_IMM32 != 0)
825- if (src[2] == 0x3f) {
826- jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
827- jitCompPutImm32(w.dst, w.r3f);
828- } else{
829- jitCompA0001_movEaxRxx(&w, src[2]);
830- }
831-#else
832- jitCompA0001_movEaxRxx(&w, src[2]);
833-#endif
834- if (*src == 0x18) {
835- /* SHL(EAX, CL); */
836- jitCompPutByte2(w.dst, 0xd3, 0xe0);
837- }
838- if (*src == 0x19) {
839- /* SAR(EAX, CL); */
840- jitCompPutByte2(w.dst, 0xd3, 0xf8);
841- }
842- jitCompA0001_movRxxEax(&w, src[1]);
843- jitCompA000_loadRegCacheAll(&w); // 手抜き.
844- cmp0reg = src[1];
845- cmp0lev = 1;
846- break;
847-
848- case 0x1a: /* DIV */
849- case 0x1b: /* MOD */
850- if (src[1] >= 0x3f || src[2] >= 0x40 || src[3] >= 0x40){
851- w.err = JITC_ERR_REGNUM;
852- }
853- jitCompA000_storeRegCacheAll(&w); // 手抜き.
854-#if (jitCompA0001_USE_R3F_IMM32 != 0)
855- if (src[3] == 0x3f) {
856- jitCompPutByte1(w.dst, 0xb8 | 1); /* MOV(ECX, ?); */
857- jitCompPutImm32(w.dst, w.r3f);
858- } else{
859- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */
860- }
861- if (src[2] == 0x3f) {
862- jitCompPutByte1(w.dst, 0xb8 | 0); /* MOV(EAX, ?); */
863- jitCompPutImm32(w.dst, w.r3f);
864- } else{
865- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, src[2] * 4); /* MOV(EAX, [EBP+?]); */
866- }
867-#else
868- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */
869- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, src[2] * 4); /* MOV(EAX, [EBP+?]); */
870-#endif
871- jitCompPutByte1(w.dst, 0x99); /* CDQ(); */
872- /* ECXがゼロではないことを確認すべき */
873- jitCompPutByte2(w.dst, 0xf7, 0xf9); /* IDIV(ECX); */
874- if (*src == 0x1a) {
875- jitCompPutOp_MOV_EBPDisp_GReg(&w, src[1] * 4, IA32_REG0_EAX);
876- }
877- if (*src == 0x1b) {
878- jitCompPutOp_MOV_EBPDisp_GReg(&w, src[1] * 4, IA32_REG2_EDX);
879- }
880- jitCompA000_loadRegCacheAll(&w); // 手抜き.
881- cmp0reg = -1;
882- break;
883-
884- case 0x1c: /* PLMT0 */
885- case 0x1d: /* PLMT1 */
886- if (src[1] >= 0x40 || src[2] >= 0x40){
887- w.err = JITC_ERR_PREGNUM;
888- }
889- if (level < JITC_LV_FASTEST) {
890- cmp0reg = -1;
891- if (level < JITC_LV_FASTER) {
892- // typ が一致していることを確認.
893- // plsとliveSignが一致していることを確認.
894-
895- // preg1はp0 <= p <= p1 を満たしているか?.
896- // 新しいp0/p1は古いp0?p1に適合しているか?.
897-
898- }
899- }
900-
901- case 0x1e: /* PCP */ /* 未完成(p1まで完成) */
902- if (src[1] >= 0x40 || src[2] >= 0x40){
903- w.err = JITC_ERR_PREGNUM;
904- }
905- if (src[2] == 0x3f){
906- w.err = JITC_ERR_PREGNUM;
907- }
908- if (src[1] != 0x3f) {
909- /* src[2] == 0xff の場合に対応できてない */
910- jitCompA000_storePRegCacheAll(&w); // 手抜き.
911- for (i = 0; i < 32; i += 4) {
912- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + i); /* MOV(EAX, [EBP+?]); */
913- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
914- }
915- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
916- } else {
917- if (level < JITC_LV_FASTER) {
918- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + 4); /* MOV(EAX, [EBP+?]); */ /* typ */
919- jitCompPutByte3(w.dst, 0x83, 0xf8, 0); /* CMP(EAX, 0); */
920- jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */
921- jitCompPutImm32(w.dst, errfnc - (w.dst + 4));
922- /* セキュリティチェックが足りてない!(aliveとか) */
923- }
924- reg0 = IA32_REG0_EAX;
925- jitCompA000_storePRegCacheAll(&w); // 手抜き.
926- jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[2]) + 0); /* MOV(EAX, [EBP+?]); */
927- if (level < JITC_LV_FASTER) {
928- jitCompPutByte1(w.dst, 0x3b); /* CMP(reg0, [EBP+?]); */
929- jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[2]) + 8, reg0); /* p0 */
930- jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */
931- jitCompPutImm32(w.dst, errfnc - (w.dst + 4));
932- }
933- jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */
934- }
935- break;
936-
937- case 0x1f: /* PCST */
938- if (jitCompGetImm32(src + 2) == 0) {
939- if (level < JITC_LV_FASTER){
940- jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 7), 2);
941- }
942- jitCompA000_storePRegCacheAll(&w); // 手抜き.
943- for (i = 0; i < 32 - 4; i += 4) {
944- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */
945- if (i == 4) {
946- jitCompPutByte1(w.dst, 0x0d); /* OR(EAX, ?); */
947- jitCompPutImm32(w.dst, 0x80000000);
948- }
949- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
950- }
951- jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1);
952- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 28, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
953- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
954- cmp0reg = -1;
955- break;
956- }
957- if (jitCompGetImm32(src + 7) == 0) {
958- jitCompA000_storePRegCacheAll(&w); // 手抜き.
959- for (i = 0; i < 32 - 4; i += 4) {
960- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */
961- if (i == 4) {
962- jitCompPutByte1(w.dst, 0x25); /* AND(EAX, ?); */
963- jitCompPutImm32(w.dst, 0x7fffffff);
964- }
965- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
966- }
967- if (level < JITC_LV_FASTER) {
968- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + 28); /* MOV(EAX, [EBP+?]); */
969- jitCompPutByte1(w.dst, 0x3d); /* CMP(EAX, ?); */
970- jitCompPutImm32(w.dst, debugInfo1);
971- jitCompPutByte2(w.dst, 0x74, 8); /* JE */
972- jitCompPutOp_MOV_EAX_ZERO(w.dst);
973- jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 0, IA32_REG0_EAX); /* MOV([EBP+?], EAX); (1+1+4) */
974- }
975- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
976- cmp0reg = -1;
977- break;
978- }
979- w.err = JITC_ERR_OPECODE;
980- goto err_w;
981-
982- case 0x20: /* CMPE */
983- case 0x21: /* CMPNE */
984- case 0x22: /* CMPL */
985- case 0x23: /* CMPGE */
986- case 0x24: /* CMPLE */
987- case 0x25: /* CMPG */
988- case 0x26: /* TSTZ */
989- case 0x27: /* TSTNZ */
990- reg0 = jitCompA000_selectRegCache(src[2], IA32_REG0_EAX);
991- reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
992- if (src[1] == 0x3f) {
993- /* 特殊構文チェック */
994- if (w.prefix != 0) {
995- w.err = JITC_ERR_PREFIX;
996- goto err_w;
997- }
998- if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) {
999- w.err = JITC_ERR_IDIOM;
1000- goto err_w;
1001- }
1002- }
1003- if (reg0 == 0)
1004- jitCompA0001_movEaxRxx(&w, src[2]);
1005-#if (jitCompA0001_USE_R3F_IMM32 != 0)
1006- if (src[3] == 0x3f) {
1007-#if (jitCompA0001_OPTIMIZE_CMP != 0)
1008- if ((*src <= 0x25 && w.r3f == 0) || (*src >= 0x26 && w.r3f == -1)) {
1009- i = 0;
1010- if (cmp0reg == src[2]) {
1011- if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27)){
1012- i = 1;
1013- }
1014- if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25)){
1015- i = 1;
1016- }
1017- }
1018- if (i == 0) {
1019- jitCompPutByte2(w.dst, 0x85, 0xc0 | reg0 << 3 | reg0); /* TEST(reg0, reg0); */
1020- }
1021- cmp0reg = src[2];
1022- cmp0lev = 2;
1023- goto cmpcc1;
1024- }
1025-#endif
1026-#if (jitCompA0001_USE_R3F_IMM8 != 0)
1027- if (-0x80 <= w.r3f && w.r3f <= 0x7f && *src <= 0x25) {
1028- jitCompPutByte3(w.dst, 0x83, 0xf8 | reg0, w.r3f);
1029- goto cmpcc1;
1030- }
1031-#endif
1032- if (reg0 == 0) {
1033- if (*src <= 0x25) {
1034- jitCompPutByte1(w.dst, 0x3d);
1035- }
1036- if (*src >= 0x26) {
1037- jitCompPutByte1(w.dst, 0xa9);
1038- }
1039- }
1040- else {
1041- if (*src <= 0x25) {
1042- jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0);
1043- }
1044- if (*src >= 0x26) {
1045- jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0);
1046- }
1047- }
1048- jitCompPutImm32(w.dst, w.r3f);
1049- goto cmpcc1;
1050- }
1051-#endif
1052- if (src[3] >= 0x40){
1053- w.err = JITC_ERR_PREGNUM;
1054- }
1055- if (reg1 >= 0) {
1056- if (*src <= 0x25) {
1057- jitCompPutByte2(w.dst, 0x39, 0xc0 | reg1 << 3 | reg0);
1058- }
1059- if (*src >= 0x26) {
1060- jitCompPutByte2(w.dst, 0x85, 0xc0 | reg1 << 3 | reg0);
1061- }
1062- } else{
1063- if (*src <= 0x25) {
1064- jitCompPutByte1(w.dst, 0x3b);
1065- }
1066- if (*src >= 0x26) {
1067- jitCompPutByte1(w.dst, 0x85);
1068- }
1069- jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0);
1070- }
1071- cmpcc1:
1072- if (w.err != 0){
1073- goto err_w;
1074- }
1075- static unsigned char cmpcc_table0[] = {
1076- 0x04, 0x05, 0x0c, 0x0d, 0x0e, 0x0f, 0x04, 0x05, /* CMPcc, TSTcc */
1077- 0x04, 0x05, 0x02, 0x03, 0x06, 0x07 /* PCMPcc */
1078- };
1079-#if (jitCompA0001_USE_R3F_CMPJMP != 0)
1080- if (src[1] == 0x3f) {
1081- /* 特殊構文を利用した最適化 */
1082- jitCompPutByte2(w.dst, 0x0f, 0x80 | cmpcc_table0[*src - 0x20]);
1083- src += 6;
1084- i = jitCompGetLabelNum(&w, src + 2);
1085- if ((flags & JITC_PHASE1) != 0 && w.err != 0) {
1086- if (label[i].opt == 0) {
1087- w.err = JITC_ERR_LABELNODEF;
1088- goto err_w;
1089- }
1090- // if (label[i].typ != 1) { w.err = JITC_ERR_LABELTYP; goto err_w; }
1091- }
1092- j = 0;
1093- if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)){
1094- j = label[i].p - (w.dst + 4);
1095- }
1096- jitCompPutImm32(w.dst, j);
1097-#if (jitCompA0001_OPTIMIZE_JMP != 0)
1098- if (-128 - 4 <= j && j < 0) {
1099- j += 4;
1100- w.dst -= 6;
1101- jitCompPutByte2(w.dst, w.dst[1] ^ 0xf0, j & 0xff);
1102- }
1103-#endif
1104- src += 6;
1105- if (w.err != 0){
1106- goto err_w;
1107- }
1108- continue;
1109- }
1110-#endif
1111- /* 一般的なJITC */
1112- reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
1113- jitCompPutByte3(w.dst, 0x0f, 0x90 | cmpcc_table0[*src - 0x20], 0xc0 | reg0); /* SETcc(BYTE(reg0)); */
1114- jitCompPutByte3(w.dst, 0x0f, 0xb6, 0xc0 | reg0 << 3 | reg0); /* MOVZX(reg0, BYTE(reg0)); */
1115- jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */
1116- if (reg0 == 0){
1117- jitCompA0001_movRxxEax(&w, src[1]);
1118- }
1119- cmp0reg = src[2];
1120- cmp0lev = 1;
1121- break;
1122-
1123- case 0x28: /* PCMPE */
1124- case 0x29: /* PCMPNE */
1125- case 0x2a: /* PCMPL */
1126- case 0x2b: /* PCMPGE */
1127- case 0x2c: /* PCMPLE */
1128- case 0x2d: /* PCMPG */
1129- if (src[1] == 0x3f) {
1130- /* 特殊構文チェック */
1131- if (w.prefix != 0) {
1132- w.err = JITC_ERR_PREFIX;
1133- goto err_w;
1134- }
1135- if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) {
1136- w.err = JITC_ERR_IDIOM;
1137- goto err_w;
1138- }
1139- }
1140- if (src[2] >= 0x40) {
1141- w.err = JITC_ERR_PREGNUM;
1142- }
1143- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1144- if (src[3] != 0xff){
1145- jitCompA0001_checkCompPtr(&w, src[2], src[3]);
1146- }
1147- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + 0); /* MOV(EAX, [EBP+?]); */
1148- if (src[3] != 0xff) {
1149- jitCompPutByte1(w.dst, 0x3b); /* CMP(EAX, [EBP+?]); */
1150- jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[3]) + 0, 0);
1151- } else{
1152- /* ヌルポインタとの比較はこれでいいのか?たぶんよくない */
1153- jitCompPutByte3(w.dst, 0x83, 0xf8, 0x00); /* CMP(EAX, 0); */
1154- }
1155- cmp0reg = -1;
1156- goto cmpcc1;
1157-
1158- case 0x30: /* talloc(old:F4) */
1159- case 0x31: /* tfree(old:F5) */
1160- case 0x32: /* malloc(old:F6) */
1161- case 0x33: /* mfree(old:F7) */
1162- jitCompA000_storeRegCacheAll(&w); // 手抜き.
1163- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1164-
1165- jitCompPutOp_PUSH_Imm8(w.dst, src[3]);
1166- jitCompPutOp_PUSH_Imm8(w.dst, src[2]);
1167- jitCompPutOp_PUSH_Imm8(w.dst, src[1]);
1168- jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP);
1169-
1170- switch (*src) {
1171- case 0x30:
1172- j = ((unsigned char *)&funcf4) - (w.dst + 1 + 4);
1173- break;
1174- case 0x31:
1175- j = ((unsigned char *)&funcf5) - (w.dst + 1 + 4);
1176- break;
1177- case 0x32:
1178- j = ((unsigned char *)&funcf6) - (w.dst + 1 + 4);
1179- break;
1180- case 0x33:
1181- j = ((unsigned char *)&funcf7) - (w.dst + 1 + 4);
1182- break;
1183- }
1184- jitCompPutOp_CALL_Relative(w.dst, j);
1185- jitCompPutOp_ADD_GReg_Imm8(w.dst, IA32_REG4_ESP, 16);
1186-
1187- jitCompA000_loadRegCacheAll(&w); // 手抜き.
1188- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1189- cmp0reg = -1;
1190- break;
1191-
1192- case 0x34: /* data (暫定) */
1193- // 0 1234 5678 9
1194- // 34 typ32 len32 data...
1195- // len32 is NOT byte size!
1196-
1197- cmp0reg = -1;
1198- if (w.prefix != 0) {
1199- w.err = JITC_ERR_PREFIX;
1200- goto err_w;
1201- }
1202- int k, tmpData, bitCount, dataWidth;
1203- // kはtyp32
1204- k = jitCompGetImm32(&src[1]);
1205- dataWidth = jitCompA000_dataWidth(k);
1206- if (lastlabel >= 0 && label[lastlabel].typ == 0){
1207- //直前のラベルタイプを設定
1208- label[lastlabel].typ = k;
1209- }
1210- if (k != 1) {
1211- i = jitCompA000_convTyp(k);
1212- if (i < 2 || i > 7) {
1213- w.err = JITC_ERR_BADTYPE;
1214- goto err_w;
1215- }
1216- }
1217- // jはlen32
1218- j = jitCompGetImm32(&src[5]);
1219- oldsrc = src;
1220- src += 9;
1221-
1222- // srcはdata本体を指す
1223- if (k != 1) {
1224- // 一般データ
1225- bitCount = 7;
1226- while (j > 0) {
1227- if (src >= src1) {
1228- // バイトコードを末端を超えて読もうとした
1229- w.err = JITC_ERR_SRC1;
1230- src = oldsrc;
1231- goto err_w;
1232- }
1233- if (w.dst + 256 > dst1) {
1234- // 書き込み先の残り容量が256Bytesを切った
1235- w.err = JITC_ERR_DST1;
1236- src = oldsrc;
1237- goto err_w;
1238- }
1239- tmpData = 0;
1240- for (k = 0; k < dataWidth; k++) {
1241- // dataWidthビットごとに切り出してtmpDataに入れる
1242- tmpData = tmpData << 1 | ((*src >> bitCount) & 1);
1243- bitCount--;
1244- if (bitCount < 0) {
1245- bitCount = 7;
1246- src++;
1247- }
1248- }
1249- if ((i & 1) == 0 && dataWidth <= 31 && (tmpData >> (dataWidth - 1)) != 0) {
1250- // 符号あり型で、かつtmpDataの符号ビットが1なので、マイナスにする
1251- tmpData -= 1 << dataWidth;
1252- }
1253- if (i == 2 || i == 3) {
1254- // BYTE
1255- jitCompPutByte1(w.dst, tmpData & 0xff);
1256- }
1257- if (i == 4 || i == 5) {
1258- // WORD
1259- jitCompPutByte2(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff);
1260- }
1261- if (i == 6 || i == 7) {
1262- // DWORD
1263- jitCompPutByte4(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff, (tmpData >> 16) & 0xff, (tmpData >> 24) & 0xff);
1264- }
1265- j--;
1266- }
1267- } else{
1268- // VPtr型
1269- while (j > 0) {
1270- if (src >= src1) {
1271- // バイトコードを末端を超えて読もうとした
1272- w.err = JITC_ERR_SRC1;
1273- src = oldsrc;
1274- goto err_w;
1275- }
1276- if (w.dst + 256 > dst1) {
1277- // 書き込み先の残り容量が256Bytesを切った
1278- w.err = JITC_ERR_DST1;
1279- src = oldsrc;
1280- goto err_w;
1281- }
1282- i = jitCompGetImm32(src);
1283- src += 4;
1284- if ((flags & JITC_PHASE1) != 0 && w.err == 0) {
1285- // Only in phase1
1286- if (label[i].opt == 0) {
1287- // ローカルラベルはだめです...
1288- w.err = JITC_ERR_LABELNODEF;
1289- goto err_w;
1290- }
1291- }
1292- jitCompPutImm32(w.dst, (int)label[i].p);
1293- jitCompPutImm32(w.dst, label[i].typ);
1294- jitCompPutImm32(w.dst, (int)label[i].p);
1295- jitCompPutImm32(w.dst, (int)label[i].p1);
1296- jitCompPutImm32(w.dst, 0); /* liveSign */
1297- jitCompPutImm32(w.dst, envOffset_PTRCTRL); /* pls */
1298- jitCompPutImm32(w.dst, 0);
1299- jitCompPutImm32(w.dst, 0);
1300- j--;
1301- }
1302- }
1303- if (lastlabel >= 0 && label[lastlabel].p1 < w.dst){
1304- label[lastlabel].p1 = w.dst;
1305- }
1306- continue;
1307-
1308- case 0x3c: /* ENTER */
1309- jitCompA000_storeRegCacheAll(&w); // 手抜き.
1310- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1311- jitCompPutOp_PUSH_Imm8(w.dst, src[6]);
1312- jitCompPutOp_PUSH_Imm8(w.dst, src[5]);
1313- jitCompPutOp_PUSH_Imm8(w.dst, src[4] & 0x0f);
1314- jitCompPutOp_PUSH_Imm8(w.dst, (src[4] >> 4) & 0x0f);
1315- jitCompPutOp_PUSH_Imm8(w.dst, src[3]);
1316- jitCompPutOp_PUSH_Imm8(w.dst, src[2]);
1317- jitCompPutOp_PUSH_Imm8(w.dst, src[1]);
1318- jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP);
1319- j = ((unsigned char *)&func3c) - (w.dst + 1 + 4);
1320- jitCompPutOp_CALL_Relative(w.dst, j)
1321- jitCompPutOp_ADD_GReg_Imm8(w.dst, IA32_REG4_ESP, 32);
1322- jitCompA000_loadRegCacheAll(&w); // 手抜き.
1323- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1324- cmp0reg = -1;
1325- break;
1326-
1327- case 0x3d: /* LEAVE */
1328- jitCompA000_storeRegCacheAll(&w); // 手抜き.
1329- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1330- jitCompPutOp_PUSH_Imm8(w.dst, src[6]);
1331- jitCompPutOp_PUSH_Imm8(w.dst, src[5]);
1332- jitCompPutOp_PUSH_Imm8(w.dst, src[4] & 0x0f);
1333- jitCompPutOp_PUSH_Imm8(w.dst, (src[4] >> 4) & 0x0f);
1334- jitCompPutOp_PUSH_Imm8(w.dst, src[3]);
1335- jitCompPutOp_PUSH_Imm8(w.dst, src[2]);
1336- jitCompPutOp_PUSH_Imm8(w.dst, src[1]);
1337- jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP);
1338- j = ((unsigned char *)&func3d) - (w.dst + 1 + 4);
1339- jitCompPutOp_CALL_Relative(w.dst, j)
1340- jitCompPutOp_ADD_GReg_Imm8(w.dst, IA32_REG4_ESP, 32);
1341- jitCompA000_loadRegCacheAll(&w); // 手抜き.
1342- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1343- cmp0reg = -1;
1344- break;
1345-
1346- case 0xfe: /* remark */
1347- if (src[1] == 0x01 && src[2] == 0x00) {
1348- // DBGINFO1
1349- if (level <= JITC_LV_SLOWER) {
1350- jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1);
1351- jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX);
1352- }
1353- }
1354- if (src[1] == 0x01 && src[2] == 0x03) {
1355- // DBGINFO1CLR
1356- if (level <= JITC_LV_SLOWER) {
1357- jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, -1);
1358- jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX);
1359- }
1360- }
1361- if (src[1] == 0x05 && src[2] == 0x00) {
1362- // DBGINFO0
1363- if (level <= JITC_LV_SLOWEST) {
1364- debugInfo0 = jitCompGetImm32(src + 3);
1365- jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo0);
1366- jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO0, IA32_REG0_EAX);
1367- }
1368- }
1369- break;
1370-
1371- default:
1372- w.err = JITC_ERR_OPECODE;
1373- goto err_w;
1374- }
1375- if (w.err != 0){
1376- goto err_w;
1377- }
1378- jitCompA0001_fixPrefix(&w);
1379- if (w.err != 0) {
1380- goto err_w;
1381- }
1382-
1383- if(*src != 0x00 && *src != 0x01 && *src != 0x34){
1384- DEBUGCode(&w, 315315);
1385- }
1386-
1387- src += jitCompCmdLen(src);
1388- }
1389- if (enter0 != NULL) {
1390- j = w.dst - (enter0 + 4);
1391- enter0[0] = j & 0xff;
1392- enter0[1] = (j >> 8) & 0xff;
1393- enter0[2] = (j >> 16) & 0xff;
1394- enter0[3] = (j >> 24) & 0xff;
1395- }
1396- if ((flags & JITC_NOSTARTUP) == 0) {
1397- jitCompA000_storeRegCacheAll(&w);
1398- jitCompA000_storePRegCacheAll(&w);
1399- jitCompPutOp_POPAD(w.dst);
1400- }
1401- if ((flags & JITC_PHASE1) != 0){
1402- return w.dst - dst00;
1403- }
1404- return 0;
1405-
1406-err_w:
1407- if ((w.err & JITC_ERR_PHASE0ONLY) != 0) {
1408- if ((flags & JITC_PHASE1) == 0){
1409- w.err &= ~JITC_ERR_PHASE0ONLY;
1410- }
1411- }
1412- if (w.err == (JITC_ERR_MASK & JITC_ERR_REGNUM)) errmsg = "reg-number error";
1413- if (w.err == (JITC_ERR_MASK & JITC_ERR_DST1)) errmsg = "dst1 error";
1414- if (w.err == (JITC_ERR_MASK & JITC_ERR_OPECODE)) errmsg = "opecode error";
1415- if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELNUM)) errmsg = "label number too large";
1416- if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELREDEF)) errmsg = "label redefine";
1417- if (w.err == (JITC_ERR_MASK & JITC_ERR_PREFIX)) { errmsg = "prefix redefine"; w.dst -= 2; }
1418- if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELNODEF)) errmsg = "label not defined";
1419- if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELTYP)) errmsg = "label type error";
1420- if (w.err == (JITC_ERR_MASK & JITC_ERR_IDIOM)) errmsg = "idiom error";
1421- if (w.err == (JITC_ERR_MASK & JITC_ERR_PREGNUM)) errmsg = "preg-number error";
1422- if (w.err == (JITC_ERR_MASK & JITC_ERR_SRC1)) errmsg = "src1 error";
1423- if (w.err == (JITC_ERR_MASK & JITC_ERR_BADTYPE)) errmsg = "bad type code";
1424- if (w.err == (JITC_ERR_MASK & JITC_ERR_PREFIXFAR)) errmsg = "prefix internal error";
1425- if (w.err == (JITC_ERR_MASK & JITC_ERR_INTERNAL)) errmsg = "general internal error";
1426- if (*errmsg != '\0') {
1427- fprintf(stderr, "JITC: %s at %06X (debugInfo0=%d)\n ", errmsg, src - src0, debugInfo0);
1428- for (i = 0; i < 16; i++)
1429- fprintf(stderr, "%02X ", src[i]);
1430- static char *table[0x30] = {
1431- "NOP", "LB", "LIMM", "PLIMM", "CND", "??", "??", "??",
1432- "LMEM", "SMEM", "PLMEM", "PSMEM", "LEA", "??", "PADD", "PDIF",
1433- "CP/OR", "XOR", "AND", "??", "ADD", "SUB", "MUL", "??",
1434- "SHL", "SAR", "DIV", "MOD", "PLMT0", "PLMT1", "PCP", "PCST",
1435- "CMPE", "CMPNE", "CMPL", "CMPGE", "CMPLE", "CMPG", "TSTZ", "TSTNZ",
1436- "PCMPE", "PCMPNE", "PCMPL", "PCMPGE", "PCMPLE", "PCMPG", "??", "EXT" };
1437- errmsg = "??";
1438- if (*src < 0x30) errmsg = table[*src];
1439- fprintf(stderr, "(%s)\n", errmsg);
1440- }
1441- return -1;
1442-}
1443-
1444-unsigned char *jitCompCallFunc(unsigned char *dst, void *func)
1445-{
1446- //この関数の中では結局w->dstしか参照していない
1447- struct JitCompWork w;
1448- w.dst = dst;
1449- jitCompA000_storeRegCacheAll(&w);
1450- jitCompA000_storePRegCacheAll(&w);
1451- jitCompPutOp_PUSHAD(w.dst);
1452- jitCompPutOp_PUSH_GReg(w.dst, IA32_REG0_EAX); /* for 16Byte-align(Mac OSX) */
1453- jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP);
1454-
1455- int j = ((unsigned char *)func) - (w.dst + 1 + 4);
1456- jitCompPutOp_CALL_Relative(w.dst, j);
1457-
1458- jitCompPutOp_POP_GReg(w.dst, IA32_REG0_EAX);
1459- jitCompPutOp_POP_GReg(w.dst, IA32_REG0_EAX); /* for 16Byte-align (Mac OSX) */
1460- jitCompPutOp_POPAD(w.dst);
1461- jitCompA000_loadRegCacheAll(&w);
1462- jitCompA000_loadPRegCacheAll(&w);
1463- jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(0x30) + 0);
1464-
1465- jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */
1466- return w.dst;
1467-}
1468-
1469-unsigned char *jitCompInit(unsigned char *dst)
1470-{
1471- errfnc = dst;
1472- return jitCompCallFunc(dst, &errHndl);
1473-}
1474-
1475-void jitcRunBinary(void (*bin)(char *), HOSECPU_RuntimeEnvironment *env)
1476-{
1477- (*bin)(((char *)env) + jitCompA0001_EBP128); /* サイズを節約するためにEBPをjitCompA0001_EBP128バイトずらす */
1478- return;
1479-}
1480-
1481-void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0)
1482-{
1483- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1484- int i, *pi;
1485- HOSECPU_PointerRegisterEntry *pp;
1486-
1487- if (r->junkStack + 2048 > r->junkStack1) {
1488- (*(r->errHndl))(r);
1489- }
1490- pi = (void *)r->junkStack;
1491- r->junkStack += r1 * 4;
1492- for (i = 0; i < r1; i++){
1493- pi[i] = r->ireg[i];
1494- }
1495- pp = (void *)r->junkStack;
1496- r->junkStack += p1 * 32;
1497- for (i = 0; i < p1; i++){
1498- //pp[i] = r->preg[i];
1499- PRegCopy(&pp[i], &r->preg[i]);
1500- //
1501- }
1502- pp = (void *)r->junkStack;
1503- r->junkStack += 32;
1504- //*pp = r->preg[0x30];
1505- PRegCopy(pp, &r->preg[0x30]);
1506- //
1507- pi = (void *)r->junkStack;
1508- r->junkStack += 4;
1509- *pi = opt << 16 | r1 << 8 | p1;
1510- for (i = 0; i < lenR; i++){
1511- r->ireg[r0 + i] = r->ireg[0x30 + i];
1512- }
1513- for (i = 0; i < lenP; i++){
1514- r->preg[p0 + i] = r->preg[0x31 + i];
1515- }
1516- return;
1517-}
1518-
1519-void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0)
1520-{
1521- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1522- int i;
1523- r->junkStack -= 4;
1524- r->junkStack -= 32;
1525- HOSECPU_PointerRegisterEntry *pp = (void *)r->junkStack;
1526-
1527- //r->preg[0x30] = *pp;
1528- PRegCopy(&r->preg[0x30], pp);
1529- //
1530- r->junkStack -= p1 * 32; pp = (void *)r->junkStack;
1531- for (i = 0; i < p1; i++){
1532- //r->preg[i] = pp[i];
1533- PRegCopy(&r->preg[i], &pp[i]);
1534- //
1535- }
1536- r->junkStack -= r1 * 4; int *pi = (void *)r->junkStack;
1537- for (i = 0; i < r1; i++){
1538- r->ireg[i] = pi[i];
1539- }
1540- return;
1541-}
1542-
1543-void funcf4(char *ebp, int pxx, int typ, int len)
1544-{
1545- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1546- int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3;
1547- if (width < 0 || r->ireg[len] < 0){
1548- (*(r->errHndl))(r);
1549- }
1550- void *p = r->junkStack;
1551- if (r->junkStack + width * r->ireg[len] + 256 > r->junkStack1){
1552- (*(r->errHndl))(r);
1553- }
1554- r->junkStack += width * r->ireg[len];
1555- r->preg[pxx].p = p;
1556- r->preg[pxx].typ = r->ireg[typ];
1557- r->preg[pxx].p0 = p;
1558- r->preg[pxx].p1 = (void *)r->junkStack;
1559- int *pi = (int *)r->junkStack;
1560- *pi = width * r->ireg[len];
1561- r->junkStack += sizeof (int);
1562- if (r->ireg[typ] == 1) {
1563- int i, i1 = (width * r->ireg[len]) >> 2;
1564- pi = p;
1565- for (i = 0; i < i1; i++){
1566- pi[i] = 0;
1567- }
1568- }
1569- return;
1570-}
1571-
1572-void funcf5(char *ebp, int pxx, int typ, int len)
1573-{
1574- // pxxはダミーで参照されない
1575- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1576- r->junkStack -= sizeof (int);
1577- int *pi = (int *)r->junkStack;
1578- r->junkStack -= *pi;
1579-#if 0
1580- int width = jitCompA000_dataWidth(r->ireg[typ]);
1581- void *p = r->junkStack;
1582- r->junkStack -= width * r->ireg[len];
1583-#endif
1584- return;
1585-}
1586-
1587-void funcf6(char *ebp, int pxx, int typ, int len)
1588-{
1589- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1590- int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3;
1591- if (width < 0 || r->ireg[len] < 0){
1592- (*(r->errHndl))(r);
1593- }
1594- void *p = malloc(width * r->ireg[len]);
1595- r->preg[pxx].p = p;
1596- r->preg[pxx].typ = r->ireg[typ];
1597- r->preg[pxx].p0 = p;
1598- r->preg[pxx].p1 = (unsigned char *)p + width * r->ireg[len];
1599- if (r->ireg[typ] == 1) {
1600- int i, i1 = (width * r->ireg[len]) >> 2, *pi;
1601- pi = p;
1602- for (i = 0; i < i1; i++){
1603- pi[i] = 0;
1604- }
1605- for (i = 1; i < i1; i += 8){
1606- pi[i] |= -1;
1607- }
1608- }
1609- return;
1610-}
1611-
1612-void funcf7(char *ebp, int pxx, int typ, int len)
1613-{
1614- // typとlenはダミーで参照されない
1615- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1616- free(r->preg[pxx].p);
1617- return;
1618-}
1619-
1620-void errHndl(HOSECPU_RuntimeEnvironment *r)
1621-{
1622- r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - jitCompA0001_EBP128);
1623- (*(r->errHndl))(r);
1624- // ここに帰ってきてはいけない.
1625-}
1626-
1627-/*
1628- * jitcの出力コードをひとまとめにする関数を作成しその中身をjitCompile()で生成
1629- *
1630- * qq : 出力バイナリの書き込み位置のアドレスへの参照(書き込み位置を呼び出しに反映させるため参照渡しにする)
1631- * q1 : 出力バイナリの書き込み位置のアドレスの最大値
1632- * p0 : (*.ose)バイナリの読み込み位置のアドレス(ヘッダ部除去済)
1633- * p1 : (*.ose)バイナリの読み込み位置の取りうる最大値
1634- * (ただし、「確保したメモリ」の最大値なのでこれより手前にゴミデータが入っているかもしれない)
1635- * ret=1 : ヘッダのエラー
1636- * ret=2 : jitコンパイルエラー
1637- */
1638-int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label)
1639-{
1640- unsigned char *q = *qq;
1641- int i;
1642-
1643- if (p0[0] != 0x05 || p0[1] != SIGN1){
1644- // OSECPUのヘッダ (05E1) を確認
1645- return 1;
1646- }
1647-
1648- jitCompPutOp_PUSH_GReg(q, IA32_REG5_EBP);
1649-
1650- *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */
1651-
1652- for (i = 0; i < JITC_MAXLABELS; i++){
1653- label[i].opt = 0;
1654- }
1655-
1656- // 以下のjitCompile()呼び出しでは第二引数をq1-2にした方がよいのではないか?
1657- i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, 0); // ラベルのチェック
1658- if (i != 0){
1659- return 2;
1660- }
1661- i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, JITC_PHASE1 + 0);
1662- if (i < 0){
1663- return 2;
1664- }
1665- q += i;
1666-
1667- jitCompPutOp_POP_GReg(q, IA32_REG5_EBP);
1668- *q++ = 0xc3; /* RET(); */
1669- *qq = q;
1670- return 0;
1671-}
1672-
1673-#if (USE_DEBUGGER != 0)
1674-
1675-int dbgrGetRegNum(const char *p)
1676-{
1677- int i, j, r = -1;
1678- if (p[2] <= ' ') {
1679- i = p[0] - '0';
1680- j = p[1] - '0';
1681- if (i > 9){
1682- i -= 'A' - '0' - 10;
1683- }
1684- if (j > 9){
1685- j -= 'A' - '0' - 10;
1686- }
1687- if (0 <= i && i <= 15 && 0 <= j && j <= 15){
1688- r = i << 4 | j;
1689- }
1690- }
1691- return r;
1692-}
1693-
1694-void dbgrMain(HOSECPU_RuntimeEnvironment *r)
1695-{
1696- if (r->dbgr == 0){
1697- return;
1698- }
1699- for (;;) {
1700- char cmd[64], *p;
1701- int i, j, k;
1702-
1703- printf("\ndbgr>");
1704- p = fgets(cmd, 64, stdin);
1705- if (p == NULL){
1706- break;
1707- }
1708- if (cmd[0] == '\0'){
1709- continue;
1710- }
1711- if (cmd[0] == 'q' && cmd[1] <= ' '){
1712- break;
1713- }
1714- if (cmd[0] == 'p' && cmd[1] <= ' ' && cmd[1] != '\0') {
1715- p = &cmd[2];
1716- while (*p <= ' ' && *p != '\0'){
1717- p++;
1718- }
1719- if (*p == 'R') {
1720- i = dbgrGetRegNum(p + 1);
1721- if (0 <= i && i <= 0x3f) {
1722- printf("R%02X = 0x%08X = %d\n", i, r->ireg[i], r->ireg[i]);
1723- } else{
1724- puts("register name error");
1725- }
1726- continue;
1727- }
1728- if (*p == 'P') {
1729- i = dbgrGetRegNum(p + 1);
1730- if (0 <= i && i <= 0x3f) {
1731- p = "invalid";
1732- if (0 <= r->preg[i].typ && r->preg[i].typ <= 0x15) {
1733- static char *typName[] = {
1734- "T_CODE", "T_VPTR", "T_SINT8", "T_UINT8",
1735- "T_SINT16", "T_UINT16", "T_SINT32", "T_UINT32",
1736- "T_SINT4", "T_UINT4", "T_SINT2", "T_UINT2",
1737- "T_SINT1", "T_UINT1", "T_SINT12", "T_UINT12",
1738- "T_SINT20", "T_UINT20", "T_SINT24", "T_UINT24",
1739- "T_SINT28", "T_UINT28"
1740- };
1741- p = typName[r->preg[i].typ];
1742- }
1743- printf("P%02X:\n type = %s(%04X), (origin-ptr) = 0x%08X\n", i, p, r->preg[i].typ, (unsigned int)(r->preg[i].p0));
1744- if (r->preg[i].p != NULL && r->preg[i].p0 != NULL) {
1745- j = jitCompA000_dataWidth(jitCompA000_convTyp(r->preg[i].typ)) >> 3;
1746- if (j <= 0){
1747- j = 1;
1748- }
1749- k = (r->preg[i].p1 - r->preg[i].p0) / j;
1750- printf(" size = 0x%08X = %d\n", k, k);
1751- k = (r->preg[i].p - r->preg[i].p0) / j;
1752- printf(" pos = 0x%08X = %d\n", k, k);
1753- }
1754- else {
1755- puts(" null pointer");
1756- }
1757- }
1758- else
1759- puts("register name error");
1760- continue;
1761- }
1762- }
1763- puts("command error");
1764- }
1765- return;
1766-}
1767-
1768-#endif
1769-
1770-
1+#include "osecpu.h"
2+#include "jitc.h"
3+
4+#if (JITC_ARCNUM == 0x0001)
5+//
6+// for x86-32bit
7+//
8+
9+// F5の場合、decoderが対応するalloc-freeを結びつけるのが簡単で、typやlenを指定必須にしてもフロントエンドコードに影響はない.
10+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)
11+{
12+ // For IA-32 (x86, 32-bit)
13+ // 本来ならこのレイヤでは文法チェックしない
14+ //
15+ // dst : 現在の書き込みアドレス。
16+ // dst1 : 書き込みアドレスの最大値
17+ // src : 現在の読み込みアドレス(ヘッダ部は飛ばしてある
18+ // src1 : 読み込みアドレスの最大値
19+ // src0 : 読み込みバイナリのアドレス
20+ struct JitCompWork w;
21+ unsigned char *dst00 = dst, *enter0 = NULL, *tmp_ucp;
22+ char *errmsg = "";
23+ const unsigned char *oldsrc;
24+ int timecount = 0, i, j = 0, lastlabel = -1, debugInfo0 = -1;
25+ int reg0, reg1, reg2, cmp0reg = -1, cmp0lev = 0;
26+
27+ w.dst = w.dst0 = dst;
28+ w.err = 0;
29+ w.maxLabels = maxLabels;
30+
31+ if ((flags & JITC_NOSTARTUP) == 0) {
32+ jitCompPutOp_PUSHAD(w.dst);
33+ // Load cache
34+ jitCompA000_loadRegCacheAll(&w);
35+ jitCompA000_loadPRegCacheAll(&w);
36+ }
37+ if (level <= JITC_LV_SLOWER) {
38+ // env.debugInfo0 <- 0;
39+ // env.debugInfo1 <- debugInfo1;
40+ jitCompPutOp_MOV_EAX_ZERO(w.dst);
41+ jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO0, IA32_REG0_EAX);
42+ jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1);
43+ jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX);
44+ }
45+ while (src < src1) {
46+ w.prefix = 0; //0x04 CND 命令で変更される
47+ if (w.dst + 256 > dst1) {
48+ // 書き込み領域が残り256バイト未満ならエラー
49+ w.err = JITC_ERR_DST1;
50+ goto err_w;
51+ }
52+ timecount++;
53+ if (timecount >= 64) {
54+ timecount -= 64;
55+ /* 未完成(timeoutチェックコードを入れる) */
56+ }
57+#if ENABLE_DEBUG_CODE != 0
58+ if(*src != 0x00 && *src != 0x01 && *src != 0x34){
59+
60+ DEBUGCode(&w, *src);
61+ }
62+#endif
63+ prefix_continue:
64+ // CND命令コンパイル後ここに戻る
65+ switch (*src) {
66+ case 0x00:
67+ // NOP
68+ if (w.prefix != 0) {
69+ // 「条件付きでNOPを実行」するなんて、矛盾している!
70+ w.err = JITC_ERR_PREFIX;
71+ goto err_w;
72+ }
73+ break;
74+
75+ case 0x01:
76+ // LB : ラベル設置命令。(6byte)
77+ // ・prefex = 1にする
78+ // ・timecount++し、timecountのチェックをする。
79+ // ・ラベル位置を登録する。
80+ // ・割り込みがある場合、このタイミングで割り込みを発生させる。
81+ // Encode:
82+ // 0 1 2345
83+ // 01 opt imm32
84+ //
85+ if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) {
86+ //beginFunc()中のLB
87+ // LB命令の後に0x3C命令・・・beginFunc()
88+ enter0 = w.dst;
89+ jitCompPutOp_JMPnear(w.dst, 0);
90+ }
91+
92+ if (src[6] == 0x34) {
93+ // 後続命令はDATA
94+ // なので、DATA部分をJMPですっとばすコードを生成
95+ // DAT_SA0(label, typ32, length) ・・・メモリ確保命令
96+
97+ i = jitCompGetImm32(&src[6 + 1]); // type32 を取得
98+ j = 32;
99+
100+ if (i != 1) {
101+ i = jitCompA000_convTyp(i);
102+ j = 0;
103+ switch (i >> 1) {
104+ case 1:
105+ j = 1;
106+ break;
107+ case 2:
108+ j = 2;
109+ break;
110+ case 3:
111+ j = 4;
112+ break;
113+ }
114+ }
115+ // jはデータサイズになる
116+ j *= jitCompGetImm32(&src[6 + 5]); // len32
117+ if (j <= 0){
118+ w.err = JITC_ERR_BADTYPE;
119+ }
120+ // DATA部分を飛び越すジャンプ
121+ tmp_ucp = w.dst;
122+ jitCompPutOp_JMPnear(w.dst, j);
123+
124+#if (jitCompA0001_OPTIMIZE_JMP != 0)
125+ if (j < 127 - jitCompA0001_OPTIMIZE_ALIGN) {
126+ //飛び先が十分近いので
127+ // 今書いたのはなかったことにして、
128+ w.dst -= 5;
129+ // よりサイズの小さな書き方にする
130+ jitCompPutOp_JMPshort(w.dst, j);
131+ }
132+#endif
133+ }
134+#if (jitCompA0001_OPTIMIZE_ALIGN != 0)
135+ // アラインを jitCompA0001_OPTIMIZE_ALIGNにそろえる
136+
137+ i = ((int)w.dst + 1) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */
138+ i = jitCompA0001_OPTIMIZE_ALIGN - i;
139+ if (i == 1) { jitCompPutByte1(w.dst, 0x90); j += i; } /* NOP(); */
140+ if (i == 2) { jitCompPutByte2(w.dst, 0x89, 0xc0); j += i; } /* MOV(EAX, EAX); */
141+ if (i == 3) { jitCompPutByte3(w.dst, 0x8d, 0x76, 0x00); j += i; } /* LEA(ESI, [ESI+0]); */
142+ if (i == 4) { jitCompPutByte4(w.dst, 0x8d, 0x74, 0x26, 0x00); j += i; } /* LEA(ESI, [ESI*1+0]); */
143+ if (i == 5) { jitCompPutByte1(w.dst, 0x0d); jitCompPutImm32(w.dst, 0); j += i; } /* OR(EAX, 0); */
144+ if (i == 6) { jitCompPutByte2(w.dst, 0x8d, 0xb6); jitCompPutImm32(w.dst, 0); j += i; } /* LEA(ESI, [ESI+0]); */
145+ if (i == 7) { jitCompPutByte3(w.dst, 0x8d, 0xb4, 0x26); jitCompPutImm32(w.dst, 0); j += 7; } /* LEA(ESI, [ESI*1+0]); */
146+#endif
147+ if (src[6] == 0x34) {
148+ // 後続命令はDATA
149+ // パディングに合わせて一個前の相対ジャンプを修正
150+ tmp_ucp[1] = j & 0xff;
151+ if (*tmp_ucp == 0xe9) {
152+ // Near jump so imm is DWORD
153+ tmp_ucp[2] = (j >> 8) & 0xff;
154+ tmp_ucp[3] = (j >> 16) & 0xff;
155+ tmp_ucp[4] = (j >> 24) & 0xff;
156+ }
157+ }
158+ if ((flags & JITC_PHASE1) == 0) { // Phase 0ならば
159+ i = jitCompGetLabelNum(&w, src + 2);
160+ if (label[i].opt != 0 && w.err == 0) {
161+ w.err = JITC_ERR_LABELREDEF; // すでに同じ値のラベルがあればエラー
162+ goto err_w;
163+ }
164+ if (w.prefix != 0) { // CND命令の直後にラベルは設置できない
165+ w.err = JITC_ERR_PREFIX;
166+ goto err_w;
167+ }
168+ label[i].opt = src[1] + 1;
169+ label[i].typ = 0; /* TYP_CODE */
170+ label[i].p = w.dst;
171+ label[i].p1 = w.dst + 1;
172+ lastlabel = i;
173+ }
174+ cmp0reg = -1;
175+ timecount = 0;
176+ /* 未完成(timeoutチェックコードを入れる) */
177+ break;
178+
179+ case 0x02:
180+ // LIMM : 定数即値代入命令(6byte)
181+ // Encode:
182+ // 0 1 2345
183+ // 02 reg0R imm32
184+ //
185+ // reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。
186+
187+ if (src[1] == 0x3f && w.prefix != 0){
188+ // CND命令の直後でR3Fを書き換えるなんて変だよね
189+ w.err = JITC_ERR_PREFIX;
190+ }
191+
192+#if (jitCompA0001_USE_R3F_IMM32 != 0)
193+ if (src[1] == 0x3f) {
194+ // R3Fへの代入は例外で、 w.r3f を使用
195+ w.r3f = jitCompGetImm32(src + 2);
196+ break;
197+ }
198+#endif
199+ i = jitCompGetImm32(src + 2); // 与えられた即値(第二引数)を取得
200+ /* R00-R02 なら EBX, ECX, EDX 、それ以外なら EAX のレジスタIDを reg0 に代入 */
201+ reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
202+
203+#if (jitCompA0001_OPTIMIZE_MOV != 0)
204+ // size optimization
205+ // MOV reg, 0 -> XOR reg, reg
206+ if (i == 0) {
207+ jitCompPutOp_XOR_GReg_GReg(w.dst, reg0, reg0);
208+ jitCompA0001_movRxxEax(&w, src[1]);
209+ break;
210+ }
211+#endif
212+ /* reg0 のレジスタに対応したMOV命令を発行 */
213+ jitCompPutOp_MOV_GReg_Imm32(w.dst, reg0, i);
214+
215+ if (reg0 == 0){
216+ // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合
217+ jitCompA0001_movRxxEax(&w, src[1]);
218+ }
219+
220+ break;
221+
222+ case 0x03: /* 未完成(plsまで対応) */
223+ // PLIMM : ラベル番号代入命令(6byte)
224+ // Encode:
225+ // 0 1 2345
226+ // 03 PXX imm32
227+ //
228+ // ・P28 はAPI用
229+ // ・P30 はリターンアドレス
230+ // ・P3F はプログラムカウンタ
231+ //
232+
233+ i = jitCompGetLabelNum(&w, src + 2); // Pxxに代入するラベルの番号(第二引数)
234+ if ((flags & JITC_PHASE1) != 0 && w.err == 0) {
235+ // Phase 1であるならば
236+ if (label[i].opt == 0) {
237+ // 指定されたラベル番号は存在しない
238+ w.err = JITC_ERR_LABELNODEF;
239+ goto err_w;
240+ }
241+ if (src[1] != 0x3f && label[i].opt != 2) {
242+ // ?
243+ w.err = JITC_ERR_LABELTYP;
244+ goto err_w;
245+ }
246+ if (src[1] == 0x3f && label[i].typ != 0) {
247+ // プログラムカウンタに TYP_CODEでない値は代入できない
248+ w.err = JITC_ERR_LABELTYP;
249+ goto err_w;
250+ }
251+ }
252+ if (src[1] == 0x3f) {
253+ // プログラムカウンタへの代入
254+ if (w.prefix == 0) {
255+ // CND命令による条件付きでなければ、即座に移動
256+ jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */
257+ } else {
258+ // 直前はCND命令。
259+
260+ /*
261+ * CND命令
262+ * 1 2
263+ * 04 reg0R
264+ *
265+ * いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd
266+ */
267+
268+ // Jccの条件変更
269+ // 0F 75
270+ w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */
271+ w.dst[-2] = 0x0f;
272+
273+ w.prefix = 0;
274+ }
275+ j = 0;
276+ if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) // label番号iが確保されているか、Phase 1なら
277+ j = label[i].p - (w.dst + 4); // j はとび先の相対番地
278+ jitCompPutImm32(w.dst, j); // JMP もしくは JZ 命令のアドレス部を記述
279+#if (jitCompA0001_OPTIMIZE_JMP != 0)
280+ if (-128 - 3 <= j && j < 0) {
281+ if (w.dst[-5] == 0xe9) {
282+ j += 3;
283+ w.dst -= 5;
284+ jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */
285+ } else {
286+ j += 4;
287+ w.dst -= 6;
288+ jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0);
289+ }
290+ jitCompPutByte1(w.dst, j & 0xff);
291+ }
292+#endif
293+ } else { // プログラムカウンタ以外への代入
294+ // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定
295+ reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX);
296+ // ラベルのパスを各レジスタに代入
297+ jitCompPutOp_MOV_GReg_Imm32(w.dst, reg0, (int)label[i].p);
298+ // レジスタへの代入をメモリでエミュレーションする場合は、スタックに書き込む。
299+ if (reg0 == 0){
300+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 0, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
301+ }
302+
303+ if (level < JITC_LV_FASTEST) {
304+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 8, reg0); /* p0 */
305+ jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, label[i].typ);
306+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 4, IA32_REG0_EAX); /* typ */
307+ jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, (int)label[i].p1);
308+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 12, IA32_REG0_EAX); /* p1 */
309+ jitCompPutOp_MOV_EAX_ZERO(w.dst);
310+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 16, IA32_REG0_EAX); /* liveSign */
311+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, envOffset_PTRCTRL);
312+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 20, IA32_REG0_EAX); /* pls */
313+ }
314+ }
315+ break;
316+
317+ case 0x04:
318+ // CND (prefix)
319+ // 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。
320+
321+ if (src[1] >= 0x40){
322+ // R00-R3F 以外のレジスタは比較対象にできない
323+ w.err = JITC_ERR_REGNUM;
324+ goto err_w;
325+ }
326+
327+ // 比較対象のレジスタがメモリ上にあれば-1, それ以外なら適切なレジスタ番号を返す
328+ reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */);
329+
330+ /* TEST命令を発行 */
331+ if (reg0 < 0) {
332+ // 比較対象のレジスタはメモリ上にある
333+ jitCompPutByte1(w.dst, 0xf7); /* TEST = 1111 011w : mod 000 r/m : immediate data */
334+ jitCompPutModRM_Disp_BaseEBP(&w, src[1] * 4, 0);
335+ } else {
336+ // 比較対象はキャッシュレジスタ上にある
337+ jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST = 1111 011w : 11 000 reg : immediate data */
338+ }
339+ jitCompPutImm32(w.dst, 1);
340+
341+ /* JZ命令を発行 */
342+ jitCompPutByte2(w.dst, 0x74, 0x00); /* JZ($+2) */
343+ cmp0reg = -1;
344+ if (w.err != 0){
345+ goto err_w;
346+ }
347+ src += 2;
348+ w.prefix = 1; // プリフィックスをセット
349+ w.dst0 = w.dst;
350+ goto prefix_continue;
351+
352+ case 0x08: /* LMEM */ /* 完成 */
353+ i = jitCompGetImm32(src + 2);
354+ if (i == 0x0001){
355+ w.err = JITC_ERR_BADTYPE;
356+ }
357+ if (level < JITC_LV_FASTER) {
358+ jitCompA0001_checkType(&w, src[6], i, 0); // read
359+ cmp0reg = -1;
360+ }
361+ reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
362+ reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX);
363+ if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX){
364+ reg1 = IA32_REG0_EAX;
365+ }
366+ if (reg1 == IA32_REG2_EDX){
367+ jitCompA000_storeRegCacheEdx(&w);
368+ }
369+ if (reg1 <= 3 /* EAX, EDX */){
370+ jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6]));
371+ }
372+ if (level < JITC_LV_FASTER){
373+ jitCompA0001_checkLimit(&w, reg1, src[6]);
374+ }
375+ i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
376+ switch (i) {
377+ case 0x0002:
378+ jitCompPutByte3(w.dst, 0x0f, 0xbe, reg0 << 3 | reg1); /* MOVSX(reg0,BYTE [reg1]); */
379+ break;
380+ case 0x0003:
381+ jitCompPutByte3(w.dst, 0x0f, 0xb6, reg0 << 3 | reg1); /* MOVZX(reg0,BYTE [reg1]); */
382+ break;
383+ case 0x0004:
384+ jitCompPutByte3(w.dst, 0x0f, 0xbf, reg0 << 3 | reg1); /* MOVSX(reg0,WORD [reg1]); */
385+ break;
386+ case 0x0005:
387+ jitCompPutByte3(w.dst, 0x0f, 0xb7, reg0 << 3 | reg1); /* MOVZX(reg0,WORD [reg1]); */
388+ break;
389+ case 0x0006:
390+ case 0x0007:
391+ jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */
392+ break;
393+ default:
394+ w.err = JITC_ERR_BADTYPE;
395+ }
396+ if (reg0 == IA32_REG0_EAX){
397+ jitCompA0001_movRxxEax(&w, src[1]);
398+ }
399+ if (reg1 == IA32_REG2_EDX){
400+ jitCompA000_loadRegCacheEdx(&w);
401+ }
402+ break;
403+
404+ case 0x09: /* SMEM */ /* 完成 */
405+ i = jitCompGetImm32(src + 2);
406+ if (i == 0x0001){
407+ w.err = JITC_ERR_BADTYPE;
408+ }
409+ if (level < JITC_LV_FASTER) {
410+ jitCompA0001_checkType(&w, src[6], i, 1); // write
411+ cmp0reg = -1;
412+ }
413+ reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
414+ reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX);
415+ if (reg0 != IA32_REG0_EAX && reg1 == IA32_REG2_EDX){
416+ reg1 = IA32_REG0_EAX;
417+ }
418+ if (reg1 == IA32_REG2_EDX){
419+ jitCompA000_storeRegCacheEdx(&w);
420+ }
421+ if (reg1 <= 3 /* EAX, EDX */){
422+ jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6]) + 0); /* MOV(reg1, [EBP+?]); */
423+ }
424+ if (level < JITC_LV_FASTER){
425+ jitCompA0001_checkLimit(&w, reg1, src[6]);
426+ }
427+ if (reg0 == IA32_REG0_EAX){
428+ jitCompA0001_movEaxRxx(&w, src[1]);
429+ }
430+ /* 値の範囲チェック */
431+ i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
432+ switch (i) {
433+ case 0x0002:
434+ case 0x0003:
435+ jitCompPutByte2(w.dst, 0x88, reg0 << 3 | reg1); /* MOV([reg1], BYTE(reg0)); */
436+ break;
437+ case 0x0004:
438+ case 0x0005:
439+ jitCompPutByte3(w.dst, 0x66, 0x89, reg0 << 3 | reg1); /* MOV([reg1], WORD(reg0)); */
440+ break;
441+ case 0x0006:
442+ case 0x0007:
443+ jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */
444+ break;
445+ default:
446+ w.err = JITC_ERR_BADTYPE;
447+ }
448+ if (reg1 == IA32_REG2_EDX){
449+ jitCompA000_loadRegCacheEdx(&w);
450+ }
451+ break;
452+
453+ case 0x0a: /* PLMEM */ /* 完成 */
454+ i = jitCompGetImm32(src + 2);
455+ if (i != 0x0001){
456+ w.err = JITC_ERR_BADTYPE;
457+ }
458+ if (level < JITC_LV_FASTER) {
459+ jitCompA0001_checkType(&w, src[6], i, 0); // read
460+ cmp0reg = -1;
461+ }
462+ reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX);
463+ reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX);
464+ // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */
465+ // reg1 = 0; /* EAX */
466+ if (reg0 == reg1 && reg0 != 0) {
467+ // bugfix: hinted by yao, 2013.09.14. thanks!
468+ jitCompA000_storePRegCacheAll(&w);
469+ reg1 = IA32_REG2_EDX;
470+ }
471+ if (reg1 == IA32_REG2_EDX){
472+ jitCompA000_storeRegCacheEdx(&w);
473+ }
474+ if (reg1 <= 3 /* EAX, EDX */){
475+ jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6])); /* MOV(reg1, [EBP+?]); */
476+ }
477+ if (level < JITC_LV_FASTER){
478+ jitCompA0001_checkLimit(&w, reg1, src[6]);
479+ }
480+ jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */
481+ if (reg0 == IA32_REG0_EAX){
482+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]), IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
483+ }
484+ for (i = 4; i < 32; i += 4) {
485+ jitCompPutByte3(w.dst, 0x8b, 0x40 | reg1, i); /* MOV(EAX, [reg1+?]); */
486+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
487+ }
488+ if (reg1 == IA32_REG2_EDX){
489+ jitCompA000_loadRegCacheEdx(&w);
490+ }
491+ break;
492+
493+ case 0x0b: /* PSMEM */ /* 完成 */
494+ i = jitCompGetImm32(src + 2);
495+ if (i != 0x0001) w.err = JITC_ERR_BADTYPE;
496+ if (level < JITC_LV_FASTER) {
497+ jitCompA0001_checkType(&w, src[6], i, 1); // write
498+ cmp0reg = -1;
499+ }
500+ reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX);
501+ reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX);
502+ /* これをやってはいけない!(by K, 2013.08.02) */
503+ // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */)
504+ // reg1 = 0; /* EAX */
505+ if (reg1 == IA32_REG2_EDX){
506+ jitCompA000_storeRegCacheEdx(&w);
507+ }
508+ if (reg1 <= 3 /* EAX, EDX */){
509+ jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6])); /* MOV(reg1, [EBP+?]); */
510+ }
511+ if (level < JITC_LV_FASTER){
512+ jitCompA0001_checkLimit(&w, reg1, src[6]);
513+ }
514+ if (reg0 == IA32_REG0_EAX){
515+ jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[1])); /* MOV(reg0, [EBP+?]); */
516+ }
517+ jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */
518+ for (i = 4; i < 32; i += 4) {
519+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[1]) + i); /* MOV(EAX, [EBP+?]); */
520+ jitCompPutByte3(w.dst, 0x89, 0x40 | reg1, i); /* MOV([reg1+?], EAX); */
521+ }
522+ if (reg1 == IA32_REG2_EDX)
523+ jitCompA000_loadRegCacheEdx(&w);
524+ break;
525+
526+ case 0x0e: /* PADD */ /* 完成 */
527+ if (level < JITC_LV_FASTER) {
528+ jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 2), 2); // other, aliveテストはとりあえずしない.
529+ cmp0reg = -1;
530+ }
531+ reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX);
532+ reg1 = jitCompA000_selectPRegCache(src[6], -1 /* mem */);
533+ if (reg1 < 0 /* mem */){
534+ jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[6])); /* MOV(reg0, [EBP+?]); */
535+ }
536+ if (reg1 >= 0 && reg0 != reg1) {
537+ jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
538+ }
539+ i = jitCompGetImm32(src + 2);
540+ j = -1;
541+ if (i == 1){
542+ j = 5; /* 32 */
543+ } else {
544+ i = jitCompA000_convTyp(i);
545+ if (0x0002 <= i && i <= 0x0007){
546+ j = (i - 0x0002) >> 1;
547+ }
548+ }
549+ if (j < 0) {
550+ w.err = JITC_ERR_BADTYPE;
551+ goto err_w;
552+ }
553+#if (jitCompA0001_USE_R3F_IMM32 != 0)
554+ if (src[7] == 0x3f) {
555+ j = w.r3f << j;
556+#if (jitCompA0001_USE_R3F_IMM8 != 0)
557+ if (-0x80 <= j && j <= 0x7f) {
558+#if (jitCompA0001_USE_R3F_INCDEC != 0)
559+ if (j == 1) {
560+ /* INC */
561+ jitCompPutByte1(w.dst, 0x40 | reg0);
562+ goto padd1;
563+ }
564+ if (j == -1) {
565+ /* DEC */
566+ jitCompPutByte1(w.dst, 0x48 | reg0);
567+ goto padd1;
568+ }
569+#endif
570+ /* ADD(reg0, im8); */
571+ jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff);
572+ goto padd1;
573+ }
574+#endif
575+ if (reg0 == 0) {
576+ jitCompPutByte1(w.dst, 0x05); /* ADD(reg0, ?); */
577+ } else {
578+ jitCompPutByte2(w.dst, 0x81, 0xc0 | reg0); /* ADD(reg0, ?); */
579+ }
580+ jitCompPutImm32(w.dst, j);
581+ goto padd1;
582+ }
583+#endif
584+ if (src[7] >= 0x40){
585+ w.err = JITC_ERR_REGNUM;
586+ }
587+ if (j == 0) {
588+ reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */);
589+ if (reg1 >= 0) {
590+ jitCompPutByte2(w.dst, 0x01, 0xc0 | reg1 << 3 | reg0); /* ADD(reg0, reg1); */
591+ } else {
592+ jitCompPutByte1(w.dst, 0x03); /* ADD(reg0, [EBP+?]); */
593+ jitCompPutModRM_Disp_BaseEBP(&w, src[7] * 4, reg0);
594+ }
595+ }
596+ else {
597+ reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */);
598+ reg2 = IA32_REG2_EDX;
599+ jitCompA000_storeRegCacheEdx(&w);
600+ if (reg1 < 0){
601+ jitCompPutOp_MOV_GReg_EBPDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */
602+ }
603+ if (reg1 >= 0 && reg1 != reg2) {
604+ jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg2); /* MOV(reg2, reg1); */
605+ }
606+ jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg2, j); /* SHL(reg2, ?); */
607+ jitCompPutByte2(w.dst, 0x01, 0xc0 | reg2 << 3 | reg0); /* ADD(reg0, reg2); */
608+ jitCompA000_loadRegCacheEdx(&w);
609+ }
610+#if (jitCompA0001_USE_R3F_IMM32 != 0)
611+ padd1:
612+#endif
613+ if (reg0 == IA32_REG0_EAX){
614+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]), reg0); /* MOV([EBP+?], reg0); */
615+ }
616+ if (src[1] != src[6]) {
617+ for (i = 4; i < 32; i += 4) {
618+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */
619+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
620+ }
621+ }
622+ cmp0reg = -1;
623+ break;
624+
625+ case 0x0f: /* PDIF */ /* 未完成 */
626+ reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
627+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
628+ jitCompA0001_checkCompPtr(&w, src[6], src[7]);
629+ jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[6])); /* MOV(reg0, [EBP+?]); */
630+ jitCompPutByte1(w.dst, 0x2b); /* SUB(EAX, [EBP+?]); */
631+ jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[7]) + 0, reg0);
632+ i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
633+ j = -1;
634+ if (0x0002 <= i && i <= 0x0007){
635+ j = (i - 0x0002) >> 1;
636+ }
637+ if (j < 0) {
638+ w.err = JITC_ERR_BADTYPE;
639+ goto err_w;
640+ }
641+ if (j > 0) {
642+ jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, j); /* SAR(reg0,?); */
643+ }
644+ if (reg0 == IA32_REG0_EAX){
645+ jitCompA0001_movRxxEax(&w, src[1]);
646+ }
647+ cmp0reg = src[1];
648+ cmp0lev = 1;
649+ break;
650+
651+ case 0x10: /* OR */
652+ case 0x11: /* XOR */
653+ case 0x12: /* AND */
654+ case 0x14: /* ADD */
655+ case 0x15: /* SUB */
656+ case 0x16: /* MUL */
657+ if (src[1] >= 0x3f){
658+ w.err = JITC_ERR_REGNUM;
659+ }
660+ reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
661+ reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */);
662+#if (jitCompA0001_USE_R3F_IMM32 != 0)
663+ if (src[2] == 0x3f) { // SUBのみ該当.
664+ if (*src != 0x15){
665+ w.err = JITC_ERR_REGNUM;
666+ }
667+ reg2 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
668+ if (reg2 >= 0){
669+ jitCompA000_storeRegCacheAll(&w);
670+ }
671+ jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */
672+ jitCompPutImm32(w.dst, w.r3f);
673+ jitCompPutByte1(w.dst, 0x2b);
674+ jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0);
675+ if (reg0 == 0){
676+ jitCompA0001_movRxxEax(&w, src[1]);
677+ }
678+ break;
679+ }
680+#endif
681+ if (reg1 < 0) {
682+ jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, src[2] * 4); /* MOV(reg0, [EBP+?]); */
683+ }
684+ if (reg1 >= 0 && reg0 != reg1) {
685+ jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
686+ }
687+ if (!(src[0] == 0x10 && src[3] == 0xff)) {
688+ // bugfix: hinted by Iris, 2013.06.26. thanks!
689+ cmp0reg = src[1];
690+ cmp0lev = 1;
691+ if (src[0] < 0x14){
692+ cmp0lev = 2;
693+ }
694+ if (src[0] == 0x16){
695+ cmp0reg = -1;
696+ }
697+ }
698+ if (!(src[0] == 0x10 && src[3] == 0xff)) {
699+#if (jitCompA0001_USE_R3F_IMM32 != 0)
700+ if (src[3] == 0x3f) {
701+ if (*src == 0x16 && w.r3f == -1) {
702+ jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */
703+ if (reg0 == 0){
704+ jitCompA0001_movRxxEax(&w, src[1]);
705+ }
706+ break;
707+ }
708+#if (jitCompA0001_USE_R3F_INCDEC != 0)
709+ if ((*src == 0x14 && w.r3f == 1) || (*src == 0x15 && w.r3f == -1)) {
710+ jitCompPutByte1(w.dst, 0x40 | reg0); /* INC(reg0); */
711+ if (reg0 == 0){
712+ jitCompA0001_movRxxEax(&w, src[1]);
713+ }
714+ break;
715+ }
716+ if ((*src == 0x15 && w.r3f == 1) || (*src == 0x14 && w.r3f == -1)) {
717+ jitCompPutByte1(w.dst, 0x48 | reg0); /* DEC(reg0); */
718+ if (reg0 == 0){
719+ jitCompA0001_movRxxEax(&w, src[1]);
720+ }
721+ break;
722+ }
723+#endif
724+#if (jitCompA0001_USE_R3F_IMM8 != 0)
725+ if (-0x80 <= w.r3f && w.r3f <= 0x7f) {
726+ if (*src != 0x16) {
727+ static unsigned char basic_op_table_im8[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 };
728+ jitCompPutByte3(w.dst, 0x83, basic_op_table_im8[*src - 0x10] | reg0, w.r3f & 0xff);
729+ } else{
730+ jitCompPutByte3(w.dst, 0x6b, 0xc0 | reg0 << 3 | reg0, w.r3f & 0xff);
731+ }
732+ if (reg0 == 0){
733+ jitCompA0001_movRxxEax(&w, src[1]);
734+ }
735+ break;
736+ }
737+#endif
738+ if (reg0 == IA32_REG0_EAX) {
739+ static unsigned char basic_op_table_im32_eax[] = { 0x0d, 0x35, 0x25, 0, 0x05, 0x2d, 0xc0 };
740+ if (*src == 0x16) {
741+ jitCompPutByte1(w.dst, 0x69);
742+ }
743+ jitCompPutByte1(w.dst, basic_op_table_im32_eax[*src - 0x10]);
744+ } else{
745+ if (*src != 0x16) {
746+ static unsigned char basic_op_table_im32_reg[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 };
747+ jitCompPutByte2(w.dst, 0x81, basic_op_table_im32_reg[*src - 0x10] | reg0);
748+ }
749+ else {
750+ jitCompPutByte2(w.dst, 0x69, 0xc0 | reg0 << 3 | reg0);
751+ }
752+ }
753+ jitCompPutImm32(w.dst, w.r3f);
754+ if (reg0 == 0){
755+ jitCompA0001_movRxxEax(&w, src[1]);
756+ }
757+ break;
758+ }
759+#endif
760+ reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
761+ if (src[3] >= 0x40){
762+ w.err = JITC_ERR_REGNUM;
763+ }
764+ if (*src != 0x16) {
765+ if (reg1 >= 0) {
766+ static unsigned char basic_op_table_rr[] = { 0x09, 0x31, 0x21, 0, 0x01, 0x29 }; /* op(reg,reg); */
767+ jitCompPutByte2(w.dst, basic_op_table_rr[*src - 0x10], 0xc0 | reg1 << 3 | reg0);
768+ } else{
769+ static unsigned char basic_op_table_rm[] = { 0x0b, 0x33, 0x23, 0, 0x03, 0x2b, 0xaf }; /* op(reg,mem); */
770+ jitCompPutByte1(w.dst, basic_op_table_rm[*src - 0x10]);
771+ jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0);
772+ }
773+ } else{
774+ if (reg1 >= 0) {
775+ jitCompPutByte3(w.dst, 0x0f, 0xaf, 0xc0 | reg0 << 3 | reg1);
776+ } else{
777+ jitCompPutByte2(w.dst, 0x0f, 0xaf);
778+ jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0);
779+ }
780+ }
781+ }
782+ if (reg0 == 0){
783+ jitCompA0001_movRxxEax(&w, src[1]);
784+ }
785+ break;
786+
787+ case 0x18: /* SHL */
788+ case 0x19: /* SAR */
789+ if (src[1] >= 0x3f){
790+ w.err = JITC_ERR_REGNUM;
791+ }
792+ if (src[3] >= 0x40){
793+ w.err = JITC_ERR_REGNUM;
794+ }
795+#if (jitCompA0001_USE_R3F_IMM32 != 0)
796+ if (src[3] == 0x3f) {
797+ reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
798+ reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */);
799+ if (src[1] >= 0x3f){
800+ w.err = JITC_ERR_REGNUM;
801+ }
802+ if (reg1 == -1){
803+ jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, src[2] * 4); /* MOV(reg1, [EBP+?]); */
804+ } else{
805+ if (reg0 != reg1) {
806+ jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
807+ }
808+ }
809+ if (*src == 0x18) {
810+ /* SHL(reg0, im8); */
811+ jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f);
812+ }
813+ if (*src == 0x19) {
814+ /* SAR(reg0, im8); */
815+ jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f);
816+ }
817+ if (reg0 == IA32_REG0_EAX){
818+ jitCompA0001_movRxxEax(&w, src[1]);
819+ }
820+ cmp0reg = src[1];
821+ cmp0lev = 1;
822+ break;
823+ }
824+#endif
825+ jitCompA000_storeRegCacheAll(&w); // 手抜き.
826+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */
827+#if (jitCompA0001_USE_R3F_IMM32 != 0)
828+ if (src[2] == 0x3f) {
829+ jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
830+ jitCompPutImm32(w.dst, w.r3f);
831+ } else{
832+ jitCompA0001_movEaxRxx(&w, src[2]);
833+ }
834+#else
835+ jitCompA0001_movEaxRxx(&w, src[2]);
836+#endif
837+ if (*src == 0x18) {
838+ /* SHL(EAX, CL); */
839+ jitCompPutByte2(w.dst, 0xd3, 0xe0);
840+ }
841+ if (*src == 0x19) {
842+ /* SAR(EAX, CL); */
843+ jitCompPutByte2(w.dst, 0xd3, 0xf8);
844+ }
845+ jitCompA0001_movRxxEax(&w, src[1]);
846+ jitCompA000_loadRegCacheAll(&w); // 手抜き.
847+ cmp0reg = src[1];
848+ cmp0lev = 1;
849+ break;
850+
851+ case 0x1a: /* DIV */
852+ case 0x1b: /* MOD */
853+ if (src[1] >= 0x3f || src[2] >= 0x40 || src[3] >= 0x40){
854+ w.err = JITC_ERR_REGNUM;
855+ }
856+ jitCompA000_storeRegCacheAll(&w); // 手抜き.
857+#if (jitCompA0001_USE_R3F_IMM32 != 0)
858+ if (src[3] == 0x3f) {
859+ jitCompPutByte1(w.dst, 0xb8 | 1); /* MOV(ECX, ?); */
860+ jitCompPutImm32(w.dst, w.r3f);
861+ } else{
862+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */
863+ }
864+ if (src[2] == 0x3f) {
865+ jitCompPutByte1(w.dst, 0xb8 | 0); /* MOV(EAX, ?); */
866+ jitCompPutImm32(w.dst, w.r3f);
867+ } else{
868+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, src[2] * 4); /* MOV(EAX, [EBP+?]); */
869+ }
870+#else
871+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */
872+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, src[2] * 4); /* MOV(EAX, [EBP+?]); */
873+#endif
874+ jitCompPutByte1(w.dst, 0x99); /* CDQ(); */
875+ /* ECXがゼロではないことを確認すべき */
876+ jitCompPutByte2(w.dst, 0xf7, 0xf9); /* IDIV(ECX); */
877+ if (*src == 0x1a) {
878+ jitCompPutOp_MOV_EBPDisp_GReg(&w, src[1] * 4, IA32_REG0_EAX);
879+ }
880+ if (*src == 0x1b) {
881+ jitCompPutOp_MOV_EBPDisp_GReg(&w, src[1] * 4, IA32_REG2_EDX);
882+ }
883+ jitCompA000_loadRegCacheAll(&w); // 手抜き.
884+ cmp0reg = -1;
885+ break;
886+
887+ case 0x1c: /* PLMT0 */
888+ case 0x1d: /* PLMT1 */
889+ if (src[1] >= 0x40 || src[2] >= 0x40){
890+ w.err = JITC_ERR_PREGNUM;
891+ }
892+ if (level < JITC_LV_FASTEST) {
893+ cmp0reg = -1;
894+ if (level < JITC_LV_FASTER) {
895+ // typ が一致していることを確認.
896+ // plsとliveSignが一致していることを確認.
897+
898+ // preg1はp0 <= p <= p1 を満たしているか?.
899+ // 新しいp0/p1は古いp0?p1に適合しているか?.
900+
901+ }
902+ }
903+
904+ case 0x1e: /* PCP */ /* 未完成(p1まで完成) */
905+ if (src[1] >= 0x40 || src[2] >= 0x40){
906+ w.err = JITC_ERR_PREGNUM;
907+ }
908+ if (src[2] == 0x3f){
909+ w.err = JITC_ERR_PREGNUM;
910+ }
911+ if (src[1] != 0x3f) {
912+ /* src[2] == 0xff の場合に対応できてない */
913+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
914+ for (i = 0; i < 32; i += 4) {
915+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + i); /* MOV(EAX, [EBP+?]); */
916+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
917+ }
918+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
919+ } else {
920+ if (level < JITC_LV_FASTER) {
921+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + 4); /* MOV(EAX, [EBP+?]); */ /* typ */
922+ jitCompPutByte3(w.dst, 0x83, 0xf8, 0); /* CMP(EAX, 0); */
923+ jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */
924+ jitCompPutImm32(w.dst, errfnc - (w.dst + 4));
925+ /* セキュリティチェックが足りてない!(aliveとか) */
926+ }
927+ reg0 = IA32_REG0_EAX;
928+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
929+ jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[2]) + 0); /* MOV(EAX, [EBP+?]); */
930+ if (level < JITC_LV_FASTER) {
931+ jitCompPutByte1(w.dst, 0x3b); /* CMP(reg0, [EBP+?]); */
932+ jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[2]) + 8, reg0); /* p0 */
933+ jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */
934+ jitCompPutImm32(w.dst, errfnc - (w.dst + 4));
935+ }
936+ jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */
937+ }
938+ break;
939+
940+ case 0x1f: /* PCST */
941+ if (jitCompGetImm32(src + 2) == 0) {
942+ if (level < JITC_LV_FASTER){
943+ jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 7), 2);
944+ }
945+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
946+ for (i = 0; i < 32 - 4; i += 4) {
947+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */
948+ if (i == 4) {
949+ jitCompPutByte1(w.dst, 0x0d); /* OR(EAX, ?); */
950+ jitCompPutImm32(w.dst, 0x80000000);
951+ }
952+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
953+ }
954+ jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1);
955+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 28, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
956+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
957+ cmp0reg = -1;
958+ break;
959+ }
960+ if (jitCompGetImm32(src + 7) == 0) {
961+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
962+ for (i = 0; i < 32 - 4; i += 4) {
963+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */
964+ if (i == 4) {
965+ jitCompPutByte1(w.dst, 0x25); /* AND(EAX, ?); */
966+ jitCompPutImm32(w.dst, 0x7fffffff);
967+ }
968+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
969+ }
970+ if (level < JITC_LV_FASTER) {
971+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + 28); /* MOV(EAX, [EBP+?]); */
972+ jitCompPutByte1(w.dst, 0x3d); /* CMP(EAX, ?); */
973+ jitCompPutImm32(w.dst, debugInfo1);
974+ jitCompPutByte2(w.dst, 0x74, 8); /* JE */
975+ jitCompPutOp_MOV_EAX_ZERO(w.dst);
976+ jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + 0, IA32_REG0_EAX); /* MOV([EBP+?], EAX); (1+1+4) */
977+ }
978+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
979+ cmp0reg = -1;
980+ break;
981+ }
982+ w.err = JITC_ERR_OPECODE;
983+ goto err_w;
984+
985+ case 0x20: /* CMPE */
986+ case 0x21: /* CMPNE */
987+ case 0x22: /* CMPL */
988+ case 0x23: /* CMPGE */
989+ case 0x24: /* CMPLE */
990+ case 0x25: /* CMPG */
991+ case 0x26: /* TSTZ */
992+ case 0x27: /* TSTNZ */
993+ reg0 = jitCompA000_selectRegCache(src[2], IA32_REG0_EAX);
994+ reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
995+ if (src[1] == 0x3f) {
996+ /* 特殊構文チェック */
997+ if (w.prefix != 0) {
998+ w.err = JITC_ERR_PREFIX;
999+ goto err_w;
1000+ }
1001+ if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) {
1002+ w.err = JITC_ERR_IDIOM;
1003+ goto err_w;
1004+ }
1005+ }
1006+ if (reg0 == 0)
1007+ jitCompA0001_movEaxRxx(&w, src[2]);
1008+#if (jitCompA0001_USE_R3F_IMM32 != 0)
1009+ if (src[3] == 0x3f) {
1010+#if (jitCompA0001_OPTIMIZE_CMP != 0)
1011+ if ((*src <= 0x25 && w.r3f == 0) || (*src >= 0x26 && w.r3f == -1)) {
1012+ i = 0;
1013+ if (cmp0reg == src[2]) {
1014+ if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27)){
1015+ i = 1;
1016+ }
1017+ if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25)){
1018+ i = 1;
1019+ }
1020+ }
1021+ if (i == 0) {
1022+ jitCompPutByte2(w.dst, 0x85, 0xc0 | reg0 << 3 | reg0); /* TEST(reg0, reg0); */
1023+ }
1024+ cmp0reg = src[2];
1025+ cmp0lev = 2;
1026+ goto cmpcc1;
1027+ }
1028+#endif
1029+#if (jitCompA0001_USE_R3F_IMM8 != 0)
1030+ if (-0x80 <= w.r3f && w.r3f <= 0x7f && *src <= 0x25) {
1031+ jitCompPutByte3(w.dst, 0x83, 0xf8 | reg0, w.r3f);
1032+ goto cmpcc1;
1033+ }
1034+#endif
1035+ if (reg0 == 0) {
1036+ if (*src <= 0x25) {
1037+ jitCompPutByte1(w.dst, 0x3d);
1038+ }
1039+ if (*src >= 0x26) {
1040+ jitCompPutByte1(w.dst, 0xa9);
1041+ }
1042+ }
1043+ else {
1044+ if (*src <= 0x25) {
1045+ jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0);
1046+ }
1047+ if (*src >= 0x26) {
1048+ jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0);
1049+ }
1050+ }
1051+ jitCompPutImm32(w.dst, w.r3f);
1052+ goto cmpcc1;
1053+ }
1054+#endif
1055+ if (src[3] >= 0x40){
1056+ w.err = JITC_ERR_PREGNUM;
1057+ }
1058+ if (reg1 >= 0) {
1059+ if (*src <= 0x25) {
1060+ jitCompPutByte2(w.dst, 0x39, 0xc0 | reg1 << 3 | reg0);
1061+ }
1062+ if (*src >= 0x26) {
1063+ jitCompPutByte2(w.dst, 0x85, 0xc0 | reg1 << 3 | reg0);
1064+ }
1065+ } else{
1066+ if (*src <= 0x25) {
1067+ jitCompPutByte1(w.dst, 0x3b);
1068+ }
1069+ if (*src >= 0x26) {
1070+ jitCompPutByte1(w.dst, 0x85);
1071+ }
1072+ jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0);
1073+ }
1074+ cmpcc1:
1075+ if (w.err != 0){
1076+ goto err_w;
1077+ }
1078+ static unsigned char cmpcc_table0[] = {
1079+ 0x04, 0x05, 0x0c, 0x0d, 0x0e, 0x0f, 0x04, 0x05, /* CMPcc, TSTcc */
1080+ 0x04, 0x05, 0x02, 0x03, 0x06, 0x07 /* PCMPcc */
1081+ };
1082+#if (jitCompA0001_USE_R3F_CMPJMP != 0)
1083+ if (src[1] == 0x3f) {
1084+ /* 特殊構文を利用した最適化 */
1085+ jitCompPutByte2(w.dst, 0x0f, 0x80 | cmpcc_table0[*src - 0x20]);
1086+ src += 6;
1087+ i = jitCompGetLabelNum(&w, src + 2);
1088+ if ((flags & JITC_PHASE1) != 0 && w.err != 0) {
1089+ if (label[i].opt == 0) {
1090+ w.err = JITC_ERR_LABELNODEF;
1091+ goto err_w;
1092+ }
1093+ // if (label[i].typ != 1) { w.err = JITC_ERR_LABELTYP; goto err_w; }
1094+ }
1095+ j = 0;
1096+ if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)){
1097+ j = label[i].p - (w.dst + 4);
1098+ }
1099+ jitCompPutImm32(w.dst, j);
1100+#if (jitCompA0001_OPTIMIZE_JMP != 0)
1101+ if (-128 - 4 <= j && j < 0) {
1102+ j += 4;
1103+ w.dst -= 6;
1104+ jitCompPutByte2(w.dst, w.dst[1] ^ 0xf0, j & 0xff);
1105+ }
1106+#endif
1107+ src += 6;
1108+ if (w.err != 0){
1109+ goto err_w;
1110+ }
1111+ continue;
1112+ }
1113+#endif
1114+ /* 一般的なJITC */
1115+ reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
1116+ jitCompPutByte3(w.dst, 0x0f, 0x90 | cmpcc_table0[*src - 0x20], 0xc0 | reg0); /* SETcc(BYTE(reg0)); */
1117+ jitCompPutByte3(w.dst, 0x0f, 0xb6, 0xc0 | reg0 << 3 | reg0); /* MOVZX(reg0, BYTE(reg0)); */
1118+ jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */
1119+ if (reg0 == 0){
1120+ jitCompA0001_movRxxEax(&w, src[1]);
1121+ }
1122+ cmp0reg = src[2];
1123+ cmp0lev = 1;
1124+ break;
1125+
1126+ case 0x28: /* PCMPE */
1127+ case 0x29: /* PCMPNE */
1128+ case 0x2a: /* PCMPL */
1129+ case 0x2b: /* PCMPGE */
1130+ case 0x2c: /* PCMPLE */
1131+ case 0x2d: /* PCMPG */
1132+ if (src[1] == 0x3f) {
1133+ /* 特殊構文チェック */
1134+ if (w.prefix != 0) {
1135+ w.err = JITC_ERR_PREFIX;
1136+ goto err_w;
1137+ }
1138+ if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) {
1139+ w.err = JITC_ERR_IDIOM;
1140+ goto err_w;
1141+ }
1142+ }
1143+ if (src[2] >= 0x40) {
1144+ w.err = JITC_ERR_PREGNUM;
1145+ }
1146+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1147+ if (src[3] != 0xff){
1148+ jitCompA0001_checkCompPtr(&w, src[2], src[3]);
1149+ }
1150+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + 0); /* MOV(EAX, [EBP+?]); */
1151+ if (src[3] != 0xff) {
1152+ jitCompPutByte1(w.dst, 0x3b); /* CMP(EAX, [EBP+?]); */
1153+ jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[3]) + 0, 0);
1154+ } else{
1155+ /* ヌルポインタとの比較はこれでいいのか?たぶんよくない */
1156+ jitCompPutByte3(w.dst, 0x83, 0xf8, 0x00); /* CMP(EAX, 0); */
1157+ }
1158+ cmp0reg = -1;
1159+ goto cmpcc1;
1160+
1161+ case 0x30: /* talloc(old:F4) */
1162+ case 0x31: /* tfree(old:F5) */
1163+ case 0x32: /* malloc(old:F6) */
1164+ case 0x33: /* mfree(old:F7) */
1165+ jitCompA000_storeRegCacheAll(&w); // 手抜き.
1166+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1167+
1168+ jitCompPutOp_PUSH_Imm8(w.dst, src[3]);
1169+ jitCompPutOp_PUSH_Imm8(w.dst, src[2]);
1170+ jitCompPutOp_PUSH_Imm8(w.dst, src[1]);
1171+ jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP);
1172+
1173+ switch (*src) {
1174+ case 0x30:
1175+ j = ((unsigned char *)&funcf4) - (w.dst + 1 + 4);
1176+ break;
1177+ case 0x31:
1178+ j = ((unsigned char *)&funcf5) - (w.dst + 1 + 4);
1179+ break;
1180+ case 0x32:
1181+ j = ((unsigned char *)&funcf6) - (w.dst + 1 + 4);
1182+ break;
1183+ case 0x33:
1184+ j = ((unsigned char *)&funcf7) - (w.dst + 1 + 4);
1185+ break;
1186+ }
1187+ jitCompPutOp_CALL_Relative(w.dst, j);
1188+ jitCompPutOp_ADD_GReg_Imm8(w.dst, IA32_REG4_ESP, 16);
1189+
1190+ jitCompA000_loadRegCacheAll(&w); // 手抜き.
1191+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1192+ cmp0reg = -1;
1193+ break;
1194+
1195+ case 0x34: /* data (暫定) */
1196+ // 0 1234 5678 9
1197+ // 34 typ32 len32 data...
1198+ // len32 is NOT byte size!
1199+
1200+ cmp0reg = -1;
1201+ if (w.prefix != 0) {
1202+ w.err = JITC_ERR_PREFIX;
1203+ goto err_w;
1204+ }
1205+ int k, tmpData, bitCount, dataWidth;
1206+ // kはtyp32
1207+ k = jitCompGetImm32(&src[1]);
1208+ dataWidth = jitCompA000_dataWidth(k);
1209+ if (lastlabel >= 0 && label[lastlabel].typ == 0){
1210+ //直前のラベルタイプを設定
1211+ label[lastlabel].typ = k;
1212+ }
1213+ if (k != 1) {
1214+ i = jitCompA000_convTyp(k);
1215+ if (i < 2 || i > 7) {
1216+ w.err = JITC_ERR_BADTYPE;
1217+ goto err_w;
1218+ }
1219+ }
1220+ // jはlen32
1221+ j = jitCompGetImm32(&src[5]);
1222+ oldsrc = src;
1223+ src += 9;
1224+
1225+ // srcはdata本体を指す
1226+ if (k != 1) {
1227+ // 一般データ
1228+ bitCount = 7;
1229+ while (j > 0) {
1230+ if (src >= src1) {
1231+ // バイトコードを末端を超えて読もうとした
1232+ w.err = JITC_ERR_SRC1;
1233+ src = oldsrc;
1234+ goto err_w;
1235+ }
1236+ if (w.dst + 256 > dst1) {
1237+ // 書き込み先の残り容量が256Bytesを切った
1238+ w.err = JITC_ERR_DST1;
1239+ src = oldsrc;
1240+ goto err_w;
1241+ }
1242+ tmpData = 0;
1243+ for (k = 0; k < dataWidth; k++) {
1244+ // dataWidthビットごとに切り出してtmpDataに入れる
1245+ tmpData = tmpData << 1 | ((*src >> bitCount) & 1);
1246+ bitCount--;
1247+ if (bitCount < 0) {
1248+ bitCount = 7;
1249+ src++;
1250+ }
1251+ }
1252+ if ((i & 1) == 0 && dataWidth <= 31 && (tmpData >> (dataWidth - 1)) != 0) {
1253+ // 符号あり型で、かつtmpDataの符号ビットが1なので、マイナスにする
1254+ tmpData -= 1 << dataWidth;
1255+ }
1256+ if (i == 2 || i == 3) {
1257+ // BYTE
1258+ jitCompPutByte1(w.dst, tmpData & 0xff);
1259+ }
1260+ if (i == 4 || i == 5) {
1261+ // WORD
1262+ jitCompPutByte2(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff);
1263+ }
1264+ if (i == 6 || i == 7) {
1265+ // DWORD
1266+ jitCompPutByte4(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff, (tmpData >> 16) & 0xff, (tmpData >> 24) & 0xff);
1267+ }
1268+ j--;
1269+ }
1270+ } else{
1271+ // VPtr型
1272+ while (j > 0) {
1273+ if (src >= src1) {
1274+ // バイトコードを末端を超えて読もうとした
1275+ w.err = JITC_ERR_SRC1;
1276+ src = oldsrc;
1277+ goto err_w;
1278+ }
1279+ if (w.dst + 256 > dst1) {
1280+ // 書き込み先の残り容量が256Bytesを切った
1281+ w.err = JITC_ERR_DST1;
1282+ src = oldsrc;
1283+ goto err_w;
1284+ }
1285+ i = jitCompGetImm32(src);
1286+ src += 4;
1287+ if ((flags & JITC_PHASE1) != 0 && w.err == 0) {
1288+ // Only in phase1
1289+ if (label[i].opt == 0) {
1290+ // ローカルラベルはだめです...
1291+ w.err = JITC_ERR_LABELNODEF;
1292+ goto err_w;
1293+ }
1294+ }
1295+ jitCompPutImm32(w.dst, (int)label[i].p);
1296+ jitCompPutImm32(w.dst, label[i].typ);
1297+ jitCompPutImm32(w.dst, (int)label[i].p);
1298+ jitCompPutImm32(w.dst, (int)label[i].p1);
1299+ jitCompPutImm32(w.dst, 0); /* liveSign */
1300+ jitCompPutImm32(w.dst, envOffset_PTRCTRL); /* pls */
1301+ jitCompPutImm32(w.dst, 0);
1302+ jitCompPutImm32(w.dst, 0);
1303+ j--;
1304+ }
1305+ }
1306+ if (lastlabel >= 0 && label[lastlabel].p1 < w.dst){
1307+ label[lastlabel].p1 = w.dst;
1308+ }
1309+ continue;
1310+
1311+ case 0x3c: /* ENTER */
1312+ jitCompA000_storeRegCacheAll(&w); // 手抜き.
1313+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1314+ jitCompPutOp_PUSH_Imm8(w.dst, src[6]);
1315+ jitCompPutOp_PUSH_Imm8(w.dst, src[5]);
1316+ jitCompPutOp_PUSH_Imm8(w.dst, src[4] & 0x0f);
1317+ jitCompPutOp_PUSH_Imm8(w.dst, (src[4] >> 4) & 0x0f);
1318+ jitCompPutOp_PUSH_Imm8(w.dst, src[3]);
1319+ jitCompPutOp_PUSH_Imm8(w.dst, src[2]);
1320+ jitCompPutOp_PUSH_Imm8(w.dst, src[1]);
1321+ jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP);
1322+ j = ((unsigned char *)&func3c) - (w.dst + 1 + 4);
1323+ jitCompPutOp_CALL_Relative(w.dst, j)
1324+ jitCompPutOp_ADD_GReg_Imm8(w.dst, IA32_REG4_ESP, 32);
1325+ jitCompA000_loadRegCacheAll(&w); // 手抜き.
1326+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1327+ cmp0reg = -1;
1328+ break;
1329+
1330+ case 0x3d: /* LEAVE */
1331+ jitCompA000_storeRegCacheAll(&w); // 手抜き.
1332+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1333+ jitCompPutOp_PUSH_Imm8(w.dst, src[6]);
1334+ jitCompPutOp_PUSH_Imm8(w.dst, src[5]);
1335+ jitCompPutOp_PUSH_Imm8(w.dst, src[4] & 0x0f);
1336+ jitCompPutOp_PUSH_Imm8(w.dst, (src[4] >> 4) & 0x0f);
1337+ jitCompPutOp_PUSH_Imm8(w.dst, src[3]);
1338+ jitCompPutOp_PUSH_Imm8(w.dst, src[2]);
1339+ jitCompPutOp_PUSH_Imm8(w.dst, src[1]);
1340+ jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP);
1341+ j = ((unsigned char *)&func3d) - (w.dst + 1 + 4);
1342+ jitCompPutOp_CALL_Relative(w.dst, j)
1343+ jitCompPutOp_ADD_GReg_Imm8(w.dst, IA32_REG4_ESP, 32);
1344+ jitCompA000_loadRegCacheAll(&w); // 手抜き.
1345+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1346+ cmp0reg = -1;
1347+ break;
1348+
1349+ case 0xfe: /* remark */
1350+ if (src[1] == 0x01 && src[2] == 0x00) {
1351+ // DBGINFO1
1352+ if (level <= JITC_LV_SLOWER) {
1353+ jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1);
1354+ jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX);
1355+ }
1356+ }
1357+ if (src[1] == 0x01 && src[2] == 0x03) {
1358+ // DBGINFO1CLR
1359+ if (level <= JITC_LV_SLOWER) {
1360+ jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, -1);
1361+ jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX);
1362+ }
1363+ }
1364+ if (src[1] == 0x05 && src[2] == 0x00) {
1365+ // DBGINFO0
1366+ if (level <= JITC_LV_SLOWEST) {
1367+ debugInfo0 = jitCompGetImm32(src + 3);
1368+ jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo0);
1369+ jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO0, IA32_REG0_EAX);
1370+ }
1371+ }
1372+ break;
1373+
1374+ default:
1375+ w.err = JITC_ERR_OPECODE;
1376+ goto err_w;
1377+ }
1378+ if (w.err != 0){
1379+ goto err_w;
1380+ }
1381+ jitCompA0001_fixPrefix(&w);
1382+ if (w.err != 0) {
1383+ goto err_w;
1384+ }
1385+#if ENABLE_DEBUG_CODE != 0
1386+ if(*src != 0x00 && *src != 0x01 && *src != 0x34){
1387+ DEBUGCode(&w, 315315);
1388+ }
1389+#endif
1390+ src += jitCompCmdLen(src);
1391+ }
1392+ if (enter0 != NULL) {
1393+ j = w.dst - (enter0 + 4);
1394+ enter0[0] = j & 0xff;
1395+ enter0[1] = (j >> 8) & 0xff;
1396+ enter0[2] = (j >> 16) & 0xff;
1397+ enter0[3] = (j >> 24) & 0xff;
1398+ }
1399+ if ((flags & JITC_NOSTARTUP) == 0) {
1400+ jitCompA000_storeRegCacheAll(&w);
1401+ jitCompA000_storePRegCacheAll(&w);
1402+ jitCompPutOp_POPAD(w.dst);
1403+ }
1404+ if ((flags & JITC_PHASE1) != 0){
1405+ return w.dst - dst00;
1406+ }
1407+ return 0;
1408+
1409+err_w:
1410+ if ((w.err & JITC_ERR_PHASE0ONLY) != 0) {
1411+ if ((flags & JITC_PHASE1) == 0){
1412+ w.err &= ~JITC_ERR_PHASE0ONLY;
1413+ }
1414+ }
1415+ if (w.err == (JITC_ERR_MASK & JITC_ERR_REGNUM)) errmsg = "reg-number error";
1416+ if (w.err == (JITC_ERR_MASK & JITC_ERR_DST1)) errmsg = "dst1 error";
1417+ if (w.err == (JITC_ERR_MASK & JITC_ERR_OPECODE)) errmsg = "opecode error";
1418+ if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELNUM)) errmsg = "label number too large";
1419+ if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELREDEF)) errmsg = "label redefine";
1420+ if (w.err == (JITC_ERR_MASK & JITC_ERR_PREFIX)) { errmsg = "prefix redefine"; w.dst -= 2; }
1421+ if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELNODEF)) errmsg = "label not defined";
1422+ if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELTYP)) errmsg = "label type error";
1423+ if (w.err == (JITC_ERR_MASK & JITC_ERR_IDIOM)) errmsg = "idiom error";
1424+ if (w.err == (JITC_ERR_MASK & JITC_ERR_PREGNUM)) errmsg = "preg-number error";
1425+ if (w.err == (JITC_ERR_MASK & JITC_ERR_SRC1)) errmsg = "src1 error";
1426+ if (w.err == (JITC_ERR_MASK & JITC_ERR_BADTYPE)) errmsg = "bad type code";
1427+ if (w.err == (JITC_ERR_MASK & JITC_ERR_PREFIXFAR)) errmsg = "prefix internal error";
1428+ if (w.err == (JITC_ERR_MASK & JITC_ERR_INTERNAL)) errmsg = "general internal error";
1429+ if (*errmsg != '\0') {
1430+ fprintf(stderr, "JITC: %s at %06X (debugInfo0=%d)\n ", errmsg, src - src0, debugInfo0);
1431+ for (i = 0; i < 16; i++)
1432+ fprintf(stderr, "%02X ", src[i]);
1433+ static char *table[0x30] = {
1434+ "NOP", "LB", "LIMM", "PLIMM", "CND", "??", "??", "??",
1435+ "LMEM", "SMEM", "PLMEM", "PSMEM", "LEA", "??", "PADD", "PDIF",
1436+ "CP/OR", "XOR", "AND", "??", "ADD", "SUB", "MUL", "??",
1437+ "SHL", "SAR", "DIV", "MOD", "PLMT0", "PLMT1", "PCP", "PCST",
1438+ "CMPE", "CMPNE", "CMPL", "CMPGE", "CMPLE", "CMPG", "TSTZ", "TSTNZ",
1439+ "PCMPE", "PCMPNE", "PCMPL", "PCMPGE", "PCMPLE", "PCMPG", "??", "EXT" };
1440+ errmsg = "??";
1441+ if (*src < 0x30) errmsg = table[*src];
1442+ fprintf(stderr, "(%s)\n", errmsg);
1443+ }
1444+ return -1;
1445+}
1446+
1447+unsigned char *jitCompCallFunc(unsigned char *dst, void *func)
1448+{
1449+ //この関数の中では結局w->dstしか参照していない
1450+ struct JitCompWork w;
1451+ w.dst = dst;
1452+ jitCompA000_storeRegCacheAll(&w);
1453+ jitCompA000_storePRegCacheAll(&w);
1454+ jitCompPutOp_PUSHAD(w.dst);
1455+ jitCompPutOp_PUSH_GReg(w.dst, IA32_REG0_EAX); /* for 16Byte-align(Mac OSX) */
1456+ jitCompPutOp_PUSH_GReg(w.dst, IA32_REG5_EBP);
1457+
1458+ int j = ((unsigned char *)func) - (w.dst + 1 + 4);
1459+ jitCompPutOp_CALL_Relative(w.dst, j);
1460+
1461+ jitCompPutOp_POP_GReg(w.dst, IA32_REG0_EAX);
1462+ jitCompPutOp_POP_GReg(w.dst, IA32_REG0_EAX); /* for 16Byte-align (Mac OSX) */
1463+ jitCompPutOp_POPAD(w.dst);
1464+ jitCompA000_loadRegCacheAll(&w);
1465+ jitCompA000_loadPRegCacheAll(&w);
1466+ jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(0x30) + 0);
1467+
1468+ jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */
1469+ return w.dst;
1470+}
1471+
1472+unsigned char *jitCompInit(unsigned char *dst)
1473+{
1474+ errfnc = dst;
1475+ return jitCompCallFunc(dst, &errHndl);
1476+}
1477+
1478+void jitcRunBinary(void (*bin)(char *), HOSECPU_RuntimeEnvironment *env)
1479+{
1480+ (*bin)(((char *)env) + jitCompA0001_EBP128); /* サイズを節約するためにEBPをjitCompA0001_EBP128バイトずらす */
1481+ return;
1482+}
1483+
1484+void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0)
1485+{
1486+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1487+ int i, *pi;
1488+ HOSECPU_PointerRegisterEntry *pp;
1489+
1490+ if (r->junkStack + 2048 > r->junkStack1) {
1491+ (*(r->errHndl))(r);
1492+ }
1493+ pi = (void *)r->junkStack;
1494+ r->junkStack += r1 * 4;
1495+ for (i = 0; i < r1; i++){
1496+ pi[i] = r->ireg[i];
1497+ }
1498+ pp = (void *)r->junkStack;
1499+ r->junkStack += p1 * 32;
1500+ for (i = 0; i < p1; i++){
1501+ //pp[i] = r->preg[i];
1502+ PRegCopy(&pp[i], &r->preg[i]);
1503+ //
1504+ }
1505+ pp = (void *)r->junkStack;
1506+ r->junkStack += 32;
1507+ //*pp = r->preg[0x30];
1508+ PRegCopy(pp, &r->preg[0x30]);
1509+ //
1510+ pi = (void *)r->junkStack;
1511+ r->junkStack += 4;
1512+ *pi = opt << 16 | r1 << 8 | p1;
1513+ for (i = 0; i < lenR; i++){
1514+ r->ireg[r0 + i] = r->ireg[0x30 + i];
1515+ }
1516+ for (i = 0; i < lenP; i++){
1517+ r->preg[p0 + i] = r->preg[0x31 + i];
1518+ }
1519+ return;
1520+}
1521+
1522+void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0)
1523+{
1524+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1525+ int i;
1526+ r->junkStack -= 4;
1527+ r->junkStack -= 32;
1528+ HOSECPU_PointerRegisterEntry *pp = (void *)r->junkStack;
1529+
1530+ //r->preg[0x30] = *pp;
1531+ PRegCopy(&r->preg[0x30], pp);
1532+ //
1533+ r->junkStack -= p1 * 32; pp = (void *)r->junkStack;
1534+ for (i = 0; i < p1; i++){
1535+ //r->preg[i] = pp[i];
1536+ PRegCopy(&r->preg[i], &pp[i]);
1537+ //
1538+ }
1539+ r->junkStack -= r1 * 4; int *pi = (void *)r->junkStack;
1540+ for (i = 0; i < r1; i++){
1541+ r->ireg[i] = pi[i];
1542+ }
1543+ return;
1544+}
1545+
1546+void funcf4(char *ebp, int pxx, int typ, int len)
1547+{
1548+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1549+ int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3;
1550+ if (width < 0 || r->ireg[len] < 0){
1551+ (*(r->errHndl))(r);
1552+ }
1553+ void *p = r->junkStack;
1554+ if (r->junkStack + width * r->ireg[len] + 256 > r->junkStack1){
1555+ (*(r->errHndl))(r);
1556+ }
1557+ r->junkStack += width * r->ireg[len];
1558+ r->preg[pxx].p = p;
1559+ r->preg[pxx].typ = r->ireg[typ];
1560+ r->preg[pxx].p0 = p;
1561+ r->preg[pxx].p1 = (void *)r->junkStack;
1562+ int *pi = (int *)r->junkStack;
1563+ *pi = width * r->ireg[len];
1564+ r->junkStack += sizeof (int);
1565+ if (r->ireg[typ] == 1) {
1566+ int i, i1 = (width * r->ireg[len]) >> 2;
1567+ pi = p;
1568+ for (i = 0; i < i1; i++){
1569+ pi[i] = 0;
1570+ }
1571+ }
1572+ return;
1573+}
1574+
1575+void funcf5(char *ebp, int pxx, int typ, int len)
1576+{
1577+ // pxxはダミーで参照されない
1578+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1579+ r->junkStack -= sizeof (int);
1580+ int *pi = (int *)r->junkStack;
1581+ r->junkStack -= *pi;
1582+#if 0
1583+ int width = jitCompA000_dataWidth(r->ireg[typ]);
1584+ void *p = r->junkStack;
1585+ r->junkStack -= width * r->ireg[len];
1586+#endif
1587+ return;
1588+}
1589+
1590+void funcf6(char *ebp, int pxx, int typ, int len)
1591+{
1592+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1593+ int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3;
1594+ if (width < 0 || r->ireg[len] < 0){
1595+ (*(r->errHndl))(r);
1596+ }
1597+ void *p = malloc(width * r->ireg[len]);
1598+ r->preg[pxx].p = p;
1599+ r->preg[pxx].typ = r->ireg[typ];
1600+ r->preg[pxx].p0 = p;
1601+ r->preg[pxx].p1 = (unsigned char *)p + width * r->ireg[len];
1602+ if (r->ireg[typ] == 1) {
1603+ int i, i1 = (width * r->ireg[len]) >> 2, *pi;
1604+ pi = p;
1605+ for (i = 0; i < i1; i++){
1606+ pi[i] = 0;
1607+ }
1608+ for (i = 1; i < i1; i += 8){
1609+ pi[i] |= -1;
1610+ }
1611+ }
1612+ return;
1613+}
1614+
1615+void funcf7(char *ebp, int pxx, int typ, int len)
1616+{
1617+ // typとlenはダミーで参照されない
1618+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1619+ free(r->preg[pxx].p);
1620+ return;
1621+}
1622+
1623+void errHndl(HOSECPU_RuntimeEnvironment *r)
1624+{
1625+ r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - jitCompA0001_EBP128);
1626+ (*(r->errHndl))(r);
1627+ // ここに帰ってきてはいけない.
1628+}
1629+
1630+/*
1631+ * jitcの出力コードをひとまとめにする関数を作成しその中身をjitCompile()で生成
1632+ *
1633+ * qq : 出力バイナリの書き込み位置のアドレスへの参照(書き込み位置を呼び出しに反映させるため参照渡しにする)
1634+ * q1 : 出力バイナリの書き込み位置のアドレスの最大値
1635+ * p0 : (*.ose)バイナリの読み込み位置のアドレス(ヘッダ部除去済)
1636+ * p1 : (*.ose)バイナリの読み込み位置の取りうる最大値
1637+ * (ただし、「確保したメモリ」の最大値なのでこれより手前にゴミデータが入っているかもしれない)
1638+ * ret=1 : ヘッダのエラー
1639+ * ret=2 : jitコンパイルエラー
1640+ */
1641+int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label)
1642+{
1643+ unsigned char *q = *qq;
1644+ int i;
1645+
1646+ if (p0[0] != 0x05 || p0[1] != SIGN1){
1647+ // OSECPUのヘッダ (05E1) を確認
1648+ return 1;
1649+ }
1650+
1651+ jitCompPutOp_PUSH_GReg(q, IA32_REG5_EBP);
1652+
1653+ *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */
1654+
1655+ for (i = 0; i < JITC_MAXLABELS; i++){
1656+ label[i].opt = 0;
1657+ }
1658+
1659+ // 以下のjitCompile()呼び出しでは第二引数をq1-2にした方がよいのではないか?
1660+ i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, 0); // ラベルのチェック
1661+ if (i != 0){
1662+ return 2;
1663+ }
1664+ i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, JITC_PHASE1 + 0);
1665+ if (i < 0){
1666+ return 2;
1667+ }
1668+ q += i;
1669+
1670+ jitCompPutOp_POP_GReg(q, IA32_REG5_EBP);
1671+ *q++ = 0xc3; /* RET(); */
1672+ *qq = q;
1673+ return 0;
1674+}
1675+
1676+#if (USE_DEBUGGER != 0)
1677+
1678+int dbgrGetRegNum(const char *p)
1679+{
1680+ int i, j, r = -1;
1681+ if (p[2] <= ' ') {
1682+ i = p[0] - '0';
1683+ j = p[1] - '0';
1684+ if (i > 9){
1685+ i -= 'A' - '0' - 10;
1686+ }
1687+ if (j > 9){
1688+ j -= 'A' - '0' - 10;
1689+ }
1690+ if (0 <= i && i <= 15 && 0 <= j && j <= 15){
1691+ r = i << 4 | j;
1692+ }
1693+ }
1694+ return r;
1695+}
1696+
1697+void dbgrMain(HOSECPU_RuntimeEnvironment *r)
1698+{
1699+ if (r->dbgr == 0){
1700+ return;
1701+ }
1702+ for (;;) {
1703+ char cmd[64], *p;
1704+ int i, j, k;
1705+
1706+ printf("\ndbgr>");
1707+ p = fgets(cmd, 64, stdin);
1708+ if (p == NULL){
1709+ break;
1710+ }
1711+ if (cmd[0] == '\0'){
1712+ continue;
1713+ }
1714+ if (cmd[0] == 'q' && cmd[1] <= ' '){
1715+ break;
1716+ }
1717+ if (cmd[0] == 'p' && cmd[1] <= ' ' && cmd[1] != '\0') {
1718+ p = &cmd[2];
1719+ while (*p <= ' ' && *p != '\0'){
1720+ p++;
1721+ }
1722+ if (*p == 'R') {
1723+ i = dbgrGetRegNum(p + 1);
1724+ if (0 <= i && i <= 0x3f) {
1725+ printf("R%02X = 0x%08X = %d\n", i, r->ireg[i], r->ireg[i]);
1726+ } else{
1727+ puts("register name error");
1728+ }
1729+ continue;
1730+ }
1731+ if (*p == 'P') {
1732+ i = dbgrGetRegNum(p + 1);
1733+ if (0 <= i && i <= 0x3f) {
1734+ p = "invalid";
1735+ if (0 <= r->preg[i].typ && r->preg[i].typ <= 0x15) {
1736+ static char *typName[] = {
1737+ "T_CODE", "T_VPTR", "T_SINT8", "T_UINT8",
1738+ "T_SINT16", "T_UINT16", "T_SINT32", "T_UINT32",
1739+ "T_SINT4", "T_UINT4", "T_SINT2", "T_UINT2",
1740+ "T_SINT1", "T_UINT1", "T_SINT12", "T_UINT12",
1741+ "T_SINT20", "T_UINT20", "T_SINT24", "T_UINT24",
1742+ "T_SINT28", "T_UINT28"
1743+ };
1744+ p = typName[r->preg[i].typ];
1745+ }
1746+ printf("P%02X:\n type = %s(%04X), (origin-ptr) = 0x%08X\n", i, p, r->preg[i].typ, (unsigned int)(r->preg[i].p0));
1747+ if (r->preg[i].p != NULL && r->preg[i].p0 != NULL) {
1748+ j = jitCompA000_dataWidth(jitCompA000_convTyp(r->preg[i].typ)) >> 3;
1749+ if (j <= 0){
1750+ j = 1;
1751+ }
1752+ k = (r->preg[i].p1 - r->preg[i].p0) / j;
1753+ printf(" size = 0x%08X = %d\n", k, k);
1754+ k = (r->preg[i].p - r->preg[i].p0) / j;
1755+ printf(" pos = 0x%08X = %d\n", k, k);
1756+ }
1757+ else {
1758+ puts(" null pointer");
1759+ }
1760+ }
1761+ else
1762+ puts("register name error");
1763+ continue;
1764+ }
1765+ }
1766+ puts("command error");
1767+ }
1768+ return;
1769+}
1770+
1771+#endif
1772+
1773+
17711774 #endif
\ No newline at end of file
--- a/osecpu.h
+++ b/osecpu.h
@@ -53,6 +53,7 @@
5353
5454 #define USE_DEBUGGER 1
5555 #define USE_TEK5 1
56+#define ENABLE_DEBUG_CODE 0 // env.dbg_currentCodeに実行するコードを保存するデバッグコードを挿入する
5657
5758 /* JITC mode flags */
5859 #define JITC_LV_SLOWEST 0 /* デバッグ支援は何でもやる */
旧リポジトリブラウザで表示