Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/xtensa/lib/memset.S
26424 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 <linux/linkage.h>
15
#include <asm/asmmacro.h>
16
#include <asm/core.h>
17
18
/*
19
* void *memset(void *dst, int c, size_t length)
20
*
21
* The algorithm is as follows:
22
* Create a word with c in all byte positions
23
* If the destination is aligned,
24
* do 16B chucks with a loop, and then finish up with
25
* 8B, 4B, 2B, and 1B stores conditional on the length.
26
* If destination is unaligned, align it by conditionally
27
* setting 1B and 2B and then go to aligned case.
28
* This code tries to use fall-through branches for the common
29
* case of an aligned destination (except for the branches to
30
* the alignment labels).
31
*/
32
33
.text
34
ENTRY(__memset)
35
WEAK(memset)
36
37
abi_entry_default
38
# a2/ dst, a3/ c, a4/ length
39
extui a3, a3, 0, 8 # mask to just 8 bits
40
slli a7, a3, 8 # duplicate character in all bytes of word
41
or a3, a3, a7 # ...
42
slli a7, a3, 16 # ...
43
or a3, a3, a7 # ...
44
mov a5, a2 # copy dst so that a2 is return value
45
movi a6, 3 # for alignment tests
46
bany a2, a6, .Ldstunaligned # if dst is unaligned
47
.L0: # return here from .Ldstunaligned when dst is aligned
48
srli a7, a4, 4 # number of loop iterations with 16B
49
# per iteration
50
bnez a4, .Laligned
51
abi_ret_default
52
53
/*
54
* Destination is word-aligned.
55
*/
56
# set 16 bytes per iteration for word-aligned dst
57
.align 4 # 1 mod 4 alignment for LOOPNEZ
58
.byte 0 # (0 mod 4 alignment for LBEG)
59
.Laligned:
60
#if XCHAL_HAVE_LOOPS
61
loopnez a7, .Loop1done
62
#else /* !XCHAL_HAVE_LOOPS */
63
beqz a7, .Loop1done
64
slli a6, a7, 4
65
add a6, a6, a5 # a6 = end of last 16B chunk
66
#endif /* !XCHAL_HAVE_LOOPS */
67
.Loop1:
68
EX(10f) s32i a3, a5, 0
69
EX(10f) s32i a3, a5, 4
70
EX(10f) s32i a3, a5, 8
71
EX(10f) s32i a3, a5, 12
72
addi a5, a5, 16
73
#if !XCHAL_HAVE_LOOPS
74
blt a5, a6, .Loop1
75
#endif /* !XCHAL_HAVE_LOOPS */
76
.Loop1done:
77
bbci.l a4, 3, .L2
78
# set 8 bytes
79
EX(10f) s32i a3, a5, 0
80
EX(10f) s32i a3, a5, 4
81
addi a5, a5, 8
82
.L2:
83
bbci.l a4, 2, .L3
84
# set 4 bytes
85
EX(10f) s32i a3, a5, 0
86
addi a5, a5, 4
87
.L3:
88
bbci.l a4, 1, .L4
89
# set 2 bytes
90
EX(10f) s16i a3, a5, 0
91
addi a5, a5, 2
92
.L4:
93
bbci.l a4, 0, .L5
94
# set 1 byte
95
EX(10f) s8i a3, a5, 0
96
.L5:
97
.Lret1:
98
abi_ret_default
99
100
/*
101
* Destination is unaligned
102
*/
103
104
.Ldstunaligned:
105
bltui a4, 8, .Lbyteset # do short copies byte by byte
106
bbci.l a5, 0, .L20 # branch if dst alignment half-aligned
107
# dst is only byte aligned
108
# set 1 byte
109
EX(10f) s8i a3, a5, 0
110
addi a5, a5, 1
111
addi a4, a4, -1
112
# now retest if dst aligned
113
bbci.l a5, 1, .L0 # if now aligned, return to main algorithm
114
.L20:
115
# dst half-aligned
116
# set 2 bytes
117
EX(10f) s16i a3, a5, 0
118
addi a5, a5, 2
119
addi a4, a4, -2
120
j .L0 # dst is now aligned, return to main algorithm
121
122
/*
123
* Byte by byte set
124
*/
125
.align 4
126
.byte 0 # 1 mod 4 alignment for LOOPNEZ
127
# (0 mod 4 alignment for LBEG)
128
.Lbyteset:
129
#if XCHAL_HAVE_LOOPS
130
loopnez a4, .Lbytesetdone
131
#else /* !XCHAL_HAVE_LOOPS */
132
beqz a4, .Lbytesetdone
133
add a6, a5, a4 # a6 = ending address
134
#endif /* !XCHAL_HAVE_LOOPS */
135
.Lbyteloop:
136
EX(10f) s8i a3, a5, 0
137
addi a5, a5, 1
138
#if !XCHAL_HAVE_LOOPS
139
blt a5, a6, .Lbyteloop
140
#endif /* !XCHAL_HAVE_LOOPS */
141
.Lbytesetdone:
142
abi_ret_default
143
144
ENDPROC(__memset)
145
EXPORT_SYMBOL(__memset)
146
EXPORT_SYMBOL(memset)
147
148
.section .fixup, "ax"
149
.align 4
150
151
/* We return zero if a failure occurred. */
152
153
10:
154
movi a2, 0
155
abi_ret_default
156
157