qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 024/111] m68k: add cas


From: Bryce Lanham
Subject: [Qemu-devel] [PATCH 024/111] m68k: add cas
Date: Wed, 17 Aug 2011 15:46:29 -0500

From: Laurent Vivier <address@hidden>

This instruction is needed to execute commands like "ls" or "date"
(from a debian lenny m68k).

It define a new feaure, CAS, and attach this new instruction to it.

Signed-off-by: Laurent Vivier <address@hidden>
---
 target-m68k/cpu.h       |    3 +-
 target-m68k/helper.c    |    2 +
 target-m68k/translate.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 1 deletions(-)

diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 91d3141..ae4f6fa 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -210,7 +210,8 @@ enum m68k_features {
     M68K_FEATURE_QUAD_MULDIV,  /* 64 bit multiply/divide. */
     M68K_FEATURE_BCCL,         /* Long conditional branches.  */
     M68K_FEATURE_BITFIELD,     /* Bit field insns.  */
-    M68K_FEATURE_FPU
+    M68K_FEATURE_FPU,
+    M68K_FEATURE_CAS
 };
 
 static inline int m68k_feature(CPUM68KState *env, int feature)
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index fd9867d..d0fc155 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -165,6 +165,7 @@ static int cpu_m68k_set_model(CPUM68KState *env, const char 
*name)
         m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX);
         m68k_set_feature(env, M68K_FEATURE_LONG_MULDIV);
         m68k_set_feature(env, M68K_FEATURE_FPU);
+        m68k_set_feature(env, M68K_FEATURE_CAS);
     case M68K_CPUID_M68000:
         m68k_set_feature(env, M68K_FEATURE_M68000);
         m68k_set_feature(env, M68K_FEATURE_USP);
@@ -210,6 +211,7 @@ static int cpu_m68k_set_model(CPUM68KState *env, const char 
*name)
         m68k_set_feature(env, M68K_FEATURE_BITFIELD);
         m68k_set_feature(env, M68K_FEATURE_LONG_MULDIV);
         m68k_set_feature(env, M68K_FEATURE_QUAD_MULDIV);
+        m68k_set_feature(env, M68K_FEATURE_CAS);
         break;
     }
 
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index fa67ff9..c186fe1 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1371,6 +1371,67 @@ DISAS_INSN(arith_im)
     }
 }
 
+DISAS_INSN(cas)
+{
+    int opsize;
+    TCGv dest;
+    TCGv tmp;
+    TCGv cmp;
+    TCGv update;
+    TCGv addr;
+    TCGv res;
+    uint16_t ext;
+    int l1, l2;
+
+    if ((insn & 0x3f) == 0x3c) {
+        /* CAS2: Not yet implemented */
+        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
+    }
+
+    switch((insn >> 9) & 3) {
+    case 1:
+        opsize = OS_BYTE;
+        break;
+    case 2:
+        opsize = OS_WORD;
+        break;
+    case 3:
+        opsize = OS_LONG;
+        break;
+    default:
+        abort();
+    }
+
+    ext = lduw_code(s->pc);
+    s->pc += 2;
+    addr = gen_lea(s, insn, opsize);
+    if (IS_NULL_QREG(addr)) {
+        gen_addr_fault(s);
+        return;
+    }
+
+    cmp = DREG(ext, 0);
+    update = DREG(ext, 6);
+    tmp = gen_load(s, opsize, addr, 0);
+    dest = tcg_temp_local_new();
+    tcg_gen_mov_i32(dest, tmp);
+
+    res = tcg_temp_new();
+    tcg_gen_sub_i32(res, dest, cmp);
+    gen_logic_cc(s, res);
+
+    l1 = gen_new_label();
+    l2 = gen_new_label();
+
+    gen_jmpcc(s, 6 /* !Z */, l1);
+    gen_store(s, opsize, addr, update);
+    tcg_gen_br(l2);
+    gen_set_label(l1);
+    tcg_gen_mov_i32(cmp, dest);
+    gen_set_label(l2);
+    tcg_temp_free(dest);
+}
+
 DISAS_INSN(byterev)
 {
     TCGv reg;
@@ -3660,6 +3721,7 @@ void register_m68k_insns (CPUM68KState *env)
     INSN(bitop_im,  0840, ffc0, M68000);
     INSN(bitop_im,  0880, ffc0, CF_ISA_A);
     INSN(bitop_im,  0880, ffc0, M68000);
+    INSN(cas,       08c0, f9c0, CAS);
     INSN(bitop_im,  08c0, ffc0, CF_ISA_A);
     INSN(bitop_im,  08c0, ffc0, M68000);
     INSN(arith_im,  0a80, fff8, CF_ISA_A);
-- 
1.7.2.3




reply via email to

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