xref: /openbsd/sys/arch/mips64/include/asm.h (revision bfc185c1)
1 /*	$OpenBSD: asm.h,v 1.27 2021/05/01 16:11:10 visa 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 #define	_MIPS_ISA_MIPS1		1	/* R2000/R3000 */
34 #define	_MIPS_ISA_MIPS2		2	/* R4000/R6000 */
35 #define	_MIPS_ISA_MIPS3		3	/* R4000 */
36 #define	_MIPS_ISA_MIPS4		4	/* TFP (R1x000) */
37 #define	_MIPS_ISA_MIPS32	32	/* MIPS32 */
38 #define	_MIPS_ISA_MIPS64	64	/* MIPS64 */
39 
40 #if !defined(ABICALLS) && !defined(_NO_ABICALLS)
41 #define	ABICALLS	.abicalls
42 #endif
43 
44 #if defined(ABICALLS) && !defined(_KERNEL)
45 	ABICALLS
46 #endif
47 
48 #define _C_LABEL(x) x		/* XXX Obsolete but keep for a while */
49 
50 #if !defined(__MIPSEL__) && !defined(__MIPSEB__)
51 #error "__MIPSEL__ or __MIPSEB__ must be defined"
52 #endif
53 /*
54  * Define how to access unaligned data word
55  */
56 #if defined(__MIPSEL__)
57 #define LWLO    lwl
58 #define LWHI    lwr
59 #define	SWLO	swl
60 #define	SWHI	swr
61 #define LDLO    ldl
62 #define LDHI    ldr
63 #define	SDLO	sdl
64 #define	SDHI	sdr
65 #endif
66 #if defined(__MIPSEB__)
67 #define LWLO    lwr
68 #define LWHI    lwl
69 #define	SWLO	swr
70 #define	SWHI	swl
71 #define LDLO    ldr
72 #define LDHI    ldl
73 #define	SDLO	sdr
74 #define	SDHI	sdl
75 #endif
76 
77 /*
78  *  Define programming environment for ABI.
79  */
80 #if defined(ABICALLS) && !defined(_KERNEL) && !defined(_STANDALONE)
81 
82 #ifndef _MIPS_SIM
83 #define _MIPS_SIM 1
84 #define _ABIO32	1
85 #endif
86 #ifndef _MIPS_ISA
87 #define _MIPS_ISA 2
88 #define _MIPS_ISA_MIPS2 2
89 #endif
90 
91 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
92 #define NARGSAVE	4
93 
94 #define	SETUP_GP		\
95 	.set	noreorder;	\
96 	.cpload	t9;		\
97 	.set	reorder;
98 
99 #define	SAVE_GP(x)		\
100 	.cprestore x
101 
102 #define	SETUP_GP64(gpoff, name)
103 #define	RESTORE_GP64
104 #endif
105 
106 #if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)
107 #define NARGSAVE	0
108 
109 #define	SETUP_GP
110 #define	SAVE_GP(x)
111 #define	SETUP_GP64(gpoff, name)	\
112 	.cpsetup t9, gpoff, name
113 #define	RESTORE_GP64		\
114 	.cpreturn
115 #endif
116 
117 #define	MKFSIZ(narg,locals) (((narg+locals)*REGSZ+31)&(~31))
118 
119 #else /* defined(ABICALLS) && !defined(_KERNEL) */
120 
121 #define	NARGSAVE	4
122 #define	SETUP_GP
123 #define	SAVE_GP(x)
124 
125 #define	ALIGNSZ		16	/* Stack layout alignment */
126 #define	FRAMESZ(sz)	(((sz) + (ALIGNSZ-1)) & ~(ALIGNSZ-1))
127 
128 #endif
129 
130 /*
131  *  Basic register operations based on selected ISA
132  */
133 #if (_MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || \
134     _MIPS_ISA == _MIPS_ISA_MIPS32)
135 #define REGSZ		4	/* 32 bit mode register size */
136 #define LOGREGSZ	2	/* log rsize */
137 #define	REG_S	sw
138 #define	REG_L	lw
139 #define	CF_SZ		24	/* Call frame size */
140 #define	CF_ARGSZ	16	/* Call frame arg size */
141 #define	CF_RA_OFFS	20	/* Call ra save offset */
142 #endif
143 
144 #if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || \
145     _MIPS_ISA == _MIPS_ISA_MIPS64)
146 #define REGSZ		8	/* 64 bit mode register size */
147 #define LOGREGSZ	3	/* log rsize */
148 #define	REG_S	sd
149 #define	REG_L	ld
150 #define	CF_SZ		48	/* Call frame size (multiple of ALIGNSZ) */
151 #define	CF_ARGSZ	32	/* Call frame arg size */
152 #define	CF_RA_OFFS	40	/* Call ra save offset */
153 #endif
154 
155 #ifndef __LP64__
156 #define	PTR_L		lw
157 #define	PTR_S		sw
158 #define	PTR_SUB		sub
159 #define	PTR_ADD		add
160 #define	PTR_SUBU	subu
161 #define	PTR_ADDU	addu
162 #define LI		li
163 #define	LA		la
164 #define	PTR_SLL		sll
165 #define	PTR_SRL		srl
166 #define	PTR_VAL		.word
167 #else
168 #define	PTR_L		ld
169 #define	PTR_S		sd
170 #define	PTR_ADD		dadd
171 #define	PTR_SUB		dsub
172 #define	PTR_SUBU	dsubu
173 #define	PTR_ADDU	daddu
174 #define LI		dli
175 #define LA		dla
176 #define	PTR_SLL		dsll
177 #define	PTR_SRL		dsrl
178 #define	PTR_VAL		.dword
179 #endif
180 
181 #define	NOP	nop
182 #define	DMFC0	dmfc0
183 #define	DMTC0	dmtc0
184 #define	MFC0	mfc0
185 #define	MTC0	mtc0
186 #define	ERET	sync; eret
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  * STRONG_ALIAS, WEAK_ALIAS
279  *	Create a strong or weak alias.
280  */
281 #define STRONG_ALIAS(alias,sym) \
282 	.global alias; alias = sym
283 #define WEAK_ALIAS(alias,sym) \
284 	.weak alias; alias = sym
285 
286 
287 /*
288  * Macros to panic and printf from assembly language.
289  */
290 #define PANIC(msg) \
291 	LA	a0, 9f; \
292 	jal	panic;	\
293 	nop	;	\
294 	MSG(msg)
295 
296 #define	PRINTF(msg) \
297 	LA	a0, 9f; \
298 	jal	printf; \
299 	nop	;	\
300 	MSG(msg)
301 
302 #define	MSG(msg) \
303 	.rdata; \
304 9:	.asciiz	msg; \
305 	.text
306 
307 #define	LOAD_XKPHYS(reg, cca) \
308 	li	reg, cca | 0x10; \
309 	dsll	reg, reg, 59
310 
311 #ifdef MULTIPROCESSOR
312 #define GET_CPU_INFO(ci, tmp)	HW_GET_CPU_INFO(ci, tmp)
313 #else  /* MULTIPROCESSOR */
314 #define GET_CPU_INFO(ci, tmp)		\
315 	LA	ci, cpu_info_primary
316 #endif /* MULTIPROCESSOR */
317 
318 /*
319  * Hazards
320  */
321 
322 #ifdef CPU_OCTEON
323 /*
324  * OCTEON clears hazards in hardware.
325  */
326 #define	MFC0_HAZARD		/* nothing */
327 #define	MTC0_HAZARD		/* nothing */
328 #define	MTC0_SR_IE_HAZARD	/* nothing */
329 #define	MTC0_SR_CU_HAZARD	/* nothing */
330 #define	TLB_HAZARD		/* nothing */
331 #endif
332 
333 /* Hazard between {d,}mfc0 of COP_0_VADDR */
334 #ifndef	PRE_MFC0_ADDR_HAZARD
335 #define	PRE_MFC0_ADDR_HAZARD	/* nothing */
336 #endif
337 
338 /* Hazard after {d,}mfc0 from any register */
339 #ifndef	MFC0_HAZARD
340 #define	MFC0_HAZARD     	/* nothing */
341 #endif
342 /* Hazard after {d,}mtc0 to any register */
343 #ifndef	MTC0_HAZARD
344 #define	MTC0_HAZARD     	NOP; NOP; NOP; NOP
345 #endif
346 /* Hazard after {d,}mtc0 to COP_0_SR affecting the state of interrupts */
347 #ifndef	MTC0_SR_IE_HAZARD
348 #define	MTC0_SR_IE_HAZARD	MTC0_HAZARD
349 #endif
350 /* Hazard after {d,}mtc0 to COP_0_SR affecting the state of coprocessors */
351 #ifndef	MTC0_SR_CU_HAZARD
352 #define	MTC0_SR_CU_HAZARD	NOP; NOP
353 #endif
354 
355 /* Hazard before and after a tlbp, tlbr, tlbwi or tlbwr instruction */
356 #ifndef	TLB_HAZARD
357 #define	TLB_HAZARD		NOP; NOP
358 #endif
359 
360 #endif /* !_MIPS64_ASM_H_ */
361