1 /* $OpenBSD: asm.h,v 1.15 2012/06/23 21:53:38 miod 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 /* 34 * Due to a flaw in RM7000 1.x processors a pipeline 'drain' is 35 * required after some mtc0 instructions. 36 * Ten nops in sequence does the trick. 37 */ 38 #ifdef CPU_RM7000 39 #define ITLBNOPFIX nop;nop;nop;nop;nop;nop;nop;nop;nop;nop 40 #else 41 #define ITLBNOPFIX nop;nop;nop;nop 42 #endif 43 44 #define _MIPS_ISA_MIPS1 1 /* R2000/R3000 */ 45 #define _MIPS_ISA_MIPS2 2 /* R4000/R6000 */ 46 #define _MIPS_ISA_MIPS3 3 /* R4000 */ 47 #define _MIPS_ISA_MIPS4 4 /* TFP (R1x000) */ 48 49 #if !defined(ABICALLS) && !defined(_NO_ABICALLS) 50 #define ABICALLS .abicalls 51 #endif 52 53 #if defined(ABICALLS) && !defined(_KERNEL) 54 ABICALLS 55 #endif 56 57 #define _C_LABEL(x) x /* XXX Obsolete but keep for a while */ 58 59 #if !defined(__MIPSEL__) && !defined(__MIPSEB__) 60 #error "__MIPSEL__ or __MIPSEB__ must be defined" 61 #endif 62 /* 63 * Define how to access unaligned data word 64 */ 65 #if defined(__MIPSEL__) 66 #define LWLO lwl 67 #define LWHI lwr 68 #define SWLO swl 69 #define SWHI swr 70 #define LDLO ldl 71 #define LDHI ldr 72 #define SDLO sdl 73 #define SDHI sdr 74 #endif 75 #if defined(__MIPSEB__) 76 #define LWLO lwr 77 #define LWHI lwl 78 #define SWLO swr 79 #define SWHI swl 80 #define LDLO ldr 81 #define LDHI ldl 82 #define SDLO sdr 83 #define SDHI sdl 84 #endif 85 86 /* 87 * Define programming environment for ABI. 88 */ 89 #if defined(ABICALLS) && !defined(_KERNEL) && !defined(_STANDALONE) 90 91 #ifndef _MIPS_SIM 92 #define _MIPS_SIM 1 93 #define _ABIO32 1 94 #endif 95 #ifndef _MIPS_ISA 96 #define _MIPS_ISA 2 97 #define _MIPS_ISA_MIPS2 2 98 #endif 99 100 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32) 101 #define NARGSAVE 4 102 103 #define SETUP_GP \ 104 .set noreorder; \ 105 .cpload t9; \ 106 .set reorder; 107 108 #define SAVE_GP(x) \ 109 .cprestore x 110 111 #define SETUP_GP64(gpoff, name) 112 #define RESTORE_GP64 113 #endif 114 115 #if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32) 116 #define NARGSAVE 0 117 118 #define SETUP_GP 119 #define SAVE_GP(x) 120 #define SETUP_GP64(gpoff, name) \ 121 .cpsetup t9, gpoff, name 122 #define RESTORE_GP64 \ 123 .cpreturn 124 #endif 125 126 #define MKFSIZ(narg,locals) (((narg+locals)*REGSZ+31)&(~31)) 127 128 #else /* defined(ABICALLS) && !defined(_KERNEL) */ 129 130 #define NARGSAVE 4 131 #define SETUP_GP 132 #define SAVE_GP(x) 133 134 #define ALIGNSZ 16 /* Stack layout alignment */ 135 #define FRAMESZ(sz) (((sz) + (ALIGNSZ-1)) & ~(ALIGNSZ-1)) 136 137 #endif 138 139 /* 140 * Basic register operations based on selected ISA 141 */ 142 #if (_MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2) 143 #define REGSZ 4 /* 32 bit mode register size */ 144 #define LOGREGSZ 2 /* log rsize */ 145 #define REG_S sw 146 #define REG_L lw 147 #define CF_SZ 24 /* Call frame size */ 148 #define CF_ARGSZ 16 /* Call frame arg size */ 149 #define CF_RA_OFFS 20 /* Call ra save offset */ 150 #endif 151 152 #if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4) 153 #define REGSZ 8 /* 64 bit mode register size */ 154 #define LOGREGSZ 3 /* log rsize */ 155 #define REG_S sd 156 #define REG_L ld 157 #define CF_SZ 48 /* Call frame size (multiple of ALIGNSZ) */ 158 #define CF_ARGSZ 32 /* Call frame arg size */ 159 #define CF_RA_OFFS 40 /* Call ra save offset */ 160 #endif 161 162 #ifndef __LP64__ 163 #define PTR_L lw 164 #define PTR_S sw 165 #define PTR_SUB sub 166 #define PTR_ADD add 167 #define PTR_SUBU subu 168 #define PTR_ADDU addu 169 #define LI li 170 #define LA la 171 #define PTR_SLL sll 172 #define PTR_SRL srl 173 #define PTR_VAL .word 174 #else 175 #define PTR_L ld 176 #define PTR_S sd 177 #define PTR_ADD dadd 178 #define PTR_SUB dsub 179 #define PTR_SUBU dsubu 180 #define PTR_ADDU daddu 181 #define LI dli 182 #define LA dla 183 #define PTR_SLL dsll 184 #define PTR_SRL dsrl 185 #define PTR_VAL .dword 186 #endif 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 * WEAK ALIAS: create a weak alias 279 */ 280 #define WEAK_ALIAS(alias,sym) \ 281 .weak alias; alias = sym 282 283 284 /* 285 * Macros to panic and printf from assembly language. 286 */ 287 #define PANIC(msg) \ 288 LA a0, 9f; \ 289 jal panic; \ 290 nop ; \ 291 MSG(msg) 292 293 #define PRINTF(msg) \ 294 LA a0, 9f; \ 295 jal printf; \ 296 nop ; \ 297 MSG(msg) 298 299 #define MSG(msg) \ 300 .rdata; \ 301 9: .asciiz msg; \ 302 .text 303 304 #define ASMSTR(str) \ 305 .asciiz str; \ 306 .align 3 307 308 #define LOAD_XKPHYS(reg, cca) \ 309 li reg, cca | 0x10; \ 310 dsll reg, reg, 59 311 312 #ifdef MULTIPROCESSOR 313 #define GET_CPU_INFO(ci, tmp) HW_GET_CPU_INFO(ci, tmp) 314 #else /* MULTIPROCESSOR */ 315 #define GET_CPU_INFO(ci, tmp) \ 316 LA ci, cpu_info_primary 317 #endif /* MULTIPROCESSOR */ 318 319 #endif /* !_MIPS64_ASM_H_ */ 320