xref: /openbsd-src/sys/arch/mips64/include/asm.h (revision bfc185c1fc344eead3f54156b93fe14638b67e0e)
1*bfc185c1Svisa /*	$OpenBSD: asm.h,v 1.27 2021/05/01 16:11:10 visa Exp $ */
2f58c7388Spefo 
3f58c7388Spefo /*
4f58c7388Spefo  * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
5f58c7388Spefo  *
6f58c7388Spefo  * Redistribution and use in source and binary forms, with or without
7f58c7388Spefo  * modification, are permitted provided that the following conditions
8f58c7388Spefo  * are met:
9f58c7388Spefo  * 1. Redistributions of source code must retain the above copyright
10f58c7388Spefo  *    notice, this list of conditions and the following disclaimer.
11f58c7388Spefo  * 2. Redistributions in binary form must reproduce the above copyright
12f58c7388Spefo  *    notice, this list of conditions and the following disclaimer in the
13f58c7388Spefo  *    documentation and/or other materials provided with the distribution.
14f58c7388Spefo  *
15f58c7388Spefo  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16f58c7388Spefo  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17f58c7388Spefo  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18f58c7388Spefo  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19f58c7388Spefo  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20f58c7388Spefo  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21f58c7388Spefo  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22f58c7388Spefo  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23f58c7388Spefo  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24f58c7388Spefo  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25f58c7388Spefo  * SUCH DAMAGE.
26f58c7388Spefo  *
27f58c7388Spefo  */
282fa72412Spirofti #ifndef _MIPS64_ASM_H_
292fa72412Spirofti #define _MIPS64_ASM_H_
30f58c7388Spefo 
31f58c7388Spefo #include <machine/regdef.h>
32f58c7388Spefo 
33f58c7388Spefo #define	_MIPS_ISA_MIPS1		1	/* R2000/R3000 */
34f58c7388Spefo #define	_MIPS_ISA_MIPS2		2	/* R4000/R6000 */
35f58c7388Spefo #define	_MIPS_ISA_MIPS3		3	/* R4000 */
36f58c7388Spefo #define	_MIPS_ISA_MIPS4		4	/* TFP (R1x000) */
370fa15b16Svisa #define	_MIPS_ISA_MIPS32	32	/* MIPS32 */
380fa15b16Svisa #define	_MIPS_ISA_MIPS64	64	/* MIPS64 */
39f58c7388Spefo 
40f58c7388Spefo #if !defined(ABICALLS) && !defined(_NO_ABICALLS)
41f58c7388Spefo #define	ABICALLS	.abicalls
42f58c7388Spefo #endif
43f58c7388Spefo 
44f58c7388Spefo #if defined(ABICALLS) && !defined(_KERNEL)
45f58c7388Spefo 	ABICALLS
46f58c7388Spefo #endif
47f58c7388Spefo 
48f58c7388Spefo #define _C_LABEL(x) x		/* XXX Obsolete but keep for a while */
49f58c7388Spefo 
50f58c7388Spefo #if !defined(__MIPSEL__) && !defined(__MIPSEB__)
51f58c7388Spefo #error "__MIPSEL__ or __MIPSEB__ must be defined"
52f58c7388Spefo #endif
53f58c7388Spefo /*
54f58c7388Spefo  * Define how to access unaligned data word
55f58c7388Spefo  */
56f58c7388Spefo #if defined(__MIPSEL__)
57f58c7388Spefo #define LWLO    lwl
58f58c7388Spefo #define LWHI    lwr
59f58c7388Spefo #define	SWLO	swl
60f58c7388Spefo #define	SWHI	swr
61f58c7388Spefo #define LDLO    ldl
62f58c7388Spefo #define LDHI    ldr
63f58c7388Spefo #define	SDLO	sdl
64f58c7388Spefo #define	SDHI	sdr
65f58c7388Spefo #endif
66f58c7388Spefo #if defined(__MIPSEB__)
67f58c7388Spefo #define LWLO    lwr
68f58c7388Spefo #define LWHI    lwl
69f58c7388Spefo #define	SWLO	swr
70f58c7388Spefo #define	SWHI	swl
71f58c7388Spefo #define LDLO    ldr
72f58c7388Spefo #define LDHI    ldl
73f58c7388Spefo #define	SDLO	sdr
74f58c7388Spefo #define	SDHI	sdl
75f58c7388Spefo #endif
76f58c7388Spefo 
77f58c7388Spefo /*
78f58c7388Spefo  *  Define programming environment for ABI.
79f58c7388Spefo  */
80f58c7388Spefo #if defined(ABICALLS) && !defined(_KERNEL) && !defined(_STANDALONE)
81f58c7388Spefo 
82f58c7388Spefo #ifndef _MIPS_SIM
83f58c7388Spefo #define _MIPS_SIM 1
84f58c7388Spefo #define _ABIO32	1
85f58c7388Spefo #endif
86f58c7388Spefo #ifndef _MIPS_ISA
87f58c7388Spefo #define _MIPS_ISA 2
88f58c7388Spefo #define _MIPS_ISA_MIPS2 2
89f58c7388Spefo #endif
90f58c7388Spefo 
91f58c7388Spefo #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
92f58c7388Spefo #define NARGSAVE	4
93f58c7388Spefo 
94f58c7388Spefo #define	SETUP_GP		\
95f58c7388Spefo 	.set	noreorder;	\
96f58c7388Spefo 	.cpload	t9;		\
97f58c7388Spefo 	.set	reorder;
98f58c7388Spefo 
99f58c7388Spefo #define	SAVE_GP(x)		\
100f58c7388Spefo 	.cprestore x
101f58c7388Spefo 
1024a63270fSpefo #define	SETUP_GP64(gpoff, name)
1034a63270fSpefo #define	RESTORE_GP64
104f58c7388Spefo #endif
105f58c7388Spefo 
106f58c7388Spefo #if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)
107f58c7388Spefo #define NARGSAVE	0
108f58c7388Spefo 
109f58c7388Spefo #define	SETUP_GP
110f58c7388Spefo #define	SAVE_GP(x)
1114a63270fSpefo #define	SETUP_GP64(gpoff, name)	\
1124a63270fSpefo 	.cpsetup t9, gpoff, name
1134a63270fSpefo #define	RESTORE_GP64		\
1144a63270fSpefo 	.cpreturn
115f58c7388Spefo #endif
116f58c7388Spefo 
1174a63270fSpefo #define	MKFSIZ(narg,locals) (((narg+locals)*REGSZ+31)&(~31))
1184a63270fSpefo 
119f58c7388Spefo #else /* defined(ABICALLS) && !defined(_KERNEL) */
120f58c7388Spefo 
121f58c7388Spefo #define	NARGSAVE	4
122f58c7388Spefo #define	SETUP_GP
123f58c7388Spefo #define	SAVE_GP(x)
124f58c7388Spefo 
125f58c7388Spefo #define	ALIGNSZ		16	/* Stack layout alignment */
126f58c7388Spefo #define	FRAMESZ(sz)	(((sz) + (ALIGNSZ-1)) & ~(ALIGNSZ-1))
127f58c7388Spefo 
1284a63270fSpefo #endif
1294a63270fSpefo 
130f58c7388Spefo /*
131f58c7388Spefo  *  Basic register operations based on selected ISA
132f58c7388Spefo  */
1330fa15b16Svisa #if (_MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || \
1340fa15b16Svisa     _MIPS_ISA == _MIPS_ISA_MIPS32)
135f58c7388Spefo #define REGSZ		4	/* 32 bit mode register size */
136f58c7388Spefo #define LOGREGSZ	2	/* log rsize */
137f58c7388Spefo #define	REG_S	sw
138f58c7388Spefo #define	REG_L	lw
139f58c7388Spefo #define	CF_SZ		24	/* Call frame size */
140f58c7388Spefo #define	CF_ARGSZ	16	/* Call frame arg size */
141f58c7388Spefo #define	CF_RA_OFFS	20	/* Call ra save offset */
142f58c7388Spefo #endif
143f58c7388Spefo 
1440fa15b16Svisa #if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || \
1450fa15b16Svisa     _MIPS_ISA == _MIPS_ISA_MIPS64)
146f58c7388Spefo #define REGSZ		8	/* 64 bit mode register size */
147f58c7388Spefo #define LOGREGSZ	3	/* log rsize */
148f58c7388Spefo #define	REG_S	sd
149f58c7388Spefo #define	REG_L	ld
150f58c7388Spefo #define	CF_SZ		48	/* Call frame size (multiple of ALIGNSZ) */
151f58c7388Spefo #define	CF_ARGSZ	32	/* Call frame arg size */
152f58c7388Spefo #define	CF_RA_OFFS	40	/* Call ra save offset */
153f58c7388Spefo #endif
154f58c7388Spefo 
155195da3bdSmiod #ifndef __LP64__
156195da3bdSmiod #define	PTR_L		lw
157195da3bdSmiod #define	PTR_S		sw
158195da3bdSmiod #define	PTR_SUB		sub
159195da3bdSmiod #define	PTR_ADD		add
160195da3bdSmiod #define	PTR_SUBU	subu
161195da3bdSmiod #define	PTR_ADDU	addu
162195da3bdSmiod #define LI		li
163195da3bdSmiod #define	LA		la
164195da3bdSmiod #define	PTR_SLL		sll
165195da3bdSmiod #define	PTR_SRL		srl
166195da3bdSmiod #define	PTR_VAL		.word
167195da3bdSmiod #else
168f58c7388Spefo #define	PTR_L		ld
169f58c7388Spefo #define	PTR_S		sd
170f58c7388Spefo #define	PTR_ADD		dadd
171f58c7388Spefo #define	PTR_SUB		dsub
172f58c7388Spefo #define	PTR_SUBU	dsubu
173f58c7388Spefo #define	PTR_ADDU	daddu
174f58c7388Spefo #define LI		dli
175f58c7388Spefo #define LA		dla
176f58c7388Spefo #define	PTR_SLL		dsll
177f58c7388Spefo #define	PTR_SRL		dsrl
178f58c7388Spefo #define	PTR_VAL		.dword
179195da3bdSmiod #endif
180f58c7388Spefo 
18199068adfSmiod #define	NOP	nop
18299068adfSmiod #define	DMFC0	dmfc0
18399068adfSmiod #define	DMTC0	dmtc0
18499068adfSmiod #define	MFC0	mfc0
18599068adfSmiod #define	MTC0	mtc0
18699068adfSmiod #define	ERET	sync; eret
18799068adfSmiod 
188f58c7388Spefo /*
189f58c7388Spefo  * Define -pg profile entry code.
190f58c7388Spefo  */
191f58c7388Spefo #if defined(XGPROF) || defined(XPROF)
192f58c7388Spefo #define	MCOUNT			\
19350027fe1Smiod 	PTR_SUBU sp, sp, 64;	\
194f58c7388Spefo 	SAVE_GP(16);		\
19550027fe1Smiod 	sd	ra, 56(sp);	\
19650027fe1Smiod 	sd	gp, 48(sp);	\
197f58c7388Spefo 	.set	noat;		\
198f58c7388Spefo 	.set	noreorder;	\
199f58c7388Spefo 	move	AT, ra;		\
200f58c7388Spefo 	jal	_mcount;	\
20150027fe1Smiod 	PTR_SUBU sp, sp, 16;	\
20250027fe1Smiod 	ld	ra, 56(sp);	\
20350027fe1Smiod 	PTR_ADDU sp, sp, 64;	\
204f58c7388Spefo 	.set reorder;		\
205f58c7388Spefo 	.set	at;
206f58c7388Spefo #else
207f58c7388Spefo #define	MCOUNT
208f58c7388Spefo #endif
209f58c7388Spefo 
210f58c7388Spefo /*
2114a63270fSpefo  * LEAF(x, fsize)
212f58c7388Spefo  *
213f58c7388Spefo  *	Declare a leaf routine.
214f58c7388Spefo  */
2154a63270fSpefo #define LEAF(x, fsize)		\
216f58c7388Spefo 	.align	3;		\
217f58c7388Spefo 	.globl x;		\
218f58c7388Spefo 	.ent x, 0;		\
219f58c7388Spefo x: ;				\
2204a63270fSpefo 	.frame sp, fsize, ra;	\
221f58c7388Spefo 	SETUP_GP		\
222f58c7388Spefo 	MCOUNT
223f58c7388Spefo 
224f58c7388Spefo #define	ALEAF(x)		\
225f58c7388Spefo 	.globl	x;		\
226f58c7388Spefo x:
227f58c7388Spefo 
228f58c7388Spefo /*
229f58c7388Spefo  * NLEAF(x)
230f58c7388Spefo  *
231f58c7388Spefo  *	Declare a non-profiled leaf routine.
232f58c7388Spefo  */
2334a63270fSpefo #define NLEAF(x, fsize)		\
234f58c7388Spefo 	.align	3;		\
235f58c7388Spefo 	.globl x;		\
236f58c7388Spefo 	.ent x, 0;		\
237f58c7388Spefo x: ;				\
2384a63270fSpefo 	.frame sp, fsize, ra;	\
239f58c7388Spefo 	SETUP_GP
240f58c7388Spefo 
241f58c7388Spefo /*
242f58c7388Spefo  * NON_LEAF(x)
243f58c7388Spefo  *
244f58c7388Spefo  *	Declare a non-leaf routine (a routine that makes other C calls).
245f58c7388Spefo  */
246f58c7388Spefo #define NON_LEAF(x, fsize, retpc) \
247f58c7388Spefo 	.align	3;		\
248f58c7388Spefo 	.globl x;		\
249f58c7388Spefo 	.ent x, 0;		\
250f58c7388Spefo x: ;				\
251f58c7388Spefo 	.frame sp, fsize, retpc; \
252f58c7388Spefo 	SETUP_GP		\
253f58c7388Spefo 	MCOUNT
254f58c7388Spefo 
255f58c7388Spefo /*
256f58c7388Spefo  * NNON_LEAF(x)
257f58c7388Spefo  *
258f58c7388Spefo  *	Declare a non-profiled non-leaf routine
259f58c7388Spefo  *	(a routine that makes other C calls).
260f58c7388Spefo  */
261f58c7388Spefo #define NNON_LEAF(x, fsize, retpc) \
262f58c7388Spefo 	.align	3;		\
263f58c7388Spefo 	.globl x;		\
264f58c7388Spefo 	.ent x, 0;		\
265f58c7388Spefo x: ;				\
266f58c7388Spefo 	.frame sp, fsize, retpc	\
267f58c7388Spefo 	SETUP_GP
268f58c7388Spefo 
269f58c7388Spefo /*
270f58c7388Spefo  * END(x)
271f58c7388Spefo  *
272f58c7388Spefo  *	Mark end of a procedure.
273f58c7388Spefo  */
274f58c7388Spefo #define END(x) \
275f58c7388Spefo 	.end x
276f58c7388Spefo 
277f58c7388Spefo /*
2785a25e2caSmartynas  * STRONG_ALIAS, WEAK_ALIAS
2795a25e2caSmartynas  *	Create a strong or weak alias.
280eca0a8dbSguenther  */
2815a25e2caSmartynas #define STRONG_ALIAS(alias,sym) \
2825a25e2caSmartynas 	.global alias; alias = sym
283eca0a8dbSguenther #define WEAK_ALIAS(alias,sym) \
284eca0a8dbSguenther 	.weak alias; alias = sym
285eca0a8dbSguenther 
286eca0a8dbSguenther 
287eca0a8dbSguenther /*
288f58c7388Spefo  * Macros to panic and printf from assembly language.
289f58c7388Spefo  */
290f58c7388Spefo #define PANIC(msg) \
2914a63270fSpefo 	LA	a0, 9f; \
292f58c7388Spefo 	jal	panic;	\
293f58c7388Spefo 	nop	;	\
294f58c7388Spefo 	MSG(msg)
295f58c7388Spefo 
296f58c7388Spefo #define	PRINTF(msg) \
29750027fe1Smiod 	LA	a0, 9f; \
298f58c7388Spefo 	jal	printf; \
299f58c7388Spefo 	nop	;	\
300f58c7388Spefo 	MSG(msg)
301f58c7388Spefo 
302f58c7388Spefo #define	MSG(msg) \
303f58c7388Spefo 	.rdata; \
304f58c7388Spefo 9:	.asciiz	msg; \
305f58c7388Spefo 	.text
306f58c7388Spefo 
307c1805af1Smiod #define	LOAD_XKPHYS(reg, cca) \
308c1805af1Smiod 	li	reg, cca | 0x10; \
309c1805af1Smiod 	dsll	reg, reg, 59
310c1805af1Smiod 
3111b9cca20Ssyuu #ifdef MULTIPROCESSOR
3121d6e3571Ssyuu #define GET_CPU_INFO(ci, tmp)	HW_GET_CPU_INFO(ci, tmp)
3131b9cca20Ssyuu #else  /* MULTIPROCESSOR */
3141b9cca20Ssyuu #define GET_CPU_INFO(ci, tmp)		\
3151b9cca20Ssyuu 	LA	ci, cpu_info_primary
3161b9cca20Ssyuu #endif /* MULTIPROCESSOR */
3171b9cca20Ssyuu 
3183b05e32eSmiod /*
3193b05e32eSmiod  * Hazards
3203b05e32eSmiod  */
3213b05e32eSmiod 
322692dc7b2Svisa #ifdef CPU_OCTEON
323692dc7b2Svisa /*
324692dc7b2Svisa  * OCTEON clears hazards in hardware.
325692dc7b2Svisa  */
326692dc7b2Svisa #define	MFC0_HAZARD		/* nothing */
327692dc7b2Svisa #define	MTC0_HAZARD		/* nothing */
328692dc7b2Svisa #define	MTC0_SR_IE_HAZARD	/* nothing */
329692dc7b2Svisa #define	MTC0_SR_CU_HAZARD	/* nothing */
330692dc7b2Svisa #define	TLB_HAZARD		/* nothing */
331692dc7b2Svisa #endif
332692dc7b2Svisa 
3333b05e32eSmiod /* Hazard between {d,}mfc0 of COP_0_VADDR */
3343b05e32eSmiod #ifndef	PRE_MFC0_ADDR_HAZARD
3353b05e32eSmiod #define	PRE_MFC0_ADDR_HAZARD	/* nothing */
3363b05e32eSmiod #endif
3373b05e32eSmiod 
3383b05e32eSmiod /* Hazard after {d,}mfc0 from any register */
3393b05e32eSmiod #ifndef	MFC0_HAZARD
3403b05e32eSmiod #define	MFC0_HAZARD     	/* nothing */
3413b05e32eSmiod #endif
3423b05e32eSmiod /* Hazard after {d,}mtc0 to any register */
3433b05e32eSmiod #ifndef	MTC0_HAZARD
3443b05e32eSmiod #define	MTC0_HAZARD     	NOP; NOP; NOP; NOP
3453b05e32eSmiod #endif
3463b05e32eSmiod /* Hazard after {d,}mtc0 to COP_0_SR affecting the state of interrupts */
3473b05e32eSmiod #ifndef	MTC0_SR_IE_HAZARD
3483b05e32eSmiod #define	MTC0_SR_IE_HAZARD	MTC0_HAZARD
3493b05e32eSmiod #endif
3503b05e32eSmiod /* Hazard after {d,}mtc0 to COP_0_SR affecting the state of coprocessors */
3513b05e32eSmiod #ifndef	MTC0_SR_CU_HAZARD
3523b05e32eSmiod #define	MTC0_SR_CU_HAZARD	NOP; NOP
3533b05e32eSmiod #endif
3543b05e32eSmiod 
3553b05e32eSmiod /* Hazard before and after a tlbp, tlbr, tlbwi or tlbwr instruction */
3563b05e32eSmiod #ifndef	TLB_HAZARD
3573b05e32eSmiod #define	TLB_HAZARD		NOP; NOP
3583b05e32eSmiod #endif
3593b05e32eSmiod 
3602fa72412Spirofti #endif /* !_MIPS64_ASM_H_ */
361