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

📄 interp.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
      int uncached;      if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,			      isTARGET, isREAL))	{	  const uword64 mask = 0x7;	  const unsigned int reverse = ReverseEndian ? 1 : 0;	  const unsigned int bigend = BigEndianCPU ? 1 : 0;	  uword64 memval;	  unsigned int byte;	  paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));	  LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,			       isDATA, isREAL);	  byte = (vaddr & mask) ^ (bigend << 2);	  return EXTEND32 (memval >> (8 * byte));	}    }  return 0;}/* Simulate the mips16 entry and exit pseudo-instructions.  These   would normally be handled by the reserved instruction exception   code, but for ease of simulation we just handle them directly.  */static voidmips16_entry (SIM_DESC sd,	      sim_cpu *cpu,	      address_word cia,	      unsigned int insn){  int aregs, sregs, rreg;#ifdef DEBUG  printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);#endif /* DEBUG */  aregs = (insn & 0x700) >> 8;  sregs = (insn & 0x0c0) >> 6;  rreg =  (insn & 0x020) >> 5;  /* This should be checked by the caller.  */  if (sregs == 3)    abort ();  if (aregs < 5)    {      int i;      signed_word tsp;      /* This is the entry pseudo-instruction.  */      for (i = 0; i < aregs; i++)	store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);      tsp = SP;      SP -= 32;      if (rreg)	{	  tsp -= 4;	  store_word (SD, CPU, cia, (uword64) tsp, RA);	}      for (i = 0; i < sregs; i++)	{	  tsp -= 4;	  store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);	}    }  else    {      int i;      signed_word tsp;      /* This is the exit pseudo-instruction.  */      tsp = SP + 32;      if (rreg)	{	  tsp -= 4;	  RA = load_word (SD, CPU, cia, (uword64) tsp);	}      for (i = 0; i < sregs; i++)	{	  tsp -= 4;	  GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);	}      SP += 32;      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)	{	  if (aregs == 5)	    {	      FGR[0] = WORD64LO (GPR[4]);	      FPR_STATE[0] = fmt_uninterpreted;	    }	  else if (aregs == 6)	    {	      FGR[0] = WORD64LO (GPR[5]);	      FGR[1] = WORD64LO (GPR[4]);	      FPR_STATE[0] = fmt_uninterpreted;	      FPR_STATE[1] = fmt_uninterpreted;	    }	}	        PC = RA;    }  }/*-- trace support ----------------------------------------------------------*//* The TRACE support is provided (if required) in the memory accessing   routines. Since we are also providing the architecture specific   features, the architecture simulation code can also deal with   notifying the TRACE world of cache flushes, etc. Similarly we do   not need to provide profiling support in the simulator engine,   since we can sample in the instruction fetch control loop. By   defining the TRACE manifest, we add tracing as a run-time   option. */#if defined(TRACE)/* Tracing by default produces "din" format (as required by   dineroIII). Each line of such a trace file *MUST* have a din label   and address field. The rest of the line is ignored, so comments can   be included if desired. The first field is the label which must be   one of the following values:	0       read data        1       write data        2       instruction fetch        3       escape record (treated as unknown access type)        4       escape record (causes cache flush)   The address field is a 32bit (lower-case) hexadecimal address   value. The address should *NOT* be preceded by "0x".   The size of the memory transfer is not important when dealing with   cache lines (as long as no more than a cache line can be   transferred in a single operation :-), however more information   could be given following the dineroIII requirement to allow more   complete memory and cache simulators to provide better   results. i.e. the University of Pisa has a cache simulator that can   also take bus size and speed as (variable) inputs to calculate   complete system performance (a much more useful ability when trying   to construct an end product, rather than a processor). They   currently have an ARM version of their tool called ChARM. */voiddotrace (SIM_DESC sd,	 sim_cpu *cpu,	 FILE *tracefh,	 int type,	 SIM_ADDR address,	 int width,	 char *comment,...){  if (STATE & simTRACE) {    va_list ap;    fprintf(tracefh,"%d %s ; width %d ; ", 		type,		pr_addr(address),		width);    va_start(ap,comment);    vfprintf(tracefh,comment,ap);    va_end(ap);    fprintf(tracefh,"\n");  }  /* NOTE: Since the "din" format will only accept 32bit addresses, and     we may be generating 64bit ones, we should put the hi-32bits of the     address into the comment field. */  /* TODO: Provide a buffer for the trace lines. We can then avoid     performing writes until the buffer is filled, or the file is     being closed. */  /* NOTE: We could consider adding a comment field to the "din" file     produced using type 3 markers (unknown access). This would then     allow information about the program that the "din" is for, and     the MIPs world that was being simulated, to be placed into the     trace file. */  return;}#endif /* TRACE *//*---------------------------------------------------------------------------*//*-- simulator engine -------------------------------------------------------*//*---------------------------------------------------------------------------*/static voidColdReset (SIM_DESC sd){  int cpu_nr;  for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)    {      sim_cpu *cpu = STATE_CPU (sd, cpu_nr);      /* RESET: Fixed PC address: */      PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000);      /* The reset vector address is in the unmapped, uncached memory space. */            SR &= ~(status_SR | status_TS | status_RP);      SR |= (status_ERL | status_BEV);            /* Cheat and allow access to the complete register set immediately */      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT	  && WITH_TARGET_WORD_BITSIZE == 64)	SR |= status_FR; /* 64bit registers */            /* Ensure that any instructions with pending register updates are	 cleared: */      PENDING_INVALIDATE();            /* Initialise the FPU registers to the unknown state */      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)	{	  int rn;	  for (rn = 0; (rn < 32); rn++)	    FPR_STATE[rn] = fmt_uninterpreted;	}          }}/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) *//* Signal an exception condition. This will result in an exception   that aborts the instruction. The instruction operation pseudocode   will never see a return from this function call. */voidsignal_exception (SIM_DESC sd,		  sim_cpu *cpu,		  address_word cia,		  int exception,...){  /* int vector; */#ifdef DEBUG  sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));#endif /* DEBUG */  /* Ensure that any active atomic read/modify/write operation will fail: */  LLBIT = 0;  /* Save registers before interrupt dispatching */#ifdef SIM_CPU_EXCEPTION_TRIGGER  SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);#endif  switch (exception) {    case DebugBreakPoint:      if (! (Debug & Debug_DM))        {          if (INDELAYSLOT())            {              CANCELDELAYSLOT();                            Debug |= Debug_DBD;  /* signaled from within in delay slot */              DEPC = cia - 4;      /* reference the branch instruction */            }          else            {              Debug &= ~Debug_DBD; /* not signaled from within a delay slot */              DEPC = cia;            }                  Debug |= Debug_DM;            /* in debugging mode */          Debug |= Debug_DBp;           /* raising a DBp exception */          PC = 0xBFC00200;          sim_engine_restart (SD, CPU, NULL, NULL_CIA);        }      break;    case ReservedInstruction:     {       va_list ap;       unsigned int instruction;       va_start(ap,exception);       instruction = va_arg(ap,unsigned int);       va_end(ap);       /* Provide simple monitor support using ReservedInstruction          exceptions. The following code simulates the fixed vector          entry points into the IDT monitor by causing a simulator          trap, performing the monitor operation, and returning to          the address held in the $ra register (standard PCS return          address). This means we only need to pre-load the vector          space with suitable instruction values. For systems were          actual trap instructions are used, we would not need to          perform this magic. */       if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)	 {	   int reason = (instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK;	   if (!sim_monitor (SD, CPU, cia, reason))	     sim_io_error (sd, "sim_monitor: unhandled reason = %d, pc = 0x%s\n", reason, pr_addr (cia));	   /* NOTE: This assumes that a branch-and-link style	      instruction was used to enter the vector (which is the	      case with the current IDT monitor). */	   sim_engine_restart (SD, CPU, NULL, RA);	 }       /* Look for the mips16 entry and exit instructions, and          simulate a handler for them.  */       else if ((cia & 1) != 0		&& (instruction & 0xf81f) == 0xe809		&& (instruction & 0x0c0) != 0x0c0)	 {	   mips16_entry (SD, CPU, cia, instruction);	   sim_engine_restart (sd, NULL, NULL, NULL_CIA);	 }       /* else fall through to normal exception processing */       sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));     }    default:     /* Store exception code into current exception id variable (used        by exit code): */     /* TODO: If not simulating exceptions then stop the simulator        execution. At the moment we always stop the simulation. */#ifdef SUBTARGET_R3900      /* update interrupt-related registers */      /* insert exception code in bits 6:2 */      CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2);      /* shift IE/KU history bits left */      SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2);      if (STATE & simDELAYSLOT)	{	  STATE &= ~simDELAYSLOT;	  CAUSE |= cause_BD;	  EPC = (cia - 4); /* reference the branch instruction */	}      else	EPC = cia;     if (SR & status_BEV)       PC = (signed)0xBFC00000 + 0x180;     else       PC = (signed)0x80000000 + 0x080;#else     /* See figure 5-17 for an outline of the code below */     if (! (SR & status_EXL))       {	 CAUSE = (exception << 2);	 if (STATE & simDELAYSLOT)	   {	     STATE &= ~simDELAYSLOT;	     CAUSE |= cause_BD;	     EPC = (cia - 4); /* reference the branch instruction */	   }	 else	   EPC = cia;	 /* FIXME: TLB et.al. */	 /* vector = 0x180; */       }     else       {	 CAUSE = (exception << 2);	 /* vector = 0x180; */       }     SR |= status_EXL;     /* Store exception code into current exception id variable (used        by exit code): */     if (SR & status_BEV)       PC = (signed)0xBFC00200 + 0x180;     else       PC = (signed)0x80000000 + 0x180;#endif     switch ((CAUSE >> 2) & 0x1F)       {       case Interrupt:	 /* Interrupts arrive during event processing, no need to            restart */	 return;       case NMIReset:	 /* Ditto */#ifdef SUBTARGET_3900	 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000  */	 PC = (signed)0xBFC00000;#endif /* SUBTARGET_3900 */	 return;       case TLBModification:       case TLBLoad:       case TLBStore:       case AddressLoad:       case AddressStore:       case InstructionFetch:       case DataReference:	 /* The following is so that the simulator will continue from the	    exception handler address. */	 sim_engine_halt (SD, CPU, NULL, PC,			  sim_stopped, SIM_SIGBUS);       case ReservedInstruction:       case CoProcessorUnusable:	 PC = EPC;	 sim_engine_halt (SD, CPU, NULL, PC,			  sim_stopped, SIM_SIGILL);       case IntegerOverflow:       case FPE:	 sim_engine_halt (SD, CPU, NULL, PC,			  sim_stopped, SIM_SIGFPE);	        case BreakPoint:	 sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);	 break;       case SystemCall:       case Trap:	 sim_engine_restart (SD, CPU, NULL, PC);	 break;       case Watch:	 PC = EPC;	 sim_engine_halt (SD, CPU, NULL, PC,			  sim_stopped, SIM_SIGTRAP);       default: /* Unknown internal exception */	 PC = EPC;	 sim_engine_halt (SD, CPU, NULL, PC,			  sim_stopped, SIM_SIGABRT);       }    case SimulatorFault:     {       va_list ap;       char *msg;       va_start(ap,exception);       msg = va_arg(ap,char *);       va_end(ap);       sim_engine_abort (SD, CPU, NULL_CIA,			 "FATAL: Simulator error \"%s\"\n",msg);     }   }  return;}/* This function implements what the MIPS32 and MIPS64 ISAs define as   "UNPREDICTABLE" behaviour.   About UNPREDICTABLE behaviour they say: "UNPREDICTABLE results   may vary from processor implementation to processor implementation,   instruction to instruction, or as a function of time on the same   implementation or instruction.  Software can never depend on results   that are UNPREDICTABLE. ..."  (MIPS64 Architecture for Programmers   Volume II, The MIPS64 Instruction Set.  MIPS Document MD00087 revision   0.95, page 2.)     For UNPREDICTABLE behaviour, we print a message, if possible print   the offending instructions mips.igen instruction name (provided by   the caller), and stop the simulator.

⌨️ 快捷键说明

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