From a00dfa360a4115f6f1c698b501018c8a21c020ec Mon Sep 17 00:00:00 2001 From: Michael Snyder Date: Tue, 23 Jun 1998 18:22:43 +0000 Subject: [PATCH] Tue Jun 23 11:14:04 1998 Michael Snyder * config/mips/tm-irix5.h: Modify to work better on irix 6, by making FP registers 8 bytes instead of 4. REGISTER_BYTES: redefine. REGISTER_BYTE(): redefine. REGISTER_VIRTUAL_TYPE: redefine. MIPS_LAST_ARG_REGNUM: redefine. * irix5-nat.c (fetch_core_registers): read 8 bytes per FP register. * mips-tdep.c (FP_REGISTER_DOUBLE): new macro to distinguish targets with 8-byte FP registers (don't use TARGET_MIPS64). (STACK_ARGSIZE): new macro, how much space is taken up on the stack for each function argument (don't use TARGET_MIPS64). (mips_push_arguments): modify logic to work better on Irix 6 (n32 ABI). --- gdb/ChangeLog | 14 +++++++ gdb/config/mips/tm-irix5.h | 31 +++++++++++++++ gdb/irix5-nat.c | 18 ++++++++- gdb/mips-tdep.c | 78 ++++++++++++++++++++++++++++++-------- 4 files changed, 123 insertions(+), 18 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6be91502c3e..e9eaf2c5b44 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +Tue Jun 23 11:14:04 1998 Michael Snyder + + * config/mips/tm-irix5.h: Modify to work better on irix 6, by + making FP registers 8 bytes instead of 4. + REGISTER_BYTES: redefine. REGISTER_BYTE(): redefine. + REGISTER_VIRTUAL_TYPE: redefine. MIPS_LAST_ARG_REGNUM: redefine. + * irix5-nat.c (fetch_core_registers): read 8 bytes per FP register. + * mips-tdep.c (FP_REGISTER_DOUBLE): new macro to distinguish + targets with 8-byte FP registers (don't use TARGET_MIPS64). + (STACK_ARGSIZE): new macro, how much space is taken up on the + stack for each function argument (don't use TARGET_MIPS64). + (mips_push_arguments): modify logic to work better on Irix 6 + (n32 ABI). + Tue Jun 23 12:29:53 1998 Jillian Ye * configure.in: Add -lXext to mips_extra_libs diff --git a/gdb/config/mips/tm-irix5.h b/gdb/config/mips/tm-irix5.h index d70afd57c01..ad98e881859 100644 --- a/gdb/config/mips/tm-irix5.h +++ b/gdb/config/mips/tm-irix5.h @@ -19,6 +19,37 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "mips/tm-irix3.h" +#if defined (_MIPS_SIM_NABI32) && _MIPS_SIM == _MIPS_SIM_NABI32 +/* + * Irix 6 (n32 ABI) has 32-bit GP regs and 64-bit FP regs + */ + +#undef REGISTER_BYTES +#define REGISTER_BYTES (MIPS_NUMREGS * 8 + (NUM_REGS - MIPS_NUMREGS) * MIPS_REGSIZE) + +#undef REGISTER_BYTE +#define REGISTER_BYTE(N) \ + (((N) < FP0_REGNUM) ? (N) * MIPS_REGSIZE : \ + ((N) < FP0_REGNUM + 32) ? \ + FP0_REGNUM * MIPS_REGSIZE + \ + ((N) - FP0_REGNUM) * sizeof(double) : \ + 32 * sizeof(double) + ((N) - 32) * MIPS_REGSIZE) + +#undef REGISTER_VIRTUAL_TYPE +#define REGISTER_VIRTUAL_TYPE(N) \ + (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) ? builtin_type_double \ + : ((N) == 32 /*SR*/) ? builtin_type_uint32 \ + : ((N) >= 70 && (N) <= 89) ? builtin_type_uint32 \ + : builtin_type_int) + +#undef MIPS_LAST_ARG_REGNUM +#define MIPS_LAST_ARG_REGNUM 11 /* N32 uses R4 through R11 for args */ + +#undef MIPS_NUM_ARG_REGS +#define MIPS_NUM_ARG_REGS 8 + +#endif /* N32 */ + /* When calling functions on Irix 5 (or any MIPS SVR4 ABI compliant platform) $25 must hold the function address. Dest_Reg is a macro used in CALL_DUMMY in tm-mips.h. */ diff --git a/gdb/irix5-nat.c b/gdb/irix5-nat.c index 6ea5deafed7..88bbf96e102 100644 --- a/gdb/irix5-nat.c +++ b/gdb/irix5-nat.c @@ -192,7 +192,8 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) { memcpy ((char *)registers, core_reg_sect, core_reg_size); } - else if (core_reg_size == (2 * REGISTER_BYTES) && MIPS_REGSIZE == 4) + else if (MIPS_REGSIZE == 4 && + core_reg_size == (2 * MIPS_REGSIZE) * NUM_REGS) { /* This is a core file from a N32 executable, 64 bits are saved for all registers. */ @@ -210,7 +211,20 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) *dstp++ = *srcp++; *dstp++ = *srcp++; *dstp++ = *srcp++; - srcp += 4; + if (REGISTER_RAW_SIZE(regno) == 4) + { + /* copying 4 bytes from eight bytes? + I don't see how this can be right... */ + srcp += 4; + } + else + { + /* copy all 8 bytes (sizeof(double)) */ + *dstp++ = *srcp++; + *dstp++ = *srcp++; + *dstp++ = *srcp++; + *dstp++ = *srcp++; + } } else { diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 41dc0cad017..ec0fa969e79 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -1,5 +1,5 @@ /* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger. - Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 + Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin. @@ -38,6 +38,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define VM_MIN_ADDRESS (CORE_ADDR)0x400000 +/* Do not use "TARGET_IS_MIPS64" to test the size of floating point registers */ +#define FP_REGISTER_DOUBLE (REGISTER_VIRTUAL_SIZE(FP0_REGNUM) == 8) + /* FIXME: Put this declaration in frame.h. */ extern struct obstack frame_cache_obstack; @@ -282,6 +285,9 @@ mips32_decode_reg_save (inst, gen_mask, float_mask) if ((inst & 0xffe00000) == 0xafa00000 /* sw reg,n($sp) */ || (inst & 0xffe00000) == 0xafc00000 /* sw reg,n($r30) */ + /* start-sanitize-r5900 */ + || (inst & 0xffe00000) == 0x7fa00000 /* sq reg,n($sp) */ + /* end-sanitize-r5900 */ || (inst & 0xffe00000) == 0xffa00000) /* sd reg,n($sp) */ { /* It might be possible to use the instruction to @@ -916,6 +922,15 @@ mips_find_saved_regs (fci) { fci->saved_regs->regs[ireg] = reg_position; reg_position -= MIPS_REGSIZE; + /* start-sanitize-r5900 */ +#ifdef R5900_128BIT_GPR_HACK + /* Gross. The r5900 has 128bit wide registers, but MIPS_REGSIZE is + still 64bits. See the comments in tm.h for a discussion of the + various problems this causes. */ + if (ireg <= RA_REGNUM) + reg_position -= MIPS_REGSIZE; +#endif + /* end-sanitize-r5900 */ } /* The MIPS16 entry instruction saves $s0 and $s1 in the reverse order @@ -1395,6 +1410,15 @@ restart: PROC_REG_MASK(&temp_proc_desc) |= 1 << reg; set_reg_offset (reg, sp + low_word + 8 - MIPS_REGSIZE); } + /* start-sanitize-r5900 */ + else if ((high_word & 0xFFE0) == 0x7fa0) /* sq reg,offset($sp) */ + { + /* I don't think we have to worry about the Irix 6.2 N32 ABI + issue noted int he sd reg, offset($sp) case above. */ + PROC_REG_MASK(&temp_proc_desc) |= 1 << reg; + set_reg_offset (reg, sp + low_word); + } + /* end-sanitize-r5900 */ else if (high_word == 0x27be) /* addiu $30,$sp,size */ { /* Old gcc frame, r30 is virtual frame pointer. */ @@ -1708,6 +1732,20 @@ setup_arbitrary_frame (argc, argv) return create_new_frame (argv[0], argv[1]); } +/* + * STACK_ARGSIZE -- how many bytes does a pushed function arg take up on the stack? + * + * For n32 ABI, eight. + * For all others, he same as the size of a general register. + */ +#if defined (_MIPS_SIM_NABI32) && _MIPS_SIM == _MIPS_SIM_NABI32 +#define MIPS_NABI32 1 +#define STACK_ARGSIZE 8 +#else +#define MIPS_NABI32 0 +#define STACK_ARGSIZE MIPS_REGSIZE +#endif + CORE_ADDR mips_push_arguments(nargs, args, sp, struct_return, struct_addr) int nargs; @@ -1775,7 +1813,7 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr) /* 32-bit ABIs always start floating point arguments in an even-numbered floating point register. */ - if (!GDB_TARGET_IS_MIPS64 && typecode == TYPE_CODE_FLT + if (!FP_REGISTER_DOUBLE && typecode == TYPE_CODE_FLT && (float_argreg & 1)) float_argreg++; @@ -1792,7 +1830,7 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr) && float_argreg <= MIPS_LAST_FP_ARG_REGNUM && mips_fpu != MIPS_FPU_NONE) { - if (!GDB_TARGET_IS_MIPS64 && len == 8) + if (!FP_REGISTER_DOUBLE && len == 8) { int low_offset = TARGET_BYTE_ORDER == BIG_ENDIAN ? 4 : 0; unsigned long regval; @@ -1822,7 +1860,7 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr) if (!MIPS_EABI) { write_register (argreg, regval); - argreg += GDB_TARGET_IS_MIPS64 ? 1 : 2; + argreg += FP_REGISTER_DOUBLE ? 1 : 2; } } } @@ -1850,15 +1888,15 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr) int longword_offset = 0; if (TARGET_BYTE_ORDER == BIG_ENDIAN) - if (MIPS_REGSIZE == 8 && + if (STACK_ARGSIZE == 8 && (typecode == TYPE_CODE_INT || typecode == TYPE_CODE_PTR || typecode == TYPE_CODE_FLT) && len <= 4) - longword_offset = MIPS_REGSIZE - len; + longword_offset = STACK_ARGSIZE - len; else if ((typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION) && - TYPE_LENGTH (arg_type) < MIPS_REGSIZE) - longword_offset = MIPS_REGSIZE - len; + TYPE_LENGTH (arg_type) < STACK_ARGSIZE) + longword_offset = STACK_ARGSIZE - len; write_memory (sp + stack_offset + longword_offset, val, partial_len); @@ -1907,12 +1945,14 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr) begins at (4 * MIPS_REGSIZE) in the old ABI. This leaves room for the "home" area for register parameters. - In the new EABI, the 8 register parameters do not - have "home" stack space reserved for them, so the + In the new EABI (and the NABI32), the 8 register parameters + do not have "home" stack space reserved for them, so the stack offset does not get incremented until after we have used up the 8 parameter registers. */ - if (!(MIPS_EABI && argnum < 8)) - stack_offset += ROUND_UP (partial_len, MIPS_REGSIZE); + + if (!(MIPS_EABI || MIPS_NABI32) || + argnum >= 8) + stack_offset += ROUND_UP (partial_len, STACK_ARGSIZE); } } } @@ -1990,7 +2030,8 @@ mips_push_dummy_frame() /* Save general CPU registers */ PROC_REG_MASK(proc_desc) = GEN_REG_SAVE_MASK; - PROC_REG_OFFSET(proc_desc) = sp - old_sp; /* offset of (Saved R31) from FP */ + /* PROC_REG_OFFSET is the offset of the first saved register from FP. */ + PROC_REG_OFFSET(proc_desc) = sp - old_sp - MIPS_REGSIZE; for (ireg = 32; --ireg >= 0; ) if (PROC_REG_MASK(proc_desc) & (1 << ireg)) mips_push_register (&sp, ireg); @@ -1999,7 +2040,9 @@ mips_push_dummy_frame() PROC_FREG_MASK(proc_desc) = mips_fpu == MIPS_FPU_DOUBLE ? FLOAT_REG_SAVE_MASK : mips_fpu == MIPS_FPU_SINGLE ? FLOAT_SINGLE_REG_SAVE_MASK : 0; - PROC_FREG_OFFSET(proc_desc) = sp - old_sp; /* offset of (Saved D18) from FP */ + /* 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); @@ -2086,7 +2129,7 @@ mips_print_register (regnum, all) /* If an even floating point register, also print as double. */ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT && !((regnum-FP0_REGNUM) & 1)) - if (REGISTER_RAW_SIZE(regnum) == 4) /* this would be silly on MIPS64 */ + if (REGISTER_RAW_SIZE(regnum) == 4) /* this would be silly on MIPS64 or N32 (Irix 6) */ { char dbuffer[2 * MAX_REGISTER_RAW_SIZE]; @@ -2112,7 +2155,7 @@ mips_print_register (regnum, all) /* 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) + if (FP_REGISTER_DOUBLE) { /* show 8-byte floats as float AND double: */ int offset = 4 * (TARGET_BYTE_ORDER == BIG_ENDIAN); @@ -2387,6 +2430,9 @@ mips32_skip_prologue (pc, lenient) inst == 0x03a8e823) /* subu $sp,$sp,$t0 */ seen_sp_adjust = 1; else if (((inst & 0xFFE00000) == 0xAFA00000 /* sw reg,n($sp) */ + /* start-sanitize-r5900 */ + || (inst & 0xFFE00000) == 0x7FA00000 /* sq reg,n($sp) */ + /* end-sanitize-r5900 */ || (inst & 0xFFE00000) == 0xFFA00000) /* sd reg,n($sp) */ && (inst & 0x001F0000)) /* reg != $zero */ continue;