[RFC PATCH] RISC-V: Remove f{r,s}flags builtins

2023-11-29 Thread Christoph Muellner
From: Christoph Müllner 

We have two builtins which are undocumented and have no known users.
Further, they don't exist in LLVM (so are no portable).
This means they are in an unclear state of being supported or not.
Let's remove them get them out of this undecided state.

A discussion about making these builtins available in all
compilers was held many years ago with the decision to
not document them in the RISC-V C API documentation:
  https://github.com/riscv-non-isa/riscv-c-api-doc/pull/3

This is an RFC patch as this breaks existing code that uses
these builtins, even if we don't know if such code exists.

An alternative to this patch would be to document them
in gcc/doc/extend.texi (like has been done with __builtin_riscv_pause)
and put them into a supported state.

This patch removes two tests for these builtins.
A test of this patch did not trigger any regressions in riscv.exp.

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/riscv-builtins.cc: Remove the builtins
__builtin_riscv_frflags and __builtin_riscv_fsflags.

gcc/testsuite/ChangeLog:

* g++.target/riscv/frflags.C: Removed.
* gcc.target/riscv/fsflags.c: Removed.
---
 gcc/config/riscv/riscv-builtins.cc   |  2 --
 gcc/testsuite/g++.target/riscv/frflags.C |  7 ---
 gcc/testsuite/gcc.target/riscv/fsflags.c | 16 
 3 files changed, 25 deletions(-)
 delete mode 100644 gcc/testsuite/g++.target/riscv/frflags.C
 delete mode 100644 gcc/testsuite/gcc.target/riscv/fsflags.c

diff --git a/gcc/config/riscv/riscv-builtins.cc 
b/gcc/config/riscv/riscv-builtins.cc
index fc3976f3ba1..1655492b246 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -188,8 +188,6 @@ static const struct riscv_builtin_description 
riscv_builtins[] = {
   #include "riscv-scalar-crypto.def"
   #include "corev.def"
 
-  DIRECT_BUILTIN (frflags, RISCV_USI_FTYPE, hard_float),
-  DIRECT_NO_TARGET_BUILTIN (fsflags, RISCV_VOID_FTYPE_USI, hard_float),
   RISCV_BUILTIN (pause, "pause", RISCV_BUILTIN_DIRECT_NO_TARGET, 
RISCV_VOID_FTYPE, hint_pause),
 };
 
diff --git a/gcc/testsuite/g++.target/riscv/frflags.C 
b/gcc/testsuite/g++.target/riscv/frflags.C
deleted file mode 100644
index 6353044dcf7..000
--- a/gcc/testsuite/g++.target/riscv/frflags.C
+++ /dev/null
@@ -1,7 +0,0 @@
-/* { dg-options "-O2 -march=rv32if -mabi=ilp32f" } */
-/* { dg-do compile } */
-
-int f()
-{
-  return __builtin_riscv_frflags();
-}
diff --git a/gcc/testsuite/gcc.target/riscv/fsflags.c 
b/gcc/testsuite/gcc.target/riscv/fsflags.c
deleted file mode 100644
index 74a97b8a7c7..000
--- a/gcc/testsuite/gcc.target/riscv/fsflags.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Verify that fsflags is using the correct register or immediate.  */
-/* { dg-do compile } */
-/* { dg-require-effective-target hard_float } */
-/* { dg-options "-O" } */
-
-void foo1 (int a)
-{
-   __builtin_riscv_fsflags(a);
-}
-void foo2 ()
-{
-   __builtin_riscv_fsflags(4);
-}
-
-/* { dg-final { scan-assembler-times "fsflags\t" 1 } } */
-/* { dg-final { scan-assembler-times "fsflagsi\t" 1 } } */
-- 
2.41.0



[PATCH] RISC-V: Use stdint-gcc.h in rvv testsuite

2023-11-07 Thread Christoph Muellner
From: Christoph Müllner 

stdint.h can be replaced with stdint-gcc.h to resolve some missing
system headers in non-multilib installations.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadmemidx-helpers.h:
Replace stdint.h with stdint-gcc.h.

Signed-off-by: Christoph Müllner 
---
 gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h 
b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h
index a97f08c5cc1..9d8ce124a93 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h
@@ -1,7 +1,7 @@
 #ifndef XTHEADMEMIDX_HELPERS_H
 #define XTHEADMEMIDX_HELPERS_H
 
-#include 
+#include 
 
 #define intX_t long
 #define uintX_t unsigned long
-- 
2.41.0



[PATCH] RISC-V: Add ABI requirement for XTheadFMemIdx tests

2023-11-06 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadFMemIdx tests set the required ABI for RV32, but not
for RV64, which has the effect that the tests are expected to
succeed for RV64/LP64.  Let's set the ABI to LP64D in these
tests to clarify the requirements.

Signed-off-by: Christoph Müllner 

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadfmemidx-index-update.c: Add ABI.
* gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c: Likewise.
* gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c: Likewise.
* gcc.target/riscv/xtheadfmemidx-index.c: Likewise.
* gcc.target/riscv/xtheadfmemidx-uindex-update.c: Likewise.
* gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c: Likewise.
* gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c: Likewise.
* gcc.target/riscv/xtheadfmemidx-uindex.c: Likewise.
---
 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c | 2 +-
 .../gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c  | 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c   | 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c| 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c| 2 +-
 .../gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c | 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c  | 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c   | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c 
b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c
index 24bbb63d174..cb86b8ad296 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
-/* { dg-options "-march=rv64gc_xtheadmemidx_xtheadfmemidx" { target { rv64 } } 
} */
+/* { dg-options "-march=rv64gc_xtheadmemidx_xtheadfmemidx -mabi=lp64d" { 
target { rv64 } } } */
 /* { dg-options "-march=rv32imafc_xtheadmemidx_xtheadfmemidx -mabi=ilp32f" { 
target { rv32 } } } */
 
 #include "xtheadmemidx-helpers.h"
diff --git 
a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c 
b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c
index 3b931a4b980..cc3f6219c05 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
-/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx_xtheadfmemidx" { target { 
rv64 } } } */
+/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx_xtheadfmemidx 
-mabi=lp64d" { target { rv64 } } } */
 /* { dg-options "-march=rv32imafc_xtheadbb_xtheadmemidx_xtheadfmemidx 
-mabi=ilp32f" { target { rv32 } } } */
 
 #include "xtheadmemidx-helpers.h"
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c 
b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c
index 48858605c24..8ee98c87469 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
-/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx_xtheadfmemidx" { target { 
rv64 } } } */
+/* { dg-options "-march=rv64gc_xtheadbb_xtheadmemidx_xtheadfmemidx 
-mabi=lp64d" { target { rv64 } } } */
 /* { dg-options "-march=rv32imafc_xtheadbb_xtheadmemidx_xtheadfmemidx 
-mabi=ilp32f" { target { rv32 } } } */
 
 #include "xtheadmemidx-helpers.h"
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c 
b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c
index 1bb231a9e88..35704063598 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
-/* { dg-options "-march=rv64gc_xtheadmemidx_xtheadfmemidx" { target { rv64 } } 
} */
+/* { dg-options "-march=rv64gc_xtheadmemidx_xtheadfmemidx -mabi=lp64d" { 
target { rv64 } } } */
 /* { dg-options "-march=rv32imafc_xtheadmemidx_xtheadfmemidx -mabi=ilp32f" { 
target { rv32 } } } */
 
 #include "xtheadmemidx-helpers.h"
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c 
b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c
index bc50fa799e0..37ffe6afd53 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
-/* { dg-options "-march=rv64gc_xtheadmemidx_xtheadfmemidx" { target { rv64 } } 
} */
+/* { dg-options 

[committed 1/2] riscv: thead: Add support for the XTheadMemIdx ISA extension

2023-10-31 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadMemIdx ISA extension provides a additional load and store
instructions with new addressing modes.

The following memory accesses types are supported:
* load: b,bu,h,hu,w,wu,d
* store: b,h,w,d

The following addressing modes are supported:
* immediate offset with PRE_MODIFY or POST_MODIFY (22 instructions):
  l.ia, l.ib, s.ia, s.ib
* register offset with additional immediate offset (11 instructions):
  lr, sr
* zero-extended register offset with additional immediate offset
  (11 instructions): lur, sur

The RISC-V base ISA does not support index registers, so the changes
are kept separate from the RISC-V standard support as much as possible.

To combine the shift/multiply instructions into the memory access
instructions, this patch comes with a few insn_and_split optimizations
that allow the combiner to do this task.

Handling the different cases of extensions results in a couple of INSNs
that look redundant on first view, but they are just the equivalence
of what we already have for Zbb as well. The only difference is, that
we have much more load instructions.

We already have a constraint with the name 'th_f_fmv', therefore,
the new constraints follow this pattern and have the same length
as required ('th_m_mia', 'th_m_mib', 'th_m_mir', 'th_m_miu').

The added tests ensure that this feature won't regress without notice.
Testing: GCC regression test suite, GCC bootstrap build, and
SPEC CPU 2017 intrate (base) on C920.

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/constraints.md (th_m_mia): New constraint.
(th_m_mib): Likewise.
(th_m_mir): Likewise.
(th_m_miu): Likewise.
* config/riscv/riscv-protos.h (enum riscv_address_type):
Add new address types ADDRESS_REG_REG, ADDRESS_REG_UREG,
and ADDRESS_REG_WB and their documentation.
(struct riscv_address_info): Add new field 'shift' and
document the field usage for the new address types.
(riscv_valid_base_register_p): New prototype.
(th_memidx_legitimate_modify_p): Likewise.
(th_memidx_legitimate_index_p): Likewise.
(th_classify_address): Likewise.
(th_output_move): Likewise.
(th_print_operand_address): Likewise.
* config/riscv/riscv.cc (riscv_index_reg_class):
Return GR_REGS for XTheadMemIdx.
(riscv_regno_ok_for_index_p): Add support for XTheadMemIdx.
(riscv_classify_address): Call th_classify_address() on top.
(riscv_output_move): Call th_output_move() on top.
(riscv_print_operand_address): Call th_print_operand_address()
on top.
* config/riscv/riscv.h (HAVE_POST_MODIFY_DISP): New macro.
(HAVE_PRE_MODIFY_DISP): Likewise.
* config/riscv/riscv.md (zero_extendqi2): Disable
for XTheadMemIdx.
(*zero_extendqi2_internal): Convert to expand,
create INSN with same name and disable it for XTheadMemIdx.
(extendsidi2): Likewise.
(*extendsidi2_internal): Disable for XTheadMemIdx.
* config/riscv/thead.cc (valid_signed_immediate): New helper
function.
(th_memidx_classify_address_modify): New function.
(th_memidx_legitimate_modify_p): Likewise.
(th_memidx_output_modify): Likewise.
(is_memidx_mode): Likewise.
(th_memidx_classify_address_index): Likewise.
(th_memidx_legitimate_index_p): Likewise.
(th_memidx_output_index): Likewise.
(th_classify_address): Likewise.
(th_output_move): Likewise.
(th_print_operand_address): Likewise.
* config/riscv/thead.md (*th_memidx_operand): New splitter.
(*th_memidx_zero_extendqi2): New INSN.
(*th_memidx_extendsidi2): Likewise.
(*th_memidx_zero_extendsidi2): Likewise.
(*th_memidx_zero_extendhi2): Likewise.
(*th_memidx_extend2): Likewise.
(*th_memidx_bb_zero_extendsidi2): Likewise.
(*th_memidx_bb_zero_extendhi2): Likewise.
(*th_memidx_bb_extendhi2): Likewise.
(*th_memidx_bb_extendqi2): Likewise.
(TH_M_ANYI): New mode iterator.
(TH_M_NOEXTI): Likewise.
(*th_memidx_I_a): New combiner optimization.
(*th_memidx_I_b): Likewise.
(*th_memidx_I_c): Likewise.
(*th_memidx_US_a): Likewise.
(*th_memidx_US_b): Likewise.
(*th_memidx_US_c): Likewise.
(*th_memidx_UZ_a): Likewise.
(*th_memidx_UZ_b): Likewise.
(*th_memidx_UZ_c): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadmemidx-helpers.h: New test.
* gcc.target/riscv/xtheadmemidx-index-update.c: New test.
* gcc.target/riscv/xtheadmemidx-index-xtheadbb-update.c: New test.
* gcc.target/riscv/xtheadmemidx-index-xtheadbb.c: New test.
* gcc.target/riscv/xtheadmemidx-index.c: New test.
* gcc.target/riscv/xtheadmemidx-modify-xtheadbb.c: New test.
* gcc.target/riscv/xtheadmemidx-modify.c: New test.

[committed 2/2] riscv: thead: Add support for the XTheadFMemIdx ISA extension

2023-10-31 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadFMemIdx ISA extension provides additional load and store
instructions for floating-point registers with new addressing modes.

The following memory accesses types are supported:
* load/store: [w,d] (single-precision FP, double-precision FP)

The following addressing modes are supported:
* register offset with additional immediate offset (4 instructions):
  flr, fsr
* zero-extended register offset with additional immediate offset
  (4 instructions): flur, fsur

These addressing modes are also part of the similar XTheadMemIdx
ISA extension support, whose code is reused and extended to support
floating-point registers.

One challenge that this patch needs to solve are GP registers in FP-mode
(e.g. "(reg:DF a2)"), which cannot be handled by the XTheadFMemIdx
instructions. Such registers are the result of independent
optimizations, which can happen after register allocation.
This patch uses a simple but efficient method to address this:
add a dependency for XTheadMemIdx to XTheadFMemIdx optimizations.
This allows to use the instructions from XTheadMemIdx in case
of such registers.

The added tests ensure that this feature won't regress without notice.
Testing: GCC regression test suite and SPEC CPU 2017 intrate (base).

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_index_reg_class):
Return GR_REGS for XTheadFMemIdx.
(riscv_regno_ok_for_index_p): Add support for XTheadFMemIdx.
* config/riscv/riscv.h (HARDFP_REG_P): New macro.
* config/riscv/thead.cc (is_fmemidx_mode): New function.
(th_memidx_classify_address_index): Add support for XTheadFMemIdx.
(th_fmemidx_output_index): New function.
(th_output_move): Add support for XTheadFMemIdx.
* config/riscv/thead.md (TH_M_ANYF): New mode iterator.
(TH_M_NOEXTF): Likewise.
(*th_fmemidx_movsf_hardfloat): New INSN.
(*th_fmemidx_movdf_hardfloat_rv64): Likewise.
(*th_fmemidx_I_a): Likewise.
(*th_fmemidx_I_c): Likewise.
(*th_fmemidx_US_a): Likewise.
(*th_fmemidx_US_c): Likewise.
(*th_fmemidx_UZ_a): Likewise.
(*th_fmemidx_UZ_c): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadfmemidx-index-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c: New test.
* gcc.target/riscv/xtheadfmemidx-index.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.cc |   4 +-
 gcc/config/riscv/riscv.h  |   2 +
 gcc/config/riscv/thead.cc |  69 +++-
 gcc/config/riscv/thead.md | 161 ++
 .../riscv/xtheadfmemidx-index-update.c|  20 +++
 .../xtheadfmemidx-index-xtheadbb-update.c |  20 +++
 .../riscv/xtheadfmemidx-index-xtheadbb.c  |  22 +++
 .../gcc.target/riscv/xtheadfmemidx-index.c|  22 +++
 .../riscv/xtheadfmemidx-uindex-update.c   |  20 +++
 .../xtheadfmemidx-uindex-xtheadbb-update.c|  20 +++
 .../riscv/xtheadfmemidx-uindex-xtheadbb.c |  24 +++
 .../gcc.target/riscv/xtheadfmemidx-uindex.c   |  25 +++
 12 files changed, 404 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index de6d9734da0..0148a4f2e43 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1084,7 +1084,7 @@ riscv_regno_mode_ok_for_base_p (int regno,
 enum reg_class
 riscv_index_reg_class ()
 {
-  if (TARGET_XTHEADMEMIDX)
+  if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)
 return GR_REGS;
 
   return NO_REGS;
@@ -1097,7 +1097,7 @@ riscv_index_reg_class ()
 int
 riscv_regno_ok_for_index_p (int regno)
 {
-  if (TARGET_XTHEADMEMIDX)
+  if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)
 return riscv_regno_mode_ok_for_base_p (regno, VOIDmode, 1);
 
   return 0;
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index eb162abcb92..1e9813b4f39 

[PATCH v2 1/2] riscv: thead: Add support for the XTheadMemIdx ISA extension

2023-10-20 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadMemIdx ISA extension provides a additional load and store
instructions with new addressing modes.

The following memory accesses types are supported:
* load: b,bu,h,hu,w,wu,d
* store: b,h,w,d

The following addressing modes are supported:
* immediate offset with PRE_MODIFY or POST_MODIFY (22 instructions):
  l.ia, l.ib, s.ia, s.ib
* register offset with additional immediate offset (11 instructions):
  lr, sr
* zero-extended register offset with additional immediate offset
  (11 instructions): lur, sur

The RISC-V base ISA does not support index registers, so the changes
are kept separate from the RISC-V standard support as much as possible.

To combine the shift/multiply instructions into the memory access
instructions, this patch comes with a few insn_and_split optimizations
that allow the combiner to do this task.

Handling the different cases of extensions results in a couple of INSNs
that look redundant on first view, but they are just the equivalence
of what we already have for Zbb as well. The only difference is, that
we have much more load instructions.

We already have a constraint with the name 'th_f_fmv', therefore,
the new constraints follow this pattern and have the same length
as required ('th_m_mia', 'th_m_mib', 'th_m_mir', 'th_m_miu').

The added tests ensure that this feature won't regress without notice.
Testing: GCC regression test suite, GCC bootstrap build, and
SPEC CPU 2017 intrate (base) on C920.

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/constraints.md (th_m_mia): New constraint.
(th_m_mib): Likewise.
(th_m_mir): Likewise.
(th_m_miu): Likewise.
* config/riscv/riscv-protos.h (enum riscv_address_type):
Add new address types ADDRESS_REG_REG, ADDRESS_REG_UREG,
and ADDRESS_REG_WB and their documentation.
(struct riscv_address_info): Add new field 'shift' and
document the field usage for the new address types.
(riscv_valid_base_register_p): New prototype.
(th_memidx_legitimate_modify_p): Likewise.
(th_memidx_legitimate_index_p): Likewise.
(th_classify_address): Likewise.
(th_output_move): Likewise.
(th_print_operand_address): Likewise.
* config/riscv/riscv.cc (riscv_index_reg_class):
Return GR_REGS for XTheadMemIdx.
(riscv_regno_ok_for_index_p): Add support for XTheadMemIdx.
(riscv_classify_address): Call th_classify_address() on top.
(riscv_output_move): Call th_output_move() on top.
(riscv_print_operand_address): Call th_print_operand_address()
on top.
* config/riscv/riscv.h (HAVE_POST_MODIFY_DISP): New macro.
(HAVE_PRE_MODIFY_DISP): Likewise.
* config/riscv/riscv.md (zero_extendqi2): Disable
for XTheadMemIdx.
(*zero_extendqi2_internal): Convert to expand,
create INSN with same name and disable it for XTheadMemIdx.
(extendsidi2): Likewise.
(*extendsidi2_internal): Disable for XTheadMemIdx.
* config/riscv/thead.cc (valid_signed_immediate): New helper
function.
(th_memidx_classify_address_modify): New function.
(th_memidx_legitimate_modify_p): Likewise.
(th_memidx_output_modify): Likewise.
(is_memidx_mode): Likewise.
(th_memidx_classify_address_index): Likewise.
(th_memidx_legitimate_index_p): Likewise.
(th_memidx_output_index): Likewise.
(th_classify_address): Likewise.
(th_output_move): Likewise.
(th_print_operand_address): Likewise.
* config/riscv/thead.md (*th_memidx_operand): New splitter.
(*th_memidx_zero_extendqi2): New INSN.
(*th_memidx_extendsidi2): Likewise.
(*th_memidx_zero_extendsidi2): Likewise.
(*th_memidx_zero_extendhi2): Likewise.
(*th_memidx_extend2): Likewise.
(*th_memidx_bb_zero_extendsidi2): Likewise.
(*th_memidx_bb_zero_extendhi2): Likewise.
(*th_memidx_bb_extendhi2): Likewise.
(*th_memidx_bb_extendqi2): Likewise.
(TH_M_ANYI): New mode iterator.
(TH_M_NOEXTI): Likewise.
(*th_memidx_I_a): New combiner optimization.
(*th_memidx_I_b): Likewise.
(*th_memidx_I_c): Likewise.
(*th_memidx_US_a): Likewise.
(*th_memidx_US_b): Likewise.
(*th_memidx_US_c): Likewise.
(*th_memidx_UZ_a): Likewise.
(*th_memidx_UZ_b): Likewise.
(*th_memidx_UZ_c): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadmemidx-helpers.h: New test.
* gcc.target/riscv/xtheadmemidx-index-update.c: New test.
* gcc.target/riscv/xtheadmemidx-index-xtheadbb-update.c: New test.
* gcc.target/riscv/xtheadmemidx-index-xtheadbb.c: New test.
* gcc.target/riscv/xtheadmemidx-index.c: New test.
* gcc.target/riscv/xtheadmemidx-modify-xtheadbb.c: New test.
* gcc.target/riscv/xtheadmemidx-modify.c: New test.

[PATCH v2 2/2] riscv: thead: Add support for the XTheadFMemIdx ISA extension

2023-10-20 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadFMemIdx ISA extension provides additional load and store
instructions for floating-point registers with new addressing modes.

The following memory accesses types are supported:
* load/store: [w,d] (single-precision FP, double-precision FP)

The following addressing modes are supported:
* register offset with additional immediate offset (4 instructions):
  flr, fsr
* zero-extended register offset with additional immediate offset
  (4 instructions): flur, fsur

These addressing modes are also part of the similar XTheadMemIdx
ISA extension support, whose code is reused and extended to support
floating-point registers.

One challenge that this patch needs to solve are GP registers in FP-mode
(e.g. "(reg:DF a2)"), which cannot be handled by the XTheadFMemIdx
instructions. Such registers are the result of independent
optimizations, which can happen after register allocation.
This patch uses a simple but efficient method to address this:
add a dependency for XTheadMemIdx to XTheadFMemIdx optimizations.
This allows to use the instructions from XTheadMemIdx in case
of such registers.

The added tests ensure that this feature won't regress without notice.
Testing: GCC regression test suite and SPEC CPU 2017 intrate (base).

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_index_reg_class):
Return GR_REGS for XTheadFMemIdx.
(riscv_regno_ok_for_index_p): Add support for XTheadFMemIdx.
* config/riscv/riscv.h (HARDFP_REG_P): New macro.
* config/riscv/thead.cc (is_fmemidx_mode): New function.
(th_memidx_classify_address_index): Add support for XTheadFMemIdx.
(th_fmemidx_output_index): New function.
(th_output_move): Add support for XTheadFMemIdx.
* config/riscv/thead.md (TH_M_ANYF): New mode iterator.
(TH_M_NOEXTF): Likewise.
(*th_fmemidx_movsf_hardfloat): New INSN.
(*th_fmemidx_movdf_hardfloat_rv64): Likewise.
(*th_fmemidx_I_a): Likewise.
(*th_fmemidx_I_c): Likewise.
(*th_fmemidx_US_a): Likewise.
(*th_fmemidx_US_c): Likewise.
(*th_fmemidx_UZ_a): Likewise.
(*th_fmemidx_UZ_c): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadfmemidx-index-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c: New test.
* gcc.target/riscv/xtheadfmemidx-index.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex.c: New test.
---
 gcc/config/riscv/riscv.cc |   4 +-
 gcc/config/riscv/riscv.h  |   2 +
 gcc/config/riscv/thead.cc |  65 ++-
 gcc/config/riscv/thead.md | 161 ++
 .../riscv/xtheadfmemidx-index-update.c|  20 +++
 .../xtheadfmemidx-index-xtheadbb-update.c |  20 +++
 .../riscv/xtheadfmemidx-index-xtheadbb.c  |  22 +++
 .../gcc.target/riscv/xtheadfmemidx-index.c|  22 +++
 .../riscv/xtheadfmemidx-uindex-update.c   |  20 +++
 .../xtheadfmemidx-uindex-xtheadbb-update.c|  20 +++
 .../riscv/xtheadfmemidx-uindex-xtheadbb.c |  24 +++
 .../gcc.target/riscv/xtheadfmemidx-uindex.c   |  25 +++
 12 files changed, 400 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 7053b76..2ecdd521b75 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1084,7 +1084,7 @@ riscv_regno_mode_ok_for_base_p (int regno,
 enum reg_class
 riscv_index_reg_class ()
 {
-  if (TARGET_XTHEADMEMIDX)
+  if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)
 return GR_REGS;
 
   return NO_REGS;
@@ -1097,7 +1097,7 @@ riscv_index_reg_class ()
 int
 riscv_regno_ok_for_index_p (int regno)
 {
-  if (TARGET_XTHEADMEMIDX)
+  if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)
 return riscv_regno_mode_ok_for_base_p (regno, VOIDmode, 1);
 
   return 0;
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index eb162abcb92..1e9813b4f39 100644
--- a/gcc/config/riscv/riscv.h

[PATCH v2 0/2] riscv: Adding support for XTHead(F)MemIdx

2023-10-20 Thread Christoph Muellner
From: Christoph Müllner 

This two patches add support for the XTheadMemIdx
and XTheadFMemIdx ISA extensions, that support additional
addressing modes. The extensions are implemented in a range
of T-Head cores (e.g. C906, C910, C920) and are available
on the market for quite some time.

The ISA spec can be found here:
  https://github.com/T-head-Semi/thead-extension-spec

An initial version of these patches has been sent a while ago.
Jeff Law suggested to use INSNs instead of peepholes to let
the combiner do the optimization.  This is the major change
that this patches have seen.

Both patches come with their own tests and don't introduce
any regressions for RV32 or RV64.  Further the patches did
not show any issues with SPEC CPU 2017 (base) using
multiple combinations of XThead* extensions.
The patches have been tested on QEMU and a C920-based machine.

Changes in v2:
* Convert peepholes to INSNs (let the combiner do the work)
* Enable XTheadFMemIdx optimizations only if XTheadMemIdx is available
  (to address the case when GP regs are used in FP mode (e.g. (reg:DF a2))
* Add a insn_and_split (th_memidx_operand) to address the case when
  reload splits off the index calculation.

Christoph Müllner (2):
  riscv: thead: Add support for the XTheadMemIdx ISA extension
  riscv: thead: Add support for the XTheadFMemIdx ISA extension

 gcc/config/riscv/constraints.md   |  26 +
 gcc/config/riscv/riscv-protos.h   |  29 +
 gcc/config/riscv/riscv.cc |  24 +-
 gcc/config/riscv/riscv.h  |   6 +-
 gcc/config/riscv/riscv.md |  26 +-
 gcc/config/riscv/thead.cc | 485 ++
 gcc/config/riscv/thead.md | 594 +-
 .../riscv/xtheadfmemidx-index-update.c|  20 +
 .../xtheadfmemidx-index-xtheadbb-update.c |  20 +
 .../riscv/xtheadfmemidx-index-xtheadbb.c  |  22 +
 .../gcc.target/riscv/xtheadfmemidx-index.c|  22 +
 .../riscv/xtheadfmemidx-uindex-update.c   |  20 +
 .../xtheadfmemidx-uindex-xtheadbb-update.c|  20 +
 .../riscv/xtheadfmemidx-uindex-xtheadbb.c |  24 +
 .../gcc.target/riscv/xtheadfmemidx-uindex.c   |  25 +
 .../gcc.target/riscv/xtheadmemidx-helpers.h   | 152 +
 .../riscv/xtheadmemidx-index-update.c |  27 +
 .../xtheadmemidx-index-xtheadbb-update.c  |  27 +
 .../riscv/xtheadmemidx-index-xtheadbb.c   |  36 ++
 .../gcc.target/riscv/xtheadmemidx-index.c |  36 ++
 .../riscv/xtheadmemidx-modify-xtheadbb.c  |  74 +++
 .../gcc.target/riscv/xtheadmemidx-modify.c|  74 +++
 .../riscv/xtheadmemidx-uindex-update.c|  27 +
 .../xtheadmemidx-uindex-xtheadbb-update.c |  27 +
 .../riscv/xtheadmemidx-uindex-xtheadbb.c  |  44 ++
 .../gcc.target/riscv/xtheadmemidx-uindex.c|  44 ++
 26 files changed, 1917 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-xtheadbb-update.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-index-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-index.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadmemidx-modify-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-modify.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-xtheadbb-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-uindex.c

-- 
2.41.0



[PATCH v2] RISC-V: Make xtheadcondmov-indirect tests robust against instruction reordering

2023-10-12 Thread Christoph Muellner
From: Christoph Müllner 

Fixes: c1bc7513b1d7 ("RISC-V: const: hide mvconst splitter from IRA")

A recent change broke the xtheadcondmov-indirect tests, because the order of
emitted instructions changed. Since the test is too strict when testing for
a fixed instruction order, let's change the tests to simply count instruction,
like it is done for similar tests.

Reported-by: Patrick O'Neill 
Signed-off-by: Christoph Müllner 

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-indirect.c: Make robust against
instruction reordering.

Signed-off-by: Christoph Müllner 
---
 .../gcc.target/riscv/xtheadcondmov-indirect.c | 89 ++-
 1 file changed, 29 insertions(+), 60 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c
index c3253ba5239..427c9c1a41e 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c
@@ -1,16 +1,11 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv32gc_xtheadcondmov -fno-sched-pressure" { target { 
rv32 } } } */
-/* { dg-options "-march=rv64gc_xtheadcondmov -fno-sched-pressure" { target { 
rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Os" "-Og" "-Oz" "-flto" } } */
-/* { dg-final { check-function-bodies "**" "" } } */
 
-/*
-** ConEmv_imm_imm_reg:
-** addia[0-9]+,a[0-9]+,-1000
-** li  a[0-9]+,10
-** th\.mvnez   a[0-9]+,a[0-9]+,a[0-9]+
-** ret
-*/
+/* addi aX, aX, -1000
+   li aX, 10
+   th.mvnez aX, aX, aX  */
 int ConEmv_imm_imm_reg(int x, int y)
 {
   if (x == 1000)
@@ -18,13 +13,8 @@ int ConEmv_imm_imm_reg(int x, int y)
   return y;
 }
 
-/*
-** ConEmv_imm_reg_reg:
-** addia[0-9]+,a[0-9]+,-1000
-** th.mveqza[0-9]+,a[0-9]+,a[0-9]+
-** mv  a[0-9]+,a[0-9]+
-** ret
-*/
+/* addiaX, aX, -1000
+   th.mveqz aX, aX, aX  */
 int ConEmv_imm_reg_reg(int x, int y, int z)
 {
   if (x == 1000)
@@ -32,13 +22,9 @@ int ConEmv_imm_reg_reg(int x, int y, int z)
   return z;
 }
 
-/*
-** ConEmv_reg_imm_reg:
-** sub a[0-9]+,a[0-9]+,a[0-9]+
-** li  a[0-9]+,10
-** th.mvneza[0-9]+,a[0-9]+,a[0-9]+
-** ret
-*/
+/* sub aX, aX, aX
+   li aX, 10
+   th.mvnez aX, aX, aX  */
 int ConEmv_reg_imm_reg(int x, int y, int z)
 {
   if (x == y)
@@ -46,13 +32,8 @@ int ConEmv_reg_imm_reg(int x, int y, int z)
   return z;
 }
 
-/*
-** ConEmv_reg_reg_reg:
-** sub a[0-9]+,a[0-9]+,a[0-9]+
-** th.mveqza[0-9]+,a[0-9]+,a[0-9]+
-** mv  a[0-9]+,a[0-9]+
-** ret
-*/
+/* sub aX, aX, aX
+   th.mveqz aX, aX, aX  */
 int ConEmv_reg_reg_reg(int x, int y, int z, int n)
 {
   if (x == y)
@@ -60,14 +41,10 @@ int ConEmv_reg_reg_reg(int x, int y, int z, int n)
   return n;
 }
 
-/*
-** ConNmv_imm_imm_reg:
-** addia[0-9]+,a[0-9]+,-1000+
-** li  a[0-9]+,9998336+
-** addia[0-9]+,a[0-9]+,1664+
-** th.mveqza[0-9]+,a[0-9]+,a[0-9]+
-** ret
-*/
+/* addi aX, aX, -1000
+   li aX, 9998336
+   addi aX, aX, 1664
+   th.mveqz aX, aX, aX  */
 int ConNmv_imm_imm_reg(int x, int y)
 {
   if (x != 1000)
@@ -75,13 +52,8 @@ int ConNmv_imm_imm_reg(int x, int y)
   return y;
 }
 
-/*
-**ConNmv_imm_reg_reg:
-** addia[0-9]+,a[0-9]+,-1000+
-** th.mvneza[0-9]+,a[0-9]+,a[0-9]+
-** mv  a[0-9]+,a[0-9]+
-** ret
-*/
+/* addi aX, aX, 1000
+   th.mvnez aX, aX, aX  */
 int ConNmv_imm_reg_reg(int x, int y, int z)
 {
   if (x != 1000)
@@ -89,13 +61,9 @@ int ConNmv_imm_reg_reg(int x, int y, int z)
   return z;
 }
 
-/*
-**ConNmv_reg_imm_reg:
-** sub a[0-9]+,a[0-9]+,a[0-9]+
-** li  a[0-9]+,10+
-** th.mveqza[0-9]+,a[0-9]+,a[0-9]+
-** ret
-*/
+/* sub aX, aX, aX
+   li aX, 10
+   th.mveqz aX, aX, aX  */
 int ConNmv_reg_imm_reg(int x, int y, int z)
 {
   if (x != y)
@@ -103,16 +71,17 @@ int ConNmv_reg_imm_reg(int x, int y, int z)
   return z;
 }
 
-/*
-**ConNmv_reg_reg_reg:
-** sub a[0-9]+,a[0-9]+,a[0-9]+
-** th.mvneza[0-9]+,a[0-9]+,a[0-9]+
-** mv  a[0-9]+,a[0-9]+
-** ret
-*/
+/* sub aX, aX, aX
+   th.mvnez aX, aX, aX  */
 int ConNmv_reg_reg_reg(int x, int y, int z, int n)
 {
   if (x != y)
 return z;
   return n;
 }
+
+/* { dg-final { scan-assembler-times "addi\t" 5 } } */
+/* { dg-final { scan-assembler-times "li\t" 4 } } */
+/* { dg-final { scan-assembler-times "sub\t" 4 } } */
+/* { dg-final { scan-assembler-times "th.mveqz\t" 4 } } */
+/* { dg-final { scan-assembler-times "th.mvnez\t" 4 } } */
-- 
2.41.0



[COMMITTED] MAINTAINERS: Add myself to write after approval

2023-10-10 Thread Christoph Muellner
From: Christoph Müllner 

Signed-off-by: Christoph Müllner 

ChangeLog:

* MAINTAINERS: Add myself.
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e9154878517..aa441de5332 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -576,6 +576,7 @@ Catherine Moore 

 James A. Morrison  
 Brooks Moses   
 Dirk Mueller   
+Christoph Müllner  
 Phil Muldoon   
 Gaius Mulley   
 Steven Munroe  
-- 
2.41.0



[PATCH] RISC-V: Make xtheadcondmov-indirect tests robust against instruction reordering

2023-10-09 Thread Christoph Muellner
From: Christoph Müllner 

Fixes: c1bc7513b1d7 ("RISC-V: const: hide mvconst splitter from IRA")

A recent change broke the xtheadcondmov-indirect tests, because the order of
emitted instructions changed. Since the test is too strict when testing for
a fixed instruction order, let's change the tests to simply count instruction,
like it is done for similar tests.

Reported-by: Patrick O'Neill 
Signed-off-by: Christoph Müllner 

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-indirect.c: Make robust against
instruction reordering.

Signed-off-by: Christoph Müllner 
---
 .../gcc.target/riscv/xtheadcondmov-indirect.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c
index c3253ba5239..eba1b86137b 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c
@@ -1,8 +1,7 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv32gc_xtheadcondmov -fno-sched-pressure" { target { 
rv32 } } } */
-/* { dg-options "-march=rv64gc_xtheadcondmov -fno-sched-pressure" { target { 
rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Os" "-Og" "-Oz" "-flto" } } */
-/* { dg-final { check-function-bodies "**" "" } } */
 
 /*
 ** ConEmv_imm_imm_reg:
@@ -116,3 +115,9 @@ int ConNmv_reg_reg_reg(int x, int y, int z, int n)
 return z;
   return n;
 }
+
+/* { dg-final { scan-assembler-times "addi\t" 5 } } */
+/* { dg-final { scan-assembler-times "li\t" 4 } } */
+/* { dg-final { scan-assembler-times "sub\t" 4 } } */
+/* { dg-final { scan-assembler-times "th.mveqz\t" 4 } } */
+/* { dg-final { scan-assembler-times "th.mvnez\t" 4 } } */
-- 
2.41.0



[PATCH] riscv: bitmanip: Remove duplicate zero_extendhi2 pattern

2023-09-08 Thread Christoph Muellner
From: Christoph Müllner 

We currently have two identical zero_extendhi2 patterns:
* '*zero_extendhi2_zbb'
* '*zero_extendhi2_bitmanip'

This patch removes the *_zbb pattern and ensures that all sign- and
zero-extensions use the postfix '_bitmanip'.

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/bitmanip.md (*extend2_zbb):
Rename postfix to _bitmanip.
(*extend2_bitmanip): Renamed pattern.
(*zero_extendhi2_zbb): Remove duplicated pattern.
---
 gcc/config/riscv/bitmanip.md | 13 +
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 1544ef4e125..431b3292213 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -283,7 +283,7 @@ (define_insn "*zero_extendhi2_bitmanip"
   [(set_attr "type" "bitmanip,load")
(set_attr "mode" "")])
 
-(define_insn "*extend2_zbb"
+(define_insn "*extend2_bitmanip"
   [(set (match_operand:SUPERQI   0 "register_operand" "=r,r")
(sign_extend:SUPERQI
(match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
@@ -294,17 +294,6 @@ (define_insn "*extend2_zbb"
   [(set_attr "type" "bitmanip,load")
(set_attr "mode" "")])
 
-(define_insn "*zero_extendhi2_zbb"
-  [(set (match_operand:GPR0 "register_operand" "=r,r")
-   (zero_extend:GPR
-   (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
-  "TARGET_ZBB"
-  "@
-   zext.h\t%0,%1
-   lhu\t%0,%1"
-  [(set_attr "type" "bitmanip,load")
-   (set_attr "mode" "HI")])
-
 (define_expand "rotrdi3"
   [(set (match_operand:DI 0 "register_operand")
(rotatert:DI (match_operand:DI 1 "register_operand")
-- 
2.41.0



[PATCH] riscv: thead: Fix mode attribute for extension patterns

2023-09-08 Thread Christoph Muellner
From: Christoph Müllner 

The mode attribute of an extension pattern is usually set to the target type.
Let's follow this convention consistently for xtheadbb.

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/thead.md: Use more appropriate mode attributes
for extensions.
---
 gcc/config/riscv/thead.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 05d1b32bd94..2287b752ea1 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -101,7 +101,7 @@ (define_insn "*zero_extendsidi2_th_extu"
th.extu\t%0,%1,31,0
lwu\t%0,%1"
   [(set_attr "type" "bitmanip,load")
-   (set_attr "mode" "SI")])
+   (set_attr "mode" "DI")])
 
 (define_insn "*zero_extendhi2_th_extu"
   [(set (match_operand:GPR 0 "register_operand" "=r,r")
@@ -111,7 +111,7 @@ (define_insn "*zero_extendhi2_th_extu"
th.extu\t%0,%1,15,0
lhu\t%0,%1"
   [(set_attr "type" "bitmanip,load")
-   (set_attr "mode" "HI")])
+   (set_attr "mode" "")])
 
 (define_insn "*th_clz2"
   [(set (match_operand:X 0 "register_operand" "=r")
-- 
2.41.0



[PATCH] riscv: xtheadbb: Fix extendqi insn

2023-09-08 Thread Christoph Muellner
From: Christoph Müllner 

Recently three SPEC CPU 2017 benchmarks broke when using xtheadbb:
* 500.perlbench_r
* 525.x264_r
* 557.xz_r

Tracing the issue down revealed, that we emit a 'th.ext xN,xN,15,0'
for a extendqi insn, which is obviously wrong.
This patch splits the common 'extend2_th_ext'
insn into two 'extendqi' and 'extendhi' insns,
which emit the right extension instruction.
Additionally, this patch adds test cases for these insns.

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/thead.md (*extend2_th_ext):
Remove broken INSN.
(*extendhi2_th_ext): New INSN.
(*extendqi2_th_ext): New INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-ext-2.c: New test.
* gcc.target/riscv/xtheadbb-ext-3.c: New test.
---
 gcc/config/riscv/thead.md   | 17 ++---
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext-2.c | 12 
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext-3.c | 12 
 3 files changed, 38 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext-3.c

diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 29f98dec3a8..05d1b32bd94 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -58,14 +58,25 @@ (define_insn "*th_ext4"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
 
-(define_insn "*extend2_th_ext"
+(define_insn "*extendhi2_th_ext"
   [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
(sign_extend:SUPERQI
-   (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
+   (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
   "TARGET_XTHEADBB"
   "@
th.ext\t%0,%1,15,0
-   l\t%0,%1"
+   lh\t%0,%1"
+  [(set_attr "type" "bitmanip,load")
+   (set_attr "mode" "")])
+
+(define_insn "*extendqi2_th_ext"
+  [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
+   (sign_extend:SUPERQI
+   (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
+  "TARGET_XTHEADBB"
+  "@
+   th.ext\t%0,%1,7,0
+   lb\t%0,%1"
   [(set_attr "type" "bitmanip,load")
(set_attr "mode" "")])
 
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-2.c 
b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-2.c
new file mode 100644
index 000..4645b9c56df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */
+
+signed long extqi(signed char i)
+{
+return --i;
+}
+
+/* { dg-final { scan-assembler "th.ext\ta\[0-9\]+,a\[0-9\]+,7,0" } } */
+/* { dg-final { scan-assembler-not "th.ext\ta\[0-9\]+,a\[0-9\]+,15,0" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-3.c 
b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-3.c
new file mode 100644
index 000..2c9ebbc563a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */
+
+signed long exthi(signed short i)
+{
+return --i;
+}
+
+/* { dg-final { scan-assembler "th.ext\ta\[0-9\]+,a\[0-9\]+,15,0" } } */
+/* { dg-final { scan-assembler-not "th.ext\ta\[0-9\]+,a\[0-9\]+,7,0" } } */
-- 
2.41.0



[PATCH v2 1/2] riscv: Add support for strlen inline expansion

2023-09-06 Thread Christoph Muellner
From: Christoph Müllner 

This patch implements the expansion of the strlen builtin for RV32/RV64
for xlen-aligned aligned strings if Zbb or XTheadBb instructions are available.
The inserted sequences are:

rv32gc_zbb (RV64 is similar):
  add a3,a0,4
  li  a4,-1
.L1:  lw  a5,0(a0)
  add a0,a0,4
  orc.b   a5,a5
  beq a5,a4,.L1
  not a5,a5
  ctz a5,a5
  srl a5,a5,0x3
  add a0,a0,a5
  sub a0,a0,a3

rv64gc_xtheadbb (RV32 is similar):
  add   a4,a0,8
.L2:  lda5,0(a0)
  add   a0,a0,8
  th.tstnbz a5,a5
  beqz  a5,.L2
  th.reva5,a5
  th.ff1a5,a5
  srl   a5,a5,0x3
  add   a0,a0,a5
  sub   a0,a0,a4

This allows to inline calls to strlen(), with optimized code for
xlen-aligned strings, resulting in the following benefits over
a call to libc:
* no call/ret instructions
* no stack frame allocation
* no register saving/restoring
* no alignment test

The inlining mechanism is gated by a new switch ('-minline-strlen')
and by the variable 'optimize_size'.

Tested using the glibc string tests.

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config.gcc: Add new object riscv-string.o.
riscv-string.cc.
* config/riscv/riscv-protos.h (riscv_expand_strlen):
New function.
* config/riscv/riscv.md (strlen): New expand INSN.
* config/riscv/riscv.opt: New flag 'minline-strlen'.
* config/riscv/t-riscv: Add new object riscv-string.o.
* config/riscv/thead.md (th_rev2): Export INSN name.
(th_rev2): Likewise.
(th_tstnbz2): New INSN.
* doc/invoke.texi: Document '-minline-strlen'.
* emit-rtl.cc (emit_likely_jump_insn): New helper function.
(emit_unlikely_jump_insn): Likewise.
* rtl.h (emit_likely_jump_insn): New prototype.
(emit_unlikely_jump_insn): Likewise.
* config/riscv/riscv-string.cc: New file.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-strlen-unaligned.c: New test.
* gcc.target/riscv/xtheadbb-strlen.c: New test.
* gcc.target/riscv/zbb-strlen-disabled-2.c: New test.
* gcc.target/riscv/zbb-strlen-disabled.c: New test.
* gcc.target/riscv/zbb-strlen-unaligned.c: New test.
* gcc.target/riscv/zbb-strlen.c: New test.
---
 gcc/config.gcc|   3 +-
 gcc/config/riscv/riscv-protos.h   |   3 +
 gcc/config/riscv/riscv-string.cc  | 183 ++
 gcc/config/riscv/riscv.md |  28 +++
 gcc/config/riscv/riscv.opt|   4 +
 gcc/config/riscv/t-riscv  |   6 +
 gcc/config/riscv/thead.md |   9 +-
 gcc/doc/invoke.texi   |  11 +-
 gcc/emit-rtl.cc   |  24 +++
 gcc/rtl.h |   2 +
 .../riscv/xtheadbb-strlen-unaligned.c |  14 ++
 .../gcc.target/riscv/xtheadbb-strlen.c|  19 ++
 .../gcc.target/riscv/zbb-strlen-disabled-2.c  |  15 ++
 .../gcc.target/riscv/zbb-strlen-disabled.c|  15 ++
 .../gcc.target/riscv/zbb-strlen-unaligned.c   |  14 ++
 gcc/testsuite/gcc.target/riscv/zbb-strlen.c   |  19 ++
 16 files changed, 366 insertions(+), 3 deletions(-)
 create mode 100644 gcc/config/riscv/riscv-string.cc
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-strlen-unaligned.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-strlen.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen-disabled-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen-disabled.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen-unaligned.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen.c

diff --git a/gcc/config.gcc b/gcc/config.gcc
index b2fe7c7ceef..aff6b6a5601 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -530,7 +530,8 @@ pru-*-*)
;;
 riscv*)
cpu_type=riscv
-   extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o 
riscv-shorten-memrefs.o riscv-selftests.o riscv-v.o riscv-vsetvl.o 
riscv-vector-costs.o"
+   extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o 
riscv-shorten-memrefs.o riscv-selftests.o riscv-string.o"
+   extra_objs="${extra_objs} riscv-v.o riscv-vsetvl.o riscv-vector-costs.o"
extra_objs="${extra_objs} riscv-vector-builtins.o 
riscv-vector-builtins-shapes.o riscv-vector-builtins-bases.o"
extra_objs="${extra_objs} thead.o"
d_target_objs="riscv-d.o"
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 6dbf6b9f943..b060d047f01 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -517,6 +517,9 @@ const unsigned int RISCV_BUILTIN_SHIFT = 1;
 /* Mask that selects the riscv_builtin_class part of a function code.  */
 const unsigned int RISCV_BUILTIN_CLASS = (1 << RISCV_BUILTIN_SHIFT) - 1;
 
+/* Routines implemented 

[PATCH v2 2/2] riscv: Add support for str(n)cmp inline expansion

2023-09-06 Thread Christoph Muellner
From: Christoph Müllner 

This patch implements expansions for the cmpstrsi and cmpstrnsi
builtins for RV32/RV64 for xlen-aligned strings if Zbb or XTheadBb
instructions are available.  The expansion basically emits a comparison
sequence which compares XLEN bits per step if possible.

This allows to inline calls to strcmp() and strncmp() if both strings
are xlen-aligned.  For strncmp() the length parameter needs to be known.
The benefits over calls to libc are:
* no call/ret instructions
* no stack frame allocation
* no register saving/restoring
* no alignment tests

The inlining mechanism is gated by a new switches ('-minline-strcmp' and
'-minline-strncmp') and by the variable 'optimize_size'.
The amount of emitted unrolled loop iterations can be controlled by the
parameter '--param=riscv-strcmp-inline-limit=N', which defaults to 64.

The comparision sequence is inspired by the strcmp example
in the appendix of the Bitmanip specification (incl. the fast
result calculation in case the first word does not contain
a NULL byte).  Additional inspiration comes from rs6000-string.c.

The emitted sequence is not triggering any readahead pagefault issues,
because only aligned strings are accessed by aligned xlen-loads.

This patch has been tested using the glibc string tests on QEMU:
* rv64gc_zbb/rv64gc_xtheadbb with riscv-strcmp-inline-limit=64
* rv64gc_zbb/rv64gc_xtheadbb with riscv-strcmp-inline-limit=8
* rv32gc_zbb/rv32gc_xtheadbb with riscv-strcmp-inline-limit=64

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/bitmanip.md (*_not): Export INSN name.
(_not3): Likewise.
* config/riscv/riscv-protos.h (riscv_expand_strcmp): New
prototype.
* config/riscv/riscv-string.cc (GEN_EMIT_HELPER3): New helper
macros.
(GEN_EMIT_HELPER2): Likewise.
(emit_strcmp_scalar_compare_byte): New function.
(emit_strcmp_scalar_compare_subword): Likewise.
(emit_strcmp_scalar_compare_word): Likewise.
(emit_strcmp_scalar_load_and_compare): Likewise.
(emit_strcmp_scalar_call_to_libc): Likewise.
(emit_strcmp_scalar_result_calculation_nonul): Likewise.
(emit_strcmp_scalar_result_calculation): Likewise.
(riscv_expand_strcmp_scalar): Likewise.
(riscv_expand_strcmp): Likewise.
* config/riscv/riscv.md (*slt_): Export
INSN name.
(@slt_3): Likewise.
(cmpstrnsi): Invoke expansion function for str(n)cmp.
(cmpstrsi): Likewise.
* config/riscv/riscv.opt: Add new parameter
'-mstring-compare-inline-limit'.
* doc/invoke.texi: Document new parameter
'-mstring-compare-inline-limit'.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-strcmp-unaligned.c: New test.
* gcc.target/riscv/xtheadbb-strcmp.c: New test.
* gcc.target/riscv/zbb-strcmp-disabled-2.c: New test.
* gcc.target/riscv/zbb-strcmp-disabled.c: New test.
* gcc.target/riscv/zbb-strcmp-unaligned.c: New test.
* gcc.target/riscv/zbb-strcmp.c: New test.
---
 gcc/config/riscv/bitmanip.md  |   2 +-
 gcc/config/riscv/riscv-protos.h   |   1 +
 gcc/config/riscv/riscv-string.cc  | 411 ++
 gcc/config/riscv/riscv.md |  44 +-
 gcc/config/riscv/riscv.opt|  12 +
 gcc/doc/invoke.texi   |  20 +-
 .../gcc.target/riscv/xtheadbb-strcmp.c|  57 +++
 .../gcc.target/riscv/zbb-strcmp-disabled-2.c  |  38 ++
 .../gcc.target/riscv/zbb-strcmp-disabled.c|  38 ++
 .../gcc.target/riscv/zbb-strcmp-limit.c   |  57 +++
 .../gcc.target/riscv/zbb-strcmp-unaligned.c   |  38 ++
 gcc/testsuite/gcc.target/riscv/zbb-strcmp.c   |  57 +++
 12 files changed, 772 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-strcmp.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp-disabled-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp-disabled.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp-limit.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp-unaligned.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 1544ef4e125..1e90636dd60 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -206,7 +206,7 @@ (define_expand "popcount2"
(popcount:GPR (match_operand:GPR 1 "register_operand")))]
   "TARGET_ZBB")
 
-(define_insn "*_not"
+(define_insn "_not3"
   [(set (match_operand:X 0 "register_operand" "=r")
 (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
 (match_operand:X 2 "register_operand" "r")))]
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index b060d047f01..0006fe0564e 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ 

[PATCH v2 0/2] riscv: Introduce strlen/strcmp/strncmp inline expansion

2023-09-06 Thread Christoph Muellner
From: Christoph Müllner 

This series introduces strlen/strcmp/strncmp inline expansion for Zbb/XTheadBb.

In the last months, glibc as well as the Linux kernel merged changes for
optimized string processing for RISC-V. The instruction, which enables
optimized string routines is Zbb's orc.b (or T-Head's th.tstnbz) instruction.

This patch attempts to add optimized string processing to GCC with the
following properties:
* strlen: inline a loop if the string is xlen-aligned
* strcmp/strncmp: inline a peeled comparison loop sequence if both strings
  are xlen-aligned

I've already posted the idea in a previous series last November
(therefore, this series is called 'v2'):
* https://gcc.gnu.org/pipermail/gcc-patches/2022-November/605996.html
* https://gcc.gnu.org/pipermail/gcc-patches/2022-November/605998.html

Back then, there were a couple of comments, which have been addressed,
but the str(n)cmp patch has been restructured to make the code easier
to digest.  In total the following changes are made:
* Address Jeff's comments for the strlen patch
* Change str(n)cmp flags according to Kito's comments
* Ensure that all flags are documented
* Break str(n)cmp expansion into several functions
* Add support for XTheadBb's th.tstnbz

I have not introduced "-minline-str[n]cmp=[bitmanip|vector|auto]"
or "-mstringop-strategy=alg" because we only have one bitmanip/scalar
expansion.  But it is possible to add this in the future (or not and
decide based on mtune).

By default all optimizations are disabled, so there should be no risk
of regressions.

Testing was done using the following strategy:
* Enablement/flag tests are part of the patches
* Correctness was tested using qemu-user with glibc's string tests compiled for:
** rv64gc (baseline) QEMU_CPU=rv64
** rv64gc_zbb (limit=64) QEMU_CPU=rv64,zbb=false (must fail)
** rv64gc_zbb (limit=64) QEMU_CPU=rv64,zbb=true
** rv64gc_zbb (limit=32) QEMU_CPU=rv64,zbb=true
** rv64gc_xtheadbb (limit=64) QEMU_CPU=rv64 (must fail)
** rv64gc_xtheadbb (limit=64) QEMU_CPU=thead-c906
** rv64gc_xtheadbb (limit=8) QEMU_CPU=thead-c906
** rv32gc_zbb (limit=64) QEMU_CPU=rv32,zbb=true
* SPEC CPU 2017 intrate base/peak with LTO

Christoph Müllner (2):
  riscv: Add support for strlen inline expansion
  riscv: Add support for str(n)cmp inline expansion

 gcc/config.gcc|   3 +-
 gcc/config/riscv/bitmanip.md  |   2 +-
 gcc/config/riscv/riscv-protos.h   |   4 +
 gcc/config/riscv/riscv-string.cc  | 594 ++
 gcc/config/riscv/riscv.md |  72 ++-
 gcc/config/riscv/riscv.opt|  16 +
 gcc/config/riscv/t-riscv  |   6 +
 gcc/config/riscv/thead.md |   9 +-
 gcc/doc/invoke.texi   |  29 +-
 gcc/emit-rtl.cc   |  24 +
 gcc/rtl.h |   2 +
 .../gcc.target/riscv/xtheadbb-strcmp.c|  57 ++
 .../riscv/xtheadbb-strlen-unaligned.c |  14 +
 .../gcc.target/riscv/xtheadbb-strlen.c|  19 +
 .../gcc.target/riscv/zbb-strcmp-disabled-2.c  |  38 ++
 .../gcc.target/riscv/zbb-strcmp-disabled.c|  38 ++
 .../gcc.target/riscv/zbb-strcmp-limit.c   |  57 ++
 .../gcc.target/riscv/zbb-strcmp-unaligned.c   |  38 ++
 gcc/testsuite/gcc.target/riscv/zbb-strcmp.c   |  57 ++
 .../gcc.target/riscv/zbb-strlen-disabled-2.c  |  15 +
 .../gcc.target/riscv/zbb-strlen-disabled.c|  15 +
 .../gcc.target/riscv/zbb-strlen-unaligned.c   |  14 +
 gcc/testsuite/gcc.target/riscv/zbb-strlen.c   |  19 +
 23 files changed, 1137 insertions(+), 5 deletions(-)
 create mode 100644 gcc/config/riscv/riscv-string.cc
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-strcmp.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-strlen-unaligned.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-strlen.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp-disabled-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp-disabled.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp-limit.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp-unaligned.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen-disabled-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen-disabled.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen-unaligned.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen.c

-- 
2.41.0



[PATCH] riscv: xtheadbb: Fix xtheadbb-li-rotr test for rv32

2023-09-06 Thread Christoph Muellner
From: Christoph Müllner 

The test was introduced recently and tests a RV64-only feature.
However, when testing an RV32 compiler, the test gets executed as well
and fails with "cc1: error: ABI requires '-march=rv32'".
This patch fixes this by adding '-mabi=lp64' (like it is done for
other RV64-only tests as well).

Retested with RV32 and RV64 to ensure this won't pop up again.

Signed-off-by: Christoph Müllner 

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-li-rotr.c: Don't run for RV32.
---
 gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c 
b/gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c
index 136dcb01cf4..01f4215179a 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_xtheadbb" } */
+/* { dg-options "-march=rv64gc_xtheadbb -mabi=lp64" } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Os" "-Og" "-Oz" "-flto" } } */
 /* { dg-final { check-function-bodies "**" "" } } */
 
-- 
2.41.0



[PATCH] riscv: Synthesize all 11-bit-rotate constants with rori

2023-09-05 Thread Christoph Muellner
From: Christoph Müllner 

Some constants can be built up using LI+RORI instructions.
The current implementation requires one of the upper 32-bits
to be a zero bit, which is not neccesary.
Let's drop this requirement in order to be able to synthesize
a constant like 0x00ffL.

The tests for LI+RORI are made more strict to detect regression
in the calculation of the LI constant and the rotation amount.

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_build_integer_1): Don't
require one zero bit in the upper 32 bits for LI+RORI synthesis.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-li-rotr.c: New tests.
* gcc.target/riscv/zbb-li-rotr.c: Likewise.
---
 gcc/config/riscv/riscv.cc |  7 +-
 .../gcc.target/riscv/xtheadbb-li-rotr.c   | 66 +--
 gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c  | 57 +++-
 3 files changed, 118 insertions(+), 12 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index ef63079de8e..d8917d75087 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -572,10 +572,9 @@ riscv_build_integer_1 (struct riscv_integer_op 
codes[RISCV_MAX_INTEGER_OPS],
   int trailing_ones = ctz_hwi (~value);
 
   /* If all bits are one except a few that are zero, and the zero bits
-are within a range of 11 bits, and at least one of the upper 32-bits
-is a zero, then we can generate a constant by loading a small
-negative constant and rotating.  */
-  if (leading_ones < 32
+are within a range of 11 bits, then we can synthesize a constant
+by loading a small negative constant and rotating.  */
+  if (leading_ones < 64
  && ((64 - leading_ones - trailing_ones) < 12))
{
  codes[0].code = UNKNOWN;
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c 
b/gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c
index ecd50448d77..136dcb01cf4 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c
@@ -1,34 +1,88 @@
 /* { dg-do compile } */
 /* { dg-options "-march=rv64gc_xtheadbb" } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os" "-Og" "-Oz" "-flto" } } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
+/*
+**li_th_srri_1:
+** li  a[0-9]+,-18
+** th.srri a[0-9]+,a[0-9]+,21
+** ret
+*/
 long
-li_rori (void)
+li_th_srri_1 (void)
 {
   return 0x77ffL;
 }
 
+/*
+**li_th_srri_2:
+** li  a[0-9]+,-18
+** th.srri a[0-9]+,a[0-9]+,5
+** ret
+*/
 long
-li_rori_2 (void)
+li_th_srri_2 (void)
 {
   return 0x77ffL;
 }
 
+/*
+**li_th_srri_3:
+** li  a[0-9]+,-18
+** th.srri a[0-9]+,a[0-9]+,36
+** ret
+*/
 long
-li_rori_3 (void)
+li_th_srri_3 (void)
 {
   return 0xfffeefffL;
 }
 
+/*
+**li_th_srri_4:
+** li  a[0-9]+,-86
+** th.srri a[0-9]+,a[0-9]+,3
+** ret
+*/
 long
-li_rori_4 (void)
+li_th_srri_4 (void)
 {
   return 0x5ff5L;
 }
 
+/*
+**li_th_srri_5:
+** li  a[0-9]+,-86
+** th.srri a[0-9]+,a[0-9]+,4
+** ret
+*/
 long
-li_rori_5 (void)
+li_th_srri_5 (void)
 {
   return 0xaffaL;
 }
 
-/* { dg-final { scan-assembler-times "th.srri\t" 5 } } */
+/*
+**li_th_srri_6:
+** li  a[0-9]+,-256
+** th.srri a[0-9]+,a[0-9]+,40
+** ret
+*/
+long
+li_th_srri_6 (void)
+{
+  return 0x00ffL;
+}
+
+/*
+**li_th_srri_7:
+** li  a[0-9]+,-2048
+** th.srri a[0-9]+,a[0-9]+,16
+** ret
+*/
+long
+li_th_srri_7 (void)
+{
+  return 0xf800L;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c 
b/gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c
index 500264a49dd..594c3dcaa49 100644
--- a/gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c
+++ b/gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c
@@ -1,35 +1,88 @@
 /* { dg-do compile } */
 /* { dg-options "-march=rv64gc_zbb -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os" "-Og" "-Oz" "-flto" } } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
+/*
+**li_rori_1:
+** li  a[0-9]+,-18
+** roria[0-9]+,a[0-9]+,21
+** ret
+*/
 long
-li_rori (void)
+li_rori_1 (void)
 {
   return 0x77ffL;
 }
 
+/*
+**li_rori_2:
+** li  a[0-9]+,-18
+** roria[0-9]+,a[0-9]+,5
+** ret
+*/
 long
 li_rori_2 (void)
 {
   return 0x77ffL;
 }
 
+/*
+**li_rori_3:
+** li  a[0-9]+,-18
+** roria[0-9]+,a[0-9]+,36
+** ret
+*/
 long
 li_rori_3 (void)
 {
   return 0xfffeefffL;
 }
 
+/*
+**li_rori_4:
+** li  a[0-9]+,-86
+** roria[0-9]+,a[0-9]+,3
+** ret
+*/
 long
 li_rori_4 (void)
 {
   return 0x5ff5L;
 }
 
+/*
+**li_rori_5:
+** li  a[0-9]+,-86
+** roria[0-9]+,a[0-9]+,4
+** ret
+*/
 long
 li_rori_5 (void)
 {
   return 0xaffaL;
 }
 
+/*
+**li_rori_6:
+** li  a[0-9]+,-256
+**  

[PATCH] riscv: xtheadbb: Enable constant synthesis with th.srri

2023-09-05 Thread Christoph Muellner
From: Christoph Müllner 

Some constants can be built up using rotate-right instructions.
The code that enables this can be found in riscv_build_integer_1().
However, this functionality is only available for Zbb, which
includes the rori instruction.  This patch enables this also for
XTheadBb, which includes the th.srri instruction.

Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_build_integer_1): Enable constant
synthesis with rotate-right for XTheadBb.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-li-rotr.c: New test.
---
 gcc/config/riscv/riscv.cc |  2 +-
 .../gcc.target/riscv/xtheadbb-li-rotr.c   | 34 +++
 2 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 2db9c81ac8b..ef63079de8e 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -566,7 +566,7 @@ riscv_build_integer_1 (struct riscv_integer_op 
codes[RISCV_MAX_INTEGER_OPS],
}
 }
 
-  if (cost > 2 && TARGET_64BIT && TARGET_ZBB)
+  if (cost > 2 && TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB))
 {
   int leading_ones = clz_hwi (~value);
   int trailing_ones = ctz_hwi (~value);
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c 
b/gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c
new file mode 100644
index 000..ecd50448d77
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-li-rotr.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbb" } */
+
+long
+li_rori (void)
+{
+  return 0x77ffL;
+}
+
+long
+li_rori_2 (void)
+{
+  return 0x77ffL;
+}
+
+long
+li_rori_3 (void)
+{
+  return 0xfffeefffL;
+}
+
+long
+li_rori_4 (void)
+{
+  return 0x5ff5L;
+}
+
+long
+li_rori_5 (void)
+{
+  return 0xaffaL;
+}
+
+/* { dg-final { scan-assembler-times "th.srri\t" 5 } } */
-- 
2.41.0



[PATCH] riscv: xtheadcondmov: Don't run tests with -Oz

2023-09-01 Thread Christoph Muellner
From: Christoph Müllner 

Recently, these xtheadcondmov tests regressed with -Oz:
* FAIL: gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
* FAIL: gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
* FAIL: gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c
* FAIL: gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c

As -Oz stands for "Optimize aggressively for size rather than speed.",
we need to inspect the generated code, which looks like this:

  -Oz
   :
 0:   e199bneza1,6 <.L2>
 2:   40100513li  a0,1025
  0006 <.L2>:
 6:   8082ret

  -O2:
   :
 0:   40100793li  a5,1025
 4:   40b7950bth.mveqza0,a5,a1
 8:   8082ret

As the generated code with -Oz consumes less size, there is nothing
wrong in the code generation. Instead, let's not run the xtheadcondmov
tests with -Oz.

Signed-off-by: Christoph Müllner 

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c: Disable for -Oz.
* gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c: Likewise.
* gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c: Likewise.
* gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c: Likewise.
* gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c: Likewise.
* gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c: Likewise.
* gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c: Likewise.
* gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c: Likewise.
---
 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c  | 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c  | 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c  | 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c  | 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c | 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c  | 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c | 2 +-
 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c  | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
index 913ae43f21b..9cc9ec1d0c7 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */
 /* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */
-/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */
 
 int
 not_int_int (int x, int cond)
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
index 1bc8b838233..491343370b7 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */
 /* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */
-/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */
 
 int
 not_int_int (int x, int cond)
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
index 8ef5869a89b..d7227249e84 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */
 /* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */
-/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */
 
 int
 not_int_int (int x, int cond, int v)
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
index f9568bee27f..6cc98e36e71 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */
 /* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */
-/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */
 
 int
 not_int_int (int x, int cond, int v)
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c
index 8feddbeb79d..7cce2c71d18 100644

[PATCH] riscv: Fix warning in riscv_regno_ok_for_index_p

2023-07-17 Thread Christoph Muellner
From: Christoph Müllner 

The variable `regno` is currently not used in riscv_regno_ok_for_index_p(),
which triggers a compiler warning. Let's address this.

Fixes: 423604278ed5 ("riscv: Prepare backend for index registers")

Reported-by: Juzhe Zhong 
Reported-by: Andreas Schwab 
Signed-off-by: Christoph Müllner 

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_regno_ok_for_index_p):
Remove parameter name from declaration of unused parameter.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 6ed735d6983..ae3c034e76e 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -861,7 +861,7 @@ riscv_index_reg_class ()
but extensions might support that.  */
 
 int
-riscv_regno_ok_for_index_p (int regno)
+riscv_regno_ok_for_index_p (int)
 {
   return 0;
 }
-- 
2.41.0



[PATCH] riscv: thead: Fix failing XTheadCondMov tests (indirect-rv[32|64])

2023-07-10 Thread Christoph Muellner
From: Christoph Müllner 

Recently, two identical XTheadCondMov tests have been added, which both fail.
Let's fix that by changing the following:
* Merge both files into one (no need for separate tests for rv32 and rv64)
* Drop unrelated attribute check test (we already test for `th.mveqz`
  and `th.mvnez` instructions, so there is little additional value)
* Fix the pattern to allow matching

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-indirect-rv32.c: Moved to...
* gcc.target/riscv/xtheadcondmov-indirect.c: ...here.
* gcc.target/riscv/xtheadcondmov-indirect-rv64.c: Removed.

Fixes: a1806f0918c0 ("RISC-V: Optimize TARGET_XTHEADCONDMOV")
Signed-off-by: Christoph Müllner 
---
 .../riscv/xtheadcondmov-indirect-rv32.c   | 104 ---
 .../riscv/xtheadcondmov-indirect-rv64.c   | 104 ---
 .../gcc.target/riscv/xtheadcondmov-indirect.c | 118 ++
 3 files changed, 118 insertions(+), 208 deletions(-)
 delete mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c
 delete mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv64.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c

diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c
deleted file mode 100644
index d0df59c5e1c..000
--- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -march=rv32gc_xtheadcondmov -mabi=ilp32 
-mriscv-attribute" } */
-/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os" "-Og" "-O3" "-Oz" "-flto"} } */
-/* { dg-final { check-function-bodies "**" ""  } } */
-
-/*
-**ConEmv_imm_imm_reg:
-** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+
-** li\t\s*[a-x0-9]+,10+
-** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** ret
-*/
-int ConEmv_imm_imm_reg(int x, int y){
-  if (x == 1000) return 10;
-  return y;
-}
-
-/*
-**ConEmv_imm_reg_reg:
-** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+
-** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+
-** ret
-*/
-int ConEmv_imm_reg_reg(int x, int y, int z){
-  if (x == 1000) return y;
-  return z;
-}
-
-/*
-**ConEmv_reg_imm_reg:
-** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** li\t\s*[a-x0-9]+,10+
-** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** ret
-*/
-int ConEmv_reg_imm_reg(int x, int y, int z){
-  if (x == y) return 10;
-  return z;
-}
-
-/*
-**ConEmv_reg_reg_reg:
-** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+
-** ret
-*/
-int ConEmv_reg_reg_reg(int x, int y, int z, int n){
-  if (x == y) return z;
-  return n;
-}
-
-/*
-**ConNmv_imm_imm_reg:
-** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+
-** li\t\s*[a-x0-9]+,9998336+
-** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,1664+
-** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** ret
-*/
-int ConNmv_imm_imm_reg(int x, int y){
-  if (x != 1000) return 1000;
-  return y;
-}
-
-/*
-**ConNmv_imm_reg_reg:
-** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+
-** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+
-** ret
-*/
-int ConNmv_imm_reg_reg(int x, int y, int z){
-  if (x != 1000) return y;
-  return z;
-}
-
-/*
-**ConNmv_reg_imm_reg:
-** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** li\t\s*[a-x0-9]+,10+
-** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** ret
-*/
-int ConNmv_reg_imm_reg(int x, int y, int z){
-  if (x != y) return 10;
-  return z;
-}
-
-/*
-**ConNmv_reg_reg_reg:
-** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+
-** ret
-*/
-int ConNmv_reg_reg_reg(int x, int y, int z, int n){
-  if (x != y) return z;
-  return n;
-}
-
-
-/* { dg-final { scan-assembler ".attribute arch, 
\"rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_xtheadcondmov1p0\"" } 
} */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv64.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv64.c
deleted file mode 100644
index cc971a75ace..000
--- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv64.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -march=rv64gc_xtheadcondmov -mabi=lp64d 
-mriscv-attribute" } */
-/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os" "-Og" "-O3" "-Oz" "-flto"} } */
-/* { dg-final { check-function-bodies "**" ""  } } */
-
-/*
-**ConEmv_imm_imm_reg:
-** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+
-** li\t\s*[a-x0-9]+,10+
-** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+
-** ret
-*/
-int ConEmv_imm_imm_reg(int x, int y){
-  if (x == 1000) return 10;
-  return y;
-}
-
-/*
-**ConEmv_imm_reg_reg:
-** 

[PATCH v2] RISC-V: Add support for vector crypto extensions

2023-07-03 Thread Christoph Muellner
From: Christoph Müllner 

This series adds basic support for the vector crypto extensions:
* Zvbb
* Zvbc
* Zvkg
* Zvkned
* Zvkhn[a,b]
* Zvksed
* Zvksh
* Zvkn
* Zvknc
* Zvkng
* Zvks
* Zvksc
* Zvksg
* Zvkt

This patch is based on the v20230620 version of the Vector Cryptography
specification. The specification is frozen and can be found here:
  https://github.com/riscv/riscv-crypto/releases/tag/v20230620

Binutils support has been merged upstream a few days ago.

All extensions come with tests for the feature test macros.

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc: Add support for zvbb,
zvbc, zvkg, zvkned, zvknha, zvknhb, zvksed, zvksh, zvkn,
zvknc, zvkng, zvks, zvksc, zvksg, zvkt and the implied subsets.
* config/riscv/arch-canonicalize: Add canonicalization info for
zvkn, zvknc, zvkng, zvks, zvksc, zvksg.
* config/riscv/riscv-opts.h (MASK_ZVBB): New macro.
(MASK_ZVBC): Likewise.
(TARGET_ZVBB): Likewise.
(TARGET_ZVBC): Likewise.
(MASK_ZVKG): Likewise.
(MASK_ZVKNED): Likewise.
(MASK_ZVKNHA): Likewise.
(MASK_ZVKNHB): Likewise.
(MASK_ZVKSED): Likewise.
(MASK_ZVKSH): Likewise.
(MASK_ZVKN): Likewise.
(MASK_ZVKNC): Likewise.
(MASK_ZVKNG): Likewise.
(MASK_ZVKS): Likewise.
(MASK_ZVKSC): Likewise.
(MASK_ZVKSG): Likewise.
(MASK_ZVKT): Likewise.
(TARGET_ZVKG): Likewise.
(TARGET_ZVKNED): Likewise.
(TARGET_ZVKNHA): Likewise.
(TARGET_ZVKNHB): Likewise.
(TARGET_ZVKSED): Likewise.
(TARGET_ZVKSH): Likewise.
(TARGET_ZVKN): Likewise.
(TARGET_ZVKNC): Likewise.
(TARGET_ZVKNG): Likewise.
(TARGET_ZVKS): Likewise.
(TARGET_ZVKSC): Likewise.
(TARGET_ZVKSG): Likewise.
(TARGET_ZVKT): Likewise.
* config/riscv/riscv.opt: Introduction of riscv_zv{b,k}_subext.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zvbb.c: New test.
* gcc.target/riscv/zvbc.c: New test.
* gcc.target/riscv/zvkg.c: New test.
* gcc.target/riscv/zvkn-1.c: New test.
* gcc.target/riscv/zvkn.c: New test.
* gcc.target/riscv/zvknc-1.c: New test.
* gcc.target/riscv/zvknc-2.c: New test.
* gcc.target/riscv/zvknc.c: New test.
* gcc.target/riscv/zvkned.c: New test.
* gcc.target/riscv/zvkng-1.c: New test.
* gcc.target/riscv/zvkng-2.c: New test.
* gcc.target/riscv/zvkng.c: New test.
* gcc.target/riscv/zvknha.c: New test.
* gcc.target/riscv/zvknhb.c: New test.
* gcc.target/riscv/zvks-1.c: New test.
* gcc.target/riscv/zvks.c: New test.
* gcc.target/riscv/zvksc-1.c: New test.
* gcc.target/riscv/zvksc-2.c: New test.
* gcc.target/riscv/zvksc.c: New test.
* gcc.target/riscv/zvksed.c: New test.
* gcc.target/riscv/zvksg-1.c: New test.
* gcc.target/riscv/zvksg-2.c: New test.
* gcc.target/riscv/zvksg.c: New test.
* gcc.target/riscv/zvksh.c: New test.
* gcc.target/riscv/zvkt.c: New test.

Signed-off-by: Christoph Müllner 
---
Changes for v2:
- Update patch for specification version v20230620

 gcc/common/config/riscv/riscv-common.cc  | 55 
 gcc/config/riscv/arch-canonicalize   |  7 +++
 gcc/config/riscv/riscv-opts.h| 34 +++
 gcc/config/riscv/riscv.opt   |  6 +++
 gcc/testsuite/gcc.target/riscv/zvbb.c| 13 ++
 gcc/testsuite/gcc.target/riscv/zvbc.c| 13 ++
 gcc/testsuite/gcc.target/riscv/zvkg.c| 13 ++
 gcc/testsuite/gcc.target/riscv/zvkn-1.c  | 29 +
 gcc/testsuite/gcc.target/riscv/zvkn.c| 29 +
 gcc/testsuite/gcc.target/riscv/zvknc-1.c | 37 
 gcc/testsuite/gcc.target/riscv/zvknc-2.c | 37 
 gcc/testsuite/gcc.target/riscv/zvknc.c   | 37 
 gcc/testsuite/gcc.target/riscv/zvkned.c  | 13 ++
 gcc/testsuite/gcc.target/riscv/zvkng-1.c | 37 
 gcc/testsuite/gcc.target/riscv/zvkng-2.c | 37 
 gcc/testsuite/gcc.target/riscv/zvkng.c   | 37 
 gcc/testsuite/gcc.target/riscv/zvknha.c  | 13 ++
 gcc/testsuite/gcc.target/riscv/zvknhb.c  | 13 ++
 gcc/testsuite/gcc.target/riscv/zvks-1.c  | 29 +
 gcc/testsuite/gcc.target/riscv/zvks.c| 29 +
 gcc/testsuite/gcc.target/riscv/zvksc-1.c | 37 
 gcc/testsuite/gcc.target/riscv/zvksc-2.c | 37 
 gcc/testsuite/gcc.target/riscv/zvksc.c   | 37 
 gcc/testsuite/gcc.target/riscv/zvksed.c  | 13 ++
 gcc/testsuite/gcc.target/riscv/zvksg-1.c | 37 
 gcc/testsuite/gcc.target/riscv/zvksg-2.c | 37 
 gcc/testsuite/gcc.target/riscv/zvksg.c   | 37 
 gcc/testsuite/gcc.target/riscv/zvksh.c   | 13 ++
 gcc/testsuite/gcc.target/riscv/zvkt.c| 13 ++
 29 

[PATCH 10/11] riscv: thead: Add support for the XTheadMemIdx ISA extension

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadMemIdx ISA extension provides a additional load and store
instructions with new addressing modes.

The following memory accesses types are supported:
* ltype = [b,bu,h,hu,w,wu,d]
* stype = [b,h,w,d]

The following addressing modes are supported:
* immediate offset with PRE_MODIFY or POST_MODIFY (22 instructions):
  l.ia, l.ib, s.ia, s.ib
* register offset with additional immediate offset (11 instructions):
  lr, sr
* zero-extended register offset with additional immediate offset
  (11 instructions): lur, sur

The RISC-V base ISA does not support index registers, so the changes
are kept separate from the RISC-V standard support.

Similar like other extensions (Zbb, XTheadBb), this patch needs to
prevent the conversion of sign-extensions/zero-extensions into
shift instructions. The case of the zero-extended register offset
addressing mode is handled by a new peephole pass.

Handling the different cases of extensions results in a couple of INSNs
that look redundant on first view, but they are just the equivalent
of what we already have for Zbb as well. The only difference is, that
we have much more load instructions.

To fully utilize the capabilities of the instructions, there are
a few new peephole passes which fold shift amounts into the RTX
if possible. The added tests ensure that this feature won't
regress without notice.

We already have a constraint with the name 'th_f_fmv', therefore,
the new constraints follow this pattern and have the same length
as required ('th_m_mia', 'th_m_mib', 'th_m_mir', 'th_m_miu').

gcc/ChangeLog:

* config/riscv/constraints.md (th_m_mia): New constraint.
(th_m_mib): Likewise.
(th_m_mir): Likewise.
(th_m_miu): Likewise.
* config/riscv/riscv-protos.h (enum riscv_address_type):
Add new address types ADDRESS_REG_REG, ADDRESS_REG_UREG,
and ADDRESS_REG_WB and their documentation.
(struct riscv_address_info): Add new field 'shift' and
document the field usage for the new address types.
(riscv_valid_base_register_p): New prototype.
(th_memidx_legitimate_modify_p): Likewise.
(th_memidx_legitimate_index_p): Likewise.
(th_classify_address): Likewise.
(th_output_move): Likewise.
(th_print_operand_address): Likewise.
* config/riscv/riscv.cc (riscv_index_reg_class):
Return GR_REGS for XTheadMemIdx.
(riscv_regno_ok_for_index_p): Add support for XTheadMemIdx.
(riscv_classify_address): Call th_classify_address() on top.
(riscv_output_move): Call th_output_move() on top.
(riscv_print_operand_address): Call th_print_operand_address()
on top.
* config/riscv/riscv.h (HAVE_POST_MODIFY_DISP): New macro.
(HAVE_PRE_MODIFY_DISP): Likewise.
* config/riscv/riscv.md (zero_extendqi2): Disable
for XTheadMemIdx.
(*zero_extendqi2_internal): Convert to expand,
create INSN with same name and disable it for XTheadMemIdx.
(extendsidi2): Likewise.
(*extendsidi2_internal): Disable for XTheadMemIdx.
* config/riscv/thead-peephole.md: Add helper peephole passes.
* config/riscv/thead.cc (valid_signed_immediate): New helper
function.
(th_memidx_classify_address_modify): New function.
(th_memidx_legitimate_modify_p): Likewise.
(th_memidx_output_modify): Likewise.
(is_memidx_mode): Likewise.
(th_memidx_classify_address_index): Likewise.
(th_memidx_legitimate_index_p): Likewise.
(th_memidx_output_index): Likewise.
(th_classify_address): Likewise.
(th_output_move): Likewise.
(th_print_operand_address): Likewise.
* config/riscv/thead.md (*th_memidx_mov2):
New INSN.
(*th_memidx_zero_extendqi2): Likewise.
(*th_memidx_extendsidi2): Likewise
(*th_memidx_zero_extendsidi2): Likewise.
(*th_memidx_zero_extendhi2): Likewise.
(*th_memidx_extend2): Likewise
(*th_memidx_bb_zero_extendsidi2): Likewise.
(*th_memidx_bb_zero_extendhi2): Likewise.
(*th_memidx_bb_extendhi2): Likewise.
(*th_memidx_bb_extendqi2): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadmemidx-helpers.h: New test.
* gcc.target/riscv/xtheadmemidx-index-update.c: New test.
* gcc.target/riscv/xtheadmemidx-index-xtheadbb-update.c: New test.
* gcc.target/riscv/xtheadmemidx-index-xtheadbb.c: New test.
* gcc.target/riscv/xtheadmemidx-index.c: New test.
* gcc.target/riscv/xtheadmemidx-modify-xtheadbb.c: New test.
* gcc.target/riscv/xtheadmemidx-modify.c: New test.
* gcc.target/riscv/xtheadmemidx-uindex-update.c: New test.
* gcc.target/riscv/xtheadmemidx-uindex-xtheadbb-update.c: New test.
* gcc.target/riscv/xtheadmemidx-uindex-xtheadbb.c: New test.
* gcc.target/riscv/xtheadmemidx-uindex.c: New test.

Signed-off-by: 

[PATCH 11/11] riscv: thead: Add support for the XTheadFMemIdx ISA extension

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadFMemIdx ISA extension provides additional load and store
instructions for floating-point registers with new addressing modes.

The following memory accesses types are supported:
* ftype = [w,d] (single-precision, double-precision)

The following addressing modes are supported:
* register offset with additional immediate offset (4 instructions):
  flr, fsr
* zero-extended register offset with additional immediate offset
  (4 instructions): flur, fsur

These addressing modes are also part of the similar XTheadMemIdx
ISA extension support, whose code is reused and extended to support
floating-point registers.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_index_reg_class): Also allow
for XTheadFMemIdx.
(riscv_regno_ok_for_index_p): Likewise.
* config/riscv/thead-peephole.md (TARGET_64BIT):
Generalize peepholes for XTheadFMemIdx.
* config/riscv/thead.cc (is_fmemidx_mode): New function.
(th_memidx_classify_address_index): Add support for
XTheadFMemIdx.
(th_fmemidx_output_index): New function.
(th_output_move): Add support for XTheadFMemIdx.
* config/riscv/thead.md (*th_fmemidx_movsf_hardfloat): New INSN.
(*th_fmemidx_movdf_hardfloat_rv64): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadmemidx-helpers.h: Add helpers for
  XTheadMemFIdx.
* gcc.target/riscv/xtheadfmemidx-index-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c: New test.
* gcc.target/riscv/xtheadfmemidx-index.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c: New test.
* gcc.target/riscv/xtheadfmemidx-uindex.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.cc |  4 +-
 gcc/config/riscv/thead-peephole.md| 24 ---
 gcc/config/riscv/thead.cc | 68 +-
 gcc/config/riscv/thead.md | 22 ++
 .../riscv/xtheadfmemidx-index-update.c| 20 ++
 .../xtheadfmemidx-index-xtheadbb-update.c | 20 ++
 .../riscv/xtheadfmemidx-index-xtheadbb.c  | 22 ++
 .../gcc.target/riscv/xtheadfmemidx-index.c| 22 ++
 .../riscv/xtheadfmemidx-uindex-update.c   | 20 ++
 .../xtheadfmemidx-uindex-xtheadbb-update.c| 20 ++
 .../riscv/xtheadfmemidx-uindex-xtheadbb.c | 24 +++
 .../gcc.target/riscv/xtheadfmemidx-uindex.c   | 25 +++
 .../gcc.target/riscv/xtheadmemidx-helpers.h   | 70 +++
 13 files changed, 348 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 1691ecf3a94..d1e08974023 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -834,7 +834,7 @@ riscv_regno_mode_ok_for_base_p (int regno,
 enum reg_class
 riscv_index_reg_class ()
 {
-  if (TARGET_XTHEADMEMIDX)
+  if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)
 return GR_REGS;
 
   return NO_REGS;
@@ -847,7 +847,7 @@ riscv_index_reg_class ()
 int
 riscv_regno_ok_for_index_p (int regno)
 {
-  if (TARGET_XTHEADMEMIDX)
+  if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)
 return riscv_regno_mode_ok_for_base_p (regno, VOIDmode, 1);
 
   return 0;
diff --git a/gcc/config/riscv/thead-peephole.md 
b/gcc/config/riscv/thead-peephole.md
index 2a4c734a220..e3de9b8e8d3 100644
--- a/gcc/config/riscv/thead-peephole.md
+++ b/gcc/config/riscv/thead-peephole.md
@@ -73,11 +73,15 @@ (define_peephole2
   th_mempair_order_operands (operands, true, SImode);
 })
 
-;; All modes that are supported by XTheadMemIdx
-(define_mode_iterator TH_M_ANY [QI HI SI (DI "TARGET_64BIT")])
+;; All modes that are supported by XTheadMemIdx and XTheadFMemIdx
+(define_mode_iterator TH_M_ANY [QI HI SI (DI "TARGET_64BIT")
+(SF "TARGET_HARD_FLOAT")
+(DF "TARGET_DOUBLE_FLOAT")])
 
-;; All non-extension modes that are supported by XTheadMemIdx
-(define_mode_iterator TH_M_NOEXT [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
+;; All non-extension modes that 

[PATCH 08/11] riscv: Prepare backend for index registers

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

RISC-V does currently not support index registers.
However, there are some vendor extensions that specify them.
Let's do the necessary changes in the backend so that we can
add support for such a vendor extension in the future.

This is a non-functional change without any intended side-effects.

gcc/ChangeLog:

* config/riscv/riscv-protos.h (riscv_regno_ok_for_index_p):
New prototype.
(riscv_index_reg_class): Likewise.
* config/riscv/riscv.cc (riscv_regno_ok_for_index_p): New function.
(riscv_index_reg_class): New function.
* config/riscv/riscv.h (INDEX_REG_CLASS): Call new function
riscv_index_reg_class().
(REGNO_OK_FOR_INDEX_P): Call new function
riscv_regno_ok_for_index_p().

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv-protos.h |  2 ++
 gcc/config/riscv/riscv.cc   | 20 
 gcc/config/riscv/riscv.h|  6 --
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 628c64cf628..b7417e97d99 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -82,6 +82,8 @@ struct riscv_address_info {
 extern enum riscv_symbol_type riscv_classify_symbolic_expression (rtx);
 extern bool riscv_symbolic_constant_p (rtx, enum riscv_symbol_type *);
 extern int riscv_regno_mode_ok_for_base_p (int, machine_mode, bool);
+extern enum reg_class riscv_index_reg_class ();
+extern int riscv_regno_ok_for_index_p (int);
 extern int riscv_address_insns (rtx, machine_mode, bool);
 extern int riscv_const_insns (rtx);
 extern int riscv_split_const_insns (rtx);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 8388235d8cc..a33f0fff8ea 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -827,6 +827,26 @@ riscv_regno_mode_ok_for_base_p (int regno,
   return GP_REG_P (regno);
 }
 
+/* Get valid index register class.
+   The RISC-V base instructions don't support index registers,
+   but extensions might support that.  */
+
+enum reg_class
+riscv_index_reg_class ()
+{
+  return NO_REGS;
+}
+
+/* Return true if register REGNO is a valid index register.
+   The RISC-V base instructions don't support index registers,
+   but extensions might support that.  */
+
+int
+riscv_regno_ok_for_index_p (int regno)
+{
+  return 0;
+}
+
 /* Return true if X is a valid base register for mode MODE.
STRICT_P is true if REG_OK_STRICT is in effect.  */
 
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 90746fe14e3..21b81c22dea 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -535,7 +535,7 @@ enum reg_class
factor or added to another register (as well as added to a
displacement).  */
 
-#define INDEX_REG_CLASS NO_REGS
+#define INDEX_REG_CLASS riscv_index_reg_class()
 
 /* We generally want to put call-clobbered registers ahead of
call-saved ones.  (IRA expects this.)  */
@@ -705,7 +705,9 @@ typedef struct {
 
 /* Addressing modes, and classification of registers for them.  */
 
-#define REGNO_OK_FOR_INDEX_P(REGNO) 0
+#define REGNO_OK_FOR_INDEX_P(REGNO) \
+  riscv_regno_ok_for_index_p (REGNO)
+
 #define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
   riscv_regno_mode_ok_for_base_p (REGNO, MODE, 1)
 
-- 
2.40.1



[PATCH 03/11] riscv: xtheadmempair: Fix doc for th_mempair_order_operands()

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

There is an incorrect sentence in the documentation of the function
th_mempair_order_operands(). Let's remove it.

gcc/ChangeLog:

* config/riscv/thead.cc (th_mempair_operands_p):
Fix documentation of th_mempair_order_operands().

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/thead.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index d7e3cf80d9b..507c912bc39 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -336,8 +336,8 @@ th_mempair_operands_p (rtx operands[4], bool load_p,
 }
 
 /* Given OPERANDS of consecutive load/store that can be merged,
-   swap them if they are not in ascending order.
-   Return true if swap was performed.  */
+   swap them if they are not in ascending order.  */
+
 void
 th_mempair_order_operands (rtx operands[4], bool load_p, machine_mode mode)
 {
-- 
2.40.1



[PATCH 09/11] riscv: thead: Factor out XThead*-specific peepholes

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

This patch moves the XThead*-specific peephole passes
into thead-peephole.md with the intend to keep vendor-specific
code separated from RISC-V standard code.

This patch does not contain any functional changes.

gcc/ChangeLog:

* config/riscv/peephole.md: Remove XThead* peephole passes.
* config/riscv/thead.md: Include thead-peephole.md.
* config/riscv/thead-peephole.md: New file.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/peephole.md   | 56 --
 gcc/config/riscv/thead-peephole.md | 74 ++
 gcc/config/riscv/thead.md  |  2 +
 3 files changed, 76 insertions(+), 56 deletions(-)
 create mode 100644 gcc/config/riscv/thead-peephole.md

diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md
index 67e7046d7e6..0ef0c04410b 100644
--- a/gcc/config/riscv/peephole.md
+++ b/gcc/config/riscv/peephole.md
@@ -38,59 +38,3 @@ (define_peephole2
 {
   operands[5] = GEN_INT (INTVAL (operands[2]) - INTVAL (operands[5]));
 })
-
-;; XTheadMemPair: merge two SI or DI loads
-(define_peephole2
-  [(set (match_operand:GPR 0 "register_operand" "")
-   (match_operand:GPR 1 "memory_operand" ""))
-   (set (match_operand:GPR 2 "register_operand" "")
-   (match_operand:GPR 3 "memory_operand" ""))]
-  "TARGET_XTHEADMEMPAIR
-  && th_mempair_operands_p (operands, true, mode)"
-  [(parallel [(set (match_dup 0) (match_dup 1))
- (set (match_dup 2) (match_dup 3))])]
-{
-  th_mempair_order_operands (operands, true, mode);
-})
-
-;; XTheadMemPair: merge two SI or DI stores
-(define_peephole2
-  [(set (match_operand:GPR 0 "memory_operand" "")
-   (match_operand:GPR 1 "register_operand" ""))
-   (set (match_operand:GPR 2 "memory_operand" "")
-   (match_operand:GPR 3 "register_operand" ""))]
-  "TARGET_XTHEADMEMPAIR
-  && th_mempair_operands_p (operands, false, mode)"
-  [(parallel [(set (match_dup 0) (match_dup 1))
-  (set (match_dup 2) (match_dup 3))])]
-{
-  th_mempair_order_operands (operands, false, mode);
-})
-
-;; XTheadMemPair: merge two SI loads with sign-extension
-(define_peephole2
-  [(set (match_operand:DI 0 "register_operand" "")
-   (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))
-   (set (match_operand:DI 2 "register_operand" "")
-   (sign_extend:DI (match_operand:SI 3 "memory_operand" "")))]
-  "TARGET_XTHEADMEMPAIR && TARGET_64BIT
-  && th_mempair_operands_p (operands, true, SImode)"
-  [(parallel [(set (match_dup 0) (sign_extend:DI (match_dup 1)))
-  (set (match_dup 2) (sign_extend:DI (match_dup 3)))])]
-{
-  th_mempair_order_operands (operands, true, SImode);
-})
-
-;; XTheadMemPair: merge two SI loads with zero-extension
-(define_peephole2
-  [(set (match_operand:DI 0 "register_operand" "")
-   (zero_extend:DI (match_operand:SI 1 "memory_operand" "")))
-   (set (match_operand:DI 2 "register_operand" "")
-   (zero_extend:DI (match_operand:SI 3 "memory_operand" "")))]
-  "TARGET_XTHEADMEMPAIR && TARGET_64BIT
-  && th_mempair_operands_p (operands, true, SImode)"
-  [(parallel [(set (match_dup 0) (zero_extend:DI (match_dup 1)))
-  (set (match_dup 2) (zero_extend:DI (match_dup 3)))])]
-{
-  th_mempair_order_operands (operands, true, SImode);
-})
diff --git a/gcc/config/riscv/thead-peephole.md 
b/gcc/config/riscv/thead-peephole.md
new file mode 100644
index 000..5b829b5b968
--- /dev/null
+++ b/gcc/config/riscv/thead-peephole.md
@@ -0,0 +1,74 @@
+;; Machine description for T-Head vendor extensions
+;; Copyright (C) 2023 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
+;; .
+
+;; XTheadMemPair: merge two SI or DI loads
+(define_peephole2
+  [(set (match_operand:GPR 0 "register_operand" "")
+   (match_operand:GPR 1 "memory_operand" ""))
+   (set (match_operand:GPR 2 "register_operand" "")
+   (match_operand:GPR 3 "memory_operand" ""))]
+  "TARGET_XTHEADMEMPAIR
+  && th_mempair_operands_p (operands, true, mode)"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+ (set (match_dup 2) (match_dup 3))])]
+{
+  th_mempair_order_operands (operands, true, mode);
+})
+
+;; XTheadMemPair: merge two SI or DI stores
+(define_peephole2
+  [(set (match_operand:GPR 0 "memory_operand" "")
+   (match_operand:GPR 1 "register_operand" ""))
+   (set 

[PATCH 06/11] riscv: Define Xmode macro

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

Define a Xmode macro that specifies the registers size (XLEN)
similar to Pmode. This allows the backend code to write generic
RV32/RV64 C code (under certain circumstances).

gcc/ChangeLog:

* config/riscv/riscv.h (Xmode): New macro.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 66fb07d6652..90746fe14e3 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -791,6 +791,10 @@ typedef struct {
 
 #define Pmode word_mode
 
+/* Specify the machine mode that registers have.  */
+
+#define Xmode (TARGET_64BIT ? DImode : SImode)
+
 /* Give call MEMs SImode since it is the "most permissive" mode
for both 32-bit and 64-bit targets.  */
 
-- 
2.40.1



[PATCH 07/11] riscv: Move address classification info types to riscv-protos.h

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

enum riscv_address_type and struct riscv_address_info are used
to store address classification information. Let's move this types
into our common header file in order to share them with other
compilation units.

This is a non-functional change without any intendet side-effects.

gcc/ChangeLog:

* config/riscv/riscv-protos.h (enum riscv_address_type):
New location of type definition.
(struct riscv_address_info): Likewise.
* config/riscv/riscv.cc (enum riscv_address_type):
Old location of type definition.
(struct riscv_address_info): Likewise.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv-protos.h | 43 +
 gcc/config/riscv/riscv.cc   | 43 -
 2 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 5244e8dcbf0..628c64cf628 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -35,6 +35,49 @@ enum riscv_symbol_type {
 };
 #define NUM_SYMBOL_TYPES (SYMBOL_TLS_GD + 1)
 
+/* Classifies an address.
+
+   ADDRESS_REG
+   A natural register + offset address.  The register satisfies
+   riscv_valid_base_register_p and the offset is a const_arith_operand.
+
+   ADDRESS_LO_SUM
+   A LO_SUM rtx.  The first operand is a valid base register and
+   the second operand is a symbolic address.
+
+   ADDRESS_CONST_INT
+   A signed 16-bit constant address.
+
+   ADDRESS_SYMBOLIC:
+   A constant symbolic address.  */
+enum riscv_address_type {
+  ADDRESS_REG,
+  ADDRESS_LO_SUM,
+  ADDRESS_CONST_INT,
+  ADDRESS_SYMBOLIC
+};
+
+/* Information about an address described by riscv_address_type.
+
+   ADDRESS_CONST_INT
+   No fields are used.
+
+   ADDRESS_REG
+   REG is the base register and OFFSET is the constant offset.
+
+   ADDRESS_LO_SUM
+   REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
+   is the type of symbol it references.
+
+   ADDRESS_SYMBOLIC
+   SYMBOL_TYPE is the type of symbol that the address references.  */
+struct riscv_address_info {
+  enum riscv_address_type type;
+  rtx reg;
+  rtx offset;
+  enum riscv_symbol_type symbol_type;
+};
+
 /* Routines implemented in riscv.cc.  */
 extern enum riscv_symbol_type riscv_classify_symbolic_expression (rtx);
 extern bool riscv_symbolic_constant_p (rtx, enum riscv_symbol_type *);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 92043236b17..8388235d8cc 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -81,28 +81,6 @@ along with GCC; see the file COPYING3.  If not see
 /* True if bit BIT is set in VALUE.  */
 #define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
 
-/* Classifies an address.
-
-   ADDRESS_REG
-   A natural register + offset address.  The register satisfies
-   riscv_valid_base_register_p and the offset is a const_arith_operand.
-
-   ADDRESS_LO_SUM
-   A LO_SUM rtx.  The first operand is a valid base register and
-   the second operand is a symbolic address.
-
-   ADDRESS_CONST_INT
-   A signed 16-bit constant address.
-
-   ADDRESS_SYMBOLIC:
-   A constant symbolic address.  */
-enum riscv_address_type {
-  ADDRESS_REG,
-  ADDRESS_LO_SUM,
-  ADDRESS_CONST_INT,
-  ADDRESS_SYMBOLIC
-};
-
 /* Information about a function's frame layout.  */
 struct GTY(())  riscv_frame_info {
   /* The size of the frame in bytes.  */
@@ -182,27 +160,6 @@ struct riscv_arg_info {
   unsigned int fpr_offset;
 };
 
-/* Information about an address described by riscv_address_type.
-
-   ADDRESS_CONST_INT
-   No fields are used.
-
-   ADDRESS_REG
-   REG is the base register and OFFSET is the constant offset.
-
-   ADDRESS_LO_SUM
-   REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
-   is the type of symbol it references.
-
-   ADDRESS_SYMBOLIC
-   SYMBOL_TYPE is the type of symbol that the address references.  */
-struct riscv_address_info {
-  enum riscv_address_type type;
-  rtx reg;
-  rtx offset;
-  enum riscv_symbol_type symbol_type;
-};
-
 /* One stage in a constant building sequence.  These sequences have
the form:
 
-- 
2.40.1



[PATCH 02/11] riscv: xtheadmempair: Fix CFA reg notes

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

The current implementation triggers an assertion in
dwarf2out_frame_debug_cfa_offset() under certain circumstances.
The standard code uses REG_FRAME_RELATED_EXPR notes instead
of REG_CFA_OFFSET notes when saving registers on the stack.
So let's do this as well.

gcc/ChangeLog:

* config/riscv/thead.cc (th_mempair_save_regs):
Emit REG_FRAME_RELATED_EXPR notes in prologue.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/thead.cc | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index 75203805310..d7e3cf80d9b 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -368,8 +368,12 @@ th_mempair_save_regs (rtx operands[4])
   rtx set2 = gen_rtx_SET (operands[2], operands[3]);
   rtx insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set1, 
set2)));
   RTX_FRAME_RELATED_P (insn) = 1;
-  add_reg_note (insn, REG_CFA_OFFSET, copy_rtx (set1));
-  add_reg_note (insn, REG_CFA_OFFSET, copy_rtx (set2));
+
+  REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ copy_rtx (set1), REG_NOTES (insn));
+
+  REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ copy_rtx (set2), REG_NOTES (insn));
 }
 
 /* Similar like riscv_restore_reg, but restores two registers from memory
-- 
2.40.1



[PATCH 04/11] riscv: thead: Adjust constraints of th_addsl INSN

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

A recent change adjusted the constraints of ZBA's shNadd INSN.
Let's mirror this change here as well.

gcc/ChangeLog:

* config/riscv/thead.md: Adjust constraints of th_addsl.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/thead.md | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 6a06d0dfcf2..aa933960a98 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -22,10 +22,9 @@
 (define_insn "*th_addsl4"
   [(set (match_operand:X 0 "register_operand" "=r")
(plus:X (ashift:X (match_operand:X 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "n"))
+ (match_operand:QI 2 "imm123_operand" "Ds3"))
(match_operand:X 3 "register_operand" "r")))]
-  "TARGET_XTHEADBA
-   && (INTVAL (operands[2]) >= 0) && (INTVAL (operands[2]) <= 3)"
+  "TARGET_XTHEADBA"
   "th.addsl\t%0,%3,%1,%2"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
-- 
2.40.1



[PATCH 05/11] riscv: Simplify output of MEM addresses

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

We have the following situation for MEM RTX objects:
* TARGET_PRINT_OPERAND expands to riscv_print_operand()
* This falls into the default case (unknown or on letter) of the outer
  switch-case-block and the MEM case of the inner switch-case-block and
  calls output_address() in final.cc with XEXP (op, 0) (the address)
* This calls targetm.asm_out.print_operand_address() which is
  riscv_print_operand_address()
* riscv_print_operand_address() is targeting the address of a MEM RTX
* riscv_print_operand_address() calls riscv_print_operand() for the offset
  and directly prints the register if the address is classified as ADDRESS_REG
* This falls into the default case (unknown or on letter) of the outer
  switch-case-block and the default case of the inner switch-case-block and
  calls output_addr_const().

However, since we know that offset must be a CONST_INT (which will be
followed by a '()' string), there is no need to call
riscv_print_operand() for the offset.
Instead we can take the shortcut and use output_addr_const().

This change also brings the code in riscv_print_operand_address()
in line with the other cases, where output_addr_const() is used
to print offsets.

Tested with GCC regression test suite and SPEC intrate.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 5d2550871c7..92043236b17 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4581,7 +4581,7 @@ riscv_print_operand_address (FILE *file, machine_mode 
mode ATTRIBUTE_UNUSED, rtx
 switch (addr.type)
   {
   case ADDRESS_REG:
-   riscv_print_operand (file, addr.offset, 0);
+   output_addr_const (file, riscv_strip_unspec_address (addr.offset));
fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
return;
 
-- 
2.40.1



[PATCH 01/11] riscv: xtheadbb: Add sign/zero extension support for th.ext and th.extu

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

The current support of the bitfield-extraction instructions
th.ext and th.extu (XTheadBb extension) only covers sign_extract
and zero_extract. This patch add support for sign_extend and
zero_extend to avoid any shifts for sign or zero extensions.

gcc/ChangeLog:

* config/riscv/riscv.md: No base-ISA extension splitter for XThead*.
* config/riscv/thead.md (*extend2_th_ext):
New XThead extension INSN.
(*zero_extendsidi2_th_extu): New XThead extension INSN.
(*zero_extendhi2_th_extu): New XThead extension INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-ext-1.c: New test.
* gcc.target/riscv/xtheadbb-extu-1.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.md |  6 +-
 gcc/config/riscv/thead.md | 31 +
 .../gcc.target/riscv/xtheadbb-ext-1.c | 67 +++
 .../gcc.target/riscv/xtheadbb-extu-1.c| 67 +++
 4 files changed, 168 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 1fb29da8a0b..f4cc99187ed 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -1368,7 +1368,7 @@ (define_insn_and_split "*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_ZBA
+  "TARGET_64BIT && !TARGET_ZBA && !TARGET_XTHEADBB
&& !(register_operand (operands[1], SImode)
 && reg_or_subregno (operands[1]) == VL_REGNUM)"
   "@
@@ -1395,7 +1395,7 @@ (define_insn_and_split "*zero_extendhi2"
   [(set (match_operand:GPR0 "register_operand" "=r,r")
(zero_extend:GPR
(match_operand:HI 1 "nonimmediate_operand" " r,m")))]
-  "!TARGET_ZBB"
+  "!TARGET_ZBB && !TARGET_XTHEADBB"
   "@
#
lhu\t%0,%1"
@@ -1451,7 +1451,7 @@ (define_insn_and_split 
"*extend2"
   [(set (match_operand:SUPERQI   0 "register_operand" "=r,r")
(sign_extend:SUPERQI
(match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
-  "!TARGET_ZBB"
+  "!TARGET_ZBB && !TARGET_XTHEADBB"
   "@
#
l\t%0,%1"
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 0623607d3dc..6a06d0dfcf2 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -59,6 +59,17 @@ (define_insn "*th_ext4"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
 
+(define_insn "*extend2_th_ext"
+  [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
+   (sign_extend:SUPERQI
+   (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
+  "TARGET_XTHEADBB"
+  "@
+   th.ext\t%0,%1,15,0
+   l\t%0,%1"
+  [(set_attr "type" "bitmanip,load")
+   (set_attr "mode" "")])
+
 (define_insn "*th_extu4"
   [(set (match_operand:GPR 0 "register_operand" "=r")
(zero_extract:GPR (match_operand:GPR 1 "register_operand" "r")
@@ -72,6 +83,26 @@ (define_insn "*th_extu4"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
 
+(define_insn "*zero_extendsidi2_th_extu"
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
+   (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
+  "TARGET_64BIT && TARGET_XTHEADBB"
+  "@
+   th.extu\t%0,%1,31,0
+   lwu\t%0,%1"
+  [(set_attr "type" "bitmanip,load")
+   (set_attr "mode" "SI")])
+
+(define_insn "*zero_extendhi2_th_extu"
+  [(set (match_operand:GPR 0 "register_operand" "=r,r")
+   (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
+  "TARGET_XTHEADBB"
+  "@
+   th.extu\t%0,%1,15,0
+   lhu\t%0,%1"
+  [(set_attr "type" "bitmanip,load")
+   (set_attr "mode" "HI")])
+
 (define_insn "*th_clz2"
   [(set (match_operand:X 0 "register_operand" "=r")
(clz:X (match_operand:X 1 "register_operand" "r")))]
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c 
b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c
new file mode 100644
index 000..02f6ec1417d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c
@@ -0,0 +1,67 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+long sext64_32(int s32)
+{
+return s32;
+}
+
+long sext64_16(short s16)
+{
+return s16;
+}
+
+long sext64_8(char s8)
+{
+return s8;
+}
+
+int sext32_64(long s64)
+{
+return s64;
+}
+
+int sext32_16(short s16)
+{
+return s16;
+}
+
+int sext32_8(char s8)
+{
+return s8;
+}
+
+short sext16_64(long s64)
+{
+return s64;
+}
+
+short sext16_32(int s32)
+{
+return s32;
+}
+
+short sext16_8(char s8)
+{
+return s8;
+}
+
+char sext8_64(long s64)
+{
+return s64;
+}
+

[PATCH 00/11] Improvements for XThead* support

2023-04-28 Thread Christoph Muellner
From: Christoph Müllner 

This series improves the support for the XThead* ISA extensions
which are available e.g. on the T-Head XuanTie C906.

The ISA spec can be found here:
  https://github.com/T-head-Semi/thead-extension-spec

So far the following extension support has been merged in GCC:
* XTheadBa
* XTheadBb
* XTheadBs
* XTheadCmo
* XTheadCondMov
* XTheadMemPair

This patchset builds upon that and contains the following changes:
* Fix for sign/zero extension support for th.ext and th.extu
  This is actually a resend, that has not been merged.
  Jeff Law acked the patch last Friday.
* Fix for CFA reg notes creation
* Small fix for documentation of th_mempair_order_operands()
* Introduction of Xmode macro
* Two non-functional preparation commits for additional addressing modes
* A patch that moves XThead* specific peephole passes in its own file
* Support for XTheadMemIdx and its addressing modes
* Support for XTheadFMemIdx, which is similar to XTheadMemIdx

All patches have been tested and don't introduce regressions
for RV32 or RV64. The patches have also been tested with
SPEC CPU2017 on QEMU (multiple combinations of extensions).

Support patches of these extensions for Binutils, QEMU, and
LLVM have already been merged in the corresponding upstream
projects.

Support patches for XTheadMemIdx and XTheadFMemIdx have been
submitted in an earlier series as well and received a couple of
rework-comments from Kito. We rewrote the whole support to
better meet the (reasonable) goal of keeping vendor extension
code separated from RISC-V standard code and to address other issues.
The resulting code is structured much better, which can be seen
in the small number of changes that are required for the last patch
(XTheadFMemIdx support).

Christoph Müllner (11):
  riscv: xtheadbb: Add sign/zero extension support for th.ext and
th.extu
  riscv: xtheadmempair: Fix CFA reg notes
  riscv: xtheadmempair: Fix doc for th_mempair_order_operands()
  riscv: thead: Adjust constraints of th_addsl INSN
  riscv: Simplify output of MEM addresses
  riscv: Define Xmode macro
  riscv: Move address classification info types to riscv-protos.h
  riscv: Prepare backend for index registers
  riscv: thead: Factor out XThead*-specific peepholes
  riscv: thead: Add support for the XTheadMemIdx ISA extension
  riscv: thead: Add support for the XTheadFMemIdx ISA extension

 gcc/config/riscv/constraints.md   |  24 +
 gcc/config/riscv/peephole.md  |  56 --
 gcc/config/riscv/riscv-protos.h   |  74 +++
 gcc/config/riscv/riscv.cc |  87 ++-
 gcc/config/riscv/riscv.h  |  13 +-
 gcc/config/riscv/riscv.md |  26 +-
 gcc/config/riscv/thead-peephole.md| 292 ++
 gcc/config/riscv/thead.cc | 506 +-
 gcc/config/riscv/thead.md | 240 -
 .../gcc.target/riscv/xtheadbb-ext-1.c |  67 +++
 .../gcc.target/riscv/xtheadbb-extu-1.c|  67 +++
 .../riscv/xtheadfmemidx-index-update.c|  20 +
 .../xtheadfmemidx-index-xtheadbb-update.c |  20 +
 .../riscv/xtheadfmemidx-index-xtheadbb.c  |  22 +
 .../gcc.target/riscv/xtheadfmemidx-index.c|  22 +
 .../riscv/xtheadfmemidx-uindex-update.c   |  20 +
 .../xtheadfmemidx-uindex-xtheadbb-update.c|  20 +
 .../riscv/xtheadfmemidx-uindex-xtheadbb.c |  24 +
 .../gcc.target/riscv/xtheadfmemidx-uindex.c   |  25 +
 .../gcc.target/riscv/xtheadmemidx-helpers.h   | 222 
 .../riscv/xtheadmemidx-index-update.c |  27 +
 .../xtheadmemidx-index-xtheadbb-update.c  |  27 +
 .../riscv/xtheadmemidx-index-xtheadbb.c   |  36 ++
 .../gcc.target/riscv/xtheadmemidx-index.c |  36 ++
 .../riscv/xtheadmemidx-modify-xtheadbb.c  |  74 +++
 .../gcc.target/riscv/xtheadmemidx-modify.c|  74 +++
 .../riscv/xtheadmemidx-uindex-update.c|  27 +
 .../xtheadmemidx-uindex-xtheadbb-update.c |  27 +
 .../riscv/xtheadmemidx-uindex-xtheadbb.c  |  44 ++
 .../gcc.target/riscv/xtheadmemidx-uindex.c|  44 ++
 30 files changed, 2146 insertions(+), 117 deletions(-)
 create mode 100644 gcc/config/riscv/thead-peephole.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c
 

[PATCH] target/109296 - riscv: Add missing mode specifiers for XTheadMemPair

2023-03-27 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds missing mode specifiers for XTheadMemPair INSNs.

gcc/ChangeLog:
PR target/109296
* config/riscv/thead.md: Add missing mode specifiers.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/thead.md | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 63c4af6f77d..0623607d3dc 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -321,10 +321,10 @@ (define_insn "*th_mempair_store_2"
 
 ;; MEMPAIR load DI extended signed SI
 (define_insn "*th_mempair_load_extendsidi2"
-  [(set (match_operand 0 "register_operand" "=r")
-   (sign_extend:DI (match_operand 1 "memory_operand" "m")))
-   (set (match_operand 2 "register_operand" "=r")
-   (sign_extend:DI (match_operand 3 "memory_operand" "m")))]
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (sign_extend:DI (match_operand:SI 1 "memory_operand" "m")))
+   (set (match_operand:DI 2 "register_operand" "=r")
+   (sign_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
   "TARGET_XTHEADMEMPAIR && TARGET_64BIT && reload_completed
&& th_mempair_operands_p (operands, true, SImode)"
   { return th_mempair_output_move (operands, true, SImode, SIGN_EXTEND); }
@@ -334,10 +334,10 @@ (define_insn "*th_mempair_load_extendsidi2"
 
 ;; MEMPAIR load DI extended unsigned SI
 (define_insn "*th_mempair_load_zero_extendsidi2"
-  [(set (match_operand 0 "register_operand" "=r")
-   (zero_extend:DI (match_operand 1 "memory_operand" "m")))
-   (set (match_operand 2 "register_operand" "=r")
-   (zero_extend:DI (match_operand 3 "memory_operand" "m")))]
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (zero_extend:DI (match_operand:SI 1 "memory_operand" "m")))
+   (set (match_operand:DI 2 "register_operand" "=r")
+   (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
   "TARGET_XTHEADMEMPAIR && TARGET_64BIT && reload_completed
&& th_mempair_operands_p (operands, true, SImode)"
   { return th_mempair_output_move (operands, true, SImode, ZERO_EXTEND); }
-- 
2.39.2



[PATCH] riscv: thead: Add sign/zero extension support for th.ext and th.extu

2023-03-15 Thread Christoph Muellner
From: Christoph Müllner 

The current support of the bitfield-extraction instructions
th.ext and th.extu (XTheadBb extension) only covers sign_extract
and zero_extract. This patch add support for sign_extend and
zero_extend to avoid any shifts for sign or zero extensions.

gcc/ChangeLog:

* config/riscv/riscv.md:
* config/riscv/thead.md (*extend2_th_ext):
(*zero_extendsidi2_th_extu):
(*zero_extendhi2_th_extu):

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-ext-1.c: New test.
* gcc.target/riscv/xtheadbb-extu-1.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.md |  6 +-
 gcc/config/riscv/thead.md | 31 +
 .../gcc.target/riscv/xtheadbb-ext-1.c | 67 +++
 .../gcc.target/riscv/xtheadbb-extu-1.c| 67 +++
 4 files changed, 168 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 863400cd447..b763b84b763 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -1368,7 +1368,7 @@ (define_insn_and_split "*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_ZBA
+  "TARGET_64BIT && !TARGET_ZBA && !TARGET_XTHEADBB
&& !(REG_P (operands[1])
 && REGNO (operands[1]) == VL_REGNUM)"
   "@
@@ -1395,7 +1395,7 @@ (define_insn_and_split "*zero_extendhi2"
   [(set (match_operand:GPR0 "register_operand" "=r,r")
(zero_extend:GPR
(match_operand:HI 1 "nonimmediate_operand" " r,m")))]
-  "!TARGET_ZBB"
+  "!TARGET_ZBB && !TARGET_XTHEADBB"
   "@
#
lhu\t%0,%1"
@@ -1451,7 +1451,7 @@ (define_insn_and_split 
"*extend2"
   [(set (match_operand:SUPERQI   0 "register_operand" "=r,r")
(sign_extend:SUPERQI
(match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
-  "!TARGET_ZBB"
+  "!TARGET_ZBB && !TARGET_XTHEADBB"
   "@
#
l\t%0,%1"
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 63c4af6f77d..978402e0b5d 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -59,6 +59,17 @@ (define_insn "*th_ext4"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
 
+(define_insn "*extend2_th_ext"
+  [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
+   (sign_extend:SUPERQI
+   (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
+  "TARGET_XTHEADBB"
+  "@
+   th.ext\t%0,%1,15,0
+   l\t%0,%1"
+  [(set_attr "type" "bitmanip,load")
+   (set_attr "mode" "")])
+
 (define_insn "*th_extu4"
   [(set (match_operand:GPR 0 "register_operand" "=r")
(zero_extract:GPR (match_operand:GPR 1 "register_operand" "r")
@@ -72,6 +83,26 @@ (define_insn "*th_extu4"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
 
+(define_insn "*zero_extendsidi2_th_extu"
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
+   (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
+  "TARGET_64BIT && TARGET_XTHEADBB"
+  "@
+   th.extu\t%0,%1,31,0
+   lwu\t%0,%1"
+  [(set_attr "type" "bitmanip,load")
+   (set_attr "mode" "SI")])
+
+(define_insn "*zero_extendhi2_th_extu"
+  [(set (match_operand:GPR 0 "register_operand" "=r,r")
+   (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
+  "TARGET_XTHEADBB"
+  "@
+   th.extu\t%0,%1,15,0
+   lhu\t%0,%1"
+  [(set_attr "type" "bitmanip,load")
+   (set_attr "mode" "HI")])
+
 (define_insn "*th_clz2"
   [(set (match_operand:X 0 "register_operand" "=r")
(clz:X (match_operand:X 1 "register_operand" "r")))]
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c 
b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c
new file mode 100644
index 000..02f6ec1417d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c
@@ -0,0 +1,67 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+long sext64_32(int s32)
+{
+return s32;
+}
+
+long sext64_16(short s16)
+{
+return s16;
+}
+
+long sext64_8(char s8)
+{
+return s8;
+}
+
+int sext32_64(long s64)
+{
+return s64;
+}
+
+int sext32_16(short s16)
+{
+return s16;
+}
+
+int sext32_8(char s8)
+{
+return s8;
+}
+
+short sext16_64(long s64)
+{
+return s64;
+}
+
+short sext16_32(int s32)
+{
+return s32;
+}
+
+short sext16_8(char s8)
+{
+return s8;
+}
+
+char sext8_64(long s64)
+{
+return s64;
+}
+
+char sext8_32(int s32)
+{
+return s32;
+}
+
+char sext8_16(short s16)
+{
+return s16;
+}
+
+/* { dg-final { scan-assembler-not "slli" } } */
+/* { 

[PATCH v4 9/9] riscv: thead: Add support for the XTheadMemPair ISA extension

2023-03-02 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadMemPair ISA extension allows to pair two loads or stores:
* th.ldd (2x LD)
* th.lwd (2x LW)
* th.lwud (2x LWU)
* th.sdd (2x SD)
* th.swd (2x SW)

The displacement of these instructions is quite limited:
* Displacement := imm2 << shamt
* imm2 is a 2-bit unsigned value {0..3}
* shamt is 4 for th.ldd/th.sdd and 3 otherwise
But even with this small displacement we can identify many candidates.

The merge of the two loads/stores is realized in form of peephole2
passes that support instruction reordering.
The CFA expansion (save/restore registers on/from stack) is not
processed by the peephole2 pass and, therefore, needs special-treatment.
Many ideas of this patch are inspired by similar/equal approaches
in other backends.

gcc/ChangeLog:

* config.gcc: Add thead.o to RISC-V extra_objs.
* config/riscv/peephole.md: Add mempair peephole passes.
* config/riscv/riscv-protos.h (riscv_split_64bit_move_p): New
prototype.
(th_mempair_operands_p): Likewise.
(th_mempair_order_operands): Likewise.
(th_mempair_prepare_save_restore_operands): Likewise.
(th_mempair_save_restore_regs): Likewise.
(th_mempair_output_move): Likewise.
* config/riscv/riscv.cc (riscv_save_reg): Move code.
(riscv_restore_reg): Move code.
(riscv_for_each_saved_reg): Add code to emit mempair insns.
* config/riscv/t-riscv: Add thead.cc.
* config/riscv/thead.md (*th_mempair_load_2):
New insn.
(*th_mempair_store_2): Likewise.
(*th_mempair_load_extendsidi2): Likewise.
(*th_mempair_load_zero_extendsidi2): Likewise.
* config/riscv/thead.cc: New file.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadmempair-1.c: New test.
* gcc.target/riscv/xtheadmempair-2.c: New test.
* gcc.target/riscv/xtheadmempair-3.c: New test.

Changes in v4:
- Unify function prefix ("th_")
- Move th_* functions to thead.cc
- Minimize code in CFA code in riscv.cc

Changes in v3:
- Don't emit instructions during peephole2, but emit parallel INSNs
- Add proper checks for the INSN patterns to avoid ICEs or illegal
  instructions reported by the assembler
- Don't insert any `add` instructions
- Rework the constraint handling
- Simplify the output function
- Restructure and simplify CFA processing
- Add debug notes to CFA instructions
- Emit parallel INSNs in the CFA code (same as peephole2)
- Drop tests that target reordering
- Drop tests that are irrelevant (e.g. unrolled loops)
- Add tests for all possible displacements and all instructions
- Add tests for CFA

Signed-off-by: Christoph Müllner 
---
 gcc/config.gcc|   1 +
 gcc/config/riscv/peephole.md  |  56 +++
 gcc/config/riscv/riscv-protos.h   |  14 +
 gcc/config/riscv/riscv.cc |  88 ++--
 gcc/config/riscv/t-riscv  |   4 +
 gcc/config/riscv/thead.cc | 427 ++
 gcc/config/riscv/thead.md |  52 +++
 .../gcc.target/riscv/xtheadmempair-1.c|  98 
 .../gcc.target/riscv/xtheadmempair-2.c|  84 
 .../gcc.target/riscv/xtheadmempair-3.c|  29 ++
 10 files changed, 824 insertions(+), 29 deletions(-)
 create mode 100644 gcc/config/riscv/thead.cc
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-3.c

diff --git a/gcc/config.gcc b/gcc/config.gcc
index c070e6ecd2e..ad0b6d3302a 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -531,6 +531,7 @@ riscv*)
cpu_type=riscv
extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o 
riscv-shorten-memrefs.o riscv-selftests.o riscv-v.o riscv-vsetvl.o"
extra_objs="${extra_objs} riscv-vector-builtins.o 
riscv-vector-builtins-shapes.o riscv-vector-builtins-bases.o"
+   extra_objs="${extra_objs} thead.o"
d_target_objs="riscv-d.o"
extra_headers="riscv_vector.h"
target_gtfiles="$target_gtfiles 
\$(srcdir)/config/riscv/riscv-vector-builtins.cc"
diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md
index 0ef0c04410b..67e7046d7e6 100644
--- a/gcc/config/riscv/peephole.md
+++ b/gcc/config/riscv/peephole.md
@@ -38,3 +38,59 @@ (define_peephole2
 {
   operands[5] = GEN_INT (INTVAL (operands[2]) - INTVAL (operands[5]));
 })
+
+;; XTheadMemPair: merge two SI or DI loads
+(define_peephole2
+  [(set (match_operand:GPR 0 "register_operand" "")
+   (match_operand:GPR 1 "memory_operand" ""))
+   (set (match_operand:GPR 2 "register_operand" "")
+   (match_operand:GPR 3 "memory_operand" ""))]
+  "TARGET_XTHEADMEMPAIR
+  && th_mempair_operands_p (operands, true, mode)"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+ (set (match_dup 2) (match_dup 3))])]
+{
+  th_mempair_order_operands (operands, true, 

[PATCH v4 7/9] riscv: thead: Add support for the XTheadMac ISA extension

2023-03-02 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadMac ISA extension provides multiply-accumulate/subtract
instructions:
* mula/mulaw/mulah
* muls/mulsw/mulsh

To benefit from middle-end passes, we expand the following named
patterns in riscv.md (as they are not T-Head-specific):
* maddhisi4
* msubhisi4

gcc/ChangeLog:

* config/riscv/riscv.md (maddhisi4): New expand.
(msubhisi4): New expand.
* config/riscv/thead.md (*th_mula): New pattern.
(*th_mulawsi): New pattern.
(*th_mulawsi2): New pattern.
(*th_maddhisi4): New pattern.
(*th_sextw_maddhisi4): New pattern.
(*th_muls): New pattern.
(*th_mulswsi): New pattern.
(*th_mulswsi2): New pattern.
(*th_msubhisi4): New pattern.
(*th_sextw_msubhisi4): New pattern.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/thead-mula-muls.c: New test.

Co-Developed-by: Xianmiao Qu 
Signed-off-by: Xianmiao Qu 
Signed-off-by: Christoph Müllner 

Changed in v2:
- Add missing prefix in on INSN
---
 gcc/config/riscv/riscv.md |  18 +++
 gcc/config/riscv/thead.md | 121 ++
 .../gcc.target/riscv/xtheadmac-mula-muls.c|  43 +++
 3 files changed, 182 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac-mula-muls.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 5562e5621fa..112c93f733e 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3106,6 +3106,24 @@ (define_expand "extzv"
 FAIL;
 })
 
+(define_expand "maddhisi4"
+  [(set (match_operand:SI 0 "register_operand")
+   (plus:SI
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"))
+  (sign_extend:SI (match_operand:HI 2 "register_operand")))
+ (match_operand:SI 3 "register_operand")))]
+  "TARGET_XTHEADMAC"
+)
+
+(define_expand "msubhisi4"
+  [(set (match_operand:SI 0 "register_operand")
+   (minus:SI
+ (match_operand:SI 3 "register_operand")
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"))
+  (sign_extend:SI (match_operand:HI 2 "register_operand")]
+  "TARGET_XTHEADMAC"
+)
+
 (include "bitmanip.md")
 (include "sync.md")
 (include "peephole.md")
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 88b6a95e993..ce709ca79a4 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -138,3 +138,124 @@ (define_insn "*th_cond_gpr_mov"
th.mveqz\t%0,%z3,%1"
   [(set_attr "type" "condmove")
(set_attr "mode" "")])
+
+;; XTheadMac
+
+(define_insn "*th_mula"
+  [(set (match_operand:X 0 "register_operand" "=r")
+ (plus:X (mult:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:X 2 "register_operand" "r"))
+ (match_operand:X 3 "register_operand" "0")))]
+  "TARGET_XTHEADMAC"
+  "th.mula\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "")]
+)
+
+(define_insn "*th_mulawsi"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (sign_extend:DI
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+   (match_operand:SI 2 "register_operand" "r"))
+  (match_operand:SI 3 "register_operand" "0"]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulaw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_mulawsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+   (match_operand:SI 2 "register_operand" "r"))
+  (match_operand:SI 3 "register_operand" "0")))]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulaw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_maddhisi4"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI
+   (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" " r"))
+ (sign_extend:SI (match_operand:HI 2 "register_operand" " r")))
+   (match_operand:SI 3 "register_operand" " 0")))]
+  "TARGET_XTHEADMAC"
+  "th.mulah\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_sextw_maddhisi4"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (sign_extend:DI
+ (plus:SI
+   (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" " r"))
+ (sign_extend:SI (match_operand:HI 2 "register_operand" " r")))
+   (match_operand:SI 3 "register_operand" " 0"]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulah\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_muls"
+  [(set (match_operand:X 0 "register_operand" "=r")
+ (minus:X (match_operand:X 3 "register_operand" "0")
+  (mult:X 

[PATCH v4 8/9] riscv: thead: Add support for the XTheadFmv ISA extension

2023-03-02 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadFmv ISA extension provides instructions to move
data between 32-bit GP registers and 64-bit FP registers.

gcc/ChangeLog:

* config/riscv/constraints.md (TARGET_XTHEADFMV ? FP_REGS : NO_REGS)
New constraint "th_f_fmv".
(TARGET_XTHEADFMV ? GR_REGS : NO_REGS): New constraint
"th_r_fmv".
* config/riscv/riscv.cc (riscv_split_doubleword_move):
Add split code for XTheadFmv.
(riscv_secondary_memory_needed): XTheadFmv does not need
secondary memory.
* config/riscv/riscv.md: Add new UNSPEC_XTHEADFMV and
UNSPEC_XTHEADFMV_HW. Add support for XTheadFmv to
movdf_hardfloat_rv32.
* config/riscv/thead.md (th_fmv_hw_w_x): New INSN.
(th_fmv_x_w): New INSN.
(th_fmv_x_hw): New INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadfmv-fmv.c: New test.

Co-Developed-by: Xianmiao Qu 
Signed-off-by: Xianmiao Qu 
Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/constraints.md   |  8 +
 gcc/config/riscv/riscv.cc | 25 --
 gcc/config/riscv/riscv.md | 11 +--
 gcc/config/riscv/thead.md | 33 +++
 .../gcc.target/riscv/xtheadfmv-fmv.c  | 24 ++
 5 files changed, 95 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c

diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index a051d466ae2..e49019d8fa9 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -166,3 +166,11 @@ (define_memory_constraint "Wdm"
   "Vector duplicate memory operand"
   (and (match_code "mem")
(match_code "reg" "0")))
+
+;; Vendor ISA extension constraints.
+
+(define_register_constraint "th_f_fmv" "TARGET_XTHEADFMV ? FP_REGS : NO_REGS"
+  "A floating-point register for XTheadFmv.")
+
+(define_register_constraint "th_r_fmv" "TARGET_XTHEADFMV ? GR_REGS : NO_REGS"
+  "An integer register for XTheadFmv.")
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a60ab2c7fad..48f2cb399ae 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2754,11 +2754,29 @@ riscv_split_64bit_move_p (rtx dest, rtx src)
 void
 riscv_split_doubleword_move (rtx dest, rtx src)
 {
-  rtx low_dest;
+  /* XTheadFmv has instructions for accessing the upper bits of a double.  */
+  if (!TARGET_64BIT && TARGET_XTHEADFMV)
+{
+  if (FP_REG_RTX_P (dest))
+   {
+ rtx low_src = riscv_subword (src, false);
+ rtx high_src = riscv_subword (src, true);
+ emit_insn (gen_th_fmv_hw_w_x (dest, high_src, low_src));
+ return;
+   }
+  if (FP_REG_RTX_P (src))
+   {
+ rtx low_dest = riscv_subword (dest, false);
+ rtx high_dest = riscv_subword (dest, true);
+ emit_insn (gen_th_fmv_x_w (low_dest, src));
+ emit_insn (gen_th_fmv_x_hw (high_dest, src));
+ return;
+   }
+}
 
/* The operation can be split into two normal moves.  Decide in
   which order to do them.  */
-   low_dest = riscv_subword (dest, false);
+   rtx low_dest = riscv_subword (dest, false);
if (REG_P (low_dest) && reg_overlap_mentioned_p (low_dest, src))
  {
riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
@@ -5802,7 +5820,8 @@ riscv_secondary_memory_needed (machine_mode mode, 
reg_class_t class1,
 {
   return (!riscv_v_ext_vector_mode_p (mode)
  && GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD
- && (class1 == FP_REGS) != (class2 == FP_REGS));
+ && (class1 == FP_REGS) != (class2 == FP_REGS)
+ && !TARGET_XTHEADFMV);
 }
 
 /* Implement TARGET_REGISTER_MOVE_COST.  */
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 112c93f733e..61f175bb62b 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -100,6 +100,10 @@ (define_c_enum "unspecv" [
 
   ;; Zihintpause unspec
   UNSPECV_PAUSE
+
+  ;; XTheadFmv unspec
+  UNSPEC_XTHEADFMV
+  UNSPEC_XTHEADFMV_HW
 ])
 
 (define_constants
@@ -1856,16 +1860,17 @@ (define_expand "movdf"
 DONE;
 })
 
+
 ;; In RV32, we lack fmv.x.d and fmv.d.x.  Go through memory instead.
 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
 (define_insn "*movdf_hardfloat_rv32"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,  *r,*r,*m")
-   (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r*G,*m,*r"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" 
"=f,f,f,m,m,*th_f_fmv,*th_r_fmv,  *r,*r,*m")
+   (match_operand:DF 1 "move_operand" " 
f,G,m,f,G,*th_r_fmv,*th_f_fmv,*r*G,*m,*r"))]
   "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
&& (register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))"
   { return riscv_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" 

[PATCH v4 6/9] riscv: thead: Add support for the XTheadCondMov ISA extensions

2023-03-02 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for XTheadCondMov ISA extension.
The extension brings a one-sided conditional move (no else-assignment).
Given that GCC has a great if-conversion pass, we don't need to do much,
besides properly expanding movcc accordingly and adjust the cost
model.

gcc/ChangeLog:

* config/riscv/iterators.md (TARGET_64BIT): Add GPR2 iterator.
* config/riscv/riscv-protos.h (riscv_expand_conditional_move):
Add prototype.
* config/riscv/riscv.cc (riscv_rtx_costs): Add costs for
XTheadCondMov.
(riscv_expand_conditional_move): New function.
(riscv_expand_conditional_move_onesided): New function.
* config/riscv/riscv.md: Add support for XTheadCondMov.
* config/riscv/thead.md (*th_cond_mov): Add
support for XTheadCondMov.
(*th_cond_gpr_mov): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c: New test.

Changes for v2:
- Properly gate expansion constraints to avoid failing INSN lookup
- Restrict subreg comparisons

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/iterators.md |   4 +
 gcc/config/riscv/riscv-protos.h   |   2 +-
 gcc/config/riscv/riscv.cc | 100 +++---
 gcc/config/riscv/riscv.md |  17 ++-
 gcc/config/riscv/thead.md |  37 +++
 .../riscv/xtheadcondmov-mveqz-imm-eqz.c   |  38 +++
 .../riscv/xtheadcondmov-mveqz-imm-not.c   |  38 +++
 .../riscv/xtheadcondmov-mveqz-reg-eqz.c   |  38 +++
 .../riscv/xtheadcondmov-mveqz-reg-not.c   |  38 +++
 .../riscv/xtheadcondmov-mvnez-imm-cond.c  |  38 +++
 .../riscv/xtheadcondmov-mvnez-imm-nez.c   |  38 +++
 .../riscv/xtheadcondmov-mvnez-reg-cond.c  |  38 +++
 .../riscv/xtheadcondmov-mvnez-reg-nez.c   |  38 +++
 13 files changed, 440 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c

diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 5b70ab20758..9b767038452 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -26,6 +26,10 @@
 ;; from the same template.
 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
 
+;; A copy of GPR that can be used when a pattern has two independent
+;; modes.
+(define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
+
 ;; This mode iterator allows :P to be used for patterns that operate on
 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 37c634eca1d..5cf4fafd662 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -58,8 +58,8 @@ extern const char *riscv_output_return ();
 extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx);
 extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx);
 extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx);
-extern void riscv_expand_conditional_move (rtx, rtx, rtx, rtx_code, rtx, rtx);
 #endif
+extern bool riscv_expand_conditional_move (rtx, rtx, rtx, rtx);
 extern rtx riscv_legitimize_call_address (rtx);
 extern void riscv_set_return_address (rtx, rtx);
 extern bool riscv_expand_block_move (rtx, rtx, rtx);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 7613bae8024..a60ab2c7fad 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2300,8 +2300,8 @@ 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
- && register_operand (XEXP (x, 1), mode)
+  if ((TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
+ && reg_or_0_operand 

[PATCH v4 5/9] riscv: thead: Add support for the XTheadBb ISA extension

2023-03-02 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the XTheadBb ISA extension.
Thus, there is a functional overlap of the new instructions with
existing Bitmanip instruction, which allows a good amount of code
sharing. However, the vendor extensions are cleanly separated from
the standard extensions (e.g. by using INSN expand pattern that
will re-emit RTL that matches the patterns of either Bitmanip or
XThead INSNs).

gcc/ChangeLog:

* config/riscv/bitmanip.md (clzdi2): New expand.
(clzsi2): New expand.
(ctz2): New expand.
(popcount2): New expand.
(si2): Rename INSN.
(*si2): Hide INSN name.
(di2): Rename INSN.
(*di2): Hide INSN name.
(rotrsi3): Remove INSN.
(rotr3): Add expand.
(*rotrsi3): New INSN.
(rotrdi3): Rename INSN.
(*rotrdi3): Hide INSN name.
(rotrsi3_sext): Rename INSN.
(*rotrsi3_sext): Hide INSN name.
(bswap2): Remove INSN.
(bswapdi2): Add expand.
(bswapsi2): Add expand.
(*bswap2): Hide INSN name.
* config/riscv/riscv.cc (riscv_rtx_costs): Add costs for sign
extraction.
* config/riscv/riscv.md (extv): New expand.
(extzv): New expand.
* config/riscv/thead.md (*th_srri3): New INSN.
(*th_ext): New INSN.
(*th_extu): New INSN.
(*th_clz2): New INSN.
(*th_rev2): New INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-ext.c: New test.
* gcc.target/riscv/xtheadbb-extu-2.c: New test.
* gcc.target/riscv/xtheadbb-extu.c: New test.
* gcc.target/riscv/xtheadbb-ff1.c: New test.
* gcc.target/riscv/xtheadbb-rev.c: New test.
* gcc.target/riscv/xtheadbb-srri.c: New test.

Changes in v4:
- Replace 'immediate_operand' by 'const_int_operand'
- Add number of arguments to pattern names
- Merge th_srri3 patterns
- Merge th_rev2 patterns
- Improve coverage of th.srri test

Changes for v2:
- Merge all XTheadB* support patches
- Remove useless operand sanity checks for extv and extzv
- Prefer c.andi over th.extu if possible
- Add ff1 tests for clz/ctz
- Fix ext/extu test cases
- Enable tests for RV32

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/bitmanip.md  | 52 ++--
 gcc/config/riscv/riscv.cc |  9 +++
 gcc/config/riscv/riscv.md | 20 ++
 gcc/config/riscv/thead.md | 61 +++
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c | 20 ++
 .../gcc.target/riscv/xtheadbb-extu-2.c| 22 +++
 .../gcc.target/riscv/xtheadbb-extu.c  | 22 +++
 gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c | 18 ++
 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c | 45 ++
 .../gcc.target/riscv/xtheadbb-srri.c  | 25 
 10 files changed, 288 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 14d18edbe62..ca0c98ee686 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -185,6 +185,26 @@ (define_insn "*slliuw"
 
 ;; ZBB extension.
 
+(define_expand "clzdi2"
+  [(set (match_operand:DI 0 "register_operand")
+   (clz:DI (match_operand:DI 1 "register_operand")))]
+  "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB)")
+
+(define_expand "clzsi2"
+  [(set (match_operand:SI 0 "register_operand")
+   (clz:SI (match_operand:SI 1 "register_operand")))]
+  "TARGET_ZBB || (!TARGET_64BIT && TARGET_XTHEADBB)")
+
+(define_expand "ctz2"
+  [(set (match_operand:GPR 0 "register_operand")
+   (ctz:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB")
+
+(define_expand "popcount2"
+  [(set (match_operand:GPR 0 "register_operand")
+   (popcount:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB")
+
 (define_insn "*_not"
   [(set (match_operand:X 0 "register_operand" "=r")
 (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
@@ -216,7 +236,7 @@ (define_insn "*xor_not"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
 
-(define_insn "si2"
+(define_insn "*si2"
   [(set (match_operand:SI 0 "register_operand" "=r")
 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))]
   "TARGET_ZBB"
@@ -233,7 +253,7 @@ (define_insn "*disi2"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "SI")])
 
-(define_insn "di2"
+(define_insn "*di2"
   [(set (match_operand:DI 0 "register_operand" "=r")
 (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
   "TARGET_64BIT && 

[PATCH v4 3/9] riscv: thead: Add support for the XTheadBa ISA extension

2023-03-02 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the XTheadBa ISA extension.
The new INSN pattern is defined in a new file to separate
this vendor extension from the standard extensions.

gcc/ChangeLog:

* config/riscv/riscv.md: Include thead.md
* config/riscv/thead.md: New file.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadba-addsl.c: New test.

Changes in v4:
- Replace 'immediate_operand' by 'const_int_operand'
- Add number of arguments to pattern name

Changes in v3:
- Fix operand order for th.addsl.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.md |  1 +
 gcc/config/riscv/thead.md | 31 +++
 .../gcc.target/riscv/xtheadba-addsl.c | 55 +++
 3 files changed, 87 insertions(+)
 create mode 100644 gcc/config/riscv/thead.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 05924e9bbf1..d6c2265e9d4 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3093,4 +3093,5 @@ (define_insn "riscv_prefetchi_"
 (include "pic.md")
 (include "generic.md")
 (include "sifive-7.md")
+(include "thead.md")
 (include "vector.md")
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
new file mode 100644
index 000..2da5aaee94f
--- /dev/null
+++ b/gcc/config/riscv/thead.md
@@ -0,0 +1,31 @@
+;; Machine description for T-Head vendor extensions
+;; Copyright (C) 2021-2022 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
+;; .
+
+;; XTheadBa
+
+(define_insn "*th_addsl4"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (plus:X (ashift:X (match_operand:X 1 "register_operand" "r")
+ (match_operand 2 "const_int_operand" "n"))
+   (match_operand:X 3 "register_operand" "r")))]
+  "TARGET_XTHEADBA
+   && (INTVAL (operands[2]) >= 0) && (INTVAL (operands[2]) <= 3)"
+  "th.addsl\t%0,%3,%1,%2"
+  [(set_attr "type" "bitmanip")
+   (set_attr "mode" "")])
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c 
b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
new file mode 100644
index 000..5004735a246
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadba" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadba" { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+long
+test_1 (long a, long b)
+{
+  /* th.addsl aX, aX, 1  */
+  return a + (b << 1);
+}
+
+int
+foos (short *x, int n)
+{
+  /* th.addsl aX, aX, 1  */
+  return x[n];
+}
+
+long
+test_2 (long a, long b)
+{
+  /* th.addsl aX, aX, 2  */
+  return a + (b << 2);
+}
+
+int
+fooi (int *x, int n)
+{
+  /* th.addsl aX, aX, 2  */
+  return x[n];
+}
+
+long
+test_3 (long a, long b)
+{
+  /* th.addsl aX, aX, 3  */
+  return a + (b << 3);
+}
+
+long
+fool (long *x, int n)
+{
+  /* th.addsl aX, aX, 2 (rv32)  */
+  /* th.addsl aX, aX, 3 (rv64)  */
+  return x[n];
+}
+
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,1" 2 } } */
+
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,2" 3 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,2" 2 { target { rv64 } } } } */
+
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,3" 1 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,3" 2 { target { rv64 } } } } */
-- 
2.39.2



[PATCH v4 4/9] riscv: thead: Add support for the XTheadBs ISA extension

2023-03-02 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the XTheadBs ISA extension.
The new INSN pattern is defined in a new file to separate
this vendor extension from the standard extensions.
The cost model adjustment reuses the xbs:bext cost.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_rtx_costs): Add xthead:tst cost.
* config/riscv/thead.md (*th_tst3): New INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbs-tst.c: New test.

Changes in v4:
- Replace 'immediate_operand' by 'const_int_operand'
- Add number of arguments to pattern name
- Add range check

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.cc |  4 ++--
 gcc/config/riscv/thead.md | 11 +++
 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c | 13 +
 3 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f11b7949a49..e35bc0a745b 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2400,8 +2400,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int 
outer_code, int opno ATTRIBUTE_UN
  *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
  return true;
}
-  /* bext pattern for zbs.  */
-  if (TARGET_ZBS && outer_code == SET
+  /* bit extraction pattern (zbs:bext, xtheadbs:tst).  */
+  if ((TARGET_ZBS || TARGET_XTHEADBS) && outer_code == SET
  && GET_CODE (XEXP (x, 1)) == CONST_INT
  && INTVAL (XEXP (x, 1)) == 1)
{
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 2da5aaee94f..3842a194d16 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -29,3 +29,14 @@ (define_insn "*th_addsl4"
   "th.addsl\t%0,%3,%1,%2"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
+
+;; XTheadBs
+
+(define_insn "*th_tst3"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (zero_extract:X (match_operand:X 1 "register_operand" "r")
+   (const_int 1)
+   (match_operand 2 "const_int_operand" "n")))]
+  "TARGET_XTHEADBS && UINTVAL (operands[2]) < GET_MODE_BITSIZE (mode)"
+  "th.tst\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")])
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c 
b/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c
new file mode 100644
index 000..674cec09128
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadbs" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadbs" { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+long
+foo1 (long i)
+{
+  return 1L & (i >> 20);
+}
+
+/* { dg-final { scan-assembler-times "th.tst\t" 1 } } */
+/* { dg-final { scan-assembler-not "andi" } } */
-- 
2.39.2



[PATCH v4 2/9] riscv: riscv-cores.def: Add T-Head XuanTie C906

2023-03-02 Thread Christoph Muellner
From: Christoph Müllner 

This adds T-Head's XuanTie C906 to the list of known cores as "thead-c906".
The C906 is shipped for quite some time (it is the core of the Allwinner D1).
Note, that the tuning struct for the C906 is already part of GCC (it is
also name "thead-c906").

gcc/ChangeLog:

* config/riscv/riscv-cores.def (RISCV_CORE): Add "thead-c906".

gcc/testsuite/ChangeLog:

* gcc.target/riscv/mcpu-thead-c906.c: New test.

Changes for v2:
- Enable all supported vendor extensions

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv-cores.def  |  4 +++
 .../gcc.target/riscv/mcpu-thead-c906.c| 28 +++
 2 files changed, 32 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c

diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
index 2a834cae21d..7d87ab7ce28 100644
--- a/gcc/config/riscv/riscv-cores.def
+++ b/gcc/config/riscv/riscv-cores.def
@@ -73,4 +73,8 @@ RISCV_CORE("sifive-s76",  "rv64imafdc", "sifive-7-series")
 RISCV_CORE("sifive-u54",  "rv64imafdc", "sifive-5-series")
 RISCV_CORE("sifive-u74",  "rv64imafdc", "sifive-7-series")
 
+RISCV_CORE("thead-c906",  
"rv64imafdc_xtheadba_xtheadbb_xtheadbs_xtheadcmo_"
+ "xtheadcondmov_xtheadfmemidx_xtheadmac_"
+ "xtheadmemidx_xtheadmempair_xtheadsync",
+ "thead-c906")
 #undef RISCV_CORE
diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c 
b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
new file mode 100644
index 000..a71b43a6167
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */
+/* { dg-options "-mcpu=thead-c906" { target { rv64 } } } */
+/* T-Head XuanTie C906 => rv64imafdc */
+
+#if !((__riscv_xlen == 64) \
+  && !defined(__riscv_32e) \
+  && defined(__riscv_mul)  \
+  && defined(__riscv_atomic)   \
+  && (__riscv_flen == 64)  \
+  && defined(__riscv_compressed)   \
+  && defined(__riscv_xtheadba) \
+  && defined(__riscv_xtheadbb) \
+  && defined(__riscv_xtheadbs) \
+  && defined(__riscv_xtheadcmo)\
+  && defined(__riscv_xtheadcondmov)\
+  && defined(__riscv_xtheadfmemidx)\
+  && defined(__riscv_xtheadmac)\
+  && defined(__riscv_xtheadmemidx) \
+  && defined(__riscv_xtheadmempair)\
+  && defined(__riscv_xtheadsync))
+#error "unexpected arch"
+#endif
+
+int main()
+{
+  return 0;
+}
-- 
2.39.2



[PATCH v4 1/9] riscv: Add basic XThead* vendor extension support

2023-03-02 Thread Christoph Muellner
From: Christoph Müllner 

This patch add basic support for the following XThead* ISA extensions:

* XTheadBa
* XTheadBb
* XTheadBs
* XTheadCmo
* XTheadCondMov
* XTheadFMemIdx
* XTheadFmv
* XTheadInt
* XTheadMac
* XTheadMemIdx
* XTheadMemPair
* XTheadSync

The extensions are just recognized by the compiler and feature test
macros are generated (which this patch also brings tests for).

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc: Add xthead* extensions.
* config/riscv/riscv-opts.h (MASK_XTHEADBA): New.
(MASK_XTHEADBB): New.
(MASK_XTHEADBS): New.
(MASK_XTHEADCMO): New.
(MASK_XTHEADCONDMOV): New.
(MASK_XTHEADFMEMIDX): New.
(MASK_XTHEADFMV): New.
(MASK_XTHEADINT): New.
(MASK_XTHEADMAC): New.
(MASK_XTHEADMEMIDX): New.
(MASK_XTHEADMEMPAIR): New.
(MASK_XTHEADSYNC): New.
(TARGET_XTHEADBA): New.
(TARGET_XTHEADBB): New.
(TARGET_XTHEADBS): New.
(TARGET_XTHEADCMO): New.
(TARGET_XTHEADCONDMOV): New.
(TARGET_XTHEADFMEMIDX): New.
(TARGET_XTHEADFMV): New.
(TARGET_XTHEADINT): New.
(TARGET_XTHEADMAC): New.
(TARGET_XTHEADMEMIDX): New.
(TARGET_XTHEADMEMPAIR): new.
(TARGET_XTHEADSYNC): New.
* config/riscv/riscv.opt: Add riscv_xthead_subext.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadba.c: New test.
* gcc.target/riscv/xtheadbb.c: New test.
* gcc.target/riscv/xtheadbs.c: New test.
* gcc.target/riscv/xtheadcmo.c: New test.
* gcc.target/riscv/xtheadcondmov.c: New test.
* gcc.target/riscv/xtheadfmemidx.c: New test.
* gcc.target/riscv/xtheadfmv.c: New test.
* gcc.target/riscv/xtheadint.c: New test.
* gcc.target/riscv/xtheadmac.c: New test.
* gcc.target/riscv/xtheadmemidx.c: New test.
* gcc.target/riscv/xtheadmempair.c: New test.
* gcc.target/riscv/xtheadsync.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/common/config/riscv/riscv-common.cc   | 26 +++
 gcc/config/riscv/riscv-opts.h | 26 +++
 gcc/config/riscv/riscv.opt|  3 +++
 gcc/testsuite/gcc.target/riscv/xtheadba.c | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadbb.c | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadbs.c | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadcmo.c| 14 ++
 .../gcc.target/riscv/xtheadcondmov.c  | 14 ++
 .../gcc.target/riscv/xtheadfmemidx.c  | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadfmv.c| 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadint.c| 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadmac.c| 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c | 14 ++
 .../gcc.target/riscv/xtheadmempair.c  | 13 ++
 gcc/testsuite/gcc.target/riscv/xtheadsync.c   | 14 ++
 15 files changed, 222 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcmo.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadsync.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index ebc1ed7d7e4..ef221be1eb1 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -222,6 +222,19 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"svinval", ISA_SPEC_CLASS_NONE, 1, 0},
   {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0},
 
+  {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadbs", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadcmo", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadcondmov", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadfmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadfmv", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadint", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmac", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmempair", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadsync", ISA_SPEC_CLASS_NONE, 1, 0},
+
   /* Terminate the list.  */
   {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
 };
@@ -1248,6 +1261,19 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"svinval", _options::x_riscv_sv_subext, MASK_SVINVAL},
   {"svnapot", 

[PATCH v4 0/9] RISC-V: Add XThead* extension support

2023-03-02 Thread Christoph Muellner
From: Christoph Müllner 

This series introduces support for the T-Head specific RISC-V ISA extensions
which are available e.g. on the T-Head XuanTie C906.

The ISA spec can be found here:
  https://github.com/T-head-Semi/thead-extension-spec

This series adds support for the following XThead* extensions:
* XTheadBa
* XTheadBb
* XTheadBs
* XTheadCmo
* XTheadCondMov
* XTheadFmv
* XTheadInt
* XTheadMac
* XTheadMemPair
* XTheadSync

All extensions are properly integrated and the included tests
demonstrate the improvements of the generated code.

The series also introduces support for "-mcpu=thead-c906", which also
enables all available XThead* ISA extensions of the T-Head C906.

All patches have been tested and don't introduce regressions for RV32 or RV64.
The patches have also been tested with SPEC CPU2017 on QEMU and real HW
(D1 board).

Support patches for these extensions for Binutils, QEMU, and LLVM have
already been merged in the corresponding upstream projects.

Patches 1-8 from this series (everything except the last one) got an ACK
by Kito. However, since there were a few comments after the ACK, I
decided to send out a v4, so that reviewers can verify that their
comments have been addressed properly.

Note, that there was a concern raised by Andrew Pinski (on CC), which
might not be resolved with this series (I could not reproduce the issue,
but I might have misunderstood something).

Changes in v4:
- Drop XTheadMemIdx and XTheadFMemIdx (will be a follow-up series)
- Replace 'immediate_operand' by 'const_int_operand' in many patterns
- Small cleanups in XTheadBb
- Factor out C code into thead.cc (XTheadMemPair) to minimize changes in
  riscv.cc

Changes in v3:
- Bugfix in XTheadBa
- Rewrite of XTheadMemPair
- Inclusion of XTheadMemIdx and XTheadFMemIdx

Christoph Müllner (9):
  riscv: Add basic XThead* vendor extension support
  riscv: riscv-cores.def: Add T-Head XuanTie C906
  riscv: thead: Add support for the XTheadBa ISA extension
  riscv: thead: Add support for the XTheadBs ISA extension
  riscv: thead: Add support for the XTheadBb ISA extension
  riscv: thead: Add support for the XTheadCondMov ISA extensions
  riscv: thead: Add support for the XTheadMac ISA extension
  riscv: thead: Add support for the XTheadFmv ISA extension
  riscv: thead: Add support for the XTheadMemPair ISA extension

 gcc/common/config/riscv/riscv-common.cc   |  26 ++
 gcc/config.gcc|   1 +
 gcc/config/riscv/bitmanip.md  |  52 ++-
 gcc/config/riscv/constraints.md   |   8 +
 gcc/config/riscv/iterators.md |   4 +
 gcc/config/riscv/peephole.md  |  56 +++
 gcc/config/riscv/riscv-cores.def  |   4 +
 gcc/config/riscv/riscv-opts.h |  26 ++
 gcc/config/riscv/riscv-protos.h   |  16 +-
 gcc/config/riscv/riscv.cc | 226 +++--
 gcc/config/riscv/riscv.md |  67 ++-
 gcc/config/riscv/riscv.opt|   3 +
 gcc/config/riscv/t-riscv  |   4 +
 gcc/config/riscv/thead.cc | 427 ++
 gcc/config/riscv/thead.md | 346 ++
 .../gcc.target/riscv/mcpu-thead-c906.c|  28 ++
 .../gcc.target/riscv/xtheadba-addsl.c |  55 +++
 gcc/testsuite/gcc.target/riscv/xtheadba.c |  14 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c |  20 +
 .../gcc.target/riscv/xtheadbb-extu-2.c|  22 +
 .../gcc.target/riscv/xtheadbb-extu.c  |  22 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c |  18 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c |  45 ++
 .../gcc.target/riscv/xtheadbb-srri.c  |  25 +
 gcc/testsuite/gcc.target/riscv/xtheadbb.c |  14 +
 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadbs.c |  14 +
 gcc/testsuite/gcc.target/riscv/xtheadcmo.c|  14 +
 .../riscv/xtheadcondmov-mveqz-imm-eqz.c   |  38 ++
 .../riscv/xtheadcondmov-mveqz-imm-not.c   |  38 ++
 .../riscv/xtheadcondmov-mveqz-reg-eqz.c   |  38 ++
 .../riscv/xtheadcondmov-mveqz-reg-not.c   |  38 ++
 .../riscv/xtheadcondmov-mvnez-imm-cond.c  |  38 ++
 .../riscv/xtheadcondmov-mvnez-imm-nez.c   |  38 ++
 .../riscv/xtheadcondmov-mvnez-reg-cond.c  |  38 ++
 .../riscv/xtheadcondmov-mvnez-reg-nez.c   |  38 ++
 .../gcc.target/riscv/xtheadcondmov.c  |  14 +
 .../gcc.target/riscv/xtheadfmemidx.c  |  14 +
 .../gcc.target/riscv/xtheadfmv-fmv.c  |  24 +
 gcc/testsuite/gcc.target/riscv/xtheadfmv.c|  14 +
 gcc/testsuite/gcc.target/riscv/xtheadint.c|  14 +
 .../gcc.target/riscv/xtheadmac-mula-muls.c|  43 ++
 gcc/testsuite/gcc.target/riscv/xtheadmac.c|  14 +
 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c |  14 +
 .../gcc.target/riscv/xtheadmempair-1.c|  98 
 .../gcc.target/riscv/xtheadmempair-2.c|  84 
 .../gcc.target/riscv/xtheadmempair-3.c|  29 ++
 

[wwwdocs] gcc-13: riscv: Document the T-Head CPU support

2023-02-24 Thread Christoph Muellner
From: Christoph Müllner 

This patch documents the new T-Head CPU support for RISC-V.

Signed-off-by: Christoph Müllner 
---
 htdocs/gcc-13/changes.html | 24 +++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html
index a803f501..ce5ba35c 100644
--- a/htdocs/gcc-13/changes.html
+++ b/htdocs/gcc-13/changes.html
@@ -490,7 +490,29 @@ a work-in-progress.
 
 RISC-V
 
-New ISA extension support for zawrs.
+  New ISA extension support for Zawrs.
+  Support for the following vendor extensions has been added:
+
+  XTheadBa
+  XTheadBb
+  XTheadBs
+  XTheadCmo
+  XTheadCondMov
+  XTheadFMemIdx
+  XTheadFmv
+  XTheadInt
+  XTheadMac
+  XTheadMemIdx
+  XTheadMemPair
+  XTheadSync
+
+  
+  The following new CPUs are supported through the -mcpu
+  option (GCC identifiers in parentheses).
+
+  T-Head's XuanTie C906 (thead-c906).
+
+  
 
 
 
-- 
2.39.2



[PATCH v3 10/11] riscv: thead: Add support for the XTheadMemIdx ISA extension

2023-02-23 Thread Christoph Muellner
From: "moiz.hussain" 

The XTheadMemIdx ISA extension provides a additional addressing
modes to load and store instructions:
* increment after
* increment before
* register indexed

gcc/ChangeLog:

* config/riscv/constraints.md (Qmb): New constraint.
(Qma): Likewise.
(Qmr): Likewise.
(Qmu): Likewise.
* config/riscv/riscv-opts.h (HAVE_POST_MODIFY_DISP): New macro.
(HAVE_PRE_MODIFY_DISP): Likewise.
* config/riscv/riscv-protos.h (riscv_classify_address_index):
New prototype.
(riscv_classify_address_modify): Likewise.
(riscv_output_move_index): Likewise.
(riscv_output_move_modify): Likewise.
(riscv_legitimize_address_index_p): Likewise.
(riscv_legitimize_address_modify_p): Likewise.
* config/riscv/riscv.cc (enum riscv_address_type): Add
new addressing modes.
(struct riscv_address_info): New field 'shift'.
(riscv_classify_address): Add support for XTheadMemIdx.
(riscv_classify_address_index): New function.
(riscv_classify_address_modify): New function.
(AM_IMM): New helper macro.
(AM_OFFSET): New helper macro.
(riscv_legitimize_address_modify_p): New function.
(riscv_output_move_modify): New function.
(riscv_legitimize_address_index_p): New function.
(riscv_output_move_index): New function.
(riscv_legitimize_address): Add support for XTheadMemIdx.
(riscv_rtx_costs): Adjust for XTheadMemIdx.
(riscv_output_move): Generalize to support XTheadMemIdx.
(riscv_print_operand_address): Add support for XTheadMemIdx.
* config/riscv/riscv.h (INDEX_REG_CLASS): Adjust for
XTheadMemIdx.
(REGNO_OK_FOR_INDEX_P): Adjust for XTheadMemIdx.
* config/riscv/riscv.md (*zero_extendhi2): Adjust
pattern for XTheadMemIdx.
(*zero_extendhi2_internal): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadmemidx-ldi-sdi.c: New test.
* gcc.target/riscv/xtheadmemidx-ldr-str-32.c: New test.
* gcc.target/riscv/xtheadmemidx-ldr-str-64.c: New test.
* gcc.target/riscv/xtheadmemidx-macros.h: New test.

Signed-off-by: M. Moiz Hussain 
Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/constraints.md   |  28 ++
 gcc/config/riscv/riscv-opts.h |   3 +
 gcc/config/riscv/riscv-protos.h   |  18 +
 gcc/config/riscv/riscv.cc | 438 --
 gcc/config/riscv/riscv.h  |   8 +-
 gcc/config/riscv/riscv.md |  78 +++-
 .../gcc.target/riscv/xtheadmemidx-ldi-sdi.c   |  72 +++
 .../riscv/xtheadmemidx-ldr-str-32.c   |  23 +
 .../riscv/xtheadmemidx-ldr-str-64.c   |  53 +++
 .../gcc.target/riscv/xtheadmemidx-macros.h| 110 +
 10 files changed, 772 insertions(+), 59 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldi-sdi.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldr-str-32.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldr-str-64.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-macros.h

diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index e49019d8fa9..a007cf0b4f5 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -174,3 +174,31 @@ (define_register_constraint "th_f_fmv" "TARGET_XTHEADFMV ? 
FP_REGS : NO_REGS"
 
 (define_register_constraint "th_r_fmv" "TARGET_XTHEADFMV ? GR_REGS : NO_REGS"
   "An integer register for XTheadFmv.")
+
+(define_memory_constraint "Qmb"
+  "@internal
+   An address valid for LDIB/LDIA and STIB/STIA instructions."
+  (and (match_code "mem")
+   (match_test "riscv_legitimize_address_modify_p (
+   XEXP (op, 0), GET_MODE (op), false)")))
+
+(define_memory_constraint "Qma"
+  "@internal
+   An address valid for LDIA and STIA instructions."
+  (and (match_code "mem")
+   (match_test "riscv_legitimize_address_modify_p (
+   XEXP (op, 0), GET_MODE (op), true)")))
+
+(define_memory_constraint "Qmr"
+  "@internal
+   An address valid for LDR and STR instructions."
+  (and (match_code "mem")
+   (match_test "riscv_legitimize_address_index_p (
+   XEXP (op, 0), GET_MODE (op), false)")))
+
+(define_memory_constraint "Qmu"
+  "@internal
+   An address valid for LDUR and STUR instructions."
+  (and (match_code "mem")
+   (match_test "riscv_legitimize_address_index_p (
+   XEXP (op, 0), GET_MODE (op), true)")))
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index cf0cd669be4..5cd3f7673f0 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -215,4 +215,7 @@ enum stack_protector_guard {
 #define TARGET_XTHEADMEMPAIR ((riscv_xthead_subext & MASK_XTHEADMEMPAIR) != 0)
 #define TARGET_XTHEADSYNC((riscv_xthead_subext & 

[PATCH v3 09/11] riscv: thead: Add support for the XTheadMemPair ISA extension

2023-02-23 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadMemPair ISA extension allows to pair two loads or stores:
* th.ldd (2x LD)
* th.lwd (2x LW)
* th.lwud (2x LWU)
* th.sdd (2x SD)
* th.swd (2x SW)

The displacement of these instructions is quite limited:
* Displacement := imm2 << shamt
* imm2 is a 2-bit unsigned value {0..3}
* shamt is 4 for th.ldd/th.sdd and 3 otherwise
But even with this small displacement we can identify many candidates.

The merge of the two loads/stores is realized in form of peephole2
passes that support instruction reordering.
The CFA expansion (save/restore registers on/from stack) is not
processed by the peephole2 pass and, therefore, needs special-treatment.
Many ideas of this patch are inspired by similar/equal approaches
in other backends.

gcc/ChangeLog:

* config/riscv/peephole.md: New peephole passes for
XTheadMemPair.
* config/riscv/riscv-protos.h (thead_mempair_operands_p):
New prototype.
(thead_mempair_order_operands): Likewise.
(thead_mempair_output_move): Likewise.
* config/riscv/riscv.cc (extract_base_offset_in_addr):
New function.
(riscv_split_plus): New function.
(thead_mempair_output_move): New function.
(thead_mempair_check_consecutive_mems): New function.
(thead_mempair_operand_p): New function.
(thead_mempair_load_overlap_p): New function.
(thead_mempair_operands_p): New function.
(thead_mempair_order_operands): New function.
(riscv_save_reg): Moved code.
(th_mempair_save_reg): New function.
(riscv_restore_reg): Moved code.
(th_mempair_restore_reg): New function.
(riscv_for_each_saved_reg): Add code to handle mempair
instructions.
* config/riscv/thead.md (*th_mempair_load_2):
New pattern.
(*th_mempair_store_2): Likewise.
(*th_mempair_load_extendsidi2): Likewise.
(*th_mempair_load_zero_extendsidi2): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadmempair-1.c: New test.
* gcc.target/riscv/xtheadmempair-2.c: New test.
* gcc.target/riscv/xtheadmempair-3.c: New test.

Changes in v3:
- Don't emit instructions during peephole2, but emit parallel INSNs
- Add proper checks for the INSN patterns to avoid ICEs or illegal
  instructions reported by the assembler
- Don't insert any `add` instructions
- Rework the constraint handling
- Simplify the output function
- Restructure and simplify CFA processing
- Add debug notes to CFA instructions
- Emit parallel INSNs in the CFA code (same as peephole2)
- Drop tests that target reordering
- Drop tests that are irrelevant (e.g. unrolled loops)
- Add tests for all possible displacements and all instructions
- Add tests for CFA

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/peephole.md  |  56 +++
 gcc/config/riscv/riscv-protos.h   |   6 +
 gcc/config/riscv/riscv.cc | 450 --
 gcc/config/riscv/thead.md |  52 ++
 .../gcc.target/riscv/xtheadmempair-1.c|  98 
 .../gcc.target/riscv/xtheadmempair-2.c|  84 
 .../gcc.target/riscv/xtheadmempair-3.c|  29 ++
 7 files changed, 746 insertions(+), 29 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-3.c

diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md
index 0ef0c04410b..ea696f3116c 100644
--- a/gcc/config/riscv/peephole.md
+++ b/gcc/config/riscv/peephole.md
@@ -38,3 +38,59 @@ (define_peephole2
 {
   operands[5] = GEN_INT (INTVAL (operands[2]) - INTVAL (operands[5]));
 })
+
+;; XTheadMemPair: merge two SI or DI loads
+(define_peephole2
+  [(set (match_operand:GPR 0 "register_operand" "")
+   (match_operand:GPR 1 "memory_operand" ""))
+   (set (match_operand:GPR 2 "register_operand" "")
+   (match_operand:GPR 3 "memory_operand" ""))]
+  "TARGET_XTHEADMEMPAIR
+  && thead_mempair_operands_p (operands, true, mode)"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+ (set (match_dup 2) (match_dup 3))])]
+{
+  thead_mempair_order_operands (operands, true, mode);
+})
+
+;; XTheadMemPair: merge two SI or DI stores
+(define_peephole2
+  [(set (match_operand:GPR 0 "memory_operand" "")
+   (match_operand:GPR 1 "register_operand" ""))
+   (set (match_operand:GPR 2 "memory_operand" "")
+   (match_operand:GPR 3 "register_operand" ""))]
+  "TARGET_XTHEADMEMPAIR
+  && thead_mempair_operands_p (operands, false, mode)"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+  (set (match_dup 2) (match_dup 3))])]
+{
+  thead_mempair_order_operands (operands, false, mode);
+})
+
+;; XTheadMemPair: merge two SI loads with sign-extension
+(define_peephole2
+  [(set (match_operand:DI 0 "register_operand" "")
+   (sign_extend:DI 

[PATCH v3 08/11] riscv: thead: Add support for the XTheadFmv ISA extension

2023-02-23 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadFmv ISA extension provides instructions to move
data between 32-bit GP registers and 64-bit FP registers.

gcc/ChangeLog:

* config/riscv/constraints.md (TARGET_XTHEADFMV ? FP_REGS : NO_REGS)
New constraint "th_f_fmv".
(TARGET_XTHEADFMV ? GR_REGS : NO_REGS): New constraint
"th_r_fmv".
* config/riscv/riscv.cc (riscv_split_doubleword_move):
Add split code for XTheadFmv.
(riscv_secondary_memory_needed): XTheadFmv does not need
secondary memory.
* config/riscv/riscv.md: Add new UNSPEC_XTHEADFMV and
UNSPEC_XTHEADFMV_HW. Add support for XTheadFmv to
movdf_hardfloat_rv32.
* config/riscv/thead.md (th_fmv_hw_w_x): New INSN.
(th_fmv_x_w): New INSN.
(th_fmv_x_hw): New INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadfmv-fmv.c: New test.

Co-Developed-by: Xianmiao Qu 
Signed-off-by: Xianmiao Qu 
Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/constraints.md   |  8 +
 gcc/config/riscv/riscv.cc | 25 --
 gcc/config/riscv/riscv.md | 11 +--
 gcc/config/riscv/thead.md | 33 +++
 .../gcc.target/riscv/xtheadfmv-fmv.c  | 24 ++
 5 files changed, 95 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c

diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index a051d466ae2..e49019d8fa9 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -166,3 +166,11 @@ (define_memory_constraint "Wdm"
   "Vector duplicate memory operand"
   (and (match_code "mem")
(match_code "reg" "0")))
+
+;; Vendor ISA extension constraints.
+
+(define_register_constraint "th_f_fmv" "TARGET_XTHEADFMV ? FP_REGS : NO_REGS"
+  "A floating-point register for XTheadFmv.")
+
+(define_register_constraint "th_r_fmv" "TARGET_XTHEADFMV ? GR_REGS : NO_REGS"
+  "An integer register for XTheadFmv.")
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a60ab2c7fad..48f2cb399ae 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2754,11 +2754,29 @@ riscv_split_64bit_move_p (rtx dest, rtx src)
 void
 riscv_split_doubleword_move (rtx dest, rtx src)
 {
-  rtx low_dest;
+  /* XTheadFmv has instructions for accessing the upper bits of a double.  */
+  if (!TARGET_64BIT && TARGET_XTHEADFMV)
+{
+  if (FP_REG_RTX_P (dest))
+   {
+ rtx low_src = riscv_subword (src, false);
+ rtx high_src = riscv_subword (src, true);
+ emit_insn (gen_th_fmv_hw_w_x (dest, high_src, low_src));
+ return;
+   }
+  if (FP_REG_RTX_P (src))
+   {
+ rtx low_dest = riscv_subword (dest, false);
+ rtx high_dest = riscv_subword (dest, true);
+ emit_insn (gen_th_fmv_x_w (low_dest, src));
+ emit_insn (gen_th_fmv_x_hw (high_dest, src));
+ return;
+   }
+}
 
/* The operation can be split into two normal moves.  Decide in
   which order to do them.  */
-   low_dest = riscv_subword (dest, false);
+   rtx low_dest = riscv_subword (dest, false);
if (REG_P (low_dest) && reg_overlap_mentioned_p (low_dest, src))
  {
riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
@@ -5802,7 +5820,8 @@ riscv_secondary_memory_needed (machine_mode mode, 
reg_class_t class1,
 {
   return (!riscv_v_ext_vector_mode_p (mode)
  && GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD
- && (class1 == FP_REGS) != (class2 == FP_REGS));
+ && (class1 == FP_REGS) != (class2 == FP_REGS)
+ && !TARGET_XTHEADFMV);
 }
 
 /* Implement TARGET_REGISTER_MOVE_COST.  */
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 112c93f733e..61f175bb62b 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -100,6 +100,10 @@ (define_c_enum "unspecv" [
 
   ;; Zihintpause unspec
   UNSPECV_PAUSE
+
+  ;; XTheadFmv unspec
+  UNSPEC_XTHEADFMV
+  UNSPEC_XTHEADFMV_HW
 ])
 
 (define_constants
@@ -1856,16 +1860,17 @@ (define_expand "movdf"
 DONE;
 })
 
+
 ;; In RV32, we lack fmv.x.d and fmv.d.x.  Go through memory instead.
 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
 (define_insn "*movdf_hardfloat_rv32"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,  *r,*r,*m")
-   (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r*G,*m,*r"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" 
"=f,f,f,m,m,*th_f_fmv,*th_r_fmv,  *r,*r,*m")
+   (match_operand:DF 1 "move_operand" " 
f,G,m,f,G,*th_r_fmv,*th_f_fmv,*r*G,*m,*r"))]
   "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
&& (register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))"
   { return riscv_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" 

[PATCH v3 11/11] riscv: thead: Add support for the XTheadFMemIdx ISA extension

2023-02-23 Thread Christoph Muellner
From: "moiz.hussain" 

The XTheadFMemIdx ISA extension provides register-indexed
addressing modes to floating-point load and store instructions.

gcc/ChangeLog:

* config/riscv/constraints.md (Qmx): New constraint.
* config/riscv/riscv-protos.h (riscv_output_move_index_float):
New prototyp.
* config/riscv/riscv.cc (riscv_classify_address_index): Adjust
for XTheadFMemIdx.
(riscv_classify_address_modify): Likewise.
(riscv_output_move_index_float): New function.
(riscv_rtx_costs): Adjust for XTheadFMemIdx.
(riscv_split_64bit_move_p): Likewise.
(riscv_output_move): Likewise.
* config/riscv/riscv.h (INDEX_REG_CLASS): Likewise.
(REGNO_OK_FOR_INDEX_P): Likewise.
* config/riscv/riscv.md (*movsf_hardfloat): New pattern.
(*movdf_hardfloat_rv32): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadfmemidx-fldr-fstr.c: New test.

Signed-off-by: M. Moiz Hussain 
Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/constraints.md   |  7 ++
 gcc/config/riscv/riscv-protos.h   |  2 +
 gcc/config/riscv/riscv.cc | 70 ++-
 gcc/config/riscv/riscv.h  |  4 +-
 gcc/config/riscv/riscv.md | 28 
 .../riscv/xtheadfmemidx-fldr-fstr.c   | 58 +++
 6 files changed, 164 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-fldr-fstr.c

diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index a007cf0b4f5..711268d05f6 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -202,3 +202,10 @@ (define_memory_constraint "Qmu"
   (and (match_code "mem")
(match_test "riscv_legitimize_address_index_p (
XEXP (op, 0), GET_MODE (op), true)")))
+
+(define_memory_constraint "Qmx"
+  "@internal
+   An address valid for GPR."
+  (and (match_code "mem")
+   (match_test "!riscv_legitimize_address_index_p (
+   XEXP (op, 0), GET_MODE (op), false)")))
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 019a0e08285..ba53bf710d7 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -77,6 +77,8 @@ extern const char *
 riscv_output_move_index (rtx x, machine_mode mode, bool ldr);
 extern const char *
 riscv_output_move_modify (rtx x, machine_mode mode, bool ldi);
+extern const char *
+riscv_output_move_index_float (rtx x, machine_mode mode, bool ldr);
 
 extern bool
 riscv_legitimize_address_index_p (rtx x, machine_mode mode, bool uindex);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 2980dbd69f9..caa30eed8d6 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1316,7 +1316,7 @@ riscv_classify_address_index (struct riscv_address_info 
*info, rtx x,
   rtx index;
   int shift = 0;
 
-  if (!TARGET_XTHEADMEMIDX)
+  if (!(TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX))
 return false;
 
   if (!TARGET_64BIT && mode == DImode)
@@ -1326,6 +1326,8 @@ riscv_classify_address_index (struct riscv_address_info 
*info, rtx x,
 {
   if (!TARGET_HARD_FLOAT)
return false;
+  if (!(TARGET_HARD_FLOAT && TARGET_XTHEADFMEMIDX))
+   return false;
   if (GET_MODE_SIZE (mode).to_constant () == 2)
return false;
 }
@@ -1422,7 +1424,7 @@ riscv_classify_address_modify (struct riscv_address_info 
*info, rtx x,
   ? (SHIFT) + 1 \
   : 0)
 
-  if (!TARGET_XTHEADMEMIDX)
+  if (!(TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX))
 return false;
 
   if (!(INTEGRAL_MODE_P (mode) && GET_MODE_SIZE (mode).to_constant () <= 8))
@@ -1562,6 +1564,42 @@ riscv_output_move_index (rtx x, machine_mode mode, bool 
ldr)
   return buf;
 }
 
+const char *
+riscv_output_move_index_float (rtx x, machine_mode mode, bool ldr)
+{
+  static char buf[128] = {0};
+
+  int index = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
+  if (!IN_RANGE (index, 2, 3))
+return NULL;
+
+  if (!riscv_legitimize_address_index_p (x, mode, false))
+return NULL;
+
+  bool uindex = riscv_legitimize_address_index_p (x, mode, true);
+
+  /* Not using index, 0, 1, as they are not implemented
+ for xtheadfmemidx yet.  */
+  const char *const insn[][4] = {
+{
+  "th.fs%srb\t%%z1,%%0",
+  "th.fs%srh\t%%z1,%%0",
+  "th.fs%srw\t%%z1,%%0",
+  "th.fs%srd\t%%z1,%%0"
+},
+{
+  "th.fl%srb\t%%0,%%1",
+  "th.fl%srh\t%%0,%%1",
+  "th.fl%srw\t%%0,%%1",
+  "th.fl%srd\t%%0,%%1"
+}
+  };
+
+  snprintf (buf, sizeof (buf), insn[ldr][index], uindex ? "u" : "");
+
+  return buf;
+}
+
 /* Emit an instruction of the form (set TARGET SRC).  */
 
 static rtx
@@ -2739,7 +2777,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int 
outer_code, int opno ATTRIBUTE_UN
}
   /* bit extraction pattern (xtheadmemidx, xtheadfmemidx).  */
   if 

[PATCH v3 03/11] riscv: thead: Add support for the XTheadBa ISA extension

2023-02-23 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the XTheadBa ISA extension.
The new INSN pattern is defined in a new file to separate
this vendor extension from the standard extensions.

gcc/ChangeLog:

* config/riscv/riscv.md: Include thead.md
* config/riscv/thead.md: New file.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadba-addsl.c: New test.

Changes in v3:
- Fix operand order for th.addsl.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.md |  1 +
 gcc/config/riscv/thead.md | 31 +++
 .../gcc.target/riscv/xtheadba-addsl.c | 55 +++
 3 files changed, 87 insertions(+)
 create mode 100644 gcc/config/riscv/thead.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 05924e9bbf1..d6c2265e9d4 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3093,4 +3093,5 @@ (define_insn "riscv_prefetchi_"
 (include "pic.md")
 (include "generic.md")
 (include "sifive-7.md")
+(include "thead.md")
 (include "vector.md")
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
new file mode 100644
index 000..158e9124c3a
--- /dev/null
+++ b/gcc/config/riscv/thead.md
@@ -0,0 +1,31 @@
+;; Machine description for T-Head vendor extensions
+;; Copyright (C) 2021-2022 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
+;; .
+
+;; XTheadBa
+
+(define_insn "*th_addsl"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (plus:X (ashift:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "I"))
+   (match_operand:X 3 "register_operand" "r")))]
+  "TARGET_XTHEADBA
+   && (INTVAL (operands[2]) >= 0) && (INTVAL (operands[2]) <= 3)"
+  "th.addsl\t%0,%3,%1,%2"
+  [(set_attr "type" "bitmanip")
+   (set_attr "mode" "")])
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c 
b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
new file mode 100644
index 000..5004735a246
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadba" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadba" { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+long
+test_1 (long a, long b)
+{
+  /* th.addsl aX, aX, 1  */
+  return a + (b << 1);
+}
+
+int
+foos (short *x, int n)
+{
+  /* th.addsl aX, aX, 1  */
+  return x[n];
+}
+
+long
+test_2 (long a, long b)
+{
+  /* th.addsl aX, aX, 2  */
+  return a + (b << 2);
+}
+
+int
+fooi (int *x, int n)
+{
+  /* th.addsl aX, aX, 2  */
+  return x[n];
+}
+
+long
+test_3 (long a, long b)
+{
+  /* th.addsl aX, aX, 3  */
+  return a + (b << 3);
+}
+
+long
+fool (long *x, int n)
+{
+  /* th.addsl aX, aX, 2 (rv32)  */
+  /* th.addsl aX, aX, 3 (rv64)  */
+  return x[n];
+}
+
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,1" 2 } } */
+
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,2" 3 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,2" 2 { target { rv64 } } } } */
+
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,3" 1 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,3" 2 { target { rv64 } } } } */
-- 
2.39.2



[PATCH v3 06/11] riscv: thead: Add support for the XTheadCondMov ISA extensions

2023-02-23 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for XTheadCondMov ISA extension.
The extension brings a one-sided conditional move (no else-assignment).
Given that GCC has a great if-conversion pass, we don't need to do much,
besides properly expanding movcc accordingly and adjust the cost
model.

gcc/ChangeLog:

* config/riscv/iterators.md (TARGET_64BIT): Add GPR2 iterator.
* config/riscv/riscv-protos.h (riscv_expand_conditional_move):
Add prototype.
* config/riscv/riscv.cc (riscv_rtx_costs): Add costs for
XTheadCondMov.
(riscv_expand_conditional_move): New function.
(riscv_expand_conditional_move_onesided): New function.
* config/riscv/riscv.md: Add support for XTheadCondMov.
* config/riscv/thead.md (*th_cond_mov): Add
support for XTheadCondMov.
(*th_cond_gpr_mov): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c: New test.

Changes for v2:
- Properly gate expansion constraints to avoid failing INSN lookup
- Restrict subreg comparisons

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/iterators.md |   4 +
 gcc/config/riscv/riscv-protos.h   |   2 +-
 gcc/config/riscv/riscv.cc | 100 +++---
 gcc/config/riscv/riscv.md |  17 ++-
 gcc/config/riscv/thead.md |  37 +++
 .../riscv/xtheadcondmov-mveqz-imm-eqz.c   |  38 +++
 .../riscv/xtheadcondmov-mveqz-imm-not.c   |  38 +++
 .../riscv/xtheadcondmov-mveqz-reg-eqz.c   |  38 +++
 .../riscv/xtheadcondmov-mveqz-reg-not.c   |  38 +++
 .../riscv/xtheadcondmov-mvnez-imm-cond.c  |  38 +++
 .../riscv/xtheadcondmov-mvnez-imm-nez.c   |  38 +++
 .../riscv/xtheadcondmov-mvnez-reg-cond.c  |  38 +++
 .../riscv/xtheadcondmov-mvnez-reg-nez.c   |  38 +++
 13 files changed, 440 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c

diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 5b70ab20758..9b767038452 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -26,6 +26,10 @@
 ;; from the same template.
 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
 
+;; A copy of GPR that can be used when a pattern has two independent
+;; modes.
+(define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
+
 ;; This mode iterator allows :P to be used for patterns that operate on
 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 37c634eca1d..5cf4fafd662 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -58,8 +58,8 @@ extern const char *riscv_output_return ();
 extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx);
 extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx);
 extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx);
-extern void riscv_expand_conditional_move (rtx, rtx, rtx, rtx_code, rtx, rtx);
 #endif
+extern bool riscv_expand_conditional_move (rtx, rtx, rtx, rtx);
 extern rtx riscv_legitimize_call_address (rtx);
 extern void riscv_set_return_address (rtx, rtx);
 extern bool riscv_expand_block_move (rtx, rtx, rtx);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 7613bae8024..a60ab2c7fad 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2300,8 +2300,8 @@ 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
- && register_operand (XEXP (x, 1), mode)
+  if ((TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
+ && reg_or_0_operand 

[PATCH v3 05/11] riscv: thead: Add support for the XTheadBb ISA extension

2023-02-23 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the XTheadBb ISA extension.
Thus, there is a functional overlap of the new instructions with
existing Bitmanip instruction, which allows a good amount of code
sharing. However, the vendor extensions are cleanly separated from
the standard extensions (e.g. by using INSN expand pattern that
will re-emit RTL that matches the patterns of either Bitmanip or
XThead INSNs).

gcc/ChangeLog:

* config/riscv/bitmanip.md (clzdi2): New expand.
(clzsi2): New expand.
(ctz2): New expand.
(popcount2): New expand.
(si2): Rename INSN.
(*si2): Hide INSN name.
(di2): Rename INSN.
(*di2): Hide INSN name.
(rotrsi3): Remove INSN.
(rotr3): Add expand.
(*rotrsi3): New INSN.
(rotrdi3): Rename INSN.
(*rotrdi3): Hide INSN name.
(rotrsi3_sext): Rename INSN.
(*rotrsi3_sext): Hide INSN name.
(bswap2): Remove INSN.
(bswapdi2): Add expand.
(bswapsi2): Add expand.
(*bswap2): Hide INSN name.
* config/riscv/riscv.cc (riscv_rtx_costs): Add costs for sign
extraction.
* config/riscv/riscv.md (extv): New expand.
(extzv): New expand.
* config/riscv/thead.md (*th_srrisi3): New INSN.
(*th_srridi3): New INSN.
(*th_ext): New INSN.
(*th_extu): New INSN.
(*th_clz2): New INSN.
(*th_revsi2): New INSN.
(*th_revdi2): New INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-ext.c: New test.
* gcc.target/riscv/xtheadbb-extu-2.c: New test.
* gcc.target/riscv/xtheadbb-extu.c: New test.
* gcc.target/riscv/xtheadbb-ff1.c: New test.
* gcc.target/riscv/xtheadbb-rev.c: New test.
* gcc.target/riscv/xtheadbb-srri.c: New test.

Changes for v2:
- Merge all XTheadB* support patches
- Remove useless operand sanity checks for extv and extzv
- Prefer c.andi over th.extu if possible
- Add ff1 tests for clz/ctz
- Fix ext/extu test cases
- Enable tests for RV32

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/bitmanip.md  | 52 +--
 gcc/config/riscv/riscv.cc |  9 +++
 gcc/config/riscv/riscv.md | 20 ++
 gcc/config/riscv/thead.md | 66 +++
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c | 20 ++
 .../gcc.target/riscv/xtheadbb-extu-2.c| 22 +++
 .../gcc.target/riscv/xtheadbb-extu.c  | 22 +++
 gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c | 18 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c | 45 +
 .../gcc.target/riscv/xtheadbb-srri.c  | 21 ++
 10 files changed, 289 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 14d18edbe62..ca0c98ee686 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -185,6 +185,26 @@ (define_insn "*slliuw"
 
 ;; ZBB extension.
 
+(define_expand "clzdi2"
+  [(set (match_operand:DI 0 "register_operand")
+   (clz:DI (match_operand:DI 1 "register_operand")))]
+  "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB)")
+
+(define_expand "clzsi2"
+  [(set (match_operand:SI 0 "register_operand")
+   (clz:SI (match_operand:SI 1 "register_operand")))]
+  "TARGET_ZBB || (!TARGET_64BIT && TARGET_XTHEADBB)")
+
+(define_expand "ctz2"
+  [(set (match_operand:GPR 0 "register_operand")
+   (ctz:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB")
+
+(define_expand "popcount2"
+  [(set (match_operand:GPR 0 "register_operand")
+   (popcount:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB")
+
 (define_insn "*_not"
   [(set (match_operand:X 0 "register_operand" "=r")
 (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
@@ -216,7 +236,7 @@ (define_insn "*xor_not"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
 
-(define_insn "si2"
+(define_insn "*si2"
   [(set (match_operand:SI 0 "register_operand" "=r")
 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))]
   "TARGET_ZBB"
@@ -233,7 +253,7 @@ (define_insn "*disi2"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "SI")])
 
-(define_insn "di2"
+(define_insn "*di2"
   [(set (match_operand:DI 0 "register_operand" "=r")
 (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
   "TARGET_64BIT && TARGET_ZBB"
@@ -273,7 +293,17 @@ (define_insn "*zero_extendhi2_zbb"
   [(set_attr "type" "bitmanip,load")
(set_attr "mode" "HI")])

[PATCH v3 07/11] riscv: thead: Add support for the XTheadMac ISA extension

2023-02-23 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadMac ISA extension provides multiply-accumulate/subtract
instructions:
* mula/mulaw/mulah
* muls/mulsw/mulsh

To benefit from middle-end passes, we expand the following named
patterns in riscv.md (as they are not T-Head-specific):
* maddhisi4
* msubhisi4

gcc/ChangeLog:

* config/riscv/riscv.md (maddhisi4): New expand.
(msubhisi4): New expand.
* config/riscv/thead.md (*th_mula): New pattern.
(*th_mulawsi): New pattern.
(*th_mulawsi2): New pattern.
(*th_maddhisi4): New pattern.
(*th_sextw_maddhisi4): New pattern.
(*th_muls): New pattern.
(*th_mulswsi): New pattern.
(*th_mulswsi2): New pattern.
(*th_msubhisi4): New pattern.
(*th_sextw_msubhisi4): New pattern.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/thead-mula-muls.c: New test.

Co-Developed-by: Xianmiao Qu 
Signed-off-by: Xianmiao Qu 
Signed-off-by: Christoph Müllner 

Changed in v2:
- Add missing prefix in on INSN
---
 gcc/config/riscv/riscv.md |  18 +++
 gcc/config/riscv/thead.md | 121 ++
 .../gcc.target/riscv/xtheadmac-mula-muls.c|  43 +++
 3 files changed, 182 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac-mula-muls.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 5562e5621fa..112c93f733e 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3106,6 +3106,24 @@ (define_expand "extzv"
 FAIL;
 })
 
+(define_expand "maddhisi4"
+  [(set (match_operand:SI 0 "register_operand")
+   (plus:SI
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"))
+  (sign_extend:SI (match_operand:HI 2 "register_operand")))
+ (match_operand:SI 3 "register_operand")))]
+  "TARGET_XTHEADMAC"
+)
+
+(define_expand "msubhisi4"
+  [(set (match_operand:SI 0 "register_operand")
+   (minus:SI
+ (match_operand:SI 3 "register_operand")
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"))
+  (sign_extend:SI (match_operand:HI 2 "register_operand")]
+  "TARGET_XTHEADMAC"
+)
+
 (include "bitmanip.md")
 (include "sync.md")
 (include "peephole.md")
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index ae5a65e9a7e..f616035e5a5 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -143,3 +143,124 @@ (define_insn "*th_cond_gpr_mov"
th.mveqz\t%0,%z3,%1"
   [(set_attr "type" "condmove")
(set_attr "mode" "")])
+
+;; XTheadMac
+
+(define_insn "*th_mula"
+  [(set (match_operand:X 0 "register_operand" "=r")
+ (plus:X (mult:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:X 2 "register_operand" "r"))
+ (match_operand:X 3 "register_operand" "0")))]
+  "TARGET_XTHEADMAC"
+  "th.mula\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "")]
+)
+
+(define_insn "*th_mulawsi"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (sign_extend:DI
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+   (match_operand:SI 2 "register_operand" "r"))
+  (match_operand:SI 3 "register_operand" "0"]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulaw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_mulawsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+   (match_operand:SI 2 "register_operand" "r"))
+  (match_operand:SI 3 "register_operand" "0")))]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulaw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_maddhisi4"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI
+   (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" " r"))
+ (sign_extend:SI (match_operand:HI 2 "register_operand" " r")))
+   (match_operand:SI 3 "register_operand" " 0")))]
+  "TARGET_XTHEADMAC"
+  "th.mulah\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_sextw_maddhisi4"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (sign_extend:DI
+ (plus:SI
+   (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" " r"))
+ (sign_extend:SI (match_operand:HI 2 "register_operand" " r")))
+   (match_operand:SI 3 "register_operand" " 0"]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulah\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_muls"
+  [(set (match_operand:X 0 "register_operand" "=r")
+ (minus:X (match_operand:X 3 "register_operand" "0")
+  (mult:X 

[PATCH v3 00/11] RISC-V: Add XThead* extension support

2023-02-23 Thread Christoph Muellner
From: Christoph Müllner 

This series introduces support for the T-Head specific RISC-V ISA extensions
which are available e.g. on the T-Head XuanTie C906.

The ISA spec can be found here:
  https://github.com/T-head-Semi/thead-extension-spec

This series adds support for the following XThead* extensions:
* XTheadBa
* XTheadBb
* XTheadBs
* XTheadCmo
* XTheadCondMov
* XTheadFMemIdx
* XTheadFmv
* XTheadInt
* XTheadMac
* XTheadMemIdx
* XTheadMemPair
* XTheadSync

All extensions are properly integrated and the included tests
demonstrate the improvements of the generated code.

The series also introduces support for "-mcpu=thead-c906", which also
enables all available XThead* ISA extensions of the T-Head C906.

All patches have been tested and don't introduce regressions for RV32 or RV64.
The patches have also been tested with SPEC CPU2017 on QEMU and real HW
(D1 board).

Support patches for these extensions for Binutils, QEMU, and LLVM have
already been merged in the corresponding upstream projects.

Changes in v3:
- Bugfix in XTheadBa
- Rewrite of XTheadMemPair
- Inclusion of XTheadMemIdx and XTheadFMemIdx

Christoph Müllner (9):
  riscv: Add basic XThead* vendor extension support
  riscv: riscv-cores.def: Add T-Head XuanTie C906
  riscv: thead: Add support for the XTheadBa ISA extension
  riscv: thead: Add support for the XTheadBs ISA extension
  riscv: thead: Add support for the XTheadBb ISA extension
  riscv: thead: Add support for the XTheadCondMov ISA extensions
  riscv: thead: Add support for the XTheadMac ISA extension
  riscv: thead: Add support for the XTheadFmv ISA extension
  riscv: thead: Add support for the XTheadMemPair ISA extension

moiz.hussain (2):
  riscv: thead: Add support for the XTheadMemIdx ISA extension
  riscv: thead: Add support for the XTheadFMemIdx ISA extension

 gcc/common/config/riscv/riscv-common.cc   |   26 +
 gcc/config/riscv/bitmanip.md  |   52 +-
 gcc/config/riscv/constraints.md   |   43 +
 gcc/config/riscv/iterators.md |4 +
 gcc/config/riscv/peephole.md  |   56 +
 gcc/config/riscv/riscv-cores.def  |4 +
 gcc/config/riscv/riscv-opts.h |   29 +
 gcc/config/riscv/riscv-protos.h   |   28 +-
 gcc/config/riscv/riscv.cc | 1090 +++--
 gcc/config/riscv/riscv.h  |8 +-
 gcc/config/riscv/riscv.md |  169 ++-
 gcc/config/riscv/riscv.opt|3 +
 gcc/config/riscv/thead.md |  351 ++
 .../gcc.target/riscv/mcpu-thead-c906.c|   28 +
 .../gcc.target/riscv/xtheadba-addsl.c |   55 +
 gcc/testsuite/gcc.target/riscv/xtheadba.c |   14 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c |   20 +
 .../gcc.target/riscv/xtheadbb-extu-2.c|   22 +
 .../gcc.target/riscv/xtheadbb-extu.c  |   22 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c |   18 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c |   45 +
 .../gcc.target/riscv/xtheadbb-srri.c  |   21 +
 gcc/testsuite/gcc.target/riscv/xtheadbb.c |   14 +
 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c |   13 +
 gcc/testsuite/gcc.target/riscv/xtheadbs.c |   14 +
 gcc/testsuite/gcc.target/riscv/xtheadcmo.c|   14 +
 .../riscv/xtheadcondmov-mveqz-imm-eqz.c   |   38 +
 .../riscv/xtheadcondmov-mveqz-imm-not.c   |   38 +
 .../riscv/xtheadcondmov-mveqz-reg-eqz.c   |   38 +
 .../riscv/xtheadcondmov-mveqz-reg-not.c   |   38 +
 .../riscv/xtheadcondmov-mvnez-imm-cond.c  |   38 +
 .../riscv/xtheadcondmov-mvnez-imm-nez.c   |   38 +
 .../riscv/xtheadcondmov-mvnez-reg-cond.c  |   38 +
 .../riscv/xtheadcondmov-mvnez-reg-nez.c   |   38 +
 .../gcc.target/riscv/xtheadcondmov.c  |   14 +
 .../riscv/xtheadfmemidx-fldr-fstr.c   |   58 +
 .../gcc.target/riscv/xtheadfmemidx.c  |   14 +
 .../gcc.target/riscv/xtheadfmv-fmv.c  |   24 +
 gcc/testsuite/gcc.target/riscv/xtheadfmv.c|   14 +
 gcc/testsuite/gcc.target/riscv/xtheadint.c|   14 +
 .../gcc.target/riscv/xtheadmac-mula-muls.c|   43 +
 gcc/testsuite/gcc.target/riscv/xtheadmac.c|   14 +
 .../gcc.target/riscv/xtheadmemidx-ldi-sdi.c   |   72 ++
 .../riscv/xtheadmemidx-ldr-str-32.c   |   23 +
 .../riscv/xtheadmemidx-ldr-str-64.c   |   53 +
 .../gcc.target/riscv/xtheadmemidx-macros.h|  110 ++
 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c |   14 +
 .../gcc.target/riscv/xtheadmempair-1.c|   98 ++
 .../gcc.target/riscv/xtheadmempair-2.c|   84 ++
 .../gcc.target/riscv/xtheadmempair-3.c|   29 +
 .../gcc.target/riscv/xtheadmempair.c  |   13 +
 gcc/testsuite/gcc.target/riscv/xtheadsync.c   |   14 +
 52 files changed, 3048 insertions(+), 124 deletions(-)
 create mode 100644 gcc/config/riscv/thead.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
 create mode 100644 

[PATCH v3 02/11] riscv: riscv-cores.def: Add T-Head XuanTie C906

2023-02-23 Thread Christoph Muellner
From: Christoph Müllner 

This adds T-Head's XuanTie C906 to the list of known cores as "thead-c906".
The C906 is shipped for quite some time (it is the core of the Allwinner D1).
Note, that the tuning struct for the C906 is already part of GCC (it is
also name "thead-c906").

gcc/ChangeLog:

* config/riscv/riscv-cores.def (RISCV_CORE): Add "thead-c906".

gcc/testsuite/ChangeLog:

* gcc.target/riscv/mcpu-thead-c906.c: New test.

Changes for v2:
- Enable all supported vendor extensions

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv-cores.def  |  4 +++
 .../gcc.target/riscv/mcpu-thead-c906.c| 28 +++
 2 files changed, 32 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c

diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
index 2a834cae21d..7d87ab7ce28 100644
--- a/gcc/config/riscv/riscv-cores.def
+++ b/gcc/config/riscv/riscv-cores.def
@@ -73,4 +73,8 @@ RISCV_CORE("sifive-s76",  "rv64imafdc", "sifive-7-series")
 RISCV_CORE("sifive-u54",  "rv64imafdc", "sifive-5-series")
 RISCV_CORE("sifive-u74",  "rv64imafdc", "sifive-7-series")
 
+RISCV_CORE("thead-c906",  
"rv64imafdc_xtheadba_xtheadbb_xtheadbs_xtheadcmo_"
+ "xtheadcondmov_xtheadfmemidx_xtheadmac_"
+ "xtheadmemidx_xtheadmempair_xtheadsync",
+ "thead-c906")
 #undef RISCV_CORE
diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c 
b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
new file mode 100644
index 000..a71b43a6167
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */
+/* { dg-options "-mcpu=thead-c906" { target { rv64 } } } */
+/* T-Head XuanTie C906 => rv64imafdc */
+
+#if !((__riscv_xlen == 64) \
+  && !defined(__riscv_32e) \
+  && defined(__riscv_mul)  \
+  && defined(__riscv_atomic)   \
+  && (__riscv_flen == 64)  \
+  && defined(__riscv_compressed)   \
+  && defined(__riscv_xtheadba) \
+  && defined(__riscv_xtheadbb) \
+  && defined(__riscv_xtheadbs) \
+  && defined(__riscv_xtheadcmo)\
+  && defined(__riscv_xtheadcondmov)\
+  && defined(__riscv_xtheadfmemidx)\
+  && defined(__riscv_xtheadmac)\
+  && defined(__riscv_xtheadmemidx) \
+  && defined(__riscv_xtheadmempair)\
+  && defined(__riscv_xtheadsync))
+#error "unexpected arch"
+#endif
+
+int main()
+{
+  return 0;
+}
-- 
2.39.2



[PATCH v3 04/11] riscv: thead: Add support for the XTheadBs ISA extension

2023-02-23 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the XTheadBs ISA extension.
The new INSN pattern is defined in a new file to separate
this vendor extension from the standard extensions.
The cost model adjustment reuses the xbs:bext cost.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_rtx_costs): Add xthead:tst cost.
* config/riscv/thead.md (*th_tst): New INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbs-tst.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.cc |  4 ++--
 gcc/config/riscv/thead.md | 11 +++
 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c | 13 +
 3 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f11b7949a49..e35bc0a745b 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2400,8 +2400,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int 
outer_code, int opno ATTRIBUTE_UN
  *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
  return true;
}
-  /* bext pattern for zbs.  */
-  if (TARGET_ZBS && outer_code == SET
+  /* bit extraction pattern (zbs:bext, xtheadbs:tst).  */
+  if ((TARGET_ZBS || TARGET_XTHEADBS) && outer_code == SET
  && GET_CODE (XEXP (x, 1)) == CONST_INT
  && INTVAL (XEXP (x, 1)) == 1)
{
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 158e9124c3a..2c684885850 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -29,3 +29,14 @@ (define_insn "*th_addsl"
   "th.addsl\t%0,%3,%1,%2"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
+
+;; XTheadBs
+
+(define_insn "*th_tst"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (zero_extract:X (match_operand:X 1 "register_operand" "r")
+   (const_int 1)
+   (match_operand 2 "immediate_operand" "i")))]
+  "TARGET_XTHEADBS"
+  "th.tst\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")])
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c 
b/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c
new file mode 100644
index 000..674cec09128
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadbs" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadbs" { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+long
+foo1 (long i)
+{
+  return 1L & (i >> 20);
+}
+
+/* { dg-final { scan-assembler-times "th.tst\t" 1 } } */
+/* { dg-final { scan-assembler-not "andi" } } */
-- 
2.39.2



[PATCH v3 01/11] riscv: Add basic XThead* vendor extension support

2023-02-23 Thread Christoph Muellner
From: Christoph Müllner 

This patch add basic support for the following XThead* ISA extensions:

* XTheadBa
* XTheadBb
* XTheadBs
* XTheadCmo
* XTheadCondMov
* XTheadFMemIdx
* XTheadFmv
* XTheadInt
* XTheadMac
* XTheadMemIdx
* XTheadMemPair
* XTheadSync

The extensions are just recognized by the compiler and feature test
macros are generated (which this patch also brings tests for).

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc: Add xthead* extensions.
* config/riscv/riscv-opts.h (MASK_XTHEADBA): New.
(MASK_XTHEADBB): New.
(MASK_XTHEADBS): New.
(MASK_XTHEADCMO): New.
(MASK_XTHEADCONDMOV): New.
(MASK_XTHEADFMEMIDX): New.
(MASK_XTHEADFMV): New.
(MASK_XTHEADINT): New.
(MASK_XTHEADMAC): New.
(MASK_XTHEADMEMIDX): New.
(MASK_XTHEADMEMPAIR): New.
(MASK_XTHEADSYNC): New.
(TARGET_XTHEADBA): New.
(TARGET_XTHEADBB): New.
(TARGET_XTHEADBS): New.
(TARGET_XTHEADCMO): New.
(TARGET_XTHEADCONDMOV): New.
(TARGET_XTHEADFMEMIDX): New.
(TARGET_XTHEADFMV): New.
(TARGET_XTHEADINT): New.
(TARGET_XTHEADMAC): New.
(TARGET_XTHEADMEMIDX): New.
(TARGET_XTHEADMEMPAIR): new.
(TARGET_XTHEADSYNC): New.
* config/riscv/riscv.opt: Add riscv_xthead_subext.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadba.c: New test.
* gcc.target/riscv/xtheadbb.c: New test.
* gcc.target/riscv/xtheadbs.c: New test.
* gcc.target/riscv/xtheadcmo.c: New test.
* gcc.target/riscv/xtheadcondmov.c: New test.
* gcc.target/riscv/xtheadfmemidx.c: New test.
* gcc.target/riscv/xtheadfmv.c: New test.
* gcc.target/riscv/xtheadint.c: New test.
* gcc.target/riscv/xtheadmac.c: New test.
* gcc.target/riscv/xtheadmemidx.c: New test.
* gcc.target/riscv/xtheadmempair.c: New test.
* gcc.target/riscv/xtheadsync.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/common/config/riscv/riscv-common.cc   | 26 +++
 gcc/config/riscv/riscv-opts.h | 26 +++
 gcc/config/riscv/riscv.opt|  3 +++
 gcc/testsuite/gcc.target/riscv/xtheadba.c | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadbb.c | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadbs.c | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadcmo.c| 14 ++
 .../gcc.target/riscv/xtheadcondmov.c  | 14 ++
 .../gcc.target/riscv/xtheadfmemidx.c  | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadfmv.c| 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadint.c| 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadmac.c| 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c | 14 ++
 .../gcc.target/riscv/xtheadmempair.c  | 13 ++
 gcc/testsuite/gcc.target/riscv/xtheadsync.c   | 14 ++
 15 files changed, 222 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcmo.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadsync.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index ebc1ed7d7e4..ef221be1eb1 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -222,6 +222,19 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"svinval", ISA_SPEC_CLASS_NONE, 1, 0},
   {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0},
 
+  {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadbs", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadcmo", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadcondmov", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadfmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadfmv", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadint", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmac", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmempair", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadsync", ISA_SPEC_CLASS_NONE, 1, 0},
+
   /* Terminate the list.  */
   {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
 };
@@ -1248,6 +1261,19 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"svinval", _options::x_riscv_sv_subext, MASK_SVINVAL},
   {"svnapot", 

[RFC PATCH] RISC-V: Add support for vector crypto extensions

2022-12-21 Thread Christoph Muellner
From: Christoph Müllner 

This series adds basic support for the vector crypto extensions:
* Zvkb
* Zvkg
* Zvkh[a,b]
* Zvkn
* Zvksed
* Zvksh

The implementation follows the version 20221220 of the specification,
which can be found here:
  https://github.com/riscv/riscv-crypto/releases/tag/v20221220

Note, that this specification is not frozen yet, meaning that
incompatible changes are possible.
Therefore, this patchset is marked as RFC and should not be considered
for upstream inclusion.

All extensions come with (passing) tests for the feature test macros.

A Binutils patch series for vector crypto support can be found here:
  https://sourceware.org/pipermail/binutils/2022-December/125272.html

Signed-off-by: Christoph Müllner 
---
 gcc/common/config/riscv/riscv-common.cc | 16 
 gcc/config/riscv/riscv-opts.h   | 16 
 gcc/config/riscv/riscv.opt  |  3 +++
 gcc/testsuite/gcc.target/riscv/zvkb.c   | 13 +
 gcc/testsuite/gcc.target/riscv/zvkg.c   | 13 +
 gcc/testsuite/gcc.target/riscv/zvkha.c  | 13 +
 gcc/testsuite/gcc.target/riscv/zvkhb.c  | 13 +
 gcc/testsuite/gcc.target/riscv/zvkn.c   | 13 +
 gcc/testsuite/gcc.target/riscv/zvksed.c | 13 +
 gcc/testsuite/gcc.target/riscv/zvksh.c  | 13 +
 10 files changed, 126 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zvkb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zvkg.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zvkha.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zvkhb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zvkn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zvksed.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zvksh.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 4b7f777c103..dfd654eea24 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -201,6 +201,14 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"zve64f", ISA_SPEC_CLASS_NONE, 1, 0},
   {"zve64d", ISA_SPEC_CLASS_NONE, 1, 0},
 
+  {"zvkb", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zvkg", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zvkha", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zvkhb", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zvkn", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zvksed", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zvksh", ISA_SPEC_CLASS_NONE, 1, 0},
+
   {"zvl32b", ISA_SPEC_CLASS_NONE, 1, 0},
   {"zvl64b", ISA_SPEC_CLASS_NONE, 1, 0},
   {"zvl128b", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1226,6 +1234,14 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"zve64f",   _options::x_riscv_vector_elen_flags, 
MASK_VECTOR_ELEN_FP_32},
   {"zve64d",   _options::x_riscv_vector_elen_flags, 
MASK_VECTOR_ELEN_FP_64},
 
+  {"zvkb", _options::x_riscv_zvk_subext, MASK_ZVKB},
+  {"zvkg", _options::x_riscv_zvk_subext, MASK_ZVKG},
+  {"zvkha",_options::x_riscv_zvk_subext, MASK_ZVKHA},
+  {"zvkhb",_options::x_riscv_zvk_subext, MASK_ZVKHB},
+  {"zvkn", _options::x_riscv_zvk_subext, MASK_ZVKN},
+  {"zvksed",   _options::x_riscv_zvk_subext, MASK_ZVKSED},
+  {"zvksh",_options::x_riscv_zvk_subext, MASK_ZVKSH},
+
   {"zvl32b",_options::x_riscv_zvl_flags, MASK_ZVL32B},
   {"zvl64b",_options::x_riscv_zvl_flags, MASK_ZVL64B},
   {"zvl128b",   _options::x_riscv_zvl_flags, MASK_ZVL128B},
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 25fd85b09b1..5b367bd194c 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -132,6 +132,22 @@ enum stack_protector_guard {
 #define TARGET_VECTOR_ELEN_FP_64 \
   ((riscv_vector_elen_flags & MASK_VECTOR_ELEN_FP_64) != 0)
 
+#define MASK_ZVKB  (1 << 0)
+#define MASK_ZVKG  (1 << 1)
+#define MASK_ZVKHA (1 << 2)
+#define MASK_ZVKHB (1 << 3)
+#define MASK_ZVKN  (1 << 4)
+#define MASK_ZVKSED(1 << 5)
+#define MASK_ZVKSH (1 << 6)
+
+#define TARGET_ZVKB((riscv_zvk_subext & MASK_ZVKB) != 0)
+#define TARGET_ZVKG((riscv_zvk_subext & MASK_ZVKG) != 0)
+#define TARGET_ZVKHA   ((riscv_zvk_subext & MASK_ZVKHA) != 0)
+#define TARGET_ZVKHB   ((riscv_zvk_subext & MASK_ZVKHB) != 0)
+#define TARGET_ZVKN((riscv_zvk_subext & MASK_ZVKN) != 0)
+#define TARGET_ZVKSED  ((riscv_zvk_subext & MASK_ZVKSED) != 0)
+#define TARGET_ZVKSH   ((riscv_zvk_subext & MASK_ZVKSH) != 0)
+
 #define MASK_ZVL32B(1 <<  0)
 #define MASK_ZVL64B(1 <<  1)
 #define MASK_ZVL128B   (1 <<  2)
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 7c3ca48d1cc..ea24a80d734 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -218,6 +218,9 @@ int riscv_zk_subext
 TargetVariable
 int riscv_vector_elen_flags
 
+TargetVariable
+int riscv_zvk_subext
+
 TargetVariable
 int riscv_zvl_flags
 
diff --git a/gcc/testsuite/gcc.target/riscv/zvkb.c 
b/gcc/testsuite/gcc.target/riscv/zvkb.c
new file mode 

[PATCH v2 11/11] riscv: thead: Add support for XTheadMemPair ISA extension

2022-12-18 Thread Christoph Muellner
From: "moiz.hussain" 

The XTheadMemPair ISA extension provides load/store pair instructions:
* th.ldd
* th.sdd
* th.lwd
* th.lwud
* th.swd

This patch adds the following unnamed patterns to the peephole.md stage,
which take care of reordering loads/stores appropriately:
* load/store pair patterns for 4 instructions
* load/store pair patterns for 2 instructions

The generation of the load/store-pair instructions (based on ordered
load/store sequences) is inspired by the approaches of other backends.

The CFA expansion (save/restore registers on/from stack) is done quite
late, therefore it needs special-treatment. This patch tries to minimize
the impact for the default case and follows the pattern of other
backends.

gcc/ChangeLog:

* config/riscv/peephole.md: New load/store pair ordering
peephole optimizations.
* config/riscv/predicates.md (reg_or_const_operand): New
predicate.
* config/riscv/riscv-protos.h (riscv_load_store_bonding_p_2instr):
New prototype.
(riscv_load_store_bonding_p_4instr): Likewise.
(riscv_ldrstr_offset_compare): Likewise.
(extract_base_offset_in_addr): Likewise.
(th_riscv_output_mempair_move): Likewise.
(th_riscv_gen_adjusted_mempair): Likewise.
* config/riscv/riscv.cc (extract_base_offset_in_addr): New function.
(riscv_split_plus): Likewise.
(th_riscv_output_mempair_move): Likewise.
(riscv_load_store_bonding_p_4instr): Likewise.
(riscv_load_store_bonding_p_2instr): Likewise.
(riscv_ldrstr_offset_compare): Likewise.
(th_riscv_gen_adjusted_mempair): Likewise.
(riscv_save_reg): Moved before new uses.
(riscv_restore_reg): Moved before new uses.
(riscv_for_each_saved_reg): Adjusted for load/store-pair support
in CFA expansion.
* config/riscv/thead.md (th_mov_mempair_): New INSN.
(th_mov_mempair_di_si_zero_ext): New INSN.
(th_mov_mempair_di_si_sign_ext): New INSN.
(th_mov_mempair_si_si_zero_ext): New INSN.
(th_mov_mempair_si_si_sign_ext): New INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadmempair-1.c: New test.
* gcc.target/riscv/xtheadmempair-10.c: New test.
* gcc.target/riscv/xtheadmempair-11.c: New test.
* gcc.target/riscv/xtheadmempair-12.c: New test.
* gcc.target/riscv/xtheadmempair-13.c: New test.
* gcc.target/riscv/xtheadmempair-14.c: New test.
* gcc.target/riscv/xtheadmempair-15.c: New test.
* gcc.target/riscv/xtheadmempair-16.c: New test.
* gcc.target/riscv/xtheadmempair-17.c: New test.
* gcc.target/riscv/xtheadmempair-18.c: New test.
* gcc.target/riscv/xtheadmempair-19.c: New test.
* gcc.target/riscv/xtheadmempair-2.c: New test.
* gcc.target/riscv/xtheadmempair-20.c: New test.
* gcc.target/riscv/xtheadmempair-3.c: New test.
* gcc.target/riscv/xtheadmempair-4.c: New test.
* gcc.target/riscv/xtheadmempair-5.c: New test.
* gcc.target/riscv/xtheadmempair-6.c: New test.
* gcc.target/riscv/xtheadmempair-7.c: New test.
* gcc.target/riscv/xtheadmempair-8.c: New test.
* gcc.target/riscv/xtheadmempair-9.c: New test.
* gcc.target/riscv/xtheadmempair-helper.h: New test.

Co-Developed-by: Christoph Müllner 
Signed-off-by: Christoph Müllner 
Signed-off-by: M. Moiz Hussain 
Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/peephole.md  | 298 
 gcc/config/riscv/predicates.md|   4 +
 gcc/config/riscv/riscv-protos.h   |   9 +
 gcc/config/riscv/riscv.cc | 701 +-
 gcc/config/riscv/thead.md |  86 +++
 .../gcc.target/riscv/xtheadmempair-1.c|  29 +
 .../gcc.target/riscv/xtheadmempair-10.c   |  36 +
 .../gcc.target/riscv/xtheadmempair-11.c   |  18 +
 .../gcc.target/riscv/xtheadmempair-12.c   |  20 +
 .../gcc.target/riscv/xtheadmempair-13.c   |  23 +
 .../gcc.target/riscv/xtheadmempair-14.c   |  30 +
 .../gcc.target/riscv/xtheadmempair-15.c   |  15 +
 .../gcc.target/riscv/xtheadmempair-16.c   |  18 +
 .../gcc.target/riscv/xtheadmempair-17.c   |  13 +
 .../gcc.target/riscv/xtheadmempair-18.c   |  49 ++
 .../gcc.target/riscv/xtheadmempair-19.c   |  86 +++
 .../gcc.target/riscv/xtheadmempair-2.c|  26 +
 .../gcc.target/riscv/xtheadmempair-20.c   |  21 +
 .../gcc.target/riscv/xtheadmempair-3.c|  30 +
 .../gcc.target/riscv/xtheadmempair-4.c|  20 +
 .../gcc.target/riscv/xtheadmempair-5.c|  21 +
 .../gcc.target/riscv/xtheadmempair-6.c|  19 +
 .../gcc.target/riscv/xtheadmempair-7.c|  22 +
 .../gcc.target/riscv/xtheadmempair-8.c|  29 +
 .../gcc.target/riscv/xtheadmempair-9.c|  37 +
 .../gcc.target/riscv/xtheadmempair-helper.h   |  52 ++
 26 files changed, 1680 insertions(+), 32 deletions(-)
 create 

[PATCH v2 10/11] riscv: thead: Add support for XTheadFmv ISA extension

2022-12-18 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadFmv ISA extension provides instructions to move
data between 32-bit GP registers and 64-bit FP registers.

gcc/ChangeLog:

* config/riscv/constraints.md (TARGET_XTHEADFMV ? FP_REGS : NO_REGS)
New constraint "th_f_fmv".
(TARGET_XTHEADFMV ? GR_REGS : NO_REGS): New constraint
"th_r_fmv".
* config/riscv/riscv.cc (riscv_split_doubleword_move):
Add split code for XTheadFmv.
(riscv_secondary_memory_needed): XTheadFmv does not need
secondary memory.
* config/riscv/riscv.md: Add new UNSPEC_XTHEADFMV and
UNSPEC_XTHEADFMV_HW. Add support for XTheadFmv to
movdf_hardfloat_rv32.
* config/riscv/thead.md (th_fmv_hw_w_x): New INSN.
(th_fmv_x_w): New INSN.
(th_fmv_x_hw): New INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadfmv-fmv.c: New test.

Co-Developed-by: Xianmiao Qu 
Signed-off-by: Xianmiao Qu 
Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/constraints.md   |  8 +
 gcc/config/riscv/riscv.cc | 25 --
 gcc/config/riscv/riscv.md | 11 +--
 gcc/config/riscv/thead.md | 33 +++
 .../gcc.target/riscv/xtheadfmv-fmv.c  | 24 ++
 5 files changed, 95 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c

diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index 51cffb2bcb6..f3b1af774e1 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -156,3 +156,11 @@ (define_constraint "Wdm"
   "Vector duplicate memory operand"
   (and (match_operand 0 "memory_operand")
(match_code "reg" "0")))
+
+;; Vendor ISA extension constraints.
+
+(define_register_constraint "th_f_fmv" "TARGET_XTHEADFMV ? FP_REGS : NO_REGS"
+  "A floating-point register for XTheadFmv.")
+
+(define_register_constraint "th_r_fmv" "TARGET_XTHEADFMV ? GR_REGS : NO_REGS"
+  "An integer register for XTheadFmv.")
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 21ec7a6225b..fc18ce2c766 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2754,11 +2754,29 @@ riscv_split_64bit_move_p (rtx dest, rtx src)
 void
 riscv_split_doubleword_move (rtx dest, rtx src)
 {
-  rtx low_dest;
+  /* XTheadFmv has instructions for accessing the upper bits of a double.  */
+  if (!TARGET_64BIT && TARGET_XTHEADFMV)
+{
+  if (FP_REG_RTX_P (dest))
+   {
+ rtx low_src = riscv_subword (src, false);
+ rtx high_src = riscv_subword (src, true);
+ emit_insn (gen_th_fmv_hw_w_x (dest, high_src, low_src));
+ return;
+   }
+  if (FP_REG_RTX_P (src))
+   {
+ rtx low_dest = riscv_subword (dest, false);
+ rtx high_dest = riscv_subword (dest, true);
+ emit_insn (gen_th_fmv_x_w (low_dest, src));
+ emit_insn (gen_th_fmv_x_hw (high_dest, src));
+ return;
+   }
+}
 
/* The operation can be split into two normal moves.  Decide in
   which order to do them.  */
-   low_dest = riscv_subword (dest, false);
+   rtx low_dest = riscv_subword (dest, false);
if (REG_P (low_dest) && reg_overlap_mentioned_p (low_dest, src))
  {
riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
@@ -5752,7 +5770,8 @@ riscv_secondary_memory_needed (machine_mode mode, 
reg_class_t class1,
 {
   return (!riscv_v_ext_vector_mode_p (mode)
  && GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD
- && (class1 == FP_REGS) != (class2 == FP_REGS));
+ && (class1 == FP_REGS) != (class2 == FP_REGS)
+ && !TARGET_XTHEADFMV);
 }
 
 /* Implement TARGET_REGISTER_MOVE_COST.  */
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 20506451e7c..ef6ae443059 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -100,6 +100,10 @@ (define_c_enum "unspecv" [
 
   ;; Zihintpause unspec
   UNSPECV_PAUSE
+
+  ;; XTheadFmv unspec
+  UNSPEC_XTHEADFMV
+  UNSPEC_XTHEADFMV_HW
 ])
 
 (define_constants
@@ -1836,16 +1840,17 @@ (define_expand "movdf"
 DONE;
 })
 
+
 ;; In RV32, we lack fmv.x.d and fmv.d.x.  Go through memory instead.
 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
 (define_insn "*movdf_hardfloat_rv32"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,  *r,*r,*m")
-   (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r*G,*m,*r"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" 
"=f,f,f,m,m,*th_f_fmv,*th_r_fmv,  *r,*r,*m")
+   (match_operand:DF 1 "move_operand" " 
f,G,m,f,G,*th_r_fmv,*th_f_fmv,*r*G,*m,*r"))]
   "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
&& (register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))"
   { return riscv_output_move (operands[0], operands[1]); }
-  [(set_attr 

[PATCH v2 09/11] riscv: thead: Add support for XTheadMac ISA extension

2022-12-18 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadMac ISA extension provides multiply-accumulate/subtract
instructions:
* mula/mulaw/mulah
* muls/mulsw/mulsh

To benefit from middle-end passes, we expand the following named
patterns in riscv.md (as they are not T-Head-specific):
* maddhisi4
* msubhisi4

gcc/ChangeLog:

* config/riscv/riscv.md (maddhisi4): New expand.
(msubhisi4): New expand.
* config/riscv/thead.md (*th_mula): New pattern.
(*th_mulawsi): New pattern.
(*th_mulawsi2): New pattern.
(*th_maddhisi4): New pattern.
(*th_sextw_maddhisi4): New pattern.
(*th_muls): New pattern.
(*th_mulswsi): New pattern.
(*th_mulswsi2): New pattern.
(*th_msubhisi4): New pattern.
(*th_sextw_msubhisi4): New pattern.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/thead-mula-muls.c: New test.

Co-Developed-by: Xianmiao Qu 
Signed-off-by: Xianmiao Qu 
Signed-off-by: Christoph Müllner 

Changed in v2:
- Add missing prefix in on INSN
---
 gcc/config/riscv/riscv.md |  18 +++
 gcc/config/riscv/thead.md | 121 ++
 .../gcc.target/riscv/xtheadmac-mula-muls.c|  43 +++
 3 files changed, 182 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac-mula-muls.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 34327bfb01f..20506451e7c 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3086,6 +3086,24 @@ (define_expand "extzv"
 FAIL;
 })
 
+(define_expand "maddhisi4"
+  [(set (match_operand:SI 0 "register_operand")
+   (plus:SI
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"))
+  (sign_extend:SI (match_operand:HI 2 "register_operand")))
+ (match_operand:SI 3 "register_operand")))]
+  "TARGET_XTHEADMAC"
+)
+
+(define_expand "msubhisi4"
+  [(set (match_operand:SI 0 "register_operand")
+   (minus:SI
+ (match_operand:SI 3 "register_operand")
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"))
+  (sign_extend:SI (match_operand:HI 2 "register_operand")]
+  "TARGET_XTHEADMAC"
+)
+
 (include "bitmanip.md")
 (include "sync.md")
 (include "peephole.md")
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 9f03d1d43b4..d9cac15cc5f 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -143,3 +143,124 @@ (define_insn "*th_cond_gpr_mov"
th.mveqz\t%0,%z3,%1"
   [(set_attr "type" "condmove")
(set_attr "mode" "")])
+
+;; XTheadMac
+
+(define_insn "*th_mula"
+  [(set (match_operand:X 0 "register_operand" "=r")
+ (plus:X (mult:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:X 2 "register_operand" "r"))
+ (match_operand:X 3 "register_operand" "0")))]
+  "TARGET_XTHEADMAC"
+  "th.mula\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "")]
+)
+
+(define_insn "*th_mulawsi"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (sign_extend:DI
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+   (match_operand:SI 2 "register_operand" "r"))
+  (match_operand:SI 3 "register_operand" "0"]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulaw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_mulawsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+   (match_operand:SI 2 "register_operand" "r"))
+  (match_operand:SI 3 "register_operand" "0")))]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulaw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_maddhisi4"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI
+   (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" " r"))
+ (sign_extend:SI (match_operand:HI 2 "register_operand" " r")))
+   (match_operand:SI 3 "register_operand" " 0")))]
+  "TARGET_XTHEADMAC"
+  "th.mulah\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_sextw_maddhisi4"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (sign_extend:DI
+ (plus:SI
+   (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" " r"))
+ (sign_extend:SI (match_operand:HI 2 "register_operand" " r")))
+   (match_operand:SI 3 "register_operand" " 0"]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulah\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_muls"
+  [(set (match_operand:X 0 "register_operand" "=r")
+ (minus:X (match_operand:X 3 "register_operand" "0")
+  (mult:X 

[PATCH v2 08/11] riscv: thead: Add support for XTheadCondMov ISA extensions

2022-12-18 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for XTheadCondMov ISA extension.
The extension brings a one-sided conditional move (no else-assignment).
Given that GCC has a great if-conversion pass, we don't need to do much,
besides properly expanding movcc accordingly and adjust the cost
model.

gcc/ChangeLog:

* config/riscv/iterators.md (TARGET_64BIT): Add GPR2 iterator.
* config/riscv/riscv-protos.h (riscv_expand_conditional_move):
Add prototype.
* config/riscv/riscv.cc (riscv_rtx_costs): Add costs for
XTheadCondMov.
(riscv_expand_conditional_move): New function.
(riscv_expand_conditional_move_onesided): New function.
* config/riscv/riscv.md: Add support for XTheadCondMov.
* config/riscv/thead.md (*th_cond_mov): Add
support for XTheadCondMov.
(*th_cond_gpr_mov): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c: New test.

Changes for v2:
- Properly gate expansion constraints to avoid failing INSN lookup
- Restrict subreg comparisons

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/iterators.md |   4 +
 gcc/config/riscv/riscv-protos.h   |   2 +-
 gcc/config/riscv/riscv.cc | 100 +++---
 gcc/config/riscv/riscv.md |  17 ++-
 gcc/config/riscv/thead.md |  37 +++
 .../riscv/xtheadcondmov-mveqz-imm-eqz.c   |  38 +++
 .../riscv/xtheadcondmov-mveqz-imm-not.c   |  38 +++
 .../riscv/xtheadcondmov-mveqz-reg-eqz.c   |  38 +++
 .../riscv/xtheadcondmov-mveqz-reg-not.c   |  38 +++
 .../riscv/xtheadcondmov-mvnez-imm-cond.c  |  38 +++
 .../riscv/xtheadcondmov-mvnez-imm-nez.c   |  38 +++
 .../riscv/xtheadcondmov-mvnez-reg-cond.c  |  38 +++
 .../riscv/xtheadcondmov-mvnez-reg-nez.c   |  38 +++
 13 files changed, 440 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c

diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index efdd3ccc9a7..1c5f3dd5681 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -26,6 +26,10 @@
 ;; from the same template.
 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
 
+;; A copy of GPR that can be used when a pattern has two independent
+;; modes.
+(define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
+
 ;; This mode iterator allows :P to be used for patterns that operate on
 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index e17e003f8e2..7975bc4f438 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -58,8 +58,8 @@ extern const char *riscv_output_return ();
 extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx);
 extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx);
 extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx);
-extern void riscv_expand_conditional_move (rtx, rtx, rtx, rtx_code, rtx, rtx);
 #endif
+extern bool riscv_expand_conditional_move (rtx, rtx, rtx, rtx);
 extern rtx riscv_legitimize_call_address (rtx);
 extern void riscv_set_return_address (rtx, rtx);
 extern bool riscv_expand_block_move (rtx, rtx, rtx);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index b57c1f1d727..21ec7a6225b 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2300,8 +2300,8 @@ 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
- && register_operand (XEXP (x, 1), mode)
+  if ((TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
+ && reg_or_0_operand 

[PATCH v2 05/11] riscv: thead: Add support for the XTheadBa ISA extension

2022-12-18 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the XTheadBa ISA extension.
The new INSN pattern is defined in a new file to separate
this vendor extension from the standard extensions.

gcc/ChangeLog:

* config/riscv/riscv.md: Include thead.md
* config/riscv/thead.md: New file.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadba-addsl.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.md |  1 +
 gcc/config/riscv/thead.md | 31 +++
 .../gcc.target/riscv/xtheadba-addsl.c | 55 +++
 3 files changed, 87 insertions(+)
 create mode 100644 gcc/config/riscv/thead.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index a8bb331f25c..571349b1ca5 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3073,4 +3073,5 @@ (define_insn "riscv_prefetchi_"
 (include "pic.md")
 (include "generic.md")
 (include "sifive-7.md")
+(include "thead.md")
 (include "vector.md")
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
new file mode 100644
index 000..0257cbfad3e
--- /dev/null
+++ b/gcc/config/riscv/thead.md
@@ -0,0 +1,31 @@
+;; Machine description for T-Head vendor extensions
+;; Copyright (C) 2021-2022 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
+;; .
+
+;; XTheadBa
+
+(define_insn "*th_addsl"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (plus:X (ashift:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "I"))
+   (match_operand:X 3 "register_operand" "r")))]
+  "TARGET_XTHEADBA
+   && (INTVAL (operands[2]) >= 0) && (INTVAL (operands[2]) <= 3)"
+  "th.addsl\t%0,%1,%3,%2"
+  [(set_attr "type" "bitmanip")
+   (set_attr "mode" "")])
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c 
b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
new file mode 100644
index 000..5004735a246
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadba" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadba" { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+long
+test_1 (long a, long b)
+{
+  /* th.addsl aX, aX, 1  */
+  return a + (b << 1);
+}
+
+int
+foos (short *x, int n)
+{
+  /* th.addsl aX, aX, 1  */
+  return x[n];
+}
+
+long
+test_2 (long a, long b)
+{
+  /* th.addsl aX, aX, 2  */
+  return a + (b << 2);
+}
+
+int
+fooi (int *x, int n)
+{
+  /* th.addsl aX, aX, 2  */
+  return x[n];
+}
+
+long
+test_3 (long a, long b)
+{
+  /* th.addsl aX, aX, 3  */
+  return a + (b << 3);
+}
+
+long
+fool (long *x, int n)
+{
+  /* th.addsl aX, aX, 2 (rv32)  */
+  /* th.addsl aX, aX, 3 (rv64)  */
+  return x[n];
+}
+
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,1" 2 } } */
+
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,2" 3 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,2" 2 { target { rv64 } } } } */
+
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,3" 1 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,3" 2 { target { rv64 } } } } */
-- 
2.38.1



[PATCH v2 03/11] riscv: Add basic XThead* vendor extension support

2022-12-18 Thread Christoph Muellner
From: Christoph Müllner 

This patch add basic support for the following XThead* ISA extensions:

* XTheadBa
* XTheadBb
* XTheadBs
* XTheadCmo
* XTheadCondMov
* XTheadFMemIdx
* XTheadFmv
* XTheadInt
* XTheadMac
* XTheadMemIdx
* XTheadMemPair
* XTheadSync

The extensions are just recognized by the compiler and feature test
macros are generated (which this patch also brings tests for).

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc: Add xthead* extensions.
* config/riscv/riscv-opts.h (MASK_XTHEADBA): New.
(TARGET_XTHEADBA): New.
(MASK_XTHEADBB): New.
(TARGET_XTHEADBB): New.
(MASK_XTHEADBS): New.
(TARGET_XTHEADBS): New.
(MASK_XTHEADCMO): New.
(TARGET_XTHEADCMO): New.
(MASK_XTHEADCONDMOV): New.
(TARGET_XTHEADCONDMOV): New.
(MASK_XTHEADFMEMIDX): New.
(TARGET_XTHEADFMEMIDX): New.
(MASK_XTHEADFMV): New.
(TARGET_XTHEADFMV): New.
(MASK_XTHEADINT): New.
(TARGET_XTHEADINT): New.
(MASK_XTHEADMAC): New.
(TARGET_XTHEADMAC): New.
(MASK_XTHEADMEMIDX): New.
(TARGET_XTHEADMEMIDX): New.
(MASK_XTHEADMEMPAIR): New.
(TARGET_XTHEADMEMPAIR): new.
(MASK_XTHEADSYNC): New.
(TARGET_XTHEADSYNC): New.
* config/riscv/riscv.opt: Add riscv_xthead_subext.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadba.c: New test.
* gcc.target/riscv/xtheadbb.c: New test.
* gcc.target/riscv/xtheadbs.c: New test.
* gcc.target/riscv/xtheadcmo.c: New test.
* gcc.target/riscv/xtheadcondmov.c: New test.
* gcc.target/riscv/xtheadfmemidx.c: New test.
* gcc.target/riscv/xtheadfmv.c: New test.
* gcc.target/riscv/xtheadint.c: New test.
* gcc.target/riscv/xtheadmac.c: New test.
* gcc.target/riscv/xtheadmemidx.c: New test.
* gcc.target/riscv/xtheadmempair.c: New test.
* gcc.target/riscv/xtheadsync.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/common/config/riscv/riscv-common.cc   | 26 +++
 gcc/config/riscv/riscv-opts.h | 26 +++
 gcc/config/riscv/riscv.opt|  3 +++
 gcc/testsuite/gcc.target/riscv/xtheadba.c | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadbb.c | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadbs.c | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadcmo.c| 14 ++
 .../gcc.target/riscv/xtheadcondmov.c  | 14 ++
 .../gcc.target/riscv/xtheadfmemidx.c  | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadfmv.c| 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadint.c| 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadmac.c| 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c | 14 ++
 .../gcc.target/riscv/xtheadmempair.c  | 13 ++
 gcc/testsuite/gcc.target/riscv/xtheadsync.c   | 14 ++
 15 files changed, 222 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcmo.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadsync.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 4b7f777c103..84f7de8a16e 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -222,6 +222,19 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"svinval", ISA_SPEC_CLASS_NONE, 1, 0},
   {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0},
 
+  {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadbs", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadcmo", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadcondmov", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadfmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadfmv", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadint", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmac", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmempair", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadsync", ISA_SPEC_CLASS_NONE, 1, 0},
+
   /* Terminate the list.  */
   {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
 };
@@ -1247,6 +1260,19 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"svinval", _options::x_riscv_sv_subext, MASK_SVINVAL},
   {"svnapot", 

[PATCH v2 07/11] riscv: thead: Add support for th XTheadBb ISA extension

2022-12-18 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the XTheadBb ISA extension.
Thus, there is a functional overlap of the new instructions with
existing Bitmanip instruction, which allows a good amount of code
sharing. However, the vendor extensions are cleanly separated from
the standard extensions (e.g. by using INSN expand pattern that
will re-emit RTL that matches the patterns of either Bitmanip or
XThead INSNs).

gcc/ChangeLog:

* config/riscv/bitmanip.md (clzdi2): New expand.
(clzsi2): New expand.
(ctz2): New expand.
(popcount2): New expand.
(si2): Rename INSN.
(*si2): Hide INSN name.
(di2): Rename INSN.
(*di2): Hide INSN name.
(rotrsi3): Remove INSN.
(rotr3): Add expand.
(*rotrsi3): New INSN.
(rotrdi3): Rename INSN.
(*rotrdi3): Hide INSN name.
(rotrsi3_sext): Rename INSN.
(*rotrsi3_sext): Hide INSN name.
(bswap2): Remove INSN.
(bswapdi2): Add expand.
(bswapsi2): Add expand.
(*bswap2): Hide INSN name.
* config/riscv/riscv.cc (riscv_rtx_costs): Add costs for sign
extraction.
* config/riscv/riscv.md (extv): New expand.
(extzv): New expand.
* config/riscv/thead.md (*th_srrisi3): New INSN.
(*th_srridi3): New INSN.
(*th_ext): New INSN.
(*th_extu): New INSN.
(*th_clz2): New INSN.
(*th_revsi2): New INSN.
(*th_revdi2): New INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-ext.c: New test.
* gcc.target/riscv/xtheadbb-extu-2.c: New test.
* gcc.target/riscv/xtheadbb-extu.c: New test.
* gcc.target/riscv/xtheadbb-ff1.c: New test.
* gcc.target/riscv/xtheadbb-rev.c: New test.
* gcc.target/riscv/xtheadbb-srri.c: New test.

Changes for v2:
- Merge all XTheadB* support patches
- Remove useless operand sanity checks for extv and extzv
- Prefer c.andi over th.extu if possible
- Add ff1 tests for clz/ctz
- Fix ext/extu test cases
- Enable tests for RV32

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/bitmanip.md  | 52 +--
 gcc/config/riscv/riscv.cc |  9 +++
 gcc/config/riscv/riscv.md | 20 ++
 gcc/config/riscv/thead.md | 66 +++
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c | 20 ++
 .../gcc.target/riscv/xtheadbb-extu-2.c| 22 +++
 .../gcc.target/riscv/xtheadbb-extu.c  | 22 +++
 gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c | 18 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c | 45 +
 .../gcc.target/riscv/xtheadbb-srri.c  | 21 ++
 10 files changed, 289 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index d17133d58c1..70e72a35d7d 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -185,6 +185,26 @@ (define_insn "*slliuw"
 
 ;; ZBB extension.
 
+(define_expand "clzdi2"
+  [(set (match_operand:DI 0 "register_operand")
+   (clz:DI (match_operand:DI 1 "register_operand")))]
+  "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB)")
+
+(define_expand "clzsi2"
+  [(set (match_operand:SI 0 "register_operand")
+   (clz:SI (match_operand:SI 1 "register_operand")))]
+  "TARGET_ZBB || (!TARGET_64BIT && TARGET_XTHEADBB)")
+
+(define_expand "ctz2"
+  [(set (match_operand:GPR 0 "register_operand")
+   (ctz:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB")
+
+(define_expand "popcount2"
+  [(set (match_operand:GPR 0 "register_operand")
+   (popcount:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB")
+
 (define_insn "*_not"
   [(set (match_operand:X 0 "register_operand" "=r")
 (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
@@ -216,7 +236,7 @@ (define_insn "*xor_not"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
 
-(define_insn "si2"
+(define_insn "*si2"
   [(set (match_operand:SI 0 "register_operand" "=r")
 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))]
   "TARGET_ZBB"
@@ -233,7 +253,7 @@ (define_insn "*disi2"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "SI")])
 
-(define_insn "di2"
+(define_insn "*di2"
   [(set (match_operand:DI 0 "register_operand" "=r")
 (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
   "TARGET_64BIT && TARGET_ZBB"
@@ -273,7 +293,17 @@ (define_insn "*zero_extendhi2_zbb"
   [(set_attr "type" "bitmanip,load")
(set_attr "mode" "HI")])

[PATCH v2 06/11] riscv: thead: Add support for the XTheadBs ISA extension

2022-12-18 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the XTheadBs ISA extension.
The new INSN pattern is defined in a new file to separate
this vendor extension from the standard extensions.
The cost model adjustment reuses the xbs:bext cost.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_rtx_costs): Add xthead:tst cost.
* config/riscv/thead.md (*th_tst): New INSN.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbs-tst.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.cc |  4 ++--
 gcc/config/riscv/thead.md | 11 +++
 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c | 13 +
 3 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a8d5e1dac7f..537515771c6 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2400,8 +2400,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int 
outer_code, int opno ATTRIBUTE_UN
  *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
  return true;
}
-  /* bext pattern for zbs.  */
-  if (TARGET_ZBS && outer_code == SET
+  /* bit extraction pattern (zbs:bext, xtheadbs:tst).  */
+  if ((TARGET_ZBS || TARGET_XTHEADBS) && outer_code == SET
  && GET_CODE (XEXP (x, 1)) == CONST_INT
  && INTVAL (XEXP (x, 1)) == 1)
{
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 0257cbfad3e..0e23644ef59 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -29,3 +29,14 @@ (define_insn "*th_addsl"
   "th.addsl\t%0,%1,%3,%2"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
+
+;; XTheadBs
+
+(define_insn "*th_tst"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (zero_extract:X (match_operand:X 1 "register_operand" "r")
+   (const_int 1)
+   (match_operand 2 "immediate_operand" "i")))]
+  "TARGET_XTHEADBS"
+  "th.tst\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")])
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c 
b/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c
new file mode 100644
index 000..674cec09128
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadbs" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadbs" { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+long
+foo1 (long i)
+{
+  return 1L & (i >> 20);
+}
+
+/* { dg-final { scan-assembler-times "th.tst\t" 1 } } */
+/* { dg-final { scan-assembler-not "andi" } } */
-- 
2.38.1



[PATCH v2 04/11] riscv: riscv-cores.def: Add T-Head XuanTie C906

2022-12-18 Thread Christoph Muellner
From: Christoph Müllner 

This adds T-Head's XuanTie C906 to the list of known cores as "thead-c906".
The C906 is shipped for quite some time (it is the core of the Allwinner D1).
Note, that the tuning struct for the C906 is already part of GCC (it is
also name "thead-c906").

gcc/ChangeLog:

* config/riscv/riscv-cores.def (RISCV_CORE): Add "thead-c906".

gcc/testsuite/ChangeLog:

* gcc.target/riscv/mcpu-thead-c906.c: New test.

Changes for v2:
- Enable all supported vendor extensions

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv-cores.def  |  4 +++
 .../gcc.target/riscv/mcpu-thead-c906.c| 28 +++
 2 files changed, 32 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c

diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
index 31ad34682c5..307381802fa 100644
--- a/gcc/config/riscv/riscv-cores.def
+++ b/gcc/config/riscv/riscv-cores.def
@@ -73,4 +73,8 @@ RISCV_CORE("sifive-s76",  "rv64imafdc", "sifive-7-series")
 RISCV_CORE("sifive-u54",  "rv64imafdc", "sifive-5-series")
 RISCV_CORE("sifive-u74",  "rv64imafdc", "sifive-7-series")
 
+RISCV_CORE("thead-c906",  
"rv64imafdc_xtheadba_xtheadbb_xtheadbs_xtheadcmo_"
+ "xtheadcondmov_xtheadfmemidx_xtheadmac_"
+ "xtheadmemidx_xtheadmempair_xtheadsync",
+ "thead-c906")
 #undef RISCV_CORE
diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c 
b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
new file mode 100644
index 000..a71b43a6167
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */
+/* { dg-options "-mcpu=thead-c906" { target { rv64 } } } */
+/* T-Head XuanTie C906 => rv64imafdc */
+
+#if !((__riscv_xlen == 64) \
+  && !defined(__riscv_32e) \
+  && defined(__riscv_mul)  \
+  && defined(__riscv_atomic)   \
+  && (__riscv_flen == 64)  \
+  && defined(__riscv_compressed)   \
+  && defined(__riscv_xtheadba) \
+  && defined(__riscv_xtheadbb) \
+  && defined(__riscv_xtheadbs) \
+  && defined(__riscv_xtheadcmo)\
+  && defined(__riscv_xtheadcondmov)\
+  && defined(__riscv_xtheadfmemidx)\
+  && defined(__riscv_xtheadmac)\
+  && defined(__riscv_xtheadmemidx) \
+  && defined(__riscv_xtheadmempair)\
+  && defined(__riscv_xtheadsync))
+#error "unexpected arch"
+#endif
+
+int main()
+{
+  return 0;
+}
-- 
2.38.1



[PATCH v2 02/11] riscv: Restructure callee-saved register save/restore code

2022-12-18 Thread Christoph Muellner
From: Christoph Müllner 

This patch restructures the loop over the GP registers
which saves/restores then as part of the prologue/epilogue.
No functional change is intended by this patch, but it
offers the possibility to use load-pair/store-pair instructions.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_next_saved_reg): New function.
(riscv_is_eh_return_data_register): New function.
(riscv_for_each_saved_reg): Restructure loop.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.cc | 94 +++
 1 file changed, 66 insertions(+), 28 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 6dd2ab2d11e..a8d5e1dac7f 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4835,6 +4835,49 @@ riscv_save_restore_reg (machine_mode mode, int regno,
   fn (gen_rtx_REG (mode, regno), mem);
 }
 
+/* Return the next register up from REGNO up to LIMIT for the callee
+   to save or restore.  OFFSET will be adjusted accordingly.
+   If INC is set, then REGNO will be incremented first.  */
+
+static unsigned int
+riscv_next_saved_reg (unsigned int regno, unsigned int limit,
+ HOST_WIDE_INT *offset, bool inc = true)
+{
+  if (inc)
+regno++;
+
+  while (regno <= limit)
+{
+  if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
+   {
+ *offset = *offset - UNITS_PER_WORD;
+ break;
+   }
+
+  regno++;
+}
+  return regno;
+}
+
+/* Return TRUE if provided REGNO is eh return data register.  */
+
+static bool
+riscv_is_eh_return_data_register (unsigned int regno)
+{
+  unsigned int i, regnum;
+
+  if (!crtl->calls_eh_return)
+return false;
+
+  for (i = 0; (regnum = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
+if (regno == regnum)
+  {
+   return true;
+  }
+
+  return false;
+}
+
 /* Call FN for each register that is saved by the current function.
SP_OFFSET is the offset of the current stack pointer from the start
of the frame.  */
@@ -4844,36 +4887,31 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, 
riscv_save_restore_fn fn,
  bool epilogue, bool maybe_eh_return)
 {
   HOST_WIDE_INT offset;
+  unsigned int regno;
+  unsigned int start = GP_REG_FIRST;
+  unsigned int limit = GP_REG_LAST;
 
   /* Save the link register and s-registers. */
-  offset = (cfun->machine->frame.gp_sp_offset - sp_offset).to_constant ();
-  for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
-if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
-  {
-   bool handle_reg = !cfun->machine->reg_is_wrapped_separately[regno];
-
-   /* If this is a normal return in a function that calls the eh_return
-  builtin, then do not restore the eh return data registers as that
-  would clobber the return value.  But we do still need to save them
-  in the prologue, and restore them for an exception return, so we
-  need special handling here.  */
-   if (epilogue && !maybe_eh_return && crtl->calls_eh_return)
- {
-   unsigned int i, regnum;
-
-   for (i = 0; (regnum = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM;
-i++)
- if (regno == regnum)
-   {
- handle_reg = FALSE;
- break;
-   }
- }
-
-   if (handle_reg)
- riscv_save_restore_reg (word_mode, regno, offset, fn);
-   offset -= UNITS_PER_WORD;
-  }
+  offset = (cfun->machine->frame.gp_sp_offset - sp_offset).to_constant ()
+  + UNITS_PER_WORD;
+  for (regno = riscv_next_saved_reg (start, limit, , false);
+   regno <= limit;
+   regno = riscv_next_saved_reg (regno, limit, ))
+{
+  if (cfun->machine->reg_is_wrapped_separately[regno])
+   continue;
+
+  /* If this is a normal return in a function that calls the eh_return
+builtin, then do not restore the eh return data registers as that
+would clobber the return value.  But we do still need to save them
+in the prologue, and restore them for an exception return, so we
+need special handling here.  */
+  if (epilogue && !maybe_eh_return
+ && riscv_is_eh_return_data_register (regno))
+   continue;
+
+  riscv_save_restore_reg (word_mode, regno, offset, fn);
+}
 
   /* This loop must iterate over the same space as its companion in
  riscv_compute_frame_info.  */
-- 
2.38.1



[PATCH v2 00/11] RISC-V: Add XThead* extension support

2022-12-18 Thread Christoph Muellner
From: Christoph Müllner 

This series introduces support for the T-Head specific RISC-V ISA extensions
which are available e.g. on the T-Head XuanTie C906.

The ISA spec can be found here:
  https://github.com/T-head-Semi/thead-extension-spec

The series begins with two preparation patches, that do not introduce
any functional changes.  The first patch just fixes the comment order
to the code order.  And the second patch restructures the register
save/restore code in the CFA expansion, which simplifies the
XTheadMemPair patch.

This series adds basic support (i.e. awareness of the extension name and test
macro) for the following XThead* extensions:
* XTheadBa
* XTheadBb
* XTheadBs
* XTheadCmo
* XTheadCondMov
* XTheadFMemIdx
* XTheadFmv
* XTheadInt
* XTheadMac
* XTheadMemIdx
* XTheadMemPair
* XTheadSync

The series includes optimizations for most of these extensions
(the exceptions are XTheadInt and XTheadMemIdx).

The series also introduces support for "-mcpu=thead-c906", which also
enables all available XThead* ISA extensions of the T-Head C906.

All patches have been tested and don't introduce regressions for RV32 or
RV64. Therefore partial inclusion of this series is possible.

Christoph Müllner (10):
  riscv: attr: Synchronize comments with code
  riscv: Restructure callee-saved register save/restore code
  riscv: Add basic XThead* vendor extension support
  riscv: riscv-cores.def: Add T-Head XuanTie C906
  riscv: thead: Add support for the XTheadBa ISA extension
  riscv: thead: Add support for the XTheadBs ISA extension
  riscv: thead: Add support for th XTheadBb ISA extension
  riscv: thead: Add support for XTheadCondMov ISA extensions
  riscv: thead: Add support for XTheadMac ISA extension
  riscv: thead: Add support for XTheadFmv ISA extension

moiz.hussain (1):
  riscv: thead: Add support for XTheadMemPair ISA extension

 gcc/common/config/riscv/riscv-common.cc   |  26 +
 gcc/config/riscv/bitmanip.md  |  52 +-
 gcc/config/riscv/constraints.md   |   8 +
 gcc/config/riscv/iterators.md |   4 +
 gcc/config/riscv/peephole.md  | 298 ++
 gcc/config/riscv/predicates.md|   4 +
 gcc/config/riscv/riscv-cores.def  |   4 +
 gcc/config/riscv/riscv-opts.h |  26 +
 gcc/config/riscv/riscv-protos.h   |  11 +-
 gcc/config/riscv/riscv.cc | 919 --
 gcc/config/riscv/riscv.md |  72 +-
 gcc/config/riscv/riscv.opt|   3 +
 gcc/config/riscv/thead.md | 385 
 .../gcc.target/riscv/mcpu-thead-c906.c|  28 +
 .../gcc.target/riscv/xtheadba-addsl.c |  55 ++
 gcc/testsuite/gcc.target/riscv/xtheadba.c |  14 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c |  20 +
 .../gcc.target/riscv/xtheadbb-extu-2.c|  22 +
 .../gcc.target/riscv/xtheadbb-extu.c  |  22 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c |  18 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c |  45 +
 .../gcc.target/riscv/xtheadbb-srri.c  |  21 +
 gcc/testsuite/gcc.target/riscv/xtheadbb.c |  14 +
 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadbs.c |  14 +
 gcc/testsuite/gcc.target/riscv/xtheadcmo.c|  14 +
 .../riscv/xtheadcondmov-mveqz-imm-eqz.c   |  38 +
 .../riscv/xtheadcondmov-mveqz-imm-not.c   |  38 +
 .../riscv/xtheadcondmov-mveqz-reg-eqz.c   |  38 +
 .../riscv/xtheadcondmov-mveqz-reg-not.c   |  38 +
 .../riscv/xtheadcondmov-mvnez-imm-cond.c  |  38 +
 .../riscv/xtheadcondmov-mvnez-imm-nez.c   |  38 +
 .../riscv/xtheadcondmov-mvnez-reg-cond.c  |  38 +
 .../riscv/xtheadcondmov-mvnez-reg-nez.c   |  38 +
 .../gcc.target/riscv/xtheadcondmov.c  |  14 +
 .../gcc.target/riscv/xtheadfmemidx.c  |  14 +
 .../gcc.target/riscv/xtheadfmv-fmv.c  |  24 +
 gcc/testsuite/gcc.target/riscv/xtheadfmv.c|  14 +
 gcc/testsuite/gcc.target/riscv/xtheadint.c|  14 +
 .../gcc.target/riscv/xtheadmac-mula-muls.c|  43 +
 gcc/testsuite/gcc.target/riscv/xtheadmac.c|  14 +
 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c |  14 +
 .../gcc.target/riscv/xtheadmempair-1.c|  29 +
 .../gcc.target/riscv/xtheadmempair-10.c   |  36 +
 .../gcc.target/riscv/xtheadmempair-11.c   |  18 +
 .../gcc.target/riscv/xtheadmempair-12.c   |  20 +
 .../gcc.target/riscv/xtheadmempair-13.c   |  23 +
 .../gcc.target/riscv/xtheadmempair-14.c   |  30 +
 .../gcc.target/riscv/xtheadmempair-15.c   |  15 +
 .../gcc.target/riscv/xtheadmempair-16.c   |  18 +
 .../gcc.target/riscv/xtheadmempair-17.c   |  13 +
 .../gcc.target/riscv/xtheadmempair-18.c   |  49 +
 .../gcc.target/riscv/xtheadmempair-19.c   |  86 ++
 .../gcc.target/riscv/xtheadmempair-2.c|  26 +
 .../gcc.target/riscv/xtheadmempair-20.c   |  21 +
 .../gcc.target/riscv/xtheadmempair-3.c|  30 +
 

[PATCH v2 01/11] riscv: attr: Synchronize comments with code

2022-12-18 Thread Christoph Muellner
From: Christoph Müllner 

The comment above the enumeration of existing attributes got out of
order and a few entries were forgotten.
This patch synchronizes the comments according to the list.
This commit does not include any functional change.

gcc/ChangeLog:

* config/riscv/riscv.md: Sync comments with code.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.md | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index df57e2b0b4a..a8bb331f25c 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -220,7 +220,6 @@ (define_attr "enabled" "no,yes"
 ;; mfc transfer from coprocessor
 ;; const   load constant
 ;; arith   integer arithmetic instructions
-;; auipc   integer addition to PC
 ;; logical  integer logical instructions
 ;; shift   integer shift instructions
 ;; slt set less than instructions
@@ -236,9 +235,13 @@ (define_attr "enabled" "no,yes"
 ;; fcvtfloating point convert
 ;; fsqrt   floating point square root
 ;; multi   multiword sequence (or user asm statements)
+;; auipc   integer addition to PC
+;; sfb_alu  SFB ALU instruction
 ;; nop no operation
 ;; ghost   an instruction that produces no real code
 ;; bitmanipbit manipulation instructions
+;; rotate   rotation instructions
+;; atomic   atomic instructions
 ;; Classification of RVV instructions which will be added to each RVV .md 
pattern and used by scheduler.
 ;; rdvlenb vector byte length vlenb csrr read
 ;; rdvlvector length vl csrr read
-- 
2.38.1



[PATCH v2] RISC-V: Add support for AIA ISA extensions (Ssaia and Smaia)

2022-11-27 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the two AIA ISA extensions Ssaia and Smaia.
They are not relelvant for the compiler, but the assembler might want
to validate the CSRs. Therefore, all this patch does is recognize the
extension name, emit a feature macro (incl. a test).

Changes for v2:
- Imply "ssaia" with "smaia"
- Adding comment to invoke.texi as requested by Palmer

Signed-off-by: Christoph Müllner 
---
 gcc/common/config/riscv/riscv-common.cc |  4 
 gcc/doc/invoke.texi |  4 
 gcc/testsuite/gcc.target/riscv/smaia.c  | 18 ++
 gcc/testsuite/gcc.target/riscv/ssaia.c  | 13 +
 4 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/smaia.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/ssaia.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 4b7f777c103..a1e7d9c3787 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -108,6 +108,8 @@ static const riscv_implied_info_t riscv_implied_info[] =
   {"zhinx", "zhinxmin"},
   {"zhinxmin", "zfinx"},
 
+  {"smaia", "ssaia"},
+
   {NULL, NULL}
 };
 
@@ -219,6 +221,8 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
 
   {"zmmul", ISA_SPEC_CLASS_NONE, 1, 0},
 
+  {"smaia", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"ssaia", ISA_SPEC_CLASS_NONE, 1, 0},
   {"svinval", ISA_SPEC_CLASS_NONE, 1, 0},
   {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0},
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 202388b3fb8..a24c6fe2499 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -28662,6 +28662,10 @@ If both @option{-march} and @option{-mcpu=} are not 
specified, the default for
 this argument is system dependent, users who want a specific architecture
 extensions should specify one explicitly.
 
+Note, that AIA support (@samp{Smaia} and @samp{Ssaia}) is based on an AIA
+specification, which is frozen but contains draft chapters ("Duo-PLIC" and
+"IOMMU Support").
+
 @item -mcpu=@var{processor-string}
 @opindex mcpu
 Use architecture of and optimize the output for the given processor, specified
diff --git a/gcc/testsuite/gcc.target/riscv/smaia.c 
b/gcc/testsuite/gcc.target/riscv/smaia.c
new file mode 100644
index 000..497b4133c22
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/smaia.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_smaia" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_smaia" { target { rv32 } } } */
+
+#ifndef __riscv_smaia
+#error Feature macro not defined
+#endif
+
+// Smaia implies Ssaia
+#ifndef __riscv_ssaia
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/ssaia.c 
b/gcc/testsuite/gcc.target/riscv/ssaia.c
new file mode 100644
index 000..b20e0eb10f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/ssaia.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_ssaia" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_ssaia" { target { rv32 } } } */
+
+#ifndef __riscv_ssaia
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
-- 
2.38.1



[PATCH] RISC-V: Add support for AIA ISA extensions (Ssaia and Smaia)

2022-11-17 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the two AIA ISA extensions Ssaia and Smaia.
They are not relelvant for the compiler, but the assembler might want
to validate the CSRs. Therefore, all this patch does is recognize the
extension name, emit a feature macro (incl. a test).

Signed-off-by: Christoph Müllner 
---
 gcc/common/config/riscv/riscv-common.cc |  2 ++
 gcc/testsuite/gcc.target/riscv/smaia.c  | 13 +
 gcc/testsuite/gcc.target/riscv/ssaia.c  | 13 +
 3 files changed, 28 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/smaia.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/ssaia.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 4b7f777c103..674eded07b7 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -219,6 +219,8 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
 
   {"zmmul", ISA_SPEC_CLASS_NONE, 1, 0},
 
+  {"smaia", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"ssaia", ISA_SPEC_CLASS_NONE, 1, 0},
   {"svinval", ISA_SPEC_CLASS_NONE, 1, 0},
   {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0},
 
diff --git a/gcc/testsuite/gcc.target/riscv/smaia.c 
b/gcc/testsuite/gcc.target/riscv/smaia.c
new file mode 100644
index 000..9ca80236245
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/smaia.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_smaia" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_smaia" { target { rv32 } } } */
+
+#ifndef __riscv_smaia
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/ssaia.c 
b/gcc/testsuite/gcc.target/riscv/ssaia.c
new file mode 100644
index 000..b20e0eb10f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/ssaia.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_ssaia" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_ssaia" { target { rv32 } } } */
+
+#ifndef __riscv_ssaia
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
-- 
2.38.1



[PATCH] doc: invoke: pru/riscv: Fix option list formatting

2022-11-15 Thread Christoph Muellner
From: Christoph Müllner 

This patch fixes a wrong placed closing bracket in the RISC-V option
list and an unneeded @gol in the PRU option list in invoke.texi.

gcc/ChangeLog:

* doc/invoke.texi: Fix PRU/RISC-V option list formatting.

Signed-off-by: Christoph Müllner 
---
 gcc/doc/invoke.texi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 057439a004c..cbfe1102bd2 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1197,7 +1197,7 @@ See RS/6000 and PowerPC Options.
 
 @emph{PRU Options}
 @gccoptlist{-mmcu=@var{mcu}  -minrt  -mno-relax  -mloop @gol
--mabi=@var{variant} @gol}
+-mabi=@var{variant}}
 
 @emph{RISC-V Options}
 @gccoptlist{-mbranch-cost=@var{N-instruction} @gol
@@ -1220,8 +1220,8 @@ See RS/6000 and PowerPC Options.
 -malign-data=@var{type} @gol
 -mbig-endian  -mlittle-endian @gol
 -mstack-protector-guard=@var{guard}  -mstack-protector-guard-reg=@var{reg} @gol
--mstack-protector-guard-offset=@var{offset}}
--mcsr-check -mno-csr-check @gol
+-mstack-protector-guard-offset=@var{offset} @gol
+-mcsr-check -mno-csr-check}
 
 @emph{RL78 Options}
 @gccoptlist{-msim  -mmul=none  -mmul=g13  -mmul=g14  -mallregs @gol
-- 
2.38.1



[PATCH] doc: invoke: riscv: Fix closing block bracket

2022-11-15 Thread Christoph Muellner
From: Christoph Müllner 

This patch fixes a wrong placed closing bracket in the RISC-V section of
invoke.texi.

gcc/ChangeLog:

* doc/invoke.texi: Fix closing block bracket

Signed-off-by: Christoph Müllner 
---
 gcc/doc/invoke.texi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 057439a004c..dfac7c85844 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1220,8 +1220,8 @@ See RS/6000 and PowerPC Options.
 -malign-data=@var{type} @gol
 -mbig-endian  -mlittle-endian @gol
 -mstack-protector-guard=@var{guard}  -mstack-protector-guard-reg=@var{reg} @gol
--mstack-protector-guard-offset=@var{offset}}
--mcsr-check -mno-csr-check @gol
+-mstack-protector-guard-offset=@var{offset} @gol
+-mcsr-check -mno-csr-check @gol}
 
 @emph{RL78 Options}
 @gccoptlist{-msim  -mmul=none  -mmul=g13  -mmul=g14  -mallregs @gol
-- 
2.38.1



[PATCH 7/7] riscv: Add support for str(n)cmp inline expansion

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

This patch implements expansions for the cmpstrsi and the cmpstrnsi
builtins using Zbb instructions (if available).
This allows to inline calls to strcmp() and strncmp().

The expansion basically emits a peeled comparison sequence (i.e. a peeled
comparison loop) which compares XLEN bits per step if possible.

The emitted sequence can be controlled, by setting the maximum number
of compared bytes (-mstring-compare-inline-limit).

gcc/ChangeLog:

* config/riscv/riscv-protos.h (riscv_expand_strn_compare): New
  prototype.
* config/riscv/riscv-string.cc (GEN_EMIT_HELPER3): New helper
  macros.
(GEN_EMIT_HELPER2): New helper macros.
(expand_strncmp_zbb_sequence): New function.
(riscv_emit_str_compare_zbb): New function.
(riscv_expand_strn_compare): New function.
* config/riscv/riscv.md (cmpstrnsi): Invoke expansion functions
  for strn_compare.
(cmpstrsi): Invoke expansion functions for strn_compare.
* config/riscv/riscv.opt: Add new parameter
  '-mstring-compare-inline-limit'.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv-protos.h   |   1 +
 gcc/config/riscv/riscv-string.cc  | 344 ++
 gcc/config/riscv/riscv.md |  46 +++
 gcc/config/riscv/riscv.opt|   5 +
 .../gcc.target/riscv/zbb-strcmp-unaligned.c   |  36 ++
 gcc/testsuite/gcc.target/riscv/zbb-strcmp.c   |  55 +++
 6 files changed, 487 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp-unaligned.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp.c

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 18187e3bd78..7f334be333c 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -97,6 +97,7 @@ rtl_opt_pass * make_pass_shorten_memrefs (gcc::context *ctxt);
 /* Routines implemented in riscv-string.c.  */
 extern bool riscv_expand_block_move (rtx, rtx, rtx);
 extern bool riscv_expand_strlen (rtx[]);
+extern bool riscv_expand_strn_compare (rtx[], int);
 
 /* Information about one CPU we know about.  */
 struct riscv_cpu_info {
diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc
index bf96522b608..f157e04ac0c 100644
--- a/gcc/config/riscv/riscv-string.cc
+++ b/gcc/config/riscv/riscv-string.cc
@@ -84,6 +84,11 @@ GEN_EMIT_HELPER2(one_cmpl) /* do_one_cmpl2  */
 GEN_EMIT_HELPER2(clz) /* do_clz2  */
 GEN_EMIT_HELPER2(ctz) /* do_ctz2  */
 GEN_EMIT_HELPER2(zero_extendqi) /* do_zero_extendqi2  */
+GEN_EMIT_HELPER3(xor) /* do_xor3  */
+GEN_EMIT_HELPER3(ashl) /* do_ashl3  */
+GEN_EMIT_HELPER2(bswap) /* do_bswap2  */
+GEN_EMIT_HELPER3(riscv_ior_not) /* do_riscv_ior_not3  */
+GEN_EMIT_HELPER3(riscv_and_not) /* do_riscv_and_not3  */
 
 /* Helper function to load a byte or a Pmode register.
 
@@ -268,6 +273,345 @@ riscv_expand_block_move (rtx dest, rtx src, rtx length)
   return false;
 }
 
+/* Generate the sequence of compares for strcmp/strncmp using zbb instructions.
+   BYTES_TO_COMPARE is the number of bytes to be compared.
+   BASE_ALIGN is the smaller of the alignment of the two strings.
+   ORIG_SRC1 is the unmodified rtx for the first string.
+   ORIG_SRC2 is the unmodified rtx for the second string.
+   DATA1 is the register for loading the first string.
+   DATA2 is the register for loading the second string.
+   HAS_NUL is the register holding non-NUL bytes for NUL-bytes in the string.
+   TARGET is the rtx for the result register (SImode)
+   EQUALITY_COMPARE_REST if set, then we hand over to libc if string matches.
+   END_LABEL is the location before the calculation of the result value.
+   FINAL_LABEL is the location after the calculation of the result value.  */
+
+static void
+expand_strncmp_zbb_sequence (unsigned HOST_WIDE_INT bytes_to_compare,
+rtx src1, rtx src2, rtx data1, rtx data2,
+rtx target, rtx orc, bool equality_compare_rest,
+rtx end_label, rtx final_label)
+{
+  const unsigned HOST_WIDE_INT p_mode_size = GET_MODE_SIZE (Pmode);
+  rtx src1_addr = force_reg (Pmode, XEXP (src1, 0));
+  rtx src2_addr = force_reg (Pmode, XEXP (src2, 0));
+  unsigned HOST_WIDE_INT offset = 0;
+
+  rtx m1 = gen_reg_rtx (Pmode);
+  emit_insn (gen_rtx_SET (m1, constm1_rtx));
+
+  /* Generate a compare sequence.  */
+  while (bytes_to_compare > 0)
+{
+  machine_mode load_mode = QImode;
+  unsigned HOST_WIDE_INT load_mode_size = 1;
+  if (bytes_to_compare > 1)
+   {
+ load_mode = Pmode;
+ load_mode_size = p_mode_size;
+   }
+  unsigned HOST_WIDE_INT cmp_bytes = 0;
+
+  if (bytes_to_compare >= load_mode_size)
+   cmp_bytes = load_mode_size;
+  else
+   cmp_bytes = bytes_to_compare;
+
+  unsigned HOST_WIDE_INT remain = bytes_to_compare - cmp_bytes;
+
+  /* 

[PATCH 6/7] riscv: Add support for strlen inline expansion

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

This patch implements the expansion of the strlen builtin
using Zbb instructions (if available) for aligned strings
using the following sequence:

  li  a3,-1
  addia4,a0,8
.L2:  ld  a5,0(a0)
  addia0,a0,8
  orc.b   a5,a5
  beq a5,a3,6 <.L2>
  not a5,a5
  ctz a5,a5
  srlia5,a5,0x3
  add a0,a0,a5
  sub a0,a0,a4

This allows to inline calls to strlen(), with optimized code for
determining the length of a string.

gcc/ChangeLog:

* config/riscv/riscv-protos.h (riscv_expand_strlen): New
  prototype.
* config/riscv/riscv-string.cc (riscv_emit_unlikely_jump): New
  function.
(GEN_EMIT_HELPER2): New helper macro.
(GEN_EMIT_HELPER3): New helper macro.
(do_load_from_addr): New helper function.
(riscv_expand_strlen_zbb): New function.
(riscv_expand_strlen): New function.
* config/riscv/riscv.md (strlen): Invoke expansion
  functions for strlen.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv-protos.h   |   1 +
 gcc/config/riscv/riscv-string.cc  | 149 ++
 gcc/config/riscv/riscv.md |  28 
 .../gcc.target/riscv/zbb-strlen-unaligned.c   |  13 ++
 gcc/testsuite/gcc.target/riscv/zbb-strlen.c   |  18 +++
 5 files changed, 209 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen-unaligned.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen.c

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 344515dbaf4..18187e3bd78 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -96,6 +96,7 @@ rtl_opt_pass * make_pass_shorten_memrefs (gcc::context *ctxt);
 
 /* Routines implemented in riscv-string.c.  */
 extern bool riscv_expand_block_move (rtx, rtx, rtx);
+extern bool riscv_expand_strlen (rtx[]);
 
 /* Information about one CPU we know about.  */
 struct riscv_cpu_info {
diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc
index 1137df475be..bf96522b608 100644
--- a/gcc/config/riscv/riscv-string.cc
+++ b/gcc/config/riscv/riscv-string.cc
@@ -38,6 +38,81 @@
 #include "predict.h"
 #include "optabs.h"
 
+/* Emit unlikely jump instruction.  */
+
+static rtx_insn *
+riscv_emit_unlikely_jump (rtx insn)
+{
+  rtx_insn *jump = emit_jump_insn (insn);
+  add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
+  return jump;
+}
+
+/* Emit proper instruction depending on type of dest.  */
+
+#define GEN_EMIT_HELPER2(name) \
+static rtx_insn *  \
+do_## name ## 2(rtx dest, rtx src) \
+{  \
+  rtx_insn *insn;  \
+  if (GET_MODE (dest) == DImode)   \
+insn = emit_insn (gen_ ## name ## di2 (dest, src));\
+  else \
+insn = emit_insn (gen_ ## name ## si2 (dest, src));\
+  return insn; \
+}
+
+/* Emit proper instruction depending on type of dest.  */
+
+#define GEN_EMIT_HELPER3(name) \
+static rtx_insn *  \
+do_## name ## 3(rtx dest, rtx src1, rtx src2)  \
+{  \
+  rtx_insn *insn;  \
+  if (GET_MODE (dest) == DImode)   \
+insn = emit_insn (gen_ ## name ## di3 (dest, src1, src2)); \
+  else \
+insn = emit_insn (gen_ ## name ## si3 (dest, src1, src2)); \
+  return insn; \
+}
+
+GEN_EMIT_HELPER3(add) /* do_add3  */
+GEN_EMIT_HELPER3(sub) /* do_sub3  */
+GEN_EMIT_HELPER3(lshr) /* do_lshr3  */
+GEN_EMIT_HELPER2(orcb) /* do_orcb2  */
+GEN_EMIT_HELPER2(one_cmpl) /* do_one_cmpl2  */
+GEN_EMIT_HELPER2(clz) /* do_clz2  */
+GEN_EMIT_HELPER2(ctz) /* do_ctz2  */
+GEN_EMIT_HELPER2(zero_extendqi) /* do_zero_extendqi2  */
+
+/* Helper function to load a byte or a Pmode register.
+
+   MODE is the mode to use for the load (QImode or Pmode).
+   DEST is the destination register for the data.
+   ADDR_REG is the register that holds the address.
+   ADDR is the address expression to load from.
+
+   This function returns an rtx containing the register,
+   where the ADDR is stored.  */
+
+static rtx
+do_load_from_addr (machine_mode mode, rtx dest, rtx addr_reg, rtx addr)
+{
+  rtx mem = gen_rtx_MEM (mode, addr_reg);
+  MEM_COPY_ATTRIBUTES (mem, addr);
+  set_mem_size (mem, GET_MODE_SIZE (mode));
+
+  if (mode == QImode)
+do_zero_extendqi2 (dest, mem);
+  else if (mode == Pmode)
+emit_move_insn (dest, mem);
+  else
+

[PATCH 4/7] riscv: Move riscv_block_move_loop to separate file

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

Let's try to not accumulate too much functionality in one single file
as this does not really help maintaining or extending the code.
So in order to add more similar functionality like riscv_block_move_loop
let's move this function to a separate file.

This change does not do any functional changes.
It does modify a single line in the existing code,
that check_GNU_style.py complained about.

gcc/ChangeLog:

* config.gcc: Add new object riscv-string.o
* config/riscv/riscv-protos.h (riscv_expand_block_move): Remove
  duplicated prototype and move to new section for
  riscv-string.cc.
* config/riscv/riscv.cc (riscv_block_move_straight): Remove function.
(riscv_adjust_block_mem): Likewise.
(riscv_block_move_loop): Likewise.
(riscv_expand_block_move): Likewise.
* config/riscv/riscv.md (cpymemsi): Move to new section for
  riscv-string.cc.
* config/riscv/t-riscv: Add compile rule for riscv-string.o
* config/riscv/riscv-string.c: New file.

Signed-off-by: Christoph Müllner 
---
 gcc/config.gcc   |   3 +-
 gcc/config/riscv/riscv-protos.h  |   5 +-
 gcc/config/riscv/riscv-string.cc | 194 +++
 gcc/config/riscv/riscv.cc| 155 
 gcc/config/riscv/riscv.md|  28 ++---
 gcc/config/riscv/t-riscv |   4 +
 6 files changed, 218 insertions(+), 171 deletions(-)
 create mode 100644 gcc/config/riscv/riscv-string.cc

diff --git a/gcc/config.gcc b/gcc/config.gcc
index b5eda046033..fc9e582e713 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -518,7 +518,8 @@ pru-*-*)
;;
 riscv*)
cpu_type=riscv
-   extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o 
riscv-shorten-memrefs.o riscv-selftests.o riscv-v.o"
+   extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o 
riscv-shorten-memrefs.o riscv-selftests.o"
+   extra_objs="${extra_objs} riscv-string.o riscv-v.o"
extra_objs="${extra_objs} riscv-vector-builtins.o 
riscv-vector-builtins-shapes.o riscv-vector-builtins-bases.o"
d_target_objs="riscv-d.o"
extra_headers="riscv_vector.h"
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 5a718bb62b4..344515dbaf4 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -62,7 +62,6 @@ extern void riscv_expand_conditional_move (rtx, rtx, rtx, 
rtx_code, rtx, rtx);
 #endif
 extern rtx riscv_legitimize_call_address (rtx);
 extern void riscv_set_return_address (rtx, rtx);
-extern bool riscv_expand_block_move (rtx, rtx, rtx);
 extern rtx riscv_return_addr (int, rtx);
 extern poly_int64 riscv_initial_elimination_offset (int, int);
 extern void riscv_expand_prologue (void);
@@ -70,7 +69,6 @@ extern void riscv_expand_epilogue (int);
 extern bool riscv_epilogue_uses (unsigned int);
 extern bool riscv_can_use_return_insn (void);
 extern rtx riscv_function_value (const_tree, const_tree, enum machine_mode);
-extern bool riscv_expand_block_move (rtx, rtx, rtx);
 extern bool riscv_store_data_bypass_p (rtx_insn *, rtx_insn *);
 extern rtx riscv_gen_gpr_save_insn (struct riscv_frame_info *);
 extern bool riscv_gpr_save_operation_p (rtx);
@@ -96,6 +94,9 @@ extern bool riscv_hard_regno_rename_ok (unsigned, unsigned);
 
 rtl_opt_pass * make_pass_shorten_memrefs (gcc::context *ctxt);
 
+/* Routines implemented in riscv-string.c.  */
+extern bool riscv_expand_block_move (rtx, rtx, rtx);
+
 /* Information about one CPU we know about.  */
 struct riscv_cpu_info {
   /* This CPU's canonical name.  */
diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc
new file mode 100644
index 000..6882f0be269
--- /dev/null
+++ b/gcc/config/riscv/riscv-string.cc
@@ -0,0 +1,194 @@
+/* Subroutines used to expand string and block move, clear,
+   compare and other operations for RISC-V.
+   Copyright (C) 2011-2022 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
+   .  */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "rtl.h"
+#include "tree.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "ira.h"
+#include "print-tree.h"
+#include "varasm.h"
+#include "explow.h"
+#include "expr.h"
+#include "output.h"
+#include 

[PATCH 2/7] riscv: bitmanip/zbb: Add prefix/postfix and enable visiblity

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

INSNs are usually postfixed by a number representing the argument count.
Given the instructions will be used in a later commit, let's make them
visible, but add a "riscv_" prefix to avoid conflicts with standard
INSNs.

gcc/ChangeLog:

* config/riscv/bitmanip.md (*_not): Rename INSN.
(riscv__not3): Rename INSN.
(*xor_not): Rename INSN.
(xor_not3): Rename INSN.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/bitmanip.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 3dbe6002974..d6d94e5cdf8 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -119,7 +119,7 @@ (define_insn "*slliuw"
 
 ;; ZBB extension.
 
-(define_insn "*_not"
+(define_insn "riscv__not3"
   [(set (match_operand:X 0 "register_operand" "=r")
 (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
 (match_operand:X 2 "register_operand" "r")))]
@@ -128,7 +128,7 @@ (define_insn "*_not"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
 
-(define_insn "*xor_not"
+(define_insn "riscv_xor_not3"
   [(set (match_operand:X 0 "register_operand" "=r")
 (not:X (xor:X (match_operand:X 1 "register_operand" "r")
   (match_operand:X 2 "register_operand" "r"]
-- 
2.38.1



[PATCH 1/7] riscv: bitmanip: add orc.b as an unspec

2022-11-13 Thread Christoph Muellner
From: Philipp Tomsich 

As a basis for optimized string functions (e.g., the by-pieces
implementations), we need orc.b available.  This adds orc.b as an
unspec, so we can expand to it.

gcc/ChangeLog:

* config/riscv/bitmanip.md (orcb2): Add orc.b as an
  unspec.
* config/riscv/riscv.md: Add UNSPEC_ORC_B.

Signed-off-by: Philipp Tomsich 
---
 gcc/config/riscv/bitmanip.md | 8 
 gcc/config/riscv/riscv.md| 3 +++
 2 files changed, 11 insertions(+)

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index b44fb9517e7..3dbe6002974 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -242,6 +242,14 @@ (define_insn "rotlsi3_sext"
   "rolw\t%0,%1,%2"
   [(set_attr "type" "bitmanip")])
 
+;; orc.b (or-combine) is added as an unspec for the benefit of the support
+;; for optimized string functions (such as strcmp).
+(define_insn "orcb2"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (unspec:X [(match_operand:X 1 "register_operand" "r")] UNSPEC_ORC_B))]
+  "TARGET_ZBB"
+  "orc.b\t%0,%1")
+
 (define_insn "bswap2"
   [(set (match_operand:X 0 "register_operand" "=r")
 (bswap:X (match_operand:X 1 "register_operand" "r")))]
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 798f7370a08..532289dd178 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -62,6 +62,9 @@ (define_c_enum "unspec" [
 
   ;; Stack tie
   UNSPEC_TIE
+
+  ;; OR-COMBINE
+  UNSPEC_ORC_B
 ])
 
 (define_c_enum "unspecv" [
-- 
2.38.1



[PATCH 0/7] riscv: Improve builtins expansion

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

This patchset adds includes patches to improve the following builtin
expansions:

* cpymemsi: Allow by-pieces to generate overlapping memory accesses
* cmpstrsi: Add expansion for strcmp and strncmp for aligned strings when 
zbb/orc.b is available
* strlen: Add expansion for strlen when zbb/orc.b is available

This changes were inspired a lot by the PowerPC backend
(e.g. moving the expansion code into riscv-string.cc and emitting an
unrolled loop which eventually calls the C runtime if necessary).

This series is meant to be applied on top of the VT1 support series:
  https://gcc.gnu.org/pipermail/gcc-patches/2022-November/605959.html

The patches come with their own tests and show no regressions to
existing tests. Further the series has been tested with all SPEC CPU2017
benchmarks.

Christoph Müllner (6):
  riscv: bitmanip/zbb: Add prefix/postfix and enable visiblity
  riscv: Enable overlap-by-pieces via tune param
  riscv: Move riscv_block_move_loop to separate file
  riscv: Use by-pieces to do overlapping accesses in block_move_straight
  riscv: Add support for strlen inline expansion
  riscv: Add support for str(n)cmp inline expansion

Philipp Tomsich (1):
  riscv: bitmanip: add orc.b as an unspec

 gcc/config.gcc|   3 +-
 gcc/config/riscv/bitmanip.md  |  12 +-
 gcc/config/riscv/riscv-protos.h   |   7 +-
 gcc/config/riscv/riscv-string.cc  | 687 ++
 gcc/config/riscv/riscv.cc | 172 +
 gcc/config/riscv/riscv.md | 105 ++-
 gcc/config/riscv/riscv.opt|   5 +
 gcc/config/riscv/t-riscv  |   4 +
 .../gcc.target/riscv/memcpy-nonoverlapping.c  |  54 ++
 .../gcc.target/riscv/memcpy-overlapping.c |  47 ++
 .../gcc.target/riscv/memset-nonoverlapping.c  |  45 ++
 .../gcc.target/riscv/memset-overlapping.c |  43 ++
 .../gcc.target/riscv/zbb-strcmp-unaligned.c   |  36 +
 gcc/testsuite/gcc.target/riscv/zbb-strcmp.c   |  55 ++
 .../gcc.target/riscv/zbb-strlen-unaligned.c   |  13 +
 gcc/testsuite/gcc.target/riscv/zbb-strlen.c   |  18 +
 16 files changed, 1132 insertions(+), 174 deletions(-)
 create mode 100644 gcc/config/riscv/riscv-string.cc
 create mode 100644 gcc/testsuite/gcc.target/riscv/memcpy-nonoverlapping.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/memcpy-overlapping.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/memset-nonoverlapping.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/memset-overlapping.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp-unaligned.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strcmp.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen-unaligned.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-strlen.c

-- 
2.38.1



[PATCH 5/7] riscv: Use by-pieces to do overlapping accesses in block_move_straight

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

The current implementation of riscv_block_move_straight() emits a couple
of load-store pairs with maximum width (e.g. 8-byte for RV64).
The remainder is handed over to move_by_pieces(), which emits code based
target settings like slow_unaligned_access and overlap_op_by_pieces.

move_by_pieces() will emit overlapping memory accesses with maximum
width only if the given length exceeds the size of one access
(e.g. 15-bytes for 8-byte accesses).

This patch changes the implementation of riscv_block_move_straight()
such, that it preserves a remainder within the interval
[delta..2*delta) instead of [0..delta), so that overlapping memory
access may be emitted (if the requirements for them are given).

gcc/ChangeLog:

* config/riscv/riscv-string.c (riscv_block_move_straight):
  Adjust range for emitted load/store pairs.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv-string.cc  |  8 
 .../gcc.target/riscv/memcpy-overlapping.c | 19 ---
 2 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc
index 6882f0be269..1137df475be 100644
--- a/gcc/config/riscv/riscv-string.cc
+++ b/gcc/config/riscv/riscv-string.cc
@@ -57,18 +57,18 @@ riscv_block_move_straight (rtx dest, rtx src, unsigned 
HOST_WIDE_INT length)
   delta = bits / BITS_PER_UNIT;
 
   /* Allocate a buffer for the temporary registers.  */
-  regs = XALLOCAVEC (rtx, length / delta);
+  regs = XALLOCAVEC (rtx, length / delta - 1);
 
   /* Load as many BITS-sized chunks as possible.  Use a normal load if
  the source has enough alignment, otherwise use left/right pairs.  */
-  for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
+  for (offset = 0, i = 0; offset + 2 * delta <= length; offset += delta, i++)
 {
   regs[i] = gen_reg_rtx (mode);
   riscv_emit_move (regs[i], adjust_address (src, mode, offset));
 }
 
   /* Copy the chunks to the destination.  */
-  for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
+  for (offset = 0, i = 0; offset + 2 * delta <= length; offset += delta, i++)
 riscv_emit_move (adjust_address (dest, mode, offset), regs[i]);
 
   /* Mop up any left-over bytes.  */
@@ -166,7 +166,7 @@ riscv_expand_block_move (rtx dest, rtx src, rtx length)
 
   if (hwi_length <= (RISCV_MAX_MOVE_BYTES_STRAIGHT / factor))
{
- riscv_block_move_straight (dest, src, INTVAL (length));
+ riscv_block_move_straight (dest, src, hwi_length);
  return true;
}
   else if (optimize && align >= BITS_PER_WORD)
diff --git a/gcc/testsuite/gcc.target/riscv/memcpy-overlapping.c 
b/gcc/testsuite/gcc.target/riscv/memcpy-overlapping.c
index ffb7248bfd1..ef95bfb879b 100644
--- a/gcc/testsuite/gcc.target/riscv/memcpy-overlapping.c
+++ b/gcc/testsuite/gcc.target/riscv/memcpy-overlapping.c
@@ -25,26 +25,23 @@ COPY_N(15)
 /* Emits 2x {ld,sd} and 1x {lw,sw}.  */
 COPY_N(19)
 
-/* Emits 3x ld and 3x sd.  */
+/* Emits 3x {ld,sd}.  */
 COPY_N(23)
 
 /* The by-pieces infrastructure handles up to 24 bytes.
So the code below is emitted via cpymemsi/block_move_straight.  */
 
-/* Emits 3x {ld,sd} and 1x {lhu,lbu,sh,sb}.  */
+/* Emits 3x {ld,sd} and 1x {lw,sw}.  */
 COPY_N(27)
 
-/* Emits 3x {ld,sd} and 1x {lw,lbu,sw,sb}.  */
+/* Emits 4x {ld,sd}.  */
 COPY_N(29)
 
-/* Emits 3x {ld,sd} and 2x {lw,sw}.  */
+/* Emits 4x {ld,sd}.  */
 COPY_N(31)
 
-/* { dg-final { scan-assembler-times "ld\t" 21 } } */
-/* { dg-final { scan-assembler-times "sd\t" 21 } } */
+/* { dg-final { scan-assembler-times "ld\t" 23 } } */
+/* { dg-final { scan-assembler-times "sd\t" 23 } } */
 
-/* { dg-final { scan-assembler-times "lw\t" 5 } } */
-/* { dg-final { scan-assembler-times "sw\t" 5 } } */
-
-/* { dg-final { scan-assembler-times "lbu\t" 2 } } */
-/* { dg-final { scan-assembler-times "sb\t" 2 } } */
+/* { dg-final { scan-assembler-times "lw\t" 3 } } */
+/* { dg-final { scan-assembler-times "sw\t" 3 } } */
-- 
2.38.1



[PATCH 3/7] riscv: Enable overlap-by-pieces via tune param

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds the field overlap_op_by_pieces to the struct
riscv_tune_param, which allows to enable the overlap_op_by_pieces
infrastructure.

gcc/ChangeLog:

* config/riscv/riscv.c (struct riscv_tune_param): New field.
(riscv_overlap_op_by_pieces): New function.
(TARGET_OVERLAP_OP_BY_PIECES_P): Connect to
riscv_overlap_op_by_pieces.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.cc | 17 +-
 .../gcc.target/riscv/memcpy-nonoverlapping.c  | 54 +++
 .../gcc.target/riscv/memcpy-overlapping.c | 50 +
 .../gcc.target/riscv/memset-nonoverlapping.c  | 45 
 .../gcc.target/riscv/memset-overlapping.c | 43 +++
 5 files changed, 208 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/memcpy-nonoverlapping.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/memcpy-overlapping.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/memset-nonoverlapping.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/memset-overlapping.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a0c00cfb66f..7357cf51cdf 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -243,6 +243,7 @@ struct riscv_tune_param
   unsigned short fmv_cost;
   bool slow_unaligned_access;
   unsigned int fusible_ops;
+  bool overlap_op_by_pieces;
 };
 
 /* Information about one micro-arch we know about.  */
@@ -331,6 +332,7 @@ static const struct riscv_tune_param rocket_tune_info = {
   8,   /* fmv_cost */
   true,/* 
slow_unaligned_access */
   RISCV_FUSE_NOTHING,   /* fusible_ops */
+  false,   /* overlap_op_by_pieces */
 };
 
 /* Costs to use when optimizing for Sifive 7 Series.  */
@@ -346,6 +348,7 @@ static const struct riscv_tune_param sifive_7_tune_info = {
   8,   /* fmv_cost */
   true,/* 
slow_unaligned_access */
   RISCV_FUSE_NOTHING,   /* fusible_ops */
+  false,   /* overlap_op_by_pieces */
 };
 
 /* Costs to use when optimizing for T-HEAD c906.  */
@@ -361,6 +364,7 @@ static const struct riscv_tune_param thead_c906_tune_info = 
{
   8,   /* fmv_cost */
   false,/* slow_unaligned_access */
   RISCV_FUSE_NOTHING,   /* fusible_ops */
+  false,   /* overlap_op_by_pieces */
 };
 
 /* Costs to use when optimizing for size.  */
@@ -376,6 +380,7 @@ static const struct riscv_tune_param 
optimize_size_tune_info = {
   8,   /* fmv_cost */
   false,   /* slow_unaligned_access */
   RISCV_FUSE_NOTHING,   /* fusible_ops */
+  false,   /* overlap_op_by_pieces */
 };
 
 /* Costs to use when optimizing for Ventana Micro VT1.  */
@@ -393,7 +398,8 @@ static const struct riscv_tune_param ventana_vt1_tune_info 
= {
   ( RISCV_FUSE_ZEXTW | RISCV_FUSE_ZEXTH |   /* fusible_ops */
 RISCV_FUSE_ZEXTWS | RISCV_FUSE_LDINDEXED |
 RISCV_FUSE_LUI_ADDI | RISCV_FUSE_AUIPC_ADDI |
-RISCV_FUSE_LUI_LD | RISCV_FUSE_AUIPC_LD )
+RISCV_FUSE_LUI_LD | RISCV_FUSE_AUIPC_LD ),
+  true,/* overlap_op_by_pieces 
*/
 };
 
 static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
@@ -6444,6 +6450,12 @@ riscv_slow_unaligned_access (machine_mode, unsigned int)
   return riscv_slow_unaligned_access_p;
 }
 
+static bool
+riscv_overlap_op_by_pieces (void)
+{
+  return tune_param->overlap_op_by_pieces;
+}
+
 /* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */
 
 static bool
@@ -6974,6 +6986,9 @@ riscv_dwarf_poly_indeterminate_value (unsigned int i, 
unsigned int *factor,
 #undef TARGET_SLOW_UNALIGNED_ACCESS
 #define TARGET_SLOW_UNALIGNED_ACCESS riscv_slow_unaligned_access
 
+#undef TARGET_OVERLAP_OP_BY_PIECES_P
+#define TARGET_OVERLAP_OP_BY_PIECES_P riscv_overlap_op_by_pieces
+
 #undef TARGET_SECONDARY_MEMORY_NEEDED
 #define TARGET_SECONDARY_MEMORY_NEEDED riscv_secondary_memory_needed
 
diff --git a/gcc/testsuite/gcc.target/riscv/memcpy-nonoverlapping.c 
b/gcc/testsuite/gcc.target/riscv/memcpy-nonoverlapping.c
new file mode 100644
index 000..1c99e13fc26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/memcpy-nonoverlapping.c
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=sifive-u74 -march=rv64gc -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Oz" "-Og" } } */
+
+
+#define COPY_N(N)  \
+void copy##N (char *src, char *dst)\
+{  \
+  dst = __builtin_assume_aligned 

[RFC PATCH] riscv: thead: Add support for XTheadMemPair ISA extension

2022-11-13 Thread Christoph Muellner
From: "moiz.hussain" 

The XTheadMacXTheadMemPair ISA extension provides load/store
pair instructions:
* th.ldd
* th.sdd
* th.lwd
* th.lwud
* th.swd

We added the following unnamed patterns to the
peephole.md stage:
* load/store pair patterns for 4 instructions
* load/store pair patterns for 2 instructions

It was also required to add define_insn patterns to thead.md:
* th_mov_mempair_
* th_mov_mempair_di_si_zero_ext
* th_mov_mempair_di_si_sign_ext
* th_mov_mempair_si_si_zero_ext
* th_mov_mempair_si_si_sign_ext

Much of the code has been inspired by the MIPS and the aarch64 backend.
Also the new test cases were inspired by other architectures.

The patch is meant to apply on top of the XThead* series
that has been posted here:
  https://gcc.gnu.org/pipermail/gcc-patches/2022-November/605980.html

This patch is in RFC mode as we still need to sort out some failing
tests. However, we'd like to get some feedback from the RISC-V
maintainers on the approach that we have taken. Especially since the
patch is already quite big.

Signed-off-by: M. Moiz Hussain 
---
 gcc/common/config/riscv/riscv-common.cc   |   2 +
 gcc/config/riscv/peephole.md  | 336 +
 gcc/config/riscv/riscv-opts.h |   4 +-
 gcc/config/riscv/riscv-protos.h   |   9 +
 gcc/config/riscv/riscv.cc | 701 ++
 gcc/config/riscv/thead.md |  83 +++
 .../gcc.target/riscv/xtheadmempair-1.c|  39 +
 .../gcc.target/riscv/xtheadmempair-10.c   |  35 +
 .../gcc.target/riscv/xtheadmempair-11.c   |  22 +
 .../gcc.target/riscv/xtheadmempair-12.c   |  23 +
 .../gcc.target/riscv/xtheadmempair-13.c   |  31 +
 .../gcc.target/riscv/xtheadmempair-14.c   |  36 +
 .../gcc.target/riscv/xtheadmempair-15.c   |  20 +
 .../gcc.target/riscv/xtheadmempair-16.c   |  24 +
 .../gcc.target/riscv/xtheadmempair-17.c   |  16 +
 .../gcc.target/riscv/xtheadmempair-18.c   |  67 ++
 .../gcc.target/riscv/xtheadmempair-18.h   |  59 ++
 .../gcc.target/riscv/xtheadmempair-19.c   |  86 +++
 .../gcc.target/riscv/xtheadmempair-2.c|  24 +
 .../gcc.target/riscv/xtheadmempair-20.c   |  23 +
 .../gcc.target/riscv/xtheadmempair-3.c|  35 +
 .../gcc.target/riscv/xtheadmempair-4.c|  25 +
 .../gcc.target/riscv/xtheadmempair-5.c|  23 +
 .../gcc.target/riscv/xtheadmempair-6.c|  22 +
 .../gcc.target/riscv/xtheadmempair-7.c|  22 +
 .../gcc.target/riscv/xtheadmempair-8.c|  31 +
 .../gcc.target/riscv/xtheadmempair-9.c|  36 +
 27 files changed, 1833 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-11.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-13.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-14.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-15.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-16.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-17.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-18.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-18.h
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-19.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-20.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-9.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 8e1449d3543..b541c55976b 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -230,6 +230,7 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"xtheadfmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadmac", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmempair", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadsync", ISA_SPEC_CLASS_NONE, 1, 0},
 
   /* Terminate the list.  */
@@ -1265,6 +1266,7 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"xtheadfmemidx", _options::x_riscv_xthead_subext, MASK_XTHEADFMEMIDX},
   {"xtheadmac", _options::x_riscv_xthead_subext, MASK_XTHEADMAC},
   {"xtheadmemidx",  _options::x_riscv_xthead_subext, MASK_XTHEADMEMIDX},
+  

[PATCH 6/7] riscv: thead: Add support for XTheadMac ISA extension

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadMac ISA extension provides multiply-accumulate/subtract
instructions:
* mula/mulaw/mulah
* muls/mulsw/mulsh

To benefit from middle-end passes, we expand the following named
patterns in riscv.md (as they are not T-Head-specific):
* maddhisi4
* msubhisi4

gcc/ChangeLog:

* config/riscv/riscv.md (maddhisi4): New expand.
(msubhisi4): New expand.
* config/riscv/thead.md (*th_mula): New pattern.
(*th_mulawsi): New pattern.
(*th_mulawsi2): New pattern.
(*th_maddhisi4): New pattern.
(*th_sextw_maddhisi4): New pattern.
(*th_muls): New pattern.
(*th_mulswsi): New pattern.
(*th_mulswsi2): New pattern.
(*th_msubhisi4): New pattern.
(*th_sextw_msubhisi4): New pattern.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/thead-mula-1.c: New test.
* gcc.target/riscv/thead-mula-2.c: New test.

Co-Developed-by: quxm 
Signed-off-by: quxm 
Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.md |  18 +++
 gcc/config/riscv/thead.md | 117 ++
 gcc/testsuite/gcc.target/riscv/thead-mula-1.c |  40 ++
 gcc/testsuite/gcc.target/riscv/thead-mula-2.c |  28 +
 4 files changed, 203 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/thead-mula-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/thead-mula-2.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index cfe1fd6baea..998169115f2 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3029,6 +3029,24 @@ (define_expand "extzv"
 FAIL;
 })
 
+(define_expand "maddhisi4"
+  [(set (match_operand:SI 0 "register_operand")
+   (plus:SI
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"))
+  (sign_extend:SI (match_operand:HI 2 "register_operand")))
+ (match_operand:SI 3 "register_operand")))]
+  "TARGET_XTHEADMAC"
+)
+
+(define_expand "msubhisi4"
+  [(set (match_operand:SI 0 "register_operand")
+   (minus:SI
+ (match_operand:SI 3 "register_operand")
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"))
+  (sign_extend:SI (match_operand:HI 2 "register_operand")]
+  "TARGET_XTHEADMAC"
+)
+
 (include "bitmanip.md")
 (include "sync.md")
 (include "peephole.md")
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index ad42c03c0ce..f31ba18aa84 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -133,3 +133,120 @@ (define_insn "*th_cond_gpr_mov"
th.mveqz\t%0,%z3,%1"
   [(set_attr "type" "condmove")
(set_attr "mode" "")])
+
+;; XTheadMac
+
+(define_insn "*th_mula"
+  [(set (match_operand:X 0 "register_operand" "=r")
+ (plus:X (mult:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:X 2 "register_operand" "r"))
+ (match_operand:X 3 "register_operand" "0")))]
+  "TARGET_XTHEADMAC"
+  "th.mula\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "")]
+)
+
+(define_insn "*th_mulawsi"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (sign_extend:DI
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+   (match_operand:SI 2 "register_operand" "r"))
+  (match_operand:SI 3 "register_operand" "0"]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulaw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_mulawsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+   (match_operand:SI 2 "register_operand" "r"))
+  (match_operand:SI 3 "register_operand" "0")))]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "mulaw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_maddhisi4"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 
"register_operand" " r"))
+ (sign_extend:SI (match_operand:HI 2 
"register_operand" " r")))
+(match_operand:SI 3 "register_operand" " 0")))]
+  "TARGET_XTHEADMAC"
+  "th.mulah\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_sextw_maddhisi4"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (sign_extend:DI
+ (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 
"register_operand" " r"))
+   (sign_extend:SI (match_operand:HI 2 
"register_operand" " r")))
+  (match_operand:SI 3 "register_operand" " 0"]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulah\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_muls"
+  [(set (match_operand:X 0 "register_operand" "=r")
+ 

[PATCH 7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

This patch add basic support for the XTheadFmv and XTheadInt
ISA extension. As both extensions only contain instruction,
which are not supposed to be emitted by the compiler, the support
only covers awareness of the extension name in the march string
and the definition of a feature test macro.

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc: Add xtheadfmv and
  xtheadint.
* config/riscv/riscv-opts.h (MASK_XTHEADMAC): New.
(MASK_XTHEADFMV): New.
(TARGET_XTHEADFMV): New.
(MASK_XTHEADINT): New.
(TARGET_XTHEADINT): New.
(MASK_XTHEADMEMIDX): New.
(MASK_XTHEADSYNC): New.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadfmv.c: New test.
* gcc.target/riscv/xtheadint.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/common/config/riscv/riscv-common.cc|  4 
 gcc/config/riscv/riscv-opts.h  | 10 +++---
 gcc/testsuite/gcc.target/riscv/xtheadfmv.c | 14 ++
 gcc/testsuite/gcc.target/riscv/xtheadint.c | 14 ++
 4 files changed, 39 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 8e1449d3543..b3e6732 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -228,6 +228,8 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"xtheadcmo", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadcondmov", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadfmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadfmv", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadint", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadmac", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadsync", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1263,6 +1265,8 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"xtheadcmo", _options::x_riscv_xthead_subext, MASK_XTHEADCMO},
   {"xtheadcondmov", _options::x_riscv_xthead_subext, MASK_XTHEADCONDMOV},
   {"xtheadfmemidx", _options::x_riscv_xthead_subext, MASK_XTHEADFMEMIDX},
+  {"xtheadfmv", _options::x_riscv_xthead_subext, MASK_XTHEADFMV},
+  {"xtheadint", _options::x_riscv_xthead_subext, MASK_XTHEADINT},
   {"xtheadmac", _options::x_riscv_xthead_subext, MASK_XTHEADMAC},
   {"xtheadmemidx",  _options::x_riscv_xthead_subext, MASK_XTHEADMEMIDX},
   {"xtheadsync",_options::x_riscv_xthead_subext, MASK_XTHEADSYNC},
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 18daac40dbd..c1868dcf284 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -201,11 +201,15 @@ enum stack_protector_guard {
 #define TARGET_XTHEADCONDMOV   ((riscv_xthead_subext & MASK_XTHEADCONDMOV) != 
0)
 #define MASK_XTHEADFMEMIDX (1 << 5)
 #define TARGET_XTHEADFMEMIDX   ((riscv_xthead_subext & MASK_XTHEADFMEMIDX) != 
0)
-#define MASK_XTHEADMAC (1 << 6)
+#define MASK_XTHEADFMV (1 << 6)
+#define TARGET_XTHEADFMV   ((riscv_xthead_subext & MASK_XTHEADFMV) != 0)
+#define MASK_XTHEADINT (1 << 7)
+#define TARGET_XTHEADINT   ((riscv_xthead_subext & MASK_XTHEADINT) != 0)
+#define MASK_XTHEADMAC (1 << 8)
 #define TARGET_XTHEADMAC   ((riscv_xthead_subext & MASK_XTHEADMAC) != 0)
-#define MASK_XTHEADMEMIDX  (1 << 7)
+#define MASK_XTHEADMEMIDX  (1 << 9)
 #define TARGET_XTHEADMEMIDX((riscv_xthead_subext & MASK_XTHEADMEMIDX) != 0)
-#define MASK_XTHEADSYNC(1 << 8)
+#define MASK_XTHEADSYNC(1 << 10)
 #define TARGET_XTHEADSYNC  ((riscv_xthead_subext & MASK_XTHEADSYNC) != 0)
 
 #endif /* ! GCC_RISCV_OPTS_H */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmv.c 
b/gcc/testsuite/gcc.target/riscv/xtheadfmv.c
new file mode 100644
index 000..e97e8f461f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmv.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadfmv" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadfmv" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadfmv
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadint.c 
b/gcc/testsuite/gcc.target/riscv/xtheadint.c
new file mode 100644
index 000..ee6989a380e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadint.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadint" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadint" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadint
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
-- 
2.38.1



[PATCH 5/7] riscv: thead: Add support for XTheadBb ISA extension

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

The XTheadBb ISA extension provides instructions similar to Zbb:
* th.srri/th.srriw
* th.ext/th.extu
* th.ff1 (count-leading-zeros)
* th.rev/th.revw

Instructions that are not covered, because they don't fit into a
pattern:
* th.ff0 (count-leading-ones)
* th.tstnbz

For the cases where the RISC-V backend already provides instruction
patterns with GCC standard pattern names (e.g. rotatert), this
patch simply uses expanders so we can match the pattern using unnamed
instruction patterns for zb* and xtheadb*.

gcc/ChangeLog:

* config/riscv/bitmanip.md (clz2): Add expand.
(ctz2): Add expand.
(popcount2): Add expand.
(*si2): Hide pattern name.
(*di2): Hide pattern name.
(rotr3): Add expand.
(*rotrsi3): Hide pattern name.
(*rotrdi3): Hide pattern name.
(*rotrsi3_sext): Hide pattern name.
(bswapdi2): Add expand.
(bswapsi2): Add expand.
(*bswap2): Hide pattern name.
* config/riscv/riscv.cc (riscv_rtx_costs): Add support for
  sign-extract.
* config/riscv/riscv.md (extv): New expand.
(extzv): New expand.
* config/riscv/thead.md (*th_srrisi3): New pattern.
(*th_srridi3): New pattern.
(*th_ext): New pattern.
(*th_extu): New pattern.
(*th_clz): New pattern.
(*th_revsi2): New pattern.
(*th_revdi2): New pattern.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadbb-ext.c: New test.
* gcc.target/riscv/xtheadbb-extu.c: New test.
* gcc.target/riscv/xtheadbb-rev.c: New test.
* gcc.target/riscv/xtheadbb-srri.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/bitmanip.md  | 47 --
 gcc/config/riscv/riscv.cc | 10 +++
 gcc/config/riscv/riscv.md | 26 
 gcc/config/riscv/thead.md | 62 +++
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c | 19 ++
 .../gcc.target/riscv/xtheadbb-extu.c  | 12 
 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c | 40 
 .../gcc.target/riscv/xtheadbb-srri.c  | 18 ++
 8 files changed, 228 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index b44fb9517e7..3dbb92b6115 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -119,6 +119,21 @@ (define_insn "*slliuw"
 
 ;; ZBB extension.
 
+(define_expand "clz2"
+  [(set (match_operand:GPR 0 "register_operand")
+   (clz:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB || TARGET_XTHEADBB")
+
+(define_expand "ctz2"
+  [(set (match_operand:GPR 0 "register_operand")
+   (ctz:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB")
+
+(define_expand "popcount2"
+  [(set (match_operand:GPR 0 "register_operand")
+   (popcount:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB")
+
 (define_insn "*_not"
   [(set (match_operand:X 0 "register_operand" "=r")
 (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
@@ -137,7 +152,7 @@ (define_insn "*xor_not"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "")])
 
-(define_insn "si2"
+(define_insn "*si2"
   [(set (match_operand:SI 0 "register_operand" "=r")
 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))]
   "TARGET_ZBB"
@@ -154,7 +169,7 @@ (define_insn "*disi2"
   [(set_attr "type" "bitmanip")
(set_attr "mode" "SI")])
 
-(define_insn "di2"
+(define_insn "*di2"
   [(set (match_operand:DI 0 "register_operand" "=r")
 (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
   "TARGET_64BIT && TARGET_ZBB"
@@ -194,7 +209,17 @@ (define_insn "*zero_extendhi2_zbb"
   [(set_attr "type" "bitmanip,load")
(set_attr "mode" "HI")])
 
-(define_insn "rotrsi3"
+(define_expand "rotr3"
+  [(set (match_operand:GPR 0 "register_operand")
+   (rotatert:GPR (match_operand:GPR 1 "register_operand")
+(match_operand:QI 2 "arith_operand")))]
+  "TARGET_ZBB || TARGET_XTHEADBB"
+{
+  if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode))
+FAIL;
+})
+
+(define_insn "*rotrsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
(rotatert:SI (match_operand:SI 1 "register_operand" "r")
 (match_operand:QI 2 "arith_operand" "rI")))]
@@ -202,7 +227,7 @@ (define_insn "rotrsi3"
   "ror%i2%~\t%0,%1,%2"
   [(set_attr "type" "bitmanip")])
 
-(define_insn "rotrdi3"
+(define_insn "*rotrdi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
(rotatert:DI (match_operand:DI 1 "register_operand" "r")
 

[PATCH 3/7] riscv: thead: Add support for XTheadBa and XTheadBs ISA extensions

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for the following T-Head vendor extensions:
* XTheadBa
* XTheadBs

Both extensions provide just one instruction, that has a counterpart
in the similar named Bitmanip ISA extension.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_rtx_costs): Adjust for th.tst.
* config/riscv/riscv.md: Include thead.md.
* config/riscv/thead.md: New file.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadba-addsl-64.c: New test.
* gcc.target/riscv/xtheadba-addsl.c: New test.
* gcc.target/riscv/xtheadbs-tst.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv.cc |  4 +-
 gcc/config/riscv/riscv.md |  1 +
 gcc/config/riscv/thead.md | 38 +++
 .../gcc.target/riscv/xtheadba-addsl-64.c  | 18 +
 .../gcc.target/riscv/xtheadba-addsl.c | 20 ++
 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c | 12 ++
 6 files changed, 91 insertions(+), 2 deletions(-)
 create mode 100644 gcc/config/riscv/thead.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl-64.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 02a01ca0b7c..decade0fedd 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2369,8 +2369,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int 
outer_code, int opno ATTRIBUTE_UN
  *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
  return true;
}
-  /* bext pattern for zbs.  */
-  if (TARGET_ZBS && outer_code == SET
+  /* bit extraction pattern (zbs:bext, xtheadbs:tst).  */
+  if ((TARGET_ZBS || TARGET_XTHEADBS) && outer_code == SET
  && GET_CODE (XEXP (x, 1)) == CONST_INT
  && INTVAL (XEXP (x, 1)) == 1)
{
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 798f7370a08..a9254df7820 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3009,3 +3009,4 @@ (define_insn "riscv_prefetchi_"
 (include "generic.md")
 (include "sifive-7.md")
 (include "vector.md")
+(include "thead.md")
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
new file mode 100644
index 000..676d10b71d7
--- /dev/null
+++ b/gcc/config/riscv/thead.md
@@ -0,0 +1,38 @@
+;; Machine description for T-Head vendor extensions
+;; Copyright (C) 2021-2022 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
+;; .
+
+(define_insn "*th_addsl"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (plus:X (ashift:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:QI 2 "immediate_operand" "I"))
+   (match_operand:X 3 "register_operand" "r")))]
+  "TARGET_XTHEADBA
+   && (INTVAL (operands[2]) >= 0) && (INTVAL (operands[2]) <= 3)"
+  "th.addsl\t%0,%1,%3,%2"
+  [(set_attr "type" "bitmanip")
+   (set_attr "mode" "")])
+
+(define_insn "*th_tst"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (zero_extract:X (match_operand:X 1 "register_operand" "r")
+   (const_int 1)
+   (match_operand 2 "immediate_operand" "i")))]
+  "TARGET_XTHEADBS"
+  "th.tst\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")])
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadba-addsl-64.c 
b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl-64.c
new file mode 100644
index 000..7f47929967a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl-64.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadba -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+/* RV64 only.  */
+int foos(short *x, int n){
+  return x[n];
+}
+int fooi(int *x, int n){
+  return x[n];
+}
+int fooll(long long *x, int n){
+  return x[n];
+}
+
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,1" 1 } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,2" 1 } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ 
\t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,3" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c 

[PATCH 4/7] riscv: thead: Add support for XTheadCondMov ISA extensions

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds support for XTheadCondMov ISA extension.
The extension brings a one-sided conditional move (no else-assignment).
Given that GCC has a great if-conversion pass, we don't need to do much,
besides properly expanding movcc accordingly and adjust the cost
model.

gcc/ChangeLog:

* config/riscv/iterators.md (TARGET_64BIT): Add GPR2 iterator.
* config/riscv/riscv.cc (riscv_rtx_costs): Add costs for
  XTheadCondMov.
(riscv_expand_conditional_move_onesided): New function.
(riscv_expand_conditional_move): New function.
* config/riscv/riscv.md: Add support for XTheadCondMov.
* config/riscv/thead.md (*th_cond_mov): Add
  support for XTheadCondMov.
(*th_cond_gpr_mov): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c: New test.
* gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c: New test.
* gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/iterators.md |  4 ++
 gcc/config/riscv/riscv.cc | 53 ---
 gcc/config/riscv/riscv.md |  7 +--
 gcc/config/riscv/thead.md | 35 
 .../riscv/xtheadcondmov-mveqz-imm-eqz.c   | 37 +
 .../riscv/xtheadcondmov-mveqz-imm-not.c   | 37 +
 .../riscv/xtheadcondmov-mveqz-reg-eqz.c   | 37 +
 .../riscv/xtheadcondmov-mveqz-reg-not.c   | 37 +
 .../riscv/xtheadcondmov-mvnez-imm-cond.c  | 37 +
 .../riscv/xtheadcondmov-mvnez-imm-nez.c   | 37 +
 .../riscv/xtheadcondmov-mvnez-reg-cond.c  | 37 +
 .../riscv/xtheadcondmov-mvnez-reg-nez.c   | 37 +
 12 files changed, 386 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c

diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 50380ecfac9..3932eab14fa 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -26,6 +26,10 @@
 ;; from the same template.
 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
 
+;; A copy of GPR that can be used when a pattern has two independent
+;; modes.
+(define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
+
 ;; This mode iterator allows :P to be used for patterns that operate on
 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index decade0fedd..9a795264e00 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2269,8 +2269,8 @@ 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
- && register_operand (XEXP (x, 1), mode)
+  if ((TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
+ && reg_or_0_operand (XEXP (x, 1), mode)
  && sfb_alu_operand (XEXP (x, 2), mode)
  && comparison_operator (XEXP (x, 0), VOIDmode))
{
@@ -3231,16 +3231,57 @@ riscv_expand_conditional_branch (rtx label, rtx_code 
code, rtx op0, rtx op1)
   emit_jump_insn (gen_condjump (condition, label));
 }
 
+/* Helper to emit two one-sided conditional moves for the movecc.  */
+
+static void
+riscv_expand_conditional_move_onesided (rtx dest, rtx cons, rtx alt,
+   rtx_code code, rtx op0, rtx op1)
+{
+  machine_mode mode = GET_MODE (dest);
+
+  gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
+  gcc_assert (reg_or_0_operand (cons, mode));
+  gcc_assert (reg_or_0_operand (alt, mode));
+
+  riscv_emit_int_compare (, , );
+  rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+
+  rtx tmp1 = gen_reg_rtx (mode);
+  rtx tmp2 = gen_reg_rtx (mode);
+
+  emit_insn (gen_rtx_SET (tmp1, gen_rtx_IF_THEN_ELSE (mode, cond,
+   

[PATCH 0/7] Add XThead* support

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

This series adds support for the following vendor extensions
from T-Head:

* XTheadCmo, XTheadSync
* XTheadBa, XTheadBb, XTheadBs
* XTheadCondMov
* XTheadMac
* XTheadFmv, XTheadInt

No regressions observed.

Christoph Müllner (7):
  riscv: Add basic XThead* vendor extension support
  riscv: riscv-cores.def: Add T-Head XuanTie C906
  riscv: thead: Add support for XTheadBa and XTheadBs ISA extensions
  riscv: thead: Add support for XTheadCondMov ISA extensions
  riscv: thead: Add support for XTheadBb ISA extension
  riscv: thead: Add support for XTheadMac ISA extension
  riscv: Add basic extension support for XTheadFmv and XTheadInt

 gcc/common/config/riscv/riscv-common.cc   |  24 ++
 gcc/config/riscv/bitmanip.md  |  47 +++-
 gcc/config/riscv/iterators.md |   4 +
 gcc/config/riscv/riscv-cores.def  |   2 +
 gcc/config/riscv/riscv-opts.h |  23 ++
 gcc/config/riscv/riscv.cc |  67 -
 gcc/config/riscv/riscv.md |  52 +++-
 gcc/config/riscv/riscv.opt|   3 +
 gcc/config/riscv/thead.md | 252 ++
 .../gcc.target/riscv/mcpu-thead-c906.c|  18 ++
 gcc/testsuite/gcc.target/riscv/thead-mula-1.c |  40 +++
 gcc/testsuite/gcc.target/riscv/thead-mula-2.c |  28 ++
 .../gcc.target/riscv/xtheadba-addsl-64.c  |  18 ++
 .../gcc.target/riscv/xtheadba-addsl.c |  20 ++
 gcc/testsuite/gcc.target/riscv/xtheadba.c |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c |  19 ++
 .../gcc.target/riscv/xtheadbb-extu.c  |  12 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c |  40 +++
 .../gcc.target/riscv/xtheadbb-srri.c  |  18 ++
 gcc/testsuite/gcc.target/riscv/xtheadbb.c |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c |  12 +
 gcc/testsuite/gcc.target/riscv/xtheadbs.c |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadcmo.c|  13 +
 .../riscv/xtheadcondmov-mveqz-imm-eqz.c   |  37 +++
 .../riscv/xtheadcondmov-mveqz-imm-not.c   |  37 +++
 .../riscv/xtheadcondmov-mveqz-reg-eqz.c   |  37 +++
 .../riscv/xtheadcondmov-mveqz-reg-not.c   |  37 +++
 .../riscv/xtheadcondmov-mvnez-imm-cond.c  |  37 +++
 .../riscv/xtheadcondmov-mvnez-imm-nez.c   |  37 +++
 .../riscv/xtheadcondmov-mvnez-reg-cond.c  |  37 +++
 .../riscv/xtheadcondmov-mvnez-reg-nez.c   |  37 +++
 .../gcc.target/riscv/xtheadcondmov.c  |  13 +
 .../gcc.target/riscv/xtheadfmemidx.c  |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadfmv.c|  14 +
 gcc/testsuite/gcc.target/riscv/xtheadint.c|  14 +
 gcc/testsuite/gcc.target/riscv/xtheadmac.c|  13 +
 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadsync.c   |  13 +
 38 files changed, 1123 insertions(+), 17 deletions(-)
 create mode 100644 gcc/config/riscv/thead.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/thead-mula-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/thead-mula-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl-64.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcmo.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadsync.c

-- 
2.38.1



[PATCH 1/7] riscv: Add basic XThead* vendor extension support

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

This patch add basic support for the following XThead* ISA extensions:

* XTheadCmo, XTheadSync
* XTheadBa, XTheadBb, XTheadBs, XTheadCondMov
* XTheadMac
* XTheadFMemIdx, XTheadMemIdx

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc: Add xthead* extensions.
* config/riscv/riscv-opts.h (MASK_XTHEADBA): New.
(TARGET_XTHEADBA): New.
(MASK_XTHEADBB): New.
(TARGET_XTHEADBB): New.
(MASK_XTHEADBS): New.
(TARGET_XTHEADBS): New.
(MASK_XTHEADCMO): New.
(TARGET_XTHEADCMO): New.
(MASK_XTHEADCONDMOV): New.
(TARGET_XTHEADCONDMOV): New.
(MASK_XTHEADFMEMIDX): New.
(TARGET_XTHEADFMEMIDX): New.
(MASK_XTHEADMAC): New.
(TARGET_XTHEADMAC): New.
(MASK_XTHEADMEMIDX): New.
(TARGET_XTHEADMEMIDX): New.
(MASK_XTHEADSYNC): New.
(TARGET_XTHEADSYNC): New.
* config/riscv/riscv.opt: Add riscv_xthead_subext.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadba.c: New test.
* gcc.target/riscv/xtheadbb.c: New test.
* gcc.target/riscv/xtheadbs.c: New test.
* gcc.target/riscv/xtheadcmo.c: New test.
* gcc.target/riscv/xtheadcondmov.c: New test.
* gcc.target/riscv/xtheadfmemidx.c: New test.
* gcc.target/riscv/xtheadmac.c: New test.
* gcc.target/riscv/xtheadmemidx.c: New test.
* gcc.target/riscv/xtheadsync.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/common/config/riscv/riscv-common.cc   | 20 +++
 gcc/config/riscv/riscv-opts.h | 19 ++
 gcc/config/riscv/riscv.opt|  3 +++
 gcc/testsuite/gcc.target/riscv/xtheadba.c | 13 
 gcc/testsuite/gcc.target/riscv/xtheadbb.c | 13 
 gcc/testsuite/gcc.target/riscv/xtheadbs.c | 13 
 gcc/testsuite/gcc.target/riscv/xtheadcmo.c| 13 
 .../gcc.target/riscv/xtheadcondmov.c  | 13 
 .../gcc.target/riscv/xtheadfmemidx.c  | 13 
 gcc/testsuite/gcc.target/riscv/xtheadmac.c| 13 
 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c | 13 
 gcc/testsuite/gcc.target/riscv/xtheadsync.c   | 13 
 12 files changed, 159 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcmo.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadsync.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 4b7f777c103..8e1449d3543 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -222,6 +222,16 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"svinval", ISA_SPEC_CLASS_NONE, 1, 0},
   {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0},
 
+  {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadbs", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadcmo", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadcondmov", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadfmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmac", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadsync", ISA_SPEC_CLASS_NONE, 1, 0},
+
   /* Terminate the list.  */
   {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
 };
@@ -1247,6 +1257,16 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"svinval", _options::x_riscv_sv_subext, MASK_SVINVAL},
   {"svnapot", _options::x_riscv_sv_subext, MASK_SVNAPOT},
 
+  {"xtheadba",  _options::x_riscv_xthead_subext, MASK_XTHEADBA},
+  {"xtheadbb",  _options::x_riscv_xthead_subext, MASK_XTHEADBB},
+  {"xtheadbs",  _options::x_riscv_xthead_subext, MASK_XTHEADBS},
+  {"xtheadcmo", _options::x_riscv_xthead_subext, MASK_XTHEADCMO},
+  {"xtheadcondmov", _options::x_riscv_xthead_subext, MASK_XTHEADCONDMOV},
+  {"xtheadfmemidx", _options::x_riscv_xthead_subext, MASK_XTHEADFMEMIDX},
+  {"xtheadmac", _options::x_riscv_xthead_subext, MASK_XTHEADMAC},
+  {"xtheadmemidx",  _options::x_riscv_xthead_subext, MASK_XTHEADMEMIDX},
+  {"xtheadsync",_options::x_riscv_xthead_subext, MASK_XTHEADSYNC},
+
   {NULL, NULL, 0}
 };
 
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 25fd85b09b1..18daac40dbd 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -189,4 +189,23 @@ enum stack_protector_guard {
? 0 \
: 32 << (__builtin_popcount (riscv_zvl_flags) - 1))
 
+#define MASK_XTHEADBA   

[PATCH 2/7] riscv: riscv-cores.def: Add T-Head XuanTie C906

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

This adds T-Head's XuanTie C906 to the list of known cores as "thead-c906".
The C906 is shipped for quite some time (it is the core of the Allwinner D1).
Note, that the tuning struct for the C906 is already part of GCC (it is
also name "thead-c906").

gcc/ChangeLog:

* config/riscv/riscv-cores.def (RISCV_CORE): Add "thead-c906".

gcc/testsuite/ChangeLog:

* gcc.target/riscv/mcpu-thead-c906.c: New test.

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv-cores.def   |  2 ++
 .../gcc.target/riscv/mcpu-thead-c906.c | 18 ++
 2 files changed, 20 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c

diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
index 31ad34682c5..648a010e09b 100644
--- a/gcc/config/riscv/riscv-cores.def
+++ b/gcc/config/riscv/riscv-cores.def
@@ -73,4 +73,6 @@ RISCV_CORE("sifive-s76",  "rv64imafdc", "sifive-7-series")
 RISCV_CORE("sifive-u54",  "rv64imafdc", "sifive-5-series")
 RISCV_CORE("sifive-u74",  "rv64imafdc", "sifive-7-series")
 
+RISCV_CORE("thead-c906",  "rv64imafdc", "thead-c906")
+
 #undef RISCV_CORE
diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c 
b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
new file mode 100644
index 000..f579e7e2215
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */
+/* { dg-options "-mcpu=thead-c906" { target { rv64 } } } */
+/* T-Head XuanTie C906 => rv64imafdc */
+
+#if !((__riscv_xlen == 64) \
+  && !defined(__riscv_32e) \
+  && defined(__riscv_mul)  \
+  && defined(__riscv_atomic)   \
+  && (__riscv_flen == 64)  \
+  && defined(__riscv_compressed))
+#error "unexpected arch"
+#endif
+
+int main()
+{
+  return 0;
+}
-- 
2.38.1



[RFC PATCH] ipa-cp: Speculatively call specialized functions

2022-11-13 Thread Christoph Muellner
From: mtsamis 

The IPA CP pass offers a wide range of optimizations, where most of them
lead to specialized functions that are called from a call site.
This can lead to multiple specialized function clones, if more than
one call-site allows such an optimization.
If not all call-sites can be optimized, the program might end
up with call-sites to the original function.

This pass assumes that non-optimized call-sites (i.e. call-sites
that don't call specialized functions) are likely to be called
with arguments that would allow calling specialized clones.
Since we cannot guarantee this (for obvious reasons), we can't
replace the existing calls. However, we can introduce dynamic
guards that test the arguments for the collected constants
and calls the specialized function if there is a match.

To demonstrate the effect, let's consider the following program part:

  func_1()
myfunc(1)
  func_2()
myfunc(2)
  func_i(i)
myfunc(i)

In this case the transformation would do the following:

  func_1()
myfunc.constprop.1() // myfunc() with arg0 == 1
  func_2()
myfunc.constprop.2() // myfunc() with arg0 == 2
  func_i(i)
if (i == 1)
  myfunc.constprop.1() // myfunc() with arg0 == 1
else if (i == 2)
  myfunc.constprop.2() // myfunc() with arg0 == 2
else
  myfunc(i)

The pass consists of two main parts:
* collecting all specialized functions and the argument/constant pair(s)
* insertion of the guards during materialization

The patch integrates well into ipa-cp and related IPA functionality.
Given the nature of IPA, the changes are touching many IPA-related
files as well as call-graph data structures.

The impact of the dynamic guard is expected to be less than the speedup
gained by enabled optimizations (e.g. inlining or constant propagation).

PR ipa/107667
gcc/Changelog:

* cgraph.cc (cgraph_add_edge_to_call_site_hash): Add support for 
guarded specialized edges.
(cgraph_edge::set_call_stmt): Likewise.
(symbol_table::create_edge): Likewise.
(cgraph_edge::remove): Likewise.
(cgraph_edge::make_speculative): Likewise.
(cgraph_edge::make_specialized): Likewise.
(cgraph_edge::remove_specializations): Likewise.
(cgraph_edge::redirect_call_stmt_to_callee): Likewise.
(cgraph_edge::dump_edge_flags): Likewise.
(verify_speculative_call): Likewise.
(verify_specialized_call): Likewise.
(cgraph_node::verify_node): Likewise.
* cgraph.h (class GTY): Add new class that contains info of specialized 
edges.
* cgraphclones.cc (cgraph_edge::clone): Add support for guarded 
specialized edges.
(cgraph_node::set_call_stmt_including_clones): Likewise.
* ipa-cp.cc (want_remove_some_param_p): Likewise.
(create_specialized_node): Likewise.
(add_specialized_edges): Likewise.
(ipcp_driver): Likewise.
* ipa-fnsummary.cc (redirect_to_unreachable): Likewise.
(ipa_fn_summary_t::duplicate): Likewise.
(analyze_function_body): Likewise.
(estimate_edge_size_and_time): Likewise.
(remap_edge_summaries): Likewise.
* ipa-inline-transform.cc (inline_transform): Likewise.
* ipa-inline.cc (edge_badness): Likewise.
 lto-cgraph.cc (lto_output_edge): Likewise.
(input_edge): Likewise.
* tree-inline.cc (copy_bb): Likewise.
* value-prof.cc (gimple_sc): Add function to create guarded 
specializations.
* value-prof.h (gimple_sc): Likewise.

Signed-off-by: Manolis Tsamis 
---
 gcc/cgraph.cc   | 316 +++-
 gcc/cgraph.h| 102 
 gcc/cgraphclones.cc |  30 
 gcc/common.opt  |   4 +
 gcc/ipa-cp.cc   | 105 
 gcc/ipa-fnsummary.cc|  42 +
 gcc/ipa-inline-transform.cc |  11 ++
 gcc/ipa-inline.cc   |   5 +
 gcc/lto-cgraph.cc   |  46 ++
 gcc/tree-inline.cc  |  54 ++
 gcc/value-prof.cc   | 214 
 gcc/value-prof.h|   1 +
 12 files changed, 923 insertions(+), 7 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 5851b2ffc6c..ee819c87261 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -718,18 +718,24 @@ cgraph_add_edge_to_call_site_hash (cgraph_edge *e)
  one indirect); always hash the direct one.  */
   if (e->speculative && e->indirect_unknown_callee)
 return;
+  /* There are potentially multiple specialization edges for every
+ specialized call; always hash the base egde.  */
+  if (e->guarded_specialization_edge_p ())
+return;
   cgraph_edge **slot = e->caller->call_site_hash->find_slot_with_hash
   (e->call_stmt, cgraph_edge_hasher::hash (e->call_stmt), INSERT);
   if (*slot)
 {
-  gcc_assert (((cgraph_edge *)*slot)->speculative);
+  gcc_assert (((cgraph_edge *)*slot)->speculative
+ || ((cgraph_edge *)*slot)->specialized);
   if 

[RFC PATCH] ipa-guarded-deref: Add new pass to dereference function pointers

2022-11-13 Thread Christoph Muellner
From: Christoph Müllner 

This patch adds a new pass that looks up function pointer assignments,
and adds guarded direct calls to the call sites of the function
pointers.

E.g.: Lets assume an assignment to a function pointer as follows:
b->cb = 
  Other part of the program can use the function pointer as follows:
b->cb ();
  With this pass the invocation will be transformed to:
if (b->cb == myfun)
  myfun();
else
   b->cb ()

The impact of the dynamic guard is expected to be less than the speedup
gained by enabled optimizations (e.g. inlining or constant propagation).

PR ipa/107666
gcc/ChangeLog:

* Makefile.in: Add new pass.
* common.opt: Add flag -fipa-guarded-deref.
* lto-section-in.cc: Add new section "ipa_guarded_deref".
* lto-streamer.h (enum lto_section_type): Add new section.
* passes.def: Add new pass.
* timevar.def (TV_IPA_GUARDED_DEREF): Add time var.
* tree-pass.h (make_pass_ipa_guarded_deref): New prototype.
* ipa-guarded-deref.cc: New file.

Signed-off-by: Christoph Müllner 
---
 gcc/Makefile.in  |1 +
 gcc/common.opt   |4 +
 gcc/ipa-guarded-deref.cc | 1115 ++
 gcc/lto-section-in.cc|1 +
 gcc/lto-streamer.h   |1 +
 gcc/passes.def   |1 +
 gcc/timevar.def  |1 +
 gcc/tree-pass.h  |1 +
 8 files changed, 1125 insertions(+)
 create mode 100644 gcc/ipa-guarded-deref.cc

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f672e6ea549..402c4a6ea3f 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1462,6 +1462,7 @@ OBJS = \
ipa-sra.o \
ipa-devirt.o \
ipa-fnsummary.o \
+   ipa-guarded-deref.o \
ipa-polymorphic-call.o \
ipa-split.o \
ipa-inline.o \
diff --git a/gcc/common.opt b/gcc/common.opt
index bce3e514f65..8344940ae5b 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1933,6 +1933,10 @@ fipa-bit-cp
 Common Var(flag_ipa_bit_cp) Optimization
 Perform interprocedural bitwise constant propagation.
 
+fipa-guarded-deref
+Common Var(flag_ipa_guarded_deref) Optimization
+Perform guarded function pointer derferencing.
+
 fipa-modref
 Common Var(flag_ipa_modref) Optimization
 Perform interprocedural modref analysis.
diff --git a/gcc/ipa-guarded-deref.cc b/gcc/ipa-guarded-deref.cc
new file mode 100644
index 000..198fb9b33ad
--- /dev/null
+++ b/gcc/ipa-guarded-deref.cc
@@ -0,0 +1,1115 @@
+/* IPA pass to transform indirect calls to guarded direct calls.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   Contributed by Christoph Muellner (Vrull GmbH)
+   Based on work by Erick Ochoa (Vrull GmbH)
+
+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/>.  */
+
+/* Indirect calls are used to separate callees from their call sites.
+   This helps to implement proper abstraction layers, but prevents
+   optimizations like constant-propagation or function specialization.
+
+   Assuming that we identify a function pointer that gets assigned
+   only a small amount of times, we can convert the indirect calls
+   to the target function into guarded direct calls and let later
+   passes apply additional optimizations.
+
+   This pass does this by:
+   * Identifying function pointers that are assigned up to N=1 times
+ to struct fields.
+   * Convert the indirect calls into a test for the call target
+ and a direct call
+   * If the test fails, then the indirect call will be executed.
+
+   E.g.:
+   - function foo's address is taken and stored in a field of struct
+   o->func = foo;
+   - the program writes into this struct field only once
+   - it is possible, that we miss a store (we would need strong guarantees)
+ therefore, we do the following conversion:
+   o->func ()
+ <-->
+   if (o->func == foo)
+foo ()
+   else
+o->func ()
+
+   This pass is implemented as a full IPA pass that uses the LTO section
+   "ipa_guarded_deref".  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple.h"
+#include "alloc-pool.h"
+#include "tree-pass.h"
+#include "tree-cfg.h"
+#include "ssa.h"

[wwwdocs] gcc-13: riscv: Document the Zawrs support

2022-11-02 Thread Christoph Muellner
From: Christoph Müllner 

This patch documents the new RISC-V Zawrs support.

Signed-off-by: Christoph Müllner 
---
 htdocs/gcc-13/changes.html | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html
index 7c6bfa6e..5e6e054b 100644
--- a/htdocs/gcc-13/changes.html
+++ b/htdocs/gcc-13/changes.html
@@ -261,7 +261,10 @@ a work-in-progress.
 
 
 
-
+RISC-V
+
+New ISA extension support for zawrs.
+
 
 
 
-- 
2.38.1



[PATCH] RISC-V: Add Zawrs ISA extension support

2022-10-27 Thread Christoph Muellner
From: Christoph Muellner 

This patch adds support for the Zawrs ISA extension.
The patch depends on the corresponding Binutils patch
to be usable (see [1])

The specification can be found here:
https://github.com/riscv/riscv-zawrs/blob/main/zawrs.adoc

Note, that the Zawrs extension is not frozen or ratified yet.
Therefore this patch is an RFC and not intended to get merged.

[1] https://sourceware.org/pipermail/binutils/2022-April/120559.html

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc: Add zawrs extension.
* config/riscv/riscv-opts.h (MASK_ZAWRS): New.
(TARGET_ZAWRS): New.
* config/riscv/riscv.opt: New.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zawrs.c: New test.

Signed-off-by: Christoph Muellner 
---
 gcc/common/config/riscv/riscv-common.cc |  4 
 gcc/config/riscv/riscv-opts.h   |  3 +++
 gcc/config/riscv/riscv.opt  |  3 +++
 gcc/testsuite/gcc.target/riscv/zawrs.c  | 13 +
 4 files changed, 23 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zawrs.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index d6404a01205..4b7f777c103 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -163,6 +163,8 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0},
   {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0},
 
+  {"zawrs", ISA_SPEC_CLASS_NONE, 1, 0},
+
   {"zba", ISA_SPEC_CLASS_NONE, 1, 0},
   {"zbb", ISA_SPEC_CLASS_NONE, 1, 0},
   {"zbc", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1180,6 +1182,8 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"zicsr",_options::x_riscv_zi_subext, MASK_ZICSR},
   {"zifencei", _options::x_riscv_zi_subext, MASK_ZIFENCEI},
 
+  {"zawrs", _options::x_riscv_za_subext, MASK_ZAWRS},
+
   {"zba",_options::x_riscv_zb_subext, MASK_ZBA},
   {"zbb",_options::x_riscv_zb_subext, MASK_ZBB},
   {"zbc",_options::x_riscv_zb_subext, MASK_ZBC},
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 1dfe8c89209..25fd85b09b1 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -73,6 +73,9 @@ enum stack_protector_guard {
 #define TARGET_ZICSR((riscv_zi_subext & MASK_ZICSR) != 0)
 #define TARGET_ZIFENCEI ((riscv_zi_subext & MASK_ZIFENCEI) != 0)
 
+#define MASK_ZAWRS   (1 << 0)
+#define TARGET_ZAWRS ((riscv_za_subext & MASK_ZAWRS) != 0)
+
 #define MASK_ZBA  (1 << 0)
 #define MASK_ZBB  (1 << 1)
 #define MASK_ZBC  (1 << 2)
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 426ea95cd14..7c3ca48d1cc 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -203,6 +203,9 @@ long riscv_stack_protector_guard_offset = 0
 TargetVariable
 int riscv_zi_subext
 
+TargetVariable
+int riscv_za_subext
+
 TargetVariable
 int riscv_zb_subext
 
diff --git a/gcc/testsuite/gcc.target/riscv/zawrs.c 
b/gcc/testsuite/gcc.target/riscv/zawrs.c
new file mode 100644
index 000..0b7e2662343
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zawrs.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zawrs" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zawrs" { target { rv32 } } } */
+
+#ifndef __riscv_zawrs
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
-- 
2.37.3



[PATCH v2 2/2] riscv-cores.def: Add T-Head XuanTie C906

2022-06-15 Thread Christoph Muellner
From: Christoph Müllner 

This adds T-Head's XuanTie C906 to the list of known cores as "thead-c906".
The C906 is shipped for quite some time (it is the core of the Allwinner D1).
Note, that the tuning struct for the C906 is already part of GCC (it is
also name "thead-c906").

gcc/ChangeLog:

* config/riscv/riscv-cores.def (RISCV_CORE): Add "thead-c906".

gcc/testsuite/ChangeLog:

* gcc.target/riscv/mcpu-thead-c906.c: New test.

Changes since v1:
* Adding test case
* Reword commit message

Signed-off-by: Christoph Müllner 
---
 gcc/config/riscv/riscv-cores.def   |  2 ++
 .../gcc.target/riscv/mcpu-thead-c906.c | 18 ++
 2 files changed, 20 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c

diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
index 60bcadbb034..dd97ece376f 100644
--- a/gcc/config/riscv/riscv-cores.def
+++ b/gcc/config/riscv/riscv-cores.def
@@ -44,4 +44,6 @@ RISCV_CORE("sifive-s76",  "rv64imafdc", "sifive-7-series")
 RISCV_CORE("sifive-u54",  "rv64imafdc", "sifive-5-series")
 RISCV_CORE("sifive-u74",  "rv64imafdc", "sifive-7-series")
 
+RISCV_CORE("thead-c906",  "rv64imafdc", "thead-c906")
+
 #undef RISCV_CORE
diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c 
b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
new file mode 100644
index 000..f579e7e2215
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */
+/* { dg-options "-mcpu=thead-c906" { target { rv64 } } } */
+/* T-Head XuanTie C906 => rv64imafdc */
+
+#if !((__riscv_xlen == 64) \
+  && !defined(__riscv_32e) \
+  && defined(__riscv_mul)  \
+  && defined(__riscv_atomic)   \
+  && (__riscv_flen == 64)  \
+  && defined(__riscv_compressed))
+#error "unexpected arch"
+#endif
+
+int main()
+{
+  return 0;
+}
-- 
2.35.3



  1   2   >