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