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