void d30v_frame_find_saved_regs PARAMS ((struct frame_info *fi,
struct frame_saved_regs *fsr));
+void d30v_frame_find_saved_regs_offsets PARAMS ((struct frame_info *fi,
+ struct frame_saved_regs *fsr));
static void d30v_pop_dummy_frame PARAMS ((struct frame_info *fi));
static void d30v_print_flags PARAMS ((void));
static void print_flags_command PARAMS ((char *, int));
#define OP_ADD_SP_IMM 0x080bffc0 /* add sp,sp,imm */
#define OP_ADD_R22_SP_IMM 0x08096fc0 /* add r22,sp,imm */
#define OP_STW_FP_SP_IMM 0x054bdfc0 /* stw fp,@(sp,imm) */
+#define OP_OR_SP_R0_IMM 0x03abf000 /* or sp,r0,imm */
/* no mask */
#define OP_OR_FP_R0_SP 0x03a3d03f /* or fp,r0,sp */
#define EXTRACT_IMM26(op) ((((op)&0x0ff00000) >> 2) | ((op)&0x0003ffff))
#define EXTRACT_IMM32(opl, opr) ((EXTRACT_UIMM6(opl) << 26)|EXTRACT_IMM26(opr))
+
+int
+d30v_frame_chain_valid (chain, fi)
+ CORE_ADDR chain;
+ struct frame_info *fi; /* not used here */
+{
+#if 0
+ return ((chain) != 0 && (fi) != 0 && (fi)->return_pc != 0);
+#else
+ return ((chain) != 0 && (fi) != 0 && (fi)->frame <= chain);
+#endif
+}
+
/* Discard from the stack the innermost frame, restoring all saved
registers. */
return pc;
}
+static int end_of_stack;
+
/* Given a GDB frame, determine the address of the calling function's frame.
This will be used to create a new GDB frame struct, and then
INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
d30v_frame_find_saved_regs (frame, &fsr);
+ if (end_of_stack)
+ return (CORE_ADDR)0;
+
if (frame->return_pc == IMEM_START)
return (CORE_ADDR)0;
if (!read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4))
return (CORE_ADDR)0;
- return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4)| DMEM_START;
+ return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4);
}
static int next_addr, uses_frame;
if ((op & OP_MASK_ALL_BUT_IMM) == OP_SUB_SP_IMM)
{
offset = EXTRACT_IMM6(op);
- next_addr -= offset;
+ frame_size += -offset;
return 1;
}
- /* st rn, @(sp,0) */
+ /* st rn, @(sp,0) -- observed */
if (((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_R0) ||
((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_IMM0))
{
n = EXTRACT_RA(op);
- fsr->regs[n] = next_addr;
+ fsr->regs[n] = (- frame_size);
return 1;
}
((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_IMM0))
{
n = EXTRACT_RA(op);
- fsr->regs[n] = next_addr;
- fsr->regs[n+1] = next_addr+4;
+ fsr->regs[n] = (- frame_size);
+ fsr->regs[n+1] = (- frame_size) + 4;
return 1;
}
+ /* stw fp,@(sp,imm) -- observed */
+ if ((op & OP_MASK_ALL_BUT_IMM) == OP_STW_FP_SP_IMM)
+ {
+ offset = EXTRACT_IMM6(op);
+ fsr->regs[FP_REGNUM] = (offset - frame_size);
+ return 1;
+ }
return 0;
}
memset (fsr, 0, sizeof (*fsr));
next_addr = 0;
frame_size = 0;
+ end_of_stack = 0;
+
+ uses_frame = 0;
+
+ d30v_frame_find_saved_regs_offsets (fi, fsr);
+
+ fi->size = frame_size;
+
+ if (!fp)
+ fp = read_register(SP_REGNUM);
+
+ for (i=0; i<NUM_REGS-1; i++)
+ if (fsr->regs[i])
+ {
+ fsr->regs[i] = fsr->regs[i] + fp + frame_size;
+ }
+
+ if (fsr->regs[LR_REGNUM])
+ fi->return_pc = read_memory_unsigned_integer(fsr->regs[LR_REGNUM],4);
+ else
+ fi->return_pc = read_register(LR_REGNUM);
+
+ /* the SP is not normally (ever?) saved, but check anyway */
+ if (!fsr->regs[SP_REGNUM])
+ {
+ /* if the FP was saved, that means the current FP is valid, */
+ /* otherwise, it isn't being used, so we use the SP instead */
+ if (uses_frame)
+ fsr->regs[SP_REGNUM] = read_register(FP_REGNUM) + fi->size;
+ else
+ {
+ fsr->regs[SP_REGNUM] = fp + fi->size;
+ fi->frameless = 1;
+ fsr->regs[FP_REGNUM] = 0;
+ }
+ }
+}
+
+void
+d30v_frame_find_saved_regs_offsets (fi, fsr)
+ struct frame_info *fi;
+ struct frame_saved_regs *fsr;
+{
+ CORE_ADDR fp, pc;
+ unsigned long opl, opr;
+ unsigned long op1, op2;
+ unsigned long fm0, fm1;
+ int i;
+
+ fp = fi->frame;
+ memset (fsr, 0, sizeof (*fsr));
+ next_addr = 0;
+ frame_size = 0;
+ end_of_stack = 0;
pc = get_pc_function_start (fi->pc);
uses_frame = 0;
- while (1)
+ while (pc < fi->pc)
{
opl = (unsigned long)read_memory_integer (pc, 4);
opr = (unsigned long)read_memory_integer (pc+4, 4);
fsr->regs[n] = (offset - frame_size);
fsr->regs[n+1] = (offset - frame_size) + 4;
}
+ else if ((opl & OP_MASK_ALL_BUT_IMM) == OP_OR_SP_R0_IMM)
+ {
+ end_of_stack = 1;
+ }
else
break;
}
pc += 8;
}
+#if 0
fi->size = frame_size;
+
if (!fp)
-#if 0
- fp = read_register(SP_REGNUM) | DMEM_START;
-#else
fp = read_register(SP_REGNUM);
-#endif
+
for (i=0; i<NUM_REGS-1; i++)
if (fsr->regs[i])
{
else
fi->return_pc = read_register(LR_REGNUM);
- /* th SP is not normally (ever?) saved, but check anyway */
+ /* the SP is not normally (ever?) saved, but check anyway */
if (!fsr->regs[SP_REGNUM])
{
/* if the FP was saved, that means the current FP is valid, */
fsr->regs[FP_REGNUM] = 0;
}
}
+#endif
}
void
if (fi->next && (fi->pc == 0))
fi->pc = fi->next->return_pc;
- d30v_frame_find_saved_regs (fi, &dummy);
+ d30v_frame_find_saved_regs_offsets (fi, &dummy);
+
+ if (uses_frame == 0)
+ fi->frameless = 1;
+ else
+ fi->frameless = 0;
+
+ if ((fi->next == 0) && (uses_frame == 0))
+ /* innermost frame and it's "frameless",
+ so the fi->frame field is wrong, fix it! */
+ fi->frame = read_sp ();
+
+ if (dummy.regs[LR_REGNUM])
+ {
+ /* it was saved, grab it! */
+ dummy.regs[LR_REGNUM] += (fi->frame + frame_size);
+ fi->return_pc = read_memory_unsigned_integer(dummy.regs[LR_REGNUM],4);
+ }
+ else
+ fi->return_pc = read_register(LR_REGNUM);
}
void
read_relative_register_raw_bytes (regnum, regbuf);
- val_print (REGISTER_VIRTUAL_TYPE (regnum), regbuf, 0,
+ val_print (REGISTER_VIRTUAL_TYPE (regnum), regbuf, 0, 0,
gdb_stdout, 'x', 1, 0, Val_pretty_default);
if (!tabular)
{
printf_filtered (" ");
- val_print (REGISTER_VIRTUAL_TYPE (regnum), regbuf, 0,
+ val_print (REGISTER_VIRTUAL_TYPE (regnum), regbuf, 0, 0,
gdb_stdout, 'd', 1, 0, Val_pretty_default);
}
}
if (regnum != -1)
{
- if (reg_names[0] == NULL || reg_names[0][0] == '\000')
+ if (REGISTER_NAME (0) == NULL || REGISTER_NAME (0)[0] == '\000')
return;
- printf_filtered ("%s ", reg_names[regnum]);
+ printf_filtered ("%s ", REGISTER_NAME (regnum));
d30v_print_register (regnum, 0);
printf_filtered ("\n");
struct type *arg_type = check_typedef (VALUE_TYPE (arg));
len = TYPE_LENGTH (arg_type);
contents = VALUE_CONTENTS(arg);
- val = extract_signed_integer (contents, len);
if (len > 4)
{
/* we need multiple registers */
int ndx;
- for (ndx = 0; ndx < len; ndx += 4, len -= 4)
+ for (ndx = 0; len > 0; ndx += 8, len -= 8)
{
+ if (regnum & 1)
+ regnum++; /* all args > 4 bytes start in even register */
+
if (regnum < 18)
{
- if (len > 4)
- val = extract_signed_integer (&contents[ndx], 4);
- else
- val = extract_signed_integer (&contents[ndx], len);
+ val = extract_signed_integer (&contents[ndx], 4);
+ write_register (regnum++, val);
+ if (len >= 8)
+ val = extract_signed_integer (&contents[ndx+4], 4);
+ else
+ val = extract_signed_integer (&contents[ndx+4], len-4);
write_register (regnum++, val);
}
else
{
/* no more registers available. put it on the stack */
- sp -= len;
+
+ /* all args > 4 bytes are padded to a multiple of 8 bytes
+ and start on an 8 byte boundary */
+ if (sp & 7)
+ sp -= (sp & 7); /* align it */
+
+ sp -= ((len + 7) & ~7); /* allocate space */
write_memory (sp, &contents[ndx], len);
break;
}
{
if (regnum < 18 )
{
+ val = extract_signed_integer (contents, len);
write_register (regnum++, val);
}
else
{
- sp -= len;
- store_address (buffer, len, val);
- write_memory (sp, buffer, len);
+ /* all args are padded to a multiple of 4 bytes (at least) */
+ sp -= ((len + 3) & ~3);
+ write_memory (sp, contents, len);
}
}
}
+ if (sp & 7)
+ /* stack pointer is not on an 8 byte boundary -- align it */
+ sp -= (sp & 7);
return sp;
}