Home | History | Annotate | Line # | Download | only in include
asm.h revision 1.23.4.1
      1  1.23.4.1   thorpej /* $NetBSD: asm.h,v 1.23.4.1 2001/09/13 01:12:55 thorpej 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.23.4.1   thorpej #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.18      ross  * 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.18      ross 	.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.18      ross 	.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.18      ross 	.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.10       cgd  * WEAK_ALIAS: create a weak alias (ELF only).
    615      1.10       cgd  */
    616      1.10       cgd #ifdef __ELF__
    617      1.10       cgd #define WEAK_ALIAS(alias,sym)					\
    618      1.10       cgd 	.weak alias;						\
    619      1.10       cgd 	alias = sym
    620      1.10       cgd #endif
    621      1.22   thorpej 
    622      1.22   thorpej /*
    623      1.22   thorpej  * WARN_REFERENCES: create a warning if the specified symbol is referenced
    624      1.22   thorpej  * (ELF only).
    625      1.22   thorpej  */
    626      1.22   thorpej #ifdef __ELF__
    627      1.22   thorpej #ifdef __STDC__
    628      1.22   thorpej #define	WARN_REFERENCES(_sym,_msg)				\
    629      1.22   thorpej 	.section .gnu.warning. ## _sym ; .ascii _msg ; .text
    630      1.22   thorpej #else
    631      1.22   thorpej #define	WARN_REFERENCES(_sym,_msg)				\
    632      1.22   thorpej 	.section .gnu.warning./**/_sym ; .ascii _msg ; .text
    633      1.22   thorpej #endif /* __STDC__ */
    634      1.22   thorpej #endif /* __ELF__ */
    635      1.13       cgd 
    636      1.13       cgd /*
    637      1.13       cgd  * Kernel RCS ID tag and copyright macros
    638      1.13       cgd  */
    639      1.13       cgd 
    640      1.13       cgd #ifdef _KERNEL
    641      1.13       cgd 
    642      1.15       cgd #ifdef __ELF__
    643      1.13       cgd #define	__KERNEL_SECTIONSTRING(_sec, _str)				\
    644      1.13       cgd 	.section _sec ; .asciz _str ; .text
    645      1.15       cgd #else /* __ELF__ */
    646      1.15       cgd #define	__KERNEL_SECTIONSTRING(_sec, _str)				\
    647      1.15       cgd 	.data ; .asciz _str ; .align 3 ; .text
    648      1.15       cgd #endif /* __ELF__ */
    649      1.13       cgd 
    650      1.13       cgd #define	__KERNEL_RCSID(_n, _s)		__KERNEL_SECTIONSTRING(.ident, _s)
    651      1.13       cgd #define	__KERNEL_COPYRIGHT(_n, _s)	__KERNEL_SECTIONSTRING(.copyright, _s)
    652      1.13       cgd 
    653      1.13       cgd #ifdef NO_KERNEL_RCSIDS
    654      1.13       cgd #undef __KERNEL_RCSID
    655      1.13       cgd #define	__KERNEL_RCSID(_n, _s)		/* nothing */
    656      1.13       cgd #endif
    657      1.13       cgd 
    658      1.13       cgd #endif /* _KERNEL */
    659