| // 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. | |
| // +build ppc64 ppc64le | |
| #include "textflag.h" | |
| // func xorBytesVSX(dst, a, b *byte, n int) | |
| TEXT ·xorBytesVSX(SB), NOSPLIT, $0 | |
| MOVD dst+0(FP), R3 // R3 = dst | |
| MOVD a+8(FP), R4 // R4 = a | |
| MOVD b+16(FP), R5 // R5 = b | |
| MOVD n+24(FP), R6 // R6 = n | |
| CMPU R6, $32, CR7 // Check if n ≥ 32 bytes | |
| MOVD R0, R8 // R8 = index | |
| CMPU R6, $8, CR6 // Check if 8 ≤ n < 32 bytes | |
| BLT CR6, small // Smaller than 8 | |
| BLT CR7, xor16 // Case for 16 ≤ n < 32 bytes | |
| // Case for n ≥ 32 bytes | |
| preloop32: | |
| SRD $5, R6, R7 // Setup loop counter | |
| MOVD R7, CTR | |
| MOVD $16, R10 | |
| ANDCC $31, R6, R9 // Check for tailing bytes for later | |
| loop32: | |
| LXVD2X (R4)(R8), VS32 // VS32 = a[i,...,i+15] | |
| LXVD2X (R4)(R10), VS34 | |
| LXVD2X (R5)(R8), VS33 // VS33 = b[i,...,i+15] | |
| LXVD2X (R5)(R10), VS35 | |
| XXLXOR VS32, VS33, VS32 // VS34 = a[] ^ b[] | |
| XXLXOR VS34, VS35, VS34 | |
| STXVD2X VS32, (R3)(R8) // Store to dst | |
| STXVD2X VS34, (R3)(R10) | |
| ADD $32, R8 // Update index | |
| ADD $32, R10 | |
| BC 16, 0, loop32 // bdnz loop16 | |
| BEQ CR0, done | |
| MOVD R9, R6 | |
| CMP R6, $8 | |
| BLT small | |
| xor16: | |
| CMP R6, $16 | |
| BLT xor8 | |
| LXVD2X (R4)(R8), VS32 | |
| LXVD2X (R5)(R8), VS33 | |
| XXLXOR VS32, VS33, VS32 | |
| STXVD2X VS32, (R3)(R8) | |
| ADD $16, R8 | |
| ADD $-16, R6 | |
| CMP R6, $8 | |
| BLT small | |
| xor8: | |
| // Case for 8 ≤ n < 16 bytes | |
| MOVD (R4)(R8), R14 // R14 = a[i,...,i+7] | |
| MOVD (R5)(R8), R15 // R15 = b[i,...,i+7] | |
| XOR R14, R15, R16 // R16 = a[] ^ b[] | |
| SUB $8, R6 // n = n - 8 | |
| MOVD R16, (R3)(R8) // Store to dst | |
| ADD $8, R8 | |
| // Check if we're finished | |
| CMP R6, R0 | |
| BGT small | |
| RET | |
| // Case for n < 8 bytes and tailing bytes from the | |
| // previous cases. | |
| small: | |
| CMP R6, R0 | |
| BEQ done | |
| MOVD R6, CTR // Setup loop counter | |
| loop: | |
| MOVBZ (R4)(R8), R14 // R14 = a[i] | |
| MOVBZ (R5)(R8), R15 // R15 = b[i] | |
| XOR R14, R15, R16 // R16 = a[i] ^ b[i] | |
| MOVB R16, (R3)(R8) // Store to dst | |
| ADD $1, R8 | |
| BC 16, 0, loop // bdnz loop | |
| done: | |
| RET |