This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR c/11420 (broken amd64 movabs*) (take 3)


On Mon, Jul 07, 2003 at 04:19:50PM -0700, Richard Henderson wrote:
> On Mon, Jul 07, 2003 at 04:18:23PM +0200, Jakub Jelinek wrote:
> > +  mem = SET_SRC (set);
> > +  while (GET_CODE (mem) == SUBREG)
> > +    mem = SUBREG_REG (mem);
> > +  if (GET_CODE (mem) != MEM || XEXP (mem, 0) != op)
> > +    {
> > +      mem = SET_DEST (set);
> > +      while (GET_CODE (mem) == SUBREG)
> > +	mem = SUBREG_REG (mem);
> > +      if (GET_CODE (mem) != MEM || XEXP (mem, 0) != op)
> > +	abort ();
> 
> What is the logic behind doing it this way with op an rtx
> instead of passing in an operand number and doing
> 
>   mem = XEXP (set, opnum);
>   if (GET_CODE (mem) != MEM)
>     abort ();
> 
> and so forth?

Probably paranoia.
Here is the updated patch:

2003-07-08  Jakub Jelinek  <jakub@redhat.com>

	PR c/11420
	* config/i386/i386.c (ix86_check_movabs): New function.
	* config/i386/i386-protos.h (ix86_check_movabs): New prototype.
	* config/i386/i386.md (movabs[shqd]i_1_rex64): Kill broken alternative.
	(movabs[shqd]i_[12]_rex64): Add ix86_check_movabs check to conditions.

	* config/i386/i386.md (movdi_1_rex64): Set Y<-m alternative's type
	to ssemov.

	PR c/11420
	* gcc.dg/20030707-1.c: New test.

--- gcc/config/i386/i386.md.jj	2003-06-16 07:28:07.000000000 -0400
+++ gcc/config/i386/i386.md	2003-07-08 04:11:49.000000000 -0400
@@ -1145,24 +1145,23 @@
 ;; We fake an second form of instruction to force reload to load address
 ;; into register when rax is not available
 (define_insn "*movabssi_1_rex64"
-  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
-	(match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
-  "TARGET_64BIT"
+  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
+	(match_operand:SI 1 "nonmemory_operand" "a,er"))]
+  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
   "@
    movabs{l}\t{%1, %P0|%P0, %1}
-   mov{l}\t{%1, %a0|%a0, %1}
-   movabs{l}\t{%1, %a0|%a0, %1}"
+   mov{l}\t{%1, %a0|%a0, %1}"
   [(set_attr "type" "imov")
-   (set_attr "modrm" "0,*,*")
-   (set_attr "length_address" "8,0,0")
-   (set_attr "length_immediate" "0,*,*")
+   (set_attr "modrm" "0,*")
+   (set_attr "length_address" "8,0")
+   (set_attr "length_immediate" "0,*")
    (set_attr "memory" "store")
    (set_attr "mode" "SI")])
 
 (define_insn "*movabssi_2_rex64"
   [(set (match_operand:SI 0 "register_operand" "=a,r")
         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
   "@
    movabs{l}\t{%P1, %0|%0, %P1}
    mov{l}\t{%a1, %0|%0, %a1}"
@@ -1265,24 +1264,23 @@
 ;; We fake an second form of instruction to force reload to load address
 ;; into register when rax is not available
 (define_insn "*movabshi_1_rex64"
-  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
-	(match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
-  "TARGET_64BIT"
+  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
+	(match_operand:HI 1 "nonmemory_operand" "a,er"))]
+  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
   "@
    movabs{w}\t{%1, %P0|%P0, %1}
-   mov{w}\t{%1, %a0|%a0, %1}
-   movabs{w}\t{%1, %a0|%a0, %1}"
+   mov{w}\t{%1, %a0|%a0, %1}"
   [(set_attr "type" "imov")
-   (set_attr "modrm" "0,*,*")
-   (set_attr "length_address" "8,0,0")
-   (set_attr "length_immediate" "0,*,*")
+   (set_attr "modrm" "0,*")
+   (set_attr "length_address" "8,0")
+   (set_attr "length_immediate" "0,*")
    (set_attr "memory" "store")
    (set_attr "mode" "HI")])
 
 (define_insn "*movabshi_2_rex64"
   [(set (match_operand:HI 0 "register_operand" "=a,r")
         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
   "@
    movabs{w}\t{%P1, %0|%0, %P1}
    mov{w}\t{%a1, %0|%0, %a1}"
@@ -1584,24 +1582,23 @@
 ;; We fake an second form of instruction to force reload to load address
 ;; into register when rax is not available
 (define_insn "*movabsqi_1_rex64"
-  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
-	(match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
-  "TARGET_64BIT"
+  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
+	(match_operand:QI 1 "nonmemory_operand" "a,er"))]
+  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
   "@
    movabs{b}\t{%1, %P0|%P0, %1}
-   mov{b}\t{%1, %a0|%a0, %1}
-   movabs{b}\t{%1, %a0|%a0, %1}"
+   mov{b}\t{%1, %a0|%a0, %1}"
   [(set_attr "type" "imov")
-   (set_attr "modrm" "0,*,*")
-   (set_attr "length_address" "8,0,0")
-   (set_attr "length_immediate" "0,*,*")
+   (set_attr "modrm" "0,*")
+   (set_attr "length_address" "8,0")
+   (set_attr "length_immediate" "0,*")
    (set_attr "memory" "store")
    (set_attr "mode" "QI")])
 
 (define_insn "*movabsqi_2_rex64"
   [(set (match_operand:QI 0 "register_operand" "=a,r")
         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
   "@
    movabs{b}\t{%P1, %0|%0, %P1}
    mov{b}\t{%a1, %0|%0, %a1}"
@@ -1896,7 +1893,7 @@
   [(set (attr "type")
      (cond [(eq_attr "alternative" "5,6")
 	      (const_string "mmxmov")
-	    (eq_attr "alternative" "7,8")
+	    (eq_attr "alternative" "7,8,9")
 	      (const_string "ssemov")
 	    (eq_attr "alternative" "4")
 	      (const_string "multi")
@@ -1913,24 +1910,23 @@
 ;; We fake an second form of instruction to force reload to load address
 ;; into register when rax is not available
 (define_insn "*movabsdi_1_rex64"
-  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
-	(match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
-  "TARGET_64BIT"
+  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
+	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
+  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
   "@
    movabs{q}\t{%1, %P0|%P0, %1}
-   mov{q}\t{%1, %a0|%a0, %1}
-   movabs{q}\t{%1, %a0|%a0, %1}"
+   mov{q}\t{%1, %a0|%a0, %1}"
   [(set_attr "type" "imov")
-   (set_attr "modrm" "0,*,*")
-   (set_attr "length_address" "8,0,0")
-   (set_attr "length_immediate" "0,*,*")
+   (set_attr "modrm" "0,*")
+   (set_attr "length_address" "8,0")
+   (set_attr "length_immediate" "0,*")
    (set_attr "memory" "store")
    (set_attr "mode" "DI")])
 
 (define_insn "*movabsdi_2_rex64"
   [(set (match_operand:DI 0 "register_operand" "=a,r")
         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
   "@
    movabs{q}\t{%P1, %0|%0, %P1}
    mov{q}\t{%a1, %0|%0, %a1}"
--- gcc/config/i386/i386.c.jj	2003-06-23 17:16:51.000000000 -0400
+++ gcc/config/i386/i386.c	2003-07-08 04:10:54.000000000 -0400
@@ -3080,6 +3080,29 @@ x86_64_movabs_operand (op, mode)
   return 0;
 }
 
+/* Return nonzero if OPNUM's MEM should be matched
+   in movabs* patterns.  */
+
+int
+ix86_check_movabs (insn, opnum)
+     rtx insn;
+     int opnum;
+{
+  rtx set, mem;
+
+  set = PATTERN (insn);
+  if (GET_CODE (set) == PARALLEL)
+    set = XVECEXP (set, 0, 0);
+  if (GET_CODE (set) != SET)
+    abort ();
+  mem = XEXP (set, opnum);
+  while (GET_CODE (mem) == SUBREG)
+    mem = SUBREG_REG (mem);
+  if (GET_CODE (mem) != MEM)
+    abort ();
+  return (volatile_ok || !MEM_VOLATILE_P (mem));
+}
+
 /* Return nonzero if OP is nonmemory operand representable on x86_64.  */
 
 int
--- gcc/config/i386/i386-protos.h.jj	2003-03-19 07:58:53.000000000 -0500
+++ gcc/config/i386/i386-protos.h	2003-07-08 04:11:08.000000000 -0400
@@ -146,6 +146,7 @@ extern void ix86_split_ashrdi PARAMS ((r
 extern void ix86_split_lshrdi PARAMS ((rtx *, rtx));
 extern int ix86_address_cost PARAMS ((rtx));
 extern rtx ix86_find_base_term PARAMS ((rtx));
+extern int ix86_check_movabs PARAMS ((rtx, int));
 
 extern rtx assign_386_stack_local PARAMS ((enum machine_mode, int));
 extern int ix86_attr_length_immediate_default PARAMS ((rtx, int));
--- gcc/testsuite/gcc.dg/20030707-1.c.jj	2003-01-30 05:24:37.000000000 -0500
+++ gcc/testsuite/gcc.dg/20030707-1.c	2003-07-07 09:43:29.000000000 -0400
@@ -0,0 +1,14 @@
+/* PR c/11420 */
+/* { dg-do link } */
+/* { dg-options "-O2 -fpic" } */
+
+void (* volatile fn) (void);
+static void foo (void)
+{
+}
+
+int main (void)
+{
+  fn = foo;
+  return 0;
+}


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]