Home | History | Annotate | Line # | Download | only in include
asm.h revision 1.1
      1 /*	$NetBSD: asm.h,v 1.1 1995/02/13 23:07:30 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  * LEAF
    199  *	Declare a global leaf function.
    200  *	A leaf function does not call other functions AND does not
    201  *	use any register that is callee-saved AND does not modify
    202  *	the stack pointer.
    203  */
    204 #define	LEAF(_name_,_n_args_)					\
    205 	.globl	_name_;						\
    206 	.ent	_name_ 0;					\
    207 _name_:;							\
    208 	.frame	sp,0,ra
    209 /* should have been
    210 	.proc	_name_,_n_args_;				\
    211 	.frame	0,ra,0,0
    212 */
    213 
    214 /*
    215  * STATIC_LEAF
    216  *	Declare a local leaf function.
    217  */
    218 #define STATIC_LEAF(_name_,_n_args_)				\
    219 	.ent	_name_ 0;					\
    220 _name_:;							\
    221 	.frame	sp,0,ra
    222 /* should have been
    223 	.proc	_name_,_n_args_;				\
    224 	.frame	0,ra,0,0
    225 */
    226 /*
    227  * XLEAF
    228  *	Global alias for a leaf function, or alternate entry point
    229  */
    230 #define	XLEAF(_name_,_n_args_)					\
    231 	.globl	_name_;						\
    232 	.aent	_name_ 0;					\
    233 _name_:
    234 /* should have been
    235 	.aproc	_name_,_n_args_;
    236 */
    237 
    238 /*
    239  * STATIC_XLEAF
    240  *	Local alias for a leaf function, or alternate entry point
    241  */
    242 #define	STATIC_XLEAF(_name_,_n_args_)				\
    243 	.aent	_name_ 0;					\
    244 _name_:
    245 /* should have been
    246 	.aproc	_name_,_n_args_;
    247 */
    248 
    249 /*
    250  * NESTED
    251  *	Declare a (global) nested function
    252  *	A nested function calls other functions and needs
    253  *	therefore stack space to save/restore registers.
    254  */
    255 #define	NESTED(_name_, _n_args_, _framesize_, _pc_reg_, _i_mask_, _f_mask_ ) \
    256 	.globl	_name_;						\
    257 	.ent	_name_ 0;					\
    258 _name_:;							\
    259 	.frame	sp,_framesize_,_pc_reg_;			\
    260 	.livereg _i_mask_,_f_mask_
    261 /* should have been
    262 	.proc	_name_,_n_args_;				\
    263 	.frame	_framesize_, _pc_reg_, _i_mask_, _f_mask_
    264 */
    265 
    266 /*
    267  * STATIC_NESTED
    268  *	Declare a local nested function.
    269  */
    270 #define	STATIC_NESTED(_name_, _n_args_, _framesize_, _pc_reg_, _i_mask_, _f_mask_ ) \
    271 	.ent	_name_ 0;					\
    272 _name_:;							\
    273 	.frame	sp,_framesize_,_pc_reg_;			\
    274 	.livereg _i_mask_,_f_mask_
    275 /* should have been
    276 	.proc	_name_,_n_args_;				\
    277 	.frame	_framesize_, _pc_reg_, _i_mask_, _f_mask_
    278 */
    279 
    280 /*
    281  * XNESTED
    282  *	Same as XLEAF, for a nested function.
    283  */
    284 #define	XNESTED(_name_,_n_args_)				\
    285 	.globl	_name_;						\
    286 	.aent	_name_ 0;					\
    287 _name_:
    288 /* should have been
    289 	.aproc	_name_,_n_args_;
    290 */
    291 
    292 
    293 /*
    294  * STATIC_XNESTED
    295  *	Same as STATIC_XLEAF, for a nested function.
    296  */
    297 #define	STATIC_XNESTED(_name_,_n_args_)				\
    298 	.aent	_name_ 0;					\
    299 _name_:
    300 /* should have been
    301 	.aproc	_name_,_n_args_;
    302 */
    303 
    304 
    305 /*
    306  * END
    307  *	Function delimiter
    308  */
    309 #define	END(_name_)						\
    310 	.end	_name_
    311 
    312 
    313 /*
    314  * CALL
    315  *	Function invocation
    316  */
    317 #define	CALL(_name_)						\
    318 	jsr	ra,_name_;					\
    319 	ldgp	gp,0(ra)
    320 /* but this would cover longer jumps
    321 	br	ra,.+4;						\
    322 	bsr	ra,_name_
    323 */
    324 
    325 
    326 /*
    327  * RET
    328  *	Return from function
    329  */
    330 #define	RET							\
    331 	ret	zero,(ra),1
    332 
    333 
    334 /*
    335  * EXPORT
    336  *	Export a symbol
    337  */
    338 #define	EXPORT(_name_)						\
    339 	.globl	_name_;						\
    340 _name_:
    341 
    342 
    343 /*
    344  * IMPORT
    345  *	Make an external name visible, typecheck the size
    346  */
    347 #define	IMPORT(_name_, _size_)					\
    348 	.extern	_name_,_size_
    349 
    350 
    351 /*
    352  * ABS
    353  *	Define an absolute symbol
    354  */
    355 #define	ABS(_name_, _value_)					\
    356 	.globl	_name_;						\
    357 _name_	=	_value_
    358 
    359 
    360 /*
    361  * BSS
    362  *	Allocate un-initialized space for a global symbol
    363  */
    364 #define	BSS(_name_,_numbytes_)					\
    365 	.comm	_name_,_numbytes_
    366 
    367 /*
    368  * VECTOR
    369  *	Make an exception entry point look like a called function,
    370  *	to make it digestible to the debugger (KERNEL only)
    371  */
    372 #define	VECTOR(_name_, _i_mask_)				\
    373 	.globl	_name_;						\
    374 	.ent	_name_ 0;					\
    375 _name_:;							\
    376 	.mask	_i_mask_|IM_EXC,0;				\
    377 	.frame	sp,MSS_SIZE,ra;
    378 /*	.livereg _i_mask_|IM_EXC,0
    379 /* should have been
    380 	.proc	_name_,1;					\
    381 	.frame	MSS_SIZE,$31,_i_mask_,0;			\
    382 */
    383 
    384 /*
    385  * MSG
    386  *	Allocate space for a message (a read-only ascii string)
    387  */
    388 #ifdef __ALPHA_AS__
    389 #define	ASCIZ	.asciiz
    390 #else
    391 #define	ASCIZ	.asciz
    392 #endif
    393 #define	MSG(msg,reg)						\
    394 	lda reg, 9f;						\
    395 	.data;							\
    396 9:	ASCIZ msg;						\
    397 	.text;
    398 
    399 /*
    400  * PRINTF
    401  *	Print a message
    402  */
    403 #define	PRINTF(msg)						\
    404 	MSG(msg,a0);						\
    405 	CALL(printf)
    406 
    407 /*
    408  * PANIC
    409  *	Fatal error (KERNEL)
    410  */
    411 #define	PANIC(msg)						\
    412 	MSG(msg,a0);						\
    413 	CALL(panic)
    414 
    415 /*
    416  * Register mask defines, used to define both save
    417  * and use register sets.
    418  *
    419  * NOTE: The bit order should HAVE BEEN maintained when saving
    420  *	 registers on the stack: sp goes at the highest
    421  *	 address, gp lower on the stack, etc etc
    422  *	 BUT NOONE CARES ABOUT DEBUGGERS AT MIPS
    423  */
    424 
    425 #define	IM_EXC	0x80000000
    426 #define	IM_SP	0x40000000
    427 #define	IM_GP	0x20000000
    428 #define	IM_AT	0x10000000
    429 #define	IM_T12	0x08000000
    430 #	define	IM_PV	IM_T4
    431 #define	IM_RA	0x04000000
    432 #define	IM_T11	0x02000000
    433 #	define	IM_AI	IM_T3
    434 #define	IM_T10	0x01000000
    435 #define	IM_T9	0x00800000
    436 #define	IM_T8	0x00400000
    437 #define	IM_A5	0x00200000
    438 #define	IM_A4	0x00100000
    439 #define	IM_A3	0x00080000
    440 #define	IM_A2	0x00040000
    441 #define	IM_A1	0x00020000
    442 #define	IM_A0	0x00010000
    443 #define	IM_S6	0x00008000
    444 #define	IM_S5	0x00004000
    445 #define	IM_S4	0x00002000
    446 #define	IM_S3	0x00001000
    447 #define	IM_S2	0x00000800
    448 #define	IM_S1	0x00000400
    449 #define	IM_S0	0x00000200
    450 #define	IM_T7	0x00000100
    451 #define	IM_T6	0x00000080
    452 #define	IM_T5	0x00000040
    453 #define	IM_T4	0x00000020
    454 #define	IM_T3	0x00000010
    455 #define	IM_T2	0x00000008
    456 #define	IM_T1	0x00000004
    457 #define	IM_T0	0x00000002
    458 #define	IM_V0	0x00000001
    459 
    460 #define	FM_T15	0x40000000
    461 #define	FM_T14	0x20000000
    462 #define	FM_T13	0x10000000
    463 #define	FM_T12	0x08000000
    464 #define	FM_T11	0x04000000
    465 #define	FM_T10	0x02000000
    466 #define	FM_T9	0x01000000
    467 #define	FM_T8	0x00800000
    468 #define	FM_T7	0x00400000
    469 #define	FM_A5	0x00200000
    470 #define	FM_A4	0x00100000
    471 #define	FM_A3	0x00080000
    472 #define	FM_A2	0x00040000
    473 #define	FM_A1	0x00020000
    474 #define	FM_A0	0x00010000
    475 #define	FM_T6	0x00008000
    476 #define	FM_T5	0x00004000
    477 #define	FM_T4	0x00002000
    478 #define	FM_T3	0x00001000
    479 #define	FM_T2	0x00000800
    480 #define	FM_T1	0x00000400
    481 #define	FM_S7	0x00000200
    482 #define	FM_S6	0x00000100
    483 #define	FM_S5	0x00000080
    484 #define	FM_S4	0x00000040
    485 #define	FM_S3	0x00000020
    486 #define	FM_S2	0x00000010
    487 #define	FM_S1	0x00000008
    488 #define	FM_S0	0x00000004
    489 #define	FM_T0	0x00000002
    490 #define	FM_V1	FM_T0
    491 #define	FM_V0	0x00000001
    492 
    493 /*
    494  * PAL "function" codes (used as arguments to call_pal instructions).
    495  *
    496  * Those marked with "P" are privileged, and those marked with "U"
    497  * are unprivileged.
    498  */
    499 
    500 /* Common PAL codes. */
    501 #define	PAL_halt		0x0000			/* P */
    502 #define	PAL_draina		0x0002			/* P */
    503 #define	PAL_swppal		0x000a			/* P */
    504 #define	PAL_bpt			0x0080			/* U */
    505 #define	PAL_bugchk		0x0081			/* U */
    506 #define	PAL_imb			0x0086			/* U */
    507 #define	PAL_rdunique		0x009e			/* U */
    508 #define	PAL_wrunique		0x009f			/* U */
    509 #define	PAL_gentrap		0x00aa			/* U */
    510 
    511 /* VMS PAL codes. */
    512 #define	PAL_VMS_ldqp		0x0003			/* P */
    513 #define	PAL_VMS_stqp		0x0004			/* P */
    514 #define	PAL_VMS_mtpr_fen	0x000c			/* P */
    515 #define	PAL_VMS_mtpr_ipir	0x000d			/* P */
    516 #define	PAL_VMS_mfpr_ipl	0x000e			/* P */
    517 #define	PAL_VMS_mtpr_ipl	0x000f			/* P */
    518 #define	PAL_VMS_mfpr_mces	0x0010			/* P */
    519 #define	PAL_VMS_mtpr_mces	0x0011			/* P */
    520 #define	PAL_VMS_mfpr_prbr	0x0013			/* P */
    521 #define	PAL_VMS_mtpr_prbr	0x0014			/* P */
    522 #define	PAL_VMS_mfpr_ptbr	0x0015			/* P */
    523 #define	PAL_VMS_mtpr_scbb	0x0017			/* P */
    524 #define	PAL_VMS_mtpr_sirr	0x0018			/* P */
    525 #define	PAL_VMS_mtpr_tbia	0x001b			/* P */
    526 #define	PAL_VMS_mtpr_tbiap	0x001c			/* P */
    527 #define	PAL_VMS_mtpr_tbis	0x001d			/* P */
    528 #define	PAL_VMS_mfpr_usp	0x0022			/* P */
    529 #define	PAL_VMS_mtpr_usp	0x0023			/* P */
    530 #define	PAL_VMS_mfpr_vptb	0x0029			/* P */
    531 #define	PAL_VMS_mfpr_whami	0x003f			/* P */
    532 #define	PAL_VMS_rei		0x0092			/* U */
    533 
    534 /* OSF/1 PAL codes. */
    535 #define	PAL_OSF1_wrfen		0x002b			/* P */
    536 #define	PAL_OSF1_wrvptptr	0x002d			/* P */
    537 #define	PAL_OSF1_swpctx		0x0030			/* P */
    538 #define	PAL_OSF1_wrval		0x0031			/* P */
    539 #define	PAL_OSF1_rdval		0x0032			/* P */
    540 #define	PAL_OSF1_tbi		0x0033			/* P */
    541 #define	PAL_OSF1_wrent		0x0034			/* P */
    542 #define	PAL_OSF1_swpipl		0x0035			/* P */
    543 #define	PAL_OSF1_rdps		0x0036			/* P */
    544 #define	PAL_OSF1_wrkgp		0x0037			/* P */
    545 #define	PAL_OSF1_wrusp		0x0038			/* P */
    546 #define	PAL_OSF1_rdusp		0x003a			/* P */
    547 #define	PAL_OSF1_whami		0x003c			/* P */
    548 #define	PAL_OSF1_retsys		0x003d			/* P */
    549 #define	PAL_OSF1_rti		0x003f			/* P */
    550 #define	PAL_OSF1_callsys	0x0083			/* U */
    551 #define	PAL_OSF1_imb		0x0086			/* U */
    552 
    553 /*
    554  * Defintions to make things portable between gcc and OSF/1 cc.
    555  */
    556 #define	SETGP(pv)	ldgp	gp,0(pv)
    557 
    558 #ifdef __ALPHA_AS__
    559 #define	MF_FPCR(x)	mf_fpcr x,x,x
    560 #define	MT_FPCR(x)	mt_fpcr x,x,x
    561 #define	JMP(loc)	jmp	loc
    562 #define	CONST(c,reg)	mov	c, reg
    563 #else
    564 #define	MF_FPCR(x)	mf_fpcr x
    565 #define	MT_FPCR(x)	mt_fpcr x
    566 #define	JMP(loc)	br	zero,loc
    567 #define	CONST(c,reg)	ldiq	reg, c
    568 #endif
    569 
    570