]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/arc/simdext.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / arc / simdext.md
index 41c426906331ba474aed5ebb098bb15a51b135f4..4e51a237c3ae175cce0f60376aabaa1dd67c24ec 100644 (file)
@@ -1,5 +1,5 @@
 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler
-;; Copyright (C) 2007-2021 Free Software Foundation, Inc.
+;; Copyright (C) 2007-2024 Free Software Foundation, Inc.
 
 ;; This file is part of GCC.
 
 (define_mode_attr V_addsub_suffix [(V2HI "2h") (V2SI "")])
 
 ;;all vectors
-(define_mode_iterator VCT [V2HI V4HI V2SI])
+(define_mode_iterator VCT [(V2HI "TARGET_PLUS_DMPY")
+                          (V4HI "TARGET_PLUS_QMACW")
+                          (V2SI "TARGET_PLUS_QMACW")])
 (define_mode_attr V_suffix [(V2HI "2h") (V4HI "4h") (V2SI "2")])
 
+(define_code_iterator EMUVEC [(mult "TARGET_MPYW")
+                             (div "TARGET_DIVREM")
+                             smax smin])
+
+(define_code_attr voptab [(mult "mul")
+                         (div "div")
+                         (smin "smin")
+                         (smax "smax")])
+
 ;; Widening operations.
 (define_code_iterator SE [sign_extend zero_extend])
 (define_code_attr V_US [(sign_extend "s") (zero_extend "u")])
        (match_operand:VWH 1 "general_operand"    "i,r,m,r"))]
   "(register_operand (operands[0], <MODE>mode)
        || register_operand (operands[1], <MODE>mode))"
-  "*
-{
-  switch (which_alternative)
-    {
-     default:
-       return \"#\";
-
-     case 1:
-       if (TARGET_PLUS_QMACW
-          && even_register_operand (operands[0], <MODE>mode)
-          && even_register_operand (operands[1], <MODE>mode))
-        return \"vadd2%?\\t%0,%1,0\";
-       return \"#\";
-
-     case 2:
-       if (TARGET_LL64)
-        return \"ldd%U1%V1\\t%0,%1\";
-       return \"#\";
-
-     case 3:
-       if (TARGET_LL64)
-          return \"std%U0%V0\\t%1,%0\";
-        return \"#\";
-    }
-}"
-  "reload_completed"
+  "@
+   #
+   vadd2\\t%0,%1,0
+   ldd%U1%V1\\t%0,%1
+   std%U0%V0\\t%1,%0"
+  "&& reload_completed && arc_split_move_p (operands)"
   [(const_int 0)]
   {
    arc_split_move (operands);
    DONE;
   }
-  [(set_attr "type" "move,multi,load,store")
-   (set_attr "predicable" "no,no,no,no")
-   (set_attr "iscompact"  "false,false,false,false")
-   ])
+  [(set_attr "type" "move,move,load,store")
+   (set_attr "length" "16,8,16,16")])
 
 (define_expand "movmisalign<mode>"
   [(set (match_operand:VWH 0 "general_operand" "")
                  (SE:V2SI (vec_select:V2HI
                            (match_operand:V4HI 2 "even_register_operand")
                            (parallel [(const_int 2) (const_int 3)])))))]
-  "TARGET_PLUS_MACD"
+  "TARGET_PLUS_QMACW"
   {
      emit_insn (gen_arc_vec_<V_US>mult_hi_v4hi (operands[0],
                                                operands[1],
    (set_attr "type" "multi")
    (set_attr "predicable" "yes,no")
    (set_attr "cond" "canuse,nocond")])
+
+;; Emulated vector instructions.
+(define_insn_and_split "<voptab>v2si3"
+  [(set (match_operand:V2SI 0 "register_operand" "=r")
+       (EMUVEC:V2SI (match_operand:V2SI 1 "register_operand" "r")
+                    (match_operand:V2SI 2 "nonmemory_operand" "ri")))]
+  ""
+  "#"
+  "reload_completed"
+  [(const_int 0)]
+  {
+   rtx high_dest = gen_highpart (SImode, operands[0]);
+   rtx low_dest = gen_lowpart (SImode, operands[0]);
+   rtx high_op1 = gen_highpart (SImode, operands[1]);
+   rtx low_op1 = gen_lowpart (SImode, operands[1]);
+   rtx high_op2 = gen_highpart (SImode, operands[2]);
+   rtx low_op2 = gen_lowpart (SImode, operands[2]);
+   emit_insn (gen_<voptab>si3 (low_dest, low_op1, low_op2));
+   emit_insn (gen_<voptab>si3 (high_dest, high_op1, high_op2));
+   DONE;
+  }
+  [(set_attr "length" "12")
+   (set_attr "type" "multi")])
+
+(define_expand "neg<mode>2"
+  [(set (match_operand:VCT 0 "register_operand")
+       (neg:VCT (match_operand:VCT 1 "register_operand")))]
+  "TARGET_PLUS_DMPY"
+  "")
+
+(define_insn "*neg<mode>2"
+  [(set (match_operand:VCT 0 "register_operand" "=r")
+       (neg:VCT (match_operand:VCT 1 "register_operand" "r")))]
+  "TARGET_PLUS_DMPY"
+  "vsub<V_suffix>\\t%0,0,%1"
+  [(set_attr "length" "8")
+   (set_attr "type" "multi")])
+
+(define_insn "reduc_plus_scal_v4hi"
+  [(set (match_operand:HI 0 "even_register_operand" "=r")
+       (unspec:HI [(match_operand:V4HI 1 "even_register_operand" "r")]
+                  UNSPEC_ARC_QMPYH))
+   (clobber (reg:DI ARCV2_ACC))]
+  "TARGET_PLUS_QMACW"
+  "qmpyh\\t%0,%1,1"
+  [(set_attr "length" "4")
+   (set_attr "type" "multi")])
+
+(define_insn "reduc_plus_scal_v2si"
+  [(set (match_operand:SI 0 "even_register_operand" "=r")
+       (unspec:SI [(match_operand:V2SI 1 "even_register_operand" "r")]
+                  UNSPEC_ARC_DMPYWH))
+   (clobber (reg:DI ARCV2_ACC))]
+  "TARGET_PLUS_DMPY"
+  "dmpywh\\t%0,%1,1"
+  [(set_attr "length" "4")
+   (set_attr "type" "multi")])
+
+(define_insn_and_split "vec_duplicatev2si"
+  [(set (match_operand:V2SI 0 "register_operand" "=r")
+       (vec_duplicate:V2SI
+        (match_operand:SI 1 "nonmemory_operand" "ri")))]
+  ""
+  "#"
+  "reload_completed"
+  [(const_int 0)]
+  {
+   rtx high_dest = gen_highpart (SImode, operands[0]);
+   rtx low_dest = gen_lowpart (SImode, operands[0]);
+   emit_move_insn (high_dest, operands[1]);
+   emit_move_insn (low_dest, operands[1]);
+   DONE;
+  }
+  [(set_attr "length" "8")
+   (set_attr "type" "multi")])
+
+(define_insn_and_split "vec_duplicatev4hi"
+  [(set (match_operand:V4HI 0 "register_operand" "=r")
+       (vec_duplicate:V4HI
+        (match_operand:HI 1 "nonmemory_operand" "ri")))]
+  "TARGET_BARREL_SHIFTER"
+  "#"
+  "reload_completed"
+  [(const_int 0)]
+  {
+   rtx high_dest = gen_highpart (SImode, operands[0]);
+   rtx low_dest = gen_lowpart (SImode, operands[0]);
+   rtx tmp = gen_lowpart (SImode, operands[1]);
+   emit_insn (gen_rtx_SET (high_dest,
+                          gen_rtx_ASHIFT (SImode, tmp, GEN_INT (16))));
+   emit_insn (gen_rtx_SET (low_dest,
+                          gen_rtx_IOR (SImode, high_dest, tmp)));
+   emit_move_insn (high_dest, low_dest);
+   DONE;
+  }
+  [(set_attr "length" "12")
+   (set_attr "type" "multi")])