1 /* $NetBSD: asm.h,v 1.11 2025/01/06 10:46:43 martin 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 #ifndef _RISCV_ASM_H 33 #define _RISCV_ASM_H 34 35 #define _C_LABEL(x) x 36 37 #define __CONCAT(x,y) x ## y 38 #define __STRING(x) #x 39 40 #define ___CONCAT(x,y) __CONCAT(x,y) 41 42 /* 43 * Define -pg profile entry code. 44 * Must always be noreorder, must never use a macro instruction 45 * Final addiu to t9 must always equal the size of this _KERN_MCOUNT 46 */ 47 #define _KERN_MCOUNT \ 48 .set push; \ 49 subi sp, sp, CALLFRAME_SIZE; \ 50 REG_S a0, CALLFRAME_S0(sp); \ 51 REG_S ra, CALLFRAME_RA(sp); \ 52 move a0, ra; \ 53 call _mcount \ 54 REG_L ra, CALLFRAME_RA(sp); \ 55 REG_L a0, CALLFRAME_S0(sp); \ 56 addi sp, sp, CALLFRAME_SIZ; \ 57 .set pop; 58 59 #ifdef GPROF 60 #define _PROF_PROLOGUE _KERN_MCOUNT 61 #else 62 #define _PROF_PROLOGUE 63 #endif 64 65 #ifdef __PIC__ 66 #define PLT(x) x##@plt 67 #else 68 #define PLT(x) x 69 #endif 70 71 /* 72 * WEAK_ALIAS: create a weak alias. 73 */ 74 #define WEAK_ALIAS(alias,sym) \ 75 .weak alias; \ 76 alias = sym 77 /* 78 * STRONG_ALIAS: create a strong alias. 79 */ 80 #define STRONG_ALIAS(alias,sym) \ 81 .globl alias; \ 82 alias = sym 83 84 /* 85 * WARN_REFERENCES: create a warning if the specified symbol is referenced. 86 */ 87 #define WARN_REFERENCES(sym,msg) \ 88 .pushsection __CONCAT(.gnu.warning.,sym); \ 89 .ascii msg; \ 90 .popsection 91 92 #define _ENTRY(x) \ 93 .globl _C_LABEL(x); \ 94 .type _C_LABEL(x), @function; \ 95 _C_LABEL(x): 96 97 #define ENTRY_NP(x) .text; .align 2; _ENTRY(x) 98 #define ENTRY(x) ENTRY_NP(x); _PROF_PROLOGUE 99 #define ALTENTRY(x) _ENTRY(x) 100 #define END(x) .size _C_LABEL(x), . - _C_LABEL(x) 101 102 /* 103 * Macros to panic and printf from assembly language. 104 */ 105 #define PANIC(msg) \ 106 la a0, 9f; \ 107 call _C_LABEL(panic); \ 108 MSG(msg) 109 110 #define PRINTF(msg) \ 111 la a0, 9f; \ 112 call _C_LABEL(printf); \ 113 MSG(msg) 114 115 #define MSG(msg) \ 116 .pushsection .rodata.str1.8,"aMS",@progbits,1; \ 117 9: .asciiz msg; \ 118 .popsection 119 120 #define ASMSTR(str) \ 121 .asciiz str; \ 122 .align 3 123 124 #ifdef _NETBSD_REVISIONID 125 #define __RCSID(x) .pushsection ".ident","MS",@progbits,1; \ 126 .asciz x; \ 127 .ascii "$"; .ascii "NetBSD: "; .ascii __FILE__; \ 128 .ascii " "; .ascii _NETBSD_REVISIONID; \ 129 .asciz " $"; \ 130 .popsection 131 #else 132 #define __RCSID(x) .pushsection ".ident","MS",@progbits,1; \ 133 .asciz x; \ 134 .popsection 135 #endif 136 #define RCSID(name) __RCSID(name) 137 138 #if defined(_LP64) 139 #define SZREG 8 140 #else 141 #define SZREG 4 142 #endif 143 144 #define ALSK 15 /* stack alignment */ 145 #define ALMASK -15 /* stack alignment */ 146 #define SZFPREG 8 147 #define FP_L fld 148 #define FP_S fsd 149 150 /* 151 * standard callframe { 152 * register_t cf_sp; frame pointer 153 * register_t cf_ra; return address 154 * }; 155 */ 156 #define CALLFRAME_SIZ (SZREG * 4) 157 #define CALLFRAME_S1 (CALLFRAME_SIZ - 4 * SZREG) 158 #define CALLFRAME_S0 (CALLFRAME_SIZ - 3 * SZREG) 159 #define CALLFRAME_SP (CALLFRAME_SIZ - 2 * SZREG) 160 #define CALLFRAME_RA (CALLFRAME_SIZ - 1 * SZREG) 161 162 /* 163 * These macros hide the use of rv32 and rv64 instructions from the 164 * assembler to prevent the assembler from generating 64-bit style 165 * ABI calls. 166 */ 167 #define PTR_ADD add 168 #define PTR_ADDI addi 169 #define PTR_SUB sub 170 #define PTR_SUBI subi 171 #define PTR_LA la 172 #define PTR_SLLI slli 173 #define PTR_SLL sll 174 #define PTR_SRLI srli 175 #define PTR_SRL srl 176 #define PTR_SRAI srai 177 #define PTR_SRA sra 178 #if _LP64 179 #define PTR_L ld 180 #define PTR_S sd 181 #define PTR_LR lr.d 182 #define PTR_SC sc.d 183 #define PTR_WORD .dword 184 #define PTR_SCALESHIFT 3 185 #else 186 #define PTR_L lw 187 #define PTR_S sw 188 #define PTR_LR lr.w 189 #define PTR_SC sc.w 190 #define PTR_WORD .word 191 #define PTR_SCALESHIFT 2 192 #endif 193 194 #define INT_L lw 195 #define INT_LA la 196 #define INT_S sw 197 #define INT_LR lr.w 198 #define INT_SC sc.w 199 #define INT_WORD .word 200 #define INT_SCALESHIFT 2 201 #ifdef _LP64 202 #define INT_ADD addw 203 #define INT_ADDI addwi 204 #define INT_SUB subw 205 #define INT_SUBI subwi 206 #define INT_SLL sllwi 207 #define INT_SLLV sllw 208 #define INT_SRL srlwi 209 #define INT_SRLV srlw 210 #define INT_SRA srawi 211 #define INT_SRAV sraw 212 #else 213 #define INT_ADD add 214 #define INT_ADDI addi 215 #define INT_SUB sub 216 #define INT_SUBI subi 217 #define INT_SLLI slli 218 #define INT_SLL sll 219 #define INT_SRLI srli 220 #define INT_SRL srl 221 #define INT_SRAI srai 222 #define INT_SRA sra 223 #endif 224 225 #define LONG_LA la 226 #define LONG_ADD add 227 #define LONG_ADDI addi 228 #define LONG_SUB sub 229 #define LONG_SUBI subi 230 #define LONG_SLLI slli 231 #define LONG_SLL sll 232 #define LONG_SRLI srli 233 #define LONG_SRL srl 234 #define LONG_SRAI srai 235 #define LONG_SRA sra 236 #ifdef _LP64 237 #define LONG_L ld 238 #define LONG_S sd 239 #define LONG_LR lr.d 240 #define LONG_SC sc.d 241 #define LONG_WORD .quad 242 #define LONG_SCALESHIFT 3 243 #else 244 #define LONG_L lw 245 #define LONG_S sw 246 #define LONG_LR lr.w 247 #define LONG_SC sc.w 248 #define LONG_WORD .word 249 #define LONG_SCALESHIFT 2 250 #endif 251 252 #define REG_LI li 253 #define REG_ADD add 254 #define REG_SLLI slli 255 #define REG_SLL sll 256 #define REG_SRLI srli 257 #define REG_SRL srl 258 #define REG_SRAI srai 259 #define REG_SRA sra 260 #if _LP64 261 #define REG_L ld 262 #define REG_S sd 263 #define REG_LR lr.d 264 #define REG_SC sc.d 265 #define REG_SCALESHIFT 3 266 #else 267 #define REG_L lw 268 #define REG_S sw 269 #define REG_LR lr.w 270 #define REG_SC sc.w 271 #define REG_SCALESHIFT 2 272 #endif 273 274 #define CPUVAR(off) _C_LABEL(cpu_info_store)+__CONCAT(CPU_INFO_,off) 275 276 #endif /* _RISCV_ASM_H */ 277