1/*	$OpenBSD: asm.h,v 1.7 2004/10/20 12:49:15 pefo 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#ifdef NEED_OLD_RM7KFIX
34#define ITLBNOPFIX      nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
35#else
36#define ITLBNOPFIX      nop;nop;nop;nop
37#endif
38
39#define	_MIPS_ISA_MIPS1	1	/* R2000/R3000 */
40#define	_MIPS_ISA_MIPS2	2	/* R4000/R6000 */
41#define	_MIPS_ISA_MIPS3	3	/* R4000 */
42#define	_MIPS_ISA_MIPS4	4	/* TFP (R1x000) */
43#ifdef __linux__
44#define	_MIPS_ISA_MIPS5 5
45#define	_MIPS_ISA_MIPS32 6
46#define	_MIPS_ISA_MIPS64 7
47#else
48#define	_MIPS_ISA_MIPS32 32	/* MIPS32 */
49#endif
50
51#if !defined(ABICALLS) && !defined(_NO_ABICALLS)
52#define	ABICALLS	.abicalls
53#endif
54
55#if defined(ABICALLS) && !defined(_KERNEL)
56	ABICALLS
57#endif
58
59#define _C_LABEL(x) x		/* XXX Obsolete but keep for a while */
60
61#if !defined(__MIPSEL__) && !defined(__MIPSEB__)
62#error "__MIPSEL__ or __MIPSEB__ must be defined"
63#endif
64/*
65 * Define how to access unaligned data word
66 */
67#if defined(__MIPSEL__)
68#define LWLO    lwl
69#define LWHI    lwr
70#define	SWLO	swl
71#define	SWHI	swr
72#define LDLO    ldl
73#define LDHI    ldr
74#define	SDLO	sdl
75#define	SDHI	sdr
76#endif
77#if defined(__MIPSEB__)
78#define LWLO    lwr
79#define LWHI    lwl
80#define	SWLO	swr
81#define	SWHI	swl
82#define LDLO    ldr
83#define LDHI    ldl
84#define	SDLO	sdr
85#define	SDHI	sdl
86#endif
87
88/*
89 *  Define programming environment for ABI.
90 */
91#if defined(ABICALLS) && !defined(_KERNEL) && !defined(_STANDALONE)
92
93#ifndef _MIPS_SIM
94#define _MIPS_SIM 1
95#define _ABIO32	1
96#endif
97#ifndef _MIPS_ISA
98#define _MIPS_ISA 2
99#define _MIPS_ISA_MIPS2 2
100#endif
101
102#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
103#define NARGSAVE	4
104
105#define	SETUP_GP		\
106	.set	noreorder;	\
107	.cpload	t9;		\
108	.set	reorder;
109
110#define	SAVE_GP(x)		\
111	.cprestore x
112
113#define	SETUP_GP64(gpoff, name)
114#define	RESTORE_GP64
115#endif
116
117#if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)
118#define NARGSAVE	0
119
120#define	SETUP_GP
121#define	SAVE_GP(x)
122#define	SETUP_GP64(gpoff, name)	\
123	.cpsetup t9, gpoff, name
124#define	RESTORE_GP64		\
125	.cpreturn
126#endif
127
128#define	MKFSIZ(narg,locals) (((narg+locals)*REGSZ+31)&(~31))
129
130#else /* defined(ABICALLS) && !defined(_KERNEL) */
131
132#define	NARGSAVE	4
133#define	SETUP_GP
134#define	SAVE_GP(x)
135
136#define	ALIGNSZ		16	/* Stack layout alignment */
137#define	FRAMESZ(sz)	(((sz) + (ALIGNSZ-1)) & ~(ALIGNSZ-1))
138
139#endif
140
141/*
142 *  Basic register operations based on selected ISA
143 */
144#if (_MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || _MIPS_ISA == _MIPS_ISA_MIPS32)
145#define REGSZ		4	/* 32 bit mode register size */
146#define LOGREGSZ	2	/* log rsize */
147#define	REG_S	sw
148#define	REG_L	lw
149#define	CF_SZ		24	/* Call frame size */
150#define	CF_ARGSZ	16	/* Call frame arg size */
151#define	CF_RA_OFFS	20	/* Call ra save offset */
152#endif
153
154#if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4)
155#define REGSZ		8	/* 64 bit mode register size */
156#define LOGREGSZ	3	/* log rsize */
157#define	REG_S	sd
158#define	REG_L	ld
159#define	CF_SZ		48	/* Call frame size (multiple of ALIGNSZ) */
160#define	CF_ARGSZ	32	/* Call frame arg size */
161#define	CF_RA_OFFS	40	/* Call ra save offset */
162#endif
163
164#define REGSZ_FP	 8	/* 64 bit FP register size */
165
166#ifndef __LP64__
167#define	PTR_L		lw
168#define	PTR_S		sw
169#define	PTR_SUB		sub
170#define	PTR_ADD		add
171#define	PTR_SUBU	subu
172#define	PTR_ADDU	addu
173#define LI		li
174#define	LA		la
175#define	PTR_SLL		sll
176#define	PTR_SRL		srl
177#define	PTR_VAL		.word
178#else
179#define	PTR_L		ld
180#define	PTR_S		sd
181#define	PTR_ADD		dadd
182#define	PTR_SUB		dsub
183#define	PTR_SUBU	dsubu
184#define	PTR_ADDU	daddu
185#define LI		dli
186#define LA		dla
187#define	PTR_SLL		dsll
188#define	PTR_SRL		dsrl
189#define	PTR_VAL		.dword
190#endif
191
192/*
193 * Define -pg profile entry code.
194 */
195#if defined(XGPROF) || defined(XPROF)
196#define	MCOUNT			\
197	PTR_SUBU sp, sp, 32;	\
198	SAVE_GP(16);		\
199	sw	ra, 28(sp);	\
200	sw	gp, 24(sp);	\
201	.set	noat;		\
202	.set	noreorder;	\
203	move	AT, ra;		\
204	jal	_mcount;	\
205	PTR_SUBU sp, sp, 8;	\
206	lw	ra, 28(sp);	\
207	PTR_ADDU sp, sp, 32;	\
208	.set reorder;		\
209	.set	at;
210#else
211#define	MCOUNT
212#endif
213
214/*
215 * LEAF(x, fsize)
216 *
217 *	Declare a leaf routine.
218 */
219#define LEAF(x, fsize)		\
220	.align	3;		\
221	.globl x;		\
222	.ent x, 0;		\
223x: ;				\
224	.frame sp, fsize, ra;	\
225	SETUP_GP		\
226	MCOUNT
227
228#define	ALEAF(x)		\
229	.globl	x;		\
230x:
231
232/*
233 * NLEAF(x)
234 *
235 *	Declare a non-profiled leaf routine.
236 */
237#define NLEAF(x, fsize)		\
238	.align	3;		\
239	.globl x;		\
240	.ent x, 0;		\
241x: ;				\
242	.frame sp, fsize, ra;	\
243	SETUP_GP
244
245/*
246 * NON_LEAF(x)
247 *
248 *	Declare a non-leaf routine (a routine that makes other C calls).
249 */
250#define NON_LEAF(x, fsize, retpc) \
251	.align	3;		\
252	.globl x;		\
253	.ent x, 0;		\
254x: ;				\
255	.frame sp, fsize, retpc; \
256	SETUP_GP		\
257	MCOUNT
258
259/*
260 * NNON_LEAF(x)
261 *
262 *	Declare a non-profiled non-leaf routine
263 *	(a routine that makes other C calls).
264 */
265#define NNON_LEAF(x, fsize, retpc) \
266	.align	3;		\
267	.globl x;		\
268	.ent x, 0;		\
269x: ;				\
270	.frame sp, fsize, retpc	\
271	SETUP_GP
272
273/*
274 * END(x)
275 *
276 *	Mark end of a procedure.
277 */
278#define END(x) \
279	.end x
280
281/*
282 * Macros to panic and printf from assembly language.
283 */
284#define PANIC(msg) \
285	LA	a0, 9f; \
286	jal	panic;	\
287	nop	;	\
288	MSG(msg)
289
290#define	PRINTF(msg) \
291	la	a0, 9f; \
292	jal	printf; \
293	nop	;	\
294	MSG(msg)
295
296#define	MSG(msg) \
297	.rdata; \
2989:	.asciiz	msg; \
299	.text
300
301#define ASMSTR(str) \
302	.asciiz str; \
303	.align	3
304
305#endif /* !_MIPS_ASM_H */
306