aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Edelsohn <edelsohn@gnu.org>2003-01-08 23:05:22 +0000
committerDavid Edelsohn <dje@gcc.gnu.org>2003-01-08 18:05:22 -0500
commit5b71a4e7aca0ce49e11ad30cad705d10fbbc3be5 (patch)
tree1780067f61586da2b47e577b223448fb249491d0 /gcc
parent66e2aa7d3acf0b5ef6eac043668211d06e37573f (diff)
downloadgcc-5b71a4e7aca0ce49e11ad30cad705d10fbbc3be5.zip
gcc-5b71a4e7aca0ce49e11ad30cad705d10fbbc3be5.tar.gz
gcc-5b71a4e7aca0ce49e11ad30cad705d10fbbc3be5.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/rs6000/rs6000.c240
-rw-r--r--gcc/config/rs6000/rs6000.h2
-rw-r--r--gcc/config/rs6000/xcoff.h6
4 files changed, 100 insertions, 159 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 91d8a3d..ed19269 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+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
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 0daf648..292a0b8 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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'
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 08f32be..6756804 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -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.
diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h
index 64a0dcd..890e30d 100644
--- a/gcc/config/rs6000/xcoff.h
+++ b/gcc/config/rs6000/xcoff.h
@@ -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); \
}