From 26e06712268ecae09004bfacbb938994593af159 Mon Sep 17 00:00:00 2001 From: Emman Date: Thu, 16 Dec 2021 09:33:28 +0800 Subject: [PATCH] limited support arm64 assembly language --- internal/xor/xor_arm64.go | 29 ++++++++++++++++ internal/xor/xor_arm64.s | 67 +++++++++++++++++++++++++++++++++++++ internal/xor/xor_generic.go | 4 +-- 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 internal/xor/xor_arm64.go create mode 100644 internal/xor/xor_arm64.s diff --git a/internal/xor/xor_arm64.go b/internal/xor/xor_arm64.go new file mode 100644 index 0000000..0246011 --- /dev/null +++ b/internal/xor/xor_arm64.go @@ -0,0 +1,29 @@ +// Copyright 2018 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. + +package xor + +// xorBytes xors the bytes in a and b. The destination should have enough +// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. +func XorBytes(dst, a, b []byte) int { + n := len(a) + if len(b) < n { + n = len(b) + } + if n == 0 { + return 0 + } + // make sure dst has enough space + _ = dst[n-1] + + xorBytesARM64(&dst[0], &a[0], &b[0], n) + return n +} + +func XorWords(dst, a, b []byte) { + XorBytes(dst, a, b) +} + +//go:noescape +func xorBytesARM64(dst, a, b *byte, n int) diff --git a/internal/xor/xor_arm64.s b/internal/xor/xor_arm64.s new file mode 100644 index 0000000..791e267 --- /dev/null +++ b/internal/xor/xor_arm64.s @@ -0,0 +1,67 @@ +// Copyright 2020 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" + +// func xorBytesARM64(dst, a, b *byte, n int) +TEXT ·xorBytesARM64(SB), NOSPLIT|NOFRAME, $0 + MOVD dst+0(FP), R0 + MOVD a+8(FP), R1 + MOVD b+16(FP), R2 + MOVD n+24(FP), R3 + CMP $64, R3 + BLT tail +loop_64: + VLD1.P 64(R1), [V0.B16, V1.B16, V2.B16, V3.B16] + VLD1.P 64(R2), [V4.B16, V5.B16, V6.B16, V7.B16] + VEOR V0.B16, V4.B16, V4.B16 + VEOR V1.B16, V5.B16, V5.B16 + VEOR V2.B16, V6.B16, V6.B16 + VEOR V3.B16, V7.B16, V7.B16 + VST1.P [V4.B16, V5.B16, V6.B16, V7.B16], 64(R0) + SUBS $64, R3 + CMP $64, R3 + BGE loop_64 +tail: + // quick end + CBZ R3, end + TBZ $5, R3, less_than32 + VLD1.P 32(R1), [V0.B16, V1.B16] + VLD1.P 32(R2), [V2.B16, V3.B16] + VEOR V0.B16, V2.B16, V2.B16 + VEOR V1.B16, V3.B16, V3.B16 + VST1.P [V2.B16, V3.B16], 32(R0) +less_than32: + TBZ $4, R3, less_than16 + LDP.P 16(R1), (R11, R12) + LDP.P 16(R2), (R13, R14) + EOR R11, R13, R13 + EOR R12, R14, R14 + STP.P (R13, R14), 16(R0) +less_than16: + TBZ $3, R3, less_than8 + MOVD.P 8(R1), R11 + MOVD.P 8(R2), R12 + EOR R11, R12, R12 + MOVD.P R12, 8(R0) +less_than8: + TBZ $2, R3, less_than4 + MOVWU.P 4(R1), R13 + MOVWU.P 4(R2), R14 + EORW R13, R14, R14 + MOVWU.P R14, 4(R0) +less_than4: + TBZ $1, R3, less_than2 + MOVHU.P 2(R1), R15 + MOVHU.P 2(R2), R16 + EORW R15, R16, R16 + MOVHU.P R16, 2(R0) +less_than2: + TBZ $0, R3, end + MOVBU (R1), R17 + MOVBU (R2), R19 + EORW R17, R19, R19 + MOVBU R19, (R0) +end: + RET \ No newline at end of file diff --git a/internal/xor/xor_generic.go b/internal/xor/xor_generic.go index 490816f..5f6252b 100644 --- a/internal/xor/xor_generic.go +++ b/internal/xor/xor_generic.go @@ -1,8 +1,8 @@ // Copyright 2013 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. -//go:build !amd64 -// +build !amd64 +//go:build !amd64 && !arm64 +// +build !amd64,!arm64 package xor