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,
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)));
return addr;
}
\f
+/* 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. */
}
}
\f
+/* 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);
+}
+\f
/* Return true if calls to X can use R_MIPS_CALL* relocations. */
static bool
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 ();
+}
\f
/* Make the last instruction frame-related and note that it performs
the operation described by FRAME_PATTERN. */
#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