qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH for-2.5 17/30] m68k: ori/andi/subi/addi/eori/cmpi ca


From: Laurent Vivier
Subject: [Qemu-devel] [PATCH for-2.5 17/30] m68k: ori/andi/subi/addi/eori/cmpi can modify SR/CCR
Date: Sun, 9 Aug 2015 22:13:36 +0200

Signed-off-by: Laurent Vivier <address@hidden>
---
 target-m68k/translate.c | 95 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 58 insertions(+), 37 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 6a426e1..9e379b3 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1343,6 +1343,42 @@ DISAS_INSN(bitop_im)
         DEST_EA(env, insn, opsize, tmp, &addr);
     }
 }
+
+static TCGv gen_get_ccr(DisasContext *s)
+{
+    TCGv dest;
+
+    gen_flush_flags(s);
+    dest = tcg_temp_new();
+    tcg_gen_shli_i32(dest, QREG_CC_X, 4);
+    tcg_gen_or_i32(dest, dest, QREG_CC_DEST);
+    return dest;
+}
+
+static TCGv gen_get_sr(DisasContext *s)
+{
+    TCGv ccr;
+    TCGv sr;
+
+    ccr = gen_get_ccr(s);
+    sr = tcg_temp_new();
+    tcg_gen_andi_i32(sr, QREG_SR, 0xffe0);
+    tcg_gen_or_i32(sr, sr, ccr);
+    return sr;
+}
+
+static void gen_set_sr(DisasContext *s, TCGv val, int ccr_only)
+{
+    TCGv tmp;
+    tmp = tcg_temp_new();
+    tcg_gen_andi_i32(QREG_CC_DEST, val, 0xf);
+    tcg_gen_shri_i32(tmp, val, 4);
+    tcg_gen_andi_i32(QREG_CC_X, tmp, 1);
+    if (!ccr_only) {
+        gen_helper_set_sr(cpu_env, val);
+    }
+}
+
 DISAS_INSN(arith_im)
 {
     int op;
@@ -1367,7 +1403,20 @@ DISAS_INSN(arith_im)
     default:
        abort();
     }
-    SRC_EA(env, src1, opsize, -1, (op == 6) ? NULL : &addr);
+    if ((op == 0 || op == 1) &&
+        (insn & 0x3f) == 0x3c) {
+        if (opsize == OS_BYTE) {
+            src1 = gen_get_ccr(s);
+        } else {
+            if (IS_USER(s)) {
+                gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
+                return;
+            }
+            src1 = gen_get_sr(s);
+        }
+    } else {
+        SRC_EA(env, src1, opsize, -1, (op == 6) ? NULL : &addr);
+    }
     dest = tcg_temp_new();
     switch (op) {
     case 0: /* ori */
@@ -1405,7 +1454,14 @@ DISAS_INSN(arith_im)
     default:
         abort();
     }
-    DEST_EA(env, insn, opsize, dest, &addr);
+    if (op != 6) {
+        if ((op == 0 || op == 1) &&
+            (insn & 0x3f) == 0x3c) {
+            gen_set_sr(s, dest, opsize == OS_BYTE);
+        } else {
+            DEST_EA(env, insn, opsize, dest, &addr);
+        }
+    }
 }
 
 DISAS_INSN(byterev)
@@ -1488,17 +1544,6 @@ DISAS_INSN(clr)
     gen_logic_cc(s, zero, opsize);
 }
 
-static TCGv gen_get_ccr(DisasContext *s)
-{
-    TCGv dest;
-
-    gen_flush_flags(s);
-    dest = tcg_temp_new();
-    tcg_gen_shli_i32(dest, QREG_CC_X, 4);
-    tcg_gen_or_i32(dest, dest, QREG_CC_DEST);
-    return dest;
-}
-
 DISAS_INSN(move_from_ccr)
 {
     TCGv reg;
@@ -1536,18 +1581,6 @@ static void gen_set_sr_im(DisasContext *s, uint16_t val, 
int ccr_only)
     set_cc_op(s, CC_OP_FLAGS);
 }
 
-static void gen_set_sr(DisasContext *s, TCGv val, int ccr_only)
-{
-    TCGv tmp;
-    tmp = tcg_temp_new();
-    tcg_gen_andi_i32(QREG_CC_DEST, val, 0xf);
-    tcg_gen_shri_i32(tmp, val, 4);
-    tcg_gen_andi_i32(QREG_CC_X, tmp, 1);
-    if (!ccr_only) {
-        gen_helper_set_sr(cpu_env, val);
-    }
-}
-
 static void gen_move_to_sr(CPUM68KState *env, DisasContext *s, uint16_t insn,
                            int ccr_only)
 {
@@ -2068,18 +2101,6 @@ DISAS_INSN(ff1)
     gen_helper_ff1(reg, reg);
 }
 
-static TCGv gen_get_sr(DisasContext *s)
-{
-    TCGv ccr;
-    TCGv sr;
-
-    ccr = gen_get_ccr(s);
-    sr = tcg_temp_new();
-    tcg_gen_andi_i32(sr, QREG_SR, 0xffe0);
-    tcg_gen_or_i32(sr, sr, ccr);
-    return sr;
-}
-
 DISAS_INSN(strldsr)
 {
     uint16_t ext;
-- 
2.4.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]