Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | /* * linux/arch/arm/lib/string.S * * Copyright (C) 1995-1998 Russell King * * This is commonly used to clear the frame buffer and the frame * backing buffer. As such, it will be rarely called with r2 < 32. * * Optimisations by Matthew Wilcox */ #include <linux/linkage.h> #include <asm/assembler.h> .text # Prototype: char *strrchr(const char *s,char c); /* * Prototype: void memzero(void *d, size_t n) */ ENTRY(memzero) mov r2, r1 mov r1, #0 /* * Prototype: void memsetl(unsigned long *d, unsigned long c, size_t n) */ ENTRY(memsetl) teq r2, #0 RETINSTR(moveq,pc,lr) stmfd sp!, {lr} mov lr, r1 mov r3, r1 mov ip, r1 @ r2 = {32 ... 4} 1: subs r2, r2, #32 stmgeia r0!, {r1, r3, ip, lr} stmgeia r0!, {r1, r3, ip, lr} bgt 1b LOADREGS(eqfd, sp!, {pc}) @ r2 can be {-4 ... -28} cmp r2, #-16 stmgeia r0!, {r1, r3, ip, lr} addlts r2, r2, #16 LOADREGS(eqfd, sp!, {pc}) @ r2 can be {-4 ... -12} cmp r2, #-8 stmgeia r0!, {r1, r3} strne r1, [r0] LOADREGS(fd, sp!, {pc}) .global __page_memcpy __page_memcpy: stmfd sp!, {r4, r5, lr} 1: subs r2, r2, #4*8 ldmgeia r1!, {r3, r4, r5, ip} stmgeia r0!, {r3, r4, r5, ip} ldmgeia r1!, {r3, r4, r5, ip} stmgeia r0!, {r3, r4, r5, ip} bgt 1b LOADREGS(fd, sp!, {r4, r5, pc}) .global memset memset: mov r3, r0 cmp r2, #16 blt 6f ands ip, r3, #3 beq 1f cmp ip, #2 strltb r1, [r3], #1 @ Align destination strleb r1, [r3], #1 strb r1, [r3], #1 rsb ip, ip, #4 sub r2, r2, ip 1: orr r1, r1, r1, lsl #8 orr r1, r1, r1, lsl #16 cmp r2, #256 blt 4f stmfd sp!, {r4, r5, lr} mov r4, r1 mov r5, r1 mov lr, r1 mov ip, r2, lsr #6 sub r2, r2, ip, lsl #6 2: stmia r3!, {r1, r4, r5, lr} @ 64 bytes at a time. stmia r3!, {r1, r4, r5, lr} stmia r3!, {r1, r4, r5, lr} stmia r3!, {r1, r4, r5, lr} subs ip, ip, #1 bne 2b teq r2, #0 LOADREGS(eqfd, sp!, {r4, r5, pc}) @ Now <64 bytes to go. tst r2, #32 stmneia r3!, {r1, r4, r5, lr} stmneia r3!, {r1, r4, r5, lr} tst r2, #16 stmneia r3!, {r1, r4, r5, lr} ldmia sp!, {r4, r5} 3: tst r2, #8 stmneia r3!, {r1, lr} tst r2, #4 strne r1, [r3], #4 tst r2, #2 strneb r1, [r3], #1 strneb r1, [r3], #1 tst r2, #1 strneb r1, [r3], #1 LOADREGS(fd, sp!, {pc}) 4: movs ip, r2, lsr #3 beq 3b sub r2, r2, ip, lsl #3 stmfd sp!, {lr} mov lr, r1 subs ip, ip, #4 5: stmgeia r3!, {r1, lr} stmgeia r3!, {r1, lr} stmgeia r3!, {r1, lr} stmgeia r3!, {r1, lr} subges ip, ip, #4 bge 5b tst ip, #2 stmneia r3!, {r1, lr} stmneia r3!, {r1, lr} tst ip, #1 stmneia r3!, {r1, lr} teq r2, #0 LOADREGS(eqfd, sp!, {pc}) b 3b 6: subs r2, r2, #1 strgeb r1, [r3], #1 bgt 6b RETINSTR(mov, pc, lr) ENTRY(strrchr) stmfd sp!, {lr} mov r3, #0 1: ldrb r2, [r0], #1 teq r2, r1 moveq r3, r0 teq r2, #0 bne 1b mov r0, r3 LOADREGS(fd, sp!, {pc}) ENTRY(strchr) stmfd sp!,{lr} mov r3, #0 1: ldrb r2, [r0], #1 teq r2, r1 teqne r2, #0 bne 1b teq r2, #0 moveq r0, #0 subne r0, r0, #1 LOADREGS(fd, sp!, {pc}) ENTRY(memchr) stmfd sp!, {lr} 1: ldrb r3, [r0], #1 teq r3, r1 beq 2f subs r2, r2, #1 bpl 1b 2: movne r0, #0 subeq r0, r0, #1 LOADREGS(fd, sp!, {pc}) |