]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add cr and cf constraint
authorKito Cheng <kito.cheng@sifive.com>
Wed, 13 Nov 2024 09:54:16 +0000 (17:54 +0800)
committerKito Cheng <kito.cheng@sifive.com>
Tue, 17 Dec 2024 14:28:04 +0000 (22:28 +0800)
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.

gcc/config/riscv/constraints.md
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.h
gcc/doc/md.texi
gcc/testsuite/gcc.target/riscv/constraint-cf-zfinx.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/constraint-cf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/constraint-cr.c [new file with mode: 0644]

index af8186117dbd76217d3a067c545827d23bf2e319..2dce9832219b9193a75145c2569a0603a3168d58 100644 (file)
 (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"
index aa8a4562d9af6fda3b35c0a4eb0a5795c94d2fd2..6492913d8f8062fb43eb17baa977ad38ac432ea1 100644 (file)
@@ -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)
index 09de74667a901ac0fcf964a85d034fbb8519816a..aacb557248f982c049f0e46e3e9346f2bee2d8e0 100644 (file)
@@ -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 */           \
index 523ce9bce17e777c55aae85433682cdfd3ebeea1..d5e5367e4efe31727aa08d0a8c638090a7f909ca 100644 (file)
@@ -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 (file)
index 0000000..6745f85
--- /dev/null
@@ -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 (file)
index 0000000..1dc2045
--- /dev/null
@@ -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 (file)
index 0000000..692ae57
--- /dev/null
@@ -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");
+}