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 <ma...@codesourcery.com> Catherine Moore <c...@codesourcery.com> Richard Sandiford <rdsandif...@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. */