1 /* 2 * include/asm/xor.h 3 * 4 * Optimized RAID-5 checksumming functions for 32-bit Sparc. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2, or (at your option) 9 * any later version. 10 * 11 * You should have received a copy of the GNU General Public License 12 * (for example /usr/src/linux/COPYING); if not, write to the Free 13 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 14 */ 15 16 /* 17 * High speed xor_block operation for RAID4/5 utilizing the 18 * ldd/std SPARC instructions. 19 * 20 * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz) 21 */ 22 23 static void 24 sparc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) 25 { 26 int lines = bytes / (sizeof (long)) / 8; 27 28 do { 29 __asm__ __volatile__( 30 "ldd [%0 + 0x00], %%g2\n\t" 31 "ldd [%0 + 0x08], %%g4\n\t" 32 "ldd [%0 + 0x10], %%o0\n\t" 33 "ldd [%0 + 0x18], %%o2\n\t" 34 "ldd [%1 + 0x00], %%o4\n\t" 35 "ldd [%1 + 0x08], %%l0\n\t" 36 "ldd [%1 + 0x10], %%l2\n\t" 37 "ldd [%1 + 0x18], %%l4\n\t" 38 "xor %%g2, %%o4, %%g2\n\t" 39 "xor %%g3, %%o5, %%g3\n\t" 40 "xor %%g4, %%l0, %%g4\n\t" 41 "xor %%g5, %%l1, %%g5\n\t" 42 "xor %%o0, %%l2, %%o0\n\t" 43 "xor %%o1, %%l3, %%o1\n\t" 44 "xor %%o2, %%l4, %%o2\n\t" 45 "xor %%o3, %%l5, %%o3\n\t" 46 "std %%g2, [%0 + 0x00]\n\t" 47 "std %%g4, [%0 + 0x08]\n\t" 48 "std %%o0, [%0 + 0x10]\n\t" 49 "std %%o2, [%0 + 0x18]\n" 50 : 51 : "r" (p1), "r" (p2) 52 : "g2", "g3", "g4", "g5", 53 "o0", "o1", "o2", "o3", "o4", "o5", 54 "l0", "l1", "l2", "l3", "l4", "l5"); 55 p1 += 8; 56 p2 += 8; 57 } while (--lines > 0); 58 } 59 60 static void 61 sparc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, 62 unsigned long *p3) 63 { 64 int lines = bytes / (sizeof (long)) / 8; 65 66 do { 67 __asm__ __volatile__( 68 "ldd [%0 + 0x00], %%g2\n\t" 69 "ldd [%0 + 0x08], %%g4\n\t" 70 "ldd [%0 + 0x10], %%o0\n\t" 71 "ldd [%0 + 0x18], %%o2\n\t" 72 "ldd [%1 + 0x00], %%o4\n\t" 73 "ldd [%1 + 0x08], %%l0\n\t" 74 "ldd [%1 + 0x10], %%l2\n\t" 75 "ldd [%1 + 0x18], %%l4\n\t" 76 "xor %%g2, %%o4, %%g2\n\t" 77 "xor %%g3, %%o5, %%g3\n\t" 78 "ldd [%2 + 0x00], %%o4\n\t" 79 "xor %%g4, %%l0, %%g4\n\t" 80 "xor %%g5, %%l1, %%g5\n\t" 81 "ldd [%2 + 0x08], %%l0\n\t" 82 "xor %%o0, %%l2, %%o0\n\t" 83 "xor %%o1, %%l3, %%o1\n\t" 84 "ldd [%2 + 0x10], %%l2\n\t" 85 "xor %%o2, %%l4, %%o2\n\t" 86 "xor %%o3, %%l5, %%o3\n\t" 87 "ldd [%2 + 0x18], %%l4\n\t" 88 "xor %%g2, %%o4, %%g2\n\t" 89 "xor %%g3, %%o5, %%g3\n\t" 90 "xor %%g4, %%l0, %%g4\n\t" 91 "xor %%g5, %%l1, %%g5\n\t" 92 "xor %%o0, %%l2, %%o0\n\t" 93 "xor %%o1, %%l3, %%o1\n\t" 94 "xor %%o2, %%l4, %%o2\n\t" 95 "xor %%o3, %%l5, %%o3\n\t" 96 "std %%g2, [%0 + 0x00]\n\t" 97 "std %%g4, [%0 + 0x08]\n\t" 98 "std %%o0, [%0 + 0x10]\n\t" 99 "std %%o2, [%0 + 0x18]\n" 100 : 101 : "r" (p1), "r" (p2), "r" (p3) 102 : "g2", "g3", "g4", "g5", 103 "o0", "o1", "o2", "o3", "o4", "o5", 104 "l0", "l1", "l2", "l3", "l4", "l5"); 105 p1 += 8; 106 p2 += 8; 107 p3 += 8; 108 } while (--lines > 0); 109 } 110 111 static void 112 sparc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, 113 unsigned long *p3, unsigned long *p4) 114 { 115 int lines = bytes / (sizeof (long)) / 8; 116 117 do { 118 __asm__ __volatile__( 119 "ldd [%0 + 0x00], %%g2\n\t" 120 "ldd [%0 + 0x08], %%g4\n\t" 121 "ldd [%0 + 0x10], %%o0\n\t" 122 "ldd [%0 + 0x18], %%o2\n\t" 123 "ldd [%1 + 0x00], %%o4\n\t" 124 "ldd [%1 + 0x08], %%l0\n\t" 125 "ldd [%1 + 0x10], %%l2\n\t" 126 "ldd [%1 + 0x18], %%l4\n\t" 127 "xor %%g2, %%o4, %%g2\n\t" 128 "xor %%g3, %%o5, %%g3\n\t" 129 "ldd [%2 + 0x00], %%o4\n\t" 130 "xor %%g4, %%l0, %%g4\n\t" 131 "xor %%g5, %%l1, %%g5\n\t" 132 "ldd [%2 + 0x08], %%l0\n\t" 133 "xor %%o0, %%l2, %%o0\n\t" 134 "xor %%o1, %%l3, %%o1\n\t" 135 "ldd [%2 + 0x10], %%l2\n\t" 136 "xor %%o2, %%l4, %%o2\n\t" 137 "xor %%o3, %%l5, %%o3\n\t" 138 "ldd [%2 + 0x18], %%l4\n\t" 139 "xor %%g2, %%o4, %%g2\n\t" 140 "xor %%g3, %%o5, %%g3\n\t" 141 "ldd [%3 + 0x00], %%o4\n\t" 142 "xor %%g4, %%l0, %%g4\n\t" 143 "xor %%g5, %%l1, %%g5\n\t" 144 "ldd [%3 + 0x08], %%l0\n\t" 145 "xor %%o0, %%l2, %%o0\n\t" 146 "xor %%o1, %%l3, %%o1\n\t" 147 "ldd [%3 + 0x10], %%l2\n\t" 148 "xor %%o2, %%l4, %%o2\n\t" 149 "xor %%o3, %%l5, %%o3\n\t" 150 "ldd [%3 + 0x18], %%l4\n\t" 151 "xor %%g2, %%o4, %%g2\n\t" 152 "xor %%g3, %%o5, %%g3\n\t" 153 "xor %%g4, %%l0, %%g4\n\t" 154 "xor %%g5, %%l1, %%g5\n\t" 155 "xor %%o0, %%l2, %%o0\n\t" 156 "xor %%o1, %%l3, %%o1\n\t" 157 "xor %%o2, %%l4, %%o2\n\t" 158 "xor %%o3, %%l5, %%o3\n\t" 159 "std %%g2, [%0 + 0x00]\n\t" 160 "std %%g4, [%0 + 0x08]\n\t" 161 "std %%o0, [%0 + 0x10]\n\t" 162 "std %%o2, [%0 + 0x18]\n" 163 : 164 : "r" (p1), "r" (p2), "r" (p3), "r" (p4) 165 : "g2", "g3", "g4", "g5", 166 "o0", "o1", "o2", "o3", "o4", "o5", 167 "l0", "l1", "l2", "l3", "l4", "l5"); 168 p1 += 8; 169 p2 += 8; 170 p3 += 8; 171 p4 += 8; 172 } while (--lines > 0); 173 } 174 175 static void 176 sparc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, 177 unsigned long *p3, unsigned long *p4, unsigned long *p5) 178 { 179 int lines = bytes / (sizeof (long)) / 8; 180 181 do { 182 __asm__ __volatile__( 183 "ldd [%0 + 0x00], %%g2\n\t" 184 "ldd [%0 + 0x08], %%g4\n\t" 185 "ldd [%0 + 0x10], %%o0\n\t" 186 "ldd [%0 + 0x18], %%o2\n\t" 187 "ldd [%1 + 0x00], %%o4\n\t" 188 "ldd [%1 + 0x08], %%l0\n\t" 189 "ldd [%1 + 0x10], %%l2\n\t" 190 "ldd [%1 + 0x18], %%l4\n\t" 191 "xor %%g2, %%o4, %%g2\n\t" 192 "xor %%g3, %%o5, %%g3\n\t" 193 "ldd [%2 + 0x00], %%o4\n\t" 194 "xor %%g4, %%l0, %%g4\n\t" 195 "xor %%g5, %%l1, %%g5\n\t" 196 "ldd [%2 + 0x08], %%l0\n\t" 197 "xor %%o0, %%l2, %%o0\n\t" 198 "xor %%o1, %%l3, %%o1\n\t" 199 "ldd [%2 + 0x10], %%l2\n\t" 200 "xor %%o2, %%l4, %%o2\n\t" 201 "xor %%o3, %%l5, %%o3\n\t" 202 "ldd [%2 + 0x18], %%l4\n\t" 203 "xor %%g2, %%o4, %%g2\n\t" 204 "xor %%g3, %%o5, %%g3\n\t" 205 "ldd [%3 + 0x00], %%o4\n\t" 206 "xor %%g4, %%l0, %%g4\n\t" 207 "xor %%g5, %%l1, %%g5\n\t" 208 "ldd [%3 + 0x08], %%l0\n\t" 209 "xor %%o0, %%l2, %%o0\n\t" 210 "xor %%o1, %%l3, %%o1\n\t" 211 "ldd [%3 + 0x10], %%l2\n\t" 212 "xor %%o2, %%l4, %%o2\n\t" 213 "xor %%o3, %%l5, %%o3\n\t" 214 "ldd [%3 + 0x18], %%l4\n\t" 215 "xor %%g2, %%o4, %%g2\n\t" 216 "xor %%g3, %%o5, %%g3\n\t" 217 "ldd [%4 + 0x00], %%o4\n\t" 218 "xor %%g4, %%l0, %%g4\n\t" 219 "xor %%g5, %%l1, %%g5\n\t" 220 "ldd [%4 + 0x08], %%l0\n\t" 221 "xor %%o0, %%l2, %%o0\n\t" 222 "xor %%o1, %%l3, %%o1\n\t" 223 "ldd [%4 + 0x10], %%l2\n\t" 224 "xor %%o2, %%l4, %%o2\n\t" 225 "xor %%o3, %%l5, %%o3\n\t" 226 "ldd [%4 + 0x18], %%l4\n\t" 227 "xor %%g2, %%o4, %%g2\n\t" 228 "xor %%g3, %%o5, %%g3\n\t" 229 "xor %%g4, %%l0, %%g4\n\t" 230 "xor %%g5, %%l1, %%g5\n\t" 231 "xor %%o0, %%l2, %%o0\n\t" 232 "xor %%o1, %%l3, %%o1\n\t" 233 "xor %%o2, %%l4, %%o2\n\t" 234 "xor %%o3, %%l5, %%o3\n\t" 235 "std %%g2, [%0 + 0x00]\n\t" 236 "std %%g4, [%0 + 0x08]\n\t" 237 "std %%o0, [%0 + 0x10]\n\t" 238 "std %%o2, [%0 + 0x18]\n" 239 : 240 : "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5) 241 : "g2", "g3", "g4", "g5", 242 "o0", "o1", "o2", "o3", "o4", "o5", 243 "l0", "l1", "l2", "l3", "l4", "l5"); 244 p1 += 8; 245 p2 += 8; 246 p3 += 8; 247 p4 += 8; 248 p5 += 8; 249 } while (--lines > 0); 250 } 251 252 static struct xor_block_template xor_block_SPARC = { 253 .name = "SPARC", 254 .do_2 = sparc_2, 255 .do_3 = sparc_3, 256 .do_4 = sparc_4, 257 .do_5 = sparc_5, 258 }; 259 260 /* For grins, also test the generic routines. */ 261 #include <asm-generic/xor.h> 262 263 #undef XOR_TRY_TEMPLATES 264 #define XOR_TRY_TEMPLATES \ 265 do { \ 266 xor_speed(&xor_block_8regs); \ 267 xor_speed(&xor_block_32regs); \ 268 xor_speed(&xor_block_SPARC); \ 269 } while (0) 270