blob: 7abcf6df07c78249ce38b8c2a5b6cd2bd0d68fc0 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0 */
Shinya Kuribayashi06222122008-03-25 21:30:06 +09002/*
Shinya Kuribayashi06222122008-03-25 21:30:06 +09003 * 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__
Daniel Schwierzecka6dae712016-01-12 21:48:26 +010033#define CPRESTORE(register) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +090034 .cprestore register
Daniel Schwierzecka6dae712016-01-12 21:48:26 +010035#define CPADD(register) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +090036 .cpadd register
Daniel Schwierzecka6dae712016-01-12 21:48:26 +010037#define CPLOAD(register) \
38 .cpload register
Shinya Kuribayashi06222122008-03-25 21:30:06 +090039#else
40#define CPRESTORE(register)
41#define CPADD(register)
42#define CPLOAD(register)
43#endif
44
Daniel Schwierzecka6dae712016-01-12 21:48:26 +010045#define ENTRY(symbol) \
46 .globl symbol; \
47 .type symbol, @function; \
48 .ent symbol, 0; \
Daniel Schwierzeck7509b572015-12-19 20:20:45 +010049symbol:
50
Shinya Kuribayashi06222122008-03-25 21:30:06 +090051/*
52 * LEAF - declare leaf routine
53 */
Daniel Schwierzecka6dae712016-01-12 21:48:26 +010054#define LEAF(symbol) \
55 .globl symbol; \
56 .align 2; \
57 .type symbol, @function; \
58 .ent symbol, 0; \
Daniel Schwierzeck04a665d2015-12-19 20:20:46 +010059 .section .text.symbol, "x"; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +090060symbol: .frame sp, 0, ra
61
62/*
63 * NESTED - declare nested routine entry point
64 */
Daniel Schwierzecka6dae712016-01-12 21:48:26 +010065#define NESTED(symbol, framesize, rpc) \
66 .globl symbol; \
67 .align 2; \
68 .type symbol, @function; \
69 .ent symbol, 0; \
Daniel Schwierzeck04a665d2015-12-19 20:20:46 +010070 .section .text.symbol, "x"; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +090071symbol: .frame sp, framesize, rpc
72
73/*
74 * END - mark end of function
75 */
Daniel Schwierzecka6dae712016-01-12 21:48:26 +010076#define END(function) \
77 .end function; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +090078 .size function, .-function
79
80/*
81 * EXPORT - export definition of symbol
82 */
83#define EXPORT(symbol) \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +010084 .globl symbol; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +090085symbol:
86
87/*
88 * FEXPORT - export definition of a function symbol
89 */
90#define FEXPORT(symbol) \
91 .globl symbol; \
92 .type symbol, @function; \
93symbol:
94
95/*
96 * ABS - export absolute symbol
97 */
Daniel Schwierzecka6dae712016-01-12 21:48:26 +010098#define ABS(symbol,value) \
99 .globl symbol; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900100symbol = value
101
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100102#define PANIC(msg) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900103 .set push; \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100104 .set reorder; \
105 PTR_LA a0, 8f; \
106 jal panic; \
1079: b 9b; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900108 .set pop; \
109 TEXT(msg)
110
111/*
112 * Print formatted string
113 */
114#ifdef CONFIG_PRINTK
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100115#define PRINT(string) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900116 .set push; \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100117 .set reorder; \
118 PTR_LA a0, 8f; \
119 jal printk; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900120 .set pop; \
121 TEXT(string)
122#else
123#define PRINT(string)
124#endif
125
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100126#define TEXT(msg) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900127 .pushsection .data; \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +01001288: .asciiz msg; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900129 .popsection;
130
131/*
132 * Build text tables
133 */
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100134#define TTABLE(string) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900135 .pushsection .text; \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100136 .word 1f; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900137 .popsection \
138 .pushsection .data; \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +01001391: .asciiz string; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900140 .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
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100151#define PREF(hint, addr) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900152 .set push; \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100153 .set arch=r5000; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900154 pref hint, addr; \
155 .set pop
156
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100157#define PREFE(hint, addr) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900158 .set push; \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100159 .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; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900167 prefx hint, addr; \
168 .set pop
169
170#else /* !CONFIG_CPU_HAS_PREFETCH */
171
172#define PREF(hint, addr)
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100173#define PREFE(hint, addr)
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900174#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)
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100182#define MOVN(rd, rs, rt) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900183 .set push; \
184 .set reorder; \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100185 beqz rt, 9f; \
186 move rd, rs; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900187 .set pop; \
1889:
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100189#define MOVZ(rd, rs, rt) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900190 .set push; \
191 .set reorder; \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100192 bnez rt, 9f; \
193 move rd, rs; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900194 .set pop; \
1959:
196#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
197#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100198#define MOVN(rd, rs, rt) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900199 .set push; \
200 .set noreorder; \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100201 bnezl rt, 9f; \
202 move rd, rs; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900203 .set pop; \
2049:
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100205#define MOVZ(rd, rs, rt) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900206 .set push; \
207 .set noreorder; \
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100208 beqzl rt, 9f; \
209 move rd, rs; \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900210 .set pop; \
2119:
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)
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100215#define MOVN(rd, rs, rt) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900216 movn rd, rs, rt
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100217#define MOVZ(rd, rs, rt) \
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900218 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
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100312#define LONG_SP swp
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900313#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
Daniel Schwierzecka6dae712016-01-12 21:48:26 +0100335#define LONG_SP sdp
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900336#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>
Zhi-zhou Zhang724f6182012-10-16 15:02:08 +0200419#define R10KCBARRIER(addr) cache CACHE_BARRIER, addr;
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900420#else
421#define R10KCBARRIER(addr)
422#endif
423
424#endif /* __ASM_ASM_H */