The internal GCP package used `pkg.go.dev/google.golang.org/api` [1] to interact with Compute Engine API. Modify the package to use the new and idiomatic `pkg.go.dev/cloud.google.com/go` [2] library for interacting with the Compute Engine API. The new library have been already used to interact with the Cloudbuild and Storage APIs. The new library was not used for Compute Engine since the beginning, because at that time, it didn't support Compute Engine. Update go.mod and vendored packages. [1] https://github.com/googleapis/google-api-go-client [2] https://github.com/googleapis/google-cloud-go Signed-off-by: Tomas Hozza <thozza@redhat.com>
233 lines
4.1 KiB
ArmAsm
233 lines
4.1 KiB
ArmAsm
// +build !appengine
|
|
// +build gc
|
|
// +build !purego
|
|
|
|
#include "textflag.h"
|
|
|
|
// Register allocation:
|
|
// AX h
|
|
// CX pointer to advance through b
|
|
// DX n
|
|
// BX loop end
|
|
// R8 v1, k1
|
|
// R9 v2
|
|
// R10 v3
|
|
// R11 v4
|
|
// R12 tmp
|
|
// R13 prime1v
|
|
// R14 prime2v
|
|
// R15 prime4v
|
|
|
|
// round reads from and advances the buffer pointer in CX.
|
|
// It assumes that R13 has prime1v and R14 has prime2v.
|
|
#define round(r) \
|
|
MOVQ (CX), R12 \
|
|
ADDQ $8, CX \
|
|
IMULQ R14, R12 \
|
|
ADDQ R12, r \
|
|
ROLQ $31, r \
|
|
IMULQ R13, r
|
|
|
|
// mergeRound applies a merge round on the two registers acc and val.
|
|
// It assumes that R13 has prime1v, R14 has prime2v, and R15 has prime4v.
|
|
#define mergeRound(acc, val) \
|
|
IMULQ R14, val \
|
|
ROLQ $31, val \
|
|
IMULQ R13, val \
|
|
XORQ val, acc \
|
|
IMULQ R13, acc \
|
|
ADDQ R15, acc
|
|
|
|
// func Sum64(b []byte) uint64
|
|
TEXT ·Sum64(SB), NOSPLIT, $0-32
|
|
// Load fixed primes.
|
|
MOVQ ·prime1v(SB), R13
|
|
MOVQ ·prime2v(SB), R14
|
|
MOVQ ·prime4v(SB), R15
|
|
|
|
// Load slice.
|
|
MOVQ b_base+0(FP), CX
|
|
MOVQ b_len+8(FP), DX
|
|
LEAQ (CX)(DX*1), BX
|
|
|
|
// The first loop limit will be len(b)-32.
|
|
SUBQ $32, BX
|
|
|
|
// Check whether we have at least one block.
|
|
CMPQ DX, $32
|
|
JLT noBlocks
|
|
|
|
// Set up initial state (v1, v2, v3, v4).
|
|
MOVQ R13, R8
|
|
ADDQ R14, R8
|
|
MOVQ R14, R9
|
|
XORQ R10, R10
|
|
XORQ R11, R11
|
|
SUBQ R13, R11
|
|
|
|
// Loop until CX > BX.
|
|
blockLoop:
|
|
round(R8)
|
|
round(R9)
|
|
round(R10)
|
|
round(R11)
|
|
|
|
CMPQ CX, BX
|
|
JLE blockLoop
|
|
|
|
MOVQ R8, AX
|
|
ROLQ $1, AX
|
|
MOVQ R9, R12
|
|
ROLQ $7, R12
|
|
ADDQ R12, AX
|
|
MOVQ R10, R12
|
|
ROLQ $12, R12
|
|
ADDQ R12, AX
|
|
MOVQ R11, R12
|
|
ROLQ $18, R12
|
|
ADDQ R12, AX
|
|
|
|
mergeRound(AX, R8)
|
|
mergeRound(AX, R9)
|
|
mergeRound(AX, R10)
|
|
mergeRound(AX, R11)
|
|
|
|
JMP afterBlocks
|
|
|
|
noBlocks:
|
|
MOVQ ·prime5v(SB), AX
|
|
|
|
afterBlocks:
|
|
ADDQ DX, AX
|
|
|
|
// Right now BX has len(b)-32, and we want to loop until CX > len(b)-8.
|
|
ADDQ $24, BX
|
|
|
|
CMPQ CX, BX
|
|
JG fourByte
|
|
|
|
wordLoop:
|
|
// Calculate k1.
|
|
MOVQ (CX), R8
|
|
ADDQ $8, CX
|
|
IMULQ R14, R8
|
|
ROLQ $31, R8
|
|
IMULQ R13, R8
|
|
|
|
XORQ R8, AX
|
|
ROLQ $27, AX
|
|
IMULQ R13, AX
|
|
ADDQ R15, AX
|
|
|
|
CMPQ CX, BX
|
|
JLE wordLoop
|
|
|
|
fourByte:
|
|
ADDQ $4, BX
|
|
CMPQ CX, BX
|
|
JG singles
|
|
|
|
MOVL (CX), R8
|
|
ADDQ $4, CX
|
|
IMULQ R13, R8
|
|
XORQ R8, AX
|
|
|
|
ROLQ $23, AX
|
|
IMULQ R14, AX
|
|
ADDQ ·prime3v(SB), AX
|
|
|
|
singles:
|
|
ADDQ $4, BX
|
|
CMPQ CX, BX
|
|
JGE finalize
|
|
|
|
singlesLoop:
|
|
MOVBQZX (CX), R12
|
|
ADDQ $1, CX
|
|
IMULQ ·prime5v(SB), R12
|
|
XORQ R12, AX
|
|
|
|
ROLQ $11, AX
|
|
IMULQ R13, AX
|
|
|
|
CMPQ CX, BX
|
|
JL singlesLoop
|
|
|
|
finalize:
|
|
MOVQ AX, R12
|
|
SHRQ $33, R12
|
|
XORQ R12, AX
|
|
IMULQ R14, AX
|
|
MOVQ AX, R12
|
|
SHRQ $29, R12
|
|
XORQ R12, AX
|
|
IMULQ ·prime3v(SB), AX
|
|
MOVQ AX, R12
|
|
SHRQ $32, R12
|
|
XORQ R12, AX
|
|
|
|
MOVQ AX, ret+24(FP)
|
|
RET
|
|
|
|
// writeBlocks uses the same registers as above except that it uses AX to store
|
|
// the x pointer.
|
|
|
|
// func writeBlocks(x *xxh, b []byte) []byte
|
|
TEXT ·writeBlocks(SB), NOSPLIT, $0-56
|
|
// Load fixed primes needed for round.
|
|
MOVQ ·prime1v(SB), R13
|
|
MOVQ ·prime2v(SB), R14
|
|
|
|
// Load slice.
|
|
MOVQ b_base+8(FP), CX
|
|
MOVQ CX, ret_base+32(FP) // initialize return base pointer; see NOTE below
|
|
MOVQ b_len+16(FP), DX
|
|
LEAQ (CX)(DX*1), BX
|
|
SUBQ $32, BX
|
|
|
|
// Load vN from x.
|
|
MOVQ x+0(FP), AX
|
|
MOVQ 0(AX), R8 // v1
|
|
MOVQ 8(AX), R9 // v2
|
|
MOVQ 16(AX), R10 // v3
|
|
MOVQ 24(AX), R11 // v4
|
|
|
|
// We don't need to check the loop condition here; this function is
|
|
// always called with at least one block of data to process.
|
|
blockLoop:
|
|
round(R8)
|
|
round(R9)
|
|
round(R10)
|
|
round(R11)
|
|
|
|
CMPQ CX, BX
|
|
JLE blockLoop
|
|
|
|
// Copy vN back to x.
|
|
MOVQ R8, 0(AX)
|
|
MOVQ R9, 8(AX)
|
|
MOVQ R10, 16(AX)
|
|
MOVQ R11, 24(AX)
|
|
|
|
// Construct return slice.
|
|
// NOTE: It's important that we don't construct a slice that has a base
|
|
// pointer off the end of the original slice, as in Go 1.7+ this will
|
|
// cause runtime crashes. (See discussion in, for example,
|
|
// https://github.com/golang/go/issues/16772.)
|
|
// Therefore, we calculate the length/cap first, and if they're zero, we
|
|
// keep the old base. This is what the compiler does as well if you
|
|
// write code like
|
|
// b = b[len(b):]
|
|
|
|
// New length is 32 - (CX - BX) -> BX+32 - CX.
|
|
ADDQ $32, BX
|
|
SUBQ CX, BX
|
|
JZ afterSetBase
|
|
|
|
MOVQ CX, ret_base+32(FP)
|
|
|
|
afterSetBase:
|
|
MOVQ BX, ret_len+40(FP)
|
|
MOVQ BX, ret_cap+48(FP) // set cap == len
|
|
|
|
RET
|