xref: /openbsd-src/sys/arch/mips64/include/asm.h (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /*	$OpenBSD: asm.h,v 1.15 2012/06/23 21:53:38 miod Exp $ */
2 
3 /*
4  * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  */
28 #ifndef _MIPS64_ASM_H_
29 #define _MIPS64_ASM_H_
30 
31 #include <machine/regdef.h>
32 
33 /*
34  * Due to a flaw in RM7000 1.x processors a pipeline 'drain' is
35  * required after some mtc0 instructions.
36  * Ten nops in sequence does the trick.
37  */
38 #ifdef CPU_RM7000
39 #define ITLBNOPFIX      nop;nop;nop;nop;nop;nop;nop;nop;nop;nop
40 #else
41 #define ITLBNOPFIX      nop;nop;nop;nop
42 #endif
43 
44 #define	_MIPS_ISA_MIPS1	1	/* R2000/R3000 */
45 #define	_MIPS_ISA_MIPS2	2	/* R4000/R6000 */
46 #define	_MIPS_ISA_MIPS3	3	/* R4000 */
47 #define	_MIPS_ISA_MIPS4	4	/* TFP (R1x000) */
48 
49 #if !defined(ABICALLS) && !defined(_NO_ABICALLS)
50 #define	ABICALLS	.abicalls
51 #endif
52 
53 #if defined(ABICALLS) && !defined(_KERNEL)
54 	ABICALLS
55 #endif
56 
57 #define _C_LABEL(x) x		/* XXX Obsolete but keep for a while */
58 
59 #if !defined(__MIPSEL__) && !defined(__MIPSEB__)
60 #error "__MIPSEL__ or __MIPSEB__ must be defined"
61 #endif
62 /*
63  * Define how to access unaligned data word
64  */
65 #if defined(__MIPSEL__)
66 #define LWLO    lwl
67 #define LWHI    lwr
68 #define	SWLO	swl
69 #define	SWHI	swr
70 #define LDLO    ldl
71 #define LDHI    ldr
72 #define	SDLO	sdl
73 #define	SDHI	sdr
74 #endif
75 #if defined(__MIPSEB__)
76 #define LWLO    lwr
77 #define LWHI    lwl
78 #define	SWLO	swr
79 #define	SWHI	swl
80 #define LDLO    ldr
81 #define LDHI    ldl
82 #define	SDLO	sdr
83 #define	SDHI	sdl
84 #endif
85 
86 /*
87  *  Define programming environment for ABI.
88  */
89 #if defined(ABICALLS) && !defined(_KERNEL) && !defined(_STANDALONE)
90 
91 #ifndef _MIPS_SIM
92 #define _MIPS_SIM 1
93 #define _ABIO32	1
94 #endif
95 #ifndef _MIPS_ISA
96 #define _MIPS_ISA 2
97 #define _MIPS_ISA_MIPS2 2
98 #endif
99 
100 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
101 #define NARGSAVE	4
102 
103 #define	SETUP_GP		\
104 	.set	noreorder;	\
105 	.cpload	t9;		\
106 	.set	reorder;
107 
108 #define	SAVE_GP(x)		\
109 	.cprestore x
110 
111 #define	SETUP_GP64(gpoff, name)
112 #define	RESTORE_GP64
113 #endif
114 
115 #if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)
116 #define NARGSAVE	0
117 
118 #define	SETUP_GP
119 #define	SAVE_GP(x)
120 #define	SETUP_GP64(gpoff, name)	\
121 	.cpsetup t9, gpoff, name
122 #define	RESTORE_GP64		\
123 	.cpreturn
124 #endif
125 
126 #define	MKFSIZ(narg,locals) (((narg+locals)*REGSZ+31)&(~31))
127 
128 #else /* defined(ABICALLS) && !defined(_KERNEL) */
129 
130 #define	NARGSAVE	4
131 #define	SETUP_GP
132 #define	SAVE_GP(x)
133 
134 #define	ALIGNSZ		16	/* Stack layout alignment */
135 #define	FRAMESZ(sz)	(((sz) + (ALIGNSZ-1)) & ~(ALIGNSZ-1))
136 
137 #endif
138 
139 /*
140  *  Basic register operations based on selected ISA
141  */
142 #if (_MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2)
143 #define REGSZ		4	/* 32 bit mode register size */
144 #define LOGREGSZ	2	/* log rsize */
145 #define	REG_S	sw
146 #define	REG_L	lw
147 #define	CF_SZ		24	/* Call frame size */
148 #define	CF_ARGSZ	16	/* Call frame arg size */
149 #define	CF_RA_OFFS	20	/* Call ra save offset */
150 #endif
151 
152 #if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4)
153 #define REGSZ		8	/* 64 bit mode register size */
154 #define LOGREGSZ	3	/* log rsize */
155 #define	REG_S	sd
156 #define	REG_L	ld
157 #define	CF_SZ		48	/* Call frame size (multiple of ALIGNSZ) */
158 #define	CF_ARGSZ	32	/* Call frame arg size */
159 #define	CF_RA_OFFS	40	/* Call ra save offset */
160 #endif
161 
162 #ifndef __LP64__
163 #define	PTR_L		lw
164 #define	PTR_S		sw
165 #define	PTR_SUB		sub
166 #define	PTR_ADD		add
167 #define	PTR_SUBU	subu
168 #define	PTR_ADDU	addu
169 #define LI		li
170 #define	LA		la
171 #define	PTR_SLL		sll
172 #define	PTR_SRL		srl
173 #define	PTR_VAL		.word
174 #else
175 #define	PTR_L		ld
176 #define	PTR_S		sd
177 #define	PTR_ADD		dadd
178 #define	PTR_SUB		dsub
179 #define	PTR_SUBU	dsubu
180 #define	PTR_ADDU	daddu
181 #define LI		dli
182 #define LA		dla
183 #define	PTR_SLL		dsll
184 #define	PTR_SRL		dsrl
185 #define	PTR_VAL		.dword
186 #endif
187 
188 /*
189  * Define -pg profile entry code.
190  */
191 #if defined(XGPROF) || defined(XPROF)
192 #define	MCOUNT			\
193 	PTR_SUBU sp, sp, 64;	\
194 	SAVE_GP(16);		\
195 	sd	ra, 56(sp);	\
196 	sd	gp, 48(sp);	\
197 	.set	noat;		\
198 	.set	noreorder;	\
199 	move	AT, ra;		\
200 	jal	_mcount;	\
201 	PTR_SUBU sp, sp, 16;	\
202 	ld	ra, 56(sp);	\
203 	PTR_ADDU sp, sp, 64;	\
204 	.set reorder;		\
205 	.set	at;
206 #else
207 #define	MCOUNT
208 #endif
209 
210 /*
211  * LEAF(x, fsize)
212  *
213  *	Declare a leaf routine.
214  */
215 #define LEAF(x, fsize)		\
216 	.align	3;		\
217 	.globl x;		\
218 	.ent x, 0;		\
219 x: ;				\
220 	.frame sp, fsize, ra;	\
221 	SETUP_GP		\
222 	MCOUNT
223 
224 #define	ALEAF(x)		\
225 	.globl	x;		\
226 x:
227 
228 /*
229  * NLEAF(x)
230  *
231  *	Declare a non-profiled leaf routine.
232  */
233 #define NLEAF(x, fsize)		\
234 	.align	3;		\
235 	.globl x;		\
236 	.ent x, 0;		\
237 x: ;				\
238 	.frame sp, fsize, ra;	\
239 	SETUP_GP
240 
241 /*
242  * NON_LEAF(x)
243  *
244  *	Declare a non-leaf routine (a routine that makes other C calls).
245  */
246 #define NON_LEAF(x, fsize, retpc) \
247 	.align	3;		\
248 	.globl x;		\
249 	.ent x, 0;		\
250 x: ;				\
251 	.frame sp, fsize, retpc; \
252 	SETUP_GP		\
253 	MCOUNT
254 
255 /*
256  * NNON_LEAF(x)
257  *
258  *	Declare a non-profiled non-leaf routine
259  *	(a routine that makes other C calls).
260  */
261 #define NNON_LEAF(x, fsize, retpc) \
262 	.align	3;		\
263 	.globl x;		\
264 	.ent x, 0;		\
265 x: ;				\
266 	.frame sp, fsize, retpc	\
267 	SETUP_GP
268 
269 /*
270  * END(x)
271  *
272  *	Mark end of a procedure.
273  */
274 #define END(x) \
275 	.end x
276 
277 /*
278  * WEAK ALIAS: create a weak alias
279  */
280 #define WEAK_ALIAS(alias,sym) \
281 	.weak alias; alias = sym
282 
283 
284 /*
285  * Macros to panic and printf from assembly language.
286  */
287 #define PANIC(msg) \
288 	LA	a0, 9f; \
289 	jal	panic;	\
290 	nop	;	\
291 	MSG(msg)
292 
293 #define	PRINTF(msg) \
294 	LA	a0, 9f; \
295 	jal	printf; \
296 	nop	;	\
297 	MSG(msg)
298 
299 #define	MSG(msg) \
300 	.rdata; \
301 9:	.asciiz	msg; \
302 	.text
303 
304 #define ASMSTR(str) \
305 	.asciiz str; \
306 	.align	3
307 
308 #define	LOAD_XKPHYS(reg, cca) \
309 	li	reg, cca | 0x10; \
310 	dsll	reg, reg, 59
311 
312 #ifdef MULTIPROCESSOR
313 #define GET_CPU_INFO(ci, tmp)	HW_GET_CPU_INFO(ci, tmp)
314 #else  /* MULTIPROCESSOR */
315 #define GET_CPU_INFO(ci, tmp)		\
316 	LA	ci, cpu_info_primary
317 #endif /* MULTIPROCESSOR */
318 
319 #endif /* !_MIPS64_ASM_H_ */
320