From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: laurent@vivier.eu
Subject: [Qemu-devel] [PATCH v2 1/5] target-m68k: Implement 680x0 movem
Date: Wed, 9 Nov 2016 14:46:07 +0100 [thread overview]
Message-ID: <1478699171-10637-2-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1478699171-10637-1-git-send-email-rth@twiddle.net>
From: Laurent Vivier <laurent@vivier.eu>
680x0 movem can load/store words and long words and can use more
addressing modes. Coldfire can only use long words with (Ax) and
(d16,Ax) addressing modes.
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-m68k/translate.c | 130 +++++++++++++++++++++++++++++++++++++++---------
1 file changed, 107 insertions(+), 23 deletions(-)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 5d91e4e..ca99072 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1793,40 +1793,122 @@ static void gen_push(DisasContext *s, TCGv val)
tcg_gen_mov_i32(QREG_SP, tmp);
}
+static TCGv mreg(int reg)
+{
+ if (reg < 8) {
+ /* Dx */
+ return cpu_dregs[reg];
+ }
+ /* Ax */
+ return cpu_aregs[reg & 7];
+}
+
DISAS_INSN(movem)
{
- TCGv addr;
+ TCGv addr, incr, tmp, r[16];
+ int is_load = (insn & 0x0400) != 0;
+ int opsize = (insn & 0x40) != 0 ? OS_LONG : OS_WORD;
+ uint16_t mask = read_im16(env, s);
+ int mode = extract32(insn, 3, 3);
+ int reg0 = REG(insn, 0);
int i;
- uint16_t mask;
- TCGv reg;
- TCGv tmp;
- int is_load;
- mask = read_im16(env, s);
- tmp = gen_lea(env, s, insn, OS_LONG);
- if (IS_NULL_QREG(tmp)) {
+ tmp = cpu_aregs[reg0];
+
+ switch (mode) {
+ case 0: /* data register direct */
+ case 1: /* addr register direct */
+ do_addr_fault:
gen_addr_fault(s);
return;
+
+ case 2: /* indirect */
+ break;
+
+ case 3: /* indirect post-increment */
+ if (!is_load) {
+ /* post-increment is not allowed */
+ goto do_addr_fault;
+ }
+ break;
+
+ case 4: /* indirect pre-decrement */
+ if (is_load) {
+ /* pre-decrement is not allowed */
+ goto do_addr_fault;
+ }
+ /* We want a bare copy of the address reg, without any pre-decrement
+ adjustment, as gen_lea would provide. */
+ break;
+
+ default:
+ tmp = gen_lea_mode(env, s, mode, reg0, opsize);
+ if (IS_NULL_QREG(tmp)) {
+ goto do_addr_fault;
+ }
+ break;
}
+
addr = tcg_temp_new();
tcg_gen_mov_i32(addr, tmp);
- is_load = ((insn & 0x0400) != 0);
- for (i = 0; i < 16; i++, mask >>= 1) {
- if (mask & 1) {
- if (i < 8)
- reg = DREG(i, 0);
- else
- reg = AREG(i, 0);
- if (is_load) {
- tmp = gen_load(s, OS_LONG, addr, 0);
- tcg_gen_mov_i32(reg, tmp);
- } else {
- gen_store(s, OS_LONG, addr, reg);
+ incr = tcg_const_i32(opsize_bytes(opsize));
+
+ if (is_load) {
+ /* memory to register */
+ for (i = 0; i < 16; i++) {
+ if (mask & (1 << i)) {
+ r[i] = gen_load(s, opsize, addr, 1);
+ tcg_gen_add_i32(addr, addr, incr);
+ }
+ }
+ for (i = 0; i < 16; i++) {
+ if (mask & (1 << i)) {
+ tcg_gen_mov_i32(mreg(i), r[i]);
+ tcg_temp_free(r[i]);
+ }
+ }
+ if (mode == 3) {
+ /* post-increment: movem (An)+,X */
+ tcg_gen_mov_i32(cpu_aregs[reg0], addr);
+ }
+ } else {
+ /* register to memory */
+ if (mode == 4) {
+ /* pre-decrement: movem X,-(An) */
+ for (i = 15; i >= 0; i--) {
+ if ((mask << i) & 0x8000) {
+ tcg_gen_sub_i32(addr, addr, incr);
+ if (reg0 + 8 == i &&
+ m68k_feature(s->env, M68K_FEATURE_EXT_FULL)) {
+ /* M68020+: if the addressing register is the
+ * register moved to memory, the value written
+ * is the initial value decremented by the size of
+ * the operation, regardless of how many actual
+ * stores have been performed until this point.
+ * M68000/M68010: the value is the initial value.
+ */
+ tmp = tcg_temp_new();
+ tcg_gen_sub_i32(tmp, cpu_aregs[reg0], incr);
+ gen_store(s, opsize, addr, tmp);
+ tcg_temp_free(tmp);
+ } else {
+ gen_store(s, opsize, addr, mreg(i));
+ }
+ }
+ }
+ tcg_gen_mov_i32(cpu_aregs[reg0], addr);
+ } else {
+ for (i = 0; i < 16; i++) {
+ if (mask & (1 << i)) {
+ gen_store(s, opsize, addr, mreg(i));
+ tcg_gen_add_i32(addr, addr, incr);
+ }
}
- if (mask != 1)
- tcg_gen_addi_i32(addr, addr, 4);
}
}
+
+ tcg_temp_free(incr);
+ tcg_temp_free(addr);
}
DISAS_INSN(bitop_im)
@@ -4029,7 +4111,9 @@ void register_m68k_insns (CPUM68KState *env)
BASE(pea, 4840, ffc0);
BASE(swap, 4840, fff8);
INSN(bkpt, 4848, fff8, BKPT);
- BASE(movem, 48c0, fbc0);
+ INSN(movem, 48d0, fbf8, CF_ISA_A);
+ INSN(movem, 48e8, fbf8, CF_ISA_A);
+ INSN(movem, 4880, fb80, M68000);
BASE(ext, 4880, fff8);
BASE(ext, 48c0, fff8);
BASE(ext, 49c0, fff8);
--
2.7.4
next prev parent reply other threads:[~2016-11-09 13:46 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-09 13:46 [Qemu-devel] [PATCH v2 0/5] target-m68k-patches Richard Henderson
2016-11-09 13:46 ` Richard Henderson [this message]
2016-11-09 13:46 ` [Qemu-devel] [PATCH v2 2/5] target-m68k: Do not cpu_abort on undefined insns Richard Henderson
2016-11-09 13:46 ` [Qemu-devel] [PATCH v2 3/5] target-m68k: Inline shifts Richard Henderson
2016-11-27 17:53 ` Laurent Vivier
2016-11-28 14:35 ` Richard Henderson
2016-11-27 19:30 ` Laurent Vivier
2016-11-28 14:47 ` Richard Henderson
2016-11-27 19:35 ` Laurent Vivier
2016-11-28 14:54 ` Richard Henderson
2016-11-29 23:52 ` Laurent Vivier
2016-11-30 20:42 ` Richard Henderson
2016-11-09 13:46 ` [Qemu-devel] [PATCH v2 4/5] target-m68k: Implement bitfield ops for registers Richard Henderson
2016-11-27 19:46 ` Laurent Vivier
2016-11-28 14:55 ` Richard Henderson
2016-11-09 13:46 ` [Qemu-devel] [PATCH v2 5/5] target-m68k: Implement bitfield ops for memory Richard Henderson
2016-11-27 19:48 ` Laurent Vivier
2016-11-28 16:26 ` Richard Henderson
2016-11-09 14:31 ` [Qemu-devel] [PATCH v2 0/5] target-m68k-patches Laurent Vivier
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=1478699171-10637-2-git-send-email-rth@twiddle.net \
--to=rth@twiddle.net \
--cc=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.