/*1* linux/arch/arm/lib/copy_template.s2*3* Code template for optimized memory copy functions4*5* Author: Nicolas Pitre6* Created: Sep 28, 20057* Copyright: MontaVista Software, Inc.8*9* This program is free software; you can redistribute it and/or modify10* it under the terms of the GNU General Public License version 2 as11* published by the Free Software Foundation.12*/1314/*15* Theory of operation16* -------------------17*18* This file provides the core code for a forward memory copy used in19* the implementation of memcopy(), copy_to_user() and copy_from_user().20*21* The including file must define the following accessor macros22* according to the need of the given function:23*24* ldr1w ptr reg abort25*26* This loads one word from 'ptr', stores it in 'reg' and increments27* 'ptr' to the next word. The 'abort' argument is used for fixup tables.28*29* ldr4w ptr reg1 reg2 reg3 reg4 abort30* ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort31*32* This loads four or eight words starting from 'ptr', stores them33* in provided registers and increments 'ptr' past those words.34* The'abort' argument is used for fixup tables.35*36* ldr1b ptr reg cond abort37*38* Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.39* It also must apply the condition code if provided, otherwise the40* "al" condition is assumed by default.41*42* str1w ptr reg abort43* str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort44* str1b ptr reg cond abort45*46* Same as their ldr* counterparts, but data is stored to 'ptr' location47* rather than being loaded.48*49* enter reg1 reg250*51* Preserve the provided registers on the stack plus any additional52* data as needed by the implementation including this code. Called53* upon code entry.54*55* exit reg1 reg256*57* Restore registers with the values previously saved with the58* 'preserv' macro. Called upon code termination.59*60* LDR1W_SHIFT61* STR1W_SHIFT62*63* Correction to be applied to the "ip" register when branching into64* the ldr1w or str1w instructions (some of these macros may expand to65* than one 32bit instruction in Thumb-2)66*/676869enter r4, lr7071subs r2, r2, #472blt 8f73ands ip, r0, #374PLD( pld [r1, #0] )75bne 9f76ands ip, r1, #377bne 10f78791: subs r2, r2, #(28)80stmfd sp!, {r5 - r8}81blt 5f8283CALGN( ands ip, r0, #31 )84CALGN( rsb r3, ip, #32 )85CALGN( sbcnes r4, r3, r2 ) @ C is always set here86CALGN( bcs 2f )87CALGN( adr r4, 6f )88CALGN( subs r2, r2, r3 ) @ C gets set89CALGN( add pc, r4, ip )9091PLD( pld [r1, #0] )922: PLD( subs r2, r2, #96 )93PLD( pld [r1, #28] )94PLD( blt 4f )95PLD( pld [r1, #60] )96PLD( pld [r1, #92] )97983: PLD( pld [r1, #124] )994: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f100subs r2, r2, #32101str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f102bge 3b103PLD( cmn r2, #96 )104PLD( bge 4b )1051065: ands ip, r2, #28107rsb ip, ip, #32108#if LDR1W_SHIFT > 0109lsl ip, ip, #LDR1W_SHIFT110#endif111addne pc, pc, ip @ C is always clear here112b 7f1136:114.rept (1 << LDR1W_SHIFT)115W(nop)116.endr117ldr1w r1, r3, abort=20f118ldr1w r1, r4, abort=20f119ldr1w r1, r5, abort=20f120ldr1w r1, r6, abort=20f121ldr1w r1, r7, abort=20f122ldr1w r1, r8, abort=20f123ldr1w r1, lr, abort=20f124125#if LDR1W_SHIFT < STR1W_SHIFT126lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT127#elif LDR1W_SHIFT > STR1W_SHIFT128lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT129#endif130add pc, pc, ip131nop132.rept (1 << STR1W_SHIFT)133W(nop)134.endr135str1w r0, r3, abort=20f136str1w r0, r4, abort=20f137str1w r0, r5, abort=20f138str1w r0, r6, abort=20f139str1w r0, r7, abort=20f140str1w r0, r8, abort=20f141str1w r0, lr, abort=20f142143CALGN( bcs 2b )1441457: ldmfd sp!, {r5 - r8}1461478: movs r2, r2, lsl #31148ldr1b r1, r3, ne, abort=21f149ldr1b r1, r4, cs, abort=21f150ldr1b r1, ip, cs, abort=21f151str1b r0, r3, ne, abort=21f152str1b r0, r4, cs, abort=21f153str1b r0, ip, cs, abort=21f154155exit r4, pc1561579: rsb ip, ip, #4158cmp ip, #2159ldr1b r1, r3, gt, abort=21f160ldr1b r1, r4, ge, abort=21f161ldr1b r1, lr, abort=21f162str1b r0, r3, gt, abort=21f163str1b r0, r4, ge, abort=21f164subs r2, r2, ip165str1b r0, lr, abort=21f166blt 8b167ands ip, r1, #3168beq 1b16917010: bic r1, r1, #3171cmp ip, #2172ldr1w r1, lr, abort=21f173beq 17f174bgt 18f175176177.macro forward_copy_shift pull push178179subs r2, r2, #28180blt 14f181182CALGN( ands ip, r0, #31 )183CALGN( rsb ip, ip, #32 )184CALGN( sbcnes r4, ip, r2 ) @ C is always set here185CALGN( subcc r2, r2, ip )186CALGN( bcc 15f )18718811: stmfd sp!, {r5 - r9}189190PLD( pld [r1, #0] )191PLD( subs r2, r2, #96 )192PLD( pld [r1, #28] )193PLD( blt 13f )194PLD( pld [r1, #60] )195PLD( pld [r1, #92] )19619712: PLD( pld [r1, #124] )19813: ldr4w r1, r4, r5, r6, r7, abort=19f199mov r3, lr, pull #\pull200subs r2, r2, #32201ldr4w r1, r8, r9, ip, lr, abort=19f202orr r3, r3, r4, push #\push203mov r4, r4, pull #\pull204orr r4, r4, r5, push #\push205mov r5, r5, pull #\pull206orr r5, r5, r6, push #\push207mov r6, r6, pull #\pull208orr r6, r6, r7, push #\push209mov r7, r7, pull #\pull210orr r7, r7, r8, push #\push211mov r8, r8, pull #\pull212orr r8, r8, r9, push #\push213mov r9, r9, pull #\pull214orr r9, r9, ip, push #\push215mov ip, ip, pull #\pull216orr ip, ip, lr, push #\push217str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f218bge 12b219PLD( cmn r2, #96 )220PLD( bge 13b )221222ldmfd sp!, {r5 - r9}22322414: ands ip, r2, #28225beq 16f22622715: mov r3, lr, pull #\pull228ldr1w r1, lr, abort=21f229subs ip, ip, #4230orr r3, r3, lr, push #\push231str1w r0, r3, abort=21f232bgt 15b233CALGN( cmp r2, #0 )234CALGN( bge 11b )23523616: sub r1, r1, #(\push / 8)237b 8b238239.endm240241242forward_copy_shift pull=8 push=2424324417: forward_copy_shift pull=16 push=1624524618: forward_copy_shift pull=24 push=8247248249/*250* Abort preamble and completion macros.251* If a fixup handler is required then those macros must surround it.252* It is assumed that the fixup code will handle the private part of253* the exit macro.254*/255256.macro copy_abort_preamble25719: ldmfd sp!, {r5 - r9}258b 21f25920: ldmfd sp!, {r5 - r8}26021:261.endm262263.macro copy_abort_end264ldmfd sp!, {r4, pc}265.endm266267268269