diff options
Diffstat (limited to 'sys/arch/alpha/include/asm.h')
-rw-r--r-- | sys/arch/alpha/include/asm.h | 569 |
1 files changed, 569 insertions, 0 deletions
diff --git a/sys/arch/alpha/include/asm.h b/sys/arch/alpha/include/asm.h new file mode 100644 index 00000000000..4283fbe52cc --- /dev/null +++ b/sys/arch/alpha/include/asm.h @@ -0,0 +1,569 @@ +/* $NetBSD: asm.h,v 1.1 1995/02/13 23:07:30 cgd Exp $ */ + +/* + * Copyright (c) 1991,1990,1989,1994,1995 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * Assembly coding style + * + * This file contains macros and register defines to + * aid in writing more readable assembly code. + * Some rules to make assembly code understandable by + * a debugger are also noted. + * + * The document + * + * "ALPHA Calling Standard", DEC 27-Apr-90 + * + * defines (a superset of) the rules and conventions + * we use. While we make no promise of adhering to + * such standard and its evolution (esp where we + * can get faster code paths) it is certainly intended + * that we be interoperable with such standard. + * + * In this sense, this file is a proper part of the + * definition of the (software) Alpha architecture. + */ + +/* + * Symbolic register names and register saving rules + * + * Legend: + * T Saved by caller (Temporaries) + * S Saved by callee (call-Safe registers) + */ + +#define v0 $0 /* (T) return value */ +#define t0 $1 /* (T) temporary registers */ +#define t1 $2 +#define t2 $3 +#define t3 $4 +#define t4 $5 +#define t5 $6 +#define t6 $7 +#define t7 $8 + +#define s0 $9 /* (S) call-safe registers */ +#define s1 $10 +#define s2 $11 +#define s3 $12 +#define s4 $13 +#define s5 $14 +#define s6 $15 +#define a0 $16 /* (T) argument registers */ +#define a1 $17 +#define a2 $18 +#define a3 $19 +#define a4 $20 +#define a5 $21 +#define t8 $22 /* (T) temporary registers */ +#define t9 $23 +#define t10 $24 +#define t11 $25 +#define ra $26 /* (T) return address */ +#define t12 $27 /* (T) another temporary */ +#define at_reg $28 /* (T) assembler scratch */ +#define gp $29 /* (T) (local) data pointer */ +#define sp $30 /* (S) stack pointer */ +#define zero $31 /* wired zero */ + +/* Floating point registers (XXXX VERIFY THIS) */ +#define fv0 $f0 /* (T) return value (real) */ +#define fv1 $f1 /* (T) return value (imaginary)*/ +#define ft0 fv1 +#define fs0 $f2 /* (S) call-safe registers */ +#define fs1 $f3 +#define fs2 $f4 +#define fs3 $f5 +#define fs4 $f6 +#define fs5 $f7 +#define fs6 $f8 +#define fs7 $f9 +#define ft1 $f10 /* (T) temporary registers */ +#define ft2 $f11 +#define ft3 $f12 +#define ft4 $f13 +#define ft5 $f14 +#define ft6 $f15 +#define fa0 $f16 /* (T) argument registers */ +#define fa1 $f17 +#define fa2 $f18 +#define fa3 $f19 +#define fa4 $f20 +#define fa5 $f21 +#define ft7 $f22 /* (T) more temporaries */ +#define ft8 $f23 +#define ft9 $f24 +#define ft10 $f25 +#define ft11 $f26 +#define ft12 $f27 +#define ft13 $f28 +#define ft14 $f29 +#define ft15 $f30 +#define fzero $f31 /* wired zero */ + + +/* Other DEC standard names */ +#define ai $25 /* (T) argument information */ +#define pv $27 /* (T) procedure value */ + +/* + * + * Debuggers need symbol table information to be able to properly + * decode a stack trace. The minimum that should be provided is: + * + * name: + * .proc name,numargs + * + * where "name" is the function's name; + * "numargs" how many arguments it expects. For varargs + * procedures this should be a negative number, + * indicating the minimum required number of + * arguments (which is at least 1); + * + * NESTED functions (functions that call other functions) should define + * how they handle their stack frame in a .frame directive: + * + * .frame framesize, pc_reg, i_mask, f_mask + * + * where "framesize" is the size of the frame for this function, in bytes. + * That is: + * new_sp + framesize == old_sp + * Framesizes should be rounded to a cacheline size. + * Note that old_sp plays the role of a conventional + * "frame pointer"; + * "pc_reg" is either a register which preserves the caller's PC + * or 'std', if std the saved PC should be stored at + * old_sp-8 + * "i_mask" is a bitmask that indicates which of the integer + * registers are saved. See the M_xx defines at the + * end for the encoding of this 32bit value. + * "f_mask" is the same, for floating point registers. + * + * Note that registers should be saved starting at "old_sp-8", where the + * return address should be stored. Other registers follow at -16-24-32.. + * starting from register 0 (if saved) and up. Then float registers (ifany) + * are saved. + * + * If you need to alias a leaf function, or to provide multiple entry points + * use the LEAF() macro for the main entry point and XLEAF() for the other + * additional/alternate entry points. + * "XLEAF"s must be nested within a "LEAF" and a ".end". + * Similar rules for nested routines, e.g. use NESTED/XNESTED + * Symbols that should not be exported can be declared with the STATIC_xxx + * macros. + * + * All functions must be terminated by the END macro + * + * It is conceivable, although currently at the limits of compiler + * technology, that while performing inter-procedural optimizations + * the compiler/linker be able to avoid unnecessary register spills + * if told about the register usage of LEAF procedures (and by transitive + * closure of NESTED procedures as well). Assembly code can help + * this process using the .reguse directive: + * + * .reguse i_mask, f_mask + * + * where the register masks are built as above or-ing M_xx defines. + * + * + * All symbols are internal unless EXPORTed. Symbols that are IMPORTed + * must be appropriately described to the debugger. + * + */ + +/* + * LEAF + * Declare a global leaf function. + * A leaf function does not call other functions AND does not + * use any register that is callee-saved AND does not modify + * the stack pointer. + */ +#define LEAF(_name_,_n_args_) \ + .globl _name_; \ + .ent _name_ 0; \ +_name_:; \ + .frame sp,0,ra +/* should have been + .proc _name_,_n_args_; \ + .frame 0,ra,0,0 +*/ + +/* + * STATIC_LEAF + * Declare a local leaf function. + */ +#define STATIC_LEAF(_name_,_n_args_) \ + .ent _name_ 0; \ +_name_:; \ + .frame sp,0,ra +/* should have been + .proc _name_,_n_args_; \ + .frame 0,ra,0,0 +*/ +/* + * XLEAF + * Global alias for a leaf function, or alternate entry point + */ +#define XLEAF(_name_,_n_args_) \ + .globl _name_; \ + .aent _name_ 0; \ +_name_: +/* should have been + .aproc _name_,_n_args_; +*/ + +/* + * STATIC_XLEAF + * Local alias for a leaf function, or alternate entry point + */ +#define STATIC_XLEAF(_name_,_n_args_) \ + .aent _name_ 0; \ +_name_: +/* should have been + .aproc _name_,_n_args_; +*/ + +/* + * NESTED + * Declare a (global) nested function + * A nested function calls other functions and needs + * therefore stack space to save/restore registers. + */ +#define NESTED(_name_, _n_args_, _framesize_, _pc_reg_, _i_mask_, _f_mask_ ) \ + .globl _name_; \ + .ent _name_ 0; \ +_name_:; \ + .frame sp,_framesize_,_pc_reg_; \ + .livereg _i_mask_,_f_mask_ +/* should have been + .proc _name_,_n_args_; \ + .frame _framesize_, _pc_reg_, _i_mask_, _f_mask_ +*/ + +/* + * STATIC_NESTED + * Declare a local nested function. + */ +#define STATIC_NESTED(_name_, _n_args_, _framesize_, _pc_reg_, _i_mask_, _f_mask_ ) \ + .ent _name_ 0; \ +_name_:; \ + .frame sp,_framesize_,_pc_reg_; \ + .livereg _i_mask_,_f_mask_ +/* should have been + .proc _name_,_n_args_; \ + .frame _framesize_, _pc_reg_, _i_mask_, _f_mask_ +*/ + +/* + * XNESTED + * Same as XLEAF, for a nested function. + */ +#define XNESTED(_name_,_n_args_) \ + .globl _name_; \ + .aent _name_ 0; \ +_name_: +/* should have been + .aproc _name_,_n_args_; +*/ + + +/* + * STATIC_XNESTED + * Same as STATIC_XLEAF, for a nested function. + */ +#define STATIC_XNESTED(_name_,_n_args_) \ + .aent _name_ 0; \ +_name_: +/* should have been + .aproc _name_,_n_args_; +*/ + + +/* + * END + * Function delimiter + */ +#define END(_name_) \ + .end _name_ + + +/* + * CALL + * Function invocation + */ +#define CALL(_name_) \ + jsr ra,_name_; \ + ldgp gp,0(ra) +/* but this would cover longer jumps + br ra,.+4; \ + bsr ra,_name_ +*/ + + +/* + * RET + * Return from function + */ +#define RET \ + ret zero,(ra),1 + + +/* + * EXPORT + * Export a symbol + */ +#define EXPORT(_name_) \ + .globl _name_; \ +_name_: + + +/* + * IMPORT + * Make an external name visible, typecheck the size + */ +#define IMPORT(_name_, _size_) \ + .extern _name_,_size_ + + +/* + * ABS + * Define an absolute symbol + */ +#define ABS(_name_, _value_) \ + .globl _name_; \ +_name_ = _value_ + + +/* + * BSS + * Allocate un-initialized space for a global symbol + */ +#define BSS(_name_,_numbytes_) \ + .comm _name_,_numbytes_ + +/* + * VECTOR + * Make an exception entry point look like a called function, + * to make it digestible to the debugger (KERNEL only) + */ +#define VECTOR(_name_, _i_mask_) \ + .globl _name_; \ + .ent _name_ 0; \ +_name_:; \ + .mask _i_mask_|IM_EXC,0; \ + .frame sp,MSS_SIZE,ra; +/* .livereg _i_mask_|IM_EXC,0 +/* should have been + .proc _name_,1; \ + .frame MSS_SIZE,$31,_i_mask_,0; \ +*/ + +/* + * MSG + * Allocate space for a message (a read-only ascii string) + */ +#ifdef __ALPHA_AS__ +#define ASCIZ .asciiz +#else +#define ASCIZ .asciz +#endif +#define MSG(msg,reg) \ + lda reg, 9f; \ + .data; \ +9: ASCIZ msg; \ + .text; + +/* + * PRINTF + * Print a message + */ +#define PRINTF(msg) \ + MSG(msg,a0); \ + CALL(printf) + +/* + * PANIC + * Fatal error (KERNEL) + */ +#define PANIC(msg) \ + MSG(msg,a0); \ + CALL(panic) + +/* + * Register mask defines, used to define both save + * and use register sets. + * + * NOTE: The bit order should HAVE BEEN maintained when saving + * registers on the stack: sp goes at the highest + * address, gp lower on the stack, etc etc + * BUT NOONE CARES ABOUT DEBUGGERS AT MIPS + */ + +#define IM_EXC 0x80000000 +#define IM_SP 0x40000000 +#define IM_GP 0x20000000 +#define IM_AT 0x10000000 +#define IM_T12 0x08000000 +# define IM_PV IM_T4 +#define IM_RA 0x04000000 +#define IM_T11 0x02000000 +# define IM_AI IM_T3 +#define IM_T10 0x01000000 +#define IM_T9 0x00800000 +#define IM_T8 0x00400000 +#define IM_A5 0x00200000 +#define IM_A4 0x00100000 +#define IM_A3 0x00080000 +#define IM_A2 0x00040000 +#define IM_A1 0x00020000 +#define IM_A0 0x00010000 +#define IM_S6 0x00008000 +#define IM_S5 0x00004000 +#define IM_S4 0x00002000 +#define IM_S3 0x00001000 +#define IM_S2 0x00000800 +#define IM_S1 0x00000400 +#define IM_S0 0x00000200 +#define IM_T7 0x00000100 +#define IM_T6 0x00000080 +#define IM_T5 0x00000040 +#define IM_T4 0x00000020 +#define IM_T3 0x00000010 +#define IM_T2 0x00000008 +#define IM_T1 0x00000004 +#define IM_T0 0x00000002 +#define IM_V0 0x00000001 + +#define FM_T15 0x40000000 +#define FM_T14 0x20000000 +#define FM_T13 0x10000000 +#define FM_T12 0x08000000 +#define FM_T11 0x04000000 +#define FM_T10 0x02000000 +#define FM_T9 0x01000000 +#define FM_T8 0x00800000 +#define FM_T7 0x00400000 +#define FM_A5 0x00200000 +#define FM_A4 0x00100000 +#define FM_A3 0x00080000 +#define FM_A2 0x00040000 +#define FM_A1 0x00020000 +#define FM_A0 0x00010000 +#define FM_T6 0x00008000 +#define FM_T5 0x00004000 +#define FM_T4 0x00002000 +#define FM_T3 0x00001000 +#define FM_T2 0x00000800 +#define FM_T1 0x00000400 +#define FM_S7 0x00000200 +#define FM_S6 0x00000100 +#define FM_S5 0x00000080 +#define FM_S4 0x00000040 +#define FM_S3 0x00000020 +#define FM_S2 0x00000010 +#define FM_S1 0x00000008 +#define FM_S0 0x00000004 +#define FM_T0 0x00000002 +#define FM_V1 FM_T0 +#define FM_V0 0x00000001 + +/* + * PAL "function" codes (used as arguments to call_pal instructions). + * + * Those marked with "P" are privileged, and those marked with "U" + * are unprivileged. + */ + +/* Common PAL codes. */ +#define PAL_halt 0x0000 /* P */ +#define PAL_draina 0x0002 /* P */ +#define PAL_swppal 0x000a /* P */ +#define PAL_bpt 0x0080 /* U */ +#define PAL_bugchk 0x0081 /* U */ +#define PAL_imb 0x0086 /* U */ +#define PAL_rdunique 0x009e /* U */ +#define PAL_wrunique 0x009f /* U */ +#define PAL_gentrap 0x00aa /* U */ + +/* VMS PAL codes. */ +#define PAL_VMS_ldqp 0x0003 /* P */ +#define PAL_VMS_stqp 0x0004 /* P */ +#define PAL_VMS_mtpr_fen 0x000c /* P */ +#define PAL_VMS_mtpr_ipir 0x000d /* P */ +#define PAL_VMS_mfpr_ipl 0x000e /* P */ +#define PAL_VMS_mtpr_ipl 0x000f /* P */ +#define PAL_VMS_mfpr_mces 0x0010 /* P */ +#define PAL_VMS_mtpr_mces 0x0011 /* P */ +#define PAL_VMS_mfpr_prbr 0x0013 /* P */ +#define PAL_VMS_mtpr_prbr 0x0014 /* P */ +#define PAL_VMS_mfpr_ptbr 0x0015 /* P */ +#define PAL_VMS_mtpr_scbb 0x0017 /* P */ +#define PAL_VMS_mtpr_sirr 0x0018 /* P */ +#define PAL_VMS_mtpr_tbia 0x001b /* P */ +#define PAL_VMS_mtpr_tbiap 0x001c /* P */ +#define PAL_VMS_mtpr_tbis 0x001d /* P */ +#define PAL_VMS_mfpr_usp 0x0022 /* P */ +#define PAL_VMS_mtpr_usp 0x0023 /* P */ +#define PAL_VMS_mfpr_vptb 0x0029 /* P */ +#define PAL_VMS_mfpr_whami 0x003f /* P */ +#define PAL_VMS_rei 0x0092 /* U */ + +/* OSF/1 PAL codes. */ +#define PAL_OSF1_wrfen 0x002b /* P */ +#define PAL_OSF1_wrvptptr 0x002d /* P */ +#define PAL_OSF1_swpctx 0x0030 /* P */ +#define PAL_OSF1_wrval 0x0031 /* P */ +#define PAL_OSF1_rdval 0x0032 /* P */ +#define PAL_OSF1_tbi 0x0033 /* P */ +#define PAL_OSF1_wrent 0x0034 /* P */ +#define PAL_OSF1_swpipl 0x0035 /* P */ +#define PAL_OSF1_rdps 0x0036 /* P */ +#define PAL_OSF1_wrkgp 0x0037 /* P */ +#define PAL_OSF1_wrusp 0x0038 /* P */ +#define PAL_OSF1_rdusp 0x003a /* P */ +#define PAL_OSF1_whami 0x003c /* P */ +#define PAL_OSF1_retsys 0x003d /* P */ +#define PAL_OSF1_rti 0x003f /* P */ +#define PAL_OSF1_callsys 0x0083 /* U */ +#define PAL_OSF1_imb 0x0086 /* U */ + +/* + * Defintions to make things portable between gcc and OSF/1 cc. + */ +#define SETGP(pv) ldgp gp,0(pv) + +#ifdef __ALPHA_AS__ +#define MF_FPCR(x) mf_fpcr x,x,x +#define MT_FPCR(x) mt_fpcr x,x,x +#define JMP(loc) jmp loc +#define CONST(c,reg) mov c, reg +#else +#define MF_FPCR(x) mf_fpcr x +#define MT_FPCR(x) mt_fpcr x +#define JMP(loc) br zero,loc +#define CONST(c,reg) ldiq reg, c +#endif + |