1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include <stdlib.h>
11
12 #include "EmulateInstructionARM.h"
13 #include "EmulationStateARM.h"
14 #include "lldb/Core/Address.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Host/PosixApi.h"
17 #include "lldb/Interpreter/OptionValueArray.h"
18 #include "lldb/Interpreter/OptionValueDictionary.h"
19 #include "lldb/Symbol/UnwindPlan.h"
20 #include "lldb/Utility/ArchSpec.h"
21 #include "lldb/Utility/ConstString.h"
22 #include "lldb/Utility/Stream.h"
23
24 #include "Plugins/Process/Utility/ARMDefines.h"
25 #include "Plugins/Process/Utility/ARMUtils.h"
26 #include "Utility/ARM_DWARF_Registers.h"
27
28 #include "llvm/ADT/STLExtras.h"
29 #include "llvm/Support/MathExtras.h"
30
31 using namespace lldb;
32 using namespace lldb_private;
33
34 // Convenient macro definitions.
35 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
36 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
37
38 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
39
40 //----------------------------------------------------------------------
41 //
42 // ITSession implementation
43 //
44 //----------------------------------------------------------------------
45
GetARMDWARFRegisterInfo(unsigned reg_num,RegisterInfo & reg_info)46 static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) {
47 ::memset(®_info, 0, sizeof(RegisterInfo));
48 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
49
50 if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) {
51 reg_info.byte_size = 16;
52 reg_info.format = eFormatVectorOfUInt8;
53 reg_info.encoding = eEncodingVector;
54 }
55
56 if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) {
57 reg_info.byte_size = 8;
58 reg_info.format = eFormatFloat;
59 reg_info.encoding = eEncodingIEEE754;
60 } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) {
61 reg_info.byte_size = 4;
62 reg_info.format = eFormatFloat;
63 reg_info.encoding = eEncodingIEEE754;
64 } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) {
65 reg_info.byte_size = 12;
66 reg_info.format = eFormatFloat;
67 reg_info.encoding = eEncodingIEEE754;
68 } else {
69 reg_info.byte_size = 4;
70 reg_info.format = eFormatHex;
71 reg_info.encoding = eEncodingUint;
72 }
73
74 reg_info.kinds[eRegisterKindDWARF] = reg_num;
75
76 switch (reg_num) {
77 case dwarf_r0:
78 reg_info.name = "r0";
79 break;
80 case dwarf_r1:
81 reg_info.name = "r1";
82 break;
83 case dwarf_r2:
84 reg_info.name = "r2";
85 break;
86 case dwarf_r3:
87 reg_info.name = "r3";
88 break;
89 case dwarf_r4:
90 reg_info.name = "r4";
91 break;
92 case dwarf_r5:
93 reg_info.name = "r5";
94 break;
95 case dwarf_r6:
96 reg_info.name = "r6";
97 break;
98 case dwarf_r7:
99 reg_info.name = "r7";
100 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
101 break;
102 case dwarf_r8:
103 reg_info.name = "r8";
104 break;
105 case dwarf_r9:
106 reg_info.name = "r9";
107 break;
108 case dwarf_r10:
109 reg_info.name = "r10";
110 break;
111 case dwarf_r11:
112 reg_info.name = "r11";
113 break;
114 case dwarf_r12:
115 reg_info.name = "r12";
116 break;
117 case dwarf_sp:
118 reg_info.name = "sp";
119 reg_info.alt_name = "r13";
120 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
121 break;
122 case dwarf_lr:
123 reg_info.name = "lr";
124 reg_info.alt_name = "r14";
125 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
126 break;
127 case dwarf_pc:
128 reg_info.name = "pc";
129 reg_info.alt_name = "r15";
130 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
131 break;
132 case dwarf_cpsr:
133 reg_info.name = "cpsr";
134 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
135 break;
136
137 case dwarf_s0:
138 reg_info.name = "s0";
139 break;
140 case dwarf_s1:
141 reg_info.name = "s1";
142 break;
143 case dwarf_s2:
144 reg_info.name = "s2";
145 break;
146 case dwarf_s3:
147 reg_info.name = "s3";
148 break;
149 case dwarf_s4:
150 reg_info.name = "s4";
151 break;
152 case dwarf_s5:
153 reg_info.name = "s5";
154 break;
155 case dwarf_s6:
156 reg_info.name = "s6";
157 break;
158 case dwarf_s7:
159 reg_info.name = "s7";
160 break;
161 case dwarf_s8:
162 reg_info.name = "s8";
163 break;
164 case dwarf_s9:
165 reg_info.name = "s9";
166 break;
167 case dwarf_s10:
168 reg_info.name = "s10";
169 break;
170 case dwarf_s11:
171 reg_info.name = "s11";
172 break;
173 case dwarf_s12:
174 reg_info.name = "s12";
175 break;
176 case dwarf_s13:
177 reg_info.name = "s13";
178 break;
179 case dwarf_s14:
180 reg_info.name = "s14";
181 break;
182 case dwarf_s15:
183 reg_info.name = "s15";
184 break;
185 case dwarf_s16:
186 reg_info.name = "s16";
187 break;
188 case dwarf_s17:
189 reg_info.name = "s17";
190 break;
191 case dwarf_s18:
192 reg_info.name = "s18";
193 break;
194 case dwarf_s19:
195 reg_info.name = "s19";
196 break;
197 case dwarf_s20:
198 reg_info.name = "s20";
199 break;
200 case dwarf_s21:
201 reg_info.name = "s21";
202 break;
203 case dwarf_s22:
204 reg_info.name = "s22";
205 break;
206 case dwarf_s23:
207 reg_info.name = "s23";
208 break;
209 case dwarf_s24:
210 reg_info.name = "s24";
211 break;
212 case dwarf_s25:
213 reg_info.name = "s25";
214 break;
215 case dwarf_s26:
216 reg_info.name = "s26";
217 break;
218 case dwarf_s27:
219 reg_info.name = "s27";
220 break;
221 case dwarf_s28:
222 reg_info.name = "s28";
223 break;
224 case dwarf_s29:
225 reg_info.name = "s29";
226 break;
227 case dwarf_s30:
228 reg_info.name = "s30";
229 break;
230 case dwarf_s31:
231 reg_info.name = "s31";
232 break;
233
234 // FPA Registers 0-7
235 case dwarf_f0:
236 reg_info.name = "f0";
237 break;
238 case dwarf_f1:
239 reg_info.name = "f1";
240 break;
241 case dwarf_f2:
242 reg_info.name = "f2";
243 break;
244 case dwarf_f3:
245 reg_info.name = "f3";
246 break;
247 case dwarf_f4:
248 reg_info.name = "f4";
249 break;
250 case dwarf_f5:
251 reg_info.name = "f5";
252 break;
253 case dwarf_f6:
254 reg_info.name = "f6";
255 break;
256 case dwarf_f7:
257 reg_info.name = "f7";
258 break;
259
260 // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator
261 // register 0 - 7 (they do overlap with wCGR0 - wCGR7)
262 case dwarf_wCGR0:
263 reg_info.name = "wCGR0/ACC0";
264 break;
265 case dwarf_wCGR1:
266 reg_info.name = "wCGR1/ACC1";
267 break;
268 case dwarf_wCGR2:
269 reg_info.name = "wCGR2/ACC2";
270 break;
271 case dwarf_wCGR3:
272 reg_info.name = "wCGR3/ACC3";
273 break;
274 case dwarf_wCGR4:
275 reg_info.name = "wCGR4/ACC4";
276 break;
277 case dwarf_wCGR5:
278 reg_info.name = "wCGR5/ACC5";
279 break;
280 case dwarf_wCGR6:
281 reg_info.name = "wCGR6/ACC6";
282 break;
283 case dwarf_wCGR7:
284 reg_info.name = "wCGR7/ACC7";
285 break;
286
287 // Intel wireless MMX data registers 0 - 15
288 case dwarf_wR0:
289 reg_info.name = "wR0";
290 break;
291 case dwarf_wR1:
292 reg_info.name = "wR1";
293 break;
294 case dwarf_wR2:
295 reg_info.name = "wR2";
296 break;
297 case dwarf_wR3:
298 reg_info.name = "wR3";
299 break;
300 case dwarf_wR4:
301 reg_info.name = "wR4";
302 break;
303 case dwarf_wR5:
304 reg_info.name = "wR5";
305 break;
306 case dwarf_wR6:
307 reg_info.name = "wR6";
308 break;
309 case dwarf_wR7:
310 reg_info.name = "wR7";
311 break;
312 case dwarf_wR8:
313 reg_info.name = "wR8";
314 break;
315 case dwarf_wR9:
316 reg_info.name = "wR9";
317 break;
318 case dwarf_wR10:
319 reg_info.name = "wR10";
320 break;
321 case dwarf_wR11:
322 reg_info.name = "wR11";
323 break;
324 case dwarf_wR12:
325 reg_info.name = "wR12";
326 break;
327 case dwarf_wR13:
328 reg_info.name = "wR13";
329 break;
330 case dwarf_wR14:
331 reg_info.name = "wR14";
332 break;
333 case dwarf_wR15:
334 reg_info.name = "wR15";
335 break;
336
337 case dwarf_spsr:
338 reg_info.name = "spsr";
339 break;
340 case dwarf_spsr_fiq:
341 reg_info.name = "spsr_fiq";
342 break;
343 case dwarf_spsr_irq:
344 reg_info.name = "spsr_irq";
345 break;
346 case dwarf_spsr_abt:
347 reg_info.name = "spsr_abt";
348 break;
349 case dwarf_spsr_und:
350 reg_info.name = "spsr_und";
351 break;
352 case dwarf_spsr_svc:
353 reg_info.name = "spsr_svc";
354 break;
355
356 case dwarf_r8_usr:
357 reg_info.name = "r8_usr";
358 break;
359 case dwarf_r9_usr:
360 reg_info.name = "r9_usr";
361 break;
362 case dwarf_r10_usr:
363 reg_info.name = "r10_usr";
364 break;
365 case dwarf_r11_usr:
366 reg_info.name = "r11_usr";
367 break;
368 case dwarf_r12_usr:
369 reg_info.name = "r12_usr";
370 break;
371 case dwarf_r13_usr:
372 reg_info.name = "r13_usr";
373 break;
374 case dwarf_r14_usr:
375 reg_info.name = "r14_usr";
376 break;
377 case dwarf_r8_fiq:
378 reg_info.name = "r8_fiq";
379 break;
380 case dwarf_r9_fiq:
381 reg_info.name = "r9_fiq";
382 break;
383 case dwarf_r10_fiq:
384 reg_info.name = "r10_fiq";
385 break;
386 case dwarf_r11_fiq:
387 reg_info.name = "r11_fiq";
388 break;
389 case dwarf_r12_fiq:
390 reg_info.name = "r12_fiq";
391 break;
392 case dwarf_r13_fiq:
393 reg_info.name = "r13_fiq";
394 break;
395 case dwarf_r14_fiq:
396 reg_info.name = "r14_fiq";
397 break;
398 case dwarf_r13_irq:
399 reg_info.name = "r13_irq";
400 break;
401 case dwarf_r14_irq:
402 reg_info.name = "r14_irq";
403 break;
404 case dwarf_r13_abt:
405 reg_info.name = "r13_abt";
406 break;
407 case dwarf_r14_abt:
408 reg_info.name = "r14_abt";
409 break;
410 case dwarf_r13_und:
411 reg_info.name = "r13_und";
412 break;
413 case dwarf_r14_und:
414 reg_info.name = "r14_und";
415 break;
416 case dwarf_r13_svc:
417 reg_info.name = "r13_svc";
418 break;
419 case dwarf_r14_svc:
420 reg_info.name = "r14_svc";
421 break;
422
423 // Intel wireless MMX control register in co-processor 0 - 7
424 case dwarf_wC0:
425 reg_info.name = "wC0";
426 break;
427 case dwarf_wC1:
428 reg_info.name = "wC1";
429 break;
430 case dwarf_wC2:
431 reg_info.name = "wC2";
432 break;
433 case dwarf_wC3:
434 reg_info.name = "wC3";
435 break;
436 case dwarf_wC4:
437 reg_info.name = "wC4";
438 break;
439 case dwarf_wC5:
440 reg_info.name = "wC5";
441 break;
442 case dwarf_wC6:
443 reg_info.name = "wC6";
444 break;
445 case dwarf_wC7:
446 reg_info.name = "wC7";
447 break;
448
449 // VFP-v3/Neon
450 case dwarf_d0:
451 reg_info.name = "d0";
452 break;
453 case dwarf_d1:
454 reg_info.name = "d1";
455 break;
456 case dwarf_d2:
457 reg_info.name = "d2";
458 break;
459 case dwarf_d3:
460 reg_info.name = "d3";
461 break;
462 case dwarf_d4:
463 reg_info.name = "d4";
464 break;
465 case dwarf_d5:
466 reg_info.name = "d5";
467 break;
468 case dwarf_d6:
469 reg_info.name = "d6";
470 break;
471 case dwarf_d7:
472 reg_info.name = "d7";
473 break;
474 case dwarf_d8:
475 reg_info.name = "d8";
476 break;
477 case dwarf_d9:
478 reg_info.name = "d9";
479 break;
480 case dwarf_d10:
481 reg_info.name = "d10";
482 break;
483 case dwarf_d11:
484 reg_info.name = "d11";
485 break;
486 case dwarf_d12:
487 reg_info.name = "d12";
488 break;
489 case dwarf_d13:
490 reg_info.name = "d13";
491 break;
492 case dwarf_d14:
493 reg_info.name = "d14";
494 break;
495 case dwarf_d15:
496 reg_info.name = "d15";
497 break;
498 case dwarf_d16:
499 reg_info.name = "d16";
500 break;
501 case dwarf_d17:
502 reg_info.name = "d17";
503 break;
504 case dwarf_d18:
505 reg_info.name = "d18";
506 break;
507 case dwarf_d19:
508 reg_info.name = "d19";
509 break;
510 case dwarf_d20:
511 reg_info.name = "d20";
512 break;
513 case dwarf_d21:
514 reg_info.name = "d21";
515 break;
516 case dwarf_d22:
517 reg_info.name = "d22";
518 break;
519 case dwarf_d23:
520 reg_info.name = "d23";
521 break;
522 case dwarf_d24:
523 reg_info.name = "d24";
524 break;
525 case dwarf_d25:
526 reg_info.name = "d25";
527 break;
528 case dwarf_d26:
529 reg_info.name = "d26";
530 break;
531 case dwarf_d27:
532 reg_info.name = "d27";
533 break;
534 case dwarf_d28:
535 reg_info.name = "d28";
536 break;
537 case dwarf_d29:
538 reg_info.name = "d29";
539 break;
540 case dwarf_d30:
541 reg_info.name = "d30";
542 break;
543 case dwarf_d31:
544 reg_info.name = "d31";
545 break;
546
547 // NEON 128-bit vector registers (overlays the d registers)
548 case dwarf_q0:
549 reg_info.name = "q0";
550 break;
551 case dwarf_q1:
552 reg_info.name = "q1";
553 break;
554 case dwarf_q2:
555 reg_info.name = "q2";
556 break;
557 case dwarf_q3:
558 reg_info.name = "q3";
559 break;
560 case dwarf_q4:
561 reg_info.name = "q4";
562 break;
563 case dwarf_q5:
564 reg_info.name = "q5";
565 break;
566 case dwarf_q6:
567 reg_info.name = "q6";
568 break;
569 case dwarf_q7:
570 reg_info.name = "q7";
571 break;
572 case dwarf_q8:
573 reg_info.name = "q8";
574 break;
575 case dwarf_q9:
576 reg_info.name = "q9";
577 break;
578 case dwarf_q10:
579 reg_info.name = "q10";
580 break;
581 case dwarf_q11:
582 reg_info.name = "q11";
583 break;
584 case dwarf_q12:
585 reg_info.name = "q12";
586 break;
587 case dwarf_q13:
588 reg_info.name = "q13";
589 break;
590 case dwarf_q14:
591 reg_info.name = "q14";
592 break;
593 case dwarf_q15:
594 reg_info.name = "q15";
595 break;
596
597 default:
598 return false;
599 }
600 return true;
601 }
602
603 // A8.6.50
604 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
CountITSize(uint32_t ITMask)605 static uint32_t CountITSize(uint32_t ITMask) {
606 // First count the trailing zeros of the IT mask.
607 uint32_t TZ = llvm::countTrailingZeros(ITMask);
608 if (TZ > 3) {
609 #ifdef LLDB_CONFIGURATION_DEBUG
610 printf("Encoding error: IT Mask '0000'\n");
611 #endif
612 return 0;
613 }
614 return (4 - TZ);
615 }
616
617 // Init ITState. Note that at least one bit is always 1 in mask.
InitIT(uint32_t bits7_0)618 bool ITSession::InitIT(uint32_t bits7_0) {
619 ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
620 if (ITCounter == 0)
621 return false;
622
623 // A8.6.50 IT
624 unsigned short FirstCond = Bits32(bits7_0, 7, 4);
625 if (FirstCond == 0xF) {
626 #ifdef LLDB_CONFIGURATION_DEBUG
627 printf("Encoding error: IT FirstCond '1111'\n");
628 #endif
629 return false;
630 }
631 if (FirstCond == 0xE && ITCounter != 1) {
632 #ifdef LLDB_CONFIGURATION_DEBUG
633 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
634 #endif
635 return false;
636 }
637
638 ITState = bits7_0;
639 return true;
640 }
641
642 // Update ITState if necessary.
ITAdvance()643 void ITSession::ITAdvance() {
644 // assert(ITCounter);
645 --ITCounter;
646 if (ITCounter == 0)
647 ITState = 0;
648 else {
649 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
650 SetBits32(ITState, 4, 0, NewITState4_0);
651 }
652 }
653
654 // Return true if we're inside an IT Block.
InITBlock()655 bool ITSession::InITBlock() { return ITCounter != 0; }
656
657 // Return true if we're the last instruction inside an IT Block.
LastInITBlock()658 bool ITSession::LastInITBlock() { return ITCounter == 1; }
659
660 // Get condition bits for the current thumb instruction.
GetCond()661 uint32_t ITSession::GetCond() {
662 if (InITBlock())
663 return Bits32(ITState, 7, 4);
664 else
665 return COND_AL;
666 }
667
668 // ARM constants used during decoding
669 #define REG_RD 0
670 #define LDM_REGLIST 1
671 #define SP_REG 13
672 #define LR_REG 14
673 #define PC_REG 15
674 #define PC_REGLIST_BIT 0x8000
675
676 #define ARMv4 (1u << 0)
677 #define ARMv4T (1u << 1)
678 #define ARMv5T (1u << 2)
679 #define ARMv5TE (1u << 3)
680 #define ARMv5TEJ (1u << 4)
681 #define ARMv6 (1u << 5)
682 #define ARMv6K (1u << 6)
683 #define ARMv6T2 (1u << 7)
684 #define ARMv7 (1u << 8)
685 #define ARMv7S (1u << 9)
686 #define ARMv8 (1u << 10)
687 #define ARMvAll (0xffffffffu)
688
689 #define ARMV4T_ABOVE \
690 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \
691 ARMv7S | ARMv8)
692 #define ARMV5_ABOVE \
693 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \
694 ARMv8)
695 #define ARMV5TE_ABOVE \
696 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
697 #define ARMV5J_ABOVE \
698 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
699 #define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
700 #define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
701 #define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
702
703 #define No_VFP 0
704 #define VFPv1 (1u << 1)
705 #define VFPv2 (1u << 2)
706 #define VFPv3 (1u << 3)
707 #define AdvancedSIMD (1u << 4)
708
709 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
710 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
711 #define VFPv2v3 (VFPv2 | VFPv3)
712
713 //----------------------------------------------------------------------
714 //
715 // EmulateInstructionARM implementation
716 //
717 //----------------------------------------------------------------------
718
Initialize()719 void EmulateInstructionARM::Initialize() {
720 PluginManager::RegisterPlugin(GetPluginNameStatic(),
721 GetPluginDescriptionStatic(), CreateInstance);
722 }
723
Terminate()724 void EmulateInstructionARM::Terminate() {
725 PluginManager::UnregisterPlugin(CreateInstance);
726 }
727
GetPluginNameStatic()728 ConstString EmulateInstructionARM::GetPluginNameStatic() {
729 static ConstString g_name("arm");
730 return g_name;
731 }
732
GetPluginDescriptionStatic()733 const char *EmulateInstructionARM::GetPluginDescriptionStatic() {
734 return "Emulate instructions for the ARM architecture.";
735 }
736
737 EmulateInstruction *
CreateInstance(const ArchSpec & arch,InstructionType inst_type)738 EmulateInstructionARM::CreateInstance(const ArchSpec &arch,
739 InstructionType inst_type) {
740 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(
741 inst_type)) {
742 if (arch.GetTriple().getArch() == llvm::Triple::arm) {
743 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap(
744 new EmulateInstructionARM(arch));
745
746 if (emulate_insn_ap.get())
747 return emulate_insn_ap.release();
748 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) {
749 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap(
750 new EmulateInstructionARM(arch));
751
752 if (emulate_insn_ap.get())
753 return emulate_insn_ap.release();
754 }
755 }
756
757 return NULL;
758 }
759
SetTargetTriple(const ArchSpec & arch)760 bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) {
761 if (arch.GetTriple().getArch() == llvm::Triple::arm)
762 return true;
763 else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
764 return true;
765
766 return false;
767 }
768
769 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for
770 // many ARM instructions.
WriteBits32UnknownToMemory(addr_t address)771 bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) {
772 EmulateInstruction::Context context;
773 context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
774 context.SetNoArgs();
775
776 uint32_t random_data = rand();
777 const uint32_t addr_byte_size = GetAddressByteSize();
778
779 return MemAWrite(context, address, random_data, addr_byte_size);
780 }
781
782 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM
783 // instructions.
WriteBits32Unknown(int n)784 bool EmulateInstructionARM::WriteBits32Unknown(int n) {
785 EmulateInstruction::Context context;
786 context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
787 context.SetNoArgs();
788
789 bool success;
790 uint32_t data =
791 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
792
793 if (!success)
794 return false;
795
796 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data))
797 return false;
798
799 return true;
800 }
801
GetRegisterInfo(lldb::RegisterKind reg_kind,uint32_t reg_num,RegisterInfo & reg_info)802 bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind,
803 uint32_t reg_num,
804 RegisterInfo ®_info) {
805 if (reg_kind == eRegisterKindGeneric) {
806 switch (reg_num) {
807 case LLDB_REGNUM_GENERIC_PC:
808 reg_kind = eRegisterKindDWARF;
809 reg_num = dwarf_pc;
810 break;
811 case LLDB_REGNUM_GENERIC_SP:
812 reg_kind = eRegisterKindDWARF;
813 reg_num = dwarf_sp;
814 break;
815 case LLDB_REGNUM_GENERIC_FP:
816 reg_kind = eRegisterKindDWARF;
817 reg_num = dwarf_r7;
818 break;
819 case LLDB_REGNUM_GENERIC_RA:
820 reg_kind = eRegisterKindDWARF;
821 reg_num = dwarf_lr;
822 break;
823 case LLDB_REGNUM_GENERIC_FLAGS:
824 reg_kind = eRegisterKindDWARF;
825 reg_num = dwarf_cpsr;
826 break;
827 default:
828 return false;
829 }
830 }
831
832 if (reg_kind == eRegisterKindDWARF)
833 return GetARMDWARFRegisterInfo(reg_num, reg_info);
834 return false;
835 }
836
GetFramePointerRegisterNumber() const837 uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
838 if (m_arch.GetTriple().isAndroid())
839 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
840 bool is_apple = false;
841 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
842 is_apple = true;
843 switch (m_arch.GetTriple().getOS()) {
844 case llvm::Triple::Darwin:
845 case llvm::Triple::MacOSX:
846 case llvm::Triple::IOS:
847 case llvm::Triple::TvOS:
848 case llvm::Triple::WatchOS:
849 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
850 is_apple = true;
851 break;
852 default:
853 break;
854 }
855
856 /* On Apple iOS et al, the frame pointer register is always r7.
857 * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
858 */
859
860 uint32_t fp_regnum = 11;
861
862 if (is_apple)
863 fp_regnum = 7;
864
865 if (m_opcode_mode == eModeThumb)
866 fp_regnum = 7;
867
868 return fp_regnum;
869 }
870
GetFramePointerDWARFRegisterNumber() const871 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
872 bool is_apple = false;
873 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
874 is_apple = true;
875 switch (m_arch.GetTriple().getOS()) {
876 case llvm::Triple::Darwin:
877 case llvm::Triple::MacOSX:
878 case llvm::Triple::IOS:
879 is_apple = true;
880 break;
881 default:
882 break;
883 }
884
885 /* On Apple iOS et al, the frame pointer register is always r7.
886 * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
887 */
888
889 uint32_t fp_regnum = dwarf_r11;
890
891 if (is_apple)
892 fp_regnum = dwarf_r7;
893
894 if (m_opcode_mode == eModeThumb)
895 fp_regnum = dwarf_r7;
896
897 return fp_regnum;
898 }
899
900 // Push Multiple Registers stores multiple registers to the stack, storing to
901 // consecutive memory locations ending just below the address in SP, and
902 // updates
903 // SP to point to the start of the stored data.
EmulatePUSH(const uint32_t opcode,const ARMEncoding encoding)904 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
905 const ARMEncoding encoding) {
906 #if 0
907 // ARM pseudo code...
908 if (ConditionPassed())
909 {
910 EncodingSpecificOperations();
911 NullCheckIfThumbEE(13);
912 address = SP - 4*BitCount(registers);
913
914 for (i = 0 to 14)
915 {
916 if (registers<i> == '1')
917 {
918 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
919 MemA[address,4] = bits(32) UNKNOWN;
920 else
921 MemA[address,4] = R[i];
922 address = address + 4;
923 }
924 }
925
926 if (registers<15> == '1') // Only possible for encoding A1 or A2
927 MemA[address,4] = PCStoreValue();
928
929 SP = SP - 4*BitCount(registers);
930 }
931 #endif
932
933 bool success = false;
934 if (ConditionPassed(opcode)) {
935 const uint32_t addr_byte_size = GetAddressByteSize();
936 const addr_t sp = ReadCoreReg(SP_REG, &success);
937 if (!success)
938 return false;
939 uint32_t registers = 0;
940 uint32_t Rt; // the source register
941 switch (encoding) {
942 case eEncodingT1:
943 registers = Bits32(opcode, 7, 0);
944 // The M bit represents LR.
945 if (Bit32(opcode, 8))
946 registers |= (1u << 14);
947 // if BitCount(registers) < 1 then UNPREDICTABLE;
948 if (BitCount(registers) < 1)
949 return false;
950 break;
951 case eEncodingT2:
952 // Ignore bits 15 & 13.
953 registers = Bits32(opcode, 15, 0) & ~0xa000;
954 // if BitCount(registers) < 2 then UNPREDICTABLE;
955 if (BitCount(registers) < 2)
956 return false;
957 break;
958 case eEncodingT3:
959 Rt = Bits32(opcode, 15, 12);
960 // if BadReg(t) then UNPREDICTABLE;
961 if (BadReg(Rt))
962 return false;
963 registers = (1u << Rt);
964 break;
965 case eEncodingA1:
966 registers = Bits32(opcode, 15, 0);
967 // Instead of return false, let's handle the following case as well,
968 // which amounts to pushing one reg onto the full descending stacks.
969 // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
970 break;
971 case eEncodingA2:
972 Rt = Bits32(opcode, 15, 12);
973 // if t == 13 then UNPREDICTABLE;
974 if (Rt == dwarf_sp)
975 return false;
976 registers = (1u << Rt);
977 break;
978 default:
979 return false;
980 }
981 addr_t sp_offset = addr_byte_size * BitCount(registers);
982 addr_t addr = sp - sp_offset;
983 uint32_t i;
984
985 EmulateInstruction::Context context;
986 context.type = EmulateInstruction::eContextPushRegisterOnStack;
987 RegisterInfo reg_info;
988 RegisterInfo sp_reg;
989 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
990 for (i = 0; i < 15; ++i) {
991 if (BitIsSet(registers, i)) {
992 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info);
993 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
994 uint32_t reg_value = ReadCoreReg(i, &success);
995 if (!success)
996 return false;
997 if (!MemAWrite(context, addr, reg_value, addr_byte_size))
998 return false;
999 addr += addr_byte_size;
1000 }
1001 }
1002
1003 if (BitIsSet(registers, 15)) {
1004 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info);
1005 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
1006 const uint32_t pc = ReadCoreReg(PC_REG, &success);
1007 if (!success)
1008 return false;
1009 if (!MemAWrite(context, addr, pc, addr_byte_size))
1010 return false;
1011 }
1012
1013 context.type = EmulateInstruction::eContextAdjustStackPointer;
1014 context.SetImmediateSigned(-sp_offset);
1015
1016 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1017 LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1018 return false;
1019 }
1020 return true;
1021 }
1022
1023 // Pop Multiple Registers loads multiple registers from the stack, loading from
1024 // consecutive memory locations staring at the address in SP, and updates
1025 // SP to point just above the loaded data.
EmulatePOP(const uint32_t opcode,const ARMEncoding encoding)1026 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
1027 const ARMEncoding encoding) {
1028 #if 0
1029 // ARM pseudo code...
1030 if (ConditionPassed())
1031 {
1032 EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1033 address = SP;
1034 for i = 0 to 14
1035 if registers<i> == '1' then
1036 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
1037 if registers<15> == '1' then
1038 if UnalignedAllowed then
1039 LoadWritePC(MemU[address,4]);
1040 else
1041 LoadWritePC(MemA[address,4]);
1042 if registers<13> == '0' then SP = SP + 4*BitCount(registers);
1043 if registers<13> == '1' then SP = bits(32) UNKNOWN;
1044 }
1045 #endif
1046
1047 bool success = false;
1048
1049 if (ConditionPassed(opcode)) {
1050 const uint32_t addr_byte_size = GetAddressByteSize();
1051 const addr_t sp = ReadCoreReg(SP_REG, &success);
1052 if (!success)
1053 return false;
1054 uint32_t registers = 0;
1055 uint32_t Rt; // the destination register
1056 switch (encoding) {
1057 case eEncodingT1:
1058 registers = Bits32(opcode, 7, 0);
1059 // The P bit represents PC.
1060 if (Bit32(opcode, 8))
1061 registers |= (1u << 15);
1062 // if BitCount(registers) < 1 then UNPREDICTABLE;
1063 if (BitCount(registers) < 1)
1064 return false;
1065 break;
1066 case eEncodingT2:
1067 // Ignore bit 13.
1068 registers = Bits32(opcode, 15, 0) & ~0x2000;
1069 // if BitCount(registers) < 2 || (P == '1' && M == '1') then
1070 // UNPREDICTABLE;
1071 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
1072 return false;
1073 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
1074 // UNPREDICTABLE;
1075 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1076 return false;
1077 break;
1078 case eEncodingT3:
1079 Rt = Bits32(opcode, 15, 12);
1080 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
1081 // UNPREDICTABLE;
1082 if (Rt == 13)
1083 return false;
1084 if (Rt == 15 && InITBlock() && !LastInITBlock())
1085 return false;
1086 registers = (1u << Rt);
1087 break;
1088 case eEncodingA1:
1089 registers = Bits32(opcode, 15, 0);
1090 // Instead of return false, let's handle the following case as well,
1091 // which amounts to popping one reg from the full descending stacks.
1092 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
1093
1094 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
1095 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
1096 return false;
1097 break;
1098 case eEncodingA2:
1099 Rt = Bits32(opcode, 15, 12);
1100 // if t == 13 then UNPREDICTABLE;
1101 if (Rt == dwarf_sp)
1102 return false;
1103 registers = (1u << Rt);
1104 break;
1105 default:
1106 return false;
1107 }
1108 addr_t sp_offset = addr_byte_size * BitCount(registers);
1109 addr_t addr = sp;
1110 uint32_t i, data;
1111
1112 EmulateInstruction::Context context;
1113 context.type = EmulateInstruction::eContextPopRegisterOffStack;
1114
1115 RegisterInfo sp_reg;
1116 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1117
1118 for (i = 0; i < 15; ++i) {
1119 if (BitIsSet(registers, i)) {
1120 context.SetAddress(addr);
1121 data = MemARead(context, addr, 4, 0, &success);
1122 if (!success)
1123 return false;
1124 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
1125 data))
1126 return false;
1127 addr += addr_byte_size;
1128 }
1129 }
1130
1131 if (BitIsSet(registers, 15)) {
1132 context.SetRegisterPlusOffset(sp_reg, addr - sp);
1133 data = MemARead(context, addr, 4, 0, &success);
1134 if (!success)
1135 return false;
1136 // In ARMv5T and above, this is an interworking branch.
1137 if (!LoadWritePC(context, data))
1138 return false;
1139 // addr += addr_byte_size;
1140 }
1141
1142 context.type = EmulateInstruction::eContextAdjustStackPointer;
1143 context.SetImmediateSigned(sp_offset);
1144
1145 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1146 LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1147 return false;
1148 }
1149 return true;
1150 }
1151
1152 // Set r7 or ip to point to saved value residing within the stack.
1153 // ADD (SP plus immediate)
EmulateADDRdSPImm(const uint32_t opcode,const ARMEncoding encoding)1154 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
1155 const ARMEncoding encoding) {
1156 #if 0
1157 // ARM pseudo code...
1158 if (ConditionPassed())
1159 {
1160 EncodingSpecificOperations();
1161 (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1162 if d == 15 then
1163 ALUWritePC(result); // setflags is always FALSE here
1164 else
1165 R[d] = result;
1166 if setflags then
1167 APSR.N = result<31>;
1168 APSR.Z = IsZeroBit(result);
1169 APSR.C = carry;
1170 APSR.V = overflow;
1171 }
1172 #endif
1173
1174 bool success = false;
1175
1176 if (ConditionPassed(opcode)) {
1177 const addr_t sp = ReadCoreReg(SP_REG, &success);
1178 if (!success)
1179 return false;
1180 uint32_t Rd; // the destination register
1181 uint32_t imm32;
1182 switch (encoding) {
1183 case eEncodingT1:
1184 Rd = 7;
1185 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
1186 break;
1187 case eEncodingA1:
1188 Rd = Bits32(opcode, 15, 12);
1189 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1190 break;
1191 default:
1192 return false;
1193 }
1194 addr_t sp_offset = imm32;
1195 addr_t addr = sp + sp_offset; // a pointer to the stack area
1196
1197 EmulateInstruction::Context context;
1198 if (Rd == GetFramePointerRegisterNumber())
1199 context.type = eContextSetFramePointer;
1200 else
1201 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1202 RegisterInfo sp_reg;
1203 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1204 context.SetRegisterPlusOffset(sp_reg, sp_offset);
1205
1206 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
1207 addr))
1208 return false;
1209 }
1210 return true;
1211 }
1212
1213 // Set r7 or ip to the current stack pointer.
1214 // MOV (register)
EmulateMOVRdSP(const uint32_t opcode,const ARMEncoding encoding)1215 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
1216 const ARMEncoding encoding) {
1217 #if 0
1218 // ARM pseudo code...
1219 if (ConditionPassed())
1220 {
1221 EncodingSpecificOperations();
1222 result = R[m];
1223 if d == 15 then
1224 ALUWritePC(result); // setflags is always FALSE here
1225 else
1226 R[d] = result;
1227 if setflags then
1228 APSR.N = result<31>;
1229 APSR.Z = IsZeroBit(result);
1230 // APSR.C unchanged
1231 // APSR.V unchanged
1232 }
1233 #endif
1234
1235 bool success = false;
1236
1237 if (ConditionPassed(opcode)) {
1238 const addr_t sp = ReadCoreReg(SP_REG, &success);
1239 if (!success)
1240 return false;
1241 uint32_t Rd; // the destination register
1242 switch (encoding) {
1243 case eEncodingT1:
1244 Rd = 7;
1245 break;
1246 case eEncodingA1:
1247 Rd = 12;
1248 break;
1249 default:
1250 return false;
1251 }
1252
1253 EmulateInstruction::Context context;
1254 if (Rd == GetFramePointerRegisterNumber())
1255 context.type = EmulateInstruction::eContextSetFramePointer;
1256 else
1257 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1258 RegisterInfo sp_reg;
1259 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1260 context.SetRegisterPlusOffset(sp_reg, 0);
1261
1262 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
1263 return false;
1264 }
1265 return true;
1266 }
1267
1268 // Move from high register (r8-r15) to low register (r0-r7).
1269 // MOV (register)
EmulateMOVLowHigh(const uint32_t opcode,const ARMEncoding encoding)1270 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
1271 const ARMEncoding encoding) {
1272 return EmulateMOVRdRm(opcode, encoding);
1273 }
1274
1275 // Move from register to register.
1276 // MOV (register)
EmulateMOVRdRm(const uint32_t opcode,const ARMEncoding encoding)1277 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
1278 const ARMEncoding encoding) {
1279 #if 0
1280 // ARM pseudo code...
1281 if (ConditionPassed())
1282 {
1283 EncodingSpecificOperations();
1284 result = R[m];
1285 if d == 15 then
1286 ALUWritePC(result); // setflags is always FALSE here
1287 else
1288 R[d] = result;
1289 if setflags then
1290 APSR.N = result<31>;
1291 APSR.Z = IsZeroBit(result);
1292 // APSR.C unchanged
1293 // APSR.V unchanged
1294 }
1295 #endif
1296
1297 bool success = false;
1298
1299 if (ConditionPassed(opcode)) {
1300 uint32_t Rm; // the source register
1301 uint32_t Rd; // the destination register
1302 bool setflags;
1303 switch (encoding) {
1304 case eEncodingT1:
1305 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1306 Rm = Bits32(opcode, 6, 3);
1307 setflags = false;
1308 if (Rd == 15 && InITBlock() && !LastInITBlock())
1309 return false;
1310 break;
1311 case eEncodingT2:
1312 Rd = Bits32(opcode, 2, 0);
1313 Rm = Bits32(opcode, 5, 3);
1314 setflags = true;
1315 if (InITBlock())
1316 return false;
1317 break;
1318 case eEncodingT3:
1319 Rd = Bits32(opcode, 11, 8);
1320 Rm = Bits32(opcode, 3, 0);
1321 setflags = BitIsSet(opcode, 20);
1322 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1323 if (setflags && (BadReg(Rd) || BadReg(Rm)))
1324 return false;
1325 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
1326 // UNPREDICTABLE;
1327 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1328 return false;
1329 break;
1330 case eEncodingA1:
1331 Rd = Bits32(opcode, 15, 12);
1332 Rm = Bits32(opcode, 3, 0);
1333 setflags = BitIsSet(opcode, 20);
1334
1335 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1336 // instructions;
1337 if (Rd == 15 && setflags)
1338 return EmulateSUBSPcLrEtc(opcode, encoding);
1339 break;
1340 default:
1341 return false;
1342 }
1343 uint32_t result = ReadCoreReg(Rm, &success);
1344 if (!success)
1345 return false;
1346
1347 // The context specifies that Rm is to be moved into Rd.
1348 EmulateInstruction::Context context;
1349 if (Rd == 13)
1350 context.type = EmulateInstruction::eContextAdjustStackPointer;
1351 else
1352 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1353 RegisterInfo dwarf_reg;
1354 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1355 context.SetRegisterPlusOffset(dwarf_reg, 0);
1356
1357 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1358 return false;
1359 }
1360 return true;
1361 }
1362
1363 // Move (immediate) writes an immediate value to the destination register. It
1364 // can optionally update the condition flags based on the value.
1365 // MOV (immediate)
EmulateMOVRdImm(const uint32_t opcode,const ARMEncoding encoding)1366 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
1367 const ARMEncoding encoding) {
1368 #if 0
1369 // ARM pseudo code...
1370 if (ConditionPassed())
1371 {
1372 EncodingSpecificOperations();
1373 result = imm32;
1374 if d == 15 then // Can only occur for ARM encoding
1375 ALUWritePC(result); // setflags is always FALSE here
1376 else
1377 R[d] = result;
1378 if setflags then
1379 APSR.N = result<31>;
1380 APSR.Z = IsZeroBit(result);
1381 APSR.C = carry;
1382 // APSR.V unchanged
1383 }
1384 #endif
1385
1386 if (ConditionPassed(opcode)) {
1387 uint32_t Rd; // the destination register
1388 uint32_t imm32; // the immediate value to be written to Rd
1389 uint32_t carry =
1390 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
1391 // for setflags == false, this value is a don't care initialized to
1392 // 0 to silence the static analyzer
1393 bool setflags;
1394 switch (encoding) {
1395 case eEncodingT1:
1396 Rd = Bits32(opcode, 10, 8);
1397 setflags = !InITBlock();
1398 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
1399 carry = APSR_C;
1400
1401 break;
1402
1403 case eEncodingT2:
1404 Rd = Bits32(opcode, 11, 8);
1405 setflags = BitIsSet(opcode, 20);
1406 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1407 if (BadReg(Rd))
1408 return false;
1409
1410 break;
1411
1412 case eEncodingT3: {
1413 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
1414 // 32);
1415 Rd = Bits32(opcode, 11, 8);
1416 setflags = false;
1417 uint32_t imm4 = Bits32(opcode, 19, 16);
1418 uint32_t imm3 = Bits32(opcode, 14, 12);
1419 uint32_t i = Bit32(opcode, 26);
1420 uint32_t imm8 = Bits32(opcode, 7, 0);
1421 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1422
1423 // if BadReg(d) then UNPREDICTABLE;
1424 if (BadReg(Rd))
1425 return false;
1426 } break;
1427
1428 case eEncodingA1:
1429 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
1430 // ARMExpandImm_C(imm12, APSR.C);
1431 Rd = Bits32(opcode, 15, 12);
1432 setflags = BitIsSet(opcode, 20);
1433 imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1434
1435 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1436 // instructions;
1437 if ((Rd == 15) && setflags)
1438 return EmulateSUBSPcLrEtc(opcode, encoding);
1439
1440 break;
1441
1442 case eEncodingA2: {
1443 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
1444 Rd = Bits32(opcode, 15, 12);
1445 setflags = false;
1446 uint32_t imm4 = Bits32(opcode, 19, 16);
1447 uint32_t imm12 = Bits32(opcode, 11, 0);
1448 imm32 = (imm4 << 12) | imm12;
1449
1450 // if d == 15 then UNPREDICTABLE;
1451 if (Rd == 15)
1452 return false;
1453 } break;
1454
1455 default:
1456 return false;
1457 }
1458 uint32_t result = imm32;
1459
1460 // The context specifies that an immediate is to be moved into Rd.
1461 EmulateInstruction::Context context;
1462 context.type = EmulateInstruction::eContextImmediate;
1463 context.SetNoArgs();
1464
1465 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1466 return false;
1467 }
1468 return true;
1469 }
1470
1471 // MUL multiplies two register values. The least significant 32 bits of the
1472 // result are written to the destination
1473 // register. These 32 bits do not depend on whether the source register values
1474 // are considered to be signed values or unsigned values.
1475 //
1476 // Optionally, it can update the condition flags based on the result. In the
1477 // Thumb instruction set, this option is limited to only a few forms of the
1478 // instruction.
EmulateMUL(const uint32_t opcode,const ARMEncoding encoding)1479 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
1480 const ARMEncoding encoding) {
1481 #if 0
1482 if ConditionPassed() then
1483 EncodingSpecificOperations();
1484 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1485 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1486 result = operand1 * operand2;
1487 R[d] = result<31:0>;
1488 if setflags then
1489 APSR.N = result<31>;
1490 APSR.Z = IsZeroBit(result);
1491 if ArchVersion() == 4 then
1492 APSR.C = bit UNKNOWN;
1493 // else APSR.C unchanged
1494 // APSR.V always unchanged
1495 #endif
1496
1497 if (ConditionPassed(opcode)) {
1498 uint32_t d;
1499 uint32_t n;
1500 uint32_t m;
1501 bool setflags;
1502
1503 // EncodingSpecificOperations();
1504 switch (encoding) {
1505 case eEncodingT1:
1506 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
1507 d = Bits32(opcode, 2, 0);
1508 n = Bits32(opcode, 5, 3);
1509 m = Bits32(opcode, 2, 0);
1510 setflags = !InITBlock();
1511
1512 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1513 if ((ArchVersion() < ARMv6) && (d == n))
1514 return false;
1515
1516 break;
1517
1518 case eEncodingT2:
1519 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
1520 d = Bits32(opcode, 11, 8);
1521 n = Bits32(opcode, 19, 16);
1522 m = Bits32(opcode, 3, 0);
1523 setflags = false;
1524
1525 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1526 if (BadReg(d) || BadReg(n) || BadReg(m))
1527 return false;
1528
1529 break;
1530
1531 case eEncodingA1:
1532 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1533 d = Bits32(opcode, 19, 16);
1534 n = Bits32(opcode, 3, 0);
1535 m = Bits32(opcode, 11, 8);
1536 setflags = BitIsSet(opcode, 20);
1537
1538 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1539 if ((d == 15) || (n == 15) || (m == 15))
1540 return false;
1541
1542 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1543 if ((ArchVersion() < ARMv6) && (d == n))
1544 return false;
1545
1546 break;
1547
1548 default:
1549 return false;
1550 }
1551
1552 bool success = false;
1553
1554 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1555 // results
1556 uint64_t operand1 =
1557 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1558 if (!success)
1559 return false;
1560
1561 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1562 // results
1563 uint64_t operand2 =
1564 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1565 if (!success)
1566 return false;
1567
1568 // result = operand1 * operand2;
1569 uint64_t result = operand1 * operand2;
1570
1571 // R[d] = result<31:0>;
1572 RegisterInfo op1_reg;
1573 RegisterInfo op2_reg;
1574 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1575 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1576
1577 EmulateInstruction::Context context;
1578 context.type = eContextArithmetic;
1579 context.SetRegisterRegisterOperands(op1_reg, op2_reg);
1580
1581 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
1582 (0x0000ffff & result)))
1583 return false;
1584
1585 // if setflags then
1586 if (setflags) {
1587 // APSR.N = result<31>;
1588 // APSR.Z = IsZeroBit(result);
1589 m_new_inst_cpsr = m_opcode_cpsr;
1590 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
1591 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1592 if (m_new_inst_cpsr != m_opcode_cpsr) {
1593 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1594 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1595 return false;
1596 }
1597
1598 // if ArchVersion() == 4 then
1599 // APSR.C = bit UNKNOWN;
1600 }
1601 }
1602 return true;
1603 }
1604
1605 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1606 // the destination register. It can optionally update the condition flags based
1607 // on the value.
EmulateMVNImm(const uint32_t opcode,const ARMEncoding encoding)1608 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1609 const ARMEncoding encoding) {
1610 #if 0
1611 // ARM pseudo code...
1612 if (ConditionPassed())
1613 {
1614 EncodingSpecificOperations();
1615 result = NOT(imm32);
1616 if d == 15 then // Can only occur for ARM encoding
1617 ALUWritePC(result); // setflags is always FALSE here
1618 else
1619 R[d] = result;
1620 if setflags then
1621 APSR.N = result<31>;
1622 APSR.Z = IsZeroBit(result);
1623 APSR.C = carry;
1624 // APSR.V unchanged
1625 }
1626 #endif
1627
1628 if (ConditionPassed(opcode)) {
1629 uint32_t Rd; // the destination register
1630 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1631 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1632 bool setflags;
1633 switch (encoding) {
1634 case eEncodingT1:
1635 Rd = Bits32(opcode, 11, 8);
1636 setflags = BitIsSet(opcode, 20);
1637 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1638 break;
1639 case eEncodingA1:
1640 Rd = Bits32(opcode, 15, 12);
1641 setflags = BitIsSet(opcode, 20);
1642 imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1643
1644 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1645 // instructions;
1646 if (Rd == 15 && setflags)
1647 return EmulateSUBSPcLrEtc(opcode, encoding);
1648 break;
1649 default:
1650 return false;
1651 }
1652 uint32_t result = ~imm32;
1653
1654 // The context specifies that an immediate is to be moved into Rd.
1655 EmulateInstruction::Context context;
1656 context.type = EmulateInstruction::eContextImmediate;
1657 context.SetNoArgs();
1658
1659 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1660 return false;
1661 }
1662 return true;
1663 }
1664
1665 // Bitwise NOT (register) writes the bitwise inverse of a register value to the
1666 // destination register. It can optionally update the condition flags based on
1667 // the result.
EmulateMVNReg(const uint32_t opcode,const ARMEncoding encoding)1668 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1669 const ARMEncoding encoding) {
1670 #if 0
1671 // ARM pseudo code...
1672 if (ConditionPassed())
1673 {
1674 EncodingSpecificOperations();
1675 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1676 result = NOT(shifted);
1677 if d == 15 then // Can only occur for ARM encoding
1678 ALUWritePC(result); // setflags is always FALSE here
1679 else
1680 R[d] = result;
1681 if setflags then
1682 APSR.N = result<31>;
1683 APSR.Z = IsZeroBit(result);
1684 APSR.C = carry;
1685 // APSR.V unchanged
1686 }
1687 #endif
1688
1689 if (ConditionPassed(opcode)) {
1690 uint32_t Rm; // the source register
1691 uint32_t Rd; // the destination register
1692 ARM_ShifterType shift_t;
1693 uint32_t shift_n; // the shift applied to the value read from Rm
1694 bool setflags;
1695 uint32_t carry; // the carry bit after the shift operation
1696 switch (encoding) {
1697 case eEncodingT1:
1698 Rd = Bits32(opcode, 2, 0);
1699 Rm = Bits32(opcode, 5, 3);
1700 setflags = !InITBlock();
1701 shift_t = SRType_LSL;
1702 shift_n = 0;
1703 if (InITBlock())
1704 return false;
1705 break;
1706 case eEncodingT2:
1707 Rd = Bits32(opcode, 11, 8);
1708 Rm = Bits32(opcode, 3, 0);
1709 setflags = BitIsSet(opcode, 20);
1710 shift_n = DecodeImmShiftThumb(opcode, shift_t);
1711 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1712 if (BadReg(Rd) || BadReg(Rm))
1713 return false;
1714 break;
1715 case eEncodingA1:
1716 Rd = Bits32(opcode, 15, 12);
1717 Rm = Bits32(opcode, 3, 0);
1718 setflags = BitIsSet(opcode, 20);
1719 shift_n = DecodeImmShiftARM(opcode, shift_t);
1720 break;
1721 default:
1722 return false;
1723 }
1724 bool success = false;
1725 uint32_t value = ReadCoreReg(Rm, &success);
1726 if (!success)
1727 return false;
1728
1729 uint32_t shifted =
1730 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1731 if (!success)
1732 return false;
1733 uint32_t result = ~shifted;
1734
1735 // The context specifies that an immediate is to be moved into Rd.
1736 EmulateInstruction::Context context;
1737 context.type = EmulateInstruction::eContextImmediate;
1738 context.SetNoArgs();
1739
1740 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1741 return false;
1742 }
1743 return true;
1744 }
1745
1746 // PC relative immediate load into register, possibly followed by ADD (SP plus
1747 // register).
1748 // LDR (literal)
EmulateLDRRtPCRelative(const uint32_t opcode,const ARMEncoding encoding)1749 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
1750 const ARMEncoding encoding) {
1751 #if 0
1752 // ARM pseudo code...
1753 if (ConditionPassed())
1754 {
1755 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1756 base = Align(PC,4);
1757 address = if add then (base + imm32) else (base - imm32);
1758 data = MemU[address,4];
1759 if t == 15 then
1760 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1761 elsif UnalignedSupport() || address<1:0> = '00' then
1762 R[t] = data;
1763 else // Can only apply before ARMv7
1764 if CurrentInstrSet() == InstrSet_ARM then
1765 R[t] = ROR(data, 8*UInt(address<1:0>));
1766 else
1767 R[t] = bits(32) UNKNOWN;
1768 }
1769 #endif
1770
1771 if (ConditionPassed(opcode)) {
1772 bool success = false;
1773 const uint32_t pc = ReadCoreReg(PC_REG, &success);
1774 if (!success)
1775 return false;
1776
1777 // PC relative immediate load context
1778 EmulateInstruction::Context context;
1779 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1780 RegisterInfo pc_reg;
1781 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
1782 context.SetRegisterPlusOffset(pc_reg, 0);
1783
1784 uint32_t Rt; // the destination register
1785 uint32_t imm32; // immediate offset from the PC
1786 bool add; // +imm32 or -imm32?
1787 addr_t base; // the base address
1788 addr_t address; // the PC relative address
1789 uint32_t data; // the literal data value from the PC relative load
1790 switch (encoding) {
1791 case eEncodingT1:
1792 Rt = Bits32(opcode, 10, 8);
1793 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1794 add = true;
1795 break;
1796 case eEncodingT2:
1797 Rt = Bits32(opcode, 15, 12);
1798 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1799 add = BitIsSet(opcode, 23);
1800 if (Rt == 15 && InITBlock() && !LastInITBlock())
1801 return false;
1802 break;
1803 default:
1804 return false;
1805 }
1806
1807 base = Align(pc, 4);
1808 if (add)
1809 address = base + imm32;
1810 else
1811 address = base - imm32;
1812
1813 context.SetRegisterPlusOffset(pc_reg, address - base);
1814 data = MemURead(context, address, 4, 0, &success);
1815 if (!success)
1816 return false;
1817
1818 if (Rt == 15) {
1819 if (Bits32(address, 1, 0) == 0) {
1820 // In ARMv5T and above, this is an interworking branch.
1821 if (!LoadWritePC(context, data))
1822 return false;
1823 } else
1824 return false;
1825 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1826 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
1827 data))
1828 return false;
1829 } else // We don't handle ARM for now.
1830 return false;
1831 }
1832 return true;
1833 }
1834
1835 // An add operation to adjust the SP.
1836 // ADD (SP plus immediate)
EmulateADDSPImm(const uint32_t opcode,const ARMEncoding encoding)1837 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
1838 const ARMEncoding encoding) {
1839 #if 0
1840 // ARM pseudo code...
1841 if (ConditionPassed())
1842 {
1843 EncodingSpecificOperations();
1844 (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1845 if d == 15 then // Can only occur for ARM encoding
1846 ALUWritePC(result); // setflags is always FALSE here
1847 else
1848 R[d] = result;
1849 if setflags then
1850 APSR.N = result<31>;
1851 APSR.Z = IsZeroBit(result);
1852 APSR.C = carry;
1853 APSR.V = overflow;
1854 }
1855 #endif
1856
1857 bool success = false;
1858
1859 if (ConditionPassed(opcode)) {
1860 const addr_t sp = ReadCoreReg(SP_REG, &success);
1861 if (!success)
1862 return false;
1863 uint32_t imm32; // the immediate operand
1864 uint32_t d;
1865 bool setflags;
1866 switch (encoding) {
1867 case eEncodingT1:
1868 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1869 d = Bits32(opcode, 10, 8);
1870 imm32 = (Bits32(opcode, 7, 0) << 2);
1871 setflags = false;
1872 break;
1873
1874 case eEncodingT2:
1875 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1876 d = 13;
1877 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1878 setflags = false;
1879 break;
1880
1881 case eEncodingT3:
1882 // d = UInt(Rd); setflags = (S == "1"); imm32 =
1883 // ThumbExpandImm(i:imm3:imm8);
1884 d = Bits32(opcode, 11, 8);
1885 imm32 = ThumbExpandImm(opcode);
1886 setflags = Bit32(opcode, 20);
1887
1888 // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1889 if (d == 15 && setflags == 1)
1890 return false; // CMN (immediate) not yet supported
1891
1892 // if d == 15 && S == "0" then UNPREDICTABLE;
1893 if (d == 15 && setflags == 0)
1894 return false;
1895 break;
1896
1897 case eEncodingT4: {
1898 // if Rn == '1111' then SEE ADR;
1899 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1900 d = Bits32(opcode, 11, 8);
1901 setflags = false;
1902 uint32_t i = Bit32(opcode, 26);
1903 uint32_t imm3 = Bits32(opcode, 14, 12);
1904 uint32_t imm8 = Bits32(opcode, 7, 0);
1905 imm32 = (i << 11) | (imm3 << 8) | imm8;
1906
1907 // if d == 15 then UNPREDICTABLE;
1908 if (d == 15)
1909 return false;
1910 } break;
1911
1912 default:
1913 return false;
1914 }
1915 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1916 AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1917
1918 EmulateInstruction::Context context;
1919 if (d == 13)
1920 context.type = EmulateInstruction::eContextAdjustStackPointer;
1921 else
1922 context.type = EmulateInstruction::eContextRegisterPlusOffset;
1923
1924 RegisterInfo sp_reg;
1925 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1926 context.SetRegisterPlusOffset(sp_reg, res.result - sp);
1927
1928 if (d == 15) {
1929 if (!ALUWritePC(context, res.result))
1930 return false;
1931 } else {
1932 // R[d] = result;
1933 // if setflags then
1934 // APSR.N = result<31>;
1935 // APSR.Z = IsZeroBit(result);
1936 // APSR.C = carry;
1937 // APSR.V = overflow;
1938 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1939 res.carry_out, res.overflow))
1940 return false;
1941 }
1942 }
1943 return true;
1944 }
1945
1946 // An add operation to adjust the SP.
1947 // ADD (SP plus register)
EmulateADDSPRm(const uint32_t opcode,const ARMEncoding encoding)1948 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1949 const ARMEncoding encoding) {
1950 #if 0
1951 // ARM pseudo code...
1952 if (ConditionPassed())
1953 {
1954 EncodingSpecificOperations();
1955 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1956 (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1957 if d == 15 then
1958 ALUWritePC(result); // setflags is always FALSE here
1959 else
1960 R[d] = result;
1961 if setflags then
1962 APSR.N = result<31>;
1963 APSR.Z = IsZeroBit(result);
1964 APSR.C = carry;
1965 APSR.V = overflow;
1966 }
1967 #endif
1968
1969 bool success = false;
1970
1971 if (ConditionPassed(opcode)) {
1972 const addr_t sp = ReadCoreReg(SP_REG, &success);
1973 if (!success)
1974 return false;
1975 uint32_t Rm; // the second operand
1976 switch (encoding) {
1977 case eEncodingT2:
1978 Rm = Bits32(opcode, 6, 3);
1979 break;
1980 default:
1981 return false;
1982 }
1983 int32_t reg_value = ReadCoreReg(Rm, &success);
1984 if (!success)
1985 return false;
1986
1987 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1988
1989 EmulateInstruction::Context context;
1990 context.type = eContextArithmetic;
1991 RegisterInfo sp_reg;
1992 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1993
1994 RegisterInfo other_reg;
1995 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1996 context.SetRegisterRegisterOperands(sp_reg, other_reg);
1997
1998 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1999 LLDB_REGNUM_GENERIC_SP, addr))
2000 return false;
2001 }
2002 return true;
2003 }
2004
2005 // Branch with Link and Exchange Instruction Sets (immediate) calls a
2006 // subroutine at a PC-relative address, and changes instruction set from ARM to
2007 // Thumb, or from Thumb to ARM.
2008 // BLX (immediate)
EmulateBLXImmediate(const uint32_t opcode,const ARMEncoding encoding)2009 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
2010 const ARMEncoding encoding) {
2011 #if 0
2012 // ARM pseudo code...
2013 if (ConditionPassed())
2014 {
2015 EncodingSpecificOperations();
2016 if CurrentInstrSet() == InstrSet_ARM then
2017 LR = PC - 4;
2018 else
2019 LR = PC<31:1> : '1';
2020 if targetInstrSet == InstrSet_ARM then
2021 targetAddress = Align(PC,4) + imm32;
2022 else
2023 targetAddress = PC + imm32;
2024 SelectInstrSet(targetInstrSet);
2025 BranchWritePC(targetAddress);
2026 }
2027 #endif
2028
2029 bool success = true;
2030
2031 if (ConditionPassed(opcode)) {
2032 EmulateInstruction::Context context;
2033 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2034 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2035 if (!success)
2036 return false;
2037 addr_t lr; // next instruction address
2038 addr_t target; // target address
2039 int32_t imm32; // PC-relative offset
2040 switch (encoding) {
2041 case eEncodingT1: {
2042 lr = pc | 1u; // return address
2043 uint32_t S = Bit32(opcode, 26);
2044 uint32_t imm10 = Bits32(opcode, 25, 16);
2045 uint32_t J1 = Bit32(opcode, 13);
2046 uint32_t J2 = Bit32(opcode, 11);
2047 uint32_t imm11 = Bits32(opcode, 10, 0);
2048 uint32_t I1 = !(J1 ^ S);
2049 uint32_t I2 = !(J2 ^ S);
2050 uint32_t imm25 =
2051 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2052 imm32 = llvm::SignExtend32<25>(imm25);
2053 target = pc + imm32;
2054 SelectInstrSet(eModeThumb);
2055 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2056 if (InITBlock() && !LastInITBlock())
2057 return false;
2058 break;
2059 }
2060 case eEncodingT2: {
2061 lr = pc | 1u; // return address
2062 uint32_t S = Bit32(opcode, 26);
2063 uint32_t imm10H = Bits32(opcode, 25, 16);
2064 uint32_t J1 = Bit32(opcode, 13);
2065 uint32_t J2 = Bit32(opcode, 11);
2066 uint32_t imm10L = Bits32(opcode, 10, 1);
2067 uint32_t I1 = !(J1 ^ S);
2068 uint32_t I2 = !(J2 ^ S);
2069 uint32_t imm25 =
2070 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2071 imm32 = llvm::SignExtend32<25>(imm25);
2072 target = Align(pc, 4) + imm32;
2073 SelectInstrSet(eModeARM);
2074 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
2075 if (InITBlock() && !LastInITBlock())
2076 return false;
2077 break;
2078 }
2079 case eEncodingA1:
2080 lr = pc - 4; // return address
2081 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2082 target = Align(pc, 4) + imm32;
2083 SelectInstrSet(eModeARM);
2084 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2085 break;
2086 case eEncodingA2:
2087 lr = pc - 4; // return address
2088 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
2089 Bits32(opcode, 24, 24) << 1);
2090 target = pc + imm32;
2091 SelectInstrSet(eModeThumb);
2092 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
2093 break;
2094 default:
2095 return false;
2096 }
2097 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2098 LLDB_REGNUM_GENERIC_RA, lr))
2099 return false;
2100 if (!BranchWritePC(context, target))
2101 return false;
2102 if (m_opcode_cpsr != m_new_inst_cpsr)
2103 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2104 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
2105 return false;
2106 }
2107 return true;
2108 }
2109
2110 // Branch with Link and Exchange (register) calls a subroutine at an address
2111 // and instruction set specified by a register.
2112 // BLX (register)
EmulateBLXRm(const uint32_t opcode,const ARMEncoding encoding)2113 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
2114 const ARMEncoding encoding) {
2115 #if 0
2116 // ARM pseudo code...
2117 if (ConditionPassed())
2118 {
2119 EncodingSpecificOperations();
2120 target = R[m];
2121 if CurrentInstrSet() == InstrSet_ARM then
2122 next_instr_addr = PC - 4;
2123 LR = next_instr_addr;
2124 else
2125 next_instr_addr = PC - 2;
2126 LR = next_instr_addr<31:1> : '1';
2127 BXWritePC(target);
2128 }
2129 #endif
2130
2131 bool success = false;
2132
2133 if (ConditionPassed(opcode)) {
2134 EmulateInstruction::Context context;
2135 context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2136 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2137 addr_t lr; // next instruction address
2138 if (!success)
2139 return false;
2140 uint32_t Rm; // the register with the target address
2141 switch (encoding) {
2142 case eEncodingT1:
2143 lr = (pc - 2) | 1u; // return address
2144 Rm = Bits32(opcode, 6, 3);
2145 // if m == 15 then UNPREDICTABLE;
2146 if (Rm == 15)
2147 return false;
2148 if (InITBlock() && !LastInITBlock())
2149 return false;
2150 break;
2151 case eEncodingA1:
2152 lr = pc - 4; // return address
2153 Rm = Bits32(opcode, 3, 0);
2154 // if m == 15 then UNPREDICTABLE;
2155 if (Rm == 15)
2156 return false;
2157 break;
2158 default:
2159 return false;
2160 }
2161 addr_t target = ReadCoreReg(Rm, &success);
2162 if (!success)
2163 return false;
2164 RegisterInfo dwarf_reg;
2165 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2166 context.SetRegister(dwarf_reg);
2167 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2168 LLDB_REGNUM_GENERIC_RA, lr))
2169 return false;
2170 if (!BXWritePC(context, target))
2171 return false;
2172 }
2173 return true;
2174 }
2175
2176 // Branch and Exchange causes a branch to an address and instruction set
2177 // specified by a register.
EmulateBXRm(const uint32_t opcode,const ARMEncoding encoding)2178 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
2179 const ARMEncoding encoding) {
2180 #if 0
2181 // ARM pseudo code...
2182 if (ConditionPassed())
2183 {
2184 EncodingSpecificOperations();
2185 BXWritePC(R[m]);
2186 }
2187 #endif
2188
2189 if (ConditionPassed(opcode)) {
2190 EmulateInstruction::Context context;
2191 context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2192 uint32_t Rm; // the register with the target address
2193 switch (encoding) {
2194 case eEncodingT1:
2195 Rm = Bits32(opcode, 6, 3);
2196 if (InITBlock() && !LastInITBlock())
2197 return false;
2198 break;
2199 case eEncodingA1:
2200 Rm = Bits32(opcode, 3, 0);
2201 break;
2202 default:
2203 return false;
2204 }
2205 bool success = false;
2206 addr_t target = ReadCoreReg(Rm, &success);
2207 if (!success)
2208 return false;
2209
2210 RegisterInfo dwarf_reg;
2211 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2212 context.SetRegister(dwarf_reg);
2213 if (!BXWritePC(context, target))
2214 return false;
2215 }
2216 return true;
2217 }
2218
2219 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the
2220 // attempt fails, it branches to an address and instruction set specified by a
2221 // register as though it were a BX instruction.
2222 //
2223 // TODO: Emulate Jazelle architecture?
2224 // We currently assume that switching to Jazelle state fails, thus
2225 // treating BXJ as a BX operation.
EmulateBXJRm(const uint32_t opcode,const ARMEncoding encoding)2226 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
2227 const ARMEncoding encoding) {
2228 #if 0
2229 // ARM pseudo code...
2230 if (ConditionPassed())
2231 {
2232 EncodingSpecificOperations();
2233 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
2234 BXWritePC(R[m]);
2235 else
2236 if JazelleAcceptsExecution() then
2237 SwitchToJazelleExecution();
2238 else
2239 SUBARCHITECTURE_DEFINED handler call;
2240 }
2241 #endif
2242
2243 if (ConditionPassed(opcode)) {
2244 EmulateInstruction::Context context;
2245 context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2246 uint32_t Rm; // the register with the target address
2247 switch (encoding) {
2248 case eEncodingT1:
2249 Rm = Bits32(opcode, 19, 16);
2250 if (BadReg(Rm))
2251 return false;
2252 if (InITBlock() && !LastInITBlock())
2253 return false;
2254 break;
2255 case eEncodingA1:
2256 Rm = Bits32(opcode, 3, 0);
2257 if (Rm == 15)
2258 return false;
2259 break;
2260 default:
2261 return false;
2262 }
2263 bool success = false;
2264 addr_t target = ReadCoreReg(Rm, &success);
2265 if (!success)
2266 return false;
2267
2268 RegisterInfo dwarf_reg;
2269 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2270 context.SetRegister(dwarf_reg);
2271 if (!BXWritePC(context, target))
2272 return false;
2273 }
2274 return true;
2275 }
2276
2277 // Set r7 to point to some ip offset.
2278 // SUB (immediate)
EmulateSUBR7IPImm(const uint32_t opcode,const ARMEncoding encoding)2279 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
2280 const ARMEncoding encoding) {
2281 #if 0
2282 // ARM pseudo code...
2283 if (ConditionPassed())
2284 {
2285 EncodingSpecificOperations();
2286 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2287 if d == 15 then // Can only occur for ARM encoding
2288 ALUWritePC(result); // setflags is always FALSE here
2289 else
2290 R[d] = result;
2291 if setflags then
2292 APSR.N = result<31>;
2293 APSR.Z = IsZeroBit(result);
2294 APSR.C = carry;
2295 APSR.V = overflow;
2296 }
2297 #endif
2298
2299 if (ConditionPassed(opcode)) {
2300 bool success = false;
2301 const addr_t ip = ReadCoreReg(12, &success);
2302 if (!success)
2303 return false;
2304 uint32_t imm32;
2305 switch (encoding) {
2306 case eEncodingA1:
2307 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2308 break;
2309 default:
2310 return false;
2311 }
2312 addr_t ip_offset = imm32;
2313 addr_t addr = ip - ip_offset; // the adjusted ip value
2314
2315 EmulateInstruction::Context context;
2316 context.type = EmulateInstruction::eContextRegisterPlusOffset;
2317 RegisterInfo dwarf_reg;
2318 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg);
2319 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset);
2320
2321 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
2322 return false;
2323 }
2324 return true;
2325 }
2326
2327 // Set ip to point to some stack offset.
2328 // SUB (SP minus immediate)
EmulateSUBIPSPImm(const uint32_t opcode,const ARMEncoding encoding)2329 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
2330 const ARMEncoding encoding) {
2331 #if 0
2332 // ARM pseudo code...
2333 if (ConditionPassed())
2334 {
2335 EncodingSpecificOperations();
2336 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2337 if d == 15 then // Can only occur for ARM encoding
2338 ALUWritePC(result); // setflags is always FALSE here
2339 else
2340 R[d] = result;
2341 if setflags then
2342 APSR.N = result<31>;
2343 APSR.Z = IsZeroBit(result);
2344 APSR.C = carry;
2345 APSR.V = overflow;
2346 }
2347 #endif
2348
2349 if (ConditionPassed(opcode)) {
2350 bool success = false;
2351 const addr_t sp = ReadCoreReg(SP_REG, &success);
2352 if (!success)
2353 return false;
2354 uint32_t imm32;
2355 switch (encoding) {
2356 case eEncodingA1:
2357 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2358 break;
2359 default:
2360 return false;
2361 }
2362 addr_t sp_offset = imm32;
2363 addr_t addr = sp - sp_offset; // the adjusted stack pointer value
2364
2365 EmulateInstruction::Context context;
2366 context.type = EmulateInstruction::eContextRegisterPlusOffset;
2367 RegisterInfo dwarf_reg;
2368 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
2369 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset);
2370
2371 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
2372 return false;
2373 }
2374 return true;
2375 }
2376
2377 // This instruction subtracts an immediate value from the SP value, and writes
2378 // the result to the destination register.
2379 //
2380 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
2381 // storage.
EmulateSUBSPImm(const uint32_t opcode,const ARMEncoding encoding)2382 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
2383 const ARMEncoding encoding) {
2384 #if 0
2385 // ARM pseudo code...
2386 if (ConditionPassed())
2387 {
2388 EncodingSpecificOperations();
2389 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2390 if d == 15 then // Can only occur for ARM encoding
2391 ALUWritePC(result); // setflags is always FALSE here
2392 else
2393 R[d] = result;
2394 if setflags then
2395 APSR.N = result<31>;
2396 APSR.Z = IsZeroBit(result);
2397 APSR.C = carry;
2398 APSR.V = overflow;
2399 }
2400 #endif
2401
2402 bool success = false;
2403 if (ConditionPassed(opcode)) {
2404 const addr_t sp = ReadCoreReg(SP_REG, &success);
2405 if (!success)
2406 return false;
2407
2408 uint32_t Rd;
2409 bool setflags;
2410 uint32_t imm32;
2411 switch (encoding) {
2412 case eEncodingT1:
2413 Rd = 13;
2414 setflags = false;
2415 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
2416 break;
2417 case eEncodingT2:
2418 Rd = Bits32(opcode, 11, 8);
2419 setflags = BitIsSet(opcode, 20);
2420 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2421 if (Rd == 15 && setflags)
2422 return EmulateCMPImm(opcode, eEncodingT2);
2423 if (Rd == 15 && !setflags)
2424 return false;
2425 break;
2426 case eEncodingT3:
2427 Rd = Bits32(opcode, 11, 8);
2428 setflags = false;
2429 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
2430 if (Rd == 15)
2431 return false;
2432 break;
2433 case eEncodingA1:
2434 Rd = Bits32(opcode, 15, 12);
2435 setflags = BitIsSet(opcode, 20);
2436 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2437
2438 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
2439 // instructions;
2440 if (Rd == 15 && setflags)
2441 return EmulateSUBSPcLrEtc(opcode, encoding);
2442 break;
2443 default:
2444 return false;
2445 }
2446 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
2447
2448 EmulateInstruction::Context context;
2449 if (Rd == 13) {
2450 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
2451 // to negate it, or the wrong
2452 // value gets passed down to context.SetImmediateSigned.
2453 context.type = EmulateInstruction::eContextAdjustStackPointer;
2454 context.SetImmediateSigned(-imm64); // the stack pointer offset
2455 } else {
2456 context.type = EmulateInstruction::eContextImmediate;
2457 context.SetNoArgs();
2458 }
2459
2460 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2461 res.carry_out, res.overflow))
2462 return false;
2463 }
2464 return true;
2465 }
2466
2467 // A store operation to the stack that also updates the SP.
EmulateSTRRtSP(const uint32_t opcode,const ARMEncoding encoding)2468 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
2469 const ARMEncoding encoding) {
2470 #if 0
2471 // ARM pseudo code...
2472 if (ConditionPassed())
2473 {
2474 EncodingSpecificOperations();
2475 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2476 address = if index then offset_addr else R[n];
2477 MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
2478 if wback then R[n] = offset_addr;
2479 }
2480 #endif
2481
2482 bool success = false;
2483 if (ConditionPassed(opcode)) {
2484 const uint32_t addr_byte_size = GetAddressByteSize();
2485 const addr_t sp = ReadCoreReg(SP_REG, &success);
2486 if (!success)
2487 return false;
2488 uint32_t Rt; // the source register
2489 uint32_t imm12;
2490 uint32_t
2491 Rn; // This function assumes Rn is the SP, but we should verify that.
2492
2493 bool index;
2494 bool add;
2495 bool wback;
2496 switch (encoding) {
2497 case eEncodingA1:
2498 Rt = Bits32(opcode, 15, 12);
2499 imm12 = Bits32(opcode, 11, 0);
2500 Rn = Bits32(opcode, 19, 16);
2501
2502 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP.
2503 return false;
2504
2505 index = BitIsSet(opcode, 24);
2506 add = BitIsSet(opcode, 23);
2507 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
2508
2509 if (wback && ((Rn == 15) || (Rn == Rt)))
2510 return false;
2511 break;
2512 default:
2513 return false;
2514 }
2515 addr_t offset_addr;
2516 if (add)
2517 offset_addr = sp + imm12;
2518 else
2519 offset_addr = sp - imm12;
2520
2521 addr_t addr;
2522 if (index)
2523 addr = offset_addr;
2524 else
2525 addr = sp;
2526
2527 EmulateInstruction::Context context;
2528 context.type = EmulateInstruction::eContextPushRegisterOnStack;
2529 RegisterInfo sp_reg;
2530 RegisterInfo dwarf_reg;
2531
2532 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2533 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2534 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2535 if (Rt != 15) {
2536 uint32_t reg_value = ReadCoreReg(Rt, &success);
2537 if (!success)
2538 return false;
2539 if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2540 return false;
2541 } else {
2542 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2543 if (!success)
2544 return false;
2545 if (!MemUWrite(context, addr, pc, addr_byte_size))
2546 return false;
2547 }
2548
2549 if (wback) {
2550 context.type = EmulateInstruction::eContextAdjustStackPointer;
2551 context.SetImmediateSigned(addr - sp);
2552 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2553 LLDB_REGNUM_GENERIC_SP, offset_addr))
2554 return false;
2555 }
2556 }
2557 return true;
2558 }
2559
2560 // Vector Push stores multiple extension registers to the stack. It also
2561 // updates SP to point to the start of the stored data.
EmulateVPUSH(const uint32_t opcode,const ARMEncoding encoding)2562 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2563 const ARMEncoding encoding) {
2564 #if 0
2565 // ARM pseudo code...
2566 if (ConditionPassed())
2567 {
2568 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2569 address = SP - imm32;
2570 SP = SP - imm32;
2571 if single_regs then
2572 for r = 0 to regs-1
2573 MemA[address,4] = S[d+r]; address = address+4;
2574 else
2575 for r = 0 to regs-1
2576 // Store as two word-aligned words in the correct order for
2577 // current endianness.
2578 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2579 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2580 address = address+8;
2581 }
2582 #endif
2583
2584 bool success = false;
2585 if (ConditionPassed(opcode)) {
2586 const uint32_t addr_byte_size = GetAddressByteSize();
2587 const addr_t sp = ReadCoreReg(SP_REG, &success);
2588 if (!success)
2589 return false;
2590 bool single_regs;
2591 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
2592 uint32_t imm32; // stack offset
2593 uint32_t regs; // number of registers
2594 switch (encoding) {
2595 case eEncodingT1:
2596 case eEncodingA1:
2597 single_regs = false;
2598 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2599 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2600 // If UInt(imm8) is odd, see "FSTMX".
2601 regs = Bits32(opcode, 7, 0) / 2;
2602 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2603 if (regs == 0 || regs > 16 || (d + regs) > 32)
2604 return false;
2605 break;
2606 case eEncodingT2:
2607 case eEncodingA2:
2608 single_regs = true;
2609 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2610 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2611 regs = Bits32(opcode, 7, 0);
2612 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2613 if (regs == 0 || regs > 16 || (d + regs) > 32)
2614 return false;
2615 break;
2616 default:
2617 return false;
2618 }
2619 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2620 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2621 addr_t sp_offset = imm32;
2622 addr_t addr = sp - sp_offset;
2623 uint32_t i;
2624
2625 EmulateInstruction::Context context;
2626 context.type = EmulateInstruction::eContextPushRegisterOnStack;
2627
2628 RegisterInfo dwarf_reg;
2629 RegisterInfo sp_reg;
2630 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2631 for (i = 0; i < regs; ++i) {
2632 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2633 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2634 // uint64_t to accommodate 64-bit registers.
2635 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success);
2636 if (!success)
2637 return false;
2638 if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2639 return false;
2640 addr += reg_byte_size;
2641 }
2642
2643 context.type = EmulateInstruction::eContextAdjustStackPointer;
2644 context.SetImmediateSigned(-sp_offset);
2645
2646 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2647 LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2648 return false;
2649 }
2650 return true;
2651 }
2652
2653 // Vector Pop loads multiple extension registers from the stack. It also
2654 // updates SP to point just above the loaded data.
EmulateVPOP(const uint32_t opcode,const ARMEncoding encoding)2655 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2656 const ARMEncoding encoding) {
2657 #if 0
2658 // ARM pseudo code...
2659 if (ConditionPassed())
2660 {
2661 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2662 address = SP;
2663 SP = SP + imm32;
2664 if single_regs then
2665 for r = 0 to regs-1
2666 S[d+r] = MemA[address,4]; address = address+4;
2667 else
2668 for r = 0 to regs-1
2669 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2670 // Combine the word-aligned words in the correct order for
2671 // current endianness.
2672 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2673 }
2674 #endif
2675
2676 bool success = false;
2677 if (ConditionPassed(opcode)) {
2678 const uint32_t addr_byte_size = GetAddressByteSize();
2679 const addr_t sp = ReadCoreReg(SP_REG, &success);
2680 if (!success)
2681 return false;
2682 bool single_regs;
2683 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
2684 uint32_t imm32; // stack offset
2685 uint32_t regs; // number of registers
2686 switch (encoding) {
2687 case eEncodingT1:
2688 case eEncodingA1:
2689 single_regs = false;
2690 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2691 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2692 // If UInt(imm8) is odd, see "FLDMX".
2693 regs = Bits32(opcode, 7, 0) / 2;
2694 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2695 if (regs == 0 || regs > 16 || (d + regs) > 32)
2696 return false;
2697 break;
2698 case eEncodingT2:
2699 case eEncodingA2:
2700 single_regs = true;
2701 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2702 imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2703 regs = Bits32(opcode, 7, 0);
2704 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2705 if (regs == 0 || regs > 16 || (d + regs) > 32)
2706 return false;
2707 break;
2708 default:
2709 return false;
2710 }
2711 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2712 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2713 addr_t sp_offset = imm32;
2714 addr_t addr = sp;
2715 uint32_t i;
2716 uint64_t data; // uint64_t to accommodate 64-bit registers.
2717
2718 EmulateInstruction::Context context;
2719 context.type = EmulateInstruction::eContextPopRegisterOffStack;
2720
2721 RegisterInfo dwarf_reg;
2722 RegisterInfo sp_reg;
2723 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2724 for (i = 0; i < regs; ++i) {
2725 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2726 context.SetAddress(addr);
2727 data = MemARead(context, addr, reg_byte_size, 0, &success);
2728 if (!success)
2729 return false;
2730 if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2731 return false;
2732 addr += reg_byte_size;
2733 }
2734
2735 context.type = EmulateInstruction::eContextAdjustStackPointer;
2736 context.SetImmediateSigned(sp_offset);
2737
2738 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2739 LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2740 return false;
2741 }
2742 return true;
2743 }
2744
2745 // SVC (previously SWI)
EmulateSVC(const uint32_t opcode,const ARMEncoding encoding)2746 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2747 const ARMEncoding encoding) {
2748 #if 0
2749 // ARM pseudo code...
2750 if (ConditionPassed())
2751 {
2752 EncodingSpecificOperations();
2753 CallSupervisor();
2754 }
2755 #endif
2756
2757 bool success = false;
2758
2759 if (ConditionPassed(opcode)) {
2760 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2761 addr_t lr; // next instruction address
2762 if (!success)
2763 return false;
2764 uint32_t imm32; // the immediate constant
2765 uint32_t mode; // ARM or Thumb mode
2766 switch (encoding) {
2767 case eEncodingT1:
2768 lr = (pc + 2) | 1u; // return address
2769 imm32 = Bits32(opcode, 7, 0);
2770 mode = eModeThumb;
2771 break;
2772 case eEncodingA1:
2773 lr = pc + 4; // return address
2774 imm32 = Bits32(opcode, 23, 0);
2775 mode = eModeARM;
2776 break;
2777 default:
2778 return false;
2779 }
2780
2781 EmulateInstruction::Context context;
2782 context.type = EmulateInstruction::eContextSupervisorCall;
2783 context.SetISAAndImmediate(mode, imm32);
2784 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2785 LLDB_REGNUM_GENERIC_RA, lr))
2786 return false;
2787 }
2788 return true;
2789 }
2790
2791 // If Then makes up to four following instructions (the IT block) conditional.
EmulateIT(const uint32_t opcode,const ARMEncoding encoding)2792 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2793 const ARMEncoding encoding) {
2794 #if 0
2795 // ARM pseudo code...
2796 EncodingSpecificOperations();
2797 ITSTATE.IT<7:0> = firstcond:mask;
2798 #endif
2799
2800 m_it_session.InitIT(Bits32(opcode, 7, 0));
2801 return true;
2802 }
2803
EmulateNop(const uint32_t opcode,const ARMEncoding encoding)2804 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2805 const ARMEncoding encoding) {
2806 // NOP, nothing to do...
2807 return true;
2808 }
2809
2810 // Branch causes a branch to a target address.
EmulateB(const uint32_t opcode,const ARMEncoding encoding)2811 bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2812 const ARMEncoding encoding) {
2813 #if 0
2814 // ARM pseudo code...
2815 if (ConditionPassed())
2816 {
2817 EncodingSpecificOperations();
2818 BranchWritePC(PC + imm32);
2819 }
2820 #endif
2821
2822 bool success = false;
2823
2824 if (ConditionPassed(opcode)) {
2825 EmulateInstruction::Context context;
2826 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2827 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2828 if (!success)
2829 return false;
2830 addr_t target; // target address
2831 int32_t imm32; // PC-relative offset
2832 switch (encoding) {
2833 case eEncodingT1:
2834 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2835 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2836 target = pc + imm32;
2837 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2838 break;
2839 case eEncodingT2:
2840 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2841 target = pc + imm32;
2842 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2843 break;
2844 case eEncodingT3:
2845 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2846 {
2847 if (Bits32(opcode, 25, 23) == 7)
2848 return false; // See Branches and miscellaneous control on page
2849 // A6-235.
2850
2851 uint32_t S = Bit32(opcode, 26);
2852 uint32_t imm6 = Bits32(opcode, 21, 16);
2853 uint32_t J1 = Bit32(opcode, 13);
2854 uint32_t J2 = Bit32(opcode, 11);
2855 uint32_t imm11 = Bits32(opcode, 10, 0);
2856 uint32_t imm21 =
2857 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2858 imm32 = llvm::SignExtend32<21>(imm21);
2859 target = pc + imm32;
2860 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2861 break;
2862 }
2863 case eEncodingT4: {
2864 uint32_t S = Bit32(opcode, 26);
2865 uint32_t imm10 = Bits32(opcode, 25, 16);
2866 uint32_t J1 = Bit32(opcode, 13);
2867 uint32_t J2 = Bit32(opcode, 11);
2868 uint32_t imm11 = Bits32(opcode, 10, 0);
2869 uint32_t I1 = !(J1 ^ S);
2870 uint32_t I2 = !(J2 ^ S);
2871 uint32_t imm25 =
2872 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2873 imm32 = llvm::SignExtend32<25>(imm25);
2874 target = pc + imm32;
2875 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2876 break;
2877 }
2878 case eEncodingA1:
2879 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2880 target = pc + imm32;
2881 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2882 break;
2883 default:
2884 return false;
2885 }
2886 if (!BranchWritePC(context, target))
2887 return false;
2888 }
2889 return true;
2890 }
2891
2892 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2893 // value in a register with zero and conditionally branch forward a constant
2894 // value. They do not affect the condition flags. CBNZ, CBZ
EmulateCB(const uint32_t opcode,const ARMEncoding encoding)2895 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2896 const ARMEncoding encoding) {
2897 #if 0
2898 // ARM pseudo code...
2899 EncodingSpecificOperations();
2900 if nonzero ^ IsZero(R[n]) then
2901 BranchWritePC(PC + imm32);
2902 #endif
2903
2904 bool success = false;
2905
2906 // Read the register value from the operand register Rn.
2907 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2908 if (!success)
2909 return false;
2910
2911 EmulateInstruction::Context context;
2912 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2913 const uint32_t pc = ReadCoreReg(PC_REG, &success);
2914 if (!success)
2915 return false;
2916
2917 addr_t target; // target address
2918 uint32_t imm32; // PC-relative offset to branch forward
2919 bool nonzero;
2920 switch (encoding) {
2921 case eEncodingT1:
2922 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2923 nonzero = BitIsSet(opcode, 11);
2924 target = pc + imm32;
2925 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2926 break;
2927 default:
2928 return false;
2929 }
2930 if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2931 if (!BranchWritePC(context, target))
2932 return false;
2933
2934 return true;
2935 }
2936
2937 // Table Branch Byte causes a PC-relative forward branch using a table of
2938 // single byte offsets.
2939 // A base register provides a pointer to the table, and a second register
2940 // supplies an index into the table.
2941 // The branch length is twice the value of the byte returned from the table.
2942 //
2943 // Table Branch Halfword causes a PC-relative forward branch using a table of
2944 // single halfword offsets.
2945 // A base register provides a pointer to the table, and a second register
2946 // supplies an index into the table.
2947 // The branch length is twice the value of the halfword returned from the
2948 // table. TBB, TBH
EmulateTB(const uint32_t opcode,const ARMEncoding encoding)2949 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2950 const ARMEncoding encoding) {
2951 #if 0
2952 // ARM pseudo code...
2953 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2954 if is_tbh then
2955 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2956 else
2957 halfwords = UInt(MemU[R[n]+R[m], 1]);
2958 BranchWritePC(PC + 2*halfwords);
2959 #endif
2960
2961 bool success = false;
2962
2963 if (ConditionPassed(opcode)) {
2964 uint32_t Rn; // the base register which contains the address of the table of
2965 // branch lengths
2966 uint32_t Rm; // the index register which contains an integer pointing to a
2967 // byte/halfword in the table
2968 bool is_tbh; // true if table branch halfword
2969 switch (encoding) {
2970 case eEncodingT1:
2971 Rn = Bits32(opcode, 19, 16);
2972 Rm = Bits32(opcode, 3, 0);
2973 is_tbh = BitIsSet(opcode, 4);
2974 if (Rn == 13 || BadReg(Rm))
2975 return false;
2976 if (InITBlock() && !LastInITBlock())
2977 return false;
2978 break;
2979 default:
2980 return false;
2981 }
2982
2983 // Read the address of the table from the operand register Rn. The PC can
2984 // be used, in which case the table immediately follows this instruction.
2985 uint32_t base = ReadCoreReg(Rn, &success);
2986 if (!success)
2987 return false;
2988
2989 // the table index
2990 uint32_t index = ReadCoreReg(Rm, &success);
2991 if (!success)
2992 return false;
2993
2994 // the offsetted table address
2995 addr_t addr = base + (is_tbh ? index * 2 : index);
2996
2997 // PC-relative offset to branch forward
2998 EmulateInstruction::Context context;
2999 context.type = EmulateInstruction::eContextTableBranchReadMemory;
3000 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
3001 if (!success)
3002 return false;
3003
3004 const uint32_t pc = ReadCoreReg(PC_REG, &success);
3005 if (!success)
3006 return false;
3007
3008 // target address
3009 addr_t target = pc + offset;
3010 context.type = EmulateInstruction::eContextRelativeBranchImmediate;
3011 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
3012
3013 if (!BranchWritePC(context, target))
3014 return false;
3015 }
3016
3017 return true;
3018 }
3019
3020 // This instruction adds an immediate value to a register value, and writes the
3021 // result to the destination register. It can optionally update the condition
3022 // flags based on the result.
EmulateADDImmThumb(const uint32_t opcode,const ARMEncoding encoding)3023 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
3024 const ARMEncoding encoding) {
3025 #if 0
3026 if ConditionPassed() then
3027 EncodingSpecificOperations();
3028 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3029 R[d] = result;
3030 if setflags then
3031 APSR.N = result<31>;
3032 APSR.Z = IsZeroBit(result);
3033 APSR.C = carry;
3034 APSR.V = overflow;
3035 #endif
3036
3037 bool success = false;
3038
3039 if (ConditionPassed(opcode)) {
3040 uint32_t d;
3041 uint32_t n;
3042 bool setflags;
3043 uint32_t imm32;
3044 uint32_t carry_out;
3045
3046 // EncodingSpecificOperations();
3047 switch (encoding) {
3048 case eEncodingT1:
3049 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
3050 // ZeroExtend(imm3, 32);
3051 d = Bits32(opcode, 2, 0);
3052 n = Bits32(opcode, 5, 3);
3053 setflags = !InITBlock();
3054 imm32 = Bits32(opcode, 8, 6);
3055
3056 break;
3057
3058 case eEncodingT2:
3059 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
3060 // ZeroExtend(imm8, 32);
3061 d = Bits32(opcode, 10, 8);
3062 n = Bits32(opcode, 10, 8);
3063 setflags = !InITBlock();
3064 imm32 = Bits32(opcode, 7, 0);
3065
3066 break;
3067
3068 case eEncodingT3:
3069 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
3070 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
3071 // ThumbExpandImm(i:imm3:imm8);
3072 d = Bits32(opcode, 11, 8);
3073 n = Bits32(opcode, 19, 16);
3074 setflags = BitIsSet(opcode, 20);
3075 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
3076
3077 // if Rn == '1101' then SEE ADD (SP plus immediate);
3078 if (n == 13)
3079 return EmulateADDSPImm(opcode, eEncodingT3);
3080
3081 // if BadReg(d) || n == 15 then UNPREDICTABLE;
3082 if (BadReg(d) || (n == 15))
3083 return false;
3084
3085 break;
3086
3087 case eEncodingT4: {
3088 // if Rn == '1111' then SEE ADR;
3089 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
3090 // ZeroExtend(i:imm3:imm8, 32);
3091 d = Bits32(opcode, 11, 8);
3092 n = Bits32(opcode, 19, 16);
3093 setflags = false;
3094 uint32_t i = Bit32(opcode, 26);
3095 uint32_t imm3 = Bits32(opcode, 14, 12);
3096 uint32_t imm8 = Bits32(opcode, 7, 0);
3097 imm32 = (i << 11) | (imm3 << 8) | imm8;
3098
3099 // if Rn == '1101' then SEE ADD (SP plus immediate);
3100 if (n == 13)
3101 return EmulateADDSPImm(opcode, eEncodingT4);
3102
3103 // if BadReg(d) then UNPREDICTABLE;
3104 if (BadReg(d))
3105 return false;
3106
3107 break;
3108 }
3109
3110 default:
3111 return false;
3112 }
3113
3114 uint64_t Rn =
3115 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3116 if (!success)
3117 return false;
3118
3119 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3120 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
3121
3122 RegisterInfo reg_n;
3123 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
3124
3125 EmulateInstruction::Context context;
3126 context.type = eContextArithmetic;
3127 context.SetRegisterPlusOffset(reg_n, imm32);
3128
3129 // R[d] = result;
3130 // if setflags then
3131 // APSR.N = result<31>;
3132 // APSR.Z = IsZeroBit(result);
3133 // APSR.C = carry;
3134 // APSR.V = overflow;
3135 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
3136 res.carry_out, res.overflow))
3137 return false;
3138 }
3139 return true;
3140 }
3141
3142 // This instruction adds an immediate value to a register value, and writes the
3143 // result to the destination register. It can optionally update the condition
3144 // flags based on the result.
EmulateADDImmARM(const uint32_t opcode,const ARMEncoding encoding)3145 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
3146 const ARMEncoding encoding) {
3147 #if 0
3148 // ARM pseudo code...
3149 if ConditionPassed() then
3150 EncodingSpecificOperations();
3151 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3152 if d == 15 then
3153 ALUWritePC(result); // setflags is always FALSE here
3154 else
3155 R[d] = result;
3156 if setflags then
3157 APSR.N = result<31>;
3158 APSR.Z = IsZeroBit(result);
3159 APSR.C = carry;
3160 APSR.V = overflow;
3161 #endif
3162
3163 bool success = false;
3164
3165 if (ConditionPassed(opcode)) {
3166 uint32_t Rd, Rn;
3167 uint32_t
3168 imm32; // the immediate value to be added to the value obtained from Rn
3169 bool setflags;
3170 switch (encoding) {
3171 case eEncodingA1:
3172 Rd = Bits32(opcode, 15, 12);
3173 Rn = Bits32(opcode, 19, 16);
3174 setflags = BitIsSet(opcode, 20);
3175 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3176 break;
3177 default:
3178 return false;
3179 }
3180
3181 // Read the first operand.
3182 uint32_t val1 = ReadCoreReg(Rn, &success);
3183 if (!success)
3184 return false;
3185
3186 AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
3187
3188 EmulateInstruction::Context context;
3189 if (Rd == 13)
3190 context.type = EmulateInstruction::eContextAdjustStackPointer;
3191 else if (Rd == GetFramePointerRegisterNumber())
3192 context.type = EmulateInstruction::eContextSetFramePointer;
3193 else
3194 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3195
3196 RegisterInfo dwarf_reg;
3197 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
3198 context.SetRegisterPlusOffset(dwarf_reg, imm32);
3199
3200 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3201 res.carry_out, res.overflow))
3202 return false;
3203 }
3204 return true;
3205 }
3206
3207 // This instruction adds a register value and an optionally-shifted register
3208 // value, and writes the result to the destination register. It can optionally
3209 // update the condition flags based on the result.
EmulateADDReg(const uint32_t opcode,const ARMEncoding encoding)3210 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
3211 const ARMEncoding encoding) {
3212 #if 0
3213 // ARM pseudo code...
3214 if ConditionPassed() then
3215 EncodingSpecificOperations();
3216 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3217 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3218 if d == 15 then
3219 ALUWritePC(result); // setflags is always FALSE here
3220 else
3221 R[d] = result;
3222 if setflags then
3223 APSR.N = result<31>;
3224 APSR.Z = IsZeroBit(result);
3225 APSR.C = carry;
3226 APSR.V = overflow;
3227 #endif
3228
3229 bool success = false;
3230
3231 if (ConditionPassed(opcode)) {
3232 uint32_t Rd, Rn, Rm;
3233 ARM_ShifterType shift_t;
3234 uint32_t shift_n; // the shift applied to the value read from Rm
3235 bool setflags;
3236 switch (encoding) {
3237 case eEncodingT1:
3238 Rd = Bits32(opcode, 2, 0);
3239 Rn = Bits32(opcode, 5, 3);
3240 Rm = Bits32(opcode, 8, 6);
3241 setflags = !InITBlock();
3242 shift_t = SRType_LSL;
3243 shift_n = 0;
3244 break;
3245 case eEncodingT2:
3246 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3247 Rm = Bits32(opcode, 6, 3);
3248 setflags = false;
3249 shift_t = SRType_LSL;
3250 shift_n = 0;
3251 if (Rn == 15 && Rm == 15)
3252 return false;
3253 if (Rd == 15 && InITBlock() && !LastInITBlock())
3254 return false;
3255 break;
3256 case eEncodingA1:
3257 Rd = Bits32(opcode, 15, 12);
3258 Rn = Bits32(opcode, 19, 16);
3259 Rm = Bits32(opcode, 3, 0);
3260 setflags = BitIsSet(opcode, 20);
3261 shift_n = DecodeImmShiftARM(opcode, shift_t);
3262 break;
3263 default:
3264 return false;
3265 }
3266
3267 // Read the first operand.
3268 uint32_t val1 = ReadCoreReg(Rn, &success);
3269 if (!success)
3270 return false;
3271
3272 // Read the second operand.
3273 uint32_t val2 = ReadCoreReg(Rm, &success);
3274 if (!success)
3275 return false;
3276
3277 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3278 if (!success)
3279 return false;
3280 AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3281
3282 EmulateInstruction::Context context;
3283 context.type = eContextArithmetic;
3284 RegisterInfo op1_reg;
3285 RegisterInfo op2_reg;
3286 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
3287 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
3288 context.SetRegisterRegisterOperands(op1_reg, op2_reg);
3289
3290 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3291 res.carry_out, res.overflow))
3292 return false;
3293 }
3294 return true;
3295 }
3296
3297 // Compare Negative (immediate) adds a register value and an immediate value.
3298 // It updates the condition flags based on the result, and discards the result.
EmulateCMNImm(const uint32_t opcode,const ARMEncoding encoding)3299 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
3300 const ARMEncoding encoding) {
3301 #if 0
3302 // ARM pseudo code...
3303 if ConditionPassed() then
3304 EncodingSpecificOperations();
3305 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3306 APSR.N = result<31>;
3307 APSR.Z = IsZeroBit(result);
3308 APSR.C = carry;
3309 APSR.V = overflow;
3310 #endif
3311
3312 bool success = false;
3313
3314 uint32_t Rn; // the first operand
3315 uint32_t imm32; // the immediate value to be compared with
3316 switch (encoding) {
3317 case eEncodingT1:
3318 Rn = Bits32(opcode, 19, 16);
3319 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3320 if (Rn == 15)
3321 return false;
3322 break;
3323 case eEncodingA1:
3324 Rn = Bits32(opcode, 19, 16);
3325 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3326 break;
3327 default:
3328 return false;
3329 }
3330 // Read the register value from the operand register Rn.
3331 uint32_t reg_val = ReadCoreReg(Rn, &success);
3332 if (!success)
3333 return false;
3334
3335 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
3336
3337 EmulateInstruction::Context context;
3338 context.type = EmulateInstruction::eContextImmediate;
3339 context.SetNoArgs();
3340 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3341 }
3342
3343 // Compare Negative (register) adds a register value and an optionally-shifted
3344 // register value. It updates the condition flags based on the result, and
3345 // discards the result.
EmulateCMNReg(const uint32_t opcode,const ARMEncoding encoding)3346 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
3347 const ARMEncoding encoding) {
3348 #if 0
3349 // ARM pseudo code...
3350 if ConditionPassed() then
3351 EncodingSpecificOperations();
3352 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3353 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3354 APSR.N = result<31>;
3355 APSR.Z = IsZeroBit(result);
3356 APSR.C = carry;
3357 APSR.V = overflow;
3358 #endif
3359
3360 bool success = false;
3361
3362 uint32_t Rn; // the first operand
3363 uint32_t Rm; // the second operand
3364 ARM_ShifterType shift_t;
3365 uint32_t shift_n; // the shift applied to the value read from Rm
3366 switch (encoding) {
3367 case eEncodingT1:
3368 Rn = Bits32(opcode, 2, 0);
3369 Rm = Bits32(opcode, 5, 3);
3370 shift_t = SRType_LSL;
3371 shift_n = 0;
3372 break;
3373 case eEncodingT2:
3374 Rn = Bits32(opcode, 19, 16);
3375 Rm = Bits32(opcode, 3, 0);
3376 shift_n = DecodeImmShiftThumb(opcode, shift_t);
3377 // if n == 15 || BadReg(m) then UNPREDICTABLE;
3378 if (Rn == 15 || BadReg(Rm))
3379 return false;
3380 break;
3381 case eEncodingA1:
3382 Rn = Bits32(opcode, 19, 16);
3383 Rm = Bits32(opcode, 3, 0);
3384 shift_n = DecodeImmShiftARM(opcode, shift_t);
3385 break;
3386 default:
3387 return false;
3388 }
3389 // Read the register value from register Rn.
3390 uint32_t val1 = ReadCoreReg(Rn, &success);
3391 if (!success)
3392 return false;
3393
3394 // Read the register value from register Rm.
3395 uint32_t val2 = ReadCoreReg(Rm, &success);
3396 if (!success)
3397 return false;
3398
3399 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3400 if (!success)
3401 return false;
3402 AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3403
3404 EmulateInstruction::Context context;
3405 context.type = EmulateInstruction::eContextImmediate;
3406 context.SetNoArgs();
3407 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3408 }
3409
3410 // Compare (immediate) subtracts an immediate value from a register value. It
3411 // updates the condition flags based on the result, and discards the result.
EmulateCMPImm(const uint32_t opcode,const ARMEncoding encoding)3412 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
3413 const ARMEncoding encoding) {
3414 #if 0
3415 // ARM pseudo code...
3416 if ConditionPassed() then
3417 EncodingSpecificOperations();
3418 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
3419 APSR.N = result<31>;
3420 APSR.Z = IsZeroBit(result);
3421 APSR.C = carry;
3422 APSR.V = overflow;
3423 #endif
3424
3425 bool success = false;
3426
3427 uint32_t Rn; // the first operand
3428 uint32_t imm32; // the immediate value to be compared with
3429 switch (encoding) {
3430 case eEncodingT1:
3431 Rn = Bits32(opcode, 10, 8);
3432 imm32 = Bits32(opcode, 7, 0);
3433 break;
3434 case eEncodingT2:
3435 Rn = Bits32(opcode, 19, 16);
3436 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3437 if (Rn == 15)
3438 return false;
3439 break;
3440 case eEncodingA1:
3441 Rn = Bits32(opcode, 19, 16);
3442 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3443 break;
3444 default:
3445 return false;
3446 }
3447 // Read the register value from the operand register Rn.
3448 uint32_t reg_val = ReadCoreReg(Rn, &success);
3449 if (!success)
3450 return false;
3451
3452 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
3453
3454 EmulateInstruction::Context context;
3455 context.type = EmulateInstruction::eContextImmediate;
3456 context.SetNoArgs();
3457 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3458 }
3459
3460 // Compare (register) subtracts an optionally-shifted register value from a
3461 // register value. It updates the condition flags based on the result, and
3462 // discards the result.
EmulateCMPReg(const uint32_t opcode,const ARMEncoding encoding)3463 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
3464 const ARMEncoding encoding) {
3465 #if 0
3466 // ARM pseudo code...
3467 if ConditionPassed() then
3468 EncodingSpecificOperations();
3469 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3470 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
3471 APSR.N = result<31>;
3472 APSR.Z = IsZeroBit(result);
3473 APSR.C = carry;
3474 APSR.V = overflow;
3475 #endif
3476
3477 bool success = false;
3478
3479 uint32_t Rn; // the first operand
3480 uint32_t Rm; // the second operand
3481 ARM_ShifterType shift_t;
3482 uint32_t shift_n; // the shift applied to the value read from Rm
3483 switch (encoding) {
3484 case eEncodingT1:
3485 Rn = Bits32(opcode, 2, 0);
3486 Rm = Bits32(opcode, 5, 3);
3487 shift_t = SRType_LSL;
3488 shift_n = 0;
3489 break;
3490 case eEncodingT2:
3491 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3492 Rm = Bits32(opcode, 6, 3);
3493 shift_t = SRType_LSL;
3494 shift_n = 0;
3495 if (Rn < 8 && Rm < 8)
3496 return false;
3497 if (Rn == 15 || Rm == 15)
3498 return false;
3499 break;
3500 case eEncodingT3:
3501 Rn = Bits32(opcode, 19, 16);
3502 Rm = Bits32(opcode, 3, 0);
3503 shift_n = DecodeImmShiftThumb(opcode, shift_t);
3504 if (Rn == 15 || BadReg(Rm))
3505 return false;
3506 break;
3507 case eEncodingA1:
3508 Rn = Bits32(opcode, 19, 16);
3509 Rm = Bits32(opcode, 3, 0);
3510 shift_n = DecodeImmShiftARM(opcode, shift_t);
3511 break;
3512 default:
3513 return false;
3514 }
3515 // Read the register value from register Rn.
3516 uint32_t val1 = ReadCoreReg(Rn, &success);
3517 if (!success)
3518 return false;
3519
3520 // Read the register value from register Rm.
3521 uint32_t val2 = ReadCoreReg(Rm, &success);
3522 if (!success)
3523 return false;
3524
3525 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3526 if (!success)
3527 return false;
3528 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3529
3530 EmulateInstruction::Context context;
3531 context.type = EmulateInstruction::eContextImmediate;
3532 context.SetNoArgs();
3533 return WriteFlags(context, res.result, res.carry_out, res.overflow);
3534 }
3535
3536 // Arithmetic Shift Right (immediate) shifts a register value right by an
3537 // immediate number of bits, shifting in copies of its sign bit, and writes the
3538 // result to the destination register. It can optionally update the condition
3539 // flags based on the result.
EmulateASRImm(const uint32_t opcode,const ARMEncoding encoding)3540 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3541 const ARMEncoding encoding) {
3542 #if 0
3543 // ARM pseudo code...
3544 if ConditionPassed() then
3545 EncodingSpecificOperations();
3546 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3547 if d == 15 then // Can only occur for ARM encoding
3548 ALUWritePC(result); // setflags is always FALSE here
3549 else
3550 R[d] = result;
3551 if setflags then
3552 APSR.N = result<31>;
3553 APSR.Z = IsZeroBit(result);
3554 APSR.C = carry;
3555 // APSR.V unchanged
3556 #endif
3557
3558 return EmulateShiftImm(opcode, encoding, SRType_ASR);
3559 }
3560
3561 // Arithmetic Shift Right (register) shifts a register value right by a
3562 // variable number of bits, shifting in copies of its sign bit, and writes the
3563 // result to the destination register. The variable number of bits is read from
3564 // the bottom byte of a register. It can optionally update the condition flags
3565 // based on the result.
EmulateASRReg(const uint32_t opcode,const ARMEncoding encoding)3566 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3567 const ARMEncoding encoding) {
3568 #if 0
3569 // ARM pseudo code...
3570 if ConditionPassed() then
3571 EncodingSpecificOperations();
3572 shift_n = UInt(R[m]<7:0>);
3573 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3574 R[d] = result;
3575 if setflags then
3576 APSR.N = result<31>;
3577 APSR.Z = IsZeroBit(result);
3578 APSR.C = carry;
3579 // APSR.V unchanged
3580 #endif
3581
3582 return EmulateShiftReg(opcode, encoding, SRType_ASR);
3583 }
3584
3585 // Logical Shift Left (immediate) shifts a register value left by an immediate
3586 // number of bits, shifting in zeros, and writes the result to the destination
3587 // register. It can optionally update the condition flags based on the result.
EmulateLSLImm(const uint32_t opcode,const ARMEncoding encoding)3588 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3589 const ARMEncoding encoding) {
3590 #if 0
3591 // ARM pseudo code...
3592 if ConditionPassed() then
3593 EncodingSpecificOperations();
3594 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3595 if d == 15 then // Can only occur for ARM encoding
3596 ALUWritePC(result); // setflags is always FALSE here
3597 else
3598 R[d] = result;
3599 if setflags then
3600 APSR.N = result<31>;
3601 APSR.Z = IsZeroBit(result);
3602 APSR.C = carry;
3603 // APSR.V unchanged
3604 #endif
3605
3606 return EmulateShiftImm(opcode, encoding, SRType_LSL);
3607 }
3608
3609 // Logical Shift Left (register) shifts a register value left by a variable
3610 // number of bits, shifting in zeros, and writes the result to the destination
3611 // register. The variable number of bits is read from the bottom byte of a
3612 // register. It can optionally update the condition flags based on the result.
EmulateLSLReg(const uint32_t opcode,const ARMEncoding encoding)3613 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3614 const ARMEncoding encoding) {
3615 #if 0
3616 // ARM pseudo code...
3617 if ConditionPassed() then
3618 EncodingSpecificOperations();
3619 shift_n = UInt(R[m]<7:0>);
3620 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3621 R[d] = result;
3622 if setflags then
3623 APSR.N = result<31>;
3624 APSR.Z = IsZeroBit(result);
3625 APSR.C = carry;
3626 // APSR.V unchanged
3627 #endif
3628
3629 return EmulateShiftReg(opcode, encoding, SRType_LSL);
3630 }
3631
3632 // Logical Shift Right (immediate) shifts a register value right by an
3633 // immediate number of bits, shifting in zeros, and writes the result to the
3634 // destination register. It can optionally update the condition flags based on
3635 // the result.
EmulateLSRImm(const uint32_t opcode,const ARMEncoding encoding)3636 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3637 const ARMEncoding encoding) {
3638 #if 0
3639 // ARM pseudo code...
3640 if ConditionPassed() then
3641 EncodingSpecificOperations();
3642 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3643 if d == 15 then // Can only occur for ARM encoding
3644 ALUWritePC(result); // setflags is always FALSE here
3645 else
3646 R[d] = result;
3647 if setflags then
3648 APSR.N = result<31>;
3649 APSR.Z = IsZeroBit(result);
3650 APSR.C = carry;
3651 // APSR.V unchanged
3652 #endif
3653
3654 return EmulateShiftImm(opcode, encoding, SRType_LSR);
3655 }
3656
3657 // Logical Shift Right (register) shifts a register value right by a variable
3658 // number of bits, shifting in zeros, and writes the result to the destination
3659 // register. The variable number of bits is read from the bottom byte of a
3660 // register. It can optionally update the condition flags based on the result.
EmulateLSRReg(const uint32_t opcode,const ARMEncoding encoding)3661 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3662 const ARMEncoding encoding) {
3663 #if 0
3664 // ARM pseudo code...
3665 if ConditionPassed() then
3666 EncodingSpecificOperations();
3667 shift_n = UInt(R[m]<7:0>);
3668 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3669 R[d] = result;
3670 if setflags then
3671 APSR.N = result<31>;
3672 APSR.Z = IsZeroBit(result);
3673 APSR.C = carry;
3674 // APSR.V unchanged
3675 #endif
3676
3677 return EmulateShiftReg(opcode, encoding, SRType_LSR);
3678 }
3679
3680 // Rotate Right (immediate) provides the value of the contents of a register
3681 // rotated by a constant value. The bits that are rotated off the right end are
3682 // inserted into the vacated bit positions on the left. It can optionally
3683 // update the condition flags based on the result.
EmulateRORImm(const uint32_t opcode,const ARMEncoding encoding)3684 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3685 const ARMEncoding encoding) {
3686 #if 0
3687 // ARM pseudo code...
3688 if ConditionPassed() then
3689 EncodingSpecificOperations();
3690 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3691 if d == 15 then // Can only occur for ARM encoding
3692 ALUWritePC(result); // setflags is always FALSE here
3693 else
3694 R[d] = result;
3695 if setflags then
3696 APSR.N = result<31>;
3697 APSR.Z = IsZeroBit(result);
3698 APSR.C = carry;
3699 // APSR.V unchanged
3700 #endif
3701
3702 return EmulateShiftImm(opcode, encoding, SRType_ROR);
3703 }
3704
3705 // Rotate Right (register) provides the value of the contents of a register
3706 // rotated by a variable number of bits. The bits that are rotated off the
3707 // right end are inserted into the vacated bit positions on the left. The
3708 // variable number of bits is read from the bottom byte of a register. It can
3709 // optionally update the condition flags based on the result.
EmulateRORReg(const uint32_t opcode,const ARMEncoding encoding)3710 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3711 const ARMEncoding encoding) {
3712 #if 0
3713 // ARM pseudo code...
3714 if ConditionPassed() then
3715 EncodingSpecificOperations();
3716 shift_n = UInt(R[m]<7:0>);
3717 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3718 R[d] = result;
3719 if setflags then
3720 APSR.N = result<31>;
3721 APSR.Z = IsZeroBit(result);
3722 APSR.C = carry;
3723 // APSR.V unchanged
3724 #endif
3725
3726 return EmulateShiftReg(opcode, encoding, SRType_ROR);
3727 }
3728
3729 // Rotate Right with Extend provides the value of the contents of a register
3730 // shifted right by one place, with the carry flag shifted into bit [31].
3731 //
3732 // RRX can optionally update the condition flags based on the result.
3733 // In that case, bit [0] is shifted into the carry flag.
EmulateRRX(const uint32_t opcode,const ARMEncoding encoding)3734 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3735 const ARMEncoding encoding) {
3736 #if 0
3737 // ARM pseudo code...
3738 if ConditionPassed() then
3739 EncodingSpecificOperations();
3740 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3741 if d == 15 then // Can only occur for ARM encoding
3742 ALUWritePC(result); // setflags is always FALSE here
3743 else
3744 R[d] = result;
3745 if setflags then
3746 APSR.N = result<31>;
3747 APSR.Z = IsZeroBit(result);
3748 APSR.C = carry;
3749 // APSR.V unchanged
3750 #endif
3751
3752 return EmulateShiftImm(opcode, encoding, SRType_RRX);
3753 }
3754
EmulateShiftImm(const uint32_t opcode,const ARMEncoding encoding,ARM_ShifterType shift_type)3755 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
3756 const ARMEncoding encoding,
3757 ARM_ShifterType shift_type) {
3758 // assert(shift_type == SRType_ASR
3759 // || shift_type == SRType_LSL
3760 // || shift_type == SRType_LSR
3761 // || shift_type == SRType_ROR
3762 // || shift_type == SRType_RRX);
3763
3764 bool success = false;
3765
3766 if (ConditionPassed(opcode)) {
3767 uint32_t Rd; // the destination register
3768 uint32_t Rm; // the first operand register
3769 uint32_t imm5; // encoding for the shift amount
3770 uint32_t carry; // the carry bit after the shift operation
3771 bool setflags;
3772
3773 // Special case handling!
3774 // A8.6.139 ROR (immediate) -- Encoding T1
3775 ARMEncoding use_encoding = encoding;
3776 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3777 // Morph the T1 encoding from the ARM Architecture Manual into T2
3778 // encoding to have the same decoding of bit fields as the other Thumb2
3779 // shift operations.
3780 use_encoding = eEncodingT2;
3781 }
3782
3783 switch (use_encoding) {
3784 case eEncodingT1:
3785 // Due to the above special case handling!
3786 if (shift_type == SRType_ROR)
3787 return false;
3788
3789 Rd = Bits32(opcode, 2, 0);
3790 Rm = Bits32(opcode, 5, 3);
3791 setflags = !InITBlock();
3792 imm5 = Bits32(opcode, 10, 6);
3793 break;
3794 case eEncodingT2:
3795 // A8.6.141 RRX
3796 // There's no imm form of RRX instructions.
3797 if (shift_type == SRType_RRX)
3798 return false;
3799
3800 Rd = Bits32(opcode, 11, 8);
3801 Rm = Bits32(opcode, 3, 0);
3802 setflags = BitIsSet(opcode, 20);
3803 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3804 if (BadReg(Rd) || BadReg(Rm))
3805 return false;
3806 break;
3807 case eEncodingA1:
3808 Rd = Bits32(opcode, 15, 12);
3809 Rm = Bits32(opcode, 3, 0);
3810 setflags = BitIsSet(opcode, 20);
3811 imm5 = Bits32(opcode, 11, 7);
3812 break;
3813 default:
3814 return false;
3815 }
3816
3817 // A8.6.139 ROR (immediate)
3818 if (shift_type == SRType_ROR && imm5 == 0)
3819 shift_type = SRType_RRX;
3820
3821 // Get the first operand.
3822 uint32_t value = ReadCoreReg(Rm, &success);
3823 if (!success)
3824 return false;
3825
3826 // Decode the shift amount if not RRX.
3827 uint32_t amt =
3828 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3829
3830 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3831 if (!success)
3832 return false;
3833
3834 // The context specifies that an immediate is to be moved into Rd.
3835 EmulateInstruction::Context context;
3836 context.type = EmulateInstruction::eContextImmediate;
3837 context.SetNoArgs();
3838
3839 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3840 return false;
3841 }
3842 return true;
3843 }
3844
EmulateShiftReg(const uint32_t opcode,const ARMEncoding encoding,ARM_ShifterType shift_type)3845 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
3846 const ARMEncoding encoding,
3847 ARM_ShifterType shift_type) {
3848 // assert(shift_type == SRType_ASR
3849 // || shift_type == SRType_LSL
3850 // || shift_type == SRType_LSR
3851 // || shift_type == SRType_ROR);
3852
3853 bool success = false;
3854
3855 if (ConditionPassed(opcode)) {
3856 uint32_t Rd; // the destination register
3857 uint32_t Rn; // the first operand register
3858 uint32_t
3859 Rm; // the register whose bottom byte contains the amount to shift by
3860 uint32_t carry; // the carry bit after the shift operation
3861 bool setflags;
3862 switch (encoding) {
3863 case eEncodingT1:
3864 Rd = Bits32(opcode, 2, 0);
3865 Rn = Rd;
3866 Rm = Bits32(opcode, 5, 3);
3867 setflags = !InITBlock();
3868 break;
3869 case eEncodingT2:
3870 Rd = Bits32(opcode, 11, 8);
3871 Rn = Bits32(opcode, 19, 16);
3872 Rm = Bits32(opcode, 3, 0);
3873 setflags = BitIsSet(opcode, 20);
3874 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3875 return false;
3876 break;
3877 case eEncodingA1:
3878 Rd = Bits32(opcode, 15, 12);
3879 Rn = Bits32(opcode, 3, 0);
3880 Rm = Bits32(opcode, 11, 8);
3881 setflags = BitIsSet(opcode, 20);
3882 if (Rd == 15 || Rn == 15 || Rm == 15)
3883 return false;
3884 break;
3885 default:
3886 return false;
3887 }
3888
3889 // Get the first operand.
3890 uint32_t value = ReadCoreReg(Rn, &success);
3891 if (!success)
3892 return false;
3893 // Get the Rm register content.
3894 uint32_t val = ReadCoreReg(Rm, &success);
3895 if (!success)
3896 return false;
3897
3898 // Get the shift amount.
3899 uint32_t amt = Bits32(val, 7, 0);
3900
3901 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3902 if (!success)
3903 return false;
3904
3905 // The context specifies that an immediate is to be moved into Rd.
3906 EmulateInstruction::Context context;
3907 context.type = EmulateInstruction::eContextImmediate;
3908 context.SetNoArgs();
3909
3910 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3911 return false;
3912 }
3913 return true;
3914 }
3915
3916 // LDM loads multiple registers from consecutive memory locations, using an
3917 // address from a base register. Optionally the address just above the highest
3918 // of those locations can be written back to the base register.
EmulateLDM(const uint32_t opcode,const ARMEncoding encoding)3919 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3920 const ARMEncoding encoding) {
3921 #if 0
3922 // ARM pseudo code...
3923 if ConditionPassed()
3924 EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3925 address = R[n];
3926
3927 for i = 0 to 14
3928 if registers<i> == '1' then
3929 R[i] = MemA[address, 4]; address = address + 4;
3930 if registers<15> == '1' then
3931 LoadWritePC (MemA[address, 4]);
3932
3933 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3934 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3935
3936 #endif
3937
3938 bool success = false;
3939 if (ConditionPassed(opcode)) {
3940 uint32_t n;
3941 uint32_t registers = 0;
3942 bool wback;
3943 const uint32_t addr_byte_size = GetAddressByteSize();
3944 switch (encoding) {
3945 case eEncodingT1:
3946 // n = UInt(Rn); registers = '00000000':register_list; wback =
3947 // (registers<n> == '0');
3948 n = Bits32(opcode, 10, 8);
3949 registers = Bits32(opcode, 7, 0);
3950 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3951 wback = BitIsClear(registers, n);
3952 // if BitCount(registers) < 1 then UNPREDICTABLE;
3953 if (BitCount(registers) < 1)
3954 return false;
3955 break;
3956 case eEncodingT2:
3957 // if W == '1' && Rn == '1101' then SEE POP;
3958 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3959 n = Bits32(opcode, 19, 16);
3960 registers = Bits32(opcode, 15, 0);
3961 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3962 wback = BitIsSet(opcode, 21);
3963
3964 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3965 // UNPREDICTABLE;
3966 if ((n == 15) || (BitCount(registers) < 2) ||
3967 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3968 return false;
3969
3970 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3971 // UNPREDICTABLE;
3972 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3973 return false;
3974
3975 // if wback && registers<n> == '1' then UNPREDICTABLE;
3976 if (wback && BitIsSet(registers, n))
3977 return false;
3978 break;
3979
3980 case eEncodingA1:
3981 n = Bits32(opcode, 19, 16);
3982 registers = Bits32(opcode, 15, 0);
3983 wback = BitIsSet(opcode, 21);
3984 if ((n == 15) || (BitCount(registers) < 1))
3985 return false;
3986 break;
3987 default:
3988 return false;
3989 }
3990
3991 int32_t offset = 0;
3992 const addr_t base_address =
3993 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3994 if (!success)
3995 return false;
3996
3997 EmulateInstruction::Context context;
3998 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3999 RegisterInfo dwarf_reg;
4000 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4001 context.SetRegisterPlusOffset(dwarf_reg, offset);
4002
4003 for (int i = 0; i < 14; ++i) {
4004 if (BitIsSet(registers, i)) {
4005 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4006 context.SetRegisterPlusOffset(dwarf_reg, offset);
4007 if (wback && (n == 13)) // Pop Instruction
4008 {
4009 context.type = EmulateInstruction::eContextPopRegisterOffStack;
4010 context.SetAddress(base_address + offset);
4011 }
4012
4013 // R[i] = MemA [address, 4]; address = address + 4;
4014 uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
4015 0, &success);
4016 if (!success)
4017 return false;
4018
4019 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4020 data))
4021 return false;
4022
4023 offset += addr_byte_size;
4024 }
4025 }
4026
4027 if (BitIsSet(registers, 15)) {
4028 // LoadWritePC (MemA [address, 4]);
4029 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4030 context.SetRegisterPlusOffset(dwarf_reg, offset);
4031 uint32_t data =
4032 MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4033 if (!success)
4034 return false;
4035 // In ARMv5T and above, this is an interworking branch.
4036 if (!LoadWritePC(context, data))
4037 return false;
4038 }
4039
4040 if (wback && BitIsClear(registers, n)) {
4041 // R[n] = R[n] + 4 * BitCount (registers)
4042 int32_t offset = addr_byte_size * BitCount(registers);
4043 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4044 context.SetRegisterPlusOffset(dwarf_reg, offset);
4045
4046 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4047 base_address + offset))
4048 return false;
4049 }
4050 if (wback && BitIsSet(registers, n))
4051 // R[n] bits(32) UNKNOWN;
4052 return WriteBits32Unknown(n);
4053 }
4054 return true;
4055 }
4056
4057 // LDMDA loads multiple registers from consecutive memory locations using an
4058 // address from a base register.
4059 // The consecutive memory locations end at this address and the address just
4060 // below the lowest of those locations can optionally be written back to the
4061 // base register.
EmulateLDMDA(const uint32_t opcode,const ARMEncoding encoding)4062 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
4063 const ARMEncoding encoding) {
4064 #if 0
4065 // ARM pseudo code...
4066 if ConditionPassed() then
4067 EncodingSpecificOperations();
4068 address = R[n] - 4*BitCount(registers) + 4;
4069
4070 for i = 0 to 14
4071 if registers<i> == '1' then
4072 R[i] = MemA[address,4]; address = address + 4;
4073
4074 if registers<15> == '1' then
4075 LoadWritePC(MemA[address,4]);
4076
4077 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4078 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4079 #endif
4080
4081 bool success = false;
4082
4083 if (ConditionPassed(opcode)) {
4084 uint32_t n;
4085 uint32_t registers = 0;
4086 bool wback;
4087 const uint32_t addr_byte_size = GetAddressByteSize();
4088
4089 // EncodingSpecificOperations();
4090 switch (encoding) {
4091 case eEncodingA1:
4092 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4093 n = Bits32(opcode, 19, 16);
4094 registers = Bits32(opcode, 15, 0);
4095 wback = BitIsSet(opcode, 21);
4096
4097 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4098 if ((n == 15) || (BitCount(registers) < 1))
4099 return false;
4100
4101 break;
4102
4103 default:
4104 return false;
4105 }
4106 // address = R[n] - 4*BitCount(registers) + 4;
4107
4108 int32_t offset = 0;
4109 addr_t Rn = ReadCoreReg(n, &success);
4110
4111 if (!success)
4112 return false;
4113
4114 addr_t address =
4115 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
4116
4117 EmulateInstruction::Context context;
4118 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4119 RegisterInfo dwarf_reg;
4120 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4121 context.SetRegisterPlusOffset(dwarf_reg, offset);
4122
4123 // for i = 0 to 14
4124 for (int i = 0; i < 14; ++i) {
4125 // if registers<i> == '1' then
4126 if (BitIsSet(registers, i)) {
4127 // R[i] = MemA[address,4]; address = address + 4;
4128 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4129 uint32_t data =
4130 MemARead(context, address + offset, addr_byte_size, 0, &success);
4131 if (!success)
4132 return false;
4133 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4134 data))
4135 return false;
4136 offset += addr_byte_size;
4137 }
4138 }
4139
4140 // if registers<15> == '1' then
4141 // LoadWritePC(MemA[address,4]);
4142 if (BitIsSet(registers, 15)) {
4143 context.SetRegisterPlusOffset(dwarf_reg, offset);
4144 uint32_t data =
4145 MemARead(context, address + offset, addr_byte_size, 0, &success);
4146 if (!success)
4147 return false;
4148 // In ARMv5T and above, this is an interworking branch.
4149 if (!LoadWritePC(context, data))
4150 return false;
4151 }
4152
4153 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4154 if (wback && BitIsClear(registers, n)) {
4155 if (!success)
4156 return false;
4157
4158 offset = (addr_byte_size * BitCount(registers)) * -1;
4159 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4160 context.SetImmediateSigned(offset);
4161 addr_t addr = Rn + offset;
4162 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4163 addr))
4164 return false;
4165 }
4166
4167 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4168 if (wback && BitIsSet(registers, n))
4169 return WriteBits32Unknown(n);
4170 }
4171 return true;
4172 }
4173
4174 // LDMDB loads multiple registers from consecutive memory locations using an
4175 // address from a base register. The
4176 // consecutive memory locations end just below this address, and the address of
4177 // the lowest of those locations can be optionally written back to the base
4178 // register.
EmulateLDMDB(const uint32_t opcode,const ARMEncoding encoding)4179 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
4180 const ARMEncoding encoding) {
4181 #if 0
4182 // ARM pseudo code...
4183 if ConditionPassed() then
4184 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4185 address = R[n] - 4*BitCount(registers);
4186
4187 for i = 0 to 14
4188 if registers<i> == '1' then
4189 R[i] = MemA[address,4]; address = address + 4;
4190 if registers<15> == '1' then
4191 LoadWritePC(MemA[address,4]);
4192
4193 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4194 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
4195 #endif
4196
4197 bool success = false;
4198
4199 if (ConditionPassed(opcode)) {
4200 uint32_t n;
4201 uint32_t registers = 0;
4202 bool wback;
4203 const uint32_t addr_byte_size = GetAddressByteSize();
4204 switch (encoding) {
4205 case eEncodingT1:
4206 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
4207 n = Bits32(opcode, 19, 16);
4208 registers = Bits32(opcode, 15, 0);
4209 registers = registers & 0xdfff; // Make sure bit 13 is a zero.
4210 wback = BitIsSet(opcode, 21);
4211
4212 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4213 // UNPREDICTABLE;
4214 if ((n == 15) || (BitCount(registers) < 2) ||
4215 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4216 return false;
4217
4218 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4219 // UNPREDICTABLE;
4220 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4221 return false;
4222
4223 // if wback && registers<n> == '1' then UNPREDICTABLE;
4224 if (wback && BitIsSet(registers, n))
4225 return false;
4226
4227 break;
4228
4229 case eEncodingA1:
4230 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4231 n = Bits32(opcode, 19, 16);
4232 registers = Bits32(opcode, 15, 0);
4233 wback = BitIsSet(opcode, 21);
4234
4235 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4236 if ((n == 15) || (BitCount(registers) < 1))
4237 return false;
4238
4239 break;
4240
4241 default:
4242 return false;
4243 }
4244
4245 // address = R[n] - 4*BitCount(registers);
4246
4247 int32_t offset = 0;
4248 addr_t Rn =
4249 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4250
4251 if (!success)
4252 return false;
4253
4254 addr_t address = Rn - (addr_byte_size * BitCount(registers));
4255 EmulateInstruction::Context context;
4256 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4257 RegisterInfo dwarf_reg;
4258 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4259 context.SetRegisterPlusOffset(dwarf_reg, Rn - address);
4260
4261 for (int i = 0; i < 14; ++i) {
4262 if (BitIsSet(registers, i)) {
4263 // R[i] = MemA[address,4]; address = address + 4;
4264 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4265 uint32_t data =
4266 MemARead(context, address + offset, addr_byte_size, 0, &success);
4267 if (!success)
4268 return false;
4269
4270 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4271 data))
4272 return false;
4273
4274 offset += addr_byte_size;
4275 }
4276 }
4277
4278 // if registers<15> == '1' then
4279 // LoadWritePC(MemA[address,4]);
4280 if (BitIsSet(registers, 15)) {
4281 context.SetRegisterPlusOffset(dwarf_reg, offset);
4282 uint32_t data =
4283 MemARead(context, address + offset, addr_byte_size, 0, &success);
4284 if (!success)
4285 return false;
4286 // In ARMv5T and above, this is an interworking branch.
4287 if (!LoadWritePC(context, data))
4288 return false;
4289 }
4290
4291 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4292 if (wback && BitIsClear(registers, n)) {
4293 if (!success)
4294 return false;
4295
4296 offset = (addr_byte_size * BitCount(registers)) * -1;
4297 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4298 context.SetImmediateSigned(offset);
4299 addr_t addr = Rn + offset;
4300 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4301 addr))
4302 return false;
4303 }
4304
4305 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4306 // possible for encoding A1
4307 if (wback && BitIsSet(registers, n))
4308 return WriteBits32Unknown(n);
4309 }
4310 return true;
4311 }
4312
4313 // LDMIB loads multiple registers from consecutive memory locations using an
4314 // address from a base register. The
4315 // consecutive memory locations start just above this address, and thea ddress
4316 // of the last of those locations can optinoally be written back to the base
4317 // register.
EmulateLDMIB(const uint32_t opcode,const ARMEncoding encoding)4318 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
4319 const ARMEncoding encoding) {
4320 #if 0
4321 if ConditionPassed() then
4322 EncodingSpecificOperations();
4323 address = R[n] + 4;
4324
4325 for i = 0 to 14
4326 if registers<i> == '1' then
4327 R[i] = MemA[address,4]; address = address + 4;
4328 if registers<15> == '1' then
4329 LoadWritePC(MemA[address,4]);
4330
4331 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4332 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4333 #endif
4334
4335 bool success = false;
4336
4337 if (ConditionPassed(opcode)) {
4338 uint32_t n;
4339 uint32_t registers = 0;
4340 bool wback;
4341 const uint32_t addr_byte_size = GetAddressByteSize();
4342 switch (encoding) {
4343 case eEncodingA1:
4344 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4345 n = Bits32(opcode, 19, 16);
4346 registers = Bits32(opcode, 15, 0);
4347 wback = BitIsSet(opcode, 21);
4348
4349 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4350 if ((n == 15) || (BitCount(registers) < 1))
4351 return false;
4352
4353 break;
4354 default:
4355 return false;
4356 }
4357 // address = R[n] + 4;
4358
4359 int32_t offset = 0;
4360 addr_t Rn =
4361 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4362
4363 if (!success)
4364 return false;
4365
4366 addr_t address = Rn + addr_byte_size;
4367
4368 EmulateInstruction::Context context;
4369 context.type = EmulateInstruction::eContextRegisterPlusOffset;
4370 RegisterInfo dwarf_reg;
4371 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4372 context.SetRegisterPlusOffset(dwarf_reg, offset);
4373
4374 for (int i = 0; i < 14; ++i) {
4375 if (BitIsSet(registers, i)) {
4376 // R[i] = MemA[address,4]; address = address + 4;
4377
4378 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size);
4379 uint32_t data =
4380 MemARead(context, address + offset, addr_byte_size, 0, &success);
4381 if (!success)
4382 return false;
4383
4384 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4385 data))
4386 return false;
4387
4388 offset += addr_byte_size;
4389 }
4390 }
4391
4392 // if registers<15> == '1' then
4393 // LoadWritePC(MemA[address,4]);
4394 if (BitIsSet(registers, 15)) {
4395 context.SetRegisterPlusOffset(dwarf_reg, offset);
4396 uint32_t data =
4397 MemARead(context, address + offset, addr_byte_size, 0, &success);
4398 if (!success)
4399 return false;
4400 // In ARMv5T and above, this is an interworking branch.
4401 if (!LoadWritePC(context, data))
4402 return false;
4403 }
4404
4405 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4406 if (wback && BitIsClear(registers, n)) {
4407 if (!success)
4408 return false;
4409
4410 offset = addr_byte_size * BitCount(registers);
4411 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4412 context.SetImmediateSigned(offset);
4413 addr_t addr = Rn + offset;
4414 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4415 addr))
4416 return false;
4417 }
4418
4419 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4420 // possible for encoding A1
4421 if (wback && BitIsSet(registers, n))
4422 return WriteBits32Unknown(n);
4423 }
4424 return true;
4425 }
4426
4427 // Load Register (immediate) calculates an address from a base register value
4428 // and an immediate offset, loads a word from memory, and writes to a register.
4429 // LDR (immediate, Thumb)
EmulateLDRRtRnImm(const uint32_t opcode,const ARMEncoding encoding)4430 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
4431 const ARMEncoding encoding) {
4432 #if 0
4433 // ARM pseudo code...
4434 if (ConditionPassed())
4435 {
4436 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4437 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4438 address = if index then offset_addr else R[n];
4439 data = MemU[address,4];
4440 if wback then R[n] = offset_addr;
4441 if t == 15 then
4442 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
4443 elsif UnalignedSupport() || address<1:0> = '00' then
4444 R[t] = data;
4445 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
4446 }
4447 #endif
4448
4449 bool success = false;
4450
4451 if (ConditionPassed(opcode)) {
4452 uint32_t Rt; // the destination register
4453 uint32_t Rn; // the base register
4454 uint32_t imm32; // the immediate offset used to form the address
4455 addr_t offset_addr; // the offset address
4456 addr_t address; // the calculated address
4457 uint32_t data; // the literal data value from memory load
4458 bool add, index, wback;
4459 switch (encoding) {
4460 case eEncodingT1:
4461 Rt = Bits32(opcode, 2, 0);
4462 Rn = Bits32(opcode, 5, 3);
4463 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
4464 // index = TRUE; add = TRUE; wback = FALSE
4465 add = true;
4466 index = true;
4467 wback = false;
4468
4469 break;
4470
4471 case eEncodingT2:
4472 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4473 Rt = Bits32(opcode, 10, 8);
4474 Rn = 13;
4475 imm32 = Bits32(opcode, 7, 0) << 2;
4476
4477 // index = TRUE; add = TRUE; wback = FALSE;
4478 index = true;
4479 add = true;
4480 wback = false;
4481
4482 break;
4483
4484 case eEncodingT3:
4485 // if Rn == '1111' then SEE LDR (literal);
4486 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4487 Rt = Bits32(opcode, 15, 12);
4488 Rn = Bits32(opcode, 19, 16);
4489 imm32 = Bits32(opcode, 11, 0);
4490
4491 // index = TRUE; add = TRUE; wback = FALSE;
4492 index = true;
4493 add = true;
4494 wback = false;
4495
4496 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4497 if ((Rt == 15) && InITBlock() && !LastInITBlock())
4498 return false;
4499
4500 break;
4501
4502 case eEncodingT4:
4503 // if Rn == '1111' then SEE LDR (literal);
4504 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4505 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
4506 // '00000100' then SEE POP;
4507 // if P == '0' && W == '0' then UNDEFINED;
4508 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
4509 return false;
4510
4511 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4512 Rt = Bits32(opcode, 15, 12);
4513 Rn = Bits32(opcode, 19, 16);
4514 imm32 = Bits32(opcode, 7, 0);
4515
4516 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4517 index = BitIsSet(opcode, 10);
4518 add = BitIsSet(opcode, 9);
4519 wback = BitIsSet(opcode, 8);
4520
4521 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4522 // then UNPREDICTABLE;
4523 if ((wback && (Rn == Rt)) ||
4524 ((Rt == 15) && InITBlock() && !LastInITBlock()))
4525 return false;
4526
4527 break;
4528
4529 default:
4530 return false;
4531 }
4532 uint32_t base = ReadCoreReg(Rn, &success);
4533 if (!success)
4534 return false;
4535 if (add)
4536 offset_addr = base + imm32;
4537 else
4538 offset_addr = base - imm32;
4539
4540 address = (index ? offset_addr : base);
4541
4542 RegisterInfo base_reg;
4543 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4544 if (wback) {
4545 EmulateInstruction::Context ctx;
4546 if (Rn == 13) {
4547 ctx.type = eContextAdjustStackPointer;
4548 ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4549 } else if (Rn == GetFramePointerRegisterNumber()) {
4550 ctx.type = eContextSetFramePointer;
4551 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4552 } else {
4553 ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4554 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4555 }
4556
4557 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
4558 offset_addr))
4559 return false;
4560 }
4561
4562 // Prepare to write to the Rt register.
4563 EmulateInstruction::Context context;
4564 context.type = EmulateInstruction::eContextRegisterLoad;
4565 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4566
4567 // Read memory from the address.
4568 data = MemURead(context, address, 4, 0, &success);
4569 if (!success)
4570 return false;
4571
4572 if (Rt == 15) {
4573 if (Bits32(address, 1, 0) == 0) {
4574 if (!LoadWritePC(context, data))
4575 return false;
4576 } else
4577 return false;
4578 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4579 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
4580 data))
4581 return false;
4582 } else
4583 WriteBits32Unknown(Rt);
4584 }
4585 return true;
4586 }
4587
4588 // STM (Store Multiple Increment After) stores multiple registers to consecutive
4589 // memory locations using an address
4590 // from a base register. The consecutive memory locations start at this
4591 // address, and the address just above the last of those locations can
4592 // optionally be written back to the base register.
EmulateSTM(const uint32_t opcode,const ARMEncoding encoding)4593 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4594 const ARMEncoding encoding) {
4595 #if 0
4596 if ConditionPassed() then
4597 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4598 address = R[n];
4599
4600 for i = 0 to 14
4601 if registers<i> == '1' then
4602 if i == n && wback && i != LowestSetBit(registers) then
4603 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4604 else
4605 MemA[address,4] = R[i];
4606 address = address + 4;
4607
4608 if registers<15> == '1' then // Only possible for encoding A1
4609 MemA[address,4] = PCStoreValue();
4610 if wback then R[n] = R[n] + 4*BitCount(registers);
4611 #endif
4612
4613 bool success = false;
4614
4615 if (ConditionPassed(opcode)) {
4616 uint32_t n;
4617 uint32_t registers = 0;
4618 bool wback;
4619 const uint32_t addr_byte_size = GetAddressByteSize();
4620
4621 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4622 switch (encoding) {
4623 case eEncodingT1:
4624 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4625 n = Bits32(opcode, 10, 8);
4626 registers = Bits32(opcode, 7, 0);
4627 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4628 wback = true;
4629
4630 // if BitCount(registers) < 1 then UNPREDICTABLE;
4631 if (BitCount(registers) < 1)
4632 return false;
4633
4634 break;
4635
4636 case eEncodingT2:
4637 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4638 n = Bits32(opcode, 19, 16);
4639 registers = Bits32(opcode, 15, 0);
4640 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4641 wback = BitIsSet(opcode, 21);
4642
4643 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4644 if ((n == 15) || (BitCount(registers) < 2))
4645 return false;
4646
4647 // if wback && registers<n> == '1' then UNPREDICTABLE;
4648 if (wback && BitIsSet(registers, n))
4649 return false;
4650
4651 break;
4652
4653 case eEncodingA1:
4654 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4655 n = Bits32(opcode, 19, 16);
4656 registers = Bits32(opcode, 15, 0);
4657 wback = BitIsSet(opcode, 21);
4658
4659 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4660 if ((n == 15) || (BitCount(registers) < 1))
4661 return false;
4662
4663 break;
4664
4665 default:
4666 return false;
4667 }
4668
4669 // address = R[n];
4670 int32_t offset = 0;
4671 const addr_t address =
4672 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4673 if (!success)
4674 return false;
4675
4676 EmulateInstruction::Context context;
4677 context.type = EmulateInstruction::eContextRegisterStore;
4678 RegisterInfo base_reg;
4679 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4680
4681 // for i = 0 to 14
4682 uint32_t lowest_set_bit = 14;
4683 for (uint32_t i = 0; i < 14; ++i) {
4684 // if registers<i> == '1' then
4685 if (BitIsSet(registers, i)) {
4686 if (i < lowest_set_bit)
4687 lowest_set_bit = i;
4688 // if i == n && wback && i != LowestSetBit(registers) then
4689 if ((i == n) && wback && (i != lowest_set_bit))
4690 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4691 // T1 and A1
4692 WriteBits32UnknownToMemory(address + offset);
4693 else {
4694 // MemA[address,4] = R[i];
4695 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4696 0, &success);
4697 if (!success)
4698 return false;
4699
4700 RegisterInfo data_reg;
4701 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4702 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
4703 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4704 return false;
4705 }
4706
4707 // address = address + 4;
4708 offset += addr_byte_size;
4709 }
4710 }
4711
4712 // if registers<15> == '1' then // Only possible for encoding A1
4713 // MemA[address,4] = PCStoreValue();
4714 if (BitIsSet(registers, 15)) {
4715 RegisterInfo pc_reg;
4716 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4717 context.SetRegisterPlusOffset(pc_reg, 8);
4718 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4719 if (!success)
4720 return false;
4721
4722 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4723 return false;
4724 }
4725
4726 // if wback then R[n] = R[n] + 4*BitCount(registers);
4727 if (wback) {
4728 offset = addr_byte_size * BitCount(registers);
4729 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4730 context.SetImmediateSigned(offset);
4731 addr_t data = address + offset;
4732 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4733 data))
4734 return false;
4735 }
4736 }
4737 return true;
4738 }
4739
4740 // STMDA (Store Multiple Decrement After) stores multiple registers to
4741 // consecutive memory locations using an address from a base register. The
4742 // consecutive memory locations end at this address, and the address just below
4743 // the lowest of those locations can optionally be written back to the base
4744 // register.
EmulateSTMDA(const uint32_t opcode,const ARMEncoding encoding)4745 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4746 const ARMEncoding encoding) {
4747 #if 0
4748 if ConditionPassed() then
4749 EncodingSpecificOperations();
4750 address = R[n] - 4*BitCount(registers) + 4;
4751
4752 for i = 0 to 14
4753 if registers<i> == '1' then
4754 if i == n && wback && i != LowestSetBit(registers) then
4755 MemA[address,4] = bits(32) UNKNOWN;
4756 else
4757 MemA[address,4] = R[i];
4758 address = address + 4;
4759
4760 if registers<15> == '1' then
4761 MemA[address,4] = PCStoreValue();
4762
4763 if wback then R[n] = R[n] - 4*BitCount(registers);
4764 #endif
4765
4766 bool success = false;
4767
4768 if (ConditionPassed(opcode)) {
4769 uint32_t n;
4770 uint32_t registers = 0;
4771 bool wback;
4772 const uint32_t addr_byte_size = GetAddressByteSize();
4773
4774 // EncodingSpecificOperations();
4775 switch (encoding) {
4776 case eEncodingA1:
4777 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4778 n = Bits32(opcode, 19, 16);
4779 registers = Bits32(opcode, 15, 0);
4780 wback = BitIsSet(opcode, 21);
4781
4782 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4783 if ((n == 15) || (BitCount(registers) < 1))
4784 return false;
4785 break;
4786 default:
4787 return false;
4788 }
4789
4790 // address = R[n] - 4*BitCount(registers) + 4;
4791 int32_t offset = 0;
4792 addr_t Rn = ReadCoreReg(n, &success);
4793 if (!success)
4794 return false;
4795
4796 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4797
4798 EmulateInstruction::Context context;
4799 context.type = EmulateInstruction::eContextRegisterStore;
4800 RegisterInfo base_reg;
4801 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4802
4803 // for i = 0 to 14
4804 uint32_t lowest_bit_set = 14;
4805 for (uint32_t i = 0; i < 14; ++i) {
4806 // if registers<i> == '1' then
4807 if (BitIsSet(registers, i)) {
4808 if (i < lowest_bit_set)
4809 lowest_bit_set = i;
4810 // if i == n && wback && i != LowestSetBit(registers) then
4811 if ((i == n) && wback && (i != lowest_bit_set))
4812 // MemA[address,4] = bits(32) UNKNOWN;
4813 WriteBits32UnknownToMemory(address + offset);
4814 else {
4815 // MemA[address,4] = R[i];
4816 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4817 0, &success);
4818 if (!success)
4819 return false;
4820
4821 RegisterInfo data_reg;
4822 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4823 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4824 Rn - (address + offset));
4825 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4826 return false;
4827 }
4828
4829 // address = address + 4;
4830 offset += addr_byte_size;
4831 }
4832 }
4833
4834 // if registers<15> == '1' then
4835 // MemA[address,4] = PCStoreValue();
4836 if (BitIsSet(registers, 15)) {
4837 RegisterInfo pc_reg;
4838 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4839 context.SetRegisterPlusOffset(pc_reg, 8);
4840 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4841 if (!success)
4842 return false;
4843
4844 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4845 return false;
4846 }
4847
4848 // if wback then R[n] = R[n] - 4*BitCount(registers);
4849 if (wback) {
4850 offset = (addr_byte_size * BitCount(registers)) * -1;
4851 context.type = EmulateInstruction::eContextAdjustBaseRegister;
4852 context.SetImmediateSigned(offset);
4853 addr_t data = Rn + offset;
4854 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4855 data))
4856 return false;
4857 }
4858 }
4859 return true;
4860 }
4861
4862 // STMDB (Store Multiple Decrement Before) stores multiple registers to
4863 // consecutive memory locations using an address from a base register. The
4864 // consecutive memory locations end just below this address, and the address of
4865 // the first of those locations can optionally be written back to the base
4866 // register.
EmulateSTMDB(const uint32_t opcode,const ARMEncoding encoding)4867 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4868 const ARMEncoding encoding) {
4869 #if 0
4870 if ConditionPassed() then
4871 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4872 address = R[n] - 4*BitCount(registers);
4873
4874 for i = 0 to 14
4875 if registers<i> == '1' then
4876 if i == n && wback && i != LowestSetBit(registers) then
4877 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4878 else
4879 MemA[address,4] = R[i];
4880 address = address + 4;
4881
4882 if registers<15> == '1' then // Only possible for encoding A1
4883 MemA[address,4] = PCStoreValue();
4884
4885 if wback then R[n] = R[n] - 4*BitCount(registers);
4886 #endif
4887
4888 bool success = false;
4889
4890 if (ConditionPassed(opcode)) {
4891 uint32_t n;
4892 uint32_t registers = 0;
4893 bool wback;
4894 const uint32_t addr_byte_size = GetAddressByteSize();
4895
4896 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4897 switch (encoding) {
4898 case eEncodingT1:
4899 // if W == '1' && Rn == '1101' then SEE PUSH;
4900 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4901 // See PUSH
4902 }
4903 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4904 n = Bits32(opcode, 19, 16);
4905 registers = Bits32(opcode, 15, 0);
4906 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4907 wback = BitIsSet(opcode, 21);
4908 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4909 if ((n == 15) || BitCount(registers) < 2)
4910 return false;
4911 // if wback && registers<n> == '1' then UNPREDICTABLE;
4912 if (wback && BitIsSet(registers, n))
4913 return false;
4914 break;
4915
4916 case eEncodingA1:
4917 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4918 // PUSH;
4919 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4920 BitCount(Bits32(opcode, 15, 0)) >= 2) {
4921 // See Push
4922 }
4923 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4924 n = Bits32(opcode, 19, 16);
4925 registers = Bits32(opcode, 15, 0);
4926 wback = BitIsSet(opcode, 21);
4927 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4928 if ((n == 15) || BitCount(registers) < 1)
4929 return false;
4930 break;
4931
4932 default:
4933 return false;
4934 }
4935
4936 // address = R[n] - 4*BitCount(registers);
4937
4938 int32_t offset = 0;
4939 addr_t Rn =
4940 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4941 if (!success)
4942 return false;
4943
4944 addr_t address = Rn - (addr_byte_size * BitCount(registers));
4945
4946 EmulateInstruction::Context context;
4947 context.type = EmulateInstruction::eContextRegisterStore;
4948 RegisterInfo base_reg;
4949 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4950
4951 // for i = 0 to 14
4952 uint32_t lowest_set_bit = 14;
4953 for (uint32_t i = 0; i < 14; ++i) {
4954 // if registers<i> == '1' then
4955 if (BitIsSet(registers, i)) {
4956 if (i < lowest_set_bit)
4957 lowest_set_bit = i;
4958 // if i == n && wback && i != LowestSetBit(registers) then
4959 if ((i == n) && wback && (i != lowest_set_bit))
4960 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4961 // A1
4962 WriteBits32UnknownToMemory(address + offset);
4963 else {
4964 // MemA[address,4] = R[i];
4965 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4966 0, &success);
4967 if (!success)
4968 return false;
4969
4970 RegisterInfo data_reg;
4971 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4972 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4973 Rn - (address + offset));
4974 if (!MemAWrite(context, address + offset, data, addr_byte_size))
4975 return false;
4976 }
4977
4978 // address = address + 4;
4979 offset += addr_byte_size;
4980 }
4981 }
4982
4983 // if registers<15> == '1' then // Only possible for encoding A1
4984 // MemA[address,4] = PCStoreValue();
4985 if (BitIsSet(registers, 15)) {
4986 RegisterInfo pc_reg;
4987 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4988 context.SetRegisterPlusOffset(pc_reg, 8);
4989 const uint32_t pc = ReadCoreReg(PC_REG, &success);
4990 if (!success)
4991 return false;
4992
4993 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4994 return false;
4995 }
4996
4997 // if wback then R[n] = R[n] - 4*BitCount(registers);
4998 if (wback) {
4999 offset = (addr_byte_size * BitCount(registers)) * -1;
5000 context.type = EmulateInstruction::eContextAdjustBaseRegister;
5001 context.SetImmediateSigned(offset);
5002 addr_t data = Rn + offset;
5003 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5004 data))
5005 return false;
5006 }
5007 }
5008 return true;
5009 }
5010
5011 // STMIB (Store Multiple Increment Before) stores multiple registers to
5012 // consecutive memory locations using an address from a base register. The
5013 // consecutive memory locations start just above this address, and the address
5014 // of the last of those locations can optionally be written back to the base
5015 // register.
EmulateSTMIB(const uint32_t opcode,const ARMEncoding encoding)5016 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
5017 const ARMEncoding encoding) {
5018 #if 0
5019 if ConditionPassed() then
5020 EncodingSpecificOperations();
5021 address = R[n] + 4;
5022
5023 for i = 0 to 14
5024 if registers<i> == '1' then
5025 if i == n && wback && i != LowestSetBit(registers) then
5026 MemA[address,4] = bits(32) UNKNOWN;
5027 else
5028 MemA[address,4] = R[i];
5029 address = address + 4;
5030
5031 if registers<15> == '1' then
5032 MemA[address,4] = PCStoreValue();
5033
5034 if wback then R[n] = R[n] + 4*BitCount(registers);
5035 #endif
5036
5037 bool success = false;
5038
5039 if (ConditionPassed(opcode)) {
5040 uint32_t n;
5041 uint32_t registers = 0;
5042 bool wback;
5043 const uint32_t addr_byte_size = GetAddressByteSize();
5044
5045 // EncodingSpecificOperations();
5046 switch (encoding) {
5047 case eEncodingA1:
5048 // n = UInt(Rn); registers = register_list; wback = (W == '1');
5049 n = Bits32(opcode, 19, 16);
5050 registers = Bits32(opcode, 15, 0);
5051 wback = BitIsSet(opcode, 21);
5052
5053 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
5054 if ((n == 15) && (BitCount(registers) < 1))
5055 return false;
5056 break;
5057 default:
5058 return false;
5059 }
5060 // address = R[n] + 4;
5061
5062 int32_t offset = 0;
5063 addr_t Rn = ReadCoreReg(n, &success);
5064 if (!success)
5065 return false;
5066
5067 addr_t address = Rn + addr_byte_size;
5068
5069 EmulateInstruction::Context context;
5070 context.type = EmulateInstruction::eContextRegisterStore;
5071 RegisterInfo base_reg;
5072 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5073
5074 uint32_t lowest_set_bit = 14;
5075 // for i = 0 to 14
5076 for (uint32_t i = 0; i < 14; ++i) {
5077 // if registers<i> == '1' then
5078 if (BitIsSet(registers, i)) {
5079 if (i < lowest_set_bit)
5080 lowest_set_bit = i;
5081 // if i == n && wback && i != LowestSetBit(registers) then
5082 if ((i == n) && wback && (i != lowest_set_bit))
5083 // MemA[address,4] = bits(32) UNKNOWN;
5084 WriteBits32UnknownToMemory(address + offset);
5085 // else
5086 else {
5087 // MemA[address,4] = R[i];
5088 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
5089 0, &success);
5090 if (!success)
5091 return false;
5092
5093 RegisterInfo data_reg;
5094 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
5095 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5096 offset + addr_byte_size);
5097 if (!MemAWrite(context, address + offset, data, addr_byte_size))
5098 return false;
5099 }
5100
5101 // address = address + 4;
5102 offset += addr_byte_size;
5103 }
5104 }
5105
5106 // if registers<15> == '1' then
5107 // MemA[address,4] = PCStoreValue();
5108 if (BitIsSet(registers, 15)) {
5109 RegisterInfo pc_reg;
5110 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
5111 context.SetRegisterPlusOffset(pc_reg, 8);
5112 const uint32_t pc = ReadCoreReg(PC_REG, &success);
5113 if (!success)
5114 return false;
5115
5116 if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5117 return false;
5118 }
5119
5120 // if wback then R[n] = R[n] + 4*BitCount(registers);
5121 if (wback) {
5122 offset = addr_byte_size * BitCount(registers);
5123 context.type = EmulateInstruction::eContextAdjustBaseRegister;
5124 context.SetImmediateSigned(offset);
5125 addr_t data = Rn + offset;
5126 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5127 data))
5128 return false;
5129 }
5130 }
5131 return true;
5132 }
5133
5134 // STR (store immediate) calculates an address from a base register value and an
5135 // immediate offset, and stores a word
5136 // from a register to memory. It can use offset, post-indexed, or pre-indexed
5137 // addressing.
EmulateSTRThumb(const uint32_t opcode,const ARMEncoding encoding)5138 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
5139 const ARMEncoding encoding) {
5140 #if 0
5141 if ConditionPassed() then
5142 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5143 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5144 address = if index then offset_addr else R[n];
5145 if UnalignedSupport() || address<1:0> == '00' then
5146 MemU[address,4] = R[t];
5147 else // Can only occur before ARMv7
5148 MemU[address,4] = bits(32) UNKNOWN;
5149 if wback then R[n] = offset_addr;
5150 #endif
5151
5152 bool success = false;
5153
5154 if (ConditionPassed(opcode)) {
5155 const uint32_t addr_byte_size = GetAddressByteSize();
5156
5157 uint32_t t;
5158 uint32_t n;
5159 uint32_t imm32;
5160 bool index;
5161 bool add;
5162 bool wback;
5163 // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5164 switch (encoding) {
5165 case eEncodingT1:
5166 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
5167 t = Bits32(opcode, 2, 0);
5168 n = Bits32(opcode, 5, 3);
5169 imm32 = Bits32(opcode, 10, 6) << 2;
5170
5171 // index = TRUE; add = TRUE; wback = FALSE;
5172 index = true;
5173 add = false;
5174 wback = false;
5175 break;
5176
5177 case eEncodingT2:
5178 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
5179 t = Bits32(opcode, 10, 8);
5180 n = 13;
5181 imm32 = Bits32(opcode, 7, 0) << 2;
5182
5183 // index = TRUE; add = TRUE; wback = FALSE;
5184 index = true;
5185 add = true;
5186 wback = false;
5187 break;
5188
5189 case eEncodingT3:
5190 // if Rn == '1111' then UNDEFINED;
5191 if (Bits32(opcode, 19, 16) == 15)
5192 return false;
5193
5194 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5195 t = Bits32(opcode, 15, 12);
5196 n = Bits32(opcode, 19, 16);
5197 imm32 = Bits32(opcode, 11, 0);
5198
5199 // index = TRUE; add = TRUE; wback = FALSE;
5200 index = true;
5201 add = true;
5202 wback = false;
5203
5204 // if t == 15 then UNPREDICTABLE;
5205 if (t == 15)
5206 return false;
5207 break;
5208
5209 case eEncodingT4:
5210 // if P == '1' && U == '1' && W == '0' then SEE STRT;
5211 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
5212 // '00000100' then SEE PUSH;
5213 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5214 if ((Bits32(opcode, 19, 16) == 15) ||
5215 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
5216 return false;
5217
5218 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5219 t = Bits32(opcode, 15, 12);
5220 n = Bits32(opcode, 19, 16);
5221 imm32 = Bits32(opcode, 7, 0);
5222
5223 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5224 index = BitIsSet(opcode, 10);
5225 add = BitIsSet(opcode, 9);
5226 wback = BitIsSet(opcode, 8);
5227
5228 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
5229 if ((t == 15) || (wback && (n == t)))
5230 return false;
5231 break;
5232
5233 default:
5234 return false;
5235 }
5236
5237 addr_t offset_addr;
5238 addr_t address;
5239
5240 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5241 uint32_t base_address = ReadCoreReg(n, &success);
5242 if (!success)
5243 return false;
5244
5245 if (add)
5246 offset_addr = base_address + imm32;
5247 else
5248 offset_addr = base_address - imm32;
5249
5250 // address = if index then offset_addr else R[n];
5251 if (index)
5252 address = offset_addr;
5253 else
5254 address = base_address;
5255
5256 EmulateInstruction::Context context;
5257 if (n == 13)
5258 context.type = eContextPushRegisterOnStack;
5259 else
5260 context.type = eContextRegisterStore;
5261
5262 RegisterInfo base_reg;
5263 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5264
5265 // if UnalignedSupport() || address<1:0> == '00' then
5266 if (UnalignedSupport() ||
5267 (BitIsClear(address, 1) && BitIsClear(address, 0))) {
5268 // MemU[address,4] = R[t];
5269 uint32_t data =
5270 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5271 if (!success)
5272 return false;
5273
5274 RegisterInfo data_reg;
5275 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5276 int32_t offset = address - base_address;
5277 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
5278 if (!MemUWrite(context, address, data, addr_byte_size))
5279 return false;
5280 } else {
5281 // MemU[address,4] = bits(32) UNKNOWN;
5282 WriteBits32UnknownToMemory(address);
5283 }
5284
5285 // if wback then R[n] = offset_addr;
5286 if (wback) {
5287 if (n == 13)
5288 context.type = eContextAdjustStackPointer;
5289 else
5290 context.type = eContextAdjustBaseRegister;
5291 context.SetAddress(offset_addr);
5292
5293 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5294 offset_addr))
5295 return false;
5296 }
5297 }
5298 return true;
5299 }
5300
5301 // STR (Store Register) calculates an address from a base register value and an
5302 // offset register value, stores a
5303 // word from a register to memory. The offset register value can optionally
5304 // be shifted.
EmulateSTRRegister(const uint32_t opcode,const ARMEncoding encoding)5305 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
5306 const ARMEncoding encoding) {
5307 #if 0
5308 if ConditionPassed() then
5309 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5310 offset = Shift(R[m], shift_t, shift_n, APSR.C);
5311 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5312 address = if index then offset_addr else R[n];
5313 if t == 15 then // Only possible for encoding A1
5314 data = PCStoreValue();
5315 else
5316 data = R[t];
5317 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
5318 MemU[address,4] = data;
5319 else // Can only occur before ARMv7
5320 MemU[address,4] = bits(32) UNKNOWN;
5321 if wback then R[n] = offset_addr;
5322 #endif
5323
5324 bool success = false;
5325
5326 if (ConditionPassed(opcode)) {
5327 const uint32_t addr_byte_size = GetAddressByteSize();
5328
5329 uint32_t t;
5330 uint32_t n;
5331 uint32_t m;
5332 ARM_ShifterType shift_t;
5333 uint32_t shift_n;
5334 bool index;
5335 bool add;
5336 bool wback;
5337
5338 // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5339 switch (encoding) {
5340 case eEncodingT1:
5341 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5342 // in ThumbEE";
5343 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5344 t = Bits32(opcode, 2, 0);
5345 n = Bits32(opcode, 5, 3);
5346 m = Bits32(opcode, 8, 6);
5347
5348 // index = TRUE; add = TRUE; wback = FALSE;
5349 index = true;
5350 add = true;
5351 wback = false;
5352
5353 // (shift_t, shift_n) = (SRType_LSL, 0);
5354 shift_t = SRType_LSL;
5355 shift_n = 0;
5356 break;
5357
5358 case eEncodingT2:
5359 // if Rn == '1111' then UNDEFINED;
5360 if (Bits32(opcode, 19, 16) == 15)
5361 return false;
5362
5363 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5364 t = Bits32(opcode, 15, 12);
5365 n = Bits32(opcode, 19, 16);
5366 m = Bits32(opcode, 3, 0);
5367
5368 // index = TRUE; add = TRUE; wback = FALSE;
5369 index = true;
5370 add = true;
5371 wback = false;
5372
5373 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5374 shift_t = SRType_LSL;
5375 shift_n = Bits32(opcode, 5, 4);
5376
5377 // if t == 15 || BadReg(m) then UNPREDICTABLE;
5378 if ((t == 15) || (BadReg(m)))
5379 return false;
5380 break;
5381
5382 case eEncodingA1: {
5383 // if P == '0' && W == '1' then SEE STRT;
5384 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5385 t = Bits32(opcode, 15, 12);
5386 n = Bits32(opcode, 19, 16);
5387 m = Bits32(opcode, 3, 0);
5388
5389 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
5390 // (W == '1');
5391 index = BitIsSet(opcode, 24);
5392 add = BitIsSet(opcode, 23);
5393 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5394
5395 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5396 uint32_t typ = Bits32(opcode, 6, 5);
5397 uint32_t imm5 = Bits32(opcode, 11, 7);
5398 shift_n = DecodeImmShift(typ, imm5, shift_t);
5399
5400 // if m == 15 then UNPREDICTABLE;
5401 if (m == 15)
5402 return false;
5403
5404 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5405 if (wback && ((n == 15) || (n == t)))
5406 return false;
5407
5408 break;
5409 }
5410 default:
5411 return false;
5412 }
5413
5414 addr_t offset_addr;
5415 addr_t address;
5416 int32_t offset = 0;
5417
5418 addr_t base_address =
5419 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5420 if (!success)
5421 return false;
5422
5423 uint32_t Rm_data =
5424 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5425 if (!success)
5426 return false;
5427
5428 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5429 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
5430 if (!success)
5431 return false;
5432
5433 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5434 if (add)
5435 offset_addr = base_address + offset;
5436 else
5437 offset_addr = base_address - offset;
5438
5439 // address = if index then offset_addr else R[n];
5440 if (index)
5441 address = offset_addr;
5442 else
5443 address = base_address;
5444
5445 uint32_t data;
5446 // if t == 15 then // Only possible for encoding A1
5447 if (t == 15)
5448 // data = PCStoreValue();
5449 data = ReadCoreReg(PC_REG, &success);
5450 else
5451 // data = R[t];
5452 data =
5453 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5454
5455 if (!success)
5456 return false;
5457
5458 EmulateInstruction::Context context;
5459 context.type = eContextRegisterStore;
5460
5461 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
5462 // InstrSet_ARM then
5463 if (UnalignedSupport() ||
5464 (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
5465 CurrentInstrSet() == eModeARM) {
5466 // MemU[address,4] = data;
5467
5468 RegisterInfo base_reg;
5469 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5470
5471 RegisterInfo data_reg;
5472 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5473
5474 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5475 address - base_address);
5476 if (!MemUWrite(context, address, data, addr_byte_size))
5477 return false;
5478
5479 } else
5480 // MemU[address,4] = bits(32) UNKNOWN;
5481 WriteBits32UnknownToMemory(address);
5482
5483 // if wback then R[n] = offset_addr;
5484 if (wback) {
5485 context.type = eContextRegisterLoad;
5486 context.SetAddress(offset_addr);
5487 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5488 offset_addr))
5489 return false;
5490 }
5491 }
5492 return true;
5493 }
5494
EmulateSTRBThumb(const uint32_t opcode,const ARMEncoding encoding)5495 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
5496 const ARMEncoding encoding) {
5497 #if 0
5498 if ConditionPassed() then
5499 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5500 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5501 address = if index then offset_addr else R[n];
5502 MemU[address,1] = R[t]<7:0>;
5503 if wback then R[n] = offset_addr;
5504 #endif
5505
5506 bool success = false;
5507
5508 if (ConditionPassed(opcode)) {
5509 uint32_t t;
5510 uint32_t n;
5511 uint32_t imm32;
5512 bool index;
5513 bool add;
5514 bool wback;
5515 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5516 switch (encoding) {
5517 case eEncodingT1:
5518 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5519 t = Bits32(opcode, 2, 0);
5520 n = Bits32(opcode, 5, 3);
5521 imm32 = Bits32(opcode, 10, 6);
5522
5523 // index = TRUE; add = TRUE; wback = FALSE;
5524 index = true;
5525 add = true;
5526 wback = false;
5527 break;
5528
5529 case eEncodingT2:
5530 // if Rn == '1111' then UNDEFINED;
5531 if (Bits32(opcode, 19, 16) == 15)
5532 return false;
5533
5534 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5535 t = Bits32(opcode, 15, 12);
5536 n = Bits32(opcode, 19, 16);
5537 imm32 = Bits32(opcode, 11, 0);
5538
5539 // index = TRUE; add = TRUE; wback = FALSE;
5540 index = true;
5541 add = true;
5542 wback = false;
5543
5544 // if BadReg(t) then UNPREDICTABLE;
5545 if (BadReg(t))
5546 return false;
5547 break;
5548
5549 case eEncodingT3:
5550 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5551 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5552 if (Bits32(opcode, 19, 16) == 15)
5553 return false;
5554
5555 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5556 t = Bits32(opcode, 15, 12);
5557 n = Bits32(opcode, 19, 16);
5558 imm32 = Bits32(opcode, 7, 0);
5559
5560 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5561 index = BitIsSet(opcode, 10);
5562 add = BitIsSet(opcode, 9);
5563 wback = BitIsSet(opcode, 8);
5564
5565 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5566 if ((BadReg(t)) || (wback && (n == t)))
5567 return false;
5568 break;
5569
5570 default:
5571 return false;
5572 }
5573
5574 addr_t offset_addr;
5575 addr_t address;
5576 addr_t base_address =
5577 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5578 if (!success)
5579 return false;
5580
5581 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5582 if (add)
5583 offset_addr = base_address + imm32;
5584 else
5585 offset_addr = base_address - imm32;
5586
5587 // address = if index then offset_addr else R[n];
5588 if (index)
5589 address = offset_addr;
5590 else
5591 address = base_address;
5592
5593 // MemU[address,1] = R[t]<7:0>
5594 RegisterInfo base_reg;
5595 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5596
5597 RegisterInfo data_reg;
5598 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5599
5600 EmulateInstruction::Context context;
5601 context.type = eContextRegisterStore;
5602 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5603 address - base_address);
5604
5605 uint32_t data =
5606 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5607 if (!success)
5608 return false;
5609
5610 data = Bits32(data, 7, 0);
5611
5612 if (!MemUWrite(context, address, data, 1))
5613 return false;
5614
5615 // if wback then R[n] = offset_addr;
5616 if (wback) {
5617 context.type = eContextRegisterLoad;
5618 context.SetAddress(offset_addr);
5619 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5620 offset_addr))
5621 return false;
5622 }
5623 }
5624
5625 return true;
5626 }
5627
5628 // STRH (register) calculates an address from a base register value and an
5629 // offset register value, and stores a
5630 // halfword from a register to memory. The offset register value can be
5631 // shifted left by 0, 1, 2, or 3 bits.
EmulateSTRHRegister(const uint32_t opcode,const ARMEncoding encoding)5632 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
5633 const ARMEncoding encoding) {
5634 #if 0
5635 if ConditionPassed() then
5636 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5637 offset = Shift(R[m], shift_t, shift_n, APSR.C);
5638 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5639 address = if index then offset_addr else R[n];
5640 if UnalignedSupport() || address<0> == '0' then
5641 MemU[address,2] = R[t]<15:0>;
5642 else // Can only occur before ARMv7
5643 MemU[address,2] = bits(16) UNKNOWN;
5644 if wback then R[n] = offset_addr;
5645 #endif
5646
5647 bool success = false;
5648
5649 if (ConditionPassed(opcode)) {
5650 uint32_t t;
5651 uint32_t n;
5652 uint32_t m;
5653 bool index;
5654 bool add;
5655 bool wback;
5656 ARM_ShifterType shift_t;
5657 uint32_t shift_n;
5658
5659 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5660 switch (encoding) {
5661 case eEncodingT1:
5662 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5663 // in ThumbEE";
5664 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5665 t = Bits32(opcode, 2, 0);
5666 n = Bits32(opcode, 5, 3);
5667 m = Bits32(opcode, 8, 6);
5668
5669 // index = TRUE; add = TRUE; wback = FALSE;
5670 index = true;
5671 add = true;
5672 wback = false;
5673
5674 // (shift_t, shift_n) = (SRType_LSL, 0);
5675 shift_t = SRType_LSL;
5676 shift_n = 0;
5677
5678 break;
5679
5680 case eEncodingT2:
5681 // if Rn == '1111' then UNDEFINED;
5682 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5683 t = Bits32(opcode, 15, 12);
5684 n = Bits32(opcode, 19, 16);
5685 m = Bits32(opcode, 3, 0);
5686 if (n == 15)
5687 return false;
5688
5689 // index = TRUE; add = TRUE; wback = FALSE;
5690 index = true;
5691 add = true;
5692 wback = false;
5693
5694 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5695 shift_t = SRType_LSL;
5696 shift_n = Bits32(opcode, 5, 4);
5697
5698 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5699 if (BadReg(t) || BadReg(m))
5700 return false;
5701
5702 break;
5703
5704 case eEncodingA1:
5705 // if P == '0' && W == '1' then SEE STRHT;
5706 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5707 t = Bits32(opcode, 15, 12);
5708 n = Bits32(opcode, 19, 16);
5709 m = Bits32(opcode, 3, 0);
5710
5711 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
5712 // (W == '1');
5713 index = BitIsSet(opcode, 24);
5714 add = BitIsSet(opcode, 23);
5715 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5716
5717 // (shift_t, shift_n) = (SRType_LSL, 0);
5718 shift_t = SRType_LSL;
5719 shift_n = 0;
5720
5721 // if t == 15 || m == 15 then UNPREDICTABLE;
5722 if ((t == 15) || (m == 15))
5723 return false;
5724
5725 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5726 if (wback && ((n == 15) || (n == t)))
5727 return false;
5728
5729 break;
5730
5731 default:
5732 return false;
5733 }
5734
5735 uint32_t Rm = ReadCoreReg(m, &success);
5736 if (!success)
5737 return false;
5738
5739 uint32_t Rn = ReadCoreReg(n, &success);
5740 if (!success)
5741 return false;
5742
5743 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5744 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
5745 if (!success)
5746 return false;
5747
5748 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5749 addr_t offset_addr;
5750 if (add)
5751 offset_addr = Rn + offset;
5752 else
5753 offset_addr = Rn - offset;
5754
5755 // address = if index then offset_addr else R[n];
5756 addr_t address;
5757 if (index)
5758 address = offset_addr;
5759 else
5760 address = Rn;
5761
5762 EmulateInstruction::Context context;
5763 context.type = eContextRegisterStore;
5764 RegisterInfo base_reg;
5765 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5766 RegisterInfo offset_reg;
5767 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5768
5769 // if UnalignedSupport() || address<0> == '0' then
5770 if (UnalignedSupport() || BitIsClear(address, 0)) {
5771 // MemU[address,2] = R[t]<15:0>;
5772 uint32_t Rt = ReadCoreReg(t, &success);
5773 if (!success)
5774 return false;
5775
5776 EmulateInstruction::Context context;
5777 context.type = eContextRegisterStore;
5778 RegisterInfo base_reg;
5779 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5780 RegisterInfo offset_reg;
5781 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5782 RegisterInfo data_reg;
5783 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5784 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
5785 data_reg);
5786
5787 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
5788 return false;
5789 } else // Can only occur before ARMv7
5790 {
5791 // MemU[address,2] = bits(16) UNKNOWN;
5792 }
5793
5794 // if wback then R[n] = offset_addr;
5795 if (wback) {
5796 context.type = eContextAdjustBaseRegister;
5797 context.SetAddress(offset_addr);
5798 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5799 offset_addr))
5800 return false;
5801 }
5802 }
5803
5804 return true;
5805 }
5806
5807 // Add with Carry (immediate) adds an immediate value and the carry flag value
5808 // to a register value, and writes the result to the destination register. It
5809 // can optionally update the condition flags based on the result.
EmulateADCImm(const uint32_t opcode,const ARMEncoding encoding)5810 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
5811 const ARMEncoding encoding) {
5812 #if 0
5813 // ARM pseudo code...
5814 if ConditionPassed() then
5815 EncodingSpecificOperations();
5816 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5817 if d == 15 then // Can only occur for ARM encoding
5818 ALUWritePC(result); // setflags is always FALSE here
5819 else
5820 R[d] = result;
5821 if setflags then
5822 APSR.N = result<31>;
5823 APSR.Z = IsZeroBit(result);
5824 APSR.C = carry;
5825 APSR.V = overflow;
5826 #endif
5827
5828 bool success = false;
5829
5830 if (ConditionPassed(opcode)) {
5831 uint32_t Rd, Rn;
5832 uint32_t
5833 imm32; // the immediate value to be added to the value obtained from Rn
5834 bool setflags;
5835 switch (encoding) {
5836 case eEncodingT1:
5837 Rd = Bits32(opcode, 11, 8);
5838 Rn = Bits32(opcode, 19, 16);
5839 setflags = BitIsSet(opcode, 20);
5840 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5841 if (BadReg(Rd) || BadReg(Rn))
5842 return false;
5843 break;
5844 case eEncodingA1:
5845 Rd = Bits32(opcode, 15, 12);
5846 Rn = Bits32(opcode, 19, 16);
5847 setflags = BitIsSet(opcode, 20);
5848 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5849
5850 if (Rd == 15 && setflags)
5851 return EmulateSUBSPcLrEtc(opcode, encoding);
5852 break;
5853 default:
5854 return false;
5855 }
5856
5857 // Read the first operand.
5858 int32_t val1 = ReadCoreReg(Rn, &success);
5859 if (!success)
5860 return false;
5861
5862 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5863
5864 EmulateInstruction::Context context;
5865 context.type = EmulateInstruction::eContextImmediate;
5866 context.SetNoArgs();
5867
5868 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5869 res.carry_out, res.overflow))
5870 return false;
5871 }
5872 return true;
5873 }
5874
5875 // Add with Carry (register) adds a register value, the carry flag value, and
5876 // an optionally-shifted register value, and writes the result to the
5877 // destination register. It can optionally update the condition flags based on
5878 // the result.
EmulateADCReg(const uint32_t opcode,const ARMEncoding encoding)5879 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
5880 const ARMEncoding encoding) {
5881 #if 0
5882 // ARM pseudo code...
5883 if ConditionPassed() then
5884 EncodingSpecificOperations();
5885 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5886 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5887 if d == 15 then // Can only occur for ARM encoding
5888 ALUWritePC(result); // setflags is always FALSE here
5889 else
5890 R[d] = result;
5891 if setflags then
5892 APSR.N = result<31>;
5893 APSR.Z = IsZeroBit(result);
5894 APSR.C = carry;
5895 APSR.V = overflow;
5896 #endif
5897
5898 bool success = false;
5899
5900 if (ConditionPassed(opcode)) {
5901 uint32_t Rd, Rn, Rm;
5902 ARM_ShifterType shift_t;
5903 uint32_t shift_n; // the shift applied to the value read from Rm
5904 bool setflags;
5905 switch (encoding) {
5906 case eEncodingT1:
5907 Rd = Rn = Bits32(opcode, 2, 0);
5908 Rm = Bits32(opcode, 5, 3);
5909 setflags = !InITBlock();
5910 shift_t = SRType_LSL;
5911 shift_n = 0;
5912 break;
5913 case eEncodingT2:
5914 Rd = Bits32(opcode, 11, 8);
5915 Rn = Bits32(opcode, 19, 16);
5916 Rm = Bits32(opcode, 3, 0);
5917 setflags = BitIsSet(opcode, 20);
5918 shift_n = DecodeImmShiftThumb(opcode, shift_t);
5919 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5920 return false;
5921 break;
5922 case eEncodingA1:
5923 Rd = Bits32(opcode, 15, 12);
5924 Rn = Bits32(opcode, 19, 16);
5925 Rm = Bits32(opcode, 3, 0);
5926 setflags = BitIsSet(opcode, 20);
5927 shift_n = DecodeImmShiftARM(opcode, shift_t);
5928
5929 if (Rd == 15 && setflags)
5930 return EmulateSUBSPcLrEtc(opcode, encoding);
5931 break;
5932 default:
5933 return false;
5934 }
5935
5936 // Read the first operand.
5937 int32_t val1 = ReadCoreReg(Rn, &success);
5938 if (!success)
5939 return false;
5940
5941 // Read the second operand.
5942 int32_t val2 = ReadCoreReg(Rm, &success);
5943 if (!success)
5944 return false;
5945
5946 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5947 if (!success)
5948 return false;
5949 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5950
5951 EmulateInstruction::Context context;
5952 context.type = EmulateInstruction::eContextImmediate;
5953 context.SetNoArgs();
5954
5955 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5956 res.carry_out, res.overflow))
5957 return false;
5958 }
5959 return true;
5960 }
5961
5962 // This instruction adds an immediate value to the PC value to form a PC-
5963 // relative address, and writes the result to the destination register.
EmulateADR(const uint32_t opcode,const ARMEncoding encoding)5964 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
5965 const ARMEncoding encoding) {
5966 #if 0
5967 // ARM pseudo code...
5968 if ConditionPassed() then
5969 EncodingSpecificOperations();
5970 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5971 if d == 15 then // Can only occur for ARM encodings
5972 ALUWritePC(result);
5973 else
5974 R[d] = result;
5975 #endif
5976
5977 bool success = false;
5978
5979 if (ConditionPassed(opcode)) {
5980 uint32_t Rd;
5981 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5982 bool add;
5983 switch (encoding) {
5984 case eEncodingT1:
5985 Rd = Bits32(opcode, 10, 8);
5986 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5987 add = true;
5988 break;
5989 case eEncodingT2:
5990 case eEncodingT3:
5991 Rd = Bits32(opcode, 11, 8);
5992 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5993 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5994 if (BadReg(Rd))
5995 return false;
5996 break;
5997 case eEncodingA1:
5998 case eEncodingA2:
5999 Rd = Bits32(opcode, 15, 12);
6000 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
6001 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
6002 break;
6003 default:
6004 return false;
6005 }
6006
6007 // Read the PC value.
6008 uint32_t pc = ReadCoreReg(PC_REG, &success);
6009 if (!success)
6010 return false;
6011
6012 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
6013
6014 EmulateInstruction::Context context;
6015 context.type = EmulateInstruction::eContextImmediate;
6016 context.SetNoArgs();
6017
6018 if (!WriteCoreReg(context, result, Rd))
6019 return false;
6020 }
6021 return true;
6022 }
6023
6024 // This instruction performs a bitwise AND of a register value and an immediate
6025 // value, and writes the result to the destination register. It can optionally
6026 // update the condition flags based on the result.
EmulateANDImm(const uint32_t opcode,const ARMEncoding encoding)6027 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
6028 const ARMEncoding encoding) {
6029 #if 0
6030 // ARM pseudo code...
6031 if ConditionPassed() then
6032 EncodingSpecificOperations();
6033 result = R[n] AND imm32;
6034 if d == 15 then // Can only occur for ARM encoding
6035 ALUWritePC(result); // setflags is always FALSE here
6036 else
6037 R[d] = result;
6038 if setflags then
6039 APSR.N = result<31>;
6040 APSR.Z = IsZeroBit(result);
6041 APSR.C = carry;
6042 // APSR.V unchanged
6043 #endif
6044
6045 bool success = false;
6046
6047 if (ConditionPassed(opcode)) {
6048 uint32_t Rd, Rn;
6049 uint32_t
6050 imm32; // the immediate value to be ANDed to the value obtained from Rn
6051 bool setflags;
6052 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6053 switch (encoding) {
6054 case eEncodingT1:
6055 Rd = Bits32(opcode, 11, 8);
6056 Rn = Bits32(opcode, 19, 16);
6057 setflags = BitIsSet(opcode, 20);
6058 imm32 = ThumbExpandImm_C(
6059 opcode, APSR_C,
6060 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6061 // if Rd == '1111' && S == '1' then SEE TST (immediate);
6062 if (Rd == 15 && setflags)
6063 return EmulateTSTImm(opcode, eEncodingT1);
6064 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
6065 return false;
6066 break;
6067 case eEncodingA1:
6068 Rd = Bits32(opcode, 15, 12);
6069 Rn = Bits32(opcode, 19, 16);
6070 setflags = BitIsSet(opcode, 20);
6071 imm32 =
6072 ARMExpandImm_C(opcode, APSR_C,
6073 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6074
6075 if (Rd == 15 && setflags)
6076 return EmulateSUBSPcLrEtc(opcode, encoding);
6077 break;
6078 default:
6079 return false;
6080 }
6081
6082 // Read the first operand.
6083 uint32_t val1 = ReadCoreReg(Rn, &success);
6084 if (!success)
6085 return false;
6086
6087 uint32_t result = val1 & imm32;
6088
6089 EmulateInstruction::Context context;
6090 context.type = EmulateInstruction::eContextImmediate;
6091 context.SetNoArgs();
6092
6093 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6094 return false;
6095 }
6096 return true;
6097 }
6098
6099 // This instruction performs a bitwise AND of a register value and an
6100 // optionally-shifted register value, and writes the result to the destination
6101 // register. It can optionally update the condition flags based on the result.
EmulateANDReg(const uint32_t opcode,const ARMEncoding encoding)6102 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
6103 const ARMEncoding encoding) {
6104 #if 0
6105 // ARM pseudo code...
6106 if ConditionPassed() then
6107 EncodingSpecificOperations();
6108 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6109 result = R[n] AND shifted;
6110 if d == 15 then // Can only occur for ARM encoding
6111 ALUWritePC(result); // setflags is always FALSE here
6112 else
6113 R[d] = result;
6114 if setflags then
6115 APSR.N = result<31>;
6116 APSR.Z = IsZeroBit(result);
6117 APSR.C = carry;
6118 // APSR.V unchanged
6119 #endif
6120
6121 bool success = false;
6122
6123 if (ConditionPassed(opcode)) {
6124 uint32_t Rd, Rn, Rm;
6125 ARM_ShifterType shift_t;
6126 uint32_t shift_n; // the shift applied to the value read from Rm
6127 bool setflags;
6128 uint32_t carry;
6129 switch (encoding) {
6130 case eEncodingT1:
6131 Rd = Rn = Bits32(opcode, 2, 0);
6132 Rm = Bits32(opcode, 5, 3);
6133 setflags = !InITBlock();
6134 shift_t = SRType_LSL;
6135 shift_n = 0;
6136 break;
6137 case eEncodingT2:
6138 Rd = Bits32(opcode, 11, 8);
6139 Rn = Bits32(opcode, 19, 16);
6140 Rm = Bits32(opcode, 3, 0);
6141 setflags = BitIsSet(opcode, 20);
6142 shift_n = DecodeImmShiftThumb(opcode, shift_t);
6143 // if Rd == '1111' && S == '1' then SEE TST (register);
6144 if (Rd == 15 && setflags)
6145 return EmulateTSTReg(opcode, eEncodingT2);
6146 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
6147 return false;
6148 break;
6149 case eEncodingA1:
6150 Rd = Bits32(opcode, 15, 12);
6151 Rn = Bits32(opcode, 19, 16);
6152 Rm = Bits32(opcode, 3, 0);
6153 setflags = BitIsSet(opcode, 20);
6154 shift_n = DecodeImmShiftARM(opcode, shift_t);
6155
6156 if (Rd == 15 && setflags)
6157 return EmulateSUBSPcLrEtc(opcode, encoding);
6158 break;
6159 default:
6160 return false;
6161 }
6162
6163 // Read the first operand.
6164 uint32_t val1 = ReadCoreReg(Rn, &success);
6165 if (!success)
6166 return false;
6167
6168 // Read the second operand.
6169 uint32_t val2 = ReadCoreReg(Rm, &success);
6170 if (!success)
6171 return false;
6172
6173 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6174 if (!success)
6175 return false;
6176 uint32_t result = val1 & shifted;
6177
6178 EmulateInstruction::Context context;
6179 context.type = EmulateInstruction::eContextImmediate;
6180 context.SetNoArgs();
6181
6182 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6183 return false;
6184 }
6185 return true;
6186 }
6187
6188 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
6189 // the complement of an immediate value, and writes the result to the
6190 // destination register. It can optionally update the condition flags based on
6191 // the result.
EmulateBICImm(const uint32_t opcode,const ARMEncoding encoding)6192 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
6193 const ARMEncoding encoding) {
6194 #if 0
6195 // ARM pseudo code...
6196 if ConditionPassed() then
6197 EncodingSpecificOperations();
6198 result = R[n] AND NOT(imm32);
6199 if d == 15 then // Can only occur for ARM encoding
6200 ALUWritePC(result); // setflags is always FALSE here
6201 else
6202 R[d] = result;
6203 if setflags then
6204 APSR.N = result<31>;
6205 APSR.Z = IsZeroBit(result);
6206 APSR.C = carry;
6207 // APSR.V unchanged
6208 #endif
6209
6210 bool success = false;
6211
6212 if (ConditionPassed(opcode)) {
6213 uint32_t Rd, Rn;
6214 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
6215 // the value obtained from Rn
6216 bool setflags;
6217 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6218 switch (encoding) {
6219 case eEncodingT1:
6220 Rd = Bits32(opcode, 11, 8);
6221 Rn = Bits32(opcode, 19, 16);
6222 setflags = BitIsSet(opcode, 20);
6223 imm32 = ThumbExpandImm_C(
6224 opcode, APSR_C,
6225 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6226 if (BadReg(Rd) || BadReg(Rn))
6227 return false;
6228 break;
6229 case eEncodingA1:
6230 Rd = Bits32(opcode, 15, 12);
6231 Rn = Bits32(opcode, 19, 16);
6232 setflags = BitIsSet(opcode, 20);
6233 imm32 =
6234 ARMExpandImm_C(opcode, APSR_C,
6235 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6236
6237 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6238 // instructions;
6239 if (Rd == 15 && setflags)
6240 return EmulateSUBSPcLrEtc(opcode, encoding);
6241 break;
6242 default:
6243 return false;
6244 }
6245
6246 // Read the first operand.
6247 uint32_t val1 = ReadCoreReg(Rn, &success);
6248 if (!success)
6249 return false;
6250
6251 uint32_t result = val1 & ~imm32;
6252
6253 EmulateInstruction::Context context;
6254 context.type = EmulateInstruction::eContextImmediate;
6255 context.SetNoArgs();
6256
6257 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6258 return false;
6259 }
6260 return true;
6261 }
6262
6263 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and
6264 // the complement of an optionally-shifted register value, and writes the
6265 // result to the destination register. It can optionally update the condition
6266 // flags based on the result.
EmulateBICReg(const uint32_t opcode,const ARMEncoding encoding)6267 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
6268 const ARMEncoding encoding) {
6269 #if 0
6270 // ARM pseudo code...
6271 if ConditionPassed() then
6272 EncodingSpecificOperations();
6273 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6274 result = R[n] AND NOT(shifted);
6275 if d == 15 then // Can only occur for ARM encoding
6276 ALUWritePC(result); // setflags is always FALSE here
6277 else
6278 R[d] = result;
6279 if setflags then
6280 APSR.N = result<31>;
6281 APSR.Z = IsZeroBit(result);
6282 APSR.C = carry;
6283 // APSR.V unchanged
6284 #endif
6285
6286 bool success = false;
6287
6288 if (ConditionPassed(opcode)) {
6289 uint32_t Rd, Rn, Rm;
6290 ARM_ShifterType shift_t;
6291 uint32_t shift_n; // the shift applied to the value read from Rm
6292 bool setflags;
6293 uint32_t carry;
6294 switch (encoding) {
6295 case eEncodingT1:
6296 Rd = Rn = Bits32(opcode, 2, 0);
6297 Rm = Bits32(opcode, 5, 3);
6298 setflags = !InITBlock();
6299 shift_t = SRType_LSL;
6300 shift_n = 0;
6301 break;
6302 case eEncodingT2:
6303 Rd = Bits32(opcode, 11, 8);
6304 Rn = Bits32(opcode, 19, 16);
6305 Rm = Bits32(opcode, 3, 0);
6306 setflags = BitIsSet(opcode, 20);
6307 shift_n = DecodeImmShiftThumb(opcode, shift_t);
6308 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
6309 return false;
6310 break;
6311 case eEncodingA1:
6312 Rd = Bits32(opcode, 15, 12);
6313 Rn = Bits32(opcode, 19, 16);
6314 Rm = Bits32(opcode, 3, 0);
6315 setflags = BitIsSet(opcode, 20);
6316 shift_n = DecodeImmShiftARM(opcode, shift_t);
6317
6318 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6319 // instructions;
6320 if (Rd == 15 && setflags)
6321 return EmulateSUBSPcLrEtc(opcode, encoding);
6322 break;
6323 default:
6324 return false;
6325 }
6326
6327 // Read the first operand.
6328 uint32_t val1 = ReadCoreReg(Rn, &success);
6329 if (!success)
6330 return false;
6331
6332 // Read the second operand.
6333 uint32_t val2 = ReadCoreReg(Rm, &success);
6334 if (!success)
6335 return false;
6336
6337 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6338 if (!success)
6339 return false;
6340 uint32_t result = val1 & ~shifted;
6341
6342 EmulateInstruction::Context context;
6343 context.type = EmulateInstruction::eContextImmediate;
6344 context.SetNoArgs();
6345
6346 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6347 return false;
6348 }
6349 return true;
6350 }
6351
6352 // LDR (immediate, ARM) calculates an address from a base register value and an
6353 // immediate offset, loads a word
6354 // from memory, and writes it to a register. It can use offset, post-indexed,
6355 // or pre-indexed addressing.
EmulateLDRImmediateARM(const uint32_t opcode,const ARMEncoding encoding)6356 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
6357 const ARMEncoding encoding) {
6358 #if 0
6359 if ConditionPassed() then
6360 EncodingSpecificOperations();
6361 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6362 address = if index then offset_addr else R[n];
6363 data = MemU[address,4];
6364 if wback then R[n] = offset_addr;
6365 if t == 15 then
6366 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6367 elsif UnalignedSupport() || address<1:0> = '00' then
6368 R[t] = data;
6369 else // Can only apply before ARMv7
6370 R[t] = ROR(data, 8*UInt(address<1:0>));
6371 #endif
6372
6373 bool success = false;
6374
6375 if (ConditionPassed(opcode)) {
6376 const uint32_t addr_byte_size = GetAddressByteSize();
6377
6378 uint32_t t;
6379 uint32_t n;
6380 uint32_t imm32;
6381 bool index;
6382 bool add;
6383 bool wback;
6384
6385 switch (encoding) {
6386 case eEncodingA1:
6387 // if Rn == '1111' then SEE LDR (literal);
6388 // if P == '0' && W == '1' then SEE LDRT;
6389 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
6390 // '000000000100' then SEE POP;
6391 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6392 t = Bits32(opcode, 15, 12);
6393 n = Bits32(opcode, 19, 16);
6394 imm32 = Bits32(opcode, 11, 0);
6395
6396 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
6397 // (W == '1');
6398 index = BitIsSet(opcode, 24);
6399 add = BitIsSet(opcode, 23);
6400 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6401
6402 // if wback && n == t then UNPREDICTABLE;
6403 if (wback && (n == t))
6404 return false;
6405
6406 break;
6407
6408 default:
6409 return false;
6410 }
6411
6412 addr_t address;
6413 addr_t offset_addr;
6414 addr_t base_address = ReadCoreReg(n, &success);
6415 if (!success)
6416 return false;
6417
6418 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6419 if (add)
6420 offset_addr = base_address + imm32;
6421 else
6422 offset_addr = base_address - imm32;
6423
6424 // address = if index then offset_addr else R[n];
6425 if (index)
6426 address = offset_addr;
6427 else
6428 address = base_address;
6429
6430 // data = MemU[address,4];
6431
6432 RegisterInfo base_reg;
6433 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6434
6435 EmulateInstruction::Context context;
6436 context.type = eContextRegisterLoad;
6437 context.SetRegisterPlusOffset(base_reg, address - base_address);
6438
6439 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6440 if (!success)
6441 return false;
6442
6443 // if wback then R[n] = offset_addr;
6444 if (wback) {
6445 context.type = eContextAdjustBaseRegister;
6446 context.SetAddress(offset_addr);
6447 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6448 offset_addr))
6449 return false;
6450 }
6451
6452 // if t == 15 then
6453 if (t == 15) {
6454 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6455 if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6456 // LoadWritePC (data);
6457 context.type = eContextRegisterLoad;
6458 context.SetRegisterPlusOffset(base_reg, address - base_address);
6459 LoadWritePC(context, data);
6460 } else
6461 return false;
6462 }
6463 // elsif UnalignedSupport() || address<1:0> = '00' then
6464 else if (UnalignedSupport() ||
6465 (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6466 // R[t] = data;
6467 context.type = eContextRegisterLoad;
6468 context.SetRegisterPlusOffset(base_reg, address - base_address);
6469 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6470 data))
6471 return false;
6472 }
6473 // else // Can only apply before ARMv7
6474 else {
6475 // R[t] = ROR(data, 8*UInt(address<1:0>));
6476 data = ROR(data, Bits32(address, 1, 0), &success);
6477 if (!success)
6478 return false;
6479 context.type = eContextRegisterLoad;
6480 context.SetImmediate(data);
6481 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6482 data))
6483 return false;
6484 }
6485 }
6486 return true;
6487 }
6488
6489 // LDR (register) calculates an address from a base register value and an offset
6490 // register value, loads a word
6491 // from memory, and writes it to a register. The offset register value can
6492 // optionally be shifted.
EmulateLDRRegister(const uint32_t opcode,const ARMEncoding encoding)6493 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
6494 const ARMEncoding encoding) {
6495 #if 0
6496 if ConditionPassed() then
6497 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6498 offset = Shift(R[m], shift_t, shift_n, APSR.C);
6499 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6500 address = if index then offset_addr else R[n];
6501 data = MemU[address,4];
6502 if wback then R[n] = offset_addr;
6503 if t == 15 then
6504 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6505 elsif UnalignedSupport() || address<1:0> = '00' then
6506 R[t] = data;
6507 else // Can only apply before ARMv7
6508 if CurrentInstrSet() == InstrSet_ARM then
6509 R[t] = ROR(data, 8*UInt(address<1:0>));
6510 else
6511 R[t] = bits(32) UNKNOWN;
6512 #endif
6513
6514 bool success = false;
6515
6516 if (ConditionPassed(opcode)) {
6517 const uint32_t addr_byte_size = GetAddressByteSize();
6518
6519 uint32_t t;
6520 uint32_t n;
6521 uint32_t m;
6522 bool index;
6523 bool add;
6524 bool wback;
6525 ARM_ShifterType shift_t;
6526 uint32_t shift_n;
6527
6528 switch (encoding) {
6529 case eEncodingT1:
6530 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6531 // in ThumbEE";
6532 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6533 t = Bits32(opcode, 2, 0);
6534 n = Bits32(opcode, 5, 3);
6535 m = Bits32(opcode, 8, 6);
6536
6537 // index = TRUE; add = TRUE; wback = FALSE;
6538 index = true;
6539 add = true;
6540 wback = false;
6541
6542 // (shift_t, shift_n) = (SRType_LSL, 0);
6543 shift_t = SRType_LSL;
6544 shift_n = 0;
6545
6546 break;
6547
6548 case eEncodingT2:
6549 // if Rn == '1111' then SEE LDR (literal);
6550 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6551 t = Bits32(opcode, 15, 12);
6552 n = Bits32(opcode, 19, 16);
6553 m = Bits32(opcode, 3, 0);
6554
6555 // index = TRUE; add = TRUE; wback = FALSE;
6556 index = true;
6557 add = true;
6558 wback = false;
6559
6560 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6561 shift_t = SRType_LSL;
6562 shift_n = Bits32(opcode, 5, 4);
6563
6564 // if BadReg(m) then UNPREDICTABLE;
6565 if (BadReg(m))
6566 return false;
6567
6568 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6569 if ((t == 15) && InITBlock() && !LastInITBlock())
6570 return false;
6571
6572 break;
6573
6574 case eEncodingA1: {
6575 // if P == '0' && W == '1' then SEE LDRT;
6576 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6577 t = Bits32(opcode, 15, 12);
6578 n = Bits32(opcode, 19, 16);
6579 m = Bits32(opcode, 3, 0);
6580
6581 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
6582 // (W == '1');
6583 index = BitIsSet(opcode, 24);
6584 add = BitIsSet(opcode, 23);
6585 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6586
6587 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6588 uint32_t type = Bits32(opcode, 6, 5);
6589 uint32_t imm5 = Bits32(opcode, 11, 7);
6590 shift_n = DecodeImmShift(type, imm5, shift_t);
6591
6592 // if m == 15 then UNPREDICTABLE;
6593 if (m == 15)
6594 return false;
6595
6596 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6597 if (wback && ((n == 15) || (n == t)))
6598 return false;
6599 } break;
6600
6601 default:
6602 return false;
6603 }
6604
6605 uint32_t Rm =
6606 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6607 if (!success)
6608 return false;
6609
6610 uint32_t Rn =
6611 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6612 if (!success)
6613 return false;
6614
6615 addr_t offset_addr;
6616 addr_t address;
6617
6618 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is
6619 // an application level alias for the CPSR".
6620 addr_t offset =
6621 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
6622 if (!success)
6623 return false;
6624
6625 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6626 if (add)
6627 offset_addr = Rn + offset;
6628 else
6629 offset_addr = Rn - offset;
6630
6631 // address = if index then offset_addr else R[n];
6632 if (index)
6633 address = offset_addr;
6634 else
6635 address = Rn;
6636
6637 // data = MemU[address,4];
6638 RegisterInfo base_reg;
6639 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6640
6641 EmulateInstruction::Context context;
6642 context.type = eContextRegisterLoad;
6643 context.SetRegisterPlusOffset(base_reg, address - Rn);
6644
6645 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6646 if (!success)
6647 return false;
6648
6649 // if wback then R[n] = offset_addr;
6650 if (wback) {
6651 context.type = eContextAdjustBaseRegister;
6652 context.SetAddress(offset_addr);
6653 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6654 offset_addr))
6655 return false;
6656 }
6657
6658 // if t == 15 then
6659 if (t == 15) {
6660 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6661 if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6662 context.type = eContextRegisterLoad;
6663 context.SetRegisterPlusOffset(base_reg, address - Rn);
6664 LoadWritePC(context, data);
6665 } else
6666 return false;
6667 }
6668 // elsif UnalignedSupport() || address<1:0> = '00' then
6669 else if (UnalignedSupport() ||
6670 (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6671 // R[t] = data;
6672 context.type = eContextRegisterLoad;
6673 context.SetRegisterPlusOffset(base_reg, address - Rn);
6674 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6675 data))
6676 return false;
6677 } else // Can only apply before ARMv7
6678 {
6679 // if CurrentInstrSet() == InstrSet_ARM then
6680 if (CurrentInstrSet() == eModeARM) {
6681 // R[t] = ROR(data, 8*UInt(address<1:0>));
6682 data = ROR(data, Bits32(address, 1, 0), &success);
6683 if (!success)
6684 return false;
6685 context.type = eContextRegisterLoad;
6686 context.SetImmediate(data);
6687 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6688 data))
6689 return false;
6690 } else {
6691 // R[t] = bits(32) UNKNOWN;
6692 WriteBits32Unknown(t);
6693 }
6694 }
6695 }
6696 return true;
6697 }
6698
6699 // LDRB (immediate, Thumb)
EmulateLDRBImmediate(const uint32_t opcode,const ARMEncoding encoding)6700 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
6701 const ARMEncoding encoding) {
6702 #if 0
6703 if ConditionPassed() then
6704 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6705 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6706 address = if index then offset_addr else R[n];
6707 R[t] = ZeroExtend(MemU[address,1], 32);
6708 if wback then R[n] = offset_addr;
6709 #endif
6710
6711 bool success = false;
6712
6713 if (ConditionPassed(opcode)) {
6714 uint32_t t;
6715 uint32_t n;
6716 uint32_t imm32;
6717 bool index;
6718 bool add;
6719 bool wback;
6720
6721 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6722 switch (encoding) {
6723 case eEncodingT1:
6724 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6725 t = Bits32(opcode, 2, 0);
6726 n = Bits32(opcode, 5, 3);
6727 imm32 = Bits32(opcode, 10, 6);
6728
6729 // index = TRUE; add = TRUE; wback = FALSE;
6730 index = true;
6731 add = true;
6732 wback = false;
6733
6734 break;
6735
6736 case eEncodingT2:
6737 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6738 t = Bits32(opcode, 15, 12);
6739 n = Bits32(opcode, 19, 16);
6740 imm32 = Bits32(opcode, 11, 0);
6741
6742 // index = TRUE; add = TRUE; wback = FALSE;
6743 index = true;
6744 add = true;
6745 wback = false;
6746
6747 // if Rt == '1111' then SEE PLD;
6748 if (t == 15)
6749 return false; // PLD is not implemented yet
6750
6751 // if Rn == '1111' then SEE LDRB (literal);
6752 if (n == 15)
6753 return EmulateLDRBLiteral(opcode, eEncodingT1);
6754
6755 // if t == 13 then UNPREDICTABLE;
6756 if (t == 13)
6757 return false;
6758
6759 break;
6760
6761 case eEncodingT3:
6762 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6763 // if P == '0' && W == '0' then UNDEFINED;
6764 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6765 return false;
6766
6767 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6768 t = Bits32(opcode, 15, 12);
6769 n = Bits32(opcode, 19, 16);
6770 imm32 = Bits32(opcode, 7, 0);
6771
6772 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6773 index = BitIsSet(opcode, 10);
6774 add = BitIsSet(opcode, 9);
6775 wback = BitIsSet(opcode, 8);
6776
6777 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6778 if (t == 15)
6779 return false; // PLD is not implemented yet
6780
6781 // if Rn == '1111' then SEE LDRB (literal);
6782 if (n == 15)
6783 return EmulateLDRBLiteral(opcode, eEncodingT1);
6784
6785 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6786 if (BadReg(t) || (wback && (n == t)))
6787 return false;
6788
6789 break;
6790
6791 default:
6792 return false;
6793 }
6794
6795 uint32_t Rn =
6796 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6797 if (!success)
6798 return false;
6799
6800 addr_t address;
6801 addr_t offset_addr;
6802
6803 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6804 if (add)
6805 offset_addr = Rn + imm32;
6806 else
6807 offset_addr = Rn - imm32;
6808
6809 // address = if index then offset_addr else R[n];
6810 if (index)
6811 address = offset_addr;
6812 else
6813 address = Rn;
6814
6815 // R[t] = ZeroExtend(MemU[address,1], 32);
6816 RegisterInfo base_reg;
6817 RegisterInfo data_reg;
6818 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6819 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6820
6821 EmulateInstruction::Context context;
6822 context.type = eContextRegisterLoad;
6823 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
6824
6825 uint64_t data = MemURead(context, address, 1, 0, &success);
6826 if (!success)
6827 return false;
6828
6829 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6830 return false;
6831
6832 // if wback then R[n] = offset_addr;
6833 if (wback) {
6834 context.type = eContextAdjustBaseRegister;
6835 context.SetAddress(offset_addr);
6836 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6837 offset_addr))
6838 return false;
6839 }
6840 }
6841 return true;
6842 }
6843
6844 // LDRB (literal) calculates an address from the PC value and an immediate
6845 // offset, loads a byte from memory,
6846 // zero-extends it to form a 32-bit word and writes it to a register.
EmulateLDRBLiteral(const uint32_t opcode,const ARMEncoding encoding)6847 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
6848 const ARMEncoding encoding) {
6849 #if 0
6850 if ConditionPassed() then
6851 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6852 base = Align(PC,4);
6853 address = if add then (base + imm32) else (base - imm32);
6854 R[t] = ZeroExtend(MemU[address,1], 32);
6855 #endif
6856
6857 bool success = false;
6858
6859 if (ConditionPassed(opcode)) {
6860 uint32_t t;
6861 uint32_t imm32;
6862 bool add;
6863 switch (encoding) {
6864 case eEncodingT1:
6865 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6866 t = Bits32(opcode, 15, 12);
6867 imm32 = Bits32(opcode, 11, 0);
6868 add = BitIsSet(opcode, 23);
6869
6870 // if Rt == '1111' then SEE PLD;
6871 if (t == 15)
6872 return false; // PLD is not implemented yet
6873
6874 // if t == 13 then UNPREDICTABLE;
6875 if (t == 13)
6876 return false;
6877
6878 break;
6879
6880 case eEncodingA1:
6881 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6882 t = Bits32(opcode, 15, 12);
6883 imm32 = Bits32(opcode, 11, 0);
6884 add = BitIsSet(opcode, 23);
6885
6886 // if t == 15 then UNPREDICTABLE;
6887 if (t == 15)
6888 return false;
6889 break;
6890
6891 default:
6892 return false;
6893 }
6894
6895 // base = Align(PC,4);
6896 uint32_t pc_val = ReadCoreReg(PC_REG, &success);
6897 if (!success)
6898 return false;
6899
6900 uint32_t base = AlignPC(pc_val);
6901
6902 addr_t address;
6903 // address = if add then (base + imm32) else (base - imm32);
6904 if (add)
6905 address = base + imm32;
6906 else
6907 address = base - imm32;
6908
6909 // R[t] = ZeroExtend(MemU[address,1], 32);
6910 EmulateInstruction::Context context;
6911 context.type = eContextRelativeBranchImmediate;
6912 context.SetImmediate(address - base);
6913
6914 uint64_t data = MemURead(context, address, 1, 0, &success);
6915 if (!success)
6916 return false;
6917
6918 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6919 return false;
6920 }
6921 return true;
6922 }
6923
6924 // LDRB (register) calculates an address from a base register value and an
6925 // offset rigister value, loads a byte from memory, zero-extends it to form a
6926 // 32-bit word, and writes it to a register. The offset register value can
6927 // optionally be shifted.
EmulateLDRBRegister(const uint32_t opcode,const ARMEncoding encoding)6928 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
6929 const ARMEncoding encoding) {
6930 #if 0
6931 if ConditionPassed() then
6932 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6933 offset = Shift(R[m], shift_t, shift_n, APSR.C);
6934 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6935 address = if index then offset_addr else R[n];
6936 R[t] = ZeroExtend(MemU[address,1],32);
6937 if wback then R[n] = offset_addr;
6938 #endif
6939
6940 bool success = false;
6941
6942 if (ConditionPassed(opcode)) {
6943 uint32_t t;
6944 uint32_t n;
6945 uint32_t m;
6946 bool index;
6947 bool add;
6948 bool wback;
6949 ARM_ShifterType shift_t;
6950 uint32_t shift_n;
6951
6952 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6953 switch (encoding) {
6954 case eEncodingT1:
6955 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6956 t = Bits32(opcode, 2, 0);
6957 n = Bits32(opcode, 5, 3);
6958 m = Bits32(opcode, 8, 6);
6959
6960 // index = TRUE; add = TRUE; wback = FALSE;
6961 index = true;
6962 add = true;
6963 wback = false;
6964
6965 // (shift_t, shift_n) = (SRType_LSL, 0);
6966 shift_t = SRType_LSL;
6967 shift_n = 0;
6968 break;
6969
6970 case eEncodingT2:
6971 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6972 t = Bits32(opcode, 15, 12);
6973 n = Bits32(opcode, 19, 16);
6974 m = Bits32(opcode, 3, 0);
6975
6976 // index = TRUE; add = TRUE; wback = FALSE;
6977 index = true;
6978 add = true;
6979 wback = false;
6980
6981 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6982 shift_t = SRType_LSL;
6983 shift_n = Bits32(opcode, 5, 4);
6984
6985 // if Rt == '1111' then SEE PLD;
6986 if (t == 15)
6987 return false; // PLD is not implemented yet
6988
6989 // if Rn == '1111' then SEE LDRB (literal);
6990 if (n == 15)
6991 return EmulateLDRBLiteral(opcode, eEncodingT1);
6992
6993 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6994 if ((t == 13) || BadReg(m))
6995 return false;
6996 break;
6997
6998 case eEncodingA1: {
6999 // if P == '0' && W == '1' then SEE LDRBT;
7000 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7001 t = Bits32(opcode, 15, 12);
7002 n = Bits32(opcode, 19, 16);
7003 m = Bits32(opcode, 3, 0);
7004
7005 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7006 // (W == '1');
7007 index = BitIsSet(opcode, 24);
7008 add = BitIsSet(opcode, 23);
7009 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7010
7011 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
7012 uint32_t type = Bits32(opcode, 6, 5);
7013 uint32_t imm5 = Bits32(opcode, 11, 7);
7014 shift_n = DecodeImmShift(type, imm5, shift_t);
7015
7016 // if t == 15 || m == 15 then UNPREDICTABLE;
7017 if ((t == 15) || (m == 15))
7018 return false;
7019
7020 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7021 if (wback && ((n == 15) || (n == t)))
7022 return false;
7023 } break;
7024
7025 default:
7026 return false;
7027 }
7028
7029 addr_t offset_addr;
7030 addr_t address;
7031
7032 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7033 uint32_t Rm =
7034 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7035 if (!success)
7036 return false;
7037
7038 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7039 if (!success)
7040 return false;
7041
7042 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7043 uint32_t Rn =
7044 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7045 if (!success)
7046 return false;
7047
7048 if (add)
7049 offset_addr = Rn + offset;
7050 else
7051 offset_addr = Rn - offset;
7052
7053 // address = if index then offset_addr else R[n];
7054 if (index)
7055 address = offset_addr;
7056 else
7057 address = Rn;
7058
7059 // R[t] = ZeroExtend(MemU[address,1],32);
7060 RegisterInfo base_reg;
7061 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7062
7063 EmulateInstruction::Context context;
7064 context.type = eContextRegisterLoad;
7065 context.SetRegisterPlusOffset(base_reg, address - Rn);
7066
7067 uint64_t data = MemURead(context, address, 1, 0, &success);
7068 if (!success)
7069 return false;
7070
7071 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
7072 return false;
7073
7074 // if wback then R[n] = offset_addr;
7075 if (wback) {
7076 context.type = eContextAdjustBaseRegister;
7077 context.SetAddress(offset_addr);
7078 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7079 offset_addr))
7080 return false;
7081 }
7082 }
7083 return true;
7084 }
7085
7086 // LDRH (immediate, Thumb) calculates an address from a base register value and
7087 // an immediate offset, loads a
7088 // halfword from memory, zero-extends it to form a 32-bit word, and writes it
7089 // to a register. It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRHImmediate(const uint32_t opcode,const ARMEncoding encoding)7090 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
7091 const ARMEncoding encoding) {
7092 #if 0
7093 if ConditionPassed() then
7094 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7095 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7096 address = if index then offset_addr else R[n];
7097 data = MemU[address,2];
7098 if wback then R[n] = offset_addr;
7099 if UnalignedSupport() || address<0> = '0' then
7100 R[t] = ZeroExtend(data, 32);
7101 else // Can only apply before ARMv7
7102 R[t] = bits(32) UNKNOWN;
7103 #endif
7104
7105 bool success = false;
7106
7107 if (ConditionPassed(opcode)) {
7108 uint32_t t;
7109 uint32_t n;
7110 uint32_t imm32;
7111 bool index;
7112 bool add;
7113 bool wback;
7114
7115 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7116 switch (encoding) {
7117 case eEncodingT1:
7118 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
7119 t = Bits32(opcode, 2, 0);
7120 n = Bits32(opcode, 5, 3);
7121 imm32 = Bits32(opcode, 10, 6) << 1;
7122
7123 // index = TRUE; add = TRUE; wback = FALSE;
7124 index = true;
7125 add = true;
7126 wback = false;
7127
7128 break;
7129
7130 case eEncodingT2:
7131 // if Rt == '1111' then SEE "Unallocated memory hints";
7132 // if Rn == '1111' then SEE LDRH (literal);
7133 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7134 t = Bits32(opcode, 15, 12);
7135 n = Bits32(opcode, 19, 16);
7136 imm32 = Bits32(opcode, 11, 0);
7137
7138 // index = TRUE; add = TRUE; wback = FALSE;
7139 index = true;
7140 add = true;
7141 wback = false;
7142
7143 // if t == 13 then UNPREDICTABLE;
7144 if (t == 13)
7145 return false;
7146 break;
7147
7148 case eEncodingT3:
7149 // if Rn == '1111' then SEE LDRH (literal);
7150 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7151 // "Unallocated memory hints";
7152 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
7153 // if P == '0' && W == '0' then UNDEFINED;
7154 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7155 return false;
7156
7157 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7158 t = Bits32(opcode, 15, 12);
7159 n = Bits32(opcode, 19, 16);
7160 imm32 = Bits32(opcode, 7, 0);
7161
7162 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7163 index = BitIsSet(opcode, 10);
7164 add = BitIsSet(opcode, 9);
7165 wback = BitIsSet(opcode, 8);
7166
7167 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7168 if (BadReg(t) || (wback && (n == t)))
7169 return false;
7170 break;
7171
7172 default:
7173 return false;
7174 }
7175
7176 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7177 uint32_t Rn =
7178 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7179 if (!success)
7180 return false;
7181
7182 addr_t offset_addr;
7183 addr_t address;
7184
7185 if (add)
7186 offset_addr = Rn + imm32;
7187 else
7188 offset_addr = Rn - imm32;
7189
7190 // address = if index then offset_addr else R[n];
7191 if (index)
7192 address = offset_addr;
7193 else
7194 address = Rn;
7195
7196 // data = MemU[address,2];
7197 RegisterInfo base_reg;
7198 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7199
7200 EmulateInstruction::Context context;
7201 context.type = eContextRegisterLoad;
7202 context.SetRegisterPlusOffset(base_reg, address - Rn);
7203
7204 uint64_t data = MemURead(context, address, 2, 0, &success);
7205 if (!success)
7206 return false;
7207
7208 // if wback then R[n] = offset_addr;
7209 if (wback) {
7210 context.type = eContextAdjustBaseRegister;
7211 context.SetAddress(offset_addr);
7212 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7213 offset_addr))
7214 return false;
7215 }
7216
7217 // if UnalignedSupport() || address<0> = '0' then
7218 if (UnalignedSupport() || BitIsClear(address, 0)) {
7219 // R[t] = ZeroExtend(data, 32);
7220 context.type = eContextRegisterLoad;
7221 context.SetRegisterPlusOffset(base_reg, address - Rn);
7222 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7223 data))
7224 return false;
7225 } else // Can only apply before ARMv7
7226 {
7227 // R[t] = bits(32) UNKNOWN;
7228 WriteBits32Unknown(t);
7229 }
7230 }
7231 return true;
7232 }
7233
7234 // LDRH (literal) caculates an address from the PC value and an immediate
7235 // offset, loads a halfword from memory,
7236 // zero-extends it to form a 32-bit word, and writes it to a register.
EmulateLDRHLiteral(const uint32_t opcode,const ARMEncoding encoding)7237 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
7238 const ARMEncoding encoding) {
7239 #if 0
7240 if ConditionPassed() then
7241 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7242 base = Align(PC,4);
7243 address = if add then (base + imm32) else (base - imm32);
7244 data = MemU[address,2];
7245 if UnalignedSupport() || address<0> = '0' then
7246 R[t] = ZeroExtend(data, 32);
7247 else // Can only apply before ARMv7
7248 R[t] = bits(32) UNKNOWN;
7249 #endif
7250
7251 bool success = false;
7252
7253 if (ConditionPassed(opcode)) {
7254 uint32_t t;
7255 uint32_t imm32;
7256 bool add;
7257
7258 // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7259 switch (encoding) {
7260 case eEncodingT1:
7261 // if Rt == '1111' then SEE "Unallocated memory hints";
7262 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7263 t = Bits32(opcode, 15, 12);
7264 imm32 = Bits32(opcode, 11, 0);
7265 add = BitIsSet(opcode, 23);
7266
7267 // if t == 13 then UNPREDICTABLE;
7268 if (t == 13)
7269 return false;
7270
7271 break;
7272
7273 case eEncodingA1: {
7274 uint32_t imm4H = Bits32(opcode, 11, 8);
7275 uint32_t imm4L = Bits32(opcode, 3, 0);
7276
7277 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7278 t = Bits32(opcode, 15, 12);
7279 imm32 = (imm4H << 4) | imm4L;
7280 add = BitIsSet(opcode, 23);
7281
7282 // if t == 15 then UNPREDICTABLE;
7283 if (t == 15)
7284 return false;
7285 break;
7286 }
7287
7288 default:
7289 return false;
7290 }
7291
7292 // base = Align(PC,4);
7293 uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7294 if (!success)
7295 return false;
7296
7297 addr_t base = AlignPC(pc_value);
7298 addr_t address;
7299
7300 // address = if add then (base + imm32) else (base - imm32);
7301 if (add)
7302 address = base + imm32;
7303 else
7304 address = base - imm32;
7305
7306 // data = MemU[address,2];
7307 RegisterInfo base_reg;
7308 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7309
7310 EmulateInstruction::Context context;
7311 context.type = eContextRegisterLoad;
7312 context.SetRegisterPlusOffset(base_reg, address - base);
7313
7314 uint64_t data = MemURead(context, address, 2, 0, &success);
7315 if (!success)
7316 return false;
7317
7318 // if UnalignedSupport() || address<0> = '0' then
7319 if (UnalignedSupport() || BitIsClear(address, 0)) {
7320 // R[t] = ZeroExtend(data, 32);
7321 context.type = eContextRegisterLoad;
7322 context.SetRegisterPlusOffset(base_reg, address - base);
7323 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7324 data))
7325 return false;
7326
7327 } else // Can only apply before ARMv7
7328 {
7329 // R[t] = bits(32) UNKNOWN;
7330 WriteBits32Unknown(t);
7331 }
7332 }
7333 return true;
7334 }
7335
7336 // LDRH (literal) calculates an address from a base register value and an offset
7337 // register value, loads a halfword
7338 // from memory, zero-extends it to form a 32-bit word, and writes it to a
7339 // register. The offset register value can be shifted left by 0, 1, 2, or 3
7340 // bits.
EmulateLDRHRegister(const uint32_t opcode,const ARMEncoding encoding)7341 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
7342 const ARMEncoding encoding) {
7343 #if 0
7344 if ConditionPassed() then
7345 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7346 offset = Shift(R[m], shift_t, shift_n, APSR.C);
7347 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7348 address = if index then offset_addr else R[n];
7349 data = MemU[address,2];
7350 if wback then R[n] = offset_addr;
7351 if UnalignedSupport() || address<0> = '0' then
7352 R[t] = ZeroExtend(data, 32);
7353 else // Can only apply before ARMv7
7354 R[t] = bits(32) UNKNOWN;
7355 #endif
7356
7357 bool success = false;
7358
7359 if (ConditionPassed(opcode)) {
7360 uint32_t t;
7361 uint32_t n;
7362 uint32_t m;
7363 bool index;
7364 bool add;
7365 bool wback;
7366 ARM_ShifterType shift_t;
7367 uint32_t shift_n;
7368
7369 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7370 switch (encoding) {
7371 case eEncodingT1:
7372 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
7373 // in ThumbEE";
7374 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7375 t = Bits32(opcode, 2, 0);
7376 n = Bits32(opcode, 5, 3);
7377 m = Bits32(opcode, 8, 6);
7378
7379 // index = TRUE; add = TRUE; wback = FALSE;
7380 index = true;
7381 add = true;
7382 wback = false;
7383
7384 // (shift_t, shift_n) = (SRType_LSL, 0);
7385 shift_t = SRType_LSL;
7386 shift_n = 0;
7387
7388 break;
7389
7390 case eEncodingT2:
7391 // if Rn == '1111' then SEE LDRH (literal);
7392 // if Rt == '1111' then SEE "Unallocated memory hints";
7393 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7394 t = Bits32(opcode, 15, 12);
7395 n = Bits32(opcode, 19, 16);
7396 m = Bits32(opcode, 3, 0);
7397
7398 // index = TRUE; add = TRUE; wback = FALSE;
7399 index = true;
7400 add = true;
7401 wback = false;
7402
7403 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7404 shift_t = SRType_LSL;
7405 shift_n = Bits32(opcode, 5, 4);
7406
7407 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7408 if ((t == 13) || BadReg(m))
7409 return false;
7410 break;
7411
7412 case eEncodingA1:
7413 // if P == '0' && W == '1' then SEE LDRHT;
7414 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7415 t = Bits32(opcode, 15, 12);
7416 n = Bits32(opcode, 19, 16);
7417 m = Bits32(opcode, 3, 0);
7418
7419 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7420 // (W == '1');
7421 index = BitIsSet(opcode, 24);
7422 add = BitIsSet(opcode, 23);
7423 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7424
7425 // (shift_t, shift_n) = (SRType_LSL, 0);
7426 shift_t = SRType_LSL;
7427 shift_n = 0;
7428
7429 // if t == 15 || m == 15 then UNPREDICTABLE;
7430 if ((t == 15) || (m == 15))
7431 return false;
7432
7433 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7434 if (wback && ((n == 15) || (n == t)))
7435 return false;
7436
7437 break;
7438
7439 default:
7440 return false;
7441 }
7442
7443 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7444
7445 uint64_t Rm =
7446 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7447 if (!success)
7448 return false;
7449
7450 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7451 if (!success)
7452 return false;
7453
7454 addr_t offset_addr;
7455 addr_t address;
7456
7457 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7458 uint64_t Rn =
7459 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7460 if (!success)
7461 return false;
7462
7463 if (add)
7464 offset_addr = Rn + offset;
7465 else
7466 offset_addr = Rn - offset;
7467
7468 // address = if index then offset_addr else R[n];
7469 if (index)
7470 address = offset_addr;
7471 else
7472 address = Rn;
7473
7474 // data = MemU[address,2];
7475 RegisterInfo base_reg;
7476 RegisterInfo offset_reg;
7477 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7478 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7479
7480 EmulateInstruction::Context context;
7481 context.type = eContextRegisterLoad;
7482 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7483 uint64_t data = MemURead(context, address, 2, 0, &success);
7484 if (!success)
7485 return false;
7486
7487 // if wback then R[n] = offset_addr;
7488 if (wback) {
7489 context.type = eContextAdjustBaseRegister;
7490 context.SetAddress(offset_addr);
7491 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7492 offset_addr))
7493 return false;
7494 }
7495
7496 // if UnalignedSupport() || address<0> = '0' then
7497 if (UnalignedSupport() || BitIsClear(address, 0)) {
7498 // R[t] = ZeroExtend(data, 32);
7499 context.type = eContextRegisterLoad;
7500 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7501 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7502 data))
7503 return false;
7504 } else // Can only apply before ARMv7
7505 {
7506 // R[t] = bits(32) UNKNOWN;
7507 WriteBits32Unknown(t);
7508 }
7509 }
7510 return true;
7511 }
7512
7513 // LDRSB (immediate) calculates an address from a base register value and an
7514 // immediate offset, loads a byte from
7515 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7516 // It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRSBImmediate(const uint32_t opcode,const ARMEncoding encoding)7517 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
7518 const ARMEncoding encoding) {
7519 #if 0
7520 if ConditionPassed() then
7521 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7522 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7523 address = if index then offset_addr else R[n];
7524 R[t] = SignExtend(MemU[address,1], 32);
7525 if wback then R[n] = offset_addr;
7526 #endif
7527
7528 bool success = false;
7529
7530 if (ConditionPassed(opcode)) {
7531 uint32_t t;
7532 uint32_t n;
7533 uint32_t imm32;
7534 bool index;
7535 bool add;
7536 bool wback;
7537
7538 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7539 switch (encoding) {
7540 case eEncodingT1:
7541 // if Rt == '1111' then SEE PLI;
7542 // if Rn == '1111' then SEE LDRSB (literal);
7543 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7544 t = Bits32(opcode, 15, 12);
7545 n = Bits32(opcode, 19, 16);
7546 imm32 = Bits32(opcode, 11, 0);
7547
7548 // index = TRUE; add = TRUE; wback = FALSE;
7549 index = true;
7550 add = true;
7551 wback = false;
7552
7553 // if t == 13 then UNPREDICTABLE;
7554 if (t == 13)
7555 return false;
7556
7557 break;
7558
7559 case eEncodingT2:
7560 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7561 // if Rn == '1111' then SEE LDRSB (literal);
7562 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7563 // if P == '0' && W == '0' then UNDEFINED;
7564 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7565 return false;
7566
7567 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7568 t = Bits32(opcode, 15, 12);
7569 n = Bits32(opcode, 19, 16);
7570 imm32 = Bits32(opcode, 7, 0);
7571
7572 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7573 index = BitIsSet(opcode, 10);
7574 add = BitIsSet(opcode, 9);
7575 wback = BitIsSet(opcode, 8);
7576
7577 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7578 if (((t == 13) ||
7579 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
7580 BitIsSet(opcode, 8)))) ||
7581 (wback && (n == t)))
7582 return false;
7583
7584 break;
7585
7586 case eEncodingA1: {
7587 // if Rn == '1111' then SEE LDRSB (literal);
7588 // if P == '0' && W == '1' then SEE LDRSBT;
7589 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7590 t = Bits32(opcode, 15, 12);
7591 n = Bits32(opcode, 19, 16);
7592
7593 uint32_t imm4H = Bits32(opcode, 11, 8);
7594 uint32_t imm4L = Bits32(opcode, 3, 0);
7595 imm32 = (imm4H << 4) | imm4L;
7596
7597 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7598 // (W == '1');
7599 index = BitIsSet(opcode, 24);
7600 add = BitIsSet(opcode, 23);
7601 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7602
7603 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7604 if ((t == 15) || (wback && (n == t)))
7605 return false;
7606
7607 break;
7608 }
7609
7610 default:
7611 return false;
7612 }
7613
7614 uint64_t Rn = ReadCoreReg(n, &success);
7615 if (!success)
7616 return false;
7617
7618 addr_t offset_addr;
7619 addr_t address;
7620
7621 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7622 if (add)
7623 offset_addr = Rn + imm32;
7624 else
7625 offset_addr = Rn - imm32;
7626
7627 // address = if index then offset_addr else R[n];
7628 if (index)
7629 address = offset_addr;
7630 else
7631 address = Rn;
7632
7633 // R[t] = SignExtend(MemU[address,1], 32);
7634 RegisterInfo base_reg;
7635 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7636
7637 EmulateInstruction::Context context;
7638 context.type = eContextRegisterLoad;
7639 context.SetRegisterPlusOffset(base_reg, address - Rn);
7640
7641 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7642 if (!success)
7643 return false;
7644
7645 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7646 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7647 (uint64_t)signed_data))
7648 return false;
7649
7650 // if wback then R[n] = offset_addr;
7651 if (wback) {
7652 context.type = eContextAdjustBaseRegister;
7653 context.SetAddress(offset_addr);
7654 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7655 offset_addr))
7656 return false;
7657 }
7658 }
7659
7660 return true;
7661 }
7662
7663 // LDRSB (literal) calculates an address from the PC value and an immediate
7664 // offset, loads a byte from memory,
7665 // sign-extends it to form a 32-bit word, and writes tit to a register.
EmulateLDRSBLiteral(const uint32_t opcode,const ARMEncoding encoding)7666 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
7667 const ARMEncoding encoding) {
7668 #if 0
7669 if ConditionPassed() then
7670 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7671 base = Align(PC,4);
7672 address = if add then (base + imm32) else (base - imm32);
7673 R[t] = SignExtend(MemU[address,1], 32);
7674 #endif
7675
7676 bool success = false;
7677
7678 if (ConditionPassed(opcode)) {
7679 uint32_t t;
7680 uint32_t imm32;
7681 bool add;
7682
7683 // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7684 switch (encoding) {
7685 case eEncodingT1:
7686 // if Rt == '1111' then SEE PLI;
7687 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7688 t = Bits32(opcode, 15, 12);
7689 imm32 = Bits32(opcode, 11, 0);
7690 add = BitIsSet(opcode, 23);
7691
7692 // if t == 13 then UNPREDICTABLE;
7693 if (t == 13)
7694 return false;
7695
7696 break;
7697
7698 case eEncodingA1: {
7699 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7700 t = Bits32(opcode, 15, 12);
7701 uint32_t imm4H = Bits32(opcode, 11, 8);
7702 uint32_t imm4L = Bits32(opcode, 3, 0);
7703 imm32 = (imm4H << 4) | imm4L;
7704 add = BitIsSet(opcode, 23);
7705
7706 // if t == 15 then UNPREDICTABLE;
7707 if (t == 15)
7708 return false;
7709
7710 break;
7711 }
7712
7713 default:
7714 return false;
7715 }
7716
7717 // base = Align(PC,4);
7718 uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7719 if (!success)
7720 return false;
7721 uint64_t base = AlignPC(pc_value);
7722
7723 // address = if add then (base + imm32) else (base - imm32);
7724 addr_t address;
7725 if (add)
7726 address = base + imm32;
7727 else
7728 address = base - imm32;
7729
7730 // R[t] = SignExtend(MemU[address,1], 32);
7731 RegisterInfo base_reg;
7732 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7733
7734 EmulateInstruction::Context context;
7735 context.type = eContextRegisterLoad;
7736 context.SetRegisterPlusOffset(base_reg, address - base);
7737
7738 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7739 if (!success)
7740 return false;
7741
7742 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7743 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7744 (uint64_t)signed_data))
7745 return false;
7746 }
7747 return true;
7748 }
7749
7750 // LDRSB (register) calculates an address from a base register value and an
7751 // offset register value, loadsa byte from
7752 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7753 // The offset register value can be shifted left by 0, 1, 2, or 3 bits.
EmulateLDRSBRegister(const uint32_t opcode,const ARMEncoding encoding)7754 bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
7755 const ARMEncoding encoding) {
7756 #if 0
7757 if ConditionPassed() then
7758 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7759 offset = Shift(R[m], shift_t, shift_n, APSR.C);
7760 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7761 address = if index then offset_addr else R[n];
7762 R[t] = SignExtend(MemU[address,1], 32);
7763 if wback then R[n] = offset_addr;
7764 #endif
7765
7766 bool success = false;
7767
7768 if (ConditionPassed(opcode)) {
7769 uint32_t t;
7770 uint32_t n;
7771 uint32_t m;
7772 bool index;
7773 bool add;
7774 bool wback;
7775 ARM_ShifterType shift_t;
7776 uint32_t shift_n;
7777
7778 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7779 switch (encoding) {
7780 case eEncodingT1:
7781 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7782 t = Bits32(opcode, 2, 0);
7783 n = Bits32(opcode, 5, 3);
7784 m = Bits32(opcode, 8, 6);
7785
7786 // index = TRUE; add = TRUE; wback = FALSE;
7787 index = true;
7788 add = true;
7789 wback = false;
7790
7791 // (shift_t, shift_n) = (SRType_LSL, 0);
7792 shift_t = SRType_LSL;
7793 shift_n = 0;
7794
7795 break;
7796
7797 case eEncodingT2:
7798 // if Rt == '1111' then SEE PLI;
7799 // if Rn == '1111' then SEE LDRSB (literal);
7800 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7801 t = Bits32(opcode, 15, 12);
7802 n = Bits32(opcode, 19, 16);
7803 m = Bits32(opcode, 3, 0);
7804
7805 // index = TRUE; add = TRUE; wback = FALSE;
7806 index = true;
7807 add = true;
7808 wback = false;
7809
7810 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7811 shift_t = SRType_LSL;
7812 shift_n = Bits32(opcode, 5, 4);
7813
7814 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7815 if ((t == 13) || BadReg(m))
7816 return false;
7817 break;
7818
7819 case eEncodingA1:
7820 // if P == '0' && W == '1' then SEE LDRSBT;
7821 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7822 t = Bits32(opcode, 15, 12);
7823 n = Bits32(opcode, 19, 16);
7824 m = Bits32(opcode, 3, 0);
7825
7826 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7827 // (W == '1');
7828 index = BitIsSet(opcode, 24);
7829 add = BitIsSet(opcode, 23);
7830 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7831
7832 // (shift_t, shift_n) = (SRType_LSL, 0);
7833 shift_t = SRType_LSL;
7834 shift_n = 0;
7835
7836 // if t == 15 || m == 15 then UNPREDICTABLE;
7837 if ((t == 15) || (m == 15))
7838 return false;
7839
7840 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7841 if (wback && ((n == 15) || (n == t)))
7842 return false;
7843 break;
7844
7845 default:
7846 return false;
7847 }
7848
7849 uint64_t Rm =
7850 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7851 if (!success)
7852 return false;
7853
7854 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7855 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7856 if (!success)
7857 return false;
7858
7859 addr_t offset_addr;
7860 addr_t address;
7861
7862 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7863 uint64_t Rn =
7864 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7865 if (!success)
7866 return false;
7867
7868 if (add)
7869 offset_addr = Rn + offset;
7870 else
7871 offset_addr = Rn - offset;
7872
7873 // address = if index then offset_addr else R[n];
7874 if (index)
7875 address = offset_addr;
7876 else
7877 address = Rn;
7878
7879 // R[t] = SignExtend(MemU[address,1], 32);
7880 RegisterInfo base_reg;
7881 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7882 RegisterInfo offset_reg;
7883 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7884
7885 EmulateInstruction::Context context;
7886 context.type = eContextRegisterLoad;
7887 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7888
7889 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7890 if (!success)
7891 return false;
7892
7893 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7894 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7895 (uint64_t)signed_data))
7896 return false;
7897
7898 // if wback then R[n] = offset_addr;
7899 if (wback) {
7900 context.type = eContextAdjustBaseRegister;
7901 context.SetAddress(offset_addr);
7902 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7903 offset_addr))
7904 return false;
7905 }
7906 }
7907 return true;
7908 }
7909
7910 // LDRSH (immediate) calculates an address from a base register value and an
7911 // immediate offset, loads a halfword from
7912 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7913 // It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRSHImmediate(const uint32_t opcode,const ARMEncoding encoding)7914 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
7915 const ARMEncoding encoding) {
7916 #if 0
7917 if ConditionPassed() then
7918 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7919 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7920 address = if index then offset_addr else R[n];
7921 data = MemU[address,2];
7922 if wback then R[n] = offset_addr;
7923 if UnalignedSupport() || address<0> = '0' then
7924 R[t] = SignExtend(data, 32);
7925 else // Can only apply before ARMv7
7926 R[t] = bits(32) UNKNOWN;
7927 #endif
7928
7929 bool success = false;
7930
7931 if (ConditionPassed(opcode)) {
7932 uint32_t t;
7933 uint32_t n;
7934 uint32_t imm32;
7935 bool index;
7936 bool add;
7937 bool wback;
7938
7939 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7940 switch (encoding) {
7941 case eEncodingT1:
7942 // if Rn == '1111' then SEE LDRSH (literal);
7943 // if Rt == '1111' then SEE "Unallocated memory hints";
7944 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7945 t = Bits32(opcode, 15, 12);
7946 n = Bits32(opcode, 19, 16);
7947 imm32 = Bits32(opcode, 11, 0);
7948
7949 // index = TRUE; add = TRUE; wback = FALSE;
7950 index = true;
7951 add = true;
7952 wback = false;
7953
7954 // if t == 13 then UNPREDICTABLE;
7955 if (t == 13)
7956 return false;
7957
7958 break;
7959
7960 case eEncodingT2:
7961 // if Rn == '1111' then SEE LDRSH (literal);
7962 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7963 // "Unallocated memory hints";
7964 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7965 // if P == '0' && W == '0' then UNDEFINED;
7966 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7967 return false;
7968
7969 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7970 t = Bits32(opcode, 15, 12);
7971 n = Bits32(opcode, 19, 16);
7972 imm32 = Bits32(opcode, 7, 0);
7973
7974 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7975 index = BitIsSet(opcode, 10);
7976 add = BitIsSet(opcode, 9);
7977 wback = BitIsSet(opcode, 8);
7978
7979 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7980 if (BadReg(t) || (wback && (n == t)))
7981 return false;
7982
7983 break;
7984
7985 case eEncodingA1: {
7986 // if Rn == '1111' then SEE LDRSH (literal);
7987 // if P == '0' && W == '1' then SEE LDRSHT;
7988 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7989 t = Bits32(opcode, 15, 12);
7990 n = Bits32(opcode, 19, 16);
7991 uint32_t imm4H = Bits32(opcode, 11, 8);
7992 uint32_t imm4L = Bits32(opcode, 3, 0);
7993 imm32 = (imm4H << 4) | imm4L;
7994
7995 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
7996 // (W == '1');
7997 index = BitIsSet(opcode, 24);
7998 add = BitIsSet(opcode, 23);
7999 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8000
8001 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
8002 if ((t == 15) || (wback && (n == t)))
8003 return false;
8004
8005 break;
8006 }
8007
8008 default:
8009 return false;
8010 }
8011
8012 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
8013 uint64_t Rn =
8014 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8015 if (!success)
8016 return false;
8017
8018 addr_t offset_addr;
8019 if (add)
8020 offset_addr = Rn + imm32;
8021 else
8022 offset_addr = Rn - imm32;
8023
8024 // address = if index then offset_addr else R[n];
8025 addr_t address;
8026 if (index)
8027 address = offset_addr;
8028 else
8029 address = Rn;
8030
8031 // data = MemU[address,2];
8032 RegisterInfo base_reg;
8033 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8034
8035 EmulateInstruction::Context context;
8036 context.type = eContextRegisterLoad;
8037 context.SetRegisterPlusOffset(base_reg, address - Rn);
8038
8039 uint64_t data = MemURead(context, address, 2, 0, &success);
8040 if (!success)
8041 return false;
8042
8043 // if wback then R[n] = offset_addr;
8044 if (wback) {
8045 context.type = eContextAdjustBaseRegister;
8046 context.SetAddress(offset_addr);
8047 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8048 offset_addr))
8049 return false;
8050 }
8051
8052 // if UnalignedSupport() || address<0> = '0' then
8053 if (UnalignedSupport() || BitIsClear(address, 0)) {
8054 // R[t] = SignExtend(data, 32);
8055 int64_t signed_data = llvm::SignExtend64<16>(data);
8056 context.type = eContextRegisterLoad;
8057 context.SetRegisterPlusOffset(base_reg, address - Rn);
8058 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8059 (uint64_t)signed_data))
8060 return false;
8061 } else // Can only apply before ARMv7
8062 {
8063 // R[t] = bits(32) UNKNOWN;
8064 WriteBits32Unknown(t);
8065 }
8066 }
8067 return true;
8068 }
8069
8070 // LDRSH (literal) calculates an address from the PC value and an immediate
8071 // offset, loads a halfword from memory,
8072 // sign-extends it to from a 32-bit word, and writes it to a register.
EmulateLDRSHLiteral(const uint32_t opcode,const ARMEncoding encoding)8073 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
8074 const ARMEncoding encoding) {
8075 #if 0
8076 if ConditionPassed() then
8077 EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8078 base = Align(PC,4);
8079 address = if add then (base + imm32) else (base - imm32);
8080 data = MemU[address,2];
8081 if UnalignedSupport() || address<0> = '0' then
8082 R[t] = SignExtend(data, 32);
8083 else // Can only apply before ARMv7
8084 R[t] = bits(32) UNKNOWN;
8085 #endif
8086
8087 bool success = false;
8088
8089 if (ConditionPassed(opcode)) {
8090 uint32_t t;
8091 uint32_t imm32;
8092 bool add;
8093
8094 // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8095 switch (encoding) {
8096 case eEncodingT1:
8097 // if Rt == '1111' then SEE "Unallocated memory hints";
8098 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
8099 t = Bits32(opcode, 15, 12);
8100 imm32 = Bits32(opcode, 11, 0);
8101 add = BitIsSet(opcode, 23);
8102
8103 // if t == 13 then UNPREDICTABLE;
8104 if (t == 13)
8105 return false;
8106
8107 break;
8108
8109 case eEncodingA1: {
8110 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
8111 t = Bits32(opcode, 15, 12);
8112 uint32_t imm4H = Bits32(opcode, 11, 8);
8113 uint32_t imm4L = Bits32(opcode, 3, 0);
8114 imm32 = (imm4H << 4) | imm4L;
8115 add = BitIsSet(opcode, 23);
8116
8117 // if t == 15 then UNPREDICTABLE;
8118 if (t == 15)
8119 return false;
8120
8121 break;
8122 }
8123 default:
8124 return false;
8125 }
8126
8127 // base = Align(PC,4);
8128 uint64_t pc_value = ReadCoreReg(PC_REG, &success);
8129 if (!success)
8130 return false;
8131
8132 uint64_t base = AlignPC(pc_value);
8133
8134 addr_t address;
8135 // address = if add then (base + imm32) else (base - imm32);
8136 if (add)
8137 address = base + imm32;
8138 else
8139 address = base - imm32;
8140
8141 // data = MemU[address,2];
8142 RegisterInfo base_reg;
8143 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
8144
8145 EmulateInstruction::Context context;
8146 context.type = eContextRegisterLoad;
8147 context.SetRegisterPlusOffset(base_reg, imm32);
8148
8149 uint64_t data = MemURead(context, address, 2, 0, &success);
8150 if (!success)
8151 return false;
8152
8153 // if UnalignedSupport() || address<0> = '0' then
8154 if (UnalignedSupport() || BitIsClear(address, 0)) {
8155 // R[t] = SignExtend(data, 32);
8156 int64_t signed_data = llvm::SignExtend64<16>(data);
8157 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8158 (uint64_t)signed_data))
8159 return false;
8160 } else // Can only apply before ARMv7
8161 {
8162 // R[t] = bits(32) UNKNOWN;
8163 WriteBits32Unknown(t);
8164 }
8165 }
8166 return true;
8167 }
8168
8169 // LDRSH (register) calculates an address from a base register value and an
8170 // offset register value, loads a halfword
8171 // from memory, sign-extends it to form a 32-bit word, and writes it to a
8172 // register. The offset register value can be shifted left by 0, 1, 2, or 3
8173 // bits.
EmulateLDRSHRegister(const uint32_t opcode,const ARMEncoding encoding)8174 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
8175 const ARMEncoding encoding) {
8176 #if 0
8177 if ConditionPassed() then
8178 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8179 offset = Shift(R[m], shift_t, shift_n, APSR.C);
8180 offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8181 address = if index then offset_addr else R[n];
8182 data = MemU[address,2];
8183 if wback then R[n] = offset_addr;
8184 if UnalignedSupport() || address<0> = '0' then
8185 R[t] = SignExtend(data, 32);
8186 else // Can only apply before ARMv7
8187 R[t] = bits(32) UNKNOWN;
8188 #endif
8189
8190 bool success = false;
8191
8192 if (ConditionPassed(opcode)) {
8193 uint32_t t;
8194 uint32_t n;
8195 uint32_t m;
8196 bool index;
8197 bool add;
8198 bool wback;
8199 ARM_ShifterType shift_t;
8200 uint32_t shift_n;
8201
8202 // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8203 switch (encoding) {
8204 case eEncodingT1:
8205 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
8206 // in ThumbEE";
8207 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8208 t = Bits32(opcode, 2, 0);
8209 n = Bits32(opcode, 5, 3);
8210 m = Bits32(opcode, 8, 6);
8211
8212 // index = TRUE; add = TRUE; wback = FALSE;
8213 index = true;
8214 add = true;
8215 wback = false;
8216
8217 // (shift_t, shift_n) = (SRType_LSL, 0);
8218 shift_t = SRType_LSL;
8219 shift_n = 0;
8220
8221 break;
8222
8223 case eEncodingT2:
8224 // if Rn == '1111' then SEE LDRSH (literal);
8225 // if Rt == '1111' then SEE "Unallocated memory hints";
8226 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8227 t = Bits32(opcode, 15, 12);
8228 n = Bits32(opcode, 19, 16);
8229 m = Bits32(opcode, 3, 0);
8230
8231 // index = TRUE; add = TRUE; wback = FALSE;
8232 index = true;
8233 add = true;
8234 wback = false;
8235
8236 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
8237 shift_t = SRType_LSL;
8238 shift_n = Bits32(opcode, 5, 4);
8239
8240 // if t == 13 || BadReg(m) then UNPREDICTABLE;
8241 if ((t == 13) || BadReg(m))
8242 return false;
8243
8244 break;
8245
8246 case eEncodingA1:
8247 // if P == '0' && W == '1' then SEE LDRSHT;
8248 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8249 t = Bits32(opcode, 15, 12);
8250 n = Bits32(opcode, 19, 16);
8251 m = Bits32(opcode, 3, 0);
8252
8253 // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
8254 // (W == '1');
8255 index = BitIsSet(opcode, 24);
8256 add = BitIsSet(opcode, 23);
8257 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8258
8259 // (shift_t, shift_n) = (SRType_LSL, 0);
8260 shift_t = SRType_LSL;
8261 shift_n = 0;
8262
8263 // if t == 15 || m == 15 then UNPREDICTABLE;
8264 if ((t == 15) || (m == 15))
8265 return false;
8266
8267 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
8268 if (wback && ((n == 15) || (n == t)))
8269 return false;
8270
8271 break;
8272
8273 default:
8274 return false;
8275 }
8276
8277 uint64_t Rm =
8278 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8279 if (!success)
8280 return false;
8281
8282 uint64_t Rn =
8283 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8284 if (!success)
8285 return false;
8286
8287 // offset = Shift(R[m], shift_t, shift_n, APSR.C);
8288 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
8289 if (!success)
8290 return false;
8291
8292 addr_t offset_addr;
8293 addr_t address;
8294
8295 // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8296 if (add)
8297 offset_addr = Rn + offset;
8298 else
8299 offset_addr = Rn - offset;
8300
8301 // address = if index then offset_addr else R[n];
8302 if (index)
8303 address = offset_addr;
8304 else
8305 address = Rn;
8306
8307 // data = MemU[address,2];
8308 RegisterInfo base_reg;
8309 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8310
8311 RegisterInfo offset_reg;
8312 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
8313
8314 EmulateInstruction::Context context;
8315 context.type = eContextRegisterLoad;
8316 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8317
8318 uint64_t data = MemURead(context, address, 2, 0, &success);
8319 if (!success)
8320 return false;
8321
8322 // if wback then R[n] = offset_addr;
8323 if (wback) {
8324 context.type = eContextAdjustBaseRegister;
8325 context.SetAddress(offset_addr);
8326 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8327 offset_addr))
8328 return false;
8329 }
8330
8331 // if UnalignedSupport() || address<0> = '0' then
8332 if (UnalignedSupport() || BitIsClear(address, 0)) {
8333 // R[t] = SignExtend(data, 32);
8334 context.type = eContextRegisterLoad;
8335 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8336
8337 int64_t signed_data = llvm::SignExtend64<16>(data);
8338 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8339 (uint64_t)signed_data))
8340 return false;
8341 } else // Can only apply before ARMv7
8342 {
8343 // R[t] = bits(32) UNKNOWN;
8344 WriteBits32Unknown(t);
8345 }
8346 }
8347 return true;
8348 }
8349
8350 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
8351 // writes the result to the destination
8352 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before
8353 // extracting the 8-bit value.
EmulateSXTB(const uint32_t opcode,const ARMEncoding encoding)8354 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
8355 const ARMEncoding encoding) {
8356 #if 0
8357 if ConditionPassed() then
8358 EncodingSpecificOperations();
8359 rotated = ROR(R[m], rotation);
8360 R[d] = SignExtend(rotated<7:0>, 32);
8361 #endif
8362
8363 bool success = false;
8364
8365 if (ConditionPassed(opcode)) {
8366 uint32_t d;
8367 uint32_t m;
8368 uint32_t rotation;
8369
8370 // EncodingSpecificOperations();
8371 switch (encoding) {
8372 case eEncodingT1:
8373 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8374 d = Bits32(opcode, 2, 0);
8375 m = Bits32(opcode, 5, 3);
8376 rotation = 0;
8377
8378 break;
8379
8380 case eEncodingT2:
8381 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8382 d = Bits32(opcode, 11, 8);
8383 m = Bits32(opcode, 3, 0);
8384 rotation = Bits32(opcode, 5, 4) << 3;
8385
8386 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8387 if (BadReg(d) || BadReg(m))
8388 return false;
8389
8390 break;
8391
8392 case eEncodingA1:
8393 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8394 d = Bits32(opcode, 15, 12);
8395 m = Bits32(opcode, 3, 0);
8396 rotation = Bits32(opcode, 11, 10) << 3;
8397
8398 // if d == 15 || m == 15 then UNPREDICTABLE;
8399 if ((d == 15) || (m == 15))
8400 return false;
8401
8402 break;
8403
8404 default:
8405 return false;
8406 }
8407
8408 uint64_t Rm =
8409 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8410 if (!success)
8411 return false;
8412
8413 // rotated = ROR(R[m], rotation);
8414 uint64_t rotated = ROR(Rm, rotation, &success);
8415 if (!success)
8416 return false;
8417
8418 // R[d] = SignExtend(rotated<7:0>, 32);
8419 int64_t data = llvm::SignExtend64<8>(rotated);
8420
8421 RegisterInfo source_reg;
8422 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8423
8424 EmulateInstruction::Context context;
8425 context.type = eContextRegisterLoad;
8426 context.SetRegister(source_reg);
8427
8428 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8429 (uint64_t)data))
8430 return false;
8431 }
8432 return true;
8433 }
8434
8435 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
8436 // writes the result to the destination
8437 // register. You can specify a rotation by 0, 8, 16, or 24 bits before
8438 // extracting the 16-bit value.
EmulateSXTH(const uint32_t opcode,const ARMEncoding encoding)8439 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
8440 const ARMEncoding encoding) {
8441 #if 0
8442 if ConditionPassed() then
8443 EncodingSpecificOperations();
8444 rotated = ROR(R[m], rotation);
8445 R[d] = SignExtend(rotated<15:0>, 32);
8446 #endif
8447
8448 bool success = false;
8449
8450 if (ConditionPassed(opcode)) {
8451 uint32_t d;
8452 uint32_t m;
8453 uint32_t rotation;
8454
8455 // EncodingSpecificOperations();
8456 switch (encoding) {
8457 case eEncodingT1:
8458 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8459 d = Bits32(opcode, 2, 0);
8460 m = Bits32(opcode, 5, 3);
8461 rotation = 0;
8462
8463 break;
8464
8465 case eEncodingT2:
8466 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8467 d = Bits32(opcode, 11, 8);
8468 m = Bits32(opcode, 3, 0);
8469 rotation = Bits32(opcode, 5, 4) << 3;
8470
8471 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8472 if (BadReg(d) || BadReg(m))
8473 return false;
8474
8475 break;
8476
8477 case eEncodingA1:
8478 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8479 d = Bits32(opcode, 15, 12);
8480 m = Bits32(opcode, 3, 0);
8481 rotation = Bits32(opcode, 11, 10) << 3;
8482
8483 // if d == 15 || m == 15 then UNPREDICTABLE;
8484 if ((d == 15) || (m == 15))
8485 return false;
8486
8487 break;
8488
8489 default:
8490 return false;
8491 }
8492
8493 uint64_t Rm =
8494 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8495 if (!success)
8496 return false;
8497
8498 // rotated = ROR(R[m], rotation);
8499 uint64_t rotated = ROR(Rm, rotation, &success);
8500 if (!success)
8501 return false;
8502
8503 // R[d] = SignExtend(rotated<15:0>, 32);
8504 RegisterInfo source_reg;
8505 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8506
8507 EmulateInstruction::Context context;
8508 context.type = eContextRegisterLoad;
8509 context.SetRegister(source_reg);
8510
8511 int64_t data = llvm::SignExtend64<16>(rotated);
8512 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8513 (uint64_t)data))
8514 return false;
8515 }
8516
8517 return true;
8518 }
8519
8520 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and
8521 // writes the result to the destination
8522 // register. You can specify a rotation by 0, 8, 16, or 24 bits before
8523 // extracting the 8-bit value.
EmulateUXTB(const uint32_t opcode,const ARMEncoding encoding)8524 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
8525 const ARMEncoding encoding) {
8526 #if 0
8527 if ConditionPassed() then
8528 EncodingSpecificOperations();
8529 rotated = ROR(R[m], rotation);
8530 R[d] = ZeroExtend(rotated<7:0>, 32);
8531 #endif
8532
8533 bool success = false;
8534
8535 if (ConditionPassed(opcode)) {
8536 uint32_t d;
8537 uint32_t m;
8538 uint32_t rotation;
8539
8540 // EncodingSpecificOperations();
8541 switch (encoding) {
8542 case eEncodingT1:
8543 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8544 d = Bits32(opcode, 2, 0);
8545 m = Bits32(opcode, 5, 3);
8546 rotation = 0;
8547
8548 break;
8549
8550 case eEncodingT2:
8551 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8552 d = Bits32(opcode, 11, 8);
8553 m = Bits32(opcode, 3, 0);
8554 rotation = Bits32(opcode, 5, 4) << 3;
8555
8556 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8557 if (BadReg(d) || BadReg(m))
8558 return false;
8559
8560 break;
8561
8562 case eEncodingA1:
8563 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8564 d = Bits32(opcode, 15, 12);
8565 m = Bits32(opcode, 3, 0);
8566 rotation = Bits32(opcode, 11, 10) << 3;
8567
8568 // if d == 15 || m == 15 then UNPREDICTABLE;
8569 if ((d == 15) || (m == 15))
8570 return false;
8571
8572 break;
8573
8574 default:
8575 return false;
8576 }
8577
8578 uint64_t Rm =
8579 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8580 if (!success)
8581 return false;
8582
8583 // rotated = ROR(R[m], rotation);
8584 uint64_t rotated = ROR(Rm, rotation, &success);
8585 if (!success)
8586 return false;
8587
8588 // R[d] = ZeroExtend(rotated<7:0>, 32);
8589 RegisterInfo source_reg;
8590 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8591
8592 EmulateInstruction::Context context;
8593 context.type = eContextRegisterLoad;
8594 context.SetRegister(source_reg);
8595
8596 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8597 Bits32(rotated, 7, 0)))
8598 return false;
8599 }
8600 return true;
8601 }
8602
8603 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
8604 // writes the result to the destination
8605 // register. You can specify a rotation by 0, 8, 16, or 24 bits before
8606 // extracting the 16-bit value.
EmulateUXTH(const uint32_t opcode,const ARMEncoding encoding)8607 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
8608 const ARMEncoding encoding) {
8609 #if 0
8610 if ConditionPassed() then
8611 EncodingSpecificOperations();
8612 rotated = ROR(R[m], rotation);
8613 R[d] = ZeroExtend(rotated<15:0>, 32);
8614 #endif
8615
8616 bool success = false;
8617
8618 if (ConditionPassed(opcode)) {
8619 uint32_t d;
8620 uint32_t m;
8621 uint32_t rotation;
8622
8623 switch (encoding) {
8624 case eEncodingT1:
8625 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8626 d = Bits32(opcode, 2, 0);
8627 m = Bits32(opcode, 5, 3);
8628 rotation = 0;
8629
8630 break;
8631
8632 case eEncodingT2:
8633 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8634 d = Bits32(opcode, 11, 8);
8635 m = Bits32(opcode, 3, 0);
8636 rotation = Bits32(opcode, 5, 4) << 3;
8637
8638 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8639 if (BadReg(d) || BadReg(m))
8640 return false;
8641
8642 break;
8643
8644 case eEncodingA1:
8645 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8646 d = Bits32(opcode, 15, 12);
8647 m = Bits32(opcode, 3, 0);
8648 rotation = Bits32(opcode, 11, 10) << 3;
8649
8650 // if d == 15 || m == 15 then UNPREDICTABLE;
8651 if ((d == 15) || (m == 15))
8652 return false;
8653
8654 break;
8655
8656 default:
8657 return false;
8658 }
8659
8660 uint64_t Rm =
8661 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8662 if (!success)
8663 return false;
8664
8665 // rotated = ROR(R[m], rotation);
8666 uint64_t rotated = ROR(Rm, rotation, &success);
8667 if (!success)
8668 return false;
8669
8670 // R[d] = ZeroExtend(rotated<15:0>, 32);
8671 RegisterInfo source_reg;
8672 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8673
8674 EmulateInstruction::Context context;
8675 context.type = eContextRegisterLoad;
8676 context.SetRegister(source_reg);
8677
8678 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8679 Bits32(rotated, 15, 0)))
8680 return false;
8681 }
8682 return true;
8683 }
8684
8685 // RFE (Return From Exception) loads the PC and the CPSR from the word at the
8686 // specified address and the following
8687 // word respectively.
EmulateRFE(const uint32_t opcode,const ARMEncoding encoding)8688 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
8689 const ARMEncoding encoding) {
8690 #if 0
8691 if ConditionPassed() then
8692 EncodingSpecificOperations();
8693 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8694 UNPREDICTABLE;
8695 else
8696 address = if increment then R[n] else R[n]-8;
8697 if wordhigher then address = address+4;
8698 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8699 BranchWritePC(MemA[address,4]);
8700 if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8701 #endif
8702
8703 bool success = false;
8704
8705 if (ConditionPassed(opcode)) {
8706 uint32_t n;
8707 bool wback;
8708 bool increment;
8709 bool wordhigher;
8710
8711 // EncodingSpecificOperations();
8712 switch (encoding) {
8713 case eEncodingT1:
8714 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
8715 // FALSE;
8716 n = Bits32(opcode, 19, 16);
8717 wback = BitIsSet(opcode, 21);
8718 increment = false;
8719 wordhigher = false;
8720
8721 // if n == 15 then UNPREDICTABLE;
8722 if (n == 15)
8723 return false;
8724
8725 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8726 if (InITBlock() && !LastInITBlock())
8727 return false;
8728
8729 break;
8730
8731 case eEncodingT2:
8732 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8733 n = Bits32(opcode, 19, 16);
8734 wback = BitIsSet(opcode, 21);
8735 increment = true;
8736 wordhigher = false;
8737
8738 // if n == 15 then UNPREDICTABLE;
8739 if (n == 15)
8740 return false;
8741
8742 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8743 if (InITBlock() && !LastInITBlock())
8744 return false;
8745
8746 break;
8747
8748 case eEncodingA1:
8749 // n = UInt(Rn);
8750 n = Bits32(opcode, 19, 16);
8751
8752 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8753 wback = BitIsSet(opcode, 21);
8754 increment = BitIsSet(opcode, 23);
8755 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
8756
8757 // if n == 15 then UNPREDICTABLE;
8758 if (n == 15)
8759 return false;
8760
8761 break;
8762
8763 default:
8764 return false;
8765 }
8766
8767 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
8768 // then
8769 if (!CurrentModeIsPrivileged())
8770 // UNPREDICTABLE;
8771 return false;
8772 else {
8773 uint64_t Rn =
8774 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8775 if (!success)
8776 return false;
8777
8778 addr_t address;
8779 // address = if increment then R[n] else R[n]-8;
8780 if (increment)
8781 address = Rn;
8782 else
8783 address = Rn - 8;
8784
8785 // if wordhigher then address = address+4;
8786 if (wordhigher)
8787 address = address + 4;
8788
8789 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8790 RegisterInfo base_reg;
8791 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8792
8793 EmulateInstruction::Context context;
8794 context.type = eContextReturnFromException;
8795 context.SetRegisterPlusOffset(base_reg, address - Rn);
8796
8797 uint64_t data = MemARead(context, address + 4, 4, 0, &success);
8798 if (!success)
8799 return false;
8800
8801 CPSRWriteByInstr(data, 15, true);
8802
8803 // BranchWritePC(MemA[address,4]);
8804 uint64_t data2 = MemARead(context, address, 4, 0, &success);
8805 if (!success)
8806 return false;
8807
8808 BranchWritePC(context, data2);
8809
8810 // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8811 if (wback) {
8812 context.type = eContextAdjustBaseRegister;
8813 if (increment) {
8814 context.SetOffset(8);
8815 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8816 Rn + 8))
8817 return false;
8818 } else {
8819 context.SetOffset(-8);
8820 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8821 Rn - 8))
8822 return false;
8823 }
8824 } // if wback
8825 }
8826 } // if ConditionPassed()
8827 return true;
8828 }
8829
8830 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
8831 // register value and an immediate value, and writes the result to the
8832 // destination register. It can optionally update the condition flags based on
8833 // the result.
EmulateEORImm(const uint32_t opcode,const ARMEncoding encoding)8834 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
8835 const ARMEncoding encoding) {
8836 #if 0
8837 // ARM pseudo code...
8838 if ConditionPassed() then
8839 EncodingSpecificOperations();
8840 result = R[n] EOR imm32;
8841 if d == 15 then // Can only occur for ARM encoding
8842 ALUWritePC(result); // setflags is always FALSE here
8843 else
8844 R[d] = result;
8845 if setflags then
8846 APSR.N = result<31>;
8847 APSR.Z = IsZeroBit(result);
8848 APSR.C = carry;
8849 // APSR.V unchanged
8850 #endif
8851
8852 bool success = false;
8853
8854 if (ConditionPassed(opcode)) {
8855 uint32_t Rd, Rn;
8856 uint32_t
8857 imm32; // the immediate value to be ORed to the value obtained from Rn
8858 bool setflags;
8859 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8860 switch (encoding) {
8861 case eEncodingT1:
8862 Rd = Bits32(opcode, 11, 8);
8863 Rn = Bits32(opcode, 19, 16);
8864 setflags = BitIsSet(opcode, 20);
8865 imm32 = ThumbExpandImm_C(
8866 opcode, APSR_C,
8867 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8868 // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8869 if (Rd == 15 && setflags)
8870 return EmulateTEQImm(opcode, eEncodingT1);
8871 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8872 return false;
8873 break;
8874 case eEncodingA1:
8875 Rd = Bits32(opcode, 15, 12);
8876 Rn = Bits32(opcode, 19, 16);
8877 setflags = BitIsSet(opcode, 20);
8878 imm32 =
8879 ARMExpandImm_C(opcode, APSR_C,
8880 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8881
8882 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8883 // instructions;
8884 if (Rd == 15 && setflags)
8885 return EmulateSUBSPcLrEtc(opcode, encoding);
8886 break;
8887 default:
8888 return false;
8889 }
8890
8891 // Read the first operand.
8892 uint32_t val1 = ReadCoreReg(Rn, &success);
8893 if (!success)
8894 return false;
8895
8896 uint32_t result = val1 ^ imm32;
8897
8898 EmulateInstruction::Context context;
8899 context.type = EmulateInstruction::eContextImmediate;
8900 context.SetNoArgs();
8901
8902 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8903 return false;
8904 }
8905 return true;
8906 }
8907
8908 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a
8909 // register value and an optionally-shifted register value, and writes the
8910 // result to the destination register. It can optionally update the condition
8911 // flags based on the result.
EmulateEORReg(const uint32_t opcode,const ARMEncoding encoding)8912 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
8913 const ARMEncoding encoding) {
8914 #if 0
8915 // ARM pseudo code...
8916 if ConditionPassed() then
8917 EncodingSpecificOperations();
8918 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8919 result = R[n] EOR shifted;
8920 if d == 15 then // Can only occur for ARM encoding
8921 ALUWritePC(result); // setflags is always FALSE here
8922 else
8923 R[d] = result;
8924 if setflags then
8925 APSR.N = result<31>;
8926 APSR.Z = IsZeroBit(result);
8927 APSR.C = carry;
8928 // APSR.V unchanged
8929 #endif
8930
8931 bool success = false;
8932
8933 if (ConditionPassed(opcode)) {
8934 uint32_t Rd, Rn, Rm;
8935 ARM_ShifterType shift_t;
8936 uint32_t shift_n; // the shift applied to the value read from Rm
8937 bool setflags;
8938 uint32_t carry;
8939 switch (encoding) {
8940 case eEncodingT1:
8941 Rd = Rn = Bits32(opcode, 2, 0);
8942 Rm = Bits32(opcode, 5, 3);
8943 setflags = !InITBlock();
8944 shift_t = SRType_LSL;
8945 shift_n = 0;
8946 break;
8947 case eEncodingT2:
8948 Rd = Bits32(opcode, 11, 8);
8949 Rn = Bits32(opcode, 19, 16);
8950 Rm = Bits32(opcode, 3, 0);
8951 setflags = BitIsSet(opcode, 20);
8952 shift_n = DecodeImmShiftThumb(opcode, shift_t);
8953 // if Rd == '1111' && S == '1' then SEE TEQ (register);
8954 if (Rd == 15 && setflags)
8955 return EmulateTEQReg(opcode, eEncodingT1);
8956 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8957 return false;
8958 break;
8959 case eEncodingA1:
8960 Rd = Bits32(opcode, 15, 12);
8961 Rn = Bits32(opcode, 19, 16);
8962 Rm = Bits32(opcode, 3, 0);
8963 setflags = BitIsSet(opcode, 20);
8964 shift_n = DecodeImmShiftARM(opcode, shift_t);
8965
8966 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8967 // instructions;
8968 if (Rd == 15 && setflags)
8969 return EmulateSUBSPcLrEtc(opcode, encoding);
8970 break;
8971 default:
8972 return false;
8973 }
8974
8975 // Read the first operand.
8976 uint32_t val1 = ReadCoreReg(Rn, &success);
8977 if (!success)
8978 return false;
8979
8980 // Read the second operand.
8981 uint32_t val2 = ReadCoreReg(Rm, &success);
8982 if (!success)
8983 return false;
8984
8985 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8986 if (!success)
8987 return false;
8988 uint32_t result = val1 ^ shifted;
8989
8990 EmulateInstruction::Context context;
8991 context.type = EmulateInstruction::eContextImmediate;
8992 context.SetNoArgs();
8993
8994 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8995 return false;
8996 }
8997 return true;
8998 }
8999
9000 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
9001 // and an immediate value, and writes the result to the destination register.
9002 // It can optionally update the condition flags based on the result.
EmulateORRImm(const uint32_t opcode,const ARMEncoding encoding)9003 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
9004 const ARMEncoding encoding) {
9005 #if 0
9006 // ARM pseudo code...
9007 if ConditionPassed() then
9008 EncodingSpecificOperations();
9009 result = R[n] OR imm32;
9010 if d == 15 then // Can only occur for ARM encoding
9011 ALUWritePC(result); // setflags is always FALSE here
9012 else
9013 R[d] = result;
9014 if setflags then
9015 APSR.N = result<31>;
9016 APSR.Z = IsZeroBit(result);
9017 APSR.C = carry;
9018 // APSR.V unchanged
9019 #endif
9020
9021 bool success = false;
9022
9023 if (ConditionPassed(opcode)) {
9024 uint32_t Rd, Rn;
9025 uint32_t
9026 imm32; // the immediate value to be ORed to the value obtained from Rn
9027 bool setflags;
9028 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9029 switch (encoding) {
9030 case eEncodingT1:
9031 Rd = Bits32(opcode, 11, 8);
9032 Rn = Bits32(opcode, 19, 16);
9033 setflags = BitIsSet(opcode, 20);
9034 imm32 = ThumbExpandImm_C(
9035 opcode, APSR_C,
9036 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9037 // if Rn == '1111' then SEE MOV (immediate);
9038 if (Rn == 15)
9039 return EmulateMOVRdImm(opcode, eEncodingT2);
9040 if (BadReg(Rd) || Rn == 13)
9041 return false;
9042 break;
9043 case eEncodingA1:
9044 Rd = Bits32(opcode, 15, 12);
9045 Rn = Bits32(opcode, 19, 16);
9046 setflags = BitIsSet(opcode, 20);
9047 imm32 =
9048 ARMExpandImm_C(opcode, APSR_C,
9049 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9050
9051 if (Rd == 15 && setflags)
9052 return EmulateSUBSPcLrEtc(opcode, encoding);
9053 break;
9054 default:
9055 return false;
9056 }
9057
9058 // Read the first operand.
9059 uint32_t val1 = ReadCoreReg(Rn, &success);
9060 if (!success)
9061 return false;
9062
9063 uint32_t result = val1 | imm32;
9064
9065 EmulateInstruction::Context context;
9066 context.type = EmulateInstruction::eContextImmediate;
9067 context.SetNoArgs();
9068
9069 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9070 return false;
9071 }
9072 return true;
9073 }
9074
9075 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
9076 // and an optionally-shifted register value, and writes the result to the
9077 // destination register. It can optionally update the condition flags based on
9078 // the result.
EmulateORRReg(const uint32_t opcode,const ARMEncoding encoding)9079 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
9080 const ARMEncoding encoding) {
9081 #if 0
9082 // ARM pseudo code...
9083 if ConditionPassed() then
9084 EncodingSpecificOperations();
9085 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9086 result = R[n] OR shifted;
9087 if d == 15 then // Can only occur for ARM encoding
9088 ALUWritePC(result); // setflags is always FALSE here
9089 else
9090 R[d] = result;
9091 if setflags then
9092 APSR.N = result<31>;
9093 APSR.Z = IsZeroBit(result);
9094 APSR.C = carry;
9095 // APSR.V unchanged
9096 #endif
9097
9098 bool success = false;
9099
9100 if (ConditionPassed(opcode)) {
9101 uint32_t Rd, Rn, Rm;
9102 ARM_ShifterType shift_t;
9103 uint32_t shift_n; // the shift applied to the value read from Rm
9104 bool setflags;
9105 uint32_t carry;
9106 switch (encoding) {
9107 case eEncodingT1:
9108 Rd = Rn = Bits32(opcode, 2, 0);
9109 Rm = Bits32(opcode, 5, 3);
9110 setflags = !InITBlock();
9111 shift_t = SRType_LSL;
9112 shift_n = 0;
9113 break;
9114 case eEncodingT2:
9115 Rd = Bits32(opcode, 11, 8);
9116 Rn = Bits32(opcode, 19, 16);
9117 Rm = Bits32(opcode, 3, 0);
9118 setflags = BitIsSet(opcode, 20);
9119 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9120 // if Rn == '1111' then SEE MOV (register);
9121 if (Rn == 15)
9122 return EmulateMOVRdRm(opcode, eEncodingT3);
9123 if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
9124 return false;
9125 break;
9126 case eEncodingA1:
9127 Rd = Bits32(opcode, 15, 12);
9128 Rn = Bits32(opcode, 19, 16);
9129 Rm = Bits32(opcode, 3, 0);
9130 setflags = BitIsSet(opcode, 20);
9131 shift_n = DecodeImmShiftARM(opcode, shift_t);
9132
9133 if (Rd == 15 && setflags)
9134 return EmulateSUBSPcLrEtc(opcode, encoding);
9135 break;
9136 default:
9137 return false;
9138 }
9139
9140 // Read the first operand.
9141 uint32_t val1 = ReadCoreReg(Rn, &success);
9142 if (!success)
9143 return false;
9144
9145 // Read the second operand.
9146 uint32_t val2 = ReadCoreReg(Rm, &success);
9147 if (!success)
9148 return false;
9149
9150 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9151 if (!success)
9152 return false;
9153 uint32_t result = val1 | shifted;
9154
9155 EmulateInstruction::Context context;
9156 context.type = EmulateInstruction::eContextImmediate;
9157 context.SetNoArgs();
9158
9159 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9160 return false;
9161 }
9162 return true;
9163 }
9164
9165 // Reverse Subtract (immediate) subtracts a register value from an immediate
9166 // value, and writes the result to the destination register. It can optionally
9167 // update the condition flags based on the result.
EmulateRSBImm(const uint32_t opcode,const ARMEncoding encoding)9168 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
9169 const ARMEncoding encoding) {
9170 #if 0
9171 // ARM pseudo code...
9172 if ConditionPassed() then
9173 EncodingSpecificOperations();
9174 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
9175 if d == 15 then // Can only occur for ARM encoding
9176 ALUWritePC(result); // setflags is always FALSE here
9177 else
9178 R[d] = result;
9179 if setflags then
9180 APSR.N = result<31>;
9181 APSR.Z = IsZeroBit(result);
9182 APSR.C = carry;
9183 APSR.V = overflow;
9184 #endif
9185
9186 bool success = false;
9187
9188 uint32_t Rd; // the destination register
9189 uint32_t Rn; // the first operand
9190 bool setflags;
9191 uint32_t
9192 imm32; // the immediate value to be added to the value obtained from Rn
9193 switch (encoding) {
9194 case eEncodingT1:
9195 Rd = Bits32(opcode, 2, 0);
9196 Rn = Bits32(opcode, 5, 3);
9197 setflags = !InITBlock();
9198 imm32 = 0;
9199 break;
9200 case eEncodingT2:
9201 Rd = Bits32(opcode, 11, 8);
9202 Rn = Bits32(opcode, 19, 16);
9203 setflags = BitIsSet(opcode, 20);
9204 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9205 if (BadReg(Rd) || BadReg(Rn))
9206 return false;
9207 break;
9208 case eEncodingA1:
9209 Rd = Bits32(opcode, 15, 12);
9210 Rn = Bits32(opcode, 19, 16);
9211 setflags = BitIsSet(opcode, 20);
9212 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9213
9214 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9215 // instructions;
9216 if (Rd == 15 && setflags)
9217 return EmulateSUBSPcLrEtc(opcode, encoding);
9218 break;
9219 default:
9220 return false;
9221 }
9222 // Read the register value from the operand register Rn.
9223 uint32_t reg_val = ReadCoreReg(Rn, &success);
9224 if (!success)
9225 return false;
9226
9227 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
9228
9229 EmulateInstruction::Context context;
9230 context.type = EmulateInstruction::eContextImmediate;
9231 context.SetNoArgs();
9232
9233 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9234 res.carry_out, res.overflow);
9235 }
9236
9237 // Reverse Subtract (register) subtracts a register value from an optionally-
9238 // shifted register value, and writes the result to the destination register.
9239 // It can optionally update the condition flags based on the result.
EmulateRSBReg(const uint32_t opcode,const ARMEncoding encoding)9240 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
9241 const ARMEncoding encoding) {
9242 #if 0
9243 // ARM pseudo code...
9244 if ConditionPassed() then
9245 EncodingSpecificOperations();
9246 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9247 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
9248 if d == 15 then // Can only occur for ARM encoding
9249 ALUWritePC(result); // setflags is always FALSE here
9250 else
9251 R[d] = result;
9252 if setflags then
9253 APSR.N = result<31>;
9254 APSR.Z = IsZeroBit(result);
9255 APSR.C = carry;
9256 APSR.V = overflow;
9257 #endif
9258
9259 bool success = false;
9260
9261 uint32_t Rd; // the destination register
9262 uint32_t Rn; // the first operand
9263 uint32_t Rm; // the second operand
9264 bool setflags;
9265 ARM_ShifterType shift_t;
9266 uint32_t shift_n; // the shift applied to the value read from Rm
9267 switch (encoding) {
9268 case eEncodingT1:
9269 Rd = Bits32(opcode, 11, 8);
9270 Rn = Bits32(opcode, 19, 16);
9271 Rm = Bits32(opcode, 3, 0);
9272 setflags = BitIsSet(opcode, 20);
9273 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9274 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
9275 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9276 return false;
9277 break;
9278 case eEncodingA1:
9279 Rd = Bits32(opcode, 15, 12);
9280 Rn = Bits32(opcode, 19, 16);
9281 Rm = Bits32(opcode, 3, 0);
9282 setflags = BitIsSet(opcode, 20);
9283 shift_n = DecodeImmShiftARM(opcode, shift_t);
9284
9285 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9286 // instructions;
9287 if (Rd == 15 && setflags)
9288 return EmulateSUBSPcLrEtc(opcode, encoding);
9289 break;
9290 default:
9291 return false;
9292 }
9293 // Read the register value from register Rn.
9294 uint32_t val1 = ReadCoreReg(Rn, &success);
9295 if (!success)
9296 return false;
9297
9298 // Read the register value from register Rm.
9299 uint32_t val2 = ReadCoreReg(Rm, &success);
9300 if (!success)
9301 return false;
9302
9303 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9304 if (!success)
9305 return false;
9306 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
9307
9308 EmulateInstruction::Context context;
9309 context.type = EmulateInstruction::eContextImmediate;
9310 context.SetNoArgs();
9311 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9312 res.carry_out, res.overflow);
9313 }
9314
9315 // Reverse Subtract with Carry (immediate) subtracts a register value and the
9316 // value of NOT (Carry flag) from an immediate value, and writes the result to
9317 // the destination register. It can optionally update the condition flags based
9318 // on the result.
EmulateRSCImm(const uint32_t opcode,const ARMEncoding encoding)9319 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
9320 const ARMEncoding encoding) {
9321 #if 0
9322 // ARM pseudo code...
9323 if ConditionPassed() then
9324 EncodingSpecificOperations();
9325 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
9326 if d == 15 then
9327 ALUWritePC(result); // setflags is always FALSE here
9328 else
9329 R[d] = result;
9330 if setflags then
9331 APSR.N = result<31>;
9332 APSR.Z = IsZeroBit(result);
9333 APSR.C = carry;
9334 APSR.V = overflow;
9335 #endif
9336
9337 bool success = false;
9338
9339 uint32_t Rd; // the destination register
9340 uint32_t Rn; // the first operand
9341 bool setflags;
9342 uint32_t
9343 imm32; // the immediate value to be added to the value obtained from Rn
9344 switch (encoding) {
9345 case eEncodingA1:
9346 Rd = Bits32(opcode, 15, 12);
9347 Rn = Bits32(opcode, 19, 16);
9348 setflags = BitIsSet(opcode, 20);
9349 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9350
9351 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9352 // instructions;
9353 if (Rd == 15 && setflags)
9354 return EmulateSUBSPcLrEtc(opcode, encoding);
9355 break;
9356 default:
9357 return false;
9358 }
9359 // Read the register value from the operand register Rn.
9360 uint32_t reg_val = ReadCoreReg(Rn, &success);
9361 if (!success)
9362 return false;
9363
9364 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
9365
9366 EmulateInstruction::Context context;
9367 context.type = EmulateInstruction::eContextImmediate;
9368 context.SetNoArgs();
9369
9370 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9371 res.carry_out, res.overflow);
9372 }
9373
9374 // Reverse Subtract with Carry (register) subtracts a register value and the
9375 // value of NOT (Carry flag) from an optionally-shifted register value, and
9376 // writes the result to the destination register. It can optionally update the
9377 // condition flags based on the result.
EmulateRSCReg(const uint32_t opcode,const ARMEncoding encoding)9378 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
9379 const ARMEncoding encoding) {
9380 #if 0
9381 // ARM pseudo code...
9382 if ConditionPassed() then
9383 EncodingSpecificOperations();
9384 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9385 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
9386 if d == 15 then
9387 ALUWritePC(result); // setflags is always FALSE here
9388 else
9389 R[d] = result;
9390 if setflags then
9391 APSR.N = result<31>;
9392 APSR.Z = IsZeroBit(result);
9393 APSR.C = carry;
9394 APSR.V = overflow;
9395 #endif
9396
9397 bool success = false;
9398
9399 uint32_t Rd; // the destination register
9400 uint32_t Rn; // the first operand
9401 uint32_t Rm; // the second operand
9402 bool setflags;
9403 ARM_ShifterType shift_t;
9404 uint32_t shift_n; // the shift applied to the value read from Rm
9405 switch (encoding) {
9406 case eEncodingA1:
9407 Rd = Bits32(opcode, 15, 12);
9408 Rn = Bits32(opcode, 19, 16);
9409 Rm = Bits32(opcode, 3, 0);
9410 setflags = BitIsSet(opcode, 20);
9411 shift_n = DecodeImmShiftARM(opcode, shift_t);
9412
9413 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9414 // instructions;
9415 if (Rd == 15 && setflags)
9416 return EmulateSUBSPcLrEtc(opcode, encoding);
9417 break;
9418 default:
9419 return false;
9420 }
9421 // Read the register value from register Rn.
9422 uint32_t val1 = ReadCoreReg(Rn, &success);
9423 if (!success)
9424 return false;
9425
9426 // Read the register value from register Rm.
9427 uint32_t val2 = ReadCoreReg(Rm, &success);
9428 if (!success)
9429 return false;
9430
9431 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9432 if (!success)
9433 return false;
9434 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
9435
9436 EmulateInstruction::Context context;
9437 context.type = EmulateInstruction::eContextImmediate;
9438 context.SetNoArgs();
9439 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9440 res.carry_out, res.overflow);
9441 }
9442
9443 // Subtract with Carry (immediate) subtracts an immediate value and the value
9444 // of
9445 // NOT (Carry flag) from a register value, and writes the result to the
9446 // destination register.
9447 // It can optionally update the condition flags based on the result.
EmulateSBCImm(const uint32_t opcode,const ARMEncoding encoding)9448 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
9449 const ARMEncoding encoding) {
9450 #if 0
9451 // ARM pseudo code...
9452 if ConditionPassed() then
9453 EncodingSpecificOperations();
9454 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
9455 if d == 15 then // Can only occur for ARM encoding
9456 ALUWritePC(result); // setflags is always FALSE here
9457 else
9458 R[d] = result;
9459 if setflags then
9460 APSR.N = result<31>;
9461 APSR.Z = IsZeroBit(result);
9462 APSR.C = carry;
9463 APSR.V = overflow;
9464 #endif
9465
9466 bool success = false;
9467
9468 uint32_t Rd; // the destination register
9469 uint32_t Rn; // the first operand
9470 bool setflags;
9471 uint32_t
9472 imm32; // the immediate value to be added to the value obtained from Rn
9473 switch (encoding) {
9474 case eEncodingT1:
9475 Rd = Bits32(opcode, 11, 8);
9476 Rn = Bits32(opcode, 19, 16);
9477 setflags = BitIsSet(opcode, 20);
9478 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9479 if (BadReg(Rd) || BadReg(Rn))
9480 return false;
9481 break;
9482 case eEncodingA1:
9483 Rd = Bits32(opcode, 15, 12);
9484 Rn = Bits32(opcode, 19, 16);
9485 setflags = BitIsSet(opcode, 20);
9486 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9487
9488 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9489 // instructions;
9490 if (Rd == 15 && setflags)
9491 return EmulateSUBSPcLrEtc(opcode, encoding);
9492 break;
9493 default:
9494 return false;
9495 }
9496 // Read the register value from the operand register Rn.
9497 uint32_t reg_val = ReadCoreReg(Rn, &success);
9498 if (!success)
9499 return false;
9500
9501 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9502
9503 EmulateInstruction::Context context;
9504 context.type = EmulateInstruction::eContextImmediate;
9505 context.SetNoArgs();
9506
9507 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9508 res.carry_out, res.overflow);
9509 }
9510
9511 // Subtract with Carry (register) subtracts an optionally-shifted register
9512 // value and the value of
9513 // NOT (Carry flag) from a register value, and writes the result to the
9514 // destination register.
9515 // It can optionally update the condition flags based on the result.
EmulateSBCReg(const uint32_t opcode,const ARMEncoding encoding)9516 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
9517 const ARMEncoding encoding) {
9518 #if 0
9519 // ARM pseudo code...
9520 if ConditionPassed() then
9521 EncodingSpecificOperations();
9522 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9523 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9524 if d == 15 then // Can only occur for ARM encoding
9525 ALUWritePC(result); // setflags is always FALSE here
9526 else
9527 R[d] = result;
9528 if setflags then
9529 APSR.N = result<31>;
9530 APSR.Z = IsZeroBit(result);
9531 APSR.C = carry;
9532 APSR.V = overflow;
9533 #endif
9534
9535 bool success = false;
9536
9537 uint32_t Rd; // the destination register
9538 uint32_t Rn; // the first operand
9539 uint32_t Rm; // the second operand
9540 bool setflags;
9541 ARM_ShifterType shift_t;
9542 uint32_t shift_n; // the shift applied to the value read from Rm
9543 switch (encoding) {
9544 case eEncodingT1:
9545 Rd = Rn = Bits32(opcode, 2, 0);
9546 Rm = Bits32(opcode, 5, 3);
9547 setflags = !InITBlock();
9548 shift_t = SRType_LSL;
9549 shift_n = 0;
9550 break;
9551 case eEncodingT2:
9552 Rd = Bits32(opcode, 11, 8);
9553 Rn = Bits32(opcode, 19, 16);
9554 Rm = Bits32(opcode, 3, 0);
9555 setflags = BitIsSet(opcode, 20);
9556 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9557 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9558 return false;
9559 break;
9560 case eEncodingA1:
9561 Rd = Bits32(opcode, 15, 12);
9562 Rn = Bits32(opcode, 19, 16);
9563 Rm = Bits32(opcode, 3, 0);
9564 setflags = BitIsSet(opcode, 20);
9565 shift_n = DecodeImmShiftARM(opcode, shift_t);
9566
9567 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9568 // instructions;
9569 if (Rd == 15 && setflags)
9570 return EmulateSUBSPcLrEtc(opcode, encoding);
9571 break;
9572 default:
9573 return false;
9574 }
9575 // Read the register value from register Rn.
9576 uint32_t val1 = ReadCoreReg(Rn, &success);
9577 if (!success)
9578 return false;
9579
9580 // Read the register value from register Rm.
9581 uint32_t val2 = ReadCoreReg(Rm, &success);
9582 if (!success)
9583 return false;
9584
9585 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9586 if (!success)
9587 return false;
9588 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9589
9590 EmulateInstruction::Context context;
9591 context.type = EmulateInstruction::eContextImmediate;
9592 context.SetNoArgs();
9593 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9594 res.carry_out, res.overflow);
9595 }
9596
9597 // This instruction subtracts an immediate value from a register value, and
9598 // writes the result to the destination register. It can optionally update the
9599 // condition flags based on the result.
EmulateSUBImmThumb(const uint32_t opcode,const ARMEncoding encoding)9600 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
9601 const ARMEncoding encoding) {
9602 #if 0
9603 // ARM pseudo code...
9604 if ConditionPassed() then
9605 EncodingSpecificOperations();
9606 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9607 R[d] = result;
9608 if setflags then
9609 APSR.N = result<31>;
9610 APSR.Z = IsZeroBit(result);
9611 APSR.C = carry;
9612 APSR.V = overflow;
9613 #endif
9614
9615 bool success = false;
9616
9617 uint32_t Rd; // the destination register
9618 uint32_t Rn; // the first operand
9619 bool setflags;
9620 uint32_t imm32; // the immediate value to be subtracted from the value
9621 // obtained from Rn
9622 switch (encoding) {
9623 case eEncodingT1:
9624 Rd = Bits32(opcode, 2, 0);
9625 Rn = Bits32(opcode, 5, 3);
9626 setflags = !InITBlock();
9627 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9628 break;
9629 case eEncodingT2:
9630 Rd = Rn = Bits32(opcode, 10, 8);
9631 setflags = !InITBlock();
9632 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9633 break;
9634 case eEncodingT3:
9635 Rd = Bits32(opcode, 11, 8);
9636 Rn = Bits32(opcode, 19, 16);
9637 setflags = BitIsSet(opcode, 20);
9638 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9639
9640 // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9641 if (Rd == 15 && setflags)
9642 return EmulateCMPImm(opcode, eEncodingT2);
9643
9644 // if Rn == '1101' then SEE SUB (SP minus immediate);
9645 if (Rn == 13)
9646 return EmulateSUBSPImm(opcode, eEncodingT2);
9647
9648 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9649 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9650 return false;
9651 break;
9652 case eEncodingT4:
9653 Rd = Bits32(opcode, 11, 8);
9654 Rn = Bits32(opcode, 19, 16);
9655 setflags = BitIsSet(opcode, 20);
9656 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9657
9658 // if Rn == '1111' then SEE ADR;
9659 if (Rn == 15)
9660 return EmulateADR(opcode, eEncodingT2);
9661
9662 // if Rn == '1101' then SEE SUB (SP minus immediate);
9663 if (Rn == 13)
9664 return EmulateSUBSPImm(opcode, eEncodingT3);
9665
9666 if (BadReg(Rd))
9667 return false;
9668 break;
9669 default:
9670 return false;
9671 }
9672 // Read the register value from the operand register Rn.
9673 uint32_t reg_val = ReadCoreReg(Rn, &success);
9674 if (!success)
9675 return false;
9676
9677 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9678
9679 EmulateInstruction::Context context;
9680 context.type = EmulateInstruction::eContextImmediate;
9681 context.SetNoArgs();
9682
9683 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9684 res.carry_out, res.overflow);
9685 }
9686
9687 // This instruction subtracts an immediate value from a register value, and
9688 // writes the result to the destination register. It can optionally update the
9689 // condition flags based on the result.
EmulateSUBImmARM(const uint32_t opcode,const ARMEncoding encoding)9690 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
9691 const ARMEncoding encoding) {
9692 #if 0
9693 // ARM pseudo code...
9694 if ConditionPassed() then
9695 EncodingSpecificOperations();
9696 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9697 if d == 15 then
9698 ALUWritePC(result); // setflags is always FALSE here
9699 else
9700 R[d] = result;
9701 if setflags then
9702 APSR.N = result<31>;
9703 APSR.Z = IsZeroBit(result);
9704 APSR.C = carry;
9705 APSR.V = overflow;
9706 #endif
9707
9708 bool success = false;
9709
9710 if (ConditionPassed(opcode)) {
9711 uint32_t Rd; // the destination register
9712 uint32_t Rn; // the first operand
9713 bool setflags;
9714 uint32_t imm32; // the immediate value to be subtracted from the value
9715 // obtained from Rn
9716 switch (encoding) {
9717 case eEncodingA1:
9718 Rd = Bits32(opcode, 15, 12);
9719 Rn = Bits32(opcode, 19, 16);
9720 setflags = BitIsSet(opcode, 20);
9721 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9722
9723 // if Rn == '1111' && S == '0' then SEE ADR;
9724 if (Rn == 15 && !setflags)
9725 return EmulateADR(opcode, eEncodingA2);
9726
9727 // if Rn == '1101' then SEE SUB (SP minus immediate);
9728 if (Rn == 13)
9729 return EmulateSUBSPImm(opcode, eEncodingA1);
9730
9731 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9732 // instructions;
9733 if (Rd == 15 && setflags)
9734 return EmulateSUBSPcLrEtc(opcode, encoding);
9735 break;
9736 default:
9737 return false;
9738 }
9739 // Read the register value from the operand register Rn.
9740 uint32_t reg_val = ReadCoreReg(Rn, &success);
9741 if (!success)
9742 return false;
9743
9744 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9745
9746 EmulateInstruction::Context context;
9747 if (Rd == 13)
9748 context.type = EmulateInstruction::eContextAdjustStackPointer;
9749 else
9750 context.type = EmulateInstruction::eContextRegisterPlusOffset;
9751
9752 RegisterInfo dwarf_reg;
9753 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
9754 int64_t imm32_signed = imm32;
9755 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed);
9756
9757 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9758 res.carry_out, res.overflow))
9759 return false;
9760 }
9761 return true;
9762 }
9763
9764 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
9765 // register value and an immediate value. It updates the condition flags based
9766 // on the result, and discards the result.
EmulateTEQImm(const uint32_t opcode,const ARMEncoding encoding)9767 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
9768 const ARMEncoding encoding) {
9769 #if 0
9770 // ARM pseudo code...
9771 if ConditionPassed() then
9772 EncodingSpecificOperations();
9773 result = R[n] EOR imm32;
9774 APSR.N = result<31>;
9775 APSR.Z = IsZeroBit(result);
9776 APSR.C = carry;
9777 // APSR.V unchanged
9778 #endif
9779
9780 bool success = false;
9781
9782 if (ConditionPassed(opcode)) {
9783 uint32_t Rn;
9784 uint32_t
9785 imm32; // the immediate value to be ANDed to the value obtained from Rn
9786 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9787 switch (encoding) {
9788 case eEncodingT1:
9789 Rn = Bits32(opcode, 19, 16);
9790 imm32 = ThumbExpandImm_C(
9791 opcode, APSR_C,
9792 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9793 if (BadReg(Rn))
9794 return false;
9795 break;
9796 case eEncodingA1:
9797 Rn = Bits32(opcode, 19, 16);
9798 imm32 =
9799 ARMExpandImm_C(opcode, APSR_C,
9800 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9801 break;
9802 default:
9803 return false;
9804 }
9805
9806 // Read the first operand.
9807 uint32_t val1 = ReadCoreReg(Rn, &success);
9808 if (!success)
9809 return false;
9810
9811 uint32_t result = val1 ^ imm32;
9812
9813 EmulateInstruction::Context context;
9814 context.type = EmulateInstruction::eContextImmediate;
9815 context.SetNoArgs();
9816
9817 if (!WriteFlags(context, result, carry))
9818 return false;
9819 }
9820 return true;
9821 }
9822
9823 // Test Equivalence (register) performs a bitwise exclusive OR operation on a
9824 // register value and an optionally-shifted register value. It updates the
9825 // condition flags based on the result, and discards the result.
EmulateTEQReg(const uint32_t opcode,const ARMEncoding encoding)9826 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
9827 const ARMEncoding encoding) {
9828 #if 0
9829 // ARM pseudo code...
9830 if ConditionPassed() then
9831 EncodingSpecificOperations();
9832 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9833 result = R[n] EOR shifted;
9834 APSR.N = result<31>;
9835 APSR.Z = IsZeroBit(result);
9836 APSR.C = carry;
9837 // APSR.V unchanged
9838 #endif
9839
9840 bool success = false;
9841
9842 if (ConditionPassed(opcode)) {
9843 uint32_t Rn, Rm;
9844 ARM_ShifterType shift_t;
9845 uint32_t shift_n; // the shift applied to the value read from Rm
9846 uint32_t carry;
9847 switch (encoding) {
9848 case eEncodingT1:
9849 Rn = Bits32(opcode, 19, 16);
9850 Rm = Bits32(opcode, 3, 0);
9851 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9852 if (BadReg(Rn) || BadReg(Rm))
9853 return false;
9854 break;
9855 case eEncodingA1:
9856 Rn = Bits32(opcode, 19, 16);
9857 Rm = Bits32(opcode, 3, 0);
9858 shift_n = DecodeImmShiftARM(opcode, shift_t);
9859 break;
9860 default:
9861 return false;
9862 }
9863
9864 // Read the first operand.
9865 uint32_t val1 = ReadCoreReg(Rn, &success);
9866 if (!success)
9867 return false;
9868
9869 // Read the second operand.
9870 uint32_t val2 = ReadCoreReg(Rm, &success);
9871 if (!success)
9872 return false;
9873
9874 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9875 if (!success)
9876 return false;
9877 uint32_t result = val1 ^ shifted;
9878
9879 EmulateInstruction::Context context;
9880 context.type = EmulateInstruction::eContextImmediate;
9881 context.SetNoArgs();
9882
9883 if (!WriteFlags(context, result, carry))
9884 return false;
9885 }
9886 return true;
9887 }
9888
9889 // Test (immediate) performs a bitwise AND operation on a register value and an
9890 // immediate value. It updates the condition flags based on the result, and
9891 // discards the result.
EmulateTSTImm(const uint32_t opcode,const ARMEncoding encoding)9892 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
9893 const ARMEncoding encoding) {
9894 #if 0
9895 // ARM pseudo code...
9896 if ConditionPassed() then
9897 EncodingSpecificOperations();
9898 result = R[n] AND imm32;
9899 APSR.N = result<31>;
9900 APSR.Z = IsZeroBit(result);
9901 APSR.C = carry;
9902 // APSR.V unchanged
9903 #endif
9904
9905 bool success = false;
9906
9907 if (ConditionPassed(opcode)) {
9908 uint32_t Rn;
9909 uint32_t
9910 imm32; // the immediate value to be ANDed to the value obtained from Rn
9911 uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9912 switch (encoding) {
9913 case eEncodingT1:
9914 Rn = Bits32(opcode, 19, 16);
9915 imm32 = ThumbExpandImm_C(
9916 opcode, APSR_C,
9917 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9918 if (BadReg(Rn))
9919 return false;
9920 break;
9921 case eEncodingA1:
9922 Rn = Bits32(opcode, 19, 16);
9923 imm32 =
9924 ARMExpandImm_C(opcode, APSR_C,
9925 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9926 break;
9927 default:
9928 return false;
9929 }
9930
9931 // Read the first operand.
9932 uint32_t val1 = ReadCoreReg(Rn, &success);
9933 if (!success)
9934 return false;
9935
9936 uint32_t result = val1 & imm32;
9937
9938 EmulateInstruction::Context context;
9939 context.type = EmulateInstruction::eContextImmediate;
9940 context.SetNoArgs();
9941
9942 if (!WriteFlags(context, result, carry))
9943 return false;
9944 }
9945 return true;
9946 }
9947
9948 // Test (register) performs a bitwise AND operation on a register value and an
9949 // optionally-shifted register value. It updates the condition flags based on
9950 // the result, and discards the result.
EmulateTSTReg(const uint32_t opcode,const ARMEncoding encoding)9951 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
9952 const ARMEncoding encoding) {
9953 #if 0
9954 // ARM pseudo code...
9955 if ConditionPassed() then
9956 EncodingSpecificOperations();
9957 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9958 result = R[n] AND shifted;
9959 APSR.N = result<31>;
9960 APSR.Z = IsZeroBit(result);
9961 APSR.C = carry;
9962 // APSR.V unchanged
9963 #endif
9964
9965 bool success = false;
9966
9967 if (ConditionPassed(opcode)) {
9968 uint32_t Rn, Rm;
9969 ARM_ShifterType shift_t;
9970 uint32_t shift_n; // the shift applied to the value read from Rm
9971 uint32_t carry;
9972 switch (encoding) {
9973 case eEncodingT1:
9974 Rn = Bits32(opcode, 2, 0);
9975 Rm = Bits32(opcode, 5, 3);
9976 shift_t = SRType_LSL;
9977 shift_n = 0;
9978 break;
9979 case eEncodingT2:
9980 Rn = Bits32(opcode, 19, 16);
9981 Rm = Bits32(opcode, 3, 0);
9982 shift_n = DecodeImmShiftThumb(opcode, shift_t);
9983 if (BadReg(Rn) || BadReg(Rm))
9984 return false;
9985 break;
9986 case eEncodingA1:
9987 Rn = Bits32(opcode, 19, 16);
9988 Rm = Bits32(opcode, 3, 0);
9989 shift_n = DecodeImmShiftARM(opcode, shift_t);
9990 break;
9991 default:
9992 return false;
9993 }
9994
9995 // Read the first operand.
9996 uint32_t val1 = ReadCoreReg(Rn, &success);
9997 if (!success)
9998 return false;
9999
10000 // Read the second operand.
10001 uint32_t val2 = ReadCoreReg(Rm, &success);
10002 if (!success)
10003 return false;
10004
10005 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
10006 if (!success)
10007 return false;
10008 uint32_t result = val1 & shifted;
10009
10010 EmulateInstruction::Context context;
10011 context.type = EmulateInstruction::eContextImmediate;
10012 context.SetNoArgs();
10013
10014 if (!WriteFlags(context, result, carry))
10015 return false;
10016 }
10017 return true;
10018 }
10019
10020 // A8.6.216 SUB (SP minus register)
EmulateSUBSPReg(const uint32_t opcode,const ARMEncoding encoding)10021 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
10022 const ARMEncoding encoding) {
10023 #if 0
10024 if ConditionPassed() then
10025 EncodingSpecificOperations();
10026 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10027 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10028 if d == 15 then // Can only occur for ARM encoding
10029 ALUWritePC(result); // setflags is always FALSE here
10030 else
10031 R[d] = result;
10032 if setflags then
10033 APSR.N = result<31>;
10034 APSR.Z = IsZeroBit(result);
10035 APSR.C = carry;
10036 APSR.V = overflow;
10037 #endif
10038
10039 bool success = false;
10040
10041 if (ConditionPassed(opcode)) {
10042 uint32_t d;
10043 uint32_t m;
10044 bool setflags;
10045 ARM_ShifterType shift_t;
10046 uint32_t shift_n;
10047
10048 switch (encoding) {
10049 case eEncodingT1:
10050 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10051 d = Bits32(opcode, 11, 8);
10052 m = Bits32(opcode, 3, 0);
10053 setflags = BitIsSet(opcode, 20);
10054
10055 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10056 shift_n = DecodeImmShiftThumb(opcode, shift_t);
10057
10058 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
10059 // UNPREDICTABLE;
10060 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
10061 return false;
10062
10063 // if d == 15 || BadReg(m) then UNPREDICTABLE;
10064 if ((d == 15) || BadReg(m))
10065 return false;
10066 break;
10067
10068 case eEncodingA1:
10069 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10070 d = Bits32(opcode, 15, 12);
10071 m = Bits32(opcode, 3, 0);
10072 setflags = BitIsSet(opcode, 20);
10073
10074 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10075 // instructions;
10076 if (d == 15 && setflags)
10077 EmulateSUBSPcLrEtc(opcode, encoding);
10078
10079 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10080 shift_n = DecodeImmShiftARM(opcode, shift_t);
10081 break;
10082
10083 default:
10084 return false;
10085 }
10086
10087 // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10088 uint32_t Rm = ReadCoreReg(m, &success);
10089 if (!success)
10090 return false;
10091
10092 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10093 if (!success)
10094 return false;
10095
10096 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10097 uint32_t sp_val = ReadCoreReg(SP_REG, &success);
10098 if (!success)
10099 return false;
10100
10101 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
10102
10103 EmulateInstruction::Context context;
10104 context.type = eContextArithmetic;
10105 RegisterInfo sp_reg;
10106 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
10107 RegisterInfo dwarf_reg;
10108 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
10109 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg);
10110
10111 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10112 res.carry_out, res.overflow))
10113 return false;
10114 }
10115 return true;
10116 }
10117
10118 // A8.6.7 ADD (register-shifted register)
EmulateADDRegShift(const uint32_t opcode,const ARMEncoding encoding)10119 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
10120 const ARMEncoding encoding) {
10121 #if 0
10122 if ConditionPassed() then
10123 EncodingSpecificOperations();
10124 shift_n = UInt(R[s]<7:0>);
10125 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10126 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10127 R[d] = result;
10128 if setflags then
10129 APSR.N = result<31>;
10130 APSR.Z = IsZeroBit(result);
10131 APSR.C = carry;
10132 APSR.V = overflow;
10133 #endif
10134
10135 bool success = false;
10136
10137 if (ConditionPassed(opcode)) {
10138 uint32_t d;
10139 uint32_t n;
10140 uint32_t m;
10141 uint32_t s;
10142 bool setflags;
10143 ARM_ShifterType shift_t;
10144
10145 switch (encoding) {
10146 case eEncodingA1:
10147 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
10148 d = Bits32(opcode, 15, 12);
10149 n = Bits32(opcode, 19, 16);
10150 m = Bits32(opcode, 3, 0);
10151 s = Bits32(opcode, 11, 8);
10152
10153 // setflags = (S == '1'); shift_t = DecodeRegShift(type);
10154 setflags = BitIsSet(opcode, 20);
10155 shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
10156
10157 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
10158 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
10159 return false;
10160 break;
10161
10162 default:
10163 return false;
10164 }
10165
10166 // shift_n = UInt(R[s]<7:0>);
10167 uint32_t Rs = ReadCoreReg(s, &success);
10168 if (!success)
10169 return false;
10170
10171 uint32_t shift_n = Bits32(Rs, 7, 0);
10172
10173 // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10174 uint32_t Rm = ReadCoreReg(m, &success);
10175 if (!success)
10176 return false;
10177
10178 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10179 if (!success)
10180 return false;
10181
10182 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10183 uint32_t Rn = ReadCoreReg(n, &success);
10184 if (!success)
10185 return false;
10186
10187 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
10188
10189 // R[d] = result;
10190 EmulateInstruction::Context context;
10191 context.type = eContextArithmetic;
10192 RegisterInfo reg_n;
10193 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10194 RegisterInfo reg_m;
10195 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10196
10197 context.SetRegisterRegisterOperands(reg_n, reg_m);
10198
10199 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
10200 res.result))
10201 return false;
10202
10203 // if setflags then
10204 // APSR.N = result<31>;
10205 // APSR.Z = IsZeroBit(result);
10206 // APSR.C = carry;
10207 // APSR.V = overflow;
10208 if (setflags)
10209 return WriteFlags(context, res.result, res.carry_out, res.overflow);
10210 }
10211 return true;
10212 }
10213
10214 // A8.6.213 SUB (register)
EmulateSUBReg(const uint32_t opcode,const ARMEncoding encoding)10215 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
10216 const ARMEncoding encoding) {
10217 #if 0
10218 if ConditionPassed() then
10219 EncodingSpecificOperations();
10220 shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10221 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10222 if d == 15 then // Can only occur for ARM encoding
10223 ALUWritePC(result); // setflags is always FALSE here
10224 else
10225 R[d] = result;
10226 if setflags then
10227 APSR.N = result<31>;
10228 APSR.Z = IsZeroBit(result);
10229 APSR.C = carry;
10230 APSR.V = overflow;
10231 #endif
10232
10233 bool success = false;
10234
10235 if (ConditionPassed(opcode)) {
10236 uint32_t d;
10237 uint32_t n;
10238 uint32_t m;
10239 bool setflags;
10240 ARM_ShifterType shift_t;
10241 uint32_t shift_n;
10242
10243 switch (encoding) {
10244 case eEncodingT1:
10245 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
10246 d = Bits32(opcode, 2, 0);
10247 n = Bits32(opcode, 5, 3);
10248 m = Bits32(opcode, 8, 6);
10249 setflags = !InITBlock();
10250
10251 // (shift_t, shift_n) = (SRType_LSL, 0);
10252 shift_t = SRType_LSL;
10253 shift_n = 0;
10254
10255 break;
10256
10257 case eEncodingT2:
10258 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
10259 d = Bits32(opcode, 11, 8);
10260 n = Bits32(opcode, 19, 16);
10261 m = Bits32(opcode, 3, 0);
10262 setflags = BitIsSet(opcode, 20);
10263
10264 // if Rd == "1111" && S == "1" then SEE CMP (register);
10265 if (d == 15 && setflags == 1)
10266 return EmulateCMPImm(opcode, eEncodingT3);
10267
10268 // if Rn == "1101" then SEE SUB (SP minus register);
10269 if (n == 13)
10270 return EmulateSUBSPReg(opcode, eEncodingT1);
10271
10272 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10273 shift_n = DecodeImmShiftThumb(opcode, shift_t);
10274
10275 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
10276 // UNPREDICTABLE;
10277 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
10278 BadReg(m))
10279 return false;
10280
10281 break;
10282
10283 case eEncodingA1:
10284 // if Rn == '1101' then SEE SUB (SP minus register);
10285 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
10286 d = Bits32(opcode, 15, 12);
10287 n = Bits32(opcode, 19, 16);
10288 m = Bits32(opcode, 3, 0);
10289 setflags = BitIsSet(opcode, 20);
10290
10291 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10292 // instructions;
10293 if ((d == 15) && setflags)
10294 EmulateSUBSPcLrEtc(opcode, encoding);
10295
10296 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10297 shift_n = DecodeImmShiftARM(opcode, shift_t);
10298
10299 break;
10300
10301 default:
10302 return false;
10303 }
10304
10305 // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10306 uint32_t Rm = ReadCoreReg(m, &success);
10307 if (!success)
10308 return false;
10309
10310 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10311 if (!success)
10312 return false;
10313
10314 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10315 uint32_t Rn = ReadCoreReg(n, &success);
10316 if (!success)
10317 return false;
10318
10319 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
10320
10321 // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result);
10322 // // setflags is always FALSE here else
10323 // R[d] = result;
10324 // if setflags then
10325 // APSR.N = result<31>;
10326 // APSR.Z = IsZeroBit(result);
10327 // APSR.C = carry;
10328 // APSR.V = overflow;
10329
10330 EmulateInstruction::Context context;
10331 context.type = eContextArithmetic;
10332 RegisterInfo reg_n;
10333 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10334 RegisterInfo reg_m;
10335 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10336 context.SetRegisterRegisterOperands(reg_n, reg_m);
10337
10338 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10339 res.carry_out, res.overflow))
10340 return false;
10341 }
10342 return true;
10343 }
10344
10345 // A8.6.202 STREX
10346 // Store Register Exclusive calculates an address from a base register value
10347 // and an immediate offset, and stores a word from a register to memory if the
10348 // executing processor has exclusive access to the memory addressed.
EmulateSTREX(const uint32_t opcode,const ARMEncoding encoding)10349 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
10350 const ARMEncoding encoding) {
10351 #if 0
10352 if ConditionPassed() then
10353 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10354 address = R[n] + imm32;
10355 if ExclusiveMonitorsPass(address,4) then
10356 MemA[address,4] = R[t];
10357 R[d] = 0;
10358 else
10359 R[d] = 1;
10360 #endif
10361
10362 bool success = false;
10363
10364 if (ConditionPassed(opcode)) {
10365 uint32_t d;
10366 uint32_t t;
10367 uint32_t n;
10368 uint32_t imm32;
10369 const uint32_t addr_byte_size = GetAddressByteSize();
10370
10371 switch (encoding) {
10372 case eEncodingT1:
10373 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 =
10374 // ZeroExtend(imm8:'00',
10375 // 32);
10376 d = Bits32(opcode, 11, 8);
10377 t = Bits32(opcode, 15, 12);
10378 n = Bits32(opcode, 19, 16);
10379 imm32 = Bits32(opcode, 7, 0) << 2;
10380
10381 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
10382 if (BadReg(d) || BadReg(t) || (n == 15))
10383 return false;
10384
10385 // if d == n || d == t then UNPREDICTABLE;
10386 if ((d == n) || (d == t))
10387 return false;
10388
10389 break;
10390
10391 case eEncodingA1:
10392 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
10393 // offset
10394 d = Bits32(opcode, 15, 12);
10395 t = Bits32(opcode, 3, 0);
10396 n = Bits32(opcode, 19, 16);
10397 imm32 = 0;
10398
10399 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
10400 if ((d == 15) || (t == 15) || (n == 15))
10401 return false;
10402
10403 // if d == n || d == t then UNPREDICTABLE;
10404 if ((d == n) || (d == t))
10405 return false;
10406
10407 break;
10408
10409 default:
10410 return false;
10411 }
10412
10413 // address = R[n] + imm32;
10414 uint32_t Rn = ReadCoreReg(n, &success);
10415 if (!success)
10416 return false;
10417
10418 addr_t address = Rn + imm32;
10419
10420 RegisterInfo base_reg;
10421 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10422 RegisterInfo data_reg;
10423 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10424 EmulateInstruction::Context context;
10425 context.type = eContextRegisterStore;
10426 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32);
10427
10428 // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass
10429 // (address, addr_byte_size)) -- For now, for the sake of emulation, we
10430 // will say this
10431 // always return
10432 // true.
10433 if (true) {
10434 // MemA[address,4] = R[t];
10435 uint32_t Rt =
10436 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
10437 if (!success)
10438 return false;
10439
10440 if (!MemAWrite(context, address, Rt, addr_byte_size))
10441 return false;
10442
10443 // R[d] = 0;
10444 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
10445 return false;
10446 }
10447 #if 0 // unreachable because if true
10448 else
10449 {
10450 // R[d] = 1;
10451 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
10452 return false;
10453 }
10454 #endif // unreachable because if true
10455 }
10456 return true;
10457 }
10458
10459 // A8.6.197 STRB (immediate, ARM)
EmulateSTRBImmARM(const uint32_t opcode,const ARMEncoding encoding)10460 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
10461 const ARMEncoding encoding) {
10462 #if 0
10463 if ConditionPassed() then
10464 EncodingSpecificOperations();
10465 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10466 address = if index then offset_addr else R[n];
10467 MemU[address,1] = R[t]<7:0>;
10468 if wback then R[n] = offset_addr;
10469 #endif
10470
10471 bool success = false;
10472
10473 if (ConditionPassed(opcode)) {
10474 uint32_t t;
10475 uint32_t n;
10476 uint32_t imm32;
10477 bool index;
10478 bool add;
10479 bool wback;
10480
10481 switch (encoding) {
10482 case eEncodingA1:
10483 // if P == '0' && W == '1' then SEE STRBT;
10484 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10485 t = Bits32(opcode, 15, 12);
10486 n = Bits32(opcode, 19, 16);
10487 imm32 = Bits32(opcode, 11, 0);
10488
10489 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10490 index = BitIsSet(opcode, 24);
10491 add = BitIsSet(opcode, 23);
10492 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10493
10494 // if t == 15 then UNPREDICTABLE;
10495 if (t == 15)
10496 return false;
10497
10498 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10499 if (wback && ((n == 15) || (n == t)))
10500 return false;
10501
10502 break;
10503
10504 default:
10505 return false;
10506 }
10507
10508 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10509 uint32_t Rn = ReadCoreReg(n, &success);
10510 if (!success)
10511 return false;
10512
10513 addr_t offset_addr;
10514 if (add)
10515 offset_addr = Rn + imm32;
10516 else
10517 offset_addr = Rn - imm32;
10518
10519 // address = if index then offset_addr else R[n];
10520 addr_t address;
10521 if (index)
10522 address = offset_addr;
10523 else
10524 address = Rn;
10525
10526 // MemU[address,1] = R[t]<7:0>;
10527 uint32_t Rt = ReadCoreReg(t, &success);
10528 if (!success)
10529 return false;
10530
10531 RegisterInfo base_reg;
10532 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10533 RegisterInfo data_reg;
10534 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10535 EmulateInstruction::Context context;
10536 context.type = eContextRegisterStore;
10537 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10538
10539 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
10540 return false;
10541
10542 // if wback then R[n] = offset_addr;
10543 if (wback) {
10544 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10545 offset_addr))
10546 return false;
10547 }
10548 }
10549 return true;
10550 }
10551
10552 // A8.6.194 STR (immediate, ARM)
EmulateSTRImmARM(const uint32_t opcode,const ARMEncoding encoding)10553 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
10554 const ARMEncoding encoding) {
10555 #if 0
10556 if ConditionPassed() then
10557 EncodingSpecificOperations();
10558 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10559 address = if index then offset_addr else R[n];
10560 MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10561 if wback then R[n] = offset_addr;
10562 #endif
10563
10564 bool success = false;
10565
10566 if (ConditionPassed(opcode)) {
10567 uint32_t t;
10568 uint32_t n;
10569 uint32_t imm32;
10570 bool index;
10571 bool add;
10572 bool wback;
10573
10574 const uint32_t addr_byte_size = GetAddressByteSize();
10575
10576 switch (encoding) {
10577 case eEncodingA1:
10578 // if P == '0' && W == '1' then SEE STRT;
10579 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
10580 // '000000000100' then SEE PUSH;
10581 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10582 t = Bits32(opcode, 15, 12);
10583 n = Bits32(opcode, 19, 16);
10584 imm32 = Bits32(opcode, 11, 0);
10585
10586 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10587 index = BitIsSet(opcode, 24);
10588 add = BitIsSet(opcode, 23);
10589 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10590
10591 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10592 if (wback && ((n == 15) || (n == t)))
10593 return false;
10594
10595 break;
10596
10597 default:
10598 return false;
10599 }
10600
10601 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10602 uint32_t Rn = ReadCoreReg(n, &success);
10603 if (!success)
10604 return false;
10605
10606 addr_t offset_addr;
10607 if (add)
10608 offset_addr = Rn + imm32;
10609 else
10610 offset_addr = Rn - imm32;
10611
10612 // address = if index then offset_addr else R[n];
10613 addr_t address;
10614 if (index)
10615 address = offset_addr;
10616 else
10617 address = Rn;
10618
10619 RegisterInfo base_reg;
10620 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10621 RegisterInfo data_reg;
10622 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10623 EmulateInstruction::Context context;
10624 context.type = eContextRegisterStore;
10625 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10626
10627 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10628 uint32_t Rt = ReadCoreReg(t, &success);
10629 if (!success)
10630 return false;
10631
10632 if (t == 15) {
10633 uint32_t pc_value = ReadCoreReg(PC_REG, &success);
10634 if (!success)
10635 return false;
10636
10637 if (!MemUWrite(context, address, pc_value, addr_byte_size))
10638 return false;
10639 } else {
10640 if (!MemUWrite(context, address, Rt, addr_byte_size))
10641 return false;
10642 }
10643
10644 // if wback then R[n] = offset_addr;
10645 if (wback) {
10646 context.type = eContextAdjustBaseRegister;
10647 context.SetImmediate(offset_addr);
10648
10649 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10650 offset_addr))
10651 return false;
10652 }
10653 }
10654 return true;
10655 }
10656
10657 // A8.6.66 LDRD (immediate)
10658 // Load Register Dual (immediate) calculates an address from a base register
10659 // value and an immediate offset, loads two words from memory, and writes them
10660 // to two registers. It can use offset, post-indexed, or pre-indexed
10661 // addressing.
EmulateLDRDImmediate(const uint32_t opcode,const ARMEncoding encoding)10662 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
10663 const ARMEncoding encoding) {
10664 #if 0
10665 if ConditionPassed() then
10666 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10667 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10668 address = if index then offset_addr else R[n];
10669 R[t] = MemA[address,4];
10670 R[t2] = MemA[address+4,4];
10671 if wback then R[n] = offset_addr;
10672 #endif
10673
10674 bool success = false;
10675
10676 if (ConditionPassed(opcode)) {
10677 uint32_t t;
10678 uint32_t t2;
10679 uint32_t n;
10680 uint32_t imm32;
10681 bool index;
10682 bool add;
10683 bool wback;
10684
10685 switch (encoding) {
10686 case eEncodingT1:
10687 // if P == '0' && W == '0' then SEE 'Related encodings';
10688 // if Rn == '1111' then SEE LDRD (literal);
10689 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10690 // ZeroExtend(imm8:'00', 32);
10691 t = Bits32(opcode, 15, 12);
10692 t2 = Bits32(opcode, 11, 8);
10693 n = Bits32(opcode, 19, 16);
10694 imm32 = Bits32(opcode, 7, 0) << 2;
10695
10696 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10697 index = BitIsSet(opcode, 24);
10698 add = BitIsSet(opcode, 23);
10699 wback = BitIsSet(opcode, 21);
10700
10701 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10702 if (wback && ((n == t) || (n == t2)))
10703 return false;
10704
10705 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10706 if (BadReg(t) || BadReg(t2) || (t == t2))
10707 return false;
10708
10709 break;
10710
10711 case eEncodingA1:
10712 // if Rn == '1111' then SEE LDRD (literal);
10713 // if Rt<0> == '1' then UNPREDICTABLE;
10714 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10715 // 32);
10716 t = Bits32(opcode, 15, 12);
10717 if (BitIsSet(t, 0))
10718 return false;
10719 t2 = t + 1;
10720 n = Bits32(opcode, 19, 16);
10721 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10722
10723 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10724 index = BitIsSet(opcode, 24);
10725 add = BitIsSet(opcode, 23);
10726 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10727
10728 // if P == '0' && W == '1' then UNPREDICTABLE;
10729 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10730 return false;
10731
10732 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10733 if (wback && ((n == t) || (n == t2)))
10734 return false;
10735
10736 // if t2 == 15 then UNPREDICTABLE;
10737 if (t2 == 15)
10738 return false;
10739
10740 break;
10741
10742 default:
10743 return false;
10744 }
10745
10746 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10747 uint32_t Rn = ReadCoreReg(n, &success);
10748 if (!success)
10749 return false;
10750
10751 addr_t offset_addr;
10752 if (add)
10753 offset_addr = Rn + imm32;
10754 else
10755 offset_addr = Rn - imm32;
10756
10757 // address = if index then offset_addr else R[n];
10758 addr_t address;
10759 if (index)
10760 address = offset_addr;
10761 else
10762 address = Rn;
10763
10764 // R[t] = MemA[address,4];
10765 RegisterInfo base_reg;
10766 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10767
10768 EmulateInstruction::Context context;
10769 if (n == 13)
10770 context.type = eContextPopRegisterOffStack;
10771 else
10772 context.type = eContextRegisterLoad;
10773 context.SetAddress(address);
10774
10775 const uint32_t addr_byte_size = GetAddressByteSize();
10776 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10777 if (!success)
10778 return false;
10779
10780 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10781 return false;
10782
10783 // R[t2] = MemA[address+4,4];
10784 context.SetAddress(address + 4);
10785 data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10786 if (!success)
10787 return false;
10788
10789 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10790 data))
10791 return false;
10792
10793 // if wback then R[n] = offset_addr;
10794 if (wback) {
10795 context.type = eContextAdjustBaseRegister;
10796 context.SetAddress(offset_addr);
10797
10798 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10799 offset_addr))
10800 return false;
10801 }
10802 }
10803 return true;
10804 }
10805
10806 // A8.6.68 LDRD (register)
10807 // Load Register Dual (register) calculates an address from a base register
10808 // value and a register offset, loads two words from memory, and writes them to
10809 // two registers. It can use offset, post-indexed or pre-indexed addressing.
EmulateLDRDRegister(const uint32_t opcode,const ARMEncoding encoding)10810 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
10811 const ARMEncoding encoding) {
10812 #if 0
10813 if ConditionPassed() then
10814 EncodingSpecificOperations();
10815 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10816 address = if index then offset_addr else R[n];
10817 R[t] = MemA[address,4];
10818 R[t2] = MemA[address+4,4];
10819 if wback then R[n] = offset_addr;
10820 #endif
10821
10822 bool success = false;
10823
10824 if (ConditionPassed(opcode)) {
10825 uint32_t t;
10826 uint32_t t2;
10827 uint32_t n;
10828 uint32_t m;
10829 bool index;
10830 bool add;
10831 bool wback;
10832
10833 switch (encoding) {
10834 case eEncodingA1:
10835 // if Rt<0> == '1' then UNPREDICTABLE;
10836 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10837 t = Bits32(opcode, 15, 12);
10838 if (BitIsSet(t, 0))
10839 return false;
10840 t2 = t + 1;
10841 n = Bits32(opcode, 19, 16);
10842 m = Bits32(opcode, 3, 0);
10843
10844 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10845 index = BitIsSet(opcode, 24);
10846 add = BitIsSet(opcode, 23);
10847 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10848
10849 // if P == '0' && W == '1' then UNPREDICTABLE;
10850 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10851 return false;
10852
10853 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10854 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10855 return false;
10856
10857 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10858 if (wback && ((n == 15) || (n == t) || (n == t2)))
10859 return false;
10860
10861 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10862 if ((ArchVersion() < 6) && wback && (m == n))
10863 return false;
10864 break;
10865
10866 default:
10867 return false;
10868 }
10869
10870 uint32_t Rn = ReadCoreReg(n, &success);
10871 if (!success)
10872 return false;
10873 RegisterInfo base_reg;
10874 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10875
10876 uint32_t Rm = ReadCoreReg(m, &success);
10877 if (!success)
10878 return false;
10879 RegisterInfo offset_reg;
10880 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10881
10882 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10883 addr_t offset_addr;
10884 if (add)
10885 offset_addr = Rn + Rm;
10886 else
10887 offset_addr = Rn - Rm;
10888
10889 // address = if index then offset_addr else R[n];
10890 addr_t address;
10891 if (index)
10892 address = offset_addr;
10893 else
10894 address = Rn;
10895
10896 EmulateInstruction::Context context;
10897 if (n == 13)
10898 context.type = eContextPopRegisterOffStack;
10899 else
10900 context.type = eContextRegisterLoad;
10901 context.SetAddress(address);
10902
10903 // R[t] = MemA[address,4];
10904 const uint32_t addr_byte_size = GetAddressByteSize();
10905 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10906 if (!success)
10907 return false;
10908
10909 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10910 return false;
10911
10912 // R[t2] = MemA[address+4,4];
10913
10914 data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10915 if (!success)
10916 return false;
10917
10918 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10919 data))
10920 return false;
10921
10922 // if wback then R[n] = offset_addr;
10923 if (wback) {
10924 context.type = eContextAdjustBaseRegister;
10925 context.SetAddress(offset_addr);
10926
10927 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10928 offset_addr))
10929 return false;
10930 }
10931 }
10932 return true;
10933 }
10934
10935 // A8.6.200 STRD (immediate)
10936 // Store Register Dual (immediate) calculates an address from a base register
10937 // value and an immediate offset, and stores two words from two registers to
10938 // memory. It can use offset, post-indexed, or pre-indexed addressing.
EmulateSTRDImm(const uint32_t opcode,const ARMEncoding encoding)10939 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
10940 const ARMEncoding encoding) {
10941 #if 0
10942 if ConditionPassed() then
10943 EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10944 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10945 address = if index then offset_addr else R[n];
10946 MemA[address,4] = R[t];
10947 MemA[address+4,4] = R[t2];
10948 if wback then R[n] = offset_addr;
10949 #endif
10950
10951 bool success = false;
10952
10953 if (ConditionPassed(opcode)) {
10954 uint32_t t;
10955 uint32_t t2;
10956 uint32_t n;
10957 uint32_t imm32;
10958 bool index;
10959 bool add;
10960 bool wback;
10961
10962 switch (encoding) {
10963 case eEncodingT1:
10964 // if P == '0' && W == '0' then SEE 'Related encodings';
10965 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10966 // ZeroExtend(imm8:'00', 32);
10967 t = Bits32(opcode, 15, 12);
10968 t2 = Bits32(opcode, 11, 8);
10969 n = Bits32(opcode, 19, 16);
10970 imm32 = Bits32(opcode, 7, 0) << 2;
10971
10972 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10973 index = BitIsSet(opcode, 24);
10974 add = BitIsSet(opcode, 23);
10975 wback = BitIsSet(opcode, 21);
10976
10977 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10978 if (wback && ((n == t) || (n == t2)))
10979 return false;
10980
10981 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10982 if ((n == 15) || BadReg(t) || BadReg(t2))
10983 return false;
10984
10985 break;
10986
10987 case eEncodingA1:
10988 // if Rt<0> == '1' then UNPREDICTABLE;
10989 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10990 // 32);
10991 t = Bits32(opcode, 15, 12);
10992 if (BitIsSet(t, 0))
10993 return false;
10994
10995 t2 = t + 1;
10996 n = Bits32(opcode, 19, 16);
10997 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10998
10999 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11000 index = BitIsSet(opcode, 24);
11001 add = BitIsSet(opcode, 23);
11002 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11003
11004 // if P == '0' && W == '1' then UNPREDICTABLE;
11005 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11006 return false;
11007
11008 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11009 if (wback && ((n == 15) || (n == t) || (n == t2)))
11010 return false;
11011
11012 // if t2 == 15 then UNPREDICTABLE;
11013 if (t2 == 15)
11014 return false;
11015
11016 break;
11017
11018 default:
11019 return false;
11020 }
11021
11022 RegisterInfo base_reg;
11023 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11024
11025 uint32_t Rn = ReadCoreReg(n, &success);
11026 if (!success)
11027 return false;
11028
11029 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
11030 addr_t offset_addr;
11031 if (add)
11032 offset_addr = Rn + imm32;
11033 else
11034 offset_addr = Rn - imm32;
11035
11036 // address = if index then offset_addr else R[n];
11037 addr_t address;
11038 if (index)
11039 address = offset_addr;
11040 else
11041 address = Rn;
11042
11043 // MemA[address,4] = R[t];
11044 RegisterInfo data_reg;
11045 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11046
11047 uint32_t data = ReadCoreReg(t, &success);
11048 if (!success)
11049 return false;
11050
11051 EmulateInstruction::Context context;
11052 if (n == 13)
11053 context.type = eContextPushRegisterOnStack;
11054 else
11055 context.type = eContextRegisterStore;
11056 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11057
11058 const uint32_t addr_byte_size = GetAddressByteSize();
11059
11060 if (!MemAWrite(context, address, data, addr_byte_size))
11061 return false;
11062
11063 // MemA[address+4,4] = R[t2];
11064 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11065 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11066 (address + 4) - Rn);
11067
11068 data = ReadCoreReg(t2, &success);
11069 if (!success)
11070 return false;
11071
11072 if (!MemAWrite(context, address + 4, data, addr_byte_size))
11073 return false;
11074
11075 // if wback then R[n] = offset_addr;
11076 if (wback) {
11077 if (n == 13)
11078 context.type = eContextAdjustStackPointer;
11079 else
11080 context.type = eContextAdjustBaseRegister;
11081 context.SetAddress(offset_addr);
11082
11083 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11084 offset_addr))
11085 return false;
11086 }
11087 }
11088 return true;
11089 }
11090
11091 // A8.6.201 STRD (register)
EmulateSTRDReg(const uint32_t opcode,const ARMEncoding encoding)11092 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
11093 const ARMEncoding encoding) {
11094 #if 0
11095 if ConditionPassed() then
11096 EncodingSpecificOperations();
11097 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11098 address = if index then offset_addr else R[n];
11099 MemA[address,4] = R[t];
11100 MemA[address+4,4] = R[t2];
11101 if wback then R[n] = offset_addr;
11102 #endif
11103
11104 bool success = false;
11105
11106 if (ConditionPassed(opcode)) {
11107 uint32_t t;
11108 uint32_t t2;
11109 uint32_t n;
11110 uint32_t m;
11111 bool index;
11112 bool add;
11113 bool wback;
11114
11115 switch (encoding) {
11116 case eEncodingA1:
11117 // if Rt<0> == '1' then UNPREDICTABLE;
11118 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
11119 t = Bits32(opcode, 15, 12);
11120 if (BitIsSet(t, 0))
11121 return false;
11122
11123 t2 = t + 1;
11124 n = Bits32(opcode, 19, 16);
11125 m = Bits32(opcode, 3, 0);
11126
11127 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11128 index = BitIsSet(opcode, 24);
11129 add = BitIsSet(opcode, 23);
11130 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11131
11132 // if P == '0' && W == '1' then UNPREDICTABLE;
11133 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11134 return false;
11135
11136 // if t2 == 15 || m == 15 then UNPREDICTABLE;
11137 if ((t2 == 15) || (m == 15))
11138 return false;
11139
11140 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11141 if (wback && ((n == 15) || (n == t) || (n == t2)))
11142 return false;
11143
11144 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
11145 if ((ArchVersion() < 6) && wback && (m == n))
11146 return false;
11147
11148 break;
11149
11150 default:
11151 return false;
11152 }
11153
11154 RegisterInfo base_reg;
11155 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11156 RegisterInfo offset_reg;
11157 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
11158 RegisterInfo data_reg;
11159
11160 uint32_t Rn = ReadCoreReg(n, &success);
11161 if (!success)
11162 return false;
11163
11164 uint32_t Rm = ReadCoreReg(m, &success);
11165 if (!success)
11166 return false;
11167
11168 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11169 addr_t offset_addr;
11170 if (add)
11171 offset_addr = Rn + Rm;
11172 else
11173 offset_addr = Rn - Rm;
11174
11175 // address = if index then offset_addr else R[n];
11176 addr_t address;
11177 if (index)
11178 address = offset_addr;
11179 else
11180 address = Rn;
11181 // MemA[address,4] = R[t];
11182 uint32_t Rt = ReadCoreReg(t, &success);
11183 if (!success)
11184 return false;
11185
11186 EmulateInstruction::Context context;
11187 if (t == 13)
11188 context.type = eContextPushRegisterOnStack;
11189 else
11190 context.type = eContextRegisterStore;
11191
11192 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11193 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11194 data_reg);
11195
11196 const uint32_t addr_byte_size = GetAddressByteSize();
11197
11198 if (!MemAWrite(context, address, Rt, addr_byte_size))
11199 return false;
11200
11201 // MemA[address+4,4] = R[t2];
11202 uint32_t Rt2 = ReadCoreReg(t2, &success);
11203 if (!success)
11204 return false;
11205
11206 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11207
11208 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11209 data_reg);
11210
11211 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
11212 return false;
11213
11214 // if wback then R[n] = offset_addr;
11215 if (wback) {
11216 context.type = eContextAdjustBaseRegister;
11217 context.SetAddress(offset_addr);
11218
11219 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11220 offset_addr))
11221 return false;
11222 }
11223 }
11224 return true;
11225 }
11226
11227 // A8.6.319 VLDM
11228 // Vector Load Multiple loads multiple extension registers from consecutive
11229 // memory locations using an address from an ARM core register.
EmulateVLDM(const uint32_t opcode,const ARMEncoding encoding)11230 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
11231 const ARMEncoding encoding) {
11232 #if 0
11233 if ConditionPassed() then
11234 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11235 address = if add then R[n] else R[n]-imm32;
11236 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11237 for r = 0 to regs-1
11238 if single_regs then
11239 S[d+r] = MemA[address,4]; address = address+4;
11240 else
11241 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
11242 // Combine the word-aligned words in the correct order for
11243 // current endianness.
11244 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11245 #endif
11246
11247 bool success = false;
11248
11249 if (ConditionPassed(opcode)) {
11250 bool single_regs;
11251 bool add;
11252 bool wback;
11253 uint32_t d;
11254 uint32_t n;
11255 uint32_t imm32;
11256 uint32_t regs;
11257
11258 switch (encoding) {
11259 case eEncodingT1:
11260 case eEncodingA1:
11261 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11262 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11263 // if P == '1' && W == '0' then SEE VLDR;
11264 // if P == U && W == '1' then UNDEFINED;
11265 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11266 return false;
11267
11268 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11269 // !), 101 (DB with !)
11270 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11271 single_regs = false;
11272 add = BitIsSet(opcode, 23);
11273 wback = BitIsSet(opcode, 21);
11274
11275 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11276 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11277 n = Bits32(opcode, 19, 16);
11278 imm32 = Bits32(opcode, 7, 0) << 2;
11279
11280 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
11281 regs = Bits32(opcode, 7, 0) / 2;
11282
11283 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11284 // UNPREDICTABLE;
11285 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
11286 return false;
11287
11288 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11289 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11290 return false;
11291
11292 break;
11293
11294 case eEncodingT2:
11295 case eEncodingA2:
11296 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11297 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11298 // if P == '1' && W == '0' then SEE VLDR;
11299 // if P == U && W == '1' then UNDEFINED;
11300 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11301 return false;
11302
11303 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11304 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11305 // == '1'); d =
11306 // UInt(Vd:D); n = UInt(Rn);
11307 single_regs = true;
11308 add = BitIsSet(opcode, 23);
11309 wback = BitIsSet(opcode, 21);
11310 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11311 n = Bits32(opcode, 19, 16);
11312
11313 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11314 imm32 = Bits32(opcode, 7, 0) << 2;
11315 regs = Bits32(opcode, 7, 0);
11316
11317 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11318 // UNPREDICTABLE;
11319 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11320 return false;
11321
11322 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11323 if ((regs == 0) || ((d + regs) > 32))
11324 return false;
11325 break;
11326
11327 default:
11328 return false;
11329 }
11330
11331 RegisterInfo base_reg;
11332 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11333
11334 uint32_t Rn = ReadCoreReg(n, &success);
11335 if (!success)
11336 return false;
11337
11338 // address = if add then R[n] else R[n]-imm32;
11339 addr_t address;
11340 if (add)
11341 address = Rn;
11342 else
11343 address = Rn - imm32;
11344
11345 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11346 EmulateInstruction::Context context;
11347
11348 if (wback) {
11349 uint32_t value;
11350 if (add)
11351 value = Rn + imm32;
11352 else
11353 value = Rn - imm32;
11354
11355 context.type = eContextAdjustBaseRegister;
11356 context.SetImmediateSigned(value - Rn);
11357 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11358 value))
11359 return false;
11360 }
11361
11362 const uint32_t addr_byte_size = GetAddressByteSize();
11363 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11364
11365 context.type = eContextRegisterLoad;
11366
11367 // for r = 0 to regs-1
11368 for (uint32_t r = 0; r < regs; ++r) {
11369 if (single_regs) {
11370 // S[d+r] = MemA[address,4]; address = address+4;
11371 context.SetRegisterPlusOffset(base_reg, address - Rn);
11372
11373 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11374 if (!success)
11375 return false;
11376
11377 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11378 start_reg + d + r, data))
11379 return false;
11380
11381 address = address + 4;
11382 } else {
11383 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
11384 // address+8;
11385 context.SetRegisterPlusOffset(base_reg, address - Rn);
11386 uint32_t word1 =
11387 MemARead(context, address, addr_byte_size, 0, &success);
11388 if (!success)
11389 return false;
11390
11391 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn);
11392 uint32_t word2 =
11393 MemARead(context, address + 4, addr_byte_size, 0, &success);
11394 if (!success)
11395 return false;
11396
11397 address = address + 8;
11398 // // Combine the word-aligned words in the correct order for current
11399 // endianness.
11400 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11401 uint64_t data;
11402 if (GetByteOrder() == eByteOrderBig) {
11403 data = word1;
11404 data = (data << 32) | word2;
11405 } else {
11406 data = word2;
11407 data = (data << 32) | word1;
11408 }
11409
11410 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11411 start_reg + d + r, data))
11412 return false;
11413 }
11414 }
11415 }
11416 return true;
11417 }
11418
11419 // A8.6.399 VSTM
11420 // Vector Store Multiple stores multiple extension registers to consecutive
11421 // memory locations using an address from an
11422 // ARM core register.
EmulateVSTM(const uint32_t opcode,const ARMEncoding encoding)11423 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
11424 const ARMEncoding encoding) {
11425 #if 0
11426 if ConditionPassed() then
11427 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11428 address = if add then R[n] else R[n]-imm32;
11429 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11430 for r = 0 to regs-1
11431 if single_regs then
11432 MemA[address,4] = S[d+r]; address = address+4;
11433 else
11434 // Store as two word-aligned words in the correct order for
11435 // current endianness.
11436 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11437 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11438 address = address+8;
11439 #endif
11440
11441 bool success = false;
11442
11443 if (ConditionPassed(opcode)) {
11444 bool single_regs;
11445 bool add;
11446 bool wback;
11447 uint32_t d;
11448 uint32_t n;
11449 uint32_t imm32;
11450 uint32_t regs;
11451
11452 switch (encoding) {
11453 case eEncodingT1:
11454 case eEncodingA1:
11455 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11456 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11457 // if P == '1' && W == '0' then SEE VSTR;
11458 // if P == U && W == '1' then UNDEFINED;
11459 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11460 return false;
11461
11462 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11463 // !), 101 (DB with !)
11464 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11465 single_regs = false;
11466 add = BitIsSet(opcode, 23);
11467 wback = BitIsSet(opcode, 21);
11468
11469 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11470 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11471 n = Bits32(opcode, 19, 16);
11472 imm32 = Bits32(opcode, 7, 0) << 2;
11473
11474 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11475 regs = Bits32(opcode, 7, 0) / 2;
11476
11477 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11478 // UNPREDICTABLE;
11479 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11480 return false;
11481
11482 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11483 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11484 return false;
11485
11486 break;
11487
11488 case eEncodingT2:
11489 case eEncodingA2:
11490 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11491 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11492 // if P == '1' && W == '0' then SEE VSTR;
11493 // if P == U && W == '1' then UNDEFINED;
11494 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11495 return false;
11496
11497 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11498 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11499 // == '1'); d =
11500 // UInt(Vd:D); n = UInt(Rn);
11501 single_regs = true;
11502 add = BitIsSet(opcode, 23);
11503 wback = BitIsSet(opcode, 21);
11504 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11505 n = Bits32(opcode, 19, 16);
11506
11507 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11508 imm32 = Bits32(opcode, 7, 0) << 2;
11509 regs = Bits32(opcode, 7, 0);
11510
11511 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11512 // UNPREDICTABLE;
11513 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11514 return false;
11515
11516 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11517 if ((regs == 0) || ((d + regs) > 32))
11518 return false;
11519
11520 break;
11521
11522 default:
11523 return false;
11524 }
11525
11526 RegisterInfo base_reg;
11527 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11528
11529 uint32_t Rn = ReadCoreReg(n, &success);
11530 if (!success)
11531 return false;
11532
11533 // address = if add then R[n] else R[n]-imm32;
11534 addr_t address;
11535 if (add)
11536 address = Rn;
11537 else
11538 address = Rn - imm32;
11539
11540 EmulateInstruction::Context context;
11541 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11542 if (wback) {
11543 uint32_t value;
11544 if (add)
11545 value = Rn + imm32;
11546 else
11547 value = Rn - imm32;
11548
11549 context.type = eContextAdjustBaseRegister;
11550 context.SetRegisterPlusOffset(base_reg, value - Rn);
11551
11552 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11553 value))
11554 return false;
11555 }
11556
11557 const uint32_t addr_byte_size = GetAddressByteSize();
11558 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11559
11560 context.type = eContextRegisterStore;
11561 // for r = 0 to regs-1
11562 for (uint32_t r = 0; r < regs; ++r) {
11563
11564 if (single_regs) {
11565 // MemA[address,4] = S[d+r]; address = address+4;
11566 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11567 start_reg + d + r, 0, &success);
11568 if (!success)
11569 return false;
11570
11571 RegisterInfo data_reg;
11572 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11573 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11574 address - Rn);
11575 if (!MemAWrite(context, address, data, addr_byte_size))
11576 return false;
11577
11578 address = address + 4;
11579 } else {
11580 // // Store as two word-aligned words in the correct order for current
11581 // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
11582 // D[d+r]<31:0>;
11583 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
11584 // D[d+r]<63:32>;
11585 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11586 start_reg + d + r, 0, &success);
11587 if (!success)
11588 return false;
11589
11590 RegisterInfo data_reg;
11591 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11592
11593 if (GetByteOrder() == eByteOrderBig) {
11594 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11595 address - Rn);
11596 if (!MemAWrite(context, address, Bits64(data, 63, 32),
11597 addr_byte_size))
11598 return false;
11599
11600 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11601 (address + 4) - Rn);
11602 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11603 addr_byte_size))
11604 return false;
11605 } else {
11606 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11607 address - Rn);
11608 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11609 return false;
11610
11611 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11612 (address + 4) - Rn);
11613 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11614 addr_byte_size))
11615 return false;
11616 }
11617 // address = address+8;
11618 address = address + 8;
11619 }
11620 }
11621 }
11622 return true;
11623 }
11624
11625 // A8.6.320
11626 // This instruction loads a single extension register from memory, using an
11627 // address from an ARM core register, with an optional offset.
EmulateVLDR(const uint32_t opcode,ARMEncoding encoding)11628 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
11629 ARMEncoding encoding) {
11630 #if 0
11631 if ConditionPassed() then
11632 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11633 base = if n == 15 then Align(PC,4) else R[n];
11634 address = if add then (base + imm32) else (base - imm32);
11635 if single_reg then
11636 S[d] = MemA[address,4];
11637 else
11638 word1 = MemA[address,4]; word2 = MemA[address+4,4];
11639 // Combine the word-aligned words in the correct order for current
11640 // endianness.
11641 D[d] = if BigEndian() then word1:word2 else word2:word1;
11642 #endif
11643
11644 bool success = false;
11645
11646 if (ConditionPassed(opcode)) {
11647 bool single_reg;
11648 bool add;
11649 uint32_t imm32;
11650 uint32_t d;
11651 uint32_t n;
11652
11653 switch (encoding) {
11654 case eEncodingT1:
11655 case eEncodingA1:
11656 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11657 // 32);
11658 single_reg = false;
11659 add = BitIsSet(opcode, 23);
11660 imm32 = Bits32(opcode, 7, 0) << 2;
11661
11662 // d = UInt(D:Vd); n = UInt(Rn);
11663 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11664 n = Bits32(opcode, 19, 16);
11665
11666 break;
11667
11668 case eEncodingT2:
11669 case eEncodingA2:
11670 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11671 single_reg = true;
11672 add = BitIsSet(opcode, 23);
11673 imm32 = Bits32(opcode, 7, 0) << 2;
11674
11675 // d = UInt(Vd:D); n = UInt(Rn);
11676 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11677 n = Bits32(opcode, 19, 16);
11678
11679 break;
11680
11681 default:
11682 return false;
11683 }
11684 RegisterInfo base_reg;
11685 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11686
11687 uint32_t Rn = ReadCoreReg(n, &success);
11688 if (!success)
11689 return false;
11690
11691 // base = if n == 15 then Align(PC,4) else R[n];
11692 uint32_t base;
11693 if (n == 15)
11694 base = AlignPC(Rn);
11695 else
11696 base = Rn;
11697
11698 // address = if add then (base + imm32) else (base - imm32);
11699 addr_t address;
11700 if (add)
11701 address = base + imm32;
11702 else
11703 address = base - imm32;
11704
11705 const uint32_t addr_byte_size = GetAddressByteSize();
11706 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11707
11708 EmulateInstruction::Context context;
11709 context.type = eContextRegisterLoad;
11710 context.SetRegisterPlusOffset(base_reg, address - base);
11711
11712 if (single_reg) {
11713 // S[d] = MemA[address,4];
11714 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11715 if (!success)
11716 return false;
11717
11718 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11719 data))
11720 return false;
11721 } else {
11722 // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11723 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
11724 if (!success)
11725 return false;
11726
11727 context.SetRegisterPlusOffset(base_reg, (address + 4) - base);
11728 uint32_t word2 =
11729 MemARead(context, address + 4, addr_byte_size, 0, &success);
11730 if (!success)
11731 return false;
11732 // // Combine the word-aligned words in the correct order for current
11733 // endianness.
11734 // D[d] = if BigEndian() then word1:word2 else word2:word1;
11735 uint64_t data64;
11736 if (GetByteOrder() == eByteOrderBig) {
11737 data64 = word1;
11738 data64 = (data64 << 32) | word2;
11739 } else {
11740 data64 = word2;
11741 data64 = (data64 << 32) | word1;
11742 }
11743
11744 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11745 data64))
11746 return false;
11747 }
11748 }
11749 return true;
11750 }
11751
11752 // A8.6.400 VSTR
11753 // This instruction stores a signle extension register to memory, using an
11754 // address from an ARM core register, with an optional offset.
EmulateVSTR(const uint32_t opcode,ARMEncoding encoding)11755 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
11756 ARMEncoding encoding) {
11757 #if 0
11758 if ConditionPassed() then
11759 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11760 address = if add then (R[n] + imm32) else (R[n] - imm32);
11761 if single_reg then
11762 MemA[address,4] = S[d];
11763 else
11764 // Store as two word-aligned words in the correct order for current
11765 // endianness.
11766 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11767 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11768 #endif
11769
11770 bool success = false;
11771
11772 if (ConditionPassed(opcode)) {
11773 bool single_reg;
11774 bool add;
11775 uint32_t imm32;
11776 uint32_t d;
11777 uint32_t n;
11778
11779 switch (encoding) {
11780 case eEncodingT1:
11781 case eEncodingA1:
11782 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11783 // 32);
11784 single_reg = false;
11785 add = BitIsSet(opcode, 23);
11786 imm32 = Bits32(opcode, 7, 0) << 2;
11787
11788 // d = UInt(D:Vd); n = UInt(Rn);
11789 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11790 n = Bits32(opcode, 19, 16);
11791
11792 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11793 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11794 return false;
11795
11796 break;
11797
11798 case eEncodingT2:
11799 case eEncodingA2:
11800 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11801 single_reg = true;
11802 add = BitIsSet(opcode, 23);
11803 imm32 = Bits32(opcode, 7, 0) << 2;
11804
11805 // d = UInt(Vd:D); n = UInt(Rn);
11806 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11807 n = Bits32(opcode, 19, 16);
11808
11809 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11810 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11811 return false;
11812
11813 break;
11814
11815 default:
11816 return false;
11817 }
11818
11819 RegisterInfo base_reg;
11820 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11821
11822 uint32_t Rn = ReadCoreReg(n, &success);
11823 if (!success)
11824 return false;
11825
11826 // address = if add then (R[n] + imm32) else (R[n] - imm32);
11827 addr_t address;
11828 if (add)
11829 address = Rn + imm32;
11830 else
11831 address = Rn - imm32;
11832
11833 const uint32_t addr_byte_size = GetAddressByteSize();
11834 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11835
11836 RegisterInfo data_reg;
11837 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg);
11838 EmulateInstruction::Context context;
11839 context.type = eContextRegisterStore;
11840 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11841
11842 if (single_reg) {
11843 // MemA[address,4] = S[d];
11844 uint32_t data =
11845 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11846 if (!success)
11847 return false;
11848
11849 if (!MemAWrite(context, address, data, addr_byte_size))
11850 return false;
11851 } else {
11852 // // Store as two word-aligned words in the correct order for current
11853 // endianness.
11854 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11855 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11856 uint64_t data =
11857 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11858 if (!success)
11859 return false;
11860
11861 if (GetByteOrder() == eByteOrderBig) {
11862 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
11863 return false;
11864
11865 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11866 (address + 4) - Rn);
11867 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11868 addr_byte_size))
11869 return false;
11870 } else {
11871 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11872 return false;
11873
11874 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11875 (address + 4) - Rn);
11876 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11877 addr_byte_size))
11878 return false;
11879 }
11880 }
11881 }
11882 return true;
11883 }
11884
11885 // A8.6.307 VLDI1 (multiple single elements) This instruction loads elements
11886 // from memory into one, two, three or four registers, without de-interleaving.
11887 // Every element of each register is loaded.
EmulateVLD1Multiple(const uint32_t opcode,ARMEncoding encoding)11888 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
11889 ARMEncoding encoding) {
11890 #if 0
11891 if ConditionPassed() then
11892 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11893 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11894 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11895 for r = 0 to regs-1
11896 for e = 0 to elements-1
11897 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11898 address = address + ebytes;
11899 #endif
11900
11901 bool success = false;
11902
11903 if (ConditionPassed(opcode)) {
11904 uint32_t regs;
11905 uint32_t alignment;
11906 uint32_t ebytes;
11907 uint32_t esize;
11908 uint32_t elements;
11909 uint32_t d;
11910 uint32_t n;
11911 uint32_t m;
11912 bool wback;
11913 bool register_index;
11914
11915 switch (encoding) {
11916 case eEncodingT1:
11917 case eEncodingA1: {
11918 // case type of
11919 // when '0111'
11920 // regs = 1; if align<1> == '1' then UNDEFINED;
11921 // when '1010'
11922 // regs = 2; if align == '11' then UNDEFINED;
11923 // when '0110'
11924 // regs = 3; if align<1> == '1' then UNDEFINED;
11925 // when '0010'
11926 // regs = 4;
11927 // otherwise
11928 // SEE 'Related encodings';
11929 uint32_t type = Bits32(opcode, 11, 8);
11930 uint32_t align = Bits32(opcode, 5, 4);
11931 if (type == 7) // '0111'
11932 {
11933 regs = 1;
11934 if (BitIsSet(align, 1))
11935 return false;
11936 } else if (type == 10) // '1010'
11937 {
11938 regs = 2;
11939 if (align == 3)
11940 return false;
11941
11942 } else if (type == 6) // '0110'
11943 {
11944 regs = 3;
11945 if (BitIsSet(align, 1))
11946 return false;
11947 } else if (type == 2) // '0010'
11948 {
11949 regs = 4;
11950 } else
11951 return false;
11952
11953 // alignment = if align == '00' then 1 else 4 << UInt(align);
11954 if (align == 0)
11955 alignment = 1;
11956 else
11957 alignment = 4 << align;
11958
11959 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11960 ebytes = 1 << Bits32(opcode, 7, 6);
11961 esize = 8 * ebytes;
11962 elements = 8 / ebytes;
11963
11964 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11965 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11966 n = Bits32(opcode, 19, 15);
11967 m = Bits32(opcode, 3, 0);
11968
11969 // wback = (m != 15); register_index = (m != 15 && m != 13);
11970 wback = (m != 15);
11971 register_index = ((m != 15) && (m != 13));
11972
11973 // if d+regs > 32 then UNPREDICTABLE;
11974 if ((d + regs) > 32)
11975 return false;
11976 } break;
11977
11978 default:
11979 return false;
11980 }
11981
11982 RegisterInfo base_reg;
11983 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11984
11985 uint32_t Rn = ReadCoreReg(n, &success);
11986 if (!success)
11987 return false;
11988
11989 // address = R[n]; if (address MOD alignment) != 0 then
11990 // GenerateAlignmentException();
11991 addr_t address = Rn;
11992 if ((address % alignment) != 0)
11993 return false;
11994
11995 EmulateInstruction::Context context;
11996 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11997 if (wback) {
11998 uint32_t Rm = ReadCoreReg(m, &success);
11999 if (!success)
12000 return false;
12001
12002 uint32_t offset;
12003 if (register_index)
12004 offset = Rm;
12005 else
12006 offset = 8 * regs;
12007
12008 uint32_t value = Rn + offset;
12009 context.type = eContextAdjustBaseRegister;
12010 context.SetRegisterPlusOffset(base_reg, offset);
12011
12012 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12013 value))
12014 return false;
12015 }
12016
12017 // for r = 0 to regs-1
12018 for (uint32_t r = 0; r < regs; ++r) {
12019 // for e = 0 to elements-1
12020 uint64_t assembled_data = 0;
12021 for (uint32_t e = 0; e < elements; ++e) {
12022 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
12023 context.type = eContextRegisterLoad;
12024 context.SetRegisterPlusOffset(base_reg, address - Rn);
12025 uint64_t data = MemURead(context, address, ebytes, 0, &success);
12026 if (!success)
12027 return false;
12028
12029 assembled_data =
12030 (data << (e * esize)) |
12031 assembled_data; // New data goes to the left of existing data
12032
12033 // address = address + ebytes;
12034 address = address + ebytes;
12035 }
12036 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12037 assembled_data))
12038 return false;
12039 }
12040 }
12041 return true;
12042 }
12043
12044 // A8.6.308 VLD1 (single element to one lane)
12045 //
EmulateVLD1Single(const uint32_t opcode,const ARMEncoding encoding)12046 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
12047 const ARMEncoding encoding) {
12048 #if 0
12049 if ConditionPassed() then
12050 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12051 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12052 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12053 Elem[D[d],index,esize] = MemU[address,ebytes];
12054 #endif
12055
12056 bool success = false;
12057
12058 if (ConditionPassed(opcode)) {
12059 uint32_t ebytes;
12060 uint32_t esize;
12061 uint32_t index;
12062 uint32_t alignment;
12063 uint32_t d;
12064 uint32_t n;
12065 uint32_t m;
12066 bool wback;
12067 bool register_index;
12068
12069 switch (encoding) {
12070 case eEncodingT1:
12071 case eEncodingA1: {
12072 uint32_t size = Bits32(opcode, 11, 10);
12073 uint32_t index_align = Bits32(opcode, 7, 4);
12074 // if size == '11' then SEE VLD1 (single element to all lanes);
12075 if (size == 3)
12076 return EmulateVLD1SingleAll(opcode, encoding);
12077 // case size of
12078 if (size == 0) // when '00'
12079 {
12080 // if index_align<0> != '0' then UNDEFINED;
12081 if (BitIsClear(index_align, 0))
12082 return false;
12083
12084 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12085 ebytes = 1;
12086 esize = 8;
12087 index = Bits32(index_align, 3, 1);
12088 alignment = 1;
12089 } else if (size == 1) // when '01'
12090 {
12091 // if index_align<1> != '0' then UNDEFINED;
12092 if (BitIsClear(index_align, 1))
12093 return false;
12094
12095 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12096 ebytes = 2;
12097 esize = 16;
12098 index = Bits32(index_align, 3, 2);
12099
12100 // alignment = if index_align<0> == '0' then 1 else 2;
12101 if (BitIsClear(index_align, 0))
12102 alignment = 1;
12103 else
12104 alignment = 2;
12105 } else if (size == 2) // when '10'
12106 {
12107 // if index_align<2> != '0' then UNDEFINED;
12108 if (BitIsClear(index_align, 2))
12109 return false;
12110
12111 // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12112 // UNDEFINED;
12113 if ((Bits32(index_align, 1, 0) != 0) &&
12114 (Bits32(index_align, 1, 0) != 3))
12115 return false;
12116
12117 // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12118 ebytes = 4;
12119 esize = 32;
12120 index = Bit32(index_align, 3);
12121
12122 // alignment = if index_align<1:0> == '00' then 1 else 4;
12123 if (Bits32(index_align, 1, 0) == 0)
12124 alignment = 1;
12125 else
12126 alignment = 4;
12127 } else {
12128 return false;
12129 }
12130 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12131 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12132 n = Bits32(opcode, 19, 16);
12133 m = Bits32(opcode, 3, 0);
12134
12135 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12136 // then UNPREDICTABLE;
12137 wback = (m != 15);
12138 register_index = ((m != 15) && (m != 13));
12139
12140 if (n == 15)
12141 return false;
12142
12143 } break;
12144
12145 default:
12146 return false;
12147 }
12148
12149 RegisterInfo base_reg;
12150 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12151
12152 uint32_t Rn = ReadCoreReg(n, &success);
12153 if (!success)
12154 return false;
12155
12156 // address = R[n]; if (address MOD alignment) != 0 then
12157 // GenerateAlignmentException();
12158 addr_t address = Rn;
12159 if ((address % alignment) != 0)
12160 return false;
12161
12162 EmulateInstruction::Context context;
12163 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12164 if (wback) {
12165 uint32_t Rm = ReadCoreReg(m, &success);
12166 if (!success)
12167 return false;
12168
12169 uint32_t offset;
12170 if (register_index)
12171 offset = Rm;
12172 else
12173 offset = ebytes;
12174
12175 uint32_t value = Rn + offset;
12176
12177 context.type = eContextAdjustBaseRegister;
12178 context.SetRegisterPlusOffset(base_reg, offset);
12179
12180 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12181 value))
12182 return false;
12183 }
12184
12185 // Elem[D[d],index,esize] = MemU[address,ebytes];
12186 uint32_t element = MemURead(context, address, esize, 0, &success);
12187 if (!success)
12188 return false;
12189
12190 element = element << (index * esize);
12191
12192 uint64_t reg_data =
12193 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12194 if (!success)
12195 return false;
12196
12197 uint64_t all_ones = -1;
12198 uint64_t mask = all_ones
12199 << ((index + 1) * esize); // mask is all 1's to left of
12200 // where 'element' goes, & all 0's
12201 // at element & to the right of element.
12202 if (index > 0)
12203 mask = mask | Bits64(all_ones, (index * esize) - 1,
12204 0); // add 1's to the right of where 'element' goes.
12205 // now mask should be 0's where element goes & 1's everywhere else.
12206
12207 uint64_t masked_reg =
12208 reg_data & mask; // Take original reg value & zero out 'element' bits
12209 reg_data =
12210 masked_reg & element; // Put 'element' into those bits in reg_data.
12211
12212 context.type = eContextRegisterLoad;
12213 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
12214 reg_data))
12215 return false;
12216 }
12217 return true;
12218 }
12219
12220 // A8.6.391 VST1 (multiple single elements) Vector Store (multiple single
12221 // elements) stores elements to memory from one, two, three, or four registers,
12222 // without interleaving. Every element of each register is stored.
EmulateVST1Multiple(const uint32_t opcode,ARMEncoding encoding)12223 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
12224 ARMEncoding encoding) {
12225 #if 0
12226 if ConditionPassed() then
12227 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12228 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12229 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12230 for r = 0 to regs-1
12231 for e = 0 to elements-1
12232 MemU[address,ebytes] = Elem[D[d+r],e,esize];
12233 address = address + ebytes;
12234 #endif
12235
12236 bool success = false;
12237
12238 if (ConditionPassed(opcode)) {
12239 uint32_t regs;
12240 uint32_t alignment;
12241 uint32_t ebytes;
12242 uint32_t esize;
12243 uint32_t elements;
12244 uint32_t d;
12245 uint32_t n;
12246 uint32_t m;
12247 bool wback;
12248 bool register_index;
12249
12250 switch (encoding) {
12251 case eEncodingT1:
12252 case eEncodingA1: {
12253 uint32_t type = Bits32(opcode, 11, 8);
12254 uint32_t align = Bits32(opcode, 5, 4);
12255
12256 // case type of
12257 if (type == 7) // when '0111'
12258 {
12259 // regs = 1; if align<1> == '1' then UNDEFINED;
12260 regs = 1;
12261 if (BitIsSet(align, 1))
12262 return false;
12263 } else if (type == 10) // when '1010'
12264 {
12265 // regs = 2; if align == '11' then UNDEFINED;
12266 regs = 2;
12267 if (align == 3)
12268 return false;
12269 } else if (type == 6) // when '0110'
12270 {
12271 // regs = 3; if align<1> == '1' then UNDEFINED;
12272 regs = 3;
12273 if (BitIsSet(align, 1))
12274 return false;
12275 } else if (type == 2) // when '0010'
12276 // regs = 4;
12277 regs = 4;
12278 else // otherwise
12279 // SEE 'Related encodings';
12280 return false;
12281
12282 // alignment = if align == '00' then 1 else 4 << UInt(align);
12283 if (align == 0)
12284 alignment = 1;
12285 else
12286 alignment = 4 << align;
12287
12288 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
12289 ebytes = 1 << Bits32(opcode, 7, 6);
12290 esize = 8 * ebytes;
12291 elements = 8 / ebytes;
12292
12293 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12294 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12295 n = Bits32(opcode, 19, 16);
12296 m = Bits32(opcode, 3, 0);
12297
12298 // wback = (m != 15); register_index = (m != 15 && m != 13);
12299 wback = (m != 15);
12300 register_index = ((m != 15) && (m != 13));
12301
12302 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12303 if ((d + regs) > 32)
12304 return false;
12305
12306 if (n == 15)
12307 return false;
12308
12309 } break;
12310
12311 default:
12312 return false;
12313 }
12314
12315 RegisterInfo base_reg;
12316 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12317
12318 uint32_t Rn = ReadCoreReg(n, &success);
12319 if (!success)
12320 return false;
12321
12322 // address = R[n]; if (address MOD alignment) != 0 then
12323 // GenerateAlignmentException();
12324 addr_t address = Rn;
12325 if ((address % alignment) != 0)
12326 return false;
12327
12328 EmulateInstruction::Context context;
12329 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12330 if (wback) {
12331 uint32_t Rm = ReadCoreReg(m, &success);
12332 if (!success)
12333 return false;
12334
12335 uint32_t offset;
12336 if (register_index)
12337 offset = Rm;
12338 else
12339 offset = 8 * regs;
12340
12341 context.type = eContextAdjustBaseRegister;
12342 context.SetRegisterPlusOffset(base_reg, offset);
12343
12344 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12345 Rn + offset))
12346 return false;
12347 }
12348
12349 RegisterInfo data_reg;
12350 context.type = eContextRegisterStore;
12351 // for r = 0 to regs-1
12352 for (uint32_t r = 0; r < regs; ++r) {
12353 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
12354 uint64_t register_data = ReadRegisterUnsigned(
12355 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
12356 if (!success)
12357 return false;
12358
12359 // for e = 0 to elements-1
12360 for (uint32_t e = 0; e < elements; ++e) {
12361 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
12362 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
12363
12364 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
12365 address - Rn);
12366 if (!MemUWrite(context, address, word, ebytes))
12367 return false;
12368
12369 // address = address + ebytes;
12370 address = address + ebytes;
12371 }
12372 }
12373 }
12374 return true;
12375 }
12376
12377 // A8.6.392 VST1 (single element from one lane) This instruction stores one
12378 // element to memory from one element of a register.
EmulateVST1Single(const uint32_t opcode,ARMEncoding encoding)12379 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
12380 ARMEncoding encoding) {
12381 #if 0
12382 if ConditionPassed() then
12383 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12384 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12385 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12386 MemU[address,ebytes] = Elem[D[d],index,esize];
12387 #endif
12388
12389 bool success = false;
12390
12391 if (ConditionPassed(opcode)) {
12392 uint32_t ebytes;
12393 uint32_t esize;
12394 uint32_t index;
12395 uint32_t alignment;
12396 uint32_t d;
12397 uint32_t n;
12398 uint32_t m;
12399 bool wback;
12400 bool register_index;
12401
12402 switch (encoding) {
12403 case eEncodingT1:
12404 case eEncodingA1: {
12405 uint32_t size = Bits32(opcode, 11, 10);
12406 uint32_t index_align = Bits32(opcode, 7, 4);
12407
12408 // if size == '11' then UNDEFINED;
12409 if (size == 3)
12410 return false;
12411
12412 // case size of
12413 if (size == 0) // when '00'
12414 {
12415 // if index_align<0> != '0' then UNDEFINED;
12416 if (BitIsClear(index_align, 0))
12417 return false;
12418 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12419 ebytes = 1;
12420 esize = 8;
12421 index = Bits32(index_align, 3, 1);
12422 alignment = 1;
12423 } else if (size == 1) // when '01'
12424 {
12425 // if index_align<1> != '0' then UNDEFINED;
12426 if (BitIsClear(index_align, 1))
12427 return false;
12428
12429 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12430 ebytes = 2;
12431 esize = 16;
12432 index = Bits32(index_align, 3, 2);
12433
12434 // alignment = if index_align<0> == '0' then 1 else 2;
12435 if (BitIsClear(index_align, 0))
12436 alignment = 1;
12437 else
12438 alignment = 2;
12439 } else if (size == 2) // when '10'
12440 {
12441 // if index_align<2> != '0' then UNDEFINED;
12442 if (BitIsClear(index_align, 2))
12443 return false;
12444
12445 // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12446 // UNDEFINED;
12447 if ((Bits32(index_align, 1, 0) != 0) &&
12448 (Bits32(index_align, 1, 0) != 3))
12449 return false;
12450
12451 // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12452 ebytes = 4;
12453 esize = 32;
12454 index = Bit32(index_align, 3);
12455
12456 // alignment = if index_align<1:0> == '00' then 1 else 4;
12457 if (Bits32(index_align, 1, 0) == 0)
12458 alignment = 1;
12459 else
12460 alignment = 4;
12461 } else {
12462 return false;
12463 }
12464 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12465 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12466 n = Bits32(opcode, 19, 16);
12467 m = Bits32(opcode, 3, 0);
12468
12469 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12470 // then UNPREDICTABLE;
12471 wback = (m != 15);
12472 register_index = ((m != 15) && (m != 13));
12473
12474 if (n == 15)
12475 return false;
12476 } break;
12477
12478 default:
12479 return false;
12480 }
12481
12482 RegisterInfo base_reg;
12483 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12484
12485 uint32_t Rn = ReadCoreReg(n, &success);
12486 if (!success)
12487 return false;
12488
12489 // address = R[n]; if (address MOD alignment) != 0 then
12490 // GenerateAlignmentException();
12491 addr_t address = Rn;
12492 if ((address % alignment) != 0)
12493 return false;
12494
12495 EmulateInstruction::Context context;
12496 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12497 if (wback) {
12498 uint32_t Rm = ReadCoreReg(m, &success);
12499 if (!success)
12500 return false;
12501
12502 uint32_t offset;
12503 if (register_index)
12504 offset = Rm;
12505 else
12506 offset = ebytes;
12507
12508 context.type = eContextAdjustBaseRegister;
12509 context.SetRegisterPlusOffset(base_reg, offset);
12510
12511 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12512 Rn + offset))
12513 return false;
12514 }
12515
12516 // MemU[address,ebytes] = Elem[D[d],index,esize];
12517 uint64_t register_data =
12518 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12519 if (!success)
12520 return false;
12521
12522 uint64_t word =
12523 Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12524
12525 RegisterInfo data_reg;
12526 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12527 context.type = eContextRegisterStore;
12528 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
12529
12530 if (!MemUWrite(context, address, word, ebytes))
12531 return false;
12532 }
12533 return true;
12534 }
12535
12536 // A8.6.309 VLD1 (single element to all lanes) This instruction loads one
12537 // element from memory into every element of one or two vectors.
EmulateVLD1SingleAll(const uint32_t opcode,const ARMEncoding encoding)12538 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
12539 const ARMEncoding encoding) {
12540 #if 0
12541 if ConditionPassed() then
12542 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12543 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12544 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12545 replicated_element = Replicate(MemU[address,ebytes], elements);
12546 for r = 0 to regs-1
12547 D[d+r] = replicated_element;
12548 #endif
12549
12550 bool success = false;
12551
12552 if (ConditionPassed(opcode)) {
12553 uint32_t ebytes;
12554 uint32_t elements;
12555 uint32_t regs;
12556 uint32_t alignment;
12557 uint32_t d;
12558 uint32_t n;
12559 uint32_t m;
12560 bool wback;
12561 bool register_index;
12562
12563 switch (encoding) {
12564 case eEncodingT1:
12565 case eEncodingA1: {
12566 // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12567 uint32_t size = Bits32(opcode, 7, 6);
12568 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
12569 return false;
12570
12571 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
12572 // then 1 else 2;
12573 ebytes = 1 << size;
12574 elements = 8 / ebytes;
12575 if (BitIsClear(opcode, 5))
12576 regs = 1;
12577 else
12578 regs = 2;
12579
12580 // alignment = if a == '0' then 1 else ebytes;
12581 if (BitIsClear(opcode, 4))
12582 alignment = 1;
12583 else
12584 alignment = ebytes;
12585
12586 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12587 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12588 n = Bits32(opcode, 19, 16);
12589 m = Bits32(opcode, 3, 0);
12590
12591 // wback = (m != 15); register_index = (m != 15 && m != 13);
12592 wback = (m != 15);
12593 register_index = ((m != 15) && (m != 13));
12594
12595 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12596 if ((d + regs) > 32)
12597 return false;
12598
12599 if (n == 15)
12600 return false;
12601 } break;
12602
12603 default:
12604 return false;
12605 }
12606
12607 RegisterInfo base_reg;
12608 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12609
12610 uint32_t Rn = ReadCoreReg(n, &success);
12611 if (!success)
12612 return false;
12613
12614 // address = R[n]; if (address MOD alignment) != 0 then
12615 // GenerateAlignmentException();
12616 addr_t address = Rn;
12617 if ((address % alignment) != 0)
12618 return false;
12619
12620 EmulateInstruction::Context context;
12621 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12622 if (wback) {
12623 uint32_t Rm = ReadCoreReg(m, &success);
12624 if (!success)
12625 return false;
12626
12627 uint32_t offset;
12628 if (register_index)
12629 offset = Rm;
12630 else
12631 offset = ebytes;
12632
12633 context.type = eContextAdjustBaseRegister;
12634 context.SetRegisterPlusOffset(base_reg, offset);
12635
12636 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12637 Rn + offset))
12638 return false;
12639 }
12640
12641 // replicated_element = Replicate(MemU[address,ebytes], elements);
12642
12643 context.type = eContextRegisterLoad;
12644 uint64_t word = MemURead(context, address, ebytes, 0, &success);
12645 if (!success)
12646 return false;
12647
12648 uint64_t replicated_element = 0;
12649 uint32_t esize = ebytes * 8;
12650 for (uint32_t e = 0; e < elements; ++e)
12651 replicated_element =
12652 (replicated_element << esize) | Bits64(word, esize - 1, 0);
12653
12654 // for r = 0 to regs-1
12655 for (uint32_t r = 0; r < regs; ++r) {
12656 // D[d+r] = replicated_element;
12657 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12658 replicated_element))
12659 return false;
12660 }
12661 }
12662 return true;
12663 }
12664
12665 // B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const?
12666 // instruction provides an exception return without the use of the stack. It
12667 // subtracts the immediate constant from the LR, branches to the resulting
12668 // address, and also copies the SPSR to the CPSR.
EmulateSUBSPcLrEtc(const uint32_t opcode,const ARMEncoding encoding)12669 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
12670 const ARMEncoding encoding) {
12671 #if 0
12672 if ConditionPassed() then
12673 EncodingSpecificOperations();
12674 if CurrentInstrSet() == InstrSet_ThumbEE then
12675 UNPREDICTABLE;
12676 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12677 case opcode of
12678 when '0000' result = R[n] AND operand2; // AND
12679 when '0001' result = R[n] EOR operand2; // EOR
12680 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12681 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12682 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12683 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12684 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12685 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12686 when '1100' result = R[n] OR operand2; // ORR
12687 when '1101' result = operand2; // MOV
12688 when '1110' result = R[n] AND NOT(operand2); // BIC
12689 when '1111' result = NOT(operand2); // MVN
12690 CPSRWriteByInstr(SPSR[], '1111', TRUE);
12691 BranchWritePC(result);
12692 #endif
12693
12694 bool success = false;
12695
12696 if (ConditionPassed(opcode)) {
12697 uint32_t n;
12698 uint32_t m;
12699 uint32_t imm32;
12700 bool register_form;
12701 ARM_ShifterType shift_t;
12702 uint32_t shift_n;
12703 uint32_t code;
12704
12705 switch (encoding) {
12706 case eEncodingT1:
12707 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14;
12708 // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010';
12709 // // = SUB
12710 n = 14;
12711 imm32 = Bits32(opcode, 7, 0);
12712 register_form = false;
12713 code = 2;
12714
12715 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12716 if (InITBlock() && !LastInITBlock())
12717 return false;
12718
12719 break;
12720
12721 case eEncodingA1:
12722 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12723 n = Bits32(opcode, 19, 16);
12724 imm32 = ARMExpandImm(opcode);
12725 register_form = false;
12726 code = Bits32(opcode, 24, 21);
12727
12728 break;
12729
12730 case eEncodingA2:
12731 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12732 n = Bits32(opcode, 19, 16);
12733 m = Bits32(opcode, 3, 0);
12734 register_form = true;
12735
12736 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12737 shift_n = DecodeImmShiftARM(opcode, shift_t);
12738
12739 break;
12740
12741 default:
12742 return false;
12743 }
12744
12745 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
12746 // else imm32;
12747 uint32_t operand2;
12748 if (register_form) {
12749 uint32_t Rm = ReadCoreReg(m, &success);
12750 if (!success)
12751 return false;
12752
12753 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
12754 if (!success)
12755 return false;
12756 } else {
12757 operand2 = imm32;
12758 }
12759
12760 uint32_t Rn = ReadCoreReg(n, &success);
12761 if (!success)
12762 return false;
12763
12764 AddWithCarryResult result;
12765
12766 // case opcode of
12767 switch (code) {
12768 case 0: // when '0000'
12769 // result = R[n] AND operand2; // AND
12770 result.result = Rn & operand2;
12771 break;
12772
12773 case 1: // when '0001'
12774 // result = R[n] EOR operand2; // EOR
12775 result.result = Rn ^ operand2;
12776 break;
12777
12778 case 2: // when '0010'
12779 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12780 result = AddWithCarry(Rn, ~(operand2), 1);
12781 break;
12782
12783 case 3: // when '0011'
12784 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12785 result = AddWithCarry(~(Rn), operand2, 1);
12786 break;
12787
12788 case 4: // when '0100'
12789 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12790 result = AddWithCarry(Rn, operand2, 0);
12791 break;
12792
12793 case 5: // when '0101'
12794 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12795 result = AddWithCarry(Rn, operand2, APSR_C);
12796 break;
12797
12798 case 6: // when '0110'
12799 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12800 result = AddWithCarry(Rn, ~(operand2), APSR_C);
12801 break;
12802
12803 case 7: // when '0111'
12804 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12805 result = AddWithCarry(~(Rn), operand2, APSR_C);
12806 break;
12807
12808 case 10: // when '1100'
12809 // result = R[n] OR operand2; // ORR
12810 result.result = Rn | operand2;
12811 break;
12812
12813 case 11: // when '1101'
12814 // result = operand2; // MOV
12815 result.result = operand2;
12816 break;
12817
12818 case 12: // when '1110'
12819 // result = R[n] AND NOT(operand2); // BIC
12820 result.result = Rn & ~(operand2);
12821 break;
12822
12823 case 15: // when '1111'
12824 // result = NOT(operand2); // MVN
12825 result.result = ~(operand2);
12826 break;
12827
12828 default:
12829 return false;
12830 }
12831 // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12832
12833 // For now, in emulation mode, we don't have access to the SPSR, so we will
12834 // use the CPSR instead, and hope for the best.
12835 uint32_t spsr =
12836 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12837 if (!success)
12838 return false;
12839
12840 CPSRWriteByInstr(spsr, 15, true);
12841
12842 // BranchWritePC(result);
12843 EmulateInstruction::Context context;
12844 context.type = eContextAdjustPC;
12845 context.SetImmediate(result.result);
12846
12847 BranchWritePC(context, result.result);
12848 }
12849 return true;
12850 }
12851
12852 EmulateInstructionARM::ARMOpcode *
GetARMOpcodeForInstruction(const uint32_t opcode,uint32_t arm_isa)12853 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
12854 uint32_t arm_isa) {
12855 static ARMOpcode g_arm_opcodes[] = {
12856 //----------------------------------------------------------------------
12857 // Prologue instructions
12858 //----------------------------------------------------------------------
12859
12860 // push register(s)
12861 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12862 &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12863 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12864 &EmulateInstructionARM::EmulatePUSH, "push <register>"},
12865
12866 // set r7 to point to a stack offset
12867 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12868 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
12869 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12870 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12871 // copy the stack pointer to ip
12872 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
12873 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
12874 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12875 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
12876 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12877 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12878
12879 // adjust the stack pointer
12880 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12881 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12882 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12883 &EmulateInstructionARM::EmulateSUBSPReg,
12884 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12885
12886 // push one register
12887 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12888 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12889 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
12890
12891 // vector push consecutive extension register(s)
12892 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12893 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12894 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12895 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12896
12897 //----------------------------------------------------------------------
12898 // Epilogue instructions
12899 //----------------------------------------------------------------------
12900
12901 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12902 &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12903 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12904 &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12905 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12906 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12907 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12908 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12909
12910 //----------------------------------------------------------------------
12911 // Supervisor Call (previously Software Interrupt)
12912 //----------------------------------------------------------------------
12913 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12914 &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12915
12916 //----------------------------------------------------------------------
12917 // Branch instructions
12918 //----------------------------------------------------------------------
12919 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
12920 // "bl <label>".
12921 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
12922 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12923 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12924 &EmulateInstructionARM::EmulateB, "b #imm24"},
12925 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12926 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12927 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
12928 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12929 // for example, "bx lr"
12930 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
12931 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12932 // bxj
12933 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
12934 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12935
12936 //----------------------------------------------------------------------
12937 // Data-processing instructions
12938 //----------------------------------------------------------------------
12939 // adc (immediate)
12940 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12941 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12942 // adc (register)
12943 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12944 &EmulateInstructionARM::EmulateADCReg,
12945 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12946 // add (immediate)
12947 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12948 &EmulateInstructionARM::EmulateADDImmARM,
12949 "add{s}<c> <Rd>, <Rn>, #const"},
12950 // add (register)
12951 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12952 &EmulateInstructionARM::EmulateADDReg,
12953 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12954 // add (register-shifted register)
12955 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
12956 &EmulateInstructionARM::EmulateADDRegShift,
12957 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12958 // adr
12959 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12960 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12961 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
12962 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12963 // and (immediate)
12964 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12965 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12966 // and (register)
12967 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12968 &EmulateInstructionARM::EmulateANDReg,
12969 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12970 // bic (immediate)
12971 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12972 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12973 // bic (register)
12974 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12975 &EmulateInstructionARM::EmulateBICReg,
12976 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12977 // eor (immediate)
12978 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12979 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12980 // eor (register)
12981 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12982 &EmulateInstructionARM::EmulateEORReg,
12983 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12984 // orr (immediate)
12985 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12986 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12987 // orr (register)
12988 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12989 &EmulateInstructionARM::EmulateORRReg,
12990 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12991 // rsb (immediate)
12992 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12993 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12994 // rsb (register)
12995 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12996 &EmulateInstructionARM::EmulateRSBReg,
12997 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12998 // rsc (immediate)
12999 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13000 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
13001 // rsc (register)
13002 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13003 &EmulateInstructionARM::EmulateRSCReg,
13004 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13005 // sbc (immediate)
13006 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13007 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13008 // sbc (register)
13009 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13010 &EmulateInstructionARM::EmulateSBCReg,
13011 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13012 // sub (immediate, ARM)
13013 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13014 &EmulateInstructionARM::EmulateSUBImmARM,
13015 "sub{s}<c> <Rd>, <Rn>, #<const>"},
13016 // sub (sp minus immediate)
13017 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13018 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
13019 // sub (register)
13020 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13021 &EmulateInstructionARM::EmulateSUBReg,
13022 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
13023 // teq (immediate)
13024 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13025 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
13026 // teq (register)
13027 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13028 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13029 // tst (immediate)
13030 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13031 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
13032 // tst (register)
13033 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13034 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
13035
13036 // mov (immediate)
13037 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13038 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
13039 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
13040 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
13041 // mov (register)
13042 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13043 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
13044 // mvn (immediate)
13045 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13046 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
13047 // mvn (register)
13048 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13049 &EmulateInstructionARM::EmulateMVNReg,
13050 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
13051 // cmn (immediate)
13052 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13053 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13054 // cmn (register)
13055 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13056 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13057 // cmp (immediate)
13058 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13059 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
13060 // cmp (register)
13061 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13062 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
13063 // asr (immediate)
13064 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
13065 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
13066 // asr (register)
13067 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13068 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
13069 // lsl (immediate)
13070 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13071 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
13072 // lsl (register)
13073 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
13074 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
13075 // lsr (immediate)
13076 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
13077 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
13078 // lsr (register)
13079 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13080 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
13081 // rrx is a special case encoding of ror (immediate)
13082 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13083 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
13084 // ror (immediate)
13085 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13086 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
13087 // ror (register)
13088 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
13089 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
13090 // mul
13091 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
13092 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
13093
13094 // subs pc, lr and related instructions
13095 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13096 &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13097 "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
13098 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
13099 &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13100 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
13101
13102 //----------------------------------------------------------------------
13103 // Load instructions
13104 //----------------------------------------------------------------------
13105 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13106 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13107 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13108 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
13109 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13110 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13111 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13112 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
13113 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13114 &EmulateInstructionARM::EmulateLDRImmediateARM,
13115 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
13116 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13117 &EmulateInstructionARM::EmulateLDRRegister,
13118 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
13119 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13120 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
13121 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13122 &EmulateInstructionARM::EmulateLDRBRegister,
13123 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
13124 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13125 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13126 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13127 &EmulateInstructionARM::EmulateLDRHRegister,
13128 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13129 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13130 &EmulateInstructionARM::EmulateLDRSBImmediate,
13131 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
13132 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13133 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
13134 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13135 &EmulateInstructionARM::EmulateLDRSBRegister,
13136 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13137 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13138 &EmulateInstructionARM::EmulateLDRSHImmediate,
13139 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
13140 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13141 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13142 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13143 &EmulateInstructionARM::EmulateLDRSHRegister,
13144 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13145 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13146 &EmulateInstructionARM::EmulateLDRDImmediate,
13147 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
13148 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13149 &EmulateInstructionARM::EmulateLDRDRegister,
13150 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13151 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13152 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13153 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13154 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13155 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13156 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13157 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13158 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13159 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13160 &EmulateInstructionARM::EmulateVLD1Multiple,
13161 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13162 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13163 &EmulateInstructionARM::EmulateVLD1Single,
13164 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13165 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13166 &EmulateInstructionARM::EmulateVLD1SingleAll,
13167 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13168
13169 //----------------------------------------------------------------------
13170 // Store instructions
13171 //----------------------------------------------------------------------
13172 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13173 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13174 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13175 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
13176 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13177 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13178 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13179 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
13180 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13181 &EmulateInstructionARM::EmulateSTRRegister,
13182 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
13183 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13184 &EmulateInstructionARM::EmulateSTRHRegister,
13185 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
13186 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13187 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
13188 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13189 &EmulateInstructionARM::EmulateSTRBImmARM,
13190 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13191 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13192 &EmulateInstructionARM::EmulateSTRImmARM,
13193 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13194 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13195 &EmulateInstructionARM::EmulateSTRDImm,
13196 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
13197 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13198 &EmulateInstructionARM::EmulateSTRDReg,
13199 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13200 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13201 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13202 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13203 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13204 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13205 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
13206 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13207 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
13208 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13209 &EmulateInstructionARM::EmulateVST1Multiple,
13210 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13211 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13212 &EmulateInstructionARM::EmulateVST1Single,
13213 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13214
13215 //----------------------------------------------------------------------
13216 // Other instructions
13217 //----------------------------------------------------------------------
13218 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13219 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
13220 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13221 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
13222 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13223 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
13224 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13225 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
13226 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13227 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
13228
13229 };
13230 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
13231
13232 for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
13233 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
13234 (g_arm_opcodes[i].variants & arm_isa) != 0)
13235 return &g_arm_opcodes[i];
13236 }
13237 return NULL;
13238 }
13239
13240 EmulateInstructionARM::ARMOpcode *
GetThumbOpcodeForInstruction(const uint32_t opcode,uint32_t arm_isa)13241 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
13242 uint32_t arm_isa) {
13243
13244 static ARMOpcode g_thumb_opcodes[] = {
13245 //----------------------------------------------------------------------
13246 // Prologue instructions
13247 //----------------------------------------------------------------------
13248
13249 // push register(s)
13250 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
13251 &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
13252 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13253 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
13254 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13255 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
13256
13257 // set r7 to point to a stack offset
13258 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13259 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
13260 // copy the stack pointer to r7
13261 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
13262 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
13263 // move from high register to low register (comes after "mov r7, sp" to
13264 // resolve ambiguity)
13265 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
13266 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
13267
13268 // PC-relative load into register (see also EmulateADDSPRm)
13269 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13270 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
13271
13272 // adjust the stack pointer
13273 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
13274 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
13275 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13276 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
13277 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13278 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
13279 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13280 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
13281 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13282 &EmulateInstructionARM::EmulateSUBSPReg,
13283 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
13284
13285 // vector push consecutive extension register(s)
13286 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13287 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
13288 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13289 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
13290
13291 //----------------------------------------------------------------------
13292 // Epilogue instructions
13293 //----------------------------------------------------------------------
13294
13295 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13296 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
13297 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13298 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
13299 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13300 &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
13301 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13302 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
13303 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13304 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
13305 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13306 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
13307 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13308 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
13309
13310 //----------------------------------------------------------------------
13311 // Supervisor Call (previously Software Interrupt)
13312 //----------------------------------------------------------------------
13313 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13314 &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
13315
13316 //----------------------------------------------------------------------
13317 // If Then makes up to four following instructions conditional.
13318 //----------------------------------------------------------------------
13319 // The next 5 opcode _must_ come before the if then instruction
13320 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13321 &EmulateInstructionARM::EmulateNop, "nop"},
13322 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13323 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
13324 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13325 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
13326 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13327 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
13328 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13329 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
13330 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13331 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
13332
13333 //----------------------------------------------------------------------
13334 // Branch instructions
13335 //----------------------------------------------------------------------
13336 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
13337 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13338 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
13339 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13340 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
13341 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13342 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
13343 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13344 &EmulateInstructionARM::EmulateB,
13345 "b<c>.w #imm8 (outside or last in IT)"},
13346 // J1 == J2 == 1
13347 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
13348 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
13349 // J1 == J2 == 1
13350 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
13351 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
13352 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
13353 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
13354 // for example, "bx lr"
13355 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
13356 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
13357 // bxj
13358 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
13359 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
13360 // compare and branch
13361 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13362 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
13363 // table branch byte
13364 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13365 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
13366 // table branch halfword
13367 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13368 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
13369
13370 //----------------------------------------------------------------------
13371 // Data-processing instructions
13372 //----------------------------------------------------------------------
13373 // adc (immediate)
13374 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13375 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
13376 // adc (register)
13377 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
13378 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
13379 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13380 &EmulateInstructionARM::EmulateADCReg,
13381 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13382 // add (register)
13383 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13384 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
13385 // Make sure "add sp, <Rm>" comes before this instruction, so there's no
13386 // ambiguity decoding the two.
13387 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
13388 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
13389 // adr
13390 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13391 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13392 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13393 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
13394 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13395 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13396 // and (immediate)
13397 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13398 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
13399 // and (register)
13400 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13401 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
13402 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13403 &EmulateInstructionARM::EmulateANDReg,
13404 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13405 // bic (immediate)
13406 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13407 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
13408 // bic (register)
13409 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
13410 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
13411 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13412 &EmulateInstructionARM::EmulateBICReg,
13413 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13414 // eor (immediate)
13415 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13416 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
13417 // eor (register)
13418 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
13419 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
13420 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13421 &EmulateInstructionARM::EmulateEORReg,
13422 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13423 // orr (immediate)
13424 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13425 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
13426 // orr (register)
13427 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
13428 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
13429 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13430 &EmulateInstructionARM::EmulateORRReg,
13431 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13432 // rsb (immediate)
13433 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
13434 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
13435 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13436 &EmulateInstructionARM::EmulateRSBImm,
13437 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
13438 // rsb (register)
13439 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13440 &EmulateInstructionARM::EmulateRSBReg,
13441 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13442 // sbc (immediate)
13443 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13444 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13445 // sbc (register)
13446 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
13447 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
13448 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13449 &EmulateInstructionARM::EmulateSBCReg,
13450 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13451 // add (immediate, Thumb)
13452 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13453 &EmulateInstructionARM::EmulateADDImmThumb,
13454 "adds|add<c> <Rd>,<Rn>,#<imm3>"},
13455 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13456 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
13457 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13458 &EmulateInstructionARM::EmulateADDImmThumb,
13459 "add{s}<c>.w <Rd>,<Rn>,#<const>"},
13460 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13461 &EmulateInstructionARM::EmulateADDImmThumb,
13462 "addw<c> <Rd>,<Rn>,#<imm12>"},
13463 // sub (immediate, Thumb)
13464 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13465 &EmulateInstructionARM::EmulateSUBImmThumb,
13466 "subs|sub<c> <Rd>, <Rn> #imm3"},
13467 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
13468 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
13469 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13470 &EmulateInstructionARM::EmulateSUBImmThumb,
13471 "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13472 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13473 &EmulateInstructionARM::EmulateSUBImmThumb,
13474 "subw<c> <Rd>, <Rn>, #imm12"},
13475 // sub (sp minus immediate)
13476 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13477 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
13478 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13479 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
13480 // sub (register)
13481 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13482 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
13483 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13484 &EmulateInstructionARM::EmulateSUBReg,
13485 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13486 // teq (immediate)
13487 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13488 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
13489 // teq (register)
13490 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13491 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13492 // tst (immediate)
13493 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13494 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
13495 // tst (register)
13496 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
13497 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
13498 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13499 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
13500
13501 // move from high register to high register
13502 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
13503 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
13504 // move from low register to low register
13505 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13506 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
13507 // mov{s}<c>.w <Rd>, <Rm>
13508 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13509 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
13510 // move immediate
13511 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13512 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
13513 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13514 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
13515 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13516 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
13517 // mvn (immediate)
13518 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13519 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
13520 // mvn (register)
13521 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13522 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
13523 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13524 &EmulateInstructionARM::EmulateMVNReg,
13525 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13526 // cmn (immediate)
13527 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13528 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13529 // cmn (register)
13530 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13531 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
13532 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13533 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13534 // cmp (immediate)
13535 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13536 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
13537 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13538 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
13539 // cmp (register) (Rn and Rm both from r0-r7)
13540 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
13541 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13542 // cmp (register) (Rn and Rm not both from r0-r7)
13543 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
13544 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13545 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
13546 &EmulateInstructionARM::EmulateCMPReg,
13547 "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13548 // asr (immediate)
13549 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13550 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
13551 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13552 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
13553 // asr (register)
13554 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
13555 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
13556 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13557 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13558 // lsl (immediate)
13559 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13560 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
13561 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13562 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
13563 // lsl (register)
13564 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13565 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
13566 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13567 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
13568 // lsr (immediate)
13569 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13570 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
13571 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13572 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
13573 // lsr (register)
13574 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13575 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
13576 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13577 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13578 // rrx is a special case encoding of ror (immediate)
13579 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13580 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
13581 // ror (immediate)
13582 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13583 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
13584 // ror (register)
13585 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13586 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
13587 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13588 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
13589 // mul
13590 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13591 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
13592 // mul
13593 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13594 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
13595
13596 // subs pc, lr and related instructions
13597 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13598 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
13599
13600 //----------------------------------------------------------------------
13601 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
13602 // LDM.. Instructions in this table;
13603 // otherwise the wrong instructions will be selected.
13604 //----------------------------------------------------------------------
13605
13606 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13607 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
13608 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13609 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
13610
13611 //----------------------------------------------------------------------
13612 // Load instructions
13613 //----------------------------------------------------------------------
13614 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13615 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13616 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13617 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
13618 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13619 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13620 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13621 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
13622 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13623 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
13624 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13625 &EmulateInstructionARM::EmulateLDRRtRnImm,
13626 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13627 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13628 &EmulateInstructionARM::EmulateLDRRtRnImm,
13629 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13630 // Thumb2 PC-relative load into register
13631 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13632 &EmulateInstructionARM::EmulateLDRRtPCRelative,
13633 "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13634 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13635 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
13636 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13637 &EmulateInstructionARM::EmulateLDRRegister,
13638 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13639 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13640 &EmulateInstructionARM::EmulateLDRBImmediate,
13641 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13642 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13643 &EmulateInstructionARM::EmulateLDRBImmediate,
13644 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13645 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13646 &EmulateInstructionARM::EmulateLDRBImmediate,
13647 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13648 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13649 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
13650 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13651 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
13652 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13653 &EmulateInstructionARM::EmulateLDRBRegister,
13654 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13655 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13656 &EmulateInstructionARM::EmulateLDRHImmediate,
13657 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13658 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13659 &EmulateInstructionARM::EmulateLDRHImmediate,
13660 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13661 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13662 &EmulateInstructionARM::EmulateLDRHImmediate,
13663 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13664 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13665 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13666 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13667 &EmulateInstructionARM::EmulateLDRHRegister,
13668 "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13669 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13670 &EmulateInstructionARM::EmulateLDRHRegister,
13671 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13672 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13673 &EmulateInstructionARM::EmulateLDRSBImmediate,
13674 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13675 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13676 &EmulateInstructionARM::EmulateLDRSBImmediate,
13677 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13678 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13679 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
13680 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13681 &EmulateInstructionARM::EmulateLDRSBRegister,
13682 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13683 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13684 &EmulateInstructionARM::EmulateLDRSBRegister,
13685 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13686 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13687 &EmulateInstructionARM::EmulateLDRSHImmediate,
13688 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13689 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13690 &EmulateInstructionARM::EmulateLDRSHImmediate,
13691 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13692 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13693 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13694 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13695 &EmulateInstructionARM::EmulateLDRSHRegister,
13696 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13697 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13698 &EmulateInstructionARM::EmulateLDRSHRegister,
13699 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13700 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13701 &EmulateInstructionARM::EmulateLDRDImmediate,
13702 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13703 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13704 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13705 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13706 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13707 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13708 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13709 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13710 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
13711 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13712 &EmulateInstructionARM::EmulateVLD1Multiple,
13713 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13714 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13715 &EmulateInstructionARM::EmulateVLD1Single,
13716 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13717 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13718 &EmulateInstructionARM::EmulateVLD1SingleAll,
13719 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13720
13721 //----------------------------------------------------------------------
13722 // Store instructions
13723 //----------------------------------------------------------------------
13724 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13725 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13726 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13727 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
13728 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13729 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13730 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13731 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
13732 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13733 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
13734 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13735 &EmulateInstructionARM::EmulateSTRThumb,
13736 "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13737 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13738 &EmulateInstructionARM::EmulateSTRThumb,
13739 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13740 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13741 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
13742 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13743 &EmulateInstructionARM::EmulateSTRRegister,
13744 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13745 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13746 &EmulateInstructionARM::EmulateSTRBThumb,
13747 "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13748 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13749 &EmulateInstructionARM::EmulateSTRBThumb,
13750 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13751 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13752 &EmulateInstructionARM::EmulateSTRBThumb,
13753 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13754 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13755 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
13756 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13757 &EmulateInstructionARM::EmulateSTRHRegister,
13758 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13759 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13760 &EmulateInstructionARM::EmulateSTREX,
13761 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13762 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13763 &EmulateInstructionARM::EmulateSTRDImm,
13764 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13765 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13766 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13767 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13768 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13769 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13770 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13771 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13772 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13773 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13774 &EmulateInstructionARM::EmulateVST1Multiple,
13775 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13776 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13777 &EmulateInstructionARM::EmulateVST1Single,
13778 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13779
13780 //----------------------------------------------------------------------
13781 // Other instructions
13782 //----------------------------------------------------------------------
13783 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13784 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
13785 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
13786 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13787 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13788 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
13789 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13790 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13791 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13792 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
13793 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13794 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13795 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13796 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
13797 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13798 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13799 };
13800
13801 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
13802 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13803 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13804 (g_thumb_opcodes[i].variants & arm_isa) != 0)
13805 return &g_thumb_opcodes[i];
13806 }
13807 return NULL;
13808 }
13809
SetArchitecture(const ArchSpec & arch)13810 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
13811 m_arch = arch;
13812 m_arm_isa = 0;
13813 const char *arch_cstr = arch.GetArchitectureName();
13814 if (arch_cstr) {
13815 if (0 == ::strcasecmp(arch_cstr, "armv4t"))
13816 m_arm_isa = ARMv4T;
13817 else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))
13818 m_arm_isa = ARMv5TEJ;
13819 else if (0 == ::strcasecmp(arch_cstr, "armv5te"))
13820 m_arm_isa = ARMv5TE;
13821 else if (0 == ::strcasecmp(arch_cstr, "armv5t"))
13822 m_arm_isa = ARMv5T;
13823 else if (0 == ::strcasecmp(arch_cstr, "armv6k"))
13824 m_arm_isa = ARMv6K;
13825 else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))
13826 m_arm_isa = ARMv6T2;
13827 else if (0 == ::strcasecmp(arch_cstr, "armv7s"))
13828 m_arm_isa = ARMv7S;
13829 else if (0 == ::strcasecmp(arch_cstr, "arm"))
13830 m_arm_isa = ARMvAll;
13831 else if (0 == ::strcasecmp(arch_cstr, "thumb"))
13832 m_arm_isa = ARMvAll;
13833 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5))
13834 m_arm_isa = ARMv4;
13835 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5))
13836 m_arm_isa = ARMv6;
13837 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5))
13838 m_arm_isa = ARMv7;
13839 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5))
13840 m_arm_isa = ARMv8;
13841 }
13842 return m_arm_isa != 0;
13843 }
13844
SetInstruction(const Opcode & insn_opcode,const Address & inst_addr,Target * target)13845 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
13846 const Address &inst_addr,
13847 Target *target) {
13848 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
13849 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
13850 m_arch.IsAlwaysThumbInstructions())
13851 m_opcode_mode = eModeThumb;
13852 else {
13853 AddressClass addr_class = inst_addr.GetAddressClass();
13854
13855 if ((addr_class == AddressClass::eCode) ||
13856 (addr_class == AddressClass::eUnknown))
13857 m_opcode_mode = eModeARM;
13858 else if (addr_class == AddressClass::eCodeAlternateISA)
13859 m_opcode_mode = eModeThumb;
13860 else
13861 return false;
13862 }
13863 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
13864 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13865 else
13866 m_opcode_cpsr = CPSR_MODE_USR;
13867 return true;
13868 }
13869 return false;
13870 }
13871
ReadInstruction()13872 bool EmulateInstructionARM::ReadInstruction() {
13873 bool success = false;
13874 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
13875 LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13876 if (success) {
13877 addr_t pc =
13878 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
13879 LLDB_INVALID_ADDRESS, &success);
13880 if (success) {
13881 Context read_inst_context;
13882 read_inst_context.type = eContextReadOpcode;
13883 read_inst_context.SetNoArgs();
13884
13885 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
13886 m_opcode_mode = eModeThumb;
13887 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13888
13889 if (success) {
13890 if ((thumb_opcode & 0xe000) != 0xe000 ||
13891 ((thumb_opcode & 0x1800u) == 0)) {
13892 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
13893 } else {
13894 m_opcode.SetOpcode32(
13895 (thumb_opcode << 16) |
13896 MemARead(read_inst_context, pc + 2, 2, 0, &success),
13897 GetByteOrder());
13898 }
13899 }
13900 } else {
13901 m_opcode_mode = eModeARM;
13902 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
13903 GetByteOrder());
13904 }
13905
13906 if (!m_ignore_conditions) {
13907 // If we are not ignoreing the conditions then init the it session from
13908 // the current value of cpsr.
13909 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
13910 Bits32(m_opcode_cpsr, 26, 25);
13911 if (it != 0)
13912 m_it_session.InitIT(it);
13913 }
13914 }
13915 }
13916 if (!success) {
13917 m_opcode_mode = eModeInvalid;
13918 m_addr = LLDB_INVALID_ADDRESS;
13919 }
13920 return success;
13921 }
13922
ArchVersion()13923 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
13924
ConditionPassed(const uint32_t opcode)13925 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
13926 // If we are ignoring conditions, then always return true. this allows us to
13927 // iterate over disassembly code and still emulate an instruction even if we
13928 // don't have all the right bits set in the CPSR register...
13929 if (m_ignore_conditions)
13930 return true;
13931
13932 const uint32_t cond = CurrentCond(opcode);
13933 if (cond == UINT32_MAX)
13934 return false;
13935
13936 bool result = false;
13937 switch (UnsignedBits(cond, 3, 1)) {
13938 case 0:
13939 if (m_opcode_cpsr == 0)
13940 result = true;
13941 else
13942 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13943 break;
13944 case 1:
13945 if (m_opcode_cpsr == 0)
13946 result = true;
13947 else
13948 result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13949 break;
13950 case 2:
13951 if (m_opcode_cpsr == 0)
13952 result = true;
13953 else
13954 result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13955 break;
13956 case 3:
13957 if (m_opcode_cpsr == 0)
13958 result = true;
13959 else
13960 result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13961 break;
13962 case 4:
13963 if (m_opcode_cpsr == 0)
13964 result = true;
13965 else
13966 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
13967 ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13968 break;
13969 case 5:
13970 if (m_opcode_cpsr == 0)
13971 result = true;
13972 else {
13973 bool n = (m_opcode_cpsr & MASK_CPSR_N);
13974 bool v = (m_opcode_cpsr & MASK_CPSR_V);
13975 result = n == v;
13976 }
13977 break;
13978 case 6:
13979 if (m_opcode_cpsr == 0)
13980 result = true;
13981 else {
13982 bool n = (m_opcode_cpsr & MASK_CPSR_N);
13983 bool v = (m_opcode_cpsr & MASK_CPSR_V);
13984 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13985 }
13986 break;
13987 case 7:
13988 // Always execute (cond == 0b1110, or the special 0b1111 which gives
13989 // opcodes different meanings, but always means execution happens.
13990 return true;
13991 }
13992
13993 if (cond & 1)
13994 result = !result;
13995 return result;
13996 }
13997
CurrentCond(const uint32_t opcode)13998 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
13999 switch (m_opcode_mode) {
14000 case eModeInvalid:
14001 break;
14002
14003 case eModeARM:
14004 return UnsignedBits(opcode, 31, 28);
14005
14006 case eModeThumb:
14007 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
14008 // 'cond' field of the encoding.
14009 {
14010 const uint32_t byte_size = m_opcode.GetByteSize();
14011 if (byte_size == 2) {
14012 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
14013 return Bits32(opcode, 11, 8);
14014 } else if (byte_size == 4) {
14015 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
14016 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
14017 return Bits32(opcode, 25, 22);
14018 }
14019 } else
14020 // We have an invalid thumb instruction, let's bail out.
14021 break;
14022
14023 return m_it_session.GetCond();
14024 }
14025 }
14026 return UINT32_MAX; // Return invalid value
14027 }
14028
InITBlock()14029 bool EmulateInstructionARM::InITBlock() {
14030 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
14031 }
14032
LastInITBlock()14033 bool EmulateInstructionARM::LastInITBlock() {
14034 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
14035 }
14036
BadMode(uint32_t mode)14037 bool EmulateInstructionARM::BadMode(uint32_t mode) {
14038
14039 switch (mode) {
14040 case 16:
14041 return false; // '10000'
14042 case 17:
14043 return false; // '10001'
14044 case 18:
14045 return false; // '10010'
14046 case 19:
14047 return false; // '10011'
14048 case 22:
14049 return false; // '10110'
14050 case 23:
14051 return false; // '10111'
14052 case 27:
14053 return false; // '11011'
14054 case 31:
14055 return false; // '11111'
14056 default:
14057 return true;
14058 }
14059 return true;
14060 }
14061
CurrentModeIsPrivileged()14062 bool EmulateInstructionARM::CurrentModeIsPrivileged() {
14063 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
14064
14065 if (BadMode(mode))
14066 return false;
14067
14068 if (mode == 16)
14069 return false;
14070
14071 return true;
14072 }
14073
CPSRWriteByInstr(uint32_t value,uint32_t bytemask,bool affect_execstate)14074 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
14075 bool affect_execstate) {
14076 bool privileged = CurrentModeIsPrivileged();
14077
14078 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
14079
14080 if (BitIsSet(bytemask, 3)) {
14081 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
14082 if (affect_execstate)
14083 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
14084 }
14085
14086 if (BitIsSet(bytemask, 2)) {
14087 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
14088 }
14089
14090 if (BitIsSet(bytemask, 1)) {
14091 if (affect_execstate)
14092 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
14093 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
14094 if (privileged)
14095 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
14096 }
14097
14098 if (BitIsSet(bytemask, 0)) {
14099 if (privileged)
14100 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
14101 if (affect_execstate)
14102 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
14103 if (privileged)
14104 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
14105 }
14106
14107 m_opcode_cpsr = tmp_cpsr;
14108 }
14109
BranchWritePC(const Context & context,uint32_t addr)14110 bool EmulateInstructionARM::BranchWritePC(const Context &context,
14111 uint32_t addr) {
14112 addr_t target;
14113
14114 // Check the current instruction set.
14115 if (CurrentInstrSet() == eModeARM)
14116 target = addr & 0xfffffffc;
14117 else
14118 target = addr & 0xfffffffe;
14119
14120 return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14121 LLDB_REGNUM_GENERIC_PC, target);
14122 }
14123
14124 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
14125 // inspecting addr.
BXWritePC(Context & context,uint32_t addr)14126 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
14127 addr_t target;
14128 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
14129 // we want to record it and issue a WriteRegister callback so the clients can
14130 // track the mode changes accordingly.
14131 bool cpsr_changed = false;
14132
14133 if (BitIsSet(addr, 0)) {
14134 if (CurrentInstrSet() != eModeThumb) {
14135 SelectInstrSet(eModeThumb);
14136 cpsr_changed = true;
14137 }
14138 target = addr & 0xfffffffe;
14139 context.SetISA(eModeThumb);
14140 } else if (BitIsClear(addr, 1)) {
14141 if (CurrentInstrSet() != eModeARM) {
14142 SelectInstrSet(eModeARM);
14143 cpsr_changed = true;
14144 }
14145 target = addr & 0xfffffffc;
14146 context.SetISA(eModeARM);
14147 } else
14148 return false; // address<1:0> == '10' => UNPREDICTABLE
14149
14150 if (cpsr_changed) {
14151 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14152 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14153 return false;
14154 }
14155 return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14156 LLDB_REGNUM_GENERIC_PC, target);
14157 }
14158
14159 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14160 // versions.
LoadWritePC(Context & context,uint32_t addr)14161 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
14162 if (ArchVersion() >= ARMv5T)
14163 return BXWritePC(context, addr);
14164 else
14165 return BranchWritePC((const Context)context, addr);
14166 }
14167
14168 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14169 // versions and current instruction set.
ALUWritePC(Context & context,uint32_t addr)14170 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
14171 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
14172 return BXWritePC(context, addr);
14173 else
14174 return BranchWritePC((const Context)context, addr);
14175 }
14176
CurrentInstrSet()14177 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
14178 return m_opcode_mode;
14179 }
14180
14181 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next
14182 // ReadInstruction() is performed. This function has a side effect of updating
14183 // the m_new_inst_cpsr member variable if necessary.
SelectInstrSet(Mode arm_or_thumb)14184 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
14185 m_new_inst_cpsr = m_opcode_cpsr;
14186 switch (arm_or_thumb) {
14187 default:
14188 return false;
14189 case eModeARM:
14190 // Clear the T bit.
14191 m_new_inst_cpsr &= ~MASK_CPSR_T;
14192 break;
14193 case eModeThumb:
14194 // Set the T bit.
14195 m_new_inst_cpsr |= MASK_CPSR_T;
14196 break;
14197 }
14198 return true;
14199 }
14200
14201 // This function returns TRUE if the processor currently provides support for
14202 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
14203 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
UnalignedSupport()14204 bool EmulateInstructionARM::UnalignedSupport() {
14205 return (ArchVersion() >= ARMv7);
14206 }
14207
14208 // The main addition and subtraction instructions can produce status
14209 // information about both unsigned carry and signed overflow conditions. This
14210 // status information can be used to synthesize multi-word additions and
14211 // subtractions.
14212 EmulateInstructionARM::AddWithCarryResult
AddWithCarry(uint32_t x,uint32_t y,uint8_t carry_in)14213 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
14214 uint32_t result;
14215 uint8_t carry_out;
14216 uint8_t overflow;
14217
14218 uint64_t unsigned_sum = x + y + carry_in;
14219 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
14220
14221 result = UnsignedBits(unsigned_sum, 31, 0);
14222 // carry_out = (result == unsigned_sum ? 0 : 1);
14223 overflow = ((int32_t)result == signed_sum ? 0 : 1);
14224
14225 if (carry_in)
14226 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
14227 else
14228 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
14229
14230 AddWithCarryResult res = {result, carry_out, overflow};
14231 return res;
14232 }
14233
ReadCoreReg(uint32_t num,bool * success)14234 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
14235 lldb::RegisterKind reg_kind;
14236 uint32_t reg_num;
14237 switch (num) {
14238 case SP_REG:
14239 reg_kind = eRegisterKindGeneric;
14240 reg_num = LLDB_REGNUM_GENERIC_SP;
14241 break;
14242 case LR_REG:
14243 reg_kind = eRegisterKindGeneric;
14244 reg_num = LLDB_REGNUM_GENERIC_RA;
14245 break;
14246 case PC_REG:
14247 reg_kind = eRegisterKindGeneric;
14248 reg_num = LLDB_REGNUM_GENERIC_PC;
14249 break;
14250 default:
14251 if (num < SP_REG) {
14252 reg_kind = eRegisterKindDWARF;
14253 reg_num = dwarf_r0 + num;
14254 } else {
14255 // assert(0 && "Invalid register number");
14256 *success = false;
14257 return UINT32_MAX;
14258 }
14259 break;
14260 }
14261
14262 // Read our register.
14263 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
14264
14265 // When executing an ARM instruction , PC reads as the address of the current
14266 // instruction plus 8. When executing a Thumb instruction , PC reads as the
14267 // address of the current instruction plus 4.
14268 if (num == 15) {
14269 if (CurrentInstrSet() == eModeARM)
14270 val += 8;
14271 else
14272 val += 4;
14273 }
14274
14275 return val;
14276 }
14277
14278 // Write the result to the ARM core register Rd, and optionally update the
14279 // condition flags based on the result.
14280 //
14281 // This helper method tries to encapsulate the following pseudocode from the
14282 // ARM Architecture Reference Manual:
14283 //
14284 // if d == 15 then // Can only occur for encoding A1
14285 // ALUWritePC(result); // setflags is always FALSE here
14286 // else
14287 // R[d] = result;
14288 // if setflags then
14289 // APSR.N = result<31>;
14290 // APSR.Z = IsZeroBit(result);
14291 // APSR.C = carry;
14292 // // APSR.V unchanged
14293 //
14294 // In the above case, the API client does not pass in the overflow arg, which
14295 // defaults to ~0u.
WriteCoreRegOptionalFlags(Context & context,const uint32_t result,const uint32_t Rd,bool setflags,const uint32_t carry,const uint32_t overflow)14296 bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
14297 Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
14298 const uint32_t carry, const uint32_t overflow) {
14299 if (Rd == 15) {
14300 if (!ALUWritePC(context, result))
14301 return false;
14302 } else {
14303 lldb::RegisterKind reg_kind;
14304 uint32_t reg_num;
14305 switch (Rd) {
14306 case SP_REG:
14307 reg_kind = eRegisterKindGeneric;
14308 reg_num = LLDB_REGNUM_GENERIC_SP;
14309 break;
14310 case LR_REG:
14311 reg_kind = eRegisterKindGeneric;
14312 reg_num = LLDB_REGNUM_GENERIC_RA;
14313 break;
14314 default:
14315 reg_kind = eRegisterKindDWARF;
14316 reg_num = dwarf_r0 + Rd;
14317 }
14318 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
14319 return false;
14320 if (setflags)
14321 return WriteFlags(context, result, carry, overflow);
14322 }
14323 return true;
14324 }
14325
14326 // This helper method tries to encapsulate the following pseudocode from the
14327 // ARM Architecture Reference Manual:
14328 //
14329 // APSR.N = result<31>;
14330 // APSR.Z = IsZeroBit(result);
14331 // APSR.C = carry;
14332 // APSR.V = overflow
14333 //
14334 // Default arguments can be specified for carry and overflow parameters, which
14335 // means not to update the respective flags.
WriteFlags(Context & context,const uint32_t result,const uint32_t carry,const uint32_t overflow)14336 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
14337 const uint32_t carry,
14338 const uint32_t overflow) {
14339 m_new_inst_cpsr = m_opcode_cpsr;
14340 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
14341 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
14342 if (carry != ~0u)
14343 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
14344 if (overflow != ~0u)
14345 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
14346 if (m_new_inst_cpsr != m_opcode_cpsr) {
14347 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14348 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14349 return false;
14350 }
14351 return true;
14352 }
14353
EvaluateInstruction(uint32_t evaluate_options)14354 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
14355 ARMOpcode *opcode_data = NULL;
14356
14357 if (m_opcode_mode == eModeThumb)
14358 opcode_data =
14359 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14360 else if (m_opcode_mode == eModeARM)
14361 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14362
14363 const bool auto_advance_pc =
14364 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
14365 m_ignore_conditions =
14366 evaluate_options & eEmulateInstructionOptionIgnoreConditions;
14367
14368 bool success = false;
14369 if (m_opcode_cpsr == 0 || !m_ignore_conditions) {
14370 m_opcode_cpsr =
14371 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
14372 }
14373
14374 // Only return false if we are unable to read the CPSR if we care about
14375 // conditions
14376 if (!success && !m_ignore_conditions)
14377 return false;
14378
14379 uint32_t orig_pc_value = 0;
14380 if (auto_advance_pc) {
14381 orig_pc_value =
14382 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14383 if (!success)
14384 return false;
14385 }
14386
14387 // Call the Emulate... function if we managed to decode the opcode.
14388 if (opcode_data) {
14389 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
14390 opcode_data->encoding);
14391 if (!success)
14392 return false;
14393 }
14394
14395 // Advance the ITSTATE bits to their values for the next instruction if we
14396 // haven't just executed an IT instruction what initialized it.
14397 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
14398 (opcode_data == nullptr ||
14399 opcode_data->callback != &EmulateInstructionARM::EmulateIT))
14400 m_it_session.ITAdvance();
14401
14402 if (auto_advance_pc) {
14403 uint32_t after_pc_value =
14404 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14405 if (!success)
14406 return false;
14407
14408 if (auto_advance_pc && (after_pc_value == orig_pc_value)) {
14409 after_pc_value += m_opcode.GetByteSize();
14410
14411 EmulateInstruction::Context context;
14412 context.type = eContextAdvancePC;
14413 context.SetNoArgs();
14414 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
14415 after_pc_value))
14416 return false;
14417 }
14418 }
14419 return true;
14420 }
14421
14422 EmulateInstruction::InstructionCondition
GetInstructionCondition()14423 EmulateInstructionARM::GetInstructionCondition() {
14424 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
14425 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
14426 return EmulateInstruction::UnconditionalCondition;
14427 return cond;
14428 }
14429
TestEmulation(Stream * out_stream,ArchSpec & arch,OptionValueDictionary * test_data)14430 bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch,
14431 OptionValueDictionary *test_data) {
14432 if (!test_data) {
14433 out_stream->Printf("TestEmulation: Missing test data.\n");
14434 return false;
14435 }
14436
14437 static ConstString opcode_key("opcode");
14438 static ConstString before_key("before_state");
14439 static ConstString after_key("after_state");
14440
14441 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
14442
14443 uint32_t test_opcode;
14444 if ((value_sp.get() == NULL) ||
14445 (value_sp->GetType() != OptionValue::eTypeUInt64)) {
14446 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n");
14447 return false;
14448 }
14449 test_opcode = value_sp->GetUInt64Value();
14450
14451 if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
14452 arch.IsAlwaysThumbInstructions()) {
14453 m_opcode_mode = eModeThumb;
14454 if (test_opcode < 0x10000)
14455 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
14456 else
14457 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14458 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
14459 m_opcode_mode = eModeARM;
14460 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14461 } else {
14462 out_stream->Printf("TestEmulation: Invalid arch.\n");
14463 return false;
14464 }
14465
14466 EmulationStateARM before_state;
14467 EmulationStateARM after_state;
14468
14469 value_sp = test_data->GetValueForKey(before_key);
14470 if ((value_sp.get() == NULL) ||
14471 (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14472 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n");
14473 return false;
14474 }
14475
14476 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
14477 if (!before_state.LoadStateFromDictionary(state_dictionary)) {
14478 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n");
14479 return false;
14480 }
14481
14482 value_sp = test_data->GetValueForKey(after_key);
14483 if ((value_sp.get() == NULL) ||
14484 (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14485 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n");
14486 return false;
14487 }
14488
14489 state_dictionary = value_sp->GetAsDictionary();
14490 if (!after_state.LoadStateFromDictionary(state_dictionary)) {
14491 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n");
14492 return false;
14493 }
14494
14495 SetBaton((void *)&before_state);
14496 SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
14497 &EmulationStateARM::WritePseudoMemory,
14498 &EmulationStateARM::ReadPseudoRegister,
14499 &EmulationStateARM::WritePseudoRegister);
14500
14501 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
14502 if (!success) {
14503 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n");
14504 return false;
14505 }
14506
14507 success = before_state.CompareState(after_state);
14508 if (!success)
14509 out_stream->Printf(
14510 "TestEmulation: 'before' and 'after' states do not match.\n");
14511
14512 return success;
14513 }
14514 //
14515 //
14516 // const char *
14517 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
14518 //{
14519 // if (reg_kind == eRegisterKindGeneric)
14520 // {
14521 // switch (reg_num)
14522 // {
14523 // case LLDB_REGNUM_GENERIC_PC: return "pc";
14524 // case LLDB_REGNUM_GENERIC_SP: return "sp";
14525 // case LLDB_REGNUM_GENERIC_FP: return "fp";
14526 // case LLDB_REGNUM_GENERIC_RA: return "lr";
14527 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
14528 // default: return NULL;
14529 // }
14530 // }
14531 // else if (reg_kind == eRegisterKindDWARF)
14532 // {
14533 // return GetARMDWARFRegisterName (reg_num);
14534 // }
14535 // return NULL;
14536 //}
14537 //
CreateFunctionEntryUnwind(UnwindPlan & unwind_plan)14538 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
14539 unwind_plan.Clear();
14540 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
14541
14542 UnwindPlan::RowSP row(new UnwindPlan::Row);
14543
14544 // Our previous Call Frame Address is the stack pointer
14545 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
14546
14547 unwind_plan.AppendRow(row);
14548 unwind_plan.SetSourceName("EmulateInstructionARM");
14549 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
14550 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
14551 unwind_plan.SetReturnAddressRegister(dwarf_lr);
14552 return true;
14553 }
14554