aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/arc/simdext.md
diff options
context:
space:
mode:
authorClaudiu Zissulescu <claziss@synopsys.com>2016-04-28 11:53:13 +0200
committerClaudiu Zissulescu <claziss@gcc.gnu.org>2016-04-28 11:53:13 +0200
commit00c072ae51c132e346eab0c6f8c176542efbcd5a (patch)
tree146450a4a2fcb549676ac1fec42051bbc2176e40 /gcc/config/arc/simdext.md
parent174f66220d4d39ed503ded1ec3e7ba514cc4283e (diff)
downloadgcc-00c072ae51c132e346eab0c6f8c176542efbcd5a.zip
gcc-00c072ae51c132e346eab0c6f8c176542efbcd5a.tar.gz
gcc-00c072ae51c132e346eab0c6f8c176542efbcd5a.tar.bz2
[ARC] Add SIMD extensions for ARC HS
gcc/ 2016-04-28 Claudiu Zissulescu <claziss@synopsys.com> * config/arc/arc.c (arc_vector_mode_supported_p): Add support for the new ARC HS SIMD instructions. (arc_preferred_simd_mode): New function. (arc_autovectorize_vector_sizes): Likewise. (TARGET_VECTORIZE_PREFERRED_SIMD_MODE) (TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES): Define. (arc_init_reg_tables): Accept new ARC HS SIMD modes. (arc_init_builtins): Add new SIMD builtin types. (arc_split_move): Handle 64 bit vector moves. * config/arc/arc.h (TARGET_PLUS_DMPY, TARGET_PLUS_MACD) (TARGET_PLUS_QMACW): Define. * config/arc/builtins.def (QMACH, QMACHU, QMPYH, QMPYHU, DMACH) (DMACHU, DMPYH, DMPYHU, DMACWH, DMACWHU, VMAC2H, VMAC2HU, VMPY2H) (VMPY2HU, VADDSUB2H, VSUBADD2H, VADDSUB, VSUBADD, VADDSUB4H) (VSUBADD4H): New builtins. * config/arc/simdext.md: Add new ARC HS SIMD instructions. * testsuite/gcc.target/arc/builtin_simdarc.c: New file. From-SVN: r235551
Diffstat (limited to 'gcc/config/arc/simdext.md')
-rw-r--r--gcc/config/arc/simdext.md571
1 files changed, 571 insertions, 0 deletions
diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md
index 9fd9d62..51869e3 100644
--- a/gcc/config/arc/simdext.md
+++ b/gcc/config/arc/simdext.md
@@ -1288,3 +1288,574 @@
[(set_attr "type" "simd_vcontrol")
(set_attr "length" "4")
(set_attr "cond" "nocond")])
+
+;; New ARCv2 SIMD extensions
+
+;;64-bit vectors of halwords and words
+(define_mode_iterator VWH [V4HI V2SI])
+
+;;double element vectors
+(define_mode_iterator VDV [V2HI V2SI])
+(define_mode_attr V_addsub [(V2HI "HI") (V2SI "SI")])
+(define_mode_attr V_addsub_suffix [(V2HI "2h") (V2SI "")])
+
+;;all vectors
+(define_mode_iterator VCT [V2HI V4HI V2SI])
+(define_mode_attr V_suffix [(V2HI "2h") (V4HI "4h") (V2SI "2")])
+
+;; Widening operations.
+(define_code_iterator SE [sign_extend zero_extend])
+(define_code_attr V_US [(sign_extend "s") (zero_extend "u")])
+(define_code_attr V_US_suffix [(sign_extend "") (zero_extend "u")])
+
+
+;; Move patterns
+(define_expand "movv2hi"
+ [(set (match_operand:V2HI 0 "move_dest_operand" "")
+ (match_operand:V2HI 1 "general_operand" ""))]
+ ""
+ "{
+ if (prepare_move_operands (operands, V2HImode))
+ DONE;
+ }")
+
+(define_insn_and_split "*movv2hi_insn"
+ [(set (match_operand:V2HI 0 "nonimmediate_operand" "=r,r,r,m")
+ (match_operand:V2HI 1 "general_operand" "i,r,m,r"))]
+ "(register_operand (operands[0], V2HImode)
+ || register_operand (operands[1], V2HImode))"
+ "@
+ #
+ mov%? %0, %1
+ ld%U1%V1 %0,%1
+ st%U0%V0 %1,%0"
+ "reload_completed && GET_CODE (operands[1]) == CONST_VECTOR"
+ [(set (match_dup 0) (match_dup 2))]
+ {
+ HOST_WIDE_INT intval = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
+ intval |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
+
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ operands[2] = GEN_INT (trunc_int_for_mode (intval, SImode));
+ }
+ [(set_attr "type" "move,move,load,store")
+ (set_attr "predicable" "yes,yes,no,no")
+ (set_attr "iscompact" "false,false,false,false")
+ ])
+
+(define_expand "movmisalignv2hi"
+ [(set (match_operand:V2HI 0 "general_operand" "")
+ (match_operand:V2HI 1 "general_operand" ""))]
+ ""
+{
+ if (!register_operand (operands[0], V2HImode)
+ && !register_operand (operands[1], V2HImode))
+ operands[1] = force_reg (V2HImode, operands[1]);
+})
+
+(define_expand "mov<mode>"
+ [(set (match_operand:VWH 0 "move_dest_operand" "")
+ (match_operand:VWH 1 "general_operand" ""))]
+ ""
+ "{
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (<MODE>mode, operands[1]);
+ }")
+
+(define_insn_and_split "*mov<mode>_insn"
+ [(set (match_operand:VWH 0 "move_dest_operand" "=r,r,r,m")
+ (match_operand:VWH 1 "general_operand" "i,r,m,r"))]
+ "TARGET_PLUS_QMACW
+ && (register_operand (operands[0], <MODE>mode)
+ || register_operand (operands[1], <MODE>mode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ default:
+ return \"#\";
+
+ case 1:
+ return \"vadd2 %0, %1, 0\";
+
+ case 2:
+ if (TARGET_LL64)
+ return \"ldd%U1%V1 %0,%1\";
+ return \"#\";
+
+ case 3:
+ if (TARGET_LL64)
+ return \"std%U0%V0 %1,%0\";
+ return \"#\";
+ }
+}"
+ "reload_completed"
+ [(const_int 0)]
+ {
+ arc_split_move (operands);
+ DONE;
+ }
+ [(set_attr "type" "move,move,load,store")
+ (set_attr "predicable" "yes,no,no,no")
+ (set_attr "iscompact" "false,false,false,false")
+ ])
+
+(define_expand "movmisalign<mode>"
+ [(set (match_operand:VWH 0 "general_operand" "")
+ (match_operand:VWH 1 "general_operand" ""))]
+ ""
+{
+ if (!register_operand (operands[0], <MODE>mode)
+ && !register_operand (operands[1], <MODE>mode))
+ operands[1] = force_reg (<MODE>mode, operands[1]);
+})
+
+(define_insn "bswapv2hi2"
+ [(set (match_operand:V2HI 0 "register_operand" "=r,r")
+ (bswap:V2HI (match_operand:V2HI 1 "nonmemory_operand" "r,i")))]
+ "TARGET_V2 && TARGET_SWAP"
+ "swape %0, %1"
+ [(set_attr "length" "4,8")
+ (set_attr "type" "two_cycle_core")])
+
+;; Simple arithmetic insns
+(define_insn "add<mode>3"
+ [(set (match_operand:VCT 0 "register_operand" "=r,r")
+ (plus:VCT (match_operand:VCT 1 "register_operand" "0,r")
+ (match_operand:VCT 2 "register_operand" "r,r")))]
+ "TARGET_PLUS_DMPY"
+ "vadd<V_suffix>%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "sub<mode>3"
+ [(set (match_operand:VCT 0 "register_operand" "=r,r")
+ (minus:VCT (match_operand:VCT 1 "register_operand" "0,r")
+ (match_operand:VCT 2 "register_operand" "r,r")))]
+ "TARGET_PLUS_DMPY"
+ "vsub<V_suffix>%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+;; Combined arithmetic ops
+(define_insn "addsub<mode>3"
+ [(set (match_operand:VDV 0 "register_operand" "=r,r")
+ (vec_concat:VDV
+ (plus:<V_addsub> (vec_select:<V_addsub> (match_operand:VDV 1 "register_operand" "0,r")
+ (parallel [(const_int 0)]))
+ (vec_select:<V_addsub> (match_operand:VDV 2 "register_operand" "r,r")
+ (parallel [(const_int 0)])))
+ (minus:<V_addsub> (vec_select:<V_addsub> (match_dup 1) (parallel [(const_int 1)]))
+ (vec_select:<V_addsub> (match_dup 2) (parallel [(const_int 1)])))))]
+ "TARGET_PLUS_DMPY"
+ "vaddsub<V_addsub_suffix>%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "subadd<mode>3"
+ [(set (match_operand:VDV 0 "register_operand" "=r,r")
+ (vec_concat:VDV
+ (minus:<V_addsub> (vec_select:<V_addsub> (match_operand:VDV 1 "register_operand" "0,r")
+ (parallel [(const_int 0)]))
+ (vec_select:<V_addsub> (match_operand:VDV 2 "register_operand" "r,r")
+ (parallel [(const_int 0)])))
+ (plus:<V_addsub> (vec_select:<V_addsub> (match_dup 1) (parallel [(const_int 1)]))
+ (vec_select:<V_addsub> (match_dup 2) (parallel [(const_int 1)])))))]
+ "TARGET_PLUS_DMPY"
+ "vsubadd<V_addsub_suffix>%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "addsubv4hi3"
+ [(set (match_operand:V4HI 0 "even_register_operand" "=r,r")
+ (vec_concat:V4HI
+ (vec_concat:V2HI
+ (plus:HI (vec_select:HI (match_operand:V4HI 1 "even_register_operand" "0,r")
+ (parallel [(const_int 0)]))
+ (vec_select:HI (match_operand:V4HI 2 "even_register_operand" "r,r")
+ (parallel [(const_int 0)])))
+ (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
+ (vec_select:HI (match_dup 2) (parallel [(const_int 1)]))))
+ (vec_concat:V2HI
+ (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
+ (vec_select:HI (match_dup 2) (parallel [(const_int 2)])))
+ (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))
+ (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
+ ))]
+ "TARGET_PLUS_QMACW"
+ "vaddsub4h%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "subaddv4hi3"
+ [(set (match_operand:V4HI 0 "even_register_operand" "=r,r")
+ (vec_concat:V4HI
+ (vec_concat:V2HI
+ (minus:HI (vec_select:HI (match_operand:V4HI 1 "even_register_operand" "0,r")
+ (parallel [(const_int 0)]))
+ (vec_select:HI (match_operand:V4HI 2 "even_register_operand" "r,r")
+ (parallel [(const_int 0)])))
+ (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
+ (vec_select:HI (match_dup 2) (parallel [(const_int 1)]))))
+ (vec_concat:V2HI
+ (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
+ (vec_select:HI (match_dup 2) (parallel [(const_int 2)])))
+ (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))
+ (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
+ ))]
+ "TARGET_PLUS_QMACW"
+ "vsubadd4h%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+;; Multiplication
+(define_insn "dmpyh<V_US_suffix>"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI
+ (mult:SI
+ (SE:SI
+ (vec_select:HI (match_operand:V2HI 1 "register_operand" "0,r")
+ (parallel [(const_int 0)])))
+ (SE:SI
+ (vec_select:HI (match_operand:V2HI 2 "register_operand" "r,r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (SE:SI (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
+ (SE:SI (vec_select:HI (match_dup 2) (parallel [(const_int 1)]))))))
+ (set (reg:DI ARCV2_ACC)
+ (zero_extend:DI
+ (plus:SI
+ (mult:SI
+ (SE:SI (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
+ (SE:SI (vec_select:HI (match_dup 2) (parallel [(const_int 0)]))))
+ (mult:SI
+ (SE:SI (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
+ (SE:SI (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))))]
+ "TARGET_PLUS_DMPY"
+ "dmpy<V_US_suffix>%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+;; We can use dmac as well here. To be investigated which version
+;; brings more.
+(define_expand "sdot_prodv2hi"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")
+ (match_operand:SI 3 "register_operand" "")]
+ "TARGET_PLUS_DMPY"
+{
+ rtx t = gen_reg_rtx (SImode);
+ emit_insn (gen_dmpyh (t, operands[1], operands[2]));
+ emit_insn (gen_addsi3 (operands[0], operands[3], t));
+ DONE;
+})
+
+(define_expand "udot_prodv2hi"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")
+ (match_operand:SI 3 "register_operand" "")]
+ "TARGET_PLUS_DMPY"
+{
+ rtx t = gen_reg_rtx (SImode);
+ emit_insn (gen_dmpyhu (t, operands[1], operands[2]));
+ emit_insn (gen_addsi3 (operands[0], operands[3], t));
+ DONE;
+})
+
+(define_insn "arc_vec_<V_US>mult_lo_v4hi"
+ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r")
+ (mult:V2SI (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 1 "even_register_operand" "0,r")
+ (parallel [(const_int 0) (const_int 1)])))
+ (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 2 "even_register_operand" "r,r")
+ (parallel [(const_int 0) (const_int 1)])))))
+ (set (reg:V2SI ARCV2_ACC)
+ (mult:V2SI (SE:V2SI (vec_select:V2HI (match_dup 1)
+ (parallel [(const_int 0) (const_int 1)])))
+ (SE:V2SI (vec_select:V2HI (match_dup 2)
+ (parallel [(const_int 0) (const_int 1)])))))
+ ]
+ "TARGET_PLUS_MACD"
+ "vmpy2h<V_US_suffix>%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "arc_vec_<V_US>multacc_lo_v4hi"
+ [(set (reg:V2SI ARCV2_ACC)
+ (mult:V2SI (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 0 "even_register_operand" "r")
+ (parallel [(const_int 0) (const_int 1)])))
+ (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 1 "even_register_operand" "r")
+ (parallel [(const_int 0) (const_int 1)])))))
+ ]
+ "TARGET_PLUS_MACD"
+ "vmpy2h<V_US_suffix>%? 0, %0, %1"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "no")
+ (set_attr "cond" "nocond")])
+
+(define_expand "vec_widen_<V_US>mult_lo_v4hi"
+ [(set (match_operand:V2SI 0 "even_register_operand" "")
+ (mult:V2SI (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 1 "even_register_operand" "")
+ (parallel [(const_int 0) (const_int 1)])))
+ (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 2 "even_register_operand" "")
+ (parallel [(const_int 0) (const_int 1)])))))]
+ "TARGET_PLUS_QMACW"
+ {
+ emit_insn (gen_arc_vec_<V_US>mult_lo_v4hi (operands[0],
+ operands[1],
+ operands[2]));
+ DONE;
+ }
+)
+
+(define_insn "arc_vec_<V_US>mult_hi_v4hi"
+ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r")
+ (mult:V2SI (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 1 "even_register_operand" "0,r")
+ (parallel [(const_int 2) (const_int 3)])))
+ (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 2 "even_register_operand" "r,r")
+ (parallel [(const_int 2) (const_int 3)])))))
+ (set (reg:V2SI ARCV2_ACC)
+ (mult:V2SI (SE:V2SI (vec_select:V2HI (match_dup 1)
+ (parallel [(const_int 2) (const_int 3)])))
+ (SE:V2SI (vec_select:V2HI (match_dup 2)
+ (parallel [(const_int 2) (const_int 3)])))))
+ ]
+ "TARGET_PLUS_QMACW"
+ "vmpy2h<V_US_suffix>%? %0, %R1, %R2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_expand "vec_widen_<V_US>mult_hi_v4hi"
+ [(set (match_operand:V2SI 0 "even_register_operand" "")
+ (mult:V2SI (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 1 "even_register_operand" "")
+ (parallel [(const_int 2) (const_int 3)])))
+ (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 2 "even_register_operand" "")
+ (parallel [(const_int 2) (const_int 3)])))))]
+ "TARGET_PLUS_MACD"
+ {
+ emit_insn (gen_arc_vec_<V_US>mult_hi_v4hi (operands[0],
+ operands[1],
+ operands[2]));
+ DONE;
+ }
+)
+
+(define_insn "arc_vec_<V_US>mac_hi_v4hi"
+ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r")
+ (plus:V2SI
+ (reg:V2SI ARCV2_ACC)
+ (mult:V2SI (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 1 "even_register_operand" "0,r")
+ (parallel [(const_int 2) (const_int 3)])))
+ (SE:V2SI (vec_select:V2HI
+ (match_operand:V4HI 2 "even_register_operand" "r,r")
+ (parallel [(const_int 2) (const_int 3)]))))))
+ (set (reg:V2SI ARCV2_ACC)
+ (plus:V2SI
+ (reg:V2SI ARCV2_ACC)
+ (mult:V2SI (SE:V2SI (vec_select:V2HI (match_dup 1)
+ (parallel [(const_int 2) (const_int 3)])))
+ (SE:V2SI (vec_select:V2HI (match_dup 2)
+ (parallel [(const_int 2) (const_int 3)]))))))
+ ]
+ "TARGET_PLUS_MACD"
+ "vmac2h<V_US_suffix>%? %0, %R1, %R2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+;; Builtins
+(define_insn "dmach"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (unspec:SI [(match_operand:V2HI 1 "register_operand" "0,r")
+ (match_operand:V2HI 2 "register_operand" "r,r")
+ (reg:DI ARCV2_ACC)]
+ UNSPEC_ARC_DMACH))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_DMPY"
+ "dmach%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "dmachu"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (unspec:SI [(match_operand:V2HI 1 "register_operand" "0,r")
+ (match_operand:V2HI 2 "register_operand" "r,r")
+ (reg:DI ARCV2_ACC)]
+ UNSPEC_ARC_DMACHU))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_DMPY"
+ "dmachu%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "dmacwh"
+ [(set (match_operand:DI 0 "even_register_operand" "=r,r")
+ (unspec:DI [(match_operand:V2SI 1 "even_register_operand" "0,r")
+ (match_operand:V2HI 2 "register_operand" "r,r")
+ (reg:DI ARCV2_ACC)]
+ UNSPEC_ARC_DMACWH))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_QMACW"
+ "dmacwh%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "dmacwhu"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (unspec:DI [(match_operand:V2SI 1 "even_register_operand" "0,r")
+ (match_operand:V2HI 2 "register_operand" "r,r")
+ (reg:DI ARCV2_ACC)]
+ UNSPEC_ARC_DMACWHU))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_QMACW"
+ "dmacwhu%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "vmac2h"
+ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r")
+ (unspec:V2SI [(match_operand:V2HI 1 "register_operand" "0,r")
+ (match_operand:V2HI 2 "register_operand" "r,r")
+ (reg:DI ARCV2_ACC)]
+ UNSPEC_ARC_VMAC2H))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_MACD"
+ "vmac2h%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "vmac2hu"
+ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r")
+ (unspec:V2SI [(match_operand:V2HI 1 "register_operand" "0,r")
+ (match_operand:V2HI 2 "register_operand" "r,r")
+ (reg:DI ARCV2_ACC)]
+ UNSPEC_ARC_VMAC2HU))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_MACD"
+ "vmac2hu%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "vmpy2h"
+ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r")
+ (unspec:V2SI [(match_operand:V2HI 1 "register_operand" "0,r")
+ (match_operand:V2HI 2 "register_operand" "r,r")]
+ UNSPEC_ARC_VMPY2H))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_MACD"
+ "vmpy2h%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "vmpy2hu"
+ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r")
+ (unspec:V2SI [(match_operand:V2HI 1 "register_operand" "0,r")
+ (match_operand:V2HI 2 "register_operand" "r,r")]
+ UNSPEC_ARC_VMPY2HU))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_MACD"
+ "vmpy2hu%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "qmach"
+ [(set (match_operand:DI 0 "even_register_operand" "=r,r")
+ (unspec:DI [(match_operand:V4HI 1 "even_register_operand" "0,r")
+ (match_operand:V4HI 2 "even_register_operand" "r,r")
+ (reg:DI ARCV2_ACC)]
+ UNSPEC_ARC_QMACH))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_QMACW"
+ "qmach%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "qmachu"
+ [(set (match_operand:DI 0 "even_register_operand" "=r,r")
+ (unspec:DI [(match_operand:V4HI 1 "even_register_operand" "0,r")
+ (match_operand:V4HI 2 "even_register_operand" "r,r")
+ (reg:DI ARCV2_ACC)]
+ UNSPEC_ARC_QMACHU))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_QMACW"
+ "qmachu%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "qmpyh"
+ [(set (match_operand:DI 0 "even_register_operand" "=r,r")
+ (unspec:DI [(match_operand:V4HI 1 "even_register_operand" "0,r")
+ (match_operand:V4HI 2 "even_register_operand" "r,r")]
+ UNSPEC_ARC_QMPYH))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_QMACW"
+ "qmpyh%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "qmpyhu"
+ [(set (match_operand:DI 0 "even_register_operand" "=r,r")
+ (unspec:DI [(match_operand:V4HI 1 "even_register_operand" "0,r")
+ (match_operand:V4HI 2 "even_register_operand" "r,r")]
+ UNSPEC_ARC_QMPYHU))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_QMACW"
+ "qmpyhu%? %0, %1, %2"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])