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