From 60d65bceb8fa0065d353770ec3bb81d8a5de4a49 Mon Sep 17 00:00:00 2001 From: rth Date: Wed, 19 Oct 2005 02:13:37 +0000 Subject: [PATCH] PR target/24428 * config/i386/i386.c (legitimate_constant_p): Check SYMBOL_REF_TLS_MODEL directly. Don't fallthru to SYMBOL_REF if LABEL_REF. (legitimate_pic_operand_p): Test SYMBOL_REF_TLS_MODEL directly. (legitimate_pic_address_disp_p): Reorg CONST checking to make sure SYMBOL_REF_TLS_MODEL is tested. Test SYMBOL_REF_TLS_MODEL directly. (print_operand_address): Likewise. * config/i386/predicates.md (x86_64_immediate_operand): Test SYMBOL_REF_TLS_MODEL properly inside CONST. (x86_64_zext_immediate_operand): Likewise. (global_dynamic_symbolic_operand, local_dynamic_symbolic_operand, initial_exec_symbolic_operand, local_exec_symbolic_operand): Remove. * config/i386/i386-protos.h: Remove predicates.md entries. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@105592 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 18 +++++++ gcc/config/i386/i386-protos.h | 47 ----------------- gcc/config/i386/i386.c | 105 ++++++++++++++++++++++--------------- gcc/config/i386/predicates.md | 26 +++------ gcc/testsuite/gcc.dg/tls/pr24428.c | 11 ++++ 5 files changed, 100 insertions(+), 107 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tls/pr24428.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 15988f7f71b..88c5974f207 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2006-10-18 Richard Henderson + + PR target/24428 + * config/i386/i386.c (legitimate_constant_p): Check + SYMBOL_REF_TLS_MODEL directly. Don't fallthru to SYMBOL_REF + if LABEL_REF. + (legitimate_pic_operand_p): Test SYMBOL_REF_TLS_MODEL directly. + (legitimate_pic_address_disp_p): Reorg CONST checking to make + sure SYMBOL_REF_TLS_MODEL is tested. Test SYMBOL_REF_TLS_MODEL + directly. + (print_operand_address): Likewise. + * config/i386/predicates.md (x86_64_immediate_operand): Test + SYMBOL_REF_TLS_MODEL properly inside CONST. + (x86_64_zext_immediate_operand): Likewise. + (global_dynamic_symbolic_operand, local_dynamic_symbolic_operand, + initial_exec_symbolic_operand, local_exec_symbolic_operand): Remove. + * config/i386/i386-protos.h: Remove predicates.md entries. + 2005-10-18 Danny Smith * config/i386/winnt-cxx.c (i386_pe_adjust_class_at_definition): diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 6c81d4d7e9f..df2ba4e8841 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -46,53 +46,6 @@ extern int symbolic_reference_mentioned_p (rtx); extern bool extended_reg_mentioned_p (rtx); extern bool x86_extended_QIreg_mentioned_p (rtx); extern bool x86_extended_reg_mentioned_p (rtx); - -extern int any_fp_register_operand (rtx, enum machine_mode); -extern int register_and_not_any_fp_reg_operand (rtx, enum machine_mode); - -extern int fp_register_operand (rtx, enum machine_mode); -extern int register_and_not_fp_reg_operand (rtx, enum machine_mode); - -extern int x86_64_general_operand (rtx, enum machine_mode); -extern int x86_64_szext_general_operand (rtx, enum machine_mode); -extern int x86_64_nonmemory_operand (rtx, enum machine_mode); -extern int x86_64_szext_nonmemory_operand (rtx, enum machine_mode); -extern int x86_64_immediate_operand (rtx, enum machine_mode); -extern int x86_64_zext_immediate_operand (rtx, enum machine_mode); -extern int symbolic_operand (rtx, enum machine_mode); -extern int tls_symbolic_operand (rtx, enum machine_mode); -extern int global_dynamic_symbolic_operand (rtx, enum machine_mode); -extern int local_dynamic_symbolic_operand (rtx, enum machine_mode); -extern int initial_exec_symbolic_operand (rtx, enum machine_mode); -extern int local_exec_symbolic_operand (rtx, enum machine_mode); -extern int pic_symbolic_operand (rtx, enum machine_mode); -extern int call_insn_operand (rtx, enum machine_mode); -extern int sibcall_insn_operand (rtx, enum machine_mode); -extern int constant_call_address_operand (rtx, enum machine_mode); -extern int const0_operand (rtx, enum machine_mode); -extern int const1_operand (rtx, enum machine_mode); -extern int const248_operand (rtx, enum machine_mode); -extern int incdec_operand (rtx, enum machine_mode); -extern int reg_no_sp_operand (rtx, enum machine_mode); -extern int mmx_reg_operand (rtx, enum machine_mode); -extern int general_no_elim_operand (rtx, enum machine_mode); -extern int nonmemory_no_elim_operand (rtx, enum machine_mode); -extern int q_regs_operand (rtx, enum machine_mode); -extern int non_q_regs_operand (rtx, enum machine_mode); -extern int sse_comparison_operator (rtx, enum machine_mode); -extern int fcmov_comparison_operator (rtx, enum machine_mode); -extern int cmp_fp_expander_operand (rtx, enum machine_mode); -extern int ix86_comparison_operator (rtx, enum machine_mode); -extern int ext_register_operand (rtx, enum machine_mode); -extern int binary_fp_operator (rtx, enum machine_mode); -extern int mult_operator (rtx, enum machine_mode); -extern int div_operator (rtx, enum machine_mode); -extern int arith_or_logical_operator (rtx, enum machine_mode); -extern int promotable_binary_operator (rtx, enum machine_mode); -extern int memory_displacement_operand (rtx, enum machine_mode); -extern int cmpsi_operand (rtx, enum machine_mode); -extern int long_memory_operand (rtx, enum machine_mode); -extern int aligned_operand (rtx, enum machine_mode); extern enum machine_mode ix86_cc_mode (enum rtx_code, rtx, rtx); extern int ix86_expand_movmem (rtx, rtx, rtx, rtx); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7b3cf6a9255..5fe9e3f0062 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5423,21 +5423,27 @@ legitimate_constant_p (rtx x) return TARGET_64BIT; case UNSPEC_TPOFF: case UNSPEC_NTPOFF: - return local_exec_symbolic_operand (XVECEXP (x, 0, 0), Pmode); + x = XVECEXP (x, 0, 0); + return (GET_CODE (x) == SYMBOL_REF + && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC); case UNSPEC_DTPOFF: - return local_dynamic_symbolic_operand (XVECEXP (x, 0, 0), Pmode); + x = XVECEXP (x, 0, 0); + return (GET_CODE (x) == SYMBOL_REF + && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC); default: return false; } /* We must have drilled down to a symbol. */ - if (!symbolic_operand (x, Pmode)) + if (GET_CODE (x) == LABEL_REF) + return true; + if (GET_CODE (x) != SYMBOL_REF) return false; /* FALLTHRU */ case SYMBOL_REF: /* TLS symbols are never valid. */ - if (tls_symbolic_operand (x, Pmode)) + if (SYMBOL_REF_TLS_MODEL (x)) return false; break; @@ -5491,7 +5497,9 @@ legitimate_pic_operand_p (rtx x) case UNSPEC_GOTOFF: return TARGET_64BIT; case UNSPEC_TPOFF: - return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode); + x = XVECEXP (inner, 0, 0); + return (GET_CODE (x) == SYMBOL_REF + && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC); default: return false; } @@ -5518,32 +5526,38 @@ legitimate_pic_address_disp_p (rtx disp) when they are not dynamic symbols. */ if (TARGET_64BIT) { - /* TLS references should always be enclosed in UNSPEC. */ - if (tls_symbolic_operand (disp, GET_MODE (disp))) - return 0; - if (GET_CODE (disp) == SYMBOL_REF - && !SYMBOL_REF_FAR_ADDR_P (disp) - && SYMBOL_REF_LOCAL_P (disp)) - return 1; - if (GET_CODE (disp) == LABEL_REF) - return 1; - if (GET_CODE (disp) == CONST - && GET_CODE (XEXP (disp, 0)) == PLUS) + rtx op0 = disp, op1; + + switch (GET_CODE (disp)) { - rtx op0 = XEXP (XEXP (disp, 0), 0); - rtx op1 = XEXP (XEXP (disp, 0), 1); + case LABEL_REF: + return true; + + case CONST: + if (GET_CODE (XEXP (disp, 0)) != PLUS) + break; + op0 = XEXP (XEXP (disp, 0), 0); + op1 = XEXP (XEXP (disp, 0), 1); + if (GET_CODE (op1) != CONST_INT + || INTVAL (op1) >= 16*1024*1024 + || INTVAL (op1) < -16*1024*1024) + break; + if (GET_CODE (op0) == LABEL_REF) + return true; + if (GET_CODE (op0) != SYMBOL_REF) + break; + /* FALLTHRU */ + case SYMBOL_REF: /* TLS references should always be enclosed in UNSPEC. */ - if (tls_symbolic_operand (op0, GET_MODE (op0))) - return 0; - if (((GET_CODE (op0) == SYMBOL_REF - && !SYMBOL_REF_FAR_ADDR_P (op0) - && SYMBOL_REF_LOCAL_P (op0)) - || GET_CODE (op0) == LABEL_REF) - && GET_CODE (op1) == CONST_INT - && INTVAL (op1) < 16*1024*1024 - && INTVAL (op1) >= -16*1024*1024) - return 1; + if (SYMBOL_REF_TLS_MODEL (op0)) + return false; + if (!SYMBOL_REF_FAR_ADDR_P (op0) && SYMBOL_REF_LOCAL_P (op0)) + return true; + break; + + default: + break; } } if (GET_CODE (disp) != CONST) @@ -5600,11 +5614,17 @@ legitimate_pic_address_disp_p (rtx disp) case UNSPEC_INDNTPOFF: if (saw_plus) return false; - return initial_exec_symbolic_operand (XVECEXP (disp, 0, 0), Pmode); + disp = XVECEXP (disp, 0, 0); + return (GET_CODE (disp) == SYMBOL_REF + && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_INITIAL_EXEC); case UNSPEC_NTPOFF: - return local_exec_symbolic_operand (XVECEXP (disp, 0, 0), Pmode); + disp = XVECEXP (disp, 0, 0); + return (GET_CODE (disp) == SYMBOL_REF + && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_EXEC); case UNSPEC_DTPOFF: - return local_dynamic_symbolic_operand (XVECEXP (disp, 0, 0), Pmode); + disp = XVECEXP (disp, 0, 0); + return (GET_CODE (disp) == SYMBOL_REF + && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_DYNAMIC); } return 0; @@ -6856,7 +6876,7 @@ get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED) rtx x = *px; if (GET_CODE (x) == SYMBOL_REF - && local_dynamic_symbolic_operand (x, Pmode)) + && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC) { cfun->machine->some_ld_name = XSTR (x, 0); return 1; @@ -7329,16 +7349,17 @@ print_operand_address (FILE *file, rtx addr) output_addr_const (file, disp); /* Use one byte shorter RIP relative addressing for 64bit mode. */ - if (TARGET_64BIT - && ((GET_CODE (disp) == SYMBOL_REF - && ! tls_symbolic_operand (disp, GET_MODE (disp))) - || GET_CODE (disp) == LABEL_REF - || (GET_CODE (disp) == CONST - && GET_CODE (XEXP (disp, 0)) == PLUS - && (GET_CODE (XEXP (XEXP (disp, 0), 0)) == SYMBOL_REF - || GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF) - && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT))) - fputs ("(%rip)", file); + if (TARGET_64BIT) + { + if (GET_CODE (disp) == CONST + && GET_CODE (XEXP (disp, 0)) == PLUS + && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT) + disp = XEXP (XEXP (disp, 0), 0); + if (GET_CODE (disp) == LABEL_REF + || (GET_CODE (disp) == SYMBOL_REF + && SYMBOL_REF_TLS_MODEL (disp) == 0)) + fputs ("(%rip)", file); + } } else { diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 71dd6880030..b61d2d25bde 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -108,7 +108,7 @@ library. Don't count TLS SYMBOL_REFs here, since they should fit only if inside of UNSPEC handled below. */ /* TLS symbols are not constant. */ - if (tls_symbolic_operand (op, Pmode)) + if (SYMBOL_REF_TLS_MODEL (op)) return false; return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL || (ix86_cmodel == CM_MEDIUM && !SYMBOL_REF_FAR_ADDR_P (op))); @@ -147,6 +147,9 @@ switch (GET_CODE (op1)) { case SYMBOL_REF: + /* TLS symbols are not constant. */ + if (SYMBOL_REF_TLS_MODEL (op1)) + return 0; /* For CM_SMALL assume that latest object is 16MB before end of 31bits boundary. We may also accept pretty large negative constants knowing that all objects are @@ -225,7 +228,7 @@ case SYMBOL_REF: /* For certain code models, the symbolic references are known to fit. */ /* TLS symbols are not constant. */ - if (tls_symbolic_operand (op, Pmode)) + if (SYMBOL_REF_TLS_MODEL (op)) return false; return (ix86_cmodel == CM_SMALL || (ix86_cmodel == CM_MEDIUM @@ -248,6 +251,9 @@ switch (GET_CODE (op1)) { case SYMBOL_REF: + /* TLS symbols are not constant. */ + if (SYMBOL_REF_TLS_MODEL (op1)) + return 0; /* For small code model we may accept pretty large positive offsets, since one bit is available for free. Negative offsets are limited by the size of NULL pointer area @@ -456,22 +462,6 @@ (and (match_code "symbol_ref") (match_test "SYMBOL_REF_TLS_MODEL (op) != 0"))) -(define_predicate "global_dynamic_symbolic_operand" - (and (match_code "symbol_ref") - (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_GLOBAL_DYNAMIC"))) - -(define_predicate "local_dynamic_symbolic_operand" - (and (match_code "symbol_ref") - (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_DYNAMIC"))) - -(define_predicate "initial_exec_symbolic_operand" - (and (match_code "symbol_ref") - (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC"))) - -(define_predicate "local_exec_symbolic_operand" - (and (match_code "symbol_ref") - (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC"))) - ;; Test for a pc-relative call operand (define_predicate "constant_call_address_operand" (ior (match_code "symbol_ref") diff --git a/gcc/testsuite/gcc.dg/tls/pr24428.c b/gcc/testsuite/gcc.dg/tls/pr24428.c new file mode 100644 index 00000000000..53b1245d509 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/pr24428.c @@ -0,0 +1,11 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +__thread double thrtest[81]; +int main () +{ + int i; + for (i = 0; i < 81; i++) + thrtest[i] = 1.0; + return 0; +} -- 2.11.4.GIT