Home | History | Annotate | Line # | Download | only in include
      1  1.46  riastrad /* $NetBSD: asm.h,v 1.46 2024/06/09 22:35:37 riastradh Exp $ */
      2   1.1       cgd 
      3  1.33      matt /*
      4   1.4       cgd  * Copyright (c) 1991,1990,1989,1994,1995,1996 Carnegie Mellon University
      5   1.1       cgd  * All Rights Reserved.
      6  1.33      matt  *
      7   1.1       cgd  * Permission to use, copy, modify and distribute this software and its
      8   1.1       cgd  * documentation is hereby granted, provided that both the copyright
      9   1.1       cgd  * notice and this permission notice appear in all copies of the
     10   1.1       cgd  * software, derivative works or modified versions, and any portions
     11   1.1       cgd  * thereof, and that both notices appear in supporting documentation.
     12  1.33      matt  *
     13   1.1       cgd  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     14   1.1       cgd  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
     15   1.1       cgd  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     16  1.33      matt  *
     17   1.1       cgd  * Carnegie Mellon requests users of this software to return to
     18  1.33      matt  *
     19   1.1       cgd  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     20   1.1       cgd  *  School of Computer Science
     21   1.1       cgd  *  Carnegie Mellon University
     22   1.1       cgd  *  Pittsburgh PA 15213-3890
     23  1.33      matt  *
     24   1.1       cgd  * any improvements or extensions that they make and grant Carnegie Mellon
     25   1.1       cgd  * the rights to redistribute these changes.
     26   1.1       cgd  */
     27   1.1       cgd 
     28   1.1       cgd /*
     29   1.1       cgd  *	Assembly coding style
     30   1.1       cgd  *
     31   1.1       cgd  *	This file contains macros and register defines to
     32   1.1       cgd  *	aid in writing more readable assembly code.
     33   1.1       cgd  *	Some rules to make assembly code understandable by
     34   1.1       cgd  *	a debugger are also noted.
     35   1.1       cgd  *
     36   1.1       cgd  *	The document
     37   1.1       cgd  *
     38   1.1       cgd  *		"ALPHA Calling Standard", DEC 27-Apr-90
     39   1.1       cgd  *
     40   1.1       cgd  *	defines (a superset of) the rules and conventions
     41   1.1       cgd  *	we use.  While we make no promise of adhering to
     42   1.1       cgd  *	such standard and its evolution (esp where we
     43   1.1       cgd  *	can get faster code paths) it is certainly intended
     44   1.1       cgd  *	that we be interoperable with such standard.
     45   1.1       cgd  *
     46   1.1       cgd  *	In this sense, this file is a proper part of the
     47   1.1       cgd  *	definition of the (software) Alpha architecture.
     48   1.1       cgd  */
     49   1.1       cgd 
     50   1.1       cgd /*
     51   1.1       cgd  *	Symbolic register names and register saving rules
     52   1.1       cgd  *
     53   1.1       cgd  *	Legend:
     54   1.1       cgd  *		T	Saved by caller (Temporaries)
     55   1.1       cgd  *		S	Saved by callee (call-Safe registers)
     56   1.1       cgd  */
     57   1.1       cgd 
     58   1.1       cgd #define	v0	$0	/* (T)		return value		*/
     59   1.1       cgd #define t0	$1	/* (T)		temporary registers	*/
     60   1.1       cgd #define t1	$2
     61   1.1       cgd #define t2	$3
     62   1.1       cgd #define t3	$4
     63   1.1       cgd #define t4	$5
     64   1.1       cgd #define t5	$6
     65   1.1       cgd #define t6	$7
     66   1.1       cgd #define t7	$8
     67   1.1       cgd 
     68   1.1       cgd #define s0	$9	/* (S)		call-safe registers	*/
     69   1.1       cgd #define s1	$10
     70   1.1       cgd #define s2	$11
     71   1.1       cgd #define s3	$12
     72   1.1       cgd #define s4	$13
     73   1.1       cgd #define s5	$14
     74   1.1       cgd #define s6	$15
     75   1.1       cgd #define a0	$16	/* (T)		argument registers	*/
     76   1.1       cgd #define a1	$17
     77   1.1       cgd #define a2	$18
     78   1.1       cgd #define a3	$19
     79   1.1       cgd #define a4	$20
     80   1.1       cgd #define a5	$21
     81   1.1       cgd #define t8	$22	/* (T)		temporary registers	*/
     82   1.1       cgd #define t9	$23
     83   1.1       cgd #define t10	$24
     84   1.1       cgd #define t11	$25
     85  1.24   nathanw #define ra	$26	/* (S)		return address		*/
     86   1.1       cgd #define t12	$27	/* (T)		another temporary	*/
     87   1.1       cgd #define at_reg	$28	/* (T)		assembler scratch	*/
     88   1.1       cgd #define	gp	$29	/* (T)		(local) data pointer	*/
     89   1.1       cgd #define sp	$30	/* (S)		stack pointer		*/
     90   1.1       cgd #define zero	$31	/* 		wired zero		*/
     91   1.1       cgd 
     92   1.1       cgd /* Floating point registers  (XXXX VERIFY THIS) */
     93   1.1       cgd #define	fv0	$f0	/* (T)		return value (real)	*/
     94   1.1       cgd #define	fv1	$f1	/* (T)		return value (imaginary)*/
     95   1.1       cgd #define	ft0	fv1
     96   1.1       cgd #define	fs0	$f2	/* (S)		call-safe registers	*/
     97   1.1       cgd #define	fs1	$f3
     98   1.1       cgd #define	fs2	$f4
     99   1.1       cgd #define	fs3	$f5
    100   1.1       cgd #define	fs4	$f6
    101   1.1       cgd #define	fs5	$f7
    102   1.1       cgd #define	fs6	$f8
    103   1.1       cgd #define	fs7	$f9
    104   1.1       cgd #define	ft1	$f10	/* (T)		temporary registers	*/
    105   1.1       cgd #define	ft2	$f11
    106   1.1       cgd #define	ft3	$f12
    107   1.1       cgd #define	ft4	$f13
    108   1.1       cgd #define	ft5	$f14
    109   1.1       cgd #define	ft6	$f15
    110   1.1       cgd #define	fa0	$f16	/* (T)		argument registers	*/
    111   1.1       cgd #define	fa1	$f17
    112   1.1       cgd #define	fa2	$f18
    113   1.1       cgd #define	fa3	$f19
    114   1.1       cgd #define	fa4	$f20
    115   1.1       cgd #define	fa5	$f21
    116   1.1       cgd #define	ft7	$f22	/* (T)		more temporaries	*/
    117   1.1       cgd #define	ft8	$f23
    118   1.1       cgd #define	ft9	$f24
    119   1.1       cgd #define	ft10	$f25
    120   1.1       cgd #define	ft11	$f26
    121   1.1       cgd #define	ft12	$f27
    122   1.1       cgd #define	ft13	$f28
    123   1.1       cgd #define	ft14	$f29
    124   1.1       cgd #define	ft15	$f30
    125   1.1       cgd #define	fzero	$f31	/*		wired zero		*/
    126   1.1       cgd 
    127   1.1       cgd 
    128   1.1       cgd /* Other DEC standard names */
    129   1.1       cgd #define ai	$25	/* (T)		argument information	*/
    130   1.1       cgd #define pv	$27	/* (T)		procedure value		*/
    131   1.1       cgd 
    132   1.9       cgd 
    133   1.9       cgd /*
    134   1.9       cgd  * Useful stuff.
    135   1.9       cgd  */
    136   1.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.27    keihan  * 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.29  christos  * STRONG_ALIAS: create a strong alias.
    622  1.29  christos  */
    623  1.29  christos #define STRONG_ALIAS(alias,sym)					\
    624  1.29  christos 	.globl alias;						\
    625  1.29  christos 	alias = sym
    626  1.29  christos 
    627  1.29  christos /*
    628  1.26   thorpej  * WARN_REFERENCES: create a warning if the specified symbol is referenced.
    629  1.22   thorpej  */
    630  1.22   thorpej #ifdef __STDC__
    631  1.31     joerg #define	WARN_REFERENCES(sym,msg)					\
    632  1.31     joerg 	.pushsection .gnu.warning. ## sym;				\
    633  1.31     joerg 	.ascii msg;							\
    634  1.31     joerg 	.popsection
    635  1.22   thorpej #else
    636  1.31     joerg #define	WARN_REFERENCES(sym,msg)					\
    637  1.31     joerg 	.pushsection .gnu.warning./**/sym;				\
    638  1.31     joerg 	.ascii msg;							\
    639  1.31     joerg 	.popsection
    640  1.22   thorpej #endif /* __STDC__ */
    641  1.13       cgd 
    642  1.13       cgd /*
    643  1.13       cgd  * Kernel RCS ID tag and copyright macros
    644  1.13       cgd  */
    645  1.34      matt #define	__SECTIONSTRING(_sec, _str)				\
    646  1.37     joerg 	.pushsection _sec,"MS",@progbits,1;			\
    647  1.38    martin 	.asciz _str;						\
    648  1.37     joerg 	.popsection
    649  1.13       cgd 
    650  1.13       cgd #ifdef _KERNEL
    651  1.13       cgd 
    652  1.46  riastrad #ifdef _NETBSD_REVISIONID
    653  1.46  riastrad #define	__KERNEL_RCSID(_n, _s)						      \
    654  1.46  riastrad 	__SECTIONSTRING(.ident, _s);					      \
    655  1.46  riastrad 	__SECTIONSTRING(.ident,						      \
    656  1.46  riastrad 	    "$" "NetBSD: " __FILE__ " " _NETBSD_REVISIONID " $")
    657  1.46  riastrad #else
    658  1.34      matt #define	__KERNEL_RCSID(_n, _s)		__SECTIONSTRING(.ident, _s)
    659  1.46  riastrad #endif
    660  1.34      matt #define	__KERNEL_COPYRIGHT(_n, _s)	__SECTIONSTRING(.copyright, _s)
    661  1.13       cgd 
    662  1.13       cgd #ifdef NO_KERNEL_RCSIDS
    663  1.13       cgd #undef __KERNEL_RCSID
    664  1.13       cgd #define	__KERNEL_RCSID(_n, _s)		/* nothing */
    665  1.13       cgd #endif
    666  1.13       cgd 
    667  1.30        ad #if defined(MULTIPROCESSOR)
    668  1.30        ad 
    669  1.30        ad /*
    670  1.30        ad  * Get various per-cpu values.  A pointer to our cpu_info structure
    671  1.30        ad  * is stored in SysValue.  These macros clobber v0, t0, t8..t11.
    672  1.44   thorpej  * SET_CURLWP also clobbers a0.
    673  1.30        ad  *
    674  1.30        ad  * All return values are in v0.
    675  1.30        ad  */
    676  1.30        ad #define	GET_CURLWP							\
    677  1.44   thorpej 	call_pal PAL_OSF1_rdval
    678  1.41   thorpej 
    679  1.45  riastrad /*
    680  1.45  riastrad  * Issue barriers to coordinate mutex_exit on this CPU with
    681  1.45  riastrad  * mutex_vector_enter on another CPU.
    682  1.45  riastrad  *
    683  1.45  riastrad  * 1. Any prior mutex_exit by oldlwp must be visible to other
    684  1.45  riastrad  *    CPUs before we set ci_curlwp := newlwp on this one,
    685  1.45  riastrad  *    requiring a store-before-store barrier.
    686  1.45  riastrad  *
    687  1.45  riastrad  * 2. ci_curlwp := newlwp must be visible on all other CPUs
    688  1.45  riastrad  *    before any subsequent mutex_exit by newlwp can even test
    689  1.45  riastrad  *    whether there might be waiters, requiring a
    690  1.45  riastrad  *    store-before-load barrier.
    691  1.45  riastrad  *
    692  1.45  riastrad  * See kern_mutex.c for details -- this is necessary for
    693  1.45  riastrad  * adaptive mutexes to detect whether the lwp is on the CPU in
    694  1.45  riastrad  * order to safely block without requiring atomic r/m/w in
    695  1.45  riastrad  * mutex_exit.
    696  1.45  riastrad  */
    697  1.41   thorpej #define	SET_CURLWP(r)							\
    698  1.44   thorpej 	ldq	v0, L_CPU(r)					;	\
    699  1.44   thorpej 	mov	r, a0						;	\
    700  1.45  riastrad 	wmb	/* store-before-store XXX patch out if !MP? */	;	\
    701  1.44   thorpej 	stq	r, CPU_INFO_CURLWP(v0)				;	\
    702  1.45  riastrad 	mb	/* store-before-load XXX patch out if !MP? */	;	\
    703  1.44   thorpej 	call_pal PAL_OSF1_wrval
    704  1.30        ad 
    705  1.30        ad #else	/* if not MULTIPROCESSOR... */
    706  1.30        ad 
    707  1.30        ad IMPORT(cpu_info_primary, CPU_INFO_SIZEOF)
    708  1.30        ad 
    709  1.41   thorpej #define	GET_CURLWP		lda v0, cpu_info_primary	;	\
    710  1.41   thorpej 				ldq v0, CPU_INFO_CURLWP(v0)
    711  1.41   thorpej 
    712  1.41   thorpej #define	SET_CURLWP(r)		lda v0, cpu_info_primary 	;	\
    713  1.41   thorpej 				stq r, CPU_INFO_CURLWP(v0)
    714  1.30        ad 
    715  1.34      matt #endif /* MULTIPROCESSOR */
    716  1.46  riastrad 
    717  1.46  riastrad #else /* !_KERNEL */
    718  1.46  riastrad 
    719  1.46  riastrad #ifdef _NETBSD_REVISIONID
    720  1.46  riastrad #define	RCSID(_s)							      \
    721  1.46  riastrad 	__SECTIONSTRING(.ident, _s);					      \
    722  1.46  riastrad 	__SECTIONSTRING(.ident,						      \
    723  1.46  riastrad 	    "$" "NetBSD: " __FILE__ " " _NETBSD_REVISIONID " $")
    724  1.34      matt #else
    725  1.34      matt #define	RCSID(_s)		__SECTIONSTRING(.ident, _s)
    726  1.46  riastrad #endif
    727  1.30        ad 
    728  1.13       cgd #endif /* _KERNEL */
    729