From 47efdea45ed80d81aac8c2e74208bc0631467b2f Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 8 Aug 2005 18:29:51 +0200 Subject: [PATCH] i386.c (legitimate_pic_address_disp_p): Refuse GOTOFF in 64bit mode. * 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 | 7 +++++++ gcc/config/i386/i386.c | 17 +++++++++++++++-- gcc/config/i386/i386.md | 6 ++---- gcc/config/i386/predicates.md | 22 ++++++++++++++++++++++ 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0996eced0df..fdeef963043 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2005-08-08 Jan Hubicka + + * 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 PR c++/21166 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5afa63f0fec..68589b28da9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index d533408b770..9e7e92ce8e5 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1200,8 +1200,7 @@ (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"))) @@ -2019,8 +2018,7 @@ (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"))) diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index f8ff8049d0f..71dd6880030 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -318,6 +318,28 @@ (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") -- 2.30.2