Mercurial > repos > blastem
diff 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 |
line wrap: on
line diff
--- a/gen_x86.c Sat Dec 22 21:37:25 2012 -0800 +++ b/gen_x86.c Wed Dec 26 11:09:04 2012 -0800 @@ -37,6 +37,7 @@ #define OP_CALL 0xE8 #define OP_JMP 0xE9 #define OP_JMP_BYTE 0xEB +#define OP_NOT_NEG 0xF6 #define OP_SINGLE_EA 0xFF #define OP2_JCC 0x80 @@ -68,6 +69,10 @@ #define OP_EX_BTR 0x6 #define OP_EX_BTC 0x7 +#define OP_EX_TEST_I 0x0 +#define OP_EX_NOT 0x2 +#define OP_EX_NEG 0x3 + #define OP_EX_INC 0x0 #define OP_EX_DEC 0x1 #define OP_EX_CALL_EA 0x2 @@ -222,6 +227,61 @@ return out; } +uint8_t * x86_r_size(uint8_t * out, uint8_t opcode, uint8_t opex, uint8_t dst, uint8_t size) +{ + uint8_t tmp; + if (size == SZ_W) { + *(out++) = PRE_SIZE; + } + if (size == SZ_Q || dst >= R8) { + *out = PRE_REX; + if (size == SZ_Q) { + *out |= REX_QUAD; + } + if (dst >= R8) { + *out |= REX_RM_FIELD; + dst -= (R8 - X86_R8); + } + out++; + } + if (size == SZ_B) { + if (dst >= AH && dst <= BH) { + dst -= (AH-X86_AH); + } + } else { + opcode |= BIT_SIZE; + } + *(out++) = opcode; + *(out++) = MODE_REG_DIRECT | dst | (opex << 3); + return out; +} + +uint8_t * x86_rdisp8_size(uint8_t * out, uint8_t opcode, uint8_t opex, uint8_t dst, int8_t disp, uint8_t size) +{ + uint8_t tmp; + if (size == SZ_W) { + *(out++) = PRE_SIZE; + } + if (size == SZ_Q || dst >= R8) { + *out = PRE_REX; + if (size == SZ_Q) { + *out |= REX_QUAD; + } + if (dst >= R8) { + *out |= REX_RM_FIELD; + dst -= (R8 - X86_R8); + } + out++; + } + if (size != SZ_B) { + opcode |= BIT_SIZE; + } + *(out++) = opcode; + *(out++) = MODE_REG_DISPLACE8 | dst | (opex << 3); + *(out++) = disp; + return out; +} + 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) { uint8_t sign_extend = 0; @@ -297,9 +357,6 @@ } out++; } - if (dst >= AH && dst <= BH) { - dst -= (AH-X86_AH); - } if (size != SZ_B) { opcode |= BIT_SIZE; } @@ -718,6 +775,26 @@ return x86_rrdisp8_sizedir(out, OP_CMP, dst, src_base, disp, size, BIT_DIR); } +uint8_t * not_r(uint8_t * out, uint8_t dst, uint8_t size) +{ + return x86_r_size(out, OP_NOT_NEG, OP_EX_NOT, dst, size); +} + +uint8_t * neg_r(uint8_t * out, uint8_t dst, uint8_t size) +{ + return x86_r_size(out, OP_NOT_NEG, OP_EX_NEG, dst, size); +} + +uint8_t * not_rdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) +{ + return x86_rdisp8_size(out, OP_NOT_NEG, OP_EX_NOT, dst_base, disp, size); +} + +uint8_t * neg_rdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) +{ + return x86_rdisp8_size(out, OP_NOT_NEG, OP_EX_NEG, dst_base, disp, size); +} + uint8_t * mov_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) { return x86_rr_sizedir(out, OP_MOV, src, dst, size); @@ -1147,6 +1224,7 @@ { *(out++) = OP_SINGLE_EA; *(out++) = MODE_REG_DIRECT | dst | (OP_EX_JMP_EA << 3); + return out; } uint8_t * call(uint8_t * out, uint8_t * fun)