LLDB mainline
EmulateInstructionARM.cpp
Go to the documentation of this file.
1//===-- EmulateInstructionARM.cpp -----------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <cstdlib>
10#include <optional>
11
13#include "EmulationStateARM.h"
14#include "lldb/Core/Address.h"
16#include "lldb/Host/PosixApi.h"
21#include "lldb/Utility/Stream.h"
22
26
27#include "llvm/ADT/STLExtras.h"
28#include "llvm/Support/MathExtras.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
34
35// Convenient macro definitions.
36#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
37#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
38
39#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
40
41//
42// ITSession implementation
43//
44
45static std::optional<RegisterInfo> GetARMDWARFRegisterInfo(unsigned reg_num) {
46 RegisterInfo reg_info;
47 ::memset(&reg_info, 0, sizeof(RegisterInfo));
48 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
49
50 if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) {
51 reg_info.byte_size = 16;
53 reg_info.encoding = eEncodingVector;
54 }
55
56 if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) {
57 reg_info.byte_size = 8;
58 reg_info.format = eFormatFloat;
59 reg_info.encoding = eEncodingIEEE754;
60 } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) {
61 reg_info.byte_size = 4;
62 reg_info.format = eFormatFloat;
63 reg_info.encoding = eEncodingIEEE754;
64 } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) {
65 reg_info.byte_size = 12;
66 reg_info.format = eFormatFloat;
67 reg_info.encoding = eEncodingIEEE754;
68 } else {
69 reg_info.byte_size = 4;
70 reg_info.format = eFormatHex;
71 reg_info.encoding = eEncodingUint;
72 }
73
74 reg_info.kinds[eRegisterKindDWARF] = reg_num;
75
76 switch (reg_num) {
77 case dwarf_r0:
78 reg_info.name = "r0";
79 break;
80 case dwarf_r1:
81 reg_info.name = "r1";
82 break;
83 case dwarf_r2:
84 reg_info.name = "r2";
85 break;
86 case dwarf_r3:
87 reg_info.name = "r3";
88 break;
89 case dwarf_r4:
90 reg_info.name = "r4";
91 break;
92 case dwarf_r5:
93 reg_info.name = "r5";
94 break;
95 case dwarf_r6:
96 reg_info.name = "r6";
97 break;
98 case dwarf_r7:
99 reg_info.name = "r7";
101 break;
102 case dwarf_r8:
103 reg_info.name = "r8";
104 break;
105 case dwarf_r9:
106 reg_info.name = "r9";
107 break;
108 case dwarf_r10:
109 reg_info.name = "r10";
110 break;
111 case dwarf_r11:
112 reg_info.name = "r11";
113 break;
114 case dwarf_r12:
115 reg_info.name = "r12";
116 break;
117 case dwarf_sp:
118 reg_info.name = "sp";
119 reg_info.alt_name = "r13";
121 break;
122 case dwarf_lr:
123 reg_info.name = "lr";
124 reg_info.alt_name = "r14";
126 break;
127 case dwarf_pc:
128 reg_info.name = "pc";
129 reg_info.alt_name = "r15";
131 break;
132 case dwarf_cpsr:
133 reg_info.name = "cpsr";
135 break;
136
137 case dwarf_s0:
138 reg_info.name = "s0";
139 break;
140 case dwarf_s1:
141 reg_info.name = "s1";
142 break;
143 case dwarf_s2:
144 reg_info.name = "s2";
145 break;
146 case dwarf_s3:
147 reg_info.name = "s3";
148 break;
149 case dwarf_s4:
150 reg_info.name = "s4";
151 break;
152 case dwarf_s5:
153 reg_info.name = "s5";
154 break;
155 case dwarf_s6:
156 reg_info.name = "s6";
157 break;
158 case dwarf_s7:
159 reg_info.name = "s7";
160 break;
161 case dwarf_s8:
162 reg_info.name = "s8";
163 break;
164 case dwarf_s9:
165 reg_info.name = "s9";
166 break;
167 case dwarf_s10:
168 reg_info.name = "s10";
169 break;
170 case dwarf_s11:
171 reg_info.name = "s11";
172 break;
173 case dwarf_s12:
174 reg_info.name = "s12";
175 break;
176 case dwarf_s13:
177 reg_info.name = "s13";
178 break;
179 case dwarf_s14:
180 reg_info.name = "s14";
181 break;
182 case dwarf_s15:
183 reg_info.name = "s15";
184 break;
185 case dwarf_s16:
186 reg_info.name = "s16";
187 break;
188 case dwarf_s17:
189 reg_info.name = "s17";
190 break;
191 case dwarf_s18:
192 reg_info.name = "s18";
193 break;
194 case dwarf_s19:
195 reg_info.name = "s19";
196 break;
197 case dwarf_s20:
198 reg_info.name = "s20";
199 break;
200 case dwarf_s21:
201 reg_info.name = "s21";
202 break;
203 case dwarf_s22:
204 reg_info.name = "s22";
205 break;
206 case dwarf_s23:
207 reg_info.name = "s23";
208 break;
209 case dwarf_s24:
210 reg_info.name = "s24";
211 break;
212 case dwarf_s25:
213 reg_info.name = "s25";
214 break;
215 case dwarf_s26:
216 reg_info.name = "s26";
217 break;
218 case dwarf_s27:
219 reg_info.name = "s27";
220 break;
221 case dwarf_s28:
222 reg_info.name = "s28";
223 break;
224 case dwarf_s29:
225 reg_info.name = "s29";
226 break;
227 case dwarf_s30:
228 reg_info.name = "s30";
229 break;
230 case dwarf_s31:
231 reg_info.name = "s31";
232 break;
233
234 // FPA Registers 0-7
235 case dwarf_f0:
236 reg_info.name = "f0";
237 break;
238 case dwarf_f1:
239 reg_info.name = "f1";
240 break;
241 case dwarf_f2:
242 reg_info.name = "f2";
243 break;
244 case dwarf_f3:
245 reg_info.name = "f3";
246 break;
247 case dwarf_f4:
248 reg_info.name = "f4";
249 break;
250 case dwarf_f5:
251 reg_info.name = "f5";
252 break;
253 case dwarf_f6:
254 reg_info.name = "f6";
255 break;
256 case dwarf_f7:
257 reg_info.name = "f7";
258 break;
259
260 // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator
261 // register 0 - 7 (they do overlap with wCGR0 - wCGR7)
262 case dwarf_wCGR0:
263 reg_info.name = "wCGR0/ACC0";
264 break;
265 case dwarf_wCGR1:
266 reg_info.name = "wCGR1/ACC1";
267 break;
268 case dwarf_wCGR2:
269 reg_info.name = "wCGR2/ACC2";
270 break;
271 case dwarf_wCGR3:
272 reg_info.name = "wCGR3/ACC3";
273 break;
274 case dwarf_wCGR4:
275 reg_info.name = "wCGR4/ACC4";
276 break;
277 case dwarf_wCGR5:
278 reg_info.name = "wCGR5/ACC5";
279 break;
280 case dwarf_wCGR6:
281 reg_info.name = "wCGR6/ACC6";
282 break;
283 case dwarf_wCGR7:
284 reg_info.name = "wCGR7/ACC7";
285 break;
286
287 // Intel wireless MMX data registers 0 - 15
288 case dwarf_wR0:
289 reg_info.name = "wR0";
290 break;
291 case dwarf_wR1:
292 reg_info.name = "wR1";
293 break;
294 case dwarf_wR2:
295 reg_info.name = "wR2";
296 break;
297 case dwarf_wR3:
298 reg_info.name = "wR3";
299 break;
300 case dwarf_wR4:
301 reg_info.name = "wR4";
302 break;
303 case dwarf_wR5:
304 reg_info.name = "wR5";
305 break;
306 case dwarf_wR6:
307 reg_info.name = "wR6";
308 break;
309 case dwarf_wR7:
310 reg_info.name = "wR7";
311 break;
312 case dwarf_wR8:
313 reg_info.name = "wR8";
314 break;
315 case dwarf_wR9:
316 reg_info.name = "wR9";
317 break;
318 case dwarf_wR10:
319 reg_info.name = "wR10";
320 break;
321 case dwarf_wR11:
322 reg_info.name = "wR11";
323 break;
324 case dwarf_wR12:
325 reg_info.name = "wR12";
326 break;
327 case dwarf_wR13:
328 reg_info.name = "wR13";
329 break;
330 case dwarf_wR14:
331 reg_info.name = "wR14";
332 break;
333 case dwarf_wR15:
334 reg_info.name = "wR15";
335 break;
336
337 case dwarf_spsr:
338 reg_info.name = "spsr";
339 break;
340 case dwarf_spsr_fiq:
341 reg_info.name = "spsr_fiq";
342 break;
343 case dwarf_spsr_irq:
344 reg_info.name = "spsr_irq";
345 break;
346 case dwarf_spsr_abt:
347 reg_info.name = "spsr_abt";
348 break;
349 case dwarf_spsr_und:
350 reg_info.name = "spsr_und";
351 break;
352 case dwarf_spsr_svc:
353 reg_info.name = "spsr_svc";
354 break;
355
356 case dwarf_r8_usr:
357 reg_info.name = "r8_usr";
358 break;
359 case dwarf_r9_usr:
360 reg_info.name = "r9_usr";
361 break;
362 case dwarf_r10_usr:
363 reg_info.name = "r10_usr";
364 break;
365 case dwarf_r11_usr:
366 reg_info.name = "r11_usr";
367 break;
368 case dwarf_r12_usr:
369 reg_info.name = "r12_usr";
370 break;
371 case dwarf_r13_usr:
372 reg_info.name = "r13_usr";
373 break;
374 case dwarf_r14_usr:
375 reg_info.name = "r14_usr";
376 break;
377 case dwarf_r8_fiq:
378 reg_info.name = "r8_fiq";
379 break;
380 case dwarf_r9_fiq:
381 reg_info.name = "r9_fiq";
382 break;
383 case dwarf_r10_fiq:
384 reg_info.name = "r10_fiq";
385 break;
386 case dwarf_r11_fiq:
387 reg_info.name = "r11_fiq";
388 break;
389 case dwarf_r12_fiq:
390 reg_info.name = "r12_fiq";
391 break;
392 case dwarf_r13_fiq:
393 reg_info.name = "r13_fiq";
394 break;
395 case dwarf_r14_fiq:
396 reg_info.name = "r14_fiq";
397 break;
398 case dwarf_r13_irq:
399 reg_info.name = "r13_irq";
400 break;
401 case dwarf_r14_irq:
402 reg_info.name = "r14_irq";
403 break;
404 case dwarf_r13_abt:
405 reg_info.name = "r13_abt";
406 break;
407 case dwarf_r14_abt:
408 reg_info.name = "r14_abt";
409 break;
410 case dwarf_r13_und:
411 reg_info.name = "r13_und";
412 break;
413 case dwarf_r14_und:
414 reg_info.name = "r14_und";
415 break;
416 case dwarf_r13_svc:
417 reg_info.name = "r13_svc";
418 break;
419 case dwarf_r14_svc:
420 reg_info.name = "r14_svc";
421 break;
422
423 // Intel wireless MMX control register in co-processor 0 - 7
424 case dwarf_wC0:
425 reg_info.name = "wC0";
426 break;
427 case dwarf_wC1:
428 reg_info.name = "wC1";
429 break;
430 case dwarf_wC2:
431 reg_info.name = "wC2";
432 break;
433 case dwarf_wC3:
434 reg_info.name = "wC3";
435 break;
436 case dwarf_wC4:
437 reg_info.name = "wC4";
438 break;
439 case dwarf_wC5:
440 reg_info.name = "wC5";
441 break;
442 case dwarf_wC6:
443 reg_info.name = "wC6";
444 break;
445 case dwarf_wC7:
446 reg_info.name = "wC7";
447 break;
448
449 // VFP-v3/Neon
450 case dwarf_d0:
451 reg_info.name = "d0";
452 break;
453 case dwarf_d1:
454 reg_info.name = "d1";
455 break;
456 case dwarf_d2:
457 reg_info.name = "d2";
458 break;
459 case dwarf_d3:
460 reg_info.name = "d3";
461 break;
462 case dwarf_d4:
463 reg_info.name = "d4";
464 break;
465 case dwarf_d5:
466 reg_info.name = "d5";
467 break;
468 case dwarf_d6:
469 reg_info.name = "d6";
470 break;
471 case dwarf_d7:
472 reg_info.name = "d7";
473 break;
474 case dwarf_d8:
475 reg_info.name = "d8";
476 break;
477 case dwarf_d9:
478 reg_info.name = "d9";
479 break;
480 case dwarf_d10:
481 reg_info.name = "d10";
482 break;
483 case dwarf_d11:
484 reg_info.name = "d11";
485 break;
486 case dwarf_d12:
487 reg_info.name = "d12";
488 break;
489 case dwarf_d13:
490 reg_info.name = "d13";
491 break;
492 case dwarf_d14:
493 reg_info.name = "d14";
494 break;
495 case dwarf_d15:
496 reg_info.name = "d15";
497 break;
498 case dwarf_d16:
499 reg_info.name = "d16";
500 break;
501 case dwarf_d17:
502 reg_info.name = "d17";
503 break;
504 case dwarf_d18:
505 reg_info.name = "d18";
506 break;
507 case dwarf_d19:
508 reg_info.name = "d19";
509 break;
510 case dwarf_d20:
511 reg_info.name = "d20";
512 break;
513 case dwarf_d21:
514 reg_info.name = "d21";
515 break;
516 case dwarf_d22:
517 reg_info.name = "d22";
518 break;
519 case dwarf_d23:
520 reg_info.name = "d23";
521 break;
522 case dwarf_d24:
523 reg_info.name = "d24";
524 break;
525 case dwarf_d25:
526 reg_info.name = "d25";
527 break;
528 case dwarf_d26:
529 reg_info.name = "d26";
530 break;
531 case dwarf_d27:
532 reg_info.name = "d27";
533 break;
534 case dwarf_d28:
535 reg_info.name = "d28";
536 break;
537 case dwarf_d29:
538 reg_info.name = "d29";
539 break;
540 case dwarf_d30:
541 reg_info.name = "d30";
542 break;
543 case dwarf_d31:
544 reg_info.name = "d31";
545 break;
546
547 // NEON 128-bit vector registers (overlays the d registers)
548 case dwarf_q0:
549 reg_info.name = "q0";
550 break;
551 case dwarf_q1:
552 reg_info.name = "q1";
553 break;
554 case dwarf_q2:
555 reg_info.name = "q2";
556 break;
557 case dwarf_q3:
558 reg_info.name = "q3";
559 break;
560 case dwarf_q4:
561 reg_info.name = "q4";
562 break;
563 case dwarf_q5:
564 reg_info.name = "q5";
565 break;
566 case dwarf_q6:
567 reg_info.name = "q6";
568 break;
569 case dwarf_q7:
570 reg_info.name = "q7";
571 break;
572 case dwarf_q8:
573 reg_info.name = "q8";
574 break;
575 case dwarf_q9:
576 reg_info.name = "q9";
577 break;
578 case dwarf_q10:
579 reg_info.name = "q10";
580 break;
581 case dwarf_q11:
582 reg_info.name = "q11";
583 break;
584 case dwarf_q12:
585 reg_info.name = "q12";
586 break;
587 case dwarf_q13:
588 reg_info.name = "q13";
589 break;
590 case dwarf_q14:
591 reg_info.name = "q14";
592 break;
593 case dwarf_q15:
594 reg_info.name = "q15";
595 break;
596
597 default:
598 return {};
599 }
600 return reg_info;
601}
602
603// A8.6.50
604// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
605static uint32_t CountITSize(uint32_t ITMask) {
606 // First count the trailing zeros of the IT mask.
607 uint32_t TZ = llvm::countr_zero(ITMask);
608 if (TZ > 3) {
609 return 0;
610 }
611 return (4 - TZ);
612}
613
614// Init ITState. Note that at least one bit is always 1 in mask.
615bool ITSession::InitIT(uint32_t bits7_0) {
616 ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
617 if (ITCounter == 0)
618 return false;
619
620 // A8.6.50 IT
621 unsigned short FirstCond = Bits32(bits7_0, 7, 4);
622 if (FirstCond == 0xF) {
623 return false;
624 }
625 if (FirstCond == 0xE && ITCounter != 1) {
626 return false;
627 }
628
629 ITState = bits7_0;
630 return true;
631}
632
633// Update ITState if necessary.
635 // assert(ITCounter);
636 --ITCounter;
637 if (ITCounter == 0)
638 ITState = 0;
639 else {
640 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
641 SetBits32(ITState, 4, 0, NewITState4_0);
642 }
643}
644
645// Return true if we're inside an IT Block.
646bool ITSession::InITBlock() { return ITCounter != 0; }
647
648// Return true if we're the last instruction inside an IT Block.
649bool ITSession::LastInITBlock() { return ITCounter == 1; }
650
651// Get condition bits for the current thumb instruction.
653 if (InITBlock())
654 return Bits32(ITState, 7, 4);
655 else
656 return COND_AL;
657}
658
659// ARM constants used during decoding
660#define REG_RD 0
661#define LDM_REGLIST 1
662#define SP_REG 13
663#define LR_REG 14
664#define PC_REG 15
665#define PC_REGLIST_BIT 0x8000
666
667#define ARMv4 (1u << 0)
668#define ARMv4T (1u << 1)
669#define ARMv5T (1u << 2)
670#define ARMv5TE (1u << 3)
671#define ARMv5TEJ (1u << 4)
672#define ARMv6 (1u << 5)
673#define ARMv6K (1u << 6)
674#define ARMv6T2 (1u << 7)
675#define ARMv7 (1u << 8)
676#define ARMv7S (1u << 9)
677#define ARMv8 (1u << 10)
678#define ARMvAll (0xffffffffu)
679
680#define ARMV4T_ABOVE \
681 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \
682 ARMv7S | ARMv8)
683#define ARMV5_ABOVE \
684 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \
685 ARMv8)
686#define ARMV5TE_ABOVE \
687 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
688#define ARMV5J_ABOVE \
689 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
690#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
691#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
692#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
693
694#define No_VFP 0
695#define VFPv1 (1u << 1)
696#define VFPv2 (1u << 2)
697#define VFPv3 (1u << 3)
698#define AdvancedSIMD (1u << 4)
699
700#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
701#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
702#define VFPv2v3 (VFPv2 | VFPv3)
703
704//
705// EmulateInstructionARM implementation
706//
707
711}
712
715}
716
718 return "Emulate instructions for the ARM architecture.";
719}
720
723 InstructionType inst_type) {
725 inst_type)) {
726 if (arch.GetTriple().getArch() == llvm::Triple::arm) {
727 std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
728 new EmulateInstructionARM(arch));
729
730 if (emulate_insn_up)
731 return emulate_insn_up.release();
732 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) {
733 std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
734 new EmulateInstructionARM(arch));
735
736 if (emulate_insn_up)
737 return emulate_insn_up.release();
738 }
739 }
740
741 return nullptr;
742}
743
745 if (arch.GetTriple().getArch() == llvm::Triple::arm)
746 return true;
747 else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
748 return true;
749
750 return false;
751}
752
753// Write "bits (32) UNKNOWN" to memory address "address". Helper function for
754// many ARM instructions.
758 context.SetNoArgs();
759
760 uint32_t random_data = rand();
761 const uint32_t addr_byte_size = GetAddressByteSize();
762
763 return MemAWrite(context, address, random_data, addr_byte_size);
764}
765
766// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM
767// instructions.
771 context.SetNoArgs();
772
773 bool success;
774 uint32_t data =
776
777 if (!success)
778 return false;
779
780 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data))
781 return false;
782
783 return true;
784}
785
786std::optional<RegisterInfo>
788 uint32_t reg_num) {
789 if (reg_kind == eRegisterKindGeneric) {
790 switch (reg_num) {
792 reg_kind = eRegisterKindDWARF;
793 reg_num = dwarf_pc;
794 break;
796 reg_kind = eRegisterKindDWARF;
797 reg_num = dwarf_sp;
798 break;
800 reg_kind = eRegisterKindDWARF;
801 reg_num = dwarf_r7;
802 break;
804 reg_kind = eRegisterKindDWARF;
805 reg_num = dwarf_lr;
806 break;
808 reg_kind = eRegisterKindDWARF;
809 reg_num = dwarf_cpsr;
810 break;
811 default:
812 return {};
813 }
814 }
815
816 if (reg_kind == eRegisterKindDWARF)
817 return GetARMDWARFRegisterInfo(reg_num);
818 return {};
819}
820
822 if (m_arch.GetTriple().isAndroid())
823 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
824 bool is_apple = false;
825 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
826 is_apple = true;
827 switch (m_arch.GetTriple().getOS()) {
828 case llvm::Triple::Darwin:
829 case llvm::Triple::MacOSX:
830 case llvm::Triple::IOS:
831 case llvm::Triple::TvOS:
832 case llvm::Triple::WatchOS:
833 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
834 is_apple = true;
835 break;
836 default:
837 break;
838 }
839
840 /* On Apple iOS et al, the frame pointer register is always r7.
841 * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
842 * Windows on ARM, which is in thumb mode, uses r11 though.
843 */
844
845 uint32_t fp_regnum = 11;
846
847 if (is_apple)
848 fp_regnum = 7;
849
850 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
851 fp_regnum = 7;
852
853 return fp_regnum;
854}
855
857 bool is_apple = false;
858 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
859 is_apple = true;
860 switch (m_arch.GetTriple().getOS()) {
861 case llvm::Triple::Darwin:
862 case llvm::Triple::MacOSX:
863 case llvm::Triple::IOS:
864 is_apple = true;
865 break;
866 default:
867 break;
868 }
869
870 /* On Apple iOS et al, the frame pointer register is always r7.
871 * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
872 * Windows on ARM, which is in thumb mode, uses r11 though.
873 */
874
875 uint32_t fp_regnum = dwarf_r11;
876
877 if (is_apple)
878 fp_regnum = dwarf_r7;
879
880 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
881 fp_regnum = dwarf_r7;
882
883 return fp_regnum;
884}
885
886// Push Multiple Registers stores multiple registers to the stack, storing to
887// consecutive memory locations ending just below the address in SP, and
888// updates
889// SP to point to the start of the stored data.
890bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
891 const ARMEncoding encoding) {
892#if 0
893 // ARM pseudo code...
894 if (ConditionPassed())
895 {
896 EncodingSpecificOperations();
897 NullCheckIfThumbEE(13);
898 address = SP - 4*BitCount(registers);
899
900 for (i = 0 to 14)
901 {
902 if (registers<i> == '1')
903 {
904 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
905 MemA[address,4] = bits(32) UNKNOWN;
906 else
907 MemA[address,4] = R[i];
908 address = address + 4;
909 }
910 }
911
912 if (registers<15> == '1') // Only possible for encoding A1 or A2
913 MemA[address,4] = PCStoreValue();
914
915 SP = SP - 4*BitCount(registers);
916 }
917#endif
918
919 bool success = false;
920 if (ConditionPassed(opcode)) {
921 const uint32_t addr_byte_size = GetAddressByteSize();
922 const addr_t sp = ReadCoreReg(SP_REG, &success);
923 if (!success)
924 return false;
925 uint32_t registers = 0;
926 uint32_t Rt; // the source register
927 switch (encoding) {
928 case eEncodingT1:
929 registers = Bits32(opcode, 7, 0);
930 // The M bit represents LR.
931 if (Bit32(opcode, 8))
932 registers |= (1u << 14);
933 // if BitCount(registers) < 1 then UNPREDICTABLE;
934 if (BitCount(registers) < 1)
935 return false;
936 break;
937 case eEncodingT2:
938 // Ignore bits 15 & 13.
939 registers = Bits32(opcode, 15, 0) & ~0xa000;
940 // if BitCount(registers) < 2 then UNPREDICTABLE;
941 if (BitCount(registers) < 2)
942 return false;
943 break;
944 case eEncodingT3:
945 Rt = Bits32(opcode, 15, 12);
946 // if BadReg(t) then UNPREDICTABLE;
947 if (BadReg(Rt))
948 return false;
949 registers = (1u << Rt);
950 break;
951 case eEncodingA1:
952 registers = Bits32(opcode, 15, 0);
953 // Instead of return false, let's handle the following case as well,
954 // which amounts to pushing one reg onto the full descending stacks.
955 // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
956 break;
957 case eEncodingA2:
958 Rt = Bits32(opcode, 15, 12);
959 // if t == 13 then UNPREDICTABLE;
960 if (Rt == dwarf_sp)
961 return false;
962 registers = (1u << Rt);
963 break;
964 default:
965 return false;
966 }
967 addr_t sp_offset = addr_byte_size * BitCount(registers);
968 addr_t addr = sp - sp_offset;
969 uint32_t i;
970
973 std::optional<RegisterInfo> sp_reg =
975 for (i = 0; i < 15; ++i) {
976 if (BitIsSet(registers, i)) {
977 std::optional<RegisterInfo> reg_info =
979 context.SetRegisterToRegisterPlusOffset(*reg_info, *sp_reg, addr - sp);
980 uint32_t reg_value = ReadCoreReg(i, &success);
981 if (!success)
982 return false;
983 if (!MemAWrite(context, addr, reg_value, addr_byte_size))
984 return false;
985 addr += addr_byte_size;
986 }
987 }
988
989 if (BitIsSet(registers, 15)) {
990 std::optional<RegisterInfo> reg_info =
992 context.SetRegisterToRegisterPlusOffset(*reg_info, *sp_reg, addr - sp);
993 const uint32_t pc = ReadCoreReg(PC_REG, &success);
994 if (!success)
995 return false;
996 if (!MemAWrite(context, addr, pc, addr_byte_size))
997 return false;
998 }
999
1001 context.SetImmediateSigned(-sp_offset);
1002
1004 LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1005 return false;
1006 }
1007 return true;
1008}
1009
1010// Pop Multiple Registers loads multiple registers from the stack, loading from
1011// consecutive memory locations staring at the address in SP, and updates
1012// SP to point just above the loaded data.
1013bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
1014 const ARMEncoding encoding) {
1015#if 0
1016 // ARM pseudo code...
1017 if (ConditionPassed())
1018 {
1019 EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1020 address = SP;
1021 for i = 0 to 14
1022 if registers<i> == '1' then
1023 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
1024 if registers<15> == '1' then
1025 if UnalignedAllowed then
1026 LoadWritePC(MemU[address,4]);
1027 else
1028 LoadWritePC(MemA[address,4]);
1029 if registers<13> == '0' then SP = SP + 4*BitCount(registers);
1030 if registers<13> == '1' then SP = bits(32) UNKNOWN;
1031 }
1032#endif
1033
1034 bool success = false;
1035
1036 if (ConditionPassed(opcode)) {
1037 const uint32_t addr_byte_size = GetAddressByteSize();
1038 const addr_t sp = ReadCoreReg(SP_REG, &success);
1039 if (!success)
1040 return false;
1041 uint32_t registers = 0;
1042 uint32_t Rt; // the destination register
1043 switch (encoding) {
1044 case eEncodingT1:
1045 registers = Bits32(opcode, 7, 0);
1046 // The P bit represents PC.
1047 if (Bit32(opcode, 8))
1048 registers |= (1u << 15);
1049 // if BitCount(registers) < 1 then UNPREDICTABLE;
1050 if (BitCount(registers) < 1)
1051 return false;
1052 break;
1053 case eEncodingT2:
1054 // Ignore bit 13.
1055 registers = Bits32(opcode, 15, 0) & ~0x2000;
1056 // if BitCount(registers) < 2 || (P == '1' && M == '1') then
1057 // UNPREDICTABLE;
1058 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
1059 return false;
1060 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
1061 // UNPREDICTABLE;
1062 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1063 return false;
1064 break;
1065 case eEncodingT3:
1066 Rt = Bits32(opcode, 15, 12);
1067 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
1068 // UNPREDICTABLE;
1069 if (Rt == 13)
1070 return false;
1071 if (Rt == 15 && InITBlock() && !LastInITBlock())
1072 return false;
1073 registers = (1u << Rt);
1074 break;
1075 case eEncodingA1:
1076 registers = Bits32(opcode, 15, 0);
1077 // Instead of return false, let's handle the following case as well,
1078 // which amounts to popping one reg from the full descending stacks.
1079 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
1080
1081 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
1082 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
1083 return false;
1084 break;
1085 case eEncodingA2:
1086 Rt = Bits32(opcode, 15, 12);
1087 // if t == 13 then UNPREDICTABLE;
1088 if (Rt == dwarf_sp)
1089 return false;
1090 registers = (1u << Rt);
1091 break;
1092 default:
1093 return false;
1094 }
1095 addr_t sp_offset = addr_byte_size * BitCount(registers);
1096 addr_t addr = sp;
1097 uint32_t i, data;
1098
1101
1102 std::optional<RegisterInfo> sp_reg =
1104
1105 for (i = 0; i < 15; ++i) {
1106 if (BitIsSet(registers, i)) {
1107 context.SetAddress(addr);
1108 data = MemARead(context, addr, 4, 0, &success);
1109 if (!success)
1110 return false;
1112 data))
1113 return false;
1114 addr += addr_byte_size;
1115 }
1116 }
1117
1118 if (BitIsSet(registers, 15)) {
1119 context.SetRegisterPlusOffset(*sp_reg, addr - sp);
1120 data = MemARead(context, addr, 4, 0, &success);
1121 if (!success)
1122 return false;
1123 // In ARMv5T and above, this is an interworking branch.
1124 if (!LoadWritePC(context, data))
1125 return false;
1126 // addr += addr_byte_size;
1127 }
1128
1130 context.SetImmediateSigned(sp_offset);
1131
1133 LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1134 return false;
1135 }
1136 return true;
1137}
1138
1139// Set r7 or ip to point to saved value residing within the stack.
1140// ADD (SP plus immediate)
1142 const ARMEncoding encoding) {
1143#if 0
1144 // ARM pseudo code...
1145 if (ConditionPassed())
1146 {
1147 EncodingSpecificOperations();
1148 (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1149 if d == 15 then
1150 ALUWritePC(result); // setflags is always FALSE here
1151 else
1152 R[d] = result;
1153 if setflags then
1154 APSR.N = result<31>;
1155 APSR.Z = IsZeroBit(result);
1156 APSR.C = carry;
1157 APSR.V = overflow;
1158 }
1159#endif
1160
1161 bool success = false;
1162
1163 if (ConditionPassed(opcode)) {
1164 const addr_t sp = ReadCoreReg(SP_REG, &success);
1165 if (!success)
1166 return false;
1167 uint32_t Rd; // the destination register
1168 uint32_t imm32;
1169 switch (encoding) {
1170 case eEncodingT1:
1171 Rd = 7;
1172 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
1173 break;
1174 case eEncodingA1:
1175 Rd = Bits32(opcode, 15, 12);
1176 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1177 break;
1178 default:
1179 return false;
1180 }
1181 addr_t sp_offset = imm32;
1182 addr_t addr = sp + sp_offset; // a pointer to the stack area
1183
1186 context.type = eContextSetFramePointer;
1187 else
1189 std::optional<RegisterInfo> sp_reg =
1191 context.SetRegisterPlusOffset(*sp_reg, sp_offset);
1192
1194 addr))
1195 return false;
1196 }
1197 return true;
1198}
1199
1200// Set r7 or ip to the current stack pointer.
1201// MOV (register)
1202bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
1203 const ARMEncoding encoding) {
1204#if 0
1205 // ARM pseudo code...
1206 if (ConditionPassed())
1207 {
1208 EncodingSpecificOperations();
1209 result = R[m];
1210 if d == 15 then
1211 ALUWritePC(result); // setflags is always FALSE here
1212 else
1213 R[d] = result;
1214 if setflags then
1215 APSR.N = result<31>;
1216 APSR.Z = IsZeroBit(result);
1217 // APSR.C unchanged
1218 // APSR.V unchanged
1219 }
1220#endif
1221
1222 bool success = false;
1223
1224 if (ConditionPassed(opcode)) {
1225 const addr_t sp = ReadCoreReg(SP_REG, &success);
1226 if (!success)
1227 return false;
1228 uint32_t Rd; // the destination register
1229 switch (encoding) {
1230 case eEncodingT1:
1231 Rd = 7;
1232 break;
1233 case eEncodingA1:
1234 Rd = 12;
1235 break;
1236 default:
1237 return false;
1238 }
1239
1243 else
1245 std::optional<RegisterInfo> sp_reg =
1247 context.SetRegisterPlusOffset(*sp_reg, 0);
1248
1250 return false;
1251 }
1252 return true;
1253}
1254
1255// Move from high register (r8-r15) to low register (r0-r7).
1256// MOV (register)
1258 const ARMEncoding encoding) {
1259 return EmulateMOVRdRm(opcode, encoding);
1260}
1261
1262// Move from register to register.
1263// MOV (register)
1264bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
1265 const ARMEncoding encoding) {
1266#if 0
1267 // ARM pseudo code...
1268 if (ConditionPassed())
1269 {
1270 EncodingSpecificOperations();
1271 result = R[m];
1272 if d == 15 then
1273 ALUWritePC(result); // setflags is always FALSE here
1274 else
1275 R[d] = result;
1276 if setflags then
1277 APSR.N = result<31>;
1278 APSR.Z = IsZeroBit(result);
1279 // APSR.C unchanged
1280 // APSR.V unchanged
1281 }
1282#endif
1283
1284 bool success = false;
1285
1286 if (ConditionPassed(opcode)) {
1287 uint32_t Rm; // the source register
1288 uint32_t Rd; // the destination register
1289 bool setflags;
1290 switch (encoding) {
1291 case eEncodingT1:
1292 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1293 Rm = Bits32(opcode, 6, 3);
1294 setflags = false;
1295 if (Rd == 15 && InITBlock() && !LastInITBlock())
1296 return false;
1297 break;
1298 case eEncodingT2:
1299 Rd = Bits32(opcode, 2, 0);
1300 Rm = Bits32(opcode, 5, 3);
1301 setflags = true;
1302 if (InITBlock())
1303 return false;
1304 break;
1305 case eEncodingT3:
1306 Rd = Bits32(opcode, 11, 8);
1307 Rm = Bits32(opcode, 3, 0);
1308 setflags = BitIsSet(opcode, 20);
1309 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1310 if (setflags && (BadReg(Rd) || BadReg(Rm)))
1311 return false;
1312 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
1313 // UNPREDICTABLE;
1314 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1315 return false;
1316 break;
1317 case eEncodingA1:
1318 Rd = Bits32(opcode, 15, 12);
1319 Rm = Bits32(opcode, 3, 0);
1320 setflags = BitIsSet(opcode, 20);
1321
1322 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1323 // instructions;
1324 if (Rd == 15 && setflags)
1325 return EmulateSUBSPcLrEtc(opcode, encoding);
1326 break;
1327 default:
1328 return false;
1329 }
1330 uint32_t result = ReadCoreReg(Rm, &success);
1331 if (!success)
1332 return false;
1333
1334 // The context specifies that Rm is to be moved into Rd.
1336 if (Rd == 13)
1338 else if (Rd == GetFramePointerRegisterNumber() && Rm == 13)
1340 else
1342 std::optional<RegisterInfo> dwarf_reg =
1344 context.SetRegisterPlusOffset(*dwarf_reg, 0);
1345
1346 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1347 return false;
1348 }
1349 return true;
1350}
1351
1352// Move (immediate) writes an immediate value to the destination register. It
1353// can optionally update the condition flags based on the value.
1354// MOV (immediate)
1356 const ARMEncoding encoding) {
1357#if 0
1358 // ARM pseudo code...
1359 if (ConditionPassed())
1360 {
1361 EncodingSpecificOperations();
1362 result = imm32;
1363 if d == 15 then // Can only occur for ARM encoding
1364 ALUWritePC(result); // setflags is always FALSE here
1365 else
1366 R[d] = result;
1367 if setflags then
1368 APSR.N = result<31>;
1369 APSR.Z = IsZeroBit(result);
1370 APSR.C = carry;
1371 // APSR.V unchanged
1372 }
1373#endif
1374
1375 if (ConditionPassed(opcode)) {
1376 uint32_t Rd; // the destination register
1377 uint32_t imm32; // the immediate value to be written to Rd
1378 uint32_t carry =
1379 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
1380 // for setflags == false, this value is a don't care initialized to
1381 // 0 to silence the static analyzer
1382 bool setflags;
1383 switch (encoding) {
1384 case eEncodingT1:
1385 Rd = Bits32(opcode, 10, 8);
1386 setflags = !InITBlock();
1387 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
1388 carry = APSR_C;
1389
1390 break;
1391
1392 case eEncodingT2:
1393 Rd = Bits32(opcode, 11, 8);
1394 setflags = BitIsSet(opcode, 20);
1395 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1396 if (BadReg(Rd))
1397 return false;
1398
1399 break;
1400
1401 case eEncodingT3: {
1402 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
1403 // 32);
1404 Rd = Bits32(opcode, 11, 8);
1405 setflags = false;
1406 uint32_t imm4 = Bits32(opcode, 19, 16);
1407 uint32_t imm3 = Bits32(opcode, 14, 12);
1408 uint32_t i = Bit32(opcode, 26);
1409 uint32_t imm8 = Bits32(opcode, 7, 0);
1410 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1411
1412 // if BadReg(d) then UNPREDICTABLE;
1413 if (BadReg(Rd))
1414 return false;
1415 } break;
1416
1417 case eEncodingA1:
1418 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
1419 // ARMExpandImm_C(imm12, APSR.C);
1420 Rd = Bits32(opcode, 15, 12);
1421 setflags = BitIsSet(opcode, 20);
1422 imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1423
1424 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1425 // instructions;
1426 if ((Rd == 15) && setflags)
1427 return EmulateSUBSPcLrEtc(opcode, encoding);
1428
1429 break;
1430
1431 case eEncodingA2: {
1432 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
1433 Rd = Bits32(opcode, 15, 12);
1434 setflags = false;
1435 uint32_t imm4 = Bits32(opcode, 19, 16);
1436 uint32_t imm12 = Bits32(opcode, 11, 0);
1437 imm32 = (imm4 << 12) | imm12;
1438
1439 // if d == 15 then UNPREDICTABLE;
1440 if (Rd == 15)
1441 return false;
1442 } break;
1443
1444 default:
1445 return false;
1446 }
1447 uint32_t result = imm32;
1448
1449 // The context specifies that an immediate is to be moved into Rd.
1452 context.SetNoArgs();
1453
1454 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1455 return false;
1456 }
1457 return true;
1458}
1459
1460// MUL multiplies two register values. The least significant 32 bits of the
1461// result are written to the destination
1462// register. These 32 bits do not depend on whether the source register values
1463// are considered to be signed values or unsigned values.
1464//
1465// Optionally, it can update the condition flags based on the result. In the
1466// Thumb instruction set, this option is limited to only a few forms of the
1467// instruction.
1468bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
1469 const ARMEncoding encoding) {
1470#if 0
1471 if ConditionPassed() then
1472 EncodingSpecificOperations();
1473 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1474 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1475 result = operand1 * operand2;
1476 R[d] = result<31:0>;
1477 if setflags then
1478 APSR.N = result<31>;
1479 APSR.Z = IsZeroBit(result);
1480 if ArchVersion() == 4 then
1481 APSR.C = bit UNKNOWN;
1482 // else APSR.C unchanged
1483 // APSR.V always unchanged
1484#endif
1485
1486 if (ConditionPassed(opcode)) {
1487 uint32_t d;
1488 uint32_t n;
1489 uint32_t m;
1490 bool setflags;
1491
1492 // EncodingSpecificOperations();
1493 switch (encoding) {
1494 case eEncodingT1:
1495 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
1496 d = Bits32(opcode, 2, 0);
1497 n = Bits32(opcode, 5, 3);
1498 m = Bits32(opcode, 2, 0);
1499 setflags = !InITBlock();
1500
1501 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1502 if ((ArchVersion() < ARMv6) && (d == n))
1503 return false;
1504
1505 break;
1506
1507 case eEncodingT2:
1508 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
1509 d = Bits32(opcode, 11, 8);
1510 n = Bits32(opcode, 19, 16);
1511 m = Bits32(opcode, 3, 0);
1512 setflags = false;
1513
1514 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1515 if (BadReg(d) || BadReg(n) || BadReg(m))
1516 return false;
1517
1518 break;
1519
1520 case eEncodingA1:
1521 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1522 d = Bits32(opcode, 19, 16);
1523 n = Bits32(opcode, 3, 0);
1524 m = Bits32(opcode, 11, 8);
1525 setflags = BitIsSet(opcode, 20);
1526
1527 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1528 if ((d == 15) || (n == 15) || (m == 15))
1529 return false;
1530
1531 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1532 if ((ArchVersion() < ARMv6) && (d == n))
1533 return false;
1534
1535 break;
1536
1537 default:
1538 return false;
1539 }
1540
1541 bool success = false;
1542
1543 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1544 // results
1545 uint64_t operand1 =
1547 if (!success)
1548 return false;
1549
1550 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1551 // results
1552 uint64_t operand2 =
1554 if (!success)
1555 return false;
1556
1557 // result = operand1 * operand2;
1558 uint64_t result = operand1 * operand2;
1559
1560 // R[d] = result<31:0>;
1561 std::optional<RegisterInfo> op1_reg =
1563 std::optional<RegisterInfo> op2_reg =
1565
1567 context.type = eContextArithmetic;
1568 context.SetRegisterRegisterOperands(*op1_reg, *op2_reg);
1569
1571 (0x0000ffff & result)))
1572 return false;
1573
1574 // if setflags then
1575 if (setflags) {
1576 // APSR.N = result<31>;
1577 // APSR.Z = IsZeroBit(result);
1580 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1584 return false;
1585 }
1586
1587 // if ArchVersion() == 4 then
1588 // APSR.C = bit UNKNOWN;
1589 }
1590 }
1591 return true;
1592}
1593
1594// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1595// the destination register. It can optionally update the condition flags based
1596// on the value.
1597bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1598 const ARMEncoding encoding) {
1599#if 0
1600 // ARM pseudo code...
1601 if (ConditionPassed())
1602 {
1603 EncodingSpecificOperations();
1604 result = NOT(imm32);
1605 if d == 15 then // Can only occur for ARM encoding
1606 ALUWritePC(result); // setflags is always FALSE here
1607 else
1608 R[d] = result;
1609 if setflags then
1610 APSR.N = result<31>;
1611 APSR.Z = IsZeroBit(result);
1612 APSR.C = carry;
1613 // APSR.V unchanged
1614 }
1615#endif
1616
1617 if (ConditionPassed(opcode)) {
1618 uint32_t Rd; // the destination register
1619 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1620 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1621 bool setflags;
1622 switch (encoding) {
1623 case eEncodingT1:
1624 Rd = Bits32(opcode, 11, 8);
1625 setflags = BitIsSet(opcode, 20);
1626 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1627 break;
1628 case eEncodingA1:
1629 Rd = Bits32(opcode, 15, 12);
1630 setflags = BitIsSet(opcode, 20);
1631 imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1632
1633 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1634 // instructions;
1635 if (Rd == 15 && setflags)
1636 return EmulateSUBSPcLrEtc(opcode, encoding);
1637 break;
1638 default:
1639 return false;
1640 }
1641 uint32_t result = ~imm32;
1642
1643 // The context specifies that an immediate is to be moved into Rd.
1646 context.SetNoArgs();
1647
1648 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1649 return false;
1650 }
1651 return true;
1652}
1653
1654// Bitwise NOT (register) writes the bitwise inverse of a register value to the
1655// destination register. It can optionally update the condition flags based on
1656// the result.
1657bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1658 const ARMEncoding encoding) {
1659#if 0
1660 // ARM pseudo code...
1661 if (ConditionPassed())
1662 {
1663 EncodingSpecificOperations();
1664 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1665 result = NOT(shifted);
1666 if d == 15 then // Can only occur for ARM encoding
1667 ALUWritePC(result); // setflags is always FALSE here
1668 else
1669 R[d] = result;
1670 if setflags then
1671 APSR.N = result<31>;
1672 APSR.Z = IsZeroBit(result);
1673 APSR.C = carry;
1674 // APSR.V unchanged
1675 }
1676#endif
1677
1678 if (ConditionPassed(opcode)) {
1679 uint32_t Rm; // the source register
1680 uint32_t Rd; // the destination register
1681 ARM_ShifterType shift_t;
1682 uint32_t shift_n; // the shift applied to the value read from Rm
1683 bool setflags;
1684 uint32_t carry; // the carry bit after the shift operation
1685 switch (encoding) {
1686 case eEncodingT1:
1687 Rd = Bits32(opcode, 2, 0);
1688 Rm = Bits32(opcode, 5, 3);
1689 setflags = !InITBlock();
1690 shift_t = SRType_LSL;
1691 shift_n = 0;
1692 if (InITBlock())
1693 return false;
1694 break;
1695 case eEncodingT2:
1696 Rd = Bits32(opcode, 11, 8);
1697 Rm = Bits32(opcode, 3, 0);
1698 setflags = BitIsSet(opcode, 20);
1699 shift_n = DecodeImmShiftThumb(opcode, shift_t);
1700 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1701 if (BadReg(Rd) || BadReg(Rm))
1702 return false;
1703 break;
1704 case eEncodingA1:
1705 Rd = Bits32(opcode, 15, 12);
1706 Rm = Bits32(opcode, 3, 0);
1707 setflags = BitIsSet(opcode, 20);
1708 shift_n = DecodeImmShiftARM(opcode, shift_t);
1709 break;
1710 default:
1711 return false;
1712 }
1713 bool success = false;
1714 uint32_t value = ReadCoreReg(Rm, &success);
1715 if (!success)
1716 return false;
1717
1718 uint32_t shifted =
1719 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1720 if (!success)
1721 return false;
1722 uint32_t result = ~shifted;
1723
1724 // The context specifies that an immediate is to be moved into Rd.
1727 context.SetNoArgs();
1728
1729 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1730 return false;
1731 }
1732 return true;
1733}
1734
1735// PC relative immediate load into register, possibly followed by ADD (SP plus
1736// register).
1737// LDR (literal)
1739 const ARMEncoding encoding) {
1740#if 0
1741 // ARM pseudo code...
1742 if (ConditionPassed())
1743 {
1744 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1745 base = Align(PC,4);
1746 address = if add then (base + imm32) else (base - imm32);
1747 data = MemU[address,4];
1748 if t == 15 then
1749 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1750 elsif UnalignedSupport() || address<1:0> = '00' then
1751 R[t] = data;
1752 else // Can only apply before ARMv7
1753 if CurrentInstrSet() == InstrSet_ARM then
1754 R[t] = ROR(data, 8*UInt(address<1:0>));
1755 else
1756 R[t] = bits(32) UNKNOWN;
1757 }
1758#endif
1759
1760 if (ConditionPassed(opcode)) {
1761 bool success = false;
1762 const uint32_t pc = ReadCoreReg(PC_REG, &success);
1763 if (!success)
1764 return false;
1765
1766 // PC relative immediate load context
1769 std::optional<RegisterInfo> pc_reg =
1771 context.SetRegisterPlusOffset(*pc_reg, 0);
1772
1773 uint32_t Rt; // the destination register
1774 uint32_t imm32; // immediate offset from the PC
1775 bool add; // +imm32 or -imm32?
1776 addr_t base; // the base address
1777 addr_t address; // the PC relative address
1778 uint32_t data; // the literal data value from the PC relative load
1779 switch (encoding) {
1780 case eEncodingT1:
1781 Rt = Bits32(opcode, 10, 8);
1782 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1783 add = true;
1784 break;
1785 case eEncodingT2:
1786 Rt = Bits32(opcode, 15, 12);
1787 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1788 add = BitIsSet(opcode, 23);
1789 if (Rt == 15 && InITBlock() && !LastInITBlock())
1790 return false;
1791 break;
1792 default:
1793 return false;
1794 }
1795
1796 base = Align(pc, 4);
1797 if (add)
1798 address = base + imm32;
1799 else
1800 address = base - imm32;
1801
1802 context.SetRegisterPlusOffset(*pc_reg, address - base);
1803 data = MemURead(context, address, 4, 0, &success);
1804 if (!success)
1805 return false;
1806
1807 if (Rt == 15) {
1808 if (Bits32(address, 1, 0) == 0) {
1809 // In ARMv5T and above, this is an interworking branch.
1810 if (!LoadWritePC(context, data))
1811 return false;
1812 } else
1813 return false;
1814 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1816 data))
1817 return false;
1818 } else // We don't handle ARM for now.
1819 return false;
1820 }
1821 return true;
1822}
1823
1824// An add operation to adjust the SP.
1825// ADD (SP plus immediate)
1827 const ARMEncoding encoding) {
1828#if 0
1829 // ARM pseudo code...
1830 if (ConditionPassed())
1831 {
1832 EncodingSpecificOperations();
1833 (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1834 if d == 15 then // Can only occur for ARM encoding
1835 ALUWritePC(result); // setflags is always FALSE here
1836 else
1837 R[d] = result;
1838 if setflags then
1839 APSR.N = result<31>;
1840 APSR.Z = IsZeroBit(result);
1841 APSR.C = carry;
1842 APSR.V = overflow;
1843 }
1844#endif
1845
1846 bool success = false;
1847
1848 if (ConditionPassed(opcode)) {
1849 const addr_t sp = ReadCoreReg(SP_REG, &success);
1850 if (!success)
1851 return false;
1852 uint32_t imm32; // the immediate operand
1853 uint32_t d;
1854 bool setflags;
1855 switch (encoding) {
1856 case eEncodingT1:
1857 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1858 d = Bits32(opcode, 10, 8);
1859 imm32 = (Bits32(opcode, 7, 0) << 2);
1860 setflags = false;
1861 break;
1862
1863 case eEncodingT2:
1864 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1865 d = 13;
1866 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1867 setflags = false;
1868 break;
1869
1870 case eEncodingT3:
1871 // d = UInt(Rd); setflags = (S == "1"); imm32 =
1872 // ThumbExpandImm(i:imm3:imm8);
1873 d = Bits32(opcode, 11, 8);
1874 imm32 = ThumbExpandImm(opcode);
1875 setflags = Bit32(opcode, 20);
1876
1877 // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1878 if (d == 15 && setflags == 1)
1879 return false; // CMN (immediate) not yet supported
1880
1881 // if d == 15 && S == "0" then UNPREDICTABLE;
1882 if (d == 15 && setflags == 0)
1883 return false;
1884 break;
1885
1886 case eEncodingT4: {
1887 // if Rn == '1111' then SEE ADR;
1888 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1889 d = Bits32(opcode, 11, 8);
1890 setflags = false;
1891 uint32_t i = Bit32(opcode, 26);
1892 uint32_t imm3 = Bits32(opcode, 14, 12);
1893 uint32_t imm8 = Bits32(opcode, 7, 0);
1894 imm32 = (i << 11) | (imm3 << 8) | imm8;
1895
1896 // if d == 15 then UNPREDICTABLE;
1897 if (d == 15)
1898 return false;
1899 } break;
1900
1901 default:
1902 return false;
1903 }
1904 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1905 AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1906
1908 if (d == 13)
1910 else
1912
1913 std::optional<RegisterInfo> sp_reg =
1915 context.SetRegisterPlusOffset(*sp_reg, res.result - sp);
1916
1917 if (d == 15) {
1918 if (!ALUWritePC(context, res.result))
1919 return false;
1920 } else {
1921 // R[d] = result;
1922 // if setflags then
1923 // APSR.N = result<31>;
1924 // APSR.Z = IsZeroBit(result);
1925 // APSR.C = carry;
1926 // APSR.V = overflow;
1927 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1928 res.carry_out, res.overflow))
1929 return false;
1930 }
1931 }
1932 return true;
1933}
1934
1935// An add operation to adjust the SP.
1936// ADD (SP plus register)
1937bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1938 const ARMEncoding encoding) {
1939#if 0
1940 // ARM pseudo code...
1941 if (ConditionPassed())
1942 {
1943 EncodingSpecificOperations();
1944 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1945 (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1946 if d == 15 then
1947 ALUWritePC(result); // setflags is always FALSE here
1948 else
1949 R[d] = result;
1950 if setflags then
1951 APSR.N = result<31>;
1952 APSR.Z = IsZeroBit(result);
1953 APSR.C = carry;
1954 APSR.V = overflow;
1955 }
1956#endif
1957
1958 bool success = false;
1959
1960 if (ConditionPassed(opcode)) {
1961 const addr_t sp = ReadCoreReg(SP_REG, &success);
1962 if (!success)
1963 return false;
1964 uint32_t Rm; // the second operand
1965 switch (encoding) {
1966 case eEncodingT2:
1967 Rm = Bits32(opcode, 6, 3);
1968 break;
1969 default:
1970 return false;
1971 }
1972 int32_t reg_value = ReadCoreReg(Rm, &success);
1973 if (!success)
1974 return false;
1975
1976 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1977
1979 context.type = eContextArithmetic;
1980 std::optional<RegisterInfo> sp_reg =
1982 std::optional<RegisterInfo> other_reg =
1984 context.SetRegisterRegisterOperands(*sp_reg, *other_reg);
1985
1988 return false;
1989 }
1990 return true;
1991}
1992
1993// Branch with Link and Exchange Instruction Sets (immediate) calls a
1994// subroutine at a PC-relative address, and changes instruction set from ARM to
1995// Thumb, or from Thumb to ARM.
1996// BLX (immediate)
1998 const ARMEncoding encoding) {
1999#if 0
2000 // ARM pseudo code...
2001 if (ConditionPassed())
2002 {
2003 EncodingSpecificOperations();
2004 if CurrentInstrSet() == InstrSet_ARM then
2005 LR = PC - 4;
2006 else
2007 LR = PC<31:1> : '1';
2008 if targetInstrSet == InstrSet_ARM then
2009 targetAddress = Align(PC,4) + imm32;
2010 else
2011 targetAddress = PC + imm32;
2012 SelectInstrSet(targetInstrSet);
2013 BranchWritePC(targetAddress);
2014 }
2015#endif
2016
2017 bool success = true;
2018
2019 if (ConditionPassed(opcode)) {
2022 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2023 if (!success)
2024 return false;
2025 addr_t lr; // next instruction address
2026 addr_t target; // target address
2027 int32_t imm32; // PC-relative offset
2028 switch (encoding) {
2029 case eEncodingT1: {
2030 lr = pc | 1u; // return address
2031 uint32_t S = Bit32(opcode, 26);
2032 uint32_t imm10 = Bits32(opcode, 25, 16);
2033 uint32_t J1 = Bit32(opcode, 13);
2034 uint32_t J2 = Bit32(opcode, 11);
2035 uint32_t imm11 = Bits32(opcode, 10, 0);
2036 uint32_t I1 = !(J1 ^ S);
2037 uint32_t I2 = !(J2 ^ S);
2038 uint32_t imm25 =
2039 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2040 imm32 = llvm::SignExtend32<25>(imm25);
2041 target = pc + imm32;
2043 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2044 if (InITBlock() && !LastInITBlock())
2045 return false;
2046 break;
2047 }
2048 case eEncodingT2: {
2049 lr = pc | 1u; // return address
2050 uint32_t S = Bit32(opcode, 26);
2051 uint32_t imm10H = Bits32(opcode, 25, 16);
2052 uint32_t J1 = Bit32(opcode, 13);
2053 uint32_t J2 = Bit32(opcode, 11);
2054 uint32_t imm10L = Bits32(opcode, 10, 1);
2055 uint32_t I1 = !(J1 ^ S);
2056 uint32_t I2 = !(J2 ^ S);
2057 uint32_t imm25 =
2058 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2059 imm32 = llvm::SignExtend32<25>(imm25);
2060 target = Align(pc, 4) + imm32;
2062 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
2063 if (InITBlock() && !LastInITBlock())
2064 return false;
2065 break;
2066 }
2067 case eEncodingA1:
2068 lr = pc - 4; // return address
2069 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2070 target = Align(pc, 4) + imm32;
2072 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2073 break;
2074 case eEncodingA2:
2075 lr = pc - 4; // return address
2076 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
2077 Bits32(opcode, 24, 24) << 1);
2078 target = pc + imm32;
2080 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
2081 break;
2082 default:
2083 return false;
2084 }
2087 return false;
2088 if (!BranchWritePC(context, target))
2089 return false;
2093 return false;
2094 }
2095 return true;
2096}
2097
2098// Branch with Link and Exchange (register) calls a subroutine at an address
2099// and instruction set specified by a register.
2100// BLX (register)
2101bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
2102 const ARMEncoding encoding) {
2103#if 0
2104 // ARM pseudo code...
2105 if (ConditionPassed())
2106 {
2107 EncodingSpecificOperations();
2108 target = R[m];
2109 if CurrentInstrSet() == InstrSet_ARM then
2110 next_instr_addr = PC - 4;
2111 LR = next_instr_addr;
2112 else
2113 next_instr_addr = PC - 2;
2114 LR = next_instr_addr<31:1> : '1';
2115 BXWritePC(target);
2116 }
2117#endif
2118
2119 bool success = false;
2120
2121 if (ConditionPassed(opcode)) {
2124 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2125 addr_t lr; // next instruction address
2126 if (!success)
2127 return false;
2128 uint32_t Rm; // the register with the target address
2129 switch (encoding) {
2130 case eEncodingT1:
2131 lr = (pc - 2) | 1u; // return address
2132 Rm = Bits32(opcode, 6, 3);
2133 // if m == 15 then UNPREDICTABLE;
2134 if (Rm == 15)
2135 return false;
2136 if (InITBlock() && !LastInITBlock())
2137 return false;
2138 break;
2139 case eEncodingA1:
2140 lr = pc - 4; // return address
2141 Rm = Bits32(opcode, 3, 0);
2142 // if m == 15 then UNPREDICTABLE;
2143 if (Rm == 15)
2144 return false;
2145 break;
2146 default:
2147 return false;
2148 }
2149 addr_t target = ReadCoreReg(Rm, &success);
2150 if (!success)
2151 return false;
2152 std::optional<RegisterInfo> dwarf_reg =
2154 context.SetRegister(*dwarf_reg);
2157 return false;
2158 if (!BXWritePC(context, target))
2159 return false;
2160 }
2161 return true;
2162}
2163
2164// Branch and Exchange causes a branch to an address and instruction set
2165// specified by a register.
2166bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
2167 const ARMEncoding encoding) {
2168#if 0
2169 // ARM pseudo code...
2170 if (ConditionPassed())
2171 {
2172 EncodingSpecificOperations();
2173 BXWritePC(R[m]);
2174 }
2175#endif
2176
2177 if (ConditionPassed(opcode)) {
2180 uint32_t Rm; // the register with the target address
2181 switch (encoding) {
2182 case eEncodingT1:
2183 Rm = Bits32(opcode, 6, 3);
2184 if (InITBlock() && !LastInITBlock())
2185 return false;
2186 break;
2187 case eEncodingA1:
2188 Rm = Bits32(opcode, 3, 0);
2189 break;
2190 default:
2191 return false;
2192 }
2193 bool success = false;
2194 addr_t target = ReadCoreReg(Rm, &success);
2195 if (!success)
2196 return false;
2197
2198 std::optional<RegisterInfo> dwarf_reg =
2200 context.SetRegister(*dwarf_reg);
2201 if (!BXWritePC(context, target))
2202 return false;
2203 }
2204 return true;
2205}
2206
2207// Branch and Exchange Jazelle attempts to change to Jazelle state. If the
2208// attempt fails, it branches to an address and instruction set specified by a
2209// register as though it were a BX instruction.
2210//
2211// TODO: Emulate Jazelle architecture?
2212// We currently assume that switching to Jazelle state fails, thus
2213// treating BXJ as a BX operation.
2214bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
2215 const ARMEncoding encoding) {
2216#if 0
2217 // ARM pseudo code...
2218 if (ConditionPassed())
2219 {
2220 EncodingSpecificOperations();
2221 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
2222 BXWritePC(R[m]);
2223 else
2224 if JazelleAcceptsExecution() then
2225 SwitchToJazelleExecution();
2226 else
2227 SUBARCHITECTURE_DEFINED handler call;
2228 }
2229#endif
2230
2231 if (ConditionPassed(opcode)) {
2234 uint32_t Rm; // the register with the target address
2235 switch (encoding) {
2236 case eEncodingT1:
2237 Rm = Bits32(opcode, 19, 16);
2238 if (BadReg(Rm))
2239 return false;
2240 if (InITBlock() && !LastInITBlock())
2241 return false;
2242 break;
2243 case eEncodingA1:
2244 Rm = Bits32(opcode, 3, 0);
2245 if (Rm == 15)
2246 return false;
2247 break;
2248 default:
2249 return false;
2250 }
2251 bool success = false;
2252 addr_t target = ReadCoreReg(Rm, &success);
2253 if (!success)
2254 return false;
2255
2256 std::optional<RegisterInfo> dwarf_reg =
2258 context.SetRegister(*dwarf_reg);
2259 if (!BXWritePC(context, target))
2260 return false;
2261 }
2262 return true;
2263}
2264
2265// Set r7 to point to some ip offset.
2266// SUB (immediate)
2268 const ARMEncoding encoding) {
2269#if 0
2270 // ARM pseudo code...
2271 if (ConditionPassed())
2272 {
2273 EncodingSpecificOperations();
2274 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2275 if d == 15 then // Can only occur for ARM encoding
2276 ALUWritePC(result); // setflags is always FALSE here
2277 else
2278 R[d] = result;
2279 if setflags then
2280 APSR.N = result<31>;
2281 APSR.Z = IsZeroBit(result);
2282 APSR.C = carry;
2283 APSR.V = overflow;
2284 }
2285#endif
2286
2287 if (ConditionPassed(opcode)) {
2288 bool success = false;
2289 const addr_t ip = ReadCoreReg(12, &success);
2290 if (!success)
2291 return false;
2292 uint32_t imm32;
2293 switch (encoding) {
2294 case eEncodingA1:
2295 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2296 break;
2297 default:
2298 return false;
2299 }
2300 addr_t ip_offset = imm32;
2301 addr_t addr = ip - ip_offset; // the adjusted ip value
2302
2305 std::optional<RegisterInfo> dwarf_reg =
2307 context.SetRegisterPlusOffset(*dwarf_reg, -ip_offset);
2308
2310 return false;
2311 }
2312 return true;
2313}
2314
2315// Set ip to point to some stack offset.
2316// SUB (SP minus immediate)
2318 const ARMEncoding encoding) {
2319#if 0
2320 // ARM pseudo code...
2321 if (ConditionPassed())
2322 {
2323 EncodingSpecificOperations();
2324 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2325 if d == 15 then // Can only occur for ARM encoding
2326 ALUWritePC(result); // setflags is always FALSE here
2327 else
2328 R[d] = result;
2329 if setflags then
2330 APSR.N = result<31>;
2331 APSR.Z = IsZeroBit(result);
2332 APSR.C = carry;
2333 APSR.V = overflow;
2334 }
2335#endif
2336
2337 if (ConditionPassed(opcode)) {
2338 bool success = false;
2339 const addr_t sp = ReadCoreReg(SP_REG, &success);
2340 if (!success)
2341 return false;
2342 uint32_t imm32;
2343 switch (encoding) {
2344 case eEncodingA1:
2345 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2346 break;
2347 default:
2348 return false;
2349 }
2350 addr_t sp_offset = imm32;
2351 addr_t addr = sp - sp_offset; // the adjusted stack pointer value
2352
2355 std::optional<RegisterInfo> dwarf_reg =
2357 context.SetRegisterPlusOffset(*dwarf_reg, -sp_offset);
2358
2360 return false;
2361 }
2362 return true;
2363}
2364
2365// This instruction subtracts an immediate value from the SP value, and writes
2366// the result to the destination register.
2367//
2368// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
2369// storage.
2371 const ARMEncoding encoding) {
2372#if 0
2373 // ARM pseudo code...
2374 if (ConditionPassed())
2375 {
2376 EncodingSpecificOperations();
2377 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2378 if d == 15 then // Can only occur for ARM encoding
2379 ALUWritePC(result); // setflags is always FALSE here
2380 else
2381 R[d] = result;
2382 if setflags then
2383 APSR.N = result<31>;
2384 APSR.Z = IsZeroBit(result);
2385 APSR.C = carry;
2386 APSR.V = overflow;
2387 }
2388#endif
2389
2390 bool success = false;
2391 if (ConditionPassed(opcode)) {
2392 const addr_t sp = ReadCoreReg(SP_REG, &success);
2393 if (!success)
2394 return false;
2395
2396 uint32_t Rd;
2397 bool setflags;
2398 uint32_t imm32;
2399 switch (encoding) {
2400 case eEncodingT1:
2401 Rd = 13;
2402 setflags = false;
2403 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
2404 break;
2405 case eEncodingT2:
2406 Rd = Bits32(opcode, 11, 8);
2407 setflags = BitIsSet(opcode, 20);
2408 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2409 if (Rd == 15 && setflags)
2410 return EmulateCMPImm(opcode, eEncodingT2);
2411 if (Rd == 15 && !setflags)
2412 return false;
2413 break;
2414 case eEncodingT3:
2415 Rd = Bits32(opcode, 11, 8);
2416 setflags = false;
2417 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
2418 if (Rd == 15)
2419 return false;
2420 break;
2421 case eEncodingA1:
2422 Rd = Bits32(opcode, 15, 12);
2423 setflags = BitIsSet(opcode, 20);
2424 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2425
2426 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
2427 // instructions;
2428 if (Rd == 15 && setflags)
2429 return EmulateSUBSPcLrEtc(opcode, encoding);
2430 break;
2431 default:
2432 return false;
2433 }
2434 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
2435
2437 if (Rd == 13) {
2438 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
2439 // to negate it, or the wrong
2440 // value gets passed down to context.SetImmediateSigned.
2442 context.SetImmediateSigned(-imm64); // the stack pointer offset
2443 } else {
2445 context.SetNoArgs();
2446 }
2447
2448 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2449 res.carry_out, res.overflow))
2450 return false;
2451 }
2452 return true;
2453}
2454
2455// A store operation to the stack that also updates the SP.
2456bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
2457 const ARMEncoding encoding) {
2458#if 0
2459 // ARM pseudo code...
2460 if (ConditionPassed())
2461 {
2462 EncodingSpecificOperations();
2463 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2464 address = if index then offset_addr else R[n];
2465 MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
2466 if wback then R[n] = offset_addr;
2467 }
2468#endif
2469
2470 bool success = false;
2471 if (ConditionPassed(opcode)) {
2472 const uint32_t addr_byte_size = GetAddressByteSize();
2473 const addr_t sp = ReadCoreReg(SP_REG, &success);
2474 if (!success)
2475 return false;
2476 uint32_t Rt; // the source register
2477 uint32_t imm12;
2478 uint32_t
2479 Rn; // This function assumes Rn is the SP, but we should verify that.
2480
2481 bool index;
2482 bool add;
2483 bool wback;
2484 switch (encoding) {
2485 case eEncodingA1:
2486 Rt = Bits32(opcode, 15, 12);
2487 imm12 = Bits32(opcode, 11, 0);
2488 Rn = Bits32(opcode, 19, 16);
2489
2490 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP.
2491 return false;
2492
2493 index = BitIsSet(opcode, 24);
2494 add = BitIsSet(opcode, 23);
2495 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
2496
2497 if (wback && ((Rn == 15) || (Rn == Rt)))
2498 return false;
2499 break;
2500 default:
2501 return false;
2502 }
2503 addr_t offset_addr;
2504 if (add)
2505 offset_addr = sp + imm12;
2506 else
2507 offset_addr = sp - imm12;
2508
2509 addr_t addr;
2510 if (index)
2511 addr = offset_addr;
2512 else
2513 addr = sp;
2514
2517 std::optional<RegisterInfo> sp_reg =
2519 std::optional<RegisterInfo> dwarf_reg =
2521
2522 context.SetRegisterToRegisterPlusOffset(*dwarf_reg, *sp_reg, addr - sp);
2523 if (Rt != 15) {
2524 uint32_t reg_value = ReadCoreReg(Rt, &success);
2525 if (!success)
2526 return false;
2527 if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2528 return false;
2529 } else {
2530 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2531 if (!success)
2532 return false;
2533 if (!MemUWrite(context, addr, pc, addr_byte_size))
2534 return false;
2535 }
2536
2537 if (wback) {
2539 context.SetImmediateSigned(addr - sp);
2541 LLDB_REGNUM_GENERIC_SP, offset_addr))
2542 return false;
2543 }
2544 }
2545 return true;
2546}
2547
2548// Vector Push stores multiple extension registers to the stack. It also
2549// updates SP to point to the start of the stored data.
2550bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2551 const ARMEncoding encoding) {
2552#if 0
2553 // ARM pseudo code...
2554 if (ConditionPassed())
2555 {
2556 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2557 address = SP - imm32;
2558 SP = SP - imm32;
2559 if single_regs then
2560 for r = 0 to regs-1
2561 MemA[address,4] = S[d+r]; address = address+4;
2562 else
2563 for r = 0 to regs-1
2564 // Store as two word-aligned words in the correct order for
2565 // current endianness.
2566 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2567 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2568 address = address+8;
2569 }
2570#endif
2571
2572 bool success = false;
2573 if (ConditionPassed(opcode)) {
2574 const uint32_t addr_byte_size = GetAddressByteSize();
2575 const addr_t sp = ReadCoreReg(SP_REG, &success);
2576 if (!success)
2577 return false;
2578 bool single_regs;
2579 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
2580 uint32_t imm32; // stack offset
2581 uint32_t regs; // number of registers
2582 switch (encoding) {
2583 case eEncodingT1:
2584 case eEncodingA1:
2585 single_regs = false;
2586 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2587 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2588 // If UInt(imm8) is odd, see "FSTMX".
2589 regs = Bits32(opcode, 7, 0) / 2;
2590 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2591 if (regs == 0 || regs > 16 || (d + regs) > 32)
2592 return false;
2593 break;
2594 case eEncodingT2:
2595 case eEncodingA2:
2596 single_regs = true;
2597 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2598 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2599 regs = Bits32(opcode, 7, 0);
2600 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2601 if (regs == 0 || regs > 16 || (d + regs) > 32)
2602 return false;
2603 break;
2604 default:
2605 return false;
2606 }
2607 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2608 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2609 addr_t sp_offset = imm32;
2610 addr_t addr = sp - sp_offset;
2611 uint32_t i;
2612
2615
2616 std::optional<RegisterInfo> sp_reg =
2618 for (i = 0; i < regs; ++i) {
2619 std::optional<RegisterInfo> dwarf_reg =
2620 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i);
2621 context.SetRegisterToRegisterPlusOffset(*dwarf_reg, *sp_reg, addr - sp);
2622 // uint64_t to accommodate 64-bit registers.
2623 uint64_t reg_value = ReadRegisterUnsigned(*dwarf_reg, 0, &success);
2624 if (!success)
2625 return false;
2626 if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2627 return false;
2628 addr += reg_byte_size;
2629 }
2630
2632 context.SetImmediateSigned(-sp_offset);
2633
2635 LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2636 return false;
2637 }
2638 return true;
2639}
2640
2641// Vector Pop loads multiple extension registers from the stack. It also
2642// updates SP to point just above the loaded data.
2643bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2644 const ARMEncoding encoding) {
2645#if 0
2646 // ARM pseudo code...
2647 if (ConditionPassed())
2648 {
2649 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2650 address = SP;
2651 SP = SP + imm32;
2652 if single_regs then
2653 for r = 0 to regs-1
2654 S[d+r] = MemA[address,4]; address = address+4;
2655 else
2656 for r = 0 to regs-1
2657 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2658 // Combine the word-aligned words in the correct order for
2659 // current endianness.
2660 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2661 }
2662#endif
2663
2664 bool success = false;
2665 if (ConditionPassed(opcode)) {
2666 const uint32_t addr_byte_size = GetAddressByteSize();
2667 const addr_t sp = ReadCoreReg(SP_REG, &success);
2668 if (!success)
2669 return false;
2670 bool single_regs;
2671 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
2672 uint32_t imm32; // stack offset
2673 uint32_t regs; // number of registers
2674 switch (encoding) {
2675 case eEncodingT1:
2676 case eEncodingA1:
2677 single_regs = false;
2678 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2679 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2680 // If UInt(imm8) is odd, see "FLDMX".
2681 regs = Bits32(opcode, 7, 0) / 2;
2682 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2683 if (regs == 0 || regs > 16 || (d + regs) > 32)
2684 return false;
2685 break;
2686 case eEncodingT2:
2687 case eEncodingA2:
2688 single_regs = true;
2689 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2690 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2691 regs = Bits32(opcode, 7, 0);
2692 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2693 if (regs == 0 || regs > 16 || (d + regs) > 32)
2694 return false;
2695 break;
2696 default:
2697 return false;
2698 }
2699 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2700 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2701 addr_t sp_offset = imm32;
2702 addr_t addr = sp;
2703 uint32_t i;
2704 uint64_t data; // uint64_t to accommodate 64-bit registers.
2705
2708
2709 for (i = 0; i < regs; ++i) {
2710 std::optional<RegisterInfo> dwarf_reg =
2711 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i);
2712 context.SetAddress(addr);
2713 data = MemARead(context, addr, reg_byte_size, 0, &success);
2714 if (!success)
2715 return false;
2716 if (!WriteRegisterUnsigned(context, *dwarf_reg, data))
2717 return false;
2718 addr += reg_byte_size;
2719 }
2720
2722 context.SetImmediateSigned(sp_offset);
2723
2725 LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2726 return false;
2727 }
2728 return true;
2729}
2730
2731// SVC (previously SWI)
2732bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2733 const ARMEncoding encoding) {
2734#if 0
2735 // ARM pseudo code...
2736 if (ConditionPassed())
2737 {
2738 EncodingSpecificOperations();
2739 CallSupervisor();
2740 }
2741#endif
2742
2743 bool success = false;
2744
2745 if (ConditionPassed(opcode)) {
2746 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2747 addr_t lr; // next instruction address
2748 if (!success)
2749 return false;
2750 uint32_t imm32; // the immediate constant
2751 uint32_t mode; // ARM or Thumb mode
2752 switch (encoding) {
2753 case eEncodingT1:
2754 lr = (pc + 2) | 1u; // return address
2755 imm32 = Bits32(opcode, 7, 0);
2756 mode = eModeThumb;
2757 break;
2758 case eEncodingA1:
2759 lr = pc + 4; // return address
2760 imm32 = Bits32(opcode, 23, 0);
2761 mode = eModeARM;
2762 break;
2763 default:
2764 return false;
2765 }
2766
2769 context.SetISAAndImmediate(mode, imm32);
2772 return false;
2773 }
2774 return true;
2775}
2776
2777// If Then makes up to four following instructions (the IT block) conditional.
2778bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2779 const ARMEncoding encoding) {
2780#if 0
2781 // ARM pseudo code...
2782 EncodingSpecificOperations();
2783 ITSTATE.IT<7:0> = firstcond:mask;
2784#endif
2785
2786 m_it_session.InitIT(Bits32(opcode, 7, 0));
2787 return true;
2788}
2789
2790bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2791 const ARMEncoding encoding) {
2792 // NOP, nothing to do...
2793 return true;
2794}
2795
2796// Branch causes a branch to a target address.
2797bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2798 const ARMEncoding encoding) {
2799#if 0
2800 // ARM pseudo code...
2801 if (ConditionPassed())
2802 {
2803 EncodingSpecificOperations();
2804 BranchWritePC(PC + imm32);
2805 }
2806#endif
2807
2808 bool success = false;
2809
2810 if (ConditionPassed(opcode)) {
2813 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2814 if (!success)
2815 return false;
2816 addr_t target; // target address
2817 int32_t imm32; // PC-relative offset
2818 switch (encoding) {
2819 case eEncodingT1:
2820 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2821 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2822 target = pc + imm32;
2823 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2824 break;
2825 case eEncodingT2:
2826 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2827 target = pc + imm32;
2828 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2829 break;
2830 case eEncodingT3:
2831 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2832 {
2833 if (Bits32(opcode, 25, 23) == 7)
2834 return false; // See Branches and miscellaneous control on page
2835 // A6-235.
2836
2837 uint32_t S = Bit32(opcode, 26);
2838 uint32_t imm6 = Bits32(opcode, 21, 16);
2839 uint32_t J1 = Bit32(opcode, 13);
2840 uint32_t J2 = Bit32(opcode, 11);
2841 uint32_t imm11 = Bits32(opcode, 10, 0);
2842 uint32_t imm21 =
2843 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2844 imm32 = llvm::SignExtend32<21>(imm21);
2845 target = pc + imm32;
2846 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2847 break;
2848 }
2849 case eEncodingT4: {
2850 uint32_t S = Bit32(opcode, 26);
2851 uint32_t imm10 = Bits32(opcode, 25, 16);
2852 uint32_t J1 = Bit32(opcode, 13);
2853 uint32_t J2 = Bit32(opcode, 11);
2854 uint32_t imm11 = Bits32(opcode, 10, 0);
2855 uint32_t I1 = !(J1 ^ S);
2856 uint32_t I2 = !(J2 ^ S);
2857 uint32_t imm25 =
2858 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2859 imm32 = llvm::SignExtend32<25>(imm25);
2860 target = pc + imm32;
2861 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2862 break;
2863 }
2864 case eEncodingA1:
2865 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2866 target = pc + imm32;
2867 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2868 break;
2869 default:
2870 return false;
2871 }
2872 if (!BranchWritePC(context, target))
2873 return false;
2874 }
2875 return true;
2876}
2877
2878// Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2879// value in a register with zero and conditionally branch forward a constant
2880// value. They do not affect the condition flags. CBNZ, CBZ
2881bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2882 const ARMEncoding encoding) {
2883#if 0
2884 // ARM pseudo code...
2885 EncodingSpecificOperations();
2886 if nonzero ^ IsZero(R[n]) then
2887 BranchWritePC(PC + imm32);
2888#endif
2889
2890 bool success = false;
2891
2892 // Read the register value from the operand register Rn.
2893 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2894 if (!success)
2895 return false;
2896
2899 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2900 if (!success)
2901 return false;
2902
2903 addr_t target; // target address
2904 uint32_t imm32; // PC-relative offset to branch forward
2905 bool nonzero;
2906 switch (encoding) {
2907 case eEncodingT1:
2908 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2909 nonzero = BitIsSet(opcode, 11);
2910 target = pc + imm32;
2911 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2912 break;
2913 default:
2914 return false;
2915 }
2916 if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2917 if (!BranchWritePC(context, target))
2918 return false;
2919
2920 return true;
2921}
2922
2923// Table Branch Byte causes a PC-relative forward branch using a table of
2924// single byte offsets.
2925// A base register provides a pointer to the table, and a second register
2926// supplies an index into the table.
2927// The branch length is twice the value of the byte returned from the table.
2928//
2929// Table Branch Halfword causes a PC-relative forward branch using a table of
2930// single halfword offsets.
2931// A base register provides a pointer to the table, and a second register
2932// supplies an index into the table.
2933// The branch length is twice the value of the halfword returned from the
2934// table. TBB, TBH
2935bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2936 const ARMEncoding encoding) {
2937#if 0
2938 // ARM pseudo code...
2939 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2940 if is_tbh then
2941 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2942 else
2943 halfwords = UInt(MemU[R[n]+R[m], 1]);
2944 BranchWritePC(PC + 2*halfwords);
2945#endif
2946
2947 bool success = false;
2948
2949 if (ConditionPassed(opcode)) {
2950 uint32_t Rn; // the base register which contains the address of the table of
2951 // branch lengths
2952 uint32_t Rm; // the index register which contains an integer pointing to a
2953 // byte/halfword in the table
2954 bool is_tbh; // true if table branch halfword
2955 switch (encoding) {
2956 case eEncodingT1:
2957 Rn = Bits32(opcode, 19, 16);
2958 Rm = Bits32(opcode, 3, 0);
2959 is_tbh = BitIsSet(opcode, 4);
2960 if (Rn == 13 || BadReg(Rm))
2961 return false;
2962 if (InITBlock() && !LastInITBlock())
2963 return false;
2964 break;
2965 default:
2966 return false;
2967 }
2968
2969 // Read the address of the table from the operand register Rn. The PC can
2970 // be used, in which case the table immediately follows this instruction.
2971 uint32_t base = ReadCoreReg(Rn, &success);
2972 if (!success)
2973 return false;
2974
2975 // the table index
2976 uint32_t index = ReadCoreReg(Rm, &success);
2977 if (!success)
2978 return false;
2979
2980 // the offsetted table address
2981 addr_t addr = base + (is_tbh ? index * 2 : index);
2982
2983 // PC-relative offset to branch forward
2986 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2987 if (!success)
2988 return false;
2989
2990 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2991 if (!success)
2992 return false;
2993
2994 // target address
2995 addr_t target = pc + offset;
2997 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
2998
2999 if (!BranchWritePC(context, target))
3000 return false;
3001 }
3002
3003 return true;
3004}
3005
3006// This instruction adds an immediate value to a register value, and writes the
3007// result to the destination register. It can optionally update the condition
3008// flags based on the result.
3010 const ARMEncoding encoding) {
3011#if 0
3012 if ConditionPassed() then
3013 EncodingSpecificOperations();
3014 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3015 R[d] = result;
3016 if setflags then
3017 APSR.N = result<31>;
3018 APSR.Z = IsZeroBit(result);
3019 APSR.C = carry;
3020 APSR.V = overflow;
3021#endif
3022
3023 bool success = false;
3024
3025 if (ConditionPassed(opcode)) {
3026 uint32_t d;
3027 uint32_t n;
3028 bool setflags;
3029 uint32_t imm32;
3030 uint32_t carry_out;
3031
3032 // EncodingSpecificOperations();
3033 switch (encoding) {
3034 case eEncodingT1:
3035 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
3036 // ZeroExtend(imm3, 32);
3037 d = Bits32(opcode, 2, 0);
3038 n = Bits32(opcode, 5, 3);
3039 setflags = !InITBlock();
3040 imm32 = Bits32(opcode, 8, 6);
3041
3042 break;
3043
3044 case eEncodingT2:
3045 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
3046 // ZeroExtend(imm8, 32);
3047 d = Bits32(opcode, 10, 8);
3048 n = Bits32(opcode, 10, 8);
3049 setflags = !InITBlock();
3050 imm32 = Bits32(opcode, 7, 0);
3051
3052 break;
3053
3054 case eEncodingT3:
3055 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
3056 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
3057 // ThumbExpandImm(i:imm3:imm8);
3058 d = Bits32(opcode, 11, 8);
3059 n = Bits32(opcode, 19, 16);
3060 setflags = BitIsSet(opcode, 20);
3061 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
3062
3063 // if Rn == '1101' then SEE ADD (SP plus immediate);
3064 if (n == 13)
3065 return EmulateADDSPImm(opcode, eEncodingT3);
3066
3067 // if BadReg(d) || n == 15 then UNPREDICTABLE;
3068 if (BadReg(d) || (n == 15))
3069 return false;
3070
3071 break;
3072
3073 case eEncodingT4: {
3074 // if Rn == '1111' then SEE ADR;
3075 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
3076 // ZeroExtend(i:imm3:imm8, 32);
3077 d = Bits32(opcode, 11, 8);
3078 n = Bits32(opcode, 19, 16);
3079 setflags = false;
3080 uint32_t i = Bit32(opcode, 26);
3081 uint32_t imm3 = Bits32(opcode, 14, 12);
3082 uint32_t imm8 = Bits32(opcode, 7, 0);
3083 imm32 = (i << 11) | (imm3 << 8) | imm8;
3084
3085 // if Rn == '1101' then SEE ADD (SP plus immediate);
3086 if (n == 13)
3087 return EmulateADDSPImm(opcode, eEncodingT4);
3088
3089 // if BadReg(d) then UNPREDICTABLE;
3090 if (BadReg(d))
3091 return false;
3092
3093 break;
3094 }
3095
3096 default:
3097 return false;
3098 }
3099
3100 uint64_t Rn =
3102 if (!success)
3103 return false;
3104
3105 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3106 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
3107
3108 std::optional<RegisterInfo> reg_n =
3111 context.type = eContextArithmetic;
3112 context.SetRegisterPlusOffset(*reg_n, imm32);
3113
3114 // R[d] = result;
3115 // if setflags then
3116 // APSR.N = result<31>;
3117 // APSR.Z = IsZeroBit(result);
3118 // APSR.C = carry;
3119 // APSR.V = overflow;
3120 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
3121 res.carry_out, res.overflow))
3122 return false;
3123 }
3124 return true;
3125}
3126
3127// This instruction adds an immediate value to a register value, and writes the
3128// result to the destination register. It can optionally update the condition
3129// flags based on the result.
3131 const ARMEncoding encoding) {
3132#if 0
3133 // ARM pseudo code...
3134 if ConditionPassed() then
3135 EncodingSpecificOperations();
3136 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3137 if d == 15 then
3138 ALUWritePC(result); // setflags is always FALSE here
3139 else
3140 R[d] = result;
3141 if setflags then
3142 APSR.N = result<31>;
3143 APSR.Z = IsZeroBit(result);
3144 APSR.C = carry;
3145 APSR.V = overflow;
3146#endif
3147
3148 bool success = false;
3149
3150 if (ConditionPassed(opcode)) {
3151 uint32_t Rd, Rn;
3152 uint32_t
3153 imm32; // the immediate value to be added to the value obtained from Rn
3154 bool setflags;
3155 switch (encoding) {
3156 case eEncodingA1:
3157 Rd = Bits32(opcode, 15, 12);
3158 Rn = Bits32(opcode, 19, 16);
3159 setflags = BitIsSet(opcode, 20);
3160 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3161 break;
3162 default:
3163 return false;
3164 }
3165
3166 // Read the first operand.
3167 uint32_t val1 = ReadCoreReg(Rn, &success);
3168 if (!success)
3169 return false;
3170
3171 AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
3172
3174 if (Rd == 13)
3176 else if (Rd == GetFramePointerRegisterNumber())
3178 else
3180
3181 std::optional<RegisterInfo> dwarf_reg =
3183 context.SetRegisterPlusOffset(*dwarf_reg, imm32);
3184
3185 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3186 res.carry_out, res.overflow))
3187 return false;
3188 }
3189 return true;
3190}
3191
3192// This instruction adds a register value and an optionally-shifted register
3193// value, and writes the result to the destination register. It can optionally
3194// update the condition flags based on the result.
3195bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
3196 const ARMEncoding encoding) {
3197#if 0
3198 // ARM pseudo code...
3199 if ConditionPassed() then
3200 EncodingSpecificOperations();
3201 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3202 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3203 if d == 15 then
3204 ALUWritePC(result); // setflags is always FALSE here
3205 else
3206 R[d] = result;
3207 if setflags then
3208 APSR.N = result<31>;
3209 APSR.Z = IsZeroBit(result);
3210 APSR.C = carry;
3211 APSR.V = overflow;
3212#endif
3213
3214 bool success = false;
3215
3216 if (ConditionPassed(opcode)) {
3217 uint32_t Rd, Rn, Rm;
3218 ARM_ShifterType shift_t;
3219 uint32_t shift_n; // the shift applied to the value read from Rm
3220 bool setflags;
3221 switch (encoding) {
3222 case eEncodingT1:
3223 Rd = Bits32(opcode, 2, 0);
3224 Rn = Bits32(opcode, 5, 3);
3225 Rm = Bits32(opcode, 8, 6);
3226 setflags = !InITBlock();
3227 shift_t = SRType_LSL;
3228 shift_n = 0;
3229 break;
3230 case eEncodingT2:
3231 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3232 Rm = Bits32(opcode, 6, 3);
3233 setflags = false;
3234 shift_t = SRType_LSL;
3235 shift_n = 0;
3236 if (Rn == 15 && Rm == 15)
3237 return false;
3238 if (Rd == 15 && InITBlock() && !LastInITBlock())
3239 return false;
3240 break;
3241 case eEncodingA1:
3242 Rd = Bits32(opcode, 15, 12);
3243 Rn = Bits32(opcode, 19, 16);
3244 Rm = Bits32(opcode, 3, 0);
3245 setflags = BitIsSet(opcode, 20);
3246 shift_n = DecodeImmShiftARM(opcode, shift_t);
3247 break;
3248 default:
3249 return false;
3250 }
3251
3252 // Read the first operand.
3253 uint32_t val1 = ReadCoreReg(Rn, &success);
3254 if (!success)
3255 return false;
3256
3257 // Read the second operand.
3258 uint32_t val2 = ReadCoreReg(Rm, &success);
3259 if (!success)
3260 return false;
3261
3262 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3263 if (!success)
3264 return false;
3265 AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3266
3268 context.type = eContextArithmetic;
3269 std::optional<RegisterInfo> op1_reg =
3271 std::optional<RegisterInfo> op2_reg =
3273 context.SetRegisterRegisterOperands(*op1_reg, *op2_reg);
3274
3275 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3276 res.carry_out, res.overflow))
3277 return false;
3278 }
3279 return true;
3280}
3281
3282// Compare Negative (immediate) adds a register value and an immediate value.
3283// It updates the condition flags based on the result, and discards the result.
3284bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
3285 const ARMEncoding encoding) {
3286#if 0
3287 // ARM pseudo code...
3288 if ConditionPassed() then
3289 EncodingSpecificOperations();
3290 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3291 APSR.N = result<31>;
3292 APSR.Z = IsZeroBit(result);
3293 APSR.C = carry;
3294 APSR.V = overflow;
3295#endif
3296
3297 bool success = false;
3298
3299 uint32_t Rn; // the first operand
3300 uint32_t imm32; // the immediate value to be compared with
3301 switch (encoding) {
3302 case eEncodingT1:
3303 Rn = Bits32(opcode, 19, 16);
3304 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3305 if (Rn == 15)
3306 return false;
3307 break;
3308 case eEncodingA1:
3309 Rn = Bits32(opcode, 19, 16);
3310 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3311 break;
3312 default:
3313 return false;
3314 }
3315 // Read the register value from the operand register Rn.
3316 uint32_t reg_val = ReadCoreReg(Rn, &success);
3317 if (!success)
3318 return false;
3319
3320 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
3321
3324 context.SetNoArgs();
3325 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3326}
3327
3328// Compare Negative (register) adds a register value and an optionally-shifted
3329// register value. It updates the condition flags based on the result, and
3330// discards the result.
3331bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
3332 const ARMEncoding encoding) {
3333#if 0
3334 // ARM pseudo code...
3335 if ConditionPassed() then
3336 EncodingSpecificOperations();
3337 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3338 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3339 APSR.N = result<31>;
3340 APSR.Z = IsZeroBit(result);
3341 APSR.C = carry;
3342 APSR.V = overflow;
3343#endif
3344
3345 bool success = false;
3346
3347 uint32_t Rn; // the first operand
3348 uint32_t Rm; // the second operand
3349 ARM_ShifterType shift_t;
3350 uint32_t shift_n; // the shift applied to the value read from Rm
3351 switch (encoding) {
3352 case eEncodingT1:
3353 Rn = Bits32(opcode, 2, 0);
3354 Rm = Bits32(opcode, 5, 3);
3355 shift_t = SRType_LSL;
3356 shift_n = 0;
3357 break;
3358 case eEncodingT2:
3359 Rn = Bits32(opcode, 19, 16);
3360 Rm = Bits32(opcode, 3, 0);
3361 shift_n = DecodeImmShiftThumb(opcode, shift_t);
3362 // if n == 15 || BadReg(m) then UNPREDICTABLE;
3363 if (Rn == 15 || BadReg(Rm))
3364 return false;
3365 break;
3366 case eEncodingA1:
3367 Rn = Bits32(opcode, 19, 16);
3368 Rm = Bits32(opcode, 3, 0);
3369 shift_n = DecodeImmShiftARM(opcode, shift_t);
3370 break;
3371 default:
3372 return false;
3373 }
3374 // Read the register value from register Rn.
3375 uint32_t val1 = ReadCoreReg(Rn, &success);
3376 if (!success)
3377 return false;
3378
3379 // Read the register value from register Rm.
3380 uint32_t val2 = ReadCoreReg(Rm, &success);
3381 if (!success)
3382 return false;
3383
3384 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3385 if (!success)
3386 return false;
3387 AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3388
3391 context.SetNoArgs();
3392 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3393}
3394
3395// Compare (immediate) subtracts an immediate value from a register value. It
3396// updates the condition flags based on the result, and discards the result.
3397bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
3398 const ARMEncoding encoding) {
3399#if 0
3400 // ARM pseudo code...
3401 if ConditionPassed() then
3402 EncodingSpecificOperations();
3403 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
3404 APSR.N = result<31>;
3405 APSR.Z = IsZeroBit(result);
3406 APSR.C = carry;
3407 APSR.V = overflow;
3408#endif
3409
3410 bool success = false;
3411
3412 uint32_t Rn; // the first operand
3413 uint32_t imm32; // the immediate value to be compared with
3414 switch (encoding) {
3415 case eEncodingT1:
3416 Rn = Bits32(opcode, 10, 8);
3417 imm32 = Bits32(opcode, 7, 0);
3418 break;
3419 case eEncodingT2:
3420 Rn = Bits32(opcode, 19, 16);
3421 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3422 if (Rn == 15)
3423 return false;
3424 break;
3425 case eEncodingA1:
3426 Rn = Bits32(opcode, 19, 16);
3427 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3428 break;
3429 default:
3430 return false;
3431 }
3432 // Read the register value from the operand register Rn.
3433 uint32_t reg_val = ReadCoreReg(Rn, &success);
3434 if (!success)
3435 return false;
3436
3437 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
3438
3441 context.SetNoArgs();
3442 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3443}
3444
3445// Compare (register) subtracts an optionally-shifted register value from a
3446// register value. It updates the condition flags based on the result, and
3447// discards the result.
3448bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
3449 const ARMEncoding encoding) {
3450#if 0
3451 // ARM pseudo code...
3452 if ConditionPassed() then
3453 EncodingSpecificOperations();
3454 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3455 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
3456 APSR.N = result<31>;
3457 APSR.Z = IsZeroBit(result);
3458 APSR.C = carry;
3459 APSR.V = overflow;
3460#endif
3461
3462 bool success = false;
3463
3464 uint32_t Rn; // the first operand
3465 uint32_t Rm; // the second operand
3466 ARM_ShifterType shift_t;
3467 uint32_t shift_n; // the shift applied to the value read from Rm
3468 switch (encoding) {
3469 case eEncodingT1:
3470 Rn = Bits32(opcode, 2, 0);
3471 Rm = Bits32(opcode, 5, 3);
3472 shift_t = SRType_LSL;
3473 shift_n = 0;
3474 break;
3475 case eEncodingT2:
3476 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3477 Rm = Bits32(opcode, 6, 3);
3478 shift_t = SRType_LSL;
3479 shift_n = 0;
3480 if (Rn < 8 && Rm < 8)
3481 return false;
3482 if (Rn == 15 || Rm == 15)
3483 return false;
3484 break;
3485 case eEncodingT3:
3486 Rn = Bits32(opcode, 19, 16);
3487 Rm = Bits32(opcode, 3, 0);
3488 shift_n = DecodeImmShiftThumb(opcode, shift_t);
3489 if (Rn == 15 || BadReg(Rm))
3490 return false;
3491 break;
3492 case eEncodingA1:
3493 Rn = Bits32(opcode, 19, 16);
3494 Rm = Bits32(opcode, 3, 0);
3495 shift_n = DecodeImmShiftARM(opcode, shift_t);
3496 break;
3497 default:
3498 return false;
3499 }
3500 // Read the register value from register Rn.
3501 uint32_t val1 = ReadCoreReg(Rn, &success);
3502 if (!success)
3503 return false;
3504
3505 // Read the register value from register Rm.
3506 uint32_t val2 = ReadCoreReg(Rm, &success);
3507 if (!success)
3508 return false;
3509
3510 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3511 if (!success)
3512 return false;
3513 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3514
3517 context.SetNoArgs();
3518 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3519}
3520
3521// Arithmetic Shift Right (immediate) shifts a register value right by an
3522// immediate number of bits, shifting in copies of its sign bit, and writes the
3523// result to the destination register. It can optionally update the condition
3524// flags based on the result.
3525bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3526 const ARMEncoding encoding) {
3527#if 0
3528 // ARM pseudo code...
3529 if ConditionPassed() then
3530 EncodingSpecificOperations();
3531 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3532 if d == 15 then // Can only occur for ARM encoding
3533 ALUWritePC(result); // setflags is always FALSE here
3534 else
3535 R[d] = result;
3536 if setflags then
3537 APSR.N = result<31>;
3538 APSR.Z = IsZeroBit(result);
3539 APSR.C = carry;
3540 // APSR.V unchanged
3541#endif
3542
3543 return EmulateShiftImm(opcode, encoding, SRType_ASR);
3544}
3545
3546// Arithmetic Shift Right (register) shifts a register value right by a
3547// variable number of bits, shifting in copies of its sign bit, and writes the
3548// result to the destination register. The variable number of bits is read from
3549// the bottom byte of a register. It can optionally update the condition flags
3550// based on the result.
3551bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3552 const ARMEncoding encoding) {
3553#if 0
3554 // ARM pseudo code...
3555 if ConditionPassed() then
3556 EncodingSpecificOperations();
3557 shift_n = UInt(R[m]<7:0>);
3558 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3559 R[d] = result;
3560 if setflags then
3561 APSR.N = result<31>;
3562 APSR.Z = IsZeroBit(result);
3563 APSR.C = carry;
3564 // APSR.V unchanged
3565#endif
3566
3567 return EmulateShiftReg(opcode, encoding, SRType_ASR);
3568}
3569
3570// Logical Shift Left (immediate) shifts a register value left by an immediate
3571// number of bits, shifting in zeros, and writes the result to the destination
3572// register. It can optionally update the condition flags based on the result.
3573bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3574 const ARMEncoding encoding) {
3575#if 0
3576 // ARM pseudo code...
3577 if ConditionPassed() then
3578 EncodingSpecificOperations();
3579 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3580 if d == 15 then // Can only occur for ARM encoding
3581 ALUWritePC(result); // setflags is always FALSE here
3582 else
3583 R[d] = result;
3584 if setflags then
3585 APSR.N = result<31>;
3586 APSR.Z = IsZeroBit(result);
3587 APSR.C = carry;
3588 // APSR.V unchanged
3589#endif
3590
3591 return EmulateShiftImm(opcode, encoding, SRType_LSL);
3592}
3593
3594// Logical Shift Left (register) shifts a register value left by a variable
3595// number of bits, shifting in zeros, and writes the result to the destination
3596// register. The variable number of bits is read from the bottom byte of a
3597// register. It can optionally update the condition flags based on the result.
3598bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3599 const ARMEncoding encoding) {
3600#if 0
3601 // ARM pseudo code...
3602 if ConditionPassed() then
3603 EncodingSpecificOperations();
3604 shift_n = UInt(R[m]<7:0>);
3605 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3606 R[d] = result;
3607 if setflags then
3608 APSR.N = result<31>;
3609 APSR.Z = IsZeroBit(result);
3610 APSR.C = carry;
3611 // APSR.V unchanged
3612#endif
3613
3614 return EmulateShiftReg(opcode, encoding, SRType_LSL);
3615}
3616
3617// Logical Shift Right (immediate) shifts a register value right by an
3618// immediate number of bits, shifting in zeros, and writes the result to the
3619// destination register. It can optionally update the condition flags based on
3620// the result.
3621bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3622 const ARMEncoding encoding) {
3623#if 0
3624 // ARM pseudo code...
3625 if ConditionPassed() then
3626 EncodingSpecificOperations();
3627 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3628 if d == 15 then // Can only occur for ARM encoding
3629 ALUWritePC(result); // setflags is always FALSE here
3630 else
3631 R[d] = result;
3632 if setflags then
3633 APSR.N = result<31>;
3634 APSR.Z = IsZeroBit(result);
3635 APSR.C = carry;
3636 // APSR.V unchanged
3637#endif
3638
3639 return EmulateShiftImm(opcode, encoding, SRType_LSR);
3640}
3641
3642// Logical Shift Right (register) shifts a register value right by a variable
3643// number of bits, shifting in zeros, and writes the result to the destination
3644// register. The variable number of bits is read from the bottom byte of a
3645// register. It can optionally update the condition flags based on the result.
3646bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3647 const ARMEncoding encoding) {
3648#if 0
3649 // ARM pseudo code...
3650 if ConditionPassed() then
3651 EncodingSpecificOperations();
3652 shift_n = UInt(R[m]<7:0>);
3653 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3654 R[d] = result;
3655 if setflags then
3656 APSR.N = result<31>;
3657 APSR.Z = IsZeroBit(result);
3658 APSR.C = carry;
3659 // APSR.V unchanged
3660#endif
3661
3662 return EmulateShiftReg(opcode, encoding, SRType_LSR);
3663}
3664
3665// Rotate Right (immediate) provides the value of the contents of a register
3666// rotated by a constant value. The bits that are rotated off the right end are
3667// inserted into the vacated bit positions on the left. It can optionally
3668// update the condition flags based on the result.
3669bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3670 const ARMEncoding encoding) {
3671#if 0
3672 // ARM pseudo code...
3673 if ConditionPassed() then
3674 EncodingSpecificOperations();
3675 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3676 if d == 15 then // Can only occur for ARM encoding
3677 ALUWritePC(result); // setflags is always FALSE here
3678 else
3679 R[d] = result;
3680 if setflags then
3681 APSR.N = result<31>;
3682 APSR.Z = IsZeroBit(result);
3683 APSR.C = carry;
3684 // APSR.V unchanged
3685#endif
3686
3687 return EmulateShiftImm(opcode, encoding, SRType_ROR);
3688}
3689
3690// Rotate Right (register) provides the value of the contents of a register
3691// rotated by a variable number of bits. The bits that are rotated off the
3692// right end are inserted into the vacated bit positions on the left. The
3693// variable number of bits is read from the bottom byte of a register. It can
3694// optionally update the condition flags based on the result.
3695bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3696 const ARMEncoding encoding) {
3697#if 0
3698 // ARM pseudo code...
3699 if ConditionPassed() then
3700 EncodingSpecificOperations();
3701 shift_n = UInt(R[m]<7:0>);
3702 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3703 R[d] = result;
3704 if setflags then
3705 APSR.N = result<31>;
3706 APSR.Z = IsZeroBit(result);
3707 APSR.C = carry;
3708 // APSR.V unchanged
3709#endif
3710
3711 return EmulateShiftReg(opcode, encoding, SRType_ROR);
3712}
3713
3714// Rotate Right with Extend provides the value of the contents of a register
3715// shifted right by one place, with the carry flag shifted into bit [31].
3716//
3717// RRX can optionally update the condition flags based on the result.
3718// In that case, bit [0] is shifted into the carry flag.
3719bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3720 const ARMEncoding encoding) {
3721#if 0
3722 // ARM pseudo code...
3723 if ConditionPassed() then
3724 EncodingSpecificOperations();
3725 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3726 if d == 15 then // Can only occur for ARM encoding
3727 ALUWritePC(result); // setflags is always FALSE here
3728 else
3729 R[d] = result;
3730 if setflags then
3731 APSR.N = result<31>;
3732 APSR.Z = IsZeroBit(result);
3733 APSR.C = carry;
3734 // APSR.V unchanged
3735#endif
3736
3737 return EmulateShiftImm(opcode, encoding, SRType_RRX);
3738}
3739
3741 const ARMEncoding encoding,
3742 ARM_ShifterType shift_type) {
3743 // assert(shift_type == SRType_ASR
3744 // || shift_type == SRType_LSL
3745 // || shift_type == SRType_LSR
3746 // || shift_type == SRType_ROR
3747 // || shift_type == SRType_RRX);
3748
3749 bool success = false;
3750
3751 if (ConditionPassed(opcode)) {
3752 uint32_t Rd; // the destination register
3753 uint32_t Rm; // the first operand register
3754 uint32_t imm5; // encoding for the shift amount
3755 uint32_t carry; // the carry bit after the shift operation
3756 bool setflags;
3757
3758 // Special case handling!
3759 // A8.6.139 ROR (immediate) -- Encoding T1
3760 ARMEncoding use_encoding = encoding;
3761 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3762 // Morph the T1 encoding from the ARM Architecture Manual into T2
3763 // encoding to have the same decoding of bit fields as the other Thumb2
3764 // shift operations.
3765 use_encoding = eEncodingT2;
3766 }
3767
3768 switch (use_encoding) {
3769 case eEncodingT1:
3770 Rd = Bits32(opcode, 2, 0);
3771 Rm = Bits32(opcode, 5, 3);
3772 setflags = !InITBlock();
3773 imm5 = Bits32(opcode, 10, 6);
3774 break;
3775 case eEncodingT2:
3776 // A8.6.141 RRX
3777 // There's no imm form of RRX instructions.
3778 if (shift_type == SRType_RRX)
3779 return false;
3780
3781 Rd = Bits32(opcode, 11, 8);
3782 Rm = Bits32(opcode, 3, 0);
3783 setflags = BitIsSet(opcode, 20);
3784 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3785 if (BadReg(Rd) || BadReg(Rm))
3786 return false;
3787 break;
3788 case eEncodingA1:
3789 Rd = Bits32(opcode, 15, 12);
3790 Rm = Bits32(opcode, 3, 0);
3791 setflags = BitIsSet(opcode, 20);
3792 imm5 = Bits32(opcode, 11, 7);
3793 break;
3794 default:
3795 return false;
3796 }
3797
3798 // A8.6.139 ROR (immediate)
3799 if (shift_type == SRType_ROR && imm5 == 0)
3800 shift_type = SRType_RRX;
3801
3802 // Get the first operand.
3803 uint32_t value = ReadCoreReg(Rm, &success);
3804 if (!success)
3805 return false;
3806
3807 // Decode the shift amount if not RRX.
3808 uint32_t amt =
3809 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3810
3811 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3812 if (!success)
3813 return false;
3814
3815 // The context specifies that an immediate is to be moved into Rd.
3818 context.SetNoArgs();
3819
3820 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3821 return false;
3822 }
3823 return true;
3824}
3825
3827 const ARMEncoding encoding,
3828 ARM_ShifterType shift_type) {
3829 // assert(shift_type == SRType_ASR
3830 // || shift_type == SRType_LSL
3831 // || shift_type == SRType_LSR
3832 // || shift_type == SRType_ROR);
3833
3834 bool success = false;
3835
3836 if (ConditionPassed(opcode)) {
3837 uint32_t Rd; // the destination register
3838 uint32_t Rn; // the first operand register
3839 uint32_t
3840 Rm; // the register whose bottom byte contains the amount to shift by
3841 uint32_t carry; // the carry bit after the shift operation
3842 bool setflags;
3843 switch (encoding) {
3844 case eEncodingT1:
3845 Rd = Bits32(opcode, 2, 0);
3846 Rn = Rd;
3847 Rm = Bits32(opcode, 5, 3);
3848 setflags = !InITBlock();
3849 break;
3850 case eEncodingT2:
3851 Rd = Bits32(opcode, 11, 8);
3852 Rn = Bits32(opcode, 19, 16);
3853 Rm = Bits32(opcode, 3, 0);
3854 setflags = BitIsSet(opcode, 20);
3855 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3856 return false;
3857 break;
3858 case eEncodingA1:
3859 Rd = Bits32(opcode, 15, 12);
3860 Rn = Bits32(opcode, 3, 0);
3861 Rm = Bits32(opcode, 11, 8);
3862 setflags = BitIsSet(opcode, 20);
3863 if (Rd == 15 || Rn == 15 || Rm == 15)
3864 return false;
3865 break;
3866 default:
3867 return false;
3868 }
3869
3870 // Get the first operand.
3871 uint32_t value = ReadCoreReg(Rn, &success);
3872 if (!success)
3873 return false;
3874 // Get the Rm register content.
3875 uint32_t val = ReadCoreReg(Rm, &success);
3876 if (!success)
3877 return false;
3878
3879 // Get the shift amount.
3880 uint32_t amt = Bits32(val, 7, 0);
3881
3882 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3883 if (!success)
3884 return false;
3885
3886 // The context specifies that an immediate is to be moved into Rd.
3889 context.SetNoArgs();
3890
3891 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3892 return false;
3893 }
3894 return true;
3895}
3896
3897// LDM loads multiple registers from consecutive memory locations, using an
3898// address from a base register. Optionally the address just above the highest
3899// of those locations can be written back to the base register.
3900bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3901 const ARMEncoding encoding) {
3902#if 0
3903 // ARM pseudo code...
3904 if ConditionPassed()
3905 EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3906 address = R[n];
3907
3908 for i = 0 to 14
3909 if registers<i> == '1' then
3910 R[i] = MemA[address, 4]; address = address + 4;
3911 if registers<15> == '1' then
3912 LoadWritePC (MemA[address, 4]);
3913
3914 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3915 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3916
3917#endif
3918
3919 bool success = false;
3920 if (ConditionPassed(opcode)) {
3921 uint32_t n;
3922 uint32_t registers = 0;
3923 bool wback;
3924 const uint32_t addr_byte_size = GetAddressByteSize();
3925 switch (encoding) {
3926 case eEncodingT1:
3927 // n = UInt(Rn); registers = '00000000':register_list; wback =
3928 // (registers<n> == '0');
3929 n = Bits32(opcode, 10, 8);
3930 registers = Bits32(opcode, 7, 0);
3931 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3932 wback = BitIsClear(registers, n);
3933 // if BitCount(registers) < 1 then UNPREDICTABLE;
3934 if (BitCount(registers) < 1)
3935 return false;
3936 break;
3937 case eEncodingT2:
3938 // if W == '1' && Rn == '1101' then SEE POP;
3939 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3940 n = Bits32(opcode, 19, 16);
3941 registers = Bits32(opcode, 15, 0);
3942 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3943 wback = BitIsSet(opcode, 21);
3944
3945 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3946 // UNPREDICTABLE;
3947 if ((n == 15) || (BitCount(registers) < 2) ||
3948 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3949 return false;
3950
3951 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3952 // UNPREDICTABLE;
3953 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3954 return false;
3955
3956 // if wback && registers<n> == '1' then UNPREDICTABLE;
3957 if (wback && BitIsSet(registers, n))
3958 return false;
3959 break;
3960
3961 case eEncodingA1:
3962 n = Bits32(opcode, 19, 16);
3963 registers = Bits32(opcode, 15, 0);
3964 wback = BitIsSet(opcode, 21);
3965 if ((n == 15) || (BitCount(registers) < 1))
3966 return false;
3967 break;
3968 default:
3969 return false;
3970 }
3971
3972 int32_t offset = 0;
3973 const addr_t base_address =
3975 if (!success)
3976 return false;
3977
3980 std::optional<RegisterInfo> dwarf_reg =
3982 context.SetRegisterPlusOffset(*dwarf_reg, offset);
3983
3984 for (int i = 0; i < 14; ++i) {
3985 if (BitIsSet(registers, i)) {
3987 context.SetRegisterPlusOffset(*dwarf_reg, offset);
3988 if (wback && (n == 13)) // Pop Instruction
3989 {
3991 context.SetAddress(base_address + offset);
3992 }
3993
3994 // R[i] = MemA [address, 4]; address = address + 4;
3995 uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
3996 0, &success);
3997 if (!success)
3998 return false;
3999
4001 data))
4002 return false;
4003
4004 offset += addr_byte_size;
4005 }
4006 }
4007
4008 if (BitIsSet(registers, 15)) {
4009 // LoadWritePC (MemA [address, 4]);
4011 context.SetRegisterPlusOffset(*dwarf_reg, offset);
4012 uint32_t data =
4013 MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4014 if (!success)
4015 return false;
4016 // In ARMv5T and above, this is an interworking branch.
4017 if (!LoadWritePC(context, data))
4018 return false;
4019 }
4020
4021 if (wback && BitIsClear(registers, n)) {
4022 // R[n] = R[n] + 4 * BitCount (registers)
4023 int32_t offset = addr_byte_size * BitCount(registers);
4025 context.SetRegisterPlusOffset(*dwarf_reg, offset);
4026
4028 base_address + offset))
4029 return false;
4030 }
4031 if (wback && BitIsSet(registers, n))
4032 // R[n] bits(32) UNKNOWN;
4033 return WriteBits32Unknown(n);
4034 }
4035 return true;
4036}
4037
4038// LDMDA loads multiple registers from consecutive memory locations using an
4039// address from a base register.
4040// The consecutive memory locations end at this address and the address just
4041// below the lowest of those locations can optionally be written back to the
4042// base register.
4043bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
4044 const ARMEncoding encoding) {
4045#if 0
4046 // ARM pseudo code...
4047 if ConditionPassed() then
4048 EncodingSpecificOperations();
4049 address = R[n] - 4*BitCount(registers) + 4;
4050
4051 for i = 0 to 14
4052 if registers<i> == '1' then
4053 R[i] = MemA[address,4]; address = address + 4;
4054
4055 if registers<15> == '1' then
4056 LoadWritePC(MemA[address,4]);
4057
4058 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4059 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4060#endif
4061
4062 bool success = false;
4063
4064 if (ConditionPassed(opcode)) {
4065 uint32_t n;
4066 uint32_t registers = 0;
4067 bool wback;
4068 const uint32_t addr_byte_size = GetAddressByteSize();
4069
4070 // EncodingSpecificOperations();
4071 switch (encoding) {
4072 case eEncodingA1:
4073 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4074 n = Bits32(opcode, 19, 16);
4075 registers = Bits32(opcode, 15, 0);
4076 wback = BitIsSet(opcode, 21);
4077
4078 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4079 if ((n == 15) || (BitCount(registers) < 1))
4080 return false;
4081
4082 break;
4083
4084 default:
4085 return false;
4086 }
4087 // address = R[n] - 4*BitCount(registers) + 4;
4088
4089 int32_t offset = 0;
4090 addr_t Rn = ReadCoreReg(n, &success);
4091
4092 if (!success)
4093 return false;
4094
4095 addr_t address =
4096 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
4097
4100 std::optional<RegisterInfo> dwarf_reg =
4102 context.SetRegisterPlusOffset(*dwarf_reg, offset);
4103
4104 // for i = 0 to 14
4105 for (int i = 0; i < 14; ++i) {
4106 // if registers<i> == '1' then
4107 if (BitIsSet(registers, i)) {
4108 // R[i] = MemA[address,4]; address = address + 4;
4109 context.SetRegisterPlusOffset(*dwarf_reg, Rn - (address + offset));
4110 uint32_t data =
4111 MemARead(context, address + offset, addr_byte_size, 0, &success);
4112 if (!success)
4113 return false;
4115 data))
4116 return false;
4117 offset += addr_byte_size;
4118 }
4119 }
4120
4121 // if registers<15> == '1' then
4122 // LoadWritePC(MemA[address,4]);
4123 if (BitIsSet(registers, 15)) {
4124 context.SetRegisterPlusOffset(*dwarf_reg, offset);
4125 uint32_t data =
4126 MemARead(context, address + offset, addr_byte_size, 0, &success);
4127 if (!success)
4128 return false;
4129 // In ARMv5T and above, this is an interworking branch.
4130 if (!LoadWritePC(context, data))
4131 return false;
4132 }
4133
4134 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4135 if (wback && BitIsClear(registers, n)) {
4136
4137 offset = (addr_byte_size * BitCount(registers)) * -1;
4139 context.SetImmediateSigned(offset);
4140 addr_t addr = Rn + offset;
4142 addr))
4143 return false;
4144 }
4145
4146 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4147 if (wback && BitIsSet(registers, n))
4148 return WriteBits32Unknown(n);
4149 }
4150 return true;
4151}
4152
4153// LDMDB loads multiple registers from consecutive memory locations using an
4154// address from a base register. The
4155// consecutive memory locations end just below this address, and the address of
4156// the lowest of those locations can be optionally written back to the base
4157// register.
4158bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
4159 const ARMEncoding encoding) {
4160#if 0
4161 // ARM pseudo code...
4162 if ConditionPassed() then
4163 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4164 address = R[n] - 4*BitCount(registers);
4165
4166 for i = 0 to 14
4167 if registers<i> == '1' then
4168 R[i] = MemA[address,4]; address = address + 4;
4169 if registers<15> == '1' then
4170 LoadWritePC(MemA[address,4]);
4171
4172 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4173 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
4174#endif
4175
4176 bool success = false;
4177
4178 if (ConditionPassed(opcode)) {
4179 uint32_t n;
4180 uint32_t registers = 0;
4181 bool wback;
4182 const uint32_t addr_byte_size = GetAddressByteSize();
4183 switch (encoding) {
4184 case eEncodingT1:
4185 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
4186 n = Bits32(opcode, 19, 16);
4187 registers = Bits32(opcode, 15, 0);
4188 registers = registers & 0xdfff; // Make sure bit 13 is a zero.
4189 wback = BitIsSet(opcode, 21);
4190
4191 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4192 // UNPREDICTABLE;
4193 if ((n == 15) || (BitCount(registers) < 2) ||
4194 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4195 return false;
4196
4197 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4198 // UNPREDICTABLE;
4199 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4200 return false;
4201
4202 // if wback && registers<n> == '1' then UNPREDICTABLE;
4203 if (wback && BitIsSet(registers, n))
4204 return false;
4205
4206 break;
4207
4208 case eEncodingA1:
4209 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4210 n = Bits32(opcode, 19, 16);
4211 registers = Bits32(opcode, 15, 0);
4212 wback = BitIsSet(opcode, 21);
4213
4214 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4215 if ((n == 15) || (BitCount(registers) < 1))
4216 return false;
4217
4218 break;
4219
4220 default:
4221 return false;
4222 }
4223
4224 // address = R[n] - 4*BitCount(registers);
4225
4226 int32_t offset = 0;
4227 addr_t Rn =
4229
4230 if (!success)
4231 return false;
4232
4233 addr_t address = Rn - (addr_byte_size * BitCount(registers));
4236 std::optional<RegisterInfo> dwarf_reg =
4238 context.SetRegisterPlusOffset(*dwarf_reg, Rn - address);
4239
4240 for (int i = 0; i < 14; ++i) {
4241 if (BitIsSet(registers, i)) {
4242 // R[i] = MemA[address,4]; address = address + 4;
4243 context.SetRegisterPlusOffset(*dwarf_reg, Rn - (address + offset));
4244 uint32_t data =
4245 MemARead(context, address + offset, addr_byte_size, 0, &success);
4246 if (!success)
4247 return false;
4248
4250 data))
4251 return false;
4252
4253 offset += addr_byte_size;
4254 }
4255 }
4256
4257 // if registers<15> == '1' then
4258 // LoadWritePC(MemA[address,4]);
4259 if (BitIsSet(registers, 15)) {
4260 context.SetRegisterPlusOffset(*dwarf_reg, offset);
4261 uint32_t data =
4262 MemARead(context, address + offset, addr_byte_size, 0, &success);
4263 if (!success)
4264 return false;
4265 // In ARMv5T and above, this is an interworking branch.
4266 if (!LoadWritePC(context, data))
4267 return false;
4268 }
4269
4270 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4271 if (wback && BitIsClear(registers, n)) {
4272
4273 offset = (addr_byte_size * BitCount(registers)) * -1;
4275 context.SetImmediateSigned(offset);
4276 addr_t addr = Rn + offset;
4278 addr))
4279 return false;
4280 }
4281
4282 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4283 // possible for encoding A1
4284 if (wback && BitIsSet(registers, n))
4285 return WriteBits32Unknown(n);
4286 }
4287 return true;
4288}
4289
4290// LDMIB loads multiple registers from consecutive memory locations using an
4291// address from a base register. The
4292// consecutive memory locations start just above this address, and thea ddress
4293// of the last of those locations can optinoally be written back to the base
4294// register.
4295bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
4296 const ARMEncoding encoding) {
4297#if 0
4298 if ConditionPassed() then
4299 EncodingSpecificOperations();
4300 address = R[n] + 4;
4301
4302 for i = 0 to 14
4303 if registers<i> == '1' then
4304 R[i] = MemA[address,4]; address = address + 4;
4305 if registers<15> == '1' then
4306 LoadWritePC(MemA[address,4]);
4307
4308 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4309 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4310#endif
4311
4312 bool success = false;
4313
4314 if (ConditionPassed(opcode)) {
4315 uint32_t n;
4316 uint32_t registers = 0;
4317 bool wback;
4318 const uint32_t addr_byte_size = GetAddressByteSize();
4319 switch (encoding) {
4320 case eEncodingA1:
4321 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4322 n = Bits32(opcode, 19, 16);
4323 registers = Bits32(opcode, 15, 0);
4324 wback = BitIsSet(opcode, 21);
4325
4326 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4327 if ((n == 15) || (BitCount(registers) < 1))
4328 return false;
4329
4330 break;
4331 default:
4332 return false;
4333 }
4334 // address = R[n] + 4;
4335
4336 int32_t offset = 0;
4337 addr_t Rn =
4339
4340 if (!success)
4341 return false;
4342
4343 addr_t address = Rn + addr_byte_size;
4344
4347 std::optional<RegisterInfo> dwarf_reg =
4349 context.SetRegisterPlusOffset(*dwarf_reg, offset);
4350
4351 for (int i = 0; i < 14; ++i) {
4352 if (BitIsSet(registers, i)) {
4353 // R[i] = MemA[address,4]; address = address + 4;
4354
4355 context.SetRegisterPlusOffset(*dwarf_reg, offset + addr_byte_size);
4356 uint32_t data =
4357 MemARead(context, address + offset, addr_byte_size, 0, &success);
4358 if (!success)
4359 return false;
4360
4362 data))
4363 return false;
4364
4365 offset += addr_byte_size;
4366 }
4367 }
4368
4369 // if registers<15> == '1' then
4370 // LoadWritePC(MemA[address,4]);
4371 if (BitIsSet(registers, 15)) {
4372 context.SetRegisterPlusOffset(*dwarf_reg, offset);
4373 uint32_t data =
4374 MemARead(context, address + offset, addr_byte_size, 0, &success);
4375 if (!success)
4376 return false;
4377 // In ARMv5T and above, this is an interworking branch.
4378 if (!LoadWritePC(context, data))
4379 return false;
4380 }
4381
4382 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4383 if (wback && BitIsClear(registers, n)) {
4384
4385 offset = addr_byte_size * BitCount(registers);
4387 context.SetImmediateSigned(offset);
4388 addr_t addr = Rn + offset;
4390 addr))
4391 return false;
4392 }
4393
4394 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4395 // possible for encoding A1
4396 if (wback && BitIsSet(registers, n))
4397 return WriteBits32Unknown(n);
4398 }
4399 return true;
4400}
4401
4402// Load Register (immediate) calculates an address from a base register value
4403// and an immediate offset, loads a word from memory, and writes to a register.
4404// LDR (immediate, Thumb)
4406 const ARMEncoding encoding) {
4407#if 0
4408 // ARM pseudo code...
4409 if (ConditionPassed())
4410 {
4411 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4412 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4413 address = if index then offset_addr else R[n];
4414 data = MemU[address,4];
4415 if wback then R[n] = offset_addr;
4416 if t == 15 then
4417 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
4418 elsif UnalignedSupport() || address<1:0> = '00' then
4419 R[t] = data;
4420 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
4421 }
4422#endif
4423
4424 bool success = false;
4425
4426 if (ConditionPassed(opcode)) {
4427 uint32_t Rt; // the destination register
4428 uint32_t Rn; // the base register
4429 uint32_t imm32; // the immediate offset used to form the address
4430 addr_t offset_addr; // the offset address
4431 addr_t address; // the calculated address
4432 uint32_t data; // the literal data value from memory load
4433 bool add, index, wback;
4434 switch (encoding) {
4435 case eEncodingT1:
4436 Rt = Bits32(opcode, 2, 0);
4437 Rn = Bits32(opcode, 5, 3);
4438 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
4439 // index = TRUE; add = TRUE; wback = FALSE
4440 add = true;
4441 index = true;
4442 wback = false;
4443
4444 break;
4445
4446 case eEncodingT2:
4447 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4448 Rt = Bits32(opcode, 10, 8);
4449 Rn = 13;
4450 imm32 = Bits32(opcode, 7, 0) << 2;
4451
4452 // index = TRUE; add = TRUE; wback = FALSE;
4453 index = true;
4454 add = true;
4455 wback = false;
4456
4457 break;
4458
4459 case eEncodingT3:
4460 // if Rn == '1111' then SEE LDR (literal);
4461 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4462 Rt = Bits32(opcode, 15, 12);
4463 Rn = Bits32(opcode, 19, 16);
4464 imm32 = Bits32(opcode, 11, 0);
4465
4466 // index = TRUE; add = TRUE; wback = FALSE;
4467 index = true;
4468 add = true;
4469 wback = false;
4470
4471 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4472 if ((Rt == 15) && InITBlock() && !LastInITBlock())
4473 return false;
4474
4475 break;
4476
4477 case eEncodingT4:
4478 // if Rn == '1111' then SEE LDR (literal);
4479 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4480 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
4481 // '00000100' then SEE POP;
4482 // if P == '0' && W == '0' then UNDEFINED;
4483 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
4484 return false;
4485
4486 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4487 Rt = Bits32(opcode, 15, 12);
4488 Rn = Bits32(opcode, 19, 16);
4489 imm32 = Bits32(opcode, 7, 0);
4490
4491 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4492 index = BitIsSet(opcode, 10);
4493 add = BitIsSet(opcode, 9);
4494 wback = BitIsSet(opcode, 8);
4495
4496 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4497 // then UNPREDICTABLE;
4498 if ((wback && (Rn == Rt)) ||
4499 ((Rt == 15) && InITBlock() && !LastInITBlock()))
4500 return false;
4501
4502 break;
4503
4504 default:
4505 return false;
4506 }
4507 uint32_t base = ReadCoreReg(Rn, &success);
4508 if (!success)
4509 return false;
4510 if (add)
4511 offset_addr = base + imm32;
4512 else
4513 offset_addr = base - imm32;
4514
4515 address = (index ? offset_addr : base);
4516
4517 std::optional<RegisterInfo> base_reg =
4519 if (wback) {
4521 if (Rn == 13) {
4523 ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4524 } else if (Rn == GetFramePointerRegisterNumber()) {
4526 ctx.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4527 } else {
4529 ctx.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4530 }
4531
4533 offset_addr))
4534 return false;
4535 }
4536
4537 // Prepare to write to the Rt register.
4540 context.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4541
4542 // Read memory from the address.
4543 data = MemURead(context, address, 4, 0, &success);
4544 if (!success)
4545 return false;
4546
4547 if (Rt == 15) {
4548 if (Bits32(address, 1, 0) == 0) {
4549 if (!LoadWritePC(context, data))
4550 return false;
4551 } else
4552 return false;
4553 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4555 data))
4556 return false;
4557 } else
4559 }
4560 return true;
4561}
4562
4563// STM (Store Multiple Increment After) stores multiple registers to consecutive
4564// memory locations using an address
4565// from a base register. The consecutive memory locations start at this
4566// address, and the address just above the last of those locations can
4567// optionally be written back to the base register.
4568bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4569 const ARMEncoding encoding) {
4570#if 0
4571 if ConditionPassed() then
4572 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4573 address = R[n];
4574
4575 for i = 0 to 14
4576 if registers<i> == '1' then
4577 if i == n && wback && i != LowestSetBit(registers) then
4578 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4579 else
4580 MemA[address,4] = R[i];
4581 address = address + 4;
4582
4583 if registers<15> == '1' then // Only possible for encoding A1
4584 MemA[address,4] = PCStoreValue();
4585 if wback then R[n] = R[n] + 4*BitCount(registers);
4586#endif
4587
4588 bool success = false;
4589
4590 if (ConditionPassed(opcode)) {
4591 uint32_t n;
4592 uint32_t registers = 0;
4593 bool wback;
4594 const uint32_t addr_byte_size = GetAddressByteSize();
4595
4596 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4597 switch (encoding) {
4598 case eEncodingT1:
4599 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4600 n = Bits32(opcode, 10, 8);
4601 registers = Bits32(opcode, 7, 0);
4602 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4603 wback = true;
4604
4605 // if BitCount(registers) < 1 then UNPREDICTABLE;
4606 if (BitCount(registers) < 1)
4607 return false;
4608
4609 break;
4610
4611 case eEncodingT2:
4612 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4613 n = Bits32(opcode, 19, 16);
4614 registers = Bits32(opcode, 15, 0);
4615 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4616 wback = BitIsSet(opcode, 21);
4617
4618 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4619 if ((n == 15) || (BitCount(registers) < 2))
4620 return false;
4621
4622 // if wback && registers<n> == '1' then UNPREDICTABLE;
4623 if (wback && BitIsSet(registers, n))
4624 return false;
4625
4626 break;
4627
4628 case eEncodingA1:
4629 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4630 n = Bits32(opcode, 19, 16);
4631 registers = Bits32(opcode, 15, 0);
4632 wback = BitIsSet(opcode, 21);
4633
4634 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4635 if ((n == 15) || (BitCount(registers) < 1))
4636 return false;
4637
4638 break;
4639
4640 default:
4641 return false;
4642 }
4643
4644 // address = R[n];
4645 int32_t offset = 0;
4646 const addr_t address =
4648 if (!success)
4649 return false;
4650
4653 std::optional<RegisterInfo> base_reg =
4655
4656 // for i = 0 to 14
4657 uint32_t lowest_set_bit = 14;
4658 for (uint32_t i = 0; i < 14; ++i) {
4659 // if registers<i> == '1' then
4660 if (BitIsSet(registers, i)) {
4661 if (i < lowest_set_bit)
4662 lowest_set_bit = i;
4663 // if i == n && wback && i != LowestSetBit(registers) then
4664 if ((i == n) && wback && (i != lowest_set_bit))
4665 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4666 // T1 and A1
4667 WriteBits32UnknownToMemory(address + offset);
4668 else {
4669 // MemA[address,4] = R[i];
4671 0, &success);
4672 if (!success)
4673 return false;
4674
4675 std::optional<RegisterInfo> data_reg =
4677 context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, offset);
4678 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4679 return false;
4680 }
4681
4682 // address = address + 4;
4683 offset += addr_byte_size;
4684 }
4685 }
4686
4687 // if registers<15> == '1' then // Only possible for encoding A1
4688 // MemA[address,4] = PCStoreValue();
4689 if (BitIsSet(registers, 15)) {
4690 std::optional<RegisterInfo> pc_reg =
4692 context.SetRegisterPlusOffset(*pc_reg, 8);
4693 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4694 if (!success)
4695 return false;
4696
4697 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4698 return false;
4699 }
4700
4701 // if wback then R[n] = R[n] + 4*BitCount(registers);
4702 if (wback) {
4703 offset = addr_byte_size * BitCount(registers);
4705 context.SetImmediateSigned(offset);
4706 addr_t data = address + offset;
4708 data))
4709 return false;
4710 }
4711 }
4712 return true;
4713}
4714
4715// STMDA (Store Multiple Decrement After) stores multiple registers to
4716// consecutive memory locations using an address from a base register. The
4717// consecutive memory locations end at this address, and the address just below
4718// the lowest of those locations can optionally be written back to the base
4719// register.
4720bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4721 const ARMEncoding encoding) {
4722#if 0
4723 if ConditionPassed() then
4724 EncodingSpecificOperations();
4725 address = R[n] - 4*BitCount(registers) + 4;
4726
4727 for i = 0 to 14
4728 if registers<i> == '1' then
4729 if i == n && wback && i != LowestSetBit(registers) then
4730 MemA[address,4] = bits(32) UNKNOWN;
4731 else
4732 MemA[address,4] = R[i];
4733 address = address + 4;
4734
4735 if registers<15> == '1' then
4736 MemA[address,4] = PCStoreValue();
4737
4738 if wback then R[n] = R[n] - 4*BitCount(registers);
4739#endif
4740
4741 bool success = false;
4742
4743 if (ConditionPassed(opcode)) {
4744 uint32_t n;
4745 uint32_t registers = 0;
4746 bool wback;
4747 const uint32_t addr_byte_size = GetAddressByteSize();
4748
4749 // EncodingSpecificOperations();
4750 switch (encoding) {
4751 case eEncodingA1:
4752 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4753 n = Bits32(opcode, 19, 16);
4754 registers = Bits32(opcode, 15, 0);
4755 wback = BitIsSet(opcode, 21);
4756
4757 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4758 if ((n == 15) || (BitCount(registers) < 1))
4759 return false;
4760 break;
4761 default:
4762 return false;
4763 }
4764
4765 // address = R[n] - 4*BitCount(registers) + 4;
4766 int32_t offset = 0;
4767 addr_t Rn = ReadCoreReg(n, &success);
4768 if (!success)
4769 return false;
4770
4771 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4772
4775 std::optional<RegisterInfo> base_reg =
4777
4778 // for i = 0 to 14
4779 uint32_t lowest_bit_set = 14;
4780 for (uint32_t i = 0; i < 14; ++i) {
4781 // if registers<i> == '1' then
4782 if (BitIsSet(registers, i)) {
4783 if (i < lowest_bit_set)
4784 lowest_bit_set = i;
4785 // if i == n && wback && i != LowestSetBit(registers) then
4786 if ((i == n) && wback && (i != lowest_bit_set))
4787 // MemA[address,4] = bits(32) UNKNOWN;
4788 WriteBits32UnknownToMemory(address + offset);
4789 else {
4790 // MemA[address,4] = R[i];
4792 0, &success);
4793 if (!success)
4794 return false;
4795
4796 std::optional<RegisterInfo> data_reg =
4798 context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
4799 Rn - (address + offset));
4800 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4801 return false;
4802 }
4803
4804 // address = address + 4;
4805 offset += addr_byte_size;
4806 }
4807 }
4808
4809 // if registers<15> == '1' then
4810 // MemA[address,4] = PCStoreValue();
4811 if (BitIsSet(registers, 15)) {
4812 std::optional<RegisterInfo> pc_reg =
4814 context.SetRegisterPlusOffset(*pc_reg, 8);
4815 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4816 if (!success)
4817 return false;
4818
4819 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4820 return false;
4821 }
4822
4823 // if wback then R[n] = R[n] - 4*BitCount(registers);
4824 if (wback) {
4825 offset = (addr_byte_size * BitCount(registers)) * -1;
4827 context.SetImmediateSigned(offset);
4828 addr_t data = Rn + offset;
4830 data))
4831 return false;
4832 }
4833 }
4834 return true;
4835}
4836
4837// STMDB (Store Multiple Decrement Before) stores multiple registers to
4838// consecutive memory locations using an address from a base register. The
4839// consecutive memory locations end just below this address, and the address of
4840// the first of those locations can optionally be written back to the base
4841// register.
4842bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4843 const ARMEncoding encoding) {
4844#if 0
4845 if ConditionPassed() then
4846 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4847 address = R[n] - 4*BitCount(registers);
4848
4849 for i = 0 to 14
4850 if registers<i> == '1' then
4851 if i == n && wback && i != LowestSetBit(registers) then
4852 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4853 else
4854 MemA[address,4] = R[i];
4855 address = address + 4;
4856
4857 if registers<15> == '1' then // Only possible for encoding A1
4858 MemA[address,4] = PCStoreValue();
4859
4860 if wback then R[n] = R[n] - 4*BitCount(registers);
4861#endif
4862
4863 bool success = false;
4864
4865 if (ConditionPassed(opcode)) {
4866 uint32_t n;
4867 uint32_t registers = 0;
4868 bool wback;
4869 const uint32_t addr_byte_size = GetAddressByteSize();
4870
4871 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4872 switch (encoding) {
4873 case eEncodingT1:
4874 // if W == '1' && Rn == '1101' then SEE PUSH;
4875 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4876 // See PUSH
4877 }
4878 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4879 n = Bits32(opcode, 19, 16);
4880 registers = Bits32(opcode, 15, 0);
4881 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4882 wback = BitIsSet(opcode, 21);
4883 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4884 if ((n == 15) || BitCount(registers) < 2)
4885 return false;
4886 // if wback && registers<n> == '1' then UNPREDICTABLE;
4887 if (wback && BitIsSet(registers, n))
4888 return false;
4889 break;
4890
4891 case eEncodingA1:
4892 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4893 // PUSH;
4894 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4895 BitCount(Bits32(opcode, 15, 0)) >= 2) {
4896 // See Push
4897 }
4898 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4899 n = Bits32(opcode, 19, 16);
4900 registers = Bits32(opcode, 15, 0);
4901 wback = BitIsSet(opcode, 21);
4902 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4903 if ((n == 15) || BitCount(registers) < 1)
4904 return false;
4905 break;
4906
4907 default:
4908 return false;
4909 }
4910
4911 // address = R[n] - 4*BitCount(registers);
4912
4913 int32_t offset = 0;
4914 addr_t Rn =
4916 if (!success)
4917 return false;
4918
4919 addr_t address = Rn - (addr_byte_size * BitCount(registers));
4920
4923 std::optional<RegisterInfo> base_reg =
4925
4926 // for i = 0 to 14
4927 uint32_t lowest_set_bit = 14;
4928 for (uint32_t i = 0; i < 14; ++i) {
4929 // if registers<i> == '1' then
4930 if (BitIsSet(registers, i)) {
4931 if (i < lowest_set_bit)
4932 lowest_set_bit = i;
4933 // if i == n && wback && i != LowestSetBit(registers) then
4934 if ((i == n) && wback && (i != lowest_set_bit))
4935 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4936 // A1
4937 WriteBits32UnknownToMemory(address + offset);
4938 else {
4939 // MemA[address,4] = R[i];
4941 0, &success);
4942 if (!success)
4943 return false;
4944
4945 std::optional<RegisterInfo> data_reg =
4947 context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
4948 Rn - (address + offset));
4949 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4950 return false;
4951 }
4952
4953 // address = address + 4;
4954 offset += addr_byte_size;
4955 }
4956 }
4957
4958 // if registers<15> == '1' then // Only possible for encoding A1
4959 // MemA[address,4] = PCStoreValue();
4960 if (BitIsSet(registers, 15)) {
4961 std::optional<RegisterInfo> pc_reg =
4963 context.SetRegisterPlusOffset(*pc_reg, 8);
4964 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4965 if (!success)
4966 return false;
4967
4968 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4969 return false;
4970 }
4971
4972 // if wback then R[n] = R[n] - 4*BitCount(registers);
4973 if (wback) {
4974 offset = (addr_byte_size * BitCount(registers)) * -1;
4976 context.SetImmediateSigned(offset);
4977 addr_t data = Rn + offset;
4979 data))
4980 return false;
4981 }
4982 }
4983 return true;
4984}
4985
4986// STMIB (Store Multiple Increment Before) stores multiple registers to
4987// consecutive memory locations using an address from a base register. The
4988// consecutive memory locations start just above this address, and the address
4989// of the last of those locations can optionally be written back to the base
4990// register.
4991bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
4992 const ARMEncoding encoding) {
4993#if 0
4994 if ConditionPassed() then
4995 EncodingSpecificOperations();
4996 address = R[n] + 4;
4997
4998 for i = 0 to 14
4999 if registers<i> == '1' then
5000 if i == n && wback && i != LowestSetBit(registers) then
5001 MemA[address,4] = bits(32) UNKNOWN;
5002 else
5003 MemA[address,4] = R[i];
5004 address = address + 4;
5005
5006 if registers<15> == '1' then
5007 MemA[address,4] = PCStoreValue();
5008
5009 if wback then R[n] = R[n] + 4*BitCount(registers);
5010#endif
5011
5012 bool success = false;
5013
5014 if (ConditionPassed(opcode)) {
5015 uint32_t n;
5016 uint32_t registers = 0;
5017 bool wback;
5018 const uint32_t addr_byte_size = GetAddressByteSize();
5019
5020 // EncodingSpecificOperations();
5021 switch (encoding) {
5022 case eEncodingA1:
5023 // n = UInt(Rn); registers = register_list; wback = (W == '1');
5024 n = Bits32(opcode, 19, 16);
5025 registers = Bits32(opcode, 15, 0);
5026 wback = BitIsSet(opcode, 21);
5027
5028 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
5029 if ((n == 15) && (BitCount(registers) < 1))
5030 return false;
5031 break;
5032 default:
5033 return false;
5034 }
5035 // address = R[n] + 4;
5036
5037 int32_t offset = 0;
5038 addr_t Rn = ReadCoreReg(n, &success);
5039 if (!success)
5040 return false;
5041
5042 addr_t address = Rn + addr_byte_size;
5043
5046 std::optional<RegisterInfo> base_reg =
5048
5049 uint32_t lowest_set_bit = 14;
5050 // for i = 0 to 14
5051 for (uint32_t i = 0; i < 14; ++i) {
5052 // if registers<i> == '1' then
5053 if (BitIsSet(registers, i)) {
5054 if (i < lowest_set_bit)
5055 lowest_set_bit = i;
5056 // if i == n && wback && i != LowestSetBit(registers) then
5057 if ((i == n) && wback && (i != lowest_set_bit))
5058 // MemA[address,4] = bits(32) UNKNOWN;
5059 WriteBits32UnknownToMemory(address + offset);
5060 // else
5061 else {
5062 // MemA[address,4] = R[i];
5064 0, &success);
5065 if (!success)
5066 return false;
5067
5068 std::optional<RegisterInfo> data_reg =
5070 context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
5071 offset + addr_byte_size);
5072 if (!MemAWrite(context, address + offset, data, addr_byte_size))
5073 return false;
5074 }
5075
5076 // address = address + 4;
5077 offset += addr_byte_size;
5078 }
5079 }
5080
5081 // if registers<15> == '1' then
5082 // MemA[address,4] = PCStoreValue();
5083 if (BitIsSet(registers, 15)) {
5084 std::optional<RegisterInfo> pc_reg =
5086 context.SetRegisterPlusOffset(*pc_reg, 8);
5087 const uint32_t pc = ReadCoreReg(PC_REG, &success);
5088 if (!success)
5089 return false;
5090
5091 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5092 return false;
5093 }
5094
5095 // if wback then R[n] = R[n] + 4*BitCount(registers);
5096 if (wback) {
5097 offset = addr_byte_size * BitCount(registers);
5099 context.SetImmediateSigned(offset);
5100 addr_t data = Rn + offset;
5102 data))
5103 return false;
5104 }
5105 }
5106 return true;
5107}
5108
5109// STR (store immediate) calculates an address from a base register value and an
5110// immediate offset, and stores a word
5111// from a register to memory. It can use offset, post-indexed, or pre-indexed
5112// addressing.
5114 const ARMEncoding encoding) {
5115#if 0
5116 if ConditionPassed() then
5117 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5118 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5119 address = if</