コミットメタ情報

リビジョン41b36c0f658bc352b53e1a3cbca9005a950eb18f (tree)
日時2014-03-14 23:58:09
作者hikarupsp <hikarupsp@user...>
コミッターhikarupsp

ログメッセージ

JITC関連の即値を定数化

変更サマリ

差分

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