base/asm-common.h: Add some macros for shifting entire NEON vectors.
[catacomb] / base / asm-common.h
index 642820a..6ec238f 100644 (file)
@@ -739,6 +739,29 @@ name:
 #endif
 .endm
 
+.macro vzero   vz=q15
+       // Set VZ (default q15) to zero.
+       vmov.u32 \vz, #0
+.endm
+
+.macro vshl128 vd, vn, nbit, vz=q15
+       // Set VD to VN shifted left by NBIT.  Assume VZ (default q15) is
+       // all-bits-zero.  NBIT must be a multiple of 8.
+  .if \nbit&3 != 0
+       .error  "shift quantity must be whole number of bytes"
+  .endif
+       vext.8  \vd, \vz, \vn, #16 - (\nbit >> 3)
+.endm
+
+.macro vshr128 vd, vn, nbit, vz=q15
+       // Set VD to VN shifted right by NBIT.  Assume VZ (default q15) is
+       // all-bits-zero.  NBIT must be a multiple of 8.
+  .if \nbit&3 != 0
+       .error  "shift quantity must be whole number of bytes"
+  .endif
+       vext.8  \vd, \vn, \vz, #\nbit >> 3
+.endm
+
 // Apply decoration decor to register name reg.
 #define _REGFORM(reg, decor) _GLUE(_REGFORM_, reg)(decor)
 
@@ -1073,6 +1096,29 @@ name:
 #endif
 .endm
 
+.macro vzero   vz=v31
+       // Set VZ (default v31) to zero.
+       dup     \vz\().4s, wzr
+.endm
+
+.macro vshl128 vd, vn, nbit, vz=v31
+       // Set VD to VN shifted left by NBIT.  Assume VZ (default v31) is
+       // all-bits-zero.  NBIT must be a multiple of 8.
+  .if \nbit&3 != 0
+       .error  "shift quantity must be whole number of bytes"
+  .endif
+       ext     \vd\().16b, \vz\().16b, \vn\().16b, #16 - (\nbit >> 3)
+.endm
+
+.macro vshr128 vd, vn, nbit, vz=v31
+       // Set VD to VN shifted right by NBIT.  Assume VZ (default v31) is
+       // all-bits-zero.  NBIT must be a multiple of 8.
+  .if \nbit&3 != 0
+       .error  "shift quantity must be whole number of bytes"
+  .endif
+       ext     \vd\().16b, \vn\().16b, \vz\().16b, #\nbit >> 3
+.endm
+
 // Stack management and unwinding.
 .macro setfp   fp=x29, offset=0
   // If you're just going through the motions with a fixed-size stack frame,