github.com/minio/simdjson-go@v0.4.6-0.20231116094823-04d21cddf993/flatten_bits_amd64.s (about) 1 //+build !noasm !appengine gc 2 3 #define MASK AX 4 #define INDEX BX 5 #define ZEROS CX 6 #define CARRIED DX 7 #define SHIFTS R8 8 #define POSITION R10 9 10 TEXT ·_flatten_bits_incremental(SB), $0-40 11 12 MOVQ base_ptr+0(FP), DI 13 MOVQ pbase+8(FP), SI 14 MOVQ mask+16(FP), MASK 15 MOVQ carried+24(FP), R11 16 MOVQ position+32(FP), R12 17 MOVQ (SI), INDEX 18 MOVQ (R11), CARRIED 19 MOVQ (R12), POSITION 20 CALL ·__flatten_bits_incremental(SB) 21 MOVQ POSITION, (R12) 22 MOVQ CARRIED, (R11) 23 MOVQ INDEX, (SI) 24 RET 25 26 TEXT ·__flatten_bits_incremental(SB), $0 27 XORQ SHIFTS, SHIFTS 28 29 // First iteration takes CARRIED into account 30 TZCNTQ MASK, ZEROS 31 JCS done // carry is set if ZEROS == 64 32 33 // Two shifts required because maximum combined shift (63+1) exceeds 6-bits 34 SHRQ $1, MASK 35 SHRQ ZEROS, MASK 36 INCQ ZEROS 37 ADDQ ZEROS, SHIFTS 38 ADDQ CARRIED, ZEROS 39 MOVL ZEROS, (DI)(INDEX*4) 40 ADDQ $1, INDEX 41 ADDQ ZEROS, POSITION 42 XORQ CARRIED, CARRIED // Reset CARRIED to 0 (since it has been used) 43 44 loop: 45 TZCNTQ MASK, ZEROS 46 JCS done // carry is set if ZEROS == 64 47 48 INCQ ZEROS 49 SHRQ ZEROS, MASK 50 ADDQ ZEROS, SHIFTS 51 MOVL ZEROS, (DI)(INDEX*4) 52 ADDQ $1, INDEX 53 ADDQ ZEROS, POSITION 54 JMP loop 55 56 done: 57 MOVQ $64, R9 58 SUBQ SHIFTS, R9 59 ADDQ R9, CARRIED // CARRIED += 64 - shifts (remaining empty bits to carry over to next call) 60 RET