target.h (gcc_target.asm_out): Merge output_mi_thunk and output_mi_vcall_thunk into a single hook.

gcc/
	* target.h (gcc_target.asm_out): Merge output_mi_thunk and
	output_mi_vcall_thunk into a single hook.  Add can_output_mi_thunk.
	* target-def.h (TARGET_ASM_OUTPUT_MI_THUNK): Don't conditionalize.
	(TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Remove.
	(TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
	(TARGET_ASM_OUT): Update.
	* hooks.c (hook_bool_tree_hwi_hwi_tree_false): New.
	(hook_bool_tree_hwi_hwi_tree_true): New.
	(default_can_output_mi_thunk_no_vcall): New.
	* hooks.h: Declare them.
	* system.h (ASM_OUTPUT_MI_THUNK): Poison.

	* config/alpha/alpha.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
	(alpha_output_mi_thunk_osf): Add VCALL_OFFSET parameter.
	* config/arm/arm.c, config/cris/cris.c, config/frv/frv.c,
	config/i960/i960.c, config/ia64/ia64.c, config/m68k/m68k.c,
	config/mmix/mmix.c, config/pa/pa.c, config/sparc/sparc.c,
	config/stormy16/stormy16.c: Similarly.

	* config/i386/i386.c (x86_output_mi_thunk): Merge vcall_offset code.
	Handle 64-bit properly.  Streamline.
	(x86_output_mi_vcall_thunk): Remove.
	(x86_this_parameter): Rename from ia32_this_parameter; handle 64-bit.
	(x86_can_output_mi_thunk): New.
	(TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Remove.
	(TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
	(override_options): Don't zap targetm.asm_out.output_mi_vcall_thunk.

	* config/rs6000/rs6000.c (rs6000_output_mi_thunk): Rename from
	output_mi_thunk; make static; always use function_section.
	(TARGET_ASM_OUTPUT_MI_THUNK): New.
	(TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
	(rs6000_ra_ever_killed): Test no_new_pseudos not
	targetm.asm_out.output_mi_thunk in conjunction with thunks.
	* config/rs6000/rs6000-protos.h: Update.
	* config/rs6000/sysv4.h (TARGET_ASM_OUTPUT_MI_THUNK): Remove.
	* config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Don't call
	xcoffout_declare_function when using rs6000_output_mi_thunk.

	* config/s390/s390.c (s390_output_mi_thunk): Rename from
	s390_output_mi_vcall_thunk.
	(TARGET_ASM_OUTPUT_MI_THUNK): Remove.
	(TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.

	* config/vax/vax.c (vax_output_mi_thunk): Static; add vcall_offset.
	(TARGET_ASM_OUTPUT_MI_THUNK, TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
	* config/vax/vax-protos.h: Update.
	* config/vax/vax.h (ASM_OUTPUT_MI_THUNK): Remove.

gcc/cp/
        * method.c (use_thunk): Always compute vcall_value; assert that
        it is not zero.  Use can_output_mi_thunk; use output_mi_thunk
        for vcall thunks as well.

From-SVN: r58424
This commit is contained in:
Richard Henderson 2002-10-22 16:05:28 -07:00 committed by Richard Henderson
parent 0e67d46049
commit 3961e8fe9e
28 changed files with 379 additions and 216 deletions

View File

@ -1,3 +1,54 @@
2002-10-22 Richard Henderson <rth@redhat.com>
* target.h (gcc_target.asm_out): Merge output_mi_thunk and
output_mi_vcall_thunk into a single hook. Add can_output_mi_thunk.
* target-def.h (TARGET_ASM_OUTPUT_MI_THUNK): Don't conditionalize.
(TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Remove.
(TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
(TARGET_ASM_OUT): Update.
* hooks.c (hook_bool_tree_hwi_hwi_tree_false): New.
(hook_bool_tree_hwi_hwi_tree_true): New.
(default_can_output_mi_thunk_no_vcall): New.
* hooks.h: Declare them.
* system.h (ASM_OUTPUT_MI_THUNK): Poison.
* config/alpha/alpha.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
(alpha_output_mi_thunk_osf): Add VCALL_OFFSET parameter.
* config/arm/arm.c, config/cris/cris.c, config/frv/frv.c,
config/i960/i960.c, config/ia64/ia64.c, config/m68k/m68k.c,
config/mmix/mmix.c, config/pa/pa.c, config/sparc/sparc.c,
config/stormy16/stormy16.c: Similarly.
* config/i386/i386.c (x86_output_mi_thunk): Merge vcall_offset code.
Handle 64-bit properly. Streamline.
(x86_output_mi_vcall_thunk): Remove.
(x86_this_parameter): Rename from ia32_this_parameter; handle 64-bit.
(x86_can_output_mi_thunk): New.
(TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Remove.
(TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
(override_options): Don't zap targetm.asm_out.output_mi_vcall_thunk.
* config/rs6000/rs6000.c (rs6000_output_mi_thunk): Rename from
output_mi_thunk; make static; always use function_section.
(TARGET_ASM_OUTPUT_MI_THUNK): New.
(TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
(rs6000_ra_ever_killed): Test no_new_pseudos not
targetm.asm_out.output_mi_thunk in conjunction with thunks.
* config/rs6000/rs6000-protos.h: Update.
* config/rs6000/sysv4.h (TARGET_ASM_OUTPUT_MI_THUNK): Remove.
* config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Don't call
xcoffout_declare_function when using rs6000_output_mi_thunk.
* config/s390/s390.c (s390_output_mi_thunk): Rename from
s390_output_mi_vcall_thunk.
(TARGET_ASM_OUTPUT_MI_THUNK): Remove.
(TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
* config/vax/vax.c (vax_output_mi_thunk): Static; add vcall_offset.
(TARGET_ASM_OUTPUT_MI_THUNK, TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
* config/vax/vax-protos.h: Update.
* config/vax/vax.h (ASM_OUTPUT_MI_THUNK): Remove.
Wed Oct 23 00:33:11 CEST 2002 Jan Hubicka <jh@suse,cz>
* i386.c (standard_sse_constant_p): Accept vector and integer zeros too.

View File

@ -197,7 +197,7 @@ static void alpha_write_linkage
#if TARGET_ABI_OSF
static void alpha_output_mi_thunk_osf
PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
#endif
static struct machine_function * alpha_init_machine_status
@ -300,6 +300,8 @@ static void unicosmk_unique_section PARAMS ((tree, int));
#if TARGET_ABI_OSF
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
#endif
struct gcc_target targetm = TARGET_INITIALIZER;
@ -7860,10 +7862,11 @@ alpha_end_function (file, fnname, decl)
Not sure why this idea hasn't been explored before... */
static void
alpha_output_mi_thunk_osf (file, thunk_fndecl, delta, function)
alpha_output_mi_thunk_osf (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;
tree function;
{
HOST_WIDE_INT hi, lo;

View File

@ -127,6 +127,7 @@ static void arm_encode_section_info PARAMS ((tree, int));
static void aof_globalize_label PARAMS ((FILE *, const char *));
#endif
static void arm_output_mi_thunk PARAMS ((FILE *, tree,
HOST_WIDE_INT,
HOST_WIDE_INT, tree));
#undef Hint
@ -192,6 +193,8 @@ static void arm_output_mi_thunk PARAMS ((FILE *, tree,
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK arm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
struct gcc_target targetm = TARGET_INITIALIZER;
@ -11154,10 +11157,11 @@ arm_encode_section_info (decl, first)
to FUNCTION. Used for C++ multiple inheritance. */
static void
arm_output_mi_thunk (file, thunk, delta, function)
arm_output_mi_thunk (file, thunk, delta, vcall_offset, function)
FILE *file;
tree thunk ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
tree function;
{
int mi_delta = delta;

View File

@ -102,7 +102,7 @@ static void cris_encode_section_info PARAMS ((tree, int));
static void cris_operand_lossage PARAMS ((const char *, rtx));
static void cris_asm_output_mi_thunk
PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
/* The function cris_target_asm_function_epilogue puts the last insn to
@ -159,6 +159,8 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION;
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK cris_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
struct gcc_target targetm = TARGET_INITIALIZER;
@ -2580,10 +2582,11 @@ cris_override_options ()
/* The TARGET_ASM_OUTPUT_MI_THUNK worker. */
static void
cris_asm_output_mi_thunk (stream, thunkdecl, delta, funcdecl)
cris_asm_output_mi_thunk (stream, thunkdecl, delta, vcall_offset, funcdecl)
FILE *stream;
tree thunkdecl ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
tree funcdecl;
{
if (delta > 0)

View File

@ -279,7 +279,8 @@ static void frv_encode_section_info PARAMS ((tree, int));
static void frv_init_builtins PARAMS ((void));
static rtx frv_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
static bool frv_in_small_data_p PARAMS ((tree));
static void frv_asm_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
static void frv_asm_output_mi_thunk
PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
/* Initialize the GCC target structure. */
#undef TARGET_ASM_FUNCTION_PROLOGUE
@ -301,6 +302,8 @@ static void frv_asm_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree)
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK frv_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
struct gcc_target targetm = TARGET_INITIALIZER;
@ -1871,10 +1874,11 @@ frv_expand_epilogue (sibcall_p)
varargs. */
static void
frv_asm_output_mi_thunk (file, thunk_fndecl, delta, function)
frv_asm_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;
tree function;
{
const char *name_func = XSTR (XEXP (DECL_RTL (function), 0), 0);

View File

@ -750,10 +750,11 @@ static int ix86_variable_issue PARAMS ((FILE *, int, rtx, int));
static int ia32_use_dfa_pipeline_interface PARAMS ((void));
static int ia32_multipass_dfa_lookahead PARAMS ((void));
static void ix86_init_mmx_sse_builtins PARAMS ((void));
static rtx ia32_this_parameter PARAMS ((tree));
static void x86_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
static void x86_output_mi_vcall_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
static rtx x86_this_parameter PARAMS ((tree));
static void x86_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
static bool x86_can_output_mi_thunk PARAMS ((tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
struct ix86_address
{
@ -902,8 +903,8 @@ static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
#undef TARGET_ASM_OUTPUT_MI_VCALL_THUNK
#define TARGET_ASM_OUTPUT_MI_VCALL_THUNK x86_output_mi_vcall_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
struct gcc_target targetm = TARGET_INITIALIZER;
@ -1305,10 +1306,6 @@ override_options ()
internal_label_prefix_len = p - internal_label_prefix;
*p = '\0';
}
/* In 64-bit mode, we do not have support for vcall thunks. */
if (TARGET_64BIT)
targetm.asm_out.output_mi_vcall_thunk = NULL;
}
void
@ -14076,11 +14073,17 @@ x86_order_regs_for_local_alloc ()
located on entry to the FUNCTION. */
static rtx
ia32_this_parameter (function)
x86_this_parameter (function)
tree function;
{
tree type = TREE_TYPE (function);
if (TARGET_64BIT)
{
int n = aggregate_value_p (TREE_TYPE (type)) != 0;
return gen_rtx_REG (DImode, x86_64_int_parameter_registers[n]);
}
if (ix86_fntype_regparm (type) > 0)
{
tree parm;
@ -14088,7 +14091,7 @@ ia32_this_parameter (function)
parm = TYPE_ARG_TYPES (type);
/* Figure out whether or not the function has a variable number of
arguments. */
for (; parm; parm = TREE_CHAIN (parm))\
for (; parm; parm = TREE_CHAIN (parm))
if (TREE_VALUE (parm) == void_type_node)
break;
/* If not, the this parameter is in %eax. */
@ -14102,122 +14105,152 @@ ia32_this_parameter (function)
return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4));
}
/* Determine whether x86_output_mi_thunk can succeed. */
static bool
x86_can_output_mi_thunk (thunk, delta, vcall_offset, function)
tree thunk ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta ATTRIBUTE_UNUSED;
HOST_WIDE_INT vcall_offset;
tree function;
{
/* 64-bit can handle anything. */
if (TARGET_64BIT)
return true;
/* For 32-bit, everything's fine if we have one free register. */
if (ix86_fntype_regparm (TREE_TYPE (function)) < 3)
return true;
/* Need a free register for vcall_offset. */
if (vcall_offset)
return false;
/* Need a free register for GOT references. */
if (flag_pic && !(*targetm.binds_local_p) (function))
return false;
/* Otherwise ok. */
return true;
}
/* Output the assembler code for a thunk function. THUNK_DECL is the
declaration for the thunk function itself, FUNCTION is the decl for
the target function. DELTA is an immediate constant offset to be
added to THIS. If VCALL_OFFSET is non-zero, the word at
*(*this + vcall_offset) should be added to THIS. */
static void
x86_output_mi_vcall_thunk (file, thunk, delta, vcall_index, function)
FILE *file;
x86_output_mi_thunk (file, thunk, delta, vcall_offset, function)
FILE *file ATTRIBUTE_UNUSED;
tree thunk ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
HOST_WIDE_INT vcall_index;
HOST_WIDE_INT vcall_offset;
tree function;
{
rtx xops[3];
rtx this = x86_this_parameter (function);
rtx this_reg, tmp;
if (TARGET_64BIT)
/* If VCALL_OFFSET, we'll need THIS in a register. Might as well
pull it in now and let DELTA benefit. */
if (REG_P (this))
this_reg = this;
else if (vcall_offset)
{
/* Put the this parameter into %eax. */
xops[0] = this;
xops[1] = this_reg = gen_rtx_REG (Pmode, 0);
output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
}
else
this_reg = NULL_RTX;
/* Adjust the this parameter by a fixed constant. */
if (delta)
{
int n = aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) != 0;
xops[0] = GEN_INT (delta);
xops[1] = gen_rtx_REG (DImode, x86_64_int_parameter_registers[n]);
output_asm_insn ("add{q} {%0, %1|%1, %0}", xops);
if (flag_pic)
xops[1] = this_reg ? this_reg : this;
if (TARGET_64BIT)
{
fprintf (file, "\tjmp *");
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
fprintf (file, "@GOTPCREL(%%rip)\n");
if (!x86_64_general_operand (xops[0], DImode))
{
tmp = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 2 /* R10 */);
xops[1] = tmp;
output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", xops);
xops[0] = tmp;
xops[1] = this;
}
output_asm_insn ("add{q}\t{%0, %1|%1, %0}", xops);
}
else
output_asm_insn ("add{l}\t{%0, %1|%1, %0}", xops);
}
/* Adjust the this parameter by a value stored in the vtable. */
if (vcall_offset)
{
if (TARGET_64BIT)
tmp = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 2 /* R10 */);
else
tmp = gen_rtx_REG (SImode, 2 /* ECX */);
xops[0] = gen_rtx_MEM (Pmode, this_reg);
xops[1] = tmp;
if (TARGET_64BIT)
output_asm_insn ("mov{q}\t{%0, %1|%1, %0}", xops);
else
output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
/* Adjust the this parameter. */
xops[0] = gen_rtx_MEM (Pmode, plus_constant (tmp, vcall_offset));
if (TARGET_64BIT && !memory_operand (xops[0], Pmode))
{
fprintf (file, "\tjmp ");
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
fprintf (file, "\n");
rtx tmp2 = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 3 /* R11 */);
xops[0] = GEN_INT (vcall_offset);
xops[1] = tmp2;
output_asm_insn ("mov{q}\t{%0, %1|%1, %0}", xops);
xops[0] = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tmp, tmp2));
}
xops[1] = this_reg;
if (TARGET_64BIT)
output_asm_insn ("add{q}\t{%0, %1|%1, %0}", xops);
else
output_asm_insn ("add{l}\t{%0, %1|%1, %0}", xops);
}
/* If necessary, drop THIS back to its stack slot. */
if (this_reg && this_reg != this)
{
xops[0] = this_reg;
xops[1] = this;
output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
}
xops[0] = DECL_RTL (function);
if (TARGET_64BIT)
{
if (!flag_pic || (*targetm.binds_local_p) (function))
output_asm_insn ("jmp\t%P0", xops);
else
output_asm_insn ("jmp\t*%P0@GOTPCREL(%%rip)", xops);
}
else
{
/* Adjust the this parameter by a fixed constant. */
if (delta)
{
xops[0] = GEN_INT (delta);
xops[1] = ia32_this_parameter (function);
output_asm_insn ("add{l}\t{%0, %1|%1, %0}", xops);
}
/* Adjust the this parameter by a value stored in the vtable. */
if (vcall_index)
{
rtx this_parm;
/* Put the this parameter into %eax. */
this_parm = ia32_this_parameter (function);
if (!REG_P (this_parm))
{
xops[0] = this_parm;
xops[1] = gen_rtx_REG (Pmode, 0);
output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
}
/* Load the virtual table pointer into %edx. */
if (ix86_fntype_regparm (TREE_TYPE (function)) > 2)
error ("virtual function `%D' cannot have more than two register parameters",
function);
xops[0] = gen_rtx_MEM (Pmode,
gen_rtx_REG (Pmode, 0));
xops[1] = gen_rtx_REG (Pmode, 1);
output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
/* Adjust the this parameter. */
xops[0] = gen_rtx_MEM (SImode,
plus_constant (gen_rtx_REG (Pmode, 1),
vcall_index));
xops[1] = gen_rtx_REG (Pmode, 0);
output_asm_insn ("add{l}\t{%0, %1|%1, %0}", xops);
/* Put the this parameter back where it came from. */
if (!REG_P (this_parm))
{
xops[0] = gen_rtx_REG (Pmode, 0);
xops[1] = ia32_this_parameter (function);
output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
}
}
if (flag_pic)
{
xops[0] = pic_offset_table_rtx;
xops[1] = gen_label_rtx ();
xops[2] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
if (ix86_regparm > 2)
abort ();
output_asm_insn ("push{l}\t%0", xops);
output_asm_insn ("call\t%P1", xops);
ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
output_asm_insn ("pop{l}\t%0", xops);
output_asm_insn
("add{l}\t{%2+[.-%P1], %0|%0, OFFSET FLAT: %2+[.-%P1]}", xops);
xops[0] = gen_rtx_MEM (SImode, XEXP (DECL_RTL (function), 0));
output_asm_insn
("mov{l}\t{%0@GOT(%%ebx), %%ecx|%%ecx, %0@GOT[%%ebx]}", xops);
asm_fprintf (file, "\tpop{l\t%%ebx|\t%%ebx}\n");
asm_fprintf (file, "\tjmp\t{*%%ecx|%%ecx}\n");
}
if (!flag_pic || (*targetm.binds_local_p) (function))
output_asm_insn ("jmp\t%P0", xops);
else
{
fprintf (file, "\tjmp\t");
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
fprintf (file, "\n");
tmp = gen_rtx_REG (SImode, 2 /* ECX */);
output_set_got (tmp);
xops[1] = tmp;
output_asm_insn ("mov{l}\t{%0@GOT(%1), %1|%1, %0@GOT[%1]}", xops);
output_asm_insn ("jmp\t{*}%1", xops);
}
}
}
static void
x86_output_mi_thunk (file, thunk, delta, function)
FILE *file;
tree thunk;
HOST_WIDE_INT delta;
tree function;
{
x86_output_mi_vcall_thunk (file, thunk, delta, /*vcall_index=*/0,
function);
}
int
x86_field_alignment (field, computed)
tree field;

View File

@ -46,7 +46,8 @@ Boston, MA 02111-1307, USA. */
static void i960_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void i960_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void i960_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
static void i960_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
/* Save the operands last given to a compare for use when we
generate a scc or bcc insn. */
@ -101,6 +102,8 @@ static int ret_label = 0;
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK i960_output_mi_thunk
#undef TARGET_CAN_ASM_OUTPUT_MI_THUNK
#define TARGET_CAN_ASM_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
struct gcc_target targetm = TARGET_INITIALIZER;
@ -2830,10 +2833,11 @@ i960_scan_opcode (p)
}
static void
i960_output_mi_thunk (file, thunk, delta, function)
i960_output_mi_thunk (file, thunk, delta, vcall_offset, function)
FILE *file;
tree thunk ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
tree function;
{
int d = delta;

View File

@ -161,7 +161,8 @@ static int ia64_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
static int ia64_sched_reorder2 PARAMS ((FILE *, int, rtx *, int *, int));
static int ia64_variable_issue PARAMS ((FILE *, int, rtx, int));
static void ia64_output_mi_thunk PARAMS((FILE *, tree, HOST_WIDE_INT, tree));
static void ia64_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
static void ia64_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
@ -248,6 +249,8 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK ia64_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
struct gcc_target targetm = TARGET_INITIALIZER;
@ -8165,10 +8168,11 @@ ia64_aix_select_rtx_section (mode, x, align)
}
static void
ia64_output_mi_thunk (file, thunk, delta, function)
ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function)
FILE *file;
tree thunk ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
tree function;
{
if (CONST_OK_FOR_I (delta))

View File

@ -65,7 +65,8 @@ static void m68k_coff_asm_named_section PARAMS ((const char *, unsigned int));
#ifdef CTOR_LIST_BEGIN
static void m68k_svr3_asm_out_constructor PARAMS ((rtx, int));
#endif
static void m68k_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
static void m68k_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
/* Alignment to use for loops and jumps */
@ -125,6 +126,8 @@ int m68k_last_compare_had_fp_operands;
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK m68k_output_mi_thunk
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
struct gcc_target targetm = TARGET_INITIALIZER;
@ -3841,10 +3844,11 @@ m68k_svr3_asm_out_constructor (symbol, priority)
#endif
static void
m68k_output_mi_thunk (file, thunk, delta, function)
m68k_output_mi_thunk (file, thunk, delta, vcall_offset, function)
FILE *file;
tree thunk ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
tree function;
{
rtx xops[1];

View File

@ -131,7 +131,7 @@ static void mmix_target_asm_function_end_prologue PARAMS ((FILE *));
static void mmix_target_asm_function_epilogue
PARAMS ((FILE *, HOST_WIDE_INT));
static void mmix_asm_output_mi_thunk
PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
/* Target structure macros. Listed by node. See `Using and Porting GCC'
@ -166,6 +166,8 @@ static void mmix_asm_output_mi_thunk
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK mmix_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
struct gcc_target targetm = TARGET_INITIALIZER;
@ -778,10 +780,11 @@ mmix_target_asm_function_epilogue (stream, locals_size)
/* TARGET_ASM_OUTPUT_MI_THUNK. */
static void
mmix_asm_output_mi_thunk (stream, fndecl, delta, func)
mmix_asm_output_mi_thunk (stream, fndecl, delta, vcall_offset, func)
FILE * stream;
tree fndecl ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
tree func;
{
/* If you define STRUCT_VALUE to 0, rather than use STRUCT_VALUE_REGNUM,

View File

@ -119,7 +119,8 @@ static void pa_encode_section_info PARAMS ((tree, int));
static const char *pa_strip_name_encoding PARAMS ((const char *));
static void pa_globalize_label PARAMS ((FILE *, const char *))
ATTRIBUTE_UNUSED;
static void pa_asm_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
static void pa_asm_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
/* Save the operands last given to a compare for use when we
@ -199,6 +200,8 @@ static size_t n_deferred_plabels = 0;
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK pa_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
struct gcc_target targetm = TARGET_INITIALIZER;
@ -6556,10 +6559,11 @@ is_function_label_plus_const (op)
/* Output assembly code for a thunk to FUNCTION. */
static void
pa_asm_output_mi_thunk (file, thunk_fndecl, delta, function)
pa_asm_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
FILE *file;
tree thunk_fndecl;
HOST_WIDE_INT delta;
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
tree function;
{
const char *target_name = XSTR (XEXP (DECL_RTL (function), 0), 0);

View File

@ -150,7 +150,6 @@ extern void setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *,
enum machine_mode, tree,
int *, int));
extern struct rtx_def *rs6000_va_arg PARAMS ((tree, tree));
extern void output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
extern int function_ok_for_sibcall PARAMS ((tree));
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */

View File

@ -194,6 +194,8 @@ const struct attribute_spec rs6000_attribute_table[];
static void rs6000_set_default_type_attributes PARAMS ((tree));
static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void rs6000_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
static rtx rs6000_emit_set_long_const PARAMS ((rtx,
HOST_WIDE_INT, HOST_WIDE_INT));
#if TARGET_ELF
@ -311,6 +313,9 @@ static const char alt_reg_names[][8] =
#ifndef MASK_STRICT_ALIGN
#define MASK_STRICT_ALIGN 0
#endif
/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
@ -373,8 +378,15 @@ static const char alt_reg_names[][8] =
#undef TARGET_BINDS_LOCAL_P
#define TARGET_BINDS_LOCAL_P rs6000_binds_local_p
/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
#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
struct gcc_target targetm = TARGET_INITIALIZER;
@ -9463,7 +9475,11 @@ rs6000_ra_ever_killed ()
rtx reg;
rtx insn;
if (targetm.asm_out.output_mi_thunk && current_function_is_thunk)
/* Irritatingly, there are two kinds of thunks -- those created with
TARGET_ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go
through the regular part of the compiler. This is a very hacky
way to tell them apart. */
if (current_function_is_thunk && !no_new_pseudos)
return 0;
/* regs_ever_live has LR marked as used if any sibcalls are present,
@ -11238,11 +11254,12 @@ rs6000_output_function_epilogue (file, size)
calls FUNCTION instead of jumping to it. The generic approach does
not support varargs. */
void
output_mi_thunk (file, thunk_fndecl, delta, function)
static void
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;
tree function;
{
const char *this_reg =
@ -11348,10 +11365,7 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
}
assemble_name (file, fname);
putc ('\n', file);
if (TARGET_ELF)
function_section (current_function_decl);
else
text_section ();
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,
@ -11398,7 +11412,6 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
}
}
}
/* A quick summary of the various types of 'constant-pool tables'
under PowerPC:

View File

@ -637,38 +637,6 @@ extern int rs6000_pic_labelno;
ASM_OUTPUT_LABEL (FILE, NAME); \
} while (0)
/* A C compound statement that outputs the assembler code for a thunk function,
used to implement C++ virtual function calls with multiple inheritance. The
thunk acts as a wrapper around a virtual function, adjusting the implicit
object parameter before handing control off to the real function.
First, emit code to add the integer DELTA to the location that contains the
incoming first argument. Assume that this argument contains a pointer, and
is the one used to pass the this' pointer in C++. This is the incoming
argument *before* the function prologue, e.g. %o0' on a sparc. The
addition must preserve the values of all other incoming arguments.
After the addition, emit code to jump to FUNCTION, which is a
FUNCTION_DECL'. This is a direct pure jump, not a call, and does not touch
the return address. Hence returning from FUNCTION will return to whoever
called the current thunk'.
The effect must be as if FUNCTION had been called directly with the adjusted
first argument. This macro is responsible for emitting all of the code for
a thunk function; FUNCTION_PROLOGUE' and FUNCTION_EPILOGUE' are not
invoked.
The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already been
extracted from it.) It might possibly be useful on some targets, but
probably not.
If you do not define this macro, the target-independent code in the C++
frontend will generate a less efficient heavyweight thunk that calls
FUNCTION instead of jumping to it. The generic approach does not support
varargs. */
#define TARGET_ASM_OUTPUT_MI_THUNK output_mi_thunk
/* The USER_LABEL_PREFIX stuff is affected by the -fleading-underscore
flag. The LOCAL_LABEL_PREFIX variable is used by dbxelf.h. */

View File

@ -296,7 +296,11 @@ toc_section () \
putc ('.', FILE); \
RS6000_OUTPUT_BASENAME (FILE, NAME); \
fputs (":\n", FILE); \
if (write_symbols == XCOFF_DEBUG) \
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)) \
xcoffout_declare_function (FILE, DECL, NAME); \
}

View File

@ -54,8 +54,8 @@ static int s390_adjust_priority PARAMS ((rtx, int));
static void s390_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
static void s390_encode_section_info PARAMS ((tree, int));
static void s390_output_mi_vcall_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
static void s390_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
@ -82,8 +82,10 @@ static void s390_output_mi_vcall_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
#undef TARGET_ASM_OUTPUT_MI_VCALL_THUNK
#define TARGET_ASM_OUTPUT_MI_VCALL_THUNK s390_output_mi_vcall_thunk
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
struct gcc_target targetm = TARGET_INITIALIZER;
@ -5620,7 +5622,7 @@ s390_encode_section_info (decl, first)
relative to the resulting this pointer. */
static void
s390_output_mi_vcall_thunk (file, thunk, delta, vcall_offset, function)
s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
FILE *file;
tree thunk ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;

View File

@ -176,7 +176,8 @@ static void emit_soft_tfmode_cvt PARAMS ((enum rtx_code, rtx *));
static void emit_hard_tfmode_operation PARAMS ((enum rtx_code, rtx *));
static void sparc_encode_section_info PARAMS ((tree, int));
static void sparc_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
static void sparc_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
/* Option handling. */
@ -242,6 +243,8 @@ enum processor_type sparc_cpu;
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK sparc_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
struct gcc_target targetm = TARGET_INITIALIZER;
@ -8453,10 +8456,11 @@ sparc_encode_section_info (decl, first)
Used for C++ multiple inheritance. */
static void
sparc_output_mi_thunk (file, thunk_fndecl, delta, function)
sparc_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;
tree function;
{
rtx this, insn, funexp, delta_rtx, tmp;

View File

@ -51,7 +51,7 @@ static void xstormy16_asm_out_constructor PARAMS ((rtx, int));
static void xstormy16_asm_out_destructor PARAMS ((rtx, int));
static void xstormy16_encode_section_info PARAMS ((tree, int));
static void xstormy16_asm_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
tree));
HOST_WIDE_INT, tree));
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. */
@ -1383,10 +1383,12 @@ xstormy16_function_value (valtype, func)
probably not. */
static void
xstormy16_asm_output_mi_thunk (file, thunk_fndecl, delta, function)
xstormy16_asm_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;
tree function;
{
int regnum = FIRST_ARGUMENT_REGISTER;
@ -2035,5 +2037,7 @@ xstormy16_handle_interrupt_attribute (node, name, args, flags, no_add_attrs)
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK xstormy16_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
struct gcc_target targetm = TARGET_INITIALIZER;

View File

@ -36,7 +36,6 @@ extern int check_float_value PARAMS ((enum machine_mode, REAL_VALUE_TYPE *, int)
#ifdef TREE_CODE
extern void vms_check_external PARAMS ((tree, const char *, int));
extern void vax_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
#endif /* TREE_CODE */
extern void vms_flush_pending_externals PARAMS ((FILE *));

View File

@ -48,6 +48,8 @@ static void vms_select_section PARAMS ((tree, int, unsigned HOST_WIDE_INT));
static void vms_encode_section_info PARAMS ((tree, int));
static void vms_globalize_label PARAMS ((FILE *, const char *));
#endif
static void vax_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
@ -65,6 +67,11 @@ static void vms_globalize_label PARAMS ((FILE *, const char *));
#define TARGET_ASM_GLOBALIZE_LABEL vms_globalize_label
#endif
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
struct gcc_target targetm = TARGET_INITIALIZER;
/* Set global variables as needed for the options enabled. */
@ -993,11 +1000,12 @@ reg_was_0_p (insn, op)
&& ! reg_set_between_p (op, XEXP (link, 0), insn));
}
void
vax_output_mi_thunk (file, thunk, delta, function)
static void
vax_output_mi_thunk (file, thunk, delta, vcall_offset, function)
FILE *file;
tree thunk ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
tree function;
{
fprintf (file, "\t.word 0x0ffc\n");

View File

@ -1155,14 +1155,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance.
.mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask
addl2 $DELTA, 4(ap) #adjust first argument
jmp FUNCTION+2 #jump beyond FUNCTION's entry mask
*/
#define ASM_OUTPUT_MI_THUNK vax_output_mi_thunk
/* Print an instruction operand X on file FILE.
CODE is the code from the %-spec that requested printing this operand;
if `%z3' was used to print operand 3, then CODE is 'z'.

View File

@ -1,3 +1,9 @@
2002-10-22 Richard Henderson <rth@redhat.com>
* method.c (use_thunk): Always compute vcall_value; assert that
it is not zero. Use can_output_mi_thunk; use output_mi_thunk
for vcall thunks as well.
2002-10-21 Mark Mitchell <mark@codesourcery.com>
* class.c (empty_base_at_nonzero_offset_p): New function.

View File

@ -361,7 +361,7 @@ use_thunk (thunk_fndecl, emit_p)
tree fnaddr;
tree function;
tree vcall_offset;
HOST_WIDE_INT delta;
HOST_WIDE_INT delta, vcall_value;
if (TREE_ASM_WRITTEN (thunk_fndecl))
return;
@ -387,6 +387,17 @@ use_thunk (thunk_fndecl, emit_p)
delta = THUNK_DELTA (thunk_fndecl);
vcall_offset = THUNK_VCALL_OFFSET (thunk_fndecl);
if (vcall_offset)
{
vcall_value = tree_low_cst (vcall_offset, /*pos=*/0);
/* It is expected that a value of zero means no vcall. */
if (!vcall_value)
abort ();
}
else
vcall_value = 0;
/* And, if we need to emit the thunk, it's used. */
mark_used (thunk_fndecl);
/* This thunk is actually defined. */
@ -409,8 +420,8 @@ use_thunk (thunk_fndecl, emit_p)
BLOCK_VARS (DECL_INITIAL (thunk_fndecl))
= DECL_ARGUMENTS (thunk_fndecl);
if (targetm.asm_out.output_mi_vcall_thunk
|| (targetm.asm_out.output_mi_thunk && !vcall_offset))
if (targetm.asm_out.can_output_mi_thunk (thunk_fndecl, delta,
vcall_value, function))
{
const char *fnname;
current_function_decl = thunk_fndecl;
@ -420,22 +431,10 @@ use_thunk (thunk_fndecl, emit_p)
init_function_start (thunk_fndecl, input_filename, lineno);
current_function_is_thunk = 1;
assemble_start_function (thunk_fndecl, fnname);
if (targetm.asm_out.output_mi_vcall_thunk)
{
HOST_WIDE_INT vcall_value;
if (vcall_offset)
vcall_value = tree_low_cst (vcall_offset, /*pos=*/0);
else
vcall_value = 0;
targetm.asm_out.output_mi_vcall_thunk (asm_out_file,
thunk_fndecl, delta,
vcall_value,
function);
}
else
targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
delta, function);
targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl, delta,
vcall_value, function);
assemble_end_function (thunk_fndecl, fnname);
current_function_decl = 0;
cfun = 0;

View File

@ -62,3 +62,34 @@ hook_FILEptr_constcharptr_void (a, b)
const char *b ATTRIBUTE_UNUSED;
{
}
/* Used for the TARGET_ASM_CAN_OUTPUT_MI_THUNK hook. */
bool
hook_bool_tree_hwi_hwi_tree_false (a, b, c, d)
tree a ATTRIBUTE_UNUSED;
HOST_WIDE_INT b ATTRIBUTE_UNUSED;
HOST_WIDE_INT c ATTRIBUTE_UNUSED;
tree d ATTRIBUTE_UNUSED;
{
return false;
}
bool
hook_bool_tree_hwi_hwi_tree_true (a, b, c, d)
tree a ATTRIBUTE_UNUSED;
HOST_WIDE_INT b ATTRIBUTE_UNUSED;
HOST_WIDE_INT c ATTRIBUTE_UNUSED;
tree d ATTRIBUTE_UNUSED;
{
return true;
}
bool
default_can_output_mi_thunk_no_vcall (a, b, c, d)
tree a ATTRIBUTE_UNUSED;
HOST_WIDE_INT b ATTRIBUTE_UNUSED;
HOST_WIDE_INT c;
tree d ATTRIBUTE_UNUSED;
{
return c == 0;
}

View File

@ -27,5 +27,12 @@ bool hook_tree_bool_false PARAMS ((tree));
void hook_tree_int_void PARAMS ((tree, int));
void hook_void_void PARAMS ((void));
void hook_FILEptr_constcharptr_void PARAMS ((FILE *, const char *));
bool hook_bool_tree_hwi_hwi_tree_false
PARAMS ((tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
bool hook_bool_tree_hwi_hwi_tree_true
PARAMS ((tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
bool default_can_output_mi_thunk_no_vcall
PARAMS ((tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
#endif

View File

@ -599,7 +599,8 @@ typedef char _Bool;
MD_INIT_BUILTINS MD_EXPAND_BUILTIN ASM_OUTPUT_CONSTRUCTOR \
ASM_OUTPUT_DESTRUCTOR SIGNED_CHAR_SPEC MAX_CHAR_TYPE_SIZE \
WCHAR_UNSIGNED UNIQUE_SECTION SELECT_SECTION SELECT_RTX_SECTION \
ENCODE_SECTION_INFO STRIP_NAME_ENCODING ASM_GLOBALIZE_LABEL
ENCODE_SECTION_INFO STRIP_NAME_ENCODING ASM_GLOBALIZE_LABEL \
ASM_OUTPUT_MI_THUNK
/* Other obsolete target macros, or macros that used to be in target
headers and were not used, and may be obsolete or may never have

View File

@ -103,13 +103,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# endif
#endif
#ifndef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK NULL
#endif
#ifndef TARGET_ASM_OUTPUT_MI_VCALL_THUNK
#define TARGET_ASM_OUTPUT_MI_VCALL_THUNK NULL
#endif
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_false
#if defined(TARGET_ASM_CONSTRUCTOR) && defined(TARGET_ASM_DESTRUCTOR)
#define TARGET_HAVE_CTORS_DTORS true
@ -183,7 +178,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_ASM_CONSTRUCTOR, \
TARGET_ASM_DESTRUCTOR, \
TARGET_ASM_OUTPUT_MI_THUNK, \
TARGET_ASM_OUTPUT_MI_VCALL_THUNK }
TARGET_ASM_CAN_OUTPUT_MI_THUNK }
/* Scheduler hooks. All of these default to null pointers, which
haifa-sched.c looks for and handles. */

View File

@ -120,12 +120,26 @@ struct gcc_target
/* Output a destructor for a symbol with a given priority. */
void (* destructor) PARAMS ((rtx, int));
/* Output the assembler code for a thunk function. */
void (* output_mi_thunk) PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
/* Output the assembler code for a thunk function. THUNK_DECL is the
declaration for the thunk function itself, FUNCTION is the decl for
the target function. DELTA is an immediate constant offset to be
added to THIS. If VCALL_OFFSET is non-zero, the word at
*(*this + vcall_offset) should be added to THIS. */
void (* output_mi_thunk) PARAMS ((FILE *file, tree thunk_decl,
HOST_WIDE_INT delta,
HOST_WIDE_INT vcall_offset,
tree function_decl));
/* Output the assembler code for a thunk function with a vcall offset. */
void (* output_mi_vcall_thunk) PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
/* Determine whether output_mi_thunk would succeed. */
/* ??? Ideally, this hook would not exist, and success or failure
would be returned from output_mi_thunk directly. But there's
too much undo-able setup involved in invoking output_mi_thunk.
Could be fixed by making output_mi_thunk emit rtl instead of
text to the output file. */
bool (* can_output_mi_thunk) PARAMS ((tree thunk_decl,
HOST_WIDE_INT delta,
HOST_WIDE_INT vcall_offset,
tree function_decl));
} asm_out;
/* Functions relating to instruction scheduling. */