OSDN Git Service

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