* i386.c (legitimate_pic_address_disp_p): Refuse GOTOFF in 64bit mode.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Aug 2005 16:29:51 +0000 (16:29 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Aug 2005 16:29:51 +0000 (16:29 +0000)
(legitimate_address_p): Refuse GOT and GOTOFF in 64bit mode.
* i386.md (movdi*): Use pic_32bit_operand.
* predicates.md (pic_32bit_operand): New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102860 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/config/i386/predicates.md

index 0996ece..fdeef96 100644 (file)
@@ -1,3 +1,10 @@
+2005-08-08  Jan Hubicka  <jh@suse.cz>
+
+       * i386.c (legitimate_pic_address_disp_p): Refuse GOTOFF in 64bit mode.
+       (legitimate_address_p): Refuse GOT and GOTOFF in 64bit mode.
+       * i386.md (movdi*): Use pic_32bit_operand.
+       * predicates.md (pic_32bit_operand): New.
+
 2005-08-08  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/21166
index 5afa63f..68589b2 100644 (file)
@@ -5542,8 +5542,12 @@ legitimate_pic_address_disp_p (rtx disp)
        return false;
       return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;
     case UNSPEC_GOTOFF:
-      if (GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
-         || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
+      /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
+        While ABI specify also 32bit relocation but we don't produce it in
+        small PIC model at all.  */
+      if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
+          || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
+         && !TARGET_64BIT)
         return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
       return false;
     case UNSPEC_GOTTPOFF:
@@ -5697,8 +5701,17 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
          && GET_CODE (XEXP (disp, 0)) == UNSPEC)
        switch (XINT (XEXP (disp, 0), 1))
          {
+         /* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit when
+            used.  While ABI specify also 32bit relocations, we don't produce
+            them at all and use IP relative instead.  */
          case UNSPEC_GOT:
          case UNSPEC_GOTOFF:
+           gcc_assert (flag_pic);
+           if (!TARGET_64BIT)
+             goto is_legitimate_pic;
+           reason = "64bit address unspec";
+           goto report_error;
          case UNSPEC_GOTPCREL:
            gcc_assert (flag_pic);
            goto is_legitimate_pic;
index d533408..9e7e92c 100644 (file)
              (const_string "sselog1")
            (eq_attr "alternative" "7,8,9,10,11")
              (const_string "ssemov")
-           (and (ne (symbol_ref "flag_pic") (const_int 0))
-                (match_operand:SI 1 "symbolic_operand" ""))
+           (match_operand:DI 1 "pic_32bit_operand" "")
              (const_string "lea")
           ]
           (const_string "imov")))
              (const_string "ssecvt")
            (eq_attr "alternative" "4")
              (const_string "multi")
-           (and (ne (symbol_ref "flag_pic") (const_int 0))
-                (match_operand:DI 1 "symbolic_operand" ""))
+           (match_operand:DI 1 "pic_32bit_operand" "")
              (const_string "lea")
           ]
           (const_string "imov")))
index f8ff804..71dd688 100644 (file)
              (match_operand 0 "x86_64_zext_immediate_operand")))
     (match_operand 0 "nonmemory_operand")))
 
+;; Return true when operand is PIC expression that can be computed by lea
+;; operation.
+(define_predicate "pic_32bit_operand"
+  (match_code "const,symbol_ref,label_ref")
+{
+  if (!flag_pic)
+    return 0;
+  /* Rule out relocations that translate into 64bit constants.  */
+  if (TARGET_64BIT && GET_CODE (op) == CONST)
+    {
+      op = XEXP (op, 0);
+      if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+       op = XEXP (op, 0);
+      if (GET_CODE (op) == UNSPEC
+         && (XINT (op, 1) == UNSPEC_GOTOFF
+             || XINT (op, 1) == UNSPEC_GOT))
+       return 0;
+    }
+  return symbolic_operand (op, mode);
+})
+
+
 ;; Return nonzero if OP is nonmemory operand acceptable by movabs patterns.
 (define_predicate "x86_64_movabs_operand"
   (if_then_else (match_test "!TARGET_64BIT || !flag_pic")