X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fmips-tdep.c;h=c0d8b08127c450fe138ff925bfd8341ba2e92604;hb=7be0c536371055e9b15403d88f6149bbd656df37;hp=2f24ec0d875e622d5094465ea908a0321a321dd1;hpb=4be87837a23001df36ca5a4171eb01dec22856e1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 2f24ec0d87..c0d8b08127 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -25,6 +25,7 @@ #include "defs.h" #include "gdb_string.h" +#include "gdb_assert.h" #include "frame.h" #include "inferior.h" #include "symtab.h" @@ -40,11 +41,17 @@ #include "regcache.h" #include "osabi.h" #include "mips-tdep.h" - +#include "block.h" +#include "reggroups.h" #include "opcode/mips.h" #include "elf/mips.h" #include "elf-bfd.h" #include "symcat.h" +#include "sim-regno.h" +#include "dis-asm.h" + +static void set_reg_offset (CORE_ADDR *saved_regs, int regnum, CORE_ADDR off); +static struct type *mips_register_type (struct gdbarch *gdbarch, int regnum); /* A useful bit in the CP0 status register (PS_REGNUM). */ /* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip. */ @@ -148,6 +155,57 @@ static const char *mips_saved_regsize_string = size_auto; #define MIPS_SAVED_REGSIZE (mips_saved_regsize()) +/* MIPS16 function addresses are odd (bit 0 is set). Here are some + functions to test, set, or clear bit 0 of addresses. */ + +static CORE_ADDR +is_mips16_addr (CORE_ADDR addr) +{ + return ((addr) & 1); +} + +static CORE_ADDR +make_mips16_addr (CORE_ADDR addr) +{ + return ((addr) | 1); +} + +static CORE_ADDR +unmake_mips16_addr (CORE_ADDR addr) +{ + return ((addr) & ~1); +} + +/* Return the contents of register REGNUM as a signed integer. */ + +static LONGEST +read_signed_register (int regnum) +{ + void *buf = alloca (DEPRECATED_REGISTER_RAW_SIZE (regnum)); + deprecated_read_register_gen (regnum, buf); + return (extract_signed_integer (buf, DEPRECATED_REGISTER_RAW_SIZE (regnum))); +} + +static LONGEST +read_signed_register_pid (int regnum, ptid_t ptid) +{ + ptid_t save_ptid; + LONGEST retval; + + if (ptid_equal (ptid, inferior_ptid)) + return read_signed_register (regnum); + + save_ptid = inferior_ptid; + + inferior_ptid = ptid; + + retval = read_signed_register (regnum); + + inferior_ptid = save_ptid; + + return retval; +} + /* Return the MIPS ABI associated with GDBARCH. */ enum mips_abi mips_abi (struct gdbarch *gdbarch) @@ -213,14 +271,15 @@ mips_xfer_register (struct regcache *regcache, int reg_num, int length, enum bfd_endian endian, bfd_byte *in, const bfd_byte *out, int buf_offset) { - bfd_byte *reg = alloca (MAX_REGISTER_RAW_SIZE); + bfd_byte reg[MAX_REGISTER_SIZE]; int reg_offset = 0; + gdb_assert (reg_num >= NUM_REGS); /* 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_RAW_SIZE (reg_num) - length; + reg_offset = DEPRECATED_REGISTER_RAW_SIZE (reg_num) - length; break; case BFD_ENDIAN_LITTLE: reg_offset = 0; @@ -243,9 +302,9 @@ mips_xfer_register (struct regcache *regcache, int reg_num, int length, fprintf_unfiltered (gdb_stdlog, "%02x", out[buf_offset + i]); } if (in != NULL) - regcache_raw_read_part (regcache, reg_num, reg_offset, length, in + buf_offset); + regcache_cooked_read_part (regcache, reg_num, reg_offset, length, in + buf_offset); if (out != NULL) - regcache_raw_write_part (regcache, reg_num, reg_offset, length, out + buf_offset); + regcache_cooked_write_part (regcache, reg_num, reg_offset, length, out + buf_offset); if (mips_debug && in != NULL) { int i; @@ -266,7 +325,7 @@ mips2_fp_compat (void) { /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not meaningful. */ - if (REGISTER_RAW_SIZE (FP0_REGNUM) == 4) + if (DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM) == 4) return 0; #if 0 @@ -316,12 +375,8 @@ mips_stack_argsize (void) #define VM_MIN_ADDRESS (CORE_ADDR)0x400000 -int gdb_print_insn_mips (bfd_vma, disassemble_info *); - -static void mips_print_register (int, int); - -static mips_extra_func_info_t -heuristic_proc_desc (CORE_ADDR, CORE_ADDR, struct frame_info *, int); +static mips_extra_func_info_t heuristic_proc_desc (CORE_ADDR, CORE_ADDR, + struct frame_info *, int); static CORE_ADDR heuristic_proc_start (CORE_ADDR); @@ -333,15 +388,13 @@ static void mips_show_processor_type_command (char *, int); static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *); -static mips_extra_func_info_t -find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame); +static mips_extra_func_info_t find_proc_desc (CORE_ADDR pc, + struct frame_info *next_frame, + int cur_frame); static CORE_ADDR after_prologue (CORE_ADDR pc, mips_extra_func_info_t proc_desc); -static void mips_read_fp_register_single (int regno, char *rare_buffer); -static void mips_read_fp_register_double (int regno, char *rare_buffer); - static struct type *mips_float_register_type (void); static struct type *mips_double_register_type (void); @@ -359,23 +412,63 @@ static struct cmd_list_element *showmipscmdlist = NULL; /* A set of original names, to be used when restoring back to generic registers from a specific set. */ +static char *mips_generic_reg_names[] = MIPS_REGISTER_NAMES; -char *mips_generic_reg_names[] = MIPS_REGISTER_NAMES; -char **mips_processor_reg_names = mips_generic_reg_names; +/* Integer registers 0 thru 31 are handled explicitly by + mips_register_name(). Processor specific registers 32 and above + are listed in the sets of register names assigned to + mips_processor_reg_names. */ +static char **mips_processor_reg_names = mips_generic_reg_names; +/* Return the name of the register corresponding to REGNO. */ static const char * -mips_register_name (int i) -{ - return mips_processor_reg_names[i]; +mips_register_name (int regno) +{ + /* GPR names for all ABIs other than n32/n64. */ + static char *mips_gpr_names[] = { + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", + }; + + /* GPR names for n32 and n64 ABIs. */ + static char *mips_n32_n64_gpr_names[] = { + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" + }; + + enum mips_abi abi = mips_abi (current_gdbarch); + + /* Map [NUM_REGS .. 2*NUM_REGS) onto the raw registers, but then + don't make the raw register names visible. */ + int rawnum = regno % NUM_REGS; + if (regno < NUM_REGS) + return ""; + + /* The MIPS integer registers are always mapped from 0 to 31. The + names of the registers (which reflects the conventions regarding + register use) vary depending on the ABI. */ + if (0 <= rawnum && rawnum < 32) + { + if (abi == MIPS_ABI_N32 || abi == MIPS_ABI_N64) + return mips_n32_n64_gpr_names[rawnum]; + else + return mips_gpr_names[rawnum]; + } + else if (32 <= rawnum && rawnum < NUM_REGS) + return mips_processor_reg_names[rawnum - 32]; + else + internal_error (__FILE__, __LINE__, + "mips_register_name: bad register number %d", rawnum); } + /* *INDENT-OFF* */ /* Names of IDT R3041 registers. */ char *mips_r3041_reg_names[] = { - "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", "sr", "lo", "hi", "bad", "cause","pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", @@ -389,10 +482,6 @@ char *mips_r3041_reg_names[] = { /* Names of IDT R3051 registers. */ char *mips_r3051_reg_names[] = { - "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", "sr", "lo", "hi", "bad", "cause","pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", @@ -406,10 +495,6 @@ char *mips_r3051_reg_names[] = { /* Names of IDT R3081 registers. */ char *mips_r3081_reg_names[] = { - "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", "sr", "lo", "hi", "bad", "cause","pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", @@ -423,10 +508,6 @@ char *mips_r3081_reg_names[] = { /* Names of LSI 33k registers. */ char *mips_lsi33k_reg_names[] = { - "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", "epc", "hi", "lo", "sr", "cause","badvaddr", "dcic", "bpc", "bda", "", "", "", "", "", "", "", "", "", "", "", "", "", @@ -451,8 +532,63 @@ struct { }; /* *INDENT-ON* */ +/* Return the groups that a MIPS register can be categorised into. */ +static int +mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *reggroup) +{ + int vector_p; + int float_p; + int raw_p; + int rawnum = regnum % NUM_REGS; + int pseudo = regnum / NUM_REGS; + 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 < NUM_REGS; + if (REGISTER_NAME (regnum) == NULL + || REGISTER_NAME (regnum)[0] == '\0') + return 0; + if (reggroup == float_reggroup) + return float_p && pseudo; + if (reggroup == vector_reggroup) + return vector_p && pseudo; + if (reggroup == general_reggroup) + return (!vector_p && !float_p) && pseudo; + /* Save the pseudo registers. Need to make certain that any code + extracting register values from a saved register cache also uses + pseudo registers. */ + if (reggroup == save_reggroup) + return raw_p && pseudo; + /* Restore the same pseudo register. */ + if (reggroup == restore_reggroup) + return raw_p && pseudo; + return 0; +} + +/* Map the symbol table registers which live in the range [1 * + NUM_REGS .. 2 * NUM_REGS) back onto the corresponding raw + registers. */ +static void +mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + int cookednum, void *buf) +{ + gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS); + return regcache_raw_read (regcache, cookednum % NUM_REGS, buf); +} + +static void +mips_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int cookednum, const void *buf) +{ + gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS); + return regcache_raw_write (regcache, cookednum % NUM_REGS, buf); +} /* Table to translate MIPS16 register field to actual register number. */ static int mips16_to_32_reg[8] = @@ -488,36 +624,76 @@ struct linked_proc_info } *linked_proc_desc_table = NULL; -void -mips_print_extra_frame_info (struct frame_info *fi) -{ - if (fi - && fi->extra_info - && fi->extra_info->proc_desc - && fi->extra_info->proc_desc->pdr.framereg < NUM_REGS) - printf_filtered (" frame pointer is at %s+%s\n", - REGISTER_NAME (fi->extra_info->proc_desc->pdr.framereg), - paddr_d (fi->extra_info->proc_desc->pdr.frameoffset)); -} - /* Number of bytes of storage in the actual machine representation for register N. NOTE: This indirectly defines the register size - transfered by the GDB protocol. */ + transfered by the GDB protocol. */ static int mips64_transfers_32bit_regs_p = 0; static int -mips_register_raw_size (int reg_nr) +mips_register_raw_size (int regnum) { - if (mips64_transfers_32bit_regs_p) - return REGISTER_VIRTUAL_SIZE (reg_nr); - else if (reg_nr >= FP0_REGNUM && reg_nr < FP0_REGNUM + 32 - && FP_REGISTER_DOUBLE) - /* For MIPS_ABI_N32 (for example) we need 8 byte floating point - registers. */ - return 8; + gdb_assert (regnum >= 0); + if (regnum < NUM_REGS) + { + /* For compatibility with old code, implemnt the broken register raw + size map for the raw registers. + + NOTE: cagney/2003-06-15: This is so bogus. The register's + raw size is changing according to the ABI + (FP_REGISTER_DOUBLE). Also, GDB's protocol is defined by a + combination of DEPRECATED_REGISTER_RAW_SIZE and DEPRECATED_REGISTER_BYTE. */ + if (mips64_transfers_32bit_regs_p) + return DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum); + else if (regnum >= FP0_REGNUM && regnum < FP0_REGNUM + 32 + && FP_REGISTER_DOUBLE) + /* For MIPS_ABI_N32 (for example) we need 8 byte floating point + registers. */ + return 8; + else + return MIPS_REGSIZE; + } + else if (regnum < 2 * NUM_REGS) + { + /* For the moment map [NUM_REGS .. 2*NUM_REGS) onto the same raw + registers, but always return the virtual size. */ + int rawnum = regnum % NUM_REGS; + return TYPE_LENGTH (gdbarch_register_type (current_gdbarch, rawnum)); + } + else + internal_error (__FILE__, __LINE__, "Register %d out of range", regnum); +} + +/* Register offset in a buffer for each register. + + FIXME: cagney/2003-06-15: This is so bogus. Instead REGISTER_TYPE + should strictly return the layout of the buffer. Unfortunately + remote.c and the MIPS have come to rely on a custom layout that + doesn't 1:1 map onto the register type. */ + +static int +mips_register_byte (int regnum) +{ + gdb_assert (regnum >= 0); + if (regnum < NUM_REGS) + /* Pick up the relevant per-tm file register byte method. */ + return MIPS_REGISTER_BYTE (regnum); + else if (regnum < 2 * NUM_REGS) + { + int reg; + int byte; + /* Start with the end of the raw register buffer - assum that + MIPS_REGISTER_BYTE (NUM_REGS) returns that end. */ + byte = MIPS_REGISTER_BYTE (NUM_REGS); + /* Add space for all the proceeding registers based on their + real size. */ + for (reg = NUM_REGS; reg < regnum; reg++) + byte += TYPE_LENGTH (gdbarch_register_type (current_gdbarch, + (reg % NUM_REGS))); + return byte; + } else - return MIPS_REGSIZE; + internal_error (__FILE__, __LINE__, "Register %d out of range", regnum); } /* Convert between RAW and VIRTUAL registers. The RAW register size @@ -529,7 +705,7 @@ mips_register_convertible (int reg_nr) if (mips64_transfers_32bit_regs_p) return 0; else - return (REGISTER_RAW_SIZE (reg_nr) > REGISTER_VIRTUAL_SIZE (reg_nr)); + return (DEPRECATED_REGISTER_RAW_SIZE (reg_nr) > DEPRECATED_REGISTER_VIRTUAL_SIZE (reg_nr)); } static void @@ -538,7 +714,7 @@ mips_register_convert_to_virtual (int n, struct type *virtual_type, { if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) memcpy (virt_buf, - raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)), + raw_buf + (DEPRECATED_REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)), TYPE_LENGTH (virtual_type)); else memcpy (virt_buf, @@ -548,11 +724,11 @@ mips_register_convert_to_virtual (int n, struct type *virtual_type, static void mips_register_convert_to_raw (struct type *virtual_type, int n, - char *virt_buf, char *raw_buf) + const char *virt_buf, char *raw_buf) { - memset (raw_buf, 0, REGISTER_RAW_SIZE (n)); + memset (raw_buf, 0, DEPRECATED_REGISTER_RAW_SIZE (n)); if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - memcpy (raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)), + memcpy (raw_buf + (DEPRECATED_REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)), virt_buf, TYPE_LENGTH (virtual_type)); else @@ -561,52 +737,46 @@ mips_register_convert_to_raw (struct type *virtual_type, int n, TYPE_LENGTH (virtual_type)); } -void -mips_register_convert_to_type (int regnum, struct type *type, char *buffer) +static int +mips_convert_register_p (int regnum, struct type *type) { - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG - && REGISTER_RAW_SIZE (regnum) == 4 - && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32 - && TYPE_CODE(type) == TYPE_CODE_FLT - && TYPE_LENGTH(type) == 8) - { - char temp[4]; - memcpy (temp, ((char *)(buffer))+4, 4); - memcpy (((char *)(buffer))+4, (buffer), 4); - memcpy (((char *)(buffer)), temp, 4); - } + return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + && DEPRECATED_REGISTER_RAW_SIZE (regnum) == 4 + && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32 + && TYPE_CODE(type) == TYPE_CODE_FLT + && TYPE_LENGTH(type) == 8); } -void -mips_register_convert_from_type (int regnum, struct type *type, char *buffer) +static void +mips_register_to_value (struct frame_info *frame, int regnum, + struct type *type, void *to) { -if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG - && REGISTER_RAW_SIZE (regnum) == 4 - && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32 - && TYPE_CODE(type) == TYPE_CODE_FLT - && TYPE_LENGTH(type) == 8) - { - char temp[4]; - memcpy (temp, ((char *)(buffer))+4, 4); - memcpy (((char *)(buffer))+4, (buffer), 4); - memcpy (((char *)(buffer)), temp, 4); - } + get_frame_register (frame, regnum + 0, (char *) to + 4); + get_frame_register (frame, regnum + 1, (char *) to + 0); +} + +static void +mips_value_to_register (struct frame_info *frame, int regnum, + struct type *type, const void *from) +{ + put_frame_register (frame, regnum + 0, (const char *) from + 4); + put_frame_register (frame, regnum + 1, (const char *) from + 0); } -/* Return the GDB type object for the "standard" data type - of data in register REG. - - Note: kevinb/2002-08-01: The definition below should faithfully - reproduce the behavior of each of the REGISTER_VIRTUAL_TYPE - definitions found in config/mips/tm-*.h. I'm concerned about - the ``FCRCS_REGNUM <= reg && reg <= LAST_EMBED_REGNUM'' clause - though. In some cases FP_REGNUM is in this range, and I doubt - that this code is correct for the 64-bit case. */ +/* Return the GDB type object for the "standard" data type of data in + register REG. */ static struct type * -mips_register_virtual_type (int reg) -{ - if (FP0_REGNUM <= reg && reg < FP0_REGNUM + 32) +mips_register_type (struct gdbarch *gdbarch, int regnum) +{ + /* For moment, map [NUM_REGS .. 2*NUM_REGS) onto the same raw + registers. Even return the same type. */ + int rawnum = regnum % NUM_REGS; + gdb_assert (rawnum >= 0 && rawnum < NUM_REGS); +#ifdef MIPS_REGISTER_TYPE + return MIPS_REGISTER_TYPE (rawnum); +#else + if (FP0_REGNUM <= rawnum && rawnum < FP0_REGNUM + 32) { /* Floating point registers... */ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) @@ -614,9 +784,9 @@ mips_register_virtual_type (int reg) else return builtin_type_ieee_double_little; } - else if (reg == PS_REGNUM /* CR */) + else if (rawnum == PS_REGNUM /* CR */) return builtin_type_uint32; - else if (FCRCS_REGNUM <= reg && reg <= LAST_EMBED_REGNUM) + else if (FCRCS_REGNUM <= rawnum && rawnum <= LAST_EMBED_REGNUM) return builtin_type_uint32; else { @@ -627,6 +797,7 @@ mips_register_virtual_type (int reg) else return builtin_type_uint32; } +#endif } /* TARGET_READ_SP -- Remove useless bits from the stack pointer. */ @@ -634,7 +805,7 @@ mips_register_virtual_type (int reg) static CORE_ADDR mips_read_sp (void) { - return ADDR_BITS_REMOVE (read_register (SP_REGNUM)); + return read_signed_register (SP_REGNUM); } /* Should the upper word of 64-bit addresses be zeroed? */ @@ -695,12 +866,6 @@ mips_n32n64_use_struct_convention (int gcc_p, struct type *type) return (TYPE_LENGTH (type) > 2 * MIPS_SAVED_REGSIZE); } -static int -mips_o32_use_struct_convention (int gcc_p, struct type *type) -{ - return 1; /* Structures are returned by ref in extra arg0. */ -} - /* Should call_function pass struct by reference? For each architecture, structs are passed either by value or by reference, depending on their size. */ @@ -737,7 +902,7 @@ pc_is_mips16 (bfd_vma memaddr) struct minimal_symbol *sym; /* If bit 0 of the address is set, assume this is a MIPS16 address. */ - if (IS_MIPS16_ADDR (memaddr)) + if (is_mips16_addr (memaddr)) return 1; /* A flag indicating that this is a MIPS16 function is stored by elfread.c in @@ -870,7 +1035,7 @@ mips_fetch_instruction (CORE_ADDR addr) if (pc_is_mips16 (addr)) { instlen = MIPS16_INSTLEN; - addr = UNMAKE_MIPS16_ADDR (addr); + addr = unmake_mips16_addr (addr); } else instlen = MIPS_INSTLEN; @@ -1373,38 +1538,37 @@ mips_next_pc (CORE_ADDR pc) return mips32_next_pc (pc); } -/* Guaranteed to set fci->saved_regs to some values (it never leaves it - NULL). - - Note: kevinb/2002-08-09: The only caller of this function is (and - should remain) mips_frame_init_saved_regs(). In fact, - aside from calling mips_find_saved_regs(), mips_frame_init_saved_regs() - does nothing more than set frame->saved_regs[SP_REGNUM]. These two - functions should really be combined and now that there is only one - caller, it should be straightforward. (Watch out for multiple returns - though.) */ +/* Set up the 'saved_regs' array. This is a data structure containing + the addresses on the stack where each register has been saved, for + each stack frame. Registers that have not been saved will have + zero here. The stack pointer register is special: rather than the + address where the stack register has been saved, + saved_regs[SP_REGNUM] will have the actual value of the previous + frame's stack register. */ static void mips_find_saved_regs (struct frame_info *fci) { int ireg; - CORE_ADDR reg_position; /* r0 bit means kernel trap */ int kernel_trap; /* What registers have been saved? Bitmasks. */ unsigned long gen_mask, float_mask; mips_extra_func_info_t proc_desc; t_inst inst; + CORE_ADDR *saved_regs; - frame_saved_regs_zalloc (fci); + if (deprecated_get_frame_saved_regs (fci) != NULL) + return; + saved_regs = frame_saved_regs_zalloc (fci); /* If it is the frame for sigtramp, the saved registers are located - in a sigcontext structure somewhere on the stack. - If the stack layout for sigtramp changes we might have to change these - constants and the companion fixup_sigtramp in mdebugread.c */ + in a sigcontext structure somewhere on the stack. If the stack + layout for sigtramp changes we might have to change these + constants and the companion fixup_sigtramp in mdebugread.c */ #ifndef SIGFRAME_BASE -/* To satisfy alignment restrictions, sigcontext is located 4 bytes - above the sigtramp frame. */ + /* To satisfy alignment restrictions, sigcontext is located 4 bytes + above the sigtramp frame. */ #define SIGFRAME_BASE MIPS_REGSIZE /* FIXME! Are these correct?? */ #define SIGFRAME_PC_OFF (SIGFRAME_BASE + 2 * MIPS_REGSIZE) @@ -1413,60 +1577,65 @@ mips_find_saved_regs (struct frame_info *fci) (SIGFRAME_REGSAVE_OFF + MIPS_NUMREGS * MIPS_REGSIZE + 3 * MIPS_REGSIZE) #endif #ifndef SIGFRAME_REG_SIZE -/* FIXME! Is this correct?? */ + /* FIXME! Is this correct?? */ #define SIGFRAME_REG_SIZE MIPS_REGSIZE #endif if ((get_frame_type (fci) == SIGTRAMP_FRAME)) { for (ireg = 0; ireg < MIPS_NUMREGS; ireg++) { - reg_position = fci->frame + SIGFRAME_REGSAVE_OFF - + ireg * SIGFRAME_REG_SIZE; - get_frame_saved_regs (fci)[ireg] = reg_position; + CORE_ADDR reg_position = (get_frame_base (fci) + SIGFRAME_REGSAVE_OFF + + ireg * SIGFRAME_REG_SIZE); + set_reg_offset (saved_regs, ireg, reg_position); } for (ireg = 0; ireg < MIPS_NUMREGS; ireg++) { - reg_position = fci->frame + SIGFRAME_FPREGSAVE_OFF - + ireg * SIGFRAME_REG_SIZE; - get_frame_saved_regs (fci)[FP0_REGNUM + ireg] = reg_position; + CORE_ADDR reg_position = (get_frame_base (fci) + + SIGFRAME_FPREGSAVE_OFF + + ireg * SIGFRAME_REG_SIZE); + set_reg_offset (saved_regs, FP0_REGNUM + ireg, reg_position); } - get_frame_saved_regs (fci)[PC_REGNUM] = fci->frame + SIGFRAME_PC_OFF; + + set_reg_offset (saved_regs, PC_REGNUM, get_frame_base (fci) + SIGFRAME_PC_OFF); + /* SP_REGNUM, contains the value and not the address. */ + set_reg_offset (saved_regs, SP_REGNUM, get_frame_base (fci)); return; } - proc_desc = fci->extra_info->proc_desc; + proc_desc = get_frame_extra_info (fci)->proc_desc; if (proc_desc == NULL) - /* I'm not sure how/whether this can happen. Normally when we can't - find a proc_desc, we "synthesize" one using heuristic_proc_desc - and set the saved_regs right away. */ + /* I'm not sure how/whether this can happen. Normally when we + can't find a proc_desc, we "synthesize" one using + heuristic_proc_desc and set the saved_regs right away. */ return; kernel_trap = PROC_REG_MASK (proc_desc) & 1; gen_mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK (proc_desc); float_mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK (proc_desc); - if ( /* In any frame other than the innermost or a frame interrupted by - a signal, we assume that all registers have been saved. - This assumes that all register saves in a function happen before - the first function call. */ - (fci->next == NULL || (get_frame_type (fci->next) == SIGTRAMP_FRAME)) + if (/* In any frame other than the innermost or a frame interrupted + by a signal, we assume that all registers have been saved. + This assumes that all register saves in a function happen + before the first function call. */ + (get_next_frame (fci) == NULL + || (get_frame_type (get_next_frame (fci)) == SIGTRAMP_FRAME)) - /* In a dummy frame we know exactly where things are saved. */ + /* In a dummy frame we know exactly where things are saved. */ && !PROC_DESC_IS_DUMMY (proc_desc) - /* Don't bother unless we are inside a function prologue. Outside the - prologue, we know where everything is. */ + /* Don't bother unless we are inside a function prologue. + Outside the prologue, we know where everything is. */ && in_prologue (get_frame_pc (fci), PROC_LOW_ADDR (proc_desc)) - /* Not sure exactly what kernel_trap means, but if it means - the kernel saves the registers without a prologue doing it, - we better not examine the prologue to see whether registers - have been saved yet. */ + /* Not sure exactly what kernel_trap means, but if it means the + kernel saves the registers without a prologue doing it, we + better not examine the prologue to see whether registers + have been saved yet. */ && !kernel_trap) { - /* We need to figure out whether the registers that the proc_desc - claims are saved have been saved yet. */ + /* We need to figure out whether the registers that the + proc_desc claims are saved have been saved yet. */ CORE_ADDR addr; @@ -1479,8 +1648,8 @@ mips_find_saved_regs (struct frame_info *fci) addr = PROC_LOW_ADDR (proc_desc); instlen = pc_is_mips16 (addr) ? MIPS16_INSTLEN : MIPS_INSTLEN; - /* Scan through this function's instructions preceding the current - PC, and look for those that save registers. */ + /* Scan through this function's instructions preceding the + current PC, and look for those that save registers. */ while (addr < get_frame_pc (fci)) { inst = mips_fetch_instruction (addr); @@ -1494,117 +1663,122 @@ mips_find_saved_regs (struct frame_info *fci) float_mask = float_save_found; } - /* Fill in the offsets for the registers which gen_mask says - were saved. */ - reg_position = fci->frame + PROC_REG_OFFSET (proc_desc); - for (ireg = MIPS_NUMREGS - 1; gen_mask; --ireg, gen_mask <<= 1) - if (gen_mask & 0x80000000) - { - get_frame_saved_regs (fci)[ireg] = reg_position; - reg_position -= MIPS_SAVED_REGSIZE; - } + /* Fill in the offsets for the registers which gen_mask says were + saved. */ + { + CORE_ADDR reg_position = (get_frame_base (fci) + + PROC_REG_OFFSET (proc_desc)); + for (ireg = MIPS_NUMREGS - 1; gen_mask; --ireg, gen_mask <<= 1) + if (gen_mask & 0x80000000) + { + set_reg_offset (saved_regs, ireg, reg_position); + reg_position -= MIPS_SAVED_REGSIZE; + } + } - /* The MIPS16 entry instruction saves $s0 and $s1 in the reverse order - of that normally used by gcc. Therefore, we have to fetch the first - instruction of the function, and if it's an entry instruction that - saves $s0 or $s1, correct their saved addresses. */ + /* The MIPS16 entry instruction saves $s0 and $s1 in the reverse + order of that normally used by gcc. Therefore, we have to fetch + the first instruction of the function, and if it's an entry + instruction that saves $s0 or $s1, correct their saved addresses. */ if (pc_is_mips16 (PROC_LOW_ADDR (proc_desc))) { inst = mips_fetch_instruction (PROC_LOW_ADDR (proc_desc)); - if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */ + if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) + /* entry */ { int reg; int sreg_count = (inst >> 6) & 3; /* Check if the ra register was pushed on the stack. */ - reg_position = fci->frame + PROC_REG_OFFSET (proc_desc); + CORE_ADDR reg_position = (get_frame_base (fci) + + PROC_REG_OFFSET (proc_desc)); if (inst & 0x20) reg_position -= MIPS_SAVED_REGSIZE; - /* Check if the s0 and s1 registers were pushed on the stack. */ + /* Check if the s0 and s1 registers were pushed on the + stack. */ for (reg = 16; reg < sreg_count + 16; reg++) { - get_frame_saved_regs (fci)[reg] = reg_position; + set_reg_offset (saved_regs, reg, reg_position); reg_position -= MIPS_SAVED_REGSIZE; } } } - /* Fill in the offsets for the registers which float_mask says - were saved. */ - reg_position = fci->frame + PROC_FREG_OFFSET (proc_desc); - - /* Apparently, the freg_offset gives the offset to the first 64 bit - saved. - - When the ABI specifies 64 bit saved registers, the FREG_OFFSET - designates the first saved 64 bit register. - - When the ABI specifies 32 bit saved registers, the ``64 bit saved - DOUBLE'' consists of two adjacent 32 bit registers, Hence - FREG_OFFSET, designates the address of the lower register of the - register pair. Adjust the offset so that it designates the upper - register of the pair -- i.e., the address of the first saved 32 - bit register. */ - - if (MIPS_SAVED_REGSIZE == 4) - reg_position += MIPS_SAVED_REGSIZE; - - /* Fill in the offsets for the float registers which float_mask says - were saved. */ - for (ireg = MIPS_NUMREGS - 1; float_mask; --ireg, float_mask <<= 1) - if (float_mask & 0x80000000) - { - get_frame_saved_regs (fci)[FP0_REGNUM + ireg] = reg_position; - reg_position -= MIPS_SAVED_REGSIZE; - } + /* Fill in the offsets for the registers which float_mask says were + saved. */ + { + CORE_ADDR reg_position = (get_frame_base (fci) + + PROC_FREG_OFFSET (proc_desc)); - get_frame_saved_regs (fci)[PC_REGNUM] = get_frame_saved_regs (fci)[RA_REGNUM]; -} + /* Fill in the offsets for the float registers which float_mask + says were saved. */ + for (ireg = MIPS_NUMREGS - 1; float_mask; --ireg, float_mask <<= 1) + if (float_mask & 0x80000000) + { + if (MIPS_SAVED_REGSIZE == 4 && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + /* On a big endian 32 bit ABI, floating point registers + are paired to form doubles such that the most + significant part is in $f[N+1] and the least + significant in $f[N] vis: $f[N+1] ||| $f[N]. The + registers are also spilled as a pair and stored as a + double. + + When little-endian the least significant part is + stored first leading to the memory order $f[N] and + then $f[N+1]. + + Unfortunately, when big-endian the most significant + part of the double is stored first, and the least + significant is stored second. This leads to the + registers being ordered in memory as firt $f[N+1] and + then $f[N]. + + For the big-endian case make certain that the + addresses point at the correct (swapped) locations + $f[N] and $f[N+1] pair (keep in mind that + reg_position is decremented each time through the + loop). */ + if ((ireg & 1)) + set_reg_offset (saved_regs, FP0_REGNUM + ireg, + reg_position - MIPS_SAVED_REGSIZE); + else + set_reg_offset (saved_regs, FP0_REGNUM + ireg, + reg_position + MIPS_SAVED_REGSIZE); + } + else + set_reg_offset (saved_regs, FP0_REGNUM + ireg, reg_position); + reg_position -= MIPS_SAVED_REGSIZE; + } -/* Set up the 'saved_regs' array. This is a data structure containing - the addresses on the stack where each register has been saved, for - each stack frame. Registers that have not been saved will have - zero here. The stack pointer register is special: rather than the - address where the stack register has been saved, saved_regs[SP_REGNUM] - will have the actual value of the previous frame's stack register. */ + set_reg_offset (saved_regs, PC_REGNUM, saved_regs[RA_REGNUM]); + } -static void -mips_frame_init_saved_regs (struct frame_info *frame) -{ - if (get_frame_saved_regs (frame) == NULL) - { - mips_find_saved_regs (frame); - } - get_frame_saved_regs (frame)[SP_REGNUM] = frame->frame; + /* SP_REGNUM, contains the value and not the address. */ + set_reg_offset (saved_regs, SP_REGNUM, get_frame_base (fci)); } static CORE_ADDR read_next_frame_reg (struct frame_info *fi, int regno) { - int optimized; - CORE_ADDR addr; - int realnum; - enum lval_type lval; - void *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); - frame_register_unwind (fi, regno, &optimized, &lval, &addr, &realnum, - raw_buffer); - /* FIXME: cagney/2002-09-13: This is just soooo bad. The MIPS - should have a pseudo register range that correspons to the ABI's, - rather than the ISA's, view of registers. These registers would - then implicitly describe their size and hence could be used - without the below munging. */ - if (lval == lval_memory) + /* Always a pseudo. */ + gdb_assert (regno >= NUM_REGS); + if (fi == NULL) { - if (regno < 32) - { - /* Only MIPS_SAVED_REGSIZE bytes of GP registers are - saved. */ - return read_memory_integer (addr, MIPS_SAVED_REGSIZE); - } + LONGEST val; + regcache_cooked_read_signed (current_regcache, regno, &val); + return val; } + else if ((regno % NUM_REGS) == SP_REGNUM) + /* The SP_REGNUM is special, its value is stored in saved_regs. + In fact, it is so special that it can even only be fetched + using a raw register number! Once this code as been converted + to frame-unwind the problem goes away. */ + return frame_unwind_register_signed (fi, regno % NUM_REGS); + else + return frame_unwind_register_signed (fi, regno); - return extract_signed_integer (raw_buffer, REGISTER_VIRTUAL_SIZE (regno)); } /* mips_addr_bits_remove - remove useless address bits */ @@ -1680,8 +1854,11 @@ mips_init_frame_pc_first (int fromleaf, struct frame_info *prev) { CORE_ADDR pc, tmp; - pc = ((fromleaf) ? SAVED_PC_AFTER_CALL (prev->next) : - prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ()); + pc = ((fromleaf) + ? DEPRECATED_SAVED_PC_AFTER_CALL (get_next_frame (prev)) + : get_next_frame (prev) + ? DEPRECATED_FRAME_SAVED_PC (get_next_frame (prev)) + : read_pc ()); tmp = SKIP_TRAMPOLINE_CODE (pc); return tmp ? tmp : pc; } @@ -1691,23 +1868,29 @@ static CORE_ADDR mips_frame_saved_pc (struct frame_info *frame) { CORE_ADDR saved_pc; - mips_extra_func_info_t proc_desc = frame->extra_info->proc_desc; - /* We have to get the saved pc from the sigcontext - if it is a signal handler frame. */ - int pcreg = (get_frame_type (frame) == SIGTRAMP_FRAME) ? PC_REGNUM - : (proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM); if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame), 0, 0)) { LONGEST tmp; - frame_unwind_signed_register (frame, PC_REGNUM, &tmp); + /* Always unwind the cooked PC register value. */ + frame_unwind_signed_register (frame, NUM_REGS + PC_REGNUM, &tmp); saved_pc = tmp; } - else if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc)) - saved_pc = read_memory_integer (frame->frame - MIPS_SAVED_REGSIZE, MIPS_SAVED_REGSIZE); else - saved_pc = read_next_frame_reg (frame, pcreg); - + { + mips_extra_func_info_t proc_desc + = get_frame_extra_info (frame)->proc_desc; + if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc)) + saved_pc = read_memory_integer (get_frame_base (frame) - MIPS_SAVED_REGSIZE, MIPS_SAVED_REGSIZE); + else + { + /* We have to get the saved pc from the sigcontext if it is + a signal handler frame. */ + int pcreg = (get_frame_type (frame) == SIGTRAMP_FRAME ? PC_REGNUM + : proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM); + saved_pc = read_next_frame_reg (frame, NUM_REGS + pcreg); + } + } return ADDR_BITS_REMOVE (saved_pc); } @@ -1720,16 +1903,25 @@ static struct mips_extra_func_info temp_proc_desc; frames. */ static CORE_ADDR *temp_saved_regs; -/* Set a register's saved stack address in temp_saved_regs. If an address - has already been set for this register, do nothing; this way we will - only recognize the first save of a given register in a function prologue. - This is a helper function for mips{16,32}_heuristic_proc_desc. */ +/* Set a register's saved stack address in temp_saved_regs. If an + address has already been set for this register, do nothing; this + way we will only recognize the first save of a given register in a + function prologue. + + For simplicity, save the address in both [0 .. NUM_REGS) and + [NUM_REGS .. 2*NUM_REGS). Strictly speaking, only the second range + is used as it is only second range (the ABI instead of ISA + registers) that comes into play when finding saved registers in a + frame. */ static void -set_reg_offset (int regno, CORE_ADDR offset) +set_reg_offset (CORE_ADDR *saved_regs, int regno, CORE_ADDR offset) { - if (temp_saved_regs[regno] == 0) - temp_saved_regs[regno] = offset; + if (saved_regs[regno] == 0) + { + saved_regs[regno + 0 * NUM_REGS] = offset; + saved_regs[regno + 1 * NUM_REGS] = offset; + } } @@ -1781,10 +1973,10 @@ heuristic_proc_start (CORE_ADDR pc) if (start_pc < fence) { /* It's not clear to me why we reach this point when - stop_soon_quietly, but with this test, at least we + stop_soon, but with this test, at least we don't print out warnings for every child forked (eg, on decstation). 22apr93 rich@cygnus.com. */ - if (!stop_soon_quietly) + if (stop_soon == NO_STOP_QUIETLY) { static int blurb_printed = 0; @@ -1925,26 +2117,26 @@ mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc, offset = mips16_get_imm (prev_inst, inst, 8, 4, 0); reg = mips16_to_32_reg[(inst & 0x700) >> 8]; PROC_REG_MASK (&temp_proc_desc) |= (1 << reg); - set_reg_offset (reg, sp + offset); + set_reg_offset (temp_saved_regs, reg, sp + offset); } else if ((inst & 0xff00) == 0xf900) /* sd reg,n($sp) */ { offset = mips16_get_imm (prev_inst, inst, 5, 8, 0); reg = mips16_to_32_reg[(inst & 0xe0) >> 5]; PROC_REG_MASK (&temp_proc_desc) |= (1 << reg); - set_reg_offset (reg, sp + offset); + set_reg_offset (temp_saved_regs, reg, sp + offset); } else if ((inst & 0xff00) == 0x6200) /* sw $ra,n($sp) */ { offset = mips16_get_imm (prev_inst, inst, 8, 4, 0); PROC_REG_MASK (&temp_proc_desc) |= (1 << RA_REGNUM); - set_reg_offset (RA_REGNUM, sp + offset); + set_reg_offset (temp_saved_regs, RA_REGNUM, sp + offset); } else if ((inst & 0xff00) == 0xfa00) /* sd $ra,n($sp) */ { offset = mips16_get_imm (prev_inst, inst, 8, 8, 0); PROC_REG_MASK (&temp_proc_desc) |= (1 << RA_REGNUM); - set_reg_offset (RA_REGNUM, sp + offset); + set_reg_offset (temp_saved_regs, RA_REGNUM, sp + offset); } else if (inst == 0x673d) /* move $s1, $sp */ { @@ -1963,14 +2155,14 @@ mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc, offset = mips16_get_imm (prev_inst, inst, 5, 4, 0); reg = mips16_to_32_reg[(inst & 0xe0) >> 5]; PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; - set_reg_offset (reg, frame_addr + offset); + set_reg_offset (temp_saved_regs, reg, frame_addr + offset); } else if ((inst & 0xFF00) == 0x7900) /* sd reg,offset($s1) */ { offset = mips16_get_imm (prev_inst, inst, 5, 8, 0); reg = mips16_to_32_reg[(inst & 0xe0) >> 5]; PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; - set_reg_offset (reg, frame_addr + offset); + set_reg_offset (temp_saved_regs, reg, frame_addr + offset); } else if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */ entry_inst = inst; /* save for later processing */ @@ -2000,7 +2192,7 @@ mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc, for (reg = 4, offset = 0; reg < areg_count + 4; reg++) { PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; - set_reg_offset (reg, sp + offset); + set_reg_offset (temp_saved_regs, reg, sp + offset); offset += MIPS_SAVED_REGSIZE; } @@ -2009,7 +2201,7 @@ mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc, if (entry_inst & 0x20) { PROC_REG_MASK (&temp_proc_desc) |= 1 << RA_REGNUM; - set_reg_offset (RA_REGNUM, sp + offset); + set_reg_offset (temp_saved_regs, RA_REGNUM, sp + offset); offset -= MIPS_SAVED_REGSIZE; } @@ -2017,7 +2209,7 @@ mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc, for (reg = 16; reg < sreg_count + 16; reg++) { PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; - set_reg_offset (reg, sp + offset); + set_reg_offset (temp_saved_regs, reg, sp + offset); offset -= MIPS_SAVED_REGSIZE; } } @@ -2062,7 +2254,7 @@ restart: else if ((high_word & 0xFFE0) == 0xafa0) /* sw reg,offset($sp) */ { PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; - set_reg_offset (reg, sp + low_word); + set_reg_offset (temp_saved_regs, reg, sp + low_word); } else if ((high_word & 0xFFE0) == 0xffa0) /* sd reg,offset($sp) */ { @@ -2070,7 +2262,7 @@ restart: but the register size used is only 32 bits. Make the address for the saved register point to the lower 32 bits. */ PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; - set_reg_offset (reg, sp + low_word + 8 - MIPS_REGSIZE); + set_reg_offset (temp_saved_regs, reg, sp + low_word + 8 - MIPS_REGSIZE); } else if (high_word == 0x27be) /* addiu $30,$sp,size */ { @@ -2081,7 +2273,7 @@ restart: { unsigned alloca_adjust; PROC_FRAME_REG (&temp_proc_desc) = 30; - frame_addr = read_next_frame_reg (next_frame, 30); + frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30); alloca_adjust = (unsigned) (frame_addr - (sp + low_word)); if (alloca_adjust > 0) { @@ -2104,7 +2296,7 @@ restart: { unsigned alloca_adjust; PROC_FRAME_REG (&temp_proc_desc) = 30; - frame_addr = read_next_frame_reg (next_frame, 30); + frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30); alloca_adjust = (unsigned) (frame_addr - sp); if (alloca_adjust > 0) { @@ -2120,7 +2312,7 @@ restart: else if ((high_word & 0xFFE0) == 0xafc0) /* sw reg,offset($30) */ { PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; - set_reg_offset (reg, frame_addr + low_word); + set_reg_offset (temp_saved_regs, reg, frame_addr + low_word); } } } @@ -2132,7 +2324,7 @@ heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc, CORE_ADDR sp; if (cur_frame) - sp = read_next_frame_reg (next_frame, SP_REGNUM); + sp = read_next_frame_reg (next_frame, NUM_REGS + SP_REGNUM); else sp = 0; @@ -2322,7 +2514,7 @@ non_heuristic_proc_desc (CORE_ADDR pc, CORE_ADDR *addrptr) return NULL; } - sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, 0, NULL); + sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0, NULL); /* If we never found a PDR for this function in symbol reading, then examine prologues to find the information. */ @@ -2385,7 +2577,7 @@ find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame) to have their own proc_descs, and even if they don't, heuristic_proc_desc knows how to create them! */ - register struct linked_proc_info *link; + struct linked_proc_info *link; for (link = linked_proc_desc_table; link; link = link->next) if (PROC_LOW_ADDR (&link->info) <= pc @@ -2405,10 +2597,9 @@ static CORE_ADDR get_frame_pointer (struct frame_info *frame, mips_extra_func_info_t proc_desc) { - return ADDR_BITS_REMOVE (read_next_frame_reg (frame, - PROC_FRAME_REG (proc_desc)) + - PROC_FRAME_OFFSET (proc_desc) - - PROC_FRAME_ADJUST (proc_desc)); + return (read_next_frame_reg (frame, NUM_REGS + PROC_FRAME_REG (proc_desc)) + + PROC_FRAME_OFFSET (proc_desc) + - PROC_FRAME_ADJUST (proc_desc)); } static mips_extra_func_info_t cached_proc_desc; @@ -2418,9 +2609,9 @@ mips_frame_chain (struct frame_info *frame) { mips_extra_func_info_t proc_desc; CORE_ADDR tmp; - CORE_ADDR saved_pc = FRAME_SAVED_PC (frame); + CORE_ADDR saved_pc = DEPRECATED_FRAME_SAVED_PC (frame); - if (saved_pc == 0 || inside_entry_file (saved_pc)) + if (saved_pc == 0 || deprecated_inside_entry_file (saved_pc)) return 0; /* Check if the PC is inside a call stub. If it is, fetch the @@ -2433,7 +2624,7 @@ mips_frame_chain (struct frame_info *frame) /* A dummy frame, uses SP not FP. Get the old SP value. If all is well, frame->frame the bottom of the current frame will contain that value. */ - return frame->frame; + return get_frame_base (frame); } /* Look up the procedure descriptor for this PC. */ @@ -2463,16 +2654,26 @@ static void mips_init_extra_frame_info (int fromleaf, struct frame_info *fci) { int regnum; + mips_extra_func_info_t proc_desc; - /* Use proc_desc calculated in frame_chain */ - mips_extra_func_info_t proc_desc = - fci->next ? cached_proc_desc : find_proc_desc (get_frame_pc (fci), fci->next, 1); - - fci->extra_info = (struct frame_extra_info *) - frame_obstack_alloc (sizeof (struct frame_extra_info)); + if (get_frame_type (fci) == DUMMY_FRAME) + return; - fci->saved_regs = NULL; - fci->extra_info->proc_desc = + /* Use proc_desc calculated in frame_chain. When there is no + next frame, i.e, get_next_frame (fci) == NULL, we call + find_proc_desc () to calculate it, passing an explicit + NULL as the frame parameter. */ + proc_desc = + get_next_frame (fci) + ? cached_proc_desc + : find_proc_desc (get_frame_pc (fci), + NULL /* i.e, get_next_frame (fci) */, + 1); + + frame_extra_info_zalloc (fci, sizeof (struct frame_extra_info)); + + deprecated_set_frame_saved_regs_hack (fci, NULL); + get_frame_extra_info (fci)->proc_desc = proc_desc == &temp_proc_desc ? 0 : proc_desc; if (proc_desc) { @@ -2482,7 +2683,7 @@ mips_init_extra_frame_info (int fromleaf, struct frame_info *fci) interrupted by a signal at it's very start. */ if (get_frame_pc (fci) == PROC_LOW_ADDR (proc_desc) && !PROC_DESC_IS_DUMMY (proc_desc)) - deprecated_update_frame_base_hack (fci, read_next_frame_reg (fci->next, SP_REGNUM)); + deprecated_update_frame_base_hack (fci, read_next_frame_reg (get_next_frame (fci), NUM_REGS + SP_REGNUM)); else if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fci), 0, 0)) /* Do not ``fix'' fci->frame. It will have the value of the generic dummy frame's top-of-stack (since the draft @@ -2492,7 +2693,7 @@ mips_init_extra_frame_info (int fromleaf, struct frame_info *fci) part of the dummy frames data. */ /* Do nothing. */; else - deprecated_update_frame_base_hack (fci, get_frame_pointer (fci->next, proc_desc)); + deprecated_update_frame_base_hack (fci, get_frame_pointer (get_next_frame (fci), proc_desc)); if (proc_desc == &temp_proc_desc) { @@ -2510,26 +2711,29 @@ mips_init_extra_frame_info (int fromleaf, struct frame_info *fci) if (!PC_IN_SIGTRAMP (get_frame_pc (fci), name)) { frame_saved_regs_zalloc (fci); - memcpy (get_frame_saved_regs (fci), temp_saved_regs, SIZEOF_FRAME_SAVED_REGS); - get_frame_saved_regs (fci)[PC_REGNUM] - = get_frame_saved_regs (fci)[RA_REGNUM]; - /* Set value of previous frame's stack pointer. Remember that - saved_regs[SP_REGNUM] is special in that it contains the - value of the stack pointer register. The other saved_regs - values are addresses (in the inferior) at which a given - register's value may be found. */ - get_frame_saved_regs (fci)[SP_REGNUM] = fci->frame; + /* Set value of previous frame's stack pointer. + Remember that saved_regs[SP_REGNUM] is special in + that it contains the value of the stack pointer + register. The other saved_regs values are addresses + (in the inferior) at which a given register's value + may be found. */ + set_reg_offset (temp_saved_regs, SP_REGNUM, + get_frame_base (fci)); + set_reg_offset (temp_saved_regs, PC_REGNUM, + temp_saved_regs[RA_REGNUM]); + memcpy (deprecated_get_frame_saved_regs (fci), temp_saved_regs, + SIZEOF_FRAME_SAVED_REGS); } } /* hack: if argument regs are saved, guess these contain args */ /* assume we can't tell how many args for now */ - fci->extra_info->num_args = -1; + get_frame_extra_info (fci)->num_args = -1; for (regnum = MIPS_LAST_ARG_REGNUM; regnum >= A0_REGNUM; regnum--) { if (PROC_REG_MASK (proc_desc) & (1 << regnum)) { - fci->extra_info->num_args = regnum - A0_REGNUM + 1; + get_frame_extra_info (fci)->num_args = regnum - A0_REGNUM + 1; break; } } @@ -2606,26 +2810,19 @@ mips_type_needs_double_align (struct type *type) return 0; } -/* Macros to round N up or down to the next A boundary; - A must be a power of two. */ - -#define ROUND_DOWN(n,a) ((n) & ~((a)-1)) -#define ROUND_UP(n,a) (((n)+(a)-1) & ~((a)-1)) - /* Adjust the address downward (direction of stack growth) so that it is correctly aligned for a new stack frame. */ static CORE_ADDR mips_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) { - return ROUND_DOWN (addr, 16); + return align_down (addr, 16); } static CORE_ADDR -mips_eabi_push_arguments (int nargs, - struct value **args, - CORE_ADDR sp, - int struct_return, - CORE_ADDR struct_addr) +mips_eabi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, int nargs, + struct value **args, CORE_ADDR sp, int struct_return, + CORE_ADDR struct_addr) { int argreg; int float_argreg; @@ -2633,27 +2830,35 @@ mips_eabi_push_arguments (int nargs, int len = 0; int stack_offset = 0; + /* For shared libraries, "t9" needs to point at the function + address. */ + regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr); + + /* Set the return address register to point to the entry point of + the program, where a breakpoint lies in wait. */ + regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr); + /* First ensure that the stack and structure return address (if any) are properly aligned. The stack has to be at least 64-bit aligned even on 32-bit machines, because doubles must be 64-bit aligned. For n32 and n64, stack frames need to be 128-bit aligned, so we round to this widest known alignment. */ - sp = ROUND_DOWN (sp, 16); - struct_addr = ROUND_DOWN (struct_addr, 16); + sp = align_down (sp, 16); + struct_addr = align_down (struct_addr, 16); /* Now make space on the stack for the args. We allocate more than necessary for EABI, because the first few arguments are passed in registers, but that's OK. */ for (argnum = 0; argnum < nargs; argnum++) - len += ROUND_UP (TYPE_LENGTH (VALUE_TYPE (args[argnum])), + len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), MIPS_STACK_ARGSIZE); - sp -= ROUND_UP (len, 16); + sp -= align_up (len, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_eabi_push_arguments: sp=0x%s allocated %d\n", - paddr_nz (sp), ROUND_UP (len, 16)); + "mips_eabi_push_dummy_call: sp=0x%s allocated %ld\n", + paddr_nz (sp), (long) align_up (len, 16)); /* Initialize the integer and float register pointers. */ argreg = A0_REGNUM; @@ -2664,7 +2869,7 @@ mips_eabi_push_arguments (int nargs, { if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_eabi_push_arguments: struct_return reg=%d 0x%s\n", + "mips_eabi_push_dummy_call: struct_return reg=%d 0x%s\n", argreg, paddr_nz (struct_addr)); write_register (argreg++, struct_addr); } @@ -2675,7 +2880,7 @@ mips_eabi_push_arguments (int nargs, for (argnum = 0; argnum < nargs; argnum++) { char *val; - char *valbuf = alloca (MAX_REGISTER_RAW_SIZE); + char valbuf[MAX_REGISTER_SIZE]; struct value *arg = args[argnum]; struct type *arg_type = check_typedef (VALUE_TYPE (arg)); int len = TYPE_LENGTH (arg_type); @@ -2683,7 +2888,7 @@ mips_eabi_push_arguments (int nargs, if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_eabi_push_arguments: %d len=%d type=%d", + "mips_eabi_push_dummy_call: %d len=%d type=%d", argnum + 1, len, (int) typecode); /* The EABI passes structures that do not fit in a register by @@ -2691,7 +2896,7 @@ mips_eabi_push_arguments (int nargs, if (len > MIPS_SAVED_REGSIZE && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) { - store_address (valbuf, MIPS_SAVED_REGSIZE, VALUE_ADDRESS (arg)); + store_unsigned_integer (valbuf, MIPS_SAVED_REGSIZE, VALUE_ADDRESS (arg)); typecode = TYPE_CODE_PTR; len = MIPS_SAVED_REGSIZE; val = valbuf; @@ -2860,25 +3065,26 @@ mips_eabi_push_arguments (int nargs, only needs to be adjusted when it has been used. */ if (stack_used_p) - stack_offset += ROUND_UP (partial_len, MIPS_STACK_ARGSIZE); + stack_offset += align_up (partial_len, MIPS_STACK_ARGSIZE); } } if (mips_debug) fprintf_unfiltered (gdb_stdlog, "\n"); } + regcache_cooked_write_signed (regcache, SP_REGNUM, sp); + /* Return adjusted stack pointer. */ return sp; } -/* N32/N64 version of push_arguments. */ +/* N32/N64 version of push_dummy_call. */ static CORE_ADDR -mips_n32n64_push_arguments (int nargs, - struct value **args, - CORE_ADDR sp, - int struct_return, - CORE_ADDR struct_addr) +mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, int nargs, + struct value **args, CORE_ADDR sp, int struct_return, + CORE_ADDR struct_addr) { int argreg; int float_argreg; @@ -2886,25 +3092,33 @@ mips_n32n64_push_arguments (int nargs, int len = 0; int stack_offset = 0; + /* For shared libraries, "t9" needs to point at the function + address. */ + regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr); + + /* Set the return address register to point to the entry point of + the program, where a breakpoint lies in wait. */ + regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr); + /* First ensure that the stack and structure return address (if any) are properly aligned. The stack has to be at least 64-bit aligned even on 32-bit machines, because doubles must be 64-bit aligned. For n32 and n64, stack frames need to be 128-bit aligned, so we round to this widest known alignment. */ - sp = ROUND_DOWN (sp, 16); - struct_addr = ROUND_DOWN (struct_addr, 16); + sp = align_down (sp, 16); + struct_addr = align_down (struct_addr, 16); /* Now make space on the stack for the args. */ for (argnum = 0; argnum < nargs; argnum++) - len += ROUND_UP (TYPE_LENGTH (VALUE_TYPE (args[argnum])), + len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), MIPS_STACK_ARGSIZE); - sp -= ROUND_UP (len, 16); + sp -= align_up (len, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_n32n64_push_arguments: sp=0x%s allocated %d\n", - paddr_nz (sp), ROUND_UP (len, 16)); + "mips_n32n64_push_dummy_call: sp=0x%s allocated %ld\n", + paddr_nz (sp), (long) align_up (len, 16)); /* Initialize the integer and float register pointers. */ argreg = A0_REGNUM; @@ -2915,7 +3129,7 @@ mips_n32n64_push_arguments (int nargs, { if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_n32n64_push_arguments: struct_return reg=%d 0x%s\n", + "mips_n32n64_push_dummy_call: struct_return reg=%d 0x%s\n", argreg, paddr_nz (struct_addr)); write_register (argreg++, struct_addr); } @@ -2926,7 +3140,7 @@ mips_n32n64_push_arguments (int nargs, for (argnum = 0; argnum < nargs; argnum++) { char *val; - char *valbuf = alloca (MAX_REGISTER_RAW_SIZE); + char valbuf[MAX_REGISTER_SIZE]; struct value *arg = args[argnum]; struct type *arg_type = check_typedef (VALUE_TYPE (arg)); int len = TYPE_LENGTH (arg_type); @@ -2934,7 +3148,7 @@ mips_n32n64_push_arguments (int nargs, if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_n32n64_push_arguments: %d len=%d type=%d", + "mips_n32n64_push_dummy_call: %d len=%d type=%d", argnum + 1, len, (int) typecode); val = (char *) VALUE_CONTENTS (arg); @@ -3082,25 +3296,26 @@ mips_n32n64_push_arguments (int nargs, adjusted when it has been used. */ if (stack_used_p) - stack_offset += ROUND_UP (partial_len, MIPS_STACK_ARGSIZE); + stack_offset += align_up (partial_len, MIPS_STACK_ARGSIZE); } } if (mips_debug) fprintf_unfiltered (gdb_stdlog, "\n"); } + regcache_cooked_write_signed (regcache, SP_REGNUM, sp); + /* Return adjusted stack pointer. */ return sp; } -/* O32 version of push_arguments. */ +/* O32 version of push_dummy_call. */ static CORE_ADDR -mips_o32_push_arguments (int nargs, - struct value **args, - CORE_ADDR sp, - int struct_return, - CORE_ADDR struct_addr) +mips_o32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, int nargs, + struct value **args, CORE_ADDR sp, int struct_return, + CORE_ADDR struct_addr) { int argreg; int float_argreg; @@ -3108,25 +3323,33 @@ mips_o32_push_arguments (int nargs, int len = 0; int stack_offset = 0; + /* For shared libraries, "t9" needs to point at the function + address. */ + regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr); + + /* Set the return address register to point to the entry point of + the program, where a breakpoint lies in wait. */ + regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr); + /* First ensure that the stack and structure return address (if any) are properly aligned. The stack has to be at least 64-bit aligned even on 32-bit machines, because doubles must be 64-bit aligned. For n32 and n64, stack frames need to be 128-bit aligned, so we round to this widest known alignment. */ - sp = ROUND_DOWN (sp, 16); - struct_addr = ROUND_DOWN (struct_addr, 16); + sp = align_down (sp, 16); + struct_addr = align_down (struct_addr, 16); /* Now make space on the stack for the args. */ for (argnum = 0; argnum < nargs; argnum++) - len += ROUND_UP (TYPE_LENGTH (VALUE_TYPE (args[argnum])), + len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), MIPS_STACK_ARGSIZE); - sp -= ROUND_UP (len, 16); + sp -= align_up (len, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_o32_push_arguments: sp=0x%s allocated %d\n", - paddr_nz (sp), ROUND_UP (len, 16)); + "mips_o32_push_dummy_call: sp=0x%s allocated %ld\n", + paddr_nz (sp), (long) align_up (len, 16)); /* Initialize the integer and float register pointers. */ argreg = A0_REGNUM; @@ -3137,7 +3360,7 @@ mips_o32_push_arguments (int nargs, { if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_o32_push_arguments: struct_return reg=%d 0x%s\n", + "mips_o32_push_dummy_call: struct_return reg=%d 0x%s\n", argreg, paddr_nz (struct_addr)); write_register (argreg++, struct_addr); stack_offset += MIPS_STACK_ARGSIZE; @@ -3149,7 +3372,7 @@ mips_o32_push_arguments (int nargs, for (argnum = 0; argnum < nargs; argnum++) { char *val; - char *valbuf = alloca (MAX_REGISTER_RAW_SIZE); + char valbuf[MAX_REGISTER_SIZE]; struct value *arg = args[argnum]; struct type *arg_type = check_typedef (VALUE_TYPE (arg)); int len = TYPE_LENGTH (arg_type); @@ -3157,7 +3380,7 @@ mips_o32_push_arguments (int nargs, if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_o32_push_arguments: %d len=%d type=%d", + "mips_o32_push_dummy_call: %d len=%d type=%d", argnum + 1, len, (int) typecode); val = (char *) VALUE_CONTENTS (arg); @@ -3237,7 +3460,7 @@ mips_o32_push_arguments (int nargs, argreg += FP_REGISTER_DOUBLE ? 1 : 2; } /* Reserve space for the FP register. */ - stack_offset += ROUND_UP (len, MIPS_STACK_ARGSIZE); + stack_offset += align_up (len, MIPS_STACK_ARGSIZE); } else { @@ -3381,25 +3604,26 @@ mips_o32_push_arguments (int nargs, refered to as their "home". Consequently, space is always allocated. */ - stack_offset += ROUND_UP (partial_len, MIPS_STACK_ARGSIZE); + stack_offset += align_up (partial_len, MIPS_STACK_ARGSIZE); } } if (mips_debug) fprintf_unfiltered (gdb_stdlog, "\n"); } + regcache_cooked_write_signed (regcache, SP_REGNUM, sp); + /* Return adjusted stack pointer. */ return sp; } -/* O64 version of push_arguments. */ +/* O64 version of push_dummy_call. */ static CORE_ADDR -mips_o64_push_arguments (int nargs, - struct value **args, - CORE_ADDR sp, - int struct_return, - CORE_ADDR struct_addr) +mips_o64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, int nargs, + struct value **args, CORE_ADDR sp, int struct_return, + CORE_ADDR struct_addr) { int argreg; int float_argreg; @@ -3407,25 +3631,33 @@ mips_o64_push_arguments (int nargs, int len = 0; int stack_offset = 0; + /* For shared libraries, "t9" needs to point at the function + address. */ + regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr); + + /* Set the return address register to point to the entry point of + the program, where a breakpoint lies in wait. */ + regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr); + /* First ensure that the stack and structure return address (if any) are properly aligned. The stack has to be at least 64-bit aligned even on 32-bit machines, because doubles must be 64-bit aligned. For n32 and n64, stack frames need to be 128-bit aligned, so we round to this widest known alignment. */ - sp = ROUND_DOWN (sp, 16); - struct_addr = ROUND_DOWN (struct_addr, 16); + sp = align_down (sp, 16); + struct_addr = align_down (struct_addr, 16); /* Now make space on the stack for the args. */ for (argnum = 0; argnum < nargs; argnum++) - len += ROUND_UP (TYPE_LENGTH (VALUE_TYPE (args[argnum])), + len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), MIPS_STACK_ARGSIZE); - sp -= ROUND_UP (len, 16); + sp -= align_up (len, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_o64_push_arguments: sp=0x%s allocated %d\n", - paddr_nz (sp), ROUND_UP (len, 16)); + "mips_o64_push_dummy_call: sp=0x%s allocated %ld\n", + paddr_nz (sp), (long) align_up (len, 16)); /* Initialize the integer and float register pointers. */ argreg = A0_REGNUM; @@ -3436,7 +3668,7 @@ mips_o64_push_arguments (int nargs, { if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_o64_push_arguments: struct_return reg=%d 0x%s\n", + "mips_o64_push_dummy_call: struct_return reg=%d 0x%s\n", argreg, paddr_nz (struct_addr)); write_register (argreg++, struct_addr); stack_offset += MIPS_STACK_ARGSIZE; @@ -3448,7 +3680,7 @@ mips_o64_push_arguments (int nargs, for (argnum = 0; argnum < nargs; argnum++) { char *val; - char *valbuf = alloca (MAX_REGISTER_RAW_SIZE); + char valbuf[MAX_REGISTER_SIZE]; struct value *arg = args[argnum]; struct type *arg_type = check_typedef (VALUE_TYPE (arg)); int len = TYPE_LENGTH (arg_type); @@ -3456,7 +3688,7 @@ mips_o64_push_arguments (int nargs, if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_o64_push_arguments: %d len=%d type=%d", + "mips_o64_push_dummy_call: %d len=%d type=%d", argnum + 1, len, (int) typecode); val = (char *) VALUE_CONTENTS (arg); @@ -3536,7 +3768,7 @@ mips_o64_push_arguments (int nargs, argreg += FP_REGISTER_DOUBLE ? 1 : 2; } /* Reserve space for the FP register. */ - stack_offset += ROUND_UP (len, MIPS_STACK_ARGSIZE); + stack_offset += align_up (len, MIPS_STACK_ARGSIZE); } else { @@ -3680,138 +3912,26 @@ mips_o64_push_arguments (int nargs, refered to as their "home". Consequently, space is always allocated. */ - stack_offset += ROUND_UP (partial_len, MIPS_STACK_ARGSIZE); + stack_offset += align_up (partial_len, MIPS_STACK_ARGSIZE); } } if (mips_debug) fprintf_unfiltered (gdb_stdlog, "\n"); } - /* Return adjusted stack pointer. */ - return sp; -} + regcache_cooked_write_signed (regcache, SP_REGNUM, sp); -static CORE_ADDR -mips_push_return_address (CORE_ADDR pc, CORE_ADDR sp) -{ - /* Set the return address register to point to the entry - point of the program, where a breakpoint lies in wait. */ - write_register (RA_REGNUM, CALL_DUMMY_ADDRESS ()); + /* Return adjusted stack pointer. */ return sp; } -static void -mips_push_register (CORE_ADDR * sp, int regno) -{ - char *buffer = alloca (MAX_REGISTER_RAW_SIZE); - int regsize; - int offset; - if (MIPS_SAVED_REGSIZE < REGISTER_RAW_SIZE (regno)) - { - regsize = MIPS_SAVED_REGSIZE; - offset = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG - ? REGISTER_RAW_SIZE (regno) - MIPS_SAVED_REGSIZE - : 0); - } - else - { - regsize = REGISTER_RAW_SIZE (regno); - offset = 0; - } - *sp -= regsize; - deprecated_read_register_gen (regno, buffer); - write_memory (*sp, buffer + offset, regsize); -} - -/* MASK(i,j) == (1<info; - CORE_ADDR sp = ADDR_BITS_REMOVE (read_signed_register (SP_REGNUM)); - CORE_ADDR old_sp = sp; - link->next = linked_proc_desc_table; - linked_proc_desc_table = link; - -/* FIXME! are these correct ? */ -#define PUSH_FP_REGNUM 16 /* must be a register preserved across calls */ -#define GEN_REG_SAVE_MASK MASK(1,16)|MASK(24,28)|(1<<(MIPS_NUMREGS-1)) -#define FLOAT_REG_SAVE_MASK MASK(0,19) -#define FLOAT_SINGLE_REG_SAVE_MASK \ - ((1<<18)|(1<<16)|(1<<14)|(1<<12)|(1<<10)|(1<<8)|(1<<6)|(1<<4)|(1<<2)|(1<<0)) - /* - * The registers we must save are all those not preserved across - * procedure calls. Dest_Reg (see tm-mips.h) must also be saved. - * In addition, we must save the PC, PUSH_FP_REGNUM, MMLO/-HI - * and FP Control/Status registers. - * - * - * Dummy frame layout: - * (high memory) - * Saved PC - * Saved MMHI, MMLO, FPC_CSR - * Saved R31 - * Saved R28 - * ... - * Saved R1 - * Saved D18 (i.e. F19, F18) - * ... - * Saved D0 (i.e. F1, F0) - * Argument build area and stack arguments written via mips_push_arguments - * (low memory) - */ - - /* Save special registers (PC, MMHI, MMLO, FPC_CSR) */ - PROC_FRAME_REG (proc_desc) = PUSH_FP_REGNUM; - PROC_FRAME_OFFSET (proc_desc) = 0; - PROC_FRAME_ADJUST (proc_desc) = 0; - mips_push_register (&sp, PC_REGNUM); - mips_push_register (&sp, HI_REGNUM); - mips_push_register (&sp, LO_REGNUM); - mips_push_register (&sp, MIPS_FPU_TYPE == MIPS_FPU_NONE ? 0 : FCRCS_REGNUM); - - /* Save general CPU registers */ - PROC_REG_MASK (proc_desc) = GEN_REG_SAVE_MASK; - /* PROC_REG_OFFSET is the offset of the first saved register from FP. */ - PROC_REG_OFFSET (proc_desc) = sp - old_sp - MIPS_SAVED_REGSIZE; - for (ireg = 32; --ireg >= 0;) - if (PROC_REG_MASK (proc_desc) & (1 << ireg)) - mips_push_register (&sp, ireg); - - /* Save floating point registers starting with high order word */ - PROC_FREG_MASK (proc_desc) = - MIPS_FPU_TYPE == MIPS_FPU_DOUBLE ? FLOAT_REG_SAVE_MASK - : MIPS_FPU_TYPE == MIPS_FPU_SINGLE ? FLOAT_SINGLE_REG_SAVE_MASK : 0; - /* PROC_FREG_OFFSET is the offset of the first saved *double* register - from FP. */ - PROC_FREG_OFFSET (proc_desc) = sp - old_sp - 8; - for (ireg = 32; --ireg >= 0;) - if (PROC_FREG_MASK (proc_desc) & (1 << ireg)) - mips_push_register (&sp, ireg + FP0_REGNUM); - - /* Update the frame pointer for the call dummy and the stack pointer. - Set the procedure's starting and ending addresses to point to the - call dummy address at the entry point. */ - write_register (PUSH_FP_REGNUM, old_sp); - write_register (SP_REGNUM, sp); - PROC_LOW_ADDR (proc_desc) = CALL_DUMMY_ADDRESS (); - PROC_HIGH_ADDR (proc_desc) = CALL_DUMMY_ADDRESS () + 4; - SET_PROC_DESC_IS_DUMMY (proc_desc); - PROC_PC_REG (proc_desc) = RA_REGNUM; -} - static void mips_pop_frame (void) { - register int regnum; + int regnum; struct frame_info *frame = get_current_frame (); CORE_ADDR new_sp = get_frame_base (frame); - mips_extra_func_info_t proc_desc = frame->extra_info->proc_desc; + mips_extra_func_info_t proc_desc; if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame), 0, 0)) { @@ -3820,23 +3940,23 @@ mips_pop_frame (void) return; } - write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); - if (get_frame_saved_regs (frame) == NULL) - FRAME_INIT_SAVED_REGS (frame); + proc_desc = get_frame_extra_info (frame)->proc_desc; + write_register (PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (frame)); + mips_find_saved_regs (frame); for (regnum = 0; regnum < NUM_REGS; regnum++) if (regnum != SP_REGNUM && regnum != PC_REGNUM - && get_frame_saved_regs (frame)[regnum]) + && deprecated_get_frame_saved_regs (frame)[regnum]) { /* Floating point registers must not be sign extended, in case MIPS_SAVED_REGSIZE = 4 but sizeof (FP0_REGNUM) == 8. */ if (FP0_REGNUM <= regnum && regnum < FP0_REGNUM + 32) write_register (regnum, - read_memory_unsigned_integer (get_frame_saved_regs (frame)[regnum], + read_memory_unsigned_integer (deprecated_get_frame_saved_regs (frame)[regnum], MIPS_SAVED_REGSIZE)); else write_register (regnum, - read_memory_integer (get_frame_saved_regs (frame)[regnum], + read_memory_integer (deprecated_get_frame_saved_regs (frame)[regnum], MIPS_SAVED_REGSIZE)); } @@ -3878,13 +3998,6 @@ mips_pop_frame (void) } } -static void -mips_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, - struct value **args, struct type *type, int gcc_p) -{ - write_register(T9_REGNUM, fun); -} - /* Floating point register management. Background: MIPS1 & 2 fp registers are 32 bits wide. To support @@ -3937,12 +4050,13 @@ mips_double_register_type (void) into rare_buffer. */ static void -mips_read_fp_register_single (int regno, char *rare_buffer) +mips_read_fp_register_single (struct frame_info *frame, int regno, + char *rare_buffer) { - int raw_size = REGISTER_RAW_SIZE (regno); + int raw_size = DEPRECATED_REGISTER_RAW_SIZE (regno); char *raw_buffer = alloca (raw_size); - if (!frame_register_read (deprecated_selected_frame, regno, raw_buffer)) + if (!frame_register_read (frame, regno, raw_buffer)) error ("can't read register %d (%s)", regno, REGISTER_NAME (regno)); if (raw_size == 8) { @@ -3968,15 +4082,16 @@ mips_read_fp_register_single (int regno, char *rare_buffer) register. */ static void -mips_read_fp_register_double (int regno, char *rare_buffer) +mips_read_fp_register_double (struct frame_info *frame, int regno, + char *rare_buffer) { - int raw_size = REGISTER_RAW_SIZE (regno); + int raw_size = DEPRECATED_REGISTER_RAW_SIZE (regno); if (raw_size == 8 && !mips2_fp_compat ()) { /* We have a 64-bit value for this register, and we should use all 64 bits. */ - if (!frame_register_read (deprecated_selected_frame, regno, rare_buffer)) + if (!frame_register_read (frame, regno, rare_buffer)) error ("can't read register %d (%s)", regno, REGISTER_NAME (regno)); } else @@ -3990,224 +4105,204 @@ mips_read_fp_register_double (int regno, char *rare_buffer) each register. */ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) { - mips_read_fp_register_single (regno, rare_buffer + 4); - mips_read_fp_register_single (regno + 1, rare_buffer); + mips_read_fp_register_single (frame, regno, rare_buffer + 4); + mips_read_fp_register_single (frame, regno + 1, rare_buffer); } else { - mips_read_fp_register_single (regno, rare_buffer); - mips_read_fp_register_single (regno + 1, rare_buffer + 4); + mips_read_fp_register_single (frame, regno, rare_buffer); + mips_read_fp_register_single (frame, regno + 1, rare_buffer + 4); } } } static void -mips_print_register (int regnum, int all) -{ - char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); - - /* Get the data in raw format. */ - if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer)) - { - printf_filtered ("%s: [Invalid]", REGISTER_NAME (regnum)); - return; - } - - /* If we have a actual 32-bit floating point register (or we are in - 32-bit compatibility mode), and the register is even-numbered, - also print it as a double (spanning two registers). */ - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT - && (REGISTER_RAW_SIZE (regnum) == 4 - || mips2_fp_compat ()) - && !((regnum - FP0_REGNUM) & 1)) - { - char *dbuffer = alloca (2 * MAX_REGISTER_RAW_SIZE); - - mips_read_fp_register_double (regnum, dbuffer); +mips_print_fp_register (struct ui_file *file, struct frame_info *frame, + int regnum) +{ /* do values for FP (float) regs */ + char *raw_buffer; + double doub, flt1, flt2; /* doubles extracted from raw hex data */ + int inv1, inv2, namelen; - printf_filtered ("(d%d: ", regnum - FP0_REGNUM); - val_print (mips_double_register_type (), dbuffer, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); - printf_filtered ("); "); - } - fputs_filtered (REGISTER_NAME (regnum), gdb_stdout); + raw_buffer = (char *) alloca (2 * DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM)); - /* 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 - fix it so that either the numeric or the funky (a2, etc.) names - are accepted on input. */ - if (regnum < MIPS_NUMREGS) - printf_filtered ("(r%d): ", regnum); - else - printf_filtered (": "); + fprintf_filtered (file, "%s:", REGISTER_NAME (regnum)); + fprintf_filtered (file, "%*s", 4 - (int) strlen (REGISTER_NAME (regnum)), + ""); - /* If virtual format is floating, print it that way. */ - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT) - if (REGISTER_RAW_SIZE (regnum) == 8 && !mips2_fp_compat ()) - { - /* We have a meaningful 64-bit value in this register. Show - it as a 32-bit float and a 64-bit double. */ - int offset = 4 * (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG); - - printf_filtered (" (float) "); - val_print (mips_float_register_type (), raw_buffer + offset, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); - printf_filtered (", (double) "); - val_print (mips_double_register_type (), raw_buffer, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); - } - else - val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); - /* Else print as integer in hex. */ - else + if (DEPRECATED_REGISTER_RAW_SIZE (regnum) == 4 || mips2_fp_compat ()) { - int offset; - - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - offset = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum); - else - offset = 0; - - print_scalar_formatted (raw_buffer + offset, - REGISTER_VIRTUAL_TYPE (regnum), - 'x', 0, gdb_stdout); - } -} + /* 4-byte registers: Print hex and floating. Also print even + numbered registers as doubles. */ + mips_read_fp_register_single (frame, regnum, raw_buffer); + flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1); -/* Replacement for generic do_registers_info. - Print regs in pretty columns. */ + print_scalar_formatted (raw_buffer, builtin_type_uint32, 'x', 'w', file); -static int -do_fp_register_row (int regnum) -{ /* do values for FP (float) regs */ - char *raw_buffer; - double doub, flt1, flt2; /* doubles extracted from raw hex data */ - int inv1, inv2, inv3; + fprintf_filtered (file, " flt: "); + if (inv1) + fprintf_filtered (file, " "); + else + fprintf_filtered (file, "%-17.9g", flt1); - raw_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM)); + if (regnum % 2 == 0) + { + mips_read_fp_register_double (frame, regnum, raw_buffer); + doub = unpack_double (mips_double_register_type (), raw_buffer, + &inv2); - if (REGISTER_RAW_SIZE (regnum) == 4 || mips2_fp_compat ()) + fprintf_filtered (file, " dbl: "); + if (inv2) + fprintf_filtered (file, ""); + else + fprintf_filtered (file, "%-24.17g", doub); + } + } + else { - /* 4-byte registers: we can fit two registers per row. */ - /* Also print every pair of 4-byte regs as an 8-byte double. */ - mips_read_fp_register_single (regnum, raw_buffer); + /* Eight byte registers: print each one as hex, float and double. */ + mips_read_fp_register_single (frame, regnum, raw_buffer); flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1); - mips_read_fp_register_single (regnum + 1, raw_buffer); - flt2 = unpack_double (mips_float_register_type (), raw_buffer, &inv2); + mips_read_fp_register_double (frame, regnum, raw_buffer); + doub = unpack_double (mips_double_register_type (), raw_buffer, &inv2); - mips_read_fp_register_double (regnum, raw_buffer); - doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3); - printf_filtered (" %-5s", REGISTER_NAME (regnum)); + print_scalar_formatted (raw_buffer, builtin_type_uint64, 'x', 'g', file); + + fprintf_filtered (file, " flt: "); if (inv1) - printf_filtered (": "); + fprintf_filtered (file, ""); else - printf_filtered ("%-17.9g", flt1); + fprintf_filtered (file, "%-17.9g", flt1); - printf_filtered (" %-5s", REGISTER_NAME (regnum + 1)); + fprintf_filtered (file, " dbl: "); if (inv2) - printf_filtered (": "); + fprintf_filtered (file, ""); else - printf_filtered ("%-17.9g", flt2); + fprintf_filtered (file, "%-24.17g", doub); + } +} - printf_filtered (" dbl: "); - if (inv3) - printf_filtered (""); - else - printf_filtered ("%-24.17g", doub); - printf_filtered ("\n"); +static void +mips_print_register (struct ui_file *file, struct frame_info *frame, + int regnum, int all) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + char raw_buffer[MAX_REGISTER_SIZE]; + int offset; - /* may want to do hex display here (future enhancement) */ - regnum += 2; + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT) + { + mips_print_fp_register (file, frame, regnum); + return; } - else + + /* Get the data in raw format. */ + if (!frame_register_read (frame, regnum, raw_buffer)) { - /* Eight byte registers: print each one as float AND as double. */ - mips_read_fp_register_single (regnum, raw_buffer); - flt1 = unpack_double (mips_double_register_type (), raw_buffer, &inv1); + fprintf_filtered (file, "%s: [Invalid]", REGISTER_NAME (regnum)); + return; + } - mips_read_fp_register_double (regnum, raw_buffer); - doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3); + fputs_filtered (REGISTER_NAME (regnum), file); - printf_filtered (" %-5s: ", REGISTER_NAME (regnum)); - if (inv1) - printf_filtered (""); - else - printf_filtered ("flt: %-17.9g", flt1); + /* 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 + fix it so that either the numeric or the funky (a2, etc.) names + are accepted on input. */ + if (regnum < MIPS_NUMREGS) + fprintf_filtered (file, "(r%d): ", regnum); + else + fprintf_filtered (file, ": "); - printf_filtered (" dbl: "); - if (inv3) - printf_filtered (""); - else - printf_filtered ("%-24.17g", doub); + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + offset = DEPRECATED_REGISTER_RAW_SIZE (regnum) - DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum); + else + offset = 0; - printf_filtered ("\n"); - /* may want to do hex display here (future enhancement) */ - regnum++; - } - return regnum; + print_scalar_formatted (raw_buffer + offset, gdbarch_register_type (gdbarch, regnum), + 'x', 0, file); +} + +/* Replacement for generic do_registers_info. + Print regs in pretty columns. */ + +static int +print_fp_register_row (struct ui_file *file, struct frame_info *frame, + int regnum) +{ + fprintf_filtered (file, " "); + mips_print_fp_register (file, frame, regnum); + fprintf_filtered (file, "\n"); + return regnum + 1; } + /* Print a row's worth of GP (int) registers, with name labels above */ static int -do_gp_register_row (int regnum) +print_gp_register_row (struct ui_file *file, struct frame_info *frame, + int start_regnum) { + struct gdbarch *gdbarch = get_frame_arch (frame); /* do values for GP (int) regs */ - char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); + char raw_buffer[MAX_REGISTER_SIZE]; int ncols = (MIPS_REGSIZE == 8 ? 4 : 8); /* display cols per row */ int col, byte; - int start_regnum = regnum; - int numregs = NUM_REGS; - + int regnum; /* For GP registers, we print a separate row of names above the vals */ - printf_filtered (" "); - for (col = 0; col < ncols && regnum < numregs; regnum++) + fprintf_filtered (file, " "); + for (col = 0, regnum = start_regnum; + col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS; + regnum++) { if (*REGISTER_NAME (regnum) == '\0') continue; /* unused register */ - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT) + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT) break; /* end the row: reached FP register */ - printf_filtered (MIPS_REGSIZE == 8 ? "%17s" : "%9s", - REGISTER_NAME (regnum)); + fprintf_filtered (file, MIPS_REGSIZE == 8 ? "%17s" : "%9s", + REGISTER_NAME (regnum)); col++; } - printf_filtered (start_regnum < MIPS_NUMREGS ? "\n R%-4d" : "\n ", - start_regnum); /* print the R0 to R31 names */ + /* print the R0 to R31 names */ + if ((start_regnum % NUM_REGS) < MIPS_NUMREGS) + fprintf_filtered (file, "\n R%-4d", start_regnum % NUM_REGS); + else + fprintf_filtered (file, "\n "); - regnum = start_regnum; /* go back to start of row */ /* now print the values in hex, 4 or 8 to the row */ - for (col = 0; col < ncols && regnum < numregs; regnum++) + for (col = 0, regnum = start_regnum; + col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS; + regnum++) { if (*REGISTER_NAME (regnum) == '\0') continue; /* unused register */ - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT) + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT) break; /* end row: reached FP register */ /* OK: get the data in raw format. */ - if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer)) + if (!frame_register_read (frame, regnum, raw_buffer)) error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum)); /* pad small registers */ - for (byte = 0; byte < (MIPS_REGSIZE - REGISTER_VIRTUAL_SIZE (regnum)); byte++) + for (byte = 0; byte < (MIPS_REGSIZE - DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)); byte++) printf_filtered (" "); /* Now print the register value in hex, endian order. */ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum); - byte < REGISTER_RAW_SIZE (regnum); + for (byte = DEPRECATED_REGISTER_RAW_SIZE (regnum) - DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum); + byte < DEPRECATED_REGISTER_RAW_SIZE (regnum); byte++) - printf_filtered ("%02x", (unsigned char) raw_buffer[byte]); + fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]); else - for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1; + for (byte = DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum) - 1; byte >= 0; byte--) - printf_filtered ("%02x", (unsigned char) raw_buffer[byte]); - printf_filtered (" "); + fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]); + fprintf_filtered (file, " "); col++; } if (col > 0) /* ie. if we actually printed anything... */ - printf_filtered ("\n"); + fprintf_filtered (file, "\n"); return regnum; } @@ -4215,29 +4310,33 @@ do_gp_register_row (int regnum) /* MIPS_DO_REGISTERS_INFO(): called by "info register" command */ static void -mips_do_registers_info (int regnum, int fpregs) +mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, + struct frame_info *frame, int regnum, int all) { if (regnum != -1) /* do one specified register */ { + gdb_assert (regnum >= NUM_REGS); if (*(REGISTER_NAME (regnum)) == '\0') error ("Not a valid register for the current processor type"); - mips_print_register (regnum, 0); - printf_filtered ("\n"); + mips_print_register (file, frame, regnum, 0); + fprintf_filtered (file, "\n"); } else /* do all (or most) registers */ { - regnum = 0; - while (regnum < NUM_REGS) + regnum = NUM_REGS; + while (regnum < NUM_REGS + NUM_PSEUDO_REGS) { - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT) - if (fpregs) /* true for "INFO ALL-REGISTERS" command */ - regnum = do_fp_register_row (regnum); /* FP regs */ - else - regnum += MIPS_NUMREGS; /* skip floating point regs */ + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT) + { + if (all) /* true for "INFO ALL-REGISTERS" command */ + regnum = print_fp_register_row (file, frame, regnum); + else + regnum += MIPS_NUMREGS; /* skip floating point regs */ + } else - regnum = do_gp_register_row (regnum); /* GP (int) regs */ + regnum = print_gp_register_row (file, frame, regnum); } } } @@ -4530,7 +4629,7 @@ return_value_location (struct type *valtype, lo->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0; hi->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 0 : 4; lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG - && REGISTER_RAW_SIZE (FP0_REGNUM) == 8) + && DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM) == 8) ? 4 : 0); hi->reg_offset = lo->reg_offset; lo->reg = FP0_REGNUM + 0; @@ -4543,7 +4642,7 @@ return_value_location (struct type *valtype, /* The floating point value fits in a single floating-point register. */ lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG - && REGISTER_RAW_SIZE (FP0_REGNUM) == 8 + && DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM) == 8 && len == 4) ? 4 : 0); lo->reg = FP0_REGNUM; @@ -4599,7 +4698,7 @@ return_value_location (struct type *valtype, } } if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG - && REGISTER_RAW_SIZE (regnum) == 8 + && DEPRECATED_REGISTER_RAW_SIZE (regnum) == 8 && MIPS_SAVED_REGSIZE == 4) { /* Account for the fact that only the least-signficant part @@ -4617,7 +4716,7 @@ return_value_location (struct type *valtype, static void mips_eabi_extract_return_value (struct type *valtype, - char regbuf[REGISTER_BYTES], + char regbuf[], char *valbuf) { struct return_value_word lo; @@ -4625,18 +4724,18 @@ mips_eabi_extract_return_value (struct type *valtype, return_value_location (valtype, &hi, &lo); memcpy (valbuf + lo.buf_offset, - regbuf + REGISTER_BYTE (lo.reg) + lo.reg_offset, + regbuf + DEPRECATED_REGISTER_BYTE (lo.reg) + lo.reg_offset, lo.len); if (hi.len > 0) memcpy (valbuf + hi.buf_offset, - regbuf + REGISTER_BYTE (hi.reg) + hi.reg_offset, + regbuf + DEPRECATED_REGISTER_BYTE (hi.reg) + hi.reg_offset, hi.len); } static void mips_o64_extract_return_value (struct type *valtype, - char regbuf[REGISTER_BYTES], + char regbuf[], char *valbuf) { struct return_value_word lo; @@ -4644,12 +4743,12 @@ mips_o64_extract_return_value (struct type *valtype, return_value_location (valtype, &hi, &lo); memcpy (valbuf + lo.buf_offset, - regbuf + REGISTER_BYTE (lo.reg) + lo.reg_offset, + regbuf + DEPRECATED_REGISTER_BYTE (lo.reg) + lo.reg_offset, lo.len); if (hi.len > 0) memcpy (valbuf + hi.buf_offset, - regbuf + REGISTER_BYTE (hi.reg) + hi.reg_offset, + regbuf + DEPRECATED_REGISTER_BYTE (hi.reg) + hi.reg_offset, hi.len); } @@ -4659,44 +4758,44 @@ mips_o64_extract_return_value (struct type *valtype, static void mips_eabi_store_return_value (struct type *valtype, char *valbuf) { - char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); + char raw_buffer[MAX_REGISTER_SIZE]; struct return_value_word lo; struct return_value_word hi; return_value_location (valtype, &hi, &lo); memset (raw_buffer, 0, sizeof (raw_buffer)); memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len); - deprecated_write_register_bytes (REGISTER_BYTE (lo.reg), raw_buffer, - REGISTER_RAW_SIZE (lo.reg)); + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (lo.reg), raw_buffer, + DEPRECATED_REGISTER_RAW_SIZE (lo.reg)); if (hi.len > 0) { memset (raw_buffer, 0, sizeof (raw_buffer)); memcpy (raw_buffer + hi.reg_offset, valbuf + hi.buf_offset, hi.len); - deprecated_write_register_bytes (REGISTER_BYTE (hi.reg), raw_buffer, - REGISTER_RAW_SIZE (hi.reg)); + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (hi.reg), raw_buffer, + DEPRECATED_REGISTER_RAW_SIZE (hi.reg)); } } static void mips_o64_store_return_value (struct type *valtype, char *valbuf) { - char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); + char raw_buffer[MAX_REGISTER_SIZE]; struct return_value_word lo; struct return_value_word hi; return_value_location (valtype, &hi, &lo); memset (raw_buffer, 0, sizeof (raw_buffer)); memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len); - deprecated_write_register_bytes (REGISTER_BYTE (lo.reg), raw_buffer, - REGISTER_RAW_SIZE (lo.reg)); + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (lo.reg), raw_buffer, + DEPRECATED_REGISTER_RAW_SIZE (lo.reg)); if (hi.len > 0) { memset (raw_buffer, 0, sizeof (raw_buffer)); memcpy (raw_buffer + hi.reg_offset, valbuf + hi.buf_offset, hi.len); - deprecated_write_register_bytes (REGISTER_BYTE (hi.reg), raw_buffer, - REGISTER_RAW_SIZE (hi.reg)); + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (hi.reg), raw_buffer, + DEPRECATED_REGISTER_RAW_SIZE (hi.reg)); } } @@ -4716,30 +4815,30 @@ mips_o32_xfer_return_value (struct type *type, least significant part of FP0. */ if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); - mips_xfer_register (regcache, FP0_REGNUM, TYPE_LENGTH (type), + mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM, TYPE_LENGTH (type), TARGET_BYTE_ORDER, in, out, 0); } else if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8 && tdep->mips_fpu_type != MIPS_FPU_NONE) { - /* A double-precision floating-point value. It fits in the - least significant part of FP0/FP1 but with byte ordering - based on the target (???). */ + /* A double-precision floating-point value. The most + significant part goes in FP1, and the least significant in + FP0. */ if (mips_debug) - fprintf_unfiltered (gdb_stderr, "Return float in $fp0/$fp1\n"); + fprintf_unfiltered (gdb_stderr, "Return float in $fp1/$fp0\n"); switch (TARGET_BYTE_ORDER) { case BFD_ENDIAN_LITTLE: - mips_xfer_register (regcache, FP0_REGNUM + 0, 4, + mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 0, 4, TARGET_BYTE_ORDER, in, out, 0); - mips_xfer_register (regcache, FP0_REGNUM + 1, 4, + mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 1, 4, TARGET_BYTE_ORDER, in, out, 4); break; case BFD_ENDIAN_BIG: - mips_xfer_register (regcache, FP0_REGNUM + 1, 4, + mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 1, 4, TARGET_BYTE_ORDER, in, out, 0); - mips_xfer_register (regcache, FP0_REGNUM + 0, 4, + mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 0, 4, TARGET_BYTE_ORDER, in, out, 4); break; default: @@ -4763,7 +4862,7 @@ mips_o32_xfer_return_value (struct type *type, /* A struct that contains one or two floats. Each value is part in the least significant part of their floating point register.. */ - bfd_byte *reg = alloca (MAX_REGISTER_RAW_SIZE); + bfd_byte reg[MAX_REGISTER_SIZE]; int regnum; int field; for (field = 0, regnum = FP0_REGNUM; @@ -4774,7 +4873,8 @@ mips_o32_xfer_return_value (struct type *type, / TARGET_CHAR_BIT); if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", offset); - mips_xfer_register (regcache, regnum, TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)), + mips_xfer_register (regcache, NUM_REGS + regnum, + TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)), TARGET_BYTE_ORDER, in, out, offset); } } @@ -4790,16 +4890,16 @@ mips_o32_xfer_return_value (struct type *type, int regnum; for (offset = 0, regnum = V0_REGNUM; offset < TYPE_LENGTH (type); - offset += REGISTER_RAW_SIZE (regnum), regnum++) + offset += DEPRECATED_REGISTER_RAW_SIZE (regnum), regnum++) { - int xfer = REGISTER_RAW_SIZE (regnum); + int xfer = DEPRECATED_REGISTER_RAW_SIZE (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, regnum, xfer, BFD_ENDIAN_UNKNOWN, - in, out, offset); + mips_xfer_register (regcache, NUM_REGS + regnum, xfer, + BFD_ENDIAN_UNKNOWN, in, out, offset); } } #endif @@ -4821,8 +4921,8 @@ mips_o32_xfer_return_value (struct type *type, if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n", offset, xfer, regnum); - mips_xfer_register (regcache, regnum, xfer, TARGET_BYTE_ORDER, - in, out, offset); + mips_xfer_register (regcache, NUM_REGS + regnum, xfer, + TARGET_BYTE_ORDER, in, out, offset); } } } @@ -4856,7 +4956,7 @@ mips_n32n64_xfer_return_value (struct type *type, of FP0. */ if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); - mips_xfer_register (regcache, FP0_REGNUM, TYPE_LENGTH (type), + mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM, TYPE_LENGTH (type), TARGET_BYTE_ORDER, in, out, 0); } else if (TYPE_CODE (type) == TYPE_CODE_STRUCT @@ -4875,7 +4975,7 @@ mips_n32n64_xfer_return_value (struct type *type, /* A struct that contains one or two floats. Each value is part in the least significant part of their floating point register.. */ - bfd_byte *reg = alloca (MAX_REGISTER_RAW_SIZE); + bfd_byte reg[MAX_REGISTER_SIZE]; int regnum; int field; for (field = 0, regnum = FP0_REGNUM; @@ -4886,7 +4986,8 @@ mips_n32n64_xfer_return_value (struct type *type, / TARGET_CHAR_BIT); if (mips_debug) fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", offset); - mips_xfer_register (regcache, regnum, TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)), + mips_xfer_register (regcache, NUM_REGS + regnum, + TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)), TARGET_BYTE_ORDER, in, out, offset); } } @@ -4900,16 +5001,16 @@ mips_n32n64_xfer_return_value (struct type *type, int regnum; for (offset = 0, regnum = V0_REGNUM; offset < TYPE_LENGTH (type); - offset += REGISTER_RAW_SIZE (regnum), regnum++) + offset += DEPRECATED_REGISTER_RAW_SIZE (regnum), regnum++) { - int xfer = REGISTER_RAW_SIZE (regnum); + int xfer = DEPRECATED_REGISTER_RAW_SIZE (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, regnum, xfer, BFD_ENDIAN_UNKNOWN, - in, out, offset); + mips_xfer_register (regcache, NUM_REGS + regnum, xfer, + BFD_ENDIAN_UNKNOWN, in, out, offset); } } else @@ -4920,17 +5021,17 @@ mips_n32n64_xfer_return_value (struct type *type, int regnum; for (offset = 0, regnum = V0_REGNUM; offset < TYPE_LENGTH (type); - offset += REGISTER_RAW_SIZE (regnum), regnum++) + offset += DEPRECATED_REGISTER_RAW_SIZE (regnum), regnum++) { - int xfer = REGISTER_RAW_SIZE (regnum); + int xfer = DEPRECATED_REGISTER_RAW_SIZE (regnum); int pos = 0; 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, regnum, xfer, TARGET_BYTE_ORDER, - in, out, offset); + mips_xfer_register (regcache, NUM_REGS + regnum, xfer, + TARGET_BYTE_ORDER, in, out, offset); } } } @@ -4949,12 +5050,6 @@ mips_n32n64_store_return_value (struct type *type, char *valbuf) mips_n32n64_xfer_return_value (type, current_regcache, NULL, valbuf); } -static void -mips_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) -{ - /* Nothing to do -- push_arguments does all the work. */ -} - static CORE_ADDR mips_extract_struct_value_address (struct regcache *regcache) { @@ -5141,9 +5236,10 @@ reinit_frame_cache_sfunc (char *args, int from_tty, reinit_frame_cache (); } -int -gdb_print_insn_mips (bfd_vma memaddr, disassemble_info *info) +static int +gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info) { + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); mips_extra_func_info_t proc_desc; /* Search for the function containing this address. Set the low bit @@ -5152,22 +5248,50 @@ gdb_print_insn_mips (bfd_vma memaddr, disassemble_info *info) the search would fail because the symbol table says the function starts at an odd address, i.e. 1 byte past the given address. */ memaddr = ADDR_BITS_REMOVE (memaddr); - proc_desc = non_heuristic_proc_desc (MAKE_MIPS16_ADDR (memaddr), NULL); + proc_desc = non_heuristic_proc_desc (make_mips16_addr (memaddr), NULL); /* Make an attempt to determine if this is a 16-bit function. If the procedure descriptor exists and the address therein is odd, it's definitely a 16-bit function. Otherwise, we have to just guess that if the address passed in is odd, it's 16-bits. */ + /* FIXME: cagney/2003-06-26: Is this even necessary? The + disassembler needs to be able to locally determine the ISA, and + not rely on GDB. Otherwize the stand-alone 'objdump -d' will not + work. */ if (proc_desc) - info->mach = pc_is_mips16 (PROC_LOW_ADDR (proc_desc)) ? - bfd_mach_mips16 : TM_PRINT_INSN_MACH; + { + if (pc_is_mips16 (PROC_LOW_ADDR (proc_desc))) + info->mach = bfd_mach_mips16; + } else - info->mach = pc_is_mips16 (memaddr) ? - bfd_mach_mips16 : TM_PRINT_INSN_MACH; + { + if (pc_is_mips16 (memaddr)) + info->mach = bfd_mach_mips16; + } /* Round down the instruction address to the appropriate boundary. */ memaddr &= (info->mach == bfd_mach_mips16 ? ~1 : ~3); + /* Set the disassembler options. */ + if (tdep->mips_abi == MIPS_ABI_N32 + || tdep->mips_abi == MIPS_ABI_N64) + { + /* Set up the disassembler info, so that we get the right + register names from libopcodes. */ + if (tdep->mips_abi == MIPS_ABI_N32) + info->disassembler_options = "gpr-names=n32"; + else + info->disassembler_options = "gpr-names=64"; + info->flavour = bfd_target_elf_flavour; + } + else + /* This string is not recognized explicitly by the disassembler, + but it tells the disassembler to not try to guess the ABI from + the bfd elf headers, such that, if the user overrides the ABI + of a program linked as NewABI, the disassembly will follow the + register naming conventions specified by the user. */ + info->disassembler_options = "gpr-names=32"; + /* Call the appropriate disassembler based on the target endian-ness. */ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) return print_insn_big_mips (memaddr, info); @@ -5175,19 +5299,6 @@ gdb_print_insn_mips (bfd_vma memaddr, disassemble_info *info) return print_insn_little_mips (memaddr, info); } -/* Old-style breakpoint macros. - The IDT board uses an unusual breakpoint value, and sometimes gets - confused when it sees the usual MIPS breakpoint instruction. */ - -#define BIG_BREAKPOINT {0, 0x5, 0, 0xd} -#define LITTLE_BREAKPOINT {0xd, 0, 0x5, 0} -#define PMON_BIG_BREAKPOINT {0, 0, 0, 0xd} -#define PMON_LITTLE_BREAKPOINT {0xd, 0, 0, 0} -#define IDT_BIG_BREAKPOINT {0, 0, 0x0a, 0xd} -#define IDT_LITTLE_BREAKPOINT {0xd, 0x0a, 0, 0} -#define MIPS16_BIG_BREAKPOINT {0xe8, 0xa5} -#define MIPS16_LITTLE_BREAKPOINT {0xa5, 0xe8} - /* This function implements the BREAKPOINT_FROM_PC macro. It uses the program counter value to determine whether a 16- or 32-bit breakpoint should be used. It returns a pointer to a string of bytes that encode a breakpoint @@ -5202,17 +5313,19 @@ mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr) { if (pc_is_mips16 (*pcptr)) { - static unsigned char mips16_big_breakpoint[] = - MIPS16_BIG_BREAKPOINT; - *pcptr = UNMAKE_MIPS16_ADDR (*pcptr); + static unsigned char mips16_big_breakpoint[] = {0xe8, 0xa5}; + *pcptr = unmake_mips16_addr (*pcptr); *lenptr = sizeof (mips16_big_breakpoint); return mips16_big_breakpoint; } else { - static unsigned char big_breakpoint[] = BIG_BREAKPOINT; - static unsigned char pmon_big_breakpoint[] = PMON_BIG_BREAKPOINT; - static unsigned char idt_big_breakpoint[] = IDT_BIG_BREAKPOINT; + /* The IDT board uses an unusual breakpoint value, and + sometimes gets confused when it sees the usual MIPS + breakpoint instruction. */ + static unsigned char big_breakpoint[] = {0, 0x5, 0, 0xd}; + static unsigned char pmon_big_breakpoint[] = {0, 0, 0, 0xd}; + static unsigned char idt_big_breakpoint[] = {0, 0, 0x0a, 0xd}; *lenptr = sizeof (big_breakpoint); @@ -5230,19 +5343,16 @@ mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr) { if (pc_is_mips16 (*pcptr)) { - static unsigned char mips16_little_breakpoint[] = - MIPS16_LITTLE_BREAKPOINT; - *pcptr = UNMAKE_MIPS16_ADDR (*pcptr); + static unsigned char mips16_little_breakpoint[] = {0xa5, 0xe8}; + *pcptr = unmake_mips16_addr (*pcptr); *lenptr = sizeof (mips16_little_breakpoint); return mips16_little_breakpoint; } else { - static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT; - static unsigned char pmon_little_breakpoint[] = - PMON_LITTLE_BREAKPOINT; - static unsigned char idt_little_breakpoint[] = - IDT_LITTLE_BREAKPOINT; + static unsigned char little_breakpoint[] = {0xd, 0, 0x5, 0}; + static unsigned char pmon_little_breakpoint[] = {0xd, 0, 0, 0}; + static unsigned char idt_little_breakpoint[] = {0xd, 0x0a, 0, 0}; *lenptr = sizeof (little_breakpoint); @@ -5432,25 +5542,6 @@ mips_ignore_helper (CORE_ADDR pc) } -/* Return a location where we can set a breakpoint that will be hit - when an inferior function call returns. This is normally the - program's entry point. Executables that don't have an entry - point (e.g. programs in ROM) should define a symbol __CALL_DUMMY_ADDRESS - whose address is the location where the breakpoint should be placed. */ - -static CORE_ADDR -mips_call_dummy_address (void) -{ - struct minimal_symbol *sym; - - sym = lookup_minimal_symbol ("__CALL_DUMMY_ADDRESS", NULL, NULL); - if (sym) - return SYMBOL_VALUE_ADDRESS (sym); - else - return entry_point_address (); -} - - /* When debugging a 64 MIPS target running a 32 bit ABI, the size of the register stored on the stack (32) is different to its real raw size (64). The below ensures that registers are fetched from the @@ -5471,10 +5562,10 @@ mips_get_saved_register (char *raw_buffer, CORE_ADDR addrx; enum lval_type lvalx; int optimizedx; - int realnum; + int realnumx; - if (!target_has_registers) - error ("No registers."); + /* Always a pseudo. */ + gdb_assert (regnum >= NUM_REGS); /* Make certain that all needed parameters are present. */ if (addrp == NULL) @@ -5483,26 +5574,20 @@ mips_get_saved_register (char *raw_buffer, lvalp = &lvalx; if (optimizedp == NULL) optimizedp = &optimizedx; - frame_register_unwind (get_next_frame (frame), regnum, optimizedp, lvalp, - addrp, &realnum, raw_buffer); - /* FIXME: cagney/2002-09-13: This is just so bad. The MIPS should - have a pseudo register range that correspons to the ABI's, rather - than the ISA's, view of registers. These registers would then - implicitly describe their size and hence could be used without - the below munging. */ - if ((*lvalp) == lval_memory) - { - if (raw_buffer != NULL) - { - if (regnum < 32) - { - /* Only MIPS_SAVED_REGSIZE bytes of GP registers are - saved. */ - LONGEST val = read_memory_integer ((*addrp), MIPS_SAVED_REGSIZE); - store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), val); - } - } - } + + if ((regnum % NUM_REGS) == SP_REGNUM) + /* The SP_REGNUM is special, its value is stored in saved_regs. + In fact, it is so special that it can even only be fetched + using a raw register number! Once this code as been converted + to frame-unwind the problem goes away. */ + frame_register_unwind (deprecated_get_next_frame_hack (frame), + regnum % NUM_REGS, optimizedp, lvalp, addrp, + &realnumx, raw_buffer); + else + /* Get it from the next frame. */ + frame_register_unwind (deprecated_get_next_frame_hack (frame), + regnum, optimizedp, lvalp, addrp, + &realnumx, raw_buffer); } /* Immediately after a function call, return the saved pc. @@ -5517,29 +5602,67 @@ mips_saved_pc_after_call (struct frame_info *frame) } -/* Convert a dbx stab register number (from `r' declaration) to a gdb - REGNUM */ +/* Convert a dbx stab register number (from `r' declaration) to a GDB + [1 * NUM_REGS .. 2 * NUM_REGS) REGNUM. */ static int mips_stab_reg_to_regnum (int num) { - if (num < 32) - return num; + int regnum; + if (num >= 0 && num < 32) + regnum = num; + else if (num >= 38 && num < 70) + regnum = num + FP0_REGNUM - 38; + else if (num == 70) + regnum = HI_REGNUM; + else if (num == 71) + regnum = LO_REGNUM; else - return num + FP0_REGNUM - 38; + /* This will hopefully (eventually) provoke a warning. Should + we be calling complaint() here? */ + return NUM_REGS + NUM_PSEUDO_REGS; + return NUM_REGS + regnum; } -/* Convert a ecoff register number to a gdb REGNUM */ + +/* Convert a dwarf, dwarf2, or ecoff register number to a GDB [1 * + NUM_REGS .. 2 * NUM_REGS) REGNUM. */ static int -mips_ecoff_reg_to_regnum (int num) +mips_dwarf_dwarf2_ecoff_reg_to_regnum (int num) { - if (num < 32) - return num; + int regnum; + if (num >= 0 && num < 32) + regnum = num; + else if (num >= 32 && num < 64) + regnum = num + FP0_REGNUM - 32; + else if (num == 64) + regnum = HI_REGNUM; + else if (num == 65) + regnum = LO_REGNUM; else - return num + FP0_REGNUM - 32; + /* This will hopefully (eventually) provoke a warning. Should we + be calling complaint() here? */ + return NUM_REGS + NUM_PSEUDO_REGS; + return NUM_REGS + regnum; } +static int +mips_register_sim_regno (int regnum) +{ + /* Only makes sense to supply raw registers. */ + gdb_assert (regnum >= 0 && regnum < NUM_REGS); + /* FIXME: cagney/2002-05-13: Need to look at the pseudo register to + decide if it is valid. Should instead define a standard sim/gdb + register numbering scheme. */ + if (REGISTER_NAME (NUM_REGS + regnum) != NULL + && REGISTER_NAME (NUM_REGS + regnum)[0] != '\0') + return regnum; + else + return LEGACY_SIM_REGNO_IGNORE; +} + + /* Convert an integer into an address. By first converting the value into a pointer and then extracting it signed, the address is guarenteed to be correctly sign extended. */ @@ -5599,18 +5722,11 @@ static struct gdbarch * mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - static LONGEST mips_call_dummy_words[] = - {0}; struct gdbarch *gdbarch; struct gdbarch_tdep *tdep; int elf_flags; enum mips_abi mips_abi, found_abi, wanted_abi; - - /* Reset the disassembly info, in case it was set to something - non-default. */ - tm_print_insn_info.flavour = bfd_target_unknown_flavour; - tm_print_insn_info.arch = bfd_arch_unknown; - tm_print_insn_info.mach = 0; + int num_regs; elf_flags = 0; @@ -5729,24 +5845,29 @@ mips_gdbarch_init (struct gdbarch_info info, set_gdbarch_float_bit (gdbarch, 32); set_gdbarch_double_bit (gdbarch, 64); set_gdbarch_long_double_bit (gdbarch, 64); - set_gdbarch_register_raw_size (gdbarch, mips_register_raw_size); - set_gdbarch_max_register_raw_size (gdbarch, 8); - set_gdbarch_max_register_virtual_size (gdbarch, 8); + set_gdbarch_deprecated_register_raw_size (gdbarch, mips_register_raw_size); + set_gdbarch_deprecated_register_byte (gdbarch, mips_register_byte); + set_gdbarch_register_reggroup_p (gdbarch, mips_register_reggroup_p); + set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, mips_pseudo_register_write); tdep->found_abi = found_abi; tdep->mips_abi = mips_abi; set_gdbarch_elf_make_msymbol_special (gdbarch, mips_elf_make_msymbol_special); + if (info.osabi == GDB_OSABI_IRIX) - set_gdbarch_num_regs (gdbarch, 71); + num_regs = 71; else - set_gdbarch_num_regs (gdbarch, 90); + num_regs = 90; + set_gdbarch_num_regs (gdbarch, num_regs); + set_gdbarch_num_pseudo_regs (gdbarch, num_regs); switch (mips_abi) { case MIPS_ABI_O32: - set_gdbarch_push_arguments (gdbarch, mips_o32_push_arguments); + set_gdbarch_push_dummy_call (gdbarch, mips_o32_push_dummy_call); set_gdbarch_deprecated_store_return_value (gdbarch, mips_o32_store_return_value); set_gdbarch_extract_return_value (gdbarch, mips_o32_extract_return_value); tdep->mips_default_saved_regsize = 4; @@ -5759,13 +5880,13 @@ mips_gdbarch_init (struct gdbarch_info info, set_gdbarch_long_bit (gdbarch, 32); set_gdbarch_ptr_bit (gdbarch, 32); set_gdbarch_long_long_bit (gdbarch, 64); - set_gdbarch_reg_struct_has_addr (gdbarch, - mips_o32_reg_struct_has_addr); + set_gdbarch_deprecated_reg_struct_has_addr + (gdbarch, mips_o32_reg_struct_has_addr); set_gdbarch_use_struct_convention (gdbarch, - mips_o32_use_struct_convention); + always_use_struct_convention); break; case MIPS_ABI_O64: - set_gdbarch_push_arguments (gdbarch, mips_o64_push_arguments); + set_gdbarch_push_dummy_call (gdbarch, mips_o64_push_dummy_call); set_gdbarch_deprecated_store_return_value (gdbarch, mips_o64_store_return_value); set_gdbarch_deprecated_extract_return_value (gdbarch, mips_o64_extract_return_value); tdep->mips_default_saved_regsize = 8; @@ -5778,13 +5899,12 @@ mips_gdbarch_init (struct gdbarch_info info, set_gdbarch_long_bit (gdbarch, 32); set_gdbarch_ptr_bit (gdbarch, 32); set_gdbarch_long_long_bit (gdbarch, 64); - set_gdbarch_reg_struct_has_addr (gdbarch, - mips_o32_reg_struct_has_addr); - set_gdbarch_use_struct_convention (gdbarch, - mips_o32_use_struct_convention); + set_gdbarch_deprecated_reg_struct_has_addr + (gdbarch, mips_o32_reg_struct_has_addr); + set_gdbarch_use_struct_convention (gdbarch, always_use_struct_convention); break; case MIPS_ABI_EABI32: - set_gdbarch_push_arguments (gdbarch, mips_eabi_push_arguments); + set_gdbarch_push_dummy_call (gdbarch, mips_eabi_push_dummy_call); set_gdbarch_deprecated_store_return_value (gdbarch, mips_eabi_store_return_value); set_gdbarch_deprecated_extract_return_value (gdbarch, mips_eabi_extract_return_value); tdep->mips_default_saved_regsize = 4; @@ -5797,13 +5917,13 @@ mips_gdbarch_init (struct gdbarch_info info, set_gdbarch_long_bit (gdbarch, 32); set_gdbarch_ptr_bit (gdbarch, 32); set_gdbarch_long_long_bit (gdbarch, 64); - set_gdbarch_reg_struct_has_addr (gdbarch, - mips_eabi_reg_struct_has_addr); + set_gdbarch_deprecated_reg_struct_has_addr + (gdbarch, mips_eabi_reg_struct_has_addr); set_gdbarch_use_struct_convention (gdbarch, mips_eabi_use_struct_convention); break; case MIPS_ABI_EABI64: - set_gdbarch_push_arguments (gdbarch, mips_eabi_push_arguments); + set_gdbarch_push_dummy_call (gdbarch, mips_eabi_push_dummy_call); set_gdbarch_deprecated_store_return_value (gdbarch, mips_eabi_store_return_value); set_gdbarch_deprecated_extract_return_value (gdbarch, mips_eabi_extract_return_value); tdep->mips_default_saved_regsize = 8; @@ -5816,13 +5936,13 @@ mips_gdbarch_init (struct gdbarch_info info, set_gdbarch_long_bit (gdbarch, 64); set_gdbarch_ptr_bit (gdbarch, 64); set_gdbarch_long_long_bit (gdbarch, 64); - set_gdbarch_reg_struct_has_addr (gdbarch, - mips_eabi_reg_struct_has_addr); + set_gdbarch_deprecated_reg_struct_has_addr + (gdbarch, mips_eabi_reg_struct_has_addr); set_gdbarch_use_struct_convention (gdbarch, mips_eabi_use_struct_convention); break; case MIPS_ABI_N32: - set_gdbarch_push_arguments (gdbarch, mips_n32n64_push_arguments); + set_gdbarch_push_dummy_call (gdbarch, mips_n32n64_push_dummy_call); set_gdbarch_deprecated_store_return_value (gdbarch, mips_n32n64_store_return_value); set_gdbarch_extract_return_value (gdbarch, mips_n32n64_extract_return_value); tdep->mips_default_saved_regsize = 8; @@ -5835,25 +5955,13 @@ mips_gdbarch_init (struct gdbarch_info info, set_gdbarch_long_bit (gdbarch, 32); set_gdbarch_ptr_bit (gdbarch, 32); set_gdbarch_long_long_bit (gdbarch, 64); - - /* Set up the disassembler info, so that we get the right - register names from libopcodes. */ - tm_print_insn_info.flavour = bfd_target_elf_flavour; - tm_print_insn_info.arch = bfd_arch_mips; - if (info.bfd_arch_info != NULL - && info.bfd_arch_info->arch == bfd_arch_mips - && info.bfd_arch_info->mach) - tm_print_insn_info.mach = info.bfd_arch_info->mach; - else - tm_print_insn_info.mach = bfd_mach_mips8000; - set_gdbarch_use_struct_convention (gdbarch, mips_n32n64_use_struct_convention); - set_gdbarch_reg_struct_has_addr (gdbarch, - mips_n32n64_reg_struct_has_addr); + set_gdbarch_deprecated_reg_struct_has_addr + (gdbarch, mips_n32n64_reg_struct_has_addr); break; case MIPS_ABI_N64: - set_gdbarch_push_arguments (gdbarch, mips_n32n64_push_arguments); + set_gdbarch_push_dummy_call (gdbarch, mips_n32n64_push_dummy_call); set_gdbarch_deprecated_store_return_value (gdbarch, mips_n32n64_store_return_value); set_gdbarch_extract_return_value (gdbarch, mips_n32n64_extract_return_value); tdep->mips_default_saved_regsize = 8; @@ -5866,22 +5974,10 @@ mips_gdbarch_init (struct gdbarch_info info, set_gdbarch_long_bit (gdbarch, 64); set_gdbarch_ptr_bit (gdbarch, 64); set_gdbarch_long_long_bit (gdbarch, 64); - - /* Set up the disassembler info, so that we get the right - register names from libopcodes. */ - tm_print_insn_info.flavour = bfd_target_elf_flavour; - tm_print_insn_info.arch = bfd_arch_mips; - if (info.bfd_arch_info != NULL - && info.bfd_arch_info->arch == bfd_arch_mips - && info.bfd_arch_info->mach) - tm_print_insn_info.mach = info.bfd_arch_info->mach; - else - tm_print_insn_info.mach = bfd_mach_mips8000; - set_gdbarch_use_struct_convention (gdbarch, mips_n32n64_use_struct_convention); - set_gdbarch_reg_struct_has_addr (gdbarch, - mips_n32n64_reg_struct_has_addr); + set_gdbarch_deprecated_reg_struct_has_addr + (gdbarch, mips_n32n64_reg_struct_has_addr); break; default: internal_error (__FILE__, __LINE__, @@ -5933,17 +6029,13 @@ mips_gdbarch_init (struct gdbarch_info info, /* MIPS version of register names. NOTE: At present the MIPS register name management is part way between the old - - #undef/#define REGISTER_NAMES and the new REGISTER_NAME(nr). + #undef/#define MIPS_REGISTER_NAMES and the new REGISTER_NAME(nr). Further work on it is required. */ - /* NOTE: many targets (esp. embedded) do not go thru the - gdbarch_register_name vector at all, instead bypassing it - by defining REGISTER_NAMES. */ set_gdbarch_register_name (gdbarch, mips_register_name); set_gdbarch_read_pc (gdbarch, mips_read_pc); set_gdbarch_write_pc (gdbarch, generic_target_write_pc); - set_gdbarch_read_fp (gdbarch, mips_read_sp); /* Draft FRAME base. */ + set_gdbarch_deprecated_target_read_fp (gdbarch, mips_read_sp); /* Draft FRAME base. */ set_gdbarch_read_sp (gdbarch, mips_read_sp); - set_gdbarch_write_sp (gdbarch, generic_target_write_sp); /* Add/remove bits from an address. The MIPS needs be careful to ensure that all 32 bit addresses are sign extended to 64 bits. */ @@ -5952,56 +6044,45 @@ mips_gdbarch_init (struct gdbarch_info info, /* There's a mess in stack frame creation. See comments in blockframe.c near reference to DEPRECATED_INIT_FRAME_PC_FIRST. */ set_gdbarch_deprecated_init_frame_pc_first (gdbarch, mips_init_frame_pc_first); - set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_noop); /* Map debug register numbers onto internal register numbers. */ set_gdbarch_stab_reg_to_regnum (gdbarch, mips_stab_reg_to_regnum); - set_gdbarch_ecoff_reg_to_regnum (gdbarch, mips_ecoff_reg_to_regnum); + set_gdbarch_ecoff_reg_to_regnum (gdbarch, mips_dwarf_dwarf2_ecoff_reg_to_regnum); + set_gdbarch_dwarf_reg_to_regnum (gdbarch, mips_dwarf_dwarf2_ecoff_reg_to_regnum); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, mips_dwarf_dwarf2_ecoff_reg_to_regnum); + set_gdbarch_register_sim_regno (gdbarch, mips_register_sim_regno); /* Initialize a frame */ - set_gdbarch_init_extra_frame_info (gdbarch, mips_init_extra_frame_info); - set_gdbarch_frame_init_saved_regs (gdbarch, mips_frame_init_saved_regs); + set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, mips_find_saved_regs); + set_gdbarch_deprecated_init_extra_frame_info (gdbarch, mips_init_extra_frame_info); /* MIPS version of CALL_DUMMY */ - set_gdbarch_call_dummy_p (gdbarch, 1); - set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0); - set_gdbarch_call_dummy_address (gdbarch, mips_call_dummy_address); - set_gdbarch_push_return_address (gdbarch, mips_push_return_address); - set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame); - set_gdbarch_pop_frame (gdbarch, mips_pop_frame); - set_gdbarch_call_dummy_start_offset (gdbarch, 0); - set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1); - set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0); - set_gdbarch_call_dummy_length (gdbarch, 0); - set_gdbarch_fix_call_dummy (gdbarch, mips_fix_call_dummy); - set_gdbarch_call_dummy_words (gdbarch, mips_call_dummy_words); - set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (mips_call_dummy_words)); - set_gdbarch_push_return_address (gdbarch, mips_push_return_address); + /* NOTE: cagney/2003-08-05: Eventually call dummy location will be + replaced by a command, and all targets will default to on stack + (regardless of the stack's execute status). */ + set_gdbarch_call_dummy_location (gdbarch, AT_SYMBOL); + set_gdbarch_deprecated_pop_frame (gdbarch, mips_pop_frame); set_gdbarch_frame_align (gdbarch, mips_frame_align); - set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); - set_gdbarch_register_convertible (gdbarch, mips_register_convertible); - set_gdbarch_register_convert_to_virtual (gdbarch, - mips_register_convert_to_virtual); - set_gdbarch_register_convert_to_raw (gdbarch, - mips_register_convert_to_raw); - - set_gdbarch_frame_chain (gdbarch, mips_frame_chain); - set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid); + set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); + set_gdbarch_deprecated_register_convertible (gdbarch, mips_register_convertible); + set_gdbarch_deprecated_register_convert_to_virtual (gdbarch, mips_register_convert_to_virtual); + set_gdbarch_deprecated_register_convert_to_raw (gdbarch, mips_register_convert_to_raw); + + set_gdbarch_deprecated_frame_chain (gdbarch, mips_frame_chain); set_gdbarch_frameless_function_invocation (gdbarch, generic_frameless_function_invocation_not); - set_gdbarch_frame_saved_pc (gdbarch, mips_frame_saved_pc); - set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown); + set_gdbarch_deprecated_frame_saved_pc (gdbarch, mips_frame_saved_pc); set_gdbarch_frame_args_skip (gdbarch, 0); - set_gdbarch_get_saved_register (gdbarch, mips_get_saved_register); + set_gdbarch_deprecated_get_saved_register (gdbarch, mips_get_saved_register); set_gdbarch_inner_than (gdbarch, core_addr_lessthan); set_gdbarch_breakpoint_from_pc (gdbarch, mips_breakpoint_from_pc); set_gdbarch_decr_pc_after_break (gdbarch, 0); set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue); - set_gdbarch_saved_pc_after_call (gdbarch, mips_saved_pc_after_call); + set_gdbarch_deprecated_saved_pc_after_call (gdbarch, mips_saved_pc_after_call); set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address); set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer); @@ -6009,18 +6090,24 @@ mips_gdbarch_init (struct gdbarch_info info, set_gdbarch_function_start_offset (gdbarch, 0); - /* There are MIPS targets which do not yet use this since they still - define REGISTER_VIRTUAL_TYPE. */ - set_gdbarch_register_virtual_type (gdbarch, mips_register_virtual_type); - set_gdbarch_register_virtual_size (gdbarch, generic_register_size); + set_gdbarch_register_type (gdbarch, mips_register_type); - set_gdbarch_deprecated_do_registers_info (gdbarch, mips_do_registers_info); + set_gdbarch_print_registers_info (gdbarch, mips_print_registers_info); set_gdbarch_pc_in_sigtramp (gdbarch, mips_pc_in_sigtramp); + set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips); + + /* FIXME: cagney/2003-08-29: The macros HAVE_STEPPABLE_WATCHPOINT, + HAVE_NONSTEPPABLE_WATCHPOINT, and HAVE_CONTINUABLE_WATCHPOINT + need to all be folded into the target vector. Since they are + being used as guards for STOPPED_BY_WATCHPOINT, why not have + STOPPED_BY_WATCHPOINT return the type of watchpoint that the code + is sitting on? */ + set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); + /* Hook in OS ABI-specific overrides, if they have been registered. */ gdbarch_init_osabi (info, gdbarch); - set_gdbarch_store_struct_return (gdbarch, mips_store_struct_return); set_gdbarch_extract_struct_value_address (gdbarch, mips_extract_struct_value_address); @@ -6044,6 +6131,38 @@ mips_abi_update (char *ignore_args, int from_tty, gdbarch_update_p (info); } +/* Print out which MIPS ABI is in use. */ + +static void +show_mips_abi (char *ignore_args, int from_tty) +{ + if (gdbarch_bfd_arch_info (current_gdbarch)->arch != bfd_arch_mips) + printf_filtered ( + "The MIPS ABI is unknown because the current architecture is not MIPS.\n"); + else + { + enum mips_abi global_abi = global_mips_abi (); + enum mips_abi actual_abi = mips_abi (current_gdbarch); + const char *actual_abi_str = mips_abi_strings[actual_abi]; + + if (global_abi == MIPS_ABI_UNKNOWN) + printf_filtered ("The MIPS ABI is set automatically (currently \"%s\").\n", + actual_abi_str); + else if (global_abi == actual_abi) + printf_filtered ( + "The MIPS ABI is assumed to be \"%s\" (due to user setting).\n", + actual_abi_str); + else + { + /* Probably shouldn't happen... */ + printf_filtered ( + "The (auto detected) MIPS ABI \"%s\" is in use even though the user setting was \"%s\".\n", + actual_abi_str, + mips_abi_strings[global_abi]); + } + } +} + static void mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) { @@ -6142,8 +6261,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) fprintf_unfiltered (file, "mips_dump_tdep: BADVADDR_REGNUM = %d\n", BADVADDR_REGNUM); - fprintf_unfiltered (file, - "mips_dump_tdep: BIG_BREAKPOINT = delete?\n"); fprintf_unfiltered (file, "mips_dump_tdep: CAUSE_REGNUM = %d\n", CAUSE_REGNUM); @@ -6168,19 +6285,9 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) fprintf_unfiltered (file, "mips_dump_tdep: GDB_TARGET_IS_MIPS64 = %d\n", GDB_TARGET_IS_MIPS64); - fprintf_unfiltered (file, - "mips_dump_tdep: GEN_REG_SAVE_MASK = %d\n", - GEN_REG_SAVE_MASK); - fprintf_unfiltered (file, - "mips_dump_tdep: HAVE_NONSTEPPABLE_WATCHPOINT # %s\n", - XSTRING (HAVE_NONSTEPPABLE_WATCHPOINT)); fprintf_unfiltered (file, "mips_dump_tdep: HI_REGNUM = %d\n", HI_REGNUM); - fprintf_unfiltered (file, - "mips_dump_tdep: IDT_BIG_BREAKPOINT = delete?\n"); - fprintf_unfiltered (file, - "mips_dump_tdep: IDT_LITTLE_BREAKPOINT = delete?\n"); fprintf_unfiltered (file, "mips_dump_tdep: IGNORE_HELPER_CALL # %s\n", XSTRING (IGNORE_HELPER_CALL (PC))); @@ -6190,13 +6297,9 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) fprintf_unfiltered (file, "mips_dump_tdep: IN_SOLIB_RETURN_TRAMPOLINE # %s\n", XSTRING (IN_SOLIB_RETURN_TRAMPOLINE (PC, NAME))); - fprintf_unfiltered (file, - "mips_dump_tdep: IS_MIPS16_ADDR = FIXME!\n"); fprintf_unfiltered (file, "mips_dump_tdep: LAST_EMBED_REGNUM = %d\n", LAST_EMBED_REGNUM); - fprintf_unfiltered (file, - "mips_dump_tdep: LITTLE_BREAKPOINT = delete?\n"); fprintf_unfiltered (file, "mips_dump_tdep: LO_REGNUM = %d\n", LO_REGNUM); @@ -6215,15 +6318,9 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) "mips_dump_tdep: MACHINE_CPROC_SP_OFFSET = %d\n", MACHINE_CPROC_SP_OFFSET); #endif - fprintf_unfiltered (file, - "mips_dump_tdep: MAKE_MIPS16_ADDR = FIXME!\n"); - fprintf_unfiltered (file, - "mips_dump_tdep: MIPS16_BIG_BREAKPOINT = delete?\n"); fprintf_unfiltered (file, "mips_dump_tdep: MIPS16_INSTLEN = %d\n", MIPS16_INSTLEN); - fprintf_unfiltered (file, - "mips_dump_tdep: MIPS16_LITTLE_BREAKPOINT = delete?\n"); fprintf_unfiltered (file, "mips_dump_tdep: MIPS_DEFAULT_ABI = FIXME!\n"); fprintf_unfiltered (file, @@ -6247,16 +6344,9 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) "mips_dump_tdep: OP_LDFPR = used?\n"); fprintf_unfiltered (file, "mips_dump_tdep: OP_LDGPR = used?\n"); - fprintf_unfiltered (file, - "mips_dump_tdep: PMON_BIG_BREAKPOINT = delete?\n"); - fprintf_unfiltered (file, - "mips_dump_tdep: PMON_LITTLE_BREAKPOINT = delete?\n"); fprintf_unfiltered (file, "mips_dump_tdep: PRID_REGNUM = %d\n", PRID_REGNUM); - fprintf_unfiltered (file, - "mips_dump_tdep: PRINT_EXTRA_FRAME_INFO # %s\n", - XSTRING (PRINT_EXTRA_FRAME_INFO (FRAME))); fprintf_unfiltered (file, "mips_dump_tdep: PROC_DESC_IS_DUMMY = function?\n"); fprintf_unfiltered (file, @@ -6284,24 +6374,9 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) fprintf_unfiltered (file, "mips_dump_tdep: PS_REGNUM = %d\n", PS_REGNUM); - fprintf_unfiltered (file, - "mips_dump_tdep: PUSH_FP_REGNUM = %d\n", - PUSH_FP_REGNUM); fprintf_unfiltered (file, "mips_dump_tdep: RA_REGNUM = %d\n", RA_REGNUM); - fprintf_unfiltered (file, - "mips_dump_tdep: REGISTER_CONVERT_FROM_TYPE # %s\n", - XSTRING (REGISTER_CONVERT_FROM_TYPE (REGNUM, VALTYPE, RAW_BUFFER))); - fprintf_unfiltered (file, - "mips_dump_tdep: REGISTER_CONVERT_TO_TYPE # %s\n", - XSTRING (REGISTER_CONVERT_TO_TYPE (REGNUM, VALTYPE, RAW_BUFFER))); - fprintf_unfiltered (file, - "mips_dump_tdep: REGISTER_NAMES = delete?\n"); - fprintf_unfiltered (file, - "mips_dump_tdep: ROUND_DOWN = function?\n"); - fprintf_unfiltered (file, - "mips_dump_tdep: ROUND_UP = function?\n"); #ifdef SAVED_BYTES fprintf_unfiltered (file, "mips_dump_tdep: SAVED_BYTES = %d\n", @@ -6374,11 +6449,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) fprintf_unfiltered (file, "mips_dump_tdep: TARGET_HAS_HARDWARE_WATCHPOINTS # %s\n", XSTRING (TARGET_HAS_HARDWARE_WATCHPOINTS)); - fprintf_unfiltered (file, - "mips_dump_tdep: TARGET_MIPS = used?\n"); - fprintf_unfiltered (file, - "mips_dump_tdep: TM_PRINT_INSN_MACH # %s\n", - XSTRING (TM_PRINT_INSN_MACH)); #ifdef TRACE_CLEAR fprintf_unfiltered (file, "mips_dump_tdep: TRACE_CLEAR # %s\n", @@ -6399,8 +6469,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) "mips_dump_tdep: TRACE_SET # %s\n", XSTRING (TRACE_SET (X,STATE))); #endif - fprintf_unfiltered (file, - "mips_dump_tdep: UNMAKE_MIPS16_ADDR = function?\n"); #ifdef UNUSED_REGNUM fprintf_unfiltered (file, "mips_dump_tdep: UNUSED_REGNUM = %d\n", @@ -6412,11 +6480,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) fprintf_unfiltered (file, "mips_dump_tdep: VM_MIN_ADDRESS = %ld\n", (long) VM_MIN_ADDRESS); -#ifdef VX_NUM_REGS - fprintf_unfiltered (file, - "mips_dump_tdep: VX_NUM_REGS = %d (used?)\n", - VX_NUM_REGS); -#endif fprintf_unfiltered (file, "mips_dump_tdep: ZERO_REGNUM = %d\n", ZERO_REGNUM); @@ -6425,6 +6488,8 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) _PROC_MAGIC_); } +extern initialize_file_ftype _initialize_mips_tdep; /* -Wmissing-prototypes */ + void _initialize_mips_tdep (void) { @@ -6437,8 +6502,6 @@ _initialize_mips_tdep (void) internal_error (__FILE__, __LINE__, "mips_abi_strings out of sync"); gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep); - if (!tm_print_insn) /* Someone may have already set it */ - tm_print_insn = gdb_print_insn_mips; /* Add root prefix command for all "set mips"/"show mips" commands */ add_prefix_cmd ("mips", no_class, set_mips_command, @@ -6491,8 +6554,9 @@ This option can be set to one of:\n\ " eabi32\n" " eabi64", &setmipscmdlist); - add_show_from_set (c, &showmipscmdlist); set_cmd_sfunc (c, mips_abi_update); + add_cmd ("abi", class_obscure, show_mips_abi, + "Show ABI in use by MIPS target", &showmipscmdlist); /* Let the user turn off floating point and set the fence post for heuristic_proc_start. */