Document the GDB 10.2 release in gdb/ChangeLog
[binutils-gdb.git] / gdb / arch / arm.c
blob7407c4a7dadd8358c5cd7ac779b0b7b70e054021
1 /* Common target dependent code for GDB on ARM systems.
3 Copyright (C) 1988-2021 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #include "gdbsupport/common-defs.h"
21 #include "gdbsupport/common-regcache.h"
22 #include "arm.h"
24 #include "../features/arm/arm-core.c"
25 #include "../features/arm/arm-vfpv2.c"
26 #include "../features/arm/arm-vfpv3.c"
27 #include "../features/arm/xscale-iwmmxt.c"
28 #include "../features/arm/arm-m-profile.c"
29 #include "../features/arm/arm-m-profile-with-fpa.c"
31 /* See arm.h. */
33 int
34 thumb_insn_size (unsigned short inst1)
36 if ((inst1 & 0xe000) == 0xe000 && (inst1 & 0x1800) != 0)
37 return 4;
38 else
39 return 2;
42 /* See arm.h. */
44 int
45 condition_true (unsigned long cond, unsigned long status_reg)
47 if (cond == INST_AL || cond == INST_NV)
48 return 1;
50 switch (cond)
52 case INST_EQ:
53 return ((status_reg & FLAG_Z) != 0);
54 case INST_NE:
55 return ((status_reg & FLAG_Z) == 0);
56 case INST_CS:
57 return ((status_reg & FLAG_C) != 0);
58 case INST_CC:
59 return ((status_reg & FLAG_C) == 0);
60 case INST_MI:
61 return ((status_reg & FLAG_N) != 0);
62 case INST_PL:
63 return ((status_reg & FLAG_N) == 0);
64 case INST_VS:
65 return ((status_reg & FLAG_V) != 0);
66 case INST_VC:
67 return ((status_reg & FLAG_V) == 0);
68 case INST_HI:
69 return ((status_reg & (FLAG_C | FLAG_Z)) == FLAG_C);
70 case INST_LS:
71 return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C);
72 case INST_GE:
73 return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0));
74 case INST_LT:
75 return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0));
76 case INST_GT:
77 return (((status_reg & FLAG_Z) == 0)
78 && (((status_reg & FLAG_N) == 0)
79 == ((status_reg & FLAG_V) == 0)));
80 case INST_LE:
81 return (((status_reg & FLAG_Z) != 0)
82 || (((status_reg & FLAG_N) == 0)
83 != ((status_reg & FLAG_V) == 0)));
85 return 1;
89 /* See arm.h. */
91 int
92 thumb_advance_itstate (unsigned int itstate)
94 /* Preserve IT[7:5], the first three bits of the condition. Shift
95 the upcoming condition flags left by one bit. */
96 itstate = (itstate & 0xe0) | ((itstate << 1) & 0x1f);
98 /* If we have finished the IT block, clear the state. */
99 if ((itstate & 0x0f) == 0)
100 itstate = 0;
102 return itstate;
105 /* See arm.h. */
108 arm_instruction_changes_pc (uint32_t this_instr)
110 if (bits (this_instr, 28, 31) == INST_NV)
111 /* Unconditional instructions. */
112 switch (bits (this_instr, 24, 27))
114 case 0xa:
115 case 0xb:
116 /* Branch with Link and change to Thumb. */
117 return 1;
118 case 0xc:
119 case 0xd:
120 case 0xe:
121 /* Coprocessor register transfer. */
122 if (bits (this_instr, 12, 15) == 15)
123 error (_("Invalid update to pc in instruction"));
124 return 0;
125 default:
126 return 0;
128 else
129 switch (bits (this_instr, 25, 27))
131 case 0x0:
132 if (bits (this_instr, 23, 24) == 2 && bit (this_instr, 20) == 0)
134 /* Multiplies and extra load/stores. */
135 if (bit (this_instr, 4) == 1 && bit (this_instr, 7) == 1)
136 /* Neither multiplies nor extension load/stores are allowed
137 to modify PC. */
138 return 0;
140 /* Otherwise, miscellaneous instructions. */
142 /* BX <reg>, BXJ <reg>, BLX <reg> */
143 if (bits (this_instr, 4, 27) == 0x12fff1
144 || bits (this_instr, 4, 27) == 0x12fff2
145 || bits (this_instr, 4, 27) == 0x12fff3)
146 return 1;
148 /* Other miscellaneous instructions are unpredictable if they
149 modify PC. */
150 return 0;
152 /* Data processing instruction. */
153 /* Fall through. */
155 case 0x1:
156 if (bits (this_instr, 12, 15) == 15)
157 return 1;
158 else
159 return 0;
161 case 0x2:
162 case 0x3:
163 /* Media instructions and architecturally undefined instructions. */
164 if (bits (this_instr, 25, 27) == 3 && bit (this_instr, 4) == 1)
165 return 0;
167 /* Stores. */
168 if (bit (this_instr, 20) == 0)
169 return 0;
171 /* Loads. */
172 if (bits (this_instr, 12, 15) == ARM_PC_REGNUM)
173 return 1;
174 else
175 return 0;
177 case 0x4:
178 /* Load/store multiple. */
179 if (bit (this_instr, 20) == 1 && bit (this_instr, 15) == 1)
180 return 1;
181 else
182 return 0;
184 case 0x5:
185 /* Branch and branch with link. */
186 return 1;
188 case 0x6:
189 case 0x7:
190 /* Coprocessor transfers or SWIs can not affect PC. */
191 return 0;
193 default:
194 internal_error (__FILE__, __LINE__, _("bad value in switch"));
198 /* See arm.h. */
201 thumb_instruction_changes_pc (unsigned short inst)
203 if ((inst & 0xff00) == 0xbd00) /* pop {rlist, pc} */
204 return 1;
206 if ((inst & 0xf000) == 0xd000) /* conditional branch */
207 return 1;
209 if ((inst & 0xf800) == 0xe000) /* unconditional branch */
210 return 1;
212 if ((inst & 0xff00) == 0x4700) /* bx REG, blx REG */
213 return 1;
215 if ((inst & 0xff87) == 0x4687) /* mov pc, REG */
216 return 1;
218 if ((inst & 0xf500) == 0xb100) /* CBNZ or CBZ. */
219 return 1;
221 return 0;
225 /* See arm.h. */
228 thumb2_instruction_changes_pc (unsigned short inst1, unsigned short inst2)
230 if ((inst1 & 0xf800) == 0xf000 && (inst2 & 0x8000) == 0x8000)
232 /* Branches and miscellaneous control instructions. */
234 if ((inst2 & 0x1000) != 0 || (inst2 & 0xd001) == 0xc000)
236 /* B, BL, BLX. */
237 return 1;
239 else if (inst1 == 0xf3de && (inst2 & 0xff00) == 0x3f00)
241 /* SUBS PC, LR, #imm8. */
242 return 1;
244 else if ((inst2 & 0xd000) == 0x8000 && (inst1 & 0x0380) != 0x0380)
246 /* Conditional branch. */
247 return 1;
250 return 0;
253 if ((inst1 & 0xfe50) == 0xe810)
255 /* Load multiple or RFE. */
257 if (bit (inst1, 7) && !bit (inst1, 8))
259 /* LDMIA or POP */
260 if (bit (inst2, 15))
261 return 1;
263 else if (!bit (inst1, 7) && bit (inst1, 8))
265 /* LDMDB */
266 if (bit (inst2, 15))
267 return 1;
269 else if (bit (inst1, 7) && bit (inst1, 8))
271 /* RFEIA */
272 return 1;
274 else if (!bit (inst1, 7) && !bit (inst1, 8))
276 /* RFEDB */
277 return 1;
280 return 0;
283 if ((inst1 & 0xffef) == 0xea4f && (inst2 & 0xfff0) == 0x0f00)
285 /* MOV PC or MOVS PC. */
286 return 1;
289 if ((inst1 & 0xff70) == 0xf850 && (inst2 & 0xf000) == 0xf000)
291 /* LDR PC. */
292 if (bits (inst1, 0, 3) == 15)
293 return 1;
294 if (bit (inst1, 7))
295 return 1;
296 if (bit (inst2, 11))
297 return 1;
298 if ((inst2 & 0x0fc0) == 0x0000)
299 return 1;
301 return 0;
304 if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf000)
306 /* TBB. */
307 return 1;
310 if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf010)
312 /* TBH. */
313 return 1;
316 return 0;
319 /* See arm.h. */
321 unsigned long
322 shifted_reg_val (struct regcache *regcache, unsigned long inst,
323 int carry, unsigned long pc_val, unsigned long status_reg)
325 unsigned long res, shift;
326 int rm = bits (inst, 0, 3);
327 unsigned long shifttype = bits (inst, 5, 6);
329 if (bit (inst, 4))
331 int rs = bits (inst, 8, 11);
332 shift = (rs == 15
333 ? pc_val + 8
334 : regcache_raw_get_unsigned (regcache, rs)) & 0xFF;
336 else
337 shift = bits (inst, 7, 11);
339 res = (rm == ARM_PC_REGNUM
340 ? (pc_val + (bit (inst, 4) ? 12 : 8))
341 : regcache_raw_get_unsigned (regcache, rm));
343 switch (shifttype)
345 case 0: /* LSL */
346 res = shift >= 32 ? 0 : res << shift;
347 break;
349 case 1: /* LSR */
350 res = shift >= 32 ? 0 : res >> shift;
351 break;
353 case 2: /* ASR */
354 if (shift >= 32)
355 shift = 31;
356 res = ((res & 0x80000000L)
357 ? ~((~res) >> shift) : res >> shift);
358 break;
360 case 3: /* ROR/RRX */
361 shift &= 31;
362 if (shift == 0)
363 res = (res >> 1) | (carry ? 0x80000000L : 0);
364 else
365 res = (res >> shift) | (res << (32 - shift));
366 break;
369 return res & 0xffffffff;
372 /* See arch/arm.h. */
374 target_desc *
375 arm_create_target_description (arm_fp_type fp_type)
377 target_desc_up tdesc = allocate_target_description ();
379 #ifndef IN_PROCESS_AGENT
380 if (fp_type == ARM_FP_TYPE_IWMMXT)
381 set_tdesc_architecture (tdesc.get (), "iwmmxt");
382 else
383 set_tdesc_architecture (tdesc.get (), "arm");
384 #endif
386 long regnum = 0;
388 regnum = create_feature_arm_arm_core (tdesc.get (), regnum);
390 switch (fp_type)
392 case ARM_FP_TYPE_NONE:
393 break;
395 case ARM_FP_TYPE_VFPV2:
396 regnum = create_feature_arm_arm_vfpv2 (tdesc.get (), regnum);
397 break;
399 case ARM_FP_TYPE_VFPV3:
400 regnum = create_feature_arm_arm_vfpv3 (tdesc.get (), regnum);
401 break;
403 case ARM_FP_TYPE_IWMMXT:
404 regnum = create_feature_arm_xscale_iwmmxt (tdesc.get (), regnum);
405 break;
407 default:
408 error (_("Invalid Arm FP type: %d"), fp_type);
411 return tdesc.release ();
414 /* See arch/arm.h. */
416 target_desc *
417 arm_create_mprofile_target_description (arm_m_profile_type m_type)
419 target_desc *tdesc = allocate_target_description ().release ();
421 #ifndef IN_PROCESS_AGENT
422 set_tdesc_architecture (tdesc, "arm");
423 #endif
425 long regnum = 0;
427 switch (m_type)
429 case ARM_M_TYPE_M_PROFILE:
430 regnum = create_feature_arm_arm_m_profile (tdesc, regnum);
431 break;
433 case ARM_M_TYPE_VFP_D16:
434 regnum = create_feature_arm_arm_m_profile (tdesc, regnum);
435 regnum = create_feature_arm_arm_vfpv2 (tdesc, regnum);
436 break;
438 case ARM_M_TYPE_WITH_FPA:
439 regnum = create_feature_arm_arm_m_profile_with_fpa (tdesc, regnum);
440 break;
442 default:
443 error (_("Invalid Arm M type: %d"), m_type);
446 return tdesc;