Prepare to get rid of some long switch-case constructs.
gcc/
* config/loongarch/lasx.md (lasx_xvshuf_b): Remove.
(lasx_xvshuf_<lasxfmt_f): Remove.
(unspec): Remove UNSPEC_LASX_XVSHUF and UNSPEC_LASX_XVSHUF_B.
* config/loongarch/lsx.md (lsx_vshuf_b): Remove.
(lsx_vshuf_<lasxfmt_f): Remove.
(unspec): Remove UNSPEC_LSX_VSHUF and UNSPEC_LSX_VSHUF_B.
* config/loongarch/simd.md (unspec): Add UNSPEC_SIMD_VSHUF.
(@simd_vshuf): New define_insn.
(<simd_isa>_<x>vshuf_<simdfmt><_f>): New define_expand.
* config/loongarch/loongarch.cc
(loongarch_try_expand_lsx_vshuf_const): Call gen_simd_vshuf
instead of gen_lasx_xvshuf and gen_lasx_xvshuf_b.
(loongarch_expand_vec_perm_const): Likewise.
---
gcc/config/loongarch/lasx.md | 30 -------------
gcc/config/loongarch/loongarch.cc | 11 +----
gcc/config/loongarch/lsx.md | 31 -------------
gcc/config/loongarch/simd.md | 75 +++++++++++++++++++++++++++++--
4 files changed, 74 insertions(+), 73 deletions(-)
diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index 2b63507f22f..a1359952c8a 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -44,8 +44,6 @@ (define_c_enum "unspec" [
UNSPEC_LASX_XVREPL128VEI
UNSPEC_LASX_XVSRAR
UNSPEC_LASX_XVSRLR
- UNSPEC_LASX_XVSHUF
- UNSPEC_LASX_XVSHUF_B
UNSPEC_LASX_BRANCH
UNSPEC_LASX_BRANCH_V
@@ -135,12 +133,6 @@ (define_mode_iterator LASX_PART [V4DI V4DF V8SF])
;; Only used for copy256_{u,s}.w.
(define_mode_iterator LASX_W [V8SI V8SF])
-;; As ILASX but excludes V32QI.
-(define_mode_iterator ILASX_DWH [V4DI V8SI V16HI])
-
-;; As LASX but excludes V32QI.
-(define_mode_iterator LASX_DWH [V4DF V8SF V4DI V8SI V16HI])
-
;; As ILASX but excludes V4DI.
(define_mode_iterator ILASX_WHB [V8SI V16HI V32QI])
@@ -2103,28 +2095,6 @@ (define_insn "lasx_xvssub_u_<lasxfmt_u>"
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "<MODE>")])
-(define_insn "@lasx_xvshuf_<lasxfmt_f>"
- [(set (match_operand:LASX_DWH 0 "register_operand" "=f")
- (unspec:LASX_DWH [(match_operand:<VIMODE> 1 "register_operand" "0")
- (match_operand:LASX_DWH 2 "register_operand" "f")
- (match_operand:LASX_DWH 3 "register_operand" "f")]
- UNSPEC_LASX_XVSHUF))]
- "ISA_HAS_LASX"
- "xvshuf.<lasxfmt>\t%u0,%u2,%u3"
- [(set_attr "type" "simd_sld")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "lasx_xvshuf_b"
- [(set (match_operand:V32QI 0 "register_operand" "=f")
- (unspec:V32QI [(match_operand:V32QI 1 "register_operand" "f")
- (match_operand:V32QI 2 "register_operand" "f")
- (match_operand:V32QI 3 "register_operand" "f")]
- UNSPEC_LASX_XVSHUF_B))]
- "ISA_HAS_LASX"
- "xvshuf.b\t%u0,%u1,%u2,%u3"
- [(set_attr "type" "simd_sld")
- (set_attr "mode" "V32QI")])
-
(define_insn "lasx_xvreplve0_<lasxfmt_f>"
[(set (match_operand:LASX 0 "register_operand" "=f")
(vec_duplicate:LASX
diff --git a/gcc/config/loongarch/loongarch.cc
b/gcc/config/loongarch/loongarch.cc
index 3a5ccda808e..9e9d6cfc75f 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -8712,10 +8712,7 @@ loongarch_try_expand_lsx_vshuf_const (struct
expand_vec_perm_d *d)
rtx sel = force_reg (sel_mode,
gen_rtx_CONST_VECTOR (sel_mode, sel_v));
- if (d->vmode == E_V16QImode)
- emit_insn (gen_lsx_vshuf_b (target, op1, op0, sel));
- else
- emit_insn (gen_lsx_vshuf (d->vmode, target, sel, op1, op0));
+ emit_insn (gen_simd_vshuf (d->vmode, target, op1, op0, sel));
return true;
}
@@ -9748,11 +9745,7 @@ expand_perm_const_end:
rtx sel = force_reg (sel_mode,
gen_rtx_CONST_VECTOR (sel_mode, sel_v));
- if (d->vmode == E_V32QImode)
- emit_insn (gen_lasx_xvshuf_b (target, op1, op0, sel));
- else
- emit_insn (gen_lasx_xvshuf (d->vmode, target, sel, op1, op0));
-
+ emit_insn (gen_simd_vshuf (d->vmode, target, op1, op0, sel));
return true;
}
}
diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index cd87757827d..e4497cc910e 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -45,7 +45,6 @@ (define_c_enum "unspec" [
UNSPEC_LSX_VSAT_U
UNSPEC_LSX_VSRAR
UNSPEC_LSX_VSRLR
- UNSPEC_LSX_VSHUF
UNSPEC_LSX_VEXTW_S
UNSPEC_LSX_VEXTW_U
UNSPEC_LSX_VSLLWIL_S
@@ -86,7 +85,6 @@ (define_c_enum "unspec" [
UNSPEC_LSX_VSSRLN
UNSPEC_LSX_VSSRLRN
UNSPEC_LSX_VLDI
- UNSPEC_LSX_VSHUF_B
UNSPEC_LSX_VSTX
UNSPEC_LSX_VEXTL_QU_DU
UNSPEC_LSX_VSETEQZ_V
@@ -133,12 +131,6 @@ (define_mode_iterator LSX_D [V2DI V2DF])
;; Only used for copy_{u,s}.w and vilvh.
(define_mode_iterator LSX_W [V4SI V4SF])
-;; As ILSX but excludes V16QI.
-(define_mode_iterator ILSX_DWH [V2DI V4SI V8HI])
-
-;; As LSX but excludes V16QI.
-(define_mode_iterator LSX_DWH [V2DF V4SF V2DI V4SI V8HI])
-
;; As ILSX but excludes V2DI.
(define_mode_iterator ILSX_WHB [V4SI V8HI V16QI])
@@ -532,18 +524,6 @@ (define_expand "vec_perm<mode>"
DONE;
})
-(define_insn "@lsx_vshuf_<lsxfmt_f>"
- [(set (match_operand:LSX_DWH 0 "register_operand" "=f")
- (unspec:LSX_DWH [(match_operand:<VIMODE> 1 "register_operand" "0")
- (match_operand:LSX_DWH 2 "register_operand" "f")
- (match_operand:LSX_DWH 3 "register_operand" "f")]
- UNSPEC_LSX_VSHUF))]
- "ISA_HAS_LSX"
- "vshuf.<lsxfmt>\t%w0,%w2,%w3"
- [(set_attr "type" "simd_sld")
- (set_attr "mode" "<MODE>")])
-
-
;; Integer operations
(define_insn "add<mode>3"
[(set (match_operand:ILSX 0 "register_operand" "=f,f,f")
@@ -2668,17 +2648,6 @@ (define_insn "lsx_vldi"
[(set_attr "type" "simd_load")
(set_attr "mode" "V2DI")])
-(define_insn "lsx_vshuf_b"
- [(set (match_operand:V16QI 0 "register_operand" "=f")
- (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "f")
- (match_operand:V16QI 2 "register_operand" "f")
- (match_operand:V16QI 3 "register_operand" "f")]
- UNSPEC_LSX_VSHUF_B))]
- "ISA_HAS_LSX"
- "vshuf.b\t%w0,%w1,%w2,%w3"
- [(set_attr "type" "simd_shf")
- (set_attr "mode" "V16QI")])
-
(define_insn "lsx_vstx"
[(set (mem:V16QI (plus:DI (match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "reg_or_0_operand" "rJ")))
diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md
index b73f65aca13..0ad10683cb5 100644
--- a/gcc/config/loongarch/simd.md
+++ b/gcc/config/loongarch/simd.md
@@ -18,10 +18,14 @@
;; <http://www.gnu.org/licenses/>.
;; Integer modes supported by LSX.
-(define_mode_iterator ILSX [V2DI V4SI V8HI V16QI])
+(define_mode_iterator ILSX_DWH [V2DI V4SI V8HI])
+(define_mode_iterator ILSX [ILSX_DWH V16QI])
+(define_mode_iterator LSX_DWH [ILSX_DWH V2DF V4SF])
;; Integer modes supported by LASX.
-(define_mode_iterator ILASX [V4DI V8SI V16HI V32QI])
+(define_mode_iterator ILASX_DWH [V4DI V8SI V16HI])
+(define_mode_iterator ILASX [ILASX_DWH V32QI])
+(define_mode_iterator LASX_DWH [ILASX_DWH V4DF V8SF])
;; Only integer modes smaller than a word.
(define_mode_iterator ILSX_HB [V8HI V16QI])
@@ -46,6 +50,10 @@ (define_mode_iterator IVEC [(ILSX "ISA_HAS_LSX") (ILASX
"ISA_HAS_LASX")])
(define_mode_iterator IVEC_HB [(ILSX_HB "ISA_HAS_LSX")
(ILASX_HB "ISA_HAS_LASX")])
+;; All modes longer than a byte
+(define_mode_iterator VEC_DWH [(LSX_DWH "ISA_HAS_LSX")
+ (LASX_DWH "ISA_HAS_LASX")])
+
;; All FP modes available
(define_mode_iterator FVEC [(FLSX "ISA_HAS_LSX") (FLASX "ISA_HAS_LASX")])
@@ -255,7 +263,8 @@ (define_c_enum "unspec"
UNSPEC_SIMD_FRINTRZ
UNSPEC_SIMD_FRINT
UNSPEC_SIMD_FRINTRM
- UNSPEC_SIMD_FRINTRNE])
+ UNSPEC_SIMD_FRINTRNE
+ UNSPEC_SIMD_VSHUF])
(define_int_iterator SIMD_FRINT
[UNSPEC_SIMD_FRINTRP
@@ -1107,6 +1116,66 @@ (define_insn "and<mode>3"
[(set_attr "type" "simd_logic,simd_bit,simd_logic")
(set_attr "mode" "<MODE>")])
+(define_insn "@simd_vshuf_<mode>"
+ [(set (match_operand:QIVEC 0 "register_operand" "=f")
+ (unspec:QIVEC [(match_operand:QIVEC 1 "register_operand" "f")
+ (match_operand:QIVEC 2 "register_operand" "f")
+ (match_operand:QIVEC 3 "register_operand" "f")]
+ UNSPEC_SIMD_VSHUF))]
+ ""
+ {
+ return "<x>vshuf.b\t%<wu>0,%<wu>1,%<wu>2,%<wu>3";
+ }
+ [(set_attr "type" "simd_sld")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@simd_vshuf_<mode>"
+ [(set (match_operand:VEC_DWH 0 "register_operand" "=f")
+ (unspec:VEC_DWH [(match_operand:VEC_DWH 1 "register_operand" "f")
+ (match_operand:VEC_DWH 2 "register_operand" "f")
+ (match_operand:<VIMODE> 3 "register_operand" "0")]
+ UNSPEC_SIMD_VSHUF))]
+ ""
+ {
+ return "<x>vshuf.<simdfmt_as_i>\t%<wu>0,%<wu>1,%<wu>2";
+ }
+ [(set_attr "type" "simd_sld")
+ (set_attr "mode" "<MODE>")])
+
+;; Backward compatibility wrapper. New code should use simd_vshuf
+;; directly instead: gen_simd_vshuf (mode, ...) can often significantly
+;; simplify the logic.
+(define_expand "<simd_isa>_<x>vshuf_<simdfmt><_f>"
+ [(match_operand:ALLVEC 0 "register_operand")
+ (match_operand 1 "register_operand")
+ (match_operand 2 "register_operand")
+ (match_operand 3 "register_operand")]
+ ""
+ {
+ rtx op0 = operands[0], op1, op2, op3;
+
+ switch (<MODE>mode)
+ {
+ case V32QImode:
+ case V16QImode:
+ op1 = operands[1];
+ op2 = operands[2];
+ op3 = operands[3];
+ break;
+ default:
+ op3 = operands[1];
+ op1 = operands[2];
+ op2 = operands[3];
+ }
+
+ gcc_assert (GET_MODE (op1) == <MODE>mode);
+ gcc_assert (GET_MODE (op2) == <MODE>mode);
+ gcc_assert (GET_MODE (op3) == <VIMODE>mode);
+
+ emit_insn (gen_simd_vshuf (<MODE>mode, op0, op1, op2, op3));
+ DONE;
+ })
+
; The LoongArch SX Instructions.
(include "lsx.md")
--
2.51.2