* [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
* Re: [Qemu-devel] [M68K] Full extension word format addressing mode
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
0 siblings, 1 reply; 3+ messages in thread
From: Paul Brook @ 2007-05-26 21:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Schwab
On Saturday 26 May 2007, Andreas Schwab wrote:
> This patch implements the full extension word format addressing mode in
> the m68k emulation. I have manually verified that it gets all cases
> right.
> + 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);
This corrupts a2 in the following instruction:
move.l ([%a2,%a1.l],0),%a0
I've fixed that and tweaked how temporary variables are used.
Paul
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [M68K] Full extension word format addressing mode
2007-05-26 21:16 ` Paul Brook
@ 2007-05-26 22:44 ` Andreas Schwab
0 siblings, 0 replies; 3+ messages in thread
From: Andreas Schwab @ 2007-05-26 22:44 UTC (permalink / raw)
To: Paul Brook; +Cc: qemu-devel
Paul Brook <paul@codesourcery.com> writes:
> On Saturday 26 May 2007, Andreas Schwab wrote:
>> This patch implements the full extension word format addressing mode in
>> the m68k emulation. I have manually verified that it gets all cases
>> right.
>
>> + 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);
>
> This corrupts a2 in the following instruction:
>
> move.l ([%a2,%a1.l],0),%a0
>
> I've fixed that and tweaked how temporary variables are used.
Thanks. Here's a patch for a small typo:
Index: translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/translate.c,v
retrieving revision 1.9
diff -u -a -p -u -p -a -r1.9 translate.c
--- translate.c 26 May 2007 22:11:13 -0000 1.9
+++ translate.c 26 May 2007 22:42:35 -0000
@@ -313,7 +313,7 @@ static int gen_lea_indexed(DisasContext
od = 0;
}
if (od != 0) {
- gen_op_add32(add, tmp, gen_im32(od));
+ gen_op_add32(tmp, add, gen_im32(od));
add = tmp;
}
}
Andreas.
--
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.