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