configure.in (HAVE_AS_TLS): Add ia64 test.

* 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.

From-SVN: r53874
This commit is contained in:
Richard Henderson 2002-05-25 12:51:43 -07:00 committed by Richard Henderson
parent 8c1d52a397
commit 7b6e506ee0
8 changed files with 580 additions and 111 deletions

View File

@ -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.

View File

@ -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));

View File

@ -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;

View File

@ -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

View File

@ -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"

View File

@ -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 \

43
gcc/configure vendored
View File

@ -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"

View File

@ -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
: