This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git
The following commit(s) were added to refs/heads/main by this push:
new 11209bc4 perf(compute): add ARM64 NEON comparison kernels (#1266)
11209bc4 is described below
commit 11209bc494563ba5c5606ee157ba95ddffbf2205
Author: Minh Vu <[email protected]>
AuthorDate: Wed Sep 2 20:04:16 2026 +0200
perf(compute): add ARM64 NEON comparison kernels (#1266)
## Summary
- **Added** ARM64 NEON kernels for primitive comparisons.
- **Covered** `int32`, `uint32`, `int64`, `uint64`, `float32`, and
`float64`.
- **Kept** narrow integer types and unsupported builds on the generic
path without the NEON wrapper.
- **Removed** redundant 64-bit packing shifts from the hot loops.
- **Handled** array/array, array/scalar, scalar/array, bitmap offsets,
tails, NaNs, and unsigned boundary values.
## Benchmark
Apple M1 Pro, 65,536 `int64` values, `nullprob=0.000000`, 3 runs with
`-benchtime=1s`. The generic baseline uses `-tags noasm`. Values below
are medians.
| Case | NEON | Generic | Speedup |
| --- | ---: | ---: | ---: |
| Array/scalar | 29.6 us/op | 76.3 us/op | ~2.6x |
| Array/array | 29.3 us/op | 313.6 us/op | ~10.7x |
Native uses 29 allocs/op versus 30 for the generic baseline in both
cases.
## Tests
- `go test ./arrow/compute/internal/kernels ./arrow/compute -count=1`
- `go test -tags noasm ./arrow/compute/internal/kernels ./arrow/compute
-count=1`
- `go test -race ./arrow/compute/internal/kernels ./arrow/compute
-count=1`
- `go vet ./arrow/compute/internal/kernels`
- Linux ARM64 and AMD64 cross-builds for the touched packages
- Differential ARM64 coverage for offsets 0-7 and lengths through 1024
---
.../internal/kernels/scalar_comparison_arm64.go | 131 +
.../internal/kernels/scalar_comparison_arm64.s | 2683 ++++++++++++++++++++
.../kernels/scalar_comparison_arm64_test.go | 210 ++
.../internal/kernels/scalar_comparison_noasm.go | 2 +-
4 files changed, 3025 insertions(+), 1 deletion(-)
diff --git a/arrow/compute/internal/kernels/scalar_comparison_arm64.go
b/arrow/compute/internal/kernels/scalar_comparison_arm64.go
new file mode 100644
index 00000000..f5d99611
--- /dev/null
+++ b/arrow/compute/internal/kernels/scalar_comparison_arm64.go
@@ -0,0 +1,131 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build go1.18 && arm64 && !noasm && !appengine
+
+package kernels
+
+import (
+ "unsafe"
+
+ "github.com/apache/arrow-go/v18/arrow"
+ "golang.org/x/sys/cpu"
+)
+
+const (
+ neonCompareArrayArray = iota
+ neonCompareArrayScalar
+ neonCompareScalarArray
+)
+
+//go:noescape
+func _comparison_neon(typ int, op int, shape int, left, right, out
unsafe.Pointer, groups int64)
+
+func neonComparisonSupported(typ arrow.Type) bool {
+ switch typ {
+ case arrow.INT32, arrow.UINT32, arrow.INT64, arrow.UINT64,
+ arrow.FLOAT32, arrow.FLOAT64:
+ return true
+ default:
+ return false
+ }
+}
+
+func compareNeon(typ arrow.Type, op CompareOperator, width, shape int, left,
right, out []byte, offset int, fallback binaryKernel) {
+ n := len(left) / width
+ if shape == neonCompareScalarArray {
+ n = len(right) / width
+ }
+ if n == 0 {
+ return
+ }
+
+ if offset != 0 {
+ prefix := min(n, 8-offset)
+ switch shape {
+ case neonCompareArrayArray:
+ fallback(left[:prefix*width], right[:prefix*width],
out, offset)
+ case neonCompareArrayScalar:
+ fallback(left[:prefix*width], right, out, offset)
+ case neonCompareScalarArray:
+ fallback(left, right[:prefix*width], out, offset)
+ }
+ if prefix == n {
+ return
+ }
+
+ switch shape {
+ case neonCompareArrayArray:
+ left = left[prefix*width:]
+ right = right[prefix*width:]
+ case neonCompareArrayScalar:
+ left = left[prefix*width:]
+ case neonCompareScalarArray:
+ right = right[prefix*width:]
+ }
+ out = out[1:]
+ n -= prefix
+ }
+
+ bulk := n &^ 7
+ if bulk != 0 {
+ assemblyLeft, assemblyRight := left, right
+ switch shape {
+ case neonCompareArrayArray:
+ assemblyLeft = left[:bulk*width]
+ assemblyRight = right[:bulk*width]
+ case neonCompareArrayScalar:
+ assemblyLeft = left[:bulk*width]
+ case neonCompareScalarArray:
+ assemblyRight = right[:bulk*width]
+ }
+ _comparison_neon(int(typ), int(op), shape,
+ unsafe.Pointer(&assemblyLeft[0]),
unsafe.Pointer(&assemblyRight[0]), unsafe.Pointer(&out[0]), int64(bulk/8))
+ }
+
+ if tail := n - bulk; tail != 0 {
+ out = out[bulk/8:]
+ switch shape {
+ case neonCompareArrayArray:
+ fallback(left[bulk*width:bulk*width+tail*width],
right[bulk*width:bulk*width+tail*width], out, 0)
+ case neonCompareArrayScalar:
+ fallback(left[bulk*width:bulk*width+tail*width], right,
out, 0)
+ case neonCompareScalarArray:
+ fallback(left, right[bulk*width:bulk*width+tail*width],
out, 0)
+ }
+ }
+}
+
+func genCompareKernel[T arrow.NumericType](op CompareOperator) *CompareData {
+ ty := arrow.GetType[T]()
+ fallback := genGoCompareKernel(getCmpOp[T](op))
+ if !cpu.ARM64.HasASIMD || !neonComparisonSupported(ty) {
+ return fallback
+ }
+
+ width := int(unsafe.Sizeof(T(0)))
+ return &CompareData{
+ funcAA: func(left, right, out []byte, offset int) {
+ compareNeon(ty, op, width, neonCompareArrayArray, left,
right, out, offset, fallback.funcAA)
+ },
+ funcAS: func(left, right, out []byte, offset int) {
+ compareNeon(ty, op, width, neonCompareArrayScalar,
left, right, out, offset, fallback.funcAS)
+ },
+ funcSA: func(left, right, out []byte, offset int) {
+ compareNeon(ty, op, width, neonCompareScalarArray,
left, right, out, offset, fallback.funcSA)
+ },
+ }
+}
diff --git a/arrow/compute/internal/kernels/scalar_comparison_arm64.s
b/arrow/compute/internal/kernels/scalar_comparison_arm64.s
new file mode 100644
index 00000000..80ffc09c
--- /dev/null
+++ b/arrow/compute/internal/kernels/scalar_comparison_arm64.s
@@ -0,0 +1,2683 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build go1.18 && arm64 && !noasm && !appengine
+
+#include "textflag.h"
+
+// 32-bit packing weights: [1, 2, 4, 8].
+DATA LCMPNEON_WEIGHTS<>+0(SB)/8, $0x0000000200000001
+DATA LCMPNEON_WEIGHTS<>+8(SB)/8, $0x0000000800000004
+// 64-bit variable shift counts: [0, 1].
+DATA LCMPNEON_WEIGHTS<>+16(SB)/8, $0x0000000000000000
+DATA LCMPNEON_WEIGHTS<>+24(SB)/8, $0x0000000000000001
+GLOBL LCMPNEON_WEIGHTS<>(SB), (NOPTR+RODATA), $32
+
+TEXT ยท_comparison_neon(SB), NOSPLIT|NOFRAME, $0-56
+ MOVD typ+0(FP), R0
+ MOVD op+8(FP), R1
+ MOVD shape+16(FP), R2
+ MOVD left+24(FP), R3
+ MOVD right+32(FP), R4
+ MOVD out+40(FP), R5
+ MOVD groups+48(FP), R6
+
+ CMP $6, R0
+ BEQ Lcomparison32Int
+ CMP $7, R0
+ BEQ Lcomparison32Int
+ CMP $8, R0
+ BEQ Lcomparison64Int
+ CMP $9, R0
+ BEQ Lcomparison64Int
+ CMP $11, R0
+ BEQ Lcomparison32Float
+ CMP $12, R0
+ BEQ Lcomparison64Float
+ JMP LcomparisonReturn
+
+Lcomparison32Int:
+ MOVD $LCMPNEON_WEIGHTS<>(SB), R10
+ VLD1 (R10), [V20.S4]
+ CMP $0, R2
+ BEQ Lcomparison32IntAASelect
+ CMP $1, R2
+ BEQ Lcomparison32IntASSelect
+ CMP $2, R2
+ BEQ Lcomparison32IntSASelect
+ JMP LcomparisonReturn
+
+Lcomparison32IntAASelect:
+ CMP $0, R1
+ BEQ Lcomparison32IntAAEQ
+ CMP $1, R1
+ BEQ Lcomparison32IntAANE
+ CMP $2, R1
+ BEQ Lcomparison32IntAAGTSelect
+ CMP $3, R1
+ BEQ Lcomparison32IntAAGESelect
+ JMP LcomparisonReturn
+
+Lcomparison32IntAAGTSelect:
+ CMP $6, R0
+ BEQ Lcomparison32IntAAUGT
+ JMP Lcomparison32IntAASGT
+
+Lcomparison32IntAAGESelect:
+ CMP $6, R0
+ BEQ Lcomparison32IntAAUGE
+ JMP Lcomparison32IntAASGE
+
+Lcomparison32IntASSelect:
+ CMP $0, R1
+ BEQ Lcomparison32IntASEQ
+ CMP $1, R1
+ BEQ Lcomparison32IntASNE
+ CMP $2, R1
+ BEQ Lcomparison32IntASGTSelect
+ CMP $3, R1
+ BEQ Lcomparison32IntASGESelect
+ JMP LcomparisonReturn
+
+Lcomparison32IntASGTSelect:
+ CMP $6, R0
+ BEQ Lcomparison32IntASUGT
+ JMP Lcomparison32IntASSGT
+
+Lcomparison32IntASGESelect:
+ CMP $6, R0
+ BEQ Lcomparison32IntASUGE
+ JMP Lcomparison32IntASSGE
+
+Lcomparison32IntSASelect:
+ CMP $0, R1
+ BEQ Lcomparison32IntSAEQ
+ CMP $1, R1
+ BEQ Lcomparison32IntSANE
+ CMP $2, R1
+ BEQ Lcomparison32IntSAGTSelect
+ CMP $3, R1
+ BEQ Lcomparison32IntSAGESelect
+ JMP LcomparisonReturn
+
+Lcomparison32IntSAGTSelect:
+ CMP $6, R0
+ BEQ Lcomparison32IntSAUGT
+ JMP Lcomparison32IntSASGT
+
+Lcomparison32IntSAGESelect:
+ CMP $6, R0
+ BEQ Lcomparison32IntSAUGE
+ JMP Lcomparison32IntSASGE
+
+Lcomparison32IntAAEQ:
+Lcomparison32IntAAEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea18c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea18c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntAAEQLoop
+
+Lcomparison32IntAANE:
+Lcomparison32IntAANELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntAANELoop
+
+Lcomparison32IntAASGT:
+Lcomparison32IntAASGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x4ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x4ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntAASGTLoop
+
+Lcomparison32IntAAUGT:
+Lcomparison32IntAAUGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntAAUGTLoop
+
+Lcomparison32IntAASGE:
+Lcomparison32IntAASGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x4ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x4ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntAASGELoop
+
+Lcomparison32IntAAUGE:
+Lcomparison32IntAAUGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntAAUGELoop
+
+Lcomparison32IntASEQ:
+ VLD1R (R4), [V1.S4]
+Lcomparison32IntASEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ WORD $0x6ea18c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.S4]
+ WORD $0x6ea18c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntASEQLoop
+
+Lcomparison32IntASNE:
+ VLD1R (R4), [V1.S4]
+Lcomparison32IntASNELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ WORD $0x6ea18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.S4]
+ WORD $0x6ea18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntASNELoop
+
+Lcomparison32IntASSGT:
+ VLD1R (R4), [V1.S4]
+Lcomparison32IntASSGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ WORD $0x4ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.S4]
+ WORD $0x4ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntASSGTLoop
+
+Lcomparison32IntASUGT:
+ VLD1R (R4), [V1.S4]
+Lcomparison32IntASUGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ WORD $0x6ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.S4]
+ WORD $0x6ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntASUGTLoop
+
+Lcomparison32IntASSGE:
+ VLD1R (R4), [V1.S4]
+Lcomparison32IntASSGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ WORD $0x4ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.S4]
+ WORD $0x4ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntASSGELoop
+
+Lcomparison32IntASUGE:
+ VLD1R (R4), [V1.S4]
+Lcomparison32IntASUGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ WORD $0x6ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.S4]
+ WORD $0x6ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntASUGELoop
+
+Lcomparison32IntSAEQ:
+ VLD1R (R3), [V0.S4]
+Lcomparison32IntSAEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea18c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea18c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntSAEQLoop
+
+Lcomparison32IntSANE:
+ VLD1R (R3), [V0.S4]
+Lcomparison32IntSANELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntSANELoop
+
+Lcomparison32IntSASGT:
+ VLD1R (R3), [V0.S4]
+Lcomparison32IntSASGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.S4]
+ WORD $0x4ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.S4]
+ WORD $0x4ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntSASGTLoop
+
+Lcomparison32IntSAUGT:
+ VLD1R (R3), [V0.S4]
+Lcomparison32IntSAUGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea13402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntSAUGTLoop
+
+Lcomparison32IntSASGE:
+ VLD1R (R3), [V0.S4]
+Lcomparison32IntSASGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.S4]
+ WORD $0x4ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.S4]
+ WORD $0x4ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntSASGELoop
+
+Lcomparison32IntSAUGE:
+ VLD1R (R3), [V0.S4]
+Lcomparison32IntSAUGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea13c02
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32IntSAUGELoop
+
+Lcomparison64Int:
+ MOVD $LCMPNEON_WEIGHTS<>(SB), R10
+ ADD $16, R10, R10
+ VLD1 (R10), [V20.D2]
+ CMP $0, R2
+ BEQ Lcomparison64IntAASelect
+ CMP $1, R2
+ BEQ Lcomparison64IntASSelect
+ CMP $2, R2
+ BEQ Lcomparison64IntSASelect
+ JMP LcomparisonReturn
+
+Lcomparison64IntAASelect:
+ CMP $0, R1
+ BEQ Lcomparison64IntAAEQ
+ CMP $1, R1
+ BEQ Lcomparison64IntAANE
+ CMP $2, R1
+ BEQ Lcomparison64IntAAGTSelect
+ CMP $3, R1
+ BEQ Lcomparison64IntAAGESelect
+ JMP LcomparisonReturn
+
+Lcomparison64IntAAGTSelect:
+ CMP $8, R0
+ BEQ Lcomparison64IntAAUGT
+ JMP Lcomparison64IntAASGT
+
+Lcomparison64IntAAGESelect:
+ CMP $8, R0
+ BEQ Lcomparison64IntAAUGE
+ JMP Lcomparison64IntAASGE
+
+Lcomparison64IntASSelect:
+ CMP $0, R1
+ BEQ Lcomparison64IntASEQ
+ CMP $1, R1
+ BEQ Lcomparison64IntASNE
+ CMP $2, R1
+ BEQ Lcomparison64IntASGTSelect
+ CMP $3, R1
+ BEQ Lcomparison64IntASGESelect
+ JMP LcomparisonReturn
+
+Lcomparison64IntASGTSelect:
+ CMP $8, R0
+ BEQ Lcomparison64IntASUGT
+ JMP Lcomparison64IntASSGT
+
+Lcomparison64IntASGESelect:
+ CMP $8, R0
+ BEQ Lcomparison64IntASUGE
+ JMP Lcomparison64IntASSGE
+
+Lcomparison64IntSASelect:
+ CMP $0, R1
+ BEQ Lcomparison64IntSAEQ
+ CMP $1, R1
+ BEQ Lcomparison64IntSANE
+ CMP $2, R1
+ BEQ Lcomparison64IntSAGTSelect
+ CMP $3, R1
+ BEQ Lcomparison64IntSAGESelect
+ JMP LcomparisonReturn
+
+Lcomparison64IntSAGTSelect:
+ CMP $8, R0
+ BEQ Lcomparison64IntSAUGT
+ JMP Lcomparison64IntSASGT
+
+Lcomparison64IntSAGESelect:
+ CMP $8, R0
+ BEQ Lcomparison64IntSAUGE
+ JMP Lcomparison64IntSASGE
+
+Lcomparison64IntAAEQ:
+Lcomparison64IntAAEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntAAEQLoop
+
+Lcomparison64IntAANE:
+Lcomparison64IntAANELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntAANELoop
+
+Lcomparison64IntAASGT:
+Lcomparison64IntAASGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntAASGTLoop
+
+Lcomparison64IntAAUGT:
+Lcomparison64IntAAUGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntAAUGTLoop
+
+Lcomparison64IntAASGE:
+Lcomparison64IntAASGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntAASGELoop
+
+Lcomparison64IntAAUGE:
+Lcomparison64IntAAUGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntAAUGELoop
+
+Lcomparison64IntASEQ:
+ VLD1R (R4), [V1.D2]
+Lcomparison64IntASEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntASEQLoop
+
+Lcomparison64IntASNE:
+ VLD1R (R4), [V1.D2]
+Lcomparison64IntASNELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntASNELoop
+
+Lcomparison64IntASSGT:
+ VLD1R (R4), [V1.D2]
+Lcomparison64IntASSGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntASSGTLoop
+
+Lcomparison64IntASUGT:
+ VLD1R (R4), [V1.D2]
+Lcomparison64IntASUGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntASUGTLoop
+
+Lcomparison64IntASSGE:
+ VLD1R (R4), [V1.D2]
+Lcomparison64IntASSGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntASSGELoop
+
+Lcomparison64IntASUGE:
+ VLD1R (R4), [V1.D2]
+Lcomparison64IntASUGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntASUGELoop
+
+Lcomparison64IntSAEQ:
+ VLD1R (R3), [V0.D2]
+Lcomparison64IntSAEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntSAEQLoop
+
+Lcomparison64IntSANE:
+ VLD1R (R3), [V0.D2]
+Lcomparison64IntSANELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee18c02
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntSANELoop
+
+Lcomparison64IntSASGT:
+ VLD1R (R3), [V0.D2]
+Lcomparison64IntSASGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntSASGTLoop
+
+Lcomparison64IntSAUGT:
+ VLD1R (R3), [V0.D2]
+Lcomparison64IntSAUGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntSAUGTLoop
+
+Lcomparison64IntSASGE:
+ VLD1R (R3), [V0.D2]
+Lcomparison64IntSASGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntSASGELoop
+
+Lcomparison64IntSAUGE:
+ VLD1R (R3), [V0.D2]
+Lcomparison64IntSAUGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee13c02
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64IntSAUGELoop
+
+Lcomparison32Float:
+ MOVD $LCMPNEON_WEIGHTS<>(SB), R10
+ VLD1 (R10), [V20.S4]
+ CMP $0, R2
+ BEQ Lcomparison32FloatAASelect
+ CMP $1, R2
+ BEQ Lcomparison32FloatASSelect
+ CMP $2, R2
+ BEQ Lcomparison32FloatSASelect
+ JMP LcomparisonReturn
+
+Lcomparison32FloatAASelect:
+ CMP $0, R1
+ BEQ Lcomparison32FloatAAEQ
+ CMP $1, R1
+ BEQ Lcomparison32FloatAANE
+ CMP $2, R1
+ BEQ Lcomparison32FloatAAGTSelect
+ CMP $3, R1
+ BEQ Lcomparison32FloatAAGESelect
+ JMP LcomparisonReturn
+
+Lcomparison32FloatAAGTSelect:
+ JMP Lcomparison32FloatAAFGT
+
+Lcomparison32FloatAAGESelect:
+ JMP Lcomparison32FloatAAFGE
+
+Lcomparison32FloatASSelect:
+ CMP $0, R1
+ BEQ Lcomparison32FloatASEQ
+ CMP $1, R1
+ BEQ Lcomparison32FloatASNE
+ CMP $2, R1
+ BEQ Lcomparison32FloatASGTSelect
+ CMP $3, R1
+ BEQ Lcomparison32FloatASGESelect
+ JMP LcomparisonReturn
+
+Lcomparison32FloatASGTSelect:
+ JMP Lcomparison32FloatASFGT
+
+Lcomparison32FloatASGESelect:
+ JMP Lcomparison32FloatASFGE
+
+Lcomparison32FloatSASelect:
+ CMP $0, R1
+ BEQ Lcomparison32FloatSAEQ
+ CMP $1, R1
+ BEQ Lcomparison32FloatSANE
+ CMP $2, R1
+ BEQ Lcomparison32FloatSAGTSelect
+ CMP $3, R1
+ BEQ Lcomparison32FloatSAGESelect
+ JMP LcomparisonReturn
+
+Lcomparison32FloatSAGTSelect:
+ JMP Lcomparison32FloatSAFGT
+
+Lcomparison32FloatSAGESelect:
+ JMP Lcomparison32FloatSAFGE
+
+Lcomparison32FloatAAEQ:
+Lcomparison32FloatAAEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x4e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x4e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatAAEQLoop
+
+Lcomparison32FloatAANE:
+Lcomparison32FloatAANELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x4e21e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x4e21e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatAANELoop
+
+Lcomparison32FloatAAFGT:
+Lcomparison32FloatAAFGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea1e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea1e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatAAFGTLoop
+
+Lcomparison32FloatAAFGE:
+Lcomparison32FloatAAFGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.S4]
+ VLD1 (R4), [V1.S4]
+ WORD $0x6e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatAAFGELoop
+
+Lcomparison32FloatASEQ:
+ VLD1R (R4), [V1.S4]
+Lcomparison32FloatASEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ WORD $0x4e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.S4]
+ WORD $0x4e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatASEQLoop
+
+Lcomparison32FloatASNE:
+ VLD1R (R4), [V1.S4]
+Lcomparison32FloatASNELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ WORD $0x4e21e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.S4]
+ WORD $0x4e21e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatASNELoop
+
+Lcomparison32FloatASFGT:
+ VLD1R (R4), [V1.S4]
+Lcomparison32FloatASFGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ WORD $0x6ea1e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.S4]
+ WORD $0x6ea1e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatASFGTLoop
+
+Lcomparison32FloatASFGE:
+ VLD1R (R4), [V1.S4]
+Lcomparison32FloatASFGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.S4]
+ WORD $0x6e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.S4]
+ WORD $0x6e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatASFGELoop
+
+Lcomparison32FloatSAEQ:
+ VLD1R (R3), [V0.S4]
+Lcomparison32FloatSAEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.S4]
+ WORD $0x4e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.S4]
+ WORD $0x4e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatSAEQLoop
+
+Lcomparison32FloatSANE:
+ VLD1R (R3), [V0.S4]
+Lcomparison32FloatSANELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.S4]
+ WORD $0x4e21e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.S4]
+ WORD $0x4e21e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatSANELoop
+
+Lcomparison32FloatSAFGT:
+ VLD1R (R3), [V0.S4]
+Lcomparison32FloatSAFGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea1e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.S4]
+ WORD $0x6ea1e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatSAFGTLoop
+
+Lcomparison32FloatSAFGE:
+ VLD1R (R3), [V0.S4]
+Lcomparison32FloatSAFGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.S4]
+ WORD $0x6e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c47 // umov result
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.S4]
+ WORD $0x6e21e402
+ VUSHR $31, V2.S4, V2.S4
+ WORD $0x4eb49c42 // mul v2.4s, v2.4s, v20.4s
+ VADDV V2.S4, V2
+ WORD $0x0e043c48 // umov result
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison32FloatSAFGELoop
+
+Lcomparison64Float:
+ MOVD $LCMPNEON_WEIGHTS<>(SB), R10
+ ADD $16, R10, R10
+ VLD1 (R10), [V20.D2]
+ CMP $0, R2
+ BEQ Lcomparison64FloatAASelect
+ CMP $1, R2
+ BEQ Lcomparison64FloatASSelect
+ CMP $2, R2
+ BEQ Lcomparison64FloatSASelect
+ JMP LcomparisonReturn
+
+Lcomparison64FloatAASelect:
+ CMP $0, R1
+ BEQ Lcomparison64FloatAAEQ
+ CMP $1, R1
+ BEQ Lcomparison64FloatAANE
+ CMP $2, R1
+ BEQ Lcomparison64FloatAAGTSelect
+ CMP $3, R1
+ BEQ Lcomparison64FloatAAGESelect
+ JMP LcomparisonReturn
+
+Lcomparison64FloatAAGTSelect:
+ JMP Lcomparison64FloatAAFGT
+
+Lcomparison64FloatAAGESelect:
+ JMP Lcomparison64FloatAAFGE
+
+Lcomparison64FloatASSelect:
+ CMP $0, R1
+ BEQ Lcomparison64FloatASEQ
+ CMP $1, R1
+ BEQ Lcomparison64FloatASNE
+ CMP $2, R1
+ BEQ Lcomparison64FloatASGTSelect
+ CMP $3, R1
+ BEQ Lcomparison64FloatASGESelect
+ JMP LcomparisonReturn
+
+Lcomparison64FloatASGTSelect:
+ JMP Lcomparison64FloatASFGT
+
+Lcomparison64FloatASGESelect:
+ JMP Lcomparison64FloatASFGE
+
+Lcomparison64FloatSASelect:
+ CMP $0, R1
+ BEQ Lcomparison64FloatSAEQ
+ CMP $1, R1
+ BEQ Lcomparison64FloatSANE
+ CMP $2, R1
+ BEQ Lcomparison64FloatSAGTSelect
+ CMP $3, R1
+ BEQ Lcomparison64FloatSAGESelect
+ JMP LcomparisonReturn
+
+Lcomparison64FloatSAGTSelect:
+ JMP Lcomparison64FloatSAFGT
+
+Lcomparison64FloatSAGESelect:
+ JMP Lcomparison64FloatSAFGE
+
+Lcomparison64FloatAAEQ:
+Lcomparison64FloatAAEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatAAEQLoop
+
+Lcomparison64FloatAANE:
+Lcomparison64FloatAANELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatAANELoop
+
+Lcomparison64FloatAAFGT:
+Lcomparison64FloatAAFGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatAAFGTLoop
+
+Lcomparison64FloatAAFGE:
+Lcomparison64FloatAAFGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ VLD1 (R3), [V0.D2]
+ VLD1 (R4), [V1.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatAAFGELoop
+
+Lcomparison64FloatASEQ:
+ VLD1R (R4), [V1.D2]
+Lcomparison64FloatASEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatASEQLoop
+
+Lcomparison64FloatASNE:
+ VLD1R (R4), [V1.D2]
+Lcomparison64FloatASNELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatASNELoop
+
+Lcomparison64FloatASFGT:
+ VLD1R (R4), [V1.D2]
+Lcomparison64FloatASFGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatASFGTLoop
+
+Lcomparison64FloatASFGE:
+ VLD1R (R4), [V1.D2]
+Lcomparison64FloatASFGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R3), [V0.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R3, R3
+ VLD1 (R3), [V0.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R3, R3
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatASFGELoop
+
+Lcomparison64FloatSAEQ:
+ VLD1R (R3), [V0.D2]
+Lcomparison64FloatSAEQLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatSAEQLoop
+
+Lcomparison64FloatSANE:
+ VLD1R (R3), [V0.D2]
+Lcomparison64FloatSANELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x4e61e402
+ WORD $0x6e205842 // mvn v2.16b, v2.16b
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatSANELoop
+
+Lcomparison64FloatSAFGT:
+ VLD1R (R3), [V0.D2]
+Lcomparison64FloatSAFGTLoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6ee1e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatSAFGTLoop
+
+Lcomparison64FloatSAFGE:
+ VLD1R (R3), [V0.D2]
+Lcomparison64FloatSAFGELoop:
+ CMP $0, R6
+ BEQ LcomparisonReturn
+ VLD1 (R4), [V1.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c47 // umov x7, v2.d[0]
+ WORD $0x4e183c48 // umov x8, v2.d[1]
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $2, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $4, R8, R8
+ ORR R8, R7, R7
+ ADD $16, R4, R4
+ VLD1 (R4), [V1.D2]
+ WORD $0x6e61e402
+ VUSHR $63, V2.D2, V2.D2
+ WORD $0x6ef44442 // ushl v2.2d, v2.2d, v20.2d
+ WORD $0x4e083c48 // umov x8, v2.d[0]
+ WORD $0x4e183c49 // umov x9, v2.d[1]
+ ORR R9, R8, R8
+ LSL $6, R8, R8
+ ORR R8, R7, R7
+ MOVB R7, (R5)
+ ADD $16, R4, R4
+ ADD $1, R5, R5
+ SUB $1, R6, R6
+ JMP Lcomparison64FloatSAFGELoop
+
+LcomparisonReturn:
+ RET
diff --git a/arrow/compute/internal/kernels/scalar_comparison_arm64_test.go
b/arrow/compute/internal/kernels/scalar_comparison_arm64_test.go
new file mode 100644
index 00000000..460d8aca
--- /dev/null
+++ b/arrow/compute/internal/kernels/scalar_comparison_arm64_test.go
@@ -0,0 +1,210 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build go1.18 && arm64 && !noasm && !appengine
+
+package kernels
+
+import (
+ "bytes"
+ "fmt"
+ "math"
+ "testing"
+ "unsafe"
+
+ "github.com/apache/arrow-go/v18/arrow"
+ "github.com/apache/arrow-go/v18/arrow/bitutil"
+)
+
+const neonComparisonTestLength = 1024
+
+func testNeonComparison[T arrow.NumericType](t *testing.T, left, right []T,
leftScalar, rightScalar T) {
+ t.Helper()
+
+ operations := []struct {
+ name string
+ op CompareOperator
+ }{
+ {"equal", CmpEQ},
+ {"not_equal", CmpNE},
+ {"greater", CmpGT},
+ {"greater_equal", CmpGE},
+ }
+
+ leftBytes := arrow.GetBytes(left)
+ rightBytes := arrow.GetBytes(right)
+ leftScalarBytes := arrow.GetBytes([]T{leftScalar})
+ rightScalarBytes := arrow.GetBytes([]T{rightScalar})
+ width := int(unsafe.Sizeof(T(0)))
+ lengths := []int{0, 1, 2, 7, 8, 9, 15, 16, 17, 23, 24, 25, 31, 32, 33,
63, 64, 65, 127, 128, 129, neonComparisonTestLength}
+
+ for _, operation := range operations {
+ t.Run(operation.name, func(t *testing.T) {
+ cmp := genCompareKernel[T](operation.op)
+ fallback :=
genGoCompareKernel(getCmpOp[T](operation.op))
+ for _, shape := range []string{"array_array",
"array_scalar", "scalar_array"} {
+ t.Run(shape, func(t *testing.T) {
+ for offset := 0; offset < 8; offset++ {
+ for _, length := range lengths {
+
t.Run(fmt.Sprintf("offset_%d/length_%d", offset, length), func(t *testing.T) {
+ out :=
bytes.Repeat([]byte{0xa5}, int(bitutil.BytesForBits(int64(offset+length))))
+ expected :=
append([]byte(nil), out...)
+
+ switch shape {
+ case
"array_array":
+
fallback.funcAA(leftBytes[:length*width], rightBytes[:length*width], expected,
offset)
+ case
"array_scalar":
+
fallback.funcAS(leftBytes[:length*width], rightScalarBytes, expected, offset)
+ case
"scalar_array":
+
fallback.funcSA(leftScalarBytes, rightBytes[:length*width], expected, offset)
+ }
+
+ switch shape {
+ case
"array_array":
+
cmp.funcAA(leftBytes[:length*width], rightBytes[:length*width], out, offset)
+ case
"array_scalar":
+
cmp.funcAS(leftBytes[:length*width], rightScalarBytes, out, offset)
+ case
"scalar_array":
+
cmp.funcSA(leftScalarBytes, rightBytes[:length*width], out, offset)
+ }
+
+ if
!bytes.Equal(expected, out) {
+
t.Fatalf("expected %08b, got %08b", expected, out)
+ }
+ })
+ }
+ }
+ })
+ }
+ })
+ }
+}
+
+func TestNeonComparisons(t *testing.T) {
+ t.Run("int32", func(t *testing.T) {
+ leftPattern := []int32{-1 << 31, -17, -1, 0, 1, 17, 1<<31 - 1,
42, -42, 3, 9, -9, 5, -5, 2, -2}
+ rightPattern := []int32{1<<31 - 1, -17, 0, 1, -1, -42, -1 <<
31, 42, 4, -3, 9, -10, -5, 5, -2, 2}
+ left := make([]int32, neonComparisonTestLength)
+ right := make([]int32, neonComparisonTestLength)
+ for i := range left {
+ left[i] = leftPattern[i%len(leftPattern)]
+ right[i] = rightPattern[i%len(rightPattern)]
+ }
+ testNeonComparison(t, left, right, int32(-3), int32(4))
+ })
+
+ t.Run("uint32", func(t *testing.T) {
+ leftPattern := []uint32{0, 1, 2, 1<<31 - 1, 1 << 31,
^uint32(0), 42, 7, 100, 3, 19, 5, 77, 11, 12, 13}
+ rightPattern := []uint32{^uint32(0), 1, 3, 1 << 31, 1<<31 - 1,
0, 42, 8, 99, 4, 19, 6, 78, 10, 13, 12}
+ left := make([]uint32, neonComparisonTestLength)
+ right := make([]uint32, neonComparisonTestLength)
+ for i := range left {
+ left[i] = leftPattern[i%len(leftPattern)]
+ right[i] = rightPattern[i%len(rightPattern)]
+ }
+ testNeonComparison(t, left, right, uint32(1<<31), uint32(7))
+ })
+
+ t.Run("int64", func(t *testing.T) {
+ leftPattern := []int64{-1 << 63, -17, -1, 0, 1, 17, 1<<63 - 1,
42, -42, 3, 9, -9, 5, -5, 2, -2}
+ rightPattern := []int64{1<<63 - 1, -17, 0, 1, -1, -42, -1 <<
63, 42, 4, -3, 9, -10, -5, 5, -2, 2}
+ left := make([]int64, neonComparisonTestLength)
+ right := make([]int64, neonComparisonTestLength)
+ for i := range left {
+ left[i] = leftPattern[i%len(leftPattern)]
+ right[i] = rightPattern[i%len(rightPattern)]
+ }
+ testNeonComparison(t, left, right, int64(-3), int64(4))
+ })
+
+ t.Run("uint64", func(t *testing.T) {
+ leftPattern := []uint64{0, 1, 2, 1<<63 - 1, 1 << 63,
^uint64(0), 42, 7, 100, 3, 19, 5, 77, 11, 12, 13}
+ rightPattern := []uint64{^uint64(0), 1, 3, 1 << 63, 1<<63 - 1,
0, 42, 8, 99, 4, 19, 6, 78, 10, 13, 12}
+ left := make([]uint64, neonComparisonTestLength)
+ right := make([]uint64, neonComparisonTestLength)
+ for i := range left {
+ left[i] = leftPattern[i%len(leftPattern)]
+ right[i] = rightPattern[i%len(rightPattern)]
+ }
+ testNeonComparison(t, left, right, uint64(1<<63), uint64(7))
+ })
+
+ t.Run("float32", func(t *testing.T) {
+ leftPattern := []float32{float32(math.NaN()),
float32(math.Inf(-1)), -1.5, float32(math.Copysign(0, -1)), 0, 1.5,
float32(math.Inf(1)), float32(math.NaN())}
+ rightPattern := []float32{float32(math.NaN()),
-float32(math.Inf(1)), -1.5, 0, float32(math.Copysign(0, -1)), 2.5,
float32(math.Inf(1)), 3}
+ left := make([]float32, neonComparisonTestLength)
+ right := make([]float32, neonComparisonTestLength)
+ for i := range left {
+ left[i] = leftPattern[i%len(leftPattern)]
+ right[i] = rightPattern[i%len(rightPattern)]
+ }
+ testNeonComparison(t, left, right, float32(math.NaN()),
float32(1.5))
+ })
+
+ t.Run("float64", func(t *testing.T) {
+ leftPattern := []float64{math.NaN(), math.Inf(-1), -1.5,
math.Copysign(0, -1), 0, 1.5, math.Inf(1), math.NaN()}
+ rightPattern := []float64{math.NaN(), -math.Inf(1), -1.5, 0,
math.Copysign(0, -1), 2.5, math.Inf(1), 3}
+ left := make([]float64, neonComparisonTestLength)
+ right := make([]float64, neonComparisonTestLength)
+ for i := range left {
+ left[i] = leftPattern[i%len(leftPattern)]
+ right[i] = rightPattern[i%len(rightPattern)]
+ }
+ testNeonComparison(t, left, right, math.NaN(), 1.5)
+ })
+}
+
+func TestNeonComparisonBitPacking(t *testing.T) {
+ t.Run("int32", testNeonComparisonBitPacking[int32])
+ t.Run("uint32", testNeonComparisonBitPacking[uint32])
+ t.Run("int64", testNeonComparisonBitPacking[int64])
+ t.Run("uint64", testNeonComparisonBitPacking[uint64])
+ t.Run("float32", testNeonComparisonBitPacking[float32])
+ t.Run("float64", testNeonComparisonBitPacking[float64])
+}
+
+func testNeonComparisonBitPacking[T arrow.NumericType](t *testing.T) {
+ const n = 256 * 8
+ left, right := make([]T, n), make([]T, n)
+ for mask := 0; mask < 256; mask++ {
+ for bit := 0; bit < 8; bit++ {
+ left[mask*8+bit] = T(mask >> bit & 1)
+ right[mask*8+bit] = T(mask >> (7 - bit) & 1)
+ }
+ }
+ leftBytes, rightBytes := arrow.GetBytes(left), arrow.GetBytes(right)
+ scalar := arrow.GetBytes([]T{0})
+ for _, op := range []CompareOperator{CmpEQ, CmpNE, CmpGT, CmpGE} {
+ got, want := genCompareKernel[T](op),
genGoCompareKernel(getCmpOp[T](op))
+ for _, shape := range []struct {
+ name string
+ got, want binaryKernel
+ left, right []byte
+ }{
+ {"array_array", got.funcAA, want.funcAA, leftBytes,
rightBytes},
+ {"array_scalar", got.funcAS, want.funcAS, leftBytes,
scalar},
+ {"scalar_array", got.funcSA, want.funcSA, scalar,
rightBytes},
+ } {
+ output := bytes.Repeat([]byte{0xa5}, n/8+2)
+ expected := bytes.Clone(output)
+ shape.want(shape.left, shape.right,
expected[1:len(expected)-1], 0)
+ shape.got(shape.left, shape.right,
output[1:len(output)-1], 0)
+ if !bytes.Equal(output, expected) {
+ t.Fatalf("%s %s: expected %08b, got %08b", op,
shape.name, expected, output)
+ }
+ }
+ }
+}
diff --git a/arrow/compute/internal/kernels/scalar_comparison_noasm.go
b/arrow/compute/internal/kernels/scalar_comparison_noasm.go
index 61966769..c94ec537 100644
--- a/arrow/compute/internal/kernels/scalar_comparison_noasm.go
+++ b/arrow/compute/internal/kernels/scalar_comparison_noasm.go
@@ -14,7 +14,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-//go:build go1.18 && (noasm || !amd64)
+//go:build go1.18 && (noasm || (!amd64 && !arm64) || (appengine && arm64))
package kernels