1 /* $NetBSD: asm.h,v 1.35 2024/06/09 22:35:47 riastradh 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 /* 228 * Annoyingly, gas on arm seems to generate _two_ NUL-terminated 229 * strings for 230 * 231 * .asciz "foo" "bar" 232 * 233 * instead of concatenating it into a single NUL-terminated string as 234 * on other architectures. 235 * 236 * To work around this, we concatenate into a single NUL-terminated by: 237 * 238 * .ascii "foo" 239 * .asciz "bar" 240 */ 241 #define _IDENTSTR(x) .pushsection ".ident","MS",%progbits,1; \ 242 x; \ 243 .popsection 244 245 #ifdef _NETBSD_REVISIONID 246 #define RCSID(_s) \ 247 _IDENTSTR(.asciz _s); \ 248 _IDENTSTR(.ascii "$"; .ascii "NetBSD: "; .ascii __FILE__; \ 249 .ascii " "; .ascii _NETBSD_REVISIONID; .asciz " $") 250 #else 251 #define RCSID(_s) _IDENTSTR(.asciz _s) 252 #endif 253 254 #define WEAK_ALIAS(alias,sym) \ 255 .weak alias; \ 256 alias = sym 257 258 /* 259 * STRONG_ALIAS: create a strong alias. 260 */ 261 #define STRONG_ALIAS(alias,sym) \ 262 .globl alias; \ 263 alias = sym 264 265 #ifdef __STDC__ 266 #define WARN_REFERENCES(sym,msg) \ 267 .pushsection .gnu.warning. ## sym; \ 268 .ascii msg; \ 269 .popsection 270 #else 271 #define WARN_REFERENCES(sym,msg) \ 272 .pushsection .gnu.warning./**/sym; \ 273 .ascii msg; \ 274 .popsection 275 #endif /* __STDC__ */ 276 277 #ifdef __thumb__ 278 # define XPUSH push 279 # define XPOP pop 280 # define XPOPRET pop {pc} 281 #else 282 # define XPUSH stmfd sp!, 283 # define XPOP ldmfd sp!, 284 # ifdef _ARM_ARCH_5 285 # define XPOPRET ldmfd sp!, {pc} 286 # else 287 # define XPOPRET ldmfd sp!, {lr}; mov pc, lr 288 # endif 289 #endif 290 291 #if defined(__aarch64__) 292 # define RET ret 293 #elif defined (_ARM_ARCH_4T) 294 # define RET bx lr 295 # define RETr(r) bx r 296 # if defined(__thumb__) 297 # if defined(_ARM_ARCH_7) 298 # define RETc(c) it c; __CONCAT(bx,c) lr 299 # endif 300 # else 301 # define RETc(c) __CONCAT(bx,c) lr 302 # endif 303 #else 304 # define RET mov pc, lr 305 # define RETr(r) mov pc, r 306 # define RETc(c) __CONCAT(mov,c) pc, lr 307 #endif 308 309 #ifdef _ARM_ARCH_7 310 #define KMODTRAMPOLINE(n) \ 311 _ENTRY(__wrap_ ## n) \ 312 movw ip, #:lower16:n; \ 313 movt ip, #:upper16:n; \ 314 bx ip 315 #elif defined(_ARM_ARCH_4T) 316 #define KMODTRAMPOLINE(n) \ 317 _ENTRY(__wrap_ ## n) \ 318 ldr ip, [pc]; \ 319 bx ip; \ 320 .word n 321 #else 322 #define KMODTRAMPOLINE(n) \ 323 _ENTRY(__wrap_ ## n) \ 324 ldr pc, [pc, #-4]; \ 325 .word n 326 #endif 327 328 #endif /* !_ARM_ASM_H_ */ 329