Hi Jeff and Marco, Please pass your comments on the below changes and do needful.
Thank you ~U On Sun, Jul 6, 2025 at 12:56 PM Umesh Kalappa <ukalappa.m...@gmail.com> wrote: > Hi @Jeff Law <jeffreya...@gmail.com> and @ma...@orcam.me.uk > <ma...@orcam.me.uk> , > > Please have a look at the updated patch for conditional move support and > any comments or suggestions please let us know ? > > Thank you > ~U > > On Wed, Jul 2, 2025 at 12:46 PM Umesh Kalappa <ukalappa.m...@gmail.com> > wrote: > >> Indentation are updated accordingly and no regress found. >> >> gcc/ChangeLog: >> >> *config/riscv/riscv-cores.def(RISCV_CORE): Updated the supported >> march. >> *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 >> and outlined some code that handle arch cond move. >> *config/riscv/riscv.md(mov<mode>cc): updated expand for MIPS >> CCMOV. >> *config/riscv/mips-insn.md: New file for mips-p8700 ccmov insn. >> *gcc/doc/riscv-ext.texi: Updated for mips cmov. >> >> gcc/testsuite/ChangeLog: >> >> *testsuite/gcc.target/riscv/mipscondmov.c: Test file for >> mips.ccmov insn. >> --- >> gcc/config/riscv/mips-insn.md | 36 +++++++ >> gcc/config/riscv/riscv-cores.def | 3 +- >> gcc/config/riscv/riscv-ext-mips.def | 35 ++++++ >> gcc/config/riscv/riscv-ext.def | 1 + >> gcc/config/riscv/riscv-ext.opt | 4 + >> gcc/config/riscv/riscv.cc | 107 +++++++++++++------ >> gcc/config/riscv/riscv.md | 3 +- >> gcc/config/riscv/t-riscv | 3 +- >> gcc/doc/riscv-ext.texi | 4 + >> gcc/testsuite/gcc.target/riscv/mipscondmov.c | 30 ++++++ >> 10 files changed, 189 insertions(+), 37 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..de53638d587 >> --- /dev/null >> +++ b/gcc/config/riscv/mips-insn.md >> @@ -0,0 +1,36 @@ >> +;; Machine description for MIPS custom instructions. >> +;; 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 >> + (any_eq:X (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 = <CODE>; >> + 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 2096c0095d4..98f347034fb 100644 >> --- a/gcc/config/riscv/riscv-cores.def >> +++ b/gcc/config/riscv/riscv-cores.def >> @@ -169,7 +169,6 @@ RISCV_CORE("xiangshan-kunminghu", >> "rv64imafdcbvh_sdtrig_sha_shcounterenw_" >> "zvfhmin_zvkt_zvl128b_zvl32b_zvl64b", >> "xiangshan-kunminghu") >> >> -RISCV_CORE("mips-p8700", "rv64imafd_zicsr_zmmul_" >> - "zaamo_zalrsc_zba_zbb", >> +RISCV_CORE("mips-p8700", "rv64imfd_zicsr_zifencei_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..f24507139f6 >> --- /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, >> + /* UPPERCASE_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 816acaa34f4..6fc6d388635 100644 >> --- a/gcc/config/riscv/riscv-ext.def >> +++ b/gcc/config/riscv/riscv-ext.def >> @@ -2082,3 +2082,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 9f8c5451d49..26d6e683acd 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 >> >> @@ -445,3 +448,4 @@ 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 bbc7547d385..fa94bb2948a 100644 >> --- a/gcc/config/riscv/riscv.cc >> +++ b/gcc/config/riscv/riscv.cc >> @@ -87,6 +87,10 @@ along with GCC; see the file COPYING3. If not see >> #include "riscv-vector-costs.h" >> #include "riscv-subset.h" >> >> +/* Target variants that support full conditional move. */ >> +#define TARGET_COND_MOV \ >> + (TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_XMIPSCMOV) >> + >> /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */ >> #define UNSPEC_ADDRESS_P(X) \ >> (GET_CODE (X) == UNSPEC \ >> @@ -4150,7 +4154,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_COND_MOV >> && reg_or_0_operand (XEXP (x, 1), mode) >> && sfb_alu_operand (XEXP (x, 2), mode) >> && comparison_operator (XEXP (x, 0), VOIDmode)) >> @@ -5468,6 +5472,68 @@ riscv_expand_conditional_branch (rtx label, >> rtx_code code, rtx op0, rtx op1) >> emit_jump_insn (gen_condjump (condition, label)); >> } >> >> +/* canonicalization of the comparands. */ >> +void >> +canonicalize_comparands (rtx_code code, rtx *op0, rtx *op1) >> +{ >> + /* An integer comparison must be comparing WORD_MODE objects. >> + Extend the comparison arguments as necessary. */ >> + if ((INTEGRAL_MODE_P (GET_MODE (*op0)) && GET_MODE (*op0) != word_mode) >> + || (INTEGRAL_MODE_P (GET_MODE (*op1)) && GET_MODE (*op1) != >> word_mode)) >> + riscv_extend_comparands (code, op0, op1); >> + >> + /* We might have been handed back a SUBREG. Just to make things >> + easy, force it into a REG. */ >> + if (!REG_P (*op0) && !CONST_INT_P (*op0)) >> + *op0 = force_reg (word_mode, *op0); >> + if (!REG_P (*op1) && !CONST_INT_P (*op1)) >> + *op1 = force_reg (word_mode, *op1); >> +} >> + >> +/* Emit target specific conditional move like TARGET_XMIPSCMOV etc. */ >> +bool >> +riscv_target_conditional_move (rtx dest, rtx op0, rtx op1, rtx_code code, >> + rtx cons, rtx alt) >> +{ >> + machine_mode dst_mode = GET_MODE (dest); >> + rtx target; >> + >> + /* force the operands to the register. */ >> + cons = force_reg (dst_mode, cons); >> + alt = force_reg (dst_mode, alt); >> + >> + if (TARGET_XMIPSCMOV) >> + { >> + 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 (dst_mode, >> + cond, cons, >> alt))); >> + return true; >> + } >> + /* TARGET_SFB_ALU || TARGET_XTHEADCONDMOV. */ >> + else >> + { >> + riscv_emit_int_compare (&code, &op0, &op1, !TARGET_SFB_ALU); >> + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); >> + emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (dst_mode, cond, >> + cons, alt))); >> + return true; >> + } >> +} >> + >> /* Emit a cond move: If OP holds, move CONS to DEST; else move ALT to >> DEST. >> Return 0 if expansion failed. */ >> >> @@ -5520,34 +5586,22 @@ riscv_expand_conditional_move (rtx dest, rtx op, >> rtx cons, rtx alt) >> /* If we need more special cases, add them here. */ >> } >> >> + >> if (((TARGET_ZICOND_LIKE >> || (arith_operand (cons, dst_mode) && arith_operand (alt, >> dst_mode))) >> && GET_MODE_CLASS (dst_mode) == MODE_INT >> && GET_MODE_CLASS (cond_mode) == MODE_INT) >> - || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV) >> + || TARGET_COND_MOV) >> { >> machine_mode mode0 = GET_MODE (op0); >> - machine_mode mode1 = GET_MODE (op1); >> >> - /* An integer comparison must be comparing WORD_MODE objects. >> - Extend the comparison arguments as necessary. */ >> - if ((INTEGRAL_MODE_P (mode0) && mode0 != word_mode) >> - || (INTEGRAL_MODE_P (mode1) && mode1 != word_mode)) >> - riscv_extend_comparands (code, &op0, &op1); >> - >> - /* We might have been handed back a SUBREG. Just to make things >> - easy, force it into a REG. */ >> - if (!REG_P (op0) && !CONST_INT_P (op0)) >> - op0 = force_reg (word_mode, op0); >> - if (!REG_P (op1) && !CONST_INT_P (op1)) >> - op1 = force_reg (word_mode, op1); >> + canonicalize_comparands (code,&op0,&op1); >> >> /* In the fallback generic case use DST_MODE rather than WORD_MODE >> for the output of the SCC instruction, to match the mode of the >> NEG >> operation below. The output of SCC is 0 or 1 boolean, so it is >> valid for input in any scalar integer mode. */ >> - rtx tmp = gen_reg_rtx ((TARGET_ZICOND_LIKE >> - || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV) >> + rtx tmp = gen_reg_rtx ((TARGET_ZICOND_LIKE || TARGET_COND_MOV) >> ? word_mode : dst_mode); >> bool invert = false; >> >> @@ -5584,25 +5638,12 @@ riscv_expand_conditional_move (rtx dest, rtx op, >> rtx cons, rtx alt) >> op0 = XEXP (op, 0); >> op1 = XEXP (op, 1); >> } >> - else if (!TARGET_ZICOND_LIKE && !TARGET_SFB_ALU && >> !TARGET_XTHEADCONDMOV) >> + else if (!TARGET_ZICOND_LIKE && !TARGET_COND_MOV) >> riscv_expand_int_scc (tmp, code, op0, op1, &invert); >> >> - if (TARGET_SFB_ALU || TARGET_XTHEADCONDMOV) >> - { >> - riscv_emit_int_compare (&code, &op0, &op1, !TARGET_SFB_ALU); >> - rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); >> + if (TARGET_COND_MOV) >> + return riscv_target_conditional_move (dest, op0, op1, code, cons, >> alt); >> >> - /* The expander is a bit loose in its specification of the true >> - arm of the conditional move. That allows us to support more >> - cases for extensions which are more general than SFB. But >> - does mean we need to force CONS into a register at this >> point. */ >> - cons = force_reg (dst_mode, cons); >> - /* With XTheadCondMov we need to force ALT into a register >> too. */ >> - alt = force_reg (dst_mode, alt); >> - emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (dst_mode, >> cond, >> - cons, >> alt))); >> - return true; >> - } >> else if (!TARGET_ZICOND_LIKE) >> { >> if (invert) >> diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md >> index 893c925b6b9..8500cac98d9 100644 >> --- a/gcc/config/riscv/riscv.md >> +++ b/gcc/config/riscv/riscv.md >> @@ -3298,7 +3298,7 @@ >> (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 (riscv_expand_conditional_move (operands[0], operands[1], >> operands[2], operands[3])) >> @@ -4886,3 +4886,4 @@ >> (include "sifive-p600.md") >> (include "generic-vector-ooo.md") >> (include "generic-ooo.md") >> +(include "mips-insn.md") >> diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv >> index 32092d85687..7aac56ac86c 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 c3ed1bfb593..572b70e20fa 100644 >> --- a/gcc/doc/riscv-ext.texi >> +++ b/gcc/doc/riscv-ext.texi >> @@ -714,4 +714,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: 2609a7a5971aa8a2ef1bafbf5581dcabd68a466e >> -- >> 2.43.0 >> >>