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_ */ 306