Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/xtensa/include/asm/asmmacro.h
26442 views
1
/*
2
* include/asm-xtensa/asmmacro.h
3
*
4
* This file is subject to the terms and conditions of the GNU General Public
5
* License. See the file "COPYING" in the main directory of this archive
6
* for more details.
7
*
8
* Copyright (C) 2005 Tensilica Inc.
9
*/
10
11
#ifndef _XTENSA_ASMMACRO_H
12
#define _XTENSA_ASMMACRO_H
13
14
#include <linux/export.h>
15
#include <asm/core.h>
16
17
/*
18
* Some little helpers for loops. Use zero-overhead-loops
19
* where applicable and if supported by the processor.
20
*
21
* __loopi ar, at, size, inc
22
* ar register initialized with the start address
23
* at scratch register used by macro
24
* size size immediate value
25
* inc increment
26
*
27
* __loops ar, as, at, inc_log2[, mask_log2][, cond][, ncond]
28
* ar register initialized with the start address
29
* as register initialized with the size
30
* at scratch register use by macro
31
* inc_log2 increment [in log2]
32
* mask_log2 mask [in log2]
33
* cond true condition (used in loop'cond')
34
* ncond false condition (used in b'ncond')
35
*
36
* __loop as
37
* restart loop. 'as' register must not have been modified!
38
*
39
* __endla ar, as, incr
40
* ar start address (modified)
41
* as scratch register used by __loops/__loopi macros or
42
* end address used by __loopt macro
43
* inc increment
44
*/
45
46
/*
47
* loop for given size as immediate
48
*/
49
50
.macro __loopi ar, at, size, incr
51
52
#if XCHAL_HAVE_LOOPS
53
movi \at, ((\size + \incr - 1) / (\incr))
54
loop \at, 99f
55
#else
56
addi \at, \ar, \size
57
98:
58
#endif
59
60
.endm
61
62
/*
63
* loop for given size in register
64
*/
65
66
.macro __loops ar, as, at, incr_log2, mask_log2, cond, ncond
67
68
#if XCHAL_HAVE_LOOPS
69
.ifgt \incr_log2 - 1
70
addi \at, \as, (1 << \incr_log2) - 1
71
.ifnc \mask_log2,
72
extui \at, \at, \incr_log2, \mask_log2
73
.else
74
srli \at, \at, \incr_log2
75
.endif
76
.endif
77
loop\cond \at, 99f
78
#else
79
.ifnc \mask_log2,
80
extui \at, \as, \incr_log2, \mask_log2
81
.else
82
.ifnc \ncond,
83
srli \at, \as, \incr_log2
84
.endif
85
.endif
86
.ifnc \ncond,
87
b\ncond \at, 99f
88
89
.endif
90
.ifnc \mask_log2,
91
slli \at, \at, \incr_log2
92
add \at, \ar, \at
93
.else
94
add \at, \ar, \as
95
.endif
96
#endif
97
98:
98
99
.endm
100
101
/*
102
* loop from ar to as
103
*/
104
105
.macro __loopt ar, as, at, incr_log2
106
107
#if XCHAL_HAVE_LOOPS
108
sub \at, \as, \ar
109
.ifgt \incr_log2 - 1
110
addi \at, \at, (1 << \incr_log2) - 1
111
srli \at, \at, \incr_log2
112
.endif
113
loop \at, 99f
114
#else
115
98:
116
#endif
117
118
.endm
119
120
/*
121
* restart loop. registers must be unchanged
122
*/
123
124
.macro __loop as
125
126
#if XCHAL_HAVE_LOOPS
127
loop \as, 99f
128
#else
129
98:
130
#endif
131
132
.endm
133
134
/*
135
* end of loop with no increment of the address.
136
*/
137
138
.macro __endl ar, as
139
#if !XCHAL_HAVE_LOOPS
140
bltu \ar, \as, 98b
141
#endif
142
99:
143
.endm
144
145
/*
146
* end of loop with increment of the address.
147
*/
148
149
.macro __endla ar, as, incr
150
addi \ar, \ar, \incr
151
__endl \ar \as
152
.endm
153
154
/* Load or store instructions that may cause exceptions use the EX macro. */
155
156
#define EX(handler) \
157
.section __ex_table, "a"; \
158
.word 97f, handler; \
159
.previous \
160
97:
161
162
163
/*
164
* Extract unaligned word that is split between two registers w0 and w1
165
* into r regardless of machine endianness. SAR must be loaded with the
166
* starting bit of the word (see __ssa8).
167
*/
168
169
.macro __src_b r, w0, w1
170
#ifdef __XTENSA_EB__
171
src \r, \w0, \w1
172
#else
173
src \r, \w1, \w0
174
#endif
175
.endm
176
177
/*
178
* Load 2 lowest address bits of r into SAR for __src_b to extract unaligned
179
* word starting at r from two registers loaded from consecutive aligned
180
* addresses covering r regardless of machine endianness.
181
*
182
* r 0 1 2 3
183
* LE SAR 0 8 16 24
184
* BE SAR 32 24 16 8
185
*/
186
187
.macro __ssa8 r
188
#ifdef __XTENSA_EB__
189
ssa8b \r
190
#else
191
ssa8l \r
192
#endif
193
.endm
194
195
.macro do_nsau cnt, val, tmp, a
196
#if XCHAL_HAVE_NSA
197
nsau \cnt, \val
198
#else
199
mov \a, \val
200
movi \cnt, 0
201
extui \tmp, \a, 16, 16
202
bnez \tmp, 0f
203
movi \cnt, 16
204
slli \a, \a, 16
205
0:
206
extui \tmp, \a, 24, 8
207
bnez \tmp, 1f
208
addi \cnt, \cnt, 8
209
slli \a, \a, 8
210
1:
211
movi \tmp, __nsau_data
212
extui \a, \a, 24, 8
213
add \tmp, \tmp, \a
214
l8ui \tmp, \tmp, 0
215
add \cnt, \cnt, \tmp
216
#endif /* !XCHAL_HAVE_NSA */
217
.endm
218
219
.macro do_abs dst, src, tmp
220
#if XCHAL_HAVE_ABS
221
abs \dst, \src
222
#else
223
neg \tmp, \src
224
movgez \tmp, \src, \src
225
mov \dst, \tmp
226
#endif
227
.endm
228
229
#if defined(__XTENSA_WINDOWED_ABI__)
230
231
/* Assembly instructions for windowed kernel ABI. */
232
#define KABI_W
233
/* Assembly instructions for call0 kernel ABI (will be ignored). */
234
#define KABI_C0 #
235
236
#define XTENSA_FRAME_SIZE_RESERVE 16
237
#define XTENSA_SPILL_STACK_RESERVE 32
238
239
#define abi_entry(frame_size) \
240
entry sp, (XTENSA_FRAME_SIZE_RESERVE + \
241
(((frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \
242
-XTENSA_STACK_ALIGNMENT))
243
#define abi_entry_default abi_entry(0)
244
245
#define abi_ret(frame_size) retw
246
#define abi_ret_default retw
247
248
/* direct call */
249
#define abi_call call4
250
/* indirect call */
251
#define abi_callx callx4
252
/* outgoing call argument registers */
253
#define abi_arg0 a6
254
#define abi_arg1 a7
255
#define abi_arg2 a8
256
#define abi_arg3 a9
257
#define abi_arg4 a10
258
#define abi_arg5 a11
259
/* return value */
260
#define abi_rv a6
261
/* registers preserved across call */
262
#define abi_saved0 a2
263
#define abi_saved1 a3
264
265
/* none of the above */
266
#define abi_tmp0 a4
267
#define abi_tmp1 a5
268
269
#elif defined(__XTENSA_CALL0_ABI__)
270
271
/* Assembly instructions for windowed kernel ABI (will be ignored). */
272
#define KABI_W #
273
/* Assembly instructions for call0 kernel ABI. */
274
#define KABI_C0
275
276
#define XTENSA_SPILL_STACK_RESERVE 0
277
278
#define abi_entry(frame_size) __abi_entry (frame_size)
279
280
.macro __abi_entry frame_size
281
.ifgt \frame_size
282
addi sp, sp, -(((\frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \
283
-XTENSA_STACK_ALIGNMENT)
284
.endif
285
.endm
286
287
#define abi_entry_default
288
289
#define abi_ret(frame_size) __abi_ret (frame_size)
290
291
.macro __abi_ret frame_size
292
.ifgt \frame_size
293
addi sp, sp, (((\frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \
294
-XTENSA_STACK_ALIGNMENT)
295
.endif
296
ret
297
.endm
298
299
#define abi_ret_default ret
300
301
/* direct call */
302
#define abi_call call0
303
/* indirect call */
304
#define abi_callx callx0
305
/* outgoing call argument registers */
306
#define abi_arg0 a2
307
#define abi_arg1 a3
308
#define abi_arg2 a4
309
#define abi_arg3 a5
310
#define abi_arg4 a6
311
#define abi_arg5 a7
312
/* return value */
313
#define abi_rv a2
314
/* registers preserved across call */
315
#define abi_saved0 a12
316
#define abi_saved1 a13
317
318
/* none of the above */
319
#define abi_tmp0 a8
320
#define abi_tmp1 a9
321
322
#else
323
#error Unsupported Xtensa ABI
324
#endif
325
326
#if defined(USER_SUPPORT_WINDOWED)
327
/* Assembly instructions for windowed user ABI. */
328
#define UABI_W
329
/* Assembly instructions for call0 user ABI (will be ignored). */
330
#define UABI_C0 #
331
#else
332
/* Assembly instructions for windowed user ABI (will be ignored). */
333
#define UABI_W #
334
/* Assembly instructions for call0 user ABI. */
335
#define UABI_C0
336
#endif
337
338
#define __XTENSA_HANDLER .section ".exception.text", "ax"
339
340
#endif /* _XTENSA_ASMMACRO_H */
341
342