X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmips-tdep.c;h=8d2cfa708ca2b1ef602693f8d52c51a43a509e5f;hb=324300c09f1c95c4d7da1058ca0324aa0a900096;hp=db4d9efb0bb9aab3a13711603231210b800ee5d8;hpb=a9762ec78a53fbe9209fe1654db42df0cd328d50;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index db4d9efb0b..8d2cfa708c 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -165,6 +165,9 @@ static int mips_debug = 0; #define PROPERTY_GP32 "internal: transfers-32bit-registers" #define PROPERTY_GP64 "internal: transfers-64bit-registers" +struct target_desc *mips_tdesc_gp32; +struct target_desc *mips_tdesc_gp64; + /* MIPS specific per-architecture information */ struct gdbarch_tdep { @@ -345,13 +348,15 @@ mips_xfer_register (struct regcache *regcache, int reg_num, int length, const gdb_byte *out, int buf_offset) { int reg_offset = 0; - gdb_assert (reg_num >= gdbarch_num_regs (current_gdbarch)); + struct gdbarch *gdbarch = get_regcache_arch (regcache); + + gdb_assert (reg_num >= gdbarch_num_regs (gdbarch)); /* Need to transfer the left or right part of the register, based on the targets byte order. */ switch (endian) { case BFD_ENDIAN_BIG: - reg_offset = register_size (current_gdbarch, reg_num) - length; + reg_offset = register_size (gdbarch, reg_num) - length; break; case BFD_ENDIAN_LITTLE: reg_offset = 0; @@ -397,10 +402,10 @@ mips_xfer_register (struct regcache *regcache, int reg_num, int length, static int mips2_fp_compat (struct frame_info *frame) { + struct gdbarch *gdbarch = get_frame_arch (frame); /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not meaningful. */ - if (register_size (current_gdbarch, mips_regnum (current_gdbarch)->fp0) == - 4) + if (register_size (gdbarch, mips_regnum (gdbarch)->fp0) == 4) return 0; #if 0 @@ -546,17 +551,17 @@ mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum, int vector_p; int float_p; int raw_p; - int rawnum = regnum % gdbarch_num_regs (current_gdbarch); - int pseudo = regnum / gdbarch_num_regs (current_gdbarch); + int rawnum = regnum % gdbarch_num_regs (gdbarch); + int pseudo = regnum / gdbarch_num_regs (gdbarch); if (reggroup == all_reggroup) return pseudo; vector_p = TYPE_VECTOR (register_type (gdbarch, regnum)); float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT; /* FIXME: cagney/2003-04-13: Can't yet use gdbarch_num_regs (gdbarch), as not all architectures are multi-arch. */ - raw_p = rawnum < gdbarch_num_regs (current_gdbarch); - if (gdbarch_register_name (current_gdbarch, regnum) == NULL - || gdbarch_register_name (current_gdbarch, regnum)[0] == '\0') + raw_p = rawnum < gdbarch_num_regs (gdbarch); + if (gdbarch_register_name (gdbarch, regnum) == NULL + || gdbarch_register_name (gdbarch, regnum)[0] == '\0') return 0; if (reggroup == float_reggroup) return float_p && pseudo; @@ -612,16 +617,16 @@ static void mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, gdb_byte *buf) { - int rawnum = cookednum % gdbarch_num_regs (current_gdbarch); - gdb_assert (cookednum >= gdbarch_num_regs (current_gdbarch) - && cookednum < 2 * gdbarch_num_regs (current_gdbarch)); + int rawnum = cookednum % gdbarch_num_regs (gdbarch); + gdb_assert (cookednum >= gdbarch_num_regs (gdbarch) + && cookednum < 2 * gdbarch_num_regs (gdbarch)); if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum)) regcache_raw_read (regcache, rawnum, buf); else if (register_size (gdbarch, rawnum) > register_size (gdbarch, cookednum)) { if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p - || gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE) + || gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) regcache_raw_read_part (regcache, rawnum, 0, 4, buf); else regcache_raw_read_part (regcache, rawnum, 4, 4, buf); @@ -635,16 +640,16 @@ mips_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf) { - int rawnum = cookednum % gdbarch_num_regs (current_gdbarch); - gdb_assert (cookednum >= gdbarch_num_regs (current_gdbarch) - && cookednum < 2 * gdbarch_num_regs (current_gdbarch)); + int rawnum = cookednum % gdbarch_num_regs (gdbarch); + gdb_assert (cookednum >= gdbarch_num_regs (gdbarch) + && cookednum < 2 * gdbarch_num_regs (gdbarch)); if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum)) regcache_raw_write (regcache, rawnum, buf); else if (register_size (gdbarch, rawnum) > register_size (gdbarch, cookednum)) { if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p - || gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE) + || gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) regcache_raw_write_part (regcache, rawnum, 0, 4, buf); else regcache_raw_write_part (regcache, rawnum, 4, 4, buf); @@ -720,11 +725,10 @@ mips_value_to_register (struct frame_info *frame, int regnum, static struct type * mips_register_type (struct gdbarch *gdbarch, int regnum) { - gdb_assert (regnum >= 0 && regnum < 2 * gdbarch_num_regs (current_gdbarch)); - if ((regnum % gdbarch_num_regs (current_gdbarch)) - >= mips_regnum (current_gdbarch)->fp0 - && (regnum % gdbarch_num_regs (current_gdbarch)) - < mips_regnum (current_gdbarch)->fp0 + 32) + gdb_assert (regnum >= 0 && regnum < 2 * gdbarch_num_regs (gdbarch)); + if ((regnum % gdbarch_num_regs (gdbarch)) >= mips_regnum (gdbarch)->fp0 + && (regnum % gdbarch_num_regs (gdbarch)) + < mips_regnum (gdbarch)->fp0 + 32) { /* The floating-point registers raw, or cooked, always match mips_isa_regsize(), and also map 1:1, byte for byte. */ @@ -733,7 +737,7 @@ mips_register_type (struct gdbarch *gdbarch, int regnum) else return builtin_type_ieee_double; } - else if (regnum < gdbarch_num_regs (current_gdbarch)) + else if (regnum < gdbarch_num_regs (gdbarch)) { /* The raw or ISA registers. These are all sized according to the ISA regsize. */ @@ -746,10 +750,9 @@ mips_register_type (struct gdbarch *gdbarch, int regnum) { /* The cooked or ABI registers. These are sized according to the ABI (with a few complications). */ - if (regnum >= (gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->fp_control_status) - && regnum <= gdbarch_num_regs (current_gdbarch) - + MIPS_LAST_EMBED_REGNUM) + if (regnum >= (gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp_control_status) + && regnum <= gdbarch_num_regs (gdbarch) + MIPS_LAST_EMBED_REGNUM) /* The pseudo/cooked view of the embedded registers is always 32-bit. The raw view is handled below. */ return builtin_type_int32; @@ -905,17 +908,15 @@ mips_read_pc (struct regcache *regcache) static CORE_ADDR mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { - return frame_unwind_register_signed (next_frame, - gdbarch_num_regs (current_gdbarch) - + mips_regnum (gdbarch)->pc); + return frame_unwind_register_signed + (next_frame, gdbarch_num_regs (gdbarch) + mips_regnum (gdbarch)->pc); } static CORE_ADDR mips_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) { - return frame_unwind_register_signed (next_frame, - gdbarch_num_regs (current_gdbarch) - + MIPS_SP_REGNUM); + return frame_unwind_register_signed + (next_frame, gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM); } /* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that @@ -928,7 +929,7 @@ mips_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) { return frame_id_build (frame_unwind_register_signed (next_frame, - gdbarch_num_regs (current_gdbarch) + gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM), frame_pc_unwind (next_frame)); } @@ -1008,7 +1009,7 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc) goto neq_branch; case 2: /* BLEZL */ goto less_branch; - case 3: /* BGTZ */ + case 3: /* BGTZL */ goto greater_branch; default: pc += 4; @@ -1020,7 +1021,8 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc) int tf = itype_rt (inst) & 0x01; int cnum = itype_rt (inst) >> 2; int fcrcs = - get_frame_register_signed (frame, mips_regnum (current_gdbarch)-> + get_frame_register_signed (frame, + mips_regnum (get_frame_arch (frame))-> fp_control_status); int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01); @@ -1535,12 +1537,13 @@ mips16_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc, int extend_bytes = 0; int prev_extend_bytes; CORE_ADDR end_prologue_addr = 0; + struct gdbarch *gdbarch = get_frame_arch (next_frame); /* Can be called when there's no process, and hence when there's no NEXT_FRAME. */ if (next_frame != NULL) sp = frame_unwind_register_signed (next_frame, - gdbarch_num_regs (current_gdbarch) + gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM); else sp = 0; @@ -1671,7 +1674,7 @@ mips16_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc, for (reg = 4, offset = 0; reg < areg_count + 4; reg++) { set_reg_offset (this_cache, reg, sp + offset); - offset += mips_abi_regsize (current_gdbarch); + offset += mips_abi_regsize (gdbarch); } /* Check if the ra register was pushed on the stack. */ @@ -1679,14 +1682,14 @@ mips16_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc, if (entry_inst & 0x20) { set_reg_offset (this_cache, MIPS_RA_REGNUM, sp + offset); - offset -= mips_abi_regsize (current_gdbarch); + offset -= mips_abi_regsize (gdbarch); } /* Check if the s0 and s1 registers were pushed on the stack. */ for (reg = 16; reg < sreg_count + 16; reg++) { set_reg_offset (this_cache, reg, sp + offset); - offset -= mips_abi_regsize (current_gdbarch); + offset -= mips_abi_regsize (gdbarch); } } @@ -1694,16 +1697,14 @@ mips16_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc, { this_cache->base = (frame_unwind_register_signed (next_frame, - gdbarch_num_regs (current_gdbarch) - + frame_reg) + gdbarch_num_regs (gdbarch) + frame_reg) + frame_offset - frame_adjust); /* FIXME: brobecker/2004-10-10: Just as in the mips32 case, we should be able to get rid of the assignment below, evetually. But it's still needed for now. */ - this_cache->saved_regs[gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->pc] - = this_cache->saved_regs[gdbarch_num_regs (current_gdbarch) - + MIPS_RA_REGNUM]; + this_cache->saved_regs[gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->pc] + = this_cache->saved_regs[gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM]; } /* If we didn't reach the end of the prologue when scanning the function @@ -1748,8 +1749,10 @@ mips_insn16_frame_cache (struct frame_info *next_frame, void **this_cache) } /* gdbarch_sp_regnum contains the value and not the address. */ - trad_frame_set_value (cache->saved_regs, gdbarch_num_regs (current_gdbarch) - + MIPS_SP_REGNUM, cache->base); + trad_frame_set_value (cache->saved_regs, + gdbarch_num_regs (get_frame_arch (next_frame)) + + MIPS_SP_REGNUM, + cache->base); return (*this_cache); } @@ -1857,12 +1860,13 @@ mips32_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc, CORE_ADDR end_prologue_addr = 0; int seen_sp_adjust = 0; int load_immediate_bytes = 0; + struct gdbarch *gdbarch = get_frame_arch (next_frame); /* Can be called when there's no process, and hence when there's no NEXT_FRAME. */ if (next_frame != NULL) sp = frame_unwind_register_signed (next_frame, - gdbarch_num_regs (current_gdbarch) + gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM); else sp = 0; @@ -1919,8 +1923,7 @@ restart: frame_reg = 30; frame_addr = frame_unwind_register_signed - (next_frame, - gdbarch_num_regs (current_gdbarch) + 30); + (next_frame, gdbarch_num_regs (gdbarch) + 30); alloca_adjust = (unsigned) (frame_addr - (sp + low_word)); if (alloca_adjust > 0) @@ -1950,8 +1953,7 @@ restart: frame_reg = 30; frame_addr = frame_unwind_register_signed - (next_frame, - gdbarch_num_regs (current_gdbarch) + 30); + (next_frame, gdbarch_num_regs (gdbarch) + 30); alloca_adjust = (unsigned) (frame_addr - sp); if (alloca_adjust > 0) @@ -2018,15 +2020,14 @@ restart: { this_cache->base = (frame_unwind_register_signed (next_frame, - gdbarch_num_regs (current_gdbarch) - + frame_reg) + gdbarch_num_regs (gdbarch) + frame_reg) + frame_offset); /* FIXME: brobecker/2004-09-15: We should be able to get rid of this assignment below, eventually. But it's still needed for now. */ - this_cache->saved_regs[gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->pc] - = this_cache->saved_regs[gdbarch_num_regs (current_gdbarch) + this_cache->saved_regs[gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->pc] + = this_cache->saved_regs[gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM]; } @@ -2084,7 +2085,8 @@ mips_insn32_frame_cache (struct frame_info *next_frame, void **this_cache) /* gdbarch_sp_regnum contains the value and not the address. */ trad_frame_set_value (cache->saved_regs, - gdbarch_num_regs (current_gdbarch) + MIPS_SP_REGNUM, + gdbarch_num_regs (get_frame_arch (next_frame)) + + MIPS_SP_REGNUM, cache->base); return (*this_cache); @@ -2162,6 +2164,7 @@ mips_stub_frame_cache (struct frame_info *next_frame, void **this_cache) CORE_ADDR start_addr; CORE_ADDR stack_addr; struct trad_frame_cache *this_trad_cache; + struct gdbarch *gdbarch = get_frame_arch (next_frame); if ((*this_cache) != NULL) return (*this_cache); @@ -2170,15 +2173,15 @@ mips_stub_frame_cache (struct frame_info *next_frame, void **this_cache) /* The return address is in the link register. */ trad_frame_set_reg_realreg (this_trad_cache, - gdbarch_pc_regnum (current_gdbarch), - MIPS_RA_REGNUM); + gdbarch_pc_regnum (gdbarch), + (gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM)); /* Frame ID, since it's a frameless / stackless function, no stack space is allocated and SP on entry is the current SP. */ pc = frame_pc_unwind (next_frame); find_pc_partial_function (pc, NULL, &start_addr, NULL); stack_addr = frame_unwind_register_signed (next_frame, MIPS_SP_REGNUM); - trad_frame_set_id (this_trad_cache, frame_id_build (start_addr, stack_addr)); + trad_frame_set_id (this_trad_cache, frame_id_build (stack_addr, start_addr)); /* Assume that the frame's base is the same as the stack-pointer. */ @@ -2219,9 +2222,14 @@ static const struct frame_unwind mips_stub_frame_unwind = static const struct frame_unwind * mips_stub_frame_sniffer (struct frame_info *next_frame) { + gdb_byte dummy[4]; struct obj_section *s; CORE_ADDR pc = frame_unwind_address_in_block (next_frame, NORMAL_FRAME); + /* Use the stub unwinder for unreadable code. */ + if (target_read_memory (frame_pc_unwind (next_frame), dummy, 4) != 0) + return &mips_stub_frame_unwind; + if (in_plt_section (pc, NULL)) return &mips_stub_frame_unwind; @@ -2541,7 +2549,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; - float_argreg = mips_fpa0_regnum (current_gdbarch); + float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ if (struct_return) @@ -2618,7 +2626,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, making the ABI determination. */ if (len == 8 && mips_abi (gdbarch) == MIPS_ABI_EABI32) { - int low_offset = gdbarch_byte_order (current_gdbarch) + int low_offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 4 : 0; unsigned long regval; @@ -2683,7 +2691,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int longword_offset = 0; CORE_ADDR addr; stack_used_p = 1; - if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) { if (regsize == 8 && (typecode == TYPE_CODE_INT @@ -2875,7 +2883,7 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; - float_argreg = mips_fpa0_regnum (current_gdbarch); + float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ if (struct_return) @@ -2928,12 +2936,14 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Copy the argument to general registers or the stack in register-sized pieces. Large arguments are split between registers and stack. */ - /* Note: structs whose size is not a multiple of MIPS64_REGSIZE - are treated specially: Irix cc passes them in registers - where gcc sometimes puts them on the stack. For maximum - compatibility, we will put them in both places. */ - int odd_sized_struct = (len > MIPS64_REGSIZE - && len % MIPS64_REGSIZE != 0); + /* For N32/N64, structs, unions, or other composite types are + treated as a sequence of doublewords, and are passed in integer + or floating point registers as though they were simple scalar + parameters to the extent that they fit, with any excess on the + stack packed according to the normal memory layout of the + object. + The caller does not reserve space for the register arguments; + the callee is responsible for reserving it if required. */ /* Note: Floating-point values that didn't fit into an FP register are only written to memory. */ while (len > 0) @@ -2950,15 +2960,14 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, gdb_assert (argreg > MIPS_LAST_ARG_REGNUM); /* Write this portion of the argument to the stack. */ - if (argreg > MIPS_LAST_ARG_REGNUM - || odd_sized_struct) + if (argreg > MIPS_LAST_ARG_REGNUM) { /* Should shorter than int integer values be promoted to int before being stored? */ int longword_offset = 0; CORE_ADDR addr; stack_used_p = 1; - if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) { if ((typecode == TYPE_CODE_INT || typecode == TYPE_CODE_PTR @@ -3009,7 +3018,7 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, It does not seem to be necessary to do the same for integral types. */ - if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG && partial_len < MIPS64_REGSIZE && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) @@ -3065,10 +3074,31 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - if (TYPE_CODE (type) == TYPE_CODE_STRUCT - || TYPE_CODE (type) == TYPE_CODE_UNION - || TYPE_CODE (type) == TYPE_CODE_ARRAY + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* From MIPSpro N32 ABI Handbook, Document Number: 007-2816-004 + + Function results are returned in $2 (and $3 if needed), or $f0 (and $f2 + if needed), as appropriate for the type. Composite results (struct, + union, or array) are returned in $2/$f0 and $3/$f2 according to the + following rules: + + * A struct with only one or two floating point fields is returned in $f0 + (and $f2 if necessary). This is a generalization of the Fortran COMPLEX + case. + + * Any other struct or union results of at most 128 bits are returned in + $2 (first 64 bits) and $3 (remainder, if necessary). + + * Larger composite results are handled by converting the function to a + procedure with an implicit first parameter, which is a pointer to an area + reserved by the caller to receive the result. [The o32-bit ABI requires + that all composite results be handled by conversion to implicit first + parameters. The MIPS/SGI Fortran implementation has always made a + specific exception to return COMPLEX results in the floating point + registers.] */ + + if (TYPE_CODE (type) == TYPE_CODE_ARRAY || TYPE_LENGTH (type) > 2 * MIPS64_REGSIZE) return RETURN_VALUE_STRUCT_CONVENTION; else if (TYPE_CODE (type) == TYPE_CODE_FLT @@ -3081,14 +3111,14 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return float in $f0 and $f2\n"); mips_xfer_register (regcache, - gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->fp0, - 8, gdbarch_byte_order (current_gdbarch), + gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp0, + 8, gdbarch_byte_order (gdbarch), readbuf, writebuf, 0); mips_xfer_register (regcache, - gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->fp0 + 2, - 8, gdbarch_byte_order (current_gdbarch), + gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp0 + 2, + 8, gdbarch_byte_order (gdbarch), readbuf ? readbuf + 8 : readbuf, writebuf ? writebuf + 8 : writebuf, 0); return RETURN_VALUE_REGISTER_CONVENTION; @@ -3096,15 +3126,14 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, else if (TYPE_CODE (type) == TYPE_CODE_FLT && tdep->mips_fpu_type != MIPS_FPU_NONE) { - /* A floating-point value belongs in the least significant part - of FP0. */ + /* A single or double floating-point value that fits in FP0. */ if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); mips_xfer_register (regcache, - gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->fp0, + gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp0, TYPE_LENGTH (type), - gdbarch_byte_order (current_gdbarch), + gdbarch_byte_order (gdbarch), readbuf, writebuf, 0); return RETURN_VALUE_REGISTER_CONVENTION; } @@ -3112,12 +3141,12 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, && TYPE_NFIELDS (type) <= 2 && TYPE_NFIELDS (type) >= 1 && ((TYPE_NFIELDS (type) == 1 - && (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) + && (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0))) == TYPE_CODE_FLT)) || (TYPE_NFIELDS (type) == 2 - && (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) + && (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0))) == TYPE_CODE_FLT) - && (TYPE_CODE (TYPE_FIELD_TYPE (type, 1)) + && (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 1))) == TYPE_CODE_FLT))) && tdep->mips_fpu_type != MIPS_FPU_NONE) { @@ -3126,7 +3155,7 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, register.. */ int regnum; int field; - for (field = 0, regnum = mips_regnum (current_gdbarch)->fp0; + for (field = 0, regnum = mips_regnum (gdbarch)->fp0; field < TYPE_NFIELDS (type); field++, regnum += 2) { int offset = (FIELD_BITPOS (TYPE_FIELDS (type)[field]) @@ -3134,10 +3163,10 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", offset); - mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch) + mips_xfer_register (regcache, gdbarch_num_regs (gdbarch) + regnum, TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)), - gdbarch_byte_order (current_gdbarch), + gdbarch_byte_order (gdbarch), readbuf, writebuf, offset); } return RETURN_VALUE_REGISTER_CONVENTION; @@ -3152,17 +3181,17 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, int regnum; for (offset = 0, regnum = MIPS_V0_REGNUM; offset < TYPE_LENGTH (type); - offset += register_size (current_gdbarch, regnum), regnum++) + offset += register_size (gdbarch, regnum), regnum++) { - int xfer = register_size (current_gdbarch, regnum); + int xfer = register_size (gdbarch, regnum); if (offset + xfer > TYPE_LENGTH (type)) xfer = TYPE_LENGTH (type) - offset; if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n", offset, xfer, regnum); - mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch) - + regnum, xfer, - BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset); + mips_xfer_register (regcache, gdbarch_num_regs (gdbarch) + regnum, + xfer, BFD_ENDIAN_UNKNOWN, readbuf, writebuf, + offset); } return RETURN_VALUE_REGISTER_CONVENTION; } @@ -3174,17 +3203,16 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, int regnum; for (offset = 0, regnum = MIPS_V0_REGNUM; offset < TYPE_LENGTH (type); - offset += register_size (current_gdbarch, regnum), regnum++) + offset += register_size (gdbarch, regnum), regnum++) { - int xfer = register_size (current_gdbarch, regnum); + int xfer = register_size (gdbarch, regnum); if (offset + xfer > TYPE_LENGTH (type)) xfer = TYPE_LENGTH (type) - offset; if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n", offset, xfer, regnum); - mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch) - + regnum, xfer, - gdbarch_byte_order (current_gdbarch), + mips_xfer_register (regcache, gdbarch_num_regs (gdbarch) + regnum, + xfer, gdbarch_byte_order (gdbarch), readbuf, writebuf, offset); } return RETURN_VALUE_REGISTER_CONVENTION; @@ -3245,7 +3273,7 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; - float_argreg = mips_fpa0_regnum (current_gdbarch); + float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ if (struct_return) @@ -3302,7 +3330,7 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, { if (register_size (gdbarch, float_argreg) < 8 && len == 8) { - int low_offset = gdbarch_byte_order (current_gdbarch) + int low_offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 4 : 0; unsigned long regval; @@ -3454,7 +3482,7 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, identified as such and GDB gets tweaked accordingly. */ - if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG && partial_len < MIPS32_REGSIZE && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) @@ -3502,7 +3530,7 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION @@ -3516,10 +3544,10 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type, if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); mips_xfer_register (regcache, - gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->fp0, + gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp0, TYPE_LENGTH (type), - gdbarch_byte_order (current_gdbarch), + gdbarch_byte_order (gdbarch), readbuf, writebuf, 0); return RETURN_VALUE_REGISTER_CONVENTION; } @@ -3531,30 +3559,30 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type, FP0. */ if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return float in $fp1/$fp0\n"); - switch (gdbarch_byte_order (current_gdbarch)) + switch (gdbarch_byte_order (gdbarch)) { case BFD_ENDIAN_LITTLE: mips_xfer_register (regcache, - gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->fp0 + - 0, 4, gdbarch_byte_order (current_gdbarch), + gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp0 + + 0, 4, gdbarch_byte_order (gdbarch), readbuf, writebuf, 0); mips_xfer_register (regcache, - gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->fp0 + 1, - 4, gdbarch_byte_order (current_gdbarch), + gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp0 + 1, + 4, gdbarch_byte_order (gdbarch), readbuf, writebuf, 4); break; case BFD_ENDIAN_BIG: mips_xfer_register (regcache, - gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->fp0 + 1, - 4, gdbarch_byte_order (current_gdbarch), + gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp0 + 1, + 4, gdbarch_byte_order (gdbarch), readbuf, writebuf, 0); mips_xfer_register (regcache, - gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->fp0 + 0, - 4, gdbarch_byte_order (current_gdbarch), + gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp0 + 0, + 4, gdbarch_byte_order (gdbarch), readbuf, writebuf, 4); break; default: @@ -3582,7 +3610,7 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type, gdb_byte reg[MAX_REGISTER_SIZE]; int regnum; int field; - for (field = 0, regnum = mips_regnum (current_gdbarch)->fp0; + for (field = 0, regnum = mips_regnum (gdbarch)->fp0; field < TYPE_NFIELDS (type); field++, regnum += 2) { int offset = (FIELD_BITPOS (TYPE_FIELDS (type)[field]) @@ -3590,10 +3618,10 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type, if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", offset); - mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch) + mips_xfer_register (regcache, gdbarch_num_regs (gdbarch) + regnum, TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)), - gdbarch_byte_order (current_gdbarch), + gdbarch_byte_order (gdbarch), readbuf, writebuf, offset); } return RETURN_VALUE_REGISTER_CONVENTION; @@ -3610,15 +3638,15 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type, int regnum; for (offset = 0, regnum = MIPS_V0_REGNUM; offset < TYPE_LENGTH (type); - offset += register_size (current_gdbarch, regnum), regnum++) + offset += register_size (gdbarch, regnum), regnum++) { - int xfer = register_size (current_gdbarch, regnum); + int xfer = register_size (gdbarch, regnum); if (offset + xfer > TYPE_LENGTH (type)) xfer = TYPE_LENGTH (type) - offset; if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n", offset, xfer, regnum); - mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch) + mips_xfer_register (regcache, gdbarch_num_regs (gdbarch) + regnum, xfer, BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset); } @@ -3642,9 +3670,9 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type, if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n", offset, xfer, regnum); - mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch) + mips_xfer_register (regcache, gdbarch_num_regs (gdbarch) + regnum, xfer, - gdbarch_byte_order (current_gdbarch), + gdbarch_byte_order (gdbarch), readbuf, writebuf, offset); } return RETURN_VALUE_REGISTER_CONVENTION; @@ -3704,7 +3732,7 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; - float_argreg = mips_fpa0_regnum (current_gdbarch); + float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ if (struct_return) @@ -3791,7 +3819,7 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int longword_offset = 0; CORE_ADDR addr; stack_used_p = 1; - if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) { if ((typecode == TYPE_CODE_INT || typecode == TYPE_CODE_PTR @@ -3843,7 +3871,7 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, It does not seem to be necessary to do the same for integral types. */ - if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG && partial_len < MIPS64_REGSIZE && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) @@ -3891,7 +3919,7 @@ mips_o64_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION @@ -3904,10 +3932,10 @@ mips_o64_return_value (struct gdbarch *gdbarch, if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); mips_xfer_register (regcache, - gdbarch_num_regs (current_gdbarch) - + mips_regnum (current_gdbarch)->fp0, + gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp0, TYPE_LENGTH (type), - gdbarch_byte_order (current_gdbarch), + gdbarch_byte_order (gdbarch), readbuf, writebuf, 0); return RETURN_VALUE_REGISTER_CONVENTION; } @@ -3927,9 +3955,8 @@ mips_o64_return_value (struct gdbarch *gdbarch, if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n", offset, xfer, regnum); - mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch) - + regnum, xfer, - gdbarch_byte_order (current_gdbarch), + mips_xfer_register (regcache, gdbarch_num_regs (gdbarch) + regnum, + xfer, gdbarch_byte_order (gdbarch), readbuf, writebuf, offset); } return RETURN_VALUE_REGISTER_CONVENTION; @@ -3985,19 +4012,20 @@ static void mips_read_fp_register_single (struct frame_info *frame, int regno, gdb_byte *rare_buffer) { - int raw_size = register_size (current_gdbarch, regno); + struct gdbarch *gdbarch = get_frame_arch (frame); + int raw_size = register_size (gdbarch, regno); gdb_byte *raw_buffer = alloca (raw_size); if (!frame_register_read (frame, regno, raw_buffer)) error (_("can't read register %d (%s)"), - regno, gdbarch_register_name (current_gdbarch, regno)); + regno, gdbarch_register_name (gdbarch, regno)); if (raw_size == 8) { /* We have a 64-bit value for this register. Find the low-order 32 bits. */ int offset; - if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) offset = 4; else offset = 0; @@ -4018,7 +4046,8 @@ static void mips_read_fp_register_double (struct frame_info *frame, int regno, gdb_byte *rare_buffer) { - int raw_size = register_size (current_gdbarch, regno); + struct gdbarch *gdbarch = get_frame_arch (frame); + int raw_size = register_size (gdbarch, regno); if (raw_size == 8 && !mips2_fp_compat (frame)) { @@ -4026,18 +4055,20 @@ mips_read_fp_register_double (struct frame_info *frame, int regno, all 64 bits. */ if (!frame_register_read (frame, regno, rare_buffer)) error (_("can't read register %d (%s)"), - regno, gdbarch_register_name (current_gdbarch, regno)); + regno, gdbarch_register_name (gdbarch, regno)); } else { - if ((regno - mips_regnum (current_gdbarch)->fp0) & 1) + int rawnum = regno % gdbarch_num_regs (gdbarch); + + if ((rawnum - mips_regnum (gdbarch)->fp0) & 1) internal_error (__FILE__, __LINE__, _("mips_read_fp_register_double: bad access to " "odd-numbered FP register")); /* mips_read_fp_register_single will find the correct 32 bits from each register. */ - if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) { mips_read_fp_register_single (frame, regno, rare_buffer + 4); mips_read_fp_register_single (frame, regno + 1, rare_buffer); @@ -4054,21 +4085,19 @@ static void mips_print_fp_register (struct ui_file *file, struct frame_info *frame, int regnum) { /* do values for FP (float) regs */ + struct gdbarch *gdbarch = get_frame_arch (frame); gdb_byte *raw_buffer; double doub, flt1; /* doubles extracted from raw hex data */ int inv1, inv2; - raw_buffer = alloca (2 * register_size (current_gdbarch, - mips_regnum (current_gdbarch)->fp0)); + raw_buffer = alloca (2 * register_size (gdbarch, mips_regnum (gdbarch)->fp0)); - fprintf_filtered (file, "%s:", - gdbarch_register_name (current_gdbarch, regnum)); + fprintf_filtered (file, "%s:", gdbarch_register_name (gdbarch, regnum)); fprintf_filtered (file, "%*s", - 4 - (int) strlen (gdbarch_register_name - (current_gdbarch, regnum)), + 4 - (int) strlen (gdbarch_register_name (gdbarch, regnum)), ""); - if (register_size (current_gdbarch, regnum) == 4 || mips2_fp_compat (frame)) + if (register_size (gdbarch, regnum) == 4 || mips2_fp_compat (frame)) { /* 4-byte registers: Print hex and floating. Also print even numbered registers as doubles. */ @@ -4084,7 +4113,7 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame, else fprintf_filtered (file, "%-17.9g", flt1); - if (regnum % 2 == 0) + if ((regnum - gdbarch_num_regs (gdbarch)) % 2 == 0) { mips_read_fp_register_double (frame, regnum, raw_buffer); doub = unpack_double (mips_double_register_type (), raw_buffer, @@ -4142,11 +4171,11 @@ mips_print_register (struct ui_file *file, struct frame_info *frame, if (!frame_register_read (frame, regnum, raw_buffer)) { fprintf_filtered (file, "%s: [Invalid]", - gdbarch_register_name (current_gdbarch, regnum)); + gdbarch_register_name (gdbarch, regnum)); return; } - fputs_filtered (gdbarch_register_name (current_gdbarch, regnum), file); + fputs_filtered (gdbarch_register_name (gdbarch, regnum), file); /* The problem with printing numeric register names (r26, etc.) is that the user can't use them on input. Probably the best solution is to @@ -4157,10 +4186,9 @@ mips_print_register (struct ui_file *file, struct frame_info *frame, else fprintf_filtered (file, ": "); - if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) offset = - register_size (current_gdbarch, - regnum) - register_size (current_gdbarch, regnum); + register_size (gdbarch, regnum) - register_size (gdbarch, regnum); else offset = 0; @@ -4198,18 +4226,17 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame, /* For GP registers, we print a separate row of names above the vals */ for (col = 0, regnum = start_regnum; - col < ncols && regnum < gdbarch_num_regs (current_gdbarch) - + gdbarch_num_pseudo_regs (current_gdbarch); + col < ncols && regnum < gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch); regnum++) { - if (*gdbarch_register_name (current_gdbarch, regnum) == '\0') + if (*gdbarch_register_name (gdbarch, regnum) == '\0') continue; /* unused register */ if (TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT) break; /* end the row: reached FP register */ /* Large registers are handled separately. */ - if (register_size (current_gdbarch, regnum) - > mips_abi_regsize (current_gdbarch)) + if (register_size (gdbarch, regnum) > mips_abi_regsize (gdbarch)) { if (col > 0) break; /* End the row before this register. */ @@ -4222,8 +4249,8 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame, if (col == 0) fprintf_filtered (file, " "); fprintf_filtered (file, - mips_abi_regsize (current_gdbarch) == 8 ? "%17s" : "%9s", - gdbarch_register_name (current_gdbarch, regnum)); + mips_abi_regsize (gdbarch) == 8 ? "%17s" : "%9s", + gdbarch_register_name (gdbarch, regnum)); col++; } @@ -4231,45 +4258,43 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame, return regnum; /* print the R0 to R31 names */ - if ((start_regnum % gdbarch_num_regs (current_gdbarch)) < MIPS_NUMREGS) + if ((start_regnum % gdbarch_num_regs (gdbarch)) < MIPS_NUMREGS) fprintf_filtered (file, "\n R%-4d", - start_regnum % gdbarch_num_regs (current_gdbarch)); + start_regnum % gdbarch_num_regs (gdbarch)); else fprintf_filtered (file, "\n "); /* now print the values in hex, 4 or 8 to the row */ for (col = 0, regnum = start_regnum; - col < ncols && regnum < gdbarch_num_regs (current_gdbarch) - + gdbarch_num_pseudo_regs (current_gdbarch); + col < ncols && regnum < gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch); regnum++) { - if (*gdbarch_register_name (current_gdbarch, regnum) == '\0') + if (*gdbarch_register_name (gdbarch, regnum) == '\0') continue; /* unused register */ if (TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT) break; /* end row: reached FP register */ - if (register_size (current_gdbarch, regnum) - > mips_abi_regsize (current_gdbarch)) + if (register_size (gdbarch, regnum) > mips_abi_regsize (gdbarch)) break; /* End row: large register. */ /* OK: get the data in raw format. */ if (!frame_register_read (frame, regnum, raw_buffer)) error (_("can't read register %d (%s)"), - regnum, gdbarch_register_name (current_gdbarch, regnum)); + regnum, gdbarch_register_name (gdbarch, regnum)); /* pad small registers */ for (byte = 0; - byte < (mips_abi_regsize (current_gdbarch) - - register_size (current_gdbarch, regnum)); byte++) + byte < (mips_abi_regsize (gdbarch) + - register_size (gdbarch, regnum)); byte++) printf_filtered (" "); /* Now print the register value in hex, endian order. */ - if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) for (byte = - register_size (current_gdbarch, - regnum) - register_size (current_gdbarch, regnum); - byte < register_size (current_gdbarch, regnum); byte++) + register_size (gdbarch, regnum) - register_size (gdbarch, regnum); + byte < register_size (gdbarch, regnum); byte++) fprintf_filtered (file, "%02x", raw_buffer[byte]); else - for (byte = register_size (current_gdbarch, regnum) - 1; + for (byte = register_size (gdbarch, regnum) - 1; byte >= 0; byte--) fprintf_filtered (file, "%02x", raw_buffer[byte]); fprintf_filtered (file, " "); @@ -4289,8 +4314,8 @@ mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, { if (regnum != -1) /* do one specified register */ { - gdb_assert (regnum >= gdbarch_num_regs (current_gdbarch)); - if (*(gdbarch_register_name (current_gdbarch, regnum)) == '\0') + gdb_assert (regnum >= gdbarch_num_regs (gdbarch)); + if (*(gdbarch_register_name (gdbarch, regnum)) == '\0') error (_("Not a valid register for the current processor type")); mips_print_register (file, frame, regnum); @@ -4299,9 +4324,9 @@ mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, else /* do all (or most) registers */ { - regnum = gdbarch_num_regs (current_gdbarch); - while (regnum < gdbarch_num_regs (current_gdbarch) - + gdbarch_num_pseudo_regs (current_gdbarch)) + regnum = gdbarch_num_regs (gdbarch); + while (regnum < gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch)) { if (TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT) @@ -4395,6 +4420,95 @@ mips_skip_prologue (CORE_ADDR pc) return mips32_scan_prologue (pc, limit_pc, NULL, NULL); } +/* Check whether the PC is in a function epilogue (32-bit version). + This is a helper function for mips_in_function_epilogue_p. */ +static int +mips32_in_function_epilogue_p (CORE_ADDR pc) +{ + CORE_ADDR func_addr = 0, func_end = 0; + + if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) + { + /* The MIPS epilogue is max. 12 bytes long. */ + CORE_ADDR addr = func_end - 12; + + if (addr < func_addr + 4) + addr = func_addr + 4; + if (pc < addr) + return 0; + + for (; pc < func_end; pc += MIPS_INSN32_SIZE) + { + unsigned long high_word; + unsigned long inst; + + inst = mips_fetch_instruction (pc); + high_word = (inst >> 16) & 0xffff; + + if (high_word != 0x27bd /* addiu $sp,$sp,offset */ + && high_word != 0x67bd /* daddiu $sp,$sp,offset */ + && inst != 0x03e00008 /* jr $ra */ + && inst != 0x00000000) /* nop */ + return 0; + } + + return 1; + } + + return 0; +} + +/* Check whether the PC is in a function epilogue (16-bit version). + This is a helper function for mips_in_function_epilogue_p. */ +static int +mips16_in_function_epilogue_p (CORE_ADDR pc) +{ + CORE_ADDR func_addr = 0, func_end = 0; + + if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) + { + /* The MIPS epilogue is max. 12 bytes long. */ + CORE_ADDR addr = func_end - 12; + + if (addr < func_addr + 4) + addr = func_addr + 4; + if (pc < addr) + return 0; + + for (; pc < func_end; pc += MIPS_INSN16_SIZE) + { + unsigned short inst; + + inst = mips_fetch_instruction (pc); + + if ((inst & 0xf800) == 0xf000) /* extend */ + continue; + + if (inst != 0x6300 /* addiu $sp,offset */ + && inst != 0xfb00 /* daddiu $sp,$sp,offset */ + && inst != 0xe820 /* jr $ra */ + && inst != 0xe8a0 /* jrc $ra */ + && inst != 0x6500) /* nop */ + return 0; + } + + return 1; + } + + return 0; +} + +/* The epilogue is defined here as the area at the end of a function, + after an instruction which destroys the function's stack frame. */ +static int +mips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + if (mips_pc_is_mips16 (pc)) + return mips16_in_function_epilogue_p (pc); + else + return mips32_in_function_epilogue_p (pc); +} + /* Root of all "set mips "/"show mips " commands. This will eventually be used for all MIPS-specific commands. */ @@ -4809,6 +4923,18 @@ mips_integer_to_address (struct gdbarch *gdbarch, return (CORE_ADDR) extract_signed_integer (buf, TYPE_LENGTH (type)); } +/* Dummy virtual frame pointer method. This is no more or less accurate + than most other architectures; we just need to be explicit about it, + because the pseudo-register gdbarch_sp_regnum will otherwise lead to + an assertion failure. */ + +static void +mips_virtual_frame_pointer (CORE_ADDR pc, int *reg, LONGEST *offset) +{ + *reg = MIPS_SP_REGNUM; + *offset = 0; +} + static void mips_find_abi_section (bfd *abfd, asection *sect, void *obj) { @@ -4866,30 +4992,16 @@ global_mips_abi (void) static void mips_register_g_packet_guesses (struct gdbarch *gdbarch) { - static struct target_desc *tdesc_gp32, *tdesc_gp64; - - if (tdesc_gp32 == NULL) - { - /* Create feature sets with the appropriate properties. The values - are not important. */ - - tdesc_gp32 = allocate_target_description (); - set_tdesc_property (tdesc_gp32, PROPERTY_GP32, ""); - - tdesc_gp64 = allocate_target_description (); - set_tdesc_property (tdesc_gp64, PROPERTY_GP64, ""); - } - /* If the size matches the set of 32-bit or 64-bit integer registers, assume that's what we've got. */ - register_remote_g_packet_guess (gdbarch, 38 * 4, tdesc_gp32); - register_remote_g_packet_guess (gdbarch, 38 * 8, tdesc_gp64); + register_remote_g_packet_guess (gdbarch, 38 * 4, mips_tdesc_gp32); + register_remote_g_packet_guess (gdbarch, 38 * 8, mips_tdesc_gp64); /* If the size matches the full set of registers GDB traditionally knows about, including floating point, for either 32-bit or 64-bit, assume that's what we've got. */ - register_remote_g_packet_guess (gdbarch, 90 * 4, tdesc_gp32); - register_remote_g_packet_guess (gdbarch, 90 * 8, tdesc_gp64); + register_remote_g_packet_guess (gdbarch, 90 * 4, mips_tdesc_gp32); + register_remote_g_packet_guess (gdbarch, 90 * 8, mips_tdesc_gp64); /* Otherwise we don't have a useful guess. */ } @@ -5304,6 +5416,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_num_regs (gdbarch, num_regs); set_gdbarch_num_pseudo_regs (gdbarch, num_regs); set_gdbarch_register_name (gdbarch, mips_register_name); + set_gdbarch_virtual_frame_pointer (gdbarch, mips_virtual_frame_pointer); tdep->mips_processor_reg_names = reg_names; tdep->regnum = regnum; } @@ -5490,6 +5603,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue); + set_gdbarch_in_function_epilogue_p (gdbarch, mips_in_function_epilogue_p); + set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address); set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer); set_gdbarch_integer_to_address (gdbarch, mips_integer_to_address); @@ -5617,9 +5732,9 @@ show_mips_abi (struct ui_file *file, } static void -mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) +mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (tdep != NULL) { int ef_mips_arch; @@ -5696,6 +5811,14 @@ _initialize_mips_tdep (void) mips_pdr_data = register_objfile_data (); + /* Create feature sets with the appropriate properties. The values + are not important. */ + mips_tdesc_gp32 = allocate_target_description (); + set_tdesc_property (mips_tdesc_gp32, PROPERTY_GP32, ""); + + mips_tdesc_gp64 = allocate_target_description (); + set_tdesc_property (mips_tdesc_gp64, PROPERTY_GP64, ""); + /* Add root prefix command for all "set mips"/"show mips" commands */ add_prefix_cmd ("mips", no_class, set_mips_command, _("Various MIPS specific commands."),