Mercurial > repos > blastem
comparison m68k_core_x86.c @ 584:b6713c1b6f55
Combine andi ccr/sr and ori ccr/sr.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 07 Mar 2014 19:35:13 -0800 |
parents | 819921b76b4b |
children | 82aadd5d103a |
comparison
equal
deleted
inserted
replaced
583:819921b76b4b | 584:b6713c1b6f55 |
---|---|
1990 call(code, (code_ptr)print_regs_exit); | 1990 call(code, (code_ptr)print_regs_exit); |
1991 } | 1991 } |
1992 | 1992 |
1993 #define BIT_SUPERVISOR 5 | 1993 #define BIT_SUPERVISOR 5 |
1994 | 1994 |
1995 void translate_m68k_andi_ccr_sr(m68k_options *opts, m68kinst *inst) | 1995 void translate_m68k_andi_ori_ccr_sr(m68k_options *opts, m68kinst *inst) |
1996 { | 1996 { |
1997 code_info *code = &opts->gen.code; | 1997 code_info *code = &opts->gen.code; |
1998 cycles(&opts->gen, 20); | 1998 cycles(&opts->gen, 20); |
1999 //TODO: If ANDI to SR, trap if not in supervisor mode | 1999 //TODO: If ANDI to SR, trap if not in supervisor mode |
2000 uint32_t flag_mask = 0; | 2000 uint32_t flag_mask = 0; |
2001 if (!(inst->src.params.immed & 0x1)) { | 2001 uint32_t base_flag = inst->op == M68K_ANDI_SR || inst->op == M68K_ANDI_CCR ? X0 : X1; |
2002 flag_mask |= C0; | 2002 for (int i = 0; i < 5; i++) |
2003 } | 2003 { |
2004 if (!(inst->src.params.immed & 0x2)) { | 2004 if ((base_flag == X0) ^ (inst->src.params.immed & 1 << i) > 0) |
2005 flag_mask |= V0; | 2005 { |
2006 } | 2006 flag_mask |= base_flag << ((4 - i) * 3); |
2007 if (!(inst->src.params.immed & 0x4)) { | 2007 } |
2008 flag_mask |= Z0; | |
2009 } | |
2010 if (!(inst->src.params.immed & 0x8)) { | |
2011 flag_mask |= N0; | |
2012 } | |
2013 if (!(inst->src.params.immed & 0x10)) { | |
2014 flag_mask |= X0; | |
2015 } | 2008 } |
2016 update_flags(opts, flag_mask); | 2009 update_flags(opts, flag_mask); |
2017 if (inst->op == M68K_ANDI_SR) { | 2010 if (inst->op == M68K_ANDI_SR || inst->op == M68K_ORI_SR) { |
2018 and_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); | 2011 if (inst->op == M68K_ANDI_SR) { |
2019 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { | 2012 and_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); |
2013 } else { | |
2014 or_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); | |
2015 } | |
2016 if ((base_flag == X0) ^ (((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR)) > 0)) { | |
2020 //leave supervisor mode | 2017 //leave supervisor mode |
2021 swap_ssp_usp(opts); | 2018 swap_ssp_usp(opts); |
2022 } | 2019 } |
2023 if (inst->src.params.immed & 0x700) { | 2020 if ((inst->op == M68K_ANDI_SR && (inst->src.params.immed & 0x700) != 0x700) |
2024 call(code, opts->do_sync); | 2021 || (inst->op == M68K_ORI_SR && inst->src.params.immed & 0x700)) { |
2025 } | |
2026 } | |
2027 } | |
2028 | |
2029 void translate_m68k_ori_ccr_sr(m68k_options *opts, m68kinst *inst) | |
2030 { | |
2031 code_info *code = &opts->gen.code; | |
2032 cycles(&opts->gen, 20); | |
2033 //TODO: If ORI to SR, trap if not in supervisor mode | |
2034 uint32_t flag_mask = 0; | |
2035 if (inst->src.params.immed & 0x1) { | |
2036 flag_mask |= C1; | |
2037 } | |
2038 if (inst->src.params.immed & 0x2) { | |
2039 flag_mask |= V1; | |
2040 } | |
2041 if (inst->src.params.immed & 0x4) { | |
2042 flag_mask |= Z1; | |
2043 } | |
2044 if (inst->src.params.immed & 0x8) { | |
2045 flag_mask |= N1; | |
2046 } | |
2047 if (inst->src.params.immed & 0x10) { | |
2048 flag_mask |= X1; | |
2049 } | |
2050 update_flags(opts, flag_mask); | |
2051 if (inst->op == M68K_ORI_SR) { | |
2052 or_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); | |
2053 if (inst->src.params.immed & 0x700) { | |
2054 call(code, opts->do_sync); | 2022 call(code, opts->do_sync); |
2055 } | 2023 } |
2056 } | 2024 } |
2057 } | 2025 } |
2058 | 2026 |