|
From: <sv...@va...> - 2011-03-22 16:51:46
|
Author: sewardj
Date: 2011-03-22 16:51:38 +0000 (Tue, 22 Mar 2011)
New Revision: 2112
Log:
Emit Ain_Imm64 (64-bit immediate constant loads to register) using a
short form when the immediate is < 2^20. Gives a 3% code size
reduction for Helgrind with --ignore-stack-refs=yes.
Modified:
trunk/priv/host_amd64_defs.c
Modified: trunk/priv/host_amd64_defs.c
===================================================================
--- trunk/priv/host_amd64_defs.c 2011-03-15 12:41:30 UTC (rev 2111)
+++ trunk/priv/host_amd64_defs.c 2011-03-22 16:51:38 UTC (rev 2112)
@@ -2325,9 +2325,20 @@
switch (i->tag) {
case Ain_Imm64:
- *p++ = toUChar(0x48 + (1 & iregBit3(i->Ain.Imm64.dst)));
- *p++ = toUChar(0xB8 + iregBits210(i->Ain.Imm64.dst));
- p = emit64(p, i->Ain.Imm64.imm64);
+ if (i->Ain.Imm64.imm64 <= 0xFFFFFULL) {
+ /* Use the short form (load into 32 bit reg, + default
+ widening rule) for constants under 1 million. We could
+ use this form for the range 0 to 0x7FFFFFFF inclusive, but
+ limit it to a smaller range for verifiability purposes. */
+ if (1 & iregBit3(i->Ain.Imm64.dst))
+ *p++ = 0x41;
+ *p++ = 0xB8 + iregBits210(i->Ain.Imm64.dst);
+ p = emit32(p, (UInt)i->Ain.Imm64.imm64);
+ } else {
+ *p++ = toUChar(0x48 + (1 & iregBit3(i->Ain.Imm64.dst)));
+ *p++ = toUChar(0xB8 + iregBits210(i->Ain.Imm64.dst));
+ p = emit64(p, i->Ain.Imm64.imm64);
+ }
goto done;
case Ain_Alu64R:
@@ -2335,7 +2346,7 @@
if (i->Ain.Alu64R.op == Aalu_MOV) {
switch (i->Ain.Alu64R.src->tag) {
case Armi_Imm:
- if (0 == (i->Ain.Alu64R.src->Armi.Imm.imm32 & ~0xFFF)) {
+ if (0 == (i->Ain.Alu64R.src->Armi.Imm.imm32 & ~0xFFFFF)) {
/* Actually we could use this form for constants in
the range 0 through 0x7FFFFFFF inclusive, but
limit it to a small range for verifiability
|