re PR target/49781 ([x32] Unnecessary lea in x32 mode)
authorUros Bizjak <uros@gcc.gnu.org>
Mon, 8 Aug 2011 14:59:19 +0000 (16:59 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 8 Aug 2011 14:59:19 +0000 (16:59 +0200)
PR target/49781
* config/i386/i386.c (ix86_decompose_address): Allow zero-extended
SImode addresses.
(ix86_print_operand_address): Handle zero-extended addresses.
(memory_address_length): Add length of addr32 prefix for
zero-extended addresses.
(ix86_secondary_reload): Handle moves to/from double-word general
registers from/to zero-extended addresses.
* config/i386/predicates.md (lea_address_operand): Reject
zero-extended operands.

From-SVN: r177566

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/predicates.md

index d1371d2b25d95be27003299d9ec255515d825432..79d104eba8d656b16b88f1708c141702d335998f 100644 (file)
@@ -1,8 +1,20 @@
+2011-08-07  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/49781
+       * config/i386/i386.c (ix86_decompose_address): Allow zero-extended
+       SImode addresses.
+       (ix86_print_operand_address): Handle zero-extended addresses.
+       (memory_address_length): Add length of addr32 prefix for
+       zero-extended addresses.
+       (ix86_secondary_reload): Handle moves to/from double-word general
+       registers from/to zero-extended addresses.
+       * config/i386/predicates.md (lea_address_operand): Reject
+       zero-extended operands.
+
 2011-08-08  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR other/48007
-       * config.gcc (libgcc_tm_file): Add i386/value-unwind.h for
-       Linux/x86.
+       * config.gcc (libgcc_tm_file): Add i386/value-unwind.h for Linux/x86.
 
        * system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.
        (ASSUME_EXTENDED_UNWIND_CONTEXT): Likewise.
 
        * config/sparc/driver-sparc.c: New file.
        * config/sparc/x-sparc: New file.
-       * config.host: Use driver-sparc.o, sparc/x-sparc on
-       sparc*-*-solaris2*.
-       * config/sparc/sparc.opt (native): New value for enum
-       processor_type.
+       * config.host: Use driver-sparc.o, sparc/x-sparc on sparc*-*-solaris2*.
+       * config/sparc/sparc.opt (native): New value for enum processor_type.
        * config/sparc/sparc-opts.h (PROCESSOR_NATIVE): Declare.
        * config/sparc/sparc.c (sparc_option_override): Abort if
        PROCESSOR_NATIVE gets here.
        (TARGET_INSTANTIATE_DECLS): New define.
 
 2011-08-06  Paolo Bonzini  <bonzini@gnu.org>
-            Mikael Morin   <mikael.morin@sfr.fr>
+           Mikael Morin   <mikael.morin@sfr.fr>
 
        * Makefile.in (INCLUDES_FOR_TARGET): New.
        (LIBGCC2_CFLAGS): Use it.
index 19dd24330c50287849ce0120eba92c3a3650b7a8..b50b3d018bbc83a37d3a38ffc5c866d54bbf90a6 100644 (file)
@@ -11142,6 +11142,14 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
   int retval = 1;
   enum ix86_address_seg seg = SEG_DEFAULT;
 
+  /* Allow zero-extended SImode addresses,
+     they will be emitted with addr32 prefix.  */
+  if (TARGET_64BIT
+      && GET_CODE (addr) == ZERO_EXTEND
+      && GET_MODE (addr) == DImode
+      && GET_MODE (XEXP (addr, 0)) == SImode)
+    addr = XEXP (addr, 0);
   if (REG_P (addr))
     base = addr;
   else if (GET_CODE (addr) == SUBREG)
@@ -14159,8 +14167,12 @@ ix86_print_operand_address (FILE *file, rtx addr)
     }
   else
     {
-      /* Print DImode registers on 64bit targets to avoid addr32 prefixes.  */
-      int code = TARGET_64BIT ? 'q' : 0;
+      int code = 0;
+
+      /* Print SImode registers for zero-extended addresses to force
+        addr32 prefix.  Otherwise print DImode registers to avoid it.  */
+      if (TARGET_64BIT)
+       code = (GET_CODE (addr) == ZERO_EXTEND) ? 'l' : 'q';
 
       if (ASSEMBLER_DIALECT == ASM_ATT)
        {
@@ -21772,7 +21784,8 @@ assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n)
 }
 \f
 /* Calculate the length of the memory address in the instruction
-   encoding.  Does not include the one-byte modrm, opcode, or prefix.  */
+   encoding.  Includes addr32 prefix, does not include the one-byte modrm,
+   opcode, or other prefixes.  */
 
 int
 memory_address_length (rtx addr)
@@ -21799,7 +21812,9 @@ memory_address_length (rtx addr)
   base = parts.base;
   index = parts.index;
   disp = parts.disp;
-  len = 0;
+
+  /* Add length of addr32 prefix.  */
+  len = (GET_CODE (addr) == ZERO_EXTEND);
 
   /* Rule of thumb:
        - esp as the base always wants an index,
@@ -28233,6 +28248,15 @@ ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
                       enum machine_mode mode,
                       secondary_reload_info *sri ATTRIBUTE_UNUSED)
 {
+  /* Double-word spills from general registers to non-offsettable memory
+     references (zero-extended addresses) go through XMM register.  */
+  if (TARGET_64BIT
+      && MEM_P (x)
+      && GET_MODE_SIZE (mode) > UNITS_PER_WORD
+      && rclass == GENERAL_REGS
+      && !offsettable_memref_p (x))
+    return SSE_REGS;
+
   /* QImode spills from non-QI registers require
      intermediate register on 32bit targets.  */
   if (!TARGET_64BIT
index 52ea3f3a2da389b418b61e6469f9f84655067477..cfcd061e1f645027eea90edb72b82cfca148a377 100644 (file)
   struct ix86_address parts;
   int ok;
 
+  /*  LEA handles zero-extend by itself.  */
+  if (GET_CODE (op) == ZERO_EXTEND)
+    return false;
+
   ok = ix86_decompose_address (op, &parts);
   gcc_assert (ok);
   return parts.seg == SEG_DEFAULT;