Example #1
0
void
generic_pop_current_frame (void (*popper) (struct frame_info * frame))
{
  struct frame_info *frame = get_current_frame ();

  if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
    generic_pop_dummy_frame ();
  else
    (*popper) (frame);
}
Example #2
0
void
microblaze_pop_frame (struct frame_info *fi)
{
  int rn;
  CORE_ADDR func_addr, func_end, addr;
  enum microblaze_instr op;
  int insn, rd, ra, rb, imm;
  int status;
  char *name;
  int offset = 0;	/* offset that the return instruction specifies */

  /* Find the start and end of this function. */
  /* siva/9/19/05: pop frame was not computing this offset. copied code from
     microblaze_fix_call_dummy to find the return insn & the offset */
  status = find_pc_partial_function (fi->pc, &name, &func_addr, &func_end);

  for (addr = func_addr; addr < func_end; addr += INST_WORD_SIZE) {
	  /* Start decoding the function looking for rtsd */
	  insn = get_insn (addr);
	  op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);

	  /* Check for return. */
	  if (IS_RETURN(op)) {
		  offset = imm;
		  break; 
	  }
  }

  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
    generic_pop_dummy_frame ();
  else
    {
      /* Write out the PC we saved. */
      write_register (PC_REGNUM, FRAME_SAVED_PC (fi) + offset);

      /* Restore any saved registers. */
      for (rn = 0; rn < NUM_REGS; rn++)
	{
	  if (fi->saved_regs[rn] != 0)
	    {
	      ULONGEST value;

	      value = read_memory_unsigned_integer (fi->saved_regs[rn],
						    REGISTER_SIZE);
	      write_register (rn, value);
	    }
	}

      /* Actually cut back the stack. */
      write_register (SP_REGNUM, FRAME_FP (fi));
    }

  /* Finally, throw away any cached frame information. */
  flush_cached_frames ();
}