+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):
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);
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;
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;
}
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)
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;
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;
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
{
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)));
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
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
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
(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")
--- /dev/null
+/* { 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;
+}