// Code generated by command: go run gen.go -out ../seqdec.s -arch amd64,arm64 -pkg=zstd. DO NOT EDIT. //go:build !appengine && !noasm && gc && !noasm // func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // Requires: CMOV TEXT ·sequenceDecs_decode_amd64(SB), $40-32 MOVQ br+8(FP), CX MOVQ 24(CX), DX MOVBQZX 40(CX), BX MOVQ (CX), AX MOVQ 32(CX), SI ADDQ SI, AX MOVQ AX, (SP) MOVQ ctx+16(FP), AX MOVQ 72(AX), DI MOVQ 80(AX), R8 MOVQ 88(AX), R9 MOVQ (AX), CX MOVQ CX, 8(SP) MOVQ 24(AX), CX MOVQ CX, 16(SP) MOVQ 48(AX), CX MOVQ CX, 24(SP) MOVQ 96(AX), CX MOVQ CX, 32(SP) MOVQ 104(AX), R10 MOVQ s+0(FP), AX MOVQ 144(AX), R11 MOVQ 152(AX), R12 MOVQ 160(AX), R13 sequenceDecs_decode_amd64_main_loop: MOVQ (SP), R14 // Fill bitreader to have enough for the offset and match length. CMPQ SI, $0x08 JL sequenceDecs_decode_amd64_fill_byte_by_byte MOVQ BX, AX SHRQ $0x03, AX SUBQ AX, R14 MOVQ (R14), DX SUBQ AX, SI ANDQ $0x07, BX JMP sequenceDecs_decode_amd64_fill_end sequenceDecs_decode_amd64_fill_byte_by_byte: CMPQ SI, $0x00 JLE sequenceDecs_decode_amd64_fill_check_overread CMPQ BX, $0x07 JLE sequenceDecs_decode_amd64_fill_end SHLQ $0x08, DX SUBQ $0x01, R14 SUBQ $0x01, SI SUBQ $0x08, BX MOVBQZX (R14), AX ORQ AX, DX JMP sequenceDecs_decode_amd64_fill_byte_by_byte sequenceDecs_decode_amd64_fill_check_overread: CMPQ BX, $0x40 JA error_overread sequenceDecs_decode_amd64_fill_end: // Update offset MOVQ R9, AX MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R15 ADDQ R15, AX MOVQ AX, 16(R10) // Update match length MOVQ R8, AX MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R15 ADDQ R15, AX MOVQ AX, 8(R10) // Fill bitreader to have enough for the remaining CMPQ SI, $0x08 JL sequenceDecs_decode_amd64_fill_2_byte_by_byte MOVQ BX, AX SHRQ $0x03, AX SUBQ AX, R14 MOVQ (R14), DX SUBQ AX, SI ANDQ $0x07, BX JMP sequenceDecs_decode_amd64_fill_2_end sequenceDecs_decode_amd64_fill_2_byte_by_byte: CMPQ SI, $0x00 JLE sequenceDecs_decode_amd64_fill_2_check_overread CMPQ BX, $0x07 JLE sequenceDecs_decode_amd64_fill_2_end SHLQ $0x08, DX SUBQ $0x01, R14 SUBQ $0x01, SI SUBQ $0x08, BX MOVBQZX (R14), AX ORQ AX, DX JMP sequenceDecs_decode_amd64_fill_2_byte_by_byte sequenceDecs_decode_amd64_fill_2_check_overread: CMPQ BX, $0x40 JA error_overread sequenceDecs_decode_amd64_fill_2_end: // Update literal length MOVQ DI, AX MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R15 ADDQ R15, AX MOVQ AX, (R10) // Fill bitreader for state updates MOVQ R14, (SP) MOVQ R9, AX SHRQ $0x08, AX MOVBQZX AL, AX CMPQ 32(SP), $0x00 JZ sequenceDecs_decode_amd64_skip_update // Update Literal Length State MOVBQZX DI, R14 SHRL $0x10, DI MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 ADDQ R14, BX XORQ $0x3f, R14 MOVQ R14, CX SHRQ CL, R15 ADDQ R15, DI // Load ctx.llTable MOVQ 8(SP), CX MOVQ (CX)(DI*8), DI // Update Match Length State MOVBQZX R8, R14 SHRL $0x10, R8 MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 ADDQ R14, BX XORQ $0x3f, R14 MOVQ R14, CX SHRQ CL, R15 ADDQ R15, R8 // Load ctx.mlTable MOVQ 16(SP), CX MOVQ (CX)(R8*8), R8 // Update Offset State MOVBQZX R9, R14 SHRL $0x10, R9 MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 ADDQ R14, BX XORQ $0x3f, R14 MOVQ R14, CX SHRQ CL, R15 ADDQ R15, R9 // Load ctx.ofTable MOVQ 24(SP), CX MOVQ (CX)(R9*8), R9 sequenceDecs_decode_amd64_skip_update: // Adjust offset MOVQ 16(R10), CX CMPQ AX, $0x01 JBE sequenceDecs_decode_amd64_adjust_offsetB_1_or_0 MOVQ R12, R13 MOVQ R11, R12 MOVQ CX, R11 JMP sequenceDecs_decode_amd64_after_adjust sequenceDecs_decode_amd64_adjust_offsetB_1_or_0: CMPQ (R10), $0x00000000 JNE sequenceDecs_decode_amd64_adjust_offset_maybezero INCQ CX JMP sequenceDecs_decode_amd64_adjust_offset_nonzero sequenceDecs_decode_amd64_adjust_offset_maybezero: TESTQ CX, CX JNZ sequenceDecs_decode_amd64_adjust_offset_nonzero MOVQ R11, CX JMP sequenceDecs_decode_amd64_after_adjust sequenceDecs_decode_amd64_adjust_offset_nonzero: CMPQ CX, $0x01 JB sequenceDecs_decode_amd64_adjust_zero JEQ sequenceDecs_decode_amd64_adjust_one CMPQ CX, $0x02 JA sequenceDecs_decode_amd64_adjust_three JMP sequenceDecs_decode_amd64_adjust_two sequenceDecs_decode_amd64_adjust_zero: MOVQ R11, AX JMP sequenceDecs_decode_amd64_adjust_test_temp_valid sequenceDecs_decode_amd64_adjust_one: MOVQ R12, AX JMP sequenceDecs_decode_amd64_adjust_test_temp_valid sequenceDecs_decode_amd64_adjust_two: MOVQ R13, AX JMP sequenceDecs_decode_amd64_adjust_test_temp_valid sequenceDecs_decode_amd64_adjust_three: LEAQ -1(R11), AX sequenceDecs_decode_amd64_adjust_test_temp_valid: TESTQ AX, AX JNZ sequenceDecs_decode_amd64_adjust_temp_valid MOVQ $0x00000001, AX sequenceDecs_decode_amd64_adjust_temp_valid: CMPQ CX, $0x01 CMOVQNE R12, R13 MOVQ R11, R12 MOVQ AX, R11 MOVQ AX, CX sequenceDecs_decode_amd64_after_adjust: MOVQ CX, 16(R10) // Check values MOVQ 8(R10), AX MOVQ (R10), R14 LEAQ (AX)(R14*1), R15 MOVQ s+0(FP), BP ADDQ R15, 256(BP) MOVQ ctx+16(FP), R15 SUBQ R14, 128(R15) JS error_not_enough_literals CMPQ AX, $0x00020002 JA sequenceDecs_decode_amd64_error_match_len_too_big TESTQ CX, CX JNZ sequenceDecs_decode_amd64_match_len_ofs_ok TESTQ AX, AX JNZ sequenceDecs_decode_amd64_error_match_len_ofs_mismatch sequenceDecs_decode_amd64_match_len_ofs_ok: ADDQ $0x18, R10 DECQ 32(SP) JNS sequenceDecs_decode_amd64_main_loop MOVQ s+0(FP), AX MOVQ R11, 144(AX) MOVQ R12, 152(AX) MOVQ R13, 160(AX) MOVQ br+8(FP), AX MOVQ DX, 24(AX) MOVB BL, 40(AX) MOVQ SI, 32(AX) // Return success MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000000, ret+24(FP) RET // Return with match length error sequenceDecs_decode_amd64_error_match_len_ofs_mismatch: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000001, ret+24(FP) RET // Return with match too long error sequenceDecs_decode_amd64_error_match_len_too_big: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000002, ret+24(FP) RET // Return with match offset too long error MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000003, ret+24(FP) RET // Return with not enough literals error error_not_enough_literals: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000004, ret+24(FP) RET // Return with overread error error_overread: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000006, ret+24(FP) RET // func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // Requires: CMOV TEXT ·sequenceDecs_decode_56_amd64(SB), $40-32 MOVQ br+8(FP), CX MOVQ 24(CX), DX MOVBQZX 40(CX), BX MOVQ (CX), AX MOVQ 32(CX), SI ADDQ SI, AX MOVQ AX, (SP) MOVQ ctx+16(FP), AX MOVQ 72(AX), DI MOVQ 80(AX), R8 MOVQ 88(AX), R9 MOVQ (AX), CX MOVQ CX, 8(SP) MOVQ 24(AX), CX MOVQ CX, 16(SP) MOVQ 48(AX), CX MOVQ CX, 24(SP) MOVQ 96(AX), CX MOVQ CX, 32(SP) MOVQ 104(AX), R10 MOVQ s+0(FP), AX MOVQ 144(AX), R11 MOVQ 152(AX), R12 MOVQ 160(AX), R13 sequenceDecs_decode_56_amd64_main_loop: MOVQ (SP), R14 // Fill bitreader to have enough for the offset and match length. CMPQ SI, $0x08 JL sequenceDecs_decode_56_amd64_fill_byte_by_byte MOVQ BX, AX SHRQ $0x03, AX SUBQ AX, R14 MOVQ (R14), DX SUBQ AX, SI ANDQ $0x07, BX JMP sequenceDecs_decode_56_amd64_fill_end sequenceDecs_decode_56_amd64_fill_byte_by_byte: CMPQ SI, $0x00 JLE sequenceDecs_decode_56_amd64_fill_check_overread CMPQ BX, $0x07 JLE sequenceDecs_decode_56_amd64_fill_end SHLQ $0x08, DX SUBQ $0x01, R14 SUBQ $0x01, SI SUBQ $0x08, BX MOVBQZX (R14), AX ORQ AX, DX JMP sequenceDecs_decode_56_amd64_fill_byte_by_byte sequenceDecs_decode_56_amd64_fill_check_overread: CMPQ BX, $0x40 JA error_overread sequenceDecs_decode_56_amd64_fill_end: // Update offset MOVQ R9, AX MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R15 ADDQ R15, AX MOVQ AX, 16(R10) // Update match length MOVQ R8, AX MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R15 ADDQ R15, AX MOVQ AX, 8(R10) // Update literal length MOVQ DI, AX MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R15 ADDQ R15, AX MOVQ AX, (R10) // Fill bitreader for state updates MOVQ R14, (SP) MOVQ R9, AX SHRQ $0x08, AX MOVBQZX AL, AX CMPQ 32(SP), $0x00 JZ sequenceDecs_decode_56_amd64_skip_update // Update Literal Length State MOVBQZX DI, R14 SHRL $0x10, DI MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 ADDQ R14, BX XORQ $0x3f, R14 MOVQ R14, CX SHRQ CL, R15 ADDQ R15, DI // Load ctx.llTable MOVQ 8(SP), CX MOVQ (CX)(DI*8), DI // Update Match Length State MOVBQZX R8, R14 SHRL $0x10, R8 MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 ADDQ R14, BX XORQ $0x3f, R14 MOVQ R14, CX SHRQ CL, R15 ADDQ R15, R8 // Load ctx.mlTable MOVQ 16(SP), CX MOVQ (CX)(R8*8), R8 // Update Offset State MOVBQZX R9, R14 SHRL $0x10, R9 MOVQ BX, CX MOVQ DX, R15 SHLQ CL, R15 SHRQ $0x01, R15 ADDQ R14, BX XORQ $0x3f, R14 MOVQ R14, CX SHRQ CL, R15 ADDQ R15, R9 // Load ctx.ofTable MOVQ 24(SP), CX MOVQ (CX)(R9*8), R9 sequenceDecs_decode_56_amd64_skip_update: // Adjust offset MOVQ 16(R10), CX CMPQ AX, $0x01 JBE sequenceDecs_decode_56_amd64_adjust_offsetB_1_or_0 MOVQ R12, R13 MOVQ R11, R12 MOVQ CX, R11 JMP sequenceDecs_decode_56_amd64_after_adjust sequenceDecs_decode_56_amd64_adjust_offsetB_1_or_0: CMPQ (R10), $0x00000000 JNE sequenceDecs_decode_56_amd64_adjust_offset_maybezero INCQ CX JMP sequenceDecs_decode_56_amd64_adjust_offset_nonzero sequenceDecs_decode_56_amd64_adjust_offset_maybezero: TESTQ CX, CX JNZ sequenceDecs_decode_56_amd64_adjust_offset_nonzero MOVQ R11, CX JMP sequenceDecs_decode_56_amd64_after_adjust sequenceDecs_decode_56_amd64_adjust_offset_nonzero: CMPQ CX, $0x01 JB sequenceDecs_decode_56_amd64_adjust_zero JEQ sequenceDecs_decode_56_amd64_adjust_one CMPQ CX, $0x02 JA sequenceDecs_decode_56_amd64_adjust_three JMP sequenceDecs_decode_56_amd64_adjust_two sequenceDecs_decode_56_amd64_adjust_zero: MOVQ R11, AX JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid sequenceDecs_decode_56_amd64_adjust_one: MOVQ R12, AX JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid sequenceDecs_decode_56_amd64_adjust_two: MOVQ R13, AX JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid sequenceDecs_decode_56_amd64_adjust_three: LEAQ -1(R11), AX sequenceDecs_decode_56_amd64_adjust_test_temp_valid: TESTQ AX, AX JNZ sequenceDecs_decode_56_amd64_adjust_temp_valid MOVQ $0x00000001, AX sequenceDecs_decode_56_amd64_adjust_temp_valid: CMPQ CX, $0x01 CMOVQNE R12, R13 MOVQ R11, R12 MOVQ AX, R11 MOVQ AX, CX sequenceDecs_decode_56_amd64_after_adjust: MOVQ CX, 16(R10) // Check values MOVQ 8(R10), AX MOVQ (R10), R14 LEAQ (AX)(R14*1), R15 MOVQ s+0(FP), BP ADDQ R15, 256(BP) MOVQ ctx+16(FP), R15 SUBQ R14, 128(R15) JS error_not_enough_literals CMPQ AX, $0x00020002 JA sequenceDecs_decode_56_amd64_error_match_len_too_big TESTQ CX, CX JNZ sequenceDecs_decode_56_amd64_match_len_ofs_ok TESTQ AX, AX JNZ sequenceDecs_decode_56_amd64_error_match_len_ofs_mismatch sequenceDecs_decode_56_amd64_match_len_ofs_ok: ADDQ $0x18, R10 DECQ 32(SP) JNS sequenceDecs_decode_56_amd64_main_loop MOVQ s+0(FP), AX MOVQ R11, 144(AX) MOVQ R12, 152(AX) MOVQ R13, 160(AX) MOVQ br+8(FP), AX MOVQ DX, 24(AX) MOVB BL, 40(AX) MOVQ SI, 32(AX) // Return success MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000000, ret+24(FP) RET // Return with match length error sequenceDecs_decode_56_amd64_error_match_len_ofs_mismatch: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000001, ret+24(FP) RET // Return with match too long error sequenceDecs_decode_56_amd64_error_match_len_too_big: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000002, ret+24(FP) RET // Return with match offset too long error MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000003, ret+24(FP) RET // Return with not enough literals error error_not_enough_literals: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000004, ret+24(FP) RET // Return with overread error error_overread: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000006, ret+24(FP) RET // func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // Requires: BMI, BMI2, CMOV TEXT ·sequenceDecs_decode_bmi2(SB), $40-32 MOVQ br+8(FP), BX MOVQ 24(BX), AX MOVBQZX 40(BX), DX MOVQ (BX), CX MOVQ 32(BX), BX ADDQ BX, CX MOVQ CX, (SP) MOVQ ctx+16(FP), CX MOVQ 72(CX), SI MOVQ 80(CX), DI MOVQ 88(CX), R8 MOVQ (CX), R9 MOVQ R9, 8(SP) MOVQ 24(CX), R9 MOVQ R9, 16(SP) MOVQ 48(CX), R9 MOVQ R9, 24(SP) MOVQ 96(CX), R9 MOVQ R9, 32(SP) MOVQ 104(CX), R9 MOVQ s+0(FP), CX MOVQ 144(CX), R10 MOVQ 152(CX), R11 MOVQ 160(CX), R12 sequenceDecs_decode_bmi2_main_loop: MOVQ (SP), R13 // Fill bitreader to have enough for the offset and match length. CMPQ BX, $0x08 JL sequenceDecs_decode_bmi2_fill_byte_by_byte MOVQ DX, CX SHRQ $0x03, CX SUBQ CX, R13 MOVQ (R13), AX SUBQ CX, BX ANDQ $0x07, DX JMP sequenceDecs_decode_bmi2_fill_end sequenceDecs_decode_bmi2_fill_byte_by_byte: CMPQ BX, $0x00 JLE sequenceDecs_decode_bmi2_fill_check_overread CMPQ DX, $0x07 JLE sequenceDecs_decode_bmi2_fill_end SHLQ $0x08, AX SUBQ $0x01, R13 SUBQ $0x01, BX SUBQ $0x08, DX MOVBQZX (R13), CX ORQ CX, AX JMP sequenceDecs_decode_bmi2_fill_byte_by_byte sequenceDecs_decode_bmi2_fill_check_overread: CMPQ DX, $0x40 JA error_overread sequenceDecs_decode_bmi2_fill_end: // Update offset MOVQ $0x00000808, CX BEXTRQ CX, R8, R14 MOVQ AX, R15 LEAQ (DX)(R14*1), CX ROLQ CL, R15 BZHIQ R14, R15, R15 MOVQ CX, DX MOVQ R8, CX SHRQ $0x20, CX ADDQ R15, CX MOVQ CX, 16(R9) // Update match length MOVQ $0x00000808, CX BEXTRQ CX, DI, R14 MOVQ AX, R15 LEAQ (DX)(R14*1), CX ROLQ CL, R15 BZHIQ R14, R15, R15 MOVQ CX, DX MOVQ DI, CX SHRQ $0x20, CX ADDQ R15, CX MOVQ CX, 8(R9) // Fill bitreader to have enough for the remaining CMPQ BX, $0x08 JL sequenceDecs_decode_bmi2_fill_2_byte_by_byte MOVQ DX, CX SHRQ $0x03, CX SUBQ CX, R13 MOVQ (R13), AX SUBQ CX, BX ANDQ $0x07, DX JMP sequenceDecs_decode_bmi2_fill_2_end sequenceDecs_decode_bmi2_fill_2_byte_by_byte: CMPQ BX, $0x00 JLE sequenceDecs_decode_bmi2_fill_2_check_overread CMPQ DX, $0x07 JLE sequenceDecs_decode_bmi2_fill_2_end SHLQ $0x08, AX SUBQ $0x01, R13 SUBQ $0x01, BX SUBQ $0x08, DX MOVBQZX (R13), CX ORQ CX, AX JMP sequenceDecs_decode_bmi2_fill_2_byte_by_byte sequenceDecs_decode_bmi2_fill_2_check_overread: CMPQ DX, $0x40 JA error_overread sequenceDecs_decode_bmi2_fill_2_end: // Update literal length MOVQ $0x00000808, CX BEXTRQ CX, SI, R14 MOVQ AX, R15 LEAQ (DX)(R14*1), CX ROLQ CL, R15 BZHIQ R14, R15, R15 MOVQ CX, DX MOVQ SI, CX SHRQ $0x20, CX ADDQ R15, CX MOVQ CX, (R9) // Fill bitreader for state updates MOVQ R13, (SP) MOVQ $0x00000808, CX BEXTRQ CX, R8, R13 CMPQ 32(SP), $0x00 JZ sequenceDecs_decode_bmi2_skip_update LEAQ (SI)(DI*1), R14 ADDQ R8, R14 MOVBQZX R14, R14 LEAQ (DX)(R14*1), CX MOVQ AX, R15 MOVQ CX, DX ROLQ CL, R15 BZHIQ R14, R15, R15 // Update Offset State BZHIQ R8, R15, CX SHRXQ R8, R15, R15 SHRL $0x10, R8 ADDQ CX, R8 // Load ctx.ofTable MOVQ 24(SP), CX MOVQ (CX)(R8*8), R8 // Update Match Length State BZHIQ DI, R15, CX SHRXQ DI, R15, R15 SHRL $0x10, DI ADDQ CX, DI // Load ctx.mlTable MOVQ 16(SP), CX MOVQ (CX)(DI*8), DI // Update Literal Length State BZHIQ SI, R15, CX SHRL $0x10, SI ADDQ CX, SI // Load ctx.llTable MOVQ 8(SP), CX MOVQ (CX)(SI*8), SI sequenceDecs_decode_bmi2_skip_update: // Adjust offset MOVQ 16(R9), CX CMPQ R13, $0x01 JBE sequenceDecs_decode_bmi2_adjust_offsetB_1_or_0 MOVQ R11, R12 MOVQ R10, R11 MOVQ CX, R10 JMP sequenceDecs_decode_bmi2_after_adjust sequenceDecs_decode_bmi2_adjust_offsetB_1_or_0: CMPQ (R9), $0x00000000 JNE sequenceDecs_decode_bmi2_adjust_offset_maybezero INCQ CX JMP sequenceDecs_decode_bmi2_adjust_offset_nonzero sequenceDecs_decode_bmi2_adjust_offset_maybezero: TESTQ CX, CX JNZ sequenceDecs_decode_bmi2_adjust_offset_nonzero MOVQ R10, CX JMP sequenceDecs_decode_bmi2_after_adjust sequenceDecs_decode_bmi2_adjust_offset_nonzero: CMPQ CX, $0x01 JB sequenceDecs_decode_bmi2_adjust_zero JEQ sequenceDecs_decode_bmi2_adjust_one CMPQ CX, $0x02 JA sequenceDecs_decode_bmi2_adjust_three JMP sequenceDecs_decode_bmi2_adjust_two sequenceDecs_decode_bmi2_adjust_zero: MOVQ R10, R13 JMP sequenceDecs_decode_bmi2_adjust_test_temp_valid sequenceDecs_decode_bmi2_adjust_one: MOVQ R11, R13 JMP sequenceDecs_decode_bmi2_adjust_test_temp_valid sequenceDecs_decode_bmi2_adjust_two: MOVQ R12, R13 JMP sequenceDecs_decode_bmi2_adjust_test_temp_valid sequenceDecs_decode_bmi2_adjust_three: LEAQ -1(R10), R13 sequenceDecs_decode_bmi2_adjust_test_temp_valid: TESTQ R13, R13 JNZ sequenceDecs_decode_bmi2_adjust_temp_valid MOVQ $0x00000001, R13 sequenceDecs_decode_bmi2_adjust_temp_valid: CMPQ CX, $0x01 CMOVQNE R11, R12 MOVQ R10, R11 MOVQ R13, R10 MOVQ R13, CX sequenceDecs_decode_bmi2_after_adjust: MOVQ CX, 16(R9) // Check values MOVQ 8(R9), R13 MOVQ (R9), R14 LEAQ (R13)(R14*1), R15 MOVQ s+0(FP), BP ADDQ R15, 256(BP) MOVQ ctx+16(FP), R15 SUBQ R14, 128(R15) JS error_not_enough_literals CMPQ R13, $0x00020002 JA sequenceDecs_decode_bmi2_error_match_len_too_big TESTQ CX, CX JNZ sequenceDecs_decode_bmi2_match_len_ofs_ok TESTQ R13, R13 JNZ sequenceDecs_decode_bmi2_error_match_len_ofs_mismatch sequenceDecs_decode_bmi2_match_len_ofs_ok: ADDQ $0x18, R9 DECQ 32(SP) JNS sequenceDecs_decode_bmi2_main_loop MOVQ s+0(FP), CX MOVQ R10, 144(CX) MOVQ R11, 152(CX) MOVQ R12, 160(CX) MOVQ br+8(FP), CX MOVQ AX, 24(CX) MOVB DL, 40(CX) MOVQ BX, 32(CX) // Return success MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000000, ret+24(FP) RET // Return with match length error sequenceDecs_decode_bmi2_error_match_len_ofs_mismatch: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000001, ret+24(FP) RET // Return with match too long error sequenceDecs_decode_bmi2_error_match_len_too_big: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000002, ret+24(FP) RET // Return with match offset too long error MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000003, ret+24(FP) RET // Return with not enough literals error error_not_enough_literals: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000004, ret+24(FP) RET // Return with overread error error_overread: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000006, ret+24(FP) RET // func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // Requires: BMI, BMI2, CMOV TEXT ·sequenceDecs_decode_56_bmi2(SB), $40-32 MOVQ br+8(FP), BX MOVQ 24(BX), AX MOVBQZX 40(BX), DX MOVQ (BX), CX MOVQ 32(BX), BX ADDQ BX, CX MOVQ CX, (SP) MOVQ ctx+16(FP), CX MOVQ 72(CX), SI MOVQ 80(CX), DI MOVQ 88(CX), R8 MOVQ (CX), R9 MOVQ R9, 8(SP) MOVQ 24(CX), R9 MOVQ R9, 16(SP) MOVQ 48(CX), R9 MOVQ R9, 24(SP) MOVQ 96(CX), R9 MOVQ R9, 32(SP) MOVQ 104(CX), R9 MOVQ s+0(FP), CX MOVQ 144(CX), R10 MOVQ 152(CX), R11 MOVQ 160(CX), R12 sequenceDecs_decode_56_bmi2_main_loop: MOVQ (SP), R13 // Fill bitreader to have enough for the offset and match length. CMPQ BX, $0x08 JL sequenceDecs_decode_56_bmi2_fill_byte_by_byte MOVQ DX, CX SHRQ $0x03, CX SUBQ CX, R13 MOVQ (R13), AX SUBQ CX, BX ANDQ $0x07, DX JMP sequenceDecs_decode_56_bmi2_fill_end sequenceDecs_decode_56_bmi2_fill_byte_by_byte: CMPQ BX, $0x00 JLE sequenceDecs_decode_56_bmi2_fill_check_overread CMPQ DX, $0x07 JLE sequenceDecs_decode_56_bmi2_fill_end SHLQ $0x08, AX SUBQ $0x01, R13 SUBQ $0x01, BX SUBQ $0x08, DX MOVBQZX (R13), CX ORQ CX, AX JMP sequenceDecs_decode_56_bmi2_fill_byte_by_byte sequenceDecs_decode_56_bmi2_fill_check_overread: CMPQ DX, $0x40 JA error_overread sequenceDecs_decode_56_bmi2_fill_end: // Update offset MOVQ $0x00000808, CX BEXTRQ CX, R8, R14 MOVQ AX, R15 LEAQ (DX)(R14*1), CX ROLQ CL, R15 BZHIQ R14, R15, R15 MOVQ CX, DX MOVQ R8, CX SHRQ $0x20, CX ADDQ R15, CX MOVQ CX, 16(R9) // Update match length MOVQ $0x00000808, CX BEXTRQ CX, DI, R14 MOVQ AX, R15 LEAQ (DX)(R14*1), CX ROLQ CL, R15 BZHIQ R14, R15, R15 MOVQ CX, DX MOVQ DI, CX SHRQ $0x20, CX ADDQ R15, CX MOVQ CX, 8(R9) // Update literal length MOVQ $0x00000808, CX BEXTRQ CX, SI, R14 MOVQ AX, R15 LEAQ (DX)(R14*1), CX ROLQ CL, R15 BZHIQ R14, R15, R15 MOVQ CX, DX MOVQ SI, CX SHRQ $0x20, CX ADDQ R15, CX MOVQ CX, (R9) // Fill bitreader for state updates MOVQ R13, (SP) MOVQ $0x00000808, CX BEXTRQ CX, R8, R13 CMPQ 32(SP), $0x00 JZ sequenceDecs_decode_56_bmi2_skip_update LEAQ (SI)(DI*1), R14 ADDQ R8, R14 MOVBQZX R14, R14 LEAQ (DX)(R14*1), CX MOVQ AX, R15 MOVQ CX, DX ROLQ CL, R15 BZHIQ R14, R15, R15 // Update Offset State BZHIQ R8, R15, CX SHRXQ R8, R15, R15 SHRL $0x10, R8 ADDQ CX, R8 // Load ctx.ofTable MOVQ 24(SP), CX MOVQ (CX)(R8*8), R8 // Update Match Length State BZHIQ DI, R15, CX SHRXQ DI, R15, R15 SHRL $0x10, DI ADDQ CX, DI // Load ctx.mlTable MOVQ 16(SP), CX MOVQ (CX)(DI*8), DI // Update Literal Length State BZHIQ SI, R15, CX SHRL $0x10, SI ADDQ CX, SI // Load ctx.llTable MOVQ 8(SP), CX MOVQ (CX)(SI*8), SI sequenceDecs_decode_56_bmi2_skip_update: // Adjust offset MOVQ 16(R9), CX CMPQ R13, $0x01 JBE sequenceDecs_decode_56_bmi2_adjust_offsetB_1_or_0 MOVQ R11, R12 MOVQ R10, R11 MOVQ CX, R10 JMP sequenceDecs_decode_56_bmi2_after_adjust sequenceDecs_decode_56_bmi2_adjust_offsetB_1_or_0: CMPQ (R9), $0x00000000 JNE sequenceDecs_decode_56_bmi2_adjust_offset_maybezero INCQ CX JMP sequenceDecs_decode_56_bmi2_adjust_offset_nonzero sequenceDecs_decode_56_bmi2_adjust_offset_maybezero: TESTQ CX, CX JNZ sequenceDecs_decode_56_bmi2_adjust_offset_nonzero MOVQ R10, CX JMP sequenceDecs_decode_56_bmi2_after_adjust sequenceDecs_decode_56_bmi2_adjust_offset_nonzero: CMPQ CX, $0x01 JB sequenceDecs_decode_56_bmi2_adjust_zero JEQ sequenceDecs_decode_56_bmi2_adjust_one CMPQ CX, $0x02 JA sequenceDecs_decode_56_bmi2_adjust_three JMP sequenceDecs_decode_56_bmi2_adjust_two sequenceDecs_decode_56_bmi2_adjust_zero: MOVQ R10, R13 JMP sequenceDecs_decode_56_bmi2_adjust_test_temp_valid sequenceDecs_decode_56_bmi2_adjust_one: MOVQ R11, R13 JMP sequenceDecs_decode_56_bmi2_adjust_test_temp_valid sequenceDecs_decode_56_bmi2_adjust_two: MOVQ R12, R13 JMP sequenceDecs_decode_56_bmi2_adjust_test_temp_valid sequenceDecs_decode_56_bmi2_adjust_three: LEAQ -1(R10), R13 sequenceDecs_decode_56_bmi2_adjust_test_temp_valid: TESTQ R13, R13 JNZ sequenceDecs_decode_56_bmi2_adjust_temp_valid MOVQ $0x00000001, R13 sequenceDecs_decode_56_bmi2_adjust_temp_valid: CMPQ CX, $0x01 CMOVQNE R11, R12 MOVQ R10, R11 MOVQ R13, R10 MOVQ R13, CX sequenceDecs_decode_56_bmi2_after_adjust: MOVQ CX, 16(R9) // Check values MOVQ 8(R9), R13 MOVQ (R9), R14 LEAQ (R13)(R14*1), R15 MOVQ s+0(FP), BP ADDQ R15, 256(BP) MOVQ ctx+16(FP), R15 SUBQ R14, 128(R15) JS error_not_enough_literals CMPQ R13, $0x00020002 JA sequenceDecs_decode_56_bmi2_error_match_len_too_big TESTQ CX, CX JNZ sequenceDecs_decode_56_bmi2_match_len_ofs_ok TESTQ R13, R13 JNZ sequenceDecs_decode_56_bmi2_error_match_len_ofs_mismatch sequenceDecs_decode_56_bmi2_match_len_ofs_ok: ADDQ $0x18, R9 DECQ 32(SP) JNS sequenceDecs_decode_56_bmi2_main_loop MOVQ s+0(FP), CX MOVQ R10, 144(CX) MOVQ R11, 152(CX) MOVQ R12, 160(CX) MOVQ br+8(FP), CX MOVQ AX, 24(CX) MOVB DL, 40(CX) MOVQ BX, 32(CX) // Return success MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000000, ret+24(FP) RET // Return with match length error sequenceDecs_decode_56_bmi2_error_match_len_ofs_mismatch: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000001, ret+24(FP) RET // Return with match too long error sequenceDecs_decode_56_bmi2_error_match_len_too_big: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000002, ret+24(FP) RET // Return with match offset too long error MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000003, ret+24(FP) RET // Return with not enough literals error error_not_enough_literals: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000004, ret+24(FP) RET // Return with overread error error_overread: MOVQ 32(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 96(CX) MOVQ $0x00000006, ret+24(FP) RET // func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool // Requires: SSE TEXT ·sequenceDecs_executeSimple_amd64(SB), $8-9 MOVQ ctx+0(FP), R10 MOVQ 8(R10), CX TESTQ CX, CX JZ empty_seqs MOVQ (R10), AX MOVQ 24(R10), DX MOVQ 32(R10), BX MOVQ 80(R10), SI MOVQ 104(R10), DI MOVQ 120(R10), R8 MOVQ 56(R10), R9 MOVQ 64(R10), R10 ADDQ R10, R9 // seqsBase += 24 * seqIndex LEAQ (DX)(DX*2), R11 SHLQ $0x03, R11 ADDQ R11, AX // outBase += outPosition ADDQ DI, BX main_loop: MOVQ (AX), R11 MOVQ 16(AX), R12 MOVQ 8(AX), R13 // Copy literals MOVUPS (SI), X0 MOVUPS X0, (BX) CMPQ R11, $0x10 JBE copy_1_end MOVQ $0x00000010, R14 copy_1: MOVUPS (SI)(R14*1), X0 MOVUPS X0, (BX)(R14*1) ADDQ $0x10, R14 CMPQ R14, R11 JB copy_1 copy_1_end: ADDQ R11, SI ADDQ R11, BX ADDQ R11, DI // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) LEAQ (DI)(R10*1), R11 CMPQ R12, R11 JG error_match_off_too_big CMPQ R12, R8 JG error_match_off_too_big // Copy match from history MOVQ R12, R11 SUBQ DI, R11 JLS copy_match MOVQ R9, R14 SUBQ R11, R14 CMPQ R13, R11 JG copy_all_from_history MOVQ R13, R11 SUBQ $0x10, R11 JB copy_4_small copy_4_loop: MOVUPS (R14), X0 MOVUPS X0, (BX) ADDQ $0x10, R14 ADDQ $0x10, BX SUBQ $0x10, R11 JAE copy_4_loop LEAQ 16(R14)(R11*1), R14 LEAQ 16(BX)(R11*1), BX MOVUPS -16(R14), X0 MOVUPS X0, -16(BX) JMP copy_4_end copy_4_small: CMPQ R13, $0x03 JE copy_4_move_3 CMPQ R13, $0x08 JB copy_4_move_4through7 JMP copy_4_move_8through16 copy_4_move_3: MOVWQZX (R14), R11 MOVB 2(R14), R12 MOVW R11, (BX) MOVB R12, 2(BX) ADDQ R13, R14 ADDQ R13, BX JMP copy_4_end copy_4_move_4through7: MOVL (R14), R11 MOVL -4(R14)(R13*1), R12 MOVL R11, (BX) MOVL R12, -4(BX)(R13*1) ADDQ R13, R14 ADDQ R13, BX JMP copy_4_end copy_4_move_8through16: MOVQ (R14), R11 MOVQ -8(R14)(R13*1), R12 MOVQ R11, (BX) MOVQ R12, -8(BX)(R13*1) ADDQ R13, R14 ADDQ R13, BX copy_4_end: ADDQ R13, DI ADDQ $0x18, AX INCQ DX CMPQ DX, CX JB main_loop JMP loop_finished copy_all_from_history: MOVQ R11, R15 SUBQ $0x10, R15 JB copy_5_small copy_5_loop: MOVUPS (R14), X0 MOVUPS X0, (BX) ADDQ $0x10, R14 ADDQ $0x10, BX SUBQ $0x10, R15 JAE copy_5_loop LEAQ 16(R14)(R15*1), R14 LEAQ 16(BX)(R15*1), BX MOVUPS -16(R14), X0 MOVUPS X0, -16(BX) JMP copy_5_end copy_5_small: CMPQ R11, $0x03 JE copy_5_move_3 JB copy_5_move_1or2 CMPQ R11, $0x08 JB copy_5_move_4through7 JMP copy_5_move_8through16 copy_5_move_1or2: MOVB (R14), R15 MOVB -1(R14)(R11*1), BP MOVB R15, (BX) MOVB BP, -1(BX)(R11*1) ADDQ R11, R14 ADDQ R11, BX JMP copy_5_end copy_5_move_3: MOVWQZX (R14), R15 MOVB 2(R14), BP MOVW R15, (BX) MOVB BP, 2(BX) ADDQ R11, R14 ADDQ R11, BX JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 MOVL -4(R14)(R11*1), BP MOVL R15, (BX) MOVL BP, -4(BX)(R11*1) ADDQ R11, R14 ADDQ R11, BX JMP copy_5_end copy_5_move_8through16: MOVQ (R14), R15 MOVQ -8(R14)(R11*1), BP MOVQ R15, (BX) MOVQ BP, -8(BX)(R11*1) ADDQ R11, R14 ADDQ R11, BX copy_5_end: ADDQ R11, DI SUBQ R11, R13 // Copy match from the current buffer copy_match: MOVQ BX, R11 SUBQ R12, R11 // ml <= mo CMPQ R13, R12 JA copy_overlapping_match // Copy non-overlapping match ADDQ R13, DI MOVUPS (R11), X0 MOVUPS X0, (BX) CMPQ R13, $0x10 JA copy_2_long ADDQ R13, BX JMP handle_loop copy_2_long: LEAQ 16(BX), R12 ADDQ R13, BX ADDQ $0x10, R11 SUBQ $0x10, R13 copy_2: MOVUPS (R11), X0 MOVUPS X0, (R12) ADDQ $0x10, R11 ADDQ $0x10, R12 SUBQ $0x10, R13 JHI copy_2 JMP handle_loop // Copy overlapping match copy_overlapping_match: ADDQ R13, DI copy_slow_3: MOVBQZX (R11), R12 MOVB R12, (BX) INCQ R11 INCQ BX DECQ R13 JNZ copy_slow_3 handle_loop: ADDQ $0x18, AX INCQ DX CMPQ DX, CX JB main_loop loop_finished: // Return value MOVB $0x01, ret+8(FP) // Update the context MOVQ ctx+0(FP), AX MOVQ DX, 24(AX) MOVQ DI, 104(AX) SUBQ 80(AX), SI MOVQ SI, 112(AX) RET error_match_off_too_big: // Return value MOVB $0x00, ret+8(FP) // Update the context MOVQ ctx+0(FP), AX MOVQ DX, 24(AX) MOVQ DI, 104(AX) SUBQ 80(AX), SI MOVQ SI, 112(AX) RET empty_seqs: // Return value MOVB $0x01, ret+8(FP) RET // func sequenceDecs_executeSimple_safe_amd64(ctx *executeAsmContext) bool // Requires: SSE TEXT ·sequenceDecs_executeSimple_safe_amd64(SB), $8-9 MOVQ ctx+0(FP), R10 MOVQ 8(R10), CX TESTQ CX, CX JZ empty_seqs MOVQ (R10), AX MOVQ 24(R10), DX MOVQ 32(R10), BX MOVQ 80(R10), SI MOVQ 104(R10), DI MOVQ 120(R10), R8 MOVQ 56(R10), R9 MOVQ 64(R10), R10 ADDQ R10, R9 // seqsBase += 24 * seqIndex LEAQ (DX)(DX*2), R11 SHLQ $0x03, R11 ADDQ R11, AX // outBase += outPosition ADDQ DI, BX main_loop: MOVQ (AX), R11 MOVQ 16(AX), R12 MOVQ 8(AX), R13 // Copy literals TESTQ R11, R11 JZ check_offset MOVQ R11, R14 SUBQ $0x10, R14 JB copy_1_small copy_1_loop: MOVUPS (SI), X0 MOVUPS X0, (BX) ADDQ $0x10, SI ADDQ $0x10, BX SUBQ $0x10, R14 JAE copy_1_loop LEAQ 16(SI)(R14*1), SI LEAQ 16(BX)(R14*1), BX MOVUPS -16(SI), X0 MOVUPS X0, -16(BX) JMP copy_1_end copy_1_small: CMPQ R11, $0x03 JE copy_1_move_3 JB copy_1_move_1or2 CMPQ R11, $0x08 JB copy_1_move_4through7 JMP copy_1_move_8through16 copy_1_move_1or2: MOVB (SI), R14 MOVB -1(SI)(R11*1), R15 MOVB R14, (BX) MOVB R15, -1(BX)(R11*1) ADDQ R11, SI ADDQ R11, BX JMP copy_1_end copy_1_move_3: MOVWQZX (SI), R14 MOVB 2(SI), R15 MOVW R14, (BX) MOVB R15, 2(BX) ADDQ R11, SI ADDQ R11, BX JMP copy_1_end copy_1_move_4through7: MOVL (SI), R14 MOVL -4(SI)(R11*1), R15 MOVL R14, (BX) MOVL R15, -4(BX)(R11*1) ADDQ R11, SI ADDQ R11, BX JMP copy_1_end copy_1_move_8through16: MOVQ (SI), R14 MOVQ -8(SI)(R11*1), R15 MOVQ R14, (BX) MOVQ R15, -8(BX)(R11*1) ADDQ R11, SI ADDQ R11, BX copy_1_end: ADDQ R11, DI // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) check_offset: LEAQ (DI)(R10*1), R11 CMPQ R12, R11 JG error_match_off_too_big CMPQ R12, R8 JG error_match_off_too_big // Copy match from history MOVQ R12, R11 SUBQ DI, R11 JLS copy_match MOVQ R9, R14 SUBQ R11, R14 CMPQ R13, R11 JG copy_all_from_history MOVQ R13, R11 SUBQ $0x10, R11 JB copy_4_small copy_4_loop: MOVUPS (R14), X0 MOVUPS X0, (BX) ADDQ $0x10, R14 ADDQ $0x10, BX SUBQ $0x10, R11 JAE copy_4_loop LEAQ 16(R14)(R11*1), R14 LEAQ 16(BX)(R11*1), BX MOVUPS -16(R14), X0 MOVUPS X0, -16(BX) JMP copy_4_end copy_4_small: CMPQ R13, $0x03 JE copy_4_move_3 CMPQ R13, $0x08 JB copy_4_move_4through7 JMP copy_4_move_8through16 copy_4_move_3: MOVWQZX (R14), R11 MOVB 2(R14), R12 MOVW R11, (BX) MOVB R12, 2(BX) ADDQ R13, R14 ADDQ R13, BX JMP copy_4_end copy_4_move_4through7: MOVL (R14), R11 MOVL -4(R14)(R13*1), R12 MOVL R11, (BX) MOVL R12, -4(BX)(R13*1) ADDQ R13, R14 ADDQ R13, BX JMP copy_4_end copy_4_move_8through16: MOVQ (R14), R11 MOVQ -8(R14)(R13*1), R12 MOVQ R11, (BX) MOVQ R12, -8(BX)(R13*1) ADDQ R13, R14 ADDQ R13, BX copy_4_end: ADDQ R13, DI ADDQ $0x18, AX INCQ DX CMPQ DX, CX JB main_loop JMP loop_finished copy_all_from_history: MOVQ R11, R15 SUBQ $0x10, R15 JB copy_5_small copy_5_loop: MOVUPS (R14), X0 MOVUPS X0, (BX) ADDQ $0x10, R14 ADDQ $0x10, BX SUBQ $0x10, R15 JAE copy_5_loop LEAQ 16(R14)(R15*1), R14 LEAQ 16(BX)(R15*1), BX MOVUPS -16(R14), X0 MOVUPS X0, -16(BX) JMP copy_5_end copy_5_small: CMPQ R11, $0x03 JE copy_5_move_3 JB copy_5_move_1or2 CMPQ R11, $0x08 JB copy_5_move_4through7 JMP copy_5_move_8through16 copy_5_move_1or2: MOVB (R14), R15 MOVB -1(R14)(R11*1), BP MOVB R15, (BX) MOVB BP, -1(BX)(R11*1) ADDQ R11, R14 ADDQ R11, BX JMP copy_5_end copy_5_move_3: MOVWQZX (R14), R15 MOVB 2(R14), BP MOVW R15, (BX) MOVB BP, 2(BX) ADDQ R11, R14 ADDQ R11, BX JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 MOVL -4(R14)(R11*1), BP MOVL R15, (BX) MOVL BP, -4(BX)(R11*1) ADDQ R11, R14 ADDQ R11, BX JMP copy_5_end copy_5_move_8through16: MOVQ (R14), R15 MOVQ -8(R14)(R11*1), BP MOVQ R15, (BX) MOVQ BP, -8(BX)(R11*1) ADDQ R11, R14 ADDQ R11, BX copy_5_end: ADDQ R11, DI SUBQ R11, R13 // Copy match from the current buffer copy_match: MOVQ BX, R11 SUBQ R12, R11 // ml <= mo CMPQ R13, R12 JA copy_overlapping_match // Copy non-overlapping match ADDQ R13, DI MOVQ R13, R12 SUBQ $0x10, R12 JB copy_2_small copy_2_loop: MOVUPS (R11), X0 MOVUPS X0, (BX) ADDQ $0x10, R11 ADDQ $0x10, BX SUBQ $0x10, R12 JAE copy_2_loop LEAQ 16(R11)(R12*1), R11 LEAQ 16(BX)(R12*1), BX MOVUPS -16(R11), X0 MOVUPS X0, -16(BX) JMP copy_2_end copy_2_small: CMPQ R13, $0x03 JE copy_2_move_3 JB copy_2_move_1or2 CMPQ R13, $0x08 JB copy_2_move_4through7 JMP copy_2_move_8through16 copy_2_move_1or2: MOVB (R11), R12 MOVB -1(R11)(R13*1), R14 MOVB R12, (BX) MOVB R14, -1(BX)(R13*1) ADDQ R13, R11 ADDQ R13, BX JMP copy_2_end copy_2_move_3: MOVWQZX (R11), R12 MOVB 2(R11), R14 MOVW R12, (BX) MOVB R14, 2(BX) ADDQ R13, R11 ADDQ R13, BX JMP copy_2_end copy_2_move_4through7: MOVL (R11), R12 MOVL -4(R11)(R13*1), R14 MOVL R12, (BX) MOVL R14, -4(BX)(R13*1) ADDQ R13, R11 ADDQ R13, BX JMP copy_2_end copy_2_move_8through16: MOVQ (R11), R12 MOVQ -8(R11)(R13*1), R14 MOVQ R12, (BX) MOVQ R14, -8(BX)(R13*1) ADDQ R13, R11 ADDQ R13, BX copy_2_end: JMP handle_loop // Copy overlapping match copy_overlapping_match: ADDQ R13, DI copy_slow_3: MOVBQZX (R11), R12 MOVB R12, (BX) INCQ R11 INCQ BX DECQ R13 JNZ copy_slow_3 handle_loop: ADDQ $0x18, AX INCQ DX CMPQ DX, CX JB main_loop loop_finished: // Return value MOVB $0x01, ret+8(FP) // Update the context MOVQ ctx+0(FP), AX MOVQ DX, 24(AX) MOVQ DI, 104(AX) SUBQ 80(AX), SI MOVQ SI, 112(AX) RET error_match_off_too_big: // Return value MOVB $0x00, ret+8(FP) // Update the context MOVQ ctx+0(FP), AX MOVQ DX, 24(AX) MOVQ DI, 104(AX) SUBQ 80(AX), SI MOVQ SI, 112(AX) RET empty_seqs: // Return value MOVB $0x01, ret+8(FP) RET // func sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int // Requires: CMOV, SSE TEXT ·sequenceDecs_decodeSync_amd64(SB), $96-32 MOVQ br+8(FP), CX MOVQ 24(CX), DX MOVBQZX 40(CX), BX MOVQ (CX), AX MOVQ 32(CX), SI ADDQ SI, AX MOVQ AX, (SP) MOVQ ctx+16(FP), AX MOVQ 72(AX), DI MOVQ 80(AX), R8 MOVQ 88(AX), R9 MOVQ (AX), CX MOVQ CX, 8(SP) MOVQ 24(AX), CX MOVQ CX, 16(SP) MOVQ 48(AX), CX MOVQ CX, 24(SP) MOVQ 96(AX), CX MOVQ CX, 32(SP) XORQ CX, CX MOVQ CX, 40(SP) MOVQ CX, 48(SP) MOVQ CX, 56(SP) MOVQ 112(AX), R10 MOVQ 128(AX), CX MOVQ CX, 64(SP) MOVQ 144(AX), R11 MOVQ 136(AX), R12 MOVQ 200(AX), CX MOVQ CX, 88(SP) MOVQ 176(AX), CX MOVQ CX, 80(SP) MOVQ 184(AX), AX MOVQ AX, 72(SP) MOVQ 72(SP), AX ADDQ AX, 80(SP) // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) ADDQ R10, 64(SP) // outBase += outPosition ADDQ R12, R10 sequenceDecs_decodeSync_amd64_main_loop: MOVQ (SP), R13 // Fill bitreader to have enough for the offset and match length. CMPQ SI, $0x08 JL sequenceDecs_decodeSync_amd64_fill_byte_by_byte MOVQ BX, AX SHRQ $0x03, AX SUBQ AX, R13 MOVQ (R13), DX SUBQ AX, SI ANDQ $0x07, BX JMP sequenceDecs_decodeSync_amd64_fill_end sequenceDecs_decodeSync_amd64_fill_byte_by_byte: CMPQ SI, $0x00 JLE sequenceDecs_decodeSync_amd64_fill_check_overread CMPQ BX, $0x07 JLE sequenceDecs_decodeSync_amd64_fill_end SHLQ $0x08, DX SUBQ $0x01, R13 SUBQ $0x01, SI SUBQ $0x08, BX MOVBQZX (R13), AX ORQ AX, DX JMP sequenceDecs_decodeSync_amd64_fill_byte_by_byte sequenceDecs_decodeSync_amd64_fill_check_overread: CMPQ BX, $0x40 JA error_overread sequenceDecs_decodeSync_amd64_fill_end: // Update offset MOVQ R9, AX MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R14 ADDQ R14, AX MOVQ AX, 40(SP) // Update match length MOVQ R8, AX MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R14 ADDQ R14, AX MOVQ AX, 48(SP) // Fill bitreader to have enough for the remaining CMPQ SI, $0x08 JL sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte MOVQ BX, AX SHRQ $0x03, AX SUBQ AX, R13 MOVQ (R13), DX SUBQ AX, SI ANDQ $0x07, BX JMP sequenceDecs_decodeSync_amd64_fill_2_end sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte: CMPQ SI, $0x00 JLE sequenceDecs_decodeSync_amd64_fill_2_check_overread CMPQ BX, $0x07 JLE sequenceDecs_decodeSync_amd64_fill_2_end SHLQ $0x08, DX SUBQ $0x01, R13 SUBQ $0x01, SI SUBQ $0x08, BX MOVBQZX (R13), AX ORQ AX, DX JMP sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte sequenceDecs_decodeSync_amd64_fill_2_check_overread: CMPQ BX, $0x40 JA error_overread sequenceDecs_decodeSync_amd64_fill_2_end: // Update literal length MOVQ DI, AX MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R14 ADDQ R14, AX MOVQ AX, 56(SP) // Fill bitreader for state updates MOVQ R13, (SP) MOVQ R9, AX SHRQ $0x08, AX MOVBQZX AL, AX CMPQ 32(SP), $0x00 JZ sequenceDecs_decodeSync_amd64_skip_update // Update Literal Length State MOVBQZX DI, R13 SHRL $0x10, DI MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 ADDQ R13, BX XORQ $0x3f, R13 MOVQ R13, CX SHRQ CL, R14 ADDQ R14, DI // Load ctx.llTable MOVQ 8(SP), CX MOVQ (CX)(DI*8), DI // Update Match Length State MOVBQZX R8, R13 SHRL $0x10, R8 MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 ADDQ R13, BX XORQ $0x3f, R13 MOVQ R13, CX SHRQ CL, R14 ADDQ R14, R8 // Load ctx.mlTable MOVQ 16(SP), CX MOVQ (CX)(R8*8), R8 // Update Offset State MOVBQZX R9, R13 SHRL $0x10, R9 MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 ADDQ R13, BX XORQ $0x3f, R13 MOVQ R13, CX SHRQ CL, R14 ADDQ R14, R9 // Load ctx.ofTable MOVQ 24(SP), CX MOVQ (CX)(R9*8), R9 sequenceDecs_decodeSync_amd64_skip_update: // Adjust offset MOVQ s+0(FP), CX MOVQ 40(SP), R13 CMPQ AX, $0x01 JBE sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0 MOVUPS 144(CX), X0 MOVQ R13, 144(CX) MOVUPS X0, 152(CX) JMP sequenceDecs_decodeSync_amd64_after_adjust sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0: CMPQ 56(SP), $0x00000000 JNE sequenceDecs_decodeSync_amd64_adjust_offset_maybezero INCQ R13 JMP sequenceDecs_decodeSync_amd64_adjust_offset_nonzero sequenceDecs_decodeSync_amd64_adjust_offset_maybezero: TESTQ R13, R13 JNZ sequenceDecs_decodeSync_amd64_adjust_offset_nonzero MOVQ 144(CX), R13 JMP sequenceDecs_decodeSync_amd64_after_adjust sequenceDecs_decodeSync_amd64_adjust_offset_nonzero: MOVQ R13, AX XORQ R14, R14 MOVQ $-1, R15 CMPQ R13, $0x03 CMOVQEQ R14, AX CMOVQEQ R15, R14 ADDQ 144(CX)(AX*8), R14 JNZ sequenceDecs_decodeSync_amd64_adjust_temp_valid MOVQ $0x00000001, R14 sequenceDecs_decodeSync_amd64_adjust_temp_valid: CMPQ R13, $0x01 JZ sequenceDecs_decodeSync_amd64_adjust_skip MOVQ 152(CX), AX MOVQ AX, 160(CX) sequenceDecs_decodeSync_amd64_adjust_skip: MOVQ 144(CX), AX MOVQ AX, 152(CX) MOVQ R14, 144(CX) MOVQ R14, R13 sequenceDecs_decodeSync_amd64_after_adjust: MOVQ R13, 40(SP) // Check values MOVQ 48(SP), AX MOVQ 56(SP), CX MOVQ ctx+16(FP), R14 SUBQ CX, 104(R14) JS error_not_enough_literals CMPQ AX, $0x00020002 JA sequenceDecs_decodeSync_amd64_error_match_len_too_big TESTQ R13, R13 JNZ sequenceDecs_decodeSync_amd64_match_len_ofs_ok TESTQ AX, AX JNZ sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch sequenceDecs_decodeSync_amd64_match_len_ofs_ok: // Check if we have enough space in s.out LEAQ 16(CX)(AX*1), R14 ADDQ R10, R14 CMPQ R14, 64(SP) JA error_not_enough_space // Copy literals MOVUPS (R11), X0 MOVUPS X0, (R10) CMPQ CX, $0x10 JBE copy_1_end MOVQ $0x00000010, R14 copy_1: MOVUPS (R11)(R14*1), X0 MOVUPS X0, (R10)(R14*1) ADDQ $0x10, R14 CMPQ R14, CX JB copy_1 copy_1_end: ADDQ CX, R11 ADDQ CX, R10 ADDQ CX, R12 // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) MOVQ R12, CX ADDQ 72(SP), CX CMPQ R13, CX JG error_match_off_too_big CMPQ R13, 88(SP) JG error_match_off_too_big // Copy match from history MOVQ R13, CX SUBQ R12, CX JLS copy_match MOVQ 80(SP), R14 SUBQ CX, R14 CMPQ AX, CX JG copy_all_from_history MOVQ AX, CX SUBQ $0x10, CX JB copy_4_small copy_4_loop: MOVUPS (R14), X0 MOVUPS X0, (R10) ADDQ $0x10, R14 ADDQ $0x10, R10 SUBQ $0x10, CX JAE copy_4_loop LEAQ 16(R14)(CX*1), R14 LEAQ 16(R10)(CX*1), R10 MOVUPS -16(R14), X0 MOVUPS X0, -16(R10) JMP copy_4_end copy_4_small: CMPQ AX, $0x03 JE copy_4_move_3 CMPQ AX, $0x08 JB copy_4_move_4through7 JMP copy_4_move_8through16 copy_4_move_3: MOVWQZX (R14), CX MOVB 2(R14), R13 MOVW CX, (R10) MOVB R13, 2(R10) ADDQ AX, R14 ADDQ AX, R10 JMP copy_4_end copy_4_move_4through7: MOVL (R14), CX MOVL -4(R14)(AX*1), R13 MOVL CX, (R10) MOVL R13, -4(R10)(AX*1) ADDQ AX, R14 ADDQ AX, R10 JMP copy_4_end copy_4_move_8through16: MOVQ (R14), CX MOVQ -8(R14)(AX*1), R13 MOVQ CX, (R10) MOVQ R13, -8(R10)(AX*1) ADDQ AX, R14 ADDQ AX, R10 copy_4_end: ADDQ AX, R12 JMP handle_loop JMP loop_finished copy_all_from_history: MOVQ CX, R15 SUBQ $0x10, R15 JB copy_5_small copy_5_loop: MOVUPS (R14), X0 MOVUPS X0, (R10) ADDQ $0x10, R14 ADDQ $0x10, R10 SUBQ $0x10, R15 JAE copy_5_loop LEAQ 16(R14)(R15*1), R14 LEAQ 16(R10)(R15*1), R10 MOVUPS -16(R14), X0 MOVUPS X0, -16(R10) JMP copy_5_end copy_5_small: CMPQ CX, $0x03 JE copy_5_move_3 JB copy_5_move_1or2 CMPQ CX, $0x08 JB copy_5_move_4through7 JMP copy_5_move_8through16 copy_5_move_1or2: MOVB (R14), R15 MOVB -1(R14)(CX*1), BP MOVB R15, (R10) MOVB BP, -1(R10)(CX*1) ADDQ CX, R14 ADDQ CX, R10 JMP copy_5_end copy_5_move_3: MOVWQZX (R14), R15 MOVB 2(R14), BP MOVW R15, (R10) MOVB BP, 2(R10) ADDQ CX, R14 ADDQ CX, R10 JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 MOVL -4(R14)(CX*1), BP MOVL R15, (R10) MOVL BP, -4(R10)(CX*1) ADDQ CX, R14 ADDQ CX, R10 JMP copy_5_end copy_5_move_8through16: MOVQ (R14), R15 MOVQ -8(R14)(CX*1), BP MOVQ R15, (R10) MOVQ BP, -8(R10)(CX*1) ADDQ CX, R14 ADDQ CX, R10 copy_5_end: ADDQ CX, R12 SUBQ CX, AX // Copy match from the current buffer copy_match: MOVQ R10, CX SUBQ R13, CX // ml <= mo CMPQ AX, R13 JA copy_overlapping_match // Copy non-overlapping match ADDQ AX, R12 MOVUPS (CX), X0 MOVUPS X0, (R10) CMPQ AX, $0x10 JA copy_2_long ADDQ AX, R10 JMP handle_loop copy_2_long: LEAQ 16(R10), R13 ADDQ AX, R10 ADDQ $0x10, CX SUBQ $0x10, AX copy_2: MOVUPS (CX), X0 MOVUPS X0, (R13) ADDQ $0x10, CX ADDQ $0x10, R13 SUBQ $0x10, AX JHI copy_2 JMP handle_loop // Copy overlapping match copy_overlapping_match: ADDQ AX, R12 copy_slow_3: MOVBQZX (CX), R13 MOVB R13, (R10) INCQ CX INCQ R10 DECQ AX JNZ copy_slow_3 handle_loop: DECQ 32(SP) JNS sequenceDecs_decodeSync_amd64_main_loop loop_finished: MOVQ br+8(FP), AX MOVQ DX, 24(AX) MOVB BL, 40(AX) MOVQ SI, 32(AX) // s.seqSize += outPosition - ctx.outPosition MOVQ ctx+16(FP), AX MOVQ s+0(FP), CX MOVQ R12, DX SUBQ 136(AX), DX ADDQ DX, 256(CX) // Update the context MOVQ ctx+16(FP), AX MOVQ R12, 136(AX) MOVQ 144(AX), CX SUBQ CX, R11 MOVQ R11, 168(AX) // Return success MOVQ $0x00000000, ret+24(FP) RET // Return with match length error sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch: MOVQ 48(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 216(CX) MOVQ $0x00000001, ret+24(FP) RET // Return with match too long error sequenceDecs_decodeSync_amd64_error_match_len_too_big: MOVQ ctx+16(FP), AX MOVQ 48(SP), CX MOVQ CX, 216(AX) MOVQ $0x00000002, ret+24(FP) RET // Return with match offset too long error error_match_off_too_big: MOVQ ctx+16(FP), AX MOVQ 40(SP), CX MOVQ CX, 224(AX) MOVQ R12, 136(AX) MOVQ $0x00000003, ret+24(FP) RET // Return with not enough literals error error_not_enough_literals: MOVQ ctx+16(FP), AX MOVQ 56(SP), CX MOVQ CX, 208(AX) MOVQ $0x00000004, ret+24(FP) RET // Return with overread error error_overread: MOVQ $0x00000006, ret+24(FP) RET // Return with not enough output space error error_not_enough_space: MOVQ ctx+16(FP), AX MOVQ 56(SP), CX MOVQ CX, 208(AX) MOVQ 48(SP), CX MOVQ CX, 216(AX) MOVQ R12, 136(AX) MOVQ $0x00000005, ret+24(FP) RET // func sequenceDecs_decodeSync_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int // Requires: BMI, BMI2, CMOV, SSE TEXT ·sequenceDecs_decodeSync_bmi2(SB), $96-32 MOVQ br+8(FP), BX MOVQ 24(BX), AX MOVBQZX 40(BX), DX MOVQ (BX), CX MOVQ 32(BX), BX ADDQ BX, CX MOVQ CX, (SP) MOVQ ctx+16(FP), CX MOVQ 72(CX), SI MOVQ 80(CX), DI MOVQ 88(CX), R8 MOVQ (CX), R9 MOVQ R9, 8(SP) MOVQ 24(CX), R9 MOVQ R9, 16(SP) MOVQ 48(CX), R9 MOVQ R9, 24(SP) MOVQ 96(CX), R9 MOVQ R9, 32(SP) XORQ R9, R9 MOVQ R9, 40(SP) MOVQ R9, 48(SP) MOVQ R9, 56(SP) MOVQ 112(CX), R9 MOVQ 128(CX), R10 MOVQ R10, 64(SP) MOVQ 144(CX), R10 MOVQ 136(CX), R11 MOVQ 200(CX), R12 MOVQ R12, 88(SP) MOVQ 176(CX), R12 MOVQ R12, 80(SP) MOVQ 184(CX), CX MOVQ CX, 72(SP) MOVQ 72(SP), CX ADDQ CX, 80(SP) // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) ADDQ R9, 64(SP) // outBase += outPosition ADDQ R11, R9 sequenceDecs_decodeSync_bmi2_main_loop: MOVQ (SP), R12 // Fill bitreader to have enough for the offset and match length. CMPQ BX, $0x08 JL sequenceDecs_decodeSync_bmi2_fill_byte_by_byte MOVQ DX, CX SHRQ $0x03, CX SUBQ CX, R12 MOVQ (R12), AX SUBQ CX, BX ANDQ $0x07, DX JMP sequenceDecs_decodeSync_bmi2_fill_end sequenceDecs_decodeSync_bmi2_fill_byte_by_byte: CMPQ BX, $0x00 JLE sequenceDecs_decodeSync_bmi2_fill_check_overread CMPQ DX, $0x07 JLE sequenceDecs_decodeSync_bmi2_fill_end SHLQ $0x08, AX SUBQ $0x01, R12 SUBQ $0x01, BX SUBQ $0x08, DX MOVBQZX (R12), CX ORQ CX, AX JMP sequenceDecs_decodeSync_bmi2_fill_byte_by_byte sequenceDecs_decodeSync_bmi2_fill_check_overread: CMPQ DX, $0x40 JA error_overread sequenceDecs_decodeSync_bmi2_fill_end: // Update offset MOVQ $0x00000808, CX BEXTRQ CX, R8, R13 MOVQ AX, R14 LEAQ (DX)(R13*1), CX ROLQ CL, R14 BZHIQ R13, R14, R14 MOVQ CX, DX MOVQ R8, CX SHRQ $0x20, CX ADDQ R14, CX MOVQ CX, 40(SP) // Update match length MOVQ $0x00000808, CX BEXTRQ CX, DI, R13 MOVQ AX, R14 LEAQ (DX)(R13*1), CX ROLQ CL, R14 BZHIQ R13, R14, R14 MOVQ CX, DX MOVQ DI, CX SHRQ $0x20, CX ADDQ R14, CX MOVQ CX, 48(SP) // Fill bitreader to have enough for the remaining CMPQ BX, $0x08 JL sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte MOVQ DX, CX SHRQ $0x03, CX SUBQ CX, R12 MOVQ (R12), AX SUBQ CX, BX ANDQ $0x07, DX JMP sequenceDecs_decodeSync_bmi2_fill_2_end sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte: CMPQ BX, $0x00 JLE sequenceDecs_decodeSync_bmi2_fill_2_check_overread CMPQ DX, $0x07 JLE sequenceDecs_decodeSync_bmi2_fill_2_end SHLQ $0x08, AX SUBQ $0x01, R12 SUBQ $0x01, BX SUBQ $0x08, DX MOVBQZX (R12), CX ORQ CX, AX JMP sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte sequenceDecs_decodeSync_bmi2_fill_2_check_overread: CMPQ DX, $0x40 JA error_overread sequenceDecs_decodeSync_bmi2_fill_2_end: // Update literal length MOVQ $0x00000808, CX BEXTRQ CX, SI, R13 MOVQ AX, R14 LEAQ (DX)(R13*1), CX ROLQ CL, R14 BZHIQ R13, R14, R14 MOVQ CX, DX MOVQ SI, CX SHRQ $0x20, CX ADDQ R14, CX MOVQ CX, 56(SP) // Fill bitreader for state updates MOVQ R12, (SP) MOVQ $0x00000808, CX BEXTRQ CX, R8, R12 CMPQ 32(SP), $0x00 JZ sequenceDecs_decodeSync_bmi2_skip_update LEAQ (SI)(DI*1), R13 ADDQ R8, R13 MOVBQZX R13, R13 LEAQ (DX)(R13*1), CX MOVQ AX, R14 MOVQ CX, DX ROLQ CL, R14 BZHIQ R13, R14, R14 // Update Offset State BZHIQ R8, R14, CX SHRXQ R8, R14, R14 SHRL $0x10, R8 ADDQ CX, R8 // Load ctx.ofTable MOVQ 24(SP), CX MOVQ (CX)(R8*8), R8 // Update Match Length State BZHIQ DI, R14, CX SHRXQ DI, R14, R14 SHRL $0x10, DI ADDQ CX, DI // Load ctx.mlTable MOVQ 16(SP), CX MOVQ (CX)(DI*8), DI // Update Literal Length State BZHIQ SI, R14, CX SHRL $0x10, SI ADDQ CX, SI // Load ctx.llTable MOVQ 8(SP), CX MOVQ (CX)(SI*8), SI sequenceDecs_decodeSync_bmi2_skip_update: // Adjust offset MOVQ s+0(FP), CX MOVQ 40(SP), R13 CMPQ R12, $0x01 JBE sequenceDecs_decodeSync_bmi2_adjust_offsetB_1_or_0 MOVUPS 144(CX), X0 MOVQ R13, 144(CX) MOVUPS X0, 152(CX) JMP sequenceDecs_decodeSync_bmi2_after_adjust sequenceDecs_decodeSync_bmi2_adjust_offsetB_1_or_0: CMPQ 56(SP), $0x00000000 JNE sequenceDecs_decodeSync_bmi2_adjust_offset_maybezero INCQ R13 JMP sequenceDecs_decodeSync_bmi2_adjust_offset_nonzero sequenceDecs_decodeSync_bmi2_adjust_offset_maybezero: TESTQ R13, R13 JNZ sequenceDecs_decodeSync_bmi2_adjust_offset_nonzero MOVQ 144(CX), R13 JMP sequenceDecs_decodeSync_bmi2_after_adjust sequenceDecs_decodeSync_bmi2_adjust_offset_nonzero: MOVQ R13, R12 XORQ R14, R14 MOVQ $-1, R15 CMPQ R13, $0x03 CMOVQEQ R14, R12 CMOVQEQ R15, R14 ADDQ 144(CX)(R12*8), R14 JNZ sequenceDecs_decodeSync_bmi2_adjust_temp_valid MOVQ $0x00000001, R14 sequenceDecs_decodeSync_bmi2_adjust_temp_valid: CMPQ R13, $0x01 JZ sequenceDecs_decodeSync_bmi2_adjust_skip MOVQ 152(CX), R12 MOVQ R12, 160(CX) sequenceDecs_decodeSync_bmi2_adjust_skip: MOVQ 144(CX), R12 MOVQ R12, 152(CX) MOVQ R14, 144(CX) MOVQ R14, R13 sequenceDecs_decodeSync_bmi2_after_adjust: MOVQ R13, 40(SP) // Check values MOVQ 48(SP), CX MOVQ 56(SP), R12 MOVQ ctx+16(FP), R14 SUBQ R12, 104(R14) JS error_not_enough_literals CMPQ CX, $0x00020002 JA sequenceDecs_decodeSync_bmi2_error_match_len_too_big TESTQ R13, R13 JNZ sequenceDecs_decodeSync_bmi2_match_len_ofs_ok TESTQ CX, CX JNZ sequenceDecs_decodeSync_bmi2_error_match_len_ofs_mismatch sequenceDecs_decodeSync_bmi2_match_len_ofs_ok: // Check if we have enough space in s.out LEAQ 16(R12)(CX*1), R14 ADDQ R9, R14 CMPQ R14, 64(SP) JA error_not_enough_space // Copy literals MOVUPS (R10), X0 MOVUPS X0, (R9) CMPQ R12, $0x10 JBE copy_1_end MOVQ $0x00000010, R14 copy_1: MOVUPS (R10)(R14*1), X0 MOVUPS X0, (R9)(R14*1) ADDQ $0x10, R14 CMPQ R14, R12 JB copy_1 copy_1_end: ADDQ R12, R10 ADDQ R12, R9 ADDQ R12, R11 // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) MOVQ R11, R12 ADDQ 72(SP), R12 CMPQ R13, R12 JG error_match_off_too_big CMPQ R13, 88(SP) JG error_match_off_too_big // Copy match from history MOVQ R13, R12 SUBQ R11, R12 JLS copy_match MOVQ 80(SP), R14 SUBQ R12, R14 CMPQ CX, R12 JG copy_all_from_history MOVQ CX, R12 SUBQ $0x10, R12 JB copy_4_small copy_4_loop: MOVUPS (R14), X0 MOVUPS X0, (R9) ADDQ $0x10, R14 ADDQ $0x10, R9 SUBQ $0x10, R12 JAE copy_4_loop LEAQ 16(R14)(R12*1), R14 LEAQ 16(R9)(R12*1), R9 MOVUPS -16(R14), X0 MOVUPS X0, -16(R9) JMP copy_4_end copy_4_small: CMPQ CX, $0x03 JE copy_4_move_3 CMPQ CX, $0x08 JB copy_4_move_4through7 JMP copy_4_move_8through16 copy_4_move_3: MOVWQZX (R14), R12 MOVB 2(R14), R13 MOVW R12, (R9) MOVB R13, 2(R9) ADDQ CX, R14 ADDQ CX, R9 JMP copy_4_end copy_4_move_4through7: MOVL (R14), R12 MOVL -4(R14)(CX*1), R13 MOVL R12, (R9) MOVL R13, -4(R9)(CX*1) ADDQ CX, R14 ADDQ CX, R9 JMP copy_4_end copy_4_move_8through16: MOVQ (R14), R12 MOVQ -8(R14)(CX*1), R13 MOVQ R12, (R9) MOVQ R13, -8(R9)(CX*1) ADDQ CX, R14 ADDQ CX, R9 copy_4_end: ADDQ CX, R11 JMP handle_loop JMP loop_finished copy_all_from_history: MOVQ R12, R15 SUBQ $0x10, R15 JB copy_5_small copy_5_loop: MOVUPS (R14), X0 MOVUPS X0, (R9) ADDQ $0x10, R14 ADDQ $0x10, R9 SUBQ $0x10, R15 JAE copy_5_loop LEAQ 16(R14)(R15*1), R14 LEAQ 16(R9)(R15*1), R9 MOVUPS -16(R14), X0 MOVUPS X0, -16(R9) JMP copy_5_end copy_5_small: CMPQ R12, $0x03 JE copy_5_move_3 JB copy_5_move_1or2 CMPQ R12, $0x08 JB copy_5_move_4through7 JMP copy_5_move_8through16 copy_5_move_1or2: MOVB (R14), R15 MOVB -1(R14)(R12*1), BP MOVB R15, (R9) MOVB BP, -1(R9)(R12*1) ADDQ R12, R14 ADDQ R12, R9 JMP copy_5_end copy_5_move_3: MOVWQZX (R14), R15 MOVB 2(R14), BP MOVW R15, (R9) MOVB BP, 2(R9) ADDQ R12, R14 ADDQ R12, R9 JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 MOVL -4(R14)(R12*1), BP MOVL R15, (R9) MOVL BP, -4(R9)(R12*1) ADDQ R12, R14 ADDQ R12, R9 JMP copy_5_end copy_5_move_8through16: MOVQ (R14), R15 MOVQ -8(R14)(R12*1), BP MOVQ R15, (R9) MOVQ BP, -8(R9)(R12*1) ADDQ R12, R14 ADDQ R12, R9 copy_5_end: ADDQ R12, R11 SUBQ R12, CX // Copy match from the current buffer copy_match: MOVQ R9, R12 SUBQ R13, R12 // ml <= mo CMPQ CX, R13 JA copy_overlapping_match // Copy non-overlapping match ADDQ CX, R11 MOVUPS (R12), X0 MOVUPS X0, (R9) CMPQ CX, $0x10 JA copy_2_long ADDQ CX, R9 JMP handle_loop copy_2_long: LEAQ 16(R9), R13 ADDQ CX, R9 ADDQ $0x10, R12 SUBQ $0x10, CX copy_2: MOVUPS (R12), X0 MOVUPS X0, (R13) ADDQ $0x10, R12 ADDQ $0x10, R13 SUBQ $0x10, CX JHI copy_2 JMP handle_loop // Copy overlapping match copy_overlapping_match: ADDQ CX, R11 copy_slow_3: MOVBQZX (R12), R13 MOVB R13, (R9) INCQ R12 INCQ R9 DECQ CX JNZ copy_slow_3 handle_loop: DECQ 32(SP) JNS sequenceDecs_decodeSync_bmi2_main_loop loop_finished: MOVQ br+8(FP), CX MOVQ AX, 24(CX) MOVB DL, 40(CX) MOVQ BX, 32(CX) // s.seqSize += outPosition - ctx.outPosition MOVQ ctx+16(FP), AX MOVQ s+0(FP), CX MOVQ R11, DX SUBQ 136(AX), DX ADDQ DX, 256(CX) // Update the context MOVQ ctx+16(FP), AX MOVQ R11, 136(AX) MOVQ 144(AX), CX SUBQ CX, R10 MOVQ R10, 168(AX) // Return success MOVQ $0x00000000, ret+24(FP) RET // Return with match length error sequenceDecs_decodeSync_bmi2_error_match_len_ofs_mismatch: MOVQ 48(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 216(CX) MOVQ $0x00000001, ret+24(FP) RET // Return with match too long error sequenceDecs_decodeSync_bmi2_error_match_len_too_big: MOVQ ctx+16(FP), AX MOVQ 48(SP), CX MOVQ CX, 216(AX) MOVQ $0x00000002, ret+24(FP) RET // Return with match offset too long error error_match_off_too_big: MOVQ ctx+16(FP), AX MOVQ 40(SP), CX MOVQ CX, 224(AX) MOVQ R11, 136(AX) MOVQ $0x00000003, ret+24(FP) RET // Return with not enough literals error error_not_enough_literals: MOVQ ctx+16(FP), AX MOVQ 56(SP), CX MOVQ CX, 208(AX) MOVQ $0x00000004, ret+24(FP) RET // Return with overread error error_overread: MOVQ $0x00000006, ret+24(FP) RET // Return with not enough output space error error_not_enough_space: MOVQ ctx+16(FP), AX MOVQ 56(SP), CX MOVQ CX, 208(AX) MOVQ 48(SP), CX MOVQ CX, 216(AX) MOVQ R11, 136(AX) MOVQ $0x00000005, ret+24(FP) RET // func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int // Requires: CMOV, SSE TEXT ·sequenceDecs_decodeSync_safe_amd64(SB), $96-32 MOVQ br+8(FP), CX MOVQ 24(CX), DX MOVBQZX 40(CX), BX MOVQ (CX), AX MOVQ 32(CX), SI ADDQ SI, AX MOVQ AX, (SP) MOVQ ctx+16(FP), AX MOVQ 72(AX), DI MOVQ 80(AX), R8 MOVQ 88(AX), R9 MOVQ (AX), CX MOVQ CX, 8(SP) MOVQ 24(AX), CX MOVQ CX, 16(SP) MOVQ 48(AX), CX MOVQ CX, 24(SP) MOVQ 96(AX), CX MOVQ CX, 32(SP) XORQ CX, CX MOVQ CX, 40(SP) MOVQ CX, 48(SP) MOVQ CX, 56(SP) MOVQ 112(AX), R10 MOVQ 128(AX), CX MOVQ CX, 64(SP) MOVQ 144(AX), R11 MOVQ 136(AX), R12 MOVQ 200(AX), CX MOVQ CX, 88(SP) MOVQ 176(AX), CX MOVQ CX, 80(SP) MOVQ 184(AX), AX MOVQ AX, 72(SP) MOVQ 72(SP), AX ADDQ AX, 80(SP) // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) ADDQ R10, 64(SP) // outBase += outPosition ADDQ R12, R10 sequenceDecs_decodeSync_safe_amd64_main_loop: MOVQ (SP), R13 // Fill bitreader to have enough for the offset and match length. CMPQ SI, $0x08 JL sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte MOVQ BX, AX SHRQ $0x03, AX SUBQ AX, R13 MOVQ (R13), DX SUBQ AX, SI ANDQ $0x07, BX JMP sequenceDecs_decodeSync_safe_amd64_fill_end sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte: CMPQ SI, $0x00 JLE sequenceDecs_decodeSync_safe_amd64_fill_check_overread CMPQ BX, $0x07 JLE sequenceDecs_decodeSync_safe_amd64_fill_end SHLQ $0x08, DX SUBQ $0x01, R13 SUBQ $0x01, SI SUBQ $0x08, BX MOVBQZX (R13), AX ORQ AX, DX JMP sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte sequenceDecs_decodeSync_safe_amd64_fill_check_overread: CMPQ BX, $0x40 JA error_overread sequenceDecs_decodeSync_safe_amd64_fill_end: // Update offset MOVQ R9, AX MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R14 ADDQ R14, AX MOVQ AX, 40(SP) // Update match length MOVQ R8, AX MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R14 ADDQ R14, AX MOVQ AX, 48(SP) // Fill bitreader to have enough for the remaining CMPQ SI, $0x08 JL sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte MOVQ BX, AX SHRQ $0x03, AX SUBQ AX, R13 MOVQ (R13), DX SUBQ AX, SI ANDQ $0x07, BX JMP sequenceDecs_decodeSync_safe_amd64_fill_2_end sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte: CMPQ SI, $0x00 JLE sequenceDecs_decodeSync_safe_amd64_fill_2_check_overread CMPQ BX, $0x07 JLE sequenceDecs_decodeSync_safe_amd64_fill_2_end SHLQ $0x08, DX SUBQ $0x01, R13 SUBQ $0x01, SI SUBQ $0x08, BX MOVBQZX (R13), AX ORQ AX, DX JMP sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte sequenceDecs_decodeSync_safe_amd64_fill_2_check_overread: CMPQ BX, $0x40 JA error_overread sequenceDecs_decodeSync_safe_amd64_fill_2_end: // Update literal length MOVQ DI, AX MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 MOVBLZX AH, CX SHRQ $0x20, AX ADDQ CX, BX XORQ $0x3f, CX SHRQ CL, R14 ADDQ R14, AX MOVQ AX, 56(SP) // Fill bitreader for state updates MOVQ R13, (SP) MOVQ R9, AX SHRQ $0x08, AX MOVBQZX AL, AX CMPQ 32(SP), $0x00 JZ sequenceDecs_decodeSync_safe_amd64_skip_update // Update Literal Length State MOVBQZX DI, R13 SHRL $0x10, DI MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 ADDQ R13, BX XORQ $0x3f, R13 MOVQ R13, CX SHRQ CL, R14 ADDQ R14, DI // Load ctx.llTable MOVQ 8(SP), CX MOVQ (CX)(DI*8), DI // Update Match Length State MOVBQZX R8, R13 SHRL $0x10, R8 MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 ADDQ R13, BX XORQ $0x3f, R13 MOVQ R13, CX SHRQ CL, R14 ADDQ R14, R8 // Load ctx.mlTable MOVQ 16(SP), CX MOVQ (CX)(R8*8), R8 // Update Offset State MOVBQZX R9, R13 SHRL $0x10, R9 MOVQ BX, CX MOVQ DX, R14 SHLQ CL, R14 SHRQ $0x01, R14 ADDQ R13, BX XORQ $0x3f, R13 MOVQ R13, CX SHRQ CL, R14 ADDQ R14, R9 // Load ctx.ofTable MOVQ 24(SP), CX MOVQ (CX)(R9*8), R9 sequenceDecs_decodeSync_safe_amd64_skip_update: // Adjust offset MOVQ s+0(FP), CX MOVQ 40(SP), R13 CMPQ AX, $0x01 JBE sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0 MOVUPS 144(CX), X0 MOVQ R13, 144(CX) MOVUPS X0, 152(CX) JMP sequenceDecs_decodeSync_safe_amd64_after_adjust sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0: CMPQ 56(SP), $0x00000000 JNE sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero INCQ R13 JMP sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero: TESTQ R13, R13 JNZ sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero MOVQ 144(CX), R13 JMP sequenceDecs_decodeSync_safe_amd64_after_adjust sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero: MOVQ R13, AX XORQ R14, R14 MOVQ $-1, R15 CMPQ R13, $0x03 CMOVQEQ R14, AX CMOVQEQ R15, R14 ADDQ 144(CX)(AX*8), R14 JNZ sequenceDecs_decodeSync_safe_amd64_adjust_temp_valid MOVQ $0x00000001, R14 sequenceDecs_decodeSync_safe_amd64_adjust_temp_valid: CMPQ R13, $0x01 JZ sequenceDecs_decodeSync_safe_amd64_adjust_skip MOVQ 152(CX), AX MOVQ AX, 160(CX) sequenceDecs_decodeSync_safe_amd64_adjust_skip: MOVQ 144(CX), AX MOVQ AX, 152(CX) MOVQ R14, 144(CX) MOVQ R14, R13 sequenceDecs_decodeSync_safe_amd64_after_adjust: MOVQ R13, 40(SP) // Check values MOVQ 48(SP), AX MOVQ 56(SP), CX MOVQ ctx+16(FP), R14 SUBQ CX, 104(R14) JS error_not_enough_literals CMPQ AX, $0x00020002 JA sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big TESTQ R13, R13 JNZ sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok TESTQ AX, AX JNZ sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok: // Check if we have enough space in s.out LEAQ (CX)(AX*1), R14 ADDQ R10, R14 CMPQ R14, 64(SP) JA error_not_enough_space // Copy literals TESTQ CX, CX JZ check_offset MOVQ CX, R14 SUBQ $0x10, R14 JB copy_1_small copy_1_loop: MOVUPS (R11), X0 MOVUPS X0, (R10) ADDQ $0x10, R11 ADDQ $0x10, R10 SUBQ $0x10, R14 JAE copy_1_loop LEAQ 16(R11)(R14*1), R11 LEAQ 16(R10)(R14*1), R10 MOVUPS -16(R11), X0 MOVUPS X0, -16(R10) JMP copy_1_end copy_1_small: CMPQ CX, $0x03 JE copy_1_move_3 JB copy_1_move_1or2 CMPQ CX, $0x08 JB copy_1_move_4through7 JMP copy_1_move_8through16 copy_1_move_1or2: MOVB (R11), R14 MOVB -1(R11)(CX*1), R15 MOVB R14, (R10) MOVB R15, -1(R10)(CX*1) ADDQ CX, R11 ADDQ CX, R10 JMP copy_1_end copy_1_move_3: MOVWQZX (R11), R14 MOVB 2(R11), R15 MOVW R14, (R10) MOVB R15, 2(R10) ADDQ CX, R11 ADDQ CX, R10 JMP copy_1_end copy_1_move_4through7: MOVL (R11), R14 MOVL -4(R11)(CX*1), R15 MOVL R14, (R10) MOVL R15, -4(R10)(CX*1) ADDQ CX, R11 ADDQ CX, R10 JMP copy_1_end copy_1_move_8through16: MOVQ (R11), R14 MOVQ -8(R11)(CX*1), R15 MOVQ R14, (R10) MOVQ R15, -8(R10)(CX*1) ADDQ CX, R11 ADDQ CX, R10 copy_1_end: ADDQ CX, R12 // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) check_offset: MOVQ R12, CX ADDQ 72(SP), CX CMPQ R13, CX JG error_match_off_too_big CMPQ R13, 88(SP) JG error_match_off_too_big // Copy match from history MOVQ R13, CX SUBQ R12, CX JLS copy_match MOVQ 80(SP), R14 SUBQ CX, R14 CMPQ AX, CX JG copy_all_from_history MOVQ AX, CX SUBQ $0x10, CX JB copy_4_small copy_4_loop: MOVUPS (R14), X0 MOVUPS X0, (R10) ADDQ $0x10, R14 ADDQ $0x10, R10 SUBQ $0x10, CX JAE copy_4_loop LEAQ 16(R14)(CX*1), R14 LEAQ 16(R10)(CX*1), R10 MOVUPS -16(R14), X0 MOVUPS X0, -16(R10) JMP copy_4_end copy_4_small: CMPQ AX, $0x03 JE copy_4_move_3 CMPQ AX, $0x08 JB copy_4_move_4through7 JMP copy_4_move_8through16 copy_4_move_3: MOVWQZX (R14), CX MOVB 2(R14), R13 MOVW CX, (R10) MOVB R13, 2(R10) ADDQ AX, R14 ADDQ AX, R10 JMP copy_4_end copy_4_move_4through7: MOVL (R14), CX MOVL -4(R14)(AX*1), R13 MOVL CX, (R10) MOVL R13, -4(R10)(AX*1) ADDQ AX, R14 ADDQ AX, R10 JMP copy_4_end copy_4_move_8through16: MOVQ (R14), CX MOVQ -8(R14)(AX*1), R13 MOVQ CX, (R10) MOVQ R13, -8(R10)(AX*1) ADDQ AX, R14 ADDQ AX, R10 copy_4_end: ADDQ AX, R12 JMP handle_loop JMP loop_finished copy_all_from_history: MOVQ CX, R15 SUBQ $0x10, R15 JB copy_5_small copy_5_loop: MOVUPS (R14), X0 MOVUPS X0, (R10) ADDQ $0x10, R14 ADDQ $0x10, R10 SUBQ $0x10, R15 JAE copy_5_loop LEAQ 16(R14)(R15*1), R14 LEAQ 16(R10)(R15*1), R10 MOVUPS -16(R14), X0 MOVUPS X0, -16(R10) JMP copy_5_end copy_5_small: CMPQ CX, $0x03 JE copy_5_move_3 JB copy_5_move_1or2 CMPQ CX, $0x08 JB copy_5_move_4through7 JMP copy_5_move_8through16 copy_5_move_1or2: MOVB (R14), R15 MOVB -1(R14)(CX*1), BP MOVB R15, (R10) MOVB BP, -1(R10)(CX*1) ADDQ CX, R14 ADDQ CX, R10 JMP copy_5_end copy_5_move_3: MOVWQZX (R14), R15 MOVB 2(R14), BP MOVW R15, (R10) MOVB BP, 2(R10) ADDQ CX, R14 ADDQ CX, R10 JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 MOVL -4(R14)(CX*1), BP MOVL R15, (R10) MOVL BP, -4(R10)(CX*1) ADDQ CX, R14 ADDQ CX, R10 JMP copy_5_end copy_5_move_8through16: MOVQ (R14), R15 MOVQ -8(R14)(CX*1), BP MOVQ R15, (R10) MOVQ BP, -8(R10)(CX*1) ADDQ CX, R14 ADDQ CX, R10 copy_5_end: ADDQ CX, R12 SUBQ CX, AX // Copy match from the current buffer copy_match: MOVQ R10, CX SUBQ R13, CX // ml <= mo CMPQ AX, R13 JA copy_overlapping_match // Copy non-overlapping match ADDQ AX, R12 MOVQ AX, R13 SUBQ $0x10, R13 JB copy_2_small copy_2_loop: MOVUPS (CX), X0 MOVUPS X0, (R10) ADDQ $0x10, CX ADDQ $0x10, R10 SUBQ $0x10, R13 JAE copy_2_loop LEAQ 16(CX)(R13*1), CX LEAQ 16(R10)(R13*1), R10 MOVUPS -16(CX), X0 MOVUPS X0, -16(R10) JMP copy_2_end copy_2_small: CMPQ AX, $0x03 JE copy_2_move_3 JB copy_2_move_1or2 CMPQ AX, $0x08 JB copy_2_move_4through7 JMP copy_2_move_8through16 copy_2_move_1or2: MOVB (CX), R13 MOVB -1(CX)(AX*1), R14 MOVB R13, (R10) MOVB R14, -1(R10)(AX*1) ADDQ AX, CX ADDQ AX, R10 JMP copy_2_end copy_2_move_3: MOVWQZX (CX), R13 MOVB 2(CX), R14 MOVW R13, (R10) MOVB R14, 2(R10) ADDQ AX, CX ADDQ AX, R10 JMP copy_2_end copy_2_move_4through7: MOVL (CX), R13 MOVL -4(CX)(AX*1), R14 MOVL R13, (R10) MOVL R14, -4(R10)(AX*1) ADDQ AX, CX ADDQ AX, R10 JMP copy_2_end copy_2_move_8through16: MOVQ (CX), R13 MOVQ -8(CX)(AX*1), R14 MOVQ R13, (R10) MOVQ R14, -8(R10)(AX*1) ADDQ AX, CX ADDQ AX, R10 copy_2_end: JMP handle_loop // Copy overlapping match copy_overlapping_match: ADDQ AX, R12 copy_slow_3: MOVBQZX (CX), R13 MOVB R13, (R10) INCQ CX INCQ R10 DECQ AX JNZ copy_slow_3 handle_loop: DECQ 32(SP) JNS sequenceDecs_decodeSync_safe_amd64_main_loop loop_finished: MOVQ br+8(FP), AX MOVQ DX, 24(AX) MOVB BL, 40(AX) MOVQ SI, 32(AX) // s.seqSize += outPosition - ctx.outPosition MOVQ ctx+16(FP), AX MOVQ s+0(FP), CX MOVQ R12, DX SUBQ 136(AX), DX ADDQ DX, 256(CX) // Update the context MOVQ ctx+16(FP), AX MOVQ R12, 136(AX) MOVQ 144(AX), CX SUBQ CX, R11 MOVQ R11, 168(AX) // Return success MOVQ $0x00000000, ret+24(FP) RET // Return with match length error sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch: MOVQ 48(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 216(CX) MOVQ $0x00000001, ret+24(FP) RET // Return with match too long error sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big: MOVQ ctx+16(FP), AX MOVQ 48(SP), CX MOVQ CX, 216(AX) MOVQ $0x00000002, ret+24(FP) RET // Return with match offset too long error error_match_off_too_big: MOVQ ctx+16(FP), AX MOVQ 40(SP), CX MOVQ CX, 224(AX) MOVQ R12, 136(AX) MOVQ $0x00000003, ret+24(FP) RET // Return with not enough literals error error_not_enough_literals: MOVQ ctx+16(FP), AX MOVQ 56(SP), CX MOVQ CX, 208(AX) MOVQ $0x00000004, ret+24(FP) RET // Return with overread error error_overread: MOVQ $0x00000006, ret+24(FP) RET // Return with not enough output space error error_not_enough_space: MOVQ ctx+16(FP), AX MOVQ 56(SP), CX MOVQ CX, 208(AX) MOVQ 48(SP), CX MOVQ CX, 216(AX) MOVQ R12, 136(AX) MOVQ $0x00000005, ret+24(FP) RET // func sequenceDecs_decodeSync_safe_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int // Requires: BMI, BMI2, CMOV, SSE TEXT ·sequenceDecs_decodeSync_safe_bmi2(SB), $96-32 MOVQ br+8(FP), BX MOVQ 24(BX), AX MOVBQZX 40(BX), DX MOVQ (BX), CX MOVQ 32(BX), BX ADDQ BX, CX MOVQ CX, (SP) MOVQ ctx+16(FP), CX MOVQ 72(CX), SI MOVQ 80(CX), DI MOVQ 88(CX), R8 MOVQ (CX), R9 MOVQ R9, 8(SP) MOVQ 24(CX), R9 MOVQ R9, 16(SP) MOVQ 48(CX), R9 MOVQ R9, 24(SP) MOVQ 96(CX), R9 MOVQ R9, 32(SP) XORQ R9, R9 MOVQ R9, 40(SP) MOVQ R9, 48(SP) MOVQ R9, 56(SP) MOVQ 112(CX), R9 MOVQ 128(CX), R10 MOVQ R10, 64(SP) MOVQ 144(CX), R10 MOVQ 136(CX), R11 MOVQ 200(CX), R12 MOVQ R12, 88(SP) MOVQ 176(CX), R12 MOVQ R12, 80(SP) MOVQ 184(CX), CX MOVQ CX, 72(SP) MOVQ 72(SP), CX ADDQ CX, 80(SP) // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) ADDQ R9, 64(SP) // outBase += outPosition ADDQ R11, R9 sequenceDecs_decodeSync_safe_bmi2_main_loop: MOVQ (SP), R12 // Fill bitreader to have enough for the offset and match length. CMPQ BX, $0x08 JL sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte MOVQ DX, CX SHRQ $0x03, CX SUBQ CX, R12 MOVQ (R12), AX SUBQ CX, BX ANDQ $0x07, DX JMP sequenceDecs_decodeSync_safe_bmi2_fill_end sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte: CMPQ BX, $0x00 JLE sequenceDecs_decodeSync_safe_bmi2_fill_check_overread CMPQ DX, $0x07 JLE sequenceDecs_decodeSync_safe_bmi2_fill_end SHLQ $0x08, AX SUBQ $0x01, R12 SUBQ $0x01, BX SUBQ $0x08, DX MOVBQZX (R12), CX ORQ CX, AX JMP sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte sequenceDecs_decodeSync_safe_bmi2_fill_check_overread: CMPQ DX, $0x40 JA error_overread sequenceDecs_decodeSync_safe_bmi2_fill_end: // Update offset MOVQ $0x00000808, CX BEXTRQ CX, R8, R13 MOVQ AX, R14 LEAQ (DX)(R13*1), CX ROLQ CL, R14 BZHIQ R13, R14, R14 MOVQ CX, DX MOVQ R8, CX SHRQ $0x20, CX ADDQ R14, CX MOVQ CX, 40(SP) // Update match length MOVQ $0x00000808, CX BEXTRQ CX, DI, R13 MOVQ AX, R14 LEAQ (DX)(R13*1), CX ROLQ CL, R14 BZHIQ R13, R14, R14 MOVQ CX, DX MOVQ DI, CX SHRQ $0x20, CX ADDQ R14, CX MOVQ CX, 48(SP) // Fill bitreader to have enough for the remaining CMPQ BX, $0x08 JL sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte MOVQ DX, CX SHRQ $0x03, CX SUBQ CX, R12 MOVQ (R12), AX SUBQ CX, BX ANDQ $0x07, DX JMP sequenceDecs_decodeSync_safe_bmi2_fill_2_end sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte: CMPQ BX, $0x00 JLE sequenceDecs_decodeSync_safe_bmi2_fill_2_check_overread CMPQ DX, $0x07 JLE sequenceDecs_decodeSync_safe_bmi2_fill_2_end SHLQ $0x08, AX SUBQ $0x01, R12 SUBQ $0x01, BX SUBQ $0x08, DX MOVBQZX (R12), CX ORQ CX, AX JMP sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte sequenceDecs_decodeSync_safe_bmi2_fill_2_check_overread: CMPQ DX, $0x40 JA error_overread sequenceDecs_decodeSync_safe_bmi2_fill_2_end: // Update literal length MOVQ $0x00000808, CX BEXTRQ CX, SI, R13 MOVQ AX, R14 LEAQ (DX)(R13*1), CX ROLQ CL, R14 BZHIQ R13, R14, R14 MOVQ CX, DX MOVQ SI, CX SHRQ $0x20, CX ADDQ R14, CX MOVQ CX, 56(SP) // Fill bitreader for state updates MOVQ R12, (SP) MOVQ $0x00000808, CX BEXTRQ CX, R8, R12 CMPQ 32(SP), $0x00 JZ sequenceDecs_decodeSync_safe_bmi2_skip_update LEAQ (SI)(DI*1), R13 ADDQ R8, R13 MOVBQZX R13, R13 LEAQ (DX)(R13*1), CX MOVQ AX, R14 MOVQ CX, DX ROLQ CL, R14 BZHIQ R13, R14, R14 // Update Offset State BZHIQ R8, R14, CX SHRXQ R8, R14, R14 SHRL $0x10, R8 ADDQ CX, R8 // Load ctx.ofTable MOVQ 24(SP), CX MOVQ (CX)(R8*8), R8 // Update Match Length State BZHIQ DI, R14, CX SHRXQ DI, R14, R14 SHRL $0x10, DI ADDQ CX, DI // Load ctx.mlTable MOVQ 16(SP), CX MOVQ (CX)(DI*8), DI // Update Literal Length State BZHIQ SI, R14, CX SHRL $0x10, SI ADDQ CX, SI // Load ctx.llTable MOVQ 8(SP), CX MOVQ (CX)(SI*8), SI sequenceDecs_decodeSync_safe_bmi2_skip_update: // Adjust offset MOVQ s+0(FP), CX MOVQ 40(SP), R13 CMPQ R12, $0x01 JBE sequenceDecs_decodeSync_safe_bmi2_adjust_offsetB_1_or_0 MOVUPS 144(CX), X0 MOVQ R13, 144(CX) MOVUPS X0, 152(CX) JMP sequenceDecs_decodeSync_safe_bmi2_after_adjust sequenceDecs_decodeSync_safe_bmi2_adjust_offsetB_1_or_0: CMPQ 56(SP), $0x00000000 JNE sequenceDecs_decodeSync_safe_bmi2_adjust_offset_maybezero INCQ R13 JMP sequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero sequenceDecs_decodeSync_safe_bmi2_adjust_offset_maybezero: TESTQ R13, R13 JNZ sequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero MOVQ 144(CX), R13 JMP sequenceDecs_decodeSync_safe_bmi2_after_adjust sequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero: MOVQ R13, R12 XORQ R14, R14 MOVQ $-1, R15 CMPQ R13, $0x03 CMOVQEQ R14, R12 CMOVQEQ R15, R14 ADDQ 144(CX)(R12*8), R14 JNZ sequenceDecs_decodeSync_safe_bmi2_adjust_temp_valid MOVQ $0x00000001, R14 sequenceDecs_decodeSync_safe_bmi2_adjust_temp_valid: CMPQ R13, $0x01 JZ sequenceDecs_decodeSync_safe_bmi2_adjust_skip MOVQ 152(CX), R12 MOVQ R12, 160(CX) sequenceDecs_decodeSync_safe_bmi2_adjust_skip: MOVQ 144(CX), R12 MOVQ R12, 152(CX) MOVQ R14, 144(CX) MOVQ R14, R13 sequenceDecs_decodeSync_safe_bmi2_after_adjust: MOVQ R13, 40(SP) // Check values MOVQ 48(SP), CX MOVQ 56(SP), R12 MOVQ ctx+16(FP), R14 SUBQ R12, 104(R14) JS error_not_enough_literals CMPQ CX, $0x00020002 JA sequenceDecs_decodeSync_safe_bmi2_error_match_len_too_big TESTQ R13, R13 JNZ sequenceDecs_decodeSync_safe_bmi2_match_len_ofs_ok TESTQ CX, CX JNZ sequenceDecs_decodeSync_safe_bmi2_error_match_len_ofs_mismatch sequenceDecs_decodeSync_safe_bmi2_match_len_ofs_ok: // Check if we have enough space in s.out LEAQ (R12)(CX*1), R14 ADDQ R9, R14 CMPQ R14, 64(SP) JA error_not_enough_space // Copy literals TESTQ R12, R12 JZ check_offset MOVQ R12, R14 SUBQ $0x10, R14 JB copy_1_small copy_1_loop: MOVUPS (R10), X0 MOVUPS X0, (R9) ADDQ $0x10, R10 ADDQ $0x10, R9 SUBQ $0x10, R14 JAE copy_1_loop LEAQ 16(R10)(R14*1), R10 LEAQ 16(R9)(R14*1), R9 MOVUPS -16(R10), X0 MOVUPS X0, -16(R9) JMP copy_1_end copy_1_small: CMPQ R12, $0x03 JE copy_1_move_3 JB copy_1_move_1or2 CMPQ R12, $0x08 JB copy_1_move_4through7 JMP copy_1_move_8through16 copy_1_move_1or2: MOVB (R10), R14 MOVB -1(R10)(R12*1), R15 MOVB R14, (R9) MOVB R15, -1(R9)(R12*1) ADDQ R12, R10 ADDQ R12, R9 JMP copy_1_end copy_1_move_3: MOVWQZX (R10), R14 MOVB 2(R10), R15 MOVW R14, (R9) MOVB R15, 2(R9) ADDQ R12, R10 ADDQ R12, R9 JMP copy_1_end copy_1_move_4through7: MOVL (R10), R14 MOVL -4(R10)(R12*1), R15 MOVL R14, (R9) MOVL R15, -4(R9)(R12*1) ADDQ R12, R10 ADDQ R12, R9 JMP copy_1_end copy_1_move_8through16: MOVQ (R10), R14 MOVQ -8(R10)(R12*1), R15 MOVQ R14, (R9) MOVQ R15, -8(R9)(R12*1) ADDQ R12, R10 ADDQ R12, R9 copy_1_end: ADDQ R12, R11 // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) check_offset: MOVQ R11, R12 ADDQ 72(SP), R12 CMPQ R13, R12 JG error_match_off_too_big CMPQ R13, 88(SP) JG error_match_off_too_big // Copy match from history MOVQ R13, R12 SUBQ R11, R12 JLS copy_match MOVQ 80(SP), R14 SUBQ R12, R14 CMPQ CX, R12 JG copy_all_from_history MOVQ CX, R12 SUBQ $0x10, R12 JB copy_4_small copy_4_loop: MOVUPS (R14), X0 MOVUPS X0, (R9) ADDQ $0x10, R14 ADDQ $0x10, R9 SUBQ $0x10, R12 JAE copy_4_loop LEAQ 16(R14)(R12*1), R14 LEAQ 16(R9)(R12*1), R9 MOVUPS -16(R14), X0 MOVUPS X0, -16(R9) JMP copy_4_end copy_4_small: CMPQ CX, $0x03 JE copy_4_move_3 CMPQ CX, $0x08 JB copy_4_move_4through7 JMP copy_4_move_8through16 copy_4_move_3: MOVWQZX (R14), R12 MOVB 2(R14), R13 MOVW R12, (R9) MOVB R13, 2(R9) ADDQ CX, R14 ADDQ CX, R9 JMP copy_4_end copy_4_move_4through7: MOVL (R14), R12 MOVL -4(R14)(CX*1), R13 MOVL R12, (R9) MOVL R13, -4(R9)(CX*1) ADDQ CX, R14 ADDQ CX, R9 JMP copy_4_end copy_4_move_8through16: MOVQ (R14), R12 MOVQ -8(R14)(CX*1), R13 MOVQ R12, (R9) MOVQ R13, -8(R9)(CX*1) ADDQ CX, R14 ADDQ CX, R9 copy_4_end: ADDQ CX, R11 JMP handle_loop JMP loop_finished copy_all_from_history: MOVQ R12, R15 SUBQ $0x10, R15 JB copy_5_small copy_5_loop: MOVUPS (R14), X0 MOVUPS X0, (R9) ADDQ $0x10, R14 ADDQ $0x10, R9 SUBQ $0x10, R15 JAE copy_5_loop LEAQ 16(R14)(R15*1), R14 LEAQ 16(R9)(R15*1), R9 MOVUPS -16(R14), X0 MOVUPS X0, -16(R9) JMP copy_5_end copy_5_small: CMPQ R12, $0x03 JE copy_5_move_3 JB copy_5_move_1or2 CMPQ R12, $0x08 JB copy_5_move_4through7 JMP copy_5_move_8through16 copy_5_move_1or2: MOVB (R14), R15 MOVB -1(R14)(R12*1), BP MOVB R15, (R9) MOVB BP, -1(R9)(R12*1) ADDQ R12, R14 ADDQ R12, R9 JMP copy_5_end copy_5_move_3: MOVWQZX (R14), R15 MOVB 2(R14), BP MOVW R15, (R9) MOVB BP, 2(R9) ADDQ R12, R14 ADDQ R12, R9 JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 MOVL -4(R14)(R12*1), BP MOVL R15, (R9) MOVL BP, -4(R9)(R12*1) ADDQ R12, R14 ADDQ R12, R9 JMP copy_5_end copy_5_move_8through16: MOVQ (R14), R15 MOVQ -8(R14)(R12*1), BP MOVQ R15, (R9) MOVQ BP, -8(R9)(R12*1) ADDQ R12, R14 ADDQ R12, R9 copy_5_end: ADDQ R12, R11 SUBQ R12, CX // Copy match from the current buffer copy_match: MOVQ R9, R12 SUBQ R13, R12 // ml <= mo CMPQ CX, R13 JA copy_overlapping_match // Copy non-overlapping match ADDQ CX, R11 MOVQ CX, R13 SUBQ $0x10, R13 JB copy_2_small copy_2_loop: MOVUPS (R12), X0 MOVUPS X0, (R9) ADDQ $0x10, R12 ADDQ $0x10, R9 SUBQ $0x10, R13 JAE copy_2_loop LEAQ 16(R12)(R13*1), R12 LEAQ 16(R9)(R13*1), R9 MOVUPS -16(R12), X0 MOVUPS X0, -16(R9) JMP copy_2_end copy_2_small: CMPQ CX, $0x03 JE copy_2_move_3 JB copy_2_move_1or2 CMPQ CX, $0x08 JB copy_2_move_4through7 JMP copy_2_move_8through16 copy_2_move_1or2: MOVB (R12), R13 MOVB -1(R12)(CX*1), R14 MOVB R13, (R9) MOVB R14, -1(R9)(CX*1) ADDQ CX, R12 ADDQ CX, R9 JMP copy_2_end copy_2_move_3: MOVWQZX (R12), R13 MOVB 2(R12), R14 MOVW R13, (R9) MOVB R14, 2(R9) ADDQ CX, R12 ADDQ CX, R9 JMP copy_2_end copy_2_move_4through7: MOVL (R12), R13 MOVL -4(R12)(CX*1), R14 MOVL R13, (R9) MOVL R14, -4(R9)(CX*1) ADDQ CX, R12 ADDQ CX, R9 JMP copy_2_end copy_2_move_8through16: MOVQ (R12), R13 MOVQ -8(R12)(CX*1), R14 MOVQ R13, (R9) MOVQ R14, -8(R9)(CX*1) ADDQ CX, R12 ADDQ CX, R9 copy_2_end: JMP handle_loop // Copy overlapping match copy_overlapping_match: ADDQ CX, R11 copy_slow_3: MOVBQZX (R12), R13 MOVB R13, (R9) INCQ R12 INCQ R9 DECQ CX JNZ copy_slow_3 handle_loop: DECQ 32(SP) JNS sequenceDecs_decodeSync_safe_bmi2_main_loop loop_finished: MOVQ br+8(FP), CX MOVQ AX, 24(CX) MOVB DL, 40(CX) MOVQ BX, 32(CX) // s.seqSize += outPosition - ctx.outPosition MOVQ ctx+16(FP), AX MOVQ s+0(FP), CX MOVQ R11, DX SUBQ 136(AX), DX ADDQ DX, 256(CX) // Update the context MOVQ ctx+16(FP), AX MOVQ R11, 136(AX) MOVQ 144(AX), CX SUBQ CX, R10 MOVQ R10, 168(AX) // Return success MOVQ $0x00000000, ret+24(FP) RET // Return with match length error sequenceDecs_decodeSync_safe_bmi2_error_match_len_ofs_mismatch: MOVQ 48(SP), AX MOVQ ctx+16(FP), CX MOVQ AX, 216(CX) MOVQ $0x00000001, ret+24(FP) RET // Return with match too long error sequenceDecs_decodeSync_safe_bmi2_error_match_len_too_big: MOVQ ctx+16(FP), AX MOVQ 48(SP), CX MOVQ CX, 216(AX) MOVQ $0x00000002, ret+24(FP) RET // Return with match offset too long error error_match_off_too_big: MOVQ ctx+16(FP), AX MOVQ 40(SP), CX MOVQ CX, 224(AX) MOVQ R11, 136(AX) MOVQ $0x00000003, ret+24(FP) RET // Return with not enough literals error error_not_enough_literals: MOVQ ctx+16(FP), AX MOVQ 56(SP), CX MOVQ CX, 208(AX) MOVQ $0x00000004, ret+24(FP) RET // Return with overread error error_overread: MOVQ $0x00000006, ret+24(FP) RET // Return with not enough output space error error_not_enough_space: MOVQ ctx+16(FP), AX MOVQ 56(SP), CX MOVQ CX, 208(AX) MOVQ 48(SP), CX MOVQ CX, 216(AX) MOVQ R11, 136(AX) MOVQ $0x00000005, ret+24(FP) RET