All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Vivier <laurent@vivier.eu>
To: qemu-devel@nongnu.org
Cc: Laurent Vivier <laurent@vivier.eu>
Subject: [Qemu-devel] [PATCH 4/6] target/m68k: add moves
Date: Tue,  9 Jan 2018 00:10:46 +0100	[thread overview]
Message-ID: <20180108231048.23966-5-laurent@vivier.eu> (raw)
In-Reply-To: <20180108231048.23966-1-laurent@vivier.eu>

and introduce SFC and DFC control registers.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target/m68k/cpu.h       |  2 ++
 target/m68k/helper.c    | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
 target/m68k/helper.h    |  2 ++
 target/m68k/monitor.c   |  2 ++
 target/m68k/op_helper.c |  4 +--
 target/m68k/qregs.def   |  2 ++
 target/m68k/translate.c | 74 ++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 166 insertions(+), 2 deletions(-)

diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 60e669c3b4..4877be93ec 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -137,6 +137,8 @@ typedef struct CPUM68KState {
     uint32_t mbar;
     uint32_t rambar0;
     uint32_t cacr;
+    uint32_t sfc;
+    uint32_t dfc;
 
     int pending_vector;
     int pending_level;
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index c5b436d382..090f50fa05 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
 #include "exec/gdbstub.h"
 
 #include "exec/helper-proto.h"
@@ -203,6 +204,12 @@ void HELPER(m68k_movec_to)(CPUM68KState *env, uint32_t reg, uint32_t val)
 
     switch (reg) {
     /* MC680[1234]0 */
+    case M68K_CR_SFC:
+        env->sfc = val & 7;
+        return;
+    case M68K_CR_DFC:
+        env->dfc = val & 7;
+        return;
     case M68K_CR_VBR:
         env->vbr = val;
         return;
@@ -254,6 +261,10 @@ uint32_t HELPER(m68k_movec_from)(CPUM68KState *env, uint32_t reg)
 
     switch (reg) {
     /* MC680[1234]0 */
+    case M68K_CR_SFC:
+        return env->sfc;
+    case M68K_CR_DFC:
+        return env->dfc;
     case M68K_CR_VBR:
         return env->vbr;
     /* MC680[234]0 */
@@ -1066,6 +1077,77 @@ void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
 }
 
 #if defined(CONFIG_SOFTMMU)
+void HELPER(moves_store)(CPUM68KState *env, uint32_t val,
+                         uint32_t addr, uint32_t size)
+{
+    if (env->dfc & 4) { /* kernel */
+        switch (size) {
+        case OS_BYTE:
+            cpu_stb_kernel_ra(env, addr, val, GETPC());
+            break;
+        case OS_WORD:
+            cpu_stw_kernel_ra(env, addr, val, GETPC());
+            break;
+        case OS_LONG:
+            cpu_stl_kernel_ra(env, addr, val, GETPC());
+            break;
+        default:
+            g_assert_not_reached();
+        }
+    } else { /* user */
+        switch (size) {
+        case OS_BYTE:
+            cpu_stb_user_ra(env, addr, val, GETPC());
+            break;
+        case OS_WORD:
+            cpu_stw_user_ra(env, addr, val, GETPC());
+            break;
+        case OS_LONG:
+            cpu_stl_user_ra(env, addr, val, GETPC());
+            break;
+        default:
+            g_assert_not_reached();
+        }
+    }
+}
+
+uint32_t HELPER(moves_load)(CPUM68KState *env, uint32_t addr, uint32_t size)
+{
+    uint32_t val;
+
+    if (env->sfc & 4) { /* kernel */
+        switch (size) {
+        case OS_BYTE:
+            val = cpu_ldub_kernel_ra(env, addr, GETPC());
+            break;
+        case OS_WORD:
+            val = cpu_lduw_kernel_ra(env, addr, GETPC());
+            break;
+        case OS_LONG:
+            val = cpu_ldl_kernel_ra(env, addr, GETPC());
+            break;
+        default:
+            g_assert_not_reached();
+        }
+    } else { /* user */
+        switch (size) {
+        case OS_BYTE:
+            val = cpu_ldub_user_ra(env, addr, GETPC());
+            break;
+        case OS_WORD:
+            val = cpu_lduw_user_ra(env, addr, GETPC());
+            break;
+        case OS_LONG:
+            val = cpu_ldl_user_ra(env, addr, GETPC());
+            break;
+        default:
+            g_assert_not_reached();
+        }
+    }
+
+    return val;
+}
+
 void HELPER(reset)(CPUM68KState *env)
 {
     /* FIXME: reset all except CPU */
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 57f210aa14..620c6d5686 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -101,5 +101,7 @@ DEF_HELPER_3(chk, void, env, s32, s32)
 DEF_HELPER_4(chk2, void, env, s32, s32, s32)
 
 #if defined(CONFIG_SOFTMMU)
+DEF_HELPER_FLAGS_4(moves_store, TCG_CALL_NO_WG, void, env, i32, i32, i32)
+DEF_HELPER_FLAGS_3(moves_load, TCG_CALL_NO_WG, i32, env, i32, i32)
 DEF_HELPER_FLAGS_1(reset, TCG_CALL_NO_RWG, void, env)
 #endif
diff --git a/target/m68k/monitor.c b/target/m68k/monitor.c
index a20af6b09c..c31feb4b02 100644
--- a/target/m68k/monitor.c
+++ b/target/m68k/monitor.c
@@ -31,6 +31,8 @@ static const MonitorDef monitor_defs[] = {
     { "ssp", offsetof(CPUM68KState, sp[0]) },
     { "usp", offsetof(CPUM68KState, sp[1]) },
     { "isp", offsetof(CPUM68KState, sp[2]) },
+    { "sfc", offsetof(CPUM68KState, sfc) },
+    { "dfc", offsetof(CPUM68KState, dfc) },
     { "urp", offsetof(CPUM68KState, mmu.urp) },
     { "srp", offsetof(CPUM68KState, mmu.srp) },
     { "dttr0", offsetof(CPUM68KState, mmu.ttr[M68K_DTTR0]) },
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 83ac1e669e..6bf16695ac 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -400,8 +400,8 @@ static void m68k_interrupt_all(CPUM68KState *env, int is_hw)
         mmu_fault = 0;
         if (qemu_loglevel_mask(CPU_LOG_INT)) {
             qemu_log("            "
-                     "ssw:  %08x ea:   %08x\n",
-                     env->mmu.ssw, env->mmu.ar);
+                     "ssw:  %08x ea:   %08x sfc:  %d    dfc: %d\n",
+                     env->mmu.ssw, env->mmu.ar, env->sfc, env->dfc);
         }
     } else if (cs->exception_index == EXCP_ADDRESS) {
         do_stack_frame(env, &sp, 2, oldsr, 0, retaddr);
diff --git a/target/m68k/qregs.def b/target/m68k/qregs.def
index 1aadc622db..efe2bf90ee 100644
--- a/target/m68k/qregs.def
+++ b/target/m68k/qregs.def
@@ -1,5 +1,7 @@
 DEFO32(PC, pc)
 DEFO32(SR, sr)
+DEFO32(DFC, dfc)
+DEFO32(SFC, sfc)
 DEFO32(CC_OP, cc_op)
 DEFO32(CC_X, cc_x)
 DEFO32(CC_C, cc_c)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index af70825480..7cb0e12ee7 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -48,6 +48,8 @@ static char cpu_reg_names[2 * 8 * 3 + 5 * 4];
 static TCGv cpu_dregs[8];
 static TCGv cpu_aregs[8];
 static TCGv_i64 cpu_macc[4];
+static TCGv QEMU_DFC;
+static TCGv QEMU_SFC;
 
 #define REG(insn, pos)  (((insn) >> (pos)) & 7)
 #define DREG(insn, pos) cpu_dregs[REG(insn, pos)]
@@ -103,6 +105,10 @@ void m68k_tcg_init(void)
         p += 5;
     }
 
+    QEMU_DFC = tcg_global_mem_new(cpu_env, offsetof(CPUM68KState, dfc),
+                                  "DFC");
+    QEMU_SFC = tcg_global_mem_new(cpu_env, offsetof(CPUM68KState, sfc),
+                                  "SFC");
     NULL_QREG = tcg_global_mem_new(cpu_env, -4, "NULL");
     store_dummy = tcg_global_mem_new(cpu_env, -8, "NULL");
 }
@@ -4449,6 +4455,70 @@ DISAS_INSN(move_from_sr)
 }
 
 #if defined(CONFIG_SOFTMMU)
+DISAS_INSN(moves)
+{
+    int opsize;
+    uint16_t ext;
+    TCGv reg;
+    TCGv addr;
+    TCGv size;
+    int extend;
+
+    if (IS_USER(s)) {
+        gen_exception(s, s->insn_pc, EXCP_PRIVILEGE);
+        return;
+    }
+
+    ext = read_im16(env, s);
+
+    opsize = insn_opsize(insn);
+
+    if (ext & 0x8000) {
+        /* address register */
+        reg = AREG(ext, 12);
+        extend = 1;
+    } else {
+        /* data register */
+        reg = DREG(ext, 12);
+        extend = 0;
+    }
+
+    addr = gen_lea(env, s, insn, opsize);
+    if (IS_NULL_QREG(addr)) {
+        gen_addr_fault(s);
+        return;
+    }
+
+    size = tcg_const_i32(opsize);
+    if (ext & 0x0800) {
+        /* from reg to ea */
+        gen_helper_moves_store(cpu_env, reg, addr, size);
+    } else {
+        /* from ea to reg */
+        TCGv tmp = tcg_temp_new();
+        gen_helper_moves_load(tmp, cpu_env, addr, size);
+        if (extend) {
+            gen_ext(reg, tmp, opsize, 1);
+        } else {
+            gen_partset_reg(opsize, reg, tmp);
+        }
+        tcg_temp_free(tmp);
+    }
+    tcg_temp_free(size);
+
+    switch (extract32(insn, 3, 3)) {
+    case 3: /* Indirect postincrement.  */
+        tcg_gen_addi_i32(AREG(insn, 0), addr,
+                         REG(insn, 0) == 7 && opsize == OS_BYTE
+                         ? 2
+                         : opsize_bytes(opsize));
+        break;
+    case 4: /* Indirect predecrememnt.  */
+        tcg_gen_mov_i32(AREG(insn, 0), addr);
+        break;
+    }
+}
+
 DISAS_INSN(move_to_sr)
 {
     if (IS_USER(s)) {
@@ -5601,6 +5671,9 @@ void register_m68k_insns (CPUM68KState *env)
     BASE(bitop_im,  08c0, ffc0);
     INSN(arith_im,  0a80, fff8, CF_ISA_A);
     INSN(arith_im,  0a00, ff00, M68000);
+#if defined(CONFIG_SOFTMMU)
+    INSN(moves,     0e00, ff00, M68000);
+#endif
     INSN(cas,       0ac0, ffc0, CAS);
     INSN(cas,       0cc0, ffc0, CAS);
     INSN(cas,       0ec0, ffc0, CAS);
@@ -5981,6 +6054,7 @@ void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                env->current_sp == M68K_USP ? "->" : "  ", env->sp[M68K_USP],
                env->current_sp == M68K_ISP ? "->" : "  ", env->sp[M68K_ISP]);
     cpu_fprintf(f, "VBR = 0x%08x\n", env->vbr);
+    cpu_fprintf(f, "SFC = %x DFC %x\n", env->sfc, env->dfc);
     cpu_fprintf(f, "SSW %08x TCR %08x URP %08x SRP %08x\n",
                 env->mmu.ssw, env->mmu.tcr, env->mmu.urp, env->mmu.srp);
     cpu_fprintf(f, "DTTR0/1: %08x/%08x ITTR0/1: %08x/%08x\n",
-- 
2.14.3

  parent reply	other threads:[~2018-01-08 23:11 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-08 23:10 [Qemu-devel] [PATCH 0/6] target/m68k: supervisor mode (part 2) Laurent Vivier
2018-01-08 23:10 ` [Qemu-devel] [PATCH 1/6] accel/tcg: add size paremeter in tlb_fill() Laurent Vivier
2018-01-10  8:43   ` [Qemu-devel] [qemu-s390x] " David Hildenbrand
2018-01-10 13:42     ` Laurent Vivier
2018-01-10 18:47       ` Richard Henderson
2018-01-08 23:10 ` [Qemu-devel] [PATCH 2/6] target/m68k: add MC68040 MMU Laurent Vivier
2018-01-10 20:12   ` Richard Henderson
2018-01-12 18:46     ` Laurent Vivier
2018-01-08 23:10 ` [Qemu-devel] [PATCH 3/6] target/m68k: add Transparent Translation Laurent Vivier
2018-01-10 21:08   ` Richard Henderson
2018-01-08 23:10 ` Laurent Vivier [this message]
2018-01-10 21:22   ` [Qemu-devel] [PATCH 4/6] target/m68k: add moves Richard Henderson
2018-01-08 23:10 ` [Qemu-devel] [PATCH 5/6] target/m68k: add pflush/ptest Laurent Vivier
2018-01-10 21:25   ` Richard Henderson
2018-01-08 23:10 ` [Qemu-devel] [PATCH 6/6] target/m68k: add HMP command "info tlb" Laurent Vivier
2018-01-10 21:27   ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180108231048.23966-5-laurent@vivier.eu \
    --to=laurent@vivier.eu \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.