-/* Function: xstormy16_frame_init_saved_regs
- Set up the 'saved_regs' array.
- This is a data structure containing the addresses on the stack
- where each register has been saved, for each stack frame.
- Registers that have not been saved will have zero here.
- The stack register is special: rather than the address where the
- stack register has been saved, saved_regs[SP_REGNUM] will have the
- actual value of the previous frame's stack register.
-
- This function may be called in any context where the saved register
- values may be needed (backtrace, frame_info, frame_register). On
- many targets, it is called directly by init_extra_frame_info, in
- part because the information may be needed immediately by
- frame_chain. */
-
-static void
-xstormy16_frame_init_saved_regs (struct frame_info *fi)
-{
- CORE_ADDR func_addr, func_end;
-
- if (!get_frame_saved_regs (fi))
- {
- frame_saved_regs_zalloc (fi);
-
- /* Find the beginning of this function, so we can analyze its
- prologue. */
- if (find_pc_partial_function (get_frame_pc (fi), NULL, &func_addr, &func_end))
- xstormy16_scan_prologue (func_addr, get_frame_pc (fi), fi, NULL);
- /* Else we're out of luck (can't debug completely stripped code).
- FIXME. */
- }
-}
-
-/* Function: xstormy16_frame_saved_pc
- Returns the return address for the selected frame.
- Called by frame_info, legacy_frame_chain_valid, and sometimes by
- get_prev_frame. */
-
-static CORE_ADDR
-xstormy16_frame_saved_pc (struct frame_info *fi)
-{
- CORE_ADDR saved_pc;
-
- if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
- get_frame_base (fi)))
- {
- saved_pc = deprecated_read_register_dummy (get_frame_pc (fi),
- get_frame_base (fi),
- E_PC_REGNUM);
- }
- else
- {
- saved_pc = read_memory_unsigned_integer (get_frame_saved_regs (fi)[E_PC_REGNUM],
- xstormy16_pc_size);
- }
-
- return saved_pc;
-}
-
-/* Function: xstormy16_init_extra_frame_info
- This is the constructor function for the frame_info struct,
- called whenever a new frame_info is created (from create_new_frame,
- and from get_prev_frame).
-*/
-
-static void
-xstormy16_init_extra_frame_info (int fromleaf, struct frame_info *fi)
-{
- if (!get_frame_extra_info (fi))
- {
- frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
- get_frame_extra_info (fi)->framesize = 0;
- get_frame_extra_info (fi)->frameless_p = 1; /* Default frameless, detect framed */
-
- /* By default, the fi->frame is set to the value of the FP reg by gdb.
- This may not always be right; we may be in a frameless function,
- or we may be in the prologue, before the FP has been set up.
- Unfortunately, we can't make this determination without first
- calling scan_prologue, and we can't do that unles we know the
- get_frame_pc (fi). */
-
- if (!get_frame_pc (fi))
- {
- /* Sometimes we are called from get_prev_frame without
- the PC being set up first. Long history, don't ask.
- Fortunately this will never happen from the outermost
- frame, so we should be able to get the saved pc from
- the next frame. */
- if (get_next_frame (fi))
- deprecated_update_frame_pc_hack (fi, xstormy16_frame_saved_pc (get_next_frame (fi)));
- }
-
- /* Take care of the saved_regs right here (non-lazy). */
- xstormy16_frame_init_saved_regs (fi);
- }
-}
-
-/* Function: xstormy16_frame_chain
- Returns a pointer to the stack frame of the calling function.
- Called only from get_prev_frame. Needed for backtrace, "up", etc.
-*/
-
-static CORE_ADDR
-xstormy16_frame_chain (struct frame_info *fi)
-{
- if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
- get_frame_base (fi)))
- {
- /* Call dummy's frame is the same as caller's. */
- return get_frame_base (fi);
- }
- else
- {
- /* Return computed offset from this frame's fp. */
- return get_frame_base (fi) - get_frame_extra_info (fi)->framesize;
- }
-}
-
-static int
-xstormy16_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
-{
- return chain < 0x8000 && DEPRECATED_FRAME_SAVED_PC (thisframe) >= 0x8000 &&
- (get_frame_extra_info (thisframe)->frameless_p ||
- get_frame_base (thisframe) - get_frame_extra_info (thisframe)->framesize == chain);
-}
-
-/* Function: xstormy16_saved_pc_after_call Returns the previous PC
- immediately after a function call. This function is meant to
- bypass the regular frame_register() mechanism, ie. it is meant to
- work even if the frame isn't complete. Called by
- step_over_function, and sometimes by get_prev_frame. */
-
-static CORE_ADDR
-xstormy16_saved_pc_after_call (struct frame_info *ignore)
-{
- CORE_ADDR sp, pc, tmp;
-
- sp = read_register (E_SP_REGNUM) - xstormy16_pc_size;
- pc = read_memory_integer (sp, xstormy16_pc_size);
-
- /* Skip over jump table entry if necessary. */
- if ((tmp = SKIP_TRAMPOLINE_CODE (pc)))
- pc = tmp;
-
- return pc;
-}
-