aboutsummaryrefslogtreecommitdiff
path: root/target/m68k/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/m68k/translate.c')
-rw-r--r--target/m68k/translate.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index ad4d4efb8d..dfecfb6e5f 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -565,7 +565,7 @@ static void gen_flush_flags(DisasContext *s)
t1 = tcg_temp_new();
tcg_gen_add_i32(t0, QREG_CC_N, QREG_CC_V);
gen_ext(t0, t0, s->cc_op - CC_OP_SUBB, 1);
- tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V);
+ tcg_gen_xor_i32(t1, QREG_CC_N, t0);
tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0);
tcg_temp_free(t0);
tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, t1);
@@ -669,6 +669,21 @@ static inline int insn_opsize(int insn)
}
}
+static inline int ext_opsize(int ext, int pos)
+{
+ switch ((ext >> pos) & 7) {
+ case 0: return OS_LONG;
+ case 1: return OS_SINGLE;
+ case 2: return OS_EXTENDED;
+ case 3: return OS_PACKED;
+ case 4: return OS_WORD;
+ case 5: return OS_DOUBLE;
+ case 6: return OS_BYTE;
+ default:
+ g_assert_not_reached();
+ }
+}
+
/* Assign value to a register. If the width is less than the register width
only the low part of the register is set. */
static void gen_partset_reg(int opsize, TCGv reg, TCGv val)
@@ -4111,20 +4126,19 @@ DISAS_INSN(fpu)
tmp32 = tcg_temp_new_i32();
/* fmove */
/* ??? TODO: Proper behavior on overflow. */
- switch ((ext >> 10) & 7) {
- case 0:
- opsize = OS_LONG;
+
+ opsize = ext_opsize(ext, 10);
+ switch (opsize) {
+ case OS_LONG:
gen_helper_f64_to_i32(tmp32, cpu_env, src);
break;
- case 1:
- opsize = OS_SINGLE;
+ case OS_SINGLE:
gen_helper_f64_to_f32(tmp32, cpu_env, src);
break;
- case 4:
- opsize = OS_WORD;
+ case OS_WORD:
gen_helper_f64_to_i32(tmp32, cpu_env, src);
break;
- case 5: /* OS_DOUBLE */
+ case OS_DOUBLE:
tcg_gen_mov_i32(tmp32, AREG(insn, 0));
switch ((insn >> 3) & 7) {
case 2:
@@ -4153,8 +4167,7 @@ DISAS_INSN(fpu)
}
tcg_temp_free_i32(tmp32);
return;
- case 6:
- opsize = OS_BYTE;
+ case OS_BYTE:
gen_helper_f64_to_i32(tmp32, cpu_env, src);
break;
default:
@@ -4227,15 +4240,7 @@ DISAS_INSN(fpu)
}
if (ext & (1 << 14)) {
/* Source effective address. */
- switch ((ext >> 10) & 7) {
- case 0: opsize = OS_LONG; break;
- case 1: opsize = OS_SINGLE; break;
- case 4: opsize = OS_WORD; break;
- case 5: opsize = OS_DOUBLE; break;
- case 6: opsize = OS_BYTE; break;
- default:
- goto undef;
- }
+ opsize = ext_opsize(ext, 10);
if (opsize == OS_DOUBLE) {
tmp32 = tcg_temp_new_i32();
tcg_gen_mov_i32(tmp32, AREG(insn, 0));