pisa.c

来自「一个很有名的硬件模拟器。可以模拟CPU」· C语言 代码 · 共 723 行 · 第 1/2 页

C
723
字号
      break;    case rt_ctrl:      switch (reg)	{	case /* HI */0:	  if (!is_write)	    {	      val->type = et_uint;	      val->value.as_uint = regs->regs_C.hi;	    }	  else	    regs->regs_C.hi = eval_as_uint(*val);	  break;	case /* LO */1:	  if (!is_write)	    {	      val->type = et_uint;	      val->value.as_uint = regs->regs_C.lo;	    }	  else	    regs->regs_C.lo = eval_as_uint(*val);	  break;	case /* FCC */2:	  if (!is_write)	    {	      val->type = et_int;	      val->value.as_int = regs->regs_C.fcc;	    }	  else	    regs->regs_C.fcc = eval_as_uint(*val);	  break;	default:	  return "register number out of range";	}      break;    case rt_PC:      if (!is_write)	{	  val->type = et_addr;	  val->value.as_addr = regs->regs_PC;	}      else	regs->regs_PC = eval_as_addr(*val);      break;    case rt_NPC:      if (!is_write)	{	  val->type = et_addr;	  val->value.as_addr = regs->regs_NPC;	}      else	regs->regs_NPC = eval_as_addr(*val);      break;    default:      panic("bogus register bank");    }  /* no error */  return NULL;}/* print integer REG(S) to STREAM */voidmd_print_ireg(md_gpr_t regs, int reg, FILE *stream){  fprintf(stream, "%4s: %12d/0x%08x",	  md_reg_name(rt_gpr, reg), regs[reg], regs[reg]);}voidmd_print_iregs(md_gpr_t regs, FILE *stream){  int i;  for (i=0; i < MD_NUM_IREGS; i += 2)    {      md_print_ireg(regs, i, stream);      fprintf(stream, "  ");      md_print_ireg(regs, i+1, stream);      fprintf(stream, "\n");    }}/* print floating point REGS to STREAM */voidmd_print_fpreg(md_fpr_t regs, int reg, FILE *stream){  fprintf(stream, "%4s: %12d/0x%08x/%f",	  md_reg_name(rt_fpr, reg), regs.l[reg], regs.l[reg], regs.f[reg]);  if (/* even? */!(reg & 1))    {      fprintf(stream, " (%4s as double: %f)",	      md_reg_name(rt_dpr, reg/2), regs.d[reg/2]);    }}voidmd_print_fpregs(md_fpr_t regs, FILE *stream){  int i;  /* floating point registers */  for (i=0; i < MD_NUM_FREGS; i += 2)    {      md_print_fpreg(regs, i, stream);      fprintf(stream, "\n");      md_print_fpreg(regs, i+1, stream);      fprintf(stream, "\n");    }}voidmd_print_creg(md_ctrl_t regs, int reg, FILE *stream){  /* index is only used to iterate over these registers, hence no enums... */  switch (reg)    {    case 0:      fprintf(stream, "HI: 0x%08x", regs.hi);      break;    case 1:      fprintf(stream, "LO: 0x%08x", regs.lo);      break;    case 2:      fprintf(stream, "FCC: 0x%08x", regs.fcc);      break;    default:      panic("bogus control register index");    }}voidmd_print_cregs(md_ctrl_t regs, FILE *stream){  md_print_creg(regs, 0, stream);  fprintf(stream, "  ");  md_print_creg(regs, 1, stream);  fprintf(stream, "  ");  md_print_creg(regs, 2, stream);  fprintf(stream, "\n");}/* compute CRC of all registers */word_tmd_crc_regs(struct regs_t *regs){  int i;  word_t crc_accum = 0;  for (i=0; i < MD_NUM_IREGS; i++)    crc_accum = crc(crc_accum, regs->regs_R[i]);  for (i=0; i < MD_NUM_FREGS; i++)    crc_accum = crc(crc_accum, regs->regs_F.l[i]);  crc_accum = crc(crc_accum, regs->regs_C.hi);  crc_accum = crc(crc_accum, regs->regs_C.lo);  crc_accum = crc(crc_accum, regs->regs_C.fcc);  crc_accum = crc(crc_accum, regs->regs_PC);  crc_accum = crc(crc_accum, regs->regs_NPC);  return crc_accum;}/* xor checksum registers */word_tmd_xor_regs(struct regs_t *regs){  int i;  word_t checksum = 0;  for (i=0; i < MD_NUM_IREGS; i++)    checksum ^= regs->regs_R[i];  for (i=0; i < MD_NUM_FREGS; i++)    checksum ^= regs->regs_F.l[i];  checksum ^= regs->regs_C.hi;  checksum ^= regs->regs_C.lo;  checksum ^= regs->regs_C.fcc;  checksum ^= regs->regs_PC;  checksum ^= regs->regs_NPC;  return checksum;}/* intialize the inst decoder, this function builds the ISA decode tables */voidmd_init_decoder(void){  /* FIXME: CONNECT defined? */#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\  if (md_mask2op[(MSK)]) fatal("doubly defined mask value");		\  if ((MSK) >= MD_MAX_MASK) fatal("mask value is too large");		\  md_mask2op[(MSK)]=(OP);#include "machine.def"}/* 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 */{  enum md_opcode op;  /* use stderr as default output stream */  if (!stream)    stream = stderr;  /* decode the instruction, assumes predecoded text segment */  MD_SET_OPCODE(op, inst);  /* disassemble the instruction */  if (op == OP_NA || op >= OP_MAX)    {      /* bogus instruction */      fprintf(stream, "<invalid inst: 0x%08x:%08x>", inst.a, inst.b);    }  else    {      char *s;      fprintf(stream, "%-10s", MD_OP_NAME(op));      s = MD_OP_FORMAT(op);      while (*s) {	switch (*s) {	case 'd':	  fprintf(stream, "r%d", RD);	  break;	case 's':	  fprintf(stream, "r%d", RS);	  break;	case 't':	  fprintf(stream, "r%d", RT);	  break;	case 'b':	  fprintf(stream, "r%d", BS);	  break;	case 'D':	  fprintf(stream, "f%d", FD);	  break;	case 'S':	  fprintf(stream, "f%d", FS);	  break;	case 'T':	  fprintf(stream, "f%d", FT);	  break;	case 'j':	  fprintf(stream, "0x%x", (pc + 8 + (OFS << 2)));	  break;	case 'o':	case 'i':	  fprintf(stream, "%d", IMM);	  break;	case 'H':	  fprintf(stream, "%d", SHAMT);	  break;	case 'u':	  fprintf(stream, "%u", UIMM);	  break;	case 'U':	  fprintf(stream, "0x%x", UIMM);	  break;	case 'J':	  fprintf(stream, "0x%x", ((pc & 036000000000) | (TARG << 2)));	  break;	case 'B':	  fprintf(stream, "0x%x", BCODE);	  break;#if 0 /* FIXME: obsolete... */	case ')':	  /* handle pre- or post-inc/dec */	  if (SS_COMP_OP == SS_COMP_NOP)	    fprintf(stream, ")");	  else if (SS_COMP_OP == SS_COMP_POST_INC)	    fprintf(stream, ")+");	  else if (SS_COMP_OP == SS_COMP_POST_DEC)	    fprintf(stream, ")-");	  else if (SS_COMP_OP == SS_COMP_PRE_INC)	    fprintf(stream, ")^+");	  else if (SS_COMP_OP == SS_COMP_PRE_DEC)	    fprintf(stream, ")^-");	  else if (SS_COMP_OP == SS_COMP_POST_DBL_INC)	    fprintf(stream, ")++");	  else if (SS_COMP_OP == SS_COMP_POST_DBL_DEC)	    fprintf(stream, ")--");	  else if (SS_COMP_OP == SS_COMP_PRE_DBL_INC)	    fprintf(stream, ")^++");	  else if (SS_COMP_OP == SS_COMP_PRE_DBL_DEC)	    fprintf(stream, ")^--");	  else	    panic("bogus SS_COMP_OP");	  break;#endif	default:	  /* anything unrecognized, e.g., '.' is just passed through */	  fputc(*s, stream);	}	s++;      }    }}#if 0/* INC_DEC expression step tables, they map (operation, size) -> step value,   and speed up pre/post-incr/desc handling *//* force a nasty address */#define XX		0x6bababab/* before increment */int ss_fore_tab[/* operand size */8][/* operation */5] = {             /* NOP   POSTI POSTD  PREI   PRED *//* byte */    {  0,    0,    0,     1,     -1,  },/* half */    {  0,    0,    0,     2,     -2,  },/* invalid */ {  XX,   XX,   XX,    XX,    XX,  },/* word */    {  0,    0,    0,     4,     -4,  },/* invalid */ {  XX,   XX,   XX,    XX,    XX,  },/* invalid */ {  XX,   XX,   XX,    XX,    XX,  },/* invalid */ {  XX,   XX,   XX,    XX,    XX,  },/* dword */   {  0,    0,    0,     8,     -8,  },};/* after increment */int ss_aft_tab[/* operand size */8][/* operation */5] = {             /* NOP   POSTI POSTD  PREI   PRED *//* byte */    {  0,    1,    -1,    0,     0,   },/* half */    {  0,    2,    -2,    0,     0,   },/* invalid */ {  XX,   XX,   XX,    XX,    XX,  },/* word */    {  0,    4,    -4,    0,     0,   },/* invalid */ {  XX,   XX,   XX,    XX,    XX,  },/* invalid */ {  XX,   XX,   XX,    XX,    XX,  },/* invalid */ {  XX,   XX,   XX,    XX,    XX,  },/* dword */   {  0,    8,    -8,    0,     0,   },};/* LWL/LWR implementation workspace */md_addr_t ss_lr_temp;/* temporary variables */md_addr_t temp_bs, temp_rd;#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?