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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [or1k-tdep.c] - Diff between revs 1123 and 1144

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

Rev 1123 Rev 1144
Line 172... Line 172...
 
 
/* 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 frame offsets of all registers saved in a function's
 
   prologue.  This is deduced by skip_prologue().  Offset is in bytes,
 
   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;
 
 
/* Trace data.  */
/* Trace data.  */
Line 648... Line 639...
    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));
}
}
 
 
 
/* Given a register index, return the first byte of the register within a remote
 
   protocol packet.  This applies only to serial targets, not jtag or sim. */
 
int
 
or1k_register_byte(regnum)
 
     int regnum;
 
{
 
  int byte_offset;
 
 
 
  byte_offset = 0;
 
  if (regnum < MAX_GPR_REGS) {
 
    if (regnum < NUM_GPR_REGS)
 
      return byte_offset + regnum * OR1K_GPR_REGSIZE;
 
    else
 
      return -1;
 
  }
 
 
 
  byte_offset += NUM_GPR_REGS * OR1K_GPR_REGSIZE;
 
  regnum -= MAX_GPR_REGS;
 
  if (regnum < MAX_VF_REGS) {
 
    if (regnum < NUM_VF_REGS)
 
      return byte_offset + regnum * OR1K_VF_REGSIZE;
 
    else
 
      return -1;
 
  }
 
 
 
  /* Must be PC, SR, or EPC */
 
  byte_offset += NUM_VF_REGS * OR1K_VF_REGSIZE;
 
  regnum -= MAX_VF_REGS;
 
  if (regnum < 3)
 
    return byte_offset + regnum * OR1K_SPR_REGSIZE;
 
 
 
  /* Illegal register */
 
  return -1;
 
}
 
 
 
/* Number of bytes of storage in the actual machine representation for
 
   register N.  NOTE: This indirectly defines the register size
 
   transfered by the GDB protocol.  If we have 64bit processor
 
   implementation, GPR register raw size is 8B, otherwise 4B.  */
 
int
 
or1k_register_raw_size(int regnum)
 
{
 
  int byte_offset;
 
 
 
  if (regnum < MAX_GPR_REGS) {
 
    if (regnum < NUM_GPR_REGS)
 
      return OR1K_GPR_REGSIZE;
 
    else
 
      return 0;
 
  }
 
 
 
  regnum -= MAX_GPR_REGS;
 
  if (regnum < MAX_VF_REGS) {
 
    if (regnum < NUM_VF_REGS)
 
      return OR1K_VF_REGSIZE;
 
    else
 
      return 0;
 
  }
 
 
 
  /* Must be PC, SR, or EPC */
 
  regnum -= MAX_VF_REGS;
 
  if (regnum < 3)
 
    return OR1K_SPR_REGSIZE;
 
 
 
  /* Illegal register */
 
  return 0;
 
}
 
 
 
/* Extra arch-specific data tied to frame */
 
struct frame_extra_info
 
{
 
  /* Size of stack frame, in bytes.  Produced by skip_prologue() */
 
  int frame_size;
 
 
 
  /* List of frame offsets of all registers saved in a function's
 
     prologue.  This is deduced by skip_prologue().  Offset is in bytes,
 
     relative to sp.  If value is -1, corresponding reg is not saved by
 
     the prologue code. */
 
  int saved_reg_frame_offset[NUM_REGS];
 
 
 
  /* Address of first instruction after the last prologue instruction;
 
     Note that there may be instructions from the function's body
 
     intermingled with the prologue.
 
     If value is -1, not initialized. */
 
  CORE_ADDR after_prologue;
 
};
 
 
 
/* Initialize arch-specific frame data */
 
void
 
or1k_init_extra_frame_info (int fromleaf, struct frame_info *frame)
 
{
 
  int i;
 
 
 
  frame->extra_info = (struct frame_extra_info *)
 
    frame_obstack_alloc (sizeof (struct frame_extra_info));
 
 
 
  frame->extra_info->after_prologue = -1;
 
  frame->extra_info->frame_size = -1;
 
  for (i = 0; i < NUM_REGS; i++)
 
    frame->extra_info->saved_reg_frame_offset[i] = -1;
 
}
 
 
/* For stack frame sizes less than 0x8000, the or1k version of gcc
/* For stack frame sizes less than 0x8000, the or1k version of gcc
   emits the following prologue:
   emits the following prologue:
 
 
     l.addi    r1, r1, -<STACK_FRAME_SIZE>
     l.addi    r1, r1, -<STACK_FRAME_SIZE>
     l.sw      <FP_OFFSET>(r1),r2
     l.sw      <FP_OFFSET>(r1),r2
Line 663... Line 756...
     ; ...
     ; ...
 
 
*/
*/
 
 
/* FIXME: Does not work with frames greater than 0x7fff in size */
/* FIXME: Does not work with frames greater than 0x7fff in size */
 
 
 
/* If pframeless is non-NULL, only parse enough of the prologue to
 
   determine if a function has a frame or not and return the result in
 
   *pframeless.  This may save some remote transactions with the
 
   target. */
CORE_ADDR
CORE_ADDR
or1k_skip_prologue (CORE_ADDR pc)
or1k_skip_prologue (CORE_ADDR pc, struct frame_info *fi)
{
{
  unsigned long insn;
  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, frameless;
  int offset = 0;
  int offset = 0;
  int rB, immediate, immediate_hi;
  int rB, immediate, immediate_hi;
 
  int* saved_reg_frame_offset;
 
 
  for (i = 0; i < MAX_GPR_REGS; i++)
  /* Check to see if prologue analysis is cached from prior call */
    or1k_saved_reg_frame_offset[i] = -1;
  if (fi && fi->extra_info->after_prologue != -1)
  frame_size = -1;
    return fi->extra_info->after_prologue;
 
 
 
  if (fi)
 
    saved_reg_frame_offset = &fi->extra_info->saved_reg_frame_offset[0];
 
 
  /* Is there a prologue?  */
  /* Is there a prologue?  */
  insn = or1k_fetch_instruction (pc);
  insn = or1k_fetch_instruction (pc);
  if ((insn & 0xFFFF0000) != 0x9c210000) /* l.addi r1,r1,I */
  if ((insn & 0xFFFF0000) != 0x9c210000) /* l.addi r1,r1,I */
    return pc;
    goto done;
 
 
  pc += OR1K_INSTLEN;
  pc += OR1K_INSTLEN;
 
 
  insn = or1k_fetch_instruction (pc);
  insn = or1k_fetch_instruction (pc);
  if ((insn & 0xfc1ff800) != 0xd4011000) /* l.sw I(r1),r2 */
  if ((insn & 0xfc1ff800) != 0xd4011000) /* l.sw I(r1),r2 */
    return pc;
    goto done;
  immediate_hi = (insn & 0x03E00000) >> 10;
  immediate_hi = (insn & 0x03E00000) >> 10;
  immediate    = (insn & 0x000007FF) | immediate_hi;
  immediate    = (insn & 0x000007FF) | immediate_hi;
  pc += OR1K_INSTLEN;
  pc += OR1K_INSTLEN;
  or1k_saved_reg_frame_offset[2] = immediate;
  if (fi)
 
    saved_reg_frame_offset[2] = immediate;
 
 
  insn = or1k_fetch_instruction (pc);
  insn = or1k_fetch_instruction (pc);
  if ((insn & 0xFFFF0000) != 0x9c410000) /* l.addi r2,r1,I */
  if ((insn & 0xFFFF0000) != 0x9c410000) /* l.addi r2,r1,I */
    return pc;
    goto done;
  frame_size = insn & 0xFFFF;
  if (fi)
 
    fi->extra_info->frame_size = insn & 0xFFFF;
  pc += OR1K_INSTLEN;
  pc += OR1K_INSTLEN;
 
 
  /* Skip stored registers.  */
  /* Skip stored registers.  */
  insn = or1k_fetch_instruction (pc);
  insn = or1k_fetch_instruction (pc);
  while ((insn & 0xfc1f0000) == 0xd4010000)  /* l.sw I(r1),rx */
  while ((insn & 0xfc1f0000) == 0xd4010000)  /* l.sw I(r1),rx */
Line 707... Line 812...
      rB           = (insn & 0x0000F800) >> 11;
      rB           = (insn & 0x0000F800) >> 11;
      immediate_hi = (insn & 0x03E00000) >> 10;
      immediate_hi = (insn & 0x03E00000) >> 10;
      immediate    = (insn & 0x000007FF) | immediate_hi;
      immediate    = (insn & 0x000007FF) | immediate_hi;
 
 
      /* get saved reg. */
      /* get saved reg. */
      or1k_saved_reg_frame_offset[rB] = immediate;
      if (fi)
 
        saved_reg_frame_offset[rB] = immediate;
      pc += OR1K_INSTLEN;
      pc += OR1K_INSTLEN;
      insn = or1k_fetch_instruction (pc);
      insn = or1k_fetch_instruction (pc);
    }
    }
 
 done:
 
  if (fi)
 
    fi->extra_info->after_prologue = pc;
  return pc;
  return pc;
}
}
 
 
/* Determines whether this function has frame.  */
/* Determines whether this function has frame.  */
 
 
int
int
or1k_frameless_function_invocation (struct frame_info *fi)
or1k_frameless_function_invocation (struct frame_info *fi)
{
{
  CORE_ADDR func_start, after_prologue;
 
  int frameless;
  int frameless;
 
  CORE_ADDR func_start, after_prologue;
  func_start = (get_pc_function_start ((fi)->pc) + FUNCTION_START_OFFSET);
  func_start = (get_pc_function_start ((fi)->pc) + FUNCTION_START_OFFSET);
  after_prologue = SKIP_PROLOGUE (func_start);
 
 
 
  /* If we don't skip pc, we don't have even shortest possible  prologue.  */
  /* If we don't skip pc, we don't have even shortest possible  prologue.  */
 
  after_prologue = or1k_skip_prologue (func_start, fi);
  frameless = (after_prologue <= func_start);
  frameless = (after_prologue <= func_start);
  return frameless;
  return frameless;
}
}
 
 
/* Given a GDB frame, determine the address of the calling function's frame.
/* Given a GDB frame, determine the address of the calling function's frame.
Line 826... Line 935...
  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 pc_found = 0;
  int pc_found = 0;
 
 
  frame_saved_regs_zalloc (fi);
  frame_saved_regs_zalloc (fi);
 
 
  /* Skip prologue sets frame_size and or1k_saved_reg_frame_offset[],
  /* Skip prologue sets frame_size and register frame save offsets
     which will both be used shortly. */
     which will both be used shortly. */
  or1k_skip_prologue (func_pc);
  or1k_skip_prologue (func_pc, fi);
 
 
  /* 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(fi->extra_info->frame_size < 0)
    {
    {
      printf("Found a function without a prologue at 0x%08x\n",func_pc);
      printf("Found a function without a prologue at 0x%08x\n",func_pc);
      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_frame_offset[i] >= 0)
    if (fi->extra_info->saved_reg_frame_offset[i] >= 0)
      fi->saved_regs[i] =
      fi->saved_regs[i] =
        fi->frame + (or1k_saved_reg_frame_offset[i] - frame_size);
        fi->frame + (fi->extra_info->saved_reg_frame_offset[i] - fi->extra_info->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. */
  fi->saved_regs[1] = fi->frame - frame_size;
  fi->saved_regs[1] = fi->frame - fi->extra_info->frame_size;
 
 
  if(fi->saved_regs[LR_REGNUM])
  if(fi->saved_regs[LR_REGNUM])
    fi->saved_regs[PC_REGNUM] = read_memory_integer(fi->saved_regs[LR_REGNUM],4);
    fi->saved_regs[PC_REGNUM] = read_memory_integer(fi->saved_regs[LR_REGNUM],4);
  else
  else
    fi->saved_regs[PC_REGNUM] = read_register(LR_REGNUM);
    fi->saved_regs[PC_REGNUM] = read_register(LR_REGNUM);

powered by: WebSVN 2.1.0

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