1 /* Common code for ARM software single stepping support.
3 Copyright (C) 1988-2019 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 "common-defs.h"
22 #include "common-regcache.h"
24 #include "arm-get-next-pcs.h"
26 /* See arm-get-next-pcs.h. */
29 arm_get_next_pcs_ctor (struct arm_get_next_pcs
*self
,
30 struct arm_get_next_pcs_ops
*ops
,
32 int byte_order_for_code
,
33 int has_thumb2_breakpoint
,
34 struct regcache
*regcache
)
37 self
->byte_order
= byte_order
;
38 self
->byte_order_for_code
= byte_order_for_code
;
39 self
->has_thumb2_breakpoint
= has_thumb2_breakpoint
;
40 self
->regcache
= regcache
;
43 /* Checks for an atomic sequence of instructions beginning with a LDREX{,B,H,D}
44 instruction and ending with a STREX{,B,H,D} instruction. If such a sequence
45 is found, attempt to step through it. The end of the sequence address is
46 added to the next_pcs list. */
48 static std::vector
<CORE_ADDR
>
49 thumb_deal_with_atomic_sequence_raw (struct arm_get_next_pcs
*self
)
51 int byte_order_for_code
= self
->byte_order_for_code
;
52 CORE_ADDR breaks
[2] = {CORE_ADDR_MAX
, CORE_ADDR_MAX
};
53 CORE_ADDR pc
= regcache_read_pc (self
->regcache
);
55 unsigned short insn1
, insn2
;
58 int last_breakpoint
= 0; /* Defaults to 0 (no breakpoints placed). */
59 const int atomic_sequence_length
= 16; /* Instruction sequence length. */
60 ULONGEST status
, itstate
;
62 /* We currently do not support atomic sequences within an IT block. */
63 status
= regcache_raw_get_unsigned (self
->regcache
, ARM_PS_REGNUM
);
64 itstate
= ((status
>> 8) & 0xfc) | ((status
>> 25) & 0x3);
68 /* Assume all atomic sequences start with a ldrex{,b,h,d} instruction. */
69 insn1
= self
->ops
->read_mem_uint (loc
, 2, byte_order_for_code
);
72 if (thumb_insn_size (insn1
) != 4)
75 insn2
= self
->ops
->read_mem_uint (loc
, 2, byte_order_for_code
);
78 if (!((insn1
& 0xfff0) == 0xe850
79 || ((insn1
& 0xfff0) == 0xe8d0 && (insn2
& 0x00c0) == 0x0040)))
82 /* Assume that no atomic sequence is longer than "atomic_sequence_length"
84 for (insn_count
= 0; insn_count
< atomic_sequence_length
; ++insn_count
)
86 insn1
= self
->ops
->read_mem_uint (loc
, 2,byte_order_for_code
);
89 if (thumb_insn_size (insn1
) != 4)
91 /* Assume that there is at most one conditional branch in the
92 atomic sequence. If a conditional branch is found, put a
93 breakpoint in its destination address. */
94 if ((insn1
& 0xf000) == 0xd000 && bits (insn1
, 8, 11) != 0x0f)
96 if (last_breakpoint
> 0)
97 return {}; /* More than one conditional branch found,
98 fallback to the standard code. */
100 breaks
[1] = loc
+ 2 + (sbits (insn1
, 0, 7) << 1);
104 /* We do not support atomic sequences that use any *other*
105 instructions but conditional branches to change the PC.
106 Fall back to standard code to avoid losing control of
108 else if (thumb_instruction_changes_pc (insn1
))
113 insn2
= self
->ops
->read_mem_uint (loc
, 2, byte_order_for_code
);
117 /* Assume that there is at most one conditional branch in the
118 atomic sequence. If a conditional branch is found, put a
119 breakpoint in its destination address. */
120 if ((insn1
& 0xf800) == 0xf000
121 && (insn2
& 0xd000) == 0x8000
122 && (insn1
& 0x0380) != 0x0380)
124 int sign
, j1
, j2
, imm1
, imm2
;
127 sign
= sbits (insn1
, 10, 10);
128 imm1
= bits (insn1
, 0, 5);
129 imm2
= bits (insn2
, 0, 10);
130 j1
= bit (insn2
, 13);
131 j2
= bit (insn2
, 11);
133 offset
= (sign
<< 20) + (j2
<< 19) + (j1
<< 18);
134 offset
+= (imm1
<< 12) + (imm2
<< 1);
136 if (last_breakpoint
> 0)
137 return {}; /* More than one conditional branch found,
138 fallback to the standard code. */
140 breaks
[1] = loc
+ offset
;
144 /* We do not support atomic sequences that use any *other*
145 instructions but conditional branches to change the PC.
146 Fall back to standard code to avoid losing control of
148 else if (thumb2_instruction_changes_pc (insn1
, insn2
))
151 /* If we find a strex{,b,h,d}, we're done. */
152 if ((insn1
& 0xfff0) == 0xe840
153 || ((insn1
& 0xfff0) == 0xe8c0 && (insn2
& 0x00c0) == 0x0040))
158 /* If we didn't find the strex{,b,h,d}, we cannot handle the sequence. */
159 if (insn_count
== atomic_sequence_length
)
162 /* Insert a breakpoint right after the end of the atomic sequence. */
165 /* Check for duplicated breakpoints. Check also for a breakpoint
166 placed (branch instruction's destination) anywhere in sequence. */
168 && (breaks
[1] == breaks
[0]
169 || (breaks
[1] >= pc
&& breaks
[1] < loc
)))
172 std::vector
<CORE_ADDR
> next_pcs
;
174 /* Adds the breakpoints to the list to be inserted. */
175 for (index
= 0; index
<= last_breakpoint
; index
++)
176 next_pcs
.push_back (MAKE_THUMB_ADDR (breaks
[index
]));
181 /* Checks for an atomic sequence of instructions beginning with a LDREX{,B,H,D}
182 instruction and ending with a STREX{,B,H,D} instruction. If such a sequence
183 is found, attempt to step through it. The end of the sequence address is
184 added to the next_pcs list. */
186 static std::vector
<CORE_ADDR
>
187 arm_deal_with_atomic_sequence_raw (struct arm_get_next_pcs
*self
)
189 int byte_order_for_code
= self
->byte_order_for_code
;
190 CORE_ADDR breaks
[2] = {CORE_ADDR_MAX
, CORE_ADDR_MAX
};
191 CORE_ADDR pc
= regcache_read_pc (self
->regcache
);
196 int last_breakpoint
= 0; /* Defaults to 0 (no breakpoints placed). */
197 const int atomic_sequence_length
= 16; /* Instruction sequence length. */
199 /* Assume all atomic sequences start with a ldrex{,b,h,d} instruction.
200 Note that we do not currently support conditionally executed atomic
202 insn
= self
->ops
->read_mem_uint (loc
, 4, byte_order_for_code
);
205 if ((insn
& 0xff9000f0) != 0xe1900090)
208 /* Assume that no atomic sequence is longer than "atomic_sequence_length"
210 for (insn_count
= 0; insn_count
< atomic_sequence_length
; ++insn_count
)
212 insn
= self
->ops
->read_mem_uint (loc
, 4, byte_order_for_code
);
216 /* Assume that there is at most one conditional branch in the atomic
217 sequence. If a conditional branch is found, put a breakpoint in
218 its destination address. */
219 if (bits (insn
, 24, 27) == 0xa)
221 if (last_breakpoint
> 0)
222 return {}; /* More than one conditional branch found, fallback
223 to the standard single-step code. */
225 breaks
[1] = BranchDest (loc
- 4, insn
);
229 /* We do not support atomic sequences that use any *other* instructions
230 but conditional branches to change the PC. Fall back to standard
231 code to avoid losing control of execution. */
232 else if (arm_instruction_changes_pc (insn
))
235 /* If we find a strex{,b,h,d}, we're done. */
236 if ((insn
& 0xff9000f0) == 0xe1800090)
240 /* If we didn't find the strex{,b,h,d}, we cannot handle the sequence. */
241 if (insn_count
== atomic_sequence_length
)
244 /* Insert a breakpoint right after the end of the atomic sequence. */
247 /* Check for duplicated breakpoints. Check also for a breakpoint
248 placed (branch instruction's destination) anywhere in sequence. */
250 && (breaks
[1] == breaks
[0]
251 || (breaks
[1] >= pc
&& breaks
[1] < loc
)))
254 std::vector
<CORE_ADDR
> next_pcs
;
256 /* Adds the breakpoints to the list to be inserted. */
257 for (index
= 0; index
<= last_breakpoint
; index
++)
258 next_pcs
.push_back (breaks
[index
]);
263 /* Find the next possible PCs for thumb mode. */
265 static std::vector
<CORE_ADDR
>
266 thumb_get_next_pcs_raw (struct arm_get_next_pcs
*self
)
268 int byte_order
= self
->byte_order
;
269 int byte_order_for_code
= self
->byte_order_for_code
;
270 CORE_ADDR pc
= regcache_read_pc (self
->regcache
);
271 unsigned long pc_val
= ((unsigned long) pc
) + 4; /* PC after prefetch */
272 unsigned short inst1
;
273 CORE_ADDR nextpc
= pc
+ 2; /* Default is next instruction. */
274 ULONGEST status
, itstate
;
275 struct regcache
*regcache
= self
->regcache
;
276 std::vector
<CORE_ADDR
> next_pcs
;
278 nextpc
= MAKE_THUMB_ADDR (nextpc
);
279 pc_val
= MAKE_THUMB_ADDR (pc_val
);
281 inst1
= self
->ops
->read_mem_uint (pc
, 2, byte_order_for_code
);
283 /* Thumb-2 conditional execution support. There are eight bits in
284 the CPSR which describe conditional execution state. Once
285 reconstructed (they're in a funny order), the low five bits
286 describe the low bit of the condition for each instruction and
287 how many instructions remain. The high three bits describe the
288 base condition. One of the low four bits will be set if an IT
289 block is active. These bits read as zero on earlier
291 status
= regcache_raw_get_unsigned (regcache
, ARM_PS_REGNUM
);
292 itstate
= ((status
>> 8) & 0xfc) | ((status
>> 25) & 0x3);
294 /* If-Then handling. On GNU/Linux, where this routine is used, we
295 use an undefined instruction as a breakpoint. Unlike BKPT, IT
296 can disable execution of the undefined instruction. So we might
297 miss the breakpoint if we set it on a skipped conditional
298 instruction. Because conditional instructions can change the
299 flags, affecting the execution of further instructions, we may
300 need to set two breakpoints. */
302 if (self
->has_thumb2_breakpoint
)
304 if ((inst1
& 0xff00) == 0xbf00 && (inst1
& 0x000f) != 0)
306 /* An IT instruction. Because this instruction does not
307 modify the flags, we can accurately predict the next
308 executed instruction. */
309 itstate
= inst1
& 0x00ff;
310 pc
+= thumb_insn_size (inst1
);
312 while (itstate
!= 0 && ! condition_true (itstate
>> 4, status
))
314 inst1
= self
->ops
->read_mem_uint (pc
, 2,byte_order_for_code
);
315 pc
+= thumb_insn_size (inst1
);
316 itstate
= thumb_advance_itstate (itstate
);
319 next_pcs
.push_back (MAKE_THUMB_ADDR (pc
));
322 else if (itstate
!= 0)
324 /* We are in a conditional block. Check the condition. */
325 if (! condition_true (itstate
>> 4, status
))
327 /* Advance to the next executed instruction. */
328 pc
+= thumb_insn_size (inst1
);
329 itstate
= thumb_advance_itstate (itstate
);
331 while (itstate
!= 0 && ! condition_true (itstate
>> 4, status
))
333 inst1
= self
->ops
->read_mem_uint (pc
, 2, byte_order_for_code
);
335 pc
+= thumb_insn_size (inst1
);
336 itstate
= thumb_advance_itstate (itstate
);
339 next_pcs
.push_back (MAKE_THUMB_ADDR (pc
));
342 else if ((itstate
& 0x0f) == 0x08)
344 /* This is the last instruction of the conditional
345 block, and it is executed. We can handle it normally
346 because the following instruction is not conditional,
347 and we must handle it normally because it is
348 permitted to branch. Fall through. */
354 /* There are conditional instructions after this one.
355 If this instruction modifies the flags, then we can
356 not predict what the next executed instruction will
357 be. Fortunately, this instruction is architecturally
358 forbidden to branch; we know it will fall through.
359 Start by skipping past it. */
360 pc
+= thumb_insn_size (inst1
);
361 itstate
= thumb_advance_itstate (itstate
);
363 /* Set a breakpoint on the following instruction. */
364 gdb_assert ((itstate
& 0x0f) != 0);
365 next_pcs
.push_back (MAKE_THUMB_ADDR (pc
));
367 cond_negated
= (itstate
>> 4) & 1;
369 /* Skip all following instructions with the same
370 condition. If there is a later instruction in the IT
371 block with the opposite condition, set the other
372 breakpoint there. If not, then set a breakpoint on
373 the instruction after the IT block. */
376 inst1
= self
->ops
->read_mem_uint (pc
, 2, byte_order_for_code
);
377 pc
+= thumb_insn_size (inst1
);
378 itstate
= thumb_advance_itstate (itstate
);
380 while (itstate
!= 0 && ((itstate
>> 4) & 1) == cond_negated
);
382 next_pcs
.push_back (MAKE_THUMB_ADDR (pc
));
388 else if (itstate
& 0x0f)
390 /* We are in a conditional block. Check the condition. */
391 int cond
= itstate
>> 4;
393 if (! condition_true (cond
, status
))
395 /* Advance to the next instruction. All the 32-bit
396 instructions share a common prefix. */
397 next_pcs
.push_back (MAKE_THUMB_ADDR (pc
+ thumb_insn_size (inst1
)));
402 /* Otherwise, handle the instruction normally. */
405 if ((inst1
& 0xff00) == 0xbd00) /* pop {rlist, pc} */
409 /* Fetch the saved PC from the stack. It's stored above
410 all of the other registers. */
411 unsigned long offset
= bitcount (bits (inst1
, 0, 7)) * INT_REGISTER_SIZE
;
412 sp
= regcache_raw_get_unsigned (regcache
, ARM_SP_REGNUM
);
413 nextpc
= self
->ops
->read_mem_uint (sp
+ offset
, 4, byte_order
);
415 else if ((inst1
& 0xf000) == 0xd000) /* conditional branch */
417 unsigned long cond
= bits (inst1
, 8, 11);
418 if (cond
== 0x0f) /* 0x0f = SWI */
420 nextpc
= self
->ops
->syscall_next_pc (self
);
422 else if (cond
!= 0x0f && condition_true (cond
, status
))
423 nextpc
= pc_val
+ (sbits (inst1
, 0, 7) << 1);
425 else if ((inst1
& 0xf800) == 0xe000) /* unconditional branch */
427 nextpc
= pc_val
+ (sbits (inst1
, 0, 10) << 1);
429 else if (thumb_insn_size (inst1
) == 4) /* 32-bit instruction */
431 unsigned short inst2
;
432 inst2
= self
->ops
->read_mem_uint (pc
+ 2, 2, byte_order_for_code
);
434 /* Default to the next instruction. */
436 nextpc
= MAKE_THUMB_ADDR (nextpc
);
438 if ((inst1
& 0xf800) == 0xf000 && (inst2
& 0x8000) == 0x8000)
440 /* Branches and miscellaneous control instructions. */
442 if ((inst2
& 0x1000) != 0 || (inst2
& 0xd001) == 0xc000)
445 int j1
, j2
, imm1
, imm2
;
447 imm1
= sbits (inst1
, 0, 10);
448 imm2
= bits (inst2
, 0, 10);
449 j1
= bit (inst2
, 13);
450 j2
= bit (inst2
, 11);
452 unsigned long offset
= ((imm1
<< 12) + (imm2
<< 1));
453 offset
^= ((!j2
) << 22) | ((!j1
) << 23);
455 nextpc
= pc_val
+ offset
;
456 /* For BLX make sure to clear the low bits. */
457 if (bit (inst2
, 12) == 0)
458 nextpc
= nextpc
& 0xfffffffc;
460 else if (inst1
== 0xf3de && (inst2
& 0xff00) == 0x3f00)
462 /* SUBS PC, LR, #imm8. */
463 nextpc
= regcache_raw_get_unsigned (regcache
, ARM_LR_REGNUM
);
464 nextpc
-= inst2
& 0x00ff;
466 else if ((inst2
& 0xd000) == 0x8000 && (inst1
& 0x0380) != 0x0380)
468 /* Conditional branch. */
469 if (condition_true (bits (inst1
, 6, 9), status
))
471 int sign
, j1
, j2
, imm1
, imm2
;
473 sign
= sbits (inst1
, 10, 10);
474 imm1
= bits (inst1
, 0, 5);
475 imm2
= bits (inst2
, 0, 10);
476 j1
= bit (inst2
, 13);
477 j2
= bit (inst2
, 11);
480 = (sign
<< 20) + (j2
<< 19) + (j1
<< 18);
481 offset
+= (imm1
<< 12) + (imm2
<< 1);
483 nextpc
= pc_val
+ offset
;
487 else if ((inst1
& 0xfe50) == 0xe810)
489 /* Load multiple or RFE. */
490 int rn
, offset
, load_pc
= 1;
492 rn
= bits (inst1
, 0, 3);
493 if (bit (inst1
, 7) && !bit (inst1
, 8))
496 if (!bit (inst2
, 15))
498 offset
= bitcount (inst2
) * 4 - 4;
500 else if (!bit (inst1
, 7) && bit (inst1
, 8))
503 if (!bit (inst2
, 15))
507 else if (bit (inst1
, 7) && bit (inst1
, 8))
512 else if (!bit (inst1
, 7) && !bit (inst1
, 8))
522 CORE_ADDR addr
= regcache_raw_get_unsigned (regcache
, rn
);
523 nextpc
= self
->ops
->read_mem_uint (addr
+ offset
, 4, byte_order
);
526 else if ((inst1
& 0xffef) == 0xea4f && (inst2
& 0xfff0) == 0x0f00)
528 /* MOV PC or MOVS PC. */
529 nextpc
= regcache_raw_get_unsigned (regcache
, bits (inst2
, 0, 3));
530 nextpc
= MAKE_THUMB_ADDR (nextpc
);
532 else if ((inst1
& 0xff70) == 0xf850 && (inst2
& 0xf000) == 0xf000)
538 rn
= bits (inst1
, 0, 3);
539 base
= regcache_raw_get_unsigned (regcache
, rn
);
540 if (rn
== ARM_PC_REGNUM
)
542 base
= (base
+ 4) & ~(CORE_ADDR
) 0x3;
544 base
+= bits (inst2
, 0, 11);
546 base
-= bits (inst2
, 0, 11);
548 else if (bit (inst1
, 7))
549 base
+= bits (inst2
, 0, 11);
550 else if (bit (inst2
, 11))
555 base
+= bits (inst2
, 0, 7);
557 base
-= bits (inst2
, 0, 7);
560 else if ((inst2
& 0x0fc0) == 0x0000)
562 int shift
= bits (inst2
, 4, 5), rm
= bits (inst2
, 0, 3);
563 base
+= regcache_raw_get_unsigned (regcache
, rm
) << shift
;
571 = self
->ops
->read_mem_uint (base
, 4, byte_order
);
573 else if ((inst1
& 0xfff0) == 0xe8d0 && (inst2
& 0xfff0) == 0xf000)
576 CORE_ADDR tbl_reg
, table
, offset
, length
;
578 tbl_reg
= bits (inst1
, 0, 3);
580 table
= pc
+ 4; /* Regcache copy of PC isn't right yet. */
582 table
= regcache_raw_get_unsigned (regcache
, tbl_reg
);
584 offset
= regcache_raw_get_unsigned (regcache
, bits (inst2
, 0, 3));
585 length
= 2 * self
->ops
->read_mem_uint (table
+ offset
, 1, byte_order
);
586 nextpc
= pc_val
+ length
;
588 else if ((inst1
& 0xfff0) == 0xe8d0 && (inst2
& 0xfff0) == 0xf010)
591 CORE_ADDR tbl_reg
, table
, offset
, length
;
593 tbl_reg
= bits (inst1
, 0, 3);
595 table
= pc
+ 4; /* Regcache copy of PC isn't right yet. */
597 table
= regcache_raw_get_unsigned (regcache
, tbl_reg
);
599 offset
= 2 * regcache_raw_get_unsigned (regcache
, bits (inst2
, 0, 3));
600 length
= 2 * self
->ops
->read_mem_uint (table
+ offset
, 2, byte_order
);
601 nextpc
= pc_val
+ length
;
604 else if ((inst1
& 0xff00) == 0x4700) /* bx REG, blx REG */
606 if (bits (inst1
, 3, 6) == 0x0f)
607 nextpc
= UNMAKE_THUMB_ADDR (pc_val
);
609 nextpc
= regcache_raw_get_unsigned (regcache
, bits (inst1
, 3, 6));
611 else if ((inst1
& 0xff87) == 0x4687) /* mov pc, REG */
613 if (bits (inst1
, 3, 6) == 0x0f)
616 nextpc
= regcache_raw_get_unsigned (regcache
, bits (inst1
, 3, 6));
618 nextpc
= MAKE_THUMB_ADDR (nextpc
);
620 else if ((inst1
& 0xf500) == 0xb100)
623 int imm
= (bit (inst1
, 9) << 6) + (bits (inst1
, 3, 7) << 1);
624 ULONGEST reg
= regcache_raw_get_unsigned (regcache
, bits (inst1
, 0, 2));
626 if (bit (inst1
, 11) && reg
!= 0)
627 nextpc
= pc_val
+ imm
;
628 else if (!bit (inst1
, 11) && reg
== 0)
629 nextpc
= pc_val
+ imm
;
632 next_pcs
.push_back (nextpc
);
637 /* Get the raw next possible addresses. PC in next_pcs is the current program
638 counter, which is assumed to be executing in ARM mode.
640 The values returned have the execution state of the next instruction
641 encoded in it. Use IS_THUMB_ADDR () to see whether the instruction is
642 in Thumb-State, and gdbarch_addr_bits_remove () to get the plain memory
643 address in GDB and arm_addr_bits_remove in GDBServer. */
645 static std::vector
<CORE_ADDR
>
646 arm_get_next_pcs_raw (struct arm_get_next_pcs
*self
)
648 int byte_order
= self
->byte_order
;
649 int byte_order_for_code
= self
->byte_order_for_code
;
650 unsigned long pc_val
;
651 unsigned long this_instr
= 0;
652 unsigned long status
;
654 struct regcache
*regcache
= self
->regcache
;
655 CORE_ADDR pc
= regcache_read_pc (self
->regcache
);
656 std::vector
<CORE_ADDR
> next_pcs
;
658 pc_val
= (unsigned long) pc
;
659 this_instr
= self
->ops
->read_mem_uint (pc
, 4, byte_order_for_code
);
661 status
= regcache_raw_get_unsigned (regcache
, ARM_PS_REGNUM
);
662 nextpc
= (CORE_ADDR
) (pc_val
+ 4); /* Default case */
664 if (bits (this_instr
, 28, 31) == INST_NV
)
665 switch (bits (this_instr
, 24, 27))
670 /* Branch with Link and change to Thumb. */
671 nextpc
= BranchDest (pc
, this_instr
);
672 nextpc
|= bit (this_instr
, 24) << 1;
673 nextpc
= MAKE_THUMB_ADDR (nextpc
);
679 /* Coprocessor register transfer. */
680 if (bits (this_instr
, 12, 15) == 15)
681 error (_("Invalid update to pc in instruction"));
684 else if (condition_true (bits (this_instr
, 28, 31), status
))
686 switch (bits (this_instr
, 24, 27))
689 case 0x1: /* data processing */
693 unsigned long operand1
, operand2
, result
= 0;
697 if (bits (this_instr
, 12, 15) != 15)
700 if (bits (this_instr
, 22, 25) == 0
701 && bits (this_instr
, 4, 7) == 9) /* multiply */
702 error (_("Invalid update to pc in instruction"));
704 /* BX <reg>, BLX <reg> */
705 if (bits (this_instr
, 4, 27) == 0x12fff1
706 || bits (this_instr
, 4, 27) == 0x12fff3)
708 rn
= bits (this_instr
, 0, 3);
709 nextpc
= ((rn
== ARM_PC_REGNUM
)
711 : regcache_raw_get_unsigned (regcache
, rn
));
713 next_pcs
.push_back (nextpc
);
717 /* Multiply into PC. */
718 c
= (status
& FLAG_C
) ? 1 : 0;
719 rn
= bits (this_instr
, 16, 19);
720 operand1
= ((rn
== ARM_PC_REGNUM
)
722 : regcache_raw_get_unsigned (regcache
, rn
));
724 if (bit (this_instr
, 25))
726 unsigned long immval
= bits (this_instr
, 0, 7);
727 unsigned long rotate
= 2 * bits (this_instr
, 8, 11);
728 operand2
= ((immval
>> rotate
) | (immval
<< (32 - rotate
)))
731 else /* operand 2 is a shifted register. */
732 operand2
= shifted_reg_val (regcache
, this_instr
, c
,
735 switch (bits (this_instr
, 21, 24))
738 result
= operand1
& operand2
;
742 result
= operand1
^ operand2
;
746 result
= operand1
- operand2
;
750 result
= operand2
- operand1
;
754 result
= operand1
+ operand2
;
758 result
= operand1
+ operand2
+ c
;
762 result
= operand1
- operand2
+ c
;
766 result
= operand2
- operand1
+ c
;
772 case 0xb: /* tst, teq, cmp, cmn */
773 result
= (unsigned long) nextpc
;
777 result
= operand1
| operand2
;
781 /* Always step into a function. */
786 result
= operand1
& ~operand2
;
793 nextpc
= self
->ops
->addr_bits_remove (self
, result
);
798 case 0x5: /* data transfer */
801 if (bits (this_instr
, 25, 27) == 0x3 && bit (this_instr
, 4) == 1)
803 /* Media instructions and architecturally undefined
808 if (bit (this_instr
, 20))
811 if (bits (this_instr
, 12, 15) == 15)
817 if (bit (this_instr
, 22))
818 error (_("Invalid update to pc in instruction"));
820 /* byte write to PC */
821 rn
= bits (this_instr
, 16, 19);
822 base
= ((rn
== ARM_PC_REGNUM
)
824 : regcache_raw_get_unsigned (regcache
, rn
));
826 if (bit (this_instr
, 24))
829 int c
= (status
& FLAG_C
) ? 1 : 0;
830 unsigned long offset
=
831 (bit (this_instr
, 25)
832 ? shifted_reg_val (regcache
, this_instr
, c
,
834 : bits (this_instr
, 0, 11));
836 if (bit (this_instr
, 23))
842 = (CORE_ADDR
) self
->ops
->read_mem_uint ((CORE_ADDR
) base
,
849 case 0x9: /* block transfer */
850 if (bit (this_instr
, 20))
853 if (bit (this_instr
, 15))
857 CORE_ADDR rn_val_offset
= 0;
859 = regcache_raw_get_unsigned (regcache
,
860 bits (this_instr
, 16, 19));
862 if (bit (this_instr
, 23))
865 unsigned long reglist
= bits (this_instr
, 0, 14);
866 offset
= bitcount (reglist
) * 4;
867 if (bit (this_instr
, 24)) /* pre */
870 else if (bit (this_instr
, 24))
873 rn_val_offset
= rn_val
+ offset
;
874 nextpc
= (CORE_ADDR
) self
->ops
->read_mem_uint (rn_val_offset
,
880 case 0xb: /* branch & link */
881 case 0xa: /* branch */
883 nextpc
= BranchDest (pc
, this_instr
);
889 case 0xe: /* coproc ops */
893 nextpc
= self
->ops
->syscall_next_pc (self
);
898 error (_("Bad bit-field extraction"));
903 next_pcs
.push_back (nextpc
);
908 /* See arm-get-next-pcs.h. */
910 std::vector
<CORE_ADDR
>
911 arm_get_next_pcs (struct arm_get_next_pcs
*self
)
913 std::vector
<CORE_ADDR
> next_pcs
;
915 if (self
->ops
->is_thumb (self
))
917 next_pcs
= thumb_deal_with_atomic_sequence_raw (self
);
918 if (next_pcs
.empty ())
919 next_pcs
= thumb_get_next_pcs_raw (self
);
923 next_pcs
= arm_deal_with_atomic_sequence_raw (self
);
924 if (next_pcs
.empty ())
925 next_pcs
= arm_get_next_pcs_raw (self
);
928 if (self
->ops
->fixup
!= NULL
)
930 for (CORE_ADDR
&pc_ref
: next_pcs
)
931 pc_ref
= self
->ops
->fixup (self
, pc_ref
);
This page took 0.048801 seconds and 4 git commands to generate.