summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2014-03-07 19:35:13 -0800
committerMichael Pavone <pavone@retrodev.com>2014-03-07 19:35:13 -0800
commit617f6c62ea109d2209e2b6fbdc150d279a1885cf (patch)
treeb364d9fb9771ec2d70c86bc0dde655a9793f92f8
parent28bc72c0e478ec24bc9d10e822ef8818448ce491 (diff)
Combine andi ccr/sr and ori ccr/sr.
-rw-r--r--m68k_core.c8
-rw-r--r--m68k_core_x86.c66
-rw-r--r--m68k_internal.h3
3 files changed, 22 insertions, 55 deletions
diff --git a/m68k_core.c b/m68k_core.c
index 4a44ebc..af6d544 100644
--- a/m68k_core.c
+++ b/m68k_core.c
@@ -551,12 +551,12 @@ impl_info m68k_impls[] = {
RAW_IMPL(M68K_UNLK, translate_m68k_unlk),
//SR/CCR stuff
- RAW_IMPL(M68K_ANDI_CCR, translate_m68k_andi_ccr_sr),
- RAW_IMPL(M68K_ANDI_SR, translate_m68k_andi_ccr_sr),
+ RAW_IMPL(M68K_ANDI_CCR, translate_m68k_andi_ori_ccr_sr),
+ RAW_IMPL(M68K_ANDI_SR, translate_m68k_andi_ori_ccr_sr),
RAW_IMPL(M68K_EORI_CCR, translate_m68k_eori_ccr_sr),
RAW_IMPL(M68K_EORI_SR, translate_m68k_eori_ccr_sr),
- RAW_IMPL(M68K_ORI_CCR, translate_m68k_ori_ccr_sr),
- RAW_IMPL(M68K_ORI_SR, translate_m68k_ori_ccr_sr),
+ RAW_IMPL(M68K_ORI_CCR, translate_m68k_andi_ori_ccr_sr),
+ RAW_IMPL(M68K_ORI_SR, translate_m68k_andi_ori_ccr_sr),
OP_IMPL(M68K_MOVE_CCR, translate_m68k_move_ccr_sr),
OP_IMPL(M68K_MOVE_SR, translate_m68k_move_ccr_sr),
OP_IMPL(M68K_MOVE_FROM_SR, translate_m68k_move_from_sr),
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);
}
}
diff --git a/m68k_internal.h b/m68k_internal.h
index ef39c2e..e867dbb 100644
--- a/m68k_internal.h
+++ b/m68k_internal.h
@@ -79,8 +79,7 @@ void translate_m68k_mul(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos
void translate_m68k_negx(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op);
void translate_m68k_rot(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op);
void translate_m68k_illegal(m68k_options *opts, m68kinst *inst);
-void translate_m68k_andi_ccr_sr(m68k_options *opts, m68kinst *inst);
-void translate_m68k_ori_ccr_sr(m68k_options *opts, m68kinst *inst);
+void translate_m68k_andi_ori_ccr_sr(m68k_options *opts, m68kinst *inst);
void translate_m68k_eori_ccr_sr(m68k_options *opts, m68kinst *inst);
void translate_m68k_move_ccr_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op);
void translate_m68k_stop(m68k_options *opts, m68kinst *inst);