On Sat, Jul 23, 2011 at 2:38 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
> On Fri, Jul 22, 2011 at 9:03 PM, H.J. Lu <hongjiu...@intel.com> wrote:
>
>> This patch adds x32 LEA insn support.  The main issue is
>>
>> gen_lowpart (Pmode, operands[1]);
>>
>> doesn't work on symbol.  This patch avoids it.
>>
>> Also we shouldn't generate 32bit store with x32 PIC source.
>>
>> Any comments?
>
> Can you please post some testcases to see the effect of the patch?
>
> Thanks,
> Uros.
>

Here is the updated patch with 3 testcases


-- 
H.J.
---
gcc/

2011-07-22  H.J. Lu  <hongjiu...@intel.com>

        PR target/47381
        * config/i386/constraints.md (Ys): Rewritten.
        (Ye): Updated.
        (Yl): Likewise.

        * config/i386/constraints.md (i): Replace "i" with "Ye".
        (l): New.
        (g): Replace "g" with "rmYe".
        (general_operand): Replace general_operand with
        with si_general_operand on SI.
        (general_szext_operand): Likewise.
        (*movsi_internal): Replace "i" with "Ys".
        (*add<mode>_1): Replace <i> with <l>.
        (addsi_1_zext): Replace general_operand with si_general_operand
        and "g" with "rmYe".
        (*addsi_2_zext): Likewise.
        (*subsi_1_zext): Likewise.
        (*subsi_2_zext): Likewise.
        (*subsi_3_zext): Likewise.
        (*addsi3_carry_zext): Likewise.
        (*subsi3_carry_zext): Likewise.
        (*andsi_1): Likewise.
        (*andsi_1_zext): Likewise.
        (*andsi_2_zext): Likewise.
        (LEA split): Replace nonmemory_operand with
        si_lea_nonmemory_operand and "i" with "Ye".
        (*lea_general_2): Likewise.
        (*lea_general_2_zext): Likewise.
        (*lea_general_1): Replace immediate_operand with
        si_lea_immediate_operand and "i" with "Ye".
        (*lea_general_1_zext): Likewise.
        (*lea_general_3): Likewise.
        (*lea_general_3_zext): Likewise.

        config/i386/predicates.md (si_general_operand): New.
        (si_lea_immediate_operand): Likewise.
        (si_lea_nonmemory_operand): Likewise.

gcc/testsuite/

2011-07-22  H.J. Lu  <hongjiu...@intel.com>

        PR target/47381
        * gcc.target/i386/pr47381-1.c: New.
        * gcc.target/i386/pr47381-2.c: Likewise.
        * gcc.target/i386/pr47381-3.c: Likewise.
gcc/

2011-07-22  H.J. Lu  <hongjiu...@intel.com>

        PR target/47381
        * config/i386/constraints.md (Ys): Rewritten.
        (Ye): Updated.
        (Yl): Likewise.

        * config/i386/constraints.md (i): Replace "i" with "Ye".
        (l): New.
        (g): Replace "g" with "rmYe".
        (general_operand): Replace general_operand with
        with si_general_operand on SI.
        (general_szext_operand): Likewise.
        (*movsi_internal): Replace "i" with "Ys".
        (*add<mode>_1): Replace <i> with <l>.
        (addsi_1_zext): Replace general_operand with si_general_operand
        and "g" with "rmYe".
        (*addsi_2_zext): Likewise.
        (*subsi_1_zext): Likewise.
        (*subsi_2_zext): Likewise.
        (*subsi_3_zext): Likewise.
        (*addsi3_carry_zext): Likewise.
        (*subsi3_carry_zext): Likewise.
        (*andsi_1): Likewise.
        (*andsi_1_zext): Likewise.
        (*andsi_2_zext): Likewise.
        (LEA split): Replace nonmemory_operand with
        si_lea_nonmemory_operand and "i" with "Ye".
        (*lea_general_2): Likewise.
        (*lea_general_2_zext): Likewise.
        (*lea_general_1): Replace immediate_operand with
        si_lea_immediate_operand and "i" with "Ye".
        (*lea_general_1_zext): Likewise.
        (*lea_general_3): Likewise.
        (*lea_general_3_zext): Likewise.

        config/i386/predicates.md (si_general_operand): New.
        (si_lea_immediate_operand): Likewise.
        (si_lea_nonmemory_operand): Likewise.

gcc/testsuite/

2011-07-22  H.J. Lu  <hongjiu...@intel.com>

        PR target/47381
        * gcc.target/i386/pr47381-1.c: New.
        * gcc.target/i386/pr47381-2.c: Likewise.
        * gcc.target/i386/pr47381-3.c: Likewise.

diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 8d3e45a..a5d54a1 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -123,6 +123,31 @@
  "optimize_function_for_speed_p (cfun) ? GENERAL_REGS : NO_REGS"
  "@internal Any integer register when integer XFmode moves are enabled.")
 
+;; Constant constraints.
+;; We also use the Y prefix to denote constant constraints:
+;;  s  Immediate constant source operand for store
+;;  e  Immediate constant for SImode
+;;  l  Immediate constant for lea
+
+(define_constraint "Ys"
+  "@internal Immediate constant source operand for store."
+  (and (match_operand 0 "immediate_operand")
+       (ior (match_test "!TARGET_X32")
+           (not (match_operand 0 "pic_32bit_operand")))))
+
+(define_constraint "Ye"
+  "@internal Immediate constant for SImode."
+  (if_then_else (and (match_test "TARGET_X32")
+                    (match_test "flag_pic"))
+    (match_operand 0 "x86_64_immediate_operand")
+    (match_operand 0 "immediate_operand")))
+
+(define_constraint "Yl"
+  "@internal Immediate constant for lea."
+  (if_then_else (match_test "TARGET_X32")
+    (match_operand 0 "si_lea_immediate_operand")
+    (match_operand 0 "immediate_operand")))
+
 (define_constraint "z"
   "@internal Constant call address operand."
   (match_operand 0 "constant_call_address_operand"))
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index b704fa7..02b6fd6 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -861,10 +861,13 @@
 (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 "Ye") (DI "e")])
+
+;; Immediate operand constraint for integer modes with lea.
+(define_mode_attr l [(QI "n") (HI "n") (SI "Yl") (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 "rmYe") (DI "rme")])
 
 ;; Immediate operand constraint for double integer modes.
 (define_mode_attr di [(SI "iF") (DI "e")])
@@ -876,7 +879,7 @@
 (define_mode_attr general_operand
        [(QI "general_operand")
         (HI "general_operand")
-        (SI "general_operand")
+        (SI "si_general_operand")
         (DI "x86_64_general_operand")
         (TI "x86_64_general_operand")])
 
@@ -884,7 +887,7 @@
 (define_mode_attr general_szext_operand
        [(QI "general_operand")
         (HI "general_operand")
-        (SI "general_operand")
+        (SI "si_general_operand")
         (DI "x86_64_szext_general_operand")])
 
 ;; Immediate operand predicate for integer modes.
@@ -2180,11 +2198,13 @@
   [(const_int 0)]
   "ix86_split_long_move (operands); DONE;")
 
+;; Use "Ys" constraint to disallow store with X32 PIC operand as
+;; immediate.
 (define_insn "*movsi_internal"
   [(set (match_operand:SI 0 "nonimmediate_operand"
-                       "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
+                       "=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 ,rYs,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
 {
   switch (get_attr_type (insn))
@@ -5453,7 +5473,7 @@
   [(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 "<general_operand>" "<g>,r<i>,0,l<l>")))
    (clobber (reg:CC FLAGS_REG))]
   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
 {
@@ -5512,7 +5532,7 @@
   [(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 "si_general_operand" "rmYe,0,lYl"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
 {
@@ -5844,7 +5864,7 @@
   [(set (match_operand:DI 0 "register_operand" "")
        (zero_extend:DI
          (plus:SI (match_operand:SI 1 "register_operand" "")
-                  (match_operand:SI 2 "nonmemory_operand" ""))))
+                  (match_operand:SI 2 "si_lea_nonmemory_operand" ""))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && reload_completed
    && ix86_lea_for_add_ok (insn, operands)"
@@ -5901,7 +5921,7 @@
   [(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 "si_general_operand" "rmYe"))
          (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
@@ -6240,7 +6260,7 @@
   [(set (match_operand 0 "register_operand" "=r")
        (plus (plus (match_operand 1 "index_register_operand" "l")
                    (match_operand 2 "register_operand" "r"))
-             (match_operand 3 "immediate_operand" "i")))]
+             (match_operand 3 "si_lea_immediate_operand" "Ye")))]
   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
@@ -6273,7 +6293,7 @@
          (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"))))]
+                  (match_operand:SI 3 "si_lea_immediate_operand" "Ye"))))]
   "TARGET_64BIT"
   "#"
   "&& reload_completed"
@@ -6293,7 +6313,7 @@
   [(set (match_operand 0 "register_operand" "=r")
        (plus (mult (match_operand 1 "index_register_operand" "l")
                    (match_operand 2 "const248_operand" "i"))
-             (match_operand 3 "nonmemory_operand" "ri")))]
+             (match_operand 3 "si_lea_nonmemory_operand" "rYe")))]
   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
    && (!TARGET_PARTIAL_REG_STALL
@@ -6326,7 +6346,7 @@
          (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"))))]
+                  (match_operand:SI 3 "si_lea_nonmemory_operand" "rYe"))))]
   "TARGET_64BIT"
   "#"
   "&& reload_completed"
@@ -6346,7 +6366,7 @@
        (plus (plus (mult (match_operand 1 "index_register_operand" "l")
                          (match_operand 2 "const248_operand" "i"))
                    (match_operand 3 "register_operand" "r"))
-             (match_operand 4 "immediate_operand" "i")))]
+             (match_operand 4 "si_lea_immediate_operand" "Ye")))]
   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
    && (!TARGET_PARTIAL_REG_STALL
@@ -6384,7 +6404,7 @@
                       (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"))))]
+                  (match_operand:SI 4 "si_lea_immediate_operand" "Ye"))))]
   "TARGET_64BIT"
   "#"
   "&& reload_completed"
@@ -6481,7 +6501,7 @@
   [(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 "si_general_operand" "rmYe"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
   "sub{l}\t{%2, %k0|%k0, %2}"
@@ -6518,7 +6538,7 @@
   [(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 "si_general_operand" "rmYe"))
          (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
@@ -6545,7 +6565,7 @@
 (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 "si_general_operand" "rmYe")))
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
          (minus:SI (match_dup 1)
@@ -6592,7 +6612,7 @@
          (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 "si_general_operand" "rmYe")))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
   "adc{l}\t{%2, %k0|%k0, %2}"
@@ -6607,7 +6627,7 @@
          (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 "si_general_operand" 
"rmYe")))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
   "sbb{l}\t{%2, %k0|%k0, %2}"
@@ -7730,7 +7750,7 @@
 (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 "si_general_operand" "rYe,rm,L")))
    (clobber (reg:CC FLAGS_REG))]
   "ix86_binary_operator_ok (AND, SImode, operands)"
 {
@@ -7777,7 +7797,7 @@
   [(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 "si_general_operand" "rmYe"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
   "and{l}\t{%2, %k0|%k0, %2}"
@@ -7940,7 +7960,7 @@
   [(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 "si_general_operand" "rmYe"))
                 (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 2ef9129..267136a 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -1188,3 +1198,24 @@
       return false;
   return true;
 })
+
+;; Test for a valid general operand for SImode.
+(define_predicate "si_general_operand"
+  (if_then_else (and (match_test "TARGET_X32")
+                    (match_test "flag_pic"))
+    (match_operand 0 "x86_64_general_operand")
+    (match_operand 0 "general_operand")))
+
+;; Test for a valid immediate operand for lea in SImode.
+(define_predicate "si_lea_immediate_operand"
+  (and (match_operand 0 "immediate_operand")
+       (ior (match_test "!TARGET_X32")
+           (match_test "GET_MODE (op) != SImode")
+           (match_test "!SYMBOLIC_CONST (op)"))))
+
+;; Test for a valid nonmemory operand for lea in SImode.
+(define_predicate "si_lea_nonmemory_operand"
+  (and (match_operand 0 "nonmemory_operand")
+       (ior (match_test "!TARGET_X32")
+           (match_test "GET_MODE (op) != SImode")
+           (match_test "!SYMBOLIC_CONST (op)"))))
diff --git a/gcc/testsuite/gcc.target/i386/pr47381-1.c 
b/gcc/testsuite/gcc.target/i386/pr47381-1.c
new file mode 100644
index 0000000..738a892
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr47381-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned IPos;
+typedef unsigned char uch;
+extern uch window[];
+unsigned max_chain_length;
+unsigned strstart;
+int longest_match(IPos cur_match, int len, int best_len)
+{
+    unsigned chain_length = max_chain_length;
+    register uch *scan = window + strstart;
+    register uch *match;
+    register uch scan_end1 = scan[best_len-1];
+    register uch scan_end = scan[best_len];
+    do {
+        ;
+        match = window + cur_match;
+        if (match[best_len] != scan_end ||
+            match[best_len-1] != scan_end1 ||
+            *match != *scan ||
+            *++match != scan[1]) continue;
+            best_len = len;
+    } while ( --chain_length != 0);
+    return best_len;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr47381-2.c 
b/gcc/testsuite/gcc.target/i386/pr47381-2.c
new file mode 100644
index 0000000..8aa7be7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr47381-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned long ulg;
+long block_start;
+typedef unsigned char uch;
+extern uch window[];
+ unsigned strstart;
+ulg flush_block (char *buf, ulg stored_len, int eof);
+ulg deflate()
+{
+    return flush_block(block_start >= 0L ? 
(char*)&window[(unsigned)block_start] : (char*)((void *)0), (long)strstart - 
block_start, (1));
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr47381-3.c 
b/gcc/testsuite/gcc.target/i386/pr47381-3.c
new file mode 100644
index 0000000..c4b2127
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr47381-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=atom" } */
+
+struct foo_t {
+  int limit;
+} foo[3];
+void
+bar () {
+  int i;
+  for (i = 0; i < 3; i++) {
+    __builtin_memset (&foo[i], 0, sizeof(*foo));
+  }
+}

Reply via email to