1 /* Common code for ARM software single stepping support.
3 Copyright (C) 1988-2023 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/gdb_vecs.h"
22 #include "gdbsupport/common-regcache.h"
24 #include "arm-get-next-pcs.h"
25 #include "count-one-bits.h"
27 /* See arm-get-next-pcs.h. */
30 arm_get_next_pcs_ctor (struct arm_get_next_pcs
*self
,
31 struct arm_get_next_pcs_ops
*ops
,
33 int byte_order_for_code
,
34 int has_thumb2_breakpoint
,
35 struct regcache
*regcache
)
38 self
->byte_order
= byte_order
;
39 self
->byte_order_for_code
= byte_order_for_code
;
40 self
->has_thumb2_breakpoint
= has_thumb2_breakpoint
;
41 self
->regcache
= regcache
;
44 /* Checks for an atomic sequence of instructions beginning with a LDREX{,B,H,D}
45 instruction and ending with a STREX{,B,H,D} instruction. If such a sequence
46 is found, attempt to step through it. The end of the sequence address is
47 added to the next_pcs list. */
49 static std::vector
<CORE_ADDR
>
50 thumb_deal_with_atomic_sequence_raw (struct arm_get_next_pcs
*self
)
52 int byte_order_for_code
= self
->byte_order_for_code
;
53 CORE_ADDR breaks
[2] = {CORE_ADDR_MAX
, CORE_ADDR_MAX
};
54 CORE_ADDR pc
= regcache_read_pc (self
->regcache
);
56 unsigned short insn1
, insn2
;
59 int last_breakpoint
= 0; /* Defaults to 0 (no breakpoints placed). */
60 const int atomic_sequence_length
= 16; /* Instruction sequence length. */
61 ULONGEST status
, itstate
;
63 /* We currently do not support atomic sequences within an IT block. */
64 status
= regcache_raw_get_unsigned (self
->regcache
, ARM_PS_REGNUM
);
65 itstate
= ((status
>> 8) & 0xfc) | ((status
>> 25) & 0x3);
69 /* Assume all atomic sequences start with a ldrex{,b,h,d} instruction. */
70 insn1
= self
->ops
->read_mem_uint (loc
, 2, byte_order_for_code
);
73 if (thumb_insn_size (insn1
) != 4)
76 insn2
= self
->ops
->read_mem_uint (loc
, 2, byte_order_for_code
);
79 if (!((insn1
& 0xfff0) == 0xe850
80 || ((insn1
& 0xfff0) == 0xe8d0 && (insn2
& 0x00c0) == 0x0040)))
83 /* Assume that no atomic sequence is longer than "atomic_sequence_length"
85 for (insn_count
= 0; insn_count
< atomic_sequence_length
; ++insn_count
)
87 insn1
= self
->ops
->read_mem_uint (loc
, 2,byte_order_for_code
);
90 if (thumb_insn_size (insn1
) != 4)
92 /* Assume that there is at most one conditional branch in the
93 atomic sequence. If a conditional branch is found, put a
94 breakpoint in its destination address. */
95 if ((insn1
& 0xf000) == 0xd000 && bits (insn1
, 8, 11) != 0x0f)
97 if (last_breakpoint
> 0)
98 return {}; /* More than one conditional branch found,
99 fallback to the standard code. */
101 breaks
[1] = loc
+ 2 + (sbits (insn1
, 0, 7) << 1);
105 /* We do not support atomic sequences that use any *other*
106 instructions but conditional branches to change the PC.
107 Fall back to standard code to avoid losing control of
109 else if (thumb_instruction_changes_pc (insn1
))
114 insn2
= self
->ops
->read_mem_uint (loc
, 2, byte_order_for_code
);
118 /* Assume that there is at most one conditional branch in the
119 atomic sequence. If a conditional branch is found, put a
120 breakpoint in its destination address. */
121 if ((insn1
& 0xf800) == 0xf000
122 && (insn2
& 0xd000) == 0x8000
123 && (insn1
& 0x0380) != 0x0380)
125 int sign
, j1
, j2
, imm1
, imm2
;
128 sign
= sbits (insn1
, 10, 10);
129 imm1
= bits (insn1
, 0, 5);
130 imm2
= bits (insn2
, 0, 10);
131 j1
= bit (insn2
, 13);
132 j2
= bit (insn2
, 11);
134 offset
= (sign
<< 20) + (j2
<< 19) + (j1
<< 18);
135 offset
+= (imm1
<< 12) + (imm2
<< 1);
137 if (last_breakpoint
> 0)
138 return {}; /* More than one conditional branch found,
139 fallback to the standard code. */
141 breaks
[1] = loc
+ offset
;
145 /* We do not support atomic sequences that use any *other*
146 instructions but conditional branches to change the PC.
147 Fall back to standard code to avoid losing control of
149 else if (thumb2_instruction_changes_pc (insn1
, insn2
))
152 /* If we find a strex{,b,h,d}, we're done. */
153 if ((insn1
& 0xfff0) == 0xe840
154 || ((insn1
& 0xfff0) == 0xe8c0 && (insn2
& 0x00c0) == 0x0040))
159 /* If we didn't find the strex{,b,h,d}, we cannot handle the sequence. */
160 if (insn_count
== atomic_sequence_length
)
163 /* Insert a breakpoint right after the end of the atomic sequence. */
166 /* Check for duplicated breakpoints. Check also for a breakpoint
167 placed (branch instruction's destination) anywhere in sequence. */
169 && (breaks
[1] == breaks
[0]
170 || (breaks
[1] >= pc
&& breaks
[1] < loc
)))
173 std::vector
<CORE_ADDR
> next_pcs
;
175 /* Adds the breakpoints to the list to be inserted. */
176 for (index
= 0; index
<= last_breakpoint
; index
++)
177 next_pcs
.push_back (MAKE_THUMB_ADDR (breaks
[index
]));
182 /* Checks for an atomic sequence of instructions beginning with a LDREX{,B,H,D}
183 instruction and ending with a STREX{,B,H,D} instruction. If such a sequence
184 is found, attempt to step through it. The end of the sequence address is
185 added to the next_pcs list. */
187 static std::vector
<CORE_ADDR
>
188 arm_deal_with_atomic_sequence_raw (struct arm_get_next_pcs
*self
)
190 int byte_order_for_code
= self
->byte_order_for_code
;
191 CORE_ADDR breaks
[2] = {CORE_ADDR_MAX
, CORE_ADDR_MAX
};
192 CORE_ADDR pc
= regcache_read_pc (self
->regcache
);
197 int last_breakpoint
= 0; /* Defaults to 0 (no breakpoints placed). */
198 const int atomic_sequence_length
= 16; /* Instruction sequence length. */
200 /* Assume all atomic sequences start with a ldrex{,b,h,d} instruction.
201 Note that we do not currently support conditionally executed atomic
203 insn
= self
->ops
->read_mem_uint (loc
, 4, byte_order_for_code
);
206 if ((insn
& 0xff9000f0) != 0xe1900090)
209 /* Assume that no atomic sequence is longer than "atomic_sequence_length"
211 for (insn_count
= 0; insn_count
< atomic_sequence_length
; ++insn_count
)
213 insn
= self
->ops
->read_mem_uint (loc
, 4, byte_order_for_code
);
217 /* Assume that there is at most one conditional branch in the atomic
218 sequence. If a conditional branch is found, put a breakpoint in
219 its destination address. */
220 if (bits (insn
, 24, 27) == 0xa)
222 if (last_breakpoint
> 0)
223 return {}; /* More than one conditional branch found, fallback
224 to the standard single-step code. */
226 breaks
[1] = BranchDest (loc
- 4, insn
);
230 /* We do not support atomic sequences that use any *other* instructions
231 but conditional branches to change the PC. Fall back to standard
232 code to avoid losing control of execution. */
233 else if (arm_instruction_changes_pc (insn
))
236 /* If we find a strex{,b,h,d}, we're done. */
237 if ((insn
& 0xff9000f0) == 0xe1800090)
241 /* If we didn't find the strex{,b,h,d}, we cannot handle the sequence. */
242 if (insn_count
== atomic_sequence_length
)
245 /* Insert a breakpoint right after the end of the atomic sequence. */
248 /* Check for duplicated breakpoints. Check also for a breakpoint
249 placed (branch instruction's destination) anywhere in sequence. */
251 && (breaks
[1] == breaks
[0]
252 || (breaks
[1] >= pc
&& breaks
[1] < loc
)))
255 std::vector
<CORE_ADDR
> next_pcs
;
257 /* Adds the breakpoints to the list to be inserted. */
258 for (index
= 0; index
<= last_breakpoint
; index
++)
259 next_pcs
.push_back (breaks
[index
]);
264 /* Find the next possible PCs for thumb mode. */
266 static std::vector
<CORE_ADDR
>
267 thumb_get_next_pcs_raw (struct arm_get_next_pcs
*self
)
269 int byte_order
= self
->byte_order
;
270 int byte_order_for_code
= self
->byte_order_for_code
;
271 CORE_ADDR pc
= regcache_read_pc (self
->regcache
);
272 unsigned long pc_val
= ((unsigned long) pc
) + 4; /* PC after prefetch */
273 unsigned short inst1
;
274 CORE_ADDR nextpc
= pc
+ 2; /* Default is next instruction. */
275 ULONGEST status
, itstate
;
276 struct regcache
*regcache
= self
->regcache
;
277 std::vector
<CORE_ADDR
> next_pcs
;
279 nextpc
= MAKE_THUMB_ADDR (nextpc
);
280 pc_val
= MAKE_THUMB_ADDR (pc_val
);
282 inst1
= self
->ops
->read_mem_uint (pc
, 2, byte_order_for_code
);
284 /* Thumb-2 conditional execution support. There are eight bits in
285 the CPSR which describe conditional execution state. Once
286 reconstructed (they're in a funny order), the low five bits
287 describe the low bit of the condition for each instruction and
288 how many instructions remain. The high three bits describe the
289 base condition. One of the low four bits will be set if an IT
290 block is active. These bits read as zero on earlier
292 status
= regcache_raw_get_unsigned (regcache
, ARM_PS_REGNUM
);
293 itstate
= ((status
>> 8) & 0xfc) | ((status
>> 25) & 0x3);
295 /* If-Then handling. On GNU/Linux, where this routine is used, we
296 use an undefined instruction as a breakpoint. Unlike BKPT, IT
297 can disable execution of the undefined instruction. So we might
298 miss the breakpoint if we set it on a skipped conditional
299 instruction. Because conditional instructions can change the
300 flags, affecting the execution of further instructions, we may
301 need to set two breakpoints. */
303 if (self
->has_thumb2_breakpoint
)
305 if ((inst1
& 0xff00) == 0xbf00 && (inst1
& 0x000f) != 0)
307 /* An IT instruction. Because this instruction does not
308 modify the flags, we can accurately predict the next
309 executed instruction. */
310 itstate
= inst1
& 0x00ff;
311 pc
+= thumb_insn_size (inst1
);
313 while (itstate
!= 0 && ! condition_true (itstate
>> 4, status
))
315 inst1
= self
->ops
->read_mem_uint (pc
, 2,byte_order_for_code
);
316 pc
+= thumb_insn_size (inst1
);
317 itstate
= thumb_advance_itstate (itstate
);
320 next_pcs
.push_back (MAKE_THUMB_ADDR (pc
));
323 else if (itstate
!= 0)
325 /* We are in a conditional block. Check the condition. */
326 if (! condition_true (itstate
>> 4, status
))
328 /* Advance to the next executed instruction. */
329 pc
+= thumb_insn_size (inst1
);
330 itstate
= thumb_advance_itstate (itstate
);
332 while (itstate
!= 0 && ! condition_true (itstate
>> 4, status
))
334 inst1
= self
->ops
->read_mem_uint (pc
, 2, byte_order_for_code
);
336 pc
+= thumb_insn_size (inst1
);
337 itstate
= thumb_advance_itstate (itstate
);
340 next_pcs
.push_back (MAKE_THUMB_ADDR (pc
));
343 else if ((itstate
& 0x0f) == 0x08)
345 /* This is the last instruction of the conditional
346 block, and it is executed. We can handle it normally
347 because the following instruction is not conditional,
348 and we must handle it normally because it is
349 permitted to branch. Fall through. */
355 /* There are conditional instructions after this one.
356 If this instruction modifies the flags, then we can
357 not predict what the next executed instruction will
358 be. Fortunately, this instruction is architecturally
359 forbidden to branch; we know it will fall through.
360 Start by skipping past it. */
361 pc
+= thumb_insn_size (inst1
);
362 itstate
= thumb_advance_itstate (itstate
);
364 /* Set a breakpoint on the following instruction. */
365 gdb_assert ((itstate
& 0x0f) != 0);
366 next_pcs
.push_back (MAKE_THUMB_ADDR (pc
));
368 cond_negated
= (itstate
>> 4) & 1;
370 /* Skip all following instructions with the same
371 condition. If there is a later instruction in the IT
372 block with the opposite condition, set the other
373 breakpoint there. If not, then set a breakpoint on
374 the instruction after the IT block. */
377 inst1
= self
->ops
->read_mem_uint (pc
, 2, byte_order_for_code
);
378 pc
+= thumb_insn_size (inst1
);
379 itstate
= thumb_advance_itstate (itstate
);
381 while (itstate
!= 0 && ((itstate
>> 4) & 1) == cond_negated
);
383 next_pcs
.push_back (MAKE_THUMB_ADDR (pc
));
389 else if (itstate
& 0x0f)
391 /* We are in a conditional block. Check the condition. */
392 int cond
= itstate
>> 4;
394 if (! condition_true (cond
, status
))
396 /* Advance to the next instruction. All the 32-bit
397 instructions share a common prefix. */
398 next_pcs
.push_back (MAKE_THUMB_ADDR (pc
+ thumb_insn_size (inst1
)));
403 /* Otherwise, handle the instruction normally. */
406 if ((inst1
& 0xff00) == 0xbd00) /* pop {rlist, pc} */
410 /* Fetch the saved PC from the stack. It's stored above
411 all of the other registers. */
413 = count_one_bits (bits (inst1
, 0, 7)) * ARM_INT_REGISTER_SIZE
;
414 sp
= regcache_raw_get_unsigned (regcache
, ARM_SP_REGNUM
);
415 nextpc
= self
->ops
->read_mem_uint (sp
+ offset
, 4, byte_order
);
417 else if ((inst1
& 0xf000) == 0xd000) /* conditional branch */
419 unsigned long cond
= bits (inst1
, 8, 11);
420 if (cond
== 0x0f) /* 0x0f = SWI */
422 nextpc
= self
->ops
->syscall_next_pc (self
);
424 else if (cond
!= 0x0f && condition_true (cond
, status
))
425 nextpc
= pc_val
+ (sbits (inst1
, 0, 7) << 1);
427 else if ((inst1
& 0xf800) == 0xe000) /* unconditional branch */
429 nextpc
= pc_val
+ (sbits (inst1
, 0, 10) << 1);
431 else if (thumb_insn_size (inst1
) == 4) /* 32-bit instruction */
433 unsigned short inst2
;
434 inst2
= self
->ops
->read_mem_uint (pc
+ 2, 2, byte_order_for_code
);
436 /* Default to the next instruction. */
438 nextpc
= MAKE_THUMB_ADDR (nextpc
);
440 if ((inst1
& 0xf800) == 0xf000 && (inst2
& 0x8000) == 0x8000)
442 /* Branches and miscellaneous control instructions. */
444 if ((inst2
& 0x1000) != 0 || (inst2
& 0xd001) == 0xc000)
447 int j1
, j2
, imm1
, imm2
;
449 imm1
= sbits (inst1
, 0, 10);
450 imm2
= bits (inst2
, 0, 10);
451 j1
= bit (inst2
, 13);
452 j2
= bit (inst2
, 11);
454 unsigned long offset
= ((imm1
<< 12) + (imm2
<< 1));
455 offset
^= ((!j2
) << 22) | ((!j1
) << 23);
457 nextpc
= pc_val
+ offset
;
458 /* For BLX make sure to clear the low bits. */
459 if (bit (inst2
, 12) == 0)
460 nextpc
= nextpc
& 0xfffffffc;
462 else if (inst1
== 0xf3de && (inst2
& 0xff00) == 0x3f00)
464 /* SUBS PC, LR, #imm8. */
465 nextpc
= regcache_raw_get_unsigned (regcache
, ARM_LR_REGNUM
);
466 nextpc
-= inst2
& 0x00ff;
468 else if ((inst2
& 0xd000) == 0x8000 && (inst1
& 0x0380) != 0x0380)
470 /* Conditional branch. */
471 if (condition_true (bits (inst1
, 6, 9), status
))
473 int sign
, j1
, j2
, imm1
, imm2
;
475 sign
= sbits (inst1
, 10, 10);
476 imm1
= bits (inst1
, 0, 5);
477 imm2
= bits (inst2
, 0, 10);
478 j1
= bit (inst2
, 13);
479 j2
= bit (inst2
, 11);
482 = (sign
<< 20) + (j2
<< 19) + (j1
<< 18);
483 offset
+= (imm1
<< 12) + (imm2
<< 1);
485 nextpc
= pc_val
+ offset
;
489 else if ((inst1
& 0xfe50) == 0xe810)
491 /* Load multiple or RFE. */
492 int rn
, offset
, load_pc
= 1;
494 rn
= bits (inst1
, 0, 3);
495 if (bit (inst1
, 7) && !bit (inst1
, 8))
498 if (!bit (inst2
, 15))
500 offset
= count_one_bits (inst2
) * 4 - 4;
502 else if (!bit (inst1
, 7) && bit (inst1
, 8))
505 if (!bit (inst2
, 15))
509 else if (bit (inst1
, 7) && bit (inst1
, 8))
514 else if (!bit (inst1
, 7) && !bit (inst1
, 8))
524 CORE_ADDR addr
= regcache_raw_get_unsigned (regcache
, rn
);
525 nextpc
= self
->ops
->read_mem_uint (addr
+ offset
, 4, byte_order
);
528 else if ((inst1
& 0xffef) == 0xea4f && (inst2
& 0xfff0) == 0x0f00)
530 /* MOV PC or MOVS PC. */
531 nextpc
= regcache_raw_get_unsigned (regcache
, bits (inst2
, 0, 3));
532 nextpc
= MAKE_THUMB_ADDR (nextpc
);
534 else if ((inst1
& 0xff70) == 0xf850 && (inst2
& 0xf000) == 0xf000)
540 rn
= bits (inst1
, 0, 3);
541 base
= regcache_raw_get_unsigned (regcache
, rn
);
542 if (rn
== ARM_PC_REGNUM
)
544 base
= (base
+ 4) & ~(CORE_ADDR
) 0x3;
546 base
+= bits (inst2
, 0, 11);
548 base
-= bits (inst2
, 0, 11);
550 else if (bit (inst1
, 7))
551 base
+= bits (inst2
, 0, 11);
552 else if (bit (inst2
, 11))
557 base
+= bits (inst2
, 0, 7);
559 base
-= bits (inst2
, 0, 7);
562 else if ((inst2
& 0x0fc0) == 0x0000)
564 int shift
= bits (inst2
, 4, 5), rm
= bits (inst2
, 0, 3);
565 base
+= regcache_raw_get_unsigned (regcache
, rm
) << shift
;
573 = self
->ops
->read_mem_uint (base
, 4, byte_order
);
575 else if ((inst1
& 0xfff0) == 0xe8d0 && (inst2
& 0xfff0) == 0xf000)
578 CORE_ADDR tbl_reg
, table
, offset
, length
;
580 tbl_reg
= bits (inst1
, 0, 3);
582 table
= pc
+ 4; /* Regcache copy of PC isn't right yet. */
584 table
= regcache_raw_get_unsigned (regcache
, tbl_reg
);
586 offset
= regcache_raw_get_unsigned (regcache
, bits (inst2
, 0, 3));
587 length
= 2 * self
->ops
->read_mem_uint (table
+ offset
, 1, byte_order
);
588 nextpc
= pc_val
+ length
;
590 else if ((inst1
& 0xfff0) == 0xe8d0 && (inst2
& 0xfff0) == 0xf010)
593 CORE_ADDR tbl_reg
, table
, offset
, length
;
595 tbl_reg
= bits (inst1
, 0, 3);
597 table
= pc
+ 4; /* Regcache copy of PC isn't right yet. */
599 table
= regcache_raw_get_unsigned (regcache
, tbl_reg
);
601 offset
= 2 * regcache_raw_get_unsigned (regcache
, bits (inst2
, 0, 3));
602 length
= 2 * self
->ops
->read_mem_uint (table
+ offset
, 2, byte_order
);
603 nextpc
= pc_val
+ length
;
606 else if ((inst1
& 0xff00) == 0x4700) /* bx REG, blx REG */
608 if (bits (inst1
, 3, 6) == 0x0f)
609 nextpc
= UNMAKE_THUMB_ADDR (pc_val
);
611 nextpc
= regcache_raw_get_unsigned (regcache
, bits (inst1
, 3, 6));
613 else if ((inst1
& 0xff87) == 0x4687) /* mov pc, REG */
615 if (bits (inst1
, 3, 6) == 0x0f)
618 nextpc
= regcache_raw_get_unsigned (regcache
, bits (inst1
, 3, 6));
620 nextpc
= MAKE_THUMB_ADDR (nextpc
);
622 else if ((inst1
& 0xf500) == 0xb100)
625 int imm
= (bit (inst1
, 9) << 6) + (bits (inst1
, 3, 7) << 1);
626 ULONGEST reg
= regcache_raw_get_unsigned (regcache
, bits (inst1
, 0, 2));
628 if (bit (inst1
, 11) && reg
!= 0)
629 nextpc
= pc_val
+ imm
;
630 else if (!bit (inst1
, 11) && reg
== 0)
631 nextpc
= pc_val
+ imm
;
634 next_pcs
.push_back (nextpc
);
639 /* Get the raw next possible addresses. PC in next_pcs is the current program
640 counter, which is assumed to be executing in ARM mode.
642 The values returned have the execution state of the next instruction
643 encoded in it. Use IS_THUMB_ADDR () to see whether the instruction is
644 in Thumb-State, and gdbarch_addr_bits_remove () to get the plain memory
645 address in GDB and arm_addr_bits_remove in GDBServer. */
647 static std::vector
<CORE_ADDR
>
648 arm_get_next_pcs_raw (struct arm_get_next_pcs
*self
)
650 int byte_order
= self
->byte_order
;
651 int byte_order_for_code
= self
->byte_order_for_code
;
652 unsigned long pc_val
;
653 unsigned long this_instr
= 0;
654 unsigned long status
;
656 struct regcache
*regcache
= self
->regcache
;
657 CORE_ADDR pc
= regcache_read_pc (self
->regcache
);
658 std::vector
<CORE_ADDR
> next_pcs
;
660 pc_val
= (unsigned long) pc
;
661 this_instr
= self
->ops
->read_mem_uint (pc
, 4, byte_order_for_code
);
663 status
= regcache_raw_get_unsigned (regcache
, ARM_PS_REGNUM
);
664 nextpc
= (CORE_ADDR
) (pc_val
+ 4); /* Default case */
666 if (bits (this_instr
, 28, 31) == INST_NV
)
667 switch (bits (this_instr
, 24, 27))
672 /* Branch with Link and change to Thumb. */
673 nextpc
= BranchDest (pc
, this_instr
);
674 nextpc
|= bit (this_instr
, 24) << 1;
675 nextpc
= MAKE_THUMB_ADDR (nextpc
);
681 /* Coprocessor register transfer. */
682 if (bits (this_instr
, 12, 15) == 15)
683 error (_("Invalid update to pc in instruction"));
686 else if (condition_true (bits (this_instr
, 28, 31), status
))
688 switch (bits (this_instr
, 24, 27))
691 case 0x1: /* data processing */
695 unsigned long operand1
, operand2
, result
= 0;
699 if (bits (this_instr
, 12, 15) != 15)
702 if (bits (this_instr
, 22, 25) == 0
703 && bits (this_instr
, 4, 7) == 9) /* multiply */
704 error (_("Invalid update to pc in instruction"));
706 /* BX <reg>, BLX <reg> */
707 if (bits (this_instr
, 4, 27) == 0x12fff1
708 || bits (this_instr
, 4, 27) == 0x12fff3)
710 rn
= bits (this_instr
, 0, 3);
711 nextpc
= ((rn
== ARM_PC_REGNUM
)
713 : regcache_raw_get_unsigned (regcache
, rn
));
715 next_pcs
.push_back (nextpc
);
719 /* Multiply into PC. */
720 c
= (status
& FLAG_C
) ? 1 : 0;
721 rn
= bits (this_instr
, 16, 19);
722 operand1
= ((rn
== ARM_PC_REGNUM
)
724 : regcache_raw_get_unsigned (regcache
, rn
));
726 if (bit (this_instr
, 25))
728 unsigned long immval
= bits (this_instr
, 0, 7);
729 unsigned long rotate
= 2 * bits (this_instr
, 8, 11);
730 operand2
= ((immval
>> rotate
) | (immval
<< (32 - rotate
)))
733 else /* operand 2 is a shifted register. */
734 operand2
= shifted_reg_val (regcache
, this_instr
, c
,
737 switch (bits (this_instr
, 21, 24))
740 result
= operand1
& operand2
;
744 result
= operand1
^ operand2
;
748 result
= operand1
- operand2
;
752 result
= operand2
- operand1
;
756 result
= operand1
+ operand2
;
760 result
= operand1
+ operand2
+ c
;
764 result
= operand1
- operand2
+ c
;
768 result
= operand2
- operand1
+ c
;
774 case 0xb: /* tst, teq, cmp, cmn */
775 result
= (unsigned long) nextpc
;
779 result
= operand1
| operand2
;
783 /* Always step into a function. */
788 result
= operand1
& ~operand2
;
795 nextpc
= self
->ops
->addr_bits_remove (self
, result
);
800 case 0x5: /* data transfer */
803 if (bits (this_instr
, 25, 27) == 0x3 && bit (this_instr
, 4) == 1)
805 /* Media instructions and architecturally undefined
810 if (bit (this_instr
, 20))
813 if (bits (this_instr
, 12, 15) == 15)
819 if (bit (this_instr
, 22))
820 error (_("Invalid update to pc in instruction"));
822 /* byte write to PC */
823 rn
= bits (this_instr
, 16, 19);
824 base
= ((rn
== ARM_PC_REGNUM
)
826 : regcache_raw_get_unsigned (regcache
, rn
));
828 if (bit (this_instr
, 24))
831 int c
= (status
& FLAG_C
) ? 1 : 0;
832 unsigned long offset
=
833 (bit (this_instr
, 25)
834 ? shifted_reg_val (regcache
, this_instr
, c
,
836 : bits (this_instr
, 0, 11));
838 if (bit (this_instr
, 23))
844 = (CORE_ADDR
) self
->ops
->read_mem_uint ((CORE_ADDR
) base
,
851 case 0x9: /* block transfer */
852 if (bit (this_instr
, 20))
855 if (bit (this_instr
, 15))
859 CORE_ADDR rn_val_offset
= 0;
861 = regcache_raw_get_unsigned (regcache
,
862 bits (this_instr
, 16, 19));
864 if (bit (this_instr
, 23))
867 unsigned long reglist
= bits (this_instr
, 0, 14);
868 offset
= count_one_bits_l (reglist
) * 4;
869 if (bit (this_instr
, 24)) /* pre */
872 else if (bit (this_instr
, 24))
875 rn_val_offset
= rn_val
+ offset
;
876 nextpc
= (CORE_ADDR
) self
->ops
->read_mem_uint (rn_val_offset
,
882 case 0xb: /* branch & link */
883 case 0xa: /* branch */
885 nextpc
= BranchDest (pc
, this_instr
);
891 case 0xe: /* coproc ops */
895 nextpc
= self
->ops
->syscall_next_pc (self
);
900 error (_("Bad bit-field extraction"));
905 next_pcs
.push_back (nextpc
);
910 /* See arm-get-next-pcs.h. */
912 std::vector
<CORE_ADDR
>
913 arm_get_next_pcs (struct arm_get_next_pcs
*self
)
915 std::vector
<CORE_ADDR
> next_pcs
;
917 if (self
->ops
->is_thumb (self
))
919 next_pcs
= thumb_deal_with_atomic_sequence_raw (self
);
920 if (next_pcs
.empty ())
921 next_pcs
= thumb_get_next_pcs_raw (self
);
925 next_pcs
= arm_deal_with_atomic_sequence_raw (self
);
926 if (next_pcs
.empty ())
927 next_pcs
= arm_get_next_pcs_raw (self
);
930 if (self
->ops
->fixup
!= NULL
)
932 for (CORE_ADDR
&pc_ref
: next_pcs
)
933 pc_ref
= self
->ops
->fixup (self
, pc_ref
);