Mercurial > repos > blastem
comparison gen_x86.c @ 241:2586d49ddd46
Implement EX, EXX and RST in Z80 core
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 28 Apr 2013 13:45:17 -0700 |
parents | d9bf8e61c33c |
children | 1788e3f29c28 |
comparison
equal
deleted
inserted
replaced
240:ed540dd4cf2b | 241:2586d49ddd46 |
---|---|
22 #define OP_POP 0x58 | 22 #define OP_POP 0x58 |
23 #define OP_MOVSXD 0x63 | 23 #define OP_MOVSXD 0x63 |
24 #define PRE_SIZE 0x66 | 24 #define PRE_SIZE 0x66 |
25 #define OP_JCC 0x70 | 25 #define OP_JCC 0x70 |
26 #define OP_IMMED_ARITH 0x80 | 26 #define OP_IMMED_ARITH 0x80 |
27 #define OP_XCHG 0x86 | |
27 #define OP_MOV 0x88 | 28 #define OP_MOV 0x88 |
29 #define OP_XCHG_AX 0x90 | |
28 #define OP_CDQ 0x99 | 30 #define OP_CDQ 0x99 |
29 #define OP_PUSHF 0x9C | 31 #define OP_PUSHF 0x9C |
30 #define OP_POPF 0x9D | 32 #define OP_POPF 0x9D |
31 #define OP_MOV_I8R 0xB0 | 33 #define OP_MOV_I8R 0xB0 |
32 #define OP_MOV_IR 0xB8 | 34 #define OP_MOV_IR 0xB8 |
118 X86_R15 | 120 X86_R15 |
119 } x86_regs_enc; | 121 } x86_regs_enc; |
120 | 122 |
121 uint8_t * x86_rr_sizedir(uint8_t * out, uint16_t opcode, uint8_t src, uint8_t dst, uint8_t size) | 123 uint8_t * x86_rr_sizedir(uint8_t * out, uint16_t opcode, uint8_t src, uint8_t dst, uint8_t size) |
122 { | 124 { |
123 //TODO: Deal with the fact that AH, BH, CH and DH can only be in the R/M param when there's a REX prefix | |
124 uint8_t tmp; | 125 uint8_t tmp; |
125 if (size == SZ_W) { | 126 if (size == SZ_W) { |
126 *(out++) = PRE_SIZE; | 127 *(out++) = PRE_SIZE; |
127 } | 128 } |
128 if (size == SZ_B && dst >= RSP && dst <= RDI) { | 129 if (size == SZ_B && dst >= RSP && dst <= RDI) { |
1182 *(out++) = MODE_REG_DISPLACE8 | src | (dst << 3); | 1183 *(out++) = MODE_REG_DISPLACE8 | src | (dst << 3); |
1183 *(out++) = disp; | 1184 *(out++) = disp; |
1184 return out; | 1185 return out; |
1185 } | 1186 } |
1186 | 1187 |
1188 uint8_t * xchg_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | |
1189 { | |
1190 //TODO: Use OP_XCHG_AX when one of the registers is AX, EAX or RAX | |
1191 uint8_t tmp; | |
1192 if (size == SZ_W) { | |
1193 *(out++) = PRE_SIZE; | |
1194 } | |
1195 if (size == SZ_B && dst >= RSP && dst <= RDI) { | |
1196 tmp = dst; | |
1197 dst = src; | |
1198 src = tmp; | |
1199 } | |
1200 if (size == SZ_Q || src >= R8 || dst >= R8 || (size == SZ_B && src >= RSP && src <= RDI)) { | |
1201 *out = PRE_REX; | |
1202 if (size == SZ_Q) { | |
1203 *out |= REX_QUAD; | |
1204 } | |
1205 if (src >= R8) { | |
1206 *out |= REX_REG_FIELD; | |
1207 src -= (R8 - X86_R8); | |
1208 } | |
1209 if (dst >= R8) { | |
1210 *out |= REX_RM_FIELD; | |
1211 dst -= (R8 - X86_R8); | |
1212 } | |
1213 out++; | |
1214 } | |
1215 uint8_t opcode = OP_XCHG; | |
1216 if (size == SZ_B) { | |
1217 if (src >= AH && src <= BH) { | |
1218 src -= (AH-X86_AH); | |
1219 } | |
1220 if (dst >= AH && dst <= BH) { | |
1221 dst -= (AH-X86_AH); | |
1222 } | |
1223 } else { | |
1224 opcode |= BIT_SIZE; | |
1225 } | |
1226 *(out++) = opcode; | |
1227 *(out++) = MODE_REG_DIRECT | dst | (src << 3); | |
1228 return out; | |
1229 } | |
1230 | |
1187 uint8_t * pushf(uint8_t * out) | 1231 uint8_t * pushf(uint8_t * out) |
1188 { | 1232 { |
1189 *(out++) = OP_PUSHF; | 1233 *(out++) = OP_PUSHF; |
1190 return out; | 1234 return out; |
1191 } | 1235 } |