10d64a24eSChristoph Hellwig // SPDX-License-Identifier: GPL-2.0-only 20d64a24eSChristoph Hellwig /* 30d64a24eSChristoph Hellwig * Copyright (C) 2001 Russell King 40d64a24eSChristoph Hellwig */ 5e20043b4SChristoph Hellwig #include "xor_impl.h" 6e20043b4SChristoph Hellwig #include "xor_arch.h" 70d64a24eSChristoph Hellwig 80d64a24eSChristoph Hellwig #define __XOR(a1, a2) a1 ^= a2 90d64a24eSChristoph Hellwig 100d64a24eSChristoph Hellwig #define GET_BLOCK_2(dst) \ 110d64a24eSChristoph Hellwig __asm__("ldmia %0, {%1, %2}" \ 120d64a24eSChristoph Hellwig : "=r" (dst), "=r" (a1), "=r" (a2) \ 130d64a24eSChristoph Hellwig : "0" (dst)) 140d64a24eSChristoph Hellwig 150d64a24eSChristoph Hellwig #define GET_BLOCK_4(dst) \ 160d64a24eSChristoph Hellwig __asm__("ldmia %0, {%1, %2, %3, %4}" \ 170d64a24eSChristoph Hellwig : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \ 180d64a24eSChristoph Hellwig : "0" (dst)) 190d64a24eSChristoph Hellwig 200d64a24eSChristoph Hellwig #define XOR_BLOCK_2(src) \ 210d64a24eSChristoph Hellwig __asm__("ldmia %0!, {%1, %2}" \ 220d64a24eSChristoph Hellwig : "=r" (src), "=r" (b1), "=r" (b2) \ 230d64a24eSChristoph Hellwig : "0" (src)); \ 240d64a24eSChristoph Hellwig __XOR(a1, b1); __XOR(a2, b2); 250d64a24eSChristoph Hellwig 260d64a24eSChristoph Hellwig #define XOR_BLOCK_4(src) \ 270d64a24eSChristoph Hellwig __asm__("ldmia %0!, {%1, %2, %3, %4}" \ 280d64a24eSChristoph Hellwig : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \ 290d64a24eSChristoph Hellwig : "0" (src)); \ 300d64a24eSChristoph Hellwig __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4) 310d64a24eSChristoph Hellwig 320d64a24eSChristoph Hellwig #define PUT_BLOCK_2(dst) \ 330d64a24eSChristoph Hellwig __asm__ __volatile__("stmia %0!, {%2, %3}" \ 340d64a24eSChristoph Hellwig : "=r" (dst) \ 350d64a24eSChristoph Hellwig : "0" (dst), "r" (a1), "r" (a2)) 360d64a24eSChristoph Hellwig 370d64a24eSChristoph Hellwig #define PUT_BLOCK_4(dst) \ 380d64a24eSChristoph Hellwig __asm__ __volatile__("stmia %0!, {%2, %3, %4, %5}" \ 390d64a24eSChristoph Hellwig : "=r" (dst) \ 400d64a24eSChristoph Hellwig : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4)) 410d64a24eSChristoph Hellwig 420d64a24eSChristoph Hellwig static void 430d64a24eSChristoph Hellwig xor_arm4regs_2(unsigned long bytes, unsigned long * __restrict p1, 440d64a24eSChristoph Hellwig const unsigned long * __restrict p2) 450d64a24eSChristoph Hellwig { 460d64a24eSChristoph Hellwig unsigned int lines = bytes / sizeof(unsigned long) / 4; 470d64a24eSChristoph Hellwig register unsigned int a1 __asm__("r4"); 480d64a24eSChristoph Hellwig register unsigned int a2 __asm__("r5"); 490d64a24eSChristoph Hellwig register unsigned int a3 __asm__("r6"); 500d64a24eSChristoph Hellwig register unsigned int a4 __asm__("r10"); 510d64a24eSChristoph Hellwig register unsigned int b1 __asm__("r8"); 520d64a24eSChristoph Hellwig register unsigned int b2 __asm__("r9"); 530d64a24eSChristoph Hellwig register unsigned int b3 __asm__("ip"); 540d64a24eSChristoph Hellwig register unsigned int b4 __asm__("lr"); 550d64a24eSChristoph Hellwig 560d64a24eSChristoph Hellwig do { 570d64a24eSChristoph Hellwig GET_BLOCK_4(p1); 580d64a24eSChristoph Hellwig XOR_BLOCK_4(p2); 590d64a24eSChristoph Hellwig PUT_BLOCK_4(p1); 600d64a24eSChristoph Hellwig } while (--lines); 610d64a24eSChristoph Hellwig } 620d64a24eSChristoph Hellwig 630d64a24eSChristoph Hellwig static void 640d64a24eSChristoph Hellwig xor_arm4regs_3(unsigned long bytes, unsigned long * __restrict p1, 650d64a24eSChristoph Hellwig const unsigned long * __restrict p2, 660d64a24eSChristoph Hellwig const unsigned long * __restrict p3) 670d64a24eSChristoph Hellwig { 680d64a24eSChristoph Hellwig unsigned int lines = bytes / sizeof(unsigned long) / 4; 690d64a24eSChristoph Hellwig register unsigned int a1 __asm__("r4"); 700d64a24eSChristoph Hellwig register unsigned int a2 __asm__("r5"); 710d64a24eSChristoph Hellwig register unsigned int a3 __asm__("r6"); 720d64a24eSChristoph Hellwig register unsigned int a4 __asm__("r10"); 730d64a24eSChristoph Hellwig register unsigned int b1 __asm__("r8"); 740d64a24eSChristoph Hellwig register unsigned int b2 __asm__("r9"); 750d64a24eSChristoph Hellwig register unsigned int b3 __asm__("ip"); 760d64a24eSChristoph Hellwig register unsigned int b4 __asm__("lr"); 770d64a24eSChristoph Hellwig 780d64a24eSChristoph Hellwig do { 790d64a24eSChristoph Hellwig GET_BLOCK_4(p1); 800d64a24eSChristoph Hellwig XOR_BLOCK_4(p2); 810d64a24eSChristoph Hellwig XOR_BLOCK_4(p3); 820d64a24eSChristoph Hellwig PUT_BLOCK_4(p1); 830d64a24eSChristoph Hellwig } while (--lines); 840d64a24eSChristoph Hellwig } 850d64a24eSChristoph Hellwig 860d64a24eSChristoph Hellwig static void 870d64a24eSChristoph Hellwig xor_arm4regs_4(unsigned long bytes, unsigned long * __restrict p1, 880d64a24eSChristoph Hellwig const unsigned long * __restrict p2, 890d64a24eSChristoph Hellwig const unsigned long * __restrict p3, 900d64a24eSChristoph Hellwig const unsigned long * __restrict p4) 910d64a24eSChristoph Hellwig { 920d64a24eSChristoph Hellwig unsigned int lines = bytes / sizeof(unsigned long) / 2; 930d64a24eSChristoph Hellwig register unsigned int a1 __asm__("r8"); 940d64a24eSChristoph Hellwig register unsigned int a2 __asm__("r9"); 950d64a24eSChristoph Hellwig register unsigned int b1 __asm__("ip"); 960d64a24eSChristoph Hellwig register unsigned int b2 __asm__("lr"); 970d64a24eSChristoph Hellwig 980d64a24eSChristoph Hellwig do { 990d64a24eSChristoph Hellwig GET_BLOCK_2(p1); 1000d64a24eSChristoph Hellwig XOR_BLOCK_2(p2); 1010d64a24eSChristoph Hellwig XOR_BLOCK_2(p3); 1020d64a24eSChristoph Hellwig XOR_BLOCK_2(p4); 1030d64a24eSChristoph Hellwig PUT_BLOCK_2(p1); 1040d64a24eSChristoph Hellwig } while (--lines); 1050d64a24eSChristoph Hellwig } 1060d64a24eSChristoph Hellwig 1070d64a24eSChristoph Hellwig static void 1080d64a24eSChristoph Hellwig xor_arm4regs_5(unsigned long bytes, unsigned long * __restrict p1, 1090d64a24eSChristoph Hellwig const unsigned long * __restrict p2, 1100d64a24eSChristoph Hellwig const unsigned long * __restrict p3, 1110d64a24eSChristoph Hellwig const unsigned long * __restrict p4, 1120d64a24eSChristoph Hellwig const unsigned long * __restrict p5) 1130d64a24eSChristoph Hellwig { 1140d64a24eSChristoph Hellwig unsigned int lines = bytes / sizeof(unsigned long) / 2; 1150d64a24eSChristoph Hellwig register unsigned int a1 __asm__("r8"); 1160d64a24eSChristoph Hellwig register unsigned int a2 __asm__("r9"); 1170d64a24eSChristoph Hellwig register unsigned int b1 __asm__("ip"); 1180d64a24eSChristoph Hellwig register unsigned int b2 __asm__("lr"); 1190d64a24eSChristoph Hellwig 1200d64a24eSChristoph Hellwig do { 1210d64a24eSChristoph Hellwig GET_BLOCK_2(p1); 1220d64a24eSChristoph Hellwig XOR_BLOCK_2(p2); 1230d64a24eSChristoph Hellwig XOR_BLOCK_2(p3); 1240d64a24eSChristoph Hellwig XOR_BLOCK_2(p4); 1250d64a24eSChristoph Hellwig XOR_BLOCK_2(p5); 1260d64a24eSChristoph Hellwig PUT_BLOCK_2(p1); 1270d64a24eSChristoph Hellwig } while (--lines); 1280d64a24eSChristoph Hellwig } 1290d64a24eSChristoph Hellwig 130*80dcf0a7SChristoph Hellwig DO_XOR_BLOCKS(arm4regs, xor_arm4regs_2, xor_arm4regs_3, xor_arm4regs_4, 131*80dcf0a7SChristoph Hellwig xor_arm4regs_5); 132*80dcf0a7SChristoph Hellwig 1330d64a24eSChristoph Hellwig struct xor_block_template xor_block_arm4regs = { 1340d64a24eSChristoph Hellwig .name = "arm4regs", 135*80dcf0a7SChristoph Hellwig .xor_gen = xor_gen_arm4regs, 1360d64a24eSChristoph Hellwig }; 137