OSDN Git Service

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