Commit 5b71a4e7 by David Edelsohn Committed by David Edelsohn

rs6000.h (FUNCTION_MODE): Always use SImode.

        * config/rs6000/rs6000.h (FUNCTION_MODE): Always use SImode.
        * config/rs6000/rs6000.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): Redefine
        as hook_bool_tree_hwi_hwi_tree_true.
        (rs6000_emit_allocate_stack): Use TARGET_32BIT.
        (rs6000_emit_epilogue): Same.
        (rs6000_output_mi_thunk): Re-implement as RTL.
        * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Call
        xcoffout_declare_function if any debugging enabled.

From-SVN: r61058
parent 66e2aa7d
2003-01-08 David Edelsohn <edelsohn@gnu.org>
* config/rs6000/rs6000.h (FUNCTION_MODE): Always use SImode.
* config/rs6000/rs6000.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): Redefine
as hook_bool_tree_hwi_hwi_tree_true.
(rs6000_emit_allocate_stack): Use TARGET_32BIT.
(rs6000_emit_epilogue): Same.
(rs6000_output_mi_thunk): Re-implement as RTL.
* config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Call
xcoffout_declare_function if any debugging enabled.
2003-01-08 Chris Demetriou <cgd@broadcom.com>
* config.gcc (mipsisa32r2-*-elf*, mipsisa32r2el-*-elf*): New
......
......@@ -207,7 +207,7 @@ static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
static void rs6000_elf_select_section PARAMS ((tree, int,
unsigned HOST_WIDE_INT));
unsigned HOST_WIDE_INT));
static void rs6000_elf_unique_section PARAMS ((tree, int));
static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
......@@ -388,12 +388,8 @@ static const char alt_reg_names[][8] =
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
/* ??? Should work everywhere, but ask dje@watson.ibm.com before
enabling for AIX. */
#if TARGET_OBJECT_FORMAT != OBJECT_XCOFF
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
#endif
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
......@@ -9916,14 +9912,14 @@ rs6000_emit_allocate_stack (size, copy_r12)
&& REGNO (stack_limit_rtx) > 1
&& REGNO (stack_limit_rtx) <= 31)
{
emit_insn (Pmode == SImode
emit_insn (TARGET_32BIT
? gen_addsi3 (tmp_reg,
stack_limit_rtx,
GEN_INT (size))
: gen_adddi3 (tmp_reg,
stack_limit_rtx,
GEN_INT (size)));
emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
const0_rtx));
}
......@@ -9935,7 +9931,7 @@ rs6000_emit_allocate_stack (size, copy_r12)
gen_rtx_PLUS (Pmode,
stack_limit_rtx,
GEN_INT (size)));
emit_insn (gen_elf_high (tmp_reg, toload));
emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
......@@ -9959,24 +9955,22 @@ rs6000_emit_allocate_stack (size, copy_r12)
try_split (PATTERN (insn), insn, 0);
todec = tmp_reg;
}
if (Pmode == SImode)
insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
todec, stack_reg));
else
insn = emit_insn (gen_movdi_update (stack_reg, stack_reg,
insn = emit_insn (TARGET_32BIT
? gen_movsi_update (stack_reg, stack_reg,
todec, stack_reg)
: gen_movdi_update (stack_reg, stack_reg,
todec, stack_reg));
}
else
{
if (Pmode == SImode)
insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
else
insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
insn = emit_insn (TARGET_32BIT
? gen_addsi3 (stack_reg, stack_reg, todec)
: gen_adddi3 (stack_reg, stack_reg, todec));
emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
gen_rtx_REG (Pmode, 12));
}
RTX_FRAME_RELATED_P (insn) = 1;
REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
......@@ -10970,7 +10964,7 @@ rs6000_emit_epilogue (sibcall)
}
else if (sp_offset != 0)
{
emit_insn (Pmode == SImode
emit_insn (TARGET_32BIT
? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
GEN_INT (sp_offset))
: gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
......@@ -10981,7 +10975,7 @@ rs6000_emit_epilogue (sibcall)
if (current_function_calls_eh_return)
{
rtx sa = EH_RETURN_STACKADJ_RTX;
emit_insn (Pmode == SImode
emit_insn (TARGET_32BIT
? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
: gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
}
......@@ -11344,159 +11338,99 @@ rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
FILE *file;
tree thunk_fndecl ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
HOST_WIDE_INT vcall_offset;
tree function;
{
const char *this_reg =
reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
const char *prefix;
const char *fname;
const char *r0 = reg_names[0];
const char *toc = reg_names[2];
const char *schain = reg_names[11];
const char *r12 = reg_names[12];
char buf[512];
static int labelno = 0;
/* Small constants that can be done by one add instruction. */
if (delta >= -32768 && delta <= 32767)
{
if (! TARGET_NEW_MNEMONICS)
fprintf (file, "\tcal %s,%d(%s)\n", this_reg, (int) delta, this_reg);
else
fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, (int) delta);
}
rtx this, insn, funexp;
/* 64-bit constants. If "int" is 32 bits, we'll never hit this abort. */
else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
abort ();
reload_completed = 1;
no_new_pseudos = 1;
/* Large constants that can be done by one addis instruction. */
else if ((delta & 0xffff) == 0)
asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
(int) (delta >> 16));
/* Mark the end of the (empty) prologue. */
emit_note (NULL, NOTE_INSN_PROLOGUE_END);
/* 32-bit constants that can be done by an add and addis instruction. */
/* Find the "this" pointer. If the function returns a structure,
the structure return pointer is in r3. */
if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
this = gen_rtx_REG (Pmode, 4);
else
{
/* Break into two pieces, propagating the sign bit from the low
word to the upper word. */
int delta_low = ((delta & 0xffff) ^ 0x8000) - 0x8000;
int delta_high = (delta - delta_low) >> 16;
this = gen_rtx_REG (Pmode, 3);
asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
delta_high);
if (! TARGET_NEW_MNEMONICS)
fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
else
fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
/* Apply the constant offset, if required. */
if (delta)
{
rtx delta_rtx = GEN_INT (delta);
emit_insn (TARGET_32BIT
? gen_addsi3 (this, this, delta_rtx)
: gen_adddi3 (this, this, delta_rtx));
}
/* Get the prefix in front of the names. */
switch (DEFAULT_ABI)
/* Apply the offset from the vtable, if required. */
if (vcall_offset)
{
default:
abort ();
rtx vcall_offset_rtx = GEN_INT (vcall_offset);
rtx tmp = gen_rtx_REG (Pmode, 12);
case ABI_AIX:
prefix = ".";
break;
case ABI_V4:
case ABI_AIX_NODESC:
case ABI_DARWIN:
prefix = "";
break;
emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
emit_insn (TARGET_32BIT
? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
: gen_adddi3 (tmp, tmp, vcall_offset_rtx));
emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
emit_insn (TARGET_32BIT
? gen_addsi3 (this, this, tmp)
: gen_adddi3 (this, this, tmp));
}
/* If the function is compiled in this module, jump to it directly.
Otherwise, load up its address and jump to it. */
fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
/* Generate a tail call to the target function. */
if (!TREE_USED (function))
{
assemble_external (function);
TREE_USED (function) = 1;
}
funexp = XEXP (DECL_RTL (function), 0);
if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
SYMBOL_REF_FLAG (funexp) = 0;
if (current_file_function_operand (funexp, VOIDmode)
&& (! lookup_attribute ("longcall",
TYPE_ATTRIBUTES (TREE_TYPE (function)))
|| lookup_attribute ("shortcall",
TYPE_ATTRIBUTES (TREE_TYPE (function)))))
{
fprintf (file, "\tb %s", prefix);
assemble_name (file, fname);
if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
putc ('\n', file);
}
else
{
switch (DEFAULT_ABI)
{
default:
abort ();
case ABI_AIX:
/* Set up a TOC entry for the function. */
ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
toc_section ();
(*targetm.asm_out.internal_label) (file, "Lthunk", labelno);
labelno++;
SYMBOL_REF_FLAG (funexp) = 1;
if (TARGET_MINIMAL_TOC)
fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
else
{
fputs ("\t.tc ", file);
assemble_name (file, fname);
fputs ("[TC],", file);
}
assemble_name (file, fname);
putc ('\n', file);
function_section (current_function_decl);
if (TARGET_MINIMAL_TOC)
asm_fprintf (file, (TARGET_32BIT)
? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
assemble_name (file, buf);
if (TARGET_ELF && TARGET_MINIMAL_TOC)
fputs ("-(.LCTOC1)", file);
asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
asm_fprintf (file,
(TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
r0, r12);
asm_fprintf (file,
(TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
toc, r12);
asm_fprintf (file, "\tmtctr %s\n", r0);
asm_fprintf (file,
(TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
schain, r12);
asm_fprintf (file, "\tbctr\n");
break;
case ABI_AIX_NODESC:
case ABI_V4:
fprintf (file, "\tb %s", prefix);
assemble_name (file, fname);
if (flag_pic) fputs ("@plt", file);
putc ('\n', file);
break;
funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
#if TARGET_MACHO
case ABI_DARWIN:
fprintf (file, "\tb %s", prefix);
if (flag_pic && !machopic_name_defined_p (fname))
assemble_name (file, machopic_stub_name (fname));
else
assemble_name (file, fname);
putc ('\n', file);
break;
if (flag_pic)
funexp = machopic_indirect_call_target (funexp);
#endif
}
}
/* gen_sibcall expects reload to convert scratch pseudo to LR so we must
generate sibcall RTL explicitly to avoid constraint abort. */
insn = emit_call_insn (
gen_rtx_PARALLEL (VOIDmode,
gen_rtvec (4,
gen_rtx_CALL (VOIDmode,
funexp, const0_rtx),
gen_rtx_USE (VOIDmode, const0_rtx),
gen_rtx_USE (VOIDmode,
gen_rtx_REG (SImode,
LINK_REGISTER_REGNUM)),
gen_rtx_RETURN (VOIDmode))));
SIBLING_CALL_P (insn) = 1;
emit_barrier ();
/* Run just enough of rest_of_compilation to get the insns emitted.
There's not really enough bulk here to make other passes such as
instruction scheduling worth while. Note that use_thunk calls
assemble_start_function and assemble_end_function. */
insn = get_insns ();
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1, 0);
final_end_function ();
reload_completed = 0;
no_new_pseudos = 0;
}
/* A quick summary of the various types of 'constant-pool tables'
......
......@@ -2274,7 +2274,7 @@ do { \
/* Mode of a function address in a call instruction (for indexing purposes).
Doesn't matter on RS/6000. */
#define FUNCTION_MODE (TARGET_32BIT ? SImode : DImode)
#define FUNCTION_MODE SImode
/* Define this if addresses of constant functions
shouldn't be put through pseudo regs where they can be cse'd.
......
......@@ -296,11 +296,7 @@ toc_section () \
putc ('.', FILE); \
RS6000_OUTPUT_BASENAME (FILE, NAME); \
fputs (":\n", FILE); \
if (write_symbols == XCOFF_DEBUG \
/* When called before targetm.asm_out.output_mi_thunk, \
we won't be emitting the rest of the debug info that \
goes along with this, leading to assembler errors. */ \
&& !(current_function_is_thunk && !no_new_pseudos)) \
if (write_symbols != NO_DEBUG) \
xcoffout_declare_function (FILE, DECL, NAME); \
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment