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

📄 ppc32_exec.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Cisco router simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) * * PowerPC (32-bit) step-by-step execution. */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include <fcntl.h>#include <assert.h>#include "cpu.h"#include "vm.h"#include "ppc32_exec.h"#include "ppc32_mem.h"#include "memory.h"#include "insn_lookup.h"#include "dynamips.h"/* Forward declaration of instruction array */static struct ppc32_insn_exec_tag ppc32_exec_tags[];static insn_lookup_t *ilt = NULL;/* ILT */static forced_inline void *ppc32_exec_get_insn(int index){   return(&ppc32_exec_tags[index]);}static int ppc32_exec_chk_lo(struct ppc32_insn_exec_tag *tag,int value){   return((value & tag->mask) == (tag->value & 0xFFFF));}static int ppc32_exec_chk_hi(struct ppc32_insn_exec_tag *tag,int value){         return((value & (tag->mask >> 16)) == (tag->value >> 16));}/* Initialize instruction lookup table */void ppc32_exec_create_ilt(void){   int i,count;   for(i=0,count=0;ppc32_exec_tags[i].exec;i++)      count++;   ilt = ilt_create("ppc32e",count,                    (ilt_get_insn_cbk_t)ppc32_exec_get_insn,                    (ilt_check_cbk_t)ppc32_exec_chk_lo,                    (ilt_check_cbk_t)ppc32_exec_chk_hi);}/* Dump statistics */void ppc32_dump_stats(cpu_ppc_t *cpu){   int i;#if NJM_STATS_ENABLE   printf("\n");   for(i=0;ppc32_exec_tags[i].exec;i++)      printf("  * %-10s : %10llu\n",             ppc32_exec_tags[i].name,ppc32_exec_tags[i].count);   printf("%llu instructions executed since startup.\n",cpu->insn_exec_count);#else   printf("Statistics support is not compiled in.\n");#endif}/* Execute a memory operation */static forced_inline void ppc32_exec_memop(cpu_ppc_t *cpu,int memop,                                           m_uint32_t vaddr,u_int dst_reg){        fastcall ppc_memop_fn fn;       fn = cpu->mem_op_fn[memop];   fn(cpu,vaddr,dst_reg);}/* Fetch an instruction */static forced_inline int ppc32_exec_fetch(cpu_ppc_t *cpu,m_uint32_t ia,                                          ppc_insn_t *insn){   m_uint32_t exec_page,offset;   exec_page = ia & ~PPC32_MIN_PAGE_IMASK;   if (unlikely(exec_page != cpu->njm_exec_page)) {      cpu->njm_exec_page = exec_page;      cpu->njm_exec_ptr  = cpu->mem_op_lookup(cpu,exec_page,PPC32_MTS_ICACHE);   }   offset = (ia & PPC32_MIN_PAGE_IMASK) >> 2;   *insn = vmtoh32(cpu->njm_exec_ptr[offset]);   return(0);}/* Unknown opcode */static fastcall int ppc32_exec_unknown(cpu_ppc_t *cpu,ppc_insn_t insn){      printf("PPC32: unknown opcode 0x%8.8x at ia = 0x%x\n",insn,cpu->ia);   ppc32_dump_regs(cpu->gen);   return(0);}/* Execute a single instruction */static forced_inline int ppc32_exec_single_instruction(cpu_ppc_t *cpu,ppc_insn_t instruction){   register fastcall int (*exec)(cpu_ppc_t *,ppc_insn_t) = NULL;   struct ppc32_insn_exec_tag *tag;   int index;   #if DEBUG_INSN_PERF_CNT   cpu->perf_counter++;#endif      /* Lookup for instruction */   index = ilt_lookup(ilt,instruction);   tag = ppc32_exec_get_insn(index);   exec = tag->exec;#if NJM_STATS_ENABLE   cpu->insn_exec_count++;   ppc32_exec_tags[index].count++;#endif   return(exec(cpu,instruction));}/* Execute a single instruction (external) */fastcall int ppc32_exec_single_insn_ext(cpu_ppc_t *cpu,ppc_insn_t insn){   int res;   res = ppc32_exec_single_instruction(cpu,insn);   if (likely(!res)) cpu->ia += sizeof(ppc_insn_t);   return(res);}/* Execute a page */fastcall int ppc32_exec_page(cpu_ppc_t *cpu){   m_uint32_t exec_page,offset;   ppc_insn_t insn;   int res;   exec_page = cpu->ia & ~PPC32_MIN_PAGE_IMASK;   cpu->njm_exec_page = exec_page;   cpu->njm_exec_ptr  = cpu->mem_op_lookup(cpu,exec_page,PPC32_MTS_ICACHE);   do {      offset = (cpu->ia & PPC32_MIN_PAGE_IMASK) >> 2;      insn = vmtoh32(cpu->njm_exec_ptr[offset]);      res = ppc32_exec_single_instruction(cpu,insn);      if (likely(!res)) cpu->ia += sizeof(ppc_insn_t);   }while((cpu->ia & ~PPC32_MIN_PAGE_IMASK) == exec_page);   return(0);}/* Run PowerPC code in step-by-step mode */void *ppc32_exec_run_cpu(cpu_gen_t *gen){      cpu_ppc_t *cpu = CPU_PPC32(gen);   pthread_t timer_irq_thread;   int timer_irq_check = 0;   ppc_insn_t insn;   int res;   if (pthread_create(&timer_irq_thread,NULL,                      (void *)ppc32_timer_irq_run,cpu))   {      fprintf(stderr,"VM '%s': unable to create Timer IRQ thread for CPU%u.\n",              cpu->vm->name,gen->id);      cpu_stop(gen);      return NULL;   }   gen->cpu_thread_running = TRUE;   cpu_exec_loop_set(gen); start_cpu:   for(;;) {      if (unlikely(gen->state != CPU_STATE_RUNNING))         break;      /* Check IRQ */      if (unlikely(cpu->irq_check))         ppc32_trigger_irq(cpu);      /* Handle virtual idle loop */      if (unlikely(cpu->ia == cpu->idle_pc)) {         if (++gen->idle_count == gen->idle_max) {            cpu_idle_loop(gen);            gen->idle_count = 0;         }      }      /* Handle the virtual CPU clock */      if (++timer_irq_check == cpu->timer_irq_check_itv) {         timer_irq_check = 0;         if (cpu->timer_irq_pending && !cpu->irq_disable &&              (cpu->msr & PPC32_MSR_EE))          {                    cpu->timer_irq_armed = 0;            cpu->timer_irq_pending--;            vm_set_irq(cpu->vm,0);            //ppc32_trigger_timer_irq(cpu);         }      }      /* Increment the time base */      cpu->tb += 100;      /* Fetch and execute the instruction */      ppc32_exec_fetch(cpu,cpu->ia,&insn);      res = ppc32_exec_single_instruction(cpu,insn);      /* Normal flow ? */      if (likely(!res)) cpu->ia += sizeof(ppc_insn_t);   }   /* Check regularly if the CPU has been restarted */   while(gen->cpu_thread_running) {      gen->seq_state++;      switch(gen->state) {         case CPU_STATE_RUNNING:            gen->state = CPU_STATE_RUNNING;            goto start_cpu;         case CPU_STATE_HALTED:                 gen->cpu_thread_running = FALSE;            pthread_join(timer_irq_thread,NULL);            break;      }            /* CPU is paused */      usleep(200000);   }   return NULL;}/* ========================================================================= *//* Update CR0 */static forced_inline void ppc32_exec_update_cr0(cpu_ppc_t *cpu,m_uint32_t val){   m_uint32_t res;   if (val & 0x80000000)      res = 1 << PPC32_CR_LT_BIT;   else {      if (val > 0)         res = 1 << PPC32_CR_GT_BIT;      else         res = 1 << PPC32_CR_EQ_BIT;   }   if (cpu->xer & PPC32_XER_SO)      res |= 1 << PPC32_CR_SO_BIT;   cpu->cr_fields[0] = res;}/*  * Update Overflow bit from a sum result (r = a + b) * * (a > 0) && (b > 0) => r > 0, otherwise overflow * (a < 0) && (a < 0) => r < 0, otherwise overflow. */static forced_inline void ppc32_exec_ov_sum(cpu_ppc_t *cpu,m_uint32_t r,                                            m_uint32_t a,m_uint32_t b){   register m_uint32_t sc;   sc = (~(a ^ b) & (a ^ r) & 0x80000000);   if (unlikely(sc))      cpu->xer |= PPC32_XER_SO | PPC32_XER_OV;   else      cpu->xer &= ~PPC32_XER_OV;}/*  * Update Overflow bit from a substraction result (r = a - b) * * (a > 0) && (b < 0) => r > 0, otherwise overflow * (a < 0) && (a > 0) => r < 0, otherwise overflow. */static forced_inline void ppc32_exec_ov_sub(cpu_ppc_t *cpu,m_uint32_t r,                                            m_uint32_t a,m_uint32_t b){   register m_uint32_t sc;   sc = ((a ^ b) & (a ^ r) & 0x80000000);   if (unlikely(sc))      cpu->xer |= PPC32_XER_SO | PPC32_XER_OV;   else      cpu->xer &= ~PPC32_XER_OV;}/*  * Update CA bit from a sum result (r = a + b) */static forced_inline void ppc32_exec_ca_sum(cpu_ppc_t *cpu,m_uint32_t r,                                            m_uint32_t a,m_uint32_t b){   cpu->xer_ca = (r < a) ? 1 : 0;}/*  * Update CA bit from a substraction result (r = a - b) */static forced_inline void ppc32_exec_ca_sub(cpu_ppc_t *cpu,m_uint32_t r,                                            m_uint32_t a,m_uint32_t b){   cpu->xer_ca = (b > a) ? 1 : 0;}/* Check condition code */static forced_inline int ppc32_check_cond(cpu_ppc_t *cpu,m_uint32_t bo,                                          m_uint32_t bi){   u_int ctr_ok = TRUE;   u_int cond_ok;   u_int cr_bit;   if (!(bo & 0x04)) {      cpu->ctr--;      ctr_ok = (cpu->ctr != 0) ^ ((bo >> 1) & 0x1);   }   cr_bit = ppc32_read_cr_bit(cpu,bi);   cond_ok = (bo >> 4) | ((cr_bit ^ (~bo >> 3)) & 0x1);   return(ctr_ok & cond_ok);}/* MFLR - Move From Link Register */static fastcall int ppc32_exec_MFLR(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   cpu->gpr[rd] = cpu->lr;   return(0);}/* MTLR - Move To Link Register */static fastcall int ppc32_exec_MTLR(cpu_ppc_t *cpu,ppc_insn_t insn){   int rs = bits(insn,21,25);   cpu->lr = cpu->gpr[rs];   return(0);}/* MFCTR - Move From Counter Register */static fastcall int ppc32_exec_MFCTR(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   cpu->gpr[rd] = cpu->ctr;   return(0);}/* MTCTR - Move To Counter Register */static fastcall int ppc32_exec_MTCTR(cpu_ppc_t *cpu,ppc_insn_t insn){   int rs = bits(insn,21,25);   cpu->ctr = cpu->gpr[rs];   return(0);}/* ADD */static fastcall int ppc32_exec_ADD(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   int ra = bits(insn,16,20);   int rb = bits(insn,11,15);   cpu->gpr[rd] = cpu->gpr[ra] + cpu->gpr[rb];   return(0);}/* ADD. */static fastcall int ppc32_exec_ADD_dot(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   int ra = bits(insn,16,20);   int rb = bits(insn,11,15);   register m_uint32_t tmp;   tmp = cpu->gpr[ra] + cpu->gpr[rb];   ppc32_exec_update_cr0(cpu,tmp);   cpu->gpr[rd] = tmp;   return(0);}/* ADDO - Add with Overflow */static fastcall int ppc32_exec_ADDO(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   int ra = bits(insn,16,20);   int rb = bits(insn,11,15);   register m_uint32_t a,b,d;   a = cpu->gpr[ra];   b = cpu->gpr[rb];   d = a + b;   ppc32_exec_ov_sum(cpu,d,a,b);   cpu->gpr[rd] = d;   return(0);}/* ADDO. */static fastcall int ppc32_exec_ADDO_dot(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   int ra = bits(insn,16,20);   int rb = bits(insn,11,15);   register m_uint32_t a,b,d;   a = cpu->gpr[ra];   b = cpu->gpr[rb];   d = a + b;   ppc32_exec_ov_sum(cpu,d,a,b);     ppc32_exec_update_cr0(cpu,d);   cpu->gpr[rd] = d;   return(0);}/* ADDC - Add Carrying */static fastcall int ppc32_exec_ADDC(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   int ra = bits(insn,16,20);   int rb = bits(insn,11,15);   register m_uint32_t a,b,d;   a = cpu->gpr[ra];   b = cpu->gpr[rb];   d = a + b;   ppc32_exec_ca_sum(cpu,d,a,b);   cpu->gpr[rd] = d;   return(0);}/* ADDC. */static fastcall int ppc32_exec_ADDC_dot(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   int ra = bits(insn,16,20);   int rb = bits(insn,11,15);   register m_uint32_t a,b,d;   a = cpu->gpr[ra];   b = cpu->gpr[rb];   d = a + b;   ppc32_exec_ca_sum(cpu,d,a,b);   ppc32_exec_update_cr0(cpu,d);   cpu->gpr[rd] = d;   return(0);}/* ADDCO - Add Carrying with Overflow */static fastcall int ppc32_exec_ADDCO(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   int ra = bits(insn,16,20);   int rb = bits(insn,11,15);   register m_uint32_t a,b,d;   a = cpu->gpr[ra];   b = cpu->gpr[rb];   d = a + b;   ppc32_exec_ca_sum(cpu,d,a,b);   ppc32_exec_ov_sum(cpu,d,a,b);   cpu->gpr[rd] = d;   return(0);}/* ADDCO. */static fastcall int ppc32_exec_ADDCO_dot(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   int ra = bits(insn,16,20);   int rb = bits(insn,11,15);   register m_uint32_t a,b,d;   a = cpu->gpr[ra];   b = cpu->gpr[rb];   d = a + b;   ppc32_exec_ca_sum(cpu,d,a,b);   ppc32_exec_ov_sum(cpu,d,a,b);   ppc32_exec_update_cr0(cpu,d);   cpu->gpr[rd] = d;   return(0);}/* ADDE - Add Extended */static fastcall int ppc32_exec_ADDE(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   int ra = bits(insn,16,20);   int rb = bits(insn,11,15);   register m_uint32_t a,b,d;   m_uint32_t carry;   carry = cpu->xer_ca;   cpu->xer_ca = 0;   a = cpu->gpr[ra];   b = cpu->gpr[rb];   d = a + b + carry;   if (((b + carry) < b) || (d < a))      cpu->xer_ca = 1;   cpu->gpr[rd] = d;   return(0);}/* ADDE. */static fastcall int ppc32_exec_ADDE_dot(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   int ra = bits(insn,16,20);   int rb = bits(insn,11,15);   register m_uint32_t a,b,d;   m_uint32_t carry;   carry = cpu->xer_ca;   cpu->xer_ca = 0;   a = cpu->gpr[ra];   b = cpu->gpr[rb];   d = a + b + carry;   if (((b + carry) < b) || (d < a))      cpu->xer_ca = 1;   ppc32_exec_update_cr0(cpu,d);   cpu->gpr[rd] = d;   return(0);}/* ADDEO - Add Extended with Overflow */static fastcall int ppc32_exec_ADDEO(cpu_ppc_t *cpu,ppc_insn_t insn){   int rd = bits(insn,21,25);   int ra = bits(insn,16,20);   int rb = bits(insn,11,15);   register m_uint32_t a,b,d;   m_uint32_t carry;   carry = cpu->xer_ca;   cpu->xer_ca = 0;   a = cpu->gpr[ra];   b = cpu->gpr[rb];   d = a + b + carry;

⌨️ 快捷键说明

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