1129198Scognet/*	$NetBSD: asm.h,v 1.5 2003/08/07 16:26:53 agc Exp $	*/
2129198Scognet
3139735Simp/*-
4129198Scognet * Copyright (c) 1990 The Regents of the University of California.
5129198Scognet * All rights reserved.
6129198Scognet *
7129198Scognet * This code is derived from software contributed to Berkeley by
8129198Scognet * William Jolitz.
9129198Scognet *
10129198Scognet * Redistribution and use in source and binary forms, with or without
11129198Scognet * modification, are permitted provided that the following conditions
12129198Scognet * are met:
13129198Scognet * 1. Redistributions of source code must retain the above copyright
14129198Scognet *    notice, this list of conditions and the following disclaimer.
15129198Scognet * 2. Redistributions in binary form must reproduce the above copyright
16129198Scognet *    notice, this list of conditions and the following disclaimer in the
17129198Scognet *    documentation and/or other materials provided with the distribution.
18129198Scognet * 3. Neither the name of the University nor the names of its contributors
19129198Scognet *    may be used to endorse or promote products derived from this software
20129198Scognet *    without specific prior written permission.
21129198Scognet *
22129198Scognet * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23129198Scognet * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24129198Scognet * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25129198Scognet * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26129198Scognet * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27129198Scognet * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28129198Scognet * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32129198Scognet * SUCH DAMAGE.
33129198Scognet *
34129198Scognet *	from: @(#)asm.h	5.5 (Berkeley) 5/7/91
35129198Scognet *
36129198Scognet * $FreeBSD$
37129198Scognet */
38129198Scognet
39129198Scognet#ifndef _MACHINE_ASM_H_
40129198Scognet#define _MACHINE_ASM_H_
41129198Scognet#include <sys/cdefs.h>
42129198Scognet
43251510Sandrew#define	_C_LABEL(x)	x
44129198Scognet#define	_ASM_LABEL(x)	x
45129198Scognet
46129198Scognet#define I32_bit (1 << 7)	/* IRQ disable */
47129198Scognet#define F32_bit (1 << 6)        /* FIQ disable */
48129198Scognet
49129198Scognet#define CPU_CONTROL_32BP_ENABLE 0x00000010 /* P: 32-bit exception handlers */
50129198Scognet#define CPU_CONTROL_32BD_ENABLE 0x00000020 /* D: 32-bit addressing */
51129198Scognet
52129198Scognet#ifndef _ALIGN_TEXT
53129198Scognet# define _ALIGN_TEXT .align 0
54129198Scognet#endif
55129198Scognet
56271337Sian#if defined(__ARM_EABI__) && !defined(_STANDALONE)
57248361Sandrew#define	STOP_UNWINDING	.cantunwind
58248361Sandrew#define	_FNSTART	.fnstart
59248361Sandrew#define	_FNEND		.fnend
60248361Sandrew#else
61248361Sandrew#define	STOP_UNWINDING
62248361Sandrew#define	_FNSTART
63248361Sandrew#define	_FNEND
64248361Sandrew#endif
65248361Sandrew
66129198Scognet/*
67129198Scognet * gas/arm uses @ as a single comment character and thus cannot be used here
68129198Scognet * Instead it recognised the # instead of an @ symbols in .type directives
69251510Sandrew * We define a couple of macros so that assembly code will not be dependent
70129198Scognet * on one or the other.
71129198Scognet */
72129198Scognet#define _ASM_TYPE_FUNCTION	#function
73129198Scognet#define _ASM_TYPE_OBJECT	#object
74129198Scognet#define GLOBAL(X) .globl x
75129198Scognet#define _ENTRY(x) \
76248361Sandrew	.text; _ALIGN_TEXT; .globl x; .type x,_ASM_TYPE_FUNCTION; x: _FNSTART
77251510Sandrew#define	_END(x)	.size x, . - x; _FNEND
78248361Sandrew
79269796Sian/*
80269796Sian * EENTRY()/EEND() mark "extra" entry/exit points from a function.
81269796Sian * The unwind info cannot handle the concept of a nested function, or a function
82269796Sian * with multiple .fnstart directives, but some of our assembler code is written
83269796Sian * with multiple labels to allow entry at several points.  The EENTRY() macro
84269796Sian * defines such an extra entry point without a new .fnstart, so that it's
85269796Sian * basically just a label that you can jump to.  The EEND() macro does nothing
86269796Sian * at all, except document the exit point associated with the same-named entry.
87269796Sian */
88269796Sian#define _EENTRY(x) 	.globl x; .type x,_ASM_TYPE_FUNCTION; x:
89269796Sian#define _EEND(x)	/* nothing */
90269796Sian
91129198Scognet#ifdef GPROF
92129198Scognet#  define _PROF_PROLOGUE	\
93169768Scognet	mov ip, lr; bl __mcount
94129198Scognet#else
95129198Scognet# define _PROF_PROLOGUE
96129198Scognet#endif
97129198Scognet
98129198Scognet#define	ENTRY(y)	_ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
99269796Sian#define	EENTRY(y)	_EENTRY(_C_LABEL(y)); _PROF_PROLOGUE
100129198Scognet#define	ENTRY_NP(y)	_ENTRY(_C_LABEL(y))
101269796Sian#define	EENTRY_NP(y)	_EENTRY(_C_LABEL(y))
102251510Sandrew#define	END(y)		_END(_C_LABEL(y))
103269796Sian#define	EEND(y)
104129198Scognet#define	ASENTRY(y)	_ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
105269796Sian#define	ASEENTRY(y)	_EENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
106129198Scognet#define	ASENTRY_NP(y)	_ENTRY(_ASM_LABEL(y))
107269796Sian#define	ASEENTRY_NP(y)	_EENTRY(_ASM_LABEL(y))
108251510Sandrew#define	ASEND(y)	_END(_ASM_LABEL(y))
109269796Sian#define	ASEEND(y)
110129198Scognet
111129198Scognet#define	ASMSTR		.asciz
112129198Scognet
113251510Sandrew#if defined(PIC)
114251510Sandrew#define	PLT_SYM(x)	PIC_SYM(x, PLT)
115251510Sandrew#define	GOT_SYM(x)	PIC_SYM(x, GOT)
116251510Sandrew#define	GOT_GET(x,got,sym)	\
117251510Sandrew	ldr	x, sym;		\
118251510Sandrew	ldr	x, [x, got]
119251510Sandrew#define	GOT_INIT(got,gotsym,pclabel) \
120251510Sandrew	ldr	got, gotsym;	\
121251510Sandrew	add	got, got, pc;	\
122251510Sandrew	pclabel:
123251510Sandrew#define	GOT_INITSYM(gotsym,pclabel) \
124251510Sandrew	gotsym: .word _C_LABEL(_GLOBAL_OFFSET_TABLE_) + (. - (pclabel+4))
125251510Sandrew
126129198Scognet#ifdef __STDC__
127129198Scognet#define	PIC_SYM(x,y)	x ## ( ## y ## )
128129198Scognet#else
129129198Scognet#define	PIC_SYM(x,y)	x/**/(/**/y/**/)
130129198Scognet#endif
131251510Sandrew
132129198Scognet#else
133251510Sandrew#define	PLT_SYM(x)	x
134251510Sandrew#define	GOT_SYM(x)	x
135251510Sandrew#define	GOT_GET(x,got,sym)	\
136251510Sandrew	ldr	x, sym;
137251510Sandrew#define	GOT_INIT(got,gotsym,pclabel)
138251510Sandrew#define	GOT_INITSYM(gotsym,pclabel)
139129198Scognet#define	PIC_SYM(x,y)	x
140251510Sandrew#endif	/* PIC */
141129198Scognet
142129198Scognet#undef __FBSDID
143129198Scognet#if !defined(lint) && !defined(STRIP_FBSDID)
144129198Scognet#define __FBSDID(s)     .ident s
145129198Scognet#else
146129198Scognet#define __FBSDID(s)     /* nothing */
147129198Scognet#endif
148129198Scognet
149129198Scognet
150129198Scognet#define	WEAK_ALIAS(alias,sym)						\
151129198Scognet	.weak alias;							\
152129198Scognet	alias = sym
153129198Scognet
154129198Scognet#ifdef __STDC__
155129198Scognet#define	WARN_REFERENCES(sym,msg)					\
156129198Scognet	.stabs msg ## ,30,0,0,0 ;					\
157129198Scognet	.stabs __STRING(_C_LABEL(sym)) ## ,1,0,0,0
158251510Sandrew#else
159129198Scognet#define	WARN_REFERENCES(sym,msg)					\
160129198Scognet	.stabs msg,30,0,0,0 ;						\
161129198Scognet	.stabs __STRING(sym),1,0,0,0
162129198Scognet#endif /* __STDC__ */
163129198Scognet
164239268Sgonzo/* Exactly one of the __ARM_ARCH_*__ macros will be defined by the compiler. */
165239268Sgonzo/* The _ARM_ARCH_* macros are deprecated and will be removed soon. */
166239268Sgonzo/* This should be moved into another header so it can be used in
167239268Sgonzo * both asm and C code. machine/asm.h cannot be included in C code. */
168239268Sgonzo#if defined (__ARM_ARCH_7__) || defined (__ARM_ARCH_7A__)
169239268Sgonzo#define _ARM_ARCH_7
170239268Sgonzo#define _HAVE_ARMv7_INSTRUCTIONS 1
171239268Sgonzo#endif
172137462Scognet
173239268Sgonzo#if defined (_HAVE_ARMv7_INSTRUCTIONS) || defined (__ARM_ARCH_6__) || \
174239268Sgonzo	defined (__ARM_ARCH_6J__) || defined (__ARM_ARCH_6K__) || \
175239268Sgonzo	defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6ZK__)
176137462Scognet#define _ARM_ARCH_6
177239268Sgonzo#define _HAVE_ARMv6_INSTRUCTIONS 1
178137462Scognet#endif
179137462Scognet
180239268Sgonzo#if defined (_HAVE_ARMv6_INSTRUCTIONS) || defined (__ARM_ARCH_5TE__) || \
181172613Scognet    defined (__ARM_ARCH_5TEJ__) || defined (__ARM_ARCH_5E__)
182239268Sgonzo#define _ARM_ARCH_5E
183239268Sgonzo#define _HAVE_ARMv5E_INSTRUCTIONS 1
184137462Scognet#endif
185137462Scognet
186239268Sgonzo#if defined (_HAVE_ARMv5E_INSTRUCTIONS) || defined (__ARM_ARCH_5__) || \
187239268Sgonzo    defined (__ARM_ARCH_5T__)
188239268Sgonzo#define _ARM_ARCH_5
189239268Sgonzo#define _HAVE_ARMv5_INSTRUCTIONS 1
190172613Scognet#endif
191172613Scognet
192239268Sgonzo#if defined (_HAVE_ARMv5_INSTRUCTIONS) || defined (__ARM_ARCH_4T__)
193137462Scognet#define _ARM_ARCH_4T
194239268Sgonzo#define _HAVE_ARMv4T_INSTRUCTIONS 1
195137462Scognet#endif
196137462Scognet
197239268Sgonzo/* FreeBSD requires ARMv4, so this is always set. */
198239268Sgonzo#define _HAVE_ARMv4_INSTRUCTIONS 1
199137462Scognet
200239268Sgonzo#if defined (_HAVE_ARMv4T_INSTRUCTIONS)
201137462Scognet# define RET	bx	lr
202137462Scognet# define RETeq	bxeq	lr
203137462Scognet# define RETne	bxne	lr
204239268Sgonzo# define RETc(c) bx##c	lr
205137462Scognet#else
206137462Scognet# define RET	mov	pc, lr
207137462Scognet# define RETeq	moveq	pc, lr
208137462Scognet# define RETne	movne	pc, lr
209239268Sgonzo# define RETc(c) mov##c	pc, lr
210137462Scognet#endif
211137462Scognet
212129198Scognet#endif /* !_MACHINE_ASM_H_ */
213