Initial QSfera import
This commit is contained in:
+213
@@ -0,0 +1,213 @@
|
||||
#include "textflag.h"
|
||||
|
||||
#define LOAD_ARGS() \
|
||||
MOVD dst_base+0(FP), R0; \
|
||||
MOVD R0, R3; \
|
||||
MOVD src_base+24(FP), R1; \
|
||||
MOVD R1, R4; \
|
||||
MOVD src_len+32(FP), R2; \
|
||||
BIC $31, R2, R2; \
|
||||
ADD R1, R2, R2
|
||||
|
||||
#define LOAD_ARG_LUT() \
|
||||
MOVD lut+48(FP), R5; \
|
||||
VLD2R (R5), [V0.B16, V1.B16]
|
||||
|
||||
#define LOAD_CONST_LUT() \
|
||||
MOVD $·mask_lut(SB), R6; \
|
||||
MOVD $·bpos_lut(SB), R7; \
|
||||
MOVD $·shft_lut(SB), R8; \
|
||||
VLD1 (R6), [V2.B16]; \
|
||||
VLD1 (R7), [V3.B16]; \
|
||||
VLD1 (R8), [V4.B16]; \
|
||||
VMOVI $43, V5.B8; \
|
||||
VMOVI $47, V6.B8; \
|
||||
VMOVI $15, V7.B8; \
|
||||
VMOVI $16, V8.B8; \
|
||||
|
||||
#define LOAD_INPUT() \
|
||||
VLD4 (R4), [V10.B8, V11.B8, V12.B8, V13.B8]
|
||||
|
||||
#define COMPARE_INPUT(v) \
|
||||
VCMEQ V10.B8, v.B8, V14.B8; \
|
||||
VCMEQ V11.B8, v.B8, V15.B8; \
|
||||
VCMEQ V12.B8, v.B8, V16.B8; \
|
||||
VCMEQ V13.B8, v.B8, V17.B8
|
||||
|
||||
#define UPDATE_INPUT(v) \
|
||||
VBIT V14.B8, v.B8, V10.B8; \
|
||||
VBIT V15.B8, v.B8, V11.B8; \
|
||||
VBIT V16.B8, v.B8, V12.B8; \
|
||||
VBIT V17.B8, v.B8, V13.B8
|
||||
|
||||
#define DECODE_INPUT(goto_err) \
|
||||
/* Create hi/lo nibles */ \
|
||||
VUSHR $4, V10.B8, V18.B8; \
|
||||
VUSHR $4, V11.B8, V19.B8; \
|
||||
VUSHR $4, V12.B8, V20.B8; \
|
||||
VUSHR $4, V13.B8, V21.B8; \
|
||||
VAND V7.B8, V10.B8, V22.B8; \
|
||||
VAND V7.B8, V11.B8, V23.B8; \
|
||||
VAND V7.B8, V12.B8, V24.B8; \
|
||||
VAND V7.B8, V13.B8, V25.B8; \
|
||||
/* Detect invalid input characters */ \
|
||||
VTBL V22.B8, [V2.B8], V22.B8; \
|
||||
VTBL V23.B8, [V2.B8], V23.B8; \
|
||||
VTBL V24.B8, [V2.B8], V24.B8; \
|
||||
VTBL V25.B8, [V2.B8], V25.B8; \
|
||||
VTBL V18.B8, [V3.B8], V26.B8; \
|
||||
VTBL V19.B8, [V3.B8], V27.B8; \
|
||||
VTBL V20.B8, [V3.B8], V28.B8; \
|
||||
VTBL V21.B8, [V3.B8], V29.B8; \
|
||||
VAND V22.B8, V26.B8, V26.B8; \
|
||||
VAND V23.B8, V27.B8, V27.B8; \
|
||||
VAND V24.B8, V28.B8, V28.B8; \
|
||||
VAND V25.B8, V29.B8, V29.B8; \
|
||||
WORD $0x0e209b5a /* VCMEQ $0, V26.B8, V26.B8 */; \
|
||||
WORD $0x0e209b7b /* VCMEQ $0, V27.B8, V27.B8 */; \
|
||||
WORD $0x0e209b9c /* VCMEQ $0, V28.B8, V28.B8 */; \
|
||||
WORD $0x0e209bbd /* VCMEQ $0, V29.B8, V29.B8 */; \
|
||||
VORR V26.B8, V27.B8, V26.B8; \
|
||||
VORR V28.B8, V29.B8, V28.B8; \
|
||||
VORR V26.B8, V28.B8, V26.B8; \
|
||||
VMOV V26.D[0], R5; \
|
||||
VMOV V26.D[1], R6; \
|
||||
ORR R6, R5; \
|
||||
CBNZ R5, goto_err; \
|
||||
/* Shift hi nibles */ \
|
||||
VTBL V18.B8, [V4.B8], V18.B8; \
|
||||
VTBL V19.B8, [V4.B8], V19.B8; \
|
||||
VTBL V20.B8, [V4.B8], V20.B8; \
|
||||
VTBL V21.B8, [V4.B8], V21.B8; \
|
||||
VBIT V14.B8, V8.B8, V18.B8; \
|
||||
VBIT V15.B8, V8.B8, V19.B8; \
|
||||
VBIT V16.B8, V8.B8, V20.B8; \
|
||||
VBIT V17.B8, V8.B8, V21.B8; \
|
||||
/* Combine results */ \
|
||||
VADD V18.B8, V10.B8, V10.B8; \
|
||||
VADD V19.B8, V11.B8, V11.B8; \
|
||||
VADD V20.B8, V12.B8, V12.B8; \
|
||||
VADD V21.B8, V13.B8, V13.B8; \
|
||||
VUSHR $4, V11.B8, V14.B8; \
|
||||
VUSHR $2, V12.B8, V15.B8; \
|
||||
VSHL $2, V10.B8, V10.B8; \
|
||||
VSHL $4, V11.B8, V11.B8; \
|
||||
VSHL $6, V12.B8, V12.B8; \
|
||||
VORR V10.B8, V14.B8, V16.B8; \
|
||||
VORR V11.B8, V15.B8, V17.B8; \
|
||||
VORR V12.B8, V13.B8, V18.B8
|
||||
|
||||
#define ADVANCE_LOOP(goto_loop) \
|
||||
VST3.P [V16.B8, V17.B8, V18.B8], 24(R3); \
|
||||
ADD $32, R4; \
|
||||
CMP R4, R2; \
|
||||
BGT goto_loop
|
||||
|
||||
#define RETURN() \
|
||||
SUB R0, R3; \
|
||||
SUB R1, R4; \
|
||||
MOVD R3, ret+56(FP); \
|
||||
MOVD R4, ret1+64(FP); \
|
||||
RET
|
||||
|
||||
|
||||
// func decodeARM64(dst []byte, src []byte, lut *int8) (int, int)
|
||||
TEXT ·decodeARM64(SB),NOSPLIT,$0-72
|
||||
LOAD_ARGS()
|
||||
LOAD_ARG_LUT()
|
||||
LOAD_CONST_LUT()
|
||||
|
||||
loop:
|
||||
LOAD_INPUT()
|
||||
|
||||
// Compare and normalize the 63rd and 64th characters
|
||||
COMPARE_INPUT(V0)
|
||||
UPDATE_INPUT(V5)
|
||||
COMPARE_INPUT(V1)
|
||||
UPDATE_INPUT(V6)
|
||||
|
||||
DECODE_INPUT(done) // Detect invalid input characters
|
||||
ADVANCE_LOOP(loop) // Store results and continue
|
||||
|
||||
done:
|
||||
// RETURN() replacing the macro to please go vet.
|
||||
SUB R0, R3;
|
||||
SUB R1, R4;
|
||||
MOVD R3, ret+56(FP);
|
||||
MOVD R4, ret1+64(FP);
|
||||
RET
|
||||
|
||||
|
||||
// func decodeStdARM64(dst []byte, src []byte, lut *int8) (int, int)
|
||||
TEXT ·decodeStdARM64(SB),NOSPLIT,$0-72
|
||||
LOAD_ARGS()
|
||||
LOAD_CONST_LUT()
|
||||
|
||||
loop:
|
||||
LOAD_INPUT()
|
||||
COMPARE_INPUT(V6) // Compare to '+'
|
||||
DECODE_INPUT(done) // Detect invalid input characters
|
||||
ADVANCE_LOOP(loop) // Store results and continue
|
||||
|
||||
done:
|
||||
// RETURN() replacing the macro to please go vet.
|
||||
SUB R0, R3;
|
||||
SUB R1, R4;
|
||||
MOVD R3, ret+56(FP);
|
||||
MOVD R4, ret1+64(FP);
|
||||
RET
|
||||
|
||||
|
||||
DATA ·mask_lut+0x00(SB)/1, $0xa8
|
||||
DATA ·mask_lut+0x01(SB)/1, $0xf8
|
||||
DATA ·mask_lut+0x02(SB)/1, $0xf8
|
||||
DATA ·mask_lut+0x03(SB)/1, $0xf8
|
||||
DATA ·mask_lut+0x04(SB)/1, $0xf8
|
||||
DATA ·mask_lut+0x05(SB)/1, $0xf8
|
||||
DATA ·mask_lut+0x06(SB)/1, $0xf8
|
||||
DATA ·mask_lut+0x07(SB)/1, $0xf8
|
||||
DATA ·mask_lut+0x08(SB)/1, $0xf8
|
||||
DATA ·mask_lut+0x09(SB)/1, $0xf8
|
||||
DATA ·mask_lut+0x0a(SB)/1, $0xf0
|
||||
DATA ·mask_lut+0x0b(SB)/1, $0x54
|
||||
DATA ·mask_lut+0x0c(SB)/1, $0x50
|
||||
DATA ·mask_lut+0x0d(SB)/1, $0x50
|
||||
DATA ·mask_lut+0x0e(SB)/1, $0x50
|
||||
DATA ·mask_lut+0x0f(SB)/1, $0x54
|
||||
GLOBL ·mask_lut(SB), NOPTR|RODATA, $16
|
||||
|
||||
DATA ·bpos_lut+0x00(SB)/1, $0x01
|
||||
DATA ·bpos_lut+0x01(SB)/1, $0x02
|
||||
DATA ·bpos_lut+0x02(SB)/1, $0x04
|
||||
DATA ·bpos_lut+0x03(SB)/1, $0x08
|
||||
DATA ·bpos_lut+0x04(SB)/1, $0x10
|
||||
DATA ·bpos_lut+0x05(SB)/1, $0x20
|
||||
DATA ·bpos_lut+0x06(SB)/1, $0x40
|
||||
DATA ·bpos_lut+0x07(SB)/1, $0x80
|
||||
DATA ·bpos_lut+0x08(SB)/1, $0x00
|
||||
DATA ·bpos_lut+0x09(SB)/1, $0x00
|
||||
DATA ·bpos_lut+0x0a(SB)/1, $0x00
|
||||
DATA ·bpos_lut+0x0b(SB)/1, $0x00
|
||||
DATA ·bpos_lut+0x0c(SB)/1, $0x00
|
||||
DATA ·bpos_lut+0x0d(SB)/1, $0x00
|
||||
DATA ·bpos_lut+0x0e(SB)/1, $0x00
|
||||
DATA ·bpos_lut+0x0f(SB)/1, $0x00
|
||||
GLOBL ·bpos_lut(SB), NOPTR|RODATA, $16
|
||||
|
||||
DATA ·shft_lut+0x00(SB)/1, $0x00
|
||||
DATA ·shft_lut+0x01(SB)/1, $0x00
|
||||
DATA ·shft_lut+0x02(SB)/1, $0x13
|
||||
DATA ·shft_lut+0x03(SB)/1, $0x04
|
||||
DATA ·shft_lut+0x04(SB)/1, $0xbf
|
||||
DATA ·shft_lut+0x05(SB)/1, $0xbf
|
||||
DATA ·shft_lut+0x06(SB)/1, $0xb9
|
||||
DATA ·shft_lut+0x07(SB)/1, $0xb9
|
||||
DATA ·shft_lut+0x08(SB)/1, $0x00
|
||||
DATA ·shft_lut+0x09(SB)/1, $0x00
|
||||
DATA ·shft_lut+0x0a(SB)/1, $0x00
|
||||
DATA ·shft_lut+0x0b(SB)/1, $0x00
|
||||
DATA ·shft_lut+0x0c(SB)/1, $0x00
|
||||
DATA ·shft_lut+0x0d(SB)/1, $0x00
|
||||
DATA ·shft_lut+0x0e(SB)/1, $0x00
|
||||
DATA ·shft_lut+0x0f(SB)/1, $0x00
|
||||
GLOBL ·shft_lut(SB), NOPTR|RODATA, $16
|
||||
Reference in New Issue
Block a user