X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Frs6000-tdep.c;h=98e1a0ca088ee69f5975627d5dbb4ebe0dfd9f2c;hb=143985b7f3c98d0644b2eef50059f14974fe9d64;hp=72079ce3e9ee0504f568c33869d341027c4dd6eb;hpb=8bedc05091d9d4874d382a6c66b7845133f7b5ea;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 72079ce3e9..98e1a0ca08 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -137,6 +137,18 @@ altivec_register_p (int regno) return (regno >= tdep->ppc_vr0_regnum && regno <= tdep->ppc_vrsave_regnum); } +/* Use the architectures FP registers? */ +int +ppc_floating_point_unit_p (struct gdbarch *gdbarch) +{ + const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch); + if (info->arch == bfd_arch_powerpc) + return (info->mach != bfd_mach_ppc_e500); + if (info->arch == bfd_arch_rs6000) + return 1; + return 0; +} + /* Read a LEN-byte address from debugged memory address MEMADDR. */ static CORE_ADDR @@ -218,6 +230,16 @@ rs6000_saved_pc_after_call (struct frame_info *fi) 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 @@ -293,14 +315,11 @@ branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety) /* 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; @@ -517,13 +536,13 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) 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; } @@ -549,7 +568,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) { fdata->saved_gpr = reg; if ((op & 0xfc1f0003) == 0xf8010000) - op = (op >> 1) << 1; + op &= ~3UL; fdata->gpr_offset = SIGNED_SHORT (op) + offset; } continue; @@ -581,20 +600,42 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) 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; } @@ -638,30 +679,41 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) 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; @@ -972,13 +1024,13 @@ rs6000_pop_frame (void) } /* 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 saved %pc value in the previous frame. */ - addr = get_pc_function_start (get_frame_pc (frame)); + addr = get_frame_func (frame); (void) skip_prologue (addr, get_frame_pc (frame), &fdata); wordsize = gdbarch_tdep (current_gdbarch)->wordsize; @@ -1257,7 +1309,7 @@ ran_out_of_registers_for_arguments: 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); @@ -1487,7 +1539,7 @@ rs6000_frameless_function_invocation (struct frame_info *fi) && !(get_frame_type (get_next_frame (fi)) == SIGTRAMP_FRAME)) return 0; - func_start = get_pc_function_start (get_frame_pc (fi)); + func_start = get_frame_func (fi); /* If we failed to find the start of the function, it is a mistake to inspect the instructions. */ @@ -1528,7 +1580,7 @@ rs6000_frame_saved_pc (struct frame_info *fi) return deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), PC_REGNUM); - func_start = get_pc_function_start (get_frame_pc (fi)); + func_start = get_frame_func (fi); /* If we failed to find the start of the function, it is a mistake to inspect the instructions. */ @@ -1554,14 +1606,16 @@ rs6000_frame_saved_pc (struct frame_info *fi) return lr; } else - return read_memory_addr (FRAME_CHAIN (fi) + tdep->lr_frame_offset, + return read_memory_addr (DEPRECATED_FRAME_CHAIN (fi) + + tdep->lr_frame_offset, wordsize); } if (fdata.lr_offset == 0) return read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum); - return read_memory_addr (FRAME_CHAIN (fi) + fdata.lr_offset, wordsize); + return read_memory_addr (DEPRECATED_FRAME_CHAIN (fi) + fdata.lr_offset, + wordsize); } /* If saved registers of frame FI are not known yet, read and cache them. @@ -1582,8 +1636,7 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) if (fdatap == NULL) { fdatap = &work_fdata; - (void) skip_prologue (get_pc_function_start (get_frame_pc (fi)), - get_frame_pc (fi), fdatap); + (void) skip_prologue (get_frame_func (fi), get_frame_pc (fi), fdatap); } frame_saved_regs_zalloc (fi); @@ -1608,7 +1661,7 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) ->frame pointed to the outer-most address of the frame. In the mean time, the address of the prev frame is used as the base address of this frame. */ - frame_addr = FRAME_CHAIN (fi); + frame_addr = DEPRECATED_FRAME_CHAIN (fi); /* if != -1, fdatap->saved_fpr is the smallest number of saved_fpr. All fpr's from saved_fpr to fp31 are saved. */ @@ -1633,7 +1686,7 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) CORE_ADDR gpr_addr = frame_addr + fdatap->gpr_offset; for (i = fdatap->saved_gpr; i < 32; i++) { - get_frame_saved_regs (fi)[i] = gpr_addr; + get_frame_saved_regs (fi)[tdep->ppc_gp0_regnum + i] = gpr_addr; gpr_addr += wordsize; } } @@ -1706,8 +1759,7 @@ frame_initial_stack_address (struct frame_info *fi) /* Find out if this function is using an alloca register. */ - (void) skip_prologue (get_pc_function_start (get_frame_pc (fi)), - get_frame_pc (fi), &fdata); + (void) skip_prologue (get_frame_func (fi), get_frame_pc (fi), &fdata); /* If saved registers of this frame are not known yet, read and cache them. */ @@ -1727,7 +1779,7 @@ frame_initial_stack_address (struct frame_info *fi) /* 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 @@ -1746,8 +1798,8 @@ frame_initial_stack_address (struct frame_info *fi) /* Describe the pointer in each stack frame to the previous stack frame (its caller). */ -/* FRAME_CHAIN takes a frame's nominal address - and produces the frame's chain-pointer. */ +/* DEPRECATED_FRAME_CHAIN takes a frame's nominal address and produces + the frame's chain-pointer. */ /* In the case of the RS/6000, the frame's nominal address is the address of a 4-byte word containing the calling frame's address. */ @@ -1880,8 +1932,8 @@ rs6000_register_convert_to_virtual (int n, struct type *type, { if (TYPE_LENGTH (type) != REGISTER_RAW_SIZE (n)) { - double val = extract_floating (from, REGISTER_RAW_SIZE (n)); - store_floating (to, TYPE_LENGTH (type), val); + double val = deprecated_extract_floating (from, REGISTER_RAW_SIZE (n)); + deprecated_store_floating (to, TYPE_LENGTH (type), val); } else memcpy (to, from, REGISTER_RAW_SIZE (n)); @@ -1896,8 +1948,8 @@ rs6000_register_convert_to_raw (struct type *type, int n, { if (TYPE_LENGTH (type) != REGISTER_RAW_SIZE (n)) { - double val = extract_floating (from, TYPE_LENGTH (type)); - store_floating (to, REGISTER_RAW_SIZE (n), val); + double val = deprecated_extract_floating (from, TYPE_LENGTH (type)); + deprecated_store_floating (to, REGISTER_RAW_SIZE (n), val); } else memcpy (to, from, REGISTER_RAW_SIZE (n)); @@ -1909,7 +1961,7 @@ e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, { 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 @@ -1932,7 +1984,7 @@ e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, { 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 @@ -2062,10 +2114,10 @@ rs6000_extract_struct_value_address (struct regcache *regcache) /* FIXME: cagney/2002-09-26: PR gdb/724: When making an inferior function call GDB knows the address of the struct return value and hence, should not need to call this function. Unfortunately, - the current hand_function_call() code only saves the most recent - struct address leading to occasional calls. The code should - instead maintain a stack of such addresses (in the dummy frame - object). */ + the current call_function_by_hand() code only saves the most + recent struct address leading to occasional calls. The code + should instead maintain a stack of such addresses (in the dummy + frame object). */ /* NOTE: cagney/2002-09-26: Return 0 which indicates that we've really got no idea where the return value is being stored. While r3, on function entry, contained the address it will have since @@ -2727,9 +2779,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) else { arch = bfd_arch_powerpc; - mach = 0; - bfd_default_set_arch_mach (&abfd, arch, mach); + bfd_default_set_arch_mach (&abfd, arch, 0); info.bfd_arch_info = bfd_get_arch_info (&abfd); + mach = info.bfd_arch_info->mach; } tdep = xmalloc (sizeof (struct gdbarch_tdep)); tdep->wordsize = wordsize; @@ -2785,7 +2837,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pc_regnum (gdbarch, 64); set_gdbarch_sp_regnum (gdbarch, 1); - set_gdbarch_fp_regnum (gdbarch, 1); + set_gdbarch_deprecated_fp_regnum (gdbarch, 1); set_gdbarch_deprecated_extract_return_value (gdbarch, rs6000_extract_return_value); set_gdbarch_deprecated_store_return_value (gdbarch, rs6000_store_return_value); @@ -2818,7 +2870,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->ppc_ev31_regnum = 38; set_gdbarch_pc_regnum (gdbarch, 0); set_gdbarch_sp_regnum (gdbarch, tdep->ppc_gp0_regnum + 1); - set_gdbarch_fp_regnum (gdbarch, tdep->ppc_gp0_regnum + 1); + set_gdbarch_deprecated_fp_regnum (gdbarch, tdep->ppc_gp0_regnum + 1); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, e500_dwarf2_reg_to_regnum); set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write); @@ -2860,15 +2912,14 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_read_pc (gdbarch, generic_target_read_pc); set_gdbarch_write_pc (gdbarch, generic_target_write_pc); - set_gdbarch_read_fp (gdbarch, generic_target_read_fp); set_gdbarch_read_sp (gdbarch, generic_target_read_sp); - set_gdbarch_write_sp (gdbarch, generic_target_write_sp); + set_gdbarch_deprecated_dummy_write_sp (gdbarch, generic_target_write_sp); set_gdbarch_num_regs (gdbarch, v->nregs); set_gdbarch_num_pseudo_regs (gdbarch, v->npregs); set_gdbarch_register_name (gdbarch, rs6000_register_name); - set_gdbarch_register_size (gdbarch, wordsize); - set_gdbarch_register_bytes (gdbarch, off); + set_gdbarch_deprecated_register_size (gdbarch, wordsize); + 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); @@ -2883,20 +2934,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT); set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT); set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); - set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); + if (sysv_abi) + set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT); + else + set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); set_gdbarch_char_signed (gdbarch, 0); - set_gdbarch_call_dummy_length (gdbarch, 0); - set_gdbarch_call_dummy_address (gdbarch, entry_point_address); - set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1); - set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0); - set_gdbarch_call_dummy_start_offset (gdbarch, 0); - set_gdbarch_call_dummy_p (gdbarch, 1); - set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0); - set_gdbarch_fix_call_dummy (gdbarch, rs6000_fix_call_dummy); + set_gdbarch_deprecated_fix_call_dummy (gdbarch, rs6000_fix_call_dummy); set_gdbarch_frame_align (gdbarch, rs6000_frame_align); set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); - set_gdbarch_push_return_address (gdbarch, ppc_push_return_address); + set_gdbarch_deprecated_push_return_address (gdbarch, ppc_push_return_address); set_gdbarch_believe_pcc_promotion (gdbarch, 1); set_gdbarch_register_convertible (gdbarch, rs6000_register_convertible); @@ -2911,13 +2958,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 64-bit code. At some point in the future, this matter needs to be revisited. */ if (sysv_abi && wordsize == 4) - set_gdbarch_push_arguments (gdbarch, ppc_sysv_abi_push_arguments); + set_gdbarch_deprecated_push_arguments (gdbarch, ppc_sysv_abi_push_arguments); else - set_gdbarch_push_arguments (gdbarch, rs6000_push_arguments); + set_gdbarch_deprecated_push_arguments (gdbarch, rs6000_push_arguments); - set_gdbarch_store_struct_return (gdbarch, rs6000_store_struct_return); + set_gdbarch_deprecated_store_struct_return (gdbarch, rs6000_store_struct_return); set_gdbarch_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address); - set_gdbarch_pop_frame (gdbarch, rs6000_pop_frame); + set_gdbarch_deprecated_pop_frame (gdbarch, rs6000_pop_frame); set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue); set_gdbarch_inner_than (gdbarch, core_addr_lessthan); @@ -2937,7 +2984,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_frameless_function_invocation (gdbarch, rs6000_frameless_function_invocation); - set_gdbarch_frame_chain (gdbarch, rs6000_frame_chain); + set_gdbarch_deprecated_frame_chain (gdbarch, rs6000_frame_chain); set_gdbarch_deprecated_frame_saved_pc (gdbarch, rs6000_frame_saved_pc); set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, rs6000_frame_init_saved_regs); @@ -2952,7 +2999,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } set_gdbarch_frame_args_address (gdbarch, rs6000_frame_args_address); set_gdbarch_frame_locals_address (gdbarch, rs6000_frame_args_address); - set_gdbarch_saved_pc_after_call (gdbarch, rs6000_saved_pc_after_call); + 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. */