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