Skip to content

Commit

Permalink
test arm64 encode
Browse files Browse the repository at this point in the history
  • Loading branch information
emmansun authored Nov 3, 2023
1 parent ca0acc0 commit e635bf6
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 0 deletions.
1 change: 1 addition & 0 deletions README-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
使用SIMD指令加速的Base64实现。

[![ci](https://github.com/emmansun/base64/actions/workflows/ci.yml/badge.svg)](https://github.com/emmansun/base64/actions/workflows/ci.yml)
[![arm64-qemu](https://github.com/emmansun/base64/actions/workflows/ci_qemu.yml/badge.svg)](https://github.com/emmansun/base64/actions/workflows/ci_qemu.yml)
![GitHub go.mod Go version (branch)](https://img.shields.io/github/go-mod/go-version/emmansun/base64)

## 致谢
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ English | [简体中文](README-CN.md)
Base64 with SIMD acceleration

[![ci](https://github.com/emmansun/base64/actions/workflows/ci.yml/badge.svg)](https://github.com/emmansun/base64/actions/workflows/ci.yml)
[![arm64-qemu](https://github.com/emmansun/base64/actions/workflows/ci_qemu.yml/badge.svg)](https://github.com/emmansun/base64/actions/workflows/ci_qemu.yml)
![GitHub go.mod Go version (branch)](https://img.shields.io/github/go-mod/go-version/emmansun/base64)

## Acknowledgements
Expand Down
7 changes: 7 additions & 0 deletions base64_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build arm64 && !purego
// +build arm64,!purego

package base64

//go:noescape
func encodeAsm(dst, src []byte, lut *[64]byte) int
53 changes: 53 additions & 0 deletions base64_arm64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Reference
// https://github.com/aklomp/base64/blob/master/lib/arch/neon64/enc_loop.c
//go:build arm64 && !purego
// +build arm64,!purego

//func encodeAsm(dst, src []byte, lut *[64]byte) int
TEXT ·encodeAsm(SB),NOSPLIT,$0
MOVD dst_base+0(FP), R0
MOVD src_base+24(FP), R1
MOVD src_len+32(FP), R2
MOVD lut+48(FP), R3

VLD1 (R3), [V8.B16, V9.B16, V10.B16, V11.B16]
MOVB $0x3F, R4
VDUP R3, V7.B16
EOR R5, R5, R5

loop:
CMP $48, R2
BLT done

// Move the input bits to where they need to be in the outputs. Except
// for the first output, the high two bits are not cleared.
VLD3.P 48(R1), [V0.B16, V1.B16, V2.B16]
VUSHR $2, V0.B16, V3.B16
VUSHR $4, V1.B16, V4.B16
VUSHR $6, V2.B16, V5.B16
VSLI $4, V0.B16, V4.B16
VSLI $2, V1.B16, V5.B16

// Clear the high two bits in the second, third and fourth output.
VAND V7.B16, V4.B16, V4.B16
VAND V7.B16, V5.B16, V5.B16
VAND V7.B16, V2.B16, V6.B16

// The bits have now been shifted to the right locations;
// translate their values 0..63 to the Base64 alphabet.
// Use a 64-byte table lookup:
VTBL V3.B16, [V8.B16, V9.B16, V10.B16, V11.B16], V3.B16
VTBL V4.B16, [V8.B16, V9.B16, V10.B16, V11.B16], V4.B16
VTBL V5.B16, [V8.B16, V9.B16, V10.B16, V11.B16], V5.B16
VTBL V6.B16, [V8.B16, V9.B16, V10.B16, V11.B16], V6.B16

// Interleave and store output:
VST4.P [V3.B16, V4.B16, V5.B16, V6.B16], 64(R0)

SUB $48, R2
ADD $64, R5
B loop

done:
MOVD R5, ret+56(FP)
RET
25 changes: 25 additions & 0 deletions base64_arm64_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//go:build arm64 && !purego
// +build arm64,!purego

package base64

func TestStdEncodeSIMD(t *testing.T) {

Check failure on line 6 in base64_arm64_test.go

View workflow job for this annotation

GitHub Actions / test (1.21.x, arm64)

undefined: testing
pairs := []testpair{
{"abcdefghijklabcdefghijklabcdefghijklabcdefghijkl", "YWJjZGVmZ2hpamtsYWJjZGVmZ2hpamtsYWJjZGVmZ2hpamtsYWJjZGVmZ2hpamts"},
{"abcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijkl", "YWJjZGVmZ2hpamtsYWJjZGVmZ2hpamtsYWJjZGVmZ2hpamtsYWJjZGVmZ2hpamtsYWJjZGVmZ2hpamtsYWJjZGVmZ2hpamtsYWJjZGVmZ2hpamtsYWJjZGVmZ2hpamts"},
}
for _, p := range pairs {
src := []byte(p.decoded)
expected := []byte(p.encoded)
dst := make([]byte, len(expected))

ret := encodeAsm(dst, src, &encodeStd)

Check failure on line 16 in base64_arm64_test.go

View workflow job for this annotation

GitHub Actions / test (1.21.x, arm64)

invalid operation: cannot take address of encodeStd (untyped string constant "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
if ret != len(expected) {
t.Fatalf("should return %v", len(expected))
}
if !bytes.Equal(dst, expected) {

Check failure on line 20 in base64_arm64_test.go

View workflow job for this annotation

GitHub Actions / test (1.21.x, arm64)

undefined: bytes
t.Fatalf("got %v", string(dst))
}

}
}

0 comments on commit e635bf6

Please sign in to comment.