sh.c (TARGET_HAVE_TLS): Conditionally define.
* config/sh/sh.c (TARGET_HAVE_TLS): Conditionally define. (prepare_move_operands): Handle TLS operands. (tls_symbolic_operand): New. (nonpic_symbol_mentioned_p): Handle TLS UNSPECs. (legitimize_pic_address): Do nothing for the TLS symbol. (sh_encode_section_info): Handle TLS case. (sh_strip_name_encoding): Drop TLS encoding. * config/sh/sh-protos.h (tls_symbolic_operand): Add prototype. * config/sh/sh.h (SH_TLS_ENCODING): Define. (TLS_SYMNAME_P, STRIP_TLS_ENCODING): Likewise. (ASM_OUTPUT_LABELREF): Drop TLS encoding. (OUTPUT_ADDR_CONST_EXTRA): Handle TLS UNSPECs. * config/sh/sh.md: Define TLS UNSPEC constants. (type): Add tls_load. ("tls_global_dynamic", "tls_local_dynamic"): New insns. ("sym2DTPOFF", "symDTPOFF2reg", "sym2GOTTPOFF"): New expanders. ("tls_initial_exec"): New insn. ("sym2TPOFF", "symTPOFF2reg"): New expanders. ("load_gbr"): New insn. * configure.in (HAVE_AS_TLS): Add sh-*-* and sh[34]*-*-* cases. * configure: Regenerate. From-SVN: r63353
This commit is contained in:
parent
cf88ede3d2
commit
463f02cd03
|
@ -1,3 +1,28 @@
|
||||||
|
2003-02-24 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||||
|
|
||||||
|
* config/sh/sh.c (TARGET_HAVE_TLS): Conditionally define.
|
||||||
|
(prepare_move_operands): Handle TLS operands.
|
||||||
|
(tls_symbolic_operand): New.
|
||||||
|
(nonpic_symbol_mentioned_p): Handle TLS UNSPECs.
|
||||||
|
(legitimize_pic_address): Do nothing for the TLS symbol.
|
||||||
|
(sh_encode_section_info): Handle TLS case.
|
||||||
|
(sh_strip_name_encoding): Drop TLS encoding.
|
||||||
|
* config/sh/sh-protos.h (tls_symbolic_operand): Add prototype.
|
||||||
|
* config/sh/sh.h (SH_TLS_ENCODING): Define.
|
||||||
|
(TLS_SYMNAME_P, STRIP_TLS_ENCODING): Likewise.
|
||||||
|
(ASM_OUTPUT_LABELREF): Drop TLS encoding.
|
||||||
|
(OUTPUT_ADDR_CONST_EXTRA): Handle TLS UNSPECs.
|
||||||
|
* config/sh/sh.md: Define TLS UNSPEC constants.
|
||||||
|
(type): Add tls_load.
|
||||||
|
("tls_global_dynamic", "tls_local_dynamic"): New insns.
|
||||||
|
("sym2DTPOFF", "symDTPOFF2reg", "sym2GOTTPOFF"): New expanders.
|
||||||
|
("tls_initial_exec"): New insn.
|
||||||
|
("sym2TPOFF", "symTPOFF2reg"): New expanders.
|
||||||
|
("load_gbr"): New insn.
|
||||||
|
|
||||||
|
* configure.in (HAVE_AS_TLS): Add sh-*-* and sh[34]*-*-* cases.
|
||||||
|
* configure: Regenerate.
|
||||||
|
|
||||||
2003-02-24 Alan Modra <amodra@bigpond.net.au>
|
2003-02-24 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* calls.c (store_one_arg): Revert 1999-02-16 change. Revert
|
* calls.c (store_one_arg): Revert 1999-02-16 change. Revert
|
||||||
|
|
|
@ -75,6 +75,7 @@ extern void fixup_addr_diff_vecs PARAMS ((rtx));
|
||||||
extern int get_dest_uid PARAMS ((rtx, int));
|
extern int get_dest_uid PARAMS ((rtx, int));
|
||||||
extern void final_prescan_insn PARAMS ((rtx, rtx *, int));
|
extern void final_prescan_insn PARAMS ((rtx, rtx *, int));
|
||||||
extern int symbol_ref_operand PARAMS ((rtx, enum machine_mode));
|
extern int symbol_ref_operand PARAMS ((rtx, enum machine_mode));
|
||||||
|
extern int tls_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||||
extern int system_reg_operand PARAMS ((rtx, enum machine_mode));
|
extern int system_reg_operand PARAMS ((rtx, enum machine_mode));
|
||||||
extern int general_movsrc_operand PARAMS ((rtx, enum machine_mode));
|
extern int general_movsrc_operand PARAMS ((rtx, enum machine_mode));
|
||||||
extern int general_movdst_operand PARAMS ((rtx, enum machine_mode));
|
extern int general_movdst_operand PARAMS ((rtx, enum machine_mode));
|
||||||
|
|
|
@ -280,6 +280,11 @@ static int sh_address_cost PARAMS ((rtx));
|
||||||
#undef TARGET_ADDRESS_COST
|
#undef TARGET_ADDRESS_COST
|
||||||
#define TARGET_ADDRESS_COST sh_address_cost
|
#define TARGET_ADDRESS_COST sh_address_cost
|
||||||
|
|
||||||
|
#ifdef HAVE_AS_TLS
|
||||||
|
#undef TARGET_HAVE_TLS
|
||||||
|
#define TARGET_HAVE_TLS true
|
||||||
|
#endif
|
||||||
|
|
||||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||||
|
|
||||||
/* Print the operand address in x to the stream. */
|
/* Print the operand address in x to the stream. */
|
||||||
|
@ -708,7 +713,10 @@ prepare_move_operands (operands, mode)
|
||||||
rtx operands[];
|
rtx operands[];
|
||||||
enum machine_mode mode;
|
enum machine_mode mode;
|
||||||
{
|
{
|
||||||
if ((mode == SImode || mode == DImode) && flag_pic)
|
if ((mode == SImode || mode == DImode)
|
||||||
|
&& flag_pic
|
||||||
|
&& ! ((mode == Pmode || mode == ptr_mode)
|
||||||
|
&& tls_symbolic_operand (operands[1], Pmode) != 0))
|
||||||
{
|
{
|
||||||
rtx temp;
|
rtx temp;
|
||||||
if (SYMBOLIC_CONST_P (operands[1]))
|
if (SYMBOLIC_CONST_P (operands[1]))
|
||||||
|
@ -758,6 +766,73 @@ prepare_move_operands (operands, mode)
|
||||||
operands[1] = copy_to_mode_reg (mode, operands[1]);
|
operands[1] = copy_to_mode_reg (mode, operands[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode == Pmode || mode == ptr_mode)
|
||||||
|
{
|
||||||
|
rtx op0, op1;
|
||||||
|
enum tls_model tls_kind;
|
||||||
|
|
||||||
|
op0 = operands[0];
|
||||||
|
op1 = operands[1];
|
||||||
|
if ((tls_kind = tls_symbolic_operand (op1, Pmode)))
|
||||||
|
{
|
||||||
|
rtx tga_op1, tga_ret, tmp, tmp2;
|
||||||
|
|
||||||
|
|
||||||
|
switch (tls_kind)
|
||||||
|
{
|
||||||
|
case TLS_MODEL_GLOBAL_DYNAMIC:
|
||||||
|
tga_ret = gen_rtx_REG (Pmode, R0_REG);
|
||||||
|
emit_insn (gen_tls_global_dynamic (tga_ret, op1));
|
||||||
|
op1 = tga_ret;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TLS_MODEL_LOCAL_DYNAMIC:
|
||||||
|
tga_ret = gen_rtx_REG (Pmode, R0_REG);
|
||||||
|
emit_insn (gen_tls_local_dynamic (tga_ret, op1));
|
||||||
|
|
||||||
|
tmp = gen_reg_rtx (Pmode);
|
||||||
|
emit_move_insn (tmp, tga_ret);
|
||||||
|
|
||||||
|
if (register_operand (op0, Pmode))
|
||||||
|
tmp2 = op0;
|
||||||
|
else
|
||||||
|
tmp2 = gen_reg_rtx (Pmode);
|
||||||
|
|
||||||
|
emit_insn (gen_symDTPOFF2reg (tmp2, op1, tmp));
|
||||||
|
op1 = tmp2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TLS_MODEL_INITIAL_EXEC:
|
||||||
|
if (! flag_pic)
|
||||||
|
emit_insn (gen_GOTaddr2picreg ());
|
||||||
|
tga_op1 = gen_reg_rtx (Pmode);
|
||||||
|
tmp = gen_sym2GOTTPOFF (op1);
|
||||||
|
emit_insn (gen_tls_initial_exec (tga_op1, tmp));
|
||||||
|
op1 = tga_op1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TLS_MODEL_LOCAL_EXEC:
|
||||||
|
tmp2 = gen_reg_rtx (Pmode);
|
||||||
|
emit_insn (gen_load_gbr (tmp2));
|
||||||
|
tmp = gen_reg_rtx (Pmode);
|
||||||
|
emit_insn (gen_symTPOFF2reg (tmp, op1));
|
||||||
|
RTX_UNCHANGING_P (tmp) = 1;
|
||||||
|
|
||||||
|
if (register_operand (op0, Pmode))
|
||||||
|
op1 = op0;
|
||||||
|
else
|
||||||
|
op1 = gen_reg_rtx (Pmode);
|
||||||
|
|
||||||
|
emit_insn (gen_addsi3 (op1, tmp, tmp2));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
operands[1] = op1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6429,6 +6504,36 @@ symbol_ref_operand (op, mode)
|
||||||
return (GET_CODE (op) == SYMBOL_REF);
|
return (GET_CODE (op) == SYMBOL_REF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the TLS type for TLS symbols, 0 for otherwise. */
|
||||||
|
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);
|
||||||
|
STRIP_DATALABEL_ENCODING(str, str);
|
||||||
|
if (! TLS_SYMNAME_P (str))
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
commutative_float_operator (op, mode)
|
commutative_float_operator (op, mode)
|
||||||
rtx op;
|
rtx op;
|
||||||
|
@ -7174,6 +7279,8 @@ nonpic_symbol_mentioned_p (x)
|
||||||
|| XINT (x, 1) == UNSPEC_GOT
|
|| XINT (x, 1) == UNSPEC_GOT
|
||||||
|| XINT (x, 1) == UNSPEC_GOTOFF
|
|| XINT (x, 1) == UNSPEC_GOTOFF
|
||||||
|| XINT (x, 1) == UNSPEC_GOTPLT
|
|| XINT (x, 1) == UNSPEC_GOTPLT
|
||||||
|
|| XINT (x, 1) == UNSPEC_GOTTPOFF
|
||||||
|
|| XINT (x, 1) == UNSPEC_DTPOFF
|
||||||
|| XINT (x, 1) == UNSPEC_PLT))
|
|| XINT (x, 1) == UNSPEC_PLT))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -7203,6 +7310,9 @@ legitimize_pic_address (orig, mode, reg)
|
||||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||||
rtx reg;
|
rtx reg;
|
||||||
{
|
{
|
||||||
|
if (tls_symbolic_operand (orig, Pmode))
|
||||||
|
return orig;
|
||||||
|
|
||||||
if (GET_CODE (orig) == LABEL_REF
|
if (GET_CODE (orig) == LABEL_REF
|
||||||
|| (GET_CODE (orig) == SYMBOL_REF
|
|| (GET_CODE (orig) == SYMBOL_REF
|
||||||
&& (CONSTANT_POOL_ADDRESS_P (orig)
|
&& (CONSTANT_POOL_ADDRESS_P (orig)
|
||||||
|
@ -7555,6 +7665,60 @@ sh_encode_section_info (decl, first)
|
||||||
if (flag_pic)
|
if (flag_pic)
|
||||||
SYMBOL_REF_FLAG (symbol) = (*targetm.binds_local_p) (decl);
|
SYMBOL_REF_FLAG (symbol) = (*targetm.binds_local_p) (decl);
|
||||||
|
|
||||||
|
if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
|
||||||
|
{
|
||||||
|
const char *symbol_str, *orig_str;
|
||||||
|
bool is_local;
|
||||||
|
enum tls_model kind;
|
||||||
|
char encoding;
|
||||||
|
char *newstr;
|
||||||
|
size_t len, dlen;
|
||||||
|
|
||||||
|
orig_str = XSTR (symbol, 0);
|
||||||
|
is_local = (*targetm.binds_local_p) (decl);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
STRIP_DATALABEL_ENCODING (symbol_str, orig_str);
|
||||||
|
dlen = symbol_str - orig_str;
|
||||||
|
|
||||||
|
encoding = " GLil"[kind];
|
||||||
|
if (TLS_SYMNAME_P (symbol_str))
|
||||||
|
{
|
||||||
|
if (encoding == symbol_str[1])
|
||||||
|
return;
|
||||||
|
/* Handle the changes from initial-exec to local-exec and
|
||||||
|
from global-dynamic to local-dynamic. */
|
||||||
|
if ((encoding == 'l' && symbol_str[1] == 'i')
|
||||||
|
|| (encoding == 'L' && symbol_str[1] == 'G'))
|
||||||
|
symbol_str += 2;
|
||||||
|
else
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen (symbol_str);
|
||||||
|
newstr = alloca (dlen + len + 3);
|
||||||
|
if (dlen)
|
||||||
|
memcpy (newstr, orig_str, dlen);
|
||||||
|
newstr[dlen + 0] = SH_TLS_ENCODING[0];
|
||||||
|
newstr[dlen + 1] = encoding;
|
||||||
|
memcpy (newstr + dlen + 2, symbol_str, len + 1);
|
||||||
|
|
||||||
|
XSTR (symbol, 0) = ggc_alloc_string (newstr, dlen + len + 2);
|
||||||
|
}
|
||||||
|
|
||||||
if (TARGET_SH5 && first && TREE_CODE (decl) != FUNCTION_DECL)
|
if (TARGET_SH5 && first && TREE_CODE (decl) != FUNCTION_DECL)
|
||||||
XEXP (rtl, 0) = gen_datalabel_ref (symbol);
|
XEXP (rtl, 0) = gen_datalabel_ref (symbol);
|
||||||
}
|
}
|
||||||
|
@ -7566,6 +7730,7 @@ sh_strip_name_encoding (str)
|
||||||
const char *str;
|
const char *str;
|
||||||
{
|
{
|
||||||
STRIP_DATALABEL_ENCODING (str, str);
|
STRIP_DATALABEL_ENCODING (str, str);
|
||||||
|
STRIP_TLS_ENCODING (str, str);
|
||||||
str += *str == '*';
|
str += *str == '*';
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2752,6 +2752,20 @@ while (0)
|
||||||
((GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == LABEL_REF) \
|
((GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == LABEL_REF) \
|
||||||
&& nonpic_symbol_mentioned_p (X))
|
&& nonpic_symbol_mentioned_p (X))
|
||||||
|
|
||||||
|
/* TLS. */
|
||||||
|
|
||||||
|
/* The prefix used to mark SYMBOL_REFs that refer to TLS symbols. */
|
||||||
|
#define SH_TLS_ENCODING "@"
|
||||||
|
|
||||||
|
/* Return true if SYM_NAME starts with SH_TLS_ENCODING. */
|
||||||
|
#define TLS_SYMNAME_P(SYM_NAME) \
|
||||||
|
((SYM_NAME)[0] == SH_TLS_ENCODING[0])
|
||||||
|
|
||||||
|
/* Skip an optional SH_TLS_ENCODING in the beginning of SYM_NAME. */
|
||||||
|
#define STRIP_TLS_ENCODING(VAR, SYM_NAME) \
|
||||||
|
(VAR) = (SYM_NAME) + (TLS_SYMNAME_P (SYM_NAME) \
|
||||||
|
? strlen (SH_TLS_ENCODING) + 1 : 0)
|
||||||
|
|
||||||
/* Compute extra cost of moving data between one register class
|
/* Compute extra cost of moving data between one register class
|
||||||
and another. */
|
and another. */
|
||||||
|
|
||||||
|
@ -2915,6 +2929,7 @@ while (0)
|
||||||
const char * lname; \
|
const char * lname; \
|
||||||
\
|
\
|
||||||
STRIP_DATALABEL_ENCODING (lname, (NAME)); \
|
STRIP_DATALABEL_ENCODING (lname, (NAME)); \
|
||||||
|
STRIP_TLS_ENCODING (lname, lname); \
|
||||||
if (lname[0] == '*') \
|
if (lname[0] == '*') \
|
||||||
fputs (lname + 1, (FILE)); \
|
fputs (lname + 1, (FILE)); \
|
||||||
else \
|
else \
|
||||||
|
@ -3053,6 +3068,18 @@ while (0)
|
||||||
output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \
|
output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \
|
||||||
fputs ("@GOTPLT", (STREAM)); \
|
fputs ("@GOTPLT", (STREAM)); \
|
||||||
break; \
|
break; \
|
||||||
|
case UNSPEC_DTPOFF: \
|
||||||
|
output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \
|
||||||
|
fputs ("@DTPOFF", (STREAM)); \
|
||||||
|
break; \
|
||||||
|
case UNSPEC_GOTTPOFF: \
|
||||||
|
output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \
|
||||||
|
fputs ("@GOTTPOFF", (STREAM)); \
|
||||||
|
break; \
|
||||||
|
case UNSPEC_TPOFF: \
|
||||||
|
output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \
|
||||||
|
fputs ("@TPOFF", (STREAM)); \
|
||||||
|
break; \
|
||||||
case UNSPEC_CALLER: \
|
case UNSPEC_CALLER: \
|
||||||
{ \
|
{ \
|
||||||
char name[32]; \
|
char name[32]; \
|
||||||
|
|
|
@ -136,6 +136,12 @@
|
||||||
(UNSPEC_NSB 17)
|
(UNSPEC_NSB 17)
|
||||||
(UNSPEC_ALLOCO 18)
|
(UNSPEC_ALLOCO 18)
|
||||||
(UNSPEC_EH_RETURN 19)
|
(UNSPEC_EH_RETURN 19)
|
||||||
|
(UNSPEC_TLSGD 20)
|
||||||
|
(UNSPEC_TLSLDM 21)
|
||||||
|
(UNSPEC_TLSIE 22)
|
||||||
|
(UNSPEC_DTPOFF 23)
|
||||||
|
(UNSPEC_GOTTPOFF 24)
|
||||||
|
(UNSPEC_TPOFF 25)
|
||||||
|
|
||||||
;; These are used with unspec_volatile.
|
;; These are used with unspec_volatile.
|
||||||
(UNSPECV_BLOCKAGE 0)
|
(UNSPECV_BLOCKAGE 0)
|
||||||
|
@ -211,6 +217,7 @@
|
||||||
;; ftrc_s fix_truncsfsi2_i4
|
;; ftrc_s fix_truncsfsi2_i4
|
||||||
;; dfdiv double precision floating point divide (or square root)
|
;; dfdiv double precision floating point divide (or square root)
|
||||||
;; cwb ic_invalidate_line_i
|
;; cwb ic_invalidate_line_i
|
||||||
|
;; tls_load load TLS related address
|
||||||
;; arith_media SHmedia arithmetic, logical, and shift instructions
|
;; arith_media SHmedia arithmetic, logical, and shift instructions
|
||||||
;; cbranch_media SHmedia conditional branch instructions
|
;; cbranch_media SHmedia conditional branch instructions
|
||||||
;; cmp_media SHmedia compare instructions
|
;; cmp_media SHmedia compare instructions
|
||||||
|
@ -241,7 +248,7 @@
|
||||||
;; nil no-op move, will be deleted.
|
;; nil no-op move, will be deleted.
|
||||||
|
|
||||||
(define_attr "type"
|
(define_attr "type"
|
||||||
"mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
|
"mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
|
||||||
(const_string "other"))
|
(const_string "other"))
|
||||||
|
|
||||||
;; We define a new attribute namely "insn_class".We use
|
;; We define a new attribute namely "insn_class".We use
|
||||||
|
@ -6801,6 +6808,142 @@
|
||||||
""
|
""
|
||||||
"")
|
"")
|
||||||
|
|
||||||
|
;; TLS code generation.
|
||||||
|
;; ??? this should be a define_insn_and_split
|
||||||
|
;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
|
||||||
|
;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
|
||||||
|
;; for details.
|
||||||
|
|
||||||
|
(define_insn "tls_global_dynamic"
|
||||||
|
[(set (match_operand:SI 0 "register_operand" "=&z")
|
||||||
|
(unspec:SI [(match_operand:SI 1 "" "")]
|
||||||
|
UNSPEC_TLSGD))
|
||||||
|
(use (reg:PSI FPSCR_REG))
|
||||||
|
(use (reg:SI PIC_REG))
|
||||||
|
(clobber (reg:SI PR_REG))
|
||||||
|
(clobber (scratch:SI))]
|
||||||
|
"TARGET_SH1"
|
||||||
|
"*
|
||||||
|
{
|
||||||
|
return \"\\
|
||||||
|
mov.l\\t1f,r4\\n\\
|
||||||
|
\\tmova\\t2f,r0\\n\\
|
||||||
|
\\tmov.l\\t2f,r1\\n\\
|
||||||
|
\\tadd\\tr0,r1\\n\\
|
||||||
|
\\tjsr\\t@r1\\n\\
|
||||||
|
\\tadd\\tr12,r4\\n\\
|
||||||
|
\\tbra\\t3f\\n\\
|
||||||
|
\\tnop\\n\\
|
||||||
|
\\t.align\\t2\\n\\
|
||||||
|
1:\\t.long\\t%a1@TLSGD\\n\\
|
||||||
|
2:\\t.long\\t__tls_get_addr@PLT\\n\\
|
||||||
|
3:\";
|
||||||
|
}"
|
||||||
|
[(set_attr "type" "tls_load")
|
||||||
|
(set_attr "length" "26")])
|
||||||
|
|
||||||
|
(define_insn "tls_local_dynamic"
|
||||||
|
[(set (match_operand:SI 0 "register_operand" "=&z")
|
||||||
|
(unspec:SI [(match_operand:SI 1 "" "")]
|
||||||
|
UNSPEC_TLSLDM))
|
||||||
|
(use (reg:PSI FPSCR_REG))
|
||||||
|
(use (reg:SI PIC_REG))
|
||||||
|
(clobber (reg:SI PR_REG))
|
||||||
|
(clobber (scratch:SI))]
|
||||||
|
"TARGET_SH1"
|
||||||
|
"*
|
||||||
|
{
|
||||||
|
return \"\\
|
||||||
|
mov.l\\t1f,r4\\n\\
|
||||||
|
\\tmova\\t2f,r0\\n\\
|
||||||
|
\\tmov.l\\t2f,r1\\n\\
|
||||||
|
\\tadd\\tr0,r1\\n\\
|
||||||
|
\\tjsr\\t@r1\\n\\
|
||||||
|
\\tadd\\tr12,r4\\n\\
|
||||||
|
\\tbra\\t3f\\n\\
|
||||||
|
\\tnop\\n\\
|
||||||
|
\\t.align\\t2\\n\\
|
||||||
|
1:\\t.long\\t%a1@TLSLDM\\n\\
|
||||||
|
2:\\t.long\\t__tls_get_addr@PLT\\n\\
|
||||||
|
3:\";
|
||||||
|
}"
|
||||||
|
[(set_attr "type" "tls_load")
|
||||||
|
(set_attr "length" "26")])
|
||||||
|
|
||||||
|
(define_expand "sym2DTPOFF"
|
||||||
|
[(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
|
||||||
|
""
|
||||||
|
"")
|
||||||
|
|
||||||
|
(define_expand "symDTPOFF2reg"
|
||||||
|
[(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
|
||||||
|
""
|
||||||
|
"
|
||||||
|
{
|
||||||
|
rtx dtpoffsym, insn;
|
||||||
|
rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
|
||||||
|
|
||||||
|
dtpoffsym = gen_sym2DTPOFF (operands[1]);
|
||||||
|
PUT_MODE (dtpoffsym, Pmode);
|
||||||
|
emit_move_insn (t, dtpoffsym);
|
||||||
|
insn = emit_move_insn (operands[0],
|
||||||
|
gen_rtx_PLUS (Pmode, t, operands[2]));
|
||||||
|
DONE;
|
||||||
|
}")
|
||||||
|
|
||||||
|
(define_expand "sym2GOTTPOFF"
|
||||||
|
[(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
|
||||||
|
""
|
||||||
|
"")
|
||||||
|
|
||||||
|
(define_insn "tls_initial_exec"
|
||||||
|
[(set (match_operand:SI 0 "register_operand" "=&r")
|
||||||
|
(unspec:SI [(match_operand:SI 1 "" "")]
|
||||||
|
UNSPEC_TLSIE))
|
||||||
|
(use (reg:SI GBR_REG))
|
||||||
|
(use (reg:SI PIC_REG))
|
||||||
|
(clobber (reg:SI R0_REG))]
|
||||||
|
""
|
||||||
|
"*
|
||||||
|
{
|
||||||
|
return \"\\
|
||||||
|
mov.l\\t1f,r0\\n\\
|
||||||
|
\\tstc\\tgbr,%0\\n\\
|
||||||
|
\\tmov.l\\t@(r0,r12),r0\\n\\
|
||||||
|
\\tbra\\t2f\\n\\
|
||||||
|
\\tadd\\tr0,%0\\n\\
|
||||||
|
\\t.align\\t2\\n\\
|
||||||
|
1:\\t.long\\t%a1\\n\\
|
||||||
|
2:\";
|
||||||
|
}"
|
||||||
|
[(set_attr "type" "tls_load")
|
||||||
|
(set_attr "length" "16")])
|
||||||
|
|
||||||
|
(define_expand "sym2TPOFF"
|
||||||
|
[(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
|
||||||
|
""
|
||||||
|
"")
|
||||||
|
|
||||||
|
(define_expand "symTPOFF2reg"
|
||||||
|
[(match_operand 0 "" "") (match_operand 1 "" "")]
|
||||||
|
""
|
||||||
|
"
|
||||||
|
{
|
||||||
|
rtx tpoffsym, insn;
|
||||||
|
|
||||||
|
tpoffsym = gen_sym2TPOFF (operands[1]);
|
||||||
|
PUT_MODE (tpoffsym, Pmode);
|
||||||
|
insn = emit_move_insn (operands[0], tpoffsym);
|
||||||
|
DONE;
|
||||||
|
}")
|
||||||
|
|
||||||
|
(define_insn "load_gbr"
|
||||||
|
[(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
|
||||||
|
(use (reg:SI GBR_REG))]
|
||||||
|
""
|
||||||
|
"stc gbr,%0"
|
||||||
|
[(set_attr "type" "tls_load")])
|
||||||
|
|
||||||
;; case instruction for switch statements.
|
;; case instruction for switch statements.
|
||||||
|
|
||||||
;; Operand 0 is index
|
;; Operand 0 is index
|
||||||
|
|
Loading…
Reference in New Issue