[PATCH] MIPS/libgcc: Avoid the PLT in MIPS16 stub calls
Maciej W. Rozycki
macro@codesourcery.com
Fri Aug 16 22:30:00 GMT 2013
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
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. */
More information about the Gcc-patches
mailing list