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 | 6 ++++ gcc/config/riscv/riscv.cc | 28 +++++++++++-------- gcc/config/riscv/riscv.h | 6 ++++ gcc/doc/md.texi | 7 +++++ .../gcc.target/riscv/constraint-cf-zfinx.c | 14 ++++++++++ .../gcc.target/riscv/constraint-cf.c | 14 ++++++++++ .../gcc.target/riscv/constraint-cr.c | 13 +++++++++ 7 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/constraint-cf-zfinx.c create mode 100644 gcc/testsuite/gcc.target/riscv/constraint-cf.c create mode 100644 gcc/testsuite/gcc.target/riscv/constraint-cr.c diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index af8186117db..2dce9832219 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -33,6 +33,12 @@ (define_register_constraint "j" "SIBCALL_REGS" (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 7860e5fbc23..db4de34f969 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 @@ static 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; return riscv_secondary_memory_needed (mode, from, to) ? 8 : 2; diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 09de74667a9..aacb557248f 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 f0b63a144ad..494a9e14c2a 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 00000000000..6745f85184c --- /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 00000000000..1dc204550bb --- /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 00000000000..692ae5753ae --- /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"); +} -- 2.34.1