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