|
dvander@70
|
1 |
#include <limits.h> |
|
dvander@70
|
2 |
#include <string.h> |
|
dvander@70
|
3 |
#include "jit_x86.h" |
|
dvander@70
|
4 |
#include "opcode_helpers.h" |
|
dvander@70
|
5 |
#include "x86_macros.h" |
|
dvander@70
|
6 |
|
|
dvander@70
|
7 |
int OpAdvTable[OP_NUM_OPCODES]; |
|
dvander@70
|
8 |
|
|
dvander@70
|
9 |
void Macro_PushN_Addr(JitWriter *jit, int i) |
|
dvander@70
|
10 |
{ |
|
dvander@70
|
11 |
//push eax |
|
dvander@70
|
12 |
//mov eax, frm |
|
dvander@70
|
13 |
//loop i times: |
|
dvander@70
|
14 |
// lea ecx, [eax+<val>] |
|
dvander@70
|
15 |
// mov [ebp-4*i], ecx |
|
dvander@70
|
16 |
//sub ebp, 4*N |
|
dvander@70
|
17 |
//pop eax |
|
dvander@70
|
18 |
|
|
dvander@70
|
19 |
cell_t val; |
|
dvander@70
|
20 |
int n = 1; |
|
dvander@70
|
21 |
IA32_Push_Reg(jit, AMX_REG_PRI); |
|
dvander@70
|
22 |
IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_INFO_FRM, MOD_MEM_REG); |
|
dvander@70
|
23 |
do |
|
dvander@70
|
24 |
{ |
|
dvander@70
|
25 |
val = jit->read_cell(); |
|
dvander@70
|
26 |
if (val < SCHAR_MAX && val > SCHAR_MIN) |
|
dvander@70
|
27 |
IA32_Lea_DispRegImm8(jit, AMX_REG_TMP, AMX_REG_PRI, (jit_int8_t)val); |
|
dvander@70
|
28 |
else |
|
dvander@70
|
29 |
IA32_Lea_DispRegImm32(jit, AMX_REG_TMP, AMX_REG_PRI, val); |
|
dvander@70
|
30 |
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n); |
|
dvander@70
|
31 |
} while (n++ < i); |
|
dvander@70
|
32 |
IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG); |
|
dvander@70
|
33 |
IA32_Pop_Reg(jit, AMX_REG_PRI); |
|
dvander@70
|
34 |
} |
|
dvander@70
|
35 |
|
|
dvander@70
|
36 |
void Macro_PushN_S(JitWriter *jit, int i) |
|
dvander@70
|
37 |
{ |
|
dvander@70
|
38 |
//loop i times: |
|
dvander@70
|
39 |
// mov ecx, [ebx+<val>] |
|
dvander@70
|
40 |
// mov [ebp-4*i], ecx |
|
dvander@70
|
41 |
//sub ebp, 4*N |
|
dvander@70
|
42 |
|
|
dvander@70
|
43 |
cell_t val; |
|
dvander@70
|
44 |
int n = 1; |
|
dvander@70
|
45 |
do |
|
dvander@70
|
46 |
{ |
|
dvander@70
|
47 |
val = jit->read_cell(); |
|
dvander@70
|
48 |
if (val < SCHAR_MAX && val > SCHAR_MIN) |
|
dvander@70
|
49 |
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val); |
|
dvander@70
|
50 |
else |
|
dvander@70
|
51 |
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val); |
|
dvander@70
|
52 |
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n); |
|
dvander@70
|
53 |
} while (n++ < i); |
|
dvander@70
|
54 |
IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG); |
|
dvander@70
|
55 |
} |
|
dvander@70
|
56 |
|
|
dvander@70
|
57 |
void Macro_PushN_C(JitWriter *jit, int i) |
|
dvander@70
|
58 |
{ |
|
dvander@70
|
59 |
//loop i times: |
|
dvander@70
|
60 |
// mov [ebp-4*i], <val> |
|
dvander@70
|
61 |
//sub ebp, 4*N |
|
dvander@70
|
62 |
|
|
dvander@70
|
63 |
int n = 1; |
|
dvander@70
|
64 |
do |
|
dvander@70
|
65 |
{ |
|
dvander@70
|
66 |
IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_STK, jit->read_cell(), -4*n); |
|
dvander@70
|
67 |
} while (n++ < i); |
|
dvander@70
|
68 |
IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG); |
|
dvander@70
|
69 |
} |
|
dvander@70
|
70 |
|
|
dvander@70
|
71 |
void Macro_PushN(JitWriter *jit, int i) |
|
dvander@70
|
72 |
{ |
|
dvander@70
|
73 |
//loop i times: |
|
dvander@70
|
74 |
// mov ecx, [edi+<val>] |
|
dvander@70
|
75 |
// mov [ebp-4*i], ecx |
|
dvander@70
|
76 |
//sub ebp, 4*N |
|
dvander@70
|
77 |
|
|
dvander@70
|
78 |
cell_t val; |
|
dvander@70
|
79 |
int n = 1; |
|
dvander@70
|
80 |
do |
|
dvander@70
|
81 |
{ |
|
dvander@70
|
82 |
val = jit->read_cell(); |
|
dvander@70
|
83 |
if (val < SCHAR_MAX && val > SCHAR_MIN) |
|
dvander@70
|
84 |
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_DAT, (jit_int8_t)val); |
|
dvander@70
|
85 |
else |
|
dvander@70
|
86 |
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val); |
|
dvander@70
|
87 |
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n); |
|
dvander@70
|
88 |
} while (n++ < i); |
|
dvander@70
|
89 |
IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG); |
|
dvander@70
|
90 |
} |
|
dvander@70
|
91 |
|
|
dvander@70
|
92 |
JITX86::JITX86() |
|
dvander@70
|
93 |
{ |
|
dvander@70
|
94 |
memset(OpAdvTable, -1, sizeof(OpAdvTable)); |
|
dvander@70
|
95 |
|
|
dvander@70
|
96 |
/* instructions with 5 parameters */ |
|
dvander@70
|
97 |
OpAdvTable[OP_PUSH5_C] = sizeof(cell_t)*5; |
|
dvander@70
|
98 |
OpAdvTable[OP_PUSH5] = sizeof(cell_t)*5; |
|
dvander@70
|
99 |
OpAdvTable[OP_PUSH5_S] = sizeof(cell_t)*5; |
|
dvander@70
|
100 |
OpAdvTable[OP_PUSH5_ADR] = sizeof(cell_t)*5; |
|
dvander@70
|
101 |
|
|
dvander@70
|
102 |
/* instructions with 4 parameters */ |
|
dvander@70
|
103 |
OpAdvTable[OP_PUSH4_C] = sizeof(cell_t)*4; |
|
dvander@70
|
104 |
OpAdvTable[OP_PUSH4] = sizeof(cell_t)*4; |
|
dvander@70
|
105 |
OpAdvTable[OP_PUSH4_S] = sizeof(cell_t)*4; |
|
dvander@70
|
106 |
OpAdvTable[OP_PUSH4_ADR] = sizeof(cell_t)*4; |
|
dvander@70
|
107 |
|
|
dvander@70
|
108 |
/* instructions with 3 parameters */ |
|
dvander@70
|
109 |
OpAdvTable[OP_PUSH3_C] = sizeof(cell_t)*3; |
|
dvander@70
|
110 |
OpAdvTable[OP_PUSH3] = sizeof(cell_t)*3; |
|
dvander@70
|
111 |
OpAdvTable[OP_PUSH3_S] = sizeof(cell_t)*3; |
|
dvander@70
|
112 |
OpAdvTable[OP_PUSH3_ADR] = sizeof(cell_t)*3; |
|
dvander@70
|
113 |
|
|
dvander@70
|
114 |
/* instructions with 2 parameters */ |
|
dvander@70
|
115 |
OpAdvTable[OP_PUSH2_C] = sizeof(cell_t)*2; |
|
dvander@70
|
116 |
OpAdvTable[OP_PUSH2] = sizeof(cell_t)*2; |
|
dvander@70
|
117 |
OpAdvTable[OP_PUSH2_S] = sizeof(cell_t)*2; |
|
dvander@70
|
118 |
OpAdvTable[OP_PUSH2_ADR] = sizeof(cell_t)*2; |
|
dvander@70
|
119 |
OpAdvTable[OP_LOAD_BOTH] = sizeof(cell_t)*2; |
|
dvander@70
|
120 |
OpAdvTable[OP_LOAD_S_BOTH] = sizeof(cell_t)*2; |
|
dvander@70
|
121 |
OpAdvTable[OP_CONST] = sizeof(cell_t)*2; |
|
dvander@70
|
122 |
OpAdvTable[OP_CONST_S] = sizeof(cell_t)*2; |
|
dvander@70
|
123 |
|
|
dvander@70
|
124 |
/* instructions with 1 parameter */ |
|
dvander@70
|
125 |
OpAdvTable[OP_LOAD_PRI] = sizeof(cell_t); |
|
dvander@70
|
126 |
OpAdvTable[OP_LOAD_ALT] = sizeof(cell_t); |
|
dvander@70
|
127 |
OpAdvTable[OP_LOAD_S_PRI] = sizeof(cell_t); |
|
dvander@70
|
128 |
OpAdvTable[OP_LOAD_S_ALT] = sizeof(cell_t); |
|
dvander@70
|
129 |
OpAdvTable[OP_LREF_PRI] = sizeof(cell_t); |
|
dvander@70
|
130 |
OpAdvTable[OP_LREF_ALT] = sizeof(cell_t); |
|
dvander@70
|
131 |
OpAdvTable[OP_LREF_S_PRI] = sizeof(cell_t); |
|
dvander@70
|
132 |
OpAdvTable[OP_LREF_S_ALT] = sizeof(cell_t); |
|
dvander@70
|
133 |
OpAdvTable[OP_LODB_I] = sizeof(cell_t); |
|
dvander@70
|
134 |
OpAdvTable[OP_CONST_PRI] = sizeof(cell_t); |
|
dvander@70
|
135 |
OpAdvTable[OP_CONST_ALT] = sizeof(cell_t); |
|
dvander@70
|
136 |
OpAdvTable[OP_ADDR_PRI] = sizeof(cell_t); |
|
dvander@70
|
137 |
OpAdvTable[OP_ADDR_ALT] = sizeof(cell_t); |
|
dvander@70
|
138 |
OpAdvTable[OP_STOR_PRI] = sizeof(cell_t); |
|
dvander@70
|
139 |
OpAdvTable[OP_STOR_ALT] = sizeof(cell_t); |
|
dvander@70
|
140 |
OpAdvTable[OP_STOR_S_PRI] = sizeof(cell_t); |
|
dvander@70
|
141 |
OpAdvTable[OP_STOR_S_ALT] = sizeof(cell_t); |
|
dvander@70
|
142 |
OpAdvTable[OP_SREF_PRI] = sizeof(cell_t); |
|
dvander@70
|
143 |
OpAdvTable[OP_SREF_ALT] = sizeof(cell_t); |
|
dvander@70
|
144 |
OpAdvTable[OP_SREF_S_PRI] = sizeof(cell_t); |
|
dvander@70
|
145 |
OpAdvTable[OP_SREF_S_ALT] = sizeof(cell_t); |
|
dvander@70
|
146 |
OpAdvTable[OP_STRB_I] = sizeof(cell_t); |
|
dvander@70
|
147 |
OpAdvTable[OP_LIDX_B] = sizeof(cell_t); |
|
dvander@70
|
148 |
OpAdvTable[OP_IDXADDR_B] = sizeof(cell_t); |
|
dvander@70
|
149 |
OpAdvTable[OP_ALIGN_PRI] = sizeof(cell_t); |
|
dvander@70
|
150 |
OpAdvTable[OP_ALIGN_ALT] = sizeof(cell_t); |
|
dvander@70
|
151 |
OpAdvTable[OP_LCTRL] = sizeof(cell_t); |
|
dvander@70
|
152 |
OpAdvTable[OP_SCTRL] = sizeof(cell_t); |
|
dvander@70
|
153 |
OpAdvTable[OP_PUSH_C] = sizeof(cell_t); |
|
dvander@70
|
154 |
OpAdvTable[OP_PUSH] = sizeof(cell_t); |
|
dvander@70
|
155 |
OpAdvTable[OP_PUSH_S] = sizeof(cell_t); |
|
dvander@70
|
156 |
OpAdvTable[OP_STACK] = sizeof(cell_t); |
|
dvander@70
|
157 |
OpAdvTable[OP_HEAP] = sizeof(cell_t); |
|
dvander@70
|
158 |
OpAdvTable[OP_JREL] = sizeof(cell_t); |
|
dvander@70
|
159 |
OpAdvTable[OP_SHL_C_PRI] = sizeof(cell_t); |
|
dvander@70
|
160 |
OpAdvTable[OP_SHL_C_ALT] = sizeof(cell_t); |
|
dvander@70
|
161 |
OpAdvTable[OP_SHR_C_PRI] = sizeof(cell_t); |
|
dvander@70
|
162 |
OpAdvTable[OP_SHR_C_ALT] = sizeof(cell_t); |
|
dvander@70
|
163 |
OpAdvTable[OP_ADD_C] = sizeof(cell_t); |
|
dvander@70
|
164 |
OpAdvTable[OP_SMUL_C] = sizeof(cell_t); |
|
dvander@70
|
165 |
OpAdvTable[OP_ZERO] = sizeof(cell_t); |
|
dvander@70
|
166 |
OpAdvTable[OP_ZERO_S] = sizeof(cell_t); |
|
dvander@70
|
167 |
OpAdvTable[OP_EQ_C_PRI] = sizeof(cell_t); |
|
dvander@70
|
168 |
OpAdvTable[OP_EQ_C_ALT] = sizeof(cell_t); |
|
dvander@70
|
169 |
OpAdvTable[OP_INC] = sizeof(cell_t); |
|
dvander@70
|
170 |
OpAdvTable[OP_INC_S] = sizeof(cell_t); |
|
dvander@70
|
171 |
OpAdvTable[OP_DEC] = sizeof(cell_t); |
|
dvander@70
|
172 |
OpAdvTable[OP_DEC_S] = sizeof(cell_t); |
|
dvander@70
|
173 |
OpAdvTable[OP_MOVS] = sizeof(cell_t); |
|
dvander@70
|
174 |
OpAdvTable[OP_CMPS] = sizeof(cell_t); |
|
dvander@70
|
175 |
OpAdvTable[OP_FILL] = sizeof(cell_t); |
|
dvander@70
|
176 |
OpAdvTable[OP_HALT] = sizeof(cell_t); |
|
dvander@70
|
177 |
OpAdvTable[OP_BOUNDS] = sizeof(cell_t); |
|
dvander@70
|
178 |
OpAdvTable[OP_PUSH_ADR] = sizeof(cell_t); |
|
dvander@71
|
179 |
OpAdvTable[OP_PUSH_HEAP_C] = sizeof(cell_t); |
|
dvander@70
|
180 |
|
|
dvander@70
|
181 |
/* instructions with 0 parameters */ |
|
dvander@70
|
182 |
OpAdvTable[OP_LOAD_I] = 0; |
|
dvander@70
|
183 |
OpAdvTable[OP_STOR_I] = 0; |
|
dvander@70
|
184 |
OpAdvTable[OP_LIDX] = 0; |
|
dvander@70
|
185 |
OpAdvTable[OP_IDXADDR] = 0; |
|
dvander@70
|
186 |
OpAdvTable[OP_MOVE_PRI] = 0; |
|
dvander@70
|
187 |
OpAdvTable[OP_MOVE_ALT] = 0; |
|
dvander@70
|
188 |
OpAdvTable[OP_XCHG] = 0; |
|
dvander@70
|
189 |
OpAdvTable[OP_PUSH_PRI] = 0; |
|
dvander@70
|
190 |
OpAdvTable[OP_PUSH_ALT] = 0; |
|
dvander@70
|
191 |
OpAdvTable[OP_POP_PRI] = 0; |
|
dvander@70
|
192 |
OpAdvTable[OP_POP_ALT] = 0; |
|
dvander@70
|
193 |
OpAdvTable[OP_PROC] = 0; |
|
dvander@70
|
194 |
OpAdvTable[OP_RET] = 0; |
|
dvander@70
|
195 |
OpAdvTable[OP_RETN] = 0; |
|
dvander@70
|
196 |
OpAdvTable[OP_CALL_PRI] = 0; |
|
dvander@70
|
197 |
OpAdvTable[OP_SHL] = 0; |
|
dvander@70
|
198 |
OpAdvTable[OP_SHR] = 0; |
|
dvander@70
|
199 |
OpAdvTable[OP_SSHR] = 0; |
|
dvander@70
|
200 |
OpAdvTable[OP_SMUL] = 0; |
|
dvander@70
|
201 |
OpAdvTable[OP_SDIV] = 0; |
|
dvander@70
|
202 |
OpAdvTable[OP_SDIV_ALT] = 0; |
|
dvander@70
|
203 |
OpAdvTable[OP_UMUL] = 0; |
|
dvander@70
|
204 |
OpAdvTable[OP_UDIV] = 0; |
|
dvander@70
|
205 |
OpAdvTable[OP_UDIV_ALT] = 0; |
|
dvander@70
|
206 |
OpAdvTable[OP_ADD] = 0; |
|
dvander@70
|
207 |
OpAdvTable[OP_SUB] = 0; |
|
dvander@70
|
208 |
OpAdvTable[OP_SUB_ALT] = 0; |
|
dvander@70
|
209 |
OpAdvTable[OP_AND] = 0; |
|
dvander@70
|
210 |
OpAdvTable[OP_OR] = 0; |
|
dvander@70
|
211 |
OpAdvTable[OP_XOR] = 0; |
|
dvander@70
|
212 |
OpAdvTable[OP_NOT] = 0; |
|
dvander@70
|
213 |
OpAdvTable[OP_NEG] = 0; |
|
dvander@70
|
214 |
OpAdvTable[OP_INVERT] = 0; |
|
dvander@70
|
215 |
OpAdvTable[OP_ZERO_PRI] = 0; |
|
dvander@70
|
216 |
OpAdvTable[OP_ZERO_ALT] = 0; |
|
dvander@70
|
217 |
OpAdvTable[OP_SIGN_PRI] = 0; |
|
dvander@70
|
218 |
OpAdvTable[OP_SIGN_ALT] = 0; |
|
dvander@70
|
219 |
OpAdvTable[OP_EQ] = 0; |
|
dvander@70
|
220 |
OpAdvTable[OP_NEQ] = 0; |
|
dvander@70
|
221 |
OpAdvTable[OP_LESS] = 0; |
|
dvander@70
|
222 |
OpAdvTable[OP_LEQ] = 0; |
|
dvander@70
|
223 |
OpAdvTable[OP_GRTR] = 0; |
|
dvander@70
|
224 |
OpAdvTable[OP_GEQ] = 0; |
|
dvander@70
|
225 |
OpAdvTable[OP_SLESS] = 0; |
|
dvander@70
|
226 |
OpAdvTable[OP_SLEQ] = 0; |
|
dvander@70
|
227 |
OpAdvTable[OP_SGRTR] = 0; |
|
dvander@70
|
228 |
OpAdvTable[OP_SGEQ] = 0; |
|
dvander@70
|
229 |
OpAdvTable[OP_INC_PRI] = 0; |
|
dvander@70
|
230 |
OpAdvTable[OP_INC_ALT] = 0; |
|
dvander@70
|
231 |
OpAdvTable[OP_INC_I] = 0; |
|
dvander@70
|
232 |
OpAdvTable[OP_DEC_PRI] = 0; |
|
dvander@70
|
233 |
OpAdvTable[OP_DEC_ALT] = 0; |
|
dvander@70
|
234 |
OpAdvTable[OP_DEC_I] = 0; |
|
dvander@70
|
235 |
OpAdvTable[OP_JUMP_PRI] = 0; |
|
dvander@70
|
236 |
OpAdvTable[OP_SWAP_PRI] = 0; |
|
dvander@70
|
237 |
OpAdvTable[OP_SWAP_ALT] = 0; |
|
dvander@70
|
238 |
OpAdvTable[OP_NOP] = 0; |
|
dvander@70
|
239 |
OpAdvTable[OP_BREAK] = 0; |
|
dvander@71
|
240 |
OpAdvTable[OP_HEAP_PRI] = 0; |
|
dvander@71
|
241 |
OpAdvTable[OP_POP_HEAP_PRI] = 0; |
|
dvander@70
|
242 |
|
|
dvander@70
|
243 |
/* opcodes that need relocation */ |
|
dvander@70
|
244 |
OpAdvTable[OP_CALL] = -2; |
|
dvander@70
|
245 |
OpAdvTable[OP_JUMP] = -2; |
|
dvander@70
|
246 |
OpAdvTable[OP_JZER] = -2; |
|
dvander@70
|
247 |
OpAdvTable[OP_JNZ] = -2; |
|
dvander@70
|
248 |
OpAdvTable[OP_JEQ] = -2; |
|
dvander@70
|
249 |
OpAdvTable[OP_JNEQ] = -2; |
|
dvander@70
|
250 |
OpAdvTable[OP_JLESS] = -2; |
|
dvander@70
|
251 |
OpAdvTable[OP_JLEQ] = -2; |
|
dvander@70
|
252 |
OpAdvTable[OP_JGRTR] = -2; |
|
dvander@70
|
253 |
OpAdvTable[OP_JGEQ] = -2; |
|
dvander@70
|
254 |
OpAdvTable[OP_JSLESS] = -2; |
|
dvander@70
|
255 |
OpAdvTable[OP_JSLEQ] = -2; |
|
dvander@70
|
256 |
OpAdvTable[OP_JSGRTR] = -2; |
|
dvander@70
|
257 |
OpAdvTable[OP_JSGEQ] = -2; |
|
dvander@70
|
258 |
OpAdvTable[OP_SWITCH] = -2; |
|
dvander@70
|
259 |
|
|
dvander@70
|
260 |
/* opcodes that are totally invalid */ |
|
dvander@70
|
261 |
OpAdvTable[OP_FILE] = -3; |
|
dvander@70
|
262 |
OpAdvTable[OP_SYMBOL] = -3; |
|
dvander@70
|
263 |
OpAdvTable[OP_LINE] = -3; |
|
dvander@70
|
264 |
OpAdvTable[OP_SRANGE] = -3; |
|
dvander@70
|
265 |
OpAdvTable[OP_SYMTAG] = -3; |
|
dvander@70
|
266 |
OpAdvTable[OP_SYSREQ_D] = -3; |
|
dvander@70
|
267 |
OpAdvTable[OP_SYSREQ_ND] = -3; |
|
dvander@70
|
268 |
OpAdvTable[OP_PUSH_R] = -3; |
|
dvander@70
|
269 |
} |
|
dvander@70
|
270 |
|