OSDN Git Service

PR target/47381
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Jul 2011 12:00:33 +0000 (12:00 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Jul 2011 12:00:33 +0000 (12:00 +0000)
PR target/49832
PR target/49833
* config/i386/i386.md (i): Change SImode attribute to "e".
(g): Change SImode attribute to "rme".
(di): Change SImode attribute to "nF".
(general_operand): Change SImode attribute to x86_64_general_operand.
(general_szext_operand): Change SImode attribute to
x86_64_szext_general_operand.
(immediate_operand): Change SImode attribute to
x86_64_immediate_operand.
(nonmemory_operand): Change SImode attribute to
x86_64_nonmemory_operand.
(*movdi_internal_rex64): Remove mode from pic_32bit_operand check.
(*movsi_internal): Ditto.  Use "e" constraint in alternative 2.
(*lea_1): Use SWI48 mode iterator.
(*lea_1_zext): New insn pattern.
(testsi_ccno_1): Use x86_64_nonmemory_operand predicate for operand 2.
(*bt<mode>): Ditto.
(*add<mode>1): Use x86_64_general_operand predicate for operand 2.
Update operand constraints.
(addsi_1_zext): Ditto.
(*add<mode>2): Ditto.
(*addsi_3_zext): Ditto.
(*subsi_1_zext): Ditto.
(*subsi_2_zext): Ditto.
(*subsi_3_zext): Ditto.
(*addsi3_carry_zext): Ditto.
(*<plusminus_insn>si3_zext_cc_overflow): Ditto.
(*mulsi3_1_zext): Ditto.
(*andsi_1): Ditto.
(*andsi_1_zext): Ditto.
(*andsi_2_zext): Ditto.
(*<any_or:code>si_1_zext): Ditto.
(*<any_or:code>si_2_zext): Ditto.
(*test<mode>_1): Use <general_operand> predicate for operand 1.
(*and<mode>_2): Ditto.
(mov<mode>cc): Use  <general_operand> predicate for operands 1 and 2.
(add->lea splitter): Check operand modes in insn constraint.  Extend
operands less than SImode wide to SImode.
(add->lea zext splitter): Do not extend input operands to DImode.
(*lea_general_1): Handle only QImode and HImode operands.
(*lea_general_2): Ditto.
(*lea_general_3): Ditto.
(*lea_general_1_zext): Remove.
(*lea_general_2_zext): Ditto.
(*lea_general_3_zext): Ditto.
(*lea_general_4): Check operand modes in insn constraint.  Extend
operands less than SImode wide to SImode.
(ashift->lea splitter): Ditto.
* config/i386/i386.c (ix86_print_operand_address): Print address
registers with 'q' modifier on 64bit targets.
* config/i386/predicates.md (pic_32bit_opreand): Define as special
predicate.  Reject non-SI and non-DI modes.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@176788 138bc75d-0d04-0410-961f-82ee72b054a4

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

index c93e5e3..913e202 100644 (file)
@@ -1,3 +1,61 @@
+2011-07-26  Uros Bizjak  <ubizjak@gmail.com>
+           H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/47381
+       PR target/49832
+       PR target/49833
+       * config/i386/i386.md (i): Change SImode attribute to "e".
+       (g): Change SImode attribute to "rme".
+       (di): Change SImode attribute to "nF".
+       (general_operand): Change SImode attribute to x86_64_general_operand.
+       (general_szext_operand): Change SImode attribute to
+       x86_64_szext_general_operand.
+       (immediate_operand): Change SImode attribute to
+       x86_64_immediate_operand.
+       (nonmemory_operand): Change SImode attribute to
+       x86_64_nonmemory_operand.
+       (*movdi_internal_rex64): Remove mode from pic_32bit_operand check.
+       (*movsi_internal): Ditto.  Use "e" constraint in alternative 2.
+       (*lea_1): Use SWI48 mode iterator.
+       (*lea_1_zext): New insn pattern.
+       (testsi_ccno_1): Use x86_64_nonmemory_operand predicate for operand 2.
+       (*bt<mode>): Ditto.
+       (*add<mode>1): Use x86_64_general_operand predicate for operand 2.
+       Update operand constraints.
+       (addsi_1_zext): Ditto.
+       (*add<mode>2): Ditto.
+       (*addsi_3_zext): Ditto.
+       (*subsi_1_zext): Ditto.
+       (*subsi_2_zext): Ditto.
+       (*subsi_3_zext): Ditto.
+       (*addsi3_carry_zext): Ditto.
+       (*<plusminus_insn>si3_zext_cc_overflow): Ditto.
+       (*mulsi3_1_zext): Ditto.
+       (*andsi_1): Ditto.
+       (*andsi_1_zext): Ditto.
+       (*andsi_2_zext): Ditto.
+       (*<any_or:code>si_1_zext): Ditto.
+       (*<any_or:code>si_2_zext): Ditto.
+       (*test<mode>_1): Use <general_operand> predicate for operand 1.
+       (*and<mode>_2): Ditto.
+       (mov<mode>cc): Use  <general_operand> predicate for operands 1 and 2.
+       (add->lea splitter): Check operand modes in insn constraint.  Extend
+       operands less than SImode wide to SImode.
+       (add->lea zext splitter): Do not extend input operands to DImode.
+       (*lea_general_1): Handle only QImode and HImode operands.
+       (*lea_general_2): Ditto.
+       (*lea_general_3): Ditto.
+       (*lea_general_1_zext): Remove.
+       (*lea_general_2_zext): Ditto.
+       (*lea_general_3_zext): Ditto.
+       (*lea_general_4): Check operand modes in insn constraint.  Extend
+       operands less than SImode wide to SImode.
+       (ashift->lea splitter): Ditto.
+       * config/i386/i386.c (ix86_print_operand_address): Print address
+       registers with 'q' modifier on 64bit targets.
+       * config/i386/predicates.md (pic_32bit_opreand): Define as special
+       predicate.  Reject non-SI and non-DI modes.
+
 2011-07-25  Andrew Pinski  <apinski@cavium.com>
 
        PR tree-opt/49671
        * config/mmix/mmix.c (mmix_print_operand_punct_valid_p): Make static.
        Change return type to bool. Change argument type to bool.
        (mmix_print_operand, mmix_print_operand_address): Make static.
-       (mmix_intval, mmix_output_condition): Change 'x' argument type 
+       (mmix_intval, mmix_output_condition): Change 'x' argument type
        to const_rtx.
        (TARGET_PRINT_OPERAND, TARGET_PRINT_OPERAND_ADDRESS,
        TARGET_PRINT_OPERAND_PUNCT_VALID_P): Define.
 
 2011-07-25  Georg-Johann Lay  <avr@gjlay.de>
-       
+
        PR target/39386
        * config/avr/avr.c (out_shift_with_cnt): Use tmp_reg as
        shift counter for x << x and x >> x shifts.
        (EDGE_ALL_FLAGS, EDGE_COMPLEX): Include it.
        * bb-reorder.c: Include except.h.
        (fix_up_crossing_landing_pad): New.
-       (find_rarely_executed_basic_blocks_and_crossing_edges): Place 
+       (find_rarely_executed_basic_blocks_and_crossing_edges): Place
        landing pads in the right partition.  Duplicate as necessary.
        (partition_hot_cold_basic_blocks): Fix up DF info after
        duplicating landing pads.
        (producer_string): New variable.
        (gen_producer_string): New function.
        (gen_compile_unit_die): Use it.
-       (dwarf2out_finish): Fix up comp_unit_die () DW_AT_producer
-       if needed.
+       (dwarf2out_finish): Fix up comp_unit_die () DW_AT_producer if needed.
        * Makefile.in (dwarf2out.o): Depend on $(OPTS_H).
        * doc/invoke.texi: Document -grecord-gcc-switches and
        -gno-record-gcc-switches, add a -grecord-gcc-switches reference
        MS ABI in x32 mode.
        (ix86_init_builtins): Call ix86_init_builtins_va_builtins_abi
        only for TARGET_LP64.
-       (ix86_handle_abi_attribute): Check TARGET_LP64 instead of
-       TARGET_64BIT.
+       (ix86_handle_abi_attribute): Check TARGET_LP64 instead of TARGET_64BIT.
 
 2011-07-22  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
 
        PR lto/49796
        * cgraphunit.c (verify_edge_corresponds_to_fndecl): Return false
-       if decl node is in another partition, call cgraph_get_node only
-       once.
+       if decl node is in another partition, call cgraph_get_node only once.
 
 2011-07-22  Uros Bizjak  <ubizjak@gmail.com>
 
index 96263ed..3668357 100644 (file)
@@ -14122,6 +14122,9 @@ 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;
+
       if (ASSEMBLER_DIALECT == ASM_ATT)
        {
          if (disp)
@@ -14136,11 +14139,11 @@ ix86_print_operand_address (FILE *file, rtx addr)
 
          putc ('(', file);
          if (base)
-           print_reg (base, 0, file);
+           print_reg (base, code, file);
          if (index)
            {
              putc (',', file);
-             print_reg (index, 0, file);
+             print_reg (index, code, file);
              if (scale != 1)
                fprintf (file, ",%d", scale);
            }
@@ -14175,7 +14178,7 @@ ix86_print_operand_address (FILE *file, rtx addr)
          putc ('[', file);
          if (base)
            {
-             print_reg (base, 0, file);
+             print_reg (base, code, file);
              if (offset)
                {
                  if (INTVAL (offset) >= 0)
@@ -14191,7 +14194,7 @@ ix86_print_operand_address (FILE *file, rtx addr)
          if (index)
            {
              putc ('+', file);
-             print_reg (index, 0, file);
+             print_reg (index, code, file);
              if (scale != 1)
                fprintf (file, "*%d", scale);
            }
index b704fa7..98d60ec 100644 (file)
 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
 
 ;; Immediate operand constraint for integer modes.
-(define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
+(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
 
 ;; General operand constraint for word modes.
-(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
+(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
 
 ;; Immediate operand constraint for double integer modes.
-(define_mode_attr di [(SI "iF") (DI "e")])
+(define_mode_attr di [(SI "nF") (DI "e")])
 
 ;; Immediate operand constraint for shifts.
 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
 (define_mode_attr general_operand
        [(QI "general_operand")
         (HI "general_operand")
-        (SI "general_operand")
+        (SI "x86_64_general_operand")
         (DI "x86_64_general_operand")
         (TI "x86_64_general_operand")])
 
 (define_mode_attr general_szext_operand
        [(QI "general_operand")
         (HI "general_operand")
-        (SI "general_operand")
+        (SI "x86_64_szext_general_operand")
         (DI "x86_64_szext_general_operand")])
 
 ;; Immediate operand predicate for integer modes.
 (define_mode_attr immediate_operand
        [(QI "immediate_operand")
         (HI "immediate_operand")
-        (SI "immediate_operand")
+        (SI "x86_64_immediate_operand")
         (DI "x86_64_immediate_operand")])
 
 ;; Nonmemory operand predicate for integer modes.
 (define_mode_attr nonmemory_operand
        [(QI "nonmemory_operand")
         (HI "nonmemory_operand")
-        (SI "nonmemory_operand")
+        (SI "x86_64_nonmemory_operand")
         (DI "x86_64_nonmemory_operand")])
 
 ;; Operand predicate for shifts.
              (const_string "ssemov")
            (eq_attr "alternative" "16,17")
              (const_string "ssecvt")
-           (match_operand:DI 1 "pic_32bit_operand" "")
+           (match_operand 1 "pic_32bit_operand" "")
              (const_string "lea")
           ]
           (const_string "imov")))
   [(set (match_operand:SI 0 "nonimmediate_operand"
                        "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
        (match_operand:SI 1 "general_operand"
-                       "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
+                       "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
 {
   switch (get_attr_type (insn))
              (const_string "sselog1")
            (eq_attr "alternative" "7,8,9,10,11")
              (const_string "ssemov")
-           (match_operand:DI 1 "pic_32bit_operand" "")
+           (match_operand 1 "pic_32bit_operand" "")
              (const_string "lea")
           ]
           (const_string "imov")))
    (set_attr "mode" "QI")])
 
 (define_insn "*lea_1"
-  [(set (match_operand:P 0 "register_operand" "=r")
-       (match_operand:P 1 "no_seg_address_operand" "p"))]
+  [(set (match_operand:SWI48 0 "register_operand" "=r")
+       (match_operand:SWI48 1 "no_seg_address_operand" "p"))]
   ""
   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
   [(set_attr "type" "lea")
    (set_attr "mode" "<MODE>")])
 
+(define_insn "*lea_1_zext"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI
+         (match_operand:SI 1 "no_seg_address_operand" "p")))]
+  "TARGET_64BIT"
+  "lea{l}\t{%a1, %k0|%k0, %a1}"
+  [(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 "no_seg_address_operand" "p") 0))]
   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
        (plus:SWI48
          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
-         (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
+         (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
    (clobber (reg:CC FLAGS_REG))]
   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
 {
   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
-                  (match_operand:SI 2 "general_operand" "g,0,li"))))
+                  (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
 {
         (const_string "none")))
    (set_attr "mode" "QI")])
 
-;; Convert lea to the lea pattern to avoid flags dependency.
+;; Convert add to the lea pattern to avoid flags dependency.
 (define_split
   [(set (match_operand 0 "register_operand" "")
        (plus (match_operand 1 "register_operand" "")
               (match_operand 2 "nonmemory_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
-  "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
+  "GET_MODE (operands[0]) == GET_MODE (operands[1])
+   && (GET_MODE (operands[0]) == GET_MODE (operands[2])
+       || GET_MODE (operands[2]) == VOIDmode)
+   && reload_completed && ix86_lea_for_add_ok (insn, operands)" 
   [(const_int 0)]
 {
-  rtx pat;
   enum machine_mode mode = GET_MODE (operands[0]);
-
-  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
-     may confuse gen_lowpart.  */
-  if (mode != Pmode)
-    {
-      operands[1] = gen_lowpart (Pmode, operands[1]);
-      operands[2] = gen_lowpart (Pmode, operands[2]);
-    }
-
-  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
+  rtx pat;
 
   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
-    operands[0] = gen_lowpart (SImode, operands[0]);
+    { 
+      mode = SImode; 
+      operands[0] = gen_lowpart (mode, operands[0]);
+      operands[1] = gen_lowpart (mode, operands[1]);
+      operands[2] = gen_lowpart (mode, operands[2]);
+    }
 
-  if (TARGET_64BIT && mode != Pmode)
-    pat = gen_rtx_SUBREG (SImode, pat, 0);
+  pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
 
   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
   DONE;
 })
 
-;; Convert lea to the lea pattern to avoid flags dependency.
+;; Convert add to the lea pattern to avoid flags dependency.
 ;; ??? This pattern handles immediate operands that do not satisfy immediate
 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
 (define_split
   [(set (match_dup 0)
        (plus:DI (match_dup 1) (match_dup 2)))])
 
-;; Convert lea to the lea pattern to avoid flags dependency.
+;; Convert add to the lea pattern to avoid flags dependency.
 (define_split
   [(set (match_operand:DI 0 "register_operand" "")
        (zero_extend:DI
   "TARGET_64BIT && reload_completed
    && ix86_lea_for_add_ok (insn, operands)"
   [(set (match_dup 0)
-       (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
-{
-  operands[1] = gen_lowpart (DImode, operands[1]);
-  operands[2] = gen_lowpart (DImode, operands[2]);
-})
+       (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
 
 (define_insn "*add<mode>_2"
   [(set (reg FLAGS_REG)
   [(set (reg FLAGS_REG)
        (compare
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
-                  (match_operand:SI 2 "general_operand" "g"))
+                  (match_operand:SI 2 "x86_64_general_operand" "rme"))
          (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
 (define_insn "*addsi_3_zext"
   [(set (reg FLAGS_REG)
        (compare
-         (neg:SI (match_operand:SI 2 "general_operand" "g"))
+         (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
          (match_operand:SI 1 "nonimmediate_operand" "%0")))
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
   [(set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
-;; The lea patterns for non-Pmodes needs to be matched by
+;; The lea patterns for modes less than 32 bits need to be matched by
 ;; several insns converted to real lea by splitters.
 
 (define_insn_and_split "*lea_general_1"
        (plus (plus (match_operand 1 "index_register_operand" "l")
                    (match_operand 2 "register_operand" "r"))
              (match_operand 3 "immediate_operand" "i")))]
-  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
-    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
+  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
    && GET_MODE (operands[0]) == GET_MODE (operands[1])
    && GET_MODE (operands[0]) == GET_MODE (operands[2])
   "&& reload_completed"
   [(const_int 0)]
 {
+  enum machine_mode mode = SImode;
   rtx pat;
-  operands[0] = gen_lowpart (SImode, operands[0]);
-  operands[1] = gen_lowpart (Pmode, operands[1]);
-  operands[2] = gen_lowpart (Pmode, operands[2]);
-  operands[3] = gen_lowpart (Pmode, operands[3]);
-  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
+
+  operands[0] = gen_lowpart (mode, operands[0]);
+  operands[1] = gen_lowpart (mode, operands[1]);
+  operands[2] = gen_lowpart (mode, operands[2]);
+  operands[3] = gen_lowpart (mode, operands[3]);
+
+  pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
                      operands[3]);
-  if (Pmode != SImode)
-    pat = gen_rtx_SUBREG (SImode, pat, 0);
+
   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
   DONE;
 }
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
-(define_insn_and_split "*lea_general_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (zero_extend:DI
-         (plus:SI (plus:SI
-                    (match_operand:SI 1 "index_register_operand" "l")
-                    (match_operand:SI 2 "register_operand" "r"))
-                  (match_operand:SI 3 "immediate_operand" "i"))))]
-  "TARGET_64BIT"
-  "#"
-  "&& reload_completed"
-  [(set (match_dup 0)
-       (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
-                                                    (match_dup 2))
-                                           (match_dup 3)) 0)))]
-{
-  operands[1] = gen_lowpart (Pmode, operands[1]);
-  operands[2] = gen_lowpart (Pmode, operands[2]);
-  operands[3] = gen_lowpart (Pmode, operands[3]);
-}
-  [(set_attr "type" "lea")
-   (set_attr "mode" "SI")])
-
 (define_insn_and_split "*lea_general_2"
   [(set (match_operand 0 "register_operand" "=r")
        (plus (mult (match_operand 1 "index_register_operand" "l")
-                   (match_operand 2 "const248_operand" "i"))
+                   (match_operand 2 "const248_operand" "n"))
              (match_operand 3 "nonmemory_operand" "ri")))]
-  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
-    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
-   && (!TARGET_PARTIAL_REG_STALL
-       || GET_MODE (operands[0]) == SImode
-       || optimize_function_for_size_p (cfun))
+  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
+   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
    && GET_MODE (operands[0]) == GET_MODE (operands[1])
    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
        || GET_MODE (operands[3]) == VOIDmode)"
   "&& reload_completed"
   [(const_int 0)]
 {
+  enum machine_mode mode = SImode;
   rtx pat;
-  operands[0] = gen_lowpart (SImode, operands[0]);
-  operands[1] = gen_lowpart (Pmode, operands[1]);
-  operands[3] = gen_lowpart (Pmode, operands[3]);
-  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
-                     operands[3]);
-  if (Pmode != SImode)
-    pat = gen_rtx_SUBREG (SImode, pat, 0);
+
+  operands[0] = gen_lowpart (mode, operands[0]);
+  operands[1] = gen_lowpart (mode, operands[1]);
+  operands[3] = gen_lowpart (mode, operands[3]);
+
+  pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
+                     operands[3]);
+
   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
   DONE;
 }
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
-(define_insn_and_split "*lea_general_2_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (zero_extend:DI
-         (plus:SI (mult:SI
-                    (match_operand:SI 1 "index_register_operand" "l")
-                    (match_operand:SI 2 "const248_operand" "n"))
-                  (match_operand:SI 3 "nonmemory_operand" "ri"))))]
-  "TARGET_64BIT"
-  "#"
-  "&& reload_completed"
-  [(set (match_dup 0)
-       (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
-                                                    (match_dup 2))
-                                           (match_dup 3)) 0)))]
-{
-  operands[1] = gen_lowpart (Pmode, operands[1]);
-  operands[3] = gen_lowpart (Pmode, operands[3]);
-}
-  [(set_attr "type" "lea")
-   (set_attr "mode" "SI")])
-
 (define_insn_and_split "*lea_general_3"
   [(set (match_operand 0 "register_operand" "=r")
        (plus (plus (mult (match_operand 1 "index_register_operand" "l")
-                         (match_operand 2 "const248_operand" "i"))
+                         (match_operand 2 "const248_operand" "n"))
                    (match_operand 3 "register_operand" "r"))
              (match_operand 4 "immediate_operand" "i")))]
-  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
-    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
-   && (!TARGET_PARTIAL_REG_STALL
-       || GET_MODE (operands[0]) == SImode
-       || optimize_function_for_size_p (cfun))
+  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
+   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
    && GET_MODE (operands[0]) == GET_MODE (operands[1])
    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
   "#"
   "&& reload_completed"
   [(const_int 0)]
 {
+  enum machine_mode mode = SImode;
   rtx pat;
-  operands[0] = gen_lowpart (SImode, operands[0]);
-  operands[1] = gen_lowpart (Pmode, operands[1]);
-  operands[3] = gen_lowpart (Pmode, operands[3]);
-  operands[4] = gen_lowpart (Pmode, operands[4]);
-  pat = gen_rtx_PLUS (Pmode,
-                     gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
-                                                        operands[2]),
+
+  operands[0] = gen_lowpart (mode, operands[0]);
+  operands[1] = gen_lowpart (mode, operands[1]);
+  operands[3] = gen_lowpart (mode, operands[3]);
+  operands[4] = gen_lowpart (mode, operands[4]);
+
+  pat = gen_rtx_PLUS (mode,
+                     gen_rtx_PLUS (mode,
+                                   gen_rtx_MULT (mode, operands[1],
+                                                       operands[2]),
                                    operands[3]),
                      operands[4]);
-  if (Pmode != SImode)
-    pat = gen_rtx_SUBREG (SImode, pat, 0);
+
   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
   DONE;
 }
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
-(define_insn_and_split "*lea_general_3_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (zero_extend:DI
-         (plus:SI (plus:SI
-                    (mult:SI
-                      (match_operand:SI 1 "index_register_operand" "l")
-                      (match_operand:SI 2 "const248_operand" "n"))
-                    (match_operand:SI 3 "register_operand" "r"))
-                  (match_operand:SI 4 "immediate_operand" "i"))))]
-  "TARGET_64BIT"
-  "#"
-  "&& reload_completed"
-  [(set (match_dup 0)
-       (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
-                                                             (match_dup 2))
-                                                    (match_dup 3))
-                                           (match_dup 4)) 0)))]
-{
-  operands[1] = gen_lowpart (Pmode, operands[1]);
-  operands[3] = gen_lowpart (Pmode, operands[3]);
-  operands[4] = gen_lowpart (Pmode, operands[4]);
-}
-  [(set_attr "type" "lea")
-   (set_attr "mode" "SI")])
-
 (define_insn_and_split "*lea_general_4"
-  [(set (match_operand:SWI 0 "register_operand" "=r")
-       (any_or:SWI (ashift:SWI (match_operand:SWI 1 "index_register_operand" "l")
-                               (match_operand:SWI 2 "const_int_operand" "n"))
-                   (match_operand 3 "const_int_operand" "n")))]
-  "(<MODE>mode == DImode
-    || <MODE>mode == SImode
-    || !TARGET_PARTIAL_REG_STALL
-    || optimize_function_for_size_p (cfun))
+  [(set (match_operand 0 "register_operand" "=r")
+       (any_or (ashift
+                 (match_operand 1 "index_register_operand" "l")
+                 (match_operand 2 "const_int_operand" "n"))
+               (match_operand 3 "const_int_operand" "n")))]
+  "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
+      && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
+    || GET_MODE (operands[0]) == SImode
+    || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
+   && GET_MODE (operands[0]) == GET_MODE (operands[1])
    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
   "&& reload_completed"
   [(const_int 0)]
 {
+  enum machine_mode mode = GET_MODE (operands[0]);
   rtx pat;
-  if (<MODE>mode != DImode)
-    operands[0] = gen_lowpart (SImode, operands[0]);
-  operands[1] = gen_lowpart (Pmode, operands[1]);
+
+  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
+    { 
+      mode = SImode; 
+      operands[0] = gen_lowpart (mode, operands[0]);
+      operands[1] = gen_lowpart (mode, operands[1]);
+    }
+
   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
-  pat = plus_constant (gen_rtx_MULT (Pmode, operands[1], operands[2]),
+
+  pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
                       INTVAL (operands[3]));
-  if (Pmode != SImode && <MODE>mode != DImode)
-    pat = gen_rtx_SUBREG (SImode, pat, 0);
+
   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
   DONE;
 }
   [(set_attr "type" "lea")
    (set (attr "mode")
-      (if_then_else (eq (symbol_ref "<MODE>mode == DImode") (const_int 0))
-       (const_string "SI")
-       (const_string "DI")))])
+      (if_then_else (match_operand:DI 0 "" "")
+       (const_string "DI")
+       (const_string "SI")))])
 \f
 ;; Subtract instructions
 
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
          (minus:SI (match_operand:SI 1 "register_operand" "0")
-                   (match_operand:SI 2 "general_operand" "g"))))
+                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
   "sub{l}\t{%2, %k0|%k0, %2}"
   [(set (reg FLAGS_REG)
        (compare
          (minus:SI (match_operand:SI 1 "register_operand" "0")
-                   (match_operand:SI 2 "general_operand" "g"))
+                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
          (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
 (define_insn "*subsi_3_zext"
   [(set (reg FLAGS_REG)
        (compare (match_operand:SI 1 "register_operand" "0")
-                (match_operand:SI 2 "general_operand" "g")))
+                (match_operand:SI 2 "x86_64_general_operand" "rme")))
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
          (minus:SI (match_dup 1)
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
                   (plus:SI (match_operator 3 "ix86_carry_flag_operator"
                             [(reg FLAGS_REG) (const_int 0)])
-                           (match_operand:SI 2 "general_operand" "g")))))
+                           (match_operand:SI 2 "x86_64_general_operand" "rme")))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
   "adc{l}\t{%2, %k0|%k0, %2}"
          (minus:SI (match_operand:SI 1 "register_operand" "0")
                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
                              [(reg FLAGS_REG) (const_int 0)])
-                            (match_operand:SI 2 "general_operand" "g")))))
+                            (match_operand:SI 2 "x86_64_general_operand" "rme")))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
   "sbb{l}\t{%2, %k0|%k0, %2}"
        (compare:CCC
          (plusminus:SI
            (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
-           (match_operand:SI 2 "general_operand" "g"))
+           (match_operand:SI 2 "x86_64_general_operand" "rme"))
          (match_dup 1)))
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
-                  (match_operand:SI 2 "general_operand" "K,i,mr"))))
+                  (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT
    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
   [(set (reg:CCNO FLAGS_REG)
        (compare:CCNO
          (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
-                 (match_operand:SI 1 "nonmemory_operand" ""))
+                 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
          (const_int 0)))])
 
 (define_expand "testqi_ccz_1"
        (compare
         (and:SWI124
          (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
-         (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
+         (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
         (const_int 0)))]
   "ix86_match_ccmode (insn, CCNOmode)
    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
 (define_insn "*andsi_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
        (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
-               (match_operand:SI 2 "general_operand" "ri,rm,L")))
+               (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
    (clobber (reg:CC FLAGS_REG))]
   "ix86_binary_operator_ok (AND, SImode, operands)"
 {
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
          (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
-                 (match_operand:SI 2 "general_operand" "g"))))
+                 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
   "and{l}\t{%2, %k0|%k0, %2}"
   [(set (reg FLAGS_REG)
        (compare (and:SWI124
                  (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
-                 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
+                 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
                 (const_int 0)))
    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
        (and:SWI124 (match_dup 1) (match_dup 2)))]
   [(set (reg FLAGS_REG)
        (compare (and:SI
                  (match_operand:SI 1 "nonimmediate_operand" "%0")
-                 (match_operand:SI 2 "general_operand" "g"))
+                 (match_operand:SI 2 "x86_64_general_operand" "rme"))
                 (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
         (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
-                   (match_operand:SI 2 "general_operand" "g"))))
+                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
   "<logic>{l}\t{%2, %k0|%k0, %2}"
 (define_insn "*<code>si_2_zext"
   [(set (reg FLAGS_REG)
        (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
-                           (match_operand:SI 2 "general_operand" "g"))
+                           (match_operand:SI 2 "x86_64_general_operand" "rme"))
                 (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
        (const_string "*")))
    (set_attr "mode" "QI")])
 
-;; Convert lea to the lea pattern to avoid flags dependency.
+;; Convert ashift to the lea pattern to avoid flags dependency.
 (define_split
   [(set (match_operand 0 "register_operand" "")
        (ashift (match_operand 1 "index_register_operand" "")
                 (match_operand:QI 2 "const_int_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
-  "reload_completed
+  "GET_MODE (operands[0]) == GET_MODE (operands[1])
+   && reload_completed
    && true_regnum (operands[0]) != true_regnum (operands[1])"
   [(const_int 0)]
 {
-  rtx pat;
   enum machine_mode mode = GET_MODE (operands[0]);
-
-  if (mode != Pmode)
-    operands[1] = gen_lowpart (Pmode, operands[1]);
-  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
-
-  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
+  rtx pat;
 
   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
-    operands[0] = gen_lowpart (SImode, operands[0]);
+    { 
+      mode = SImode; 
+      operands[0] = gen_lowpart (mode, operands[0]);
+      operands[1] = gen_lowpart (mode, operands[1]);
+    }
+
+  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
 
-  if (TARGET_64BIT && mode != Pmode)
-    pat = gen_rtx_SUBREG (SImode, pat, 0);
+  pat = gen_rtx_MULT (mode, operands[1], operands[2]);
 
   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
   DONE;
 })
 
-;; Convert lea to the lea pattern to avoid flags dependency.
+;; Convert ashift to the lea pattern to avoid flags dependency.
 (define_split
   [(set (match_operand:DI 0 "register_operand" "")
        (zero_extend:DI
          (zero_extract:SWI48
            (match_operand:SWI48 0 "register_operand" "r")
            (const_int 1)
-           (match_operand:SWI48 1 "nonmemory_operand" "rN"))
+           (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
          (const_int 0)))]
   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
 (define_expand "mov<mode>cc"
   [(set (match_operand:SWIM 0 "register_operand" "")
        (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
-                          (match_operand:SWIM 2 "general_operand" "")
-                          (match_operand:SWIM 3 "general_operand" "")))]
+                          (match_operand:SWIM 2 "<general_operand>" "")
+                          (match_operand:SWIM 3 "<general_operand>" "")))]
   ""
   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
 
index 2ef9129..0515519 100644 (file)
 
 ;; Return true when operand is PIC expression that can be computed by lea
 ;; operation.
-(define_predicate "pic_32bit_operand"
+(define_special_predicate "pic_32bit_operand"
   (match_code "const,symbol_ref,label_ref")
 {
+  if (GET_MODE (op) != SImode
+      && GET_MODE (op) != DImode)
+    return false;
+
   if (!flag_pic)
     return false;
   /* Rule out relocations that translate into 64bit constants.  */