aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2015-12-10 02:53:28 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2015-12-10 03:06:15 -0800
commit99d308218f152f0a454ee2fc2eec42a7dd371ba9 (patch)
tree353be29e702b3e6af3003f6832302896a4776703 /gcc
parent65f3edba70f149f191c78f226df0ef0ad3ae82ea (diff)
downloadriscv-gnu-toolchain-99d308218f152f0a454ee2fc2eec42a7dd371ba9.zip
riscv-gnu-toolchain-99d308218f152f0a454ee2fc2eec42a7dd371ba9.tar.gz
riscv-gnu-toolchain-99d308218f152f0a454ee2fc2eec42a7dd371ba9.tar.bz2
gcc: "Fix" RV32D integer <> fp moves (#98)
We have no pattern for moving between a double-precision floating-point register and an integer register in RV32. This makes the compiler choke. This workaround raises the cost of those moves significantly. This has no effect on -O0, which always worked; the other -Ox all seem to work now. For obvious reasons, this makes me very uncomfortable. But, as far as I can tell, MIPS is relying on the same behavior. If this bug rears its head again, no big deal: we can add an "instruction" for this, which does something like addi sp, sp, -16 fsd f4, 0(sp) lw x6, 0(sp) lw x7, 4(sp) addi sp, sp, 16 This is heinous, but it's always correct. If the cost model is right, the compiler will only very rarely invoke it, so the performance cost of this ingorious hack will be hidden. @palmer-dabbelt
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gcc/config/riscv/riscv.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/gcc/gcc/config/riscv/riscv.c b/gcc/gcc/config/riscv/riscv.c
index 979ee8f..d8587fc 100644
--- a/gcc/gcc/config/riscv/riscv.c
+++ b/gcc/gcc/config/riscv/riscv.c
@@ -3563,6 +3563,15 @@ riscv_can_use_return_insn (void)
return reload_completed && cfun->machine->frame.total_size == 0;
}
+/* Implement TARGET_REGISTER_MOVE_COST. */
+
+static int
+riscv_register_move_cost (enum machine_mode mode,
+ reg_class_t from, reg_class_t to)
+{
+ return SECONDARY_MEMORY_NEEDED (from, to, mode) ? 8 : 2;
+}
+
/* Return true if register REGNO can store a value of mode MODE.
The result of this function is cached in riscv_hard_regno_mode_ok. */
@@ -4294,6 +4303,8 @@ riscv_lra_p (void)
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall
+#undef TARGET_REGISTER_MOVE_COST
+#define TARGET_REGISTER_MOVE_COST riscv_register_move_cost
#undef TARGET_MEMORY_MOVE_COST
#define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost
#undef TARGET_RTX_COSTS