Home | History | Annotate | Line # | Download | only in arch
arm.c revision 1.1.1.1.4.1
      1 /* Common target dependent code for GDB on ARM systems.
      2 
      3    Copyright (C) 1988-2017 Free Software Foundation, Inc.
      4 
      5    This file is part of GDB.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19 
     20 #include "common-defs.h"
     21 #include "common-regcache.h"
     22 #include "arm.h"
     23 
     24 /* See arm.h.  */
     25 
     26 int
     27 thumb_insn_size (unsigned short inst1)
     28 {
     29   if ((inst1 & 0xe000) == 0xe000 && (inst1 & 0x1800) != 0)
     30     return 4;
     31   else
     32     return 2;
     33 }
     34 
     35 /* See arm.h.  */
     36 
     37 int
     38 bitcount (unsigned long val)
     39 {
     40   int nbits;
     41   for (nbits = 0; val != 0; nbits++)
     42     val &= val - 1;		/* Delete rightmost 1-bit in val.  */
     43   return nbits;
     44 }
     45 
     46 /* See arm.h.  */
     47 
     48 int
     49 condition_true (unsigned long cond, unsigned long status_reg)
     50 {
     51   if (cond == INST_AL || cond == INST_NV)
     52     return 1;
     53 
     54   switch (cond)
     55     {
     56     case INST_EQ:
     57       return ((status_reg & FLAG_Z) != 0);
     58     case INST_NE:
     59       return ((status_reg & FLAG_Z) == 0);
     60     case INST_CS:
     61       return ((status_reg & FLAG_C) != 0);
     62     case INST_CC:
     63       return ((status_reg & FLAG_C) == 0);
     64     case INST_MI:
     65       return ((status_reg & FLAG_N) != 0);
     66     case INST_PL:
     67       return ((status_reg & FLAG_N) == 0);
     68     case INST_VS:
     69       return ((status_reg & FLAG_V) != 0);
     70     case INST_VC:
     71       return ((status_reg & FLAG_V) == 0);
     72     case INST_HI:
     73       return ((status_reg & (FLAG_C | FLAG_Z)) == FLAG_C);
     74     case INST_LS:
     75       return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C);
     76     case INST_GE:
     77       return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0));
     78     case INST_LT:
     79       return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0));
     80     case INST_GT:
     81       return (((status_reg & FLAG_Z) == 0)
     82 	      && (((status_reg & FLAG_N) == 0)
     83 		  == ((status_reg & FLAG_V) == 0)));
     84     case INST_LE:
     85       return (((status_reg & FLAG_Z) != 0)
     86 	      || (((status_reg & FLAG_N) == 0)
     87 		  != ((status_reg & FLAG_V) == 0)));
     88     }
     89   return 1;
     90 }
     91 
     92 
     93 /* See arm.h.  */
     94 
     95 int
     96 thumb_advance_itstate (unsigned int itstate)
     97 {
     98   /* Preserve IT[7:5], the first three bits of the condition.  Shift
     99      the upcoming condition flags left by one bit.  */
    100   itstate = (itstate & 0xe0) | ((itstate << 1) & 0x1f);
    101 
    102   /* If we have finished the IT block, clear the state.  */
    103   if ((itstate & 0x0f) == 0)
    104     itstate = 0;
    105 
    106   return itstate;
    107 }
    108 
    109 /* See arm.h.  */
    110 
    111 int
    112 arm_instruction_changes_pc (uint32_t this_instr)
    113 {
    114   if (bits (this_instr, 28, 31) == INST_NV)
    115     /* Unconditional instructions.  */
    116     switch (bits (this_instr, 24, 27))
    117       {
    118       case 0xa:
    119       case 0xb:
    120 	/* Branch with Link and change to Thumb.  */
    121 	return 1;
    122       case 0xc:
    123       case 0xd:
    124       case 0xe:
    125 	/* Coprocessor register transfer.  */
    126         if (bits (this_instr, 12, 15) == 15)
    127 	  error (_("Invalid update to pc in instruction"));
    128 	return 0;
    129       default:
    130 	return 0;
    131       }
    132   else
    133     switch (bits (this_instr, 25, 27))
    134       {
    135       case 0x0:
    136 	if (bits (this_instr, 23, 24) == 2 && bit (this_instr, 20) == 0)
    137 	  {
    138 	    /* Multiplies and extra load/stores.  */
    139 	    if (bit (this_instr, 4) == 1 && bit (this_instr, 7) == 1)
    140 	      /* Neither multiplies nor extension load/stores are allowed
    141 		 to modify PC.  */
    142 	      return 0;
    143 
    144 	    /* Otherwise, miscellaneous instructions.  */
    145 
    146 	    /* BX <reg>, BXJ <reg>, BLX <reg> */
    147 	    if (bits (this_instr, 4, 27) == 0x12fff1
    148 		|| bits (this_instr, 4, 27) == 0x12fff2
    149 		|| bits (this_instr, 4, 27) == 0x12fff3)
    150 	      return 1;
    151 
    152 	    /* Other miscellaneous instructions are unpredictable if they
    153 	       modify PC.  */
    154 	    return 0;
    155 	  }
    156 	/* Data processing instruction.  Fall through.  */
    157 
    158       case 0x1:
    159 	if (bits (this_instr, 12, 15) == 15)
    160 	  return 1;
    161 	else
    162 	  return 0;
    163 
    164       case 0x2:
    165       case 0x3:
    166 	/* Media instructions and architecturally undefined instructions.  */
    167 	if (bits (this_instr, 25, 27) == 3 && bit (this_instr, 4) == 1)
    168 	  return 0;
    169 
    170 	/* Stores.  */
    171 	if (bit (this_instr, 20) == 0)
    172 	  return 0;
    173 
    174 	/* Loads.  */
    175 	if (bits (this_instr, 12, 15) == ARM_PC_REGNUM)
    176 	  return 1;
    177 	else
    178 	  return 0;
    179 
    180       case 0x4:
    181 	/* Load/store multiple.  */
    182 	if (bit (this_instr, 20) == 1 && bit (this_instr, 15) == 1)
    183 	  return 1;
    184 	else
    185 	  return 0;
    186 
    187       case 0x5:
    188 	/* Branch and branch with link.  */
    189 	return 1;
    190 
    191       case 0x6:
    192       case 0x7:
    193 	/* Coprocessor transfers or SWIs can not affect PC.  */
    194 	return 0;
    195 
    196       default:
    197 	internal_error (__FILE__, __LINE__, _("bad value in switch"));
    198       }
    199 }
    200 
    201 /* See arm.h.  */
    202 
    203 int
    204 thumb_instruction_changes_pc (unsigned short inst)
    205 {
    206   if ((inst & 0xff00) == 0xbd00)	/* pop {rlist, pc} */
    207     return 1;
    208 
    209   if ((inst & 0xf000) == 0xd000)	/* conditional branch */
    210     return 1;
    211 
    212   if ((inst & 0xf800) == 0xe000)	/* unconditional branch */
    213     return 1;
    214 
    215   if ((inst & 0xff00) == 0x4700)	/* bx REG, blx REG */
    216     return 1;
    217 
    218   if ((inst & 0xff87) == 0x4687)	/* mov pc, REG */
    219     return 1;
    220 
    221   if ((inst & 0xf500) == 0xb100)	/* CBNZ or CBZ.  */
    222     return 1;
    223 
    224   return 0;
    225 }
    226 
    227 
    228 /* See arm.h.  */
    229 
    230 int
    231 thumb2_instruction_changes_pc (unsigned short inst1, unsigned short inst2)
    232 {
    233   if ((inst1 & 0xf800) == 0xf000 && (inst2 & 0x8000) == 0x8000)
    234     {
    235       /* Branches and miscellaneous control instructions.  */
    236 
    237       if ((inst2 & 0x1000) != 0 || (inst2 & 0xd001) == 0xc000)
    238 	{
    239 	  /* B, BL, BLX.  */
    240 	  return 1;
    241 	}
    242       else if (inst1 == 0xf3de && (inst2 & 0xff00) == 0x3f00)
    243 	{
    244 	  /* SUBS PC, LR, #imm8.  */
    245 	  return 1;
    246 	}
    247       else if ((inst2 & 0xd000) == 0x8000 && (inst1 & 0x0380) != 0x0380)
    248 	{
    249 	  /* Conditional branch.  */
    250 	  return 1;
    251 	}
    252 
    253       return 0;
    254     }
    255 
    256   if ((inst1 & 0xfe50) == 0xe810)
    257     {
    258       /* Load multiple or RFE.  */
    259 
    260       if (bit (inst1, 7) && !bit (inst1, 8))
    261 	{
    262 	  /* LDMIA or POP */
    263 	  if (bit (inst2, 15))
    264 	    return 1;
    265 	}
    266       else if (!bit (inst1, 7) && bit (inst1, 8))
    267 	{
    268 	  /* LDMDB */
    269 	  if (bit (inst2, 15))
    270 	    return 1;
    271 	}
    272       else if (bit (inst1, 7) && bit (inst1, 8))
    273 	{
    274 	  /* RFEIA */
    275 	  return 1;
    276 	}
    277       else if (!bit (inst1, 7) && !bit (inst1, 8))
    278 	{
    279 	  /* RFEDB */
    280 	  return 1;
    281 	}
    282 
    283       return 0;
    284     }
    285 
    286   if ((inst1 & 0xffef) == 0xea4f && (inst2 & 0xfff0) == 0x0f00)
    287     {
    288       /* MOV PC or MOVS PC.  */
    289       return 1;
    290     }
    291 
    292   if ((inst1 & 0xff70) == 0xf850 && (inst2 & 0xf000) == 0xf000)
    293     {
    294       /* LDR PC.  */
    295       if (bits (inst1, 0, 3) == 15)
    296 	return 1;
    297       if (bit (inst1, 7))
    298 	return 1;
    299       if (bit (inst2, 11))
    300 	return 1;
    301       if ((inst2 & 0x0fc0) == 0x0000)
    302 	return 1;
    303 
    304       return 0;
    305     }
    306 
    307   if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf000)
    308     {
    309       /* TBB.  */
    310       return 1;
    311     }
    312 
    313   if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf010)
    314     {
    315       /* TBH.  */
    316       return 1;
    317     }
    318 
    319   return 0;
    320 }
    321 
    322 /* See arm.h.  */
    323 
    324 unsigned long
    325 shifted_reg_val (struct regcache *regcache, unsigned long inst,
    326 		 int carry, unsigned long pc_val, unsigned long status_reg)
    327 {
    328   unsigned long res, shift;
    329   int rm = bits (inst, 0, 3);
    330   unsigned long shifttype = bits (inst, 5, 6);
    331 
    332   if (bit (inst, 4))
    333     {
    334       int rs = bits (inst, 8, 11);
    335       shift = (rs == 15
    336 	       ? pc_val + 8
    337 	       : regcache_raw_get_unsigned (regcache, rs)) & 0xFF;
    338     }
    339   else
    340     shift = bits (inst, 7, 11);
    341 
    342   res = (rm == ARM_PC_REGNUM
    343 	 ? (pc_val + (bit (inst, 4) ? 12 : 8))
    344 	 : regcache_raw_get_unsigned (regcache, rm));
    345 
    346   switch (shifttype)
    347     {
    348     case 0:			/* LSL */
    349       res = shift >= 32 ? 0 : res << shift;
    350       break;
    351 
    352     case 1:			/* LSR */
    353       res = shift >= 32 ? 0 : res >> shift;
    354       break;
    355 
    356     case 2:			/* ASR */
    357       if (shift >= 32)
    358 	shift = 31;
    359       res = ((res & 0x80000000L)
    360 	     ? ~((~res) >> shift) : res >> shift);
    361       break;
    362 
    363     case 3:			/* ROR/RRX */
    364       shift &= 31;
    365       if (shift == 0)
    366 	res = (res >> 1) | (carry ? 0x80000000L : 0);
    367       else
    368 	res = (res >> shift) | (res << (32 - shift));
    369       break;
    370     }
    371 
    372   return res & 0xffffffff;
    373 }
    374