Mercurial > repos > blastem
comparison gen_x86.c @ 82:6331ddec228f
Initial stab at interrupt support. Make native code offsets bigger so I don't have to worry about overflowing the offset. Implement neg and not (untested).
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 26 Dec 2012 11:09:04 -0800 |
parents | 6d231dbe75ab |
children | e3594572fb98 |
comparison
equal
deleted
inserted
replaced
81:6d231dbe75ab | 82:6331ddec228f |
---|---|
35 #define OP_SHIFTROT_1 0xD0 | 35 #define OP_SHIFTROT_1 0xD0 |
36 #define OP_SHIFTROT_CL 0xD2 | 36 #define OP_SHIFTROT_CL 0xD2 |
37 #define OP_CALL 0xE8 | 37 #define OP_CALL 0xE8 |
38 #define OP_JMP 0xE9 | 38 #define OP_JMP 0xE9 |
39 #define OP_JMP_BYTE 0xEB | 39 #define OP_JMP_BYTE 0xEB |
40 #define OP_NOT_NEG 0xF6 | |
40 #define OP_SINGLE_EA 0xFF | 41 #define OP_SINGLE_EA 0xFF |
41 | 42 |
42 #define OP2_JCC 0x80 | 43 #define OP2_JCC 0x80 |
43 #define OP2_SETCC 0x90 | 44 #define OP2_SETCC 0x90 |
44 #define OP2_BT 0xA3 | 45 #define OP2_BT 0xA3 |
65 | 66 |
66 #define OP_EX_BT 0x4 | 67 #define OP_EX_BT 0x4 |
67 #define OP_EX_BTS 0x5 | 68 #define OP_EX_BTS 0x5 |
68 #define OP_EX_BTR 0x6 | 69 #define OP_EX_BTR 0x6 |
69 #define OP_EX_BTC 0x7 | 70 #define OP_EX_BTC 0x7 |
71 | |
72 #define OP_EX_TEST_I 0x0 | |
73 #define OP_EX_NOT 0x2 | |
74 #define OP_EX_NEG 0x3 | |
70 | 75 |
71 #define OP_EX_INC 0x0 | 76 #define OP_EX_INC 0x0 |
72 #define OP_EX_DEC 0x1 | 77 #define OP_EX_DEC 0x1 |
73 #define OP_EX_CALL_EA 0x2 | 78 #define OP_EX_CALL_EA 0x2 |
74 #define OP_EX_JMP_EA 0x4 | 79 #define OP_EX_JMP_EA 0x4 |
220 *(out++) = (RSP << 3) | RSP; | 225 *(out++) = (RSP << 3) | RSP; |
221 } | 226 } |
222 return out; | 227 return out; |
223 } | 228 } |
224 | 229 |
230 uint8_t * x86_r_size(uint8_t * out, uint8_t opcode, uint8_t opex, uint8_t dst, uint8_t size) | |
231 { | |
232 uint8_t tmp; | |
233 if (size == SZ_W) { | |
234 *(out++) = PRE_SIZE; | |
235 } | |
236 if (size == SZ_Q || dst >= R8) { | |
237 *out = PRE_REX; | |
238 if (size == SZ_Q) { | |
239 *out |= REX_QUAD; | |
240 } | |
241 if (dst >= R8) { | |
242 *out |= REX_RM_FIELD; | |
243 dst -= (R8 - X86_R8); | |
244 } | |
245 out++; | |
246 } | |
247 if (size == SZ_B) { | |
248 if (dst >= AH && dst <= BH) { | |
249 dst -= (AH-X86_AH); | |
250 } | |
251 } else { | |
252 opcode |= BIT_SIZE; | |
253 } | |
254 *(out++) = opcode; | |
255 *(out++) = MODE_REG_DIRECT | dst | (opex << 3); | |
256 return out; | |
257 } | |
258 | |
259 uint8_t * x86_rdisp8_size(uint8_t * out, uint8_t opcode, uint8_t opex, uint8_t dst, int8_t disp, uint8_t size) | |
260 { | |
261 uint8_t tmp; | |
262 if (size == SZ_W) { | |
263 *(out++) = PRE_SIZE; | |
264 } | |
265 if (size == SZ_Q || dst >= R8) { | |
266 *out = PRE_REX; | |
267 if (size == SZ_Q) { | |
268 *out |= REX_QUAD; | |
269 } | |
270 if (dst >= R8) { | |
271 *out |= REX_RM_FIELD; | |
272 dst -= (R8 - X86_R8); | |
273 } | |
274 out++; | |
275 } | |
276 if (size != SZ_B) { | |
277 opcode |= BIT_SIZE; | |
278 } | |
279 *(out++) = opcode; | |
280 *(out++) = MODE_REG_DISPLACE8 | dst | (opex << 3); | |
281 *(out++) = disp; | |
282 return out; | |
283 } | |
284 | |
225 uint8_t * x86_ir(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst, uint8_t size) | 285 uint8_t * x86_ir(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst, uint8_t size) |
226 { | 286 { |
227 uint8_t sign_extend = 0; | 287 uint8_t sign_extend = 0; |
228 if ((size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) { | 288 if ((size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) { |
229 sign_extend = 1; | 289 sign_extend = 1; |
295 *out |= REX_RM_FIELD; | 355 *out |= REX_RM_FIELD; |
296 dst -= (R8 - X86_R8); | 356 dst -= (R8 - X86_R8); |
297 } | 357 } |
298 out++; | 358 out++; |
299 } | 359 } |
300 if (dst >= AH && dst <= BH) { | |
301 dst -= (AH-X86_AH); | |
302 } | |
303 if (size != SZ_B) { | 360 if (size != SZ_B) { |
304 opcode |= BIT_SIZE; | 361 opcode |= BIT_SIZE; |
305 } | 362 } |
306 *(out++) = opcode; | 363 *(out++) = opcode; |
307 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); | 364 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); |
714 } | 771 } |
715 | 772 |
716 uint8_t * cmp_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) | 773 uint8_t * cmp_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) |
717 { | 774 { |
718 return x86_rrdisp8_sizedir(out, OP_CMP, dst, src_base, disp, size, BIT_DIR); | 775 return x86_rrdisp8_sizedir(out, OP_CMP, dst, src_base, disp, size, BIT_DIR); |
776 } | |
777 | |
778 uint8_t * not_r(uint8_t * out, uint8_t dst, uint8_t size) | |
779 { | |
780 return x86_r_size(out, OP_NOT_NEG, OP_EX_NOT, dst, size); | |
781 } | |
782 | |
783 uint8_t * neg_r(uint8_t * out, uint8_t dst, uint8_t size) | |
784 { | |
785 return x86_r_size(out, OP_NOT_NEG, OP_EX_NEG, dst, size); | |
786 } | |
787 | |
788 uint8_t * not_rdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) | |
789 { | |
790 return x86_rdisp8_size(out, OP_NOT_NEG, OP_EX_NOT, dst_base, disp, size); | |
791 } | |
792 | |
793 uint8_t * neg_rdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) | |
794 { | |
795 return x86_rdisp8_size(out, OP_NOT_NEG, OP_EX_NEG, dst_base, disp, size); | |
719 } | 796 } |
720 | 797 |
721 uint8_t * mov_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | 798 uint8_t * mov_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) |
722 { | 799 { |
723 return x86_rr_sizedir(out, OP_MOV, src, dst, size); | 800 return x86_rr_sizedir(out, OP_MOV, src, dst, size); |
1145 | 1222 |
1146 uint8_t * jmp_r(uint8_t * out, uint8_t dst) | 1223 uint8_t * jmp_r(uint8_t * out, uint8_t dst) |
1147 { | 1224 { |
1148 *(out++) = OP_SINGLE_EA; | 1225 *(out++) = OP_SINGLE_EA; |
1149 *(out++) = MODE_REG_DIRECT | dst | (OP_EX_JMP_EA << 3); | 1226 *(out++) = MODE_REG_DIRECT | dst | (OP_EX_JMP_EA << 3); |
1227 return out; | |
1150 } | 1228 } |
1151 | 1229 |
1152 uint8_t * call(uint8_t * out, uint8_t * fun) | 1230 uint8_t * call(uint8_t * out, uint8_t * fun) |
1153 { | 1231 { |
1154 ptrdiff_t disp = fun-(out+5); | 1232 ptrdiff_t disp = fun-(out+5); |