aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2024-11-13 17:54:16 +0800
committerKito Cheng <kito.cheng@sifive.com>2024-12-17 22:28:04 +0800
commit46888571d242cf5623b7b0b74bb4490572f81cc9 (patch)
tree7744e29df4eb09a42d57c8601dd435665ea259f5 /gcc
parent1a2e0fcb857d82a7cb8909cf27a5dc833fecfa9a (diff)
downloadgcc-46888571d242cf5623b7b0b74bb4490572f81cc9.zip
gcc-46888571d242cf5623b7b0b74bb4490572f81cc9.tar.gz
gcc-46888571d242cf5623b7b0b74bb4490572f81cc9.tar.bz2
RISC-V: Add cr and cf constraint
gcc/ChangeLog: * config/riscv/constraints.md (cr): New. (cf): New. * config/riscv/riscv.h (reg_class): Add RVC_GR_REGS and RVC_FP_REGS. (REG_CLASS_NAMES): Ditto. (REG_CLASS_CONTENTS): Ditto. * doc/md.texi: Document cr and cf constraint. * config/riscv/riscv.cc (riscv_regno_to_class): Update FP_REGS to RVC_FP_REGS since it smaller set. (riscv_secondary_memory_needed): Handle RVC_FP_REGS. (riscv_register_move_cost): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/constraint-cf-zfinx.c: New. * gcc.target/riscv/constraint-cf.c: New. * gcc.target/riscv/constraint-cr.c: New.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/constraints.md6
-rw-r--r--gcc/config/riscv/riscv.cc28
-rw-r--r--gcc/config/riscv/riscv.h6
-rw-r--r--gcc/doc/md.texi7
-rw-r--r--gcc/testsuite/gcc.target/riscv/constraint-cf-zfinx.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/constraint-cf.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/constraint-cr.c13
7 files changed, 77 insertions, 11 deletions
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index af81861..2dce983 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -33,6 +33,12 @@
(define_register_constraint "l" "JALR_REGS"
"@internal")
+(define_register_constraint "cr" "RVC_GR_REGS"
+ "RVC general purpose register (x8-x15).")
+
+(define_register_constraint "cf" "TARGET_HARD_FLOAT ? RVC_FP_REGS : (TARGET_ZFINX ? RVC_GR_REGS : NO_REGS)"
+ "RVC floating-point registers (f8-f15), if available, reuse GPR as FPR when use zfinx.")
+
;; General constraints
(define_constraint "I"
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index aa8a456..6492913 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -350,14 +350,14 @@ const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = {
JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS,
JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS,
SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS,
- FP_REGS, FP_REGS, FP_REGS, FP_REGS,
- FP_REGS, FP_REGS, FP_REGS, FP_REGS,
- FP_REGS, FP_REGS, FP_REGS, FP_REGS,
- FP_REGS, FP_REGS, FP_REGS, FP_REGS,
- FP_REGS, FP_REGS, FP_REGS, FP_REGS,
- FP_REGS, FP_REGS, FP_REGS, FP_REGS,
- FP_REGS, FP_REGS, FP_REGS, FP_REGS,
- FP_REGS, FP_REGS, FP_REGS, FP_REGS,
+ RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS,
+ RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS,
+ RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS,
+ RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS,
+ RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS,
+ RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS,
+ RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS,
+ RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS, RVC_FP_REGS,
FRAME_REGS, FRAME_REGS, NO_REGS, NO_REGS,
NO_REGS, NO_REGS, NO_REGS, NO_REGS,
NO_REGS, NO_REGS, NO_REGS, NO_REGS,
@@ -9500,9 +9500,11 @@ static bool
riscv_secondary_memory_needed (machine_mode mode, reg_class_t class1,
reg_class_t class2)
{
+ bool class1_is_fpr = class1 == FP_REGS || class1 == RVC_FP_REGS;
+ bool class2_is_fpr = class2 == FP_REGS || class2 == RVC_FP_REGS;
return (!riscv_v_ext_mode_p (mode)
&& GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD
- && (class1 == FP_REGS) != (class2 == FP_REGS)
+ && (class1_is_fpr != class2_is_fpr)
&& !TARGET_XTHEADFMV
&& !TARGET_ZFA);
}
@@ -9513,8 +9515,12 @@ int
riscv_register_move_cost (machine_mode mode,
reg_class_t from, reg_class_t to)
{
- if ((from == FP_REGS && to == GR_REGS) ||
- (from == GR_REGS && to == FP_REGS))
+ bool from_is_fpr = from == FP_REGS || from == RVC_FP_REGS;
+ bool from_is_gpr = from == GR_REGS || from == RVC_GR_REGS;
+ bool to_is_fpr = to == FP_REGS || to == RVC_FP_REGS;
+ bool to_is_gpr = to == GR_REGS || to == RVC_GR_REGS;
+ if ((from_is_fpr && to == to_is_gpr) ||
+ (from_is_gpr && to_is_fpr))
return tune_param->fmv_cost;
if (from == V_REGS)
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 09de746..aacb557 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -504,8 +504,10 @@ enum reg_class
{
NO_REGS, /* no registers in set */
SIBCALL_REGS, /* registers used by indirect sibcalls */
+ RVC_GR_REGS, /* RVC general registers */
JALR_REGS, /* registers used by indirect calls */
GR_REGS, /* integer registers */
+ RVC_FP_REGS, /* RVC floating-point registers */
FP_REGS, /* floating-point registers */
FRAME_REGS, /* arg pointer and frame pointer */
VM_REGS, /* v0.t registers */
@@ -527,8 +529,10 @@ enum reg_class
{ \
"NO_REGS", \
"SIBCALL_REGS", \
+ "RVC_GR_REGS", \
"JALR_REGS", \
"GR_REGS", \
+ "RVC_FP_REGS", \
"FP_REGS", \
"FRAME_REGS", \
"VM_REGS", \
@@ -552,8 +556,10 @@ enum reg_class
{ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
{ 0xf003fcc0, 0x00000000, 0x00000000, 0x00000000 }, /* SIBCALL_REGS */ \
+ { 0x0000ff00, 0x00000000, 0x00000000, 0x00000000 }, /* RVC_GR_REGS */ \
{ 0xffffffc0, 0x00000000, 0x00000000, 0x00000000 }, /* JALR_REGS */ \
{ 0xffffffff, 0x00000000, 0x00000000, 0x00000000 }, /* GR_REGS */ \
+ { 0x00000000, 0x0000ff00, 0x00000000, 0x00000000 }, /* RVC_FP_REGS */ \
{ 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FP_REGS */ \
{ 0x00000000, 0x00000000, 0x00000003, 0x00000000 }, /* FRAME_REGS */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000001 }, /* V0_REGS */ \
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 523ce9b..d5e5367 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -3660,6 +3660,13 @@ A vector register, excluding v0 (if available).
@item vm
A vector register, only v0 (if available).
+@item cr
+RVC general purpose register (x8-x15).
+
+@item cf
+RVC floating-point registers (f8-f15), if available, reuse GPR as FPR when use
+zfinx.
+
@end table
@item RX---@file{config/rx/constraints.md}
diff --git a/gcc/testsuite/gcc.target/riscv/constraint-cf-zfinx.c b/gcc/testsuite/gcc.target/riscv/constraint-cf-zfinx.c
new file mode 100644
index 0000000..6745f85
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/constraint-cf-zfinx.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-options "-march=rv64i_zfinx -mabi=lp64" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+void foo(float a0, float a1, float a2, float a3, float a4, float a5, float a6, float a7, float m0, float m1) {
+/*
+** foo:
+** ...
+** fadd.s\s*t0,\s*(a[0-5]|s[0-1]),\s*(a[0-5]|s[0-1])
+** ...
+*/
+ __asm__ volatile("fadd.s t0, %0, %0" : : "cf" (m0));
+}
diff --git a/gcc/testsuite/gcc.target/riscv/constraint-cf.c b/gcc/testsuite/gcc.target/riscv/constraint-cf.c
new file mode 100644
index 0000000..1dc2045
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/constraint-cf.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-options "-march=rv64if -mabi=lp64" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+void foo(float a0, float a1, float a2, float a3, float a4, float a5, float a6, float a7, float m0, float m1) {
+/*
+** foo:
+** ...
+** fadd.s\s*ft0,\s*f(a[0-5]|s[0-1]),\s*f(a[0-5]|s[0-1])
+** ...
+*/
+ __asm__ volatile("fadd.s ft0, %0, %0" : : "cf" (m0));
+}
diff --git a/gcc/testsuite/gcc.target/riscv/constraint-cr.c b/gcc/testsuite/gcc.target/riscv/constraint-cr.c
new file mode 100644
index 0000000..692ae57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/constraint-cr.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+void foo(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int m0, int m1) {
+/*
+** foo:
+** ...
+** addi\s*t0,\s*(a[0-5]|s[0-1]),\s*(a[0-5]|s[0-1])
+** ...
+*/
+ __asm__ volatile("addi t0, %0, %0" : : "cr" (m0) : "memory");
+}