base/asm-common.h: Add some macros for shifting entire NEON vectors.
[catacomb] / base / asm-common.h
index 10a79a5..6ec238f 100644 (file)
@@ -453,7 +453,7 @@ name:
 #define WHOLE(reg) _REGFORM(reg, r)
 
 // Stack management and unwinding.
-.macro setfp   fp, offset=0
+.macro setfp   fp=R_bp(r), offset=0
   .if \offset == 0
        mov     \fp, R_sp(r)
 #if __ELF__
@@ -723,12 +723,12 @@ name:
 #if WANT_PIC
        ldr\cond \reg, .L$_leaextq$\@
 .L$_leaextq_pc$\@:
-       .if     .L$_pcoff == 8
+  .if .L$_pcoff == 8
        ldr\cond \reg, [pc, \reg]
-       .else
+  .else
        add\cond \reg, pc
        ldr\cond \reg, [\reg]
-       .endif
+  .endif
   _LIT
        .balign 4
 .L$_leaextq$\@:
@@ -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)
 
@@ -989,7 +1012,7 @@ name:
 #define QQ(qlo, qhi) D0(qlo)-D1(qhi)
 
 // Stack management and unwinding.
-.macro setfp   fp, offset=0
+.macro setfp   fp=r11, offset=0
   .if \offset == 0
        mov     \fp, sp
          .setfp \fp, sp
@@ -1022,12 +1045,12 @@ name:
 .endm
 
 .macro pushreg rr:vararg
-       stmfd   sp!, {\rr}
+       push    {\rr}
          .save {\rr}
 .endm
 
 .macro popreg  rr:vararg
-       ldmfd   sp!, {\rr}
+       pop     {\rr}
 .endm
 
 .macro pushvfp rr:vararg
@@ -1073,8 +1096,31 @@ 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, offset=0
+.macro setfp   fp=x29, offset=0
   // If you're just going through the motions with a fixed-size stack frame,
   // then you want to say `add x29, sp, #OFFSET' directly, which will avoid
   // pointlessly restoring sp later.
@@ -1113,8 +1159,8 @@ name:
          .cfi_adjust_cfa_offset -\n
 .endm
 
-.macro pushreg x, y=
-  .ifeqs "\y", ""
+.macro pushreg x, y=nil
+  .ifeqs "\y", "nil"
        str     \x, [sp, #-16]!
          .cfi_adjust_cfa_offset +16
          .cfi_rel_offset \x, 0
@@ -1126,8 +1172,8 @@ name:
   .endif
 .endm
 
-.macro popreg  x, y=
-  .ifeqs "\y", ""
+.macro popreg  x, y=nil
+  .ifeqs "\y", "nil"
        ldr     \x, [sp], #16
          .cfi_restore \x
          .cfi_adjust_cfa_offset -16
@@ -1139,9 +1185,9 @@ name:
   .endif
 .endm
 
-.macro savereg x, y, z=
-  .ifeqs "\z", ""
-       str     \x, [sp, #\y]
+.macro savereg x, y, z=nil
+  .ifeqs "\z", "nil"
+       str     \x, [sp, \y]
          .cfi_rel_offset \x, \y
   .else
        stp     \x, \y, [sp, #\z]
@@ -1150,9 +1196,9 @@ name:
   .endif
 .endm
 
-.macro rstrreg x, y, z=
-  .ifeqs "\z", ""
-       ldr     \x, [sp, #\y]
+.macro rstrreg x, y, z=nil
+  .ifeqs "\z", "nil"
+       ldr     \x, [sp, \y]
          .cfi_restore \x
   .else
        ldp     \x, \y, [sp, #\z]