1 /* Common target dependent code for GDB on ARM systems. 2 3 Copyright (C) 1988-2023 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 "gdbsupport/common-defs.h" 21 #include "gdbsupport/common-regcache.h" 22 #include "arm.h" 23 24 #include "../features/arm/arm-core.c" 25 #include "../features/arm/arm-tls.c" 26 #include "../features/arm/arm-vfpv2.c" 27 #include "../features/arm/arm-vfpv3.c" 28 #include "../features/arm/xscale-iwmmxt.c" 29 #include "../features/arm/arm-m-profile.c" 30 #include "../features/arm/arm-m-profile-with-fpa.c" 31 #include "../features/arm/arm-m-profile-mve.c" 32 #include "../features/arm/arm-m-system.c" 33 34 /* See arm.h. */ 35 36 int 37 thumb_insn_size (unsigned short inst1) 38 { 39 if ((inst1 & 0xe000) == 0xe000 && (inst1 & 0x1800) != 0) 40 return 4; 41 else 42 return 2; 43 } 44 45 /* See arm.h. */ 46 47 int 48 condition_true (unsigned long cond, unsigned long status_reg) 49 { 50 if (cond == INST_AL || cond == INST_NV) 51 return 1; 52 53 switch (cond) 54 { 55 case INST_EQ: 56 return ((status_reg & FLAG_Z) != 0); 57 case INST_NE: 58 return ((status_reg & FLAG_Z) == 0); 59 case INST_CS: 60 return ((status_reg & FLAG_C) != 0); 61 case INST_CC: 62 return ((status_reg & FLAG_C) == 0); 63 case INST_MI: 64 return ((status_reg & FLAG_N) != 0); 65 case INST_PL: 66 return ((status_reg & FLAG_N) == 0); 67 case INST_VS: 68 return ((status_reg & FLAG_V) != 0); 69 case INST_VC: 70 return ((status_reg & FLAG_V) == 0); 71 case INST_HI: 72 return ((status_reg & (FLAG_C | FLAG_Z)) == FLAG_C); 73 case INST_LS: 74 return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C); 75 case INST_GE: 76 return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0)); 77 case INST_LT: 78 return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0)); 79 case INST_GT: 80 return (((status_reg & FLAG_Z) == 0) 81 && (((status_reg & FLAG_N) == 0) 82 == ((status_reg & FLAG_V) == 0))); 83 case INST_LE: 84 return (((status_reg & FLAG_Z) != 0) 85 || (((status_reg & FLAG_N) == 0) 86 != ((status_reg & FLAG_V) == 0))); 87 } 88 return 1; 89 } 90 91 92 /* See arm.h. */ 93 94 int 95 thumb_advance_itstate (unsigned int itstate) 96 { 97 /* Preserve IT[7:5], the first three bits of the condition. Shift 98 the upcoming condition flags left by one bit. */ 99 itstate = (itstate & 0xe0) | ((itstate << 1) & 0x1f); 100 101 /* If we have finished the IT block, clear the state. */ 102 if ((itstate & 0x0f) == 0) 103 itstate = 0; 104 105 return itstate; 106 } 107 108 /* See arm.h. */ 109 110 int 111 arm_instruction_changes_pc (uint32_t this_instr) 112 { 113 if (bits (this_instr, 28, 31) == INST_NV) 114 /* Unconditional instructions. */ 115 switch (bits (this_instr, 24, 27)) 116 { 117 case 0xa: 118 case 0xb: 119 /* Branch with Link and change to Thumb. */ 120 return 1; 121 case 0xc: 122 case 0xd: 123 case 0xe: 124 /* Coprocessor register transfer. */ 125 if (bits (this_instr, 12, 15) == 15) 126 error (_("Invalid update to pc in instruction")); 127 return 0; 128 default: 129 return 0; 130 } 131 else 132 switch (bits (this_instr, 25, 27)) 133 { 134 case 0x0: 135 if (bits (this_instr, 23, 24) == 2 && bit (this_instr, 20) == 0) 136 { 137 /* Multiplies and extra load/stores. */ 138 if (bit (this_instr, 4) == 1 && bit (this_instr, 7) == 1) 139 /* Neither multiplies nor extension load/stores are allowed 140 to modify PC. */ 141 return 0; 142 143 /* Otherwise, miscellaneous instructions. */ 144 145 /* BX <reg>, BXJ <reg>, BLX <reg> */ 146 if (bits (this_instr, 4, 27) == 0x12fff1 147 || bits (this_instr, 4, 27) == 0x12fff2 148 || bits (this_instr, 4, 27) == 0x12fff3) 149 return 1; 150 151 /* Other miscellaneous instructions are unpredictable if they 152 modify PC. */ 153 return 0; 154 } 155 /* Data processing instruction. */ 156 /* 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 (_("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 375 /* See arch/arm.h. */ 376 377 target_desc * 378 arm_create_target_description (arm_fp_type fp_type, bool tls) 379 { 380 target_desc_up tdesc = allocate_target_description (); 381 382 #ifndef IN_PROCESS_AGENT 383 if (fp_type == ARM_FP_TYPE_IWMMXT) 384 set_tdesc_architecture (tdesc.get (), "iwmmxt"); 385 else 386 set_tdesc_architecture (tdesc.get (), "arm"); 387 #endif 388 389 long regnum = 0; 390 391 regnum = create_feature_arm_arm_core (tdesc.get (), regnum); 392 393 switch (fp_type) 394 { 395 case ARM_FP_TYPE_NONE: 396 break; 397 398 case ARM_FP_TYPE_VFPV2: 399 regnum = create_feature_arm_arm_vfpv2 (tdesc.get (), regnum); 400 break; 401 402 case ARM_FP_TYPE_VFPV3: 403 regnum = create_feature_arm_arm_vfpv3 (tdesc.get (), regnum); 404 break; 405 406 case ARM_FP_TYPE_IWMMXT: 407 regnum = create_feature_arm_xscale_iwmmxt (tdesc.get (), regnum); 408 break; 409 410 default: 411 error (_("Invalid Arm FP type: %d"), fp_type); 412 } 413 414 if (tls) 415 regnum = create_feature_arm_arm_tls (tdesc.get (), regnum); 416 417 return tdesc.release (); 418 } 419 420 /* See arch/arm.h. */ 421 422 target_desc * 423 arm_create_mprofile_target_description (arm_m_profile_type m_type) 424 { 425 target_desc *tdesc = allocate_target_description ().release (); 426 427 #ifndef IN_PROCESS_AGENT 428 set_tdesc_architecture (tdesc, "arm"); 429 #endif 430 431 long regnum = 0; 432 433 switch (m_type) 434 { 435 case ARM_M_TYPE_M_PROFILE: 436 regnum = create_feature_arm_arm_m_profile (tdesc, regnum); 437 break; 438 439 case ARM_M_TYPE_VFP_D16: 440 regnum = create_feature_arm_arm_m_profile (tdesc, regnum); 441 regnum = create_feature_arm_arm_vfpv2 (tdesc, regnum); 442 break; 443 444 case ARM_M_TYPE_WITH_FPA: 445 regnum = create_feature_arm_arm_m_profile_with_fpa (tdesc, regnum); 446 break; 447 448 case ARM_M_TYPE_MVE: 449 regnum = create_feature_arm_arm_m_profile (tdesc, regnum); 450 regnum = create_feature_arm_arm_vfpv2 (tdesc, regnum); 451 regnum = create_feature_arm_arm_m_profile_mve (tdesc, regnum); 452 break; 453 454 case ARM_M_TYPE_SYSTEM: 455 regnum = create_feature_arm_arm_m_profile (tdesc, regnum); 456 regnum = create_feature_arm_arm_m_system (tdesc, regnum); 457 break; 458 459 default: 460 error (_("Invalid Arm M type: %d"), m_type); 461 } 462 463 return tdesc; 464 } 465