x86-64 thunks
Jan Hubicka
jh@suse.cz
Tue May 14 06:14:00 GMT 2002
Hi,
we missed the OUTPUT_MI_THUNK macro...
Would be OK to install this for 3.1.1 as well?
Mon May 13 18:11:38 CEST 2002 Jan Hubicka <jh@suse.cz>
* i386-protos.h (x86_output_mi_thunk): Declare.
* unix.h (ASM_OUTPUT_MI_THUNK): Move offline to ...
* i386.c (x86_output_mi_thunk): ... here; handle 64bits.
Index: i386-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.68
diff -c -3 -p -r1.68 i386-protos.h
*** i386-protos.h 7 Feb 2002 11:18:32 -0000 1.68
--- i386-protos.h 14 May 2002 09:25:57 -0000
*************** extern tree ix86_handle_shared_attribute
*** 197,200 ****
--- 197,201 ----
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));
#endif
Index: i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.368.2.9
diff -c -3 -p -r1.368.2.9 i386.c
*** i386.c 23 Apr 2002 08:11:22 -0000 1.368.2.9
--- i386.c 14 May 2002 09:25:58 -0000
*************** x86_order_regs_for_local_alloc ()
*** 12472,12475 ****
--- 12527,12605 ----
at all. */
while (pos < FIRST_PSEUDO_REGISTER)
reg_alloc_order [pos++] = 0;
+ }
+
+ void
+ x86_output_mi_thunk (file, delta, function)
+ FILE *file;
+ int delta;
+ 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[1] = gen_rtx_REG (DImode, x86_64_int_parameter_registers[n]);
+ output_asm_insn ("add{q} {%0, %1|%1, %0}", xops);
+ if (flag_pic)
+ {
+ fprintf (file, "\tjmp *");
+ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
+ fprintf (file, "@GOTPCREL(%%rip)\n");
+ }
+ else
+ {
+ fprintf (file, "\tjmp ");
+ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
+ fprintf (file, "\n");
+ }
+ }
+ 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);
+
+ if (flag_pic)
+ {
+ xops[0] = pic_offset_table_rtx;
+ xops[1] = gen_label_rtx ();
+ xops[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+
+ 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");
+ }
+ else
+ {
+ fprintf (file, "\tjmp ");
+ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
+ fprintf (file, "\n");
+ }
+ }
}
Index: unix.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/unix.h,v
retrieving revision 1.19
diff -c -3 -p -r1.19 unix.h
*** unix.h 21 Sep 2001 12:55:18 -0000 1.19
--- unix.h 14 May 2002 09:25:58 -0000
*************** Boston, MA 02111-1307, USA. */
*** 79,135 ****
/* 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) \
! do { \
! 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 (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); \
! \
! if (flag_pic && !TARGET_64BIT) \
! { \
! xops[0] = pic_offset_table_rtx; \
! xops[1] = gen_label_rtx (); \
! xops[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); \
! \
! 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"); \
! } \
! else if (flag_pic && TARGET_64BIT) \
! { \
! fprintf (FILE, "\tjmp *"); \
! assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
! fprintf (FILE, "@GOTPCREL(%%rip)\n"); \
! } \
! else \
! { \
! fprintf (FILE, "\tjmp "); \
! assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
! fprintf (FILE, "\n"); \
! } \
! } while (0)
--- 79,83 ----
/* 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);
More information about the Gcc-patches
mailing list