177fd47e5SChristoph Hellwig // SPDX-License-Identifier: GPL-2.0-or-later 277fd47e5SChristoph Hellwig /* 377fd47e5SChristoph Hellwig * Optimized XOR parity functions for SSE. 477fd47e5SChristoph Hellwig * 577fd47e5SChristoph Hellwig * Cache avoiding checksumming functions utilizing KNI instructions 677fd47e5SChristoph Hellwig * Copyright (C) 1999 Zach Brown (with obvious credit due Ingo) 777fd47e5SChristoph Hellwig * 877fd47e5SChristoph Hellwig * Based on 977fd47e5SChristoph Hellwig * High-speed RAID5 checksumming functions utilizing SSE instructions. 1077fd47e5SChristoph Hellwig * Copyright (C) 1998 Ingo Molnar. 1177fd47e5SChristoph Hellwig * 1277fd47e5SChristoph Hellwig * x86-64 changes / gcc fixes from Andi Kleen. 1377fd47e5SChristoph Hellwig * Copyright 2002 Andi Kleen, SuSE Labs. 1477fd47e5SChristoph Hellwig */ 1577fd47e5SChristoph Hellwig #include <asm/fpu/api.h> 16e20043b4SChristoph Hellwig #include "xor_impl.h" 17e20043b4SChristoph Hellwig #include "xor_arch.h" 1877fd47e5SChristoph Hellwig 1977fd47e5SChristoph Hellwig #ifdef CONFIG_X86_32 2077fd47e5SChristoph Hellwig /* reduce register pressure */ 2177fd47e5SChristoph Hellwig # define XOR_CONSTANT_CONSTRAINT "i" 2277fd47e5SChristoph Hellwig #else 2377fd47e5SChristoph Hellwig # define XOR_CONSTANT_CONSTRAINT "re" 2477fd47e5SChristoph Hellwig #endif 2577fd47e5SChristoph Hellwig 2677fd47e5SChristoph Hellwig #define OFFS(x) "16*("#x")" 2777fd47e5SChristoph Hellwig #define PF_OFFS(x) "256+16*("#x")" 2877fd47e5SChristoph Hellwig #define PF0(x) " prefetchnta "PF_OFFS(x)"(%[p1]) ;\n" 2977fd47e5SChristoph Hellwig #define LD(x, y) " movaps "OFFS(x)"(%[p1]), %%xmm"#y" ;\n" 3077fd47e5SChristoph Hellwig #define ST(x, y) " movaps %%xmm"#y", "OFFS(x)"(%[p1]) ;\n" 3177fd47e5SChristoph Hellwig #define PF1(x) " prefetchnta "PF_OFFS(x)"(%[p2]) ;\n" 3277fd47e5SChristoph Hellwig #define PF2(x) " prefetchnta "PF_OFFS(x)"(%[p3]) ;\n" 3377fd47e5SChristoph Hellwig #define PF3(x) " prefetchnta "PF_OFFS(x)"(%[p4]) ;\n" 3477fd47e5SChristoph Hellwig #define PF4(x) " prefetchnta "PF_OFFS(x)"(%[p5]) ;\n" 3577fd47e5SChristoph Hellwig #define XO1(x, y) " xorps "OFFS(x)"(%[p2]), %%xmm"#y" ;\n" 3677fd47e5SChristoph Hellwig #define XO2(x, y) " xorps "OFFS(x)"(%[p3]), %%xmm"#y" ;\n" 3777fd47e5SChristoph Hellwig #define XO3(x, y) " xorps "OFFS(x)"(%[p4]), %%xmm"#y" ;\n" 3877fd47e5SChristoph Hellwig #define XO4(x, y) " xorps "OFFS(x)"(%[p5]), %%xmm"#y" ;\n" 3977fd47e5SChristoph Hellwig #define NOP(x) 4077fd47e5SChristoph Hellwig 4177fd47e5SChristoph Hellwig #define BLK64(pf, op, i) \ 4277fd47e5SChristoph Hellwig pf(i) \ 4377fd47e5SChristoph Hellwig op(i, 0) \ 4477fd47e5SChristoph Hellwig op(i + 1, 1) \ 4577fd47e5SChristoph Hellwig op(i + 2, 2) \ 4677fd47e5SChristoph Hellwig op(i + 3, 3) 4777fd47e5SChristoph Hellwig 4877fd47e5SChristoph Hellwig static void 4977fd47e5SChristoph Hellwig xor_sse_2(unsigned long bytes, unsigned long * __restrict p1, 5077fd47e5SChristoph Hellwig const unsigned long * __restrict p2) 5177fd47e5SChristoph Hellwig { 5277fd47e5SChristoph Hellwig unsigned long lines = bytes >> 8; 5377fd47e5SChristoph Hellwig 5477fd47e5SChristoph Hellwig asm volatile( 5577fd47e5SChristoph Hellwig #undef BLOCK 5677fd47e5SChristoph Hellwig #define BLOCK(i) \ 5777fd47e5SChristoph Hellwig LD(i, 0) \ 5877fd47e5SChristoph Hellwig LD(i + 1, 1) \ 5977fd47e5SChristoph Hellwig PF1(i) \ 6077fd47e5SChristoph Hellwig PF1(i + 2) \ 6177fd47e5SChristoph Hellwig LD(i + 2, 2) \ 6277fd47e5SChristoph Hellwig LD(i + 3, 3) \ 6377fd47e5SChristoph Hellwig PF0(i + 4) \ 6477fd47e5SChristoph Hellwig PF0(i + 6) \ 6577fd47e5SChristoph Hellwig XO1(i, 0) \ 6677fd47e5SChristoph Hellwig XO1(i + 1, 1) \ 6777fd47e5SChristoph Hellwig XO1(i + 2, 2) \ 6877fd47e5SChristoph Hellwig XO1(i + 3, 3) \ 6977fd47e5SChristoph Hellwig ST(i, 0) \ 7077fd47e5SChristoph Hellwig ST(i + 1, 1) \ 7177fd47e5SChristoph Hellwig ST(i + 2, 2) \ 7277fd47e5SChristoph Hellwig ST(i + 3, 3) \ 7377fd47e5SChristoph Hellwig 7477fd47e5SChristoph Hellwig 7577fd47e5SChristoph Hellwig PF0(0) 7677fd47e5SChristoph Hellwig PF0(2) 7777fd47e5SChristoph Hellwig 7877fd47e5SChristoph Hellwig " .align 32 ;\n" 7977fd47e5SChristoph Hellwig " 1: ;\n" 8077fd47e5SChristoph Hellwig 8177fd47e5SChristoph Hellwig BLOCK(0) 8277fd47e5SChristoph Hellwig BLOCK(4) 8377fd47e5SChristoph Hellwig BLOCK(8) 8477fd47e5SChristoph Hellwig BLOCK(12) 8577fd47e5SChristoph Hellwig 8677fd47e5SChristoph Hellwig " add %[inc], %[p1] ;\n" 8777fd47e5SChristoph Hellwig " add %[inc], %[p2] ;\n" 8877fd47e5SChristoph Hellwig " dec %[cnt] ;\n" 8977fd47e5SChristoph Hellwig " jnz 1b ;\n" 9077fd47e5SChristoph Hellwig : [cnt] "+r" (lines), 9177fd47e5SChristoph Hellwig [p1] "+r" (p1), [p2] "+r" (p2) 9277fd47e5SChristoph Hellwig : [inc] XOR_CONSTANT_CONSTRAINT (256UL) 9377fd47e5SChristoph Hellwig : "memory"); 9477fd47e5SChristoph Hellwig } 9577fd47e5SChristoph Hellwig 9677fd47e5SChristoph Hellwig static void 9777fd47e5SChristoph Hellwig xor_sse_2_pf64(unsigned long bytes, unsigned long * __restrict p1, 9877fd47e5SChristoph Hellwig const unsigned long * __restrict p2) 9977fd47e5SChristoph Hellwig { 10077fd47e5SChristoph Hellwig unsigned long lines = bytes >> 8; 10177fd47e5SChristoph Hellwig 10277fd47e5SChristoph Hellwig asm volatile( 10377fd47e5SChristoph Hellwig #undef BLOCK 10477fd47e5SChristoph Hellwig #define BLOCK(i) \ 10577fd47e5SChristoph Hellwig BLK64(PF0, LD, i) \ 10677fd47e5SChristoph Hellwig BLK64(PF1, XO1, i) \ 10777fd47e5SChristoph Hellwig BLK64(NOP, ST, i) \ 10877fd47e5SChristoph Hellwig 10977fd47e5SChristoph Hellwig " .align 32 ;\n" 11077fd47e5SChristoph Hellwig " 1: ;\n" 11177fd47e5SChristoph Hellwig 11277fd47e5SChristoph Hellwig BLOCK(0) 11377fd47e5SChristoph Hellwig BLOCK(4) 11477fd47e5SChristoph Hellwig BLOCK(8) 11577fd47e5SChristoph Hellwig BLOCK(12) 11677fd47e5SChristoph Hellwig 11777fd47e5SChristoph Hellwig " add %[inc], %[p1] ;\n" 11877fd47e5SChristoph Hellwig " add %[inc], %[p2] ;\n" 11977fd47e5SChristoph Hellwig " dec %[cnt] ;\n" 12077fd47e5SChristoph Hellwig " jnz 1b ;\n" 12177fd47e5SChristoph Hellwig : [cnt] "+r" (lines), 12277fd47e5SChristoph Hellwig [p1] "+r" (p1), [p2] "+r" (p2) 12377fd47e5SChristoph Hellwig : [inc] XOR_CONSTANT_CONSTRAINT (256UL) 12477fd47e5SChristoph Hellwig : "memory"); 12577fd47e5SChristoph Hellwig } 12677fd47e5SChristoph Hellwig 12777fd47e5SChristoph Hellwig static void 12877fd47e5SChristoph Hellwig xor_sse_3(unsigned long bytes, unsigned long * __restrict p1, 12977fd47e5SChristoph Hellwig const unsigned long * __restrict p2, 13077fd47e5SChristoph Hellwig const unsigned long * __restrict p3) 13177fd47e5SChristoph Hellwig { 13277fd47e5SChristoph Hellwig unsigned long lines = bytes >> 8; 13377fd47e5SChristoph Hellwig 13477fd47e5SChristoph Hellwig asm volatile( 13577fd47e5SChristoph Hellwig #undef BLOCK 13677fd47e5SChristoph Hellwig #define BLOCK(i) \ 13777fd47e5SChristoph Hellwig PF1(i) \ 13877fd47e5SChristoph Hellwig PF1(i + 2) \ 13977fd47e5SChristoph Hellwig LD(i, 0) \ 14077fd47e5SChristoph Hellwig LD(i + 1, 1) \ 14177fd47e5SChristoph Hellwig LD(i + 2, 2) \ 14277fd47e5SChristoph Hellwig LD(i + 3, 3) \ 14377fd47e5SChristoph Hellwig PF2(i) \ 14477fd47e5SChristoph Hellwig PF2(i + 2) \ 14577fd47e5SChristoph Hellwig PF0(i + 4) \ 14677fd47e5SChristoph Hellwig PF0(i + 6) \ 14777fd47e5SChristoph Hellwig XO1(i, 0) \ 14877fd47e5SChristoph Hellwig XO1(i + 1, 1) \ 14977fd47e5SChristoph Hellwig XO1(i + 2, 2) \ 15077fd47e5SChristoph Hellwig XO1(i + 3, 3) \ 15177fd47e5SChristoph Hellwig XO2(i, 0) \ 15277fd47e5SChristoph Hellwig XO2(i + 1, 1) \ 15377fd47e5SChristoph Hellwig XO2(i + 2, 2) \ 15477fd47e5SChristoph Hellwig XO2(i + 3, 3) \ 15577fd47e5SChristoph Hellwig ST(i, 0) \ 15677fd47e5SChristoph Hellwig ST(i + 1, 1) \ 15777fd47e5SChristoph Hellwig ST(i + 2, 2) \ 15877fd47e5SChristoph Hellwig ST(i + 3, 3) \ 15977fd47e5SChristoph Hellwig 16077fd47e5SChristoph Hellwig 16177fd47e5SChristoph Hellwig PF0(0) 16277fd47e5SChristoph Hellwig PF0(2) 16377fd47e5SChristoph Hellwig 16477fd47e5SChristoph Hellwig " .align 32 ;\n" 16577fd47e5SChristoph Hellwig " 1: ;\n" 16677fd47e5SChristoph Hellwig 16777fd47e5SChristoph Hellwig BLOCK(0) 16877fd47e5SChristoph Hellwig BLOCK(4) 16977fd47e5SChristoph Hellwig BLOCK(8) 17077fd47e5SChristoph Hellwig BLOCK(12) 17177fd47e5SChristoph Hellwig 17277fd47e5SChristoph Hellwig " add %[inc], %[p1] ;\n" 17377fd47e5SChristoph Hellwig " add %[inc], %[p2] ;\n" 17477fd47e5SChristoph Hellwig " add %[inc], %[p3] ;\n" 17577fd47e5SChristoph Hellwig " dec %[cnt] ;\n" 17677fd47e5SChristoph Hellwig " jnz 1b ;\n" 17777fd47e5SChristoph Hellwig : [cnt] "+r" (lines), 17877fd47e5SChristoph Hellwig [p1] "+r" (p1), [p2] "+r" (p2), [p3] "+r" (p3) 17977fd47e5SChristoph Hellwig : [inc] XOR_CONSTANT_CONSTRAINT (256UL) 18077fd47e5SChristoph Hellwig : "memory"); 18177fd47e5SChristoph Hellwig } 18277fd47e5SChristoph Hellwig 18377fd47e5SChristoph Hellwig static void 18477fd47e5SChristoph Hellwig xor_sse_3_pf64(unsigned long bytes, unsigned long * __restrict p1, 18577fd47e5SChristoph Hellwig const unsigned long * __restrict p2, 18677fd47e5SChristoph Hellwig const unsigned long * __restrict p3) 18777fd47e5SChristoph Hellwig { 18877fd47e5SChristoph Hellwig unsigned long lines = bytes >> 8; 18977fd47e5SChristoph Hellwig 19077fd47e5SChristoph Hellwig asm volatile( 19177fd47e5SChristoph Hellwig #undef BLOCK 19277fd47e5SChristoph Hellwig #define BLOCK(i) \ 19377fd47e5SChristoph Hellwig BLK64(PF0, LD, i) \ 19477fd47e5SChristoph Hellwig BLK64(PF1, XO1, i) \ 19577fd47e5SChristoph Hellwig BLK64(PF2, XO2, i) \ 19677fd47e5SChristoph Hellwig BLK64(NOP, ST, i) \ 19777fd47e5SChristoph Hellwig 19877fd47e5SChristoph Hellwig " .align 32 ;\n" 19977fd47e5SChristoph Hellwig " 1: ;\n" 20077fd47e5SChristoph Hellwig 20177fd47e5SChristoph Hellwig BLOCK(0) 20277fd47e5SChristoph Hellwig BLOCK(4) 20377fd47e5SChristoph Hellwig BLOCK(8) 20477fd47e5SChristoph Hellwig BLOCK(12) 20577fd47e5SChristoph Hellwig 20677fd47e5SChristoph Hellwig " add %[inc], %[p1] ;\n" 20777fd47e5SChristoph Hellwig " add %[inc], %[p2] ;\n" 20877fd47e5SChristoph Hellwig " add %[inc], %[p3] ;\n" 20977fd47e5SChristoph Hellwig " dec %[cnt] ;\n" 21077fd47e5SChristoph Hellwig " jnz 1b ;\n" 21177fd47e5SChristoph Hellwig : [cnt] "+r" (lines), 21277fd47e5SChristoph Hellwig [p1] "+r" (p1), [p2] "+r" (p2), [p3] "+r" (p3) 21377fd47e5SChristoph Hellwig : [inc] XOR_CONSTANT_CONSTRAINT (256UL) 21477fd47e5SChristoph Hellwig : "memory"); 21577fd47e5SChristoph Hellwig } 21677fd47e5SChristoph Hellwig 21777fd47e5SChristoph Hellwig static void 21877fd47e5SChristoph Hellwig xor_sse_4(unsigned long bytes, unsigned long * __restrict p1, 21977fd47e5SChristoph Hellwig const unsigned long * __restrict p2, 22077fd47e5SChristoph Hellwig const unsigned long * __restrict p3, 22177fd47e5SChristoph Hellwig const unsigned long * __restrict p4) 22277fd47e5SChristoph Hellwig { 22377fd47e5SChristoph Hellwig unsigned long lines = bytes >> 8; 22477fd47e5SChristoph Hellwig 22577fd47e5SChristoph Hellwig asm volatile( 22677fd47e5SChristoph Hellwig #undef BLOCK 22777fd47e5SChristoph Hellwig #define BLOCK(i) \ 22877fd47e5SChristoph Hellwig PF1(i) \ 22977fd47e5SChristoph Hellwig PF1(i + 2) \ 23077fd47e5SChristoph Hellwig LD(i, 0) \ 23177fd47e5SChristoph Hellwig LD(i + 1, 1) \ 23277fd47e5SChristoph Hellwig LD(i + 2, 2) \ 23377fd47e5SChristoph Hellwig LD(i + 3, 3) \ 23477fd47e5SChristoph Hellwig PF2(i) \ 23577fd47e5SChristoph Hellwig PF2(i + 2) \ 23677fd47e5SChristoph Hellwig XO1(i, 0) \ 23777fd47e5SChristoph Hellwig XO1(i + 1, 1) \ 23877fd47e5SChristoph Hellwig XO1(i + 2, 2) \ 23977fd47e5SChristoph Hellwig XO1(i + 3, 3) \ 24077fd47e5SChristoph Hellwig PF3(i) \ 24177fd47e5SChristoph Hellwig PF3(i + 2) \ 24277fd47e5SChristoph Hellwig PF0(i + 4) \ 24377fd47e5SChristoph Hellwig PF0(i + 6) \ 24477fd47e5SChristoph Hellwig XO2(i, 0) \ 24577fd47e5SChristoph Hellwig XO2(i + 1, 1) \ 24677fd47e5SChristoph Hellwig XO2(i + 2, 2) \ 24777fd47e5SChristoph Hellwig XO2(i + 3, 3) \ 24877fd47e5SChristoph Hellwig XO3(i, 0) \ 24977fd47e5SChristoph Hellwig XO3(i + 1, 1) \ 25077fd47e5SChristoph Hellwig XO3(i + 2, 2) \ 25177fd47e5SChristoph Hellwig XO3(i + 3, 3) \ 25277fd47e5SChristoph Hellwig ST(i, 0) \ 25377fd47e5SChristoph Hellwig ST(i + 1, 1) \ 25477fd47e5SChristoph Hellwig ST(i + 2, 2) \ 25577fd47e5SChristoph Hellwig ST(i + 3, 3) \ 25677fd47e5SChristoph Hellwig 25777fd47e5SChristoph Hellwig 25877fd47e5SChristoph Hellwig PF0(0) 25977fd47e5SChristoph Hellwig PF0(2) 26077fd47e5SChristoph Hellwig 26177fd47e5SChristoph Hellwig " .align 32 ;\n" 26277fd47e5SChristoph Hellwig " 1: ;\n" 26377fd47e5SChristoph Hellwig 26477fd47e5SChristoph Hellwig BLOCK(0) 26577fd47e5SChristoph Hellwig BLOCK(4) 26677fd47e5SChristoph Hellwig BLOCK(8) 26777fd47e5SChristoph Hellwig BLOCK(12) 26877fd47e5SChristoph Hellwig 26977fd47e5SChristoph Hellwig " add %[inc], %[p1] ;\n" 27077fd47e5SChristoph Hellwig " add %[inc], %[p2] ;\n" 27177fd47e5SChristoph Hellwig " add %[inc], %[p3] ;\n" 27277fd47e5SChristoph Hellwig " add %[inc], %[p4] ;\n" 27377fd47e5SChristoph Hellwig " dec %[cnt] ;\n" 27477fd47e5SChristoph Hellwig " jnz 1b ;\n" 27577fd47e5SChristoph Hellwig : [cnt] "+r" (lines), [p1] "+r" (p1), 27677fd47e5SChristoph Hellwig [p2] "+r" (p2), [p3] "+r" (p3), [p4] "+r" (p4) 27777fd47e5SChristoph Hellwig : [inc] XOR_CONSTANT_CONSTRAINT (256UL) 27877fd47e5SChristoph Hellwig : "memory"); 27977fd47e5SChristoph Hellwig } 28077fd47e5SChristoph Hellwig 28177fd47e5SChristoph Hellwig static void 28277fd47e5SChristoph Hellwig xor_sse_4_pf64(unsigned long bytes, unsigned long * __restrict p1, 28377fd47e5SChristoph Hellwig const unsigned long * __restrict p2, 28477fd47e5SChristoph Hellwig const unsigned long * __restrict p3, 28577fd47e5SChristoph Hellwig const unsigned long * __restrict p4) 28677fd47e5SChristoph Hellwig { 28777fd47e5SChristoph Hellwig unsigned long lines = bytes >> 8; 28877fd47e5SChristoph Hellwig 28977fd47e5SChristoph Hellwig asm volatile( 29077fd47e5SChristoph Hellwig #undef BLOCK 29177fd47e5SChristoph Hellwig #define BLOCK(i) \ 29277fd47e5SChristoph Hellwig BLK64(PF0, LD, i) \ 29377fd47e5SChristoph Hellwig BLK64(PF1, XO1, i) \ 29477fd47e5SChristoph Hellwig BLK64(PF2, XO2, i) \ 29577fd47e5SChristoph Hellwig BLK64(PF3, XO3, i) \ 29677fd47e5SChristoph Hellwig BLK64(NOP, ST, i) \ 29777fd47e5SChristoph Hellwig 29877fd47e5SChristoph Hellwig " .align 32 ;\n" 29977fd47e5SChristoph Hellwig " 1: ;\n" 30077fd47e5SChristoph Hellwig 30177fd47e5SChristoph Hellwig BLOCK(0) 30277fd47e5SChristoph Hellwig BLOCK(4) 30377fd47e5SChristoph Hellwig BLOCK(8) 30477fd47e5SChristoph Hellwig BLOCK(12) 30577fd47e5SChristoph Hellwig 30677fd47e5SChristoph Hellwig " add %[inc], %[p1] ;\n" 30777fd47e5SChristoph Hellwig " add %[inc], %[p2] ;\n" 30877fd47e5SChristoph Hellwig " add %[inc], %[p3] ;\n" 30977fd47e5SChristoph Hellwig " add %[inc], %[p4] ;\n" 31077fd47e5SChristoph Hellwig " dec %[cnt] ;\n" 31177fd47e5SChristoph Hellwig " jnz 1b ;\n" 31277fd47e5SChristoph Hellwig : [cnt] "+r" (lines), [p1] "+r" (p1), 31377fd47e5SChristoph Hellwig [p2] "+r" (p2), [p3] "+r" (p3), [p4] "+r" (p4) 31477fd47e5SChristoph Hellwig : [inc] XOR_CONSTANT_CONSTRAINT (256UL) 31577fd47e5SChristoph Hellwig : "memory"); 31677fd47e5SChristoph Hellwig } 31777fd47e5SChristoph Hellwig 31877fd47e5SChristoph Hellwig static void 31977fd47e5SChristoph Hellwig xor_sse_5(unsigned long bytes, unsigned long * __restrict p1, 32077fd47e5SChristoph Hellwig const unsigned long * __restrict p2, 32177fd47e5SChristoph Hellwig const unsigned long * __restrict p3, 32277fd47e5SChristoph Hellwig const unsigned long * __restrict p4, 32377fd47e5SChristoph Hellwig const unsigned long * __restrict p5) 32477fd47e5SChristoph Hellwig { 32577fd47e5SChristoph Hellwig unsigned long lines = bytes >> 8; 32677fd47e5SChristoph Hellwig 32777fd47e5SChristoph Hellwig asm volatile( 32877fd47e5SChristoph Hellwig #undef BLOCK 32977fd47e5SChristoph Hellwig #define BLOCK(i) \ 33077fd47e5SChristoph Hellwig PF1(i) \ 33177fd47e5SChristoph Hellwig PF1(i + 2) \ 33277fd47e5SChristoph Hellwig LD(i, 0) \ 33377fd47e5SChristoph Hellwig LD(i + 1, 1) \ 33477fd47e5SChristoph Hellwig LD(i + 2, 2) \ 33577fd47e5SChristoph Hellwig LD(i + 3, 3) \ 33677fd47e5SChristoph Hellwig PF2(i) \ 33777fd47e5SChristoph Hellwig PF2(i + 2) \ 33877fd47e5SChristoph Hellwig XO1(i, 0) \ 33977fd47e5SChristoph Hellwig XO1(i + 1, 1) \ 34077fd47e5SChristoph Hellwig XO1(i + 2, 2) \ 34177fd47e5SChristoph Hellwig XO1(i + 3, 3) \ 34277fd47e5SChristoph Hellwig PF3(i) \ 34377fd47e5SChristoph Hellwig PF3(i + 2) \ 34477fd47e5SChristoph Hellwig XO2(i, 0) \ 34577fd47e5SChristoph Hellwig XO2(i + 1, 1) \ 34677fd47e5SChristoph Hellwig XO2(i + 2, 2) \ 34777fd47e5SChristoph Hellwig XO2(i + 3, 3) \ 34877fd47e5SChristoph Hellwig PF4(i) \ 34977fd47e5SChristoph Hellwig PF4(i + 2) \ 35077fd47e5SChristoph Hellwig PF0(i + 4) \ 35177fd47e5SChristoph Hellwig PF0(i + 6) \ 35277fd47e5SChristoph Hellwig XO3(i, 0) \ 35377fd47e5SChristoph Hellwig XO3(i + 1, 1) \ 35477fd47e5SChristoph Hellwig XO3(i + 2, 2) \ 35577fd47e5SChristoph Hellwig XO3(i + 3, 3) \ 35677fd47e5SChristoph Hellwig XO4(i, 0) \ 35777fd47e5SChristoph Hellwig XO4(i + 1, 1) \ 35877fd47e5SChristoph Hellwig XO4(i + 2, 2) \ 35977fd47e5SChristoph Hellwig XO4(i + 3, 3) \ 36077fd47e5SChristoph Hellwig ST(i, 0) \ 36177fd47e5SChristoph Hellwig ST(i + 1, 1) \ 36277fd47e5SChristoph Hellwig ST(i + 2, 2) \ 36377fd47e5SChristoph Hellwig ST(i + 3, 3) \ 36477fd47e5SChristoph Hellwig 36577fd47e5SChristoph Hellwig 36677fd47e5SChristoph Hellwig PF0(0) 36777fd47e5SChristoph Hellwig PF0(2) 36877fd47e5SChristoph Hellwig 36977fd47e5SChristoph Hellwig " .align 32 ;\n" 37077fd47e5SChristoph Hellwig " 1: ;\n" 37177fd47e5SChristoph Hellwig 37277fd47e5SChristoph Hellwig BLOCK(0) 37377fd47e5SChristoph Hellwig BLOCK(4) 37477fd47e5SChristoph Hellwig BLOCK(8) 37577fd47e5SChristoph Hellwig BLOCK(12) 37677fd47e5SChristoph Hellwig 37777fd47e5SChristoph Hellwig " add %[inc], %[p1] ;\n" 37877fd47e5SChristoph Hellwig " add %[inc], %[p2] ;\n" 37977fd47e5SChristoph Hellwig " add %[inc], %[p3] ;\n" 38077fd47e5SChristoph Hellwig " add %[inc], %[p4] ;\n" 38177fd47e5SChristoph Hellwig " add %[inc], %[p5] ;\n" 38277fd47e5SChristoph Hellwig " dec %[cnt] ;\n" 38377fd47e5SChristoph Hellwig " jnz 1b ;\n" 38477fd47e5SChristoph Hellwig : [cnt] "+r" (lines), [p1] "+r" (p1), [p2] "+r" (p2), 38577fd47e5SChristoph Hellwig [p3] "+r" (p3), [p4] "+r" (p4), [p5] "+r" (p5) 38677fd47e5SChristoph Hellwig : [inc] XOR_CONSTANT_CONSTRAINT (256UL) 38777fd47e5SChristoph Hellwig : "memory"); 38877fd47e5SChristoph Hellwig } 38977fd47e5SChristoph Hellwig 39077fd47e5SChristoph Hellwig static void 39177fd47e5SChristoph Hellwig xor_sse_5_pf64(unsigned long bytes, unsigned long * __restrict p1, 39277fd47e5SChristoph Hellwig const unsigned long * __restrict p2, 39377fd47e5SChristoph Hellwig const unsigned long * __restrict p3, 39477fd47e5SChristoph Hellwig const unsigned long * __restrict p4, 39577fd47e5SChristoph Hellwig const unsigned long * __restrict p5) 39677fd47e5SChristoph Hellwig { 39777fd47e5SChristoph Hellwig unsigned long lines = bytes >> 8; 39877fd47e5SChristoph Hellwig 39977fd47e5SChristoph Hellwig asm volatile( 40077fd47e5SChristoph Hellwig #undef BLOCK 40177fd47e5SChristoph Hellwig #define BLOCK(i) \ 40277fd47e5SChristoph Hellwig BLK64(PF0, LD, i) \ 40377fd47e5SChristoph Hellwig BLK64(PF1, XO1, i) \ 40477fd47e5SChristoph Hellwig BLK64(PF2, XO2, i) \ 40577fd47e5SChristoph Hellwig BLK64(PF3, XO3, i) \ 40677fd47e5SChristoph Hellwig BLK64(PF4, XO4, i) \ 40777fd47e5SChristoph Hellwig BLK64(NOP, ST, i) \ 40877fd47e5SChristoph Hellwig 40977fd47e5SChristoph Hellwig " .align 32 ;\n" 41077fd47e5SChristoph Hellwig " 1: ;\n" 41177fd47e5SChristoph Hellwig 41277fd47e5SChristoph Hellwig BLOCK(0) 41377fd47e5SChristoph Hellwig BLOCK(4) 41477fd47e5SChristoph Hellwig BLOCK(8) 41577fd47e5SChristoph Hellwig BLOCK(12) 41677fd47e5SChristoph Hellwig 41777fd47e5SChristoph Hellwig " add %[inc], %[p1] ;\n" 41877fd47e5SChristoph Hellwig " add %[inc], %[p2] ;\n" 41977fd47e5SChristoph Hellwig " add %[inc], %[p3] ;\n" 42077fd47e5SChristoph Hellwig " add %[inc], %[p4] ;\n" 42177fd47e5SChristoph Hellwig " add %[inc], %[p5] ;\n" 42277fd47e5SChristoph Hellwig " dec %[cnt] ;\n" 42377fd47e5SChristoph Hellwig " jnz 1b ;\n" 42477fd47e5SChristoph Hellwig : [cnt] "+r" (lines), [p1] "+r" (p1), [p2] "+r" (p2), 42577fd47e5SChristoph Hellwig [p3] "+r" (p3), [p4] "+r" (p4), [p5] "+r" (p5) 42677fd47e5SChristoph Hellwig : [inc] XOR_CONSTANT_CONSTRAINT (256UL) 42777fd47e5SChristoph Hellwig : "memory"); 428*80dcf0a7SChristoph Hellwig } 42977fd47e5SChristoph Hellwig 430*80dcf0a7SChristoph Hellwig DO_XOR_BLOCKS(sse_inner, xor_sse_2, xor_sse_3, xor_sse_4, xor_sse_5); 431*80dcf0a7SChristoph Hellwig 432*80dcf0a7SChristoph Hellwig static void xor_gen_sse(void *dest, void **srcs, unsigned int src_cnt, 433*80dcf0a7SChristoph Hellwig unsigned int bytes) 434*80dcf0a7SChristoph Hellwig { 435*80dcf0a7SChristoph Hellwig kernel_fpu_begin(); 436*80dcf0a7SChristoph Hellwig xor_gen_sse_inner(dest, srcs, src_cnt, bytes); 43777fd47e5SChristoph Hellwig kernel_fpu_end(); 43877fd47e5SChristoph Hellwig } 43977fd47e5SChristoph Hellwig 44077fd47e5SChristoph Hellwig struct xor_block_template xor_block_sse = { 44177fd47e5SChristoph Hellwig .name = "sse", 442*80dcf0a7SChristoph Hellwig .xor_gen = xor_gen_sse, 44377fd47e5SChristoph Hellwig }; 44477fd47e5SChristoph Hellwig 445*80dcf0a7SChristoph Hellwig DO_XOR_BLOCKS(sse_pf64_inner, xor_sse_2_pf64, xor_sse_3_pf64, xor_sse_4_pf64, 446*80dcf0a7SChristoph Hellwig xor_sse_5_pf64); 447*80dcf0a7SChristoph Hellwig 448*80dcf0a7SChristoph Hellwig static void xor_gen_sse_pf64(void *dest, void **srcs, unsigned int src_cnt, 449*80dcf0a7SChristoph Hellwig unsigned int bytes) 450*80dcf0a7SChristoph Hellwig { 451*80dcf0a7SChristoph Hellwig kernel_fpu_begin(); 452*80dcf0a7SChristoph Hellwig xor_gen_sse_pf64_inner(dest, srcs, src_cnt, bytes); 453*80dcf0a7SChristoph Hellwig kernel_fpu_end(); 454*80dcf0a7SChristoph Hellwig } 455*80dcf0a7SChristoph Hellwig 45677fd47e5SChristoph Hellwig struct xor_block_template xor_block_sse_pf64 = { 45777fd47e5SChristoph Hellwig .name = "prefetch64-sse", 458*80dcf0a7SChristoph Hellwig .xor_gen = xor_gen_sse_pf64, 45977fd47e5SChristoph Hellwig }; 460