github.com/segmentio/parquet-go@v0.0.0-20230712180008-5d42db8f0d47/value_amd64.s (about) 1 //go:build !purego 2 3 #include "textflag.h" 4 5 #define sizeOfValue 24 6 7 // This function is an optimized implementation of the memsetValues function 8 // which assigns the parquet.Value passed as second argument to all elements of 9 // the first slice argument. 10 // 11 // The optimizations relies on the fact that we can pack 4 parquet.Value values 12 // into 3 YMM registers (24 x 4 = 32 x 3 = 96). 13 // 14 // func memsetValuesAVX2(values []Value, model Value, _ uint64) 15 TEXT ·memsetValuesAVX2(SB), NOSPLIT, $0-56 // 48 + padding to load model in YMM 16 MOVQ values_base+0(FP), AX 17 MOVQ values_len+8(FP), BX 18 19 MOVQ model_ptr+24(FP), R10 20 MOVQ model_u64+32(FP), R11 21 MOVQ model+40(FP), R12 // go vet complains about this line but it's OK 22 23 XORQ SI, SI // byte index 24 MOVQ BX, DI // byte count 25 IMULQ $sizeOfValue, DI 26 27 CMPQ BX, $4 28 JB test 29 30 MOVQ BX, R8 31 SHRQ $2, R8 32 SHLQ $2, R8 33 IMULQ $sizeOfValue, R8 34 35 VMOVDQU model+24(FP), Y0 36 VMOVDQU Y0, Y1 37 VMOVDQU Y0, Y2 38 39 VPERMQ $0b00100100, Y0, Y0 40 VPERMQ $0b01001001, Y1, Y1 41 VPERMQ $0b10010010, Y2, Y2 42 loop4: 43 VMOVDQU Y0, 0(AX)(SI*1) 44 VMOVDQU Y1, 32(AX)(SI*1) 45 VMOVDQU Y2, 64(AX)(SI*1) 46 ADDQ $4*sizeOfValue, SI 47 CMPQ SI, R8 48 JNE loop4 49 VZEROUPPER 50 JMP test 51 loop: 52 MOVQ R10, 0(AX)(SI*1) 53 MOVQ R11, 8(AX)(SI*1) 54 MOVQ R12, 16(AX)(SI*1) 55 ADDQ $sizeOfValue, SI 56 test: 57 CMPQ SI, DI 58 JNE loop 59 RET