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
|
/* memset.S: optimised assembly memset
*
* Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <features.h>
.text
.p2align 4
###############################################################################
#
# void *memset(void *p, char ch, size_t count)
#
# - NOTE: must not use any stack. exception detection performs function return
# to caller's fixup routine, aborting the remainder of the set
# GR4, GR7, GR8, and GR11 must be managed
#
###############################################################################
.globl memset
.type memset,@function
memset:
orcc.p gr10,gr0,gr5,icc3 ; GR5 = count
andi gr9,#0xff,gr9
or.p gr8,gr0,gr4 ; GR4 = address
beqlr icc3,#0
# conditionally write a byte to 2b-align the address
setlos.p #1,gr6
andicc gr4,#1,gr0,icc0
ckne icc0,cc7
cstb.p gr9,@(gr4,gr0) ,cc7,#1
csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3
cadd.p gr4,gr6,gr4 ,cc7,#1
beqlr icc3,#0
# conditionally write a word to 4b-align the address
andicc.p gr4,#2,gr0,icc0
subicc gr5,#2,gr0,icc1
setlos.p #2,gr6
ckne icc0,cc7
slli.p gr9,#8,gr12 ; need to double up the pattern
cknc icc1,cc5
or.p gr9,gr12,gr12
andcr cc7,cc5,cc7
csth.p gr12,@(gr4,gr0) ,cc7,#1
csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3
cadd.p gr4,gr6,gr4 ,cc7,#1
beqlr icc3,#0
# conditionally write a dword to 8b-align the address
andicc.p gr4,#4,gr0,icc0
subicc gr5,#4,gr0,icc1
setlos.p #4,gr6
ckne icc0,cc7
slli.p gr12,#16,gr13 ; need to quadruple-up the pattern
cknc icc1,cc5
or.p gr13,gr12,gr12
andcr cc7,cc5,cc7
cst.p gr12,@(gr4,gr0) ,cc7,#1
csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3
cadd.p gr4,gr6,gr4 ,cc7,#1
beqlr icc3,#0
or.p gr12,gr12,gr13 ; need to octuple-up the pattern
# the address is now 8b-aligned - loop around writing 64b chunks
setlos #8,gr7
subi.p gr4,#8,gr4 ; store with update index does weird stuff
setlos #64,gr6
subicc gr5,#64,gr0,icc0
0: cknc icc0,cc7
cstdu gr12,@(gr4,gr7) ,cc7,#1
cstdu gr12,@(gr4,gr7) ,cc7,#1
cstdu gr12,@(gr4,gr7) ,cc7,#1
cstdu gr12,@(gr4,gr7) ,cc7,#1
cstdu gr12,@(gr4,gr7) ,cc7,#1
cstdu.p gr12,@(gr4,gr7) ,cc7,#1
csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3
cstdu.p gr12,@(gr4,gr7) ,cc7,#1
subicc gr5,#64,gr0,icc0
cstdu.p gr12,@(gr4,gr7) ,cc7,#1
beqlr icc3,#0
bnc icc0,#2,0b
# now do 32-byte remnant
subicc.p gr5,#32,gr0,icc0
setlos #32,gr6
cknc icc0,cc7
cstdu.p gr12,@(gr4,gr7) ,cc7,#1
csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3
cstdu.p gr12,@(gr4,gr7) ,cc7,#1
setlos #16,gr6
cstdu.p gr12,@(gr4,gr7) ,cc7,#1
subicc gr5,#16,gr0,icc0
cstdu.p gr12,@(gr4,gr7) ,cc7,#1
beqlr icc3,#0
# now do 16-byte remnant
cknc icc0,cc7
cstdu.p gr12,@(gr4,gr7) ,cc7,#1
csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3
cstdu.p gr12,@(gr4,gr7) ,cc7,#1
beqlr icc3,#0
# now do 8-byte remnant
subicc gr5,#8,gr0,icc1
cknc icc1,cc7
cstdu.p gr12,@(gr4,gr7) ,cc7,#1
csubcc gr5,gr7,gr5 ,cc7,#1 ; also set ICC3
setlos.p #4,gr7
beqlr icc3,#0
# now do 4-byte remnant
subicc gr5,#4,gr0,icc0
addi.p gr4,#4,gr4
cknc icc0,cc7
cstu.p gr12,@(gr4,gr7) ,cc7,#1
csubcc gr5,gr7,gr5 ,cc7,#1 ; also set ICC3
subicc.p gr5,#2,gr0,icc1
beqlr icc3,#0
# now do 2-byte remnant
setlos #2,gr7
addi.p gr4,#2,gr4
cknc icc1,cc7
csthu.p gr12,@(gr4,gr7) ,cc7,#1
csubcc gr5,gr7,gr5 ,cc7,#1 ; also set ICC3
subicc.p gr5,#1,gr0,icc0
beqlr icc3,#0
# now do 1-byte remnant
setlos #0,gr7
addi.p gr4,#2,gr4
cknc icc0,cc7
cstb.p gr12,@(gr4,gr0) ,cc7,#1
bralr
.size memset, .-memset
/* Experimentally off - libc_hidden_proto(memset) */
|