リビジョン | 035a08b35ab09fd704b2c66c5de5c70b66572bc6 (tree) |
---|---|
日時 | 2014-03-17 07:52:03 |
作者 | ttwilb <ttwilb@user...> |
コミッター | ttwilb |
Merge branch 'master' of git.sourceforge.jp:/gitroot/heavyosecpu/HeavyOSECPU
Conflicts:
jitcx86.c
main.c
osecpu.h
@@ -1,759 +1,760 @@ | ||
1 | -#include "osecpu.h" | |
2 | - | |
3 | -extern unsigned char fontdata[]; // @fontdata.c | |
4 | - | |
5 | -const char *searchArg(int argc, const char **argv, const char *tag, int i) | |
6 | -{ | |
7 | - // 引数リストargvの中から、文字列tagが前方一致する引数のi番目を探し出し、 | |
8 | - // その引数の文字列の、tagに続く部分の文字へのポインタを返す。 | |
9 | - int j, l; | |
10 | - const char *r = NULL; | |
11 | - | |
12 | - if (tag != NULL) { | |
13 | - l = (int)strlen(tag); | |
14 | - for (j = 1; j < argc; j++) { | |
15 | - if (strncmp(argv[j], tag, l) == 0) { | |
16 | - r = argv[j] + l; | |
17 | - if (i == 0){ | |
18 | - break; | |
19 | - } | |
20 | - i--; | |
21 | - } | |
22 | - } | |
23 | - } | |
24 | - /* | |
25 | - // 未使用 | |
26 | - else { | |
27 | - for (j = 1; j < argc; j++) { | |
28 | - if (strchr(argv[j], ':') == NULL) { | |
29 | - r = argv[j]; | |
30 | - if (i == 0){ | |
31 | - break; | |
32 | - } | |
33 | - i--; | |
34 | - } | |
35 | - } | |
36 | - } | |
37 | - */ | |
38 | - if (i != 0){ | |
39 | - r = NULL; | |
40 | - } | |
41 | - return r; | |
42 | -} | |
43 | - | |
44 | -void devFunc0001(int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r) | |
45 | -{ | |
46 | - // OSASK文字列の出力 | |
47 | - while (len > 0) { | |
48 | - putOsaskChar(*puc++, r); | |
49 | - len--; | |
50 | - } | |
51 | - return; | |
52 | -} | |
53 | - | |
54 | -void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r) | |
55 | -{ | |
56 | - // drawString | |
57 | - int xx; | |
58 | - int yy; | |
59 | - int i, ddx, ddy, j, ch, dx, dy; | |
60 | - | |
61 | - if (sy == 0){ | |
62 | - sy = sx; | |
63 | - } | |
64 | - xx = x + sx * 8; | |
65 | - yy = y + sy * 16; | |
66 | - if (xx <= 0 || xx > mainWindow.xsize || yy <= 0 || yy > mainWindow.ysize){ | |
67 | - (*(r->errHndl))(r); | |
68 | - } | |
69 | - if (x < 0 || x >= mainWindow.xsize || y < 0 || y >= mainWindow.ysize){ | |
70 | - (*(r->errHndl))(r); | |
71 | - } | |
72 | - | |
73 | - | |
74 | - if ((mod & 3) == 0 && sx == 1 && sy == 1) { | |
75 | - // メジャーケースを高速化. | |
76 | - for (i = 0; i < len; i++) { | |
77 | - ch = puc[i]; | |
78 | - if (0x10 <= ch && ch <= 0x1f) | |
79 | - ch = "0123456789ABCDEF"[ch & 0x0f]; | |
80 | - for (dy = 0; dy < 16; dy++) { | |
81 | - j = fontdata[(ch - ' ') * 16 + dy]; | |
82 | - for (dx = 0; dx < 8; dx++) { | |
83 | - if ((j & (0x80 >> dx)) != 0){ | |
84 | - mainWindow.vram[(x + dx) + (y + dy) * mainWindow.xsize] = c; | |
85 | - } | |
86 | - } | |
87 | - } | |
88 | - x += 8; | |
89 | - } | |
90 | - return; | |
91 | - } | |
92 | - for (i = 0; i < len; i++) { | |
93 | - ch = puc[i]; | |
94 | - if (0x10 <= ch && ch <= 0x1f) | |
95 | - ch = "0123456789ABCDEF"[ch & 0x0f]; | |
96 | - for (dy = 0; dy < 16; dy++) { | |
97 | - j = fontdata[(ch - ' ') * 16 + dy]; | |
98 | - for (ddy = 0; ddy < sy; ddy++) { | |
99 | - for (dx = 0; dx < 8; dx++) { | |
100 | - if ((j & (0x80 >> dx)) != 0) { | |
101 | - for (ddx = 0; ddx < sx; ddx++) { | |
102 | - switch (mod & 3) { | |
103 | - case 0: | |
104 | - mainWindow.vram[x + y * mainWindow.xsize] = c; | |
105 | - break; | |
106 | - case 1: | |
107 | - mainWindow.vram[x + y * mainWindow.xsize] |= c; | |
108 | - break; | |
109 | - case 2: | |
110 | - mainWindow.vram[x + y * mainWindow.xsize] ^= c; | |
111 | - break; | |
112 | - case 3: | |
113 | - mainWindow.vram[x + y * mainWindow.xsize] &= c; | |
114 | - break; | |
115 | - } | |
116 | - x++; | |
117 | - } | |
118 | - } else{ | |
119 | - x += sx; | |
120 | - } | |
121 | - } | |
122 | - x -= sx * 8; | |
123 | - y++; | |
124 | - } | |
125 | - } | |
126 | - x += sx * 8; | |
127 | - y -= sy * 16; | |
128 | - } | |
129 | - return; | |
130 | -} | |
131 | - | |
132 | -void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c) | |
133 | -{ | |
134 | - // FillRect | |
135 | - int x, y; | |
136 | - if (mod == 0) { | |
137 | - for (y = y0; y <= y1; y++) { | |
138 | - for (x = x0; x <= x1; x++) { | |
139 | - mainWindow.vram[x + y * mainWindow.xsize] = c; | |
140 | - } | |
141 | - } | |
142 | - } | |
143 | - else { | |
144 | - for (y = y0; y <= y1; y++) { | |
145 | - for (x = x0; x <= x1; x++) { | |
146 | - switch (mod) { | |
147 | - case 1: | |
148 | - mainWindow.vram[x + y * mainWindow.xsize] |= c; | |
149 | - break; | |
150 | - case 2: | |
151 | - mainWindow.vram[x + y * mainWindow.xsize] ^= c; | |
152 | - break; | |
153 | - case 3: | |
154 | - mainWindow.vram[x + y * mainWindow.xsize] &= c; | |
155 | - break; | |
156 | - } | |
157 | - } | |
158 | - } | |
159 | - } | |
160 | - return; | |
161 | -} | |
162 | - | |
163 | -int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r) | |
164 | -{ | |
165 | - // OSASK文字列への変換? | |
166 | - int i = 0, base, j, k; | |
167 | - char sign; | |
168 | - | |
169 | - while (plen > 0) { | |
170 | - if (i >= buflen){ | |
171 | - (*(r->errHndl))(r); | |
172 | - } | |
173 | - if (*p != 0x01) { | |
174 | - buf[i++] = *p++; | |
175 | - plen--; | |
176 | - continue; | |
177 | - } | |
178 | - p++; | |
179 | - plen--; | |
180 | - if (qlen < 4){ | |
181 | - (*(r->errHndl))(r); | |
182 | - } | |
183 | - base = q[0]; | |
184 | - sign = 0; | |
185 | - if (base == 0){ | |
186 | - base = 16; | |
187 | - } | |
188 | -#if (REVISION == 1) | |
189 | - if (base == -3){ | |
190 | - base = 10; | |
191 | - } | |
192 | -#endif | |
193 | - if (base == -1){ | |
194 | - base = 10; | |
195 | - } | |
196 | - if (base < 0 || base > 16){ | |
197 | - (*(r->errHndl))(r); | |
198 | - } | |
199 | - if (q[1] + i > buflen){ | |
200 | - (*(r->errHndl))(r); | |
201 | - } | |
202 | - j = q[3]; | |
203 | - if ((q[2] & 4) == 0) { | |
204 | - // jは符号付き整数. | |
205 | - if ((q[2] & 8) != 0 && j > 0){ | |
206 | - sign = '+'; | |
207 | - } | |
208 | - if (j < 0) { | |
209 | - sign = '-'; j *= -1; | |
210 | - } | |
211 | - } else{ | |
212 | - // jは符号無し整数. | |
213 | - if ((q[2] & 8) != 0 && j != 0){ | |
214 | - sign = '+'; | |
215 | - } | |
216 | - } | |
217 | - for (k = q[1] - 1; k >= 0; k--) { | |
218 | - buf[i + k] = (j % base) + 0x10; | |
219 | - j = ((unsigned)j) / base; | |
220 | - } | |
221 | - k = 0; | |
222 | - if ((q[2] & 2) == 0 && j == 0) { | |
223 | - for (k = 0; k < q[1] - 1; k++) { | |
224 | - if (buf[i + k] != 0x10){ | |
225 | - break; | |
226 | - } | |
227 | - buf[i + k] = ' '; | |
228 | - } | |
229 | - } | |
230 | - if (sign != 0) { | |
231 | - if (k > 0){ | |
232 | - k--; | |
233 | - } | |
234 | - buf[i + k] = sign; | |
235 | - } | |
236 | - if ((q[2] & 1) != 0 && buf[i] == ' ') { | |
237 | - for (j = 0; k < q[1]; k++, j++){ | |
238 | - buf[i + j] = buf[i + k]; | |
239 | - } | |
240 | - i += j; | |
241 | - } else{ | |
242 | - i += q[1]; | |
243 | - } | |
244 | - qlen -= 4; | |
245 | - q += 4; | |
246 | - } | |
247 | - return i; | |
248 | -} | |
249 | - | |
250 | -void devFunc(HOSECPU_RuntimeEnvironment *r) | |
251 | -{ | |
252 | - FILE *fp; | |
253 | - int i, c; | |
254 | - int x, y, len, dx, dy; | |
255 | - unsigned char *puc; | |
256 | - unsigned char pucbuf[256]; | |
257 | - | |
258 | - //サイズを節約するためにEBPを128バイトずらしているのを元に戻す | |
259 | - r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - 128); | |
260 | - | |
261 | - if (r->winClosed != 0){ | |
262 | - longjmp(r->setjmpEnv, 1); | |
263 | - } | |
264 | - if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) { | |
265 | - if (mainWindow.vram == NULL) { | |
266 | - mainWindow.xsize = 640; | |
267 | - mainWindow.ysize = 480; | |
268 | - mainWindow.vram = malloc(640 * 480 * 4); | |
269 | - drv_openWin(640, 480, (void *)mainWindow.vram, &r->winClosed); | |
270 | - r->autoSleep = 1; | |
271 | - for (i = 640 * 480 - 1; i >= 0; i--){ | |
272 | - mainWindow.vram[i] = 0; | |
273 | - } | |
274 | - } | |
275 | - } | |
276 | - | |
277 | - switch (r->ireg[0x30]){ | |
278 | - case 0xff00: | |
279 | - printf("R31=%d(dec)\n", r->ireg[0x31]); | |
280 | - break; | |
281 | - | |
282 | - case 0xff01: | |
283 | - // junkApi_fopenRead(_filesize, _p, arg) | |
284 | - // args: R31=arg, R30=_filesize, P31=_p | |
285 | - // retv: R30, P31 | |
286 | - if (r->buf0 == NULL){ | |
287 | - r->buf0 = malloc(1024 * 1024); | |
288 | - } | |
289 | - if (r->mainArgc <= r->ireg[0x31]) { | |
290 | - fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]); | |
291 | - exit(1); | |
292 | - } | |
293 | - fp = fopen(r->mainArgv[r->ireg[0x31]], "rb"); | |
294 | - if (fp == NULL) { | |
295 | - fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]); | |
296 | - exit(1); | |
297 | - } | |
298 | - i = (int)fread(r->buf0, 1, 1024 * 1024 - 4, fp); | |
299 | - if (i >= 1024 * 1024 - 4 || i < 0) { | |
300 | - fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->mainArgv[r->ireg[0x31]]); | |
301 | - exit(1); | |
302 | - } | |
303 | - fclose(fp); | |
304 | - r->preg[0x31].p = r->buf0; | |
305 | - r->preg[0x31].p0 = r->buf0; | |
306 | - r->preg[0x31].p1 = r->buf0 + i; | |
307 | - r->preg[0x31].typ = 3; // T_UINT8 | |
308 | - r->ireg[0x30] = i; | |
309 | - break; | |
310 | - | |
311 | - case 0xff02: | |
312 | - // junkApi_fopenWrite(arg, filesize, p) | |
313 | - // args: R31=arg, R32=filesize, P31=p | |
314 | - // retv: (none) | |
315 | - if (r->mainArgc <= r->ireg[0x31]) { | |
316 | - fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]); | |
317 | - exit(1); | |
318 | - } | |
319 | - fp = fopen(r->mainArgv[r->ireg[0x31]], "wb"); | |
320 | - if (fp == NULL) { | |
321 | - fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]); | |
322 | - exit(1); | |
323 | - } | |
324 | - if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){ | |
325 | - fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]); | |
326 | - exit(1); | |
327 | - } | |
328 | - fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp); | |
329 | - fclose(fp); | |
330 | - break; | |
331 | - | |
332 | - case 0xff03: | |
333 | - // junkApi_allocBuf(_p) | |
334 | - // args: P31=_p | |
335 | - // retv: P31 | |
336 | - if (r->buf1 == NULL){ | |
337 | - r->buf1 = malloc(1024 * 1024); | |
338 | - } | |
339 | - r->preg[0x31].p = r->buf1; | |
340 | - r->preg[0x31].p0 = r->buf1; | |
341 | - r->preg[0x31].p1 = r->buf1 + 1024 * 1024; | |
342 | - break; | |
343 | - | |
344 | - case 0xff04: | |
345 | - printf("P31.(p-p0)=%d(dec)\n", (int)(r->preg[0x31].p - r->preg[0x31].p0)); | |
346 | - break; | |
347 | - | |
348 | - case 0xff05: | |
349 | - // junkApi_writeStdout(len, p) | |
350 | - // args: R31=len, P31=p | |
351 | - // retv: (none) | |
352 | - fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout); | |
353 | - break; | |
354 | - | |
355 | - case 0xff06: | |
356 | - // junkApi_exit(i) | |
357 | - // args: R31=i | |
358 | - // retv: (none) | |
359 | - r->appReturnCode = r->ireg[31]; | |
360 | - longjmp(r->setjmpEnv, 1); | |
361 | - break; | |
362 | - | |
363 | - case 0xff07: | |
364 | - // junkApi_putConstString0(s) | |
365 | - // DB(0xff,0x00,0x00); DB%(s,0x00); | |
366 | - // マシになった文字列表示. | |
367 | - // OSASK文字列に対応.offにすれば通常の文字列処理もできる. | |
368 | - // 現状はonのみサポート. | |
369 | - checkString(r, 0x31, 0x31); | |
370 | - devFunc0001(r->ireg[0x31], r->preg[0x31].p, r); | |
371 | - break; | |
372 | - | |
373 | - case 0xff08: | |
374 | - // junkApi_jitc2(_rc, _p, mod, lev, di1, len, s) | |
375 | - // R31=mod; R32=lev; R33=di1; R34=len; P31=s; _rc=R30; _p=P31 | |
376 | - // JITC on JITC | |
377 | - // R31: 言語(back-end, front-end, ... | |
378 | - // R32: level | |
379 | - // R33: debugInfo1 | |
380 | - checkString(r, 0x34, 0x31); | |
381 | - if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15){ | |
382 | - (*(r->errHndl))(r); | |
383 | - } | |
384 | - for (i = 0; i < r->maxLabels; i++){ | |
385 | - r->label[i].opt = 0; | |
386 | - } | |
387 | - puc = r->preg[0x31].p; | |
388 | - i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + 0); | |
389 | - if (i == 0) { | |
390 | - i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + JITC_PHASE1 + 0); | |
391 | - if (i >= 0) { | |
392 | - r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = di1_serial; | |
393 | - di1_serial++; | |
394 | - r->ireg[0x30] = 0; | |
395 | - r->preg[0x31].p = r->jitbuf; | |
396 | - r->preg[0x31].typ = 0; // TYP_CODE | |
397 | - r->preg[0x31].p0 = r->jitbuf; | |
398 | - r->preg[0x31].p1 = r->jitbuf + 1; | |
399 | - //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n'); | |
400 | - r->jitbuf += i; | |
401 | - static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 }; | |
402 | - i = jitCompiler(r->jitbuf, r->jitbuf1, ff08_ret, ff08_ret + 3, puc, r->label, r->maxLabels, r->ireg[0x32], -1, JITC_NOSTARTUP + JITC_PHASE1 + 0); | |
403 | - r->jitbuf += i; | |
404 | - break; | |
405 | - } | |
406 | - } | |
407 | - r->ireg[0x30] = -1; | |
408 | - break; | |
409 | - | |
410 | - case 0xff09: | |
411 | - //putStringDec | |
412 | - // たぶんbit7を使ったテキストはうまく処理できない(これはもはや仕様にしても問題ないかも). | |
413 | - checkString(r, 0x31, 0x31); | |
414 | - len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r); | |
415 | - devFunc0001(len, pucbuf, r); | |
416 | - break; | |
417 | - | |
418 | - case 0xff40: | |
419 | - // junkApi_openWin(xsiz, ysiz) R31=xsiz; R32=ysiz; | |
420 | - /* R31とR32でサイズを指定 */ | |
421 | - mainWindow.xsize = r->ireg[0x31]; | |
422 | - mainWindow.ysize = r->ireg[0x32]; | |
423 | - if (mainWindow.xsize <= 0 || mainWindow.ysize <= 0){ | |
424 | - (*(r->errHndl))(r); | |
425 | - } | |
426 | - r->preg[0x31].p = (void *)(mainWindow.vram = malloc(mainWindow.xsize * mainWindow.ysize * 4)); | |
427 | - r->preg[0x31].p0 = r->preg[0x31].p; | |
428 | - r->preg[0x31].p1 = r->preg[0x31].p + mainWindow.xsize * mainWindow.ysize * 4; | |
429 | - drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed); | |
430 | - // drv_flshWin(r->ireg[1], r->ireg[2], 0, 0); | |
431 | - r->autoSleep = 1; | |
432 | - for (i = mainWindow.xsize * mainWindow.ysize - 1; i >= 0; i--){ | |
433 | - mainWindow.vram[i] = 0; | |
434 | - } | |
435 | - break; | |
436 | - | |
437 | - case 0xff41: | |
438 | - // junkApi_flushWin(xsiz, ysiz, x0, y0) | |
439 | - // R31=xsiz; R32=ysiz; R33=x0; R34=y0 | |
440 | - /* R31とR32でサイズを指定、R33とR34でx0,y0指定 */ | |
441 | - if (r->ireg[0x31] == -1) { | |
442 | - r->ireg[0x31] = mainWindow.xsize; r->ireg[0x33] &= 0; | |
443 | - } | |
444 | - if (r->ireg[0x32] == -1) { | |
445 | - r->ireg[0x32] = mainWindow.ysize; r->ireg[0x34] &= 0; | |
446 | - } | |
447 | - checkRect(r, 0x31); | |
448 | - drv_flshWin(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34]); | |
449 | - break; | |
450 | - | |
451 | - case 0xff42: | |
452 | - // junkApi_sleep(opt, msec) R31=opt; R32=msec | |
453 | - if (r->ireg[0x32] == -1) { | |
454 | - r->autoSleep = 1; | |
455 | - longjmp(r->setjmpEnv, 1); | |
456 | - } | |
457 | - if (r->ireg[0x32] < 0){ | |
458 | - (*(r->errHndl))(r); | |
459 | - } | |
460 | - r->autoSleep = 0; | |
461 | - if ((r->ireg[0x31] & 1) == 0 && mainWindow.vram != NULL){ | |
462 | - drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0); | |
463 | - } | |
464 | - for (;;) { | |
465 | - if (r->winClosed != 0){ | |
466 | - longjmp(r->setjmpEnv, 1); | |
467 | - } | |
468 | - drv_sleep(r->ireg[0x32]); | |
469 | - if ((r->ireg[0x31] & 2) != 0 && keybuf_c <= 0){ | |
470 | - continue; | |
471 | - } | |
472 | - break; | |
473 | - } | |
474 | - break; | |
475 | - | |
476 | - case 0xff43: | |
477 | - // junkApi_inkey(_i, mod) R31=mod; _i=R30 | |
478 | - // 1:peek | |
479 | - // 2:stdin | |
480 | - // 4,8: ソース指定. | |
481 | - // 16: shift, lock系を有効化. | |
482 | - // 32: 左右のshift系を区別する. | |
483 | - if (r->ireg[0x31] == 2) { // なぜ3にしなかったのか... | |
484 | - r->ireg[0x30] = fgetc(stdin); | |
485 | - if (r->ireg[0x30] == EOF){ | |
486 | - r->ireg[0x30] = -1; | |
487 | - } | |
488 | - break; | |
489 | - } | |
490 | - r->ireg[0x30] |= -1; | |
491 | - if (keybuf_c > 0) { | |
492 | - r->ireg[0x30] = keybuf[keybuf_r]; | |
493 | - if ((r->ireg[0x31] & 16) == 0){ | |
494 | - r->ireg[0x30] &= 0x3e3effff; | |
495 | - } | |
496 | - if ((r->ireg[0x31] & 32) == 0){ | |
497 | - r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000; | |
498 | - } | |
499 | - if ((r->ireg[0x31] & 1) != 0) { | |
500 | - keybuf_c--; | |
501 | - keybuf_r = (keybuf_r + 1) & (KEYBUFSIZ - 1); | |
502 | - } | |
503 | - } | |
504 | - r->ireg[0x32] = r->ireg[0x33] = 0; | |
505 | - if (r->ireg[0x30] == 4132) r->ireg[0x32]--; | |
506 | - if (r->ireg[0x30] == 4133) r->ireg[0x33]--; | |
507 | - if (r->ireg[0x30] == 4134) r->ireg[0x32]++; | |
508 | - if (r->ireg[0x30] == 4135) r->ireg[0x33]++; | |
509 | - break; | |
510 | - | |
511 | - case 0xff44: | |
512 | - // junkApi_drawPoint(mod, x, y, c) R31=mod; R32=x; R33=y; R34=c | |
513 | - c = loadColor(r, 0x34); | |
514 | - if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize || | |
515 | - r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){ | |
516 | - (*(r->errHndl))(r); | |
517 | - } | |
518 | - | |
519 | - switch ((r->ireg[0x31] & 3)) { | |
520 | - case 0: | |
521 | - mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] = c; | |
522 | - break; | |
523 | - case 1: | |
524 | - mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] |= c; | |
525 | - break; | |
526 | - case 2: | |
527 | - mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] ^= c; | |
528 | - break; | |
529 | - case 3: | |
530 | - mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] &= c; | |
531 | - break; | |
532 | - } | |
533 | - break; | |
534 | - | |
535 | - case 0xff45: | |
536 | - // junkApi_drawLine(mod, x0, y0, x1, y1, c) DB(0xfe,0x05,0x01); DDBE(0x0003); R30=0xff45; R31=mod; R32=x0; R33=y0; R34=x1; R35=y1; R36=c | |
537 | - //drawLine | |
538 | - c = loadColor(r, 0x36); | |
539 | - if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize || | |
540 | - r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){ | |
541 | - (*(r->errHndl))(r); | |
542 | - } | |
543 | - if (r->ireg[0x34] < 0 || r->ireg[0x34] >= mainWindow.xsize || | |
544 | - r->ireg[0x35] < 0 || r->ireg[0x35] >= mainWindow.ysize){ | |
545 | - (*(r->errHndl))(r); | |
546 | - } | |
547 | - dx = r->ireg[0x34] - r->ireg[0x32]; | |
548 | - dy = r->ireg[0x35] - r->ireg[0x33]; | |
549 | - x = r->ireg[0x32] << 10; | |
550 | - y = r->ireg[0x33] << 10; | |
551 | - if (dx < 0){ | |
552 | - dx = -dx; | |
553 | - } | |
554 | - if (dy < 0){ | |
555 | - dy = -dy; | |
556 | - } | |
557 | - if (dx >= dy) { | |
558 | - len = dx + 1; dx = 1024; | |
559 | - if (r->ireg[0x32] > r->ireg[0x34]){ | |
560 | - dx *= -1; | |
561 | - } | |
562 | - if (r->ireg[0x33] > r->ireg[0x35]){ | |
563 | - dy *= -1; | |
564 | - } | |
565 | - dy = (dy << 10) / len; | |
566 | - } else { | |
567 | - len = dy + 1; dy = 1024; | |
568 | - if (r->ireg[0x33] > r->ireg[0x35]){ | |
569 | - dy *= -1; | |
570 | - } | |
571 | - if (r->ireg[0x32] > r->ireg[0x34]){ | |
572 | - dx *= -1; | |
573 | - } | |
574 | - dx = (dx << 10) / len; | |
575 | - } | |
576 | - if ((r->ireg[0x31] & 3) == 0) { | |
577 | - for (i = 0; i < len; i++) { | |
578 | - mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] = c; | |
579 | - x += dx; | |
580 | - y += dy; | |
581 | - } | |
582 | - break; | |
583 | - } | |
584 | - for (i = 0; i < len; i++) { | |
585 | - // if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] = c; | |
586 | - switch ((r->ireg[0x31] & 3)) { | |
587 | - case 1: | |
588 | - mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] |= c; | |
589 | - break; | |
590 | - case 2: | |
591 | - mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] ^= c; | |
592 | - break; | |
593 | - case 3: | |
594 | - mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] &= c; | |
595 | - break; | |
596 | - default: | |
597 | - break; | |
598 | - } | |
599 | - x += dx; | |
600 | - y += dy; | |
601 | - } | |
602 | - break; | |
603 | - | |
604 | - case 0xff46: | |
605 | - // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36) | |
606 | - c = loadColor(r, 0x36); | |
607 | - if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; } | |
608 | - if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; } | |
609 | - checkRect(r, 0x32); | |
610 | - int mod3 = r->ireg[0x31] & 3, x0 = r->ireg[0x34], y0 = r->ireg[0x35], x1 = r->ireg[0x34] + r->ireg[0x32] - 1, y1 = r->ireg[0x35] + r->ireg[0x33] - 1; | |
611 | - if ((r->ireg[0x31] & 0x20) == 0) { | |
612 | - devFunc0004(mod3, x0, y0, x1, y1, c); | |
613 | - } else { // drawRect | |
614 | - devFunc0004(mod3, x0, y0, x1, y0, c); | |
615 | - devFunc0004(mod3, x0, y1, x1, y1, c); | |
616 | - devFunc0004(mod3, x0, y0, x0, y1, c); | |
617 | - devFunc0004(mod3, x1, y0, x1, y1, c); | |
618 | - } | |
619 | - break; | |
620 | - | |
621 | - case 0xff47: | |
622 | - // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36) | |
623 | - // これの計算精度はアーキテクチャに依存する. | |
624 | - c = loadColor(r, 0x36); | |
625 | - if (r->ireg[0x32] == -1) { | |
626 | - r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; | |
627 | - } | |
628 | - if (r->ireg[0x33] == -1) { | |
629 | - r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; | |
630 | - } | |
631 | - checkRect(r, 0x32); | |
632 | - double dcx = 0.5 * (r->ireg[0x32] - 1); | |
633 | - double dcy = 0.5 * (r->ireg[0x33] - 1); | |
634 | - double dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1; | |
635 | - dcxy *= dcxy; | |
636 | - mod3 = r->ireg[0x31] & 3; | |
637 | - x1 = r->ireg[0x32]; | |
638 | - y1 = r->ireg[0x33]; | |
639 | - if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) { | |
640 | - for (y = 0; y < y1; y++) { | |
641 | - double dty = (y - dcy) * dcx; | |
642 | - for (x = 0; x < x1; x++) { | |
643 | - double dtx = (x - dcx) * dcy; | |
644 | - if (dtx * dtx + dty * dty > dcxy){ | |
645 | - continue; | |
646 | - } | |
647 | - mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c; | |
648 | - } | |
649 | - } | |
650 | - } else { | |
651 | -#define DRAWOVALPARAM 1 | |
652 | - double dcx1 = 0.5 * (r->ireg[0x32] - (1 + DRAWOVALPARAM * 2)); | |
653 | - double dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2)); | |
654 | - double dcxy1 = (dcx1 + 0.5) * (dcy1 + 0.5) - 0.1; | |
655 | - dcxy1 *= dcxy1; | |
656 | - for (y = 0; y < y1; y++) { | |
657 | - double dty = (y - dcy) * dcx; | |
658 | - double dty1 = (y - dcy) * dcx1; | |
659 | - for (x = 0; x < x1; x++) { | |
660 | - double dtx = (x - dcx) * dcy; | |
661 | - double dtx1 = (x - dcx) * dcy1; | |
662 | - if (dtx * dtx + dty * dty > dcxy){ | |
663 | - continue; | |
664 | - } | |
665 | - if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) { | |
666 | - if (dtx1 * dtx1 + dty1 * dty1 < dcxy1){ | |
667 | - continue; | |
668 | - } | |
669 | - } | |
670 | - switch (mod3) { | |
671 | - case 0: | |
672 | - mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c; | |
673 | - break; | |
674 | - case 1: | |
675 | - mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] |= c; | |
676 | - break; | |
677 | - case 2: | |
678 | - mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] ^= c; | |
679 | - break; | |
680 | - case 3: | |
681 | - mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] &= c; | |
682 | - break; | |
683 | - } | |
684 | - } | |
685 | - } | |
686 | - } | |
687 | - break; | |
688 | - | |
689 | - case 0xff48: | |
690 | - // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31) | |
691 | - checkString(r, 0x37, 0x31); | |
692 | - devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), r->ireg[0x37], r->preg[0x31].p, r); | |
693 | - break; | |
694 | - | |
695 | - case 0xff49: | |
696 | - // junkApi_rand(_r, range) R31=range; _r=R30 | |
697 | - // **** junkApi_rand(i, max) **** | |
698 | - // 0 <= i <= maxとなるiを返す。 | |
699 | - // max==0のとき、iはSINT32全体を範囲とする乱数となる。 | |
700 | - r->ireg[0x30] = randGetNextUInt32(); | |
701 | - if (r->ireg[0x31] > 0){ | |
702 | - r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1); | |
703 | - } | |
704 | - break; | |
705 | - | |
706 | - case 0xff4a: | |
707 | - // srand | |
708 | - randStatInit(r->ireg[0x31]); | |
709 | - break; | |
710 | - | |
711 | - case 0xff4b: | |
712 | - // srand(random) | |
713 | - r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555); | |
714 | - break; | |
715 | - | |
716 | - case 0xff4c: | |
717 | - // drawStringDec | |
718 | - checkString(r, 0x37, 0x31); | |
719 | - len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r); | |
720 | - devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r); | |
721 | - break; | |
722 | - | |
723 | - case 0xff4d: | |
724 | - // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1); | |
725 | - // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color | |
726 | - puc = r->preg[0x31].p; | |
727 | - mod3 = r->ireg[0x31] & 3; | |
728 | - dx = r->ireg[0x34]; | |
729 | - dy = r->ireg[0x35]; | |
730 | - if (dy == 0){ | |
731 | - dy = dx; | |
732 | - } | |
733 | - if (r->ireg[0x32] == -1) { | |
734 | - r->ireg[0x32] = mainWindow.xsize / dx; r->ireg[0x36] &= 0; | |
735 | - } | |
736 | - if (r->ireg[0x33] == -1) { | |
737 | - r->ireg[0x33] = mainWindow.ysize / dy; r->ireg[0x37] &= 0; | |
738 | - } | |
739 | - for (y = 0; y < r->ireg[0x33]; y++) { | |
740 | - y0 = y * dy + r->ireg[0x37]; | |
741 | - for (x = 0; x < r->ireg[0x32]; x++) { | |
742 | - x0 = x * dx + r->ireg[0x36]; | |
743 | - c = iColor1[*puc++]; | |
744 | - devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c); | |
745 | - } | |
746 | - puc += r->ireg[0x38]; | |
747 | - } | |
748 | - break; | |
749 | - | |
750 | - default: | |
751 | - printf("devFunc: error: R30=%08X\n", r->ireg[0x30]); | |
752 | - exit(EXIT_FAILURE); | |
753 | - | |
754 | - } | |
755 | - return; | |
756 | -} | |
757 | - | |
758 | - | |
759 | - | |
1 | +#include "osecpu.h" | |
2 | +#include "jitc.h" | |
3 | + | |
4 | +extern unsigned char fontdata[]; // @fontdata.c | |
5 | + | |
6 | +const char *searchArg(int argc, const char **argv, const char *tag, int i) | |
7 | +{ | |
8 | + // 引数リストargvの中から、文字列tagが前方一致する引数のi番目を探し出し、 | |
9 | + // その引数の文字列の、tagに続く部分の文字へのポインタを返す。 | |
10 | + int j, l; | |
11 | + const char *r = NULL; | |
12 | + | |
13 | + if (tag != NULL) { | |
14 | + l = (int)strlen(tag); | |
15 | + for (j = 1; j < argc; j++) { | |
16 | + if (strncmp(argv[j], tag, l) == 0) { | |
17 | + r = argv[j] + l; | |
18 | + if (i == 0){ | |
19 | + break; | |
20 | + } | |
21 | + i--; | |
22 | + } | |
23 | + } | |
24 | + } | |
25 | + /* | |
26 | + // 未使用 | |
27 | + else { | |
28 | + for (j = 1; j < argc; j++) { | |
29 | + if (strchr(argv[j], ':') == NULL) { | |
30 | + r = argv[j]; | |
31 | + if (i == 0){ | |
32 | + break; | |
33 | + } | |
34 | + i--; | |
35 | + } | |
36 | + } | |
37 | + } | |
38 | + */ | |
39 | + if (i != 0){ | |
40 | + r = NULL; | |
41 | + } | |
42 | + return r; | |
43 | +} | |
44 | + | |
45 | +void devFunc0001(int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r) | |
46 | +{ | |
47 | + // OSASK文字列の出力 | |
48 | + while (len > 0) { | |
49 | + putOsaskChar(*puc++, r); | |
50 | + len--; | |
51 | + } | |
52 | + return; | |
53 | +} | |
54 | + | |
55 | +void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r) | |
56 | +{ | |
57 | + // drawString | |
58 | + int xx; | |
59 | + int yy; | |
60 | + int i, ddx, ddy, j, ch, dx, dy; | |
61 | + | |
62 | + if (sy == 0){ | |
63 | + sy = sx; | |
64 | + } | |
65 | + xx = x + sx * 8; | |
66 | + yy = y + sy * 16; | |
67 | + if (xx <= 0 || xx > mainWindow.xsize || yy <= 0 || yy > mainWindow.ysize){ | |
68 | + (*(r->errHndl))(r); | |
69 | + } | |
70 | + if (x < 0 || x >= mainWindow.xsize || y < 0 || y >= mainWindow.ysize){ | |
71 | + (*(r->errHndl))(r); | |
72 | + } | |
73 | + | |
74 | + | |
75 | + if ((mod & 3) == 0 && sx == 1 && sy == 1) { | |
76 | + // メジャーケースを高速化. | |
77 | + for (i = 0; i < len; i++) { | |
78 | + ch = puc[i]; | |
79 | + if (0x10 <= ch && ch <= 0x1f) | |
80 | + ch = "0123456789ABCDEF"[ch & 0x0f]; | |
81 | + for (dy = 0; dy < 16; dy++) { | |
82 | + j = fontdata[(ch - ' ') * 16 + dy]; | |
83 | + for (dx = 0; dx < 8; dx++) { | |
84 | + if ((j & (0x80 >> dx)) != 0){ | |
85 | + mainWindow.vram[(x + dx) + (y + dy) * mainWindow.xsize] = c; | |
86 | + } | |
87 | + } | |
88 | + } | |
89 | + x += 8; | |
90 | + } | |
91 | + return; | |
92 | + } | |
93 | + for (i = 0; i < len; i++) { | |
94 | + ch = puc[i]; | |
95 | + if (0x10 <= ch && ch <= 0x1f) | |
96 | + ch = "0123456789ABCDEF"[ch & 0x0f]; | |
97 | + for (dy = 0; dy < 16; dy++) { | |
98 | + j = fontdata[(ch - ' ') * 16 + dy]; | |
99 | + for (ddy = 0; ddy < sy; ddy++) { | |
100 | + for (dx = 0; dx < 8; dx++) { | |
101 | + if ((j & (0x80 >> dx)) != 0) { | |
102 | + for (ddx = 0; ddx < sx; ddx++) { | |
103 | + switch (mod & 3) { | |
104 | + case 0: | |
105 | + mainWindow.vram[x + y * mainWindow.xsize] = c; | |
106 | + break; | |
107 | + case 1: | |
108 | + mainWindow.vram[x + y * mainWindow.xsize] |= c; | |
109 | + break; | |
110 | + case 2: | |
111 | + mainWindow.vram[x + y * mainWindow.xsize] ^= c; | |
112 | + break; | |
113 | + case 3: | |
114 | + mainWindow.vram[x + y * mainWindow.xsize] &= c; | |
115 | + break; | |
116 | + } | |
117 | + x++; | |
118 | + } | |
119 | + } else{ | |
120 | + x += sx; | |
121 | + } | |
122 | + } | |
123 | + x -= sx * 8; | |
124 | + y++; | |
125 | + } | |
126 | + } | |
127 | + x += sx * 8; | |
128 | + y -= sy * 16; | |
129 | + } | |
130 | + return; | |
131 | +} | |
132 | + | |
133 | +void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c) | |
134 | +{ | |
135 | + // FillRect | |
136 | + int x, y; | |
137 | + if (mod == 0) { | |
138 | + for (y = y0; y <= y1; y++) { | |
139 | + for (x = x0; x <= x1; x++) { | |
140 | + mainWindow.vram[x + y * mainWindow.xsize] = c; | |
141 | + } | |
142 | + } | |
143 | + } | |
144 | + else { | |
145 | + for (y = y0; y <= y1; y++) { | |
146 | + for (x = x0; x <= x1; x++) { | |
147 | + switch (mod) { | |
148 | + case 1: | |
149 | + mainWindow.vram[x + y * mainWindow.xsize] |= c; | |
150 | + break; | |
151 | + case 2: | |
152 | + mainWindow.vram[x + y * mainWindow.xsize] ^= c; | |
153 | + break; | |
154 | + case 3: | |
155 | + mainWindow.vram[x + y * mainWindow.xsize] &= c; | |
156 | + break; | |
157 | + } | |
158 | + } | |
159 | + } | |
160 | + } | |
161 | + return; | |
162 | +} | |
163 | + | |
164 | +int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r) | |
165 | +{ | |
166 | + // OSASK文字列への変換? | |
167 | + int i = 0, base, j, k; | |
168 | + char sign; | |
169 | + | |
170 | + while (plen > 0) { | |
171 | + if (i >= buflen){ | |
172 | + (*(r->errHndl))(r); | |
173 | + } | |
174 | + if (*p != 0x01) { | |
175 | + buf[i++] = *p++; | |
176 | + plen--; | |
177 | + continue; | |
178 | + } | |
179 | + p++; | |
180 | + plen--; | |
181 | + if (qlen < 4){ | |
182 | + (*(r->errHndl))(r); | |
183 | + } | |
184 | + base = q[0]; | |
185 | + sign = 0; | |
186 | + if (base == 0){ | |
187 | + base = 16; | |
188 | + } | |
189 | +#if (REVISION == 1) | |
190 | + if (base == -3){ | |
191 | + base = 10; | |
192 | + } | |
193 | +#endif | |
194 | + if (base == -1){ | |
195 | + base = 10; | |
196 | + } | |
197 | + if (base < 0 || base > 16){ | |
198 | + (*(r->errHndl))(r); | |
199 | + } | |
200 | + if (q[1] + i > buflen){ | |
201 | + (*(r->errHndl))(r); | |
202 | + } | |
203 | + j = q[3]; | |
204 | + if ((q[2] & 4) == 0) { | |
205 | + // jは符号付き整数. | |
206 | + if ((q[2] & 8) != 0 && j > 0){ | |
207 | + sign = '+'; | |
208 | + } | |
209 | + if (j < 0) { | |
210 | + sign = '-'; j *= -1; | |
211 | + } | |
212 | + } else{ | |
213 | + // jは符号無し整数. | |
214 | + if ((q[2] & 8) != 0 && j != 0){ | |
215 | + sign = '+'; | |
216 | + } | |
217 | + } | |
218 | + for (k = q[1] - 1; k >= 0; k--) { | |
219 | + buf[i + k] = (j % base) + 0x10; | |
220 | + j = ((unsigned)j) / base; | |
221 | + } | |
222 | + k = 0; | |
223 | + if ((q[2] & 2) == 0 && j == 0) { | |
224 | + for (k = 0; k < q[1] - 1; k++) { | |
225 | + if (buf[i + k] != 0x10){ | |
226 | + break; | |
227 | + } | |
228 | + buf[i + k] = ' '; | |
229 | + } | |
230 | + } | |
231 | + if (sign != 0) { | |
232 | + if (k > 0){ | |
233 | + k--; | |
234 | + } | |
235 | + buf[i + k] = sign; | |
236 | + } | |
237 | + if ((q[2] & 1) != 0 && buf[i] == ' ') { | |
238 | + for (j = 0; k < q[1]; k++, j++){ | |
239 | + buf[i + j] = buf[i + k]; | |
240 | + } | |
241 | + i += j; | |
242 | + } else{ | |
243 | + i += q[1]; | |
244 | + } | |
245 | + qlen -= 4; | |
246 | + q += 4; | |
247 | + } | |
248 | + return i; | |
249 | +} | |
250 | + | |
251 | +void devFunc(HOSECPU_RuntimeEnvironment *r) | |
252 | +{ | |
253 | + FILE *fp; | |
254 | + int i, c; | |
255 | + int x, y, len, dx, dy; | |
256 | + unsigned char *puc; | |
257 | + unsigned char pucbuf[256]; | |
258 | + | |
259 | + //サイズを節約するためにEBPを128バイトずらしているのを元に戻す | |
260 | + r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - jitCompA0001_EBP128); | |
261 | + | |
262 | + if (r->winClosed != 0){ | |
263 | + longjmp(r->setjmpEnv, 1); | |
264 | + } | |
265 | + if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) { | |
266 | + if (mainWindow.vram == NULL) { | |
267 | + mainWindow.xsize = 640; | |
268 | + mainWindow.ysize = 480; | |
269 | + mainWindow.vram = malloc(640 * 480 * 4); | |
270 | + drv_openWin(640, 480, (void *)mainWindow.vram, &r->winClosed); | |
271 | + r->autoSleep = 1; | |
272 | + for (i = 640 * 480 - 1; i >= 0; i--){ | |
273 | + mainWindow.vram[i] = 0; | |
274 | + } | |
275 | + } | |
276 | + } | |
277 | + | |
278 | + switch (r->ireg[0x30]){ | |
279 | + case 0xff00: | |
280 | + printf("R31=%d(dec)\n", r->ireg[0x31]); | |
281 | + break; | |
282 | + | |
283 | + case 0xff01: | |
284 | + // junkApi_fopenRead(_filesize, _p, arg) | |
285 | + // args: R31=arg, R30=_filesize, P31=_p | |
286 | + // retv: R30, P31 | |
287 | + if (r->buf0 == NULL){ | |
288 | + r->buf0 = malloc(1024 * 1024); | |
289 | + } | |
290 | + if (r->mainArgc <= r->ireg[0x31]) { | |
291 | + fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]); | |
292 | + exit(1); | |
293 | + } | |
294 | + fp = fopen(r->mainArgv[r->ireg[0x31]], "rb"); | |
295 | + if (fp == NULL) { | |
296 | + fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]); | |
297 | + exit(1); | |
298 | + } | |
299 | + i = (int)fread(r->buf0, 1, 1024 * 1024 - 4, fp); | |
300 | + if (i >= 1024 * 1024 - 4 || i < 0) { | |
301 | + fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->mainArgv[r->ireg[0x31]]); | |
302 | + exit(1); | |
303 | + } | |
304 | + fclose(fp); | |
305 | + r->preg[0x31].p = r->buf0; | |
306 | + r->preg[0x31].p0 = r->buf0; | |
307 | + r->preg[0x31].p1 = r->buf0 + i; | |
308 | + r->preg[0x31].typ = 3; // T_UINT8 | |
309 | + r->ireg[0x30] = i; | |
310 | + break; | |
311 | + | |
312 | + case 0xff02: | |
313 | + // junkApi_fopenWrite(arg, filesize, p) | |
314 | + // args: R31=arg, R32=filesize, P31=p | |
315 | + // retv: (none) | |
316 | + if (r->mainArgc <= r->ireg[0x31]) { | |
317 | + fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]); | |
318 | + exit(1); | |
319 | + } | |
320 | + fp = fopen(r->mainArgv[r->ireg[0x31]], "wb"); | |
321 | + if (fp == NULL) { | |
322 | + fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]); | |
323 | + exit(1); | |
324 | + } | |
325 | + if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){ | |
326 | + fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]); | |
327 | + exit(1); | |
328 | + } | |
329 | + fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp); | |
330 | + fclose(fp); | |
331 | + break; | |
332 | + | |
333 | + case 0xff03: | |
334 | + // junkApi_allocBuf(_p) | |
335 | + // args: P31=_p | |
336 | + // retv: P31 | |
337 | + if (r->buf1 == NULL){ | |
338 | + r->buf1 = malloc(1024 * 1024); | |
339 | + } | |
340 | + r->preg[0x31].p = r->buf1; | |
341 | + r->preg[0x31].p0 = r->buf1; | |
342 | + r->preg[0x31].p1 = r->buf1 + 1024 * 1024; | |
343 | + break; | |
344 | + | |
345 | + case 0xff04: | |
346 | + printf("P31.(p-p0)=%d(dec)\n", (int)(r->preg[0x31].p - r->preg[0x31].p0)); | |
347 | + break; | |
348 | + | |
349 | + case 0xff05: | |
350 | + // junkApi_writeStdout(len, p) | |
351 | + // args: R31=len, P31=p | |
352 | + // retv: (none) | |
353 | + fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout); | |
354 | + break; | |
355 | + | |
356 | + case 0xff06: | |
357 | + // junkApi_exit(i) | |
358 | + // args: R31=i | |
359 | + // retv: (none) | |
360 | + r->appReturnCode = r->ireg[31]; | |
361 | + longjmp(r->setjmpEnv, 1); | |
362 | + break; | |
363 | + | |
364 | + case 0xff07: | |
365 | + // junkApi_putConstString0(s) | |
366 | + // DB(0xff,0x00,0x00); DB%(s,0x00); | |
367 | + // マシになった文字列表示. | |
368 | + // OSASK文字列に対応.offにすれば通常の文字列処理もできる. | |
369 | + // 現状はonのみサポート. | |
370 | + checkString(r, 0x31, 0x31); | |
371 | + devFunc0001(r->ireg[0x31], r->preg[0x31].p, r); | |
372 | + break; | |
373 | + | |
374 | + case 0xff08: | |
375 | + // junkApi_jitc2(_rc, _p, mod, lev, di1, len, s) | |
376 | + // R31=mod; R32=lev; R33=di1; R34=len; P31=s; _rc=R30; _p=P31 | |
377 | + // JITC on JITC | |
378 | + // R31: 言語(back-end, front-end, ... | |
379 | + // R32: level | |
380 | + // R33: debugInfo1 | |
381 | + checkString(r, 0x34, 0x31); | |
382 | + if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15){ | |
383 | + (*(r->errHndl))(r); | |
384 | + } | |
385 | + for (i = 0; i < r->maxLabels; i++){ | |
386 | + r->label[i].opt = 0; | |
387 | + } | |
388 | + puc = r->preg[0x31].p; | |
389 | + i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + 0); | |
390 | + if (i == 0) { | |
391 | + i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + JITC_PHASE1 + 0); | |
392 | + if (i >= 0) { | |
393 | + r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = di1_serial; | |
394 | + di1_serial++; | |
395 | + r->ireg[0x30] = 0; | |
396 | + r->preg[0x31].p = r->jitbuf; | |
397 | + r->preg[0x31].typ = 0; // TYP_CODE | |
398 | + r->preg[0x31].p0 = r->jitbuf; | |
399 | + r->preg[0x31].p1 = r->jitbuf + 1; | |
400 | + //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n'); | |
401 | + r->jitbuf += i; | |
402 | + static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 }; | |
403 | + i = jitCompiler(r->jitbuf, r->jitbuf1, ff08_ret, ff08_ret + 3, puc, r->label, r->maxLabels, r->ireg[0x32], -1, JITC_NOSTARTUP + JITC_PHASE1 + 0); | |
404 | + r->jitbuf += i; | |
405 | + break; | |
406 | + } | |
407 | + } | |
408 | + r->ireg[0x30] = -1; | |
409 | + break; | |
410 | + | |
411 | + case 0xff09: | |
412 | + //putStringDec | |
413 | + // たぶんbit7を使ったテキストはうまく処理できない(これはもはや仕様にしても問題ないかも). | |
414 | + checkString(r, 0x31, 0x31); | |
415 | + len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r); | |
416 | + devFunc0001(len, pucbuf, r); | |
417 | + break; | |
418 | + | |
419 | + case 0xff40: | |
420 | + // junkApi_openWin(xsiz, ysiz) R31=xsiz; R32=ysiz; | |
421 | + /* R31とR32でサイズを指定 */ | |
422 | + mainWindow.xsize = r->ireg[0x31]; | |
423 | + mainWindow.ysize = r->ireg[0x32]; | |
424 | + if (mainWindow.xsize <= 0 || mainWindow.ysize <= 0){ | |
425 | + (*(r->errHndl))(r); | |
426 | + } | |
427 | + r->preg[0x31].p = (void *)(mainWindow.vram = malloc(mainWindow.xsize * mainWindow.ysize * 4)); | |
428 | + r->preg[0x31].p0 = r->preg[0x31].p; | |
429 | + r->preg[0x31].p1 = r->preg[0x31].p + mainWindow.xsize * mainWindow.ysize * 4; | |
430 | + drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed); | |
431 | + // drv_flshWin(r->ireg[1], r->ireg[2], 0, 0); | |
432 | + r->autoSleep = 1; | |
433 | + for (i = mainWindow.xsize * mainWindow.ysize - 1; i >= 0; i--){ | |
434 | + mainWindow.vram[i] = 0; | |
435 | + } | |
436 | + break; | |
437 | + | |
438 | + case 0xff41: | |
439 | + // junkApi_flushWin(xsiz, ysiz, x0, y0) | |
440 | + // R31=xsiz; R32=ysiz; R33=x0; R34=y0 | |
441 | + /* R31とR32でサイズを指定、R33とR34でx0,y0指定 */ | |
442 | + if (r->ireg[0x31] == -1) { | |
443 | + r->ireg[0x31] = mainWindow.xsize; r->ireg[0x33] &= 0; | |
444 | + } | |
445 | + if (r->ireg[0x32] == -1) { | |
446 | + r->ireg[0x32] = mainWindow.ysize; r->ireg[0x34] &= 0; | |
447 | + } | |
448 | + checkRect(r, 0x31); | |
449 | + drv_flshWin(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34]); | |
450 | + break; | |
451 | + | |
452 | + case 0xff42: | |
453 | + // junkApi_sleep(opt, msec) R31=opt; R32=msec | |
454 | + if (r->ireg[0x32] == -1) { | |
455 | + r->autoSleep = 1; | |
456 | + longjmp(r->setjmpEnv, 1); | |
457 | + } | |
458 | + if (r->ireg[0x32] < 0){ | |
459 | + (*(r->errHndl))(r); | |
460 | + } | |
461 | + r->autoSleep = 0; | |
462 | + if ((r->ireg[0x31] & 1) == 0 && mainWindow.vram != NULL){ | |
463 | + drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0); | |
464 | + } | |
465 | + for (;;) { | |
466 | + if (r->winClosed != 0){ | |
467 | + longjmp(r->setjmpEnv, 1); | |
468 | + } | |
469 | + drv_sleep(r->ireg[0x32]); | |
470 | + if ((r->ireg[0x31] & 2) != 0 && keybuf_c <= 0){ | |
471 | + continue; | |
472 | + } | |
473 | + break; | |
474 | + } | |
475 | + break; | |
476 | + | |
477 | + case 0xff43: | |
478 | + // junkApi_inkey(_i, mod) R31=mod; _i=R30 | |
479 | + // 1:peek | |
480 | + // 2:stdin | |
481 | + // 4,8: ソース指定. | |
482 | + // 16: shift, lock系を有効化. | |
483 | + // 32: 左右のshift系を区別する. | |
484 | + if (r->ireg[0x31] == 2) { // なぜ3にしなかったのか... | |
485 | + r->ireg[0x30] = fgetc(stdin); | |
486 | + if (r->ireg[0x30] == EOF){ | |
487 | + r->ireg[0x30] = -1; | |
488 | + } | |
489 | + break; | |
490 | + } | |
491 | + r->ireg[0x30] |= -1; | |
492 | + if (keybuf_c > 0) { | |
493 | + r->ireg[0x30] = keybuf[keybuf_r]; | |
494 | + if ((r->ireg[0x31] & 16) == 0){ | |
495 | + r->ireg[0x30] &= 0x3e3effff; | |
496 | + } | |
497 | + if ((r->ireg[0x31] & 32) == 0){ | |
498 | + r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000; | |
499 | + } | |
500 | + if ((r->ireg[0x31] & 1) != 0) { | |
501 | + keybuf_c--; | |
502 | + keybuf_r = (keybuf_r + 1) & (KEYBUFSIZ - 1); | |
503 | + } | |
504 | + } | |
505 | + r->ireg[0x32] = r->ireg[0x33] = 0; | |
506 | + if (r->ireg[0x30] == 4132) r->ireg[0x32]--; | |
507 | + if (r->ireg[0x30] == 4133) r->ireg[0x33]--; | |
508 | + if (r->ireg[0x30] == 4134) r->ireg[0x32]++; | |
509 | + if (r->ireg[0x30] == 4135) r->ireg[0x33]++; | |
510 | + break; | |
511 | + | |
512 | + case 0xff44: | |
513 | + // junkApi_drawPoint(mod, x, y, c) R31=mod; R32=x; R33=y; R34=c | |
514 | + c = loadColor(r, 0x34); | |
515 | + if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize || | |
516 | + r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){ | |
517 | + (*(r->errHndl))(r); | |
518 | + } | |
519 | + | |
520 | + switch ((r->ireg[0x31] & 3)) { | |
521 | + case 0: | |
522 | + mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] = c; | |
523 | + break; | |
524 | + case 1: | |
525 | + mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] |= c; | |
526 | + break; | |
527 | + case 2: | |
528 | + mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] ^= c; | |
529 | + break; | |
530 | + case 3: | |
531 | + mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] &= c; | |
532 | + break; | |
533 | + } | |
534 | + break; | |
535 | + | |
536 | + case 0xff45: | |
537 | + // junkApi_drawLine(mod, x0, y0, x1, y1, c) DB(0xfe,0x05,0x01); DDBE(0x0003); R30=0xff45; R31=mod; R32=x0; R33=y0; R34=x1; R35=y1; R36=c | |
538 | + //drawLine | |
539 | + c = loadColor(r, 0x36); | |
540 | + if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize || | |
541 | + r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){ | |
542 | + (*(r->errHndl))(r); | |
543 | + } | |
544 | + if (r->ireg[0x34] < 0 || r->ireg[0x34] >= mainWindow.xsize || | |
545 | + r->ireg[0x35] < 0 || r->ireg[0x35] >= mainWindow.ysize){ | |
546 | + (*(r->errHndl))(r); | |
547 | + } | |
548 | + dx = r->ireg[0x34] - r->ireg[0x32]; | |
549 | + dy = r->ireg[0x35] - r->ireg[0x33]; | |
550 | + x = r->ireg[0x32] << 10; | |
551 | + y = r->ireg[0x33] << 10; | |
552 | + if (dx < 0){ | |
553 | + dx = -dx; | |
554 | + } | |
555 | + if (dy < 0){ | |
556 | + dy = -dy; | |
557 | + } | |
558 | + if (dx >= dy) { | |
559 | + len = dx + 1; dx = 1024; | |
560 | + if (r->ireg[0x32] > r->ireg[0x34]){ | |
561 | + dx *= -1; | |
562 | + } | |
563 | + if (r->ireg[0x33] > r->ireg[0x35]){ | |
564 | + dy *= -1; | |
565 | + } | |
566 | + dy = (dy << 10) / len; | |
567 | + } else { | |
568 | + len = dy + 1; dy = 1024; | |
569 | + if (r->ireg[0x33] > r->ireg[0x35]){ | |
570 | + dy *= -1; | |
571 | + } | |
572 | + if (r->ireg[0x32] > r->ireg[0x34]){ | |
573 | + dx *= -1; | |
574 | + } | |
575 | + dx = (dx << 10) / len; | |
576 | + } | |
577 | + if ((r->ireg[0x31] & 3) == 0) { | |
578 | + for (i = 0; i < len; i++) { | |
579 | + mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] = c; | |
580 | + x += dx; | |
581 | + y += dy; | |
582 | + } | |
583 | + break; | |
584 | + } | |
585 | + for (i = 0; i < len; i++) { | |
586 | + // if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] = c; | |
587 | + switch ((r->ireg[0x31] & 3)) { | |
588 | + case 1: | |
589 | + mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] |= c; | |
590 | + break; | |
591 | + case 2: | |
592 | + mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] ^= c; | |
593 | + break; | |
594 | + case 3: | |
595 | + mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] &= c; | |
596 | + break; | |
597 | + default: | |
598 | + break; | |
599 | + } | |
600 | + x += dx; | |
601 | + y += dy; | |
602 | + } | |
603 | + break; | |
604 | + | |
605 | + case 0xff46: | |
606 | + // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36) | |
607 | + c = loadColor(r, 0x36); | |
608 | + if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; } | |
609 | + if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; } | |
610 | + checkRect(r, 0x32); | |
611 | + int mod3 = r->ireg[0x31] & 3, x0 = r->ireg[0x34], y0 = r->ireg[0x35], x1 = r->ireg[0x34] + r->ireg[0x32] - 1, y1 = r->ireg[0x35] + r->ireg[0x33] - 1; | |
612 | + if ((r->ireg[0x31] & 0x20) == 0) { | |
613 | + devFunc0004(mod3, x0, y0, x1, y1, c); | |
614 | + } else { // drawRect | |
615 | + devFunc0004(mod3, x0, y0, x1, y0, c); | |
616 | + devFunc0004(mod3, x0, y1, x1, y1, c); | |
617 | + devFunc0004(mod3, x0, y0, x0, y1, c); | |
618 | + devFunc0004(mod3, x1, y0, x1, y1, c); | |
619 | + } | |
620 | + break; | |
621 | + | |
622 | + case 0xff47: | |
623 | + // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36) | |
624 | + // これの計算精度はアーキテクチャに依存する. | |
625 | + c = loadColor(r, 0x36); | |
626 | + if (r->ireg[0x32] == -1) { | |
627 | + r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; | |
628 | + } | |
629 | + if (r->ireg[0x33] == -1) { | |
630 | + r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; | |
631 | + } | |
632 | + checkRect(r, 0x32); | |
633 | + double dcx = 0.5 * (r->ireg[0x32] - 1); | |
634 | + double dcy = 0.5 * (r->ireg[0x33] - 1); | |
635 | + double dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1; | |
636 | + dcxy *= dcxy; | |
637 | + mod3 = r->ireg[0x31] & 3; | |
638 | + x1 = r->ireg[0x32]; | |
639 | + y1 = r->ireg[0x33]; | |
640 | + if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) { | |
641 | + for (y = 0; y < y1; y++) { | |
642 | + double dty = (y - dcy) * dcx; | |
643 | + for (x = 0; x < x1; x++) { | |
644 | + double dtx = (x - dcx) * dcy; | |
645 | + if (dtx * dtx + dty * dty > dcxy){ | |
646 | + continue; | |
647 | + } | |
648 | + mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c; | |
649 | + } | |
650 | + } | |
651 | + } else { | |
652 | +#define DRAWOVALPARAM 1 | |
653 | + double dcx1 = 0.5 * (r->ireg[0x32] - (1 + DRAWOVALPARAM * 2)); | |
654 | + double dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2)); | |
655 | + double dcxy1 = (dcx1 + 0.5) * (dcy1 + 0.5) - 0.1; | |
656 | + dcxy1 *= dcxy1; | |
657 | + for (y = 0; y < y1; y++) { | |
658 | + double dty = (y - dcy) * dcx; | |
659 | + double dty1 = (y - dcy) * dcx1; | |
660 | + for (x = 0; x < x1; x++) { | |
661 | + double dtx = (x - dcx) * dcy; | |
662 | + double dtx1 = (x - dcx) * dcy1; | |
663 | + if (dtx * dtx + dty * dty > dcxy){ | |
664 | + continue; | |
665 | + } | |
666 | + if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) { | |
667 | + if (dtx1 * dtx1 + dty1 * dty1 < dcxy1){ | |
668 | + continue; | |
669 | + } | |
670 | + } | |
671 | + switch (mod3) { | |
672 | + case 0: | |
673 | + mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c; | |
674 | + break; | |
675 | + case 1: | |
676 | + mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] |= c; | |
677 | + break; | |
678 | + case 2: | |
679 | + mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] ^= c; | |
680 | + break; | |
681 | + case 3: | |
682 | + mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] &= c; | |
683 | + break; | |
684 | + } | |
685 | + } | |
686 | + } | |
687 | + } | |
688 | + break; | |
689 | + | |
690 | + case 0xff48: | |
691 | + // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31) | |
692 | + checkString(r, 0x37, 0x31); | |
693 | + devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), r->ireg[0x37], r->preg[0x31].p, r); | |
694 | + break; | |
695 | + | |
696 | + case 0xff49: | |
697 | + // junkApi_rand(_r, range) R31=range; _r=R30 | |
698 | + // **** junkApi_rand(i, max) **** | |
699 | + // 0 <= i <= maxとなるiを返す。 | |
700 | + // max==0のとき、iはSINT32全体を範囲とする乱数となる。 | |
701 | + r->ireg[0x30] = randGetNextUInt32(); | |
702 | + if (r->ireg[0x31] > 0){ | |
703 | + r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1); | |
704 | + } | |
705 | + break; | |
706 | + | |
707 | + case 0xff4a: | |
708 | + // srand | |
709 | + randStatInit(r->ireg[0x31]); | |
710 | + break; | |
711 | + | |
712 | + case 0xff4b: | |
713 | + // srand(random) | |
714 | + r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555); | |
715 | + break; | |
716 | + | |
717 | + case 0xff4c: | |
718 | + // drawStringDec | |
719 | + checkString(r, 0x37, 0x31); | |
720 | + len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r); | |
721 | + devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r); | |
722 | + break; | |
723 | + | |
724 | + case 0xff4d: | |
725 | + // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1); | |
726 | + // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color | |
727 | + puc = r->preg[0x31].p; | |
728 | + mod3 = r->ireg[0x31] & 3; | |
729 | + dx = r->ireg[0x34]; | |
730 | + dy = r->ireg[0x35]; | |
731 | + if (dy == 0){ | |
732 | + dy = dx; | |
733 | + } | |
734 | + if (r->ireg[0x32] == -1) { | |
735 | + r->ireg[0x32] = mainWindow.xsize / dx; r->ireg[0x36] &= 0; | |
736 | + } | |
737 | + if (r->ireg[0x33] == -1) { | |
738 | + r->ireg[0x33] = mainWindow.ysize / dy; r->ireg[0x37] &= 0; | |
739 | + } | |
740 | + for (y = 0; y < r->ireg[0x33]; y++) { | |
741 | + y0 = y * dy + r->ireg[0x37]; | |
742 | + for (x = 0; x < r->ireg[0x32]; x++) { | |
743 | + x0 = x * dx + r->ireg[0x36]; | |
744 | + c = iColor1[*puc++]; | |
745 | + devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c); | |
746 | + } | |
747 | + puc += r->ireg[0x38]; | |
748 | + } | |
749 | + break; | |
750 | + | |
751 | + default: | |
752 | + printf("devFunc: error: R30=%08X\n", r->ireg[0x30]); | |
753 | + exit(EXIT_FAILURE); | |
754 | + | |
755 | + } | |
756 | + return; | |
757 | +} | |
758 | + | |
759 | + | |
760 | + |
@@ -62,7 +62,20 @@ int jitCompCmdLen(const unsigned char *src) | ||
62 | 62 | return i; |
63 | 63 | } |
64 | 64 | |
65 | +void PRegCopy(HOSECPU_PointerRegisterEntry *dst, HOSECPU_PointerRegisterEntry *src) | |
66 | +{ | |
67 | + // なんか直接代入するとMacではアライメントエラーで落ちるのです... | |
68 | + // dst = src; | |
65 | 69 | |
70 | + dst->p = src->p; | |
71 | + dst->typ = src->typ; | |
72 | + dst->p0 = src->p0; | |
73 | + dst->p1 = src->p1; | |
74 | + dst->liveSign = src->liveSign; | |
75 | + dst->pls = src->pls; | |
76 | + dst->flags = src->flags; | |
77 | + dst->dummy = src->dummy; | |
78 | +} | |
66 | 79 | |
67 | 80 | |
68 | 81 |
@@ -1,7 +1,9 @@ | ||
1 | - | |
1 | + | |
2 | 2 | #ifndef HeavyOSECPU_jitc_h |
3 | 3 | #define HeavyOSECPU_jitc_h |
4 | 4 | |
5 | + | |
6 | + | |
5 | 7 | // Error flags |
6 | 8 | #define JITC_ERR_MASK 255 |
7 | 9 | #define JITC_ERR_PHASE0ONLY 256 |
@@ -39,7 +41,49 @@ int jitCompCmdLen(const unsigned char *src); | ||
39 | 41 | // |
40 | 42 | // for x86-32bit |
41 | 43 | // |
42 | - | |
44 | +#define IA32_REG0_EAX 0 | |
45 | +#define IA32_REG1_ECX 1 | |
46 | +#define IA32_REG2_EDX 2 | |
47 | +#define IA32_REG3_EBX 3 | |
48 | +#define IA32_REG4_ESP 4 | |
49 | +#define IA32_REG5_EBP 5 | |
50 | +#define IA32_REG6_ESI 6 | |
51 | +#define IA32_REG7_EDI 7 | |
52 | +// | |
53 | +#define IA32_MOD_R_M(mod, reg, rm) ((mod << 6) | reg << 3 | rm) | |
54 | +// | |
55 | +#define IA32_OP_MOD_INDEXONLY 0 | |
56 | +#define IA32_OP_MOD_INDEX_AND_DISP_BYTE 1 | |
57 | +#define IA32_OP_MOD_INDEX_AND_DISP_FULL 2 | |
58 | +#define IA32_OP_MOD_REGISTER 3 | |
59 | +// | |
60 | +#define IA32_OP_RM32_MOD00_ADDR_DISP32 5 | |
61 | +// | |
62 | +#define envOffset_DBGINFO0 (2304 + 0) | |
63 | +#define envOffset_DBGINFO1 (2304 + 4) | |
64 | +#define envOffset_DBGCURRENTCODE (2304 + 8) | |
65 | +#define envOffset_PTRCTRL (2320) | |
66 | +#define PRegOffset(regid) (256 + 32 * regid) | |
67 | +// | |
68 | +#define jitCompPutImm32(p, i) jitCompPutByte4(p, ((i) & 0xff), (((i) >> 8) & 0xff), (((i) >> 16) & 0xff), (((i) >> 24) & 0xff)) | |
69 | +// | |
70 | +#define jitCompPutOp_ADD_GReg_Imm8(p, dReg, i) jitCompPutByte3(p, 0x83, 0xc0 | dReg, i); /* ADD(reg0, imm8); == [1000 0011] [11000 reg] imm8 */ | |
71 | +#define jitCompPutOp_XOR_GReg_GReg(p, d, s) jitCompPutByte2(w.dst, 0x31, 0xc0 | (s) << 3 | (d)); | |
72 | +#define jitCompPutOp_MOV_GReg_Imm32(p, dReg, i) jitCompPutByte1(p, 0xb8 | dReg); jitCompPutImm32(p, i); /* MOV(reg0, imm32); == [1011 1 reg] imm32 */ | |
73 | +#define jitCompPutOp_PUSHAD(p) jitCompPutByte1(p, 0x60); | |
74 | +#define jitCompPutOp_POPAD(p) jitCompPutByte1(p, 0x61); | |
75 | +#define jitCompPutOp_PUSH_GReg(p, reg) jitCompPutByte1(p, 0x50 | (reg)); | |
76 | +#define jitCompPutOp_PUSH_Imm8(p, i) jitCompPutByte2(p, 0x6a, i); | |
77 | +#define jitCompPutOp_POP_GReg(p, reg) jitCompPutByte1(p, 0x58 | (reg)); | |
78 | +#define jitCompPutOp_CALL_Relative(p, diff) jitCompPutByte1(p, 0xe8); jitCompPutImm32(p, diff); /*次の命令との相対オフセットだけ相対コールする*/ | |
79 | +#define jitCompPutOp_JMPnear(p, diff) jitCompPutByte1(p, 0xe9); jitCompPutImm32(p, diff); /*次の命令との相対オフセットだけ相対ジャンプする*/ | |
80 | +#define jitCompPutOp_JMPshort(p, diff) jitCompPutByte2(p, 0xeb, diff & 0xff);/*次の命令との相対オフセットだけ相対ジャンプする*/ | |
81 | +#define jitCompPutOp_INT3(p) jitCompPutByte1(p, 0xCC); | |
82 | +// | |
83 | +#define jitCompPutOp_MOV_EAX_ZERO(p) jitCompPutOp_XOR_GReg_GReg(p, IA32_REG0_EAX, IA32_REG0_EAX); | |
84 | +// | |
85 | +#define DEBUGCode(work, code) jitCompPutOp_MOV_GReg_Imm32((work)->dst, IA32_REG0_EAX, code); jitCompPutOp_MOV_EBPDisp_GReg(work, envOffset_DBGCURRENTCODE, IA32_REG0_EAX); | |
86 | +// Optimization settings | |
43 | 87 | // 他のCPUへ移植する人へ: |
44 | 88 | // 以下の定数は最適化のためのものなので、すべて0として簡単に移植しても問題ありません |
45 | 89 | #define jitCompA0001_USE_R3F_CMPJMP 1*1 |
@@ -49,8 +93,8 @@ int jitCompCmdLen(const unsigned char *src); | ||
49 | 93 | #define jitCompA0001_OPTIMIZE_JMP 1*1 |
50 | 94 | #define jitCompA0001_OPTIMIZE_MOV 1*1 /* 1にすると速度低下する? */ |
51 | 95 | #define jitCompA0001_OPTIMIZE_CMP 1*1 |
52 | -#define jitCompA0001_OPTIMIZE_ALIGN 4*1 /* 0-8を想定 */ | |
53 | -#define jitCompA0001_EBP128 128*1 | |
96 | +#define jitCompA0001_OPTIMIZE_ALIGN 8 /* 0-8を想定 */ | |
97 | +#define jitCompA0001_EBP128 128 // 0にもできる | |
54 | 98 | |
55 | 99 | struct JitCompWork { |
56 | 100 | unsigned char *dst, *dst0; |
@@ -61,12 +105,12 @@ struct JitCompWork { | ||
61 | 105 | char prefix; //CND命令の値を記録(初期値=0) |
62 | 106 | }; |
63 | 107 | |
64 | -void jitCompPutImm32(struct JitCompWork *w, int i); | |
108 | +// @jitcx86a.c | |
65 | 109 | int jitCompGetImm32(const unsigned char *src); |
66 | 110 | int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src); |
67 | -void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n); | |
68 | -void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32); | |
69 | -void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp); | |
111 | +void jitCompPutModRM_Disp_BaseEBP(struct JitCompWork *w, int disp, int opReg); | |
112 | +void jitCompPutOp_MOV_EBPDisp_GReg(struct JitCompWork *w, int disp, int reg32); | |
113 | +void jitCompPutOp_MOV_GReg_EBPDisp(struct JitCompWork *w, int reg32, int disp); | |
70 | 114 | void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx); |
71 | 115 | void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx); |
72 | 116 | void jitCompA0001_fixPrefix(struct JitCompWork *w); |
@@ -86,6 +130,9 @@ int jitCompA000_dataWidth(int t); | ||
86 | 130 | void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac); |
87 | 131 | void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac); |
88 | 132 | void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx); |
133 | + | |
134 | +// @jitcx86.c | |
135 | +extern unsigned char *errfnc; | |
89 | 136 | 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); |
90 | 137 | unsigned char *jitCompCallFunc(unsigned char *dst, void *func); |
91 | 138 | unsigned char *jitCompInit(unsigned char *dst); |
@@ -105,14 +152,6 @@ void dbgrMain(HOSECPU_RuntimeEnvironment *r); | ||
105 | 152 | |
106 | 153 | |
107 | 154 | |
108 | - | |
109 | - | |
110 | - | |
111 | - | |
112 | - | |
113 | - | |
114 | - | |
115 | - | |
116 | 155 | #endif |
117 | 156 | |
118 | 157 | #endif |
@@ -1,4 +1,4 @@ | ||
1 | -#include "osecpu.h" | |
1 | +#include "osecpu.h" | |
2 | 2 | #include "jitc.h" |
3 | 3 | |
4 | 4 | #if (JITC_ARCNUM == 0x0001) |
@@ -6,264 +6,6 @@ | ||
6 | 6 | // for x86-32bit |
7 | 7 | // |
8 | 8 | |
9 | -void jitCompPutImm32(struct JitCompWork *w, int i) | |
10 | -{ | |
11 | - jitCompPutByte1(w->dst, i & 0xff); | |
12 | - jitCompPutByte1(w->dst, (i >> 8) & 0xff); | |
13 | - jitCompPutByte1(w->dst, (i >> 16) & 0xff); | |
14 | - jitCompPutByte1(w->dst, (i >> 24) & 0xff); | |
15 | - return; | |
16 | -} | |
17 | - | |
18 | -int jitCompGetImm32(const unsigned char *src) | |
19 | -{ | |
20 | - return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; | |
21 | -} | |
22 | - | |
23 | -int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src) | |
24 | -{ | |
25 | - int i = jitCompGetImm32(src); | |
26 | - if (i < 0 || i >= w->maxLabels) { | |
27 | - w->err = JITC_ERR_LABELNUM; | |
28 | - i = 0; | |
29 | - } | |
30 | - return i; | |
31 | -} | |
32 | - | |
33 | -void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n) | |
34 | -{ | |
35 | - disp -= jitCompA0001_EBP128; | |
36 | - if (-128 <= disp && disp <= 127) { | |
37 | - jitCompPutByte2(w->dst, 0x45 | (n << 3), disp & 0xff); | |
38 | - } else { | |
39 | - jitCompPutByte1(w->dst, 0x85 | (n << 3)); | |
40 | - jitCompPutImm32(w, disp); | |
41 | - } | |
42 | - return; | |
43 | -} | |
44 | - | |
45 | -void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32) | |
46 | -{ | |
47 | - jitCompPutByte1(w->dst, 0x89); /* MOV(mem, reg32); */ | |
48 | - jitCompA0001_85DispN(w, disp, reg32); | |
49 | - return; | |
50 | -} | |
51 | - | |
52 | -void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp) | |
53 | -{ | |
54 | - jitCompPutByte1(w->dst, 0x8b); /* MOV(reg32, mem); */ | |
55 | - jitCompA0001_85DispN(w, disp, reg32); | |
56 | - return; | |
57 | -} | |
58 | - | |
59 | -void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx) | |
60 | -{ | |
61 | -#if (jitCompA0001_USE_R3F_IMM32 != 0) | |
62 | - if (rxx == 0x3f) { | |
63 | - jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */ | |
64 | - jitCompPutImm32(w, w->r3f); | |
65 | - return; | |
66 | - } | |
67 | -#endif | |
68 | - if (rxx >= 0x40 || rxx < 0){ | |
69 | - w->err = JITC_ERR_REGNUM; | |
70 | - } | |
71 | - jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, rxx * 4); /* MOV(EAX, [EBP+?]); */ | |
72 | - return; | |
73 | -} | |
74 | - | |
75 | -void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx) | |
76 | -{ | |
77 | - if (rxx >= 0x40 || rxx < 0){ | |
78 | - w->err = JITC_ERR_REGNUM; | |
79 | - } | |
80 | - jitCompA0001_movEbpDispReg32(w, rxx * 4, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
81 | - return; | |
82 | -} | |
83 | - | |
84 | -void jitCompA0001_fixPrefix(struct JitCompWork *w) | |
85 | -{ | |
86 | - if (w->prefix != 0) { | |
87 | - if (w->dst - w->dst0 > 127){ | |
88 | - w->err = JITC_ERR_REGNUM; | |
89 | - } | |
90 | - w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff); | |
91 | - } | |
92 | - return; | |
93 | -} | |
94 | - | |
95 | -void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1) | |
96 | -{ | |
97 | - if (p0 >= 0x3f || p0 < 0){ | |
98 | - w->err = JITC_ERR_PREGNUM; | |
99 | - } | |
100 | - if (p1 >= 0x3f || p1 < 0){ | |
101 | - w->err = JITC_ERR_PREGNUM; | |
102 | - } | |
103 | - /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */ | |
104 | - return; | |
105 | -} | |
106 | - | |
107 | -void jitCompA000_loadRegCacheAll(struct JitCompWork *w) | |
108 | -{ | |
109 | - jitCompA0001_movReg32EbpDisp(w, 3 /* EBX */, 0 * 4); /* EBX = R00; */ | |
110 | - jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */ | |
111 | - jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */ | |
112 | - return; | |
113 | -} | |
114 | - | |
115 | -void jitCompA000_storeRegCacheAll(struct JitCompWork *w) | |
116 | -{ | |
117 | - jitCompA0001_movEbpDispReg32(w, 0 * 4, 3 /* EBX */); /* R00 = EBX; */ | |
118 | - jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */ | |
119 | - jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */ | |
120 | - return; | |
121 | -} | |
122 | - | |
123 | -void jitCompA000_loadRegCacheEcx(struct JitCompWork *w) | |
124 | -{ | |
125 | - jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */ | |
126 | - return; | |
127 | -} | |
128 | - | |
129 | -void jitCompA000_storeRegCacheEcx(struct JitCompWork *w) | |
130 | -{ | |
131 | - jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */ | |
132 | - return; | |
133 | -} | |
134 | - | |
135 | -void jitCompA000_loadRegCacheEdx(struct JitCompWork *w) | |
136 | -{ | |
137 | - jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */ | |
138 | - return; | |
139 | -} | |
140 | - | |
141 | -void jitCompA000_storeRegCacheEdx(struct JitCompWork *w) | |
142 | -{ | |
143 | - jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */ | |
144 | - return; | |
145 | -} | |
146 | - | |
147 | -int jitCompA000_selectRegCache(int rxx, int reg) | |
148 | -{ | |
149 | - switch (rxx) { | |
150 | - case 0: | |
151 | - //EBX | |
152 | - reg = 3; | |
153 | - break; | |
154 | - case 1: | |
155 | - //ECX | |
156 | - reg = 1; | |
157 | - break; | |
158 | - case 2: | |
159 | - //EDX | |
160 | - reg = 2; | |
161 | - break; | |
162 | - } | |
163 | - return reg; | |
164 | -} | |
165 | - | |
166 | -void jitCompA000_loadPRegCacheAll(struct JitCompWork *w) | |
167 | -{ | |
168 | - // jitCompA0001_movReg32EbpDisp(w, 5 /* EBP */, 256 + 0 * 32 + 0); /* EBP = P00; */ | |
169 | - jitCompA0001_movReg32EbpDisp(w, 6 /* ESI */, 256 + 1 * 32 + 0); /* ESI = P01; */ | |
170 | - jitCompA0001_movReg32EbpDisp(w, 7 /* EDI */, 256 + 2 * 32 + 0); /* EDI = P02; */ | |
171 | - return; | |
172 | -} | |
173 | - | |
174 | -void jitCompA000_storePRegCacheAll(struct JitCompWork *w) | |
175 | -{ | |
176 | - // jitCompA0001_movEbpDispReg32(w, 256 + 0 * 32 + 0, 5 /* EBP */); /* P00 = EBP; */ | |
177 | - jitCompA0001_movEbpDispReg32(w, 256 + 1 * 32 + 0, 6 /* ESI */); /* P01 = ESI; */ | |
178 | - jitCompA0001_movEbpDispReg32(w, 256 + 2 * 32 + 0, 7 /* EDI */); /* P02 = EDI; */ | |
179 | - return; | |
180 | -} | |
181 | - | |
182 | -int jitCompA000_selectPRegCache(int pxx, int reg) | |
183 | -{ | |
184 | - // if (pxx == 0) reg = 5; /* EBP */ | |
185 | - switch (pxx) { | |
186 | - case 1: | |
187 | - //ESI | |
188 | - reg = 6; | |
189 | - break; | |
190 | - | |
191 | - case 2: | |
192 | - //EDI | |
193 | - reg = 7; | |
194 | - break; | |
195 | - } | |
196 | - return reg; | |
197 | -} | |
198 | - | |
199 | -int jitCompA000_convTyp(int t) | |
200 | -{ | |
201 | - int r = -1; | |
202 | - | |
203 | - if (1 <= t && t <= 7){ | |
204 | - r = t; | |
205 | - } else if (8 <= t && t <= 13){ | |
206 | - r = 2 | (t & 1); | |
207 | - } else if (14 <= t && t <= 15){ | |
208 | - r = 4 | (t & 1); | |
209 | - } else if (16 <= t && t <= 21){ | |
210 | - r = 6 | (t & 1); | |
211 | - } | |
212 | - return r; | |
213 | -} | |
214 | - | |
215 | -int jitCompA000_dataWidth(int t) | |
216 | -{ | |
217 | - int r = -1; | |
218 | - if (t == 0x0001) r = 256; | |
219 | - t >>= 1; | |
220 | - if (t == 0x0002 / 2) r = 8; | |
221 | - if (t == 0x0004 / 2) r = 16; | |
222 | - if (t == 0x0006 / 2) r = 32; | |
223 | - if (t == 0x0008 / 2) r = 4; | |
224 | - if (t == 0x000a / 2) r = 2; | |
225 | - if (t == 0x000c / 2) r = 1; | |
226 | - if (t == 0x000e / 2) r = 12; | |
227 | - if (t == 0x0010 / 2) r = 20; | |
228 | - if (t == 0x0012 / 2) r = 24; | |
229 | - if (t == 0x0014 / 2) r = 28; | |
230 | - return r; | |
231 | -} | |
232 | - | |
233 | -static unsigned char *errfnc; | |
234 | - | |
235 | -void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac) | |
236 | -{ | |
237 | - if (typ <= 0) { w->err = JITC_ERR_BADTYPE; } | |
238 | - if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; } | |
239 | - jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, 256 + pxx * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ | |
240 | - jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */ | |
241 | - jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */ | |
242 | - jitCompPutImm32(w, errfnc - (w->dst + 4)); | |
243 | - return; | |
244 | -} | |
245 | - | |
246 | -void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac) | |
247 | -// data用. | |
248 | -// 将来的にはaliveやアクセス権チェックも入れる | |
249 | -{ | |
250 | - jitCompA0001_checkType0(w, pxx, typ, ac); | |
251 | - return; | |
252 | -} | |
253 | - | |
254 | -void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx) | |
255 | -{ | |
256 | - jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ | |
257 | - jitCompA0001_85DispN(w, 256 + pxx * 32 + 8, reg); /* p0 */ | |
258 | - jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */ | |
259 | - jitCompPutImm32(w, errfnc - (w->dst + 4)); | |
260 | - jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ | |
261 | - jitCompA0001_85DispN(w, 256 + pxx * 32 + 12, reg); /* p1 */ | |
262 | - jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */ | |
263 | - jitCompPutImm32(w, errfnc - (w->dst + 4)); | |
264 | - return; | |
265 | -} | |
266 | - | |
267 | 9 | // F5の場合、decoderが対応するalloc-freeを結びつけるのが簡単で、typやlenを指定必須にしてもフロントエンドコードに影響はない. |
268 | 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) |
269 | 11 | { |
@@ -281,96 +23,130 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
281 | 23 | const unsigned char *oldsrc; |
282 | 24 | int timecount = 0, i, j = 0, lastlabel = -1, debugInfo0 = -1; |
283 | 25 | int reg0, reg1, reg2, cmp0reg = -1, cmp0lev = 0; |
26 | + | |
284 | 27 | w.dst = w.dst0 = dst; |
285 | 28 | w.err = 0; |
286 | 29 | w.maxLabels = maxLabels; |
287 | 30 | |
288 | 31 | if ((flags & JITC_NOSTARTUP) == 0) { |
289 | - jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */ | |
290 | - jitCompA000_loadRegCacheAll(&w); /* start-up */ | |
32 | + jitCompPutOp_PUSHAD(w.dst); | |
33 | + // Load cache | |
34 | + jitCompA000_loadRegCacheAll(&w); | |
291 | 35 | jitCompA000_loadPRegCacheAll(&w); |
292 | 36 | } |
293 | 37 | if (level <= JITC_LV_SLOWER) { |
294 | - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */ | |
295 | - jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */ | |
296 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
297 | - jitCompPutImm32(&w, debugInfo1); | |
298 | - jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ | |
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); | |
299 | 44 | } |
300 | 45 | while (src < src1) { |
301 | 46 | w.prefix = 0; //0x04 CND 命令で変更される |
302 | - if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; goto err_w; } // 書き込み領域が残り256バイト未満ならエラー | |
47 | + if (w.dst + 256 > dst1) { | |
48 | + // 書き込み領域が残り256バイト未満ならエラー | |
49 | + w.err = JITC_ERR_DST1; | |
50 | + goto err_w; | |
51 | + } | |
303 | 52 | timecount++; |
304 | 53 | if (timecount >= 64) { |
305 | 54 | timecount -= 64; |
306 | 55 | /* 未完成(timeoutチェックコードを入れる) */ |
307 | 56 | } |
308 | - prefix_continue: // CND命令実行後ここに戻る | |
57 | + if(*src != 0x00 && *src != 0x01 && *src != 0x34){ | |
58 | + DEBUGCode(&w, *src); | |
59 | + } | |
60 | + prefix_continue: | |
61 | + // CND命令コンパイル後ここに戻る | |
309 | 62 | switch (*src) { |
310 | - | |
311 | - case 0x00: /* NOP */ | |
312 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } // 「条件付きでNOPを実行」するなんて、矛盾している! | |
63 | + case 0x00: | |
64 | + // NOP | |
65 | + if (w.prefix != 0) { | |
66 | + // 「条件付きでNOPを実行」するなんて、矛盾している! | |
67 | + w.err = JITC_ERR_PREFIX; | |
68 | + goto err_w; | |
69 | + } | |
313 | 70 | break; |
314 | 71 | |
315 | - case 0x01: /* LB */ | |
316 | - | |
317 | - /* | |
318 | - * LB : ラベル設置命令。(6byte) | |
319 | - * ・prefex = 1にする | |
320 | - * ・timecount++し、timecountのチェックをする。 | |
321 | - * ・ラベル位置を登録する。 | |
322 | - * ・割り込みがある場合、このタイミングで割り込みを発生させる。 | |
323 | - * | |
324 | - * 1 2 3 456 | |
325 | - * LB 01 opt imm32 | |
326 | - * | |
327 | - */ | |
328 | - | |
329 | - if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) { //beginFunc()中のLB | |
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 | |
330 | 84 | // LB命令の後に0x3C命令・・・beginFunc() |
331 | - jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする | |
332 | 85 | enter0 = w.dst; |
333 | - jitCompPutImm32(&w, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ?? | |
86 | + jitCompPutOp_JMPnear(w.dst, 0); | |
334 | 87 | } |
335 | - if (src[6] == 0x34) { // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令 | |
336 | - tmp_ucp = w.dst; | |
337 | - jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする | |
338 | - i = jitCompGetImm32(&src[7]); // type32 を取得 | |
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 を取得 | |
339 | 95 | j = 32; |
96 | + | |
340 | 97 | if (i != 1) { |
341 | 98 | i = jitCompA000_convTyp(i); |
342 | 99 | j = 0; |
343 | - if (i == 2 || i == 3) { j = 1; } | |
344 | - if (i == 4 || i == 5) { j = 2; } | |
345 | - if (i == 6 || i == 7) { j = 4; } | |
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 | + } | |
346 | 111 | } |
347 | - j *= jitCompGetImm32(&src[11]); | |
348 | - if (j <= 0) w.err = JITC_ERR_BADTYPE; | |
349 | - jitCompPutImm32(&w, j); | |
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 | + | |
350 | 121 | #if (jitCompA0001_OPTIMIZE_JMP != 0) |
351 | - if (j <= 127 - jitCompA0001_OPTIMIZE_ALIGN) { | |
122 | + if (j < 127 - jitCompA0001_OPTIMIZE_ALIGN) { | |
123 | + //飛び先が十分近いので | |
124 | + // 今書いたのはなかったことにして、 | |
352 | 125 | w.dst -= 5; |
353 | - jitCompPutByte2(w.dst, 0xeb, j); | |
126 | + // よりサイズの小さな書き方にする | |
127 | + jitCompPutOp_JMPshort(w.dst, j); | |
354 | 128 | } |
355 | 129 | #endif |
356 | 130 | } |
357 | 131 | #if (jitCompA0001_OPTIMIZE_ALIGN != 0) |
358 | - for (;;) { | |
359 | - i = ((int)w.dst) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */ | |
360 | - if (i == 0) break; | |
361 | - i = jitCompA0001_OPTIMIZE_ALIGN - i; | |
362 | - if (i == 1) { jitCompPutByte1(w.dst, 0x90); j += i; } /* NOP(); */ | |
363 | - if (i == 2) { jitCompPutByte2(w.dst, 0x89, 0xc0); j += i; } /* MOV(EAX, EAX); */ | |
364 | - if (i == 3) { jitCompPutByte3(w.dst, 0x8d, 0x76, 0x00); j += i; } /* LEA(ESI, [ESI+0]); */ | |
365 | - if (i == 4) { jitCompPutByte4(w.dst, 0x8d, 0x74, 0x26, 0x00); j += i; } /* LEA(ESI, [ESI*1+0]); */ | |
366 | - if (i == 5) { jitCompPutByte1(w.dst, 0x0d); jitCompPutImm32(&w, 0); j += i; } /* OR(EAX, 0); */ | |
367 | - if (i == 6) { jitCompPutByte2(w.dst, 0x8d, 0xb6); jitCompPutImm32(&w, 0); j += i; } /* LEA(ESI, [ESI+0]); */ | |
368 | - if (i >= 7) { jitCompPutByte3(w.dst, 0x8d, 0xb4, 0x26); jitCompPutImm32(&w, 0); j += 7; } /* LEA(ESI, [ESI*1+0]); */ | |
369 | - } | |
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]); */ | |
370 | 143 | #endif |
371 | 144 | if (src[6] == 0x34) { |
145 | + // 後続命令はDATA | |
146 | + // パディングに合わせて一個前の相対ジャンプを修正 | |
372 | 147 | tmp_ucp[1] = j & 0xff; |
373 | 148 | if (*tmp_ucp == 0xe9) { |
149 | + // Near jump so imm is DWORD | |
374 | 150 | tmp_ucp[2] = (j >> 8) & 0xff; |
375 | 151 | tmp_ucp[3] = (j >> 16) & 0xff; |
376 | 152 | tmp_ucp[4] = (j >> 24) & 0xff; |
@@ -378,9 +154,14 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
378 | 154 | } |
379 | 155 | if ((flags & JITC_PHASE1) == 0) { |
380 | 156 | i = jitCompGetLabelNum(&w, src + 2); |
381 | - //printf("i=%06X %06X\n", i, src-src0); | |
382 | - if (label[i].opt != 0 && w.err == 0) { w.err = JITC_ERR_LABELREDEF; goto err_w; } | |
383 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
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) { | |
162 | + w.err = JITC_ERR_PREFIX; | |
163 | + goto err_w; | |
164 | + } | |
384 | 165 | label[i].opt = src[1] + 1; |
385 | 166 | label[i].typ = 0; /* TYP_CODE */ |
386 | 167 | label[i].p = w.dst; |
@@ -392,71 +173,86 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
392 | 173 | /* 未完成(timeoutチェックコードを入れる) */ |
393 | 174 | break; |
394 | 175 | |
395 | - case 0x02: /* LIMM */ | |
396 | - | |
397 | - /* | |
398 | - * LIMM : 定数即値代入命令(6byte) | |
399 | - * | |
400 | - * 1 2 3456 | |
401 | - * 02 reg0R imm32 | |
402 | - * | |
403 | - * ・reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。 | |
404 | - */ | |
176 | + case 0x02: | |
177 | + // LIMM : 定数即値代入命令(6byte) | |
178 | + // Encode: | |
179 | + // 0 1 2345 | |
180 | + // 02 reg0R imm32 | |
181 | + // | |
182 | + // reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。 | |
405 | 183 | |
406 | - if (src[1] == 0x3f && w.prefix != 0) w.err = JITC_ERR_PREFIX; // CND命令の直後でR3Fを書き換えるなんて変だよね | |
184 | + if (src[1] == 0x3f && w.prefix != 0){ | |
185 | + // CND命令の直後でR3Fを書き換えるなんて変だよね | |
186 | + w.err = JITC_ERR_PREFIX; | |
187 | + } | |
407 | 188 | |
408 | 189 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
409 | - if (src[1] == 0x3f) { // R3Fへの代入は例外敵に、 w.r3f を使用 | |
190 | + if (src[1] == 0x3f) { | |
191 | + // R3Fへの代入は例外で、 w.r3f を使用 | |
410 | 192 | w.r3f = jitCompGetImm32(src + 2); |
411 | 193 | break; |
412 | 194 | } |
413 | 195 | #endif |
414 | 196 | i = jitCompGetImm32(src + 2); // 与えられた即値(第二引数)を取得 |
415 | - | |
416 | 197 | /* R00-R02 なら EBX, ECX, EDX 、それ以外なら EAX のレジスタIDを reg0 に代入 */ |
417 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
418 | - | |
198 | + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); | |
199 | + | |
419 | 200 | #if (jitCompA0001_OPTIMIZE_MOV != 0) |
201 | + // size optimization | |
202 | + // MOV reg, 0 -> XOR reg, reg | |
420 | 203 | if (i == 0) { |
421 | - jitCompPutByte2(w.dst, 0x31, 0xc0 | reg0 << 3 | reg0); /* XOR(reg0, reg0); */ | |
204 | + jitCompPutOp_XOR_GReg_GReg(w.dst, reg0, reg0); | |
422 | 205 | jitCompA0001_movRxxEax(&w, src[1]); |
423 | 206 | break; |
424 | 207 | } |
425 | 208 | #endif |
426 | - | |
427 | 209 | /* reg0 のレジスタに対応したMOV命令を発行 */ |
428 | - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); == 10111000b+wr imm32 */ | |
429 | - jitCompPutImm32(&w, i); | |
210 | + jitCompPutOp_MOV_GReg_Imm32(w.dst, reg0, i); | |
430 | 211 | |
431 | - if (reg0 == 0) // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合 | |
432 | - | |
212 | + if (reg0 == 0){ | |
213 | + // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合 | |
433 | 214 | jitCompA0001_movRxxEax(&w, src[1]); |
434 | - break; | |
215 | + } | |
435 | 216 | |
436 | - case 0x03: /* PLIMM */ /* 未完成(plsまで対応) */ | |
217 | + break; | |
437 | 218 | |
438 | - /* | |
439 | - * PLIMM : ラベル番号代入命令(6byte) | |
440 | - * | |
441 | - * 1 2 3456 | |
442 | - * 03 PXX imm32 | |
443 | - * | |
444 | - * ・P28 はAPI用 | |
445 | - * ・P30 はリターンアドレス | |
446 | - * ・P3F はプログラムカウンタ | |
447 | - */ | |
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 | + // | |
448 | 229 | |
449 | 230 | i = jitCompGetLabelNum(&w, src + 2); // Pxxに代入するラベルの番号(第二引数) |
450 | - if ((flags & JITC_PHASE1) != 0 && w.err == 0) { // Phase 1であるならば | |
451 | - if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } // 指定されたラベル番号は存在しない | |
452 | - if (src[1] != 0x3f && label[i].opt != 2) { w.err = JITC_ERR_LABELTYP; goto err_w; } // | |
453 | - if (src[1] == 0x3f && label[i].typ != 0) { w.err = JITC_ERR_LABELTYP; goto err_w; } // プログラムカウンタに TYP_CODEでない値は代入できない | |
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 | + } | |
454 | 248 | } |
455 | - if (src[1] == 0x3f) { // プログラムカウンタへの代入なら | |
456 | - if (w.prefix == 0) { // CND命令による条件付きでなければ、即座に移動 | |
249 | + if (src[1] == 0x3f) { | |
250 | + // プログラムカウンタへの代入 | |
251 | + if (w.prefix == 0) { | |
252 | + // CND命令による条件付きでなければ、即座に移動 | |
457 | 253 | jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */ |
458 | - } | |
459 | - else { // 直前はCND命令。 | |
254 | + } else { | |
255 | + // 直前はCND命令。 | |
460 | 256 | |
461 | 257 | /* |
462 | 258 | * CND命令 |
@@ -466,7 +262,8 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
466 | 262 | * いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd |
467 | 263 | */ |
468 | 264 | |
469 | - // JZのとび先アドレスの書き換え? | |
265 | + // Jccの条件変更 | |
266 | + // 0F 75 | |
470 | 267 | w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */ |
471 | 268 | w.dst[-2] = 0x0f; |
472 | 269 |
@@ -475,15 +272,14 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
475 | 272 | j = 0; |
476 | 273 | if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) // label番号iが確保されていれば (このif文は意味をなさない) |
477 | 274 | j = label[i].p - (w.dst + 4); // j はとび先の相対番地 |
478 | - jitCompPutImm32(&w, j); // JMP もしくは JZ 命令のアドレス部を記述 | |
275 | + jitCompPutImm32(w.dst, j); // JMP もしくは JZ 命令のアドレス部を記述 | |
479 | 276 | #if (jitCompA0001_OPTIMIZE_JMP != 0) |
480 | 277 | if (-128 - 3 <= j && j < 0) { |
481 | 278 | if (w.dst[-5] == 0xe9) { |
482 | 279 | j += 3; |
483 | 280 | w.dst -= 5; |
484 | 281 | jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */ |
485 | - } | |
486 | - else { | |
282 | + } else { | |
487 | 283 | j += 4; |
488 | 284 | w.dst -= 6; |
489 | 285 | jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0); |
@@ -491,60 +287,60 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
491 | 287 | jitCompPutByte1(w.dst, j & 0xff); |
492 | 288 | } |
493 | 289 | #endif |
494 | - } | |
495 | - else { // プログラムカウンタ以外への代入 | |
496 | - | |
290 | + } else { // プログラムカウンタ以外への代入 | |
497 | 291 | // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定 |
498 | - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
499 | - jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ | |
500 | - jitCompPutImm32(&w, (int)label[i].p); // ラベルのパスを各レジスタに代入 | |
501 | - | |
502 | - // レジスタへの代入をメモリでエミュレーションする場合は、スタックに積む。 | |
503 | - if (reg0 == 0) | |
504 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32, 0); /* MOV([EBP+?], 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 | + } | |
505 | 299 | |
506 | 300 | if (level < JITC_LV_FASTEST) { |
507 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 8, reg0); /* MOV([EBP+?], reg0); */ /* p0 */ | |
508 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
509 | - jitCompPutImm32(&w, label[i].typ); | |
510 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 4, 0); /* MOV([EBP+?], EAX); */ /* typ */ | |
511 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
512 | - jitCompPutImm32(&w, (int)label[i].p1); | |
513 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 12, 0); /* MOV([EBP+?], EAX); */ /* p1 */ | |
514 | - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */ | |
515 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 16, 0); /* MOV([EBP+?], EAX); */ /* liveSign */ | |
516 | - jitCompA0001_movReg32EbpDisp(&w, 0, 2320); /* MOV(EAX, ptrCtrl); */ | |
517 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 20, 0); /* MOV([EBP+?], EAX); */ /* pls */ | |
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 */ | |
518 | 310 | } |
519 | 311 | } |
520 | 312 | break; |
521 | 313 | |
522 | - case 0x04: /* CND (prefix) */ | |
523 | - | |
524 | - /* | |
525 | - * CND命令 | |
526 | - * 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。 | |
527 | - */ | |
314 | + case 0x04: | |
315 | + // CND (prefix) | |
316 | + // 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。 | |
528 | 317 | |
529 | - if (src[1] >= 0x40) w.err = JITC_ERR_REGNUM; // R00-R3F 以外のレジスタは比較対象にできない | |
318 | + if (src[1] >= 0x40){ | |
319 | + // R00-R3F 以外のレジスタは比較対象にできない | |
320 | + w.err = JITC_ERR_REGNUM; | |
321 | + goto err_w; | |
322 | + } | |
530 | 323 | |
531 | 324 | // 比較対象のレジスタがメモリ上にあれば-1, それ以外なら適切なレジスタ番号を返す |
532 | 325 | reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */); |
533 | 326 | |
534 | 327 | /* TEST命令を発行 */ |
535 | - if (reg0 < 0) { //比較対象のレジスタはメモリ上にある | |
536 | - jitCompPutByte1(w.dst, 0xf7); /* TEST([EBP+?],1); */ | |
537 | - jitCompA0001_85DispN(&w, src[1] * 4, 0); | |
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 */ | |
538 | 335 | } |
539 | - else { | |
540 | - jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST(reg0,1); */ | |
541 | - } | |
542 | - jitCompPutImm32(&w, 1); | |
336 | + jitCompPutImm32(w.dst, 1); | |
543 | 337 | |
544 | 338 | /* JZ命令を発行 */ |
545 | 339 | jitCompPutByte2(w.dst, 0x74, 0x00); /* JZ($+2) */ |
546 | 340 | cmp0reg = -1; |
547 | - if (w.err != 0) goto err_w; | |
341 | + if (w.err != 0){ | |
342 | + goto err_w; | |
343 | + } | |
548 | 344 | src += 2; |
549 | 345 | w.prefix = 1; // プリフィックスをセット |
550 | 346 | w.dst0 = w.dst; |
@@ -552,21 +348,27 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
552 | 348 | |
553 | 349 | case 0x08: /* LMEM */ /* 完成 */ |
554 | 350 | i = jitCompGetImm32(src + 2); |
555 | - if (i == 0x0001) w.err = JITC_ERR_BADTYPE; | |
351 | + if (i == 0x0001){ | |
352 | + w.err = JITC_ERR_BADTYPE; | |
353 | + } | |
556 | 354 | if (level < JITC_LV_FASTER) { |
557 | 355 | jitCompA0001_checkType(&w, src[6], i, 0); // read |
558 | 356 | cmp0reg = -1; |
559 | 357 | } |
560 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
561 | - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
562 | - if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) | |
563 | - reg1 = 0; /* EAX */ | |
564 | - if (reg1 == 2 /* EDX */) | |
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){ | |
565 | 364 | jitCompA000_storeRegCacheEdx(&w); |
566 | - if (reg1 <= 3 /* EAX, EDX */) | |
567 | - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
568 | - if (level < JITC_LV_FASTER) | |
365 | + } | |
366 | + if (reg1 <= 3 /* EAX, EDX */){ | |
367 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg1, PRegOffset(src[6])); | |
368 | + } | |
369 | + if (level < JITC_LV_FASTER){ | |
569 | 370 | jitCompA0001_checkLimit(&w, reg1, src[6]); |
371 | + } | |
570 | 372 | i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); |
571 | 373 | switch (i) { |
572 | 374 | case 0x0002: |
@@ -588,31 +390,40 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
588 | 390 | default: |
589 | 391 | w.err = JITC_ERR_BADTYPE; |
590 | 392 | } |
591 | - if (reg0 == 0 /* EAX */) | |
393 | + if (reg0 == IA32_REG0_EAX){ | |
592 | 394 | jitCompA0001_movRxxEax(&w, src[1]); |
593 | - if (reg1 == 2 /* EDX */) | |
395 | + } | |
396 | + if (reg1 == IA32_REG2_EDX){ | |
594 | 397 | jitCompA000_loadRegCacheEdx(&w); |
398 | + } | |
595 | 399 | break; |
596 | 400 | |
597 | 401 | case 0x09: /* SMEM */ /* 完成 */ |
598 | 402 | i = jitCompGetImm32(src + 2); |
599 | - if (i == 0x0001) w.err = JITC_ERR_BADTYPE; | |
403 | + if (i == 0x0001){ | |
404 | + w.err = JITC_ERR_BADTYPE; | |
405 | + } | |
600 | 406 | if (level < JITC_LV_FASTER) { |
601 | 407 | jitCompA0001_checkType(&w, src[6], i, 1); // write |
602 | 408 | cmp0reg = -1; |
603 | 409 | } |
604 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
605 | - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
606 | - if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) | |
607 | - reg1 = 0; /* EAX */ | |
608 | - if (reg1 == 2 /* EDX */) | |
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){ | |
609 | 416 | jitCompA000_storeRegCacheEdx(&w); |
610 | - if (reg1 <= 3 /* EAX, EDX */) | |
611 | - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
612 | - if (level < JITC_LV_FASTER) | |
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){ | |
613 | 422 | jitCompA0001_checkLimit(&w, reg1, src[6]); |
614 | - if (reg0 == 0 /* EAX */) | |
423 | + } | |
424 | + if (reg0 == IA32_REG0_EAX){ | |
615 | 425 | jitCompA0001_movEaxRxx(&w, src[1]); |
426 | + } | |
616 | 427 | /* 値の範囲チェック */ |
617 | 428 | i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); |
618 | 429 | switch (i) { |
@@ -631,40 +442,49 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
631 | 442 | default: |
632 | 443 | w.err = JITC_ERR_BADTYPE; |
633 | 444 | } |
634 | - if (reg1 == 2 /* EDX */) | |
445 | + if (reg1 == IA32_REG2_EDX){ | |
635 | 446 | jitCompA000_loadRegCacheEdx(&w); |
447 | + } | |
636 | 448 | break; |
637 | 449 | |
638 | 450 | case 0x0a: /* PLMEM */ /* 完成 */ |
639 | 451 | i = jitCompGetImm32(src + 2); |
640 | - if (i != 0x0001) w.err = JITC_ERR_BADTYPE; | |
452 | + if (i != 0x0001){ | |
453 | + w.err = JITC_ERR_BADTYPE; | |
454 | + } | |
641 | 455 | if (level < JITC_LV_FASTER) { |
642 | 456 | jitCompA0001_checkType(&w, src[6], i, 0); // read |
643 | 457 | cmp0reg = -1; |
644 | 458 | } |
645 | - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
646 | - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
459 | + reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX); | |
460 | + reg1 = jitCompA000_selectPRegCache(src[6], IA32_REG2_EDX); | |
647 | 461 | // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */ |
648 | 462 | // reg1 = 0; /* EAX */ |
649 | - if (reg0 == reg1 && reg0 != 0) { // bugfix: hinted by yao, 2013.09.14. thanks! | |
463 | + if (reg0 == reg1 && reg0 != 0) { | |
464 | + // bugfix: hinted by yao, 2013.09.14. thanks! | |
650 | 465 | jitCompA000_storePRegCacheAll(&w); |
651 | - reg1 = 2; /* EDX */ | |
466 | + reg1 = IA32_REG2_EDX; | |
652 | 467 | } |
653 | - if (reg1 == 2 /* EDX */) | |
468 | + if (reg1 == IA32_REG2_EDX){ | |
654 | 469 | jitCompA000_storeRegCacheEdx(&w); |
655 | - if (reg1 <= 3 /* EAX, EDX */) | |
656 | - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
657 | - if (level < JITC_LV_FASTER) | |
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){ | |
658 | 475 | jitCompA0001_checkLimit(&w, reg1, src[6]); |
476 | + } | |
659 | 477 | jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */ |
660 | - if (reg0 == 0 /* EAX */) | |
661 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0); /* MOV([EBP+?], EAX); */ | |
478 | + if (reg0 == IA32_REG0_EAX){ | |
479 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]), IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
480 | + } | |
662 | 481 | for (i = 4; i < 32; i += 4) { |
663 | 482 | jitCompPutByte3(w.dst, 0x8b, 0x40 | reg1, i); /* MOV(EAX, [reg1+?]); */ |
664 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
483 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
665 | 484 | } |
666 | - if (reg1 == 2 /* EDX */) | |
485 | + if (reg1 == IA32_REG2_EDX){ | |
667 | 486 | jitCompA000_loadRegCacheEdx(&w); |
487 | + } | |
668 | 488 | break; |
669 | 489 | |
670 | 490 | case 0x0b: /* PSMEM */ /* 完成 */ |
@@ -674,24 +494,29 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
674 | 494 | jitCompA0001_checkType(&w, src[6], i, 1); // write |
675 | 495 | cmp0reg = -1; |
676 | 496 | } |
677 | - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
678 | - reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */); | |
679 | - // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */ | |
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 */) | |
680 | 501 | // reg1 = 0; /* EAX */ |
681 | - if (reg1 == 2 /* EDX */) | |
502 | + if (reg1 == IA32_REG2_EDX){ | |
682 | 503 | jitCompA000_storeRegCacheEdx(&w); |
683 | - if (reg1 <= 3 /* EAX, EDX */) | |
684 | - jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */ | |
685 | - if (level < JITC_LV_FASTER) | |
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){ | |
686 | 509 | jitCompA0001_checkLimit(&w, reg1, src[6]); |
687 | - if (reg0 == 0 /* EAX */) | |
688 | - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[1] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
510 | + } | |
511 | + if (reg0 == IA32_REG0_EAX){ | |
512 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[1])); /* MOV(reg0, [EBP+?]); */ | |
513 | + } | |
689 | 514 | jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */ |
690 | 515 | for (i = 4; i < 32; i += 4) { |
691 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[1] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
516 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[1]) + i); /* MOV(EAX, [EBP+?]); */ | |
692 | 517 | jitCompPutByte3(w.dst, 0x89, 0x40 | reg1, i); /* MOV([reg1+?], EAX); */ |
693 | 518 | } |
694 | - if (reg1 == 2 /* EDX */) | |
519 | + if (reg1 == IA32_REG2_EDX) | |
695 | 520 | jitCompA000_loadRegCacheEdx(&w); |
696 | 521 | break; |
697 | 522 |
@@ -700,63 +525,78 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
700 | 525 | jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 2), 2); // other, aliveテストはとりあえずしない. |
701 | 526 | cmp0reg = -1; |
702 | 527 | } |
703 | - reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */); | |
528 | + reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX); | |
704 | 529 | reg1 = jitCompA000_selectPRegCache(src[6], -1 /* mem */); |
705 | - if (reg1 < 0 /* mem */) | |
706 | - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
530 | + if (reg1 < 0 /* mem */){ | |
531 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[6])); /* MOV(reg0, [EBP+?]); */ | |
532 | + } | |
707 | 533 | if (reg1 >= 0 && reg0 != reg1) { |
708 | 534 | jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ |
709 | 535 | } |
710 | 536 | i = jitCompGetImm32(src + 2); |
711 | 537 | j = -1; |
712 | - if (i == 1) | |
538 | + if (i == 1){ | |
713 | 539 | j = 5; /* 32 */ |
714 | - else { | |
540 | + } else { | |
715 | 541 | i = jitCompA000_convTyp(i); |
716 | - if (0x0002 <= i && i <= 0x0007) | |
542 | + if (0x0002 <= i && i <= 0x0007){ | |
717 | 543 | j = (i - 0x0002) >> 1; |
544 | + } | |
545 | + } | |
546 | + if (j < 0) { | |
547 | + w.err = JITC_ERR_BADTYPE; | |
548 | + goto err_w; | |
718 | 549 | } |
719 | - if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
720 | 550 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
721 | 551 | if (src[7] == 0x3f) { |
722 | 552 | j = w.r3f << j; |
723 | 553 | #if (jitCompA0001_USE_R3F_IMM8 != 0) |
724 | 554 | if (-0x80 <= j && j <= 0x7f) { |
725 | 555 | #if (jitCompA0001_USE_R3F_INCDEC != 0) |
726 | - if (j == 1) { jitCompPutByte1(w.dst, 0x40 | reg0); goto padd1; } /* INC */ | |
727 | - if (j == -1) { jitCompPutByte1(w.dst, 0x48 | reg0); goto padd1; } /* DEC */ | |
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 | + } | |
728 | 566 | #endif |
729 | - jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff); /* ADD(reg0, im8); */ | |
567 | + /* ADD(reg0, im8); */ | |
568 | + jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff); | |
730 | 569 | goto padd1; |
731 | 570 | } |
732 | 571 | #endif |
733 | 572 | if (reg0 == 0) { |
734 | 573 | jitCompPutByte1(w.dst, 0x05); /* ADD(reg0, ?); */ |
735 | - } | |
736 | - else { | |
574 | + } else { | |
737 | 575 | jitCompPutByte2(w.dst, 0x81, 0xc0 | reg0); /* ADD(reg0, ?); */ |
738 | 576 | } |
739 | - jitCompPutImm32(&w, j); | |
577 | + jitCompPutImm32(w.dst, j); | |
740 | 578 | goto padd1; |
741 | 579 | } |
742 | 580 | #endif |
743 | - if (src[7] >= 0x40) w.err = JITC_ERR_REGNUM; | |
581 | + if (src[7] >= 0x40){ | |
582 | + w.err = JITC_ERR_REGNUM; | |
583 | + } | |
744 | 584 | if (j == 0) { |
745 | 585 | reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */); |
746 | 586 | if (reg1 >= 0) { |
747 | 587 | jitCompPutByte2(w.dst, 0x01, 0xc0 | reg1 << 3 | reg0); /* ADD(reg0, reg1); */ |
748 | - } | |
749 | - else { | |
588 | + } else { | |
750 | 589 | jitCompPutByte1(w.dst, 0x03); /* ADD(reg0, [EBP+?]); */ |
751 | - jitCompA0001_85DispN(&w, src[7] * 4, reg0); | |
590 | + jitCompPutModRM_Disp_BaseEBP(&w, src[7] * 4, reg0); | |
752 | 591 | } |
753 | 592 | } |
754 | 593 | else { |
755 | 594 | reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */); |
756 | - reg2 = 2; /* EDX */ | |
595 | + reg2 = IA32_REG2_EDX; | |
757 | 596 | jitCompA000_storeRegCacheEdx(&w); |
758 | - if (reg1 < 0) | |
759 | - jitCompA0001_movReg32EbpDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */ | |
597 | + if (reg1 < 0){ | |
598 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */ | |
599 | + } | |
760 | 600 | if (reg1 >= 0 && reg1 != reg2) { |
761 | 601 | jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg2); /* MOV(reg2, reg1); */ |
762 | 602 | } |
@@ -767,35 +607,42 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
767 | 607 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
768 | 608 | padd1: |
769 | 609 | #endif |
770 | - if (reg0 == 0 /* EAX */) | |
771 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, reg0); /* MOV([EBP+?], reg0); */ | |
610 | + if (reg0 == IA32_REG0_EAX){ | |
611 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]), reg0); /* MOV([EBP+?], reg0); */ | |
612 | + } | |
772 | 613 | if (src[1] != src[6]) { |
773 | 614 | for (i = 4; i < 32; i += 4) { |
774 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
775 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
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); */ | |
776 | 617 | } |
777 | 618 | } |
778 | 619 | cmp0reg = -1; |
779 | 620 | break; |
780 | 621 | |
781 | 622 | case 0x0f: /* PDIF */ /* 未完成 */ |
782 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
623 | + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); | |
783 | 624 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
784 | 625 | jitCompA0001_checkCompPtr(&w, src[6], src[7]); |
785 | - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */ | |
626 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[6])); /* MOV(reg0, [EBP+?]); */ | |
786 | 627 | jitCompPutByte1(w.dst, 0x2b); /* SUB(EAX, [EBP+?]); */ |
787 | - jitCompA0001_85DispN(&w, 256 + src[7] * 32 + 0, reg0); | |
628 | + jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[7]) + 0, reg0); | |
788 | 629 | i = jitCompA000_convTyp(jitCompGetImm32(src + 2)); |
789 | 630 | j = -1; |
790 | - if (0x0002 <= i && i <= 0x0007) | |
631 | + if (0x0002 <= i && i <= 0x0007){ | |
791 | 632 | j = (i - 0x0002) >> 1; |
792 | - if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
633 | + } | |
634 | + if (j < 0) { | |
635 | + w.err = JITC_ERR_BADTYPE; | |
636 | + goto err_w; | |
637 | + } | |
793 | 638 | if (j > 0) { |
794 | 639 | jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, j); /* SAR(reg0,?); */ |
795 | 640 | } |
796 | - if (reg0 == 0 /* EAX */) | |
641 | + if (reg0 == IA32_REG0_EAX){ | |
797 | 642 | jitCompA0001_movRxxEax(&w, src[1]); |
798 | - cmp0reg = src[1]; cmp0lev = 1; | |
643 | + } | |
644 | + cmp0reg = src[1]; | |
645 | + cmp0lev = 1; | |
799 | 646 | break; |
800 | 647 | |
801 | 648 | case 0x10: /* OR */ |
@@ -804,58 +651,70 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
804 | 651 | case 0x14: /* ADD */ |
805 | 652 | case 0x15: /* SUB */ |
806 | 653 | case 0x16: /* MUL */ |
807 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
808 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
654 | + if (src[1] >= 0x3f){ | |
655 | + w.err = JITC_ERR_REGNUM; | |
656 | + } | |
657 | + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); | |
809 | 658 | reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); |
810 | 659 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
811 | 660 | if (src[2] == 0x3f) { // SUBのみ該当. |
812 | - if (*src != 0x15) w.err = JITC_ERR_REGNUM; | |
661 | + if (*src != 0x15){ | |
662 | + w.err = JITC_ERR_REGNUM; | |
663 | + } | |
813 | 664 | reg2 = jitCompA000_selectRegCache(src[3], -1 /* mem */); |
814 | - if (reg2 >= 0) | |
665 | + if (reg2 >= 0){ | |
815 | 666 | jitCompA000_storeRegCacheAll(&w); |
667 | + } | |
816 | 668 | jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */ |
817 | - jitCompPutImm32(&w, w.r3f); | |
669 | + jitCompPutImm32(w.dst, w.r3f); | |
818 | 670 | jitCompPutByte1(w.dst, 0x2b); |
819 | - jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
820 | - if (reg0 == 0) | |
671 | + jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); | |
672 | + if (reg0 == 0){ | |
821 | 673 | jitCompA0001_movRxxEax(&w, src[1]); |
674 | + } | |
822 | 675 | break; |
823 | 676 | } |
824 | 677 | #endif |
825 | 678 | if (reg1 < 0) { |
826 | - jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg0, [EBP+?]); */ | |
679 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, src[2] * 4); /* MOV(reg0, [EBP+?]); */ | |
827 | 680 | } |
828 | 681 | if (reg1 >= 0 && reg0 != reg1) { |
829 | 682 | jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ |
830 | 683 | } |
831 | - if (!(src[0] == 0x10 && src[3] == 0xff)) { // bugfix: hinted by Iris, 2013.06.26. thanks! | |
684 | + if (!(src[0] == 0x10 && src[3] == 0xff)) { | |
685 | + // bugfix: hinted by Iris, 2013.06.26. thanks! | |
832 | 686 | cmp0reg = src[1]; |
833 | 687 | cmp0lev = 1; |
834 | - if (src[0] < 0x14) | |
688 | + if (src[0] < 0x14){ | |
835 | 689 | cmp0lev = 2; |
836 | - if (src[0] == 0x16) | |
690 | + } | |
691 | + if (src[0] == 0x16){ | |
837 | 692 | cmp0reg = -1; |
693 | + } | |
838 | 694 | } |
839 | 695 | if (!(src[0] == 0x10 && src[3] == 0xff)) { |
840 | 696 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
841 | 697 | if (src[3] == 0x3f) { |
842 | 698 | if (*src == 0x16 && w.r3f == -1) { |
843 | 699 | jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */ |
844 | - if (reg0 == 0) | |
700 | + if (reg0 == 0){ | |
845 | 701 | jitCompA0001_movRxxEax(&w, src[1]); |
702 | + } | |
846 | 703 | break; |
847 | 704 | } |
848 | 705 | #if (jitCompA0001_USE_R3F_INCDEC != 0) |
849 | 706 | if ((*src == 0x14 && w.r3f == 1) || (*src == 0x15 && w.r3f == -1)) { |
850 | 707 | jitCompPutByte1(w.dst, 0x40 | reg0); /* INC(reg0); */ |
851 | - if (reg0 == 0) | |
708 | + if (reg0 == 0){ | |
852 | 709 | jitCompA0001_movRxxEax(&w, src[1]); |
710 | + } | |
853 | 711 | break; |
854 | 712 | } |
855 | 713 | if ((*src == 0x15 && w.r3f == 1) || (*src == 0x14 && w.r3f == -1)) { |
856 | 714 | jitCompPutByte1(w.dst, 0x48 | reg0); /* DEC(reg0); */ |
857 | - if (reg0 == 0) | |
715 | + if (reg0 == 0){ | |
858 | 716 | jitCompA0001_movRxxEax(&w, src[1]); |
717 | + } | |
859 | 718 | break; |
860 | 719 | } |
861 | 720 | #endif |
@@ -864,21 +723,22 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
864 | 723 | if (*src != 0x16) { |
865 | 724 | static unsigned char basic_op_table_im8[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 }; |
866 | 725 | jitCompPutByte3(w.dst, 0x83, basic_op_table_im8[*src - 0x10] | reg0, w.r3f & 0xff); |
867 | - } | |
868 | - else { | |
726 | + } else{ | |
869 | 727 | jitCompPutByte3(w.dst, 0x6b, 0xc0 | reg0 << 3 | reg0, w.r3f & 0xff); |
870 | 728 | } |
871 | - if (reg0 == 0) | |
729 | + if (reg0 == 0){ | |
872 | 730 | jitCompA0001_movRxxEax(&w, src[1]); |
731 | + } | |
873 | 732 | break; |
874 | 733 | } |
875 | 734 | #endif |
876 | - if (reg0 == 0 /* EAX */) { | |
735 | + if (reg0 == IA32_REG0_EAX) { | |
877 | 736 | static unsigned char basic_op_table_im32_eax[] = { 0x0d, 0x35, 0x25, 0, 0x05, 0x2d, 0xc0 }; |
878 | - if (*src == 0x16) { jitCompPutByte1(w.dst, 0x69); } | |
737 | + if (*src == 0x16) { | |
738 | + jitCompPutByte1(w.dst, 0x69); | |
739 | + } | |
879 | 740 | jitCompPutByte1(w.dst, basic_op_table_im32_eax[*src - 0x10]); |
880 | - } | |
881 | - else { | |
741 | + } else{ | |
882 | 742 | if (*src != 0x16) { |
883 | 743 | static unsigned char basic_op_table_im32_reg[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 }; |
884 | 744 | jitCompPutByte2(w.dst, 0x81, basic_op_table_im32_reg[*src - 0x10] | reg0); |
@@ -887,79 +747,98 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
887 | 747 | jitCompPutByte2(w.dst, 0x69, 0xc0 | reg0 << 3 | reg0); |
888 | 748 | } |
889 | 749 | } |
890 | - jitCompPutImm32(&w, w.r3f); | |
891 | - if (reg0 == 0) | |
750 | + jitCompPutImm32(w.dst, w.r3f); | |
751 | + if (reg0 == 0){ | |
892 | 752 | jitCompA0001_movRxxEax(&w, src[1]); |
753 | + } | |
893 | 754 | break; |
894 | 755 | } |
895 | 756 | #endif |
896 | 757 | reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); |
897 | - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
758 | + if (src[3] >= 0x40){ | |
759 | + w.err = JITC_ERR_REGNUM; | |
760 | + } | |
898 | 761 | if (*src != 0x16) { |
899 | 762 | if (reg1 >= 0) { |
900 | 763 | static unsigned char basic_op_table_rr[] = { 0x09, 0x31, 0x21, 0, 0x01, 0x29 }; /* op(reg,reg); */ |
901 | 764 | jitCompPutByte2(w.dst, basic_op_table_rr[*src - 0x10], 0xc0 | reg1 << 3 | reg0); |
902 | - } | |
903 | - else { | |
765 | + } else{ | |
904 | 766 | static unsigned char basic_op_table_rm[] = { 0x0b, 0x33, 0x23, 0, 0x03, 0x2b, 0xaf }; /* op(reg,mem); */ |
905 | 767 | jitCompPutByte1(w.dst, basic_op_table_rm[*src - 0x10]); |
906 | - jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
768 | + jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); | |
907 | 769 | } |
908 | - } | |
909 | - else { | |
770 | + } else{ | |
910 | 771 | if (reg1 >= 0) { |
911 | 772 | jitCompPutByte3(w.dst, 0x0f, 0xaf, 0xc0 | reg0 << 3 | reg1); |
912 | - } | |
913 | - else { | |
773 | + } else{ | |
914 | 774 | jitCompPutByte2(w.dst, 0x0f, 0xaf); |
915 | - jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
775 | + jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0); | |
916 | 776 | } |
917 | 777 | } |
918 | 778 | } |
919 | - if (reg0 == 0) | |
779 | + if (reg0 == 0){ | |
920 | 780 | jitCompA0001_movRxxEax(&w, src[1]); |
781 | + } | |
921 | 782 | break; |
922 | 783 | |
923 | 784 | case 0x18: /* SHL */ |
924 | 785 | case 0x19: /* SAR */ |
925 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
926 | - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
786 | + if (src[1] >= 0x3f){ | |
787 | + w.err = JITC_ERR_REGNUM; | |
788 | + } | |
789 | + if (src[3] >= 0x40){ | |
790 | + w.err = JITC_ERR_REGNUM; | |
791 | + } | |
927 | 792 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
928 | 793 | if (src[3] == 0x3f) { |
929 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
794 | + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); | |
930 | 795 | reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */); |
931 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
932 | - if (reg1 == -1) | |
933 | - jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg1, [EBP+?]); */ | |
934 | - else { | |
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{ | |
935 | 802 | if (reg0 != reg1) { |
936 | 803 | jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */ |
937 | 804 | } |
938 | 805 | } |
939 | - if (*src == 0x18) { jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f); } /* SHL(reg0, im8); */ | |
940 | - if (*src == 0x19) { jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f); } /* SAR(reg0, im8); */ | |
941 | - if (reg0 == 0 /* EAX */) | |
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){ | |
942 | 815 | jitCompA0001_movRxxEax(&w, src[1]); |
816 | + } | |
943 | 817 | cmp0reg = src[1]; |
944 | 818 | cmp0lev = 1; |
945 | 819 | break; |
946 | 820 | } |
947 | 821 | #endif |
948 | 822 | jitCompA000_storeRegCacheAll(&w); // 手抜き. |
949 | - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ | |
823 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */ | |
950 | 824 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
951 | 825 | if (src[2] == 0x3f) { |
952 | 826 | jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ |
953 | - jitCompPutImm32(&w, w.r3f); | |
954 | - } | |
955 | - else { | |
827 | + jitCompPutImm32(w.dst, w.r3f); | |
828 | + } else{ | |
956 | 829 | jitCompA0001_movEaxRxx(&w, src[2]); |
957 | 830 | } |
958 | 831 | #else |
959 | 832 | jitCompA0001_movEaxRxx(&w, src[2]); |
960 | 833 | #endif |
961 | - if (*src == 0x18) { jitCompPutByte2(w.dst, 0xd3, 0xe0); } /* SHL(EAX, CL); */ | |
962 | - if (*src == 0x19) { jitCompPutByte2(w.dst, 0xd3, 0xf8); } /* SAR(EAX, CL); */ | |
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 | + } | |
963 | 842 | jitCompA0001_movRxxEax(&w, src[1]); |
964 | 843 | jitCompA000_loadRegCacheAll(&w); // 手抜き. |
965 | 844 | cmp0reg = src[1]; |
@@ -968,41 +847,45 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
968 | 847 | |
969 | 848 | case 0x1a: /* DIV */ |
970 | 849 | case 0x1b: /* MOD */ |
971 | - if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM; | |
972 | - if (src[2] >= 0x40) w.err = JITC_ERR_REGNUM; | |
973 | - if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM; | |
850 | + if (src[1] >= 0x3f || src[2] >= 0x40 || src[3] >= 0x40){ | |
851 | + w.err = JITC_ERR_REGNUM; | |
852 | + } | |
974 | 853 | jitCompA000_storeRegCacheAll(&w); // 手抜き. |
975 | 854 | #if (jitCompA0001_USE_R3F_IMM32 != 0) |
976 | 855 | if (src[3] == 0x3f) { |
977 | 856 | jitCompPutByte1(w.dst, 0xb8 | 1); /* MOV(ECX, ?); */ |
978 | - jitCompPutImm32(&w, w.r3f); | |
979 | - } | |
980 | - else { | |
981 | - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ | |
857 | + jitCompPutImm32(w.dst, w.r3f); | |
858 | + } else{ | |
859 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG1_ECX, src[3] * 4); /* MOV(ECX, [EBP+?]); */ | |
982 | 860 | } |
983 | 861 | if (src[2] == 0x3f) { |
984 | 862 | jitCompPutByte1(w.dst, 0xb8 | 0); /* MOV(EAX, ?); */ |
985 | - jitCompPutImm32(&w, w.r3f); | |
986 | - } | |
987 | - else { | |
988 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */ | |
863 | + jitCompPutImm32(w.dst, w.r3f); | |
864 | + } else{ | |
865 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, src[2] * 4); /* MOV(EAX, [EBP+?]); */ | |
989 | 866 | } |
990 | 867 | #else |
991 | - jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */ | |
992 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */ | |
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+?]); */ | |
993 | 870 | #endif |
994 | 871 | jitCompPutByte1(w.dst, 0x99); /* CDQ(); */ |
995 | 872 | /* ECXがゼロではないことを確認すべき */ |
996 | 873 | jitCompPutByte2(w.dst, 0xf7, 0xf9); /* IDIV(ECX); */ |
997 | - if (*src == 0x1a) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 0 /* EAX */); } | |
998 | - if (*src == 0x1b) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 2 /* EDX */); } | |
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 | + } | |
999 | 880 | jitCompA000_loadRegCacheAll(&w); // 手抜き. |
1000 | 881 | cmp0reg = -1; |
1001 | 882 | break; |
1002 | 883 | |
1003 | 884 | case 0x1c: /* PLMT0 */ |
1004 | 885 | case 0x1d: /* PLMT1 */ |
1005 | - if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
886 | + if (src[1] >= 0x40 || src[2] >= 0x40){ | |
887 | + w.err = JITC_ERR_PREGNUM; | |
888 | + } | |
1006 | 889 | if (level < JITC_LV_FASTEST) { |
1007 | 890 | cmp0reg = -1; |
1008 | 891 | if (level < JITC_LV_FASTER) { |
@@ -1010,39 +893,42 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1010 | 893 | // plsとliveSignが一致していることを確認. |
1011 | 894 | |
1012 | 895 | // preg1はp0 <= p <= p1 を満たしているか?. |
1013 | - // 新しいp0/p1は古いp0〜p1に適合しているか?. | |
896 | + // 新しいp0/p1は古いp0?p1に適合しているか?. | |
1014 | 897 | |
1015 | 898 | } |
1016 | 899 | } |
1017 | 900 | |
1018 | 901 | case 0x1e: /* PCP */ /* 未完成(p1まで完成) */ |
1019 | - if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1020 | - if (src[2] == 0x3f) w.err = JITC_ERR_PREGNUM; | |
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 | + } | |
1021 | 908 | if (src[1] != 0x3f) { |
1022 | 909 | /* src[2] == 0xff の場合に対応できてない */ |
1023 | 910 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
1024 | 911 | for (i = 0; i < 32; i += 4) { |
1025 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
1026 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
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); */ | |
1027 | 914 | } |
1028 | 915 | jitCompA000_loadPRegCacheAll(&w); // 手抜き. |
1029 | - } | |
1030 | - else { | |
916 | + } else { | |
1031 | 917 | if (level < JITC_LV_FASTER) { |
1032 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ | |
918 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ | |
1033 | 919 | jitCompPutByte3(w.dst, 0x83, 0xf8, 0); /* CMP(EAX, 0); */ |
1034 | 920 | jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ |
1035 | - jitCompPutImm32(&w, errfnc - (w.dst + 4)); | |
921 | + jitCompPutImm32(w.dst, errfnc - (w.dst + 4)); | |
1036 | 922 | /* セキュリティチェックが足りてない!(aliveとか) */ |
1037 | 923 | } |
1038 | - reg0 = 0; /* EAX */ | |
924 | + reg0 = IA32_REG0_EAX; | |
1039 | 925 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
1040 | - jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ | |
926 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, reg0, PRegOffset(src[2]) + 0); /* MOV(EAX, [EBP+?]); */ | |
1041 | 927 | if (level < JITC_LV_FASTER) { |
1042 | 928 | jitCompPutByte1(w.dst, 0x3b); /* CMP(reg0, [EBP+?]); */ |
1043 | - jitCompA0001_85DispN(&w, 256 + src[2] * 32 + 8, reg0); /* p0 */ | |
929 | + jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[2]) + 8, reg0); /* p0 */ | |
1044 | 930 | jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */ |
1045 | - jitCompPutImm32(&w, errfnc - (w.dst + 4)); | |
931 | + jitCompPutImm32(w.dst, errfnc - (w.dst + 4)); | |
1046 | 932 | } |
1047 | 933 | jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */ |
1048 | 934 | } |
@@ -1050,20 +936,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1050 | 936 | |
1051 | 937 | case 0x1f: /* PCST */ |
1052 | 938 | if (jitCompGetImm32(src + 2) == 0) { |
1053 | - if (level < JITC_LV_FASTER) | |
939 | + if (level < JITC_LV_FASTER){ | |
1054 | 940 | jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 7), 2); |
941 | + } | |
1055 | 942 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
1056 | 943 | for (i = 0; i < 32 - 4; i += 4) { |
1057 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
944 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */ | |
1058 | 945 | if (i == 4) { |
1059 | 946 | jitCompPutByte1(w.dst, 0x0d); /* OR(EAX, ?); */ |
1060 | - jitCompPutImm32(&w, 0x80000000); | |
947 | + jitCompPutImm32(w.dst, 0x80000000); | |
1061 | 948 | } |
1062 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
949 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
1063 | 950 | } |
1064 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1065 | - jitCompPutImm32(&w, debugInfo1); | |
1066 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 28, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
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); */ | |
1067 | 953 | jitCompA000_loadPRegCacheAll(&w); // 手抜き. |
1068 | 954 | cmp0reg = -1; |
1069 | 955 | break; |
@@ -1071,20 +957,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1071 | 957 | if (jitCompGetImm32(src + 7) == 0) { |
1072 | 958 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
1073 | 959 | for (i = 0; i < 32 - 4; i += 4) { |
1074 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */ | |
960 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + i); /* MOV(EAX, [EBP+?]); */ | |
1075 | 961 | if (i == 4) { |
1076 | 962 | jitCompPutByte1(w.dst, 0x25); /* AND(EAX, ?); */ |
1077 | - jitCompPutImm32(&w, 0x7fffffff); | |
963 | + jitCompPutImm32(w.dst, 0x7fffffff); | |
1078 | 964 | } |
1079 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */ | |
965 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, PRegOffset(src[1]) + i, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */ | |
1080 | 966 | } |
1081 | 967 | if (level < JITC_LV_FASTER) { |
1082 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + 28); /* MOV(EAX, [EBP+?]); */ | |
968 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[6]) + 28); /* MOV(EAX, [EBP+?]); */ | |
1083 | 969 | jitCompPutByte1(w.dst, 0x3d); /* CMP(EAX, ?); */ |
1084 | - jitCompPutImm32(&w, debugInfo1); | |
970 | + jitCompPutImm32(w.dst, debugInfo1); | |
1085 | 971 | jitCompPutByte2(w.dst, 0x74, 8); /* JE */ |
1086 | - jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); (2) */ | |
1087 | - jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0 /* EAX */); /* MOV([EBP+?], EAX); (1+1+4) */ | |
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) */ | |
1088 | 974 | } |
1089 | 975 | jitCompA000_loadPRegCacheAll(&w); // 手抜き. |
1090 | 976 | cmp0reg = -1; |
@@ -1101,13 +987,17 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1101 | 987 | case 0x25: /* CMPG */ |
1102 | 988 | case 0x26: /* TSTZ */ |
1103 | 989 | case 0x27: /* TSTNZ */ |
1104 | - reg0 = jitCompA000_selectRegCache(src[2], 0 /* EAX */); | |
990 | + reg0 = jitCompA000_selectRegCache(src[2], IA32_REG0_EAX); | |
1105 | 991 | reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */); |
1106 | 992 | if (src[1] == 0x3f) { |
1107 | 993 | /* 特殊構文チェック */ |
1108 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
994 | + if (w.prefix != 0) { | |
995 | + w.err = JITC_ERR_PREFIX; | |
996 | + goto err_w; | |
997 | + } | |
1109 | 998 | if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) { |
1110 | - w.err = JITC_ERR_IDIOM; goto err_w; | |
999 | + w.err = JITC_ERR_IDIOM; | |
1000 | + goto err_w; | |
1111 | 1001 | } |
1112 | 1002 | } |
1113 | 1003 | if (reg0 == 0) |
@@ -1118,10 +1008,12 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1118 | 1008 | if ((*src <= 0x25 && w.r3f == 0) || (*src >= 0x26 && w.r3f == -1)) { |
1119 | 1009 | i = 0; |
1120 | 1010 | if (cmp0reg == src[2]) { |
1121 | - if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27)) | |
1011 | + if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27)){ | |
1122 | 1012 | i = 1; |
1123 | - if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25)) | |
1013 | + } | |
1014 | + if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25)){ | |
1124 | 1015 | i = 1; |
1016 | + } | |
1125 | 1017 | } |
1126 | 1018 | if (i == 0) { |
1127 | 1019 | jitCompPutByte2(w.dst, 0x85, 0xc0 | reg0 << 3 | reg0); /* TEST(reg0, reg0); */ |
@@ -1138,29 +1030,48 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1138 | 1030 | } |
1139 | 1031 | #endif |
1140 | 1032 | if (reg0 == 0) { |
1141 | - if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3d); } | |
1142 | - if (*src >= 0x26) { jitCompPutByte1(w.dst, 0xa9); } | |
1033 | + if (*src <= 0x25) { | |
1034 | + jitCompPutByte1(w.dst, 0x3d); | |
1035 | + } | |
1036 | + if (*src >= 0x26) { | |
1037 | + jitCompPutByte1(w.dst, 0xa9); | |
1038 | + } | |
1143 | 1039 | } |
1144 | 1040 | else { |
1145 | - if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0); } | |
1146 | - if (*src >= 0x26) { jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); } | |
1041 | + if (*src <= 0x25) { | |
1042 | + jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0); | |
1043 | + } | |
1044 | + if (*src >= 0x26) { | |
1045 | + jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); | |
1046 | + } | |
1147 | 1047 | } |
1148 | - jitCompPutImm32(&w, w.r3f); | |
1048 | + jitCompPutImm32(w.dst, w.r3f); | |
1149 | 1049 | goto cmpcc1; |
1150 | 1050 | } |
1151 | 1051 | #endif |
1152 | - if (src[3] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1153 | - if (reg1 >= 0) { | |
1154 | - if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x39, 0xc0 | reg1 << 3 | reg0); } | |
1155 | - if (*src >= 0x26) { jitCompPutByte2(w.dst, 0x85, 0xc0 | reg1 << 3 | reg0); } | |
1052 | + if (src[3] >= 0x40){ | |
1053 | + w.err = JITC_ERR_PREGNUM; | |
1156 | 1054 | } |
1157 | - else { | |
1158 | - if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3b); } | |
1159 | - if (*src >= 0x26) { jitCompPutByte1(w.dst, 0x85); } | |
1160 | - jitCompA0001_85DispN(&w, src[3] * 4, reg0); | |
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); | |
1161 | 1070 | } |
1162 | 1071 | cmpcc1: |
1163 | - if (w.err != 0) goto err_w; | |
1072 | + if (w.err != 0){ | |
1073 | + goto err_w; | |
1074 | + } | |
1164 | 1075 | static unsigned char cmpcc_table0[] = { |
1165 | 1076 | 0x04, 0x05, 0x0c, 0x0d, 0x0e, 0x0f, 0x04, 0x05, /* CMPcc, TSTcc */ |
1166 | 1077 | 0x04, 0x05, 0x02, 0x03, 0x06, 0x07 /* PCMPcc */ |
@@ -1172,13 +1083,17 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1172 | 1083 | src += 6; |
1173 | 1084 | i = jitCompGetLabelNum(&w, src + 2); |
1174 | 1085 | if ((flags & JITC_PHASE1) != 0 && w.err != 0) { |
1175 | - if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } | |
1086 | + if (label[i].opt == 0) { | |
1087 | + w.err = JITC_ERR_LABELNODEF; | |
1088 | + goto err_w; | |
1089 | + } | |
1176 | 1090 | // if (label[i].typ != 1) { w.err = JITC_ERR_LABELTYP; goto err_w; } |
1177 | 1091 | } |
1178 | 1092 | j = 0; |
1179 | - if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) | |
1093 | + if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)){ | |
1180 | 1094 | j = label[i].p - (w.dst + 4); |
1181 | - jitCompPutImm32(&w, j); | |
1095 | + } | |
1096 | + jitCompPutImm32(w.dst, j); | |
1182 | 1097 | #if (jitCompA0001_OPTIMIZE_JMP != 0) |
1183 | 1098 | if (-128 - 4 <= j && j < 0) { |
1184 | 1099 | j += 4; |
@@ -1187,17 +1102,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1187 | 1102 | } |
1188 | 1103 | #endif |
1189 | 1104 | src += 6; |
1190 | - if (w.err != 0) goto err_w; | |
1105 | + if (w.err != 0){ | |
1106 | + goto err_w; | |
1107 | + } | |
1191 | 1108 | continue; |
1192 | 1109 | } |
1193 | 1110 | #endif |
1194 | 1111 | /* 一般的なJITC */ |
1195 | - reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */); | |
1112 | + reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX); | |
1196 | 1113 | jitCompPutByte3(w.dst, 0x0f, 0x90 | cmpcc_table0[*src - 0x20], 0xc0 | reg0); /* SETcc(BYTE(reg0)); */ |
1197 | 1114 | jitCompPutByte3(w.dst, 0x0f, 0xb6, 0xc0 | reg0 << 3 | reg0); /* MOVZX(reg0, BYTE(reg0)); */ |
1198 | 1115 | jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */ |
1199 | - if (reg0 == 0) | |
1116 | + if (reg0 == 0){ | |
1200 | 1117 | jitCompA0001_movRxxEax(&w, src[1]); |
1118 | + } | |
1201 | 1119 | cmp0reg = src[2]; |
1202 | 1120 | cmp0lev = 1; |
1203 | 1121 | break; |
@@ -1210,21 +1128,27 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1210 | 1128 | case 0x2d: /* PCMPG */ |
1211 | 1129 | if (src[1] == 0x3f) { |
1212 | 1130 | /* 特殊構文チェック */ |
1213 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
1131 | + if (w.prefix != 0) { | |
1132 | + w.err = JITC_ERR_PREFIX; | |
1133 | + goto err_w; | |
1134 | + } | |
1214 | 1135 | if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) { |
1215 | - w.err = JITC_ERR_IDIOM; goto err_w; | |
1136 | + w.err = JITC_ERR_IDIOM; | |
1137 | + goto err_w; | |
1216 | 1138 | } |
1217 | 1139 | } |
1218 | - if (src[2] >= 0x40) w.err = JITC_ERR_PREGNUM; | |
1140 | + if (src[2] >= 0x40) { | |
1141 | + w.err = JITC_ERR_PREGNUM; | |
1142 | + } | |
1219 | 1143 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
1220 | - if (src[3] != 0xff) | |
1144 | + if (src[3] != 0xff){ | |
1221 | 1145 | jitCompA0001_checkCompPtr(&w, src[2], src[3]); |
1222 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */ | |
1146 | + } | |
1147 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(src[2]) + 0); /* MOV(EAX, [EBP+?]); */ | |
1223 | 1148 | if (src[3] != 0xff) { |
1224 | 1149 | jitCompPutByte1(w.dst, 0x3b); /* CMP(EAX, [EBP+?]); */ |
1225 | - jitCompA0001_85DispN(&w, 256 + src[3] * 32 + 0, 0); | |
1226 | - } | |
1227 | - else { | |
1150 | + jitCompPutModRM_Disp_BaseEBP(&w, PRegOffset(src[3]) + 0, 0); | |
1151 | + } else{ | |
1228 | 1152 | /* ヌルポインタとの比較はこれでいいのか?たぶんよくない */ |
1229 | 1153 | jitCompPutByte3(w.dst, 0x83, 0xf8, 0x00); /* CMP(EAX, 0); */ |
1230 | 1154 | } |
@@ -1237,42 +1161,84 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1237 | 1161 | case 0x33: /* mfree(old:F7) */ |
1238 | 1162 | jitCompA000_storeRegCacheAll(&w); // 手抜き. |
1239 | 1163 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
1240 | - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ | |
1241 | - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ | |
1242 | - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ | |
1243 | - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ | |
1244 | - jitCompPutByte1(w.dst, 0xe8); | |
1245 | - if (*src == 0x30) j = ((unsigned char *)&funcf4) - (w.dst + 4); | |
1246 | - if (*src == 0x31) j = ((unsigned char *)&funcf5) - (w.dst + 4); | |
1247 | - if (*src == 0x32) j = ((unsigned char *)&funcf6) - (w.dst + 4); | |
1248 | - if (*src == 0x33) j = ((unsigned char *)&funcf7) - (w.dst + 4); | |
1249 | - jitCompPutImm32(&w, j); | |
1250 | - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x10); /* ADD(ESP,16); */ | |
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 | + | |
1251 | 1187 | jitCompA000_loadRegCacheAll(&w); // 手抜き. |
1252 | 1188 | jitCompA000_loadPRegCacheAll(&w); // 手抜き. |
1253 | 1189 | cmp0reg = -1; |
1254 | 1190 | break; |
1255 | 1191 | |
1256 | 1192 | case 0x34: /* data (暫定) */ |
1193 | + // 0 1234 5678 9 | |
1194 | + // 34 typ32 len32 data... | |
1195 | + // len32 is NOT byte size! | |
1196 | + | |
1257 | 1197 | cmp0reg = -1; |
1258 | - if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } | |
1259 | - int k = jitCompGetImm32(&src[1]), tmpData, bitCount, dataWidth = jitCompA000_dataWidth(k); | |
1260 | - if (lastlabel >= 0 && label[lastlabel].typ == 0) | |
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 | + //直前のラベルタイプを設定 | |
1261 | 1208 | label[lastlabel].typ = k; |
1209 | + } | |
1262 | 1210 | if (k != 1) { |
1263 | 1211 | i = jitCompA000_convTyp(k); |
1264 | - if (i < 2 || i > 7) { w.err = JITC_ERR_BADTYPE; goto err_w; } | |
1212 | + if (i < 2 || i > 7) { | |
1213 | + w.err = JITC_ERR_BADTYPE; | |
1214 | + goto err_w; | |
1215 | + } | |
1265 | 1216 | } |
1217 | + // jはlen32 | |
1266 | 1218 | j = jitCompGetImm32(&src[5]); |
1267 | 1219 | oldsrc = src; |
1268 | 1220 | src += 9; |
1221 | + | |
1222 | + // srcはdata本体を指す | |
1269 | 1223 | if (k != 1) { |
1224 | + // 一般データ | |
1270 | 1225 | bitCount = 7; |
1271 | 1226 | while (j > 0) { |
1272 | - if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; } | |
1273 | - if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; } | |
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 | + } | |
1274 | 1239 | tmpData = 0; |
1275 | 1240 | for (k = 0; k < dataWidth; k++) { |
1241 | + // dataWidthビットごとに切り出してtmpDataに入れる | |
1276 | 1242 | tmpData = tmpData << 1 | ((*src >> bitCount) & 1); |
1277 | 1243 | bitCount--; |
1278 | 1244 | if (bitCount < 0) { |
@@ -1281,53 +1247,78 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1281 | 1247 | } |
1282 | 1248 | } |
1283 | 1249 | if ((i & 1) == 0 && dataWidth <= 31 && (tmpData >> (dataWidth - 1)) != 0) { |
1250 | + // 符号あり型で、かつtmpDataの符号ビットが1なので、マイナスにする | |
1284 | 1251 | tmpData -= 1 << dataWidth; |
1285 | 1252 | } |
1286 | - if (i == 2 || i == 3) { jitCompPutByte1(w.dst, tmpData & 0xff); } | |
1287 | - if (i == 4 || i == 5) { jitCompPutByte2(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff); } | |
1288 | - if (i == 6 || i == 7) { jitCompPutByte4(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff, (tmpData >> 16) & 0xff, (tmpData >> 24) & 0xff); } | |
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 | + } | |
1289 | 1265 | j--; |
1290 | 1266 | } |
1291 | - } | |
1292 | - else { | |
1267 | + } else{ | |
1268 | + // VPtr型 | |
1293 | 1269 | while (j > 0) { |
1294 | - if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; } | |
1295 | - if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; } | |
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 | + } | |
1296 | 1282 | i = jitCompGetImm32(src); |
1297 | 1283 | src += 4; |
1298 | 1284 | if ((flags & JITC_PHASE1) != 0 && w.err == 0) { |
1299 | - if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } | |
1285 | + // Only in phase1 | |
1286 | + if (label[i].opt == 0) { | |
1287 | + // ローカルラベルはだめです... | |
1288 | + w.err = JITC_ERR_LABELNODEF; | |
1289 | + goto err_w; | |
1290 | + } | |
1300 | 1291 | } |
1301 | - jitCompPutImm32(&w, (int)label[i].p); | |
1302 | - jitCompPutImm32(&w, label[i].typ); | |
1303 | - jitCompPutImm32(&w, (int)label[i].p); | |
1304 | - jitCompPutImm32(&w, (int)label[i].p1); | |
1305 | - jitCompPutImm32(&w, 0); /* liveSign */ | |
1306 | - jitCompPutImm32(&w, 2320); /* pls */ | |
1307 | - jitCompPutImm32(&w, 0); | |
1308 | - jitCompPutImm32(&w, 0); | |
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); | |
1309 | 1300 | j--; |
1310 | 1301 | } |
1311 | 1302 | } |
1312 | - if (lastlabel >= 0 && label[lastlabel].p1 < w.dst) | |
1303 | + if (lastlabel >= 0 && label[lastlabel].p1 < w.dst){ | |
1313 | 1304 | label[lastlabel].p1 = w.dst; |
1305 | + } | |
1314 | 1306 | continue; |
1315 | 1307 | |
1316 | 1308 | case 0x3c: /* ENTER */ |
1317 | 1309 | jitCompA000_storeRegCacheAll(&w); // 手抜き. |
1318 | 1310 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
1319 | - jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */ | |
1320 | - jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */ | |
1321 | - jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */ | |
1322 | - jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */ | |
1323 | - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ | |
1324 | - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ | |
1325 | - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ | |
1326 | - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ | |
1327 | - jitCompPutByte1(w.dst, 0xe8); | |
1328 | - j = ((unsigned char *)&func3c) - (w.dst + 4); | |
1329 | - jitCompPutImm32(&w, j); | |
1330 | - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */ | |
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); | |
1331 | 1322 | jitCompA000_loadRegCacheAll(&w); // 手抜き. |
1332 | 1323 | jitCompA000_loadPRegCacheAll(&w); // 手抜き. |
1333 | 1324 | cmp0reg = -1; |
@@ -1336,46 +1327,43 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1336 | 1327 | case 0x3d: /* LEAVE */ |
1337 | 1328 | jitCompA000_storeRegCacheAll(&w); // 手抜き. |
1338 | 1329 | jitCompA000_storePRegCacheAll(&w); // 手抜き. |
1339 | - jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */ | |
1340 | - jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */ | |
1341 | - jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */ | |
1342 | - jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */ | |
1343 | - jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */ | |
1344 | - jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */ | |
1345 | - jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */ | |
1346 | - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ | |
1347 | - jitCompPutByte1(w.dst, 0xe8); | |
1348 | - j = ((unsigned char *)&func3d) - (w.dst + 4); | |
1349 | - jitCompPutImm32(&w, j); | |
1350 | - jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */ | |
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); | |
1351 | 1341 | jitCompA000_loadRegCacheAll(&w); // 手抜き. |
1352 | 1342 | jitCompA000_loadPRegCacheAll(&w); // 手抜き. |
1353 | 1343 | cmp0reg = -1; |
1354 | 1344 | break; |
1355 | 1345 | |
1356 | 1346 | case 0xfe: /* remark */ |
1357 | - if (src[1] == 0x01 && src[2] == 0x00) { // DBGINFO1 | |
1347 | + if (src[1] == 0x01 && src[2] == 0x00) { | |
1348 | + // DBGINFO1 | |
1358 | 1349 | if (level <= JITC_LV_SLOWER) { |
1359 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1360 | - jitCompPutImm32(&w, debugInfo1); | |
1361 | - jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ | |
1350 | + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1); | |
1351 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX); | |
1362 | 1352 | } |
1363 | 1353 | } |
1364 | - if (src[1] == 0x01 && src[2] == 0x03) { // DBGINFO1CLR | |
1354 | + if (src[1] == 0x01 && src[2] == 0x03) { | |
1355 | + // DBGINFO1CLR | |
1365 | 1356 | if (level <= JITC_LV_SLOWER) { |
1366 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1367 | - jitCompPutImm32(&w, -1); | |
1368 | - jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */ | |
1357 | + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, -1); | |
1358 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO1, IA32_REG0_EAX); | |
1369 | 1359 | } |
1370 | 1360 | } |
1371 | - if (src[1] == 0x05 && src[2] == 0x00) { // DBGINFO0 | |
1361 | + if (src[1] == 0x05 && src[2] == 0x00) { | |
1362 | + // DBGINFO0 | |
1372 | 1363 | if (level <= JITC_LV_SLOWEST) { |
1373 | 1364 | debugInfo0 = jitCompGetImm32(src + 3); |
1374 | - // jitCompPutByte1(w.dst, 0xbf); /* MOV(EDI, ?); */ | |
1375 | - // jitCompPutImm32(&w, debugInfo0); | |
1376 | - jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */ | |
1377 | - jitCompPutImm32(&w, debugInfo0); | |
1378 | - jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */ | |
1365 | + jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo0); | |
1366 | + jitCompPutOp_MOV_EBPDisp_GReg(&w, envOffset_DBGINFO0, IA32_REG0_EAX); | |
1379 | 1367 | } |
1380 | 1368 | } |
1381 | 1369 | break; |
@@ -1384,9 +1372,18 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1384 | 1372 | w.err = JITC_ERR_OPECODE; |
1385 | 1373 | goto err_w; |
1386 | 1374 | } |
1387 | - if (w.err != 0) goto err_w; | |
1375 | + if (w.err != 0){ | |
1376 | + goto err_w; | |
1377 | + } | |
1388 | 1378 | jitCompA0001_fixPrefix(&w); |
1389 | - if (w.err != 0) goto err_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 | + | |
1390 | 1387 | src += jitCompCmdLen(src); |
1391 | 1388 | } |
1392 | 1389 | if (enter0 != NULL) { |
@@ -1399,16 +1396,18 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr | ||
1399 | 1396 | if ((flags & JITC_NOSTARTUP) == 0) { |
1400 | 1397 | jitCompA000_storeRegCacheAll(&w); |
1401 | 1398 | jitCompA000_storePRegCacheAll(&w); |
1402 | - jitCompPutByte1(w.dst, 0x61); /* POPAD(); */ | |
1399 | + jitCompPutOp_POPAD(w.dst); | |
1403 | 1400 | } |
1404 | - if ((flags & JITC_PHASE1) != 0) | |
1401 | + if ((flags & JITC_PHASE1) != 0){ | |
1405 | 1402 | return w.dst - dst00; |
1403 | + } | |
1406 | 1404 | return 0; |
1407 | 1405 | |
1408 | 1406 | err_w: |
1409 | 1407 | if ((w.err & JITC_ERR_PHASE0ONLY) != 0) { |
1410 | - if ((flags & JITC_PHASE1) == 0) | |
1408 | + if ((flags & JITC_PHASE1) == 0){ | |
1411 | 1409 | w.err &= ~JITC_ERR_PHASE0ONLY; |
1410 | + } | |
1412 | 1411 | } |
1413 | 1412 | if (w.err == (JITC_ERR_MASK & JITC_ERR_REGNUM)) errmsg = "reg-number error"; |
1414 | 1413 | if (w.err == (JITC_ERR_MASK & JITC_ERR_DST1)) errmsg = "dst1 error"; |
@@ -1444,56 +1443,76 @@ err_w: | ||
1444 | 1443 | |
1445 | 1444 | unsigned char *jitCompCallFunc(unsigned char *dst, void *func) |
1446 | 1445 | { |
1446 | + //この関数の中では結局w->dstしか参照していない | |
1447 | 1447 | struct JitCompWork w; |
1448 | 1448 | w.dst = dst; |
1449 | 1449 | jitCompA000_storeRegCacheAll(&w); |
1450 | 1450 | jitCompA000_storePRegCacheAll(&w); |
1451 | - jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */ | |
1452 | - jitCompPutByte1(w.dst, 0x50); /* PUSH(EAX); */ /* for 16byte-align(win32では不要なのだけど、MacOSには必要らしい) */ | |
1453 | - jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */ | |
1454 | - jitCompPutByte1(w.dst, 0xe8); /* CALL(func); */ | |
1455 | - int j = ((unsigned char *)func) - (w.dst + 4); | |
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); | |
1456 | 1454 | |
1457 | - //この関数の中では結局w->dstしか参照していない | |
1458 | - jitCompPutImm32(&w, j); | |
1455 | + int j = ((unsigned char *)func) - (w.dst + 1 + 4); | |
1456 | + jitCompPutOp_CALL_Relative(w.dst, j); | |
1459 | 1457 | |
1460 | - jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */ /* (win32では不要なのだけど、MacOSには必要らしい) */ | |
1461 | - jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */ | |
1462 | - jitCompPutByte1(w.dst, 0x61); /* POPAD(); */ | |
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); | |
1463 | 1461 | jitCompA000_loadRegCacheAll(&w); |
1464 | 1462 | jitCompA000_loadPRegCacheAll(&w); |
1465 | - jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + 0x30 * 32 + 0); /* MOV(EAX, [EBP+?]); */ | |
1463 | + jitCompPutOp_MOV_GReg_EBPDisp(&w, IA32_REG0_EAX, PRegOffset(0x30) + 0); | |
1464 | + | |
1466 | 1465 | jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */ |
1467 | 1466 | return w.dst; |
1468 | 1467 | } |
1469 | 1468 | |
1470 | -// dst に errHndl() を呼ぶコードを置く。このコードの番地はerrfncにセットされる。 | |
1471 | 1469 | unsigned char *jitCompInit(unsigned char *dst) |
1472 | 1470 | { |
1473 | 1471 | errfnc = dst; |
1474 | 1472 | return jitCompCallFunc(dst, &errHndl); |
1475 | 1473 | } |
1476 | 1474 | |
1475 | +void jitcRunBinary(void (*bin)(char *), HOSECPU_RuntimeEnvironment *env) | |
1476 | +{ | |
1477 | + (*bin)(((char *)env) + jitCompA0001_EBP128); /* サイズを節約するためにEBPをjitCompA0001_EBP128バイトずらす */ | |
1478 | + return; | |
1479 | +} | |
1480 | + | |
1477 | 1481 | void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0) |
1478 | 1482 | { |
1479 | 1483 | HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128); |
1480 | 1484 | int i, *pi; |
1481 | 1485 | HOSECPU_PointerRegisterEntry *pp; |
1482 | - if (r->junkStack + 2048 > r->junkStack1) (*(r->errHndl))(r); | |
1483 | - pi = (void *)r->junkStack; r->junkStack += r1 * 4; | |
1484 | - for (i = 0; i < r1; i++) | |
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++){ | |
1485 | 1493 | pi[i] = r->ireg[i]; |
1486 | - pp = (void *)r->junkStack; r->junkStack += p1 * 32; | |
1487 | - for (i = 0; i < p1; i++) | |
1488 | - pp[i] = r->preg[i]; | |
1489 | - pp = (void *)r->junkStack; r->junkStack += 32; | |
1490 | - *pp = r->preg[0x30]; | |
1491 | - pi = (void *)r->junkStack; r->junkStack += 4; | |
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; | |
1492 | 1509 | *pi = opt << 16 | r1 << 8 | p1; |
1493 | - for (i = 0; i < lenR; i++) | |
1510 | + for (i = 0; i < lenR; i++){ | |
1494 | 1511 | r->ireg[r0 + i] = r->ireg[0x30 + i]; |
1495 | - for (i = 0; i < lenP; i++) | |
1512 | + } | |
1513 | + for (i = 0; i < lenP; i++){ | |
1496 | 1514 | r->preg[p0 + i] = r->preg[0x31 + i]; |
1515 | + } | |
1497 | 1516 | return; |
1498 | 1517 | } |
1499 | 1518 |
@@ -1504,13 +1523,20 @@ void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int | ||
1504 | 1523 | r->junkStack -= 4; |
1505 | 1524 | r->junkStack -= 32; |
1506 | 1525 | HOSECPU_PointerRegisterEntry *pp = (void *)r->junkStack; |
1507 | - r->preg[0x30] = *pp; | |
1526 | + | |
1527 | + //r->preg[0x30] = *pp; | |
1528 | + PRegCopy(&r->preg[0x30], pp); | |
1529 | + // | |
1508 | 1530 | r->junkStack -= p1 * 32; pp = (void *)r->junkStack; |
1509 | - for (i = 0; i < p1; i++) | |
1510 | - r->preg[i] = pp[i]; | |
1531 | + for (i = 0; i < p1; i++){ | |
1532 | + //r->preg[i] = pp[i]; | |
1533 | + PRegCopy(&r->preg[i], &pp[i]); | |
1534 | + // | |
1535 | + } | |
1511 | 1536 | r->junkStack -= r1 * 4; int *pi = (void *)r->junkStack; |
1512 | - for (i = 0; i < r1; i++) | |
1537 | + for (i = 0; i < r1; i++){ | |
1513 | 1538 | r->ireg[i] = pi[i]; |
1539 | + } | |
1514 | 1540 | return; |
1515 | 1541 | } |
1516 | 1542 |
@@ -1518,10 +1544,13 @@ void funcf4(char *ebp, int pxx, int typ, int len) | ||
1518 | 1544 | { |
1519 | 1545 | HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128); |
1520 | 1546 | int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3; |
1521 | - if (width < 0 || r->ireg[len] < 0) | |
1547 | + if (width < 0 || r->ireg[len] < 0){ | |
1522 | 1548 | (*(r->errHndl))(r); |
1549 | + } | |
1523 | 1550 | void *p = r->junkStack; |
1524 | - if (r->junkStack + width * r->ireg[len] + 256 > r->junkStack1) (*(r->errHndl))(r); | |
1551 | + if (r->junkStack + width * r->ireg[len] + 256 > r->junkStack1){ | |
1552 | + (*(r->errHndl))(r); | |
1553 | + } | |
1525 | 1554 | r->junkStack += width * r->ireg[len]; |
1526 | 1555 | r->preg[pxx].p = p; |
1527 | 1556 | r->preg[pxx].typ = r->ireg[typ]; |
@@ -1533,8 +1562,9 @@ void funcf4(char *ebp, int pxx, int typ, int len) | ||
1533 | 1562 | if (r->ireg[typ] == 1) { |
1534 | 1563 | int i, i1 = (width * r->ireg[len]) >> 2; |
1535 | 1564 | pi = p; |
1536 | - for (i = 0; i < i1; i++) | |
1565 | + for (i = 0; i < i1; i++){ | |
1537 | 1566 | pi[i] = 0; |
1567 | + } | |
1538 | 1568 | } |
1539 | 1569 | return; |
1540 | 1570 | } |
@@ -1558,8 +1588,9 @@ void funcf6(char *ebp, int pxx, int typ, int len) | ||
1558 | 1588 | { |
1559 | 1589 | HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128); |
1560 | 1590 | int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3; |
1561 | - if (width < 0 || r->ireg[len] < 0) | |
1591 | + if (width < 0 || r->ireg[len] < 0){ | |
1562 | 1592 | (*(r->errHndl))(r); |
1593 | + } | |
1563 | 1594 | void *p = malloc(width * r->ireg[len]); |
1564 | 1595 | r->preg[pxx].p = p; |
1565 | 1596 | r->preg[pxx].typ = r->ireg[typ]; |
@@ -1568,10 +1599,12 @@ void funcf6(char *ebp, int pxx, int typ, int len) | ||
1568 | 1599 | if (r->ireg[typ] == 1) { |
1569 | 1600 | int i, i1 = (width * r->ireg[len]) >> 2, *pi; |
1570 | 1601 | pi = p; |
1571 | - for (i = 0; i < i1; i++) | |
1602 | + for (i = 0; i < i1; i++){ | |
1572 | 1603 | pi[i] = 0; |
1573 | - for (i = 1; i < i1; i += 8) | |
1604 | + } | |
1605 | + for (i = 1; i < i1; i += 8){ | |
1574 | 1606 | pi[i] |= -1; |
1607 | + } | |
1575 | 1608 | } |
1576 | 1609 | return; |
1577 | 1610 | } |
@@ -1605,26 +1638,34 @@ void errHndl(HOSECPU_RuntimeEnvironment *r) | ||
1605 | 1638 | int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label) |
1606 | 1639 | { |
1607 | 1640 | unsigned char *q = *qq; |
1608 | - if (p0[0] != 0x05 || p0[1] != SIGN1) // OSECPUのヘッダ (05E1) を確認 | |
1641 | + int i; | |
1642 | + | |
1643 | + if (p0[0] != 0x05 || p0[1] != SIGN1){ | |
1644 | + // OSECPUのヘッダ (05E1) を確認 | |
1609 | 1645 | return 1; |
1646 | + } | |
1647 | + | |
1648 | + jitCompPutOp_PUSH_GReg(q, IA32_REG5_EBP); | |
1610 | 1649 | |
1611 | - *q++ = 0x55; /* PUSH(EBP); */ | |
1612 | 1650 | *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */ |
1613 | 1651 | |
1614 | - int i; | |
1615 | - for (i = 0; i < JITC_MAXLABELS; i++) | |
1652 | + for (i = 0; i < JITC_MAXLABELS; i++){ | |
1616 | 1653 | label[i].opt = 0; |
1654 | + } | |
1617 | 1655 | |
1618 | 1656 | // 以下のjitCompile()呼び出しでは第二引数をq1-2にした方がよいのではないか? |
1619 | 1657 | i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, 0); |
1620 | - if (i != 0) return 2; | |
1658 | + if (i != 0){ | |
1659 | + return 2; | |
1660 | + } | |
1621 | 1661 | i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, JITC_PHASE1 + 0); |
1622 | - if (i < 0) return 2; | |
1662 | + if (i < 0){ | |
1663 | + return 2; | |
1664 | + } | |
1623 | 1665 | q += i; |
1624 | 1666 | |
1625 | - *q++ = 0x5d; /* POP(EBP); */ | |
1667 | + jitCompPutOp_POP_GReg(q, IA32_REG5_EBP); | |
1626 | 1668 | *q++ = 0xc3; /* RET(); */ |
1627 | - | |
1628 | 1669 | *qq = q; |
1629 | 1670 | return 0; |
1630 | 1671 | } |
@@ -1637,35 +1678,51 @@ int dbgrGetRegNum(const char *p) | ||
1637 | 1678 | if (p[2] <= ' ') { |
1638 | 1679 | i = p[0] - '0'; |
1639 | 1680 | j = p[1] - '0'; |
1640 | - if (i > 9) i -= 'A' - '0' - 10; | |
1641 | - if (j > 9) j -= 'A' - '0' - 10; | |
1642 | - if (0 <= i && i <= 15 && 0 <= j && j <= 15) | |
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){ | |
1643 | 1688 | r = i << 4 | j; |
1689 | + } | |
1644 | 1690 | } |
1645 | 1691 | return r; |
1646 | 1692 | } |
1647 | 1693 | |
1648 | 1694 | void dbgrMain(HOSECPU_RuntimeEnvironment *r) |
1649 | 1695 | { |
1650 | - if (r->dbgr == 0) return; | |
1696 | + if (r->dbgr == 0){ | |
1697 | + return; | |
1698 | + } | |
1651 | 1699 | for (;;) { |
1652 | 1700 | char cmd[64], *p; |
1653 | 1701 | int i, j, k; |
1702 | + | |
1654 | 1703 | printf("\ndbgr>"); |
1655 | 1704 | p = fgets(cmd, 64, stdin); |
1656 | - if (p == NULL) break; | |
1657 | - if (cmd[0] == '\0') continue; | |
1658 | - if (cmd[0] == 'q' && cmd[1] <= ' ') break; | |
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 | + } | |
1659 | 1714 | if (cmd[0] == 'p' && cmd[1] <= ' ' && cmd[1] != '\0') { |
1660 | 1715 | p = &cmd[2]; |
1661 | - while (*p <= ' ' && *p != '\0') p++; | |
1716 | + while (*p <= ' ' && *p != '\0'){ | |
1717 | + p++; | |
1718 | + } | |
1662 | 1719 | if (*p == 'R') { |
1663 | 1720 | i = dbgrGetRegNum(p + 1); |
1664 | 1721 | if (0 <= i && i <= 0x3f) { |
1665 | 1722 | printf("R%02X = 0x%08X = %d\n", i, r->ireg[i], r->ireg[i]); |
1666 | - } | |
1667 | - else | |
1723 | + } else{ | |
1668 | 1724 | puts("register name error"); |
1725 | + } | |
1669 | 1726 | continue; |
1670 | 1727 | } |
1671 | 1728 | if (*p == 'P') { |
@@ -1686,7 +1743,9 @@ void dbgrMain(HOSECPU_RuntimeEnvironment *r) | ||
1686 | 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)); |
1687 | 1744 | if (r->preg[i].p != NULL && r->preg[i].p0 != NULL) { |
1688 | 1745 | j = jitCompA000_dataWidth(jitCompA000_convTyp(r->preg[i].typ)) >> 3; |
1689 | - if (j <= 0) j = 1; | |
1746 | + if (j <= 0){ | |
1747 | + j = 1; | |
1748 | + } | |
1690 | 1749 | k = (r->preg[i].p1 - r->preg[i].p0) / j; |
1691 | 1750 | printf(" size = 0x%08X = %d\n", k, k); |
1692 | 1751 | k = (r->preg[i].p - r->preg[i].p0) / j; |
@@ -0,0 +1,275 @@ | ||
1 | +#include "osecpu.h" | |
2 | +#include "jitc.h" | |
3 | + | |
4 | +#if (JITC_ARCNUM == 0x0001) | |
5 | +// | |
6 | +// for x86-32bit | |
7 | +// | |
8 | +int jitCompGetImm32(const unsigned char *src) | |
9 | +{ | |
10 | + return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; | |
11 | +} | |
12 | + | |
13 | +int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src) | |
14 | +{ | |
15 | + int i = jitCompGetImm32(src); | |
16 | + if (i < 0 || i >= w->maxLabels) { | |
17 | + w->err = JITC_ERR_LABELNUM; | |
18 | + i = 0; | |
19 | + } | |
20 | + return i; | |
21 | +} | |
22 | + | |
23 | +void jitCompPutModRM_Disp_BaseEBP(struct JitCompWork *w, int disp, int opReg) | |
24 | +{ | |
25 | + // EBPをベースとするアドレスオペランドとレジスタオペランドを出力する | |
26 | + disp -= jitCompA0001_EBP128; | |
27 | + if (-128 <= disp && disp <= 127) { | |
28 | + // [EBP + Disp08] | |
29 | + jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_BYTE, opReg, IA32_REG5_EBP)); | |
30 | + jitCompPutByte1(w->dst, disp & 0xff); | |
31 | + } else { | |
32 | + // [EBP + Disp32] | |
33 | + jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_FULL, opReg, IA32_REG5_EBP)); | |
34 | + jitCompPutImm32(w->dst, disp); | |
35 | + } | |
36 | + return; | |
37 | +} | |
38 | + | |
39 | +void jitCompPutOp_MOV_EBPDisp_GReg(struct JitCompWork *w, int disp, int reg32) | |
40 | +{ | |
41 | + // MOV([EBP + disp] <- reg32); | |
42 | + // MOV Ev, Gv | |
43 | + // [1000 100 1] [mod reg r/m] | |
44 | + jitCompPutByte1(w->dst, 0x89); | |
45 | + jitCompPutModRM_Disp_BaseEBP(w, disp, reg32); | |
46 | + return; | |
47 | +} | |
48 | + | |
49 | +void jitCompPutOp_MOV_GReg_EBPDisp(struct JitCompWork *w, int reg32, int disp) | |
50 | +{ | |
51 | + // MOV (reg32 <- [EBP + disp]) | |
52 | + // MOV Gv, Ev | |
53 | + // [1000 101 1] [mod reg r/m] | |
54 | + jitCompPutByte1(w->dst, 0x8b); | |
55 | + jitCompPutModRM_Disp_BaseEBP(w, disp, reg32); | |
56 | + return; | |
57 | +} | |
58 | + | |
59 | +void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx) | |
60 | +{ | |
61 | +#if (jitCompA0001_USE_R3F_IMM32 != 0) | |
62 | + if (rxx == 0x3f) { | |
63 | + jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */ | |
64 | + jitCompPutImm32(w->dst, w->r3f); | |
65 | + return; | |
66 | + } | |
67 | +#endif | |
68 | + if (rxx >= 0x40 || rxx < 0){ | |
69 | + w->err = JITC_ERR_REGNUM; | |
70 | + } | |
71 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, rxx * 4); | |
72 | + return; | |
73 | +} | |
74 | + | |
75 | +void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx) | |
76 | +{ | |
77 | + if (rxx >= 0x40 || rxx < 0){ | |
78 | + w->err = JITC_ERR_REGNUM; | |
79 | + } | |
80 | + jitCompPutOp_MOV_EBPDisp_GReg(w, rxx * 4, IA32_REG0_EAX); | |
81 | + return; | |
82 | +} | |
83 | + | |
84 | +void jitCompA0001_fixPrefix(struct JitCompWork *w) | |
85 | +{ | |
86 | + if (w->prefix != 0) { | |
87 | + if (w->dst - w->dst0 > 127){ | |
88 | + w->err = JITC_ERR_REGNUM; | |
89 | + } | |
90 | + w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff); | |
91 | + } | |
92 | + return; | |
93 | +} | |
94 | + | |
95 | +void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1) | |
96 | +{ | |
97 | + if (p0 >= 0x3f || p0 < 0){ | |
98 | + w->err = JITC_ERR_PREGNUM; | |
99 | + } | |
100 | + if (p1 >= 0x3f || p1 < 0){ | |
101 | + w->err = JITC_ERR_PREGNUM; | |
102 | + } | |
103 | + /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */ | |
104 | + return; | |
105 | +} | |
106 | + | |
107 | +void jitCompA000_loadRegCacheAll(struct JitCompWork *w) | |
108 | +{ | |
109 | + //保存されたレジスタキャッシュをメモリからロード | |
110 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG3_EBX, 4 * 0); /* EBX = R00; */ | |
111 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 4 * 1); /* ECX = R01; */ | |
112 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 4 * 2); /* EDX = R02; */ | |
113 | + return; | |
114 | +} | |
115 | + | |
116 | +void jitCompA000_storeRegCacheAll(struct JitCompWork *w) | |
117 | +{ | |
118 | + //レジスタキャッシュをメモリに退避 | |
119 | + jitCompPutOp_MOV_EBPDisp_GReg(w, 0 * 4, IA32_REG3_EBX); /* R00 = EBX; */ | |
120 | + jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */ | |
121 | + jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */ | |
122 | + return; | |
123 | +} | |
124 | + | |
125 | +void jitCompA000_loadRegCacheEcx(struct JitCompWork *w) | |
126 | +{ | |
127 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 1 * 4); /* ECX = R01; */ | |
128 | + return; | |
129 | +} | |
130 | + | |
131 | +void jitCompA000_storeRegCacheEcx(struct JitCompWork *w) | |
132 | +{ | |
133 | + jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */ | |
134 | + return; | |
135 | +} | |
136 | + | |
137 | +void jitCompA000_loadRegCacheEdx(struct JitCompWork *w) | |
138 | +{ | |
139 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 2 * 4); /* EDX = R02; */ | |
140 | + return; | |
141 | +} | |
142 | + | |
143 | +void jitCompA000_storeRegCacheEdx(struct JitCompWork *w) | |
144 | +{ | |
145 | + jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */ | |
146 | + return; | |
147 | +} | |
148 | + | |
149 | +int jitCompA000_selectRegCache(int rxx, int reg) | |
150 | +{ | |
151 | + // OSECPUレジスタ番号をIA32レジスタ番号へ変換 | |
152 | + // 対応するキャッシュレジスタがない場合regが返る | |
153 | + switch (rxx) { | |
154 | + case 0: | |
155 | + reg = IA32_REG3_EBX; | |
156 | + break; | |
157 | + case 1: | |
158 | + reg = IA32_REG1_ECX; | |
159 | + break; | |
160 | + case 2: | |
161 | + reg = IA32_REG2_EDX; | |
162 | + break; | |
163 | + } | |
164 | + return reg; | |
165 | +} | |
166 | + | |
167 | +void jitCompA000_loadPRegCacheAll(struct JitCompWork *w) | |
168 | +{ | |
169 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG6_ESI, PRegOffset(0x01) + 0); /* ESI = P01; */ | |
170 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG7_EDI, PRegOffset(0x02) + 0); /* EDI = P02; */ | |
171 | + return; | |
172 | +} | |
173 | + | |
174 | +void jitCompA000_storePRegCacheAll(struct JitCompWork *w) | |
175 | +{ | |
176 | + jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x01) + 0, IA32_REG6_ESI); /* P01 = ESI; */ | |
177 | + jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x02) + 0, IA32_REG7_EDI); /* P02 = EDI; */ | |
178 | + return; | |
179 | +} | |
180 | + | |
181 | +int jitCompA000_selectPRegCache(int pxx, int reg) | |
182 | +{ | |
183 | + // if (pxx == 0) reg = 5; /* EBP */ | |
184 | + switch (pxx) { | |
185 | + case 1: | |
186 | + //ESI | |
187 | + reg = 6; | |
188 | + break; | |
189 | + | |
190 | + case 2: | |
191 | + //EDI | |
192 | + reg = 7; | |
193 | + break; | |
194 | + } | |
195 | + return reg; | |
196 | +} | |
197 | + | |
198 | +int jitCompA000_convTyp(int t) | |
199 | +{ | |
200 | + // 指定されたタイプのデータ幅を返す。 | |
201 | + // unsigned なら奇数(1bit目がOn) | |
202 | + // retv = 1 : VPtr | |
203 | + // retv = 2 or 3: BYTE ( 8, 4, 2, 1 bit) | |
204 | + // retv = 4 or 5: WORD (16, 12 bit) | |
205 | + // retv = 6 or 7: DWORD(32, 20, 24, 28 bit) | |
206 | + // -1はエラー | |
207 | + int r = -1; | |
208 | + | |
209 | + if (1 <= t && t <= 7){ | |
210 | + // 1 - 7はそのままでOK | |
211 | + r = t; | |
212 | + } else if (8 <= t && t <= 13){ | |
213 | + r = 2 | (t & 1); | |
214 | + } else if (14 <= t && t <= 15){ | |
215 | + r = 4 | (t & 1); | |
216 | + } else if (16 <= t && t <= 21){ | |
217 | + r = 6 | (t & 1); | |
218 | + } | |
219 | + return r; | |
220 | +} | |
221 | + | |
222 | +int jitCompA000_dataWidth(int t) | |
223 | +{ | |
224 | + // 指定されたタイプのビット数を返す | |
225 | + int r = -1; | |
226 | + if (t == 0x0001) r = 256; | |
227 | + t >>= 1; | |
228 | + if (t == 0x0002 / 2) r = 8; | |
229 | + if (t == 0x0004 / 2) r = 16; | |
230 | + if (t == 0x0006 / 2) r = 32; | |
231 | + if (t == 0x0008 / 2) r = 4; | |
232 | + if (t == 0x000a / 2) r = 2; | |
233 | + if (t == 0x000c / 2) r = 1; | |
234 | + if (t == 0x000e / 2) r = 12; | |
235 | + if (t == 0x0010 / 2) r = 20; | |
236 | + if (t == 0x0012 / 2) r = 24; | |
237 | + if (t == 0x0014 / 2) r = 28; | |
238 | + return r; | |
239 | +} | |
240 | + | |
241 | +unsigned char *errfnc; | |
242 | + | |
243 | +void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac) | |
244 | +{ | |
245 | + if (typ <= 0) { w->err = JITC_ERR_BADTYPE; } | |
246 | + if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; } | |
247 | + jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, PRegOffset(pxx) + 4); /* MOV(EAX, [EBP+?]); */ /* typ */ | |
248 | + jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */ | |
249 | + jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */ | |
250 | + jitCompPutImm32(w->dst, errfnc - (w->dst + 4)); | |
251 | + return; | |
252 | +} | |
253 | + | |
254 | +void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac) | |
255 | +{ | |
256 | + // data用. | |
257 | + // 将来的にはaliveやアクセス権チェックも入れる | |
258 | + jitCompA0001_checkType0(w, pxx, typ, ac); | |
259 | + return; | |
260 | +} | |
261 | + | |
262 | +void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx) | |
263 | +{ | |
264 | + jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ | |
265 | + jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 8, reg); /* p0 */ | |
266 | + jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */ | |
267 | + jitCompPutImm32(w->dst, errfnc - (w->dst + 4)); | |
268 | + jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */ | |
269 | + jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 12, reg); /* p1 */ | |
270 | + jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */ | |
271 | + jitCompPutImm32(w->dst, errfnc - (w->dst + 4)); | |
272 | + return; | |
273 | +} | |
274 | + | |
275 | +#endif |
@@ -1,9 +1,10 @@ | ||
1 | -#include "osecpu.h" | |
1 | +#include "osecpu.h" | |
2 | 2 | |
3 | 3 | int *keybuf, keybuf_r, keybuf_w, keybuf_c; |
4 | 4 | HOSECPU_Device_Window mainWindow; |
5 | 5 | //デバッグ用。プログラム中の随所で加算される変数 |
6 | 6 | int di1_serial; |
7 | +HOSECPU_RuntimeEnvironment *dbg_env; | |
7 | 8 | |
8 | 9 | |
9 | 10 |
@@ -22,44 +23,39 @@ void putKeybuf(int i) | ||
22 | 23 | |
23 | 24 | int HeavyOSECPUMain(int argc, char **argv) |
24 | 25 | { |
26 | + HOSECPU_RuntimeEnvironment env; | |
25 | 27 | FILE *fp; |
26 | - unsigned char *jitbuf, *sysjit; | |
28 | + unsigned char *jitbuf, *sysjit00, *sysjit; | |
27 | 29 | unsigned char *systmp0, *systmp1, *systmp2; |
28 | 30 | unsigned char *opTbl; |
29 | 31 | HOSECPU_LabelListTag *label; |
30 | 32 | int tmpsiz, i; |
31 | 33 | double tm0, tm1, tm2; |
32 | 34 | HOSECPU_PointerControlTag *ptrCtrl; |
35 | + unsigned char *syslib; | |
33 | 36 | int argDebug = 0, stacksiz = 1; |
34 | 37 | const char *cp; |
35 | - HOSECPU_RuntimeEnvironment env; | |
36 | 38 | void(*jitfunc)(char *); |
37 | 39 | unsigned char *jp; |
38 | 40 | |
39 | - //Initialize mainWindow | |
41 | + // For debug | |
42 | + dbg_env = &env; | |
43 | + | |
44 | + // Initialize mainWindow | |
40 | 45 | mainWindow.vram = NULL; |
41 | 46 | mainWindow.xsize = 0; |
42 | 47 | mainWindow.ysize = 0; |
43 | 48 | di1_serial = 0; |
44 | 49 | |
45 | - //実行環境初期化 | |
50 | + // 実行環境初期化 | |
46 | 51 | env.mainArgc = argc; |
47 | 52 | env.mainArgv = (const char **)argv; |
48 | 53 | env.appBin = malloc(APPSIZ1); |
49 | 54 | env.executionLevel = JITC_LV_SLOWEST; |
50 | - | |
51 | - if (env.mainArgc <= 1) | |
52 | - { | |
53 | - printf("Warning: file name is not set.\n"); | |
54 | - return 0; | |
55 | - } | |
56 | - | |
57 | - // JITコンパイラ用のバッファを確保 | |
58 | - jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */ | |
59 | - | |
55 | + jitbuf = mallocRWE(APPJITSIZE); /* とりあえず1MBで */ | |
60 | 56 | // syslib.oseのjitc結果を格納する領域を確保。 |
61 | - sysjit = mallocRWE(SJITSIZ1 + 256); // jitCompInit() のための領域を多めにとる | |
62 | - | |
57 | + sysjit00 = mallocRWE(SYSJITSIZ1); | |
58 | + sysjit = sysjit00; | |
63 | 59 | // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス |
64 | 60 | // sysjit: 現在のjitc書き込み位置 |
65 | 61 | // sysjit00: jitc結果の先頭 |
@@ -82,30 +78,19 @@ int HeavyOSECPUMain(int argc, char **argv) | ||
82 | 78 | ptrCtrl[0].size = -2; |
83 | 79 | |
84 | 80 | /* syslibの読み込み */ |
85 | - unsigned char const * const syslib = Init_LoadSysLib(argv[0], systmp0); | |
86 | - if ((argDebug & 4) != 0) | |
87 | - { | |
88 | - fp = fopen("debug4.bin", "wb"); | |
89 | - fwrite(syslib, 1, SYSLIBSIZ1, fp); | |
90 | - fclose(fp); | |
91 | - } | |
92 | - | |
93 | - // errHndl() を呼ぶコードを置く。このコードの番地はerrfncにセットされる。 | |
81 | + syslib = Init_LoadSysLib(argv[0], systmp0); | |
82 | + | |
94 | 83 | sysjit = jitCompInit(sysjit); |
95 | - unsigned char const * const sysjit00 = sysjit; | |
96 | - | |
84 | + sysjit00 = sysjit; | |
97 | 85 | // labelはjitc0()内で初期化される。 |
98 | - i = jitc0(&sysjit, sysjit00 + SJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST + 9, label); | |
86 | + i = jitc0(&sysjit, sysjit00 + SYSJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label); | |
99 | 87 | if (i != 0){ |
100 | - switch (i) | |
101 | - { | |
102 | - case 1: fputs("syslib-file header error.\n", stderr); break; | |
103 | - default: fputs("syslib-file JITC error.\n", stderr); break; | |
104 | - } | |
88 | + fputs("syslib-file JITC error.\n", stderr); | |
105 | 89 | return 1; |
106 | 90 | } |
107 | 91 | |
108 | - di1_serial = 1; | |
92 | + // エラー時にデバッグ用に表示する変数を加算 | |
93 | + di1_serial++; | |
109 | 94 | |
110 | 95 | /* アプリバイナリの読み込み */ |
111 | 96 | LoadAppBin(&env); |
@@ -113,7 +98,7 @@ int HeavyOSECPUMain(int argc, char **argv) | ||
113 | 98 | /* クロック初期化 */ |
114 | 99 | tm0 = clock() / (double)CLOCKS_PER_SEC; |
115 | 100 | |
116 | - if (env.appBin[2] == 0xf0) { // 最初の2byteはOSECPUのシグネチャである | |
101 | + if (env.appBin[2] == 0xf0) { | |
117 | 102 | // tek5圧縮がかかっている |
118 | 103 | #if (USE_TEK5 != 0) |
119 | 104 | env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0); |
@@ -125,8 +110,6 @@ int HeavyOSECPUMain(int argc, char **argv) | ||
125 | 110 | fputs("unsupported-format(tek5)\n", stderr); |
126 | 111 | return 1; |
127 | 112 | } |
128 | - | |
129 | - | |
130 | 113 | } |
131 | 114 | //デバッグモード指定 |
132 | 115 | cp = searchArg(argc, (const char **)argv, "debug:", 0); |
@@ -144,21 +127,21 @@ int HeavyOSECPUMain(int argc, char **argv) | ||
144 | 127 | |
145 | 128 | /* フロントエンドコードをバックエンドコードに変換する */ |
146 | 129 | if ((env.appBin[2] & 0xf0) != 0) { // 3バイト目が00なら処理しない |
147 | - systmp0[0] = env.appBin[0]; // 05 | |
148 | - systmp0[1] = env.appBin[1]; // E1 | |
149 | - env.preg[2].p = systmp0 + 2; // P02 : バックエンドコードを書き出すアドレス | |
150 | - env.preg[3].p = systmp0 + SYSTMP0SIZ; // P03 : バックエンドコードを書き出すアドレスの最大値 | |
151 | - env.preg[4].p = env.appBin + 2; // P04 : フロントエンドコードが格納されたアドレス(シグネチャ除く) | |
152 | - env.preg[5].p = env.appBin + env.appSize1; // P05 : フロントエンドコードが存在するアドレスの最大値 | |
153 | - env.preg[6].p = systmp1; // P06 : テンポラリメモリを確保したアドレス | |
154 | - env.preg[7].p = systmp1 + SYSTMP1SIZ; // P07 : P06の最大値 | |
155 | - env.preg[10].p = systmp2; // P0A : また別のテンポラリ | |
130 | + systmp0[0] = env.appBin[0]; | |
131 | + systmp0[1] = env.appBin[1]; | |
132 | + env.preg[2].p = systmp0 + 2; | |
133 | + env.preg[3].p = systmp0 + SYSTMP0SIZ; | |
134 | + env.preg[4].p = env.appBin + 2; | |
135 | + env.preg[5].p = env.appBin + env.appSize1; | |
136 | + env.preg[6].p = systmp1; | |
137 | + env.preg[7].p = systmp1 + SYSTMP1SIZ; | |
138 | + env.preg[10].p = systmp2; | |
156 | 139 | int pxxFlag[64], typLabel[4096]; |
157 | - env.preg[0x0b].p = (void *)pxxFlag; // P0B | |
158 | - env.preg[0x0c].p = (void *)typLabel; // P0C | |
159 | - env.preg[0x0d].p = opTbl; // P0D | |
140 | + env.preg[0x0b].p = (void *)pxxFlag; | |
141 | + env.preg[0x0c].p = (void *)typLabel; | |
142 | + env.preg[0x0d].p = opTbl; | |
160 | 143 | jitfunc = (void *)sysjit00; |
161 | - (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ | |
144 | + jitcRunBinary(jitfunc, &env); | |
162 | 145 | if (env.ireg[0] != 0) { |
163 | 146 | jp = env.preg[2].p - 1; |
164 | 147 | fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]); |
@@ -247,7 +230,7 @@ int HeavyOSECPUMain(int argc, char **argv) | ||
247 | 230 | /* JITコード実行 */ |
248 | 231 | jitfunc = (void *)jitbuf; |
249 | 232 | if (setjmp(env.setjmpEnv) == 0){ |
250 | - (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ | |
233 | + jitcRunBinary(jitfunc, &env); | |
251 | 234 | } |
252 | 235 | if (env.autoSleep != 0) { |
253 | 236 | if (mainWindow.vram != NULL){ |
@@ -276,22 +259,20 @@ int HeavyOSECPUMain(int argc, char **argv) | ||
276 | 259 | return env.appReturnCode; |
277 | 260 | } |
278 | 261 | |
279 | -/* | |
280 | - * argv0 : osecpu.exe の存在するパス | |
281 | - * tmpWprkMemory : SYSTMP0SIZ分確保されている | |
282 | - */ | |
283 | 262 | unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory) |
284 | 263 | { |
264 | + unsigned char *syslib; | |
285 | 265 | FILE *fp; |
286 | 266 | unsigned char *up; |
287 | 267 | int appsize; |
288 | 268 | |
289 | 269 | /* syslibの読み込み */ |
290 | - unsigned char *syslib = malloc(SYSLIBSIZ1); | |
270 | + syslib = malloc(SYSLIBSIZ1); | |
291 | 271 | fp = fopen(SYSLIB_OSE, "rb"); |
292 | 272 | if (fp == NULL) { |
293 | - strcpy((char *)syslib, argv0); | |
294 | - up = syslib; | |
273 | + syslib[0] = '/'; | |
274 | + strcpy((char *)syslib + 1, argv0); | |
275 | + up = syslib + 1; | |
295 | 276 | while (*up != '\0'){ |
296 | 277 | up++; |
297 | 278 | } |
@@ -300,7 +281,7 @@ unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory) | ||
300 | 281 | } |
301 | 282 | up++; |
302 | 283 | strcpy((char *)up, SYSLIB_OSE); |
303 | - fp = fopen((char *)syslib, "rb"); | |
284 | + fp = fopen((char *)syslib + 1, "rb"); | |
304 | 285 | } |
305 | 286 | if (fp == NULL) { |
306 | 287 | fputs("syslib-file fopen error.\n", stderr); |
@@ -319,7 +300,10 @@ unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory) | ||
319 | 300 | syslib[0] = 0x05; |
320 | 301 | syslib[1] = 0x1b; |
321 | 302 | } |
322 | - | |
303 | + | |
304 | + fp = fopen("syslib_dbg.ose", "wb"); | |
305 | + fwrite(syslib, 1, SYSLIBSIZ1, fp); | |
306 | + fclose(fp); | |
323 | 307 | return syslib; |
324 | 308 | } |
325 | 309 |
@@ -328,6 +312,10 @@ void LoadAppBin(HOSECPU_RuntimeEnvironment *env) | ||
328 | 312 | FILE *fp; |
329 | 313 | const char *fileName; |
330 | 314 | /* アプリバイナリの読み込み */ |
315 | + if (env->mainArgc <= 1) { | |
316 | + //アプリ名未指定なので何事もなく終了 | |
317 | + exit(EXIT_SUCCESS); | |
318 | + } | |
331 | 319 | fileName = env->mainArgv[1]; |
332 | 320 | //アプリ名先頭に:n:をつけることでレベルnでの実行が可能? |
333 | 321 | if (fileName[0] == ':' && fileName[2] == ':') { |
@@ -1,4 +1,4 @@ | ||
1 | -#ifndef _HDLOAD_OSECPU | |
1 | +#ifndef _HDLOAD_OSECPU | |
2 | 2 | #define _HDLOAD_OSECPU 1 |
3 | 3 | |
4 | 4 | /* Visual Studio で fopen()やsprintf() などの古い関数を使用する時に出る警告を抑止する*/ |
@@ -67,8 +67,8 @@ | ||
67 | 67 | #define PTRCTRLSIZ 4096 |
68 | 68 | |
69 | 69 | #define APPSIZ1 1 * 1024 * 1024 /* 1MB for now */ |
70 | -#define JITSIZ1 1 * 1024 * 1024 /* 1MB for now */ | |
71 | -#define SJITSIZ1 1 * 1024 * 1024 /* 1MB for now */ | |
70 | +#define APPJITSIZE 1 * 1024 * 1024 /* 1MB for now */ | |
71 | +#define SYSJITSIZ1 2 * 1024 * 1024 /* 1MB for now */ | |
72 | 72 | #define SYSLIBSIZ1 1 * 1024 * 1024 /* 1MB for now */ |
73 | 73 | #define SYSTMP0SIZ 1 * 1024 * 1024 /* 1MB for now */ |
74 | 74 | #define SYSTMP1SIZ 2 * 1024 * 1024 /* 1MB for now */ |
@@ -100,11 +100,11 @@ struct PtrCtrl { | ||
100 | 100 | unsigned char *p0; |
101 | 101 | }; |
102 | 102 | |
103 | -// Ptr | |
104 | 103 | typedef struct Ptr HOSECPU_PointerRegisterEntry; |
105 | -struct Ptr { /* 32バイト(=256bit!) */ | |
104 | +struct Ptr { | |
105 | + // 32バイト(=256bit!) | |
106 | 106 | unsigned char *p; |
107 | - | |
107 | + | |
108 | 108 | /* static char *typName[] = { |
109 | 109 | "T_CODE", "T_VPTR", "T_SINT8", "T_UINT8", |
110 | 110 | "T_SINT16", "T_UINT16", "T_SINT32", "T_UINT32", |
@@ -120,7 +120,6 @@ struct Ptr { /* 32バイト(=256bit!) */ | ||
120 | 120 | int flags, dummy; /* read/writeなど */ |
121 | 121 | }; |
122 | 122 | |
123 | -// LabelTable | |
124 | 123 | typedef struct LabelTable HOSECPU_LabelListTag; |
125 | 124 | struct LabelTable { |
126 | 125 | unsigned char *p, *p1; |
@@ -135,36 +134,38 @@ struct LabelTable { | ||
135 | 134 | int typ; |
136 | 135 | }; |
137 | 136 | |
138 | -// Device_Window | |
139 | 137 | typedef struct Device_Window HOSECPU_Device_Window; |
140 | 138 | struct Device_Window { |
141 | - int *vram; // 初期値 : NULL | |
142 | - int xsize, ysize; // 初期値 : 0, 0 | |
139 | + int *vram; | |
140 | + int xsize, ysize; | |
143 | 141 | }; |
144 | 142 | |
145 | -// Regs + env | |
146 | 143 | typedef struct Regs HOSECPU_RuntimeEnvironment; |
147 | -struct Regs{ | |
148 | - int ireg[64]; /* 32bit整数レジスタ */ | |
149 | - HOSECPU_PointerRegisterEntry preg[64]; /* ポインタレジスタ */ | |
144 | +struct Regs { | |
145 | + int ireg[64]; // 整数レジスタ (4 * 64) = 256 | |
146 | + HOSECPU_PointerRegisterEntry preg[64]; // ポインタレジスタ (32 * 64) = 2048 | |
147 | + // | |
148 | + int debugInfo0; // 2304 | |
149 | + int debugInfo1; // 2308 | |
150 | + int dbg_currentCode; // 2312 | |
151 | + int dmy; // 2316 | |
150 | 152 | // |
151 | - int debugInfo0, debugInfo1, dmy[2]; /* 2304 */ | |
152 | - HOSECPU_PointerControlTag *ptrCtrl; /* 2320 */ | |
153 | + HOSECPU_PointerControlTag *ptrCtrl; // 2320 | |
153 | 154 | char winClosed, autoSleep; |
154 | 155 | jmp_buf setjmpEnv; |
155 | - int appReturnCode; // アプリ自体の終了コード | |
156 | - | |
157 | - /* Main environment */ | |
158 | - int mainArgc; // HOSECPU起動引数の個数 | |
159 | - const char **mainArgv; // HOSECPU起動引数リスト | |
160 | - unsigned char *appBin; // 実行するアプリのバイナリ | |
161 | - int appSize0; // アプリバイナリ読み込み時のサイズ(定数) | |
162 | - int appSize1; // アプリのフロントエンドコードのサイズ(tek解凍後) | |
163 | - int executionLevel; | |
164 | - | |
156 | + int appReturnCode; // アプリ自体の終了コード | |
157 | + | |
158 | + /* Main environment */ | |
159 | + int mainArgc; // HOSECPU起動引数の個数 | |
160 | + const char **mainArgv; // HOSECPU起動引数リスト | |
161 | + unsigned char *appBin; // 実行するアプリのバイナリ | |
162 | + int appSize0; | |
163 | + int appSize1; | |
164 | + int executionLevel; | |
165 | + | |
165 | 166 | /* for-junkApi */ |
166 | 167 | unsigned char *buf0, *buf1, *junkStack, lastConsoleChar, *junkStack1; |
167 | - | |
168 | + | |
168 | 169 | HOSECPU_LabelListTag *label; |
169 | 170 | int maxLabels; |
170 | 171 | unsigned char *jitbuf, *jitbuf1; |
@@ -205,11 +206,14 @@ const char *searchArg(int argc, const char **argv, const char *tag, int i); // | ||
205 | 206 | void devFunc(HOSECPU_RuntimeEnvironment *r); // junkApiを処理する関数 |
206 | 207 | |
207 | 208 | // @jitc.c |
209 | +void errorHandler(HOSECPU_RuntimeEnvironment *r); | |
210 | +void PRegCopy(HOSECPU_PointerRegisterEntry *dst, HOSECPU_PointerRegisterEntry *src); | |
211 | +// @jitcx86.c | |
208 | 212 | int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label); |
209 | 213 | 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); |
210 | 214 | unsigned char *jitCompCallFunc(unsigned char *dst, void *func); |
211 | 215 | unsigned char *jitCompInit(unsigned char *dst); |
212 | -void errorHandler(HOSECPU_RuntimeEnvironment *r); | |
216 | +void jitcRunBinary(void (*bin)(char *), HOSECPU_RuntimeEnvironment *env); | |
213 | 217 | |
214 | 218 | // @randmt.c |
215 | 219 | void randStatInit(unsigned int seed); |
@@ -237,3 +241,4 @@ int tek5Decomp(UCHAR *buf, UCHAR *buf1, UCHAR *tmp); | ||
237 | 241 | |
238 | 242 | #endif |
239 | 243 | |
244 | +>>>>>>> 4d5d6fa61ff576ba035ee4bd882e8476f2ceeb2b |