/*1* linux/arch/arm/lib/memset.S2*3* Copyright (C) 1995-2000 Russell King4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License version 2 as7* published by the Free Software Foundation.8*9* ASM optimised string functions10*/11#include <linux/linkage.h>12#include <asm/assembler.h>1314.text15.align 516.word 017181: subs r2, r2, #4 @ 1 do we have enough19blt 5f @ 1 bytes to align with?20cmp r3, #2 @ 121strltb r1, [r0], #1 @ 122strleb r1, [r0], #1 @ 123strb r1, [r0], #1 @ 124add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))25/*26* The pointer is now aligned and the length is adjusted. Try doing the27* memset again.28*/2930ENTRY(memset)31ands r3, r0, #3 @ 1 unaligned?32bne 1b @ 133/*34* we know that the pointer in r0 is aligned to a word boundary.35*/36orr r1, r1, r1, lsl #837orr r1, r1, r1, lsl #1638mov r3, r139cmp r2, #1640blt 4f4142#if ! CALGN(1)+04344/*45* We need an extra register for this loop - save the return address and46* use the LR47*/48str lr, [sp, #-4]!49mov ip, r150mov lr, r151522: subs r2, r2, #6453stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.54stmgeia r0!, {r1, r3, ip, lr}55stmgeia r0!, {r1, r3, ip, lr}56stmgeia r0!, {r1, r3, ip, lr}57bgt 2b58ldmeqfd sp!, {pc} @ Now <64 bytes to go.59/*60* No need to correct the count; we're only testing bits from now on61*/62tst r2, #3263stmneia r0!, {r1, r3, ip, lr}64stmneia r0!, {r1, r3, ip, lr}65tst r2, #1666stmneia r0!, {r1, r3, ip, lr}67ldr lr, [sp], #46869#else7071/*72* This version aligns the destination pointer in order to write73* whole cache lines at once.74*/7576stmfd sp!, {r4-r7, lr}77mov r4, r178mov r5, r179mov r6, r180mov r7, r181mov ip, r182mov lr, r18384cmp r2, #9685tstgt r0, #3186ble 3f8788and ip, r0, #3189rsb ip, ip, #3290sub r2, r2, ip91movs ip, ip, lsl #(32 - 4)92stmcsia r0!, {r4, r5, r6, r7}93stmmiia r0!, {r4, r5}94tst ip, #(1 << 30)95mov ip, r196strne r1, [r0], #497983: subs r2, r2, #6499stmgeia r0!, {r1, r3-r7, ip, lr}100stmgeia r0!, {r1, r3-r7, ip, lr}101bgt 3b102ldmeqfd sp!, {r4-r7, pc}103104tst r2, #32105stmneia r0!, {r1, r3-r7, ip, lr}106tst r2, #16107stmneia r0!, {r4-r7}108ldmfd sp!, {r4-r7, lr}109110#endif1111124: tst r2, #8113stmneia r0!, {r1, r3}114tst r2, #4115strne r1, [r0], #4116/*117* When we get here, we've got less than 4 bytes to zero. We118* may have an unaligned pointer as well.119*/1205: tst r2, #2121strneb r1, [r0], #1122strneb r1, [r0], #1123tst r2, #1124strneb r1, [r0], #1125mov pc, lr126ENDPROC(memset)127128129