===================================================================
@@ -742,13 +742,13 @@ mips*-*-linux*) # Linux MIPS, either
tmake_file="${tmake_file} t-crtfm"
# Check for MicroMIPS support.
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
===================================================================
@@ -479,14 +479,34 @@ 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. /*
+
/* 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
+
#ifdef L_m16retsf
RET_FUNCTION (__mips16_ret_sf, SF)
#endif
@@ -525,7 +545,7 @@ RET_FUNCTION (__mips16_ret_dc, DC)
pointer. They must copy the floating point arguments from the GPRs
to FPRs and then call function $2. */
-#define CALL_STUB_NO_RET(NAME, CODE) \
+#define _CALL_STUB_NO_RET(NAME, CODE) \
STARTFN (NAME); \
STUB_ARGS_##CODE; \
.set noreorder; \
@@ -534,6 +554,16 @@ STARTFN (NAME); \
.set reorder; \
ENDFN (NAME)
+#ifdef SHARED
+#define CALL_STUB_NO_RET(NAME, CODE) \
+ _CALL_STUB_NO_RET (NAME##_compat, CODE); \
+ .symver NAME##_compat, NAME##@GCC_4.4.0
+#else
+#define CALL_STUB_NO_RET(NAME, CODE) \
+ _CALL_STUB_NO_RET (NAME, CODE); \
+ .hidden NAME
+#endif
+
#ifdef L_m16stub1
CALL_STUB_NO_RET (__mips16_call_stub_1, 1)
#endif
@@ -574,7 +604,7 @@ CALL_STUB_NO_RET (__mips16_call_stub_10,
being called is 16 bits, in which case the copy is unnecessary;
however, it's faster to always do the copy. */
-#define CALL_STUB_RET(NAME, CODE, MODE) \
+#define _CALL_STUB_RET(NAME, CODE, MODE) \
STARTFN (NAME); \
.cfi_startproc; \
/* Create a fake CFA 4 bytes below the stack pointer. */ \
@@ -593,6 +623,16 @@ STARTFN (NAME); \
.cfi_endproc; \
ENDFN (NAME)
+#ifdef SHARED
+#define CALL_STUB_RET(NAME, CODE, MODE) \
+ _CALL_STUB_RET (NAME##_compat, CODE, MODE); \
+ .symver NAME##_compat, NAME##@GCC_4.4.0
+#else
+#define CALL_STUB_RET(NAME, CODE, MODE) \
+ _CALL_STUB_RET (NAME, CODE, MODE); \
+ .hidden NAME
+#endif
+
/* First, instantiate the single-float set. */
#ifdef L_m16stubsf0