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:
parent
0e67d46049
commit
3961e8fe9e
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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' */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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); \
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 *));
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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'.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
31
gcc/hooks.c
31
gcc/hooks.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
24
gcc/target.h
24
gcc/target.h
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue