i386.c (legitimate_pic_address_disp_p): Refuse GOTOFF in 64bit mode.
authorJan Hubicka <jh@suse.cz>
Mon, 8 Aug 2005 16:29:51 +0000 (18:29 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 8 Aug 2005 16:29:51 +0000 (16:29 +0000)
* 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.

From-SVN: r102860

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

index 0996eced0df8f1dc61e0eb368a1d32ee6cec21c9..fdeef963043b694cb45a95d92699b778c74658d3 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 5afa63f0fecd1423e81084bab8ccd13985603a8c..68589b28da9f0f6a7bd7bde97aaebebc84757fd2 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 d533408b7700cf06cfc7c412c1e7b2f5b1aa3b4c..9e7e92ce8e5516db7f193658017600e9b81b233c 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 f8ff8049d0f37294d5d5be52b8672397758ba88b..71dd6880030e9e144caac981efa6a69e3aa42b37 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")