asm.h revision 1.41 1 1.41 thorpej /* $NetBSD: asm.h,v 1.41 2020/09/04 02:54:56 thorpej 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.34 matt #define __KERNEL_RCSID(_n, _s) __SECTIONSTRING(.ident, _s)
653 1.34 matt #define __KERNEL_COPYRIGHT(_n, _s) __SECTIONSTRING(.copyright, _s)
654 1.13 cgd
655 1.13 cgd #ifdef NO_KERNEL_RCSIDS
656 1.13 cgd #undef __KERNEL_RCSID
657 1.13 cgd #define __KERNEL_RCSID(_n, _s) /* nothing */
658 1.13 cgd #endif
659 1.13 cgd
660 1.30 ad #if defined(MULTIPROCESSOR)
661 1.30 ad
662 1.30 ad /*
663 1.30 ad * Get various per-cpu values. A pointer to our cpu_info structure
664 1.30 ad * is stored in SysValue. These macros clobber v0, t0, t8..t11.
665 1.30 ad *
666 1.30 ad * All return values are in v0.
667 1.30 ad */
668 1.30 ad #define GET_CPUINFO call_pal PAL_OSF1_rdval
669 1.30 ad
670 1.30 ad #define GET_CURLWP \
671 1.30 ad call_pal PAL_OSF1_rdval ; \
672 1.41 thorpej ldq v0, CPU_INFO_CURLWP(v0)
673 1.41 thorpej
674 1.41 thorpej #define SET_CURLWP(r) \
675 1.41 thorpej call_pal PAL_OSF1_rdval ; \
676 1.41 thorpej stq r, CPU_INFO_CURLWP(v0)
677 1.30 ad
678 1.30 ad #define GET_FPCURLWP \
679 1.30 ad call_pal PAL_OSF1_rdval ; \
680 1.30 ad addq v0, CPU_INFO_FPCURLWP, v0
681 1.30 ad
682 1.30 ad #else /* if not MULTIPROCESSOR... */
683 1.30 ad
684 1.30 ad IMPORT(cpu_info_primary, CPU_INFO_SIZEOF)
685 1.30 ad
686 1.30 ad #define GET_CPUINFO lda v0, cpu_info_primary
687 1.30 ad
688 1.41 thorpej #define GET_CURLWP lda v0, cpu_info_primary ; \
689 1.41 thorpej ldq v0, CPU_INFO_CURLWP(v0)
690 1.41 thorpej
691 1.41 thorpej #define SET_CURLWP(r) lda v0, cpu_info_primary ; \
692 1.41 thorpej stq r, CPU_INFO_CURLWP(v0)
693 1.30 ad
694 1.34 matt #endif /* MULTIPROCESSOR */
695 1.34 matt #else
696 1.34 matt #define RCSID(_s) __SECTIONSTRING(.ident, _s)
697 1.30 ad
698 1.13 cgd #endif /* _KERNEL */
699