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 #include <altivec.h> 21 22 #include <linux/preempt.h> 23 #include <linux/export.h> 24 #include <linux/sched.h> 25 #include <asm/switch_to.h> 26 27 typedef vector signed char unative_t; 28 29 #define DEFINE(V) \ 30 unative_t *V = (unative_t *)V##_in; \ 31 unative_t V##_0, V##_1, V##_2, V##_3 32 33 #define LOAD(V) \ 34 do { \ 35 V##_0 = V[0]; \ 36 V##_1 = V[1]; \ 37 V##_2 = V[2]; \ 38 V##_3 = V[3]; \ 39 } while (0) 40 41 #define STORE(V) \ 42 do { \ 43 V[0] = V##_0; \ 44 V[1] = V##_1; \ 45 V[2] = V##_2; \ 46 V[3] = V##_3; \ 47 } while (0) 48 49 #define XOR(V1, V2) \ 50 do { \ 51 V1##_0 = vec_xor(V1##_0, V2##_0); \ 52 V1##_1 = vec_xor(V1##_1, V2##_1); \ 53 V1##_2 = vec_xor(V1##_2, V2##_2); \ 54 V1##_3 = vec_xor(V1##_3, V2##_3); \ 55 } while (0) 56 57 void xor_altivec_2(unsigned long bytes, unsigned long *v1_in, 58 unsigned long *v2_in) 59 { 60 DEFINE(v1); 61 DEFINE(v2); 62 unsigned long lines = bytes / (sizeof(unative_t)) / 4; 63 64 preempt_disable(); 65 enable_kernel_altivec(); 66 67 do { 68 LOAD(v1); 69 LOAD(v2); 70 XOR(v1, v2); 71 STORE(v1); 72 73 v1 += 4; 74 v2 += 4; 75 } while (--lines > 0); 76 77 disable_kernel_altivec(); 78 preempt_enable(); 79 } 80 EXPORT_SYMBOL(xor_altivec_2); 81 82 void xor_altivec_3(unsigned long bytes, unsigned long *v1_in, 83 unsigned long *v2_in, unsigned long *v3_in) 84 { 85 DEFINE(v1); 86 DEFINE(v2); 87 DEFINE(v3); 88 unsigned long lines = bytes / (sizeof(unative_t)) / 4; 89 90 preempt_disable(); 91 enable_kernel_altivec(); 92 93 do { 94 LOAD(v1); 95 LOAD(v2); 96 LOAD(v3); 97 XOR(v1, v2); 98 XOR(v1, v3); 99 STORE(v1); 100 101 v1 += 4; 102 v2 += 4; 103 v3 += 4; 104 } while (--lines > 0); 105 106 disable_kernel_altivec(); 107 preempt_enable(); 108 } 109 EXPORT_SYMBOL(xor_altivec_3); 110 111 void xor_altivec_4(unsigned long bytes, unsigned long *v1_in, 112 unsigned long *v2_in, unsigned long *v3_in, 113 unsigned long *v4_in) 114 { 115 DEFINE(v1); 116 DEFINE(v2); 117 DEFINE(v3); 118 DEFINE(v4); 119 unsigned long lines = bytes / (sizeof(unative_t)) / 4; 120 121 preempt_disable(); 122 enable_kernel_altivec(); 123 124 do { 125 LOAD(v1); 126 LOAD(v2); 127 LOAD(v3); 128 LOAD(v4); 129 XOR(v1, v2); 130 XOR(v3, v4); 131 XOR(v1, v3); 132 STORE(v1); 133 134 v1 += 4; 135 v2 += 4; 136 v3 += 4; 137 v4 += 4; 138 } while (--lines > 0); 139 140 disable_kernel_altivec(); 141 preempt_enable(); 142 } 143 EXPORT_SYMBOL(xor_altivec_4); 144 145 void xor_altivec_5(unsigned long bytes, unsigned long *v1_in, 146 unsigned long *v2_in, unsigned long *v3_in, 147 unsigned long *v4_in, unsigned long *v5_in) 148 { 149 DEFINE(v1); 150 DEFINE(v2); 151 DEFINE(v3); 152 DEFINE(v4); 153 DEFINE(v5); 154 unsigned long lines = bytes / (sizeof(unative_t)) / 4; 155 156 preempt_disable(); 157 enable_kernel_altivec(); 158 159 do { 160 LOAD(v1); 161 LOAD(v2); 162 LOAD(v3); 163 LOAD(v4); 164 LOAD(v5); 165 XOR(v1, v2); 166 XOR(v3, v4); 167 XOR(v1, v5); 168 XOR(v1, v3); 169 STORE(v1); 170 171 v1 += 4; 172 v2 += 4; 173 v3 += 4; 174 v4 += 4; 175 v5 += 4; 176 } while (--lines > 0); 177 178 disable_kernel_altivec(); 179 preempt_enable(); 180 } 181 EXPORT_SYMBOL(xor_altivec_5); 182