mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	* update github.com/alecthomas/chroma v0.8.0 -> v0.8.1 * github.com/blevesearch/bleve v1.0.10 -> v1.0.12 * editorconfig-core-go v2.1.1 -> v2.3.7 * github.com/gliderlabs/ssh v0.2.2 -> v0.3.1 * migrate editorconfig.ParseBytes to Parse * github.com/shurcooL/vfsgen to 0d455de96546 * github.com/go-git/go-git/v5 v5.1.0 -> v5.2.0 * github.com/google/uuid v1.1.1 -> v1.1.2 * github.com/huandu/xstrings v1.3.0 -> v1.3.2 * github.com/klauspost/compress v1.10.11 -> v1.11.1 * github.com/markbates/goth v1.61.2 -> v1.65.0 * github.com/mattn/go-sqlite3 v1.14.0 -> v1.14.4 * github.com/mholt/archiver v3.3.0 -> v3.3.2 * github.com/microcosm-cc/bluemonday 4f7140c49acb -> v1.0.4 * github.com/minio/minio-go v7.0.4 -> v7.0.5 * github.com/olivere/elastic v7.0.9 -> v7.0.20 * github.com/urfave/cli v1.20.0 -> v1.22.4 * github.com/prometheus/client_golang v1.1.0 -> v1.8.0 * github.com/xanzy/go-gitlab v0.37.0 -> v0.38.1 * mvdan.cc/xurls v2.1.0 -> v2.2.0 Co-authored-by: Lauris BH <lauris@nix.lv>
		
			
				
	
	
		
			376 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			376 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
		
			Vendored
		
	
	
	
// +build !appengine
 | 
						|
// +build gc
 | 
						|
// +build !noasm
 | 
						|
 | 
						|
#include "textflag.h"
 | 
						|
 | 
						|
// AX scratch
 | 
						|
// BX scratch
 | 
						|
// CX scratch
 | 
						|
// DX token
 | 
						|
//
 | 
						|
// DI &dst
 | 
						|
// SI &src
 | 
						|
// R8 &dst + len(dst)
 | 
						|
// R9 &src + len(src)
 | 
						|
// R11 &dst
 | 
						|
// R12 short output end
 | 
						|
// R13 short input end
 | 
						|
// func decodeBlock(dst, src []byte) int
 | 
						|
// using 50 bytes of stack currently
 | 
						|
TEXT ·decodeBlock(SB), NOSPLIT, $64-56
 | 
						|
	MOVQ dst_base+0(FP), DI
 | 
						|
	MOVQ DI, R11
 | 
						|
	MOVQ dst_len+8(FP), R8
 | 
						|
	ADDQ DI, R8
 | 
						|
 | 
						|
	MOVQ src_base+24(FP), SI
 | 
						|
	MOVQ src_len+32(FP), R9
 | 
						|
	ADDQ SI, R9
 | 
						|
 | 
						|
	// shortcut ends
 | 
						|
	// short output end
 | 
						|
	MOVQ R8, R12
 | 
						|
	SUBQ $32, R12
 | 
						|
	// short input end
 | 
						|
	MOVQ R9, R13
 | 
						|
	SUBQ $16, R13
 | 
						|
 | 
						|
loop:
 | 
						|
	// for si < len(src)
 | 
						|
	CMPQ SI, R9
 | 
						|
	JGE end
 | 
						|
 | 
						|
	// token := uint32(src[si])
 | 
						|
	MOVBQZX (SI), DX
 | 
						|
	INCQ SI
 | 
						|
 | 
						|
	// lit_len = token >> 4
 | 
						|
	// if lit_len > 0
 | 
						|
	// CX = lit_len
 | 
						|
	MOVQ DX, CX
 | 
						|
	SHRQ $4, CX
 | 
						|
 | 
						|
	// if lit_len != 0xF
 | 
						|
	CMPQ CX, $0xF
 | 
						|
	JEQ lit_len_loop_pre
 | 
						|
	CMPQ DI, R12
 | 
						|
	JGE lit_len_loop_pre
 | 
						|
	CMPQ SI, R13
 | 
						|
	JGE lit_len_loop_pre
 | 
						|
 | 
						|
	// copy shortcut
 | 
						|
 | 
						|
	// A two-stage shortcut for the most common case:
 | 
						|
	// 1) If the literal length is 0..14, and there is enough space,
 | 
						|
	// enter the shortcut and copy 16 bytes on behalf of the literals
 | 
						|
	// (in the fast mode, only 8 bytes can be safely copied this way).
 | 
						|
	// 2) Further if the match length is 4..18, copy 18 bytes in a similar
 | 
						|
	// manner; but we ensure that there's enough space in the output for
 | 
						|
	// those 18 bytes earlier, upon entering the shortcut (in other words,
 | 
						|
	// there is a combined check for both stages).
 | 
						|
 | 
						|
	// copy literal
 | 
						|
	MOVOU (SI), X0
 | 
						|
	MOVOU X0, (DI)
 | 
						|
	ADDQ CX, DI
 | 
						|
	ADDQ CX, SI
 | 
						|
 | 
						|
	MOVQ DX, CX
 | 
						|
	ANDQ $0xF, CX
 | 
						|
 | 
						|
	// The second stage: prepare for match copying, decode full info.
 | 
						|
	// If it doesn't work out, the info won't be wasted.
 | 
						|
	// offset := uint16(data[:2])
 | 
						|
	MOVWQZX (SI), DX
 | 
						|
	ADDQ $2, SI
 | 
						|
 | 
						|
	MOVQ DI, AX
 | 
						|
	SUBQ DX, AX
 | 
						|
	CMPQ AX, DI
 | 
						|
	JGT err_short_buf
 | 
						|
 | 
						|
	// if we can't do the second stage then jump straight to read the
 | 
						|
	// match length, we already have the offset.
 | 
						|
	CMPQ CX, $0xF
 | 
						|
	JEQ match_len_loop_pre
 | 
						|
	CMPQ DX, $8
 | 
						|
	JLT match_len_loop_pre
 | 
						|
	CMPQ AX, R11
 | 
						|
	JLT err_short_buf
 | 
						|
 | 
						|
	// memcpy(op + 0, match + 0, 8);
 | 
						|
	MOVQ (AX), BX
 | 
						|
	MOVQ BX, (DI)
 | 
						|
	// memcpy(op + 8, match + 8, 8);
 | 
						|
	MOVQ 8(AX), BX
 | 
						|
	MOVQ BX, 8(DI)
 | 
						|
	// memcpy(op +16, match +16, 2);
 | 
						|
	MOVW 16(AX), BX
 | 
						|
	MOVW BX, 16(DI)
 | 
						|
 | 
						|
	ADDQ $4, DI // minmatch
 | 
						|
	ADDQ CX, DI
 | 
						|
 | 
						|
	// shortcut complete, load next token
 | 
						|
	JMP loop
 | 
						|
 | 
						|
lit_len_loop_pre:
 | 
						|
	// if lit_len > 0
 | 
						|
	CMPQ CX, $0
 | 
						|
	JEQ offset
 | 
						|
	CMPQ CX, $0xF
 | 
						|
	JNE copy_literal
 | 
						|
 | 
						|
lit_len_loop:
 | 
						|
	// for src[si] == 0xFF
 | 
						|
	CMPB (SI), $0xFF
 | 
						|
	JNE lit_len_finalise
 | 
						|
 | 
						|
	// bounds check src[si+1]
 | 
						|
	MOVQ SI, AX
 | 
						|
	ADDQ $1, AX
 | 
						|
	CMPQ AX, R9
 | 
						|
	JGT err_short_buf
 | 
						|
 | 
						|
	// lit_len += 0xFF
 | 
						|
	ADDQ $0xFF, CX
 | 
						|
	INCQ SI
 | 
						|
	JMP lit_len_loop
 | 
						|
 | 
						|
lit_len_finalise:
 | 
						|
	// lit_len += int(src[si])
 | 
						|
	// si++
 | 
						|
	MOVBQZX (SI), AX
 | 
						|
	ADDQ AX, CX
 | 
						|
	INCQ SI
 | 
						|
 | 
						|
copy_literal:
 | 
						|
	// bounds check src and dst
 | 
						|
	MOVQ SI, AX
 | 
						|
	ADDQ CX, AX
 | 
						|
	CMPQ AX, R9
 | 
						|
	JGT err_short_buf
 | 
						|
 | 
						|
	MOVQ DI, AX
 | 
						|
	ADDQ CX, AX
 | 
						|
	CMPQ AX, R8
 | 
						|
	JGT err_short_buf
 | 
						|
 | 
						|
	// whats a good cut off to call memmove?
 | 
						|
	CMPQ CX, $16
 | 
						|
	JGT memmove_lit
 | 
						|
 | 
						|
	// if len(dst[di:]) < 16
 | 
						|
	MOVQ R8, AX
 | 
						|
	SUBQ DI, AX
 | 
						|
	CMPQ AX, $16
 | 
						|
	JLT memmove_lit
 | 
						|
 | 
						|
	// if len(src[si:]) < 16
 | 
						|
	MOVQ R9, AX
 | 
						|
	SUBQ SI, AX
 | 
						|
	CMPQ AX, $16
 | 
						|
	JLT memmove_lit
 | 
						|
 | 
						|
	MOVOU (SI), X0
 | 
						|
	MOVOU X0, (DI)
 | 
						|
 | 
						|
	JMP finish_lit_copy
 | 
						|
 | 
						|
memmove_lit:
 | 
						|
	// memmove(to, from, len)
 | 
						|
	MOVQ DI, 0(SP)
 | 
						|
	MOVQ SI, 8(SP)
 | 
						|
	MOVQ CX, 16(SP)
 | 
						|
	// spill
 | 
						|
	MOVQ DI, 24(SP)
 | 
						|
	MOVQ SI, 32(SP)
 | 
						|
	MOVQ CX, 40(SP) // need len to inc SI, DI after
 | 
						|
	MOVB DX, 48(SP)
 | 
						|
	CALL runtime·memmove(SB)
 | 
						|
 | 
						|
	// restore registers
 | 
						|
	MOVQ 24(SP), DI
 | 
						|
	MOVQ 32(SP), SI
 | 
						|
	MOVQ 40(SP), CX
 | 
						|
	MOVB 48(SP), DX
 | 
						|
 | 
						|
	// recalc initial values
 | 
						|
	MOVQ dst_base+0(FP), R8
 | 
						|
	MOVQ R8, R11
 | 
						|
	ADDQ dst_len+8(FP), R8
 | 
						|
	MOVQ src_base+24(FP), R9
 | 
						|
	ADDQ src_len+32(FP), R9
 | 
						|
	MOVQ R8, R12
 | 
						|
	SUBQ $32, R12
 | 
						|
	MOVQ R9, R13
 | 
						|
	SUBQ $16, R13
 | 
						|
 | 
						|
finish_lit_copy:
 | 
						|
	ADDQ CX, SI
 | 
						|
	ADDQ CX, DI
 | 
						|
 | 
						|
	CMPQ SI, R9
 | 
						|
	JGE end
 | 
						|
 | 
						|
offset:
 | 
						|
	// CX := mLen
 | 
						|
	// free up DX to use for offset
 | 
						|
	MOVQ DX, CX
 | 
						|
 | 
						|
	MOVQ SI, AX
 | 
						|
	ADDQ $2, AX
 | 
						|
	CMPQ AX, R9
 | 
						|
	JGT err_short_buf
 | 
						|
 | 
						|
	// offset
 | 
						|
	// DX := int(src[si]) | int(src[si+1])<<8
 | 
						|
	MOVWQZX (SI), DX
 | 
						|
	ADDQ $2, SI
 | 
						|
 | 
						|
	// 0 offset is invalid
 | 
						|
	CMPQ DX, $0
 | 
						|
	JEQ err_corrupt
 | 
						|
 | 
						|
	ANDB $0xF, CX
 | 
						|
 | 
						|
match_len_loop_pre:
 | 
						|
	// if mlen != 0xF
 | 
						|
	CMPB CX, $0xF
 | 
						|
	JNE copy_match
 | 
						|
 | 
						|
match_len_loop:
 | 
						|
	// for src[si] == 0xFF
 | 
						|
	// lit_len += 0xFF
 | 
						|
	CMPB (SI), $0xFF
 | 
						|
	JNE match_len_finalise
 | 
						|
 | 
						|
	// bounds check src[si+1]
 | 
						|
	MOVQ SI, AX
 | 
						|
	ADDQ $1, AX
 | 
						|
	CMPQ AX, R9
 | 
						|
	JGT err_short_buf
 | 
						|
 | 
						|
	ADDQ $0xFF, CX
 | 
						|
	INCQ SI
 | 
						|
	JMP match_len_loop
 | 
						|
 | 
						|
match_len_finalise:
 | 
						|
	// lit_len += int(src[si])
 | 
						|
	// si++
 | 
						|
	MOVBQZX (SI), AX
 | 
						|
	ADDQ AX, CX
 | 
						|
	INCQ SI
 | 
						|
 | 
						|
copy_match:
 | 
						|
	// mLen += minMatch
 | 
						|
	ADDQ $4, CX
 | 
						|
 | 
						|
	// check we have match_len bytes left in dst
 | 
						|
	// di+match_len < len(dst)
 | 
						|
	MOVQ DI, AX
 | 
						|
	ADDQ CX, AX
 | 
						|
	CMPQ AX, R8
 | 
						|
	JGT err_short_buf
 | 
						|
 | 
						|
	// DX = offset
 | 
						|
	// CX = match_len
 | 
						|
	// BX = &dst + (di - offset)
 | 
						|
	MOVQ DI, BX
 | 
						|
	SUBQ DX, BX
 | 
						|
 | 
						|
	// check BX is within dst
 | 
						|
	// if BX < &dst
 | 
						|
	CMPQ BX, R11
 | 
						|
	JLT err_short_buf
 | 
						|
 | 
						|
	// if offset + match_len < di
 | 
						|
	MOVQ BX, AX
 | 
						|
	ADDQ CX, AX
 | 
						|
	CMPQ DI, AX
 | 
						|
	JGT copy_interior_match
 | 
						|
 | 
						|
	// AX := len(dst[:di])
 | 
						|
	// MOVQ DI, AX
 | 
						|
	// SUBQ R11, AX
 | 
						|
 | 
						|
	// copy 16 bytes at a time
 | 
						|
	// if di-offset < 16 copy 16-(di-offset) bytes to di
 | 
						|
	// then do the remaining
 | 
						|
 | 
						|
copy_match_loop:
 | 
						|
	// for match_len >= 0
 | 
						|
	// dst[di] = dst[i]
 | 
						|
	// di++
 | 
						|
	// i++
 | 
						|
	MOVB (BX), AX
 | 
						|
	MOVB AX, (DI)
 | 
						|
	INCQ DI
 | 
						|
	INCQ BX
 | 
						|
	DECQ CX
 | 
						|
 | 
						|
	CMPQ CX, $0
 | 
						|
	JGT copy_match_loop
 | 
						|
 | 
						|
	JMP loop
 | 
						|
 | 
						|
copy_interior_match:
 | 
						|
	CMPQ CX, $16
 | 
						|
	JGT memmove_match
 | 
						|
 | 
						|
	// if len(dst[di:]) < 16
 | 
						|
	MOVQ R8, AX
 | 
						|
	SUBQ DI, AX
 | 
						|
	CMPQ AX, $16
 | 
						|
	JLT memmove_match
 | 
						|
 | 
						|
	MOVOU (BX), X0
 | 
						|
	MOVOU X0, (DI)
 | 
						|
 | 
						|
	ADDQ CX, DI
 | 
						|
	JMP loop
 | 
						|
 | 
						|
memmove_match:
 | 
						|
	// memmove(to, from, len)
 | 
						|
	MOVQ DI, 0(SP)
 | 
						|
	MOVQ BX, 8(SP)
 | 
						|
	MOVQ CX, 16(SP)
 | 
						|
	// spill
 | 
						|
	MOVQ DI, 24(SP)
 | 
						|
	MOVQ SI, 32(SP)
 | 
						|
	MOVQ CX, 40(SP) // need len to inc SI, DI after
 | 
						|
	CALL runtime·memmove(SB)
 | 
						|
 | 
						|
	// restore registers
 | 
						|
	MOVQ 24(SP), DI
 | 
						|
	MOVQ 32(SP), SI
 | 
						|
	MOVQ 40(SP), CX
 | 
						|
 | 
						|
	// recalc initial values
 | 
						|
	MOVQ dst_base+0(FP), R8
 | 
						|
	MOVQ R8, R11 // TODO: make these sensible numbers
 | 
						|
	ADDQ dst_len+8(FP), R8
 | 
						|
	MOVQ src_base+24(FP), R9
 | 
						|
	ADDQ src_len+32(FP), R9
 | 
						|
	MOVQ R8, R12
 | 
						|
	SUBQ $32, R12
 | 
						|
	MOVQ R9, R13
 | 
						|
	SUBQ $16, R13
 | 
						|
 | 
						|
	ADDQ CX, DI
 | 
						|
	JMP loop
 | 
						|
 | 
						|
err_corrupt:
 | 
						|
	MOVQ $-1, ret+48(FP)
 | 
						|
	RET
 | 
						|
 | 
						|
err_short_buf:
 | 
						|
	MOVQ $-2, ret+48(FP)
 | 
						|
	RET
 | 
						|
 | 
						|
end:
 | 
						|
	SUBQ R11, DI
 | 
						|
	MOVQ DI, ret+48(FP)
 | 
						|
	RET
 |