1 /* $OpenBSD: asm.h,v 1.27 2021/05/01 16:11:10 visa Exp $ */ 2 3 /* 4 * Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 #ifndef _MIPS64_ASM_H_ 29 #define _MIPS64_ASM_H_ 30 31 #include <machine/regdef.h> 32 33 #define _MIPS_ISA_MIPS1 1 /* R2000/R3000 */ 34 #define _MIPS_ISA_MIPS2 2 /* R4000/R6000 */ 35 #define _MIPS_ISA_MIPS3 3 /* R4000 */ 36 #define _MIPS_ISA_MIPS4 4 /* TFP (R1x000) */ 37 #define _MIPS_ISA_MIPS32 32 /* MIPS32 */ 38 #define _MIPS_ISA_MIPS64 64 /* MIPS64 */ 39 40 #if !defined(ABICALLS) && !defined(_NO_ABICALLS) 41 #define ABICALLS .abicalls 42 #endif 43 44 #if defined(ABICALLS) && !defined(_KERNEL) 45 ABICALLS 46 #endif 47 48 #define _C_LABEL(x) x /* XXX Obsolete but keep for a while */ 49 50 #if !defined(__MIPSEL__) && !defined(__MIPSEB__) 51 #error "__MIPSEL__ or __MIPSEB__ must be defined" 52 #endif 53 /* 54 * Define how to access unaligned data word 55 */ 56 #if defined(__MIPSEL__) 57 #define LWLO lwl 58 #define LWHI lwr 59 #define SWLO swl 60 #define SWHI swr 61 #define LDLO ldl 62 #define LDHI ldr 63 #define SDLO sdl 64 #define SDHI sdr 65 #endif 66 #if defined(__MIPSEB__) 67 #define LWLO lwr 68 #define LWHI lwl 69 #define SWLO swr 70 #define SWHI swl 71 #define LDLO ldr 72 #define LDHI ldl 73 #define SDLO sdr 74 #define SDHI sdl 75 #endif 76 77 /* 78 * Define programming environment for ABI. 79 */ 80 #if defined(ABICALLS) && !defined(_KERNEL) && !defined(_STANDALONE) 81 82 #ifndef _MIPS_SIM 83 #define _MIPS_SIM 1 84 #define _ABIO32 1 85 #endif 86 #ifndef _MIPS_ISA 87 #define _MIPS_ISA 2 88 #define _MIPS_ISA_MIPS2 2 89 #endif 90 91 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32) 92 #define NARGSAVE 4 93 94 #define SETUP_GP \ 95 .set noreorder; \ 96 .cpload t9; \ 97 .set reorder; 98 99 #define SAVE_GP(x) \ 100 .cprestore x 101 102 #define SETUP_GP64(gpoff, name) 103 #define RESTORE_GP64 104 #endif 105 106 #if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32) 107 #define NARGSAVE 0 108 109 #define SETUP_GP 110 #define SAVE_GP(x) 111 #define SETUP_GP64(gpoff, name) \ 112 .cpsetup t9, gpoff, name 113 #define RESTORE_GP64 \ 114 .cpreturn 115 #endif 116 117 #define MKFSIZ(narg,locals) (((narg+locals)*REGSZ+31)&(~31)) 118 119 #else /* defined(ABICALLS) && !defined(_KERNEL) */ 120 121 #define NARGSAVE 4 122 #define SETUP_GP 123 #define SAVE_GP(x) 124 125 #define ALIGNSZ 16 /* Stack layout alignment */ 126 #define FRAMESZ(sz) (((sz) + (ALIGNSZ-1)) & ~(ALIGNSZ-1)) 127 128 #endif 129 130 /* 131 * Basic register operations based on selected ISA 132 */ 133 #if (_MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || \ 134 _MIPS_ISA == _MIPS_ISA_MIPS32) 135 #define REGSZ 4 /* 32 bit mode register size */ 136 #define LOGREGSZ 2 /* log rsize */ 137 #define REG_S sw 138 #define REG_L lw 139 #define CF_SZ 24 /* Call frame size */ 140 #define CF_ARGSZ 16 /* Call frame arg size */ 141 #define CF_RA_OFFS 20 /* Call ra save offset */ 142 #endif 143 144 #if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || \ 145 _MIPS_ISA == _MIPS_ISA_MIPS64) 146 #define REGSZ 8 /* 64 bit mode register size */ 147 #define LOGREGSZ 3 /* log rsize */ 148 #define REG_S sd 149 #define REG_L ld 150 #define CF_SZ 48 /* Call frame size (multiple of ALIGNSZ) */ 151 #define CF_ARGSZ 32 /* Call frame arg size */ 152 #define CF_RA_OFFS 40 /* Call ra save offset */ 153 #endif 154 155 #ifndef __LP64__ 156 #define PTR_L lw 157 #define PTR_S sw 158 #define PTR_SUB sub 159 #define PTR_ADD add 160 #define PTR_SUBU subu 161 #define PTR_ADDU addu 162 #define LI li 163 #define LA la 164 #define PTR_SLL sll 165 #define PTR_SRL srl 166 #define PTR_VAL .word 167 #else 168 #define PTR_L ld 169 #define PTR_S sd 170 #define PTR_ADD dadd 171 #define PTR_SUB dsub 172 #define PTR_SUBU dsubu 173 #define PTR_ADDU daddu 174 #define LI dli 175 #define LA dla 176 #define PTR_SLL dsll 177 #define PTR_SRL dsrl 178 #define PTR_VAL .dword 179 #endif 180 181 #define NOP nop 182 #define DMFC0 dmfc0 183 #define DMTC0 dmtc0 184 #define MFC0 mfc0 185 #define MTC0 mtc0 186 #define ERET sync; eret 187 188 /* 189 * Define -pg profile entry code. 190 */ 191 #if defined(XGPROF) || defined(XPROF) 192 #define MCOUNT \ 193 PTR_SUBU sp, sp, 64; \ 194 SAVE_GP(16); \ 195 sd ra, 56(sp); \ 196 sd gp, 48(sp); \ 197 .set noat; \ 198 .set noreorder; \ 199 move AT, ra; \ 200 jal _mcount; \ 201 PTR_SUBU sp, sp, 16; \ 202 ld ra, 56(sp); \ 203 PTR_ADDU sp, sp, 64; \ 204 .set reorder; \ 205 .set at; 206 #else 207 #define MCOUNT 208 #endif 209 210 /* 211 * LEAF(x, fsize) 212 * 213 * Declare a leaf routine. 214 */ 215 #define LEAF(x, fsize) \ 216 .align 3; \ 217 .globl x; \ 218 .ent x, 0; \ 219 x: ; \ 220 .frame sp, fsize, ra; \ 221 SETUP_GP \ 222 MCOUNT 223 224 #define ALEAF(x) \ 225 .globl x; \ 226 x: 227 228 /* 229 * NLEAF(x) 230 * 231 * Declare a non-profiled leaf routine. 232 */ 233 #define NLEAF(x, fsize) \ 234 .align 3; \ 235 .globl x; \ 236 .ent x, 0; \ 237 x: ; \ 238 .frame sp, fsize, ra; \ 239 SETUP_GP 240 241 /* 242 * NON_LEAF(x) 243 * 244 * Declare a non-leaf routine (a routine that makes other C calls). 245 */ 246 #define NON_LEAF(x, fsize, retpc) \ 247 .align 3; \ 248 .globl x; \ 249 .ent x, 0; \ 250 x: ; \ 251 .frame sp, fsize, retpc; \ 252 SETUP_GP \ 253 MCOUNT 254 255 /* 256 * NNON_LEAF(x) 257 * 258 * Declare a non-profiled non-leaf routine 259 * (a routine that makes other C calls). 260 */ 261 #define NNON_LEAF(x, fsize, retpc) \ 262 .align 3; \ 263 .globl x; \ 264 .ent x, 0; \ 265 x: ; \ 266 .frame sp, fsize, retpc \ 267 SETUP_GP 268 269 /* 270 * END(x) 271 * 272 * Mark end of a procedure. 273 */ 274 #define END(x) \ 275 .end x 276 277 /* 278 * STRONG_ALIAS, WEAK_ALIAS 279 * Create a strong or weak alias. 280 */ 281 #define STRONG_ALIAS(alias,sym) \ 282 .global alias; alias = sym 283 #define WEAK_ALIAS(alias,sym) \ 284 .weak alias; alias = sym 285 286 287 /* 288 * Macros to panic and printf from assembly language. 289 */ 290 #define PANIC(msg) \ 291 LA a0, 9f; \ 292 jal panic; \ 293 nop ; \ 294 MSG(msg) 295 296 #define PRINTF(msg) \ 297 LA a0, 9f; \ 298 jal printf; \ 299 nop ; \ 300 MSG(msg) 301 302 #define MSG(msg) \ 303 .rdata; \ 304 9: .asciiz msg; \ 305 .text 306 307 #define LOAD_XKPHYS(reg, cca) \ 308 li reg, cca | 0x10; \ 309 dsll reg, reg, 59 310 311 #ifdef MULTIPROCESSOR 312 #define GET_CPU_INFO(ci, tmp) HW_GET_CPU_INFO(ci, tmp) 313 #else /* MULTIPROCESSOR */ 314 #define GET_CPU_INFO(ci, tmp) \ 315 LA ci, cpu_info_primary 316 #endif /* MULTIPROCESSOR */ 317 318 /* 319 * Hazards 320 */ 321 322 #ifdef CPU_OCTEON 323 /* 324 * OCTEON clears hazards in hardware. 325 */ 326 #define MFC0_HAZARD /* nothing */ 327 #define MTC0_HAZARD /* nothing */ 328 #define MTC0_SR_IE_HAZARD /* nothing */ 329 #define MTC0_SR_CU_HAZARD /* nothing */ 330 #define TLB_HAZARD /* nothing */ 331 #endif 332 333 /* Hazard between {d,}mfc0 of COP_0_VADDR */ 334 #ifndef PRE_MFC0_ADDR_HAZARD 335 #define PRE_MFC0_ADDR_HAZARD /* nothing */ 336 #endif 337 338 /* Hazard after {d,}mfc0 from any register */ 339 #ifndef MFC0_HAZARD 340 #define MFC0_HAZARD /* nothing */ 341 #endif 342 /* Hazard after {d,}mtc0 to any register */ 343 #ifndef MTC0_HAZARD 344 #define MTC0_HAZARD NOP; NOP; NOP; NOP 345 #endif 346 /* Hazard after {d,}mtc0 to COP_0_SR affecting the state of interrupts */ 347 #ifndef MTC0_SR_IE_HAZARD 348 #define MTC0_SR_IE_HAZARD MTC0_HAZARD 349 #endif 350 /* Hazard after {d,}mtc0 to COP_0_SR affecting the state of coprocessors */ 351 #ifndef MTC0_SR_CU_HAZARD 352 #define MTC0_SR_CU_HAZARD NOP; NOP 353 #endif 354 355 /* Hazard before and after a tlbp, tlbr, tlbwi or tlbwr instruction */ 356 #ifndef TLB_HAZARD 357 #define TLB_HAZARD NOP; NOP 358 #endif 359 360 #endif /* !_MIPS64_ASM_H_ */ 361