All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [M68K] Full extension word format addressing mode
@ 2007-05-26 13:04 Andreas Schwab
  2007-05-26 21:16 ` Paul Brook
  0 siblings, 1 reply; 3+ messages in thread
From: Andreas Schwab @ 2007-05-26 13:04 UTC (permalink / raw)
  To: qemu-devel

This patch implements the full extension word format addressing mode in
the m68k emulation.  I have manually verified that it gets all cases
right.

Andreas.

Index: target-m68k/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/translate.c,v
retrieving revision 1.5
diff -u -a -p -a -u -p -r1.5 target-m68k/translate.c
--- target-m68k/translate.c	23 May 2007 19:58:11 -0000	1.5
+++ target-m68k/translate.c	26 May 2007 12:56:00 -0000
@@ -217,6 +217,18 @@ static int gen_ldst(DisasContext *s, int
     }
 }
 
+/* Read a 32-bit immediate constant.  */
+static inline uint32_t read_im32(DisasContext *s)
+{
+    uint32_t im;
+    im = ((uint32_t)lduw_code(s->pc)) << 16;
+    s->pc += 2;
+    im |= lduw_code(s->pc);
+    s->pc += 2;
+    return im;
+}
+
+
 /* Handle a base + index + displacement effective addresss.  A base of
    -1 means pc-relative.  */
 static int gen_lea_indexed(DisasContext *s, int opsize, int base)
@@ -226,41 +238,105 @@ static int gen_lea_indexed(DisasContext 
     uint16_t ext;
     int add;
     int tmp;
+    uint32_t bd, od;
 
     offset = s->pc;
     ext = lduw_code(s->pc);
     s->pc += 2;
-    tmp = ((ext >> 12) & 7) + ((ext & 0x8000) ? QREG_A0 : QREG_D0);
-    /* ??? Check W/L bit.  */
-    scale = (ext >> 9) & 3;
-    if (scale == 0) {
-        add = tmp;
-    } else {
-        add = gen_new_qreg(QMODE_I32);
-        gen_op_shl32(add, tmp, gen_im32(scale));
-    }
-    tmp = gen_new_qreg(QMODE_I32);
-    if (base != -1) {
-        gen_op_add32(tmp, base, gen_im32((int8_t)ext));
-        gen_op_add32(tmp, tmp, add);
-    } else {
-        gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
+    if (ext & 0x100) {
+	/* full extension word format */
+	if ((ext & 0x30) > 0x10)
+	    /* base displacement */
+	    if ((ext & 0x30) == 0x20) {
+		bd = (int16_t)lduw_code(s->pc);
+		s->pc += 2;
+	    } else
+		bd = read_im32(s);
+	else
+	    bd = 0;
+	if ((ext & 0x40) == 0) {
+	    /* index not suppressed */
+	    add = ((ext >> 12) & 7) + ((ext & 0x8000) ? QREG_A0 : QREG_D0);
+	    if ((ext & 0x800) == 0) {
+		tmp = gen_new_qreg(QMODE_I32);
+		gen_op_ext16s32(tmp, add);
+		add = tmp;
+	    }
+	    scale = (ext >> 9) & 3;
+	    if (scale != 0) {
+		if ((ext & 0x800) == 0)
+		    tmp = add;
+		else
+		    tmp = gen_new_qreg(QMODE_I32);
+		gen_op_shl32(tmp, add, gen_im32(scale));
+		add = tmp;
+	    }
+	}
+	if ((ext & 0x80) == 0) {
+	    /* base not suppressed */
+	    if (base == -1)
+		tmp = gen_im32(offset + bd);
+	    else if (bd != 0) {
+		tmp = gen_new_qreg(QMODE_I32);
+		gen_op_add32(tmp, base, gen_im32(bd));
+	    } else
+		tmp = base;
+	    if ((ext & 0x44) == 0)
+		gen_op_add32(tmp, tmp, add);
+	} else if (bd != 0) {
+	    tmp = gen_im32(bd);
+	    if ((ext & 0x44) == 0)
+		gen_op_add32(tmp, tmp, add);
+	} else if ((ext & 0x44) == 0)
+	    tmp = add;
+	else
+	    tmp = gen_im32(0);
+	if ((ext & 3) != 0) {
+	    /* memory indirect */
+	    tmp = gen_load(s, OS_LONG, tmp, 0);
+	    if ((ext & 0x44) == 4)
+		gen_op_add32(tmp, tmp, add);
+	    if ((ext & 3) > 1)
+		/* outer displacement */
+		if ((ext & 3) == 2) {
+		    od = (int16_t)lduw_code(s->pc);
+		    s->pc += 2;
+		} else
+		    od = read_im32(s);
+	    else
+		od = 0;
+	    if (od != 0)
+		gen_op_add32(tmp, tmp, gen_im32(od));
+	}
+    } else {
+	/* brief extension word format */
+	tmp = ((ext >> 12) & 7) + ((ext & 0x8000) ? QREG_A0 : QREG_D0);
+	if ((ext & 0x800) == 0) {
+	    add = gen_new_qreg(QMODE_I32);
+	    gen_op_ext16s32(add, tmp);
+	    tmp = add;
+	}
+	scale = (ext >> 9) & 3;
+	if (scale == 0) {
+	    add = tmp;
+	} else {
+	    if ((ext & 0x800) == 0)
+		add = tmp;
+	    else
+		add = gen_new_qreg(QMODE_I32);
+	    gen_op_shl32(add, tmp, gen_im32(scale));
+	}
+	tmp = gen_new_qreg(QMODE_I32);
+	if (base != -1) {
+	    gen_op_add32(tmp, base, gen_im32((int8_t)ext));
+	    gen_op_add32(tmp, tmp, add);
+	} else {
+	    gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
+	}
     }
     return tmp;
 }
 
-/* Read a 32-bit immediate constant.  */
-static inline uint32_t read_im32(DisasContext *s)
-{
-    uint32_t im;
-    im = ((uint32_t)lduw_code(s->pc)) << 16;
-    s->pc += 2;
-    im |= lduw_code(s->pc);
-    s->pc += 2;
-    return im;
-}
-
-
 /* Update the CPU env CC_OP state.  */
 static inline void gen_flush_cc_op(DisasContext *s)
 {

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-05-26 22:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-26 13:04 [Qemu-devel] [M68K] Full extension word format addressing mode Andreas Schwab
2007-05-26 21:16 ` Paul Brook
2007-05-26 22:44   ` Andreas Schwab

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.