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 <stdlib.h>
10
11 #include "EmulateInstructionARM.h"
12 #include "EmulationStateARM.h"
13 #include "lldb/Core/Address.h"
14 #include "lldb/Core/PluginManager.h"
15 #include "lldb/Host/PosixApi.h"
16 #include "lldb/Interpreter/OptionValueArray.h"
17 #include "lldb/Interpreter/OptionValueDictionary.h"
18 #include "lldb/Symbol/UnwindPlan.h"
19 #include "lldb/Utility/ArchSpec.h"
20 #include "lldb/Utility/ConstString.h"
21 #include "lldb/Utility/Stream.h"
22
23 #include "Plugins/Process/Utility/ARMDefines.h"
24 #include "Plugins/Process/Utility/ARMUtils.h"
25 #include "Utility/ARM_DWARF_Registers.h"
26
27 #include "llvm/ADT/STLExtras.h"
28 #include "llvm/Support/MathExtras.h"
29
30 using namespace lldb;
31 using namespace lldb_private;
32
LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionARM,InstructionARM)33 LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionARM, InstructionARM)
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
45 static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) {
46 ::memset(®_info, 0, sizeof(RegisterInfo));
47 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
48
49 if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) {
50 reg_info.byte_size = 16;
51 reg_info.format = eFormatVectorOfUInt8;
52 reg_info.encoding = eEncodingVector;
53 }
54
55 if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) {
56 reg_info.byte_size = 8;
57 reg_info.format = eFormatFloat;
58 reg_info.encoding = eEncodingIEEE754;
59 } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) {
60 reg_info.byte_size = 4;
61 reg_info.format = eFormatFloat;
62 reg_info.encoding = eEncodingIEEE754;
63 } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) {
64 reg_info.byte_size = 12;
65 reg_info.format = eFormatFloat;
66 reg_info.encoding = eEncodingIEEE754;
67 } else {
68 reg_info.byte_size = 4;
69 reg_info.format = eFormatHex;
70 reg_info.encoding = eEncodingUint;
71 }
72
73 reg_info.kinds[eRegisterKindDWARF] = reg_num;
74
75 switch (reg_num) {
76 case dwarf_r0:
77 reg_info.name = "r0";
78 break;
79 case dwarf_r1:
80 reg_info.name = "r1";
81 break;
82 case dwarf_r2:
83 reg_info.name = "r2";
84 break;
85 case dwarf_r3:
86 reg_info.name = "r3";
87 break;
88 case dwarf_r4:
89 reg_info.name = "r4";
90 break;
91 case dwarf_r5:
92 reg_info.name = "r5";
93 break;
94 case dwarf_r6:
95 reg_info.name = "r6";
96 break;
97 case dwarf_r7:
98 reg_info.name = "r7";
99 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
100 break;
101 case dwarf_r8:
102 reg_info.name = "r8";
103 break;
104 case dwarf_r9:
105 reg_info.name = "r9";
106 break;
107 case dwarf_r10:
108 reg_info.name = "r10";
109 break;
110 case dwarf_r11:
111 reg_info.name = "r11";
112 break;
113 case dwarf_r12:
114 reg_info.name = "r12";
115 break;
116 case dwarf_sp:
117 reg_info.name = "sp";
118 reg_info.alt_name = "r13";
119 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
120 break;
121 case dwarf_lr:
122 reg_info.name = "lr";
123 reg_info.alt_name = "r14";
124 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
125 break;
126 case dwarf_pc:
127 reg_info.name = "pc";
128 reg_info.alt_name = "r15";
129 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
130 break;
131 case dwarf_cpsr:
132 reg_info.name = "cpsr";
133 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
134 break;
135
136 case dwarf_s0:
137 reg_info.name = "s0";
138 break;
139 case dwarf_s1:
140 reg_info.name = "s1";
141 break;
142 case dwarf_s2:
143 reg_info.name = "s2";
144 break;
145 case dwarf_s3:
146 reg_info.name = "s3";
147 break;
148 case dwarf_s4:
149 reg_info.name = "s4";
150 break;
151 case dwarf_s5:
152 reg_info.name = "s5";
153 break;
154 case dwarf_s6:
155 reg_info.name = "s6";
156 break;
157 case dwarf_s7:
158 reg_info.name = "s7";
159 break;
160 case dwarf_s8:
161 reg_info.name = "s8";
162 break;
163 case dwarf_s9:
164 reg_info.name = "s9";
165 break;
166 case dwarf_s10:
167 reg_info.name = "s10";
168 break;
169 case dwarf_s11:
170 reg_info.name = "s11";
171 break;
172 case dwarf_s12:
173 reg_info.name = "s12";
174 break;
175 case dwarf_s13:
176 reg_info.name = "s13";
177 break;
178 case dwarf_s14:
179 reg_info.name = "s14";
180 break;
181 case dwarf_s15:
182 reg_info.name = "s15";
183 break;
184 case dwarf_s16:
185 reg_info.name = "s16";
186 break;
187 case dwarf_s17:
188 reg_info.name = "s17";
189 break;
190 case dwarf_s18:
191 reg_info.name = "s18";
192 break;
193 case dwarf_s19:
194 reg_info.name = "s19";
195 break;
196 case dwarf_s20:
197 reg_info.name = "s20";
198 break;
199 case dwarf_s21:
200 reg_info.name = "s21";
201 break;
202 case dwarf_s22:
203 reg_info.name = "s22";
204 break;
205 case dwarf_s23:
206 reg_info.name = "s23";
207 break;
208 case dwarf_s24:
209 reg_info.name = "s24";
210 break;
211 case dwarf_s25:
212 reg_info.name = "s25";
213 break;
214 case dwarf_s26:
215 reg_info.name = "s26";
216 break;
217 case dwarf_s27:
218 reg_info.name = "s27";
219 break;
220 case dwarf_s28:
221 reg_info.name = "s28";
222 break;
223 case dwarf_s29:
224 reg_info.name = "s29";
225 break;
226 case dwarf_s30:
227 reg_info.name = "s30";
228 break;
229 case dwarf_s31:
230 reg_info.name = "s31";
231 break;
232
233 // FPA Registers 0-7
234 case dwarf_f0:
235 reg_info.name = "f0";
236 break;
237 case dwarf_f1:
238 reg_info.name = "f1";
239 break;
240 case dwarf_f2:
241 reg_info.name = "f2";
242 break;
243 case dwarf_f3:
244 reg_info.name = "f3";
245 break;
246 case dwarf_f4:
247 reg_info.name = "f4";
248 break;
249 case dwarf_f5:
250 reg_info.name = "f5";
251 break;
252 case dwarf_f6:
253 reg_info.name = "f6";
254 break;
255 case dwarf_f7:
256 reg_info.name = "f7";
257 break;
258
259 // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator
260 // register 0 - 7 (they do overlap with wCGR0 - wCGR7)
261 case dwarf_wCGR0:
262 reg_info.name = "wCGR0/ACC0";
263 break;
264 case dwarf_wCGR1:
265 reg_info.name = "wCGR1/ACC1";
266 break;
267 case dwarf_wCGR2:
268 reg_info.name = "wCGR2/ACC2";
269 break;
270 case dwarf_wCGR3:
271 reg_info.name = "wCGR3/ACC3";
272 break;
273 case dwarf_wCGR4:
274 reg_info.name = "wCGR4/ACC4";
275 break;
276 case dwarf_wCGR5:
277 reg_info.name = "wCGR5/ACC5";
278 break;
279 case dwarf_wCGR6:
280 reg_info.name = "wCGR6/ACC6";
281 break;
282 case dwarf_wCGR7:
283 reg_info.name = "wCGR7/ACC7";
284 break;
285
286 // Intel wireless MMX data registers 0 - 15
287 case dwarf_wR0:
288 reg_info.name = "wR0";
289 break;
290 case dwarf_wR1:
291 reg_info.name = "wR1";
292 break;
293 case dwarf_wR2:
294 reg_info.name = "wR2";
295 break;
296 case dwarf_wR3:
297 reg_info.name = "wR3";
298 break;
299 case dwarf_wR4:
300 reg_info.name = "wR4";
301 break;
302 case dwarf_wR5:
303 reg_info.name = "wR5";
304 break;
305 case dwarf_wR6:
306 reg_info.name = "wR6";
307 break;
308 case dwarf_wR7:
309 reg_info.name = "wR7";
310 break;
311 case dwarf_wR8:
312 reg_info.name = "wR8";
313 break;
314 case dwarf_wR9:
315 reg_info.name = "wR9";
316 break;
317 case dwarf_wR10:
318 reg_info.name = "wR10";
319 break;
320 case dwarf_wR11:
321 reg_info.name = "wR11";
322 break;
323 case dwarf_wR12:
324 reg_info.name = "wR12";
325 break;
326 case dwarf_wR13:
327 reg_info.name = "wR13";
328 break;
329 case dwarf_wR14:
330 reg_info.name = "wR14";
331 break;
332 case dwarf_wR15:
333 reg_info.name = "wR15";
334 break;
335
336 case dwarf_spsr:
337 reg_info.name = "spsr";
338 break;
339 case dwarf_spsr_fiq:
340 reg_info.name = "spsr_fiq";
341 break;
342 case dwarf_spsr_irq:
343 reg_info.name = "spsr_irq";
344 break;
345 case dwarf_spsr_abt:
346 reg_info.name = "spsr_abt";
347 break;
348 case dwarf_spsr_und:
349 reg_info.name = "spsr_und";
350 break;
351 case dwarf_spsr_svc:
352 reg_info.name = "spsr_svc";
353 break;
354
355 case dwarf_r8_usr:
356 reg_info.name = "r8_usr";
357 break;
358 case dwarf_r9_usr:
359 reg_info.name = "r9_usr";
360 break;
361 case dwarf_r10_usr:
362 reg_info.name = "r10_usr";
363 break;
364 case dwarf_r11_usr:
365 reg_info.name = "r11_usr";
366 break;
367 case dwarf_r12_usr:
368 reg_info.name = "r12_usr";
369 break;
370 case dwarf_r13_usr:
371 reg_info.name = "r13_usr";
372 break;
373 case dwarf_r14_usr:
374 reg_info.name = "r14_usr";
375 break;
376 case dwarf_r8_fiq:
377 reg_info.name = "r8_fiq";
378 break;
379 case dwarf_r9_fiq:
380 reg_info.name = "r9_fiq";
381 break;
382 case dwarf_r10_fiq:
383 reg_info.name = "r10_fiq";
384 break;
385 case dwarf_r11_fiq:
386 reg_info.name = "r11_fiq";
387 break;
388 case dwarf_r12_fiq:
389 reg_info.name = "r12_fiq";
390 break;
391 case dwarf_r13_fiq:
392 reg_info.name = "r13_fiq";
393 break;
394 case dwarf_r14_fiq:
395 reg_info.name = "r14_fiq";
396 break;
397 case dwarf_r13_irq:
398 reg_info.name = "r13_irq";
399 break;
400 case dwarf_r14_irq:
401 reg_info.name = "r14_irq";
402 break;
403 case dwarf_r13_abt:
404 reg_info.name = "r13_abt";
405 break;
406 case dwarf_r14_abt:
407 reg_info.name = "r14_abt";
408 break;
409 case dwarf_r13_und:
410 reg_info.name = "r13_und";
411 break;
412 case dwarf_r14_und:
413 reg_info.name = "r14_und";
414 break;
415 case dwarf_r13_svc:
416 reg_info.name = "r13_svc";
417 break;
418 case dwarf_r14_svc:
419 reg_info.name = "r14_svc";
420 break;
421
422 // Intel wireless MMX control register in co-processor 0 - 7
423 case dwarf_wC0:
424 reg_info.name = "wC0";
425 break;
426 case dwarf_wC1:
427 reg_info.name = "wC1";
428 break;
429 case dwarf_wC2:
430 reg_info.name = "wC2";
431 break;
432 case dwarf_wC3:
433 reg_info.name = "wC3";
434 break;
435 case dwarf_wC4:
436 reg_info.name = "wC4";
437 break;
438 case dwarf_wC5:
439 reg_info.name = "wC5";
440 break;
441 case dwarf_wC6:
442 reg_info.name = "wC6";
443 break;
444 case dwarf_wC7:
445 reg_info.name = "wC7";
446 break;
447
448 // VFP-v3/Neon
449 case dwarf_d0:
450 reg_info.name = "d0";
451 break;
452 case dwarf_d1:
453 reg_info.name = "d1";
454 break;
455 case dwarf_d2:
456 reg_info.name = "d2";
457 break;
458 case dwarf_d3:
459 reg_info.name = "d3";
460 break;
461 case dwarf_d4:
462 reg_info.name = "d4";
463 break;
464 case dwarf_d5:
465 reg_info.name = "d5";
466 break;
467 case dwarf_d6:
468 reg_info.name = "d6";
469 break;
470 case dwarf_d7:
471 reg_info.name = "d7";
472 break;
473 case dwarf_d8:
474 reg_info.name = "d8";
475 break;
476 case dwarf_d9:
477 reg_info.name = "d9";
478 break;
479 case dwarf_d10:
480 reg_info.name = "d10";
481 break;
482 case dwarf_d11:
483 reg_info.name = "d11";
484 break;
485 case dwarf_d12:
486 reg_info.name = "d12";
487 break;
488 case dwarf_d13:
489 reg_info.name = "d13";
490 break;
491 case dwarf_d14:
492 reg_info.name = "d14";
493 break;
494 case dwarf_d15:
495 reg_info.name = "d15";
496 break;
497 case dwarf_d16:
498 reg_info.name = "d16";
499 break;
500 case dwarf_d17:
501 reg_info.name = "d17";
502 break;
503 case dwarf_d18:
504 reg_info.name = "d18";
505 break;
506 case dwarf_d19:
507 reg_info.name = "d19";
508 break;
509 case dwarf_d20:
510 reg_info.name = "d20";
511 break;
512 case dwarf_d21:
513 reg_info.name = "d21";
514 break;
515 case dwarf_d22:
516 reg_info.name = "d22";
517 break;
518 case dwarf_d23:
519 reg_info.name = "d23";
520 break;
521 case dwarf_d24:
522 reg_info.name = "d24";
523 break;
524 case dwarf_d25:
525 reg_info.name = "d25";
526 break;
527 case dwarf_d26:
528 reg_info.name = "d26";
529 break;
530 case dwarf_d27:
531 reg_info.name = "d27";
532 break;
533 case dwarf_d28:
534 reg_info.name = "d28";
535 break;
536 case dwarf_d29:
537 reg_info.name = "d29";
538 break;
539 case dwarf_d30:
540 reg_info.name = "d30";
541 break;
542 case dwarf_d31:
543 reg_info.name = "d31";
544 break;
545
546 // NEON 128-bit vector registers (overlays the d registers)
547 case dwarf_q0:
548 reg_info.name = "q0";
549 break;
550 case dwarf_q1:
551 reg_info.name = "q1";
552 break;
553 case dwarf_q2:
554 reg_info.name = "q2";
555 break;
556 case dwarf_q3:
557 reg_info.name = "q3";
558 break;
559 case dwarf_q4:
560 reg_info.name = "q4";
561 break;
562 case dwarf_q5:
563 reg_info.name = "q5";
564 break;
565 case dwarf_q6:
566 reg_info.name = "q6";
567 break;
568 case dwarf_q7:
569 reg_info.name = "q7";
570 break;
571 case dwarf_q8:
572 reg_info.name = "q8";
573 break;
574 case dwarf_q9:
575 reg_info.name = "q9";
576 break;
577 case dwarf_q10:
578 reg_info.name = "q10";
579 break;
580 case dwarf_q11:
581 reg_info.name = "q11";
582 break;
583 case dwarf_q12:
584 reg_info.name = "q12";
585 break;
586 case dwarf_q13:
587 reg_info.name = "q13";
588 break;
589 case dwarf_q14:
590 reg_info.name = "q14";
591 break;
592 case dwarf_q15:
593 reg_info.name = "q15";
594 break;
595
596 default:
597 return false;
598 }
599 return true;
600 }
601
602 // A8.6.50
603 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
CountITSize(uint32_t ITMask)604 static uint32_t CountITSize(uint32_t ITMask) {
605 // First count the trailing zeros of the IT mask.
606 uint32_t TZ = llvm::countTrailingZeros(ITMask);
607 if (TZ > 3) {
608 return 0;
609 }
610 return (4 - TZ);
611 }
612
613 // Init ITState. Note that at least one bit is always 1 in mask.
InitIT(uint32_t bits7_0)614 bool ITSession::InitIT(uint32_t bits7_0) {
615 ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
616 if (ITCounter == 0)
617 return false;
618
619 // A8.6.50 IT
620 unsigned short FirstCond = Bits32(bits7_0, 7, 4);
621 if (FirstCond == 0xF) {
622 return false;
623 }
624 if (FirstCond == 0xE && ITCounter != 1) {
625 return false;
626 }
627
628 ITState = bits7_0;
629 return true;
630 }
631
632 // Update ITState if necessary.
ITAdvance()633 void ITSession::ITAdvance() {
634 // assert(ITCounter);
635 --ITCounter;
636 if (ITCounter == 0)
637 ITState = 0;
638 else {
639 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
640 SetBits32(ITState, 4, 0, NewITState4_0);
641 }
642 }
643
644 // Return true if we're inside an IT Block.
InITBlock()645 bool ITSession::InITBlock() { return ITCounter != 0; }
646
647 // Return true if we're the last instruction inside an IT Block.
LastInITBlock()648 bool ITSession::LastInITBlock() { return ITCounter == 1; }
649
650 // Get condition bits for the current thumb instruction.
GetCond()651 uint32_t ITSession::GetCond() {
652 if (InITBlock())
653 return Bits32(ITState, 7, 4);
654 else
655 return COND_AL;
656 }
657
658 // ARM constants used during decoding
659 #define REG_RD 0
660 #define LDM_REGLIST 1
661 #define SP_REG 13
662 #define LR_REG 14
663 #define PC_REG 15
664 #define PC_REGLIST_BIT 0x8000
665
666 #define ARMv4 (1u << 0)
667 #define ARMv4T (1u << 1)
668 #define ARMv5T (1u << 2)
669 #define ARMv5TE (1u << 3)
670 #define ARMv5TEJ (1u << 4)
671 #define ARMv6 (1u << 5)
672 #define ARMv6K (1u << 6)
673 #define ARMv6T2 (1u << 7)
674 #define ARMv7 (1u << 8)
675 #define ARMv7S (1u << 9)
676 #define ARMv8 (1u << 10)
677 #define ARMvAll (0xffffffffu)
678
679 #define ARMV4T_ABOVE \
680 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \
681 ARMv7S | ARMv8)
682 #define ARMV5_ABOVE \
683 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \
684 ARMv8)
685 #define ARMV5TE_ABOVE \
686 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
687 #define ARMV5J_ABOVE \
688 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
689 #define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
690 #define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
691 #define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
692
693 #define No_VFP 0
694 #define VFPv1 (1u << 1)
695 #define VFPv2 (1u << 2)
696 #define VFPv3 (1u << 3)
697 #define AdvancedSIMD (1u << 4)
698
699 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
700 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
701 #define VFPv2v3 (VFPv2 | VFPv3)
702
703 //
704 // EmulateInstructionARM implementation
705 //
706
Initialize()707 void EmulateInstructionARM::Initialize() {
708 PluginManager::RegisterPlugin(GetPluginNameStatic(),
709 GetPluginDescriptionStatic(), CreateInstance);
710 }
711
Terminate()712 void EmulateInstructionARM::Terminate() {
713 PluginManager::UnregisterPlugin(CreateInstance);
714 }
715
GetPluginNameStatic()716 ConstString EmulateInstructionARM::GetPluginNameStatic() {
717 static ConstString g_name("arm");
718 return g_name;
719 }
720
GetPluginDescriptionStatic()721 const char *EmulateInstructionARM::GetPluginDescriptionStatic() {
722 return "Emulate instructions for the ARM architecture.";
723 }
724
725 EmulateInstruction *
CreateInstance(const ArchSpec & arch,InstructionType inst_type)726 EmulateInstructionARM::CreateInstance(const ArchSpec &arch,
727 InstructionType inst_type) {
728 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(
729 inst_type)) {
730 if (arch.GetTriple().getArch() == llvm::Triple::arm) {
731 std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
732 new EmulateInstructionARM(arch));
733
734 if (emulate_insn_up)
735 return emulate_insn_up.release();
736 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) {
737 std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
738 new EmulateInstructionARM(arch));
739
740 if (emulate_insn_up)
741 return emulate_insn_up.release();
742 }
743 }
744
745 return nullptr;
746 }
747
SetTargetTriple(const ArchSpec & arch)748 bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) {
749 if (arch.GetTriple().getArch() == llvm::Triple::arm)
750 return true;
751 else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
752 return true;
753
754 return false;
755 }
756
757 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for
758 // many ARM instructions.
WriteBits32UnknownToMemory(addr_t address)759 bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) {
760 EmulateInstruction::Context context;
761 context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
762 context.SetNoArgs();
763
764 uint32_t random_data = rand();
765 const uint32_t addr_byte_size = GetAddressByteSize();
766
767 return MemAWrite(context, address, random_data, addr_byte_size);
768 }
769
770 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM
771 // instructions.
WriteBits32Unknown(int n)772 bool EmulateInstructionARM::WriteBits32Unknown(int n) {
773 EmulateInstruction::Context context;
774 context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
775 context.SetNoArgs();
776
777 bool success;
778 uint32_t data =
779 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
780
781 if (!success)
782 return false;
783
784 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data))
785 return false;
786
787 return true;
788 }
789
GetRegisterInfo(lldb::RegisterKind reg_kind,uint32_t reg_num,RegisterInfo & reg_info)790 bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind,
791 uint32_t reg_num,
792 RegisterInfo ®_info) {
793 if (reg_kind == eRegisterKindGeneric) {
794 switch (reg_num) {
795 case LLDB_REGNUM_GENERIC_PC:
796 reg_kind = eRegisterKindDWARF;
797 reg_num = dwarf_pc;
798 break;
799 case LLDB_REGNUM_GENERIC_SP:
800 reg_kind = eRegisterKindDWARF;
801 reg_num = dwarf_sp;
802 break;
803 case LLDB_REGNUM_GENERIC_FP:
804 reg_kind = eRegisterKindDWARF;
805 reg_num = dwarf_r7;
806 break;
807 case LLDB_REGNUM_GENERIC_RA:
808 reg_kind = eRegisterKindDWARF;
809 reg_num = dwarf_lr;
810 break;
811 case LLDB_REGNUM_GENERIC_FLAGS:
812 reg_kind = eRegisterKindDWARF;
813 reg_num = dwarf_cpsr;
814 break;
815 default:
816 return false;
817 }
818 }
819
820 if (reg_kind == eRegisterKindDWARF)
821 return GetARMDWARFRegisterInfo(reg_num, reg_info);
822 return false;
823 }
824
GetFramePointerRegisterNumber() const825 uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
826 if (m_arch.GetTriple().isAndroid())
827 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
828 bool is_apple = false;
829 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
830 is_apple = true;
831 switch (m_arch.GetTriple().getOS()) {
832 case llvm::Triple::Darwin:
833 case llvm::Triple::MacOSX:
834 case llvm::Triple::IOS:
835 case llvm::Triple::TvOS:
836 case llvm::Triple::WatchOS:
837 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
838 is_apple = true;
839 break;
840 default:
841 break;
842 }
843
844 /* On Apple iOS et al, the frame pointer register is always r7.
845 * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
846 * Windows on ARM, which is in thumb mode, uses r11 though.
847 */
848
849 uint32_t fp_regnum = 11;
850
851 if (is_apple)
852 fp_regnum = 7;
853
854 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
855 fp_regnum = 7;
856
857 return fp_regnum;
858 }
859
GetFramePointerDWARFRegisterNumber() const860 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
861 bool is_apple = false;
862 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
863 is_apple = true;
864 switch (m_arch.GetTriple().getOS()) {
865 case llvm::Triple::Darwin:
866 case llvm::Triple::MacOSX:
867 case llvm::Triple::IOS:
868 is_apple = true;
869 break;
870 default:
871 break;
872 }
873
874 /* On Apple iOS et al, the frame pointer register is always r7.
875 * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
876 * Windows on ARM, which is in thumb mode, uses r11 though.
877 */
878
879 uint32_t fp_regnum = dwarf_r11;
880
881 if (is_apple)
882 fp_regnum = dwarf_r7;
883
884 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
885 fp_regnum = dwarf_r7;
886
887 return fp_regnum;
888 }
889
890 // Push Multiple Registers stores multiple registers to the stack, storing to
891 // consecutive memory locations ending just below the address in SP, and
892 // updates
893 // SP to point to the start of the stored data.
EmulatePUSH(const uint32_t opcode,const ARMEncoding encoding)894 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
895 const ARMEncoding encoding) {
896 #if 0
897 // ARM pseudo code...
898 if (ConditionPassed())
899 {
900 EncodingSpecificOperations();
901 NullCheckIfThumbEE(13);
902 address = SP - 4*BitCount(registers);
903
904 for (i = 0 to 14)
905 {
906 if (registers<i> == '1')
907 {
908 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
909 MemA[address,4] = bits(32) UNKNOWN;
910 else
911 MemA[address,4] = R[i];
912 address = address + 4;
913 }
914 }
915
916 if (registers<15> == '1') // Only possible for encoding A1 or A2
917 MemA[address,4] = PCStoreValue();
918
919 SP = SP - 4*BitCount(registers);
920 }
921 #endif
922
923 bool success = false;
924 if (ConditionPassed(opcode)) {
925 const uint32_t addr_byte_size = GetAddressByteSize();
926 const addr_t sp = ReadCoreReg(SP_REG, &success);
927 if (!success)
928 return false;
929 uint32_t registers = 0;
930 uint32_t Rt; // the source register
931 switch (encoding) {
932 case eEncodingT1:
933 registers = Bits32(opcode, 7, 0);
934 // The M bit represents LR.
935 if (Bit32(opcode, 8))
936 registers |= (1u << 14);
937 // if BitCount(registers) < 1 then UNPREDICTABLE;
938 if (BitCount(registers) < 1)
939 return false;
940 break;
941 case eEncodingT2:
942 // Ignore bits 15 & 13.
943 registers = Bits32(opcode, 15, 0) & ~0xa000;
944 // if BitCount(registers) < 2 then UNPREDICTABLE;
945 if (BitCount(registers) < 2)
946 return false;
947 break;
948 case eEncodingT3:
949 Rt = Bits32(opcode, 15, 12);
950 // if BadReg(t) then UNPREDICTABLE;
951 if (BadReg(Rt))
952 return false;
953 registers = (1u << Rt);
954 break;
955 case eEncodingA1:
956 registers = Bits32(opcode, 15, 0);
957 // Instead of return false, let's handle the following case as well,
958 // which amounts to pushing one reg onto the full descending stacks.
959 // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
960 break;
961 case eEncodingA2:
962 Rt = Bits32(opcode, 15, 12);
963 // if t == 13 then UNPREDICTABLE;
964 if (Rt == dwarf_sp)
965 return false;
966 registers = (1u << Rt);
967 break;
968 default:
969 return false;
970 }
971 addr_t sp_offset = addr_byte_size * BitCount(registers);
972 addr_t addr = sp - sp_offset;
973 uint32_t i;
974
975 EmulateInstruction::Context context;
976 context.type = EmulateInstruction::eContextPushRegisterOnStack;
977 RegisterInfo reg_info;
978 RegisterInfo sp_reg;
979 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
980 for (i = 0; i < 15; ++i) {
981 if (BitIsSet(registers, i)) {
982 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info);
983 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
984 uint32_t reg_value = ReadCoreReg(i, &success);
985 if (!success)
986 return false;
987 if (!MemAWrite(context, addr, reg_value, addr_byte_size))
988 return false;
989 addr += addr_byte_size;
990 }
991 }
992
993 if (BitIsSet(registers, 15)) {
994 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info);
995 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
996 const uint32_t pc = ReadCoreReg(PC_REG, &success);
997 if (!success)
998 return false;
999 if (!MemAWrite(context, addr, pc, addr_byte_size))
1000 return false;
1001 }
1002
1003 context.type = EmulateInstruction::eContextAdjustStackPointer;
1004 context.SetImmediateSigned(-sp_offset);
1005
1006 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1007 LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1008 return false;
1009 }
1010 return true;
1011 }
1012
1013 // Pop Multiple Registers loads multiple registers from the stack, loading from
1014 // consecutive memory locations staring at the address in SP, and updates
1015 // SP to point just above the loaded data.
EmulatePOP(const uint32_t opcode,const ARMEncoding encoding)1016 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
1017 const ARMEncoding encoding) {
1018 #if 0
1019 // ARM pseudo code...
1020 if (ConditionPassed())
1021 {
1022 EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1023 address = SP;
1024 for i = 0 to 14
1025 if registers<i> == '1' then
1026 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
1027 if registers<15> == '1' then
1028 if UnalignedAllowed then
1029 LoadWritePC(MemU[address,4]);
1030 else
1031 LoadWritePC(MemA[address,4]);
1032 if registers<13> == '0' then SP = SP + 4*BitCount(registers);
1033 if registers<13> == '1' then SP = bits(32) UNKNOWN;
1034 }
1035 #endif
1036
1037 bool success = false;
1038
1039 if (ConditionPassed(opcode)) {
1040 const uint32_t addr_byte_size = GetAddressByteSize();
1041 const addr_t sp = ReadCoreReg(SP_REG, &success);
1042 if (!success)
1043 return false;
1044 uint32_t registers = 0;
1045 uint32_t Rt; // the destination register
1046 switch (encoding) {
1047 case eEncodingT1:
1048 registers = Bits32(opcode, 7, 0);
1049 // The P bit represents PC.
1050 if (Bit32(opcode, 8))
1051 registers |= (1u << 15);
1052 // if BitCount(registers) < 1 then UNPREDICTABLE;
1053 if (BitCount(registers) < 1)
1054 return false;
1055 break;
1056 case eEncodingT2:
1057 // Ignore bit 13.
1058 registers = Bits32(opcode, 15, 0) & ~0x2000;
1059 // if BitCount(registers) < 2 || (P == '1' && M == '1') then
1060 // UNPREDICTABLE;
1061 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
1062 return false;
1063 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
1064 // UNPREDICTABLE;
1065 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1066 return false;
1067 break;
1068 case eEncodingT3:
1069 Rt = Bits32(opcode, 15, 12);
1070 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
1071 // UNPREDICTABLE;
1072 if (Rt == 13)
1073 return false;
1074 if (Rt == 15 && InITBlock() && !LastInITBlock())
1075 return false;
1076 registers = (1u << Rt);
1077 break;
1078 case eEncodingA1:
1079 registers = Bits32(opcode, 15, 0);
1080 // Instead of return false, let's handle the following case as well,
1081 // which amounts to popping one reg from the full descending stacks.
1082 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
1083
1084 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
1085 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
1086 return false;
1087 break;
1088 case eEncodingA2:
1089 Rt = Bits32(opcode, 15, 12);
1090 // if t == 13 then UNPREDICTABLE;
1091 if (Rt == dwarf_sp)
1092 return false;
1093 registers = (1u << Rt);
1094 break;
1095 default:
1096 return false;
1097 }
1098 addr_t sp_offset = addr_byte_size * BitCount(registers);
1099 addr_t addr = sp;
1100 uint32_t i, data;
1101
1102 EmulateInstruction::Context context;
1103 context.type = EmulateInstruction::eContextPopRegisterOffStack;
1104
1105 RegisterInfo sp_reg;
1106 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1107
1108 for (i = 0; i < 15; ++i) {
1109 if (BitIsSet(registers, i)) {
1110 context.SetAddress(addr);
1111 data = MemARead(context, addr, 4, 0, &success);
1112 if (!success)
1113 return false;
1114 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
1115 data))
1116 return false;
1117 addr += addr_byte_size;
1118 }
1119 }
1120
1121 if (BitIsSet(registers, 15)) {
1122 context.SetRegisterPlusOffset(sp_reg, addr - sp);
1123 data = MemARead(context, addr, 4, 0, &success);
1124 if (!success)
1125 return false;
1126 // In ARMv5T and above, this is an interworking branch.
1127 if (!LoadWritePC(context, data))
1128 return false;
1129 // addr += addr_byte_size;
1130 }
1131
1132 context.type = EmulateInstruction::eContextAdjustStackPointer;
1133 context.SetImmediateSigned(sp_offset);
1134
1135 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1136 LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1137 return false;
1138 }
1139 return true;
1140 }
1141
1142 // Set r7 or ip to point to saved value residing within the stack.
1143 // ADD (SP plus immediate)
EmulateADDRdSPImm(const uint32_t opcode,const ARMEncoding encoding)1144 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
1145 const ARMEncoding encoding) {
1146 #if 0
1147 // ARM pseudo code...
1148 if (ConditionPassed())
1149 {
1150 EncodingSpecificOperations();
1151 (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1152 if d == 15 then
1153 ALUWritePC(result); // setflags is always FALSE here
1154 else
1155 R[d] = result;
1156 if setflags then
1157 APSR.N = result<31>;
1158 APSR.Z = IsZeroBit(result);
1159 APSR.C = carry;
1160 APSR.V = overflow;
1161 }
1162 #endif
1163
1164 bool success = false;
1165
1166 if (ConditionPassed(opcode)) {
1167 const addr_t sp = ReadCoreReg(SP_REG, &success);
1168 if (!success)
1169 return false;
1170 uint32_t Rd; // the destination register
1171 uint32_t imm32;
1172 switch (encoding) {
1173 case eEncodingT1:
1174 Rd = 7;
1175 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
1176 break;
1177 case eEncodingA1:
1178 Rd = Bits32(opcode, 15, 12);
1179 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1180 break;
1181 default:
1182 return false;
1183 }
1184 addr_t sp_offset = imm32;
1185 addr_t addr = sp + sp_offset; // a pointer to the stack area
1186
1187 EmulateInstruction::Context context;
1188 if (Rd == GetFramePointerRegisterNumber())
1189 context.type = eContextSetFramePointer;
1190 else
1191 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1192 RegisterInfo sp_reg;
1193 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1194 context.SetRegisterPlusOffset(sp_reg, sp_offset);
1195
1196 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
1197 addr))
1198 return false;
1199 }
1200 return true;
1201 }
1202
1203 // Set r7 or ip to the current stack pointer.
1204 // MOV (register)
EmulateMOVRdSP(const uint32_t opcode,const ARMEncoding encoding)1205 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
1206 const ARMEncoding encoding) {
1207 #if 0
1208 // ARM pseudo code...
1209 if (ConditionPassed())
1210 {
1211 EncodingSpecificOperations();
1212 result = R[m];
1213 if d == 15 then
1214 ALUWritePC(result); // setflags is always FALSE here
1215 else
1216 R[d] = result;
1217 if setflags then
1218 APSR.N = result<31>;
1219 APSR.Z = IsZeroBit(result);
1220 // APSR.C unchanged
1221 // APSR.V unchanged
1222 }
1223 #endif
1224
1225 bool success = false;
1226
1227 if (ConditionPassed(opcode)) {
1228 const addr_t sp = ReadCoreReg(SP_REG, &success);
1229 if (!success)
1230 return false;
1231 uint32_t Rd; // the destination register
1232 switch (encoding) {
1233 case eEncodingT1:
1234 Rd = 7;
1235 break;
1236 case eEncodingA1:
1237 Rd = 12;
1238 break;
1239 default:
1240 return false;
1241 }
1242
1243 EmulateInstruction::Context context;
1244 if (Rd == GetFramePointerRegisterNumber())
1245 context.type = EmulateInstruction::eContextSetFramePointer;
1246 else
1247 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1248 RegisterInfo sp_reg;
1249 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1250 context.SetRegisterPlusOffset(sp_reg, 0);
1251
1252 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
1253 return false;
1254 }
1255 return true;
1256 }
1257
1258 // Move from high register (r8-r15) to low register (r0-r7).
1259 // MOV (register)
EmulateMOVLowHigh(const uint32_t opcode,const ARMEncoding encoding)1260 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
1261 const ARMEncoding encoding) {
1262 return EmulateMOVRdRm(opcode, encoding);
1263 }
1264
1265 // Move from register to register.
1266 // MOV (register)
EmulateMOVRdRm(const uint32_t opcode,const ARMEncoding encoding)1267 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
1268 const ARMEncoding encoding) {
1269 #if 0
1270 // ARM pseudo code...
1271 if (ConditionPassed())
1272 {
1273 EncodingSpecificOperations();
1274 result = R[m];
1275 if d == 15 then
1276 ALUWritePC(result); // setflags is always FALSE here
1277 else
1278 R[d] = result;
1279 if setflags then
1280 APSR.N = result<31>;
1281 APSR.Z = IsZeroBit(result);
1282 // APSR.C unchanged
1283 // APSR.V unchanged
1284 }
1285 #endif
1286
1287 bool success = false;
1288
1289 if (ConditionPassed(opcode)) {
1290 uint32_t Rm; // the source register
1291 uint32_t Rd; // the destination register
1292 bool setflags;
1293 switch (encoding) {
1294 case eEncodingT1:
1295 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1296 Rm = Bits32(opcode, 6, 3);
1297 setflags = false;
1298 if (Rd == 15 && InITBlock() && !LastInITBlock())
1299 return false;
1300 break;
1301 case eEncodingT2:
1302 Rd = Bits32(opcode, 2, 0);
1303 Rm = Bits32(opcode, 5, 3);
1304 setflags = true;
1305 if (InITBlock())
1306 return false;
1307 break;
1308 case eEncodingT3:
1309 Rd = Bits32(opcode, 11, 8);
1310 Rm = Bits32(opcode, 3, 0);
1311 setflags = BitIsSet(opcode, 20);
1312 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1313 if (setflags && (BadReg(Rd) || BadReg(Rm)))
1314 return false;
1315 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
1316 // UNPREDICTABLE;
1317 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1318 return false;
1319 break;
1320 case eEncodingA1:
1321 Rd = Bits32(opcode, 15, 12);
1322 Rm = Bits32(opcode, 3, 0);
1323 setflags = BitIsSet(opcode, 20);
1324
1325 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1326 // instructions;
1327 if (Rd == 15 && setflags)
1328 return EmulateSUBSPcLrEtc(opcode, encoding);
1329 break;
1330 default:
1331 return false;
1332 }
1333 uint32_t result = ReadCoreReg(Rm, &success);
1334 if (!success)
1335 return false;
1336
1337 // The context specifies that Rm is to be moved into Rd.
1338 EmulateInstruction::Context context;
1339 if (Rd == 13)
1340 context.type = EmulateInstruction::eContextAdjustStackPointer;
1341 else if (Rd == GetFramePointerRegisterNumber() && Rm == 13)
1342 context.type = EmulateInstruction::eContextSetFramePointer;
1343 else
1344 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1345 RegisterInfo dwarf_reg;
1346 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1347 context.SetRegisterPlusOffset(dwarf_reg, 0);
1348
1349 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1350 return false;
1351 }
1352 return true;
1353 }
1354
1355 // Move (immediate) writes an immediate value to the destination register. It
1356 // can optionally update the condition flags based on the value.
1357 // MOV (immediate)
EmulateMOVRdImm(const uint32_t opcode,const ARMEncoding encoding)1358 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
1359 const ARMEncoding encoding) {
1360 #if 0
1361 // ARM pseudo code...
1362 if (ConditionPassed())
1363 {
1364 EncodingSpecificOperations();
1365 result = imm32;
1366 if d == 15 then // Can only occur for ARM encoding
1367 ALUWritePC(result); // setflags is always FALSE here
1368 else
1369 R[d] = result;
1370 if setflags then
1371 APSR.N = result<31>;
1372 APSR.Z = IsZeroBit(result);
1373 APSR.C = carry;
1374 // APSR.V unchanged
1375 }
1376 #endif
1377
1378 if (ConditionPassed(opcode)) {
1379 uint32_t Rd; // the destination register
1380 uint32_t imm32; // the immediate value to be written to Rd
1381 uint32_t carry =
1382 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
1383 // for setflags == false, this value is a don't care initialized to
1384 // 0 to silence the static analyzer
1385 bool setflags;
1386 switch (encoding) {
1387 case eEncodingT1:
1388 Rd = Bits32(opcode, 10, 8);
1389 setflags = !InITBlock();
1390 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
1391 carry = APSR_C;
1392
1393 break;
1394
1395 case eEncodingT2:
1396 Rd = Bits32(opcode, 11, 8);
1397 setflags = BitIsSet(opcode, 20);
1398 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1399 if (BadReg(Rd))
1400 return false;
1401
1402 break;
1403
1404 case eEncodingT3: {
1405 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
1406 // 32);
1407 Rd = Bits32(opcode, 11, 8);
1408 setflags = false;
1409 uint32_t imm4 = Bits32(opcode, 19, 16);
1410 uint32_t imm3 = Bits32(opcode, 14, 12);
1411 uint32_t i = Bit32(opcode, 26);
1412 uint32_t imm8 = Bits32(opcode, 7, 0);
1413 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1414
1415 // if BadReg(d) then UNPREDICTABLE;
1416 if (BadReg(Rd))
1417 return false;
1418 } break;
1419
1420 case eEncodingA1:
1421 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
1422 // ARMExpandImm_C(imm12, APSR.C);
1423 Rd = Bits32(opcode, 15, 12);
1424 setflags = BitIsSet(opcode, 20);
1425 imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1426
1427 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1428 // instructions;
1429 if ((Rd == 15) && setflags)
1430 return EmulateSUBSPcLrEtc(opcode, encoding);
1431
1432 break;
1433
1434 case eEncodingA2: {
1435 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
1436 Rd = Bits32(opcode, 15, 12);
1437 setflags = false;
1438 uint32_t imm4 = Bits32(opcode, 19, 16);
1439 uint32_t imm12 = Bits32(opcode, 11, 0);
1440 imm32 = (imm4 << 12) | imm12;
1441
1442 // if d == 15 then UNPREDICTABLE;
1443 if (Rd == 15)
1444 return false;
1445 } break;
1446
1447 default:
1448 return false;
1449 }
1450 uint32_t result = imm32;
1451
1452 // The context specifies that an immediate is to be moved into Rd.
1453 EmulateInstruction::Context context;
1454 context.type = EmulateInstruction::eContextImmediate;
1455 context.SetNoArgs();
1456
1457 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1458 return false;
1459 }
1460 return true;
1461 }
1462
1463 // MUL multiplies two register values. The least significant 32 bits of the
1464 // result are written to the destination
1465 // register. These 32 bits do not depend on whether the source register values
1466 // are considered to be signed values or unsigned values.
1467 //
1468 // Optionally, it can update the condition flags based on the result. In the
1469 // Thumb instruction set, this option is limited to only a few forms of the
1470 // instruction.
EmulateMUL(const uint32_t opcode,const ARMEncoding encoding)1471 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
1472 const ARMEncoding encoding) {
1473 #if 0
1474 if ConditionPassed() then
1475 EncodingSpecificOperations();
1476 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1477 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1478 result = operand1 * operand2;
1479 R[d] = result<31:0>;
1480 if setflags then
1481 APSR.N = result<31>;
1482 APSR.Z = IsZeroBit(result);
1483 if ArchVersion() == 4 then
1484 APSR.C = bit UNKNOWN;
1485 // else APSR.C unchanged
1486 // APSR.V always unchanged
1487 #endif
1488
1489 if (ConditionPassed(opcode)) {
1490 uint32_t d;
1491 uint32_t n;
1492 uint32_t m;
1493 bool setflags;
1494
1495 // EncodingSpecificOperations();
1496 switch (encoding) {
1497 case eEncodingT1:
1498 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
1499 d = Bits32(opcode, 2, 0);
1500 n = Bits32(opcode, 5, 3);
1501 m = Bits32(opcode, 2, 0);
1502 setflags = !InITBlock();
1503
1504 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1505 if ((ArchVersion() < ARMv6) && (d == n))
1506 return false;
1507
1508 break;
1509
1510 case eEncodingT2:
1511 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
1512 d = Bits32(opcode, 11, 8);
1513 n = Bits32(opcode, 19, 16);
1514 m = Bits32(opcode, 3, 0);
1515 setflags = false;
1516
1517 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1518 if (BadReg(d) || BadReg(n) || BadReg(m))
1519 return false;
1520
1521 break;
1522
1523 case eEncodingA1:
1524 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1525 d = Bits32(opcode, 19, 16);
1526 n = Bits32(opcode, 3, 0);
1527 m = Bits32(opcode, 11, 8);
1528 setflags = BitIsSet(opcode, 20);
1529
1530 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1531 if ((d == 15) || (n == 15) || (m == 15))
1532 return false;
1533
1534 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1535 if ((ArchVersion() < ARMv6) && (d == n))
1536 return false;
1537
1538 break;
1539
1540 default:
1541 return false;
1542 }
1543
1544 bool success = false;
1545
1546 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1547 // results
1548 uint64_t operand1 =
1549 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1550 if (!success)
1551 return false;
1552
1553 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1554 // results
1555 uint64_t operand2 =
1556 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1557 if (!success)
1558 return false;
1559
1560 // result = operand1 * operand2;
1561 uint64_t result = operand1 * operand2;
1562
1563 // R[d] = result<31:0>;
1564 RegisterInfo op1_reg;
1565 RegisterInfo op2_reg;
1566 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1567 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1568
1569 EmulateInstruction::Context context;
1570 context.type = eContextArithmetic;
1571 context.SetRegisterRegisterOperands(op1_reg, op2_reg);
1572
1573 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
1574 (0x0000ffff & result)))
1575 return false;
1576
1577 // if setflags then
1578 if (setflags) {
1579 // APSR.N = result<31>;
1580 // APSR.Z = IsZeroBit(result);
1581 m_new_inst_cpsr = m_opcode_cpsr;
1582 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
1583 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1584 if (m_new_inst_cpsr != m_opcode_cpsr) {
1585 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1586 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1587 return false;
1588 }
1589
1590 // if ArchVersion() == 4 then
1591 // APSR.C = bit UNKNOWN;
1592 }
1593 }
1594 return true;
1595 }
1596
1597 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1598 // the destination register. It can optionally update the condition flags based
1599 // on the value.
EmulateMVNImm(const uint32_t opcode,const ARMEncoding encoding)1600 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1601 const ARMEncoding encoding) {
1602 #if 0
1603 // ARM pseudo code...
1604 if (ConditionPassed())
1605 {
1606 EncodingSpecificOperations();
1607 result = NOT(imm32);
1608 if d == 15 then // Can only occur for ARM encoding
1609 ALUWritePC(result); // setflags is always FALSE here
1610 else
1611 R[d] = result;
1612 if setflags then
1613 APSR.N = result<31>;
1614 APSR.Z = IsZeroBit(result);
1615 APSR.C = carry;
1616 // APSR.V unchanged
1617 }
1618 #endif
1619
1620 if (ConditionPassed(opcode)) {
1621 uint32_t Rd; // the destination register
1622 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1623 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1624 bool setflags;
1625 switch (encoding) {
1626 case eEncodingT1:
1627 Rd = Bits32(opcode, 11, 8);
1628 setflags = BitIsSet(opcode, 20);
1629 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1630 break;
1631 case eEncodingA1:
1632 Rd = Bits32(opcode, 15, 12);
1633 setflags = BitIsSet(opcode, 20);
1634 imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1635
1636 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1637 // instructions;
1638 if (Rd == 15 && setflags)
1639 return EmulateSUBSPcLrEtc(opcode, encoding);
1640 break;
1641 default:
1642 return false;
1643 }
1644 uint32_t result = ~imm32;
1645
1646 // The context specifies that an immediate is to be moved into Rd.
1647 EmulateInstruction::Context context;
1648 context.type = EmulateInstruction::eContextImmediate;
1649 context.SetNoArgs();
1650
1651 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1652 return false;
1653 }
1654 return true;
1655 }
1656
1657 // Bitwise NOT (register) writes the bitwise inverse of a register value to the
1658 // destination register. It can optionally update the condition flags based on
1659 // the result.
EmulateMVNReg(const uint32_t opcode,const ARMEncoding encoding)1660 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1661 const ARMEncoding encoding) {
1662 #if 0
1663 // ARM pseudo code...
1664 if (ConditionPassed())
1665 {
1666 EncodingSpecificOperations();
1667 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1668 result = NOT(shifted);
1669 if d == 15 then // Can only occur for ARM encoding
1670 ALUWritePC(result); // setflags is always FALSE here
1671 else
1672 R[d] = result;
1673 if setflags then
1674 APSR.N = result<31>;
1675 APSR.Z = IsZeroBit(result);
1676 APSR.C = carry;
1677 // APSR.V unchanged
1678 }
1679 #endif
1680
1681 if (ConditionPassed(opcode)) {
1682 uint32_t Rm; // the source register
1683 uint32_t Rd; // the destination register
1684 ARM_ShifterType shift_t;
1685 uint32_t shift_n; // the shift applied to the value read from Rm
1686 bool setflags;
1687 uint32_t carry; // the carry bit after the shift operation
1688 switch (encoding) {
1689 case eEncodingT1:
1690 Rd = Bits32(opcode, 2, 0);
1691 Rm = Bits32(opcode, 5, 3);
1692 setflags = !InITBlock();
1693 shift_t = SRType_LSL;
1694 shift_n = 0;
1695 if (InITBlock())
1696 return false;
1697 break;
1698 case eEncodingT2:
1699 Rd = Bits32(opcode, 11, 8);
1700 Rm = Bits32(opcode, 3, 0);
1701 setflags = BitIsSet(opcode, 20);
1702 shift_n = DecodeImmShiftThumb(opcode, shift_t);
1703 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1704 if (BadReg(Rd) || BadReg(Rm))
1705 return false;
1706 break;
1707 case eEncodingA1:
1708 Rd = Bits32(opcode, 15, 12);
1709 Rm = Bits32(opcode, 3, 0);
1710 setflags = BitIsSet(opcode, 20);
1711 shift_n = DecodeImmShiftARM(opcode, shift_t);
1712 break;
1713 default:
1714 return false;
1715 }
1716 bool success = false;
1717 uint32_t value = ReadCoreReg(Rm, &success);
1718 if (!success)
1719 return false;
1720
1721 uint32_t shifted =
1722 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1723 if (!success)
1724 return false;
1725 uint32_t result = ~shifted;
1726
1727 // The context specifies that an immediate is to be moved into Rd.
1728 EmulateInstruction::Context context;
1729 context.type = EmulateInstruction::eContextImmediate;
1730 context.SetNoArgs();
1731
1732 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1733 return false;
1734 }
1735 return true;
1736 }
1737
1738 // PC relative immediate load into register, possibly followed by ADD (SP plus
1739 // register).
1740 // LDR (literal)
EmulateLDRRtPCRelative(const uint32_t opcode,const ARMEncoding encoding)1741 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
1742 const ARMEncoding encoding) {
1743 #if 0
1744 // ARM pseudo code...
1745 if (ConditionPassed())
1746 {
1747 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1748 base = Align(PC,4);
1749 address = if add then (base + imm32) else (base - imm32);
1750 data = MemU[address,4];
1751 if t == 15 then
1752 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1753 elsif UnalignedSupport() || address<1:0> = '00' then
1754 R[t] = data;
1755 else // Can only apply before ARMv7
1756 if CurrentInstrSet() == InstrSet_ARM then
1757 R[t] = ROR(data, 8*UInt(address<1:0>));
1758 else
1759 R[t] = bits(32) UNKNOWN;
1760 }
1761 #endif
1762
1763 if (ConditionPassed(opcode)) {
1764 bool success = false;
1765 const uint32_t pc = ReadCoreReg(PC_REG, &success);
1766 if (!success)
1767 return false;
1768
1769 // PC relative immediate load context
1770 EmulateInstruction::Context context;
1771 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1772 RegisterInfo pc_reg;
1773 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
1774 context.SetRegisterPlusOffset(pc_reg, 0);
1775
1776 uint32_t Rt; // the destination register
1777 uint32_t imm32; // immediate offset from the PC
1778 bool add; // +imm32 or -imm32?
1779 addr_t base; // the base address
1780 addr_t address; // the PC relative address
1781 uint32_t data; // the literal data value from the PC relative load
1782 switch (encoding) {
1783 case eEncodingT1:
1784 Rt = Bits32(opcode, 10, 8);
1785 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1786 add = true;
1787 break;
1788 case eEncodingT2:
1789 Rt = Bits32(opcode, 15, 12);
1790 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1791 add = BitIsSet(opcode, 23);
1792 if (Rt == 15 && InITBlock() && !LastInITBlock())
1793 return false;
1794 break;
1795 default:
1796 return false;
1797 }
1798
1799 base = Align(pc, 4);
1800 if (add)
1801 address = base + imm32;
1802 else
1803 address = base - imm32;
1804
1805 context.SetRegisterPlusOffset(pc_reg, address - base);
1806 data = MemURead(context, address, 4, 0, &success);
1807 if (!success)
1808 return false;
1809
1810 if (Rt == 15) {
1811 if (Bits32(address, 1, 0) == 0) {
1812 // In ARMv5T and above, this is an interworking branch.
1813 if (!LoadWritePC(context, data))
1814 return false;
1815 } else
1816 return false;
1817 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1818 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
1819 data))
1820 return false;
1821 } else // We don't handle ARM for now.
1822 return false;
1823 }
1824 return true;
1825 }
1826
1827 // An add operation to adjust the SP.
1828 // ADD (SP plus immediate)
EmulateADDSPImm(const uint32_t opcode,const ARMEncoding encoding)1829 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
1830 const ARMEncoding encoding) {
1831 #if 0
1832 // ARM pseudo code...
1833 if (ConditionPassed())
1834 {
1835 EncodingSpecificOperations();
1836 (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1837 if d == 15 then // Can only occur for ARM encoding
1838 ALUWritePC(result); // setflags is always FALSE here
1839 else
1840 R[d] = result;
1841 if setflags then
1842 APSR.N = result<31>;
1843 APSR.Z = IsZeroBit(result);
1844 APSR.C = carry;
1845 APSR.V = overflow;
1846 }
1847 #endif
1848
1849 bool success = false;
1850
1851 if (ConditionPassed(opcode)) {
1852 const addr_t sp = ReadCoreReg(SP_REG, &success);
1853 if (!success)
1854 return false;
1855 uint32_t imm32; // the immediate operand
1856 uint32_t d;
1857 bool setflags;
1858 switch (encoding) {
1859 case eEncodingT1:
1860 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1861 d = Bits32(opcode, 10, 8);
1862 imm32 = (Bits32(opcode, 7, 0) << 2);
1863 setflags = false;
1864 break;
1865
1866 case eEncodingT2:
1867 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1868 d = 13;
1869 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1870 setflags = false;
1871 break;
1872
1873 case eEncodingT3:
1874 // d = UInt(Rd); setflags = (S == "1"); imm32 =
1875 // ThumbExpandImm(i:imm3:imm8);
1876 d = Bits32(opcode, 11, 8);
1877 imm32 = ThumbExpandImm(opcode);
1878 setflags = Bit32(opcode, 20);
1879
1880 // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1881 if (d == 15 && setflags == 1)
1882 return false; // CMN (immediate) not yet supported
1883
1884 // if d == 15 && S == "0" then UNPREDICTABLE;
1885 if (d == 15 && setflags == 0)
1886 return false;
1887 break;
1888
1889 case eEncodingT4: {
1890 // if Rn == '1111' then SEE ADR;
1891 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1892 d = Bits32(opcode, 11, 8);
1893 setflags = false;
1894 uint32_t i = Bit32(opcode, 26);
1895 uint32_t imm3 = Bits32(opcode, 14, 12);
1896 uint32_t imm8 = Bits32(opcode, 7, 0);
1897 imm32 = (i << 11) | (imm3 << 8) | imm8;
1898
1899 // if d == 15 then UNPREDICTABLE;
1900 if (d == 15)
1901 return false;
1902 } break;
1903
1904 default:
1905 return false;
1906 }
1907 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1908 AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1909
1910 EmulateInstruction::Context context;
1911 if (d == 13)
1912 context.type = EmulateInstruction::eContextAdjustStackPointer;
1913 else
1914 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1915
1916 RegisterInfo sp_reg;
1917 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1918 context.SetRegisterPlusOffset(sp_reg, res.result - sp);
1919
1920 if (d == 15) {
1921 if (!ALUWritePC(context, res.result))
1922 return false;
1923 } else {
1924 // R[d] = result;
1925 // if setflags then
1926 // APSR.N = result<31>;
1927 // APSR.Z = IsZeroBit(result);
1928 // APSR.C = carry;
1929 // APSR.V = overflow;
1930 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1931 res.carry_out, res.overflow))
1932 return false;
1933 }
1934 }
1935 return true;
1936 }
1937
1938 // An add operation to adjust the SP.
1939 // ADD (SP plus register)
EmulateADDSPRm(const uint32_t opcode,const ARMEncoding encoding)1940 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1941 const ARMEncoding encoding) {
1942 #if 0
1943 // ARM pseudo code...
1944 if (ConditionPassed())
1945 {
1946 EncodingSpecificOperations();
1947 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1948 (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1949 if d == 15 then
1950 ALUWritePC(result); // setflags is always FALSE here
1951 else
1952 R[d] = result;
1953 if setflags then
1954 APSR.N = result<31>;
1955 APSR.Z = IsZeroBit(result);
1956 APSR.C = carry;
1957 APSR.V = overflow;
1958 }
1959 #endif
1960
1961 bool success = false;
1962
1963 if (ConditionPassed(opcode)) {
1964 const addr_t sp = ReadCoreReg(SP_REG, &success);
1965 if (!success)
1966 return false;
1967 uint32_t Rm; // the second operand
1968 switch (encoding) {
1969 case eEncodingT2:
1970 Rm = Bits32(opcode, 6, 3);
1971 break;
1972 default:
1973 return false;
1974 }
1975 int32_t reg_value = ReadCoreReg(Rm, &success);
1976 if (!success)
1977 return false;
1978
1979 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1980
1981 EmulateInstruction::Context context;
1982 context.type = eContextArithmetic;
1983 RegisterInfo sp_reg;
1984 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1985
1986 RegisterInfo other_reg;
1987 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1988 context.SetRegisterRegisterOperands(sp_reg, other_reg);
1989
1990 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1991 LLDB_REGNUM_GENERIC_SP, addr))
1992 return false;
1993 }
1994 return true;
1995 }
1996
1997 // Branch with Link and Exchange Instruction Sets (immediate) calls a
1998 // subroutine at a PC-relative address, and changes instruction set from ARM to
1999 // Thumb, or from Thumb to ARM.
2000 // BLX (immediate)
EmulateBLXImmediate(const uint32_t opcode,const ARMEncoding encoding)2001 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
2002 const ARMEncoding encoding) {
2003 #if 0
2004 // ARM pseudo code...
2005 if (ConditionPassed())
2006 {
2007 EncodingSpecificOperations();
2008 if CurrentInstrSet() == InstrSet_ARM then
2009 LR = PC - 4;
2010 else
2011 LR = PC<31:1> : '1';
2012 if targetInstrSet == InstrSet_ARM then
2013 targetAddress = Align(PC,4) + imm32;
2014 else
2015 targetAddress = PC + imm32;
2016 SelectInstrSet(targetInstrSet);
2017 BranchWritePC(targetAddress);
2018 }
2019 #endif
2020
2021 bool success = true;
2022
2023 if (ConditionPassed(opcode)) {
2024 EmulateInstruction::Context context;
2025 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2026 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2027 if (!success)
2028 return false;
2029 addr_t lr; // next instruction address
2030 addr_t target; // target address
2031 int32_t imm32; // PC-relative offset
2032 switch (encoding) {
2033 case eEncodingT1: {
2034 lr = pc | 1u; // return address
2035 uint32_t S = Bit32(opcode, 26);
2036 uint32_t imm10 = Bits32(opcode, 25, 16);
2037 uint32_t J1 = Bit32(opcode, 13);
2038 uint32_t J2 = Bit32(opcode, 11);
2039 uint32_t imm11 = Bits32(opcode, 10, 0);
2040 uint32_t I1 = !(J1 ^ S);
2041 uint32_t I2 = !(J2 ^ S);
2042 uint32_t imm25 =
2043 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2044 imm32 = llvm::SignExtend32<25>(imm25);
2045 target = pc + imm32;
2046 SelectInstrSet(eModeThumb);
2047 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2048 if (InITBlock() && !LastInITBlock())
2049 return false;
2050 break;
2051 }
2052 case eEncodingT2: {
2053 lr = pc | 1u; // return address
2054 uint32_t S = Bit32(opcode, 26);
2055 uint32_t imm10H = Bits32(opcode, 25, 16);
2056 uint32_t J1 = Bit32(opcode, 13);
2057 uint32_t J2 = Bit32(opcode, 11);
2058 uint32_t imm10L = Bits32(opcode, 10, 1);
2059 uint32_t I1 = !(J1 ^ S);
2060 uint32_t I2 = !(J2 ^ S);
2061 uint32_t imm25 =
2062 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2063 imm32 = llvm::SignExtend32<25>(imm25);
2064 target = Align(pc, 4) + imm32;
2065 SelectInstrSet(eModeARM);
2066 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
2067 if (InITBlock() && !LastInITBlock())
2068 return false;
2069 break;
2070 }
2071 case eEncodingA1:
2072 lr = pc - 4; // return address
2073 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2074 target = Align(pc, 4) + imm32;
2075 SelectInstrSet(eModeARM);
2076 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2077 break;
2078 case eEncodingA2:
2079 lr = pc - 4; // return address
2080 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
2081 Bits32(opcode, 24, 24) << 1);
2082 target = pc + imm32;
2083 SelectInstrSet(eModeThumb);
2084 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
2085 break;
2086 default:
2087 return false;
2088 }
2089 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2090 LLDB_REGNUM_GENERIC_RA, lr))
2091 return false;
2092 if (!BranchWritePC(context, target))
2093 return false;
2094 if (m_opcode_cpsr != m_new_inst_cpsr)
2095 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2096 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
2097 return false;
2098 }
2099 return true;
2100 }
2101
2102 // Branch with Link and Exchange (register) calls a subroutine at an address
2103 // and instruction set specified by a register.
2104 // BLX (register)
EmulateBLXRm(const uint32_t opcode,const ARMEncoding encoding)2105 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
2106 const ARMEncoding encoding) {
2107 #if 0
2108 // ARM pseudo code...
2109 if (ConditionPassed())
2110 {
2111 EncodingSpecificOperations();
2112 target = R[m];
2113 if CurrentInstrSet() == InstrSet_ARM then
2114 next_instr_addr = PC - 4;
2115 LR = next_instr_addr;
2116 else
2117 next_instr_addr = PC - 2;
2118 LR = next_instr_addr<31:1> : '1';
2119 BXWritePC(target);
2120 }
2121 #endif
2122
2123 bool success = false;
2124
2125 if (ConditionPassed(opcode)) {
2126 EmulateInstruction::Context context;
2127 context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2128 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2129 addr_t lr; // next instruction address
2130 if (!success)
2131 return false;
2132 uint32_t Rm; // the register with the target address
2133 switch (encoding) {
2134 case eEncodingT1:
2135 lr = (pc - 2) | 1u; // return address
2136 Rm = Bits32(opcode, 6, 3);
2137 // if m == 15 then UNPREDICTABLE;
2138 if (Rm == 15)
2139 return false;
2140 if (InITBlock() && !LastInITBlock())
2141 return false;
2142 break;
2143 case eEncodingA1:
2144 lr = pc - 4; // return address
2145 Rm = Bits32(opcode, 3, 0);
2146 // if m == 15 then UNPREDICTABLE;
2147 if (Rm == 15)
2148 return false;
2149 break;
2150 default:
2151 return false;
2152 }
2153 addr_t target = ReadCoreReg(Rm, &success);
2154 if (!success)
2155 return false;
2156 RegisterInfo dwarf_reg;
2157 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2158 context.SetRegister(dwarf_reg);
2159 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2160 LLDB_REGNUM_GENERIC_RA, lr))
2161 return false;
2162 if (!BXWritePC(context, target))
2163 return false;
2164 }
2165 return true;
2166 }
2167
2168 // Branch and Exchange causes a branch to an address and instruction set
2169 // specified by a register.
EmulateBXRm(const uint32_t opcode,const ARMEncoding encoding)2170 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
2171 const ARMEncoding encoding) {
2172 #if 0
2173 // ARM pseudo code...
2174 if (ConditionPassed())
2175 {
2176 EncodingSpecificOperations();
2177 BXWritePC(R[m]);
2178 }
2179 #endif
2180
2181 if (ConditionPassed(opcode)) {
2182 EmulateInstruction::Context context;
2183 context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2184 uint32_t Rm; // the register with the target address
2185 switch (encoding) {
2186 case eEncodingT1:
2187 Rm = Bits32(opcode, 6, 3);
2188 if (InITBlock() && !LastInITBlock())
2189 return false;
2190 break;
2191 case eEncodingA1:
2192 Rm = Bits32(opcode, 3, 0);
2193 break;
2194 default:
2195 return false;
2196 }
2197 bool success = false;
2198 addr_t target = ReadCoreReg(Rm, &success);
2199 if (!success)
2200 return false;
2201
2202 RegisterInfo dwarf_reg;
2203 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2204 context.SetRegister(dwarf_reg);
2205 if (!BXWritePC(context, target))
2206 return false;
2207 }
2208 return true;
2209 }
2210
2211 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the
2212 // attempt fails, it branches to an address and instruction set specified by a
2213 // register as though it were a BX instruction.
2214 //
2215 // TODO: Emulate Jazelle architecture?
2216 // We currently assume that switching to Jazelle state fails, thus
2217 // treating BXJ as a BX operation.
EmulateBXJRm(const uint32_t opcode,const ARMEncoding encoding)2218 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
2219 const ARMEncoding encoding) {
2220 #if 0
2221 // ARM pseudo code...
2222 if (ConditionPassed())
2223 {
2224 EncodingSpecificOperations();
2225 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
2226 BXWritePC(R[m]);
2227 else
2228 if JazelleAcceptsExecution() then
2229 SwitchToJazelleExecution();
2230 else
2231 SUBARCHITECTURE_DEFINED handler call;
2232 }
2233 #endif
2234
2235 if (ConditionPassed(opcode)) {
2236 EmulateInstruction::Context context;
2237 context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2238 uint32_t Rm; // the register with the target address
2239 switch (encoding) {
2240 case eEncodingT1:
2241 Rm = Bits32(opcode, 19, 16);
2242 if (BadReg(Rm))
2243 return false;
2244 if (InITBlock() && !LastInITBlock())
2245 return false;
2246 break;
2247 case eEncodingA1:
2248 Rm = Bits32(opcode, 3, 0);
2249 if (Rm == 15)
2250 return false;
2251 break;
2252 default:
2253 return false;
2254 }
2255 bool success = false;
2256 addr_t target = ReadCoreReg(Rm, &success);
2257 if (!success)
2258 return false;
2259
2260 RegisterInfo dwarf_reg;
2261 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2262 context.SetRegister(dwarf_reg);
2263 if (!BXWritePC(context, target))
2264 return false;
2265 }
2266 return true;
2267 }
2268
2269 // Set r7 to point to some ip offset.
2270 // SUB (immediate)
EmulateSUBR7IPImm(const uint32_t opcode,const ARMEncoding encoding)2271 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
2272 const ARMEncoding encoding) {
2273 #if 0
2274 // ARM pseudo code...
2275 if (ConditionPassed())
2276 {
2277 EncodingSpecificOperations();
2278 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2279 if d == 15 then // Can only occur for ARM encoding
2280 ALUWritePC(result); // setflags is always FALSE here
2281 else
2282 R[d] = result;
2283 if setflags then
2284 APSR.N = result<31>;
2285 APSR.Z = IsZeroBit(result);
2286 APSR.C = carry;
2287 APSR.V = overflow;
2288 }
2289 #endif
2290
2291 if (ConditionPassed(opcode)) {
2292 bool success = false;
2293 const addr_t ip = ReadCoreReg(12, &success);
2294 if (!success)
2295 return false;
2296 uint32_t imm32;
2297 switch (encoding) {
2298 case eEncodingA1:
2299 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2300 break;
2301 default:
2302 return false;
2303 }
2304 addr_t ip_offset = imm32;
2305 addr_t addr = ip - ip_offset; // the adjusted ip value
2306
2307 EmulateInstruction::Context context;
2308 context.type = EmulateInstruction::eContextRegisterPlusOffset;
2309 RegisterInfo dwarf_reg;
2310 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg);
2311 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset);
2312
2313 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
2314 return false;
2315 }
2316 return true;
2317 }
2318
2319 // Set ip to point to some stack offset.
2320 // SUB (SP minus immediate)
EmulateSUBIPSPImm(const uint32_t opcode,const ARMEncoding encoding)2321 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
2322 const ARMEncoding encoding) {
2323 #if 0
2324 // ARM pseudo code...
2325 if (ConditionPassed())
2326 {
2327 EncodingSpecificOperations();
2328 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2329 if d == 15 then // Can only occur for ARM encoding
2330 ALUWritePC(result); // setflags is always FALSE here
2331 else
2332 R[d] = result;
2333 if setflags then
2334 APSR.N = result<31>;
2335 APSR.Z = IsZeroBit(result);
2336 APSR.C = carry;
2337 APSR.V = overflow;
2338 }
2339 #endif
2340
2341 if (ConditionPassed(opcode)) {
2342 bool success = false;
2343 const addr_t sp = ReadCoreReg(SP_REG, &success);
2344 if (!success)
2345 return false;
2346 uint32_t imm32;
2347 switch (encoding) {
2348 case eEncodingA1:
2349 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2350 break;
2351 default:
2352 return false;
2353 }
2354 addr_t sp_offset = imm32;
2355 addr_t addr = sp - sp_offset; // the adjusted stack pointer value
2356
2357 EmulateInstruction::Context context;
2358 context.type = EmulateInstruction::eContextRegisterPlusOffset;
2359 RegisterInfo dwarf_reg;
2360 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
2361 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset);
2362
2363 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
2364 return false;
2365 }
2366 return true;
2367 }
2368
2369 // This instruction subtracts an immediate value from the SP value, and writes
2370 // the result to the destination register.
2371 //
2372 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
2373 // storage.
EmulateSUBSPImm(const uint32_t opcode,const ARMEncoding encoding)2374 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
2375 const ARMEncoding encoding) {
2376 #if 0
2377 // ARM pseudo code...
2378 if (ConditionPassed())
2379 {
2380 EncodingSpecificOperations();
2381 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2382 if d == 15 then // Can only occur for ARM encoding
2383 ALUWritePC(result); // setflags is always FALSE here
2384 else
2385 R[d] = result;
2386 if setflags then
2387 APSR.N = result<31>;
2388 APSR.Z = IsZeroBit(result);
2389 APSR.C = carry;
2390 APSR.V = overflow;
2391 }
2392 #endif
2393
2394 bool success = false;
2395 if (ConditionPassed(opcode)) {
2396 const addr_t sp = ReadCoreReg(SP_REG, &success);
2397 if (!success)
2398 return false;
2399
2400 uint32_t Rd;
2401 bool setflags;
2402 uint32_t imm32;
2403 switch (encoding) {
2404 case eEncodingT1:
2405 Rd = 13;
2406 setflags = false;
2407 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
2408 break;
2409 case eEncodingT2:
2410 Rd = Bits32(opcode, 11, 8);
2411 setflags = BitIsSet(opcode, 20);
2412 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2413 if (Rd == 15 && setflags)
2414 return EmulateCMPImm(opcode, eEncodingT2);
2415 if (Rd == 15 && !setflags)
2416 return false;
2417 break;
2418 case eEncodingT3:
2419 Rd = Bits32(opcode, 11, 8);
2420 setflags = false;
2421 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
2422 if (Rd == 15)
2423 return false;
2424 break;
2425 case eEncodingA1:
2426 Rd = Bits32(opcode, 15, 12);
2427 setflags = BitIsSet(opcode, 20);
2428 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2429
2430 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
2431 // instructions;
2432 if (Rd == 15 && setflags)
2433 return EmulateSUBSPcLrEtc(opcode, encoding);
2434 break;
2435 default:
2436 return false;
2437 }
2438 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
2439
2440 EmulateInstruction::Context context;
2441 if (Rd == 13) {
2442 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
2443 // to negate it, or the wrong
2444 // value gets passed down to context.SetImmediateSigned.
2445 context.type = EmulateInstruction::eContextAdjustStackPointer;
2446 context.SetImmediateSigned(-imm64); // the stack pointer offset
2447 } else {
2448 context.type = EmulateInstruction::eContextImmediate;
2449 context.SetNoArgs();
2450 }
2451
2452 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2453 res.carry_out, res.overflow))
2454 return false;
2455 }
2456 return true;
2457 }
2458
2459 // A store operation to the stack that also updates the SP.
EmulateSTRRtSP(const uint32_t opcode,const ARMEncoding encoding)2460 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
2461 const ARMEncoding encoding) {
2462 #if 0
2463 // ARM pseudo code...
2464 if (ConditionPassed())
2465 {
2466 EncodingSpecificOperations();
2467 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2468 address = if index then offset_addr else R[n];
2469 MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
2470 if wback then R[n] = offset_addr;
2471 }
2472 #endif
2473
2474 bool success = false;
2475 if (ConditionPassed(opcode)) {
2476 const uint32_t addr_byte_size = GetAddressByteSize();
2477 const addr_t sp = ReadCoreReg(SP_REG, &success);
2478 if (!success)
2479 return false;
2480 uint32_t Rt; // the source register
2481 uint32_t imm12;
2482 uint32_t
2483 Rn; // This function assumes Rn is the SP, but we should verify that.
2484
2485 bool index;
2486 bool add;
2487 bool wback;
2488 switch (encoding) {
2489 case eEncodingA1:
2490 Rt = Bits32(opcode, 15, 12);
2491 imm12 = Bits32(opcode, 11, 0);
2492 Rn = Bits32(opcode, 19, 16);
2493
2494 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP.
2495 return false;
2496
2497 index = BitIsSet(opcode, 24);
2498 add = BitIsSet(opcode, 23);
2499 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
2500
2501 if (wback && ((Rn == 15) || (Rn == Rt)))
2502 return false;
2503 break;
2504 default:
2505 return false;
2506 }
2507 addr_t offset_addr;
2508 if (add)
2509 offset_addr = sp + imm12;
2510 else
2511 offset_addr = sp - imm12;
2512
2513 addr_t addr;
2514 if (index)
2515 addr = offset_addr;
2516 else
2517 addr = sp;
2518
2519 EmulateInstruction::Context context;
2520 context.type = EmulateInstruction::eContextPushRegisterOnStack;
2521 RegisterInfo sp_reg;
2522 RegisterInfo dwarf_reg;
2523
2524 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2525 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2526 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2527 if (Rt != 15) {
2528 uint32_t reg_value = ReadCoreReg(Rt, &success);
2529 if (!success)
2530 return false;
2531 if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2532 return false;
2533 } else {
2534 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2535 if (!success)
2536 return false;
2537 if (!MemUWrite(context, addr, pc, addr_byte_size))
2538 return false;
2539 }
2540
2541 if (wback) {
2542 context.type = EmulateInstruction::eContextAdjustStackPointer;
2543 context.SetImmediateSigned(addr - sp);
2544 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2545 LLDB_REGNUM_GENERIC_SP, offset_addr))
2546 return false;
2547 }
2548 }
2549 return true;
2550 }
2551
2552 // Vector Push stores multiple extension registers to the stack. It also
2553 // updates SP to point to the start of the stored data.
EmulateVPUSH(const uint32_t opcode,const ARMEncoding encoding)2554 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2555 const ARMEncoding encoding) {
2556 #if 0
2557 // ARM pseudo code...
2558 if (ConditionPassed())
2559 {
2560 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2561 address = SP - imm32;
2562 SP = SP - imm32;
2563 if single_regs then
2564 for r = 0 to regs-1
2565 MemA[address,4] = S[d+r]; address = address+4;
2566 else
2567 for r = 0 to regs-1
2568 // Store as two word-aligned words in the correct order for
2569 // current endianness.
2570 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2571 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2572 address = address+8;
2573 }
2574 #endif
2575
2576 bool success = false;
2577 if (ConditionPassed(opcode)) {
2578 const uint32_t addr_byte_size = GetAddressByteSize();
2579 const addr_t sp = ReadCoreReg(SP_REG, &success);
2580 if (!success)
2581 return false;
2582 bool single_regs;
2583 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
2584 uint32_t imm32; // stack offset
2585 uint32_t regs; // number of registers
2586 switch (encoding) {
2587 case eEncodingT1:
2588 case eEncodingA1:
2589 single_regs = false;
2590 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2591 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2592 // If UInt(imm8) is odd, see "FSTMX".
2593 regs = Bits32(opcode, 7, 0) / 2;
2594 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2595 if (regs == 0 || regs > 16 || (d + regs) > 32)
2596 return false;
2597 break;
2598 case eEncodingT2:
2599 case eEncodingA2:
2600 single_regs = true;
2601 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2602 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2603 regs = Bits32(opcode, 7, 0);
2604 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2605 if (regs == 0 || regs > 16 || (d + regs) > 32)
2606 return false;
2607 break;
2608 default:
2609 return false;
2610 }
2611 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2612 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2613 addr_t sp_offset = imm32;
2614 addr_t addr = sp - sp_offset;
2615 uint32_t i;
2616
2617 EmulateInstruction::Context context;
2618 context.type = EmulateInstruction::eContextPushRegisterOnStack;
2619
2620 RegisterInfo dwarf_reg;
2621 RegisterInfo sp_reg;
2622 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2623 for (i = 0; i < regs; ++i) {
2624 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2625 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2626 // uint64_t to accommodate 64-bit registers.
2627 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success);
2628 if (!success)
2629 return false;
2630 if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2631 return false;
2632 addr += reg_byte_size;
2633 }
2634
2635 context.type = EmulateInstruction::eContextAdjustStackPointer;
2636 context.SetImmediateSigned(-sp_offset);
2637
2638 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2639 LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2640 return false;
2641 }
2642 return true;
2643 }
2644
2645 // Vector Pop loads multiple extension registers from the stack. It also
2646 // updates SP to point just above the loaded data.
EmulateVPOP(const uint32_t opcode,const ARMEncoding encoding)2647 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2648 const ARMEncoding encoding) {
2649 #if 0
2650 // ARM pseudo code...
2651 if (ConditionPassed())
2652 {
2653 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2654 address = SP;
2655 SP = SP + imm32;
2656 if single_regs then
2657 for r = 0 to regs-1
2658 S[d+r] = MemA[address,4]; address = address+4;
2659 else
2660 for r = 0 to regs-1
2661 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2662 // Combine the word-aligned words in the correct order for
2663 // current endianness.
2664 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2665 }
2666 #endif
2667
2668 bool success = false;
2669 if (ConditionPassed(opcode)) {
2670 const uint32_t addr_byte_size = GetAddressByteSize();
2671 const addr_t sp = ReadCoreReg(SP_REG, &success);
2672 if (!success)
2673 return false;
2674 bool single_regs;
2675 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
2676 uint32_t imm32; // stack offset
2677 uint32_t regs; // number of registers
2678 switch (encoding) {
2679 case eEncodingT1:
2680 case eEncodingA1:
2681 single_regs = false;
2682 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2683 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2684 // If UInt(imm8) is odd, see "FLDMX".
2685 regs = Bits32(opcode, 7, 0) / 2;
2686 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2687 if (regs == 0 || regs > 16 || (d + regs) > 32)
2688 return false;
2689 break;
2690 case eEncodingT2:
2691 case eEncodingA2:
2692 single_regs = true;
2693 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2694 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2695 regs = Bits32(opcode, 7, 0);
2696 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2697 if (regs == 0 || regs > 16 || (d + regs) > 32)
2698 return false;
2699 break;
2700 default:
2701 return false;
2702 }
2703 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2704 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2705 addr_t sp_offset = imm32;
2706 addr_t addr = sp;
2707 uint32_t i;
2708 uint64_t data; // uint64_t to accommodate 64-bit registers.
2709
2710 EmulateInstruction::Context context;
2711 context.type = EmulateInstruction::eContextPopRegisterOffStack;
2712
2713 RegisterInfo dwarf_reg;
2714 RegisterInfo sp_reg;
2715 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2716 for (i = 0; i < regs; ++i) {
2717 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2718 context.SetAddress(addr);
2719 data = MemARead(context, addr, reg_byte_size, 0, &success);
2720 if (!success)
2721 return false;
2722 if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2723 return false;
2724 addr += reg_byte_size;
2725 }
2726
2727 context.type = EmulateInstruction::eContextAdjustStackPointer;
2728 context.SetImmediateSigned(sp_offset);
2729
2730 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2731 LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2732 return false;
2733 }
2734 return true;
2735 }
2736
2737 // SVC (previously SWI)
EmulateSVC(const uint32_t opcode,const ARMEncoding encoding)2738 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2739 const ARMEncoding encoding) {
2740 #if 0
2741 // ARM pseudo code...
2742 if (ConditionPassed())
2743 {
2744 EncodingSpecificOperations();
2745 CallSupervisor();
2746 }
2747 #endif
2748
2749 bool success = false;
2750
2751 if (ConditionPassed(opcode)) {
2752 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2753 addr_t lr; // next instruction address
2754 if (!success)
2755 return false;
2756 uint32_t imm32; // the immediate constant
2757 uint32_t mode; // ARM or Thumb mode
2758 switch (encoding) {
2759 case eEncodingT1:
2760 lr = (pc + 2) | 1u; // return address
2761 imm32 = Bits32(opcode, 7, 0);
2762 mode = eModeThumb;
2763 break;
2764 case eEncodingA1:
2765 lr = pc + 4; // return address
2766 imm32 = Bits32(opcode, 23, 0);
2767 mode = eModeARM;
2768 break;
2769 default:
2770 return false;
2771 }
2772
2773 EmulateInstruction::Context context;
2774 context.type = EmulateInstruction::eContextSupervisorCall;
2775 context.SetISAAndImmediate(mode, imm32);
2776 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2777 LLDB_REGNUM_GENERIC_RA, lr))
2778 return false;
2779 }
2780 return true;
2781 }
2782
2783 // If Then makes up to four following instructions (the IT block) conditional.
EmulateIT(const uint32_t opcode,const ARMEncoding encoding)2784 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2785 const ARMEncoding encoding) {
2786 #if 0
2787 // ARM pseudo code...
2788 EncodingSpecificOperations();
2789 ITSTATE.IT<7:0> = firstcond:mask;
2790 #endif
2791
2792 m_it_session.InitIT(Bits32(opcode, 7, 0));
2793 return true;
2794 }
2795
EmulateNop(const uint32_t opcode,const ARMEncoding encoding)2796 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2797 const ARMEncoding encoding) {
2798 // NOP, nothing to do...
2799 return true;
2800 }
2801
2802 // Branch causes a branch to a target address.
EmulateB(const uint32_t opcode,const ARMEncoding encoding)2803 bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2804 const ARMEncoding encoding) {
2805 #if 0
2806 // ARM pseudo code...
2807 if (ConditionPassed())
2808 {
2809 EncodingSpecificOperations();
2810 BranchWritePC(PC + imm32);
2811 }
2812 #endif
2813
2814 bool success = false;
2815
2816 if (ConditionPassed(opcode)) {
2817 EmulateInstruction::Context context;
2818 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2819 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2820 if (!success)
2821 return false;
2822 addr_t target; // target address
2823 int32_t imm32; // PC-relative offset
2824 switch (encoding) {
2825 case eEncodingT1:
2826 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2827 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2828 target = pc + imm32;
2829 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2830 break;
2831 case eEncodingT2:
2832 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2833 target = pc + imm32;
2834 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2835 break;
2836 case eEncodingT3:
2837 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2838 {
2839 if (Bits32(opcode, 25, 23) == 7)
2840 return false; // See Branches and miscellaneous control on page
2841 // A6-235.
2842
2843 uint32_t S = Bit32(opcode, 26);
2844 uint32_t imm6 = Bits32(opcode, 21, 16);
2845 uint32_t J1 = Bit32(opcode, 13);
2846 uint32_t J2 = Bit32(opcode, 11);
2847 uint32_t imm11 = Bits32(opcode, 10, 0);
2848 uint32_t imm21 =
2849 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2850 imm32 = llvm::SignExtend32<21>(imm21);
2851 target = pc + imm32;
2852 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2853 break;
2854 }
2855 case eEncodingT4: {
2856 uint32_t S = Bit32(opcode, 26);
2857 uint32_t imm10 = Bits32(opcode, 25, 16);
2858 uint32_t J1 = Bit32(opcode, 13);
2859 uint32_t J2 = Bit32(opcode, 11);
2860 uint32_t imm11 = Bits32(opcode, 10, 0);
2861 uint32_t I1 = !(J1 ^ S);
2862 uint32_t I2 = !(J2 ^ S);
2863 uint32_t imm25 =
2864 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2865 imm32 = llvm::SignExtend32<25>(imm25);
2866 target = pc + imm32;
2867 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2868 break;
2869 }
2870 case eEncodingA1:
2871 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2872 target = pc + imm32;
2873 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2874 break;
2875 default:
2876 return false;
2877 }
2878 if (!BranchWritePC(context, target))
2879 return false;
2880 }
2881 return true;
2882 }
2883
2884 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2885 // value in a register with zero and conditionally branch forward a constant
2886 // value. They do not affect the condition flags. CBNZ, CBZ
EmulateCB(const uint32_t opcode,const ARMEncoding encoding)2887 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2888 const ARMEncoding encoding) {
2889 #if 0
2890 // ARM pseudo code...
2891 EncodingSpecificOperations();
2892 if nonzero ^ IsZero(R[n]) then
2893 BranchWritePC(PC + imm32);
2894 #endif
2895
2896 bool success = false;
2897
2898 // Read the register value from the operand register Rn.
2899 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2900 if (!success)
2901 return false;
2902
2903 EmulateInstruction::Context context;
2904 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2905 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2906 if (!success)
2907 return false;
2908
2909 addr_t target; // target address
2910 uint32_t imm32; // PC-relative offset to branch forward
2911 bool nonzero;
2912 switch (encoding) {
2913 case eEncodingT1:
2914 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2915 nonzero = BitIsSet(opcode, 11);
2916 target = pc + imm32;
2917 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2918 break;
2919 default:
2920 return false;
2921 }
2922 if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2923 if (!BranchWritePC(context, target))
2924 return false;
2925
2926 return true;
2927 }
2928
2929 // Table Branch Byte causes a PC-relative forward branch using a table of
2930 // single byte 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 byte returned from the table.
2934 //
2935 // Table Branch Halfword causes a PC-relative forward branch using a table of
2936 // single halfword offsets.
2937 // A base register provides a pointer to the table, and a second register
2938 // supplies an index into the table.
2939 // The branch length is twice the value of the halfword returned from the
2940 // table. TBB, TBH
EmulateTB(const uint32_t opcode,const ARMEncoding encoding)2941 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2942 const ARMEncoding encoding) {
2943 #if 0
2944 // ARM pseudo code...
2945 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2946 if is_tbh then
2947 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2948 else
2949 halfwords = UInt(MemU[R[n]+R[m], 1]);
2950 BranchWritePC(PC + 2*halfwords);
2951 #endif
2952
2953 bool success = false;
2954
2955 if (ConditionPassed(opcode)) {
2956 uint32_t Rn; // the base register which contains the address of the table of
2957 // branch lengths
2958 uint32_t Rm; // the index register which contains an integer pointing to a
2959 // byte/halfword in the table
2960 bool is_tbh; // true if table branch halfword
2961 switch (encoding) {
2962 case eEncodingT1:
2963 Rn = Bits32(opcode, 19, 16);
2964 Rm = Bits32(opcode, 3, 0);
2965 is_tbh = BitIsSet(opcode, 4);
2966 if (Rn == 13 || BadReg(Rm))
2967 return false;
2968 if (InITBlock() && !LastInITBlock())
2969 return false;
2970 break;
2971 default:
2972 return false;
2973 }
2974
2975 // Read the address of the table from the operand register Rn. The PC can
2976 // be used, in which case the table immediately follows this instruction.
2977 uint32_t base = ReadCoreReg(Rn, &success);
2978 if (!success)
2979 return false;
2980
2981 // the table index
2982 uint32_t index = ReadCoreReg(Rm, &success);
2983 if (!success)
2984 return false;
2985
2986 // the offsetted table address
2987 addr_t addr = base + (is_tbh ? index * 2 : index);
2988
2989 // PC-relative offset to branch forward
2990 EmulateInstruction::Context context;
2991 context.type = EmulateInstruction::eContextTableBranchReadMemory;
2992 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2993 if (!success)
2994 return false;
2995
2996 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2997 if (!success)
2998 return false;
2999
3000 // target address
3001 addr_t target = pc + offset;
3002 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
3003 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
3004
3005 if (!BranchWritePC(context, target))
3006 return false;
3007 }
3008
3009 return true;
3010 }
3011
3012 // This instruction adds an immediate value to a register value, and writes the
3013 // result to the destination register. It can optionally update the condition
3014 // flags based on the result.
EmulateADDImmThumb(const uint32_t opcode,const ARMEncoding encoding)3015 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
3016 const ARMEncoding encoding) {
3017 #if 0
3018 if ConditionPassed() then
3019 EncodingSpecificOperations();
3020 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3021 R[d] = result;
3022 if setflags then
3023 APSR.N = result<31>;
3024 APSR.Z = IsZeroBit(result);
3025 APSR.C = carry;
3026 APSR.V = overflow;
3027 #endif
3028
3029 bool success = false;
3030
3031 if (ConditionPassed(opcode)) {
3032 uint32_t d;
3033 uint32_t n;
3034 bool setflags;
3035 uint32_t imm32;
3036 uint32_t carry_out;
3037
3038 // EncodingSpecificOperations();
3039 switch (encoding) {
3040 case eEncodingT1:
3041 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
3042 // ZeroExtend(imm3, 32);
3043 d = Bits32(opcode, 2, 0);
3044 n = Bits32(opcode, 5, 3);
3045 setflags = !InITBlock();
3046 imm32 = Bits32(opcode, 8, 6);
3047
3048 break;
3049
3050 case eEncodingT2:
3051 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
3052 // ZeroExtend(imm8, 32);
3053 d = Bits32(opcode, 10, 8);
3054 n = Bits32(opcode, 10, 8);
3055 setflags = !InITBlock();
3056 imm32 = Bits32(opcode, 7, 0);
3057
3058 break;
3059
3060 case eEncodingT3:
3061 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
3062 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
3063 // ThumbExpandImm(i:imm3:imm8);
3064 d = Bits32(opcode, 11, 8);
3065 n = Bits32(opcode, 19, 16);
3066 setflags = BitIsSet(opcode, 20);
3067 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
3068
3069 // if Rn == '1101' then SEE ADD (SP plus immediate);
3070 if (n == 13)
3071 return EmulateADDSPImm(opcode, eEncodingT3);
3072
3073 // if BadReg(d) || n == 15 then UNPREDICTABLE;
3074 if (BadReg(d) || (n == 15))
3075 return false;
3076
3077 break;
3078
3079 case eEncodingT4: {
3080 // if Rn == '1111' then SEE ADR;
3081 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
3082 // ZeroExtend(i:imm3:imm8, 32);
3083 d = Bits32(opcode, 11, 8);
3084 n = Bits32(opcode, 19, 16);
3085 setflags = false;
3086 uint32_t i = Bit32(opcode, 26);
3087 uint32_t imm3 = Bits32(opcode, 14, 12);
3088 uint32_t imm8 = Bits32(opcode, 7, 0);
3089 imm32 = (i << 11) | (imm3 << 8) | imm8;
3090
3091 // if Rn == '1101' then SEE ADD (SP plus immediate);
3092 if (n == 13)
3093 return EmulateADDSPImm(opcode, eEncodingT4);
3094
3095 // if BadReg(d) then UNPREDICTABLE;
3096 if (BadReg(d))
3097 return false;
3098
3099 break;
3100 }
3101
3102 default:
3103 return false;
3104 }
3105
3106 uint64_t Rn =
3107 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3108 if (!success)
3109 return false;
3110
3111 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3112 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
3113
3114 RegisterInfo reg_n;
3115 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
3116
3117 EmulateInstruction::Context context;
3118 context.type = eContextArithmetic;
3119 context.SetRegisterPlusOffset(reg_n, imm32);
3120
3121 // R[d] = result;
3122 // if setflags then
3123 // APSR.N = result<31>;
3124 // APSR.Z = IsZeroBit(result);
3125 // APSR.C = carry;
3126 // APSR.V = overflow;
3127 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
3128 res.carry_out, res.overflow))
3129 return false;
3130 }
3131 return true;
3132 }
3133
3134 // This instruction adds an immediate value to a register value, and writes the
3135 // result to the destination register. It can optionally update the condition
3136 // flags based on the result.
EmulateADDImmARM(const uint32_t opcode,const ARMEncoding encoding)3137 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
3138 const ARMEncoding encoding) {
3139 #if 0
3140 // ARM pseudo code...
3141 if ConditionPassed() then
3142 EncodingSpecificOperations();
3143 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3144 if d == 15 then
3145 ALUWritePC(result); // setflags is always FALSE here
3146 else
3147 R[d] = result;
3148 if setflags then
3149 APSR.N = result<31>;
3150 APSR.Z = IsZeroBit(result);
3151 APSR.C = carry;
3152 APSR.V = overflow;
3153 #endif
3154
3155 bool success = false;
3156
3157 if (ConditionPassed(opcode)) {
3158 uint32_t Rd, Rn;
3159 uint32_t
3160 imm32; // the immediate value to be added to the value obtained from Rn
3161 bool setflags;
3162 switch (encoding) {
3163 case eEncodingA1:
3164 Rd = Bits32(opcode, 15, 12);
3165 Rn = Bits32(opcode, 19, 16);
3166 setflags = BitIsSet(opcode, 20);
3167 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3168 break;
3169 default:
3170 return false;
3171 }
3172
3173 // Read the first operand.
3174 uint32_t val1 = ReadCoreReg(Rn, &success);
3175 if (!success)
3176 return false;
3177
3178 AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
3179
3180 EmulateInstruction::Context context;
3181 if (Rd == 13)
3182 context.type = EmulateInstruction::eContextAdjustStackPointer;
3183 else if (Rd == GetFramePointerRegisterNumber())
3184 context.type = EmulateInstruction::eContextSetFramePointer;
3185 else
3186 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3187
3188 RegisterInfo dwarf_reg;
3189 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
3190 context.SetRegisterPlusOffset(dwarf_reg, imm32);
3191
3192 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3193 res.carry_out, res.overflow))
3194 return false;
3195 }
3196 return true;
3197 }
3198
3199 // This instruction adds a register value and an optionally-shifted register
3200 // value, and writes the result to the destination register. It can optionally
3201 // update the condition flags based on the result.
EmulateADDReg(const uint32_t opcode,const ARMEncoding encoding)3202 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
3203 const ARMEncoding encoding) {
3204 #if 0
3205 // ARM pseudo code...
3206 if ConditionPassed() then
3207 EncodingSpecificOperations();
3208 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3209 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3210 if d == 15 then
3211 ALUWritePC(result); // setflags is always FALSE here
3212 else
3213 R[d] = result;
3214 if setflags then
3215 APSR.N = result<31>;
3216 APSR.Z = IsZeroBit(result);
3217 APSR.C = carry;
3218 APSR.V = overflow;
3219 #endif
3220
3221 bool success = false;
3222
3223 if (ConditionPassed(opcode)) {
3224 uint32_t Rd, Rn, Rm;
3225 ARM_ShifterType shift_t;
3226 uint32_t shift_n; // the shift applied to the value read from Rm
3227 bool setflags;
3228 switch (encoding) {
3229 case eEncodingT1:
3230 Rd = Bits32(opcode, 2, 0);
3231 Rn = Bits32(opcode, 5, 3);
3232 Rm = Bits32(opcode, 8, 6);
3233 setflags = !InITBlock();
3234 shift_t = SRType_LSL;
3235 shift_n = 0;
3236 break;
3237 case eEncodingT2:
3238 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3239 Rm = Bits32(opcode, 6, 3);
3240 setflags = false;
3241 shift_t = SRType_LSL;
3242 shift_n = 0;
3243 if (Rn == 15 && Rm == 15)
3244 return false;
3245 if (Rd == 15 && InITBlock() && !LastInITBlock())
3246 return false;
3247 break;
3248 case eEncodingA1:
3249 Rd = Bits32(opcode, 15, 12);
3250 Rn = Bits32(opcode, 19, 16);
3251 Rm = Bits32(opcode, 3, 0);
3252 setflags = BitIsSet(opcode, 20);
3253 shift_n = DecodeImmShiftARM(opcode, shift_t);
3254 break;
3255 default:
3256 return false;
3257 }
3258
3259 // Read the first operand.
3260 uint32_t val1 = ReadCoreReg(Rn, &success);
3261 if (!success)
3262 return false;
3263
3264 // Read the second operand.
3265 uint32_t val2 = ReadCoreReg(Rm, &success);
3266 if (!success)
3267 return false;
3268
3269 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3270 if (!success)
3271 return false;
3272 AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3273
3274 EmulateInstruction::Context context;
3275 context.type = eContextArithmetic;
3276 RegisterInfo op1_reg;
3277 RegisterInfo op2_reg;
3278 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
3279 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
3280 context.SetRegisterRegisterOperands(op1_reg, op2_reg);
3281
3282 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3283 res.carry_out, res.overflow))
3284 return false;
3285 }
3286 return true;
3287 }
3288
3289 // Compare Negative (immediate) adds a register value and an immediate value.
3290 // It updates the condition flags based on the result, and discards the result.
EmulateCMNImm(const uint32_t opcode,const ARMEncoding encoding)3291 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
3292 const ARMEncoding encoding) {
3293 #if 0
3294 // ARM pseudo code...
3295 if ConditionPassed() then
3296 EncodingSpecificOperations();
3297 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3298 APSR.N = result<31>;
3299 APSR.Z = IsZeroBit(result);
3300 APSR.C = carry;
3301 APSR.V = overflow;
3302 #endif
3303
3304 bool success = false;
3305
3306 uint32_t Rn; // the first operand
3307 uint32_t imm32; // the immediate value to be compared with
3308 switch (encoding) {
3309 case eEncodingT1:
3310 Rn = Bits32(opcode, 19, 16);
3311 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3312 if (Rn == 15)
3313 return false;
3314 break;
3315 case eEncodingA1:
3316 Rn = Bits32(opcode, 19, 16);
3317 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3318 break;
3319 default:
3320 return false;
3321 }
3322 // Read the register value from the operand register Rn.
3323 uint32_t reg_val = ReadCoreReg(Rn, &success);
3324 if (!success)
3325 return false;
3326
3327 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
3328
3329 EmulateInstruction::Context context;
3330 context.type = EmulateInstruction::eContextImmediate;
3331 context.SetNoArgs();
3332 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3333 }
3334
3335 // Compare Negative (register) adds a register value and an optionally-shifted
3336 // register value. It updates the condition flags based on the result, and
3337 // discards the result.
EmulateCMNReg(const uint32_t opcode,const ARMEncoding encoding)3338 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
3339 const ARMEncoding encoding) {
3340 #if 0
3341 // ARM pseudo code...
3342 if ConditionPassed() then
3343 EncodingSpecificOperations();
3344 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3345 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3346 APSR.N = result<31>;
3347 APSR.Z = IsZeroBit(result);
3348 APSR.C = carry;
3349 APSR.V = overflow;
3350 #endif
3351
3352 bool success = false;
3353
3354 uint32_t Rn; // the first operand
3355 uint32_t Rm; // the second operand
3356 ARM_ShifterType shift_t;
3357 uint32_t shift_n; // the shift applied to the value read from Rm
3358 switch (encoding) {
3359 case eEncodingT1:
3360 Rn = Bits32(opcode, 2, 0);
3361 Rm = Bits32(opcode, 5, 3);
3362 shift_t = SRType_LSL;
3363 shift_n = 0;
3364 break;
3365 case eEncodingT2:
3366 Rn = Bits32(opcode, 19, 16);
3367 Rm = Bits32(opcode, 3, 0);
3368 shift_n = DecodeImmShiftThumb(opcode, shift_t);
3369 // if n == 15 || BadReg(m) then UNPREDICTABLE;
3370 if (Rn == 15 || BadReg(Rm))
3371 return false;
3372 break;
3373 case eEncodingA1:
3374 Rn = Bits32(opcode, 19, 16);
3375 Rm = Bits32(opcode, 3, 0);
3376 shift_n = DecodeImmShiftARM(opcode, shift_t);
3377 break;
3378 default:
3379 return false;
3380 }
3381 // Read the register value from register Rn.
3382 uint32_t val1 = ReadCoreReg(Rn, &success);
3383 if (!success)
3384 return false;
3385
3386 // Read the register value from register Rm.
3387 uint32_t val2 = ReadCoreReg(Rm, &success);
3388 if (!success)
3389 return false;
3390
3391 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3392 if (!success)
3393 return false;
3394 AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3395
3396 EmulateInstruction::Context context;
3397 context.type = EmulateInstruction::eContextImmediate;
3398 context.SetNoArgs();
3399 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3400 }
3401
3402 // Compare (immediate) subtracts an immediate value from a register value. It
3403 // updates the condition flags based on the result, and discards the result.
EmulateCMPImm(const uint32_t opcode,const ARMEncoding encoding)3404 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
3405 const ARMEncoding encoding) {
3406 #if 0
3407 // ARM pseudo code...
3408 if ConditionPassed() then
3409 EncodingSpecificOperations();
3410 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
3411 APSR.N = result<31>;
3412 APSR.Z = IsZeroBit(result);
3413 APSR.C = carry;
3414 APSR.V = overflow;
3415 #endif
3416
3417 bool success = false;
3418
3419 uint32_t Rn; // the first operand
3420 uint32_t imm32; // the immediate value to be compared with
3421 switch (encoding) {
3422 case eEncodingT1:
3423 Rn = Bits32(opcode, 10, 8);
3424 imm32 = Bits32(opcode, 7, 0);
3425 break;
3426 case eEncodingT2:
3427 Rn = Bits32(opcode, 19, 16);
3428 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3429 if (Rn == 15)
3430 return false;
3431 break;
3432 case eEncodingA1:
3433 Rn = Bits32(opcode, 19, 16);
3434 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3435 break;
3436 default:
3437 return false;
3438 }
3439 // Read the register value from the operand register Rn.
3440 uint32_t reg_val = ReadCoreReg(Rn, &success);
3441 if (!success)
3442 return false;
3443
3444 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
3445
3446 EmulateInstruction::Context context;
3447 context.type = EmulateInstruction::eContextImmediate;
3448 context.SetNoArgs();
3449 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3450 }
3451
3452 // Compare (register) subtracts an optionally-shifted register value from a
3453 // register value. It updates the condition flags based on the result, and
3454 // discards the result.
EmulateCMPReg(const uint32_t opcode,const ARMEncoding encoding)3455 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
3456 const ARMEncoding encoding) {
3457 #if 0
3458 // ARM pseudo code...
3459 if ConditionPassed() then
3460 EncodingSpecificOperations();
3461 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3462 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
3463 APSR.N = result<31>;
3464 APSR.Z = IsZeroBit(result);
3465 APSR.C = carry;
3466 APSR.V = overflow;
3467 #endif
3468
3469 bool success = false;
3470
3471 uint32_t Rn; // the first operand
3472 uint32_t Rm; // the second operand
3473 ARM_ShifterType shift_t;
3474 uint32_t shift_n; // the shift applied to the value read from Rm
3475 switch (encoding) {
3476 case eEncodingT1:
3477 Rn = Bits32(opcode, 2, 0);
3478 Rm = Bits32(opcode, 5, 3);
3479 shift_t = SRType_LSL;
3480 shift_n = 0;
3481 break;
3482 case eEncodingT2:
3483 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3484 Rm = Bits32(opcode, 6, 3);
3485 shift_t = SRType_LSL;
3486 shift_n = 0;
3487 if (Rn < 8 && Rm < 8)
3488 return false;
3489 if (Rn == 15 || Rm == 15)
3490 return false;
3491 break;
3492 case eEncodingT3:
3493 Rn = Bits32(opcode, 19, 16);
3494 Rm = Bits32(opcode, 3, 0);
3495 shift_n = DecodeImmShiftThumb(opcode, shift_t);
3496 if (Rn == 15 || BadReg(Rm))
3497 return false;
3498 break;
3499 case eEncodingA1:
3500 Rn = Bits32(opcode, 19, 16);
3501 Rm = Bits32(opcode, 3, 0);
3502 shift_n = DecodeImmShiftARM(opcode, shift_t);
3503 break;
3504 default:
3505 return false;
3506 }
3507 // Read the register value from register Rn.
3508 uint32_t val1 = ReadCoreReg(Rn, &success);
3509 if (!success)
3510 return false;
3511
3512 // Read the register value from register Rm.
3513 uint32_t val2 = ReadCoreReg(Rm, &success);
3514 if (!success)
3515 return false;
3516
3517 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3518 if (!success)
3519 return false;
3520 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3521
3522 EmulateInstruction::Context context;
3523 context.type = EmulateInstruction::eContextImmediate;
3524 context.SetNoArgs();
3525 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3526 }
3527
3528 // Arithmetic Shift Right (immediate) shifts a register value right by an
3529 // immediate number of bits, shifting in copies of its sign bit, and writes the
3530 // result to the destination register. It can optionally update the condition
3531 // flags based on the result.
EmulateASRImm(const uint32_t opcode,const ARMEncoding encoding)3532 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3533 const ARMEncoding encoding) {
3534 #if 0
3535 // ARM pseudo code...
3536 if ConditionPassed() then
3537 EncodingSpecificOperations();
3538 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3539 if d == 15 then // Can only occur for ARM encoding
3540 ALUWritePC(result); // setflags is always FALSE here
3541 else
3542 R[d] = result;
3543 if setflags then
3544 APSR.N = result<31>;
3545 APSR.Z = IsZeroBit(result);
3546 APSR.C = carry;
3547 // APSR.V unchanged
3548 #endif
3549
3550 return EmulateShiftImm(opcode, encoding, SRType_ASR);
3551 }
3552
3553 // Arithmetic Shift Right (register) shifts a register value right by a
3554 // variable number of bits, shifting in copies of its sign bit, and writes the
3555 // result to the destination register. The variable number of bits is read from
3556 // the bottom byte of a register. It can optionally update the condition flags
3557 // based on the result.
EmulateASRReg(const uint32_t opcode,const ARMEncoding encoding)3558 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3559 const ARMEncoding encoding) {
3560 #if 0
3561 // ARM pseudo code...
3562 if ConditionPassed() then
3563 EncodingSpecificOperations();
3564 shift_n = UInt(R[m]<7:0>);
3565 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3566 R[d] = result;
3567 if setflags then
3568 APSR.N = result<31>;
3569 APSR.Z = IsZeroBit(result);
3570 APSR.C = carry;
3571 // APSR.V unchanged
3572 #endif
3573
3574 return EmulateShiftReg(opcode, encoding, SRType_ASR);
3575 }
3576
3577 // Logical Shift Left (immediate) shifts a register value left by an immediate
3578 // number of bits, shifting in zeros, and writes the result to the destination
3579 // register. It can optionally update the condition flags based on the result.
EmulateLSLImm(const uint32_t opcode,const ARMEncoding encoding)3580 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3581 const ARMEncoding encoding) {
3582 #if 0
3583 // ARM pseudo code...
3584 if ConditionPassed() then
3585 EncodingSpecificOperations();
3586 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3587 if d == 15 then // Can only occur for ARM encoding
3588 ALUWritePC(result); // setflags is always FALSE here
3589 else
3590 R[d] = result;
3591 if setflags then
3592 APSR.N = result<31>;
3593 APSR.Z = IsZeroBit(result);
3594 APSR.C = carry;
3595 // APSR.V unchanged
3596 #endif
3597
3598 return EmulateShiftImm(opcode, encoding, SRType_LSL);
3599 }
3600
3601 // Logical Shift Left (register) shifts a register value left by a variable
3602 // number of bits, shifting in zeros, and writes the result to the destination
3603 // register. The variable number of bits is read from the bottom byte of a
3604 // register. It can optionally update the condition flags based on the result.
EmulateLSLReg(const uint32_t opcode,const ARMEncoding encoding)3605 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3606 const ARMEncoding encoding) {
3607 #if 0
3608 // ARM pseudo code...
3609 if ConditionPassed() then
3610 EncodingSpecificOperations();
3611 shift_n = UInt(R[m]<7:0>);
3612 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3613 R[d] = result;
3614 if setflags then
3615 APSR.N = result<31>;
3616 APSR.Z = IsZeroBit(result);
3617 APSR.C = carry;
3618 // APSR.V unchanged
3619 #endif
3620
3621 return EmulateShiftReg(opcode, encoding, SRType_LSL);
3622 }
3623
3624 // Logical Shift Right (immediate) shifts a register value right by an
3625 // immediate number of bits, shifting in zeros, and writes the result to the
3626 // destination register. It can optionally update the condition flags based on
3627 // the result.
EmulateLSRImm(const uint32_t opcode,const ARMEncoding encoding)3628 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3629 const ARMEncoding encoding) {
3630 #if 0
3631 // ARM pseudo code...
3632 if ConditionPassed() then
3633 EncodingSpecificOperations();
3634 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3635 if d == 15 then // Can only occur for ARM encoding
3636 ALUWritePC(result); // setflags is always FALSE here
3637 else
3638 R[d] = result;
3639 if setflags then
3640 APSR.N = result<31>;
3641 APSR.Z = IsZeroBit(result);
3642 APSR.C = carry;
3643 // APSR.V unchanged
3644 #endif
3645
3646 return EmulateShiftImm(opcode, encoding, SRType_LSR);
3647 }
3648
3649 // Logical Shift Right (register) shifts a register value right by a variable
3650 // number of bits, shifting in zeros, and writes the result to the destination
3651 // register. The variable number of bits is read from the bottom byte of a
3652 // register. It can optionally update the condition flags based on the result.
EmulateLSRReg(const uint32_t opcode,const ARMEncoding encoding)3653 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3654 const ARMEncoding encoding) {
3655 #if 0
3656 // ARM pseudo code...
3657 if ConditionPassed() then
3658 EncodingSpecificOperations();
3659 shift_n = UInt(R[m]<7:0>);
3660 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3661 R[d] = result;
3662 if setflags then
3663 APSR.N = result<31>;
3664 APSR.Z = IsZeroBit(result);
3665 APSR.C = carry;
3666 // APSR.V unchanged
3667 #endif
3668
3669 return EmulateShiftReg(opcode, encoding, SRType_LSR);
3670 }
3671
3672 // Rotate Right (immediate) provides the value of the contents of a register
3673 // rotated by a constant value. The bits that are rotated off the right end are
3674 // inserted into the vacated bit positions on the left. It can optionally
3675 // update the condition flags based on the result.
EmulateRORImm(const uint32_t opcode,const ARMEncoding encoding)3676 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3677 const ARMEncoding encoding) {
3678 #if 0
3679 // ARM pseudo code...
3680 if ConditionPassed() then
3681 EncodingSpecificOperations();
3682 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3683 if d == 15 then // Can only occur for ARM encoding
3684 ALUWritePC(result); // setflags is always FALSE here
3685 else
3686 R[d] = result;
3687 if setflags then
3688 APSR.N = result<31>;
3689 APSR.Z = IsZeroBit(result);
3690 APSR.C = carry;
3691 // APSR.V unchanged
3692 #endif
3693
3694 return EmulateShiftImm(opcode, encoding, SRType_ROR);
3695 }
3696
3697 // Rotate Right (register) provides the value of the contents of a register
3698 // rotated by a variable number of bits. The bits that are rotated off the
3699 // right end are inserted into the vacated bit positions on the left. The
3700 // variable number of bits is read from the bottom byte of a register. It can
3701 // optionally update the condition flags based on the result.
EmulateRORReg(const uint32_t opcode,const ARMEncoding encoding)3702 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3703 const ARMEncoding encoding) {
3704 #if 0
3705 // ARM pseudo code...
3706 if ConditionPassed() then
3707 EncodingSpecificOperations();
3708 shift_n = UInt(R[m]<7:0>);
3709 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3710 R[d] = result;
3711 if setflags then
3712 APSR.N = result<31>;
3713 APSR.Z = IsZeroBit(result);
3714 APSR.C = carry;
3715 // APSR.V unchanged
3716 #endif
3717
3718 return EmulateShiftReg(opcode, encoding, SRType_ROR);
3719 }
3720
3721 // Rotate Right with Extend provides the value of the contents of a register
3722 // shifted right by one place, with the carry flag shifted into bit [31].
3723 //
3724 // RRX can optionally update the condition flags based on the result.
3725 // In that case, bit [0] is shifted into the carry flag.
EmulateRRX(const uint32_t opcode,const ARMEncoding encoding)3726 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3727 const ARMEncoding encoding) {
3728 #if 0
3729 // ARM pseudo code...
3730 if ConditionPassed() then
3731 EncodingSpecificOperations();
3732 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3733 if d == 15 then // Can only occur for ARM encoding
3734 ALUWritePC(result); // setflags is always FALSE here
3735 else
3736 R[d] = result;
3737 if setflags then
3738 APSR.N = result<31>;
3739 APSR.Z = IsZeroBit(result);
3740 APSR.C = carry;
3741 // APSR.V unchanged
3742 #endif
3743
3744 return EmulateShiftImm(opcode, encoding, SRType_RRX);
3745 }
3746
EmulateShiftImm(const uint32_t opcode,const ARMEncoding encoding,ARM_ShifterType shift_type)3747 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
3748 const ARMEncoding encoding,
3749 ARM_ShifterType shift_type) {
3750 // assert(shift_type == SRType_ASR
3751 // || shift_type == SRType_LSL
3752 // || shift_type == SRType_LSR
3753 // || shift_type == SRType_ROR
3754 // || shift_type == SRType_RRX);
3755
3756 bool success = false;
3757
3758 if (ConditionPassed(opcode)) {
3759 uint32_t Rd; // the destination register
3760 uint32_t Rm; // the first operand register
3761 uint32_t imm5; // encoding for the shift amount
3762 uint32_t carry; // the carry bit after the shift operation
3763 bool setflags;
3764
3765 // Special case handling!
3766 // A8.6.139 ROR (immediate) -- Encoding T1
3767 ARMEncoding use_encoding = encoding;
3768 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3769 // Morph the T1 encoding from the ARM Architecture Manual into T2
3770 // encoding to have the same decoding of bit fields as the other Thumb2
3771 // shift operations.
3772 use_encoding = eEncodingT2;
3773 }
3774
3775 switch (use_encoding) {
3776 case eEncodingT1:
3777 // Due to the above special case handling!
3778 if (shift_type == SRType_ROR)
3779 return false;
3780
3781 Rd = Bits32(opcode, 2, 0);
3782 Rm = Bits32(opcode, 5, 3);
3783 setflags = !InITBlock();
3784 imm5 = Bits32(opcode, 10, 6);
3785 break;
3786 case eEncodingT2:
3787 // A8.6.141 RRX
3788 // There's no imm form of RRX instructions.
3789 if (shift_type == SRType_RRX)
3790 return false;
3791
3792 Rd = Bits32(opcode, 11, 8);
3793 Rm = Bits32(opcode, 3, 0);
3794 setflags = BitIsSet(opcode, 20);
3795 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3796 if (BadReg(Rd) || BadReg(Rm))
3797 return false;
3798 break;
3799 case eEncodingA1:
3800 Rd = Bits32(opcode, 15, 12);
3801 Rm = Bits32(opcode, 3, 0);
3802 setflags = BitIsSet(opcode, 20);
3803 imm5 = Bits32(opcode, 11, 7);
3804 break;
3805 default:
3806 return false;
3807 }
3808
3809 // A8.6.139 ROR (immediate)
3810 if (shift_type == SRType_ROR && imm5 == 0)
3811 shift_type = SRType_RRX;
3812
3813 // Get the first operand.
3814 uint32_t value = ReadCoreReg(Rm, &success);
3815 if (!success)
3816 return false;
3817
3818 // Decode the shift amount if not RRX.
3819 uint32_t amt =
3820 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3821
3822 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3823 if (!success)
3824 return false;
3825
3826 // The context specifies that an immediate is to be moved into Rd.
3827 EmulateInstruction::Context context;
3828 context.type = EmulateInstruction::eContextImmediate;
3829 context.SetNoArgs();
3830
3831 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3832 return false;
3833 }
3834 return true;
3835 }
3836
EmulateShiftReg(const uint32_t opcode,const ARMEncoding encoding,ARM_ShifterType shift_type)3837 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
3838 const ARMEncoding encoding,
3839 ARM_ShifterType shift_type) {
3840 // assert(shift_type == SRType_ASR
3841 // || shift_type == SRType_LSL
3842 // || shift_type == SRType_LSR
3843 // || shift_type == SRType_ROR);
3844
3845 bool success = false;
3846
3847 if (ConditionPassed(opcode)) {
3848 uint32_t Rd; // the destination register
3849 uint32_t Rn; // the first operand register
3850 uint32_t
3851 Rm; // the register whose bottom byte contains the amount to shift by
3852 uint32_t carry; // the carry bit after the shift operation
3853 bool setflags;
3854 switch (encoding) {
3855 case eEncodingT1:
3856 Rd = Bits32(opcode, 2, 0);
3857 Rn = Rd;
3858 Rm = Bits32(opcode, 5, 3);
3859 setflags = !InITBlock();
3860 break;
3861 case eEncodingT2:
3862 Rd = Bits32(opcode, 11, 8);
3863 Rn = Bits32(opcode, 19, 16);
3864 Rm = Bits32(opcode, 3, 0);
3865 setflags = BitIsSet(opcode, 20);
3866 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3867 return false;
3868 break;
3869 case eEncodingA1:
3870 Rd = Bits32(opcode, 15, 12);
3871 Rn = Bits32(opcode, 3, 0);
3872 Rm = Bits32(opcode, 11, 8);
3873 setflags = BitIsSet(opcode, 20);
3874 if (Rd == 15 || Rn == 15 || Rm == 15)
3875 return false;
3876 break;
3877 default:
3878 return false;
3879 }
3880
3881 // Get the first operand.
3882 uint32_t value = ReadCoreReg(Rn, &success);
3883 if (!success)
3884 return false;
3885 // Get the Rm register content.
3886 uint32_t val = ReadCoreReg(Rm, &success);
3887 if (!success)
3888 return false;
3889
3890 // Get the shift amount.
3891 uint32_t amt = Bits32(val, 7, 0);
3892
3893 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3894 if (!success)
3895 return false;
3896
3897 // The context specifies that an immediate is to be moved into Rd.
3898 EmulateInstruction::Context context;
3899 context.type = EmulateInstruction::eContextImmediate;
3900 context.SetNoArgs();
3901
3902 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3903 return false;
3904 }
3905 return true;
3906 }
3907
3908 // LDM loads multiple registers from consecutive memory locations, using an
3909 // address from a base register. Optionally the address just above the highest
3910 // of those locations can be written back to the base register.
EmulateLDM(const uint32_t opcode,const ARMEncoding encoding)3911 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3912 const ARMEncoding encoding) {
3913 #if 0
3914 // ARM pseudo code...
3915 if ConditionPassed()
3916 EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3917 address = R[n];
3918
3919 for i = 0 to 14
3920 if registers<i> == '1' then
3921 R[i] = MemA[address, 4]; address = address + 4;
3922 if registers<15> == '1' then
3923 LoadWritePC (MemA[address, 4]);
3924
3925 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3926 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3927
3928 #endif
3929
3930 bool success = false;
3931 if (ConditionPassed(opcode)) {
3932 uint32_t n;
3933 uint32_t registers = 0;
3934 bool wback;
3935 const uint32_t addr_byte_size = GetAddressByteSize();
3936 switch (encoding) {
3937 case eEncodingT1:
3938 // n = UInt(Rn); registers = '00000000':register_list; wback =
3939 // (registers<n> == '0');
3940 n = Bits32(opcode, 10, 8);
3941 registers = Bits32(opcode, 7, 0);
3942 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3943 wback = BitIsClear(registers, n);
3944 // if BitCount(registers) < 1 then UNPREDICTABLE;
3945 if (BitCount(registers) < 1)
3946 return false;
3947 break;
3948 case eEncodingT2:
3949 // if W == '1' && Rn == '1101' then SEE POP;
3950 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3951 n = Bits32(opcode, 19, 16);
3952 registers = Bits32(opcode, 15, 0);
3953 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3954 wback = BitIsSet(opcode, 21);
3955
3956 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3957 // UNPREDICTABLE;
3958 if ((n == 15) || (BitCount(registers) < 2) ||
3959 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3960 return false;
3961
3962 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3963 // UNPREDICTABLE;
3964 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3965 return false;
3966
3967 // if wback && registers<n> == '1' then UNPREDICTABLE;
3968 if (wback && BitIsSet(registers, n))
3969 return false;
3970 break;
3971
3972 case eEncodingA1:
3973 n = Bits32(opcode, 19, 16);
3974 registers = Bits32(opcode, 15, 0);
3975 wback = BitIsSet(opcode, 21);
3976 if ((n == 15) || (BitCount(registers) < 1))
3977 return false;
3978 break;
3979 default:
3980 return false;
3981 }
3982
3983 int32_t offset = 0;
3984 const addr_t base_address =
3985 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3986 if (!success)
3987 return false;
3988
3989 EmulateInstruction::Context context;
3990 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3991 RegisterInfo dwarf_reg;
3992 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3993 context.SetRegisterPlusOffset(dwarf_reg, offset);
3994
3995 for (int i = 0; i < 14; ++i) {
3996 if (BitIsSet(registers, i)) {
3997 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3998 context.SetRegisterPlusOffset(dwarf_reg, offset);
3999 if (wback && (n == 13)) // Pop Instruction
4000 {
4001 context.type = EmulateInstruction::eContextPopRegisterOffStack;
4002 context.SetAddress(base_address + offset);
4003 }
4004
4005 // R[i] = MemA [address, 4]; address = address + 4;
4006 uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
4007 0, &success);
4008 if (!success)
4009 return false;
4010
4011 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4012 data))
4013 return false;
4014
4015 offset += addr_byte_size;
4016 }
4017 }
4018
4019 if (BitIsSet(registers, 15)) {
4020 // LoadWritePC (MemA [address, 4]);
4021 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4022 context.SetRegisterPlusOffset(dwarf_reg, offset);
4023 uint32_t data =
4024 MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4025 if (!success)
4026 return false;
4027 // In ARMv5T and above, this is an interworking branch.
4028 if (!LoadWritePC(context, data))
4029 return false;
4030 }
4031
4032 if (wback && BitIsClear(registers, n)) {
4033 // R[n] = R[n] + 4 * BitCount (registers)
4034 int32_t offset = addr_byte_size * BitCount(registers);
4035 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4036 context.SetRegisterPlusOffset(dwarf_reg, offset);
4037
4038 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4039 base_address + offset))
4040 return false;
4041 }
4042 if (wback && BitIsSet(registers, n))
4043 // R[n] bits(32) UNKNOWN;
4044 return WriteBits32Unknown(n);
4045 }
4046 return true;
4047 }
4048
4049 // LDMDA loads multiple registers from consecutive memory locations using an
4050 // address from a base register.
4051 // The consecutive memory locations end at this address and the address just
4052 // below the lowest of those locations can optionally be written back to the
4053 // base register.
EmulateLDMDA(const uint32_t opcode,const ARMEncoding encoding)4054 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
4055 const ARMEncoding encoding) {
4056 #if 0
4057 // ARM pseudo code...
4058 if ConditionPassed() then
4059 EncodingSpecificOperations();
4060 address = R[n] - 4*BitCount(registers) + 4;
4061
4062 for i = 0 to 14
4063 if registers<i> == '1' then
4064 R[i] = MemA[address,4]; address = address + 4;
4065
4066 if registers<15> == '1' then
4067 LoadWritePC(MemA[address,4]);
4068
4069 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4070 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4071 #endif
4072
4073 bool success = false;
4074
4075 if (ConditionPassed(opcode)) {
4076 uint32_t n;
4077 uint32_t registers = 0;
4078 bool wback;
4079 const uint32_t addr_byte_size = GetAddressByteSize();
4080
4081 // EncodingSpecificOperations();
4082 switch (encoding) {
4083 case eEncodingA1:
4084 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4085 n = Bits32(opcode, 19, 16);
4086 registers = Bits32(opcode, 15, 0);
4087 wback = BitIsSet(opcode, 21);
4088
4089 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4090 if ((n == 15) || (BitCount(registers) < 1))
4091 return false;
4092
4093 break;
4094
4095 default:
4096 return false;
4097 }
4098 // address = R[n] - 4*BitCount(registers) + 4;
4099
4100 int32_t offset = 0;
4101 addr_t Rn = ReadCoreReg(n, &success);
4102
4103 if (!success)
4104 return false;
4105
4106 addr_t address =
4107 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
4108
4109 EmulateInstruction::Context context;
4110 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4111 RegisterInfo dwarf_reg;
4112 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4113 context.SetRegisterPlusOffset(dwarf_reg, offset);
4114
4115 // for i = 0 to 14
4116 for (int i = 0; i < 14; ++i) {
4117 // if registers<i> == '1' then
4118 if (BitIsSet(registers, i)) {
4119 // R[i] = MemA[address,4]; address = address + 4;
4120 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4121 uint32_t data =
4122 MemARead(context, address + offset, addr_byte_size, 0, &success);
4123 if (!success)
4124 return false;
4125 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4126 data))
4127 return false;
4128 offset += addr_byte_size;
4129 }
4130 }
4131
4132 // if registers<15> == '1' then
4133 // LoadWritePC(MemA[address,4]);
4134 if (BitIsSet(registers, 15)) {
4135 context.SetRegisterPlusOffset(dwarf_reg, offset);
4136 uint32_t data =
4137 MemARead(context, address + offset, addr_byte_size, 0, &success);
4138 if (!success)
4139 return false;
4140 // In ARMv5T and above, this is an interworking branch.
4141 if (!LoadWritePC(context, data))
4142 return false;
4143 }
4144
4145 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4146 if (wback && BitIsClear(registers, n)) {
4147 if (!success)
4148 return false;
4149
4150 offset = (addr_byte_size * BitCount(registers)) * -1;
4151 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4152 context.SetImmediateSigned(offset);
4153 addr_t addr = Rn + offset;
4154 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4155 addr))
4156 return false;
4157 }
4158
4159 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4160 if (wback && BitIsSet(registers, n))
4161 return WriteBits32Unknown(n);
4162 }
4163 return true;
4164 }
4165
4166 // LDMDB loads multiple registers from consecutive memory locations using an
4167 // address from a base register. The
4168 // consecutive memory locations end just below this address, and the address of
4169 // the lowest of those locations can be optionally written back to the base
4170 // register.
EmulateLDMDB(const uint32_t opcode,const ARMEncoding encoding)4171 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
4172 const ARMEncoding encoding) {
4173 #if 0
4174 // ARM pseudo code...
4175 if ConditionPassed() then
4176 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4177 address = R[n] - 4*BitCount(registers);
4178
4179 for i = 0 to 14
4180 if registers<i> == '1' then
4181 R[i] = MemA[address,4]; address = address + 4;
4182 if registers<15> == '1' then
4183 LoadWritePC(MemA[address,4]);
4184
4185 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4186 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
4187 #endif
4188
4189 bool success = false;
4190
4191 if (ConditionPassed(opcode)) {
4192 uint32_t n;
4193 uint32_t registers = 0;
4194 bool wback;
4195 const uint32_t addr_byte_size = GetAddressByteSize();
4196 switch (encoding) {
4197 case eEncodingT1:
4198 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
4199 n = Bits32(opcode, 19, 16);
4200 registers = Bits32(opcode, 15, 0);
4201 registers = registers & 0xdfff; // Make sure bit 13 is a zero.
4202 wback = BitIsSet(opcode, 21);
4203
4204 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4205 // UNPREDICTABLE;
4206 if ((n == 15) || (BitCount(registers) < 2) ||
4207 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4208 return false;
4209
4210 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4211 // UNPREDICTABLE;
4212 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4213 return false;
4214
4215 // if wback && registers<n> == '1' then UNPREDICTABLE;
4216 if (wback && BitIsSet(registers, n))
4217 return false;
4218
4219 break;
4220
4221 case eEncodingA1:
4222 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4223 n = Bits32(opcode, 19, 16);
4224 registers = Bits32(opcode, 15, 0);
4225 wback = BitIsSet(opcode, 21);
4226
4227 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4228 if ((n == 15) || (BitCount(registers) < 1))
4229 return false;
4230
4231 break;
4232
4233 default:
4234 return false;
4235 }
4236
4237 // address = R[n] - 4*BitCount(registers);
4238
4239 int32_t offset = 0;
4240 addr_t Rn =
4241 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4242
4243 if (!success)
4244 return false;
4245
4246 addr_t address = Rn - (addr_byte_size * BitCount(registers));
4247 EmulateInstruction::Context context;
4248 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4249 RegisterInfo dwarf_reg;
4250 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4251 context.SetRegisterPlusOffset(dwarf_reg, Rn - address);
4252
4253 for (int i = 0; i < 14; ++i) {
4254 if (BitIsSet(registers, i)) {
4255 // R[i] = MemA[address,4]; address = address + 4;
4256 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4257 uint32_t data =
4258 MemARead(context, address + offset, addr_byte_size, 0, &success);
4259 if (!success)
4260 return false;
4261
4262 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4263 data))
4264 return false;
4265
4266 offset += addr_byte_size;
4267 }
4268 }
4269
4270 // if registers<15> == '1' then
4271 // LoadWritePC(MemA[address,4]);
4272 if (BitIsSet(registers, 15)) {
4273 context.SetRegisterPlusOffset(dwarf_reg, offset);
4274 uint32_t data =
4275 MemARead(context, address + offset, addr_byte_size, 0, &success);
4276 if (!success)
4277 return false;
4278 // In ARMv5T and above, this is an interworking branch.
4279 if (!LoadWritePC(context, data))
4280 return false;
4281 }
4282
4283 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4284 if (wback && BitIsClear(registers, n)) {
4285 if (!success)
4286 return false;
4287
4288 offset = (addr_byte_size * BitCount(registers)) * -1;
4289 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4290 context.SetImmediateSigned(offset);
4291 addr_t addr = Rn + offset;
4292 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4293 addr))
4294 return false;
4295 }
4296
4297 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4298 // possible for encoding A1
4299 if (wback && BitIsSet(registers, n))
4300 return WriteBits32Unknown(n);
4301 }
4302 return true;
4303 }
4304
4305 // LDMIB loads multiple registers from consecutive memory locations using an
4306 // address from a base register. The
4307 // consecutive memory locations start just above this address, and thea ddress
4308 // of the last of those locations can optinoally be written back to the base
4309 // register.
EmulateLDMIB(const uint32_t opcode,const ARMEncoding encoding)4310 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
4311 const ARMEncoding encoding) {
4312 #if 0
4313 if ConditionPassed() then
4314 EncodingSpecificOperations();
4315 address = R[n] + 4;
4316
4317 for i = 0 to 14
4318 if registers<i> == '1' then
4319 R[i] = MemA[address,4]; address = address + 4;
4320 if registers<15> == '1' then
4321 LoadWritePC(MemA[address,4]);
4322
4323 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4324 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4325 #endif
4326
4327 bool success = false;
4328
4329 if (ConditionPassed(opcode)) {
4330 uint32_t n;
4331 uint32_t registers = 0;
4332 bool wback;
4333 const uint32_t addr_byte_size = GetAddressByteSize();
4334 switch (encoding) {
4335 case eEncodingA1:
4336 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4337 n = Bits32(opcode, 19, 16);
4338 registers = Bits32(opcode, 15, 0);
4339 wback = BitIsSet(opcode, 21);
4340
4341 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4342 if ((n == 15) || (BitCount(registers) < 1))
4343 return false;
4344
4345 break;
4346 default:
4347 return false;
4348 }
4349 // address = R[n] + 4;
4350
4351 int32_t offset = 0;
4352 addr_t Rn =
4353 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4354
4355 if (!success)
4356 return false;
4357
4358 addr_t address = Rn + addr_byte_size;
4359
4360 EmulateInstruction::Context context;
4361 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4362 RegisterInfo dwarf_reg;
4363 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4364 context.SetRegisterPlusOffset(dwarf_reg, offset);
4365
4366 for (int i = 0; i < 14; ++i) {
4367 if (BitIsSet(registers, i)) {
4368 // R[i] = MemA[address,4]; address = address + 4;
4369
4370 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size);
4371 uint32_t data =
4372 MemARead(context, address + offset, addr_byte_size, 0, &success);
4373 if (!success)
4374 return false;
4375
4376 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4377 data))
4378 return false;
4379
4380 offset += addr_byte_size;
4381 }
4382 }
4383
4384 // if registers<15> == '1' then
4385 // LoadWritePC(MemA[address,4]);
4386 if (BitIsSet(registers, 15)) {
4387 context.SetRegisterPlusOffset(dwarf_reg, offset);
4388 uint32_t data =
4389 MemARead(context, address + offset, addr_byte_size, 0, &success);
4390 if (!success)
4391 return false;
4392 // In ARMv5T and above, this is an interworking branch.
4393 if (!LoadWritePC(context, data))
4394 return false;
4395 }
4396
4397 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4398 if (wback && BitIsClear(registers, n)) {
4399 if (!success)
4400 return false;
4401
4402 offset = addr_byte_size * BitCount(registers);
4403 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4404 context.SetImmediateSigned(offset);
4405 addr_t addr = Rn + offset;
4406 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4407 addr))
4408 return false;
4409 }
4410
4411 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4412 // possible for encoding A1
4413 if (wback && BitIsSet(registers, n))
4414 return WriteBits32Unknown(n);
4415 }
4416 return true;
4417 }
4418
4419 // Load Register (immediate) calculates an address from a base register value
4420 // and an immediate offset, loads a word from memory, and writes to a register.
4421 // LDR (immediate, Thumb)
EmulateLDRRtRnImm(const uint32_t opcode,const ARMEncoding encoding)4422 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
4423 const ARMEncoding encoding) {
4424 #if 0
4425 // ARM pseudo code...
4426 if (ConditionPassed())
4427 {
4428 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4429 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4430 address = if index then offset_addr else R[n];
4431 data = MemU[address,4];
4432 if wback then R[n] = offset_addr;
4433 if t == 15 then
4434 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
4435 elsif UnalignedSupport() || address<1:0> = '00' then
4436 R[t] = data;
4437 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
4438 }
4439 #endif
4440
4441 bool success = false;
4442
4443 if (ConditionPassed(opcode)) {
4444 uint32_t Rt; // the destination register
4445 uint32_t Rn; // the base register
4446 uint32_t imm32; // the immediate offset used to form the address
4447 addr_t offset_addr; // the offset address
4448 addr_t address; // the calculated address
4449 uint32_t data; // the literal data value from memory load
4450 bool add, index, wback;
4451 switch (encoding) {
4452 case eEncodingT1:
4453 Rt = Bits32(opcode, 2, 0);
4454 Rn = Bits32(opcode, 5, 3);
4455 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
4456 // index = TRUE; add = TRUE; wback = FALSE
4457 add = true;
4458 index = true;
4459 wback = false;
4460
4461 break;
4462
4463 case eEncodingT2:
4464 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4465 Rt = Bits32(opcode, 10, 8);
4466 Rn = 13;
4467 imm32 = Bits32(opcode, 7, 0) << 2;
4468
4469 // index = TRUE; add = TRUE; wback = FALSE;
4470 index = true;
4471 add = true;
4472 wback = false;
4473
4474 break;
4475
4476 case eEncodingT3:
4477 // if Rn == '1111' then SEE LDR (literal);
4478 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4479 Rt = Bits32(opcode, 15, 12);
4480 Rn = Bits32(opcode, 19, 16);
4481 imm32 = Bits32(opcode, 11, 0);
4482
4483 // index = TRUE; add = TRUE; wback = FALSE;
4484 index = true;
4485 add = true;
4486 wback = false;
4487
4488 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4489 if ((Rt == 15) && InITBlock() && !LastInITBlock())
4490 return false;
4491
4492 break;
4493
4494 case eEncodingT4:
4495 // if Rn == '1111' then SEE LDR (literal);
4496 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4497 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
4498 // '00000100' then SEE POP;
4499 // if P == '0' && W == '0' then UNDEFINED;
4500 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
4501 return false;
4502
4503 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4504 Rt = Bits32(opcode, 15, 12);
4505 Rn = Bits32(opcode, 19, 16);
4506 imm32 = Bits32(opcode, 7, 0);
4507
4508 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4509 index = BitIsSet(opcode, 10);
4510 add = BitIsSet(opcode, 9);
4511 wback = BitIsSet(opcode, 8);
4512
4513 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4514 // then UNPREDICTABLE;
4515 if ((wback && (Rn == Rt)) ||
4516 ((Rt == 15) && InITBlock() && !LastInITBlock()))
4517 return false;
4518
4519 break;
4520
4521 default:
4522 return false;
4523 }
4524 uint32_t base = ReadCoreReg(Rn, &success);
4525 if (!success)
4526 return false;
4527 if (add)
4528 offset_addr = base + imm32;
4529 else
4530 offset_addr = base - imm32;
4531
4532 address = (index ? offset_addr : base);
4533
4534 RegisterInfo base_reg;
4535 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4536 if (wback) {
4537 EmulateInstruction::Context ctx;
4538 if (Rn == 13) {
4539 ctx.type = eContextAdjustStackPointer;
4540 ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4541 } else if (Rn == GetFramePointerRegisterNumber()) {
4542 ctx.type = eContextSetFramePointer;
4543 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4544 } else {
4545 ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4546 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4547 }
4548
4549 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
4550 offset_addr))
4551 return false;
4552 }
4553
4554 // Prepare to write to the Rt register.
4555 EmulateInstruction::Context context;
4556 context.type = EmulateInstruction::eContextRegisterLoad;
4557 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4558
4559 // Read memory from the address.
4560 data = MemURead(context, address, 4, 0, &success);
4561 if (!success)
4562 return false;
4563
4564 if (Rt == 15) {
4565 if (Bits32(address, 1, 0) == 0) {
4566 if (!LoadWritePC(context, data))
4567 return false;
4568 } else
4569 return false;
4570 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4571 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
4572 data))
4573 return false;
4574 } else
4575 WriteBits32Unknown(Rt);
4576 }
4577 return true;
4578 }
4579
4580 // STM (Store Multiple Increment After) stores multiple registers to consecutive
4581 // memory locations using an address
4582 // from a base register. The consecutive memory locations start at this
4583 // address, and the address just above the last of those locations can
4584 // optionally be written back to the base register.
EmulateSTM(const uint32_t opcode,const ARMEncoding encoding)4585 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4586 const ARMEncoding encoding) {
4587 #if 0
4588 if ConditionPassed() then
4589 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4590 address = R[n];
4591
4592 for i = 0 to 14
4593 if registers<i> == '1' then
4594 if i == n && wback && i != LowestSetBit(registers) then
4595 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4596 else
4597 MemA[address,4] = R[i];
4598 address = address + 4;
4599
4600 if registers<15> == '1' then // Only possible for encoding A1
4601 MemA[address,4] = PCStoreValue();
4602 if wback then R[n] = R[n] + 4*BitCount(registers);
4603 #endif
4604
4605 bool success = false;
4606
4607 if (ConditionPassed(opcode)) {
4608 uint32_t n;
4609 uint32_t registers = 0;
4610 bool wback;
4611 const uint32_t addr_byte_size = GetAddressByteSize();
4612
4613 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4614 switch (encoding) {
4615 case eEncodingT1:
4616 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4617 n = Bits32(opcode, 10, 8);
4618 registers = Bits32(opcode, 7, 0);
4619 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4620 wback = true;
4621
4622 // if BitCount(registers) < 1 then UNPREDICTABLE;
4623 if (BitCount(registers) < 1)
4624 return false;
4625
4626 break;
4627
4628 case eEncodingT2:
4629 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4630 n = Bits32(opcode, 19, 16);
4631 registers = Bits32(opcode, 15, 0);
4632 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4633 wback = BitIsSet(opcode, 21);
4634
4635 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4636 if ((n == 15) || (BitCount(registers) < 2))
4637 return false;
4638
4639 // if wback && registers<n> == '1' then UNPREDICTABLE;
4640 if (wback && BitIsSet(registers, n))
4641 return false;
4642
4643 break;
4644
4645 case eEncodingA1:
4646 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4647 n = Bits32(opcode, 19, 16);
4648 registers = Bits32(opcode, 15, 0);
4649 wback = BitIsSet(opcode, 21);
4650
4651 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4652 if ((n == 15) || (BitCount(registers) < 1))
4653 return false;
4654
4655 break;
4656
4657 default:
4658 return false;
4659 }
4660
4661 // address = R[n];
4662 int32_t offset = 0;
4663 const addr_t address =
4664 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4665 if (!success)
4666 return false;
4667
4668 EmulateInstruction::Context context;
4669 context.type = EmulateInstruction::eContextRegisterStore;
4670 RegisterInfo base_reg;
4671 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4672
4673 // for i = 0 to 14
4674 uint32_t lowest_set_bit = 14;
4675 for (uint32_t i = 0; i < 14; ++i) {
4676 // if registers<i> == '1' then
4677 if (BitIsSet(registers, i)) {
4678 if (i < lowest_set_bit)
4679 lowest_set_bit = i;
4680 // if i == n && wback && i != LowestSetBit(registers) then
4681 if ((i == n) && wback && (i != lowest_set_bit))
4682 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4683 // T1 and A1
4684 WriteBits32UnknownToMemory(address + offset);
4685 else {
4686 // MemA[address,4] = R[i];
4687 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4688 0, &success);
4689 if (!success)
4690 return false;
4691
4692 RegisterInfo data_reg;
4693 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4694 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
4695 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4696 return false;
4697 }
4698
4699 // address = address + 4;
4700 offset += addr_byte_size;
4701 }
4702 }
4703
4704 // if registers<15> == '1' then // Only possible for encoding A1
4705 // MemA[address,4] = PCStoreValue();
4706 if (BitIsSet(registers, 15)) {
4707 RegisterInfo pc_reg;
4708 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4709 context.SetRegisterPlusOffset(pc_reg, 8);
4710 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4711 if (!success)
4712 return false;
4713
4714 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4715 return false;
4716 }
4717
4718 // if wback then R[n] = R[n] + 4*BitCount(registers);
4719 if (wback) {
4720 offset = addr_byte_size * BitCount(registers);
4721 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4722 context.SetImmediateSigned(offset);
4723 addr_t data = address + offset;
4724 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4725 data))
4726 return false;
4727 }
4728 }
4729 return true;
4730 }
4731
4732 // STMDA (Store Multiple Decrement After) stores multiple registers to
4733 // consecutive memory locations using an address from a base register. The
4734 // consecutive memory locations end at this address, and the address just below
4735 // the lowest of those locations can optionally be written back to the base
4736 // register.
EmulateSTMDA(const uint32_t opcode,const ARMEncoding encoding)4737 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4738 const ARMEncoding encoding) {
4739 #if 0
4740 if ConditionPassed() then
4741 EncodingSpecificOperations();
4742 address = R[n] - 4*BitCount(registers) + 4;
4743
4744 for i = 0 to 14
4745 if registers<i> == '1' then
4746 if i == n && wback && i != LowestSetBit(registers) then
4747 MemA[address,4] = bits(32) UNKNOWN;
4748 else
4749 MemA[address,4] = R[i];
4750 address = address + 4;
4751
4752 if registers<15> == '1' then
4753 MemA[address,4] = PCStoreValue();
4754
4755 if wback then R[n] = R[n] - 4*BitCount(registers);
4756 #endif
4757
4758 bool success = false;
4759
4760 if (ConditionPassed(opcode)) {
4761 uint32_t n;
4762 uint32_t registers = 0;
4763 bool wback;
4764 const uint32_t addr_byte_size = GetAddressByteSize();
4765
4766 // EncodingSpecificOperations();
4767 switch (encoding) {
4768 case eEncodingA1:
4769 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4770 n = Bits32(opcode, 19, 16);
4771 registers = Bits32(opcode, 15, 0);
4772 wback = BitIsSet(opcode, 21);
4773
4774 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4775 if ((n == 15) || (BitCount(registers) < 1))
4776 return false;
4777 break;
4778 default:
4779 return false;
4780 }
4781
4782 // address = R[n] - 4*BitCount(registers) + 4;
4783 int32_t offset = 0;
4784 addr_t Rn = ReadCoreReg(n, &success);
4785 if (!success)
4786 return false;
4787
4788 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4789
4790 EmulateInstruction::Context context;
4791 context.type = EmulateInstruction::eContextRegisterStore;
4792 RegisterInfo base_reg;
4793 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4794
4795 // for i = 0 to 14
4796 uint32_t lowest_bit_set = 14;
4797 for (uint32_t i = 0; i < 14; ++i) {
4798 // if registers<i> == '1' then
4799 if (BitIsSet(registers, i)) {
4800 if (i < lowest_bit_set)
4801 lowest_bit_set = i;
4802 // if i == n && wback && i != LowestSetBit(registers) then
4803 if ((i == n) && wback && (i != lowest_bit_set))
4804 // MemA[address,4] = bits(32) UNKNOWN;
4805 WriteBits32UnknownToMemory(address + offset);
4806 else {
4807 // MemA[address,4] = R[i];
4808 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4809 0, &success);
4810 if (!success)
4811 return false;
4812
4813 RegisterInfo data_reg;
4814 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4815 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4816 Rn - (address + offset));
4817 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4818 return false;
4819 }
4820
4821 // address = address + 4;
4822 offset += addr_byte_size;
4823 }
4824 }
4825
4826 // if registers<15> == '1' then
4827 // MemA[address,4] = PCStoreValue();
4828 if (BitIsSet(registers, 15)) {
4829 RegisterInfo pc_reg;
4830 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4831 context.SetRegisterPlusOffset(pc_reg, 8);
4832 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4833 if (!success)
4834 return false;
4835
4836 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4837 return false;
4838 }
4839
4840 // if wback then R[n] = R[n] - 4*BitCount(registers);
4841 if (wback) {
4842 offset = (addr_byte_size * BitCount(registers)) * -1;
4843 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4844 context.SetImmediateSigned(offset);
4845 addr_t data = Rn + offset;
4846 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4847 data))
4848 return false;
4849 }
4850 }
4851 return true;
4852 }
4853
4854 // STMDB (Store Multiple Decrement Before) stores multiple registers to
4855 // consecutive memory locations using an address from a base register. The
4856 // consecutive memory locations end just below this address, and the address of
4857 // the first of those locations can optionally be written back to the base
4858 // register.
EmulateSTMDB(const uint32_t opcode,const ARMEncoding encoding)4859 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4860 const ARMEncoding encoding) {
4861 #if 0
4862 if ConditionPassed() then
4863 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4864 address = R[n] - 4*BitCount(registers);
4865
4866 for i = 0 to 14
4867 if registers<i> == '1' then
4868 if i == n && wback && i != LowestSetBit(registers) then
4869 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4870 else
4871 MemA[address,4] = R[i];
4872 address = address + 4;
4873
4874 if registers<15> == '1' then // Only possible for encoding A1
4875 MemA[address,4] = PCStoreValue();
4876
4877 if wback then R[n] = R[n] - 4*BitCount(registers);
4878 #endif
4879
4880 bool success = false;
4881
4882 if (ConditionPassed(opcode)) {
4883 uint32_t n;
4884 uint32_t registers = 0;
4885 bool wback;
4886 const uint32_t addr_byte_size = GetAddressByteSize();
4887
4888 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4889 switch (encoding) {
4890 case eEncodingT1:
4891 // if W == '1' && Rn == '1101' then SEE PUSH;
4892 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4893 // See PUSH
4894 }
4895 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4896 n = Bits32(opcode, 19, 16);
4897 registers = Bits32(opcode, 15, 0);
4898 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4899 wback = BitIsSet(opcode, 21);
4900 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4901 if ((n == 15) || BitCount(registers) < 2)
4902 return false;
4903 // if wback && registers<n> == '1' then UNPREDICTABLE;
4904 if (wback && BitIsSet(registers, n))
4905 return false;
4906 break;
4907
4908 case eEncodingA1:
4909 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4910 // PUSH;
4911 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4912 BitCount(Bits32(opcode, 15, 0)) >= 2) {
4913 // See Push
4914 }
4915 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4916 n = Bits32(opcode, 19, 16);
4917 registers = Bits32(opcode, 15, 0);
4918 wback = BitIsSet(opcode, 21);
4919 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4920 if ((n == 15) || BitCount(registers) < 1)
4921 return false;
4922 break;
4923
4924 default:
4925 return false;
4926 }
4927
4928 // address = R[n] - 4*BitCount(registers);
4929
4930 int32_t offset = 0;
4931 addr_t Rn =
4932 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4933 if (!success)
4934 return false;
4935
4936 addr_t address = Rn - (addr_byte_size * BitCount(registers));
4937
4938 EmulateInstruction::Context context;
4939 context.type = EmulateInstruction::eContextRegisterStore;
4940 RegisterInfo base_reg;
4941 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4942
4943 // for i = 0 to 14
4944 uint32_t lowest_set_bit = 14;
4945 for (uint32_t i = 0; i < 14; ++i) {
4946 // if registers<i> == '1' then
4947 if (BitIsSet(registers, i)) {
4948 if (i < lowest_set_bit)
4949 lowest_set_bit = i;
4950 // if i == n && wback && i != LowestSetBit(registers) then
4951 if ((i == n) && wback && (i != lowest_set_bit))
4952 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4953 // A1
4954 WriteBits32UnknownToMemory(address + offset);
4955 else {
4956 // MemA[address,4] = R[i];
4957 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4958 0, &success);
4959 if (!success)
4960 return false;
4961
4962 RegisterInfo data_reg;
4963 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4964 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4965 Rn - (address + offset));
4966 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4967 return false;
4968 }
4969
4970 // address = address + 4;
4971 offset += addr_byte_size;
4972 }
4973 }
4974
4975 // if registers<15> == '1' then // Only possible for encoding A1
4976 // MemA[address,4] = PCStoreValue();
4977 if (BitIsSet(registers, 15)) {
4978 RegisterInfo pc_reg;
4979 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4980 context.SetRegisterPlusOffset(pc_reg, 8);
4981 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4982 if (!success)
4983 return false;
4984
4985 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4986 return false;
4987 }
4988
4989 // if wback then R[n] = R[n] - 4*BitCount(registers);
4990 if (wback) {
4991 offset = (addr_byte_size * BitCount(registers)) * -1;
4992 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4993 context.SetImmediateSigned(offset);
4994 addr_t data = Rn + offset;
4995 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4996 data))
4997 return false;
4998 }
4999 }
5000 return true;
5001 }
5002
5003 // STMIB (Store Multiple Increment Before) stores multiple registers to
5004 // consecutive memory locations using an address from a base register. The
5005 // consecutive memory locations start just above this address, and the address
5006 // of the last of those locations can optionally be written back to the base
5007 // register.
EmulateSTMIB(const uint32_t opcode,const ARMEncoding encoding)5008 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
5009 const ARMEncoding encoding) {
5010 #if 0
5011 if ConditionPassed() then
5012 EncodingSpecificOperations();
5013 address = R[n] + 4;
5014
5015 for i = 0 to 14
5016 if registers<i> == '1' then
5017 if i == n && wback && i != LowestSetBit(registers) then
5018 MemA[address,4] = bits(32) UNKNOWN;
5019 else
5020 MemA[address,4] = R[i];
5021 address = address + 4;
5022
5023 if registers<15> == '1' then
5024 MemA[address,4] = PCStoreValue();
5025
5026 if wback then R[n] = R[n] + 4*BitCount(registers);
5027 #endif
5028
5029 bool success = false;
5030
5031 if (ConditionPassed(opcode)) {
5032 uint32_t n;
5033 uint32_t registers = 0;
5034 bool wback;
5035 const uint32_t addr_byte_size = GetAddressByteSize();
5036
5037 // EncodingSpecificOperations();
5038 switch (encoding) {
5039 case eEncodingA1:
5040 // n = UInt(Rn); registers = register_list; wback = (W == '1');
5041 n = Bits32(opcode, 19, 16);
5042 registers = Bits32(opcode, 15, 0);
5043 wback = BitIsSet(opcode, 21);
5044
5045 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
5046 if ((n == 15) && (BitCount(registers) < 1))
5047 return false;
5048 break;
5049 default:
5050 return false;
5051 }
5052 // address = R[n] + 4;
5053
5054 int32_t offset = 0;
5055 addr_t Rn = ReadCoreReg(n, &success);
5056 if (!success)
5057 return false;
5058
5059 addr_t address = Rn + addr_byte_size;
5060
5061 EmulateInstruction::Context context;
5062 context.type = EmulateInstruction::eContextRegisterStore;
5063 RegisterInfo base_reg;
5064 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5065
5066 uint32_t lowest_set_bit = 14;
5067 // for i = 0 to 14
5068 for (uint32_t i = 0; i < 14; ++i) {
5069 // if registers<i> == '1' then
5070 if (BitIsSet(registers, i)) {
5071 if (i < lowest_set_bit)
5072 lowest_set_bit = i;
5073 // if i == n && wback && i != LowestSetBit(registers) then
5074 if ((i == n) && wback && (i != lowest_set_bit))
5075 // MemA[address,4] = bits(32) UNKNOWN;
5076 WriteBits32UnknownToMemory(address + offset);
5077 // else
5078 else {
5079 // MemA[address,4] = R[i];
5080 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
5081 0, &success);
5082 if (!success)
5083 return false;
5084
5085 RegisterInfo data_reg;
5086 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
5087 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5088 offset + addr_byte_size);
5089 if (!MemAWrite(context, address + offset, data, addr_byte_size))
5090 return false;
5091 }
5092
5093 // address = address + 4;
5094 offset += addr_byte_size;
5095 }
5096 }
5097
5098 // if registers<15> == '1' then
5099 // MemA[address,4] = PCStoreValue();
5100 if (BitIsSet(registers, 15)) {
5101 RegisterInfo pc_reg;
5102 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
5103 context.SetRegisterPlusOffset(pc_reg, 8);
5104 const uint32_t pc = ReadCoreReg(PC_REG, &success);
5105 if (!success)
5106 return false;
5107
5108 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5109 return false;
5110 }
5111
5112 // if wback then R[n] = R[n] + 4*BitCount(registers);
5113 if (wback) {
5114 offset = addr_byte_size * BitCount(registers);
5115 context.type = EmulateInstruction::eContextAdjustBaseRegister;
5116 context.SetImmediateSigned(offset);
5117 addr_t data = Rn + offset;
5118 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5119 data))
5120 return false;
5121 }
5122 }
5123 return true;
5124 }
5125
5126 // STR (store immediate) calculates an address from a base register value and an
5127 // immediate offset, and stores a word
5128 // from a register to memory. It can use offset, post-indexed, or pre-indexed
5129 // addressing.
EmulateSTRThumb(const uint32_t opcode,const ARMEncoding encoding)5130 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
5131 const ARMEncoding encoding) {
5132 #if 0
5133 if ConditionPassed() then
5134 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5135 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5136 address = if index then offset_addr else R[n];
5137 if UnalignedSupport() || address<1:0> == '00' then
5138 MemU[address,4] = R[t];
5139 else // Can only occur before ARMv7
5140 MemU[address,4] = bits(32) UNKNOWN;
5141 if wback then R[n] = offset_addr;
5142 #endif
5143
5144 bool success = false;
5145
5146 if (ConditionPassed(opcode)) {
5147 const uint32_t addr_byte_size = GetAddressByteSize();
5148
5149 uint32_t t;
5150 uint32_t n;
5151 uint32_t imm32;
5152 bool index;
5153 bool add;
5154 bool wback;
5155 // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5156 switch (encoding) {
5157 case eEncodingT1:
5158 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
5159 t = Bits32(opcode, 2, 0);
5160 n = Bits32(opcode, 5, 3);
5161 imm32 = Bits32(opcode, 10, 6) << 2;
5162
5163 // index = TRUE; add = TRUE; wback = FALSE;
5164 index = true;
5165 add = false;
5166 wback = false;
5167 break;
5168
5169 case eEncodingT2:
5170 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
5171 t = Bits32(opcode, 10, 8);
5172 n = 13;
5173 imm32 = Bits32(opcode, 7, 0) << 2;
5174
5175 // index = TRUE; add = TRUE; wback = FALSE;
5176 index = true;
5177 add = true;
5178 wback = false;
5179 break;
5180
5181 case eEncodingT3:
5182 // if Rn == '1111' then UNDEFINED;
5183 if (Bits32(opcode, 19, 16) == 15)
5184 return false;
5185
5186 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5187 t = Bits32(opcode, 15, 12);
5188 n = Bits32(opcode, 19, 16);
5189 imm32 = Bits32(opcode, 11, 0);
5190
5191 // index = TRUE; add = TRUE; wback = FALSE;
5192 index = true;
5193 add = true;
5194 wback = false;
5195
5196 // if t == 15 then UNPREDICTABLE;
5197 if (t == 15)
5198 return false;
5199 break;
5200
5201 case eEncodingT4:
5202 // if P == '1' && U == '1' && W == '0' then SEE STRT;
5203 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
5204 // '00000100' then SEE PUSH;
5205 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5206 if ((Bits32(opcode, 19, 16) == 15) ||
5207 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
5208 return false;
5209
5210 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5211 t = Bits32(opcode, 15, 12);
5212 n = Bits32(opcode, 19, 16);
5213 imm32 = Bits32(opcode, 7, 0);
5214
5215 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5216 index = BitIsSet(opcode, 10);
5217 add = BitIsSet(opcode, 9);
5218 wback = BitIsSet(opcode, 8);
5219
5220 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
5221 if ((t == 15) || (wback && (n == t)))
5222 return false;
5223 break;
5224
5225 default:
5226 return false;
5227 }
5228
5229 addr_t offset_addr;
5230 addr_t address;
5231
5232 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5233 uint32_t base_address = ReadCoreReg(n, &success);
5234 if (!success)
5235 return false;
5236
5237 if (add)
5238 offset_addr = base_address + imm32;
5239 else
5240 offset_addr = base_address - imm32;
5241
5242 // address = if index then offset_addr else R[n];
5243 if (index)
5244 address = offset_addr;
5245 else
5246 address = base_address;
5247
5248 EmulateInstruction::Context context;
5249 if (n == 13)
5250 context.type = eContextPushRegisterOnStack;
5251 else
5252 context.type = eContextRegisterStore;
5253
5254 RegisterInfo base_reg;
5255 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5256
5257 // if UnalignedSupport() || address<1:0> == '00' then
5258 if (UnalignedSupport() ||
5259 (BitIsClear(address, 1) && BitIsClear(address, 0))) {
5260 // MemU[address,4] = R[t];
5261 uint32_t data =
5262 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5263 if (!success)
5264 return false;
5265
5266 RegisterInfo data_reg;
5267 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5268 int32_t offset = address - base_address;
5269 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
5270 if (!MemUWrite(context, address, data, addr_byte_size))
5271 return false;
5272 } else {
5273 // MemU[address,4] = bits(32) UNKNOWN;
5274 WriteBits32UnknownToMemory(address);
5275 }
5276
5277 // if wback then R[n] = offset_addr;
5278 if (wback) {
5279 if (n == 13)
5280 context.type = eContextAdjustStackPointer;
5281 else
5282 context.type = eContextAdjustBaseRegister;
5283 context.SetAddress(offset_addr);
5284
5285 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5286 offset_addr))
5287 return false;
5288 }
5289 }
5290 return true;
5291 }
5292
5293 // STR (Store Register) calculates an address from a base register value and an
5294 // offset register value, stores a
5295 // word from a register to memory. The offset register value can optionally
5296 // be shifted.
EmulateSTRRegister(const uint32_t opcode,const ARMEncoding encoding)5297 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
5298 const ARMEncoding encoding) {
5299 #if 0
5300 if ConditionPassed() then
5301 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5302 offset = Shift(R[m], shift_t, shift_n, APSR.C);
5303 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5304 address = if index then offset_addr else R[n];
5305 if t == 15 then // Only possible for encoding A1
5306 data = PCStoreValue();
5307 else
5308 data = R[t];
5309 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
5310 MemU[address,4] = data;
5311 else // Can only occur before ARMv7
5312 MemU[address,4] = bits(32) UNKNOWN;
5313 if wback then R[n] = offset_addr;
5314 #endif
5315
5316 bool success = false;
5317
5318 if (ConditionPassed(opcode)) {
5319 const uint32_t addr_byte_size = GetAddressByteSize();
5320
5321 uint32_t t;
5322 uint32_t n;
5323 uint32_t m;
5324 ARM_ShifterType shift_t;
5325 uint32_t shift_n;
5326 bool index;
5327 bool add;
5328 bool wback;
5329
5330 // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5331 switch (encoding) {
5332 case eEncodingT1:
5333 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5334 // in ThumbEE";
5335 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5336 t = Bits32(opcode, 2, 0);
5337 n = Bits32(opcode, 5, 3);
5338 m = Bits32(opcode, 8, 6);
5339
5340 // index = TRUE; add = TRUE; wback = FALSE;
5341 index = true;
5342 add = true;
5343 wback = false;
5344
5345 // (shift_t, shift_n) = (SRType_LSL, 0);
5346 shift_t = SRType_LSL;
5347 shift_n = 0;
5348 break;
5349
5350 case eEncodingT2:
5351 // if Rn == '1111' then UNDEFINED;
5352 if (Bits32(opcode, 19, 16) == 15)
5353 return false;
5354
5355 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5356 t = Bits32(opcode, 15, 12);
5357 n = Bits32(opcode, 19, 16);
5358 m = Bits32(opcode, 3, 0);
5359
5360 // index = TRUE; add = TRUE; wback = FALSE;
5361 index = true;
5362 add = true;
5363 wback = false;
5364
5365 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5366 shift_t = SRType_LSL;
5367 shift_n = Bits32(opcode, 5, 4);
5368
5369 // if t == 15 || BadReg(m) then UNPREDICTABLE;
5370 if ((t == 15) || (BadReg(m)))
5371 return false;
5372 break;
5373
5374 case eEncodingA1: {
5375 // if P == '0' && W == '1' then SEE STRT;
5376 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5377 t = Bits32(opcode, 15, 12);
5378 n = Bits32(opcode, 19, 16);
5379 m = Bits32(opcode, 3, 0);
5380
5381 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
5382 // (W == '1');
5383 index = BitIsSet(opcode, 24);
5384 add = BitIsSet(opcode, 23);
5385 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5386
5387 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5388 uint32_t typ = Bits32(opcode, 6, 5);
5389 uint32_t imm5 = Bits32(opcode, 11, 7);
5390 shift_n = DecodeImmShift(typ, imm5, shift_t);
5391
5392 // if m == 15 then UNPREDICTABLE;
5393 if (m == 15)
5394 return false;
5395
5396 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5397 if (wback && ((n == 15) || (n == t)))
5398 return false;
5399
5400 break;
5401 }
5402 default:
5403 return false;
5404 }
5405
5406 addr_t offset_addr;
5407 addr_t address;
5408 int32_t offset = 0;
5409
5410 addr_t base_address =
5411 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5412 if (!success)
5413 return false;
5414
5415 uint32_t Rm_data =
5416 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5417 if (!success)
5418 return false;
5419
5420 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5421 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
5422 if (!success)
5423 return false;
5424
5425 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5426 if (add)
5427 offset_addr = base_address + offset;
5428 else
5429 offset_addr = base_address - offset;
5430
5431 // address = if index then offset_addr else R[n];
5432 if (index)
5433 address = offset_addr;
5434 else
5435 address = base_address;
5436
5437 uint32_t data;
5438 // if t == 15 then // Only possible for encoding A1
5439 if (t == 15)
5440 // data = PCStoreValue();
5441 data = ReadCoreReg(PC_REG, &success);
5442 else
5443 // data = R[t];
5444 data =
5445 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5446
5447 if (!success)
5448 return false;
5449
5450 EmulateInstruction::Context context;
5451 context.type = eContextRegisterStore;
5452
5453 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
5454 // InstrSet_ARM then
5455 if (UnalignedSupport() ||
5456 (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
5457 CurrentInstrSet() == eModeARM) {
5458 // MemU[address,4] = data;
5459
5460 RegisterInfo base_reg;
5461 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5462
5463 RegisterInfo data_reg;
5464 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5465
5466 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5467 address - base_address);
5468 if (!MemUWrite(context, address, data, addr_byte_size))
5469 return false;
5470
5471 } else
5472 // MemU[address,4] = bits(32) UNKNOWN;
5473 WriteBits32UnknownToMemory(address);
5474
5475 // if wback then R[n] = offset_addr;
5476 if (wback) {
5477 context.type = eContextRegisterLoad;
5478 context.SetAddress(offset_addr);
5479 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5480 offset_addr))
5481 return false;
5482 }
5483 }
5484 return true;
5485 }
5486
EmulateSTRBThumb(const uint32_t opcode,const ARMEncoding encoding)5487 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
5488 const ARMEncoding encoding) {
5489 #if 0
5490 if ConditionPassed() then
5491 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5492 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5493 address = if index then offset_addr else R[n];
5494 MemU[address,1] = R[t]<7:0>;
5495 if wback then R[n] = offset_addr;
5496 #endif
5497
5498 bool success = false;
5499
5500 if (ConditionPassed(opcode)) {
5501 uint32_t t;
5502 uint32_t n;
5503 uint32_t imm32;
5504 bool index;
5505 bool add;
5506 bool wback;
5507 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5508 switch (encoding) {
5509 case eEncodingT1:
5510 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5511 t = Bits32(opcode, 2, 0);
5512 n = Bits32(opcode, 5, 3);
5513 imm32 = Bits32(opcode, 10, 6);
5514
5515 // index = TRUE; add = TRUE; wback = FALSE;
5516 index = true;
5517 add = true;
5518 wback = false;
5519 break;
5520
5521 case eEncodingT2:
5522 // if Rn == '1111' then UNDEFINED;
5523 if (Bits32(opcode, 19, 16) == 15)
5524 return false;
5525
5526 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5527 t = Bits32(opcode, 15, 12);
5528 n = Bits32(opcode, 19, 16);
5529 imm32 = Bits32(opcode, 11, 0);
5530
5531 // index = TRUE; add = TRUE; wback = FALSE;
5532 index = true;
5533 add = true;
5534 wback = false;
5535
5536 // if BadReg(t) then UNPREDICTABLE;
5537 if (BadReg(t))
5538 return false;
5539 break;
5540
5541 case eEncodingT3:
5542 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5543 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5544 if (Bits32(opcode, 19, 16) == 15)
5545 return false;
5546
5547 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5548 t = Bits32(opcode, 15, 12);
5549 n = Bits32(opcode, 19, 16);
5550 imm32 = Bits32(opcode, 7, 0);
5551
5552 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5553 index = BitIsSet(opcode, 10);
5554 add = BitIsSet(opcode, 9);
5555 wback = BitIsSet(opcode, 8);
5556
5557 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5558 if ((BadReg(t)) || (wback && (n == t)))
5559 return false;
5560 break;
5561
5562 default:
5563 return false;
5564 }
5565
5566 addr_t offset_addr;
5567 addr_t address;
5568 addr_t base_address =
5569 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5570 if (!success)
5571 return false;
5572
5573 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5574 if (add)
5575 offset_addr = base_address + imm32;
5576 else
5577 offset_addr = base_address - imm32;
5578
5579 // address = if index then offset_addr else R[n];
5580 if (index)
5581 address = offset_addr;
5582 else
5583 address = base_address;
5584
5585 // MemU[address,1] = R[t]<7:0>
5586 RegisterInfo base_reg;
5587 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5588
5589 RegisterInfo data_reg;
5590 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5591
5592 EmulateInstruction::Context context;
5593 context.type = eContextRegisterStore;
5594 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5595 address - base_address);
5596
5597 uint32_t data =
5598 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5599 if (!success)
5600 return false;
5601
5602 data = Bits32(data, 7, 0);
5603
5604 if (!MemUWrite(context, address, data, 1))
5605 return false;
5606
5607 // if wback then R[n] = offset_addr;
5608 if (wback) {
5609 context.type = eContextRegisterLoad;
5610 context.SetAddress(offset_addr);
5611 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5612 offset_addr))
5613 return false;
5614 }
5615 }
5616
5617 return true;
5618 }
5619
5620 // STRH (register) calculates an address from a base register value and an
5621 // offset register value, and stores a
5622 // halfword from a register to memory. The offset register value can be
5623 // shifted left by 0, 1, 2, or 3 bits.
EmulateSTRHRegister(const uint32_t opcode,const ARMEncoding encoding)5624 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
5625 const ARMEncoding encoding) {
5626 #if 0
5627 if ConditionPassed() then
5628 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5629 offset = Shift(R[m], shift_t, shift_n, APSR.C);
5630 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5631 address = if index then offset_addr else R[n];
5632 if UnalignedSupport() || address<0> == '0' then
5633 MemU[address,2] = R[t]<15:0>;
5634 else // Can only occur before ARMv7
5635 MemU[address,2] = bits(16) UNKNOWN;
5636 if wback then R[n] = offset_addr;
5637 #endif
5638
5639 bool success = false;
5640
5641 if (ConditionPassed(opcode)) {
5642 uint32_t t;
5643 uint32_t n;
5644 uint32_t m;
5645 bool index;
5646 bool add;
5647 bool wback;
5648 ARM_ShifterType shift_t;
5649 uint32_t shift_n;
5650
5651 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5652 switch (encoding) {
5653 case eEncodingT1:
5654 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5655 // in ThumbEE";
5656 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5657 t = Bits32(opcode, 2, 0);
5658 n = Bits32(opcode, 5, 3);
5659 m = Bits32(opcode, 8, 6);
5660
5661 // index = TRUE; add = TRUE; wback = FALSE;
5662 index = true;
5663 add = true;
5664 wback = false;
5665
5666 // (shift_t, shift_n) = (SRType_LSL, 0);
5667 shift_t = SRType_LSL;
5668 shift_n = 0;
5669
5670 break;
5671
5672 case eEncodingT2:
5673 // if Rn == '1111' then UNDEFINED;
5674 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5675 t = Bits32(opcode, 15, 12);
5676 n = Bits32(opcode, 19, 16);
5677 m = Bits32(opcode, 3, 0);
5678 if (n == 15)
5679 return false;
5680
5681 // index = TRUE; add = TRUE; wback = FALSE;
5682 index = true;
5683 add = true;
5684 wback = false;
5685
5686 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5687 shift_t = SRType_LSL;
5688 shift_n = Bits32(opcode, 5, 4);
5689
5690 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5691 if (BadReg(t) || BadReg(m))
5692 return false;
5693
5694 break;
5695
5696 case eEncodingA1:
5697 // if P == '0' && W == '1' then SEE STRHT;
5698 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5699 t = Bits32(opcode, 15, 12);
5700 n = Bits32(opcode, 19, 16);
5701 m = Bits32(opcode, 3, 0);
5702
5703 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
5704 // (W == '1');
5705 index = BitIsSet(opcode, 24);
5706 add = BitIsSet(opcode, 23);
5707 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5708
5709 // (shift_t, shift_n) = (SRType_LSL, 0);
5710 shift_t = SRType_LSL;
5711 shift_n = 0;
5712
5713 // if t == 15 || m == 15 then UNPREDICTABLE;
5714 if ((t == 15) || (m == 15))
5715 return false;
5716
5717 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5718 if (wback && ((n == 15) || (n == t)))
5719 return false;
5720
5721 break;
5722
5723 default:
5724 return false;
5725 }
5726
5727 uint32_t Rm = ReadCoreReg(m, &success);
5728 if (!success)
5729 return false;
5730
5731 uint32_t Rn = ReadCoreReg(n, &success);
5732 if (!success)
5733 return false;
5734
5735 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5736 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
5737 if (!success)
5738 return false;
5739
5740 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5741 addr_t offset_addr;
5742 if (add)
5743 offset_addr = Rn + offset;
5744 else
5745 offset_addr = Rn - offset;
5746
5747 // address = if index then offset_addr else R[n];
5748 addr_t address;
5749 if (index)
5750 address = offset_addr;
5751 else
5752 address = Rn;
5753
5754 EmulateInstruction::Context context;
5755 context.type = eContextRegisterStore;
5756 RegisterInfo base_reg;
5757 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5758 RegisterInfo offset_reg;
5759 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5760
5761 // if UnalignedSupport() || address<0> == '0' then
5762 if (UnalignedSupport() || BitIsClear(address, 0)) {
5763 // MemU[address,2] = R[t]<15:0>;
5764 uint32_t Rt = ReadCoreReg(t, &success);
5765 if (!success)
5766 return false;
5767
5768 EmulateInstruction::Context context;
5769 context.type = eContextRegisterStore;
5770 RegisterInfo base_reg;
5771 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5772 RegisterInfo offset_reg;
5773 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5774 RegisterInfo data_reg;
5775 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5776 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
5777 data_reg);
5778
5779 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
5780 return false;
5781 } else // Can only occur before ARMv7
5782 {
5783 // MemU[address,2] = bits(16) UNKNOWN;
5784 }
5785
5786 // if wback then R[n] = offset_addr;
5787 if (wback) {
5788 context.type = eContextAdjustBaseRegister;
5789 context.SetAddress(offset_addr);
5790 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5791 offset_addr))
5792 return false;
5793 }
5794 }
5795
5796 return true;
5797 }
5798
5799 // Add with Carry (immediate) adds an immediate value and the carry flag value
5800 // to a register value, and writes the result to the destination register. It
5801 // can optionally update the condition flags based on the result.
EmulateADCImm(const uint32_t opcode,const ARMEncoding encoding)5802 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
5803 const ARMEncoding encoding) {
5804 #if 0
5805 // ARM pseudo code...
5806 if ConditionPassed() then
5807 EncodingSpecificOperations();
5808 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5809 if d == 15 then // Can only occur for ARM encoding
5810 ALUWritePC(result); // setflags is always FALSE here
5811 else
5812 R[d] = result;
5813 if setflags then
5814 APSR.N = result<31>;
5815 APSR.Z = IsZeroBit(result);
5816 APSR.C = carry;
5817 APSR.V = overflow;
5818 #endif
5819
5820 bool success = false;
5821
5822 if (ConditionPassed(opcode)) {
5823 uint32_t Rd, Rn;
5824 uint32_t
5825 imm32; // the immediate value to be added to the value obtained from Rn
5826 bool setflags;
5827 switch (encoding) {
5828 case eEncodingT1:
5829 Rd = Bits32(opcode, 11, 8);
5830 Rn = Bits32(opcode, 19, 16);
5831 setflags = BitIsSet(opcode, 20);
5832 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5833 if (BadReg(Rd) || BadReg(Rn))
5834 return false;
5835 break;
5836 case eEncodingA1:
5837 Rd = Bits32(opcode, 15, 12);
5838 Rn = Bits32(opcode, 19, 16);
5839 setflags = BitIsSet(opcode, 20);
5840 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5841
5842 if (Rd == 15 && setflags)
5843 return EmulateSUBSPcLrEtc(opcode, encoding);
5844 break;
5845 default:
5846 return false;
5847 }
5848
5849 // Read the first operand.
5850 int32_t val1 = ReadCoreReg(Rn, &success);
5851 if (!success)
5852 return false;
5853
5854 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5855
5856 EmulateInstruction::Context context;
5857 context.type = EmulateInstruction::eContextImmediate;
5858 context.SetNoArgs();
5859
5860 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5861 res.carry_out, res.overflow))
5862 return false;
5863 }
5864 return true;
5865 }
5866
5867 // Add with Carry (register) adds a register value, the carry flag value, and
5868 // an optionally-shifted register value, and writes the result to the
5869 // destination register. It can optionally update the condition flags based on
5870 // the result.
EmulateADCReg(const uint32_t opcode,const ARMEncoding encoding)5871 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
5872 const ARMEncoding encoding) {
5873 #if 0
5874 // ARM pseudo code...
5875 if ConditionPassed() then
5876 EncodingSpecificOperations();
5877 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5878 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5879 if d == 15 then // Can only occur for ARM encoding
5880 ALUWritePC(result); // setflags is always FALSE here
5881 else
5882 R[d] = result;
5883 if setflags then
5884 APSR.N = result<31>;
5885 APSR.Z = IsZeroBit(result);
5886 APSR.C = carry;
5887 APSR.V = overflow;
5888 #endif
5889
5890 bool success = false;
5891
5892 if (ConditionPassed(opcode)) {
5893 uint32_t Rd, Rn, Rm;
5894 ARM_ShifterType shift_t;
5895 uint32_t shift_n; // the shift applied to the value read from Rm
5896 bool setflags;
5897 switch (encoding) {
5898 case eEncodingT1:
5899 Rd = Rn = Bits32(opcode, 2, 0);
5900 Rm = Bits32(opcode, 5, 3);
5901 setflags = !InITBlock();
5902 shift_t = SRType_LSL;
5903 shift_n = 0;
5904 break;
5905 case eEncodingT2:
5906 Rd = Bits32(opcode, 11, 8);
5907 Rn = Bits32(opcode, 19, 16);
5908 Rm = Bits32(opcode, 3, 0);
5909 setflags = BitIsSet(opcode, 20);
5910 shift_n = DecodeImmShiftThumb(opcode, shift_t);
5911 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5912 return false;
5913 break;
5914 case eEncodingA1:
5915 Rd = Bits32(opcode, 15, 12);
5916 Rn = Bits32(opcode, 19, 16);
5917 Rm = Bits32(opcode, 3, 0);
5918 setflags = BitIsSet(opcode, 20);
5919 shift_n = DecodeImmShiftARM(opcode, shift_t);
5920
5921 if (Rd == 15 && setflags)
5922 return EmulateSUBSPcLrEtc(opcode, encoding);
5923 break;
5924 default:
5925 return false;
5926 }
5927
5928 // Read the first operand.
5929 int32_t val1 = ReadCoreReg(Rn, &success);
5930 if (!success)
5931 return false;
5932
5933 // Read the second operand.
5934 int32_t val2 = ReadCoreReg(Rm, &success);
5935 if (!success)
5936 return false;
5937
5938 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5939 if (!success)
5940 return false;
5941 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5942
5943 EmulateInstruction::Context context;
5944 context.type = EmulateInstruction::eContextImmediate;
5945 context.SetNoArgs();
5946
5947 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5948 res.carry_out, res.overflow))
5949 return false;
5950 }
5951 return true;
5952 }
5953
5954 // This instruction adds an immediate value to the PC value to form a PC-
5955 // relative address, and writes the result to the destination register.
EmulateADR(const uint32_t opcode,const ARMEncoding encoding)5956 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
5957 const ARMEncoding encoding) {
5958 #if 0
5959 // ARM pseudo code...
5960 if ConditionPassed() then
5961 EncodingSpecificOperations();
5962 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5963 if d == 15 then // Can only occur for ARM encodings
5964 ALUWritePC(result);
5965 else
5966 R[d] = result;
5967 #endif
5968
5969 bool success = false;
5970
5971 if (ConditionPassed(opcode)) {
5972 uint32_t Rd;
5973 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5974 bool add;
5975 switch (encoding) {
5976 case eEncodingT1:
5977 Rd = Bits32(opcode, 10, 8);
5978 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5979 add = true;
5980 break;
5981 case eEncodingT2:
5982 case eEncodingT3:
5983 Rd = Bits32(opcode, 11, 8);
5984 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5985 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5986 if (BadReg(Rd))
5987 return false;
5988 break;
5989 case eEncodingA1:
5990 case eEncodingA2:
5991 Rd = Bits32(opcode, 15, 12);
5992 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5993 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5994 break;
5995 default:
5996 return false;
5997 }
5998
5999 // Read the PC value.
6000 uint32_t pc = ReadCoreReg(PC_REG, &success);
6001 if (!success)
6002 return false;
6003
6004 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
6005
6006 EmulateInstruction::Context context;
6007 context.type = EmulateInstruction::eContextImmediate;
6008 context.SetNoArgs();
6009
6010 if (!WriteCoreReg(context, result, Rd))
6011 return false;
6012 }
6013 return true;
6014 }
6015
6016 // This instruction performs a bitwise AND of a register value and an immediate
6017 // value, and writes the result to the destination register. It can optionally
6018 // update the condition flags based on the result.
EmulateANDImm(const uint32_t opcode,const ARMEncoding encoding)6019 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
6020 const ARMEncoding encoding) {
6021 #if 0
6022 // ARM pseudo code...
6023 if ConditionPassed() then
6024 EncodingSpecificOperations();
6025 result = R[n] AND imm32;
6026 if d == 15 then // Can only occur for ARM encoding
6027 ALUWritePC(result); // setflags is always FALSE here
6028 else
6029 R[d] = result;
6030 if setflags then
6031 APSR.N = result<31>;
6032 APSR.Z = IsZeroBit(result);
6033 APSR.C = carry;
6034 // APSR.V unchanged
6035 #endif
6036
6037 bool success = false;
6038
6039 if (ConditionPassed(opcode)) {
6040 uint32_t Rd, Rn;
6041 uint32_t
6042 imm32; // the immediate value to be ANDed to the value obtained from Rn
6043 bool setflags;
6044 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6045 switch (encoding) {
6046 case eEncodingT1:
6047 Rd = Bits32(opcode, 11, 8);
6048 Rn = Bits32(opcode, 19, 16);
6049 setflags = BitIsSet(opcode, 20);
6050 imm32 = ThumbExpandImm_C(
6051 opcode, APSR_C,
6052 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6053 // if Rd == '1111' && S == '1' then SEE TST (immediate);
6054 if (Rd == 15 && setflags)
6055 return EmulateTSTImm(opcode, eEncodingT1);
6056 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
6057 return false;
6058 break;
6059 case eEncodingA1:
6060 Rd = Bits32(opcode, 15, 12);
6061 Rn = Bits32(opcode, 19, 16);
6062 setflags = BitIsSet(opcode, 20);
6063 imm32 =
6064 ARMExpandImm_C(opcode, APSR_C,
6065 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6066
6067 if (Rd == 15 && setflags)
6068 return EmulateSUBSPcLrEtc(opcode, encoding);
6069 break;
6070 default:
6071 return false;
6072 }
6073
6074 // Read the first operand.
6075 uint32_t val1 = ReadCoreReg(Rn, &success);
6076 if (!success)
6077 return false;
6078
6079 uint32_t result = val1 & imm32;
6080
6081 EmulateInstruction::Context context;
6082 context.type = EmulateInstruction::eContextImmediate;
6083 context.SetNoArgs();
6084
6085 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6086 return false;
6087 }
6088 return true;
6089 }
6090
6091 // This instruction performs a bitwise AND of a register value and an
6092 // optionally-shifted register value, and writes the result to the destination
6093 // register. It can optionally update the condition flags based on the result.
EmulateANDReg(const uint32_t opcode,const ARMEncoding encoding)6094 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
6095 const ARMEncoding encoding) {
6096 #if 0
6097 // ARM pseudo code...
6098 if ConditionPassed() then
6099 EncodingSpecificOperations();
6100 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6101 result = R[n] AND shifted;
6102 if d == 15 then // Can only occur for ARM encoding
6103 ALUWritePC(result); // setflags is always FALSE here
6104 else
6105 R[d] = result;
6106 if setflags then
6107 APSR.N = result<31>;
6108 APSR.Z = IsZeroBit(result);
6109 APSR.C = carry;
6110 // APSR.V unchanged
6111 #endif
6112
6113 bool success = false;
6114
6115 if (ConditionPassed(opcode)) {
6116 uint32_t Rd, Rn, Rm;
6117 ARM_ShifterType shift_t;
6118 uint32_t shift_n; // the shift applied to the value read from Rm
6119 bool setflags;
6120 uint32_t carry;
6121 switch (encoding) {
6122 case eEncodingT1:
6123 Rd = Rn = Bits32(opcode, 2, 0);
6124 Rm = Bits32(opcode, 5, 3);
6125 setflags = !InITBlock();
6126 shift_t = SRType_LSL;
6127 shift_n = 0;
6128 break;
6129 case eEncodingT2:
6130 Rd = Bits32(opcode, 11, 8);
6131 Rn = Bits32(opcode, 19, 16);
6132 Rm = Bits32(opcode, 3, 0);
6133 setflags = BitIsSet(opcode, 20);
6134 shift_n = DecodeImmShiftThumb(opcode, shift_t);
6135 // if Rd == '1111' && S == '1' then SEE TST (register);
6136 if (Rd == 15 && setflags)
6137 return EmulateTSTReg(opcode, eEncodingT2);
6138 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
6139 return false;
6140 break;
6141 case eEncodingA1:
6142 Rd = Bits32(opcode, 15, 12);
6143 Rn = Bits32(opcode, 19, 16);
6144 Rm = Bits32(opcode, 3, 0);
6145 setflags = BitIsSet(opcode, 20);
6146 shift_n = DecodeImmShiftARM(opcode, shift_t);
6147
6148 if (Rd == 15 && setflags)
6149 return EmulateSUBSPcLrEtc(opcode, encoding);
6150 break;
6151 default:
6152 return false;
6153 }
6154
6155 // Read the first operand.
6156 uint32_t val1 = ReadCoreReg(Rn, &success);
6157 if (!success)
6158 return false;
6159
6160 // Read the second operand.
6161 uint32_t val2 = ReadCoreReg(Rm, &success);
6162 if (!success)
6163 return false;
6164
6165 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6166 if (!success)
6167 return false;
6168 uint32_t result = val1 & shifted;
6169
6170 EmulateInstruction::Context context;
6171 context.type = EmulateInstruction::eContextImmediate;
6172 context.SetNoArgs();
6173
6174 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6175 return false;
6176 }
6177 return true;
6178 }
6179
6180 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
6181 // the complement of an immediate value, and writes the result to the
6182 // destination register. It can optionally update the condition flags based on
6183 // the result.
EmulateBICImm(const uint32_t opcode,const ARMEncoding encoding)6184 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
6185 const ARMEncoding encoding) {
6186 #if 0
6187 // ARM pseudo code...
6188 if ConditionPassed() then
6189 EncodingSpecificOperations();
6190 result = R[n] AND NOT(imm32);
6191 if d == 15 then // Can only occur for ARM encoding
6192 ALUWritePC(result); // setflags is always FALSE here
6193 else
6194 R[d] = result;
6195 if setflags then
6196 APSR.N = result<31>;
6197 APSR.Z = IsZeroBit(result);
6198 APSR.C = carry;
6199 // APSR.V unchanged
6200 #endif
6201
6202 bool success = false;
6203
6204 if (ConditionPassed(opcode)) {
6205 uint32_t Rd, Rn;
6206 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
6207 // the value obtained from Rn
6208 bool setflags;
6209 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6210 switch (encoding) {
6211 case eEncodingT1:
6212 Rd = Bits32(opcode, 11, 8);
6213 Rn = Bits32(opcode, 19, 16);
6214 setflags = BitIsSet(opcode, 20);
6215 imm32 = ThumbExpandImm_C(
6216 opcode, APSR_C,
6217 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6218 if (BadReg(Rd) || BadReg(Rn))
6219 return false;
6220 break;
6221 case eEncodingA1:
6222 Rd = Bits32(opcode, 15, 12);
6223 Rn = Bits32(opcode, 19, 16);
6224 setflags = BitIsSet(opcode, 20);
6225 imm32 =
6226 ARMExpandImm_C(opcode, APSR_C,
6227 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6228
6229 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6230 // instructions;
6231 if (Rd == 15 && setflags)
6232 return EmulateSUBSPcLrEtc(opcode, encoding);
6233 break;
6234 default:
6235 return false;
6236 }
6237
6238 // Read the first operand.
6239 uint32_t val1 = ReadCoreReg(Rn, &success);
6240 if (!success)
6241 return false;
6242
6243 uint32_t result = val1 & ~imm32;
6244
6245 EmulateInstruction::Context context;
6246 context.type = EmulateInstruction::eContextImmediate;
6247 context.SetNoArgs();
6248
6249 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6250 return false;
6251 }
6252 return true;
6253 }
6254
6255 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and
6256 // the complement of an optionally-shifted register value, and writes the
6257 // result to the destination register. It can optionally update the condition
6258 // flags based on the result.
EmulateBICReg(const uint32_t opcode,const ARMEncoding encoding)6259 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
6260 const ARMEncoding encoding) {
6261 #if 0
6262 // ARM pseudo code...
6263 if ConditionPassed() then
6264 EncodingSpecificOperations();
6265 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6266 result = R[n] AND NOT(shifted);
6267 if d == 15 then // Can only occur for ARM encoding
6268 ALUWritePC(result); // setflags is always FALSE here
6269 else
6270 R[d] = result;
6271 if setflags then
6272 APSR.N = result<31>;
6273 APSR.Z = IsZeroBit(result);
6274 APSR.C = carry;
6275 // APSR.V unchanged
6276 #endif
6277
6278 bool success = false;
6279
6280 if (ConditionPassed(opcode)) {
6281 uint32_t Rd, Rn, Rm;
6282 ARM_ShifterType shift_t;
6283 uint32_t shift_n; // the shift applied to the value read from Rm
6284 bool setflags;
6285 uint32_t carry;
6286 switch (encoding) {
6287 case eEncodingT1:
6288 Rd = Rn = Bits32(opcode, 2, 0);
6289 Rm = Bits32(opcode, 5, 3);
6290 setflags = !InITBlock();
6291 shift_t = SRType_LSL;
6292 shift_n = 0;
6293 break;
6294 case eEncodingT2:
6295 Rd = Bits32(opcode, 11, 8);
6296 Rn = Bits32(opcode, 19, 16);
6297 Rm = Bits32(opcode, 3, 0);
6298 setflags = BitIsSet(opcode, 20);
6299 shift_n = DecodeImmShiftThumb(opcode, shift_t);
6300 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
6301 return false;
6302 break;
6303 case eEncodingA1:
6304 Rd = Bits32(opcode, 15, 12);
6305 Rn = Bits32(opcode, 19, 16);
6306 Rm = Bits32(opcode, 3, 0);
6307 setflags = BitIsSet(opcode, 20);
6308 shift_n = DecodeImmShiftARM(opcode, shift_t);
6309
6310 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6311 // instructions;
6312 if (Rd == 15 && setflags)
6313 return EmulateSUBSPcLrEtc(opcode, encoding);
6314 break;
6315 default:
6316 return false;
6317 }
6318
6319 // Read the first operand.
6320 uint32_t val1 = ReadCoreReg(Rn, &success);
6321 if (!success)
6322 return false;
6323
6324 // Read the second operand.
6325 uint32_t val2 = ReadCoreReg(Rm, &success);
6326 if (!success)
6327 return false;
6328
6329 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6330 if (!success)
6331 return false;
6332 uint32_t result = val1 & ~shifted;
6333
6334 EmulateInstruction::Context context;
6335 context.type = EmulateInstruction::eContextImmediate;
6336 context.SetNoArgs();
6337
6338 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6339 return false;
6340 }
6341 return true;
6342 }
6343
6344 // LDR (immediate, ARM) calculates an address from a base register value and an
6345 // immediate offset, loads a word
6346 // from memory, and writes it to a register. It can use offset, post-indexed,
6347 // or pre-indexed addressing.
EmulateLDRImmediateARM(const uint32_t opcode,const ARMEncoding encoding)6348 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
6349 const ARMEncoding encoding) {
6350 #if 0
6351 if ConditionPassed() then
6352 EncodingSpecificOperations();
6353 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6354 address = if index then offset_addr else R[n];
6355 data = MemU[address,4];
6356 if wback then R[n] = offset_addr;
6357 if t == 15 then
6358 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6359 elsif UnalignedSupport() || address<1:0> = '00' then
6360 R[t] = data;
6361 else // Can only apply before ARMv7
6362 R[t] = ROR(data, 8*UInt(address<1:0>));
6363 #endif
6364
6365 bool success = false;
6366
6367 if (ConditionPassed(opcode)) {
6368 const uint32_t addr_byte_size = GetAddressByteSize();
6369
6370 uint32_t t;
6371 uint32_t n;
6372 uint32_t imm32;
6373 bool index;
6374 bool add;
6375 bool wback;
6376
6377 switch (encoding) {
6378 case eEncodingA1:
6379 // if Rn == '1111' then SEE LDR (literal);
6380 // if P == '0' && W == '1' then SEE LDRT;
6381 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
6382 // '000000000100' then SEE POP;
6383 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6384 t = Bits32(opcode, 15, 12);
6385 n = Bits32(opcode, 19, 16);
6386 imm32 = Bits32(opcode, 11, 0);
6387
6388 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
6389 // (W == '1');
6390 index = BitIsSet(opcode, 24);
6391 add = BitIsSet(opcode, 23);
6392 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6393
6394 // if wback && n == t then UNPREDICTABLE;
6395 if (wback && (n == t))
6396 return false;
6397
6398 break;
6399
6400 default:
6401 return false;
6402 }
6403
6404 addr_t address;
6405 addr_t offset_addr;
6406 addr_t base_address = ReadCoreReg(n, &success);
6407 if (!success)
6408 return false;
6409
6410 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6411 if (add)
6412 offset_addr = base_address + imm32;
6413 else
6414 offset_addr = base_address - imm32;
6415
6416 // address = if index then offset_addr else R[n];
6417 if (index)
6418 address = offset_addr;
6419 else
6420 address = base_address;
6421
6422 // data = MemU[address,4];
6423
6424 RegisterInfo base_reg;
6425 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6426
6427 EmulateInstruction::Context context;
6428 context.type = eContextRegisterLoad;
6429 context.SetRegisterPlusOffset(base_reg, address - base_address);
6430
6431 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6432 if (!success)
6433 return false;
6434
6435 // if wback then R[n] = offset_addr;
6436 if (wback) {
6437 context.type = eContextAdjustBaseRegister;
6438 context.SetAddress(offset_addr);
6439 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6440 offset_addr))
6441 return false;
6442 }
6443
6444 // if t == 15 then
6445 if (t == 15) {
6446 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6447 if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6448 // LoadWritePC (data);
6449 context.type = eContextRegisterLoad;
6450 context.SetRegisterPlusOffset(base_reg, address - base_address);
6451 LoadWritePC(context, data);
6452 } else
6453 return false;
6454 }
6455 // elsif UnalignedSupport() || address<1:0> = '00' then
6456 else if (UnalignedSupport() ||
6457 (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6458 // R[t] = data;
6459 context.type = eContextRegisterLoad;
6460 context.SetRegisterPlusOffset(base_reg, address - base_address);
6461 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6462 data))
6463 return false;
6464 }
6465 // else // Can only apply before ARMv7
6466 else {
6467 // R[t] = ROR(data, 8*UInt(address<1:0>));
6468 data = ROR(data, Bits32(address, 1, 0), &success);
6469 if (!success)
6470 return false;
6471 context.type = eContextRegisterLoad;
6472 context.SetImmediate(data);
6473 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6474 data))
6475 return false;
6476 }
6477 }
6478 return true;
6479 }
6480
6481 // LDR (register) calculates an address from a base register value and an offset
6482 // register value, loads a word
6483 // from memory, and writes it to a register. The offset register value can
6484 // optionally be shifted.
EmulateLDRRegister(const uint32_t opcode,const ARMEncoding encoding)6485 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
6486 const ARMEncoding encoding) {
6487 #if 0
6488 if ConditionPassed() then
6489 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6490 offset = Shift(R[m], shift_t, shift_n, APSR.C);
6491 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6492 address = if index then offset_addr else R[n];
6493 data = MemU[address,4];
6494 if wback then R[n] = offset_addr;
6495 if t == 15 then
6496 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6497 elsif UnalignedSupport() || address<1:0> = '00' then
6498 R[t] = data;
6499 else // Can only apply before ARMv7
6500 if CurrentInstrSet() == InstrSet_ARM then
6501 R[t] = ROR(data, 8*UInt(address<1:0>));
6502 else
6503 R[t] = bits(32) UNKNOWN;
6504 #endif
6505
6506 bool success = false;
6507
6508 if (ConditionPassed(opcode)) {
6509 const uint32_t addr_byte_size = GetAddressByteSize();
6510
6511 uint32_t t;
6512 uint32_t n;
6513 uint32_t m;
6514 bool index;
6515 bool add;
6516 bool wback;
6517 ARM_ShifterType shift_t;
6518 uint32_t shift_n;
6519
6520 switch (encoding) {
6521 case eEncodingT1:
6522 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6523 // in ThumbEE";
6524 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6525 t = Bits32(opcode, 2, 0);
6526 n = Bits32(opcode, 5, 3);
6527 m = Bits32(opcode, 8, 6);
6528
6529 // index = TRUE; add = TRUE; wback = FALSE;
6530 index = true;
6531 add = true;
6532 wback = false;
6533
6534 // (shift_t, shift_n) = (SRType_LSL, 0);
6535 shift_t = SRType_LSL;
6536 shift_n = 0;
6537
6538 break;
6539
6540 case eEncodingT2:
6541 // if Rn == '1111' then SEE LDR (literal);
6542 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6543 t = Bits32(opcode, 15, 12);
6544 n = Bits32(opcode, 19, 16);
6545 m = Bits32(opcode, 3, 0);
6546
6547 // index = TRUE; add = TRUE; wback = FALSE;
6548 index = true;
6549 add = true;
6550 wback = false;
6551
6552 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6553 shift_t = SRType_LSL;
6554 shift_n = Bits32(opcode, 5, 4);
6555
6556 // if BadReg(m) then UNPREDICTABLE;
6557 if (BadReg(m))
6558 return false;
6559
6560 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6561 if ((t == 15) && InITBlock() && !LastInITBlock())
6562 return false;
6563
6564 break;
6565
6566 case eEncodingA1: {
6567 // if P == '0' && W == '1' then SEE LDRT;
6568 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6569 t = Bits32(opcode, 15, 12);
6570 n = Bits32(opcode, 19, 16);
6571 m = Bits32(opcode, 3, 0);
6572
6573 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
6574 // (W == '1');
6575 index = BitIsSet(opcode, 24);
6576 add = BitIsSet(opcode, 23);
6577 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6578
6579 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6580 uint32_t type = Bits32(opcode, 6, 5);
6581 uint32_t imm5 = Bits32(opcode, 11, 7);
6582 shift_n = DecodeImmShift(type, imm5, shift_t);
6583
6584 // if m == 15 then UNPREDICTABLE;
6585 if (m == 15)
6586 return false;
6587
6588 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6589 if (wback && ((n == 15) || (n == t)))
6590 return false;
6591 } break;
6592
6593 default:
6594 return false;
6595 }
6596
6597 uint32_t Rm =
6598 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6599 if (!success)
6600 return false;
6601
6602 uint32_t Rn =
6603 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6604 if (!success)
6605 return false;
6606
6607 addr_t offset_addr;
6608 addr_t address;
6609
6610 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is
6611 // an application level alias for the CPSR".
6612 addr_t offset =
6613 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
6614 if (!success)
6615 return false;
6616
6617 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6618 if (add)
6619 offset_addr = Rn + offset;
6620 else
6621 offset_addr = Rn - offset;
6622
6623 // address = if index then offset_addr else R[n];
6624 if (index)
6625 address = offset_addr;
6626 else
6627 address = Rn;
6628
6629 // data = MemU[address,4];
6630 RegisterInfo base_reg;
6631 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6632
6633 EmulateInstruction::Context context;
6634 context.type = eContextRegisterLoad;
6635 context.SetRegisterPlusOffset(base_reg, address - Rn);
6636
6637 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6638 if (!success)
6639 return false;
6640
6641 // if wback then R[n] = offset_addr;
6642 if (wback) {
6643 context.type = eContextAdjustBaseRegister;
6644 context.SetAddress(offset_addr);
6645 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6646 offset_addr))
6647 return false;
6648 }
6649
6650 // if t == 15 then
6651 if (t == 15) {
6652 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6653 if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6654 context.type = eContextRegisterLoad;
6655 context.SetRegisterPlusOffset(base_reg, address - Rn);
6656 LoadWritePC(context, data);
6657 } else
6658 return false;
6659 }
6660 // elsif UnalignedSupport() || address<1:0> = '00' then
6661 else if (UnalignedSupport() ||
6662 (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6663 // R[t] = data;
6664 context.type = eContextRegisterLoad;
6665 context.SetRegisterPlusOffset(base_reg, address - Rn);
6666 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6667 data))
6668 return false;
6669 } else // Can only apply before ARMv7
6670 {
6671 // if CurrentInstrSet() == InstrSet_ARM then
6672 if (CurrentInstrSet() == eModeARM) {
6673 // R[t] = ROR(data, 8*UInt(address<1:0>));
6674 data = ROR(data, Bits32(address, 1, 0), &success);
6675 if (!success)
6676 return false;
6677 context.type = eContextRegisterLoad;
6678 context.SetImmediate(data);
6679 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6680 data))
6681 return false;
6682 } else {
6683 // R[t] = bits(32) UNKNOWN;
6684 WriteBits32Unknown(t);
6685 }
6686 }
6687 }
6688 return true;
6689 }
6690
6691 // LDRB (immediate, Thumb)
EmulateLDRBImmediate(const uint32_t opcode,const ARMEncoding encoding)6692 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
6693 const ARMEncoding encoding) {
6694 #if 0
6695 if ConditionPassed() then
6696 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6697 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6698 address = if index then offset_addr else R[n];
6699 R[t] = ZeroExtend(MemU[address,1], 32);
6700 if wback then R[n] = offset_addr;
6701 #endif
6702
6703 bool success = false;
6704
6705 if (ConditionPassed(opcode)) {
6706 uint32_t t;
6707 uint32_t n;
6708 uint32_t imm32;
6709 bool index;
6710 bool add;
6711 bool wback;
6712
6713 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6714 switch (encoding) {
6715 case eEncodingT1:
6716 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6717 t = Bits32(opcode, 2, 0);
6718 n = Bits32(opcode, 5, 3);
6719 imm32 = Bits32(opcode, 10, 6);
6720
6721 // index = TRUE; add = TRUE; wback = FALSE;
6722 index = true;
6723 add = true;
6724 wback = false;
6725
6726 break;
6727
6728 case eEncodingT2:
6729 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6730 t = Bits32(opcode, 15, 12);
6731 n = Bits32(opcode, 19, 16);
6732 imm32 = Bits32(opcode, 11, 0);
6733
6734 // index = TRUE; add = TRUE; wback = FALSE;
6735 index = true;
6736 add = true;
6737 wback = false;
6738
6739 // if Rt == '1111' then SEE PLD;
6740 if (t == 15)
6741 return false; // PLD is not implemented yet
6742
6743 // if Rn == '1111' then SEE LDRB (literal);
6744 if (n == 15)
6745 return EmulateLDRBLiteral(opcode, eEncodingT1);
6746
6747 // if t == 13 then UNPREDICTABLE;
6748 if (t == 13)
6749 return false;
6750
6751 break;
6752
6753 case eEncodingT3:
6754 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6755 // if P == '0' && W == '0' then UNDEFINED;
6756 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6757 return false;
6758
6759 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6760 t = Bits32(opcode, 15, 12);
6761 n = Bits32(opcode, 19, 16);
6762 imm32 = Bits32(opcode, 7, 0);
6763
6764 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6765 index = BitIsSet(opcode, 10);
6766 add = BitIsSet(opcode, 9);
6767 wback = BitIsSet(opcode, 8);
6768
6769 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6770 if (t == 15)
6771 return false; // PLD is not implemented yet
6772
6773 // if Rn == '1111' then SEE LDRB (literal);
6774 if (n == 15)
6775 return EmulateLDRBLiteral(opcode, eEncodingT1);
6776
6777 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6778 if (BadReg(t) || (wback && (n == t)))
6779 return false;
6780
6781 break;
6782
6783 default:
6784 return false;
6785 }
6786
6787 uint32_t Rn =
6788 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6789 if (!success)
6790 return false;
6791
6792 addr_t address;
6793 addr_t offset_addr;
6794
6795 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6796 if (add)
6797 offset_addr = Rn + imm32;
6798 else
6799 offset_addr = Rn - imm32;
6800
6801 // address = if index then offset_addr else R[n];
6802 if (index)
6803 address = offset_addr;
6804 else
6805 address = Rn;
6806
6807 // R[t] = ZeroExtend(MemU[address,1], 32);
6808 RegisterInfo base_reg;
6809 RegisterInfo data_reg;
6810 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6811 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6812
6813 EmulateInstruction::Context context;
6814 context.type = eContextRegisterLoad;
6815 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
6816
6817 uint64_t data = MemURead(context, address, 1, 0, &success);
6818 if (!success)
6819 return false;
6820
6821 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6822 return false;
6823
6824 // if wback then R[n] = offset_addr;
6825 if (wback) {
6826 context.type = eContextAdjustBaseRegister;
6827 context.SetAddress(offset_addr);
6828 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6829 offset_addr))
6830 return false;
6831 }
6832 }
6833 return true;
6834 }
6835
6836 // LDRB (literal) calculates an address from the PC value and an immediate
6837 // offset, loads a byte from memory,
6838 // zero-extends it to form a 32-bit word and writes it to a register.
EmulateLDRBLiteral(const uint32_t opcode,const ARMEncoding encoding)6839 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
6840 const ARMEncoding encoding) {
6841 #if 0
6842 if ConditionPassed() then
6843 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6844 base = Align(PC,4);
6845 address = if add then (base + imm32) else (base - imm32);
6846 R[t] = ZeroExtend(MemU[address,1], 32);
6847 #endif
6848
6849 bool success = false;
6850
6851 if (ConditionPassed(opcode)) {
6852 uint32_t t;
6853 uint32_t imm32;
6854 bool add;
6855 switch (encoding) {
6856 case eEncodingT1:
6857 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6858 t = Bits32(opcode, 15, 12);
6859 imm32 = Bits32(opcode, 11, 0);
6860 add = BitIsSet(opcode, 23);
6861
6862 // if Rt == '1111' then SEE PLD;
6863 if (t == 15)
6864 return false; // PLD is not implemented yet
6865
6866 // if t == 13 then UNPREDICTABLE;
6867 if (t == 13)
6868 return false;
6869
6870 break;
6871
6872 case eEncodingA1:
6873 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6874 t = Bits32(opcode, 15, 12);
6875 imm32 = Bits32(opcode, 11, 0);
6876 add = BitIsSet(opcode, 23);
6877
6878 // if t == 15 then UNPREDICTABLE;
6879 if (t == 15)
6880 return false;
6881 break;
6882
6883 default:
6884 return false;
6885 }
6886
6887 // base = Align(PC,4);
6888 uint32_t pc_val = ReadCoreReg(PC_REG, &success);
6889 if (!success)
6890 return false;
6891
6892 uint32_t base = AlignPC(pc_val);
6893
6894 addr_t address;
6895 // address = if add then (base + imm32) else (base - imm32);
6896 if (add)
6897 address = base + imm32;
6898 else
6899 address = base - imm32;
6900
6901 // R[t] = ZeroExtend(MemU[address,1], 32);
6902 EmulateInstruction::Context context;
6903 context.type = eContextRelativeBranchImmediate;
6904 context.SetImmediate(address - base);
6905
6906 uint64_t data = MemURead(context, address, 1, 0, &success);
6907 if (!success)
6908 return false;
6909
6910 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6911 return false;
6912 }
6913 return true;
6914 }
6915
6916 // LDRB (register) calculates an address from a base register value and an
6917 // offset rigister value, loads a byte from memory, zero-extends it to form a
6918 // 32-bit word, and writes it to a register. The offset register value can
6919 // optionally be shifted.
EmulateLDRBRegister(const uint32_t opcode,const ARMEncoding encoding)6920 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
6921 const ARMEncoding encoding) {
6922 #if 0
6923 if ConditionPassed() then
6924 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6925 offset = Shift(R[m], shift_t, shift_n, APSR.C);
6926 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6927 address = if index then offset_addr else R[n];
6928 R[t] = ZeroExtend(MemU[address,1],32);
6929 if wback then R[n] = offset_addr;
6930 #endif
6931
6932 bool success = false;
6933
6934 if (ConditionPassed(opcode)) {
6935 uint32_t t;
6936 uint32_t n;
6937 uint32_t m;
6938 bool index;
6939 bool add;
6940 bool wback;
6941 ARM_ShifterType shift_t;
6942 uint32_t shift_n;
6943
6944 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6945 switch (encoding) {
6946 case eEncodingT1:
6947 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6948 t = Bits32(opcode, 2, 0);
6949 n = Bits32(opcode, 5, 3);
6950 m = Bits32(opcode, 8, 6);
6951
6952 // index = TRUE; add = TRUE; wback = FALSE;
6953 index = true;
6954 add = true;
6955 wback = false;
6956
6957 // (shift_t, shift_n) = (SRType_LSL, 0);
6958 shift_t = SRType_LSL;
6959 shift_n = 0;
6960 break;
6961
6962 case eEncodingT2:
6963 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6964 t = Bits32(opcode, 15, 12);
6965 n = Bits32(opcode, 19, 16);
6966 m = Bits32(opcode, 3, 0);
6967
6968 // index = TRUE; add = TRUE; wback = FALSE;
6969 index = true;
6970 add = true;
6971 wback = false;
6972
6973 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6974 shift_t = SRType_LSL;
6975 shift_n = Bits32(opcode, 5, 4);
6976
6977 // if Rt == '1111' then SEE PLD;
6978 if (t == 15)
6979 return false; // PLD is not implemented yet
6980
6981 // if Rn == '1111' then SEE LDRB (literal);
6982 if (n == 15)
6983 return EmulateLDRBLiteral(opcode, eEncodingT1);
6984
6985 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6986 if ((t == 13) || BadReg(m))
6987 return false;
6988 break;
6989
6990 case eEncodingA1: {
6991 // if P == '0' && W == '1' then SEE LDRBT;
6992 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6993 t = Bits32(opcode, 15, 12);
6994 n = Bits32(opcode, 19, 16);
6995 m = Bits32(opcode, 3, 0);
6996
6997 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
6998 // (W == '1');
6999 index = BitIsSet(opcode, 24);
7000 add = BitIsSet(opcode, 23);
7001 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7002
7003 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
7004 uint32_t type = Bits32(opcode, 6, 5);
7005 uint32_t imm5 = Bits32(opcode, 11, 7);
7006 shift_n = DecodeImmShift(type, imm5, shift_t);
7007
7008 // if t == 15 || m == 15 then UNPREDICTABLE;
7009 if ((t == 15) || (m == 15))
7010 return false;
7011
7012 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7013 if (wback && ((n == 15) || (n == t)))
7014 return false;
7015 } break;
7016
7017 default:
7018 return false;
7019 }
7020
7021 addr_t offset_addr;
7022 addr_t address;
7023
7024 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7025 uint32_t Rm =
7026 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7027 if (!success)
7028 return false;
7029
7030 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7031 if (!success)
7032 return false;
7033
7034 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7035 uint32_t Rn =
7036 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7037 if (!success)
7038 return false;
7039
7040 if (add)
7041 offset_addr = Rn + offset;
7042 else
7043 offset_addr = Rn - offset;
7044
7045 // address = if index then offset_addr else R[n];
7046 if (index)
7047 address = offset_addr;
7048 else
7049 address = Rn;
7050
7051 // R[t] = ZeroExtend(MemU[address,1],32);
7052 RegisterInfo base_reg;
7053 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7054
7055 EmulateInstruction::Context context;
7056 context.type = eContextRegisterLoad;
7057 context.SetRegisterPlusOffset(base_reg, address - Rn);
7058
7059 uint64_t data = MemURead(context, address, 1, 0, &success);
7060 if (!success)
7061 return false;
7062
7063 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
7064 return false;
7065
7066 // if wback then R[n] = offset_addr;
7067 if (wback) {
7068 context.type = eContextAdjustBaseRegister;
7069 context.SetAddress(offset_addr);
7070 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7071 offset_addr))
7072 return false;
7073 }
7074 }
7075 return true;
7076 }
7077
7078 // LDRH (immediate, Thumb) calculates an address from a base register value and
7079 // an immediate offset, loads a
7080 // halfword from memory, zero-extends it to form a 32-bit word, and writes it
7081 // to a register. It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRHImmediate(const uint32_t opcode,const ARMEncoding encoding)7082 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
7083 const ARMEncoding encoding) {
7084 #if 0
7085 if ConditionPassed() then
7086 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7087 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7088 address = if index then offset_addr else R[n];
7089 data = MemU[address,2];
7090 if wback then R[n] = offset_addr;
7091 if UnalignedSupport() || address<0> = '0' then
7092 R[t] = ZeroExtend(data, 32);
7093 else // Can only apply before ARMv7
7094 R[t] = bits(32) UNKNOWN;
7095 #endif
7096
7097 bool success = false;
7098
7099 if (ConditionPassed(opcode)) {
7100 uint32_t t;
7101 uint32_t n;
7102 uint32_t imm32;
7103 bool index;
7104 bool add;
7105 bool wback;
7106
7107 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7108 switch (encoding) {
7109 case eEncodingT1:
7110 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
7111 t = Bits32(opcode, 2, 0);
7112 n = Bits32(opcode, 5, 3);
7113 imm32 = Bits32(opcode, 10, 6) << 1;
7114
7115 // index = TRUE; add = TRUE; wback = FALSE;
7116 index = true;
7117 add = true;
7118 wback = false;
7119
7120 break;
7121
7122 case eEncodingT2:
7123 // if Rt == '1111' then SEE "Unallocated memory hints";
7124 // if Rn == '1111' then SEE LDRH (literal);
7125 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7126 t = Bits32(opcode, 15, 12);
7127 n = Bits32(opcode, 19, 16);
7128 imm32 = Bits32(opcode, 11, 0);
7129
7130 // index = TRUE; add = TRUE; wback = FALSE;
7131 index = true;
7132 add = true;
7133 wback = false;
7134
7135 // if t == 13 then UNPREDICTABLE;
7136 if (t == 13)
7137 return false;
7138 break;
7139
7140 case eEncodingT3:
7141 // if Rn == '1111' then SEE LDRH (literal);
7142 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7143 // "Unallocated memory hints";
7144 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
7145 // if P == '0' && W == '0' then UNDEFINED;
7146 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7147 return false;
7148
7149 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7150 t = Bits32(opcode, 15, 12);
7151 n = Bits32(opcode, 19, 16);
7152 imm32 = Bits32(opcode, 7, 0);
7153
7154 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7155 index = BitIsSet(opcode, 10);
7156 add = BitIsSet(opcode, 9);
7157 wback = BitIsSet(opcode, 8);
7158
7159 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7160 if (BadReg(t) || (wback && (n == t)))
7161 return false;
7162 break;
7163
7164 default:
7165 return false;
7166 }
7167
7168 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7169 uint32_t Rn =
7170 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7171 if (!success)
7172 return false;
7173
7174 addr_t offset_addr;
7175 addr_t address;
7176
7177 if (add)
7178 offset_addr = Rn + imm32;
7179 else
7180 offset_addr = Rn - imm32;
7181
7182 // address = if index then offset_addr else R[n];
7183 if (index)
7184 address = offset_addr;
7185 else
7186 address = Rn;
7187
7188 // data = MemU[address,2];
7189 RegisterInfo base_reg;
7190 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7191
7192 EmulateInstruction::Context context;
7193 context.type = eContextRegisterLoad;
7194 context.SetRegisterPlusOffset(base_reg, address - Rn);
7195
7196 uint64_t data = MemURead(context, address, 2, 0, &success);
7197 if (!success)
7198 return false;
7199
7200 // if wback then R[n] = offset_addr;
7201 if (wback) {
7202 context.type = eContextAdjustBaseRegister;
7203 context.SetAddress(offset_addr);
7204 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7205 offset_addr))
7206 return false;
7207 }
7208
7209 // if UnalignedSupport() || address<0> = '0' then
7210 if (UnalignedSupport() || BitIsClear(address, 0)) {
7211 // R[t] = ZeroExtend(data, 32);
7212 context.type = eContextRegisterLoad;
7213 context.SetRegisterPlusOffset(base_reg, address - Rn);
7214 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7215 data))
7216 return false;
7217 } else // Can only apply before ARMv7
7218 {
7219 // R[t] = bits(32) UNKNOWN;
7220 WriteBits32Unknown(t);
7221 }
7222 }
7223 return true;
7224 }
7225
7226 // LDRH (literal) calculates an address from the PC value and an immediate
7227 // offset, loads a halfword from memory,
7228 // zero-extends it to form a 32-bit word, and writes it to a register.
EmulateLDRHLiteral(const uint32_t opcode,const ARMEncoding encoding)7229 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
7230 const ARMEncoding encoding) {
7231 #if 0
7232 if ConditionPassed() then
7233 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7234 base = Align(PC,4);
7235 address = if add then (base + imm32) else (base - imm32);
7236 data = MemU[address,2];
7237 if UnalignedSupport() || address<0> = '0' then
7238 R[t] = ZeroExtend(data, 32);
7239 else // Can only apply before ARMv7
7240 R[t] = bits(32) UNKNOWN;
7241 #endif
7242
7243 bool success = false;
7244
7245 if (ConditionPassed(opcode)) {
7246 uint32_t t;
7247 uint32_t imm32;
7248 bool add;
7249
7250 // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7251 switch (encoding) {
7252 case eEncodingT1:
7253 // if Rt == '1111' then SEE "Unallocated memory hints";
7254 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7255 t = Bits32(opcode, 15, 12);
7256 imm32 = Bits32(opcode, 11, 0);
7257 add = BitIsSet(opcode, 23);
7258
7259 // if t == 13 then UNPREDICTABLE;
7260 if (t == 13)
7261 return false;
7262
7263 break;
7264
7265 case eEncodingA1: {
7266 uint32_t imm4H = Bits32(opcode, 11, 8);
7267 uint32_t imm4L = Bits32(opcode, 3, 0);
7268
7269 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7270 t = Bits32(opcode, 15, 12);
7271 imm32 = (imm4H << 4) | imm4L;
7272 add = BitIsSet(opcode, 23);
7273
7274 // if t == 15 then UNPREDICTABLE;
7275 if (t == 15)
7276 return false;
7277 break;
7278 }
7279
7280 default:
7281 return false;
7282 }
7283
7284 // base = Align(PC,4);
7285 uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7286 if (!success)
7287 return false;
7288
7289 addr_t base = AlignPC(pc_value);
7290 addr_t address;
7291
7292 // address = if add then (base + imm32) else (base - imm32);
7293 if (add)
7294 address = base + imm32;
7295 else
7296 address = base - imm32;
7297
7298 // data = MemU[address,2];
7299 RegisterInfo base_reg;
7300 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7301
7302 EmulateInstruction::Context context;
7303 context.type = eContextRegisterLoad;
7304 context.SetRegisterPlusOffset(base_reg, address - base);
7305
7306 uint64_t data = MemURead(context, address, 2, 0, &success);
7307 if (!success)
7308 return false;
7309
7310 // if UnalignedSupport() || address<0> = '0' then
7311 if (UnalignedSupport() || BitIsClear(address, 0)) {
7312 // R[t] = ZeroExtend(data, 32);
7313 context.type = eContextRegisterLoad;
7314 context.SetRegisterPlusOffset(base_reg, address - base);
7315 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7316 data))
7317 return false;
7318
7319 } else // Can only apply before ARMv7
7320 {
7321 // R[t] = bits(32) UNKNOWN;
7322 WriteBits32Unknown(t);
7323 }
7324 }
7325 return true;
7326 }
7327
7328 // LDRH (literal) calculates an address from a base register value and an offset
7329 // register value, loads a halfword
7330 // from memory, zero-extends it to form a 32-bit word, and writes it to a
7331 // register. The offset register value can be shifted left by 0, 1, 2, or 3
7332 // bits.
EmulateLDRHRegister(const uint32_t opcode,const ARMEncoding encoding)7333 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
7334 const ARMEncoding encoding) {
7335 #if 0
7336 if ConditionPassed() then
7337 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7338 offset = Shift(R[m], shift_t, shift_n, APSR.C);
7339 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7340 address = if index then offset_addr else R[n];
7341 data = MemU[address,2];
7342 if wback then R[n] = offset_addr;
7343 if UnalignedSupport() || address<0> = '0' then
7344 R[t] = ZeroExtend(data, 32);
7345 else // Can only apply before ARMv7
7346 R[t] = bits(32) UNKNOWN;
7347 #endif
7348
7349 bool success = false;
7350
7351 if (ConditionPassed(opcode)) {
7352 uint32_t t;
7353 uint32_t n;
7354 uint32_t m;
7355 bool index;
7356 bool add;
7357 bool wback;
7358 ARM_ShifterType shift_t;
7359 uint32_t shift_n;
7360
7361 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7362 switch (encoding) {
7363 case eEncodingT1:
7364 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
7365 // in ThumbEE";
7366 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7367 t = Bits32(opcode, 2, 0);
7368 n = Bits32(opcode, 5, 3);
7369 m = Bits32(opcode, 8, 6);
7370
7371 // index = TRUE; add = TRUE; wback = FALSE;
7372 index = true;
7373 add = true;
7374 wback = false;
7375
7376 // (shift_t, shift_n) = (SRType_LSL, 0);
7377 shift_t = SRType_LSL;
7378 shift_n = 0;
7379
7380 break;
7381
7382 case eEncodingT2:
7383 // if Rn == '1111' then SEE LDRH (literal);
7384 // if Rt == '1111' then SEE "Unallocated memory hints";
7385 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7386 t = Bits32(opcode, 15, 12);
7387 n = Bits32(opcode, 19, 16);
7388 m = Bits32(opcode, 3, 0);
7389
7390 // index = TRUE; add = TRUE; wback = FALSE;
7391 index = true;
7392 add = true;
7393 wback = false;
7394
7395 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7396 shift_t = SRType_LSL;
7397 shift_n = Bits32(opcode, 5, 4);
7398
7399 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7400 if ((t == 13) || BadReg(m))
7401 return false;
7402 break;
7403
7404 case eEncodingA1:
7405 // if P == '0' && W == '1' then SEE LDRHT;
7406 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7407 t = Bits32(opcode, 15, 12);
7408 n = Bits32(opcode, 19, 16);
7409 m = Bits32(opcode, 3, 0);
7410
7411 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7412 // (W == '1');
7413 index = BitIsSet(opcode, 24);
7414 add = BitIsSet(opcode, 23);
7415 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7416
7417 // (shift_t, shift_n) = (SRType_LSL, 0);
7418 shift_t = SRType_LSL;
7419 shift_n = 0;
7420
7421 // if t == 15 || m == 15 then UNPREDICTABLE;
7422 if ((t == 15) || (m == 15))
7423 return false;
7424
7425 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7426 if (wback && ((n == 15) || (n == t)))
7427 return false;
7428
7429 break;
7430
7431 default:
7432 return false;
7433 }
7434
7435 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7436
7437 uint64_t Rm =
7438 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7439 if (!success)
7440 return false;
7441
7442 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7443 if (!success)
7444 return false;
7445
7446 addr_t offset_addr;
7447 addr_t address;
7448
7449 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7450 uint64_t Rn =
7451 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7452 if (!success)
7453 return false;
7454
7455 if (add)
7456 offset_addr = Rn + offset;
7457 else
7458 offset_addr = Rn - offset;
7459
7460 // address = if index then offset_addr else R[n];
7461 if (index)
7462 address = offset_addr;
7463 else
7464 address = Rn;
7465
7466 // data = MemU[address,2];
7467 RegisterInfo base_reg;
7468 RegisterInfo offset_reg;
7469 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7470 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7471
7472 EmulateInstruction::Context context;
7473 context.type = eContextRegisterLoad;
7474 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7475 uint64_t data = MemURead(context, address, 2, 0, &success);
7476 if (!success)
7477 return false;
7478
7479 // if wback then R[n] = offset_addr;
7480 if (wback) {
7481 context.type = eContextAdjustBaseRegister;
7482 context.SetAddress(offset_addr);
7483 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7484 offset_addr))
7485 return false;
7486 }
7487
7488 // if UnalignedSupport() || address<0> = '0' then
7489 if (UnalignedSupport() || BitIsClear(address, 0)) {
7490 // R[t] = ZeroExtend(data, 32);
7491 context.type = eContextRegisterLoad;
7492 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7493 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7494 data))
7495 return false;
7496 } else // Can only apply before ARMv7
7497 {
7498 // R[t] = bits(32) UNKNOWN;
7499 WriteBits32Unknown(t);
7500 }
7501 }
7502 return true;
7503 }
7504
7505 // LDRSB (immediate) calculates an address from a base register value and an
7506 // immediate offset, loads a byte from
7507 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7508 // It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRSBImmediate(const uint32_t opcode,const ARMEncoding encoding)7509 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
7510 const ARMEncoding encoding) {
7511 #if 0
7512 if ConditionPassed() then
7513 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7514 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7515 address = if index then offset_addr else R[n];
7516 R[t] = SignExtend(MemU[address,1], 32);
7517 if wback then R[n] = offset_addr;
7518 #endif
7519
7520 bool success = false;
7521
7522 if (ConditionPassed(opcode)) {
7523 uint32_t t;
7524 uint32_t n;
7525 uint32_t imm32;
7526 bool index;
7527 bool add;
7528 bool wback;
7529
7530 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7531 switch (encoding) {
7532 case eEncodingT1:
7533 // if Rt == '1111' then SEE PLI;
7534 // if Rn == '1111' then SEE LDRSB (literal);
7535 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7536 t = Bits32(opcode, 15, 12);
7537 n = Bits32(opcode, 19, 16);
7538 imm32 = Bits32(opcode, 11, 0);
7539
7540 // index = TRUE; add = TRUE; wback = FALSE;
7541 index = true;
7542 add = true;
7543 wback = false;
7544
7545 // if t == 13 then UNPREDICTABLE;
7546 if (t == 13)
7547 return false;
7548
7549 break;
7550
7551 case eEncodingT2:
7552 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7553 // if Rn == '1111' then SEE LDRSB (literal);
7554 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7555 // if P == '0' && W == '0' then UNDEFINED;
7556 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7557 return false;
7558
7559 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7560 t = Bits32(opcode, 15, 12);
7561 n = Bits32(opcode, 19, 16);
7562 imm32 = Bits32(opcode, 7, 0);
7563
7564 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7565 index = BitIsSet(opcode, 10);
7566 add = BitIsSet(opcode, 9);
7567 wback = BitIsSet(opcode, 8);
7568
7569 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7570 if (((t == 13) ||
7571 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
7572 BitIsSet(opcode, 8)))) ||
7573 (wback && (n == t)))
7574 return false;
7575
7576 break;
7577
7578 case eEncodingA1: {
7579 // if Rn == '1111' then SEE LDRSB (literal);
7580 // if P == '0' && W == '1' then SEE LDRSBT;
7581 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7582 t = Bits32(opcode, 15, 12);
7583 n = Bits32(opcode, 19, 16);
7584
7585 uint32_t imm4H = Bits32(opcode, 11, 8);
7586 uint32_t imm4L = Bits32(opcode, 3, 0);
7587 imm32 = (imm4H << 4) | imm4L;
7588
7589 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7590 // (W == '1');
7591 index = BitIsSet(opcode, 24);
7592 add = BitIsSet(opcode, 23);
7593 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7594
7595 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7596 if ((t == 15) || (wback && (n == t)))
7597 return false;
7598
7599 break;
7600 }
7601
7602 default:
7603 return false;
7604 }
7605
7606 uint64_t Rn = ReadCoreReg(n, &success);
7607 if (!success)
7608 return false;
7609
7610 addr_t offset_addr;
7611 addr_t address;
7612
7613 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7614 if (add)
7615 offset_addr = Rn + imm32;
7616 else
7617 offset_addr = Rn - imm32;
7618
7619 // address = if index then offset_addr else R[n];
7620 if (index)
7621 address = offset_addr;
7622 else
7623 address = Rn;
7624
7625 // R[t] = SignExtend(MemU[address,1], 32);
7626 RegisterInfo base_reg;
7627 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7628
7629 EmulateInstruction::Context context;
7630 context.type = eContextRegisterLoad;
7631 context.SetRegisterPlusOffset(base_reg, address - Rn);
7632
7633 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7634 if (!success)
7635 return false;
7636
7637 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7638 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7639 (uint64_t)signed_data))
7640 return false;
7641
7642 // if wback then R[n] = offset_addr;
7643 if (wback) {
7644 context.type = eContextAdjustBaseRegister;
7645 context.SetAddress(offset_addr);
7646 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7647 offset_addr))
7648 return false;
7649 }
7650 }
7651
7652 return true;
7653 }
7654
7655 // LDRSB (literal) calculates an address from the PC value and an immediate
7656 // offset, loads a byte from memory,
7657 // sign-extends it to form a 32-bit word, and writes tit to a register.
EmulateLDRSBLiteral(const uint32_t opcode,const ARMEncoding encoding)7658 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
7659 const ARMEncoding encoding) {
7660 #if 0
7661 if ConditionPassed() then
7662 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7663 base = Align(PC,4);
7664 address = if add then (base + imm32) else (base - imm32);
7665 R[t] = SignExtend(MemU[address,1], 32);
7666 #endif
7667
7668 bool success = false;
7669
7670 if (ConditionPassed(opcode)) {
7671 uint32_t t;
7672 uint32_t imm32;
7673 bool add;
7674
7675 // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7676 switch (encoding) {
7677 case eEncodingT1:
7678 // if Rt == '1111' then SEE PLI;
7679 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7680 t = Bits32(opcode, 15, 12);
7681 imm32 = Bits32(opcode, 11, 0);
7682 add = BitIsSet(opcode, 23);
7683
7684 // if t == 13 then UNPREDICTABLE;
7685 if (t == 13)
7686 return false;
7687
7688 break;
7689
7690 case eEncodingA1: {
7691 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7692 t = Bits32(opcode, 15, 12);
7693 uint32_t imm4H = Bits32(opcode, 11, 8);
7694 uint32_t imm4L = Bits32(opcode, 3, 0);
7695 imm32 = (imm4H << 4) | imm4L;
7696 add = BitIsSet(opcode, 23);
7697
7698 // if t == 15 then UNPREDICTABLE;
7699 if (t == 15)
7700 return false;
7701
7702 break;
7703 }
7704
7705 default:
7706 return false;
7707 }
7708
7709 // base = Align(PC,4);
7710 uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7711 if (!success)
7712 return false;
7713 uint64_t base = AlignPC(pc_value);
7714
7715 // address = if add then (base + imm32) else (base - imm32);
7716 addr_t address;
7717 if (add)
7718 address = base + imm32;
7719 else
7720 address = base - imm32;
7721
7722 // R[t] = SignExtend(MemU[address,1], 32);
7723 RegisterInfo base_reg;
7724 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7725
7726 EmulateInstruction::Context context;
7727 context.type = eContextRegisterLoad;
7728 context.SetRegisterPlusOffset(base_reg, address - base);
7729
7730 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7731 if (!success)
7732 return false;
7733
7734 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7735 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7736 (uint64_t)signed_data))
7737 return false;
7738 }
7739 return true;
7740 }
7741
7742 // LDRSB (register) calculates an address from a base register value and an
7743 // offset register value, loadsa byte from
7744 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7745 // The offset register value can be shifted left by 0, 1, 2, or 3 bits.
EmulateLDRSBRegister(const uint32_t opcode,const ARMEncoding encoding)7746 bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
7747 const ARMEncoding encoding) {
7748 #if 0
7749 if ConditionPassed() then
7750 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7751 offset = Shift(R[m], shift_t, shift_n, APSR.C);
7752 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7753 address = if index then offset_addr else R[n];
7754 R[t] = SignExtend(MemU[address,1], 32);
7755 if wback then R[n] = offset_addr;
7756 #endif
7757
7758 bool success = false;
7759
7760 if (ConditionPassed(opcode)) {
7761 uint32_t t;
7762 uint32_t n;
7763 uint32_t m;
7764 bool index;
7765 bool add;
7766 bool wback;
7767 ARM_ShifterType shift_t;
7768 uint32_t shift_n;
7769
7770 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7771 switch (encoding) {
7772 case eEncodingT1:
7773 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7774 t = Bits32(opcode, 2, 0);
7775 n = Bits32(opcode, 5, 3);
7776 m = Bits32(opcode, 8, 6);
7777
7778 // index = TRUE; add = TRUE; wback = FALSE;
7779 index = true;
7780 add = true;
7781 wback = false;
7782
7783 // (shift_t, shift_n) = (SRType_LSL, 0);
7784 shift_t = SRType_LSL;
7785 shift_n = 0;
7786
7787 break;
7788
7789 case eEncodingT2:
7790 // if Rt == '1111' then SEE PLI;
7791 // if Rn == '1111' then SEE LDRSB (literal);
7792 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7793 t = Bits32(opcode, 15, 12);
7794 n = Bits32(opcode, 19, 16);
7795 m = Bits32(opcode, 3, 0);
7796
7797 // index = TRUE; add = TRUE; wback = FALSE;
7798 index = true;
7799 add = true;
7800 wback = false;
7801
7802 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7803 shift_t = SRType_LSL;
7804 shift_n = Bits32(opcode, 5, 4);
7805
7806 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7807 if ((t == 13) || BadReg(m))
7808 return false;
7809 break;
7810
7811 case eEncodingA1:
7812 // if P == '0' && W == '1' then SEE LDRSBT;
7813 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7814 t = Bits32(opcode, 15, 12);
7815 n = Bits32(opcode, 19, 16);
7816 m = Bits32(opcode, 3, 0);
7817
7818 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7819 // (W == '1');
7820 index = BitIsSet(opcode, 24);
7821 add = BitIsSet(opcode, 23);
7822 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7823
7824 // (shift_t, shift_n) = (SRType_LSL, 0);
7825 shift_t = SRType_LSL;
7826 shift_n = 0;
7827
7828 // if t == 15 || m == 15 then UNPREDICTABLE;
7829 if ((t == 15) || (m == 15))
7830 return false;
7831
7832 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7833 if (wback && ((n == 15) || (n == t)))
7834 return false;
7835 break;
7836
7837 default:
7838 return false;
7839 }
7840
7841 uint64_t Rm =
7842 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7843 if (!success)
7844 return false;
7845
7846 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7847 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7848 if (!success)
7849 return false;
7850
7851 addr_t offset_addr;
7852 addr_t address;
7853
7854 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7855 uint64_t Rn =
7856 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7857 if (!success)
7858 return false;
7859
7860 if (add)
7861 offset_addr = Rn + offset;
7862 else
7863 offset_addr = Rn - offset;
7864
7865 // address = if index then offset_addr else R[n];
7866 if (index)
7867 address = offset_addr;
7868 else
7869 address = Rn;
7870
7871 // R[t] = SignExtend(MemU[address,1], 32);
7872 RegisterInfo base_reg;
7873 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7874 RegisterInfo offset_reg;
7875 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7876
7877 EmulateInstruction::Context context;
7878 context.type = eContextRegisterLoad;
7879 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7880
7881 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7882 if (!success)
7883 return false;
7884
7885 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7886 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7887 (uint64_t)signed_data))
7888 return false;
7889
7890 // if wback then R[n] = offset_addr;
7891 if (wback) {
7892 context.type = eContextAdjustBaseRegister;
7893 context.SetAddress(offset_addr);
7894 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7895 offset_addr))
7896 return false;
7897 }
7898 }
7899 return true;
7900 }
7901
7902 // LDRSH (immediate) calculates an address from a base register value and an
7903 // immediate offset, loads a halfword from
7904 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7905 // It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRSHImmediate(const uint32_t opcode,const ARMEncoding encoding)7906 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
7907 const ARMEncoding encoding) {
7908 #if 0
7909 if ConditionPassed() then
7910 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7911 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7912 address = if index then offset_addr else R[n];
7913 data = MemU[address,2];
7914 if wback then R[n] = offset_addr;
7915 if UnalignedSupport() || address<0> = '0' then
7916 R[t] = SignExtend(data, 32);
7917 else // Can only apply before ARMv7
7918 R[t] = bits(32) UNKNOWN;
7919 #endif
7920
7921 bool success = false;
7922
7923 if (ConditionPassed(opcode)) {
7924 uint32_t t;
7925 uint32_t n;
7926 uint32_t imm32;
7927 bool index;
7928 bool add;
7929 bool wback;
7930
7931 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7932 switch (encoding) {
7933 case eEncodingT1:
7934 // if Rn == '1111' then SEE LDRSH (literal);
7935 // if Rt == '1111' then SEE "Unallocated memory hints";
7936 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7937 t = Bits32(opcode, 15, 12);
7938 n = Bits32(opcode, 19, 16);
7939 imm32 = Bits32(opcode, 11, 0);
7940
7941 // index = TRUE; add = TRUE; wback = FALSE;
7942 index = true;
7943 add = true;
7944 wback = false;
7945
7946 // if t == 13 then UNPREDICTABLE;
7947 if (t == 13)
7948 return false;
7949
7950 break;
7951
7952 case eEncodingT2:
7953 // if Rn == '1111' then SEE LDRSH (literal);
7954 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7955 // "Unallocated memory hints";
7956 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7957 // if P == '0' && W == '0' then UNDEFINED;
7958 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7959 return false;
7960
7961 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7962 t = Bits32(opcode, 15, 12);
7963 n = Bits32(opcode, 19, 16);
7964 imm32 = Bits32(opcode, 7, 0);
7965
7966 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7967 index = BitIsSet(opcode, 10);
7968 add = BitIsSet(opcode, 9);
7969 wback = BitIsSet(opcode, 8);
7970
7971 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7972 if (BadReg(t) || (wback && (n == t)))
7973 return false;
7974
7975 break;
7976
7977 case eEncodingA1: {
7978 // if Rn == '1111' then SEE LDRSH (literal);
7979 // if P == '0' && W == '1' then SEE LDRSHT;
7980 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7981 t = Bits32(opcode, 15, 12);
7982 n = Bits32(opcode, 19, 16);
7983 uint32_t imm4H = Bits32(opcode, 11, 8);
7984 uint32_t imm4L = Bits32(opcode, 3, 0);
7985 imm32 = (imm4H << 4) | imm4L;
7986
7987 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7988 // (W == '1');
7989 index = BitIsSet(opcode, 24);
7990 add = BitIsSet(opcode, 23);
7991 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7992
7993 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7994 if ((t == 15) || (wback && (n == t)))
7995 return false;
7996
7997 break;
7998 }
7999
8000 default:
8001 return false;
8002 }
8003
8004 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
8005 uint64_t Rn =
8006 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8007 if (!success)
8008 return false;
8009
8010 addr_t offset_addr;
8011 if (add)
8012 offset_addr = Rn + imm32;
8013 else
8014 offset_addr = Rn - imm32;
8015
8016 // address = if index then offset_addr else R[n];
8017 addr_t address;
8018 if (index)
8019 address = offset_addr;
8020 else
8021 address = Rn;
8022
8023 // data = MemU[address,2];
8024 RegisterInfo base_reg;
8025 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8026
8027 EmulateInstruction::Context context;
8028 context.type = eContextRegisterLoad;
8029 context.SetRegisterPlusOffset(base_reg, address - Rn);
8030
8031 uint64_t data = MemURead(context, address, 2, 0, &success);
8032 if (!success)
8033 return false;
8034
8035 // if wback then R[n] = offset_addr;
8036 if (wback) {
8037 context.type = eContextAdjustBaseRegister;
8038 context.SetAddress(offset_addr);
8039 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8040 offset_addr))
8041 return false;
8042 }
8043
8044 // if UnalignedSupport() || address<0> = '0' then
8045 if (UnalignedSupport() || BitIsClear(address, 0)) {
8046 // R[t] = SignExtend(data, 32);
8047 int64_t signed_data = llvm::SignExtend64<16>(data);
8048 context.type = eContextRegisterLoad;
8049 context.SetRegisterPlusOffset(base_reg, address - Rn);
8050 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8051 (uint64_t)signed_data))
8052 return false;
8053 } else // Can only apply before ARMv7
8054 {
8055 // R[t] = bits(32) UNKNOWN;
8056 WriteBits32Unknown(t);
8057 }
8058 }
8059 return true;
8060 }
8061
8062 // LDRSH (literal) calculates an address from the PC value and an immediate
8063 // offset, loads a halfword from memory,
8064 // sign-extends it to from a 32-bit word, and writes it to a register.
EmulateLDRSHLiteral(const uint32_t opcode,const ARMEncoding encoding)8065 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
8066 const ARMEncoding encoding) {
8067 #if 0
8068 if ConditionPassed() then
8069 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8070 base = Align(PC,4);
8071 address = if add then (base + imm32) else (base - imm32);
8072 data = MemU[address,2];
8073 if UnalignedSupport() || address<0> = '0' then
8074 R[t] = SignExtend(data, 32);
8075 else // Can only apply before ARMv7
8076 R[t] = bits(32) UNKNOWN;
8077 #endif
8078
8079 bool success = false;
8080
8081 if (ConditionPassed(opcode)) {
8082 uint32_t t;
8083 uint32_t imm32;
8084 bool add;
8085
8086 // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8087 switch (encoding) {
8088 case eEncodingT1:
8089 // if Rt == '1111' then SEE "Unallocated memory hints";
8090 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
8091 t = Bits32(opcode, 15, 12);
8092 imm32 = Bits32(opcode, 11, 0);
8093 add = BitIsSet(opcode, 23);
8094
8095 // if t == 13 then UNPREDICTABLE;
8096 if (t == 13)
8097 return false;
8098
8099 break;
8100
8101 case eEncodingA1: {
8102 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
8103 t = Bits32(opcode, 15, 12);
8104 uint32_t imm4H = Bits32(opcode, 11, 8);
8105 uint32_t imm4L = Bits32(opcode, 3, 0);
8106 imm32 = (imm4H << 4) | imm4L;
8107 add = BitIsSet(opcode, 23);
8108
8109 // if t == 15 then UNPREDICTABLE;
8110 if (t == 15)
8111 return false;
8112
8113 break;
8114 }
8115 default:
8116 return false;
8117 }
8118
8119 // base = Align(PC,4);
8120 uint64_t pc_value = ReadCoreReg(PC_REG, &success);
8121 if (!success)
8122 return false;
8123
8124 uint64_t base = AlignPC(pc_value);
8125
8126 addr_t address;
8127 // address = if add then (base + imm32) else (base - imm32);
8128 if (add)
8129 address = base + imm32;
8130 else
8131 address = base - imm32;
8132
8133 // data = MemU[address,2];
8134 RegisterInfo base_reg;
8135 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
8136
8137 EmulateInstruction::Context context;
8138 context.type = eContextRegisterLoad;
8139 context.SetRegisterPlusOffset(base_reg, imm32);
8140
8141 uint64_t data = MemURead(context, address, 2, 0, &success);
8142 if (!success)
8143 return false;
8144
8145 // if UnalignedSupport() || address<0> = '0' then
8146 if (UnalignedSupport() || BitIsClear(address, 0)) {
8147 // R[t] = SignExtend(data, 32);
8148 int64_t signed_data = llvm::SignExtend64<16>(data);
8149 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8150 (uint64_t)signed_data))
8151 return false;
8152 } else // Can only apply before ARMv7
8153 {
8154 // R[t] = bits(32) UNKNOWN;
8155 WriteBits32Unknown(t);
8156 }
8157 }
8158 return true;
8159 }
8160
8161 // LDRSH (register) calculates an address from a base register value and an
8162 // offset register value, loads a halfword
8163 // from memory, sign-extends it to form a 32-bit word, and writes it to a
8164 // register. The offset register value can be shifted left by 0, 1, 2, or 3
8165 // bits.
EmulateLDRSHRegister(const uint32_t opcode,const ARMEncoding encoding)8166 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
8167 const ARMEncoding encoding) {
8168 #if 0
8169 if ConditionPassed() then
8170 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8171 offset = Shift(R[m], shift_t, shift_n, APSR.C);
8172 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8173 address = if index then offset_addr else R[n];
8174 data = MemU[address,2];
8175 if wback then R[n] = offset_addr;
8176 if UnalignedSupport() || address<0> = '0' then
8177 R[t] = SignExtend(data, 32);
8178 else // Can only apply before ARMv7
8179 R[t] = bits(32) UNKNOWN;
8180 #endif
8181
8182 bool success = false;
8183
8184 if (ConditionPassed(opcode)) {
8185 uint32_t t;
8186 uint32_t n;
8187 uint32_t m;
8188 bool index;
8189 bool add;
8190 bool wback;
8191 ARM_ShifterType shift_t;
8192 uint32_t shift_n;
8193
8194 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8195 switch (encoding) {
8196 case eEncodingT1:
8197 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
8198 // in ThumbEE";
8199 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8200 t = Bits32(opcode, 2, 0);
8201 n = Bits32(opcode, 5, 3);
8202 m = Bits32(opcode, 8, 6);
8203
8204 // index = TRUE; add = TRUE; wback = FALSE;
8205 index = true;
8206 add = true;
8207 wback = false;
8208
8209 // (shift_t, shift_n) = (SRType_LSL, 0);
8210 shift_t = SRType_LSL;
8211 shift_n = 0;
8212
8213 break;
8214
8215 case eEncodingT2:
8216 // if Rn == '1111' then SEE LDRSH (literal);
8217 // if Rt == '1111' then SEE "Unallocated memory hints";
8218 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8219 t = Bits32(opcode, 15, 12);
8220 n = Bits32(opcode, 19, 16);
8221 m = Bits32(opcode, 3, 0);
8222
8223 // index = TRUE; add = TRUE; wback = FALSE;
8224 index = true;
8225 add = true;
8226 wback = false;
8227
8228 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
8229 shift_t = SRType_LSL;
8230 shift_n = Bits32(opcode, 5, 4);
8231
8232 // if t == 13 || BadReg(m) then UNPREDICTABLE;
8233 if ((t == 13) || BadReg(m))
8234 return false;
8235
8236 break;
8237
8238 case eEncodingA1:
8239 // if P == '0' && W == '1' then SEE LDRSHT;
8240 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8241 t = Bits32(opcode, 15, 12);
8242 n = Bits32(opcode, 19, 16);
8243 m = Bits32(opcode, 3, 0);
8244
8245 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
8246 // (W == '1');
8247 index = BitIsSet(opcode, 24);
8248 add = BitIsSet(opcode, 23);
8249 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8250
8251 // (shift_t, shift_n) = (SRType_LSL, 0);
8252 shift_t = SRType_LSL;
8253 shift_n = 0;
8254
8255 // if t == 15 || m == 15 then UNPREDICTABLE;
8256 if ((t == 15) || (m == 15))
8257 return false;
8258
8259 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
8260 if (wback && ((n == 15) || (n == t)))
8261 return false;
8262
8263 break;
8264
8265 default:
8266 return false;
8267 }
8268
8269 uint64_t Rm =
8270 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8271 if (!success)
8272 return false;
8273
8274 uint64_t Rn =
8275 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8276 if (!success)
8277 return false;
8278
8279 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
8280 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
8281 if (!success)
8282 return false;
8283
8284 addr_t offset_addr;
8285 addr_t address;
8286
8287 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8288 if (add)
8289 offset_addr = Rn + offset;
8290 else
8291 offset_addr = Rn - offset;
8292
8293 // address = if index then offset_addr else R[n];
8294 if (index)
8295 address = offset_addr;
8296 else
8297 address = Rn;
8298
8299 // data = MemU[address,2];
8300 RegisterInfo base_reg;
8301 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8302
8303 RegisterInfo offset_reg;
8304 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
8305
8306 EmulateInstruction::Context context;
8307 context.type = eContextRegisterLoad;
8308 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8309
8310 uint64_t data = MemURead(context, address, 2, 0, &success);
8311 if (!success)
8312 return false;
8313
8314 // if wback then R[n] = offset_addr;
8315 if (wback) {
8316 context.type = eContextAdjustBaseRegister;
8317 context.SetAddress(offset_addr);
8318 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8319 offset_addr))
8320 return false;
8321 }
8322
8323 // if UnalignedSupport() || address<0> = '0' then
8324 if (UnalignedSupport() || BitIsClear(address, 0)) {
8325 // R[t] = SignExtend(data, 32);
8326 context.type = eContextRegisterLoad;
8327 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8328
8329 int64_t signed_data = llvm::SignExtend64<16>(data);
8330 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8331 (uint64_t)signed_data))
8332 return false;
8333 } else // Can only apply before ARMv7
8334 {
8335 // R[t] = bits(32) UNKNOWN;
8336 WriteBits32Unknown(t);
8337 }
8338 }
8339 return true;
8340 }
8341
8342 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
8343 // writes the result to the destination
8344 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before
8345 // extracting the 8-bit value.
EmulateSXTB(const uint32_t opcode,const ARMEncoding encoding)8346 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
8347 const ARMEncoding encoding) {
8348 #if 0
8349 if ConditionPassed() then
8350 EncodingSpecificOperations();
8351 rotated = ROR(R[m], rotation);
8352 R[d] = SignExtend(rotated<7:0>, 32);
8353 #endif
8354
8355 bool success = false;
8356
8357 if (ConditionPassed(opcode)) {
8358 uint32_t d;
8359 uint32_t m;
8360 uint32_t rotation;
8361
8362 // EncodingSpecificOperations();
8363 switch (encoding) {
8364 case eEncodingT1:
8365 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8366 d = Bits32(opcode, 2, 0);
8367 m = Bits32(opcode, 5, 3);
8368 rotation = 0;
8369
8370 break;
8371
8372 case eEncodingT2:
8373 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8374 d = Bits32(opcode, 11, 8);
8375 m = Bits32(opcode, 3, 0);
8376 rotation = Bits32(opcode, 5, 4) << 3;
8377
8378 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8379 if (BadReg(d) || BadReg(m))
8380 return false;
8381
8382 break;
8383
8384 case eEncodingA1:
8385 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8386 d = Bits32(opcode, 15, 12);
8387 m = Bits32(opcode, 3, 0);
8388 rotation = Bits32(opcode, 11, 10) << 3;
8389
8390 // if d == 15 || m == 15 then UNPREDICTABLE;
8391 if ((d == 15) || (m == 15))
8392 return false;
8393
8394 break;
8395
8396 default:
8397 return false;
8398 }
8399
8400 uint64_t Rm =
8401 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8402 if (!success)
8403 return false;
8404
8405 // rotated = ROR(R[m], rotation);
8406 uint64_t rotated = ROR(Rm, rotation, &success);
8407 if (!success)
8408 return false;
8409
8410 // R[d] = SignExtend(rotated<7:0>, 32);
8411 int64_t data = llvm::SignExtend64<8>(rotated);
8412
8413 RegisterInfo source_reg;
8414 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8415
8416 EmulateInstruction::Context context;
8417 context.type = eContextRegisterLoad;
8418 context.SetRegister(source_reg);
8419
8420 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8421 (uint64_t)data))
8422 return false;
8423 }
8424 return true;
8425 }
8426
8427 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
8428 // writes the result to the destination
8429 // register. You can specify a rotation by 0, 8, 16, or 24 bits before
8430 // extracting the 16-bit value.
EmulateSXTH(const uint32_t opcode,const ARMEncoding encoding)8431 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
8432 const ARMEncoding encoding) {
8433 #if 0
8434 if ConditionPassed() then
8435 EncodingSpecificOperations();
8436 rotated = ROR(R[m], rotation);
8437 R[d] = SignExtend(rotated<15:0>, 32);
8438 #endif
8439
8440 bool success = false;
8441
8442 if (ConditionPassed(opcode)) {
8443 uint32_t d;
8444 uint32_t m;
8445 uint32_t rotation;
8446
8447 // EncodingSpecificOperations();
8448 switch (encoding) {
8449 case eEncodingT1:
8450 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8451 d = Bits32(opcode, 2, 0);
8452 m = Bits32(opcode, 5, 3);
8453 rotation = 0;
8454
8455 break;
8456
8457 case eEncodingT2:
8458 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8459 d = Bits32(opcode, 11, 8);
8460 m = Bits32(opcode, 3, 0);
8461 rotation = Bits32(opcode, 5, 4) << 3;
8462
8463 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8464 if (BadReg(d) || BadReg(m))
8465 return false;
8466
8467 break;
8468
8469 case eEncodingA1:
8470 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8471 d = Bits32(opcode, 15, 12);
8472 m = Bits32(opcode, 3, 0);
8473 rotation = Bits32(opcode, 11, 10) << 3;
8474
8475 // if d == 15 || m == 15 then UNPREDICTABLE;
8476 if ((d == 15) || (m == 15))
8477 return false;
8478
8479 break;
8480
8481 default:
8482 return false;
8483 }
8484
8485 uint64_t Rm =
8486 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8487 if (!success)
8488 return false;
8489
8490 // rotated = ROR(R[m], rotation);
8491 uint64_t rotated = ROR(Rm, rotation, &success);
8492 if (!success)
8493 return false;
8494
8495 // R[d] = SignExtend(rotated<15:0>, 32);
8496 RegisterInfo source_reg;
8497 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8498
8499 EmulateInstruction::Context context;
8500 context.type = eContextRegisterLoad;
8501 context.SetRegister(source_reg);
8502
8503 int64_t data = llvm::SignExtend64<16>(rotated);
8504 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8505 (uint64_t)data))
8506 return false;
8507 }
8508
8509 return true;
8510 }
8511
8512 // UXTB extracts an 8-bit value from a register, zero-extends it to 32 bits, and
8513 // writes the result to the destination
8514 // register. You can specify a rotation by 0, 8, 16, or 24 bits before
8515 // extracting the 8-bit value.
EmulateUXTB(const uint32_t opcode,const ARMEncoding encoding)8516 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
8517 const ARMEncoding encoding) {
8518 #if 0
8519 if ConditionPassed() then
8520 EncodingSpecificOperations();
8521 rotated = ROR(R[m], rotation);
8522 R[d] = ZeroExtend(rotated<7:0>, 32);
8523 #endif
8524
8525 bool success = false;
8526
8527 if (ConditionPassed(opcode)) {
8528 uint32_t d;
8529 uint32_t m;
8530 uint32_t rotation;
8531
8532 // EncodingSpecificOperations();
8533 switch (encoding) {
8534 case eEncodingT1:
8535 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8536 d = Bits32(opcode, 2, 0);
8537 m = Bits32(opcode, 5, 3);
8538 rotation = 0;
8539
8540 break;
8541
8542 case eEncodingT2:
8543 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8544 d = Bits32(opcode, 11, 8);
8545 m = Bits32(opcode, 3, 0);
8546 rotation = Bits32(opcode, 5, 4) << 3;
8547
8548 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8549 if (BadReg(d) || BadReg(m))
8550 return false;
8551
8552 break;
8553
8554 case eEncodingA1:
8555 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8556 d = Bits32(opcode, 15, 12);
8557 m = Bits32(opcode, 3, 0);
8558 rotation = Bits32(opcode, 11, 10) << 3;
8559
8560 // if d == 15 || m == 15 then UNPREDICTABLE;
8561 if ((d == 15) || (m == 15))
8562 return false;
8563
8564 break;
8565
8566 default:
8567 return false;
8568 }
8569
8570 uint64_t Rm =
8571 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8572 if (!success)
8573 return false;
8574
8575 // rotated = ROR(R[m], rotation);
8576 uint64_t rotated = ROR(Rm, rotation, &success);
8577 if (!success)
8578 return false;
8579
8580 // R[d] = ZeroExtend(rotated<7:0>, 32);
8581 RegisterInfo source_reg;
8582 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8583
8584 EmulateInstruction::Context context;
8585 context.type = eContextRegisterLoad;
8586 context.SetRegister(source_reg);
8587
8588 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8589 Bits32(rotated, 7, 0)))
8590 return false;
8591 }
8592 return true;
8593 }
8594
8595 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
8596 // writes the result to the destination
8597 // register. You can specify a rotation by 0, 8, 16, or 24 bits before
8598 // extracting the 16-bit value.
EmulateUXTH(const uint32_t opcode,const ARMEncoding encoding)8599 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
8600 const ARMEncoding encoding) {
8601 #if 0
8602 if ConditionPassed() then
8603 EncodingSpecificOperations();
8604 rotated = ROR(R[m], rotation);
8605 R[d] = ZeroExtend(rotated<15:0>, 32);
8606 #endif
8607
8608 bool success = false;
8609
8610 if (ConditionPassed(opcode)) {
8611 uint32_t d;
8612 uint32_t m;
8613 uint32_t rotation;
8614
8615 switch (encoding) {
8616 case eEncodingT1:
8617 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8618 d = Bits32(opcode, 2, 0);
8619 m = Bits32(opcode, 5, 3);
8620 rotation = 0;
8621
8622 break;
8623
8624 case eEncodingT2:
8625 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8626 d = Bits32(opcode, 11, 8);
8627 m = Bits32(opcode, 3, 0);
8628 rotation = Bits32(opcode, 5, 4) << 3;
8629
8630 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8631 if (BadReg(d) || BadReg(m))
8632 return false;
8633
8634 break;
8635
8636 case eEncodingA1:
8637 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8638 d = Bits32(opcode, 15, 12);
8639 m = Bits32(opcode, 3, 0);
8640 rotation = Bits32(opcode, 11, 10) << 3;
8641
8642 // if d == 15 || m == 15 then UNPREDICTABLE;
8643 if ((d == 15) || (m == 15))
8644 return false;
8645
8646 break;
8647
8648 default:
8649 return false;
8650 }
8651
8652 uint64_t Rm =
8653 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8654 if (!success)
8655 return false;
8656
8657 // rotated = ROR(R[m], rotation);
8658 uint64_t rotated = ROR(Rm, rotation, &success);
8659 if (!success)
8660 return false;
8661
8662 // R[d] = ZeroExtend(rotated<15:0>, 32);
8663 RegisterInfo source_reg;
8664 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8665
8666 EmulateInstruction::Context context;
8667 context.type = eContextRegisterLoad;
8668 context.SetRegister(source_reg);
8669
8670 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8671 Bits32(rotated, 15, 0)))
8672 return false;
8673 }
8674 return true;
8675 }
8676
8677 // RFE (Return From Exception) loads the PC and the CPSR from the word at the
8678 // specified address and the following
8679 // word respectively.
EmulateRFE(const uint32_t opcode,const ARMEncoding encoding)8680 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
8681 const ARMEncoding encoding) {
8682 #if 0
8683 if ConditionPassed() then
8684 EncodingSpecificOperations();
8685 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8686 UNPREDICTABLE;
8687 else
8688 address = if increment then R[n] else R[n]-8;
8689 if wordhigher then address = address+4;
8690 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8691 BranchWritePC(MemA[address,4]);
8692 if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8693 #endif
8694
8695 bool success = false;
8696
8697 if (ConditionPassed(opcode)) {
8698 uint32_t n;
8699 bool wback;
8700 bool increment;
8701 bool wordhigher;
8702
8703 // EncodingSpecificOperations();
8704 switch (encoding) {
8705 case eEncodingT1:
8706 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
8707 // FALSE;
8708 n = Bits32(opcode, 19, 16);
8709 wback = BitIsSet(opcode, 21);
8710 increment = false;
8711 wordhigher = false;
8712
8713 // if n == 15 then UNPREDICTABLE;
8714 if (n == 15)
8715 return false;
8716
8717 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8718 if (InITBlock() && !LastInITBlock())
8719 return false;
8720
8721 break;
8722
8723 case eEncodingT2:
8724 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8725 n = Bits32(opcode, 19, 16);
8726 wback = BitIsSet(opcode, 21);
8727 increment = true;
8728 wordhigher = false;
8729
8730 // if n == 15 then UNPREDICTABLE;
8731 if (n == 15)
8732 return false;
8733
8734 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8735 if (InITBlock() && !LastInITBlock())
8736 return false;
8737
8738 break;
8739
8740 case eEncodingA1:
8741 // n = UInt(Rn);
8742 n = Bits32(opcode, 19, 16);
8743
8744 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8745 wback = BitIsSet(opcode, 21);
8746 increment = BitIsSet(opcode, 23);
8747 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
8748
8749 // if n == 15 then UNPREDICTABLE;
8750 if (n == 15)
8751 return false;
8752
8753 break;
8754
8755 default:
8756 return false;
8757 }
8758
8759 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
8760 // then
8761 if (!CurrentModeIsPrivileged())
8762 // UNPREDICTABLE;
8763 return false;
8764 else {
8765 uint64_t Rn =
8766 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8767 if (!success)
8768 return false;
8769
8770 addr_t address;
8771 // address = if increment then R[n] else R[n]-8;
8772 if (increment)
8773 address = Rn;
8774 else
8775 address = Rn - 8;
8776
8777 // if wordhigher then address = address+4;
8778 if (wordhigher)
8779 address = address + 4;
8780
8781 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8782 RegisterInfo base_reg;
8783 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8784
8785 EmulateInstruction::Context context;
8786 context.type = eContextReturnFromException;
8787 context.SetRegisterPlusOffset(base_reg, address - Rn);
8788
8789 uint64_t data = MemARead(context, address + 4, 4, 0, &success);
8790 if (!success)
8791 return false;
8792
8793 CPSRWriteByInstr(data, 15, true);
8794
8795 // BranchWritePC(MemA[address,4]);
8796 uint64_t data2 = MemARead(context, address, 4, 0, &success);
8797 if (!success)
8798 return false;
8799
8800 BranchWritePC(context, data2);
8801
8802 // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8803 if (wback) {
8804 context.type = eContextAdjustBaseRegister;
8805 if (increment) {
8806 context.SetOffset(8);
8807 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8808 Rn + 8))
8809 return false;
8810 } else {
8811 context.SetOffset(-8);
8812 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8813 Rn - 8))
8814 return false;
8815 }
8816 } // if wback
8817 }
8818 } // if ConditionPassed()
8819 return true;
8820 }
8821
8822 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
8823 // register value and an immediate value, and writes the result to the
8824 // destination register. It can optionally update the condition flags based on
8825 // the result.
EmulateEORImm(const uint32_t opcode,const ARMEncoding encoding)8826 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
8827 const ARMEncoding encoding) {
8828 #if 0
8829 // ARM pseudo code...
8830 if ConditionPassed() then
8831 EncodingSpecificOperations();
8832 result = R[n] EOR imm32;
8833 if d == 15 then // Can only occur for ARM encoding
8834 ALUWritePC(result); // setflags is always FALSE here
8835 else
8836 R[d] = result;
8837 if setflags then
8838 APSR.N = result<31>;
8839 APSR.Z = IsZeroBit(result);
8840 APSR.C = carry;
8841 // APSR.V unchanged
8842 #endif
8843
8844 bool success = false;
8845
8846 if (ConditionPassed(opcode)) {
8847 uint32_t Rd, Rn;
8848 uint32_t
8849 imm32; // the immediate value to be ORed to the value obtained from Rn
8850 bool setflags;
8851 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8852 switch (encoding) {
8853 case eEncodingT1:
8854 Rd = Bits32(opcode, 11, 8);
8855 Rn = Bits32(opcode, 19, 16);
8856 setflags = BitIsSet(opcode, 20);
8857 imm32 = ThumbExpandImm_C(
8858 opcode, APSR_C,
8859 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8860 // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8861 if (Rd == 15 && setflags)
8862 return EmulateTEQImm(opcode, eEncodingT1);
8863 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8864 return false;
8865 break;
8866 case eEncodingA1:
8867 Rd = Bits32(opcode, 15, 12);
8868 Rn = Bits32(opcode, 19, 16);
8869 setflags = BitIsSet(opcode, 20);
8870 imm32 =
8871 ARMExpandImm_C(opcode, APSR_C,
8872 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8873
8874 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8875 // instructions;
8876 if (Rd == 15 && setflags)
8877 return EmulateSUBSPcLrEtc(opcode, encoding);
8878 break;
8879 default:
8880 return false;
8881 }
8882
8883 // Read the first operand.
8884 uint32_t val1 = ReadCoreReg(Rn, &success);
8885 if (!success)
8886 return false;
8887
8888 uint32_t result = val1 ^ imm32;
8889
8890 EmulateInstruction::Context context;
8891 context.type = EmulateInstruction::eContextImmediate;
8892 context.SetNoArgs();
8893
8894 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8895 return false;
8896 }
8897 return true;
8898 }
8899
8900 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a
8901 // register value and an optionally-shifted register value, and writes the
8902 // result to the destination register. It can optionally update the condition
8903 // flags based on the result.
EmulateEORReg(const uint32_t opcode,const ARMEncoding encoding)8904 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
8905 const ARMEncoding encoding) {
8906 #if 0
8907 // ARM pseudo code...
8908 if ConditionPassed() then
8909 EncodingSpecificOperations();
8910 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8911 result = R[n] EOR shifted;
8912 if d == 15 then // Can only occur for ARM encoding
8913 ALUWritePC(result); // setflags is always FALSE here
8914 else
8915 R[d] = result;
8916 if setflags then
8917 APSR.N = result<31>;
8918 APSR.Z = IsZeroBit(result);
8919 APSR.C = carry;
8920 // APSR.V unchanged
8921 #endif
8922
8923 bool success = false;
8924
8925 if (ConditionPassed(opcode)) {
8926 uint32_t Rd, Rn, Rm;
8927 ARM_ShifterType shift_t;
8928 uint32_t shift_n; // the shift applied to the value read from Rm
8929 bool setflags;
8930 uint32_t carry;
8931 switch (encoding) {
8932 case eEncodingT1:
8933 Rd = Rn = Bits32(opcode, 2, 0);
8934 Rm = Bits32(opcode, 5, 3);
8935 setflags = !InITBlock();
8936 shift_t = SRType_LSL;
8937 shift_n = 0;
8938 break;
8939 case eEncodingT2:
8940 Rd = Bits32(opcode, 11, 8);
8941 Rn = Bits32(opcode, 19, 16);
8942 Rm = Bits32(opcode, 3, 0);
8943 setflags = BitIsSet(opcode, 20);
8944 shift_n = DecodeImmShiftThumb(opcode, shift_t);
8945 // if Rd == '1111' && S == '1' then SEE TEQ (register);
8946 if (Rd == 15 && setflags)
8947 return EmulateTEQReg(opcode, eEncodingT1);
8948 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8949 return false;
8950 break;
8951 case eEncodingA1:
8952 Rd = Bits32(opcode, 15, 12);
8953 Rn = Bits32(opcode, 19, 16);
8954 Rm = Bits32(opcode, 3, 0);
8955 setflags = BitIsSet(opcode, 20);
8956 shift_n = DecodeImmShiftARM(opcode, shift_t);
8957
8958 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8959 // instructions;
8960 if (Rd == 15 && setflags)
8961 return EmulateSUBSPcLrEtc(opcode, encoding);
8962 break;
8963 default:
8964 return false;
8965 }
8966
8967 // Read the first operand.
8968 uint32_t val1 = ReadCoreReg(Rn, &success);
8969 if (!success)
8970 return false;
8971
8972 // Read the second operand.
8973 uint32_t val2 = ReadCoreReg(Rm, &success);
8974 if (!success)
8975 return false;
8976
8977 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8978 if (!success)
8979 return false;
8980 uint32_t result = val1 ^ shifted;
8981
8982 EmulateInstruction::Context context;
8983 context.type = EmulateInstruction::eContextImmediate;
8984 context.SetNoArgs();
8985
8986 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8987 return false;
8988 }
8989 return true;
8990 }
8991
8992 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
8993 // and an immediate value, and writes the result to the destination register.
8994 // It can optionally update the condition flags based on the result.
EmulateORRImm(const uint32_t opcode,const ARMEncoding encoding)8995 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
8996 const ARMEncoding encoding) {
8997 #if 0
8998 // ARM pseudo code...
8999 if ConditionPassed() then
9000 EncodingSpecificOperations();
9001 result = R[n] OR imm32;
9002 if d == 15 then // Can only occur for ARM encoding
9003 ALUWritePC(result); // setflags is always FALSE here
9004 else
9005 R[d] = result;
9006 if setflags then
9007 APSR.N = result<31>;
9008 APSR.Z = IsZeroBit(result);
9009 APSR.C = carry;
9010 // APSR.V unchanged
9011 #endif
9012
9013 bool success = false;
9014
9015 if (ConditionPassed(opcode)) {
9016 uint32_t Rd, Rn;
9017 uint32_t
9018 imm32; // the immediate value to be ORed to the value obtained from Rn
9019 bool setflags;
9020 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9021 switch (encoding) {
9022 case eEncodingT1:
9023 Rd = Bits32(opcode, 11, 8);
9024 Rn = Bits32(opcode, 19, 16);
9025 setflags = BitIsSet(opcode, 20);
9026 imm32 = ThumbExpandImm_C(
9027 opcode, APSR_C,
9028 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9029 // if Rn == '1111' then SEE MOV (immediate);
9030 if (Rn == 15)
9031 return EmulateMOVRdImm(opcode, eEncodingT2);
9032 if (BadReg(Rd) || Rn == 13)
9033 return false;
9034 break;
9035 case eEncodingA1:
9036 Rd = Bits32(opcode, 15, 12);
9037 Rn = Bits32(opcode, 19, 16);
9038 setflags = BitIsSet(opcode, 20);
9039 imm32 =
9040 ARMExpandImm_C(opcode, APSR_C,
9041 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9042
9043 if (Rd == 15 && setflags)
9044 return EmulateSUBSPcLrEtc(opcode, encoding);
9045 break;
9046 default:
9047 return false;
9048 }
9049
9050 // Read the first operand.
9051 uint32_t val1 = ReadCoreReg(Rn, &success);
9052 if (!success)
9053 return false;
9054
9055 uint32_t result = val1 | imm32;
9056
9057 EmulateInstruction::Context context;
9058 context.type = EmulateInstruction::eContextImmediate;
9059 context.SetNoArgs();
9060
9061 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9062 return false;
9063 }
9064 return true;
9065 }
9066
9067 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
9068 // and an optionally-shifted register value, and writes the result to the
9069 // destination register. It can optionally update the condition flags based on
9070 // the result.
EmulateORRReg(const uint32_t opcode,const ARMEncoding encoding)9071 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
9072 const ARMEncoding encoding) {
9073 #if 0
9074 // ARM pseudo code...
9075 if ConditionPassed() then
9076 EncodingSpecificOperations();
9077 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9078 result = R[n] OR shifted;
9079 if d == 15 then // Can only occur for ARM encoding
9080 ALUWritePC(result); // setflags is always FALSE here
9081 else
9082 R[d] = result;
9083 if setflags then
9084 APSR.N = result<31>;
9085 APSR.Z = IsZeroBit(result);
9086 APSR.C = carry;
9087 // APSR.V unchanged
9088 #endif
9089
9090 bool success = false;
9091
9092 if (ConditionPassed(opcode)) {
9093 uint32_t Rd, Rn, Rm;
9094 ARM_ShifterType shift_t;
9095 uint32_t shift_n; // the shift applied to the value read from Rm
9096 bool setflags;
9097 uint32_t carry;
9098 switch (encoding) {
9099 case eEncodingT1:
9100 Rd = Rn = Bits32(opcode, 2, 0);
9101 Rm = Bits32(opcode, 5, 3);
9102 setflags = !InITBlock();
9103 shift_t = SRType_LSL;
9104 shift_n = 0;
9105 break;
9106 case eEncodingT2:
9107 Rd = Bits32(opcode, 11, 8);
9108 Rn = Bits32(opcode, 19, 16);
9109 Rm = Bits32(opcode, 3, 0);
9110 setflags = BitIsSet(opcode, 20);
9111 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9112 // if Rn == '1111' then SEE MOV (register);
9113 if (Rn == 15)
9114 return EmulateMOVRdRm(opcode, eEncodingT3);
9115 if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
9116 return false;
9117 break;
9118 case eEncodingA1:
9119 Rd = Bits32(opcode, 15, 12);
9120 Rn = Bits32(opcode, 19, 16);
9121 Rm = Bits32(opcode, 3, 0);
9122 setflags = BitIsSet(opcode, 20);
9123 shift_n = DecodeImmShiftARM(opcode, shift_t);
9124
9125 if (Rd == 15 && setflags)
9126 return EmulateSUBSPcLrEtc(opcode, encoding);
9127 break;
9128 default:
9129 return false;
9130 }
9131
9132 // Read the first operand.
9133 uint32_t val1 = ReadCoreReg(Rn, &success);
9134 if (!success)
9135 return false;
9136
9137 // Read the second operand.
9138 uint32_t val2 = ReadCoreReg(Rm, &success);
9139 if (!success)
9140 return false;
9141
9142 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9143 if (!success)
9144 return false;
9145 uint32_t result = val1 | shifted;
9146
9147 EmulateInstruction::Context context;
9148 context.type = EmulateInstruction::eContextImmediate;
9149 context.SetNoArgs();
9150
9151 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9152 return false;
9153 }
9154 return true;
9155 }
9156
9157 // Reverse Subtract (immediate) subtracts a register value from an immediate
9158 // value, and writes the result to the destination register. It can optionally
9159 // update the condition flags based on the result.
EmulateRSBImm(const uint32_t opcode,const ARMEncoding encoding)9160 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
9161 const ARMEncoding encoding) {
9162 #if 0
9163 // ARM pseudo code...
9164 if ConditionPassed() then
9165 EncodingSpecificOperations();
9166 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
9167 if d == 15 then // Can only occur for ARM encoding
9168 ALUWritePC(result); // setflags is always FALSE here
9169 else
9170 R[d] = result;
9171 if setflags then
9172 APSR.N = result<31>;
9173 APSR.Z = IsZeroBit(result);
9174 APSR.C = carry;
9175 APSR.V = overflow;
9176 #endif
9177
9178 bool success = false;
9179
9180 uint32_t Rd; // the destination register
9181 uint32_t Rn; // the first operand
9182 bool setflags;
9183 uint32_t
9184 imm32; // the immediate value to be added to the value obtained from Rn
9185 switch (encoding) {
9186 case eEncodingT1:
9187 Rd = Bits32(opcode, 2, 0);
9188 Rn = Bits32(opcode, 5, 3);
9189 setflags = !InITBlock();
9190 imm32 = 0;
9191 break;
9192 case eEncodingT2:
9193 Rd = Bits32(opcode, 11, 8);
9194 Rn = Bits32(opcode, 19, 16);
9195 setflags = BitIsSet(opcode, 20);
9196 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9197 if (BadReg(Rd) || BadReg(Rn))
9198 return false;
9199 break;
9200 case eEncodingA1:
9201 Rd = Bits32(opcode, 15, 12);
9202 Rn = Bits32(opcode, 19, 16);
9203 setflags = BitIsSet(opcode, 20);
9204 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9205
9206 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9207 // instructions;
9208 if (Rd == 15 && setflags)
9209 return EmulateSUBSPcLrEtc(opcode, encoding);
9210 break;
9211 default:
9212 return false;
9213 }
9214 // Read the register value from the operand register Rn.
9215 uint32_t reg_val = ReadCoreReg(Rn, &success);
9216 if (!success)
9217 return false;
9218
9219 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
9220
9221 EmulateInstruction::Context context;
9222 context.type = EmulateInstruction::eContextImmediate;
9223 context.SetNoArgs();
9224
9225 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9226 res.carry_out, res.overflow);
9227 }
9228
9229 // Reverse Subtract (register) subtracts a register value from an optionally-
9230 // shifted register value, and writes the result to the destination register.
9231 // It can optionally update the condition flags based on the result.
EmulateRSBReg(const uint32_t opcode,const ARMEncoding encoding)9232 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
9233 const ARMEncoding encoding) {
9234 #if 0
9235 // ARM pseudo code...
9236 if ConditionPassed() then
9237 EncodingSpecificOperations();
9238 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9239 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
9240 if d == 15 then // Can only occur for ARM encoding
9241 ALUWritePC(result); // setflags is always FALSE here
9242 else
9243 R[d] = result;
9244 if setflags then
9245 APSR.N = result<31>;
9246 APSR.Z = IsZeroBit(result);
9247 APSR.C = carry;
9248 APSR.V = overflow;
9249 #endif
9250
9251 bool success = false;
9252
9253 uint32_t Rd; // the destination register
9254 uint32_t Rn; // the first operand
9255 uint32_t Rm; // the second operand
9256 bool setflags;
9257 ARM_ShifterType shift_t;
9258 uint32_t shift_n; // the shift applied to the value read from Rm
9259 switch (encoding) {
9260 case eEncodingT1:
9261 Rd = Bits32(opcode, 11, 8);
9262 Rn = Bits32(opcode, 19, 16);
9263 Rm = Bits32(opcode, 3, 0);
9264 setflags = BitIsSet(opcode, 20);
9265 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9266 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
9267 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9268 return false;
9269 break;
9270 case eEncodingA1:
9271 Rd = Bits32(opcode, 15, 12);
9272 Rn = Bits32(opcode, 19, 16);
9273 Rm = Bits32(opcode, 3, 0);
9274 setflags = BitIsSet(opcode, 20);
9275 shift_n = DecodeImmShiftARM(opcode, shift_t);
9276
9277 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9278 // instructions;
9279 if (Rd == 15 && setflags)
9280 return EmulateSUBSPcLrEtc(opcode, encoding);
9281 break;
9282 default:
9283 return false;
9284 }
9285 // Read the register value from register Rn.
9286 uint32_t val1 = ReadCoreReg(Rn, &success);
9287 if (!success)
9288 return false;
9289
9290 // Read the register value from register Rm.
9291 uint32_t val2 = ReadCoreReg(Rm, &success);
9292 if (!success)
9293 return false;
9294
9295 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9296 if (!success)
9297 return false;
9298 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
9299
9300 EmulateInstruction::Context context;
9301 context.type = EmulateInstruction::eContextImmediate;
9302 context.SetNoArgs();
9303 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9304 res.carry_out, res.overflow);
9305 }
9306
9307 // Reverse Subtract with Carry (immediate) subtracts a register value and the
9308 // value of NOT (Carry flag) from an immediate value, and writes the result to
9309 // the destination register. It can optionally update the condition flags based
9310 // on the result.
EmulateRSCImm(const uint32_t opcode,const ARMEncoding encoding)9311 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
9312 const ARMEncoding encoding) {
9313 #if 0
9314 // ARM pseudo code...
9315 if ConditionPassed() then
9316 EncodingSpecificOperations();
9317 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
9318 if d == 15 then
9319 ALUWritePC(result); // setflags is always FALSE here
9320 else
9321 R[d] = result;
9322 if setflags then
9323 APSR.N = result<31>;
9324 APSR.Z = IsZeroBit(result);
9325 APSR.C = carry;
9326 APSR.V = overflow;
9327 #endif
9328
9329 bool success = false;
9330
9331 uint32_t Rd; // the destination register
9332 uint32_t Rn; // the first operand
9333 bool setflags;
9334 uint32_t
9335 imm32; // the immediate value to be added to the value obtained from Rn
9336 switch (encoding) {
9337 case eEncodingA1:
9338 Rd = Bits32(opcode, 15, 12);
9339 Rn = Bits32(opcode, 19, 16);
9340 setflags = BitIsSet(opcode, 20);
9341 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9342
9343 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9344 // instructions;
9345 if (Rd == 15 && setflags)
9346 return EmulateSUBSPcLrEtc(opcode, encoding);
9347 break;
9348 default:
9349 return false;
9350 }
9351 // Read the register value from the operand register Rn.
9352 uint32_t reg_val = ReadCoreReg(Rn, &success);
9353 if (!success)
9354 return false;
9355
9356 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
9357
9358 EmulateInstruction::Context context;
9359 context.type = EmulateInstruction::eContextImmediate;
9360 context.SetNoArgs();
9361
9362 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9363 res.carry_out, res.overflow);
9364 }
9365
9366 // Reverse Subtract with Carry (register) subtracts a register value and the
9367 // value of NOT (Carry flag) from an optionally-shifted register value, and
9368 // writes the result to the destination register. It can optionally update the
9369 // condition flags based on the result.
EmulateRSCReg(const uint32_t opcode,const ARMEncoding encoding)9370 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
9371 const ARMEncoding encoding) {
9372 #if 0
9373 // ARM pseudo code...
9374 if ConditionPassed() then
9375 EncodingSpecificOperations();
9376 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9377 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
9378 if d == 15 then
9379 ALUWritePC(result); // setflags is always FALSE here
9380 else
9381 R[d] = result;
9382 if setflags then
9383 APSR.N = result<31>;
9384 APSR.Z = IsZeroBit(result);
9385 APSR.C = carry;
9386 APSR.V = overflow;
9387 #endif
9388
9389 bool success = false;
9390
9391 uint32_t Rd; // the destination register
9392 uint32_t Rn; // the first operand
9393 uint32_t Rm; // the second operand
9394 bool setflags;
9395 ARM_ShifterType shift_t;
9396 uint32_t shift_n; // the shift applied to the value read from Rm
9397 switch (encoding) {
9398 case eEncodingA1:
9399 Rd = Bits32(opcode, 15, 12);
9400 Rn = Bits32(opcode, 19, 16);
9401 Rm = Bits32(opcode, 3, 0);
9402 setflags = BitIsSet(opcode, 20);
9403 shift_n = DecodeImmShiftARM(opcode, shift_t);
9404
9405 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9406 // instructions;
9407 if (Rd == 15 && setflags)
9408 return EmulateSUBSPcLrEtc(opcode, encoding);
9409 break;
9410 default:
9411 return false;
9412 }
9413 // Read the register value from register Rn.
9414 uint32_t val1 = ReadCoreReg(Rn, &success);
9415 if (!success)
9416 return false;
9417
9418 // Read the register value from register Rm.
9419 uint32_t val2 = ReadCoreReg(Rm, &success);
9420 if (!success)
9421 return false;
9422
9423 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9424 if (!success)
9425 return false;
9426 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
9427
9428 EmulateInstruction::Context context;
9429 context.type = EmulateInstruction::eContextImmediate;
9430 context.SetNoArgs();
9431 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9432 res.carry_out, res.overflow);
9433 }
9434
9435 // Subtract with Carry (immediate) subtracts an immediate value and the value
9436 // of
9437 // NOT (Carry flag) from a register value, and writes the result to the
9438 // destination register.
9439 // It can optionally update the condition flags based on the result.
EmulateSBCImm(const uint32_t opcode,const ARMEncoding encoding)9440 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
9441 const ARMEncoding encoding) {
9442 #if 0
9443 // ARM pseudo code...
9444 if ConditionPassed() then
9445 EncodingSpecificOperations();
9446 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
9447 if d == 15 then // Can only occur for ARM encoding
9448 ALUWritePC(result); // setflags is always FALSE here
9449 else
9450 R[d] = result;
9451 if setflags then
9452 APSR.N = result<31>;
9453 APSR.Z = IsZeroBit(result);
9454 APSR.C = carry;
9455 APSR.V = overflow;
9456 #endif
9457
9458 bool success = false;
9459
9460 uint32_t Rd; // the destination register
9461 uint32_t Rn; // the first operand
9462 bool setflags;
9463 uint32_t
9464 imm32; // the immediate value to be added to the value obtained from Rn
9465 switch (encoding) {
9466 case eEncodingT1:
9467 Rd = Bits32(opcode, 11, 8);
9468 Rn = Bits32(opcode, 19, 16);
9469 setflags = BitIsSet(opcode, 20);
9470 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9471 if (BadReg(Rd) || BadReg(Rn))
9472 return false;
9473 break;
9474 case eEncodingA1:
9475 Rd = Bits32(opcode, 15, 12);
9476 Rn = Bits32(opcode, 19, 16);
9477 setflags = BitIsSet(opcode, 20);
9478 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9479
9480 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9481 // instructions;
9482 if (Rd == 15 && setflags)
9483 return EmulateSUBSPcLrEtc(opcode, encoding);
9484 break;
9485 default:
9486 return false;
9487 }
9488 // Read the register value from the operand register Rn.
9489 uint32_t reg_val = ReadCoreReg(Rn, &success);
9490 if (!success)
9491 return false;
9492
9493 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9494
9495 EmulateInstruction::Context context;
9496 context.type = EmulateInstruction::eContextImmediate;
9497 context.SetNoArgs();
9498
9499 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9500 res.carry_out, res.overflow);
9501 }
9502
9503 // Subtract with Carry (register) subtracts an optionally-shifted register
9504 // value and the value of
9505 // NOT (Carry flag) from a register value, and writes the result to the
9506 // destination register.
9507 // It can optionally update the condition flags based on the result.
EmulateSBCReg(const uint32_t opcode,const ARMEncoding encoding)9508 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
9509 const ARMEncoding encoding) {
9510 #if 0
9511 // ARM pseudo code...
9512 if ConditionPassed() then
9513 EncodingSpecificOperations();
9514 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9515 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9516 if d == 15 then // Can only occur for ARM encoding
9517 ALUWritePC(result); // setflags is always FALSE here
9518 else
9519 R[d] = result;
9520 if setflags then
9521 APSR.N = result<31>;
9522 APSR.Z = IsZeroBit(result);
9523 APSR.C = carry;
9524 APSR.V = overflow;
9525 #endif
9526
9527 bool success = false;
9528
9529 uint32_t Rd; // the destination register
9530 uint32_t Rn; // the first operand
9531 uint32_t Rm; // the second operand
9532 bool setflags;
9533 ARM_ShifterType shift_t;
9534 uint32_t shift_n; // the shift applied to the value read from Rm
9535 switch (encoding) {
9536 case eEncodingT1:
9537 Rd = Rn = Bits32(opcode, 2, 0);
9538 Rm = Bits32(opcode, 5, 3);
9539 setflags = !InITBlock();
9540 shift_t = SRType_LSL;
9541 shift_n = 0;
9542 break;
9543 case eEncodingT2:
9544 Rd = Bits32(opcode, 11, 8);
9545 Rn = Bits32(opcode, 19, 16);
9546 Rm = Bits32(opcode, 3, 0);
9547 setflags = BitIsSet(opcode, 20);
9548 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9549 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9550 return false;
9551 break;
9552 case eEncodingA1:
9553 Rd = Bits32(opcode, 15, 12);
9554 Rn = Bits32(opcode, 19, 16);
9555 Rm = Bits32(opcode, 3, 0);
9556 setflags = BitIsSet(opcode, 20);
9557 shift_n = DecodeImmShiftARM(opcode, shift_t);
9558
9559 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9560 // instructions;
9561 if (Rd == 15 && setflags)
9562 return EmulateSUBSPcLrEtc(opcode, encoding);
9563 break;
9564 default:
9565 return false;
9566 }
9567 // Read the register value from register Rn.
9568 uint32_t val1 = ReadCoreReg(Rn, &success);
9569 if (!success)
9570 return false;
9571
9572 // Read the register value from register Rm.
9573 uint32_t val2 = ReadCoreReg(Rm, &success);
9574 if (!success)
9575 return false;
9576
9577 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9578 if (!success)
9579 return false;
9580 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9581
9582 EmulateInstruction::Context context;
9583 context.type = EmulateInstruction::eContextImmediate;
9584 context.SetNoArgs();
9585 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9586 res.carry_out, res.overflow);
9587 }
9588
9589 // This instruction subtracts an immediate value from a register value, and
9590 // writes the result to the destination register. It can optionally update the
9591 // condition flags based on the result.
EmulateSUBImmThumb(const uint32_t opcode,const ARMEncoding encoding)9592 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
9593 const ARMEncoding encoding) {
9594 #if 0
9595 // ARM pseudo code...
9596 if ConditionPassed() then
9597 EncodingSpecificOperations();
9598 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9599 R[d] = result;
9600 if setflags then
9601 APSR.N = result<31>;
9602 APSR.Z = IsZeroBit(result);
9603 APSR.C = carry;
9604 APSR.V = overflow;
9605 #endif
9606
9607 bool success = false;
9608
9609 uint32_t Rd; // the destination register
9610 uint32_t Rn; // the first operand
9611 bool setflags;
9612 uint32_t imm32; // the immediate value to be subtracted from the value
9613 // obtained from Rn
9614 switch (encoding) {
9615 case eEncodingT1:
9616 Rd = Bits32(opcode, 2, 0);
9617 Rn = Bits32(opcode, 5, 3);
9618 setflags = !InITBlock();
9619 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9620 break;
9621 case eEncodingT2:
9622 Rd = Rn = Bits32(opcode, 10, 8);
9623 setflags = !InITBlock();
9624 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9625 break;
9626 case eEncodingT3:
9627 Rd = Bits32(opcode, 11, 8);
9628 Rn = Bits32(opcode, 19, 16);
9629 setflags = BitIsSet(opcode, 20);
9630 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9631
9632 // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9633 if (Rd == 15 && setflags)
9634 return EmulateCMPImm(opcode, eEncodingT2);
9635
9636 // if Rn == '1101' then SEE SUB (SP minus immediate);
9637 if (Rn == 13)
9638 return EmulateSUBSPImm(opcode, eEncodingT2);
9639
9640 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9641 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9642 return false;
9643 break;
9644 case eEncodingT4:
9645 Rd = Bits32(opcode, 11, 8);
9646 Rn = Bits32(opcode, 19, 16);
9647 setflags = BitIsSet(opcode, 20);
9648 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9649
9650 // if Rn == '1111' then SEE ADR;
9651 if (Rn == 15)
9652 return EmulateADR(opcode, eEncodingT2);
9653
9654 // if Rn == '1101' then SEE SUB (SP minus immediate);
9655 if (Rn == 13)
9656 return EmulateSUBSPImm(opcode, eEncodingT3);
9657
9658 if (BadReg(Rd))
9659 return false;
9660 break;
9661 default:
9662 return false;
9663 }
9664 // Read the register value from the operand register Rn.
9665 uint32_t reg_val = ReadCoreReg(Rn, &success);
9666 if (!success)
9667 return false;
9668
9669 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9670
9671 EmulateInstruction::Context context;
9672 context.type = EmulateInstruction::eContextImmediate;
9673 context.SetNoArgs();
9674
9675 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9676 res.carry_out, res.overflow);
9677 }
9678
9679 // This instruction subtracts an immediate value from a register value, and
9680 // writes the result to the destination register. It can optionally update the
9681 // condition flags based on the result.
EmulateSUBImmARM(const uint32_t opcode,const ARMEncoding encoding)9682 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
9683 const ARMEncoding encoding) {
9684 #if 0
9685 // ARM pseudo code...
9686 if ConditionPassed() then
9687 EncodingSpecificOperations();
9688 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9689 if d == 15 then
9690 ALUWritePC(result); // setflags is always FALSE here
9691 else
9692 R[d] = result;
9693 if setflags then
9694 APSR.N = result<31>;
9695 APSR.Z = IsZeroBit(result);
9696 APSR.C = carry;
9697 APSR.V = overflow;
9698 #endif
9699
9700 bool success = false;
9701
9702 if (ConditionPassed(opcode)) {
9703 uint32_t Rd; // the destination register
9704 uint32_t Rn; // the first operand
9705 bool setflags;
9706 uint32_t imm32; // the immediate value to be subtracted from the value
9707 // obtained from Rn
9708 switch (encoding) {
9709 case eEncodingA1:
9710 Rd = Bits32(opcode, 15, 12);
9711 Rn = Bits32(opcode, 19, 16);
9712 setflags = BitIsSet(opcode, 20);
9713 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9714
9715 // if Rn == '1111' && S == '0' then SEE ADR;
9716 if (Rn == 15 && !setflags)
9717 return EmulateADR(opcode, eEncodingA2);
9718
9719 // if Rn == '1101' then SEE SUB (SP minus immediate);
9720 if (Rn == 13)
9721 return EmulateSUBSPImm(opcode, eEncodingA1);
9722
9723 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9724 // instructions;
9725 if (Rd == 15 && setflags)
9726 return EmulateSUBSPcLrEtc(opcode, encoding);
9727 break;
9728 default:
9729 return false;
9730 }
9731 // Read the register value from the operand register Rn.
9732 uint32_t reg_val = ReadCoreReg(Rn, &success);
9733 if (!success)
9734 return false;
9735
9736 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9737
9738 EmulateInstruction::Context context;
9739 if (Rd == 13)
9740 context.type = EmulateInstruction::eContextAdjustStackPointer;
9741 else
9742 context.type = EmulateInstruction::eContextRegisterPlusOffset;
9743
9744 RegisterInfo dwarf_reg;
9745 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
9746 int64_t imm32_signed = imm32;
9747 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed);
9748
9749 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9750 res.carry_out, res.overflow))
9751 return false;
9752 }
9753 return true;
9754 }
9755
9756 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
9757 // register value and an immediate value. It updates the condition flags based
9758 // on the result, and discards the result.
EmulateTEQImm(const uint32_t opcode,const ARMEncoding encoding)9759 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
9760 const ARMEncoding encoding) {
9761 #if 0
9762 // ARM pseudo code...
9763 if ConditionPassed() then
9764 EncodingSpecificOperations();
9765 result = R[n] EOR imm32;
9766 APSR.N = result<31>;
9767 APSR.Z = IsZeroBit(result);
9768 APSR.C = carry;
9769 // APSR.V unchanged
9770 #endif
9771
9772 bool success = false;
9773
9774 if (ConditionPassed(opcode)) {
9775 uint32_t Rn;
9776 uint32_t
9777 imm32; // the immediate value to be ANDed to the value obtained from Rn
9778 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9779 switch (encoding) {
9780 case eEncodingT1:
9781 Rn = Bits32(opcode, 19, 16);
9782 imm32 = ThumbExpandImm_C(
9783 opcode, APSR_C,
9784 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9785 if (BadReg(Rn))
9786 return false;
9787 break;
9788 case eEncodingA1:
9789 Rn = Bits32(opcode, 19, 16);
9790 imm32 =
9791 ARMExpandImm_C(opcode, APSR_C,
9792 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9793 break;
9794 default:
9795 return false;
9796 }
9797
9798 // Read the first operand.
9799 uint32_t val1 = ReadCoreReg(Rn, &success);
9800 if (!success)
9801 return false;
9802
9803 uint32_t result = val1 ^ imm32;
9804
9805 EmulateInstruction::Context context;
9806 context.type = EmulateInstruction::eContextImmediate;
9807 context.SetNoArgs();
9808
9809 if (!WriteFlags(context, result, carry))
9810 return false;
9811 }
9812 return true;
9813 }
9814
9815 // Test Equivalence (register) performs a bitwise exclusive OR operation on a
9816 // register value and an optionally-shifted register value. It updates the
9817 // condition flags based on the result, and discards the result.
EmulateTEQReg(const uint32_t opcode,const ARMEncoding encoding)9818 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
9819 const ARMEncoding encoding) {
9820 #if 0
9821 // ARM pseudo code...
9822 if ConditionPassed() then
9823 EncodingSpecificOperations();
9824 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9825 result = R[n] EOR shifted;
9826 APSR.N = result<31>;
9827 APSR.Z = IsZeroBit(result);
9828 APSR.C = carry;
9829 // APSR.V unchanged
9830 #endif
9831
9832 bool success = false;
9833
9834 if (ConditionPassed(opcode)) {
9835 uint32_t Rn, Rm;
9836 ARM_ShifterType shift_t;
9837 uint32_t shift_n; // the shift applied to the value read from Rm
9838 uint32_t carry;
9839 switch (encoding) {
9840 case eEncodingT1:
9841 Rn = Bits32(opcode, 19, 16);
9842 Rm = Bits32(opcode, 3, 0);
9843 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9844 if (BadReg(Rn) || BadReg(Rm))
9845 return false;
9846 break;
9847 case eEncodingA1:
9848 Rn = Bits32(opcode, 19, 16);
9849 Rm = Bits32(opcode, 3, 0);
9850 shift_n = DecodeImmShiftARM(opcode, shift_t);
9851 break;
9852 default:
9853 return false;
9854 }
9855
9856 // Read the first operand.
9857 uint32_t val1 = ReadCoreReg(Rn, &success);
9858 if (!success)
9859 return false;
9860
9861 // Read the second operand.
9862 uint32_t val2 = ReadCoreReg(Rm, &success);
9863 if (!success)
9864 return false;
9865
9866 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9867 if (!success)
9868 return false;
9869 uint32_t result = val1 ^ shifted;
9870
9871 EmulateInstruction::Context context;
9872 context.type = EmulateInstruction::eContextImmediate;
9873 context.SetNoArgs();
9874
9875 if (!WriteFlags(context, result, carry))
9876 return false;
9877 }
9878 return true;
9879 }
9880
9881 // Test (immediate) performs a bitwise AND operation on a register value and an
9882 // immediate value. It updates the condition flags based on the result, and
9883 // discards the result.
EmulateTSTImm(const uint32_t opcode,const ARMEncoding encoding)9884 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
9885 const ARMEncoding encoding) {
9886 #if 0
9887 // ARM pseudo code...
9888 if ConditionPassed() then
9889 EncodingSpecificOperations();
9890 result = R[n] AND imm32;
9891 APSR.N = result<31>;
9892 APSR.Z = IsZeroBit(result);
9893 APSR.C = carry;
9894 // APSR.V unchanged
9895 #endif
9896
9897 bool success = false;
9898
9899 if (ConditionPassed(opcode)) {
9900 uint32_t Rn;
9901 uint32_t
9902 imm32; // the immediate value to be ANDed to the value obtained from Rn
9903 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9904 switch (encoding) {
9905 case eEncodingT1:
9906 Rn = Bits32(opcode, 19, 16);
9907 imm32 = ThumbExpandImm_C(
9908 opcode, APSR_C,
9909 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9910 if (BadReg(Rn))
9911 return false;
9912 break;
9913 case eEncodingA1:
9914 Rn = Bits32(opcode, 19, 16);
9915 imm32 =
9916 ARMExpandImm_C(opcode, APSR_C,
9917 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9918 break;
9919 default:
9920 return false;
9921 }
9922
9923 // Read the first operand.
9924 uint32_t val1 = ReadCoreReg(Rn, &success);
9925 if (!success)
9926 return false;
9927
9928 uint32_t result = val1 & imm32;
9929
9930 EmulateInstruction::Context context;
9931 context.type = EmulateInstruction::eContextImmediate;
9932 context.SetNoArgs();
9933
9934 if (!WriteFlags(context, result, carry))
9935 return false;
9936 }
9937 return true;
9938 }
9939
9940 // Test (register) performs a bitwise AND operation on a register value and an
9941 // optionally-shifted register value. It updates the condition flags based on
9942 // the result, and discards the result.
EmulateTSTReg(const uint32_t opcode,const ARMEncoding encoding)9943 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
9944 const ARMEncoding encoding) {
9945 #if 0
9946 // ARM pseudo code...
9947 if ConditionPassed() then
9948 EncodingSpecificOperations();
9949 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9950 result = R[n] AND shifted;
9951 APSR.N = result<31>;
9952 APSR.Z = IsZeroBit(result);
9953 APSR.C = carry;
9954 // APSR.V unchanged
9955 #endif
9956
9957 bool success = false;
9958
9959 if (ConditionPassed(opcode)) {
9960 uint32_t Rn, Rm;
9961 ARM_ShifterType shift_t;
9962 uint32_t shift_n; // the shift applied to the value read from Rm
9963 uint32_t carry;
9964 switch (encoding) {
9965 case eEncodingT1:
9966 Rn = Bits32(opcode, 2, 0);
9967 Rm = Bits32(opcode, 5, 3);
9968 shift_t = SRType_LSL;
9969 shift_n = 0;
9970 break;
9971 case eEncodingT2:
9972 Rn = Bits32(opcode, 19, 16);
9973 Rm = Bits32(opcode, 3, 0);
9974 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9975 if (BadReg(Rn) || BadReg(Rm))
9976 return false;
9977 break;
9978 case eEncodingA1:
9979 Rn = Bits32(opcode, 19, 16);
9980 Rm = Bits32(opcode, 3, 0);
9981 shift_n = DecodeImmShiftARM(opcode, shift_t);
9982 break;
9983 default:
9984 return false;
9985 }
9986
9987 // Read the first operand.
9988 uint32_t val1 = ReadCoreReg(Rn, &success);
9989 if (!success)
9990 return false;
9991
9992 // Read the second operand.
9993 uint32_t val2 = ReadCoreReg(Rm, &success);
9994 if (!success)
9995 return false;
9996
9997 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9998 if (!success)
9999 return false;
10000 uint32_t result = val1 & shifted;
10001
10002 EmulateInstruction::Context context;
10003 context.type = EmulateInstruction::eContextImmediate;
10004 context.SetNoArgs();
10005
10006 if (!WriteFlags(context, result, carry))
10007 return false;
10008 }
10009 return true;
10010 }
10011
10012 // A8.6.216 SUB (SP minus register)
EmulateSUBSPReg(const uint32_t opcode,const ARMEncoding encoding)10013 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
10014 const ARMEncoding encoding) {
10015 #if 0
10016 if ConditionPassed() then
10017 EncodingSpecificOperations();
10018 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10019 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10020 if d == 15 then // Can only occur for ARM encoding
10021 ALUWritePC(result); // setflags is always FALSE here
10022 else
10023 R[d] = result;
10024 if setflags then
10025 APSR.N = result<31>;
10026 APSR.Z = IsZeroBit(result);
10027 APSR.C = carry;
10028 APSR.V = overflow;
10029 #endif
10030
10031 bool success = false;
10032
10033 if (ConditionPassed(opcode)) {
10034 uint32_t d;
10035 uint32_t m;
10036 bool setflags;
10037 ARM_ShifterType shift_t;
10038 uint32_t shift_n;
10039
10040 switch (encoding) {
10041 case eEncodingT1:
10042 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10043 d = Bits32(opcode, 11, 8);
10044 m = Bits32(opcode, 3, 0);
10045 setflags = BitIsSet(opcode, 20);
10046
10047 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10048 shift_n = DecodeImmShiftThumb(opcode, shift_t);
10049
10050 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
10051 // UNPREDICTABLE;
10052 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
10053 return false;
10054
10055 // if d == 15 || BadReg(m) then UNPREDICTABLE;
10056 if ((d == 15) || BadReg(m))
10057 return false;
10058 break;
10059
10060 case eEncodingA1:
10061 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10062 d = Bits32(opcode, 15, 12);
10063 m = Bits32(opcode, 3, 0);
10064 setflags = BitIsSet(opcode, 20);
10065
10066 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10067 // instructions;
10068 if (d == 15 && setflags)
10069 EmulateSUBSPcLrEtc(opcode, encoding);
10070
10071 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10072 shift_n = DecodeImmShiftARM(opcode, shift_t);
10073 break;
10074
10075 default:
10076 return false;
10077 }
10078
10079 // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10080 uint32_t Rm = ReadCoreReg(m, &success);
10081 if (!success)
10082 return false;
10083
10084 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10085 if (!success)
10086 return false;
10087
10088 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10089 uint32_t sp_val = ReadCoreReg(SP_REG, &success);
10090 if (!success)
10091 return false;
10092
10093 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
10094
10095 EmulateInstruction::Context context;
10096 context.type = eContextArithmetic;
10097 RegisterInfo sp_reg;
10098 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
10099 RegisterInfo dwarf_reg;
10100 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
10101 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg);
10102
10103 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10104 res.carry_out, res.overflow))
10105 return false;
10106 }
10107 return true;
10108 }
10109
10110 // A8.6.7 ADD (register-shifted register)
EmulateADDRegShift(const uint32_t opcode,const ARMEncoding encoding)10111 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
10112 const ARMEncoding encoding) {
10113 #if 0
10114 if ConditionPassed() then
10115 EncodingSpecificOperations();
10116 shift_n = UInt(R[s]<7:0>);
10117 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10118 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10119 R[d] = result;
10120 if setflags then
10121 APSR.N = result<31>;
10122 APSR.Z = IsZeroBit(result);
10123 APSR.C = carry;
10124 APSR.V = overflow;
10125 #endif
10126
10127 bool success = false;
10128
10129 if (ConditionPassed(opcode)) {
10130 uint32_t d;
10131 uint32_t n;
10132 uint32_t m;
10133 uint32_t s;
10134 bool setflags;
10135 ARM_ShifterType shift_t;
10136
10137 switch (encoding) {
10138 case eEncodingA1:
10139 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
10140 d = Bits32(opcode, 15, 12);
10141 n = Bits32(opcode, 19, 16);
10142 m = Bits32(opcode, 3, 0);
10143 s = Bits32(opcode, 11, 8);
10144
10145 // setflags = (S == '1'); shift_t = DecodeRegShift(type);
10146 setflags = BitIsSet(opcode, 20);
10147 shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
10148
10149 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
10150 if ((d == 15) || (n == 15) || (m == 15) || (s == 15))
10151 return false;
10152 break;
10153
10154 default:
10155 return false;
10156 }
10157
10158 // shift_n = UInt(R[s]<7:0>);
10159 uint32_t Rs = ReadCoreReg(s, &success);
10160 if (!success)
10161 return false;
10162
10163 uint32_t shift_n = Bits32(Rs, 7, 0);
10164
10165 // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10166 uint32_t Rm = ReadCoreReg(m, &success);
10167 if (!success)
10168 return false;
10169
10170 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10171 if (!success)
10172 return false;
10173
10174 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10175 uint32_t Rn = ReadCoreReg(n, &success);
10176 if (!success)
10177 return false;
10178
10179 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
10180
10181 // R[d] = result;
10182 EmulateInstruction::Context context;
10183 context.type = eContextArithmetic;
10184 RegisterInfo reg_n;
10185 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10186 RegisterInfo reg_m;
10187 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10188
10189 context.SetRegisterRegisterOperands(reg_n, reg_m);
10190
10191 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
10192 res.result))
10193 return false;
10194
10195 // if setflags then
10196 // APSR.N = result<31>;
10197 // APSR.Z = IsZeroBit(result);
10198 // APSR.C = carry;
10199 // APSR.V = overflow;
10200 if (setflags)
10201 return WriteFlags(context, res.result, res.carry_out, res.overflow);
10202 }
10203 return true;
10204 }
10205
10206 // A8.6.213 SUB (register)
EmulateSUBReg(const uint32_t opcode,const ARMEncoding encoding)10207 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
10208 const ARMEncoding encoding) {
10209 #if 0
10210 if ConditionPassed() then
10211 EncodingSpecificOperations();
10212 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10213 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10214 if d == 15 then // Can only occur for ARM encoding
10215 ALUWritePC(result); // setflags is always FALSE here
10216 else
10217 R[d] = result;
10218 if setflags then
10219 APSR.N = result<31>;
10220 APSR.Z = IsZeroBit(result);
10221 APSR.C = carry;
10222 APSR.V = overflow;
10223 #endif
10224
10225 bool success = false;
10226
10227 if (ConditionPassed(opcode)) {
10228 uint32_t d;
10229 uint32_t n;
10230 uint32_t m;
10231 bool setflags;
10232 ARM_ShifterType shift_t;
10233 uint32_t shift_n;
10234
10235 switch (encoding) {
10236 case eEncodingT1:
10237 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
10238 d = Bits32(opcode, 2, 0);
10239 n = Bits32(opcode, 5, 3);
10240 m = Bits32(opcode, 8, 6);
10241 setflags = !InITBlock();
10242
10243 // (shift_t, shift_n) = (SRType_LSL, 0);
10244 shift_t = SRType_LSL;
10245 shift_n = 0;
10246
10247 break;
10248
10249 case eEncodingT2:
10250 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
10251 d = Bits32(opcode, 11, 8);
10252 n = Bits32(opcode, 19, 16);
10253 m = Bits32(opcode, 3, 0);
10254 setflags = BitIsSet(opcode, 20);
10255
10256 // if Rd == "1111" && S == "1" then SEE CMP (register);
10257 if (d == 15 && setflags == 1)
10258 return EmulateCMPImm(opcode, eEncodingT3);
10259
10260 // if Rn == "1101" then SEE SUB (SP minus register);
10261 if (n == 13)
10262 return EmulateSUBSPReg(opcode, eEncodingT1);
10263
10264 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10265 shift_n = DecodeImmShiftThumb(opcode, shift_t);
10266
10267 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
10268 // UNPREDICTABLE;
10269 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
10270 BadReg(m))
10271 return false;
10272
10273 break;
10274
10275 case eEncodingA1:
10276 // if Rn == '1101' then SEE SUB (SP minus register);
10277 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
10278 d = Bits32(opcode, 15, 12);
10279 n = Bits32(opcode, 19, 16);
10280 m = Bits32(opcode, 3, 0);
10281 setflags = BitIsSet(opcode, 20);
10282
10283 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10284 // instructions;
10285 if ((d == 15) && setflags)
10286 EmulateSUBSPcLrEtc(opcode, encoding);
10287
10288 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10289 shift_n = DecodeImmShiftARM(opcode, shift_t);
10290
10291 break;
10292
10293 default:
10294 return false;
10295 }
10296
10297 // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10298 uint32_t Rm = ReadCoreReg(m, &success);
10299 if (!success)
10300 return false;
10301
10302 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10303 if (!success)
10304 return false;
10305
10306 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10307 uint32_t Rn = ReadCoreReg(n, &success);
10308 if (!success)
10309 return false;
10310
10311 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
10312
10313 // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result);
10314 // // setflags is always FALSE here else
10315 // R[d] = result;
10316 // if setflags then
10317 // APSR.N = result<31>;
10318 // APSR.Z = IsZeroBit(result);
10319 // APSR.C = carry;
10320 // APSR.V = overflow;
10321
10322 EmulateInstruction::Context context;
10323 context.type = eContextArithmetic;
10324 RegisterInfo reg_n;
10325 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10326 RegisterInfo reg_m;
10327 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10328 context.SetRegisterRegisterOperands(reg_n, reg_m);
10329
10330 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10331 res.carry_out, res.overflow))
10332 return false;
10333 }
10334 return true;
10335 }
10336
10337 // A8.6.202 STREX
10338 // Store Register Exclusive calculates an address from a base register value
10339 // and an immediate offset, and stores a word from a register to memory if the
10340 // executing processor has exclusive access to the memory addressed.
EmulateSTREX(const uint32_t opcode,const ARMEncoding encoding)10341 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
10342 const ARMEncoding encoding) {
10343 #if 0
10344 if ConditionPassed() then
10345 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10346 address = R[n] + imm32;
10347 if ExclusiveMonitorsPass(address,4) then
10348 MemA[address,4] = R[t];
10349 R[d] = 0;
10350 else
10351 R[d] = 1;
10352 #endif
10353
10354 bool success = false;
10355
10356 if (ConditionPassed(opcode)) {
10357 uint32_t d;
10358 uint32_t t;
10359 uint32_t n;
10360 uint32_t imm32;
10361 const uint32_t addr_byte_size = GetAddressByteSize();
10362
10363 switch (encoding) {
10364 case eEncodingT1:
10365 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 =
10366 // ZeroExtend(imm8:'00',
10367 // 32);
10368 d = Bits32(opcode, 11, 8);
10369 t = Bits32(opcode, 15, 12);
10370 n = Bits32(opcode, 19, 16);
10371 imm32 = Bits32(opcode, 7, 0) << 2;
10372
10373 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
10374 if (BadReg(d) || BadReg(t) || (n == 15))
10375 return false;
10376
10377 // if d == n || d == t then UNPREDICTABLE;
10378 if ((d == n) || (d == t))
10379 return false;
10380
10381 break;
10382
10383 case eEncodingA1:
10384 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
10385 // offset
10386 d = Bits32(opcode, 15, 12);
10387 t = Bits32(opcode, 3, 0);
10388 n = Bits32(opcode, 19, 16);
10389 imm32 = 0;
10390
10391 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
10392 if ((d == 15) || (t == 15) || (n == 15))
10393 return false;
10394
10395 // if d == n || d == t then UNPREDICTABLE;
10396 if ((d == n) || (d == t))
10397 return false;
10398
10399 break;
10400
10401 default:
10402 return false;
10403 }
10404
10405 // address = R[n] + imm32;
10406 uint32_t Rn = ReadCoreReg(n, &success);
10407 if (!success)
10408 return false;
10409
10410 addr_t address = Rn + imm32;
10411
10412 RegisterInfo base_reg;
10413 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10414 RegisterInfo data_reg;
10415 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10416 EmulateInstruction::Context context;
10417 context.type = eContextRegisterStore;
10418 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32);
10419
10420 // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass
10421 // (address, addr_byte_size)) -- For now, for the sake of emulation, we
10422 // will say this
10423 // always return
10424 // true.
10425 if (true) {
10426 // MemA[address,4] = R[t];
10427 uint32_t Rt =
10428 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
10429 if (!success)
10430 return false;
10431
10432 if (!MemAWrite(context, address, Rt, addr_byte_size))
10433 return false;
10434
10435 // R[d] = 0;
10436 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
10437 return false;
10438 }
10439 #if 0 // unreachable because if true
10440 else
10441 {
10442 // R[d] = 1;
10443 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
10444 return false;
10445 }
10446 #endif // unreachable because if true
10447 }
10448 return true;
10449 }
10450
10451 // A8.6.197 STRB (immediate, ARM)
EmulateSTRBImmARM(const uint32_t opcode,const ARMEncoding encoding)10452 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
10453 const ARMEncoding encoding) {
10454 #if 0
10455 if ConditionPassed() then
10456 EncodingSpecificOperations();
10457 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10458 address = if index then offset_addr else R[n];
10459 MemU[address,1] = R[t]<7:0>;
10460 if wback then R[n] = offset_addr;
10461 #endif
10462
10463 bool success = false;
10464
10465 if (ConditionPassed(opcode)) {
10466 uint32_t t;
10467 uint32_t n;
10468 uint32_t imm32;
10469 bool index;
10470 bool add;
10471 bool wback;
10472
10473 switch (encoding) {
10474 case eEncodingA1:
10475 // if P == '0' && W == '1' then SEE STRBT;
10476 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10477 t = Bits32(opcode, 15, 12);
10478 n = Bits32(opcode, 19, 16);
10479 imm32 = Bits32(opcode, 11, 0);
10480
10481 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10482 index = BitIsSet(opcode, 24);
10483 add = BitIsSet(opcode, 23);
10484 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10485
10486 // if t == 15 then UNPREDICTABLE;
10487 if (t == 15)
10488 return false;
10489
10490 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10491 if (wback && ((n == 15) || (n == t)))
10492 return false;
10493
10494 break;
10495
10496 default:
10497 return false;
10498 }
10499
10500 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10501 uint32_t Rn = ReadCoreReg(n, &success);
10502 if (!success)
10503 return false;
10504
10505 addr_t offset_addr;
10506 if (add)
10507 offset_addr = Rn + imm32;
10508 else
10509 offset_addr = Rn - imm32;
10510
10511 // address = if index then offset_addr else R[n];
10512 addr_t address;
10513 if (index)
10514 address = offset_addr;
10515 else
10516 address = Rn;
10517
10518 // MemU[address,1] = R[t]<7:0>;
10519 uint32_t Rt = ReadCoreReg(t, &success);
10520 if (!success)
10521 return false;
10522
10523 RegisterInfo base_reg;
10524 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10525 RegisterInfo data_reg;
10526 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10527 EmulateInstruction::Context context;
10528 context.type = eContextRegisterStore;
10529 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10530
10531 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
10532 return false;
10533
10534 // if wback then R[n] = offset_addr;
10535 if (wback) {
10536 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10537 offset_addr))
10538 return false;
10539 }
10540 }
10541 return true;
10542 }
10543
10544 // A8.6.194 STR (immediate, ARM)
EmulateSTRImmARM(const uint32_t opcode,const ARMEncoding encoding)10545 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
10546 const ARMEncoding encoding) {
10547 #if 0
10548 if ConditionPassed() then
10549 EncodingSpecificOperations();
10550 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10551 address = if index then offset_addr else R[n];
10552 MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10553 if wback then R[n] = offset_addr;
10554 #endif
10555
10556 bool success = false;
10557
10558 if (ConditionPassed(opcode)) {
10559 uint32_t t;
10560 uint32_t n;
10561 uint32_t imm32;
10562 bool index;
10563 bool add;
10564 bool wback;
10565
10566 const uint32_t addr_byte_size = GetAddressByteSize();
10567
10568 switch (encoding) {
10569 case eEncodingA1:
10570 // if P == '0' && W == '1' then SEE STRT;
10571 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
10572 // '000000000100' then SEE PUSH;
10573 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10574 t = Bits32(opcode, 15, 12);
10575 n = Bits32(opcode, 19, 16);
10576 imm32 = Bits32(opcode, 11, 0);
10577
10578 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10579 index = BitIsSet(opcode, 24);
10580 add = BitIsSet(opcode, 23);
10581 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10582
10583 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10584 if (wback && ((n == 15) || (n == t)))
10585 return false;
10586
10587 break;
10588
10589 default:
10590 return false;
10591 }
10592
10593 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10594 uint32_t Rn = ReadCoreReg(n, &success);
10595 if (!success)
10596 return false;
10597
10598 addr_t offset_addr;
10599 if (add)
10600 offset_addr = Rn + imm32;
10601 else
10602 offset_addr = Rn - imm32;
10603
10604 // address = if index then offset_addr else R[n];
10605 addr_t address;
10606 if (index)
10607 address = offset_addr;
10608 else
10609 address = Rn;
10610
10611 RegisterInfo base_reg;
10612 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10613 RegisterInfo data_reg;
10614 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10615 EmulateInstruction::Context context;
10616 context.type = eContextRegisterStore;
10617 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10618
10619 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10620 uint32_t Rt = ReadCoreReg(t, &success);
10621 if (!success)
10622 return false;
10623
10624 if (t == 15) {
10625 uint32_t pc_value = ReadCoreReg(PC_REG, &success);
10626 if (!success)
10627 return false;
10628
10629 if (!MemUWrite(context, address, pc_value, addr_byte_size))
10630 return false;
10631 } else {
10632 if (!MemUWrite(context, address, Rt, addr_byte_size))
10633 return false;
10634 }
10635
10636 // if wback then R[n] = offset_addr;
10637 if (wback) {
10638 context.type = eContextAdjustBaseRegister;
10639 context.SetImmediate(offset_addr);
10640
10641 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10642 offset_addr))
10643 return false;
10644 }
10645 }
10646 return true;
10647 }
10648
10649 // A8.6.66 LDRD (immediate)
10650 // Load Register Dual (immediate) calculates an address from a base register
10651 // value and an immediate offset, loads two words from memory, and writes them
10652 // to two registers. It can use offset, post-indexed, or pre-indexed
10653 // addressing.
EmulateLDRDImmediate(const uint32_t opcode,const ARMEncoding encoding)10654 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
10655 const ARMEncoding encoding) {
10656 #if 0
10657 if ConditionPassed() then
10658 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10659 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10660 address = if index then offset_addr else R[n];
10661 R[t] = MemA[address,4];
10662 R[t2] = MemA[address+4,4];
10663 if wback then R[n] = offset_addr;
10664 #endif
10665
10666 bool success = false;
10667
10668 if (ConditionPassed(opcode)) {
10669 uint32_t t;
10670 uint32_t t2;
10671 uint32_t n;
10672 uint32_t imm32;
10673 bool index;
10674 bool add;
10675 bool wback;
10676
10677 switch (encoding) {
10678 case eEncodingT1:
10679 // if P == '0' && W == '0' then SEE 'Related encodings';
10680 // if Rn == '1111' then SEE LDRD (literal);
10681 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10682 // ZeroExtend(imm8:'00', 32);
10683 t = Bits32(opcode, 15, 12);
10684 t2 = Bits32(opcode, 11, 8);
10685 n = Bits32(opcode, 19, 16);
10686 imm32 = Bits32(opcode, 7, 0) << 2;
10687
10688 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10689 index = BitIsSet(opcode, 24);
10690 add = BitIsSet(opcode, 23);
10691 wback = BitIsSet(opcode, 21);
10692
10693 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10694 if (wback && ((n == t) || (n == t2)))
10695 return false;
10696
10697 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10698 if (BadReg(t) || BadReg(t2) || (t == t2))
10699 return false;
10700
10701 break;
10702
10703 case eEncodingA1:
10704 // if Rn == '1111' then SEE LDRD (literal);
10705 // if Rt<0> == '1' then UNPREDICTABLE;
10706 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10707 // 32);
10708 t = Bits32(opcode, 15, 12);
10709 if (BitIsSet(t, 0))
10710 return false;
10711 t2 = t + 1;
10712 n = Bits32(opcode, 19, 16);
10713 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10714
10715 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10716 index = BitIsSet(opcode, 24);
10717 add = BitIsSet(opcode, 23);
10718 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10719
10720 // if P == '0' && W == '1' then UNPREDICTABLE;
10721 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10722 return false;
10723
10724 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10725 if (wback && ((n == t) || (n == t2)))
10726 return false;
10727
10728 // if t2 == 15 then UNPREDICTABLE;
10729 if (t2 == 15)
10730 return false;
10731
10732 break;
10733
10734 default:
10735 return false;
10736 }
10737
10738 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10739 uint32_t Rn = ReadCoreReg(n, &success);
10740 if (!success)
10741 return false;
10742
10743 addr_t offset_addr;
10744 if (add)
10745 offset_addr = Rn + imm32;
10746 else
10747 offset_addr = Rn - imm32;
10748
10749 // address = if index then offset_addr else R[n];
10750 addr_t address;
10751 if (index)
10752 address = offset_addr;
10753 else
10754 address = Rn;
10755
10756 // R[t] = MemA[address,4];
10757 RegisterInfo base_reg;
10758 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10759
10760 EmulateInstruction::Context context;
10761 if (n == 13)
10762 context.type = eContextPopRegisterOffStack;
10763 else
10764 context.type = eContextRegisterLoad;
10765 context.SetAddress(address);
10766
10767 const uint32_t addr_byte_size = GetAddressByteSize();
10768 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10769 if (!success)
10770 return false;
10771
10772 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10773 return false;
10774
10775 // R[t2] = MemA[address+4,4];
10776 context.SetAddress(address + 4);
10777 data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10778 if (!success)
10779 return false;
10780
10781 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10782 data))
10783 return false;
10784
10785 // if wback then R[n] = offset_addr;
10786 if (wback) {
10787 context.type = eContextAdjustBaseRegister;
10788 context.SetAddress(offset_addr);
10789
10790 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10791 offset_addr))
10792 return false;
10793 }
10794 }
10795 return true;
10796 }
10797
10798 // A8.6.68 LDRD (register)
10799 // Load Register Dual (register) calculates an address from a base register
10800 // value and a register offset, loads two words from memory, and writes them to
10801 // two registers. It can use offset, post-indexed or pre-indexed addressing.
EmulateLDRDRegister(const uint32_t opcode,const ARMEncoding encoding)10802 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
10803 const ARMEncoding encoding) {
10804 #if 0
10805 if ConditionPassed() then
10806 EncodingSpecificOperations();
10807 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10808 address = if index then offset_addr else R[n];
10809 R[t] = MemA[address,4];
10810 R[t2] = MemA[address+4,4];
10811 if wback then R[n] = offset_addr;
10812 #endif
10813
10814 bool success = false;
10815
10816 if (ConditionPassed(opcode)) {
10817 uint32_t t;
10818 uint32_t t2;
10819 uint32_t n;
10820 uint32_t m;
10821 bool index;
10822 bool add;
10823 bool wback;
10824
10825 switch (encoding) {
10826 case eEncodingA1:
10827 // if Rt<0> == '1' then UNPREDICTABLE;
10828 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10829 t = Bits32(opcode, 15, 12);
10830 if (BitIsSet(t, 0))
10831 return false;
10832 t2 = t + 1;
10833 n = Bits32(opcode, 19, 16);
10834 m = Bits32(opcode, 3, 0);
10835
10836 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10837 index = BitIsSet(opcode, 24);
10838 add = BitIsSet(opcode, 23);
10839 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10840
10841 // if P == '0' && W == '1' then UNPREDICTABLE;
10842 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10843 return false;
10844
10845 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10846 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10847 return false;
10848
10849 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10850 if (wback && ((n == 15) || (n == t) || (n == t2)))
10851 return false;
10852
10853 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10854 if ((ArchVersion() < 6) && wback && (m == n))
10855 return false;
10856 break;
10857
10858 default:
10859 return false;
10860 }
10861
10862 uint32_t Rn = ReadCoreReg(n, &success);
10863 if (!success)
10864 return false;
10865 RegisterInfo base_reg;
10866 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10867
10868 uint32_t Rm = ReadCoreReg(m, &success);
10869 if (!success)
10870 return false;
10871 RegisterInfo offset_reg;
10872 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10873
10874 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10875 addr_t offset_addr;
10876 if (add)
10877 offset_addr = Rn + Rm;
10878 else
10879 offset_addr = Rn - Rm;
10880
10881 // address = if index then offset_addr else R[n];
10882 addr_t address;
10883 if (index)
10884 address = offset_addr;
10885 else
10886 address = Rn;
10887
10888 EmulateInstruction::Context context;
10889 if (n == 13)
10890 context.type = eContextPopRegisterOffStack;
10891 else
10892 context.type = eContextRegisterLoad;
10893 context.SetAddress(address);
10894
10895 // R[t] = MemA[address,4];
10896 const uint32_t addr_byte_size = GetAddressByteSize();
10897 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10898 if (!success)
10899 return false;
10900
10901 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10902 return false;
10903
10904 // R[t2] = MemA[address+4,4];
10905
10906 data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10907 if (!success)
10908 return false;
10909
10910 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10911 data))
10912 return false;
10913
10914 // if wback then R[n] = offset_addr;
10915 if (wback) {
10916 context.type = eContextAdjustBaseRegister;
10917 context.SetAddress(offset_addr);
10918
10919 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10920 offset_addr))
10921 return false;
10922 }
10923 }
10924 return true;
10925 }
10926
10927 // A8.6.200 STRD (immediate)
10928 // Store Register Dual (immediate) calculates an address from a base register
10929 // value and an immediate offset, and stores two words from two registers to
10930 // memory. It can use offset, post-indexed, or pre-indexed addressing.
EmulateSTRDImm(const uint32_t opcode,const ARMEncoding encoding)10931 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
10932 const ARMEncoding encoding) {
10933 #if 0
10934 if ConditionPassed() then
10935 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10936 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10937 address = if index then offset_addr else R[n];
10938 MemA[address,4] = R[t];
10939 MemA[address+4,4] = R[t2];
10940 if wback then R[n] = offset_addr;
10941 #endif
10942
10943 bool success = false;
10944
10945 if (ConditionPassed(opcode)) {
10946 uint32_t t;
10947 uint32_t t2;
10948 uint32_t n;
10949 uint32_t imm32;
10950 bool index;
10951 bool add;
10952 bool wback;
10953
10954 switch (encoding) {
10955 case eEncodingT1:
10956 // if P == '0' && W == '0' then SEE 'Related encodings';
10957 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10958 // ZeroExtend(imm8:'00', 32);
10959 t = Bits32(opcode, 15, 12);
10960 t2 = Bits32(opcode, 11, 8);
10961 n = Bits32(opcode, 19, 16);
10962 imm32 = Bits32(opcode, 7, 0) << 2;
10963
10964 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10965 index = BitIsSet(opcode, 24);
10966 add = BitIsSet(opcode, 23);
10967 wback = BitIsSet(opcode, 21);
10968
10969 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10970 if (wback && ((n == t) || (n == t2)))
10971 return false;
10972
10973 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10974 if ((n == 15) || BadReg(t) || BadReg(t2))
10975 return false;
10976
10977 break;
10978
10979 case eEncodingA1:
10980 // if Rt<0> == '1' then UNPREDICTABLE;
10981 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10982 // 32);
10983 t = Bits32(opcode, 15, 12);
10984 if (BitIsSet(t, 0))
10985 return false;
10986
10987 t2 = t + 1;
10988 n = Bits32(opcode, 19, 16);
10989 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10990
10991 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10992 index = BitIsSet(opcode, 24);
10993 add = BitIsSet(opcode, 23);
10994 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10995
10996 // if P == '0' && W == '1' then UNPREDICTABLE;
10997 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10998 return false;
10999
11000 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11001 if (wback && ((n == 15) || (n == t) || (n == t2)))
11002 return false;
11003
11004 // if t2 == 15 then UNPREDICTABLE;
11005 if (t2 == 15)
11006 return false;
11007
11008 break;
11009
11010 default:
11011 return false;
11012 }
11013
11014 RegisterInfo base_reg;
11015 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11016
11017 uint32_t Rn = ReadCoreReg(n, &success);
11018 if (!success)
11019 return false;
11020
11021 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
11022 addr_t offset_addr;
11023 if (add)
11024 offset_addr = Rn + imm32;
11025 else
11026 offset_addr = Rn - imm32;
11027
11028 // address = if index then offset_addr else R[n];
11029 addr_t address;
11030 if (index)
11031 address = offset_addr;
11032 else
11033 address = Rn;
11034
11035 // MemA[address,4] = R[t];
11036 RegisterInfo data_reg;
11037 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11038
11039 uint32_t data = ReadCoreReg(t, &success);
11040 if (!success)
11041 return false;
11042
11043 EmulateInstruction::Context context;
11044 if (n == 13)
11045 context.type = eContextPushRegisterOnStack;
11046 else
11047 context.type = eContextRegisterStore;
11048 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11049
11050 const uint32_t addr_byte_size = GetAddressByteSize();
11051
11052 if (!MemAWrite(context, address, data, addr_byte_size))
11053 return false;
11054
11055 // MemA[address+4,4] = R[t2];
11056 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11057 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11058 (address + 4) - Rn);
11059
11060 data = ReadCoreReg(t2, &success);
11061 if (!success)
11062 return false;
11063
11064 if (!MemAWrite(context, address + 4, data, addr_byte_size))
11065 return false;
11066
11067 // if wback then R[n] = offset_addr;
11068 if (wback) {
11069 if (n == 13)
11070 context.type = eContextAdjustStackPointer;
11071 else
11072 context.type = eContextAdjustBaseRegister;
11073 context.SetAddress(offset_addr);
11074
11075 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11076 offset_addr))
11077 return false;
11078 }
11079 }
11080 return true;
11081 }
11082
11083 // A8.6.201 STRD (register)
EmulateSTRDReg(const uint32_t opcode,const ARMEncoding encoding)11084 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
11085 const ARMEncoding encoding) {
11086 #if 0
11087 if ConditionPassed() then
11088 EncodingSpecificOperations();
11089 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11090 address = if index then offset_addr else R[n];
11091 MemA[address,4] = R[t];
11092 MemA[address+4,4] = R[t2];
11093 if wback then R[n] = offset_addr;
11094 #endif
11095
11096 bool success = false;
11097
11098 if (ConditionPassed(opcode)) {
11099 uint32_t t;
11100 uint32_t t2;
11101 uint32_t n;
11102 uint32_t m;
11103 bool index;
11104 bool add;
11105 bool wback;
11106
11107 switch (encoding) {
11108 case eEncodingA1:
11109 // if Rt<0> == '1' then UNPREDICTABLE;
11110 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
11111 t = Bits32(opcode, 15, 12);
11112 if (BitIsSet(t, 0))
11113 return false;
11114
11115 t2 = t + 1;
11116 n = Bits32(opcode, 19, 16);
11117 m = Bits32(opcode, 3, 0);
11118
11119 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11120 index = BitIsSet(opcode, 24);
11121 add = BitIsSet(opcode, 23);
11122 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11123
11124 // if P == '0' && W == '1' then UNPREDICTABLE;
11125 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11126 return false;
11127
11128 // if t2 == 15 || m == 15 then UNPREDICTABLE;
11129 if ((t2 == 15) || (m == 15))
11130 return false;
11131
11132 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11133 if (wback && ((n == 15) || (n == t) || (n == t2)))
11134 return false;
11135
11136 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
11137 if ((ArchVersion() < 6) && wback && (m == n))
11138 return false;
11139
11140 break;
11141
11142 default:
11143 return false;
11144 }
11145
11146 RegisterInfo base_reg;
11147 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11148 RegisterInfo offset_reg;
11149 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
11150 RegisterInfo data_reg;
11151
11152 uint32_t Rn = ReadCoreReg(n, &success);
11153 if (!success)
11154 return false;
11155
11156 uint32_t Rm = ReadCoreReg(m, &success);
11157 if (!success)
11158 return false;
11159
11160 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11161 addr_t offset_addr;
11162 if (add)
11163 offset_addr = Rn + Rm;
11164 else
11165 offset_addr = Rn - Rm;
11166
11167 // address = if index then offset_addr else R[n];
11168 addr_t address;
11169 if (index)
11170 address = offset_addr;
11171 else
11172 address = Rn;
11173 // MemA[address,4] = R[t];
11174 uint32_t Rt = ReadCoreReg(t, &success);
11175 if (!success)
11176 return false;
11177
11178 EmulateInstruction::Context context;
11179 if (t == 13)
11180 context.type = eContextPushRegisterOnStack;
11181 else
11182 context.type = eContextRegisterStore;
11183
11184 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11185 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11186 data_reg);
11187
11188 const uint32_t addr_byte_size = GetAddressByteSize();
11189
11190 if (!MemAWrite(context, address, Rt, addr_byte_size))
11191 return false;
11192
11193 // MemA[address+4,4] = R[t2];
11194 uint32_t Rt2 = ReadCoreReg(t2, &success);
11195 if (!success)
11196 return false;
11197
11198 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11199
11200 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11201 data_reg);
11202
11203 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
11204 return false;
11205
11206 // if wback then R[n] = offset_addr;
11207 if (wback) {
11208 context.type = eContextAdjustBaseRegister;
11209 context.SetAddress(offset_addr);
11210
11211 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11212 offset_addr))
11213 return false;
11214 }
11215 }
11216 return true;
11217 }
11218
11219 // A8.6.319 VLDM
11220 // Vector Load Multiple loads multiple extension registers from consecutive
11221 // memory locations using an address from an ARM core register.
EmulateVLDM(const uint32_t opcode,const ARMEncoding encoding)11222 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
11223 const ARMEncoding encoding) {
11224 #if 0
11225 if ConditionPassed() then
11226 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11227 address = if add then R[n] else R[n]-imm32;
11228 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11229 for r = 0 to regs-1
11230 if single_regs then
11231 S[d+r] = MemA[address,4]; address = address+4;
11232 else
11233 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
11234 // Combine the word-aligned words in the correct order for
11235 // current endianness.
11236 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11237 #endif
11238
11239 bool success = false;
11240
11241 if (ConditionPassed(opcode)) {
11242 bool single_regs;
11243 bool add;
11244 bool wback;
11245 uint32_t d;
11246 uint32_t n;
11247 uint32_t imm32;
11248 uint32_t regs;
11249
11250 switch (encoding) {
11251 case eEncodingT1:
11252 case eEncodingA1:
11253 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11254 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11255 // if P == '1' && W == '0' then SEE VLDR;
11256 // if P == U && W == '1' then UNDEFINED;
11257 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11258 return false;
11259
11260 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11261 // !), 101 (DB with !)
11262 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11263 single_regs = false;
11264 add = BitIsSet(opcode, 23);
11265 wback = BitIsSet(opcode, 21);
11266
11267 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11268 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11269 n = Bits32(opcode, 19, 16);
11270 imm32 = Bits32(opcode, 7, 0) << 2;
11271
11272 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
11273 regs = Bits32(opcode, 7, 0) / 2;
11274
11275 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11276 // UNPREDICTABLE;
11277 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
11278 return false;
11279
11280 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11281 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11282 return false;
11283
11284 break;
11285
11286 case eEncodingT2:
11287 case eEncodingA2:
11288 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11289 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11290 // if P == '1' && W == '0' then SEE VLDR;
11291 // if P == U && W == '1' then UNDEFINED;
11292 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11293 return false;
11294
11295 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11296 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11297 // == '1'); d =
11298 // UInt(Vd:D); n = UInt(Rn);
11299 single_regs = true;
11300 add = BitIsSet(opcode, 23);
11301 wback = BitIsSet(opcode, 21);
11302 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11303 n = Bits32(opcode, 19, 16);
11304
11305 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11306 imm32 = Bits32(opcode, 7, 0) << 2;
11307 regs = Bits32(opcode, 7, 0);
11308
11309 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11310 // UNPREDICTABLE;
11311 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11312 return false;
11313
11314 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11315 if ((regs == 0) || ((d + regs) > 32))
11316 return false;
11317 break;
11318
11319 default:
11320 return false;
11321 }
11322
11323 RegisterInfo base_reg;
11324 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11325
11326 uint32_t Rn = ReadCoreReg(n, &success);
11327 if (!success)
11328 return false;
11329
11330 // address = if add then R[n] else R[n]-imm32;
11331 addr_t address;
11332 if (add)
11333 address = Rn;
11334 else
11335 address = Rn - imm32;
11336
11337 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11338 EmulateInstruction::Context context;
11339
11340 if (wback) {
11341 uint32_t value;
11342 if (add)
11343 value = Rn + imm32;
11344 else
11345 value = Rn - imm32;
11346
11347 context.type = eContextAdjustBaseRegister;
11348 context.SetImmediateSigned(value - Rn);
11349 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11350 value))
11351 return false;
11352 }
11353
11354 const uint32_t addr_byte_size = GetAddressByteSize();
11355 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11356
11357 context.type = eContextRegisterLoad;
11358
11359 // for r = 0 to regs-1
11360 for (uint32_t r = 0; r < regs; ++r) {
11361 if (single_regs) {
11362 // S[d+r] = MemA[address,4]; address = address+4;
11363 context.SetRegisterPlusOffset(base_reg, address - Rn);
11364
11365 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11366 if (!success)
11367 return false;
11368
11369 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11370 start_reg + d + r, data))
11371 return false;
11372
11373 address = address + 4;
11374 } else {
11375 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
11376 // address+8;
11377 context.SetRegisterPlusOffset(base_reg, address - Rn);
11378 uint32_t word1 =
11379 MemARead(context, address, addr_byte_size, 0, &success);
11380 if (!success)
11381 return false;
11382
11383 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn);
11384 uint32_t word2 =
11385 MemARead(context, address + 4, addr_byte_size, 0, &success);
11386 if (!success)
11387 return false;
11388
11389 address = address + 8;
11390 // // Combine the word-aligned words in the correct order for current
11391 // endianness.
11392 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11393 uint64_t data;
11394 if (GetByteOrder() == eByteOrderBig) {
11395 data = word1;
11396 data = (data << 32) | word2;
11397 } else {
11398 data = word2;
11399 data = (data << 32) | word1;
11400 }
11401
11402 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11403 start_reg + d + r, data))
11404 return false;
11405 }
11406 }
11407 }
11408 return true;
11409 }
11410
11411 // A8.6.399 VSTM
11412 // Vector Store Multiple stores multiple extension registers to consecutive
11413 // memory locations using an address from an
11414 // ARM core register.
EmulateVSTM(const uint32_t opcode,const ARMEncoding encoding)11415 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
11416 const ARMEncoding encoding) {
11417 #if 0
11418 if ConditionPassed() then
11419 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11420 address = if add then R[n] else R[n]-imm32;
11421 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11422 for r = 0 to regs-1
11423 if single_regs then
11424 MemA[address,4] = S[d+r]; address = address+4;
11425 else
11426 // Store as two word-aligned words in the correct order for
11427 // current endianness.
11428 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11429 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11430 address = address+8;
11431 #endif
11432
11433 bool success = false;
11434
11435 if (ConditionPassed(opcode)) {
11436 bool single_regs;
11437 bool add;
11438 bool wback;
11439 uint32_t d;
11440 uint32_t n;
11441 uint32_t imm32;
11442 uint32_t regs;
11443
11444 switch (encoding) {
11445 case eEncodingT1:
11446 case eEncodingA1:
11447 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11448 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11449 // if P == '1' && W == '0' then SEE VSTR;
11450 // if P == U && W == '1' then UNDEFINED;
11451 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11452 return false;
11453
11454 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11455 // !), 101 (DB with !)
11456 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11457 single_regs = false;
11458 add = BitIsSet(opcode, 23);
11459 wback = BitIsSet(opcode, 21);
11460
11461 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11462 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11463 n = Bits32(opcode, 19, 16);
11464 imm32 = Bits32(opcode, 7, 0) << 2;
11465
11466 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11467 regs = Bits32(opcode, 7, 0) / 2;
11468
11469 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11470 // UNPREDICTABLE;
11471 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11472 return false;
11473
11474 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11475 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11476 return false;
11477
11478 break;
11479
11480 case eEncodingT2:
11481 case eEncodingA2:
11482 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11483 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11484 // if P == '1' && W == '0' then SEE VSTR;
11485 // if P == U && W == '1' then UNDEFINED;
11486 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11487 return false;
11488
11489 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11490 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11491 // == '1'); d =
11492 // UInt(Vd:D); n = UInt(Rn);
11493 single_regs = true;
11494 add = BitIsSet(opcode, 23);
11495 wback = BitIsSet(opcode, 21);
11496 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11497 n = Bits32(opcode, 19, 16);
11498
11499 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11500 imm32 = Bits32(opcode, 7, 0) << 2;
11501 regs = Bits32(opcode, 7, 0);
11502
11503 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11504 // UNPREDICTABLE;
11505 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11506 return false;
11507
11508 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11509 if ((regs == 0) || ((d + regs) > 32))
11510 return false;
11511
11512 break;
11513
11514 default:
11515 return false;
11516 }
11517
11518 RegisterInfo base_reg;
11519 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11520
11521 uint32_t Rn = ReadCoreReg(n, &success);
11522 if (!success)
11523 return false;
11524
11525 // address = if add then R[n] else R[n]-imm32;
11526 addr_t address;
11527 if (add)
11528 address = Rn;
11529 else
11530 address = Rn - imm32;
11531
11532 EmulateInstruction::Context context;
11533 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11534 if (wback) {
11535 uint32_t value;
11536 if (add)
11537 value = Rn + imm32;
11538 else
11539 value = Rn - imm32;
11540
11541 context.type = eContextAdjustBaseRegister;
11542 context.SetRegisterPlusOffset(base_reg, value - Rn);
11543
11544 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11545 value))
11546 return false;
11547 }
11548
11549 const uint32_t addr_byte_size = GetAddressByteSize();
11550 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11551
11552 context.type = eContextRegisterStore;
11553 // for r = 0 to regs-1
11554 for (uint32_t r = 0; r < regs; ++r) {
11555
11556 if (single_regs) {
11557 // MemA[address,4] = S[d+r]; address = address+4;
11558 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11559 start_reg + d + r, 0, &success);
11560 if (!success)
11561 return false;
11562
11563 RegisterInfo data_reg;
11564 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11565 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11566 address - Rn);
11567 if (!MemAWrite(context, address, data, addr_byte_size))
11568 return false;
11569
11570 address = address + 4;
11571 } else {
11572 // // Store as two word-aligned words in the correct order for current
11573 // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
11574 // D[d+r]<31:0>;
11575 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
11576 // D[d+r]<63:32>;
11577 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11578 start_reg + d + r, 0, &success);
11579 if (!success)
11580 return false;
11581
11582 RegisterInfo data_reg;
11583 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11584
11585 if (GetByteOrder() == eByteOrderBig) {
11586 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11587 address - Rn);
11588 if (!MemAWrite(context, address, Bits64(data, 63, 32),
11589 addr_byte_size))
11590 return false;
11591
11592 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11593 (address + 4) - Rn);
11594 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11595 addr_byte_size))
11596 return false;
11597 } else {
11598 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11599 address - Rn);
11600 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11601 return false;
11602
11603 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11604 (address + 4) - Rn);
11605 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11606 addr_byte_size))
11607 return false;
11608 }
11609 // address = address+8;
11610 address = address + 8;
11611 }
11612 }
11613 }
11614 return true;
11615 }
11616
11617 // A8.6.320
11618 // This instruction loads a single extension register from memory, using an
11619 // address from an ARM core register, with an optional offset.
EmulateVLDR(const uint32_t opcode,ARMEncoding encoding)11620 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
11621 ARMEncoding encoding) {
11622 #if 0
11623 if ConditionPassed() then
11624 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11625 base = if n == 15 then Align(PC,4) else R[n];
11626 address = if add then (base + imm32) else (base - imm32);
11627 if single_reg then
11628 S[d] = MemA[address,4];
11629 else
11630 word1 = MemA[address,4]; word2 = MemA[address+4,4];
11631 // Combine the word-aligned words in the correct order for current
11632 // endianness.
11633 D[d] = if BigEndian() then word1:word2 else word2:word1;
11634 #endif
11635
11636 bool success = false;
11637
11638 if (ConditionPassed(opcode)) {
11639 bool single_reg;
11640 bool add;
11641 uint32_t imm32;
11642 uint32_t d;
11643 uint32_t n;
11644
11645 switch (encoding) {
11646 case eEncodingT1:
11647 case eEncodingA1:
11648 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11649 // 32);
11650 single_reg = false;
11651 add = BitIsSet(opcode, 23);
11652 imm32 = Bits32(opcode, 7, 0) << 2;
11653
11654 // d = UInt(D:Vd); n = UInt(Rn);
11655 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11656 n = Bits32(opcode, 19, 16);
11657
11658 break;
11659
11660 case eEncodingT2:
11661 case eEncodingA2:
11662 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11663 single_reg = true;
11664 add = BitIsSet(opcode, 23);
11665 imm32 = Bits32(opcode, 7, 0) << 2;
11666
11667 // d = UInt(Vd:D); n = UInt(Rn);
11668 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11669 n = Bits32(opcode, 19, 16);
11670
11671 break;
11672
11673 default:
11674 return false;
11675 }
11676 RegisterInfo base_reg;
11677 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11678
11679 uint32_t Rn = ReadCoreReg(n, &success);
11680 if (!success)
11681 return false;
11682
11683 // base = if n == 15 then Align(PC,4) else R[n];
11684 uint32_t base;
11685 if (n == 15)
11686 base = AlignPC(Rn);
11687 else
11688 base = Rn;
11689
11690 // address = if add then (base + imm32) else (base - imm32);
11691 addr_t address;
11692 if (add)
11693 address = base + imm32;
11694 else
11695 address = base - imm32;
11696
11697 const uint32_t addr_byte_size = GetAddressByteSize();
11698 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11699
11700 EmulateInstruction::Context context;
11701 context.type = eContextRegisterLoad;
11702 context.SetRegisterPlusOffset(base_reg, address - base);
11703
11704 if (single_reg) {
11705 // S[d] = MemA[address,4];
11706 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11707 if (!success)
11708 return false;
11709
11710 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11711 data))
11712 return false;
11713 } else {
11714 // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11715 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
11716 if (!success)
11717 return false;
11718
11719 context.SetRegisterPlusOffset(base_reg, (address + 4) - base);
11720 uint32_t word2 =
11721 MemARead(context, address + 4, addr_byte_size, 0, &success);
11722 if (!success)
11723 return false;
11724 // // Combine the word-aligned words in the correct order for current
11725 // endianness.
11726 // D[d] = if BigEndian() then word1:word2 else word2:word1;
11727 uint64_t data64;
11728 if (GetByteOrder() == eByteOrderBig) {
11729 data64 = word1;
11730 data64 = (data64 << 32) | word2;
11731 } else {
11732 data64 = word2;
11733 data64 = (data64 << 32) | word1;
11734 }
11735
11736 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11737 data64))
11738 return false;
11739 }
11740 }
11741 return true;
11742 }
11743
11744 // A8.6.400 VSTR
11745 // This instruction stores a signle extension register to memory, using an
11746 // address from an ARM core register, with an optional offset.
EmulateVSTR(const uint32_t opcode,ARMEncoding encoding)11747 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
11748 ARMEncoding encoding) {
11749 #if 0
11750 if ConditionPassed() then
11751 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11752 address = if add then (R[n] + imm32) else (R[n] - imm32);
11753 if single_reg then
11754 MemA[address,4] = S[d];
11755 else
11756 // Store as two word-aligned words in the correct order for current
11757 // endianness.
11758 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11759 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11760 #endif
11761
11762 bool success = false;
11763
11764 if (ConditionPassed(opcode)) {
11765 bool single_reg;
11766 bool add;
11767 uint32_t imm32;
11768 uint32_t d;
11769 uint32_t n;
11770
11771 switch (encoding) {
11772 case eEncodingT1:
11773 case eEncodingA1:
11774 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11775 // 32);
11776 single_reg = false;
11777 add = BitIsSet(opcode, 23);
11778 imm32 = Bits32(opcode, 7, 0) << 2;
11779
11780 // d = UInt(D:Vd); n = UInt(Rn);
11781 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11782 n = Bits32(opcode, 19, 16);
11783
11784 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11785 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11786 return false;
11787
11788 break;
11789
11790 case eEncodingT2:
11791 case eEncodingA2:
11792 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11793 single_reg = true;
11794 add = BitIsSet(opcode, 23);
11795 imm32 = Bits32(opcode, 7, 0) << 2;
11796
11797 // d = UInt(Vd:D); n = UInt(Rn);
11798 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11799 n = Bits32(opcode, 19, 16);
11800
11801 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11802 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11803 return false;
11804
11805 break;
11806
11807 default:
11808 return false;
11809 }
11810
11811 RegisterInfo base_reg;
11812 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11813
11814 uint32_t Rn = ReadCoreReg(n, &success);
11815 if (!success)
11816 return false;
11817
11818 // address = if add then (R[n] + imm32) else (R[n] - imm32);
11819 addr_t address;
11820 if (add)
11821 address = Rn + imm32;
11822 else
11823 address = Rn - imm32;
11824
11825 const uint32_t addr_byte_size = GetAddressByteSize();
11826 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11827
11828 RegisterInfo data_reg;
11829 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg);
11830 EmulateInstruction::Context context;
11831 context.type = eContextRegisterStore;
11832 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11833
11834 if (single_reg) {
11835 // MemA[address,4] = S[d];
11836 uint32_t data =
11837 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11838 if (!success)
11839 return false;
11840
11841 if (!MemAWrite(context, address, data, addr_byte_size))
11842 return false;
11843 } else {
11844 // // Store as two word-aligned words in the correct order for current
11845 // endianness.
11846 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11847 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11848 uint64_t data =
11849 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11850 if (!success)
11851 return false;
11852
11853 if (GetByteOrder() == eByteOrderBig) {
11854 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
11855 return false;
11856
11857 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11858 (address + 4) - Rn);
11859 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11860 addr_byte_size))
11861 return false;
11862 } else {
11863 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11864 return false;
11865
11866 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11867 (address + 4) - Rn);
11868 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11869 addr_byte_size))
11870 return false;
11871 }
11872 }
11873 }
11874 return true;
11875 }
11876
11877 // A8.6.307 VLDI1 (multiple single elements) This instruction loads elements
11878 // from memory into one, two, three or four registers, without de-interleaving.
11879 // Every element of each register is loaded.
EmulateVLD1Multiple(const uint32_t opcode,ARMEncoding encoding)11880 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
11881 ARMEncoding encoding) {
11882 #if 0
11883 if ConditionPassed() then
11884 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11885 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11886 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11887 for r = 0 to regs-1
11888 for e = 0 to elements-1
11889 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11890 address = address + ebytes;
11891 #endif
11892
11893 bool success = false;
11894
11895 if (ConditionPassed(opcode)) {
11896 uint32_t regs;
11897 uint32_t alignment;
11898 uint32_t ebytes;
11899 uint32_t esize;
11900 uint32_t elements;
11901 uint32_t d;
11902 uint32_t n;
11903 uint32_t m;
11904 bool wback;
11905 bool register_index;
11906
11907 switch (encoding) {
11908 case eEncodingT1:
11909 case eEncodingA1: {
11910 // case type of
11911 // when '0111'
11912 // regs = 1; if align<1> == '1' then UNDEFINED;
11913 // when '1010'
11914 // regs = 2; if align == '11' then UNDEFINED;
11915 // when '0110'
11916 // regs = 3; if align<1> == '1' then UNDEFINED;
11917 // when '0010'
11918 // regs = 4;
11919 // otherwise
11920 // SEE 'Related encodings';
11921 uint32_t type = Bits32(opcode, 11, 8);
11922 uint32_t align = Bits32(opcode, 5, 4);
11923 if (type == 7) // '0111'
11924 {
11925 regs = 1;
11926 if (BitIsSet(align, 1))
11927 return false;
11928 } else if (type == 10) // '1010'
11929 {
11930 regs = 2;
11931 if (align == 3)
11932 return false;
11933
11934 } else if (type == 6) // '0110'
11935 {
11936 regs = 3;
11937 if (BitIsSet(align, 1))
11938 return false;
11939 } else if (type == 2) // '0010'
11940 {
11941 regs = 4;
11942 } else
11943 return false;
11944
11945 // alignment = if align == '00' then 1 else 4 << UInt(align);
11946 if (align == 0)
11947 alignment = 1;
11948 else
11949 alignment = 4 << align;
11950
11951 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11952 ebytes = 1 << Bits32(opcode, 7, 6);
11953 esize = 8 * ebytes;
11954 elements = 8 / ebytes;
11955
11956 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11957 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11958 n = Bits32(opcode, 19, 15);
11959 m = Bits32(opcode, 3, 0);
11960
11961 // wback = (m != 15); register_index = (m != 15 && m != 13);
11962 wback = (m != 15);
11963 register_index = ((m != 15) && (m != 13));
11964
11965 // if d+regs > 32 then UNPREDICTABLE;
11966 if ((d + regs) > 32)
11967 return false;
11968 } break;
11969
11970 default:
11971 return false;
11972 }
11973
11974 RegisterInfo base_reg;
11975 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11976
11977 uint32_t Rn = ReadCoreReg(n, &success);
11978 if (!success)
11979 return false;
11980
11981 // address = R[n]; if (address MOD alignment) != 0 then
11982 // GenerateAlignmentException();
11983 addr_t address = Rn;
11984 if ((address % alignment) != 0)
11985 return false;
11986
11987 EmulateInstruction::Context context;
11988 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11989 if (wback) {
11990 uint32_t Rm = ReadCoreReg(m, &success);
11991 if (!success)
11992 return false;
11993
11994 uint32_t offset;
11995 if (register_index)
11996 offset = Rm;
11997 else
11998 offset = 8 * regs;
11999
12000 uint32_t value = Rn + offset;
12001 context.type = eContextAdjustBaseRegister;
12002 context.SetRegisterPlusOffset(base_reg, offset);
12003
12004 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12005 value))
12006 return false;
12007 }
12008
12009 // for r = 0 to regs-1
12010 for (uint32_t r = 0; r < regs; ++r) {
12011 // for e = 0 to elements-1
12012 uint64_t assembled_data = 0;
12013 for (uint32_t e = 0; e < elements; ++e) {
12014 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
12015 context.type = eContextRegisterLoad;
12016 context.SetRegisterPlusOffset(base_reg, address - Rn);
12017 uint64_t data = MemURead(context, address, ebytes, 0, &success);
12018 if (!success)
12019 return false;
12020
12021 assembled_data =
12022 (data << (e * esize)) |
12023 assembled_data; // New data goes to the left of existing data
12024
12025 // address = address + ebytes;
12026 address = address + ebytes;
12027 }
12028 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12029 assembled_data))
12030 return false;
12031 }
12032 }
12033 return true;
12034 }
12035
12036 // A8.6.308 VLD1 (single element to one lane)
12037 //
EmulateVLD1Single(const uint32_t opcode,const ARMEncoding encoding)12038 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
12039 const ARMEncoding encoding) {
12040 #if 0
12041 if ConditionPassed() then
12042 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12043 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12044 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12045 Elem[D[d],index,esize] = MemU[address,ebytes];
12046 #endif
12047
12048 bool success = false;
12049
12050 if (ConditionPassed(opcode)) {
12051 uint32_t ebytes;
12052 uint32_t esize;
12053 uint32_t index;
12054 uint32_t alignment;
12055 uint32_t d;
12056 uint32_t n;
12057 uint32_t m;
12058 bool wback;
12059 bool register_index;
12060
12061 switch (encoding) {
12062 case eEncodingT1:
12063 case eEncodingA1: {
12064 uint32_t size = Bits32(opcode, 11, 10);
12065 uint32_t index_align = Bits32(opcode, 7, 4);
12066 // if size == '11' then SEE VLD1 (single element to all lanes);
12067 if (size == 3)
12068 return EmulateVLD1SingleAll(opcode, encoding);
12069 // case size of
12070 if (size == 0) // when '00'
12071 {
12072 // if index_align<0> != '0' then UNDEFINED;
12073 if (BitIsClear(index_align, 0))
12074 return false;
12075
12076 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12077 ebytes = 1;
12078 esize = 8;
12079 index = Bits32(index_align, 3, 1);
12080 alignment = 1;
12081 } else if (size == 1) // when '01'
12082 {
12083 // if index_align<1> != '0' then UNDEFINED;
12084 if (BitIsClear(index_align, 1))
12085 return false;
12086
12087 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12088 ebytes = 2;
12089 esize = 16;
12090 index = Bits32(index_align, 3, 2);
12091
12092 // alignment = if index_align<0> == '0' then 1 else 2;
12093 if (BitIsClear(index_align, 0))
12094 alignment = 1;
12095 else
12096 alignment = 2;
12097 } else if (size == 2) // when '10'
12098 {
12099 // if index_align<2> != '0' then UNDEFINED;
12100 if (BitIsClear(index_align, 2))
12101 return false;
12102
12103 // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12104 // UNDEFINED;
12105 if ((Bits32(index_align, 1, 0) != 0) &&
12106 (Bits32(index_align, 1, 0) != 3))
12107 return false;
12108
12109 // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12110 ebytes = 4;
12111 esize = 32;
12112 index = Bit32(index_align, 3);
12113
12114 // alignment = if index_align<1:0> == '00' then 1 else 4;
12115 if (Bits32(index_align, 1, 0) == 0)
12116 alignment = 1;
12117 else
12118 alignment = 4;
12119 } else {
12120 return false;
12121 }
12122 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12123 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12124 n = Bits32(opcode, 19, 16);
12125 m = Bits32(opcode, 3, 0);
12126
12127 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12128 // then UNPREDICTABLE;
12129 wback = (m != 15);
12130 register_index = ((m != 15) && (m != 13));
12131
12132 if (n == 15)
12133 return false;
12134
12135 } break;
12136
12137 default:
12138 return false;
12139 }
12140
12141 RegisterInfo base_reg;
12142 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12143
12144 uint32_t Rn = ReadCoreReg(n, &success);
12145 if (!success)
12146 return false;
12147
12148 // address = R[n]; if (address MOD alignment) != 0 then
12149 // GenerateAlignmentException();
12150 addr_t address = Rn;
12151 if ((address % alignment) != 0)
12152 return false;
12153
12154 EmulateInstruction::Context context;
12155 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12156 if (wback) {
12157 uint32_t Rm = ReadCoreReg(m, &success);
12158 if (!success)
12159 return false;
12160
12161 uint32_t offset;
12162 if (register_index)
12163 offset = Rm;
12164 else
12165 offset = ebytes;
12166
12167 uint32_t value = Rn + offset;
12168
12169 context.type = eContextAdjustBaseRegister;
12170 context.SetRegisterPlusOffset(base_reg, offset);
12171
12172 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12173 value))
12174 return false;
12175 }
12176
12177 // Elem[D[d],index,esize] = MemU[address,ebytes];
12178 uint32_t element = MemURead(context, address, esize, 0, &success);
12179 if (!success)
12180 return false;
12181
12182 element = element << (index * esize);
12183
12184 uint64_t reg_data =
12185 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12186 if (!success)
12187 return false;
12188
12189 uint64_t all_ones = -1;
12190 uint64_t mask = all_ones
12191 << ((index + 1) * esize); // mask is all 1's to left of
12192 // where 'element' goes, & all 0's
12193 // at element & to the right of element.
12194 if (index > 0)
12195 mask = mask | Bits64(all_ones, (index * esize) - 1,
12196 0); // add 1's to the right of where 'element' goes.
12197 // now mask should be 0's where element goes & 1's everywhere else.
12198
12199 uint64_t masked_reg =
12200 reg_data & mask; // Take original reg value & zero out 'element' bits
12201 reg_data =
12202 masked_reg & element; // Put 'element' into those bits in reg_data.
12203
12204 context.type = eContextRegisterLoad;
12205 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
12206 reg_data))
12207 return false;
12208 }
12209 return true;
12210 }
12211
12212 // A8.6.391 VST1 (multiple single elements) Vector Store (multiple single
12213 // elements) stores elements to memory from one, two, three, or four registers,
12214 // without interleaving. Every element of each register is stored.
EmulateVST1Multiple(const uint32_t opcode,ARMEncoding encoding)12215 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
12216 ARMEncoding encoding) {
12217 #if 0
12218 if ConditionPassed() then
12219 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12220 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12221 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12222 for r = 0 to regs-1
12223 for e = 0 to elements-1
12224 MemU[address,ebytes] = Elem[D[d+r],e,esize];
12225 address = address + ebytes;
12226 #endif
12227
12228 bool success = false;
12229
12230 if (ConditionPassed(opcode)) {
12231 uint32_t regs;
12232 uint32_t alignment;
12233 uint32_t ebytes;
12234 uint32_t esize;
12235 uint32_t elements;
12236 uint32_t d;
12237 uint32_t n;
12238 uint32_t m;
12239 bool wback;
12240 bool register_index;
12241
12242 switch (encoding) {
12243 case eEncodingT1:
12244 case eEncodingA1: {
12245 uint32_t type = Bits32(opcode, 11, 8);
12246 uint32_t align = Bits32(opcode, 5, 4);
12247
12248 // case type of
12249 if (type == 7) // when '0111'
12250 {
12251 // regs = 1; if align<1> == '1' then UNDEFINED;
12252 regs = 1;
12253 if (BitIsSet(align, 1))
12254 return false;
12255 } else if (type == 10) // when '1010'
12256 {
12257 // regs = 2; if align == '11' then UNDEFINED;
12258 regs = 2;
12259 if (align == 3)
12260 return false;
12261 } else if (type == 6) // when '0110'
12262 {
12263 // regs = 3; if align<1> == '1' then UNDEFINED;
12264 regs = 3;
12265 if (BitIsSet(align, 1))
12266 return false;
12267 } else if (type == 2) // when '0010'
12268 // regs = 4;
12269 regs = 4;
12270 else // otherwise
12271 // SEE 'Related encodings';
12272 return false;
12273
12274 // alignment = if align == '00' then 1 else 4 << UInt(align);
12275 if (align == 0)
12276 alignment = 1;
12277 else
12278 alignment = 4 << align;
12279
12280 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
12281 ebytes = 1 << Bits32(opcode, 7, 6);
12282 esize = 8 * ebytes;
12283 elements = 8 / ebytes;
12284
12285 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12286 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12287 n = Bits32(opcode, 19, 16);
12288 m = Bits32(opcode, 3, 0);
12289
12290 // wback = (m != 15); register_index = (m != 15 && m != 13);
12291 wback = (m != 15);
12292 register_index = ((m != 15) && (m != 13));
12293
12294 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12295 if ((d + regs) > 32)
12296 return false;
12297
12298 if (n == 15)
12299 return false;
12300
12301 } break;
12302
12303 default:
12304 return false;
12305 }
12306
12307 RegisterInfo base_reg;
12308 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12309
12310 uint32_t Rn = ReadCoreReg(n, &success);
12311 if (!success)
12312 return false;
12313
12314 // address = R[n]; if (address MOD alignment) != 0 then
12315 // GenerateAlignmentException();
12316 addr_t address = Rn;
12317 if ((address % alignment) != 0)
12318 return false;
12319
12320 EmulateInstruction::Context context;
12321 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12322 if (wback) {
12323 uint32_t Rm = ReadCoreReg(m, &success);
12324 if (!success)
12325 return false;
12326
12327 uint32_t offset;
12328 if (register_index)
12329 offset = Rm;
12330 else
12331 offset = 8 * regs;
12332
12333 context.type = eContextAdjustBaseRegister;
12334 context.SetRegisterPlusOffset(base_reg, offset);
12335
12336 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12337 Rn + offset))
12338 return false;
12339 }
12340
12341 RegisterInfo data_reg;
12342 context.type = eContextRegisterStore;
12343 // for r = 0 to regs-1
12344 for (uint32_t r = 0; r < regs; ++r) {
12345 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
12346 uint64_t register_data = ReadRegisterUnsigned(
12347 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
12348 if (!success)
12349 return false;
12350
12351 // for e = 0 to elements-1
12352 for (uint32_t e = 0; e < elements; ++e) {
12353 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
12354 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
12355
12356 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
12357 address - Rn);
12358 if (!MemUWrite(context, address, word, ebytes))
12359 return false;
12360
12361 // address = address + ebytes;
12362 address = address + ebytes;
12363 }
12364 }
12365 }
12366 return true;
12367 }
12368
12369 // A8.6.392 VST1 (single element from one lane) This instruction stores one
12370 // element to memory from one element of a register.
EmulateVST1Single(const uint32_t opcode,ARMEncoding encoding)12371 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
12372 ARMEncoding encoding) {
12373 #if 0
12374 if ConditionPassed() then
12375 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12376 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12377 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12378 MemU[address,ebytes] = Elem[D[d],index,esize];
12379 #endif
12380
12381 bool success = false;
12382
12383 if (ConditionPassed(opcode)) {
12384 uint32_t ebytes;
12385 uint32_t esize;
12386 uint32_t index;
12387 uint32_t alignment;
12388 uint32_t d;
12389 uint32_t n;
12390 uint32_t m;
12391 bool wback;
12392 bool register_index;
12393
12394 switch (encoding) {
12395 case eEncodingT1:
12396 case eEncodingA1: {
12397 uint32_t size = Bits32(opcode, 11, 10);
12398 uint32_t index_align = Bits32(opcode, 7, 4);
12399
12400 // if size == '11' then UNDEFINED;
12401 if (size == 3)
12402 return false;
12403
12404 // case size of
12405 if (size == 0) // when '00'
12406 {
12407 // if index_align<0> != '0' then UNDEFINED;
12408 if (BitIsClear(index_align, 0))
12409 return false;
12410 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12411 ebytes = 1;
12412 esize = 8;
12413 index = Bits32(index_align, 3, 1);
12414 alignment = 1;
12415 } else if (size == 1) // when '01'
12416 {
12417 // if index_align<1> != '0' then UNDEFINED;
12418 if (BitIsClear(index_align, 1))
12419 return false;
12420
12421 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12422 ebytes = 2;
12423 esize = 16;
12424 index = Bits32(index_align, 3, 2);
12425
12426 // alignment = if index_align<0> == '0' then 1 else 2;
12427 if (BitIsClear(index_align, 0))
12428 alignment = 1;
12429 else
12430 alignment = 2;
12431 } else if (size == 2) // when '10'
12432 {
12433 // if index_align<2> != '0' then UNDEFINED;
12434 if (BitIsClear(index_align, 2))
12435 return false;
12436
12437 // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12438 // UNDEFINED;
12439 if ((Bits32(index_align, 1, 0) != 0) &&
12440 (Bits32(index_align, 1, 0) != 3))
12441 return false;
12442
12443 // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12444 ebytes = 4;
12445 esize = 32;
12446 index = Bit32(index_align, 3);
12447
12448 // alignment = if index_align<1:0> == '00' then 1 else 4;
12449 if (Bits32(index_align, 1, 0) == 0)
12450 alignment = 1;
12451 else
12452 alignment = 4;
12453 } else {
12454 return false;
12455 }
12456 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12457 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12458 n = Bits32(opcode, 19, 16);
12459 m = Bits32(opcode, 3, 0);
12460
12461 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12462 // then UNPREDICTABLE;
12463 wback = (m != 15);
12464 register_index = ((m != 15) && (m != 13));
12465
12466 if (n == 15)
12467 return false;
12468 } break;
12469
12470 default:
12471 return false;
12472 }
12473
12474 RegisterInfo base_reg;
12475 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12476
12477 uint32_t Rn = ReadCoreReg(n, &success);
12478 if (!success)
12479 return false;
12480
12481 // address = R[n]; if (address MOD alignment) != 0 then
12482 // GenerateAlignmentException();
12483 addr_t address = Rn;
12484 if ((address % alignment) != 0)
12485 return false;
12486
12487 EmulateInstruction::Context context;
12488 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12489 if (wback) {
12490 uint32_t Rm = ReadCoreReg(m, &success);
12491 if (!success)
12492 return false;
12493
12494 uint32_t offset;
12495 if (register_index)
12496 offset = Rm;
12497 else
12498 offset = ebytes;
12499
12500 context.type = eContextAdjustBaseRegister;
12501 context.SetRegisterPlusOffset(base_reg, offset);
12502
12503 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12504 Rn + offset))
12505 return false;
12506 }
12507
12508 // MemU[address,ebytes] = Elem[D[d],index,esize];
12509 uint64_t register_data =
12510 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12511 if (!success)
12512 return false;
12513
12514 uint64_t word =
12515 Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12516
12517 RegisterInfo data_reg;
12518 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12519 context.type = eContextRegisterStore;
12520 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
12521
12522 if (!MemUWrite(context, address, word, ebytes))
12523 return false;
12524 }
12525 return true;
12526 }
12527
12528 // A8.6.309 VLD1 (single element to all lanes) This instruction loads one
12529 // element from memory into every element of one or two vectors.
EmulateVLD1SingleAll(const uint32_t opcode,const ARMEncoding encoding)12530 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
12531 const ARMEncoding encoding) {
12532 #if 0
12533 if ConditionPassed() then
12534 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12535 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12536 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12537 replicated_element = Replicate(MemU[address,ebytes], elements);
12538 for r = 0 to regs-1
12539 D[d+r] = replicated_element;
12540 #endif
12541
12542 bool success = false;
12543
12544 if (ConditionPassed(opcode)) {
12545 uint32_t ebytes;
12546 uint32_t elements;
12547 uint32_t regs;
12548 uint32_t alignment;
12549 uint32_t d;
12550 uint32_t n;
12551 uint32_t m;
12552 bool wback;
12553 bool register_index;
12554
12555 switch (encoding) {
12556 case eEncodingT1:
12557 case eEncodingA1: {
12558 // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12559 uint32_t size = Bits32(opcode, 7, 6);
12560 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
12561 return false;
12562
12563 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
12564 // then 1 else 2;
12565 ebytes = 1 << size;
12566 elements = 8 / ebytes;
12567 if (BitIsClear(opcode, 5))
12568 regs = 1;
12569 else
12570 regs = 2;
12571
12572 // alignment = if a == '0' then 1 else ebytes;
12573 if (BitIsClear(opcode, 4))
12574 alignment = 1;
12575 else
12576 alignment = ebytes;
12577
12578 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12579 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12580 n = Bits32(opcode, 19, 16);
12581 m = Bits32(opcode, 3, 0);
12582
12583 // wback = (m != 15); register_index = (m != 15 && m != 13);
12584 wback = (m != 15);
12585 register_index = ((m != 15) && (m != 13));
12586
12587 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12588 if ((d + regs) > 32)
12589 return false;
12590
12591 if (n == 15)
12592 return false;
12593 } break;
12594
12595 default:
12596 return false;
12597 }
12598
12599 RegisterInfo base_reg;
12600 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12601
12602 uint32_t Rn = ReadCoreReg(n, &success);
12603 if (!success)
12604 return false;
12605
12606 // address = R[n]; if (address MOD alignment) != 0 then
12607 // GenerateAlignmentException();
12608 addr_t address = Rn;
12609 if ((address % alignment) != 0)
12610 return false;
12611
12612 EmulateInstruction::Context context;
12613 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12614 if (wback) {
12615 uint32_t Rm = ReadCoreReg(m, &success);
12616 if (!success)
12617 return false;
12618
12619 uint32_t offset;
12620 if (register_index)
12621 offset = Rm;
12622 else
12623 offset = ebytes;
12624
12625 context.type = eContextAdjustBaseRegister;
12626 context.SetRegisterPlusOffset(base_reg, offset);
12627
12628 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12629 Rn + offset))
12630 return false;
12631 }
12632
12633 // replicated_element = Replicate(MemU[address,ebytes], elements);
12634
12635 context.type = eContextRegisterLoad;
12636 uint64_t word = MemURead(context, address, ebytes, 0, &success);
12637 if (!success)
12638 return false;
12639
12640 uint64_t replicated_element = 0;
12641 uint32_t esize = ebytes * 8;
12642 for (uint32_t e = 0; e < elements; ++e)
12643 replicated_element =
12644 (replicated_element << esize) | Bits64(word, esize - 1, 0);
12645
12646 // for r = 0 to regs-1
12647 for (uint32_t r = 0; r < regs; ++r) {
12648 // D[d+r] = replicated_element;
12649 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12650 replicated_element))
12651 return false;
12652 }
12653 }
12654 return true;
12655 }
12656
12657 // B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const?
12658 // instruction provides an exception return without the use of the stack. It
12659 // subtracts the immediate constant from the LR, branches to the resulting
12660 // address, and also copies the SPSR to the CPSR.
EmulateSUBSPcLrEtc(const uint32_t opcode,const ARMEncoding encoding)12661 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
12662 const ARMEncoding encoding) {
12663 #if 0
12664 if ConditionPassed() then
12665 EncodingSpecificOperations();
12666 if CurrentInstrSet() == InstrSet_ThumbEE then
12667 UNPREDICTABLE;
12668 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12669 case opcode of
12670 when '0000' result = R[n] AND operand2; // AND
12671 when '0001' result = R[n] EOR operand2; // EOR
12672 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12673 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12674 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12675 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12676 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12677 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12678 when '1100' result = R[n] OR operand2; // ORR
12679 when '1101' result = operand2; // MOV
12680 when '1110' result = R[n] AND NOT(operand2); // BIC
12681 when '1111' result = NOT(operand2); // MVN
12682 CPSRWriteByInstr(SPSR[], '1111', TRUE);
12683 BranchWritePC(result);
12684 #endif
12685
12686 bool success = false;
12687
12688 if (ConditionPassed(opcode)) {
12689 uint32_t n;
12690 uint32_t m;
12691 uint32_t imm32;
12692 bool register_form;
12693 ARM_ShifterType shift_t;
12694 uint32_t shift_n;
12695 uint32_t code;
12696
12697 switch (encoding) {
12698 case eEncodingT1:
12699 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14;
12700 // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010';
12701 // // = SUB
12702 n = 14;
12703 imm32 = Bits32(opcode, 7, 0);
12704 register_form = false;
12705 code = 2;
12706
12707 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12708 if (InITBlock() && !LastInITBlock())
12709 return false;
12710
12711 break;
12712
12713 case eEncodingA1:
12714 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12715 n = Bits32(opcode, 19, 16);
12716 imm32 = ARMExpandImm(opcode);
12717 register_form = false;
12718 code = Bits32(opcode, 24, 21);
12719
12720 break;
12721
12722 case eEncodingA2:
12723 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12724 n = Bits32(opcode, 19, 16);
12725 m = Bits32(opcode, 3, 0);
12726 register_form = true;
12727
12728 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12729 shift_n = DecodeImmShiftARM(opcode, shift_t);
12730
12731 break;
12732
12733 default:
12734 return false;
12735 }
12736
12737 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
12738 // else imm32;
12739 uint32_t operand2;
12740 if (register_form) {
12741 uint32_t Rm = ReadCoreReg(m, &success);
12742 if (!success)
12743 return false;
12744
12745 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
12746 if (!success)
12747 return false;
12748 } else {
12749 operand2 = imm32;
12750 }
12751
12752 uint32_t Rn = ReadCoreReg(n, &success);
12753 if (!success)
12754 return false;
12755
12756 AddWithCarryResult result;
12757
12758 // case opcode of
12759 switch (code) {
12760 case 0: // when '0000'
12761 // result = R[n] AND operand2; // AND
12762 result.result = Rn & operand2;
12763 break;
12764
12765 case 1: // when '0001'
12766 // result = R[n] EOR operand2; // EOR
12767 result.result = Rn ^ operand2;
12768 break;
12769
12770 case 2: // when '0010'
12771 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12772 result = AddWithCarry(Rn, ~(operand2), 1);
12773 break;
12774
12775 case 3: // when '0011'
12776 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12777 result = AddWithCarry(~(Rn), operand2, 1);
12778 break;
12779
12780 case 4: // when '0100'
12781 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12782 result = AddWithCarry(Rn, operand2, 0);
12783 break;
12784
12785 case 5: // when '0101'
12786 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12787 result = AddWithCarry(Rn, operand2, APSR_C);
12788 break;
12789
12790 case 6: // when '0110'
12791 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12792 result = AddWithCarry(Rn, ~(operand2), APSR_C);
12793 break;
12794
12795 case 7: // when '0111'
12796 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12797 result = AddWithCarry(~(Rn), operand2, APSR_C);
12798 break;
12799
12800 case 10: // when '1100'
12801 // result = R[n] OR operand2; // ORR
12802 result.result = Rn | operand2;
12803 break;
12804
12805 case 11: // when '1101'
12806 // result = operand2; // MOV
12807 result.result = operand2;
12808 break;
12809
12810 case 12: // when '1110'
12811 // result = R[n] AND NOT(operand2); // BIC
12812 result.result = Rn & ~(operand2);
12813 break;
12814
12815 case 15: // when '1111'
12816 // result = NOT(operand2); // MVN
12817 result.result = ~(operand2);
12818 break;
12819
12820 default:
12821 return false;
12822 }
12823 // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12824
12825 // For now, in emulation mode, we don't have access to the SPSR, so we will
12826 // use the CPSR instead, and hope for the best.
12827 uint32_t spsr =
12828 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12829 if (!success)
12830 return false;
12831
12832 CPSRWriteByInstr(spsr, 15, true);
12833
12834 // BranchWritePC(result);
12835 EmulateInstruction::Context context;
12836 context.type = eContextAdjustPC;
12837 context.SetImmediate(result.result);
12838
12839 BranchWritePC(context, result.result);
12840 }
12841 return true;
12842 }
12843
12844 EmulateInstructionARM::ARMOpcode *
GetARMOpcodeForInstruction(const uint32_t opcode,uint32_t arm_isa)12845 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
12846 uint32_t arm_isa) {
12847 static ARMOpcode g_arm_opcodes[] = {
12848 // Prologue instructions
12849
12850 // push register(s)
12851 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12852 &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12853 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12854 &EmulateInstructionARM::EmulatePUSH, "push <register>"},
12855
12856 // set r7 to point to a stack offset
12857 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12858 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
12859 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12860 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12861 // copy the stack pointer to ip
12862 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
12863 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
12864 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12865 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
12866 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12867 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12868
12869 // adjust the stack pointer
12870 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12871 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12872 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12873 &EmulateInstructionARM::EmulateSUBSPReg,
12874 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12875
12876 // push one register
12877 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12878 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12879 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
12880
12881 // vector push consecutive extension register(s)
12882 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12883 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12884 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12885 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12886
12887 // Epilogue instructions
12888
12889 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12890 &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12891 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12892 &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12893 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12894 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12895 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12896 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12897
12898 // Supervisor Call (previously Software Interrupt)
12899 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12900 &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12901
12902 // Branch instructions
12903 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
12904 // "bl <label>".
12905 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
12906 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12907 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12908 &EmulateInstructionARM::EmulateB, "b #imm24"},
12909 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12910 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12911 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
12912 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12913 // for example, "bx lr"
12914 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
12915 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12916 // bxj
12917 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
12918 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12919
12920 // Data-processing instructions
12921 // adc (immediate)
12922 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12923 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12924 // adc (register)
12925 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12926 &EmulateInstructionARM::EmulateADCReg,
12927 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12928 // add (immediate)
12929 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12930 &EmulateInstructionARM::EmulateADDImmARM,
12931 "add{s}<c> <Rd>, <Rn>, #const"},
12932 // add (register)
12933 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12934 &EmulateInstructionARM::EmulateADDReg,
12935 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12936 // add (register-shifted register)
12937 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
12938 &EmulateInstructionARM::EmulateADDRegShift,
12939 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12940 // adr
12941 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12942 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12943 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
12944 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12945 // and (immediate)
12946 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12947 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12948 // and (register)
12949 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12950 &EmulateInstructionARM::EmulateANDReg,
12951 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12952 // bic (immediate)
12953 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12954 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12955 // bic (register)
12956 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12957 &EmulateInstructionARM::EmulateBICReg,
12958 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12959 // eor (immediate)
12960 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12961 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12962 // eor (register)
12963 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12964 &EmulateInstructionARM::EmulateEORReg,
12965 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12966 // orr (immediate)
12967 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12968 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12969 // orr (register)
12970 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12971 &EmulateInstructionARM::EmulateORRReg,
12972 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12973 // rsb (immediate)
12974 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12975 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12976 // rsb (register)
12977 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12978 &EmulateInstructionARM::EmulateRSBReg,
12979 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12980 // rsc (immediate)
12981 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12982 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12983 // rsc (register)
12984 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12985 &EmulateInstructionARM::EmulateRSCReg,
12986 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12987 // sbc (immediate)
12988 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12989 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12990 // sbc (register)
12991 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12992 &EmulateInstructionARM::EmulateSBCReg,
12993 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12994 // sub (immediate, ARM)
12995 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12996 &EmulateInstructionARM::EmulateSUBImmARM,
12997 "sub{s}<c> <Rd>, <Rn>, #<const>"},
12998 // sub (sp minus immediate)
12999 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13000 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
13001 // sub (register)
13002 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13003 &EmulateInstructionARM::EmulateSUBReg,
13004 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
13005 // teq (immediate)
13006 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13007 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
13008 // teq (register)
13009 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13010 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13011 // tst (immediate)
13012 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13013 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
13014 // tst (register)
13015 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13016 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
13017
13018 // mov (immediate)
13019 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13020 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
13021 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
13022 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
13023 // mov (register)
13024 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13025 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
13026 // mvn (immediate)
13027 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13028 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
13029 // mvn (register)
13030 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13031 &EmulateInstructionARM::EmulateMVNReg,
13032 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
13033 // cmn (immediate)
13034 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13035 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13036 // cmn (register)
13037 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13038 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13039 // cmp (immediate)
13040 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13041 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
13042 // cmp (register)
13043 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13044 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
13045 // asr (immediate)
13046 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
13047 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
13048 // asr (register)
13049 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13050 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
13051 // lsl (immediate)
13052 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13053 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
13054 // lsl (register)
13055 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
13056 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
13057 // lsr (immediate)
13058 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
13059 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
13060 // lsr (register)
13061 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13062 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
13063 // rrx is a special case encoding of ror (immediate)
13064 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13065 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
13066 // ror (immediate)
13067 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13068 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
13069 // ror (register)
13070 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
13071 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
13072 // mul
13073 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
13074 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
13075
13076 // subs pc, lr and related instructions
13077 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13078 &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13079 "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
13080 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
13081 &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13082 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
13083
13084 // Load instructions
13085 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13086 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13087 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13088 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
13089 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13090 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13091 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13092 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
13093 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13094 &EmulateInstructionARM::EmulateLDRImmediateARM,
13095 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
13096 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13097 &EmulateInstructionARM::EmulateLDRRegister,
13098 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
13099 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13100 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
13101 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13102 &EmulateInstructionARM::EmulateLDRBRegister,
13103 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
13104 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13105 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13106 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13107 &EmulateInstructionARM::EmulateLDRHRegister,
13108 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13109 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13110 &EmulateInstructionARM::EmulateLDRSBImmediate,
13111 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
13112 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13113 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
13114 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13115 &EmulateInstructionARM::EmulateLDRSBRegister,
13116 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13117 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13118 &EmulateInstructionARM::EmulateLDRSHImmediate,
13119 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
13120 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13121 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13122 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13123 &EmulateInstructionARM::EmulateLDRSHRegister,
13124 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13125 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13126 &EmulateInstructionARM::EmulateLDRDImmediate,
13127 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
13128 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13129 &EmulateInstructionARM::EmulateLDRDRegister,
13130 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13131 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13132 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13133 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13134 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13135 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13136 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13137 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13138 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13139 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13140 &EmulateInstructionARM::EmulateVLD1Multiple,
13141 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13142 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13143 &EmulateInstructionARM::EmulateVLD1Single,
13144 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13145 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13146 &EmulateInstructionARM::EmulateVLD1SingleAll,
13147 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13148
13149 // Store instructions
13150 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13151 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13152 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13153 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
13154 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13155 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13156 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13157 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
13158 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13159 &EmulateInstructionARM::EmulateSTRRegister,
13160 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
13161 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13162 &EmulateInstructionARM::EmulateSTRHRegister,
13163 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
13164 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13165 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
13166 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13167 &EmulateInstructionARM::EmulateSTRBImmARM,
13168 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13169 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13170 &EmulateInstructionARM::EmulateSTRImmARM,
13171 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13172 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13173 &EmulateInstructionARM::EmulateSTRDImm,
13174 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
13175 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13176 &EmulateInstructionARM::EmulateSTRDReg,
13177 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13178 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13179 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13180 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13181 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13182 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13183 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
13184 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13185 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
13186 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13187 &EmulateInstructionARM::EmulateVST1Multiple,
13188 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13189 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13190 &EmulateInstructionARM::EmulateVST1Single,
13191 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13192
13193 // Other instructions
13194 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13195 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
13196 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13197 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
13198 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13199 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
13200 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13201 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
13202 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13203 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
13204
13205 };
13206 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
13207
13208 for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
13209 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
13210 (g_arm_opcodes[i].variants & arm_isa) != 0)
13211 return &g_arm_opcodes[i];
13212 }
13213 return nullptr;
13214 }
13215
13216 EmulateInstructionARM::ARMOpcode *
GetThumbOpcodeForInstruction(const uint32_t opcode,uint32_t arm_isa)13217 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
13218 uint32_t arm_isa) {
13219
13220 static ARMOpcode g_thumb_opcodes[] = {
13221 // Prologue instructions
13222
13223 // push register(s)
13224 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
13225 &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
13226 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13227 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
13228 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13229 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
13230
13231 // set r7 to point to a stack offset
13232 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13233 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
13234 // copy the stack pointer to r7
13235 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
13236 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
13237 // move from high register to low register (comes after "mov r7, sp" to
13238 // resolve ambiguity)
13239 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
13240 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
13241
13242 // PC-relative load into register (see also EmulateADDSPRm)
13243 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13244 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
13245
13246 // adjust the stack pointer
13247 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
13248 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
13249 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13250 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
13251 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13252 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
13253 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13254 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
13255 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13256 &EmulateInstructionARM::EmulateSUBSPReg,
13257 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
13258
13259 // vector push consecutive extension register(s)
13260 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13261 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
13262 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13263 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
13264
13265 // Epilogue instructions
13266
13267 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13268 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
13269 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13270 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
13271 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13272 &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
13273 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13274 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
13275 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13276 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
13277 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13278 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
13279 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13280 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
13281
13282 // Supervisor Call (previously Software Interrupt)
13283 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13284 &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
13285
13286 // If Then makes up to four following instructions conditional.
13287 // The next 5 opcode _must_ come before the if then instruction
13288 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13289 &EmulateInstructionARM::EmulateNop, "nop"},
13290 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13291 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
13292 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13293 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
13294 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13295 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
13296 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13297 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
13298 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13299 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
13300
13301 // Branch instructions
13302 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
13303 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13304 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
13305 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13306 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
13307 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13308 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
13309 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13310 &EmulateInstructionARM::EmulateB,
13311 "b<c>.w #imm8 (outside or last in IT)"},
13312 // J1 == J2 == 1
13313 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
13314 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
13315 // J1 == J2 == 1
13316 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
13317 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
13318 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
13319 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
13320 // for example, "bx lr"
13321 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
13322 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
13323 // bxj
13324 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
13325 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
13326 // compare and branch
13327 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13328 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
13329 // table branch byte
13330 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13331 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
13332 // table branch halfword
13333 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13334 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
13335
13336 // Data-processing instructions
13337 // adc (immediate)
13338 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13339 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
13340 // adc (register)
13341 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
13342 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
13343 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13344 &EmulateInstructionARM::EmulateADCReg,
13345 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13346 // add (register)
13347 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13348 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
13349 // Make sure "add sp, <Rm>" comes before this instruction, so there's no
13350 // ambiguity decoding the two.
13351 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
13352 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
13353 // adr
13354 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13355 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13356 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13357 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
13358 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13359 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13360 // and (immediate)
13361 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13362 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
13363 // and (register)
13364 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13365 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
13366 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13367 &EmulateInstructionARM::EmulateANDReg,
13368 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13369 // bic (immediate)
13370 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13371 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
13372 // bic (register)
13373 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
13374 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
13375 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13376 &EmulateInstructionARM::EmulateBICReg,
13377 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13378 // eor (immediate)
13379 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13380 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
13381 // eor (register)
13382 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
13383 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
13384 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13385 &EmulateInstructionARM::EmulateEORReg,
13386 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13387 // orr (immediate)
13388 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13389 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
13390 // orr (register)
13391 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
13392 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
13393 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13394 &EmulateInstructionARM::EmulateORRReg,
13395 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13396 // rsb (immediate)
13397 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
13398 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
13399 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13400 &EmulateInstructionARM::EmulateRSBImm,
13401 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
13402 // rsb (register)
13403 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13404 &EmulateInstructionARM::EmulateRSBReg,
13405 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13406 // sbc (immediate)
13407 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13408 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13409 // sbc (register)
13410 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
13411 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
13412 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13413 &EmulateInstructionARM::EmulateSBCReg,
13414 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13415 // add (immediate, Thumb)
13416 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13417 &EmulateInstructionARM::EmulateADDImmThumb,
13418 "adds|add<c> <Rd>,<Rn>,#<imm3>"},
13419 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13420 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
13421 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13422 &EmulateInstructionARM::EmulateADDImmThumb,
13423 "add{s}<c>.w <Rd>,<Rn>,#<const>"},
13424 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13425 &EmulateInstructionARM::EmulateADDImmThumb,
13426 "addw<c> <Rd>,<Rn>,#<imm12>"},
13427 // sub (immediate, Thumb)
13428 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13429 &EmulateInstructionARM::EmulateSUBImmThumb,
13430 "subs|sub<c> <Rd>, <Rn> #imm3"},
13431 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
13432 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
13433 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13434 &EmulateInstructionARM::EmulateSUBImmThumb,
13435 "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13436 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13437 &EmulateInstructionARM::EmulateSUBImmThumb,
13438 "subw<c> <Rd>, <Rn>, #imm12"},
13439 // sub (sp minus immediate)
13440 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13441 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
13442 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13443 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
13444 // sub (register)
13445 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13446 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
13447 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13448 &EmulateInstructionARM::EmulateSUBReg,
13449 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13450 // teq (immediate)
13451 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13452 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
13453 // teq (register)
13454 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13455 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13456 // tst (immediate)
13457 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13458 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
13459 // tst (register)
13460 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
13461 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
13462 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13463 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
13464
13465 // move from high register to high register
13466 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
13467 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
13468 // move from low register to low register
13469 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13470 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
13471 // mov{s}<c>.w <Rd>, <Rm>
13472 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13473 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
13474 // move immediate
13475 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13476 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
13477 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13478 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
13479 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13480 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
13481 // mvn (immediate)
13482 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13483 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
13484 // mvn (register)
13485 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13486 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
13487 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13488 &EmulateInstructionARM::EmulateMVNReg,
13489 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13490 // cmn (immediate)
13491 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13492 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13493 // cmn (register)
13494 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13495 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
13496 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13497 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13498 // cmp (immediate)
13499 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13500 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
13501 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13502 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
13503 // cmp (register) (Rn and Rm both from r0-r7)
13504 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
13505 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13506 // cmp (register) (Rn and Rm not both from r0-r7)
13507 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
13508 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13509 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
13510 &EmulateInstructionARM::EmulateCMPReg,
13511 "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13512 // asr (immediate)
13513 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13514 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
13515 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13516 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
13517 // asr (register)
13518 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
13519 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
13520 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13521 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13522 // lsl (immediate)
13523 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13524 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
13525 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13526 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
13527 // lsl (register)
13528 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13529 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
13530 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13531 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
13532 // lsr (immediate)
13533 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13534 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
13535 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13536 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
13537 // lsr (register)
13538 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13539 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
13540 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13541 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13542 // rrx is a special case encoding of ror (immediate)
13543 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13544 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
13545 // ror (immediate)
13546 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13547 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
13548 // ror (register)
13549 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13550 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
13551 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13552 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
13553 // mul
13554 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13555 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
13556 // mul
13557 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13558 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
13559
13560 // subs pc, lr and related instructions
13561 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13562 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
13563
13564 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
13565 // LDM.. Instructions in this table;
13566 // otherwise the wrong instructions will be selected.
13567
13568 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13569 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
13570 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13571 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
13572
13573 // Load instructions
13574 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13575 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13576 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13577 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
13578 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13579 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13580 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13581 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
13582 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13583 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
13584 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13585 &EmulateInstructionARM::EmulateLDRRtRnImm,
13586 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13587 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13588 &EmulateInstructionARM::EmulateLDRRtRnImm,
13589 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13590 // Thumb2 PC-relative load into register
13591 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13592 &EmulateInstructionARM::EmulateLDRRtPCRelative,
13593 "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13594 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13595 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
13596 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13597 &EmulateInstructionARM::EmulateLDRRegister,
13598 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13599 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13600 &EmulateInstructionARM::EmulateLDRBImmediate,
13601 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13602 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13603 &EmulateInstructionARM::EmulateLDRBImmediate,
13604 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13605 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13606 &EmulateInstructionARM::EmulateLDRBImmediate,
13607 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13608 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13609 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
13610 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13611 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
13612 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13613 &EmulateInstructionARM::EmulateLDRBRegister,
13614 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13615 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13616 &EmulateInstructionARM::EmulateLDRHImmediate,
13617 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13618 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13619 &EmulateInstructionARM::EmulateLDRHImmediate,
13620 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13621 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13622 &EmulateInstructionARM::EmulateLDRHImmediate,
13623 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13624 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13625 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13626 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13627 &EmulateInstructionARM::EmulateLDRHRegister,
13628 "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13629 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13630 &EmulateInstructionARM::EmulateLDRHRegister,
13631 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13632 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13633 &EmulateInstructionARM::EmulateLDRSBImmediate,
13634 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13635 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13636 &EmulateInstructionARM::EmulateLDRSBImmediate,
13637 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13638 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13639 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
13640 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13641 &EmulateInstructionARM::EmulateLDRSBRegister,
13642 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13643 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13644 &EmulateInstructionARM::EmulateLDRSBRegister,
13645 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13646 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13647 &EmulateInstructionARM::EmulateLDRSHImmediate,
13648 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13649 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13650 &EmulateInstructionARM::EmulateLDRSHImmediate,
13651 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13652 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13653 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13654 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13655 &EmulateInstructionARM::EmulateLDRSHRegister,
13656 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13657 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13658 &EmulateInstructionARM::EmulateLDRSHRegister,
13659 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13660 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13661 &EmulateInstructionARM::EmulateLDRDImmediate,
13662 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13663 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13664 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13665 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13666 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13667 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13668 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13669 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13670 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
13671 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13672 &EmulateInstructionARM::EmulateVLD1Multiple,
13673 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13674 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13675 &EmulateInstructionARM::EmulateVLD1Single,
13676 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13677 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13678 &EmulateInstructionARM::EmulateVLD1SingleAll,
13679 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13680
13681 // Store instructions
13682 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13683 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13684 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13685 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
13686 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13687 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13688 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13689 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
13690 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13691 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
13692 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13693 &EmulateInstructionARM::EmulateSTRThumb,
13694 "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13695 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13696 &EmulateInstructionARM::EmulateSTRThumb,
13697 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13698 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13699 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
13700 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13701 &EmulateInstructionARM::EmulateSTRRegister,
13702 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13703 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13704 &EmulateInstructionARM::EmulateSTRBThumb,
13705 "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13706 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13707 &EmulateInstructionARM::EmulateSTRBThumb,
13708 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13709 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13710 &EmulateInstructionARM::EmulateSTRBThumb,
13711 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13712 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13713 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
13714 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13715 &EmulateInstructionARM::EmulateSTRHRegister,
13716 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13717 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13718 &EmulateInstructionARM::EmulateSTREX,
13719 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13720 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13721 &EmulateInstructionARM::EmulateSTRDImm,
13722 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13723 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13724 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13725 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13726 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13727 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13728 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13729 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13730 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13731 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13732 &EmulateInstructionARM::EmulateVST1Multiple,
13733 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13734 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13735 &EmulateInstructionARM::EmulateVST1Single,
13736 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13737
13738 // Other instructions
13739 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13740 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
13741 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
13742 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13743 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13744 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
13745 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13746 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13747 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13748 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
13749 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13750 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13751 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13752 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
13753 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13754 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13755 };
13756
13757 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
13758 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13759 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13760 (g_thumb_opcodes[i].variants & arm_isa) != 0)
13761 return &g_thumb_opcodes[i];
13762 }
13763 return nullptr;
13764 }
13765
SetArchitecture(const ArchSpec & arch)13766 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
13767 m_arch = arch;
13768 m_arm_isa = 0;
13769 const char *arch_cstr = arch.GetArchitectureName();
13770 if (arch_cstr) {
13771 if (0 == ::strcasecmp(arch_cstr, "armv4t"))
13772 m_arm_isa = ARMv4T;
13773 else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))
13774 m_arm_isa = ARMv5TEJ;
13775 else if (0 == ::strcasecmp(arch_cstr, "armv5te"))
13776 m_arm_isa = ARMv5TE;
13777 else if (0 == ::strcasecmp(arch_cstr, "armv5t"))
13778 m_arm_isa = ARMv5T;
13779 else if (0 == ::strcasecmp(arch_cstr, "armv6k"))
13780 m_arm_isa = ARMv6K;
13781 else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))
13782 m_arm_isa = ARMv6T2;
13783 else if (0 == ::strcasecmp(arch_cstr, "armv7s"))
13784 m_arm_isa = ARMv7S;
13785 else if (0 == ::strcasecmp(arch_cstr, "arm"))
13786 m_arm_isa = ARMvAll;
13787 else if (0 == ::strcasecmp(arch_cstr, "thumb"))
13788 m_arm_isa = ARMvAll;
13789 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5))
13790 m_arm_isa = ARMv4;
13791 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5))
13792 m_arm_isa = ARMv6;
13793 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5))
13794 m_arm_isa = ARMv7;
13795 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5))
13796 m_arm_isa = ARMv8;
13797 }
13798 return m_arm_isa != 0;
13799 }
13800
SetInstruction(const Opcode & insn_opcode,const Address & inst_addr,Target * target)13801 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
13802 const Address &inst_addr,
13803 Target *target) {
13804 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
13805 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
13806 m_arch.IsAlwaysThumbInstructions())
13807 m_opcode_mode = eModeThumb;
13808 else {
13809 AddressClass addr_class = inst_addr.GetAddressClass();
13810
13811 if ((addr_class == AddressClass::eCode) ||
13812 (addr_class == AddressClass::eUnknown))
13813 m_opcode_mode = eModeARM;
13814 else if (addr_class == AddressClass::eCodeAlternateISA)
13815 m_opcode_mode = eModeThumb;
13816 else
13817 return false;
13818 }
13819 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
13820 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13821 else
13822 m_opcode_cpsr = CPSR_MODE_USR;
13823 return true;
13824 }
13825 return false;
13826 }
13827
ReadInstruction()13828 bool EmulateInstructionARM::ReadInstruction() {
13829 bool success = false;
13830 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
13831 LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13832 if (success) {
13833 addr_t pc =
13834 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
13835 LLDB_INVALID_ADDRESS, &success);
13836 if (success) {
13837 Context read_inst_context;
13838 read_inst_context.type = eContextReadOpcode;
13839 read_inst_context.SetNoArgs();
13840
13841 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
13842 m_opcode_mode = eModeThumb;
13843 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13844
13845 if (success) {
13846 if ((thumb_opcode & 0xe000) != 0xe000 ||
13847 ((thumb_opcode & 0x1800u) == 0)) {
13848 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
13849 } else {
13850 m_opcode.SetOpcode32(
13851 (thumb_opcode << 16) |
13852 MemARead(read_inst_context, pc + 2, 2, 0, &success),
13853 GetByteOrder());
13854 }
13855 }
13856 } else {
13857 m_opcode_mode = eModeARM;
13858 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
13859 GetByteOrder());
13860 }
13861
13862 if (!m_ignore_conditions) {
13863 // If we are not ignoreing the conditions then init the it session from
13864 // the current value of cpsr.
13865 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
13866 Bits32(m_opcode_cpsr, 26, 25);
13867 if (it != 0)
13868 m_it_session.InitIT(it);
13869 }
13870 }
13871 }
13872 if (!success) {
13873 m_opcode_mode = eModeInvalid;
13874 m_addr = LLDB_INVALID_ADDRESS;
13875 }
13876 return success;
13877 }
13878
ArchVersion()13879 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
13880
ConditionPassed(const uint32_t opcode)13881 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
13882 // If we are ignoring conditions, then always return true. this allows us to
13883 // iterate over disassembly code and still emulate an instruction even if we
13884 // don't have all the right bits set in the CPSR register...
13885 if (m_ignore_conditions)
13886 return true;
13887
13888 const uint32_t cond = CurrentCond(opcode);
13889 if (cond == UINT32_MAX)
13890 return false;
13891
13892 bool result = false;
13893 switch (UnsignedBits(cond, 3, 1)) {
13894 case 0:
13895 if (m_opcode_cpsr == 0)
13896 result = true;
13897 else
13898 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13899 break;
13900 case 1:
13901 if (m_opcode_cpsr == 0)
13902 result = true;
13903 else
13904 result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13905 break;
13906 case 2:
13907 if (m_opcode_cpsr == 0)
13908 result = true;
13909 else
13910 result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13911 break;
13912 case 3:
13913 if (m_opcode_cpsr == 0)
13914 result = true;
13915 else
13916 result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13917 break;
13918 case 4:
13919 if (m_opcode_cpsr == 0)
13920 result = true;
13921 else
13922 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
13923 ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13924 break;
13925 case 5:
13926 if (m_opcode_cpsr == 0)
13927 result = true;
13928 else {
13929 bool n = (m_opcode_cpsr & MASK_CPSR_N);
13930 bool v = (m_opcode_cpsr & MASK_CPSR_V);
13931 result = n == v;
13932 }
13933 break;
13934 case 6:
13935 if (m_opcode_cpsr == 0)
13936 result = true;
13937 else {
13938 bool n = (m_opcode_cpsr & MASK_CPSR_N);
13939 bool v = (m_opcode_cpsr & MASK_CPSR_V);
13940 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13941 }
13942 break;
13943 case 7:
13944 // Always execute (cond == 0b1110, or the special 0b1111 which gives
13945 // opcodes different meanings, but always means execution happens.
13946 return true;
13947 }
13948
13949 if (cond & 1)
13950 result = !result;
13951 return result;
13952 }
13953
CurrentCond(const uint32_t opcode)13954 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
13955 switch (m_opcode_mode) {
13956 case eModeInvalid:
13957 break;
13958
13959 case eModeARM:
13960 return UnsignedBits(opcode, 31, 28);
13961
13962 case eModeThumb:
13963 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13964 // 'cond' field of the encoding.
13965 {
13966 const uint32_t byte_size = m_opcode.GetByteSize();
13967 if (byte_size == 2) {
13968 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13969 return Bits32(opcode, 11, 8);
13970 } else if (byte_size == 4) {
13971 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
13972 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
13973 return Bits32(opcode, 25, 22);
13974 }
13975 } else
13976 // We have an invalid thumb instruction, let's bail out.
13977 break;
13978
13979 return m_it_session.GetCond();
13980 }
13981 }
13982 return UINT32_MAX; // Return invalid value
13983 }
13984
InITBlock()13985 bool EmulateInstructionARM::InITBlock() {
13986 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13987 }
13988
LastInITBlock()13989 bool EmulateInstructionARM::LastInITBlock() {
13990 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13991 }
13992
BadMode(uint32_t mode)13993 bool EmulateInstructionARM::BadMode(uint32_t mode) {
13994
13995 switch (mode) {
13996 case 16:
13997 return false; // '10000'
13998 case 17:
13999 return false; // '10001'
14000 case 18:
14001 return false; // '10010'
14002 case 19:
14003 return false; // '10011'
14004 case 22:
14005 return false; // '10110'
14006 case 23:
14007 return false; // '10111'
14008 case 27:
14009 return false; // '11011'
14010 case 31:
14011 return false; // '11111'
14012 default:
14013 return true;
14014 }
14015 return true;
14016 }
14017
CurrentModeIsPrivileged()14018 bool EmulateInstructionARM::CurrentModeIsPrivileged() {
14019 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
14020
14021 if (BadMode(mode))
14022 return false;
14023
14024 if (mode == 16)
14025 return false;
14026
14027 return true;
14028 }
14029
CPSRWriteByInstr(uint32_t value,uint32_t bytemask,bool affect_execstate)14030 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
14031 bool affect_execstate) {
14032 bool privileged = CurrentModeIsPrivileged();
14033
14034 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
14035
14036 if (BitIsSet(bytemask, 3)) {
14037 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
14038 if (affect_execstate)
14039 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
14040 }
14041
14042 if (BitIsSet(bytemask, 2)) {
14043 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
14044 }
14045
14046 if (BitIsSet(bytemask, 1)) {
14047 if (affect_execstate)
14048 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
14049 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
14050 if (privileged)
14051 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
14052 }
14053
14054 if (BitIsSet(bytemask, 0)) {
14055 if (privileged)
14056 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
14057 if (affect_execstate)
14058 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
14059 if (privileged)
14060 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
14061 }
14062
14063 m_opcode_cpsr = tmp_cpsr;
14064 }
14065
BranchWritePC(const Context & context,uint32_t addr)14066 bool EmulateInstructionARM::BranchWritePC(const Context &context,
14067 uint32_t addr) {
14068 addr_t target;
14069
14070 // Check the current instruction set.
14071 if (CurrentInstrSet() == eModeARM)
14072 target = addr & 0xfffffffc;
14073 else
14074 target = addr & 0xfffffffe;
14075
14076 return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14077 LLDB_REGNUM_GENERIC_PC, target);
14078 }
14079
14080 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
14081 // inspecting addr.
BXWritePC(Context & context,uint32_t addr)14082 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
14083 addr_t target;
14084 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
14085 // we want to record it and issue a WriteRegister callback so the clients can
14086 // track the mode changes accordingly.
14087 bool cpsr_changed = false;
14088
14089 if (BitIsSet(addr, 0)) {
14090 if (CurrentInstrSet() != eModeThumb) {
14091 SelectInstrSet(eModeThumb);
14092 cpsr_changed = true;
14093 }
14094 target = addr & 0xfffffffe;
14095 context.SetISA(eModeThumb);
14096 } else if (BitIsClear(addr, 1)) {
14097 if (CurrentInstrSet() != eModeARM) {
14098 SelectInstrSet(eModeARM);
14099 cpsr_changed = true;
14100 }
14101 target = addr & 0xfffffffc;
14102 context.SetISA(eModeARM);
14103 } else
14104 return false; // address<1:0> == '10' => UNPREDICTABLE
14105
14106 if (cpsr_changed) {
14107 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14108 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14109 return false;
14110 }
14111 return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14112 LLDB_REGNUM_GENERIC_PC, target);
14113 }
14114
14115 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14116 // versions.
LoadWritePC(Context & context,uint32_t addr)14117 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
14118 if (ArchVersion() >= ARMv5T)
14119 return BXWritePC(context, addr);
14120 else
14121 return BranchWritePC((const Context)context, addr);
14122 }
14123
14124 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14125 // versions and current instruction set.
ALUWritePC(Context & context,uint32_t addr)14126 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
14127 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
14128 return BXWritePC(context, addr);
14129 else
14130 return BranchWritePC((const Context)context, addr);
14131 }
14132
CurrentInstrSet()14133 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
14134 return m_opcode_mode;
14135 }
14136
14137 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next
14138 // ReadInstruction() is performed. This function has a side effect of updating
14139 // the m_new_inst_cpsr member variable if necessary.
SelectInstrSet(Mode arm_or_thumb)14140 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
14141 m_new_inst_cpsr = m_opcode_cpsr;
14142 switch (arm_or_thumb) {
14143 default:
14144 return false;
14145 case eModeARM:
14146 // Clear the T bit.
14147 m_new_inst_cpsr &= ~MASK_CPSR_T;
14148 break;
14149 case eModeThumb:
14150 // Set the T bit.
14151 m_new_inst_cpsr |= MASK_CPSR_T;
14152 break;
14153 }
14154 return true;
14155 }
14156
14157 // This function returns TRUE if the processor currently provides support for
14158 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
14159 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
UnalignedSupport()14160 bool EmulateInstructionARM::UnalignedSupport() {
14161 return (ArchVersion() >= ARMv7);
14162 }
14163
14164 // The main addition and subtraction instructions can produce status
14165 // information about both unsigned carry and signed overflow conditions. This
14166 // status information can be used to synthesize multi-word additions and
14167 // subtractions.
14168 EmulateInstructionARM::AddWithCarryResult
AddWithCarry(uint32_t x,uint32_t y,uint8_t carry_in)14169 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
14170 uint32_t result;
14171 uint8_t carry_out;
14172 uint8_t overflow;
14173
14174 uint64_t unsigned_sum = x + y + carry_in;
14175 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
14176
14177 result = UnsignedBits(unsigned_sum, 31, 0);
14178 // carry_out = (result == unsigned_sum ? 0 : 1);
14179 overflow = ((int32_t)result == signed_sum ? 0 : 1);
14180
14181 if (carry_in)
14182 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
14183 else
14184 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
14185
14186 AddWithCarryResult res = {result, carry_out, overflow};
14187 return res;
14188 }
14189
ReadCoreReg(uint32_t num,bool * success)14190 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
14191 lldb::RegisterKind reg_kind;
14192 uint32_t reg_num;
14193 switch (num) {
14194 case SP_REG:
14195 reg_kind = eRegisterKindGeneric;
14196 reg_num = LLDB_REGNUM_GENERIC_SP;
14197 break;
14198 case LR_REG:
14199 reg_kind = eRegisterKindGeneric;
14200 reg_num = LLDB_REGNUM_GENERIC_RA;
14201 break;
14202 case PC_REG:
14203 reg_kind = eRegisterKindGeneric;
14204 reg_num = LLDB_REGNUM_GENERIC_PC;
14205 break;
14206 default:
14207 if (num < SP_REG) {
14208 reg_kind = eRegisterKindDWARF;
14209 reg_num = dwarf_r0 + num;
14210 } else {
14211 // assert(0 && "Invalid register number");
14212 *success = false;
14213 return UINT32_MAX;
14214 }
14215 break;
14216 }
14217
14218 // Read our register.
14219 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
14220
14221 // When executing an ARM instruction , PC reads as the address of the current
14222 // instruction plus 8. When executing a Thumb instruction , PC reads as the
14223 // address of the current instruction plus 4.
14224 if (num == 15) {
14225 if (CurrentInstrSet() == eModeARM)
14226 val += 8;
14227 else
14228 val += 4;
14229 }
14230
14231 return val;
14232 }
14233
14234 // Write the result to the ARM core register Rd, and optionally update the
14235 // condition flags based on the result.
14236 //
14237 // This helper method tries to encapsulate the following pseudocode from the
14238 // ARM Architecture Reference Manual:
14239 //
14240 // if d == 15 then // Can only occur for encoding A1
14241 // ALUWritePC(result); // setflags is always FALSE here
14242 // else
14243 // R[d] = result;
14244 // if setflags then
14245 // APSR.N = result<31>;
14246 // APSR.Z = IsZeroBit(result);
14247 // APSR.C = carry;
14248 // // APSR.V unchanged
14249 //
14250 // In the above case, the API client does not pass in the overflow arg, which
14251 // defaults to ~0u.
WriteCoreRegOptionalFlags(Context & context,const uint32_t result,const uint32_t Rd,bool setflags,const uint32_t carry,const uint32_t overflow)14252 bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
14253 Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
14254 const uint32_t carry, const uint32_t overflow) {
14255 if (Rd == 15) {
14256 if (!ALUWritePC(context, result))
14257 return false;
14258 } else {
14259 lldb::RegisterKind reg_kind;
14260 uint32_t reg_num;
14261 switch (Rd) {
14262 case SP_REG:
14263 reg_kind = eRegisterKindGeneric;
14264 reg_num = LLDB_REGNUM_GENERIC_SP;
14265 break;
14266 case LR_REG:
14267 reg_kind = eRegisterKindGeneric;
14268 reg_num = LLDB_REGNUM_GENERIC_RA;
14269 break;
14270 default:
14271 reg_kind = eRegisterKindDWARF;
14272 reg_num = dwarf_r0 + Rd;
14273 }
14274 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
14275 return false;
14276 if (setflags)
14277 return WriteFlags(context, result, carry, overflow);
14278 }
14279 return true;
14280 }
14281
14282 // This helper method tries to encapsulate the following pseudocode from the
14283 // ARM Architecture Reference Manual:
14284 //
14285 // APSR.N = result<31>;
14286 // APSR.Z = IsZeroBit(result);
14287 // APSR.C = carry;
14288 // APSR.V = overflow
14289 //
14290 // Default arguments can be specified for carry and overflow parameters, which
14291 // means not to update the respective flags.
WriteFlags(Context & context,const uint32_t result,const uint32_t carry,const uint32_t overflow)14292 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
14293 const uint32_t carry,
14294 const uint32_t overflow) {
14295 m_new_inst_cpsr = m_opcode_cpsr;
14296 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
14297 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
14298 if (carry != ~0u)
14299 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
14300 if (overflow != ~0u)
14301 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
14302 if (m_new_inst_cpsr != m_opcode_cpsr) {
14303 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14304 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14305 return false;
14306 }
14307 return true;
14308 }
14309
EvaluateInstruction(uint32_t evaluate_options)14310 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
14311 ARMOpcode *opcode_data = nullptr;
14312
14313 if (m_opcode_mode == eModeThumb)
14314 opcode_data =
14315 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14316 else if (m_opcode_mode == eModeARM)
14317 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14318
14319 const bool auto_advance_pc =
14320 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
14321 m_ignore_conditions =
14322 evaluate_options & eEmulateInstructionOptionIgnoreConditions;
14323
14324 bool success = false;
14325 if (m_opcode_cpsr == 0 || !m_ignore_conditions) {
14326 m_opcode_cpsr =
14327 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
14328 }
14329
14330 // Only return false if we are unable to read the CPSR if we care about
14331 // conditions
14332 if (!success && !m_ignore_conditions)
14333 return false;
14334
14335 uint32_t orig_pc_value = 0;
14336 if (auto_advance_pc) {
14337 orig_pc_value =
14338 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14339 if (!success)
14340 return false;
14341 }
14342
14343 // Call the Emulate... function if we managed to decode the opcode.
14344 if (opcode_data) {
14345 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
14346 opcode_data->encoding);
14347 if (!success)
14348 return false;
14349 }
14350
14351 // Advance the ITSTATE bits to their values for the next instruction if we
14352 // haven't just executed an IT instruction what initialized it.
14353 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
14354 (opcode_data == nullptr ||
14355 opcode_data->callback != &EmulateInstructionARM::EmulateIT))
14356 m_it_session.ITAdvance();
14357
14358 if (auto_advance_pc) {
14359 uint32_t after_pc_value =
14360 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14361 if (!success)
14362 return false;
14363
14364 if (after_pc_value == orig_pc_value) {
14365 after_pc_value += m_opcode.GetByteSize();
14366
14367 EmulateInstruction::Context context;
14368 context.type = eContextAdvancePC;
14369 context.SetNoArgs();
14370 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
14371 after_pc_value))
14372 return false;
14373 }
14374 }
14375 return true;
14376 }
14377
14378 EmulateInstruction::InstructionCondition
GetInstructionCondition()14379 EmulateInstructionARM::GetInstructionCondition() {
14380 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
14381 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
14382 return EmulateInstruction::UnconditionalCondition;
14383 return cond;
14384 }
14385
TestEmulation(Stream * out_stream,ArchSpec & arch,OptionValueDictionary * test_data)14386 bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch,
14387 OptionValueDictionary *test_data) {
14388 if (!test_data) {
14389 out_stream->Printf("TestEmulation: Missing test data.\n");
14390 return false;
14391 }
14392
14393 static ConstString opcode_key("opcode");
14394 static ConstString before_key("before_state");
14395 static ConstString after_key("after_state");
14396
14397 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
14398
14399 uint32_t test_opcode;
14400 if ((value_sp.get() == nullptr) ||
14401 (value_sp->GetType() != OptionValue::eTypeUInt64)) {
14402 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n");
14403 return false;
14404 }
14405 test_opcode = value_sp->GetUInt64Value();
14406
14407 if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
14408 arch.IsAlwaysThumbInstructions()) {
14409 m_opcode_mode = eModeThumb;
14410 if (test_opcode < 0x10000)
14411 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
14412 else
14413 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14414 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
14415 m_opcode_mode = eModeARM;
14416 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14417 } else {
14418 out_stream->Printf("TestEmulation: Invalid arch.\n");
14419 return false;
14420 }
14421
14422 EmulationStateARM before_state;
14423 EmulationStateARM after_state;
14424
14425 value_sp = test_data->GetValueForKey(before_key);
14426 if ((value_sp.get() == nullptr) ||
14427 (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14428 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n");
14429 return false;
14430 }
14431
14432 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
14433 if (!before_state.LoadStateFromDictionary(state_dictionary)) {
14434 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n");
14435 return false;
14436 }
14437
14438 value_sp = test_data->GetValueForKey(after_key);
14439 if ((value_sp.get() == nullptr) ||
14440 (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14441 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n");
14442 return false;
14443 }
14444
14445 state_dictionary = value_sp->GetAsDictionary();
14446 if (!after_state.LoadStateFromDictionary(state_dictionary)) {
14447 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n");
14448 return false;
14449 }
14450
14451 SetBaton((void *)&before_state);
14452 SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
14453 &EmulationStateARM::WritePseudoMemory,
14454 &EmulationStateARM::ReadPseudoRegister,
14455 &EmulationStateARM::WritePseudoRegister);
14456
14457 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
14458 if (!success) {
14459 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n");
14460 return false;
14461 }
14462
14463 success = before_state.CompareState(after_state);
14464 if (!success)
14465 out_stream->Printf(
14466 "TestEmulation: 'before' and 'after' states do not match.\n");
14467
14468 return success;
14469 }
14470 //
14471 //
14472 // const char *
14473 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
14474 //{
14475 // if (reg_kind == eRegisterKindGeneric)
14476 // {
14477 // switch (reg_num)
14478 // {
14479 // case LLDB_REGNUM_GENERIC_PC: return "pc";
14480 // case LLDB_REGNUM_GENERIC_SP: return "sp";
14481 // case LLDB_REGNUM_GENERIC_FP: return "fp";
14482 // case LLDB_REGNUM_GENERIC_RA: return "lr";
14483 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
14484 // default: return NULL;
14485 // }
14486 // }
14487 // else if (reg_kind == eRegisterKindDWARF)
14488 // {
14489 // return GetARMDWARFRegisterName (reg_num);
14490 // }
14491 // return NULL;
14492 //}
14493 //
CreateFunctionEntryUnwind(UnwindPlan & unwind_plan)14494 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
14495 unwind_plan.Clear();
14496 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
14497
14498 UnwindPlan::RowSP row(new UnwindPlan::Row);
14499
14500 // Our previous Call Frame Address is the stack pointer
14501 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
14502
14503 unwind_plan.AppendRow(row);
14504 unwind_plan.SetSourceName("EmulateInstructionARM");
14505 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
14506 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
14507 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
14508 unwind_plan.SetReturnAddressRegister(dwarf_lr);
14509 return true;
14510 }
14511