[PATCH 16/57][Arm][GAS] Add support for MVE instructions: vdup, vddup, vdwdup, vidup...
authorAndre Vieira <andre.simoesdiasvieira@arm.com>
Wed, 15 May 2019 17:36:48 +0000 (18:36 +0100)
committerAndre Vieira <andre.simoesdiasvieira@arm.com>
Thu, 16 May 2019 15:35:52 +0000 (16:35 +0100)
gas/ChangeLog:
2019-05-16  Andre Vieira  <andre.simoesdiasvieira@arm.com>

* config/tc-arm.c (M_MNEM_vddup, M_MNEM_vdwdup, M_MNEM_vidup,
 M_MNEM_viwdup): New instruction encodings.
(NEON_SHAPE_DEF): New shapes.
(do_mve_viddup): New encoding function.
(do_neon_dup): Change to support new MVE variants.
(insns): Change existing to accept MVE variants and add new.
* testsuite/gas/arm/mve-vddup-bad.d: New test.
* testsuite/gas/arm/mve-vddup-bad.l: New test.
* testsuite/gas/arm/mve-vddup-bad.s: New test.
* testsuite/gas/arm/mve-vdup-bad.d: New test.
* testsuite/gas/arm/mve-vdup-bad.l: New test.
* testsuite/gas/arm/mve-vdup-bad.s: New test.
* testsuite/gas/arm/mve-vidup-bad.d: New test.
* testsuite/gas/arm/mve-vidup-bad.l: New test.
* testsuite/gas/arm/mve-vidup-bad.s: New test.

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/gas/arm/mve-vddup-bad.d [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vddup-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vddup-bad.s [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vdup-bad.d [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vdup-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vdup-bad.s [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vidup-bad.d [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vidup-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/mve-vidup-bad.s [new file with mode: 0644]

index 1ac53fc189368553765dd80b835b8d49fabe00b7..8b6ba620db579a38563ccae78b3060e6cb1f589c 100644 (file)
@@ -1,3 +1,21 @@
+2019-05-16  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+       * config/tc-arm.c (M_MNEM_vddup, M_MNEM_vdwdup, M_MNEM_vidup,
+        M_MNEM_viwdup): New instruction encodings.
+       (NEON_SHAPE_DEF): New shapes.
+       (do_mve_viddup): New encoding function.
+       (do_neon_dup): Change to support new MVE variants.
+       (insns): Change existing to accept MVE variants and add new.
+       * testsuite/gas/arm/mve-vddup-bad.d: New test.
+       * testsuite/gas/arm/mve-vddup-bad.l: New test.
+       * testsuite/gas/arm/mve-vddup-bad.s: New test.
+       * testsuite/gas/arm/mve-vdup-bad.d: New test.
+       * testsuite/gas/arm/mve-vdup-bad.l: New test.
+       * testsuite/gas/arm/mve-vdup-bad.s: New test.
+       * testsuite/gas/arm/mve-vidup-bad.d: New test.
+       * testsuite/gas/arm/mve-vidup-bad.l: New test.
+       * testsuite/gas/arm/mve-vidup-bad.s: New test.
+
 2019-05-16  Andre Vieira  <andre.simoesdiasvieira@arm.com>
 
        * config/tc-arm.c (do_mve_vfmas): New encoding function.
index 504fe1d4bd9bf1b363a83664fb9dc9e74e47b368..9196476c1f0e877ca816fb95aa1661fb90d17b9f 100644 (file)
@@ -14154,6 +14154,10 @@ do_t_loloop (void)
 #define M_MNEM_vaddlva 0xee890f20
 #define M_MNEM_vaddv   0xeef10f00
 #define M_MNEM_vaddva  0xeef10f20
+#define M_MNEM_vddup   0xee011f6e
+#define M_MNEM_vdwdup  0xee011f60
+#define M_MNEM_vidup   0xee010f6e
+#define M_MNEM_viwdup  0xee010f60
 
 /* Neon instruction encoder helpers.  */
 
@@ -14318,8 +14322,10 @@ NEON_ENC_TAB
      - a table used to drive neon_select_shape.  */
 
 #define NEON_SHAPE_DEF                 \
+  X(4, (Q, R, R, I), QUAD),            \
   X(4, (R, R, S, S), QUAD),            \
   X(4, (S, S, R, R), QUAD),            \
+  X(3, (Q, R, I), QUAD),               \
   X(3, (I, Q, Q), QUAD),               \
   X(3, (I, Q, R), QUAD),               \
   X(3, (R, Q, Q), QUAD),               \
@@ -15605,6 +15611,49 @@ do_mve_vfmas (void)
   inst.is_neon = 1;
 }
 
+static void
+do_mve_viddup (void)
+{
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  unsigned imm = inst.relocs[0].exp.X_add_number;
+  constraint (imm != 1 && imm != 2 && imm != 4 && imm != 8,
+             _("immediate must be either 1, 2, 4 or 8"));
+
+  enum neon_shape rs;
+  struct neon_type_el et;
+  unsigned Rm;
+  if (inst.instruction == M_MNEM_vddup || inst.instruction == M_MNEM_vidup)
+    {
+      rs = neon_select_shape (NS_QRI, NS_NULL);
+      et = neon_check_type (2, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK);
+      Rm = 7;
+    }
+  else
+    {
+      constraint ((inst.operands[2].reg % 2) != 1, BAD_EVEN);
+      if (inst.operands[2].reg == REG_SP)
+       as_tsktsk (MVE_BAD_SP);
+      else if (inst.operands[2].reg == REG_PC)
+       first_error (BAD_PC);
+
+      rs = neon_select_shape (NS_QRRI, NS_NULL);
+      et = neon_check_type (3, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK, N_EQK);
+      Rm = inst.operands[2].reg >> 1;
+    }
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= neon_logbits (et.size) << 20;
+  inst.instruction |= inst.operands[1].reg << 16;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= (imm > 2) << 7;
+  inst.instruction |= Rm << 1;
+  inst.instruction |= (imm == 2 || imm == 8);
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vcmul (void)
 {
@@ -18404,6 +18453,8 @@ do_neon_dup (void)
 {
   if (inst.operands[1].isscalar)
     {
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
+                 BAD_FPU);
       enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
       struct neon_type_el et = neon_check_type (2, rs,
        N_EQK, N_8 | N_16 | N_32 | N_KEY);
@@ -18431,6 +18482,23 @@ do_neon_dup (void)
       enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
       struct neon_type_el et = neon_check_type (2, rs,
        N_8 | N_16 | N_32 | N_KEY, N_EQK);
+      if (rs == NS_QR)
+       {
+         if (check_simd_pred_availability (0, NEON_CHECK_ARCH))
+           return;
+       }
+      else
+       constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
+                   BAD_FPU);
+
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+       {
+         if (inst.operands[1].reg == REG_SP)
+           as_tsktsk (MVE_BAD_SP);
+         else if (inst.operands[1].reg == REG_PC)
+           as_tsktsk (MVE_BAD_PC);
+       }
+
       /* Duplicate ARM register to lanes of vector.  */
       NEON_ENCODE (ARMREG, inst);
       switch (et.size)
@@ -23656,7 +23724,6 @@ static const struct asm_opcode insns[] =
  NUF(vrev16,    1b00100, 2, (RNDQ, RNDQ),     neon_rev),
  NUF(vrev16q,   1b00100, 2, (RNQ,  RNQ),      neon_rev),
   /* Vector replicate. Sizes 8 16 32.  */
- nCE(vdup,      _vdup,    2, (RNDQ, RR_RNSC),  neon_dup),
  nCE(vdupq,     _vdup,    2, (RNQ,  RR_RNSC),  neon_dup),
   /* VMOVL. Types S8 S16 S32 U8 U16 U32.  */
  NUF(vmovl,     0800a10, 2, (RNQ, RND),       neon_movl),
@@ -24218,6 +24285,10 @@ static const struct asm_opcode insns[] =
  mCEF(vaddlva, _vaddlva,   3, (RRe, RRo, RMQ),                   mve_vaddlv),
  mCEF(vaddv,   _vaddv,     2, (RRe, RMQ),                        mve_vaddv),
  mCEF(vaddva,  _vaddva,    2, (RRe, RMQ),                        mve_vaddv),
+ mCEF(vddup,   _vddup,     3, (RMQ, RRe, EXPi),                  mve_viddup),
+ mCEF(vdwdup,  _vdwdup,    4, (RMQ, RRe, RR, EXPi),              mve_viddup),
+ mCEF(vidup,   _vidup,     3, (RMQ, RRe, EXPi),                  mve_viddup),
+ mCEF(viwdup,  _viwdup,    4, (RMQ, RRe, RR, EXPi),              mve_viddup),
 
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
@@ -24280,6 +24351,7 @@ static const struct asm_opcode insns[] =
  mnUF(veor,      _veor,                  3, (RNDQMQ, oRNDQMQ, RNDQMQ),      neon_logic),
  MNUF(vcls,      1b00400,        2, (RNDQMQ, RNDQMQ),               neon_cls),
  MNUF(vclz,      1b00480,        2, (RNDQMQ, RNDQMQ),               neon_clz),
+ mnCE(vdup,      _vdup,                  2, (RNDQMQ, RR_RNSC),              neon_dup),
 
 #undef ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vddup-bad.d b/gas/testsuite/gas/arm/mve-vddup-bad.d
new file mode 100644 (file)
index 0000000..a6522dc
--- /dev/null
@@ -0,0 +1,6 @@
+#name: bad MVE VDDUP and VDWDUP instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vddup-bad.l
+
+.*: +file format .*arm.*
+
diff --git a/gas/testsuite/gas/arm/mve-vddup-bad.l b/gas/testsuite/gas/arm/mve-vddup-bad.l
new file mode 100644 (file)
index 0000000..92ff965
--- /dev/null
@@ -0,0 +1,33 @@
+[^:]*: Assembler messages:
+[^:]*:16: Error: bad type in SIMD instruction -- `vddup.s16 q0,r0,#1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vddup.u64 q0,r0,#1'
+[^:]*:18: Error: immediate must be either 1, 2, 4 or 8 -- `vddup.u32 q0,r0,#3'
+[^:]*:19: Error: immediate must be either 1, 2, 4 or 8 -- `vddup.u32 q0,r0,#0'
+[^:]*:20: Error: bad type in SIMD instruction -- `vdwdup.s16 q0,r0,r1,#1'
+[^:]*:21: Error: bad type in SIMD instruction -- `vdwdup.u64 q0,r0,r1,#1'
+[^:]*:22: Error: immediate must be either 1, 2, 4 or 8 -- `vdwdup.u32 q0,r0,r1,#3'
+[^:]*:23: Error: immediate must be either 1, 2, 4 or 8 -- `vdwdup.u32 q0,r0,r1,#0'
+[^:]*:24: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:25: Error: r15 not allowed here -- `vdwdup.u32 q0,r0,pc,#1'
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:29: Error: syntax error -- `vddupeq.u32 q0,r0,#1'
+[^:]*:30: Error: syntax error -- `vddupeq.u32 q0,r0,#1'
+[^:]*:32: Error: syntax error -- `vddupeq.u32 q0,r0,#1'
+[^:]*:33: Error: vector predicated instruction should be in VPT/VPST block -- `vddupt.u32 q0,r0,#1'
+[^:]*:35: Error: instruction missing MVE vector predication code -- `vddup.u32 q0,r0,#1'
+[^:]*:37: Error: syntax error -- `vdwdupeq.u32 q0,r0,r1,#1'
+[^:]*:38: Error: syntax error -- `vdwdupeq.u32 q0,r0,r1,#1'
+[^:]*:40: Error: syntax error -- `vdwdupeq.u32 q0,r0,r1,#1'
+[^:]*:41: Error: vector predicated instruction should be in VPT/VPST block -- `vdwdupt.u32 q0,r0,r1,#1'
+[^:]*:43: Error: instruction missing MVE vector predication code -- `vdwdup.u32 q0,r0,r1,#1'
diff --git a/gas/testsuite/gas/arm/mve-vddup-bad.s b/gas/testsuite/gas/arm/mve-vddup-bad.s
new file mode 100644 (file)
index 0000000..9951e9d
--- /dev/null
@@ -0,0 +1,43 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vddup.u32 q0, r2, #1
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vdwdup.u32 q0, r2, r1, #1
+.endr
+.endm
+.syntax unified
+.thumb
+vddup.s16 q0, r0, #1
+vddup.u64 q0, r0, #1
+vddup.u32 q0, r0, #3
+vddup.u32 q0, r0, #0
+vdwdup.s16 q0, r0, r1, #1
+vdwdup.u64 q0, r0, r1, #1
+vdwdup.u32 q0, r0, r1, #3
+vdwdup.u32 q0, r0, r1, #0
+vdwdup.u32 q0, r0, sp, #1
+vdwdup.u32 q0, r0, pc, #1
+cond1
+cond2
+it eq
+vddupeq.u32 q0, r0, #1
+vddupeq.u32 q0, r0, #1
+vpst
+vddupeq.u32 q0, r0, #1
+vddupt.u32 q0, r0, #1
+vpst
+vddup.u32 q0, r0, #1
+it eq
+vdwdupeq.u32 q0, r0, r1, #1
+vdwdupeq.u32 q0, r0, r1, #1
+vpst
+vdwdupeq.u32 q0, r0, r1, #1
+vdwdupt.u32 q0, r0, r1, #1
+vpst
+vdwdup.u32 q0, r0, r1, #1
diff --git a/gas/testsuite/gas/arm/mve-vdup-bad.d b/gas/testsuite/gas/arm/mve-vdup-bad.d
new file mode 100644 (file)
index 0000000..2ad9597
--- /dev/null
@@ -0,0 +1,5 @@
+#name: bad MVE VDUP instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vdup-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vdup-bad.l b/gas/testsuite/gas/arm/mve-vdup-bad.l
new file mode 100644 (file)
index 0000000..0880839
--- /dev/null
@@ -0,0 +1,16 @@
+[^:]*: Assembler messages:
+[^:]*:11: Error: bad type in SIMD instruction -- `vdup.64 q0,r1'
+[^:]*:12: Error: selected FPU does not support instruction -- `vdup.32 q0,d0\[1\]'
+[^:]*:13: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:14: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Error: syntax error -- `vdupeq.32 q0,r2'
+[^:]*:18: Error: syntax error -- `vdupeq.32 q0,r2'
+[^:]*:20: Error: syntax error -- `vdupeq.32 q0,r2'
+[^:]*:21: Error: incorrect condition in VPT/VPST block -- `vdupt.32 q0,r2'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vdup.32 q0,r2'
diff --git a/gas/testsuite/gas/arm/mve-vdup-bad.s b/gas/testsuite/gas/arm/mve-vdup-bad.s
new file mode 100644 (file)
index 0000000..c6539d8
--- /dev/null
@@ -0,0 +1,23 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vdup.32 q0, r2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vdup.f16 q0, r1
+vdup.64 q0, r1
+vdup.32 q0, d0[1]
+vdup.32 q0, sp
+vdup.32 q0, pc
+cond
+it eq
+vdupeq.32 q0, r2
+vdupeq.32 q0, r2
+vpste
+vdupeq.32 q0, r2
+vdupt.32 q0, r2
+vpst
+vdup.32 q0, r2
diff --git a/gas/testsuite/gas/arm/mve-vidup-bad.d b/gas/testsuite/gas/arm/mve-vidup-bad.d
new file mode 100644 (file)
index 0000000..6a9a038
--- /dev/null
@@ -0,0 +1,5 @@
+#name: bad MVE VIDUP and VIWDUP instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vidup-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vidup-bad.l b/gas/testsuite/gas/arm/mve-vidup-bad.l
new file mode 100644 (file)
index 0000000..5fb7425
--- /dev/null
@@ -0,0 +1,34 @@
+[^:]*: Assembler messages:
+[^:]*:16: Error: bad type in SIMD instruction -- `vidup.s16 q0,r0,#1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vidup.u64 q0,r0,#1'
+[^:]*:18: Error: immediate must be either 1, 2, 4 or 8 -- `vidup.u32 q0,r0,#3'
+[^:]*:19: Error: immediate must be either 1, 2, 4 or 8 -- `vidup.u32 q0,r0,#0'
+[^:]*:20: Error: bad type in SIMD instruction -- `viwdup.s16 q0,r0,r1,#1'
+[^:]*:21: Error: bad type in SIMD instruction -- `viwdup.u64 q0,r0,r1,#1'
+[^:]*:22: Error: immediate must be either 1, 2, 4 or 8 -- `viwdup.u32 q0,r0,r1,#3'
+[^:]*:23: Error: immediate must be either 1, 2, 4 or 8 -- `viwdup.u32 q0,r0,r1,#0'
+[^:]*:24: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:25: Error: r15 not allowed here -- `viwdup.u32 q0,r0,pc,#1'
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:29: Error: syntax error -- `vidupeq.u32 q0,r0,#1'
+[^:]*:30: Error: syntax error -- `vidupeq.u32 q0,r0,#1'
+[^:]*:32: Error: syntax error -- `vidupeq.u32 q0,r0,#1'
+[^:]*:33: Error: vector predicated instruction should be in VPT/VPST block -- `vidupt.u32 q0,r0,#1'
+[^:]*:35: Error: instruction missing MVE vector predication code -- `vidup.u32 q0,r0,#1'
+[^:]*:37: Error: syntax error -- `viwdupeq.u32 q0,r0,r1,#1'
+[^:]*:38: Error: syntax error -- `viwdupeq.u32 q0,r0,r1,#1'
+[^:]*:40: Error: syntax error -- `viwdupeq.u32 q0,r0,r1,#1'
+[^:]*:41: Error: vector predicated instruction should be in VPT/VPST block -- `viwdupt.u32 q0,r0,r1,#1'
+[^:]*:43: Error: instruction missing MVE vector predication code -- `viwdup.u32 q0,r0,r1,#1'
+
diff --git a/gas/testsuite/gas/arm/mve-vidup-bad.s b/gas/testsuite/gas/arm/mve-vidup-bad.s
new file mode 100644 (file)
index 0000000..3d3a448
--- /dev/null
@@ -0,0 +1,43 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vidup.u32 q0, r2, #1
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+viwdup.u32 q0, r2, r1, #1
+.endr
+.endm
+.syntax unified
+.thumb
+vidup.s16 q0, r0, #1
+vidup.u64 q0, r0, #1
+vidup.u32 q0, r0, #3
+vidup.u32 q0, r0, #0
+viwdup.s16 q0, r0, r1, #1
+viwdup.u64 q0, r0, r1, #1
+viwdup.u32 q0, r0, r1, #3
+viwdup.u32 q0, r0, r1, #0
+viwdup.u32 q0, r0, sp, #1
+viwdup.u32 q0, r0, pc, #1
+cond1
+cond2
+it eq
+vidupeq.u32 q0, r0, #1
+vidupeq.u32 q0, r0, #1
+vpst
+vidupeq.u32 q0, r0, #1
+vidupt.u32 q0, r0, #1
+vpst
+vidup.u32 q0, r0, #1
+it eq
+viwdupeq.u32 q0, r0, r1, #1
+viwdupeq.u32 q0, r0, r1, #1
+vpst
+viwdupeq.u32 q0, r0, r1, #1
+viwdupt.u32 q0, r0, r1, #1
+vpst
+viwdup.u32 q0, r0, r1, #1