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