aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog34
-rw-r--r--gcc/config/ia64/ia64-protos.h2
-rw-r--r--gcc/config/ia64/ia64.c326
-rw-r--r--gcc/config/ia64/ia64.h10
-rw-r--r--gcc/config/ia64/ia64.md252
-rw-r--r--gcc/config/ia64/sysv4.h7
-rwxr-xr-xgcc/configure43
-rw-r--r--gcc/configure.in17
8 files changed, 580 insertions, 111 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 001ff8a..b1c1dd3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,37 @@
+2002-05-25 Richard Henderson <rth@redhat.com>
+
+ * configure.in (HAVE_AS_TLS): Add ia64 test.
+ * configure: Rebuild.
+ * config/ia64/ia64.c (ia64_tls_size_string, ia64_tls_size): New.
+ (override_options): Set it.
+ (TARGET_HAVE_TLS): New.
+ (sdata_symbolic_operand): Look for 's'.
+ (tls_symbolic_operand): New.
+ (ia64_expand_load_address): Abort for tls symbols.
+ (gen_tls_get_addr): New.
+ (gen_thread_pointer): New.
+ (ia64_expand_move): Split out from movdi. Handle tls symbols.
+ (rtx_needs_barrier): Add new unspecs.
+ (ia64_encode_section_info): Handle tls symbols.
+ (ia64_strip_name_encoding): Strip two encoding chars.
+ * config/ia64/ia64.h (ia64_tls_size, ia64_tls_size_string): New.
+ (TARGET_TLS14, TARGET_TLS22, TARGET_TLS64): New.
+ (TARGET_OPTIONS): Add tls-size.
+ (ENCODE_SECTION_INFO_CHAR): Rename from SDATA_NAME_FLAG_CHAR.
+ * config/ia64/ia64.md (UNSPEC_LTOFF_DTPMOD, UNSPEC_LTOFF_DTPREL,
+ UNSPEC_DTPREL, UNSPEC_LTOFF_TPREL, UNSPEC_TPREL, UNSPEC_LD_BASE): New.
+ (movqi, movhi, movsi, movdi, movti): Use ia64_expand_move.
+ (movsf, movdf): Likewise.
+ (movdi_symbolic): Use match_scratch. Don't split if we won't
+ have a scratch availiable.
+ (load_ltoff_dtpmod, load_dtprel, load_dtprel64, load_dtprel22,
+ add_dtprel, add_dtprel14, add_dtprel22, load_ltoff_tprel, load_tprel,
+ load_tprel64, load_tprel22, add_tprel, add_tprel14, add_tprel22): New.
+ * config/ia64/ia64-protos.h: Update.
+ * config/ia64/sysv4.h (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Use
+ sdata_symbolic_operand.
+ (ASM_OUTPUT_LABELREF): Strip two characters.
+
2002-05-25 Kazu Hirata <kazu@cs.umass.edu>
* combine.c (simplify_set): Remove an unnecessary subreg.
diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h
index d28de45..204740a 100644
--- a/gcc/config/ia64/ia64-protos.h
+++ b/gcc/config/ia64/ia64-protos.h
@@ -31,6 +31,7 @@ extern int call_operand PARAMS((rtx, enum machine_mode));
extern int sdata_symbolic_operand PARAMS((rtx, enum machine_mode));
extern int got_symbolic_operand PARAMS((rtx, enum machine_mode));
extern int symbolic_operand PARAMS((rtx, enum machine_mode));
+extern int tls_symbolic_operand PARAMS((rtx, enum machine_mode));
extern int function_operand PARAMS((rtx, enum machine_mode));
extern int setjmp_operand PARAMS((rtx, enum machine_mode));
extern int move_operand PARAMS((rtx, enum machine_mode));
@@ -68,6 +69,7 @@ extern int destination_tfmode_operand PARAMS((rtx, enum machine_mode));
extern int tfreg_or_fp01_operand PARAMS((rtx, enum machine_mode));
extern int basereg_operand PARAMS((rtx, enum machine_mode));
+extern rtx ia64_expand_move PARAMS ((rtx, rtx));
extern int ia64_move_ok PARAMS((rtx, rtx));
extern int ia64_depz_field_mask PARAMS((rtx, rtx));
extern rtx ia64_gp_save_reg PARAMS((int));
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 1517a8b..1445ae9 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -94,6 +94,13 @@ static const char * const ia64_output_reg_names[8] =
/* String used with the -mfixed-range= option. */
const char *ia64_fixed_range_string;
+/* Determines whether we use adds, addl, or movl to generate our
+ TLS immediate offsets. */
+int ia64_tls_size = 22;
+
+/* String used with the -mtls-size= option. */
+const char *ia64_tls_size_string;
+
/* Determines whether we run our final scheduling pass or not. We always
avoid the normal second scheduling pass. */
static int ia64_flag_schedule_insns2;
@@ -103,6 +110,8 @@ static int ia64_flag_schedule_insns2;
unsigned int ia64_section_threshold;
+static rtx gen_tls_get_addr PARAMS ((void));
+static rtx gen_thread_pointer PARAMS ((void));
static int find_gr_spill PARAMS ((int));
static int next_scratch_gr_reg PARAMS ((void));
static void mark_reg_gr_used_mask PARAMS ((rtx, void *));
@@ -230,6 +239,11 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_SCHED_REORDER2
#define TARGET_SCHED_REORDER2 ia64_sched_reorder2
+#ifdef HAVE_AS_TLS
+#undef TARGET_HAVE_TLS
+#define TARGET_HAVE_TLS true
+#endif
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
@@ -266,7 +280,10 @@ sdata_symbolic_operand (op, mode)
if (CONSTANT_POOL_ADDRESS_P (op))
return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold;
else
- return XSTR (op, 0)[0] == SDATA_NAME_FLAG_CHAR;
+ {
+ const char *str = XSTR (op, 0);
+ return (str[0] == ENCODE_SECTION_INFO_CHAR && str[1] == 's');
+ }
default:
break;
@@ -340,6 +357,35 @@ symbolic_operand (op, mode)
return 0;
}
+/* Return tls_model if OP refers to a TLS symbol. */
+
+int
+tls_symbolic_operand (op, mode)
+ rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ const char *str;
+
+ if (GET_CODE (op) != SYMBOL_REF)
+ return 0;
+ str = XSTR (op, 0);
+ if (str[0] != ENCODE_SECTION_INFO_CHAR)
+ return 0;
+ switch (str[1])
+ {
+ case 'G':
+ return TLS_MODEL_GLOBAL_DYNAMIC;
+ case 'L':
+ return TLS_MODEL_LOCAL_DYNAMIC;
+ case 'i':
+ return TLS_MODEL_INITIAL_EXEC;
+ case 'l':
+ return TLS_MODEL_LOCAL_EXEC;
+ }
+ return 0;
+}
+
+
/* Return 1 if OP refers to a function. */
int
@@ -953,6 +999,9 @@ ia64_expand_load_address (dest, src, scratch)
else
temp = dest;
+ if (tls_symbolic_operand (src, Pmode))
+ abort ();
+
if (TARGET_AUTO_PIC)
emit_insn (gen_load_gprel64 (temp, src));
else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FLAG (src))
@@ -995,6 +1044,185 @@ ia64_expand_load_address (dest, src, scratch)
emit_move_insn (dest, temp);
}
+static rtx
+gen_tls_get_addr ()
+{
+ static rtx tga;
+ if (!tga)
+ {
+ tga = init_one_libfunc ("__tls_get_addr");
+ ggc_add_rtx_root (&tga, 1);
+ }
+ return tga;
+}
+
+static rtx
+gen_thread_pointer ()
+{
+ static rtx tp;
+ if (!tp)
+ {
+ tp = gen_rtx_REG (Pmode, 13);
+ RTX_UNCHANGING_P (tp);
+ ggc_add_rtx_root (&tp, 1);
+ }
+ return tp;
+}
+
+rtx
+ia64_expand_move (op0, op1)
+ rtx op0, op1;
+{
+ enum machine_mode mode = GET_MODE (op0);
+
+ if (!reload_in_progress && !reload_completed && !ia64_move_ok (op0, op1))
+ op1 = force_reg (mode, op1);
+
+ if (mode == Pmode)
+ {
+ enum tls_model tls_kind;
+ if ((tls_kind = tls_symbolic_operand (op1, Pmode)))
+ {
+ rtx tga_op1, tga_op2, tga_ret, tga_eqv, tmp, insns;
+
+ switch (tls_kind)
+ {
+ case TLS_MODEL_GLOBAL_DYNAMIC:
+ start_sequence ();
+
+ tga_op1 = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
+ tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
+ RTX_UNCHANGING_P (tga_op1) = 1;
+
+ tga_op2 = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_dtprel (tga_op2, op1));
+ tga_op2 = gen_rtx_MEM (Pmode, tga_op2);
+ RTX_UNCHANGING_P (tga_op2) = 1;
+
+ tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
+ LCT_CONST, Pmode, 2, tga_op1,
+ Pmode, tga_op2, Pmode);
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_libcall_block (insns, op0, tga_ret, op1);
+ return NULL_RTX;
+
+ case TLS_MODEL_LOCAL_DYNAMIC:
+ /* ??? This isn't the completely proper way to do local-dynamic
+ If the call to __tls_get_addr is used only by a single symbol,
+ then we should (somehow) move the dtprel to the second arg
+ to avoid the extra add. */
+ start_sequence ();
+
+ tga_op1 = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
+ tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
+ RTX_UNCHANGING_P (tga_op1) = 1;
+
+ tga_op2 = const0_rtx;
+
+ tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
+ LCT_CONST, Pmode, 2, tga_op1,
+ Pmode, tga_op2, Pmode);
+
+ insns = get_insns ();
+ end_sequence ();
+
+ tga_eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_LD_BASE);
+ tmp = gen_reg_rtx (Pmode);
+ emit_libcall_block (insns, tmp, tga_ret, tga_eqv);
+
+ if (register_operand (op0, Pmode))
+ tga_ret = op0;
+ else
+ tga_ret = gen_reg_rtx (Pmode);
+ if (TARGET_TLS64)
+ {
+ emit_insn (gen_load_dtprel (tga_ret, op1));
+ emit_insn (gen_adddi3 (tga_ret, tmp, tga_ret));
+ }
+ else
+ emit_insn (gen_add_dtprel (tga_ret, tmp, op1));
+ if (tga_ret == op0)
+ return NULL_RTX;
+ op1 = tga_ret;
+ break;
+
+ case TLS_MODEL_INITIAL_EXEC:
+ tmp = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_tprel (tmp, op1));
+ tmp = gen_rtx_MEM (Pmode, tmp);
+ RTX_UNCHANGING_P (tmp) = 1;
+ tmp = force_reg (Pmode, tmp);
+
+ if (register_operand (op0, Pmode))
+ op1 = op0;
+ else
+ op1 = gen_reg_rtx (Pmode);
+ emit_insn (gen_adddi3 (op1, tmp, gen_thread_pointer ()));
+ if (op1 == op0)
+ return NULL_RTX;
+ break;
+
+ case TLS_MODEL_LOCAL_EXEC:
+ if (register_operand (op0, Pmode))
+ tmp = op0;
+ else
+ tmp = gen_reg_rtx (Pmode);
+ if (TARGET_TLS64)
+ {
+ emit_insn (gen_load_tprel (tmp, op1));
+ emit_insn (gen_adddi3 (tmp, gen_thread_pointer (), tmp));
+ }
+ else
+ emit_insn (gen_add_tprel (tmp, gen_thread_pointer (), op1));
+ if (tmp == op0)
+ return NULL_RTX;
+ op1 = tmp;
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ else if (!TARGET_NO_PIC && symbolic_operand (op1, DImode))
+ {
+ /* Before optimization starts, delay committing to any particular
+ type of PIC address load. If this function gets deferred, we
+ may acquire information that changes the value of the
+ sdata_symbolic_operand predicate.
+
+ But don't delay for function pointers. Loading a function address
+ actually loads the address of the descriptor not the function.
+ If we represent these as SYMBOL_REFs, then they get cse'd with
+ calls, and we end up with calls to the descriptor address instead
+ of calls to the function address. Functions are not candidates
+ for sdata anyways.
+
+ Don't delay for LABEL_REF because the splitter loses REG_LABEL
+ notes. Don't delay for pool addresses on general principals;
+ they'll never become non-local behind our back. */
+
+ if (rtx_equal_function_value_matters
+ && GET_CODE (op1) != LABEL_REF
+ && ! (GET_CODE (op1) == SYMBOL_REF
+ && (SYMBOL_REF_FLAG (op1)
+ || CONSTANT_POOL_ADDRESS_P (op1)
+ || STRING_POOL_ADDRESS_P (op1))))
+ emit_insn (gen_movdi_symbolic (op0, op1));
+ else
+ ia64_expand_load_address (op0, op1, NULL_RTX);
+ return NULL_RTX;
+ }
+ }
+
+ return op1;
+}
+
rtx
ia64_gp_save_reg (setjmp_p)
int setjmp_p;
@@ -3975,6 +4203,16 @@ ia64_override_options ()
if (ia64_fixed_range_string)
fix_range (ia64_fixed_range_string);
+ if (ia64_tls_size_string)
+ {
+ char *end;
+ unsigned long tmp = strtoul (ia64_tls_size_string, &end, 10);
+ if (*end || (tmp != 14 && tmp != 22 && tmp != 64))
+ error ("bad value (%s) for -mtls-size= switch", ia64_tls_size_string);
+ else
+ ia64_tls_size = tmp;
+ }
+
ia64_flag_schedule_insns2 = flag_schedule_insns_after_reload;
flag_schedule_insns_after_reload = 0;
@@ -4595,6 +4833,20 @@ rtx_needs_barrier (x, flags, pred)
case UNSPEC:
switch (XINT (x, 1))
{
+ case UNSPEC_LTOFF_DTPMOD:
+ case UNSPEC_LTOFF_DTPREL:
+ case UNSPEC_DTPREL:
+ case UNSPEC_LTOFF_TPREL:
+ case UNSPEC_TPREL:
+ case UNSPEC_PRED_REL_MUTEX:
+ case UNSPEC_PIC_CALL:
+ case UNSPEC_MF:
+ case UNSPEC_FETCHADD_ACQ:
+ case UNSPEC_BSP_VALUE:
+ case UNSPEC_FLUSHRS:
+ case UNSPEC_BUNDLE_SELECTOR:
+ break;
+
case UNSPEC_GR_SPILL:
case UNSPEC_GR_RESTORE:
{
@@ -4614,15 +4866,6 @@ rtx_needs_barrier (x, flags, pred)
need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
break;
- case UNSPEC_PRED_REL_MUTEX:
- case UNSPEC_PIC_CALL:
- case UNSPEC_MF:
- case UNSPEC_FETCHADD_ACQ:
- case UNSPEC_BSP_VALUE:
- case UNSPEC_FLUSHRS:
- case UNSPEC_BUNDLE_SELECTOR:
- break;
-
case UNSPEC_ADDP4:
need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
break;
@@ -6910,8 +7153,9 @@ ia64_encode_section_info (decl, first)
int first ATTRIBUTE_UNUSED;
{
const char *symbol_str;
- bool is_local, is_small;
+ bool is_local;
rtx symbol;
+ char encoding = 0;
if (TREE_CODE (decl) == FUNCTION_DECL)
{
@@ -6930,40 +7174,66 @@ ia64_encode_section_info (decl, first)
is_local = (*targetm.binds_local_p) (decl);
+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
+ {
+ enum tls_model kind;
+ if (!flag_pic)
+ {
+ if (is_local)
+ kind = TLS_MODEL_LOCAL_EXEC;
+ else
+ kind = TLS_MODEL_INITIAL_EXEC;
+ }
+ else if (is_local)
+ kind = TLS_MODEL_LOCAL_DYNAMIC;
+ else
+ kind = TLS_MODEL_GLOBAL_DYNAMIC;
+ if (kind < flag_tls_default)
+ kind = flag_tls_default;
+
+ encoding = " GLil"[kind];
+ }
/* Determine if DECL will wind up in .sdata/.sbss. */
- is_small = ia64_in_small_data_p (decl);
+ else if (is_local && ia64_in_small_data_p (decl))
+ encoding = 's';
/* Finally, encode this into the symbol string. */
- if (is_local && is_small)
+ if (encoding)
{
char *newstr;
size_t len;
- if (symbol_str[0] == SDATA_NAME_FLAG_CHAR)
- return;
+ if (symbol_str[0] == ENCODE_SECTION_INFO_CHAR)
+ {
+ if (encoding == symbol_str[1])
+ return;
+ /* ??? Sdata became thread or thread becaome not thread. Lose. */
+ abort ();
+ }
- len = strlen (symbol_str) + 1;
- newstr = alloca (len + 1);
- newstr[0] = SDATA_NAME_FLAG_CHAR;
- memcpy (newstr + 1, symbol_str, len);
+ len = strlen (symbol_str);
+ newstr = alloca (len + 3);
+ newstr[0] = ENCODE_SECTION_INFO_CHAR;
+ newstr[1] = encoding;
+ memcpy (newstr + 2, symbol_str, len + 1);
- XSTR (symbol, 0) = ggc_alloc_string (newstr, len);
+ XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2);
}
- /* This decl is marked as being in small data/bss but it shouldn't
- be; one likely explanation for this is that the decl has been
- moved into a different section from the one it was in when
- targetm.encode_section_info was first called. Remove the '@'. */
- else if (symbol_str[0] == SDATA_NAME_FLAG_CHAR)
- XSTR (symbol, 0) = ggc_strdup (symbol_str + 1);
+ /* This decl is marked as being in small data/bss but it shouldn't be;
+ one likely explanation for this is that the decl has been moved into
+ a different section from the one it was in when encode_section_info
+ was first called. Remove the encoding. */
+ else if (symbol_str[0] == ENCODE_SECTION_INFO_CHAR)
+ XSTR (symbol, 0) = ggc_strdup (symbol_str + 2);
}
static const char *
ia64_strip_name_encoding (str)
const char *str;
{
- if (str[0] == SDATA_NAME_FLAG_CHAR)
- str++;
+ if (str[0] == ENCODE_SECTION_INFO_CHAR)
+ str += 2;
if (str[0] == '*')
str++;
return str;
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 0d3d362..d1e0556 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -109,6 +109,11 @@ extern int target_flags;
#define TARGET_DWARF2_ASM (target_flags & MASK_DWARF2_ASM)
+extern int ia64_tls_size;
+#define TARGET_TLS14 (ia64_tls_size == 14)
+#define TARGET_TLS22 (ia64_tls_size == 22)
+#define TARGET_TLS64 (ia64_tls_size == 64)
+
/* This macro defines names of command options to set and clear bits in
`target_flags'. Its definition is an initializer with a subgrouping for
each command option. */
@@ -177,10 +182,13 @@ extern int target_flags;
subgrouping for each command option. */
extern const char *ia64_fixed_range_string;
+extern const char *ia64_tls_size_string;
#define TARGET_OPTIONS \
{ \
{ "fixed-range=", &ia64_fixed_range_string, \
N_("Specify range of registers to make fixed")}, \
+ { "tls-size=", &ia64_tls_size_string, \
+ N_("Specify bit size of immediate TLS offsets")}, \
}
/* Sometimes certain combinations of command options do not make sense on a
@@ -1774,7 +1782,7 @@ do { \
#define BSS_SECTION_ASM_OP "\t.bss"
-#define SDATA_NAME_FLAG_CHAR '@'
+#define ENCODE_SECTION_INFO_CHAR '@'
#define IA64_DEFAULT_GVALUE 8
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index d81d6ac..8bfffe3 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -49,20 +49,28 @@
;; ??? Need a better way to describe alternate fp status registers.
(define_constants
- [(UNSPEC_GR_SPILL 1)
- (UNSPEC_GR_RESTORE 2)
- (UNSPEC_FR_SPILL 3)
- (UNSPEC_FR_RESTORE 4)
- (UNSPEC_FR_RECIP_APPROX 5)
- (UNSPEC_PRED_REL_MUTEX 7)
- (UNSPEC_POPCNT 8)
- (UNSPEC_PIC_CALL 9)
- (UNSPEC_MF 12)
- (UNSPEC_CMPXCHG_ACQ 13)
- (UNSPEC_FETCHADD_ACQ 19)
- (UNSPEC_BSP_VALUE 20)
- (UNSPEC_FLUSHRS 21)
- (UNSPEC_BUNDLE_SELECTOR 22)
+ [; Relocations
+ (UNSPEC_LTOFF_DTPMOD 0)
+ (UNSPEC_LTOFF_DTPREL 1)
+ (UNSPEC_DTPREL 2)
+ (UNSPEC_LTOFF_TPREL 3)
+ (UNSPEC_TPREL 4)
+
+ (UNSPEC_LD_BASE 9)
+ (UNSPEC_GR_SPILL 10)
+ (UNSPEC_GR_RESTORE 11)
+ (UNSPEC_FR_SPILL 12)
+ (UNSPEC_FR_RESTORE 13)
+ (UNSPEC_FR_RECIP_APPROX 14)
+ (UNSPEC_PRED_REL_MUTEX 15)
+ (UNSPEC_POPCNT 16)
+ (UNSPEC_PIC_CALL 17)
+ (UNSPEC_MF 18)
+ (UNSPEC_CMPXCHG_ACQ 19)
+ (UNSPEC_FETCHADD_ACQ 20)
+ (UNSPEC_BSP_VALUE 21)
+ (UNSPEC_FLUSHRS 22)
+ (UNSPEC_BUNDLE_SELECTOR 23)
(UNSPEC_ADDP4 24)
(UNSPEC_PROLOGUE_USE 25)
])
@@ -72,9 +80,9 @@
(UNSPECV_BLOCKAGE 1)
(UNSPECV_INSN_GROUP_BARRIER 2)
(UNSPECV_BREAK 3)
- (UNSPECV_SET_BSP 5)
- (UNSPECV_PSAC_ALL 8) ; pred.safe_across_calls
- (UNSPECV_PSAC_NORMAL 9)
+ (UNSPECV_SET_BSP 4)
+ (UNSPECV_PSAC_ALL 5) ; pred.safe_across_calls
+ (UNSPECV_PSAC_NORMAL 6)
])
;; ::::::::::::::::::::
@@ -276,9 +284,10 @@
(match_operand:QI 1 "general_operand" ""))]
""
{
- if (! reload_in_progress && ! reload_completed
- && ! ia64_move_ok (operands[0], operands[1]))
- operands[1] = force_reg (QImode, operands[1]);
+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
+ if (!op1)
+ DONE;
+ operands[1] = op1;
})
(define_insn "*movqi_internal"
@@ -300,9 +309,10 @@
(match_operand:HI 1 "general_operand" ""))]
""
{
- if (! reload_in_progress && ! reload_completed
- && ! ia64_move_ok (operands[0], operands[1]))
- operands[1] = force_reg (HImode, operands[1]);
+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
+ if (!op1)
+ DONE;
+ operands[1] = op1;
})
(define_insn "*movhi_internal"
@@ -324,9 +334,10 @@
(match_operand:SI 1 "general_operand" ""))]
""
{
- if (! reload_in_progress && ! reload_completed
- && ! ia64_move_ok (operands[0], operands[1]))
- operands[1] = force_reg (SImode, operands[1]);
+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
+ if (!op1)
+ DONE;
+ operands[1] = op1;
})
(define_insn "*movsi_internal"
@@ -352,30 +363,10 @@
(match_operand:DI 1 "general_operand" ""))]
""
{
- if (! reload_in_progress && ! reload_completed
- && ! ia64_move_ok (operands[0], operands[1]))
- operands[1] = force_reg (DImode, operands[1]);
- if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
- {
- /* Before optimization starts, delay committing to any particular
- type of PIC address load. If this function gets deferred, we
- may acquire information that changes the value of the
- sdata_symbolic_operand predicate. */
- /* But don't delay for function pointers. Loading a function address
- actually loads the address of the descriptor not the function.
- If we represent these as SYMBOL_REFs, then they get cse'd with
- calls, and we end up with calls to the descriptor address instead of
- calls to the function address. Functions are not candidates for
- sdata anyways. */
- if (rtx_equal_function_value_matters
- && ! (GET_CODE (operands[1]) == SYMBOL_REF
- && SYMBOL_REF_FLAG (operands[1])))
- emit_insn (gen_movdi_symbolic (operands[0], operands[1],
- gen_reg_rtx (DImode)));
- else
- ia64_expand_load_address (operands[0], operands[1], NULL_RTX);
- DONE;
- }
+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
+ if (!op1)
+ DONE;
+ operands[1] = op1;
})
;; This is used during early compilation to delay the decision on
@@ -384,19 +375,22 @@
;; deferred functions, since we may acquire additional information
;; on the variables used in the meantime.
-;; ??? This causes us to lose REG_LABEL notes, because the insn splitter
-;; does not attempt to preserve any REG_NOTES on the input instruction.
-
(define_insn_and_split "movdi_symbolic"
[(set (match_operand:DI 0 "register_operand" "=r")
(match_operand:DI 1 "symbolic_operand" "s"))
- (clobber (match_operand:DI 2 "register_operand" "+r"))
+ (clobber (match_scratch:DI 2 "=r"))
(use (reg:DI 1))]
""
"* abort ();"
- ""
+ "!no_new_pseudos || reload_completed"
[(const_int 0)]
- { ia64_expand_load_address (operands[0], operands[1], operands[2]); DONE; })
+{
+ rtx scratch = operands[2];
+ if (!reload_completed)
+ gen_reg_rtx (Pmode);
+ ia64_expand_load_address (operands[0], operands[1], scratch);
+ DONE;
+})
(define_insn "*movdi_internal"
[(set (match_operand:DI 0 "destination_operand"
@@ -505,6 +499,131 @@
"addl %0 = @ltoff(%1), gp"
[(set_attr "itanium_class" "ialu")])
+(define_insn "load_ltoff_dtpmod"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (reg:DI 1)
+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_LTOFF_DTPMOD)))]
+ ""
+ "addl %0 = @ltoff(@dtpmod(%1)), gp"
+ [(set_attr "itanium_class" "ialu")])
+
+(define_insn "load_ltoff_dtprel"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (reg:DI 1)
+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_LTOFF_DTPREL)))]
+ ""
+ "addl %0 = @ltoff(@dtprel(%1)), gp"
+ [(set_attr "itanium_class" "ialu")])
+
+(define_expand "load_dtprel"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_DTPREL))]
+ ""
+ "")
+
+(define_insn "*load_dtprel64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_DTPREL))]
+ "TARGET_TLS64"
+ "movl %0 = @dtprel(%1)"
+ [(set_attr "itanium_class" "long_i")])
+
+(define_insn "*load_dtprel22"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_DTPREL))]
+ ""
+ "addl %0 = @dtprel(%1), r0"
+ [(set_attr "itanium_class" "ialu")])
+
+(define_expand "add_dtprel"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_DTPREL)))]
+ "!TARGET_TLS64"
+ "")
+
+(define_insn "*add_dtprel14"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_DTPREL)))]
+ "TARGET_TLS14"
+ "adds %0 = @dtprel(%2), %1"
+ [(set_attr "itanium_class" "ialu")])
+
+(define_insn "*add_dtprel22"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "a")
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_DTPREL)))]
+ "TARGET_TLS22"
+ "addl %0 = @dtprel(%2), %1"
+ [(set_attr "itanium_class" "ialu")])
+
+(define_insn "load_ltoff_tprel"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (reg:DI 1)
+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_LTOFF_TPREL)))]
+ ""
+ "addl %0 = @ltoff(@tprel(%1)), gp"
+ [(set_attr "itanium_class" "ialu")])
+
+(define_expand "load_tprel"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_TPREL))]
+ ""
+ "")
+
+(define_insn "*load_tprel64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_TPREL))]
+ "TARGET_TLS64"
+ "movl %0 = @tprel(%1)"
+ [(set_attr "itanium_class" "long_i")])
+
+(define_insn "*load_tprel22"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_TPREL))]
+ ""
+ "addl %0 = @tprel(%1), r0"
+ [(set_attr "itanium_class" "ialu")])
+
+(define_expand "add_tprel"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_TPREL)))]
+ "!TARGET_TLS64"
+ "")
+
+(define_insn "*add_tprel14"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_TPREL)))]
+ "TARGET_TLS14"
+ "adds %0 = @tprel(%2), %1"
+ [(set_attr "itanium_class" "ialu")])
+
+(define_insn "*add_tprel22"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "a")
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_TPREL)))]
+ "TARGET_TLS22"
+ "addl %0 = @tprel(%2), %1"
+ [(set_attr "itanium_class" "ialu")])
+
;; With no offsettable memory references, we've got to have a scratch
;; around to play with the second word.
(define_expand "movti"
@@ -513,9 +632,10 @@
(clobber (match_scratch:DI 2 ""))])]
""
{
- if (! reload_in_progress && ! reload_completed
- && ! ia64_move_ok (operands[0], operands[1]))
- operands[1] = force_reg (TImode, operands[1]);
+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
+ if (!op1)
+ DONE;
+ operands[1] = op1;
})
(define_insn_and_split "*movti_internal"
@@ -630,9 +750,10 @@
(match_operand:SF 1 "general_operand" ""))]
""
{
- if (! reload_in_progress && ! reload_completed
- && ! ia64_move_ok (operands[0], operands[1]))
- operands[1] = force_reg (SFmode, operands[1]);
+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
+ if (!op1)
+ DONE;
+ operands[1] = op1;
})
(define_insn "*movsf_internal"
@@ -655,9 +776,10 @@
(match_operand:DF 1 "general_operand" ""))]
""
{
- if (! reload_in_progress && ! reload_completed
- && ! ia64_move_ok (operands[0], operands[1]))
- operands[1] = force_reg (DFmode, operands[1]);
+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
+ if (!op1)
+ DONE;
+ operands[1] = op1;
})
(define_insn "*movdf_internal"
diff --git a/gcc/config/ia64/sysv4.h b/gcc/config/ia64/sysv4.h
index 1684db1..164beba 100644
--- a/gcc/config/ia64/sysv4.h
+++ b/gcc/config/ia64/sysv4.h
@@ -42,8 +42,7 @@ extern int size_directive_output;
#undef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \
do { \
- if ((DECL) \
- && XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0] == SDATA_NAME_FLAG_CHAR) \
+ if ((DECL) && sdata_symbolic_operand (XEXP (DECL_RTL (DECL), 0), Pmode)) \
sbss_section (); \
else \
bss_section (); \
@@ -62,8 +61,8 @@ do { \
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
do { \
const char *name_ = NAME; \
- if (*name_ == SDATA_NAME_FLAG_CHAR) \
- name_++; \
+ if (*name_ == ENCODE_SECTION_INFO_CHAR) \
+ name_ += 2; \
if (*name_ == '*') \
name_++; \
else \
diff --git a/gcc/configure b/gcc/configure
index 483178d..9db1b43 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -7416,6 +7416,23 @@ foo: .long 25
tls_first_major=2
tls_first_minor=13
;;
+ ia64-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: data8 25
+ .text
+ addl r16 = @ltoff(@dtpmod(foo#)), gp
+ addl r17 = @ltoff(@dtprel(foo#)), gp
+ addl r18 = @ltoff(@tprel(foo#)), gp
+ addl r19 = @dtprel(foo#), gp
+ adds r21 = @dtprel(foo#), r13
+ movl r23 = @dtprel(foo#)
+ addl r20 = @tprel(foo#), gp
+ adds r22 = @tprel(foo#), r13
+ movl r24 = @tprel(foo#)'
+ tls_first_major=2
+ tls_first_minor=13
+ ;;
esac
if test -z "$tls_first_major"; then
:
@@ -7446,7 +7463,7 @@ case "$target" in
# All TARGET_ABI_OSF targets.
alpha*-*-osf* | alpha*-*-linux* | alpha*-*-*bsd*)
echo $ac_n "checking assembler supports explicit relocations""... $ac_c" 1>&6
-echo "configure:7450: checking assembler supports explicit relocations" >&5
+echo "configure:7467: checking assembler supports explicit relocations" >&5
if eval "test \"`echo '$''{'gcc_cv_as_explicit_relocs'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7496,7 +7513,7 @@ EOF
;;
sparc*-*-*)
echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
-echo "configure:7500: checking assembler .register pseudo-op support" >&5
+echo "configure:7517: checking assembler .register pseudo-op support" >&5
if eval "test \"`echo '$''{'gcc_cv_as_register_pseudo_op'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7524,7 +7541,7 @@ EOF
fi
echo $ac_n "checking assembler supports -relax""... $ac_c" 1>&6
-echo "configure:7528: checking assembler supports -relax" >&5
+echo "configure:7545: checking assembler supports -relax" >&5
if eval "test \"`echo '$''{'gcc_cv_as_relax_opt'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7552,7 +7569,7 @@ EOF
fi
echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6
-echo "configure:7556: checking assembler and linker support unaligned pc related relocs" >&5
+echo "configure:7573: checking assembler and linker support unaligned pc related relocs" >&5
if eval "test \"`echo '$''{'gcc_cv_as_sparc_ua_pcrel'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7579,7 +7596,7 @@ EOF
fi
echo $ac_n "checking assembler and linker support unaligned pc related relocs against hidden symbols""... $ac_c" 1>&6
-echo "configure:7583: checking assembler and linker support unaligned pc related relocs against hidden symbols" >&5
+echo "configure:7600: checking assembler and linker support unaligned pc related relocs against hidden symbols" >&5
if eval "test \"`echo '$''{'gcc_cv_as_sparc_ua_pcrel_hidden'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7620,7 +7637,7 @@ EOF
if test "x$gcc_cv_as_flags64" != xno; then
echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
-echo "configure:7624: checking for assembler offsetable %lo() support" >&5
+echo "configure:7641: checking for assembler offsetable %lo() support" >&5
if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7660,7 +7677,7 @@ EOF
i[34567]86-*-* | x86_64-*-*)
echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
-echo "configure:7664: checking assembler instructions" >&5
+echo "configure:7681: checking assembler instructions" >&5
gcc_cv_as_instructions=
if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 9 -o "$gcc_cv_gas_major_version" -gt 2; then
@@ -7687,7 +7704,7 @@ EOF
echo "$ac_t""$gcc_cv_as_instructions" 1>&6
echo $ac_n "checking assembler GOTOFF in data directives""... $ac_c" 1>&6
-echo "configure:7691: checking assembler GOTOFF in data directives" >&5
+echo "configure:7708: checking assembler GOTOFF in data directives" >&5
gcc_cv_as_gotoff_in_data=no
if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x
then
@@ -7717,7 +7734,7 @@ EOF
esac
echo $ac_n "checking assembler dwarf2 debug_line support""... $ac_c" 1>&6
-echo "configure:7721: checking assembler dwarf2 debug_line support" >&5
+echo "configure:7738: checking assembler dwarf2 debug_line support" >&5
gcc_cv_as_dwarf2_debug_line=no
# ??? Not all targets support dwarf2 debug_line, even within a version
# of gas. Moreover, we need to emit a valid instruction to trigger any
@@ -7773,7 +7790,7 @@ fi
echo "$ac_t""$gcc_cv_as_dwarf2_debug_line" 1>&6
echo $ac_n "checking assembler --gdwarf2 support""... $ac_c" 1>&6
-echo "configure:7777: checking assembler --gdwarf2 support" >&5
+echo "configure:7794: checking assembler --gdwarf2 support" >&5
gcc_cv_as_gdwarf2_flag=no
if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x;
then
@@ -7802,7 +7819,7 @@ fi
echo "$ac_t""$gcc_cv_as_gdwarf2_flag" 1>&6
echo $ac_n "checking assembler --gstabs support""... $ac_c" 1>&6
-echo "configure:7806: checking assembler --gstabs support" >&5
+echo "configure:7823: checking assembler --gstabs support" >&5
gcc_cv_as_gstabs_flag=no
if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x;
then
@@ -7830,7 +7847,7 @@ fi
echo "$ac_t""$gcc_cv_as_gstabs_flag" 1>&6
echo $ac_n "checking linker PT_GNU_EH_FRAME support""... $ac_c" 1>&6
-echo "configure:7834: checking linker PT_GNU_EH_FRAME support" >&5
+echo "configure:7851: checking linker PT_GNU_EH_FRAME support" >&5
gcc_cv_ld_eh_frame_hdr=no
if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 12 -o "$gcc_cv_gld_major_version" -gt 2 && grep 'EMUL = elf' ../ld/Makefile > /dev/null; then
@@ -7993,7 +8010,7 @@ fi
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:7997: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:8014: checking whether to enable maintainer-specific portions of Makefiles" >&5
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
if test "${enable_maintainer_mode+set}" = set; then
enableval="$enable_maintainer_mode"
diff --git a/gcc/configure.in b/gcc/configure.in
index 8dcb671..55ad7c4 100644
--- a/gcc/configure.in
+++ b/gcc/configure.in
@@ -1743,6 +1743,23 @@ foo: .long 25
tls_first_major=2
tls_first_minor=13
;;
+ ia64-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: data8 25
+ .text
+ addl r16 = @ltoff(@dtpmod(foo#)), gp
+ addl r17 = @ltoff(@dtprel(foo#)), gp
+ addl r18 = @ltoff(@tprel(foo#)), gp
+ addl r19 = @dtprel(foo#), gp
+ adds r21 = @dtprel(foo#), r13
+ movl r23 = @dtprel(foo#)
+ addl r20 = @tprel(foo#), gp
+ adds r22 = @tprel(foo#), r13
+ movl r24 = @tprel(foo#)'
+ tls_first_major=2
+ tls_first_minor=13
+ ;;
esac
if test -z "$tls_first_major"; then
: