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 * Returns 0, if ok, and number of bytes not yet set if exception 7 * occurs and we were called as clear_user. 8 */ 9 10#include <asm/ptrace.h> 11 12#define ALLOC #alloc 13#define EXECINSTR #execinstr 14#define EX(x,y,a,b) \ 1598: x,y; \ 16 .section .fixup,ALLOC,EXECINSTR; \ 17 .align 4; \ 1899: ba 30f; \ 19 a, b, %o0; \ 20 .section __ex_table,ALLOC; \ 21 .align 4; \ 22 .word 98b, 99b; \ 23 .text; \ 24 .align 4 25 26#define EXT(start,end,handler) \ 27 .section __ex_table,ALLOC; \ 28 .align 4; \ 29 .word start, 0, end, handler; \ 30 .text; \ 31 .align 4 32 33/* Please don't change these macros, unless you change the logic 34 * in the .fixup section below as well. 35 * Store 64 bytes at (BASE + OFFSET) using value SOURCE. */ 36#define ZERO_BIG_BLOCK(base, offset, source) \ 37 std source, [base + offset + 0x00]; \ 38 std source, [base + offset + 0x08]; \ 39 std source, [base + offset + 0x10]; \ 40 std source, [base + offset + 0x18]; \ 41 std source, [base + offset + 0x20]; \ 42 std source, [base + offset + 0x28]; \ 43 std source, [base + offset + 0x30]; \ 44 std source, [base + offset + 0x38]; 45 46#define ZERO_LAST_BLOCKS(base, offset, source) \ 47 std source, [base - offset - 0x38]; \ 48 std source, [base - offset - 0x30]; \ 49 std source, [base - offset - 0x28]; \ 50 std source, [base - offset - 0x20]; \ 51 std source, [base - offset - 0x18]; \ 52 std source, [base - offset - 0x10]; \ 53 std source, [base - offset - 0x08]; \ 54 std source, [base - offset - 0x00]; 55 56 .text 57 .align 4 58 59 .globl __bzero_begin 60__bzero_begin: 61 62 .globl __bzero 63 .globl memset 64 .globl __memset_start, __memset_end 65__memset_start: 66memset: 67 and %o1, 0xff, %g3 68 sll %g3, 8, %g2 69 or %g3, %g2, %g3 70 sll %g3, 16, %g2 71 or %g3, %g2, %g3 72 b 1f 73 mov %o2, %o1 743: 75 cmp %o2, 3 76 be 2f 77 EX(stb %g3, [%o0], sub %o1, 0) 78 79 cmp %o2, 2 80 be 2f 81 EX(stb %g3, [%o0 + 0x01], sub %o1, 1) 82 83 EX(stb %g3, [%o0 + 0x02], sub %o1, 2) 842: 85 sub %o2, 4, %o2 86 add %o1, %o2, %o1 87 b 4f 88 sub %o0, %o2, %o0 89 90__bzero: 91 mov %g0, %g3 921: 93 cmp %o1, 7 94 bleu 7f 95 andcc %o0, 3, %o2 96 97 bne 3b 984: 99 andcc %o0, 4, %g0 100 101 be 2f 102 mov %g3, %g2 103 104 EX(st %g3, [%o0], sub %o1, 0) 105 sub %o1, 4, %o1 106 add %o0, 4, %o0 1072: 108 andcc %o1, 0xffffff80, %o3 ! Now everything is 8 aligned and o1 is len to run 109 be 9f 110 andcc %o1, 0x78, %o2 11110: 112 ZERO_BIG_BLOCK(%o0, 0x00, %g2) 113 subcc %o3, 128, %o3 114 ZERO_BIG_BLOCK(%o0, 0x40, %g2) 11511: 116 EXT(10b, 11b, 20f) 117 bne 10b 118 add %o0, 128, %o0 119 120 orcc %o2, %g0, %g0 1219: 122 be 13f 123 andcc %o1, 7, %o1 124 125 srl %o2, 1, %o3 126 set 13f, %o4 127 sub %o4, %o3, %o4 128 jmp %o4 129 add %o0, %o2, %o0 130 13112: 132 ZERO_LAST_BLOCKS(%o0, 0x48, %g2) 133 ZERO_LAST_BLOCKS(%o0, 0x08, %g2) 13413: 135 be 8f 136 andcc %o1, 4, %g0 137 138 be 1f 139 andcc %o1, 2, %g0 140 141 EX(st %g3, [%o0], and %o1, 7) 142 add %o0, 4, %o0 1431: 144 be 1f 145 andcc %o1, 1, %g0 146 147 EX(sth %g3, [%o0], and %o1, 3) 148 add %o0, 2, %o0 1491: 150 bne,a 8f 151 EX(stb %g3, [%o0], and %o1, 1) 1528: 153 retl 154 clr %o0 1557: 156 be 13b 157 orcc %o1, 0, %g0 158 159 be 0f 1608: 161 add %o0, 1, %o0 162 subcc %o1, 1, %o1 163 bne 8b 164 EX(stb %g3, [%o0 - 1], add %o1, 1) 1650: 166 retl 167 clr %o0 168__memset_end: 169 170 .section .fixup,#alloc,#execinstr 171 .align 4 17220: 173 cmp %g2, 8 174 bleu 1f 175 and %o1, 0x7f, %o1 176 sub %g2, 9, %g2 177 add %o3, 64, %o3 1781: 179 sll %g2, 3, %g2 180 add %o3, %o1, %o0 181 b 30f 182 sub %o0, %g2, %o0 18321: 184 mov 8, %o0 185 and %o1, 7, %o1 186 sub %o0, %g2, %o0 187 sll %o0, 3, %o0 188 b 30f 189 add %o0, %o1, %o0 19030: 191/* %o4 is faulting address, %o5 is %pc where fault occurred */ 192 save %sp, -104, %sp 193 mov %i5, %o0 194 mov %i7, %o1 195 call lookup_fault 196 mov %i4, %o2 197 ret 198 restore 199 200 .globl __bzero_end 201__bzero_end: 202