along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-#include <stdio.h>
#include "defs.h"
-#include "param.h"
#include "frame.h"
#include "inferior.h"
#include "value.h"
#include "setjmp.h"
#include "value.h"
+/* Size of an instruction */
+#define BYTES_PER_88K_INSN 4
+
void frame_find_saved_regs ();
struct frame_info *thisframe;
{
return (chain != 0
- && outside_startup_file (FRAME_SAVED_PC (thisframe)));
-}
-
-CORE_ADDR
-frame_chain_combine (chain, thisframe)
- CORE_ADDR chain;
-{
- return chain;
+ && !inside_entry_file (FRAME_SAVED_PC (thisframe)));
}
void
fi->args_pointer = 0; /* Unknown */
fi->locals_pointer = 0; /* Unknown */
}
-
-void
-init_frame_pc (fromleaf, prev)
- int fromleaf;
- struct frame_info *prev;
-{
- /* FIXME, for now it's the default from blockframe.c. If it stays that
- way, remove it entirely from here. */
- prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) :
- prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ());
-
-}
\f
/* Examine an m88k function prologue, recording the addresses at which
registers are saved explicitly by the prologue code, and returning
(addu r30,r31,n)? # frame pointer update
(pic sequence)? # PIC code prologue
+
+ (or rn,rm,0)? # Move parameters to other regs
*/
/* Macros for extracting fields from instructions. */
{
unsigned long buf[1];
- read_memory (memaddr, buf, sizeof (buf));
- *pword1 = buf[0];
- SWAP_TARGET_AND_HOST (pword1, sizeof (long));
-
- return memaddr + 4;
+ *pword1 = read_memory_integer (memaddr, BYTES_PER_88K_INSN);
+ return memaddr + BYTES_PER_88K_INSN;
}
/* Read a register from frames called by us (or from the hardware regs). */
bzero (must_adjust, sizeof (must_adjust));
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+ /* Accept move of incoming registers to other registers, using
+ "or rd,rs,0" or "or.u rd,rs,0" or "or rd,r0,rs" or "or rd,rs,r0".
+ We don't have to worry about walking into the first lines of code,
+ since the first line number will stop us (assuming we have symbols).
+ What we have actually seen is "or r10,r0,r12". */
+
+#define OR_MOVE_INSN 0x58000000 /* or/or.u with immed of 0 */
+#define OR_MOVE_MASK 0xF800FFFF
+#define OR_REG_MOVE1_INSN 0xF4005800 /* or rd,r0,rs */
+#define OR_REG_MOVE1_MASK 0xFC1FFFE0
+#define OR_REG_MOVE2_INSN 0xF4005800 /* or rd,rs,r0 */
+#define OR_REG_MOVE2_MASK 0xFC00FFFF
+ while (next_ip &&
+ ((insn1 & OR_MOVE_MASK) == OR_MOVE_INSN ||
+ (insn1 & OR_REG_MOVE1_MASK) == OR_REG_MOVE1_INSN ||
+ (insn1 & OR_REG_MOVE2_MASK) == OR_REG_MOVE2_INSN
+ )
+ )
+ {
+ /* We don't care what moves to where. The result of the moves
+ has already been reflected in what the compiler tells us is the
+ location of these parameters. */
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+ }
+
/* Accept an optional "subu sp,sp,n" to set up the stack pointer. */
#define SUBU_SP_INSN 0x67ff0000
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
}
+ /* Accept moves of parameter registers to other registers, using
+ "or rd,rs,0" or "or.u rd,rs,0" or "or rd,r0,rs" or "or rd,rs,r0".
+ We don't have to worry about walking into the first lines of code,
+ since the first line number will stop us (assuming we have symbols).
+ What gcc actually seems to produce is "or rd,r0,rs". */
+
+#define OR_MOVE_INSN 0x58000000 /* or/or.u with immed of 0 */
+#define OR_MOVE_MASK 0xF800FFFF
+#define OR_REG_MOVE1_INSN 0xF4005800 /* or rd,r0,rs */
+#define OR_REG_MOVE1_MASK 0xFC1FFFE0
+#define OR_REG_MOVE2_INSN 0xF4005800 /* or rd,rs,r0 */
+#define OR_REG_MOVE2_MASK 0xFC00FFFF
+ while (next_ip &&
+ ((insn1 & OR_MOVE_MASK) == OR_MOVE_INSN ||
+ (insn1 & OR_REG_MOVE1_MASK) == OR_REG_MOVE1_INSN ||
+ (insn1 & OR_REG_MOVE2_MASK) == OR_REG_MOVE2_INSN
+ )
+ )
+ {
+ /* We don't care what moves to where. The result of the moves
+ has already been reflected in what the compiler tells us is the
+ location of these parameters. */
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+ }
+
/* We're done with the prologue. If we don't care about the stack
frame itself, just return. (Note that fsr->regs has been trashed,
but the one caller who calls with fi==0 passes a dummy there.) */
case TYPE_CODE_ENUM: /* Enumeration type */
case TYPE_CODE_INT: /* Integer type */
case TYPE_CODE_REF: /* C++ Reference types */
- case TYPE_CODE_ARRAY: /* Array type, lower bound zero */
+ case TYPE_CODE_ARRAY: /* Array type, lower & upper bounds */
return 1;
case TYPE_CODE_FUNC: /* Function type */
case TYPE_CODE_SET: /* Pascal sets */
case TYPE_CODE_RANGE: /* Range (integers within bounds) */
- case TYPE_CODE_PASCAL_ARRAY: /* Array with explicit type of index */
+ case TYPE_CODE_STRING: /* String type */
case TYPE_CODE_MEMBER: /* Member type */
case TYPE_CODE_METHOD: /* Method type */
/* Don't know how to pass these yet. */
CORE_ADDR address;
int val;
{
- write_memory (address, &val, 4);
+ write_memory (address, (char *)&val, 4);
}
static int
case TYPE_CODE_PTR: /* Pointer type */
case TYPE_CODE_ENUM: /* Enumeration type */
case TYPE_CODE_INT: /* Integer type */
- case TYPE_CODE_ARRAY: /* Array type, lower bound zero */
+ case TYPE_CODE_ARRAY: /* Array type, lower & upper bounds */
case TYPE_CODE_REF: /* C++ Reference types */
store_parm_word (start, *val_addr);