parent
d927801c06
commit
b54c0bebdb
@ -1,5 +0,0 @@
|
|||||||
package huff0
|
|
||||||
|
|
||||||
//go:generate go run generate.go
|
|
||||||
//go:generate asmfmt -w decompress_amd64.s
|
|
||||||
//go:generate asmfmt -w decompress_8b_amd64.s
|
|
@ -1,488 +0,0 @@
|
|||||||
// +build !appengine
|
|
||||||
// +build gc
|
|
||||||
// +build !noasm
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
#include "funcdata.h"
|
|
||||||
#include "go_asm.h"
|
|
||||||
|
|
||||||
#define bufoff 256 // see decompress.go, we're using [4][256]byte table
|
|
||||||
|
|
||||||
// func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted,
|
|
||||||
// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool)
|
|
||||||
TEXT ·decompress4x_8b_loop_x86(SB), NOSPLIT, $8
|
|
||||||
#define off R8
|
|
||||||
#define buffer DI
|
|
||||||
#define table SI
|
|
||||||
|
|
||||||
#define br_bits_read R9
|
|
||||||
#define br_value R10
|
|
||||||
#define br_offset R11
|
|
||||||
#define peek_bits R12
|
|
||||||
#define exhausted DX
|
|
||||||
|
|
||||||
#define br0 R13
|
|
||||||
#define br1 R14
|
|
||||||
#define br2 R15
|
|
||||||
#define br3 BP
|
|
||||||
|
|
||||||
MOVQ BP, 0(SP)
|
|
||||||
|
|
||||||
XORQ exhausted, exhausted // exhausted = false
|
|
||||||
XORQ off, off // off = 0
|
|
||||||
|
|
||||||
MOVBQZX peekBits+32(FP), peek_bits
|
|
||||||
MOVQ buf+40(FP), buffer
|
|
||||||
MOVQ tbl+48(FP), table
|
|
||||||
|
|
||||||
MOVQ pbr0+0(FP), br0
|
|
||||||
MOVQ pbr1+8(FP), br1
|
|
||||||
MOVQ pbr2+16(FP), br2
|
|
||||||
MOVQ pbr3+24(FP), br3
|
|
||||||
|
|
||||||
main_loop:
|
|
||||||
|
|
||||||
// const stream = 0
|
|
||||||
// br0.fillFast()
|
|
||||||
MOVBQZX bitReaderShifted_bitsRead(br0), br_bits_read
|
|
||||||
MOVQ bitReaderShifted_value(br0), br_value
|
|
||||||
MOVQ bitReaderShifted_off(br0), br_offset
|
|
||||||
|
|
||||||
// if b.bitsRead >= 32 {
|
|
||||||
CMPQ br_bits_read, $32
|
|
||||||
JB skip_fill0
|
|
||||||
|
|
||||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
|
||||||
SUBQ $4, br_offset // b.off -= 4
|
|
||||||
|
|
||||||
// v := b.in[b.off-4 : b.off]
|
|
||||||
// v = v[:4]
|
|
||||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
|
||||||
MOVQ bitReaderShifted_in(br0), AX
|
|
||||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
|
||||||
|
|
||||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
|
||||||
MOVQ br_bits_read, CX
|
|
||||||
SHLQ CL, AX
|
|
||||||
ORQ AX, br_value
|
|
||||||
|
|
||||||
// exhausted = exhausted || (br0.off < 4)
|
|
||||||
CMPQ br_offset, $4
|
|
||||||
SETLT DL
|
|
||||||
ORB DL, DH
|
|
||||||
|
|
||||||
// }
|
|
||||||
skip_fill0:
|
|
||||||
|
|
||||||
// val0 := br0.peekTopBits(peekBits)
|
|
||||||
MOVQ br_value, AX
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v0 := table[val0&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v0
|
|
||||||
|
|
||||||
// br0.advance(uint8(v0.entry))
|
|
||||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// val1 := br0.peekTopBits(peekBits)
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
MOVQ br_value, AX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v1 := table[val1&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v1
|
|
||||||
|
|
||||||
// br0.advance(uint8(v1.entry))
|
|
||||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CX, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// these two writes get coalesced
|
|
||||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
|
||||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
|
||||||
MOVW BX, 0(buffer)(off*1)
|
|
||||||
|
|
||||||
// SECOND PART:
|
|
||||||
// val2 := br0.peekTopBits(peekBits)
|
|
||||||
MOVQ br_value, AX
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v2 := table[val0&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v0
|
|
||||||
|
|
||||||
// br0.advance(uint8(v0.entry))
|
|
||||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// val3 := br0.peekTopBits(peekBits)
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
MOVQ br_value, AX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v3 := table[val1&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v1
|
|
||||||
|
|
||||||
// br0.advance(uint8(v1.entry))
|
|
||||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CX, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// these two writes get coalesced
|
|
||||||
// buf[stream][off+2] = uint8(v2.entry >> 8)
|
|
||||||
// buf[stream][off+3] = uint8(v3.entry >> 8)
|
|
||||||
MOVW BX, 0+2(buffer)(off*1)
|
|
||||||
|
|
||||||
// update the bitrader reader structure
|
|
||||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br0)
|
|
||||||
MOVQ br_value, bitReaderShifted_value(br0)
|
|
||||||
MOVQ br_offset, bitReaderShifted_off(br0)
|
|
||||||
|
|
||||||
// const stream = 1
|
|
||||||
// br1.fillFast()
|
|
||||||
MOVBQZX bitReaderShifted_bitsRead(br1), br_bits_read
|
|
||||||
MOVQ bitReaderShifted_value(br1), br_value
|
|
||||||
MOVQ bitReaderShifted_off(br1), br_offset
|
|
||||||
|
|
||||||
// if b.bitsRead >= 32 {
|
|
||||||
CMPQ br_bits_read, $32
|
|
||||||
JB skip_fill1
|
|
||||||
|
|
||||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
|
||||||
SUBQ $4, br_offset // b.off -= 4
|
|
||||||
|
|
||||||
// v := b.in[b.off-4 : b.off]
|
|
||||||
// v = v[:4]
|
|
||||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
|
||||||
MOVQ bitReaderShifted_in(br1), AX
|
|
||||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
|
||||||
|
|
||||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
|
||||||
MOVQ br_bits_read, CX
|
|
||||||
SHLQ CL, AX
|
|
||||||
ORQ AX, br_value
|
|
||||||
|
|
||||||
// exhausted = exhausted || (br1.off < 4)
|
|
||||||
CMPQ br_offset, $4
|
|
||||||
SETLT DL
|
|
||||||
ORB DL, DH
|
|
||||||
|
|
||||||
// }
|
|
||||||
skip_fill1:
|
|
||||||
|
|
||||||
// val0 := br1.peekTopBits(peekBits)
|
|
||||||
MOVQ br_value, AX
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v0 := table[val0&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v0
|
|
||||||
|
|
||||||
// br1.advance(uint8(v0.entry))
|
|
||||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// val1 := br1.peekTopBits(peekBits)
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
MOVQ br_value, AX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v1 := table[val1&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v1
|
|
||||||
|
|
||||||
// br1.advance(uint8(v1.entry))
|
|
||||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CX, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// these two writes get coalesced
|
|
||||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
|
||||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
|
||||||
MOVW BX, 256(buffer)(off*1)
|
|
||||||
|
|
||||||
// SECOND PART:
|
|
||||||
// val2 := br1.peekTopBits(peekBits)
|
|
||||||
MOVQ br_value, AX
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v2 := table[val0&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v0
|
|
||||||
|
|
||||||
// br1.advance(uint8(v0.entry))
|
|
||||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// val3 := br1.peekTopBits(peekBits)
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
MOVQ br_value, AX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v3 := table[val1&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v1
|
|
||||||
|
|
||||||
// br1.advance(uint8(v1.entry))
|
|
||||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CX, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// these two writes get coalesced
|
|
||||||
// buf[stream][off+2] = uint8(v2.entry >> 8)
|
|
||||||
// buf[stream][off+3] = uint8(v3.entry >> 8)
|
|
||||||
MOVW BX, 256+2(buffer)(off*1)
|
|
||||||
|
|
||||||
// update the bitrader reader structure
|
|
||||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br1)
|
|
||||||
MOVQ br_value, bitReaderShifted_value(br1)
|
|
||||||
MOVQ br_offset, bitReaderShifted_off(br1)
|
|
||||||
|
|
||||||
// const stream = 2
|
|
||||||
// br2.fillFast()
|
|
||||||
MOVBQZX bitReaderShifted_bitsRead(br2), br_bits_read
|
|
||||||
MOVQ bitReaderShifted_value(br2), br_value
|
|
||||||
MOVQ bitReaderShifted_off(br2), br_offset
|
|
||||||
|
|
||||||
// if b.bitsRead >= 32 {
|
|
||||||
CMPQ br_bits_read, $32
|
|
||||||
JB skip_fill2
|
|
||||||
|
|
||||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
|
||||||
SUBQ $4, br_offset // b.off -= 4
|
|
||||||
|
|
||||||
// v := b.in[b.off-4 : b.off]
|
|
||||||
// v = v[:4]
|
|
||||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
|
||||||
MOVQ bitReaderShifted_in(br2), AX
|
|
||||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
|
||||||
|
|
||||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
|
||||||
MOVQ br_bits_read, CX
|
|
||||||
SHLQ CL, AX
|
|
||||||
ORQ AX, br_value
|
|
||||||
|
|
||||||
// exhausted = exhausted || (br2.off < 4)
|
|
||||||
CMPQ br_offset, $4
|
|
||||||
SETLT DL
|
|
||||||
ORB DL, DH
|
|
||||||
|
|
||||||
// }
|
|
||||||
skip_fill2:
|
|
||||||
|
|
||||||
// val0 := br2.peekTopBits(peekBits)
|
|
||||||
MOVQ br_value, AX
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v0 := table[val0&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v0
|
|
||||||
|
|
||||||
// br2.advance(uint8(v0.entry))
|
|
||||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// val1 := br2.peekTopBits(peekBits)
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
MOVQ br_value, AX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v1 := table[val1&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v1
|
|
||||||
|
|
||||||
// br2.advance(uint8(v1.entry))
|
|
||||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CX, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// these two writes get coalesced
|
|
||||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
|
||||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
|
||||||
MOVW BX, 512(buffer)(off*1)
|
|
||||||
|
|
||||||
// SECOND PART:
|
|
||||||
// val2 := br2.peekTopBits(peekBits)
|
|
||||||
MOVQ br_value, AX
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v2 := table[val0&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v0
|
|
||||||
|
|
||||||
// br2.advance(uint8(v0.entry))
|
|
||||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// val3 := br2.peekTopBits(peekBits)
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
MOVQ br_value, AX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v3 := table[val1&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v1
|
|
||||||
|
|
||||||
// br2.advance(uint8(v1.entry))
|
|
||||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CX, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// these two writes get coalesced
|
|
||||||
// buf[stream][off+2] = uint8(v2.entry >> 8)
|
|
||||||
// buf[stream][off+3] = uint8(v3.entry >> 8)
|
|
||||||
MOVW BX, 512+2(buffer)(off*1)
|
|
||||||
|
|
||||||
// update the bitrader reader structure
|
|
||||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br2)
|
|
||||||
MOVQ br_value, bitReaderShifted_value(br2)
|
|
||||||
MOVQ br_offset, bitReaderShifted_off(br2)
|
|
||||||
|
|
||||||
// const stream = 3
|
|
||||||
// br3.fillFast()
|
|
||||||
MOVBQZX bitReaderShifted_bitsRead(br3), br_bits_read
|
|
||||||
MOVQ bitReaderShifted_value(br3), br_value
|
|
||||||
MOVQ bitReaderShifted_off(br3), br_offset
|
|
||||||
|
|
||||||
// if b.bitsRead >= 32 {
|
|
||||||
CMPQ br_bits_read, $32
|
|
||||||
JB skip_fill3
|
|
||||||
|
|
||||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
|
||||||
SUBQ $4, br_offset // b.off -= 4
|
|
||||||
|
|
||||||
// v := b.in[b.off-4 : b.off]
|
|
||||||
// v = v[:4]
|
|
||||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
|
||||||
MOVQ bitReaderShifted_in(br3), AX
|
|
||||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
|
||||||
|
|
||||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
|
||||||
MOVQ br_bits_read, CX
|
|
||||||
SHLQ CL, AX
|
|
||||||
ORQ AX, br_value
|
|
||||||
|
|
||||||
// exhausted = exhausted || (br3.off < 4)
|
|
||||||
CMPQ br_offset, $4
|
|
||||||
SETLT DL
|
|
||||||
ORB DL, DH
|
|
||||||
|
|
||||||
// }
|
|
||||||
skip_fill3:
|
|
||||||
|
|
||||||
// val0 := br3.peekTopBits(peekBits)
|
|
||||||
MOVQ br_value, AX
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v0 := table[val0&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v0
|
|
||||||
|
|
||||||
// br3.advance(uint8(v0.entry))
|
|
||||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// val1 := br3.peekTopBits(peekBits)
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
MOVQ br_value, AX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v1 := table[val1&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v1
|
|
||||||
|
|
||||||
// br3.advance(uint8(v1.entry))
|
|
||||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CX, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// these two writes get coalesced
|
|
||||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
|
||||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
|
||||||
MOVW BX, 768(buffer)(off*1)
|
|
||||||
|
|
||||||
// SECOND PART:
|
|
||||||
// val2 := br3.peekTopBits(peekBits)
|
|
||||||
MOVQ br_value, AX
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v2 := table[val0&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v0
|
|
||||||
|
|
||||||
// br3.advance(uint8(v0.entry))
|
|
||||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// val3 := br3.peekTopBits(peekBits)
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
MOVQ br_value, AX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v3 := table[val1&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v1
|
|
||||||
|
|
||||||
// br3.advance(uint8(v1.entry))
|
|
||||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CX, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// these two writes get coalesced
|
|
||||||
// buf[stream][off+2] = uint8(v2.entry >> 8)
|
|
||||||
// buf[stream][off+3] = uint8(v3.entry >> 8)
|
|
||||||
MOVW BX, 768+2(buffer)(off*1)
|
|
||||||
|
|
||||||
// update the bitrader reader structure
|
|
||||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br3)
|
|
||||||
MOVQ br_value, bitReaderShifted_value(br3)
|
|
||||||
MOVQ br_offset, bitReaderShifted_off(br3)
|
|
||||||
|
|
||||||
ADDQ $4, off // off += 2
|
|
||||||
|
|
||||||
TESTB DH, DH // any br[i].ofs < 4?
|
|
||||||
JNZ end
|
|
||||||
|
|
||||||
CMPQ off, $bufoff
|
|
||||||
JL main_loop
|
|
||||||
|
|
||||||
end:
|
|
||||||
MOVQ 0(SP), BP
|
|
||||||
|
|
||||||
MOVB off, ret+56(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
#undef off
|
|
||||||
#undef buffer
|
|
||||||
#undef table
|
|
||||||
|
|
||||||
#undef br_bits_read
|
|
||||||
#undef br_value
|
|
||||||
#undef br_offset
|
|
||||||
#undef peek_bits
|
|
||||||
#undef exhausted
|
|
||||||
|
|
||||||
#undef br0
|
|
||||||
#undef br1
|
|
||||||
#undef br2
|
|
||||||
#undef br3
|
|
@ -1,197 +0,0 @@
|
|||||||
// +build !appengine
|
|
||||||
// +build gc
|
|
||||||
// +build !noasm
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
#include "funcdata.h"
|
|
||||||
#include "go_asm.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define bufoff 256 // see decompress.go, we're using [4][256]byte table
|
|
||||||
|
|
||||||
//func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted,
|
|
||||||
// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool)
|
|
||||||
TEXT ·decompress4x_8b_loop_x86(SB), NOSPLIT, $8
|
|
||||||
#define off R8
|
|
||||||
#define buffer DI
|
|
||||||
#define table SI
|
|
||||||
|
|
||||||
#define br_bits_read R9
|
|
||||||
#define br_value R10
|
|
||||||
#define br_offset R11
|
|
||||||
#define peek_bits R12
|
|
||||||
#define exhausted DX
|
|
||||||
|
|
||||||
#define br0 R13
|
|
||||||
#define br1 R14
|
|
||||||
#define br2 R15
|
|
||||||
#define br3 BP
|
|
||||||
|
|
||||||
MOVQ BP, 0(SP)
|
|
||||||
|
|
||||||
XORQ exhausted, exhausted // exhausted = false
|
|
||||||
XORQ off, off // off = 0
|
|
||||||
|
|
||||||
MOVBQZX peekBits+32(FP), peek_bits
|
|
||||||
MOVQ buf+40(FP), buffer
|
|
||||||
MOVQ tbl+48(FP), table
|
|
||||||
|
|
||||||
MOVQ pbr0+0(FP), br0
|
|
||||||
MOVQ pbr1+8(FP), br1
|
|
||||||
MOVQ pbr2+16(FP), br2
|
|
||||||
MOVQ pbr3+24(FP), br3
|
|
||||||
|
|
||||||
main_loop:
|
|
||||||
{{ define "decode_2_values_x86" }}
|
|
||||||
// const stream = {{ var "id" }}
|
|
||||||
// br{{ var "id"}}.fillFast()
|
|
||||||
MOVBQZX bitReaderShifted_bitsRead(br{{ var "id" }}), br_bits_read
|
|
||||||
MOVQ bitReaderShifted_value(br{{ var "id" }}), br_value
|
|
||||||
MOVQ bitReaderShifted_off(br{{ var "id" }}), br_offset
|
|
||||||
|
|
||||||
// if b.bitsRead >= 32 {
|
|
||||||
CMPQ br_bits_read, $32
|
|
||||||
JB skip_fill{{ var "id" }}
|
|
||||||
|
|
||||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
|
||||||
SUBQ $4, br_offset // b.off -= 4
|
|
||||||
|
|
||||||
// v := b.in[b.off-4 : b.off]
|
|
||||||
// v = v[:4]
|
|
||||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
|
||||||
MOVQ bitReaderShifted_in(br{{ var "id" }}), AX
|
|
||||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
|
||||||
|
|
||||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
|
||||||
MOVQ br_bits_read, CX
|
|
||||||
SHLQ CL, AX
|
|
||||||
ORQ AX, br_value
|
|
||||||
|
|
||||||
// exhausted = exhausted || (br{{ var "id"}}.off < 4)
|
|
||||||
CMPQ br_offset, $4
|
|
||||||
SETLT DL
|
|
||||||
ORB DL, DH
|
|
||||||
// }
|
|
||||||
skip_fill{{ var "id" }}:
|
|
||||||
|
|
||||||
// val0 := br{{ var "id"}}.peekTopBits(peekBits)
|
|
||||||
MOVQ br_value, AX
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v0 := table[val0&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v0
|
|
||||||
|
|
||||||
// br{{ var "id"}}.advance(uint8(v0.entry))
|
|
||||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// val1 := br{{ var "id"}}.peekTopBits(peekBits)
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
MOVQ br_value, AX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v1 := table[val1&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v1
|
|
||||||
|
|
||||||
// br{{ var "id"}}.advance(uint8(v1.entry))
|
|
||||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CX, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
|
|
||||||
// these two writes get coalesced
|
|
||||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
|
||||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
|
||||||
MOVW BX, {{ var "bufofs" }}(buffer)(off*1)
|
|
||||||
|
|
||||||
// SECOND PART:
|
|
||||||
// val2 := br{{ var "id"}}.peekTopBits(peekBits)
|
|
||||||
MOVQ br_value, AX
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v2 := table[val0&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v0
|
|
||||||
|
|
||||||
// br{{ var "id"}}.advance(uint8(v0.entry))
|
|
||||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
// val3 := br{{ var "id"}}.peekTopBits(peekBits)
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
MOVQ br_value, AX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
|
|
||||||
// v3 := table[val1&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v1
|
|
||||||
|
|
||||||
// br{{ var "id"}}.advance(uint8(v1.entry))
|
|
||||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CX, br_value // value <<= n
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
|
|
||||||
// these two writes get coalesced
|
|
||||||
// buf[stream][off+2] = uint8(v2.entry >> 8)
|
|
||||||
// buf[stream][off+3] = uint8(v3.entry >> 8)
|
|
||||||
MOVW BX, {{ var "bufofs" }}+2(buffer)(off*1)
|
|
||||||
|
|
||||||
// update the bitrader reader structure
|
|
||||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br{{ var "id" }})
|
|
||||||
MOVQ br_value, bitReaderShifted_value(br{{ var "id" }})
|
|
||||||
MOVQ br_offset, bitReaderShifted_off(br{{ var "id" }})
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ set "id" "0" }}
|
|
||||||
{{ set "ofs" "0" }}
|
|
||||||
{{ set "bufofs" "0" }} {{/* id * bufoff */}}
|
|
||||||
{{ template "decode_2_values_x86" . }}
|
|
||||||
|
|
||||||
{{ set "id" "1" }}
|
|
||||||
{{ set "ofs" "8" }}
|
|
||||||
{{ set "bufofs" "256" }}
|
|
||||||
{{ template "decode_2_values_x86" . }}
|
|
||||||
|
|
||||||
{{ set "id" "2" }}
|
|
||||||
{{ set "ofs" "16" }}
|
|
||||||
{{ set "bufofs" "512" }}
|
|
||||||
{{ template "decode_2_values_x86" . }}
|
|
||||||
|
|
||||||
{{ set "id" "3" }}
|
|
||||||
{{ set "ofs" "24" }}
|
|
||||||
{{ set "bufofs" "768" }}
|
|
||||||
{{ template "decode_2_values_x86" . }}
|
|
||||||
|
|
||||||
ADDQ $4, off // off += 2
|
|
||||||
|
|
||||||
TESTB DH, DH // any br[i].ofs < 4?
|
|
||||||
JNZ end
|
|
||||||
|
|
||||||
CMPQ off, $bufoff
|
|
||||||
JL main_loop
|
|
||||||
end:
|
|
||||||
MOVQ 0(SP), BP
|
|
||||||
|
|
||||||
MOVB off, ret+56(FP)
|
|
||||||
RET
|
|
||||||
#undef off
|
|
||||||
#undef buffer
|
|
||||||
#undef table
|
|
||||||
|
|
||||||
#undef br_bits_read
|
|
||||||
#undef br_value
|
|
||||||
#undef br_offset
|
|
||||||
#undef peek_bits
|
|
||||||
#undef exhausted
|
|
||||||
|
|
||||||
#undef br0
|
|
||||||
#undef br1
|
|
||||||
#undef br2
|
|
||||||
#undef br3
|
|
File diff suppressed because it is too large
Load Diff
@ -1,195 +0,0 @@
|
|||||||
// +build !appengine
|
|
||||||
// +build gc
|
|
||||||
// +build !noasm
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
#include "funcdata.h"
|
|
||||||
#include "go_asm.h"
|
|
||||||
|
|
||||||
#ifdef GOAMD64_v4
|
|
||||||
#ifndef GOAMD64_v3
|
|
||||||
#define GOAMD64_v3
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define bufoff 256 // see decompress.go, we're using [4][256]byte table
|
|
||||||
|
|
||||||
//func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted,
|
|
||||||
// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool)
|
|
||||||
TEXT ·decompress4x_main_loop_x86(SB), NOSPLIT, $8
|
|
||||||
#define off R8
|
|
||||||
#define buffer DI
|
|
||||||
#define table SI
|
|
||||||
|
|
||||||
#define br_bits_read R9
|
|
||||||
#define br_value R10
|
|
||||||
#define br_offset R11
|
|
||||||
#define peek_bits R12
|
|
||||||
#define exhausted DX
|
|
||||||
|
|
||||||
#define br0 R13
|
|
||||||
#define br1 R14
|
|
||||||
#define br2 R15
|
|
||||||
#define br3 BP
|
|
||||||
|
|
||||||
MOVQ BP, 0(SP)
|
|
||||||
|
|
||||||
XORQ exhausted, exhausted // exhausted = false
|
|
||||||
XORQ off, off // off = 0
|
|
||||||
|
|
||||||
MOVBQZX peekBits+32(FP), peek_bits
|
|
||||||
MOVQ buf+40(FP), buffer
|
|
||||||
MOVQ tbl+48(FP), table
|
|
||||||
|
|
||||||
MOVQ pbr0+0(FP), br0
|
|
||||||
MOVQ pbr1+8(FP), br1
|
|
||||||
MOVQ pbr2+16(FP), br2
|
|
||||||
MOVQ pbr3+24(FP), br3
|
|
||||||
|
|
||||||
main_loop:
|
|
||||||
{{ define "decode_2_values_x86" }}
|
|
||||||
// const stream = {{ var "id" }}
|
|
||||||
// br{{ var "id"}}.fillFast()
|
|
||||||
MOVBQZX bitReaderShifted_bitsRead(br{{ var "id" }}), br_bits_read
|
|
||||||
MOVQ bitReaderShifted_value(br{{ var "id" }}), br_value
|
|
||||||
MOVQ bitReaderShifted_off(br{{ var "id" }}), br_offset
|
|
||||||
|
|
||||||
// We must have at least 2 * max tablelog left
|
|
||||||
CMPQ br_bits_read, $64-22
|
|
||||||
JBE skip_fill{{ var "id" }}
|
|
||||||
|
|
||||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
|
||||||
SUBQ $4, br_offset // b.off -= 4
|
|
||||||
|
|
||||||
// v := b.in[b.off-4 : b.off]
|
|
||||||
// v = v[:4]
|
|
||||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
|
||||||
MOVQ bitReaderShifted_in(br{{ var "id" }}), AX
|
|
||||||
|
|
||||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
|
||||||
#ifdef GOAMD64_v3
|
|
||||||
SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63)
|
|
||||||
#else
|
|
||||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
|
||||||
MOVQ br_bits_read, CX
|
|
||||||
SHLQ CL, AX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ORQ AX, br_value
|
|
||||||
|
|
||||||
// exhausted = exhausted || (br{{ var "id"}}.off < 4)
|
|
||||||
CMPQ br_offset, $4
|
|
||||||
SETLT DL
|
|
||||||
ORB DL, DH
|
|
||||||
// }
|
|
||||||
skip_fill{{ var "id" }}:
|
|
||||||
|
|
||||||
// val0 := br{{ var "id"}}.peekTopBits(peekBits)
|
|
||||||
#ifdef GOAMD64_v3
|
|
||||||
SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask
|
|
||||||
#else
|
|
||||||
MOVQ br_value, AX
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// v0 := table[val0&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v0
|
|
||||||
|
|
||||||
// br{{ var "id"}}.advance(uint8(v0.entry))
|
|
||||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
|
||||||
|
|
||||||
#ifdef GOAMD64_v3
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLXQ AX, br_value, br_value // value <<= n
|
|
||||||
#else
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef GOAMD64_v3
|
|
||||||
SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask
|
|
||||||
#else
|
|
||||||
// val1 := br{{ var "id"}}.peekTopBits(peekBits)
|
|
||||||
MOVQ peek_bits, CX
|
|
||||||
MOVQ br_value, AX
|
|
||||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// v1 := table[val1&mask]
|
|
||||||
MOVW 0(table)(AX*2), AX // AX - v1
|
|
||||||
|
|
||||||
// br{{ var "id"}}.advance(uint8(v1.entry))
|
|
||||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
|
||||||
|
|
||||||
#ifdef GOAMD64_v3
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLXQ AX, br_value, br_value // value <<= n
|
|
||||||
#else
|
|
||||||
MOVBQZX AL, CX
|
|
||||||
SHLQ CL, br_value // value <<= n
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ADDQ CX, br_bits_read // bits_read += n
|
|
||||||
|
|
||||||
|
|
||||||
// these two writes get coalesced
|
|
||||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
|
||||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
|
||||||
MOVW BX, {{ var "bufofs" }}(buffer)(off*1)
|
|
||||||
|
|
||||||
// update the bitrader reader structure
|
|
||||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br{{ var "id" }})
|
|
||||||
MOVQ br_value, bitReaderShifted_value(br{{ var "id" }})
|
|
||||||
MOVQ br_offset, bitReaderShifted_off(br{{ var "id" }})
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ set "id" "0" }}
|
|
||||||
{{ set "ofs" "0" }}
|
|
||||||
{{ set "bufofs" "0" }} {{/* id * bufoff */}}
|
|
||||||
{{ template "decode_2_values_x86" . }}
|
|
||||||
|
|
||||||
{{ set "id" "1" }}
|
|
||||||
{{ set "ofs" "8" }}
|
|
||||||
{{ set "bufofs" "256" }}
|
|
||||||
{{ template "decode_2_values_x86" . }}
|
|
||||||
|
|
||||||
{{ set "id" "2" }}
|
|
||||||
{{ set "ofs" "16" }}
|
|
||||||
{{ set "bufofs" "512" }}
|
|
||||||
{{ template "decode_2_values_x86" . }}
|
|
||||||
|
|
||||||
{{ set "id" "3" }}
|
|
||||||
{{ set "ofs" "24" }}
|
|
||||||
{{ set "bufofs" "768" }}
|
|
||||||
{{ template "decode_2_values_x86" . }}
|
|
||||||
|
|
||||||
ADDQ $2, off // off += 2
|
|
||||||
|
|
||||||
TESTB DH, DH // any br[i].ofs < 4?
|
|
||||||
JNZ end
|
|
||||||
|
|
||||||
CMPQ off, $bufoff
|
|
||||||
JL main_loop
|
|
||||||
end:
|
|
||||||
MOVQ 0(SP), BP
|
|
||||||
|
|
||||||
MOVB off, ret+56(FP)
|
|
||||||
RET
|
|
||||||
#undef off
|
|
||||||
#undef buffer
|
|
||||||
#undef table
|
|
||||||
|
|
||||||
#undef br_bits_read
|
|
||||||
#undef br_value
|
|
||||||
#undef br_offset
|
|
||||||
#undef peek_bits
|
|
||||||
#undef exhausted
|
|
||||||
|
|
||||||
#undef br0
|
|
||||||
#undef br1
|
|
||||||
#undef br2
|
|
||||||
#undef br3
|
|
@ -1,11 +0,0 @@
|
|||||||
//go:build ignorecrc
|
|
||||||
// +build ignorecrc
|
|
||||||
|
|
||||||
// Copyright 2019+ Klaus Post. All rights reserved.
|
|
||||||
// License information can be found in the LICENSE file.
|
|
||||||
// Based on work by Yann Collet, released under BSD License.
|
|
||||||
|
|
||||||
package zstd
|
|
||||||
|
|
||||||
// ignoreCRC can be used for fuzz testing to ignore CRC values...
|
|
||||||
const ignoreCRC = true
|
|
@ -1,11 +0,0 @@
|
|||||||
//go:build !ignorecrc
|
|
||||||
// +build !ignorecrc
|
|
||||||
|
|
||||||
// Copyright 2019+ Klaus Post. All rights reserved.
|
|
||||||
// License information can be found in the LICENSE file.
|
|
||||||
// Based on work by Yann Collet, released under BSD License.
|
|
||||||
|
|
||||||
package zstd
|
|
||||||
|
|
||||||
// ignoreCRC can be used for fuzz testing to ignore CRC values...
|
|
||||||
const ignoreCRC = false
|
|
@ -1,3 +0,0 @@
|
|||||||
cmd/xurls/xurls
|
|
||||||
generate/tldsgen/tldsgen
|
|
||||||
generate/regexgen/regexgen
|
|
@ -1,4 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.7.x
|
|
@ -1,27 +0,0 @@
|
|||||||
Copyright (c) 2015, Daniel Martí. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
* Neither the name of the copyright holder nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,40 +0,0 @@
|
|||||||
# xurls
|
|
||||||
|
|
||||||
[![GoDoc](https://godoc.org/github.com/mvdan/xurls?status.svg)](https://godoc.org/github.com/mvdan/xurls)
|
|
||||||
[![Travis](https://travis-ci.org/mvdan/xurls.svg?branch=master)](https://travis-ci.org/mvdan/xurls)
|
|
||||||
|
|
||||||
Extract urls from text using regular expressions.
|
|
||||||
|
|
||||||
go get -u github.com/mvdan/xurls
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/mvdan/xurls"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
xurls.Relaxed.FindString("Do gophers live in golang.org?")
|
|
||||||
// "golang.org"
|
|
||||||
xurls.Strict.FindAllString("foo.com is http://foo.com/.", -1)
|
|
||||||
// []string{"http://foo.com/"}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`Relaxed` is around five times slower than `Strict` since it does more
|
|
||||||
work to find the URLs without relying on the scheme:
|
|
||||||
|
|
||||||
```
|
|
||||||
BenchmarkStrictEmpty-4 1000000 1885 ns/op
|
|
||||||
BenchmarkStrictSingle-4 200000 8356 ns/op
|
|
||||||
BenchmarkStrictMany-4 100000 22547 ns/op
|
|
||||||
BenchmarkRelaxedEmpty-4 200000 7284 ns/op
|
|
||||||
BenchmarkRelaxedSingle-4 30000 58557 ns/op
|
|
||||||
BenchmarkRelaxedMany-4 10000 130251 ns/op
|
|
||||||
```
|
|
||||||
|
|
||||||
#### cmd/xurls
|
|
||||||
|
|
||||||
go get -u github.com/mvdan/xurls/cmd/xurls
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ echo "Do gophers live in http://golang.org?" | xurls
|
|
||||||
http://golang.org
|
|
||||||
```
|
|
File diff suppressed because one or more lines are too long
@ -1,17 +0,0 @@
|
|||||||
// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
|
|
||||||
// See LICENSE for licensing information
|
|
||||||
|
|
||||||
package xurls
|
|
||||||
|
|
||||||
// SchemesNoAuthority is a sorted list of some well-known url schemes that are
|
|
||||||
// followed by ":" instead of "://". Since these are more prone to false
|
|
||||||
// positives, we limit their matching.
|
|
||||||
var SchemesNoAuthority = []string{
|
|
||||||
`bitcoin`, // Bitcoin
|
|
||||||
`file`, // Files
|
|
||||||
`magnet`, // Torrent magnets
|
|
||||||
`mailto`, // Mail
|
|
||||||
`sms`, // SMS
|
|
||||||
`tel`, // Telephone
|
|
||||||
`xmpp`, // XMPP
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,24 +0,0 @@
|
|||||||
// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
|
|
||||||
// See LICENSE for licensing information
|
|
||||||
|
|
||||||
package xurls
|
|
||||||
|
|
||||||
// PseudoTLDs is a sorted list of some widely used unofficial TLDs.
|
|
||||||
//
|
|
||||||
// Sources:
|
|
||||||
// * https://en.wikipedia.org/wiki/Pseudo-top-level_domain
|
|
||||||
// * https://en.wikipedia.org/wiki/Category:Pseudo-top-level_domains
|
|
||||||
// * https://tools.ietf.org/html/draft-grothoff-iesg-special-use-p2p-names-00
|
|
||||||
// * https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml
|
|
||||||
var PseudoTLDs = []string{
|
|
||||||
`bit`, // Namecoin
|
|
||||||
`example`, // Example domain
|
|
||||||
`exit`, // Tor exit node
|
|
||||||
`gnu`, // GNS by public key
|
|
||||||
`i2p`, // I2P network
|
|
||||||
`invalid`, // Invalid domain
|
|
||||||
`local`, // Local network
|
|
||||||
`localhost`, // Local network
|
|
||||||
`test`, // Test domain
|
|
||||||
`zkey`, // GNS domain name
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
|
|
||||||
// See LICENSE for licensing information
|
|
||||||
|
|
||||||
// Package xurls extracts urls from plain text using regular expressions.
|
|
||||||
package xurls
|
|
||||||
|
|
||||||
import "regexp"
|
|
||||||
|
|
||||||
//go:generate go run generate/tldsgen/main.go
|
|
||||||
//go:generate go run generate/regexgen/main.go
|
|
||||||
|
|
||||||
const (
|
|
||||||
letter = `\p{L}`
|
|
||||||
mark = `\p{M}`
|
|
||||||
number = `\p{N}`
|
|
||||||
iriChar = letter + mark + number
|
|
||||||
currency = `\p{Sc}`
|
|
||||||
otherSymb = `\p{So}`
|
|
||||||
endChar = iriChar + `/\-+_&~*%=#` + currency + otherSymb
|
|
||||||
midChar = endChar + `@.,:;'?!|`
|
|
||||||
wellParen = `\([` + midChar + `]*(\([` + midChar + `]*\)[` + midChar + `]*)*\)`
|
|
||||||
wellBrack = `\[[` + midChar + `]*(\[[` + midChar + `]*\][` + midChar + `]*)*\]`
|
|
||||||
wellBrace = `\{[` + midChar + `]*(\{[` + midChar + `]*\}[` + midChar + `]*)*\}`
|
|
||||||
wellAll = wellParen + `|` + wellBrack + `|` + wellBrace
|
|
||||||
pathCont = `([` + midChar + `]*(` + wellAll + `|[` + endChar + `])+)+`
|
|
||||||
comScheme = `[a-zA-Z][a-zA-Z.\-+]*://`
|
|
||||||
scheme = `(` + comScheme + `|` + otherScheme + `)`
|
|
||||||
|
|
||||||
iri = `[` + iriChar + `]([` + iriChar + `\-]*[` + iriChar + `])?`
|
|
||||||
domain = `(` + iri + `\.)+`
|
|
||||||
octet = `(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])`
|
|
||||||
ipv4Addr = `\b` + octet + `\.` + octet + `\.` + octet + `\.` + octet + `\b`
|
|
||||||
ipv6Addr = `([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:[0-9a-fA-F]{0,4}|:[0-9a-fA-F]{1,4})?|(:[0-9a-fA-F]{1,4}){0,2})|(:[0-9a-fA-F]{1,4}){0,3})|(:[0-9a-fA-F]{1,4}){0,4})|:(:[0-9a-fA-F]{1,4}){0,5})((:[0-9a-fA-F]{1,4}){2}|:(25[0-5]|(2[0-4]|1[0-9]|[1-9])?[0-9])(\.(25[0-5]|(2[0-4]|1[0-9]|[1-9])?[0-9])){3})|(([0-9a-fA-F]{1,4}:){1,6}|:):[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){7}:`
|
|
||||||
ipAddr = `(` + ipv4Addr + `|` + ipv6Addr + `)`
|
|
||||||
site = domain + gtld
|
|
||||||
hostName = `(` + site + `|` + ipAddr + `)`
|
|
||||||
port = `(:[0-9]*)?`
|
|
||||||
path = `(/|/` + pathCont + `?|\b|$)`
|
|
||||||
webURL = hostName + port + path
|
|
||||||
|
|
||||||
strict = `(\b` + scheme + pathCont + `)`
|
|
||||||
relaxed = `(` + strict + `|` + webURL + `)`
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// Relaxed matches all the urls it can find.
|
|
||||||
Relaxed = regexp.MustCompile(relaxed)
|
|
||||||
// Strict only matches urls with a scheme to avoid false positives.
|
|
||||||
Strict = regexp.MustCompile(strict)
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
Relaxed.Longest()
|
|
||||||
Strict.Longest()
|
|
||||||
}
|
|
||||||
|
|
||||||
// StrictMatchingScheme produces a regexp that matches urls like Strict but
|
|
||||||
// whose scheme matches the given regular expression.
|
|
||||||
func StrictMatchingScheme(exp string) (*regexp.Regexp, error) {
|
|
||||||
strictMatching := `(\b(?i)(` + exp + `)(?-i)` + pathCont + `)`
|
|
||||||
re, err := regexp.Compile(strictMatching)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
re.Longest()
|
|
||||||
return re, nil
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue