xref: /openbmc/linux/arch/mips/include/asm/asm.h (revision 1a2c73f4)
1384740dcSRalf Baechle /*
2384740dcSRalf Baechle  * This file is subject to the terms and conditions of the GNU General Public
3384740dcSRalf Baechle  * License.  See the file "COPYING" in the main directory of this archive
4384740dcSRalf Baechle  * for more details.
5384740dcSRalf Baechle  *
6384740dcSRalf Baechle  * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
7384740dcSRalf Baechle  * Copyright (C) 1999 by Silicon Graphics, Inc.
8384740dcSRalf Baechle  * Copyright (C) 2001 MIPS Technologies, Inc.
9384740dcSRalf Baechle  * Copyright (C) 2002  Maciej W. Rozycki
10384740dcSRalf Baechle  *
11384740dcSRalf Baechle  * Some useful macros for MIPS assembler code
12384740dcSRalf Baechle  *
13384740dcSRalf Baechle  * Some of the routines below contain useless nops that will be optimized
14384740dcSRalf Baechle  * away by gas in -O mode. These nops are however required to fill delay
15384740dcSRalf Baechle  * slots in noreorder mode.
16384740dcSRalf Baechle  */
17384740dcSRalf Baechle #ifndef __ASM_ASM_H
18384740dcSRalf Baechle #define __ASM_ASM_H
19384740dcSRalf Baechle 
20384740dcSRalf Baechle #include <asm/sgidefs.h>
2193244945SMarkos Chandras #include <asm/asm-eva.h>
2210657660SHuang Pei #include <asm/isa-rev.h>
23384740dcSRalf Baechle 
24894ef530SAlexander Lobakin #ifndef __VDSO__
25894ef530SAlexander Lobakin /*
26894ef530SAlexander Lobakin  * Emit CFI data in .debug_frame sections, not .eh_frame sections.
27894ef530SAlexander Lobakin  * We don't do DWARF unwinding at runtime, so only the offline DWARF
28894ef530SAlexander Lobakin  * information is useful to anyone. Note we should change this if we
29894ef530SAlexander Lobakin  * ever decide to enable DWARF unwinding at runtime.
30894ef530SAlexander Lobakin  */
31894ef530SAlexander Lobakin #define CFI_SECTIONS	.cfi_sections .debug_frame
32894ef530SAlexander Lobakin #else
33894ef530SAlexander Lobakin  /*
34894ef530SAlexander Lobakin   * For the vDSO, emit both runtime unwind information and debug
35894ef530SAlexander Lobakin   * symbols for the .dbg file.
36894ef530SAlexander Lobakin   */
37894ef530SAlexander Lobakin #define CFI_SECTIONS
38894ef530SAlexander Lobakin #endif
39894ef530SAlexander Lobakin 
40384740dcSRalf Baechle /*
41384740dcSRalf Baechle  * LEAF - declare leaf routine
42384740dcSRalf Baechle  */
43384740dcSRalf Baechle #define LEAF(symbol)					\
44894ef530SAlexander Lobakin 		CFI_SECTIONS;				\
45384740dcSRalf Baechle 		.globl	symbol;				\
46384740dcSRalf Baechle 		.align	2;				\
47384740dcSRalf Baechle 		.type	symbol, @function;		\
48384740dcSRalf Baechle 		.ent	symbol, 0;			\
4908889582SPaul Burton symbol:		.frame	sp, 0, ra;			\
50866b6a89SCorey Minyard 		.cfi_startproc;				\
5108889582SPaul Burton 		.insn
52384740dcSRalf Baechle 
53384740dcSRalf Baechle /*
54384740dcSRalf Baechle  * NESTED - declare nested routine entry point
55384740dcSRalf Baechle  */
56384740dcSRalf Baechle #define NESTED(symbol, framesize, rpc)			\
57894ef530SAlexander Lobakin 		CFI_SECTIONS;				\
58384740dcSRalf Baechle 		.globl	symbol;				\
59384740dcSRalf Baechle 		.align	2;				\
60384740dcSRalf Baechle 		.type	symbol, @function;		\
61384740dcSRalf Baechle 		.ent	symbol, 0;			\
6208889582SPaul Burton symbol:		.frame	sp, framesize, rpc;		\
63866b6a89SCorey Minyard 		.cfi_startproc;				\
6408889582SPaul Burton 		.insn
65384740dcSRalf Baechle 
66384740dcSRalf Baechle /*
67384740dcSRalf Baechle  * END - mark end of function
68384740dcSRalf Baechle  */
69384740dcSRalf Baechle #define END(function)					\
70866b6a89SCorey Minyard 		.cfi_endproc;				\
71384740dcSRalf Baechle 		.end	function;			\
72384740dcSRalf Baechle 		.size	function, .-function
73384740dcSRalf Baechle 
74384740dcSRalf Baechle /*
75384740dcSRalf Baechle  * EXPORT - export definition of symbol
76384740dcSRalf Baechle  */
77384740dcSRalf Baechle #define EXPORT(symbol)					\
78384740dcSRalf Baechle 		.globl	symbol;				\
79384740dcSRalf Baechle symbol:
80384740dcSRalf Baechle 
81384740dcSRalf Baechle /*
82384740dcSRalf Baechle  * FEXPORT - export definition of a function symbol
83384740dcSRalf Baechle  */
84384740dcSRalf Baechle #define FEXPORT(symbol)					\
85384740dcSRalf Baechle 		.globl	symbol;				\
86384740dcSRalf Baechle 		.type	symbol, @function;		\
8708889582SPaul Burton symbol:		.insn
88384740dcSRalf Baechle 
89384740dcSRalf Baechle /*
90384740dcSRalf Baechle  * ABS - export absolute symbol
91384740dcSRalf Baechle  */
92384740dcSRalf Baechle #define ABS(symbol,value)				\
93384740dcSRalf Baechle 		.globl	symbol;				\
94384740dcSRalf Baechle symbol		=	value
95384740dcSRalf Baechle 
96da706e50SHuacai Chen #define TEXT(msg)					\
97da706e50SHuacai Chen 		.pushsection .data;			\
98da706e50SHuacai Chen 8:		.asciiz msg;				\
99da706e50SHuacai Chen 		.popsection;
100da706e50SHuacai Chen 
101da706e50SHuacai Chen #define ASM_PANIC(msg)					\
102384740dcSRalf Baechle 		.set	push;				\
103384740dcSRalf Baechle 		.set	reorder;			\
104384740dcSRalf Baechle 		PTR_LA	a0, 8f;				\
105384740dcSRalf Baechle 		jal	panic;				\
106384740dcSRalf Baechle 9:		b	9b;				\
107384740dcSRalf Baechle 		.set	pop;				\
108384740dcSRalf Baechle 		TEXT(msg)
109384740dcSRalf Baechle 
110384740dcSRalf Baechle /*
111384740dcSRalf Baechle  * Print formatted string
112384740dcSRalf Baechle  */
113384740dcSRalf Baechle #ifdef CONFIG_PRINTK
114da706e50SHuacai Chen #define ASM_PRINT(string)				\
115384740dcSRalf Baechle 		.set	push;				\
116384740dcSRalf Baechle 		.set	reorder;			\
117384740dcSRalf Baechle 		PTR_LA	a0, 8f;				\
11886ce91d5SPetr Mladek 		jal	_printk;			\
119384740dcSRalf Baechle 		.set	pop;				\
120384740dcSRalf Baechle 		TEXT(string)
121384740dcSRalf Baechle #else
122da706e50SHuacai Chen #define ASM_PRINT(string)
123384740dcSRalf Baechle #endif
124384740dcSRalf Baechle 
125384740dcSRalf Baechle /*
126384740dcSRalf Baechle  * Stack alignment
127384740dcSRalf Baechle  */
128384740dcSRalf Baechle #if (_MIPS_SIM == _MIPS_SIM_ABI32)
129384740dcSRalf Baechle #define ALSZ	7
130384740dcSRalf Baechle #define ALMASK	~7
131384740dcSRalf Baechle #endif
132384740dcSRalf Baechle #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
133384740dcSRalf Baechle #define ALSZ	15
134384740dcSRalf Baechle #define ALMASK	~15
135384740dcSRalf Baechle #endif
136384740dcSRalf Baechle 
137384740dcSRalf Baechle /*
138384740dcSRalf Baechle  * Macros to handle different pointer/register sizes for 32/64-bit code
139384740dcSRalf Baechle  */
140384740dcSRalf Baechle 
141384740dcSRalf Baechle /*
142384740dcSRalf Baechle  * Size of a register
143384740dcSRalf Baechle  */
144384740dcSRalf Baechle #ifdef __mips64
145384740dcSRalf Baechle #define SZREG	8
146384740dcSRalf Baechle #else
147384740dcSRalf Baechle #define SZREG	4
148384740dcSRalf Baechle #endif
149384740dcSRalf Baechle 
150384740dcSRalf Baechle /*
151384740dcSRalf Baechle  * Use the following macros in assemblercode to load/store registers,
152384740dcSRalf Baechle  * pointers etc.
153384740dcSRalf Baechle  */
154384740dcSRalf Baechle #if (_MIPS_SIM == _MIPS_SIM_ABI32)
155384740dcSRalf Baechle #define REG_S		sw
156384740dcSRalf Baechle #define REG_L		lw
157384740dcSRalf Baechle #define REG_SUBU	subu
158384740dcSRalf Baechle #define REG_ADDU	addu
159384740dcSRalf Baechle #endif
160384740dcSRalf Baechle #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
161384740dcSRalf Baechle #define REG_S		sd
162384740dcSRalf Baechle #define REG_L		ld
163384740dcSRalf Baechle #define REG_SUBU	dsubu
164384740dcSRalf Baechle #define REG_ADDU	daddu
165384740dcSRalf Baechle #endif
166384740dcSRalf Baechle 
167384740dcSRalf Baechle /*
168384740dcSRalf Baechle  * How to add/sub/load/store/shift C int variables.
169384740dcSRalf Baechle  */
170384740dcSRalf Baechle #if (_MIPS_SZINT == 32)
171384740dcSRalf Baechle #define INT_ADD		add
172384740dcSRalf Baechle #define INT_ADDU	addu
173384740dcSRalf Baechle #define INT_ADDI	addi
174384740dcSRalf Baechle #define INT_ADDIU	addiu
175384740dcSRalf Baechle #define INT_SUB		sub
176384740dcSRalf Baechle #define INT_SUBU	subu
177384740dcSRalf Baechle #define INT_L		lw
178384740dcSRalf Baechle #define INT_S		sw
179384740dcSRalf Baechle #define INT_SLL		sll
180384740dcSRalf Baechle #define INT_SLLV	sllv
181384740dcSRalf Baechle #define INT_SRL		srl
182384740dcSRalf Baechle #define INT_SRLV	srlv
183384740dcSRalf Baechle #define INT_SRA		sra
184384740dcSRalf Baechle #define INT_SRAV	srav
185384740dcSRalf Baechle #endif
186384740dcSRalf Baechle 
187384740dcSRalf Baechle #if (_MIPS_SZINT == 64)
188384740dcSRalf Baechle #define INT_ADD		dadd
189384740dcSRalf Baechle #define INT_ADDU	daddu
190384740dcSRalf Baechle #define INT_ADDI	daddi
191384740dcSRalf Baechle #define INT_ADDIU	daddiu
192384740dcSRalf Baechle #define INT_SUB		dsub
193384740dcSRalf Baechle #define INT_SUBU	dsubu
194384740dcSRalf Baechle #define INT_L		ld
195384740dcSRalf Baechle #define INT_S		sd
196384740dcSRalf Baechle #define INT_SLL		dsll
197384740dcSRalf Baechle #define INT_SLLV	dsllv
198384740dcSRalf Baechle #define INT_SRL		dsrl
199384740dcSRalf Baechle #define INT_SRLV	dsrlv
200384740dcSRalf Baechle #define INT_SRA		dsra
201384740dcSRalf Baechle #define INT_SRAV	dsrav
202384740dcSRalf Baechle #endif
203384740dcSRalf Baechle 
204384740dcSRalf Baechle /*
205384740dcSRalf Baechle  * How to add/sub/load/store/shift C long variables.
206384740dcSRalf Baechle  */
207384740dcSRalf Baechle #if (_MIPS_SZLONG == 32)
208384740dcSRalf Baechle #define LONG_ADD	add
209384740dcSRalf Baechle #define LONG_ADDU	addu
210384740dcSRalf Baechle #define LONG_ADDI	addi
211384740dcSRalf Baechle #define LONG_ADDIU	addiu
212384740dcSRalf Baechle #define LONG_SUB	sub
213384740dcSRalf Baechle #define LONG_SUBU	subu
214384740dcSRalf Baechle #define LONG_L		lw
21510657660SHuang Pei #define LONG_LL		ll
21610657660SHuang Pei #define LONG_SC		sc
217384740dcSRalf Baechle #define LONG_S		sw
21826c5e07dSSteven J. Hill #define LONG_SP		swp
219384740dcSRalf Baechle #define LONG_SLL	sll
220384740dcSRalf Baechle #define LONG_SLLV	sllv
221384740dcSRalf Baechle #define LONG_SRL	srl
222384740dcSRalf Baechle #define LONG_SRLV	srlv
223384740dcSRalf Baechle #define LONG_SRA	sra
224384740dcSRalf Baechle #define LONG_SRAV	srav
225f0b7ddbdSHuang Pei #define LONG_INS	ins
226f0b7ddbdSHuang Pei #define LONG_EXT	ext
227384740dcSRalf Baechle 
228d339cd02SHuacai Chen #ifdef __ASSEMBLY__
229384740dcSRalf Baechle #define LONG		.word
230d339cd02SHuacai Chen #endif
231384740dcSRalf Baechle #define LONGSIZE	4
232384740dcSRalf Baechle #define LONGMASK	3
233384740dcSRalf Baechle #define LONGLOG		2
234384740dcSRalf Baechle #endif
235384740dcSRalf Baechle 
236384740dcSRalf Baechle #if (_MIPS_SZLONG == 64)
237384740dcSRalf Baechle #define LONG_ADD	dadd
238384740dcSRalf Baechle #define LONG_ADDU	daddu
239384740dcSRalf Baechle #define LONG_ADDI	daddi
240384740dcSRalf Baechle #define LONG_ADDIU	daddiu
241384740dcSRalf Baechle #define LONG_SUB	dsub
242384740dcSRalf Baechle #define LONG_SUBU	dsubu
243384740dcSRalf Baechle #define LONG_L		ld
24410657660SHuang Pei #define LONG_LL		lld
24510657660SHuang Pei #define LONG_SC		scd
246384740dcSRalf Baechle #define LONG_S		sd
24726c5e07dSSteven J. Hill #define LONG_SP		sdp
248384740dcSRalf Baechle #define LONG_SLL	dsll
249384740dcSRalf Baechle #define LONG_SLLV	dsllv
250384740dcSRalf Baechle #define LONG_SRL	dsrl
251384740dcSRalf Baechle #define LONG_SRLV	dsrlv
252384740dcSRalf Baechle #define LONG_SRA	dsra
253384740dcSRalf Baechle #define LONG_SRAV	dsrav
254f0b7ddbdSHuang Pei #define LONG_INS	dins
255f0b7ddbdSHuang Pei #define LONG_EXT	dext
256384740dcSRalf Baechle 
257d339cd02SHuacai Chen #ifdef __ASSEMBLY__
258384740dcSRalf Baechle #define LONG		.dword
259d339cd02SHuacai Chen #endif
260384740dcSRalf Baechle #define LONGSIZE	8
261384740dcSRalf Baechle #define LONGMASK	7
262384740dcSRalf Baechle #define LONGLOG		3
263384740dcSRalf Baechle #endif
264384740dcSRalf Baechle 
265384740dcSRalf Baechle /*
266384740dcSRalf Baechle  * How to add/sub/load/store/shift pointers.
267384740dcSRalf Baechle  */
268384740dcSRalf Baechle #if (_MIPS_SZPTR == 32)
269384740dcSRalf Baechle #define PTR_ADD		add
270384740dcSRalf Baechle #define PTR_ADDU	addu
271384740dcSRalf Baechle #define PTR_ADDI	addi
272384740dcSRalf Baechle #define PTR_ADDIU	addiu
273384740dcSRalf Baechle #define PTR_SUB		sub
274384740dcSRalf Baechle #define PTR_SUBU	subu
275384740dcSRalf Baechle #define PTR_L		lw
276384740dcSRalf Baechle #define PTR_S		sw
277384740dcSRalf Baechle #define PTR_LA		la
278384740dcSRalf Baechle #define PTR_LI		li
279384740dcSRalf Baechle #define PTR_SLL		sll
280384740dcSRalf Baechle #define PTR_SLLV	sllv
281384740dcSRalf Baechle #define PTR_SRL		srl
282384740dcSRalf Baechle #define PTR_SRLV	srlv
283384740dcSRalf Baechle #define PTR_SRA		sra
284384740dcSRalf Baechle #define PTR_SRAV	srav
285384740dcSRalf Baechle 
286384740dcSRalf Baechle #define PTR_SCALESHIFT	2
287384740dcSRalf Baechle 
288fa62f39dSThomas Bogendoerfer #define PTR_WD		.word
289384740dcSRalf Baechle #define PTRSIZE		4
290384740dcSRalf Baechle #define PTRLOG		2
291384740dcSRalf Baechle #endif
292384740dcSRalf Baechle 
293384740dcSRalf Baechle #if (_MIPS_SZPTR == 64)
294384740dcSRalf Baechle #define PTR_ADD		dadd
295384740dcSRalf Baechle #define PTR_ADDU	daddu
296384740dcSRalf Baechle #define PTR_ADDI	daddi
297384740dcSRalf Baechle #define PTR_ADDIU	daddiu
298384740dcSRalf Baechle #define PTR_SUB		dsub
299384740dcSRalf Baechle #define PTR_SUBU	dsubu
300384740dcSRalf Baechle #define PTR_L		ld
301384740dcSRalf Baechle #define PTR_S		sd
302384740dcSRalf Baechle #define PTR_LA		dla
303384740dcSRalf Baechle #define PTR_LI		dli
304384740dcSRalf Baechle #define PTR_SLL		dsll
305384740dcSRalf Baechle #define PTR_SLLV	dsllv
306384740dcSRalf Baechle #define PTR_SRL		dsrl
307384740dcSRalf Baechle #define PTR_SRLV	dsrlv
308384740dcSRalf Baechle #define PTR_SRA		dsra
309384740dcSRalf Baechle #define PTR_SRAV	dsrav
310384740dcSRalf Baechle 
311384740dcSRalf Baechle #define PTR_SCALESHIFT	3
312384740dcSRalf Baechle 
313fa62f39dSThomas Bogendoerfer #define PTR_WD		.dword
314384740dcSRalf Baechle #define PTRSIZE		8
315384740dcSRalf Baechle #define PTRLOG		3
316384740dcSRalf Baechle #endif
317384740dcSRalf Baechle 
318384740dcSRalf Baechle /*
319384740dcSRalf Baechle  * Some cp0 registers were extended to 64bit for MIPS III.
320384740dcSRalf Baechle  */
321384740dcSRalf Baechle #if (_MIPS_SIM == _MIPS_SIM_ABI32)
322384740dcSRalf Baechle #define MFC0		mfc0
323384740dcSRalf Baechle #define MTC0		mtc0
324384740dcSRalf Baechle #endif
325384740dcSRalf Baechle #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
326384740dcSRalf Baechle #define MFC0		dmfc0
327384740dcSRalf Baechle #define MTC0		dmtc0
328384740dcSRalf Baechle #endif
329384740dcSRalf Baechle 
330384740dcSRalf Baechle #define SSNOP		sll zero, zero, 1
331384740dcSRalf Baechle 
33210657660SHuang Pei /*
33310657660SHuang Pei  * Using a branch-likely instruction to check the result of an sc instruction
33410657660SHuang Pei  * works around a bug present in R10000 CPUs prior to revision 3.0 that could
33510657660SHuang Pei  * cause ll-sc sequences to execute non-atomically.
33610657660SHuang Pei  */
33710657660SHuang Pei #ifdef CONFIG_WAR_R10000_LLSC
33810657660SHuang Pei # define SC_BEQZ	beqzl
339*1a2c73f4SJiaxun Yang #elif !defined(CONFIG_CC_HAS_BROKEN_INLINE_COMPAT_BRANCH) && MIPS_ISA_REV >= 6
34010657660SHuang Pei # define SC_BEQZ	beqzc
34110657660SHuang Pei #else
34210657660SHuang Pei # define SC_BEQZ	beqz
34310657660SHuang Pei #endif
34410657660SHuang Pei 
345384740dcSRalf Baechle #ifdef CONFIG_SGI_IP28
346384740dcSRalf Baechle /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
347384740dcSRalf Baechle #include <asm/cacheops.h>
348384740dcSRalf Baechle #define R10KCBARRIER(addr)  cache   Cache_Barrier, addr;
349384740dcSRalf Baechle #else
350384740dcSRalf Baechle #define R10KCBARRIER(addr)
351384740dcSRalf Baechle #endif
352384740dcSRalf Baechle 
353384740dcSRalf Baechle #endif /* __ASM_ASM_H */
354