RISC-V: Mark fsX as call clobbered when soft-float.

Message ID 20180117190753.22987-1-jimw@sifive.com
State New
Headers show
  • RISC-V: Mark fsX as call clobbered when soft-float.
Related show

Commit Message

Jim Wilson Jan. 17, 2018, 7:07 p.m.
We support architecture/ABI combinations where the ABI uses smaller FP sizes
than the hardware supports.  To avoid corruption of the call-saved FP
registers, fs0 through fs11, we only allow values in them that are smaller or
equal in size to the ABI FP size.  This means that for soft-float, we never
allow any value in these registers.  This restriction is implemented in
riscv_hard_regno_mode_ok.  This was confirmed by cross compiling SPEC CPU2006
for rv32gc/ilp32 and disassembling.  The only uses of the fsX registers are
in Unwind_* routines that are saving/restore every call saved register.

This patch allows us to use the fsX register for soft-float code by marking
them as call clobbered.  This is already specified in the ABI documents, and
this patch just changes the compiler to match the ABI.  With this patch, I am
seeing fsX registers used in the SPEC compile, and smaller frame sizes due to
better register allocation.  There is no ABI change, because we were not using
these registers at all before the patch.

Tested with a rv32gc/ilp32 make check.  There were no regressions.



	2018-01-17  Andrew Waterman  <andrew@sifive.com>
	* config/riscv/riscv.c (riscv_conditional_register_usage): If
	UNITS_PER_FP_ARG is 0, set call_used_regs to 1 for all FP regs.
 gcc/config/riscv/riscv.c | 7 +++++++
 1 file changed, 7 insertions(+)



diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 19a01e0825a..20660a4061a 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -4123,6 +4123,13 @@  riscv_conditional_register_usage (void)
       for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
 	fixed_regs[regno] = call_used_regs[regno] = 1;
+  /* In the soft-float ABI, there are no callee-saved FP registers.  */
+  if (UNITS_PER_FP_ARG == 0)
+    {
+      for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
+	call_used_regs[regno] = 1;
+    }
 /* Return a register priority for hard reg REGNO.  */