This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[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