MIPS/libgcc: Avoid the PLT in MIPS16 stub calls
diff mbox

Message ID alpine.DEB.1.10.1308162255350.8514@tp.orcam.me.uk
State Accepted
Headers show

Commit Message

Maciej W. Rozycki Aug. 16, 2013, 10:23 p.m. UTC
On Wed, 7 Aug 2013, Richard Sandiford wrote:

> >  /* Define a function NAME that moves a return value of mode MODE from
> >     FPRs to GPRs.  */
> >  
> > -#define RET_FUNCTION(NAME, MODE)	\
> > +#define _RET_FUNCTION(NAME, MODE)	\
> >  STARTFN (NAME);				\
> >  	MOVE_##MODE##_RET (t, $31);	\
> >  	ENDFN (NAME)
> >  
> > +#ifdef SHARED
> > +#define RET_FUNCTION(NAME, MODE)		\
> > +	_RET_FUNCTION (NAME##_compat, MODE);	\
> > +	.symver	NAME##_compat, NAME##@GCC_4.4.0
> > +#else
> > +#define RET_FUNCTION(NAME, MODE)		\
> > +	_RET_FUNCTION (NAME, MODE);		\
> > +	.hidden	NAME
> > +#endif
> 
> Rather than repeat this, I think we should have:
> 
> #ifdef SHARED
> #define CE_STARTFN(NAME) \
>   STARTFN (NAME##_compat); \
>   .symver NAME##_compat, NAME@GCC_4.4.0
> #define CE_ENDFN(NAME) ENDFN (NAME##_compat)
> #else
> #define CE_STARTFN(NAME) STARTFN (NAME); .hidden NAME
> #define CE_ENDFN(NAME) ENDFN (NAME)
> #endif
> 
> below your new comment, with CE arbitrarily standing for "compat export".

 Indeed, clever.  I was wondering if it was possible to avoid the 
repetition, but missed the ability to reuse STARTFN/ENDFN for this 
purpose.

> Feel free to use different names if you can think of something better.

 I think yours are as good as any other ones might be.

> Note no "##" before "@".

 Indeed, the versioned symbol alias is not a valid preprocessor token.

> Please also delete the corresponding entries in libgcc.ver, which should
> no longer be needed.

 Done, thanks for pointing it out.

> OK with those changes, thanks.  No need for a full retest; checking
> that libgcc_s.so.1 and libgcc.a are unchanged from your posted version
> should be fine.

 No differences found.  Here's what I applied (note that I decided to keep 
the formatting style consistent between the two CE_STARTFN variants).

2013-08-16  Maciej W. Rozycki  <macro@codesourcery.com>
            Catherine Moore  <clm@codesourcery.com>
            Richard Sandiford <rdsandiford@googlemail.com>
        
	libgcc/
	* config/mips/mips16.S (CE_STARTFN, CE_ENDFN): New macros.
	(RET_FUNCTION): Use them in place of STARTFN and ENDFN.
	(CALL_STUB_NO_RET): Likewise.
	(CALL_STUB_RET): Likewise.
	* config/mips/libgcc-mips16.ver: Remove __mips16_call_stub and
	__mips16_ret call/return stub symbols.
	* config.host <mips*-*-linux>: For non-R5900 add t-slibgcc-libgcc
	to tmake_file.

  Maciej

gcc-mips16-hidden-stub.diff

Patch
diff mbox

Index: gcc-fsf-trunk-quilt/libgcc/config.host
===================================================================
--- gcc-fsf-trunk-quilt.orig/libgcc/config.host	2013-08-16 20:19:15.000000000 +0100
+++ gcc-fsf-trunk-quilt/libgcc/config.host	2013-08-16 20:21:23.568799943 +0100
@@ -741,13 +741,13 @@  mips*-*-linux*)				# Linux MIPS, either 
 	extra_parts="$extra_parts crtfastmath.o"
 	tmake_file="${tmake_file} t-crtfm"
 	case ${host} in
-		mips64r5900* | mipsr5900*)
-			# The MIPS16 support code uses floating point
-			# instructions that are not supported on r5900.
-			;;
-		*)
-			tmake_file="${tmake_file} mips/t-mips16"
-			;;
+	  mips64r5900* | mipsr5900*)
+	    # The MIPS16 support code uses floating point
+	    # instructions that are not supported on r5900.
+	    ;;
+	  *)
+	    tmake_file="${tmake_file} mips/t-mips16 t-slibgcc-libgcc"
+	    ;;
 	esac
 	md_unwind_header=mips/linux-unwind.h
 	if test "${ac_cv_sizeof_long_double}" = 16; then
Index: gcc-fsf-trunk-quilt/libgcc/config/mips/libgcc-mips16.ver
===================================================================
--- gcc-fsf-trunk-quilt.orig/libgcc/config/mips/libgcc-mips16.ver	2013-08-16 22:41:01.000000000 +0100
+++ gcc-fsf-trunk-quilt/libgcc/config/mips/libgcc-mips16.ver	2013-08-16 22:41:09.617705885 +0100
@@ -45,42 +45,4 @@  GCC_4.4.0 {
   __mips16_floatsidf
   __mips16_floatunsidf
   __mips16_fix_truncdfsi
-  __mips16_ret_sf
-  __mips16_ret_sc
-  __mips16_ret_df
-  __mips16_ret_dc
-  __mips16_call_stub_1
-  __mips16_call_stub_5
-  __mips16_call_stub_2
-  __mips16_call_stub_6
-  __mips16_call_stub_9
-  __mips16_call_stub_10
-  __mips16_call_stub_sf_0
-  __mips16_call_stub_sf_1
-  __mips16_call_stub_sf_5
-  __mips16_call_stub_sf_2
-  __mips16_call_stub_sf_6
-  __mips16_call_stub_sf_9
-  __mips16_call_stub_sf_10
-  __mips16_call_stub_sc_0
-  __mips16_call_stub_sc_1
-  __mips16_call_stub_sc_5
-  __mips16_call_stub_sc_2
-  __mips16_call_stub_sc_6
-  __mips16_call_stub_sc_9
-  __mips16_call_stub_sc_10
-  __mips16_call_stub_df_0
-  __mips16_call_stub_df_1
-  __mips16_call_stub_df_5
-  __mips16_call_stub_df_2
-  __mips16_call_stub_df_6
-  __mips16_call_stub_df_9
-  __mips16_call_stub_df_10
-  __mips16_call_stub_dc_0
-  __mips16_call_stub_dc_1
-  __mips16_call_stub_dc_5
-  __mips16_call_stub_dc_2
-  __mips16_call_stub_dc_6
-  __mips16_call_stub_dc_9
-  __mips16_call_stub_dc_10
 }
Index: gcc-fsf-trunk-quilt/libgcc/config/mips/mips16.S
===================================================================
--- gcc-fsf-trunk-quilt.orig/libgcc/config/mips/mips16.S	2013-08-16 20:06:14.000000000 +0100
+++ gcc-fsf-trunk-quilt/libgcc/config/mips/mips16.S	2013-08-16 20:21:23.568799943 +0100
@@ -479,13 +479,35 @@  STARTFN (__mips16_fix_truncdfsi)
 #endif
 #endif /* !__mips_single_float */
 
+/* We don't export stubs from libgcc_s.so and always require static
+   versions to be pulled from libgcc.a as needed because they use $2
+   and possibly $3 as arguments, diverging from the standard SysV ABI,
+   and as such would require severe pessimisation of MIPS16 PLT entries
+   just for this single special case.
+
+   For compatibility with old binaries that used safe standard MIPS PLT
+   entries and referred to these functions we still export them at
+   version GCC_4.4.0 for run-time loading only.  */
+
+#ifdef SHARED
+#define CE_STARTFN(NAME)			\
+STARTFN (NAME##_compat);			\
+	.symver NAME##_compat, NAME@GCC_4.4.0
+#define CE_ENDFN(NAME) ENDFN (NAME##_compat)
+#else
+#define CE_STARTFN(NAME)			\
+STARTFN (NAME);					\
+	.hidden NAME
+#define CE_ENDFN(NAME) ENDFN (NAME)
+#endif
+
 /* Define a function NAME that moves a return value of mode MODE from
    FPRs to GPRs.  */
 
 #define RET_FUNCTION(NAME, MODE)	\
-STARTFN (NAME);				\
+CE_STARTFN (NAME);			\
 	MOVE_##MODE##_RET (t, $31);	\
-	ENDFN (NAME)
+	CE_ENDFN (NAME)
 
 #ifdef L_m16retsf
 RET_FUNCTION (__mips16_ret_sf, SF)
@@ -526,13 +548,13 @@  RET_FUNCTION (__mips16_ret_dc, DC)
    to FPRs and then call function $2.  */
 
 #define CALL_STUB_NO_RET(NAME, CODE)	\
-STARTFN (NAME);				\
+CE_STARTFN (NAME);			\
 	STUB_ARGS_##CODE;		\
 	.set	noreorder;		\
 	jr	$2;			\
 	move	$25,$2;			\
 	.set	reorder;		\
-	ENDFN (NAME)
+	CE_ENDFN (NAME)
 
 #ifdef L_m16stub1
 CALL_STUB_NO_RET (__mips16_call_stub_1, 1)
@@ -575,7 +597,7 @@  CALL_STUB_NO_RET (__mips16_call_stub_10,
    however, it's faster to always do the copy.  */
 
 #define CALL_STUB_RET(NAME, CODE, MODE)					\
-STARTFN (NAME);								\
+CE_STARTFN (NAME);							\
 	.cfi_startproc;							\
 	/* Create a fake CFA 4 bytes below the stack pointer.  */	\
 	.cfi_def_cfa 29,-4;						\
@@ -591,7 +613,7 @@  STARTFN (NAME);								\
 	.set	reorder;						\
 	MOVE_##MODE##_RET (f, $18);					\
 	.cfi_endproc;							\
-	ENDFN (NAME)
+	CE_ENDFN (NAME)
 
 /* First, instantiate the single-float set.  */