Tue Jun 23 11:14:04 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
authorMichael Snyder <msnyder@vmware.com>
Tue, 23 Jun 1998 18:22:43 +0000 (18:22 +0000)
committerMichael Snyder <msnyder@vmware.com>
Tue, 23 Jun 1998 18:22:43 +0000 (18:22 +0000)
* 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
gdb/config/mips/tm-irix5.h
gdb/irix5-nat.c
gdb/mips-tdep.c

index 6be91502c3e6c4eb30572a71160c71ce765aab26..e9eaf2c5b442d7d7f18be6eefae002d293fefc2a 100644 (file)
@@ -1,3 +1,17 @@
+Tue Jun 23 11:14:04 1998  Michael Snyder  <msnyder@cleaver.cygnus.com>
+
+       * 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  <jillian@cygnus.com>
 
         * configure.in: Add -lXext to mips_extra_libs
index d70afd57c01be4680cdbef754b5aaefe1a3d9a93..ad98e881859821641733d05ae8eec7720ff1cb1c 100644 (file)
@@ -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.  */
index 6ea5deafed7b4a489792eda3921b25fd337d07b7..88bbf96e102e6154f6af6e7040560b413f853ca7 100644 (file)
@@ -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
            {
index 41dc0cad017d4cc4e3ee852e9764505f9c048cdd..ec0fa969e79253d68d96fff46573d276b24423ee 100644 (file)
@@ -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;