Patchwork [024/111] m68k: add cas

login
register
mail settings
Submitter Bryce Lanham
Date Aug. 17, 2011, 8:46 p.m.
Message ID <1313614076-28878-25-git-send-email-blanham@gmail.com>
Download mbox | patch
Permalink /patch/110473/
State New
Headers show

Comments

Bryce Lanham - Aug. 17, 2011, 8:46 p.m.
From: Laurent Vivier <laurent@vivier.eu>

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 <laurent@vivier.eu>
---
 target-m68k/cpu.h       |    3 +-
 target-m68k/helper.c    |    2 +
 target-m68k/translate.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 1 deletions(-)

Patch

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);