Home | History | Annotate | Line # | Download | only in arch
arm-get-next-pcs.c revision 1.1.1.3
      1      1.1  christos /* Common code for ARM software single stepping support.
      2      1.1  christos 
      3  1.1.1.3  christos    Copyright (C) 1988-2019 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    This file is part of GDB.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19      1.1  christos 
     20  1.1.1.3  christos #include "common/common-defs.h"
     21  1.1.1.3  christos #include "common/gdb_vecs.h"
     22  1.1.1.3  christos #include "common/common-regcache.h"
     23      1.1  christos #include "arm.h"
     24      1.1  christos #include "arm-get-next-pcs.h"
     25      1.1  christos 
     26      1.1  christos /* See arm-get-next-pcs.h.  */
     27      1.1  christos 
     28      1.1  christos void
     29      1.1  christos arm_get_next_pcs_ctor (struct arm_get_next_pcs *self,
     30      1.1  christos 		       struct arm_get_next_pcs_ops *ops,
     31      1.1  christos 		       int byte_order,
     32      1.1  christos 		       int byte_order_for_code,
     33      1.1  christos 		       int has_thumb2_breakpoint,
     34      1.1  christos 		       struct regcache *regcache)
     35      1.1  christos {
     36      1.1  christos   self->ops = ops;
     37      1.1  christos   self->byte_order = byte_order;
     38      1.1  christos   self->byte_order_for_code = byte_order_for_code;
     39      1.1  christos   self->has_thumb2_breakpoint = has_thumb2_breakpoint;
     40      1.1  christos   self->regcache = regcache;
     41      1.1  christos }
     42      1.1  christos 
     43      1.1  christos /* Checks for an atomic sequence of instructions beginning with a LDREX{,B,H,D}
     44      1.1  christos    instruction and ending with a STREX{,B,H,D} instruction.  If such a sequence
     45      1.1  christos    is found, attempt to step through it.  The end of the sequence address is
     46      1.1  christos    added to the next_pcs list.  */
     47      1.1  christos 
     48  1.1.1.3  christos static std::vector<CORE_ADDR>
     49      1.1  christos thumb_deal_with_atomic_sequence_raw (struct arm_get_next_pcs *self)
     50      1.1  christos {
     51      1.1  christos   int byte_order_for_code = self->byte_order_for_code;
     52  1.1.1.3  christos   CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX};
     53      1.1  christos   CORE_ADDR pc = regcache_read_pc (self->regcache);
     54      1.1  christos   CORE_ADDR loc = pc;
     55      1.1  christos   unsigned short insn1, insn2;
     56      1.1  christos   int insn_count;
     57      1.1  christos   int index;
     58      1.1  christos   int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */
     59      1.1  christos   const int atomic_sequence_length = 16; /* Instruction sequence length.  */
     60      1.1  christos   ULONGEST status, itstate;
     61      1.1  christos 
     62      1.1  christos   /* We currently do not support atomic sequences within an IT block.  */
     63      1.1  christos   status = regcache_raw_get_unsigned (self->regcache, ARM_PS_REGNUM);
     64      1.1  christos   itstate = ((status >> 8) & 0xfc) | ((status >> 25) & 0x3);
     65      1.1  christos   if (itstate & 0x0f)
     66  1.1.1.3  christos     return {};
     67      1.1  christos 
     68      1.1  christos   /* Assume all atomic sequences start with a ldrex{,b,h,d} instruction.  */
     69      1.1  christos   insn1 = self->ops->read_mem_uint (loc, 2, byte_order_for_code);
     70      1.1  christos 
     71      1.1  christos   loc += 2;
     72      1.1  christos   if (thumb_insn_size (insn1) != 4)
     73  1.1.1.3  christos     return {};
     74      1.1  christos 
     75      1.1  christos   insn2 = self->ops->read_mem_uint (loc, 2, byte_order_for_code);
     76      1.1  christos 
     77      1.1  christos   loc += 2;
     78      1.1  christos   if (!((insn1 & 0xfff0) == 0xe850
     79      1.1  christos         || ((insn1 & 0xfff0) == 0xe8d0 && (insn2 & 0x00c0) == 0x0040)))
     80  1.1.1.3  christos     return {};
     81      1.1  christos 
     82      1.1  christos   /* Assume that no atomic sequence is longer than "atomic_sequence_length"
     83      1.1  christos      instructions.  */
     84      1.1  christos   for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
     85      1.1  christos     {
     86      1.1  christos       insn1 = self->ops->read_mem_uint (loc, 2,byte_order_for_code);
     87      1.1  christos       loc += 2;
     88      1.1  christos 
     89      1.1  christos       if (thumb_insn_size (insn1) != 4)
     90      1.1  christos 	{
     91      1.1  christos 	  /* Assume that there is at most one conditional branch in the
     92      1.1  christos 	     atomic sequence.  If a conditional branch is found, put a
     93      1.1  christos 	     breakpoint in its destination address.  */
     94      1.1  christos 	  if ((insn1 & 0xf000) == 0xd000 && bits (insn1, 8, 11) != 0x0f)
     95      1.1  christos 	    {
     96      1.1  christos 	      if (last_breakpoint > 0)
     97  1.1.1.3  christos 		return {}; /* More than one conditional branch found,
     98  1.1.1.3  christos 			      fallback to the standard code.  */
     99      1.1  christos 
    100      1.1  christos 	      breaks[1] = loc + 2 + (sbits (insn1, 0, 7) << 1);
    101      1.1  christos 	      last_breakpoint++;
    102      1.1  christos 	    }
    103      1.1  christos 
    104      1.1  christos 	  /* We do not support atomic sequences that use any *other*
    105      1.1  christos 	     instructions but conditional branches to change the PC.
    106      1.1  christos 	     Fall back to standard code to avoid losing control of
    107      1.1  christos 	     execution.  */
    108      1.1  christos 	  else if (thumb_instruction_changes_pc (insn1))
    109  1.1.1.3  christos 	    return {};
    110      1.1  christos 	}
    111      1.1  christos       else
    112      1.1  christos 	{
    113      1.1  christos 	  insn2 = self->ops->read_mem_uint (loc, 2, byte_order_for_code);
    114      1.1  christos 
    115      1.1  christos 	  loc += 2;
    116      1.1  christos 
    117      1.1  christos 	  /* Assume that there is at most one conditional branch in the
    118      1.1  christos 	     atomic sequence.  If a conditional branch is found, put a
    119      1.1  christos 	     breakpoint in its destination address.  */
    120      1.1  christos 	  if ((insn1 & 0xf800) == 0xf000
    121      1.1  christos 	      && (insn2 & 0xd000) == 0x8000
    122      1.1  christos 	      && (insn1 & 0x0380) != 0x0380)
    123      1.1  christos 	    {
    124      1.1  christos 	      int sign, j1, j2, imm1, imm2;
    125      1.1  christos 	      unsigned int offset;
    126      1.1  christos 
    127      1.1  christos 	      sign = sbits (insn1, 10, 10);
    128      1.1  christos 	      imm1 = bits (insn1, 0, 5);
    129      1.1  christos 	      imm2 = bits (insn2, 0, 10);
    130      1.1  christos 	      j1 = bit (insn2, 13);
    131      1.1  christos 	      j2 = bit (insn2, 11);
    132      1.1  christos 
    133      1.1  christos 	      offset = (sign << 20) + (j2 << 19) + (j1 << 18);
    134      1.1  christos 	      offset += (imm1 << 12) + (imm2 << 1);
    135      1.1  christos 
    136      1.1  christos 	      if (last_breakpoint > 0)
    137  1.1.1.3  christos 		return {}; /* More than one conditional branch found,
    138  1.1.1.3  christos 			      fallback to the standard code.  */
    139      1.1  christos 
    140      1.1  christos 	      breaks[1] = loc + offset;
    141      1.1  christos 	      last_breakpoint++;
    142      1.1  christos 	    }
    143      1.1  christos 
    144      1.1  christos 	  /* We do not support atomic sequences that use any *other*
    145      1.1  christos 	     instructions but conditional branches to change the PC.
    146      1.1  christos 	     Fall back to standard code to avoid losing control of
    147      1.1  christos 	     execution.  */
    148      1.1  christos 	  else if (thumb2_instruction_changes_pc (insn1, insn2))
    149  1.1.1.3  christos 	    return {};
    150      1.1  christos 
    151      1.1  christos 	  /* If we find a strex{,b,h,d}, we're done.  */
    152      1.1  christos 	  if ((insn1 & 0xfff0) == 0xe840
    153      1.1  christos 	      || ((insn1 & 0xfff0) == 0xe8c0 && (insn2 & 0x00c0) == 0x0040))
    154      1.1  christos 	    break;
    155      1.1  christos 	}
    156      1.1  christos     }
    157      1.1  christos 
    158      1.1  christos   /* If we didn't find the strex{,b,h,d}, we cannot handle the sequence.  */
    159      1.1  christos   if (insn_count == atomic_sequence_length)
    160  1.1.1.3  christos     return {};
    161      1.1  christos 
    162      1.1  christos   /* Insert a breakpoint right after the end of the atomic sequence.  */
    163      1.1  christos   breaks[0] = loc;
    164      1.1  christos 
    165      1.1  christos   /* Check for duplicated breakpoints.  Check also for a breakpoint
    166      1.1  christos      placed (branch instruction's destination) anywhere in sequence.  */
    167      1.1  christos   if (last_breakpoint
    168      1.1  christos       && (breaks[1] == breaks[0]
    169      1.1  christos 	  || (breaks[1] >= pc && breaks[1] < loc)))
    170      1.1  christos     last_breakpoint = 0;
    171      1.1  christos 
    172  1.1.1.3  christos   std::vector<CORE_ADDR> next_pcs;
    173  1.1.1.3  christos 
    174      1.1  christos   /* Adds the breakpoints to the list to be inserted.  */
    175      1.1  christos   for (index = 0; index <= last_breakpoint; index++)
    176  1.1.1.3  christos     next_pcs.push_back (MAKE_THUMB_ADDR (breaks[index]));
    177      1.1  christos 
    178      1.1  christos   return next_pcs;
    179      1.1  christos }
    180      1.1  christos 
    181      1.1  christos /* Checks for an atomic sequence of instructions beginning with a LDREX{,B,H,D}
    182      1.1  christos    instruction and ending with a STREX{,B,H,D} instruction.  If such a sequence
    183      1.1  christos    is found, attempt to step through it.  The end of the sequence address is
    184      1.1  christos    added to the next_pcs list.  */
    185      1.1  christos 
    186  1.1.1.3  christos static std::vector<CORE_ADDR>
    187      1.1  christos arm_deal_with_atomic_sequence_raw (struct arm_get_next_pcs *self)
    188      1.1  christos {
    189      1.1  christos   int byte_order_for_code = self->byte_order_for_code;
    190  1.1.1.3  christos   CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX};
    191      1.1  christos   CORE_ADDR pc = regcache_read_pc (self->regcache);
    192      1.1  christos   CORE_ADDR loc = pc;
    193      1.1  christos   unsigned int insn;
    194      1.1  christos   int insn_count;
    195      1.1  christos   int index;
    196      1.1  christos   int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */
    197      1.1  christos   const int atomic_sequence_length = 16; /* Instruction sequence length.  */
    198      1.1  christos 
    199      1.1  christos   /* Assume all atomic sequences start with a ldrex{,b,h,d} instruction.
    200      1.1  christos      Note that we do not currently support conditionally executed atomic
    201      1.1  christos      instructions.  */
    202      1.1  christos   insn = self->ops->read_mem_uint (loc, 4, byte_order_for_code);
    203      1.1  christos 
    204      1.1  christos   loc += 4;
    205      1.1  christos   if ((insn & 0xff9000f0) != 0xe1900090)
    206  1.1.1.3  christos     return {};
    207      1.1  christos 
    208      1.1  christos   /* Assume that no atomic sequence is longer than "atomic_sequence_length"
    209      1.1  christos      instructions.  */
    210      1.1  christos   for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
    211      1.1  christos     {
    212      1.1  christos       insn = self->ops->read_mem_uint (loc, 4, byte_order_for_code);
    213      1.1  christos 
    214      1.1  christos       loc += 4;
    215      1.1  christos 
    216      1.1  christos       /* Assume that there is at most one conditional branch in the atomic
    217      1.1  christos          sequence.  If a conditional branch is found, put a breakpoint in
    218      1.1  christos          its destination address.  */
    219      1.1  christos       if (bits (insn, 24, 27) == 0xa)
    220      1.1  christos 	{
    221      1.1  christos           if (last_breakpoint > 0)
    222  1.1.1.3  christos             return {}; /* More than one conditional branch found, fallback
    223  1.1.1.3  christos 			  to the standard single-step code.  */
    224      1.1  christos 
    225      1.1  christos 	  breaks[1] = BranchDest (loc - 4, insn);
    226      1.1  christos 	  last_breakpoint++;
    227      1.1  christos         }
    228      1.1  christos 
    229      1.1  christos       /* We do not support atomic sequences that use any *other* instructions
    230      1.1  christos          but conditional branches to change the PC.  Fall back to standard
    231      1.1  christos 	 code to avoid losing control of execution.  */
    232      1.1  christos       else if (arm_instruction_changes_pc (insn))
    233  1.1.1.3  christos 	return {};
    234      1.1  christos 
    235      1.1  christos       /* If we find a strex{,b,h,d}, we're done.  */
    236      1.1  christos       if ((insn & 0xff9000f0) == 0xe1800090)
    237      1.1  christos 	break;
    238      1.1  christos     }
    239      1.1  christos 
    240      1.1  christos   /* If we didn't find the strex{,b,h,d}, we cannot handle the sequence.  */
    241      1.1  christos   if (insn_count == atomic_sequence_length)
    242  1.1.1.3  christos     return {};
    243      1.1  christos 
    244      1.1  christos   /* Insert a breakpoint right after the end of the atomic sequence.  */
    245      1.1  christos   breaks[0] = loc;
    246      1.1  christos 
    247      1.1  christos   /* Check for duplicated breakpoints.  Check also for a breakpoint
    248      1.1  christos      placed (branch instruction's destination) anywhere in sequence.  */
    249      1.1  christos   if (last_breakpoint
    250      1.1  christos       && (breaks[1] == breaks[0]
    251      1.1  christos 	  || (breaks[1] >= pc && breaks[1] < loc)))
    252      1.1  christos     last_breakpoint = 0;
    253      1.1  christos 
    254  1.1.1.3  christos   std::vector<CORE_ADDR> next_pcs;
    255  1.1.1.3  christos 
    256      1.1  christos   /* Adds the breakpoints to the list to be inserted.  */
    257      1.1  christos   for (index = 0; index <= last_breakpoint; index++)
    258  1.1.1.3  christos     next_pcs.push_back (breaks[index]);
    259      1.1  christos 
    260      1.1  christos   return next_pcs;
    261      1.1  christos }
    262      1.1  christos 
    263      1.1  christos /* Find the next possible PCs for thumb mode.  */
    264      1.1  christos 
    265  1.1.1.3  christos static std::vector<CORE_ADDR>
    266      1.1  christos thumb_get_next_pcs_raw (struct arm_get_next_pcs *self)
    267      1.1  christos {
    268      1.1  christos   int byte_order = self->byte_order;
    269      1.1  christos   int byte_order_for_code = self->byte_order_for_code;
    270      1.1  christos   CORE_ADDR pc = regcache_read_pc (self->regcache);
    271      1.1  christos   unsigned long pc_val = ((unsigned long) pc) + 4;	/* PC after prefetch */
    272      1.1  christos   unsigned short inst1;
    273      1.1  christos   CORE_ADDR nextpc = pc + 2;		/* Default is next instruction.  */
    274      1.1  christos   ULONGEST status, itstate;
    275      1.1  christos   struct regcache *regcache = self->regcache;
    276  1.1.1.3  christos   std::vector<CORE_ADDR> next_pcs;
    277      1.1  christos 
    278      1.1  christos   nextpc = MAKE_THUMB_ADDR (nextpc);
    279      1.1  christos   pc_val = MAKE_THUMB_ADDR (pc_val);
    280      1.1  christos 
    281      1.1  christos   inst1 = self->ops->read_mem_uint (pc, 2, byte_order_for_code);
    282      1.1  christos 
    283      1.1  christos   /* Thumb-2 conditional execution support.  There are eight bits in
    284      1.1  christos      the CPSR which describe conditional execution state.  Once
    285      1.1  christos      reconstructed (they're in a funny order), the low five bits
    286      1.1  christos      describe the low bit of the condition for each instruction and
    287      1.1  christos      how many instructions remain.  The high three bits describe the
    288      1.1  christos      base condition.  One of the low four bits will be set if an IT
    289      1.1  christos      block is active.  These bits read as zero on earlier
    290      1.1  christos      processors.  */
    291      1.1  christos   status = regcache_raw_get_unsigned (regcache, ARM_PS_REGNUM);
    292      1.1  christos   itstate = ((status >> 8) & 0xfc) | ((status >> 25) & 0x3);
    293      1.1  christos 
    294      1.1  christos   /* If-Then handling.  On GNU/Linux, where this routine is used, we
    295      1.1  christos      use an undefined instruction as a breakpoint.  Unlike BKPT, IT
    296      1.1  christos      can disable execution of the undefined instruction.  So we might
    297      1.1  christos      miss the breakpoint if we set it on a skipped conditional
    298      1.1  christos      instruction.  Because conditional instructions can change the
    299      1.1  christos      flags, affecting the execution of further instructions, we may
    300      1.1  christos      need to set two breakpoints.  */
    301      1.1  christos 
    302      1.1  christos   if (self->has_thumb2_breakpoint)
    303      1.1  christos     {
    304      1.1  christos       if ((inst1 & 0xff00) == 0xbf00 && (inst1 & 0x000f) != 0)
    305      1.1  christos 	{
    306      1.1  christos 	  /* An IT instruction.  Because this instruction does not
    307      1.1  christos 	     modify the flags, we can accurately predict the next
    308      1.1  christos 	     executed instruction.  */
    309      1.1  christos 	  itstate = inst1 & 0x00ff;
    310      1.1  christos 	  pc += thumb_insn_size (inst1);
    311      1.1  christos 
    312      1.1  christos 	  while (itstate != 0 && ! condition_true (itstate >> 4, status))
    313      1.1  christos 	    {
    314      1.1  christos 	      inst1 = self->ops->read_mem_uint (pc, 2,byte_order_for_code);
    315      1.1  christos 	      pc += thumb_insn_size (inst1);
    316      1.1  christos 	      itstate = thumb_advance_itstate (itstate);
    317      1.1  christos 	    }
    318      1.1  christos 
    319  1.1.1.3  christos 	  next_pcs.push_back (MAKE_THUMB_ADDR (pc));
    320      1.1  christos 	  return next_pcs;
    321      1.1  christos 	}
    322      1.1  christos       else if (itstate != 0)
    323      1.1  christos 	{
    324      1.1  christos 	  /* We are in a conditional block.  Check the condition.  */
    325      1.1  christos 	  if (! condition_true (itstate >> 4, status))
    326      1.1  christos 	    {
    327      1.1  christos 	      /* Advance to the next executed instruction.  */
    328      1.1  christos 	      pc += thumb_insn_size (inst1);
    329      1.1  christos 	      itstate = thumb_advance_itstate (itstate);
    330      1.1  christos 
    331      1.1  christos 	      while (itstate != 0 && ! condition_true (itstate >> 4, status))
    332      1.1  christos 		{
    333      1.1  christos 		  inst1 = self->ops->read_mem_uint (pc, 2, byte_order_for_code);
    334      1.1  christos 
    335      1.1  christos 		  pc += thumb_insn_size (inst1);
    336      1.1  christos 		  itstate = thumb_advance_itstate (itstate);
    337      1.1  christos 		}
    338      1.1  christos 
    339  1.1.1.3  christos 	      next_pcs.push_back (MAKE_THUMB_ADDR (pc));
    340      1.1  christos 	      return next_pcs;
    341      1.1  christos 	    }
    342      1.1  christos 	  else if ((itstate & 0x0f) == 0x08)
    343      1.1  christos 	    {
    344      1.1  christos 	      /* This is the last instruction of the conditional
    345      1.1  christos 		 block, and it is executed.  We can handle it normally
    346      1.1  christos 		 because the following instruction is not conditional,
    347      1.1  christos 		 and we must handle it normally because it is
    348      1.1  christos 		 permitted to branch.  Fall through.  */
    349      1.1  christos 	    }
    350      1.1  christos 	  else
    351      1.1  christos 	    {
    352      1.1  christos 	      int cond_negated;
    353      1.1  christos 
    354      1.1  christos 	      /* There are conditional instructions after this one.
    355      1.1  christos 		 If this instruction modifies the flags, then we can
    356      1.1  christos 		 not predict what the next executed instruction will
    357      1.1  christos 		 be.  Fortunately, this instruction is architecturally
    358      1.1  christos 		 forbidden to branch; we know it will fall through.
    359      1.1  christos 		 Start by skipping past it.  */
    360      1.1  christos 	      pc += thumb_insn_size (inst1);
    361      1.1  christos 	      itstate = thumb_advance_itstate (itstate);
    362      1.1  christos 
    363      1.1  christos 	      /* Set a breakpoint on the following instruction.  */
    364      1.1  christos 	      gdb_assert ((itstate & 0x0f) != 0);
    365  1.1.1.3  christos 	      next_pcs.push_back (MAKE_THUMB_ADDR (pc));
    366      1.1  christos 
    367      1.1  christos 	      cond_negated = (itstate >> 4) & 1;
    368      1.1  christos 
    369      1.1  christos 	      /* Skip all following instructions with the same
    370      1.1  christos 		 condition.  If there is a later instruction in the IT
    371      1.1  christos 		 block with the opposite condition, set the other
    372      1.1  christos 		 breakpoint there.  If not, then set a breakpoint on
    373      1.1  christos 		 the instruction after the IT block.  */
    374      1.1  christos 	      do
    375      1.1  christos 		{
    376      1.1  christos 		  inst1 = self->ops->read_mem_uint (pc, 2, byte_order_for_code);
    377      1.1  christos 		  pc += thumb_insn_size (inst1);
    378      1.1  christos 		  itstate = thumb_advance_itstate (itstate);
    379      1.1  christos 		}
    380      1.1  christos 	      while (itstate != 0 && ((itstate >> 4) & 1) == cond_negated);
    381      1.1  christos 
    382  1.1.1.3  christos 	      next_pcs.push_back (MAKE_THUMB_ADDR (pc));
    383      1.1  christos 
    384      1.1  christos 	      return next_pcs;
    385      1.1  christos 	    }
    386      1.1  christos 	}
    387      1.1  christos     }
    388      1.1  christos   else if (itstate & 0x0f)
    389      1.1  christos     {
    390      1.1  christos       /* We are in a conditional block.  Check the condition.  */
    391      1.1  christos       int cond = itstate >> 4;
    392      1.1  christos 
    393      1.1  christos       if (! condition_true (cond, status))
    394      1.1  christos 	{
    395      1.1  christos 	  /* Advance to the next instruction.  All the 32-bit
    396      1.1  christos 	     instructions share a common prefix.  */
    397  1.1.1.3  christos 	  next_pcs.push_back (MAKE_THUMB_ADDR (pc + thumb_insn_size (inst1)));
    398      1.1  christos 	}
    399      1.1  christos 
    400      1.1  christos       return next_pcs;
    401      1.1  christos 
    402      1.1  christos       /* Otherwise, handle the instruction normally.  */
    403      1.1  christos     }
    404      1.1  christos 
    405      1.1  christos   if ((inst1 & 0xff00) == 0xbd00)	/* pop {rlist, pc} */
    406      1.1  christos     {
    407      1.1  christos       CORE_ADDR sp;
    408      1.1  christos 
    409      1.1  christos       /* Fetch the saved PC from the stack.  It's stored above
    410      1.1  christos          all of the other registers.  */
    411  1.1.1.3  christos       unsigned long offset = bitcount (bits (inst1, 0, 7)) * INT_REGISTER_SIZE;
    412      1.1  christos       sp = regcache_raw_get_unsigned (regcache, ARM_SP_REGNUM);
    413      1.1  christos       nextpc = self->ops->read_mem_uint (sp + offset, 4, byte_order);
    414      1.1  christos     }
    415      1.1  christos   else if ((inst1 & 0xf000) == 0xd000)	/* conditional branch */
    416      1.1  christos     {
    417      1.1  christos       unsigned long cond = bits (inst1, 8, 11);
    418      1.1  christos       if (cond == 0x0f)  /* 0x0f = SWI */
    419      1.1  christos 	{
    420      1.1  christos 	  nextpc = self->ops->syscall_next_pc (self);
    421      1.1  christos 	}
    422      1.1  christos       else if (cond != 0x0f && condition_true (cond, status))
    423      1.1  christos 	nextpc = pc_val + (sbits (inst1, 0, 7) << 1);
    424      1.1  christos     }
    425      1.1  christos   else if ((inst1 & 0xf800) == 0xe000)	/* unconditional branch */
    426      1.1  christos     {
    427      1.1  christos       nextpc = pc_val + (sbits (inst1, 0, 10) << 1);
    428      1.1  christos     }
    429      1.1  christos   else if (thumb_insn_size (inst1) == 4) /* 32-bit instruction */
    430      1.1  christos     {
    431      1.1  christos       unsigned short inst2;
    432      1.1  christos       inst2 = self->ops->read_mem_uint (pc + 2, 2, byte_order_for_code);
    433      1.1  christos 
    434      1.1  christos       /* Default to the next instruction.  */
    435      1.1  christos       nextpc = pc + 4;
    436      1.1  christos       nextpc = MAKE_THUMB_ADDR (nextpc);
    437      1.1  christos 
    438      1.1  christos       if ((inst1 & 0xf800) == 0xf000 && (inst2 & 0x8000) == 0x8000)
    439      1.1  christos 	{
    440      1.1  christos 	  /* Branches and miscellaneous control instructions.  */
    441      1.1  christos 
    442      1.1  christos 	  if ((inst2 & 0x1000) != 0 || (inst2 & 0xd001) == 0xc000)
    443      1.1  christos 	    {
    444      1.1  christos 	      /* B, BL, BLX.  */
    445      1.1  christos 	      int j1, j2, imm1, imm2;
    446      1.1  christos 
    447      1.1  christos 	      imm1 = sbits (inst1, 0, 10);
    448      1.1  christos 	      imm2 = bits (inst2, 0, 10);
    449      1.1  christos 	      j1 = bit (inst2, 13);
    450      1.1  christos 	      j2 = bit (inst2, 11);
    451      1.1  christos 
    452  1.1.1.3  christos 	      unsigned long offset = ((imm1 << 12) + (imm2 << 1));
    453      1.1  christos 	      offset ^= ((!j2) << 22) | ((!j1) << 23);
    454      1.1  christos 
    455      1.1  christos 	      nextpc = pc_val + offset;
    456      1.1  christos 	      /* For BLX make sure to clear the low bits.  */
    457      1.1  christos 	      if (bit (inst2, 12) == 0)
    458      1.1  christos 		nextpc = nextpc & 0xfffffffc;
    459      1.1  christos 	    }
    460      1.1  christos 	  else if (inst1 == 0xf3de && (inst2 & 0xff00) == 0x3f00)
    461      1.1  christos 	    {
    462      1.1  christos 	      /* SUBS PC, LR, #imm8.  */
    463      1.1  christos 	      nextpc = regcache_raw_get_unsigned (regcache, ARM_LR_REGNUM);
    464      1.1  christos 	      nextpc -= inst2 & 0x00ff;
    465      1.1  christos 	    }
    466      1.1  christos 	  else if ((inst2 & 0xd000) == 0x8000 && (inst1 & 0x0380) != 0x0380)
    467      1.1  christos 	    {
    468      1.1  christos 	      /* Conditional branch.  */
    469      1.1  christos 	      if (condition_true (bits (inst1, 6, 9), status))
    470      1.1  christos 		{
    471      1.1  christos 		  int sign, j1, j2, imm1, imm2;
    472      1.1  christos 
    473      1.1  christos 		  sign = sbits (inst1, 10, 10);
    474      1.1  christos 		  imm1 = bits (inst1, 0, 5);
    475      1.1  christos 		  imm2 = bits (inst2, 0, 10);
    476      1.1  christos 		  j1 = bit (inst2, 13);
    477      1.1  christos 		  j2 = bit (inst2, 11);
    478      1.1  christos 
    479  1.1.1.3  christos 		  unsigned long offset
    480  1.1.1.3  christos 		    = (sign << 20) + (j2 << 19) + (j1 << 18);
    481      1.1  christos 		  offset += (imm1 << 12) + (imm2 << 1);
    482      1.1  christos 
    483      1.1  christos 		  nextpc = pc_val + offset;
    484      1.1  christos 		}
    485      1.1  christos 	    }
    486      1.1  christos 	}
    487      1.1  christos       else if ((inst1 & 0xfe50) == 0xe810)
    488      1.1  christos 	{
    489      1.1  christos 	  /* Load multiple or RFE.  */
    490      1.1  christos 	  int rn, offset, load_pc = 1;
    491      1.1  christos 
    492      1.1  christos 	  rn = bits (inst1, 0, 3);
    493      1.1  christos 	  if (bit (inst1, 7) && !bit (inst1, 8))
    494      1.1  christos 	    {
    495      1.1  christos 	      /* LDMIA or POP */
    496      1.1  christos 	      if (!bit (inst2, 15))
    497      1.1  christos 		load_pc = 0;
    498      1.1  christos 	      offset = bitcount (inst2) * 4 - 4;
    499      1.1  christos 	    }
    500      1.1  christos 	  else if (!bit (inst1, 7) && bit (inst1, 8))
    501      1.1  christos 	    {
    502      1.1  christos 	      /* LDMDB */
    503      1.1  christos 	      if (!bit (inst2, 15))
    504      1.1  christos 		load_pc = 0;
    505      1.1  christos 	      offset = -4;
    506      1.1  christos 	    }
    507      1.1  christos 	  else if (bit (inst1, 7) && bit (inst1, 8))
    508      1.1  christos 	    {
    509      1.1  christos 	      /* RFEIA */
    510      1.1  christos 	      offset = 0;
    511      1.1  christos 	    }
    512      1.1  christos 	  else if (!bit (inst1, 7) && !bit (inst1, 8))
    513      1.1  christos 	    {
    514      1.1  christos 	      /* RFEDB */
    515      1.1  christos 	      offset = -8;
    516      1.1  christos 	    }
    517      1.1  christos 	  else
    518      1.1  christos 	    load_pc = 0;
    519      1.1  christos 
    520      1.1  christos 	  if (load_pc)
    521      1.1  christos 	    {
    522      1.1  christos 	      CORE_ADDR addr = regcache_raw_get_unsigned (regcache, rn);
    523      1.1  christos 	      nextpc = self->ops->read_mem_uint	(addr + offset, 4, byte_order);
    524      1.1  christos 	    }
    525      1.1  christos 	}
    526      1.1  christos       else if ((inst1 & 0xffef) == 0xea4f && (inst2 & 0xfff0) == 0x0f00)
    527      1.1  christos 	{
    528      1.1  christos 	  /* MOV PC or MOVS PC.  */
    529      1.1  christos 	  nextpc = regcache_raw_get_unsigned (regcache, bits (inst2, 0, 3));
    530      1.1  christos 	  nextpc = MAKE_THUMB_ADDR (nextpc);
    531      1.1  christos 	}
    532      1.1  christos       else if ((inst1 & 0xff70) == 0xf850 && (inst2 & 0xf000) == 0xf000)
    533      1.1  christos 	{
    534      1.1  christos 	  /* LDR PC.  */
    535      1.1  christos 	  CORE_ADDR base;
    536      1.1  christos 	  int rn, load_pc = 1;
    537      1.1  christos 
    538      1.1  christos 	  rn = bits (inst1, 0, 3);
    539      1.1  christos 	  base = regcache_raw_get_unsigned (regcache, rn);
    540      1.1  christos 	  if (rn == ARM_PC_REGNUM)
    541      1.1  christos 	    {
    542      1.1  christos 	      base = (base + 4) & ~(CORE_ADDR) 0x3;
    543      1.1  christos 	      if (bit (inst1, 7))
    544      1.1  christos 		base += bits (inst2, 0, 11);
    545      1.1  christos 	      else
    546      1.1  christos 		base -= bits (inst2, 0, 11);
    547      1.1  christos 	    }
    548      1.1  christos 	  else if (bit (inst1, 7))
    549      1.1  christos 	    base += bits (inst2, 0, 11);
    550      1.1  christos 	  else if (bit (inst2, 11))
    551      1.1  christos 	    {
    552      1.1  christos 	      if (bit (inst2, 10))
    553      1.1  christos 		{
    554      1.1  christos 		  if (bit (inst2, 9))
    555      1.1  christos 		    base += bits (inst2, 0, 7);
    556      1.1  christos 		  else
    557      1.1  christos 		    base -= bits (inst2, 0, 7);
    558      1.1  christos 		}
    559      1.1  christos 	    }
    560      1.1  christos 	  else if ((inst2 & 0x0fc0) == 0x0000)
    561      1.1  christos 	    {
    562      1.1  christos 	      int shift = bits (inst2, 4, 5), rm = bits (inst2, 0, 3);
    563      1.1  christos 	      base += regcache_raw_get_unsigned (regcache, rm) << shift;
    564      1.1  christos 	    }
    565      1.1  christos 	  else
    566      1.1  christos 	    /* Reserved.  */
    567      1.1  christos 	    load_pc = 0;
    568      1.1  christos 
    569      1.1  christos 	  if (load_pc)
    570      1.1  christos 	    nextpc
    571      1.1  christos 	      = self->ops->read_mem_uint (base, 4, byte_order);
    572      1.1  christos 	}
    573      1.1  christos       else if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf000)
    574      1.1  christos 	{
    575      1.1  christos 	  /* TBB.  */
    576      1.1  christos 	  CORE_ADDR tbl_reg, table, offset, length;
    577      1.1  christos 
    578      1.1  christos 	  tbl_reg = bits (inst1, 0, 3);
    579      1.1  christos 	  if (tbl_reg == 0x0f)
    580      1.1  christos 	    table = pc + 4;  /* Regcache copy of PC isn't right yet.  */
    581      1.1  christos 	  else
    582      1.1  christos 	    table = regcache_raw_get_unsigned (regcache, tbl_reg);
    583      1.1  christos 
    584      1.1  christos 	  offset = regcache_raw_get_unsigned (regcache, bits (inst2, 0, 3));
    585      1.1  christos 	  length = 2 * self->ops->read_mem_uint (table + offset, 1, byte_order);
    586      1.1  christos 	  nextpc = pc_val + length;
    587      1.1  christos 	}
    588      1.1  christos       else if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf010)
    589      1.1  christos 	{
    590      1.1  christos 	  /* TBH.  */
    591      1.1  christos 	  CORE_ADDR tbl_reg, table, offset, length;
    592      1.1  christos 
    593      1.1  christos 	  tbl_reg = bits (inst1, 0, 3);
    594      1.1  christos 	  if (tbl_reg == 0x0f)
    595      1.1  christos 	    table = pc + 4;  /* Regcache copy of PC isn't right yet.  */
    596      1.1  christos 	  else
    597      1.1  christos 	    table = regcache_raw_get_unsigned (regcache, tbl_reg);
    598      1.1  christos 
    599      1.1  christos 	  offset = 2 * regcache_raw_get_unsigned (regcache, bits (inst2, 0, 3));
    600      1.1  christos 	  length = 2 * self->ops->read_mem_uint (table + offset, 2, byte_order);
    601      1.1  christos 	  nextpc = pc_val + length;
    602      1.1  christos 	}
    603      1.1  christos     }
    604      1.1  christos   else if ((inst1 & 0xff00) == 0x4700)	/* bx REG, blx REG */
    605      1.1  christos     {
    606      1.1  christos       if (bits (inst1, 3, 6) == 0x0f)
    607      1.1  christos 	nextpc = UNMAKE_THUMB_ADDR (pc_val);
    608      1.1  christos       else
    609      1.1  christos 	nextpc = regcache_raw_get_unsigned (regcache, bits (inst1, 3, 6));
    610      1.1  christos     }
    611      1.1  christos   else if ((inst1 & 0xff87) == 0x4687)	/* mov pc, REG */
    612      1.1  christos     {
    613      1.1  christos       if (bits (inst1, 3, 6) == 0x0f)
    614      1.1  christos 	nextpc = pc_val;
    615      1.1  christos       else
    616      1.1  christos 	nextpc = regcache_raw_get_unsigned (regcache, bits (inst1, 3, 6));
    617      1.1  christos 
    618      1.1  christos       nextpc = MAKE_THUMB_ADDR (nextpc);
    619      1.1  christos     }
    620      1.1  christos   else if ((inst1 & 0xf500) == 0xb100)
    621      1.1  christos     {
    622      1.1  christos       /* CBNZ or CBZ.  */
    623      1.1  christos       int imm = (bit (inst1, 9) << 6) + (bits (inst1, 3, 7) << 1);
    624      1.1  christos       ULONGEST reg = regcache_raw_get_unsigned (regcache, bits (inst1, 0, 2));
    625      1.1  christos 
    626      1.1  christos       if (bit (inst1, 11) && reg != 0)
    627      1.1  christos 	nextpc = pc_val + imm;
    628      1.1  christos       else if (!bit (inst1, 11) && reg == 0)
    629      1.1  christos 	nextpc = pc_val + imm;
    630      1.1  christos     }
    631      1.1  christos 
    632  1.1.1.3  christos   next_pcs.push_back (nextpc);
    633      1.1  christos 
    634      1.1  christos   return next_pcs;
    635      1.1  christos }
    636      1.1  christos 
    637      1.1  christos /* Get the raw next possible addresses.  PC in next_pcs is the current program
    638      1.1  christos    counter, which is assumed to be executing in ARM mode.
    639      1.1  christos 
    640      1.1  christos    The values returned have the execution state of the next instruction
    641      1.1  christos    encoded in it.  Use IS_THUMB_ADDR () to see whether the instruction is
    642      1.1  christos    in Thumb-State, and gdbarch_addr_bits_remove () to get the plain memory
    643      1.1  christos    address in GDB and arm_addr_bits_remove in GDBServer.  */
    644      1.1  christos 
    645  1.1.1.3  christos static std::vector<CORE_ADDR>
    646      1.1  christos arm_get_next_pcs_raw (struct arm_get_next_pcs *self)
    647      1.1  christos {
    648      1.1  christos   int byte_order = self->byte_order;
    649      1.1  christos   int byte_order_for_code = self->byte_order_for_code;
    650      1.1  christos   unsigned long pc_val;
    651      1.1  christos   unsigned long this_instr = 0;
    652      1.1  christos   unsigned long status;
    653      1.1  christos   CORE_ADDR nextpc;
    654      1.1  christos   struct regcache *regcache = self->regcache;
    655      1.1  christos   CORE_ADDR pc = regcache_read_pc (self->regcache);
    656  1.1.1.3  christos   std::vector<CORE_ADDR> next_pcs;
    657      1.1  christos 
    658      1.1  christos   pc_val = (unsigned long) pc;
    659      1.1  christos   this_instr = self->ops->read_mem_uint (pc, 4, byte_order_for_code);
    660      1.1  christos 
    661      1.1  christos   status = regcache_raw_get_unsigned (regcache, ARM_PS_REGNUM);
    662      1.1  christos   nextpc = (CORE_ADDR) (pc_val + 4);	/* Default case */
    663      1.1  christos 
    664      1.1  christos   if (bits (this_instr, 28, 31) == INST_NV)
    665      1.1  christos     switch (bits (this_instr, 24, 27))
    666      1.1  christos       {
    667      1.1  christos       case 0xa:
    668      1.1  christos       case 0xb:
    669      1.1  christos 	{
    670      1.1  christos 	  /* Branch with Link and change to Thumb.  */
    671      1.1  christos 	  nextpc = BranchDest (pc, this_instr);
    672      1.1  christos 	  nextpc |= bit (this_instr, 24) << 1;
    673      1.1  christos 	  nextpc = MAKE_THUMB_ADDR (nextpc);
    674      1.1  christos 	  break;
    675      1.1  christos 	}
    676      1.1  christos       case 0xc:
    677      1.1  christos       case 0xd:
    678      1.1  christos       case 0xe:
    679      1.1  christos 	/* Coprocessor register transfer.  */
    680      1.1  christos         if (bits (this_instr, 12, 15) == 15)
    681      1.1  christos 	  error (_("Invalid update to pc in instruction"));
    682      1.1  christos 	break;
    683      1.1  christos       }
    684      1.1  christos   else if (condition_true (bits (this_instr, 28, 31), status))
    685      1.1  christos     {
    686      1.1  christos       switch (bits (this_instr, 24, 27))
    687      1.1  christos 	{
    688      1.1  christos 	case 0x0:
    689      1.1  christos 	case 0x1:			/* data processing */
    690      1.1  christos 	case 0x2:
    691      1.1  christos 	case 0x3:
    692      1.1  christos 	  {
    693      1.1  christos 	    unsigned long operand1, operand2, result = 0;
    694      1.1  christos 	    unsigned long rn;
    695      1.1  christos 	    int c;
    696      1.1  christos 
    697      1.1  christos 	    if (bits (this_instr, 12, 15) != 15)
    698      1.1  christos 	      break;
    699      1.1  christos 
    700      1.1  christos 	    if (bits (this_instr, 22, 25) == 0
    701      1.1  christos 		&& bits (this_instr, 4, 7) == 9)	/* multiply */
    702      1.1  christos 	      error (_("Invalid update to pc in instruction"));
    703      1.1  christos 
    704      1.1  christos 	    /* BX <reg>, BLX <reg> */
    705      1.1  christos 	    if (bits (this_instr, 4, 27) == 0x12fff1
    706      1.1  christos 		|| bits (this_instr, 4, 27) == 0x12fff3)
    707      1.1  christos 	      {
    708      1.1  christos 		rn = bits (this_instr, 0, 3);
    709      1.1  christos 		nextpc = ((rn == ARM_PC_REGNUM)
    710      1.1  christos 			  ? (pc_val + 8)
    711      1.1  christos 			  : regcache_raw_get_unsigned (regcache, rn));
    712      1.1  christos 
    713  1.1.1.3  christos 		next_pcs.push_back (nextpc);
    714      1.1  christos 		return next_pcs;
    715      1.1  christos 	      }
    716      1.1  christos 
    717      1.1  christos 	    /* Multiply into PC.  */
    718      1.1  christos 	    c = (status & FLAG_C) ? 1 : 0;
    719      1.1  christos 	    rn = bits (this_instr, 16, 19);
    720      1.1  christos 	    operand1 = ((rn == ARM_PC_REGNUM)
    721      1.1  christos 			? (pc_val + 8)
    722      1.1  christos 			: regcache_raw_get_unsigned (regcache, rn));
    723      1.1  christos 
    724      1.1  christos 	    if (bit (this_instr, 25))
    725      1.1  christos 	      {
    726      1.1  christos 		unsigned long immval = bits (this_instr, 0, 7);
    727      1.1  christos 		unsigned long rotate = 2 * bits (this_instr, 8, 11);
    728      1.1  christos 		operand2 = ((immval >> rotate) | (immval << (32 - rotate)))
    729      1.1  christos 		  & 0xffffffff;
    730      1.1  christos 	      }
    731      1.1  christos 	    else		/* operand 2 is a shifted register.  */
    732      1.1  christos 	      operand2 = shifted_reg_val (regcache, this_instr, c,
    733      1.1  christos 					  pc_val, status);
    734      1.1  christos 
    735      1.1  christos 	    switch (bits (this_instr, 21, 24))
    736      1.1  christos 	      {
    737      1.1  christos 	      case 0x0:	/*and */
    738      1.1  christos 		result = operand1 & operand2;
    739      1.1  christos 		break;
    740      1.1  christos 
    741      1.1  christos 	      case 0x1:	/*eor */
    742      1.1  christos 		result = operand1 ^ operand2;
    743      1.1  christos 		break;
    744      1.1  christos 
    745      1.1  christos 	      case 0x2:	/*sub */
    746      1.1  christos 		result = operand1 - operand2;
    747      1.1  christos 		break;
    748      1.1  christos 
    749      1.1  christos 	      case 0x3:	/*rsb */
    750      1.1  christos 		result = operand2 - operand1;
    751      1.1  christos 		break;
    752      1.1  christos 
    753      1.1  christos 	      case 0x4:	/*add */
    754      1.1  christos 		result = operand1 + operand2;
    755      1.1  christos 		break;
    756      1.1  christos 
    757      1.1  christos 	      case 0x5:	/*adc */
    758      1.1  christos 		result = operand1 + operand2 + c;
    759      1.1  christos 		break;
    760      1.1  christos 
    761      1.1  christos 	      case 0x6:	/*sbc */
    762      1.1  christos 		result = operand1 - operand2 + c;
    763      1.1  christos 		break;
    764      1.1  christos 
    765      1.1  christos 	      case 0x7:	/*rsc */
    766      1.1  christos 		result = operand2 - operand1 + c;
    767      1.1  christos 		break;
    768      1.1  christos 
    769      1.1  christos 	      case 0x8:
    770      1.1  christos 	      case 0x9:
    771      1.1  christos 	      case 0xa:
    772      1.1  christos 	      case 0xb:	/* tst, teq, cmp, cmn */
    773      1.1  christos 		result = (unsigned long) nextpc;
    774      1.1  christos 		break;
    775      1.1  christos 
    776      1.1  christos 	      case 0xc:	/*orr */
    777      1.1  christos 		result = operand1 | operand2;
    778      1.1  christos 		break;
    779      1.1  christos 
    780      1.1  christos 	      case 0xd:	/*mov */
    781      1.1  christos 		/* Always step into a function.  */
    782      1.1  christos 		result = operand2;
    783      1.1  christos 		break;
    784      1.1  christos 
    785      1.1  christos 	      case 0xe:	/*bic */
    786      1.1  christos 		result = operand1 & ~operand2;
    787      1.1  christos 		break;
    788      1.1  christos 
    789      1.1  christos 	      case 0xf:	/*mvn */
    790      1.1  christos 		result = ~operand2;
    791      1.1  christos 		break;
    792      1.1  christos 	      }
    793      1.1  christos 	      nextpc = self->ops->addr_bits_remove (self, result);
    794      1.1  christos 	    break;
    795      1.1  christos 	  }
    796      1.1  christos 
    797      1.1  christos 	case 0x4:
    798      1.1  christos 	case 0x5:		/* data transfer */
    799      1.1  christos 	case 0x6:
    800      1.1  christos 	case 0x7:
    801      1.1  christos 	  if (bits (this_instr, 25, 27) == 0x3 && bit (this_instr, 4) == 1)
    802      1.1  christos 	    {
    803      1.1  christos 	      /* Media instructions and architecturally undefined
    804      1.1  christos 		 instructions.  */
    805      1.1  christos 	      break;
    806      1.1  christos 	    }
    807      1.1  christos 
    808      1.1  christos 	  if (bit (this_instr, 20))
    809      1.1  christos 	    {
    810      1.1  christos 	      /* load */
    811      1.1  christos 	      if (bits (this_instr, 12, 15) == 15)
    812      1.1  christos 		{
    813      1.1  christos 		  /* rd == pc */
    814      1.1  christos 		  unsigned long rn;
    815      1.1  christos 		  unsigned long base;
    816      1.1  christos 
    817      1.1  christos 		  if (bit (this_instr, 22))
    818      1.1  christos 		    error (_("Invalid update to pc in instruction"));
    819      1.1  christos 
    820      1.1  christos 		  /* byte write to PC */
    821      1.1  christos 		  rn = bits (this_instr, 16, 19);
    822      1.1  christos 		  base = ((rn == ARM_PC_REGNUM)
    823      1.1  christos 			  ? (pc_val + 8)
    824      1.1  christos 			  : regcache_raw_get_unsigned (regcache, rn));
    825      1.1  christos 
    826      1.1  christos 		  if (bit (this_instr, 24))
    827      1.1  christos 		    {
    828      1.1  christos 		      /* pre-indexed */
    829      1.1  christos 		      int c = (status & FLAG_C) ? 1 : 0;
    830      1.1  christos 		      unsigned long offset =
    831      1.1  christos 		      (bit (this_instr, 25)
    832      1.1  christos 		       ? shifted_reg_val (regcache, this_instr, c,
    833      1.1  christos 					  pc_val, status)
    834      1.1  christos 		       : bits (this_instr, 0, 11));
    835      1.1  christos 
    836      1.1  christos 		      if (bit (this_instr, 23))
    837      1.1  christos 			base += offset;
    838      1.1  christos 		      else
    839      1.1  christos 			base -= offset;
    840      1.1  christos 		    }
    841      1.1  christos 		  nextpc
    842      1.1  christos 		    = (CORE_ADDR) self->ops->read_mem_uint ((CORE_ADDR) base,
    843      1.1  christos 							    4, byte_order);
    844      1.1  christos 		}
    845      1.1  christos 	    }
    846      1.1  christos 	  break;
    847      1.1  christos 
    848      1.1  christos 	case 0x8:
    849      1.1  christos 	case 0x9:		/* block transfer */
    850      1.1  christos 	  if (bit (this_instr, 20))
    851      1.1  christos 	    {
    852      1.1  christos 	      /* LDM */
    853      1.1  christos 	      if (bit (this_instr, 15))
    854      1.1  christos 		{
    855      1.1  christos 		  /* loading pc */
    856      1.1  christos 		  int offset = 0;
    857      1.1  christos 		  CORE_ADDR rn_val_offset = 0;
    858      1.1  christos 		  unsigned long rn_val
    859      1.1  christos 		    = regcache_raw_get_unsigned (regcache,
    860      1.1  christos 						 bits (this_instr, 16, 19));
    861      1.1  christos 
    862      1.1  christos 		  if (bit (this_instr, 23))
    863      1.1  christos 		    {
    864      1.1  christos 		      /* up */
    865      1.1  christos 		      unsigned long reglist = bits (this_instr, 0, 14);
    866      1.1  christos 		      offset = bitcount (reglist) * 4;
    867      1.1  christos 		      if (bit (this_instr, 24))		/* pre */
    868      1.1  christos 			offset += 4;
    869      1.1  christos 		    }
    870      1.1  christos 		  else if (bit (this_instr, 24))
    871      1.1  christos 		    offset = -4;
    872      1.1  christos 
    873      1.1  christos 		  rn_val_offset = rn_val + offset;
    874      1.1  christos 		  nextpc = (CORE_ADDR) self->ops->read_mem_uint (rn_val_offset,
    875      1.1  christos 								 4, byte_order);
    876      1.1  christos 		}
    877      1.1  christos 	    }
    878      1.1  christos 	  break;
    879      1.1  christos 
    880      1.1  christos 	case 0xb:		/* branch & link */
    881      1.1  christos 	case 0xa:		/* branch */
    882      1.1  christos 	  {
    883      1.1  christos 	    nextpc = BranchDest (pc, this_instr);
    884      1.1  christos 	    break;
    885      1.1  christos 	  }
    886      1.1  christos 
    887      1.1  christos 	case 0xc:
    888      1.1  christos 	case 0xd:
    889      1.1  christos 	case 0xe:		/* coproc ops */
    890      1.1  christos 	  break;
    891      1.1  christos 	case 0xf:		/* SWI */
    892      1.1  christos 	  {
    893      1.1  christos 	    nextpc = self->ops->syscall_next_pc (self);
    894      1.1  christos 	  }
    895      1.1  christos 	  break;
    896      1.1  christos 
    897      1.1  christos 	default:
    898      1.1  christos 	  error (_("Bad bit-field extraction"));
    899      1.1  christos 	  return next_pcs;
    900      1.1  christos 	}
    901      1.1  christos     }
    902      1.1  christos 
    903  1.1.1.3  christos   next_pcs.push_back (nextpc);
    904  1.1.1.3  christos 
    905      1.1  christos   return next_pcs;
    906      1.1  christos }
    907      1.1  christos 
    908      1.1  christos /* See arm-get-next-pcs.h.  */
    909      1.1  christos 
    910  1.1.1.3  christos std::vector<CORE_ADDR>
    911      1.1  christos arm_get_next_pcs (struct arm_get_next_pcs *self)
    912      1.1  christos {
    913  1.1.1.3  christos   std::vector<CORE_ADDR> next_pcs;
    914      1.1  christos 
    915      1.1  christos   if (self->ops->is_thumb (self))
    916      1.1  christos     {
    917      1.1  christos       next_pcs = thumb_deal_with_atomic_sequence_raw (self);
    918  1.1.1.3  christos       if (next_pcs.empty ())
    919      1.1  christos 	next_pcs = thumb_get_next_pcs_raw (self);
    920      1.1  christos     }
    921      1.1  christos   else
    922      1.1  christos     {
    923      1.1  christos       next_pcs = arm_deal_with_atomic_sequence_raw (self);
    924  1.1.1.3  christos       if (next_pcs.empty ())
    925      1.1  christos 	next_pcs = arm_get_next_pcs_raw (self);
    926      1.1  christos     }
    927      1.1  christos 
    928      1.1  christos   if (self->ops->fixup != NULL)
    929      1.1  christos     {
    930  1.1.1.3  christos       for (CORE_ADDR &pc_ref : next_pcs)
    931  1.1.1.3  christos 	pc_ref = self->ops->fixup (self, pc_ref);
    932      1.1  christos     }
    933  1.1.1.3  christos 
    934      1.1  christos   return next_pcs;
    935      1.1  christos }
    936