1a9643ea8Slogwang /* $NetBSD: asm.h,v 1.5 2003/08/07 16:26:53 agc Exp $ */ 2a9643ea8Slogwang 3a9643ea8Slogwang /*- 4*22ce4affSfengbojiang * SPDX-License-Identifier: BSD-3-Clause 5*22ce4affSfengbojiang * 6a9643ea8Slogwang * Copyright (c) 1990 The Regents of the University of California. 7a9643ea8Slogwang * All rights reserved. 8a9643ea8Slogwang * 9a9643ea8Slogwang * This code is derived from software contributed to Berkeley by 10a9643ea8Slogwang * William Jolitz. 11a9643ea8Slogwang * 12a9643ea8Slogwang * Redistribution and use in source and binary forms, with or without 13a9643ea8Slogwang * modification, are permitted provided that the following conditions 14a9643ea8Slogwang * are met: 15a9643ea8Slogwang * 1. Redistributions of source code must retain the above copyright 16a9643ea8Slogwang * notice, this list of conditions and the following disclaimer. 17a9643ea8Slogwang * 2. Redistributions in binary form must reproduce the above copyright 18a9643ea8Slogwang * notice, this list of conditions and the following disclaimer in the 19a9643ea8Slogwang * documentation and/or other materials provided with the distribution. 20a9643ea8Slogwang * 3. Neither the name of the University nor the names of its contributors 21a9643ea8Slogwang * may be used to endorse or promote products derived from this software 22a9643ea8Slogwang * without specific prior written permission. 23a9643ea8Slogwang * 24a9643ea8Slogwang * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25a9643ea8Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26a9643ea8Slogwang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27a9643ea8Slogwang * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28a9643ea8Slogwang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29a9643ea8Slogwang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30a9643ea8Slogwang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31a9643ea8Slogwang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32a9643ea8Slogwang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33a9643ea8Slogwang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34a9643ea8Slogwang * SUCH DAMAGE. 35a9643ea8Slogwang * 36a9643ea8Slogwang * from: @(#)asm.h 5.5 (Berkeley) 5/7/91 37a9643ea8Slogwang * 38a9643ea8Slogwang * $FreeBSD$ 39a9643ea8Slogwang */ 40a9643ea8Slogwang 41a9643ea8Slogwang #ifndef _MACHINE_ASM_H_ 42a9643ea8Slogwang #define _MACHINE_ASM_H_ 43a9643ea8Slogwang #include <sys/cdefs.h> 44a9643ea8Slogwang #include <machine/sysreg.h> 45a9643ea8Slogwang 46a9643ea8Slogwang #define _C_LABEL(x) x 47a9643ea8Slogwang #define _ASM_LABEL(x) x 48a9643ea8Slogwang 49a9643ea8Slogwang #ifndef _ALIGN_TEXT 50a9643ea8Slogwang # define _ALIGN_TEXT .align 2 51a9643ea8Slogwang #endif 52a9643ea8Slogwang 53a9643ea8Slogwang #ifndef _STANDALONE 54a9643ea8Slogwang #define STOP_UNWINDING .cantunwind 55a9643ea8Slogwang #define _FNSTART .fnstart 56a9643ea8Slogwang #define _FNEND .fnend 57a9643ea8Slogwang #define _SAVE(...) .save __VA_ARGS__ 58a9643ea8Slogwang #else 59a9643ea8Slogwang #define STOP_UNWINDING 60a9643ea8Slogwang #define _FNSTART 61a9643ea8Slogwang #define _FNEND 62a9643ea8Slogwang #define _SAVE(...) 63a9643ea8Slogwang #endif 64a9643ea8Slogwang 65a9643ea8Slogwang /* 66a9643ea8Slogwang * gas/arm uses @ as a single comment character and thus cannot be used here. 67a9643ea8Slogwang * It recognises the # instead of an @ symbol in .type directives. 68a9643ea8Slogwang */ 69a9643ea8Slogwang #define _ASM_TYPE_FUNCTION #function 70a9643ea8Slogwang #define _ASM_TYPE_OBJECT #object 71a9643ea8Slogwang 72a9643ea8Slogwang /* XXX Is this still the right prologue for profiling? */ 73a9643ea8Slogwang #ifdef GPROF 74a9643ea8Slogwang #define _PROF_PROLOGUE \ 75a9643ea8Slogwang mov ip, lr; \ 76a9643ea8Slogwang bl __mcount 77a9643ea8Slogwang #else 78a9643ea8Slogwang #define _PROF_PROLOGUE 79a9643ea8Slogwang #endif 80a9643ea8Slogwang 81a9643ea8Slogwang /* 82a9643ea8Slogwang * EENTRY()/EEND() mark "extra" entry/exit points from a function. 83a9643ea8Slogwang * LEENTRY()/LEEND() are the same for local symbols. 84a9643ea8Slogwang * The unwind info cannot handle the concept of a nested function, or a function 85a9643ea8Slogwang * with multiple .fnstart directives, but some of our assembler code is written 86a9643ea8Slogwang * with multiple labels to allow entry at several points. The EENTRY() macro 87a9643ea8Slogwang * defines such an extra entry point without a new .fnstart, so that it's 88a9643ea8Slogwang * basically just a label that you can jump to. The EEND() macro does nothing 89a9643ea8Slogwang * at all, except document the exit point associated with the same-named entry. 90a9643ea8Slogwang */ 91a9643ea8Slogwang #define GLOBAL(x) .global x 92a9643ea8Slogwang 93a9643ea8Slogwang #ifdef __thumb__ 94a9643ea8Slogwang #define _FUNC_MODE .code 16; .thumb_func 95a9643ea8Slogwang #else 96a9643ea8Slogwang #define _FUNC_MODE .code 32 97a9643ea8Slogwang #endif 98a9643ea8Slogwang 99a9643ea8Slogwang #define _LEENTRY(x) .type x,_ASM_TYPE_FUNCTION; _FUNC_MODE; x: 100a9643ea8Slogwang #define _LEEND(x) /* nothing */ 101a9643ea8Slogwang #define _EENTRY(x) GLOBAL(x); _LEENTRY(x) 102a9643ea8Slogwang #define _EEND(x) _LEEND(x) 103a9643ea8Slogwang 104a9643ea8Slogwang #define _LENTRY(x) .text; _ALIGN_TEXT; _LEENTRY(x); _FNSTART 105a9643ea8Slogwang #define _LEND(x) .size x, . - x; _FNEND 106a9643ea8Slogwang #define _ENTRY(x) .text; _ALIGN_TEXT; _EENTRY(x); _FNSTART 107a9643ea8Slogwang #define _END(x) _LEND(x) 108a9643ea8Slogwang 109a9643ea8Slogwang #define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE 110a9643ea8Slogwang #define EENTRY(y) _EENTRY(_C_LABEL(y)); 111a9643ea8Slogwang #define ENTRY_NP(y) _ENTRY(_C_LABEL(y)) 112a9643ea8Slogwang #define EENTRY_NP(y) _EENTRY(_C_LABEL(y)) 113a9643ea8Slogwang #define END(y) _END(_C_LABEL(y)) 114a9643ea8Slogwang #define EEND(y) _EEND(_C_LABEL(y)) 115a9643ea8Slogwang #define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE 116a9643ea8Slogwang #define ASLENTRY(y) _LENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE 117a9643ea8Slogwang #define ASEENTRY(y) _EENTRY(_ASM_LABEL(y)); 118a9643ea8Slogwang #define ASLEENTRY(y) _LEENTRY(_ASM_LABEL(y)); 119a9643ea8Slogwang #define ASENTRY_NP(y) _ENTRY(_ASM_LABEL(y)) 120a9643ea8Slogwang #define ASLENTRY_NP(y) _LENTRY(_ASM_LABEL(y)) 121a9643ea8Slogwang #define ASEENTRY_NP(y) _EENTRY(_ASM_LABEL(y)) 122a9643ea8Slogwang #define ASLEENTRY_NP(y) _LEENTRY(_ASM_LABEL(y)) 123a9643ea8Slogwang #define ASEND(y) _END(_ASM_LABEL(y)) 124a9643ea8Slogwang #define ASLEND(y) _LEND(_ASM_LABEL(y)) 125a9643ea8Slogwang #define ASEEND(y) _EEND(_ASM_LABEL(y)) 126a9643ea8Slogwang #define ASLEEND(y) _LEEND(_ASM_LABEL(y)) 127a9643ea8Slogwang 128a9643ea8Slogwang #define ASMSTR .asciz 129a9643ea8Slogwang 130a9643ea8Slogwang #if defined(PIC) 131a9643ea8Slogwang #define PLT_SYM(x) PIC_SYM(x, PLT) 132a9643ea8Slogwang #define GOT_SYM(x) PIC_SYM(x, GOT) 133a9643ea8Slogwang #define GOT_GET(x,got,sym) \ 134a9643ea8Slogwang ldr x, sym; \ 135a9643ea8Slogwang ldr x, [x, got] 136a9643ea8Slogwang #define GOT_INIT(got,gotsym,pclabel) \ 137a9643ea8Slogwang ldr got, gotsym; \ 138a9643ea8Slogwang pclabel: add got, pc 139a9643ea8Slogwang #ifdef __thumb__ 140a9643ea8Slogwang #define GOT_INITSYM(gotsym,pclabel) \ 141a9643ea8Slogwang .align 2; \ 142a9643ea8Slogwang gotsym: .word _C_LABEL(_GLOBAL_OFFSET_TABLE_) - (pclabel+4) 143a9643ea8Slogwang #else 144a9643ea8Slogwang #define GOT_INITSYM(gotsym,pclabel) \ 145a9643ea8Slogwang .align 2; \ 146a9643ea8Slogwang gotsym: .word _C_LABEL(_GLOBAL_OFFSET_TABLE_) - (pclabel+8) 147a9643ea8Slogwang #endif 148a9643ea8Slogwang 149a9643ea8Slogwang #ifdef __STDC__ 150a9643ea8Slogwang #define PIC_SYM(x,y) x ## ( ## y ## ) 151a9643ea8Slogwang #else 152a9643ea8Slogwang #define PIC_SYM(x,y) x/**/(/**/y/**/) 153a9643ea8Slogwang #endif 154a9643ea8Slogwang 155a9643ea8Slogwang #else 156a9643ea8Slogwang #define PLT_SYM(x) x 157a9643ea8Slogwang #define GOT_SYM(x) x 158a9643ea8Slogwang #define GOT_GET(x,got,sym) \ 159a9643ea8Slogwang ldr x, sym; 160a9643ea8Slogwang #define GOT_INIT(got,gotsym,pclabel) 161a9643ea8Slogwang #define GOT_INITSYM(gotsym,pclabel) 162a9643ea8Slogwang #define PIC_SYM(x,y) x 163a9643ea8Slogwang #endif /* PIC */ 164a9643ea8Slogwang 165a9643ea8Slogwang #undef __FBSDID 166a9643ea8Slogwang #if !defined(lint) && !defined(STRIP_FBSDID) 167a9643ea8Slogwang #define __FBSDID(s) .ident s 168a9643ea8Slogwang #else 169a9643ea8Slogwang #define __FBSDID(s) /* nothing */ 170a9643ea8Slogwang #endif 171a9643ea8Slogwang 172a9643ea8Slogwang #define WEAK_ALIAS(alias,sym) \ 173a9643ea8Slogwang .weak alias; \ 174a9643ea8Slogwang alias = sym 175a9643ea8Slogwang 176a9643ea8Slogwang #ifdef __STDC__ 177a9643ea8Slogwang #define WARN_REFERENCES(sym,msg) \ 178a9643ea8Slogwang .stabs msg ## ,30,0,0,0 ; \ 179a9643ea8Slogwang .stabs __STRING(_C_LABEL(sym)) ## ,1,0,0,0 180a9643ea8Slogwang #else 181a9643ea8Slogwang #define WARN_REFERENCES(sym,msg) \ 182a9643ea8Slogwang .stabs msg,30,0,0,0 ; \ 183a9643ea8Slogwang .stabs __STRING(sym),1,0,0,0 184a9643ea8Slogwang #endif /* __STDC__ */ 185a9643ea8Slogwang 186a9643ea8Slogwang /* Exactly one of the __ARM_ARCH_*__ macros will be defined by the compiler. */ 187a9643ea8Slogwang /* The _ARM_ARCH_* macros are deprecated and will be removed soon. */ 188a9643ea8Slogwang /* This should be moved into another header so it can be used in 189a9643ea8Slogwang * both asm and C code. machine/asm.h cannot be included in C code. */ 190a9643ea8Slogwang #if defined (__ARM_ARCH_7__) || defined (__ARM_ARCH_7A__) 191a9643ea8Slogwang #define _ARM_ARCH_7 192a9643ea8Slogwang #define _HAVE_ARMv7_INSTRUCTIONS 1 193a9643ea8Slogwang #endif 194a9643ea8Slogwang 195a9643ea8Slogwang #if defined (_HAVE_ARMv7_INSTRUCTIONS) || defined (__ARM_ARCH_6__) || \ 196a9643ea8Slogwang defined (__ARM_ARCH_6J__) || defined (__ARM_ARCH_6K__) || \ 197*22ce4affSfengbojiang defined (__ARM_ARCH_6KZ__) || \ 198a9643ea8Slogwang defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6ZK__) 199a9643ea8Slogwang #define _ARM_ARCH_6 200a9643ea8Slogwang #define _HAVE_ARMv6_INSTRUCTIONS 1 201a9643ea8Slogwang #endif 202a9643ea8Slogwang 203a9643ea8Slogwang #if defined (_HAVE_ARMv6_INSTRUCTIONS) || defined (__ARM_ARCH_5TE__) || \ 204a9643ea8Slogwang defined (__ARM_ARCH_5TEJ__) || defined (__ARM_ARCH_5E__) 205a9643ea8Slogwang #define _ARM_ARCH_5E 206a9643ea8Slogwang #define _HAVE_ARMv5E_INSTRUCTIONS 1 207a9643ea8Slogwang #endif 208a9643ea8Slogwang 209a9643ea8Slogwang #if defined (_HAVE_ARMv5E_INSTRUCTIONS) || defined (__ARM_ARCH_5__) || \ 210a9643ea8Slogwang defined (__ARM_ARCH_5T__) 211a9643ea8Slogwang #define _ARM_ARCH_5 212a9643ea8Slogwang #define _HAVE_ARMv5_INSTRUCTIONS 1 213a9643ea8Slogwang #endif 214a9643ea8Slogwang 215a9643ea8Slogwang #if defined (_HAVE_ARMv5_INSTRUCTIONS) || defined (__ARM_ARCH_4T__) 216a9643ea8Slogwang #define _ARM_ARCH_4T 217a9643ea8Slogwang #define _HAVE_ARMv4T_INSTRUCTIONS 1 218a9643ea8Slogwang #endif 219a9643ea8Slogwang 220a9643ea8Slogwang /* FreeBSD requires ARMv4, so this is always set. */ 221a9643ea8Slogwang #define _HAVE_ARMv4_INSTRUCTIONS 1 222a9643ea8Slogwang 223a9643ea8Slogwang #if defined (_HAVE_ARMv4T_INSTRUCTIONS) 224a9643ea8Slogwang # define RET bx lr 225a9643ea8Slogwang # define RETeq bxeq lr 226a9643ea8Slogwang # define RETne bxne lr 227a9643ea8Slogwang # define RETc(c) bx##c lr 228a9643ea8Slogwang #else 229a9643ea8Slogwang # define RET mov pc, lr 230a9643ea8Slogwang # define RETeq moveq pc, lr 231a9643ea8Slogwang # define RETne movne pc, lr 232a9643ea8Slogwang # define RETc(c) mov##c pc, lr 233a9643ea8Slogwang #endif 234a9643ea8Slogwang 235a9643ea8Slogwang #if __ARM_ARCH >= 7 236a9643ea8Slogwang #define ISB isb 237a9643ea8Slogwang #define DSB dsb 238a9643ea8Slogwang #define DMB dmb 239a9643ea8Slogwang #define WFI wfi 240*22ce4affSfengbojiang 241*22ce4affSfengbojiang #if defined(__ARM_ARCH_7VE__) || defined(__clang__) 242*22ce4affSfengbojiang #define MSR_ELR_HYP(regnum) msr elr_hyp, lr 243*22ce4affSfengbojiang #define ERET eret 244*22ce4affSfengbojiang #else 245*22ce4affSfengbojiang #define MSR_ELR_HYP(regnum) .word (0xe12ef300 | regnum) 246*22ce4affSfengbojiang #define ERET .word 0xe160006e 247*22ce4affSfengbojiang #endif 248*22ce4affSfengbojiang 249a9643ea8Slogwang #elif __ARM_ARCH == 6 250a9643ea8Slogwang #define ISB mcr CP15_CP15ISB 251a9643ea8Slogwang #define DSB mcr CP15_CP15DSB 252a9643ea8Slogwang #define DMB mcr CP15_CP15DMB 253a9643ea8Slogwang #define WFI mcr CP15_CP15WFI 254a9643ea8Slogwang #else 255a9643ea8Slogwang #define ISB mcr CP15_CP15ISB 256a9643ea8Slogwang #define DSB mcr CP15_CP15DSB /* DSB and DMB are the */ 257a9643ea8Slogwang #define DMB mcr CP15_CP15DSB /* same prior to v6.*/ 258a9643ea8Slogwang /* No form of WFI available on v4, define nothing to get an error on use. */ 259a9643ea8Slogwang #endif 260a9643ea8Slogwang 261a9643ea8Slogwang #endif /* !_MACHINE_ASM_H_ */ 262