Hi,

I checked in this patch to add x32 LEA zero-extend split.

H.J.
---
commit a57ad5f219b8aa7cc67c18fb3a217517c2a461f4
Author: H.J. Lu <hjl.to...@gmail.com>
Date:   Sat Jul 9 08:00:56 2011 -0700

    Support x32 LEA zero-extend split.

diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
index a610f23..fdff5af 100644
--- a/gcc/ChangeLog.x32
+++ b/gcc/ChangeLog.x32
@@ -1,3 +1,14 @@
+2011-07-09  H.J. Lu  <hongjiu...@intel.com>
+
+       * config/i386/i386.c (ix86_simplify_base_disp): Renamed to ...
+       (ix86_simplify_base_index_disp): This.  Handle index.
+       (ix86_simplify_base_disp): Updated.
+
+       * config/i386/i386.md (*lea_1_x32): Renamed to ...
+       (*lea_2_x32): This.
+       (*lea_2_zext_x32): New.
+       (X32 LEA zero-extend split): Likewise.
+
 2011-07-06  H.J. Lu  <hongjiu...@intel.com>
 
        * config.gcc: Check with_multilib_list instead of enable_x32.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b0112b9..c852719 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11054,6 +11054,17 @@ ix86_live_on_entry (bitmap regs)
            (const (plus:SI (symbol_ref:SI ("A.193.2210"))
                            (const_int CONST))))
 
+   We also translate
+
+   (plus:SI (reg:SI 0 ax [orig:74 D.4067 ] [74])
+           (subreg:SI (plus:DI (reg/f:DI 7 sp)
+                               (const_int 64 [0x40])) 0))
+
+   into
+
+   (plus:SI (reg:SI 0 ax [orig:74 D.4067 ] [74])
+           (plus:SI (reg/f:SI 7 sp) (const_int 64 [0x40])))
+
    If PLUS is true, we also translate
 
    (set (reg:SI 40 r11)
@@ -11072,10 +11083,11 @@ ix86_live_on_entry (bitmap regs)
  */
 
 static void
-ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, bool plus)
+ix86_simplify_base_index_disp (rtx *base_p, rtx *index_p, rtx *disp_p,
+                              bool plus)
 {
   rtx base = *base_p;
-  rtx disp;
+  rtx disp, index, op0, op1;
 
   if (!base || GET_MODE (base) != ptr_mode)
     return;
@@ -11091,10 +11103,11 @@ ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, 
bool plus)
 
   if (GET_CODE (base) == PLUS)
     {
-      rtx op0 = XEXP (base, 0);
-      rtx op1 = XEXP (base, 1);
       rtx addend;
 
+      op0 = XEXP (base, 0);
+      op1 = XEXP (base, 1);
+
       if ((REG_P (op0)
           || (!plus
               && GET_CODE (op0) == PLUS
@@ -11160,6 +11173,25 @@ ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, 
bool plus)
            *base_p = base;
        }
     }
+  else if (!plus
+          && (disp == NULL_RTX || disp == const0_rtx)
+          && index_p
+          && (index = *index_p) != NULL_RTX
+          && GET_CODE (index) == SUBREG
+          && GET_MODE (index) == ptr_mode)
+    {
+      index = SUBREG_REG (index);
+      if (GET_CODE (index) == PLUS && GET_MODE (index) == Pmode)
+       {
+         op0 = XEXP (index, 0);
+         op1 = XEXP (index, 1);
+         if (REG_P (op0) && CONST_INT_P (op1))
+           {
+             *index_p = gen_rtx_REG (ptr_mode, REGNO (op0));
+             *disp_p = op1;
+           }
+       }
+    }
 }
 
 /* Extract the parts of an RTL expression that is a valid memory address
@@ -11208,12 +11240,14 @@ ix86_decompose_address (rtx addr, struct ix86_address 
*out)
                {
                  op = XEXP (op, 0);
                  if (n == 1)
-                   ix86_simplify_base_disp (&op, &addends[0], false);
+                   ix86_simplify_base_index_disp (&op, NULL,
+                                                  &addends[0], false);
                }
              else if (n == 1
                       && GET_CODE (op) == PLUS
                       && GET_MODE (op) == ptr_mode)
-               ix86_simplify_base_disp (&op, &addends[0], true);
+               ix86_simplify_base_index_disp (&op, NULL, &addends[0],
+                                              true);
            }
        }
       while (GET_CODE (op) == PLUS);
@@ -11308,14 +11342,14 @@ ix86_decompose_address (rtx addr, struct ix86_address 
*out)
       scale = INTVAL (scale_rtx);
     }
 
-  index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
+  if (TARGET_X32 && reload_completed)
+    ix86_simplify_base_index_disp (&base, &index, &disp, false);
 
   /* Avoid useless 0 displacement.  */
   if (disp == const0_rtx && (base || index))
     disp = NULL_RTX;
 
-  if (TARGET_X32 && reload_completed)
-    ix86_simplify_base_disp (&base, &disp, false);
+  index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
 
   base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base;
 
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index fe4b6be..4230c8f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -5477,18 +5477,20 @@
   [(set_attr "type" "lea")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*lea_1_x32"
+(define_insn "*lea_2"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (match_operand:SI 1 "no_seg_address_operand" "p"))]
-  "TARGET_X32"
+       (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
+  "TARGET_64BIT"
   "lea{l}\t{%a1, %0|%0, %a1}"
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
-(define_insn "*lea_2"
+;; Place this after lea_2 since 64bit version doesn't have address
+;; size override.
+(define_insn "*lea_2_x32"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
-  "TARGET_64BIT"
+       (match_operand:SI 1 "no_seg_address_operand" "p"))]
+  "TARGET_X32"
   "lea{l}\t{%a1, %0|%0, %a1}"
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
@@ -5502,6 +5504,15 @@
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
+(define_insn "*lea_2_zext_x32"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI
+         (match_operand:SI 1 "no_seg_address_operand" "p")))]
+  "TARGET_X32"
+  "lea{l}\t{%a1, %k0|%k0, %a1}"
+  [(set_attr "type" "lea")
+   (set_attr "mode" "SI")])
+
 (define_insn "*add<mode>_1"
   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
        (plus:SWI48
@@ -5908,6 +5919,19 @@
   operands[2] = gen_lowpart (DImode, operands[2]);
 })
 
+;; Convert lea to the lea pattern to avoid flags dependency.
+(define_split
+  [(set (match_operand:DI 0 "register_operand" "")
+       (zero_extend:DI
+         (plus:SI (match_operand:SI 1 "register_operand" "")
+                  (match_operand:SI 2 "nonmemory_operand" ""))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_X32
+   && reload_completed
+   && ix86_lea_for_add_ok (insn, operands)"
+  [(set (match_dup 0)
+       (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
+
 (define_insn "*add<mode>_2"
   [(set (reg FLAGS_REG)
        (compare

Reply via email to