re PR target/49781 ([x32] Unnecessary lea in x32 mode)
authorUros Bizjak <uros@gcc.gnu.org>
Thu, 11 Aug 2011 20:03:29 +0000 (22:03 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Thu, 11 Aug 2011 20:03:29 +0000 (22:03 +0200)
PR target/49781
* config/i386/i386.md (*lea_5_zext): New.
(*lea_6_zext): Ditto.
* config/i386/predicates.md (const_32bit_mask): New predicate.
(lea_address_operand): Reject AND.
* config/i386/i386.c (ix86_decompose_address): Allow Dimode AND with
const_32bit_mask immediate.
(ix86_print_operand_address): Handle AND.
(memory_address_length): Ditto.

From-SVN: r177683

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

index 803e9c7481d465debf1d981060de045043f02205..5d6e2d0fc26b803d1def545f40f925fca433aa68 100644 (file)
@@ -1,5 +1,17 @@
+2011-08-11  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/49781
+       * config/i386/i386.md (*lea_5_zext): New.
+       (*lea_6_zext): Ditto.
+       * config/i386/predicates.md (const_32bit_mask): New predicate.
+       (lea_address_operand): Reject AND.
+       * config/i386/i386.c (ix86_decompose_address): Allow Dimode AND with
+       const_32bit_mask immediate.
+       (ix86_print_operand_address): Handle AND.
+       (memory_address_length): Ditto.
+
 2011-08-11  Romain Geissler  <romain.geissler@gmail.com>
-            Brian Hackett  <bhackett1024@gmail.com>
+           Brian Hackett  <bhackett1024@gmail.com>
 
        * plugin.def: Add event for finish_decl.
        * plugin.c (register_callback, invoke_plugin_callbacks): Same.
@@ -40,8 +52,7 @@
 
 2011-08-11   Kazuhiro Inaoka  <kazuhiro.inaoka.ud@renesas.com>
 
-       * config/rx/rx.md (movsicc): Allow register to register
-       transfers.
+       * config/rx/rx.md (movsicc): Allow register to register transfers.
        (*movsicc): Likewise.
        (*stcc): Restrict this pattern to EQ and NE compares.
        (*stcc_reg): New pattern.  Works for any comparison but only for
@@ -71,8 +82,7 @@
        (lto_materialize_tree): ... here.
        Handle CALL_EXPR codes.
        Remove call to lto_streamer_cache_append.
-       * tree-streamer-out.c (lto_output_tree_header): Handle
-       CALL_EXPR nodes.
+       * tree-streamer-out.c (lto_output_tree_header): Handle CALL_EXPR nodes.
        * tree-streamer.h (tree_read_bitfields): Declare.
 
        * Makefile.in (TREE_STREAMER_H): Add STREAMER_HOOKS_H.
        Remove assertions and adjustments for nodes
        main_identifier_node, ptrdiff_type_node and fileptr_type_node.
        (lto_streamer_hooks_init): Set streamer_hooks.write_tree to
-       lto_output_tree and streamer_hooks.read_tree to
-       lto_input_tree.
+       lto_output_tree and streamer_hooks.read_tree to lto_input_tree.
        * lto-streamer.h (lto_input_tree): Declare.
        (lto_output_tree_ref): Remove.
        * streamer-hooks.h (struct streamer_hooks): Remove fields
        (lto_output_integer_cst): Likewise.
        (lto_write_tree): Move to lto-streamer-out.c.
        (lto_output_tree): Likewise.
-       * tree-streamer.c (lto_record_common_node): Move from
-       lto-streamer.c
+       * tree-streamer.c (lto_record_common_node): Move from lto-streamer.c
        (preload_common_nodes): Likewise.
        (lto_streamer_cache_create): Call it.
        * tree-streamer.h: Include streamer-hooks.h.
        * doc/tm.texi: Regenerate.
 
 2011-08-10  Georg-Johann Lay  <avr@gjlay.de>
-       
+
        PR target/29560
        * config/avr/avr.md (*ashlhiqi3): New insn-and-split.
        (*ashl<extend_prefix>qihiqi3): New insn-and-splits.
 
 2011-08-09  Kirill Yukhin  <kirill.yukhin@intel.com>
 
-       * config/i386/i386.c: Remove traling spaces.
-       * config/i386/sse.md: Likewise.
-       (*fma_fmadd_<mode>): Fix insn alternative 1 mnemonic.
-       (*fma_fmsub_<mode>): Likewise.
-       (*fma_fnmadd_<mode>): Likewise.
-       (*fma_fnmsub_<mode>): Likewise.
+       * config/i386/i386.c: Remove traling spaces.
+       * config/i386/sse.md: Likewise.
+       (*fma_fmadd_<mode>): Fix insn alternative 1 mnemonic.
+       (*fma_fmsub_<mode>): Likewise.
+       (*fma_fnmadd_<mode>): Likewise.
+       (*fma_fnmsub_<mode>): Likewise.
 
 2011-08-09  Nick Clifton  <nickc@redhat.com>
 
index 05dd57c7ece3ae372d77900371b539d2721ff75d..fedb2cacc710a58535c06bf619910cf82b765104 100644 (file)
@@ -11146,11 +11146,22 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
 
   /* 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 (TARGET_64BIT && GET_MODE (addr) == DImode)
+    {
+      if (GET_CODE (addr) == ZERO_EXTEND
+         && GET_MODE (XEXP (addr, 0)) == SImode)
+       addr = XEXP (addr, 0);
+      else if (GET_CODE (addr) == AND
+              && const_32bit_mask (XEXP (addr, 1), DImode))
+       {
+         addr = XEXP (addr, 0);
+
+         /* Strip subreg.  */
+         if (GET_CODE (addr) == SUBREG
+             && GET_MODE (SUBREG_REG (addr)) == SImode)
+           addr = SUBREG_REG (addr);
+       }
+    }
 
   if (REG_P (addr))
     base = addr;
@@ -14174,7 +14185,10 @@ ix86_print_operand_address (FILE *file, rtx addr)
       /* 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';
+       code = ((GET_CODE (addr) == ZERO_EXTEND
+                || GET_CODE (addr) == AND)
+               ? 'l'
+               : 'q');
 
       if (ASSEMBLER_DIALECT == ASM_ATT)
        {
@@ -21785,9 +21799,9 @@ assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n)
   return s->rtl;
 }
 \f
-/* Calculate the length of the memory address in the instruction
-   encoding.  Includes addr32 prefix, does not include the one-byte modrm,
-   opcode, or other prefixes.  */
+/* Calculate the length of the memory address in the instruction encoding.
+   Includes addr32 prefix, does not include the one-byte modrm, opcode,
+   or other prefixes.  */
 
 int
 memory_address_length (rtx addr)
@@ -21816,7 +21830,8 @@ memory_address_length (rtx addr)
   disp = parts.disp;
 
   /* Add length of addr32 prefix.  */
-  len = (GET_CODE (addr) == ZERO_EXTEND);
+  len = (GET_CODE (addr) == ZERO_EXTEND
+        || GET_CODE (addr) == AND);
 
   /* Rule of thumb:
        - esp as the base always wants an index,
index 1b37118cfb8de7d793f96a9508a5157880f56c79..e61b0f4a03ea2208ec65ca4914a6544ca83ab840 100644 (file)
    (set_attr "mode" "QI")])
 
 (define_insn "*lea_1"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
+  "TARGET_64BIT"
+  "lea{l}\t{%a1, %0|%0, %a1}"
+  [(set_attr "type" "lea")
+   (set_attr "mode" "SI")])
+
+(define_insn "*lea<mode>_2"
   [(set (match_operand:SWI48 0 "register_operand" "=r")
        (match_operand:SWI48 1 "lea_address_operand" "p"))]
   ""
   [(set_attr "type" "lea")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*lea_1_zext"
+(define_insn "*lea_3_zext"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI
+         (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
+  "TARGET_64BIT"
+  "lea{l}\t{%a1, %k0|%k0, %a1}"
+  [(set_attr "type" "lea")
+   (set_attr "mode" "SI")])
+
+(define_insn "*lea_4_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
          (match_operand:SI 1 "lea_address_operand" "p")))]
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
-(define_insn "*lea_2"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
+(define_insn "*lea_5_zext"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (and:DI
+         (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
+         (match_operand:DI 2 "const_32bit_mask" "n")))]
   "TARGET_64BIT"
-  "lea{l}\t{%a1, %0|%0, %a1}"
+  "lea{l}\t{%a1, %k0|%k0, %a1}"
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
-(define_insn "*lea_2_zext"
+(define_insn "*lea_6_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (zero_extend:DI
-         (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
+       (and:DI
+         (match_operand:DI 1 "lea_address_operand" "p")
+         (match_operand:DI 2 "const_32bit_mask" "n")))]
   "TARGET_64BIT"
   "lea{l}\t{%a1, %k0|%k0, %a1}"
   [(set_attr "type" "lea")
index cfcd061e1f645027eea90edb72b82cfca148a377..bc0a357b74444735202fbad4c1827996ce42ba33 100644 (file)
   (and (match_code "const_int")
        (match_test "INTVAL (op) == 128")))
 
+;; Match exactly 0x0FFFFFFFF in anddi as a zero-extension operation
+(define_predicate "const_32bit_mask"
+  (and (match_code "const_int")
+       (match_test "trunc_int_for_mode (INTVAL (op), DImode)
+                   == (HOST_WIDE_INT) 0xffffffff")))
+
 ;; Match 2, 4, or 8.  Used for leal multiplicands.
 (define_predicate "const248_operand"
   (match_code "const_int")
   int ok;
 
   /*  LEA handles zero-extend by itself.  */
-  if (GET_CODE (op) == ZERO_EXTEND)
+  if (GET_CODE (op) == ZERO_EXTEND
+      || GET_CODE (op) == AND)
     return false;
 
   ok = ix86_decompose_address (op, &parts);