More changes, mostly from IBM for rs6000. (See ChangeLog.)

This commit is contained in:
Per Bothner
1992-03-02 01:55:31 +00:00
parent 4b8333deca
commit 6c6afbb92b
9 changed files with 374 additions and 95 deletions

View File

@@ -227,7 +227,7 @@ frameless_function_invocation (fi)
struct frame_info *fi;
{
CORE_ADDR func_start;
int frameless, dummy;
struct aix_framedata fdata;
func_start = get_pc_function_start (fi->pc) + FUNCTION_START_OFFSET;
@@ -237,11 +237,110 @@ struct frame_info *fi;
if (!func_start)
return 0;
function_frame_info (func_start, &frameless, &dummy, &dummy, &dummy);
return frameless;
function_frame_info (func_start, &fdata);
return fdata.frameless;
}
/* Return the address of a frame. This is the inital %sp value when the frame
was first allocated. For functions calling alloca(), it might be saved in
an alloca register. */
CORE_ADDR
frame_initial_stack_address (fi)
struct frame_info *fi;
{
CORE_ADDR frame_addr, tmpaddr;
struct aix_framedata fdata;
struct frame_info *callee_fi;
int ii;
extern struct obstack frame_cache_obstack;
/* if the initial stack pointer (frame address) of this frame is known,
just return it. */
if (fi->initial_sp)
return fi->initial_sp;
/* find out if this function is using an alloca register.. */
tmpaddr = get_pc_function_start (fi->pc);
function_frame_info (tmpaddr, &fdata);
/* if saved registers of this frame are not known yet, read and cache them. */
if (!fi->cache_fsr) {
fi->cache_fsr = (struct frame_saved_regs *)
obstack_alloc (&frame_cache_obstack, sizeof (struct frame_saved_regs));
bzero (fi->cache_fsr, sizeof (struct frame_saved_regs));
if (fi->prev && fi->prev->frame)
frame_addr = fi->prev->frame;
else
frame_addr = read_memory_integer (fi->frame, 4);
/* if != -1, fdata.saved_fpr is the smallest number of saved_fpr. All fpr's
from saved_fpr to fp31 are saved right underneath caller stack pointer,
starting from fp31 first. */
if (fdata.saved_fpr >= 0) {
for (ii=31; ii >= fdata.saved_fpr; --ii)
fi->cache_fsr->regs [FP0_REGNUM + ii] = frame_addr - ((32 - ii) * 8);
frame_addr -= (32 - fdata.saved_fpr) * 8;
}
/* if != -1, fdata.saved_gpr is the smallest number of saved_gpr. All gpr's
from saved_gpr to gpr31 are saved right under saved fprs, starting
from r31 first. */
if (fdata.saved_gpr >= 0)
for (ii=31; ii >= fdata.saved_gpr; --ii)
fi->cache_fsr->regs [ii] = frame_addr - ((32 - ii) * 4);
}
/* If no alloca register used, then fi->frame is the value of the %sp for
this frame, and it is good enough. */
if (fdata.alloca_reg < 0) {
fi->initial_sp = fi->frame;
return fi->initial_sp;
}
/* This function has an alloca register. If this is the top-most frame
(with the lowest address), the value in alloca register is good. */
if (!fi->next)
return fi->initial_sp = read_register (fdata.alloca_reg);
/* Otherwise, this is a caller frame. Callee has already saved (???) its
registers. Find the address in which caller's alloca register is saved. */
for (callee_fi = fi->next; callee_fi; callee_fi = callee_fi->next) {
if (!callee_fi->cache_fsr)
fatal ("Callee has not saved caller's registers.");
/* this is the address in which alloca register is saved. */
tmpaddr = callee_fi->cache_fsr->regs [fdata.alloca_reg];
if (tmpaddr) {
fi->initial_sp = read_memory_integer (tmpaddr, 4);
return fi->initial_sp;
}
/* Go look into deeper levels of the frame chain to see if any one of
the callees has saved alloca register. */
}
/* If alloca register was not saved, by the callee (or any of its callees)
then the value in the register is still good. */
return fi->initial_sp = read_register (fdata.alloca_reg);
}
/* aixcoff_relocate_symtab - hook for symbol table relocation.
also reads shared libraries.. */