* rs6000-tdep.c (gdb_print_insn_powerpc): Get the current endianess
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 9cb560a169e065fa6c6b73486c406ac7554edff9..fc12619a7b06ecec9da7e01845672681c0291402 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-dependent code for GDB, the GNU debugger.
 
    Copyright (C) 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 #include "features/rs6000/powerpc-e500.c"
 #include "features/rs6000/rs6000.c"
 
+/* Determine if regnum is an SPE pseudo-register.  */
+#define IS_SPE_PSEUDOREG(tdep, regnum) ((tdep)->ppc_ev0_regnum >= 0 \
+    && (regnum) >= (tdep)->ppc_ev0_regnum \
+    && (regnum) < (tdep)->ppc_ev0_regnum + 32)
+
+/* Determine if regnum is a decimal float pseudo-register.  */
+#define IS_DFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_dl0_regnum >= 0 \
+    && (regnum) >= (tdep)->ppc_dl0_regnum \
+    && (regnum) < (tdep)->ppc_dl0_regnum + 16)
+
 /* The list of available "set powerpc ..." and "show powerpc ..."
    commands.  */
 static struct cmd_list_element *setpowerpccmdlist = NULL;
@@ -157,14 +167,14 @@ CORE_ADDR (*rs6000_find_toc_address_hook) (CORE_ADDR) = NULL;
 
 static CORE_ADDR branch_dest (struct frame_info *frame, int opcode,
                              int instr, CORE_ADDR pc, CORE_ADDR safety);
-static CORE_ADDR skip_prologue (CORE_ADDR, CORE_ADDR,
+static CORE_ADDR skip_prologue (struct gdbarch *, CORE_ADDR, CORE_ADDR,
                                 struct rs6000_framedata *);
 
 /* Is REGNO an AltiVec register?  Return 1 if so, 0 otherwise.  */
 int
-altivec_register_p (int regno)
+altivec_register_p (struct gdbarch *gdbarch, int regno)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   if (tdep->ppc_vr0_regnum < 0 || tdep->ppc_vrsave_regnum < 0)
     return 0;
   else
@@ -174,14 +184,12 @@ altivec_register_p (int regno)
 
 /* Return true if REGNO is an SPE register, false otherwise.  */
 int
-spe_register_p (int regno)
+spe_register_p (struct gdbarch *gdbarch, int regno)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   
   /* Is it a reference to EV0 -- EV31, and do we have those?  */
-  if (tdep->ppc_ev0_regnum >= 0
-      && tdep->ppc_ev31_regnum >= 0
-      && tdep->ppc_ev0_regnum <= regno && regno <= tdep->ppc_ev31_regnum)
+  if (IS_SPE_PSEUDOREG (tdep, regno))
     return 1;
 
   /* Is it a reference to one of the raw upper GPR halves?  */
@@ -342,17 +350,17 @@ init_sim_regno_table (struct gdbarch *arch)
 /* Given a GDB register number REG, return the corresponding SIM
    register number.  */
 static int
-rs6000_register_sim_regno (int reg)
+rs6000_register_sim_regno (struct gdbarch *gdbarch, int reg)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int sim_regno;
 
   if (tdep->sim_regno == NULL)
-    init_sim_regno_table (current_gdbarch);
+    init_sim_regno_table (gdbarch);
 
   gdb_assert (0 <= reg 
-             && reg <= gdbarch_num_regs (current_gdbarch)
-                       + gdbarch_num_pseudo_regs (current_gdbarch));
+             && reg <= gdbarch_num_regs (gdbarch)
+                       + gdbarch_num_pseudo_regs (gdbarch));
   sim_regno = tdep->sim_regno[reg];
 
   if (sim_regno >= 0)
@@ -754,7 +762,7 @@ read_memory_addr (CORE_ADDR memaddr, int len)
 }
 
 static CORE_ADDR
-rs6000_skip_prologue (CORE_ADDR pc)
+rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   struct rs6000_framedata frame;
   CORE_ADDR limit_pc, func_addr;
@@ -779,7 +787,7 @@ rs6000_skip_prologue (CORE_ADDR pc)
   if (limit_pc == 0)
     limit_pc = pc + 100;          /* Magic.  */
 
-  pc = skip_prologue (pc, limit_pc, &frame);
+  pc = skip_prologue (gdbarch, pc, limit_pc, &frame);
   return pc;
 }
 
@@ -1251,7 +1259,8 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
  */
 
 static CORE_ADDR
-skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
+skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
+              struct rs6000_framedata *fdata)
 {
   CORE_ADDR orig_pc = pc;
   CORE_ADDR last_prologue_pc = pc;
@@ -1272,8 +1281,8 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
   int prev_insn_was_prologue_insn = 1;
   int num_skip_non_prologue_insns = 0;
   int r0_contains_arg = 0;
-  const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   memset (fdata, 0, sizeof (struct rs6000_framedata));
   fdata->saved_gpr = -1;
@@ -2370,9 +2379,7 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno)
     return "";
 
   /* Check if the SPE pseudo registers are available.  */
-  if (tdep->ppc_ev0_regnum >= 0
-      && tdep->ppc_ev0_regnum <= regno
-      && regno < tdep->ppc_ev0_regnum + ppc_num_gprs)
+  if (IS_SPE_PSEUDOREG (tdep, regno))
     {
       static const char *const spe_regnames[] = {
        "ev0", "ev1", "ev2", "ev3", "ev4", "ev5", "ev6", "ev7",
@@ -2383,6 +2390,18 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno)
       return spe_regnames[regno - tdep->ppc_ev0_regnum];
     }
 
+  /* Check if the decimal128 pseudo-registers are available.  */
+  if (IS_DFP_PSEUDOREG (tdep, regno))
+    {
+      static const char *const dfp128_regnames[] = {
+       "dl0", "dl1", "dl2", "dl3",
+       "dl4", "dl5", "dl6", "dl7",
+       "dl8", "dl9", "dl10", "dl11",
+       "dl12", "dl13", "dl14", "dl15"
+      };
+      return dfp128_regnames[regno - tdep->ppc_dl0_regnum];
+    }
+
   return tdesc_register_name (gdbarch, regno);
 }
 
@@ -2395,11 +2414,15 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   /* These are the only pseudo-registers we support.  */
-  gdb_assert (tdep->ppc_ev0_regnum >= 0
-             && regnum >= tdep->ppc_ev0_regnum
-             && regnum < tdep->ppc_ev0_regnum + 32);
+  gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
+             || IS_DFP_PSEUDOREG (tdep, regnum));
 
-  return rs6000_builtin_type_vec64 (gdbarch);
+  /* These are the e500 pseudo-registers.  */
+  if (IS_SPE_PSEUDOREG (tdep, regnum))
+    return rs6000_builtin_type_vec64 (gdbarch);
+  else
+    /* Could only be the ppc decimal128 pseudo-registers.  */
+    return builtin_type (gdbarch)->builtin_declong;
 }
 
 /* Is REGNUM a member of REGGROUP?  */
@@ -2410,23 +2433,25 @@ rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   /* These are the only pseudo-registers we support.  */
-  gdb_assert (tdep->ppc_ev0_regnum >= 0
-             && regnum >= tdep->ppc_ev0_regnum
-             && regnum < tdep->ppc_ev0_regnum + 32);
+  gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
+             || IS_DFP_PSEUDOREG (tdep, regnum));
 
-  if (group == all_reggroup || group == vector_reggroup)
-    return 1;
+  /* These are the e500 pseudo-registers.  */
+  if (IS_SPE_PSEUDOREG (tdep, regnum))
+    return group == all_reggroup || group == vector_reggroup;
   else
-    return 0;
+    /* Could only be the ppc decimal128 pseudo-registers.  */
+    return group == all_reggroup || group == float_reggroup;
 }
 
 /* The register format for RS/6000 floating point registers is always
    double, we need a conversion if the memory format is float.  */
 
 static int
-rs6000_convert_register_p (int regnum, struct type *type)
+rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum,
+                          struct type *type)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   return (tdep->ppc_fp0_regnum >= 0
          && regnum >= tdep->ppc_fp0_regnum
@@ -2497,8 +2522,7 @@ e500_move_ev_register (void (*move) (struct regcache *regcache,
   int reg_index;
   gdb_byte *byte_buffer = buffer;
 
-  gdb_assert (tdep->ppc_ev0_regnum <= ev_reg
-              && ev_reg < tdep->ppc_ev0_regnum + ppc_num_gprs);
+  gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
 
   reg_index = ev_reg - tdep->ppc_ev0_regnum;
 
@@ -2517,48 +2541,118 @@ e500_move_ev_register (void (*move) (struct regcache *regcache,
 static void
 e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
+{
+  e500_move_ev_register (regcache_raw_read, regcache, reg_nr, buffer);
+}
+
+static void
+e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+                           int reg_nr, const gdb_byte *buffer)
+{
+  e500_move_ev_register ((void (*) (struct regcache *, int, gdb_byte *))
+                        regcache_raw_write,
+                        regcache, reg_nr, (gdb_byte *) buffer);
+}
+
+/* Read method for PPC pseudo-registers. Currently this is handling the
+   16 decimal128 registers that map into 16 pairs of FP registers.  */
+static void
+ppc_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+                          int reg_nr, gdb_byte *buffer)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+
+  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+    {
+      /* Read two FP registers to form a whole dl register.  */
+      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+                        2 * reg_index, buffer);
+      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+                        2 * reg_index + 1, buffer + 8);
+    }
+  else
+    {
+      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+                        2 * reg_index + 1, buffer + 8);
+      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+                        2 * reg_index, buffer);
+    }
+}
+
+/* Write method for PPC pseudo-registers. Currently this is handling the
+   16 decimal128 registers that map into 16 pairs of FP registers.  */
+static void
+ppc_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+                           int reg_nr, const gdb_byte *buffer)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+
+  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+    {
+      /* Write each half of the dl register into a separate
+      FP register.  */
+      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+                         2 * reg_index, buffer);
+      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+                         2 * reg_index + 1, buffer + 8);
+    }
+  else
+    {
+      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+                         2 * reg_index + 1, buffer + 8);
+      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+                         2 * reg_index, buffer);
+    }
+}
+
+static void
+rs6000_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+                            int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch *regcache_arch = get_regcache_arch (regcache);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 
   gdb_assert (regcache_arch == gdbarch);
-  if (tdep->ppc_ev0_regnum <= reg_nr
-      && reg_nr < tdep->ppc_ev0_regnum + ppc_num_gprs)
-    e500_move_ev_register (regcache_raw_read, regcache, reg_nr, buffer);
+
+  if (IS_SPE_PSEUDOREG (tdep, reg_nr))
+    e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+  else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+    ppc_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else
     internal_error (__FILE__, __LINE__,
-                    _("e500_pseudo_register_read: "
-                    "called on unexpected register '%s' (%d)"),
-                    gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+                   _("rs6000_pseudo_register_read: "
+                   "called on unexpected register '%s' (%d)"),
+                   gdbarch_register_name (gdbarch, reg_nr), reg_nr);
 }
 
 static void
-e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
-                           int reg_nr, const gdb_byte *buffer)
+rs6000_pseudo_register_write (struct gdbarch *gdbarch,
+                             struct regcache *regcache,
+                             int reg_nr, const gdb_byte *buffer)
 {
   struct gdbarch *regcache_arch = get_regcache_arch (regcache);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 
   gdb_assert (regcache_arch == gdbarch);
-  if (tdep->ppc_ev0_regnum <= reg_nr
-      && reg_nr < tdep->ppc_ev0_regnum + ppc_num_gprs)
-    e500_move_ev_register ((void (*) (struct regcache *, int, gdb_byte *))
-                           regcache_raw_write,
-                           regcache, reg_nr, (gdb_byte *) buffer);
+
+  if (IS_SPE_PSEUDOREG (tdep, reg_nr))
+    e500_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
+  else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+    ppc_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
   else
     internal_error (__FILE__, __LINE__,
-                    _("e500_pseudo_register_read: "
-                    "called on unexpected register '%s' (%d)"),
-                    gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+                   _("rs6000_pseudo_register_write: "
+                   "called on unexpected register '%s' (%d)"),
+                   gdbarch_register_name (gdbarch, reg_nr), reg_nr);
 }
 
 /* Convert a DBX STABS register number to a GDB register number.  */
 static int
-rs6000_stab_reg_to_regnum (int num)
+rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (0 <= num && num <= 31)
     return tdep->ppc_gp0_regnum + num;
@@ -2598,9 +2692,9 @@ rs6000_stab_reg_to_regnum (int num)
 
 /* Convert a Dwarf 2 register number to a GDB register number.  */
 static int
-rs6000_dwarf2_reg_to_regnum (int num)
+rs6000_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (0 <= num && num <= 31)
     return tdep->ppc_gp0_regnum + num;
@@ -2835,7 +2929,7 @@ gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
   if (!info->disassembler_options)
     info->disassembler_options = "any";
 
-  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+  if (info->endian == BFD_ENDIAN_BIG)
     return print_insn_big_powerpc (memaddr, info);
   else
     return print_insn_little_powerpc (memaddr, info);
@@ -2881,7 +2975,7 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
 
   func = frame_func_unwind (next_frame, NORMAL_FRAME);
   pc = frame_pc_unwind (next_frame);
-  skip_prologue (func, pc, &fdata);
+  skip_prologue (gdbarch, func, pc, &fdata);
 
   /* Figure out the parent's stack pointer.  */
 
@@ -2984,7 +3078,7 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
 
   /* if != -1, fdata.saved_ev is the smallest number of saved_ev.
      All vr's from saved_ev to ev31 are saved. ????? */
-  if (tdep->ppc_ev0_regnum != -1 && tdep->ppc_ev31_regnum != -1)
+  if (tdep->ppc_ev0_regnum != -1)
     {
       if (fdata.saved_ev >= 0)
        {
@@ -3144,9 +3238,9 @@ ppc_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
     }
 
   /* Handle PC register and Stack Pointer correctly.  */
-  if (regnum == gdbarch_pc_regnum (current_gdbarch))
+  if (regnum == gdbarch_pc_regnum (gdbarch))
     reg->how = DWARF2_FRAME_REG_RA;
-  else if (regnum == gdbarch_sp_regnum (current_gdbarch))
+  else if (regnum == gdbarch_sp_regnum (gdbarch))
     reg->how = DWARF2_FRAME_REG_CFA;
 }
 
@@ -3172,11 +3266,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   enum auto_boolean soft_float_flag = powerpc_soft_float_global;
   int soft_float;
   enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
-  int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0;
+  int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0;
   int tdesc_wordsize = -1;
   const struct target_desc *tdesc = info.target_desc;
   struct tdesc_arch_data *tdesc_data = NULL;
-  int num_sprs = 0;
+  int num_pseudoregs = 0;
 
   from_xcoff_exec = info.abfd && info.abfd->format == bfd_object &&
     bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour;
@@ -3347,6 +3441,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       else
        have_fpu = 0;
 
+      /* The DFP pseudo-registers will be available when there are floating
+         point registers.  */
+      have_dfp = have_fpu;
+
       feature = tdesc_find_feature (tdesc,
                                    "org.gnu.gdb.power.altivec");
       if (feature != NULL)
@@ -3593,10 +3691,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   else
     tdep->lr_frame_offset = 8;
 
-  if (have_spe)
+  if (have_spe || have_dfp)
     {
-      set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read);
-      set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write);
+      set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
+      set_gdbarch_pseudo_register_write (gdbarch, rs6000_pseudo_register_write);
     }
 
   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
@@ -3607,8 +3705,14 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   else
     set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc);
 
-  set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS + num_sprs);
-  set_gdbarch_num_pseudo_regs (gdbarch, have_spe ? 32 : 0);
+  set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS);
+
+  if (have_spe)
+    num_pseudoregs += 32;
+  if (have_dfp)
+    num_pseudoregs += 16;
+
+  set_gdbarch_num_pseudo_regs (gdbarch, num_pseudoregs);
 
   set_gdbarch_ptr_bit (gdbarch, wordsize * TARGET_CHAR_BIT);
   set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
@@ -3730,7 +3834,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Recording the numbering of pseudo registers.  */
   tdep->ppc_ev0_regnum = have_spe ? gdbarch_num_regs (gdbarch) : -1;
-  tdep->ppc_ev31_regnum = have_spe ? tdep->ppc_ev0_regnum + 31 : -1;
+
+  /* Set the register number for _Decimal128 pseudo-registers.  */
+  tdep->ppc_dl0_regnum = have_dfp? gdbarch_num_regs (gdbarch) : -1;
+
+  if (have_dfp && have_spe)
+    /* Put the _Decimal128 pseudo-registers after the SPE registers.  */
+    tdep->ppc_dl0_regnum += 32;
 
   return gdbarch;
 }
This page took 0.031926 seconds and 4 git commands to generate.