|
From: <sv...@va...> - 2009-11-22 23:43:30
|
Author: sewardj
Date: 2009-11-22 23:43:17 +0000 (Sun, 22 Nov 2009)
New Revision: 1929
Log:
Use a shorter instruction encoding for "mov $smallish positive int, %reg".
Reduces generated code size by about 1% for Memcheck.
Modified:
trunk/priv/host_amd64_defs.c
Modified: trunk/priv/host_amd64_defs.c
===================================================================
--- trunk/priv/host_amd64_defs.c 2009-11-22 23:38:01 UTC (rev 1928)
+++ trunk/priv/host_amd64_defs.c 2009-11-22 23:43:17 UTC (rev 1929)
@@ -2335,10 +2335,26 @@
if (i->Ain.Alu64R.op == Aalu_MOV) {
switch (i->Ain.Alu64R.src->tag) {
case Armi_Imm:
- *p++ = toUChar(0x48 + (1 & iregBit3(i->Ain.Alu64R.dst)));
- *p++ = 0xC7;
- *p++ = toUChar(0xC0 + iregBits210(i->Ain.Alu64R.dst));
- p = emit32(p, i->Ain.Alu64R.src->Armi.Imm.imm32);
+ if (0 == (i->Ain.Alu64R.src->Armi.Imm.imm32 & ~0xFFF)) {
+ /* Actually we could use this form for constants in
+ the range 0 through 0x7FFFFFFF inclusive, but
+ limit it to a small range for verifiability
+ purposes. */
+ /* Generate "movl $imm32, 32-bit-register" and let
+ the default zero-extend rule cause the upper half
+ of the dst to be zeroed out too. This saves 1
+ and sometimes 2 bytes compared to the more
+ obvious encoding in the 'else' branch. */
+ if (1 & iregBit3(i->Ain.Alu64R.dst))
+ *p++ = 0x41;
+ *p++ = 0xB8 + iregBits210(i->Ain.Alu64R.dst);
+ p = emit32(p, i->Ain.Alu64R.src->Armi.Imm.imm32);
+ } else {
+ *p++ = toUChar(0x48 + (1 & iregBit3(i->Ain.Alu64R.dst)));
+ *p++ = 0xC7;
+ *p++ = toUChar(0xC0 + iregBits210(i->Ain.Alu64R.dst));
+ p = emit32(p, i->Ain.Alu64R.src->Armi.Imm.imm32);
+ }
goto done;
case Armi_Reg:
*p++ = rexAMode_R( i->Ain.Alu64R.src->Armi.Reg.reg,
|