Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/mips/lib/memset.S
10817 views
1
/*
2
* This file is subject to the terms and conditions of the GNU General Public
3
* License. See the file "COPYING" in the main directory of this archive
4
* for more details.
5
*
6
* Copyright (C) 1998, 1999, 2000 by Ralf Baechle
7
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8
* Copyright (C) 2007 Maciej W. Rozycki
9
*/
10
#include <asm/asm.h>
11
#include <asm/asm-offsets.h>
12
#include <asm/regdef.h>
13
14
#if LONGSIZE == 4
15
#define LONG_S_L swl
16
#define LONG_S_R swr
17
#else
18
#define LONG_S_L sdl
19
#define LONG_S_R sdr
20
#endif
21
22
#define EX(insn,reg,addr,handler) \
23
9: insn reg, addr; \
24
.section __ex_table,"a"; \
25
PTR 9b, handler; \
26
.previous
27
28
.macro f_fill64 dst, offset, val, fixup
29
EX(LONG_S, \val, (\offset + 0 * LONGSIZE)(\dst), \fixup)
30
EX(LONG_S, \val, (\offset + 1 * LONGSIZE)(\dst), \fixup)
31
EX(LONG_S, \val, (\offset + 2 * LONGSIZE)(\dst), \fixup)
32
EX(LONG_S, \val, (\offset + 3 * LONGSIZE)(\dst), \fixup)
33
EX(LONG_S, \val, (\offset + 4 * LONGSIZE)(\dst), \fixup)
34
EX(LONG_S, \val, (\offset + 5 * LONGSIZE)(\dst), \fixup)
35
EX(LONG_S, \val, (\offset + 6 * LONGSIZE)(\dst), \fixup)
36
EX(LONG_S, \val, (\offset + 7 * LONGSIZE)(\dst), \fixup)
37
#if LONGSIZE == 4
38
EX(LONG_S, \val, (\offset + 8 * LONGSIZE)(\dst), \fixup)
39
EX(LONG_S, \val, (\offset + 9 * LONGSIZE)(\dst), \fixup)
40
EX(LONG_S, \val, (\offset + 10 * LONGSIZE)(\dst), \fixup)
41
EX(LONG_S, \val, (\offset + 11 * LONGSIZE)(\dst), \fixup)
42
EX(LONG_S, \val, (\offset + 12 * LONGSIZE)(\dst), \fixup)
43
EX(LONG_S, \val, (\offset + 13 * LONGSIZE)(\dst), \fixup)
44
EX(LONG_S, \val, (\offset + 14 * LONGSIZE)(\dst), \fixup)
45
EX(LONG_S, \val, (\offset + 15 * LONGSIZE)(\dst), \fixup)
46
#endif
47
.endm
48
49
/*
50
* memset(void *s, int c, size_t n)
51
*
52
* a0: start of area to clear
53
* a1: char to fill with
54
* a2: size of area to clear
55
*/
56
.set noreorder
57
.align 5
58
LEAF(memset)
59
beqz a1, 1f
60
move v0, a0 /* result */
61
62
andi a1, 0xff /* spread fillword */
63
LONG_SLL t1, a1, 8
64
or a1, t1
65
LONG_SLL t1, a1, 16
66
#if LONGSIZE == 8
67
or a1, t1
68
LONG_SLL t1, a1, 32
69
#endif
70
or a1, t1
71
1:
72
73
FEXPORT(__bzero)
74
sltiu t0, a2, LONGSIZE /* very small region? */
75
bnez t0, .Lsmall_memset
76
andi t0, a0, LONGMASK /* aligned? */
77
78
#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
79
beqz t0, 1f
80
PTR_SUBU t0, LONGSIZE /* alignment in bytes */
81
#else
82
.set noat
83
li AT, LONGSIZE
84
beqz t0, 1f
85
PTR_SUBU t0, AT /* alignment in bytes */
86
.set at
87
#endif
88
89
R10KCBARRIER(0(ra))
90
#ifdef __MIPSEB__
91
EX(LONG_S_L, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */
92
#endif
93
#ifdef __MIPSEL__
94
EX(LONG_S_R, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */
95
#endif
96
PTR_SUBU a0, t0 /* long align ptr */
97
PTR_ADDU a2, t0 /* correct size */
98
99
1: ori t1, a2, 0x3f /* # of full blocks */
100
xori t1, 0x3f
101
beqz t1, .Lmemset_partial /* no block to fill */
102
andi t0, a2, 0x40-LONGSIZE
103
104
PTR_ADDU t1, a0 /* end address */
105
.set reorder
106
1: PTR_ADDIU a0, 64
107
R10KCBARRIER(0(ra))
108
f_fill64 a0, -64, a1, .Lfwd_fixup
109
bne t1, a0, 1b
110
.set noreorder
111
112
.Lmemset_partial:
113
R10KCBARRIER(0(ra))
114
PTR_LA t1, 2f /* where to start */
115
#if LONGSIZE == 4
116
PTR_SUBU t1, t0
117
#else
118
.set noat
119
LONG_SRL AT, t0, 1
120
PTR_SUBU t1, AT
121
.set at
122
#endif
123
jr t1
124
PTR_ADDU a0, t0 /* dest ptr */
125
126
.set push
127
.set noreorder
128
.set nomacro
129
f_fill64 a0, -64, a1, .Lpartial_fixup /* ... but first do longs ... */
130
2: .set pop
131
andi a2, LONGMASK /* At most one long to go */
132
133
beqz a2, 1f
134
PTR_ADDU a0, a2 /* What's left */
135
R10KCBARRIER(0(ra))
136
#ifdef __MIPSEB__
137
EX(LONG_S_R, a1, -1(a0), .Llast_fixup)
138
#endif
139
#ifdef __MIPSEL__
140
EX(LONG_S_L, a1, -1(a0), .Llast_fixup)
141
#endif
142
1: jr ra
143
move a2, zero
144
145
.Lsmall_memset:
146
beqz a2, 2f
147
PTR_ADDU t1, a0, a2
148
149
1: PTR_ADDIU a0, 1 /* fill bytewise */
150
R10KCBARRIER(0(ra))
151
bne t1, a0, 1b
152
sb a1, -1(a0)
153
154
2: jr ra /* done */
155
move a2, zero
156
END(memset)
157
158
.Lfirst_fixup:
159
jr ra
160
nop
161
162
.Lfwd_fixup:
163
PTR_L t0, TI_TASK($28)
164
andi a2, 0x3f
165
LONG_L t0, THREAD_BUADDR(t0)
166
LONG_ADDU a2, t1
167
jr ra
168
LONG_SUBU a2, t0
169
170
.Lpartial_fixup:
171
PTR_L t0, TI_TASK($28)
172
andi a2, LONGMASK
173
LONG_L t0, THREAD_BUADDR(t0)
174
LONG_ADDU a2, t1
175
jr ra
176
LONG_SUBU a2, t0
177
178
.Llast_fixup:
179
jr ra
180
andi v1, a2, LONGMASK
181
182