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

📄 interp.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <signal.h>#include "sysdep.h"#include "bfd.h"#include "gdb/callback.h"#include "gdb/remote-sim.h"#include "d10v_sim.h"#include "gdb/sim-d10v.h"enum _leftright { LEFT_FIRST, RIGHT_FIRST };static char *myname;static SIM_OPEN_KIND sim_kind;int d10v_debug;/* Set this to true to get the previous segment layout. */int old_segment_mapping;host_callback *d10v_callback;unsigned long ins_type_counters[ (int)INS_MAX ];uint16 OP[4];static int init_text_p = 0;/* non-zero if we opened prog_bfd */static int prog_bfd_was_opened_p;bfd *prog_bfd;asection *text;bfd_vma text_start;bfd_vma text_end;static long hash PARAMS ((long insn, int format));static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));static void get_operands PARAMS ((struct simops *s, uint32 ins));static void do_long PARAMS ((uint32 ins));static void do_2_short PARAMS ((uint16 ins1, uint16 ins2, enum _leftright leftright));static void do_parallel PARAMS ((uint16 ins1, uint16 ins2));static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value));extern void sim_set_profile PARAMS ((int n));extern void sim_set_profile_size PARAMS ((int n));static INLINE uint8 *map_memory (unsigned phys_addr);#ifdef NEED_UI_LOOP_HOOK/* How often to run the ui_loop update, when in use */#define UI_LOOP_POLL_INTERVAL 0x14000/* Counter for the ui_loop_hook update */static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;/* Actual hook to call to run through gdb's gui event loop */extern int (*deprecated_ui_loop_hook) PARAMS ((int signo));#endif /* NEED_UI_LOOP_HOOK */#ifndef INLINE#if defined(__GNUC__) && defined(__OPTIMIZE__)#define INLINE __inline__#else#define INLINE#endif#endif#define MAX_HASH  63struct hash_entry{  struct hash_entry *next;  uint32 opcode;  uint32 mask;  int size;  struct simops *ops;};struct hash_entry hash_table[MAX_HASH+1];INLINE static long hash(insn, format)     long insn;     int format;{  if (format & LONG_OPCODE)    return ((insn & 0x3F000000) >> 24);  else    return((insn & 0x7E00) >> 9);}INLINE static struct hash_entry *lookup_hash (ins, size)     uint32 ins;     int size;{  struct hash_entry *h;  if (size)    h = &hash_table[(ins & 0x3F000000) >> 24];  else    h = &hash_table[(ins & 0x7E00) >> 9];  while ((ins & h->mask) != h->opcode || h->size != size)    {      if (h->next == NULL)	{	  State.exception = SIGILL;	  State.pc_changed = 1; /* Don't increment the PC. */	  return NULL;	}      h = h->next;    }  return (h);}INLINE static voidget_operands (struct simops *s, uint32 ins){  int i, shift, bits, flags;  uint32 mask;  for (i=0; i < s->numops; i++)    {      shift = s->operands[3*i];      bits = s->operands[3*i+1];      flags = s->operands[3*i+2];      mask = 0x7FFFFFFF >> (31 - bits);      OP[i] = (ins >> shift) & mask;    }  /* FIXME: for tracing, update values that need to be updated each     instruction decode cycle */  State.trace.psw = PSW;}bfd_vmadecode_pc (){  asection *s;  if (!init_text_p && prog_bfd != NULL)    {      init_text_p = 1;      for (s = prog_bfd->sections; s; s = s->next)	if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)	  {	    text = s;	    text_start = bfd_get_section_vma (prog_bfd, s);	    text_end = text_start + bfd_section_size (prog_bfd, s);	    break;	  }    }  return (PC << 2) + text_start;}static voiddo_long (ins)     uint32 ins;{  struct hash_entry *h;#ifdef DEBUG  if ((d10v_debug & DEBUG_INSTRUCTION) != 0)    (*d10v_callback->printf_filtered) (d10v_callback, "do_long 0x%x\n", ins);#endif  h = lookup_hash (ins, 1);  if (h == NULL)    return;  get_operands (h->ops, ins);  State.ins_type = INS_LONG;  ins_type_counters[ (int)State.ins_type ]++;  (h->ops->func)();}static voiddo_2_short (ins1, ins2, leftright)     uint16 ins1, ins2;     enum _leftright leftright;{  struct hash_entry *h;  enum _ins_type first, second;#ifdef DEBUG  if ((d10v_debug & DEBUG_INSTRUCTION) != 0)    (*d10v_callback->printf_filtered) (d10v_callback, "do_2_short 0x%x (%s) -> 0x%x\n",				       ins1, (leftright) ? "left" : "right", ins2);#endif  if (leftright == LEFT_FIRST)    {      first = INS_LEFT;      second = INS_RIGHT;      ins_type_counters[ (int)INS_LEFTRIGHT ]++;    }  else    {      first = INS_RIGHT;      second = INS_LEFT;      ins_type_counters[ (int)INS_RIGHTLEFT ]++;    }  /* Issue the first instruction */  h = lookup_hash (ins1, 0);  if (h == NULL)    return;  get_operands (h->ops, ins1);  State.ins_type = first;  ins_type_counters[ (int)State.ins_type ]++;  (h->ops->func)();  /* Issue the second instruction (if the PC hasn't changed) */  if (!State.pc_changed && !State.exception)    {      /* finish any existing instructions */      SLOT_FLUSH ();      h = lookup_hash (ins2, 0);      if (h == NULL)	return;      get_operands (h->ops, ins2);      State.ins_type = second;      ins_type_counters[ (int)State.ins_type ]++;      ins_type_counters[ (int)INS_CYCLES ]++;      (h->ops->func)();    }  else if (!State.exception)    ins_type_counters[ (int)INS_COND_JUMP ]++;}static voiddo_parallel (ins1, ins2)     uint16 ins1, ins2;{  struct hash_entry *h1, *h2;#ifdef DEBUG  if ((d10v_debug & DEBUG_INSTRUCTION) != 0)    (*d10v_callback->printf_filtered) (d10v_callback, "do_parallel 0x%x || 0x%x\n", ins1, ins2);#endif  ins_type_counters[ (int)INS_PARALLEL ]++;  h1 = lookup_hash (ins1, 0);  if (h1 == NULL)    return;  h2 = lookup_hash (ins2, 0);  if (h2 == NULL)    return;  if (h1->ops->exec_type == PARONLY)    {      get_operands (h1->ops, ins1);      State.ins_type = INS_LEFT_COND_TEST;      ins_type_counters[ (int)State.ins_type ]++;      (h1->ops->func)();      if (State.exe)	{	  ins_type_counters[ (int)INS_COND_TRUE ]++;	  get_operands (h2->ops, ins2);	  State.ins_type = INS_RIGHT_COND_EXE;	  ins_type_counters[ (int)State.ins_type ]++;	  (h2->ops->func)();	}      else	ins_type_counters[ (int)INS_COND_FALSE ]++;    }  else if (h2->ops->exec_type == PARONLY)    {      get_operands (h2->ops, ins2);      State.ins_type = INS_RIGHT_COND_TEST;      ins_type_counters[ (int)State.ins_type ]++;      (h2->ops->func)();      if (State.exe)	{	  ins_type_counters[ (int)INS_COND_TRUE ]++;	  get_operands (h1->ops, ins1);	  State.ins_type = INS_LEFT_COND_EXE;	  ins_type_counters[ (int)State.ins_type ]++;	  (h1->ops->func)();	}      else	ins_type_counters[ (int)INS_COND_FALSE ]++;    }  else    {      get_operands (h1->ops, ins1);      State.ins_type = INS_LEFT_PARALLEL;      ins_type_counters[ (int)State.ins_type ]++;      (h1->ops->func)();      if (!State.exception)	{	  get_operands (h2->ops, ins2);	  State.ins_type = INS_RIGHT_PARALLEL;	  ins_type_counters[ (int)State.ins_type ]++;	  (h2->ops->func)();	}    }} static char *add_commas(buf, sizeof_buf, value)     char *buf;     int sizeof_buf;     unsigned long value;{  int comma = 3;  char *endbuf = buf + sizeof_buf - 1;  *--endbuf = '\0';  do {    if (comma-- == 0)      {	*--endbuf = ',';	comma = 2;      }    *--endbuf = (value % 10) + '0';  } while ((value /= 10) != 0);  return endbuf;}voidsim_size (power)     int power;{  int i;  for (i = 0; i < IMEM_SEGMENTS; i++)    {      if (State.mem.insn[i])	free (State.mem.insn[i]);    }  for (i = 0; i < DMEM_SEGMENTS; i++)    {      if (State.mem.data[i])	free (State.mem.data[i]);    }  for (i = 0; i < UMEM_SEGMENTS; i++)    {      if (State.mem.unif[i])	free (State.mem.unif[i]);    }  /* Always allocate dmem segment 0.  This contains the IMAP and DMAP     registers. */  State.mem.data[0] = calloc (1, SEGMENT_SIZE);}/* For tracing - leave info on last access around. */static char *last_segname = "invalid";static char *last_from = "invalid";static char *last_to = "invalid";enum  {    IMAP0_OFFSET = 0xff00,    DMAP0_OFFSET = 0xff08,    DMAP2_SHADDOW = 0xff04,    DMAP2_OFFSET = 0xff0c  };static voidset_dmap_register (int reg_nr, unsigned long value){  uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA			   + DMAP0_OFFSET + 2 * reg_nr);  WRITE_16 (raw, value);#ifdef DEBUG  if ((d10v_debug & DEBUG_MEMORY))    {      (*d10v_callback->printf_filtered)	(d10v_callback, "mem: dmap%d=0x%04lx\n", reg_nr, value);    }#endif}static unsigned longdmap_register (void *regcache, int reg_nr){  uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA			   + DMAP0_OFFSET + 2 * reg_nr);  return READ_16 (raw);}static voidset_imap_register (int reg_nr, unsigned long value){  uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA			   + IMAP0_OFFSET + 2 * reg_nr);  WRITE_16 (raw, value);#ifdef DEBUG  if ((d10v_debug & DEBUG_MEMORY))    {      (*d10v_callback->printf_filtered)	(d10v_callback, "mem: imap%d=0x%04lx\n", reg_nr, value);    }#endif}static unsigned longimap_register (void *regcache, int reg_nr){  uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA			   + IMAP0_OFFSET + 2 * reg_nr);  return READ_16 (raw);}enum  {    HELD_SPI_IDX = 0,    HELD_SPU_IDX = 1  };static unsigned longspu_register (void){  if (PSW_SM)    return GPR (SP_IDX);  else    return HELD_SP (HELD_SPU_IDX);}static unsigned longspi_register (void){  if (!PSW_SM)    return GPR (SP_IDX);  else    return HELD_SP (HELD_SPI_IDX);}static voidset_spi_register (unsigned long value){  if (!PSW_SM)    SET_GPR (SP_IDX, value);  SET_HELD_SP (HELD_SPI_IDX, value);}static voidset_spu_register  (unsigned long value){  if (PSW_SM)    SET_GPR (SP_IDX, value);  SET_HELD_SP (HELD_SPU_IDX, value);}/* Given a virtual address in the DMAP address space, translate it   into a physical address. */unsigned longsim_d10v_translate_dmap_addr (unsigned long offset,			      int nr_bytes,			      unsigned long *phys,			      void *regcache,			      unsigned long (*dmap_register) (void *regcache,							      int reg_nr)){  short map;  int regno;  last_from = "logical-data";  if (offset >= DMAP_BLOCK_SIZE * SIM_D10V_NR_DMAP_REGS)    {      /* Logical address out side of data segments, not supported */      return 0;    }  regno = (offset / DMAP_BLOCK_SIZE);  offset = (offset % DMAP_BLOCK_SIZE);  if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE)    {      /* Don't cross a BLOCK boundary */      nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);    }  map = dmap_register (regcache, regno);  if (regno == 3)    {      /* Always maps to data memory */      int iospi = (offset / 0x1000) % 4;      int iosp = (map >> (4 * (3 - iospi))) % 0x10;      last_to = "io-space";      *phys = (SIM_D10V_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset);    }  else    {      int sp = ((map & 0x3000) >> 12);      int segno = (map & 0x3ff);      switch (sp)	{	case 0: /* 00: Unified memory */	  *phys = SIM_D10V_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset;	  last_to = "unified";	  break;	case 1: /* 01: Instruction Memory */	  *phys = SIM_D10V_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset;	  last_to = "chip-insn";	  break;	case 2: /* 10: Internal data memory */	  *phys = SIM_D10V_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset;	  last_to = "chip-data";	  break;	case 3: /* 11: Reserved */	  return 0;	}    }  return nr_bytes;}/* Given a virtual address in the IMAP address space, translate it   into a physical address. */unsigned longsim_d10v_translate_imap_addr (unsigned long offset,			      int nr_bytes,

⌨️ 快捷键说明

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