• R/O
  • HTTP
  • SSH
  • HTTPS

HeavyOSECPU: Commit


Commit MetaInfo

Revisión035a08b35ab09fd704b2c66c5de5c70b66572bc6 (tree)
Tiempo2014-03-17 07:52:03
Autorttwilb <ttwilb@user...>
Commiterttwilb

Log Message

Merge branch 'master' of git.sourceforge.jp:/gitroot/heavyosecpu/HeavyOSECPU

Conflicts:
jitcx86.c
main.c
osecpu.h

Cambiar Resumen

Diferencia incremental

--- a/function.c
+++ b/function.c
@@ -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+
--- a/jitc.c
+++ b/jitc.c
@@ -62,7 +62,20 @@ int jitCompCmdLen(const unsigned char *src)
6262 return i;
6363 }
6464
65+void PRegCopy(HOSECPU_PointerRegisterEntry *dst, HOSECPU_PointerRegisterEntry *src)
66+{
67+ // なんか直接代入するとMacではアライメントエラーで落ちるのです...
68+ // dst = src;
6569
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+}
6679
6780
6881
--- a/jitc.h
+++ b/jitc.h
@@ -1,7 +1,9 @@
1-
1+
22 #ifndef HeavyOSECPU_jitc_h
33 #define HeavyOSECPU_jitc_h
44
5+
6+
57 // Error flags
68 #define JITC_ERR_MASK 255
79 #define JITC_ERR_PHASE0ONLY 256
@@ -39,7 +41,49 @@ int jitCompCmdLen(const unsigned char *src);
3941 //
4042 // for x86-32bit
4143 //
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
4387 // 他のCPUへ移植する人へ:
4488 // 以下の定数は最適化のためのものなので、すべて0として簡単に移植しても問題ありません
4589 #define jitCompA0001_USE_R3F_CMPJMP 1*1
@@ -49,8 +93,8 @@ int jitCompCmdLen(const unsigned char *src);
4993 #define jitCompA0001_OPTIMIZE_JMP 1*1
5094 #define jitCompA0001_OPTIMIZE_MOV 1*1 /* 1にすると速度低下する? */
5195 #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にもできる
5498
5599 struct JitCompWork {
56100 unsigned char *dst, *dst0;
@@ -61,12 +105,12 @@ struct JitCompWork {
61105 char prefix; //CND命令の値を記録(初期値=0)
62106 };
63107
64-void jitCompPutImm32(struct JitCompWork *w, int i);
108+// @jitcx86a.c
65109 int jitCompGetImm32(const unsigned char *src);
66110 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);
70114 void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx);
71115 void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx);
72116 void jitCompA0001_fixPrefix(struct JitCompWork *w);
@@ -86,6 +130,9 @@ int jitCompA000_dataWidth(int t);
86130 void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac);
87131 void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac);
88132 void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx);
133+
134+// @jitcx86.c
135+extern unsigned char *errfnc;
89136 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);
90137 unsigned char *jitCompCallFunc(unsigned char *dst, void *func);
91138 unsigned char *jitCompInit(unsigned char *dst);
@@ -105,14 +152,6 @@ void dbgrMain(HOSECPU_RuntimeEnvironment *r);
105152
106153
107154
108-
109-
110-
111-
112-
113-
114-
115-
116155 #endif
117156
118157 #endif
--- a/jitcx86.c
+++ b/jitcx86.c
@@ -1,4 +1,4 @@
1-#include "osecpu.h"
1+#include "osecpu.h"
22 #include "jitc.h"
33
44 #if (JITC_ARCNUM == 0x0001)
@@ -6,264 +6,6 @@
66 // for x86-32bit
77 //
88
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-
2679 // F5の場合、decoderが対応するalloc-freeを結びつけるのが簡単で、typやlenを指定必須にしてもフロントエンドコードに影響はない.
26810 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)
26911 {
@@ -281,96 +23,130 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
28123 const unsigned char *oldsrc;
28224 int timecount = 0, i, j = 0, lastlabel = -1, debugInfo0 = -1;
28325 int reg0, reg1, reg2, cmp0reg = -1, cmp0lev = 0;
26+
28427 w.dst = w.dst0 = dst;
28528 w.err = 0;
28629 w.maxLabels = maxLabels;
28730
28831 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);
29135 jitCompA000_loadPRegCacheAll(&w);
29236 }
29337 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);
29944 }
30045 while (src < src1) {
30146 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+ }
30352 timecount++;
30453 if (timecount >= 64) {
30554 timecount -= 64;
30655 /* 未完成(timeoutチェックコードを入れる) */
30756 }
308- prefix_continue: // CND命令実行後ここに戻る
57+ if(*src != 0x00 && *src != 0x01 && *src != 0x34){
58+ DEBUGCode(&w, *src);
59+ }
60+ prefix_continue:
61+ // CND命令コンパイル後ここに戻る
30962 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+ }
31370 break;
31471
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
33084 // LB命令の後に0x3C命令・・・beginFunc()
331- jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする
33285 enter0 = w.dst;
333- jitCompPutImm32(&w, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ??
86+ jitCompPutOp_JMPnear(w.dst, 0);
33487 }
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 を取得
33995 j = 32;
96+
34097 if (i != 1) {
34198 i = jitCompA000_convTyp(i);
34299 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+ }
346111 }
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+
350121 #if (jitCompA0001_OPTIMIZE_JMP != 0)
351- if (j <= 127 - jitCompA0001_OPTIMIZE_ALIGN) {
122+ if (j < 127 - jitCompA0001_OPTIMIZE_ALIGN) {
123+ //飛び先が十分近いので
124+ // 今書いたのはなかったことにして、
352125 w.dst -= 5;
353- jitCompPutByte2(w.dst, 0xeb, j);
126+ // よりサイズの小さな書き方にする
127+ jitCompPutOp_JMPshort(w.dst, j);
354128 }
355129 #endif
356130 }
357131 #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]); */
370143 #endif
371144 if (src[6] == 0x34) {
145+ // 後続命令はDATA
146+ // パディングに合わせて一個前の相対ジャンプを修正
372147 tmp_ucp[1] = j & 0xff;
373148 if (*tmp_ucp == 0xe9) {
149+ // Near jump so imm is DWORD
374150 tmp_ucp[2] = (j >> 8) & 0xff;
375151 tmp_ucp[3] = (j >> 16) & 0xff;
376152 tmp_ucp[4] = (j >> 24) & 0xff;
@@ -378,9 +154,14 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
378154 }
379155 if ((flags & JITC_PHASE1) == 0) {
380156 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+ }
384165 label[i].opt = src[1] + 1;
385166 label[i].typ = 0; /* TYP_CODE */
386167 label[i].p = w.dst;
@@ -392,71 +173,86 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
392173 /* 未完成(timeoutチェックコードを入れる) */
393174 break;
394175
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命令の直後では使用できない。
405183
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+ }
407188
408189 #if (jitCompA0001_USE_R3F_IMM32 != 0)
409- if (src[1] == 0x3f) { // R3Fへの代入は例外敵に、 w.r3f を使用
190+ if (src[1] == 0x3f) {
191+ // R3Fへの代入は例外で、 w.r3f を使用
410192 w.r3f = jitCompGetImm32(src + 2);
411193 break;
412194 }
413195 #endif
414196 i = jitCompGetImm32(src + 2); // 与えられた即値(第二引数)を取得
415-
416197 /* 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+
419200 #if (jitCompA0001_OPTIMIZE_MOV != 0)
201+ // size optimization
202+ // MOV reg, 0 -> XOR reg, reg
420203 if (i == 0) {
421- jitCompPutByte2(w.dst, 0x31, 0xc0 | reg0 << 3 | reg0); /* XOR(reg0, reg0); */
204+ jitCompPutOp_XOR_GReg_GReg(w.dst, reg0, reg0);
422205 jitCompA0001_movRxxEax(&w, src[1]);
423206 break;
424207 }
425208 #endif
426-
427209 /* 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);
430211
431- if (reg0 == 0) // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合
432-
212+ if (reg0 == 0){
213+ // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合
433214 jitCompA0001_movRxxEax(&w, src[1]);
434- break;
215+ }
435216
436- case 0x03: /* PLIMM */ /* 未完成(plsまで対応) */
217+ break;
437218
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+ //
448229
449230 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+ }
454248 }
455- if (src[1] == 0x3f) { // プログラムカウンタへの代入なら
456- if (w.prefix == 0) { // CND命令による条件付きでなければ、即座に移動
249+ if (src[1] == 0x3f) {
250+ // プログラムカウンタへの代入
251+ if (w.prefix == 0) {
252+ // CND命令による条件付きでなければ、即座に移動
457253 jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */
458- }
459- else { // 直前はCND命令。
254+ } else {
255+ // 直前はCND命令。
460256
461257 /*
462258 * CND命令
@@ -466,7 +262,8 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
466262 * いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd
467263 */
468264
469- // JZのとび先アドレスの書き換え?
265+ // Jccの条件変更
266+ // 0F 75
470267 w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */
471268 w.dst[-2] = 0x0f;
472269
@@ -475,15 +272,14 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
475272 j = 0;
476273 if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) // label番号iが確保されていれば (このif文は意味をなさない)
477274 j = label[i].p - (w.dst + 4); // j はとび先の相対番地
478- jitCompPutImm32(&w, j); // JMP もしくは JZ 命令のアドレス部を記述
275+ jitCompPutImm32(w.dst, j); // JMP もしくは JZ 命令のアドレス部を記述
479276 #if (jitCompA0001_OPTIMIZE_JMP != 0)
480277 if (-128 - 3 <= j && j < 0) {
481278 if (w.dst[-5] == 0xe9) {
482279 j += 3;
483280 w.dst -= 5;
484281 jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */
485- }
486- else {
282+ } else {
487283 j += 4;
488284 w.dst -= 6;
489285 jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0);
@@ -491,60 +287,60 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
491287 jitCompPutByte1(w.dst, j & 0xff);
492288 }
493289 #endif
494- }
495- else { // プログラムカウンタ以外への代入
496-
290+ } else { // プログラムカウンタ以外への代入
497291 // 代入先が 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+ }
505299
506300 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 */
518310 }
519311 }
520312 break;
521313
522- case 0x04: /* CND (prefix) */
523-
524- /*
525- * CND命令
526- * 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。
527- */
314+ case 0x04:
315+ // CND (prefix)
316+ // 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。
528317
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+ }
530323
531324 // 比較対象のレジスタがメモリ上にあれば-1, それ以外なら適切なレジスタ番号を返す
532325 reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */);
533326
534327 /* 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 */
538335 }
539- else {
540- jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST(reg0,1); */
541- }
542- jitCompPutImm32(&w, 1);
336+ jitCompPutImm32(w.dst, 1);
543337
544338 /* JZ命令を発行 */
545339 jitCompPutByte2(w.dst, 0x74, 0x00); /* JZ($+2) */
546340 cmp0reg = -1;
547- if (w.err != 0) goto err_w;
341+ if (w.err != 0){
342+ goto err_w;
343+ }
548344 src += 2;
549345 w.prefix = 1; // プリフィックスをセット
550346 w.dst0 = w.dst;
@@ -552,21 +348,27 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
552348
553349 case 0x08: /* LMEM */ /* 完成 */
554350 i = jitCompGetImm32(src + 2);
555- if (i == 0x0001) w.err = JITC_ERR_BADTYPE;
351+ if (i == 0x0001){
352+ w.err = JITC_ERR_BADTYPE;
353+ }
556354 if (level < JITC_LV_FASTER) {
557355 jitCompA0001_checkType(&w, src[6], i, 0); // read
558356 cmp0reg = -1;
559357 }
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){
565364 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){
569370 jitCompA0001_checkLimit(&w, reg1, src[6]);
371+ }
570372 i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
571373 switch (i) {
572374 case 0x0002:
@@ -588,31 +390,40 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
588390 default:
589391 w.err = JITC_ERR_BADTYPE;
590392 }
591- if (reg0 == 0 /* EAX */)
393+ if (reg0 == IA32_REG0_EAX){
592394 jitCompA0001_movRxxEax(&w, src[1]);
593- if (reg1 == 2 /* EDX */)
395+ }
396+ if (reg1 == IA32_REG2_EDX){
594397 jitCompA000_loadRegCacheEdx(&w);
398+ }
595399 break;
596400
597401 case 0x09: /* SMEM */ /* 完成 */
598402 i = jitCompGetImm32(src + 2);
599- if (i == 0x0001) w.err = JITC_ERR_BADTYPE;
403+ if (i == 0x0001){
404+ w.err = JITC_ERR_BADTYPE;
405+ }
600406 if (level < JITC_LV_FASTER) {
601407 jitCompA0001_checkType(&w, src[6], i, 1); // write
602408 cmp0reg = -1;
603409 }
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){
609416 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){
613422 jitCompA0001_checkLimit(&w, reg1, src[6]);
614- if (reg0 == 0 /* EAX */)
423+ }
424+ if (reg0 == IA32_REG0_EAX){
615425 jitCompA0001_movEaxRxx(&w, src[1]);
426+ }
616427 /* 値の範囲チェック */
617428 i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
618429 switch (i) {
@@ -631,40 +442,49 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
631442 default:
632443 w.err = JITC_ERR_BADTYPE;
633444 }
634- if (reg1 == 2 /* EDX */)
445+ if (reg1 == IA32_REG2_EDX){
635446 jitCompA000_loadRegCacheEdx(&w);
447+ }
636448 break;
637449
638450 case 0x0a: /* PLMEM */ /* 完成 */
639451 i = jitCompGetImm32(src + 2);
640- if (i != 0x0001) w.err = JITC_ERR_BADTYPE;
452+ if (i != 0x0001){
453+ w.err = JITC_ERR_BADTYPE;
454+ }
641455 if (level < JITC_LV_FASTER) {
642456 jitCompA0001_checkType(&w, src[6], i, 0); // read
643457 cmp0reg = -1;
644458 }
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);
647461 // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */
648462 // 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!
650465 jitCompA000_storePRegCacheAll(&w);
651- reg1 = 2; /* EDX */
466+ reg1 = IA32_REG2_EDX;
652467 }
653- if (reg1 == 2 /* EDX */)
468+ if (reg1 == IA32_REG2_EDX){
654469 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){
658475 jitCompA0001_checkLimit(&w, reg1, src[6]);
476+ }
659477 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+ }
662481 for (i = 4; i < 32; i += 4) {
663482 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); */
665484 }
666- if (reg1 == 2 /* EDX */)
485+ if (reg1 == IA32_REG2_EDX){
667486 jitCompA000_loadRegCacheEdx(&w);
487+ }
668488 break;
669489
670490 case 0x0b: /* PSMEM */ /* 完成 */
@@ -674,24 +494,29 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
674494 jitCompA0001_checkType(&w, src[6], i, 1); // write
675495 cmp0reg = -1;
676496 }
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 */)
680501 // reg1 = 0; /* EAX */
681- if (reg1 == 2 /* EDX */)
502+ if (reg1 == IA32_REG2_EDX){
682503 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){
686509 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+ }
689514 jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */
690515 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+?]); */
692517 jitCompPutByte3(w.dst, 0x89, 0x40 | reg1, i); /* MOV([reg1+?], EAX); */
693518 }
694- if (reg1 == 2 /* EDX */)
519+ if (reg1 == IA32_REG2_EDX)
695520 jitCompA000_loadRegCacheEdx(&w);
696521 break;
697522
@@ -700,63 +525,78 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
700525 jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 2), 2); // other, aliveテストはとりあえずしない.
701526 cmp0reg = -1;
702527 }
703- reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */);
528+ reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX);
704529 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+ }
707533 if (reg1 >= 0 && reg0 != reg1) {
708534 jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
709535 }
710536 i = jitCompGetImm32(src + 2);
711537 j = -1;
712- if (i == 1)
538+ if (i == 1){
713539 j = 5; /* 32 */
714- else {
540+ } else {
715541 i = jitCompA000_convTyp(i);
716- if (0x0002 <= i && i <= 0x0007)
542+ if (0x0002 <= i && i <= 0x0007){
717543 j = (i - 0x0002) >> 1;
544+ }
545+ }
546+ if (j < 0) {
547+ w.err = JITC_ERR_BADTYPE;
548+ goto err_w;
718549 }
719- if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; }
720550 #if (jitCompA0001_USE_R3F_IMM32 != 0)
721551 if (src[7] == 0x3f) {
722552 j = w.r3f << j;
723553 #if (jitCompA0001_USE_R3F_IMM8 != 0)
724554 if (-0x80 <= j && j <= 0x7f) {
725555 #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+ }
728566 #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);
730569 goto padd1;
731570 }
732571 #endif
733572 if (reg0 == 0) {
734573 jitCompPutByte1(w.dst, 0x05); /* ADD(reg0, ?); */
735- }
736- else {
574+ } else {
737575 jitCompPutByte2(w.dst, 0x81, 0xc0 | reg0); /* ADD(reg0, ?); */
738576 }
739- jitCompPutImm32(&w, j);
577+ jitCompPutImm32(w.dst, j);
740578 goto padd1;
741579 }
742580 #endif
743- if (src[7] >= 0x40) w.err = JITC_ERR_REGNUM;
581+ if (src[7] >= 0x40){
582+ w.err = JITC_ERR_REGNUM;
583+ }
744584 if (j == 0) {
745585 reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */);
746586 if (reg1 >= 0) {
747587 jitCompPutByte2(w.dst, 0x01, 0xc0 | reg1 << 3 | reg0); /* ADD(reg0, reg1); */
748- }
749- else {
588+ } else {
750589 jitCompPutByte1(w.dst, 0x03); /* ADD(reg0, [EBP+?]); */
751- jitCompA0001_85DispN(&w, src[7] * 4, reg0);
590+ jitCompPutModRM_Disp_BaseEBP(&w, src[7] * 4, reg0);
752591 }
753592 }
754593 else {
755594 reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */);
756- reg2 = 2; /* EDX */
595+ reg2 = IA32_REG2_EDX;
757596 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+ }
760600 if (reg1 >= 0 && reg1 != reg2) {
761601 jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg2); /* MOV(reg2, reg1); */
762602 }
@@ -767,35 +607,42 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
767607 #if (jitCompA0001_USE_R3F_IMM32 != 0)
768608 padd1:
769609 #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+ }
772613 if (src[1] != src[6]) {
773614 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); */
776617 }
777618 }
778619 cmp0reg = -1;
779620 break;
780621
781622 case 0x0f: /* PDIF */ /* 未完成 */
782- reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
623+ reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
783624 jitCompA000_storePRegCacheAll(&w); // 手抜き.
784625 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+?]); */
786627 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);
788629 i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
789630 j = -1;
790- if (0x0002 <= i && i <= 0x0007)
631+ if (0x0002 <= i && i <= 0x0007){
791632 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+ }
793638 if (j > 0) {
794639 jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, j); /* SAR(reg0,?); */
795640 }
796- if (reg0 == 0 /* EAX */)
641+ if (reg0 == IA32_REG0_EAX){
797642 jitCompA0001_movRxxEax(&w, src[1]);
798- cmp0reg = src[1]; cmp0lev = 1;
643+ }
644+ cmp0reg = src[1];
645+ cmp0lev = 1;
799646 break;
800647
801648 case 0x10: /* OR */
@@ -804,58 +651,70 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
804651 case 0x14: /* ADD */
805652 case 0x15: /* SUB */
806653 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);
809658 reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */);
810659 #if (jitCompA0001_USE_R3F_IMM32 != 0)
811660 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+ }
813664 reg2 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
814- if (reg2 >= 0)
665+ if (reg2 >= 0){
815666 jitCompA000_storeRegCacheAll(&w);
667+ }
816668 jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */
817- jitCompPutImm32(&w, w.r3f);
669+ jitCompPutImm32(w.dst, w.r3f);
818670 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){
821673 jitCompA0001_movRxxEax(&w, src[1]);
674+ }
822675 break;
823676 }
824677 #endif
825678 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+?]); */
827680 }
828681 if (reg1 >= 0 && reg0 != reg1) {
829682 jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
830683 }
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!
832686 cmp0reg = src[1];
833687 cmp0lev = 1;
834- if (src[0] < 0x14)
688+ if (src[0] < 0x14){
835689 cmp0lev = 2;
836- if (src[0] == 0x16)
690+ }
691+ if (src[0] == 0x16){
837692 cmp0reg = -1;
693+ }
838694 }
839695 if (!(src[0] == 0x10 && src[3] == 0xff)) {
840696 #if (jitCompA0001_USE_R3F_IMM32 != 0)
841697 if (src[3] == 0x3f) {
842698 if (*src == 0x16 && w.r3f == -1) {
843699 jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */
844- if (reg0 == 0)
700+ if (reg0 == 0){
845701 jitCompA0001_movRxxEax(&w, src[1]);
702+ }
846703 break;
847704 }
848705 #if (jitCompA0001_USE_R3F_INCDEC != 0)
849706 if ((*src == 0x14 && w.r3f == 1) || (*src == 0x15 && w.r3f == -1)) {
850707 jitCompPutByte1(w.dst, 0x40 | reg0); /* INC(reg0); */
851- if (reg0 == 0)
708+ if (reg0 == 0){
852709 jitCompA0001_movRxxEax(&w, src[1]);
710+ }
853711 break;
854712 }
855713 if ((*src == 0x15 && w.r3f == 1) || (*src == 0x14 && w.r3f == -1)) {
856714 jitCompPutByte1(w.dst, 0x48 | reg0); /* DEC(reg0); */
857- if (reg0 == 0)
715+ if (reg0 == 0){
858716 jitCompA0001_movRxxEax(&w, src[1]);
717+ }
859718 break;
860719 }
861720 #endif
@@ -864,21 +723,22 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
864723 if (*src != 0x16) {
865724 static unsigned char basic_op_table_im8[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 };
866725 jitCompPutByte3(w.dst, 0x83, basic_op_table_im8[*src - 0x10] | reg0, w.r3f & 0xff);
867- }
868- else {
726+ } else{
869727 jitCompPutByte3(w.dst, 0x6b, 0xc0 | reg0 << 3 | reg0, w.r3f & 0xff);
870728 }
871- if (reg0 == 0)
729+ if (reg0 == 0){
872730 jitCompA0001_movRxxEax(&w, src[1]);
731+ }
873732 break;
874733 }
875734 #endif
876- if (reg0 == 0 /* EAX */) {
735+ if (reg0 == IA32_REG0_EAX) {
877736 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+ }
879740 jitCompPutByte1(w.dst, basic_op_table_im32_eax[*src - 0x10]);
880- }
881- else {
741+ } else{
882742 if (*src != 0x16) {
883743 static unsigned char basic_op_table_im32_reg[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 };
884744 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
887747 jitCompPutByte2(w.dst, 0x69, 0xc0 | reg0 << 3 | reg0);
888748 }
889749 }
890- jitCompPutImm32(&w, w.r3f);
891- if (reg0 == 0)
750+ jitCompPutImm32(w.dst, w.r3f);
751+ if (reg0 == 0){
892752 jitCompA0001_movRxxEax(&w, src[1]);
753+ }
893754 break;
894755 }
895756 #endif
896757 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+ }
898761 if (*src != 0x16) {
899762 if (reg1 >= 0) {
900763 static unsigned char basic_op_table_rr[] = { 0x09, 0x31, 0x21, 0, 0x01, 0x29 }; /* op(reg,reg); */
901764 jitCompPutByte2(w.dst, basic_op_table_rr[*src - 0x10], 0xc0 | reg1 << 3 | reg0);
902- }
903- else {
765+ } else{
904766 static unsigned char basic_op_table_rm[] = { 0x0b, 0x33, 0x23, 0, 0x03, 0x2b, 0xaf }; /* op(reg,mem); */
905767 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);
907769 }
908- }
909- else {
770+ } else{
910771 if (reg1 >= 0) {
911772 jitCompPutByte3(w.dst, 0x0f, 0xaf, 0xc0 | reg0 << 3 | reg1);
912- }
913- else {
773+ } else{
914774 jitCompPutByte2(w.dst, 0x0f, 0xaf);
915- jitCompA0001_85DispN(&w, src[3] * 4, reg0);
775+ jitCompPutModRM_Disp_BaseEBP(&w, src[3] * 4, reg0);
916776 }
917777 }
918778 }
919- if (reg0 == 0)
779+ if (reg0 == 0){
920780 jitCompA0001_movRxxEax(&w, src[1]);
781+ }
921782 break;
922783
923784 case 0x18: /* SHL */
924785 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+ }
927792 #if (jitCompA0001_USE_R3F_IMM32 != 0)
928793 if (src[3] == 0x3f) {
929- reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
794+ reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
930795 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{
935802 if (reg0 != reg1) {
936803 jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
937804 }
938805 }
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){
942815 jitCompA0001_movRxxEax(&w, src[1]);
816+ }
943817 cmp0reg = src[1];
944818 cmp0lev = 1;
945819 break;
946820 }
947821 #endif
948822 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+?]); */
950824 #if (jitCompA0001_USE_R3F_IMM32 != 0)
951825 if (src[2] == 0x3f) {
952826 jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
953- jitCompPutImm32(&w, w.r3f);
954- }
955- else {
827+ jitCompPutImm32(w.dst, w.r3f);
828+ } else{
956829 jitCompA0001_movEaxRxx(&w, src[2]);
957830 }
958831 #else
959832 jitCompA0001_movEaxRxx(&w, src[2]);
960833 #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+ }
963842 jitCompA0001_movRxxEax(&w, src[1]);
964843 jitCompA000_loadRegCacheAll(&w); // 手抜き.
965844 cmp0reg = src[1];
@@ -968,41 +847,45 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
968847
969848 case 0x1a: /* DIV */
970849 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+ }
974853 jitCompA000_storeRegCacheAll(&w); // 手抜き.
975854 #if (jitCompA0001_USE_R3F_IMM32 != 0)
976855 if (src[3] == 0x3f) {
977856 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+?]); */
982860 }
983861 if (src[2] == 0x3f) {
984862 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+?]); */
989866 }
990867 #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+?]); */
993870 #endif
994871 jitCompPutByte1(w.dst, 0x99); /* CDQ(); */
995872 /* ECXがゼロではないことを確認すべき */
996873 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+ }
999880 jitCompA000_loadRegCacheAll(&w); // 手抜き.
1000881 cmp0reg = -1;
1001882 break;
1002883
1003884 case 0x1c: /* PLMT0 */
1004885 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+ }
1006889 if (level < JITC_LV_FASTEST) {
1007890 cmp0reg = -1;
1008891 if (level < JITC_LV_FASTER) {
@@ -1010,39 +893,42 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
1010893 // plsとliveSignが一致していることを確認.
1011894
1012895 // preg1はp0 <= p <= p1 を満たしているか?.
1013- // 新しいp0/p1は古いp0〜p1に適合しているか?.
896+ // 新しいp0/p1は古いp0?p1に適合しているか?.
1014897
1015898 }
1016899 }
1017900
1018901 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+ }
1021908 if (src[1] != 0x3f) {
1022909 /* src[2] == 0xff の場合に対応できてない */
1023910 jitCompA000_storePRegCacheAll(&w); // 手抜き.
1024911 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); */
1027914 }
1028915 jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1029- }
1030- else {
916+ } else {
1031917 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 */
1033919 jitCompPutByte3(w.dst, 0x83, 0xf8, 0); /* CMP(EAX, 0); */
1034920 jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */
1035- jitCompPutImm32(&w, errfnc - (w.dst + 4));
921+ jitCompPutImm32(w.dst, errfnc - (w.dst + 4));
1036922 /* セキュリティチェックが足りてない!(aliveとか) */
1037923 }
1038- reg0 = 0; /* EAX */
924+ reg0 = IA32_REG0_EAX;
1039925 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+?]); */
1041927 if (level < JITC_LV_FASTER) {
1042928 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 */
1044930 jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */
1045- jitCompPutImm32(&w, errfnc - (w.dst + 4));
931+ jitCompPutImm32(w.dst, errfnc - (w.dst + 4));
1046932 }
1047933 jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */
1048934 }
@@ -1050,20 +936,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
1050936
1051937 case 0x1f: /* PCST */
1052938 if (jitCompGetImm32(src + 2) == 0) {
1053- if (level < JITC_LV_FASTER)
939+ if (level < JITC_LV_FASTER){
1054940 jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 7), 2);
941+ }
1055942 jitCompA000_storePRegCacheAll(&w); // 手抜き.
1056943 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+?]); */
1058945 if (i == 4) {
1059946 jitCompPutByte1(w.dst, 0x0d); /* OR(EAX, ?); */
1060- jitCompPutImm32(&w, 0x80000000);
947+ jitCompPutImm32(w.dst, 0x80000000);
1061948 }
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); */
1063950 }
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); */
1067953 jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1068954 cmp0reg = -1;
1069955 break;
@@ -1071,20 +957,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
1071957 if (jitCompGetImm32(src + 7) == 0) {
1072958 jitCompA000_storePRegCacheAll(&w); // 手抜き.
1073959 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+?]); */
1075961 if (i == 4) {
1076962 jitCompPutByte1(w.dst, 0x25); /* AND(EAX, ?); */
1077- jitCompPutImm32(&w, 0x7fffffff);
963+ jitCompPutImm32(w.dst, 0x7fffffff);
1078964 }
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); */
1080966 }
1081967 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+?]); */
1083969 jitCompPutByte1(w.dst, 0x3d); /* CMP(EAX, ?); */
1084- jitCompPutImm32(&w, debugInfo1);
970+ jitCompPutImm32(w.dst, debugInfo1);
1085971 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) */
1088974 }
1089975 jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1090976 cmp0reg = -1;
@@ -1101,13 +987,17 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
1101987 case 0x25: /* CMPG */
1102988 case 0x26: /* TSTZ */
1103989 case 0x27: /* TSTNZ */
1104- reg0 = jitCompA000_selectRegCache(src[2], 0 /* EAX */);
990+ reg0 = jitCompA000_selectRegCache(src[2], IA32_REG0_EAX);
1105991 reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
1106992 if (src[1] == 0x3f) {
1107993 /* 特殊構文チェック */
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+ }
1109998 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;
11111001 }
11121002 }
11131003 if (reg0 == 0)
@@ -1118,10 +1008,12 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
11181008 if ((*src <= 0x25 && w.r3f == 0) || (*src >= 0x26 && w.r3f == -1)) {
11191009 i = 0;
11201010 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)){
11221012 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)){
11241015 i = 1;
1016+ }
11251017 }
11261018 if (i == 0) {
11271019 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
11381030 }
11391031 #endif
11401032 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+ }
11431039 }
11441040 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+ }
11471047 }
1148- jitCompPutImm32(&w, w.r3f);
1048+ jitCompPutImm32(w.dst, w.r3f);
11491049 goto cmpcc1;
11501050 }
11511051 #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;
11561054 }
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);
11611070 }
11621071 cmpcc1:
1163- if (w.err != 0) goto err_w;
1072+ if (w.err != 0){
1073+ goto err_w;
1074+ }
11641075 static unsigned char cmpcc_table0[] = {
11651076 0x04, 0x05, 0x0c, 0x0d, 0x0e, 0x0f, 0x04, 0x05, /* CMPcc, TSTcc */
11661077 0x04, 0x05, 0x02, 0x03, 0x06, 0x07 /* PCMPcc */
@@ -1172,13 +1083,17 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
11721083 src += 6;
11731084 i = jitCompGetLabelNum(&w, src + 2);
11741085 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+ }
11761090 // if (label[i].typ != 1) { w.err = JITC_ERR_LABELTYP; goto err_w; }
11771091 }
11781092 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)){
11801094 j = label[i].p - (w.dst + 4);
1181- jitCompPutImm32(&w, j);
1095+ }
1096+ jitCompPutImm32(w.dst, j);
11821097 #if (jitCompA0001_OPTIMIZE_JMP != 0)
11831098 if (-128 - 4 <= j && j < 0) {
11841099 j += 4;
@@ -1187,17 +1102,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
11871102 }
11881103 #endif
11891104 src += 6;
1190- if (w.err != 0) goto err_w;
1105+ if (w.err != 0){
1106+ goto err_w;
1107+ }
11911108 continue;
11921109 }
11931110 #endif
11941111 /* 一般的なJITC */
1195- reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
1112+ reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
11961113 jitCompPutByte3(w.dst, 0x0f, 0x90 | cmpcc_table0[*src - 0x20], 0xc0 | reg0); /* SETcc(BYTE(reg0)); */
11971114 jitCompPutByte3(w.dst, 0x0f, 0xb6, 0xc0 | reg0 << 3 | reg0); /* MOVZX(reg0, BYTE(reg0)); */
11981115 jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */
1199- if (reg0 == 0)
1116+ if (reg0 == 0){
12001117 jitCompA0001_movRxxEax(&w, src[1]);
1118+ }
12011119 cmp0reg = src[2];
12021120 cmp0lev = 1;
12031121 break;
@@ -1210,21 +1128,27 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
12101128 case 0x2d: /* PCMPG */
12111129 if (src[1] == 0x3f) {
12121130 /* 特殊構文チェック */
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+ }
12141135 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;
12161138 }
12171139 }
1218- if (src[2] >= 0x40) w.err = JITC_ERR_PREGNUM;
1140+ if (src[2] >= 0x40) {
1141+ w.err = JITC_ERR_PREGNUM;
1142+ }
12191143 jitCompA000_storePRegCacheAll(&w); // 手抜き.
1220- if (src[3] != 0xff)
1144+ if (src[3] != 0xff){
12211145 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+?]); */
12231148 if (src[3] != 0xff) {
12241149 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{
12281152 /* ヌルポインタとの比較はこれでいいのか?たぶんよくない */
12291153 jitCompPutByte3(w.dst, 0x83, 0xf8, 0x00); /* CMP(EAX, 0); */
12301154 }
@@ -1237,42 +1161,84 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
12371161 case 0x33: /* mfree(old:F7) */
12381162 jitCompA000_storeRegCacheAll(&w); // 手抜き.
12391163 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+
12511187 jitCompA000_loadRegCacheAll(&w); // 手抜き.
12521188 jitCompA000_loadPRegCacheAll(&w); // 手抜き.
12531189 cmp0reg = -1;
12541190 break;
12551191
12561192 case 0x34: /* data (暫定) */
1193+ // 0 1234 5678 9
1194+ // 34 typ32 len32 data...
1195+ // len32 is NOT byte size!
1196+
12571197 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+ //直前のラベルタイプを設定
12611208 label[lastlabel].typ = k;
1209+ }
12621210 if (k != 1) {
12631211 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+ }
12651216 }
1217+ // jはlen32
12661218 j = jitCompGetImm32(&src[5]);
12671219 oldsrc = src;
12681220 src += 9;
1221+
1222+ // srcはdata本体を指す
12691223 if (k != 1) {
1224+ // 一般データ
12701225 bitCount = 7;
12711226 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+ }
12741239 tmpData = 0;
12751240 for (k = 0; k < dataWidth; k++) {
1241+ // dataWidthビットごとに切り出してtmpDataに入れる
12761242 tmpData = tmpData << 1 | ((*src >> bitCount) & 1);
12771243 bitCount--;
12781244 if (bitCount < 0) {
@@ -1281,53 +1247,78 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
12811247 }
12821248 }
12831249 if ((i & 1) == 0 && dataWidth <= 31 && (tmpData >> (dataWidth - 1)) != 0) {
1250+ // 符号あり型で、かつtmpDataの符号ビットが1なので、マイナスにする
12841251 tmpData -= 1 << dataWidth;
12851252 }
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+ }
12891265 j--;
12901266 }
1291- }
1292- else {
1267+ } else{
1268+ // VPtr型
12931269 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+ }
12961282 i = jitCompGetImm32(src);
12971283 src += 4;
12981284 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+ }
13001291 }
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);
13091300 j--;
13101301 }
13111302 }
1312- if (lastlabel >= 0 && label[lastlabel].p1 < w.dst)
1303+ if (lastlabel >= 0 && label[lastlabel].p1 < w.dst){
13131304 label[lastlabel].p1 = w.dst;
1305+ }
13141306 continue;
13151307
13161308 case 0x3c: /* ENTER */
13171309 jitCompA000_storeRegCacheAll(&w); // 手抜き.
13181310 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);
13311322 jitCompA000_loadRegCacheAll(&w); // 手抜き.
13321323 jitCompA000_loadPRegCacheAll(&w); // 手抜き.
13331324 cmp0reg = -1;
@@ -1336,46 +1327,43 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
13361327 case 0x3d: /* LEAVE */
13371328 jitCompA000_storeRegCacheAll(&w); // 手抜き.
13381329 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);
13511341 jitCompA000_loadRegCacheAll(&w); // 手抜き.
13521342 jitCompA000_loadPRegCacheAll(&w); // 手抜き.
13531343 cmp0reg = -1;
13541344 break;
13551345
13561346 case 0xfe: /* remark */
1357- if (src[1] == 0x01 && src[2] == 0x00) { // DBGINFO1
1347+ if (src[1] == 0x01 && src[2] == 0x00) {
1348+ // DBGINFO1
13581349 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);
13621352 }
13631353 }
1364- if (src[1] == 0x01 && src[2] == 0x03) { // DBGINFO1CLR
1354+ if (src[1] == 0x01 && src[2] == 0x03) {
1355+ // DBGINFO1CLR
13651356 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);
13691359 }
13701360 }
1371- if (src[1] == 0x05 && src[2] == 0x00) { // DBGINFO0
1361+ if (src[1] == 0x05 && src[2] == 0x00) {
1362+ // DBGINFO0
13721363 if (level <= JITC_LV_SLOWEST) {
13731364 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);
13791367 }
13801368 }
13811369 break;
@@ -1384,9 +1372,18 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
13841372 w.err = JITC_ERR_OPECODE;
13851373 goto err_w;
13861374 }
1387- if (w.err != 0) goto err_w;
1375+ if (w.err != 0){
1376+ goto err_w;
1377+ }
13881378 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+
13901387 src += jitCompCmdLen(src);
13911388 }
13921389 if (enter0 != NULL) {
@@ -1399,16 +1396,18 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
13991396 if ((flags & JITC_NOSTARTUP) == 0) {
14001397 jitCompA000_storeRegCacheAll(&w);
14011398 jitCompA000_storePRegCacheAll(&w);
1402- jitCompPutByte1(w.dst, 0x61); /* POPAD(); */
1399+ jitCompPutOp_POPAD(w.dst);
14031400 }
1404- if ((flags & JITC_PHASE1) != 0)
1401+ if ((flags & JITC_PHASE1) != 0){
14051402 return w.dst - dst00;
1403+ }
14061404 return 0;
14071405
14081406 err_w:
14091407 if ((w.err & JITC_ERR_PHASE0ONLY) != 0) {
1410- if ((flags & JITC_PHASE1) == 0)
1408+ if ((flags & JITC_PHASE1) == 0){
14111409 w.err &= ~JITC_ERR_PHASE0ONLY;
1410+ }
14121411 }
14131412 if (w.err == (JITC_ERR_MASK & JITC_ERR_REGNUM)) errmsg = "reg-number error";
14141413 if (w.err == (JITC_ERR_MASK & JITC_ERR_DST1)) errmsg = "dst1 error";
@@ -1444,56 +1443,76 @@ err_w:
14441443
14451444 unsigned char *jitCompCallFunc(unsigned char *dst, void *func)
14461445 {
1446+ //この関数の中では結局w->dstしか参照していない
14471447 struct JitCompWork w;
14481448 w.dst = dst;
14491449 jitCompA000_storeRegCacheAll(&w);
14501450 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);
14561454
1457- //この関数の中では結局w->dstしか参照していない
1458- jitCompPutImm32(&w, j);
1455+ int j = ((unsigned char *)func) - (w.dst + 1 + 4);
1456+ jitCompPutOp_CALL_Relative(w.dst, j);
14591457
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);
14631461 jitCompA000_loadRegCacheAll(&w);
14641462 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+
14661465 jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */
14671466 return w.dst;
14681467 }
14691468
1470-// dst に errHndl() を呼ぶコードを置く。このコードの番地はerrfncにセットされる。
14711469 unsigned char *jitCompInit(unsigned char *dst)
14721470 {
14731471 errfnc = dst;
14741472 return jitCompCallFunc(dst, &errHndl);
14751473 }
14761474
1475+void jitcRunBinary(void (*bin)(char *), HOSECPU_RuntimeEnvironment *env)
1476+{
1477+ (*bin)(((char *)env) + jitCompA0001_EBP128); /* サイズを節約するためにEBPをjitCompA0001_EBP128バイトずらす */
1478+ return;
1479+}
1480+
14771481 void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0)
14781482 {
14791483 HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
14801484 int i, *pi;
14811485 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++){
14851493 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;
14921509 *pi = opt << 16 | r1 << 8 | p1;
1493- for (i = 0; i < lenR; i++)
1510+ for (i = 0; i < lenR; i++){
14941511 r->ireg[r0 + i] = r->ireg[0x30 + i];
1495- for (i = 0; i < lenP; i++)
1512+ }
1513+ for (i = 0; i < lenP; i++){
14961514 r->preg[p0 + i] = r->preg[0x31 + i];
1515+ }
14971516 return;
14981517 }
14991518
@@ -1504,13 +1523,20 @@ void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int
15041523 r->junkStack -= 4;
15051524 r->junkStack -= 32;
15061525 HOSECPU_PointerRegisterEntry *pp = (void *)r->junkStack;
1507- r->preg[0x30] = *pp;
1526+
1527+ //r->preg[0x30] = *pp;
1528+ PRegCopy(&r->preg[0x30], pp);
1529+ //
15081530 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+ }
15111536 r->junkStack -= r1 * 4; int *pi = (void *)r->junkStack;
1512- for (i = 0; i < r1; i++)
1537+ for (i = 0; i < r1; i++){
15131538 r->ireg[i] = pi[i];
1539+ }
15141540 return;
15151541 }
15161542
@@ -1518,10 +1544,13 @@ void funcf4(char *ebp, int pxx, int typ, int len)
15181544 {
15191545 HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
15201546 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){
15221548 (*(r->errHndl))(r);
1549+ }
15231550 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+ }
15251554 r->junkStack += width * r->ireg[len];
15261555 r->preg[pxx].p = p;
15271556 r->preg[pxx].typ = r->ireg[typ];
@@ -1533,8 +1562,9 @@ void funcf4(char *ebp, int pxx, int typ, int len)
15331562 if (r->ireg[typ] == 1) {
15341563 int i, i1 = (width * r->ireg[len]) >> 2;
15351564 pi = p;
1536- for (i = 0; i < i1; i++)
1565+ for (i = 0; i < i1; i++){
15371566 pi[i] = 0;
1567+ }
15381568 }
15391569 return;
15401570 }
@@ -1558,8 +1588,9 @@ void funcf6(char *ebp, int pxx, int typ, int len)
15581588 {
15591589 HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
15601590 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){
15621592 (*(r->errHndl))(r);
1593+ }
15631594 void *p = malloc(width * r->ireg[len]);
15641595 r->preg[pxx].p = p;
15651596 r->preg[pxx].typ = r->ireg[typ];
@@ -1568,10 +1599,12 @@ void funcf6(char *ebp, int pxx, int typ, int len)
15681599 if (r->ireg[typ] == 1) {
15691600 int i, i1 = (width * r->ireg[len]) >> 2, *pi;
15701601 pi = p;
1571- for (i = 0; i < i1; i++)
1602+ for (i = 0; i < i1; i++){
15721603 pi[i] = 0;
1573- for (i = 1; i < i1; i += 8)
1604+ }
1605+ for (i = 1; i < i1; i += 8){
15741606 pi[i] |= -1;
1607+ }
15751608 }
15761609 return;
15771610 }
@@ -1605,26 +1638,34 @@ void errHndl(HOSECPU_RuntimeEnvironment *r)
16051638 int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label)
16061639 {
16071640 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) を確認
16091645 return 1;
1646+ }
1647+
1648+ jitCompPutOp_PUSH_GReg(q, IA32_REG5_EBP);
16101649
1611- *q++ = 0x55; /* PUSH(EBP); */
16121650 *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */
16131651
1614- int i;
1615- for (i = 0; i < JITC_MAXLABELS; i++)
1652+ for (i = 0; i < JITC_MAXLABELS; i++){
16161653 label[i].opt = 0;
1654+ }
16171655
16181656 // 以下のjitCompile()呼び出しでは第二引数をq1-2にした方がよいのではないか?
16191657 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+ }
16211661 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+ }
16231665 q += i;
16241666
1625- *q++ = 0x5d; /* POP(EBP); */
1667+ jitCompPutOp_POP_GReg(q, IA32_REG5_EBP);
16261668 *q++ = 0xc3; /* RET(); */
1627-
16281669 *qq = q;
16291670 return 0;
16301671 }
@@ -1637,35 +1678,51 @@ int dbgrGetRegNum(const char *p)
16371678 if (p[2] <= ' ') {
16381679 i = p[0] - '0';
16391680 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){
16431688 r = i << 4 | j;
1689+ }
16441690 }
16451691 return r;
16461692 }
16471693
16481694 void dbgrMain(HOSECPU_RuntimeEnvironment *r)
16491695 {
1650- if (r->dbgr == 0) return;
1696+ if (r->dbgr == 0){
1697+ return;
1698+ }
16511699 for (;;) {
16521700 char cmd[64], *p;
16531701 int i, j, k;
1702+
16541703 printf("\ndbgr>");
16551704 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+ }
16591714 if (cmd[0] == 'p' && cmd[1] <= ' ' && cmd[1] != '\0') {
16601715 p = &cmd[2];
1661- while (*p <= ' ' && *p != '\0') p++;
1716+ while (*p <= ' ' && *p != '\0'){
1717+ p++;
1718+ }
16621719 if (*p == 'R') {
16631720 i = dbgrGetRegNum(p + 1);
16641721 if (0 <= i && i <= 0x3f) {
16651722 printf("R%02X = 0x%08X = %d\n", i, r->ireg[i], r->ireg[i]);
1666- }
1667- else
1723+ } else{
16681724 puts("register name error");
1725+ }
16691726 continue;
16701727 }
16711728 if (*p == 'P') {
@@ -1686,7 +1743,9 @@ void dbgrMain(HOSECPU_RuntimeEnvironment *r)
16861743 printf("P%02X:\n type = %s(%04X), (origin-ptr) = 0x%08X\n", i, p, r->preg[i].typ, (unsigned int)(r->preg[i].p0));
16871744 if (r->preg[i].p != NULL && r->preg[i].p0 != NULL) {
16881745 j = jitCompA000_dataWidth(jitCompA000_convTyp(r->preg[i].typ)) >> 3;
1689- if (j <= 0) j = 1;
1746+ if (j <= 0){
1747+ j = 1;
1748+ }
16901749 k = (r->preg[i].p1 - r->preg[i].p0) / j;
16911750 printf(" size = 0x%08X = %d\n", k, k);
16921751 k = (r->preg[i].p - r->preg[i].p0) / j;
--- /dev/null
+++ b/jitcx86a.c
@@ -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
--- a/main.c
+++ b/main.c
@@ -1,9 +1,10 @@
1-#include "osecpu.h"
1+#include "osecpu.h"
22
33 int *keybuf, keybuf_r, keybuf_w, keybuf_c;
44 HOSECPU_Device_Window mainWindow;
55 //デバッグ用。プログラム中の随所で加算される変数
66 int di1_serial;
7+HOSECPU_RuntimeEnvironment *dbg_env;
78
89
910
@@ -22,44 +23,39 @@ void putKeybuf(int i)
2223
2324 int HeavyOSECPUMain(int argc, char **argv)
2425 {
26+ HOSECPU_RuntimeEnvironment env;
2527 FILE *fp;
26- unsigned char *jitbuf, *sysjit;
28+ unsigned char *jitbuf, *sysjit00, *sysjit;
2729 unsigned char *systmp0, *systmp1, *systmp2;
2830 unsigned char *opTbl;
2931 HOSECPU_LabelListTag *label;
3032 int tmpsiz, i;
3133 double tm0, tm1, tm2;
3234 HOSECPU_PointerControlTag *ptrCtrl;
35+ unsigned char *syslib;
3336 int argDebug = 0, stacksiz = 1;
3437 const char *cp;
35- HOSECPU_RuntimeEnvironment env;
3638 void(*jitfunc)(char *);
3739 unsigned char *jp;
3840
39- //Initialize mainWindow
41+ // For debug
42+ dbg_env = &env;
43+
44+ // Initialize mainWindow
4045 mainWindow.vram = NULL;
4146 mainWindow.xsize = 0;
4247 mainWindow.ysize = 0;
4348 di1_serial = 0;
4449
45- //実行環境初期化
50+ // 実行環境初期化
4651 env.mainArgc = argc;
4752 env.mainArgv = (const char **)argv;
4853 env.appBin = malloc(APPSIZ1);
4954 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で */
6056 // syslib.oseのjitc結果を格納する領域を確保。
61- sysjit = mallocRWE(SJITSIZ1 + 256); // jitCompInit() のための領域を多めにとる
62-
57+ sysjit00 = mallocRWE(SYSJITSIZ1);
58+ sysjit = sysjit00;
6359 // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス
6460 // sysjit: 現在のjitc書き込み位置
6561 // sysjit00: jitc結果の先頭
@@ -82,30 +78,19 @@ int HeavyOSECPUMain(int argc, char **argv)
8278 ptrCtrl[0].size = -2;
8379
8480 /* 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+
9483 sysjit = jitCompInit(sysjit);
95- unsigned char const * const sysjit00 = sysjit;
96-
84+ sysjit00 = sysjit;
9785 // 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);
9987 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);
10589 return 1;
10690 }
10791
108- di1_serial = 1;
92+ // エラー時にデバッグ用に表示する変数を加算
93+ di1_serial++;
10994
11095 /* アプリバイナリの読み込み */
11196 LoadAppBin(&env);
@@ -113,7 +98,7 @@ int HeavyOSECPUMain(int argc, char **argv)
11398 /* クロック初期化 */
11499 tm0 = clock() / (double)CLOCKS_PER_SEC;
115100
116- if (env.appBin[2] == 0xf0) { // 最初の2byteはOSECPUのシグネチャである
101+ if (env.appBin[2] == 0xf0) {
117102 // tek5圧縮がかかっている
118103 #if (USE_TEK5 != 0)
119104 env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0);
@@ -125,8 +110,6 @@ int HeavyOSECPUMain(int argc, char **argv)
125110 fputs("unsupported-format(tek5)\n", stderr);
126111 return 1;
127112 }
128-
129-
130113 }
131114 //デバッグモード指定
132115 cp = searchArg(argc, (const char **)argv, "debug:", 0);
@@ -144,21 +127,21 @@ int HeavyOSECPUMain(int argc, char **argv)
144127
145128 /* フロントエンドコードをバックエンドコードに変換する */
146129 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;
156139 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;
160143 jitfunc = (void *)sysjit00;
161- (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */
144+ jitcRunBinary(jitfunc, &env);
162145 if (env.ireg[0] != 0) {
163146 jp = env.preg[2].p - 1;
164147 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)
247230 /* JITコード実行 */
248231 jitfunc = (void *)jitbuf;
249232 if (setjmp(env.setjmpEnv) == 0){
250- (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */
233+ jitcRunBinary(jitfunc, &env);
251234 }
252235 if (env.autoSleep != 0) {
253236 if (mainWindow.vram != NULL){
@@ -276,22 +259,20 @@ int HeavyOSECPUMain(int argc, char **argv)
276259 return env.appReturnCode;
277260 }
278261
279-/*
280- * argv0 : osecpu.exe の存在するパス
281- * tmpWprkMemory : SYSTMP0SIZ分確保されている
282- */
283262 unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory)
284263 {
264+ unsigned char *syslib;
285265 FILE *fp;
286266 unsigned char *up;
287267 int appsize;
288268
289269 /* syslibの読み込み */
290- unsigned char *syslib = malloc(SYSLIBSIZ1);
270+ syslib = malloc(SYSLIBSIZ1);
291271 fp = fopen(SYSLIB_OSE, "rb");
292272 if (fp == NULL) {
293- strcpy((char *)syslib, argv0);
294- up = syslib;
273+ syslib[0] = '/';
274+ strcpy((char *)syslib + 1, argv0);
275+ up = syslib + 1;
295276 while (*up != '\0'){
296277 up++;
297278 }
@@ -300,7 +281,7 @@ unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory)
300281 }
301282 up++;
302283 strcpy((char *)up, SYSLIB_OSE);
303- fp = fopen((char *)syslib, "rb");
284+ fp = fopen((char *)syslib + 1, "rb");
304285 }
305286 if (fp == NULL) {
306287 fputs("syslib-file fopen error.\n", stderr);
@@ -319,7 +300,10 @@ unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory)
319300 syslib[0] = 0x05;
320301 syslib[1] = 0x1b;
321302 }
322-
303+
304+ fp = fopen("syslib_dbg.ose", "wb");
305+ fwrite(syslib, 1, SYSLIBSIZ1, fp);
306+ fclose(fp);
323307 return syslib;
324308 }
325309
@@ -328,6 +312,10 @@ void LoadAppBin(HOSECPU_RuntimeEnvironment *env)
328312 FILE *fp;
329313 const char *fileName;
330314 /* アプリバイナリの読み込み */
315+ if (env->mainArgc <= 1) {
316+ //アプリ名未指定なので何事もなく終了
317+ exit(EXIT_SUCCESS);
318+ }
331319 fileName = env->mainArgv[1];
332320 //アプリ名先頭に:n:をつけることでレベルnでの実行が可能?
333321 if (fileName[0] == ':' && fileName[2] == ':') {
--- a/osecpu.h
+++ b/osecpu.h
@@ -1,4 +1,4 @@
1-#ifndef _HDLOAD_OSECPU
1+#ifndef _HDLOAD_OSECPU
22 #define _HDLOAD_OSECPU 1
33
44 /* Visual Studio で fopen()やsprintf() などの古い関数を使用する時に出る警告を抑止する*/
@@ -67,8 +67,8 @@
6767 #define PTRCTRLSIZ 4096
6868
6969 #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 */
7272 #define SYSLIBSIZ1 1 * 1024 * 1024 /* 1MB for now */
7373 #define SYSTMP0SIZ 1 * 1024 * 1024 /* 1MB for now */
7474 #define SYSTMP1SIZ 2 * 1024 * 1024 /* 1MB for now */
@@ -100,11 +100,11 @@ struct PtrCtrl {
100100 unsigned char *p0;
101101 };
102102
103-// Ptr
104103 typedef struct Ptr HOSECPU_PointerRegisterEntry;
105-struct Ptr { /* 32バイト(=256bit!) */
104+struct Ptr {
105+ // 32バイト(=256bit!)
106106 unsigned char *p;
107-
107+
108108 /* static char *typName[] = {
109109 "T_CODE", "T_VPTR", "T_SINT8", "T_UINT8",
110110 "T_SINT16", "T_UINT16", "T_SINT32", "T_UINT32",
@@ -120,7 +120,6 @@ struct Ptr { /* 32バイト(=256bit!) */
120120 int flags, dummy; /* read/writeなど */
121121 };
122122
123-// LabelTable
124123 typedef struct LabelTable HOSECPU_LabelListTag;
125124 struct LabelTable {
126125 unsigned char *p, *p1;
@@ -135,36 +134,38 @@ struct LabelTable {
135134 int typ;
136135 };
137136
138-// Device_Window
139137 typedef struct Device_Window HOSECPU_Device_Window;
140138 struct Device_Window {
141- int *vram; // 初期値 : NULL
142- int xsize, ysize; // 初期値 : 0, 0
139+ int *vram;
140+ int xsize, ysize;
143141 };
144142
145-// Regs + env
146143 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
150152 //
151- int debugInfo0, debugInfo1, dmy[2]; /* 2304 */
152- HOSECPU_PointerControlTag *ptrCtrl; /* 2320 */
153+ HOSECPU_PointerControlTag *ptrCtrl; // 2320
153154 char winClosed, autoSleep;
154155 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+
165166 /* for-junkApi */
166167 unsigned char *buf0, *buf1, *junkStack, lastConsoleChar, *junkStack1;
167-
168+
168169 HOSECPU_LabelListTag *label;
169170 int maxLabels;
170171 unsigned char *jitbuf, *jitbuf1;
@@ -205,11 +206,14 @@ const char *searchArg(int argc, const char **argv, const char *tag, int i); //
205206 void devFunc(HOSECPU_RuntimeEnvironment *r); // junkApiを処理する関数
206207
207208 // @jitc.c
209+void errorHandler(HOSECPU_RuntimeEnvironment *r);
210+void PRegCopy(HOSECPU_PointerRegisterEntry *dst, HOSECPU_PointerRegisterEntry *src);
211+// @jitcx86.c
208212 int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label);
209213 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);
210214 unsigned char *jitCompCallFunc(unsigned char *dst, void *func);
211215 unsigned char *jitCompInit(unsigned char *dst);
212-void errorHandler(HOSECPU_RuntimeEnvironment *r);
216+void jitcRunBinary(void (*bin)(char *), HOSECPU_RuntimeEnvironment *env);
213217
214218 // @randmt.c
215219 void randStatInit(unsigned int seed);
@@ -237,3 +241,4 @@ int tek5Decomp(UCHAR *buf, UCHAR *buf1, UCHAR *tmp);
237241
238242 #endif
239243
244+>>>>>>> 4d5d6fa61ff576ba035ee4bd882e8476f2ceeb2b
Show on old repository browser