1/* linux/arch/sparc/lib/memset.S: Sparc optimized memset, bzero and clear_user code 2 * Copyright (C) 1991,1996 Free Software Foundation 3 * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 4 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) 5 * 6 * Calls to memset returns initial %o0. Calls to bzero returns 0, if ok, and 7 * number of bytes not yet set if exception occurs and we were called as 8 * clear_user. 9 */ 10 11#include <asm/ptrace.h> 12#include <asm/export.h> 13 14/* Work around cpp -rob */ 15#define ALLOC #alloc 16#define EXECINSTR #execinstr 17#define EX(x,y,a,b) \ 1898: x,y; \ 19 .section .fixup,ALLOC,EXECINSTR; \ 20 .align 4; \ 2199: ba 30f; \ 22 a, b, %o0; \ 23 .section __ex_table,ALLOC; \ 24 .align 4; \ 25 .word 98b, 99b; \ 26 .text; \ 27 .align 4 28 29#define EXT(start,end,handler) \ 30 .section __ex_table,ALLOC; \ 31 .align 4; \ 32 .word start, 0, end, handler; \ 33 .text; \ 34 .align 4 35 36/* Please don't change these macros, unless you change the logic 37 * in the .fixup section below as well. 38 * Store 64 bytes at (BASE + OFFSET) using value SOURCE. */ 39#define ZERO_BIG_BLOCK(base, offset, source) \ 40 std source, [base + offset + 0x00]; \ 41 std source, [base + offset + 0x08]; \ 42 std source, [base + offset + 0x10]; \ 43 std source, [base + offset + 0x18]; \ 44 std source, [base + offset + 0x20]; \ 45 std source, [base + offset + 0x28]; \ 46 std source, [base + offset + 0x30]; \ 47 std source, [base + offset + 0x38]; 48 49#define ZERO_LAST_BLOCKS(base, offset, source) \ 50 std source, [base - offset - 0x38]; \ 51 std source, [base - offset - 0x30]; \ 52 std source, [base - offset - 0x28]; \ 53 std source, [base - offset - 0x20]; \ 54 std source, [base - offset - 0x18]; \ 55 std source, [base - offset - 0x10]; \ 56 std source, [base - offset - 0x08]; \ 57 std source, [base - offset - 0x00]; 58 59 .text 60 .align 4 61 62 .globl __bzero_begin 63__bzero_begin: 64 65 .globl __bzero 66 .type __bzero,#function 67 .globl memset 68 EXPORT_SYMBOL(__bzero) 69 EXPORT_SYMBOL(memset) 70 .globl __memset_start, __memset_end 71__memset_start: 72memset: 73 mov %o0, %g1 74 mov 1, %g4 75 and %o1, 0xff, %g3 76 sll %g3, 8, %g2 77 or %g3, %g2, %g3 78 sll %g3, 16, %g2 79 or %g3, %g2, %g3 80 b 1f 81 mov %o2, %o1 823: 83 cmp %o2, 3 84 be 2f 85 EX(stb %g3, [%o0], sub %o1, 0) 86 87 cmp %o2, 2 88 be 2f 89 EX(stb %g3, [%o0 + 0x01], sub %o1, 1) 90 91 EX(stb %g3, [%o0 + 0x02], sub %o1, 2) 922: 93 sub %o2, 4, %o2 94 add %o1, %o2, %o1 95 b 4f 96 sub %o0, %o2, %o0 97 98__bzero: 99 clr %g4 100 mov %g0, %g3 1011: 102 cmp %o1, 7 103 bleu 7f 104 andcc %o0, 3, %o2 105 106 bne 3b 1074: 108 andcc %o0, 4, %g0 109 110 be 2f 111 mov %g3, %g2 112 113 EX(st %g3, [%o0], sub %o1, 0) 114 sub %o1, 4, %o1 115 add %o0, 4, %o0 1162: 117 andcc %o1, 0xffffff80, %o3 ! Now everything is 8 aligned and o1 is len to run 118 be 9f 119 andcc %o1, 0x78, %o2 12010: 121 ZERO_BIG_BLOCK(%o0, 0x00, %g2) 122 subcc %o3, 128, %o3 123 ZERO_BIG_BLOCK(%o0, 0x40, %g2) 12411: 125 EXT(10b, 11b, 20f) 126 bne 10b 127 add %o0, 128, %o0 128 129 orcc %o2, %g0, %g0 1309: 131 be 13f 132 andcc %o1, 7, %o1 133 134 srl %o2, 1, %o3 135 set 13f, %o4 136 sub %o4, %o3, %o4 137 jmp %o4 138 add %o0, %o2, %o0 139 14012: 141 ZERO_LAST_BLOCKS(%o0, 0x48, %g2) 142 ZERO_LAST_BLOCKS(%o0, 0x08, %g2) 14313: 144 be 8f 145 andcc %o1, 4, %g0 146 147 be 1f 148 andcc %o1, 2, %g0 149 150 EX(st %g3, [%o0], and %o1, 7) 151 add %o0, 4, %o0 1521: 153 be 1f 154 andcc %o1, 1, %g0 155 156 EX(sth %g3, [%o0], and %o1, 3) 157 add %o0, 2, %o0 1581: 159 bne,a 8f 160 EX(stb %g3, [%o0], and %o1, 1) 1618: 162 b 0f 163 nop 1647: 165 be 13b 166 orcc %o1, 0, %g0 167 168 be 0f 1698: 170 add %o0, 1, %o0 171 subcc %o1, 1, %o1 172 bne 8b 173 EX(stb %g3, [%o0 - 1], add %o1, 1) 1740: 175 andcc %g4, 1, %g0 176 be 5f 177 nop 178 retl 179 mov %g1, %o0 1805: 181 retl 182 clr %o0 183__memset_end: 184 185 .section .fixup,#alloc,#execinstr 186 .align 4 18720: 188 cmp %g2, 8 189 bleu 1f 190 and %o1, 0x7f, %o1 191 sub %g2, 9, %g2 192 add %o3, 64, %o3 1931: 194 sll %g2, 3, %g2 195 add %o3, %o1, %o0 196 b 30f 197 sub %o0, %g2, %o0 19821: 199 mov 8, %o0 200 and %o1, 7, %o1 201 sub %o0, %g2, %o0 202 sll %o0, 3, %o0 203 b 30f 204 add %o0, %o1, %o0 20530: 206/* %o4 is faulting address, %o5 is %pc where fault occurred */ 207 save %sp, -104, %sp 208 mov %i5, %o0 209 mov %i7, %o1 210 call lookup_fault 211 mov %i4, %o2 212 ret 213 restore 214 215 .globl __bzero_end 216__bzero_end: 217