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