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