1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 * 16 * Copyright (C) IBM Corporation, 2012 17 * 18 * Author: Anton Blanchard <anton@au.ibm.com> 19 */ 20 21 /* 22 * Sparse (as at v0.5.0) gets very, very confused by this file. 23 * Make it a bit simpler for it. 24 */ 25 #if !defined(__CHECKER__) 26 #include <altivec.h> 27 #else 28 #define vec_xor(a, b) a ^ b 29 #define vector __attribute__((vector_size(16))) 30 #endif 31 32 #include <linux/preempt.h> 33 #include <linux/export.h> 34 #include <linux/sched.h> 35 #include <asm/switch_to.h> 36 37 typedef vector signed char unative_t; 38 39 #define DEFINE(V) \ 40 unative_t *V = (unative_t *)V##_in; \ 41 unative_t V##_0, V##_1, V##_2, V##_3 42 43 #define LOAD(V) \ 44 do { \ 45 V##_0 = V[0]; \ 46 V##_1 = V[1]; \ 47 V##_2 = V[2]; \ 48 V##_3 = V[3]; \ 49 } while (0) 50 51 #define STORE(V) \ 52 do { \ 53 V[0] = V##_0; \ 54 V[1] = V##_1; \ 55 V[2] = V##_2; \ 56 V[3] = V##_3; \ 57 } while (0) 58 59 #define XOR(V1, V2) \ 60 do { \ 61 V1##_0 = vec_xor(V1##_0, V2##_0); \ 62 V1##_1 = vec_xor(V1##_1, V2##_1); \ 63 V1##_2 = vec_xor(V1##_2, V2##_2); \ 64 V1##_3 = vec_xor(V1##_3, V2##_3); \ 65 } while (0) 66 67 void xor_altivec_2(unsigned long bytes, unsigned long *v1_in, 68 unsigned long *v2_in) 69 { 70 DEFINE(v1); 71 DEFINE(v2); 72 unsigned long lines = bytes / (sizeof(unative_t)) / 4; 73 74 preempt_disable(); 75 enable_kernel_altivec(); 76 77 do { 78 LOAD(v1); 79 LOAD(v2); 80 XOR(v1, v2); 81 STORE(v1); 82 83 v1 += 4; 84 v2 += 4; 85 } while (--lines > 0); 86 87 disable_kernel_altivec(); 88 preempt_enable(); 89 } 90 EXPORT_SYMBOL(xor_altivec_2); 91 92 void xor_altivec_3(unsigned long bytes, unsigned long *v1_in, 93 unsigned long *v2_in, unsigned long *v3_in) 94 { 95 DEFINE(v1); 96 DEFINE(v2); 97 DEFINE(v3); 98 unsigned long lines = bytes / (sizeof(unative_t)) / 4; 99 100 preempt_disable(); 101 enable_kernel_altivec(); 102 103 do { 104 LOAD(v1); 105 LOAD(v2); 106 LOAD(v3); 107 XOR(v1, v2); 108 XOR(v1, v3); 109 STORE(v1); 110 111 v1 += 4; 112 v2 += 4; 113 v3 += 4; 114 } while (--lines > 0); 115 116 disable_kernel_altivec(); 117 preempt_enable(); 118 } 119 EXPORT_SYMBOL(xor_altivec_3); 120 121 void xor_altivec_4(unsigned long bytes, unsigned long *v1_in, 122 unsigned long *v2_in, unsigned long *v3_in, 123 unsigned long *v4_in) 124 { 125 DEFINE(v1); 126 DEFINE(v2); 127 DEFINE(v3); 128 DEFINE(v4); 129 unsigned long lines = bytes / (sizeof(unative_t)) / 4; 130 131 preempt_disable(); 132 enable_kernel_altivec(); 133 134 do { 135 LOAD(v1); 136 LOAD(v2); 137 LOAD(v3); 138 LOAD(v4); 139 XOR(v1, v2); 140 XOR(v3, v4); 141 XOR(v1, v3); 142 STORE(v1); 143 144 v1 += 4; 145 v2 += 4; 146 v3 += 4; 147 v4 += 4; 148 } while (--lines > 0); 149 150 disable_kernel_altivec(); 151 preempt_enable(); 152 } 153 EXPORT_SYMBOL(xor_altivec_4); 154 155 void xor_altivec_5(unsigned long bytes, unsigned long *v1_in, 156 unsigned long *v2_in, unsigned long *v3_in, 157 unsigned long *v4_in, unsigned long *v5_in) 158 { 159 DEFINE(v1); 160 DEFINE(v2); 161 DEFINE(v3); 162 DEFINE(v4); 163 DEFINE(v5); 164 unsigned long lines = bytes / (sizeof(unative_t)) / 4; 165 166 preempt_disable(); 167 enable_kernel_altivec(); 168 169 do { 170 LOAD(v1); 171 LOAD(v2); 172 LOAD(v3); 173 LOAD(v4); 174 LOAD(v5); 175 XOR(v1, v2); 176 XOR(v3, v4); 177 XOR(v1, v5); 178 XOR(v1, v3); 179 STORE(v1); 180 181 v1 += 4; 182 v2 += 4; 183 v3 += 4; 184 v4 += 4; 185 v5 += 4; 186 } while (--lines > 0); 187 188 disable_kernel_altivec(); 189 preempt_enable(); 190 } 191 EXPORT_SYMBOL(xor_altivec_5); 192