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