/* The main purpose of this file is dealing with prologues to extract
information about stack frames and saved registers.
- For reference here's how prologues look on the mn10300:
+ In gcc/config/mn13000/mn10300.c, the expand_prologue prologue
+ function is pretty readable, and has a nice explanation of how the
+ prologue is generated. The prologues generated by that code will
+ have the following form:
- With frame pointer:
- movm [d2,d3,a2,a3],sp
- mov sp,a3
- add <size>,sp
+ + If this is an old-style varargs function, then its arguments
+ need to be flushed back to the stack:
+
+ mov d0,(4,sp)
+ mov d1,(4,sp)
- Without frame pointer:
- movm [d2,d3,a2,a3],sp (if needed)
- add <size>,sp
+ + If we use any of the callee-saved registers, save them now.
+
+ movm [some callee-saved registers],(sp)
+
+ + If we have any floating-point registers to save:
+
+ - Decrement the stack pointer to reserve space for the registers.
+ If the function doesn't need a frame pointer, we may combine
+ this with the adjustment that reserves space for the frame.
+
+ add -SIZE, sp
+
+ - Save the floating-point registers. We have two possible
+ strategies:
+
+ . Save them at fixed offset from the SP:
+
+ fmov fsN,(OFFSETN,sp)
+ fmov fsM,(OFFSETM,sp)
+ ...
+
+ . Or, set a0 to the start of the save area, and then use
+ post-increment addressing to save the FP registers.
+
+ mov sp, a0
+ add SIZE, a0
+ fmov fsN,(a0+)
+ fmov fsM,(a0+)
+ ...
+
+ + If the function needs a frame pointer, we set it here.
+
+ mov sp, a3
+
+ + Now we reserve space for the stack frame proper. This could be
+ merged into the `add -SIZE, sp' instruction for FP saves up
+ above, unless we needed to set the frame pointer in the previous
+ step, or the frame is so large that allocating the whole thing at
+ once would put the FP register save slots out of reach of the
+ addressing mode (128 bytes).
+
+ add -SIZE, sp
One day we might keep the stack pointer constant, that won't
change the code for prologues, but it will make the frame
save instructions.
MY_FRAME_IN_FP: The base of the current frame is in the
- frame pointer register ($a2).
+ frame pointer register ($a3).
NO_MORE_FRAMES: Set this if the current frame is "start" or
if the first instruction looks like mov <imm>,sp. This tells
return addr;
}
- /* First see if this insn sets the stack pointer; if so, it's something
- we won't understand, so quit now. */
+ /* First see if this insn sets the stack pointer from a register; if
+ so, it's probably the initialization of the stack pointer in _start,
+ so mark this as the bottom-most frame. */
if (buf[0] == 0xf2 && (buf[1] & 0xf3) == 0xf0)
{
if (fi)