Home | History | Annotate | Line # | Download | only in arch
arm.c revision 1.1.1.4
      1      1.1  christos /* Common target dependent code for GDB on ARM systems.
      2      1.1  christos 
      3  1.1.1.4  christos    Copyright (C) 1988-2020 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.4  christos #include "gdbsupport/common-defs.h"
     21  1.1.1.4  christos #include "gdbsupport/common-regcache.h"
     22      1.1  christos #include "arm.h"
     23      1.1  christos 
     24  1.1.1.4  christos #include "../features/arm/arm-core.c"
     25  1.1.1.4  christos #include "../features/arm/arm-vfpv2.c"
     26  1.1.1.4  christos #include "../features/arm/arm-vfpv3.c"
     27  1.1.1.4  christos #include "../features/arm/xscale-iwmmxt.c"
     28  1.1.1.4  christos #include "../features/arm/arm-m-profile.c"
     29  1.1.1.4  christos #include "../features/arm/arm-m-profile-with-fpa.c"
     30  1.1.1.4  christos 
     31      1.1  christos /* See arm.h.  */
     32      1.1  christos 
     33      1.1  christos int
     34      1.1  christos thumb_insn_size (unsigned short inst1)
     35      1.1  christos {
     36      1.1  christos   if ((inst1 & 0xe000) == 0xe000 && (inst1 & 0x1800) != 0)
     37      1.1  christos     return 4;
     38      1.1  christos   else
     39      1.1  christos     return 2;
     40      1.1  christos }
     41      1.1  christos 
     42      1.1  christos /* See arm.h.  */
     43      1.1  christos 
     44      1.1  christos int
     45      1.1  christos condition_true (unsigned long cond, unsigned long status_reg)
     46      1.1  christos {
     47      1.1  christos   if (cond == INST_AL || cond == INST_NV)
     48      1.1  christos     return 1;
     49      1.1  christos 
     50      1.1  christos   switch (cond)
     51      1.1  christos     {
     52      1.1  christos     case INST_EQ:
     53      1.1  christos       return ((status_reg & FLAG_Z) != 0);
     54      1.1  christos     case INST_NE:
     55      1.1  christos       return ((status_reg & FLAG_Z) == 0);
     56      1.1  christos     case INST_CS:
     57      1.1  christos       return ((status_reg & FLAG_C) != 0);
     58      1.1  christos     case INST_CC:
     59      1.1  christos       return ((status_reg & FLAG_C) == 0);
     60      1.1  christos     case INST_MI:
     61      1.1  christos       return ((status_reg & FLAG_N) != 0);
     62      1.1  christos     case INST_PL:
     63      1.1  christos       return ((status_reg & FLAG_N) == 0);
     64      1.1  christos     case INST_VS:
     65      1.1  christos       return ((status_reg & FLAG_V) != 0);
     66      1.1  christos     case INST_VC:
     67      1.1  christos       return ((status_reg & FLAG_V) == 0);
     68      1.1  christos     case INST_HI:
     69      1.1  christos       return ((status_reg & (FLAG_C | FLAG_Z)) == FLAG_C);
     70      1.1  christos     case INST_LS:
     71      1.1  christos       return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C);
     72      1.1  christos     case INST_GE:
     73      1.1  christos       return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0));
     74      1.1  christos     case INST_LT:
     75      1.1  christos       return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0));
     76      1.1  christos     case INST_GT:
     77      1.1  christos       return (((status_reg & FLAG_Z) == 0)
     78      1.1  christos 	      && (((status_reg & FLAG_N) == 0)
     79      1.1  christos 		  == ((status_reg & FLAG_V) == 0)));
     80      1.1  christos     case INST_LE:
     81      1.1  christos       return (((status_reg & FLAG_Z) != 0)
     82      1.1  christos 	      || (((status_reg & FLAG_N) == 0)
     83      1.1  christos 		  != ((status_reg & FLAG_V) == 0)));
     84      1.1  christos     }
     85      1.1  christos   return 1;
     86      1.1  christos }
     87      1.1  christos 
     88      1.1  christos 
     89      1.1  christos /* See arm.h.  */
     90      1.1  christos 
     91      1.1  christos int
     92      1.1  christos thumb_advance_itstate (unsigned int itstate)
     93      1.1  christos {
     94      1.1  christos   /* Preserve IT[7:5], the first three bits of the condition.  Shift
     95      1.1  christos      the upcoming condition flags left by one bit.  */
     96      1.1  christos   itstate = (itstate & 0xe0) | ((itstate << 1) & 0x1f);
     97      1.1  christos 
     98      1.1  christos   /* If we have finished the IT block, clear the state.  */
     99      1.1  christos   if ((itstate & 0x0f) == 0)
    100      1.1  christos     itstate = 0;
    101      1.1  christos 
    102      1.1  christos   return itstate;
    103      1.1  christos }
    104      1.1  christos 
    105      1.1  christos /* See arm.h.  */
    106      1.1  christos 
    107      1.1  christos int
    108      1.1  christos arm_instruction_changes_pc (uint32_t this_instr)
    109      1.1  christos {
    110      1.1  christos   if (bits (this_instr, 28, 31) == INST_NV)
    111      1.1  christos     /* Unconditional instructions.  */
    112      1.1  christos     switch (bits (this_instr, 24, 27))
    113      1.1  christos       {
    114      1.1  christos       case 0xa:
    115      1.1  christos       case 0xb:
    116      1.1  christos 	/* Branch with Link and change to Thumb.  */
    117      1.1  christos 	return 1;
    118      1.1  christos       case 0xc:
    119      1.1  christos       case 0xd:
    120      1.1  christos       case 0xe:
    121      1.1  christos 	/* Coprocessor register transfer.  */
    122      1.1  christos         if (bits (this_instr, 12, 15) == 15)
    123      1.1  christos 	  error (_("Invalid update to pc in instruction"));
    124      1.1  christos 	return 0;
    125      1.1  christos       default:
    126      1.1  christos 	return 0;
    127      1.1  christos       }
    128      1.1  christos   else
    129      1.1  christos     switch (bits (this_instr, 25, 27))
    130      1.1  christos       {
    131      1.1  christos       case 0x0:
    132      1.1  christos 	if (bits (this_instr, 23, 24) == 2 && bit (this_instr, 20) == 0)
    133      1.1  christos 	  {
    134      1.1  christos 	    /* Multiplies and extra load/stores.  */
    135      1.1  christos 	    if (bit (this_instr, 4) == 1 && bit (this_instr, 7) == 1)
    136      1.1  christos 	      /* Neither multiplies nor extension load/stores are allowed
    137      1.1  christos 		 to modify PC.  */
    138      1.1  christos 	      return 0;
    139      1.1  christos 
    140      1.1  christos 	    /* Otherwise, miscellaneous instructions.  */
    141      1.1  christos 
    142      1.1  christos 	    /* BX <reg>, BXJ <reg>, BLX <reg> */
    143      1.1  christos 	    if (bits (this_instr, 4, 27) == 0x12fff1
    144      1.1  christos 		|| bits (this_instr, 4, 27) == 0x12fff2
    145      1.1  christos 		|| bits (this_instr, 4, 27) == 0x12fff3)
    146      1.1  christos 	      return 1;
    147      1.1  christos 
    148      1.1  christos 	    /* Other miscellaneous instructions are unpredictable if they
    149      1.1  christos 	       modify PC.  */
    150      1.1  christos 	    return 0;
    151      1.1  christos 	  }
    152  1.1.1.3  christos 	/* Data processing instruction.  */
    153  1.1.1.3  christos 	/* Fall through.  */
    154      1.1  christos 
    155      1.1  christos       case 0x1:
    156      1.1  christos 	if (bits (this_instr, 12, 15) == 15)
    157      1.1  christos 	  return 1;
    158      1.1  christos 	else
    159      1.1  christos 	  return 0;
    160      1.1  christos 
    161      1.1  christos       case 0x2:
    162      1.1  christos       case 0x3:
    163      1.1  christos 	/* Media instructions and architecturally undefined instructions.  */
    164      1.1  christos 	if (bits (this_instr, 25, 27) == 3 && bit (this_instr, 4) == 1)
    165      1.1  christos 	  return 0;
    166      1.1  christos 
    167      1.1  christos 	/* Stores.  */
    168      1.1  christos 	if (bit (this_instr, 20) == 0)
    169      1.1  christos 	  return 0;
    170      1.1  christos 
    171      1.1  christos 	/* Loads.  */
    172      1.1  christos 	if (bits (this_instr, 12, 15) == ARM_PC_REGNUM)
    173      1.1  christos 	  return 1;
    174      1.1  christos 	else
    175      1.1  christos 	  return 0;
    176      1.1  christos 
    177      1.1  christos       case 0x4:
    178      1.1  christos 	/* Load/store multiple.  */
    179      1.1  christos 	if (bit (this_instr, 20) == 1 && bit (this_instr, 15) == 1)
    180      1.1  christos 	  return 1;
    181      1.1  christos 	else
    182      1.1  christos 	  return 0;
    183      1.1  christos 
    184      1.1  christos       case 0x5:
    185      1.1  christos 	/* Branch and branch with link.  */
    186      1.1  christos 	return 1;
    187      1.1  christos 
    188      1.1  christos       case 0x6:
    189      1.1  christos       case 0x7:
    190      1.1  christos 	/* Coprocessor transfers or SWIs can not affect PC.  */
    191      1.1  christos 	return 0;
    192      1.1  christos 
    193      1.1  christos       default:
    194      1.1  christos 	internal_error (__FILE__, __LINE__, _("bad value in switch"));
    195      1.1  christos       }
    196      1.1  christos }
    197      1.1  christos 
    198      1.1  christos /* See arm.h.  */
    199      1.1  christos 
    200      1.1  christos int
    201      1.1  christos thumb_instruction_changes_pc (unsigned short inst)
    202      1.1  christos {
    203      1.1  christos   if ((inst & 0xff00) == 0xbd00)	/* pop {rlist, pc} */
    204      1.1  christos     return 1;
    205      1.1  christos 
    206      1.1  christos   if ((inst & 0xf000) == 0xd000)	/* conditional branch */
    207      1.1  christos     return 1;
    208      1.1  christos 
    209      1.1  christos   if ((inst & 0xf800) == 0xe000)	/* unconditional branch */
    210      1.1  christos     return 1;
    211      1.1  christos 
    212      1.1  christos   if ((inst & 0xff00) == 0x4700)	/* bx REG, blx REG */
    213      1.1  christos     return 1;
    214      1.1  christos 
    215      1.1  christos   if ((inst & 0xff87) == 0x4687)	/* mov pc, REG */
    216      1.1  christos     return 1;
    217      1.1  christos 
    218      1.1  christos   if ((inst & 0xf500) == 0xb100)	/* CBNZ or CBZ.  */
    219      1.1  christos     return 1;
    220      1.1  christos 
    221      1.1  christos   return 0;
    222      1.1  christos }
    223      1.1  christos 
    224      1.1  christos 
    225      1.1  christos /* See arm.h.  */
    226      1.1  christos 
    227      1.1  christos int
    228      1.1  christos thumb2_instruction_changes_pc (unsigned short inst1, unsigned short inst2)
    229      1.1  christos {
    230      1.1  christos   if ((inst1 & 0xf800) == 0xf000 && (inst2 & 0x8000) == 0x8000)
    231      1.1  christos     {
    232      1.1  christos       /* Branches and miscellaneous control instructions.  */
    233      1.1  christos 
    234      1.1  christos       if ((inst2 & 0x1000) != 0 || (inst2 & 0xd001) == 0xc000)
    235      1.1  christos 	{
    236      1.1  christos 	  /* B, BL, BLX.  */
    237      1.1  christos 	  return 1;
    238      1.1  christos 	}
    239      1.1  christos       else if (inst1 == 0xf3de && (inst2 & 0xff00) == 0x3f00)
    240      1.1  christos 	{
    241      1.1  christos 	  /* SUBS PC, LR, #imm8.  */
    242      1.1  christos 	  return 1;
    243      1.1  christos 	}
    244      1.1  christos       else if ((inst2 & 0xd000) == 0x8000 && (inst1 & 0x0380) != 0x0380)
    245      1.1  christos 	{
    246      1.1  christos 	  /* Conditional branch.  */
    247      1.1  christos 	  return 1;
    248      1.1  christos 	}
    249      1.1  christos 
    250      1.1  christos       return 0;
    251      1.1  christos     }
    252      1.1  christos 
    253      1.1  christos   if ((inst1 & 0xfe50) == 0xe810)
    254      1.1  christos     {
    255      1.1  christos       /* Load multiple or RFE.  */
    256      1.1  christos 
    257      1.1  christos       if (bit (inst1, 7) && !bit (inst1, 8))
    258      1.1  christos 	{
    259      1.1  christos 	  /* LDMIA or POP */
    260      1.1  christos 	  if (bit (inst2, 15))
    261      1.1  christos 	    return 1;
    262      1.1  christos 	}
    263      1.1  christos       else if (!bit (inst1, 7) && bit (inst1, 8))
    264      1.1  christos 	{
    265      1.1  christos 	  /* LDMDB */
    266      1.1  christos 	  if (bit (inst2, 15))
    267      1.1  christos 	    return 1;
    268      1.1  christos 	}
    269      1.1  christos       else if (bit (inst1, 7) && bit (inst1, 8))
    270      1.1  christos 	{
    271      1.1  christos 	  /* RFEIA */
    272      1.1  christos 	  return 1;
    273      1.1  christos 	}
    274      1.1  christos       else if (!bit (inst1, 7) && !bit (inst1, 8))
    275      1.1  christos 	{
    276      1.1  christos 	  /* RFEDB */
    277      1.1  christos 	  return 1;
    278      1.1  christos 	}
    279      1.1  christos 
    280      1.1  christos       return 0;
    281      1.1  christos     }
    282      1.1  christos 
    283      1.1  christos   if ((inst1 & 0xffef) == 0xea4f && (inst2 & 0xfff0) == 0x0f00)
    284      1.1  christos     {
    285      1.1  christos       /* MOV PC or MOVS PC.  */
    286      1.1  christos       return 1;
    287      1.1  christos     }
    288      1.1  christos 
    289      1.1  christos   if ((inst1 & 0xff70) == 0xf850 && (inst2 & 0xf000) == 0xf000)
    290      1.1  christos     {
    291      1.1  christos       /* LDR PC.  */
    292      1.1  christos       if (bits (inst1, 0, 3) == 15)
    293      1.1  christos 	return 1;
    294      1.1  christos       if (bit (inst1, 7))
    295      1.1  christos 	return 1;
    296      1.1  christos       if (bit (inst2, 11))
    297      1.1  christos 	return 1;
    298      1.1  christos       if ((inst2 & 0x0fc0) == 0x0000)
    299      1.1  christos 	return 1;
    300      1.1  christos 
    301      1.1  christos       return 0;
    302      1.1  christos     }
    303      1.1  christos 
    304      1.1  christos   if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf000)
    305      1.1  christos     {
    306      1.1  christos       /* TBB.  */
    307      1.1  christos       return 1;
    308      1.1  christos     }
    309      1.1  christos 
    310      1.1  christos   if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf010)
    311      1.1  christos     {
    312      1.1  christos       /* TBH.  */
    313      1.1  christos       return 1;
    314      1.1  christos     }
    315      1.1  christos 
    316      1.1  christos   return 0;
    317      1.1  christos }
    318      1.1  christos 
    319      1.1  christos /* See arm.h.  */
    320      1.1  christos 
    321      1.1  christos unsigned long
    322      1.1  christos shifted_reg_val (struct regcache *regcache, unsigned long inst,
    323      1.1  christos 		 int carry, unsigned long pc_val, unsigned long status_reg)
    324      1.1  christos {
    325      1.1  christos   unsigned long res, shift;
    326      1.1  christos   int rm = bits (inst, 0, 3);
    327      1.1  christos   unsigned long shifttype = bits (inst, 5, 6);
    328      1.1  christos 
    329      1.1  christos   if (bit (inst, 4))
    330      1.1  christos     {
    331      1.1  christos       int rs = bits (inst, 8, 11);
    332      1.1  christos       shift = (rs == 15
    333      1.1  christos 	       ? pc_val + 8
    334      1.1  christos 	       : regcache_raw_get_unsigned (regcache, rs)) & 0xFF;
    335      1.1  christos     }
    336      1.1  christos   else
    337      1.1  christos     shift = bits (inst, 7, 11);
    338      1.1  christos 
    339      1.1  christos   res = (rm == ARM_PC_REGNUM
    340      1.1  christos 	 ? (pc_val + (bit (inst, 4) ? 12 : 8))
    341      1.1  christos 	 : regcache_raw_get_unsigned (regcache, rm));
    342      1.1  christos 
    343      1.1  christos   switch (shifttype)
    344      1.1  christos     {
    345      1.1  christos     case 0:			/* LSL */
    346      1.1  christos       res = shift >= 32 ? 0 : res << shift;
    347      1.1  christos       break;
    348      1.1  christos 
    349      1.1  christos     case 1:			/* LSR */
    350      1.1  christos       res = shift >= 32 ? 0 : res >> shift;
    351      1.1  christos       break;
    352      1.1  christos 
    353      1.1  christos     case 2:			/* ASR */
    354      1.1  christos       if (shift >= 32)
    355      1.1  christos 	shift = 31;
    356      1.1  christos       res = ((res & 0x80000000L)
    357      1.1  christos 	     ? ~((~res) >> shift) : res >> shift);
    358      1.1  christos       break;
    359      1.1  christos 
    360      1.1  christos     case 3:			/* ROR/RRX */
    361      1.1  christos       shift &= 31;
    362      1.1  christos       if (shift == 0)
    363      1.1  christos 	res = (res >> 1) | (carry ? 0x80000000L : 0);
    364      1.1  christos       else
    365      1.1  christos 	res = (res >> shift) | (res << (32 - shift));
    366      1.1  christos       break;
    367      1.1  christos     }
    368      1.1  christos 
    369      1.1  christos   return res & 0xffffffff;
    370      1.1  christos }
    371  1.1.1.4  christos 
    372  1.1.1.4  christos /* See arch/arm.h.  */
    373  1.1.1.4  christos 
    374  1.1.1.4  christos target_desc *
    375  1.1.1.4  christos arm_create_target_description (arm_fp_type fp_type)
    376  1.1.1.4  christos {
    377  1.1.1.4  christos   target_desc *tdesc = allocate_target_description ();
    378  1.1.1.4  christos 
    379  1.1.1.4  christos #ifndef IN_PROCESS_AGENT
    380  1.1.1.4  christos   if (fp_type == ARM_FP_TYPE_IWMMXT)
    381  1.1.1.4  christos     set_tdesc_architecture (tdesc, "iwmmxt");
    382  1.1.1.4  christos   else
    383  1.1.1.4  christos     set_tdesc_architecture (tdesc, "arm");
    384  1.1.1.4  christos #endif
    385  1.1.1.4  christos 
    386  1.1.1.4  christos   long regnum = 0;
    387  1.1.1.4  christos 
    388  1.1.1.4  christos   regnum = create_feature_arm_arm_core (tdesc, regnum);
    389  1.1.1.4  christos 
    390  1.1.1.4  christos   switch (fp_type)
    391  1.1.1.4  christos     {
    392  1.1.1.4  christos     case ARM_FP_TYPE_NONE:
    393  1.1.1.4  christos       break;
    394  1.1.1.4  christos 
    395  1.1.1.4  christos     case ARM_FP_TYPE_VFPV2:
    396  1.1.1.4  christos       regnum = create_feature_arm_arm_vfpv2 (tdesc, regnum);
    397  1.1.1.4  christos       break;
    398  1.1.1.4  christos 
    399  1.1.1.4  christos     case ARM_FP_TYPE_VFPV3:
    400  1.1.1.4  christos       regnum = create_feature_arm_arm_vfpv3 (tdesc, regnum);
    401  1.1.1.4  christos       break;
    402  1.1.1.4  christos 
    403  1.1.1.4  christos     case ARM_FP_TYPE_IWMMXT:
    404  1.1.1.4  christos       regnum = create_feature_arm_xscale_iwmmxt (tdesc, regnum);
    405  1.1.1.4  christos       break;
    406  1.1.1.4  christos 
    407  1.1.1.4  christos     default:
    408  1.1.1.4  christos       error (_("Invalid Arm FP type: %d"), fp_type);
    409  1.1.1.4  christos     }
    410  1.1.1.4  christos 
    411  1.1.1.4  christos   return tdesc;
    412  1.1.1.4  christos }
    413  1.1.1.4  christos 
    414  1.1.1.4  christos /* See arch/arm.h.  */
    415  1.1.1.4  christos 
    416  1.1.1.4  christos target_desc *
    417  1.1.1.4  christos arm_create_mprofile_target_description (arm_m_profile_type m_type)
    418  1.1.1.4  christos {
    419  1.1.1.4  christos   target_desc *tdesc = allocate_target_description ();
    420  1.1.1.4  christos 
    421  1.1.1.4  christos #ifndef IN_PROCESS_AGENT
    422  1.1.1.4  christos   set_tdesc_architecture (tdesc, "arm");
    423  1.1.1.4  christos #endif
    424  1.1.1.4  christos 
    425  1.1.1.4  christos   long regnum = 0;
    426  1.1.1.4  christos 
    427  1.1.1.4  christos   switch (m_type)
    428  1.1.1.4  christos     {
    429  1.1.1.4  christos     case ARM_M_TYPE_M_PROFILE:
    430  1.1.1.4  christos       regnum = create_feature_arm_arm_m_profile (tdesc, regnum);
    431  1.1.1.4  christos       break;
    432  1.1.1.4  christos 
    433  1.1.1.4  christos     case ARM_M_TYPE_VFP_D16:
    434  1.1.1.4  christos       regnum = create_feature_arm_arm_m_profile (tdesc, regnum);
    435  1.1.1.4  christos       regnum = create_feature_arm_arm_vfpv2 (tdesc, regnum);
    436  1.1.1.4  christos       break;
    437  1.1.1.4  christos 
    438  1.1.1.4  christos     case ARM_M_TYPE_WITH_FPA:
    439  1.1.1.4  christos       regnum = create_feature_arm_arm_m_profile_with_fpa (tdesc, regnum);
    440  1.1.1.4  christos       break;
    441  1.1.1.4  christos 
    442  1.1.1.4  christos     default:
    443  1.1.1.4  christos       error (_("Invalid Arm M type: %d"), m_type);
    444  1.1.1.4  christos     }
    445  1.1.1.4  christos 
    446  1.1.1.4  christos   return tdesc;
    447  1.1.1.4  christos }
    448