1352e51dimp/*	$NetBSD: asm.h,v 1.29 2000/12/14 21:29:51 jeffs Exp $	*/
2352e51dimp
3352e51dimp/*
44736ccfpfg * SPDX-License-Identifier: BSD-3-Clause
54736ccfpfg *
6352e51dimp * Copyright (c) 1992, 1993
7352e51dimp *	The Regents of the University of California.  All rights reserved.
8352e51dimp *
9352e51dimp * This code is derived from software contributed to Berkeley by
10352e51dimp * Ralph Campbell.
11352e51dimp *
12352e51dimp * Redistribution and use in source and binary forms, with or without
13352e51dimp * modification, are permitted provided that the following conditions
14352e51dimp * are met:
15352e51dimp * 1. Redistributions of source code must retain the above copyright
16352e51dimp *    notice, this list of conditions and the following disclaimer.
17352e51dimp * 2. Redistributions in binary form must reproduce the above copyright
18352e51dimp *    notice, this list of conditions and the following disclaimer in the
19352e51dimp *    documentation and/or other materials provided with the distribution.
207e6cabdimp * 3. Neither the name of the University nor the names of its contributors
21352e51dimp *    may be used to endorse or promote products derived from this software
22352e51dimp *    without specific prior written permission.
23352e51dimp *
24352e51dimp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25352e51dimp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26352e51dimp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27352e51dimp * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28352e51dimp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29352e51dimp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30352e51dimp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31352e51dimp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32352e51dimp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33352e51dimp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34352e51dimp * SUCH DAMAGE.
35352e51dimp *
36352e51dimp *	@(#)machAsmDefs.h	8.1 (Berkeley) 6/10/93
37352e51dimp *	JNPR: asm.h,v 1.10 2007/08/09 11:23:32 katta
38352e51dimp * $FreeBSD$
39352e51dimp */
40352e51dimp
41352e51dimp/*
42352e51dimp * machAsmDefs.h --
43352e51dimp *
44352e51dimp *	Macros used when writing assembler programs.
45352e51dimp *
46352e51dimp *	Copyright (C) 1989 Digital Equipment Corporation.
47352e51dimp *	Permission to use, copy, modify, and distribute this software and
48352e51dimp *	its documentation for any purpose and without fee is hereby granted,
49352e51dimp *	provided that the above copyright notice appears in all copies.
50352e51dimp *	Digital Equipment Corporation makes no representations about the
51352e51dimp *	suitability of this software for any purpose.  It is provided "as is"
52352e51dimp *	without express or implied warranty.
53352e51dimp *
54352e51dimp * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsmDefs.h,
55352e51dimp *	v 1.2 89/08/15 18:28:24 rab Exp  SPRITE (DECWRL)
56352e51dimp */
57352e51dimp
58352e51dimp#ifndef _MACHINE_ASM_H_
59352e51dimp#define	_MACHINE_ASM_H_
60352e51dimp
61d4fdf34jhb#include <machine/abi.h>
62352e51dimp#include <machine/regdef.h>
63352e51dimp#include <machine/endian.h>
646e3a5d4imp#include <machine/cdefs.h>
65352e51dimp
66352e51dimp#undef __FBSDID
67352e51dimp#if !defined(lint) && !defined(STRIP_FBSDID)
68352e51dimp#define	__FBSDID(s)	.ident s
69352e51dimp#else
70352e51dimp#define	__FBSDID(s)	/* nothing */
71352e51dimp#endif
72352e51dimp
73352e51dimp/*
74352e51dimp * Define -pg profile entry code.
75352e51dimp * Must always be noreorder, must never use a macro instruction
76352e51dimp * Final addiu to t9 must always equal the size of this _KERN_MCOUNT
77352e51dimp */
78352e51dimp#define	_KERN_MCOUNT			\
79352e51dimp	.set	push;			\
80352e51dimp	.set	noreorder;		\
81352e51dimp	.set	noat;			\
82352e51dimp	subu	sp,sp,16;		\
83352e51dimp	sw	t9,12(sp);		\
84352e51dimp	move	AT,ra;			\
85352e51dimp	lui	t9,%hi(_mcount);	\
86352e51dimp	addiu	t9,t9,%lo(_mcount);	\
87352e51dimp	jalr	t9;			\
88352e51dimp	nop;				\
89352e51dimp	lw	t9,4(sp);		\
90352e51dimp	addiu	sp,sp,8;		\
91352e51dimp	addiu	t9,t9,40;		\
92352e51dimp	.set	pop;
93352e51dimp
94352e51dimp#ifdef GPROF
95352e51dimp#define	MCOUNT _KERN_MCOUNT
96352e51dimp#else
97352e51dimp#define	MCOUNT
98352e51dimp#endif
99352e51dimp
100352e51dimp#define	_C_LABEL(x)	x
101352e51dimp
102352e51dimp#ifdef USE_AENT
103352e51dimp#define	AENT(x)		\
104352e51dimp	.aent	x, 0
105352e51dimp#else
106352e51dimp#define	AENT(x)
107352e51dimp#endif
108352e51dimp
109352e51dimp/*
110352e51dimp * WARN_REFERENCES: create a warning if the specified symbol is referenced
111352e51dimp */
112352e51dimp#define	WARN_REFERENCES(_sym,_msg)				\
113352e51dimp	.section .gnu.warning. ## _sym ; .ascii _msg ; .text
114352e51dimp
115352e51dimp#ifdef __ELF__
116352e51dimp# define _C_LABEL(x)    x
117352e51dimp#else
118352e51dimp#  define _C_LABEL(x)   _ ## x
119352e51dimp#endif
120352e51dimp
121352e51dimp/*
122352e51dimp * WEAK_ALIAS: create a weak alias.
123352e51dimp */
124352e51dimp#define	WEAK_ALIAS(alias,sym)						\
125352e51dimp	.weak alias;							\
126352e51dimp	alias = sym
127352e51dimp
128352e51dimp/*
129352e51dimp * STRONG_ALIAS: create a strong alias.
130352e51dimp */
131352e51dimp#define STRONG_ALIAS(alias,sym)						\
132352e51dimp	.globl alias;							\
133352e51dimp	alias = sym
134352e51dimp
135352e51dimp#define	GLOBAL(sym)						\
136352e51dimp	.globl sym; sym:
137352e51dimp
138352e51dimp#define	ENTRY(sym)						\
139352e51dimp	.text; .globl sym; .ent sym; sym:
140352e51dimp
141352e51dimp#define	ASM_ENTRY(sym)						\
142352e51dimp	.text; .globl sym; .type sym,@function; sym:
143352e51dimp
144352e51dimp/*
145352e51dimp * LEAF
146352e51dimp *	A leaf routine does
147352e51dimp *	- call no other function,
148352e51dimp *	- never use any register that callee-saved (S0-S8), and
149352e51dimp *	- not use any local stack storage.
150352e51dimp */
151352e51dimp#define	LEAF(x)			\
152352e51dimp	.globl	_C_LABEL(x);	\
153352e51dimp	.ent	_C_LABEL(x), 0;	\
154352e51dimp_C_LABEL(x): ;			\
155352e51dimp	.frame sp, 0, ra;	\
156352e51dimp	MCOUNT
157352e51dimp
158352e51dimp/*
159352e51dimp * LEAF_NOPROFILE
160352e51dimp *	No profilable leaf routine.
161352e51dimp */
162352e51dimp#define	LEAF_NOPROFILE(x)	\
163352e51dimp	.globl	_C_LABEL(x);	\
164352e51dimp	.ent	_C_LABEL(x), 0;	\
165352e51dimp_C_LABEL(x): ;			\
166352e51dimp	.frame	sp, 0, ra
167352e51dimp
168352e51dimp/*
169352e51dimp * XLEAF
170352e51dimp *	declare alternate entry to leaf routine
171352e51dimp */
172352e51dimp#define	XLEAF(x)		\
173352e51dimp	.globl	_C_LABEL(x);	\
174352e51dimp	AENT (_C_LABEL(x));	\
175352e51dimp_C_LABEL(x):
176352e51dimp
177352e51dimp/*
178352e51dimp * NESTED
179352e51dimp *	A function calls other functions and needs
180352e51dimp *	therefore stack space to save/restore registers.
181352e51dimp */
182352e51dimp#define	NESTED(x, fsize, retpc)		\
183352e51dimp	.globl	_C_LABEL(x);		\
184352e51dimp	.ent	_C_LABEL(x), 0;		\
185352e51dimp_C_LABEL(x): ;				\
186352e51dimp	.frame	sp, fsize, retpc;	\
187352e51dimp	MCOUNT
188352e51dimp
189352e51dimp/*
190352e51dimp * NESTED_NOPROFILE(x)
191352e51dimp *	No profilable nested routine.
192352e51dimp */
193352e51dimp#define	NESTED_NOPROFILE(x, fsize, retpc)	\
194352e51dimp	.globl	_C_LABEL(x);			\
195352e51dimp	.ent	_C_LABEL(x), 0;			\
196352e51dimp_C_LABEL(x): ;					\
197352e51dimp	.frame	sp, fsize, retpc
198352e51dimp
199352e51dimp/*
200352e51dimp * XNESTED
201352e51dimp *	declare alternate entry point to nested routine.
202352e51dimp */
203352e51dimp#define	XNESTED(x)		\
204352e51dimp	.globl	_C_LABEL(x);	\
205352e51dimp	AENT (_C_LABEL(x));	\
206352e51dimp_C_LABEL(x):
207352e51dimp
208352e51dimp/*
209352e51dimp * END
210352e51dimp *	Mark end of a procedure.
211352e51dimp */
212352e51dimp#define	END(x)			\
213352e51dimp	.end _C_LABEL(x)
214352e51dimp
215352e51dimp/*
216352e51dimp * IMPORT -- import external symbol
217352e51dimp */
218352e51dimp#define	IMPORT(sym, size)	\
219352e51dimp	.extern _C_LABEL(sym),size
220352e51dimp
221352e51dimp/*
222352e51dimp * EXPORT -- export definition of symbol
223352e51dimp */
224352e51dimp#define	EXPORT(x)		\
225352e51dimp	.globl	_C_LABEL(x);	\
226352e51dimp_C_LABEL(x):
227352e51dimp
228352e51dimp/*
229352e51dimp * VECTOR
230352e51dimp *	exception vector entrypoint
231352e51dimp *	XXX: regmask should be used to generate .mask
232352e51dimp */
233352e51dimp#define	VECTOR(x, regmask)	\
234352e51dimp	.ent	_C_LABEL(x),0;	\
235352e51dimp	EXPORT(x);		\
236352e51dimp
237352e51dimp#define	VECTOR_END(x)		\
238352e51dimp	EXPORT(x ## End);	\
239352e51dimp	END(x)
240352e51dimp
241352e51dimp/*
242352e51dimp * Macros to panic and printf from assembly language.
243352e51dimp */
244352e51dimp#define	PANIC(msg)			\
2456e3a5d4imp	PTR_LA	a0, 9f;			\
246352e51dimp	jal	_C_LABEL(panic);	\
247352e51dimp	nop;				\
248352e51dimp	MSG(msg)
249352e51dimp
250352e51dimp#define	PANIC_KSEG0(msg, reg)	PANIC(msg)
251352e51dimp
252352e51dimp#define	PRINTF(msg)			\
2536e3a5d4imp	PTR_LA	a0, 9f;			\
254352e51dimp	jal	_C_LABEL(printf);	\
255352e51dimp	nop;				\
256352e51dimp	MSG(msg)
257352e51dimp
258352e51dimp#define	MSG(msg)			\
259352e51dimp	.rdata;				\
260352e51dimp9:	.asciiz	msg;			\
261352e51dimp	.text
262352e51dimp
263352e51dimp#define	ASMSTR(str)			\
264352e51dimp	.asciiz str;			\
265352e51dimp	.align	3
266352e51dimp
267090d85fimp#if defined(__mips_o32) || defined(__mips_o64)
268090d85fimp#define	ALSK	7		/* stack alignment */
269090d85fimp#define	ALMASK	-7		/* stack alignment */
270090d85fimp#define	SZFPREG	4
271090d85fimp#define	FP_L	lwc1
272090d85fimp#define	FP_S	swc1
273090d85fimp#else
274090d85fimp#define	ALSK	15		/* stack alignment */
275090d85fimp#define	ALMASK	-15		/* stack alignment */
276090d85fimp#define	SZFPREG	8
277090d85fimp#define	FP_L	ldc1
278090d85fimp#define	FP_S	sdc1
279090d85fimp#endif
280090d85fimp
281352e51dimp/*
2825605409jmallett *   Endian-independent assembly-code aliases for unaligned memory accesses.
2835605409jmallett */
2845605409jmallett#if _BYTE_ORDER == _LITTLE_ENDIAN
2855605409jmallett# define LWHI lwr
2865605409jmallett# define LWLO lwl
2875605409jmallett# define SWHI swr
2885605409jmallett# define SWLO swl
2895605409jmallett# if SZREG == 4
2905605409jmallett#  define REG_LHI   lwr
2915605409jmallett#  define REG_LLO   lwl
2925605409jmallett#  define REG_SHI   swr
2935605409jmallett#  define REG_SLO   swl
2945605409jmallett# else
2955605409jmallett#  define REG_LHI   ldr
2965605409jmallett#  define REG_LLO   ldl
2975605409jmallett#  define REG_SHI   sdr
2985605409jmallett#  define REG_SLO   sdl
2995605409jmallett# endif
3005605409jmallett#endif
3015605409jmallett
3025605409jmallett#if _BYTE_ORDER == _BIG_ENDIAN
3035605409jmallett# define LWHI lwl
3045605409jmallett# define LWLO lwr
3055605409jmallett# define SWHI swl
3065605409jmallett# define SWLO swr
3075605409jmallett# if SZREG == 4
3085605409jmallett#  define REG_LHI   lwl
3095605409jmallett#  define REG_LLO   lwr
3105605409jmallett#  define REG_SHI   swl
3115605409jmallett#  define REG_SLO   swr
3125605409jmallett# else
3135605409jmallett#  define REG_LHI   ldl
3145605409jmallett#  define REG_LLO   ldr
3155605409jmallett#  define REG_SHI   sdl
3165605409jmallett#  define REG_SLO   sdr
3175605409jmallett# endif
3185605409jmallett#endif
3195605409jmallett
3205605409jmallett/*
321352e51dimp * While it would be nice to be compatible with the SGI
322352e51dimp * REG_L and REG_S macros, because they do not take parameters, it
323352e51dimp * is impossible to use them with the _MIPS_SIM_ABIX32 model.
324352e51dimp *
325352e51dimp * These macros hide the use of mips3 instructions from the
326352e51dimp * assembler to prevent the assembler from generating 64-bit style
327352e51dimp * ABI calls.
328352e51dimp */
329090d85fimp#if _MIPS_SZPTR == 32
330090d85fimp#define	PTR_ADD		add
331090d85fimp#define	PTR_ADDI	addi
332090d85fimp#define	PTR_ADDU	addu
333090d85fimp#define	PTR_ADDIU	addiu
334090d85fimp#define	PTR_SUB		add
335090d85fimp#define	PTR_SUBI	subi
336090d85fimp#define	PTR_SUBU	subu
337090d85fimp#define	PTR_SUBIU	subu
338090d85fimp#define	PTR_L		lw
339090d85fimp#define	PTR_LA		la
3405605409jmallett#define	PTR_LI		li
341090d85fimp#define	PTR_S		sw
342090d85fimp#define	PTR_SLL		sll
343090d85fimp#define	PTR_SLLV	sllv
344090d85fimp#define	PTR_SRL		srl
345090d85fimp#define	PTR_SRLV	srlv
346090d85fimp#define	PTR_SRA		sra
347090d85fimp#define	PTR_SRAV	srav
348090d85fimp#define	PTR_LL		ll
349090d85fimp#define	PTR_SC		sc
350090d85fimp#define	PTR_WORD	.word
351090d85fimp#define	PTR_SCALESHIFT	2
352090d85fimp#else /* _MIPS_SZPTR == 64 */
353090d85fimp#define	PTR_ADD		dadd
354