From: Aleksandar Rakic <aleksandar.ra...@htecgroup.com>

GCC assumes that taking a vector mode B SUBREG of vector mode A register
allows it to interpret its memory layout as if in A vector mode.

We currently allow this mode change to be no-op on MSA registers. This
works on little-endian because MSA register layout matches that of
vector value in memory. This breaks on big-endian because ordering of
bytes within the lane depends of target endianes.

We now conservatively disallow direct MSA register mode change via
TARGET_CAN_CHANGE_MODE_CLASS making it go through memory.

This fixes the MSA implementation on big-endian targets which is
essentially broken for things like SUBREG handling and calling
convention for vector types. It borrows heavily from [1] as Aarch64 has
the same problem with SVE vectors.

Conceptually, register bitconverts should act as the data has been
stored to memory in one mode, and loaded from memory in the other.
This isn't what happens on big-endian as vector load/store instructions
are essentially mixed-endian with respect to the vector as a whole.
The in-register representation of data must be changed so that the
load/store round trip becomes valid. This is done by inserting one or
two shuffle instructions for every SUBREG move, as previously
implemented in [2] for LLVM. Even if the shuffle instructions weren't
generated, constraint in mips_can_change_mode_class would force the
conceptual memory reload of SUBREG move operand, which would generate
correct, albeit very inefficient code.

New msa_reg_predicate was created in order to forbid SUBREG operands in
MSA patterns on big-endian targets. It weeds SUBREGs out of the
instruction patterns into SUBREG->REG moves which are caught by the new
msa_mov<mode>_subreg_be pattern and transformed in shuffle(s).

As for the MSA calling convention, ABI states that compiling for MSA
should not change the base ABIs vector calling convention, that is, MSA
vectors passed of returned by value do not use the MSA vector registers.
Instead, they are passed by general-purpose registers, as described by
the ABI. Passing the vector argument requires splitting it into 2 (or 4)
general-purpose registers and bitconverting it into V2DImode (or
V4SImode). The solution boils down to the one presented for SUBREG
moves: force every vector argument to the appropriate mode (V2DI or
V4SI) so that the shuffle instruction(s) might be generated in order to
conform to the calling convention. The same applies to vectors as return
values.

New testcases were added to check calling convention compliance for all
possible combinations of MSA and non-MSA interlinking.

gcc/

    * config/mips/mips-msa.md: Replace register_operand predicate with
    msa_reg_operand in every pattern.
    (vec_extract<mode><unitmode>): Use mips_weed_subreg_out_of_msa_copy
    to weed subreg out of msa_copy.
    (UNSPEC_MSA_CHANGE_MODE): New unspec.
    (UNSPEC_MSA_SUBREG_BE): Likewise.
    (msa_change_mode): New expand pattern.
    (msa_change_mode_<mode>): New insn pattern.
    (*msa_mov<mode>_subreg_be): Likewise.
    * config/mips/mips-protos.h (mips_split_msa_subreg_move): Declare.
    * config/mips/mips.cc (mips_maybe_expand_msa_subreg_move): New
    function.
    (mips_replace_reg_mode): Ditto.
    (mips_split_msa_subreg_move): Ditto.
    (mips_legitimize_move): Modify machine modes of MSA vectors which
    reside in general-purpose registers. Check whether SUBREG move can
    be replaced with shuffle(s).
    (mips_weed_subreg_out_of_msa_copy): New function.
    (mips_split_128bit_move): Replace explicit REG creation with
    mips_replace_reg_mode. Use mips_weed_subreg_out_of_msa_copy to
    weed subreg out of msa_copy.
    (mips_split_msa_copy_d): Ditto.
    (mips_split_msa_insert_d): Replace explicit REG creation with
    mips_replace_reg_mode.
    (mips_split_msa_fill_d): Ditto.
    (mips_can_change_mode_class): Disallow change of MSA modes with
    different lane width on big-endian targets.
    (mips_weed_subreg_out_of_vec_select): New function.
    (mips_expand_vselect): Use mips_weed_subreg_out_of_vec_select
    to weed subreg out of vec_select.
    (mips_expand_msa_shuffle): Ditto.
    (mips_expand_vec_unpack): Use gen_msa_change_mode instead of
    gen_lowpart for MSA modes.
    * config/mips/predicates.md (msa_reg_operand): New predicate.

gcc/testsuite:

    * gcc.target/mips/inter/msa-inter.exp: New file.
    * gcc.target/mips/inter/msa_1.h: New test.
    * gcc.target/mips/inter/msa_1_main.c: New test.
    * gcc.target/mips/inter/msa_1_x.c: New test.
    * gcc.target/mips/inter/msa_1_y.c: New test.

Cherry-picked c00d34621429f31926e0c72e027b0c1028d046f0,
8c54834001d76ed3c76832b6a47dfcb7d62bb664, and
ae63e81745e8a5c07812428ecda735320201d500
from https://github.com/MIPS/gcc

Signed-off-by: Dragan Mladjenovic <dragan.mladjeno...@rt-rk.com>
Signed-off-by: Faraz Shahbazker <fshahbaz...@wavecomp.com>
Signed-off-by: Mihailo Stojanovic <mistojano...@wavecomp.com>
Signed-off-by: Aleksandar Rakic <aleksandar.ra...@htecgroup.com>
---
 gcc/config/mips/mips-msa.md                   | 1092 +++++++++--------
 gcc/config/mips/mips-protos.h                 |    2 +
 gcc/config/mips/mips.cc                       |  224 +++-
 gcc/config/mips/predicates.md                 |    5 +
 .../gcc.target/mips/inter/msa-inter.exp       |   67 +
 gcc/testsuite/gcc.target/mips/inter/msa_1.h   |   23 +
 .../gcc.target/mips/inter/msa_1_main.c        |    8 +
 gcc/testsuite/gcc.target/mips/inter/msa_1_x.c |   35 +
 gcc/testsuite/gcc.target/mips/inter/msa_1_y.c |   14 +
 9 files changed, 939 insertions(+), 531 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/inter/msa-inter.exp
 create mode 100644 gcc/testsuite/gcc.target/mips/inter/msa_1.h
 create mode 100644 gcc/testsuite/gcc.target/mips/inter/msa_1_main.c
 create mode 100644 gcc/testsuite/gcc.target/mips/inter/msa_1_x.c
 create mode 100644 gcc/testsuite/gcc.target/mips/inter/msa_1_y.c

diff --git a/gcc/config/mips/mips-msa.md b/gcc/config/mips/mips-msa.md
index 976f296402e..3d13e59cd9c 100644
--- a/gcc/config/mips/mips-msa.md
+++ b/gcc/config/mips/mips-msa.md
@@ -90,6 +90,8 @@
   UNSPEC_MSA_SUBSUU_S
   UNSPEC_MSA_SUBSUS_U
   UNSPEC_MSA_VSHF
+  UNSPEC_MSA_CHANGE_MODE
+  UNSPEC_MSA_SUBREG_BE
 ])
 
 ;; All vector modes with 128 bits.
@@ -236,7 +238,7 @@
                             (V4SF "31") (V8SF "31")])
 
 (define_expand "vec_init<mode><unitmode>"
-  [(match_operand:MSA 0 "register_operand")
+  [(match_operand:MSA 0 "msa_reg_operand")
    (match_operand:MSA 1 "")]
   "ISA_HAS_MSA"
 {
@@ -246,22 +248,22 @@
 
 ;; pckev pattern with implicit type conversion.
 (define_insn "vec_pack_trunc_<mode>"
-   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
+   [(set (match_operand:<VHMODE> 0 "msa_reg_operand" "=f")
         (vec_concat:<VHMODE>
           (truncate:<VTRUNCMODE>
-            (match_operand:IMSA_DWH 1 "register_operand" "f"))
+            (match_operand:IMSA_DWH 1 "msa_reg_operand" "f"))
           (truncate:<VTRUNCMODE>
-            (match_operand:IMSA_DWH 2 "register_operand" "f"))))]
+            (match_operand:IMSA_DWH 2 "msa_reg_operand" "f"))))]
   "ISA_HAS_MSA"
   "pckev.<hmsafmt>\t%w0,%w2,%w1"
   [(set_attr "type" "simd_permute")
    (set_attr "mode" "<MODE>")])
 
 (define_expand "vec_unpacks_hi_v4sf"
-  [(set (match_operand:V2DF 0 "register_operand" "=f")
+  [(set (match_operand:V2DF 0 "msa_reg_operand" "=f")
        (float_extend:V2DF
          (vec_select:V2SF
-           (match_operand:V4SF 1 "register_operand" "f")
+           (match_operand:V4SF 1 "msa_reg_operand" "f")
            (match_dup 2))))]
   "ISA_HAS_MSA"
 {
@@ -269,10 +271,10 @@
 })
 
 (define_expand "vec_unpacks_lo_v4sf"
-  [(set (match_operand:V2DF 0 "register_operand" "=f")
+  [(set (match_operand:V2DF 0 "msa_reg_operand" "=f")
        (float_extend:V2DF
          (vec_select:V2SF
-           (match_operand:V4SF 1 "register_operand" "f")
+           (match_operand:V4SF 1 "msa_reg_operand" "f")
            (match_dup 2))))]
   "ISA_HAS_MSA"
 {
@@ -280,8 +282,8 @@
 })
 
 (define_expand "vec_unpacks_hi_<mode>"
-  [(match_operand:<VDMODE> 0 "register_operand")
-   (match_operand:IMSA_WHB 1 "register_operand")]
+  [(match_operand:<VDMODE> 0 "msa_reg_operand")
+   (match_operand:IMSA_WHB 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   mips_expand_vec_unpack (operands, false/*unsigned_p*/, true/*high_p*/);
@@ -289,8 +291,8 @@
 })
 
 (define_expand "vec_unpacks_lo_<mode>"
-  [(match_operand:<VDMODE> 0 "register_operand")
-   (match_operand:IMSA_WHB 1 "register_operand")]
+  [(match_operand:<VDMODE> 0 "msa_reg_operand")
+   (match_operand:IMSA_WHB 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   mips_expand_vec_unpack (operands, false/*unsigned_p*/, false/*high_p*/);
@@ -298,8 +300,8 @@
 })
 
 (define_expand "vec_unpacku_hi_<mode>"
-  [(match_operand:<VDMODE> 0 "register_operand")
-   (match_operand:IMSA_WHB 1 "register_operand")]
+  [(match_operand:<VDMODE> 0 "msa_reg_operand")
+   (match_operand:IMSA_WHB 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   mips_expand_vec_unpack (operands, true/*unsigned_p*/, true/*high_p*/);
@@ -307,8 +309,8 @@
 })
 
 (define_expand "vec_unpacku_lo_<mode>"
-  [(match_operand:<VDMODE> 0 "register_operand")
-   (match_operand:IMSA_WHB 1 "register_operand")]
+  [(match_operand:<VDMODE> 0 "msa_reg_operand")
+   (match_operand:IMSA_WHB 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   mips_expand_vec_unpack (operands, true/*unsigned_p*/, false/*high_p*/);
@@ -316,26 +318,31 @@
 })
 
 (define_expand "vec_extract<mode><unitmode>"
-  [(match_operand:<UNITMODE> 0 "register_operand")
-   (match_operand:IMSA 1 "register_operand")
+  [(match_operand:<UNITMODE> 0 "msa_reg_operand")
+   (match_operand:IMSA 1 "msa_reg_operand")
    (match_operand 2 "const_<indeximm>_operand")]
   "ISA_HAS_MSA"
 {
+  extern rtx mips_weed_subreg_out_of_msa_copy (rtx);
   if (<UNITMODE>mode == QImode || <UNITMODE>mode == HImode)
     {
       rtx dest1 = gen_reg_rtx (SImode);
-      emit_insn (gen_msa_copy_s_<msafmt> (dest1, operands[1], operands[2]));
+      emit_insn (gen_msa_copy_s_<msafmt> (dest1,
+                     mips_weed_subreg_out_of_msa_copy (operands[1]),
+                     operands[2]));
       emit_move_insn (operands[0],
                      gen_lowpart (<UNITMODE>mode, dest1));
     }
   else
-    emit_insn (gen_msa_copy_s_<msafmt> (operands[0], operands[1], 
operands[2]));
+    emit_insn (gen_msa_copy_s_<msafmt> (operands[0],
+             mips_weed_subreg_out_of_msa_copy (operands[1]),
+             operands[2]));
   DONE;
 })
 
 (define_expand "vec_extract<mode><unitmode>"
-  [(match_operand:<UNITMODE> 0 "register_operand")
-   (match_operand:FMSA 1 "register_operand")
+  [(match_operand:<UNITMODE> 0 "msa_reg_operand")
+   (match_operand:FMSA 1 "msa_reg_operand")
    (match_operand 2 "const_<indeximm>_operand")]
   "ISA_HAS_MSA"
 {
@@ -362,9 +369,9 @@
 })
 
 (define_insn_and_split "msa_vec_extract_<msafmt_f>"
-  [(set (match_operand:<UNITMODE> 0 "register_operand" "=f")
+  [(set (match_operand:<UNITMODE> 0 "msa_reg_operand" "=f")
        (vec_select:<UNITMODE>
-         (match_operand:FMSA 1 "register_operand" "f")
+         (match_operand:FMSA 1 "msa_reg_operand" "f")
          (parallel [(const_int 0)])))]
   "ISA_HAS_MSA"
   "#"
@@ -388,7 +395,7 @@
    (set_attr "mode" "<UNITMODE>")])
 
 (define_expand "vec_set<mode>"
-  [(match_operand:IMSA 0 "register_operand")
+  [(match_operand:IMSA 0 "msa_reg_operand")
    (match_operand:<UNITMODE> 1 "reg_or_0_operand")
    (match_operand 2 "const_<indeximm>_operand")]
   "ISA_HAS_MSA"
@@ -400,8 +407,8 @@
 })
 
 (define_expand "vec_set<mode>"
-  [(match_operand:FMSA 0 "register_operand")
-   (match_operand:<UNITMODE> 1 "register_operand")
+  [(match_operand:FMSA 0 "msa_reg_operand")
+   (match_operand:<UNITMODE> 1 "msa_reg_operand")
    (match_operand 2 "const_<indeximm>_operand")]
   "ISA_HAS_MSA"
 {
@@ -412,10 +419,10 @@
 })
 
 (define_expand "vcond_mask_<MSA:mode><IMSA:mode>"
-  [(match_operand:MSA 0 "register_operand")
+  [(match_operand:MSA 0 "msa_reg_operand")
    (match_operand:MSA 1 "reg_or_m1_operand")
    (match_operand:MSA 2 "reg_or_0_operand")
-   (match_operand:IMSA 3 "register_operand")]
+   (match_operand:IMSA 3 "msa_reg_operand")]
   "ISA_HAS_MSA
    && (GET_MODE_NUNITS (<MSA:MODE>mode) == GET_MODE_NUNITS (<IMSA:MODE>mode))"
 {
@@ -425,12 +432,12 @@
 
 
 (define_expand "vcondu<MSA:mode><IMSA:mode>"
-  [(match_operand:MSA 0 "register_operand")
+  [(match_operand:MSA 0 "msa_reg_operand")
    (match_operand:MSA 1 "reg_or_m1_operand")
    (match_operand:MSA 2 "reg_or_0_operand")
    (match_operator 3 ""
-     [(match_operand:IMSA 4 "register_operand")
-      (match_operand:IMSA 5 "register_operand")])]
+     [(match_operand:IMSA 4 "msa_reg_operand")
+      (match_operand:IMSA 5 "msa_reg_operand")])]
   "ISA_HAS_MSA
    && (GET_MODE_NUNITS (<MSA:MODE>mode) == GET_MODE_NUNITS (<IMSA:MODE>mode))"
 {
@@ -439,12 +446,12 @@
 })
 
 (define_expand "vcond<MSA:mode><MSA_2:mode>"
-  [(match_operand:MSA 0 "register_operand")
+  [(match_operand:MSA 0 "msa_reg_operand")
    (match_operand:MSA 1 "reg_or_m1_operand")
    (match_operand:MSA 2 "reg_or_0_operand")
    (match_operator 3 ""
-     [(match_operand:MSA_2 4 "register_operand")
-      (match_operand:MSA_2 5 "register_operand")])]
+     [(match_operand:MSA_2 4 "msa_reg_operand")
+      (match_operand:MSA_2 5 "msa_reg_operand")])]
   "ISA_HAS_MSA
    && (GET_MODE_NUNITS (<MSA:MODE>mode) == GET_MODE_NUNITS (<MSA_2:MODE>mode))"
 {
@@ -453,10 +460,10 @@
 })
 
 (define_expand "vec_cmp<MSA:mode><mode_i>"
-  [(match_operand:<VIMODE> 0 "register_operand")
+  [(match_operand:<VIMODE> 0 "msa_reg_operand")
    (match_operator 1 ""
-     [(match_operand:MSA 2 "register_operand")
-      (match_operand:MSA 3 "register_operand")])]
+     [(match_operand:MSA 2 "msa_reg_operand")
+      (match_operand:MSA 3 "msa_reg_operand")])]
   "ISA_HAS_MSA"
 {
   mips_expand_vec_cmp_expr (operands);
@@ -464,10 +471,10 @@
 })
 
 (define_expand "vec_cmpu<IMSA:mode><mode_i>"
-  [(match_operand:<VIMODE> 0 "register_operand")
+  [(match_operand:<VIMODE> 0 "msa_reg_operand")
    (match_operator 1 ""
-     [(match_operand:IMSA 2 "register_operand")
-      (match_operand:IMSA 3 "register_operand")])]
+     [(match_operand:IMSA 2 "msa_reg_operand")
+      (match_operand:IMSA 3 "msa_reg_operand")])]
   "ISA_HAS_MSA"
 {
   mips_expand_vec_cmp_expr (operands);
@@ -475,11 +482,11 @@
 })
 
 (define_insn "msa_insert_<msafmt_f>"
-  [(set (match_operand:MSA 0 "register_operand" "=f,f")
+  [(set (match_operand:MSA 0 "msa_reg_operand" "=f,f")
        (vec_merge:MSA
          (vec_duplicate:MSA
            (match_operand:<UNITMODE> 1 "reg_or_0_operand" "dJ,f"))
-         (match_operand:MSA 2 "register_operand" "0,0")
+         (match_operand:MSA 2 "msa_reg_operand" "0,0")
          (match_operand 3 "const_<bitmask>_operand" "")))]
   "ISA_HAS_MSA"
 {
@@ -495,11 +502,11 @@
    (set_attr "mode" "<MODE>")])
 
 (define_split
-  [(set (match_operand:MSA_D 0 "register_operand")
+  [(set (match_operand:MSA_D 0 "msa_reg_operand")
        (vec_merge:MSA_D
          (vec_duplicate:MSA_D
            (match_operand:<UNITMODE> 1 "<MSA_D:msa_d>_operand"))
-         (match_operand:MSA_D 2 "register_operand")
+         (match_operand:MSA_D 2 "msa_reg_operand")
          (match_operand 3 "const_<bitmask>_operand")))]
   "reload_completed && ISA_HAS_MSA && !TARGET_64BIT"
   [(const_int 0)]
@@ -511,13 +518,13 @@
 })
 
 (define_insn "msa_insve_<msafmt_f>"
-  [(set (match_operand:MSA 0 "register_operand" "=f")
+  [(set (match_operand:MSA 0 "msa_reg_operand" "=f")
        (vec_merge:MSA
          (vec_duplicate:MSA
            (vec_select:<UNITMODE>
-             (match_operand:MSA 1 "register_operand" "f")
+             (match_operand:MSA 1 "msa_reg_operand" "f")
              (parallel [(const_int 0)])))
-         (match_operand:MSA 2 "register_operand" "0")
+         (match_operand:MSA 2 "msa_reg_operand" "0")
          (match_operand 3 "const_<bitmask>_operand" "")))]
   "ISA_HAS_MSA"
   "insve.<msafmt>\t%w0[%y3],%w1[0]"
@@ -526,11 +533,11 @@
 
 ;; Operand 3 is a scalar.
 (define_insn "msa_insve_<msafmt_f>_scalar"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
        (vec_merge:FMSA
          (vec_duplicate:FMSA
-           (match_operand:<UNITMODE> 1 "register_operand" "f"))
-         (match_operand:FMSA 2 "register_operand" "0")
+           (match_operand:<UNITMODE> 1 "msa_reg_operand" "f"))
+         (match_operand:FMSA 2 "msa_reg_operand" "0")
          (match_operand 3 "const_<bitmask>_operand" "")))]
   "ISA_HAS_MSA"
   "insve.<msafmt>\t%w0[%y3],%w1[0]"
@@ -538,10 +545,10 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_copy_<su>_<msafmt>"
-  [(set (match_operand:<VRES> 0 "register_operand" "=d")
+  [(set (match_operand:<VRES> 0 "msa_reg_operand" "=d")
        (any_extend:<VRES>
          (vec_select:<UNITMODE>
-           (match_operand:IMSA_HB 1 "register_operand" "f")
+           (match_operand:IMSA_HB 1 "msa_reg_operand" "f")
            (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))]
   "ISA_HAS_MSA"
   "copy_<su>.<msafmt>\t%0,%w1[%2]"
@@ -549,10 +556,10 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_copy_u_w"
-  [(set (match_operand:DI 0 "register_operand" "=d")
+  [(set (match_operand:DI 0 "msa_reg_operand" "=d")
        (zero_extend:DI
          (vec_select:SI
-           (match_operand:V4SI 1 "register_operand" "f")
+           (match_operand:V4SI 1 "msa_reg_operand" "f")
            (parallel [(match_operand 2 "const_0_to_3_operand" "")]))))]
   "ISA_HAS_MSA && TARGET_64BIT"
   "copy_u.w\t%0,%w1[%2]"
@@ -560,10 +567,10 @@
    (set_attr "mode" "V4SI")])
 
 (define_insn "msa_copy_s_<msafmt_f>_64bit"
-  [(set (match_operand:DI 0 "register_operand" "=d")
+  [(set (match_operand:DI 0 "msa_reg_operand" "=d")
        (sign_extend:DI
          (vec_select:<UNITMODE>
-           (match_operand:MSA_W 1 "register_operand" "f")
+           (match_operand:MSA_W 1 "msa_reg_operand" "f")
            (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))]
   "ISA_HAS_MSA && TARGET_64BIT"
   "copy_s.<msafmt>\t%0,%w1[%2]"
@@ -571,9 +578,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_copy_s_<msafmt_f>"
-  [(set (match_operand:<UNITMODE> 0 "register_operand" "=d")
+  [(set (match_operand:<UNITMODE> 0 "msa_reg_operand" "=d")
        (vec_select:<UNITMODE>
-         (match_operand:MSA_W 1 "register_operand" "f")
+         (match_operand:MSA_W 1 "msa_reg_operand" "f")
          (parallel [(match_operand 2 "const_<indeximm>_operand" "")])))]
   "ISA_HAS_MSA"
   "copy_s.<msafmt>\t%0,%w1[%2]"
@@ -581,9 +588,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn_and_split "msa_copy_s_<msafmt_f>"
-  [(set (match_operand:<UNITMODE> 0 "register_operand" "=d")
+  [(set (match_operand:<UNITMODE> 0 "msa_reg_operand" "=d")
        (vec_select:<UNITMODE>
-         (match_operand:MSA_D 1 "register_operand" "f")
+         (match_operand:MSA_D 1 "msa_reg_operand" "f")
          (parallel [(match_operand 2 "const_<indeximm>_operand" "")])))]
   "ISA_HAS_MSA"
 {
@@ -603,8 +610,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_expand "abs<mode>2"
-  [(match_operand:IMSA 0 "register_operand" "=f")
-   (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))]
+  [(match_operand:IMSA 0 "msa_reg_operand" "=f")
+   (abs:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f"))]
   "ISA_HAS_MSA"
 {
   rtx reg = gen_reg_rtx (<MODE>mode);
@@ -614,9 +621,9 @@
 })
 
 (define_expand "neg<mode>2"
-  [(set (match_operand:IMSA 0 "register_operand")
+  [(set (match_operand:IMSA 0 "msa_reg_operand")
        (minus:IMSA (match_dup 2)
-                  (match_operand:IMSA 1 "register_operand")))]
+                  (match_operand:IMSA 1 "msa_reg_operand")))]
   "ISA_HAS_MSA"
 {
   rtx reg = gen_reg_rtx (<MODE>mode);
@@ -625,15 +632,15 @@
 })
 
 (define_insn "neg<mode>2"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (neg:FMSA (match_operand:FMSA 1 "register_operand" "f")))]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (neg:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "bnegi.<msafmt>\t%w0,%w1,<elmsgnbit>"
   [(set_attr "type" "simd_bit")
    (set_attr "mode" "<MODE>")])
 
 (define_expand "msa_ldi<mode>"
-  [(match_operand:IMSA 0 "register_operand")
+  [(match_operand:IMSA 0 "msa_reg_operand")
    (match_operand 1 "const_imm10_operand")]
   "ISA_HAS_MSA"
 {
@@ -646,10 +653,10 @@
 })
 
 (define_insn "vec_perm<mode>"
-  [(set (match_operand:MSA 0 "register_operand" "=f")
-       (unspec:MSA [(match_operand:MSA 1 "register_operand" "f")
-                    (match_operand:MSA 2 "register_operand" "f")
-                    (match_operand:<VIMODE> 3 "register_operand" "0")]
+  [(set (match_operand:MSA 0 "msa_reg_operand" "=f")
+       (unspec:MSA [(match_operand:MSA 1 "msa_reg_operand" "f")
+                    (match_operand:MSA 2 "msa_reg_operand" "f")
+                    (match_operand:<VIMODE> 3 "msa_reg_operand" "0")]
                    UNSPEC_MSA_VSHF))]
   "ISA_HAS_MSA"
   "vshf.<msafmt>\t%w0,%w2,%w1"
@@ -697,7 +704,7 @@
 
 ;; Offset load
 (define_expand "msa_ld_<msafmt_f>"
-  [(match_operand:MSA 0 "register_operand")
+  [(match_operand:MSA 0 "msa_reg_operand")
    (match_operand 1 "pmode_register_operand")
    (match_operand 2 "aq10<msafmt>_operand")]
   "ISA_HAS_MSA"
@@ -710,7 +717,7 @@
 
 ;; Offset store
 (define_expand "msa_st_<msafmt_f>"
-  [(match_operand:MSA 0 "register_operand")
+  [(match_operand:MSA 0 "msa_reg_operand")
    (match_operand 1 "pmode_register_operand")
    (match_operand 2 "aq10<msafmt>_operand")]
   "ISA_HAS_MSA"
@@ -723,9 +730,9 @@
 
 ;; Integer operations
 (define_insn "add<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f,f")
        (plus:IMSA
-         (match_operand:IMSA 1 "register_operand" "f,f,f")
+         (match_operand:IMSA 1 "msa_reg_operand" "f,f,f")
          (match_operand:IMSA 2 "reg_or_vector_same_ximm5_operand" 
"f,Unv5,Uuv5")))]
   "ISA_HAS_MSA"
 {
@@ -751,9 +758,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "sub<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
        (minus:IMSA
-         (match_operand:IMSA 1 "register_operand" "f,f")
+         (match_operand:IMSA 1 "msa_reg_operand" "f,f")
          (match_operand:IMSA 2 "reg_or_vector_same_uimm5_operand" "f,Uuv5")))]
   "ISA_HAS_MSA"
   "@
@@ -764,74 +771,74 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "mul<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (mult:IMSA (match_operand:IMSA 1 "register_operand" "f")
-                  (match_operand:IMSA 2 "register_operand" "f")))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (mult:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f")
+                  (match_operand:IMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "mulv.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_mul")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_maddv_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (plus:IMSA (mult:IMSA (match_operand:IMSA 1 "register_operand" "f")
-                             (match_operand:IMSA 2 "register_operand" "f"))
-                  (match_operand:IMSA 3 "register_operand" "0")))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (plus:IMSA (mult:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f")
+                             (match_operand:IMSA 2 "msa_reg_operand" "f"))
+                  (match_operand:IMSA 3 "msa_reg_operand" "0")))]
   "ISA_HAS_MSA"
   "maddv.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_mul")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_msubv_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (minus:IMSA (match_operand:IMSA 1 "register_operand" "0")
-                   (mult:IMSA (match_operand:IMSA 2 "register_operand" "f")
-                              (match_operand:IMSA 3 "register_operand" "f"))))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (minus:IMSA (match_operand:IMSA 1 "msa_reg_operand" "0")
+                   (mult:IMSA (match_operand:IMSA 2 "msa_reg_operand" "f")
+                              (match_operand:IMSA 3 "msa_reg_operand" "f"))))]
   "ISA_HAS_MSA"
   "msubv.<msafmt>\t%w0,%w2,%w3"
   [(set_attr "type" "simd_mul")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "div<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (div:IMSA (match_operand:IMSA 1 "register_operand" "f")
-                 (match_operand:IMSA 2 "register_operand" "f")))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (div:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f")
+                 (match_operand:IMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   { return mips_msa_output_division ("div_s.<msafmt>\t%w0,%w1,%w2", operands); 
}
   [(set_attr "type" "simd_div")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "udiv<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (udiv:IMSA (match_operand:IMSA 1 "register_operand" "f")
-                  (match_operand:IMSA 2 "register_operand" "f")))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (udiv:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f")
+                  (match_operand:IMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   { return mips_msa_output_division ("div_u.<msafmt>\t%w0,%w1,%w2", operands); 
}
   [(set_attr "type" "simd_div")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "mod<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (mod:IMSA (match_operand:IMSA 1 "register_operand" "f")
-                 (match_operand:IMSA 2 "register_operand" "f")))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (mod:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f")
+                 (match_operand:IMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   { return mips_msa_output_division ("mod_s.<msafmt>\t%w0,%w1,%w2", operands); 
}
   [(set_attr "type" "simd_div")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "umod<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (umod:IMSA (match_operand:IMSA 1 "register_operand" "f")
-                  (match_operand:IMSA 2 "register_operand" "f")))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (umod:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f")
+                  (match_operand:IMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   { return mips_msa_output_division ("mod_u.<msafmt>\t%w0,%w1,%w2", operands); 
}
   [(set_attr "type" "simd_div")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "xor<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f,f")
        (xor:IMSA
-         (match_operand:IMSA 1 "register_operand" "f,f,f")
+         (match_operand:IMSA 1 "msa_reg_operand" "f,f,f")
          (match_operand:IMSA 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
   "ISA_HAS_MSA"
   "@
@@ -842,9 +849,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "ior<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f,f")
        (ior:IMSA
-         (match_operand:IMSA 1 "register_operand" "f,f,f")
+         (match_operand:IMSA 1 "msa_reg_operand" "f,f,f")
          (match_operand:IMSA 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
   "ISA_HAS_MSA"
   "@
@@ -855,9 +862,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "and<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f,f")
        (and:IMSA
-         (match_operand:IMSA 1 "register_operand" "f,f,f")
+         (match_operand:IMSA 1 "msa_reg_operand" "f,f,f")
          (match_operand:IMSA 2 "reg_or_vector_same_val_operand" "f,YZ,Urv8")))]
   "ISA_HAS_MSA"
 {
@@ -882,17 +889,17 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "one_cmpl<mode>2"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (not:IMSA (match_operand:IMSA 1 "register_operand" "f")))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (not:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "nor.v\t%w0,%w1,%w1"
   [(set_attr "type" "simd_logic")
    (set_attr "mode" "TI")])
 
 (define_insn "vlshr<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
        (lshiftrt:IMSA
-         (match_operand:IMSA 1 "register_operand" "f,f")
+         (match_operand:IMSA 1 "msa_reg_operand" "f,f")
          (match_operand:IMSA 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
   "ISA_HAS_MSA"
 {
@@ -905,9 +912,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "vashr<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
        (ashiftrt:IMSA
-         (match_operand:IMSA 1 "register_operand" "f,f")
+         (match_operand:IMSA 1 "msa_reg_operand" "f,f")
          (match_operand:IMSA 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
   "ISA_HAS_MSA"
 {
@@ -920,9 +927,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "vashl<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
        (ashift:IMSA
-         (match_operand:IMSA 1 "register_operand" "f,f")
+         (match_operand:IMSA 1 "msa_reg_operand" "f,f")
          (match_operand:IMSA 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
   "ISA_HAS_MSA"
 {
@@ -936,64 +943,64 @@
 
 ;; Floating-point operations
 (define_insn "add<mode>3"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (plus:FMSA (match_operand:FMSA 1 "register_operand" "f")
-                  (match_operand:FMSA 2 "register_operand" "f")))]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (plus:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f")
+                  (match_operand:FMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "fadd.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_fadd")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "sub<mode>3"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (minus:FMSA (match_operand:FMSA 1 "register_operand" "f")
-                   (match_operand:FMSA 2 "register_operand" "f")))]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (minus:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f")
+                   (match_operand:FMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "fsub.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_fadd")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "mul<mode>3"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (mult:FMSA (match_operand:FMSA 1 "register_operand" "f")
-                  (match_operand:FMSA 2 "register_operand" "f")))]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (mult:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f")
+                  (match_operand:FMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "fmul.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_fmul")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "div<mode>3"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (div:FMSA (match_operand:FMSA 1 "register_operand" "f")
-                 (match_operand:FMSA 2 "register_operand" "f")))]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (div:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f")
+                 (match_operand:FMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "fdiv.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_fdiv")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "fma<mode>4"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (fma:FMSA (match_operand:FMSA 1 "register_operand" "f")
-                 (match_operand:FMSA 2 "register_operand" "f")
-                 (match_operand:FMSA 3 "register_operand" "0")))]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (fma:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f")
+                 (match_operand:FMSA 2 "msa_reg_operand" "f")
+                 (match_operand:FMSA 3 "msa_reg_operand" "0")))]
   "ISA_HAS_MSA"
   "fmadd.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_fmadd")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "fnma<mode>4"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (fma:FMSA (neg:FMSA (match_operand:FMSA 1 "register_operand" "f"))
-                 (match_operand:FMSA 2 "register_operand" "f")
-                 (match_operand:FMSA 3 "register_operand" "0")))]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (fma:FMSA (neg:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f"))
+                 (match_operand:FMSA 2 "msa_reg_operand" "f")
+                 (match_operand:FMSA 3 "msa_reg_operand" "0")))]
   "ISA_HAS_MSA"
   "fmsub.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_fmadd")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "sqrt<mode>2"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (sqrt:FMSA (match_operand:FMSA 1 "register_operand" "f")))]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (sqrt:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "fsqrt.<msafmt>\t%w0,%w1"
   [(set_attr "type" "simd_fdiv")
@@ -1001,46 +1008,46 @@
 
 ;; Built-in functions
 (define_insn "msa_add_a_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (plus:IMSA (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))
-                  (abs:IMSA (match_operand:IMSA 2 "register_operand" "f"))))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (plus:IMSA (abs:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f"))
+                  (abs:IMSA (match_operand:IMSA 2 "msa_reg_operand" "f"))))]
   "ISA_HAS_MSA"
   "add_a.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_int_arith")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_adds_a_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
        (ss_plus:IMSA
-         (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))
-         (abs:IMSA (match_operand:IMSA 2 "register_operand" "f"))))]
+         (abs:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f"))
+         (abs:IMSA (match_operand:IMSA 2 "msa_reg_operand" "f"))))]
   "ISA_HAS_MSA"
   "adds_a.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_int_arith")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "ssadd<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (ss_plus:IMSA (match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (ss_plus:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "adds_s.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_int_arith")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "usadd<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (us_plus:IMSA (match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (us_plus:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "adds_u.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_int_arith")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_asub_s_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_ASUB_S))]
   "ISA_HAS_MSA"
   "asub_s.<msafmt>\t%w0,%w1,%w2"
@@ -1048,9 +1055,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_asub_u_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_ASUB_U))]
   "ISA_HAS_MSA"
   "asub_u.<msafmt>\t%w0,%w1,%w2"
@@ -1058,9 +1065,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_ave_s_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_AVE_S))]
   "ISA_HAS_MSA"
   "ave_s.<msafmt>\t%w0,%w1,%w2"
@@ -1068,9 +1075,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_ave_u_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_AVE_U))]
   "ISA_HAS_MSA"
   "ave_u.<msafmt>\t%w0,%w1,%w2"
@@ -1078,9 +1085,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_aver_s_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_AVER_S))]
   "ISA_HAS_MSA"
   "aver_s.<msafmt>\t%w0,%w1,%w2"
@@ -1088,9 +1095,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_aver_u_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_AVER_U))]
   "ISA_HAS_MSA"
   "aver_u.<msafmt>\t%w0,%w1,%w2"
@@ -1098,9 +1105,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_bclr_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_BCLR))]
   "ISA_HAS_MSA"
   "bclr.<msafmt>\t%w0,%w1,%w2"
@@ -1108,8 +1115,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_bclri_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
                      (match_operand 2 "const_<bitimm>_operand" "")]
                     UNSPEC_MSA_BCLRI))]
   "ISA_HAS_MSA"
@@ -1118,10 +1125,10 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_binsl_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
-                     (match_operand:IMSA 2 "register_operand" "f")
-                     (match_operand:IMSA 3 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "0")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")
+                     (match_operand:IMSA 3 "msa_reg_operand" "f")]
                     UNSPEC_MSA_BINSL))]
   "ISA_HAS_MSA"
   "binsl.<msafmt>\t%w0,%w2,%w3"
@@ -1129,9 +1136,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_binsli_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
-                     (match_operand:IMSA 2 "register_operand" "f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "0")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")
                      (match_operand 3 "const_<bitimm>_operand" "")]
                     UNSPEC_MSA_BINSLI))]
   "ISA_HAS_MSA"
@@ -1140,10 +1147,10 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_binsr_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
-                     (match_operand:IMSA 2 "register_operand" "f")
-                     (match_operand:IMSA 3 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "0")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")
+                     (match_operand:IMSA 3 "msa_reg_operand" "f")]
                     UNSPEC_MSA_BINSR))]
   "ISA_HAS_MSA"
   "binsr.<msafmt>\t%w0,%w2,%w3"
@@ -1151,9 +1158,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_binsri_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
-                     (match_operand:IMSA 2 "register_operand" "f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "0")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")
                      (match_operand 3 "const_<bitimm>_operand" "")]
                     UNSPEC_MSA_BINSRI))]
   "ISA_HAS_MSA"
@@ -1162,11 +1169,11 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_bmnz_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
-       (ior:IMSA (and:IMSA (match_operand:IMSA 2 "register_operand" "f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
+       (ior:IMSA (and:IMSA (match_operand:IMSA 2 "msa_reg_operand" "f,f")
                            (match_operand:IMSA 3 
"reg_or_vector_same_val_operand" "f,Urv8"))
                  (and:IMSA (not:IMSA (match_dup 3))
-                           (match_operand:IMSA 1 "register_operand" "0,0"))))]
+                           (match_operand:IMSA 1 "msa_reg_operand" "0,0"))))]
   "ISA_HAS_MSA"
   "@
    bmnz.v\t%w0,%w2,%w3
@@ -1175,11 +1182,11 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_bmz_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
        (ior:IMSA (and:IMSA (not:IMSA
                              (match_operand:IMSA 3 
"reg_or_vector_same_val_operand" "f,Urv8"))
-                           (match_operand:IMSA 2 "register_operand" "f,f"))
-                 (and:IMSA (match_operand:IMSA 1 "register_operand" "0,0")
+                           (match_operand:IMSA 2 "msa_reg_operand" "f,f"))
+                 (and:IMSA (match_operand:IMSA 1 "msa_reg_operand" "0,0")
                            (match_dup 3))))]
   "ISA_HAS_MSA"
   "@
@@ -1189,9 +1196,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_bneg_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_BNEG))]
   "ISA_HAS_MSA"
   "bneg.<msafmt>\t%w0,%w1,%w2"
@@ -1199,8 +1206,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_bnegi_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
                       (match_operand 2 "const_msa_branch_operand" "")]
                     UNSPEC_MSA_BNEGI))]
   "ISA_HAS_MSA"
@@ -1209,10 +1216,10 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_bsel_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
        (ior:IMSA (and:IMSA (not:IMSA
-                             (match_operand:IMSA 1 "register_operand" "0,0"))
-                           (match_operand:IMSA 2 "register_operand" "f,f"))
+                             (match_operand:IMSA 1 "msa_reg_operand" "0,0"))
+                           (match_operand:IMSA 2 "msa_reg_operand" "f,f"))
                  (and:IMSA (match_dup 1)
                            (match_operand:IMSA 3 
"reg_or_vector_same_val_operand" "f,Urv8"))))]
   "ISA_HAS_MSA"
@@ -1223,9 +1230,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_bset_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_BSET))]
   "ISA_HAS_MSA"
   "bset.<msafmt>\t%w0,%w1,%w2"
@@ -1233,8 +1240,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_bseti_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
                      (match_operand 2 "const_<bitimm>_operand" "")]
                     UNSPEC_MSA_BSETI))]
   "ISA_HAS_MSA"
@@ -1266,9 +1273,9 @@
    (ltu  "u")])
 
 (define_insn "msa_c<ICC:icc>_<IMSA:msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
        (ICC:IMSA
-         (match_operand:IMSA 1 "register_operand" "f,f")
+         (match_operand:IMSA 1 "msa_reg_operand" "f,f")
          (match_operand:IMSA 2 "reg_or_vector_same_<ICC:cmpi>imm5_operand" 
"f,U<ICC:cmpi>v5")))]
   "ISA_HAS_MSA"
   "@
@@ -1278,16 +1285,16 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_dotp_<su>_d"
-  [(set (match_operand:V2DI 0 "register_operand" "=f")
+  [(set (match_operand:V2DI 0 "msa_reg_operand" "=f")
        (plus:V2DI
          (mult:V2DI
            (any_extend:V2DI
              (vec_select:V2SI
-               (match_operand:V4SI 1 "register_operand" "%f")
+               (match_operand:V4SI 1 "msa_reg_operand" "%f")
                (parallel [(const_int 0) (const_int 2)])))
            (any_extend:V2DI
              (vec_select:V2SI
-               (match_operand:V4SI 2 "register_operand" "f")
+               (match_operand:V4SI 2 "msa_reg_operand" "f")
                (parallel [(const_int 0) (const_int 2)]))))
          (mult:V2DI
            (any_extend:V2DI
@@ -1302,17 +1309,17 @@
    (set_attr "mode" "V2DI")])
 
 (define_insn "msa_dotp_<su>_w"
-  [(set (match_operand:V4SI 0 "register_operand" "=f")
+  [(set (match_operand:V4SI 0 "msa_reg_operand" "=f")
        (plus:V4SI
          (mult:V4SI
            (any_extend:V4SI
              (vec_select:V4HI
-               (match_operand:V8HI 1 "register_operand" "%f")
+               (match_operand:V8HI 1 "msa_reg_operand" "%f")
                (parallel [(const_int 0) (const_int 2)
                           (const_int 4) (const_int 6)])))
            (any_extend:V4SI
              (vec_select:V4HI
-               (match_operand:V8HI 2 "register_operand" "f")
+               (match_operand:V8HI 2 "msa_reg_operand" "f")
                (parallel [(const_int 0) (const_int 2)
                           (const_int 4) (const_int 6)]))))
          (mult:V4SI
@@ -1330,19 +1337,19 @@
    (set_attr "mode" "V4SI")])
 
 (define_insn "msa_dotp_<su>_h"
-  [(set (match_operand:V8HI 0 "register_operand" "=f")
+  [(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
        (plus:V8HI
          (mult:V8HI
            (any_extend:V8HI
              (vec_select:V8QI
-               (match_operand:V16QI 1 "register_operand" "%f")
+               (match_operand:V16QI 1 "msa_reg_operand" "%f")
                (parallel [(const_int 0) (const_int 2)
                           (const_int 4) (const_int 6)
                           (const_int 8) (const_int 10)
                           (const_int 12) (const_int 14)])))
            (any_extend:V8HI
              (vec_select:V8QI
-               (match_operand:V16QI 2 "register_operand" "f")
+               (match_operand:V16QI 2 "msa_reg_operand" "f")
                (parallel [(const_int 0) (const_int 2)
                           (const_int 4) (const_int 6)
                           (const_int 8) (const_int 10)
@@ -1366,17 +1373,17 @@
    (set_attr "mode" "V8HI")])
 
 (define_insn "msa_dpadd_<su>_d"
-  [(set (match_operand:V2DI 0 "register_operand" "=f")
+  [(set (match_operand:V2DI 0 "msa_reg_operand" "=f")
        (plus:V2DI
          (plus:V2DI
            (mult:V2DI
              (any_extend:V2DI
                (vec_select:V2SI
-                 (match_operand:V4SI 2 "register_operand" "%f")
+                 (match_operand:V4SI 2 "msa_reg_operand" "%f")
                  (parallel [(const_int 0) (const_int 2)])))
              (any_extend:V2DI
                (vec_select:V2SI
-                 (match_operand:V4SI 3 "register_operand" "f")
+                 (match_operand:V4SI 3 "msa_reg_operand" "f")
                  (parallel [(const_int 0) (const_int 2)]))))
            (mult:V2DI
              (any_extend:V2DI
@@ -1385,25 +1392,25 @@
              (any_extend:V2DI
                (vec_select:V2SI (match_dup 3)
                  (parallel [(const_int 1) (const_int 3)])))))
-         (match_operand:V2DI 1 "register_operand" "0")))]
+         (match_operand:V2DI 1 "msa_reg_operand" "0")))]
   "ISA_HAS_MSA"
   "dpadd_<su>.d\t%w0,%w2,%w3"
   [(set_attr "type" "simd_mul")
    (set_attr "mode" "V2DI")])
 
 (define_insn "msa_dpadd_<su>_w"
-  [(set (match_operand:V4SI 0 "register_operand" "=f")
+  [(set (match_operand:V4SI 0 "msa_reg_operand" "=f")
        (plus:V4SI
          (plus:V4SI
            (mult:V4SI
              (any_extend:V4SI
                (vec_select:V4HI
-                 (match_operand:V8HI 2 "register_operand" "%f")
+                 (match_operand:V8HI 2 "msa_reg_operand" "%f")
                  (parallel [(const_int 0) (const_int 2)
                             (const_int 4) (const_int 6)])))
              (any_extend:V4SI
                (vec_select:V4HI
-                 (match_operand:V8HI 3 "register_operand" "f")
+                 (match_operand:V8HI 3 "msa_reg_operand" "f")
                  (parallel [(const_int 0) (const_int 2)
                             (const_int 4) (const_int 6)]))))
            (mult:V4SI
@@ -1415,27 +1422,27 @@
                (vec_select:V4HI (match_dup 3)
                  (parallel [(const_int 1) (const_int 3)
                             (const_int 5) (const_int 7)])))))
-         (match_operand:V4SI 1 "register_operand" "0")))]
+         (match_operand:V4SI 1 "msa_reg_operand" "0")))]
   "ISA_HAS_MSA"
   "dpadd_<su>.w\t%w0,%w2,%w3"
   [(set_attr "type" "simd_mul")
    (set_attr "mode" "V4SI")])
 
 (define_insn "msa_dpadd_<su>_h"
-  [(set (match_operand:V8HI 0 "register_operand" "=f")
+  [(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
        (plus:V8HI
          (plus:V8HI
            (mult:V8HI
              (any_extend:V8HI
                (vec_select:V8QI
-                 (match_operand:V16QI 2 "register_operand" "%f")
+                 (match_operand:V16QI 2 "msa_reg_operand" "%f")
                  (parallel [(const_int 0) (const_int 2)
                             (const_int 4) (const_int 6)
                             (const_int 8) (const_int 10)
                             (const_int 12) (const_int 14)])))
              (any_extend:V8HI
                (vec_select:V8QI
-                 (match_operand:V16QI 3 "register_operand" "f")
+                 (match_operand:V16QI 3 "msa_reg_operand" "f")
                  (parallel [(const_int 0) (const_int 2)
                             (const_int 4) (const_int 6)
                             (const_int 8) (const_int 10)
@@ -1453,25 +1460,25 @@
                             (const_int 5) (const_int 7)
                             (const_int 9) (const_int 11)
                             (const_int 13) (const_int 15)])))))
-         (match_operand:V8HI 1 "register_operand" "0")))]
+         (match_operand:V8HI 1 "msa_reg_operand" "0")))]
   "ISA_HAS_MSA"
   "dpadd_<su>.h\t%w0,%w2,%w3"
   [(set_attr "type" "simd_mul")
    (set_attr "mode" "V8HI")])
 
 (define_insn "msa_dpsub_<su>_d"
-  [(set (match_operand:V2DI 0 "register_operand" "=f")
+  [(set (match_operand:V2DI 0 "msa_reg_operand" "=f")
        (minus:V2DI
-         (match_operand:V2DI 1 "register_operand" "0")
+         (match_operand:V2DI 1 "msa_reg_operand" "0")
          (plus:V2DI
            (mult:V2DI
              (any_extend:V2DI
                (vec_select:V2SI
-                 (match_operand:V4SI 2 "register_operand" "%f")
+                 (match_operand:V4SI 2 "msa_reg_operand" "%f")
                  (parallel [(const_int 0) (const_int 2)])))
              (any_extend:V2DI
                (vec_select:V2SI
-                 (match_operand:V4SI 3 "register_operand" "f")
+                 (match_operand:V4SI 3 "msa_reg_operand" "f")
                  (parallel [(const_int 0) (const_int 2)]))))
            (mult:V2DI
              (any_extend:V2DI
@@ -1486,19 +1493,19 @@
    (set_attr "mode" "V2DI")])
 
 (define_insn "msa_dpsub_<su>_w"
-  [(set (match_operand:V4SI 0 "register_operand" "=f")
+  [(set (match_operand:V4SI 0 "msa_reg_operand" "=f")
        (minus:V4SI
-         (match_operand:V4SI 1 "register_operand" "0")
+         (match_operand:V4SI 1 "msa_reg_operand" "0")
          (plus:V4SI
            (mult:V4SI
              (any_extend:V4SI
                (vec_select:V4HI
-                 (match_operand:V8HI 2 "register_operand" "%f")
+                 (match_operand:V8HI 2 "msa_reg_operand" "%f")
                  (parallel [(const_int 0) (const_int 2)
                             (const_int 4) (const_int 6)])))
              (any_extend:V4SI
                (vec_select:V4HI
-                 (match_operand:V8HI 3 "register_operand" "f")
+                 (match_operand:V8HI 3 "msa_reg_operand" "f")
                  (parallel [(const_int 0) (const_int 2)
                             (const_int 4) (const_int 6)]))))
            (mult:V4SI
@@ -1516,21 +1523,21 @@
    (set_attr "mode" "V4SI")])
 
 (define_insn "msa_dpsub_<su>_h"
-  [(set (match_operand:V8HI 0 "register_operand" "=f")
+  [(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
        (minus:V8HI
-         (match_operand:V8HI 1 "register_operand" "0")
+         (match_operand:V8HI 1 "msa_reg_operand" "0")
          (plus:V8HI
            (mult:V8HI
              (any_extend:V8HI
                (vec_select:V8QI
-                 (match_operand:V16QI 2 "register_operand" "%f")
+                 (match_operand:V16QI 2 "msa_reg_operand" "%f")
                  (parallel [(const_int 0) (const_int 2)
                             (const_int 4) (const_int 6)
                             (const_int 8) (const_int 10)
                             (const_int 12) (const_int 14)])))
              (any_extend:V8HI
                (vec_select:V8QI
-                 (match_operand:V16QI 3 "register_operand" "f")
+                 (match_operand:V16QI 3 "msa_reg_operand" "f")
                  (parallel [(const_int 0) (const_int 2)
                             (const_int 4) (const_int 6)
                             (const_int 8) (const_int 10)
@@ -1554,8 +1561,8 @@
    (set_attr "mode" "V8HI")])
 
 (define_insn "msa_fclass_<msafmt>"
-  [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
-       (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")]
+  [(set (match_operand:<VIMODE> 0 "msa_reg_operand" "=f")
+       (unspec:<VIMODE> [(match_operand:FMSA 1 "msa_reg_operand" "f")]
                         UNSPEC_MSA_FCLASS))]
   "ISA_HAS_MSA"
   "fclass.<msafmt>\t%w0,%w1"
@@ -1563,9 +1570,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_fcaf_<msafmt>"
-  [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
-       (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")
-                         (match_operand:FMSA 2 "register_operand" "f")]
+  [(set (match_operand:<VIMODE> 0 "msa_reg_operand" "=f")
+       (unspec:<VIMODE> [(match_operand:FMSA 1 "msa_reg_operand" "f")
+                         (match_operand:FMSA 2 "msa_reg_operand" "f")]
                         UNSPEC_MSA_FCAF))]
   "ISA_HAS_MSA"
   "fcaf.<msafmt>\t%w0,%w1,%w2"
@@ -1573,9 +1580,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_fcune_<FMSA:msafmt>"
-  [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
-       (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")
-                         (match_operand:FMSA 2 "register_operand" "f")]
+  [(set (match_operand:<VIMODE> 0 "msa_reg_operand" "=f")
+       (unspec:<VIMODE> [(match_operand:FMSA 1 "msa_reg_operand" "f")
+                         (match_operand:FMSA 2 "msa_reg_operand" "f")]
                         UNSPEC_MSA_FCUNE))]
   "ISA_HAS_MSA"
   "fcune.<FMSA:msafmt>\t%w0,%w1,%w2"
@@ -1614,18 +1621,18 @@
    (UNSPEC_MSA_FSLT  "fslt")])
 
 (define_insn "msa_<FCC:fcc>_<FMSA:msafmt>"
-  [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
-       (FCC:<VIMODE> (match_operand:FMSA 1 "register_operand" "f")
-                     (match_operand:FMSA 2 "register_operand" "f")))]
+  [(set (match_operand:<VIMODE> 0 "msa_reg_operand" "=f")
+       (FCC:<VIMODE> (match_operand:FMSA 1 "msa_reg_operand" "f")
+                     (match_operand:FMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "<FCC:fcc>.<FMSA:msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_fcmp")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_<fsc>_<FMSA:msafmt>"
-  [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
-       (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")
-                          (match_operand:FMSA 2 "register_operand" "f")]
+  [(set (match_operand:<VIMODE> 0 "msa_reg_operand" "=f")
+       (unspec:<VIMODE> [(match_operand:FMSA 1 "msa_reg_operand" "f")
+                          (match_operand:FMSA 2 "msa_reg_operand" "f")]
                         FSC_UNS))]
   "ISA_HAS_MSA"
   "<fsc>.<FMSA:msafmt>\t%w0,%w1,%w2"
@@ -1633,9 +1640,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_fexp2_<msafmt>"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")
-                     (match_operand:<VIMODE> 2 "register_operand" "f")]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (unspec:FMSA [(match_operand:FMSA 1 "msa_reg_operand" "f")
+                     (match_operand:<VIMODE> 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FEXP2))]
   "ISA_HAS_MSA"
   "fexp2.<msafmt>\t%w0,%w1,%w2"
@@ -1659,8 +1666,8 @@
    (V2DF "D2I")])
 
 (define_insn "float<fint><FMSA:mode>2"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (float:FMSA (match_operand:<VIMODE> 1 "register_operand" "f")))]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (float:FMSA (match_operand:<VIMODE> 1 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "ffint_s.<msafmt>\t%w0,%w1"
   [(set_attr "type" "simd_fcvt")
@@ -1668,9 +1675,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "floatuns<fint><FMSA:mode>2"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
        (unsigned_float:FMSA
-         (match_operand:<VIMODE> 1 "register_operand" "f")))]
+         (match_operand:<VIMODE> 1 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "ffint_u.<msafmt>\t%w0,%w1"
   [(set_attr "type" "simd_fcvt")
@@ -1682,8 +1689,8 @@
    (V2DF "V4SI")])
 
 (define_insn "msa_ffql_<msafmt>"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (unspec:FMSA [(match_operand:<FQ> 1 "register_operand" "f")]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (unspec:FMSA [(match_operand:<FQ> 1 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FFQL))]
   "ISA_HAS_MSA"
   "ffql.<msafmt>\t%w0,%w1"
@@ -1692,8 +1699,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_ffqr_<msafmt>"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (unspec:FMSA [(match_operand:<FQ> 1 "register_operand" "f")]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (unspec:FMSA [(match_operand:<FQ> 1 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FFQR))]
   "ISA_HAS_MSA"
   "ffqr.<msafmt>\t%w0,%w1"
@@ -1702,7 +1709,7 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_fill_<msafmt_f>"
-  [(set (match_operand:MSA 0 "register_operand" "=f,f")
+  [(set (match_operand:MSA 0 "msa_reg_operand" "=f,f")
        (vec_duplicate:MSA
          (match_operand:<UNITMODE> 1 "reg_or_0_operand" "d,J")))]
   "ISA_HAS_MSA"
@@ -1719,9 +1726,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_split
-  [(set (match_operand:MSA_D 0 "register_operand")
+  [(set (match_operand:MSA_D 0 "msa_reg_operand")
        (vec_duplicate:MSA_D
-         (match_operand:<UNITMODE> 1 "register_operand")))]
+         (match_operand:<UNITMODE> 1 "msa_reg_operand")))]
   "reload_completed && ISA_HAS_MSA && !TARGET_64BIT"
   [(const_int 0)]
 {
@@ -1730,8 +1737,8 @@
 })
 
 (define_insn "msa_flog2_<msafmt>"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (unspec:FMSA [(match_operand:FMSA 1 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FLOG2))]
   "ISA_HAS_MSA"
   "flog2.<msafmt>\t%w0,%w1"
@@ -1739,19 +1746,19 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "smax<mode>3"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (smax:FMSA (match_operand:FMSA 1 "register_operand" "f")
-                  (match_operand:FMSA 2 "register_operand" "f")))]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (smax:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f")
+                  (match_operand:FMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "fmax.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_fminmax")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_fmax_a_<msafmt>"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
        (if_then_else:FMSA
-          (gt (abs:FMSA (match_operand:FMSA 1 "register_operand" "f"))
-              (abs:FMSA (match_operand:FMSA 2 "register_operand" "f")))
+          (gt (abs:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f"))
+              (abs:FMSA (match_operand:FMSA 2 "msa_reg_operand" "f")))
           (match_dup 1)
           (match_dup 2)))]
   "ISA_HAS_MSA"
@@ -1760,19 +1767,19 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "smin<mode>3"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (smin:FMSA (match_operand:FMSA 1 "register_operand" "f")
-                  (match_operand:FMSA 2 "register_operand" "f")))]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (smin:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f")
+                  (match_operand:FMSA 2 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "fmin.<msafmt>\t%w0,%w1,%w2"
   [(set_attr "type" "simd_fminmax")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_fmin_a_<msafmt>"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
        (if_then_else:FMSA
-          (lt (abs:FMSA (match_operand:FMSA 1 "register_operand" "f"))
-              (abs:FMSA (match_operand:FMSA 2 "register_operand" "f")))
+          (lt (abs:FMSA (match_operand:FMSA 1 "msa_reg_operand" "f"))
+              (abs:FMSA (match_operand:FMSA 2 "msa_reg_operand" "f")))
           (match_dup 1)
           (match_dup 2)))]
   "ISA_HAS_MSA"
@@ -1781,8 +1788,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_frcp_<msafmt>"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (unspec:FMSA [(match_operand:FMSA 1 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FRCP))]
   "ISA_HAS_MSA"
   "frcp.<msafmt>\t%w0,%w1"
@@ -1790,8 +1797,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_frint_<msafmt>"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (unspec:FMSA [(match_operand:FMSA 1 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FRINT))]
   "ISA_HAS_MSA"
   "frint.<msafmt>\t%w0,%w1"
@@ -1799,8 +1806,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_frsqrt_<msafmt>"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (unspec:FMSA [(match_operand:FMSA 1 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FRSQRT))]
   "ISA_HAS_MSA"
   "frsqrt.<msafmt>\t%w0,%w1"
@@ -1808,8 +1815,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_ftint_s_<msafmt>"
-  [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
-       (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")]
+  [(set (match_operand:<VIMODE> 0 "msa_reg_operand" "=f")
+       (unspec:<VIMODE> [(match_operand:FMSA 1 "msa_reg_operand" "f")]
                         UNSPEC_MSA_FTINT_S))]
   "ISA_HAS_MSA"
   "ftint_s.<msafmt>\t%w0,%w1"
@@ -1818,8 +1825,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_ftint_u_<msafmt>"
-  [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
-       (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")]
+  [(set (match_operand:<VIMODE> 0 "msa_reg_operand" "=f")
+       (unspec:<VIMODE> [(match_operand:FMSA 1 "msa_reg_operand" "f")]
                         UNSPEC_MSA_FTINT_U))]
   "ISA_HAS_MSA"
   "ftint_u.<msafmt>\t%w0,%w1"
@@ -1828,8 +1835,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "fix_trunc<FMSA:mode><mode_i>2"
-  [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
-       (fix:<VIMODE> (match_operand:FMSA 1 "register_operand" "f")))]
+  [(set (match_operand:<VIMODE> 0 "msa_reg_operand" "=f")
+       (fix:<VIMODE> (match_operand:FMSA 1 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "ftrunc_s.<msafmt>\t%w0,%w1"
   [(set_attr "type" "simd_fcvt")
@@ -1837,8 +1844,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "fixuns_trunc<FMSA:mode><mode_i>2"
-  [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
-       (unsigned_fix:<VIMODE> (match_operand:FMSA 1 "register_operand" "f")))]
+  [(set (match_operand:<VIMODE> 0 "msa_reg_operand" "=f")
+       (unsigned_fix:<VIMODE> (match_operand:FMSA 1 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "ftrunc_u.<msafmt>\t%w0,%w1"
   [(set_attr "type" "simd_fcvt")
@@ -1846,9 +1853,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_ftq_h"
-  [(set (match_operand:V8HI 0 "register_operand" "=f")
-       (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "f")
-                     (match_operand:V4SF 2 "register_operand" "f")]
+  [(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
+       (unspec:V8HI [(match_operand:V4SF 1 "msa_reg_operand" "f")
+                     (match_operand:V4SF 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FTQ))]
   "ISA_HAS_MSA"
   "ftq.h\t%w0,%w1,%w2"
@@ -1857,9 +1864,9 @@
    (set_attr "mode" "V4SF")])
 
 (define_insn "msa_ftq_w"
-  [(set (match_operand:V4SI 0 "register_operand" "=f")
-       (unspec:V4SI [(match_operand:V2DF 1 "register_operand" "f")
-                     (match_operand:V2DF 2 "register_operand" "f")]
+  [(set (match_operand:V4SI 0 "msa_reg_operand" "=f")
+       (unspec:V4SI [(match_operand:V2DF 1 "msa_reg_operand" "f")
+                     (match_operand:V2DF 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FTQ))]
   "ISA_HAS_MSA"
   "ftq.w\t%w0,%w1,%w2"
@@ -1868,18 +1875,18 @@
    (set_attr "mode" "V2DF")])
 
 (define_insn "msa_h<optab>_<su>_h"
-  [(set (match_operand:V8HI 0 "register_operand" "=f")
+  [(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
        (addsub:V8HI
          (any_extend:V8HI
            (vec_select:V8QI
-             (match_operand:V16QI 1 "register_operand" "f")
+             (match_operand:V16QI 1 "msa_reg_operand" "f")
              (parallel [(const_int 1) (const_int 3)
                         (const_int 5) (const_int 7)
                         (const_int 9) (const_int 11)
                         (const_int 13) (const_int 15)])))
          (any_extend:V8HI
            (vec_select:V8QI
-             (match_operand:V16QI 2 "register_operand" "f")
+             (match_operand:V16QI 2 "msa_reg_operand" "f")
              (parallel [(const_int 0) (const_int 2)
                         (const_int 4) (const_int 6)
                         (const_int 8) (const_int 10)
@@ -1890,16 +1897,16 @@
    (set_attr "mode" "V8HI")])
 
 (define_insn "msa_h<optab>_<su>_w"
-  [(set (match_operand:V4SI 0 "register_operand" "=f")
+  [(set (match_operand:V4SI 0 "msa_reg_operand" "=f")
        (addsub:V4SI
          (any_extend:V4SI
            (vec_select:V4HI
-             (match_operand:V8HI 1 "register_operand" "f")
+             (match_operand:V8HI 1 "msa_reg_operand" "f")
              (parallel [(const_int 1) (const_int 3)
                         (const_int 5) (const_int 7)])))
          (any_extend:V4SI
            (vec_select:V4HI
-             (match_operand:V8HI 2 "register_operand" "f")
+             (match_operand:V8HI 2 "msa_reg_operand" "f")
              (parallel [(const_int 0) (const_int 2)
                         (const_int 4) (const_int 6)])))))]
   "ISA_HAS_MSA"
@@ -1908,15 +1915,15 @@
    (set_attr "mode" "V4SI")])
 
 (define_insn "msa_h<optab>_<su>_d"
-  [(set (match_operand:V2DI 0 "register_operand" "=f")
+  [(set (match_operand:V2DI 0 "msa_reg_operand" "=f")
        (addsub:V2DI
          (any_extend:V2DI
            (vec_select:V2SI
-             (match_operand:V4SI 1 "register_operand" "f")
+             (match_operand:V4SI 1 "msa_reg_operand" "f")
              (parallel [(const_int 1) (const_int 3)])))
          (any_extend:V2DI
            (vec_select:V2SI
-             (match_operand:V4SI 2 "register_operand" "f")
+             (match_operand:V4SI 2 "msa_reg_operand" "f")
              (parallel [(const_int 0) (const_int 2)])))))]
   "ISA_HAS_MSA"
   "h<optab>_<su>.d\t%w0,%w1,%w2"
@@ -1924,11 +1931,11 @@
    (set_attr "mode" "V2DI")])
 
 (define_insn "msa_ilvev_b"
-  [(set (match_operand:V16QI 0 "register_operand" "=f")
+  [(set (match_operand:V16QI 0 "msa_reg_operand" "=f")
        (vec_select:V16QI
          (vec_concat:V32QI
-           (match_operand:V16QI 1 "register_operand" "f")
-           (match_operand:V16QI 2 "register_operand" "f"))
+           (match_operand:V16QI 1 "msa_reg_operand" "f")
+           (match_operand:V16QI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 0)  (const_int 16)
                     (const_int 2)  (const_int 18)
                     (const_int 4)  (const_int 20)
@@ -1943,11 +1950,11 @@
    (set_attr "mode" "V16QI")])
 
 (define_insn "msa_ilvev_h"
-  [(set (match_operand:V8HI 0 "register_operand" "=f")
+  [(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
        (vec_select:V8HI
          (vec_concat:V16HI
-           (match_operand:V8HI 1 "register_operand" "f")
-           (match_operand:V8HI 2 "register_operand" "f"))
+           (match_operand:V8HI 1 "msa_reg_operand" "f")
+           (match_operand:V8HI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 0) (const_int 8)
                     (const_int 2) (const_int 10)
                     (const_int 4) (const_int 12)
@@ -1958,11 +1965,11 @@
    (set_attr "mode" "V8HI")])
 
 (define_insn "msa_ilvev_w"
-  [(set (match_operand:V4SI 0 "register_operand" "=f")
+  [(set (match_operand:V4SI 0 "msa_reg_operand" "=f")
        (vec_select:V4SI
          (vec_concat:V8SI
-           (match_operand:V4SI 1 "register_operand" "f")
-           (match_operand:V4SI 2 "register_operand" "f"))
+           (match_operand:V4SI 1 "msa_reg_operand" "f")
+           (match_operand:V4SI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 0) (const_int 4)
                     (const_int 2) (const_int 6)])))]
   "ISA_HAS_MSA"
@@ -1971,11 +1978,11 @@
    (set_attr "mode" "V4SI")])
 
 (define_insn "msa_ilvev_w_f"
-  [(set (match_operand:V4SF 0 "register_operand" "=f")
+  [(set (match_operand:V4SF 0 "msa_reg_operand" "=f")
        (vec_select:V4SF
          (vec_concat:V8SF
-           (match_operand:V4SF 1 "register_operand" "f")
-           (match_operand:V4SF 2 "register_operand" "f"))
+           (match_operand:V4SF 1 "msa_reg_operand" "f")
+           (match_operand:V4SF 2 "msa_reg_operand" "f"))
          (parallel [(const_int 0) (const_int 4)
                     (const_int 2) (const_int 6)])))]
   "ISA_HAS_MSA"
@@ -1984,11 +1991,11 @@
    (set_attr "mode" "V4SF")])
 
 (define_insn "msa_ilvl_b"
-  [(set (match_operand:V16QI 0 "register_operand" "=f")
+  [(set (match_operand:V16QI 0 "msa_reg_operand" "=f")
        (vec_select:V16QI
          (vec_concat:V32QI
-           (match_operand:V16QI 1 "register_operand" "f")
-           (match_operand:V16QI 2 "register_operand" "f"))
+           (match_operand:V16QI 1 "msa_reg_operand" "f")
+           (match_operand:V16QI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 8)  (const_int 24)
                     (const_int 9)  (const_int 25)
                     (const_int 10) (const_int 26)
@@ -2003,11 +2010,11 @@
    (set_attr "mode" "V16QI")])
 
 (define_insn "msa_ilvl_h"
-  [(set (match_operand:V8HI 0 "register_operand" "=f")
+  [(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
        (vec_select:V8HI
          (vec_concat:V16HI
-           (match_operand:V8HI 1 "register_operand" "f")
-           (match_operand:V8HI 2 "register_operand" "f"))
+           (match_operand:V8HI 1 "msa_reg_operand" "f")
+           (match_operand:V8HI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 4) (const_int 12)
                     (const_int 5) (const_int 13)
                     (const_int 6) (const_int 14)
@@ -2018,11 +2025,11 @@
    (set_attr "mode" "V8HI")])
 
 (define_insn "msa_ilvl_w"
-  [(set (match_operand:V4SI 0 "register_operand" "=f")
+  [(set (match_operand:V4SI 0 "msa_reg_operand" "=f")
        (vec_select:V4SI
          (vec_concat:V8SI
-           (match_operand:V4SI 1 "register_operand" "f")
-           (match_operand:V4SI 2 "register_operand" "f"))
+           (match_operand:V4SI 1 "msa_reg_operand" "f")
+           (match_operand:V4SI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 2) (const_int 6)
                     (const_int 3) (const_int 7)])))]
   "ISA_HAS_MSA"
@@ -2031,11 +2038,11 @@
    (set_attr "mode" "V4SI")])
 
 (define_insn "msa_ilvl_w_f"
-  [(set (match_operand:V4SF 0 "register_operand" "=f")
+  [(set (match_operand:V4SF 0 "msa_reg_operand" "=f")
        (vec_select:V4SF
          (vec_concat:V8SF
-           (match_operand:V4SF 1 "register_operand" "f")
-           (match_operand:V4SF 2 "register_operand" "f"))
+           (match_operand:V4SF 1 "msa_reg_operand" "f")
+           (match_operand:V4SF 2 "msa_reg_operand" "f"))
          (parallel [(const_int 2) (const_int 6)
                     (const_int 3) (const_int 7)])))]
   "ISA_HAS_MSA"
@@ -2044,11 +2051,11 @@
    (set_attr "mode" "V4SF")])
 
 (define_insn "msa_ilvl_d"
-  [(set (match_operand:V2DI 0 "register_operand" "=f")
+  [(set (match_operand:V2DI 0 "msa_reg_operand" "=f")
        (vec_select:V2DI
          (vec_concat:V4DI
-           (match_operand:V2DI 1 "register_operand" "f")
-           (match_operand:V2DI 2 "register_operand" "f"))
+           (match_operand:V2DI 1 "msa_reg_operand" "f")
+           (match_operand:V2DI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 1) (const_int 3)])))]
   "ISA_HAS_MSA"
   "ilvl.d\t%w0,%w2,%w1"
@@ -2056,11 +2063,11 @@
    (set_attr "mode" "V2DI")])
 
 (define_insn "msa_ilvl_d_f"
-  [(set (match_operand:V2DF 0 "register_operand" "=f")
+  [(set (match_operand:V2DF 0 "msa_reg_operand" "=f")
        (vec_select:V2DF
          (vec_concat:V4DF
-           (match_operand:V2DF 1 "register_operand" "f")
-           (match_operand:V2DF 2 "register_operand" "f"))
+           (match_operand:V2DF 1 "msa_reg_operand" "f")
+           (match_operand:V2DF 2 "msa_reg_operand" "f"))
          (parallel [(const_int 1) (const_int 3)])))]
   "ISA_HAS_MSA"
   "ilvl.d\t%w0,%w2,%w1"
@@ -2068,11 +2075,11 @@
    (set_attr "mode" "V2DF")])
 
 (define_insn "msa_ilvod_b"
-  [(set (match_operand:V16QI 0 "register_operand" "=f")
+  [(set (match_operand:V16QI 0 "msa_reg_operand" "=f")
        (vec_select:V16QI
          (vec_concat:V32QI
-           (match_operand:V16QI 1 "register_operand" "f")
-           (match_operand:V16QI 2 "register_operand" "f"))
+           (match_operand:V16QI 1 "msa_reg_operand" "f")
+           (match_operand:V16QI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 1)  (const_int 17)
                     (const_int 3)  (const_int 19)
                     (const_int 5)  (const_int 21)
@@ -2087,11 +2094,11 @@
    (set_attr "mode" "V16QI")])
 
 (define_insn "msa_ilvod_h"
-  [(set (match_operand:V8HI 0 "register_operand" "=f")
+  [(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
        (vec_select:V8HI
          (vec_concat:V16HI
-           (match_operand:V8HI 1 "register_operand" "f")
-           (match_operand:V8HI 2 "register_operand" "f"))
+           (match_operand:V8HI 1 "msa_reg_operand" "f")
+           (match_operand:V8HI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 1) (const_int 9)
                     (const_int 3) (const_int 11)
                     (const_int 5) (const_int 13)
@@ -2102,11 +2109,11 @@
    (set_attr "mode" "V8HI")])
 
 (define_insn "msa_ilvod_w"
-  [(set (match_operand:V4SI 0 "register_operand" "=f")
+  [(set (match_operand:V4SI 0 "msa_reg_operand" "=f")
        (vec_select:V4SI
          (vec_concat:V8SI
-           (match_operand:V4SI 1 "register_operand" "f")
-           (match_operand:V4SI 2 "register_operand" "f"))
+           (match_operand:V4SI 1 "msa_reg_operand" "f")
+           (match_operand:V4SI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 1) (const_int 5)
                     (const_int 3) (const_int 7)])))]
   "ISA_HAS_MSA"
@@ -2115,11 +2122,11 @@
    (set_attr "mode" "V4SI")])
 
 (define_insn "msa_ilvod_w_f"
-  [(set (match_operand:V4SF 0 "register_operand" "=f")
+  [(set (match_operand:V4SF 0 "msa_reg_operand" "=f")
        (vec_select:V4SF
          (vec_concat:V8SF
-           (match_operand:V4SF 1 "register_operand" "f")
-           (match_operand:V4SF 2 "register_operand" "f"))
+           (match_operand:V4SF 1 "msa_reg_operand" "f")
+           (match_operand:V4SF 2 "msa_reg_operand" "f"))
          (parallel [(const_int 1) (const_int 5)
                     (const_int 3) (const_int 7)])))]
   "ISA_HAS_MSA"
@@ -2128,11 +2135,11 @@
    (set_attr "mode" "V4SF")])
 
 (define_insn "msa_ilvr_b"
-  [(set (match_operand:V16QI 0 "register_operand" "=f")
+  [(set (match_operand:V16QI 0 "msa_reg_operand" "=f")
        (vec_select:V16QI
          (vec_concat:V32QI
-           (match_operand:V16QI 1 "register_operand" "f")
-           (match_operand:V16QI 2 "register_operand" "f"))
+           (match_operand:V16QI 1 "msa_reg_operand" "f")
+           (match_operand:V16QI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 0) (const_int 16)
                     (const_int 1) (const_int 17)
                     (const_int 2) (const_int 18)
@@ -2147,11 +2154,11 @@
    (set_attr "mode" "V16QI")])
 
 (define_insn "msa_ilvr_h"
-  [(set (match_operand:V8HI 0 "register_operand" "=f")
+  [(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
        (vec_select:V8HI
          (vec_concat:V16HI
-           (match_operand:V8HI 1 "register_operand" "f")
-           (match_operand:V8HI 2 "register_operand" "f"))
+           (match_operand:V8HI 1 "msa_reg_operand" "f")
+           (match_operand:V8HI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 0) (const_int 8)
                     (const_int 1) (const_int 9)
                     (const_int 2) (const_int 10)
@@ -2162,11 +2169,11 @@
    (set_attr "mode" "V8HI")])
 
 (define_insn "msa_ilvr_w"
-  [(set (match_operand:V4SI 0 "register_operand" "=f")
+  [(set (match_operand:V4SI 0 "msa_reg_operand" "=f")
        (vec_select:V4SI
          (vec_concat:V8SI
-           (match_operand:V4SI 1 "register_operand" "f")
-           (match_operand:V4SI 2 "register_operand" "f"))
+           (match_operand:V4SI 1 "msa_reg_operand" "f")
+           (match_operand:V4SI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 0) (const_int 4)
                     (const_int 1) (const_int 5)])))]
   "ISA_HAS_MSA"
@@ -2175,11 +2182,11 @@
    (set_attr "mode" "V4SI")])
 
 (define_insn "msa_ilvr_w_f"
-  [(set (match_operand:V4SF 0 "register_operand" "=f")
+  [(set (match_operand:V4SF 0 "msa_reg_operand" "=f")
        (vec_select:V4SF
          (vec_concat:V8SF
-           (match_operand:V4SF 1 "register_operand" "f")
-           (match_operand:V4SF 2 "register_operand" "f"))
+           (match_operand:V4SF 1 "msa_reg_operand" "f")
+           (match_operand:V4SF 2 "msa_reg_operand" "f"))
          (parallel [(const_int 0) (const_int 4)
                     (const_int 1) (const_int 5)])))]
   "ISA_HAS_MSA"
@@ -2188,11 +2195,11 @@
    (set_attr "mode" "V4SF")])
 
 (define_insn "msa_ilvr_d"
-  [(set (match_operand:V2DI 0 "register_operand" "=f")
+  [(set (match_operand:V2DI 0 "msa_reg_operand" "=f")
        (vec_select:V2DI
          (vec_concat:V4DI
-           (match_operand:V2DI 1 "register_operand" "f")
-           (match_operand:V2DI 2 "register_operand" "f"))
+           (match_operand:V2DI 1 "msa_reg_operand" "f")
+           (match_operand:V2DI 2 "msa_reg_operand" "f"))
          (parallel [(const_int 0) (const_int 2)])))]
   "ISA_HAS_MSA"
   "ilvr.d\t%w0,%w2,%w1"
@@ -2200,11 +2207,11 @@
    (set_attr "mode" "V2DI")])
 
 (define_insn "msa_ilvr_d_f"
-  [(set (match_operand:V2DF 0 "register_operand" "=f")
+  [(set (match_operand:V2DF 0 "msa_reg_operand" "=f")
        (vec_select:V2DF
          (vec_concat:V4DF
-           (match_operand:V2DF 1 "register_operand" "f")
-           (match_operand:V2DF 2 "register_operand" "f"))
+           (match_operand:V2DF 1 "msa_reg_operand" "f")
+           (match_operand:V2DF 2 "msa_reg_operand" "f"))
          (parallel [(const_int 0) (const_int 2)])))]
   "ISA_HAS_MSA"
   "ilvr.d\t%w0,%w2,%w1"
@@ -2212,10 +2219,10 @@
    (set_attr "mode" "V2DF")])
 
 (define_insn "msa_madd_q_<msafmt>"
-  [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
-       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0")
-                        (match_operand:IMSA_WH 2 "register_operand" "f")
-                        (match_operand:IMSA_WH 3 "register_operand" "f")]
+  [(set (match_operand:IMSA_WH 0 "msa_reg_operand" "=f")
+       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "msa_reg_operand" "0")
+                        (match_operand:IMSA_WH 2 "msa_reg_operand" "f")
+                        (match_operand:IMSA_WH 3 "msa_reg_operand" "f")]
                        UNSPEC_MSA_MADD_Q))]
   "ISA_HAS_MSA"
   "madd_q.<msafmt>\t%w0,%w2,%w3"
@@ -2223,10 +2230,10 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_maddr_q_<msafmt>"
-  [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
-       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0")
-                        (match_operand:IMSA_WH 2 "register_operand" "f")
-                        (match_operand:IMSA_WH 3 "register_operand" "f")]
+  [(set (match_operand:IMSA_WH 0 "msa_reg_operand" "=f")
+       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "msa_reg_operand" "0")
+                        (match_operand:IMSA_WH 2 "msa_reg_operand" "f")
+                        (match_operand:IMSA_WH 3 "msa_reg_operand" "f")]
                        UNSPEC_MSA_MADDR_Q))]
   "ISA_HAS_MSA"
   "maddr_q.<msafmt>\t%w0,%w2,%w3"
@@ -2234,10 +2241,10 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_max_a_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
        (if_then_else:IMSA
-          (gt (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))
-              (abs:IMSA (match_operand:IMSA 2 "register_operand" "f")))
+          (gt (abs:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f"))
+              (abs:IMSA (match_operand:IMSA 2 "msa_reg_operand" "f")))
           (match_dup 1)
           (match_dup 2)))]
   "ISA_HAS_MSA"
@@ -2246,8 +2253,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "smax<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
-       (smax:IMSA (match_operand:IMSA 1 "register_operand" "f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
+       (smax:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f,f")
                   (match_operand:IMSA 2 "reg_or_vector_same_simm5_operand" 
"f,Usv5")))]
   "ISA_HAS_MSA"
   "@
@@ -2257,8 +2264,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "umax<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
-       (umax:IMSA (match_operand:IMSA 1 "register_operand" "f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
+       (umax:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f,f")
                   (match_operand:IMSA 2 "reg_or_vector_same_uimm5_operand" 
"f,Uuv5")))]
   "ISA_HAS_MSA"
   "@
@@ -2268,10 +2275,10 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_min_a_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
        (if_then_else:IMSA
-          (lt (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))
-              (abs:IMSA (match_operand:IMSA 2 "register_operand" "f")))
+          (lt (abs:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f"))
+              (abs:IMSA (match_operand:IMSA 2 "msa_reg_operand" "f")))
           (match_dup 1)
           (match_dup 2)))]
   "ISA_HAS_MSA"
@@ -2280,8 +2287,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "smin<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
-       (smin:IMSA (match_operand:IMSA 1 "register_operand" "f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
+       (smin:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f,f")
                   (match_operand:IMSA 2 "reg_or_vector_same_simm5_operand" 
"f,Usv5")))]
   "ISA_HAS_MSA"
   "@
@@ -2291,8 +2298,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "umin<mode>3"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
-       (umin:IMSA (match_operand:IMSA 1 "register_operand" "f,f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
+       (umin:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f,f")
                   (match_operand:IMSA 2 "reg_or_vector_same_uimm5_operand" 
"f,Uuv5")))]
   "ISA_HAS_MSA"
   "@
@@ -2302,10 +2309,10 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_msub_q_<msafmt>"
-  [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
-       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0")
-                        (match_operand:IMSA_WH 2 "register_operand" "f")
-                        (match_operand:IMSA_WH 3 "register_operand" "f")]
+  [(set (match_operand:IMSA_WH 0 "msa_reg_operand" "=f")
+       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "msa_reg_operand" "0")
+                        (match_operand:IMSA_WH 2 "msa_reg_operand" "f")
+                        (match_operand:IMSA_WH 3 "msa_reg_operand" "f")]
                        UNSPEC_MSA_MSUB_Q))]
   "ISA_HAS_MSA"
   "msub_q.<msafmt>\t%w0,%w2,%w3"
@@ -2313,10 +2320,10 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_msubr_q_<msafmt>"
-  [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
-       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0")
-                        (match_operand:IMSA_WH 2 "register_operand" "f")
-                        (match_operand:IMSA_WH 3 "register_operand" "f")]
+  [(set (match_operand:IMSA_WH 0 "msa_reg_operand" "=f")
+       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "msa_reg_operand" "0")
+                        (match_operand:IMSA_WH 2 "msa_reg_operand" "f")
+                        (match_operand:IMSA_WH 3 "msa_reg_operand" "f")]
                        UNSPEC_MSA_MSUBR_Q))]
   "ISA_HAS_MSA"
   "msubr_q.<msafmt>\t%w0,%w2,%w3"
@@ -2324,9 +2331,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_mul_q_<msafmt>"
-  [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
-       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "f")
-                        (match_operand:IMSA_WH 2 "register_operand" "f")]
+  [(set (match_operand:IMSA_WH 0 "msa_reg_operand" "=f")
+       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "msa_reg_operand" "f")
+                        (match_operand:IMSA_WH 2 "msa_reg_operand" "f")]
                        UNSPEC_MSA_MUL_Q))]
   "ISA_HAS_MSA"
   "mul_q.<msafmt>\t%w0,%w1,%w2"
@@ -2334,9 +2341,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_mulr_q_<msafmt>"
-  [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
-       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "f")
-                        (match_operand:IMSA_WH 2 "register_operand" "f")]
+  [(set (match_operand:IMSA_WH 0 "msa_reg_operand" "=f")
+       (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "msa_reg_operand" "f")
+                        (match_operand:IMSA_WH 2 "msa_reg_operand" "f")]
                        UNSPEC_MSA_MULR_Q))]
   "ISA_HAS_MSA"
   "mulr_q.<msafmt>\t%w0,%w1,%w2"
@@ -2344,8 +2351,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_nloc_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")]
                     UNSPEC_MSA_NLOC))]
   "ISA_HAS_MSA"
   "nloc.<msafmt>\t%w0,%w1"
@@ -2353,16 +2360,16 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "clz<mode>2"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (clz:IMSA (match_operand:IMSA 1 "register_operand" "f")))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (clz:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "nlzc.<msafmt>\t%w0,%w1"
   [(set_attr "type" "simd_bit")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_nor_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f,f")
-       (and:IMSA (not:IMSA (match_operand:IMSA 1 "register_operand" "f,f"))
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f,f")
+       (and:IMSA (not:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f,f"))
                  (not:IMSA (match_operand:IMSA 2 
"reg_or_vector_same_val_operand" "f,Urv8"))))]
   "ISA_HAS_MSA"
   "@
@@ -2372,11 +2379,11 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_pckev_b"
-[(set (match_operand:V16QI 0 "register_operand" "=f")
+[(set (match_operand:V16QI 0 "msa_reg_operand" "=f")
       (vec_select:V16QI
        (vec_concat:V32QI
-         (match_operand:V16QI 1 "register_operand" "f")
-         (match_operand:V16QI 2 "register_operand" "f"))
+         (match_operand:V16QI 1 "msa_reg_operand" "f")
+         (match_operand:V16QI 2 "msa_reg_operand" "f"))
        (parallel [(const_int 0) (const_int 2)
                   (const_int 4) (const_int 6)
                   (const_int 8) (const_int 10)
@@ -2391,11 +2398,11 @@
    (set_attr "mode" "V16QI")])
 
 (define_insn "msa_pckev_h"
-[(set (match_operand:V8HI 0 "register_operand" "=f")
+[(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
       (vec_select:V8HI
        (vec_concat:V16HI
-         (match_operand:V8HI 1 "register_operand" "f")
-         (match_operand:V8HI 2 "register_operand" "f"))
+         (match_operand:V8HI 1 "msa_reg_operand" "f")
+         (match_operand:V8HI 2 "msa_reg_operand" "f"))
        (parallel [(const_int 0) (const_int 2)
                   (const_int 4) (const_int 6)
                   (const_int 8) (const_int 10)
@@ -2406,11 +2413,11 @@
    (set_attr "mode" "V8HI")])
 
 (define_insn "msa_pckev_w"
-[(set (match_operand:V4SI 0 "register_operand" "=f")
+[(set (match_operand:V4SI 0 "msa_reg_operand" "=f")
       (vec_select:V4SI
        (vec_concat:V8SI
-         (match_operand:V4SI 1 "register_operand" "f")
-         (match_operand:V4SI 2 "register_operand" "f"))
+         (match_operand:V4SI 1 "msa_reg_operand" "f")
+         (match_operand:V4SI 2 "msa_reg_operand" "f"))
        (parallel [(const_int 0) (const_int 2)
                   (const_int 4) (const_int 6)])))]
   "ISA_HAS_MSA"
@@ -2419,11 +2426,11 @@
    (set_attr "mode" "V4SI")])
 
 (define_insn "msa_pckev_w_f"
-[(set (match_operand:V4SF 0 "register_operand" "=f")
+[(set (match_operand:V4SF 0 "msa_reg_operand" "=f")
       (vec_select:V4SF
        (vec_concat:V8SF
-         (match_operand:V4SF 1 "register_operand" "f")
-         (match_operand:V4SF 2 "register_operand" "f"))
+         (match_operand:V4SF 1 "msa_reg_operand" "f")
+         (match_operand:V4SF 2 "msa_reg_operand" "f"))
        (parallel [(const_int 0) (const_int 2)
                   (const_int 4) (const_int 6)])))]
   "ISA_HAS_MSA"
@@ -2432,11 +2439,11 @@
    (set_attr "mode" "V4SF")])
 
 (define_insn "msa_pckod_b"
-[(set (match_operand:V16QI 0 "register_operand" "=f")
+[(set (match_operand:V16QI 0 "msa_reg_operand" "=f")
       (vec_select:V16QI
        (vec_concat:V32QI
-         (match_operand:V16QI 1 "register_operand" "f")
-         (match_operand:V16QI 2 "register_operand" "f"))
+         (match_operand:V16QI 1 "msa_reg_operand" "f")
+         (match_operand:V16QI 2 "msa_reg_operand" "f"))
        (parallel [(const_int 1) (const_int 3)
                   (const_int 5) (const_int 7)
                   (const_int 9) (const_int 11)
@@ -2451,11 +2458,11 @@
    (set_attr "mode" "V16QI")])
 
 (define_insn "msa_pckod_h"
-[(set (match_operand:V8HI 0 "register_operand" "=f")
+[(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
       (vec_select:V8HI
        (vec_concat:V16HI
-         (match_operand:V8HI 1 "register_operand" "f")
-         (match_operand:V8HI 2 "register_operand" "f"))
+         (match_operand:V8HI 1 "msa_reg_operand" "f")
+         (match_operand:V8HI 2 "msa_reg_operand" "f"))
        (parallel [(const_int 1) (const_int 3)
                   (const_int 5) (const_int 7)
                   (const_int 9) (const_int 11)
@@ -2466,11 +2473,11 @@
    (set_attr "mode" "V8HI")])
 
 (define_insn "msa_pckod_w"
-[(set (match_operand:V4SI 0 "register_operand" "=f")
+[(set (match_operand:V4SI 0 "msa_reg_operand" "=f")
       (vec_select:V4SI
        (vec_concat:V8SI
-         (match_operand:V4SI 1 "register_operand" "f")
-         (match_operand:V4SI 2 "register_operand" "f"))
+         (match_operand:V4SI 1 "msa_reg_operand" "f")
+         (match_operand:V4SI 2 "msa_reg_operand" "f"))
        (parallel [(const_int 1) (const_int 3)
                   (const_int 5) (const_int 7)])))]
   "ISA_HAS_MSA"
@@ -2479,11 +2486,11 @@
    (set_attr "mode" "V4SI")])
 
 (define_insn "msa_pckod_w_f"
-[(set (match_operand:V4SF 0 "register_operand" "=f")
+[(set (match_operand:V4SF 0 "msa_reg_operand" "=f")
       (vec_select:V4SF
        (vec_concat:V8SF
-         (match_operand:V4SF 1 "register_operand" "f")
-         (match_operand:V4SF 2 "register_operand" "f"))
+         (match_operand:V4SF 1 "msa_reg_operand" "f")
+         (match_operand:V4SF 2 "msa_reg_operand" "f"))
        (parallel [(const_int 1) (const_int 3)
                   (const_int 5) (const_int 7)])))]
   "ISA_HAS_MSA"
@@ -2492,16 +2499,16 @@
    (set_attr "mode" "V4SF")])
 
 (define_insn "popcount<mode>2"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (popcount:IMSA (match_operand:IMSA 1 "register_operand" "f")))]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (popcount:IMSA (match_operand:IMSA 1 "msa_reg_operand" "f")))]
   "ISA_HAS_MSA"
   "pcnt.<msafmt>\t%w0,%w1"
   [(set_attr "type" "simd_pcnt")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_sat_s_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
                      (match_operand 2 "const_<bitimm>_operand" "")]
                     UNSPEC_MSA_SAT_S))]
   "ISA_HAS_MSA"
@@ -2510,8 +2517,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_sat_u_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
                      (match_operand 2 "const_<bitimm>_operand" "")]
                     UNSPEC_MSA_SAT_U))]
   "ISA_HAS_MSA"
@@ -2520,9 +2527,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_shf_<msafmt_f>"
-  [(set (match_operand:MSA 0 "register_operand" "=f")
+  [(set (match_operand:MSA 0 "msa_reg_operand" "=f")
        (vec_select:MSA
-         (match_operand:MSA 1 "register_operand" "f")
+         (match_operand:MSA 1 "msa_reg_operand" "f")
          (match_operand 2 "par_const_vector_shf_set_operand" "")))]
   "ISA_HAS_MSA"
 {
@@ -2548,9 +2555,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_srar_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_SRAR))]
   "ISA_HAS_MSA"
   "srar.<msafmt>\t%w0,%w1,%w2"
@@ -2558,8 +2565,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_srari_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
                      (match_operand 2 "const_<bitimm>_operand" "")]
                     UNSPEC_MSA_SRARI))]
   "ISA_HAS_MSA"
@@ -2568,9 +2575,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_srlr_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_SRLR))]
   "ISA_HAS_MSA"
   "srlr.<msafmt>\t%w0,%w1,%w2"
@@ -2578,8 +2585,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_srlri_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
                      (match_operand 2 "const_<bitimm>_operand" "")]
                     UNSPEC_MSA_SRLRI))]
   "ISA_HAS_MSA"
@@ -2588,9 +2595,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_subs_s_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_SUBS_S))]
   "ISA_HAS_MSA"
   "subs_s.<msafmt>\t%w0,%w1,%w2"
@@ -2598,9 +2605,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_subs_u_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_SUBS_U))]
   "ISA_HAS_MSA"
   "subs_u.<msafmt>\t%w0,%w1,%w2"
@@ -2608,9 +2615,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_subsuu_s_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_SUBSUU_S))]
   "ISA_HAS_MSA"
   "subsuu_s.<msafmt>\t%w0,%w1,%w2"
@@ -2618,9 +2625,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_subsus_u_<msafmt>"
-  [(set (match_operand:IMSA 0 "register_operand" "=f")
-       (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
-                     (match_operand:IMSA 2 "register_operand" "f")]
+  [(set (match_operand:IMSA 0 "msa_reg_operand" "=f")
+       (unspec:IMSA [(match_operand:IMSA 1 "msa_reg_operand" "f")
+                     (match_operand:IMSA 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_SUBSUS_U))]
   "ISA_HAS_MSA"
   "subsus_u.<msafmt>\t%w0,%w1,%w2"
@@ -2628,9 +2635,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_sld_<msafmt_f>"
-  [(set (match_operand:MSA 0 "register_operand" "=f")
-       (unspec:MSA [(match_operand:MSA 1 "register_operand" "0")
-                    (match_operand:MSA 2 "register_operand" "f")
+  [(set (match_operand:MSA 0 "msa_reg_operand" "=f")
+       (unspec:MSA [(match_operand:MSA 1 "msa_reg_operand" "0")
+                    (match_operand:MSA 2 "msa_reg_operand" "f")
                     (match_operand:SI 3 "reg_or_0_operand" "dJ")]
                    UNSPEC_MSA_SLD))]
   "ISA_HAS_MSA"
@@ -2639,9 +2646,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_sldi_<msafmt_f>"
-  [(set (match_operand:MSA 0 "register_operand" "=f")
-       (unspec:MSA [(match_operand:MSA 1 "register_operand" "0")
-                    (match_operand:MSA 2 "register_operand" "f")
+  [(set (match_operand:MSA 0 "msa_reg_operand" "=f")
+       (unspec:MSA [(match_operand:MSA 1 "msa_reg_operand" "0")
+                    (match_operand:MSA 2 "msa_reg_operand" "f")
                     (match_operand 3 "const_<indeximm>_operand" "")]
                    UNSPEC_MSA_SLDI))]
   "ISA_HAS_MSA"
@@ -2650,9 +2657,9 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_splat_<msafmt_f>"
-  [(set (match_operand:MSA 0 "register_operand" "=f")
-       (unspec:MSA [(match_operand:MSA 1 "register_operand" "f")
-                    (match_operand:SI 2 "register_operand" "d")]
+  [(set (match_operand:MSA 0 "msa_reg_operand" "=f")
+       (unspec:MSA [(match_operand:MSA 1 "msa_reg_operand" "f")
+                    (match_operand:SI 2 "msa_reg_operand" "d")]
                    UNSPEC_MSA_SPLAT))]
   "ISA_HAS_MSA"
   "splat.<msafmt>\t%w0,%w1[%z2]"
@@ -2660,10 +2667,10 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_splati_<msafmt_f>"
-  [(set (match_operand:MSA 0 "register_operand" "=f")
+  [(set (match_operand:MSA 0 "msa_reg_operand" "=f")
        (vec_duplicate:MSA
          (vec_select:<UNITMODE>
-           (match_operand:MSA 1 "register_operand" "f")
+           (match_operand:MSA 1 "msa_reg_operand" "f")
            (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))]
   "ISA_HAS_MSA"
   "splati.<msafmt>\t%w0,%w1[%2]"
@@ -2671,8 +2678,8 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_splati_<msafmt_f>_scalar"
-  [(set (match_operand:FMSA 0 "register_operand" "=f")
-       (unspec:FMSA [(match_operand:<UNITMODE> 1 "register_operand" "f")]
+  [(set (match_operand:FMSA 0 "msa_reg_operand" "=f")
+       (unspec:FMSA [(match_operand:<UNITMODE> 1 "msa_reg_operand" "f")]
                     UNSPEC_MSA_SPLATI))]
   "ISA_HAS_MSA"
   "splati.<msafmt>\t%w0,%w1[0]"
@@ -2680,7 +2687,7 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "msa_cfcmsa"
-  [(set (match_operand:SI 0 "register_operand" "=d")
+  [(set (match_operand:SI 0 "msa_reg_operand" "=d")
        (unspec_volatile:SI [(match_operand 1 "const_uimm5_operand" "")]
                            UNSPEC_MSA_CFCMSA))]
   "ISA_HAS_MSA"
@@ -2690,7 +2697,7 @@
 
 (define_insn "msa_ctcmsa"
   [(unspec_volatile [(match_operand 0 "const_uimm5_operand" "")
-                    (match_operand:SI 1 "register_operand" "d")]
+                    (match_operand:SI 1 "msa_reg_operand" "d")]
                    UNSPEC_MSA_CTCMSA)]
   "ISA_HAS_MSA"
   "ctcmsa\t$%0,%1"
@@ -2698,9 +2705,9 @@
    (set_attr "mode" "SI")])
 
 (define_insn "msa_fexdo_h"
-  [(set (match_operand:V8HI 0 "register_operand" "=f")
-       (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "f")
-                     (match_operand:V4SF 2 "register_operand" "f")]
+  [(set (match_operand:V8HI 0 "msa_reg_operand" "=f")
+       (unspec:V8HI [(match_operand:V4SF 1 "msa_reg_operand" "f")
+                     (match_operand:V4SF 2 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FEXDO))]
   "ISA_HAS_MSA"
   "fexdo.h\t%w0,%w1,%w2"
@@ -2708,18 +2715,18 @@
    (set_attr "mode" "V8HI")])
 
 (define_insn "vec_pack_trunc_v2df"
-  [(set (match_operand:V4SF 0 "register_operand" "=f")
+  [(set (match_operand:V4SF 0 "msa_reg_operand" "=f")
        (vec_concat:V4SF
-         (float_truncate:V2SF (match_operand:V2DF 1 "register_operand" "f"))
-         (float_truncate:V2SF (match_operand:V2DF 2 "register_operand" "f"))))]
+         (float_truncate:V2SF (match_operand:V2DF 1 "msa_reg_operand" "f"))
+         (float_truncate:V2SF (match_operand:V2DF 2 "msa_reg_operand" "f"))))]
   "ISA_HAS_MSA"
   "fexdo.w\t%w0,%w2,%w1"
   [(set_attr "type" "simd_fcvt")
    (set_attr "mode" "V4SF")])
 
 (define_insn "msa_fexupl_w"
-  [(set (match_operand:V4SF 0 "register_operand" "=f")
-       (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "f")]
+  [(set (match_operand:V4SF 0 "msa_reg_operand" "=f")
+       (unspec:V4SF [(match_operand:V8HI 1 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FEXUPL))]
   "ISA_HAS_MSA"
   "fexupl.w\t%w0,%w1"
@@ -2727,10 +2734,10 @@
    (set_attr "mode" "V4SF")])
 
 (define_insn "msa_fexupl_d"
-  [(set (match_operand:V2DF 0 "register_operand" "=f")
+  [(set (match_operand:V2DF 0 "msa_reg_operand" "=f")
        (float_extend:V2DF
        (vec_select:V2SF
-         (match_operand:V4SF 1 "register_operand" "f")
+         (match_operand:V4SF 1 "msa_reg_operand" "f")
          (parallel [(const_int 2) (const_int 3)]))))]
   "ISA_HAS_MSA"
   "fexupl.d\t%w0,%w1"
@@ -2738,8 +2745,8 @@
    (set_attr "mode" "V2DF")])
 
 (define_insn "msa_fexupr_w"
-  [(set (match_operand:V4SF 0 "register_operand" "=f")
-       (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "f")]
+  [(set (match_operand:V4SF 0 "msa_reg_operand" "=f")
+       (unspec:V4SF [(match_operand:V8HI 1 "msa_reg_operand" "f")]
                     UNSPEC_MSA_FEXUPR))]
   "ISA_HAS_MSA"
   "fexupr.w\t%w0,%w1"
@@ -2747,10 +2754,10 @@
    (set_attr "mode" "V4SF")])
 
 (define_insn "msa_fexupr_d"
-  [(set (match_operand:V2DF 0 "register_operand" "=f")
+  [(set (match_operand:V2DF 0 "msa_reg_operand" "=f")
        (float_extend:V2DF
        (vec_select:V2SF
-         (match_operand:V4SF 1 "register_operand" "f")
+         (match_operand:V4SF 1 "msa_reg_operand" "f")
          (parallel [(const_int 0) (const_int 1)]))))]
   "ISA_HAS_MSA"
   "fexupr.d\t%w0,%w1"
@@ -2768,7 +2775,7 @@
 (define_insn "msa_<msabr>_<msafmt_f>"
  [(set (pc) (if_then_else
              (equality_op
-               (unspec:SI [(match_operand:MSA 1 "register_operand" "f")]
+               (unspec:SI [(match_operand:MSA 1 "msa_reg_operand" "f")]
                            UNSPEC_MSA_BRANCH)
                  (match_operand:SI 2 "const_0_operand"))
                  (label_ref (match_operand 0))
@@ -2789,7 +2796,7 @@
 (define_insn "msa_<msabr>_v_<msafmt_f>"
  [(set (pc) (if_then_else
              (equality_op
-               (unspec:SI [(match_operand:MSA 1 "register_operand" "f")]
+               (unspec:SI [(match_operand:MSA 1 "msa_reg_operand" "f")]
                            UNSPEC_MSA_BRANCH_V)
                  (match_operand:SI 2 "const_0_operand"))
                  (label_ref (match_operand 0))
@@ -2809,8 +2816,8 @@
 
 ;; Vector reduction operation
 (define_expand "reduc_smin_scal_<mode>"
-  [(match_operand:<UNITMODE> 0 "register_operand")
-   (match_operand:MSA 1 "register_operand")]
+  [(match_operand:<UNITMODE> 0 "msa_reg_operand")
+   (match_operand:MSA 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   rtx tmp = gen_reg_rtx (<MODE>mode);
@@ -2821,8 +2828,8 @@
 })
 
 (define_expand "reduc_smax_scal_<mode>"
-  [(match_operand:<UNITMODE> 0 "register_operand")
-   (match_operand:MSA 1 "register_operand")]
+  [(match_operand:<UNITMODE> 0 "msa_reg_operand")
+   (match_operand:MSA 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   rtx tmp = gen_reg_rtx (<MODE>mode);
@@ -2833,8 +2840,8 @@
 })
 
 (define_expand "reduc_umin_scal_<mode>"
-  [(match_operand:<UNITMODE> 0 "register_operand")
-   (match_operand:IMSA 1 "register_operand")]
+  [(match_operand:<UNITMODE> 0 "msa_reg_operand")
+   (match_operand:IMSA 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   rtx tmp = gen_reg_rtx (<MODE>mode);
@@ -2845,8 +2852,8 @@
 })
 
 (define_expand "reduc_umax_scal_<mode>"
-  [(match_operand:<UNITMODE> 0 "register_operand")
-   (match_operand:IMSA 1 "register_operand")]
+  [(match_operand:<UNITMODE> 0 "msa_reg_operand")
+   (match_operand:IMSA 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   rtx tmp = gen_reg_rtx (<MODE>mode);
@@ -2857,8 +2864,8 @@
 })
 
 (define_expand "reduc_plus_scal_<mode>"
-  [(match_operand:<UNITMODE> 0 "register_operand")
-   (match_operand:MSA_NO_HADD 1 "register_operand")]
+  [(match_operand:<UNITMODE> 0 "msa_reg_operand")
+   (match_operand:MSA_NO_HADD 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   rtx tmp = gen_reg_rtx (<MODE>mode);
@@ -2869,8 +2876,8 @@
 })
 
 (define_expand "reduc_plus_scal_v4si"
-  [(match_operand:SI 0 "register_operand")
-   (match_operand:V4SI 1 "register_operand")]
+  [(match_operand:SI 0 "msa_reg_operand")
+   (match_operand:V4SI 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   rtx tmp = gen_reg_rtx (SImode);
@@ -2885,8 +2892,8 @@
 })
 
 (define_expand "reduc_plus_scal_v8hi"
-  [(match_operand:HI 0 "register_operand")
-   (match_operand:V8HI 1 "register_operand")]
+  [(match_operand:HI 0 "msa_reg_operand")
+   (match_operand:V8HI 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   rtx tmp1 = gen_reg_rtx (V4SImode);
@@ -2901,8 +2908,8 @@
 })
 
 (define_expand "reduc_plus_scal_v16qi"
-  [(match_operand:QI 0 "register_operand")
-   (match_operand:V16QI 1 "register_operand")]
+  [(match_operand:QI 0 "msa_reg_operand")
+   (match_operand:V16QI 1 "msa_reg_operand")]
   "ISA_HAS_MSA"
 {
   rtx tmp1 = gen_reg_rtx (V8HImode);
@@ -2920,8 +2927,8 @@
 
 (define_expand "reduc_<optab>_scal_<mode>"
   [(any_bitwise:<UNITMODE>
-      (match_operand:<UNITMODE> 0 "register_operand")
-      (match_operand:IMSA 1 "register_operand"))]
+      (match_operand:<UNITMODE> 0 "msa_reg_operand")
+      (match_operand:IMSA 1 "msa_reg_operand"))]
   "ISA_HAS_MSA"
 {
   rtx tmp = gen_reg_rtx (<MODE>mode);
@@ -2930,3 +2937,56 @@
                                              const0_rtx));
   DONE;
 })
+
+;; On big-endian targets we cannot use subregs to refer to MSA register
+;; in different mode.  See mips_can_change_mode_class.  This is used
+;; specifically during expansion of vec_unpack operations, which requires
+;; MSA register mode changes.
+(define_expand "msa_change_mode"
+  [(match_operand 0 "msa_reg_operand")
+   (match_operand 1 "msa_reg_operand")]
+  "ISA_HAS_MSA"
+{
+  gcc_assert (MSA_SUPPORTED_MODE_P (GET_MODE (operands[0]))
+             && MSA_SUPPORTED_MODE_P (GET_MODE (operands[1])));
+
+    if (!TARGET_BIG_ENDIAN)
+      emit_move_insn (operands[0],
+                     gen_lowpart (GET_MODE (operands[0]), operands[1]));
+    else
+      emit_move_insn (operands[0],
+                     gen_rtx_UNSPEC (GET_MODE (operands[0]),
+                                     gen_rtvec (1, operands[1]),
+                                     UNSPEC_MSA_CHANGE_MODE));
+  DONE;
+})
+
+(define_insn_and_split "msa_change_mode_<mode>"
+  [(set (match_operand:MSA 0 "msa_reg_operand" "=f")
+    (unspec:MSA [(match_operand 1 "msa_reg_operand" "f")]
+         UNSPEC_MSA_CHANGE_MODE))]
+  "ISA_HAS_MSA && TARGET_BIG_ENDIAN
+   && MSA_SUPPORTED_MODE_P (GET_MODE (operands[1]))"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (match_dup 1))]
+{
+    operands[1] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
+}
+  [(set_attr "move_type" "fmove")
+   (set_attr "mode" "<MODE>")])
+
+;; A pattern for optimizing SUBREGs which have a reinterpreting effect
+;; on big-endian targets.
+(define_insn_and_split "*msa_mov<mode>_subreg_be"
+  [(set (match_operand:MSA 0 "nonimmediate_operand" "=f")
+    (unspec:MSA [(match_operand 1 "move_operand" "f")]
+      UNSPEC_MSA_SUBREG_BE))]
+  "ISA_HAS_MSA && TARGET_BIG_ENDIAN"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+{
+  mips_split_msa_subreg_move (operands[0], operands[1]);
+  DONE;
+})
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 96e084e6e64..9b2f6a85fb6 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -396,6 +396,8 @@ extern bool mips_bit_clear_p (enum machine_mode, unsigned 
HOST_WIDE_INT);
 extern void mips_bit_clear_info (enum machine_mode, unsigned HOST_WIDE_INT,
                                  int *, int *);
 
+extern void mips_split_msa_subreg_move (rtx, rtx);
+
 extern const char *mips_output_compare (const char *fpcmp, const char *fcond,
                        const char *fmt, const char *fpcc_mode, bool swap);
 #endif /* ! GCC_MIPS_PROTOS_H */
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 82c9e49c6bf..07b2fe03efc 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -3888,6 +3888,118 @@ mips_legitimize_const_move (machine_mode mode, rtx 
dest, rtx src)
   mips_emit_move (dest, src);
 }
 
+/* Called only on big-endian targets.  See whether an MSA vector move from
+   SRC to DEST is effectively a (pair of) SHF instruction(s), because at least
+   one operand is a SUBREG of an MSA vector that has wider or narrower
+   elements.  Return true and emit the instruction if so.
+
+   VIEW_CONVERT (bitconvert) between the two vectors should change only the
+   compiler's interpretation of the data, not the data itself, which is what
+   happens on big-endian targets.  Therefore, we insert one or two shuffle
+   instructions to keep the data in registers in a valid state.
+
+   Without this modification, we would spill the SUBREG operand to stack in
+   one mode and reload it in the other, which is also valid, but obviously
+   a lot slower.  */
+
+static bool
+mips_maybe_expand_msa_subreg_move (rtx dest, rtx src)
+{
+  gcc_assert (TARGET_BIG_ENDIAN);
+
+  if (GET_CODE (dest) == SUBREG)
+    dest = SUBREG_REG (dest);
+  if (GET_CODE (src) == SUBREG)
+    src = SUBREG_REG (src);
+
+  /* The optimization handles two MSA REGs with different element size.  */
+  if (!REG_P (dest)
+      || !REG_P (src)
+      || !MSA_SUPPORTED_MODE_P (GET_MODE (dest))
+      || !MSA_SUPPORTED_MODE_P (GET_MODE (src))
+      || (GET_MODE_UNIT_SIZE (GET_MODE (dest))
+         == GET_MODE_UNIT_SIZE (GET_MODE (src))))
+    return false;
+
+  /* Generate *msa_mov<mode>_subreg_be.  */
+  rtx unspec = gen_rtx_UNSPEC (GET_MODE (dest),
+                              gen_rtvec (1, src),
+                              UNSPEC_MSA_SUBREG_BE);
+  emit_insn (gen_rtx_SET (dest, unspec));
+  return true;
+}
+
+/* Return a copy of X with mode MODE, without changing its other
+   attributes.  */
+static rtx
+mips_replace_reg_mode (rtx x, machine_mode mode)
+{
+  if (GET_MODE (x) == mode)
+    return x;
+
+  x = shallow_copy_rtx (x);
+  set_mode_and_regno (x, mode, REGNO (x));
+  return x;
+}
+
+/* Split a *msa_mov<mode>_subreg_be pattern with the given operands.  */
+void
+mips_split_msa_subreg_move (rtx dest, rtx src)
+{
+  /* Decide how many and which SHF operations we need.  The size ratio of
+     machine modes defines the number of operations, while the mode with the
+     narrower elements determines the mode of the operands.  */
+  int shf_value_1, shf_value_2 = 0xb1;
+  machine_mode mode_with_wider_elts = GET_MODE (dest);
+  machine_mode mode_with_narrower_elts = GET_MODE (src);
+  unsigned char wider_mode_size, narrower_mode_size;
+  rtx x;
+
+  wider_mode_size = GET_MODE_UNIT_SIZE (mode_with_wider_elts);
+  narrower_mode_size = GET_MODE_UNIT_SIZE (mode_with_narrower_elts);
+
+  if (wider_mode_size < narrower_mode_size)
+    {
+      std::swap (mode_with_wider_elts, mode_with_narrower_elts);
+      std::swap (wider_mode_size, narrower_mode_size);
+    }
+
+  int size_ratio = wider_mode_size / narrower_mode_size;
+  switch (size_ratio)
+    {
+    case 8:
+    case 4:
+      shf_value_1 = 0x1b;
+      break;
+    case 2:
+      shf_value_1 = 0xb1;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  /* Emit the first SHF instruction with appropriate modes.  */
+  dest = mips_replace_reg_mode (dest, mode_with_narrower_elts);
+  src = mips_replace_reg_mode (src, mode_with_narrower_elts);
+  x = mips_gen_const_int_vector_shuffle (mode_with_narrower_elts,
+                                        shf_value_1);
+  x = gen_rtx_VEC_SELECT (mode_with_narrower_elts, src, x);
+  x = gen_rtx_SET (dest, x);
+  emit_insn (x);
+
+  /* Emit the second SHF instruction (if needed) with appropriate modes.  */
+  if (size_ratio == 8)
+    {
+      dest = mips_replace_reg_mode (dest, V4SImode);
+      src = mips_replace_reg_mode (dest, V4SImode);
+      x = mips_gen_const_int_vector_shuffle (V4SImode,
+                                            shf_value_2);
+      x = gen_rtx_VEC_SELECT (V4SImode, src, x);
+      x = gen_rtx_SET (dest, x);
+      emit_insn (x);
+    }
+}
+
 /* If (set DEST SRC) is not a valid move instruction, emit an equivalent
    sequence that is valid.  */
 
@@ -3915,6 +4027,33 @@ mips_legitimize_move (machine_mode mode, rtx dest, rtx 
src)
       set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src));
       return true;
     }
+
+  if (TARGET_BIG_ENDIAN
+      && MSA_SUPPORTED_MODE_P (GET_MODE (dest))
+      && MSA_SUPPORTED_MODE_P (GET_MODE (src)))
+    {
+      /* SRC or DEST with an MSA mode have an allocated hard register only if
+        they are function call arguments or return values.  In that case,
+        force their machine modes to V2DImode or V4SImode, depending on the
+        target size.  This will produce shuffle instruction(s) which will
+        reorder the elements within a vector, so that they conform to the
+        calling convention.  This fixes the discrepancy between calling
+        conventions of MSA and non-MSA builds.  */
+      if (REG_P (dest)
+         && HARD_REGISTER_P (dest)
+         && GP_REG_P (REGNO (dest)))
+       dest = mips_replace_reg_mode (dest, TARGET_64BIT ? V2DImode : V4SImode);
+
+      if (REG_P (src)
+         && HARD_REGISTER_P (src)
+         && GP_REG_P (REGNO (src)))
+       src = mips_replace_reg_mode (src, TARGET_64BIT ? V2DImode : V4SImode);
+
+      /* See whether MSA SUBREG move can be replaced with shuffle(s).  */
+      if (mips_maybe_expand_msa_subreg_move (dest, src))
+       return true;
+    }
+
   return false;
 }
 
@@ -5150,6 +5289,29 @@ mips_split_128bit_move_p (rtx dest, rtx src)
   return true;
 }
 
+/* Weed subreg out of msa_copy.  */
+
+rtx
+mips_weed_subreg_out_of_msa_copy (rtx op0)
+{
+  machine_mode m = GET_MODE (op0);
+
+  if (TARGET_BIG_ENDIAN
+      && MSA_SUPPORTED_MODE_P (m)
+      && GET_CODE (op0) == SUBREG)
+    {
+      rtx op1 = SUBREG_REG (op0);
+      if (REG_P (op1)
+         && MSA_SUPPORTED_MODE_P (GET_MODE (op1)))
+  {
+    rtx dest = gen_reg_rtx (m);
+    emit_insn (gen_msa_change_mode (dest, op1));
+    return dest;
+  }
+    }
+  return op0;
+}
+
 /* Split a 128-bit move from SRC to DEST.  */
 
 void
@@ -5166,12 +5328,12 @@ mips_split_128bit_move (rtx dest, rtx src)
       if (!TARGET_64BIT)
        {
          if (GET_MODE (dest) != V4SImode)
-           new_dest = simplify_gen_subreg (V4SImode, dest, GET_MODE (dest), 0);
+           new_dest = mips_replace_reg_mode (dest, V4SImode);
        }
       else
        {
          if (GET_MODE (dest) != V2DImode)
-           new_dest = simplify_gen_subreg (V2DImode, dest, GET_MODE (dest), 0);
+           new_dest = mips_replace_reg_mode (dest, V2DImode);
        }
 
       for (byte = 0, index = 0; byte < GET_MODE_SIZE (TImode);
@@ -5194,12 +5356,12 @@ mips_split_128bit_move (rtx dest, rtx src)
       if (!TARGET_64BIT)
        {
          if (GET_MODE (src) != V4SImode)
-           new_src = simplify_gen_subreg (V4SImode, src, GET_MODE (src), 0);
+           new_src = mips_replace_reg_mode (src, V4SImode);
        }
       else
        {
          if (GET_MODE (src) != V2DImode)
-           new_src = simplify_gen_subreg (V2DImode, src, GET_MODE (src), 0);
+           new_src = mips_replace_reg_mode (src, V2DImode);
        }
 
       for (byte = 0, index = 0; byte < GET_MODE_SIZE (TImode);
@@ -5207,9 +5369,13 @@ mips_split_128bit_move (rtx dest, rtx src)
        {
          d = mips_subword_at_byte (dest, byte);
          if (!TARGET_64BIT)
-           emit_insn (gen_msa_copy_s_w (d, new_src, GEN_INT (index)));
+           emit_insn (gen_msa_copy_s_w (d,
+                      mips_weed_subreg_out_of_msa_copy (new_src),
+                      GEN_INT (index)));
          else
-           emit_insn (gen_msa_copy_s_d (d, new_src, GEN_INT (index)));
+           emit_insn (gen_msa_copy_s_d (d,
+                      mips_weed_subreg_out_of_msa_copy (new_src),
+                      GEN_INT (index)));
        }
     }
   else
@@ -5255,8 +5421,10 @@ mips_split_msa_copy_d (rtx dest, rtx src, rtx index,
      from the higher index.  */
   rtx low = mips_subword (dest, false);
   rtx high = mips_subword (dest, true);
-  rtx new_src = simplify_gen_subreg (V4SImode, src, GET_MODE (src), 0);
 
+  rtx new_src = mips_replace_reg_mode (src, V4SImode);
+
+  new_src = mips_weed_subreg_out_of_msa_copy (new_src);
   emit_insn (gen_fn (low, new_src, GEN_INT (INTVAL (index) * 2)));
   emit_insn (gen_fn (high, new_src, GEN_INT (INTVAL (index) * 2 + 1)));
 }
@@ -5276,8 +5444,8 @@ mips_split_msa_insert_d (rtx dest, rtx src1, rtx index, 
rtx src2)
      from the higher index.  */
   rtx low = mips_subword (src2, false);
   rtx high = mips_subword (src2, true);
-  rtx new_dest = simplify_gen_subreg (V4SImode, dest, GET_MODE (dest), 0);
-  rtx new_src1 = simplify_gen_subreg (V4SImode, src1, GET_MODE (src1), 0);
+  rtx new_dest = mips_replace_reg_mode (dest, V4SImode);
+  rtx new_src1 = mips_replace_reg_mode (src1, V4SImode);
   i = exact_log2 (INTVAL (index));
   gcc_assert (i != -1);
 
@@ -5309,7 +5477,7 @@ mips_split_msa_fill_d (rtx dest, rtx src)
       low = mips_subword (src, false);
       high = mips_subword (src, true);
     }
-  rtx new_dest = simplify_gen_subreg (V4SImode, dest, GET_MODE (dest), 0);
+  rtx new_dest = mips_replace_reg_mode (dest, V4SImode);
   emit_insn (gen_msa_fill_w (new_dest, low));
   emit_insn (gen_msa_insert_w (new_dest, high, new_dest, GEN_INT (1 << 1)));
   emit_insn (gen_msa_insert_w (new_dest, high, new_dest, GEN_INT (1 << 3)));
@@ -13493,9 +13661,15 @@ mips_can_change_mode_class (machine_mode from,
       && INTEGRAL_MODE_P (from) && INTEGRAL_MODE_P (to))
     return true;
 
-  /* Allow conversions between different MSA vector modes.  */
+  /* Allow conversions between different MSA vector modes.
+     On big-endian targets the MSA register layout doesn't
+     match its memory layout, so we disallow mode change that
+     would result in lane width change.  */
   if (MSA_SUPPORTED_MODE_P (from) && MSA_SUPPORTED_MODE_P (to))
-    return true;
+   {
+    return !TARGET_BIG_ENDIAN
+          || (GET_MODE_UNIT_SIZE (from) == GET_MODE_UNIT_SIZE (to));
+   }
 
   /* Otherwise, there are several problems with changing the modes of
      values in floating-point registers:
@@ -21875,6 +22049,24 @@ struct expand_vec_perm_d
   bool testing_p;
 };
 
+/* Weed subreg out of vec_select.  */
+
+rtx
+mips_weed_subreg_out_of_vec_select (rtx op0)
+{
+  machine_mode m = GET_MODE (op0);
+
+  if (TARGET_BIG_ENDIAN
+      && MSA_SUPPORTED_MODE_P (m)
+      && GET_CODE (op0) == SUBREG)
+    {
+      rtx dest = gen_reg_rtx (m);
+      if (mips_maybe_expand_msa_subreg_move (dest, op0))
+  return dest;
+    }
+  return op0;
+}
+
 /* Construct (set target (vec_select op0 (parallel perm))) and
    return true if that's a valid instruction in the active ISA.  */
 
@@ -21890,7 +22082,8 @@ mips_expand_vselect (rtx target, rtx op0,
     rperm[i] = GEN_INT (perm[i]);
 
   x = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelt, rperm));
-  x = gen_rtx_VEC_SELECT (GET_MODE (target), op0, x);
+  x = gen_rtx_VEC_SELECT (GET_MODE (target),
+                         mips_weed_subreg_out_of_vec_select (op0), x);
   x = gen_rtx_SET (target, x);
 
   insn = emit_insn (x);
@@ -22091,7 +22284,8 @@ mips_expand_msa_shuffle (struct expand_vec_perm_d *d)
   if (!mips_const_vector_shuffle_set_p (x, d->vmode))
     return false;
 
-  x = gen_rtx_VEC_SELECT (d->vmode, d->op0, x);
+  x = gen_rtx_VEC_SELECT (d->vmode,
+                         mips_weed_subreg_out_of_vec_select (d->op0), x);
   x = gen_rtx_SET (d->target, x);
 
   insn = emit_insn (x);
@@ -22355,7 +22549,7 @@ mips_expand_vec_unpack (rtx operands[2], bool 
unsigned_p, bool high_p)
       dest = gen_reg_rtx (imode);
 
       emit_insn (unpack (dest, operands[1], tmp));
-      emit_move_insn (operands[0], gen_lowpart (GET_MODE (operands[0]), dest));
+      emit_insn (gen_msa_change_mode (operands[0], dest));
       return;
     }
 
diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md
index a64900d25ef..5323522d2a5 100644
--- a/gcc/config/mips/predicates.md
+++ b/gcc/config/mips/predicates.md
@@ -651,3 +651,8 @@
 (define_predicate "reg_or_vector_same_uimm6_operand"
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "const_vector_same_uimm6_operand")))
+
+(define_predicate "msa_reg_operand"
+  (if_then_else (match_test "TARGET_BIG_ENDIAN")
+       (match_code "reg")
+       (match_operand 0 "register_operand")))
diff --git a/gcc/testsuite/gcc.target/mips/inter/msa-inter.exp 
b/gcc/testsuite/gcc.target/mips/inter/msa-inter.exp
new file mode 100644
index 00000000000..a4d3145fd92
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inter/msa-inter.exp
@@ -0,0 +1,67 @@
+# Copyright (C) 2025 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Run calling convention compatibility tests for vector types in which the 
"alt"
+# compiler uses -mmsa.
+
+load_lib gcc-dg.exp
+
+# Check whether we can execute MSA code.
+if { ![check_mips_msa_hw_available] } {
+    return
+}
+
+# Save the old value of CFLAGS_FOR_TARGET, if any.
+global saved_CFLAGS_FOR_TARGET
+if { [info exists CFLAGS_FOR_TARGET] } {
+    set saved_CFLAGS_FOR_TARGET $CFLAGS_FOR_TARGET
+} else {
+    unset -nocomplain saved_CFLAGS_FOR_TARGET
+}
+
+# The "alt" compiler is the normal compiler with an extra "-mmsa" argument.
+proc compat-use-alt-compiler { } {
+    global saved_CFLAGS_FOR_TARGET CFLAGS_FOR_TARGET
+
+    if { [info exists saved_CFLAGS_FOR_TARGET] } {
+        set CFLAGS_FOR_TARGET [concat $saved_CFLAGS_FOR_TARGET "-mmsa"]
+    } else {
+        set CFLAGS_FOR_TARGET "-mmsa"
+    }
+}
+
+# Make the compiler under test the default.
+proc compat-use-tst-compiler { } {
+    global saved_CFLAGS_FOR_TARGET CFLAGS_FOR_TARGET
+
+    if { [info exists saved_CFLAGS_FOR_TARGET] } {
+        set CFLAGS_FOR_TARGET $saved_CFLAGS_FOR_TARGET
+    } else {
+        unset -nocomplain CFLAGS_FOR_TARGET
+    }
+}
+
+load_lib compat.exp
+
+gcc_init
+foreach src [lsort [find $srcdir/$subdir msa_*_main.c]] {
+    if { [runtest_file_p $runtests $src] } {
+        compat-execute $src "msa_inter" 1
+    }
+}
+compat-use-tst-compiler
diff --git a/gcc/testsuite/gcc.target/mips/inter/msa_1.h 
b/gcc/testsuite/gcc.target/mips/inter/msa_1.h
new file mode 100644
index 00000000000..12114a94f3e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inter/msa_1.h
@@ -0,0 +1,23 @@
+typedef signed char v16i8 __attribute__ ((vector_size(16)));
+typedef short v8i16 __attribute__ ((vector_size(16)));
+typedef int v4i32 __attribute__ ((vector_size(16)));
+typedef long long v2i64 __attribute__ ((vector_size(16)));
+typedef unsigned char v16u8 __attribute__ ((vector_size(16)));
+typedef unsigned short v8u16 __attribute__ ((vector_size(16)));
+typedef unsigned int v4u32 __attribute__ ((vector_size(16)));
+typedef unsigned long long v2u64 __attribute__ ((vector_size(16)));
+typedef float v4f32 __attribute__ ((vector_size(16)));
+typedef double v2f64 __attribute__ ((vector_size(16)));
+
+
+#define ITERATE_FOR_ALL_TYPES(FUNC) \
+  FUNC (v16i8, 16) \
+  FUNC (v8i16, 8) \
+  FUNC (v4i32, 4) \
+  FUNC (v2i64, 2) \
+  FUNC (v16u8, 16) \
+  FUNC (v8u16, 8) \
+  FUNC (v4u32, 4) \
+  FUNC (v2u64, 2) \
+  FUNC (v4f32, 4) \
+  FUNC (v2f64, 2)
diff --git a/gcc/testsuite/gcc.target/mips/inter/msa_1_main.c 
b/gcc/testsuite/gcc.target/mips/inter/msa_1_main.c
new file mode 100644
index 00000000000..0d17c8381a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inter/msa_1_main.c
@@ -0,0 +1,8 @@
+extern void test (void);
+
+int
+main (void)
+{
+  test ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/mips/inter/msa_1_x.c 
b/gcc/testsuite/gcc.target/mips/inter/msa_1_x.c
new file mode 100644
index 00000000000..f3d43ca5c16
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inter/msa_1_x.c
@@ -0,0 +1,35 @@
+#include "msa_1.h"
+
+#define INIT_2  {1, 2}
+#define INIT_4  {1, 2, 3, 4}
+#define INIT_8  {1, 2, 3, 4, 5, 6, 7, 8}
+#define INIT_16 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ,14 ,15 ,16}
+
+#define TEST(TYPE, NUM)                                         \
+__attribute__ ((noinline)) static void                          \
+test_ ## TYPE ##_caller (void)                                  \
+{                                                               \
+  extern TYPE test_ ## TYPE ##_callee (TYPE, const TYPE*);      \
+  TYPE vect = (TYPE) INIT_ ## NUM;                              \
+  TYPE res = test_ ## TYPE ## _callee (vect, &vect);            \
+  if (__builtin_memcmp (&vect, &res, sizeof vect))              \
+    __builtin_abort();                                          \
+}
+
+ITERATE_FOR_ALL_TYPES(TEST)
+
+#undef TEST
+#undef INIT_2
+#undef INIT_4
+#undef INIT_8
+#undef INIT_16
+
+#define RUN_TEST(TYPE, NUM) test_ ## TYPE ##_caller ();
+
+void
+test (void)
+{
+  ITERATE_FOR_ALL_TYPES(RUN_TEST)
+}
+
+#undef RUN_TEST
diff --git a/gcc/testsuite/gcc.target/mips/inter/msa_1_y.c 
b/gcc/testsuite/gcc.target/mips/inter/msa_1_y.c
new file mode 100644
index 00000000000..250df27d703
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inter/msa_1_y.c
@@ -0,0 +1,14 @@
+#include "msa_1.h"
+
+#define TEST(TYPE, NUM)                                       \
+TYPE                                                          \
+test_ ## TYPE ##_callee (TYPE vect, const TYPE* pvect)        \
+{                                                             \
+  if (__builtin_memcmp (&vect, pvect, sizeof vect))           \
+    __builtin_abort();                                        \
+  return *pvect;                                              \
+}
+
+ITERATE_FOR_ALL_TYPES(TEST)
+
+#undef TEST
-- 
2.34.1

Reply via email to