summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <ssp@redhat.com>2013-12-27 21:06:08 -0500
committerSøren Sandmann <ssp@redhat.com>2013-12-27 21:06:08 -0500
commitf250c220d37784f741e14fccbfdfa1966a78ff79 (patch)
tree91997e3d8e8e94bdb1bf24fd466b635eb80beffd
parentdfcef308a3dc4581bcd3868c412d8a85e2bf8590 (diff)
Fix handling of r12
r12 is the rex extended version of rsp and so requires special handling when generating mod/rm bytes.
-rw-r--r--simplex86.c9
-rw-r--r--testsuite.c3
2 files changed, 7 insertions, 5 deletions
diff --git a/simplex86.c b/simplex86.c
index ea06efe..3405fdb 100644
--- a/simplex86.c
+++ b/simplex86.c
@@ -1772,6 +1772,7 @@ emit_reg_regm (uint8_t *c, op_t reg, op_t regm,
int index_regno = GET_REGNO (index);
int ebp_regno = GET_REGNO (ebp);
int esp_regno = GET_REGNO (esp);
+ int r12_regno = GET_REGNO (r12);
int r13_regno = GET_REGNO (r13);
if (index_regno == esp_regno)
@@ -1799,23 +1800,23 @@ emit_reg_regm (uint8_t *c, op_t reg, op_t regm,
c = emit_address_byte (c, 0, reg_regno, 5, r, NULL);
c = emit_imm32 (c, disp);
}
- else if (base_regno == esp_regno)
+ else if (base_regno == esp_regno || base_regno == r12_regno)
{
if (disp == 0)
{
c = emit_address_byte (c, 0, reg_regno, esp_regno, r, NULL);
- c = emit_address_byte (c, 0, esp_regno, esp_regno, x, b);
+ c = emit_address_byte (c, 0, esp_regno, base_regno, x, b);
}
else if (IS_S8 (disp))
{
c = emit_address_byte (c, 1, reg_regno, esp_regno, r, NULL);
- c = emit_address_byte (c, 0, esp_regno, esp_regno, x, b);
+ c = emit_address_byte (c, 0, esp_regno, base_regno, x, b);
c = emit_imm8 (c, disp);
}
else
{
c = emit_address_byte (c, 2, reg_regno, esp_regno, r, NULL);
- c = emit_address_byte (c, 0, esp_regno, esp_regno, x, b);
+ c = emit_address_byte (c, 0, esp_regno, base_regno, x, b);
c = emit_imm32 (c, disp);
}
}
diff --git a/testsuite.c b/testsuite.c
index 6e41e0d..989f0b8 100644
--- a/testsuite.c
+++ b/testsuite.c
@@ -220,6 +220,7 @@ test_movd (assembler_t *as)
BEGIN_ASM (frag)
I_movd, DWORD_PTR + PTR (rdx), xmm0,
+ I_movd, xmm5, DWORD_PTR + PTR (r12),
END_ASM ();
return assembler_link (as, frag, NULL);
@@ -489,7 +490,7 @@ main ()
success &= run_test (as, "test_riprel", test_riprel, 0xf5497642);
success &= run_test (as, "test_movdq", test_movdq, 0xedd4f79d);
success &= run_test (as, "test_pshuflw", test_pshuflw, 0x7a8c7f59);
- success &= run_test (as, "test_movd", test_movd, 0xc33d08fb);
+ success &= run_test (as, "test_movd", test_movd, 0xcb69ef60);
if (success)
printf ("Test suite PASSED\n");