"or %o7,%g0,X; call Y; or X,%g0,%o7" always, so that it can be optimized.
With sethi/jmp, neither 'as' nor 'ld' has an easy way how to find out if
somebody does not branch between the sethi and jmp. */
-#define SIBCALL_SLOT_EMPTY_P 0
+#define LEAF_SIBCALL_SLOT_RESERVED_P 1
#else
-#define SIBCALL_SLOT_EMPTY_P \
- ((TARGET_ARCH32 || TARGET_CM_MEDLOW) && ! flag_pic)
+#define LEAF_SIBCALL_SLOT_RESERVED_P \
+ ((TARGET_ARCH64 && !TARGET_CM_MEDLOW) || flag_pic)
#endif
/* Global variables for machine-dependent things. */
static int sparc_adjust_cost (rtx, rtx, rtx, int);
static int sparc_issue_rate (void);
static void sparc_sched_init (FILE *, int, int);
-static int sparc_use_dfa_pipeline_interface (void);
static int sparc_use_sched_lookahead (void);
static void emit_soft_tfmode_libcall (const char *, int, rtx *);
#undef TARGET_SCHED_INIT
#define TARGET_SCHED_INIT sparc_sched_init
#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
-#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE sparc_use_dfa_pipeline_interface
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE hook_int_void_1
#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD sparc_use_sched_lookahead
{
/* If the tail call is done using the call instruction,
we have to restore %o7 in the delay slot. */
- if (! SIBCALL_SLOT_EMPTY_P)
+ if (LEAF_SIBCALL_SLOT_RESERVED_P)
return 0;
/* %g1 is used to build the function address */
static GTY(()) rtx global_offset_table;
/* The function we use to get at it. */
-static GTY(()) rtx get_pc_symbol;
-static GTY(()) char get_pc_symbol_name[256];
+static GTY(()) rtx add_pc_to_pic_symbol;
+static GTY(()) char add_pc_to_pic_symbol_name[256];
/* Ensure that we are not using patterns that are not OK with PIC. */
static void
load_pic_register (void)
{
- /* Labels to get the PC in the prologue of this function. */
int orig_flag_pic = flag_pic;
- /* If we haven't emitted the special get_pc helper function, do so now. */
- if (get_pc_symbol_name[0] == 0)
+ /* If we haven't emitted the special helper function, do so now. */
+ if (add_pc_to_pic_symbol_name[0] == 0)
{
+ const char *pic_name = reg_names[REGNO (pic_offset_table_rtx)];
int align;
- ASM_GENERATE_INTERNAL_LABEL (get_pc_symbol_name, "LGETPC", 0);
+ ASM_GENERATE_INTERNAL_LABEL (add_pc_to_pic_symbol_name, "LADDPC", 0);
text_section ();
align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
if (align > 0)
ASM_OUTPUT_ALIGN (asm_out_file, align);
- (*targetm.asm_out.internal_label) (asm_out_file, "LGETPC", 0);
- fputs ("\tretl\n\tadd\t%o7, %l7, %l7\n", asm_out_file);
+ ASM_OUTPUT_LABEL (asm_out_file, add_pc_to_pic_symbol_name);
+ fprintf (asm_out_file, "\tjmp %%o7+8\n\t add\t%%o7, %s, %s\n",
+ pic_name, pic_name);
}
/* Initialize every time through, since we can't easily
know this to be permanent. */
global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
- get_pc_symbol = gen_rtx_SYMBOL_REF (Pmode, get_pc_symbol_name);
- flag_pic = 0;
-
- emit_insn (gen_get_pc (pic_offset_table_rtx, global_offset_table,
- get_pc_symbol));
+ add_pc_to_pic_symbol = gen_rtx_SYMBOL_REF (Pmode, add_pc_to_pic_symbol_name);
+ flag_pic = 0;
+ emit_insn (gen_load_pcrel_sym (pic_offset_table_rtx, global_offset_table,
+ add_pc_to_pic_symbol));
flag_pic = orig_flag_pic;
/* Need to emit this whether or not we obey regdecls,
/* Output a 'restore' instruction. */
static void
-output_restore (rtx insn)
+output_restore (rtx pat)
{
- rtx operands[3], pat;
+ rtx operands[3];
- if (! insn)
+ if (! pat)
{
fputs ("\t restore\n", asm_out_file);
return;
}
- pat = PATTERN (insn);
if (GET_CODE (pat) != SET)
abort ();
{
fprintf (asm_out_file, "\tjmp\t%%i7+%d\n",
sparc_skip_caller_unimp ? 12 : 8);
- output_restore (delay);
+ output_restore (pat);
}
PATTERN (delay) = gen_blockage ();
register window. We simply output the jump to the function and
the insn in the delay slot (if any). */
- if (! SIBCALL_SLOT_EMPTY_P && delay_slot_filled_p)
+ if (LEAF_SIBCALL_SLOT_RESERVED_P && delay_slot_filled_p)
abort();
if (delay_slot_filled_p)
if (! delay)
abort ();
- output_restore (delay);
+ output_restore (PATTERN (delay));
PATTERN (delay) = gen_blockage ();
INSN_CODE (delay) = -1;
}
else
- output_restore (0);
+ output_restore (NULL_RTX);
}
return "";
INSN, if set, is the insn. */
-char *
+const char *
output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
int noop, rtx insn)
{
- static char string[50];
+ static char string[64];
enum rtx_code code = GET_CODE (op);
rtx cc_reg = XEXP (op, 0);
enum machine_mode mode = GET_MODE (cc_reg);
to
be,pn %xcc, .+12
- nop
+ nop
ba .LC30
and
to
fbe,pt %fcc2, .+16
- nop
+ nop
ba .LC29 */
far = get_attr_length (insn) >= 3;
p = strchr (p, '\0');
if (far)
{
- strcpy (p, ".+12\n\tnop\n\tb\t");
+ strcpy (p, ".+12\n\t nop\n\tb\t");
if (annul || noop)
p[3] = '6';
- p += 13;
+ p += 14;
}
*p++ = '%';
*p++ = 'l';
*p++ = label + '0';
*p = '\0';
if (noop)
- strcpy (p, "\n\tnop");
+ strcpy (p, "\n\t nop");
return string;
}
NOOP is nonzero if we have to follow this branch by a noop. */
-char *
+const char *
output_v9branch (rtx op, rtx dest, int reg, int label, int reversed,
int annul, int noop, rtx insn)
{
- static char string[50];
+ static char string[64];
enum rtx_code code = GET_CODE (op);
enum machine_mode mode = GET_MODE (XEXP (op, 0));
rtx note;
to
brz,pn %g1, .+12
- nop
+ nop
ba,pt %xcc, .LC30
and
to
brlz,pt %o1, .+16
- nop
+ nop
ba,pt %xcc, .LC29 */
far = get_attr_length (insn) >= 3;
veryfar = 0;
}
- strcpy (p, ".+12\n\tnop\n\t");
+ strcpy (p, ".+12\n\t nop\n\t");
if (annul || noop)
p[3] = '6';
- p += 11;
+ p += 12;
if (veryfar)
{
strcpy (p, "b\t");
*p = '\0';
if (noop)
- strcpy (p, "\n\tnop");
+ strcpy (p, "\n\t nop");
return string;
}
}
static int
-sparc_use_dfa_pipeline_interface (void)
-{
- if ((1 << sparc_cpu) &
- ((1 << PROCESSOR_ULTRASPARC) | (1 << PROCESSOR_CYPRESS) |
- (1 << PROCESSOR_SUPERSPARC) | (1 << PROCESSOR_HYPERSPARC) |
- (1 << PROCESSOR_SPARCLITE86X) | (1 << PROCESSOR_TSC701) |
- (1 << PROCESSOR_ULTRASPARC3)))
- return 1;
- return 0;
-}
-
-static int
sparc_use_sched_lookahead (void)
{
if (sparc_cpu == PROCESSOR_ULTRASPARC
/* Returns assembly code to perform a DImode shift using
a 64-bit global or out register on SPARC-V8+. */
-char *
-sparc_v8plus_shift (rtx *operands, rtx insn, const char *opcode)
+const char *
+output_v8plus_shift (rtx *operands, rtx insn, const char *opcode)
{
static char asm_code[60];
epilogue_completed = 1;
no_new_pseudos = 1;
current_function_uses_only_leaf_regs = 1;
+ reset_block_changes ();
emit_note (NOTE_INSN_PROLOGUE_END);