]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add support for the XAndesperf ISA extension.
authorKuan-Lin Chen <rufus@andestech.com>
Wed, 3 Sep 2025 22:52:49 +0000 (16:52 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Wed, 3 Sep 2025 22:53:27 +0000 (16:53 -0600)
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.

22 files changed:
gcc/config/riscv/andes.def [new file with mode: 0644]
gcc/config/riscv/andes.md [new file with mode: 0644]
gcc/config/riscv/constraints.md
gcc/config/riscv/iterators.md
gcc/config/riscv/predicates.md
gcc/config/riscv/riscv-builtins.cc
gcc/config/riscv/riscv-ftypes.def
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.md
gcc/config/riscv/vector-iterators.md
gcc/testsuite/gcc.target/riscv/riscv.exp
gcc/testsuite/gcc.target/riscv/xandes/xandesperf-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xandes/xandesperf-10.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xandes/xandesperf-11.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xandes/xandesperf-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xandes/xandesperf-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xandes/xandesperf-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xandes/xandesperf-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xandes/xandesperf-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xandes/xandesperf-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xandes/xandesperf-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xandes/xandesperf-9.c [new file with mode: 0644]

diff --git a/gcc/config/riscv/andes.def b/gcc/config/riscv/andes.def
new file mode 100644 (file)
index 0000000..e2d67b8
--- /dev/null
@@ -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 (file)
index 0000000..0f303ca
--- /dev/null
@@ -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")])
index 979e0df06f10f34f1d0456e1a3336fb4c09b09bd..dd462c653f3ab9b8a5a12e8a339aa8ce635f0e0d 100644 (file)
 (define_address_constraint "ZD"
   "An address operand that is valid for a mips prefetch instruction"
   (match_test "riscv_prefetch_offset_address_p (op, mode)"))
+
+(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")))
index 584b345f02c415d154179e01750782e15b2ec687..d300224150991d88f99aa5e4ffdecd4761055c56 100644 (file)
@@ -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")])
 ;; 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")])
 ;; <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")
index bdb3d22258d97d26354ff03268b5e9d8c8f27d53..777e71b14e38a398cbd408eacacf06fc252dcd5e 100644 (file)
   (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)")))
 (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)")))
index 9f8a9806bd94fe225fb19f23edda419ff1468e34..cfcacf40a93bcb7761e6c4638da1c5a5c78fd5cf 100644 (file)
@@ -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),
index f7854dd996bcf342a1cdaf3928fe552cc7ce0c21..6db41adc63cee6b7e8b1476e36d553a9879417fd 100644 (file)
@@ -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))
index 591122f91b8c7ae1226447d08eeb42584d0b7af4..d5a656c3781f52f7f701bcb86a952cbe9b0ce639 100644 (file)
@@ -3933,6 +3933,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);
@@ -4162,6 +4166,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)
@@ -4221,6 +4231,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))
@@ -4248,6 +4265,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:
@@ -4416,6 +4439,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
index d34405cbc3c63ca987e5f27a32f1c38c84cbd53a..63d7daa01b0ae79f3e44f0ba4df0eb5268b60dcd 100644 (file)
        (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])))"
   "@
    #
   [(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"
   [(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"
   [(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"
       || 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))"
            (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)
 ;; Vendor extensions
 (include "thead.md")
 (include "corev.md")
+(include "andes.md")
 ;; Pipeline models
 (include "generic.md")
 (include "xiangshan.md")
index aa3b6fb1ab845419127b69159d6db0db06f17a09..db89b3609b1acd2854a2e9f03301d43f657c4330 100644 (file)
                              (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 [
index b3222c56dd8571ac848d23be4ca0c9e54af872d0..b5e7618f704555fd54b81caefa72d8cb398fd819 100644 (file)
@@ -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 (file)
index 0000000..b8db0d8
--- /dev/null
@@ -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 (file)
index 0000000..1ac2246
--- /dev/null
@@ -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 (file)
index 0000000..08fdd56
--- /dev/null
@@ -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 (file)
index 0000000..c3ef29b
--- /dev/null
@@ -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 "nds\.bb\[cs\]" } } */
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 (file)
index 0000000..65ff59e
--- /dev/null
@@ -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 (file)
index 0000000..f97b98c
--- /dev/null
@@ -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 (file)
index 0000000..4b34baf
--- /dev/null
@@ -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 (file)
index 0000000..85c8581
--- /dev/null
@@ -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 (file)
index 0000000..e8cbf45
--- /dev/null
@@ -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 (file)
index 0000000..357b8fc
--- /dev/null
@@ -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 (file)
index 0000000..b21a13c
--- /dev/null
@@ -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 } } */