gcc-patches@gcc.gnu.org
[Top] [All Lists]

Re: x86-64 medium model fix

Subject: Re: x86-64 medium model fix
From: Jan Hubicka
Date: Sun, 7 Aug 2005 22:33:16 +0200
> On Mon, Aug 01, 2005 at 11:57:25AM +0200, Jan Hubicka wrote:
> >     * i386.c (legitimate_pic_address_disp_p): GOTOFF is not valid address
> >     in MEDIUM pic because it is 64bit.
> >     * (legitimate_address_p): Likewise.
> 
> Testing *just* TARGET_64BIT?  I think not.

We never use the 32bit relocations in 64bit mode.  ABI allows them (so
this is why gas silently accepted the produced code) but in general
there is not much use for them as IP relative does better.
> 
> >     * i386.md (movdi*): Choose imov instead of lea for 64bit PIC operands.
> >     * predicates.md (pic_64bit_operand): New predicate.
> 
> No, what you want is pic_32bit_operand, and make that the positive test
> that's used for the lea type.

This ineed looks cleaner ;)

Here is updated patch, bootstrapped/regtested i686-pc-gnu-linux.
Honza

2005-08-07  Jan Hubicka  <jh@xxxxxxx>
        * 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.
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.849
diff -c -3 -p -r1.849 i386.c
*** config/i386/i386.c  3 Aug 2005 21:13:12 -0000       1.849
--- config/i386/i386.c  7 Aug 2005 20:30:10 -0000
*************** legitimate_pic_address_disp_p (rtx disp)
*** 5538,5545 ****
        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)
          return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
        return false;
      case UNSPEC_GOTTPOFF:
--- 5538,5549 ----
        return false;
        return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;
      case UNSPEC_GOTOFF:
!       /* 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:
*************** legitimate_address_p (enum machine_mode 
*** 5693,5700 ****
--- 5697,5713 ----
          && 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: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.651
diff -c -3 -p -r1.651 i386.md
*** config/i386/i386.md 31 Jul 2005 09:12:30 -0000      1.651
--- config/i386/i386.md 7 Aug 2005 20:30:11 -0000
***************
*** 1200,1207 ****
              (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" ""))
              (const_string "lea")
           ]
           (const_string "imov")))
--- 1200,1206 ----
              (const_string "sselog1")
            (eq_attr "alternative" "7,8,9,10,11")
              (const_string "ssemov")
!           (match_operand:DI 1 "pic_32bit_operand" "")
              (const_string "lea")
           ]
           (const_string "imov")))
***************
*** 2019,2026 ****
              (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" ""))
              (const_string "lea")
           ]
           (const_string "imov")))
--- 2018,2024 ----
              (const_string "ssecvt")
            (eq_attr "alternative" "4")
              (const_string "multi")
!           (match_operand:DI 1 "pic_32bit_operand" "")
              (const_string "lea")
           ]
           (const_string "imov")))
Index: config/i386/predicates.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/predicates.md,v
retrieving revision 1.20
diff -c -3 -p -r1.20 predicates.md
*** config/i386/predicates.md   31 Jul 2005 09:12:33 -0000      1.20
--- config/i386/predicates.md   7 Aug 2005 20:30:11 -0000
***************
*** 318,323 ****
--- 318,345 ----
              (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")

<Prev in Thread] Current Thread [Next in Thread>