diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-10-18 23:35:40 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-10-18 23:35:40 +0000 |
commit | c6933ba665c7433567a708de11ac914c3b78d715 (patch) | |
tree | 17088ab6800bbdff9c6f83a72299fa33aada4853 /gcc/config/i386 | |
parent | f54087fb1442ddc57cc531f96a4b3c06896ea8b9 (diff) | |
download | gcc-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.h | 3 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 140 | ||||
-rw-r--r-- | gcc/config/i386/unix.h | 6 |
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 |