⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pisa.h

📁 一个很有名的硬件模拟器。可以模拟CPU
💻 H
📖 第 1 页 / 共 2 页
字号:
/* #else *//* lwl/swl stuff */#define WL_SIZE(ADDR)		((ADDR) & 0x03)#define WL_BASE(ADDR)		((ADDR) & ~0x03)#define WL_PROT_MASK1(ADDR)	(md_lr_masks[WL_SIZE(ADDR)])#define WL_PROT_MASK2(ADDR)	(md_lr_masks[4-WL_SIZE(ADDR)])/* lwr/swr stuff */#define WR_SIZE(ADDR)		(((ADDR) & 0x03)+1)#define WR_BASE(ADDR)		((ADDR) & ~0x03)#define WR_PROT_MASK1(ADDR)	((md_lr_masks[WR_SIZE(ADDR)]))#define WR_PROT_MASK2(ADDR)	(md_lr_masks[4-WR_SIZE(ADDR)])#endif/* * various other helper macros/functions *//* non-zero if system call is an exit() */#define	SS_SYS_exit			1#define MD_EXIT_SYSCALL(REGS)		((REGS)->regs_R[2] == SS_SYS_exit)/* non-zero if system call is a write to stdout/stderr */#define	SS_SYS_write		4#define MD_OUTPUT_SYSCALL(REGS)						\  ((REGS)->regs_R[2] == SS_SYS_write					\   && ((REGS)->regs_R[4] == /* stdout */1				\       || (REGS)->regs_R[4] == /* stderr */2))/* returns stream of an output system call, translated to host */#define MD_STREAM_FILENO(REGS)		((REGS)->regs_R[4])/* returns non-zero if instruction is a function call */#define MD_IS_CALL(OP)							\  ((MD_OP_FLAGS(OP) & (F_CTRL|F_CALL)) == (F_CTRL|F_CALL))/* returns non-zero if instruction is a function return */#define MD_IS_RETURN(OP)		((OP) == JR && (RS) == 31)/* returns non-zero if instruction is an indirect jump */#define MD_IS_INDIR(OP)			((OP) == JR)/* 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)					\  { if ((OP) == LUI) (FSM) = (RT); }/* compute addressing mode, only for loads/stores */#define MD_AMODE_PROBE(AM, OP, FSM)					\  {									\    if (MD_OP_FLAGS(OP) & F_DISP)					\      {									\	if ((BS) == (FSM))						\	  (AM) = md_amode_imm;						\	else if ((BS) == MD_REG_GP)					\	  (AM) = md_amode_gp;						\	else if ((BS) == MD_REG_SP)					\	  (AM) = md_amode_sp;						\	else if ((BS) == 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)						\  { (FSM) = MD_REG_ZERO; }/* * EIO package configuration/macros *//* expected EIO file format */#define MD_EIO_FILE_FORMAT		EIO_PISA_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),	\	  /*HI*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.hi),	\	  /*LO*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.lo),	\	  /*FCC*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.fcc),\	  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.l[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		\      || exo->as_list.head->next->next->next->next->next->ec != ec_integer\      || exo->as_list.head->next->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_address.val;	\  (REGS)->regs_NPC =							\    (md_addr_t)exo->as_list.head->next->next->as_address.val;		\  (REGS)->regs_C.hi =							\    (word_t)exo->as_list.head->next->next->next->as_integer.val;	\  (REGS)->regs_C.lo =							\    (word_t)exo->as_list.head->next->next->next->next->as_integer.val;	\  (REGS)->regs_C.fcc =							\    (int)exo->as_list.head->next->next->next->next->next->as_integer.val;#define MD_EXO_TO_IREG(EXO, REGS, IDX)					\  ((REGS)->regs_R[IDX] = (word_t)(EXO)->as_integer.val)#define MD_EXO_TO_FREG(EXO, REGS, IDX)					\  ((REGS)->regs_F.l[IDX] = (word_t)(EXO)->as_integer.val)#define MD_EXO_CMP_IREG(EXO, REGS, IDX)					\  ((REGS)->regs_R[IDX] != (sword_t)(EXO)->as_integer.val)#define MD_FIRST_IN_REG			2#define MD_LAST_IN_REG			7#define MD_FIRST_OUT_REG		2#define MD_LAST_OUT_REG			7/* * 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 */#ifdef HOST_HAS_QWORD#define stat_reg_counter		stat_reg_sqword#define sc_counter			sc_sqword#define for_counter			for_sqword#else /* !HOST_HAS_QWORD */#define stat_reg_counter		stat_reg_double#define sc_counter			sc_double#define for_counter			for_double#endif /* HOST_HAS_QWORD *//* address stats */#define stat_reg_addr			stat_reg_uint/* * 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);/* compute CRC of all registers */word_t md_crc_regs(struct regs_t *regs);/* 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		ADD/* NOP operation when injected into the pipeline */#define MD_NOP_OP		NOP/* 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_stack_base))/* * configure branch predictors *//* shift used to ignore branch address least significant bits, usually   log2(sizeof(md_inst_t)) */#define MD_BR_SHIFT		3	/* log2(8) *//* * target-dependent routines *//* intialize the inst decoder, this function builds the ISA decode tables */void md_init_decoder(void);/* disassemble an 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 /* PISA_H */#if 0/* virtual memory page size, this should be user configurable */#define SS_PAGE_SIZE		4096/* total number of registers in each register file (int and FP) */#define SS_NUM_REGS		32/* total number of register in processor 32I+32F+HI+LO+FCC+TMP+MEM+CTRL */#define SS_TOTAL_REGS							\  (SS_NUM_REGS+SS_NUM_REGS+/*HI*/1+/*LO*/1+/*FCC*/1+/*TMP*/1+		\   /*MEM*/1+/*CTRL*/1)/* returns pre/post-incr/decr operation field value */#define SS_COMP_OP		((inst.a & 0xff00) >> 8)/* pre/post-incr/decr operation field specifiers */#define SS_COMP_NOP		0x00#define SS_COMP_POST_INC	0x01#define SS_COMP_POST_DEC	0x02#define SS_COMP_PRE_INC		0x03#define SS_COMP_PRE_DEC		0x04#define SS_COMP_POST_DBL_INC	0x05	/* for double word accesses */#define SS_COMP_POST_DBL_DEC	0x06#define SS_COMP_PRE_DBL_INC	0x07#define SS_COMP_PRE_DBL_DEC	0x08/* the instruction expression modifications required for an expression to   support pre/post-incr/decr operations is accomplished by the INC_DEC()   macro, it looks so contorted to reduce the control complexity of the   equation (and thus reducing the compilation time greatly with GNU GCC -   the key is to only emit EXPR one time) */#define INC_DEC(EXPR, REG, SIZE)					\  (SET_GPR((REG), GPR(REG) + ss_fore_tab[(SIZE)-1][SS_COMP_OP]),	\   (EXPR),								\   SET_GPR((REG), GPR(REG) + ss_aft_tab[(SIZE)-1][SS_COMP_OP]))/* INC_DEC expression step tables, they map (operation, size) -> step value */extern int ss_fore_tab[8][5];extern int ss_aft_tab[8][5];/* pre-defined registers */#define Rgp		28		/* global data pointer */#define Rsp		29		/* stack pointer */#define Rfp		30		/* frame pointer *//* FIXME: non-reentrant LWL/LWR implementation workspace */extern SS_ADDR_TYPE ss_lr_temp;/* FIXME: non-reentrant temporary variables */extern SS_ADDR_TYPE temp_bs, temp_rd;/* 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 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)/* 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)/* 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 + -