mips.c (mips_need_mips16_rdhwr_p): New variable.

gcc/
	* config/mips/mips.c (mips_need_mips16_rdhwr_p): New variable.
	(mips_get_tp): Set it.  Record that __mips16_rdhwr binds locally.
	(mips_start_unique_function, mips_output_mips16_rdhwr)
	(mips_code_end): New functions.
	(TARGET_ASM_CODE_END): Define.

libgcc/
	* config.host (mips64*-*-linux*, mipsisa64*-*-linux*)
	(mips*-*-linux*): Remove t-slibgcc-libgcc.
	* config/mips/t-mips16 (LIB1ASMFUNCS): Remove __mips16_rdhwr.
	* config/mips/mips16.S (__mips16_rdhwr): Delete.

From-SVN: r184380
This commit is contained in:
Richard Sandiford 2012-02-19 16:47:19 +00:00 committed by Richard Sandiford
parent 5adeb24686
commit 78c2726669
6 changed files with 81 additions and 17 deletions

View File

@ -1,3 +1,11 @@
2012-02-19 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips.c (mips_need_mips16_rdhwr_p): New variable.
(mips_get_tp): Set it. Record that __mips16_rdhwr binds locally.
(mips_start_unique_function, mips_output_mips16_rdhwr)
(mips_code_end): New functions.
(TARGET_ASM_CODE_END): Define.
2012-02-19 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips.c (mips16_build_call_stub): Add CFI information

View File

@ -592,6 +592,9 @@ struct target_globals *mips16_globals;
and returned from mips_sched_reorder2. */
static int cached_can_issue_more;
/* True if the output uses __mips16_rdhwr. */
static bool mips_need_mips16_rdhwr_p;
/* Index R is the smallest register class that contains register R. */
const enum reg_class mips_regno_to_class[FIRST_PSEUDO_REGISTER] = {
LEA_REGS, LEA_REGS, M16_REGS, V1_REG,
@ -2842,7 +2845,9 @@ mips_get_tp (void)
tp = gen_reg_rtx (Pmode);
if (TARGET_MIPS16)
{
mips_need_mips16_rdhwr_p = true;
fn = mips16_stub_function ("__mips16_rdhwr");
SYMBOL_REF_FLAGS (fn) |= SYMBOL_FLAG_LOCAL;
if (!call_insn_operand (fn, VOIDmode))
fn = force_reg (Pmode, fn);
emit_insn (PMODE_INSN (gen_tls_get_tp_mips16, (tp, fn)));
@ -5827,6 +5832,33 @@ mips_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
return addr;
}
/* Declare a unique, locally-binding function called NAME, then start
its definition. */
static void
mips_start_unique_function (const char *name)
{
tree decl;
decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
get_identifier (name),
build_function_type_list (void_type_node, NULL_TREE));
DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
NULL_TREE, void_type_node);
TREE_PUBLIC (decl) = 1;
TREE_STATIC (decl) = 1;
DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
targetm.asm_out.unique_section (decl, 0);
switch_to_section (get_named_section (decl, NULL, 0));
targetm.asm_out.globalize_label (asm_out_file, name);
fputs ("\t.hidden\t", asm_out_file);
assemble_name (asm_out_file, name);
putc ('\n', asm_out_file);
}
/* Start a definition of function NAME. MIPS16_P indicates whether the
function contains MIPS16 code. */
@ -5865,6 +5897,26 @@ mips_end_function_definition (const char *name)
}
}
/* Output a definition of the __mips16_rdhwr function. */
static void
mips_output_mips16_rdhwr (void)
{
const char *name;
name = "__mips16_rdhwr";
mips_start_unique_function (name);
mips_start_function_definition (name, false);
fprintf (asm_out_file,
"\t.set\tpush\n"
"\t.set\tmips32r2\n"
"\t.set\tnoreorder\n"
"\trdhwr\t$3,$29\n"
"\t.set\tpop\n"
"\tj\t$31\n");
mips_end_function_definition (name);
}
/* Return true if calls to X can use R_MIPS_CALL* relocations. */
static bool
@ -8467,6 +8519,15 @@ mips_file_start (void)
ASM_COMMENT_START,
mips_small_data_threshold, mips_arch_info->name, mips_isa);
}
/* Implement TARGET_ASM_CODE_END. */
static void
mips_code_end (void)
{
if (mips_need_mips16_rdhwr_p)
mips_output_mips16_rdhwr ();
}
/* Make the last instruction frame-related and note that it performs
the operation described by FRAME_PATTERN. */
@ -17357,6 +17418,8 @@ mips_expand_vec_minmax (rtx target, rtx op0, rtx op1,
#define TARGET_ASM_FILE_START mips_file_start
#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
#undef TARGET_ASM_CODE_END
#define TARGET_ASM_CODE_END mips_code_end
#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS mips_init_libfuncs

View File

@ -1,3 +1,10 @@
2012-02-19 Richard Sandiford <rdsandiford@googlemail.com>
* config.host (mips64*-*-linux*, mipsisa64*-*-linux*)
(mips*-*-linux*): Remove t-slibgcc-libgcc.
* config/mips/t-mips16 (LIB1ASMFUNCS): Remove __mips16_rdhwr.
* config/mips/mips16.S (__mips16_rdhwr): Delete.
2012-02-19 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips16.S (CALL_STUB_RET): Add CFI information.

View File

@ -746,12 +746,12 @@ mips*-*-netbsd*) # NetBSD/mips, either endian.
;;
mips64*-*-linux* | mipsisa64*-*-linux*)
extra_parts="$extra_parts crtfastmath.o"
tmake_file="${tmake_file} t-crtfm mips/t-mips16 mips/t-tpbit t-slibgcc-libgcc"
tmake_file="${tmake_file} t-crtfm mips/t-mips16 mips/t-tpbit"
md_unwind_header=mips/linux-unwind.h
;;
mips*-*-linux*) # Linux MIPS, either endian.
extra_parts="$extra_parts crtfastmath.o"
tmake_file="${tmake_file} t-crtfm mips/t-mips16 t-slibgcc-libgcc"
tmake_file="${tmake_file} t-crtfm mips/t-mips16"
md_unwind_header=mips/linux-unwind.h
;;
mips*-*-openbsd*)

View File

@ -718,17 +718,4 @@ CALL_STUB_RET (__mips16_call_stub_dc_10, 10, DC)
#endif
#endif /* !__mips_single_float */
#ifdef L_m16rdhwr
STARTFN (__mips16_rdhwr)
/* Forced always hidden, because the PLT resolver function would
not preserve all necessary registers. */
.hidden __mips16_rdhwr
.set push
.set mips32r2
.set noreorder
rdhwr $3,$29
.set pop
j $31
ENDFN (__mips16_rdhwr)
#endif
#endif

View File

@ -36,8 +36,7 @@ LIB1ASMFUNCS = _m16addsf3 _m16subsf3 _m16mulsf3 _m16divsf3 \
_m16stubsc0 _m16stubsc1 _m16stubsc2 _m16stubsc5 _m16stubsc6 \
_m16stubsc9 _m16stubsc10 \
_m16stubdc0 _m16stubdc1 _m16stubdc2 _m16stubdc5 _m16stubdc6 \
_m16stubdc9 _m16stubdc10 \
_m16rdhwr
_m16stubdc9 _m16stubdc10
SYNC = yes
SYNC_CFLAGS = -mno-mips16