aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/config/i386/i386-protos.h47
-rw-r--r--gcc/config/i386/i386.c105
-rw-r--r--gcc/config/i386/predicates.md26
-rw-r--r--gcc/testsuite/gcc.dg/tls/pr24428.c11
5 files changed, 100 insertions, 107 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 15988f7..88c5974 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+2006-10-18 Richard Henderson <rth@redhat.com>
+
+ 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 <dannysmith@users.sourceforge.net>
* 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 6c81d4d..df2ba4e 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 7b3cf6a9..5fe9e3f 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 71dd688..b61d2d2 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 0000000..53b1245
--- /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;
+}