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