diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 97d5e9d4ec6..6e83cd094cc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2003-07-08 Jakub Jelinek + + 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. + 2003-07-08 Chris Demetriou * Makefile.in (install-po): Cope with empty CATALOGS. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index ba6f114c861..c3fa99fdfb5 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -149,6 +149,7 @@ extern void ix86_split_ashldi (rtx *, rtx); extern void ix86_split_ashrdi (rtx *, rtx); extern void ix86_split_lshrdi (rtx *, rtx); extern rtx ix86_find_base_term (rtx); +extern int ix86_check_movabs (rtx, int); extern rtx assign_386_stack_local (enum machine_mode, int); extern int ix86_attr_length_immediate_default (rtx, int); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 1f273b404e7..2e13624af1a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -3288,6 +3288,27 @@ x86_64_movabs_operand (rtx op, enum machine_mode mode) return 0; } +/* Return nonzero if OPNUM's MEM should be matched + in movabs* patterns. */ + +int +ix86_check_movabs (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 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index cab255746ac..91e8aefceba 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1262,24 +1262,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}" @@ -1382,24 +1381,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}" @@ -1701,24 +1699,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}" @@ -2080,24 +2077,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}" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8f678d4a7cf..5884c7fd56e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-07-08 Jakub Jelinek + + PR c/11420 + * gcc.dg/20030708-1.c: New test. + 2003-07-08 Richard Sandiford * gcc.dg/compat/sdata-section.h: New file. diff --git a/gcc/testsuite/gcc.dg/20030708-1.c b/gcc/testsuite/gcc.dg/20030708-1.c new file mode 100644 index 00000000000..b9786418ed9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20030708-1.c @@ -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; +}