This patch adds support for the XAndesperf ISA extension. The 32-bit AndeStar V5 extension includes branch instructions, load effective address instructions, and string processing instructions for performance improvement. New INSN patterns are added into the new file andes.md as a seprated vender extension.
gcc/ChangeLog: * config/riscv/constraints.md (Ou07): New constraint. (ads_Bext): New constraint. * config/riscv/iterators.md (ANYLE32): New iterator. (sizen): New iterator. (sh_limit): New iterator. (sh_bit): New iterator. (cs): New iterator. * config/riscv/predicates.md (ads_branch_bbcs_operand): New predicate. (ads_branch_bimm_operand): New predicate. (ads_imm_extract_operand): New predicate. (ads_extract_size_imm_si): New predicate. (ads_extract_size_imm_di): New predicate. (const_int5_operand): New predicate. * config/riscv/riscv-builtins.cc: Add new AVAIL andesperf32 and andesperf64. Add new define RISCV_ATYPE_DI. * config/riscv/riscv-ftypes.def: New DEF_RISCV_FTYPE. * config/riscv/riscv.cc (riscv_extend_cost): Cost for pattern 'bfo'. (riscv_rtx_costs): Cost for XAndesperf extension. * config/riscv/riscv.md: Add support for XAndesperf to patterns zero_extendsidi2_internal, zero_extendhi2, extendsidi2_internal, extend<SHORT:mode><SUPERQI:mode>2, <any_extract:optab><GPR:mode>3 and branch_on_bit. * config/riscv/vector-iterators.md (sz): Add sign_extract and zero_extract. * config/riscv/andes.def: New file for vender Andes. * config/riscv/andes.md: New file for vender Andes. gcc/testsuite/ChangeLog: * gcc.target/riscv/riscv.exp: Add runtest for subdir xandes. * gcc.target/riscv/xandes/xandesperf-1.c: New test. * gcc.target/riscv/xandes/xandesperf-10.c: New test. * gcc.target/riscv/xandes/xandesperf-2.c: New test. * gcc.target/riscv/xandes/xandesperf-3.c: New test. * gcc.target/riscv/xandes/xandesperf-4.c: New test. * gcc.target/riscv/xandes/xandesperf-5.c: New test. * gcc.target/riscv/xandes/xandesperf-6.c: New test. * gcc.target/riscv/xandes/xandesperf-7.c: New test. * gcc.target/riscv/xandes/xandesperf-8.c: New test. * gcc.target/riscv/xandes/xandesperf-9.c: New test. --- gcc/config/riscv/andes.def | 10 + gcc/config/riscv/andes.md | 429 ++++++++++++++++++ gcc/config/riscv/constraints.md | 10 + gcc/config/riscv/iterators.md | 15 + gcc/config/riscv/predicates.md | 42 ++ gcc/config/riscv/riscv-builtins.cc | 6 + gcc/config/riscv/riscv-ftypes.def | 1 + gcc/config/riscv/riscv.cc | 32 ++ gcc/config/riscv/riscv.md | 17 +- gcc/config/riscv/vector-iterators.md | 2 +- gcc/testsuite/gcc.target/riscv/riscv.exp | 2 + .../gcc.target/riscv/xandes/xandesperf-1.c | 13 + .../gcc.target/riscv/xandes/xandesperf-10.c | 32 ++ .../gcc.target/riscv/xandes/xandesperf-11.c | 32 ++ .../gcc.target/riscv/xandes/xandesperf-2.c | 13 + .../gcc.target/riscv/xandes/xandesperf-3.c | 11 + .../gcc.target/riscv/xandes/xandesperf-4.c | 11 + .../gcc.target/riscv/xandes/xandesperf-5.c | 11 + .../gcc.target/riscv/xandes/xandesperf-6.c | 18 + .../gcc.target/riscv/xandes/xandesperf-7.c | 22 + .../gcc.target/riscv/xandes/xandesperf-8.c | 26 ++ .../gcc.target/riscv/xandes/xandesperf-9.c | 31 ++ 22 files changed, 779 insertions(+), 7 deletions(-) create mode 100644 gcc/config/riscv/andes.def create mode 100644 gcc/config/riscv/andes.md create mode 100644 gcc/testsuite/gcc.target/riscv/xandes/xandesperf-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/xandes/xandesperf-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/xandes/xandesperf-11.c create mode 100644 gcc/testsuite/gcc.target/riscv/xandes/xandesperf-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/xandes/xandesperf-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/xandes/xandesperf-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/xandes/xandesperf-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/xandes/xandesperf-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/xandes/xandesperf-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/xandes/xandesperf-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/xandes/xandesperf-9.c diff --git a/gcc/config/riscv/andes.def b/gcc/config/riscv/andes.def new file mode 100644 index 000000000000..e2d67b8b2f18 --- /dev/null +++ b/gcc/config/riscv/andes.def @@ -0,0 +1,10 @@ +// XANDESPERF +/* Andes Performance Extension */ +RISCV_BUILTIN (nds_ffbsi, "nds_ffb_32", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_USI_USI, andesperf32), +RISCV_BUILTIN (nds_ffbdi, "nds_ffb_64", RISCV_BUILTIN_DIRECT, RISCV_DI_FTYPE_UDI_UDI, andesperf64), +RISCV_BUILTIN (nds_ffzmismsi, "nds_ffzmism_32", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_USI_USI, andesperf32), +RISCV_BUILTIN (nds_ffzmismdi, "nds_ffzmism_64", RISCV_BUILTIN_DIRECT, RISCV_DI_FTYPE_UDI_UDI, andesperf64), +RISCV_BUILTIN (nds_ffmismsi, "nds_ffmism_32", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_USI_USI, andesperf32), +RISCV_BUILTIN (nds_ffmismdi, "nds_ffmism_64", RISCV_BUILTIN_DIRECT, RISCV_DI_FTYPE_UDI_UDI, andesperf64), +RISCV_BUILTIN (nds_flmismsi, "nds_flmism_32", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_USI_USI, andesperf32), +RISCV_BUILTIN (nds_flmismdi, "nds_flmism_64", RISCV_BUILTIN_DIRECT, RISCV_DI_FTYPE_UDI_UDI, andesperf64), diff --git a/gcc/config/riscv/andes.md b/gcc/config/riscv/andes.md new file mode 100644 index 000000000000..0f303ca937ad --- /dev/null +++ b/gcc/config/riscv/andes.md @@ -0,0 +1,429 @@ +;; Machine description for Andes vendor extensions +;; 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_c_enum "unspec" [ + ;; XANDESPERF string + UNSPEC_NDS_FFB + UNSPEC_NDS_FFZMISM + UNSPEC_NDS_FFMISM + UNSPEC_NDS_FLMISM +]) + +;; AndesPerf +;; .................... +;; +;; BRANCH OPERATION +;; +;; .................... +;; + +(define_insn "*nds_branch_imms7<mode>" + [(set (pc) + (if_then_else (any_eq (match_operand:X 1 "register_operand" "r") + (match_operand:X 2 "ads_branch_bimm_operand" "Ou07")) + (label_ref (match_operand 0 "" "")) + (pc)))] + "TARGET_XANDESPERF" +{ + if (get_attr_length (insn) == 12) + return "nds.b<optab>c\t%1,%2,1f; jump\t%l0,ra; 1:"; + + return "nds.b<optab>c\t%1,%2,%l0"; +} + [(set_attr "type" "branch") + (set_attr "mode" "none")]) + +(define_insn "*nds_branch_on_bit<X:mode>" + [(set (pc) + (if_then_else (any_eq (zero_extract:X (match_operand:X 1 "register_operand" "r") + (const_int 1) + (match_operand 2 "ads_branch_bbcs_operand")) + (const_int 0)) + (label_ref (match_operand 0)) + (pc))) + (clobber (match_scratch:X 3 "=&r"))] + "TARGET_XANDESPERF" +{ + if (get_attr_length (insn) == 12) + return "nds.bb<any_eq:cs>\t%1,%2,%1f; jump\t%l0,ra; 1:"; + + return "nds.bb<any_eq:cs>\t%1,%2,%l0"; +} + [(set_attr "type" "branch") + (set_attr "mode" "none")]) + +;; +;; .................... +;; +;; EXTENSION OPERATION +;; +;; .................... +;; + +(define_insn "*nds_zero_extendsidi2_internal" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI + (match_operand:SI 1 "nonimmediate_operand" " r,m")))] + "TARGET_64BIT && TARGET_XANDESPERF" + "@ + nds.bfoz\t%0,%1,31,0 + lwu\t%0,%1" + [(set_attr "move_type" "arith,load") + (set_attr "type" "arith,load") + (set_attr "mode" "DI")]) + +(define_insn "*nds_zero_extendhi<GPR:mode>2" + [(set (match_operand:GPR 0 "register_operand" "=r,r") + (zero_extend:GPR + (match_operand:HI 1 "nonimmediate_operand" " r,m")))] + "TARGET_XANDESPERF" + "@ + nds.bfoz\t%0,%1,15,0 + lhu\t%0,%1" + [(set_attr "move_type" "arith,load") + (set_attr "type" "arith,load") + (set_attr "mode" "<GPR:MODE>, HI")]) + +(define_insn "*nds_extendsidi2_internal" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (sign_extend:DI + (match_operand:SI 1 "nonimmediate_operand" " r,m")))] + "TARGET_64BIT && TARGET_XANDESPERF" + "@ + nds.bfos\t%0,%1,31,0 + lw\t%0,%1" + [(set_attr "move_type" "arith,load") + (set_attr "type" "arith,load") + (set_attr "mode" "DI")]) + +(define_insn "*nds_extend<SHORT:mode><SUPERQI:mode>2" + [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") + (sign_extend:SUPERQI + (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))] + "TARGET_XANDESPERF" + "@ + nds.bfos\t%0,%1,<SHORT:sh_limit>,0 + l<SHORT:size>\t%0,%1" + [(set_attr "move_type" "arith,load") + (set_attr "type" "arith,load") + (set_attr "mode" "<SHORT:MODE>")]) + +;; +;; .................... +;; +;; BIT FIELD OPERATION +;; +;; .................... +;; + +;; BFO[SZ]: msb >= lsb: Extract sequence tail bits. +(define_insn "*nds_bfo_<sz>extra<mode>4" + [(set (match_operand:GPR 0 "register_operand" "=r") + (any_extract:GPR (match_operand:GPR 1 "register_operand" " r") + (match_operand 2 "ads_extract_size_imm_<mode>" " n") + (match_operand 3 "const_int<sh_bit>_operand" " n")))] + "TARGET_XANDESPERF + && IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]), + 1, GET_MODE_BITSIZE (<MODE>mode))" + { + operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1); + return "nds.bfo<sz>\t%0,%1,%2,%3"; + } + [(set_attr "type" "shift") + (set_attr "mode" "<GPR:MODE>")]) + +;; BFOZ: msb >= lsb: Mask sequence bits. +(define_insn "*nds_bfoz_and<mode>3" + [(set (match_operand:GPR 0 "register_operand" "=r") + (and:GPR (match_operand:GPR 1 "register_operand" " r") + (match_operand:GPR 2 "ads_imm_extract_operand" " ads_Bext")))] + "TARGET_XANDESPERF" + { + operands[2] = GEN_INT (__builtin_popcountll (INTVAL (operands[2])) - 1); + return "nds.bfoz\t%0,%1,%2,0"; + } + [(set_attr "type" "shift") + (set_attr "mode" "<GPR:MODE>")]) + +;; BFOZ: msb >= lsb: Extract sequence bits. +(define_insn "*nds_zero_extend<GPR:mode>_lshr<SHORT:mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (zero_extend:GPR (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" " r") + (match_operand 2 "const_int_operand" " n"))))] + "TARGET_XANDESPERF + && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)" + "nds.bfoz\t%0, %1, <SHORT:sh_limit>, %2" + [(set_attr "type" "shift") + (set_attr "mode" "<GPR:MODE>")]) + +;; BFOS: msb >= lsb +(define_insn "*nds_extend<GPR:mode>_ashr<SHORT:mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (sign_extend:GPR (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" " r") + (match_operand 2 "const_int_operand" " n"))))] + "TARGET_XANDESPERF + && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)" + "nds.bfos\t%0, %1, <SHORT:sh_limit>, %2" + [(set_attr "type" "shift") + (set_attr "mode" "<GPR:MODE>")]) + +;; BFO[SZ]: msb < lsb: The pattern doesn't match zero_extract when +;; exact_log2 (Y + 1) < 0 of (and (ashift) Y). +(define_insn "*nds_bfoz<mode>4" + [(set (match_operand:GPR 0 "register_operand" "=r") + (and:GPR (ashift:GPR (match_operand:GPR 1 "register_operand" " r") + (match_operand 2 "const_int<sh_bit>_operand" " n")) + (match_operand 3 "const_int_operand" " i")))] + "TARGET_XANDESPERF + && (UINTVAL (operands[2]) != 0) + && (exact_log2 ((UINTVAL (operands[3]) >> UINTVAL (operands[2])) + 1) > 1) + && ((UINTVAL (operands[3]) & ((1 << UINTVAL (operands[2])) - 1)) == 0)" + { + operands[3] = + GEN_INT (exact_log2 ((UINTVAL (operands[3]) >> UINTVAL (operands[2])) + 1) + + UINTVAL (operands[2]) - 1) ; + return "nds.bfoz\t%0,%1,%2,%3"; + } + [(set_attr "type" "shift") + (set_attr "mode" "<GPR:MODE>")]) + +;; BFOZ: msb = 0. +(define_insn "*nds_bfoz0<mode>4" + [(set (match_operand:GPR 0 "register_operand" "=r") + (and:GPR (ashift:GPR (match_operand:GPR 1 "register_operand" " r") + (match_operand 2 "const_int<sh_bit>_operand" " n")) + (match_operand 3 "const_int_operand" " i")))] + "TARGET_XANDESPERF + && (UINTVAL (operands[2]) != 0) + && (exact_log2 ((UINTVAL (operands[3]) >> UINTVAL (operands[2])) + 1) == 1) + && ((UINTVAL (operands[3]) & ((1 << UINTVAL (operands[2])) - 1)) == 0)" + { + return "nds.bfoz\t%0,%1,0,%2"; + } + [(set_attr "type" "shift") + (set_attr "mode" "<GPR:MODE>")]) + +;; BFO: msb = 0. +(define_insn "*nds_bfos0<mode>4" + [(set (match_operand:GPR 0 "register_operand" "=r") + (ashift:GPR (any_extract:GPR (match_operand:GPR 1 "register_operand" " r") + (const_int 1) + (const_int 0)) + (match_operand 2 "const_int<sh_bit>_operand" " n")))] + "TARGET_XANDESPERF" + { + return "nds.bfo<sz>\t%0,%1,0,%2"; + } + [(set_attr "type" "shift") + (set_attr "mode" "<GPR:MODE>")]) + +;; BFO: msb < lsb. +(define_insn "*nds_bfos_<sz>extra_<mode>4" + [(set (match_operand:GPR 0 "register_operand" "=r") + (ashift:GPR (any_extract:GPR (match_operand:GPR 1 "register_operand" " r") + (match_operand 2 "ads_extract_size_imm_<mode>" " n") + (const_int 0)) + (match_operand 3 "const_int<sh_bit>_operand" " n")))] + "TARGET_XANDESPERF + && UINTVAL (operands[2]) != 1" + { + operands[2] = GEN_INT (UINTVAL (operands[2]) + UINTVAL (operands[3]) - 1); + return "nds.bfo<sz>\t%0,%1,%3,%2"; + } + [(set_attr "type" "shift") + (set_attr "mode" "<GPR:MODE>")]) + +;; BFO: msb < lsb +(define_insn "*nds_<optab><ANYLE32:mode>_shft_<GPR:mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (ashift:GPR (any_extend:GPR + (match_operand:ANYLE32 1 "register_operand" " r")) + (match_operand 2 "const_int_operand" " n")))] + "TARGET_XANDESPERF + && (UINTVAL (operands[2]) < <ANYLE32:sizen>) + && ((INTVAL (operands[2]) + <ANYLE32:sizen>) <= <GPR:sizen>)" +{ + operands[3] = GEN_INT (<ANYLE32:sizen> + INTVAL (operands[2]) - 1); + return "nds.bfo<sz>\t%0, %1, %2, %3"; +} + [(set_attr "type" "shift")]) + +;; BFO: msb < lsb +(define_insn "*nds_<optab><GPR:mode>_ashl<ANYLE32:mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (any_extend:GPR + (ashift:ANYLE32 (match_operand:ANYLE32 1 "register_operand" " r") + (match_operand 2 "const_int_operand" " n"))))] + "TARGET_XANDESPERF + && UINTVAL (operands[2]) < ((<ANYLE32:sizen>) - 1)" +{ + operands[3] = GEN_INT (<ANYLE32:sizen> - 1); + return "nds.bfo<sz>\t%0, %1, %2, %3"; +} + [(set_attr "type" "shift") + (set_attr "mode" "<GPR:MODE>")]) + +;; +;; .................... +;; +;; LOAD ADDRESS +;; +;; .................... +;; + +(define_insn "lea_h<mode>" + [(set (match_operand:P 0 "register_operand" "=r") + (plus:P (ashift:P (match_operand:P 1 "register_operand" " r") + (const_int 1)) + (match_operand:P 2 "register_operand" " r")))] + "TARGET_XANDESPERF" + { return "nds.lea.h\t%0,%2,%1"; } + [(set_attr "type" "arith") + (set_attr "mode" "<MODE>")]) + +(define_insn "lea_w<mode>" + [(set (match_operand:P 0 "register_operand" "=r") + (plus:P (ashift:P (match_operand:P 1 "register_operand" " r") + (const_int 2)) + (match_operand:P 2 "register_operand" " r")))] + "TARGET_XANDESPERF" + { return "nds.lea.w\t%0,%2,%1"; } + [(set_attr "type" "arith") + (set_attr "mode" "<MODE>")]) + +(define_insn "lea_d<mode>" + [(set (match_operand:P 0 "register_operand" "=r") + (plus:P (ashift:P (match_operand:P 1 "register_operand" " r") + (const_int 3)) + (match_operand:P 2 "register_operand" " r")))] + "TARGET_XANDESPERF" + { return "nds.lea.d\t%0,%2,%1"; } + [(set_attr "type" "arith") + (set_attr "mode" "<MODE>")]) + +(define_insn "lea_b_ze" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r")) + (match_operand:DI 2 "register_operand" " r")))] + "TARGET_64BIT && TARGET_XANDESPERF" + { return "nds.lea.b.ze\t%0,%2,%1"; } + [(set_attr "type" "arith") + (set_attr "mode" "DI")]) + +(define_insn "lea_h_ze" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r")) + (const_int 1)) + (match_operand:DI 2 "register_operand" " r")))] + "TARGET_64BIT && TARGET_XANDESPERF" + { return "nds.lea.h.ze\t%0,%2,%1"; } + [(set_attr "type" "arith") + (set_attr "mode" "DI")]) + +(define_insn "lea_w_ze" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r")) + (const_int 2)) + (match_operand:DI 2 "register_operand" " r")))] + "TARGET_64BIT && TARGET_XANDESPERF" + { return "nds.lea.w.ze\t%0,%2,%1"; } + [(set_attr "type" "arith") + (set_attr "mode" "DI")]) + +(define_insn "lea_d_ze" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r")) + (const_int 3)) + (match_operand:DI 2 "register_operand" " r")))] + "TARGET_64BIT && TARGET_XANDESPERF" + { return "nds.lea.d.ze\t%0,%2,%1"; } + [(set_attr "type" "arith") + (set_attr "mode" "DI")]) + +(define_insn "lea_andim_ashift" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (and:DI (ashift:DI (match_operand:DI 1 "register_operand" " r") + (match_operand 2 "const_int_operand" " i")) + (match_operand 3 "const_int_operand" " i")) + (match_operand:DI 4 "register_operand" " r")))] + "TARGET_64BIT && TARGET_XANDESPERF + && IN_RANGE (UINTVAL (operands[2]), 0, 3) + && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) == 32 + && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0" + { + switch (UINTVAL (operands[2])) + { + case 0: + return "nds.lea.b.ze %0, %4, %1"; + case 1: + return "nds.lea.h.ze %0, %4, %1"; + case 2: + return "nds.lea.w.ze %0, %4, %1"; + case 3: + return "nds.lea.d.ze %0, %4, %1"; + default: + gcc_unreachable (); + } + } + [(set_attr "type" "arith") + (set_attr "mode" "DI")]) + +;; +;; .................... +;; +;; String Extension +;; +;; .................... +;; + +(define_insn "riscv_nds_ffb<mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (unspec:GPR [(match_operand:GPR 1 "reg_or_0_operand" "rJ") + (match_operand:GPR 2 "nonmemory_operand" "rJ")] UNSPEC_NDS_FFB))] + "" + "nds.ffb\t%0, %z1, %z2" + [(set_attr "mode" "<MODE>") + (set_attr "type" "arith")]) + +(define_insn "riscv_nds_ffzmism<mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (unspec:GPR [(match_operand:GPR 1 "reg_or_0_operand" "rJ") + (match_operand:GPR 2 "reg_or_0_operand" "rJ")] UNSPEC_NDS_FFZMISM))] + "" + "nds.ffzmism\t%0, %z1, %z2" + [(set_attr "mode" "<MODE>") + (set_attr "type" "arith")]) + +(define_insn "riscv_nds_ffmism<mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (unspec:GPR [(match_operand:GPR 1 "reg_or_0_operand" "rJ") + (match_operand:GPR 2 "reg_or_0_operand" "rJ")] UNSPEC_NDS_FFMISM))] + "" + "nds.ffmism\t%0, %z1, %z2" + [(set_attr "mode" "<MODE>") + (set_attr "type" "arith")]) + +(define_insn "riscv_nds_flmism<mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (unspec:GPR [(match_operand:GPR 1 "reg_or_0_operand" "rJ") + (match_operand:GPR 2 "reg_or_0_operand" "rJ")] UNSPEC_NDS_FLMISM))] + "" + "nds.flmism\t%0, %z1, %z2" + [(set_attr "mode" "<MODE>") + (set_attr "type" "arith")]) diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index 5ecaa19eb014..60e6dee66ead 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -330,3 +330,13 @@ (define_constraint "Q" "An address operand that is valid for a prefetch instruction" (match_operand 0 "prefetch_operand")) + +(define_constraint "Ou07" + "A 7-bit unsigned immediate." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 0, 127)"))) + +(define_constraint "ads_Bext" + "Sequence bit extract." + (and (match_code "const_int") + (match_test "(ival & (ival + 1)) == 0"))) diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md index 584b345f02c4..d30022415099 100644 --- a/gcc/config/riscv/iterators.md +++ b/gcc/config/riscv/iterators.md @@ -71,6 +71,9 @@ ;; Iterator for hardware integer modes narrower than XLEN, same as ANYI. (define_mode_iterator ANYI1 [QI HI SI (DI "TARGET_64BIT")]) +;; Iterator for integer modes less than or equal to 32bit. +(define_mode_iterator ANYLE32 [QI HI SI]) + (define_mode_iterator ANYI_DOUBLE_TRUNC [HI SI (DI "TARGET_64BIT")]) (define_mode_iterator ANYI_QUAD_TRUNC [SI (DI "TARGET_64BIT")]) @@ -169,10 +172,19 @@ ;; the controlling mode. (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")]) +;; Give the number of bits in the mode +(define_mode_attr sizen [(QI "8") (HI "16") (SI "32") (DI "64")]) + ; bitmanip mode attribute (define_mode_attr shiftm1 [(SI "const_si_mask_operand") (DI "const_di_mask_operand")]) (define_mode_attr shiftm1p [(SI "DsS") (DI "DsD")]) +; mode shift limit attribute +(define_mode_attr sh_limit [(QI "7") (HI "15")]) + +; mode shift bit limit attribute +(define_mode_attr sh_bit [(SI "5") (DI "6")]) + ; zcmp mode attribute (define_mode_attr slot0_offset [(SI "-4") (DI "-8")]) (define_mode_attr slot1_offset [(SI "-8") (DI "-16")]) @@ -284,6 +296,9 @@ ;; <su> is like <u>, but the signed form expands to "s" rather than "". (define_code_attr su [(sign_extend "s") (zero_extend "u")]) +;; eq expand to "c" and ne expand to "s". +(define_code_attr cs [(eq "c") (ne "s")]) + ;; <optab> expands to the name of the optab for a particular code. (define_code_attr optab [(ashift "ashl") (ashiftrt "ashr") diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 381f96c3e725..7fcafd040282 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -465,6 +465,10 @@ (ior (match_operand 0 "const_int6_operand") (match_operand 0 "register_operand"))) +(define_predicate "const_int5_operand" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 0, 31)"))) + (define_predicate "const_int5s_operand" (and (match_code "const_int") (match_test "IN_RANGE (INTVAL (op), -16, 15)"))) @@ -710,3 +714,41 @@ (define_predicate "reg_or_const_int_operand" (ior (match_operand 0 "const_int_operand") (match_operand 0 "register_operand"))) + +;; Branch-on-bit for AndesPerf. +(define_predicate "ads_branch_bbcs_operand" + (match_code "const_int") +{ + if (TARGET_XANDESPERF && (INTVAL (op) >= 0)) + { + if (TARGET_64BIT && INTVAL (op) <= 63) + return true; + else if (INTVAL (op) <=31) + return true; + else + return false; + } + + return false; +}) + +;; Branch on small immediate range. +(define_predicate "ads_branch_bimm_operand" + (match_code "const_int") +{ + if (TARGET_XANDESPERF) + return satisfies_constraint_Ou07 (op); + else + return false; +}) + +(define_predicate "ads_imm_extract_operand" + (match_test "satisfies_constraint_ads__Bext (op)")) + +(define_predicate "ads_extract_size_imm_si" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 1, 32)"))) + +(define_predicate "ads_extract_size_imm_di" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 1, 64)"))) diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc index 9f8a9806bd94..cfcacf40a93b 100644 --- a/gcc/config/riscv/riscv-builtins.cc +++ b/gcc/config/riscv/riscv-builtins.cc @@ -137,6 +137,10 @@ AVAIL (cvalu, TARGET_XCVALU && !TARGET_64BIT) AVAIL (cvelw, TARGET_XCVELW && !TARGET_64BIT) AVAIL (cvsimd, TARGET_XCVSIMD && !TARGET_64BIT) +/* ANDES AVAIL. */ +AVAIL (andesperf32, !TARGET_64BIT && TARGET_XANDESPERF) +AVAIL (andesperf64, TARGET_64BIT && TARGET_XANDESPERF) + /* Construct a riscv_builtin_description from the given arguments. INSN is the name of the associated instruction pattern, without the @@ -191,6 +195,7 @@ AVAIL (cvsimd, TARGET_XCVSIMD && !TARGET_64BIT) #define RISCV_ATYPE_QI intQI_type_node #define RISCV_ATYPE_HI intHI_type_node #define RISCV_ATYPE_SI intSI_type_node +#define RISCV_ATYPE_DI intDI_type_node #define RISCV_ATYPE_VOID_PTR ptr_type_node #define RISCV_ATYPE_INT_PTR integer_ptr_type_node @@ -212,6 +217,7 @@ static const struct riscv_builtin_description riscv_builtins[] = { #include "riscv-cmo.def" #include "riscv-scalar-crypto.def" #include "corev.def" + #include "andes.def" DIRECT_BUILTIN (frflags, RISCV_USI_FTYPE, hard_float), DIRECT_NO_TARGET_BUILTIN (fsflags, RISCV_VOID_FTYPE_USI, hard_float), diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def index f7854dd996bc..6db41adc63ce 100644 --- a/gcc/config/riscv/riscv-ftypes.def +++ b/gcc/config/riscv/riscv-ftypes.def @@ -52,6 +52,7 @@ DEF_RISCV_FTYPE (2, (UDI, UDI, USI)) DEF_RISCV_FTYPE (2, (UDI, UDI, UDI)) DEF_RISCV_FTYPE (2, (SI, USI, USI)) DEF_RISCV_FTYPE (2, (SI, SI, SI)) +DEF_RISCV_FTYPE (2, (DI, UDI, UDI)) DEF_RISCV_FTYPE (3, (USI, USI, USI, UQI)) DEF_RISCV_FTYPE (3, (USI, USI, USI, QI)) DEF_RISCV_FTYPE (3, (USI, USI, UQI, USI)) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 4935367dd0e0..f16fbd464b87 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3932,6 +3932,10 @@ riscv_extend_cost (rtx op, bool unsigned_p) if (MEM_P (op)) return 0; + /* Andes bfo patterns. */ + if (TARGET_XANDESPERF) + return COSTS_N_INSNS (1); + if (unsigned_p && GET_MODE (op) == QImode) /* We can use ANDI. */ return COSTS_N_INSNS (1); @@ -4161,6 +4165,12 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN return false; case AND: + /* Andes bfo patterns. */ + if (TARGET_XANDESPERF && GET_CODE (XEXP (x, 0)) == ASHIFT) + { + *total = COSTS_N_INSNS (1); + return true; + } /* slli.uw pattern for zba. */ if (TARGET_ZBA && TARGET_64BIT && mode == DImode && GET_CODE (XEXP (x, 0)) == ASHIFT) @@ -4220,6 +4230,13 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN return false; case ZERO_EXTRACT: + /* Andes bbcs patterns. */ + if (TARGET_XANDESPERF + && (outer_code == NE || outer_code == EQ)) + { + *total = 0; + return true; + } /* This is an SImode shift. */ if (outer_code == SET && CONST_INT_P (XEXP (x, 1)) @@ -4247,6 +4264,12 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); return true; } + /* Andes bfo patterns. */ + if (TARGET_XANDESPERF) + { + *total = COSTS_N_INSNS (1); + return true; + } return false; case ASHIFT: @@ -4415,6 +4438,15 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN } while (false); } + /* Andes lea patterns. */ + if (TARGET_XANDESPERF + && ((TARGET_64BIT && GET_CODE (XEXP (x, 0)) == AND) + || GET_CODE (XEXP (x, 0)) == ASHIFT)) + { + *total = COSTS_N_INSNS (1); + return true; + } + if (float_mode_p) *total = tune_param->fp_add[mode == DFmode]; else diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index a72604e29218..d2975470036d 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1911,6 +1911,7 @@ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" " r,m")))] "TARGET_64BIT && !TARGET_ZBA && !TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX + && !TARGET_XANDESPERF && !(REG_P (operands[1]) && VL_REG_P (REGNO (operands[1])))" "@ # @@ -1937,7 +1938,8 @@ [(set (match_operand:GPR 0 "register_operand" "=r,r") (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" " r,m")))] - "!TARGET_ZBB && !TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX" + "!TARGET_ZBB && !TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX + && !TARGET_XANDESPERF" "@ # lhu\t%0,%1" @@ -1999,7 +2001,7 @@ [(set (match_operand:DI 0 "register_operand" "=r,r") (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" " r,m")))] - "TARGET_64BIT && !TARGET_XTHEADMEMIDX" + "TARGET_64BIT && !TARGET_XTHEADMEMIDX && !TARGET_XANDESPERF" "@ sext.w\t%0,%1 lw\t%0,%1" @@ -2016,7 +2018,8 @@ [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") (sign_extend:SUPERQI (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))] - "!TARGET_ZBB && !TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX" + "!TARGET_ZBB && !TARGET_XTHEADBB && !TARGET_XTHEADMEMIDX + && !TARGET_XANDESPERF" "@ # l<SHORT:size>\t%0,%1" @@ -3096,6 +3099,7 @@ || TARGET_XVENTANACONDOPS || TARGET_SFB_ALU) && (INTVAL (operands[2]) == 1)) && !TARGET_XTHEADBB + && !TARGET_XANDESPERF && !(TARGET_64BIT && (INTVAL (operands[3]) > 0) && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))" @@ -3481,9 +3485,9 @@ (label_ref (match_operand 1)) (pc))) (clobber (match_scratch:X 4 "=&r"))] - "" - "#" - "reload_completed" + "!TARGET_XANDESPERF" + "#" + "&& reload_completed" [(set (match_dup 4) (ashift:X (match_dup 2) (match_dup 3))) (set (pc) @@ -4918,3 +4922,4 @@ (include "sifive-p600.md") (include "generic-vector-ooo.md") (include "generic-ooo.md") +(include "andes.md") diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index aa3b6fb1ab84..db89b3609b1a 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -4364,7 +4364,7 @@ (umax "%3,%4") (mult "%3,%4")]) -(define_code_attr sz [(sign_extend "s") (zero_extend "z")]) +(define_code_attr sz [(sign_extend "s") (zero_extend "z") (sign_extract "s") (zero_extract "z")]) ;; VLS modes that has NUNITS < 32. (define_mode_iterator VLS_AVL_IMM [ diff --git a/gcc/testsuite/gcc.target/riscv/riscv.exp b/gcc/testsuite/gcc.target/riscv/riscv.exp index b3222c56dd85..b5e7618f7045 100644 --- a/gcc/testsuite/gcc.target/riscv/riscv.exp +++ b/gcc/testsuite/gcc.target/riscv/riscv.exp @@ -40,6 +40,8 @@ gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ "" $DEFAULT_CFLAGS gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/sched1-spills/*.{\[cS\],cpp}]] \ "" $DEFAULT_CFLAGS +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/xandes/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS # Saturation alu foreach opt { diff --git a/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-1.c b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-1.c new file mode 100644 index 000000000000..b8db0d84614e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xandesperf -mabi=lp64" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xandesperf -mabi=ilp32" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +long foo (long cond) +{ + if (cond != 63) + cond += 10; + return cond; +} + +/* { dg-final { scan-assembler {\mnds.beqc} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-10.c b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-10.c new file mode 100644 index 000000000000..1ac224688a8e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-10.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv32 } */ +/* { dg-options "-march=rv32gc_xandesperf -mabi=ilp32" } */ + +int +test_nds_ffb (unsigned int a, unsigned int b) +{ + return __builtin_riscv_nds_ffb_32 (a, b); +} + +int +test_nds_ffzmism (unsigned int a, unsigned int b) +{ + return __builtin_riscv_nds_ffzmism_32 (a, b); +} + +int +test_nds_ffmism (unsigned int a, unsigned int b) +{ + return __builtin_riscv_nds_ffmism_32 (a, b); +} + +int +test_nds_flmism (unsigned int a, unsigned int b) +{ + return __builtin_riscv_nds_flmism_32 (a, b); +} + +/* { dg-final { scan-assembler-times {nds\.ffb} 1 } } */ +/* { dg-final { scan-assembler-times {nds\.ffzmism} 1 } } */ +/* { dg-final { scan-assembler-times {nds\.ffmism} 1 } } */ +/* { dg-final { scan-assembler-times {nds\.flmism} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-11.c b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-11.c new file mode 100644 index 000000000000..08fdd56bee11 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-11.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-options "-march=rv64gc_xandesperf -mabi=lp64" } */ + +long +test_nds_ffb (unsigned long a, unsigned long b) +{ + return __builtin_riscv_nds_ffb_64 (a, b); +} + +long +test_nds_ffzmism (unsigned long a, unsigned long b) +{ + return __builtin_riscv_nds_ffzmism_64 (a, b); +} + +long +test_nds_ffmism (unsigned long a, unsigned long b) +{ + return __builtin_riscv_nds_ffmism_64 (a, b); +} + +long +test_nds_flmism (unsigned long a, unsigned long b) +{ + return __builtin_riscv_nds_flmism_64 (a, b); +} + +/* { dg-final { scan-assembler-times {nds\.ffb} 1 } } */ +/* { dg-final { scan-assembler-times {nds\.ffzmism} 1 } } */ +/* { dg-final { scan-assembler-times {nds\.ffmism} 1 } } */ +/* { dg-final { scan-assembler-times {nds\.flmism} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-2.c b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-2.c new file mode 100644 index 000000000000..0b90f9e1768c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-2.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xandesperf -mabi=lp64" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xandesperf -mabi=ilp32" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +long foo (long cond) +{ + if (cond & (1 << 30)) + cond -= 10; + return cond; +} + +/* { dg-final { scan-assembler {\mnds.bbc} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-3.c b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-3.c new file mode 100644 index 000000000000..65ff59e91955 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-options "-march=rv64gc_xandesperf -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +unsigned long foo (long a) +{ + unsigned int lala = a; + return lala; +} + +/* { dg-final { scan-assembler {\mnds.bfoz} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-4.c b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-4.c new file mode 100644 index 000000000000..f97b98c5e152 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-4.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xandesperf -mabi=lp64" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xandesperf -mabi=ilp32" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +unsigned short foo (long a) +{ + return (unsigned short) a; +} + +/* { dg-final { scan-assembler {\mnds.bfoz} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-5.c b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-5.c new file mode 100644 index 000000000000..4b34baf0b4d9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-5.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-options "-march=rv64gc_xandesperf -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +long foo (long a) +{ + int lala = a; + return lala; +} + +/* { dg-final { scan-assembler {\mnds.bfos} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-6.c b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-6.c new file mode 100644 index 000000000000..85c858145c3f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-6.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xandesperf -mabi=lp64" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xandesperf -mabi=ilp32" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +short foo (long a) +{ + short lala = a; + return lala; +} + +signed char foo1 (long a) +{ + signed char lala = a; + return lala; +} + +/* { dg-final { scan-assembler-times {\mnds.bfos} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-7.c b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-7.c new file mode 100644 index 000000000000..e8cbf456cc76 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-7.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xandesperf -mabi=lp64" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xandesperf -mabi=ilp32" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +long foo (long a) +{ + return (a & 0xffe0) >> 5; +} + +unsigned long foo1 (unsigned long a) +{ + return (a & 0xffe0) >> 5; +} + +signed char foo2 (long a) +{ + return (signed char) ((a & 0xff00) >> 8); +} + +/* { dg-final { scan-assembler-times {\mnds.bfoz} 2 } } */ +/* { dg-final { scan-assembler-times {\mnds.bfos} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-8.c b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-8.c new file mode 100644 index 000000000000..357b8fc3c853 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-8.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xandesperf -mabi=lp64" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xandesperf -mabi=ilp32" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +short *ptr_h; +short foo_h (long a) +{ + return *(ptr_h + a); +} + +int *ptr_i; +int foo_i (long a) +{ + return *(ptr_i + a); +} + +long long *ptr_d; +long long foo_d (long a) +{ + return *(ptr_d + a); +} + +/* { dg-final { scan-assembler-times {\mnds.lea.h} 1 } } */ +/* { dg-final { scan-assembler-times {\mnds.lea.w} 1 } } */ +/* { dg-final { scan-assembler-times {\mnds.lea.d} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-9.c b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-9.c new file mode 100644 index 000000000000..b21a13c7895f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xandes/xandesperf-9.c @@ -0,0 +1,31 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-options "-march=rv64gc_xandesperf -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +char *ptr_ub; +char foo_ub (unsigned int a) +{ + return *(ptr_ub + a); +} + +short *ptr_uh; +short foo_uh (unsigned int a) +{ + return *(ptr_uh + a); +} + +int *ptr_ui; +int foo_ui (unsigned int a) +{ + return *(ptr_ui + a); +} + +long long *ptr_ud; +long long foo_ud (unsigned int a) +{ + return *(ptr_ud + a); +} +/* { dg-final { scan-assembler-times {\mnds.lea.b.ze} 1 } } */ +/* { dg-final { scan-assembler-times {\mnds.lea.h.ze} 1 } } */ +/* { dg-final { scan-assembler-times {\mnds.lea.w.ze} 1 } } */ +/* { dg-final { scan-assembler-times {\mnds.lea.d.ze} 1 } } */ -- 2.34.1