OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [or1k-tdep.c] - Diff between revs 874 and 1115

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 874 Rev 1115
Line 178... Line 178...
 
 
/* The list of available "set or1k " and "show or1k " commands */
/* The list of available "set or1k " and "show or1k " commands */
static struct cmd_list_element *htrace_cmdlist = NULL;
static struct cmd_list_element *htrace_cmdlist = NULL;
static struct cmd_list_element *htrace_mode_cmdlist = NULL;
static struct cmd_list_element *htrace_mode_cmdlist = NULL;
 
 
/* List of all saved register addresses, produced by skip_prologue.
/* List of frame offsets of all registers saved in a function's
   Relative address to sp, not used if 0.  */
   prologue.  This is deduced by skip_prologue().  Offset is in bytes,
static int or1k_saved_reg_addr[NUM_REGS];
   relative to sp.  If value is -1, corresponding reg is not saved by
 
   the prologue code. */
 
static int or1k_saved_reg_frame_offset[NUM_REGS];
 
 
 
/* Size of stack frame, in bytes.  Produced by skip_prologue() */
 
static int frame_size;
 
 
struct htrace_struct or1k_htrace;
struct htrace_struct or1k_htrace;
struct hwatch_struct or1k_hwatch[MAX_HW_WATCHES];
struct hwatch_struct or1k_hwatch[MAX_HW_WATCHES];
int num_hw_watches = 0;
int num_hw_watches = 0;
 
 
Line 650... Line 655...
    memcpy (valbuf, &regbuf[REGISTER_BYTE (VFRV_REGNUM)], TYPE_LENGTH (valtype));
    memcpy (valbuf, &regbuf[REGISTER_BYTE (VFRV_REGNUM)], TYPE_LENGTH (valtype));
  else
  else
    memcpy (valbuf, &regbuf[REGISTER_BYTE (RV_REGNUM)], TYPE_LENGTH (valtype));
    memcpy (valbuf, &regbuf[REGISTER_BYTE (RV_REGNUM)], TYPE_LENGTH (valtype));
}
}
 
 
/* The or1k cc defines the following
/* For stack frame sizes less than 0x8000, the or1k version of gcc
   prologue:
   emits the following prologue:
00000000 <_proc1>:
 
   0:   d7 e1 17 e4     l.sw 0xffffffe4(r1),r2
     l.addi    r1, r1, -<STACK_FRAME_SIZE>
   4:   9c 41 00 00     l.addi r2,r1,0x0
     l.sw      <FP_OFFSET>(r1),r2
   8:   9c 21 ff e8     l.addi r1,r1,0xffffffe8
     l.addi    r2, r1, <STACK_FRAME_SIZE>
   c:   d7 e2 1f f8     l.sw 0xfffffff8(r2),r3
 
  10:   d7 e2 27 f4     l.sw 0xfffffff4(r2),r4
     ; Save regs that will be clobbered
  14:   84 82 ff f8     l.lwz r4,0xfffffff8(r2)
     l.sw      <OFFSET_Rx>(r1),rx
  18:   9d 24 00 00     l.addi r9,r4,0x0
     l.sw      <OFFSET_Ry>(r1),ry
  1c:   00 00 00 02     l.j 0x2
     ; ...
  20:   15 00 00 00     l.nop
 
 
 
00000024 <_L2>:
 
  24:   84 41 ff fc     l.lwz r2,0xfffffffc(r1)
 
  28:   48 00 58 00     l.jalr r11
 
  2c:   9c 21 00 18     l.addi r1,r1,0x18 */
 
 
 
 
*/
 
 
 
/* FIXME: Does not work with frames greater than 0x7fff in size */
CORE_ADDR
CORE_ADDR
or1k_skip_prologue (CORE_ADDR pc)
or1k_skip_prologue (CORE_ADDR pc)
{
{
  unsigned long inst;
  unsigned long insn;
  CORE_ADDR skip_pc;
  CORE_ADDR skip_pc;
  CORE_ADDR func_addr, func_end;
  CORE_ADDR func_addr, func_end;
  struct symtab_and_line sal;
  struct symtab_and_line sal;
  int i;
  int i;
  int offset = 0;
  int offset = 0;
 
  int rB, immediate, immediate_hi;
 
 
  for (i = 0; i < MAX_GPR_REGS; i++)
  for (i = 0; i < MAX_GPR_REGS; i++)
    or1k_saved_reg_addr[i] = -1;
    or1k_saved_reg_frame_offset[i] = -1;
 
  frame_size = -1;
 
 
  /* Is there a prologue?  */
  /* Is there a prologue?  */
  inst = or1k_fetch_instruction (pc);
  insn = or1k_fetch_instruction (pc);
  if ((inst & 0xfc1ff800) != 0xd4011000) return pc; /* l.sw I(r1),r2 */
  if ((insn & 0xFFFF0000) != 0x9c210000) /* l.addi r1,r1,I */
  or1k_saved_reg_addr[2] = offset++;
    return pc;
  inst = or1k_fetch_instruction (pc + OR1K_INSTLEN);
  pc += OR1K_INSTLEN;
  if ((inst & 0xFFFF0000) != 0x9c410000) return pc; /* l.addi r2,r1,I */
 
  pc += 2 * OR1K_INSTLEN;
  insn = or1k_fetch_instruction (pc);
  inst = or1k_fetch_instruction (pc);
  if ((insn & 0xfc1ff800) != 0xd4011000) /* l.sw I(r1),r2 */
  if ((inst & 0xFFFF0000) != 0x9c210000) return pc; /* l.addi r1,r1,I */
    return pc;
 
  immediate_hi = (insn & 0x03E00000) >> 10;
 
  immediate    = (insn & 0x000007FF) | immediate_hi;
 
  pc += OR1K_INSTLEN;
 
  or1k_saved_reg_frame_offset[2] = immediate;
 
 
 
  insn = or1k_fetch_instruction (pc);
 
  if ((insn & 0xFFFF0000) != 0x9c410000) /* l.addi r2,r1,I */
 
    return pc;
 
  frame_size = insn & 0xFFFF;
  pc += OR1K_INSTLEN;
  pc += OR1K_INSTLEN;
 
 
  /* Skip stored registers.  */
  /* Skip stored registers.  */
  inst = or1k_fetch_instruction (pc);
  insn = or1k_fetch_instruction (pc);
  while ((inst & 0xfc1ff800) != 0xd4020000)  /* l.sw 0x0(r2),rx */
  while ((insn & 0xfc1f0000) == 0xd4010000)  /* l.sw I(r1),rx */
    {
    {
 
      rB           = (insn & 0x0000F800) >> 11;
 
      immediate_hi = (insn & 0x03E00000) >> 10;
 
      immediate    = (insn & 0x000007FF) | immediate_hi;
 
 
      /* get saved reg. */
      /* get saved reg. */
      or1k_saved_reg_addr[(inst >> 11) & 0x1f] = offset++;
      or1k_saved_reg_frame_offset[rB] = immediate;
      pc += OR1K_INSTLEN;
      pc += OR1K_INSTLEN;
      inst = or1k_fetch_instruction (pc);
      insn = or1k_fetch_instruction (pc);
    }
    }
  return pc;
  return pc;
}
}
 
 
/* Determines whether this function has frame.  */
/* Determines whether this function has frame.  */
Line 727... Line 744...
 
 
CORE_ADDR
CORE_ADDR
or1k_frame_chain (frame)
or1k_frame_chain (frame)
     struct frame_info *frame;
     struct frame_info *frame;
{
{
  CORE_ADDR fp;
  CORE_ADDR fp = 0;
  if (USE_GENERIC_DUMMY_FRAMES)
  if (USE_GENERIC_DUMMY_FRAMES)
    {
    {
      if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
      if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
        /* dummy frame same as caller's frame */
        /* dummy frame same as caller's frame */
        return frame->frame;
        return frame->frame;
Line 754... Line 771...
      unsigned long func_pc = get_pc_function_start(frame->pc);
      unsigned long func_pc = get_pc_function_start(frame->pc);
      unsigned long insn = read_memory_integer(func_pc,4);
      unsigned long insn = read_memory_integer(func_pc,4);
      int i;
      int i;
      int offset = 0;
      int offset = 0;
 
 
      /* The first instruction should be the number of bytes
      /* The first instruction should tell us the number of bytes
         in our frame. If it isn't we're in trouble because
         in our frame. If it isn't we're in trouble because
         the function is without a prologue... */
         the function is without a prologue... */
      if(((insn & 0xFC000000) == 0x9C000000) &&
      if ((insn & 0xFFFF0000) == 0x9c210000) /* l.addi r1,r1,I */
         ((insn & 0x03E00000) == 0x00200000) &&
 
         ((insn & 0x001F0000) == 0x00010000))
 
        {
        {
          short off = insn & 0xFFFF;
          /* Sign extend immediate */
 
          int immediate = (long)(insn << 16) >> 16;
 
          int frame_size = -immediate;
 
 
          /* Look for the storage of the frame pointer in the
          /* Look for the storage of the frame pointer in the
             function prologue.. */
             function prologue.. */
          for(i=1;i<20;i++)
          unsigned long insn = read_memory_integer(func_pc+4,4);
            {
 
              unsigned long insn = read_memory_integer(func_pc+4*i,4);
 
 
 
              /* If bits are 31 - 26 are %110101,
              /* If bits are 31 - 26 are %110101,
                 and bits 20 - 16 are %00001,
                 and bits 20 - 16 are %00001,
                 and bits 15 - 11 are %00010,
                 and bits 15 - 11 are %00010,
                 then our frame pointer lies at the offset specified
                 then our frame pointer lies at the offset specified
Line 783... Line 798...
              int idx_h = (insn & 0x03E00000) >> 10;
              int idx_h = (insn & 0x03E00000) >> 10;
              int idx   = (insn & 0x000007FF) | idx_h;
              int idx   = (insn & 0x000007FF) | idx_h;
 
 
              if(code == 0x35 && r1 == 1 && r2 == 2)
              if(code == 0x35 && r1 == 1 && r2 == 2)
                {
                {
                  offset = off + idx;
              offset = idx - frame_size;
                  break;
              fp = read_memory_integer (frame->frame + offset, 4);
                }
 
            }
            }
        }
        }
 
 
      fp = read_memory_integer (frame->frame + offset, 4);
 
    }
    }
 
 
  if (USE_GENERIC_DUMMY_FRAMES)
  if (USE_GENERIC_DUMMY_FRAMES)
    {
    {
      CORE_ADDR fpp, lr;
      CORE_ADDR fpp, lr;
Line 817... Line 829...
or1k_init_saved_regs (struct frame_info *fi)
or1k_init_saved_regs (struct frame_info *fi)
{
{
  int i;
  int i;
  CORE_ADDR frame_addr;
  CORE_ADDR frame_addr;
  CORE_ADDR func_pc = get_pc_function_start ((fi)->pc) + FUNCTION_START_OFFSET;
  CORE_ADDR func_pc = get_pc_function_start ((fi)->pc) + FUNCTION_START_OFFSET;
  int frame_size;
 
  int pc_found = 0;
  int pc_found = 0;
 
 
  frame_saved_regs_zalloc (fi);
  frame_saved_regs_zalloc (fi);
 
 
  /* Skip prologue sets or1k_saved_reg_addr[], we will use it later.  */
  /* Skip prologue sets frame_size and or1k_saved_reg_frame_offset[],
 
     which will both be used shortly. */
  or1k_skip_prologue (func_pc);
  or1k_skip_prologue (func_pc);
 
 
  frame_size = or1k_saved_reg_addr[1];
 
  or1k_saved_reg_addr[1] = -1;
 
 
 
  /* If the frame_size is less than 0, we have hit an assembly
  /* If the frame_size is less than 0, we have hit an assembly
     routine which we can't traverse beyond. Let's give up here,
     routine which we can't traverse beyond. Let's give up here,
     because attempting to continue will only lead to trouble. */
     because attempting to continue will only lead to trouble. */
  if(frame_size < 0)
  if(frame_size < 0)
    {
    {
Line 839... Line 848...
      printf("Frame pc was at 0x%08x\n",fi->pc);
      printf("Frame pc was at 0x%08x\n",fi->pc);
      return;
      return;
    }
    }
 
 
  for (i = 0; i < NUM_GPR_REGS + NUM_VF_REGS; i++)
  for (i = 0; i < NUM_GPR_REGS + NUM_VF_REGS; i++)
    if (or1k_saved_reg_addr[i] >= 0)
    if (or1k_saved_reg_frame_offset[i] >= 0)
      fi->saved_regs[i] = fi->frame - or1k_saved_reg_addr[i];
      fi->saved_regs[i] =
 
        fi->frame + (or1k_saved_reg_frame_offset[i] - frame_size);
 
 
  /* We want to make sure we fill in the PC with the value of the
  /* We want to make sure we fill in the PC with the value of the
     r9 register from the NEXT frame, and that the value of r1 is
     r9 register from the NEXT frame, and that the value of r1 is
     the correct value of r1 for the next frame, which can be
     the correct value of r1 for the next frame, which can be
     calculated by adding the frame_size to the frame pointer. */
     calculated by adding the frame_size to the frame pointer. */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.