asm.h revision 1.35 1 1.35 martin /* $NetBSD: asm.h,v 1.35 2017/01/14 16:15:10 martin 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.35 martin #undef __CONCAT
137 1.9 cgd #ifdef __STDC__
138 1.9 cgd #define __CONCAT(a,b) a ## b
139 1.9 cgd #else
140 1.9 cgd #define __CONCAT(a,b) a/**/b
141 1.9 cgd #endif
142 1.9 cgd #define ___CONCAT(a,b) __CONCAT(a,b)
143 1.9 cgd
144 1.9 cgd /*
145 1.9 cgd * Macro to make a local label name.
146 1.9 cgd */
147 1.9 cgd #define LLABEL(name,num) ___CONCAT(___CONCAT(L,name),num)
148 1.9 cgd
149 1.1 cgd /*
150 1.1 cgd *
151 1.1 cgd * Debuggers need symbol table information to be able to properly
152 1.1 cgd * decode a stack trace. The minimum that should be provided is:
153 1.1 cgd *
154 1.1 cgd * name:
155 1.1 cgd * .proc name,numargs
156 1.1 cgd *
157 1.1 cgd * where "name" is the function's name;
158 1.1 cgd * "numargs" how many arguments it expects. For varargs
159 1.1 cgd * procedures this should be a negative number,
160 1.1 cgd * indicating the minimum required number of
161 1.1 cgd * arguments (which is at least 1);
162 1.1 cgd *
163 1.1 cgd * NESTED functions (functions that call other functions) should define
164 1.1 cgd * how they handle their stack frame in a .frame directive:
165 1.1 cgd *
166 1.1 cgd * .frame framesize, pc_reg, i_mask, f_mask
167 1.1 cgd *
168 1.1 cgd * where "framesize" is the size of the frame for this function, in bytes.
169 1.1 cgd * That is:
170 1.1 cgd * new_sp + framesize == old_sp
171 1.1 cgd * Framesizes should be rounded to a cacheline size.
172 1.1 cgd * Note that old_sp plays the role of a conventional
173 1.1 cgd * "frame pointer";
174 1.1 cgd * "pc_reg" is either a register which preserves the caller's PC
175 1.1 cgd * or 'std', if std the saved PC should be stored at
176 1.1 cgd * old_sp-8
177 1.1 cgd * "i_mask" is a bitmask that indicates which of the integer
178 1.1 cgd * registers are saved. See the M_xx defines at the
179 1.1 cgd * end for the encoding of this 32bit value.
180 1.1 cgd * "f_mask" is the same, for floating point registers.
181 1.1 cgd *
182 1.18 ross * Note, 10/31/97: This is interesting but it isn't the way gcc outputs
183 1.18 ross * frame directives and it isn't the way the macros below output them
184 1.18 ross * either. Frame directives look like this:
185 1.18 ross *
186 1.18 ross * .frame $15,framesize,$26,0
187 1.18 ross *
188 1.18 ross * If no fp is set up then $30 should be used instead of $15.
189 1.18 ross * Also, gdb expects to find a <lda sp,-framesize(sp)> at the beginning
190 1.18 ross * of a procedure. Don't use things like sub sp,framesize,sp for this
191 1.27 keihan * reason. End Note 10/31/97. ross (at) NetBSD.org
192 1.18 ross *
193 1.1 cgd * Note that registers should be saved starting at "old_sp-8", where the
194 1.1 cgd * return address should be stored. Other registers follow at -16-24-32..
195 1.1 cgd * starting from register 0 (if saved) and up. Then float registers (ifany)
196 1.1 cgd * are saved.
197 1.1 cgd *
198 1.1 cgd * If you need to alias a leaf function, or to provide multiple entry points
199 1.1 cgd * use the LEAF() macro for the main entry point and XLEAF() for the other
200 1.1 cgd * additional/alternate entry points.
201 1.1 cgd * "XLEAF"s must be nested within a "LEAF" and a ".end".
202 1.1 cgd * Similar rules for nested routines, e.g. use NESTED/XNESTED
203 1.1 cgd * Symbols that should not be exported can be declared with the STATIC_xxx
204 1.1 cgd * macros.
205 1.1 cgd *
206 1.1 cgd * All functions must be terminated by the END macro
207 1.1 cgd *
208 1.1 cgd * It is conceivable, although currently at the limits of compiler
209 1.1 cgd * technology, that while performing inter-procedural optimizations
210 1.1 cgd * the compiler/linker be able to avoid unnecessary register spills
211 1.1 cgd * if told about the register usage of LEAF procedures (and by transitive
212 1.1 cgd * closure of NESTED procedures as well). Assembly code can help
213 1.1 cgd * this process using the .reguse directive:
214 1.1 cgd *
215 1.1 cgd * .reguse i_mask, f_mask
216 1.1 cgd *
217 1.1 cgd * where the register masks are built as above or-ing M_xx defines.
218 1.1 cgd *
219 1.1 cgd *
220 1.1 cgd * All symbols are internal unless EXPORTed. Symbols that are IMPORTed
221 1.1 cgd * must be appropriately described to the debugger.
222 1.1 cgd *
223 1.1 cgd */
224 1.1 cgd
225 1.1 cgd /*
226 1.2 cgd * MCOUNT
227 1.2 cgd */
228 1.2 cgd
229 1.11 jtc #ifndef GPROF
230 1.2 cgd #define MCOUNT /* nothing */
231 1.2 cgd #else
232 1.2 cgd #define MCOUNT \
233 1.6 cgd .set noat; \
234 1.6 cgd jsr at_reg,_mcount; \
235 1.6 cgd .set at
236 1.2 cgd #endif
237 1.18 ross /*
238 1.18 ross * PALVECT, ESETUP, and ERSAVE
239 1.18 ross * Declare a palcode transfer point, and carefully construct
240 1.18 ross * gdb symbols with an unusual _negative_ register-save offset
241 1.18 ross * so that gdb can find the otherwise lost PC and then
242 1.18 ross * invert the vector for traceback. Also, fix up framesize,
243 1.18 ross * allowing for the palframe for the same reason.
244 1.18 ross */
245 1.18 ross
246 1.18 ross #define PALVECT(_name_) \
247 1.18 ross ESETUP(_name_); \
248 1.18 ross ERSAVE()
249 1.18 ross
250 1.18 ross #define ESETUP(_name_) \
251 1.25 thorpej /* .loc 1 __LINE__; */ \
252 1.18 ross .globl _name_; \
253 1.18 ross .ent _name_ 0; \
254 1.18 ross _name_:; \
255 1.18 ross .set noat; \
256 1.18 ross lda sp,-(FRAME_SW_SIZE*8)(sp); \
257 1.18 ross .frame $30,(FRAME_SW_SIZE+6)*8,$26,0; /* give gdb the real size */\
258 1.18 ross .mask 0x4000000,-0x28; \
259 1.18 ross .set at
260 1.18 ross
261 1.18 ross #define ERSAVE() \
262 1.18 ross .set noat; \
263 1.18 ross stq at_reg,(FRAME_AT*8)(sp); \
264 1.18 ross .set at; \
265 1.18 ross stq ra,(FRAME_RA*8)(sp); \
266 1.25 thorpej /* .loc 1 __LINE__; */ \
267 1.18 ross bsr ra,exception_save_regs /* jmp/CALL trashes pv/t12 */
268 1.18 ross
269 1.2 cgd
270 1.2 cgd /*
271 1.1 cgd * LEAF
272 1.1 cgd * Declare a global leaf function.
273 1.1 cgd * A leaf function does not call other functions AND does not
274 1.1 cgd * use any register that is callee-saved AND does not modify
275 1.1 cgd * the stack pointer.
276 1.1 cgd */
277 1.1 cgd #define LEAF(_name_,_n_args_) \
278 1.1 cgd .globl _name_; \
279 1.1 cgd .ent _name_ 0; \
280 1.1 cgd _name_:; \
281 1.2 cgd .frame sp,0,ra; \
282 1.2 cgd MCOUNT
283 1.2 cgd /* should have been
284 1.2 cgd .proc _name_,_n_args_; \
285 1.2 cgd .frame 0,ra,0,0
286 1.2 cgd */
287 1.2 cgd
288 1.2 cgd #define LEAF_NOPROFILE(_name_,_n_args_) \
289 1.2 cgd .globl _name_; \
290 1.2 cgd .ent _name_ 0; \
291 1.2 cgd _name_:; \
292 1.1 cgd .frame sp,0,ra
293 1.1 cgd /* should have been
294 1.1 cgd .proc _name_,_n_args_; \
295 1.1 cgd .frame 0,ra,0,0
296 1.1 cgd */
297 1.1 cgd
298 1.1 cgd /*
299 1.1 cgd * STATIC_LEAF
300 1.1 cgd * Declare a local leaf function.
301 1.1 cgd */
302 1.1 cgd #define STATIC_LEAF(_name_,_n_args_) \
303 1.1 cgd .ent _name_ 0; \
304 1.1 cgd _name_:; \
305 1.2 cgd .frame sp,0,ra; \
306 1.2 cgd MCOUNT
307 1.1 cgd /* should have been
308 1.1 cgd .proc _name_,_n_args_; \
309 1.1 cgd .frame 0,ra,0,0
310 1.1 cgd */
311 1.1 cgd /*
312 1.1 cgd * XLEAF
313 1.1 cgd * Global alias for a leaf function, or alternate entry point
314 1.1 cgd */
315 1.1 cgd #define XLEAF(_name_,_n_args_) \
316 1.1 cgd .globl _name_; \
317 1.1 cgd .aent _name_ 0; \
318 1.1 cgd _name_:
319 1.1 cgd /* should have been
320 1.1 cgd .aproc _name_,_n_args_;
321 1.1 cgd */
322 1.1 cgd
323 1.1 cgd /*
324 1.1 cgd * STATIC_XLEAF
325 1.1 cgd * Local alias for a leaf function, or alternate entry point
326 1.1 cgd */
327 1.1 cgd #define STATIC_XLEAF(_name_,_n_args_) \
328 1.1 cgd .aent _name_ 0; \
329 1.1 cgd _name_:
330 1.1 cgd /* should have been
331 1.1 cgd .aproc _name_,_n_args_;
332 1.1 cgd */
333 1.1 cgd
334 1.1 cgd /*
335 1.1 cgd * NESTED
336 1.1 cgd * Declare a (global) nested function
337 1.1 cgd * A nested function calls other functions and needs
338 1.1 cgd * therefore stack space to save/restore registers.
339 1.1 cgd */
340 1.1 cgd #define NESTED(_name_, _n_args_, _framesize_, _pc_reg_, _i_mask_, _f_mask_ ) \
341 1.1 cgd .globl _name_; \
342 1.1 cgd .ent _name_ 0; \
343 1.1 cgd _name_:; \
344 1.1 cgd .frame sp,_framesize_,_pc_reg_; \
345 1.2 cgd .livereg _i_mask_,_f_mask_; \
346 1.2 cgd MCOUNT
347 1.2 cgd /* should have been
348 1.2 cgd .proc _name_,_n_args_; \
349 1.2 cgd .frame _framesize_, _pc_reg_, _i_mask_, _f_mask_
350 1.2 cgd */
351 1.2 cgd
352 1.2 cgd #define NESTED_NOPROFILE(_name_, _n_args_, _framesize_, _pc_reg_, _i_mask_, _f_mask_ ) \
353 1.2 cgd .globl _name_; \
354 1.2 cgd .ent _name_ 0; \
355 1.2 cgd _name_:; \
356 1.2 cgd .frame sp,_framesize_,_pc_reg_; \
357 1.1 cgd .livereg _i_mask_,_f_mask_
358 1.1 cgd /* should have been
359 1.1 cgd .proc _name_,_n_args_; \
360 1.1 cgd .frame _framesize_, _pc_reg_, _i_mask_, _f_mask_
361 1.1 cgd */
362 1.1 cgd
363 1.1 cgd /*
364 1.1 cgd * STATIC_NESTED
365 1.1 cgd * Declare a local nested function.
366 1.1 cgd */
367 1.1 cgd #define STATIC_NESTED(_name_, _n_args_, _framesize_, _pc_reg_, _i_mask_, _f_mask_ ) \
368 1.1 cgd .ent _name_ 0; \
369 1.1 cgd _name_:; \
370 1.1 cgd .frame sp,_framesize_,_pc_reg_; \
371 1.2 cgd .livereg _i_mask_,_f_mask_; \
372 1.2 cgd MCOUNT
373 1.1 cgd /* should have been
374 1.1 cgd .proc _name_,_n_args_; \
375 1.1 cgd .frame _framesize_, _pc_reg_, _i_mask_, _f_mask_
376 1.1 cgd */
377 1.1 cgd
378 1.1 cgd /*
379 1.1 cgd * XNESTED
380 1.1 cgd * Same as XLEAF, for a nested function.
381 1.1 cgd */
382 1.1 cgd #define XNESTED(_name_,_n_args_) \
383 1.1 cgd .globl _name_; \
384 1.1 cgd .aent _name_ 0; \
385 1.1 cgd _name_:
386 1.1 cgd /* should have been
387 1.1 cgd .aproc _name_,_n_args_;
388 1.1 cgd */
389 1.1 cgd
390 1.1 cgd
391 1.1 cgd /*
392 1.1 cgd * STATIC_XNESTED
393 1.1 cgd * Same as STATIC_XLEAF, for a nested function.
394 1.1 cgd */
395 1.1 cgd #define STATIC_XNESTED(_name_,_n_args_) \
396 1.1 cgd .aent _name_ 0; \
397 1.1 cgd _name_:
398 1.1 cgd /* should have been
399 1.1 cgd .aproc _name_,_n_args_;
400 1.1 cgd */
401 1.1 cgd
402 1.1 cgd
403 1.1 cgd /*
404 1.1 cgd * END
405 1.1 cgd * Function delimiter
406 1.1 cgd */
407 1.1 cgd #define END(_name_) \
408 1.1 cgd .end _name_
409 1.1 cgd
410 1.1 cgd
411 1.1 cgd /*
412 1.1 cgd * CALL
413 1.1 cgd * Function invocation
414 1.1 cgd */
415 1.1 cgd #define CALL(_name_) \
416 1.25 thorpej /* .loc 1 __LINE__; */ \
417 1.1 cgd jsr ra,_name_; \
418 1.1 cgd ldgp gp,0(ra)
419 1.1 cgd /* but this would cover longer jumps
420 1.1 cgd br ra,.+4; \
421 1.1 cgd bsr ra,_name_
422 1.1 cgd */
423 1.1 cgd
424 1.1 cgd
425 1.1 cgd /*
426 1.1 cgd * RET
427 1.1 cgd * Return from function
428 1.1 cgd */
429 1.1 cgd #define RET \
430 1.1 cgd ret zero,(ra),1
431 1.1 cgd
432 1.1 cgd
433 1.1 cgd /*
434 1.1 cgd * EXPORT
435 1.1 cgd * Export a symbol
436 1.1 cgd */
437 1.1 cgd #define EXPORT(_name_) \
438 1.1 cgd .globl _name_; \
439 1.1 cgd _name_:
440 1.1 cgd
441 1.1 cgd
442 1.1 cgd /*
443 1.1 cgd * IMPORT
444 1.1 cgd * Make an external name visible, typecheck the size
445 1.1 cgd */
446 1.1 cgd #define IMPORT(_name_, _size_) \
447 1.1 cgd .extern _name_,_size_
448 1.1 cgd
449 1.1 cgd
450 1.1 cgd /*
451 1.1 cgd * ABS
452 1.1 cgd * Define an absolute symbol
453 1.1 cgd */
454 1.1 cgd #define ABS(_name_, _value_) \
455 1.1 cgd .globl _name_; \
456 1.1 cgd _name_ = _value_
457 1.1 cgd
458 1.1 cgd
459 1.1 cgd /*
460 1.1 cgd * BSS
461 1.1 cgd * Allocate un-initialized space for a global symbol
462 1.1 cgd */
463 1.1 cgd #define BSS(_name_,_numbytes_) \
464 1.1 cgd .comm _name_,_numbytes_
465 1.1 cgd
466 1.1 cgd /*
467 1.1 cgd * VECTOR
468 1.1 cgd * Make an exception entry point look like a called function,
469 1.1 cgd * to make it digestible to the debugger (KERNEL only)
470 1.1 cgd */
471 1.1 cgd #define VECTOR(_name_, _i_mask_) \
472 1.1 cgd .globl _name_; \
473 1.1 cgd .ent _name_ 0; \
474 1.1 cgd _name_:; \
475 1.1 cgd .mask _i_mask_|IM_EXC,0; \
476 1.1 cgd .frame sp,MSS_SIZE,ra;
477 1.19 ross /* .livereg _i_mask_|IM_EXC,0 */
478 1.1 cgd /* should have been
479 1.1 cgd .proc _name_,1; \
480 1.1 cgd .frame MSS_SIZE,$31,_i_mask_,0; \
481 1.1 cgd */
482 1.1 cgd
483 1.1 cgd /*
484 1.1 cgd * MSG
485 1.1 cgd * Allocate space for a message (a read-only ascii string)
486 1.1 cgd */
487 1.1 cgd #define ASCIZ .asciz
488 1.6 cgd #define MSG(msg,reg,label) \
489 1.6 cgd lda reg, label; \
490 1.1 cgd .data; \
491 1.6 cgd label: ASCIZ msg; \
492 1.1 cgd .text;
493 1.1 cgd
494 1.1 cgd /*
495 1.1 cgd * PRINTF
496 1.1 cgd * Print a message
497 1.1 cgd */
498 1.6 cgd #define PRINTF(msg,label) \
499 1.6 cgd MSG(msg,a0,label); \
500 1.8 christos CALL(printf)
501 1.1 cgd
502 1.1 cgd /*
503 1.1 cgd * PANIC
504 1.1 cgd * Fatal error (KERNEL)
505 1.1 cgd */
506 1.6 cgd #define PANIC(msg,label) \
507 1.6 cgd MSG(msg,a0,label); \
508 1.1 cgd CALL(panic)
509 1.1 cgd
510 1.1 cgd /*
511 1.1 cgd * Register mask defines, used to define both save
512 1.1 cgd * and use register sets.
513 1.1 cgd *
514 1.1 cgd * NOTE: The bit order should HAVE BEEN maintained when saving
515 1.1 cgd * registers on the stack: sp goes at the highest
516 1.1 cgd * address, gp lower on the stack, etc etc
517 1.1 cgd * BUT NOONE CARES ABOUT DEBUGGERS AT MIPS
518 1.1 cgd */
519 1.1 cgd
520 1.1 cgd #define IM_EXC 0x80000000
521 1.1 cgd #define IM_SP 0x40000000
522 1.1 cgd #define IM_GP 0x20000000
523 1.1 cgd #define IM_AT 0x10000000
524 1.1 cgd #define IM_T12 0x08000000
525 1.1 cgd # define IM_PV IM_T4
526 1.1 cgd #define IM_RA 0x04000000
527 1.1 cgd #define IM_T11 0x02000000
528 1.1 cgd # define IM_AI IM_T3
529 1.1 cgd #define IM_T10 0x01000000
530 1.1 cgd #define IM_T9 0x00800000
531 1.1 cgd #define IM_T8 0x00400000
532 1.1 cgd #define IM_A5 0x00200000
533 1.1 cgd #define IM_A4 0x00100000
534 1.1 cgd #define IM_A3 0x00080000
535 1.1 cgd #define IM_A2 0x00040000
536 1.1 cgd #define IM_A1 0x00020000
537 1.1 cgd #define IM_A0 0x00010000
538 1.1 cgd #define IM_S6 0x00008000
539 1.1 cgd #define IM_S5 0x00004000
540 1.1 cgd #define IM_S4 0x00002000
541 1.1 cgd #define IM_S3 0x00001000
542 1.1 cgd #define IM_S2 0x00000800
543 1.1 cgd #define IM_S1 0x00000400
544 1.1 cgd #define IM_S0 0x00000200
545 1.1 cgd #define IM_T7 0x00000100
546 1.1 cgd #define IM_T6 0x00000080
547 1.1 cgd #define IM_T5 0x00000040
548 1.1 cgd #define IM_T4 0x00000020
549 1.1 cgd #define IM_T3 0x00000010
550 1.1 cgd #define IM_T2 0x00000008
551 1.1 cgd #define IM_T1 0x00000004
552 1.1 cgd #define IM_T0 0x00000002
553 1.1 cgd #define IM_V0 0x00000001
554 1.1 cgd
555 1.1 cgd #define FM_T15 0x40000000
556 1.1 cgd #define FM_T14 0x20000000
557 1.1 cgd #define FM_T13 0x10000000
558 1.1 cgd #define FM_T12 0x08000000
559 1.1 cgd #define FM_T11 0x04000000
560 1.1 cgd #define FM_T10 0x02000000
561 1.1 cgd #define FM_T9 0x01000000
562 1.1 cgd #define FM_T8 0x00800000
563 1.1 cgd #define FM_T7 0x00400000
564 1.1 cgd #define FM_A5 0x00200000
565 1.1 cgd #define FM_A4 0x00100000
566 1.1 cgd #define FM_A3 0x00080000
567 1.1 cgd #define FM_A2 0x00040000
568 1.1 cgd #define FM_A1 0x00020000
569 1.1 cgd #define FM_A0 0x00010000
570 1.1 cgd #define FM_T6 0x00008000
571 1.1 cgd #define FM_T5 0x00004000
572 1.1 cgd #define FM_T4 0x00002000
573 1.1 cgd #define FM_T3 0x00001000
574 1.1 cgd #define FM_T2 0x00000800
575 1.1 cgd #define FM_T1 0x00000400
576 1.1 cgd #define FM_S7 0x00000200
577 1.1 cgd #define FM_S6 0x00000100
578 1.1 cgd #define FM_S5 0x00000080
579 1.1 cgd #define FM_S4 0x00000040
580 1.1 cgd #define FM_S3 0x00000020
581 1.1 cgd #define FM_S2 0x00000010
582 1.1 cgd #define FM_S1 0x00000008
583 1.1 cgd #define FM_S0 0x00000004
584 1.1 cgd #define FM_T0 0x00000002
585 1.1 cgd #define FM_V1 FM_T0
586 1.1 cgd #define FM_V0 0x00000001
587 1.1 cgd
588 1.17 thorpej /* Pull in PAL "function" codes. */
589 1.17 thorpej #include <machine/pal.h>
590 1.9 cgd
591 1.1 cgd /*
592 1.9 cgd * System call glue.
593 1.1 cgd */
594 1.9 cgd #define SYSCALLNUM(name) \
595 1.9 cgd ___CONCAT(SYS_,name)
596 1.1 cgd
597 1.9 cgd #define CALLSYS_NOERROR(name) \
598 1.9 cgd ldiq v0, SYSCALLNUM(name); \
599 1.20 erh call_pal PAL_OSF1_callsys
600 1.20 erh
601 1.20 erh #define LINUX_SYSCALLNUM(name) \
602 1.20 erh ___CONCAT(LINUX_SYS_,name)
603 1.20 erh
604 1.20 erh #define LINUX_CALLSYS_NOERROR(name) \
605 1.20 erh ldiq v0, LINUX_SYSCALLNUM(name); \
606 1.9 cgd call_pal PAL_OSF1_callsys
607 1.1 cgd
608 1.9 cgd /*
609 1.9 cgd * Load the global pointer.
610 1.9 cgd */
611 1.9 cgd #define LDGP(reg) \
612 1.9 cgd ldgp gp, 0(reg)
613 1.10 cgd
614 1.10 cgd /*
615 1.26 thorpej * WEAK_ALIAS: create a weak alias.
616 1.10 cgd */
617 1.10 cgd #define WEAK_ALIAS(alias,sym) \
618 1.10 cgd .weak alias; \
619 1.10 cgd alias = sym
620 1.22 thorpej
621 1.22 thorpej /*
622 1.29 christos * STRONG_ALIAS: create a strong alias.
623 1.29 christos */
624 1.29 christos #define STRONG_ALIAS(alias,sym) \
625 1.29 christos .globl alias; \
626 1.29 christos alias = sym
627 1.29 christos
628 1.29 christos /*
629 1.26 thorpej * WARN_REFERENCES: create a warning if the specified symbol is referenced.
630 1.22 thorpej */
631 1.22 thorpej #ifdef __STDC__
632 1.31 joerg #define WARN_REFERENCES(sym,msg) \
633 1.31 joerg .pushsection .gnu.warning. ## sym; \
634 1.31 joerg .ascii msg; \
635 1.31 joerg .popsection
636 1.22 thorpej #else
637 1.31 joerg #define WARN_REFERENCES(sym,msg) \
638 1.31 joerg .pushsection .gnu.warning./**/sym; \
639 1.31 joerg .ascii msg; \
640 1.31 joerg .popsection
641 1.22 thorpej #endif /* __STDC__ */
642 1.13 cgd
643 1.13 cgd /*
644 1.13 cgd * Kernel RCS ID tag and copyright macros
645 1.13 cgd */
646 1.35 martin #undef __SECTIONSTRING
647 1.34 matt #define __SECTIONSTRING(_sec, _str) \
648 1.34 matt .pushsection _sec ; .asciz _str ; .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.30 ad addq v0, CPU_INFO_CURLWP, v0
673 1.30 ad
674 1.30 ad #define GET_FPCURLWP \
675 1.30 ad call_pal PAL_OSF1_rdval ; \
676 1.30 ad addq v0, CPU_INFO_FPCURLWP, v0
677 1.30 ad
678 1.30 ad #define GET_CURPCB \
679 1.30 ad call_pal PAL_OSF1_rdval ; \
680 1.30 ad addq v0, CPU_INFO_CURPCB, v0
681 1.30 ad
682 1.30 ad #define GET_IDLE_PCB(reg) \
683 1.30 ad call_pal PAL_OSF1_rdval ; \
684 1.30 ad ldq reg, CPU_INFO_IDLE_PCB_PADDR(v0)
685 1.30 ad
686 1.30 ad #else /* if not MULTIPROCESSOR... */
687 1.30 ad
688 1.30 ad IMPORT(cpu_info_primary, CPU_INFO_SIZEOF)
689 1.30 ad
690 1.30 ad #define GET_CPUINFO lda v0, cpu_info_primary
691 1.30 ad
692 1.30 ad #define GET_CURLWP lda v0, cpu_info_primary + CPU_INFO_CURLWP
693 1.30 ad
694 1.30 ad #define GET_FPCURLWP lda v0, cpu_info_primary + CPU_INFO_FPCURLWP
695 1.30 ad
696 1.30 ad #define GET_CURPCB lda v0, cpu_info_primary + CPU_INFO_CURPCB
697 1.30 ad
698 1.30 ad #define GET_IDLE_PCB(reg) \
699 1.30 ad lda reg, cpu_info_primary ; \
700 1.30 ad ldq reg, CPU_INFO_IDLE_PCB_PADDR(reg)
701 1.34 matt #endif /* MULTIPROCESSOR */
702 1.34 matt #else
703 1.34 matt #define RCSID(_s) __SECTIONSTRING(.ident, _s)
704 1.30 ad
705 1.13 cgd #endif /* _KERNEL */
706