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
|
/* $Id: memset.S,v 1.3 2000/01/15 23:48:55 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1998, 1999 by Ralf Baechle
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
#include <asm/asm.h>
#include <asm/offset.h>
#include <asm/regdef.h>
#define EX(insn,reg,addr,handler) \
9: insn reg, addr; \
.section __ex_table,"a"; \
PTR 9b, handler; \
.previous
#define F_FILL64(dst, offset, val, fixup) \
EX(sd, val, (offset + 0x00)(dst), fixup); \
EX(sd, val, (offset + 0x08)(dst), fixup); \
EX(sd, val, (offset + 0x10)(dst), fixup); \
EX(sd, val, (offset + 0x18)(dst), fixup); \
EX(sd, val, (offset + 0x20)(dst), fixup); \
EX(sd, val, (offset + 0x28)(dst), fixup); \
EX(sd, val, (offset + 0x30)(dst), fixup); \
EX(sd, val, (offset + 0x38)(dst), fixup)
/*
* memset(void *s, int c, size_t n)
*
* a0: start of area to clear
* a1: char to fill with
* a2: size of area to clear
*/
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
.set noreorder
.align 5
LEAF(memset)
beqz a1, 1f
move v0, a0 /* result */
andi a1, 0xff /* spread fillword */
dsll t1, a1, 8
or a1, t1
dsll t1, a1, 16
or a1, t1
dsll t1, a1, 32
or a1, t1
1:
FEXPORT(__bzero)
sltiu t0, a2, 8 /* very small region? */
bnez t0, small_memset
andi t0, a0, 7 /* aligned? */
beqz t0, 1f
dsubu t0, 8 /* alignment in bytes */
#ifdef __MIPSEB__
EX(sdl, a1, (a0), first_fixup) /* make dword aligned */
#endif
#ifdef __MIPSEL__
EX(sdr, a1, (a0), first_fixup) /* make dword aligned */
#endif
dsubu a0, t0 /* dword align ptr */
daddu a2, t0 /* correct size */
1: ori t1, a2, 0x3f /* # of full blocks */
xori t1, 0x3f
beqz t1, memset_partial /* no block to fill */
andi t0, a2, 0x38
daddu t1, a0 /* end address */
.set reorder
1: daddiu a0, 64
F_FILL64(a0, -64, a1, fwd_fixup)
bne t1, a0, 1b
.set noreorder
memset_partial:
la t1, 2f /* where to start */
.set noat
dsrl AT, t0, 1
dsubu t1, AT
.set noat
jr t1
daddu a0, t0 /* dest ptr */
F_FILL64(a0, -64, a1, partial_fixup) /* ... but first do dwds ... */
2: andi a2, 7 /* 0 <= n <= 7 to go */
beqz a2, 1f
daddu a0, a2 /* What's left */
#ifdef __MIPSEB__
EX(sdr, a1, -1(a0), last_fixup)
#endif
#ifdef __MIPSEL__
EX(sdl, a1, -1(a0), last_fixup)
#endif
1: jr ra
move a2, zero
small_memset:
beqz a2, 2f
daddu t1, a0, a2
1: daddiu a0, 1 /* fill bytewise */
bne t1, a0, 1b
sb a1, -1(a0)
2: jr ra /* done */
move a2, zero
END(memset)
first_fixup:
jr ra
nop
fwd_fixup:
ld t0, THREAD_BUADDR($28)
andi a2, 0x3f
daddu a2, t1
jr ra
dsubu a2, t0
partial_fixup:
ld t0, THREAD_BUADDR($28)
andi a2, 7
daddu a2, t1
jr ra
dsubu a2, t0
last_fixup:
jr ra
andi v1, a2, 7
|