Patchwork [i386] : various address related fixes/cleanups

login
register
mail settings
Submitter Uros Bizjak
Date Aug. 5, 2011, 3:26 p.m.
Message ID <CAFULd4aSEYq3fJ4momVZRxdekLBoa5x5E258Y_ojAHCPcMPqYw@mail.gmail.com>
Download mbox | patch
Permalink /patch/108692/
State New
Headers show

Comments

Uros Bizjak - Aug. 5, 2011, 3:26 p.m.
Hello!

These problems were found by testing ZERO_EXTENDed addresses with x32
target. The problems were in handling of SUBREGs of parts.base and
parts.index and in usage of "offsetable operand", 'o' operand
constraint.

The patch does not generate zero extended addresses (yet), since there
is a problem in IRA/reload how "offsetable operand" addresses are
handled (I will post separate RFC patch for that).

2011-08-05  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/i386.md (*push<mode>2): Use "o" constraint instead
	of "m" for operand 0.  Add type and mode attribute.
	(*pushxf_nointeger"): Use "<" constraint for operand 0.
	(*pushdf_rex64): New pattern, split out of *pushdf.  Use "m"
	constraint instead of "o" for opreand 1.
	(*pushdf): Disable for TARGET_64BIT.  Correct mode attribute.

2011-08-05  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/predicates.md (lea_address_operand): Rename from
	no_seg_address_operand.
	* config/i386/i386.md (*lea_1): Update operand 1 predicate for rename.
	(*lea_1_zext): Ditto.
	(*lea_2): Ditto.
	(*lea_2_zext): Ditto.

2011-08-05  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/i386.c (ix86_print_operand_address): Handle SUBREGs of
	parts.base and parts.index.
	* config/i386/predicates.md (aligned_operand): Ditto.
	(cmpxchg8b_pic_memory_operand): Ditto.

Patch was tested on x86_64-pc-linux-gnu {,-m32} and was committed to
mainline SVN.

Uros.
Uros Bizjak - Aug. 5, 2011, 4:12 p.m.
On Fri, Aug 5, 2011 at 5:26 PM, Uros Bizjak <ubizjak@gmail.com> wrote:

> These problems were found by testing ZERO_EXTENDed addresses with x32
> target. The problems were in handling of SUBREGs of parts.base and
> parts.index and in usage of "offsetable operand", 'o' operand
> constraint.

Whops, forgot to commit this part:

2011-08-05  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/i386.md (*movdi_internal_rex64): Use "!o" constraint
	instead of "!m" for operand 0, alternative 4.
	(*movdf_internal_rex64): Ditto for operand 0, alernative 6.

Uros.

Patch

Index: i386/i386.md
===================================================================
--- i386/i386.md	(revision 177430)
+++ i386/i386.md	(working copy)
@@ -1648,9 +1648,11 @@ 
 
 (define_insn "*push<mode>2"
   [(set (match_operand:DWI 0 "push_operand" "=<")
-	(match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
+	(match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
   ""
-  "#")
+  "#"
+  [(set_attr "type" "multi")
+   (set_attr "mode" "<MODE>")])
 
 (define_split
   [(set (match_operand:TI 0 "push_operand" "")
@@ -2704,7 +2706,7 @@ 
 ;; only once, but this ought to be handled elsewhere).
 
 (define_insn "*pushxf_nointeger"
-  [(set (match_operand:XF 0 "push_operand" "=X,X")
+  [(set (match_operand:XF 0 "push_operand" "=<,<")
 	(match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
   "optimize_function_for_size_p (cfun)"
 {
@@ -2724,6 +2726,18 @@ 
    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
 
+(define_insn "*pushdf_rex64"
+  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
+	(match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,Y2"))]
+  "TARGET_64BIT"
+{
+  /* This insn should be already split before reg-stack.  */
+  gcc_unreachable ();
+}
+  [(set_attr "type" "multi")
+   (set_attr "unit" "i387,*,*")
+   (set_attr "mode" "DF,DI,DF")])
+
 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
 ;; Size of pushdf using integer instructions is 2+2*memory operand size
 ;; On the average, pushdf using integers can be still shorter.
@@ -2731,14 +2745,14 @@ 
 (define_insn "*pushdf"
   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
 	(match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
-  ""
+  "!TARGET_64BIT"
 {
   /* This insn should be already split before reg-stack.  */
   gcc_unreachable ();
 }
   [(set_attr "type" "multi")
    (set_attr "unit" "i387,*,*")
-   (set_attr "mode" "DF,SI,DF")])
+   (set_attr "mode" "DF,DI,DF")])
 
 ;; %%% Kill this when call knows how to work this out.
 (define_split
@@ -5431,7 +5445,7 @@ 
 
 (define_insn "*lea_1"
   [(set (match_operand:SWI48 0 "register_operand" "=r")
-	(match_operand:SWI48 1 "no_seg_address_operand" "p"))]
+	(match_operand:SWI48 1 "lea_address_operand" "p"))]
   ""
   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
   [(set_attr "type" "lea")
@@ -5440,7 +5454,7 @@ 
 (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")))]
+	  (match_operand:SI 1 "lea_address_operand" "p")))]
   "TARGET_64BIT"
   "lea{l}\t{%a1, %k0|%k0, %a1}"
   [(set_attr "type" "lea")
@@ -5448,7 +5462,7 @@ 
 
 (define_insn "*lea_2"
   [(set (match_operand:SI 0 "register_operand" "=r")
-	(subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
+	(subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
   "TARGET_64BIT"
   "lea{l}\t{%a1, %0|%0, %a1}"
   [(set_attr "type" "lea")
@@ -5457,7 +5471,7 @@ 
 (define_insn "*lea_2_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(zero_extend:DI
-	  (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
+	  (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
   "TARGET_64BIT"
   "lea{l}\t{%a1, %k0|%k0, %a1}"
   [(set_attr "type" "lea")
Index: i386/predicates.md
===================================================================
--- i386/predicates.md	(revision 177430)
+++ i386/predicates.md	(working copy)
@@ -793,9 +793,9 @@ 
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "const0_operand")))
 
-;; Return true if op if a valid address, and does not contain
+;; Return true if op if a valid address for LEA, and does not contain
 ;; a segment override.
-(define_predicate "no_seg_address_operand"
+(define_predicate "lea_address_operand"
   (match_operand 0 "address_operand")
 {
   struct ix86_address parts;
@@ -840,6 +840,11 @@ 
   ok = ix86_decompose_address (op, &parts);
   gcc_assert (ok);
 
+  if (parts.base && GET_CODE (parts.base) == SUBREG)
+    parts.base = SUBREG_REG (parts.base);
+  if (parts.index && GET_CODE (parts.index) == SUBREG)
+    parts.index = SUBREG_REG (parts.index);
+
   /* Look for some component that isn't known to be aligned.  */
   if (parts.index)
     {
@@ -903,6 +908,12 @@ 
 
   ok = ix86_decompose_address (XEXP (op, 0), &parts);
   gcc_assert (ok);
+
+  if (parts.base && GET_CODE (parts.base) == SUBREG)
+    parts.base = SUBREG_REG (parts.base);
+  if (parts.index && GET_CODE (parts.index) == SUBREG)
+    parts.index = SUBREG_REG (parts.index);
+
   if (parts.base == NULL_RTX
       || parts.base == arg_pointer_rtx
       || parts.base == frame_pointer_rtx
Index: i386/i386.c
===================================================================
--- i386/i386.c	(revision 177430)
+++ i386/i386.c	(working copy)
@@ -14098,6 +14098,20 @@  ix86_print_operand_address (FILE *file, rtx addr)
 
   gcc_assert (ok);
 
+  if (parts.base && GET_CODE (parts.base) == SUBREG)
+    {
+      rtx tmp = SUBREG_REG (parts.base);
+      parts.base = simplify_subreg (GET_MODE (parts.base),
+				    tmp, GET_MODE (tmp), 0);
+    }
+
+  if (parts.index && GET_CODE (parts.index) == SUBREG)
+    {
+      rtx tmp = SUBREG_REG (parts.index);
+      parts.index = simplify_subreg (GET_MODE (parts.index),
+				     tmp, GET_MODE (tmp), 0);
+    }
+
   base = parts.base;
   index = parts.index;
   disp = parts.disp;