[gcc(refs/users/meissner/heads/work198-sha)] Add potential p-future XVRLD and XVRLDI instructions.
Michael Meissner
meissner@gcc.gnu.org
Fri Mar 28 01:15:56 GMT 2025
https://gcc.gnu.org/g:5cc5c90f5a2d0130277991b843bec930c66fbade
commit 5cc5c90f5a2d0130277991b843bec930c66fbade
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Thu Mar 27 21:14:13 2025 -0400
Add potential p-future XVRLD and XVRLDI instructions.
2025-03-27 Michael Meissner <meissner@linux.ibm.com>
gcc/
* config/rs6000/altivec.md (altivec_vrl<VI_char>): Add support for a
possible XVRLD instruction in the future.
(altivec_vrl<VI_char>_immediate): New insns.
* config/rs6000/predicates.md (vector_shift_immediate): New predicate.
* config/rs6000/rs6000.h (TARGET_XVRLW): New macro.
* config/rs6000/rs6000.md (isa attribute): Add xvrlw.
(enabled attribute): Add support for xvrlw.
gcc/testsuite/
* gcc.target/powerpc/vector-rotate-left.c: New test.
* lib/target-supports.exp (check_effective_target_powerpc_future_ok):
Add support to test -mcpu=future.
Diff:
---
gcc/config/rs6000/altivec.md | 35 +++++++++++++++++++---
gcc/config/rs6000/predicates.md | 26 ++++++++++++++++
gcc/config/rs6000/rs6000.h | 3 ++
gcc/config/rs6000/rs6000.md | 6 +++-
.../gcc.target/powerpc/vector-rotate-left.c | 34 +++++++++++++++++++++
gcc/testsuite/lib/target-supports.exp | 12 ++++++++
6 files changed, 111 insertions(+), 5 deletions(-)
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 7edc288a6565..013960438b04 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -1982,12 +1982,39 @@
}
[(set_attr "type" "vecperm")])
+;; -mcpu=future adds a vector rotate left word variant. There is no vector
+;; byte/half-word/double-word/quad-word rotate left. This insn occurs before
+;; altivec_vrl<VI_char> and will match for -mcpu=future, while other cpus will
+;; match the generic insn.
+;; However for testing, allow other xvrl variants. In particular, XVRLD for
+;; the sha3 tests for multibuf/singlebuf.
(define_insn "altivec_vrl<VI_char>"
- [(set (match_operand:VI2 0 "register_operand" "=v")
- (rotate:VI2 (match_operand:VI2 1 "register_operand" "v")
- (match_operand:VI2 2 "register_operand" "v")))]
+ [(set (match_operand:VI2 0 "register_operand" "=v,wa")
+ (rotate:VI2 (match_operand:VI2 1 "register_operand" "v,wa")
+ (match_operand:VI2 2 "register_operand" "v,wa")))]
"<VI_unit>"
- "vrl<VI_char> %0,%1,%2"
+ "@
+ vrl<VI_char> %0,%1,%2
+ xvrl<VI_char> %x0,%x1,%x2"
+ [(set_attr "type" "vecsimple")
+ (set_attr "isa" "*,xvrlw")])
+
+(define_insn "*altivec_vrl<VI_char>_immediate"
+ [(set (match_operand:VI2 0 "register_operand" "=wa,wa,wa,wa")
+ (rotate:VI2 (match_operand:VI2 1 "register_operand" "wa,wa,wa,wa")
+ (match_operand:VI2 2 "vector_shift_immediate" "j,wM,wE,wS")))]
+ "TARGET_XVRLW && <VI_unit>"
+{
+ rtx op2 = operands[2];
+ int value = 256;
+ int num_insns = -1;
+
+ if (!xxspltib_constant_p (op2, <MODE>mode, &num_insns, &value))
+ gcc_unreachable ();
+
+ operands[3] = GEN_INT (value & 0xff);
+ return "xvrl<VI_char>i %x0,%x1,%3";
+}
[(set_attr "type" "vecsimple")])
(define_insn "altivec_vrlq"
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 6485ee3eeecc..276812573977 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -728,6 +728,32 @@
return num_insns == 1;
})
+;; Return 1 if the operand is a CONST_VECTOR whose elements are all the
+;; same and the elements can be an immediate shift or rotate factor
+(define_predicate "vector_shift_immediate"
+ (match_code "const_vector,vec_duplicate,const_int")
+{
+ int value = 256;
+ int num_insns = -1;
+
+ if (zero_constant (op, mode) || all_ones_constant (op, mode))
+ return true;
+
+ if (!xxspltib_constant_p (op, mode, &num_insns, &value))
+ return false;
+
+ switch (mode)
+ {
+ case V16QImode: return IN_RANGE (value, 0, 7);
+ case V8HImode: return IN_RANGE (value, 0, 15);
+ case V4SImode: return IN_RANGE (value, 0, 31);
+ case V2DImode: return IN_RANGE (value, 0, 63);
+ default: break;
+ }
+
+ return false;
+})
+
;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a
;; vector register without using memory.
(define_predicate "easy_vector_constant"
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 9267612fbc9c..d414bc539207 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -575,6 +575,9 @@ extern int rs6000_vector_align[];
below. */
#define RS6000_FN_TARGET_INFO_HTM 1
+/* Whether we have XVRLW support. */
+#define TARGET_XVRLW TARGET_FUTURE
+
/* Whether the various reciprocal divide/square root estimate instructions
exist, and whether we should automatically generate code for the instruction
by default. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 3b876462ec32..e7927b88eaf8 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -369,7 +369,7 @@
(const (symbol_ref "(enum attr_cpu) rs6000_tune")))
;; The ISA we implement.
-(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10,xxeval"
+(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10,xxeval,xvrlw"
(const_string "any"))
;; Is this alternative enabled for the current CPU/ISA/etc.?
@@ -426,6 +426,10 @@
(match_test "TARGET_PREFIXED && TARGET_XXEVAL"))
(const_int 1)
+ (and (eq_attr "isa" "xvrlw")
+ (match_test "TARGET_XVRLW"))
+ (const_int 1)
+
] (const_int 0)))
;; If this instruction is microcoded on the CELL processor
diff --git a/gcc/testsuite/gcc.target/powerpc/vector-rotate-left.c b/gcc/testsuite/gcc.target/powerpc/vector-rotate-left.c
new file mode 100644
index 000000000000..5a5f37755077
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vector-rotate-left.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_future_ok } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-mdejagnu-cpu=future -O2" } */
+
+/* Test whether the xvrl (vector word rotate left using VSX registers insead of
+ Altivec registers is generated. */
+
+#include <altivec.h>
+
+typedef vector unsigned int v4si_t;
+
+v4si_t
+rotl_v4si_scalar (v4si_t x, unsigned long n)
+{
+ __asm__ (" # %x0" : "+f" (x));
+ return (x << n) | (x >> (32 - n)); /* xvrlw. */
+}
+
+v4si_t
+rotr_v4si_scalar (v4si_t x, unsigned long n)
+{
+ __asm__ (" # %x0" : "+f" (x));
+ return (x >> n) | (x << (32 - n)); /* xvrlw. */
+}
+
+v4si_t
+rotl_v4si_vector (v4si_t x, v4si_t y)
+{
+ __asm__ (" # %x0" : "+f" (x)); /* xvrlw. */
+ return vec_rl (x, y);
+}
+
+/* { dg-final { scan-assembler-times {\mxvrlw\M} 3 } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index ee4138aa6971..a3ce3f2d875e 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -7645,6 +7645,18 @@ proc check_effective_target_power10_ok { } {
}
}
+# Return 1 if this is a PowerPC target supporting -mcpu=future which enables
+# some potential new instructions.
+proc check_effective_target_powerpc_future_ok { } {
+ return [check_no_compiler_messages powerpc_future_ok object {
+ #ifndef _ARCH_PWR_FUTURE
+ #error "-mcpu=future is not supported"
+ #else
+ int dummy;
+ #endif
+ } "-mcpu=future"]
+}
+
# Return 1 if this is a PowerPC target supporting -mfloat128 via either
# software emulation on power7/power8 systems or hardware support on power9.
More information about the Gcc-cvs
mailing list