OSDN Git Service

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