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 }