aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Vivier <laurent@vivier.eu>2018-01-04 02:29:04 +0100
committerLaurent Vivier <laurent@vivier.eu>2018-01-04 17:24:34 +0100
commit9d4f0429f3dc1dc6c67de3eaa3106e6c1cfa1524 (patch)
tree90434aae22ec73b9d7d1ef8500d40ea415fce5b2
parent8bf6cbaf396a8b54b138bb8a7c3377f2868ed16e (diff)
downloadqemu-9d4f0429f3dc1dc6c67de3eaa3106e6c1cfa1524.zip
qemu-9d4f0429f3dc1dc6c67de3eaa3106e6c1cfa1524.tar.gz
qemu-9d4f0429f3dc1dc6c67de3eaa3106e6c1cfa1524.tar.bz2
target/m68k: add move16
move16 moves the source line to the destination line. Lines are aligned to 16-byte boundaries and are 16 bytes long. Signed-off-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20180104012913.30763-9-laurent@vivier.eu>
-rw-r--r--target/m68k/cpu.c10
-rw-r--r--target/m68k/cpu.h1
-rw-r--r--target/m68k/translate.c72
3 files changed, 82 insertions, 1 deletions
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 57ffcb2..1936efd 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -137,7 +137,15 @@ static void m68020_cpu_initfn(Object *obj)
m68k_set_feature(env, M68K_FEATURE_CHK2);
}
#define m68030_cpu_initfn m68020_cpu_initfn
-#define m68040_cpu_initfn m68020_cpu_initfn
+
+static void m68040_cpu_initfn(Object *obj)
+{
+ M68kCPU *cpu = M68K_CPU(obj);
+ CPUM68KState *env = &cpu->env;
+
+ m68020_cpu_initfn(obj);
+ m68k_set_feature(env, M68K_FEATURE_M68040);
+}
static void m68060_cpu_initfn(Object *obj)
{
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 68396bd..2ac4ab1 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -306,6 +306,7 @@ enum m68k_features {
M68K_FEATURE_BKPT,
M68K_FEATURE_RTD,
M68K_FEATURE_CHK2,
+ M68K_FEATURE_M68040, /* instructions specific to MC68040 */
};
static inline int m68k_feature(CPUM68KState *env, int feature)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 7f52065..0ef933a 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4277,6 +4277,76 @@ DISAS_INSN(chk2)
tcg_temp_free(reg);
}
+static void m68k_copy_line(TCGv dst, TCGv src, int index)
+{
+ TCGv addr;
+ TCGv_i64 t0, t1;
+
+ addr = tcg_temp_new();
+
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
+
+ tcg_gen_andi_i32(addr, src, ~15);
+ tcg_gen_qemu_ld64(t0, addr, index);
+ tcg_gen_addi_i32(addr, addr, 8);
+ tcg_gen_qemu_ld64(t1, addr, index);
+
+ tcg_gen_andi_i32(addr, dst, ~15);
+ tcg_gen_qemu_st64(t0, addr, index);
+ tcg_gen_addi_i32(addr, addr, 8);
+ tcg_gen_qemu_st64(t1, addr, index);
+
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
+ tcg_temp_free(addr);
+}
+
+DISAS_INSN(move16_reg)
+{
+ int index = IS_USER(s);
+ TCGv tmp;
+ uint16_t ext;
+
+ ext = read_im16(env, s);
+ if ((ext & (1 << 15)) == 0) {
+ gen_exception(s, s->insn_pc, EXCP_ILLEGAL);
+ }
+
+ m68k_copy_line(AREG(ext, 12), AREG(insn, 0), index);
+
+ /* Ax can be Ay, so save Ay before incrementing Ax */
+ tmp = tcg_temp_new();
+ tcg_gen_mov_i32(tmp, AREG(ext, 12));
+ tcg_gen_addi_i32(AREG(insn, 0), AREG(insn, 0), 16);
+ tcg_gen_addi_i32(AREG(ext, 12), tmp, 16);
+ tcg_temp_free(tmp);
+}
+
+DISAS_INSN(move16_mem)
+{
+ int index = IS_USER(s);
+ TCGv reg, addr;
+
+ reg = AREG(insn, 0);
+ addr = tcg_const_i32(read_im32(env, s));
+
+ if ((insn >> 3) & 1) {
+ /* MOVE16 (xxx).L, (Ay) */
+ m68k_copy_line(reg, addr, index);
+ } else {
+ /* MOVE16 (Ay), (xxx).L */
+ m68k_copy_line(addr, reg, index);
+ }
+
+ tcg_temp_free(addr);
+
+ if (((insn >> 3) & 2) == 0) {
+ /* (Ay)+ */
+ tcg_gen_addi_i32(reg, reg, 16);
+ }
+}
+
static TCGv gen_get_sr(DisasContext *s)
{
TCGv ccr;
@@ -5578,6 +5648,8 @@ void register_m68k_insns (CPUM68KState *env)
INSN(fsave, f300, ffc0, FPU);
INSN(intouch, f340, ffc0, CF_ISA_A);
INSN(cpushl, f428, ff38, CF_ISA_A);
+ INSN(move16_mem, f600, ffe0, M68040);
+ INSN(move16_reg, f620, fff8, M68040);
INSN(wddata, fb00, ff00, CF_ISA_A);
INSN(wdebug, fbc0, ffc0, CF_ISA_A);
#undef INSN