summaryrefslogtreecommitdiff
path: root/gcc/config/i386
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2002-10-18 23:35:40 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2002-10-18 23:35:40 +0000
commitc6933ba665c7433567a708de11ac914c3b78d715 (patch)
tree17088ab6800bbdff9c6f83a72299fa33aada4853 /gcc/config/i386
parentf54087fb1442ddc57cc531f96a4b3c06896ea8b9 (diff)
downloadgcc-c6933ba665c7433567a708de11ac914c3b78d715.tar.gz
* target-def.h (TARGET_ASM_OUTPUT_MI_THUNK): Default to NULL.
(TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Likewise. (TARGET_ASM_OUT): Add them. * target.h (asm_out): Add output_mi_thunk and output_mi_vcall_thunk. * config/alpha/alpha.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/arm/arm-protos.h (arm_output_mi_thunk): Declare. * config/arm/arm.c (arm_output_mi_thunk): Define. * config/arm/arm.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/cris/cris.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/frv/frv.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/i386/i386-protos.h (x86_output_mi_thunk): Adjust prototype. (x86_output_mi_vcall_thunk): Declare. * config/i386/i386.c (override_options): Clear output_mi_vcall_thunk in 64-bit mode. (ix86_fntype_regparm): New function. (ix86_return_pops_args): Use it. (ia32_this_parameter): New function. (x86_output_mi_vcall_thunk): New function. (x86_output_mi_thunk): Use it * config/i386/unix.h (TARGET_ASM_OUTPUT_MI_THUNK): Adjust. (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Define. * config/i960/i960-protos.h (i960_output_mi_thunk): Declare. * config/i960/i960.c (i960_output_mi_thunk): New function. * config/i960/i960.h (ASM_OUTPUT_MI_THUNK): Adjust. * config/ia64/ia64-protos.h (ia64_output_mi_thunk): Declare. * config/ia64/ia64.c (ia64_output_mi_thunk): Define. * config/ia64/ia64.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/m68k/m68k-protos.h (m68k_output_mi_thunk): New function. * config/m68k/linux.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/m68k/netbsd-elf.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/mmix/mmix.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/pa/pa.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/rs6000/sysv4.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/s390/s390-protos.h (s390_output_mi_thunk): Declare. * config/s390/s390.c (s390_output_mi_thunk): Define. * config/s390/s390.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/sparc/sparc.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/stormy16/stormy16.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * config/vax/vax-protos.h (vax_output_mi_thunk): Declare. * config/vax/vax.c (vax_output_mi_thunk): Define. * config/vax/vax.h (ASM_OUTPUT_MI_THUNK): Rename to ... (TARGET_ASM_OUTPUT_MI_THUNK): ... this. * doc/tm.texi: Adjust documentation. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@58293 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/i386')
-rw-r--r--gcc/config/i386/i386-protos.h3
-rw-r--r--gcc/config/i386/i386.c140
-rw-r--r--gcc/config/i386/unix.h6
3 files changed, 117 insertions, 32 deletions
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index f0bdf22cf6a..c3b7c308349 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -211,7 +211,8 @@ extern tree ix86_handle_shared_attribute PARAMS ((tree *, tree, tree, int, bool
extern unsigned int i386_pe_section_type_flags PARAMS ((tree, const char *,
int));
extern void i386_pe_asm_named_section PARAMS ((const char *, unsigned int));
-extern void x86_output_mi_thunk PARAMS ((FILE *, int, tree));
+extern void x86_output_mi_thunk PARAMS ((FILE *, tree, int, tree));
+extern void x86_output_mi_vcall_thunk PARAMS ((FILE *, tree, int, int, tree));
extern int x86_field_alignment PARAMS ((tree, int));
#endif
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 1ea90ee860f..c96270241d1 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -750,6 +750,7 @@ 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));
struct ix86_address
{
@@ -788,6 +789,7 @@ static unsigned int ix86_select_alt_pic_regnum PARAMS ((void));
static int ix86_save_reg PARAMS ((unsigned int, int));
static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
static int ix86_comp_type_attributes PARAMS ((tree, tree));
+static int ix86_fntype_regparm PARAMS ((tree));
const struct attribute_spec ix86_attribute_table[];
static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
@@ -1295,6 +1297,10 @@ 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
@@ -1431,6 +1437,21 @@ ix86_comp_type_attributes (type1, type2)
return 1;
}
+/* Return the regparm value for a fuctio with the indicated TYPE. */
+
+static int
+ix86_fntype_regparm (type)
+ tree type;
+{
+ tree attr;
+
+ attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
+ if (attr)
+ return TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
+ else
+ return ix86_regparm;
+}
+
/* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call.
FUNDECL is the declaration node of the function (as a tree),
@@ -1474,15 +1495,7 @@ ix86_return_pops_args (fundecl, funtype, size)
if (aggregate_value_p (TREE_TYPE (funtype))
&& !TARGET_64BIT)
{
- int nregs = ix86_regparm;
-
- if (funtype)
- {
- tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (funtype));
-
- if (attr)
- nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
- }
+ int nregs = ix86_fntype_regparm (funtype);
if (!nregs)
return GET_MODE_SIZE (Pmode);
@@ -13860,27 +13873,51 @@ x86_order_regs_for_local_alloc ()
reg_alloc_order [pos++] = 0;
}
+/* Returns an expression indicating where the this parameter is
+ located on entry to the FUNCTION. */
+
+static rtx
+ia32_this_parameter (function)
+ tree function;
+{
+ tree type = TREE_TYPE (function);
+
+ if (ix86_fntype_regparm (type) > 0)
+ {
+ tree parm;
+
+ parm = TYPE_ARG_TYPES (type);
+ /* Figure out whether or not the function has a variable number of
+ arguments. */
+ for (; parm; parm = TREE_CHAIN (parm))\
+ if (TREE_VALUE (parm) == void_type_node)
+ break;
+ /* If not, the this parameter is in %eax. */
+ if (parm)
+ return gen_rtx_REG (SImode, 0);
+ }
+
+ if (aggregate_value_p (TREE_TYPE (type)))
+ return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8));
+ else
+ return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4));
+}
+
+
void
-x86_output_mi_thunk (file, delta, function)
+x86_output_mi_vcall_thunk (file, thunk, delta, vcall_index, function)
FILE *file;
+ tree thunk ATTRIBUTE_UNUSED;
int delta;
+ int vcall_index;
tree function;
{
- tree parm;
rtx xops[3];
- if (ix86_regparm > 0)
- parm = TYPE_ARG_TYPES (TREE_TYPE (function));
- else
- parm = NULL_TREE;
- for (; parm; parm = TREE_CHAIN (parm))
- if (TREE_VALUE (parm) == void_type_node)
- break;
-
- xops[0] = GEN_INT (delta);
if (TARGET_64BIT)
{
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)
@@ -13898,13 +13935,49 @@ x86_output_mi_thunk (file, delta, function)
}
else
{
- if (parm)
- xops[1] = gen_rtx_REG (SImode, 0);
- else if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
- xops[1] = gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8));
- else
- xops[1] = gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4));
- output_asm_insn ("add{l} {%0, %1|%1, %0}", xops);
+ /* 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)
{
@@ -13928,13 +14001,24 @@ x86_output_mi_thunk (file, delta, function)
}
else
{
- fprintf (file, "\tjmp ");
+ fprintf (file, "\tjmp\t");
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
fprintf (file, "\n");
}
}
}
+void
+x86_output_mi_thunk (file, thunk, delta, function)
+ FILE *file;
+ tree thunk;
+ int delta;
+ tree function;
+{
+ x86_output_mi_vcall_thunk (file, thunk, delta, /*vcall_index=*/0,
+ function);
+}
+
int
x86_field_alignment (field, computed)
tree field;
diff --git a/gcc/config/i386/unix.h b/gcc/config/i386/unix.h
index 3ba1bd5da7d..09493b08808 100644
--- a/gcc/config/i386/unix.h
+++ b/gcc/config/i386/unix.h
@@ -1,5 +1,5 @@
/* Definitions for Unix assembler syntax for the Intel 80386.
- Copyright (C) 1988, 1994, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1994, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -68,5 +68,5 @@ Boston, MA 02111-1307, USA. */
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance. */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
- x86_output_mi_thunk (FILE, DELTA, FUNCTION);
+#define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
+#define TARGET_ASM_OUTPUT_MI_VCALL_THUNK x86_output_mi_vcall_thunk