diff options
author | Michael Pavone <pavone@retrodev.com> | 2014-03-07 19:35:13 -0800 |
---|---|---|
committer | Michael Pavone <pavone@retrodev.com> | 2014-03-07 19:35:13 -0800 |
commit | 617f6c62ea109d2209e2b6fbdc150d279a1885cf (patch) | |
tree | b364d9fb9771ec2d70c86bc0dde655a9793f92f8 /m68k_core_x86.c | |
parent | 28bc72c0e478ec24bc9d10e822ef8818448ce491 (diff) |
Combine andi ccr/sr and ori ccr/sr.
Diffstat (limited to 'm68k_core_x86.c')
-rw-r--r-- | m68k_core_x86.c | 66 |
1 files changed, 17 insertions, 49 deletions
diff --git a/m68k_core_x86.c b/m68k_core_x86.c index e879f88..5a6e058 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -1992,65 +1992,33 @@ void translate_m68k_illegal(m68k_options *opts, m68kinst *inst) #define BIT_SUPERVISOR 5 -void translate_m68k_andi_ccr_sr(m68k_options *opts, m68kinst *inst) +void translate_m68k_andi_ori_ccr_sr(m68k_options *opts, m68kinst *inst) { code_info *code = &opts->gen.code; cycles(&opts->gen, 20); //TODO: If ANDI to SR, trap if not in supervisor mode uint32_t flag_mask = 0; - if (!(inst->src.params.immed & 0x1)) { - flag_mask |= C0; - } - if (!(inst->src.params.immed & 0x2)) { - flag_mask |= V0; - } - if (!(inst->src.params.immed & 0x4)) { - flag_mask |= Z0; - } - if (!(inst->src.params.immed & 0x8)) { - flag_mask |= N0; - } - if (!(inst->src.params.immed & 0x10)) { - flag_mask |= X0; + uint32_t base_flag = inst->op == M68K_ANDI_SR || inst->op == M68K_ANDI_CCR ? X0 : X1; + for (int i = 0; i < 5; i++) + { + if ((base_flag == X0) ^ (inst->src.params.immed & 1 << i) > 0) + { + flag_mask |= base_flag << ((4 - i) * 3); + } } update_flags(opts, flag_mask); - if (inst->op == M68K_ANDI_SR) { - and_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); - if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { + if (inst->op == M68K_ANDI_SR || inst->op == M68K_ORI_SR) { + if (inst->op == M68K_ANDI_SR) { + and_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); + } else { + or_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); + } + if ((base_flag == X0) ^ (((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR)) > 0)) { //leave supervisor mode swap_ssp_usp(opts); } - if (inst->src.params.immed & 0x700) { - call(code, opts->do_sync); - } - } -} - -void translate_m68k_ori_ccr_sr(m68k_options *opts, m68kinst *inst) -{ - code_info *code = &opts->gen.code; - cycles(&opts->gen, 20); - //TODO: If ORI to SR, trap if not in supervisor mode - uint32_t flag_mask = 0; - if (inst->src.params.immed & 0x1) { - flag_mask |= C1; - } - if (inst->src.params.immed & 0x2) { - flag_mask |= V1; - } - if (inst->src.params.immed & 0x4) { - flag_mask |= Z1; - } - if (inst->src.params.immed & 0x8) { - flag_mask |= N1; - } - if (inst->src.params.immed & 0x10) { - flag_mask |= X1; - } - update_flags(opts, flag_mask); - if (inst->op == M68K_ORI_SR) { - or_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); - if (inst->src.params.immed & 0x700) { + if ((inst->op == M68K_ANDI_SR && (inst->src.params.immed & 0x700) != 0x700) + || (inst->op == M68K_ORI_SR && inst->src.params.immed & 0x700)) { call(code, opts->do_sync); } } |