1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2001 Russell King 4 */ 5 #include "xor_impl.h" 6 #include "xor_arch.h" 7 8 #define __XOR(a1, a2) a1 ^= a2 9 10 #define GET_BLOCK_2(dst) \ 11 __asm__("ldmia %0, {%1, %2}" \ 12 : "=r" (dst), "=r" (a1), "=r" (a2) \ 13 : "0" (dst)) 14 15 #define GET_BLOCK_4(dst) \ 16 __asm__("ldmia %0, {%1, %2, %3, %4}" \ 17 : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \ 18 : "0" (dst)) 19 20 #define XOR_BLOCK_2(src) \ 21 __asm__("ldmia %0!, {%1, %2}" \ 22 : "=r" (src), "=r" (b1), "=r" (b2) \ 23 : "0" (src)); \ 24 __XOR(a1, b1); __XOR(a2, b2); 25 26 #define XOR_BLOCK_4(src) \ 27 __asm__("ldmia %0!, {%1, %2, %3, %4}" \ 28 : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \ 29 : "0" (src)); \ 30 __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4) 31 32 #define PUT_BLOCK_2(dst) \ 33 __asm__ __volatile__("stmia %0!, {%2, %3}" \ 34 : "=r" (dst) \ 35 : "0" (dst), "r" (a1), "r" (a2)) 36 37 #define PUT_BLOCK_4(dst) \ 38 __asm__ __volatile__("stmia %0!, {%2, %3, %4, %5}" \ 39 : "=r" (dst) \ 40 : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4)) 41 42 static void 43 xor_arm4regs_2(unsigned long bytes, unsigned long * __restrict p1, 44 const unsigned long * __restrict p2) 45 { 46 unsigned int lines = bytes / sizeof(unsigned long) / 4; 47 register unsigned int a1 __asm__("r4"); 48 register unsigned int a2 __asm__("r5"); 49 register unsigned int a3 __asm__("r6"); 50 register unsigned int a4 __asm__("r10"); 51 register unsigned int b1 __asm__("r8"); 52 register unsigned int b2 __asm__("r9"); 53 register unsigned int b3 __asm__("ip"); 54 register unsigned int b4 __asm__("lr"); 55 56 do { 57 GET_BLOCK_4(p1); 58 XOR_BLOCK_4(p2); 59 PUT_BLOCK_4(p1); 60 } while (--lines); 61 } 62 63 static void 64 xor_arm4regs_3(unsigned long bytes, unsigned long * __restrict p1, 65 const unsigned long * __restrict p2, 66 const unsigned long * __restrict p3) 67 { 68 unsigned int lines = bytes / sizeof(unsigned long) / 4; 69 register unsigned int a1 __asm__("r4"); 70 register unsigned int a2 __asm__("r5"); 71 register unsigned int a3 __asm__("r6"); 72 register unsigned int a4 __asm__("r10"); 73 register unsigned int b1 __asm__("r8"); 74 register unsigned int b2 __asm__("r9"); 75 register unsigned int b3 __asm__("ip"); 76 register unsigned int b4 __asm__("lr"); 77 78 do { 79 GET_BLOCK_4(p1); 80 XOR_BLOCK_4(p2); 81 XOR_BLOCK_4(p3); 82 PUT_BLOCK_4(p1); 83 } while (--lines); 84 } 85 86 static void 87 xor_arm4regs_4(unsigned long bytes, unsigned long * __restrict p1, 88 const unsigned long * __restrict p2, 89 const unsigned long * __restrict p3, 90 const unsigned long * __restrict p4) 91 { 92 unsigned int lines = bytes / sizeof(unsigned long) / 2; 93 register unsigned int a1 __asm__("r8"); 94 register unsigned int a2 __asm__("r9"); 95 register unsigned int b1 __asm__("ip"); 96 register unsigned int b2 __asm__("lr"); 97 98 do { 99 GET_BLOCK_2(p1); 100 XOR_BLOCK_2(p2); 101 XOR_BLOCK_2(p3); 102 XOR_BLOCK_2(p4); 103 PUT_BLOCK_2(p1); 104 } while (--lines); 105 } 106 107 static void 108 xor_arm4regs_5(unsigned long bytes, unsigned long * __restrict p1, 109 const unsigned long * __restrict p2, 110 const unsigned long * __restrict p3, 111 const unsigned long * __restrict p4, 112 const unsigned long * __restrict p5) 113 { 114 unsigned int lines = bytes / sizeof(unsigned long) / 2; 115 register unsigned int a1 __asm__("r8"); 116 register unsigned int a2 __asm__("r9"); 117 register unsigned int b1 __asm__("ip"); 118 register unsigned int b2 __asm__("lr"); 119 120 do { 121 GET_BLOCK_2(p1); 122 XOR_BLOCK_2(p2); 123 XOR_BLOCK_2(p3); 124 XOR_BLOCK_2(p4); 125 XOR_BLOCK_2(p5); 126 PUT_BLOCK_2(p1); 127 } while (--lines); 128 } 129 130 DO_XOR_BLOCKS(arm4regs, xor_arm4regs_2, xor_arm4regs_3, xor_arm4regs_4, 131 xor_arm4regs_5); 132 133 struct xor_block_template xor_block_arm4regs = { 134 .name = "arm4regs", 135 .xor_gen = xor_gen_arm4regs, 136 }; 137