1/*	$NetBSD: asm.h,v 1.34 2020/04/23 23:22:41 jakllsch Exp $	*/
  2
  3/*-
  4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
  5 * All rights reserved.
  6 *
  7 * This code is derived from software contributed to The NetBSD Foundation
  8 * by Matt Thomas of 3am Software Foundry.
  9 *
 10 * Redistribution and use in source and binary forms, with or without
 11 * modification, are permitted provided that the following conditions
 12 * are met:
 13 * 1. Redistributions of source code must retain the above copyright
 14 *    notice, this list of conditions and the following disclaimer.
 15 * 2. Redistributions in binary form must reproduce the above copyright
 16 *    notice, this list of conditions and the following disclaimer in the
 17 *    documentation and/or other materials provided with the distribution.
 18 *
 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 29 * POSSIBILITY OF SUCH DAMAGE.
 30 */
 31
 32/*
 33 * Copyright (c) 1990 The Regents of the University of California.
 34 * All rights reserved.
 35 *
 36 * This code is derived from software contributed to Berkeley by
 37 * William Jolitz.
 38 *
 39 * Redistribution and use in source and binary forms, with or without
 40 * modification, are permitted provided that the following conditions
 41 * are met:
 42 * 1. Redistributions of source code must retain the above copyright
 43 *    notice, this list of conditions and the following disclaimer.
 44 * 2. Redistributions in binary form must reproduce the above copyright
 45 *    notice, this list of conditions and the following disclaimer in the
 46 *    documentation and/or other materials provided with the distribution.
 47 * 3. Neither the name of the University nor the names of its contributors
 48 *    may be used to endorse or promote products derived from this software
 49 *    without specific prior written permission.
 50 *
 51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 54 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 61 * SUCH DAMAGE.
 62 *
 63 *	from: @(#)asm.h	5.5 (Berkeley) 5/7/91
 64 */
 65
 66#ifndef _ARM_ASM_H_
 67#define _ARM_ASM_H_
 68
 69#include <arm/cdefs.h>
 70#if defined(_KERNEL_OPT)
 71#include "opt_cpuoptions.h"
 72#endif
 73
 74#ifdef __thumb__
 75#define THUMB_INSN(n)	n
 76#else
 77#define THUMB_INSN(n)
 78#endif
 79
 80#define	__BIT(n)	(1 << (n))
 81#define __BITS(hi,lo)	((~((~0)<<((hi)+1)))&((~0)<<(lo)))
 82
 83#define __LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask))
 84#define __SHIFTOUT(__x, __mask) (((__x) & (__mask)) / __LOWEST_SET_BIT(__mask))
 85#define __SHIFTIN(__x, __mask) ((__x) * __LOWEST_SET_BIT(__mask))
 86
 87#define _C_LABEL(x)	x
 88#define	_ASM_LABEL(x)	x
 89
 90#ifdef __STDC__
 91# define __CONCAT(x,y)	x ## y
 92# define __STRING(x)	#x
 93#else
 94# define __CONCAT(x,y)	x/**/y
 95# define __STRING(x)	"x"
 96#endif
 97
 98#ifndef _ALIGN_TEXT
 99# define _ALIGN_TEXT .align 2
100#endif
101
102#ifndef _TEXT_SECTION
103#define _TEXT_SECTION	.text
104#endif
105
106#ifdef __arm__
107
108	.syntax		unified
109
110/*
111 * gas/arm uses @ as a single comment character and thus cannot be used here
112 * Instead it recognised the # instead of an @ symbols in .type directives
113 * We define a couple of macros so that assembly code will not be dependent
114 * on one or the other.
115 */
116#define _ASM_TYPE_FUNCTION	%function
117#define _ASM_TYPE_OBJECT	%object
118#define _THUMB_ENTRY(x) \
119	_TEXT_SECTION; _ALIGN_TEXT; .globl x; .type x,_ASM_TYPE_FUNCTION; \
120	.thumb_func; .code 16; x:
121#define _ARM_ENTRY(x) \
122	_TEXT_SECTION; _ALIGN_TEXT; .globl x; .type x,_ASM_TYPE_FUNCTION; \
123	.code 32; x:
124#ifdef __thumb__
125#define	_ENTRY(x)	_THUMB_ENTRY(x)
126#else
127#define	_ENTRY(x)	_ARM_ENTRY(x)
128#endif
129#define	_END(x)		.size x,.-x
130
131#ifdef GPROF
132# define _PROF_PROLOGUE	\
133	mov ip, lr; bl __mcount
134#else
135# define _PROF_PROLOGUE
136#endif
137#endif
138
139#ifdef __aarch64__
140#define _ASM_TYPE_FUNCTION	@function
141#define _ASM_TYPE_OBJECT	@object
142#define _ENTRY(x) \
143	_TEXT_SECTION; _ALIGN_TEXT; .globl x; .type x,_ASM_TYPE_FUNCTION; x:
144#define	_END(x)		.size x,.-x
145
146#ifdef GPROF
147# define _PROF_PROLOGUE	\
148	stp	x29, x30, [sp, #-16]!;	\
149	mov	fp, sp;			\
150	bl	__mcount; 		\
151	ldp	x29, x30, [sp], #16;
152#else
153# define _PROF_PROLOGUE
154#endif
155
156#ifdef __PIC__
157#define GOTREF(x)		:got:x
158#define GOTLO12(x)		:got_lo12:x
159#else
160#define GOTREF(x)		x
161#define GOTLO12(x)		:lo12:x
162#endif
163#endif
164
165#ifdef ARMV85_BTI
166#define	_BTI_PROLOGUE \
167	.byte	0x5F, 0x24, 0x03, 0xD5	/* the "bti c" instruction */
168#else
169#define	_BTI_PROLOGUE		/* nothing */
170#endif
171
172#define	ENTRY(y)		_ENTRY(_C_LABEL(y)); _BTI_PROLOGUE ; _PROF_PROLOGUE
173#define	ENTRY_NP(y)		_ENTRY(_C_LABEL(y)); _BTI_PROLOGUE
174#define	ENTRY_NBTI(y)		_ENTRY(_C_LABEL(y))
175#define	END(y)			_END(_C_LABEL(y))
176#define	ARM_ENTRY(y)		_ARM_ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
177#define	ARM_ENTRY_NP(y)		_ARM_ENTRY(_C_LABEL(y))
178#define	THUMB_ENTRY(y)		_THUMB_ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
179#define	THUMB_ENTRY_NP(y)	_THUMB_ENTRY(_C_LABEL(y))
180#define	ASENTRY(y)		_ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
181#define	ASENTRY_NP(y)		_ENTRY(_ASM_LABEL(y))
182#define	ASEND(y)		_END(_ASM_LABEL(y))
183#define	ARM_ASENTRY(y)		_ARM_ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
184#define	ARM_ASENTRY_NP(y)	_ARM_ENTRY(_ASM_LABEL(y))
185#define	THUMB_ASENTRY(y)	_THUMB_ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
186#define	THUMB_ASENTRY_NP(y)	_THUMB_ENTRY(_ASM_LABEL(y))
187
188#define	ASMSTR		.asciz
189
190#ifdef __PIC__
191#define	REL_SYM(a, b)	((a) - (b))
192#define	PLT_SYM(x)	x
193#define	GOT_SYM(x)	PIC_SYM(x, GOT)
194#define	GOT_GET(x,got,sym)	\
195	ldr	x, sym;		\
196	ldr	x, [x, got]
197#define	GOT_INIT(got,gotsym,pclabel) \
198	ldr	got, gotsym;	\
199	pclabel: add	got, got, pc
200#ifdef __thumb__
201#define	GOT_INITSYM(gotsym,pclabel) \
202	.align 0;		\
203	gotsym: .word _C_LABEL(_GLOBAL_OFFSET_TABLE_) - (pclabel+4)
204#else
205#define	GOT_INITSYM(gotsym,pclabel) \
206	.align 0;		\
207	gotsym: .word _C_LABEL(_GLOBAL_OFFSET_TABLE_) - (pclabel+8)
208#endif
209
210#ifdef __STDC__
211#define	PIC_SYM(x,y)	x ## ( ## y ## )
212#else
213#define	PIC_SYM(x,y)	x/**/(/**/y/**/)
214#endif
215
216#else
217#define	REL_SYM(a, b)	(a)
218#define	PLT_SYM(x)	x
219#define	GOT_SYM(x)	x
220#define	GOT_GET(x,got,sym)	\
221	ldr	x, sym;
222#define	GOT_INIT(got,gotsym,pclabel)
223#define	GOT_INITSYM(gotsym,pclabel)
224#define	PIC_SYM(x,y)	x
225#endif	/* __PIC__ */
226
227#define RCSID(x)	.pushsection ".ident","MS",%progbits,1;		\
228			.asciz x;					\
229			.popsection
230
231#define	WEAK_ALIAS(alias,sym)						\
232	.weak alias;							\
233	alias = sym
234
235/*
236 * STRONG_ALIAS: create a strong alias.
237 */
238#define STRONG_ALIAS(alias,sym)						\
239	.globl alias;							\
240	alias = sym
241
242#ifdef __STDC__
243#define	WARN_REFERENCES(sym,msg)					\
244	.pushsection .gnu.warning. ## sym;				\
245	.ascii msg;							\
246	.popsection
247#else
248#define	WARN_REFERENCES(sym,msg)					\
249	.pushsection .gnu.warning./**/sym;				\
250	.ascii msg;							\
251	.popsection
252#endif /* __STDC__ */
253
254#ifdef __thumb__
255# define XPUSH		push
256# define XPOP		pop
257# define XPOPRET	pop	{pc}
258#else
259# define XPUSH		stmfd	sp!,
260# define XPOP		ldmfd	sp!,
261# ifdef _ARM_ARCH_5
262#  define XPOPRET	ldmfd	sp!, {pc}
263# else
264#  define XPOPRET	ldmfd	sp!, {lr}; mov pc, lr
265# endif
266#endif
267
268#if defined(__aarch64__)
269# define RET		ret
270#elif defined (_ARM_ARCH_4T)
271# define RET		bx		lr
272# define RETr(r)	bx		r
273# if defined(__thumb__)
274#  if defined(_ARM_ARCH_7)
275#   define RETc(c)	it c; __CONCAT(bx,c)	lr
276#  endif
277# else
278#  define RETc(c)	__CONCAT(bx,c)	lr
279# endif
280#else
281# define RET		mov		pc, lr
282# define RETr(r)	mov		pc, r
283# define RETc(c)	__CONCAT(mov,c)	pc, lr
284#endif
285
286#ifdef _ARM_ARCH_7
287#define KMODTRAMPOLINE(n)			\
288_ENTRY(__wrap_ ## n)				\
289	movw	ip, #:lower16:n;	\
290	movt	ip, #:upper16:n;	\
291	bx	ip
292#elif defined(_ARM_ARCH_4T)
293#define KMODTRAMPOLINE(n)	\
294_ENTRY(__wrap_ ## n)		\
295	ldr	ip, [pc];	\
296	bx	ip;		\
297	.word	n
298#else
299#define KMODTRAMPOLINE(n)	\
300_ENTRY(__wrap_ ## n)		\
301	ldr	pc, [pc, #-4];	\
302	.word	n
303#endif
304
305#endif /* !_ARM_ASM_H_ */