* infrun.c (adjust_pc_after_break): Do not assume software single-step
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 7712bd27955df88d2954fc769eaac96ae99f4ae7..ac5b091afca238e0c4808792c597a7e30f86b7df 100644 (file)
@@ -118,8 +118,8 @@ CORE_ADDR (*rs6000_find_toc_address_hook) (CORE_ADDR) = NULL;
 
 /* Static function prototypes */
 
-static CORE_ADDR branch_dest (int opcode, int instr, CORE_ADDR pc,
-                             CORE_ADDR safety);
+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,
                                 struct rs6000_framedata *);
 
@@ -342,8 +342,9 @@ ppc_supply_gregset (const struct regset *regset, struct regcache *regcache,
        ppc_supply_reg (regcache, i, gregs, offset);
     }
 
-  if (regnum == -1 || regnum == PC_REGNUM)
-    ppc_supply_reg (regcache, PC_REGNUM, gregs, offsets->pc_offset);
+  if (regnum == -1 || regnum == gdbarch_pc_regnum (current_gdbarch))
+    ppc_supply_reg (regcache, gdbarch_pc_regnum (current_gdbarch),
+                   gregs, offsets->pc_offset);
   if (regnum == -1 || regnum == tdep->ppc_ps_regnum)
     ppc_supply_reg (regcache, tdep->ppc_ps_regnum,
                    gregs, offsets->ps_offset);
@@ -418,8 +419,9 @@ ppc_collect_gregset (const struct regset *regset,
        ppc_collect_reg (regcache, i, gregs, offset);
     }
 
-  if (regnum == -1 || regnum == PC_REGNUM)
-    ppc_collect_reg (regcache, PC_REGNUM, gregs, offsets->pc_offset);
+  if (regnum == -1 || regnum == gdbarch_pc_regnum (current_gdbarch))
+    ppc_collect_reg (regcache, gdbarch_pc_regnum (current_gdbarch),
+                    gregs, offsets->pc_offset);
   if (regnum == -1 || regnum == tdep->ppc_ps_regnum)
     ppc_collect_reg (regcache, tdep->ppc_ps_regnum,
                     gregs, offsets->ps_offset);
@@ -624,8 +626,10 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
 /* Calculate the destination of a branch/jump.  Return -1 if not a branch.  */
 
 static CORE_ADDR
-branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
+branch_dest (struct frame_info *frame, int opcode, int instr,
+            CORE_ADDR pc, CORE_ADDR safety)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
   CORE_ADDR dest;
   int immediate;
   int absolute;
@@ -656,32 +660,26 @@ branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
 
       if (ext_op == 16)                /* br conditional register */
        {
-          dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum) & ~3;
+          dest = get_frame_register_unsigned (frame, tdep->ppc_lr_regnum) & ~3;
 
          /* If we are about to return from a signal handler, dest is
             something like 0x3c90.  The current frame is a signal handler
             caller frame, upon completion of the sigreturn system call
             execution will return to the saved PC in the frame.  */
-         if (dest < gdbarch_tdep (current_gdbarch)->text_segment_base)
-           {
-             struct frame_info *fi;
-
-             fi = get_current_frame ();
-             if (fi != NULL)
-               dest = read_memory_addr (get_frame_base (fi) + SIG_FRAME_PC_OFFSET,
-                                        gdbarch_tdep (current_gdbarch)->wordsize);
-           }
+         if (dest < tdep->text_segment_base)
+           dest = read_memory_addr (get_frame_base (frame) + SIG_FRAME_PC_OFFSET,
+                                    tdep->wordsize);
        }
 
       else if (ext_op == 528)  /* br cond to count reg */
        {
-          dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum) & ~3;
+          dest = get_frame_register_unsigned (frame, tdep->ppc_ctr_regnum) & ~3;
 
          /* If we are about to execute a system call, dest is something
             like 0x22fc or 0x3b00.  Upon completion the system call
             will return to the address in the link register.  */
-         if (dest < gdbarch_tdep (current_gdbarch)->text_segment_base)
-            dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum) & ~3;
+         if (dest < tdep->text_segment_base)
+            dest = get_frame_register_unsigned (frame, tdep->ppc_lr_regnum) & ~3;
        }
       else
        return -1;
@@ -690,7 +688,7 @@ branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
     default:
       return -1;
     }
-  return (dest < gdbarch_tdep (current_gdbarch)->text_segment_base) ? safety : dest;
+  return (dest < tdep->text_segment_base) ? safety : dest;
 }
 
 
@@ -725,9 +723,9 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
    the sequence.  */
 
 static int 
-deal_with_atomic_sequence (struct regcache *regcache)
+deal_with_atomic_sequence (struct frame_info *frame)
 {
-  CORE_ADDR pc = read_pc ();
+  CORE_ADDR pc = get_frame_pc (frame);
   CORE_ADDR breaks[2] = {-1, -1};
   CORE_ADDR loc = pc;
   CORE_ADDR branch_bp; /* Breakpoint at branch instruction's destination.  */
@@ -762,7 +760,7 @@ deal_with_atomic_sequence (struct regcache *regcache)
                          to the standard single-step code.  */
           
           opcode = insn >> 26;
-          branch_bp = branch_dest (opcode, insn, pc, breaks[0]);
+          branch_bp = branch_dest (frame, opcode, insn, pc, breaks[0]);
           
           if (branch_bp != -1)
             {
@@ -807,7 +805,7 @@ deal_with_atomic_sequence (struct regcache *regcache)
 /* AIX does not support PT_STEP.  Simulate it.  */
 
 int
-rs6000_software_single_step (struct regcache *regcache)
+rs6000_software_single_step (struct frame_info *frame)
 {
   CORE_ADDR dummy;
   int breakp_sz;
@@ -817,16 +815,16 @@ rs6000_software_single_step (struct regcache *regcache)
   CORE_ADDR breaks[2];
   int opcode;
 
-  loc = read_pc ();
+  loc = get_frame_pc (frame);
 
   insn = read_memory_integer (loc, 4);
 
-  if (deal_with_atomic_sequence (regcache))
+  if (deal_with_atomic_sequence (frame))
     return 1;
   
   breaks[0] = loc + breakp_sz;
   opcode = insn >> 26;
-  breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
+  breaks[1] = branch_dest (frame, opcode, insn, loc, breaks[0]);
 
   /* Don't put two breakpoints on the same address. */
   if (breaks[1] == breaks[0])
@@ -961,13 +959,18 @@ store_param_on_stack_p (unsigned long op, int framep, int *r0_contains_arg)
 static int
 bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
 {
-  const int opcode = 18;
-  const CORE_ADDR dest = branch_dest (opcode, insn, pc, -1);
+  CORE_ADDR dest;
+  int immediate;
+  int absolute;
   int dest_insn;
 
-  if (dest == -1)
-    return 0;  /* Should never happen, but just return zero to be safe.  */
-  
+  absolute = (int) ((insn >> 1) & 1);
+  immediate = ((insn & ~3) << 6) >> 6;
+  if (absolute)
+    dest = immediate;
+  else
+    dest = pc + immediate;
+
   dest_insn = read_memory_integer (dest, 4);
   if ((dest_insn & 0xfc00ffff) == 0x4c000021) /* blrl */
     return 1;
@@ -1696,7 +1699,9 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
 ran_out_of_registers_for_arguments:
 
-  regcache_cooked_read_unsigned (regcache, SP_REGNUM, &saved_sp);
+  regcache_cooked_read_unsigned (regcache,
+                                gdbarch_sp_regnum (current_gdbarch),
+                                &saved_sp);
 
   /* Location for 8 parameters are always reserved.  */
   sp -= wordsize * 8;
@@ -1738,7 +1743,8 @@ ran_out_of_registers_for_arguments:
          to use this area.  So, update %sp first before doing anything
          else.  */
 
-      regcache_raw_write_signed (regcache, SP_REGNUM, sp);
+      regcache_raw_write_signed (regcache,
+                                gdbarch_sp_regnum (current_gdbarch), sp);
 
       /* If the last argument copied into the registers didn't fit there 
          completely, push the rest of it into stack.  */
@@ -1785,7 +1791,7 @@ ran_out_of_registers_for_arguments:
      Not doing this can lead to conflicts with the kernel which thinks
      that it still has control over this not-yet-allocated stack
      region.  */
-  regcache_raw_write_signed (regcache, SP_REGNUM, sp);
+  regcache_raw_write_signed (regcache, gdbarch_sp_regnum (current_gdbarch), sp);
 
   /* Set back chain properly.  */
   store_unsigned_integer (tmp_buffer, wordsize, saved_sp);
@@ -1971,7 +1977,7 @@ rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name)
    code that should be skipped.  */
 
 CORE_ADDR
-rs6000_skip_trampoline_code (CORE_ADDR pc)
+rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 {
   unsigned int ii, op;
   int rel;
@@ -2008,7 +2014,7 @@ rs6000_skip_trampoline_code (CORE_ADDR pc)
     }
 
   /* If pc is in a shared library trampoline, return its target.  */
-  solib_target_pc = find_solib_trampoline_target (pc);
+  solib_target_pc = find_solib_trampoline_target (frame, pc);
   if (solib_target_pc)
     return solib_target_pc;
 
@@ -2018,11 +2024,93 @@ rs6000_skip_trampoline_code (CORE_ADDR pc)
       if (op != trampoline_code[ii])
        return 0;
     }
-  ii = read_register (11);     /* r11 holds destination addr   */
+  ii = get_frame_register_unsigned (frame, 11);        /* r11 holds destination addr   */
   pc = read_memory_addr (ii, gdbarch_tdep (current_gdbarch)->wordsize); /* (r11) value */
   return pc;
 }
 
+/* ISA-specific vector types.  */
+
+static struct type *
+rs6000_builtin_type_vec64 (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (!tdep->ppc_builtin_type_vec64)
+    {
+      /* The type we're building is this: */
+#if 0
+      union __gdb_builtin_type_vec64
+       {
+         int64_t uint64;
+         float v2_float[2];
+         int32_t v2_int32[2];
+         int16_t v4_int16[4];
+         int8_t v8_int8[8];
+       };
+#endif
+
+      struct type *t;
+
+      t = init_composite_type ("__ppc_builtin_type_vec64", TYPE_CODE_UNION);
+      append_composite_type_field (t, "uint64", builtin_type_int64);
+      append_composite_type_field (t, "v2_float",
+                                  init_vector_type (builtin_type_float, 2));
+      append_composite_type_field (t, "v2_int32",
+                                  init_vector_type (builtin_type_int32, 2));
+      append_composite_type_field (t, "v4_int16",
+                                  init_vector_type (builtin_type_int16, 4));
+      append_composite_type_field (t, "v8_int8",
+                                  init_vector_type (builtin_type_int8, 8));
+
+      TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
+      TYPE_NAME (t) = "ppc_builtin_type_vec64";
+      tdep->ppc_builtin_type_vec64 = t;
+    }
+
+  return tdep->ppc_builtin_type_vec64;
+}
+
+static struct type *
+rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (!tdep->ppc_builtin_type_vec128)
+    {
+      /* The type we're building is this: */
+#if 0
+      union __gdb_builtin_type_vec128
+       {
+         int128_t uint128;
+         float v4_float[4];
+         int32_t v4_int32[4];
+         int16_t v8_int16[8];
+         int8_t v16_int8[16];
+       };
+#endif
+
+      struct type *t;
+
+      t = init_composite_type ("__ppc_builtin_type_vec128", TYPE_CODE_UNION);
+      append_composite_type_field (t, "uint128", builtin_type_int128);
+      append_composite_type_field (t, "v4_float",
+                                  init_vector_type (builtin_type_float, 4));
+      append_composite_type_field (t, "v4_int32",
+                                  init_vector_type (builtin_type_int32, 4));
+      append_composite_type_field (t, "v8_int16",
+                                  init_vector_type (builtin_type_int16, 8));
+      append_composite_type_field (t, "v16_int8",
+                                  init_vector_type (builtin_type_int8, 16));
+
+      TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
+      TYPE_NAME (t) = "ppc_builtin_type_vec128";
+      tdep->ppc_builtin_type_vec128 = t;
+    }
+
+  return tdep->ppc_builtin_type_vec128;
+}
+
 /* Return the size of register REG when words are WORDSIZE bytes long.  If REG
    isn't available with that word size, return 0.  */
 
@@ -2068,12 +2156,12 @@ rs6000_register_type (struct gdbarch *gdbarch, int n)
          return builtin_type_uint32;
        case 8:
          if (tdep->ppc_ev0_regnum <= n && n <= tdep->ppc_ev31_regnum)
-           return builtin_type_vec64;
+           return rs6000_builtin_type_vec64 (gdbarch);
          else
            return builtin_type_uint64;
          break;
        case 16:
-         return builtin_type_vec128;
+         return rs6000_builtin_type_vec128 (gdbarch);
          break;
        default:
          internal_error (__FILE__, __LINE__, _("Register %d size %d unknown"),
@@ -2127,7 +2215,7 @@ rs6000_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
               || regnum == tdep->ppc_lr_regnum
               || regnum == tdep->ppc_ctr_regnum
               || regnum == tdep->ppc_xer_regnum
-              || regnum == PC_REGNUM);
+              || regnum == gdbarch_pc_regnum (current_gdbarch));
   if (group == general_reggroup)
     return general_p;
 
@@ -3036,15 +3124,16 @@ gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
 static CORE_ADDR
 rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  return frame_unwind_register_unsigned (next_frame, PC_REGNUM);
+  return frame_unwind_register_unsigned (next_frame,
+                                        gdbarch_pc_regnum (current_gdbarch));
 }
 
 static struct frame_id
 rs6000_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  return frame_id_build (frame_unwind_register_unsigned (next_frame,
-                                                        SP_REGNUM),
-                        frame_pc_unwind (next_frame));
+  return frame_id_build (frame_unwind_register_unsigned
+                        (next_frame, gdbarch_sp_regnum (current_gdbarch)),
+                       frame_pc_unwind (next_frame));
 }
 
 struct rs6000_frame_cache
@@ -3081,7 +3170,8 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
      ->frame pointed to the outer-most address of the frame.  In
      the mean time, the address of the prev frame is used as the
      base address of this frame.  */
-  cache->base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
+  cache->base = frame_unwind_register_unsigned
+               (next_frame, gdbarch_sp_regnum (current_gdbarch));
 
   /* If the function appears to be frameless, check a couple of likely
      indicators that we have simply failed to find the frame setup.
@@ -3119,7 +3209,8 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
     /* Frameless really means stackless.  */
     cache->base = read_memory_addr (cache->base, wordsize);
 
-  trad_frame_set_value (cache->saved_regs, SP_REGNUM, cache->base);
+  trad_frame_set_value (cache->saved_regs,
+                       gdbarch_sp_regnum (current_gdbarch), cache->base);
 
   /* if != -1, fdata.saved_fpr is the smallest number of saved_fpr.
      All fpr's from saved_fpr to fp31 are saved.  */
@@ -3198,7 +3289,8 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
   if (fdata.lr_offset != 0)
     cache->saved_regs[tdep->ppc_lr_regnum].addr = cache->base + fdata.lr_offset;
   /* The PC is found in the link register.  */
-  cache->saved_regs[PC_REGNUM] = cache->saved_regs[tdep->ppc_lr_regnum];
+  cache->saved_regs[gdbarch_pc_regnum (current_gdbarch)] =
+    cache->saved_regs[tdep->ppc_lr_regnum];
 
   /* If != 0, fdata.vrsave_offset is the offset from the frame that
      holds the VRSAVE.  */
@@ -3208,7 +3300,8 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
   if (fdata.alloca_reg < 0)
     /* If no alloca register used, then fi->frame is the value of the
        %sp for this frame, and it is good enough.  */
-    cache->initial_sp = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
+    cache->initial_sp = frame_unwind_register_unsigned
+                       (next_frame, gdbarch_sp_regnum (current_gdbarch));
   else
     cache->initial_sp = frame_unwind_register_unsigned (next_frame,
                                                        fdata.alloca_reg);
@@ -3363,7 +3456,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       info.bfd_arch_info = bfd_get_arch_info (&abfd);
       mach = info.bfd_arch_info->mach;
     }
-  tdep = xmalloc (sizeof (struct gdbarch_tdep));
+  tdep = XCALLOC (1, struct gdbarch_tdep);
   tdep->wordsize = wordsize;
 
   /* For e500 executables, the apuinfo section is of help here.  Such
@@ -3497,8 +3590,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   else
     set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc);
 
-  set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
-
   set_gdbarch_num_regs (gdbarch, v->nregs);
   set_gdbarch_num_pseudo_regs (gdbarch, v->npregs);
   set_gdbarch_register_name (gdbarch, rs6000_register_name);
This page took 0.028603 seconds and 4 git commands to generate.