]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/11420 ([x86_64] gcc generates invalid asm code when "-O -fPIC" is used...
authorJakub Jelinek <jakub@redhat.com>
Tue, 8 Jul 2003 18:01:51 +0000 (20:01 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 8 Jul 2003 18:01:51 +0000 (20:01 +0200)
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.

* gcc.dg/20030708-1.c: New test.

From-SVN: r69092

gcc/ChangeLog
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20030708-1.c [new file with mode: 0644]

index 97d5e9d4ec69c36f46eaf3f1d836042d048710c4..6e83cd094cc9f8ae2e181998da3c1d69c93ba2a0 100644 (file)
@@ -1,3 +1,11 @@
+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.
+
 2003-07-08  Chris Demetriou  <cgd@broadcom.com>
 
        * Makefile.in (install-po): Cope with empty CATALOGS.
index ba6f114c86177c6e0f909653c9761b5bc90618d9..c3fa99fdfb5ab3c24564c0388544196956e10322 100644 (file)
@@ -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);
index 1f273b404e7d22259afd2b073ce42a277a6898d9..2e13624af1a7438d0681b043642ee25e8bb0da5d 100644 (file)
@@ -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
index cab255746ac6d8399fbf2e977f9135ad5444165b..91e8aefceba78e0bb3fed5b352cf230f2b48fd29 100644 (file)
 ;; 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}"
 ;; 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}"
 ;; 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}"
 ;; 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}"
index 8f678d4a7cfbddab67dbe16e498ab2ca2ff5187d..5884c7fd56e146e3689fa9e965d1f8d573d957dd 100644 (file)
@@ -1,3 +1,8 @@
+2003-07-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/11420
+       * gcc.dg/20030708-1.c: New test.
+
 2003-07-08  Richard Sandiford  <rsandifo@redhat.com>
 
        * 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 (file)
index 0000000..b978641
--- /dev/null
@@ -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;
+}