Home | History | Annotate | Line # | Download | only in include
asm.h revision 1.26.16.3
      1  1.26.16.3     skrll /* $NetBSD: asm.h,v 1.26.16.3 2004/09/21 13:11:48 skrll Exp $ */
      2        1.1       cgd 
      3        1.1       cgd /*
      4        1.4       cgd  * Copyright (c) 1991,1990,1989,1994,1995,1996 Carnegie Mellon University
      5        1.1       cgd  * All Rights Reserved.
      6        1.1       cgd  *
      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.1       cgd  *
     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.1       cgd  *
     17        1.1       cgd  * Carnegie Mellon requests users of this software to return to
     18        1.1       cgd  *
     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.1       cgd  *
     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.26.16.1     skrll  * 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.26   thorpej  * WARN_REFERENCES: create a warning if the specified symbol is referenced.
    622       1.22   thorpej  */
    623       1.22   thorpej #ifdef __STDC__
    624       1.22   thorpej #define	WARN_REFERENCES(_sym,_msg)				\
    625       1.22   thorpej 	.section .gnu.warning. ## _sym ; .ascii _msg ; .text
    626       1.22   thorpej #else
    627       1.22   thorpej #define	WARN_REFERENCES(_sym,_msg)				\
    628       1.22   thorpej 	.section .gnu.warning./**/_sym ; .ascii _msg ; .text
    629       1.22   thorpej #endif /* __STDC__ */
    630       1.13       cgd 
    631       1.13       cgd /*
    632       1.13       cgd  * Kernel RCS ID tag and copyright macros
    633       1.13       cgd  */
    634       1.13       cgd 
    635       1.13       cgd #ifdef _KERNEL
    636       1.13       cgd 
    637       1.13       cgd #define	__KERNEL_SECTIONSTRING(_sec, _str)				\
    638       1.13       cgd 	.section _sec ; .asciz _str ; .text
    639       1.13       cgd 
    640       1.13       cgd #define	__KERNEL_RCSID(_n, _s)		__KERNEL_SECTIONSTRING(.ident, _s)
    641       1.13       cgd #define	__KERNEL_COPYRIGHT(_n, _s)	__KERNEL_SECTIONSTRING(.copyright, _s)
    642       1.13       cgd 
    643       1.13       cgd #ifdef NO_KERNEL_RCSIDS
    644       1.13       cgd #undef __KERNEL_RCSID
    645       1.13       cgd #define	__KERNEL_RCSID(_n, _s)		/* nothing */
    646       1.13       cgd #endif
    647       1.13       cgd 
    648       1.13       cgd #endif /* _KERNEL */
    649