Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/xtensa/lib/memset.S
10817 views
1
/*
2
* arch/xtensa/lib/memset.S
3
*
4
* ANSI C standard library function memset
5
* (Well, almost. .fixup code might return zero.)
6
*
7
* This file is subject to the terms and conditions of the GNU General
8
* Public License. See the file "COPYING" in the main directory of
9
* this archive for more details.
10
*
11
* Copyright (C) 2002 Tensilica Inc.
12
*/
13
14
#include <variant/core.h>
15
16
/*
17
* void *memset(void *dst, int c, size_t length)
18
*
19
* The algorithm is as follows:
20
* Create a word with c in all byte positions
21
* If the destination is aligned,
22
* do 16B chucks with a loop, and then finish up with
23
* 8B, 4B, 2B, and 1B stores conditional on the length.
24
* If destination is unaligned, align it by conditionally
25
* setting 1B and 2B and then go to aligned case.
26
* This code tries to use fall-through branches for the common
27
* case of an aligned destination (except for the branches to
28
* the alignment labels).
29
*/
30
31
/* Load or store instructions that may cause exceptions use the EX macro. */
32
33
#define EX(insn,reg1,reg2,offset,handler) \
34
9: insn reg1, reg2, offset; \
35
.section __ex_table, "a"; \
36
.word 9b, handler; \
37
.previous
38
39
40
.text
41
.align 4
42
.global memset
43
.type memset,@function
44
memset:
45
entry sp, 16 # minimal stack frame
46
# a2/ dst, a3/ c, a4/ length
47
extui a3, a3, 0, 8 # mask to just 8 bits
48
slli a7, a3, 8 # duplicate character in all bytes of word
49
or a3, a3, a7 # ...
50
slli a7, a3, 16 # ...
51
or a3, a3, a7 # ...
52
mov a5, a2 # copy dst so that a2 is return value
53
movi a6, 3 # for alignment tests
54
bany a2, a6, .Ldstunaligned # if dst is unaligned
55
.L0: # return here from .Ldstunaligned when dst is aligned
56
srli a7, a4, 4 # number of loop iterations with 16B
57
# per iteration
58
bnez a4, .Laligned
59
retw
60
61
/*
62
* Destination is word-aligned.
63
*/
64
# set 16 bytes per iteration for word-aligned dst
65
.align 4 # 1 mod 4 alignment for LOOPNEZ
66
.byte 0 # (0 mod 4 alignment for LBEG)
67
.Laligned:
68
#if XCHAL_HAVE_LOOPS
69
loopnez a7, .Loop1done
70
#else /* !XCHAL_HAVE_LOOPS */
71
beqz a7, .Loop1done
72
slli a6, a7, 4
73
add a6, a6, a5 # a6 = end of last 16B chunk
74
#endif /* !XCHAL_HAVE_LOOPS */
75
.Loop1:
76
EX(s32i, a3, a5, 0, memset_fixup)
77
EX(s32i, a3, a5, 4, memset_fixup)
78
EX(s32i, a3, a5, 8, memset_fixup)
79
EX(s32i, a3, a5, 12, memset_fixup)
80
addi a5, a5, 16
81
#if !XCHAL_HAVE_LOOPS
82
blt a5, a6, .Loop1
83
#endif /* !XCHAL_HAVE_LOOPS */
84
.Loop1done:
85
bbci.l a4, 3, .L2
86
# set 8 bytes
87
EX(s32i, a3, a5, 0, memset_fixup)
88
EX(s32i, a3, a5, 4, memset_fixup)
89
addi a5, a5, 8
90
.L2:
91
bbci.l a4, 2, .L3
92
# set 4 bytes
93
EX(s32i, a3, a5, 0, memset_fixup)
94
addi a5, a5, 4
95
.L3:
96
bbci.l a4, 1, .L4
97
# set 2 bytes
98
EX(s16i, a3, a5, 0, memset_fixup)
99
addi a5, a5, 2
100
.L4:
101
bbci.l a4, 0, .L5
102
# set 1 byte
103
EX(s8i, a3, a5, 0, memset_fixup)
104
.L5:
105
.Lret1:
106
retw
107
108
/*
109
* Destination is unaligned
110
*/
111
112
.Ldstunaligned:
113
bltui a4, 8, .Lbyteset # do short copies byte by byte
114
bbci.l a5, 0, .L20 # branch if dst alignment half-aligned
115
# dst is only byte aligned
116
# set 1 byte
117
EX(s8i, a3, a5, 0, memset_fixup)
118
addi a5, a5, 1
119
addi a4, a4, -1
120
# now retest if dst aligned
121
bbci.l a5, 1, .L0 # if now aligned, return to main algorithm
122
.L20:
123
# dst half-aligned
124
# set 2 bytes
125
EX(s16i, a3, a5, 0, memset_fixup)
126
addi a5, a5, 2
127
addi a4, a4, -2
128
j .L0 # dst is now aligned, return to main algorithm
129
130
/*
131
* Byte by byte set
132
*/
133
.align 4
134
.byte 0 # 1 mod 4 alignment for LOOPNEZ
135
# (0 mod 4 alignment for LBEG)
136
.Lbyteset:
137
#if XCHAL_HAVE_LOOPS
138
loopnez a4, .Lbytesetdone
139
#else /* !XCHAL_HAVE_LOOPS */
140
beqz a4, .Lbytesetdone
141
add a6, a5, a4 # a6 = ending address
142
#endif /* !XCHAL_HAVE_LOOPS */
143
.Lbyteloop:
144
EX(s8i, a3, a5, 0, memset_fixup)
145
addi a5, a5, 1
146
#if !XCHAL_HAVE_LOOPS
147
blt a5, a6, .Lbyteloop
148
#endif /* !XCHAL_HAVE_LOOPS */
149
.Lbytesetdone:
150
retw
151
152
153
.section .fixup, "ax"
154
.align 4
155
156
/* We return zero if a failure occurred. */
157
158
memset_fixup:
159
movi a2, 0
160
retw
161
162