The P8700 is a high-performance processor from MIPS by extending RISCV with the MIPS custom instruction and the following changes are added to enable the conditional move support from mips
No regressions are found for "runtest --tool gcc --target_board='riscv-sim/-mabi=lp64d/-mcmodel=medlow/-mtune=mips-p8700/-O2 ' riscv.exp" *config/riscv/riscv-cores.def(RISCV_CORE):Updated the march for mips-p8700 tune. *config/riscv/riscv-ext-mips.def(DEFINE_RISCV_EXT): New file added for mips conditional mov extension. *config/riscv/riscv-ext.def: Likewise. *config/riscv/t-riscv:Generates riscv-ext.opt *config/riscv/riscv-ext.opt: Generated file. *config/riscv/riscv.cc(riscv_expand_conditional_move):Updated for mips cmov. *config/riscv/riscv.md(mov<mode>cc):updated expand for MIPS CCMOV. *config/riscv/mips-insn.md:New file for mips-p8700 ccmov insn. *testsuite/gcc.target/riscv/mipscondmov.c:Test file for mips.ccmov insn. *gcc/doc/riscv-ext.texi:Updated for mips cmov. --- gcc/config/riscv/mips-insn.md | 37 ++++++++++++++++++++ gcc/config/riscv/riscv-cores.def | 2 +- gcc/config/riscv/riscv-ext-mips.def | 35 ++++++++++++++++++ gcc/config/riscv/riscv-ext.def | 1 + gcc/config/riscv/riscv-ext.opt | 5 +++ gcc/config/riscv/riscv.cc | 27 ++++++++++++-- gcc/config/riscv/riscv.md | 13 ++++++- gcc/config/riscv/t-riscv | 3 +- gcc/doc/riscv-ext.texi | 4 +++ gcc/testsuite/gcc.target/riscv/mipscondmov.c | 30 ++++++++++++++++ 10 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 gcc/config/riscv/mips-insn.md create mode 100644 gcc/config/riscv/riscv-ext-mips.def create mode 100644 gcc/testsuite/gcc.target/riscv/mipscondmov.c diff --git a/gcc/config/riscv/mips-insn.md b/gcc/config/riscv/mips-insn.md new file mode 100644 index 00000000000..ee106c4221e --- /dev/null +++ b/gcc/config/riscv/mips-insn.md @@ -0,0 +1,37 @@ +;; Machine description for MIPS custom instructioins. +;; Copyright (C) 2025 Free Software Foundation, Inc. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. + +(define_insn "*mov<GPR:mode><X:mode>cc_bitmanip" + [(set (match_operand:GPR 0 "register_operand" "=r") + (if_then_else:GPR + (match_operator 5 "equality_operator" + [(match_operand:X 1 "register_operand" "r") + (match_operand:X 2 "const_0_operand" "J")]) + (match_operand:GPR 3 "reg_or_0_operand" "rJ") + (match_operand:GPR 4 "reg_or_0_operand" "rJ")))] + "TARGET_XMIPSCMOV" +{ + enum rtx_code code = GET_CODE (operands[5]); + if (code == NE) + return "mips.ccmov\t%0,%1,%z3,%z4"; + else + return "mips.ccmov\t%0,%1,%z4,%z3"; +} + [(set_attr "type" "condmove") + (set_attr "mode" "<GPR:MODE>")]) diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def index 118fef23cad..b8bf81e7883 100644 --- a/gcc/config/riscv/riscv-cores.def +++ b/gcc/config/riscv/riscv-cores.def @@ -154,7 +154,7 @@ RISCV_CORE("xiangshan-nanhu", "rv64imafdc_zba_zbb_zbc_zbs_" "svinval_zicbom_zicboz", "xiangshan-nanhu") -RISCV_CORE("mips-p8700", "rv64imafd_zicsr_zmmul_" +RISCV_CORE("mips-p8700", "rv64imafd_" "zaamo_zalrsc_zba_zbb", "mips-p8700") #undef RISCV_CORE diff --git a/gcc/config/riscv/riscv-ext-mips.def b/gcc/config/riscv/riscv-ext-mips.def new file mode 100644 index 00000000000..86492223cb3 --- /dev/null +++ b/gcc/config/riscv/riscv-ext-mips.def @@ -0,0 +1,35 @@ +/* MIPS extension definition file for RISC-V. + Copyright (C) 2025 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + +Please run `make riscv-regen` in build folder to make sure updated anything. + +Format of DEFINE_RISCV_EXT, please refer to riscv-ext.def. */ + +DEFINE_RISCV_EXT( + /* NAME */ xmipscmov, + /* UPPERCAE_NAME */ XMIPSCMOV, + /* FULL_NAME */ "Mips conditional move extension", + /* DESC */ "", + /* URL */ , + /* DEP_EXTS */ ({}), + /* SUPPORTED_VERSIONS */ ({{1, 0}}), + /* FLAG_GROUP */ xmips, + /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED, + /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, + /* EXTRA_EXTENSION_FLAGS */ 0) diff --git a/gcc/config/riscv/riscv-ext.def b/gcc/config/riscv/riscv-ext.def index 97b576617ad..98f593f5c9e 100644 --- a/gcc/config/riscv/riscv-ext.def +++ b/gcc/config/riscv/riscv-ext.def @@ -1913,3 +1913,4 @@ DEFINE_RISCV_EXT( #include "riscv-ext-sifive.def" #include "riscv-ext-thead.def" #include "riscv-ext-ventana.def" +#include "riscv-ext-mips.def" diff --git a/gcc/config/riscv/riscv-ext.opt b/gcc/config/riscv/riscv-ext.opt index 9199aa31b42..145240be7bf 100644 --- a/gcc/config/riscv/riscv-ext.opt +++ b/gcc/config/riscv/riscv-ext.opt @@ -46,6 +46,9 @@ int riscv_sv_subext TargetVariable int riscv_xcv_subext +TargetVariable +int riscv_xmips_subext + TargetVariable int riscv_xsf_subext @@ -419,3 +422,5 @@ Mask(XTHEADVECTOR) Var(riscv_xthead_subext) Mask(XVENTANACONDOPS) Var(riscv_xventana_subext) +Mask(XMIPSCMOV) Var(riscv_xmips_subext) + diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index eaaca364983..e6020da8e27 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -4022,7 +4022,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN return false; case IF_THEN_ELSE: - if ((TARGET_SFB_ALU || TARGET_XTHEADCONDMOV) + if ((TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_XMIPSCMOV) && reg_or_0_operand (XEXP (x, 1), mode) && sfb_alu_operand (XEXP (x, 2), mode) && comparison_operator (XEXP (x, 0), VOIDmode)) @@ -5352,8 +5352,31 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt) rtx_code code = GET_CODE (op); rtx op0 = XEXP (op, 0); rtx op1 = XEXP (op, 1); + rtx target; - if (((TARGET_ZICOND_LIKE + if (TARGET_XMIPSCMOV && mode == word_mode && GET_MODE (op0) == word_mode) + { + if (code == EQ || code == NE) + { + op0 = riscv_zero_if_equal (op0, op1); + op1 = const0_rtx; + } + else + { + target = gen_reg_rtx (GET_MODE (op0)); + riscv_emit_int_order_test(code, 0, target, op0, op1); + op0 = target; + op1 = const0_rtx; + code = NE; + } + riscv_emit_int_compare (&code, &op0, &op1); + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest), + cond, cons, alt))); + return true; + } + + else if (((TARGET_ZICOND_LIKE || (arith_operand (cons, mode) && arith_operand (alt, mode))) && (GET_MODE_CLASS (mode) == MODE_INT)) || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 92fe7c7741a..0c25a723d9c 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3290,8 +3290,18 @@ (match_operand:GPR 2 "movcc_operand") (match_operand:GPR 3 "movcc_operand")))] "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND_LIKE - || TARGET_MOVCC" + || TARGET_MOVCC || TARGET_XMIPSCMOV" { + if (TARGET_XMIPSCMOV) { + /* operands[2] must be register or 0. */ + if (!reg_or_0_operand (operands[2], GET_MODE (operands[2]))) + operands[2] = force_reg (<GPR:MODE>mode, operands[2]); + + /* operands[3] must be register or 0. */ + if (!reg_or_0_operand (operands[3], GET_MODE (operands[3]))) + operands[3] = force_reg (<GPR:MODE>mode, operands[3]); + } + if (riscv_expand_conditional_move (operands[0], operands[1], operands[2], operands[3])) DONE; @@ -4857,3 +4867,4 @@ (include "corev.md") (include "xiangshan.md") (include "mips-p8700.md") +(include "mips-insn.md") diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv index 854daa96e73..a36d1a68fca 100644 --- a/gcc/config/riscv/t-riscv +++ b/gcc/config/riscv/t-riscv @@ -194,7 +194,8 @@ RISCV_EXT_DEFS = \ $(srcdir)/config/riscv/riscv-ext.def \ $(srcdir)/config/riscv/riscv-ext-sifive.def \ $(srcdir)/config/riscv/riscv-ext-thead.def \ - $(srcdir)/config/riscv/riscv-ext-ventana.def + $(srcdir)/config/riscv/riscv-ext-ventana.def \ + $(srcdir)/config/riscv/riscv-ext-mips.def $(srcdir)/config/riscv/riscv-ext.opt: $(RISCV_EXT_DEFS) diff --git a/gcc/doc/riscv-ext.texi b/gcc/doc/riscv-ext.texi index bd3d29c75ab..51eda797e32 100644 --- a/gcc/doc/riscv-ext.texi +++ b/gcc/doc/riscv-ext.texi @@ -662,4 +662,8 @@ @tab 1.0 @tab Ventana integer conditional operations extension +@item xmipscmov +@tab 1.0 +@tab Mips conditional move extension + @end multitable diff --git a/gcc/testsuite/gcc.target/riscv/mipscondmov.c b/gcc/testsuite/gcc.target/riscv/mipscondmov.c new file mode 100644 index 00000000000..144a6b718ef --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/mipscondmov.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64imafd_xmipscmov -mabi=lp64d" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +#define MYTEST(name, mytype) \ +mytype test1_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a == b) ? c : d; } \ +mytype test2_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a != b) ? c : d; } \ +mytype test3_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a > b) ? c : d; } \ +mytype test4_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a >= b) ? c : d; } \ +mytype test5_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a < b) ? c : d; } \ +mytype test6_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a <= b) ? c : d; } \ +mytype test7_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a == 1) ? c : d; } \ +mytype test8_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a != 1) ? c : d; } \ +mytype test9_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a > 1) ? c : d; } \ +mytype test10_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a >= 1) ? c : d; } \ +mytype test11_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a < 1) ? c : d; } \ +mytype test12_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a <= 1) ? c : d; } + +MYTEST(1, long long); +MYTEST(2, unsigned long long); +MYTEST(3, long); +MYTEST(4, unsigned long); +MYTEST(5, int); +MYTEST(6, unsigned int); +MYTEST(7, short); +MYTEST(8, unsigned short); +MYTEST(9, signed char); +MYTEST(10, unsigned char); + +/* { dg-final { scan-assembler-times "mips.ccmov" 120 } } */ base-commit: a91679a3d9f7cbc079880f201fd8292c1d54baa7 -- 2.43.0