*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index 05ba0664ffa47465100e79c976982e206fe5e32c..c56d97e474a2bb8d3803848eee2ad017038ff8e8 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
 
-   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001 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.
@@ -37,6 +37,7 @@
 #include "gdbtypes.h"
 #include "target.h"
 #include "arch-utils.h"
+#include "regcache.h"
 
 #include "opcode/mips.h"
 #include "elf/mips.h"
@@ -419,6 +420,11 @@ mips_register_raw_size (int reg_nr)
 {
   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;
   else
     return MIPS_REGSIZE;
 }
@@ -477,7 +483,8 @@ mips_mask_address_p (void)
     case CMD_AUTO_BOOLEAN_AUTO:
       return MIPS_DEFAULT_MASK_ADDRESS_P;
     default:
-      internal_error ("mips_mask_address_p: bad switch");
+      internal_error (__FILE__, __LINE__,
+                     "mips_mask_address_p: bad switch");
       return -1;
     }      
 }
@@ -498,7 +505,8 @@ show_mask_address (char *cmd, int from_tty)
                       mips_mask_address_p () ? "enabled" : "disabled");
       break;
     default:
-      internal_error ("show_mask_address: bad switch");
+      internal_error (__FILE__, __LINE__,
+                     "show_mask_address: bad switch");
       break;
     }      
 }
@@ -538,9 +546,9 @@ pc_is_mips16 (bfd_vma memaddr)
    all registers should be sign extended for simplicity? */
 
 static CORE_ADDR
-mips_read_pc (int pid)
+mips_read_pc (ptid_t ptid)
 {
-  return read_signed_register_pid (PC_REGNUM, pid);
+  return read_signed_register_pid (PC_REGNUM, ptid);
 }
 
 /* This returns the PC of the first inst after the prologue.  If we can't
@@ -982,7 +990,8 @@ unpack_mips16 (CORE_ADDR pc,
        break;
       }
     default:
-      internal_error ("%s:%d: bad switch", __FILE__, __LINE__);
+      internal_error (__FILE__, __LINE__,
+                     "bad switch");
     }
   upk->offset = offset;
   upk->regx = regx;
@@ -1331,7 +1340,7 @@ read_next_frame_reg (struct frame_info *fi, int regno)
 
 /* mips_addr_bits_remove - remove useless address bits  */
 
-CORE_ADDR
+static CORE_ADDR
 mips_addr_bits_remove (CORE_ADDR addr)
 {
   if (GDB_TARGET_IS_MIPS64)
@@ -1370,7 +1379,7 @@ mips_addr_bits_remove (CORE_ADDR addr)
   return addr;
 }
 
-void
+static void
 mips_init_frame_pc_first (int fromleaf, struct frame_info *prev)
 {
   CORE_ADDR pc, tmp;
@@ -2184,8 +2193,8 @@ mips_push_arguments (int nargs,
          don't use float registers for arguments.  This duplication of
          arguments in general registers can't hurt non-MIPS16 functions
          because those registers are normally skipped.  */
-      /* MIPS_EABI squeeses a struct that contains a single floating
-         point value into an FP register instead of pusing it onto the
+      /* MIPS_EABI squeezes a struct that contains a single floating
+         point value into an FP register instead of pushing it onto the
          stack. */
       if (fp_register_arg_p (typecode, arg_type)
          && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
@@ -2669,12 +2678,25 @@ do_fp_register_row (int regnum)
       flt2 = unpack_double (builtin_type_float, raw_buffer[LO], &inv2);
       doub = unpack_double (builtin_type_double, dbl_buffer, &inv3);
 
-      printf_filtered (inv1 ? " %-5s: <invalid float>" :
-                      " %-5s%-17.9g", REGISTER_NAME (regnum), flt1);
-      printf_filtered (inv2 ? " %-5s: <invalid float>" :
-                      " %-5s%-17.9g", REGISTER_NAME (regnum + 1), flt2);
-      printf_filtered (inv3 ? " dbl: <invalid double>\n" :
-                      " dbl: %-24.17g\n", doub);
+      printf_filtered (" %-5s", REGISTER_NAME (regnum));
+      if (inv1)
+       printf_filtered (": <invalid float>");
+      else
+       printf_filtered ("%-17.9g", flt1);
+
+      printf_filtered (" %-5s", REGISTER_NAME (regnum + 1));
+      if (inv2)
+       printf_filtered (": <invalid float>");
+      else
+       printf_filtered ("%-17.9g", flt2);
+
+      printf_filtered (" dbl: ");
+      if (inv3)
+       printf_filtered ("<invalid double>");
+      else
+       printf_filtered ("%-24.17g", doub);
+      printf_filtered ("\n");
+
       /* may want to do hex display here (future enhancement) */
       regnum += 2;
     }
@@ -2687,10 +2709,19 @@ do_fp_register_row (int regnum)
                            &raw_buffer[HI][offset], &inv1);
       doub = unpack_double (builtin_type_double, dbl_buffer, &inv3);
 
-      printf_filtered (inv1 ? " %-5s: <invalid float>" :
-                      " %-5s flt: %-17.9g", REGISTER_NAME (regnum), flt1);
-      printf_filtered (inv3 ? " dbl: <invalid double>\n" :
-                      " dbl: %-24.17g\n", doub);
+      printf_filtered (" %-5s: ", REGISTER_NAME (regnum));
+      if (inv1)
+       printf_filtered ("<invalid float>");
+      else
+       printf_filtered ("flt: %-17.9g", flt1);
+
+      printf_filtered (" dbl: ");
+      if (inv3)
+       printf_filtered ("<invalid double>");
+      else
+       printf_filtered ("%-24.17g", doub);
+
+      printf_filtered ("\n");
       /* may want to do hex display here (future enhancement) */
       regnum++;
     }
@@ -3178,7 +3209,7 @@ mips_extract_return_value (struct type *valtype,
 {
   struct return_value_word lo;
   struct return_value_word hi;
-  return_value_location (valtype, &lo, &hi);
+  return_value_location (valtype, &hi, &lo);
 
   memcpy (valbuf + lo.buf_offset,
          regbuf + REGISTER_BYTE (lo.reg) + lo.reg_offset,
@@ -3199,7 +3230,7 @@ mips_store_return_value (struct type *valtype, char *valbuf)
   char raw_buffer[MAX_REGISTER_RAW_SIZE];
   struct return_value_word lo;
   struct return_value_word hi;
-  return_value_location (valtype, &lo, &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);
@@ -3248,7 +3279,6 @@ set_mips_command (char *args, int from_tty)
 static void
 show_mipsfpu_command (char *args, int from_tty)
 {
-  char *msg;
   char *fpu;
   switch (MIPS_FPU_TYPE)
     {
@@ -3261,6 +3291,8 @@ show_mipsfpu_command (char *args, int from_tty)
     case MIPS_FPU_NONE:
       fpu = "absent (none)";
       break;
+    default:
+      internal_error (__FILE__, __LINE__, "bad switch");
     }
   if (mips_fpu_type_auto)
     printf_unfiltered ("The MIPS floating-point coprocessor is set automatically (currently %s)\n",
@@ -3354,7 +3386,7 @@ mips_show_processor_type_command (char *args, int from_tty)
 int
 mips_set_processor_type (char *str)
 {
-  int i, j;
+  int i;
 
   if (str == NULL)
     return 0;
@@ -3460,16 +3492,17 @@ mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
     {
       if (pc_is_mips16 (*pcptr))
        {
-         static char mips16_big_breakpoint[] = MIPS16_BIG_BREAKPOINT;
+         static unsigned char mips16_big_breakpoint[] =
+           MIPS16_BIG_BREAKPOINT;
          *pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
          *lenptr = sizeof (mips16_big_breakpoint);
          return mips16_big_breakpoint;
        }
       else
        {
-         static char big_breakpoint[] = BIG_BREAKPOINT;
-         static char pmon_big_breakpoint[] = PMON_BIG_BREAKPOINT;
-         static char idt_big_breakpoint[] = IDT_BIG_BREAKPOINT;
+         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;
 
          *lenptr = sizeof (big_breakpoint);
 
@@ -3487,16 +3520,19 @@ mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
     {
       if (pc_is_mips16 (*pcptr))
        {
-         static char mips16_little_breakpoint[] = MIPS16_LITTLE_BREAKPOINT;
+         static unsigned char mips16_little_breakpoint[] =
+           MIPS16_LITTLE_BREAKPOINT;
          *pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
          *lenptr = sizeof (mips16_little_breakpoint);
          return mips16_little_breakpoint;
        }
       else
        {
-         static char little_breakpoint[] = LITTLE_BREAKPOINT;
-         static char pmon_little_breakpoint[] = PMON_LITTLE_BREAKPOINT;
-         static char idt_little_breakpoint[] = IDT_LITTLE_BREAKPOINT;
+         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;
 
          *lenptr = sizeof (little_breakpoint);
 
@@ -3835,6 +3871,12 @@ mips_gdbarch_init (struct gdbarch_info info,
   int elf_flags;
   enum mips_abi mips_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;
+
   /* Extract the elf_flags if available */
   if (info.abfd != NULL
       && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
@@ -3879,6 +3921,10 @@ mips_gdbarch_init (struct gdbarch_info info,
        case bfd_mach_mips5000:
          mips_abi = MIPS_ABI_EABI64;
          break;
+       case bfd_mach_mips8000:
+       case bfd_mach_mips10000:
+         mips_abi = MIPS_ABI_N32;
+         break;
        }
     }
 #ifdef MIPS_DEFAULT_ABI
@@ -3922,6 +3968,7 @@ mips_gdbarch_init (struct gdbarch_info info,
   set_gdbarch_double_bit (gdbarch, 64);
   set_gdbarch_long_double_bit (gdbarch, 64);
   tdep->mips_abi = mips_abi;
+
   switch (mips_abi)
     {
     case MIPS_ABI_O32:
@@ -3967,7 +4014,7 @@ mips_gdbarch_init (struct gdbarch_info info,
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
     case MIPS_ABI_EABI64:
-       tdep->mips_abi_string = "eabi64";
+      tdep->mips_abi_string = "eabi64";
       tdep->mips_default_saved_regsize = 8;
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
@@ -3993,6 +4040,17 @@ 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;
       break;
     default:
       tdep->mips_abi_string = "default";
@@ -4065,6 +4123,15 @@ mips_gdbarch_init (struct gdbarch_info info,
   set_gdbarch_read_sp (gdbarch, generic_target_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. */
+  set_gdbarch_addr_bits_remove (gdbarch, mips_addr_bits_remove);
+
+  /* There's a mess in stack frame creation.  See comments in
+     blockframe.c near reference to INIT_FRAME_PC_FIRST.  */
+  set_gdbarch_init_frame_pc_first (gdbarch, mips_init_frame_pc_first);
+  set_gdbarch_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);
@@ -4126,9 +4193,10 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
          ef_mips_arch = 3;
          break;
        case E_MIPS_ARCH_4:
-         ef_mips_arch = 0;
+         ef_mips_arch = 4;
          break;
        default:
+         ef_mips_arch = 0;
          break;
        }
       /* determine the size of a pointer */
@@ -4265,12 +4333,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: IGNORE_HELPER_CALL # %s\n",
                      XSTRING (IGNORE_HELPER_CALL (PC)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: INIT_FRAME_PC # %s\n",
-                     XSTRING (INIT_FRAME_PC (FROMLEAF, PREV)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: INIT_FRAME_PC_FIRST # %s\n",
-                     XSTRING (INIT_FRAME_PC_FIRST (FROMLEAF, PREV)));
   fprintf_unfiltered (file,
                      "mips_dump_tdep: IN_SIGTRAMP # %s\n",
                      XSTRING (IN_SIGTRAMP (PC, NAME)));
@@ -4439,11 +4501,8 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
                      "mips_dump_tdep: SOFTWARE_SINGLE_STEP # %s\n",
                      XSTRING (SOFTWARE_SINGLE_STEP (SIG, BP_P)));
   fprintf_unfiltered (file,
-                     "mips_dump_tdep: SOFTWARE_SINGLE_STEP_P = %d\n",
-                     SOFTWARE_SINGLE_STEP_P);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: SOFTWARE_SINGLE_STEP_P = %d\n",
-                     SOFTWARE_SINGLE_STEP_P);
+                     "mips_dump_tdep: SOFTWARE_SINGLE_STEP_P () = %d\n",
+                     SOFTWARE_SINGLE_STEP_P ());
   fprintf_unfiltered (file,
                      "mips_dump_tdep: STAB_REG_TO_REGNUM # %s\n",
                      XSTRING (STAB_REG_TO_REGNUM (REGNUM)));
This page took 0.031656 seconds and 4 git commands to generate.