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
|
/* $NetBSD: memset.S,v 1.4 2001/12/04 17:56:33 wiz Exp $ */
/*
* Written by Matthias Pfaller, 1996
* Public domain.
*/
#include <machine/asm.h>
#if defined(LIBC_SCCS)
RCSID("$NetBSD: memset.S,v 1.4 2001/12/04 17:56:33 wiz Exp $")
# if defined(BZERO)
RCSID("$Masqueraded: as bzero $")
# endif
#endif
#if !defined(BZERO)
/*
* void *
* memset (void *b, int c, size_t len)
* write len bytes of value c to the string b.
*/
#define SETMEMB(d) movb r4,d
#define SETMEMD(d) movd r4,d
KENTRY(memset, 12)
enter [r3,r4],0
movd B_ARG0,r1 /* b */
movzbd B_ARG1,r0 /* c */
movd 0x01010101,r4
muld r0,r4
movd B_ARG2,r2 /* len */
#else
/*
* void
* bzero (void *b, size_t len)
* write len zero bytes to the string b.
*/
#define SETMEMB(d) movqb 0,d
#define SETMEMD(d) movqd 0,d
KENTRY(bzero, 8)
enter [r3],0
movd B_ARG0,r1 /* b */
movd B_ARG1,r2 /* len */
#endif
cmpd 19,r2
bhs 6f /* Not worth the trouble. */
/*
* Is address aligned?
*/
movqd 3,r0
andd r1,r0 /* r0 = b & 3 */
cmpqd 0,r0
beq 0f
/*
* Align address (if necessary).
*/
SETMEMD(0(r1))
addr -4(r0)[r2:b],r2 /* len = len + (r0 - 4) */
negd r0,r0
addr 4(r0)[r1:b],r1 /* b = b + (-r0 + 4) */
0: /*
* Compute loop start address.
*/
movd r2,r0
addr 60(r2),r3
andd 60,r0 /* r0 = len & 60 */
lshd -6,r3 /* r3 = (len + 60) >> 6 */
andd 3,r2 /* len &= 3 */
cmpqd 0,r0
beq 1f
addr -64(r1)[r0:b],r1 /* b = b - 64 + r0 */
lshd -2,r0
addr 0(r0)[r0:w],r0
negd r0,r0 /* r0 = -3 * r0 / 4 */
jump 2f(pc)[r0:b] /* Now enter the loop */
/*
* Zero 64 bytes per loop iteration.
*/
.align 2
1: SETMEMD(0(r1))
SETMEMD(4(r1))
SETMEMD(8(r1))
SETMEMD(12(r1))
SETMEMD(16(r1))
SETMEMD(20(r1))
SETMEMD(24(r1))
SETMEMD(28(r1))
SETMEMD(32(r1))
SETMEMD(36(r1))
SETMEMD(40(r1))
SETMEMD(44(r1))
SETMEMD(48(r1))
SETMEMD(52(r1))
SETMEMD(56(r1))
SETMEMD(60(r1))
2: addd 64,r1
acbd -1,r3,1b
3: cmpqd 0,r2
beq 5f
/*
* Zero out blocks shorter than four bytes.
*/
4: SETMEMB(-1(r1)[r2:b])
acbd -1,r2,4b
#ifndef BZERO
5: movd B_ARG0,r0
exit [r3,r4]
ret ARGS
#else
5: exit [r3]
ret ARGS
#endif
/*
* For blocks smaller than 20 bytes
* this is faster.
*/
.align 2
6: cmpqd 3,r2
bhs 3b
movd r2,r0
andd 3,r2
lshd -2,r0
7: SETMEMD(0(r1))
addqd 4,r1
acbd -1,r0,7b
br 3b
|