1 1.46 riastrad /* $NetBSD: asm.h,v 1.46 2024/06/09 22:35:37 riastradh Exp $ */ 2 1.1 cgd 3 1.33 matt /* 4 1.4 cgd * Copyright (c) 1991,1990,1989,1994,1995,1996 Carnegie Mellon University 5 1.1 cgd * All Rights Reserved. 6 1.33 matt * 7 1.1 cgd * Permission to use, copy, modify and distribute this software and its 8 1.1 cgd * documentation is hereby granted, provided that both the copyright 9 1.1 cgd * notice and this permission notice appear in all copies of the 10 1.1 cgd * software, derivative works or modified versions, and any portions 11 1.1 cgd * thereof, and that both notices appear in supporting documentation. 12 1.33 matt * 13 1.1 cgd * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 14 1.1 cgd * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 15 1.1 cgd * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 16 1.33 matt * 17 1.1 cgd * Carnegie Mellon requests users of this software to return to 18 1.33 matt * 19 1.1 cgd * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU 20 1.1 cgd * School of Computer Science 21 1.1 cgd * Carnegie Mellon University 22 1.1 cgd * Pittsburgh PA 15213-3890 23 1.33 matt * 24 1.1 cgd * any improvements or extensions that they make and grant Carnegie Mellon 25 1.1 cgd * the rights to redistribute these changes. 26 1.1 cgd */ 27 1.1 cgd 28 1.1 cgd /* 29 1.1 cgd * Assembly coding style 30 1.1 cgd * 31 1.1 cgd * This file contains macros and register defines to 32 1.1 cgd * aid in writing more readable assembly code. 33 1.1 cgd * Some rules to make assembly code understandable by 34 1.1 cgd * a debugger are also noted. 35 1.1 cgd * 36 1.1 cgd * The document 37 1.1 cgd * 38 1.1 cgd * "ALPHA Calling Standard", DEC 27-Apr-90 39 1.1 cgd * 40 1.1 cgd * defines (a superset of) the rules and conventions 41 1.1 cgd * we use. While we make no promise of adhering to 42 1.1 cgd * such standard and its evolution (esp where we 43 1.1 cgd * can get faster code paths) it is certainly intended 44 1.1 cgd * that we be interoperable with such standard. 45 1.1 cgd * 46 1.1 cgd * In this sense, this file is a proper part of the 47 1.1 cgd * definition of the (software) Alpha architecture. 48 1.1 cgd */ 49 1.1 cgd 50 1.1 cgd /* 51 1.1 cgd * Symbolic register names and register saving rules 52 1.1 cgd * 53 1.1 cgd * Legend: 54 1.1 cgd * T Saved by caller (Temporaries) 55 1.1 cgd * S Saved by callee (call-Safe registers) 56 1.1 cgd */ 57 1.1 cgd 58 1.1 cgd #define v0 $0 /* (T) return value */ 59 1.1 cgd #define t0 $1 /* (T) temporary registers */ 60 1.1 cgd #define t1 $2 61 1.1 cgd #define t2 $3 62 1.1 cgd #define t3 $4 63 1.1 cgd #define t4 $5 64 1.1 cgd #define t5 $6 65 1.1 cgd #define t6 $7 66 1.1 cgd #define t7 $8 67 1.1 cgd 68 1.1 cgd #define s0 $9 /* (S) call-safe registers */ 69 1.1 cgd #define s1 $10 70 1.1 cgd #define s2 $11 71 1.1 cgd #define s3 $12 72 1.1 cgd #define s4 $13 73 1.1 cgd #define s5 $14 74 1.1 cgd #define s6 $15 75 1.1 cgd #define a0 $16 /* (T) argument registers */ 76 1.1 cgd #define a1 $17 77 1.1 cgd #define a2 $18 78 1.1 cgd #define a3 $19 79 1.1 cgd #define a4 $20 80 1.1 cgd #define a5 $21 81 1.1 cgd #define t8 $22 /* (T) temporary registers */ 82 1.1 cgd #define t9 $23 83 1.1 cgd #define t10 $24 84 1.1 cgd #define t11 $25 85 1.24 nathanw #define ra $26 /* (S) return address */ 86 1.1 cgd #define t12 $27 /* (T) another temporary */ 87 1.1 cgd #define at_reg $28 /* (T) assembler scratch */ 88 1.1 cgd #define gp $29 /* (T) (local) data pointer */ 89 1.1 cgd #define sp $30 /* (S) stack pointer */ 90 1.1 cgd #define zero $31 /* wired zero */ 91 1.1 cgd 92 1.1 cgd /* Floating point registers (XXXX VERIFY THIS) */ 93 1.1 cgd #define fv0 $f0 /* (T) return value (real) */ 94 1.1 cgd #define fv1 $f1 /* (T) return value (imaginary)*/ 95 1.1 cgd #define ft0 fv1 96 1.1 cgd #define fs0 $f2 /* (S) call-safe registers */ 97 1.1 cgd #define fs1 $f3 98 1.1 cgd #define fs2 $f4 99 1.1 cgd #define fs3 $f5 100 1.1 cgd #define fs4 $f6 101 1.1 cgd #define fs5 $f7 102 1.1 cgd #define fs6 $f8 103 1.1 cgd #define fs7 $f9 104 1.1 cgd #define ft1 $f10 /* (T) temporary registers */ 105 1.1 cgd #define ft2 $f11 106 1.1 cgd #define ft3 $f12 107 1.1 cgd #define ft4 $f13 108 1.1 cgd #define ft5 $f14 109 1.1 cgd #define ft6 $f15 110 1.1 cgd #define fa0 $f16 /* (T) argument registers */ 111 1.1 cgd #define fa1 $f17 112 1.1 cgd #define fa2 $f18 113 1.1 cgd #define fa3 $f19 114 1.1 cgd #define fa4 $f20 115 1.1 cgd #define fa5 $f21 116 1.1 cgd #define ft7 $f22 /* (T) more temporaries */ 117 1.1 cgd #define ft8 $f23 118 1.1 cgd #define ft9 $f24 119 1.1 cgd #define ft10 $f25 120 1.1 cgd #define ft11 $f26 121 1.1 cgd #define ft12 $f27 122 1.1 cgd #define ft13 $f28 123 1.1 cgd #define ft14 $f29 124 1.1 cgd #define ft15 $f30 125 1.1 cgd #define fzero $f31 /* wired zero */ 126 1.1 cgd 127 1.1 cgd 128 1.1 cgd /* Other DEC standard names */ 129 1.1 cgd #define ai $25 /* (T) argument information */ 130 1.1 cgd #define pv $27 /* (T) procedure value */ 131 1.1 cgd 132 1.9 cgd 133 1.9 cgd /* 134 1.9 cgd * Useful stuff. 135 1.9 cgd */ 136 1.9 cgd #ifdef __STDC__ 137 1.9 cgd #define __CONCAT(a,b) a ## b 138 1.9 cgd #else 139 1.9 cgd #define __CONCAT(a,b) a/**/b 140 1.9 cgd #endif 141 1.9 cgd #define ___CONCAT(a,b) __CONCAT(a,b) 142 1.9 cgd 143 1.9 cgd /* 144 1.9 cgd * Macro to make a local label name. 145 1.9 cgd */ 146 1.9 cgd #define LLABEL(name,num) ___CONCAT(___CONCAT(L,name),num) 147 1.9 cgd 148 1.1 cgd /* 149 1.1 cgd * 150 1.1 cgd * Debuggers need symbol table information to be able to properly 151 1.1 cgd * decode a stack trace. The minimum that should be provided is: 152 1.1 cgd * 153 1.1 cgd * name: 154 1.1 cgd * .proc name,numargs 155 1.1 cgd * 156 1.1 cgd * where "name" is the function's name; 157 1.1 cgd * "numargs" how many arguments it expects. For varargs 158 1.1 cgd * procedures this should be a negative number, 159 1.1 cgd * indicating the minimum required number of 160 1.1 cgd * arguments (which is at least 1); 161 1.1 cgd * 162 1.1 cgd * NESTED functions (functions that call other functions) should define 163 1.1 cgd * how they handle their stack frame in a .frame directive: 164 1.1 cgd * 165 1.1 cgd * .frame framesize, pc_reg, i_mask, f_mask 166 1.1 cgd * 167 1.1 cgd * where "framesize" is the size of the frame for this function, in bytes. 168 1.1 cgd * That is: 169 1.1 cgd * new_sp + framesize == old_sp 170 1.1 cgd * Framesizes should be rounded to a cacheline size. 171 1.1 cgd * Note that old_sp plays the role of a conventional 172 1.1 cgd * "frame pointer"; 173 1.1 cgd * "pc_reg" is either a register which preserves the caller's PC 174 1.1 cgd * or 'std', if std the saved PC should be stored at 175 1.1 cgd * old_sp-8 176 1.1 cgd * "i_mask" is a bitmask that indicates which of the integer 177 1.1 cgd * registers are saved. See the M_xx defines at the 178 1.1 cgd * end for the encoding of this 32bit value. 179 1.1 cgd * "f_mask" is the same, for floating point registers. 180 1.1 cgd * 181 1.18 ross * Note, 10/31/97: This is interesting but it isn't the way gcc outputs 182 1.18 ross * frame directives and it isn't the way the macros below output them 183 1.18 ross * either. Frame directives look like this: 184 1.18 ross * 185 1.18 ross * .frame $15,framesize,$26,0 186 1.18 ross * 187 1.18 ross * If no fp is set up then $30 should be used instead of $15. 188 1.18 ross * Also, gdb expects to find a <lda sp,-framesize(sp)> at the beginning 189 1.18 ross * of a procedure. Don't use things like sub sp,framesize,sp for this 190 1.27 keihan * reason. End Note 10/31/97. ross (at) NetBSD.org 191 1.18 ross * 192 1.1 cgd * Note that registers should be saved starting at "old_sp-8", where the 193 1.1 cgd * return address should be stored. Other registers follow at -16-24-32.. 194 1.1 cgd * starting from register 0 (if saved) and up. Then float registers (ifany) 195 1.1 cgd * are saved. 196 1.1 cgd * 197 1.1 cgd * If you need to alias a leaf function, or to provide multiple entry points 198 1.1 cgd * use the LEAF() macro for the main entry point and XLEAF() for the other 199 1.1 cgd * additional/alternate entry points. 200 1.1 cgd * "XLEAF"s must be nested within a "LEAF" and a ".end". 201 1.1 cgd * Similar rules for nested routines, e.g. use NESTED/XNESTED 202 1.1 cgd * Symbols that should not be exported can be declared with the STATIC_xxx 203 1.1 cgd * macros. 204 1.1 cgd * 205 1.1 cgd * All functions must be terminated by the END macro 206 1.1 cgd * 207 1.1 cgd * It is conceivable, although currently at the limits of compiler 208 1.1 cgd * technology, that while performing inter-procedural optimizations 209 1.1 cgd * the compiler/linker be able to avoid unnecessary register spills 210 1.1 cgd * if told about the register usage of LEAF procedures (and by transitive 211 1.1 cgd * closure of NESTED procedures as well). Assembly code can help 212 1.1 cgd * this process using the .reguse directive: 213 1.1 cgd * 214 1.1 cgd * .reguse i_mask, f_mask 215 1.1 cgd * 216 1.1 cgd * where the register masks are built as above or-ing M_xx defines. 217 1.1 cgd * 218 1.1 cgd * 219 1.1 cgd * All symbols are internal unless EXPORTed. Symbols that are IMPORTed 220 1.1 cgd * must be appropriately described to the debugger. 221 1.1 cgd * 222 1.1 cgd */ 223 1.1 cgd 224 1.1 cgd /* 225 1.2 cgd * MCOUNT 226 1.2 cgd */ 227 1.2 cgd 228 1.11 jtc #ifndef GPROF 229 1.2 cgd #define MCOUNT /* nothing */ 230 1.2 cgd #else 231 1.2 cgd #define MCOUNT \ 232 1.6 cgd .set noat; \ 233 1.6 cgd jsr at_reg,_mcount; \ 234 1.6 cgd .set at 235 1.2 cgd #endif 236 1.18 ross /* 237 1.18 ross * PALVECT, ESETUP, and ERSAVE 238 1.18 ross * Declare a palcode transfer point, and carefully construct 239 1.18 ross * gdb symbols with an unusual _negative_ register-save offset 240 1.18 ross * so that gdb can find the otherwise lost PC and then 241 1.18 ross * invert the vector for traceback. Also, fix up framesize, 242 1.18 ross * allowing for the palframe for the same reason. 243 1.18 ross */ 244 1.18 ross 245 1.18 ross #define PALVECT(_name_) \ 246 1.18 ross ESETUP(_name_); \ 247 1.18 ross ERSAVE() 248 1.18 ross 249 1.18 ross #define ESETUP(_name_) \ 250 1.25 thorpej /* .loc 1 __LINE__; */ \ 251 1.18 ross .globl _name_; \ 252 1.18 ross .ent _name_ 0; \ 253 1.18 ross _name_:; \ 254 1.18 ross .set noat; \ 255 1.18 ross lda sp,-(FRAME_SW_SIZE*8)(sp); \ 256 1.18 ross .frame $30,(FRAME_SW_SIZE+6)*8,$26,0; /* give gdb the real size */\ 257 1.18 ross .mask 0x4000000,-0x28; \ 258 1.18 ross .set at 259 1.18 ross 260 1.18 ross #define ERSAVE() \ 261 1.18 ross .set noat; \ 262 1.18 ross stq at_reg,(FRAME_AT*8)(sp); \ 263 1.18 ross .set at; \ 264 1.18 ross stq ra,(FRAME_RA*8)(sp); \ 265 1.25 thorpej /* .loc 1 __LINE__; */ \ 266 1.18 ross bsr ra,exception_save_regs /* jmp/CALL trashes pv/t12 */ 267 1.18 ross 268 1.2 cgd 269 1.2 cgd /* 270 1.1 cgd * LEAF 271 1.1 cgd * Declare a global leaf function. 272 1.1 cgd * A leaf function does not call other functions AND does not 273 1.1 cgd * use any register that is callee-saved AND does not modify 274 1.1 cgd * the stack pointer. 275 1.1 cgd */ 276 1.1 cgd #define LEAF(_name_,_n_args_) \ 277 1.1 cgd .globl _name_; \ 278 1.1 cgd .ent _name_ 0; \ 279 1.1 cgd _name_:; \ 280 1.2 cgd .frame sp,0,ra; \ 281 1.2 cgd MCOUNT 282 1.2 cgd /* should have been 283 1.2 cgd .proc _name_,_n_args_; \ 284 1.2 cgd .frame 0,ra,0,0 285 1.2 cgd */ 286 1.2 cgd 287 1.2 cgd #define LEAF_NOPROFILE(_name_,_n_args_) \ 288 1.2 cgd .globl _name_; \ 289 1.2 cgd .ent _name_ 0; \ 290 1.2 cgd _name_:; \ 291 1.1 cgd .frame sp,0,ra 292 1.1 cgd /* should have been 293 1.1 cgd .proc _name_,_n_args_; \ 294 1.1 cgd .frame 0,ra,0,0 295 1.1 cgd */ 296 1.1 cgd 297 1.1 cgd /* 298 1.1 cgd * STATIC_LEAF 299 1.1 cgd * Declare a local leaf function. 300 1.1 cgd */ 301 1.1 cgd #define STATIC_LEAF(_name_,_n_args_) \ 302 1.1 cgd .ent _name_ 0; \ 303 1.1 cgd _name_:; \ 304 1.2 cgd .frame sp,0,ra; \ 305 1.2 cgd MCOUNT 306 1.1 cgd /* should have been 307 1.1 cgd .proc _name_,_n_args_; \ 308 1.1 cgd .frame 0,ra,0,0 309 1.1 cgd */ 310 1.1 cgd /* 311 1.1 cgd * XLEAF 312 1.1 cgd * Global alias for a leaf function, or alternate entry point 313 1.1 cgd */ 314 1.1 cgd #define XLEAF(_name_,_n_args_) \ 315 1.1 cgd .globl _name_; \ 316 1.1 cgd .aent _name_ 0; \ 317 1.1 cgd _name_: 318 1.1 cgd /* should have been 319 1.1 cgd .aproc _name_,_n_args_; 320 1.1 cgd */ 321 1.1 cgd 322 1.1 cgd /* 323 1.1 cgd * STATIC_XLEAF 324 1.1 cgd * Local alias for a leaf function, or alternate entry point 325 1.1 cgd */ 326 1.1 cgd #define STATIC_XLEAF(_name_,_n_args_) \ 327 1.1 cgd .aent _name_ 0; \ 328 1.1 cgd _name_: 329 1.1 cgd /* should have been 330 1.1 cgd .aproc _name_,_n_args_; 331 1.1 cgd */ 332 1.1 cgd 333 1.1 cgd /* 334 1.1 cgd * NESTED 335 1.1 cgd * Declare a (global) nested function 336 1.1 cgd * A nested function calls other functions and needs 337 1.1 cgd * therefore stack space to save/restore registers. 338 1.1 cgd */ 339 1.1 cgd #define NESTED(_name_, _n_args_, _framesize_, _pc_reg_, _i_mask_, _f_mask_ ) \ 340 1.1 cgd .globl _name_; \ 341 1.1 cgd .ent _name_ 0; \ 342 1.1 cgd _name_:; \ 343 1.1 cgd .frame sp,_framesize_,_pc_reg_; \ 344 1.2 cgd .livereg _i_mask_,_f_mask_; \ 345 1.2 cgd MCOUNT 346 1.2 cgd /* should have been 347 1.2 cgd .proc _name_,_n_args_; \ 348 1.2 cgd .frame _framesize_, _pc_reg_, _i_mask_, _f_mask_ 349 1.2 cgd */ 350 1.2 cgd 351 1.2 cgd #define NESTED_NOPROFILE(_name_, _n_args_, _framesize_, _pc_reg_, _i_mask_, _f_mask_ ) \ 352 1.2 cgd .globl _name_; \ 353 1.2 cgd .ent _name_ 0; \ 354 1.2 cgd _name_:; \ 355 1.2 cgd .frame sp,_framesize_,_pc_reg_; \ 356 1.1 cgd .livereg _i_mask_,_f_mask_ 357 1.1 cgd /* should have been 358 1.1 cgd .proc _name_,_n_args_; \ 359 1.1 cgd .frame _framesize_, _pc_reg_, _i_mask_, _f_mask_ 360 1.1 cgd */ 361 1.1 cgd 362 1.1 cgd /* 363 1.1 cgd * STATIC_NESTED 364 1.1 cgd * Declare a local nested function. 365 1.1 cgd */ 366 1.1 cgd #define STATIC_NESTED(_name_, _n_args_, _framesize_, _pc_reg_, _i_mask_, _f_mask_ ) \ 367 1.1 cgd .ent _name_ 0; \ 368 1.1 cgd _name_:; \ 369 1.1 cgd .frame sp,_framesize_,_pc_reg_; \ 370 1.2 cgd .livereg _i_mask_,_f_mask_; \ 371 1.2 cgd MCOUNT 372 1.1 cgd /* should have been 373 1.1 cgd .proc _name_,_n_args_; \ 374 1.1 cgd .frame _framesize_, _pc_reg_, _i_mask_, _f_mask_ 375 1.1 cgd */ 376 1.1 cgd 377 1.1 cgd /* 378 1.1 cgd * XNESTED 379 1.1 cgd * Same as XLEAF, for a nested function. 380 1.1 cgd */ 381 1.1 cgd #define XNESTED(_name_,_n_args_) \ 382 1.1 cgd .globl _name_; \ 383 1.1 cgd .aent _name_ 0; \ 384 1.1 cgd _name_: 385 1.1 cgd /* should have been 386 1.1 cgd .aproc _name_,_n_args_; 387 1.1 cgd */ 388 1.1 cgd 389 1.1 cgd 390 1.1 cgd /* 391 1.1 cgd * STATIC_XNESTED 392 1.1 cgd * Same as STATIC_XLEAF, for a nested function. 393 1.1 cgd */ 394 1.1 cgd #define STATIC_XNESTED(_name_,_n_args_) \ 395 1.1 cgd .aent _name_ 0; \ 396 1.1 cgd _name_: 397 1.1 cgd /* should have been 398 1.1 cgd .aproc _name_,_n_args_; 399 1.1 cgd */ 400 1.1 cgd 401 1.1 cgd 402 1.1 cgd /* 403 1.1 cgd * END 404 1.1 cgd * Function delimiter 405 1.1 cgd */ 406 1.1 cgd #define END(_name_) \ 407 1.1 cgd .end _name_ 408 1.1 cgd 409 1.1 cgd 410 1.1 cgd /* 411 1.1 cgd * CALL 412 1.1 cgd * Function invocation 413 1.1 cgd */ 414 1.1 cgd #define CALL(_name_) \ 415 1.25 thorpej /* .loc 1 __LINE__; */ \ 416 1.1 cgd jsr ra,_name_; \ 417 1.1 cgd ldgp gp,0(ra) 418 1.1 cgd /* but this would cover longer jumps 419 1.1 cgd br ra,.+4; \ 420 1.1 cgd bsr ra,_name_ 421 1.1 cgd */ 422 1.1 cgd 423 1.1 cgd 424 1.1 cgd /* 425 1.1 cgd * RET 426 1.1 cgd * Return from function 427 1.1 cgd */ 428 1.1 cgd #define RET \ 429 1.1 cgd ret zero,(ra),1 430 1.1 cgd 431 1.1 cgd 432 1.1 cgd /* 433 1.1 cgd * EXPORT 434 1.1 cgd * Export a symbol 435 1.1 cgd */ 436 1.1 cgd #define EXPORT(_name_) \ 437 1.1 cgd .globl _name_; \ 438 1.1 cgd _name_: 439 1.1 cgd 440 1.1 cgd 441 1.1 cgd /* 442 1.1 cgd * IMPORT 443 1.1 cgd * Make an external name visible, typecheck the size 444 1.1 cgd */ 445 1.1 cgd #define IMPORT(_name_, _size_) \ 446 1.1 cgd .extern _name_,_size_ 447 1.1 cgd 448 1.1 cgd 449 1.1 cgd /* 450 1.1 cgd * ABS 451 1.1 cgd * Define an absolute symbol 452 1.1 cgd */ 453 1.1 cgd #define ABS(_name_, _value_) \ 454 1.1 cgd .globl _name_; \ 455 1.1 cgd _name_ = _value_ 456 1.1 cgd 457 1.1 cgd 458 1.1 cgd /* 459 1.1 cgd * BSS 460 1.1 cgd * Allocate un-initialized space for a global symbol 461 1.1 cgd */ 462 1.1 cgd #define BSS(_name_,_numbytes_) \ 463 1.1 cgd .comm _name_,_numbytes_ 464 1.1 cgd 465 1.1 cgd /* 466 1.1 cgd * VECTOR 467 1.1 cgd * Make an exception entry point look like a called function, 468 1.1 cgd * to make it digestible to the debugger (KERNEL only) 469 1.1 cgd */ 470 1.1 cgd #define VECTOR(_name_, _i_mask_) \ 471 1.1 cgd .globl _name_; \ 472 1.1 cgd .ent _name_ 0; \ 473 1.1 cgd _name_:; \ 474 1.1 cgd .mask _i_mask_|IM_EXC,0; \ 475 1.1 cgd .frame sp,MSS_SIZE,ra; 476 1.19 ross /* .livereg _i_mask_|IM_EXC,0 */ 477 1.1 cgd /* should have been 478 1.1 cgd .proc _name_,1; \ 479 1.1 cgd .frame MSS_SIZE,$31,_i_mask_,0; \ 480 1.1 cgd */ 481 1.1 cgd 482 1.1 cgd /* 483 1.1 cgd * MSG 484 1.1 cgd * Allocate space for a message (a read-only ascii string) 485 1.1 cgd */ 486 1.1 cgd #define ASCIZ .asciz 487 1.6 cgd #define MSG(msg,reg,label) \ 488 1.6 cgd lda reg, label; \ 489 1.1 cgd .data; \ 490 1.6 cgd label: ASCIZ msg; \ 491 1.1 cgd .text; 492 1.1 cgd 493 1.1 cgd /* 494 1.1 cgd * PRINTF 495 1.1 cgd * Print a message 496 1.1 cgd */ 497 1.6 cgd #define PRINTF(msg,label) \ 498 1.6 cgd MSG(msg,a0,label); \ 499 1.8 christos CALL(printf) 500 1.1 cgd 501 1.1 cgd /* 502 1.1 cgd * PANIC 503 1.1 cgd * Fatal error (KERNEL) 504 1.1 cgd */ 505 1.6 cgd #define PANIC(msg,label) \ 506 1.6 cgd MSG(msg,a0,label); \ 507 1.1 cgd CALL(panic) 508 1.1 cgd 509 1.1 cgd /* 510 1.1 cgd * Register mask defines, used to define both save 511 1.1 cgd * and use register sets. 512 1.1 cgd * 513 1.1 cgd * NOTE: The bit order should HAVE BEEN maintained when saving 514 1.1 cgd * registers on the stack: sp goes at the highest 515 1.1 cgd * address, gp lower on the stack, etc etc 516 1.1 cgd * BUT NOONE CARES ABOUT DEBUGGERS AT MIPS 517 1.1 cgd */ 518 1.1 cgd 519 1.1 cgd #define IM_EXC 0x80000000 520 1.1 cgd #define IM_SP 0x40000000 521 1.1 cgd #define IM_GP 0x20000000 522 1.1 cgd #define IM_AT 0x10000000 523 1.1 cgd #define IM_T12 0x08000000 524 1.1 cgd # define IM_PV IM_T4 525 1.1 cgd #define IM_RA 0x04000000 526 1.1 cgd #define IM_T11 0x02000000 527 1.1 cgd # define IM_AI IM_T3 528 1.1 cgd #define IM_T10 0x01000000 529 1.1 cgd #define IM_T9 0x00800000 530 1.1 cgd #define IM_T8 0x00400000 531 1.1 cgd #define IM_A5 0x00200000 532 1.1 cgd #define IM_A4 0x00100000 533 1.1 cgd #define IM_A3 0x00080000 534 1.1 cgd #define IM_A2 0x00040000 535 1.1 cgd #define IM_A1 0x00020000 536 1.1 cgd #define IM_A0 0x00010000 537 1.1 cgd #define IM_S6 0x00008000 538 1.1 cgd #define IM_S5 0x00004000 539 1.1 cgd #define IM_S4 0x00002000 540 1.1 cgd #define IM_S3 0x00001000 541 1.1 cgd #define IM_S2 0x00000800 542 1.1 cgd #define IM_S1 0x00000400 543 1.1 cgd #define IM_S0 0x00000200 544 1.1 cgd #define IM_T7 0x00000100 545 1.1 cgd #define IM_T6 0x00000080 546 1.1 cgd #define IM_T5 0x00000040 547 1.1 cgd #define IM_T4 0x00000020 548 1.1 cgd #define IM_T3 0x00000010 549 1.1 cgd #define IM_T2 0x00000008 550 1.1 cgd #define IM_T1 0x00000004 551 1.1 cgd #define IM_T0 0x00000002 552 1.1 cgd #define IM_V0 0x00000001 553 1.1 cgd 554 1.1 cgd #define FM_T15 0x40000000 555 1.1 cgd #define FM_T14 0x20000000 556 1.1 cgd #define FM_T13 0x10000000 557 1.1 cgd #define FM_T12 0x08000000 558 1.1 cgd #define FM_T11 0x04000000 559 1.1 cgd #define FM_T10 0x02000000 560 1.1 cgd #define FM_T9 0x01000000 561 1.1 cgd #define FM_T8 0x00800000 562 1.1 cgd #define FM_T7 0x00400000 563 1.1 cgd #define FM_A5 0x00200000 564 1.1 cgd #define FM_A4 0x00100000 565 1.1 cgd #define FM_A3 0x00080000 566 1.1 cgd #define FM_A2 0x00040000 567 1.1 cgd #define FM_A1 0x00020000 568 1.1 cgd #define FM_A0 0x00010000 569 1.1 cgd #define FM_T6 0x00008000 570 1.1 cgd #define FM_T5 0x00004000 571 1.1 cgd #define FM_T4 0x00002000 572 1.1 cgd #define FM_T3 0x00001000 573 1.1 cgd #define FM_T2 0x00000800 574 1.1 cgd #define FM_T1 0x00000400 575 1.1 cgd #define FM_S7 0x00000200 576 1.1 cgd #define FM_S6 0x00000100 577 1.1 cgd #define FM_S5 0x00000080 578 1.1 cgd #define FM_S4 0x00000040 579 1.1 cgd #define FM_S3 0x00000020 580 1.1 cgd #define FM_S2 0x00000010 581 1.1 cgd #define FM_S1 0x00000008 582 1.1 cgd #define FM_S0 0x00000004 583 1.1 cgd #define FM_T0 0x00000002 584 1.1 cgd #define FM_V1 FM_T0 585 1.1 cgd #define FM_V0 0x00000001 586 1.1 cgd 587 1.17 thorpej /* Pull in PAL "function" codes. */ 588 1.17 thorpej #include <machine/pal.h> 589 1.9 cgd 590 1.1 cgd /* 591 1.9 cgd * System call glue. 592 1.1 cgd */ 593 1.9 cgd #define SYSCALLNUM(name) \ 594 1.9 cgd ___CONCAT(SYS_,name) 595 1.1 cgd 596 1.9 cgd #define CALLSYS_NOERROR(name) \ 597 1.9 cgd ldiq v0, SYSCALLNUM(name); \ 598 1.20 erh call_pal PAL_OSF1_callsys 599 1.20 erh 600 1.20 erh #define LINUX_SYSCALLNUM(name) \ 601 1.20 erh ___CONCAT(LINUX_SYS_,name) 602 1.20 erh 603 1.20 erh #define LINUX_CALLSYS_NOERROR(name) \ 604 1.20 erh ldiq v0, LINUX_SYSCALLNUM(name); \ 605 1.9 cgd call_pal PAL_OSF1_callsys 606 1.1 cgd 607 1.9 cgd /* 608 1.9 cgd * Load the global pointer. 609 1.9 cgd */ 610 1.9 cgd #define LDGP(reg) \ 611 1.9 cgd ldgp gp, 0(reg) 612 1.10 cgd 613 1.10 cgd /* 614 1.26 thorpej * WEAK_ALIAS: create a weak alias. 615 1.10 cgd */ 616 1.10 cgd #define WEAK_ALIAS(alias,sym) \ 617 1.10 cgd .weak alias; \ 618 1.10 cgd alias = sym 619 1.22 thorpej 620 1.22 thorpej /* 621 1.29 christos * STRONG_ALIAS: create a strong alias. 622 1.29 christos */ 623 1.29 christos #define STRONG_ALIAS(alias,sym) \ 624 1.29 christos .globl alias; \ 625 1.29 christos alias = sym 626 1.29 christos 627 1.29 christos /* 628 1.26 thorpej * WARN_REFERENCES: create a warning if the specified symbol is referenced. 629 1.22 thorpej */ 630 1.22 thorpej #ifdef __STDC__ 631 1.31 joerg #define WARN_REFERENCES(sym,msg) \ 632 1.31 joerg .pushsection .gnu.warning. ## sym; \ 633 1.31 joerg .ascii msg; \ 634 1.31 joerg .popsection 635 1.22 thorpej #else 636 1.31 joerg #define WARN_REFERENCES(sym,msg) \ 637 1.31 joerg .pushsection .gnu.warning./**/sym; \ 638 1.31 joerg .ascii msg; \ 639 1.31 joerg .popsection 640 1.22 thorpej #endif /* __STDC__ */ 641 1.13 cgd 642 1.13 cgd /* 643 1.13 cgd * Kernel RCS ID tag and copyright macros 644 1.13 cgd */ 645 1.34 matt #define __SECTIONSTRING(_sec, _str) \ 646 1.37 joerg .pushsection _sec,"MS",@progbits,1; \ 647 1.38 martin .asciz _str; \ 648 1.37 joerg .popsection 649 1.13 cgd 650 1.13 cgd #ifdef _KERNEL 651 1.13 cgd 652 1.46 riastrad #ifdef _NETBSD_REVISIONID 653 1.46 riastrad #define __KERNEL_RCSID(_n, _s) \ 654 1.46 riastrad __SECTIONSTRING(.ident, _s); \ 655 1.46 riastrad __SECTIONSTRING(.ident, \ 656 1.46 riastrad "$" "NetBSD: " __FILE__ " " _NETBSD_REVISIONID " $") 657 1.46 riastrad #else 658 1.34 matt #define __KERNEL_RCSID(_n, _s) __SECTIONSTRING(.ident, _s) 659 1.46 riastrad #endif 660 1.34 matt #define __KERNEL_COPYRIGHT(_n, _s) __SECTIONSTRING(.copyright, _s) 661 1.13 cgd 662 1.13 cgd #ifdef NO_KERNEL_RCSIDS 663 1.13 cgd #undef __KERNEL_RCSID 664 1.13 cgd #define __KERNEL_RCSID(_n, _s) /* nothing */ 665 1.13 cgd #endif 666 1.13 cgd 667 1.30 ad #if defined(MULTIPROCESSOR) 668 1.30 ad 669 1.30 ad /* 670 1.30 ad * Get various per-cpu values. A pointer to our cpu_info structure 671 1.30 ad * is stored in SysValue. These macros clobber v0, t0, t8..t11. 672 1.44 thorpej * SET_CURLWP also clobbers a0. 673 1.30 ad * 674 1.30 ad * All return values are in v0. 675 1.30 ad */ 676 1.30 ad #define GET_CURLWP \ 677 1.44 thorpej call_pal PAL_OSF1_rdval 678 1.41 thorpej 679 1.45 riastrad /* 680 1.45 riastrad * Issue barriers to coordinate mutex_exit on this CPU with 681 1.45 riastrad * mutex_vector_enter on another CPU. 682 1.45 riastrad * 683 1.45 riastrad * 1. Any prior mutex_exit by oldlwp must be visible to other 684 1.45 riastrad * CPUs before we set ci_curlwp := newlwp on this one, 685 1.45 riastrad * requiring a store-before-store barrier. 686 1.45 riastrad * 687 1.45 riastrad * 2. ci_curlwp := newlwp must be visible on all other CPUs 688 1.45 riastrad * before any subsequent mutex_exit by newlwp can even test 689 1.45 riastrad * whether there might be waiters, requiring a 690 1.45 riastrad * store-before-load barrier. 691 1.45 riastrad * 692 1.45 riastrad * See kern_mutex.c for details -- this is necessary for 693 1.45 riastrad * adaptive mutexes to detect whether the lwp is on the CPU in 694 1.45 riastrad * order to safely block without requiring atomic r/m/w in 695 1.45 riastrad * mutex_exit. 696 1.45 riastrad */ 697 1.41 thorpej #define SET_CURLWP(r) \ 698 1.44 thorpej ldq v0, L_CPU(r) ; \ 699 1.44 thorpej mov r, a0 ; \ 700 1.45 riastrad wmb /* store-before-store XXX patch out if !MP? */ ; \ 701 1.44 thorpej stq r, CPU_INFO_CURLWP(v0) ; \ 702 1.45 riastrad mb /* store-before-load XXX patch out if !MP? */ ; \ 703 1.44 thorpej call_pal PAL_OSF1_wrval 704 1.30 ad 705 1.30 ad #else /* if not MULTIPROCESSOR... */ 706 1.30 ad 707 1.30 ad IMPORT(cpu_info_primary, CPU_INFO_SIZEOF) 708 1.30 ad 709 1.41 thorpej #define GET_CURLWP lda v0, cpu_info_primary ; \ 710 1.41 thorpej ldq v0, CPU_INFO_CURLWP(v0) 711 1.41 thorpej 712 1.41 thorpej #define SET_CURLWP(r) lda v0, cpu_info_primary ; \ 713 1.41 thorpej stq r, CPU_INFO_CURLWP(v0) 714 1.30 ad 715 1.34 matt #endif /* MULTIPROCESSOR */ 716 1.46 riastrad 717 1.46 riastrad #else /* !_KERNEL */ 718 1.46 riastrad 719 1.46 riastrad #ifdef _NETBSD_REVISIONID 720 1.46 riastrad #define RCSID(_s) \ 721 1.46 riastrad __SECTIONSTRING(.ident, _s); \ 722 1.46 riastrad __SECTIONSTRING(.ident, \ 723 1.46 riastrad "$" "NetBSD: " __FILE__ " " _NETBSD_REVISIONID " $") 724 1.34 matt #else 725 1.34 matt #define RCSID(_s) __SECTIONSTRING(.ident, _s) 726 1.46 riastrad #endif 727 1.30 ad 728 1.13 cgd #endif /* _KERNEL */ 729