1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * linux/arch/unicore32/lib/copy_template.S 4 * 5 * Code specific to PKUnity SoC and UniCore ISA 6 * 7 * Copyright (C) 2001-2010 GUAN Xue-tao 8 */ 9 10/* 11 * Theory of operation 12 * ------------------- 13 * 14 * This file provides the core code for a forward memory copy used in 15 * the implementation of memcopy(), copy_to_user() and copy_from_user(). 16 * 17 * The including file must define the following accessor macros 18 * according to the need of the given function: 19 * 20 * ldr1w ptr reg abort 21 * 22 * This loads one word from 'ptr', stores it in 'reg' and increments 23 * 'ptr' to the next word. The 'abort' argument is used for fixup tables. 24 * 25 * ldr4w ptr reg1 reg2 reg3 reg4 abort 26 * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 27 * 28 * This loads four or eight words starting from 'ptr', stores them 29 * in provided registers and increments 'ptr' past those words. 30 * The'abort' argument is used for fixup tables. 31 * 32 * ldr1b ptr reg cond abort 33 * 34 * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte. 35 * It also must apply the condition code if provided, otherwise the 36 * "al" condition is assumed by default. 37 * 38 * str1w ptr reg abort 39 * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 40 * str1b ptr reg cond abort 41 * 42 * Same as their ldr* counterparts, but data is stored to 'ptr' location 43 * rather than being loaded. 44 * 45 * enter 46 * 47 * Preserve the provided registers on the stack plus any additional 48 * data as needed by the implementation including this code. Called 49 * upon code entry. 50 * 51 * exit 52 * 53 * Restore registers with the values previously saved with the 54 * 'preserv' macro. Called upon code termination. 55 */ 56 57 58 enter 59 60 sub.a r2, r2, #4 61 bsl 8f 62 and.a ip, r0, #3 63 bne 9f 64 and.a ip, r1, #3 65 bne 10f 66 671: sub.a r2, r2, #(28) 68 stm.w (r5 - r8), [sp-] 69 bsl 5f 70 713: 724: ldr8w r1, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f 73 sub.a r2, r2, #32 74 str8w r0, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f 75 beg 3b 76 775: and.a ip, r2, #28 78 rsub ip, ip, #32 79 beq 7f 80 add pc, pc, ip @ C is always clear here 81 nop 82 83 ldr1w r1, r3, abort=20f 84 ldr1w r1, r4, abort=20f 85 ldr1w r1, r5, abort=20f 86 ldr1w r1, r6, abort=20f 87 ldr1w r1, r7, abort=20f 88 ldr1w r1, r8, abort=20f 89 ldr1w r1, r11, abort=20f 90 91 add pc, pc, ip 92 nop 93 94 str1w r0, r3, abort=20f 95 str1w r0, r4, abort=20f 96 str1w r0, r5, abort=20f 97 str1w r0, r6, abort=20f 98 str1w r0, r7, abort=20f 99 str1w r0, r8, abort=20f 100 str1w r0, r11, abort=20f 101 1027: ldm.w (r5 - r8), [sp]+ 103 1048: mov.a r2, r2 << #31 105 ldr1b r1, r3, ne, abort=21f 106 ldr1b r1, r4, ea, abort=21f 107 ldr1b r1, r10, ea, abort=21f 108 str1b r0, r3, ne, abort=21f 109 str1b r0, r4, ea, abort=21f 110 str1b r0, r10, ea, abort=21f 111 112 exit 113 1149: rsub ip, ip, #4 115 csub.a ip, #2 116 ldr1b r1, r3, sg, abort=21f 117 ldr1b r1, r4, eg, abort=21f 118 ldr1b r1, r11, abort=21f 119 str1b r0, r3, sg, abort=21f 120 str1b r0, r4, eg, abort=21f 121 sub.a r2, r2, ip 122 str1b r0, r11, abort=21f 123 bsl 8b 124 and.a ip, r1, #3 125 beq 1b 126 12710: andn r1, r1, #3 128 csub.a ip, #2 129 ldr1w r1, r11, abort=21f 130 beq 17f 131 bsg 18f 132 133 134 .macro forward_copy_shift a b 135 136 sub.a r2, r2, #28 137 bsl 14f 138 13911: stm.w (r5 - r9), [sp-] 140 14112: 142 ldr4w r1, r4, r5, r6, r7, abort=19f 143 mov r3, r11 pull #\a 144 sub.a r2, r2, #32 145 ldr4w r1, r8, r9, r10, r11, abort=19f 146 or r3, r3, r4 push #\b 147 mov r4, r4 pull #\a 148 or r4, r4, r5 push #\b 149 mov r5, r5 pull #\a 150 or r5, r5, r6 push #\b 151 mov r6, r6 pull #\a 152 or r6, r6, r7 push #\b 153 mov r7, r7 pull #\a 154 or r7, r7, r8 push #\b 155 mov r8, r8 pull #\a 156 or r8, r8, r9 push #\b 157 mov r9, r9 pull #\a 158 or r9, r9, r10 push #\b 159 mov r10, r10 pull #\a 160 or r10, r10, r11 push #\b 161 str8w r0, r3, r4, r5, r6, r7, r8, r9, r10, , abort=19f 162 beg 12b 163 164 ldm.w (r5 - r9), [sp]+ 165 16614: and.a ip, r2, #28 167 beq 16f 168 16915: mov r3, r11 pull #\a 170 ldr1w r1, r11, abort=21f 171 sub.a ip, ip, #4 172 or r3, r3, r11 push #\b 173 str1w r0, r3, abort=21f 174 bsg 15b 175 17616: sub r1, r1, #(\b / 8) 177 b 8b 178 179 .endm 180 181 182 forward_copy_shift a=8 b=24 183 18417: forward_copy_shift a=16 b=16 185 18618: forward_copy_shift a=24 b=8 187 188 189/* 190 * Abort preamble and completion macros. 191 * If a fixup handler is required then those macros must surround it. 192 * It is assumed that the fixup code will handle the private part of 193 * the exit macro. 194 */ 195 196 .macro copy_abort_preamble 19719: ldm.w (r5 - r9), [sp]+ 198 b 21f 199299: .word 0 @ store lr 200 @ to avoid function call in fixup 20120: ldm.w (r5 - r8), [sp]+ 20221: 203 adr r1, 299b 204 stw lr, [r1] 205 .endm 206 207 .macro copy_abort_end 208 adr lr, 299b 209 ldw pc, [lr] 210 .endm 211 212