SPDX: Convert all of our single license tags to Linux Kernel style
[oweals/u-boot.git] / arch / mips / include / asm / asm.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
4  * Copyright (C) 1999 by Silicon Graphics, Inc.
5  * Copyright (C) 2001 MIPS Technologies, Inc.
6  * Copyright (C) 2002  Maciej W. Rozycki
7  *
8  * Some useful macros for MIPS assembler code
9  *
10  * Some of the routines below contain useless nops that will be optimized
11  * away by gas in -O mode. These nops are however required to fill delay
12  * slots in noreorder mode.
13  */
14 #ifndef __ASM_ASM_H
15 #define __ASM_ASM_H
16
17 #include <asm/sgidefs.h>
18
19 #ifndef CAT
20 #ifdef __STDC__
21 #define __CAT(str1, str2) str1##str2
22 #else
23 #define __CAT(str1, str2) str1/**/str2
24 #endif
25 #define CAT(str1, str2) __CAT(str1, str2)
26 #endif
27
28 /*
29  * PIC specific declarations
30  * Not used for the kernel but here seems to be the right place.
31  */
32 #ifdef __PIC__
33 #define CPRESTORE(register)                             \
34                 .cprestore register
35 #define CPADD(register)                                 \
36                 .cpadd  register
37 #define CPLOAD(register)                                \
38                 .cpload register
39 #else
40 #define CPRESTORE(register)
41 #define CPADD(register)
42 #define CPLOAD(register)
43 #endif
44
45 #define ENTRY(symbol)                                   \
46                 .globl  symbol;                         \
47                 .type   symbol, @function;              \
48                 .ent    symbol, 0;                      \
49 symbol:
50
51 /*
52  * LEAF - declare leaf routine
53  */
54 #define LEAF(symbol)                                    \
55                 .globl  symbol;                         \
56                 .align  2;                              \
57                 .type   symbol, @function;              \
58                 .ent    symbol, 0;                      \
59                 .section .text.symbol, "x";             \
60 symbol:         .frame  sp, 0, ra
61
62 /*
63  * NESTED - declare nested routine entry point
64  */
65 #define NESTED(symbol, framesize, rpc)                  \
66                 .globl  symbol;                         \
67                 .align  2;                              \
68                 .type   symbol, @function;              \
69                 .ent    symbol, 0;                      \
70                 .section .text.symbol, "x";             \
71 symbol:         .frame  sp, framesize, rpc
72
73 /*
74  * END - mark end of function
75  */
76 #define END(function)                                   \
77                 .end    function;                       \
78                 .size   function, .-function
79
80 /*
81  * EXPORT - export definition of symbol
82  */
83 #define EXPORT(symbol)                                  \
84                 .globl  symbol;                         \
85 symbol:
86
87 /*
88  * FEXPORT - export definition of a function symbol
89  */
90 #define FEXPORT(symbol)                                 \
91                 .globl  symbol;                         \
92                 .type   symbol, @function;              \
93 symbol:
94
95 /*
96  * ABS - export absolute symbol
97  */
98 #define ABS(symbol,value)                               \
99                 .globl  symbol;                         \
100 symbol          =       value
101
102 #define PANIC(msg)                                      \
103                 .set    push;                           \
104                 .set    reorder;                        \
105                 PTR_LA  a0, 8f;                          \
106                 jal     panic;                          \
107 9:              b       9b;                             \
108                 .set    pop;                            \
109                 TEXT(msg)
110
111 /*
112  * Print formatted string
113  */
114 #ifdef CONFIG_PRINTK
115 #define PRINT(string)                                   \
116                 .set    push;                           \
117                 .set    reorder;                        \
118                 PTR_LA  a0, 8f;                          \
119                 jal     printk;                         \
120                 .set    pop;                            \
121                 TEXT(string)
122 #else
123 #define PRINT(string)
124 #endif
125
126 #define TEXT(msg)                                       \
127                 .pushsection .data;                     \
128 8:              .asciiz msg;                            \
129                 .popsection;
130
131 /*
132  * Build text tables
133  */
134 #define TTABLE(string)                                  \
135                 .pushsection .text;                     \
136                 .word   1f;                             \
137                 .popsection                             \
138                 .pushsection .data;                     \
139 1:              .asciiz string;                         \
140                 .popsection
141
142 /*
143  * MIPS IV pref instruction.
144  * Use with .set noreorder only!
145  *
146  * MIPS IV implementations are free to treat this as a nop.  The R5000
147  * is one of them.  So we should have an option not to use this instruction.
148  */
149 #ifdef CONFIG_CPU_HAS_PREFETCH
150
151 #define PREF(hint, addr)                                \
152                 .set    push;                           \
153                 .set    arch=r5000;                     \
154                 pref    hint, addr;                     \
155                 .set    pop
156
157 #define PREFE(hint, addr)                               \
158                 .set    push;                           \
159                 .set    mips0;                          \
160                 .set    eva;                            \
161                 prefe   hint, addr;                     \
162                 .set    pop
163
164 #define PREFX(hint, addr)                               \
165                 .set    push;                           \
166                 .set    arch=r5000;                     \
167                 prefx   hint, addr;                     \
168                 .set    pop
169
170 #else /* !CONFIG_CPU_HAS_PREFETCH */
171
172 #define PREF(hint, addr)
173 #define PREFE(hint, addr)
174 #define PREFX(hint, addr)
175
176 #endif /* !CONFIG_CPU_HAS_PREFETCH */
177
178 /*
179  * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
180  */
181 #if (_MIPS_ISA == _MIPS_ISA_MIPS1)
182 #define MOVN(rd, rs, rt)                                \
183                 .set    push;                           \
184                 .set    reorder;                        \
185                 beqz    rt, 9f;                         \
186                 move    rd, rs;                         \
187                 .set    pop;                            \
188 9:
189 #define MOVZ(rd, rs, rt)                                \
190                 .set    push;                           \
191                 .set    reorder;                        \
192                 bnez    rt, 9f;                         \
193                 move    rd, rs;                         \
194                 .set    pop;                            \
195 9:
196 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
197 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
198 #define MOVN(rd, rs, rt)                                \
199                 .set    push;                           \
200                 .set    noreorder;                      \
201                 bnezl   rt, 9f;                         \
202                  move   rd, rs;                         \
203                 .set    pop;                            \
204 9:
205 #define MOVZ(rd, rs, rt)                                \
206                 .set    push;                           \
207                 .set    noreorder;                      \
208                 beqzl   rt, 9f;                         \
209                  move   rd, rs;                         \
210                 .set    pop;                            \
211 9:
212 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
213 #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
214     (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
215 #define MOVN(rd, rs, rt)                                \
216                 movn    rd, rs, rt
217 #define MOVZ(rd, rs, rt)                                \
218                 movz    rd, rs, rt
219 #endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
220
221 /*
222  * Stack alignment
223  */
224 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
225 #define ALSZ    7
226 #define ALMASK  ~7
227 #endif
228 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
229 #define ALSZ    15
230 #define ALMASK  ~15
231 #endif
232
233 /*
234  * Macros to handle different pointer/register sizes for 32/64-bit code
235  */
236
237 /*
238  * Size of a register
239  */
240 #ifdef __mips64
241 #define SZREG   8
242 #else
243 #define SZREG   4
244 #endif
245
246 /*
247  * Use the following macros in assemblercode to load/store registers,
248  * pointers etc.
249  */
250 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
251 #define REG_S           sw
252 #define REG_L           lw
253 #define REG_SUBU        subu
254 #define REG_ADDU        addu
255 #endif
256 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
257 #define REG_S           sd
258 #define REG_L           ld
259 #define REG_SUBU        dsubu
260 #define REG_ADDU        daddu
261 #endif
262
263 /*
264  * How to add/sub/load/store/shift C int variables.
265  */
266 #if (_MIPS_SZINT == 32)
267 #define INT_ADD         add
268 #define INT_ADDU        addu
269 #define INT_ADDI        addi
270 #define INT_ADDIU       addiu
271 #define INT_SUB         sub
272 #define INT_SUBU        subu
273 #define INT_L           lw
274 #define INT_S           sw
275 #define INT_SLL         sll
276 #define INT_SLLV        sllv
277 #define INT_SRL         srl
278 #define INT_SRLV        srlv
279 #define INT_SRA         sra
280 #define INT_SRAV        srav
281 #endif
282
283 #if (_MIPS_SZINT == 64)
284 #define INT_ADD         dadd
285 #define INT_ADDU        daddu
286 #define INT_ADDI        daddi
287 #define INT_ADDIU       daddiu
288 #define INT_SUB         dsub
289 #define INT_SUBU        dsubu
290 #define INT_L           ld
291 #define INT_S           sd
292 #define INT_SLL         dsll
293 #define INT_SLLV        dsllv
294 #define INT_SRL         dsrl
295 #define INT_SRLV        dsrlv
296 #define INT_SRA         dsra
297 #define INT_SRAV        dsrav
298 #endif
299
300 /*
301  * How to add/sub/load/store/shift C long variables.
302  */
303 #if (_MIPS_SZLONG == 32)
304 #define LONG_ADD        add
305 #define LONG_ADDU       addu
306 #define LONG_ADDI       addi
307 #define LONG_ADDIU      addiu
308 #define LONG_SUB        sub
309 #define LONG_SUBU       subu
310 #define LONG_L          lw
311 #define LONG_S          sw
312 #define LONG_SP         swp
313 #define LONG_SLL        sll
314 #define LONG_SLLV       sllv
315 #define LONG_SRL        srl
316 #define LONG_SRLV       srlv
317 #define LONG_SRA        sra
318 #define LONG_SRAV       srav
319
320 #define LONG            .word
321 #define LONGSIZE        4
322 #define LONGMASK        3
323 #define LONGLOG         2
324 #endif
325
326 #if (_MIPS_SZLONG == 64)
327 #define LONG_ADD        dadd
328 #define LONG_ADDU       daddu
329 #define LONG_ADDI       daddi
330 #define LONG_ADDIU      daddiu
331 #define LONG_SUB        dsub
332 #define LONG_SUBU       dsubu
333 #define LONG_L          ld
334 #define LONG_S          sd
335 #define LONG_SP         sdp
336 #define LONG_SLL        dsll
337 #define LONG_SLLV       dsllv
338 #define LONG_SRL        dsrl
339 #define LONG_SRLV       dsrlv
340 #define LONG_SRA        dsra
341 #define LONG_SRAV       dsrav
342
343 #define LONG            .dword
344 #define LONGSIZE        8
345 #define LONGMASK        7
346 #define LONGLOG         3
347 #endif
348
349 /*
350  * How to add/sub/load/store/shift pointers.
351  */
352 #if (_MIPS_SZPTR == 32)
353 #define PTR_ADD         add
354 #define PTR_ADDU        addu
355 #define PTR_ADDI        addi
356 #define PTR_ADDIU       addiu
357 #define PTR_SUB         sub
358 #define PTR_SUBU        subu
359 #define PTR_L           lw
360 #define PTR_S           sw
361 #define PTR_LA          la
362 #define PTR_LI          li
363 #define PTR_SLL         sll
364 #define PTR_SLLV        sllv
365 #define PTR_SRL         srl
366 #define PTR_SRLV        srlv
367 #define PTR_SRA         sra
368 #define PTR_SRAV        srav
369
370 #define PTR_SCALESHIFT  2
371
372 #define PTR             .word
373 #define PTRSIZE         4
374 #define PTRLOG          2
375 #endif
376
377 #if (_MIPS_SZPTR == 64)
378 #define PTR_ADD         dadd
379 #define PTR_ADDU        daddu
380 #define PTR_ADDI        daddi
381 #define PTR_ADDIU       daddiu
382 #define PTR_SUB         dsub
383 #define PTR_SUBU        dsubu
384 #define PTR_L           ld
385 #define PTR_S           sd
386 #define PTR_LA          dla
387 #define PTR_LI          dli
388 #define PTR_SLL         dsll
389 #define PTR_SLLV        dsllv
390 #define PTR_SRL         dsrl
391 #define PTR_SRLV        dsrlv
392 #define PTR_SRA         dsra
393 #define PTR_SRAV        dsrav
394
395 #define PTR_SCALESHIFT  3
396
397 #define PTR             .dword
398 #define PTRSIZE         8
399 #define PTRLOG          3
400 #endif
401
402 /*
403  * Some cp0 registers were extended to 64bit for MIPS III.
404  */
405 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
406 #define MFC0            mfc0
407 #define MTC0            mtc0
408 #endif
409 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
410 #define MFC0            dmfc0
411 #define MTC0            dmtc0
412 #endif
413
414 #define SSNOP           sll zero, zero, 1
415
416 #ifdef CONFIG_SGI_IP28
417 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
418 #include <asm/cacheops.h>
419 #define R10KCBARRIER(addr)  cache   CACHE_BARRIER, addr;
420 #else
421 #define R10KCBARRIER(addr)
422 #endif
423
424 #endif /* __ASM_ASM_H */