__builtin_apply* and __builtin_return accesses the floating point registers on SPARC even when compiling with -msoft-float.
gcc/ChangeLog: 2015-06-26 Daniel Cederman <ceder...@gaisler.com> * config/sparc/sparc.c (sparc_function_value_regno_p): Floating point registers cannot be used when compiling for a target without FPU. * config/sparc/sparc.md: A function cannot return a value in a floating point register when compiled without floating point support. --- gcc/config/sparc/sparc.c | 2 +- gcc/config/sparc/sparc.md | 26 ++++++++++++++++---------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 2556eec..e0d40a5 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -7403,7 +7403,7 @@ sparc_libcall_value (machine_mode mode, static bool sparc_function_value_regno_p (const unsigned int regno) { - return (regno == 8 || regno == 32); + return (regno == 8 || (TARGET_FPU && regno == 32)); } /* Do what is necessary for `va_start'. We look at the current function diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index a561877..c296913 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -6398,7 +6398,6 @@ "" { rtx valreg1 = gen_rtx_REG (DImode, 8); - rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32); rtx result = operands[1]; /* Pass constm1 to indicate that it may expect a structure value, but @@ -6407,8 +6406,12 @@ /* Save the function value registers. */ emit_move_insn (adjust_address (result, DImode, 0), valreg1); - emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8), - valreg2); + if (TARGET_FPU) + { + rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32); + emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8), + valreg2); + } /* The optimizer does not know that the call sets the function value registers we stored in the result block. We avoid problems by @@ -6620,7 +6623,6 @@ "" { rtx valreg1 = gen_rtx_REG (DImode, 24); - rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32); rtx result = operands[0]; if (! TARGET_ARCH64) @@ -6637,14 +6639,18 @@ emit_insn (gen_update_return (rtnreg, value)); } - /* Reload the function value registers. */ + /* Reload the function value registers. + Put USE insns before the return. */ emit_move_insn (valreg1, adjust_address (result, DImode, 0)); - emit_move_insn (valreg2, - adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8)); - - /* Put USE insns before the return. */ emit_use (valreg1); - emit_use (valreg2); + + if ( TARGET_FPU ) + { + rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32); + emit_move_insn (valreg2, + adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8)); + emit_use (valreg2); + } /* Construct the return. */ expand_naked_return (); -- 2.4.3