summaryrefslogtreecommitdiff
path: root/tcg/i386
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2010-04-14 08:06:00 -0700
committerAurelien Jarno <aurelien@aurel32.net>2010-05-20 21:15:09 +0200
commita042ef9470e1111bd5f5f84def886040345baabc (patch)
treead3fd4110a4318db481dcc7ad88c4ad9da19fa5d /tcg/i386
parentaf2660894f1d71cd8c9edeb19230f0336e320bcd (diff)
tcg-i386: Eliminate extra move from qemu_ld64.
If the address register overlaps one of the output registers simply issue the clobbering load last, rather than emitting an extra move of the address register. Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'tcg/i386')
-rw-r--r--tcg/i386/tcg-target.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 4b88138390..11e3661170 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -744,22 +744,20 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
}
break;
case 3:
- /* XXX: could be nicer */
- if (r0 == data_reg) {
- r1 = TCG_REG_EDX;
- if (r1 == data_reg)
- r1 = TCG_REG_EAX;
- tcg_out_mov(s, r1, r0);
- r0 = r1;
+ if (bswap) {
+ int t = data_reg;
+ data_reg = data_reg2;
+ data_reg2 = t;
}
- if (!bswap) {
+ if (r0 != data_reg) {
tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
tcg_out_ld(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE + 4);
} else {
- tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE + 4);
+ tcg_out_ld(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE + 4);
+ tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
+ }
+ if (bswap) {
tcg_out_bswap32(s, data_reg);
-
- tcg_out_ld(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE);
tcg_out_bswap32(s, data_reg2);
}
break;