return read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum);
}
+/* Get the ith function argument for the current function. */
+CORE_ADDR
+rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
+ struct type *type)
+{
+ CORE_ADDR addr;
+ frame_read_register (frame, 3 + argi, &addr);
+ return addr;
+}
+
/* Calculate the destination of a branch/jump. Return -1 if not a branch. */
static CORE_ADDR
/* Sequence of bytes for breakpoint instruction. */
-#define BIG_BREAKPOINT { 0x7d, 0x82, 0x10, 0x08 }
-#define LITTLE_BREAKPOINT { 0x08, 0x10, 0x82, 0x7d }
-
const static unsigned char *
rs6000_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
{
- static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
- static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;
+ static unsigned char big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 };
+ static unsigned char little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d };
*bp_size = 4;
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
return big_breakpoint;
if ((op & 0xfc1fffff) == 0x7c0802a6)
{ /* mflr Rx */
- lr_reg = (op & 0x03e00000) | 0x90010000;
+ lr_reg = (op & 0x03e00000);
continue;
}
else if ((op & 0xfc1fffff) == 0x7c000026)
{ /* mfcr Rx */
- cr_reg = (op & 0x03e00000) | 0x90010000;
+ cr_reg = (op & 0x03e00000);
continue;
}
{
fdata->saved_gpr = reg;
if ((op & 0xfc1f0003) == 0xf8010000)
- op = (op >> 1) << 1;
+ op &= ~3UL;
fdata->gpr_offset = SIGNED_SHORT (op) + offset;
}
continue;
continue;
}
- else if (lr_reg != -1 && (op & 0xffff0000) == lr_reg)
- { /* st Rx,NUM(r1)
- where Rx == lr */
- fdata->lr_offset = SIGNED_SHORT (op) + offset;
+ else if (lr_reg != -1 &&
+ /* std Rx, NUM(r1) || stdu Rx, NUM(r1) */
+ (((op & 0xffff0000) == (lr_reg | 0xf8010000)) ||
+ /* stw Rx, NUM(r1) */
+ ((op & 0xffff0000) == (lr_reg | 0x90010000)) ||
+ /* stwu Rx, NUM(r1) */
+ ((op & 0xffff0000) == (lr_reg | 0x94010000))))
+ { /* where Rx == lr */
+ fdata->lr_offset = offset;
fdata->nosavedpc = 0;
lr_reg = 0;
+ if ((op & 0xfc000003) == 0xf8000000 || /* std */
+ (op & 0xfc000000) == 0x90000000) /* stw */
+ {
+ /* Does not update r1, so add displacement to lr_offset. */
+ fdata->lr_offset += SIGNED_SHORT (op);
+ }
continue;
}
- else if (cr_reg != -1 && (op & 0xffff0000) == cr_reg)
- { /* st Rx,NUM(r1)
- where Rx == cr */
- fdata->cr_offset = SIGNED_SHORT (op) + offset;
+ else if (cr_reg != -1 &&
+ /* std Rx, NUM(r1) || stdu Rx, NUM(r1) */
+ (((op & 0xffff0000) == (cr_reg | 0xf8010000)) ||
+ /* stw Rx, NUM(r1) */
+ ((op & 0xffff0000) == (cr_reg | 0x90010000)) ||
+ /* stwu Rx, NUM(r1) */
+ ((op & 0xffff0000) == (cr_reg | 0x94010000))))
+ { /* where Rx == cr */
+ fdata->cr_offset = offset;
cr_reg = 0;
+ if ((op & 0xfc000003) == 0xf8000000 ||
+ (op & 0xfc000000) == 0x90000000)
+ {
+ /* Does not update r1, so add displacement to cr_offset. */
+ fdata->cr_offset += SIGNED_SHORT (op);
+ }
continue;
}
this branch */
continue;
- /* update stack pointer */
}
- else if ((op & 0xffff0000) == 0x94210000 || /* stu r1,NUM(r1) */
- (op & 0xffff0003) == 0xf8210001) /* stdu r1,NUM(r1) */
- {
+ /* update stack pointer */
+ else if ((op & 0xfc1f0000) == 0x94010000)
+ { /* stu rX,NUM(r1) || stwu rX,NUM(r1) */
fdata->frameless = 0;
- if ((op & 0xffff0003) == 0xf8210001)
- op = (op >> 1) << 1;
fdata->offset = SIGNED_SHORT (op);
offset = fdata->offset;
continue;
-
}
- else if (op == 0x7c21016e)
- { /* stwux 1,1,0 */
+ else if ((op & 0xfc1f016a) == 0x7c01016e)
+ { /* stwux rX,r1,rY */
+ /* no way to figure out what r1 is going to be */
fdata->frameless = 0;
offset = fdata->offset;
continue;
-
- /* Load up minimal toc pointer */
}
- else if ((op >> 22) == 0x20f
+ else if ((op & 0xfc1f0003) == 0xf8010001)
+ { /* stdu rX,NUM(r1) */
+ fdata->frameless = 0;
+ fdata->offset = SIGNED_SHORT (op & ~3UL);
+ offset = fdata->offset;
+ continue;
+ }
+ else if ((op & 0xfc1f016a) == 0x7c01016a)
+ { /* stdux rX,r1,rY */
+ /* no way to figure out what r1 is going to be */
+ fdata->frameless = 0;
+ offset = fdata->offset;
+ continue;
+ }
+ /* Load up minimal toc pointer */
+ else if (((op >> 22) == 0x20f || /* l r31,... or l r30,... */
+ (op >> 22) == 0x3af) /* ld r31,... or ld r30,... */
&& !minimal_toc_loaded)
- { /* l r31,... or l r30,... */
+ {
minimal_toc_loaded = 1;
continue;
}
/* Make sure that all registers are valid. */
- deprecated_read_register_bytes (0, NULL, REGISTER_BYTES);
+ deprecated_read_register_bytes (0, NULL, DEPRECATED_REGISTER_BYTES);
/* Figure out previous %pc value. If the function is frameless, it is
still in the link register, otherwise walk the frames and retrieve the
write_register (SP_REGNUM, sp);
/* set back chain properly */
- store_address (tmp_buffer, 4, saved_sp);
+ store_unsigned_integer (tmp_buffer, 4, saved_sp);
write_memory (sp, tmp_buffer, 4);
target_store_registers (-1);
/* There is an alloca register, use its value, in the current frame,
as the initial stack pointer. */
{
- char *tmpbuf = alloca (MAX_REGISTER_RAW_SIZE);
+ char tmpbuf[MAX_REGISTER_SIZE];
if (frame_register_read (fi, fdata.alloca_reg, tmpbuf))
{
get_frame_extra_info (fi)->initial_sp
{
int base_regnum;
int offset = 0;
- char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ char temp_buffer[MAX_REGISTER_SIZE];
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (reg_nr >= tdep->ppc_gp0_regnum
{
int base_regnum;
int offset = 0;
- char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ char temp_buffer[MAX_REGISTER_SIZE];
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (reg_nr >= tdep->ppc_gp0_regnum
set_gdbarch_num_pseudo_regs (gdbarch, v->npregs);
set_gdbarch_register_name (gdbarch, rs6000_register_name);
set_gdbarch_deprecated_register_size (gdbarch, wordsize);
- set_gdbarch_register_bytes (gdbarch, off);
+ set_gdbarch_deprecated_register_bytes (gdbarch, off);
set_gdbarch_register_byte (gdbarch, rs6000_register_byte);
set_gdbarch_register_raw_size (gdbarch, rs6000_register_raw_size);
set_gdbarch_deprecated_max_register_raw_size (gdbarch, 16);
set_gdbarch_frame_locals_address (gdbarch, rs6000_frame_args_address);
set_gdbarch_deprecated_saved_pc_after_call (gdbarch, rs6000_saved_pc_after_call);
+ /* Helpers for function argument information. */
+ set_gdbarch_fetch_pointer_argument (gdbarch, rs6000_fetch_pointer_argument);
+
/* We can't tell how many args there are
now that the C compiler delays popping them. */
set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);