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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [or32-tdep.c] - Diff between revs 244 and 249

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

Rev 244 Rev 249
Line 1052... Line 1052...
        }
        }
 
 
      if((len > bpw) && (argreg <= (OR32_LAST_ARG_REGNUM - 1)))
      if((len > bpw) && (argreg <= (OR32_LAST_ARG_REGNUM - 1)))
        {
        {
 
 
          /* Big scalars use two registers, must be pair aligned. This code
          /* Big scalars use two registers, but need NOT be pair aligned. This
             breaks if we can have quad-word scalars (e.g. long double). */
             code breaks if we can have quad-word scalars (e.g. long
 
             double). */
          ULONGEST regval = extract_unsigned_integer (val, len, byte_order);
          ULONGEST regval = extract_unsigned_integer (val, len, byte_order);
 
 
 
          unsigned int  bits_per_word = bpw * 8;
 
          ULONGEST      mask          = (((ULONGEST) 1) << bits_per_word) - 1;
 
          ULONGEST      lo            = regval & mask;
 
          ULONGEST      hi            = regval >> bits_per_word;
 
 
          gdb_assert (len <= (bpw * 2));
          gdb_assert (len <= (bpw * 2));
 
 
          argreg = 1 == (argreg & 1) ? argreg + 1 : argreg;
          regcache_cooked_write_unsigned (regcache, argreg,     hi);
          regcache_cooked_write_unsigned (regcache, argreg, regval >> bpw);
          regcache_cooked_write_unsigned (regcache, argreg + 1, lo);
          regcache_cooked_write_unsigned (regcache, argreg + 1,
 
                                          regval && ((ULONGEST)(1 << bpw) - 1));
 
          argreg += 2;
          argreg += 2;
        }
        }
      else if (argreg <= OR32_LAST_ARG_REGNUM)
      else if (argreg <= OR32_LAST_ARG_REGNUM)
        {
        {
 
          printf ("Writing 0x%08llx to r%d\n",
 
                  extract_unsigned_integer (val, len, byte_order), argreg);
 
 
          regcache_cooked_write_unsigned (regcache, argreg,
          regcache_cooked_write_unsigned (regcache, argreg,
                                          extract_unsigned_integer (val, len,
                                          extract_unsigned_integer (val, len,
                                                                   byte_order));
                                                                   byte_order));
          argreg++;
          argreg++;
        }
        }
Line 1184... Line 1191...
 
 
   This function is changed from its GDB 6.8 version (named
   This function is changed from its GDB 6.8 version (named
   or32_frame_unwind_cache), in that it is based on THIS frame, not the NEXT
   or32_frame_unwind_cache), in that it is based on THIS frame, not the NEXT
   frame.
   frame.
 
 
   Build up the information (saved registers etc) for the given frame if it
   We build a cache, saying where registers of the PREV frame can be found
   does not already exist.
   from the data so far set up in this THIS.
 
 
 
   We also compute a unique ID for this frame, based on the function start
 
   address and the stack pointer (as it will be, even if it has yet to be
 
   computed.
 
 
   STACK FORMAT
   STACK FORMAT
   ============
   ============
 
 
   The OR32 has a falling stack frame and a simple prolog. The Stack pointer
   The OR32 has a falling stack frame and a simple prolog. The Stack pointer
Line 1237... Line 1248...
   ========
   ========
 
 
   This prolog is used, even for -O3 with GCC.
   This prolog is used, even for -O3 with GCC.
 
 
   All this analysis must allow for the possibility that the PC is in the
   All this analysis must allow for the possibility that the PC is in the
   middle of the prologue. Data should only be set up insofar as it has been
   middle of the prologue. Data in the cache should only be set up insofar as
   computed.
   it has been computed.
 
 
 
   HOWEVER. The frame_id must be created with the SP *as it will be* at the
 
   end of the Prologue. Otherwise a recursive call, checking the frame with
 
   the PC at the start address will end up with the same frame_id as the
 
   caller.
 
 
   A suite of "helper" routines are used, allowing reuse for
   A suite of "helper" routines are used, allowing reuse for
   or32_skip_prologue().
   or32_skip_prologue().
 
 
   Reportedly, this is only valid for frames less than 0x7fff in size.
   Reportedly, this is only valid for frames less than 0x7fff in size.
Line 1260... Line 1276...
  struct gdbarch          *gdbarch;
  struct gdbarch          *gdbarch;
  struct trad_frame_cache *info;
  struct trad_frame_cache *info;
 
 
  CORE_ADDR                this_pc;
  CORE_ADDR                this_pc;
  CORE_ADDR                this_sp;
  CORE_ADDR                this_sp;
 
  CORE_ADDR                this_sp_for_id;
  int                      frame_size = 0;
  int                      frame_size = 0;
 
 
  CORE_ADDR                start_addr;
  CORE_ADDR                start_addr;
  CORE_ADDR                end_addr;
  CORE_ADDR                end_addr;
 
 
Line 1292... Line 1309...
     we won't have a frame. */
     we won't have a frame. */
  this_sp = (NULL == this_frame) ? 0 :
  this_sp = (NULL == this_frame) ? 0 :
                                   get_frame_register_unsigned (this_frame,
                                   get_frame_register_unsigned (this_frame,
                                                                OR32_SP_REGNUM);
                                                                OR32_SP_REGNUM);
 
 
  /* The frame base of THIS frame (for ID purposes only - frame base is an
  /* The default frame base of THIS frame (for ID purposes only - frame base
     overloaded term) is its stack pointer. This is the same whether we are
     is an overloaded term) is its stack pointer. For now we use the value of
     frameless or not. */
     the SP register in THIS frame. However if the PC is in the prologue of
 
     THIS frame, before the SP has been set up, then the value will actually
 
     be that of the PREV frame, and we'll need to adjust it later. */
  trad_frame_set_this_base (info, this_sp);
  trad_frame_set_this_base (info, this_sp);
 
  this_sp_for_id = this_sp;
 
 
  /* The default is to find the PC of the PREVIOUS frame in the link register
  /* The default is to find the PC of the PREVIOUS frame in the link register
     of this frame. This may be changed if we find the link register was saved
     of this frame. This may be changed if we find the link register was saved
     on the stack. */
     on the stack. */
  trad_frame_set_reg_realreg (info, OR32_NPC_REGNUM, OR32_LR_REGNUM);
  trad_frame_set_reg_realreg (info, OR32_NPC_REGNUM, OR32_LR_REGNUM);
 
 
  /* We should only examine code that is in the prologue and which has been
  /* We should only examine code that is in the prologue. This is all code up
     executed. This is all code up to (but not including) end_addr or the PC,
     to (but not including) end_addr. We should only populate the cache while
     whichever is first. */
     the address is up to (but not including) the PC or end_addr, whichever is
 
     first. */
  gdbarch = get_frame_arch (this_frame);
  gdbarch = get_frame_arch (this_frame);
  end_addr = or32_skip_prologue (gdbarch, start_addr);
  end_addr = or32_skip_prologue (gdbarch, start_addr);
  end_addr = (this_pc > end_addr) ? end_addr : this_pc;
 
 
 
  /* All the following analysis only occurs if we are in the prologue and have
  /* All the following analysis only occurs if we are in the prologue and have
     executed the code. Check we have a sane prologue size, and if zero we
     executed the code. Check we have a sane prologue size, and if zero we
     are frameless and can give up here. */
     are frameless and can give up here. */
  if (end_addr < start_addr)
  if (end_addr < start_addr)
Line 1340... Line 1360...
        {
        {
          frame_size  = -simm;
          frame_size  = -simm;
          addr       += OR32_INSTLEN;
          addr       += OR32_INSTLEN;
          inst        = or32_fetch_instruction (gdbarch, addr);
          inst        = or32_fetch_instruction (gdbarch, addr);
 
 
          /* The stack pointer of the PREVIOUS frame is frame_size greater
          /* If the PC has not actually got to this point, then the frame base
             than the stack pointer of THIS frame. */
             will be wrong, and we adjust it.
 
 
 
             If we are past this point, then we need to populate the stack
 
             accoringly. */
 
          if (this_pc <= addr)
 
            {
 
              /* Only do if executing */
 
              if (0 != this_sp)
 
                {
 
                  this_sp_for_id = this_sp + frame_size;
 
                  trad_frame_set_this_base (info, this_sp_for_id);
 
                }
 
            }
 
          else
 
            {
 
              /* We are past this point, so the stack pointer of the PREV
 
                 frame is frame_size greater than the stack pointer of THIS
 
                 frame. */
          trad_frame_set_reg_value (info, OR32_SP_REGNUM,
          trad_frame_set_reg_value (info, OR32_SP_REGNUM,
                                    this_sp + frame_size);
                                    this_sp + frame_size);
        }
        }
 
        }
 
 
 
      /* From now on we are only populating the cache, so we stop once we get
 
         to either the end OR the current PC. */
 
      end_addr = (this_pc < end_addr) ? this_pc : end_addr;
 
 
      /* Look for the frame pointer being manipulated. */
      /* Look for the frame pointer being manipulated. */
      if ((addr < end_addr) &&
      if ((addr < end_addr) &&
          or32_analyse_l_sw (inst, &simm, &ra, &rb) &&
          or32_analyse_l_sw (inst, &simm, &ra, &rb) &&
          (OR32_SP_REGNUM == ra) && (OR32_FP_REGNUM == rb) &&
          (OR32_SP_REGNUM == ra) && (OR32_FP_REGNUM == rb) &&
Line 1418... Line 1460...
            }
            }
        }
        }
    }
    }
 
 
  /* Build the frame ID */
  /* Build the frame ID */
  trad_frame_set_id (info, frame_id_build (this_sp, start_addr));
  trad_frame_set_id (info, frame_id_build (this_sp_for_id, start_addr));
 
 
  return info;
  return info;
 
 
}       /* or32_frame_cache() */
}       /* or32_frame_cache() */
 
 

powered by: WebSVN 2.1.0

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