13f276cecSChristoph Hellwig // SPDX-License-Identifier: GPL-2.0-or-later 23f276cecSChristoph Hellwig /* 33f276cecSChristoph Hellwig * 43f276cecSChristoph Hellwig * Copyright (C) IBM Corporation, 2012 53f276cecSChristoph Hellwig * 63f276cecSChristoph Hellwig * Author: Anton Blanchard <anton@au.ibm.com> 73f276cecSChristoph Hellwig */ 83f276cecSChristoph Hellwig 93f276cecSChristoph Hellwig /* 103f276cecSChristoph Hellwig * Sparse (as at v0.5.0) gets very, very confused by this file. 113f276cecSChristoph Hellwig * Make it a bit simpler for it. 123f276cecSChristoph Hellwig */ 13*80dcf0a7SChristoph Hellwig #include "xor_impl.h" 143f276cecSChristoph Hellwig #if !defined(__CHECKER__) 153f276cecSChristoph Hellwig #include <altivec.h> 163f276cecSChristoph Hellwig #else 173f276cecSChristoph Hellwig #define vec_xor(a, b) a ^ b 183f276cecSChristoph Hellwig #define vector __attribute__((vector_size(16))) 193f276cecSChristoph Hellwig #endif 203f276cecSChristoph Hellwig 213f276cecSChristoph Hellwig #include "xor_vmx.h" 223f276cecSChristoph Hellwig 233f276cecSChristoph Hellwig typedef vector signed char unative_t; 243f276cecSChristoph Hellwig 253f276cecSChristoph Hellwig #define DEFINE(V) \ 263f276cecSChristoph Hellwig unative_t *V = (unative_t *)V##_in; \ 273f276cecSChristoph Hellwig unative_t V##_0, V##_1, V##_2, V##_3 283f276cecSChristoph Hellwig 293f276cecSChristoph Hellwig #define LOAD(V) \ 303f276cecSChristoph Hellwig do { \ 313f276cecSChristoph Hellwig V##_0 = V[0]; \ 323f276cecSChristoph Hellwig V##_1 = V[1]; \ 333f276cecSChristoph Hellwig V##_2 = V[2]; \ 343f276cecSChristoph Hellwig V##_3 = V[3]; \ 353f276cecSChristoph Hellwig } while (0) 363f276cecSChristoph Hellwig 373f276cecSChristoph Hellwig #define STORE(V) \ 383f276cecSChristoph Hellwig do { \ 393f276cecSChristoph Hellwig V[0] = V##_0; \ 403f276cecSChristoph Hellwig V[1] = V##_1; \ 413f276cecSChristoph Hellwig V[2] = V##_2; \ 423f276cecSChristoph Hellwig V[3] = V##_3; \ 433f276cecSChristoph Hellwig } while (0) 443f276cecSChristoph Hellwig 453f276cecSChristoph Hellwig #define XOR(V1, V2) \ 463f276cecSChristoph Hellwig do { \ 473f276cecSChristoph Hellwig V1##_0 = vec_xor(V1##_0, V2##_0); \ 483f276cecSChristoph Hellwig V1##_1 = vec_xor(V1##_1, V2##_1); \ 493f276cecSChristoph Hellwig V1##_2 = vec_xor(V1##_2, V2##_2); \ 503f276cecSChristoph Hellwig V1##_3 = vec_xor(V1##_3, V2##_3); \ 513f276cecSChristoph Hellwig } while (0) 523f276cecSChristoph Hellwig 53*80dcf0a7SChristoph Hellwig static void __xor_altivec_2(unsigned long bytes, 543f276cecSChristoph Hellwig unsigned long * __restrict v1_in, 553f276cecSChristoph Hellwig const unsigned long * __restrict v2_in) 563f276cecSChristoph Hellwig { 573f276cecSChristoph Hellwig DEFINE(v1); 583f276cecSChristoph Hellwig DEFINE(v2); 593f276cecSChristoph Hellwig unsigned long lines = bytes / (sizeof(unative_t)) / 4; 603f276cecSChristoph Hellwig 613f276cecSChristoph Hellwig do { 623f276cecSChristoph Hellwig LOAD(v1); 633f276cecSChristoph Hellwig LOAD(v2); 643f276cecSChristoph Hellwig XOR(v1, v2); 653f276cecSChristoph Hellwig STORE(v1); 663f276cecSChristoph Hellwig 673f276cecSChristoph Hellwig v1 += 4; 683f276cecSChristoph Hellwig v2 += 4; 693f276cecSChristoph Hellwig } while (--lines > 0); 703f276cecSChristoph Hellwig } 713f276cecSChristoph Hellwig 72*80dcf0a7SChristoph Hellwig static void __xor_altivec_3(unsigned long bytes, 733f276cecSChristoph Hellwig unsigned long * __restrict v1_in, 743f276cecSChristoph Hellwig const unsigned long * __restrict v2_in, 753f276cecSChristoph Hellwig const unsigned long * __restrict v3_in) 763f276cecSChristoph Hellwig { 773f276cecSChristoph Hellwig DEFINE(v1); 783f276cecSChristoph Hellwig DEFINE(v2); 793f276cecSChristoph Hellwig DEFINE(v3); 803f276cecSChristoph Hellwig unsigned long lines = bytes / (sizeof(unative_t)) / 4; 813f276cecSChristoph Hellwig 823f276cecSChristoph Hellwig do { 833f276cecSChristoph Hellwig LOAD(v1); 843f276cecSChristoph Hellwig LOAD(v2); 853f276cecSChristoph Hellwig LOAD(v3); 863f276cecSChristoph Hellwig XOR(v1, v2); 873f276cecSChristoph Hellwig XOR(v1, v3); 883f276cecSChristoph Hellwig STORE(v1); 893f276cecSChristoph Hellwig 903f276cecSChristoph Hellwig v1 += 4; 913f276cecSChristoph Hellwig v2 += 4; 923f276cecSChristoph Hellwig v3 += 4; 933f276cecSChristoph Hellwig } while (--lines > 0); 943f276cecSChristoph Hellwig } 953f276cecSChristoph Hellwig 96*80dcf0a7SChristoph Hellwig static void __xor_altivec_4(unsigned long bytes, 973f276cecSChristoph Hellwig unsigned long * __restrict v1_in, 983f276cecSChristoph Hellwig const unsigned long * __restrict v2_in, 993f276cecSChristoph Hellwig const unsigned long * __restrict v3_in, 1003f276cecSChristoph Hellwig const unsigned long * __restrict v4_in) 1013f276cecSChristoph Hellwig { 1023f276cecSChristoph Hellwig DEFINE(v1); 1033f276cecSChristoph Hellwig DEFINE(v2); 1043f276cecSChristoph Hellwig DEFINE(v3); 1053f276cecSChristoph Hellwig DEFINE(v4); 1063f276cecSChristoph Hellwig unsigned long lines = bytes / (sizeof(unative_t)) / 4; 1073f276cecSChristoph Hellwig 1083f276cecSChristoph Hellwig do { 1093f276cecSChristoph Hellwig LOAD(v1); 1103f276cecSChristoph Hellwig LOAD(v2); 1113f276cecSChristoph Hellwig LOAD(v3); 1123f276cecSChristoph Hellwig LOAD(v4); 1133f276cecSChristoph Hellwig XOR(v1, v2); 1143f276cecSChristoph Hellwig XOR(v3, v4); 1153f276cecSChristoph Hellwig XOR(v1, v3); 1163f276cecSChristoph Hellwig STORE(v1); 1173f276cecSChristoph Hellwig 1183f276cecSChristoph Hellwig v1 += 4; 1193f276cecSChristoph Hellwig v2 += 4; 1203f276cecSChristoph Hellwig v3 += 4; 1213f276cecSChristoph Hellwig v4 += 4; 1223f276cecSChristoph Hellwig } while (--lines > 0); 1233f276cecSChristoph Hellwig } 1243f276cecSChristoph Hellwig 125*80dcf0a7SChristoph Hellwig static void __xor_altivec_5(unsigned long bytes, 1263f276cecSChristoph Hellwig unsigned long * __restrict v1_in, 1273f276cecSChristoph Hellwig const unsigned long * __restrict v2_in, 1283f276cecSChristoph Hellwig const unsigned long * __restrict v3_in, 1293f276cecSChristoph Hellwig const unsigned long * __restrict v4_in, 1303f276cecSChristoph Hellwig const unsigned long * __restrict v5_in) 1313f276cecSChristoph Hellwig { 1323f276cecSChristoph Hellwig DEFINE(v1); 1333f276cecSChristoph Hellwig DEFINE(v2); 1343f276cecSChristoph Hellwig DEFINE(v3); 1353f276cecSChristoph Hellwig DEFINE(v4); 1363f276cecSChristoph Hellwig DEFINE(v5); 1373f276cecSChristoph Hellwig unsigned long lines = bytes / (sizeof(unative_t)) / 4; 1383f276cecSChristoph Hellwig 1393f276cecSChristoph Hellwig do { 1403f276cecSChristoph Hellwig LOAD(v1); 1413f276cecSChristoph Hellwig LOAD(v2); 1423f276cecSChristoph Hellwig LOAD(v3); 1433f276cecSChristoph Hellwig LOAD(v4); 1443f276cecSChristoph Hellwig LOAD(v5); 1453f276cecSChristoph Hellwig XOR(v1, v2); 1463f276cecSChristoph Hellwig XOR(v3, v4); 1473f276cecSChristoph Hellwig XOR(v1, v5); 1483f276cecSChristoph Hellwig XOR(v1, v3); 1493f276cecSChristoph Hellwig STORE(v1); 1503f276cecSChristoph Hellwig 1513f276cecSChristoph Hellwig v1 += 4; 1523f276cecSChristoph Hellwig v2 += 4; 1533f276cecSChristoph Hellwig v3 += 4; 1543f276cecSChristoph Hellwig v4 += 4; 1553f276cecSChristoph Hellwig v5 += 4; 1563f276cecSChristoph Hellwig } while (--lines > 0); 1573f276cecSChristoph Hellwig } 158*80dcf0a7SChristoph Hellwig 159*80dcf0a7SChristoph Hellwig __DO_XOR_BLOCKS(altivec_inner, __xor_altivec_2, __xor_altivec_3, 160*80dcf0a7SChristoph Hellwig __xor_altivec_4, __xor_altivec_5); 161