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