OSDN Git Service

Merge branch 'master' of git.sourceforge.jp:/gitroot/heavyosecpu/HeavyOSECPU
[heavyosecpu/HeavyOSECPU.git] / jitcx86a.c
1 #include "osecpu.h"
2 #include "jitc.h"
3
4 #if (JITC_ARCNUM == 0x0001)
5 //
6 // for x86-32bit
7 //
8 int jitCompGetImm32(const unsigned char *src)
9 {
10         return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
11 }
12
13 int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src)
14 {
15         int i = jitCompGetImm32(src);
16         if (i < 0 || i >= w->maxLabels) {
17                 w->err = JITC_ERR_LABELNUM;
18                 i = 0;
19         }
20         return i;
21 }
22
23 void jitCompPutModRM_Disp_BaseEBP(struct JitCompWork *w, int disp, int opReg)
24 {
25         // EBPをベースとするアドレスオペランドとレジスタオペランドを出力する
26         disp -= jitCompA0001_EBP128;
27         if (-128 <= disp && disp <= 127) {
28                 // [EBP + Disp08]
29                 jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_BYTE, opReg, IA32_REG5_EBP));
30                 jitCompPutByte1(w->dst, disp & 0xff);
31         } else {
32                 // [EBP + Disp32]
33                 jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_FULL, opReg, IA32_REG5_EBP));
34                 jitCompPutImm32(w->dst, disp);
35         }
36         return;
37 }
38
39 void jitCompPutOp_MOV_EBPDisp_GReg(struct JitCompWork *w, int disp, int reg32)
40 {
41         // MOV([EBP + disp] <- reg32);
42         // MOV Ev, Gv
43         // [1000 100 1] [mod reg r/m]
44         jitCompPutByte1(w->dst, 0x89);
45         jitCompPutModRM_Disp_BaseEBP(w, disp, reg32);
46         return;
47 }
48
49 void jitCompPutOp_MOV_GReg_EBPDisp(struct JitCompWork *w, int reg32, int disp)
50 {
51         // MOV (reg32 <- [EBP + disp])
52         // MOV Gv, Ev
53         // [1000 101 1] [mod reg r/m]
54         jitCompPutByte1(w->dst, 0x8b);
55         jitCompPutModRM_Disp_BaseEBP(w, disp, reg32);
56         return;
57 }
58
59 void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)
60 {
61 #if (jitCompA0001_USE_R3F_IMM32 != 0)
62         if (rxx == 0x3f) {
63                 jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */
64                 jitCompPutImm32(w->dst, w->r3f);
65                 return;
66         }
67 #endif
68         if (rxx >= 0x40 || rxx < 0){
69                 w->err = JITC_ERR_REGNUM;
70         }
71         jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, rxx * 4);
72         return;
73 }
74
75 void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx)
76 {
77         if (rxx >= 0x40 || rxx < 0){
78                 w->err = JITC_ERR_REGNUM;
79         }
80         jitCompPutOp_MOV_EBPDisp_GReg(w, rxx * 4, IA32_REG0_EAX);
81         return;
82 }
83
84 void jitCompA0001_fixPrefix(struct JitCompWork *w)
85 {
86         if (w->prefix != 0) {
87                 if (w->dst - w->dst0 > 127){
88                         w->err = JITC_ERR_REGNUM;
89                 }
90                 w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff);
91         }
92         return;
93 }
94
95 void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1)
96 {
97         if (p0 >= 0x3f || p0 < 0){
98                 w->err = JITC_ERR_PREGNUM;
99         }
100         if (p1 >= 0x3f || p1 < 0){
101                 w->err = JITC_ERR_PREGNUM;
102         }
103         /* 比較可能可能なのかのチェックのコードを出力 */   /* 未完成 */
104         return;
105 }
106
107 void jitCompA000_loadRegCacheAll(struct JitCompWork *w)
108 {
109         //保存されたレジスタキャッシュをメモリからロード
110         jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG3_EBX, 4 * 0); /* EBX = R00; */
111         jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 4 * 1); /* ECX = R01; */
112         jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 4 * 2); /* EDX = R02; */
113         return;
114 }
115
116 void jitCompA000_storeRegCacheAll(struct JitCompWork *w)
117 {
118         //レジスタキャッシュをメモリに退避
119         jitCompPutOp_MOV_EBPDisp_GReg(w, 0 * 4, IA32_REG3_EBX); /* R00 = EBX; */
120         jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */
121         jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */
122         return;
123 }
124
125 void jitCompA000_loadRegCacheEcx(struct JitCompWork *w)
126 {
127         jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 1 * 4); /* ECX = R01; */
128         return;
129 }
130
131 void jitCompA000_storeRegCacheEcx(struct JitCompWork *w)
132 {
133         jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */
134         return;
135 }
136
137 void jitCompA000_loadRegCacheEdx(struct JitCompWork *w)
138 {
139         jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 2 * 4); /* EDX = R02; */
140         return;
141 }
142
143 void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)
144 {
145         jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */
146         return;
147 }
148
149 int jitCompA000_selectRegCache(int rxx, int reg)
150 {
151         // OSECPUレジスタ番号をIA32レジスタ番号へ変換
152         // 対応するキャッシュレジスタがない場合regが返る
153         switch (rxx) {
154                 case 0:
155                         reg = IA32_REG3_EBX;
156                         break;
157                 case 1:
158                         reg = IA32_REG1_ECX;
159                         break;
160                 case 2:
161                         reg = IA32_REG2_EDX;
162                         break;
163         }
164         return reg;
165 }
166
167 void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)
168 {
169         jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG6_ESI, PRegOffset(0x01) + 0); /* ESI = P01; */
170         jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG7_EDI, PRegOffset(0x02) + 0); /* EDI = P02; */
171         return;
172 }
173
174 void jitCompA000_storePRegCacheAll(struct JitCompWork *w)
175 {
176         jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x01) + 0, IA32_REG6_ESI); /* P01 = ESI; */
177         jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x02) + 0, IA32_REG7_EDI); /* P02 = EDI; */
178         return;
179 }
180
181 int jitCompA000_selectPRegCache(int pxx, int reg)
182 {
183         //      if (pxx == 0) reg = 5; /* EBP */
184         switch (pxx) {
185                 case 1:
186                         //ESI
187                         reg = 6;
188                         break;
189                         
190                 case 2:
191                         //EDI
192                         reg = 7;
193                         break;
194         }
195         return reg;
196 }
197
198 int jitCompA000_convTyp(int t)
199 {
200         // 指定されたタイプのデータ幅を返す。
201         // unsigned なら奇数(1bit目がOn)
202         // retv = 1     : VPtr
203         // retv = 2 or 3: BYTE ( 8,  4,  2,  1 bit)
204         // retv = 4 or 5: WORD (16, 12 bit)
205         // retv = 6 or 7: DWORD(32, 20, 24, 28 bit)
206         // -1はエラー
207         int r = -1;
208         
209         if (1 <= t && t <= 7){
210                 // 1 - 7はそのままでOK
211                 r = t;
212         } else if (8 <= t && t <= 13){
213                 r = 2 | (t & 1);
214         } else if (14 <= t && t <= 15){
215                 r = 4 | (t & 1);
216         } else if (16 <= t && t <= 21){
217                 r = 6 | (t & 1);
218         }
219         return r;
220 }
221
222 int jitCompA000_dataWidth(int t)
223 {
224     // 指定されたタイプのビット数を返す
225         int r = -1;
226         if (t == 0x0001) r = 256;
227         t >>= 1;
228         if (t == 0x0002 / 2) r = 8;
229         if (t == 0x0004 / 2) r = 16;
230         if (t == 0x0006 / 2) r = 32;
231         if (t == 0x0008 / 2) r = 4;
232         if (t == 0x000a / 2) r = 2;
233         if (t == 0x000c / 2) r = 1;
234         if (t == 0x000e / 2) r = 12;
235         if (t == 0x0010 / 2) r = 20;
236         if (t == 0x0012 / 2) r = 24;
237         if (t == 0x0014 / 2) r = 28;
238         return r;
239 }
240
241 unsigned char *errfnc;
242
243 void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac)
244 {
245         if (typ <= 0) { w->err = JITC_ERR_BADTYPE; }
246         if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; }
247         jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, PRegOffset(pxx) + 4); /* MOV(EAX, [EBP+?]); */  /* typ */
248         jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f);        /* CMP(EAX, ?); */
249         jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */
250         jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
251         return;
252 }
253
254 void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac)
255 {
256         // data用.
257         // 将来的にはaliveやアクセス権チェックも入れる
258         jitCompA0001_checkType0(w, pxx, typ, ac);
259         return;
260 }
261
262 void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx)
263 {
264         jitCompPutByte1(w->dst, 0x3b);  /* CMP(reg, [EBP+?]); */
265         jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 8, reg);      /* p0 */
266         jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */
267         jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
268         jitCompPutByte1(w->dst, 0x3b);  /* CMP(reg, [EBP+?]); */
269         jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 12, reg);     /* p1 */
270         jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */
271         jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
272         return;
273 }
274
275 #endif