diff options
author | Mike Pavone <pavone@retrodev.com> | 2012-12-29 21:10:07 -0800 |
---|---|---|
committer | Mike Pavone <pavone@retrodev.com> | 2012-12-29 21:10:07 -0800 |
commit | 25675152efc46a055f8a597ac6a73151e88d92b7 (patch) | |
tree | cce0cda33a7f9d37cc8510d3bcceaf74716d2977 | |
parent | b95588dc7e532eac892cbe4c763e8b6f07a3949e (diff) |
Implement the rest of the bit instructions
-rw-r--r-- | gen_x86.c | 99 | ||||
-rw-r--r-- | gen_x86.h | 12 | ||||
-rw-r--r-- | m68k_to_x86.c | 55 |
3 files changed, 150 insertions, 16 deletions
@@ -43,7 +43,10 @@ #define OP2_JCC 0x80 #define OP2_SETCC 0x90 #define OP2_BT 0xA3 +#define OP2_BTS 0xAB +#define OP2_BTR 0xB3 #define OP2_BTX_I 0xBA +#define OP2_BTC 0xBB #define OP2_MOVSX 0xBE #define OP_EX_ADDI 0x0 @@ -1082,7 +1085,7 @@ uint8_t * setcc_rdisp8(uint8_t * out, uint8_t cc, uint8_t dst, int8_t disp) return out; } -uint8_t * bt_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) +uint8_t * bit_rr(uint8_t * out, uint8_t op2, uint8_t src, uint8_t dst, uint8_t size) { if (size == SZ_W) { *(out++) = PRE_SIZE; @@ -1103,12 +1106,12 @@ uint8_t * bt_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) out++; } *(out++) = PRE_2BYTE; - *(out++) = OP2_BT; + *(out++) = op2; *(out++) = MODE_REG_DIRECT | dst | (src << 3); return out; } -uint8_t * bt_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size) +uint8_t * bit_rrdisp8(uint8_t * out, uint8_t op2, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size) { if (size == SZ_W) { *(out++) = PRE_SIZE; @@ -1129,13 +1132,13 @@ uint8_t * bt_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_di out++; } *(out++) = PRE_2BYTE; - *(out++) = OP2_BT; + *(out++) = op2; *(out++) = MODE_REG_DISPLACE8 | dst_base | (src << 3); *(out++) = dst_disp; return out; } -uint8_t * bt_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) +uint8_t * bit_ir(uint8_t * out, uint8_t op_ex, uint8_t val, uint8_t dst, uint8_t size) { if (size == SZ_W) { *(out++) = PRE_SIZE; @@ -1153,12 +1156,12 @@ uint8_t * bt_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) } *(out++) = PRE_2BYTE; *(out++) = OP2_BTX_I; - *(out++) = MODE_REG_DIRECT | dst | (OP_EX_BT << 3); + *(out++) = MODE_REG_DIRECT | dst | (op_ex << 3); *(out++) = val; return out; } -uint8_t * bt_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size) +uint8_t * bit_irdisp8(uint8_t * out, uint8_t op_ex, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size) { if (size == SZ_W) { *(out++) = PRE_SIZE; @@ -1176,12 +1179,92 @@ uint8_t * bt_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_di } *(out++) = PRE_2BYTE; *(out++) = OP2_BTX_I; - *(out++) = MODE_REG_DISPLACE8 | dst_base | (OP_EX_BT << 3); + *(out++) = MODE_REG_DISPLACE8 | dst_base | (op_ex << 3); *(out++) = dst_disp; *(out++) = val; return out; } +uint8_t * bt_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) +{ + return bit_rr(out, OP2_BT, src, dst, size); +} + +uint8_t * bt_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size) +{ + return bit_rrdisp8(out, OP2_BT, src, dst_base, dst_disp, size); +} + +uint8_t * bt_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) +{ + return bit_ir(out, OP_EX_BT, val, dst, size); +} + +uint8_t * bt_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size) +{ + return bit_irdisp8(out, OP_EX_BT, val, dst_base, dst_disp, size); +} + +uint8_t * bts_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) +{ + return bit_rr(out, OP2_BT, src, dst, size); +} + +uint8_t * bts_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size) +{ + return bit_rrdisp8(out, OP2_BT, src, dst_base, dst_disp, size); +} + +uint8_t * bts_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) +{ + return bit_ir(out, OP_EX_BTS, val, dst, size); +} + +uint8_t * bts_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size) +{ + return bit_irdisp8(out, OP_EX_BTS, val, dst_base, dst_disp, size); +} + +uint8_t * btr_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) +{ + return bit_rr(out, OP2_BTR, src, dst, size); +} + +uint8_t * btr_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size) +{ + return bit_rrdisp8(out, OP2_BTR, src, dst_base, dst_disp, size); +} + +uint8_t * btr_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) +{ + return bit_ir(out, OP_EX_BTR, val, dst, size); +} + +uint8_t * btr_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size) +{ + return bit_irdisp8(out, OP_EX_BTR, val, dst_base, dst_disp, size); +} + +uint8_t * btc_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) +{ + return bit_rr(out, OP2_BTC, src, dst, size); +} + +uint8_t * btc_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size) +{ + return bit_rrdisp8(out, OP2_BTC, src, dst_base, dst_disp, size); +} + +uint8_t * btc_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) +{ + return bit_ir(out, OP_EX_BTC, val, dst, size); +} + +uint8_t * btc_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size) +{ + return bit_irdisp8(out, OP_EX_BTC, val, dst_base, dst_disp, size); +} + uint8_t * jcc(uint8_t * out, uint8_t cc, uint8_t * dest) { ptrdiff_t disp = dest-(out+2); @@ -148,6 +148,18 @@ uint8_t * bt_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size); uint8_t * bt_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size); uint8_t * bt_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size); uint8_t * bt_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size); +uint8_t * bts_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size); +uint8_t * bts_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size); +uint8_t * bts_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size); +uint8_t * bts_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size); +uint8_t * btr_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size); +uint8_t * btr_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size); +uint8_t * btr_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size); +uint8_t * btr_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size); +uint8_t * btc_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size); +uint8_t * btc_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size); +uint8_t * btc_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size); +uint8_t * btc_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size); uint8_t * jcc(uint8_t * out, uint8_t cc, uint8_t *dest); uint8_t * jmp(uint8_t * out, uint8_t *dest); uint8_t * jmp_r(uint8_t * out, uint8_t dst); diff --git a/m68k_to_x86.c b/m68k_to_x86.c index 2689c59..24b6410 100644 --- a/m68k_to_x86.c +++ b/m68k_to_x86.c @@ -2075,20 +2075,39 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) case M68K_LSR: dst = translate_shift(dst, inst, &src_op, &dst_op, opts, shr_ir, shr_irdisp8, shr_clr, shr_clrdisp8, shl_ir, shl_irdisp8); break; - /*case M68K_BCHG: + case M68K_BCHG: case M68K_BCLR: case M68K_BSET: - break;*/ case M68K_BTST: dst = cycles(dst, inst->extra.size == OPSIZE_BYTE ? 4 : 6); if (src_op.mode == MODE_IMMED) { if (inst->extra.size == OPSIZE_BYTE) { src_op.disp &= 0x7; } - if (dst_op.mode == MODE_REG_DIRECT) { - dst = bt_ir(dst, src_op.disp, dst_op.base, SZ_D); + if (inst->op == M68K_BTST) { + if (dst_op.mode == MODE_REG_DIRECT) { + dst = bt_ir(dst, src_op.disp, dst_op.base, SZ_D); + } else { + dst = bt_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, SZ_D); + } + } else if (inst->op == M68K_BSET) { + if (dst_op.mode == MODE_REG_DIRECT) { + dst = bts_ir(dst, src_op.disp, dst_op.base, SZ_D); + } else { + dst = bts_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, SZ_D); + } + } else if (inst->op == M68K_BCLR) { + if (dst_op.mode == MODE_REG_DIRECT) { + dst = btr_ir(dst, src_op.disp, dst_op.base, SZ_D); + } else { + dst = btr_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, SZ_D); + } } else { - dst = bt_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, SZ_D); + if (dst_op.mode == MODE_REG_DIRECT) { + dst = btc_ir(dst, src_op.disp, dst_op.base, SZ_D); + } else { + dst = btc_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, SZ_D); + } } } else { if (src_op.mode == MODE_REG_DISPLACE8) { @@ -2104,10 +2123,30 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) if (inst->extra.size == OPSIZE_BYTE) { dst = and_ir(dst, 0x7, src_op.base, SZ_B); } - if (dst_op.mode == MODE_REG_DIRECT) { - dst = bt_rr(dst, src_op.base, dst_op.base, SZ_D); + if (inst->op == M68K_BTST) { + if (dst_op.mode == MODE_REG_DIRECT) { + dst = bt_rr(dst, src_op.base, dst_op.base, SZ_D); + } else { + dst = bt_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); + } + } else if (inst->op == M68K_BSET) { + if (dst_op.mode == MODE_REG_DIRECT) { + dst = bts_rr(dst, src_op.base, dst_op.base, SZ_D); + } else { + dst = bts_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); + } + } else if (inst->op == M68K_BCLR) { + if (dst_op.mode == MODE_REG_DIRECT) { + dst = btr_rr(dst, src_op.base, dst_op.base, SZ_D); + } else { + dst = btr_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); + } } else { - dst = bt_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); + if (dst_op.mode == MODE_REG_DIRECT) { + dst = btc_rr(dst, src_op.base, dst_op.base, SZ_D); + } else { + dst = btc_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); + } } } //x86 sets the carry flag to the value of the bit tested |