161 lines
3.2 KiB
ArmAsm
161 lines
3.2 KiB
ArmAsm
// Copyright 2024 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
#include "textflag.h"
|
|
|
|
// castagnoliUpdate updates the non-inverted crc with the given data.
|
|
|
|
// func castagnoliUpdate(crc uint32, p []byte) uint32
|
|
TEXT ·castagnoliUpdate(SB), NOSPLIT, $0-36
|
|
MOVWU crc+0(FP), R4 // a0 = CRC value
|
|
MOVV p+8(FP), R5 // a1 = data pointer
|
|
MOVV p_len+16(FP), R6 // a2 = len(p)
|
|
|
|
SGT $8, R6, R12
|
|
BNE R12, less_than_8
|
|
AND $7, R5, R12
|
|
BEQ R12, aligned
|
|
|
|
// Process the first few bytes to 8-byte align the input.
|
|
// t0 = 8 - t0. We need to process this many bytes to align.
|
|
SUB $1, R12
|
|
XOR $7, R12
|
|
|
|
AND $1, R12, R13
|
|
BEQ R13, align_2
|
|
MOVB (R5), R13
|
|
CRCCWBW R4, R13, R4
|
|
ADDV $1, R5
|
|
ADDV $-1, R6
|
|
|
|
align_2:
|
|
AND $2, R12, R13
|
|
BEQ R13, align_4
|
|
MOVH (R5), R13
|
|
CRCCWHW R4, R13, R4
|
|
ADDV $2, R5
|
|
ADDV $-2, R6
|
|
|
|
align_4:
|
|
AND $4, R12, R13
|
|
BEQ R13, aligned
|
|
MOVW (R5), R13
|
|
CRCCWWW R4, R13, R4
|
|
ADDV $4, R5
|
|
ADDV $-4, R6
|
|
|
|
aligned:
|
|
// The input is now 8-byte aligned and we can process 8-byte chunks.
|
|
SGT $8, R6, R12
|
|
BNE R12, less_than_8
|
|
MOVV (R5), R13
|
|
CRCCWVW R4, R13, R4
|
|
ADDV $8, R5
|
|
ADDV $-8, R6
|
|
JMP aligned
|
|
|
|
less_than_8:
|
|
// We may have some bytes left over; process 4 bytes, then 2, then 1.
|
|
AND $4, R6, R12
|
|
BEQ R12, less_than_4
|
|
MOVW (R5), R13
|
|
CRCCWWW R4, R13, R4
|
|
ADDV $4, R5
|
|
ADDV $-4, R6
|
|
|
|
less_than_4:
|
|
AND $2, R6, R12
|
|
BEQ R12, less_than_2
|
|
MOVH (R5), R13
|
|
CRCCWHW R4, R13, R4
|
|
ADDV $2, R5
|
|
ADDV $-2, R6
|
|
|
|
less_than_2:
|
|
BEQ R6, done
|
|
MOVB (R5), R13
|
|
CRCCWBW R4, R13, R4
|
|
|
|
done:
|
|
MOVW R4, ret+32(FP)
|
|
RET
|
|
|
|
// ieeeUpdate updates the non-inverted crc with the given data.
|
|
|
|
// func ieeeUpdate(crc uint32, p []byte) uint32
|
|
TEXT ·ieeeUpdate(SB), NOSPLIT, $0-36
|
|
MOVWU crc+0(FP), R4 // a0 = CRC value
|
|
MOVV p+8(FP), R5 // a1 = data pointer
|
|
MOVV p_len+16(FP), R6 // a2 = len(p)
|
|
|
|
SGT $8, R6, R12
|
|
BNE R12, less_than_8
|
|
AND $7, R5, R12
|
|
BEQ R12, aligned
|
|
|
|
// Process the first few bytes to 8-byte align the input.
|
|
// t0 = 8 - t0. We need to process this many bytes to align.
|
|
SUB $1, R12
|
|
XOR $7, R12
|
|
|
|
AND $1, R12, R13
|
|
BEQ R13, align_2
|
|
MOVB (R5), R13
|
|
CRCWBW R4, R13, R4
|
|
ADDV $1, R5
|
|
ADDV $-1, R6
|
|
|
|
align_2:
|
|
AND $2, R12, R13
|
|
BEQ R13, align_4
|
|
MOVH (R5), R13
|
|
CRCWHW R4, R13, R4
|
|
ADDV $2, R5
|
|
ADDV $-2, R6
|
|
|
|
align_4:
|
|
AND $4, R12, R13
|
|
BEQ R13, aligned
|
|
MOVW (R5), R13
|
|
CRCWWW R4, R13, R4
|
|
ADDV $4, R5
|
|
ADDV $-4, R6
|
|
|
|
aligned:
|
|
// The input is now 8-byte aligned and we can process 8-byte chunks.
|
|
SGT $8, R6, R12
|
|
BNE R12, less_than_8
|
|
MOVV (R5), R13
|
|
CRCWVW R4, R13, R4
|
|
ADDV $8, R5
|
|
ADDV $-8, R6
|
|
JMP aligned
|
|
|
|
less_than_8:
|
|
// We may have some bytes left over; process 4 bytes, then 2, then 1.
|
|
AND $4, R6, R12
|
|
BEQ R12, less_than_4
|
|
MOVW (R5), R13
|
|
CRCWWW R4, R13, R4
|
|
ADDV $4, R5
|
|
ADDV $-4, R6
|
|
|
|
less_than_4:
|
|
AND $2, R6, R12
|
|
BEQ R12, less_than_2
|
|
MOVH (R5), R13
|
|
CRCWHW R4, R13, R4
|
|
ADDV $2, R5
|
|
ADDV $-2, R6
|
|
|
|
less_than_2:
|
|
BEQ R6, done
|
|
MOVB (R5), R13
|
|
CRCWBW R4, R13, R4
|
|
|
|
done:
|
|
MOVW R4, ret+32(FP)
|
|
RET
|
|
|