• R/O
  • HTTP
  • SSH
  • HTTPS

HeavyOSECPU: Commit


Commit MetaInfo

Revisióne2cd1768d592faab2517f8f8970cd6ba3298ae5c (tree)
Tiempo2014-03-15 15:32:33
Autorhikarupsp <hikarupsp@user...>
Commiterhikarupsp

Log Message

jitcx86.cを分割した。

Cambiar Resumen

Diferencia incremental

--- a/jitc.h
+++ b/jitc.h
@@ -2,6 +2,8 @@
22 #ifndef HeavyOSECPU_jitc_h
33 #define HeavyOSECPU_jitc_h
44
5+
6+
57 // Error flags
68 #define JITC_ERR_MASK 255
79 #define JITC_ERR_PHASE0ONLY 256
@@ -52,12 +54,15 @@ int jitCompCmdLen(const unsigned char *src);
5254 #define envOffset_DBGINFO1 (2304 + 4)
5355 //
5456 #define jitCompPutImm32(p, i) jitCompPutByte4(p, ((i) & 0xff), (((i) >> 8) & 0xff), (((i) >> 16) & 0xff), (((i) >> 24) & 0xff))
57+#define jitCompPutOp_XOR_GReg_GReg(p, d, s) jitCompPutByte2(w.dst, 0x31, 0xc0 | (s) << 3 | (d));
58+#define jitCompPutOp_MOV_GReg_Imm32(p, dReg, i) jitCompPutByte1(p, 0xb8 | dReg); jitCompPutImm32(p, i); /* MOV(reg0, ?); == [1011 1 reg] imm32 */
5559 #define jitCompPutOp_PUSHAD(p) jitCompPutByte1(p, 0x60);
5660 #define jitCompPutOp_POPAD(p) jitCompPutByte1(p, 0x61);
5761 #define jitCompPutOp_PUSH_GReg(p, reg) jitCompPutByte1(p, 0x50 | (reg));
5862 #define jitCompPutOp_POP_GReg(p, reg) jitCompPutByte1(p, 0x58 | (reg));
5963 #define jitCompPutOp_CALL_Relative(p, diff) jitCompPutByte1(w.dst, 0xe8); jitCompPutImm32(&w, j);
60-
64+//
65+#define jitCompPutOp_MOV_EAX_ZERO(p) jitCompPutOp_XOR_GReg_GReg(p, IA32_REG0_EAX, IA32_REG0_EAX);
6166
6267 // Optimization settings
6368 // 他のCPUへ移植する人へ:
@@ -81,6 +86,7 @@ struct JitCompWork {
8186 char prefix; //CND命令の値を記録(初期値=0)
8287 };
8388
89+// @jitcx86a.c
8490 int jitCompGetImm32(const unsigned char *src);
8591 int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src);
8692 void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n);
@@ -105,6 +111,9 @@ int jitCompA000_dataWidth(int t);
105111 void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac);
106112 void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac);
107113 void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx);
114+
115+// @jitcx86.c
116+extern unsigned char *errfnc;
108117 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);
109118 unsigned char *jitCompCallFunc(unsigned char *dst, void *func);
110119 unsigned char *jitCompInit(unsigned char *dst);
@@ -124,14 +133,6 @@ void dbgrMain(HOSECPU_RuntimeEnvironment *r);
124133
125134
126135
127-
128-
129-
130-
131-
132-
133-
134-
135136 #endif
136137
137138 #endif
--- a/jitcx86.c
+++ b/jitcx86.c
@@ -5,257 +5,6 @@
55 //
66 // for x86-32bit
77 //
8-int jitCompGetImm32(const unsigned char *src)
9-{
10- return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
11-}
12-
13-int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src)
14-{
15- int i = jitCompGetImm32(src);
16- if (i < 0 || i >= w->maxLabels) {
17- w->err = JITC_ERR_LABELNUM;
18- i = 0;
19- }
20- return i;
21-}
22-
23-void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n)
24-{
25- disp -= jitCompA0001_EBP128;
26- if (-128 <= disp && disp <= 127) {
27- jitCompPutByte2(w->dst, 0x45 | (n << 3), disp & 0xff);
28- } else {
29- // 10 + reg + 101 + disp
30- jitCompPutByte1(w->dst, 0x85 | (n << 3));
31- jitCompPutImm32(w->dst, disp);
32- }
33- return;
34-}
35-
36-void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32)
37-{
38- // MOV Ev, Gv
39- // MOV + ModR/M(2Mod + 3Reg + 3R/M)
40- jitCompPutByte1(w->dst, 0x89); /* 1000 1001 MOV(mem, reg32); */
41- jitCompA0001_85DispN(w, disp, reg32);
42- return;
43-}
44-
45-void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp)
46-{
47- jitCompPutByte1(w->dst, 0x8b); /* MOV(reg32, mem); */
48- jitCompA0001_85DispN(w, disp, reg32);
49- return;
50-}
51-
52-void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)
53-{
54-#if (jitCompA0001_USE_R3F_IMM32 != 0)
55- if (rxx == 0x3f) {
56- jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */
57- jitCompPutImm32(w->dst, w->r3f);
58- return;
59- }
60-#endif
61- if (rxx >= 0x40 || rxx < 0){
62- w->err = JITC_ERR_REGNUM;
63- }
64- jitCompA0001_movReg32EbpDisp(w, IA32_REG0_EAX, rxx * 4); /* MOV(EAX, [EBP+?]); */
65- return;
66-}
67-
68-void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx)
69-{
70- if (rxx >= 0x40 || rxx < 0){
71- w->err = JITC_ERR_REGNUM;
72- }
73- jitCompA0001_movEbpDispReg32(w, rxx * 4, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
74- return;
75-}
76-
77-void jitCompA0001_fixPrefix(struct JitCompWork *w)
78-{
79- if (w->prefix != 0) {
80- if (w->dst - w->dst0 > 127){
81- w->err = JITC_ERR_REGNUM;
82- }
83- w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff);
84- }
85- return;
86-}
87-
88-void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1)
89-{
90- if (p0 >= 0x3f || p0 < 0){
91- w->err = JITC_ERR_PREGNUM;
92- }
93- if (p1 >= 0x3f || p1 < 0){
94- w->err = JITC_ERR_PREGNUM;
95- }
96- /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */
97- return;
98-}
99-
100-void jitCompA000_loadRegCacheAll(struct JitCompWork *w)
101-{
102- jitCompA0001_movReg32EbpDisp(w, 3 /* EBX */, 0 * 4); /* EBX = R00; */
103- jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */
104- jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */
105- return;
106-}
107-
108-void jitCompA000_storeRegCacheAll(struct JitCompWork *w)
109-{
110- jitCompA0001_movEbpDispReg32(w, 0 * 4, 3 /* EBX */); /* R00 = EBX; */
111- jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */
112- jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */
113- return;
114-}
115-
116-void jitCompA000_loadRegCacheEcx(struct JitCompWork *w)
117-{
118- jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */
119- return;
120-}
121-
122-void jitCompA000_storeRegCacheEcx(struct JitCompWork *w)
123-{
124- jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */
125- return;
126-}
127-
128-void jitCompA000_loadRegCacheEdx(struct JitCompWork *w)
129-{
130- jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */
131- return;
132-}
133-
134-void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)
135-{
136- jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */
137- return;
138-}
139-
140-int jitCompA000_selectRegCache(int rxx, int reg)
141-{
142- switch (rxx) {
143- case 0:
144- //EBX
145- reg = 3;
146- break;
147- case 1:
148- //ECX
149- reg = 1;
150- break;
151- case 2:
152- //EDX
153- reg = 2;
154- break;
155- }
156- return reg;
157-}
158-
159-void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)
160-{
161- // jitCompA0001_movReg32EbpDisp(w, 5 /* EBP */, 256 + 0 * 32 + 0); /* EBP = P00; */
162- jitCompA0001_movReg32EbpDisp(w, 6 /* ESI */, 256 + 1 * 32 + 0); /* ESI = P01; */
163- jitCompA0001_movReg32EbpDisp(w, 7 /* EDI */, 256 + 2 * 32 + 0); /* EDI = P02; */
164- return;
165-}
166-
167-void jitCompA000_storePRegCacheAll(struct JitCompWork *w)
168-{
169- // jitCompA0001_movEbpDispReg32(w, 256 + 0 * 32 + 0, 5 /* EBP */); /* P00 = EBP; */
170- jitCompA0001_movEbpDispReg32(w, 256 + 1 * 32 + 0, 6 /* ESI */); /* P01 = ESI; */
171- jitCompA0001_movEbpDispReg32(w, 256 + 2 * 32 + 0, 7 /* EDI */); /* P02 = EDI; */
172- return;
173-}
174-
175-int jitCompA000_selectPRegCache(int pxx, int reg)
176-{
177- // if (pxx == 0) reg = 5; /* EBP */
178- switch (pxx) {
179- case 1:
180- //ESI
181- reg = 6;
182- break;
183-
184- case 2:
185- //EDI
186- reg = 7;
187- break;
188- }
189- return reg;
190-}
191-
192-int jitCompA000_convTyp(int t)
193-{
194- int r = -1;
195-
196- if (1 <= t && t <= 7){
197- r = t;
198- } else if (8 <= t && t <= 13){
199- r = 2 | (t & 1);
200- } else if (14 <= t && t <= 15){
201- r = 4 | (t & 1);
202- } else if (16 <= t && t <= 21){
203- r = 6 | (t & 1);
204- }
205- return r;
206-}
207-
208-int jitCompA000_dataWidth(int t)
209-{
210- int r = -1;
211- if (t == 0x0001) r = 256;
212- t >>= 1;
213- if (t == 0x0002 / 2) r = 8;
214- if (t == 0x0004 / 2) r = 16;
215- if (t == 0x0006 / 2) r = 32;
216- if (t == 0x0008 / 2) r = 4;
217- if (t == 0x000a / 2) r = 2;
218- if (t == 0x000c / 2) r = 1;
219- if (t == 0x000e / 2) r = 12;
220- if (t == 0x0010 / 2) r = 20;
221- if (t == 0x0012 / 2) r = 24;
222- if (t == 0x0014 / 2) r = 28;
223- return r;
224-}
225-
226-static unsigned char *errfnc;
227-
228-void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac)
229-{
230- if (typ <= 0) { w->err = JITC_ERR_BADTYPE; }
231- if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; }
232- jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, 256 + pxx * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */
233- jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */
234- jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */
235- jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
236- return;
237-}
238-
239-void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac)
240-// data用.
241-// 将来的にはaliveやアクセス権チェックも入れる
242-{
243- jitCompA0001_checkType0(w, pxx, typ, ac);
244- return;
245-}
246-
247-void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx)
248-{
249- jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */
250- jitCompA0001_85DispN(w, 256 + pxx * 32 + 8, reg); /* p0 */
251- jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */
252- jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
253- jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */
254- jitCompA0001_85DispN(w, 256 + pxx * 32 + 12, reg); /* p1 */
255- jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */
256- jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
257- return;
258-}
2598
2609 // F5の場合、decoderが対応するalloc-freeを結びつけるのが簡単で、typやlenを指定必須にしてもフロントエンドコードに影響はない.
26110 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)
@@ -285,51 +34,54 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
28534 jitCompA000_loadPRegCacheAll(&w);
28635 }
28736 if (level <= JITC_LV_SLOWER) {
288- // XOR(EAX, EAX);
289- jitCompPutByte2(w.dst, 0x31, 0xc0);
37+ // debugInfo0 <- 0;
38+ //
39+ jitCompPutOp_MOV_EAX_ZERO(w.dst);
29040 // MOV(debugInfo0, EAX);
29141 jitCompA0001_movEbpDispReg32(&w, envOffset_DBGINFO0, IA32_REG0_EAX);
292- // MOV(EAX, ?);
293- jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, imm32); */
294- jitCompPutImm32(w.dst, debugInfo1);
42+ jitCompPutOp_MOV_GReg_Imm32(w.dst, IA32_REG0_EAX, debugInfo1);
29543 jitCompA0001_movEbpDispReg32(&w, envOffset_DBGINFO1, IA32_REG0_EAX); /* MOV(debugInfo1, EAX); */
29644 }
29745 while (src < src1) {
29846 w.prefix = 0; //0x04 CND 命令で変更される
299- if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; goto err_w; } // 書き込み領域が残り256バイト未満ならエラー
47+ if (w.dst + 256 > dst1) {
48+ // 書き込み領域が残り256バイト未満ならエラー
49+ w.err = JITC_ERR_DST1; goto err_w;
50+ }
30051 timecount++;
30152 if (timecount >= 64) {
30253 timecount -= 64;
30354 /* 未完成(timeoutチェックコードを入れる) */
30455 }
305- prefix_continue: // CND命令実行後ここに戻る
56+ prefix_continue:
57+ // CND命令コンパイル後ここに戻る
30658 switch (*src) {
307-
308- case 0x00: /* NOP */
309- if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } // 「条件付きでNOPを実行」するなんて、矛盾している!
59+ case 0x00:
60+ // NOP
61+ if (w.prefix != 0) {
62+ // 「条件付きでNOPを実行」するなんて、矛盾している!
63+ w.err = JITC_ERR_PREFIX; goto err_w;
64+ }
31065 break;
31166
312- case 0x01: /* LB */
313-
314- /*
315- * LB : ラベル設置命令。(6byte)
316- * ・prefex = 1にする
317- * ・timecount++し、timecountのチェックをする。
318- * ・ラベル位置を登録する。
319- * ・割り込みがある場合、このタイミングで割り込みを発生させる。
320- *
321- * 1 2 3 456
322- * LB 01 opt imm32
323- *
324- */
325-
67+ case 0x01:
68+ // LB : ラベル設置命令。(6byte)
69+ // ・prefex = 1にする
70+ // ・timecount++し、timecountのチェックをする。
71+ // ・ラベル位置を登録する。
72+ // ・割り込みがある場合、このタイミングで割り込みを発生させる。
73+ //
74+ // 1 2 3 456
75+ // LB 01 opt imm32
76+ //
32677 if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) { //beginFunc()中のLB
32778 // LB命令の後に0x3C命令・・・beginFunc()
32879 jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする
32980 enter0 = w.dst;
33081 jitCompPutImm32(w.dst, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ??
33182 }
332- if (src[6] == 0x34) { // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令
83+ if (src[6] == 0x34) {
84+ // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令
33385 tmp_ucp = w.dst;
33486 jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする
33587 i = jitCompGetImm32(&src[7]); // type32 を取得
@@ -337,9 +89,20 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
33789 if (i != 1) {
33890 i = jitCompA000_convTyp(i);
33991 j = 0;
340- if (i == 2 || i == 3) { j = 1; }
341- if (i == 4 || i == 5) { j = 2; }
342- if (i == 6 || i == 7) { j = 4; }
92+ switch (i) {
93+ case 2:
94+ case 3:
95+ j = 1;
96+ break;
97+ case 4:
98+ case 5:
99+ j = 2;
100+ break;
101+ case 6:
102+ case 7:
103+ j = 4;
104+ break;
105+ }
343106 }
344107 j *= jitCompGetImm32(&src[11]);
345108 if (j <= 0) w.err = JITC_ERR_BADTYPE;
@@ -375,9 +138,14 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
375138 }
376139 if ((flags & JITC_PHASE1) == 0) {
377140 i = jitCompGetLabelNum(&w, src + 2);
378- //printf("i=%06X %06X\n", i, src-src0);
379- if (label[i].opt != 0 && w.err == 0) { w.err = JITC_ERR_LABELREDEF; goto err_w; }
380- if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }
141+ if (label[i].opt != 0 && w.err == 0) {
142+ w.err = JITC_ERR_LABELREDEF;
143+ goto err_w;
144+ }
145+ if (w.prefix != 0) {
146+ w.err = JITC_ERR_PREFIX;
147+ goto err_w;
148+ }
381149 label[i].opt = src[1] + 1;
382150 label[i].typ = 0; /* TYP_CODE */
383151 label[i].p = w.dst;
@@ -389,71 +157,85 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
389157 /* 未完成(timeoutチェックコードを入れる) */
390158 break;
391159
392- case 0x02: /* LIMM */
393-
394- /*
395- * LIMM : 定数即値代入命令(6byte)
396- *
397- * 1 2 3456
398- * 02 reg0R imm32
399- *
400- * ・reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。
401- */
160+ case 0x02:
161+ // LIMM : 定数即値代入命令(6byte)
162+ // 1 2 3456
163+ // 02 reg0R imm32
164+ //
165+ // reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。
402166
403- if (src[1] == 0x3f && w.prefix != 0) w.err = JITC_ERR_PREFIX; // CND命令の直後でR3Fを書き換えるなんて変だよね
167+ if (src[1] == 0x3f && w.prefix != 0){
168+ // CND命令の直後でR3Fを書き換えるなんて変だよね
169+ w.err = JITC_ERR_PREFIX;
170+ }
404171
405172 #if (jitCompA0001_USE_R3F_IMM32 != 0)
406- if (src[1] == 0x3f) { // R3Fへの代入は例外敵に、 w.r3f を使用
173+ if (src[1] == 0x3f) {
174+ // R3Fへの代入は例外で、 w.r3f を使用
407175 w.r3f = jitCompGetImm32(src + 2);
408176 break;
409177 }
410178 #endif
411179 i = jitCompGetImm32(src + 2); // 与えられた即値(第二引数)を取得
412-
413180 /* R00-R02 なら EBX, ECX, EDX 、それ以外なら EAX のレジスタIDを reg0 に代入 */
414181 reg0 = jitCompA000_selectRegCache(src[1], IA32_REG0_EAX);
415-
182+
416183 #if (jitCompA0001_OPTIMIZE_MOV != 0)
184+ // size optimization
185+ // MOV reg, 0 -> XOR reg, reg
417186 if (i == 0) {
418- jitCompPutByte2(w.dst, 0x31, 0xc0 | reg0 << 3 | reg0); /* XOR(reg0, reg0); */
187+ jitCompPutOp_XOR_GReg_GReg(w.dst, reg0, reg0);
419188 jitCompA0001_movRxxEax(&w, src[1]);
420189 break;
421190 }
422191 #endif
423-
424192 /* reg0 のレジスタに対応したMOV命令を発行 */
425- jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); == 10111000b+wr imm32 */
426- jitCompPutImm32(w.dst, i);
193+ jitCompPutOp_MOV_GReg_Imm32(w.dst, reg0, i);
427194
428- if (reg0 == 0) // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合
429-
195+ if (reg0 == 0){
196+ // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合
430197 jitCompA0001_movRxxEax(&w, src[1]);
431- break;
198+ }
432199
433- case 0x03: /* PLIMM */ /* 未完成(plsまで対応) */
200+ break;
434201
435- /*
436- * PLIMM : ラベル番号代入命令(6byte)
437- *
438- * 1 2 3456
439- * 03 PXX imm32
440- *
441- * ・P28 はAPI用
442- * ・P30 はリターンアドレス
443- * ・P3F はプログラムカウンタ
444- */
202+ case 0x03: /* 未完成(plsまで対応) */
203+ // PLIMM : ラベル番号代入命令(6byte)
204+ //
205+ // 1 2 3456
206+ // 03 PXX imm32
207+ //
208+ // ・P28 はAPI用
209+ // ・P30 はリターンアドレス
210+ // ・P3F はプログラムカウンタ
211+ //
445212
446213 i = jitCompGetLabelNum(&w, src + 2); // Pxxに代入するラベルの番号(第二引数)
447- if ((flags & JITC_PHASE1) != 0 && w.err == 0) { // Phase 1であるならば
448- if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } // 指定されたラベル番号は存在しない
449- if (src[1] != 0x3f && label[i].opt != 2) { w.err = JITC_ERR_LABELTYP; goto err_w; } //
450- if (src[1] == 0x3f && label[i].typ != 0) { w.err = JITC_ERR_LABELTYP; goto err_w; } // プログラムカウンタに TYP_CODEでない値は代入できない
214+ if ((flags & JITC_PHASE1) != 0 && w.err == 0) {
215+ // Phase 1であるならば
216+ if (label[i].opt == 0) {
217+ // 指定されたラベル番号は存在しない
218+ w.err = JITC_ERR_LABELNODEF;
219+ goto err_w;
220+ }
221+ if (src[1] != 0x3f && label[i].opt != 2) {
222+ // ?
223+ w.err = JITC_ERR_LABELTYP;
224+ goto err_w;
225+ }
226+ if (src[1] == 0x3f && label[i].typ != 0) {
227+ // プログラムカウンタに TYP_CODEでない値は代入できない
228+ w.err = JITC_ERR_LABELTYP;
229+ goto err_w;
230+ }
451231 }
452- if (src[1] == 0x3f) { // プログラムカウンタへの代入なら
453- if (w.prefix == 0) { // CND命令による条件付きでなければ、即座に移動
232+ if (src[1] == 0x3f) {
233+ // プログラムカウンタへの代入
234+ if (w.prefix == 0) {
235+ // CND命令による条件付きでなければ、即座に移動
454236 jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */
455- }
456- else { // 直前はCND命令。
237+ } else {
238+ // 直前はCND命令。
457239
458240 /*
459241 * CND命令
@@ -463,7 +245,8 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
463245 * いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd
464246 */
465247
466- // JZのとび先アドレスの書き換え?
248+ // Jccの条件変更
249+ // 0F 75
467250 w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */
468251 w.dst[-2] = 0x0f;
469252
@@ -488,8 +271,7 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
488271 jitCompPutByte1(w.dst, j & 0xff);
489272 }
490273 #endif
491- }
492- else { // プログラムカウンタ以外への代入
274+ } else { // プログラムカウンタ以外への代入
493275
494276 // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定
495277 reg0 = jitCompA000_selectPRegCache(src[1], IA32_REG0_EAX);
@@ -516,14 +298,15 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
516298 }
517299 break;
518300
519- case 0x04: /* CND (prefix) */
520-
521- /*
522- * CND命令
523- * 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。
524- */
525-
526- if (src[1] >= 0x40) w.err = JITC_ERR_REGNUM; // R00-R3F 以外のレジスタは比較対象にできない
301+ case 0x04:
302+ // CND (prefix)
303+ // 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。
304+ //
305+ if (src[1] >= 0x40){
306+ // R00-R3F 以外のレジスタは比較対象にできない
307+ w.err = JITC_ERR_REGNUM;
308+ goto err_w;
309+ }
527310
528311 // 比較対象のレジスタがメモリ上にあれば-1, それ以外なら適切なレジスタ番号を返す
529312 reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */);
--- /dev/null
+++ b/jitcx86a.c
@@ -0,0 +1,260 @@
1+#include "osecpu.h"
2+#include "jitc.h"
3+
4+#if (JITC_ARCNUM == 0x0001)
5+//
6+// for x86-32bit
7+//
8+int jitCompGetImm32(const unsigned char *src)
9+{
10+ return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
11+}
12+
13+int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src)
14+{
15+ int i = jitCompGetImm32(src);
16+ if (i < 0 || i >= w->maxLabels) {
17+ w->err = JITC_ERR_LABELNUM;
18+ i = 0;
19+ }
20+ return i;
21+}
22+
23+void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n)
24+{
25+ disp -= jitCompA0001_EBP128;
26+ if (-128 <= disp && disp <= 127) {
27+ jitCompPutByte2(w->dst, 0x45 | (n << 3), disp & 0xff);
28+ } else {
29+ // 10 + reg + 101 + disp
30+ jitCompPutByte1(w->dst, 0x85 | (n << 3));
31+ jitCompPutImm32(w->dst, disp);
32+ }
33+ return;
34+}
35+
36+void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32)
37+{
38+ // MOV Ev, Gv
39+ // MOV + ModR/M(2Mod + 3Reg + 3R/M)
40+ jitCompPutByte1(w->dst, 0x89); /* 1000 1001 MOV(mem, reg32); */
41+ jitCompA0001_85DispN(w, disp, reg32);
42+ return;
43+}
44+
45+void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp)
46+{
47+ jitCompPutByte1(w->dst, 0x8b); /* MOV(reg32, mem); */
48+ jitCompA0001_85DispN(w, disp, reg32);
49+ return;
50+}
51+
52+void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)
53+{
54+#if (jitCompA0001_USE_R3F_IMM32 != 0)
55+ if (rxx == 0x3f) {
56+ jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */
57+ jitCompPutImm32(w->dst, w->r3f);
58+ return;
59+ }
60+#endif
61+ if (rxx >= 0x40 || rxx < 0){
62+ w->err = JITC_ERR_REGNUM;
63+ }
64+ jitCompA0001_movReg32EbpDisp(w, IA32_REG0_EAX, rxx * 4); /* MOV(EAX, [EBP+?]); */
65+ return;
66+}
67+
68+void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx)
69+{
70+ if (rxx >= 0x40 || rxx < 0){
71+ w->err = JITC_ERR_REGNUM;
72+ }
73+ jitCompA0001_movEbpDispReg32(w, rxx * 4, IA32_REG0_EAX); /* MOV([EBP+?], EAX); */
74+ return;
75+}
76+
77+void jitCompA0001_fixPrefix(struct JitCompWork *w)
78+{
79+ if (w->prefix != 0) {
80+ if (w->dst - w->dst0 > 127){
81+ w->err = JITC_ERR_REGNUM;
82+ }
83+ w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff);
84+ }
85+ return;
86+}
87+
88+void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1)
89+{
90+ if (p0 >= 0x3f || p0 < 0){
91+ w->err = JITC_ERR_PREGNUM;
92+ }
93+ if (p1 >= 0x3f || p1 < 0){
94+ w->err = JITC_ERR_PREGNUM;
95+ }
96+ /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */
97+ return;
98+}
99+
100+void jitCompA000_loadRegCacheAll(struct JitCompWork *w)
101+{
102+ jitCompA0001_movReg32EbpDisp(w, 3 /* EBX */, 0 * 4); /* EBX = R00; */
103+ jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */
104+ jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */
105+ return;
106+}
107+
108+void jitCompA000_storeRegCacheAll(struct JitCompWork *w)
109+{
110+ jitCompA0001_movEbpDispReg32(w, 0 * 4, 3 /* EBX */); /* R00 = EBX; */
111+ jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */
112+ jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */
113+ return;
114+}
115+
116+void jitCompA000_loadRegCacheEcx(struct JitCompWork *w)
117+{
118+ jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */
119+ return;
120+}
121+
122+void jitCompA000_storeRegCacheEcx(struct JitCompWork *w)
123+{
124+ jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */
125+ return;
126+}
127+
128+void jitCompA000_loadRegCacheEdx(struct JitCompWork *w)
129+{
130+ jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */
131+ return;
132+}
133+
134+void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)
135+{
136+ jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */
137+ return;
138+}
139+
140+int jitCompA000_selectRegCache(int rxx, int reg)
141+{
142+ switch (rxx) {
143+ case 0:
144+ //EBX
145+ reg = 3;
146+ break;
147+ case 1:
148+ //ECX
149+ reg = 1;
150+ break;
151+ case 2:
152+ //EDX
153+ reg = 2;
154+ break;
155+ }
156+ return reg;
157+}
158+
159+void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)
160+{
161+ // jitCompA0001_movReg32EbpDisp(w, 5 /* EBP */, 256 + 0 * 32 + 0); /* EBP = P00; */
162+ jitCompA0001_movReg32EbpDisp(w, 6 /* ESI */, 256 + 1 * 32 + 0); /* ESI = P01; */
163+ jitCompA0001_movReg32EbpDisp(w, 7 /* EDI */, 256 + 2 * 32 + 0); /* EDI = P02; */
164+ return;
165+}
166+
167+void jitCompA000_storePRegCacheAll(struct JitCompWork *w)
168+{
169+ // jitCompA0001_movEbpDispReg32(w, 256 + 0 * 32 + 0, 5 /* EBP */); /* P00 = EBP; */
170+ jitCompA0001_movEbpDispReg32(w, 256 + 1 * 32 + 0, 6 /* ESI */); /* P01 = ESI; */
171+ jitCompA0001_movEbpDispReg32(w, 256 + 2 * 32 + 0, 7 /* EDI */); /* P02 = EDI; */
172+ return;
173+}
174+
175+int jitCompA000_selectPRegCache(int pxx, int reg)
176+{
177+ // if (pxx == 0) reg = 5; /* EBP */
178+ switch (pxx) {
179+ case 1:
180+ //ESI
181+ reg = 6;
182+ break;
183+
184+ case 2:
185+ //EDI
186+ reg = 7;
187+ break;
188+ }
189+ return reg;
190+}
191+
192+int jitCompA000_convTyp(int t)
193+{
194+ int r = -1;
195+
196+ if (1 <= t && t <= 7){
197+ r = t;
198+ } else if (8 <= t && t <= 13){
199+ r = 2 | (t & 1);
200+ } else if (14 <= t && t <= 15){
201+ r = 4 | (t & 1);
202+ } else if (16 <= t && t <= 21){
203+ r = 6 | (t & 1);
204+ }
205+ return r;
206+}
207+
208+int jitCompA000_dataWidth(int t)
209+{
210+ int r = -1;
211+ if (t == 0x0001) r = 256;
212+ t >>= 1;
213+ if (t == 0x0002 / 2) r = 8;
214+ if (t == 0x0004 / 2) r = 16;
215+ if (t == 0x0006 / 2) r = 32;
216+ if (t == 0x0008 / 2) r = 4;
217+ if (t == 0x000a / 2) r = 2;
218+ if (t == 0x000c / 2) r = 1;
219+ if (t == 0x000e / 2) r = 12;
220+ if (t == 0x0010 / 2) r = 20;
221+ if (t == 0x0012 / 2) r = 24;
222+ if (t == 0x0014 / 2) r = 28;
223+ return r;
224+}
225+
226+unsigned char *errfnc;
227+
228+void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac)
229+{
230+ if (typ <= 0) { w->err = JITC_ERR_BADTYPE; }
231+ if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; }
232+ jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, 256 + pxx * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */
233+ jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */
234+ jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */
235+ jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
236+ return;
237+}
238+
239+void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac)
240+// data用.
241+// 将来的にはaliveやアクセス権チェックも入れる
242+{
243+ jitCompA0001_checkType0(w, pxx, typ, ac);
244+ return;
245+}
246+
247+void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx)
248+{
249+ jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */
250+ jitCompA0001_85DispN(w, 256 + pxx * 32 + 8, reg); /* p0 */
251+ jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */
252+ jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
253+ jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */
254+ jitCompA0001_85DispN(w, 256 + pxx * 32 + 12, reg); /* p1 */
255+ jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */
256+ jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
257+ return;
258+}
259+
260+#endif
Show on old repository browser