Patchwork [x32] PATCH: Add x32 LEA zero-extend split

login
register
mail settings
Submitter H.J. Lu
Date July 9, 2011, 8:46 p.m.
Message ID <20110709204616.GA10416@lucon.org>
Download mbox | patch
Permalink /patch/104024/
State New
Headers show

Comments

H.J. Lu - July 9, 2011, 8:46 p.m.
Hi,

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

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

    Support x32 LEA zero-extend split.

Patch

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.lu@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.lu@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