📄 machine.h
字号:
/* non-zero if system call is an exit() */#define OSF_SYS_exit 1#define MD_EXIT_SYSCALL(REGS) \ ((REGS)->regs_R[MD_REG_V0] == OSF_SYS_exit)/* non-zero if system call is a write to stdout/stderr */#define OSF_SYS_write 4#define MD_OUTPUT_SYSCALL(REGS) \ ((REGS)->regs_R[MD_REG_V0] == OSF_SYS_write \ && ((REGS)->regs_R[MD_REG_A0] == /* stdout */1 \ || (REGS)->regs_R[MD_REG_A0] == /* stderr */2))/* returns stream of an output system call, translated to host */#define MD_STREAM_FILENO(REGS) ((REGS)->regs_R[MD_REG_A0])/* returns non-zero if instruction is a function call */#define MD_IS_CALL(OP) ((OP) == JSR || (OP) == BSR)/* returns non-zero if instruction is a function return */#define MD_IS_RETURN(OP) ((OP) == RETN)/* returns non-zero if instruction is an indirect jump */#define MD_IS_INDIR(OP) \ ((OP) == JMP || (OP) == JSR || (OP) == RETN || (OP) == JSR_COROUTINE)/* addressing mode probe, enums and strings */enum md_amode_type { md_amode_imm, /* immediate addressing mode */ md_amode_gp, /* global data access through global pointer */ md_amode_sp, /* stack access through stack pointer */ md_amode_fp, /* stack access through frame pointer */ md_amode_disp, /* (reg + const) addressing */ md_amode_rr, /* (reg + reg) addressing */ md_amode_NUM};extern char *md_amode_str[md_amode_NUM];/* addressing mode pre-probe FSM, must see all instructions */#define MD_AMODE_PREPROBE(OP, FSM) { (FSM) = 0; }/* compute addressing mode, only for loads/stores */#define MD_AMODE_PROBE(AM, OP, FSM) \ { \ if (MD_OP_FLAGS(OP) & F_DISP) \ { \ if ((RB) == MD_REG_GP) \ (AM) = md_amode_gp; \ else if ((RB) == MD_REG_SP) \ (AM) = md_amode_sp; \ else if ((RB) == MD_REG_FP) /* && bind_to_seg(addr) == seg_stack */\ (AM) = md_amode_fp; \ else \ (AM) = md_amode_disp; \ } \ else if (MD_OP_FLAGS(OP) & F_RR) \ (AM) = md_amode_rr; \ else \ panic("cannot decode addressing mode"); \ }/* addressing mode pre-probe FSM, after all loads and stores */#define MD_AMODE_POSTPROBE(FSM) /* nada... *//* * EIO package configuration/macros *//* expected EIO file format */#define MD_EIO_FILE_FORMAT EIO_ALPHA_FORMAT#define MD_MISC_REGS_TO_EXO(REGS) \ exo_new(ec_list, \ /*icnt*/exo_new(ec_integer, (exo_integer_t)sim_num_insn), \ /*PC*/exo_new(ec_address, (exo_integer_t)(REGS)->regs_PC), \ /*NPC*/exo_new(ec_address, (exo_integer_t)(REGS)->regs_NPC), \ /*FPCR*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.fpcr),\ /*UNIQ*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.uniq),\ NULL)#define MD_IREG_TO_EXO(REGS, IDX) \ exo_new(ec_address, (exo_integer_t)(REGS)->regs_R[IDX])#define MD_FREG_TO_EXO(REGS, IDX) \ exo_new(ec_address, (exo_integer_t)(REGS)->regs_F.q[IDX])#define MD_EXO_TO_MISC_REGS(EXO, ICNT, REGS) \ /* check EXO format for errors... */ \ if (!exo \ || exo->ec != ec_list \ || !exo->as_list.head \ || exo->as_list.head->ec != ec_integer \ || !exo->as_list.head->next \ || exo->as_list.head->next->ec != ec_address \ || !exo->as_list.head->next->next \ || exo->as_list.head->next->next->ec != ec_address \ || !exo->as_list.head->next->next->next \ || exo->as_list.head->next->next->next->ec != ec_integer \ || !exo->as_list.head->next->next->next->next \ || exo->as_list.head->next->next->next->next->ec != ec_integer \ || exo->as_list.head->next->next->next->next->next != NULL) \ fatal("could not read EIO misc regs"); \ (ICNT) = (counter_t)exo->as_list.head->as_integer.val; \ (REGS)->regs_PC = (md_addr_t)exo->as_list.head->next->as_integer.val; \ (REGS)->regs_NPC = \ (md_addr_t)exo->as_list.head->next->next->as_integer.val; \ (REGS)->regs_C.fpcr = \ (qword_t)exo->as_list.head->next->next->next->as_integer.val; \ (REGS)->regs_C.uniq = \ (qword_t)exo->as_list.head->next->next->next->next->as_integer.val;#define MD_EXO_TO_IREG(EXO, REGS, IDX) \ ((REGS)->regs_R[IDX] = (qword_t)(EXO)->as_integer.val)#define MD_EXO_TO_FREG(EXO, REGS, IDX) \ ((REGS)->regs_F.q[IDX] = (qword_t)(EXO)->as_integer.val)#define MD_EXO_CMP_IREG(EXO, REGS, IDX) \ ((REGS)->regs_R[IDX] != (qword_t)(EXO)->as_integer.val)#define MD_FIRST_IN_REG 0#define MD_LAST_IN_REG 21#define MD_FIRST_OUT_REG 0#define MD_LAST_OUT_REG 21/* * configure the EXO package *//* EXO pointer class */typedef qword_t exo_address_t;/* EXO integer class, 64-bit encoding */typedef qword_t exo_integer_t;/* EXO floating point class, 64-bit encoding */typedef double exo_float_t;/* * configure the stats package *//* counter stats */#define stat_reg_counter stat_reg_sqword#define sc_counter sc_sqword#define for_counter for_sqword/* address stats */#define stat_reg_addr stat_reg_qword/* * configure the DLite! debugger *//* register bank specifier */enum md_reg_type { rt_gpr, /* general purpose register */ rt_lpr, /* integer-precision floating pointer register */ rt_fpr, /* single-precision floating pointer register */ rt_dpr, /* double-precision floating pointer register */ rt_ctrl, /* control register */ rt_PC, /* program counter */ rt_NPC, /* next program counter */ rt_NUM};/* register name specifier */struct md_reg_names_t { char *str; /* register name */ enum md_reg_type file; /* register file */ int reg; /* register index */};/* symbolic register names, parser is case-insensitive */extern struct md_reg_names_t md_reg_names[];/* returns a register name string */char *md_reg_name(enum md_reg_type rt, int reg);/* default register accessor object */struct eval_value_t;struct regs_t;char * /* err str, NULL for no err */md_reg_obj(struct regs_t *regs, /* registers to access */ int is_write, /* access type */ enum md_reg_type rt, /* reg bank to probe */ int reg, /* register number */ struct eval_value_t *val); /* input, output *//* print integer REG(S) to STREAM */void md_print_ireg(md_gpr_t regs, int reg, FILE *stream);void md_print_iregs(md_gpr_t regs, FILE *stream);/* print floating point REG(S) to STREAM */void md_print_fpreg(md_fpr_t regs, int reg, FILE *stream);void md_print_fpregs(md_fpr_t regs, FILE *stream);/* print control REG(S) to STREAM */void md_print_creg(md_ctrl_t regs, int reg, FILE *stream);void md_print_cregs(md_ctrl_t regs, FILE *stream);/* xor checksum registers */word_t md_xor_regs(struct regs_t *regs);/* * configure sim-outorder specifics *//* primitive operation used to compute addresses within pipeline */#define MD_AGEN_OP ADDQ/* NOP operation when injected into the pipeline */#define MD_NOP_OP OP_NA/* non-zero for a valid address, used to determine if speculative accesses should access the DL1 data cache */#define MD_VALID_ADDR(ADDR) \ (((ADDR) >= ld_text_base && (ADDR) < (ld_text_base + ld_text_size)) \ || ((ADDR) >= ld_data_base && (ADDR) < ld_brk_point) \ || ((ADDR) >= (ld_stack_base - 16*1024*1024) && (ADDR) < ld_stack_base))/* * configure branch predictors *//* shift used to ignore branch address least significant bits, usually log2(sizeof(md_inst_t)) */#define MD_BR_SHIFT 2 /* log2(4) *//* * target-dependent routines *//* intialize the inst decoder, this function builds the ISA decode tables */void md_init_decoder(void);/* disassemble a SimpleScalar instruction */voidmd_print_insn(md_inst_t inst, /* instruction to disassemble */ md_addr_t pc, /* addr of inst, used for PC-rels */ FILE *stream); /* output stream */#endif /* ALPHA_H */#if 0/* instruction/address formats */typedef qword_t MD_ADDR_TYPE;typedef qword_t MD_PTR_TYPE;typedef word_t MD_INST_TYPE;#define MD_INST_SIZE sizeof(MD_INST_TYPE)/* virtual memory segment limits */#define MD_TEXT_BASE 0x20000000ULL#define MD_STACK_BASE (MD_TEXT_BASE - (409600+4096))/* well known registers */enum { REG_V0, REG_A0=16, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_ERR=7, REG_GP=29, REG_SP, REG_ZERO, REG_RA=26 };/* total number of register in processor 32I+32F+HI+LO+FCC+TMP+MEM+CTRL */#define MD_TOTAL_REGS \ (MD_NUM_REGS+MD_NUM_REGS+/*FPCR*/1+/*UNIQ*/1+/*MEM*/1+/*CTRL*/1)/* inst check macros, activated if NO_ICHECKS is not defined (default) */#ifndef NO_ICHECKS/* instruction failure notification macro, this can be defined by the target simulator if, for example, the simulator wants to handle the instruction fault in a machine specific fashion; a string describing the instruction fault is passed to the IFAIL() macro */#ifndef IFAIL#define IFAIL(S) fatal(S)#endif /* IFAIL *//* check for overflow in X+Y, both signed */#define OVER(X,Y) (((((X) > 0) && ((Y) > 0) \ && (MAXINT_VAL - (X) < (Y))) \ ? IFAIL("+ overflow") : (void)0), \ ((((X) < 0) && ((Y) < 0) \ && (-MAXINT_VAL - (X) > (Y))) \ ? IFAIL("+ underflow") : (void)0))/* check for underflow in X-Y, both signed */#define UNDER(X,Y) (((((X) > 0) && ((Y) < 0) \ && (MAXINT_VAL + (Y) < (X))) \ ? IFAIL("- overflow") : (void)0), \ ((((X) < 0) && ((Y) > 0) \ && (-MAXINT_VAL + (Y) > (X))) \ ? IFAIL("- underflow") : (void)0))/* check for divide by zero error, N is denom */#define DIV0(N) (((N) == 0) ? IFAIL("divide by 0") : (void)0)/* check reg specifier N for required double integer word alignment */#define INTALIGN(N) (((N) & 01) \ ? IFAIL("bad INT register alignment") : (void)0)/* check reg specifier N for required double FP word alignment */#define FPALIGN(N) (((N) & 01) \ ? IFAIL("bad FP register alignment") : (void)0)/* check target address TARG for required jump target alignment */#define TALIGN(TARG) (((TARG) & 0x7) \ ? IFAIL("bad jump alignment") : (void)0)#else /* NO_ICHECKS *//* inst checks disables, change all checks to NOP expressions */#define OVER(X,Y) ((void)0)#define UNDER(X,Y) ((void)0)#define DIV0(N) ((void)0)#define INTALIGN(N) ((void)0)#define FPALIGN(N) ((void)0)#define TALIGN(TARG) ((void)0)#endif /* NO_ICHECKS *//* default division operator semantics, this operation is accessed through a macro because some simulators need to check for divide by zero faults before executing this operation */#define IDIV(A, B) ((A) / (B))#define IMOD(A, B) ((A) % (B))#define FDIV(A, B) ((A) / (B))#define FINT(A) ((int)A)#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -