EmulateInstructionARM.cpp revision 360784
1187692Snwhitehorn//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2187692Snwhitehorn//
3187692Snwhitehorn// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4187692Snwhitehorn// See https://llvm.org/LICENSE.txt for license information.
5187692Snwhitehorn// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6187692Snwhitehorn//
7187692Snwhitehorn//===----------------------------------------------------------------------===//
8187692Snwhitehorn
9187692Snwhitehorn#include <stdlib.h>
10187692Snwhitehorn
11187692Snwhitehorn#include "EmulateInstructionARM.h"
12187692Snwhitehorn#include "EmulationStateARM.h"
13187692Snwhitehorn#include "lldb/Core/Address.h"
14187692Snwhitehorn#include "lldb/Core/PluginManager.h"
15187692Snwhitehorn#include "lldb/Host/PosixApi.h"
16187692Snwhitehorn#include "lldb/Interpreter/OptionValueArray.h"
17187692Snwhitehorn#include "lldb/Interpreter/OptionValueDictionary.h"
18187692Snwhitehorn#include "lldb/Symbol/UnwindPlan.h"
19187692Snwhitehorn#include "lldb/Utility/ArchSpec.h"
20187692Snwhitehorn#include "lldb/Utility/ConstString.h"
21187692Snwhitehorn#include "lldb/Utility/Stream.h"
22187692Snwhitehorn
23187692Snwhitehorn#include "Plugins/Process/Utility/ARMDefines.h"
24187692Snwhitehorn#include "Plugins/Process/Utility/ARMUtils.h"
25187692Snwhitehorn#include "Utility/ARM_DWARF_Registers.h"
26187692Snwhitehorn
27187692Snwhitehorn#include "llvm/ADT/STLExtras.h"
28187692Snwhitehorn#include "llvm/Support/MathExtras.h"
29187692Snwhitehorn
30187692Snwhitehornusing namespace lldb;
31187692Snwhitehornusing namespace lldb_private;
32187692Snwhitehorn
33187692Snwhitehorn// Convenient macro definitions.
34187692Snwhitehorn#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
35187692Snwhitehorn#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
36187692Snwhitehorn
37187692Snwhitehorn#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
38187692Snwhitehorn
39187692Snwhitehorn//
40187692Snwhitehorn// ITSession implementation
41187692Snwhitehorn//
42187692Snwhitehorn
43187692Snwhitehornstatic bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo &reg_info) {
44187692Snwhitehorn  ::memset(&reg_info, 0, sizeof(RegisterInfo));
45187692Snwhitehorn  ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
46187692Snwhitehorn
47187692Snwhitehorn  if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) {
48187692Snwhitehorn    reg_info.byte_size = 16;
49187692Snwhitehorn    reg_info.format = eFormatVectorOfUInt8;
50187692Snwhitehorn    reg_info.encoding = eEncodingVector;
51187692Snwhitehorn  }
52187692Snwhitehorn
53187692Snwhitehorn  if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) {
54187692Snwhitehorn    reg_info.byte_size = 8;
55187692Snwhitehorn    reg_info.format = eFormatFloat;
56187692Snwhitehorn    reg_info.encoding = eEncodingIEEE754;
57187692Snwhitehorn  } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) {
58187692Snwhitehorn    reg_info.byte_size = 4;
59187692Snwhitehorn    reg_info.format = eFormatFloat;
60187692Snwhitehorn    reg_info.encoding = eEncodingIEEE754;
61187692Snwhitehorn  } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) {
62187692Snwhitehorn    reg_info.byte_size = 12;
63187692Snwhitehorn    reg_info.format = eFormatFloat;
64187692Snwhitehorn    reg_info.encoding = eEncodingIEEE754;
65187692Snwhitehorn  } else {
66187692Snwhitehorn    reg_info.byte_size = 4;
67187692Snwhitehorn    reg_info.format = eFormatHex;
68187692Snwhitehorn    reg_info.encoding = eEncodingUint;
69187692Snwhitehorn  }
70187692Snwhitehorn
71187692Snwhitehorn  reg_info.kinds[eRegisterKindDWARF] = reg_num;
72187692Snwhitehorn
73187692Snwhitehorn  switch (reg_num) {
74187692Snwhitehorn  case dwarf_r0:
75187692Snwhitehorn    reg_info.name = "r0";
76187692Snwhitehorn    break;
77187692Snwhitehorn  case dwarf_r1:
78193640Sariff    reg_info.name = "r1";
79193640Sariff    break;
80193640Sariff  case dwarf_r2:
81193640Sariff    reg_info.name = "r2";
82193640Sariff    break;
83187692Snwhitehorn  case dwarf_r3:
84193640Sariff    reg_info.name = "r3";
85187692Snwhitehorn    break;
86187692Snwhitehorn  case dwarf_r4:
87187692Snwhitehorn    reg_info.name = "r4";
88187692Snwhitehorn    break;
89187692Snwhitehorn  case dwarf_r5:
90187692Snwhitehorn    reg_info.name = "r5";
91187692Snwhitehorn    break;
92187692Snwhitehorn  case dwarf_r6:
93187692Snwhitehorn    reg_info.name = "r6";
94187692Snwhitehorn    break;
95187692Snwhitehorn  case dwarf_r7:
96187692Snwhitehorn    reg_info.name = "r7";
97187692Snwhitehorn    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
98187692Snwhitehorn    break;
99193694Sariff  case dwarf_r8:
100187692Snwhitehorn    reg_info.name = "r8";
101187692Snwhitehorn    break;
102187692Snwhitehorn  case dwarf_r9:
103193640Sariff    reg_info.name = "r9";
104187692Snwhitehorn    break;
105187692Snwhitehorn  case dwarf_r10:
106187692Snwhitehorn    reg_info.name = "r10";
107187692Snwhitehorn    break;
108187692Snwhitehorn  case dwarf_r11:
109187692Snwhitehorn    reg_info.name = "r11";
110187692Snwhitehorn    break;
111187692Snwhitehorn  case dwarf_r12:
112187692Snwhitehorn    reg_info.name = "r12";
113187692Snwhitehorn    break;
114187692Snwhitehorn  case dwarf_sp:
115187692Snwhitehorn    reg_info.name = "sp";
116187692Snwhitehorn    reg_info.alt_name = "r13";
117187692Snwhitehorn    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
118187692Snwhitehorn    break;
119187692Snwhitehorn  case dwarf_lr:
120187692Snwhitehorn    reg_info.name = "lr";
121187692Snwhitehorn    reg_info.alt_name = "r14";
122187692Snwhitehorn    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
123187692Snwhitehorn    break;
124187692Snwhitehorn  case dwarf_pc:
125187692Snwhitehorn    reg_info.name = "pc";
126187692Snwhitehorn    reg_info.alt_name = "r15";
127187692Snwhitehorn    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
128187692Snwhitehorn    break;
129187692Snwhitehorn  case dwarf_cpsr:
130193640Sariff    reg_info.name = "cpsr";
131187692Snwhitehorn    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
132187692Snwhitehorn    break;
133187692Snwhitehorn
134187692Snwhitehorn  case dwarf_s0:
135187692Snwhitehorn    reg_info.name = "s0";
136187692Snwhitehorn    break;
137187692Snwhitehorn  case dwarf_s1:
138187692Snwhitehorn    reg_info.name = "s1";
139187692Snwhitehorn    break;
140187692Snwhitehorn  case dwarf_s2:
141187692Snwhitehorn    reg_info.name = "s2";
142187692Snwhitehorn    break;
143187692Snwhitehorn  case dwarf_s3:
144187692Snwhitehorn    reg_info.name = "s3";
145187692Snwhitehorn    break;
146187692Snwhitehorn  case dwarf_s4:
147187692Snwhitehorn    reg_info.name = "s4";
148187692Snwhitehorn    break;
149187692Snwhitehorn  case dwarf_s5:
150187692Snwhitehorn    reg_info.name = "s5";
151187692Snwhitehorn    break;
152187692Snwhitehorn  case dwarf_s6:
153187692Snwhitehorn    reg_info.name = "s6";
154187692Snwhitehorn    break;
155187692Snwhitehorn  case dwarf_s7:
156187692Snwhitehorn    reg_info.name = "s7";
157187692Snwhitehorn    break;
158187692Snwhitehorn  case dwarf_s8:
159187692Snwhitehorn    reg_info.name = "s8";
160187692Snwhitehorn    break;
161187692Snwhitehorn  case dwarf_s9:
162187692Snwhitehorn    reg_info.name = "s9";
163187692Snwhitehorn    break;
164187692Snwhitehorn  case dwarf_s10:
165187692Snwhitehorn    reg_info.name = "s10";
166187692Snwhitehorn    break;
167187692Snwhitehorn  case dwarf_s11:
168187692Snwhitehorn    reg_info.name = "s11";
169187692Snwhitehorn    break;
170187692Snwhitehorn  case dwarf_s12:
171187692Snwhitehorn    reg_info.name = "s12";
172187692Snwhitehorn    break;
173187692Snwhitehorn  case dwarf_s13:
174187692Snwhitehorn    reg_info.name = "s13";
175187692Snwhitehorn    break;
176187692Snwhitehorn  case dwarf_s14:
177187692Snwhitehorn    reg_info.name = "s14";
178187692Snwhitehorn    break;
179187692Snwhitehorn  case dwarf_s15:
180187692Snwhitehorn    reg_info.name = "s15";
181187692Snwhitehorn    break;
182187692Snwhitehorn  case dwarf_s16:
183187692Snwhitehorn    reg_info.name = "s16";
184187692Snwhitehorn    break;
185187692Snwhitehorn  case dwarf_s17:
186187692Snwhitehorn    reg_info.name = "s17";
187187692Snwhitehorn    break;
188187692Snwhitehorn  case dwarf_s18:
189187692Snwhitehorn    reg_info.name = "s18";
190187692Snwhitehorn    break;
191187692Snwhitehorn  case dwarf_s19:
192187692Snwhitehorn    reg_info.name = "s19";
193187692Snwhitehorn    break;
194187692Snwhitehorn  case dwarf_s20:
195187692Snwhitehorn    reg_info.name = "s20";
196187692Snwhitehorn    break;
197187692Snwhitehorn  case dwarf_s21:
198187692Snwhitehorn    reg_info.name = "s21";
199187692Snwhitehorn    break;
200187692Snwhitehorn  case dwarf_s22:
201187692Snwhitehorn    reg_info.name = "s22";
202187692Snwhitehorn    break;
203187692Snwhitehorn  case dwarf_s23:
204187692Snwhitehorn    reg_info.name = "s23";
205187692Snwhitehorn    break;
206187692Snwhitehorn  case dwarf_s24:
207187692Snwhitehorn    reg_info.name = "s24";
208187692Snwhitehorn    break;
209187692Snwhitehorn  case dwarf_s25:
210187692Snwhitehorn    reg_info.name = "s25";
211187692Snwhitehorn    break;
212187692Snwhitehorn  case dwarf_s26:
213187692Snwhitehorn    reg_info.name = "s26";
214187692Snwhitehorn    break;
215187692Snwhitehorn  case dwarf_s27:
216187692Snwhitehorn    reg_info.name = "s27";
217187692Snwhitehorn    break;
218187692Snwhitehorn  case dwarf_s28:
219187692Snwhitehorn    reg_info.name = "s28";
220187692Snwhitehorn    break;
221187692Snwhitehorn  case dwarf_s29:
222187692Snwhitehorn    reg_info.name = "s29";
223187692Snwhitehorn    break;
224187692Snwhitehorn  case dwarf_s30:
225187692Snwhitehorn    reg_info.name = "s30";
226187692Snwhitehorn    break;
227187692Snwhitehorn  case dwarf_s31:
228187692Snwhitehorn    reg_info.name = "s31";
229187692Snwhitehorn    break;
230187692Snwhitehorn
231187692Snwhitehorn  // FPA Registers 0-7
232187692Snwhitehorn  case dwarf_f0:
233187692Snwhitehorn    reg_info.name = "f0";
234187692Snwhitehorn    break;
235187692Snwhitehorn  case dwarf_f1:
236187692Snwhitehorn    reg_info.name = "f1";
237187692Snwhitehorn    break;
238187692Snwhitehorn  case dwarf_f2:
239187692Snwhitehorn    reg_info.name = "f2";
240187692Snwhitehorn    break;
241187692Snwhitehorn  case dwarf_f3:
242187692Snwhitehorn    reg_info.name = "f3";
243187692Snwhitehorn    break;
244187692Snwhitehorn  case dwarf_f4:
245187692Snwhitehorn    reg_info.name = "f4";
246187692Snwhitehorn    break;
247187692Snwhitehorn  case dwarf_f5:
248187692Snwhitehorn    reg_info.name = "f5";
249187692Snwhitehorn    break;
250187692Snwhitehorn  case dwarf_f6:
251187692Snwhitehorn    reg_info.name = "f6";
252187692Snwhitehorn    break;
253187692Snwhitehorn  case dwarf_f7:
254187692Snwhitehorn    reg_info.name = "f7";
255187692Snwhitehorn    break;
256187692Snwhitehorn
257187692Snwhitehorn  // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator
258187692Snwhitehorn  // register 0 - 7 (they do overlap with wCGR0 - wCGR7)
259187692Snwhitehorn  case dwarf_wCGR0:
260187692Snwhitehorn    reg_info.name = "wCGR0/ACC0";
261187692Snwhitehorn    break;
262187692Snwhitehorn  case dwarf_wCGR1:
263187692Snwhitehorn    reg_info.name = "wCGR1/ACC1";
264187692Snwhitehorn    break;
265187692Snwhitehorn  case dwarf_wCGR2:
266187692Snwhitehorn    reg_info.name = "wCGR2/ACC2";
267187692Snwhitehorn    break;
268187692Snwhitehorn  case dwarf_wCGR3:
269187692Snwhitehorn    reg_info.name = "wCGR3/ACC3";
270187692Snwhitehorn    break;
271187692Snwhitehorn  case dwarf_wCGR4:
272187692Snwhitehorn    reg_info.name = "wCGR4/ACC4";
273187692Snwhitehorn    break;
274187692Snwhitehorn  case dwarf_wCGR5:
275187692Snwhitehorn    reg_info.name = "wCGR5/ACC5";
276187692Snwhitehorn    break;
277187692Snwhitehorn  case dwarf_wCGR6:
278187692Snwhitehorn    reg_info.name = "wCGR6/ACC6";
279187692Snwhitehorn    break;
280187692Snwhitehorn  case dwarf_wCGR7:
281187692Snwhitehorn    reg_info.name = "wCGR7/ACC7";
282187692Snwhitehorn    break;
283187692Snwhitehorn
284187692Snwhitehorn  // Intel wireless MMX data registers 0 - 15
285187692Snwhitehorn  case dwarf_wR0:
286187692Snwhitehorn    reg_info.name = "wR0";
287187692Snwhitehorn    break;
288187692Snwhitehorn  case dwarf_wR1:
289187692Snwhitehorn    reg_info.name = "wR1";
290187692Snwhitehorn    break;
291187692Snwhitehorn  case dwarf_wR2:
292187692Snwhitehorn    reg_info.name = "wR2";
293187692Snwhitehorn    break;
294187692Snwhitehorn  case dwarf_wR3:
295187692Snwhitehorn    reg_info.name = "wR3";
296187692Snwhitehorn    break;
297187692Snwhitehorn  case dwarf_wR4:
298187692Snwhitehorn    reg_info.name = "wR4";
299187692Snwhitehorn    break;
300187692Snwhitehorn  case dwarf_wR5:
301187692Snwhitehorn    reg_info.name = "wR5";
302187692Snwhitehorn    break;
303187692Snwhitehorn  case dwarf_wR6:
304187692Snwhitehorn    reg_info.name = "wR6";
305187692Snwhitehorn    break;
306187692Snwhitehorn  case dwarf_wR7:
307187692Snwhitehorn    reg_info.name = "wR7";
308187692Snwhitehorn    break;
309187692Snwhitehorn  case dwarf_wR8:
310187692Snwhitehorn    reg_info.name = "wR8";
311187692Snwhitehorn    break;
312187692Snwhitehorn  case dwarf_wR9:
313187692Snwhitehorn    reg_info.name = "wR9";
314187692Snwhitehorn    break;
315187692Snwhitehorn  case dwarf_wR10:
316187692Snwhitehorn    reg_info.name = "wR10";
317187692Snwhitehorn    break;
318187692Snwhitehorn  case dwarf_wR11:
319187692Snwhitehorn    reg_info.name = "wR11";
320187692Snwhitehorn    break;
321187692Snwhitehorn  case dwarf_wR12:
322187692Snwhitehorn    reg_info.name = "wR12";
323187692Snwhitehorn    break;
324187692Snwhitehorn  case dwarf_wR13:
325187692Snwhitehorn    reg_info.name = "wR13";
326187692Snwhitehorn    break;
327187692Snwhitehorn  case dwarf_wR14:
328187692Snwhitehorn    reg_info.name = "wR14";
329187692Snwhitehorn    break;
330187692Snwhitehorn  case dwarf_wR15:
331187692Snwhitehorn    reg_info.name = "wR15";
332187692Snwhitehorn    break;
333187692Snwhitehorn
334187692Snwhitehorn  case dwarf_spsr:
335187692Snwhitehorn    reg_info.name = "spsr";
336187692Snwhitehorn    break;
337187692Snwhitehorn  case dwarf_spsr_fiq:
338187692Snwhitehorn    reg_info.name = "spsr_fiq";
339187692Snwhitehorn    break;
340187692Snwhitehorn  case dwarf_spsr_irq:
341187692Snwhitehorn    reg_info.name = "spsr_irq";
342187692Snwhitehorn    break;
343187692Snwhitehorn  case dwarf_spsr_abt:
344187692Snwhitehorn    reg_info.name = "spsr_abt";
345187692Snwhitehorn    break;
346187692Snwhitehorn  case dwarf_spsr_und:
347187692Snwhitehorn    reg_info.name = "spsr_und";
348187692Snwhitehorn    break;
349187692Snwhitehorn  case dwarf_spsr_svc:
350187692Snwhitehorn    reg_info.name = "spsr_svc";
351187692Snwhitehorn    break;
352187692Snwhitehorn
353187692Snwhitehorn  case dwarf_r8_usr:
354187692Snwhitehorn    reg_info.name = "r8_usr";
355187692Snwhitehorn    break;
356187692Snwhitehorn  case dwarf_r9_usr:
357187692Snwhitehorn    reg_info.name = "r9_usr";
358187692Snwhitehorn    break;
359187692Snwhitehorn  case dwarf_r10_usr:
360187692Snwhitehorn    reg_info.name = "r10_usr";
361187692Snwhitehorn    break;
362187692Snwhitehorn  case dwarf_r11_usr:
363187692Snwhitehorn    reg_info.name = "r11_usr";
364187692Snwhitehorn    break;
365187692Snwhitehorn  case dwarf_r12_usr:
366187692Snwhitehorn    reg_info.name = "r12_usr";
367187692Snwhitehorn    break;
368187692Snwhitehorn  case dwarf_r13_usr:
369187692Snwhitehorn    reg_info.name = "r13_usr";
370187692Snwhitehorn    break;
371187692Snwhitehorn  case dwarf_r14_usr:
372193694Sariff    reg_info.name = "r14_usr";
373187692Snwhitehorn    break;
374187692Snwhitehorn  case dwarf_r8_fiq:
375193694Sariff    reg_info.name = "r8_fiq";
376187692Snwhitehorn    break;
377187692Snwhitehorn  case dwarf_r9_fiq:
378187692Snwhitehorn    reg_info.name = "r9_fiq";
379187692Snwhitehorn    break;
380187692Snwhitehorn  case dwarf_r10_fiq:
381187692Snwhitehorn    reg_info.name = "r10_fiq";
382187692Snwhitehorn    break;
383187692Snwhitehorn  case dwarf_r11_fiq:
384187692Snwhitehorn    reg_info.name = "r11_fiq";
385187692Snwhitehorn    break;
386187692Snwhitehorn  case dwarf_r12_fiq:
387187692Snwhitehorn    reg_info.name = "r12_fiq";
388188259Snwhitehorn    break;
389188259Snwhitehorn  case dwarf_r13_fiq:
390188259Snwhitehorn    reg_info.name = "r13_fiq";
391188259Snwhitehorn    break;
392187692Snwhitehorn  case dwarf_r14_fiq:
393187692Snwhitehorn    reg_info.name = "r14_fiq";
394188259Snwhitehorn    break;
395188259Snwhitehorn  case dwarf_r13_irq:
396187692Snwhitehorn    reg_info.name = "r13_irq";
397187692Snwhitehorn    break;
398187692Snwhitehorn  case dwarf_r14_irq:
399188259Snwhitehorn    reg_info.name = "r14_irq";
400188259Snwhitehorn    break;
401188259Snwhitehorn  case dwarf_r13_abt:
402188259Snwhitehorn    reg_info.name = "r13_abt";
403188259Snwhitehorn    break;
404188259Snwhitehorn  case dwarf_r14_abt:
405188259Snwhitehorn    reg_info.name = "r14_abt";
406188259Snwhitehorn    break;
407188259Snwhitehorn  case dwarf_r13_und:
408188259Snwhitehorn    reg_info.name = "r13_und";
409188259Snwhitehorn    break;
410188259Snwhitehorn  case dwarf_r14_und:
411188259Snwhitehorn    reg_info.name = "r14_und";
412188259Snwhitehorn    break;
413188259Snwhitehorn  case dwarf_r13_svc:
414188259Snwhitehorn    reg_info.name = "r13_svc";
415188259Snwhitehorn    break;
416188259Snwhitehorn  case dwarf_r14_svc:
417188259Snwhitehorn    reg_info.name = "r14_svc";
418188259Snwhitehorn    break;
419188259Snwhitehorn
420188259Snwhitehorn  // Intel wireless MMX control register in co-processor 0 - 7
421188259Snwhitehorn  case dwarf_wC0:
422188259Snwhitehorn    reg_info.name = "wC0";
423188259Snwhitehorn    break;
424188259Snwhitehorn  case dwarf_wC1:
425188259Snwhitehorn    reg_info.name = "wC1";
426188259Snwhitehorn    break;
427188259Snwhitehorn  case dwarf_wC2:
428187692Snwhitehorn    reg_info.name = "wC2";
429187692Snwhitehorn    break;
430187692Snwhitehorn  case dwarf_wC3:
431187692Snwhitehorn    reg_info.name = "wC3";
432187692Snwhitehorn    break;
433193640Sariff  case dwarf_wC4:
434187692Snwhitehorn    reg_info.name = "wC4";
435187692Snwhitehorn    break;
436187692Snwhitehorn  case dwarf_wC5:
437187692Snwhitehorn    reg_info.name = "wC5";
438187692Snwhitehorn    break;
439  case dwarf_wC6:
440    reg_info.name = "wC6";
441    break;
442  case dwarf_wC7:
443    reg_info.name = "wC7";
444    break;
445
446  // VFP-v3/Neon
447  case dwarf_d0:
448    reg_info.name = "d0";
449    break;
450  case dwarf_d1:
451    reg_info.name = "d1";
452    break;
453  case dwarf_d2:
454    reg_info.name = "d2";
455    break;
456  case dwarf_d3:
457    reg_info.name = "d3";
458    break;
459  case dwarf_d4:
460    reg_info.name = "d4";
461    break;
462  case dwarf_d5:
463    reg_info.name = "d5";
464    break;
465  case dwarf_d6:
466    reg_info.name = "d6";
467    break;
468  case dwarf_d7:
469    reg_info.name = "d7";
470    break;
471  case dwarf_d8:
472    reg_info.name = "d8";
473    break;
474  case dwarf_d9:
475    reg_info.name = "d9";
476    break;
477  case dwarf_d10:
478    reg_info.name = "d10";
479    break;
480  case dwarf_d11:
481    reg_info.name = "d11";
482    break;
483  case dwarf_d12:
484    reg_info.name = "d12";
485    break;
486  case dwarf_d13:
487    reg_info.name = "d13";
488    break;
489  case dwarf_d14:
490    reg_info.name = "d14";
491    break;
492  case dwarf_d15:
493    reg_info.name = "d15";
494    break;
495  case dwarf_d16:
496    reg_info.name = "d16";
497    break;
498  case dwarf_d17:
499    reg_info.name = "d17";
500    break;
501  case dwarf_d18:
502    reg_info.name = "d18";
503    break;
504  case dwarf_d19:
505    reg_info.name = "d19";
506    break;
507  case dwarf_d20:
508    reg_info.name = "d20";
509    break;
510  case dwarf_d21:
511    reg_info.name = "d21";
512    break;
513  case dwarf_d22:
514    reg_info.name = "d22";
515    break;
516  case dwarf_d23:
517    reg_info.name = "d23";
518    break;
519  case dwarf_d24:
520    reg_info.name = "d24";
521    break;
522  case dwarf_d25:
523    reg_info.name = "d25";
524    break;
525  case dwarf_d26:
526    reg_info.name = "d26";
527    break;
528  case dwarf_d27:
529    reg_info.name = "d27";
530    break;
531  case dwarf_d28:
532    reg_info.name = "d28";
533    break;
534  case dwarf_d29:
535    reg_info.name = "d29";
536    break;
537  case dwarf_d30:
538    reg_info.name = "d30";
539    break;
540  case dwarf_d31:
541    reg_info.name = "d31";
542    break;
543
544  // NEON 128-bit vector registers (overlays the d registers)
545  case dwarf_q0:
546    reg_info.name = "q0";
547    break;
548  case dwarf_q1:
549    reg_info.name = "q1";
550    break;
551  case dwarf_q2:
552    reg_info.name = "q2";
553    break;
554  case dwarf_q3:
555    reg_info.name = "q3";
556    break;
557  case dwarf_q4:
558    reg_info.name = "q4";
559    break;
560  case dwarf_q5:
561    reg_info.name = "q5";
562    break;
563  case dwarf_q6:
564    reg_info.name = "q6";
565    break;
566  case dwarf_q7:
567    reg_info.name = "q7";
568    break;
569  case dwarf_q8:
570    reg_info.name = "q8";
571    break;
572  case dwarf_q9:
573    reg_info.name = "q9";
574    break;
575  case dwarf_q10:
576    reg_info.name = "q10";
577    break;
578  case dwarf_q11:
579    reg_info.name = "q11";
580    break;
581  case dwarf_q12:
582    reg_info.name = "q12";
583    break;
584  case dwarf_q13:
585    reg_info.name = "q13";
586    break;
587  case dwarf_q14:
588    reg_info.name = "q14";
589    break;
590  case dwarf_q15:
591    reg_info.name = "q15";
592    break;
593
594  default:
595    return false;
596  }
597  return true;
598}
599
600// A8.6.50
601// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
602static uint32_t CountITSize(uint32_t ITMask) {
603  // First count the trailing zeros of the IT mask.
604  uint32_t TZ = llvm::countTrailingZeros(ITMask);
605  if (TZ > 3) {
606#ifdef LLDB_CONFIGURATION_DEBUG
607    printf("Encoding error: IT Mask '0000'\n");
608#endif
609    return 0;
610  }
611  return (4 - TZ);
612}
613
614// Init ITState.  Note that at least one bit is always 1 in mask.
615bool ITSession::InitIT(uint32_t bits7_0) {
616  ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
617  if (ITCounter == 0)
618    return false;
619
620  // A8.6.50 IT
621  unsigned short FirstCond = Bits32(bits7_0, 7, 4);
622  if (FirstCond == 0xF) {
623#ifdef LLDB_CONFIGURATION_DEBUG
624    printf("Encoding error: IT FirstCond '1111'\n");
625#endif
626    return false;
627  }
628  if (FirstCond == 0xE && ITCounter != 1) {
629#ifdef LLDB_CONFIGURATION_DEBUG
630    printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
631#endif
632    return false;
633  }
634
635  ITState = bits7_0;
636  return true;
637}
638
639// Update ITState if necessary.
640void ITSession::ITAdvance() {
641  // assert(ITCounter);
642  --ITCounter;
643  if (ITCounter == 0)
644    ITState = 0;
645  else {
646    unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
647    SetBits32(ITState, 4, 0, NewITState4_0);
648  }
649}
650
651// Return true if we're inside an IT Block.
652bool ITSession::InITBlock() { return ITCounter != 0; }
653
654// Return true if we're the last instruction inside an IT Block.
655bool ITSession::LastInITBlock() { return ITCounter == 1; }
656
657// Get condition bits for the current thumb instruction.
658uint32_t ITSession::GetCond() {
659  if (InITBlock())
660    return Bits32(ITState, 7, 4);
661  else
662    return COND_AL;
663}
664
665// ARM constants used during decoding
666#define REG_RD 0
667#define LDM_REGLIST 1
668#define SP_REG 13
669#define LR_REG 14
670#define PC_REG 15
671#define PC_REGLIST_BIT 0x8000
672
673#define ARMv4 (1u << 0)
674#define ARMv4T (1u << 1)
675#define ARMv5T (1u << 2)
676#define ARMv5TE (1u << 3)
677#define ARMv5TEJ (1u << 4)
678#define ARMv6 (1u << 5)
679#define ARMv6K (1u << 6)
680#define ARMv6T2 (1u << 7)
681#define ARMv7 (1u << 8)
682#define ARMv7S (1u << 9)
683#define ARMv8 (1u << 10)
684#define ARMvAll (0xffffffffu)
685
686#define ARMV4T_ABOVE                                                           \
687  (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 |   \
688   ARMv7S | ARMv8)
689#define ARMV5_ABOVE                                                            \
690  (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S |   \
691   ARMv8)
692#define ARMV5TE_ABOVE                                                          \
693  (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
694#define ARMV5J_ABOVE                                                           \
695  (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
696#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
697#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
698#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
699
700#define No_VFP 0
701#define VFPv1 (1u << 1)
702#define VFPv2 (1u << 2)
703#define VFPv3 (1u << 3)
704#define AdvancedSIMD (1u << 4)
705
706#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
707#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
708#define VFPv2v3 (VFPv2 | VFPv3)
709
710//
711// EmulateInstructionARM implementation
712//
713
714void EmulateInstructionARM::Initialize() {
715  PluginManager::RegisterPlugin(GetPluginNameStatic(),
716                                GetPluginDescriptionStatic(), CreateInstance);
717}
718
719void EmulateInstructionARM::Terminate() {
720  PluginManager::UnregisterPlugin(CreateInstance);
721}
722
723ConstString EmulateInstructionARM::GetPluginNameStatic() {
724  static ConstString g_name("arm");
725  return g_name;
726}
727
728const char *EmulateInstructionARM::GetPluginDescriptionStatic() {
729  return "Emulate instructions for the ARM architecture.";
730}
731
732EmulateInstruction *
733EmulateInstructionARM::CreateInstance(const ArchSpec &arch,
734                                      InstructionType inst_type) {
735  if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(
736          inst_type)) {
737    if (arch.GetTriple().getArch() == llvm::Triple::arm) {
738      std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
739          new EmulateInstructionARM(arch));
740
741      if (emulate_insn_up)
742        return emulate_insn_up.release();
743    } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) {
744      std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
745          new EmulateInstructionARM(arch));
746
747      if (emulate_insn_up)
748        return emulate_insn_up.release();
749    }
750  }
751
752  return nullptr;
753}
754
755bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) {
756  if (arch.GetTriple().getArch() == llvm::Triple::arm)
757    return true;
758  else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
759    return true;
760
761  return false;
762}
763
764// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for
765// many ARM instructions.
766bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) {
767  EmulateInstruction::Context context;
768  context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
769  context.SetNoArgs();
770
771  uint32_t random_data = rand();
772  const uint32_t addr_byte_size = GetAddressByteSize();
773
774  return MemAWrite(context, address, random_data, addr_byte_size);
775}
776
777// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM
778// instructions.
779bool EmulateInstructionARM::WriteBits32Unknown(int n) {
780  EmulateInstruction::Context context;
781  context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
782  context.SetNoArgs();
783
784  bool success;
785  uint32_t data =
786      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
787
788  if (!success)
789    return false;
790
791  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data))
792    return false;
793
794  return true;
795}
796
797bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind,
798                                            uint32_t reg_num,
799                                            RegisterInfo &reg_info) {
800  if (reg_kind == eRegisterKindGeneric) {
801    switch (reg_num) {
802    case LLDB_REGNUM_GENERIC_PC:
803      reg_kind = eRegisterKindDWARF;
804      reg_num = dwarf_pc;
805      break;
806    case LLDB_REGNUM_GENERIC_SP:
807      reg_kind = eRegisterKindDWARF;
808      reg_num = dwarf_sp;
809      break;
810    case LLDB_REGNUM_GENERIC_FP:
811      reg_kind = eRegisterKindDWARF;
812      reg_num = dwarf_r7;
813      break;
814    case LLDB_REGNUM_GENERIC_RA:
815      reg_kind = eRegisterKindDWARF;
816      reg_num = dwarf_lr;
817      break;
818    case LLDB_REGNUM_GENERIC_FLAGS:
819      reg_kind = eRegisterKindDWARF;
820      reg_num = dwarf_cpsr;
821      break;
822    default:
823      return false;
824    }
825  }
826
827  if (reg_kind == eRegisterKindDWARF)
828    return GetARMDWARFRegisterInfo(reg_num, reg_info);
829  return false;
830}
831
832uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
833  if (m_arch.GetTriple().isAndroid())
834    return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
835  bool is_apple = false;
836  if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
837    is_apple = true;
838  switch (m_arch.GetTriple().getOS()) {
839  case llvm::Triple::Darwin:
840  case llvm::Triple::MacOSX:
841  case llvm::Triple::IOS:
842  case llvm::Triple::TvOS:
843  case llvm::Triple::WatchOS:
844  // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
845    is_apple = true;
846    break;
847  default:
848    break;
849  }
850
851  /* On Apple iOS et al, the frame pointer register is always r7.
852   * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
853   * Windows on ARM, which is in thumb mode, uses r11 though.
854   */
855
856  uint32_t fp_regnum = 11;
857
858  if (is_apple)
859    fp_regnum = 7;
860
861  if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
862    fp_regnum = 7;
863
864  return fp_regnum;
865}
866
867uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
868  bool is_apple = false;
869  if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
870    is_apple = true;
871  switch (m_arch.GetTriple().getOS()) {
872  case llvm::Triple::Darwin:
873  case llvm::Triple::MacOSX:
874  case llvm::Triple::IOS:
875    is_apple = true;
876    break;
877  default:
878    break;
879  }
880
881  /* On Apple iOS et al, the frame pointer register is always r7.
882   * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
883   * Windows on ARM, which is in thumb mode, uses r11 though.
884   */
885
886  uint32_t fp_regnum = dwarf_r11;
887
888  if (is_apple)
889    fp_regnum = dwarf_r7;
890
891  if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
892    fp_regnum = dwarf_r7;
893
894  return fp_regnum;
895}
896
897// Push Multiple Registers stores multiple registers to the stack, storing to
898// consecutive memory locations ending just below the address in SP, and
899// updates
900// SP to point to the start of the stored data.
901bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
902                                        const ARMEncoding encoding) {
903#if 0
904    // ARM pseudo code...
905    if (ConditionPassed())
906    {
907        EncodingSpecificOperations();
908        NullCheckIfThumbEE(13);
909        address = SP - 4*BitCount(registers);
910
911        for (i = 0 to 14)
912        {
913            if (registers<i> == '1')
914            {
915                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
916                    MemA[address,4] = bits(32) UNKNOWN;
917                else
918                    MemA[address,4] = R[i];
919                address = address + 4;
920            }
921        }
922
923        if (registers<15> == '1') // Only possible for encoding A1 or A2
924            MemA[address,4] = PCStoreValue();
925
926        SP = SP - 4*BitCount(registers);
927    }
928#endif
929
930  bool success = false;
931  if (ConditionPassed(opcode)) {
932    const uint32_t addr_byte_size = GetAddressByteSize();
933    const addr_t sp = ReadCoreReg(SP_REG, &success);
934    if (!success)
935      return false;
936    uint32_t registers = 0;
937    uint32_t Rt; // the source register
938    switch (encoding) {
939    case eEncodingT1:
940      registers = Bits32(opcode, 7, 0);
941      // The M bit represents LR.
942      if (Bit32(opcode, 8))
943        registers |= (1u << 14);
944      // if BitCount(registers) < 1 then UNPREDICTABLE;
945      if (BitCount(registers) < 1)
946        return false;
947      break;
948    case eEncodingT2:
949      // Ignore bits 15 & 13.
950      registers = Bits32(opcode, 15, 0) & ~0xa000;
951      // if BitCount(registers) < 2 then UNPREDICTABLE;
952      if (BitCount(registers) < 2)
953        return false;
954      break;
955    case eEncodingT3:
956      Rt = Bits32(opcode, 15, 12);
957      // if BadReg(t) then UNPREDICTABLE;
958      if (BadReg(Rt))
959        return false;
960      registers = (1u << Rt);
961      break;
962    case eEncodingA1:
963      registers = Bits32(opcode, 15, 0);
964      // Instead of return false, let's handle the following case as well,
965      // which amounts to pushing one reg onto the full descending stacks.
966      // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
967      break;
968    case eEncodingA2:
969      Rt = Bits32(opcode, 15, 12);
970      // if t == 13 then UNPREDICTABLE;
971      if (Rt == dwarf_sp)
972        return false;
973      registers = (1u << Rt);
974      break;
975    default:
976      return false;
977    }
978    addr_t sp_offset = addr_byte_size * BitCount(registers);
979    addr_t addr = sp - sp_offset;
980    uint32_t i;
981
982    EmulateInstruction::Context context;
983    context.type = EmulateInstruction::eContextPushRegisterOnStack;
984    RegisterInfo reg_info;
985    RegisterInfo sp_reg;
986    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
987    for (i = 0; i < 15; ++i) {
988      if (BitIsSet(registers, i)) {
989        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info);
990        context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
991        uint32_t reg_value = ReadCoreReg(i, &success);
992        if (!success)
993          return false;
994        if (!MemAWrite(context, addr, reg_value, addr_byte_size))
995          return false;
996        addr += addr_byte_size;
997      }
998    }
999
1000    if (BitIsSet(registers, 15)) {
1001      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info);
1002      context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
1003      const uint32_t pc = ReadCoreReg(PC_REG, &success);
1004      if (!success)
1005        return false;
1006      if (!MemAWrite(context, addr, pc, addr_byte_size))
1007        return false;
1008    }
1009
1010    context.type = EmulateInstruction::eContextAdjustStackPointer;
1011    context.SetImmediateSigned(-sp_offset);
1012
1013    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1014                               LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1015      return false;
1016  }
1017  return true;
1018}
1019
1020// Pop Multiple Registers loads multiple registers from the stack, loading from
1021// consecutive memory locations staring at the address in SP, and updates
1022// SP to point just above the loaded data.
1023bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
1024                                       const ARMEncoding encoding) {
1025#if 0
1026    // ARM pseudo code...
1027    if (ConditionPassed())
1028    {
1029        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1030        address = SP;
1031        for i = 0 to 14
1032            if registers<i> == '1' then
1033                R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
1034        if registers<15> == '1' then
1035            if UnalignedAllowed then
1036                LoadWritePC(MemU[address,4]);
1037            else
1038                LoadWritePC(MemA[address,4]);
1039        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
1040        if registers<13> == '1' then SP = bits(32) UNKNOWN;
1041    }
1042#endif
1043
1044  bool success = false;
1045
1046  if (ConditionPassed(opcode)) {
1047    const uint32_t addr_byte_size = GetAddressByteSize();
1048    const addr_t sp = ReadCoreReg(SP_REG, &success);
1049    if (!success)
1050      return false;
1051    uint32_t registers = 0;
1052    uint32_t Rt; // the destination register
1053    switch (encoding) {
1054    case eEncodingT1:
1055      registers = Bits32(opcode, 7, 0);
1056      // The P bit represents PC.
1057      if (Bit32(opcode, 8))
1058        registers |= (1u << 15);
1059      // if BitCount(registers) < 1 then UNPREDICTABLE;
1060      if (BitCount(registers) < 1)
1061        return false;
1062      break;
1063    case eEncodingT2:
1064      // Ignore bit 13.
1065      registers = Bits32(opcode, 15, 0) & ~0x2000;
1066      // if BitCount(registers) < 2 || (P == '1' && M == '1') then
1067      // UNPREDICTABLE;
1068      if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
1069        return false;
1070      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
1071      // UNPREDICTABLE;
1072      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1073        return false;
1074      break;
1075    case eEncodingT3:
1076      Rt = Bits32(opcode, 15, 12);
1077      // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
1078      // UNPREDICTABLE;
1079      if (Rt == 13)
1080        return false;
1081      if (Rt == 15 && InITBlock() && !LastInITBlock())
1082        return false;
1083      registers = (1u << Rt);
1084      break;
1085    case eEncodingA1:
1086      registers = Bits32(opcode, 15, 0);
1087      // Instead of return false, let's handle the following case as well,
1088      // which amounts to popping one reg from the full descending stacks.
1089      // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
1090
1091      // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
1092      if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
1093        return false;
1094      break;
1095    case eEncodingA2:
1096      Rt = Bits32(opcode, 15, 12);
1097      // if t == 13 then UNPREDICTABLE;
1098      if (Rt == dwarf_sp)
1099        return false;
1100      registers = (1u << Rt);
1101      break;
1102    default:
1103      return false;
1104    }
1105    addr_t sp_offset = addr_byte_size * BitCount(registers);
1106    addr_t addr = sp;
1107    uint32_t i, data;
1108
1109    EmulateInstruction::Context context;
1110    context.type = EmulateInstruction::eContextPopRegisterOffStack;
1111
1112    RegisterInfo sp_reg;
1113    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1114
1115    for (i = 0; i < 15; ++i) {
1116      if (BitIsSet(registers, i)) {
1117        context.SetAddress(addr);
1118        data = MemARead(context, addr, 4, 0, &success);
1119        if (!success)
1120          return false;
1121        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
1122                                   data))
1123          return false;
1124        addr += addr_byte_size;
1125      }
1126    }
1127
1128    if (BitIsSet(registers, 15)) {
1129      context.SetRegisterPlusOffset(sp_reg, addr - sp);
1130      data = MemARead(context, addr, 4, 0, &success);
1131      if (!success)
1132        return false;
1133      // In ARMv5T and above, this is an interworking branch.
1134      if (!LoadWritePC(context, data))
1135        return false;
1136      // addr += addr_byte_size;
1137    }
1138
1139    context.type = EmulateInstruction::eContextAdjustStackPointer;
1140    context.SetImmediateSigned(sp_offset);
1141
1142    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1143                               LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1144      return false;
1145  }
1146  return true;
1147}
1148
1149// Set r7 or ip to point to saved value residing within the stack.
1150// ADD (SP plus immediate)
1151bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
1152                                              const ARMEncoding encoding) {
1153#if 0
1154    // ARM pseudo code...
1155    if (ConditionPassed())
1156    {
1157        EncodingSpecificOperations();
1158        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1159        if d == 15 then
1160           ALUWritePC(result); // setflags is always FALSE here
1161        else
1162            R[d] = result;
1163            if setflags then
1164                APSR.N = result<31>;
1165                APSR.Z = IsZeroBit(result);
1166                APSR.C = carry;
1167                APSR.V = overflow;
1168    }
1169#endif
1170
1171  bool success = false;
1172
1173  if (ConditionPassed(opcode)) {
1174    const addr_t sp = ReadCoreReg(SP_REG, &success);
1175    if (!success)
1176      return false;
1177    uint32_t Rd; // the destination register
1178    uint32_t imm32;
1179    switch (encoding) {
1180    case eEncodingT1:
1181      Rd = 7;
1182      imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
1183      break;
1184    case eEncodingA1:
1185      Rd = Bits32(opcode, 15, 12);
1186      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1187      break;
1188    default:
1189      return false;
1190    }
1191    addr_t sp_offset = imm32;
1192    addr_t addr = sp + sp_offset; // a pointer to the stack area
1193
1194    EmulateInstruction::Context context;
1195    if (Rd == GetFramePointerRegisterNumber())
1196      context.type = eContextSetFramePointer;
1197    else
1198      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1199    RegisterInfo sp_reg;
1200    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1201    context.SetRegisterPlusOffset(sp_reg, sp_offset);
1202
1203    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
1204                               addr))
1205      return false;
1206  }
1207  return true;
1208}
1209
1210// Set r7 or ip to the current stack pointer.
1211// MOV (register)
1212bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
1213                                           const ARMEncoding encoding) {
1214#if 0
1215    // ARM pseudo code...
1216    if (ConditionPassed())
1217    {
1218        EncodingSpecificOperations();
1219        result = R[m];
1220        if d == 15 then
1221            ALUWritePC(result); // setflags is always FALSE here
1222        else
1223            R[d] = result;
1224            if setflags then
1225                APSR.N = result<31>;
1226                APSR.Z = IsZeroBit(result);
1227                // APSR.C unchanged
1228                // APSR.V unchanged
1229    }
1230#endif
1231
1232  bool success = false;
1233
1234  if (ConditionPassed(opcode)) {
1235    const addr_t sp = ReadCoreReg(SP_REG, &success);
1236    if (!success)
1237      return false;
1238    uint32_t Rd; // the destination register
1239    switch (encoding) {
1240    case eEncodingT1:
1241      Rd = 7;
1242      break;
1243    case eEncodingA1:
1244      Rd = 12;
1245      break;
1246    default:
1247      return false;
1248    }
1249
1250    EmulateInstruction::Context context;
1251    if (Rd == GetFramePointerRegisterNumber())
1252      context.type = EmulateInstruction::eContextSetFramePointer;
1253    else
1254      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1255    RegisterInfo sp_reg;
1256    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1257    context.SetRegisterPlusOffset(sp_reg, 0);
1258
1259    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
1260      return false;
1261  }
1262  return true;
1263}
1264
1265// Move from high register (r8-r15) to low register (r0-r7).
1266// MOV (register)
1267bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
1268                                              const ARMEncoding encoding) {
1269  return EmulateMOVRdRm(opcode, encoding);
1270}
1271
1272// Move from register to register.
1273// MOV (register)
1274bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
1275                                           const ARMEncoding encoding) {
1276#if 0
1277    // ARM pseudo code...
1278    if (ConditionPassed())
1279    {
1280        EncodingSpecificOperations();
1281        result = R[m];
1282        if d == 15 then
1283            ALUWritePC(result); // setflags is always FALSE here
1284        else
1285            R[d] = result;
1286            if setflags then
1287                APSR.N = result<31>;
1288                APSR.Z = IsZeroBit(result);
1289                // APSR.C unchanged
1290                // APSR.V unchanged
1291    }
1292#endif
1293
1294  bool success = false;
1295
1296  if (ConditionPassed(opcode)) {
1297    uint32_t Rm; // the source register
1298    uint32_t Rd; // the destination register
1299    bool setflags;
1300    switch (encoding) {
1301    case eEncodingT1:
1302      Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1303      Rm = Bits32(opcode, 6, 3);
1304      setflags = false;
1305      if (Rd == 15 && InITBlock() && !LastInITBlock())
1306        return false;
1307      break;
1308    case eEncodingT2:
1309      Rd = Bits32(opcode, 2, 0);
1310      Rm = Bits32(opcode, 5, 3);
1311      setflags = true;
1312      if (InITBlock())
1313        return false;
1314      break;
1315    case eEncodingT3:
1316      Rd = Bits32(opcode, 11, 8);
1317      Rm = Bits32(opcode, 3, 0);
1318      setflags = BitIsSet(opcode, 20);
1319      // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1320      if (setflags && (BadReg(Rd) || BadReg(Rm)))
1321        return false;
1322      // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
1323      // UNPREDICTABLE;
1324      if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1325        return false;
1326      break;
1327    case eEncodingA1:
1328      Rd = Bits32(opcode, 15, 12);
1329      Rm = Bits32(opcode, 3, 0);
1330      setflags = BitIsSet(opcode, 20);
1331
1332      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1333      // instructions;
1334      if (Rd == 15 && setflags)
1335        return EmulateSUBSPcLrEtc(opcode, encoding);
1336      break;
1337    default:
1338      return false;
1339    }
1340    uint32_t result = ReadCoreReg(Rm, &success);
1341    if (!success)
1342      return false;
1343
1344    // The context specifies that Rm is to be moved into Rd.
1345    EmulateInstruction::Context context;
1346    if (Rd == 13)
1347      context.type = EmulateInstruction::eContextAdjustStackPointer;
1348    else if (Rd == GetFramePointerRegisterNumber() && Rm == 13)
1349      context.type = EmulateInstruction::eContextSetFramePointer;
1350    else
1351      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1352    RegisterInfo dwarf_reg;
1353    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1354    context.SetRegisterPlusOffset(dwarf_reg, 0);
1355
1356    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1357      return false;
1358  }
1359  return true;
1360}
1361
1362// Move (immediate) writes an immediate value to the destination register.  It
1363// can optionally update the condition flags based on the value.
1364// MOV (immediate)
1365bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
1366                                            const ARMEncoding encoding) {
1367#if 0
1368    // ARM pseudo code...
1369    if (ConditionPassed())
1370    {
1371        EncodingSpecificOperations();
1372        result = imm32;
1373        if d == 15 then         // Can only occur for ARM encoding
1374            ALUWritePC(result); // setflags is always FALSE here
1375        else
1376            R[d] = result;
1377            if setflags then
1378                APSR.N = result<31>;
1379                APSR.Z = IsZeroBit(result);
1380                APSR.C = carry;
1381                // APSR.V unchanged
1382    }
1383#endif
1384
1385  if (ConditionPassed(opcode)) {
1386    uint32_t Rd;    // the destination register
1387    uint32_t imm32; // the immediate value to be written to Rd
1388    uint32_t carry =
1389        0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
1390           // for setflags == false, this value is a don't care initialized to
1391           // 0 to silence the static analyzer
1392    bool setflags;
1393    switch (encoding) {
1394    case eEncodingT1:
1395      Rd = Bits32(opcode, 10, 8);
1396      setflags = !InITBlock();
1397      imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
1398      carry = APSR_C;
1399
1400      break;
1401
1402    case eEncodingT2:
1403      Rd = Bits32(opcode, 11, 8);
1404      setflags = BitIsSet(opcode, 20);
1405      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1406      if (BadReg(Rd))
1407        return false;
1408
1409      break;
1410
1411    case eEncodingT3: {
1412      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
1413      // 32);
1414      Rd = Bits32(opcode, 11, 8);
1415      setflags = false;
1416      uint32_t imm4 = Bits32(opcode, 19, 16);
1417      uint32_t imm3 = Bits32(opcode, 14, 12);
1418      uint32_t i = Bit32(opcode, 26);
1419      uint32_t imm8 = Bits32(opcode, 7, 0);
1420      imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1421
1422      // if BadReg(d) then UNPREDICTABLE;
1423      if (BadReg(Rd))
1424        return false;
1425    } break;
1426
1427    case eEncodingA1:
1428      // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
1429      // ARMExpandImm_C(imm12, APSR.C);
1430      Rd = Bits32(opcode, 15, 12);
1431      setflags = BitIsSet(opcode, 20);
1432      imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1433
1434      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1435      // instructions;
1436      if ((Rd == 15) && setflags)
1437        return EmulateSUBSPcLrEtc(opcode, encoding);
1438
1439      break;
1440
1441    case eEncodingA2: {
1442      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
1443      Rd = Bits32(opcode, 15, 12);
1444      setflags = false;
1445      uint32_t imm4 = Bits32(opcode, 19, 16);
1446      uint32_t imm12 = Bits32(opcode, 11, 0);
1447      imm32 = (imm4 << 12) | imm12;
1448
1449      // if d == 15 then UNPREDICTABLE;
1450      if (Rd == 15)
1451        return false;
1452    } break;
1453
1454    default:
1455      return false;
1456    }
1457    uint32_t result = imm32;
1458
1459    // The context specifies that an immediate is to be moved into Rd.
1460    EmulateInstruction::Context context;
1461    context.type = EmulateInstruction::eContextImmediate;
1462    context.SetNoArgs();
1463
1464    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1465      return false;
1466  }
1467  return true;
1468}
1469
1470// MUL multiplies two register values.  The least significant 32 bits of the
1471// result are written to the destination
1472// register.  These 32 bits do not depend on whether the source register values
1473// are considered to be signed values or unsigned values.
1474//
1475// Optionally, it can update the condition flags based on the result.  In the
1476// Thumb instruction set, this option is limited to only a few forms of the
1477// instruction.
1478bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
1479                                       const ARMEncoding encoding) {
1480#if 0
1481    if ConditionPassed() then
1482        EncodingSpecificOperations();
1483        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1484        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1485        result = operand1 * operand2;
1486        R[d] = result<31:0>;
1487        if setflags then
1488            APSR.N = result<31>;
1489            APSR.Z = IsZeroBit(result);
1490            if ArchVersion() == 4 then
1491                APSR.C = bit UNKNOWN;
1492            // else APSR.C unchanged
1493            // APSR.V always unchanged
1494#endif
1495
1496  if (ConditionPassed(opcode)) {
1497    uint32_t d;
1498    uint32_t n;
1499    uint32_t m;
1500    bool setflags;
1501
1502    // EncodingSpecificOperations();
1503    switch (encoding) {
1504    case eEncodingT1:
1505      // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
1506      d = Bits32(opcode, 2, 0);
1507      n = Bits32(opcode, 5, 3);
1508      m = Bits32(opcode, 2, 0);
1509      setflags = !InITBlock();
1510
1511      // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1512      if ((ArchVersion() < ARMv6) && (d == n))
1513        return false;
1514
1515      break;
1516
1517    case eEncodingT2:
1518      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
1519      d = Bits32(opcode, 11, 8);
1520      n = Bits32(opcode, 19, 16);
1521      m = Bits32(opcode, 3, 0);
1522      setflags = false;
1523
1524      // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1525      if (BadReg(d) || BadReg(n) || BadReg(m))
1526        return false;
1527
1528      break;
1529
1530    case eEncodingA1:
1531      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1532      d = Bits32(opcode, 19, 16);
1533      n = Bits32(opcode, 3, 0);
1534      m = Bits32(opcode, 11, 8);
1535      setflags = BitIsSet(opcode, 20);
1536
1537      // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1538      if ((d == 15) || (n == 15) || (m == 15))
1539        return false;
1540
1541      // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1542      if ((ArchVersion() < ARMv6) && (d == n))
1543        return false;
1544
1545      break;
1546
1547    default:
1548      return false;
1549    }
1550
1551    bool success = false;
1552
1553    // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1554    // results
1555    uint64_t operand1 =
1556        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1557    if (!success)
1558      return false;
1559
1560    // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1561    // results
1562    uint64_t operand2 =
1563        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1564    if (!success)
1565      return false;
1566
1567    // result = operand1 * operand2;
1568    uint64_t result = operand1 * operand2;
1569
1570    // R[d] = result<31:0>;
1571    RegisterInfo op1_reg;
1572    RegisterInfo op2_reg;
1573    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1574    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1575
1576    EmulateInstruction::Context context;
1577    context.type = eContextArithmetic;
1578    context.SetRegisterRegisterOperands(op1_reg, op2_reg);
1579
1580    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
1581                               (0x0000ffff & result)))
1582      return false;
1583
1584    // if setflags then
1585    if (setflags) {
1586      // APSR.N = result<31>;
1587      // APSR.Z = IsZeroBit(result);
1588      m_new_inst_cpsr = m_opcode_cpsr;
1589      SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
1590      SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1591      if (m_new_inst_cpsr != m_opcode_cpsr) {
1592        if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1593                                   LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1594          return false;
1595      }
1596
1597      // if ArchVersion() == 4 then
1598      // APSR.C = bit UNKNOWN;
1599    }
1600  }
1601  return true;
1602}
1603
1604// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1605// the destination register. It can optionally update the condition flags based
1606// on the value.
1607bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1608                                          const ARMEncoding encoding) {
1609#if 0
1610    // ARM pseudo code...
1611    if (ConditionPassed())
1612    {
1613        EncodingSpecificOperations();
1614        result = NOT(imm32);
1615        if d == 15 then         // Can only occur for ARM encoding
1616            ALUWritePC(result); // setflags is always FALSE here
1617        else
1618            R[d] = result;
1619            if setflags then
1620                APSR.N = result<31>;
1621                APSR.Z = IsZeroBit(result);
1622                APSR.C = carry;
1623                // APSR.V unchanged
1624    }
1625#endif
1626
1627  if (ConditionPassed(opcode)) {
1628    uint32_t Rd;    // the destination register
1629    uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1630    uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1631    bool setflags;
1632    switch (encoding) {
1633    case eEncodingT1:
1634      Rd = Bits32(opcode, 11, 8);
1635      setflags = BitIsSet(opcode, 20);
1636      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1637      break;
1638    case eEncodingA1:
1639      Rd = Bits32(opcode, 15, 12);
1640      setflags = BitIsSet(opcode, 20);
1641      imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1642
1643      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1644      // instructions;
1645      if (Rd == 15 && setflags)
1646        return EmulateSUBSPcLrEtc(opcode, encoding);
1647      break;
1648    default:
1649      return false;
1650    }
1651    uint32_t result = ~imm32;
1652
1653    // The context specifies that an immediate is to be moved into Rd.
1654    EmulateInstruction::Context context;
1655    context.type = EmulateInstruction::eContextImmediate;
1656    context.SetNoArgs();
1657
1658    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1659      return false;
1660  }
1661  return true;
1662}
1663
1664// Bitwise NOT (register) writes the bitwise inverse of a register value to the
1665// destination register. It can optionally update the condition flags based on
1666// the result.
1667bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1668                                          const ARMEncoding encoding) {
1669#if 0
1670    // ARM pseudo code...
1671    if (ConditionPassed())
1672    {
1673        EncodingSpecificOperations();
1674        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1675        result = NOT(shifted);
1676        if d == 15 then         // Can only occur for ARM encoding
1677            ALUWritePC(result); // setflags is always FALSE here
1678        else
1679            R[d] = result;
1680            if setflags then
1681                APSR.N = result<31>;
1682                APSR.Z = IsZeroBit(result);
1683                APSR.C = carry;
1684                // APSR.V unchanged
1685    }
1686#endif
1687
1688  if (ConditionPassed(opcode)) {
1689    uint32_t Rm; // the source register
1690    uint32_t Rd; // the destination register
1691    ARM_ShifterType shift_t;
1692    uint32_t shift_n; // the shift applied to the value read from Rm
1693    bool setflags;
1694    uint32_t carry; // the carry bit after the shift operation
1695    switch (encoding) {
1696    case eEncodingT1:
1697      Rd = Bits32(opcode, 2, 0);
1698      Rm = Bits32(opcode, 5, 3);
1699      setflags = !InITBlock();
1700      shift_t = SRType_LSL;
1701      shift_n = 0;
1702      if (InITBlock())
1703        return false;
1704      break;
1705    case eEncodingT2:
1706      Rd = Bits32(opcode, 11, 8);
1707      Rm = Bits32(opcode, 3, 0);
1708      setflags = BitIsSet(opcode, 20);
1709      shift_n = DecodeImmShiftThumb(opcode, shift_t);
1710      // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1711      if (BadReg(Rd) || BadReg(Rm))
1712        return false;
1713      break;
1714    case eEncodingA1:
1715      Rd = Bits32(opcode, 15, 12);
1716      Rm = Bits32(opcode, 3, 0);
1717      setflags = BitIsSet(opcode, 20);
1718      shift_n = DecodeImmShiftARM(opcode, shift_t);
1719      break;
1720    default:
1721      return false;
1722    }
1723    bool success = false;
1724    uint32_t value = ReadCoreReg(Rm, &success);
1725    if (!success)
1726      return false;
1727
1728    uint32_t shifted =
1729        Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1730    if (!success)
1731      return false;
1732    uint32_t result = ~shifted;
1733
1734    // The context specifies that an immediate is to be moved into Rd.
1735    EmulateInstruction::Context context;
1736    context.type = EmulateInstruction::eContextImmediate;
1737    context.SetNoArgs();
1738
1739    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1740      return false;
1741  }
1742  return true;
1743}
1744
1745// PC relative immediate load into register, possibly followed by ADD (SP plus
1746// register).
1747// LDR (literal)
1748bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
1749                                                   const ARMEncoding encoding) {
1750#if 0
1751    // ARM pseudo code...
1752    if (ConditionPassed())
1753    {
1754        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1755        base = Align(PC,4);
1756        address = if add then (base + imm32) else (base - imm32);
1757        data = MemU[address,4];
1758        if t == 15 then
1759            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1760        elsif UnalignedSupport() || address<1:0> = '00' then
1761            R[t] = data;
1762        else // Can only apply before ARMv7
1763            if CurrentInstrSet() == InstrSet_ARM then
1764                R[t] = ROR(data, 8*UInt(address<1:0>));
1765            else
1766                R[t] = bits(32) UNKNOWN;
1767    }
1768#endif
1769
1770  if (ConditionPassed(opcode)) {
1771    bool success = false;
1772    const uint32_t pc = ReadCoreReg(PC_REG, &success);
1773    if (!success)
1774      return false;
1775
1776    // PC relative immediate load context
1777    EmulateInstruction::Context context;
1778    context.type = EmulateInstruction::eContextRegisterPlusOffset;
1779    RegisterInfo pc_reg;
1780    GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
1781    context.SetRegisterPlusOffset(pc_reg, 0);
1782
1783    uint32_t Rt;    // the destination register
1784    uint32_t imm32; // immediate offset from the PC
1785    bool add;       // +imm32 or -imm32?
1786    addr_t base;    // the base address
1787    addr_t address; // the PC relative address
1788    uint32_t data;  // the literal data value from the PC relative load
1789    switch (encoding) {
1790    case eEncodingT1:
1791      Rt = Bits32(opcode, 10, 8);
1792      imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1793      add = true;
1794      break;
1795    case eEncodingT2:
1796      Rt = Bits32(opcode, 15, 12);
1797      imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1798      add = BitIsSet(opcode, 23);
1799      if (Rt == 15 && InITBlock() && !LastInITBlock())
1800        return false;
1801      break;
1802    default:
1803      return false;
1804    }
1805
1806    base = Align(pc, 4);
1807    if (add)
1808      address = base + imm32;
1809    else
1810      address = base - imm32;
1811
1812    context.SetRegisterPlusOffset(pc_reg, address - base);
1813    data = MemURead(context, address, 4, 0, &success);
1814    if (!success)
1815      return false;
1816
1817    if (Rt == 15) {
1818      if (Bits32(address, 1, 0) == 0) {
1819        // In ARMv5T and above, this is an interworking branch.
1820        if (!LoadWritePC(context, data))
1821          return false;
1822      } else
1823        return false;
1824    } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1825      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
1826                                 data))
1827        return false;
1828    } else // We don't handle ARM for now.
1829      return false;
1830  }
1831  return true;
1832}
1833
1834// An add operation to adjust the SP.
1835// ADD (SP plus immediate)
1836bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
1837                                            const ARMEncoding encoding) {
1838#if 0
1839    // ARM pseudo code...
1840    if (ConditionPassed())
1841    {
1842        EncodingSpecificOperations();
1843        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1844        if d == 15 then // Can only occur for ARM encoding
1845            ALUWritePC(result); // setflags is always FALSE here
1846        else
1847            R[d] = result;
1848            if setflags then
1849                APSR.N = result<31>;
1850                APSR.Z = IsZeroBit(result);
1851                APSR.C = carry;
1852                APSR.V = overflow;
1853    }
1854#endif
1855
1856  bool success = false;
1857
1858  if (ConditionPassed(opcode)) {
1859    const addr_t sp = ReadCoreReg(SP_REG, &success);
1860    if (!success)
1861      return false;
1862    uint32_t imm32; // the immediate operand
1863    uint32_t d;
1864    bool setflags;
1865    switch (encoding) {
1866    case eEncodingT1:
1867      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1868      d = Bits32(opcode, 10, 8);
1869      imm32 = (Bits32(opcode, 7, 0) << 2);
1870      setflags = false;
1871      break;
1872
1873    case eEncodingT2:
1874      // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1875      d = 13;
1876      imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1877      setflags = false;
1878      break;
1879
1880    case eEncodingT3:
1881      // d = UInt(Rd); setflags = (S == "1"); imm32 =
1882      // ThumbExpandImm(i:imm3:imm8);
1883      d = Bits32(opcode, 11, 8);
1884      imm32 = ThumbExpandImm(opcode);
1885      setflags = Bit32(opcode, 20);
1886
1887      // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1888      if (d == 15 && setflags == 1)
1889        return false; // CMN (immediate) not yet supported
1890
1891      // if d == 15 && S == "0" then UNPREDICTABLE;
1892      if (d == 15 && setflags == 0)
1893        return false;
1894      break;
1895
1896    case eEncodingT4: {
1897      // if Rn == '1111' then SEE ADR;
1898      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1899      d = Bits32(opcode, 11, 8);
1900      setflags = false;
1901      uint32_t i = Bit32(opcode, 26);
1902      uint32_t imm3 = Bits32(opcode, 14, 12);
1903      uint32_t imm8 = Bits32(opcode, 7, 0);
1904      imm32 = (i << 11) | (imm3 << 8) | imm8;
1905
1906      // if d == 15 then UNPREDICTABLE;
1907      if (d == 15)
1908        return false;
1909    } break;
1910
1911    default:
1912      return false;
1913    }
1914    // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1915    AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1916
1917    EmulateInstruction::Context context;
1918    if (d == 13)
1919      context.type = EmulateInstruction::eContextAdjustStackPointer;
1920    else
1921      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1922
1923    RegisterInfo sp_reg;
1924    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1925    context.SetRegisterPlusOffset(sp_reg, res.result - sp);
1926
1927    if (d == 15) {
1928      if (!ALUWritePC(context, res.result))
1929        return false;
1930    } else {
1931      // R[d] = result;
1932      // if setflags then
1933      //     APSR.N = result<31>;
1934      //     APSR.Z = IsZeroBit(result);
1935      //     APSR.C = carry;
1936      //     APSR.V = overflow;
1937      if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1938                                     res.carry_out, res.overflow))
1939        return false;
1940    }
1941  }
1942  return true;
1943}
1944
1945// An add operation to adjust the SP.
1946// ADD (SP plus register)
1947bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1948                                           const ARMEncoding encoding) {
1949#if 0
1950    // ARM pseudo code...
1951    if (ConditionPassed())
1952    {
1953        EncodingSpecificOperations();
1954        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1955        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1956        if d == 15 then
1957            ALUWritePC(result); // setflags is always FALSE here
1958        else
1959            R[d] = result;
1960            if setflags then
1961                APSR.N = result<31>;
1962                APSR.Z = IsZeroBit(result);
1963                APSR.C = carry;
1964                APSR.V = overflow;
1965    }
1966#endif
1967
1968  bool success = false;
1969
1970  if (ConditionPassed(opcode)) {
1971    const addr_t sp = ReadCoreReg(SP_REG, &success);
1972    if (!success)
1973      return false;
1974    uint32_t Rm; // the second operand
1975    switch (encoding) {
1976    case eEncodingT2:
1977      Rm = Bits32(opcode, 6, 3);
1978      break;
1979    default:
1980      return false;
1981    }
1982    int32_t reg_value = ReadCoreReg(Rm, &success);
1983    if (!success)
1984      return false;
1985
1986    addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1987
1988    EmulateInstruction::Context context;
1989    context.type = eContextArithmetic;
1990    RegisterInfo sp_reg;
1991    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1992
1993    RegisterInfo other_reg;
1994    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1995    context.SetRegisterRegisterOperands(sp_reg, other_reg);
1996
1997    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1998                               LLDB_REGNUM_GENERIC_SP, addr))
1999      return false;
2000  }
2001  return true;
2002}
2003
2004// Branch with Link and Exchange Instruction Sets (immediate) calls a
2005// subroutine at a PC-relative address, and changes instruction set from ARM to
2006// Thumb, or from Thumb to ARM.
2007// BLX (immediate)
2008bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
2009                                                const ARMEncoding encoding) {
2010#if 0
2011    // ARM pseudo code...
2012    if (ConditionPassed())
2013    {
2014        EncodingSpecificOperations();
2015        if CurrentInstrSet() == InstrSet_ARM then
2016            LR = PC - 4;
2017        else
2018            LR = PC<31:1> : '1';
2019        if targetInstrSet == InstrSet_ARM then
2020            targetAddress = Align(PC,4) + imm32;
2021        else
2022            targetAddress = PC + imm32;
2023        SelectInstrSet(targetInstrSet);
2024        BranchWritePC(targetAddress);
2025    }
2026#endif
2027
2028  bool success = true;
2029
2030  if (ConditionPassed(opcode)) {
2031    EmulateInstruction::Context context;
2032    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2033    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2034    if (!success)
2035      return false;
2036    addr_t lr;     // next instruction address
2037    addr_t target; // target address
2038    int32_t imm32; // PC-relative offset
2039    switch (encoding) {
2040    case eEncodingT1: {
2041      lr = pc | 1u; // return address
2042      uint32_t S = Bit32(opcode, 26);
2043      uint32_t imm10 = Bits32(opcode, 25, 16);
2044      uint32_t J1 = Bit32(opcode, 13);
2045      uint32_t J2 = Bit32(opcode, 11);
2046      uint32_t imm11 = Bits32(opcode, 10, 0);
2047      uint32_t I1 = !(J1 ^ S);
2048      uint32_t I2 = !(J2 ^ S);
2049      uint32_t imm25 =
2050          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2051      imm32 = llvm::SignExtend32<25>(imm25);
2052      target = pc + imm32;
2053      SelectInstrSet(eModeThumb);
2054      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2055      if (InITBlock() && !LastInITBlock())
2056        return false;
2057      break;
2058    }
2059    case eEncodingT2: {
2060      lr = pc | 1u; // return address
2061      uint32_t S = Bit32(opcode, 26);
2062      uint32_t imm10H = Bits32(opcode, 25, 16);
2063      uint32_t J1 = Bit32(opcode, 13);
2064      uint32_t J2 = Bit32(opcode, 11);
2065      uint32_t imm10L = Bits32(opcode, 10, 1);
2066      uint32_t I1 = !(J1 ^ S);
2067      uint32_t I2 = !(J2 ^ S);
2068      uint32_t imm25 =
2069          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2070      imm32 = llvm::SignExtend32<25>(imm25);
2071      target = Align(pc, 4) + imm32;
2072      SelectInstrSet(eModeARM);
2073      context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
2074      if (InITBlock() && !LastInITBlock())
2075        return false;
2076      break;
2077    }
2078    case eEncodingA1:
2079      lr = pc - 4; // return address
2080      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2081      target = Align(pc, 4) + imm32;
2082      SelectInstrSet(eModeARM);
2083      context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2084      break;
2085    case eEncodingA2:
2086      lr = pc - 4; // return address
2087      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
2088                                     Bits32(opcode, 24, 24) << 1);
2089      target = pc + imm32;
2090      SelectInstrSet(eModeThumb);
2091      context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
2092      break;
2093    default:
2094      return false;
2095    }
2096    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2097                               LLDB_REGNUM_GENERIC_RA, lr))
2098      return false;
2099    if (!BranchWritePC(context, target))
2100      return false;
2101    if (m_opcode_cpsr != m_new_inst_cpsr)
2102      if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2103                                 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
2104        return false;
2105  }
2106  return true;
2107}
2108
2109// Branch with Link and Exchange (register) calls a subroutine at an address
2110// and instruction set specified by a register.
2111// BLX (register)
2112bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
2113                                         const ARMEncoding encoding) {
2114#if 0
2115    // ARM pseudo code...
2116    if (ConditionPassed())
2117    {
2118        EncodingSpecificOperations();
2119        target = R[m];
2120        if CurrentInstrSet() == InstrSet_ARM then
2121            next_instr_addr = PC - 4;
2122            LR = next_instr_addr;
2123        else
2124            next_instr_addr = PC - 2;
2125            LR = next_instr_addr<31:1> : '1';
2126        BXWritePC(target);
2127    }
2128#endif
2129
2130  bool success = false;
2131
2132  if (ConditionPassed(opcode)) {
2133    EmulateInstruction::Context context;
2134    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2135    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2136    addr_t lr; // next instruction address
2137    if (!success)
2138      return false;
2139    uint32_t Rm; // the register with the target address
2140    switch (encoding) {
2141    case eEncodingT1:
2142      lr = (pc - 2) | 1u; // return address
2143      Rm = Bits32(opcode, 6, 3);
2144      // if m == 15 then UNPREDICTABLE;
2145      if (Rm == 15)
2146        return false;
2147      if (InITBlock() && !LastInITBlock())
2148        return false;
2149      break;
2150    case eEncodingA1:
2151      lr = pc - 4; // return address
2152      Rm = Bits32(opcode, 3, 0);
2153      // if m == 15 then UNPREDICTABLE;
2154      if (Rm == 15)
2155        return false;
2156      break;
2157    default:
2158      return false;
2159    }
2160    addr_t target = ReadCoreReg(Rm, &success);
2161    if (!success)
2162      return false;
2163    RegisterInfo dwarf_reg;
2164    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2165    context.SetRegister(dwarf_reg);
2166    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2167                               LLDB_REGNUM_GENERIC_RA, lr))
2168      return false;
2169    if (!BXWritePC(context, target))
2170      return false;
2171  }
2172  return true;
2173}
2174
2175// Branch and Exchange causes a branch to an address and instruction set
2176// specified by a register.
2177bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
2178                                        const ARMEncoding encoding) {
2179#if 0
2180    // ARM pseudo code...
2181    if (ConditionPassed())
2182    {
2183        EncodingSpecificOperations();
2184        BXWritePC(R[m]);
2185    }
2186#endif
2187
2188  if (ConditionPassed(opcode)) {
2189    EmulateInstruction::Context context;
2190    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2191    uint32_t Rm; // the register with the target address
2192    switch (encoding) {
2193    case eEncodingT1:
2194      Rm = Bits32(opcode, 6, 3);
2195      if (InITBlock() && !LastInITBlock())
2196        return false;
2197      break;
2198    case eEncodingA1:
2199      Rm = Bits32(opcode, 3, 0);
2200      break;
2201    default:
2202      return false;
2203    }
2204    bool success = false;
2205    addr_t target = ReadCoreReg(Rm, &success);
2206    if (!success)
2207      return false;
2208
2209    RegisterInfo dwarf_reg;
2210    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2211    context.SetRegister(dwarf_reg);
2212    if (!BXWritePC(context, target))
2213      return false;
2214  }
2215  return true;
2216}
2217
2218// Branch and Exchange Jazelle attempts to change to Jazelle state. If the
2219// attempt fails, it branches to an address and instruction set specified by a
2220// register as though it were a BX instruction.
2221//
2222// TODO: Emulate Jazelle architecture?
2223//       We currently assume that switching to Jazelle state fails, thus
2224//       treating BXJ as a BX operation.
2225bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
2226                                         const ARMEncoding encoding) {
2227#if 0
2228    // ARM pseudo code...
2229    if (ConditionPassed())
2230    {
2231        EncodingSpecificOperations();
2232        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
2233            BXWritePC(R[m]);
2234        else
2235            if JazelleAcceptsExecution() then
2236                SwitchToJazelleExecution();
2237            else
2238                SUBARCHITECTURE_DEFINED handler call;
2239    }
2240#endif
2241
2242  if (ConditionPassed(opcode)) {
2243    EmulateInstruction::Context context;
2244    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2245    uint32_t Rm; // the register with the target address
2246    switch (encoding) {
2247    case eEncodingT1:
2248      Rm = Bits32(opcode, 19, 16);
2249      if (BadReg(Rm))
2250        return false;
2251      if (InITBlock() && !LastInITBlock())
2252        return false;
2253      break;
2254    case eEncodingA1:
2255      Rm = Bits32(opcode, 3, 0);
2256      if (Rm == 15)
2257        return false;
2258      break;
2259    default:
2260      return false;
2261    }
2262    bool success = false;
2263    addr_t target = ReadCoreReg(Rm, &success);
2264    if (!success)
2265      return false;
2266
2267    RegisterInfo dwarf_reg;
2268    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2269    context.SetRegister(dwarf_reg);
2270    if (!BXWritePC(context, target))
2271      return false;
2272  }
2273  return true;
2274}
2275
2276// Set r7 to point to some ip offset.
2277// SUB (immediate)
2278bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
2279                                              const ARMEncoding encoding) {
2280#if 0
2281    // ARM pseudo code...
2282    if (ConditionPassed())
2283    {
2284        EncodingSpecificOperations();
2285        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2286        if d == 15 then // Can only occur for ARM encoding
2287           ALUWritePC(result); // setflags is always FALSE here
2288        else
2289            R[d] = result;
2290            if setflags then
2291                APSR.N = result<31>;
2292                APSR.Z = IsZeroBit(result);
2293                APSR.C = carry;
2294                APSR.V = overflow;
2295    }
2296#endif
2297
2298  if (ConditionPassed(opcode)) {
2299    bool success = false;
2300    const addr_t ip = ReadCoreReg(12, &success);
2301    if (!success)
2302      return false;
2303    uint32_t imm32;
2304    switch (encoding) {
2305    case eEncodingA1:
2306      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2307      break;
2308    default:
2309      return false;
2310    }
2311    addr_t ip_offset = imm32;
2312    addr_t addr = ip - ip_offset; // the adjusted ip value
2313
2314    EmulateInstruction::Context context;
2315    context.type = EmulateInstruction::eContextRegisterPlusOffset;
2316    RegisterInfo dwarf_reg;
2317    GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg);
2318    context.SetRegisterPlusOffset(dwarf_reg, -ip_offset);
2319
2320    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
2321      return false;
2322  }
2323  return true;
2324}
2325
2326// Set ip to point to some stack offset.
2327// SUB (SP minus immediate)
2328bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
2329                                              const ARMEncoding encoding) {
2330#if 0
2331    // ARM pseudo code...
2332    if (ConditionPassed())
2333    {
2334        EncodingSpecificOperations();
2335        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2336        if d == 15 then // Can only occur for ARM encoding
2337           ALUWritePC(result); // setflags is always FALSE here
2338        else
2339            R[d] = result;
2340            if setflags then
2341                APSR.N = result<31>;
2342                APSR.Z = IsZeroBit(result);
2343                APSR.C = carry;
2344                APSR.V = overflow;
2345    }
2346#endif
2347
2348  if (ConditionPassed(opcode)) {
2349    bool success = false;
2350    const addr_t sp = ReadCoreReg(SP_REG, &success);
2351    if (!success)
2352      return false;
2353    uint32_t imm32;
2354    switch (encoding) {
2355    case eEncodingA1:
2356      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2357      break;
2358    default:
2359      return false;
2360    }
2361    addr_t sp_offset = imm32;
2362    addr_t addr = sp - sp_offset; // the adjusted stack pointer value
2363
2364    EmulateInstruction::Context context;
2365    context.type = EmulateInstruction::eContextRegisterPlusOffset;
2366    RegisterInfo dwarf_reg;
2367    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
2368    context.SetRegisterPlusOffset(dwarf_reg, -sp_offset);
2369
2370    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
2371      return false;
2372  }
2373  return true;
2374}
2375
2376// This instruction subtracts an immediate value from the SP value, and writes
2377// the result to the destination register.
2378//
2379// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
2380// storage.
2381bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
2382                                            const ARMEncoding encoding) {
2383#if 0
2384    // ARM pseudo code...
2385    if (ConditionPassed())
2386    {
2387        EncodingSpecificOperations();
2388        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2389        if d == 15 then        // Can only occur for ARM encoding
2390           ALUWritePC(result); // setflags is always FALSE here
2391        else
2392            R[d] = result;
2393            if setflags then
2394                APSR.N = result<31>;
2395                APSR.Z = IsZeroBit(result);
2396                APSR.C = carry;
2397                APSR.V = overflow;
2398    }
2399#endif
2400
2401  bool success = false;
2402  if (ConditionPassed(opcode)) {
2403    const addr_t sp = ReadCoreReg(SP_REG, &success);
2404    if (!success)
2405      return false;
2406
2407    uint32_t Rd;
2408    bool setflags;
2409    uint32_t imm32;
2410    switch (encoding) {
2411    case eEncodingT1:
2412      Rd = 13;
2413      setflags = false;
2414      imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
2415      break;
2416    case eEncodingT2:
2417      Rd = Bits32(opcode, 11, 8);
2418      setflags = BitIsSet(opcode, 20);
2419      imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2420      if (Rd == 15 && setflags)
2421        return EmulateCMPImm(opcode, eEncodingT2);
2422      if (Rd == 15 && !setflags)
2423        return false;
2424      break;
2425    case eEncodingT3:
2426      Rd = Bits32(opcode, 11, 8);
2427      setflags = false;
2428      imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
2429      if (Rd == 15)
2430        return false;
2431      break;
2432    case eEncodingA1:
2433      Rd = Bits32(opcode, 15, 12);
2434      setflags = BitIsSet(opcode, 20);
2435      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2436
2437      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
2438      // instructions;
2439      if (Rd == 15 && setflags)
2440        return EmulateSUBSPcLrEtc(opcode, encoding);
2441      break;
2442    default:
2443      return false;
2444    }
2445    AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
2446
2447    EmulateInstruction::Context context;
2448    if (Rd == 13) {
2449      uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
2450                              // to negate it, or the wrong
2451      // value gets passed down to context.SetImmediateSigned.
2452      context.type = EmulateInstruction::eContextAdjustStackPointer;
2453      context.SetImmediateSigned(-imm64); // the stack pointer offset
2454    } else {
2455      context.type = EmulateInstruction::eContextImmediate;
2456      context.SetNoArgs();
2457    }
2458
2459    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2460                                   res.carry_out, res.overflow))
2461      return false;
2462  }
2463  return true;
2464}
2465
2466// A store operation to the stack that also updates the SP.
2467bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
2468                                           const ARMEncoding encoding) {
2469#if 0
2470    // ARM pseudo code...
2471    if (ConditionPassed())
2472    {
2473        EncodingSpecificOperations();
2474        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2475        address = if index then offset_addr else R[n];
2476        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
2477        if wback then R[n] = offset_addr;
2478    }
2479#endif
2480
2481  bool success = false;
2482  if (ConditionPassed(opcode)) {
2483    const uint32_t addr_byte_size = GetAddressByteSize();
2484    const addr_t sp = ReadCoreReg(SP_REG, &success);
2485    if (!success)
2486      return false;
2487    uint32_t Rt; // the source register
2488    uint32_t imm12;
2489    uint32_t
2490        Rn; // This function assumes Rn is the SP, but we should verify that.
2491
2492    bool index;
2493    bool add;
2494    bool wback;
2495    switch (encoding) {
2496    case eEncodingA1:
2497      Rt = Bits32(opcode, 15, 12);
2498      imm12 = Bits32(opcode, 11, 0);
2499      Rn = Bits32(opcode, 19, 16);
2500
2501      if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
2502        return false;
2503
2504      index = BitIsSet(opcode, 24);
2505      add = BitIsSet(opcode, 23);
2506      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
2507
2508      if (wback && ((Rn == 15) || (Rn == Rt)))
2509        return false;
2510      break;
2511    default:
2512      return false;
2513    }
2514    addr_t offset_addr;
2515    if (add)
2516      offset_addr = sp + imm12;
2517    else
2518      offset_addr = sp - imm12;
2519
2520    addr_t addr;
2521    if (index)
2522      addr = offset_addr;
2523    else
2524      addr = sp;
2525
2526    EmulateInstruction::Context context;
2527    context.type = EmulateInstruction::eContextPushRegisterOnStack;
2528    RegisterInfo sp_reg;
2529    RegisterInfo dwarf_reg;
2530
2531    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2532    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2533    context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2534    if (Rt != 15) {
2535      uint32_t reg_value = ReadCoreReg(Rt, &success);
2536      if (!success)
2537        return false;
2538      if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2539        return false;
2540    } else {
2541      const uint32_t pc = ReadCoreReg(PC_REG, &success);
2542      if (!success)
2543        return false;
2544      if (!MemUWrite(context, addr, pc, addr_byte_size))
2545        return false;
2546    }
2547
2548    if (wback) {
2549      context.type = EmulateInstruction::eContextAdjustStackPointer;
2550      context.SetImmediateSigned(addr - sp);
2551      if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2552                                 LLDB_REGNUM_GENERIC_SP, offset_addr))
2553        return false;
2554    }
2555  }
2556  return true;
2557}
2558
2559// Vector Push stores multiple extension registers to the stack. It also
2560// updates SP to point to the start of the stored data.
2561bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2562                                         const ARMEncoding encoding) {
2563#if 0
2564    // ARM pseudo code...
2565    if (ConditionPassed())
2566    {
2567        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2568        address = SP - imm32;
2569        SP = SP - imm32;
2570        if single_regs then
2571            for r = 0 to regs-1
2572                MemA[address,4] = S[d+r]; address = address+4;
2573        else
2574            for r = 0 to regs-1
2575                // Store as two word-aligned words in the correct order for
2576                // current endianness.
2577                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2578                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2579                address = address+8;
2580    }
2581#endif
2582
2583  bool success = false;
2584  if (ConditionPassed(opcode)) {
2585    const uint32_t addr_byte_size = GetAddressByteSize();
2586    const addr_t sp = ReadCoreReg(SP_REG, &success);
2587    if (!success)
2588      return false;
2589    bool single_regs;
2590    uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2591    uint32_t imm32; // stack offset
2592    uint32_t regs;  // number of registers
2593    switch (encoding) {
2594    case eEncodingT1:
2595    case eEncodingA1:
2596      single_regs = false;
2597      d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2598      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2599      // If UInt(imm8) is odd, see "FSTMX".
2600      regs = Bits32(opcode, 7, 0) / 2;
2601      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2602      if (regs == 0 || regs > 16 || (d + regs) > 32)
2603        return false;
2604      break;
2605    case eEncodingT2:
2606    case eEncodingA2:
2607      single_regs = true;
2608      d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2609      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2610      regs = Bits32(opcode, 7, 0);
2611      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2612      if (regs == 0 || regs > 16 || (d + regs) > 32)
2613        return false;
2614      break;
2615    default:
2616      return false;
2617    }
2618    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2619    uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2620    addr_t sp_offset = imm32;
2621    addr_t addr = sp - sp_offset;
2622    uint32_t i;
2623
2624    EmulateInstruction::Context context;
2625    context.type = EmulateInstruction::eContextPushRegisterOnStack;
2626
2627    RegisterInfo dwarf_reg;
2628    RegisterInfo sp_reg;
2629    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2630    for (i = 0; i < regs; ++i) {
2631      GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2632      context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2633      // uint64_t to accommodate 64-bit registers.
2634      uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success);
2635      if (!success)
2636        return false;
2637      if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2638        return false;
2639      addr += reg_byte_size;
2640    }
2641
2642    context.type = EmulateInstruction::eContextAdjustStackPointer;
2643    context.SetImmediateSigned(-sp_offset);
2644
2645    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2646                               LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2647      return false;
2648  }
2649  return true;
2650}
2651
2652// Vector Pop loads multiple extension registers from the stack. It also
2653// updates SP to point just above the loaded data.
2654bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2655                                        const ARMEncoding encoding) {
2656#if 0
2657    // ARM pseudo code...
2658    if (ConditionPassed())
2659    {
2660        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2661        address = SP;
2662        SP = SP + imm32;
2663        if single_regs then
2664            for r = 0 to regs-1
2665                S[d+r] = MemA[address,4]; address = address+4;
2666        else
2667            for r = 0 to regs-1
2668                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2669                // Combine the word-aligned words in the correct order for
2670                // current endianness.
2671                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2672    }
2673#endif
2674
2675  bool success = false;
2676  if (ConditionPassed(opcode)) {
2677    const uint32_t addr_byte_size = GetAddressByteSize();
2678    const addr_t sp = ReadCoreReg(SP_REG, &success);
2679    if (!success)
2680      return false;
2681    bool single_regs;
2682    uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2683    uint32_t imm32; // stack offset
2684    uint32_t regs;  // number of registers
2685    switch (encoding) {
2686    case eEncodingT1:
2687    case eEncodingA1:
2688      single_regs = false;
2689      d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2690      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2691      // If UInt(imm8) is odd, see "FLDMX".
2692      regs = Bits32(opcode, 7, 0) / 2;
2693      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2694      if (regs == 0 || regs > 16 || (d + regs) > 32)
2695        return false;
2696      break;
2697    case eEncodingT2:
2698    case eEncodingA2:
2699      single_regs = true;
2700      d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2701      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2702      regs = Bits32(opcode, 7, 0);
2703      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2704      if (regs == 0 || regs > 16 || (d + regs) > 32)
2705        return false;
2706      break;
2707    default:
2708      return false;
2709    }
2710    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2711    uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2712    addr_t sp_offset = imm32;
2713    addr_t addr = sp;
2714    uint32_t i;
2715    uint64_t data; // uint64_t to accommodate 64-bit registers.
2716
2717    EmulateInstruction::Context context;
2718    context.type = EmulateInstruction::eContextPopRegisterOffStack;
2719
2720    RegisterInfo dwarf_reg;
2721    RegisterInfo sp_reg;
2722    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2723    for (i = 0; i < regs; ++i) {
2724      GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2725      context.SetAddress(addr);
2726      data = MemARead(context, addr, reg_byte_size, 0, &success);
2727      if (!success)
2728        return false;
2729      if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2730        return false;
2731      addr += reg_byte_size;
2732    }
2733
2734    context.type = EmulateInstruction::eContextAdjustStackPointer;
2735    context.SetImmediateSigned(sp_offset);
2736
2737    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2738                               LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2739      return false;
2740  }
2741  return true;
2742}
2743
2744// SVC (previously SWI)
2745bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2746                                       const ARMEncoding encoding) {
2747#if 0
2748    // ARM pseudo code...
2749    if (ConditionPassed())
2750    {
2751        EncodingSpecificOperations();
2752        CallSupervisor();
2753    }
2754#endif
2755
2756  bool success = false;
2757
2758  if (ConditionPassed(opcode)) {
2759    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2760    addr_t lr; // next instruction address
2761    if (!success)
2762      return false;
2763    uint32_t imm32; // the immediate constant
2764    uint32_t mode;  // ARM or Thumb mode
2765    switch (encoding) {
2766    case eEncodingT1:
2767      lr = (pc + 2) | 1u; // return address
2768      imm32 = Bits32(opcode, 7, 0);
2769      mode = eModeThumb;
2770      break;
2771    case eEncodingA1:
2772      lr = pc + 4; // return address
2773      imm32 = Bits32(opcode, 23, 0);
2774      mode = eModeARM;
2775      break;
2776    default:
2777      return false;
2778    }
2779
2780    EmulateInstruction::Context context;
2781    context.type = EmulateInstruction::eContextSupervisorCall;
2782    context.SetISAAndImmediate(mode, imm32);
2783    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2784                               LLDB_REGNUM_GENERIC_RA, lr))
2785      return false;
2786  }
2787  return true;
2788}
2789
2790// If Then makes up to four following instructions (the IT block) conditional.
2791bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2792                                      const ARMEncoding encoding) {
2793#if 0
2794    // ARM pseudo code...
2795    EncodingSpecificOperations();
2796    ITSTATE.IT<7:0> = firstcond:mask;
2797#endif
2798
2799  m_it_session.InitIT(Bits32(opcode, 7, 0));
2800  return true;
2801}
2802
2803bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2804                                       const ARMEncoding encoding) {
2805  // NOP, nothing to do...
2806  return true;
2807}
2808
2809// Branch causes a branch to a target address.
2810bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2811                                     const ARMEncoding encoding) {
2812#if 0
2813    // ARM pseudo code...
2814    if (ConditionPassed())
2815    {
2816        EncodingSpecificOperations();
2817        BranchWritePC(PC + imm32);
2818    }
2819#endif
2820
2821  bool success = false;
2822
2823  if (ConditionPassed(opcode)) {
2824    EmulateInstruction::Context context;
2825    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2826    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2827    if (!success)
2828      return false;
2829    addr_t target; // target address
2830    int32_t imm32; // PC-relative offset
2831    switch (encoding) {
2832    case eEncodingT1:
2833      // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2834      imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2835      target = pc + imm32;
2836      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2837      break;
2838    case eEncodingT2:
2839      imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2840      target = pc + imm32;
2841      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2842      break;
2843    case eEncodingT3:
2844      // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2845      {
2846        if (Bits32(opcode, 25, 23) == 7)
2847          return false; // See Branches and miscellaneous control on page
2848                        // A6-235.
2849
2850        uint32_t S = Bit32(opcode, 26);
2851        uint32_t imm6 = Bits32(opcode, 21, 16);
2852        uint32_t J1 = Bit32(opcode, 13);
2853        uint32_t J2 = Bit32(opcode, 11);
2854        uint32_t imm11 = Bits32(opcode, 10, 0);
2855        uint32_t imm21 =
2856            (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2857        imm32 = llvm::SignExtend32<21>(imm21);
2858        target = pc + imm32;
2859        context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2860        break;
2861      }
2862    case eEncodingT4: {
2863      uint32_t S = Bit32(opcode, 26);
2864      uint32_t imm10 = Bits32(opcode, 25, 16);
2865      uint32_t J1 = Bit32(opcode, 13);
2866      uint32_t J2 = Bit32(opcode, 11);
2867      uint32_t imm11 = Bits32(opcode, 10, 0);
2868      uint32_t I1 = !(J1 ^ S);
2869      uint32_t I2 = !(J2 ^ S);
2870      uint32_t imm25 =
2871          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2872      imm32 = llvm::SignExtend32<25>(imm25);
2873      target = pc + imm32;
2874      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2875      break;
2876    }
2877    case eEncodingA1:
2878      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2879      target = pc + imm32;
2880      context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2881      break;
2882    default:
2883      return false;
2884    }
2885    if (!BranchWritePC(context, target))
2886      return false;
2887  }
2888  return true;
2889}
2890
2891// Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2892// value in a register with zero and conditionally branch forward a constant
2893// value.  They do not affect the condition flags. CBNZ, CBZ
2894bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2895                                      const ARMEncoding encoding) {
2896#if 0
2897    // ARM pseudo code...
2898    EncodingSpecificOperations();
2899    if nonzero ^ IsZero(R[n]) then
2900        BranchWritePC(PC + imm32);
2901#endif
2902
2903  bool success = false;
2904
2905  // Read the register value from the operand register Rn.
2906  uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2907  if (!success)
2908    return false;
2909
2910  EmulateInstruction::Context context;
2911  context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2912  const uint32_t pc = ReadCoreReg(PC_REG, &success);
2913  if (!success)
2914    return false;
2915
2916  addr_t target;  // target address
2917  uint32_t imm32; // PC-relative offset to branch forward
2918  bool nonzero;
2919  switch (encoding) {
2920  case eEncodingT1:
2921    imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2922    nonzero = BitIsSet(opcode, 11);
2923    target = pc + imm32;
2924    context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2925    break;
2926  default:
2927    return false;
2928  }
2929  if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2930    if (!BranchWritePC(context, target))
2931      return false;
2932
2933  return true;
2934}
2935
2936// Table Branch Byte causes a PC-relative forward branch using a table of
2937// single byte offsets.
2938// A base register provides a pointer to the table, and a second register
2939// supplies an index into the table.
2940// The branch length is twice the value of the byte returned from the table.
2941//
2942// Table Branch Halfword causes a PC-relative forward branch using a table of
2943// single halfword offsets.
2944// A base register provides a pointer to the table, and a second register
2945// supplies an index into the table.
2946// The branch length is twice the value of the halfword returned from the
2947// table. TBB, TBH
2948bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2949                                      const ARMEncoding encoding) {
2950#if 0
2951    // ARM pseudo code...
2952    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2953    if is_tbh then
2954        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2955    else
2956        halfwords = UInt(MemU[R[n]+R[m], 1]);
2957    BranchWritePC(PC + 2*halfwords);
2958#endif
2959
2960  bool success = false;
2961
2962  if (ConditionPassed(opcode)) {
2963    uint32_t Rn; // the base register which contains the address of the table of
2964                 // branch lengths
2965    uint32_t Rm; // the index register which contains an integer pointing to a
2966                 // byte/halfword in the table
2967    bool is_tbh; // true if table branch halfword
2968    switch (encoding) {
2969    case eEncodingT1:
2970      Rn = Bits32(opcode, 19, 16);
2971      Rm = Bits32(opcode, 3, 0);
2972      is_tbh = BitIsSet(opcode, 4);
2973      if (Rn == 13 || BadReg(Rm))
2974        return false;
2975      if (InITBlock() && !LastInITBlock())
2976        return false;
2977      break;
2978    default:
2979      return false;
2980    }
2981
2982    // Read the address of the table from the operand register Rn. The PC can
2983    // be used, in which case the table immediately follows this instruction.
2984    uint32_t base = ReadCoreReg(Rn, &success);
2985    if (!success)
2986      return false;
2987
2988    // the table index
2989    uint32_t index = ReadCoreReg(Rm, &success);
2990    if (!success)
2991      return false;
2992
2993    // the offsetted table address
2994    addr_t addr = base + (is_tbh ? index * 2 : index);
2995
2996    // PC-relative offset to branch forward
2997    EmulateInstruction::Context context;
2998    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2999    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
3000    if (!success)
3001      return false;
3002
3003    const uint32_t pc = ReadCoreReg(PC_REG, &success);
3004    if (!success)
3005      return false;
3006
3007    // target address
3008    addr_t target = pc + offset;
3009    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
3010    context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
3011
3012    if (!BranchWritePC(context, target))
3013      return false;
3014  }
3015
3016  return true;
3017}
3018
3019// This instruction adds an immediate value to a register value, and writes the
3020// result to the destination register. It can optionally update the condition
3021// flags based on the result.
3022bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
3023                                               const ARMEncoding encoding) {
3024#if 0
3025    if ConditionPassed() then
3026        EncodingSpecificOperations();
3027        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3028        R[d] = result;
3029        if setflags then
3030            APSR.N = result<31>;
3031            APSR.Z = IsZeroBit(result);
3032            APSR.C = carry;
3033            APSR.V = overflow;
3034#endif
3035
3036  bool success = false;
3037
3038  if (ConditionPassed(opcode)) {
3039    uint32_t d;
3040    uint32_t n;
3041    bool setflags;
3042    uint32_t imm32;
3043    uint32_t carry_out;
3044
3045    // EncodingSpecificOperations();
3046    switch (encoding) {
3047    case eEncodingT1:
3048      // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
3049      // ZeroExtend(imm3, 32);
3050      d = Bits32(opcode, 2, 0);
3051      n = Bits32(opcode, 5, 3);
3052      setflags = !InITBlock();
3053      imm32 = Bits32(opcode, 8, 6);
3054
3055      break;
3056
3057    case eEncodingT2:
3058      // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
3059      // ZeroExtend(imm8, 32);
3060      d = Bits32(opcode, 10, 8);
3061      n = Bits32(opcode, 10, 8);
3062      setflags = !InITBlock();
3063      imm32 = Bits32(opcode, 7, 0);
3064
3065      break;
3066
3067    case eEncodingT3:
3068      // if Rd == '1111' && S == '1' then SEE CMN (immediate);
3069      // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
3070      // ThumbExpandImm(i:imm3:imm8);
3071      d = Bits32(opcode, 11, 8);
3072      n = Bits32(opcode, 19, 16);
3073      setflags = BitIsSet(opcode, 20);
3074      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
3075
3076      // if Rn == '1101' then SEE ADD (SP plus immediate);
3077      if (n == 13)
3078        return EmulateADDSPImm(opcode, eEncodingT3);
3079
3080      // if BadReg(d) || n == 15 then UNPREDICTABLE;
3081      if (BadReg(d) || (n == 15))
3082        return false;
3083
3084      break;
3085
3086    case eEncodingT4: {
3087      // if Rn == '1111' then SEE ADR;
3088      // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
3089      // ZeroExtend(i:imm3:imm8, 32);
3090      d = Bits32(opcode, 11, 8);
3091      n = Bits32(opcode, 19, 16);
3092      setflags = false;
3093      uint32_t i = Bit32(opcode, 26);
3094      uint32_t imm3 = Bits32(opcode, 14, 12);
3095      uint32_t imm8 = Bits32(opcode, 7, 0);
3096      imm32 = (i << 11) | (imm3 << 8) | imm8;
3097
3098      // if Rn == '1101' then SEE ADD (SP plus immediate);
3099      if (n == 13)
3100        return EmulateADDSPImm(opcode, eEncodingT4);
3101
3102      // if BadReg(d) then UNPREDICTABLE;
3103      if (BadReg(d))
3104        return false;
3105
3106      break;
3107    }
3108
3109    default:
3110      return false;
3111    }
3112
3113    uint64_t Rn =
3114        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3115    if (!success)
3116      return false;
3117
3118    //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3119    AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
3120
3121    RegisterInfo reg_n;
3122    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
3123
3124    EmulateInstruction::Context context;
3125    context.type = eContextArithmetic;
3126    context.SetRegisterPlusOffset(reg_n, imm32);
3127
3128    // R[d] = result;
3129    // if setflags then
3130    // APSR.N = result<31>;
3131    // APSR.Z = IsZeroBit(result);
3132    // APSR.C = carry;
3133    // APSR.V = overflow;
3134    if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
3135                                   res.carry_out, res.overflow))
3136      return false;
3137  }
3138  return true;
3139}
3140
3141// This instruction adds an immediate value to a register value, and writes the
3142// result to the destination register.  It can optionally update the condition
3143// flags based on the result.
3144bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
3145                                             const ARMEncoding encoding) {
3146#if 0
3147    // ARM pseudo code...
3148    if ConditionPassed() then
3149        EncodingSpecificOperations();
3150        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3151        if d == 15 then
3152            ALUWritePC(result); // setflags is always FALSE here
3153        else
3154            R[d] = result;
3155            if setflags then
3156                APSR.N = result<31>;
3157                APSR.Z = IsZeroBit(result);
3158                APSR.C = carry;
3159                APSR.V = overflow;
3160#endif
3161
3162  bool success = false;
3163
3164  if (ConditionPassed(opcode)) {
3165    uint32_t Rd, Rn;
3166    uint32_t
3167        imm32; // the immediate value to be added to the value obtained from Rn
3168    bool setflags;
3169    switch (encoding) {
3170    case eEncodingA1:
3171      Rd = Bits32(opcode, 15, 12);
3172      Rn = Bits32(opcode, 19, 16);
3173      setflags = BitIsSet(opcode, 20);
3174      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3175      break;
3176    default:
3177      return false;
3178    }
3179
3180    // Read the first operand.
3181    uint32_t val1 = ReadCoreReg(Rn, &success);
3182    if (!success)
3183      return false;
3184
3185    AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
3186
3187    EmulateInstruction::Context context;
3188    if (Rd == 13)
3189      context.type = EmulateInstruction::eContextAdjustStackPointer;
3190    else if (Rd == GetFramePointerRegisterNumber())
3191      context.type = EmulateInstruction::eContextSetFramePointer;
3192    else
3193      context.type = EmulateInstruction::eContextRegisterPlusOffset;
3194
3195    RegisterInfo dwarf_reg;
3196    GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
3197    context.SetRegisterPlusOffset(dwarf_reg, imm32);
3198
3199    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3200                                   res.carry_out, res.overflow))
3201      return false;
3202  }
3203  return true;
3204}
3205
3206// This instruction adds a register value and an optionally-shifted register
3207// value, and writes the result to the destination register. It can optionally
3208// update the condition flags based on the result.
3209bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
3210                                          const ARMEncoding encoding) {
3211#if 0
3212    // ARM pseudo code...
3213    if ConditionPassed() then
3214        EncodingSpecificOperations();
3215        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3216        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3217        if d == 15 then
3218            ALUWritePC(result); // setflags is always FALSE here
3219        else
3220            R[d] = result;
3221            if setflags then
3222                APSR.N = result<31>;
3223                APSR.Z = IsZeroBit(result);
3224                APSR.C = carry;
3225                APSR.V = overflow;
3226#endif
3227
3228  bool success = false;
3229
3230  if (ConditionPassed(opcode)) {
3231    uint32_t Rd, Rn, Rm;
3232    ARM_ShifterType shift_t;
3233    uint32_t shift_n; // the shift applied to the value read from Rm
3234    bool setflags;
3235    switch (encoding) {
3236    case eEncodingT1:
3237      Rd = Bits32(opcode, 2, 0);
3238      Rn = Bits32(opcode, 5, 3);
3239      Rm = Bits32(opcode, 8, 6);
3240      setflags = !InITBlock();
3241      shift_t = SRType_LSL;
3242      shift_n = 0;
3243      break;
3244    case eEncodingT2:
3245      Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3246      Rm = Bits32(opcode, 6, 3);
3247      setflags = false;
3248      shift_t = SRType_LSL;
3249      shift_n = 0;
3250      if (Rn == 15 && Rm == 15)
3251        return false;
3252      if (Rd == 15 && InITBlock() && !LastInITBlock())
3253        return false;
3254      break;
3255    case eEncodingA1:
3256      Rd = Bits32(opcode, 15, 12);
3257      Rn = Bits32(opcode, 19, 16);
3258      Rm = Bits32(opcode, 3, 0);
3259      setflags = BitIsSet(opcode, 20);
3260      shift_n = DecodeImmShiftARM(opcode, shift_t);
3261      break;
3262    default:
3263      return false;
3264    }
3265
3266    // Read the first operand.
3267    uint32_t val1 = ReadCoreReg(Rn, &success);
3268    if (!success)
3269      return false;
3270
3271    // Read the second operand.
3272    uint32_t val2 = ReadCoreReg(Rm, &success);
3273    if (!success)
3274      return false;
3275
3276    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3277    if (!success)
3278      return false;
3279    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3280
3281    EmulateInstruction::Context context;
3282    context.type = eContextArithmetic;
3283    RegisterInfo op1_reg;
3284    RegisterInfo op2_reg;
3285    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
3286    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
3287    context.SetRegisterRegisterOperands(op1_reg, op2_reg);
3288
3289    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3290                                   res.carry_out, res.overflow))
3291      return false;
3292  }
3293  return true;
3294}
3295
3296// Compare Negative (immediate) adds a register value and an immediate value.
3297// It updates the condition flags based on the result, and discards the result.
3298bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
3299                                          const ARMEncoding encoding) {
3300#if 0
3301    // ARM pseudo code...
3302    if ConditionPassed() then
3303        EncodingSpecificOperations();
3304        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3305        APSR.N = result<31>;
3306        APSR.Z = IsZeroBit(result);
3307        APSR.C = carry;
3308        APSR.V = overflow;
3309#endif
3310
3311  bool success = false;
3312
3313  uint32_t Rn;    // the first operand
3314  uint32_t imm32; // the immediate value to be compared with
3315  switch (encoding) {
3316  case eEncodingT1:
3317    Rn = Bits32(opcode, 19, 16);
3318    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3319    if (Rn == 15)
3320      return false;
3321    break;
3322  case eEncodingA1:
3323    Rn = Bits32(opcode, 19, 16);
3324    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3325    break;
3326  default:
3327    return false;
3328  }
3329  // Read the register value from the operand register Rn.
3330  uint32_t reg_val = ReadCoreReg(Rn, &success);
3331  if (!success)
3332    return false;
3333
3334  AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
3335
3336  EmulateInstruction::Context context;
3337  context.type = EmulateInstruction::eContextImmediate;
3338  context.SetNoArgs();
3339  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3340}
3341
3342// Compare Negative (register) adds a register value and an optionally-shifted
3343// register value. It updates the condition flags based on the result, and
3344// discards the result.
3345bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
3346                                          const ARMEncoding encoding) {
3347#if 0
3348    // ARM pseudo code...
3349    if ConditionPassed() then
3350        EncodingSpecificOperations();
3351        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3352        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3353        APSR.N = result<31>;
3354        APSR.Z = IsZeroBit(result);
3355        APSR.C = carry;
3356        APSR.V = overflow;
3357#endif
3358
3359  bool success = false;
3360
3361  uint32_t Rn; // the first operand
3362  uint32_t Rm; // the second operand
3363  ARM_ShifterType shift_t;
3364  uint32_t shift_n; // the shift applied to the value read from Rm
3365  switch (encoding) {
3366  case eEncodingT1:
3367    Rn = Bits32(opcode, 2, 0);
3368    Rm = Bits32(opcode, 5, 3);
3369    shift_t = SRType_LSL;
3370    shift_n = 0;
3371    break;
3372  case eEncodingT2:
3373    Rn = Bits32(opcode, 19, 16);
3374    Rm = Bits32(opcode, 3, 0);
3375    shift_n = DecodeImmShiftThumb(opcode, shift_t);
3376    // if n == 15 || BadReg(m) then UNPREDICTABLE;
3377    if (Rn == 15 || BadReg(Rm))
3378      return false;
3379    break;
3380  case eEncodingA1:
3381    Rn = Bits32(opcode, 19, 16);
3382    Rm = Bits32(opcode, 3, 0);
3383    shift_n = DecodeImmShiftARM(opcode, shift_t);
3384    break;
3385  default:
3386    return false;
3387  }
3388  // Read the register value from register Rn.
3389  uint32_t val1 = ReadCoreReg(Rn, &success);
3390  if (!success)
3391    return false;
3392
3393  // Read the register value from register Rm.
3394  uint32_t val2 = ReadCoreReg(Rm, &success);
3395  if (!success)
3396    return false;
3397
3398  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3399  if (!success)
3400    return false;
3401  AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3402
3403  EmulateInstruction::Context context;
3404  context.type = EmulateInstruction::eContextImmediate;
3405  context.SetNoArgs();
3406  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3407}
3408
3409// Compare (immediate) subtracts an immediate value from a register value. It
3410// updates the condition flags based on the result, and discards the result.
3411bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
3412                                          const ARMEncoding encoding) {
3413#if 0
3414    // ARM pseudo code...
3415    if ConditionPassed() then
3416        EncodingSpecificOperations();
3417        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
3418        APSR.N = result<31>;
3419        APSR.Z = IsZeroBit(result);
3420        APSR.C = carry;
3421        APSR.V = overflow;
3422#endif
3423
3424  bool success = false;
3425
3426  uint32_t Rn;    // the first operand
3427  uint32_t imm32; // the immediate value to be compared with
3428  switch (encoding) {
3429  case eEncodingT1:
3430    Rn = Bits32(opcode, 10, 8);
3431    imm32 = Bits32(opcode, 7, 0);
3432    break;
3433  case eEncodingT2:
3434    Rn = Bits32(opcode, 19, 16);
3435    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3436    if (Rn == 15)
3437      return false;
3438    break;
3439  case eEncodingA1:
3440    Rn = Bits32(opcode, 19, 16);
3441    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3442    break;
3443  default:
3444    return false;
3445  }
3446  // Read the register value from the operand register Rn.
3447  uint32_t reg_val = ReadCoreReg(Rn, &success);
3448  if (!success)
3449    return false;
3450
3451  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
3452
3453  EmulateInstruction::Context context;
3454  context.type = EmulateInstruction::eContextImmediate;
3455  context.SetNoArgs();
3456  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3457}
3458
3459// Compare (register) subtracts an optionally-shifted register value from a
3460// register value. It updates the condition flags based on the result, and
3461// discards the result.
3462bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
3463                                          const ARMEncoding encoding) {
3464#if 0
3465    // ARM pseudo code...
3466    if ConditionPassed() then
3467        EncodingSpecificOperations();
3468        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3469        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
3470        APSR.N = result<31>;
3471        APSR.Z = IsZeroBit(result);
3472        APSR.C = carry;
3473        APSR.V = overflow;
3474#endif
3475
3476  bool success = false;
3477
3478  uint32_t Rn; // the first operand
3479  uint32_t Rm; // the second operand
3480  ARM_ShifterType shift_t;
3481  uint32_t shift_n; // the shift applied to the value read from Rm
3482  switch (encoding) {
3483  case eEncodingT1:
3484    Rn = Bits32(opcode, 2, 0);
3485    Rm = Bits32(opcode, 5, 3);
3486    shift_t = SRType_LSL;
3487    shift_n = 0;
3488    break;
3489  case eEncodingT2:
3490    Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3491    Rm = Bits32(opcode, 6, 3);
3492    shift_t = SRType_LSL;
3493    shift_n = 0;
3494    if (Rn < 8 && Rm < 8)
3495      return false;
3496    if (Rn == 15 || Rm == 15)
3497      return false;
3498    break;
3499  case eEncodingT3:
3500    Rn = Bits32(opcode, 19, 16);
3501    Rm = Bits32(opcode, 3, 0);
3502    shift_n = DecodeImmShiftThumb(opcode, shift_t);
3503    if (Rn == 15 || BadReg(Rm))
3504      return false;
3505    break;
3506  case eEncodingA1:
3507    Rn = Bits32(opcode, 19, 16);
3508    Rm = Bits32(opcode, 3, 0);
3509    shift_n = DecodeImmShiftARM(opcode, shift_t);
3510    break;
3511  default:
3512    return false;
3513  }
3514  // Read the register value from register Rn.
3515  uint32_t val1 = ReadCoreReg(Rn, &success);
3516  if (!success)
3517    return false;
3518
3519  // Read the register value from register Rm.
3520  uint32_t val2 = ReadCoreReg(Rm, &success);
3521  if (!success)
3522    return false;
3523
3524  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3525  if (!success)
3526    return false;
3527  AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3528
3529  EmulateInstruction::Context context;
3530  context.type = EmulateInstruction::eContextImmediate;
3531  context.SetNoArgs();
3532  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3533}
3534
3535// Arithmetic Shift Right (immediate) shifts a register value right by an
3536// immediate number of bits, shifting in copies of its sign bit, and writes the
3537// result to the destination register.  It can optionally update the condition
3538// flags based on the result.
3539bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3540                                          const ARMEncoding encoding) {
3541#if 0
3542    // ARM pseudo code...
3543    if ConditionPassed() then
3544        EncodingSpecificOperations();
3545        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3546        if d == 15 then         // Can only occur for ARM encoding
3547            ALUWritePC(result); // setflags is always FALSE here
3548        else
3549            R[d] = result;
3550            if setflags then
3551                APSR.N = result<31>;
3552                APSR.Z = IsZeroBit(result);
3553                APSR.C = carry;
3554                // APSR.V unchanged
3555#endif
3556
3557  return EmulateShiftImm(opcode, encoding, SRType_ASR);
3558}
3559
3560// Arithmetic Shift Right (register) shifts a register value right by a
3561// variable number of bits, shifting in copies of its sign bit, and writes the
3562// result to the destination register. The variable number of bits is read from
3563// the bottom byte of a register. It can optionally update the condition flags
3564// based on the result.
3565bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3566                                          const ARMEncoding encoding) {
3567#if 0
3568    // ARM pseudo code...
3569    if ConditionPassed() then
3570        EncodingSpecificOperations();
3571        shift_n = UInt(R[m]<7:0>);
3572        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3573        R[d] = result;
3574        if setflags then
3575            APSR.N = result<31>;
3576            APSR.Z = IsZeroBit(result);
3577            APSR.C = carry;
3578            // APSR.V unchanged
3579#endif
3580
3581  return EmulateShiftReg(opcode, encoding, SRType_ASR);
3582}
3583
3584// Logical Shift Left (immediate) shifts a register value left by an immediate
3585// number of bits, shifting in zeros, and writes the result to the destination
3586// register.  It can optionally update the condition flags based on the result.
3587bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3588                                          const ARMEncoding encoding) {
3589#if 0
3590    // ARM pseudo code...
3591    if ConditionPassed() then
3592        EncodingSpecificOperations();
3593        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3594        if d == 15 then         // Can only occur for ARM encoding
3595            ALUWritePC(result); // setflags is always FALSE here
3596        else
3597            R[d] = result;
3598            if setflags then
3599                APSR.N = result<31>;
3600                APSR.Z = IsZeroBit(result);
3601                APSR.C = carry;
3602                // APSR.V unchanged
3603#endif
3604
3605  return EmulateShiftImm(opcode, encoding, SRType_LSL);
3606}
3607
3608// Logical Shift Left (register) shifts a register value left by a variable
3609// number of bits, shifting in zeros, and writes the result to the destination
3610// register.  The variable number of bits is read from the bottom byte of a
3611// register. It can optionally update the condition flags based on the result.
3612bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3613                                          const ARMEncoding encoding) {
3614#if 0
3615    // ARM pseudo code...
3616    if ConditionPassed() then
3617        EncodingSpecificOperations();
3618        shift_n = UInt(R[m]<7:0>);
3619        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3620        R[d] = result;
3621        if setflags then
3622            APSR.N = result<31>;
3623            APSR.Z = IsZeroBit(result);
3624            APSR.C = carry;
3625            // APSR.V unchanged
3626#endif
3627
3628  return EmulateShiftReg(opcode, encoding, SRType_LSL);
3629}
3630
3631// Logical Shift Right (immediate) shifts a register value right by an
3632// immediate number of bits, shifting in zeros, and writes the result to the
3633// destination register.  It can optionally update the condition flags based on
3634// the result.
3635bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3636                                          const ARMEncoding encoding) {
3637#if 0
3638    // ARM pseudo code...
3639    if ConditionPassed() then
3640        EncodingSpecificOperations();
3641        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3642        if d == 15 then         // Can only occur for ARM encoding
3643            ALUWritePC(result); // setflags is always FALSE here
3644        else
3645            R[d] = result;
3646            if setflags then
3647                APSR.N = result<31>;
3648                APSR.Z = IsZeroBit(result);
3649                APSR.C = carry;
3650                // APSR.V unchanged
3651#endif
3652
3653  return EmulateShiftImm(opcode, encoding, SRType_LSR);
3654}
3655
3656// Logical Shift Right (register) shifts a register value right by a variable
3657// number of bits, shifting in zeros, and writes the result to the destination
3658// register.  The variable number of bits is read from the bottom byte of a
3659// register. It can optionally update the condition flags based on the result.
3660bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3661                                          const ARMEncoding encoding) {
3662#if 0
3663    // ARM pseudo code...
3664    if ConditionPassed() then
3665        EncodingSpecificOperations();
3666        shift_n = UInt(R[m]<7:0>);
3667        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3668        R[d] = result;
3669        if setflags then
3670            APSR.N = result<31>;
3671            APSR.Z = IsZeroBit(result);
3672            APSR.C = carry;
3673            // APSR.V unchanged
3674#endif
3675
3676  return EmulateShiftReg(opcode, encoding, SRType_LSR);
3677}
3678
3679// Rotate Right (immediate) provides the value of the contents of a register
3680// rotated by a constant value. The bits that are rotated off the right end are
3681// inserted into the vacated bit positions on the left. It can optionally
3682// update the condition flags based on the result.
3683bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3684                                          const ARMEncoding encoding) {
3685#if 0
3686    // ARM pseudo code...
3687    if ConditionPassed() then
3688        EncodingSpecificOperations();
3689        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3690        if d == 15 then         // Can only occur for ARM encoding
3691            ALUWritePC(result); // setflags is always FALSE here
3692        else
3693            R[d] = result;
3694            if setflags then
3695                APSR.N = result<31>;
3696                APSR.Z = IsZeroBit(result);
3697                APSR.C = carry;
3698                // APSR.V unchanged
3699#endif
3700
3701  return EmulateShiftImm(opcode, encoding, SRType_ROR);
3702}
3703
3704// Rotate Right (register) provides the value of the contents of a register
3705// rotated by a variable number of bits. The bits that are rotated off the
3706// right end are inserted into the vacated bit positions on the left. The
3707// variable number of bits is read from the bottom byte of a register. It can
3708// optionally update the condition flags based on the result.
3709bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3710                                          const ARMEncoding encoding) {
3711#if 0
3712    // ARM pseudo code...
3713    if ConditionPassed() then
3714        EncodingSpecificOperations();
3715        shift_n = UInt(R[m]<7:0>);
3716        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3717        R[d] = result;
3718        if setflags then
3719            APSR.N = result<31>;
3720            APSR.Z = IsZeroBit(result);
3721            APSR.C = carry;
3722            // APSR.V unchanged
3723#endif
3724
3725  return EmulateShiftReg(opcode, encoding, SRType_ROR);
3726}
3727
3728// Rotate Right with Extend provides the value of the contents of a register
3729// shifted right by one place, with the carry flag shifted into bit [31].
3730//
3731// RRX can optionally update the condition flags based on the result.
3732// In that case, bit [0] is shifted into the carry flag.
3733bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3734                                       const ARMEncoding encoding) {
3735#if 0
3736    // ARM pseudo code...
3737    if ConditionPassed() then
3738        EncodingSpecificOperations();
3739        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3740        if d == 15 then         // Can only occur for ARM encoding
3741            ALUWritePC(result); // setflags is always FALSE here
3742        else
3743            R[d] = result;
3744            if setflags then
3745                APSR.N = result<31>;
3746                APSR.Z = IsZeroBit(result);
3747                APSR.C = carry;
3748                // APSR.V unchanged
3749#endif
3750
3751  return EmulateShiftImm(opcode, encoding, SRType_RRX);
3752}
3753
3754bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
3755                                            const ARMEncoding encoding,
3756                                            ARM_ShifterType shift_type) {
3757  //    assert(shift_type == SRType_ASR
3758  //           || shift_type == SRType_LSL
3759  //           || shift_type == SRType_LSR
3760  //           || shift_type == SRType_ROR
3761  //           || shift_type == SRType_RRX);
3762
3763  bool success = false;
3764
3765  if (ConditionPassed(opcode)) {
3766    uint32_t Rd;    // the destination register
3767    uint32_t Rm;    // the first operand register
3768    uint32_t imm5;  // encoding for the shift amount
3769    uint32_t carry; // the carry bit after the shift operation
3770    bool setflags;
3771
3772    // Special case handling!
3773    // A8.6.139 ROR (immediate) -- Encoding T1
3774    ARMEncoding use_encoding = encoding;
3775    if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3776      // Morph the T1 encoding from the ARM Architecture Manual into T2
3777      // encoding to have the same decoding of bit fields as the other Thumb2
3778      // shift operations.
3779      use_encoding = eEncodingT2;
3780    }
3781
3782    switch (use_encoding) {
3783    case eEncodingT1:
3784      // Due to the above special case handling!
3785      if (shift_type == SRType_ROR)
3786        return false;
3787
3788      Rd = Bits32(opcode, 2, 0);
3789      Rm = Bits32(opcode, 5, 3);
3790      setflags = !InITBlock();
3791      imm5 = Bits32(opcode, 10, 6);
3792      break;
3793    case eEncodingT2:
3794      // A8.6.141 RRX
3795      // There's no imm form of RRX instructions.
3796      if (shift_type == SRType_RRX)
3797        return false;
3798
3799      Rd = Bits32(opcode, 11, 8);
3800      Rm = Bits32(opcode, 3, 0);
3801      setflags = BitIsSet(opcode, 20);
3802      imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3803      if (BadReg(Rd) || BadReg(Rm))
3804        return false;
3805      break;
3806    case eEncodingA1:
3807      Rd = Bits32(opcode, 15, 12);
3808      Rm = Bits32(opcode, 3, 0);
3809      setflags = BitIsSet(opcode, 20);
3810      imm5 = Bits32(opcode, 11, 7);
3811      break;
3812    default:
3813      return false;
3814    }
3815
3816    // A8.6.139 ROR (immediate)
3817    if (shift_type == SRType_ROR && imm5 == 0)
3818      shift_type = SRType_RRX;
3819
3820    // Get the first operand.
3821    uint32_t value = ReadCoreReg(Rm, &success);
3822    if (!success)
3823      return false;
3824
3825    // Decode the shift amount if not RRX.
3826    uint32_t amt =
3827        (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3828
3829    uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3830    if (!success)
3831      return false;
3832
3833    // The context specifies that an immediate is to be moved into Rd.
3834    EmulateInstruction::Context context;
3835    context.type = EmulateInstruction::eContextImmediate;
3836    context.SetNoArgs();
3837
3838    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3839      return false;
3840  }
3841  return true;
3842}
3843
3844bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
3845                                            const ARMEncoding encoding,
3846                                            ARM_ShifterType shift_type) {
3847  // assert(shift_type == SRType_ASR
3848  //        || shift_type == SRType_LSL
3849  //        || shift_type == SRType_LSR
3850  //        || shift_type == SRType_ROR);
3851
3852  bool success = false;
3853
3854  if (ConditionPassed(opcode)) {
3855    uint32_t Rd; // the destination register
3856    uint32_t Rn; // the first operand register
3857    uint32_t
3858        Rm; // the register whose bottom byte contains the amount to shift by
3859    uint32_t carry; // the carry bit after the shift operation
3860    bool setflags;
3861    switch (encoding) {
3862    case eEncodingT1:
3863      Rd = Bits32(opcode, 2, 0);
3864      Rn = Rd;
3865      Rm = Bits32(opcode, 5, 3);
3866      setflags = !InITBlock();
3867      break;
3868    case eEncodingT2:
3869      Rd = Bits32(opcode, 11, 8);
3870      Rn = Bits32(opcode, 19, 16);
3871      Rm = Bits32(opcode, 3, 0);
3872      setflags = BitIsSet(opcode, 20);
3873      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3874        return false;
3875      break;
3876    case eEncodingA1:
3877      Rd = Bits32(opcode, 15, 12);
3878      Rn = Bits32(opcode, 3, 0);
3879      Rm = Bits32(opcode, 11, 8);
3880      setflags = BitIsSet(opcode, 20);
3881      if (Rd == 15 || Rn == 15 || Rm == 15)
3882        return false;
3883      break;
3884    default:
3885      return false;
3886    }
3887
3888    // Get the first operand.
3889    uint32_t value = ReadCoreReg(Rn, &success);
3890    if (!success)
3891      return false;
3892    // Get the Rm register content.
3893    uint32_t val = ReadCoreReg(Rm, &success);
3894    if (!success)
3895      return false;
3896
3897    // Get the shift amount.
3898    uint32_t amt = Bits32(val, 7, 0);
3899
3900    uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3901    if (!success)
3902      return false;
3903
3904    // The context specifies that an immediate is to be moved into Rd.
3905    EmulateInstruction::Context context;
3906    context.type = EmulateInstruction::eContextImmediate;
3907    context.SetNoArgs();
3908
3909    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3910      return false;
3911  }
3912  return true;
3913}
3914
3915// LDM loads multiple registers from consecutive memory locations, using an
3916// address from a base register.  Optionally the address just above the highest
3917// of those locations can be written back to the base register.
3918bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3919                                       const ARMEncoding encoding) {
3920#if 0
3921    // ARM pseudo code...
3922    if ConditionPassed()
3923        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3924        address = R[n];
3925
3926        for i = 0 to 14
3927            if registers<i> == '1' then
3928                R[i] = MemA[address, 4]; address = address + 4;
3929        if registers<15> == '1' then
3930            LoadWritePC (MemA[address, 4]);
3931
3932        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3933        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3934
3935#endif
3936
3937  bool success = false;
3938  if (ConditionPassed(opcode)) {
3939    uint32_t n;
3940    uint32_t registers = 0;
3941    bool wback;
3942    const uint32_t addr_byte_size = GetAddressByteSize();
3943    switch (encoding) {
3944    case eEncodingT1:
3945      // n = UInt(Rn); registers = '00000000':register_list; wback =
3946      // (registers<n> == '0');
3947      n = Bits32(opcode, 10, 8);
3948      registers = Bits32(opcode, 7, 0);
3949      registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3950      wback = BitIsClear(registers, n);
3951      // if BitCount(registers) < 1 then UNPREDICTABLE;
3952      if (BitCount(registers) < 1)
3953        return false;
3954      break;
3955    case eEncodingT2:
3956      // if W == '1' && Rn == '1101' then SEE POP;
3957      // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3958      n = Bits32(opcode, 19, 16);
3959      registers = Bits32(opcode, 15, 0);
3960      registers = registers & 0xdfff; // Make sure bit 13 is zero.
3961      wback = BitIsSet(opcode, 21);
3962
3963      // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3964      // UNPREDICTABLE;
3965      if ((n == 15) || (BitCount(registers) < 2) ||
3966          (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3967        return false;
3968
3969      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3970      // UNPREDICTABLE;
3971      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3972        return false;
3973
3974      // if wback && registers<n> == '1' then UNPREDICTABLE;
3975      if (wback && BitIsSet(registers, n))
3976        return false;
3977      break;
3978
3979    case eEncodingA1:
3980      n = Bits32(opcode, 19, 16);
3981      registers = Bits32(opcode, 15, 0);
3982      wback = BitIsSet(opcode, 21);
3983      if ((n == 15) || (BitCount(registers) < 1))
3984        return false;
3985      break;
3986    default:
3987      return false;
3988    }
3989
3990    int32_t offset = 0;
3991    const addr_t base_address =
3992        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3993    if (!success)
3994      return false;
3995
3996    EmulateInstruction::Context context;
3997    context.type = EmulateInstruction::eContextRegisterPlusOffset;
3998    RegisterInfo dwarf_reg;
3999    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4000    context.SetRegisterPlusOffset(dwarf_reg, offset);
4001
4002    for (int i = 0; i < 14; ++i) {
4003      if (BitIsSet(registers, i)) {
4004        context.type = EmulateInstruction::eContextRegisterPlusOffset;
4005        context.SetRegisterPlusOffset(dwarf_reg, offset);
4006        if (wback && (n == 13)) // Pop Instruction
4007        {
4008          context.type = EmulateInstruction::eContextPopRegisterOffStack;
4009          context.SetAddress(base_address + offset);
4010        }
4011
4012        // R[i] = MemA [address, 4]; address = address + 4;
4013        uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
4014                                 0, &success);
4015        if (!success)
4016          return false;
4017
4018        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4019                                   data))
4020          return false;
4021
4022        offset += addr_byte_size;
4023      }
4024    }
4025
4026    if (BitIsSet(registers, 15)) {
4027      // LoadWritePC (MemA [address, 4]);
4028      context.type = EmulateInstruction::eContextRegisterPlusOffset;
4029      context.SetRegisterPlusOffset(dwarf_reg, offset);
4030      uint32_t data =
4031          MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4032      if (!success)
4033        return false;
4034      // In ARMv5T and above, this is an interworking branch.
4035      if (!LoadWritePC(context, data))
4036        return false;
4037    }
4038
4039    if (wback && BitIsClear(registers, n)) {
4040      // R[n] = R[n] + 4 * BitCount (registers)
4041      int32_t offset = addr_byte_size * BitCount(registers);
4042      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4043      context.SetRegisterPlusOffset(dwarf_reg, offset);
4044
4045      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4046                                 base_address + offset))
4047        return false;
4048    }
4049    if (wback && BitIsSet(registers, n))
4050      // R[n] bits(32) UNKNOWN;
4051      return WriteBits32Unknown(n);
4052  }
4053  return true;
4054}
4055
4056// LDMDA loads multiple registers from consecutive memory locations using an
4057// address from a base register.
4058// The consecutive memory locations end at this address and the address just
4059// below the lowest of those locations can optionally be written back to the
4060// base register.
4061bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
4062                                         const ARMEncoding encoding) {
4063#if 0
4064    // ARM pseudo code...
4065    if ConditionPassed() then
4066        EncodingSpecificOperations();
4067        address = R[n] - 4*BitCount(registers) + 4;
4068
4069        for i = 0 to 14
4070            if registers<i> == '1' then
4071                  R[i] = MemA[address,4]; address = address + 4;
4072
4073        if registers<15> == '1' then
4074            LoadWritePC(MemA[address,4]);
4075
4076        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4077        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4078#endif
4079
4080  bool success = false;
4081
4082  if (ConditionPassed(opcode)) {
4083    uint32_t n;
4084    uint32_t registers = 0;
4085    bool wback;
4086    const uint32_t addr_byte_size = GetAddressByteSize();
4087
4088    // EncodingSpecificOperations();
4089    switch (encoding) {
4090    case eEncodingA1:
4091      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4092      n = Bits32(opcode, 19, 16);
4093      registers = Bits32(opcode, 15, 0);
4094      wback = BitIsSet(opcode, 21);
4095
4096      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4097      if ((n == 15) || (BitCount(registers) < 1))
4098        return false;
4099
4100      break;
4101
4102    default:
4103      return false;
4104    }
4105    // address = R[n] - 4*BitCount(registers) + 4;
4106
4107    int32_t offset = 0;
4108    addr_t Rn = ReadCoreReg(n, &success);
4109
4110    if (!success)
4111      return false;
4112
4113    addr_t address =
4114        Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
4115
4116    EmulateInstruction::Context context;
4117    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4118    RegisterInfo dwarf_reg;
4119    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4120    context.SetRegisterPlusOffset(dwarf_reg, offset);
4121
4122    // for i = 0 to 14
4123    for (int i = 0; i < 14; ++i) {
4124      // if registers<i> == '1' then
4125      if (BitIsSet(registers, i)) {
4126        // R[i] = MemA[address,4]; address = address + 4;
4127        context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4128        uint32_t data =
4129            MemARead(context, address + offset, addr_byte_size, 0, &success);
4130        if (!success)
4131          return false;
4132        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4133                                   data))
4134          return false;
4135        offset += addr_byte_size;
4136      }
4137    }
4138
4139    // if registers<15> == '1' then
4140    //     LoadWritePC(MemA[address,4]);
4141    if (BitIsSet(registers, 15)) {
4142      context.SetRegisterPlusOffset(dwarf_reg, offset);
4143      uint32_t data =
4144          MemARead(context, address + offset, addr_byte_size, 0, &success);
4145      if (!success)
4146        return false;
4147      // In ARMv5T and above, this is an interworking branch.
4148      if (!LoadWritePC(context, data))
4149        return false;
4150    }
4151
4152    // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4153    if (wback && BitIsClear(registers, n)) {
4154      if (!success)
4155        return false;
4156
4157      offset = (addr_byte_size * BitCount(registers)) * -1;
4158      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4159      context.SetImmediateSigned(offset);
4160      addr_t addr = Rn + offset;
4161      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4162                                 addr))
4163        return false;
4164    }
4165
4166    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4167    if (wback && BitIsSet(registers, n))
4168      return WriteBits32Unknown(n);
4169  }
4170  return true;
4171}
4172
4173// LDMDB loads multiple registers from consecutive memory locations using an
4174// address from a base register.  The
4175// consecutive memory locations end just below this address, and the address of
4176// the lowest of those locations can be optionally written back to the base
4177// register.
4178bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
4179                                         const ARMEncoding encoding) {
4180#if 0
4181    // ARM pseudo code...
4182    if ConditionPassed() then
4183        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4184        address = R[n] - 4*BitCount(registers);
4185
4186        for i = 0 to 14
4187            if registers<i> == '1' then
4188                  R[i] = MemA[address,4]; address = address + 4;
4189        if registers<15> == '1' then
4190                  LoadWritePC(MemA[address,4]);
4191
4192        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4193        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
4194#endif
4195
4196  bool success = false;
4197
4198  if (ConditionPassed(opcode)) {
4199    uint32_t n;
4200    uint32_t registers = 0;
4201    bool wback;
4202    const uint32_t addr_byte_size = GetAddressByteSize();
4203    switch (encoding) {
4204    case eEncodingT1:
4205      // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
4206      n = Bits32(opcode, 19, 16);
4207      registers = Bits32(opcode, 15, 0);
4208      registers = registers & 0xdfff; // Make sure bit 13 is a zero.
4209      wback = BitIsSet(opcode, 21);
4210
4211      // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4212      // UNPREDICTABLE;
4213      if ((n == 15) || (BitCount(registers) < 2) ||
4214          (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4215        return false;
4216
4217      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4218      // UNPREDICTABLE;
4219      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4220        return false;
4221
4222      // if wback && registers<n> == '1' then UNPREDICTABLE;
4223      if (wback && BitIsSet(registers, n))
4224        return false;
4225
4226      break;
4227
4228    case eEncodingA1:
4229      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4230      n = Bits32(opcode, 19, 16);
4231      registers = Bits32(opcode, 15, 0);
4232      wback = BitIsSet(opcode, 21);
4233
4234      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4235      if ((n == 15) || (BitCount(registers) < 1))
4236        return false;
4237
4238      break;
4239
4240    default:
4241      return false;
4242    }
4243
4244    // address = R[n] - 4*BitCount(registers);
4245
4246    int32_t offset = 0;
4247    addr_t Rn =
4248        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4249
4250    if (!success)
4251      return false;
4252
4253    addr_t address = Rn - (addr_byte_size * BitCount(registers));
4254    EmulateInstruction::Context context;
4255    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4256    RegisterInfo dwarf_reg;
4257    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4258    context.SetRegisterPlusOffset(dwarf_reg, Rn - address);
4259
4260    for (int i = 0; i < 14; ++i) {
4261      if (BitIsSet(registers, i)) {
4262        // R[i] = MemA[address,4]; address = address + 4;
4263        context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4264        uint32_t data =
4265            MemARead(context, address + offset, addr_byte_size, 0, &success);
4266        if (!success)
4267          return false;
4268
4269        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4270                                   data))
4271          return false;
4272
4273        offset += addr_byte_size;
4274      }
4275    }
4276
4277    // if registers<15> == '1' then
4278    //     LoadWritePC(MemA[address,4]);
4279    if (BitIsSet(registers, 15)) {
4280      context.SetRegisterPlusOffset(dwarf_reg, offset);
4281      uint32_t data =
4282          MemARead(context, address + offset, addr_byte_size, 0, &success);
4283      if (!success)
4284        return false;
4285      // In ARMv5T and above, this is an interworking branch.
4286      if (!LoadWritePC(context, data))
4287        return false;
4288    }
4289
4290    // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4291    if (wback && BitIsClear(registers, n)) {
4292      if (!success)
4293        return false;
4294
4295      offset = (addr_byte_size * BitCount(registers)) * -1;
4296      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4297      context.SetImmediateSigned(offset);
4298      addr_t addr = Rn + offset;
4299      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4300                                 addr))
4301        return false;
4302    }
4303
4304    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4305    // possible for encoding A1
4306    if (wback && BitIsSet(registers, n))
4307      return WriteBits32Unknown(n);
4308  }
4309  return true;
4310}
4311
4312// LDMIB loads multiple registers from consecutive memory locations using an
4313// address from a base register.  The
4314// consecutive memory locations start just above this address, and thea ddress
4315// of the last of those locations can optinoally be written back to the base
4316// register.
4317bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
4318                                         const ARMEncoding encoding) {
4319#if 0
4320    if ConditionPassed() then
4321        EncodingSpecificOperations();
4322        address = R[n] + 4;
4323
4324        for i = 0 to 14
4325            if registers<i> == '1' then
4326                  R[i] = MemA[address,4]; address = address + 4;
4327        if registers<15> == '1' then
4328            LoadWritePC(MemA[address,4]);
4329
4330        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4331        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4332#endif
4333
4334  bool success = false;
4335
4336  if (ConditionPassed(opcode)) {
4337    uint32_t n;
4338    uint32_t registers = 0;
4339    bool wback;
4340    const uint32_t addr_byte_size = GetAddressByteSize();
4341    switch (encoding) {
4342    case eEncodingA1:
4343      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4344      n = Bits32(opcode, 19, 16);
4345      registers = Bits32(opcode, 15, 0);
4346      wback = BitIsSet(opcode, 21);
4347
4348      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4349      if ((n == 15) || (BitCount(registers) < 1))
4350        return false;
4351
4352      break;
4353    default:
4354      return false;
4355    }
4356    // address = R[n] + 4;
4357
4358    int32_t offset = 0;
4359    addr_t Rn =
4360        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4361
4362    if (!success)
4363      return false;
4364
4365    addr_t address = Rn + addr_byte_size;
4366
4367    EmulateInstruction::Context context;
4368    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4369    RegisterInfo dwarf_reg;
4370    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4371    context.SetRegisterPlusOffset(dwarf_reg, offset);
4372
4373    for (int i = 0; i < 14; ++i) {
4374      if (BitIsSet(registers, i)) {
4375        // R[i] = MemA[address,4]; address = address + 4;
4376
4377        context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size);
4378        uint32_t data =
4379            MemARead(context, address + offset, addr_byte_size, 0, &success);
4380        if (!success)
4381          return false;
4382
4383        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4384                                   data))
4385          return false;
4386
4387        offset += addr_byte_size;
4388      }
4389    }
4390
4391    // if registers<15> == '1' then
4392    //     LoadWritePC(MemA[address,4]);
4393    if (BitIsSet(registers, 15)) {
4394      context.SetRegisterPlusOffset(dwarf_reg, offset);
4395      uint32_t data =
4396          MemARead(context, address + offset, addr_byte_size, 0, &success);
4397      if (!success)
4398        return false;
4399      // In ARMv5T and above, this is an interworking branch.
4400      if (!LoadWritePC(context, data))
4401        return false;
4402    }
4403
4404    // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4405    if (wback && BitIsClear(registers, n)) {
4406      if (!success)
4407        return false;
4408
4409      offset = addr_byte_size * BitCount(registers);
4410      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4411      context.SetImmediateSigned(offset);
4412      addr_t addr = Rn + offset;
4413      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4414                                 addr))
4415        return false;
4416    }
4417
4418    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4419    // possible for encoding A1
4420    if (wback && BitIsSet(registers, n))
4421      return WriteBits32Unknown(n);
4422  }
4423  return true;
4424}
4425
4426// Load Register (immediate) calculates an address from a base register value
4427// and an immediate offset, loads a word from memory, and writes to a register.
4428// LDR (immediate, Thumb)
4429bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
4430                                              const ARMEncoding encoding) {
4431#if 0
4432    // ARM pseudo code...
4433    if (ConditionPassed())
4434    {
4435        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4436        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4437        address = if index then offset_addr else R[n];
4438        data = MemU[address,4];
4439        if wback then R[n] = offset_addr;
4440        if t == 15 then
4441            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
4442        elsif UnalignedSupport() || address<1:0> = '00' then
4443            R[t] = data;
4444        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
4445    }
4446#endif
4447
4448  bool success = false;
4449
4450  if (ConditionPassed(opcode)) {
4451    uint32_t Rt;        // the destination register
4452    uint32_t Rn;        // the base register
4453    uint32_t imm32;     // the immediate offset used to form the address
4454    addr_t offset_addr; // the offset address
4455    addr_t address;     // the calculated address
4456    uint32_t data;      // the literal data value from memory load
4457    bool add, index, wback;
4458    switch (encoding) {
4459    case eEncodingT1:
4460      Rt = Bits32(opcode, 2, 0);
4461      Rn = Bits32(opcode, 5, 3);
4462      imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
4463      // index = TRUE; add = TRUE; wback = FALSE
4464      add = true;
4465      index = true;
4466      wback = false;
4467
4468      break;
4469
4470    case eEncodingT2:
4471      // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4472      Rt = Bits32(opcode, 10, 8);
4473      Rn = 13;
4474      imm32 = Bits32(opcode, 7, 0) << 2;
4475
4476      // index = TRUE; add = TRUE; wback = FALSE;
4477      index = true;
4478      add = true;
4479      wback = false;
4480
4481      break;
4482
4483    case eEncodingT3:
4484      // if Rn == '1111' then SEE LDR (literal);
4485      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4486      Rt = Bits32(opcode, 15, 12);
4487      Rn = Bits32(opcode, 19, 16);
4488      imm32 = Bits32(opcode, 11, 0);
4489
4490      // index = TRUE; add = TRUE; wback = FALSE;
4491      index = true;
4492      add = true;
4493      wback = false;
4494
4495      // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4496      if ((Rt == 15) && InITBlock() && !LastInITBlock())
4497        return false;
4498
4499      break;
4500
4501    case eEncodingT4:
4502      // if Rn == '1111' then SEE LDR (literal);
4503      // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4504      // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
4505      // '00000100' then SEE POP;
4506      // if P == '0' && W == '0' then UNDEFINED;
4507      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
4508        return false;
4509
4510      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4511      Rt = Bits32(opcode, 15, 12);
4512      Rn = Bits32(opcode, 19, 16);
4513      imm32 = Bits32(opcode, 7, 0);
4514
4515      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4516      index = BitIsSet(opcode, 10);
4517      add = BitIsSet(opcode, 9);
4518      wback = BitIsSet(opcode, 8);
4519
4520      // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4521      // then UNPREDICTABLE;
4522      if ((wback && (Rn == Rt)) ||
4523          ((Rt == 15) && InITBlock() && !LastInITBlock()))
4524        return false;
4525
4526      break;
4527
4528    default:
4529      return false;
4530    }
4531    uint32_t base = ReadCoreReg(Rn, &success);
4532    if (!success)
4533      return false;
4534    if (add)
4535      offset_addr = base + imm32;
4536    else
4537      offset_addr = base - imm32;
4538
4539    address = (index ? offset_addr : base);
4540
4541    RegisterInfo base_reg;
4542    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4543    if (wback) {
4544      EmulateInstruction::Context ctx;
4545      if (Rn == 13) {
4546        ctx.type = eContextAdjustStackPointer;
4547        ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4548      } else if (Rn == GetFramePointerRegisterNumber()) {
4549        ctx.type = eContextSetFramePointer;
4550        ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4551      } else {
4552        ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4553        ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4554      }
4555
4556      if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
4557                                 offset_addr))
4558        return false;
4559    }
4560
4561    // Prepare to write to the Rt register.
4562    EmulateInstruction::Context context;
4563    context.type = EmulateInstruction::eContextRegisterLoad;
4564    context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4565
4566    // Read memory from the address.
4567    data = MemURead(context, address, 4, 0, &success);
4568    if (!success)
4569      return false;
4570
4571    if (Rt == 15) {
4572      if (Bits32(address, 1, 0) == 0) {
4573        if (!LoadWritePC(context, data))
4574          return false;
4575      } else
4576        return false;
4577    } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4578      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
4579                                 data))
4580        return false;
4581    } else
4582      WriteBits32Unknown(Rt);
4583  }
4584  return true;
4585}
4586
4587// STM (Store Multiple Increment After) stores multiple registers to consecutive
4588// memory locations using an address
4589// from a base register.  The consecutive memory locations start at this
4590// address, and the address just above the last of those locations can
4591// optionally be written back to the base register.
4592bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4593                                       const ARMEncoding encoding) {
4594#if 0
4595    if ConditionPassed() then
4596        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4597        address = R[n];
4598
4599        for i = 0 to 14
4600            if registers<i> == '1' then
4601                if i == n && wback && i != LowestSetBit(registers) then
4602                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4603                else
4604                    MemA[address,4] = R[i];
4605                address = address + 4;
4606
4607        if registers<15> == '1' then // Only possible for encoding A1
4608            MemA[address,4] = PCStoreValue();
4609        if wback then R[n] = R[n] + 4*BitCount(registers);
4610#endif
4611
4612  bool success = false;
4613
4614  if (ConditionPassed(opcode)) {
4615    uint32_t n;
4616    uint32_t registers = 0;
4617    bool wback;
4618    const uint32_t addr_byte_size = GetAddressByteSize();
4619
4620    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4621    switch (encoding) {
4622    case eEncodingT1:
4623      // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4624      n = Bits32(opcode, 10, 8);
4625      registers = Bits32(opcode, 7, 0);
4626      registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4627      wback = true;
4628
4629      // if BitCount(registers) < 1 then UNPREDICTABLE;
4630      if (BitCount(registers) < 1)
4631        return false;
4632
4633      break;
4634
4635    case eEncodingT2:
4636      // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4637      n = Bits32(opcode, 19, 16);
4638      registers = Bits32(opcode, 15, 0);
4639      registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4640      wback = BitIsSet(opcode, 21);
4641
4642      // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4643      if ((n == 15) || (BitCount(registers) < 2))
4644        return false;
4645
4646      // if wback && registers<n> == '1' then UNPREDICTABLE;
4647      if (wback && BitIsSet(registers, n))
4648        return false;
4649
4650      break;
4651
4652    case eEncodingA1:
4653      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4654      n = Bits32(opcode, 19, 16);
4655      registers = Bits32(opcode, 15, 0);
4656      wback = BitIsSet(opcode, 21);
4657
4658      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4659      if ((n == 15) || (BitCount(registers) < 1))
4660        return false;
4661
4662      break;
4663
4664    default:
4665      return false;
4666    }
4667
4668    // address = R[n];
4669    int32_t offset = 0;
4670    const addr_t address =
4671        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4672    if (!success)
4673      return false;
4674
4675    EmulateInstruction::Context context;
4676    context.type = EmulateInstruction::eContextRegisterStore;
4677    RegisterInfo base_reg;
4678    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4679
4680    // for i = 0 to 14
4681    uint32_t lowest_set_bit = 14;
4682    for (uint32_t i = 0; i < 14; ++i) {
4683      // if registers<i> == '1' then
4684      if (BitIsSet(registers, i)) {
4685        if (i < lowest_set_bit)
4686          lowest_set_bit = i;
4687        // if i == n && wback && i != LowestSetBit(registers) then
4688        if ((i == n) && wback && (i != lowest_set_bit))
4689          // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4690          // T1 and A1
4691          WriteBits32UnknownToMemory(address + offset);
4692        else {
4693          // MemA[address,4] = R[i];
4694          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4695                                               0, &success);
4696          if (!success)
4697            return false;
4698
4699          RegisterInfo data_reg;
4700          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4701          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
4702          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4703            return false;
4704        }
4705
4706        // address = address + 4;
4707        offset += addr_byte_size;
4708      }
4709    }
4710
4711    // if registers<15> == '1' then // Only possible for encoding A1
4712    //     MemA[address,4] = PCStoreValue();
4713    if (BitIsSet(registers, 15)) {
4714      RegisterInfo pc_reg;
4715      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4716      context.SetRegisterPlusOffset(pc_reg, 8);
4717      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4718      if (!success)
4719        return false;
4720
4721      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4722        return false;
4723    }
4724
4725    // if wback then R[n] = R[n] + 4*BitCount(registers);
4726    if (wback) {
4727      offset = addr_byte_size * BitCount(registers);
4728      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4729      context.SetImmediateSigned(offset);
4730      addr_t data = address + offset;
4731      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4732                                 data))
4733        return false;
4734    }
4735  }
4736  return true;
4737}
4738
4739// STMDA (Store Multiple Decrement After) stores multiple registers to
4740// consecutive memory locations using an address from a base register.  The
4741// consecutive memory locations end at this address, and the address just below
4742// the lowest of those locations can optionally be written back to the base
4743// register.
4744bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4745                                         const ARMEncoding encoding) {
4746#if 0
4747    if ConditionPassed() then
4748        EncodingSpecificOperations();
4749        address = R[n] - 4*BitCount(registers) + 4;
4750
4751        for i = 0 to 14
4752            if registers<i> == '1' then
4753                if i == n && wback && i != LowestSetBit(registers) then
4754                    MemA[address,4] = bits(32) UNKNOWN;
4755                else
4756                    MemA[address,4] = R[i];
4757                address = address + 4;
4758
4759        if registers<15> == '1' then
4760            MemA[address,4] = PCStoreValue();
4761
4762        if wback then R[n] = R[n] - 4*BitCount(registers);
4763#endif
4764
4765  bool success = false;
4766
4767  if (ConditionPassed(opcode)) {
4768    uint32_t n;
4769    uint32_t registers = 0;
4770    bool wback;
4771    const uint32_t addr_byte_size = GetAddressByteSize();
4772
4773    // EncodingSpecificOperations();
4774    switch (encoding) {
4775    case eEncodingA1:
4776      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4777      n = Bits32(opcode, 19, 16);
4778      registers = Bits32(opcode, 15, 0);
4779      wback = BitIsSet(opcode, 21);
4780
4781      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4782      if ((n == 15) || (BitCount(registers) < 1))
4783        return false;
4784      break;
4785    default:
4786      return false;
4787    }
4788
4789    // address = R[n] - 4*BitCount(registers) + 4;
4790    int32_t offset = 0;
4791    addr_t Rn = ReadCoreReg(n, &success);
4792    if (!success)
4793      return false;
4794
4795    addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4796
4797    EmulateInstruction::Context context;
4798    context.type = EmulateInstruction::eContextRegisterStore;
4799    RegisterInfo base_reg;
4800    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4801
4802    // for i = 0 to 14
4803    uint32_t lowest_bit_set = 14;
4804    for (uint32_t i = 0; i < 14; ++i) {
4805      // if registers<i> == '1' then
4806      if (BitIsSet(registers, i)) {
4807        if (i < lowest_bit_set)
4808          lowest_bit_set = i;
4809        // if i == n && wback && i != LowestSetBit(registers) then
4810        if ((i == n) && wback && (i != lowest_bit_set))
4811          // MemA[address,4] = bits(32) UNKNOWN;
4812          WriteBits32UnknownToMemory(address + offset);
4813        else {
4814          // MemA[address,4] = R[i];
4815          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4816                                               0, &success);
4817          if (!success)
4818            return false;
4819
4820          RegisterInfo data_reg;
4821          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4822          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4823                                                  Rn - (address + offset));
4824          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4825            return false;
4826        }
4827
4828        // address = address + 4;
4829        offset += addr_byte_size;
4830      }
4831    }
4832
4833    // if registers<15> == '1' then
4834    //    MemA[address,4] = PCStoreValue();
4835    if (BitIsSet(registers, 15)) {
4836      RegisterInfo pc_reg;
4837      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4838      context.SetRegisterPlusOffset(pc_reg, 8);
4839      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4840      if (!success)
4841        return false;
4842
4843      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4844        return false;
4845    }
4846
4847    // if wback then R[n] = R[n] - 4*BitCount(registers);
4848    if (wback) {
4849      offset = (addr_byte_size * BitCount(registers)) * -1;
4850      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4851      context.SetImmediateSigned(offset);
4852      addr_t data = Rn + offset;
4853      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4854                                 data))
4855        return false;
4856    }
4857  }
4858  return true;
4859}
4860
4861// STMDB (Store Multiple Decrement Before) stores multiple registers to
4862// consecutive memory locations using an address from a base register.  The
4863// consecutive memory locations end just below this address, and the address of
4864// the first of those locations can optionally be written back to the base
4865// register.
4866bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4867                                         const ARMEncoding encoding) {
4868#if 0
4869    if ConditionPassed() then
4870        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4871        address = R[n] - 4*BitCount(registers);
4872
4873        for i = 0 to 14
4874            if registers<i> == '1' then
4875                if i == n && wback && i != LowestSetBit(registers) then
4876                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4877                else
4878                    MemA[address,4] = R[i];
4879                address = address + 4;
4880
4881        if registers<15> == '1' then // Only possible for encoding A1
4882            MemA[address,4] = PCStoreValue();
4883
4884        if wback then R[n] = R[n] - 4*BitCount(registers);
4885#endif
4886
4887  bool success = false;
4888
4889  if (ConditionPassed(opcode)) {
4890    uint32_t n;
4891    uint32_t registers = 0;
4892    bool wback;
4893    const uint32_t addr_byte_size = GetAddressByteSize();
4894
4895    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4896    switch (encoding) {
4897    case eEncodingT1:
4898      // if W == '1' && Rn == '1101' then SEE PUSH;
4899      if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4900        // See PUSH
4901      }
4902      // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4903      n = Bits32(opcode, 19, 16);
4904      registers = Bits32(opcode, 15, 0);
4905      registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4906      wback = BitIsSet(opcode, 21);
4907      // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4908      if ((n == 15) || BitCount(registers) < 2)
4909        return false;
4910      // if wback && registers<n> == '1' then UNPREDICTABLE;
4911      if (wback && BitIsSet(registers, n))
4912        return false;
4913      break;
4914
4915    case eEncodingA1:
4916      // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4917      // PUSH;
4918      if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4919          BitCount(Bits32(opcode, 15, 0)) >= 2) {
4920        // See Push
4921      }
4922      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4923      n = Bits32(opcode, 19, 16);
4924      registers = Bits32(opcode, 15, 0);
4925      wback = BitIsSet(opcode, 21);
4926      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4927      if ((n == 15) || BitCount(registers) < 1)
4928        return false;
4929      break;
4930
4931    default:
4932      return false;
4933    }
4934
4935    // address = R[n] - 4*BitCount(registers);
4936
4937    int32_t offset = 0;
4938    addr_t Rn =
4939        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4940    if (!success)
4941      return false;
4942
4943    addr_t address = Rn - (addr_byte_size * BitCount(registers));
4944
4945    EmulateInstruction::Context context;
4946    context.type = EmulateInstruction::eContextRegisterStore;
4947    RegisterInfo base_reg;
4948    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4949
4950    // for i = 0 to 14
4951    uint32_t lowest_set_bit = 14;
4952    for (uint32_t i = 0; i < 14; ++i) {
4953      // if registers<i> == '1' then
4954      if (BitIsSet(registers, i)) {
4955        if (i < lowest_set_bit)
4956          lowest_set_bit = i;
4957        // if i == n && wback && i != LowestSetBit(registers) then
4958        if ((i == n) && wback && (i != lowest_set_bit))
4959          // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4960          // A1
4961          WriteBits32UnknownToMemory(address + offset);
4962        else {
4963          // MemA[address,4] = R[i];
4964          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4965                                               0, &success);
4966          if (!success)
4967            return false;
4968
4969          RegisterInfo data_reg;
4970          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4971          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4972                                                  Rn - (address + offset));
4973          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4974            return false;
4975        }
4976
4977        // address = address + 4;
4978        offset += addr_byte_size;
4979      }
4980    }
4981
4982    // if registers<15> == '1' then // Only possible for encoding A1
4983    //     MemA[address,4] = PCStoreValue();
4984    if (BitIsSet(registers, 15)) {
4985      RegisterInfo pc_reg;
4986      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4987      context.SetRegisterPlusOffset(pc_reg, 8);
4988      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4989      if (!success)
4990        return false;
4991
4992      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4993        return false;
4994    }
4995
4996    // if wback then R[n] = R[n] - 4*BitCount(registers);
4997    if (wback) {
4998      offset = (addr_byte_size * BitCount(registers)) * -1;
4999      context.type = EmulateInstruction::eContextAdjustBaseRegister;
5000      context.SetImmediateSigned(offset);
5001      addr_t data = Rn + offset;
5002      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5003                                 data))
5004        return false;
5005    }
5006  }
5007  return true;
5008}
5009
5010// STMIB (Store Multiple Increment Before) stores multiple registers to
5011// consecutive memory locations using an address from a base register.  The
5012// consecutive memory locations start just above this address, and the address
5013// of the last of those locations can optionally be written back to the base
5014// register.
5015bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
5016                                         const ARMEncoding encoding) {
5017#if 0
5018    if ConditionPassed() then
5019        EncodingSpecificOperations();
5020        address = R[n] + 4;
5021
5022        for i = 0 to 14
5023            if registers<i> == '1' then
5024                if i == n && wback && i != LowestSetBit(registers) then
5025                    MemA[address,4] = bits(32) UNKNOWN;
5026                else
5027                    MemA[address,4] = R[i];
5028                address = address + 4;
5029
5030        if registers<15> == '1' then
5031            MemA[address,4] = PCStoreValue();
5032
5033        if wback then R[n] = R[n] + 4*BitCount(registers);
5034#endif
5035
5036  bool success = false;
5037
5038  if (ConditionPassed(opcode)) {
5039    uint32_t n;
5040    uint32_t registers = 0;
5041    bool wback;
5042    const uint32_t addr_byte_size = GetAddressByteSize();
5043
5044    // EncodingSpecificOperations();
5045    switch (encoding) {
5046    case eEncodingA1:
5047      // n = UInt(Rn); registers = register_list; wback = (W == '1');
5048      n = Bits32(opcode, 19, 16);
5049      registers = Bits32(opcode, 15, 0);
5050      wback = BitIsSet(opcode, 21);
5051
5052      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
5053      if ((n == 15) && (BitCount(registers) < 1))
5054        return false;
5055      break;
5056    default:
5057      return false;
5058    }
5059    // address = R[n] + 4;
5060
5061    int32_t offset = 0;
5062    addr_t Rn = ReadCoreReg(n, &success);
5063    if (!success)
5064      return false;
5065
5066    addr_t address = Rn + addr_byte_size;
5067
5068    EmulateInstruction::Context context;
5069    context.type = EmulateInstruction::eContextRegisterStore;
5070    RegisterInfo base_reg;
5071    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5072
5073    uint32_t lowest_set_bit = 14;
5074    // for i = 0 to 14
5075    for (uint32_t i = 0; i < 14; ++i) {
5076      // if registers<i> == '1' then
5077      if (BitIsSet(registers, i)) {
5078        if (i < lowest_set_bit)
5079          lowest_set_bit = i;
5080        // if i == n && wback && i != LowestSetBit(registers) then
5081        if ((i == n) && wback && (i != lowest_set_bit))
5082          // MemA[address,4] = bits(32) UNKNOWN;
5083          WriteBits32UnknownToMemory(address + offset);
5084        // else
5085        else {
5086          // MemA[address,4] = R[i];
5087          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
5088                                               0, &success);
5089          if (!success)
5090            return false;
5091
5092          RegisterInfo data_reg;
5093          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
5094          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5095                                                  offset + addr_byte_size);
5096          if (!MemAWrite(context, address + offset, data, addr_byte_size))
5097            return false;
5098        }
5099
5100        // address = address + 4;
5101        offset += addr_byte_size;
5102      }
5103    }
5104
5105    // if registers<15> == '1' then
5106    // MemA[address,4] = PCStoreValue();
5107    if (BitIsSet(registers, 15)) {
5108      RegisterInfo pc_reg;
5109      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
5110      context.SetRegisterPlusOffset(pc_reg, 8);
5111      const uint32_t pc = ReadCoreReg(PC_REG, &success);
5112      if (!success)
5113        return false;
5114
5115      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5116        return false;
5117    }
5118
5119    // if wback then R[n] = R[n] + 4*BitCount(registers);
5120    if (wback) {
5121      offset = addr_byte_size * BitCount(registers);
5122      context.type = EmulateInstruction::eContextAdjustBaseRegister;
5123      context.SetImmediateSigned(offset);
5124      addr_t data = Rn + offset;
5125      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5126                                 data))
5127        return false;
5128    }
5129  }
5130  return true;
5131}
5132
5133// STR (store immediate) calculates an address from a base register value and an
5134// immediate offset, and stores a word
5135// from a register to memory.  It can use offset, post-indexed, or pre-indexed
5136// addressing.
5137bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
5138                                            const ARMEncoding encoding) {
5139#if 0
5140    if ConditionPassed() then
5141        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5142        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5143        address = if index then offset_addr else R[n];
5144        if UnalignedSupport() || address<1:0> == '00' then
5145            MemU[address,4] = R[t];
5146        else // Can only occur before ARMv7
5147            MemU[address,4] = bits(32) UNKNOWN;
5148        if wback then R[n] = offset_addr;
5149#endif
5150
5151  bool success = false;
5152
5153  if (ConditionPassed(opcode)) {
5154    const uint32_t addr_byte_size = GetAddressByteSize();
5155
5156    uint32_t t;
5157    uint32_t n;
5158    uint32_t imm32;
5159    bool index;
5160    bool add;
5161    bool wback;
5162    // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5163    switch (encoding) {
5164    case eEncodingT1:
5165      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
5166      t = Bits32(opcode, 2, 0);
5167      n = Bits32(opcode, 5, 3);
5168      imm32 = Bits32(opcode, 10, 6) << 2;
5169
5170      // index = TRUE; add = TRUE; wback = FALSE;
5171      index = true;
5172      add = false;
5173      wback = false;
5174      break;
5175
5176    case eEncodingT2:
5177      // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
5178      t = Bits32(opcode, 10, 8);
5179      n = 13;
5180      imm32 = Bits32(opcode, 7, 0) << 2;
5181
5182      // index = TRUE; add = TRUE; wback = FALSE;
5183      index = true;
5184      add = true;
5185      wback = false;
5186      break;
5187
5188    case eEncodingT3:
5189      // if Rn == '1111' then UNDEFINED;
5190      if (Bits32(opcode, 19, 16) == 15)
5191        return false;
5192
5193      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5194      t = Bits32(opcode, 15, 12);
5195      n = Bits32(opcode, 19, 16);
5196      imm32 = Bits32(opcode, 11, 0);
5197
5198      // index = TRUE; add = TRUE; wback = FALSE;
5199      index = true;
5200      add = true;
5201      wback = false;
5202
5203      // if t == 15 then UNPREDICTABLE;
5204      if (t == 15)
5205        return false;
5206      break;
5207
5208    case eEncodingT4:
5209      // if P == '1' && U == '1' && W == '0' then SEE STRT;
5210      // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
5211      // '00000100' then SEE PUSH;
5212      // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5213      if ((Bits32(opcode, 19, 16) == 15) ||
5214          (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
5215        return false;
5216
5217      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5218      t = Bits32(opcode, 15, 12);
5219      n = Bits32(opcode, 19, 16);
5220      imm32 = Bits32(opcode, 7, 0);
5221
5222      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5223      index = BitIsSet(opcode, 10);
5224      add = BitIsSet(opcode, 9);
5225      wback = BitIsSet(opcode, 8);
5226
5227      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
5228      if ((t == 15) || (wback && (n == t)))
5229        return false;
5230      break;
5231
5232    default:
5233      return false;
5234    }
5235
5236    addr_t offset_addr;
5237    addr_t address;
5238
5239    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5240    uint32_t base_address = ReadCoreReg(n, &success);
5241    if (!success)
5242      return false;
5243
5244    if (add)
5245      offset_addr = base_address + imm32;
5246    else
5247      offset_addr = base_address - imm32;
5248
5249    // address = if index then offset_addr else R[n];
5250    if (index)
5251      address = offset_addr;
5252    else
5253      address = base_address;
5254
5255    EmulateInstruction::Context context;
5256    if (n == 13)
5257      context.type = eContextPushRegisterOnStack;
5258    else
5259      context.type = eContextRegisterStore;
5260
5261    RegisterInfo base_reg;
5262    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5263
5264    // if UnalignedSupport() || address<1:0> == '00' then
5265    if (UnalignedSupport() ||
5266        (BitIsClear(address, 1) && BitIsClear(address, 0))) {
5267      // MemU[address,4] = R[t];
5268      uint32_t data =
5269          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5270      if (!success)
5271        return false;
5272
5273      RegisterInfo data_reg;
5274      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5275      int32_t offset = address - base_address;
5276      context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
5277      if (!MemUWrite(context, address, data, addr_byte_size))
5278        return false;
5279    } else {
5280      // MemU[address,4] = bits(32) UNKNOWN;
5281      WriteBits32UnknownToMemory(address);
5282    }
5283
5284    // if wback then R[n] = offset_addr;
5285    if (wback) {
5286      if (n == 13)
5287        context.type = eContextAdjustStackPointer;
5288      else
5289        context.type = eContextAdjustBaseRegister;
5290      context.SetAddress(offset_addr);
5291
5292      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5293                                 offset_addr))
5294        return false;
5295    }
5296  }
5297  return true;
5298}
5299
5300// STR (Store Register) calculates an address from a base register value and an
5301// offset register value, stores a
5302// word from a register to memory.   The offset register value can optionally
5303// be shifted.
5304bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
5305                                               const ARMEncoding encoding) {
5306#if 0
5307    if ConditionPassed() then
5308        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5309        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5310        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5311        address = if index then offset_addr else R[n];
5312        if t == 15 then // Only possible for encoding A1
5313            data = PCStoreValue();
5314        else
5315            data = R[t];
5316        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
5317            MemU[address,4] = data;
5318        else // Can only occur before ARMv7
5319            MemU[address,4] = bits(32) UNKNOWN;
5320        if wback then R[n] = offset_addr;
5321#endif
5322
5323  bool success = false;
5324
5325  if (ConditionPassed(opcode)) {
5326    const uint32_t addr_byte_size = GetAddressByteSize();
5327
5328    uint32_t t;
5329    uint32_t n;
5330    uint32_t m;
5331    ARM_ShifterType shift_t;
5332    uint32_t shift_n;
5333    bool index;
5334    bool add;
5335    bool wback;
5336
5337    // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5338    switch (encoding) {
5339    case eEncodingT1:
5340      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5341      // in ThumbEE";
5342      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5343      t = Bits32(opcode, 2, 0);
5344      n = Bits32(opcode, 5, 3);
5345      m = Bits32(opcode, 8, 6);
5346
5347      // index = TRUE; add = TRUE; wback = FALSE;
5348      index = true;
5349      add = true;
5350      wback = false;
5351
5352      // (shift_t, shift_n) = (SRType_LSL, 0);
5353      shift_t = SRType_LSL;
5354      shift_n = 0;
5355      break;
5356
5357    case eEncodingT2:
5358      // if Rn == '1111' then UNDEFINED;
5359      if (Bits32(opcode, 19, 16) == 15)
5360        return false;
5361
5362      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5363      t = Bits32(opcode, 15, 12);
5364      n = Bits32(opcode, 19, 16);
5365      m = Bits32(opcode, 3, 0);
5366
5367      // index = TRUE; add = TRUE; wback = FALSE;
5368      index = true;
5369      add = true;
5370      wback = false;
5371
5372      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5373      shift_t = SRType_LSL;
5374      shift_n = Bits32(opcode, 5, 4);
5375
5376      // if t == 15 || BadReg(m) then UNPREDICTABLE;
5377      if ((t == 15) || (BadReg(m)))
5378        return false;
5379      break;
5380
5381    case eEncodingA1: {
5382      // if P == '0' && W == '1' then SEE STRT;
5383      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5384      t = Bits32(opcode, 15, 12);
5385      n = Bits32(opcode, 19, 16);
5386      m = Bits32(opcode, 3, 0);
5387
5388      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5389      // (W == '1');
5390      index = BitIsSet(opcode, 24);
5391      add = BitIsSet(opcode, 23);
5392      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5393
5394      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5395      uint32_t typ = Bits32(opcode, 6, 5);
5396      uint32_t imm5 = Bits32(opcode, 11, 7);
5397      shift_n = DecodeImmShift(typ, imm5, shift_t);
5398
5399      // if m == 15 then UNPREDICTABLE;
5400      if (m == 15)
5401        return false;
5402
5403      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5404      if (wback && ((n == 15) || (n == t)))
5405        return false;
5406
5407      break;
5408    }
5409    default:
5410      return false;
5411    }
5412
5413    addr_t offset_addr;
5414    addr_t address;
5415    int32_t offset = 0;
5416
5417    addr_t base_address =
5418        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5419    if (!success)
5420      return false;
5421
5422    uint32_t Rm_data =
5423        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5424    if (!success)
5425      return false;
5426
5427    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5428    offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
5429    if (!success)
5430      return false;
5431
5432    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5433    if (add)
5434      offset_addr = base_address + offset;
5435    else
5436      offset_addr = base_address - offset;
5437
5438    // address = if index then offset_addr else R[n];
5439    if (index)
5440      address = offset_addr;
5441    else
5442      address = base_address;
5443
5444    uint32_t data;
5445    // if t == 15 then // Only possible for encoding A1
5446    if (t == 15)
5447      // data = PCStoreValue();
5448      data = ReadCoreReg(PC_REG, &success);
5449    else
5450      // data = R[t];
5451      data =
5452          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5453
5454    if (!success)
5455      return false;
5456
5457    EmulateInstruction::Context context;
5458    context.type = eContextRegisterStore;
5459
5460    // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
5461    // InstrSet_ARM then
5462    if (UnalignedSupport() ||
5463        (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
5464        CurrentInstrSet() == eModeARM) {
5465      // MemU[address,4] = data;
5466
5467      RegisterInfo base_reg;
5468      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5469
5470      RegisterInfo data_reg;
5471      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5472
5473      context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5474                                              address - base_address);
5475      if (!MemUWrite(context, address, data, addr_byte_size))
5476        return false;
5477
5478    } else
5479      // MemU[address,4] = bits(32) UNKNOWN;
5480      WriteBits32UnknownToMemory(address);
5481
5482    // if wback then R[n] = offset_addr;
5483    if (wback) {
5484      context.type = eContextRegisterLoad;
5485      context.SetAddress(offset_addr);
5486      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5487                                 offset_addr))
5488        return false;
5489    }
5490  }
5491  return true;
5492}
5493
5494bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
5495                                             const ARMEncoding encoding) {
5496#if 0
5497    if ConditionPassed() then
5498        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5499        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5500        address = if index then offset_addr else R[n];
5501        MemU[address,1] = R[t]<7:0>;
5502        if wback then R[n] = offset_addr;
5503#endif
5504
5505  bool success = false;
5506
5507  if (ConditionPassed(opcode)) {
5508    uint32_t t;
5509    uint32_t n;
5510    uint32_t imm32;
5511    bool index;
5512    bool add;
5513    bool wback;
5514    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5515    switch (encoding) {
5516    case eEncodingT1:
5517      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5518      t = Bits32(opcode, 2, 0);
5519      n = Bits32(opcode, 5, 3);
5520      imm32 = Bits32(opcode, 10, 6);
5521
5522      // index = TRUE; add = TRUE; wback = FALSE;
5523      index = true;
5524      add = true;
5525      wback = false;
5526      break;
5527
5528    case eEncodingT2:
5529      // if Rn == '1111' then UNDEFINED;
5530      if (Bits32(opcode, 19, 16) == 15)
5531        return false;
5532
5533      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5534      t = Bits32(opcode, 15, 12);
5535      n = Bits32(opcode, 19, 16);
5536      imm32 = Bits32(opcode, 11, 0);
5537
5538      // index = TRUE; add = TRUE; wback = FALSE;
5539      index = true;
5540      add = true;
5541      wback = false;
5542
5543      // if BadReg(t) then UNPREDICTABLE;
5544      if (BadReg(t))
5545        return false;
5546      break;
5547
5548    case eEncodingT3:
5549      // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5550      // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5551      if (Bits32(opcode, 19, 16) == 15)
5552        return false;
5553
5554      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5555      t = Bits32(opcode, 15, 12);
5556      n = Bits32(opcode, 19, 16);
5557      imm32 = Bits32(opcode, 7, 0);
5558
5559      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5560      index = BitIsSet(opcode, 10);
5561      add = BitIsSet(opcode, 9);
5562      wback = BitIsSet(opcode, 8);
5563
5564      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5565      if ((BadReg(t)) || (wback && (n == t)))
5566        return false;
5567      break;
5568
5569    default:
5570      return false;
5571    }
5572
5573    addr_t offset_addr;
5574    addr_t address;
5575    addr_t base_address =
5576        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5577    if (!success)
5578      return false;
5579
5580    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5581    if (add)
5582      offset_addr = base_address + imm32;
5583    else
5584      offset_addr = base_address - imm32;
5585
5586    // address = if index then offset_addr else R[n];
5587    if (index)
5588      address = offset_addr;
5589    else
5590      address = base_address;
5591
5592    // MemU[address,1] = R[t]<7:0>
5593    RegisterInfo base_reg;
5594    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5595
5596    RegisterInfo data_reg;
5597    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5598
5599    EmulateInstruction::Context context;
5600    context.type = eContextRegisterStore;
5601    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5602                                            address - base_address);
5603
5604    uint32_t data =
5605        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5606    if (!success)
5607      return false;
5608
5609    data = Bits32(data, 7, 0);
5610
5611    if (!MemUWrite(context, address, data, 1))
5612      return false;
5613
5614    // if wback then R[n] = offset_addr;
5615    if (wback) {
5616      context.type = eContextRegisterLoad;
5617      context.SetAddress(offset_addr);
5618      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5619                                 offset_addr))
5620        return false;
5621    }
5622  }
5623
5624  return true;
5625}
5626
5627// STRH (register) calculates an address from a base register value and an
5628// offset register value, and stores a
5629// halfword from a register to memory.  The offset register value can be
5630// shifted left by 0, 1, 2, or 3 bits.
5631bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
5632                                                const ARMEncoding encoding) {
5633#if 0
5634    if ConditionPassed() then
5635        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5636        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5637        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5638        address = if index then offset_addr else R[n];
5639        if UnalignedSupport() || address<0> == '0' then
5640            MemU[address,2] = R[t]<15:0>;
5641        else // Can only occur before ARMv7
5642            MemU[address,2] = bits(16) UNKNOWN;
5643        if wback then R[n] = offset_addr;
5644#endif
5645
5646  bool success = false;
5647
5648  if (ConditionPassed(opcode)) {
5649    uint32_t t;
5650    uint32_t n;
5651    uint32_t m;
5652    bool index;
5653    bool add;
5654    bool wback;
5655    ARM_ShifterType shift_t;
5656    uint32_t shift_n;
5657
5658    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5659    switch (encoding) {
5660    case eEncodingT1:
5661      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5662      // in ThumbEE";
5663      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5664      t = Bits32(opcode, 2, 0);
5665      n = Bits32(opcode, 5, 3);
5666      m = Bits32(opcode, 8, 6);
5667
5668      // index = TRUE; add = TRUE; wback = FALSE;
5669      index = true;
5670      add = true;
5671      wback = false;
5672
5673      // (shift_t, shift_n) = (SRType_LSL, 0);
5674      shift_t = SRType_LSL;
5675      shift_n = 0;
5676
5677      break;
5678
5679    case eEncodingT2:
5680      // if Rn == '1111' then UNDEFINED;
5681      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5682      t = Bits32(opcode, 15, 12);
5683      n = Bits32(opcode, 19, 16);
5684      m = Bits32(opcode, 3, 0);
5685      if (n == 15)
5686        return false;
5687
5688      // index = TRUE; add = TRUE; wback = FALSE;
5689      index = true;
5690      add = true;
5691      wback = false;
5692
5693      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5694      shift_t = SRType_LSL;
5695      shift_n = Bits32(opcode, 5, 4);
5696
5697      // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5698      if (BadReg(t) || BadReg(m))
5699        return false;
5700
5701      break;
5702
5703    case eEncodingA1:
5704      // if P == '0' && W == '1' then SEE STRHT;
5705      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5706      t = Bits32(opcode, 15, 12);
5707      n = Bits32(opcode, 19, 16);
5708      m = Bits32(opcode, 3, 0);
5709
5710      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5711      // (W == '1');
5712      index = BitIsSet(opcode, 24);
5713      add = BitIsSet(opcode, 23);
5714      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5715
5716      // (shift_t, shift_n) = (SRType_LSL, 0);
5717      shift_t = SRType_LSL;
5718      shift_n = 0;
5719
5720      // if t == 15 || m == 15 then UNPREDICTABLE;
5721      if ((t == 15) || (m == 15))
5722        return false;
5723
5724      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5725      if (wback && ((n == 15) || (n == t)))
5726        return false;
5727
5728      break;
5729
5730    default:
5731      return false;
5732    }
5733
5734    uint32_t Rm = ReadCoreReg(m, &success);
5735    if (!success)
5736      return false;
5737
5738    uint32_t Rn = ReadCoreReg(n, &success);
5739    if (!success)
5740      return false;
5741
5742    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5743    uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
5744    if (!success)
5745      return false;
5746
5747    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5748    addr_t offset_addr;
5749    if (add)
5750      offset_addr = Rn + offset;
5751    else
5752      offset_addr = Rn - offset;
5753
5754    // address = if index then offset_addr else R[n];
5755    addr_t address;
5756    if (index)
5757      address = offset_addr;
5758    else
5759      address = Rn;
5760
5761    EmulateInstruction::Context context;
5762    context.type = eContextRegisterStore;
5763    RegisterInfo base_reg;
5764    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5765    RegisterInfo offset_reg;
5766    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5767
5768    // if UnalignedSupport() || address<0> == '0' then
5769    if (UnalignedSupport() || BitIsClear(address, 0)) {
5770      // MemU[address,2] = R[t]<15:0>;
5771      uint32_t Rt = ReadCoreReg(t, &success);
5772      if (!success)
5773        return false;
5774
5775      EmulateInstruction::Context context;
5776      context.type = eContextRegisterStore;
5777      RegisterInfo base_reg;
5778      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5779      RegisterInfo offset_reg;
5780      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5781      RegisterInfo data_reg;
5782      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5783      context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
5784                                                      data_reg);
5785
5786      if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
5787        return false;
5788    } else // Can only occur before ARMv7
5789    {
5790      // MemU[address,2] = bits(16) UNKNOWN;
5791    }
5792
5793    // if wback then R[n] = offset_addr;
5794    if (wback) {
5795      context.type = eContextAdjustBaseRegister;
5796      context.SetAddress(offset_addr);
5797      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5798                                 offset_addr))
5799        return false;
5800    }
5801  }
5802
5803  return true;
5804}
5805
5806// Add with Carry (immediate) adds an immediate value and the carry flag value
5807// to a register value, and writes the result to the destination register.  It
5808// can optionally update the condition flags based on the result.
5809bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
5810                                          const ARMEncoding encoding) {
5811#if 0
5812    // ARM pseudo code...
5813    if ConditionPassed() then
5814        EncodingSpecificOperations();
5815        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5816        if d == 15 then         // Can only occur for ARM encoding
5817            ALUWritePC(result); // setflags is always FALSE here
5818        else
5819            R[d] = result;
5820            if setflags then
5821                APSR.N = result<31>;
5822                APSR.Z = IsZeroBit(result);
5823                APSR.C = carry;
5824                APSR.V = overflow;
5825#endif
5826
5827  bool success = false;
5828
5829  if (ConditionPassed(opcode)) {
5830    uint32_t Rd, Rn;
5831    uint32_t
5832        imm32; // the immediate value to be added to the value obtained from Rn
5833    bool setflags;
5834    switch (encoding) {
5835    case eEncodingT1:
5836      Rd = Bits32(opcode, 11, 8);
5837      Rn = Bits32(opcode, 19, 16);
5838      setflags = BitIsSet(opcode, 20);
5839      imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5840      if (BadReg(Rd) || BadReg(Rn))
5841        return false;
5842      break;
5843    case eEncodingA1:
5844      Rd = Bits32(opcode, 15, 12);
5845      Rn = Bits32(opcode, 19, 16);
5846      setflags = BitIsSet(opcode, 20);
5847      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5848
5849      if (Rd == 15 && setflags)
5850        return EmulateSUBSPcLrEtc(opcode, encoding);
5851      break;
5852    default:
5853      return false;
5854    }
5855
5856    // Read the first operand.
5857    int32_t val1 = ReadCoreReg(Rn, &success);
5858    if (!success)
5859      return false;
5860
5861    AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5862
5863    EmulateInstruction::Context context;
5864    context.type = EmulateInstruction::eContextImmediate;
5865    context.SetNoArgs();
5866
5867    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5868                                   res.carry_out, res.overflow))
5869      return false;
5870  }
5871  return true;
5872}
5873
5874// Add with Carry (register) adds a register value, the carry flag value, and
5875// an optionally-shifted register value, and writes the result to the
5876// destination register.  It can optionally update the condition flags based on
5877// the result.
5878bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
5879                                          const ARMEncoding encoding) {
5880#if 0
5881    // ARM pseudo code...
5882    if ConditionPassed() then
5883        EncodingSpecificOperations();
5884        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5885        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5886        if d == 15 then         // Can only occur for ARM encoding
5887            ALUWritePC(result); // setflags is always FALSE here
5888        else
5889            R[d] = result;
5890            if setflags then
5891                APSR.N = result<31>;
5892                APSR.Z = IsZeroBit(result);
5893                APSR.C = carry;
5894                APSR.V = overflow;
5895#endif
5896
5897  bool success = false;
5898
5899  if (ConditionPassed(opcode)) {
5900    uint32_t Rd, Rn, Rm;
5901    ARM_ShifterType shift_t;
5902    uint32_t shift_n; // the shift applied to the value read from Rm
5903    bool setflags;
5904    switch (encoding) {
5905    case eEncodingT1:
5906      Rd = Rn = Bits32(opcode, 2, 0);
5907      Rm = Bits32(opcode, 5, 3);
5908      setflags = !InITBlock();
5909      shift_t = SRType_LSL;
5910      shift_n = 0;
5911      break;
5912    case eEncodingT2:
5913      Rd = Bits32(opcode, 11, 8);
5914      Rn = Bits32(opcode, 19, 16);
5915      Rm = Bits32(opcode, 3, 0);
5916      setflags = BitIsSet(opcode, 20);
5917      shift_n = DecodeImmShiftThumb(opcode, shift_t);
5918      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5919        return false;
5920      break;
5921    case eEncodingA1:
5922      Rd = Bits32(opcode, 15, 12);
5923      Rn = Bits32(opcode, 19, 16);
5924      Rm = Bits32(opcode, 3, 0);
5925      setflags = BitIsSet(opcode, 20);
5926      shift_n = DecodeImmShiftARM(opcode, shift_t);
5927
5928      if (Rd == 15 && setflags)
5929        return EmulateSUBSPcLrEtc(opcode, encoding);
5930      break;
5931    default:
5932      return false;
5933    }
5934
5935    // Read the first operand.
5936    int32_t val1 = ReadCoreReg(Rn, &success);
5937    if (!success)
5938      return false;
5939
5940    // Read the second operand.
5941    int32_t val2 = ReadCoreReg(Rm, &success);
5942    if (!success)
5943      return false;
5944
5945    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5946    if (!success)
5947      return false;
5948    AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5949
5950    EmulateInstruction::Context context;
5951    context.type = EmulateInstruction::eContextImmediate;
5952    context.SetNoArgs();
5953
5954    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5955                                   res.carry_out, res.overflow))
5956      return false;
5957  }
5958  return true;
5959}
5960
5961// This instruction adds an immediate value to the PC value to form a PC-
5962// relative address, and writes the result to the destination register.
5963bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
5964                                       const ARMEncoding encoding) {
5965#if 0
5966    // ARM pseudo code...
5967    if ConditionPassed() then
5968        EncodingSpecificOperations();
5969        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5970        if d == 15 then         // Can only occur for ARM encodings
5971            ALUWritePC(result);
5972        else
5973            R[d] = result;
5974#endif
5975
5976  bool success = false;
5977
5978  if (ConditionPassed(opcode)) {
5979    uint32_t Rd;
5980    uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5981    bool add;
5982    switch (encoding) {
5983    case eEncodingT1:
5984      Rd = Bits32(opcode, 10, 8);
5985      imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5986      add = true;
5987      break;
5988    case eEncodingT2:
5989    case eEncodingT3:
5990      Rd = Bits32(opcode, 11, 8);
5991      imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5992      add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5993      if (BadReg(Rd))
5994        return false;
5995      break;
5996    case eEncodingA1:
5997    case eEncodingA2:
5998      Rd = Bits32(opcode, 15, 12);
5999      imm32 = ARMExpandImm(opcode);          // imm32 = ARMExpandImm(imm12)
6000      add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
6001      break;
6002    default:
6003      return false;
6004    }
6005
6006    // Read the PC value.
6007    uint32_t pc = ReadCoreReg(PC_REG, &success);
6008    if (!success)
6009      return false;
6010
6011    uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
6012
6013    EmulateInstruction::Context context;
6014    context.type = EmulateInstruction::eContextImmediate;
6015    context.SetNoArgs();
6016
6017    if (!WriteCoreReg(context, result, Rd))
6018      return false;
6019  }
6020  return true;
6021}
6022
6023// This instruction performs a bitwise AND of a register value and an immediate
6024// value, and writes the result to the destination register.  It can optionally
6025// update the condition flags based on the result.
6026bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
6027                                          const ARMEncoding encoding) {
6028#if 0
6029    // ARM pseudo code...
6030    if ConditionPassed() then
6031        EncodingSpecificOperations();
6032        result = R[n] AND imm32;
6033        if d == 15 then         // Can only occur for ARM encoding
6034            ALUWritePC(result); // setflags is always FALSE here
6035        else
6036            R[d] = result;
6037            if setflags then
6038                APSR.N = result<31>;
6039                APSR.Z = IsZeroBit(result);
6040                APSR.C = carry;
6041                // APSR.V unchanged
6042#endif
6043
6044  bool success = false;
6045
6046  if (ConditionPassed(opcode)) {
6047    uint32_t Rd, Rn;
6048    uint32_t
6049        imm32; // the immediate value to be ANDed to the value obtained from Rn
6050    bool setflags;
6051    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6052    switch (encoding) {
6053    case eEncodingT1:
6054      Rd = Bits32(opcode, 11, 8);
6055      Rn = Bits32(opcode, 19, 16);
6056      setflags = BitIsSet(opcode, 20);
6057      imm32 = ThumbExpandImm_C(
6058          opcode, APSR_C,
6059          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6060      // if Rd == '1111' && S == '1' then SEE TST (immediate);
6061      if (Rd == 15 && setflags)
6062        return EmulateTSTImm(opcode, eEncodingT1);
6063      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
6064        return false;
6065      break;
6066    case eEncodingA1:
6067      Rd = Bits32(opcode, 15, 12);
6068      Rn = Bits32(opcode, 19, 16);
6069      setflags = BitIsSet(opcode, 20);
6070      imm32 =
6071          ARMExpandImm_C(opcode, APSR_C,
6072                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6073
6074      if (Rd == 15 && setflags)
6075        return EmulateSUBSPcLrEtc(opcode, encoding);
6076      break;
6077    default:
6078      return false;
6079    }
6080
6081    // Read the first operand.
6082    uint32_t val1 = ReadCoreReg(Rn, &success);
6083    if (!success)
6084      return false;
6085
6086    uint32_t result = val1 & imm32;
6087
6088    EmulateInstruction::Context context;
6089    context.type = EmulateInstruction::eContextImmediate;
6090    context.SetNoArgs();
6091
6092    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6093      return false;
6094  }
6095  return true;
6096}
6097
6098// This instruction performs a bitwise AND of a register value and an
6099// optionally-shifted register value, and writes the result to the destination
6100// register.  It can optionally update the condition flags based on the result.
6101bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
6102                                          const ARMEncoding encoding) {
6103#if 0
6104    // ARM pseudo code...
6105    if ConditionPassed() then
6106        EncodingSpecificOperations();
6107        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6108        result = R[n] AND shifted;
6109        if d == 15 then         // Can only occur for ARM encoding
6110            ALUWritePC(result); // setflags is always FALSE here
6111        else
6112            R[d] = result;
6113            if setflags then
6114                APSR.N = result<31>;
6115                APSR.Z = IsZeroBit(result);
6116                APSR.C = carry;
6117                // APSR.V unchanged
6118#endif
6119
6120  bool success = false;
6121
6122  if (ConditionPassed(opcode)) {
6123    uint32_t Rd, Rn, Rm;
6124    ARM_ShifterType shift_t;
6125    uint32_t shift_n; // the shift applied to the value read from Rm
6126    bool setflags;
6127    uint32_t carry;
6128    switch (encoding) {
6129    case eEncodingT1:
6130      Rd = Rn = Bits32(opcode, 2, 0);
6131      Rm = Bits32(opcode, 5, 3);
6132      setflags = !InITBlock();
6133      shift_t = SRType_LSL;
6134      shift_n = 0;
6135      break;
6136    case eEncodingT2:
6137      Rd = Bits32(opcode, 11, 8);
6138      Rn = Bits32(opcode, 19, 16);
6139      Rm = Bits32(opcode, 3, 0);
6140      setflags = BitIsSet(opcode, 20);
6141      shift_n = DecodeImmShiftThumb(opcode, shift_t);
6142      // if Rd == '1111' && S == '1' then SEE TST (register);
6143      if (Rd == 15 && setflags)
6144        return EmulateTSTReg(opcode, eEncodingT2);
6145      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
6146        return false;
6147      break;
6148    case eEncodingA1:
6149      Rd = Bits32(opcode, 15, 12);
6150      Rn = Bits32(opcode, 19, 16);
6151      Rm = Bits32(opcode, 3, 0);
6152      setflags = BitIsSet(opcode, 20);
6153      shift_n = DecodeImmShiftARM(opcode, shift_t);
6154
6155      if (Rd == 15 && setflags)
6156        return EmulateSUBSPcLrEtc(opcode, encoding);
6157      break;
6158    default:
6159      return false;
6160    }
6161
6162    // Read the first operand.
6163    uint32_t val1 = ReadCoreReg(Rn, &success);
6164    if (!success)
6165      return false;
6166
6167    // Read the second operand.
6168    uint32_t val2 = ReadCoreReg(Rm, &success);
6169    if (!success)
6170      return false;
6171
6172    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6173    if (!success)
6174      return false;
6175    uint32_t result = val1 & shifted;
6176
6177    EmulateInstruction::Context context;
6178    context.type = EmulateInstruction::eContextImmediate;
6179    context.SetNoArgs();
6180
6181    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6182      return false;
6183  }
6184  return true;
6185}
6186
6187// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
6188// the complement of an immediate value, and writes the result to the
6189// destination register.  It can optionally update the condition flags based on
6190// the result.
6191bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
6192                                          const ARMEncoding encoding) {
6193#if 0
6194    // ARM pseudo code...
6195    if ConditionPassed() then
6196        EncodingSpecificOperations();
6197        result = R[n] AND NOT(imm32);
6198        if d == 15 then         // Can only occur for ARM encoding
6199            ALUWritePC(result); // setflags is always FALSE here
6200        else
6201            R[d] = result;
6202            if setflags then
6203                APSR.N = result<31>;
6204                APSR.Z = IsZeroBit(result);
6205                APSR.C = carry;
6206                // APSR.V unchanged
6207#endif
6208
6209  bool success = false;
6210
6211  if (ConditionPassed(opcode)) {
6212    uint32_t Rd, Rn;
6213    uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
6214                    // the value obtained from Rn
6215    bool setflags;
6216    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6217    switch (encoding) {
6218    case eEncodingT1:
6219      Rd = Bits32(opcode, 11, 8);
6220      Rn = Bits32(opcode, 19, 16);
6221      setflags = BitIsSet(opcode, 20);
6222      imm32 = ThumbExpandImm_C(
6223          opcode, APSR_C,
6224          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6225      if (BadReg(Rd) || BadReg(Rn))
6226        return false;
6227      break;
6228    case eEncodingA1:
6229      Rd = Bits32(opcode, 15, 12);
6230      Rn = Bits32(opcode, 19, 16);
6231      setflags = BitIsSet(opcode, 20);
6232      imm32 =
6233          ARMExpandImm_C(opcode, APSR_C,
6234                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6235
6236      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6237      // instructions;
6238      if (Rd == 15 && setflags)
6239        return EmulateSUBSPcLrEtc(opcode, encoding);
6240      break;
6241    default:
6242      return false;
6243    }
6244
6245    // Read the first operand.
6246    uint32_t val1 = ReadCoreReg(Rn, &success);
6247    if (!success)
6248      return false;
6249
6250    uint32_t result = val1 & ~imm32;
6251
6252    EmulateInstruction::Context context;
6253    context.type = EmulateInstruction::eContextImmediate;
6254    context.SetNoArgs();
6255
6256    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6257      return false;
6258  }
6259  return true;
6260}
6261
6262// Bitwise Bit Clear (register) performs a bitwise AND of a register value and
6263// the complement of an optionally-shifted register value, and writes the
6264// result to the destination register. It can optionally update the condition
6265// flags based on the result.
6266bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
6267                                          const ARMEncoding encoding) {
6268#if 0
6269    // ARM pseudo code...
6270    if ConditionPassed() then
6271        EncodingSpecificOperations();
6272        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6273        result = R[n] AND NOT(shifted);
6274        if d == 15 then         // Can only occur for ARM encoding
6275            ALUWritePC(result); // setflags is always FALSE here
6276        else
6277            R[d] = result;
6278            if setflags then
6279                APSR.N = result<31>;
6280                APSR.Z = IsZeroBit(result);
6281                APSR.C = carry;
6282                // APSR.V unchanged
6283#endif
6284
6285  bool success = false;
6286
6287  if (ConditionPassed(opcode)) {
6288    uint32_t Rd, Rn, Rm;
6289    ARM_ShifterType shift_t;
6290    uint32_t shift_n; // the shift applied to the value read from Rm
6291    bool setflags;
6292    uint32_t carry;
6293    switch (encoding) {
6294    case eEncodingT1:
6295      Rd = Rn = Bits32(opcode, 2, 0);
6296      Rm = Bits32(opcode, 5, 3);
6297      setflags = !InITBlock();
6298      shift_t = SRType_LSL;
6299      shift_n = 0;
6300      break;
6301    case eEncodingT2:
6302      Rd = Bits32(opcode, 11, 8);
6303      Rn = Bits32(opcode, 19, 16);
6304      Rm = Bits32(opcode, 3, 0);
6305      setflags = BitIsSet(opcode, 20);
6306      shift_n = DecodeImmShiftThumb(opcode, shift_t);
6307      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
6308        return false;
6309      break;
6310    case eEncodingA1:
6311      Rd = Bits32(opcode, 15, 12);
6312      Rn = Bits32(opcode, 19, 16);
6313      Rm = Bits32(opcode, 3, 0);
6314      setflags = BitIsSet(opcode, 20);
6315      shift_n = DecodeImmShiftARM(opcode, shift_t);
6316
6317      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6318      // instructions;
6319      if (Rd == 15 && setflags)
6320        return EmulateSUBSPcLrEtc(opcode, encoding);
6321      break;
6322    default:
6323      return false;
6324    }
6325
6326    // Read the first operand.
6327    uint32_t val1 = ReadCoreReg(Rn, &success);
6328    if (!success)
6329      return false;
6330
6331    // Read the second operand.
6332    uint32_t val2 = ReadCoreReg(Rm, &success);
6333    if (!success)
6334      return false;
6335
6336    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6337    if (!success)
6338      return false;
6339    uint32_t result = val1 & ~shifted;
6340
6341    EmulateInstruction::Context context;
6342    context.type = EmulateInstruction::eContextImmediate;
6343    context.SetNoArgs();
6344
6345    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6346      return false;
6347  }
6348  return true;
6349}
6350
6351// LDR (immediate, ARM) calculates an address from a base register value and an
6352// immediate offset, loads a word
6353// from memory, and writes it to a register.  It can use offset, post-indexed,
6354// or pre-indexed addressing.
6355bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
6356                                                   const ARMEncoding encoding) {
6357#if 0
6358    if ConditionPassed() then
6359        EncodingSpecificOperations();
6360        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6361        address = if index then offset_addr else R[n];
6362        data = MemU[address,4];
6363        if wback then R[n] = offset_addr;
6364        if t == 15 then
6365            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6366        elsif UnalignedSupport() || address<1:0> = '00' then
6367            R[t] = data;
6368        else // Can only apply before ARMv7
6369            R[t] = ROR(data, 8*UInt(address<1:0>));
6370#endif
6371
6372  bool success = false;
6373
6374  if (ConditionPassed(opcode)) {
6375    const uint32_t addr_byte_size = GetAddressByteSize();
6376
6377    uint32_t t;
6378    uint32_t n;
6379    uint32_t imm32;
6380    bool index;
6381    bool add;
6382    bool wback;
6383
6384    switch (encoding) {
6385    case eEncodingA1:
6386      // if Rn == '1111' then SEE LDR (literal);
6387      // if P == '0' && W == '1' then SEE LDRT;
6388      // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
6389      // '000000000100' then SEE POP;
6390      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6391      t = Bits32(opcode, 15, 12);
6392      n = Bits32(opcode, 19, 16);
6393      imm32 = Bits32(opcode, 11, 0);
6394
6395      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6396      // (W == '1');
6397      index = BitIsSet(opcode, 24);
6398      add = BitIsSet(opcode, 23);
6399      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6400
6401      // if wback && n == t then UNPREDICTABLE;
6402      if (wback && (n == t))
6403        return false;
6404
6405      break;
6406
6407    default:
6408      return false;
6409    }
6410
6411    addr_t address;
6412    addr_t offset_addr;
6413    addr_t base_address = ReadCoreReg(n, &success);
6414    if (!success)
6415      return false;
6416
6417    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6418    if (add)
6419      offset_addr = base_address + imm32;
6420    else
6421      offset_addr = base_address - imm32;
6422
6423    // address = if index then offset_addr else R[n];
6424    if (index)
6425      address = offset_addr;
6426    else
6427      address = base_address;
6428
6429    // data = MemU[address,4];
6430
6431    RegisterInfo base_reg;
6432    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6433
6434    EmulateInstruction::Context context;
6435    context.type = eContextRegisterLoad;
6436    context.SetRegisterPlusOffset(base_reg, address - base_address);
6437
6438    uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6439    if (!success)
6440      return false;
6441
6442    // if wback then R[n] = offset_addr;
6443    if (wback) {
6444      context.type = eContextAdjustBaseRegister;
6445      context.SetAddress(offset_addr);
6446      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6447                                 offset_addr))
6448        return false;
6449    }
6450
6451    // if t == 15 then
6452    if (t == 15) {
6453      // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6454      if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6455        // LoadWritePC (data);
6456        context.type = eContextRegisterLoad;
6457        context.SetRegisterPlusOffset(base_reg, address - base_address);
6458        LoadWritePC(context, data);
6459      } else
6460        return false;
6461    }
6462    // elsif UnalignedSupport() || address<1:0> = '00' then
6463    else if (UnalignedSupport() ||
6464             (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6465      // R[t] = data;
6466      context.type = eContextRegisterLoad;
6467      context.SetRegisterPlusOffset(base_reg, address - base_address);
6468      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6469                                 data))
6470        return false;
6471    }
6472    // else // Can only apply before ARMv7
6473    else {
6474      // R[t] = ROR(data, 8*UInt(address<1:0>));
6475      data = ROR(data, Bits32(address, 1, 0), &success);
6476      if (!success)
6477        return false;
6478      context.type = eContextRegisterLoad;
6479      context.SetImmediate(data);
6480      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6481                                 data))
6482        return false;
6483    }
6484  }
6485  return true;
6486}
6487
6488// LDR (register) calculates an address from a base register value and an offset
6489// register value, loads a word
6490// from memory, and writes it to a register.  The offset register value can
6491// optionally be shifted.
6492bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
6493                                               const ARMEncoding encoding) {
6494#if 0
6495    if ConditionPassed() then
6496        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6497        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6498        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6499        address = if index then offset_addr else R[n];
6500        data = MemU[address,4];
6501        if wback then R[n] = offset_addr;
6502        if t == 15 then
6503            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6504        elsif UnalignedSupport() || address<1:0> = '00' then
6505            R[t] = data;
6506        else // Can only apply before ARMv7
6507            if CurrentInstrSet() == InstrSet_ARM then
6508                R[t] = ROR(data, 8*UInt(address<1:0>));
6509            else
6510                R[t] = bits(32) UNKNOWN;
6511#endif
6512
6513  bool success = false;
6514
6515  if (ConditionPassed(opcode)) {
6516    const uint32_t addr_byte_size = GetAddressByteSize();
6517
6518    uint32_t t;
6519    uint32_t n;
6520    uint32_t m;
6521    bool index;
6522    bool add;
6523    bool wback;
6524    ARM_ShifterType shift_t;
6525    uint32_t shift_n;
6526
6527    switch (encoding) {
6528    case eEncodingT1:
6529      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6530      // in ThumbEE";
6531      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6532      t = Bits32(opcode, 2, 0);
6533      n = Bits32(opcode, 5, 3);
6534      m = Bits32(opcode, 8, 6);
6535
6536      // index = TRUE; add = TRUE; wback = FALSE;
6537      index = true;
6538      add = true;
6539      wback = false;
6540
6541      // (shift_t, shift_n) = (SRType_LSL, 0);
6542      shift_t = SRType_LSL;
6543      shift_n = 0;
6544
6545      break;
6546
6547    case eEncodingT2:
6548      // if Rn == '1111' then SEE LDR (literal);
6549      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6550      t = Bits32(opcode, 15, 12);
6551      n = Bits32(opcode, 19, 16);
6552      m = Bits32(opcode, 3, 0);
6553
6554      // index = TRUE; add = TRUE; wback = FALSE;
6555      index = true;
6556      add = true;
6557      wback = false;
6558
6559      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6560      shift_t = SRType_LSL;
6561      shift_n = Bits32(opcode, 5, 4);
6562
6563      // if BadReg(m) then UNPREDICTABLE;
6564      if (BadReg(m))
6565        return false;
6566
6567      // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6568      if ((t == 15) && InITBlock() && !LastInITBlock())
6569        return false;
6570
6571      break;
6572
6573    case eEncodingA1: {
6574      // if P == '0' && W == '1' then SEE LDRT;
6575      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6576      t = Bits32(opcode, 15, 12);
6577      n = Bits32(opcode, 19, 16);
6578      m = Bits32(opcode, 3, 0);
6579
6580      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6581      // (W == '1');
6582      index = BitIsSet(opcode, 24);
6583      add = BitIsSet(opcode, 23);
6584      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6585
6586      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6587      uint32_t type = Bits32(opcode, 6, 5);
6588      uint32_t imm5 = Bits32(opcode, 11, 7);
6589      shift_n = DecodeImmShift(type, imm5, shift_t);
6590
6591      // if m == 15 then UNPREDICTABLE;
6592      if (m == 15)
6593        return false;
6594
6595      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6596      if (wback && ((n == 15) || (n == t)))
6597        return false;
6598    } break;
6599
6600    default:
6601      return false;
6602    }
6603
6604    uint32_t Rm =
6605        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6606    if (!success)
6607      return false;
6608
6609    uint32_t Rn =
6610        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6611    if (!success)
6612      return false;
6613
6614    addr_t offset_addr;
6615    addr_t address;
6616
6617    // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is
6618    // an application level alias for the CPSR".
6619    addr_t offset =
6620        Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
6621    if (!success)
6622      return false;
6623
6624    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6625    if (add)
6626      offset_addr = Rn + offset;
6627    else
6628      offset_addr = Rn - offset;
6629
6630    // address = if index then offset_addr else R[n];
6631    if (index)
6632      address = offset_addr;
6633    else
6634      address = Rn;
6635
6636    // data = MemU[address,4];
6637    RegisterInfo base_reg;
6638    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6639
6640    EmulateInstruction::Context context;
6641    context.type = eContextRegisterLoad;
6642    context.SetRegisterPlusOffset(base_reg, address - Rn);
6643
6644    uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6645    if (!success)
6646      return false;
6647
6648    // if wback then R[n] = offset_addr;
6649    if (wback) {
6650      context.type = eContextAdjustBaseRegister;
6651      context.SetAddress(offset_addr);
6652      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6653                                 offset_addr))
6654        return false;
6655    }
6656
6657    // if t == 15 then
6658    if (t == 15) {
6659      // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6660      if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6661        context.type = eContextRegisterLoad;
6662        context.SetRegisterPlusOffset(base_reg, address - Rn);
6663        LoadWritePC(context, data);
6664      } else
6665        return false;
6666    }
6667    // elsif UnalignedSupport() || address<1:0> = '00' then
6668    else if (UnalignedSupport() ||
6669             (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6670      // R[t] = data;
6671      context.type = eContextRegisterLoad;
6672      context.SetRegisterPlusOffset(base_reg, address - Rn);
6673      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6674                                 data))
6675        return false;
6676    } else // Can only apply before ARMv7
6677    {
6678      // if CurrentInstrSet() == InstrSet_ARM then
6679      if (CurrentInstrSet() == eModeARM) {
6680        // R[t] = ROR(data, 8*UInt(address<1:0>));
6681        data = ROR(data, Bits32(address, 1, 0), &success);
6682        if (!success)
6683          return false;
6684        context.type = eContextRegisterLoad;
6685        context.SetImmediate(data);
6686        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6687                                   data))
6688          return false;
6689      } else {
6690        // R[t] = bits(32) UNKNOWN;
6691        WriteBits32Unknown(t);
6692      }
6693    }
6694  }
6695  return true;
6696}
6697
6698// LDRB (immediate, Thumb)
6699bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
6700                                                 const ARMEncoding encoding) {
6701#if 0
6702    if ConditionPassed() then
6703        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6704        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6705        address = if index then offset_addr else R[n];
6706        R[t] = ZeroExtend(MemU[address,1], 32);
6707        if wback then R[n] = offset_addr;
6708#endif
6709
6710  bool success = false;
6711
6712  if (ConditionPassed(opcode)) {
6713    uint32_t t;
6714    uint32_t n;
6715    uint32_t imm32;
6716    bool index;
6717    bool add;
6718    bool wback;
6719
6720    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6721    switch (encoding) {
6722    case eEncodingT1:
6723      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6724      t = Bits32(opcode, 2, 0);
6725      n = Bits32(opcode, 5, 3);
6726      imm32 = Bits32(opcode, 10, 6);
6727
6728      // index = TRUE; add = TRUE; wback = FALSE;
6729      index = true;
6730      add = true;
6731      wback = false;
6732
6733      break;
6734
6735    case eEncodingT2:
6736      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6737      t = Bits32(opcode, 15, 12);
6738      n = Bits32(opcode, 19, 16);
6739      imm32 = Bits32(opcode, 11, 0);
6740
6741      // index = TRUE; add = TRUE; wback = FALSE;
6742      index = true;
6743      add = true;
6744      wback = false;
6745
6746      // if Rt == '1111' then SEE PLD;
6747      if (t == 15)
6748        return false; // PLD is not implemented yet
6749
6750      // if Rn == '1111' then SEE LDRB (literal);
6751      if (n == 15)
6752        return EmulateLDRBLiteral(opcode, eEncodingT1);
6753
6754      // if t == 13 then UNPREDICTABLE;
6755      if (t == 13)
6756        return false;
6757
6758      break;
6759
6760    case eEncodingT3:
6761      // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6762      // if P == '0' && W == '0' then UNDEFINED;
6763      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6764        return false;
6765
6766      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6767      t = Bits32(opcode, 15, 12);
6768      n = Bits32(opcode, 19, 16);
6769      imm32 = Bits32(opcode, 7, 0);
6770
6771      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6772      index = BitIsSet(opcode, 10);
6773      add = BitIsSet(opcode, 9);
6774      wback = BitIsSet(opcode, 8);
6775
6776      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6777      if (t == 15)
6778        return false; // PLD is not implemented yet
6779
6780      // if Rn == '1111' then SEE LDRB (literal);
6781      if (n == 15)
6782        return EmulateLDRBLiteral(opcode, eEncodingT1);
6783
6784      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6785      if (BadReg(t) || (wback && (n == t)))
6786        return false;
6787
6788      break;
6789
6790    default:
6791      return false;
6792    }
6793
6794    uint32_t Rn =
6795        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6796    if (!success)
6797      return false;
6798
6799    addr_t address;
6800    addr_t offset_addr;
6801
6802    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6803    if (add)
6804      offset_addr = Rn + imm32;
6805    else
6806      offset_addr = Rn - imm32;
6807
6808    // address = if index then offset_addr else R[n];
6809    if (index)
6810      address = offset_addr;
6811    else
6812      address = Rn;
6813
6814    // R[t] = ZeroExtend(MemU[address,1], 32);
6815    RegisterInfo base_reg;
6816    RegisterInfo data_reg;
6817    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6818    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6819
6820    EmulateInstruction::Context context;
6821    context.type = eContextRegisterLoad;
6822    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
6823
6824    uint64_t data = MemURead(context, address, 1, 0, &success);
6825    if (!success)
6826      return false;
6827
6828    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6829      return false;
6830
6831    // if wback then R[n] = offset_addr;
6832    if (wback) {
6833      context.type = eContextAdjustBaseRegister;
6834      context.SetAddress(offset_addr);
6835      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6836                                 offset_addr))
6837        return false;
6838    }
6839  }
6840  return true;
6841}
6842
6843// LDRB (literal) calculates an address from the PC value and an immediate
6844// offset, loads a byte from memory,
6845// zero-extends it to form a 32-bit word and writes it to a register.
6846bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
6847                                               const ARMEncoding encoding) {
6848#if 0
6849    if ConditionPassed() then
6850        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6851        base = Align(PC,4);
6852        address = if add then (base + imm32) else (base - imm32);
6853        R[t] = ZeroExtend(MemU[address,1], 32);
6854#endif
6855
6856  bool success = false;
6857
6858  if (ConditionPassed(opcode)) {
6859    uint32_t t;
6860    uint32_t imm32;
6861    bool add;
6862    switch (encoding) {
6863    case eEncodingT1:
6864      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6865      t = Bits32(opcode, 15, 12);
6866      imm32 = Bits32(opcode, 11, 0);
6867      add = BitIsSet(opcode, 23);
6868
6869      // if Rt == '1111' then SEE PLD;
6870      if (t == 15)
6871        return false; // PLD is not implemented yet
6872
6873      // if t == 13 then UNPREDICTABLE;
6874      if (t == 13)
6875        return false;
6876
6877      break;
6878
6879    case eEncodingA1:
6880      // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6881      t = Bits32(opcode, 15, 12);
6882      imm32 = Bits32(opcode, 11, 0);
6883      add = BitIsSet(opcode, 23);
6884
6885      // if t == 15 then UNPREDICTABLE;
6886      if (t == 15)
6887        return false;
6888      break;
6889
6890    default:
6891      return false;
6892    }
6893
6894    // base = Align(PC,4);
6895    uint32_t pc_val = ReadCoreReg(PC_REG, &success);
6896    if (!success)
6897      return false;
6898
6899    uint32_t base = AlignPC(pc_val);
6900
6901    addr_t address;
6902    // address = if add then (base + imm32) else (base - imm32);
6903    if (add)
6904      address = base + imm32;
6905    else
6906      address = base - imm32;
6907
6908    // R[t] = ZeroExtend(MemU[address,1], 32);
6909    EmulateInstruction::Context context;
6910    context.type = eContextRelativeBranchImmediate;
6911    context.SetImmediate(address - base);
6912
6913    uint64_t data = MemURead(context, address, 1, 0, &success);
6914    if (!success)
6915      return false;
6916
6917    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6918      return false;
6919  }
6920  return true;
6921}
6922
6923// LDRB (register) calculates an address from a base register value and an
6924// offset rigister value, loads a byte from memory, zero-extends it to form a
6925// 32-bit word, and writes it to a register. The offset register value can
6926// optionally be shifted.
6927bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
6928                                                const ARMEncoding encoding) {
6929#if 0
6930    if ConditionPassed() then
6931        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6932        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6933        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6934        address = if index then offset_addr else R[n];
6935        R[t] = ZeroExtend(MemU[address,1],32);
6936        if wback then R[n] = offset_addr;
6937#endif
6938
6939  bool success = false;
6940
6941  if (ConditionPassed(opcode)) {
6942    uint32_t t;
6943    uint32_t n;
6944    uint32_t m;
6945    bool index;
6946    bool add;
6947    bool wback;
6948    ARM_ShifterType shift_t;
6949    uint32_t shift_n;
6950
6951    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6952    switch (encoding) {
6953    case eEncodingT1:
6954      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6955      t = Bits32(opcode, 2, 0);
6956      n = Bits32(opcode, 5, 3);
6957      m = Bits32(opcode, 8, 6);
6958
6959      // index = TRUE; add = TRUE; wback = FALSE;
6960      index = true;
6961      add = true;
6962      wback = false;
6963
6964      // (shift_t, shift_n) = (SRType_LSL, 0);
6965      shift_t = SRType_LSL;
6966      shift_n = 0;
6967      break;
6968
6969    case eEncodingT2:
6970      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6971      t = Bits32(opcode, 15, 12);
6972      n = Bits32(opcode, 19, 16);
6973      m = Bits32(opcode, 3, 0);
6974
6975      // index = TRUE; add = TRUE; wback = FALSE;
6976      index = true;
6977      add = true;
6978      wback = false;
6979
6980      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6981      shift_t = SRType_LSL;
6982      shift_n = Bits32(opcode, 5, 4);
6983
6984      // if Rt == '1111' then SEE PLD;
6985      if (t == 15)
6986        return false; // PLD is not implemented yet
6987
6988      // if Rn == '1111' then SEE LDRB (literal);
6989      if (n == 15)
6990        return EmulateLDRBLiteral(opcode, eEncodingT1);
6991
6992      // if t == 13 || BadReg(m) then UNPREDICTABLE;
6993      if ((t == 13) || BadReg(m))
6994        return false;
6995      break;
6996
6997    case eEncodingA1: {
6998      // if P == '0' && W == '1' then SEE LDRBT;
6999      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7000      t = Bits32(opcode, 15, 12);
7001      n = Bits32(opcode, 19, 16);
7002      m = Bits32(opcode, 3, 0);
7003
7004      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7005      // (W == '1');
7006      index = BitIsSet(opcode, 24);
7007      add = BitIsSet(opcode, 23);
7008      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7009
7010      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
7011      uint32_t type = Bits32(opcode, 6, 5);
7012      uint32_t imm5 = Bits32(opcode, 11, 7);
7013      shift_n = DecodeImmShift(type, imm5, shift_t);
7014
7015      // if t == 15 || m == 15 then UNPREDICTABLE;
7016      if ((t == 15) || (m == 15))
7017        return false;
7018
7019      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7020      if (wback && ((n == 15) || (n == t)))
7021        return false;
7022    } break;
7023
7024    default:
7025      return false;
7026    }
7027
7028    addr_t offset_addr;
7029    addr_t address;
7030
7031    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7032    uint32_t Rm =
7033        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7034    if (!success)
7035      return false;
7036
7037    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7038    if (!success)
7039      return false;
7040
7041    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7042    uint32_t Rn =
7043        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7044    if (!success)
7045      return false;
7046
7047    if (add)
7048      offset_addr = Rn + offset;
7049    else
7050      offset_addr = Rn - offset;
7051
7052    // address = if index then offset_addr else R[n];
7053    if (index)
7054      address = offset_addr;
7055    else
7056      address = Rn;
7057
7058    // R[t] = ZeroExtend(MemU[address,1],32);
7059    RegisterInfo base_reg;
7060    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7061
7062    EmulateInstruction::Context context;
7063    context.type = eContextRegisterLoad;
7064    context.SetRegisterPlusOffset(base_reg, address - Rn);
7065
7066    uint64_t data = MemURead(context, address, 1, 0, &success);
7067    if (!success)
7068      return false;
7069
7070    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
7071      return false;
7072
7073    // if wback then R[n] = offset_addr;
7074    if (wback) {
7075      context.type = eContextAdjustBaseRegister;
7076      context.SetAddress(offset_addr);
7077      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7078                                 offset_addr))
7079        return false;
7080    }
7081  }
7082  return true;
7083}
7084
7085// LDRH (immediate, Thumb) calculates an address from a base register value and
7086// an immediate offset, loads a
7087// halfword from memory, zero-extends it to form a 32-bit word, and writes it
7088// to a register.  It can use offset, post-indexed, or pre-indexed addressing.
7089bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
7090                                                 const ARMEncoding encoding) {
7091#if 0
7092    if ConditionPassed() then
7093        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7094        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7095        address = if index then offset_addr else R[n];
7096        data = MemU[address,2];
7097        if wback then R[n] = offset_addr;
7098        if UnalignedSupport() || address<0> = '0' then
7099            R[t] = ZeroExtend(data, 32);
7100        else // Can only apply before ARMv7
7101            R[t] = bits(32) UNKNOWN;
7102#endif
7103
7104  bool success = false;
7105
7106  if (ConditionPassed(opcode)) {
7107    uint32_t t;
7108    uint32_t n;
7109    uint32_t imm32;
7110    bool index;
7111    bool add;
7112    bool wback;
7113
7114    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7115    switch (encoding) {
7116    case eEncodingT1:
7117      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
7118      t = Bits32(opcode, 2, 0);
7119      n = Bits32(opcode, 5, 3);
7120      imm32 = Bits32(opcode, 10, 6) << 1;
7121
7122      // index = TRUE; add = TRUE; wback = FALSE;
7123      index = true;
7124      add = true;
7125      wback = false;
7126
7127      break;
7128
7129    case eEncodingT2:
7130      // if Rt == '1111' then SEE "Unallocated memory hints";
7131      // if Rn == '1111' then SEE LDRH (literal);
7132      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7133      t = Bits32(opcode, 15, 12);
7134      n = Bits32(opcode, 19, 16);
7135      imm32 = Bits32(opcode, 11, 0);
7136
7137      // index = TRUE; add = TRUE; wback = FALSE;
7138      index = true;
7139      add = true;
7140      wback = false;
7141
7142      // if t == 13 then UNPREDICTABLE;
7143      if (t == 13)
7144        return false;
7145      break;
7146
7147    case eEncodingT3:
7148      // if Rn == '1111' then SEE LDRH (literal);
7149      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7150      // "Unallocated memory hints";
7151      // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
7152      // if P == '0' && W == '0' then UNDEFINED;
7153      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7154        return false;
7155
7156      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7157      t = Bits32(opcode, 15, 12);
7158      n = Bits32(opcode, 19, 16);
7159      imm32 = Bits32(opcode, 7, 0);
7160
7161      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7162      index = BitIsSet(opcode, 10);
7163      add = BitIsSet(opcode, 9);
7164      wback = BitIsSet(opcode, 8);
7165
7166      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7167      if (BadReg(t) || (wback && (n == t)))
7168        return false;
7169      break;
7170
7171    default:
7172      return false;
7173    }
7174
7175    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7176    uint32_t Rn =
7177        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7178    if (!success)
7179      return false;
7180
7181    addr_t offset_addr;
7182    addr_t address;
7183
7184    if (add)
7185      offset_addr = Rn + imm32;
7186    else
7187      offset_addr = Rn - imm32;
7188
7189    // address = if index then offset_addr else R[n];
7190    if (index)
7191      address = offset_addr;
7192    else
7193      address = Rn;
7194
7195    // data = MemU[address,2];
7196    RegisterInfo base_reg;
7197    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7198
7199    EmulateInstruction::Context context;
7200    context.type = eContextRegisterLoad;
7201    context.SetRegisterPlusOffset(base_reg, address - Rn);
7202
7203    uint64_t data = MemURead(context, address, 2, 0, &success);
7204    if (!success)
7205      return false;
7206
7207    // if wback then R[n] = offset_addr;
7208    if (wback) {
7209      context.type = eContextAdjustBaseRegister;
7210      context.SetAddress(offset_addr);
7211      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7212                                 offset_addr))
7213        return false;
7214    }
7215
7216    // if UnalignedSupport() || address<0> = '0' then
7217    if (UnalignedSupport() || BitIsClear(address, 0)) {
7218      // R[t] = ZeroExtend(data, 32);
7219      context.type = eContextRegisterLoad;
7220      context.SetRegisterPlusOffset(base_reg, address - Rn);
7221      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7222                                 data))
7223        return false;
7224    } else // Can only apply before ARMv7
7225    {
7226      // R[t] = bits(32) UNKNOWN;
7227      WriteBits32Unknown(t);
7228    }
7229  }
7230  return true;
7231}
7232
7233// LDRH (literal) caculates an address from the PC value and an immediate
7234// offset, loads a halfword from memory,
7235// zero-extends it to form a 32-bit word, and writes it to a register.
7236bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
7237                                               const ARMEncoding encoding) {
7238#if 0
7239    if ConditionPassed() then
7240        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7241        base = Align(PC,4);
7242        address = if add then (base + imm32) else (base - imm32);
7243        data = MemU[address,2];
7244        if UnalignedSupport() || address<0> = '0' then
7245            R[t] = ZeroExtend(data, 32);
7246        else // Can only apply before ARMv7
7247            R[t] = bits(32) UNKNOWN;
7248#endif
7249
7250  bool success = false;
7251
7252  if (ConditionPassed(opcode)) {
7253    uint32_t t;
7254    uint32_t imm32;
7255    bool add;
7256
7257    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7258    switch (encoding) {
7259    case eEncodingT1:
7260      // if Rt == '1111' then SEE "Unallocated memory hints";
7261      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7262      t = Bits32(opcode, 15, 12);
7263      imm32 = Bits32(opcode, 11, 0);
7264      add = BitIsSet(opcode, 23);
7265
7266      // if t == 13 then UNPREDICTABLE;
7267      if (t == 13)
7268        return false;
7269
7270      break;
7271
7272    case eEncodingA1: {
7273      uint32_t imm4H = Bits32(opcode, 11, 8);
7274      uint32_t imm4L = Bits32(opcode, 3, 0);
7275
7276      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7277      t = Bits32(opcode, 15, 12);
7278      imm32 = (imm4H << 4) | imm4L;
7279      add = BitIsSet(opcode, 23);
7280
7281      // if t == 15 then UNPREDICTABLE;
7282      if (t == 15)
7283        return false;
7284      break;
7285    }
7286
7287    default:
7288      return false;
7289    }
7290
7291    // base = Align(PC,4);
7292    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7293    if (!success)
7294      return false;
7295
7296    addr_t base = AlignPC(pc_value);
7297    addr_t address;
7298
7299    // address = if add then (base + imm32) else (base - imm32);
7300    if (add)
7301      address = base + imm32;
7302    else
7303      address = base - imm32;
7304
7305    // data = MemU[address,2];
7306    RegisterInfo base_reg;
7307    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7308
7309    EmulateInstruction::Context context;
7310    context.type = eContextRegisterLoad;
7311    context.SetRegisterPlusOffset(base_reg, address - base);
7312
7313    uint64_t data = MemURead(context, address, 2, 0, &success);
7314    if (!success)
7315      return false;
7316
7317    // if UnalignedSupport() || address<0> = '0' then
7318    if (UnalignedSupport() || BitIsClear(address, 0)) {
7319      // R[t] = ZeroExtend(data, 32);
7320      context.type = eContextRegisterLoad;
7321      context.SetRegisterPlusOffset(base_reg, address - base);
7322      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7323                                 data))
7324        return false;
7325
7326    } else // Can only apply before ARMv7
7327    {
7328      // R[t] = bits(32) UNKNOWN;
7329      WriteBits32Unknown(t);
7330    }
7331  }
7332  return true;
7333}
7334
7335// LDRH (literal) calculates an address from a base register value and an offset
7336// register value, loads a halfword
7337// from memory, zero-extends it to form a 32-bit word, and writes it to a
7338// register.  The offset register value can be shifted left by 0, 1, 2, or 3
7339// bits.
7340bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
7341                                                const ARMEncoding encoding) {
7342#if 0
7343    if ConditionPassed() then
7344        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7345        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7346        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7347        address = if index then offset_addr else R[n];
7348        data = MemU[address,2];
7349        if wback then R[n] = offset_addr;
7350        if UnalignedSupport() || address<0> = '0' then
7351            R[t] = ZeroExtend(data, 32);
7352        else // Can only apply before ARMv7
7353            R[t] = bits(32) UNKNOWN;
7354#endif
7355
7356  bool success = false;
7357
7358  if (ConditionPassed(opcode)) {
7359    uint32_t t;
7360    uint32_t n;
7361    uint32_t m;
7362    bool index;
7363    bool add;
7364    bool wback;
7365    ARM_ShifterType shift_t;
7366    uint32_t shift_n;
7367
7368    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7369    switch (encoding) {
7370    case eEncodingT1:
7371      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
7372      // in ThumbEE";
7373      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7374      t = Bits32(opcode, 2, 0);
7375      n = Bits32(opcode, 5, 3);
7376      m = Bits32(opcode, 8, 6);
7377
7378      // index = TRUE; add = TRUE; wback = FALSE;
7379      index = true;
7380      add = true;
7381      wback = false;
7382
7383      // (shift_t, shift_n) = (SRType_LSL, 0);
7384      shift_t = SRType_LSL;
7385      shift_n = 0;
7386
7387      break;
7388
7389    case eEncodingT2:
7390      // if Rn == '1111' then SEE LDRH (literal);
7391      // if Rt == '1111' then SEE "Unallocated memory hints";
7392      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7393      t = Bits32(opcode, 15, 12);
7394      n = Bits32(opcode, 19, 16);
7395      m = Bits32(opcode, 3, 0);
7396
7397      // index = TRUE; add = TRUE; wback = FALSE;
7398      index = true;
7399      add = true;
7400      wback = false;
7401
7402      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7403      shift_t = SRType_LSL;
7404      shift_n = Bits32(opcode, 5, 4);
7405
7406      // if t == 13 || BadReg(m) then UNPREDICTABLE;
7407      if ((t == 13) || BadReg(m))
7408        return false;
7409      break;
7410
7411    case eEncodingA1:
7412      // if P == '0' && W == '1' then SEE LDRHT;
7413      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7414      t = Bits32(opcode, 15, 12);
7415      n = Bits32(opcode, 19, 16);
7416      m = Bits32(opcode, 3, 0);
7417
7418      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7419      // (W == '1');
7420      index = BitIsSet(opcode, 24);
7421      add = BitIsSet(opcode, 23);
7422      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7423
7424      // (shift_t, shift_n) = (SRType_LSL, 0);
7425      shift_t = SRType_LSL;
7426      shift_n = 0;
7427
7428      // if t == 15 || m == 15 then UNPREDICTABLE;
7429      if ((t == 15) || (m == 15))
7430        return false;
7431
7432      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7433      if (wback && ((n == 15) || (n == t)))
7434        return false;
7435
7436      break;
7437
7438    default:
7439      return false;
7440    }
7441
7442    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7443
7444    uint64_t Rm =
7445        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7446    if (!success)
7447      return false;
7448
7449    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7450    if (!success)
7451      return false;
7452
7453    addr_t offset_addr;
7454    addr_t address;
7455
7456    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7457    uint64_t Rn =
7458        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7459    if (!success)
7460      return false;
7461
7462    if (add)
7463      offset_addr = Rn + offset;
7464    else
7465      offset_addr = Rn - offset;
7466
7467    // address = if index then offset_addr else R[n];
7468    if (index)
7469      address = offset_addr;
7470    else
7471      address = Rn;
7472
7473    // data = MemU[address,2];
7474    RegisterInfo base_reg;
7475    RegisterInfo offset_reg;
7476    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7477    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7478
7479    EmulateInstruction::Context context;
7480    context.type = eContextRegisterLoad;
7481    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7482    uint64_t data = MemURead(context, address, 2, 0, &success);
7483    if (!success)
7484      return false;
7485
7486    // if wback then R[n] = offset_addr;
7487    if (wback) {
7488      context.type = eContextAdjustBaseRegister;
7489      context.SetAddress(offset_addr);
7490      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7491                                 offset_addr))
7492        return false;
7493    }
7494
7495    // if UnalignedSupport() || address<0> = '0' then
7496    if (UnalignedSupport() || BitIsClear(address, 0)) {
7497      // R[t] = ZeroExtend(data, 32);
7498      context.type = eContextRegisterLoad;
7499      context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7500      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7501                                 data))
7502        return false;
7503    } else // Can only apply before ARMv7
7504    {
7505      // R[t] = bits(32) UNKNOWN;
7506      WriteBits32Unknown(t);
7507    }
7508  }
7509  return true;
7510}
7511
7512// LDRSB (immediate) calculates an address from a base register value and an
7513// immediate offset, loads a byte from
7514// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7515// It can use offset, post-indexed, or pre-indexed addressing.
7516bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
7517                                                  const ARMEncoding encoding) {
7518#if 0
7519    if ConditionPassed() then
7520        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7521        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7522        address = if index then offset_addr else R[n];
7523        R[t] = SignExtend(MemU[address,1], 32);
7524        if wback then R[n] = offset_addr;
7525#endif
7526
7527  bool success = false;
7528
7529  if (ConditionPassed(opcode)) {
7530    uint32_t t;
7531    uint32_t n;
7532    uint32_t imm32;
7533    bool index;
7534    bool add;
7535    bool wback;
7536
7537    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7538    switch (encoding) {
7539    case eEncodingT1:
7540      // if Rt == '1111' then SEE PLI;
7541      // if Rn == '1111' then SEE LDRSB (literal);
7542      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7543      t = Bits32(opcode, 15, 12);
7544      n = Bits32(opcode, 19, 16);
7545      imm32 = Bits32(opcode, 11, 0);
7546
7547      // index = TRUE; add = TRUE; wback = FALSE;
7548      index = true;
7549      add = true;
7550      wback = false;
7551
7552      // if t == 13 then UNPREDICTABLE;
7553      if (t == 13)
7554        return false;
7555
7556      break;
7557
7558    case eEncodingT2:
7559      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7560      // if Rn == '1111' then SEE LDRSB (literal);
7561      // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7562      // if P == '0' && W == '0' then UNDEFINED;
7563      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7564        return false;
7565
7566      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7567      t = Bits32(opcode, 15, 12);
7568      n = Bits32(opcode, 19, 16);
7569      imm32 = Bits32(opcode, 7, 0);
7570
7571      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7572      index = BitIsSet(opcode, 10);
7573      add = BitIsSet(opcode, 9);
7574      wback = BitIsSet(opcode, 8);
7575
7576      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7577      if (((t == 13) ||
7578           ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
7579                          BitIsSet(opcode, 8)))) ||
7580          (wback && (n == t)))
7581        return false;
7582
7583      break;
7584
7585    case eEncodingA1: {
7586      // if Rn == '1111' then SEE LDRSB (literal);
7587      // if P == '0' && W == '1' then SEE LDRSBT;
7588      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7589      t = Bits32(opcode, 15, 12);
7590      n = Bits32(opcode, 19, 16);
7591
7592      uint32_t imm4H = Bits32(opcode, 11, 8);
7593      uint32_t imm4L = Bits32(opcode, 3, 0);
7594      imm32 = (imm4H << 4) | imm4L;
7595
7596      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7597      // (W == '1');
7598      index = BitIsSet(opcode, 24);
7599      add = BitIsSet(opcode, 23);
7600      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7601
7602      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7603      if ((t == 15) || (wback && (n == t)))
7604        return false;
7605
7606      break;
7607    }
7608
7609    default:
7610      return false;
7611    }
7612
7613    uint64_t Rn = ReadCoreReg(n, &success);
7614    if (!success)
7615      return false;
7616
7617    addr_t offset_addr;
7618    addr_t address;
7619
7620    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7621    if (add)
7622      offset_addr = Rn + imm32;
7623    else
7624      offset_addr = Rn - imm32;
7625
7626    // address = if index then offset_addr else R[n];
7627    if (index)
7628      address = offset_addr;
7629    else
7630      address = Rn;
7631
7632    // R[t] = SignExtend(MemU[address,1], 32);
7633    RegisterInfo base_reg;
7634    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7635
7636    EmulateInstruction::Context context;
7637    context.type = eContextRegisterLoad;
7638    context.SetRegisterPlusOffset(base_reg, address - Rn);
7639
7640    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7641    if (!success)
7642      return false;
7643
7644    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7645    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7646                               (uint64_t)signed_data))
7647      return false;
7648
7649    // if wback then R[n] = offset_addr;
7650    if (wback) {
7651      context.type = eContextAdjustBaseRegister;
7652      context.SetAddress(offset_addr);
7653      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7654                                 offset_addr))
7655        return false;
7656    }
7657  }
7658
7659  return true;
7660}
7661
7662// LDRSB (literal) calculates an address from the PC value and an immediate
7663// offset, loads a byte from memory,
7664// sign-extends it to form a 32-bit word, and writes tit to a register.
7665bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
7666                                                const ARMEncoding encoding) {
7667#if 0
7668    if ConditionPassed() then
7669        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7670        base = Align(PC,4);
7671        address = if add then (base + imm32) else (base - imm32);
7672        R[t] = SignExtend(MemU[address,1], 32);
7673#endif
7674
7675  bool success = false;
7676
7677  if (ConditionPassed(opcode)) {
7678    uint32_t t;
7679    uint32_t imm32;
7680    bool add;
7681
7682    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7683    switch (encoding) {
7684    case eEncodingT1:
7685      // if Rt == '1111' then SEE PLI;
7686      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7687      t = Bits32(opcode, 15, 12);
7688      imm32 = Bits32(opcode, 11, 0);
7689      add = BitIsSet(opcode, 23);
7690
7691      // if t == 13 then UNPREDICTABLE;
7692      if (t == 13)
7693        return false;
7694
7695      break;
7696
7697    case eEncodingA1: {
7698      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7699      t = Bits32(opcode, 15, 12);
7700      uint32_t imm4H = Bits32(opcode, 11, 8);
7701      uint32_t imm4L = Bits32(opcode, 3, 0);
7702      imm32 = (imm4H << 4) | imm4L;
7703      add = BitIsSet(opcode, 23);
7704
7705      // if t == 15 then UNPREDICTABLE;
7706      if (t == 15)
7707        return false;
7708
7709      break;
7710    }
7711
7712    default:
7713      return false;
7714    }
7715
7716    // base = Align(PC,4);
7717    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7718    if (!success)
7719      return false;
7720    uint64_t base = AlignPC(pc_value);
7721
7722    // address = if add then (base + imm32) else (base - imm32);
7723    addr_t address;
7724    if (add)
7725      address = base + imm32;
7726    else
7727      address = base - imm32;
7728
7729    // R[t] = SignExtend(MemU[address,1], 32);
7730    RegisterInfo base_reg;
7731    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7732
7733    EmulateInstruction::Context context;
7734    context.type = eContextRegisterLoad;
7735    context.SetRegisterPlusOffset(base_reg, address - base);
7736
7737    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7738    if (!success)
7739      return false;
7740
7741    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7742    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7743                               (uint64_t)signed_data))
7744      return false;
7745  }
7746  return true;
7747}
7748
7749// LDRSB (register) calculates an address from a base register value and an
7750// offset register value, loadsa byte from
7751// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7752// The offset register value can be shifted left by 0, 1, 2, or 3 bits.
7753bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
7754                                                 const ARMEncoding encoding) {
7755#if 0
7756    if ConditionPassed() then
7757        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7758        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7759        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7760        address = if index then offset_addr else R[n];
7761        R[t] = SignExtend(MemU[address,1], 32);
7762        if wback then R[n] = offset_addr;
7763#endif
7764
7765  bool success = false;
7766
7767  if (ConditionPassed(opcode)) {
7768    uint32_t t;
7769    uint32_t n;
7770    uint32_t m;
7771    bool index;
7772    bool add;
7773    bool wback;
7774    ARM_ShifterType shift_t;
7775    uint32_t shift_n;
7776
7777    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7778    switch (encoding) {
7779    case eEncodingT1:
7780      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7781      t = Bits32(opcode, 2, 0);
7782      n = Bits32(opcode, 5, 3);
7783      m = Bits32(opcode, 8, 6);
7784
7785      // index = TRUE; add = TRUE; wback = FALSE;
7786      index = true;
7787      add = true;
7788      wback = false;
7789
7790      // (shift_t, shift_n) = (SRType_LSL, 0);
7791      shift_t = SRType_LSL;
7792      shift_n = 0;
7793
7794      break;
7795
7796    case eEncodingT2:
7797      // if Rt == '1111' then SEE PLI;
7798      // if Rn == '1111' then SEE LDRSB (literal);
7799      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7800      t = Bits32(opcode, 15, 12);
7801      n = Bits32(opcode, 19, 16);
7802      m = Bits32(opcode, 3, 0);
7803
7804      // index = TRUE; add = TRUE; wback = FALSE;
7805      index = true;
7806      add = true;
7807      wback = false;
7808
7809      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7810      shift_t = SRType_LSL;
7811      shift_n = Bits32(opcode, 5, 4);
7812
7813      // if t == 13 || BadReg(m) then UNPREDICTABLE;
7814      if ((t == 13) || BadReg(m))
7815        return false;
7816      break;
7817
7818    case eEncodingA1:
7819      // if P == '0' && W == '1' then SEE LDRSBT;
7820      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7821      t = Bits32(opcode, 15, 12);
7822      n = Bits32(opcode, 19, 16);
7823      m = Bits32(opcode, 3, 0);
7824
7825      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7826      // (W == '1');
7827      index = BitIsSet(opcode, 24);
7828      add = BitIsSet(opcode, 23);
7829      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7830
7831      // (shift_t, shift_n) = (SRType_LSL, 0);
7832      shift_t = SRType_LSL;
7833      shift_n = 0;
7834
7835      // if t == 15 || m == 15 then UNPREDICTABLE;
7836      if ((t == 15) || (m == 15))
7837        return false;
7838
7839      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7840      if (wback && ((n == 15) || (n == t)))
7841        return false;
7842      break;
7843
7844    default:
7845      return false;
7846    }
7847
7848    uint64_t Rm =
7849        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7850    if (!success)
7851      return false;
7852
7853    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7854    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7855    if (!success)
7856      return false;
7857
7858    addr_t offset_addr;
7859    addr_t address;
7860
7861    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7862    uint64_t Rn =
7863        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7864    if (!success)
7865      return false;
7866
7867    if (add)
7868      offset_addr = Rn + offset;
7869    else
7870      offset_addr = Rn - offset;
7871
7872    // address = if index then offset_addr else R[n];
7873    if (index)
7874      address = offset_addr;
7875    else
7876      address = Rn;
7877
7878    // R[t] = SignExtend(MemU[address,1], 32);
7879    RegisterInfo base_reg;
7880    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7881    RegisterInfo offset_reg;
7882    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7883
7884    EmulateInstruction::Context context;
7885    context.type = eContextRegisterLoad;
7886    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7887
7888    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7889    if (!success)
7890      return false;
7891
7892    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7893    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7894                               (uint64_t)signed_data))
7895      return false;
7896
7897    // if wback then R[n] = offset_addr;
7898    if (wback) {
7899      context.type = eContextAdjustBaseRegister;
7900      context.SetAddress(offset_addr);
7901      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7902                                 offset_addr))
7903        return false;
7904    }
7905  }
7906  return true;
7907}
7908
7909// LDRSH (immediate) calculates an address from a base register value and an
7910// immediate offset, loads a halfword from
7911// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7912// It can use offset, post-indexed, or pre-indexed addressing.
7913bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
7914                                                  const ARMEncoding encoding) {
7915#if 0
7916    if ConditionPassed() then
7917        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7918        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7919        address = if index then offset_addr else R[n];
7920        data = MemU[address,2];
7921        if wback then R[n] = offset_addr;
7922        if UnalignedSupport() || address<0> = '0' then
7923            R[t] = SignExtend(data, 32);
7924        else // Can only apply before ARMv7
7925            R[t] = bits(32) UNKNOWN;
7926#endif
7927
7928  bool success = false;
7929
7930  if (ConditionPassed(opcode)) {
7931    uint32_t t;
7932    uint32_t n;
7933    uint32_t imm32;
7934    bool index;
7935    bool add;
7936    bool wback;
7937
7938    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7939    switch (encoding) {
7940    case eEncodingT1:
7941      // if Rn == '1111' then SEE LDRSH (literal);
7942      // if Rt == '1111' then SEE "Unallocated memory hints";
7943      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7944      t = Bits32(opcode, 15, 12);
7945      n = Bits32(opcode, 19, 16);
7946      imm32 = Bits32(opcode, 11, 0);
7947
7948      // index = TRUE; add = TRUE; wback = FALSE;
7949      index = true;
7950      add = true;
7951      wback = false;
7952
7953      // if t == 13 then UNPREDICTABLE;
7954      if (t == 13)
7955        return false;
7956
7957      break;
7958
7959    case eEncodingT2:
7960      // if Rn == '1111' then SEE LDRSH (literal);
7961      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7962      // "Unallocated memory hints";
7963      // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7964      // if P == '0' && W == '0' then UNDEFINED;
7965      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7966        return false;
7967
7968      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7969      t = Bits32(opcode, 15, 12);
7970      n = Bits32(opcode, 19, 16);
7971      imm32 = Bits32(opcode, 7, 0);
7972
7973      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7974      index = BitIsSet(opcode, 10);
7975      add = BitIsSet(opcode, 9);
7976      wback = BitIsSet(opcode, 8);
7977
7978      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7979      if (BadReg(t) || (wback && (n == t)))
7980        return false;
7981
7982      break;
7983
7984    case eEncodingA1: {
7985      // if Rn == '1111' then SEE LDRSH (literal);
7986      // if P == '0' && W == '1' then SEE LDRSHT;
7987      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7988      t = Bits32(opcode, 15, 12);
7989      n = Bits32(opcode, 19, 16);
7990      uint32_t imm4H = Bits32(opcode, 11, 8);
7991      uint32_t imm4L = Bits32(opcode, 3, 0);
7992      imm32 = (imm4H << 4) | imm4L;
7993
7994      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7995      // (W == '1');
7996      index = BitIsSet(opcode, 24);
7997      add = BitIsSet(opcode, 23);
7998      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7999
8000      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
8001      if ((t == 15) || (wback && (n == t)))
8002        return false;
8003
8004      break;
8005    }
8006
8007    default:
8008      return false;
8009    }
8010
8011    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
8012    uint64_t Rn =
8013        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8014    if (!success)
8015      return false;
8016
8017    addr_t offset_addr;
8018    if (add)
8019      offset_addr = Rn + imm32;
8020    else
8021      offset_addr = Rn - imm32;
8022
8023    // address = if index then offset_addr else R[n];
8024    addr_t address;
8025    if (index)
8026      address = offset_addr;
8027    else
8028      address = Rn;
8029
8030    // data = MemU[address,2];
8031    RegisterInfo base_reg;
8032    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8033
8034    EmulateInstruction::Context context;
8035    context.type = eContextRegisterLoad;
8036    context.SetRegisterPlusOffset(base_reg, address - Rn);
8037
8038    uint64_t data = MemURead(context, address, 2, 0, &success);
8039    if (!success)
8040      return false;
8041
8042    // if wback then R[n] = offset_addr;
8043    if (wback) {
8044      context.type = eContextAdjustBaseRegister;
8045      context.SetAddress(offset_addr);
8046      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8047                                 offset_addr))
8048        return false;
8049    }
8050
8051    // if UnalignedSupport() || address<0> = '0' then
8052    if (UnalignedSupport() || BitIsClear(address, 0)) {
8053      // R[t] = SignExtend(data, 32);
8054      int64_t signed_data = llvm::SignExtend64<16>(data);
8055      context.type = eContextRegisterLoad;
8056      context.SetRegisterPlusOffset(base_reg, address - Rn);
8057      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8058                                 (uint64_t)signed_data))
8059        return false;
8060    } else // Can only apply before ARMv7
8061    {
8062      // R[t] = bits(32) UNKNOWN;
8063      WriteBits32Unknown(t);
8064    }
8065  }
8066  return true;
8067}
8068
8069// LDRSH (literal) calculates an address from the PC value and an immediate
8070// offset, loads a halfword from memory,
8071// sign-extends it to from a 32-bit word, and writes it to a register.
8072bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
8073                                                const ARMEncoding encoding) {
8074#if 0
8075    if ConditionPassed() then
8076        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8077        base = Align(PC,4);
8078        address = if add then (base + imm32) else (base - imm32);
8079        data = MemU[address,2];
8080        if UnalignedSupport() || address<0> = '0' then
8081            R[t] = SignExtend(data, 32);
8082        else // Can only apply before ARMv7
8083            R[t] = bits(32) UNKNOWN;
8084#endif
8085
8086  bool success = false;
8087
8088  if (ConditionPassed(opcode)) {
8089    uint32_t t;
8090    uint32_t imm32;
8091    bool add;
8092
8093    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8094    switch (encoding) {
8095    case eEncodingT1:
8096      // if Rt == '1111' then SEE "Unallocated memory hints";
8097      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
8098      t = Bits32(opcode, 15, 12);
8099      imm32 = Bits32(opcode, 11, 0);
8100      add = BitIsSet(opcode, 23);
8101
8102      // if t == 13 then UNPREDICTABLE;
8103      if (t == 13)
8104        return false;
8105
8106      break;
8107
8108    case eEncodingA1: {
8109      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
8110      t = Bits32(opcode, 15, 12);
8111      uint32_t imm4H = Bits32(opcode, 11, 8);
8112      uint32_t imm4L = Bits32(opcode, 3, 0);
8113      imm32 = (imm4H << 4) | imm4L;
8114      add = BitIsSet(opcode, 23);
8115
8116      // if t == 15 then UNPREDICTABLE;
8117      if (t == 15)
8118        return false;
8119
8120      break;
8121    }
8122    default:
8123      return false;
8124    }
8125
8126    // base = Align(PC,4);
8127    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
8128    if (!success)
8129      return false;
8130
8131    uint64_t base = AlignPC(pc_value);
8132
8133    addr_t address;
8134    // address = if add then (base + imm32) else (base - imm32);
8135    if (add)
8136      address = base + imm32;
8137    else
8138      address = base - imm32;
8139
8140    // data = MemU[address,2];
8141    RegisterInfo base_reg;
8142    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
8143
8144    EmulateInstruction::Context context;
8145    context.type = eContextRegisterLoad;
8146    context.SetRegisterPlusOffset(base_reg, imm32);
8147
8148    uint64_t data = MemURead(context, address, 2, 0, &success);
8149    if (!success)
8150      return false;
8151
8152    // if UnalignedSupport() || address<0> = '0' then
8153    if (UnalignedSupport() || BitIsClear(address, 0)) {
8154      // R[t] = SignExtend(data, 32);
8155      int64_t signed_data = llvm::SignExtend64<16>(data);
8156      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8157                                 (uint64_t)signed_data))
8158        return false;
8159    } else // Can only apply before ARMv7
8160    {
8161      // R[t] = bits(32) UNKNOWN;
8162      WriteBits32Unknown(t);
8163    }
8164  }
8165  return true;
8166}
8167
8168// LDRSH (register) calculates an address from a base register value and an
8169// offset register value, loads a halfword
8170// from memory, sign-extends it to form a 32-bit word, and writes it to a
8171// register.  The offset register value can be shifted left by 0, 1, 2, or 3
8172// bits.
8173bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
8174                                                 const ARMEncoding encoding) {
8175#if 0
8176    if ConditionPassed() then
8177        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8178        offset = Shift(R[m], shift_t, shift_n, APSR.C);
8179        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8180        address = if index then offset_addr else R[n];
8181        data = MemU[address,2];
8182        if wback then R[n] = offset_addr;
8183        if UnalignedSupport() || address<0> = '0' then
8184            R[t] = SignExtend(data, 32);
8185        else // Can only apply before ARMv7
8186            R[t] = bits(32) UNKNOWN;
8187#endif
8188
8189  bool success = false;
8190
8191  if (ConditionPassed(opcode)) {
8192    uint32_t t;
8193    uint32_t n;
8194    uint32_t m;
8195    bool index;
8196    bool add;
8197    bool wback;
8198    ARM_ShifterType shift_t;
8199    uint32_t shift_n;
8200
8201    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8202    switch (encoding) {
8203    case eEncodingT1:
8204      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
8205      // in ThumbEE";
8206      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8207      t = Bits32(opcode, 2, 0);
8208      n = Bits32(opcode, 5, 3);
8209      m = Bits32(opcode, 8, 6);
8210
8211      // index = TRUE; add = TRUE; wback = FALSE;
8212      index = true;
8213      add = true;
8214      wback = false;
8215
8216      // (shift_t, shift_n) = (SRType_LSL, 0);
8217      shift_t = SRType_LSL;
8218      shift_n = 0;
8219
8220      break;
8221
8222    case eEncodingT2:
8223      // if Rn == '1111' then SEE LDRSH (literal);
8224      // if Rt == '1111' then SEE "Unallocated memory hints";
8225      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8226      t = Bits32(opcode, 15, 12);
8227      n = Bits32(opcode, 19, 16);
8228      m = Bits32(opcode, 3, 0);
8229
8230      // index = TRUE; add = TRUE; wback = FALSE;
8231      index = true;
8232      add = true;
8233      wback = false;
8234
8235      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
8236      shift_t = SRType_LSL;
8237      shift_n = Bits32(opcode, 5, 4);
8238
8239      // if t == 13 || BadReg(m) then UNPREDICTABLE;
8240      if ((t == 13) || BadReg(m))
8241        return false;
8242
8243      break;
8244
8245    case eEncodingA1:
8246      // if P == '0' && W == '1' then SEE LDRSHT;
8247      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8248      t = Bits32(opcode, 15, 12);
8249      n = Bits32(opcode, 19, 16);
8250      m = Bits32(opcode, 3, 0);
8251
8252      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
8253      // (W == '1');
8254      index = BitIsSet(opcode, 24);
8255      add = BitIsSet(opcode, 23);
8256      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8257
8258      // (shift_t, shift_n) = (SRType_LSL, 0);
8259      shift_t = SRType_LSL;
8260      shift_n = 0;
8261
8262      // if t == 15 || m == 15 then UNPREDICTABLE;
8263      if ((t == 15) || (m == 15))
8264        return false;
8265
8266      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
8267      if (wback && ((n == 15) || (n == t)))
8268        return false;
8269
8270      break;
8271
8272    default:
8273      return false;
8274    }
8275
8276    uint64_t Rm =
8277        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8278    if (!success)
8279      return false;
8280
8281    uint64_t Rn =
8282        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8283    if (!success)
8284      return false;
8285
8286    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
8287    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
8288    if (!success)
8289      return false;
8290
8291    addr_t offset_addr;
8292    addr_t address;
8293
8294    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8295    if (add)
8296      offset_addr = Rn + offset;
8297    else
8298      offset_addr = Rn - offset;
8299
8300    // address = if index then offset_addr else R[n];
8301    if (index)
8302      address = offset_addr;
8303    else
8304      address = Rn;
8305
8306    // data = MemU[address,2];
8307    RegisterInfo base_reg;
8308    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8309
8310    RegisterInfo offset_reg;
8311    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
8312
8313    EmulateInstruction::Context context;
8314    context.type = eContextRegisterLoad;
8315    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8316
8317    uint64_t data = MemURead(context, address, 2, 0, &success);
8318    if (!success)
8319      return false;
8320
8321    // if wback then R[n] = offset_addr;
8322    if (wback) {
8323      context.type = eContextAdjustBaseRegister;
8324      context.SetAddress(offset_addr);
8325      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8326                                 offset_addr))
8327        return false;
8328    }
8329
8330    // if UnalignedSupport() || address<0> = '0' then
8331    if (UnalignedSupport() || BitIsClear(address, 0)) {
8332      // R[t] = SignExtend(data, 32);
8333      context.type = eContextRegisterLoad;
8334      context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8335
8336      int64_t signed_data = llvm::SignExtend64<16>(data);
8337      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8338                                 (uint64_t)signed_data))
8339        return false;
8340    } else // Can only apply before ARMv7
8341    {
8342      // R[t] = bits(32) UNKNOWN;
8343      WriteBits32Unknown(t);
8344    }
8345  }
8346  return true;
8347}
8348
8349// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
8350// writes the result to the destination
8351// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before
8352// extracting the 8-bit value.
8353bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
8354                                        const ARMEncoding encoding) {
8355#if 0
8356    if ConditionPassed() then
8357        EncodingSpecificOperations();
8358        rotated = ROR(R[m], rotation);
8359        R[d] = SignExtend(rotated<7:0>, 32);
8360#endif
8361
8362  bool success = false;
8363
8364  if (ConditionPassed(opcode)) {
8365    uint32_t d;
8366    uint32_t m;
8367    uint32_t rotation;
8368
8369    // EncodingSpecificOperations();
8370    switch (encoding) {
8371    case eEncodingT1:
8372      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8373      d = Bits32(opcode, 2, 0);
8374      m = Bits32(opcode, 5, 3);
8375      rotation = 0;
8376
8377      break;
8378
8379    case eEncodingT2:
8380      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8381      d = Bits32(opcode, 11, 8);
8382      m = Bits32(opcode, 3, 0);
8383      rotation = Bits32(opcode, 5, 4) << 3;
8384
8385      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8386      if (BadReg(d) || BadReg(m))
8387        return false;
8388
8389      break;
8390
8391    case eEncodingA1:
8392      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8393      d = Bits32(opcode, 15, 12);
8394      m = Bits32(opcode, 3, 0);
8395      rotation = Bits32(opcode, 11, 10) << 3;
8396
8397      // if d == 15 || m == 15 then UNPREDICTABLE;
8398      if ((d == 15) || (m == 15))
8399        return false;
8400
8401      break;
8402
8403    default:
8404      return false;
8405    }
8406
8407    uint64_t Rm =
8408        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8409    if (!success)
8410      return false;
8411
8412    // rotated = ROR(R[m], rotation);
8413    uint64_t rotated = ROR(Rm, rotation, &success);
8414    if (!success)
8415      return false;
8416
8417    // R[d] = SignExtend(rotated<7:0>, 32);
8418    int64_t data = llvm::SignExtend64<8>(rotated);
8419
8420    RegisterInfo source_reg;
8421    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8422
8423    EmulateInstruction::Context context;
8424    context.type = eContextRegisterLoad;
8425    context.SetRegister(source_reg);
8426
8427    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8428                               (uint64_t)data))
8429      return false;
8430  }
8431  return true;
8432}
8433
8434// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
8435// writes the result to the destination
8436// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8437// extracting the 16-bit value.
8438bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
8439                                        const ARMEncoding encoding) {
8440#if 0
8441    if ConditionPassed() then
8442        EncodingSpecificOperations();
8443        rotated = ROR(R[m], rotation);
8444        R[d] = SignExtend(rotated<15:0>, 32);
8445#endif
8446
8447  bool success = false;
8448
8449  if (ConditionPassed(opcode)) {
8450    uint32_t d;
8451    uint32_t m;
8452    uint32_t rotation;
8453
8454    // EncodingSpecificOperations();
8455    switch (encoding) {
8456    case eEncodingT1:
8457      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8458      d = Bits32(opcode, 2, 0);
8459      m = Bits32(opcode, 5, 3);
8460      rotation = 0;
8461
8462      break;
8463
8464    case eEncodingT2:
8465      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8466      d = Bits32(opcode, 11, 8);
8467      m = Bits32(opcode, 3, 0);
8468      rotation = Bits32(opcode, 5, 4) << 3;
8469
8470      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8471      if (BadReg(d) || BadReg(m))
8472        return false;
8473
8474      break;
8475
8476    case eEncodingA1:
8477      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8478      d = Bits32(opcode, 15, 12);
8479      m = Bits32(opcode, 3, 0);
8480      rotation = Bits32(opcode, 11, 10) << 3;
8481
8482      // if d == 15 || m == 15 then UNPREDICTABLE;
8483      if ((d == 15) || (m == 15))
8484        return false;
8485
8486      break;
8487
8488    default:
8489      return false;
8490    }
8491
8492    uint64_t Rm =
8493        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8494    if (!success)
8495      return false;
8496
8497    // rotated = ROR(R[m], rotation);
8498    uint64_t rotated = ROR(Rm, rotation, &success);
8499    if (!success)
8500      return false;
8501
8502    // R[d] = SignExtend(rotated<15:0>, 32);
8503    RegisterInfo source_reg;
8504    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8505
8506    EmulateInstruction::Context context;
8507    context.type = eContextRegisterLoad;
8508    context.SetRegister(source_reg);
8509
8510    int64_t data = llvm::SignExtend64<16>(rotated);
8511    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8512                               (uint64_t)data))
8513      return false;
8514  }
8515
8516  return true;
8517}
8518
8519// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and
8520// writes the result to the destination
8521// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8522// extracting the 8-bit value.
8523bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
8524                                        const ARMEncoding encoding) {
8525#if 0
8526    if ConditionPassed() then
8527        EncodingSpecificOperations();
8528        rotated = ROR(R[m], rotation);
8529        R[d] = ZeroExtend(rotated<7:0>, 32);
8530#endif
8531
8532  bool success = false;
8533
8534  if (ConditionPassed(opcode)) {
8535    uint32_t d;
8536    uint32_t m;
8537    uint32_t rotation;
8538
8539    // EncodingSpecificOperations();
8540    switch (encoding) {
8541    case eEncodingT1:
8542      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8543      d = Bits32(opcode, 2, 0);
8544      m = Bits32(opcode, 5, 3);
8545      rotation = 0;
8546
8547      break;
8548
8549    case eEncodingT2:
8550      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8551      d = Bits32(opcode, 11, 8);
8552      m = Bits32(opcode, 3, 0);
8553      rotation = Bits32(opcode, 5, 4) << 3;
8554
8555      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8556      if (BadReg(d) || BadReg(m))
8557        return false;
8558
8559      break;
8560
8561    case eEncodingA1:
8562      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8563      d = Bits32(opcode, 15, 12);
8564      m = Bits32(opcode, 3, 0);
8565      rotation = Bits32(opcode, 11, 10) << 3;
8566
8567      // if d == 15 || m == 15 then UNPREDICTABLE;
8568      if ((d == 15) || (m == 15))
8569        return false;
8570
8571      break;
8572
8573    default:
8574      return false;
8575    }
8576
8577    uint64_t Rm =
8578        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8579    if (!success)
8580      return false;
8581
8582    // rotated = ROR(R[m], rotation);
8583    uint64_t rotated = ROR(Rm, rotation, &success);
8584    if (!success)
8585      return false;
8586
8587    // R[d] = ZeroExtend(rotated<7:0>, 32);
8588    RegisterInfo source_reg;
8589    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8590
8591    EmulateInstruction::Context context;
8592    context.type = eContextRegisterLoad;
8593    context.SetRegister(source_reg);
8594
8595    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8596                               Bits32(rotated, 7, 0)))
8597      return false;
8598  }
8599  return true;
8600}
8601
8602// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
8603// writes the result to the destination
8604// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8605// extracting the 16-bit value.
8606bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
8607                                        const ARMEncoding encoding) {
8608#if 0
8609    if ConditionPassed() then
8610        EncodingSpecificOperations();
8611        rotated = ROR(R[m], rotation);
8612        R[d] = ZeroExtend(rotated<15:0>, 32);
8613#endif
8614
8615  bool success = false;
8616
8617  if (ConditionPassed(opcode)) {
8618    uint32_t d;
8619    uint32_t m;
8620    uint32_t rotation;
8621
8622    switch (encoding) {
8623    case eEncodingT1:
8624      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8625      d = Bits32(opcode, 2, 0);
8626      m = Bits32(opcode, 5, 3);
8627      rotation = 0;
8628
8629      break;
8630
8631    case eEncodingT2:
8632      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8633      d = Bits32(opcode, 11, 8);
8634      m = Bits32(opcode, 3, 0);
8635      rotation = Bits32(opcode, 5, 4) << 3;
8636
8637      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8638      if (BadReg(d) || BadReg(m))
8639        return false;
8640
8641      break;
8642
8643    case eEncodingA1:
8644      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8645      d = Bits32(opcode, 15, 12);
8646      m = Bits32(opcode, 3, 0);
8647      rotation = Bits32(opcode, 11, 10) << 3;
8648
8649      // if d == 15 || m == 15 then UNPREDICTABLE;
8650      if ((d == 15) || (m == 15))
8651        return false;
8652
8653      break;
8654
8655    default:
8656      return false;
8657    }
8658
8659    uint64_t Rm =
8660        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8661    if (!success)
8662      return false;
8663
8664    // rotated = ROR(R[m], rotation);
8665    uint64_t rotated = ROR(Rm, rotation, &success);
8666    if (!success)
8667      return false;
8668
8669    // R[d] = ZeroExtend(rotated<15:0>, 32);
8670    RegisterInfo source_reg;
8671    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8672
8673    EmulateInstruction::Context context;
8674    context.type = eContextRegisterLoad;
8675    context.SetRegister(source_reg);
8676
8677    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8678                               Bits32(rotated, 15, 0)))
8679      return false;
8680  }
8681  return true;
8682}
8683
8684// RFE (Return From Exception) loads the PC and the CPSR from the word at the
8685// specified address and the following
8686// word respectively.
8687bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
8688                                       const ARMEncoding encoding) {
8689#if 0
8690    if ConditionPassed() then
8691        EncodingSpecificOperations();
8692        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8693            UNPREDICTABLE;
8694        else
8695            address = if increment then R[n] else R[n]-8;
8696            if wordhigher then address = address+4;
8697            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8698            BranchWritePC(MemA[address,4]);
8699            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8700#endif
8701
8702  bool success = false;
8703
8704  if (ConditionPassed(opcode)) {
8705    uint32_t n;
8706    bool wback;
8707    bool increment;
8708    bool wordhigher;
8709
8710    // EncodingSpecificOperations();
8711    switch (encoding) {
8712    case eEncodingT1:
8713      // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
8714      // FALSE;
8715      n = Bits32(opcode, 19, 16);
8716      wback = BitIsSet(opcode, 21);
8717      increment = false;
8718      wordhigher = false;
8719
8720      // if n == 15 then UNPREDICTABLE;
8721      if (n == 15)
8722        return false;
8723
8724      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8725      if (InITBlock() && !LastInITBlock())
8726        return false;
8727
8728      break;
8729
8730    case eEncodingT2:
8731      // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8732      n = Bits32(opcode, 19, 16);
8733      wback = BitIsSet(opcode, 21);
8734      increment = true;
8735      wordhigher = false;
8736
8737      // if n == 15 then UNPREDICTABLE;
8738      if (n == 15)
8739        return false;
8740
8741      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8742      if (InITBlock() && !LastInITBlock())
8743        return false;
8744
8745      break;
8746
8747    case eEncodingA1:
8748      // n = UInt(Rn);
8749      n = Bits32(opcode, 19, 16);
8750
8751      // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8752      wback = BitIsSet(opcode, 21);
8753      increment = BitIsSet(opcode, 23);
8754      wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
8755
8756      // if n == 15 then UNPREDICTABLE;
8757      if (n == 15)
8758        return false;
8759
8760      break;
8761
8762    default:
8763      return false;
8764    }
8765
8766    // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
8767    // then
8768    if (!CurrentModeIsPrivileged())
8769      // UNPREDICTABLE;
8770      return false;
8771    else {
8772      uint64_t Rn =
8773          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8774      if (!success)
8775        return false;
8776
8777      addr_t address;
8778      // address = if increment then R[n] else R[n]-8;
8779      if (increment)
8780        address = Rn;
8781      else
8782        address = Rn - 8;
8783
8784      // if wordhigher then address = address+4;
8785      if (wordhigher)
8786        address = address + 4;
8787
8788      // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8789      RegisterInfo base_reg;
8790      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8791
8792      EmulateInstruction::Context context;
8793      context.type = eContextReturnFromException;
8794      context.SetRegisterPlusOffset(base_reg, address - Rn);
8795
8796      uint64_t data = MemARead(context, address + 4, 4, 0, &success);
8797      if (!success)
8798        return false;
8799
8800      CPSRWriteByInstr(data, 15, true);
8801
8802      // BranchWritePC(MemA[address,4]);
8803      uint64_t data2 = MemARead(context, address, 4, 0, &success);
8804      if (!success)
8805        return false;
8806
8807      BranchWritePC(context, data2);
8808
8809      // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8810      if (wback) {
8811        context.type = eContextAdjustBaseRegister;
8812        if (increment) {
8813          context.SetOffset(8);
8814          if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8815                                     Rn + 8))
8816            return false;
8817        } else {
8818          context.SetOffset(-8);
8819          if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8820                                     Rn - 8))
8821            return false;
8822        }
8823      } // if wback
8824    }
8825  } // if ConditionPassed()
8826  return true;
8827}
8828
8829// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
8830// register value and an immediate value, and writes the result to the
8831// destination register.  It can optionally update the condition flags based on
8832// the result.
8833bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
8834                                          const ARMEncoding encoding) {
8835#if 0
8836    // ARM pseudo code...
8837    if ConditionPassed() then
8838        EncodingSpecificOperations();
8839        result = R[n] EOR imm32;
8840        if d == 15 then         // Can only occur for ARM encoding
8841            ALUWritePC(result); // setflags is always FALSE here
8842        else
8843            R[d] = result;
8844            if setflags then
8845                APSR.N = result<31>;
8846                APSR.Z = IsZeroBit(result);
8847                APSR.C = carry;
8848                // APSR.V unchanged
8849#endif
8850
8851  bool success = false;
8852
8853  if (ConditionPassed(opcode)) {
8854    uint32_t Rd, Rn;
8855    uint32_t
8856        imm32; // the immediate value to be ORed to the value obtained from Rn
8857    bool setflags;
8858    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8859    switch (encoding) {
8860    case eEncodingT1:
8861      Rd = Bits32(opcode, 11, 8);
8862      Rn = Bits32(opcode, 19, 16);
8863      setflags = BitIsSet(opcode, 20);
8864      imm32 = ThumbExpandImm_C(
8865          opcode, APSR_C,
8866          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8867      // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8868      if (Rd == 15 && setflags)
8869        return EmulateTEQImm(opcode, eEncodingT1);
8870      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8871        return false;
8872      break;
8873    case eEncodingA1:
8874      Rd = Bits32(opcode, 15, 12);
8875      Rn = Bits32(opcode, 19, 16);
8876      setflags = BitIsSet(opcode, 20);
8877      imm32 =
8878          ARMExpandImm_C(opcode, APSR_C,
8879                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8880
8881      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8882      // instructions;
8883      if (Rd == 15 && setflags)
8884        return EmulateSUBSPcLrEtc(opcode, encoding);
8885      break;
8886    default:
8887      return false;
8888    }
8889
8890    // Read the first operand.
8891    uint32_t val1 = ReadCoreReg(Rn, &success);
8892    if (!success)
8893      return false;
8894
8895    uint32_t result = val1 ^ imm32;
8896
8897    EmulateInstruction::Context context;
8898    context.type = EmulateInstruction::eContextImmediate;
8899    context.SetNoArgs();
8900
8901    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8902      return false;
8903  }
8904  return true;
8905}
8906
8907// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a
8908// register value and an optionally-shifted register value, and writes the
8909// result to the destination register. It can optionally update the condition
8910// flags based on the result.
8911bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
8912                                          const ARMEncoding encoding) {
8913#if 0
8914    // ARM pseudo code...
8915    if ConditionPassed() then
8916        EncodingSpecificOperations();
8917        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8918        result = R[n] EOR shifted;
8919        if d == 15 then         // Can only occur for ARM encoding
8920            ALUWritePC(result); // setflags is always FALSE here
8921        else
8922            R[d] = result;
8923            if setflags then
8924                APSR.N = result<31>;
8925                APSR.Z = IsZeroBit(result);
8926                APSR.C = carry;
8927                // APSR.V unchanged
8928#endif
8929
8930  bool success = false;
8931
8932  if (ConditionPassed(opcode)) {
8933    uint32_t Rd, Rn, Rm;
8934    ARM_ShifterType shift_t;
8935    uint32_t shift_n; // the shift applied to the value read from Rm
8936    bool setflags;
8937    uint32_t carry;
8938    switch (encoding) {
8939    case eEncodingT1:
8940      Rd = Rn = Bits32(opcode, 2, 0);
8941      Rm = Bits32(opcode, 5, 3);
8942      setflags = !InITBlock();
8943      shift_t = SRType_LSL;
8944      shift_n = 0;
8945      break;
8946    case eEncodingT2:
8947      Rd = Bits32(opcode, 11, 8);
8948      Rn = Bits32(opcode, 19, 16);
8949      Rm = Bits32(opcode, 3, 0);
8950      setflags = BitIsSet(opcode, 20);
8951      shift_n = DecodeImmShiftThumb(opcode, shift_t);
8952      // if Rd == '1111' && S == '1' then SEE TEQ (register);
8953      if (Rd == 15 && setflags)
8954        return EmulateTEQReg(opcode, eEncodingT1);
8955      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8956        return false;
8957      break;
8958    case eEncodingA1:
8959      Rd = Bits32(opcode, 15, 12);
8960      Rn = Bits32(opcode, 19, 16);
8961      Rm = Bits32(opcode, 3, 0);
8962      setflags = BitIsSet(opcode, 20);
8963      shift_n = DecodeImmShiftARM(opcode, shift_t);
8964
8965      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8966      // instructions;
8967      if (Rd == 15 && setflags)
8968        return EmulateSUBSPcLrEtc(opcode, encoding);
8969      break;
8970    default:
8971      return false;
8972    }
8973
8974    // Read the first operand.
8975    uint32_t val1 = ReadCoreReg(Rn, &success);
8976    if (!success)
8977      return false;
8978
8979    // Read the second operand.
8980    uint32_t val2 = ReadCoreReg(Rm, &success);
8981    if (!success)
8982      return false;
8983
8984    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8985    if (!success)
8986      return false;
8987    uint32_t result = val1 ^ shifted;
8988
8989    EmulateInstruction::Context context;
8990    context.type = EmulateInstruction::eContextImmediate;
8991    context.SetNoArgs();
8992
8993    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8994      return false;
8995  }
8996  return true;
8997}
8998
8999// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
9000// and an immediate value, and writes the result to the destination register.
9001// It can optionally update the condition flags based on the result.
9002bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
9003                                          const ARMEncoding encoding) {
9004#if 0
9005    // ARM pseudo code...
9006    if ConditionPassed() then
9007        EncodingSpecificOperations();
9008        result = R[n] OR imm32;
9009        if d == 15 then         // Can only occur for ARM encoding
9010            ALUWritePC(result); // setflags is always FALSE here
9011        else
9012            R[d] = result;
9013            if setflags then
9014                APSR.N = result<31>;
9015                APSR.Z = IsZeroBit(result);
9016                APSR.C = carry;
9017                // APSR.V unchanged
9018#endif
9019
9020  bool success = false;
9021
9022  if (ConditionPassed(opcode)) {
9023    uint32_t Rd, Rn;
9024    uint32_t
9025        imm32; // the immediate value to be ORed to the value obtained from Rn
9026    bool setflags;
9027    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9028    switch (encoding) {
9029    case eEncodingT1:
9030      Rd = Bits32(opcode, 11, 8);
9031      Rn = Bits32(opcode, 19, 16);
9032      setflags = BitIsSet(opcode, 20);
9033      imm32 = ThumbExpandImm_C(
9034          opcode, APSR_C,
9035          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9036      // if Rn == '1111' then SEE MOV (immediate);
9037      if (Rn == 15)
9038        return EmulateMOVRdImm(opcode, eEncodingT2);
9039      if (BadReg(Rd) || Rn == 13)
9040        return false;
9041      break;
9042    case eEncodingA1:
9043      Rd = Bits32(opcode, 15, 12);
9044      Rn = Bits32(opcode, 19, 16);
9045      setflags = BitIsSet(opcode, 20);
9046      imm32 =
9047          ARMExpandImm_C(opcode, APSR_C,
9048                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9049
9050      if (Rd == 15 && setflags)
9051        return EmulateSUBSPcLrEtc(opcode, encoding);
9052      break;
9053    default:
9054      return false;
9055    }
9056
9057    // Read the first operand.
9058    uint32_t val1 = ReadCoreReg(Rn, &success);
9059    if (!success)
9060      return false;
9061
9062    uint32_t result = val1 | imm32;
9063
9064    EmulateInstruction::Context context;
9065    context.type = EmulateInstruction::eContextImmediate;
9066    context.SetNoArgs();
9067
9068    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9069      return false;
9070  }
9071  return true;
9072}
9073
9074// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
9075// and an optionally-shifted register value, and writes the result to the
9076// destination register.  It can optionally update the condition flags based on
9077// the result.
9078bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
9079                                          const ARMEncoding encoding) {
9080#if 0
9081    // ARM pseudo code...
9082    if ConditionPassed() then
9083        EncodingSpecificOperations();
9084        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9085        result = R[n] OR shifted;
9086        if d == 15 then         // Can only occur for ARM encoding
9087            ALUWritePC(result); // setflags is always FALSE here
9088        else
9089            R[d] = result;
9090            if setflags then
9091                APSR.N = result<31>;
9092                APSR.Z = IsZeroBit(result);
9093                APSR.C = carry;
9094                // APSR.V unchanged
9095#endif
9096
9097  bool success = false;
9098
9099  if (ConditionPassed(opcode)) {
9100    uint32_t Rd, Rn, Rm;
9101    ARM_ShifterType shift_t;
9102    uint32_t shift_n; // the shift applied to the value read from Rm
9103    bool setflags;
9104    uint32_t carry;
9105    switch (encoding) {
9106    case eEncodingT1:
9107      Rd = Rn = Bits32(opcode, 2, 0);
9108      Rm = Bits32(opcode, 5, 3);
9109      setflags = !InITBlock();
9110      shift_t = SRType_LSL;
9111      shift_n = 0;
9112      break;
9113    case eEncodingT2:
9114      Rd = Bits32(opcode, 11, 8);
9115      Rn = Bits32(opcode, 19, 16);
9116      Rm = Bits32(opcode, 3, 0);
9117      setflags = BitIsSet(opcode, 20);
9118      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9119      // if Rn == '1111' then SEE MOV (register);
9120      if (Rn == 15)
9121        return EmulateMOVRdRm(opcode, eEncodingT3);
9122      if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
9123        return false;
9124      break;
9125    case eEncodingA1:
9126      Rd = Bits32(opcode, 15, 12);
9127      Rn = Bits32(opcode, 19, 16);
9128      Rm = Bits32(opcode, 3, 0);
9129      setflags = BitIsSet(opcode, 20);
9130      shift_n = DecodeImmShiftARM(opcode, shift_t);
9131
9132      if (Rd == 15 && setflags)
9133        return EmulateSUBSPcLrEtc(opcode, encoding);
9134      break;
9135    default:
9136      return false;
9137    }
9138
9139    // Read the first operand.
9140    uint32_t val1 = ReadCoreReg(Rn, &success);
9141    if (!success)
9142      return false;
9143
9144    // Read the second operand.
9145    uint32_t val2 = ReadCoreReg(Rm, &success);
9146    if (!success)
9147      return false;
9148
9149    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9150    if (!success)
9151      return false;
9152    uint32_t result = val1 | shifted;
9153
9154    EmulateInstruction::Context context;
9155    context.type = EmulateInstruction::eContextImmediate;
9156    context.SetNoArgs();
9157
9158    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9159      return false;
9160  }
9161  return true;
9162}
9163
9164// Reverse Subtract (immediate) subtracts a register value from an immediate
9165// value, and writes the result to the destination register. It can optionally
9166// update the condition flags based on the result.
9167bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
9168                                          const ARMEncoding encoding) {
9169#if 0
9170    // ARM pseudo code...
9171    if ConditionPassed() then
9172        EncodingSpecificOperations();
9173        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
9174        if d == 15 then         // Can only occur for ARM encoding
9175            ALUWritePC(result); // setflags is always FALSE here
9176        else
9177            R[d] = result;
9178            if setflags then
9179                APSR.N = result<31>;
9180                APSR.Z = IsZeroBit(result);
9181                APSR.C = carry;
9182                APSR.V = overflow;
9183#endif
9184
9185  bool success = false;
9186
9187  uint32_t Rd; // the destination register
9188  uint32_t Rn; // the first operand
9189  bool setflags;
9190  uint32_t
9191      imm32; // the immediate value to be added to the value obtained from Rn
9192  switch (encoding) {
9193  case eEncodingT1:
9194    Rd = Bits32(opcode, 2, 0);
9195    Rn = Bits32(opcode, 5, 3);
9196    setflags = !InITBlock();
9197    imm32 = 0;
9198    break;
9199  case eEncodingT2:
9200    Rd = Bits32(opcode, 11, 8);
9201    Rn = Bits32(opcode, 19, 16);
9202    setflags = BitIsSet(opcode, 20);
9203    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9204    if (BadReg(Rd) || BadReg(Rn))
9205      return false;
9206    break;
9207  case eEncodingA1:
9208    Rd = Bits32(opcode, 15, 12);
9209    Rn = Bits32(opcode, 19, 16);
9210    setflags = BitIsSet(opcode, 20);
9211    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9212
9213    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9214    // instructions;
9215    if (Rd == 15 && setflags)
9216      return EmulateSUBSPcLrEtc(opcode, encoding);
9217    break;
9218  default:
9219    return false;
9220  }
9221  // Read the register value from the operand register Rn.
9222  uint32_t reg_val = ReadCoreReg(Rn, &success);
9223  if (!success)
9224    return false;
9225
9226  AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
9227
9228  EmulateInstruction::Context context;
9229  context.type = EmulateInstruction::eContextImmediate;
9230  context.SetNoArgs();
9231
9232  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9233                                   res.carry_out, res.overflow);
9234}
9235
9236// Reverse Subtract (register) subtracts a register value from an optionally-
9237// shifted register value, and writes the result to the destination register.
9238// It can optionally update the condition flags based on the result.
9239bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
9240                                          const ARMEncoding encoding) {
9241#if 0
9242    // ARM pseudo code...
9243    if ConditionPassed() then
9244        EncodingSpecificOperations();
9245        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9246        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
9247        if d == 15 then         // Can only occur for ARM encoding
9248            ALUWritePC(result); // setflags is always FALSE here
9249        else
9250            R[d] = result;
9251            if setflags then
9252                APSR.N = result<31>;
9253                APSR.Z = IsZeroBit(result);
9254                APSR.C = carry;
9255                APSR.V = overflow;
9256#endif
9257
9258  bool success = false;
9259
9260  uint32_t Rd; // the destination register
9261  uint32_t Rn; // the first operand
9262  uint32_t Rm; // the second operand
9263  bool setflags;
9264  ARM_ShifterType shift_t;
9265  uint32_t shift_n; // the shift applied to the value read from Rm
9266  switch (encoding) {
9267  case eEncodingT1:
9268    Rd = Bits32(opcode, 11, 8);
9269    Rn = Bits32(opcode, 19, 16);
9270    Rm = Bits32(opcode, 3, 0);
9271    setflags = BitIsSet(opcode, 20);
9272    shift_n = DecodeImmShiftThumb(opcode, shift_t);
9273    // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
9274    if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9275      return false;
9276    break;
9277  case eEncodingA1:
9278    Rd = Bits32(opcode, 15, 12);
9279    Rn = Bits32(opcode, 19, 16);
9280    Rm = Bits32(opcode, 3, 0);
9281    setflags = BitIsSet(opcode, 20);
9282    shift_n = DecodeImmShiftARM(opcode, shift_t);
9283
9284    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9285    // instructions;
9286    if (Rd == 15 && setflags)
9287      return EmulateSUBSPcLrEtc(opcode, encoding);
9288    break;
9289  default:
9290    return false;
9291  }
9292  // Read the register value from register Rn.
9293  uint32_t val1 = ReadCoreReg(Rn, &success);
9294  if (!success)
9295    return false;
9296
9297  // Read the register value from register Rm.
9298  uint32_t val2 = ReadCoreReg(Rm, &success);
9299  if (!success)
9300    return false;
9301
9302  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9303  if (!success)
9304    return false;
9305  AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
9306
9307  EmulateInstruction::Context context;
9308  context.type = EmulateInstruction::eContextImmediate;
9309  context.SetNoArgs();
9310  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9311                                   res.carry_out, res.overflow);
9312}
9313
9314// Reverse Subtract with Carry (immediate) subtracts a register value and the
9315// value of NOT (Carry flag) from an immediate value, and writes the result to
9316// the destination register. It can optionally update the condition flags based
9317// on the result.
9318bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
9319                                          const ARMEncoding encoding) {
9320#if 0
9321    // ARM pseudo code...
9322    if ConditionPassed() then
9323        EncodingSpecificOperations();
9324        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
9325        if d == 15 then
9326            ALUWritePC(result); // setflags is always FALSE here
9327        else
9328            R[d] = result;
9329            if setflags then
9330                APSR.N = result<31>;
9331                APSR.Z = IsZeroBit(result);
9332                APSR.C = carry;
9333                APSR.V = overflow;
9334#endif
9335
9336  bool success = false;
9337
9338  uint32_t Rd; // the destination register
9339  uint32_t Rn; // the first operand
9340  bool setflags;
9341  uint32_t
9342      imm32; // the immediate value to be added to the value obtained from Rn
9343  switch (encoding) {
9344  case eEncodingA1:
9345    Rd = Bits32(opcode, 15, 12);
9346    Rn = Bits32(opcode, 19, 16);
9347    setflags = BitIsSet(opcode, 20);
9348    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9349
9350    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9351    // instructions;
9352    if (Rd == 15 && setflags)
9353      return EmulateSUBSPcLrEtc(opcode, encoding);
9354    break;
9355  default:
9356    return false;
9357  }
9358  // Read the register value from the operand register Rn.
9359  uint32_t reg_val = ReadCoreReg(Rn, &success);
9360  if (!success)
9361    return false;
9362
9363  AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
9364
9365  EmulateInstruction::Context context;
9366  context.type = EmulateInstruction::eContextImmediate;
9367  context.SetNoArgs();
9368
9369  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9370                                   res.carry_out, res.overflow);
9371}
9372
9373// Reverse Subtract with Carry (register) subtracts a register value and the
9374// value of NOT (Carry flag) from an optionally-shifted register value, and
9375// writes the result to the destination register. It can optionally update the
9376// condition flags based on the result.
9377bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
9378                                          const ARMEncoding encoding) {
9379#if 0
9380    // ARM pseudo code...
9381    if ConditionPassed() then
9382        EncodingSpecificOperations();
9383        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9384        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
9385        if d == 15 then
9386            ALUWritePC(result); // setflags is always FALSE here
9387        else
9388            R[d] = result;
9389            if setflags then
9390                APSR.N = result<31>;
9391                APSR.Z = IsZeroBit(result);
9392                APSR.C = carry;
9393                APSR.V = overflow;
9394#endif
9395
9396  bool success = false;
9397
9398  uint32_t Rd; // the destination register
9399  uint32_t Rn; // the first operand
9400  uint32_t Rm; // the second operand
9401  bool setflags;
9402  ARM_ShifterType shift_t;
9403  uint32_t shift_n; // the shift applied to the value read from Rm
9404  switch (encoding) {
9405  case eEncodingA1:
9406    Rd = Bits32(opcode, 15, 12);
9407    Rn = Bits32(opcode, 19, 16);
9408    Rm = Bits32(opcode, 3, 0);
9409    setflags = BitIsSet(opcode, 20);
9410    shift_n = DecodeImmShiftARM(opcode, shift_t);
9411
9412    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9413    // instructions;
9414    if (Rd == 15 && setflags)
9415      return EmulateSUBSPcLrEtc(opcode, encoding);
9416    break;
9417  default:
9418    return false;
9419  }
9420  // Read the register value from register Rn.
9421  uint32_t val1 = ReadCoreReg(Rn, &success);
9422  if (!success)
9423    return false;
9424
9425  // Read the register value from register Rm.
9426  uint32_t val2 = ReadCoreReg(Rm, &success);
9427  if (!success)
9428    return false;
9429
9430  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9431  if (!success)
9432    return false;
9433  AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
9434
9435  EmulateInstruction::Context context;
9436  context.type = EmulateInstruction::eContextImmediate;
9437  context.SetNoArgs();
9438  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9439                                   res.carry_out, res.overflow);
9440}
9441
9442// Subtract with Carry (immediate) subtracts an immediate value and the value
9443// of
9444// NOT (Carry flag) from a register value, and writes the result to the
9445// destination register.
9446// It can optionally update the condition flags based on the result.
9447bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
9448                                          const ARMEncoding encoding) {
9449#if 0
9450    // ARM pseudo code...
9451    if ConditionPassed() then
9452        EncodingSpecificOperations();
9453        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
9454        if d == 15 then         // Can only occur for ARM encoding
9455            ALUWritePC(result); // setflags is always FALSE here
9456        else
9457            R[d] = result;
9458            if setflags then
9459                APSR.N = result<31>;
9460                APSR.Z = IsZeroBit(result);
9461                APSR.C = carry;
9462                APSR.V = overflow;
9463#endif
9464
9465  bool success = false;
9466
9467  uint32_t Rd; // the destination register
9468  uint32_t Rn; // the first operand
9469  bool setflags;
9470  uint32_t
9471      imm32; // the immediate value to be added to the value obtained from Rn
9472  switch (encoding) {
9473  case eEncodingT1:
9474    Rd = Bits32(opcode, 11, 8);
9475    Rn = Bits32(opcode, 19, 16);
9476    setflags = BitIsSet(opcode, 20);
9477    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9478    if (BadReg(Rd) || BadReg(Rn))
9479      return false;
9480    break;
9481  case eEncodingA1:
9482    Rd = Bits32(opcode, 15, 12);
9483    Rn = Bits32(opcode, 19, 16);
9484    setflags = BitIsSet(opcode, 20);
9485    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9486
9487    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9488    // instructions;
9489    if (Rd == 15 && setflags)
9490      return EmulateSUBSPcLrEtc(opcode, encoding);
9491    break;
9492  default:
9493    return false;
9494  }
9495  // Read the register value from the operand register Rn.
9496  uint32_t reg_val = ReadCoreReg(Rn, &success);
9497  if (!success)
9498    return false;
9499
9500  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9501
9502  EmulateInstruction::Context context;
9503  context.type = EmulateInstruction::eContextImmediate;
9504  context.SetNoArgs();
9505
9506  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9507                                   res.carry_out, res.overflow);
9508}
9509
9510// Subtract with Carry (register) subtracts an optionally-shifted register
9511// value and the value of
9512// NOT (Carry flag) from a register value, and writes the result to the
9513// destination register.
9514// It can optionally update the condition flags based on the result.
9515bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
9516                                          const ARMEncoding encoding) {
9517#if 0
9518    // ARM pseudo code...
9519    if ConditionPassed() then
9520        EncodingSpecificOperations();
9521        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9522        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9523        if d == 15 then         // Can only occur for ARM encoding
9524            ALUWritePC(result); // setflags is always FALSE here
9525        else
9526            R[d] = result;
9527            if setflags then
9528                APSR.N = result<31>;
9529                APSR.Z = IsZeroBit(result);
9530                APSR.C = carry;
9531                APSR.V = overflow;
9532#endif
9533
9534  bool success = false;
9535
9536  uint32_t Rd; // the destination register
9537  uint32_t Rn; // the first operand
9538  uint32_t Rm; // the second operand
9539  bool setflags;
9540  ARM_ShifterType shift_t;
9541  uint32_t shift_n; // the shift applied to the value read from Rm
9542  switch (encoding) {
9543  case eEncodingT1:
9544    Rd = Rn = Bits32(opcode, 2, 0);
9545    Rm = Bits32(opcode, 5, 3);
9546    setflags = !InITBlock();
9547    shift_t = SRType_LSL;
9548    shift_n = 0;
9549    break;
9550  case eEncodingT2:
9551    Rd = Bits32(opcode, 11, 8);
9552    Rn = Bits32(opcode, 19, 16);
9553    Rm = Bits32(opcode, 3, 0);
9554    setflags = BitIsSet(opcode, 20);
9555    shift_n = DecodeImmShiftThumb(opcode, shift_t);
9556    if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9557      return false;
9558    break;
9559  case eEncodingA1:
9560    Rd = Bits32(opcode, 15, 12);
9561    Rn = Bits32(opcode, 19, 16);
9562    Rm = Bits32(opcode, 3, 0);
9563    setflags = BitIsSet(opcode, 20);
9564    shift_n = DecodeImmShiftARM(opcode, shift_t);
9565
9566    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9567    // instructions;
9568    if (Rd == 15 && setflags)
9569      return EmulateSUBSPcLrEtc(opcode, encoding);
9570    break;
9571  default:
9572    return false;
9573  }
9574  // Read the register value from register Rn.
9575  uint32_t val1 = ReadCoreReg(Rn, &success);
9576  if (!success)
9577    return false;
9578
9579  // Read the register value from register Rm.
9580  uint32_t val2 = ReadCoreReg(Rm, &success);
9581  if (!success)
9582    return false;
9583
9584  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9585  if (!success)
9586    return false;
9587  AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9588
9589  EmulateInstruction::Context context;
9590  context.type = EmulateInstruction::eContextImmediate;
9591  context.SetNoArgs();
9592  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9593                                   res.carry_out, res.overflow);
9594}
9595
9596// This instruction subtracts an immediate value from a register value, and
9597// writes the result to the destination register.  It can optionally update the
9598// condition flags based on the result.
9599bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
9600                                               const ARMEncoding encoding) {
9601#if 0
9602    // ARM pseudo code...
9603    if ConditionPassed() then
9604        EncodingSpecificOperations();
9605        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9606        R[d] = result;
9607        if setflags then
9608            APSR.N = result<31>;
9609            APSR.Z = IsZeroBit(result);
9610            APSR.C = carry;
9611            APSR.V = overflow;
9612#endif
9613
9614  bool success = false;
9615
9616  uint32_t Rd; // the destination register
9617  uint32_t Rn; // the first operand
9618  bool setflags;
9619  uint32_t imm32; // the immediate value to be subtracted from the value
9620                  // obtained from Rn
9621  switch (encoding) {
9622  case eEncodingT1:
9623    Rd = Bits32(opcode, 2, 0);
9624    Rn = Bits32(opcode, 5, 3);
9625    setflags = !InITBlock();
9626    imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9627    break;
9628  case eEncodingT2:
9629    Rd = Rn = Bits32(opcode, 10, 8);
9630    setflags = !InITBlock();
9631    imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9632    break;
9633  case eEncodingT3:
9634    Rd = Bits32(opcode, 11, 8);
9635    Rn = Bits32(opcode, 19, 16);
9636    setflags = BitIsSet(opcode, 20);
9637    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9638
9639    // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9640    if (Rd == 15 && setflags)
9641      return EmulateCMPImm(opcode, eEncodingT2);
9642
9643    // if Rn == '1101' then SEE SUB (SP minus immediate);
9644    if (Rn == 13)
9645      return EmulateSUBSPImm(opcode, eEncodingT2);
9646
9647    // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9648    if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9649      return false;
9650    break;
9651  case eEncodingT4:
9652    Rd = Bits32(opcode, 11, 8);
9653    Rn = Bits32(opcode, 19, 16);
9654    setflags = BitIsSet(opcode, 20);
9655    imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9656
9657    // if Rn == '1111' then SEE ADR;
9658    if (Rn == 15)
9659      return EmulateADR(opcode, eEncodingT2);
9660
9661    // if Rn == '1101' then SEE SUB (SP minus immediate);
9662    if (Rn == 13)
9663      return EmulateSUBSPImm(opcode, eEncodingT3);
9664
9665    if (BadReg(Rd))
9666      return false;
9667    break;
9668  default:
9669    return false;
9670  }
9671  // Read the register value from the operand register Rn.
9672  uint32_t reg_val = ReadCoreReg(Rn, &success);
9673  if (!success)
9674    return false;
9675
9676  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9677
9678  EmulateInstruction::Context context;
9679  context.type = EmulateInstruction::eContextImmediate;
9680  context.SetNoArgs();
9681
9682  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9683                                   res.carry_out, res.overflow);
9684}
9685
9686// This instruction subtracts an immediate value from a register value, and
9687// writes the result to the destination register.  It can optionally update the
9688// condition flags based on the result.
9689bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
9690                                             const ARMEncoding encoding) {
9691#if 0
9692    // ARM pseudo code...
9693    if ConditionPassed() then
9694        EncodingSpecificOperations();
9695        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9696        if d == 15 then
9697            ALUWritePC(result); // setflags is always FALSE here
9698        else
9699            R[d] = result;
9700            if setflags then
9701                APSR.N = result<31>;
9702                APSR.Z = IsZeroBit(result);
9703                APSR.C = carry;
9704                APSR.V = overflow;
9705#endif
9706
9707  bool success = false;
9708
9709  if (ConditionPassed(opcode)) {
9710    uint32_t Rd; // the destination register
9711    uint32_t Rn; // the first operand
9712    bool setflags;
9713    uint32_t imm32; // the immediate value to be subtracted from the value
9714                    // obtained from Rn
9715    switch (encoding) {
9716    case eEncodingA1:
9717      Rd = Bits32(opcode, 15, 12);
9718      Rn = Bits32(opcode, 19, 16);
9719      setflags = BitIsSet(opcode, 20);
9720      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9721
9722      // if Rn == '1111' && S == '0' then SEE ADR;
9723      if (Rn == 15 && !setflags)
9724        return EmulateADR(opcode, eEncodingA2);
9725
9726      // if Rn == '1101' then SEE SUB (SP minus immediate);
9727      if (Rn == 13)
9728        return EmulateSUBSPImm(opcode, eEncodingA1);
9729
9730      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9731      // instructions;
9732      if (Rd == 15 && setflags)
9733        return EmulateSUBSPcLrEtc(opcode, encoding);
9734      break;
9735    default:
9736      return false;
9737    }
9738    // Read the register value from the operand register Rn.
9739    uint32_t reg_val = ReadCoreReg(Rn, &success);
9740    if (!success)
9741      return false;
9742
9743    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9744
9745    EmulateInstruction::Context context;
9746    if (Rd == 13)
9747      context.type = EmulateInstruction::eContextAdjustStackPointer;
9748    else
9749      context.type = EmulateInstruction::eContextRegisterPlusOffset;
9750
9751    RegisterInfo dwarf_reg;
9752    GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
9753    int64_t imm32_signed = imm32;
9754    context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed);
9755
9756    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9757                                   res.carry_out, res.overflow))
9758      return false;
9759  }
9760  return true;
9761}
9762
9763// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
9764// register value and an immediate value.  It updates the condition flags based
9765// on the result, and discards the result.
9766bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
9767                                          const ARMEncoding encoding) {
9768#if 0
9769    // ARM pseudo code...
9770    if ConditionPassed() then
9771        EncodingSpecificOperations();
9772        result = R[n] EOR imm32;
9773        APSR.N = result<31>;
9774        APSR.Z = IsZeroBit(result);
9775        APSR.C = carry;
9776        // APSR.V unchanged
9777#endif
9778
9779  bool success = false;
9780
9781  if (ConditionPassed(opcode)) {
9782    uint32_t Rn;
9783    uint32_t
9784        imm32; // the immediate value to be ANDed to the value obtained from Rn
9785    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9786    switch (encoding) {
9787    case eEncodingT1:
9788      Rn = Bits32(opcode, 19, 16);
9789      imm32 = ThumbExpandImm_C(
9790          opcode, APSR_C,
9791          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9792      if (BadReg(Rn))
9793        return false;
9794      break;
9795    case eEncodingA1:
9796      Rn = Bits32(opcode, 19, 16);
9797      imm32 =
9798          ARMExpandImm_C(opcode, APSR_C,
9799                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9800      break;
9801    default:
9802      return false;
9803    }
9804
9805    // Read the first operand.
9806    uint32_t val1 = ReadCoreReg(Rn, &success);
9807    if (!success)
9808      return false;
9809
9810    uint32_t result = val1 ^ imm32;
9811
9812    EmulateInstruction::Context context;
9813    context.type = EmulateInstruction::eContextImmediate;
9814    context.SetNoArgs();
9815
9816    if (!WriteFlags(context, result, carry))
9817      return false;
9818  }
9819  return true;
9820}
9821
9822// Test Equivalence (register) performs a bitwise exclusive OR operation on a
9823// register value and an optionally-shifted register value.  It updates the
9824// condition flags based on the result, and discards the result.
9825bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
9826                                          const ARMEncoding encoding) {
9827#if 0
9828    // ARM pseudo code...
9829    if ConditionPassed() then
9830        EncodingSpecificOperations();
9831        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9832        result = R[n] EOR shifted;
9833        APSR.N = result<31>;
9834        APSR.Z = IsZeroBit(result);
9835        APSR.C = carry;
9836        // APSR.V unchanged
9837#endif
9838
9839  bool success = false;
9840
9841  if (ConditionPassed(opcode)) {
9842    uint32_t Rn, Rm;
9843    ARM_ShifterType shift_t;
9844    uint32_t shift_n; // the shift applied to the value read from Rm
9845    uint32_t carry;
9846    switch (encoding) {
9847    case eEncodingT1:
9848      Rn = Bits32(opcode, 19, 16);
9849      Rm = Bits32(opcode, 3, 0);
9850      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9851      if (BadReg(Rn) || BadReg(Rm))
9852        return false;
9853      break;
9854    case eEncodingA1:
9855      Rn = Bits32(opcode, 19, 16);
9856      Rm = Bits32(opcode, 3, 0);
9857      shift_n = DecodeImmShiftARM(opcode, shift_t);
9858      break;
9859    default:
9860      return false;
9861    }
9862
9863    // Read the first operand.
9864    uint32_t val1 = ReadCoreReg(Rn, &success);
9865    if (!success)
9866      return false;
9867
9868    // Read the second operand.
9869    uint32_t val2 = ReadCoreReg(Rm, &success);
9870    if (!success)
9871      return false;
9872
9873    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9874    if (!success)
9875      return false;
9876    uint32_t result = val1 ^ shifted;
9877
9878    EmulateInstruction::Context context;
9879    context.type = EmulateInstruction::eContextImmediate;
9880    context.SetNoArgs();
9881
9882    if (!WriteFlags(context, result, carry))
9883      return false;
9884  }
9885  return true;
9886}
9887
9888// Test (immediate) performs a bitwise AND operation on a register value and an
9889// immediate value. It updates the condition flags based on the result, and
9890// discards the result.
9891bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
9892                                          const ARMEncoding encoding) {
9893#if 0
9894    // ARM pseudo code...
9895    if ConditionPassed() then
9896        EncodingSpecificOperations();
9897        result = R[n] AND imm32;
9898        APSR.N = result<31>;
9899        APSR.Z = IsZeroBit(result);
9900        APSR.C = carry;
9901        // APSR.V unchanged
9902#endif
9903
9904  bool success = false;
9905
9906  if (ConditionPassed(opcode)) {
9907    uint32_t Rn;
9908    uint32_t
9909        imm32; // the immediate value to be ANDed to the value obtained from Rn
9910    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9911    switch (encoding) {
9912    case eEncodingT1:
9913      Rn = Bits32(opcode, 19, 16);
9914      imm32 = ThumbExpandImm_C(
9915          opcode, APSR_C,
9916          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9917      if (BadReg(Rn))
9918        return false;
9919      break;
9920    case eEncodingA1:
9921      Rn = Bits32(opcode, 19, 16);
9922      imm32 =
9923          ARMExpandImm_C(opcode, APSR_C,
9924                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9925      break;
9926    default:
9927      return false;
9928    }
9929
9930    // Read the first operand.
9931    uint32_t val1 = ReadCoreReg(Rn, &success);
9932    if (!success)
9933      return false;
9934
9935    uint32_t result = val1 & imm32;
9936
9937    EmulateInstruction::Context context;
9938    context.type = EmulateInstruction::eContextImmediate;
9939    context.SetNoArgs();
9940
9941    if (!WriteFlags(context, result, carry))
9942      return false;
9943  }
9944  return true;
9945}
9946
9947// Test (register) performs a bitwise AND operation on a register value and an
9948// optionally-shifted register value. It updates the condition flags based on
9949// the result, and discards the result.
9950bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
9951                                          const ARMEncoding encoding) {
9952#if 0
9953    // ARM pseudo code...
9954    if ConditionPassed() then
9955        EncodingSpecificOperations();
9956        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9957        result = R[n] AND shifted;
9958        APSR.N = result<31>;
9959        APSR.Z = IsZeroBit(result);
9960        APSR.C = carry;
9961        // APSR.V unchanged
9962#endif
9963
9964  bool success = false;
9965
9966  if (ConditionPassed(opcode)) {
9967    uint32_t Rn, Rm;
9968    ARM_ShifterType shift_t;
9969    uint32_t shift_n; // the shift applied to the value read from Rm
9970    uint32_t carry;
9971    switch (encoding) {
9972    case eEncodingT1:
9973      Rn = Bits32(opcode, 2, 0);
9974      Rm = Bits32(opcode, 5, 3);
9975      shift_t = SRType_LSL;
9976      shift_n = 0;
9977      break;
9978    case eEncodingT2:
9979      Rn = Bits32(opcode, 19, 16);
9980      Rm = Bits32(opcode, 3, 0);
9981      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9982      if (BadReg(Rn) || BadReg(Rm))
9983        return false;
9984      break;
9985    case eEncodingA1:
9986      Rn = Bits32(opcode, 19, 16);
9987      Rm = Bits32(opcode, 3, 0);
9988      shift_n = DecodeImmShiftARM(opcode, shift_t);
9989      break;
9990    default:
9991      return false;
9992    }
9993
9994    // Read the first operand.
9995    uint32_t val1 = ReadCoreReg(Rn, &success);
9996    if (!success)
9997      return false;
9998
9999    // Read the second operand.
10000    uint32_t val2 = ReadCoreReg(Rm, &success);
10001    if (!success)
10002      return false;
10003
10004    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
10005    if (!success)
10006      return false;
10007    uint32_t result = val1 & shifted;
10008
10009    EmulateInstruction::Context context;
10010    context.type = EmulateInstruction::eContextImmediate;
10011    context.SetNoArgs();
10012
10013    if (!WriteFlags(context, result, carry))
10014      return false;
10015  }
10016  return true;
10017}
10018
10019// A8.6.216 SUB (SP minus register)
10020bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
10021                                            const ARMEncoding encoding) {
10022#if 0
10023    if ConditionPassed() then
10024        EncodingSpecificOperations();
10025        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10026        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10027        if d == 15 then // Can only occur for ARM encoding
10028            ALUWritePC(result); // setflags is always FALSE here
10029        else
10030            R[d] = result;
10031            if setflags then
10032                APSR.N = result<31>;
10033                APSR.Z = IsZeroBit(result);
10034                APSR.C = carry;
10035                APSR.V = overflow;
10036#endif
10037
10038  bool success = false;
10039
10040  if (ConditionPassed(opcode)) {
10041    uint32_t d;
10042    uint32_t m;
10043    bool setflags;
10044    ARM_ShifterType shift_t;
10045    uint32_t shift_n;
10046
10047    switch (encoding) {
10048    case eEncodingT1:
10049      // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10050      d = Bits32(opcode, 11, 8);
10051      m = Bits32(opcode, 3, 0);
10052      setflags = BitIsSet(opcode, 20);
10053
10054      // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10055      shift_n = DecodeImmShiftThumb(opcode, shift_t);
10056
10057      // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
10058      // UNPREDICTABLE;
10059      if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
10060        return false;
10061
10062      // if d == 15 || BadReg(m) then UNPREDICTABLE;
10063      if ((d == 15) || BadReg(m))
10064        return false;
10065      break;
10066
10067    case eEncodingA1:
10068      // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10069      d = Bits32(opcode, 15, 12);
10070      m = Bits32(opcode, 3, 0);
10071      setflags = BitIsSet(opcode, 20);
10072
10073      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10074      // instructions;
10075      if (d == 15 && setflags)
10076        EmulateSUBSPcLrEtc(opcode, encoding);
10077
10078      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10079      shift_n = DecodeImmShiftARM(opcode, shift_t);
10080      break;
10081
10082    default:
10083      return false;
10084    }
10085
10086    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10087    uint32_t Rm = ReadCoreReg(m, &success);
10088    if (!success)
10089      return false;
10090
10091    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10092    if (!success)
10093      return false;
10094
10095    // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10096    uint32_t sp_val = ReadCoreReg(SP_REG, &success);
10097    if (!success)
10098      return false;
10099
10100    AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
10101
10102    EmulateInstruction::Context context;
10103    context.type = eContextArithmetic;
10104    RegisterInfo sp_reg;
10105    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
10106    RegisterInfo dwarf_reg;
10107    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
10108    context.SetRegisterRegisterOperands(sp_reg, dwarf_reg);
10109
10110    if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10111                                   res.carry_out, res.overflow))
10112      return false;
10113  }
10114  return true;
10115}
10116
10117// A8.6.7 ADD (register-shifted register)
10118bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
10119                                               const ARMEncoding encoding) {
10120#if 0
10121    if ConditionPassed() then
10122        EncodingSpecificOperations();
10123        shift_n = UInt(R[s]<7:0>);
10124        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10125        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10126        R[d] = result;
10127        if setflags then
10128            APSR.N = result<31>;
10129            APSR.Z = IsZeroBit(result);
10130            APSR.C = carry;
10131            APSR.V = overflow;
10132#endif
10133
10134  bool success = false;
10135
10136  if (ConditionPassed(opcode)) {
10137    uint32_t d;
10138    uint32_t n;
10139    uint32_t m;
10140    uint32_t s;
10141    bool setflags;
10142    ARM_ShifterType shift_t;
10143
10144    switch (encoding) {
10145    case eEncodingA1:
10146      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
10147      d = Bits32(opcode, 15, 12);
10148      n = Bits32(opcode, 19, 16);
10149      m = Bits32(opcode, 3, 0);
10150      s = Bits32(opcode, 11, 8);
10151
10152      // setflags = (S == '1'); shift_t = DecodeRegShift(type);
10153      setflags = BitIsSet(opcode, 20);
10154      shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
10155
10156      // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
10157      if ((d == 15) || (n == 15) || (m == 15) || (s == 15))
10158        return false;
10159      break;
10160
10161    default:
10162      return false;
10163    }
10164
10165    // shift_n = UInt(R[s]<7:0>);
10166    uint32_t Rs = ReadCoreReg(s, &success);
10167    if (!success)
10168      return false;
10169
10170    uint32_t shift_n = Bits32(Rs, 7, 0);
10171
10172    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10173    uint32_t Rm = ReadCoreReg(m, &success);
10174    if (!success)
10175      return false;
10176
10177    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10178    if (!success)
10179      return false;
10180
10181    // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10182    uint32_t Rn = ReadCoreReg(n, &success);
10183    if (!success)
10184      return false;
10185
10186    AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
10187
10188    // R[d] = result;
10189    EmulateInstruction::Context context;
10190    context.type = eContextArithmetic;
10191    RegisterInfo reg_n;
10192    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10193    RegisterInfo reg_m;
10194    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10195
10196    context.SetRegisterRegisterOperands(reg_n, reg_m);
10197
10198    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
10199                               res.result))
10200      return false;
10201
10202    // if setflags then
10203    // APSR.N = result<31>;
10204    // APSR.Z = IsZeroBit(result);
10205    // APSR.C = carry;
10206    // APSR.V = overflow;
10207    if (setflags)
10208      return WriteFlags(context, res.result, res.carry_out, res.overflow);
10209  }
10210  return true;
10211}
10212
10213// A8.6.213 SUB (register)
10214bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
10215                                          const ARMEncoding encoding) {
10216#if 0
10217    if ConditionPassed() then
10218        EncodingSpecificOperations();
10219        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10220        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10221        if d == 15 then // Can only occur for ARM encoding
10222            ALUWritePC(result); // setflags is always FALSE here
10223        else
10224            R[d] = result;
10225            if setflags then
10226                APSR.N = result<31>;
10227                APSR.Z = IsZeroBit(result);
10228                APSR.C = carry;
10229                APSR.V = overflow;
10230#endif
10231
10232  bool success = false;
10233
10234  if (ConditionPassed(opcode)) {
10235    uint32_t d;
10236    uint32_t n;
10237    uint32_t m;
10238    bool setflags;
10239    ARM_ShifterType shift_t;
10240    uint32_t shift_n;
10241
10242    switch (encoding) {
10243    case eEncodingT1:
10244      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
10245      d = Bits32(opcode, 2, 0);
10246      n = Bits32(opcode, 5, 3);
10247      m = Bits32(opcode, 8, 6);
10248      setflags = !InITBlock();
10249
10250      // (shift_t, shift_n) = (SRType_LSL, 0);
10251      shift_t = SRType_LSL;
10252      shift_n = 0;
10253
10254      break;
10255
10256    case eEncodingT2:
10257      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
10258      d = Bits32(opcode, 11, 8);
10259      n = Bits32(opcode, 19, 16);
10260      m = Bits32(opcode, 3, 0);
10261      setflags = BitIsSet(opcode, 20);
10262
10263      // if Rd == "1111" && S == "1" then SEE CMP (register);
10264      if (d == 15 && setflags == 1)
10265        return EmulateCMPImm(opcode, eEncodingT3);
10266
10267      // if Rn == "1101" then SEE SUB (SP minus register);
10268      if (n == 13)
10269        return EmulateSUBSPReg(opcode, eEncodingT1);
10270
10271      // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10272      shift_n = DecodeImmShiftThumb(opcode, shift_t);
10273
10274      // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
10275      // UNPREDICTABLE;
10276      if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
10277          BadReg(m))
10278        return false;
10279
10280      break;
10281
10282    case eEncodingA1:
10283      // if Rn == '1101' then SEE SUB (SP minus register);
10284      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
10285      d = Bits32(opcode, 15, 12);
10286      n = Bits32(opcode, 19, 16);
10287      m = Bits32(opcode, 3, 0);
10288      setflags = BitIsSet(opcode, 20);
10289
10290      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10291      // instructions;
10292      if ((d == 15) && setflags)
10293        EmulateSUBSPcLrEtc(opcode, encoding);
10294
10295      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10296      shift_n = DecodeImmShiftARM(opcode, shift_t);
10297
10298      break;
10299
10300    default:
10301      return false;
10302    }
10303
10304    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10305    uint32_t Rm = ReadCoreReg(m, &success);
10306    if (!success)
10307      return false;
10308
10309    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10310    if (!success)
10311      return false;
10312
10313    // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10314    uint32_t Rn = ReadCoreReg(n, &success);
10315    if (!success)
10316      return false;
10317
10318    AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
10319
10320    // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result);
10321    // // setflags is always FALSE here else
10322    // R[d] = result;
10323    // if setflags then
10324    // APSR.N = result<31>;
10325    // APSR.Z = IsZeroBit(result);
10326    // APSR.C = carry;
10327    // APSR.V = overflow;
10328
10329    EmulateInstruction::Context context;
10330    context.type = eContextArithmetic;
10331    RegisterInfo reg_n;
10332    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10333    RegisterInfo reg_m;
10334    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10335    context.SetRegisterRegisterOperands(reg_n, reg_m);
10336
10337    if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10338                                   res.carry_out, res.overflow))
10339      return false;
10340  }
10341  return true;
10342}
10343
10344// A8.6.202 STREX
10345// Store Register Exclusive calculates an address from a base register value
10346// and an immediate offset, and stores a word from a register to memory if the
10347// executing processor has exclusive access to the memory addressed.
10348bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
10349                                         const ARMEncoding encoding) {
10350#if 0
10351    if ConditionPassed() then
10352        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10353        address = R[n] + imm32;
10354        if ExclusiveMonitorsPass(address,4) then
10355            MemA[address,4] = R[t];
10356            R[d] = 0;
10357        else
10358            R[d] = 1;
10359#endif
10360
10361  bool success = false;
10362
10363  if (ConditionPassed(opcode)) {
10364    uint32_t d;
10365    uint32_t t;
10366    uint32_t n;
10367    uint32_t imm32;
10368    const uint32_t addr_byte_size = GetAddressByteSize();
10369
10370    switch (encoding) {
10371    case eEncodingT1:
10372      // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 =
10373      // ZeroExtend(imm8:'00',
10374      // 32);
10375      d = Bits32(opcode, 11, 8);
10376      t = Bits32(opcode, 15, 12);
10377      n = Bits32(opcode, 19, 16);
10378      imm32 = Bits32(opcode, 7, 0) << 2;
10379
10380      // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
10381      if (BadReg(d) || BadReg(t) || (n == 15))
10382        return false;
10383
10384      // if d == n || d == t then UNPREDICTABLE;
10385      if ((d == n) || (d == t))
10386        return false;
10387
10388      break;
10389
10390    case eEncodingA1:
10391      // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
10392      // offset
10393      d = Bits32(opcode, 15, 12);
10394      t = Bits32(opcode, 3, 0);
10395      n = Bits32(opcode, 19, 16);
10396      imm32 = 0;
10397
10398      // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
10399      if ((d == 15) || (t == 15) || (n == 15))
10400        return false;
10401
10402      // if d == n || d == t then UNPREDICTABLE;
10403      if ((d == n) || (d == t))
10404        return false;
10405
10406      break;
10407
10408    default:
10409      return false;
10410    }
10411
10412    // address = R[n] + imm32;
10413    uint32_t Rn = ReadCoreReg(n, &success);
10414    if (!success)
10415      return false;
10416
10417    addr_t address = Rn + imm32;
10418
10419    RegisterInfo base_reg;
10420    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10421    RegisterInfo data_reg;
10422    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10423    EmulateInstruction::Context context;
10424    context.type = eContextRegisterStore;
10425    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32);
10426
10427    // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass
10428    // (address, addr_byte_size)) -- For now, for the sake of emulation, we
10429    // will say this
10430    //                                                         always return
10431    //                                                         true.
10432    if (true) {
10433      // MemA[address,4] = R[t];
10434      uint32_t Rt =
10435          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
10436      if (!success)
10437        return false;
10438
10439      if (!MemAWrite(context, address, Rt, addr_byte_size))
10440        return false;
10441
10442      // R[d] = 0;
10443      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
10444        return false;
10445    }
10446#if 0  // unreachable because if true
10447        else
10448        {
10449            // R[d] = 1;
10450            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
10451                return false;
10452        }
10453#endif // unreachable because if true
10454  }
10455  return true;
10456}
10457
10458// A8.6.197 STRB (immediate, ARM)
10459bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
10460                                              const ARMEncoding encoding) {
10461#if 0
10462    if ConditionPassed() then
10463        EncodingSpecificOperations();
10464        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10465        address = if index then offset_addr else R[n];
10466        MemU[address,1] = R[t]<7:0>;
10467        if wback then R[n] = offset_addr;
10468#endif
10469
10470  bool success = false;
10471
10472  if (ConditionPassed(opcode)) {
10473    uint32_t t;
10474    uint32_t n;
10475    uint32_t imm32;
10476    bool index;
10477    bool add;
10478    bool wback;
10479
10480    switch (encoding) {
10481    case eEncodingA1:
10482      // if P == '0' && W == '1' then SEE STRBT;
10483      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10484      t = Bits32(opcode, 15, 12);
10485      n = Bits32(opcode, 19, 16);
10486      imm32 = Bits32(opcode, 11, 0);
10487
10488      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10489      index = BitIsSet(opcode, 24);
10490      add = BitIsSet(opcode, 23);
10491      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10492
10493      // if t == 15 then UNPREDICTABLE;
10494      if (t == 15)
10495        return false;
10496
10497      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10498      if (wback && ((n == 15) || (n == t)))
10499        return false;
10500
10501      break;
10502
10503    default:
10504      return false;
10505    }
10506
10507    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10508    uint32_t Rn = ReadCoreReg(n, &success);
10509    if (!success)
10510      return false;
10511
10512    addr_t offset_addr;
10513    if (add)
10514      offset_addr = Rn + imm32;
10515    else
10516      offset_addr = Rn - imm32;
10517
10518    // address = if index then offset_addr else R[n];
10519    addr_t address;
10520    if (index)
10521      address = offset_addr;
10522    else
10523      address = Rn;
10524
10525    // MemU[address,1] = R[t]<7:0>;
10526    uint32_t Rt = ReadCoreReg(t, &success);
10527    if (!success)
10528      return false;
10529
10530    RegisterInfo base_reg;
10531    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10532    RegisterInfo data_reg;
10533    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10534    EmulateInstruction::Context context;
10535    context.type = eContextRegisterStore;
10536    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10537
10538    if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
10539      return false;
10540
10541    // if wback then R[n] = offset_addr;
10542    if (wback) {
10543      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10544                                 offset_addr))
10545        return false;
10546    }
10547  }
10548  return true;
10549}
10550
10551// A8.6.194 STR (immediate, ARM)
10552bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
10553                                             const ARMEncoding encoding) {
10554#if 0
10555    if ConditionPassed() then
10556        EncodingSpecificOperations();
10557        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10558        address = if index then offset_addr else R[n];
10559        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10560        if wback then R[n] = offset_addr;
10561#endif
10562
10563  bool success = false;
10564
10565  if (ConditionPassed(opcode)) {
10566    uint32_t t;
10567    uint32_t n;
10568    uint32_t imm32;
10569    bool index;
10570    bool add;
10571    bool wback;
10572
10573    const uint32_t addr_byte_size = GetAddressByteSize();
10574
10575    switch (encoding) {
10576    case eEncodingA1:
10577      // if P == '0' && W == '1' then SEE STRT;
10578      // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
10579      // '000000000100' then SEE PUSH;
10580      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10581      t = Bits32(opcode, 15, 12);
10582      n = Bits32(opcode, 19, 16);
10583      imm32 = Bits32(opcode, 11, 0);
10584
10585      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10586      index = BitIsSet(opcode, 24);
10587      add = BitIsSet(opcode, 23);
10588      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10589
10590      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10591      if (wback && ((n == 15) || (n == t)))
10592        return false;
10593
10594      break;
10595
10596    default:
10597      return false;
10598    }
10599
10600    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10601    uint32_t Rn = ReadCoreReg(n, &success);
10602    if (!success)
10603      return false;
10604
10605    addr_t offset_addr;
10606    if (add)
10607      offset_addr = Rn + imm32;
10608    else
10609      offset_addr = Rn - imm32;
10610
10611    // address = if index then offset_addr else R[n];
10612    addr_t address;
10613    if (index)
10614      address = offset_addr;
10615    else
10616      address = Rn;
10617
10618    RegisterInfo base_reg;
10619    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10620    RegisterInfo data_reg;
10621    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10622    EmulateInstruction::Context context;
10623    context.type = eContextRegisterStore;
10624    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10625
10626    // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10627    uint32_t Rt = ReadCoreReg(t, &success);
10628    if (!success)
10629      return false;
10630
10631    if (t == 15) {
10632      uint32_t pc_value = ReadCoreReg(PC_REG, &success);
10633      if (!success)
10634        return false;
10635
10636      if (!MemUWrite(context, address, pc_value, addr_byte_size))
10637        return false;
10638    } else {
10639      if (!MemUWrite(context, address, Rt, addr_byte_size))
10640        return false;
10641    }
10642
10643    // if wback then R[n] = offset_addr;
10644    if (wback) {
10645      context.type = eContextAdjustBaseRegister;
10646      context.SetImmediate(offset_addr);
10647
10648      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10649                                 offset_addr))
10650        return false;
10651    }
10652  }
10653  return true;
10654}
10655
10656// A8.6.66 LDRD (immediate)
10657// Load Register Dual (immediate) calculates an address from a base register
10658// value and an immediate offset, loads two words from memory, and writes them
10659// to two registers.  It can use offset, post-indexed, or pre-indexed
10660// addressing.
10661bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
10662                                                 const ARMEncoding encoding) {
10663#if 0
10664    if ConditionPassed() then
10665        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10666        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10667        address = if index then offset_addr else R[n];
10668        R[t] = MemA[address,4];
10669        R[t2] = MemA[address+4,4];
10670        if wback then R[n] = offset_addr;
10671#endif
10672
10673  bool success = false;
10674
10675  if (ConditionPassed(opcode)) {
10676    uint32_t t;
10677    uint32_t t2;
10678    uint32_t n;
10679    uint32_t imm32;
10680    bool index;
10681    bool add;
10682    bool wback;
10683
10684    switch (encoding) {
10685    case eEncodingT1:
10686      // if P == '0' && W == '0' then SEE 'Related encodings';
10687      // if Rn == '1111' then SEE LDRD (literal);
10688      // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10689      // ZeroExtend(imm8:'00', 32);
10690      t = Bits32(opcode, 15, 12);
10691      t2 = Bits32(opcode, 11, 8);
10692      n = Bits32(opcode, 19, 16);
10693      imm32 = Bits32(opcode, 7, 0) << 2;
10694
10695      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10696      index = BitIsSet(opcode, 24);
10697      add = BitIsSet(opcode, 23);
10698      wback = BitIsSet(opcode, 21);
10699
10700      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10701      if (wback && ((n == t) || (n == t2)))
10702        return false;
10703
10704      // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10705      if (BadReg(t) || BadReg(t2) || (t == t2))
10706        return false;
10707
10708      break;
10709
10710    case eEncodingA1:
10711      // if Rn == '1111' then SEE LDRD (literal);
10712      // if Rt<0> == '1' then UNPREDICTABLE;
10713      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10714      // 32);
10715      t = Bits32(opcode, 15, 12);
10716      if (BitIsSet(t, 0))
10717        return false;
10718      t2 = t + 1;
10719      n = Bits32(opcode, 19, 16);
10720      imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10721
10722      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10723      index = BitIsSet(opcode, 24);
10724      add = BitIsSet(opcode, 23);
10725      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10726
10727      // if P == '0' && W == '1' then UNPREDICTABLE;
10728      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10729        return false;
10730
10731      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10732      if (wback && ((n == t) || (n == t2)))
10733        return false;
10734
10735      // if t2 == 15 then UNPREDICTABLE;
10736      if (t2 == 15)
10737        return false;
10738
10739      break;
10740
10741    default:
10742      return false;
10743    }
10744
10745    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10746    uint32_t Rn = ReadCoreReg(n, &success);
10747    if (!success)
10748      return false;
10749
10750    addr_t offset_addr;
10751    if (add)
10752      offset_addr = Rn + imm32;
10753    else
10754      offset_addr = Rn - imm32;
10755
10756    // address = if index then offset_addr else R[n];
10757    addr_t address;
10758    if (index)
10759      address = offset_addr;
10760    else
10761      address = Rn;
10762
10763    // R[t] = MemA[address,4];
10764    RegisterInfo base_reg;
10765    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10766
10767    EmulateInstruction::Context context;
10768    if (n == 13)
10769      context.type = eContextPopRegisterOffStack;
10770    else
10771      context.type = eContextRegisterLoad;
10772    context.SetAddress(address);
10773
10774    const uint32_t addr_byte_size = GetAddressByteSize();
10775    uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10776    if (!success)
10777      return false;
10778
10779    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10780      return false;
10781
10782    // R[t2] = MemA[address+4,4];
10783    context.SetAddress(address + 4);
10784    data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10785    if (!success)
10786      return false;
10787
10788    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10789                               data))
10790      return false;
10791
10792    // if wback then R[n] = offset_addr;
10793    if (wback) {
10794      context.type = eContextAdjustBaseRegister;
10795      context.SetAddress(offset_addr);
10796
10797      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10798                                 offset_addr))
10799        return false;
10800    }
10801  }
10802  return true;
10803}
10804
10805// A8.6.68 LDRD (register)
10806// Load Register Dual (register) calculates an address from a base register
10807// value and a register offset, loads two words from memory, and writes them to
10808// two registers.  It can use offset, post-indexed or pre-indexed addressing.
10809bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
10810                                                const ARMEncoding encoding) {
10811#if 0
10812    if ConditionPassed() then
10813        EncodingSpecificOperations();
10814        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10815        address = if index then offset_addr else R[n];
10816        R[t] = MemA[address,4];
10817        R[t2] = MemA[address+4,4];
10818        if wback then R[n] = offset_addr;
10819#endif
10820
10821  bool success = false;
10822
10823  if (ConditionPassed(opcode)) {
10824    uint32_t t;
10825    uint32_t t2;
10826    uint32_t n;
10827    uint32_t m;
10828    bool index;
10829    bool add;
10830    bool wback;
10831
10832    switch (encoding) {
10833    case eEncodingA1:
10834      // if Rt<0> == '1' then UNPREDICTABLE;
10835      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10836      t = Bits32(opcode, 15, 12);
10837      if (BitIsSet(t, 0))
10838        return false;
10839      t2 = t + 1;
10840      n = Bits32(opcode, 19, 16);
10841      m = Bits32(opcode, 3, 0);
10842
10843      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10844      index = BitIsSet(opcode, 24);
10845      add = BitIsSet(opcode, 23);
10846      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10847
10848      // if P == '0' && W == '1' then UNPREDICTABLE;
10849      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10850        return false;
10851
10852      // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10853      if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10854        return false;
10855
10856      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10857      if (wback && ((n == 15) || (n == t) || (n == t2)))
10858        return false;
10859
10860      // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10861      if ((ArchVersion() < 6) && wback && (m == n))
10862        return false;
10863      break;
10864
10865    default:
10866      return false;
10867    }
10868
10869    uint32_t Rn = ReadCoreReg(n, &success);
10870    if (!success)
10871      return false;
10872    RegisterInfo base_reg;
10873    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10874
10875    uint32_t Rm = ReadCoreReg(m, &success);
10876    if (!success)
10877      return false;
10878    RegisterInfo offset_reg;
10879    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10880
10881    // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10882    addr_t offset_addr;
10883    if (add)
10884      offset_addr = Rn + Rm;
10885    else
10886      offset_addr = Rn - Rm;
10887
10888    // address = if index then offset_addr else R[n];
10889    addr_t address;
10890    if (index)
10891      address = offset_addr;
10892    else
10893      address = Rn;
10894
10895    EmulateInstruction::Context context;
10896    if (n == 13)
10897      context.type = eContextPopRegisterOffStack;
10898    else
10899      context.type = eContextRegisterLoad;
10900    context.SetAddress(address);
10901
10902    // R[t] = MemA[address,4];
10903    const uint32_t addr_byte_size = GetAddressByteSize();
10904    uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10905    if (!success)
10906      return false;
10907
10908    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10909      return false;
10910
10911    // R[t2] = MemA[address+4,4];
10912
10913    data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10914    if (!success)
10915      return false;
10916
10917    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10918                               data))
10919      return false;
10920
10921    // if wback then R[n] = offset_addr;
10922    if (wback) {
10923      context.type = eContextAdjustBaseRegister;
10924      context.SetAddress(offset_addr);
10925
10926      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10927                                 offset_addr))
10928        return false;
10929    }
10930  }
10931  return true;
10932}
10933
10934// A8.6.200 STRD (immediate)
10935// Store Register Dual (immediate) calculates an address from a base register
10936// value and an immediate offset, and stores two words from two registers to
10937// memory.  It can use offset, post-indexed, or pre-indexed addressing.
10938bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
10939                                           const ARMEncoding encoding) {
10940#if 0
10941    if ConditionPassed() then
10942        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10943        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10944        address = if index then offset_addr else R[n];
10945        MemA[address,4] = R[t];
10946        MemA[address+4,4] = R[t2];
10947        if wback then R[n] = offset_addr;
10948#endif
10949
10950  bool success = false;
10951
10952  if (ConditionPassed(opcode)) {
10953    uint32_t t;
10954    uint32_t t2;
10955    uint32_t n;
10956    uint32_t imm32;
10957    bool index;
10958    bool add;
10959    bool wback;
10960
10961    switch (encoding) {
10962    case eEncodingT1:
10963      // if P == '0' && W == '0' then SEE 'Related encodings';
10964      // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10965      // ZeroExtend(imm8:'00', 32);
10966      t = Bits32(opcode, 15, 12);
10967      t2 = Bits32(opcode, 11, 8);
10968      n = Bits32(opcode, 19, 16);
10969      imm32 = Bits32(opcode, 7, 0) << 2;
10970
10971      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10972      index = BitIsSet(opcode, 24);
10973      add = BitIsSet(opcode, 23);
10974      wback = BitIsSet(opcode, 21);
10975
10976      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10977      if (wback && ((n == t) || (n == t2)))
10978        return false;
10979
10980      // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10981      if ((n == 15) || BadReg(t) || BadReg(t2))
10982        return false;
10983
10984      break;
10985
10986    case eEncodingA1:
10987      // if Rt<0> == '1' then UNPREDICTABLE;
10988      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10989      // 32);
10990      t = Bits32(opcode, 15, 12);
10991      if (BitIsSet(t, 0))
10992        return false;
10993
10994      t2 = t + 1;
10995      n = Bits32(opcode, 19, 16);
10996      imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10997
10998      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10999      index = BitIsSet(opcode, 24);
11000      add = BitIsSet(opcode, 23);
11001      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11002
11003      // if P == '0' && W == '1' then UNPREDICTABLE;
11004      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11005        return false;
11006
11007      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11008      if (wback && ((n == 15) || (n == t) || (n == t2)))
11009        return false;
11010
11011      // if t2 == 15 then UNPREDICTABLE;
11012      if (t2 == 15)
11013        return false;
11014
11015      break;
11016
11017    default:
11018      return false;
11019    }
11020
11021    RegisterInfo base_reg;
11022    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11023
11024    uint32_t Rn = ReadCoreReg(n, &success);
11025    if (!success)
11026      return false;
11027
11028    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
11029    addr_t offset_addr;
11030    if (add)
11031      offset_addr = Rn + imm32;
11032    else
11033      offset_addr = Rn - imm32;
11034
11035    // address = if index then offset_addr else R[n];
11036    addr_t address;
11037    if (index)
11038      address = offset_addr;
11039    else
11040      address = Rn;
11041
11042    // MemA[address,4] = R[t];
11043    RegisterInfo data_reg;
11044    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11045
11046    uint32_t data = ReadCoreReg(t, &success);
11047    if (!success)
11048      return false;
11049
11050    EmulateInstruction::Context context;
11051    if (n == 13)
11052      context.type = eContextPushRegisterOnStack;
11053    else
11054      context.type = eContextRegisterStore;
11055    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11056
11057    const uint32_t addr_byte_size = GetAddressByteSize();
11058
11059    if (!MemAWrite(context, address, data, addr_byte_size))
11060      return false;
11061
11062    // MemA[address+4,4] = R[t2];
11063    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11064    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11065                                            (address + 4) - Rn);
11066
11067    data = ReadCoreReg(t2, &success);
11068    if (!success)
11069      return false;
11070
11071    if (!MemAWrite(context, address + 4, data, addr_byte_size))
11072      return false;
11073
11074    // if wback then R[n] = offset_addr;
11075    if (wback) {
11076      if (n == 13)
11077        context.type = eContextAdjustStackPointer;
11078      else
11079        context.type = eContextAdjustBaseRegister;
11080      context.SetAddress(offset_addr);
11081
11082      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11083                                 offset_addr))
11084        return false;
11085    }
11086  }
11087  return true;
11088}
11089
11090// A8.6.201 STRD (register)
11091bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
11092                                           const ARMEncoding encoding) {
11093#if 0
11094    if ConditionPassed() then
11095        EncodingSpecificOperations();
11096        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11097        address = if index then offset_addr else R[n];
11098        MemA[address,4] = R[t];
11099        MemA[address+4,4] = R[t2];
11100        if wback then R[n] = offset_addr;
11101#endif
11102
11103  bool success = false;
11104
11105  if (ConditionPassed(opcode)) {
11106    uint32_t t;
11107    uint32_t t2;
11108    uint32_t n;
11109    uint32_t m;
11110    bool index;
11111    bool add;
11112    bool wback;
11113
11114    switch (encoding) {
11115    case eEncodingA1:
11116      // if Rt<0> == '1' then UNPREDICTABLE;
11117      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
11118      t = Bits32(opcode, 15, 12);
11119      if (BitIsSet(t, 0))
11120        return false;
11121
11122      t2 = t + 1;
11123      n = Bits32(opcode, 19, 16);
11124      m = Bits32(opcode, 3, 0);
11125
11126      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11127      index = BitIsSet(opcode, 24);
11128      add = BitIsSet(opcode, 23);
11129      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11130
11131      // if P == '0' && W == '1' then UNPREDICTABLE;
11132      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11133        return false;
11134
11135      // if t2 == 15 || m == 15 then UNPREDICTABLE;
11136      if ((t2 == 15) || (m == 15))
11137        return false;
11138
11139      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11140      if (wback && ((n == 15) || (n == t) || (n == t2)))
11141        return false;
11142
11143      // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
11144      if ((ArchVersion() < 6) && wback && (m == n))
11145        return false;
11146
11147      break;
11148
11149    default:
11150      return false;
11151    }
11152
11153    RegisterInfo base_reg;
11154    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11155    RegisterInfo offset_reg;
11156    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
11157    RegisterInfo data_reg;
11158
11159    uint32_t Rn = ReadCoreReg(n, &success);
11160    if (!success)
11161      return false;
11162
11163    uint32_t Rm = ReadCoreReg(m, &success);
11164    if (!success)
11165      return false;
11166
11167    // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11168    addr_t offset_addr;
11169    if (add)
11170      offset_addr = Rn + Rm;
11171    else
11172      offset_addr = Rn - Rm;
11173
11174    // address = if index then offset_addr else R[n];
11175    addr_t address;
11176    if (index)
11177      address = offset_addr;
11178    else
11179      address = Rn;
11180    // MemA[address,4] = R[t];
11181    uint32_t Rt = ReadCoreReg(t, &success);
11182    if (!success)
11183      return false;
11184
11185    EmulateInstruction::Context context;
11186    if (t == 13)
11187      context.type = eContextPushRegisterOnStack;
11188    else
11189      context.type = eContextRegisterStore;
11190
11191    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11192    context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11193                                                    data_reg);
11194
11195    const uint32_t addr_byte_size = GetAddressByteSize();
11196
11197    if (!MemAWrite(context, address, Rt, addr_byte_size))
11198      return false;
11199
11200    // MemA[address+4,4] = R[t2];
11201    uint32_t Rt2 = ReadCoreReg(t2, &success);
11202    if (!success)
11203      return false;
11204
11205    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11206
11207    context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11208                                                    data_reg);
11209
11210    if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
11211      return false;
11212
11213    // if wback then R[n] = offset_addr;
11214    if (wback) {
11215      context.type = eContextAdjustBaseRegister;
11216      context.SetAddress(offset_addr);
11217
11218      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11219                                 offset_addr))
11220        return false;
11221    }
11222  }
11223  return true;
11224}
11225
11226// A8.6.319 VLDM
11227// Vector Load Multiple loads multiple extension registers from consecutive
11228// memory locations using an address from an ARM core register.
11229bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
11230                                        const ARMEncoding encoding) {
11231#if 0
11232    if ConditionPassed() then
11233        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11234        address = if add then R[n] else R[n]-imm32;
11235        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11236        for r = 0 to regs-1
11237            if single_regs then
11238                S[d+r] = MemA[address,4]; address = address+4;
11239            else
11240                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
11241                // Combine the word-aligned words in the correct order for
11242                // current endianness.
11243                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11244#endif
11245
11246  bool success = false;
11247
11248  if (ConditionPassed(opcode)) {
11249    bool single_regs;
11250    bool add;
11251    bool wback;
11252    uint32_t d;
11253    uint32_t n;
11254    uint32_t imm32;
11255    uint32_t regs;
11256
11257    switch (encoding) {
11258    case eEncodingT1:
11259    case eEncodingA1:
11260      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11261      // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11262      // if P == '1' && W == '0' then SEE VLDR;
11263      // if P == U && W == '1' then UNDEFINED;
11264      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11265        return false;
11266
11267      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11268      // !), 101 (DB with !)
11269      // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11270      single_regs = false;
11271      add = BitIsSet(opcode, 23);
11272      wback = BitIsSet(opcode, 21);
11273
11274      // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11275      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11276      n = Bits32(opcode, 19, 16);
11277      imm32 = Bits32(opcode, 7, 0) << 2;
11278
11279      // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
11280      regs = Bits32(opcode, 7, 0) / 2;
11281
11282      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11283      // UNPREDICTABLE;
11284      if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
11285        return false;
11286
11287      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11288      if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11289        return false;
11290
11291      break;
11292
11293    case eEncodingT2:
11294    case eEncodingA2:
11295      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11296      // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11297      // if P == '1' && W == '0' then SEE VLDR;
11298      // if P == U && W == '1' then UNDEFINED;
11299      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11300        return false;
11301
11302      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11303      // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11304      // == '1'); d =
11305      // UInt(Vd:D); n = UInt(Rn);
11306      single_regs = true;
11307      add = BitIsSet(opcode, 23);
11308      wback = BitIsSet(opcode, 21);
11309      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11310      n = Bits32(opcode, 19, 16);
11311
11312      // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11313      imm32 = Bits32(opcode, 7, 0) << 2;
11314      regs = Bits32(opcode, 7, 0);
11315
11316      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11317      // UNPREDICTABLE;
11318      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11319        return false;
11320
11321      // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11322      if ((regs == 0) || ((d + regs) > 32))
11323        return false;
11324      break;
11325
11326    default:
11327      return false;
11328    }
11329
11330    RegisterInfo base_reg;
11331    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11332
11333    uint32_t Rn = ReadCoreReg(n, &success);
11334    if (!success)
11335      return false;
11336
11337    // address = if add then R[n] else R[n]-imm32;
11338    addr_t address;
11339    if (add)
11340      address = Rn;
11341    else
11342      address = Rn - imm32;
11343
11344    // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11345    EmulateInstruction::Context context;
11346
11347    if (wback) {
11348      uint32_t value;
11349      if (add)
11350        value = Rn + imm32;
11351      else
11352        value = Rn - imm32;
11353
11354      context.type = eContextAdjustBaseRegister;
11355      context.SetImmediateSigned(value - Rn);
11356      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11357                                 value))
11358        return false;
11359    }
11360
11361    const uint32_t addr_byte_size = GetAddressByteSize();
11362    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11363
11364    context.type = eContextRegisterLoad;
11365
11366    // for r = 0 to regs-1
11367    for (uint32_t r = 0; r < regs; ++r) {
11368      if (single_regs) {
11369        // S[d+r] = MemA[address,4]; address = address+4;
11370        context.SetRegisterPlusOffset(base_reg, address - Rn);
11371
11372        uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11373        if (!success)
11374          return false;
11375
11376        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11377                                   start_reg + d + r, data))
11378          return false;
11379
11380        address = address + 4;
11381      } else {
11382        // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
11383        // address+8;
11384        context.SetRegisterPlusOffset(base_reg, address - Rn);
11385        uint32_t word1 =
11386            MemARead(context, address, addr_byte_size, 0, &success);
11387        if (!success)
11388          return false;
11389
11390        context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn);
11391        uint32_t word2 =
11392            MemARead(context, address + 4, addr_byte_size, 0, &success);
11393        if (!success)
11394          return false;
11395
11396        address = address + 8;
11397        // // Combine the word-aligned words in the correct order for current
11398        // endianness.
11399        // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11400        uint64_t data;
11401        if (GetByteOrder() == eByteOrderBig) {
11402          data = word1;
11403          data = (data << 32) | word2;
11404        } else {
11405          data = word2;
11406          data = (data << 32) | word1;
11407        }
11408
11409        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11410                                   start_reg + d + r, data))
11411          return false;
11412      }
11413    }
11414  }
11415  return true;
11416}
11417
11418// A8.6.399 VSTM
11419// Vector Store Multiple stores multiple extension registers to consecutive
11420// memory locations using an address from an
11421// ARM core register.
11422bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
11423                                        const ARMEncoding encoding) {
11424#if 0
11425    if ConditionPassed() then
11426        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11427        address = if add then R[n] else R[n]-imm32;
11428        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11429        for r = 0 to regs-1
11430            if single_regs then
11431                MemA[address,4] = S[d+r]; address = address+4;
11432            else
11433                // Store as two word-aligned words in the correct order for
11434                // current endianness.
11435                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11436                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11437                address = address+8;
11438#endif
11439
11440  bool success = false;
11441
11442  if (ConditionPassed(opcode)) {
11443    bool single_regs;
11444    bool add;
11445    bool wback;
11446    uint32_t d;
11447    uint32_t n;
11448    uint32_t imm32;
11449    uint32_t regs;
11450
11451    switch (encoding) {
11452    case eEncodingT1:
11453    case eEncodingA1:
11454      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11455      // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11456      // if P == '1' && W == '0' then SEE VSTR;
11457      // if P == U && W == '1' then UNDEFINED;
11458      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11459        return false;
11460
11461      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11462      // !), 101 (DB with !)
11463      // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11464      single_regs = false;
11465      add = BitIsSet(opcode, 23);
11466      wback = BitIsSet(opcode, 21);
11467
11468      // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11469      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11470      n = Bits32(opcode, 19, 16);
11471      imm32 = Bits32(opcode, 7, 0) << 2;
11472
11473      // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11474      regs = Bits32(opcode, 7, 0) / 2;
11475
11476      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11477      // UNPREDICTABLE;
11478      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11479        return false;
11480
11481      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11482      if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11483        return false;
11484
11485      break;
11486
11487    case eEncodingT2:
11488    case eEncodingA2:
11489      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11490      // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11491      // if P == '1' && W == '0' then SEE VSTR;
11492      // if P == U && W == '1' then UNDEFINED;
11493      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11494        return false;
11495
11496      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11497      // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11498      // == '1'); d =
11499      // UInt(Vd:D); n = UInt(Rn);
11500      single_regs = true;
11501      add = BitIsSet(opcode, 23);
11502      wback = BitIsSet(opcode, 21);
11503      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11504      n = Bits32(opcode, 19, 16);
11505
11506      // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11507      imm32 = Bits32(opcode, 7, 0) << 2;
11508      regs = Bits32(opcode, 7, 0);
11509
11510      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11511      // UNPREDICTABLE;
11512      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11513        return false;
11514
11515      // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11516      if ((regs == 0) || ((d + regs) > 32))
11517        return false;
11518
11519      break;
11520
11521    default:
11522      return false;
11523    }
11524
11525    RegisterInfo base_reg;
11526    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11527
11528    uint32_t Rn = ReadCoreReg(n, &success);
11529    if (!success)
11530      return false;
11531
11532    // address = if add then R[n] else R[n]-imm32;
11533    addr_t address;
11534    if (add)
11535      address = Rn;
11536    else
11537      address = Rn - imm32;
11538
11539    EmulateInstruction::Context context;
11540    // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11541    if (wback) {
11542      uint32_t value;
11543      if (add)
11544        value = Rn + imm32;
11545      else
11546        value = Rn - imm32;
11547
11548      context.type = eContextAdjustBaseRegister;
11549      context.SetRegisterPlusOffset(base_reg, value - Rn);
11550
11551      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11552                                 value))
11553        return false;
11554    }
11555
11556    const uint32_t addr_byte_size = GetAddressByteSize();
11557    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11558
11559    context.type = eContextRegisterStore;
11560    // for r = 0 to regs-1
11561    for (uint32_t r = 0; r < regs; ++r) {
11562
11563      if (single_regs) {
11564        // MemA[address,4] = S[d+r]; address = address+4;
11565        uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11566                                             start_reg + d + r, 0, &success);
11567        if (!success)
11568          return false;
11569
11570        RegisterInfo data_reg;
11571        GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11572        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11573                                                address - Rn);
11574        if (!MemAWrite(context, address, data, addr_byte_size))
11575          return false;
11576
11577        address = address + 4;
11578      } else {
11579        // // Store as two word-aligned words in the correct order for current
11580        // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
11581        // D[d+r]<31:0>;
11582        // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
11583        // D[d+r]<63:32>;
11584        uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11585                                             start_reg + d + r, 0, &success);
11586        if (!success)
11587          return false;
11588
11589        RegisterInfo data_reg;
11590        GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11591
11592        if (GetByteOrder() == eByteOrderBig) {
11593          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11594                                                  address - Rn);
11595          if (!MemAWrite(context, address, Bits64(data, 63, 32),
11596                         addr_byte_size))
11597            return false;
11598
11599          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11600                                                  (address + 4) - Rn);
11601          if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11602                         addr_byte_size))
11603            return false;
11604        } else {
11605          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11606                                                  address - Rn);
11607          if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11608            return false;
11609
11610          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11611                                                  (address + 4) - Rn);
11612          if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11613                         addr_byte_size))
11614            return false;
11615        }
11616        // address = address+8;
11617        address = address + 8;
11618      }
11619    }
11620  }
11621  return true;
11622}
11623
11624// A8.6.320
11625// This instruction loads a single extension register from memory, using an
11626// address from an ARM core register, with an optional offset.
11627bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
11628                                        ARMEncoding encoding) {
11629#if 0
11630    if ConditionPassed() then
11631        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11632        base = if n == 15 then Align(PC,4) else R[n];
11633        address = if add then (base + imm32) else (base - imm32);
11634        if single_reg then
11635            S[d] = MemA[address,4];
11636        else
11637            word1 = MemA[address,4]; word2 = MemA[address+4,4];
11638            // Combine the word-aligned words in the correct order for current
11639            // endianness.
11640            D[d] = if BigEndian() then word1:word2 else word2:word1;
11641#endif
11642
11643  bool success = false;
11644
11645  if (ConditionPassed(opcode)) {
11646    bool single_reg;
11647    bool add;
11648    uint32_t imm32;
11649    uint32_t d;
11650    uint32_t n;
11651
11652    switch (encoding) {
11653    case eEncodingT1:
11654    case eEncodingA1:
11655      // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11656      // 32);
11657      single_reg = false;
11658      add = BitIsSet(opcode, 23);
11659      imm32 = Bits32(opcode, 7, 0) << 2;
11660
11661      // d = UInt(D:Vd); n = UInt(Rn);
11662      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11663      n = Bits32(opcode, 19, 16);
11664
11665      break;
11666
11667    case eEncodingT2:
11668    case eEncodingA2:
11669      // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11670      single_reg = true;
11671      add = BitIsSet(opcode, 23);
11672      imm32 = Bits32(opcode, 7, 0) << 2;
11673
11674      // d = UInt(Vd:D); n = UInt(Rn);
11675      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11676      n = Bits32(opcode, 19, 16);
11677
11678      break;
11679
11680    default:
11681      return false;
11682    }
11683    RegisterInfo base_reg;
11684    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11685
11686    uint32_t Rn = ReadCoreReg(n, &success);
11687    if (!success)
11688      return false;
11689
11690    // base = if n == 15 then Align(PC,4) else R[n];
11691    uint32_t base;
11692    if (n == 15)
11693      base = AlignPC(Rn);
11694    else
11695      base = Rn;
11696
11697    // address = if add then (base + imm32) else (base - imm32);
11698    addr_t address;
11699    if (add)
11700      address = base + imm32;
11701    else
11702      address = base - imm32;
11703
11704    const uint32_t addr_byte_size = GetAddressByteSize();
11705    uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11706
11707    EmulateInstruction::Context context;
11708    context.type = eContextRegisterLoad;
11709    context.SetRegisterPlusOffset(base_reg, address - base);
11710
11711    if (single_reg) {
11712      // S[d] = MemA[address,4];
11713      uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11714      if (!success)
11715        return false;
11716
11717      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11718                                 data))
11719        return false;
11720    } else {
11721      // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11722      uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
11723      if (!success)
11724        return false;
11725
11726      context.SetRegisterPlusOffset(base_reg, (address + 4) - base);
11727      uint32_t word2 =
11728          MemARead(context, address + 4, addr_byte_size, 0, &success);
11729      if (!success)
11730        return false;
11731      // // Combine the word-aligned words in the correct order for current
11732      // endianness.
11733      // D[d] = if BigEndian() then word1:word2 else word2:word1;
11734      uint64_t data64;
11735      if (GetByteOrder() == eByteOrderBig) {
11736        data64 = word1;
11737        data64 = (data64 << 32) | word2;
11738      } else {
11739        data64 = word2;
11740        data64 = (data64 << 32) | word1;
11741      }
11742
11743      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11744                                 data64))
11745        return false;
11746    }
11747  }
11748  return true;
11749}
11750
11751// A8.6.400 VSTR
11752// This instruction stores a signle extension register to memory, using an
11753// address from an ARM core register, with an optional offset.
11754bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
11755                                        ARMEncoding encoding) {
11756#if 0
11757    if ConditionPassed() then
11758        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11759        address = if add then (R[n] + imm32) else (R[n] - imm32);
11760        if single_reg then
11761            MemA[address,4] = S[d];
11762        else
11763            // Store as two word-aligned words in the correct order for current
11764            // endianness.
11765            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11766            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11767#endif
11768
11769  bool success = false;
11770
11771  if (ConditionPassed(opcode)) {
11772    bool single_reg;
11773    bool add;
11774    uint32_t imm32;
11775    uint32_t d;
11776    uint32_t n;
11777
11778    switch (encoding) {
11779    case eEncodingT1:
11780    case eEncodingA1:
11781      // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11782      // 32);
11783      single_reg = false;
11784      add = BitIsSet(opcode, 23);
11785      imm32 = Bits32(opcode, 7, 0) << 2;
11786
11787      // d = UInt(D:Vd); n = UInt(Rn);
11788      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11789      n = Bits32(opcode, 19, 16);
11790
11791      // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11792      if ((n == 15) && (CurrentInstrSet() != eModeARM))
11793        return false;
11794
11795      break;
11796
11797    case eEncodingT2:
11798    case eEncodingA2:
11799      // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11800      single_reg = true;
11801      add = BitIsSet(opcode, 23);
11802      imm32 = Bits32(opcode, 7, 0) << 2;
11803
11804      // d = UInt(Vd:D); n = UInt(Rn);
11805      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11806      n = Bits32(opcode, 19, 16);
11807
11808      // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11809      if ((n == 15) && (CurrentInstrSet() != eModeARM))
11810        return false;
11811
11812      break;
11813
11814    default:
11815      return false;
11816    }
11817
11818    RegisterInfo base_reg;
11819    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11820
11821    uint32_t Rn = ReadCoreReg(n, &success);
11822    if (!success)
11823      return false;
11824
11825    // address = if add then (R[n] + imm32) else (R[n] - imm32);
11826    addr_t address;
11827    if (add)
11828      address = Rn + imm32;
11829    else
11830      address = Rn - imm32;
11831
11832    const uint32_t addr_byte_size = GetAddressByteSize();
11833    uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11834
11835    RegisterInfo data_reg;
11836    GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg);
11837    EmulateInstruction::Context context;
11838    context.type = eContextRegisterStore;
11839    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11840
11841    if (single_reg) {
11842      // MemA[address,4] = S[d];
11843      uint32_t data =
11844          ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11845      if (!success)
11846        return false;
11847
11848      if (!MemAWrite(context, address, data, addr_byte_size))
11849        return false;
11850    } else {
11851      // // Store as two word-aligned words in the correct order for current
11852      // endianness.
11853      // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11854      // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11855      uint64_t data =
11856          ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11857      if (!success)
11858        return false;
11859
11860      if (GetByteOrder() == eByteOrderBig) {
11861        if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
11862          return false;
11863
11864        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11865                                                (address + 4) - Rn);
11866        if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11867                       addr_byte_size))
11868          return false;
11869      } else {
11870        if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11871          return false;
11872
11873        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11874                                                (address + 4) - Rn);
11875        if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11876                       addr_byte_size))
11877          return false;
11878      }
11879    }
11880  }
11881  return true;
11882}
11883
11884// A8.6.307 VLDI1 (multiple single elements) This instruction loads elements
11885// from memory into one, two, three or four registers, without de-interleaving.
11886// Every element of each register is loaded.
11887bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
11888                                                ARMEncoding encoding) {
11889#if 0
11890    if ConditionPassed() then
11891        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11892        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11893        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11894        for r = 0 to regs-1
11895            for e = 0 to elements-1
11896                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11897                address = address + ebytes;
11898#endif
11899
11900  bool success = false;
11901
11902  if (ConditionPassed(opcode)) {
11903    uint32_t regs;
11904    uint32_t alignment;
11905    uint32_t ebytes;
11906    uint32_t esize;
11907    uint32_t elements;
11908    uint32_t d;
11909    uint32_t n;
11910    uint32_t m;
11911    bool wback;
11912    bool register_index;
11913
11914    switch (encoding) {
11915    case eEncodingT1:
11916    case eEncodingA1: {
11917      // case type of
11918      // when '0111'
11919      // regs = 1; if align<1> == '1' then UNDEFINED;
11920      // when '1010'
11921      // regs = 2; if align == '11' then UNDEFINED;
11922      // when '0110'
11923      // regs = 3; if align<1> == '1' then UNDEFINED;
11924      // when '0010'
11925      // regs = 4;
11926      // otherwise
11927      // SEE 'Related encodings';
11928      uint32_t type = Bits32(opcode, 11, 8);
11929      uint32_t align = Bits32(opcode, 5, 4);
11930      if (type == 7) // '0111'
11931      {
11932        regs = 1;
11933        if (BitIsSet(align, 1))
11934          return false;
11935      } else if (type == 10) // '1010'
11936      {
11937        regs = 2;
11938        if (align == 3)
11939          return false;
11940
11941      } else if (type == 6) // '0110'
11942      {
11943        regs = 3;
11944        if (BitIsSet(align, 1))
11945          return false;
11946      } else if (type == 2) // '0010'
11947      {
11948        regs = 4;
11949      } else
11950        return false;
11951
11952      // alignment = if align == '00' then 1 else 4 << UInt(align);
11953      if (align == 0)
11954        alignment = 1;
11955      else
11956        alignment = 4 << align;
11957
11958      // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11959      ebytes = 1 << Bits32(opcode, 7, 6);
11960      esize = 8 * ebytes;
11961      elements = 8 / ebytes;
11962
11963      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11964      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11965      n = Bits32(opcode, 19, 15);
11966      m = Bits32(opcode, 3, 0);
11967
11968      // wback = (m != 15); register_index = (m != 15 && m != 13);
11969      wback = (m != 15);
11970      register_index = ((m != 15) && (m != 13));
11971
11972      // if d+regs > 32 then UNPREDICTABLE;
11973      if ((d + regs) > 32)
11974        return false;
11975    } break;
11976
11977    default:
11978      return false;
11979    }
11980
11981    RegisterInfo base_reg;
11982    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11983
11984    uint32_t Rn = ReadCoreReg(n, &success);
11985    if (!success)
11986      return false;
11987
11988    // address = R[n]; if (address MOD alignment) != 0 then
11989    // GenerateAlignmentException();
11990    addr_t address = Rn;
11991    if ((address % alignment) != 0)
11992      return false;
11993
11994    EmulateInstruction::Context context;
11995    // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11996    if (wback) {
11997      uint32_t Rm = ReadCoreReg(m, &success);
11998      if (!success)
11999        return false;
12000
12001      uint32_t offset;
12002      if (register_index)
12003        offset = Rm;
12004      else
12005        offset = 8 * regs;
12006
12007      uint32_t value = Rn + offset;
12008      context.type = eContextAdjustBaseRegister;
12009      context.SetRegisterPlusOffset(base_reg, offset);
12010
12011      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12012                                 value))
12013        return false;
12014    }
12015
12016    // for r = 0 to regs-1
12017    for (uint32_t r = 0; r < regs; ++r) {
12018      // for e = 0 to elements-1
12019      uint64_t assembled_data = 0;
12020      for (uint32_t e = 0; e < elements; ++e) {
12021        // Elem[D[d+r],e,esize] = MemU[address,ebytes];
12022        context.type = eContextRegisterLoad;
12023        context.SetRegisterPlusOffset(base_reg, address - Rn);
12024        uint64_t data = MemURead(context, address, ebytes, 0, &success);
12025        if (!success)
12026          return false;
12027
12028        assembled_data =
12029            (data << (e * esize)) |
12030            assembled_data; // New data goes to the left of existing data
12031
12032        // address = address + ebytes;
12033        address = address + ebytes;
12034      }
12035      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12036                                 assembled_data))
12037        return false;
12038    }
12039  }
12040  return true;
12041}
12042
12043// A8.6.308 VLD1 (single element to one lane)
12044//
12045bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
12046                                              const ARMEncoding encoding) {
12047#if 0
12048    if ConditionPassed() then
12049        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12050        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12051        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12052        Elem[D[d],index,esize] = MemU[address,ebytes];
12053#endif
12054
12055  bool success = false;
12056
12057  if (ConditionPassed(opcode)) {
12058    uint32_t ebytes;
12059    uint32_t esize;
12060    uint32_t index;
12061    uint32_t alignment;
12062    uint32_t d;
12063    uint32_t n;
12064    uint32_t m;
12065    bool wback;
12066    bool register_index;
12067
12068    switch (encoding) {
12069    case eEncodingT1:
12070    case eEncodingA1: {
12071      uint32_t size = Bits32(opcode, 11, 10);
12072      uint32_t index_align = Bits32(opcode, 7, 4);
12073      // if size == '11' then SEE VLD1 (single element to all lanes);
12074      if (size == 3)
12075        return EmulateVLD1SingleAll(opcode, encoding);
12076      // case size of
12077      if (size == 0) // when '00'
12078      {
12079        // if index_align<0> != '0' then UNDEFINED;
12080        if (BitIsClear(index_align, 0))
12081          return false;
12082
12083        // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12084        ebytes = 1;
12085        esize = 8;
12086        index = Bits32(index_align, 3, 1);
12087        alignment = 1;
12088      } else if (size == 1) // when '01'
12089      {
12090        // if index_align<1> != '0' then UNDEFINED;
12091        if (BitIsClear(index_align, 1))
12092          return false;
12093
12094        // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12095        ebytes = 2;
12096        esize = 16;
12097        index = Bits32(index_align, 3, 2);
12098
12099        // alignment = if index_align<0> == '0' then 1 else 2;
12100        if (BitIsClear(index_align, 0))
12101          alignment = 1;
12102        else
12103          alignment = 2;
12104      } else if (size == 2) // when '10'
12105      {
12106        // if index_align<2> != '0' then UNDEFINED;
12107        if (BitIsClear(index_align, 2))
12108          return false;
12109
12110        // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12111        // UNDEFINED;
12112        if ((Bits32(index_align, 1, 0) != 0) &&
12113            (Bits32(index_align, 1, 0) != 3))
12114          return false;
12115
12116        // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12117        ebytes = 4;
12118        esize = 32;
12119        index = Bit32(index_align, 3);
12120
12121        // alignment = if index_align<1:0> == '00' then 1 else 4;
12122        if (Bits32(index_align, 1, 0) == 0)
12123          alignment = 1;
12124        else
12125          alignment = 4;
12126      } else {
12127        return false;
12128      }
12129      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12130      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12131      n = Bits32(opcode, 19, 16);
12132      m = Bits32(opcode, 3, 0);
12133
12134      // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12135      // then UNPREDICTABLE;
12136      wback = (m != 15);
12137      register_index = ((m != 15) && (m != 13));
12138
12139      if (n == 15)
12140        return false;
12141
12142    } break;
12143
12144    default:
12145      return false;
12146    }
12147
12148    RegisterInfo base_reg;
12149    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12150
12151    uint32_t Rn = ReadCoreReg(n, &success);
12152    if (!success)
12153      return false;
12154
12155    // address = R[n]; if (address MOD alignment) != 0 then
12156    // GenerateAlignmentException();
12157    addr_t address = Rn;
12158    if ((address % alignment) != 0)
12159      return false;
12160
12161    EmulateInstruction::Context context;
12162    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12163    if (wback) {
12164      uint32_t Rm = ReadCoreReg(m, &success);
12165      if (!success)
12166        return false;
12167
12168      uint32_t offset;
12169      if (register_index)
12170        offset = Rm;
12171      else
12172        offset = ebytes;
12173
12174      uint32_t value = Rn + offset;
12175
12176      context.type = eContextAdjustBaseRegister;
12177      context.SetRegisterPlusOffset(base_reg, offset);
12178
12179      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12180                                 value))
12181        return false;
12182    }
12183
12184    // Elem[D[d],index,esize] = MemU[address,ebytes];
12185    uint32_t element = MemURead(context, address, esize, 0, &success);
12186    if (!success)
12187      return false;
12188
12189    element = element << (index * esize);
12190
12191    uint64_t reg_data =
12192        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12193    if (!success)
12194      return false;
12195
12196    uint64_t all_ones = -1;
12197    uint64_t mask = all_ones
12198                    << ((index + 1) * esize); // mask is all 1's to left of
12199                                              // where 'element' goes, & all 0's
12200    // at element & to the right of element.
12201    if (index > 0)
12202      mask = mask | Bits64(all_ones, (index * esize) - 1,
12203                           0); // add 1's to the right of where 'element' goes.
12204    // now mask should be 0's where element goes & 1's everywhere else.
12205
12206    uint64_t masked_reg =
12207        reg_data & mask; // Take original reg value & zero out 'element' bits
12208    reg_data =
12209        masked_reg & element; // Put 'element' into those bits in reg_data.
12210
12211    context.type = eContextRegisterLoad;
12212    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
12213                               reg_data))
12214      return false;
12215  }
12216  return true;
12217}
12218
12219// A8.6.391 VST1 (multiple single elements) Vector Store (multiple single
12220// elements) stores elements to memory from one, two, three, or four registers,
12221// without interleaving.  Every element of each register is stored.
12222bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
12223                                                ARMEncoding encoding) {
12224#if 0
12225    if ConditionPassed() then
12226        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12227        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12228        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12229        for r = 0 to regs-1
12230            for e = 0 to elements-1
12231                MemU[address,ebytes] = Elem[D[d+r],e,esize];
12232                address = address + ebytes;
12233#endif
12234
12235  bool success = false;
12236
12237  if (ConditionPassed(opcode)) {
12238    uint32_t regs;
12239    uint32_t alignment;
12240    uint32_t ebytes;
12241    uint32_t esize;
12242    uint32_t elements;
12243    uint32_t d;
12244    uint32_t n;
12245    uint32_t m;
12246    bool wback;
12247    bool register_index;
12248
12249    switch (encoding) {
12250    case eEncodingT1:
12251    case eEncodingA1: {
12252      uint32_t type = Bits32(opcode, 11, 8);
12253      uint32_t align = Bits32(opcode, 5, 4);
12254
12255      // case type of
12256      if (type == 7) // when '0111'
12257      {
12258        // regs = 1; if align<1> == '1' then UNDEFINED;
12259        regs = 1;
12260        if (BitIsSet(align, 1))
12261          return false;
12262      } else if (type == 10) // when '1010'
12263      {
12264        // regs = 2; if align == '11' then UNDEFINED;
12265        regs = 2;
12266        if (align == 3)
12267          return false;
12268      } else if (type == 6) // when '0110'
12269      {
12270        // regs = 3; if align<1> == '1' then UNDEFINED;
12271        regs = 3;
12272        if (BitIsSet(align, 1))
12273          return false;
12274      } else if (type == 2) // when '0010'
12275        // regs = 4;
12276        regs = 4;
12277      else // otherwise
12278        // SEE 'Related encodings';
12279        return false;
12280
12281      // alignment = if align == '00' then 1 else 4 << UInt(align);
12282      if (align == 0)
12283        alignment = 1;
12284      else
12285        alignment = 4 << align;
12286
12287      // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
12288      ebytes = 1 << Bits32(opcode, 7, 6);
12289      esize = 8 * ebytes;
12290      elements = 8 / ebytes;
12291
12292      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12293      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12294      n = Bits32(opcode, 19, 16);
12295      m = Bits32(opcode, 3, 0);
12296
12297      // wback = (m != 15); register_index = (m != 15 && m != 13);
12298      wback = (m != 15);
12299      register_index = ((m != 15) && (m != 13));
12300
12301      // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12302      if ((d + regs) > 32)
12303        return false;
12304
12305      if (n == 15)
12306        return false;
12307
12308    } break;
12309
12310    default:
12311      return false;
12312    }
12313
12314    RegisterInfo base_reg;
12315    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12316
12317    uint32_t Rn = ReadCoreReg(n, &success);
12318    if (!success)
12319      return false;
12320
12321    // address = R[n]; if (address MOD alignment) != 0 then
12322    // GenerateAlignmentException();
12323    addr_t address = Rn;
12324    if ((address % alignment) != 0)
12325      return false;
12326
12327    EmulateInstruction::Context context;
12328    // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12329    if (wback) {
12330      uint32_t Rm = ReadCoreReg(m, &success);
12331      if (!success)
12332        return false;
12333
12334      uint32_t offset;
12335      if (register_index)
12336        offset = Rm;
12337      else
12338        offset = 8 * regs;
12339
12340      context.type = eContextAdjustBaseRegister;
12341      context.SetRegisterPlusOffset(base_reg, offset);
12342
12343      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12344                                 Rn + offset))
12345        return false;
12346    }
12347
12348    RegisterInfo data_reg;
12349    context.type = eContextRegisterStore;
12350    // for r = 0 to regs-1
12351    for (uint32_t r = 0; r < regs; ++r) {
12352      GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
12353      uint64_t register_data = ReadRegisterUnsigned(
12354          eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
12355      if (!success)
12356        return false;
12357
12358      // for e = 0 to elements-1
12359      for (uint32_t e = 0; e < elements; ++e) {
12360        // MemU[address,ebytes] = Elem[D[d+r],e,esize];
12361        uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
12362
12363        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
12364                                                address - Rn);
12365        if (!MemUWrite(context, address, word, ebytes))
12366          return false;
12367
12368        // address = address + ebytes;
12369        address = address + ebytes;
12370      }
12371    }
12372  }
12373  return true;
12374}
12375
12376// A8.6.392 VST1 (single element from one lane) This instruction stores one
12377// element to memory from one element of a register.
12378bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
12379                                              ARMEncoding encoding) {
12380#if 0
12381    if ConditionPassed() then
12382        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12383        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12384        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12385        MemU[address,ebytes] = Elem[D[d],index,esize];
12386#endif
12387
12388  bool success = false;
12389
12390  if (ConditionPassed(opcode)) {
12391    uint32_t ebytes;
12392    uint32_t esize;
12393    uint32_t index;
12394    uint32_t alignment;
12395    uint32_t d;
12396    uint32_t n;
12397    uint32_t m;
12398    bool wback;
12399    bool register_index;
12400
12401    switch (encoding) {
12402    case eEncodingT1:
12403    case eEncodingA1: {
12404      uint32_t size = Bits32(opcode, 11, 10);
12405      uint32_t index_align = Bits32(opcode, 7, 4);
12406
12407      // if size == '11' then UNDEFINED;
12408      if (size == 3)
12409        return false;
12410
12411      // case size of
12412      if (size == 0) // when '00'
12413      {
12414        // if index_align<0> != '0' then UNDEFINED;
12415        if (BitIsClear(index_align, 0))
12416          return false;
12417        // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12418        ebytes = 1;
12419        esize = 8;
12420        index = Bits32(index_align, 3, 1);
12421        alignment = 1;
12422      } else if (size == 1) // when '01'
12423      {
12424        // if index_align<1> != '0' then UNDEFINED;
12425        if (BitIsClear(index_align, 1))
12426          return false;
12427
12428        // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12429        ebytes = 2;
12430        esize = 16;
12431        index = Bits32(index_align, 3, 2);
12432
12433        // alignment = if index_align<0> == '0' then 1 else 2;
12434        if (BitIsClear(index_align, 0))
12435          alignment = 1;
12436        else
12437          alignment = 2;
12438      } else if (size == 2) // when '10'
12439      {
12440        // if index_align<2> != '0' then UNDEFINED;
12441        if (BitIsClear(index_align, 2))
12442          return false;
12443
12444        // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12445        // UNDEFINED;
12446        if ((Bits32(index_align, 1, 0) != 0) &&
12447            (Bits32(index_align, 1, 0) != 3))
12448          return false;
12449
12450        // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12451        ebytes = 4;
12452        esize = 32;
12453        index = Bit32(index_align, 3);
12454
12455        // alignment = if index_align<1:0> == '00' then 1 else 4;
12456        if (Bits32(index_align, 1, 0) == 0)
12457          alignment = 1;
12458        else
12459          alignment = 4;
12460      } else {
12461        return false;
12462      }
12463      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12464      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12465      n = Bits32(opcode, 19, 16);
12466      m = Bits32(opcode, 3, 0);
12467
12468      // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15
12469      // then UNPREDICTABLE;
12470      wback = (m != 15);
12471      register_index = ((m != 15) && (m != 13));
12472
12473      if (n == 15)
12474        return false;
12475    } break;
12476
12477    default:
12478      return false;
12479    }
12480
12481    RegisterInfo base_reg;
12482    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12483
12484    uint32_t Rn = ReadCoreReg(n, &success);
12485    if (!success)
12486      return false;
12487
12488    // address = R[n]; if (address MOD alignment) != 0 then
12489    // GenerateAlignmentException();
12490    addr_t address = Rn;
12491    if ((address % alignment) != 0)
12492      return false;
12493
12494    EmulateInstruction::Context context;
12495    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12496    if (wback) {
12497      uint32_t Rm = ReadCoreReg(m, &success);
12498      if (!success)
12499        return false;
12500
12501      uint32_t offset;
12502      if (register_index)
12503        offset = Rm;
12504      else
12505        offset = ebytes;
12506
12507      context.type = eContextAdjustBaseRegister;
12508      context.SetRegisterPlusOffset(base_reg, offset);
12509
12510      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12511                                 Rn + offset))
12512        return false;
12513    }
12514
12515    // MemU[address,ebytes] = Elem[D[d],index,esize];
12516    uint64_t register_data =
12517        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12518    if (!success)
12519      return false;
12520
12521    uint64_t word =
12522        Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12523
12524    RegisterInfo data_reg;
12525    GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12526    context.type = eContextRegisterStore;
12527    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
12528
12529    if (!MemUWrite(context, address, word, ebytes))
12530      return false;
12531  }
12532  return true;
12533}
12534
12535// A8.6.309 VLD1 (single element to all lanes) This instruction loads one
12536// element from memory into every element of one or two vectors.
12537bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
12538                                                 const ARMEncoding encoding) {
12539#if 0
12540    if ConditionPassed() then
12541        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12542        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12543        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12544        replicated_element = Replicate(MemU[address,ebytes], elements);
12545        for r = 0 to regs-1
12546            D[d+r] = replicated_element;
12547#endif
12548
12549  bool success = false;
12550
12551  if (ConditionPassed(opcode)) {
12552    uint32_t ebytes;
12553    uint32_t elements;
12554    uint32_t regs;
12555    uint32_t alignment;
12556    uint32_t d;
12557    uint32_t n;
12558    uint32_t m;
12559    bool wback;
12560    bool register_index;
12561
12562    switch (encoding) {
12563    case eEncodingT1:
12564    case eEncodingA1: {
12565      // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12566      uint32_t size = Bits32(opcode, 7, 6);
12567      if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
12568        return false;
12569
12570      // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
12571      // then 1 else 2;
12572      ebytes = 1 << size;
12573      elements = 8 / ebytes;
12574      if (BitIsClear(opcode, 5))
12575        regs = 1;
12576      else
12577        regs = 2;
12578
12579      // alignment = if a == '0' then 1 else ebytes;
12580      if (BitIsClear(opcode, 4))
12581        alignment = 1;
12582      else
12583        alignment = ebytes;
12584
12585      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12586      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12587      n = Bits32(opcode, 19, 16);
12588      m = Bits32(opcode, 3, 0);
12589
12590      // wback = (m != 15); register_index = (m != 15 && m != 13);
12591      wback = (m != 15);
12592      register_index = ((m != 15) && (m != 13));
12593
12594      // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12595      if ((d + regs) > 32)
12596        return false;
12597
12598      if (n == 15)
12599        return false;
12600    } break;
12601
12602    default:
12603      return false;
12604    }
12605
12606    RegisterInfo base_reg;
12607    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12608
12609    uint32_t Rn = ReadCoreReg(n, &success);
12610    if (!success)
12611      return false;
12612
12613    // address = R[n]; if (address MOD alignment) != 0 then
12614    // GenerateAlignmentException();
12615    addr_t address = Rn;
12616    if ((address % alignment) != 0)
12617      return false;
12618
12619    EmulateInstruction::Context context;
12620    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12621    if (wback) {
12622      uint32_t Rm = ReadCoreReg(m, &success);
12623      if (!success)
12624        return false;
12625
12626      uint32_t offset;
12627      if (register_index)
12628        offset = Rm;
12629      else
12630        offset = ebytes;
12631
12632      context.type = eContextAdjustBaseRegister;
12633      context.SetRegisterPlusOffset(base_reg, offset);
12634
12635      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12636                                 Rn + offset))
12637        return false;
12638    }
12639
12640    // replicated_element = Replicate(MemU[address,ebytes], elements);
12641
12642    context.type = eContextRegisterLoad;
12643    uint64_t word = MemURead(context, address, ebytes, 0, &success);
12644    if (!success)
12645      return false;
12646
12647    uint64_t replicated_element = 0;
12648    uint32_t esize = ebytes * 8;
12649    for (uint32_t e = 0; e < elements; ++e)
12650      replicated_element =
12651          (replicated_element << esize) | Bits64(word, esize - 1, 0);
12652
12653    // for r = 0 to regs-1
12654    for (uint32_t r = 0; r < regs; ++r) {
12655      // D[d+r] = replicated_element;
12656      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12657                                 replicated_element))
12658        return false;
12659    }
12660  }
12661  return true;
12662}
12663
12664// B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const?
12665// instruction provides an exception return without the use of the stack.  It
12666// subtracts the immediate constant from the LR, branches to the resulting
12667// address, and also copies the SPSR to the CPSR.
12668bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
12669                                               const ARMEncoding encoding) {
12670#if 0
12671    if ConditionPassed() then
12672        EncodingSpecificOperations();
12673        if CurrentInstrSet() == InstrSet_ThumbEE then
12674            UNPREDICTABLE;
12675        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12676        case opcode of
12677            when '0000' result = R[n] AND operand2; // AND
12678            when '0001' result = R[n] EOR operand2; // EOR
12679            when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12680            when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12681            when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12682            when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12683            when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12684            when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12685            when '1100' result = R[n] OR operand2; // ORR
12686            when '1101' result = operand2; // MOV
12687            when '1110' result = R[n] AND NOT(operand2); // BIC
12688            when '1111' result = NOT(operand2); // MVN
12689        CPSRWriteByInstr(SPSR[], '1111', TRUE);
12690        BranchWritePC(result);
12691#endif
12692
12693  bool success = false;
12694
12695  if (ConditionPassed(opcode)) {
12696    uint32_t n;
12697    uint32_t m;
12698    uint32_t imm32;
12699    bool register_form;
12700    ARM_ShifterType shift_t;
12701    uint32_t shift_n;
12702    uint32_t code;
12703
12704    switch (encoding) {
12705    case eEncodingT1:
12706      // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14;
12707      // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010';
12708      // // = SUB
12709      n = 14;
12710      imm32 = Bits32(opcode, 7, 0);
12711      register_form = false;
12712      code = 2;
12713
12714      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12715      if (InITBlock() && !LastInITBlock())
12716        return false;
12717
12718      break;
12719
12720    case eEncodingA1:
12721      // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12722      n = Bits32(opcode, 19, 16);
12723      imm32 = ARMExpandImm(opcode);
12724      register_form = false;
12725      code = Bits32(opcode, 24, 21);
12726
12727      break;
12728
12729    case eEncodingA2:
12730      // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12731      n = Bits32(opcode, 19, 16);
12732      m = Bits32(opcode, 3, 0);
12733      register_form = true;
12734
12735      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12736      shift_n = DecodeImmShiftARM(opcode, shift_t);
12737
12738      break;
12739
12740    default:
12741      return false;
12742    }
12743
12744    // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
12745    // else imm32;
12746    uint32_t operand2;
12747    if (register_form) {
12748      uint32_t Rm = ReadCoreReg(m, &success);
12749      if (!success)
12750        return false;
12751
12752      operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
12753      if (!success)
12754        return false;
12755    } else {
12756      operand2 = imm32;
12757    }
12758
12759    uint32_t Rn = ReadCoreReg(n, &success);
12760    if (!success)
12761      return false;
12762
12763    AddWithCarryResult result;
12764
12765    // case opcode of
12766    switch (code) {
12767    case 0: // when '0000'
12768      // result = R[n] AND operand2; // AND
12769      result.result = Rn & operand2;
12770      break;
12771
12772    case 1: // when '0001'
12773      // result = R[n] EOR operand2; // EOR
12774      result.result = Rn ^ operand2;
12775      break;
12776
12777    case 2: // when '0010'
12778      // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12779      result = AddWithCarry(Rn, ~(operand2), 1);
12780      break;
12781
12782    case 3: // when '0011'
12783      // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12784      result = AddWithCarry(~(Rn), operand2, 1);
12785      break;
12786
12787    case 4: // when '0100'
12788      // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12789      result = AddWithCarry(Rn, operand2, 0);
12790      break;
12791
12792    case 5: // when '0101'
12793      // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12794      result = AddWithCarry(Rn, operand2, APSR_C);
12795      break;
12796
12797    case 6: // when '0110'
12798      // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12799      result = AddWithCarry(Rn, ~(operand2), APSR_C);
12800      break;
12801
12802    case 7: // when '0111'
12803      // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12804      result = AddWithCarry(~(Rn), operand2, APSR_C);
12805      break;
12806
12807    case 10: // when '1100'
12808      // result = R[n] OR operand2; // ORR
12809      result.result = Rn | operand2;
12810      break;
12811
12812    case 11: // when '1101'
12813      // result = operand2; // MOV
12814      result.result = operand2;
12815      break;
12816
12817    case 12: // when '1110'
12818      // result = R[n] AND NOT(operand2); // BIC
12819      result.result = Rn & ~(operand2);
12820      break;
12821
12822    case 15: // when '1111'
12823      // result = NOT(operand2); // MVN
12824      result.result = ~(operand2);
12825      break;
12826
12827    default:
12828      return false;
12829    }
12830    // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12831
12832    // For now, in emulation mode, we don't have access to the SPSR, so we will
12833    // use the CPSR instead, and hope for the best.
12834    uint32_t spsr =
12835        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12836    if (!success)
12837      return false;
12838
12839    CPSRWriteByInstr(spsr, 15, true);
12840
12841    // BranchWritePC(result);
12842    EmulateInstruction::Context context;
12843    context.type = eContextAdjustPC;
12844    context.SetImmediate(result.result);
12845
12846    BranchWritePC(context, result.result);
12847  }
12848  return true;
12849}
12850
12851EmulateInstructionARM::ARMOpcode *
12852EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
12853                                                  uint32_t arm_isa) {
12854  static ARMOpcode g_arm_opcodes[] = {
12855      // Prologue instructions
12856
12857      // push register(s)
12858      {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12859       &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12860      {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12861       &EmulateInstructionARM::EmulatePUSH, "push <register>"},
12862
12863      // set r7 to point to a stack offset
12864      {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12865       &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
12866      {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12867       &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12868      // copy the stack pointer to ip
12869      {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
12870       &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
12871      {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12872       &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
12873      {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12874       &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12875
12876      // adjust the stack pointer
12877      {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12878       &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12879      {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12880       &EmulateInstructionARM::EmulateSUBSPReg,
12881       "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12882
12883      // push one register
12884      // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12885      {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12886       &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
12887
12888      // vector push consecutive extension register(s)
12889      {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12890       &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12891      {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12892       &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12893
12894      // Epilogue instructions
12895
12896      {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12897       &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12898      {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12899       &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12900      {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12901       &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12902      {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12903       &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12904
12905      // Supervisor Call (previously Software Interrupt)
12906      {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12907       &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12908
12909      // Branch instructions
12910      // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
12911      // "bl <label>".
12912      {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
12913       &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12914      {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12915       &EmulateInstructionARM::EmulateB, "b #imm24"},
12916      {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12917       &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12918      {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
12919       &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12920      // for example, "bx lr"
12921      {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
12922       &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12923      // bxj
12924      {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
12925       &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12926
12927      // Data-processing instructions
12928      // adc (immediate)
12929      {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12930       &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12931      // adc (register)
12932      {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12933       &EmulateInstructionARM::EmulateADCReg,
12934       "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12935      // add (immediate)
12936      {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12937       &EmulateInstructionARM::EmulateADDImmARM,
12938       "add{s}<c> <Rd>, <Rn>, #const"},
12939      // add (register)
12940      {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12941       &EmulateInstructionARM::EmulateADDReg,
12942       "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12943      // add (register-shifted register)
12944      {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
12945       &EmulateInstructionARM::EmulateADDRegShift,
12946       "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12947      // adr
12948      {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12949       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12950      {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
12951       &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12952      // and (immediate)
12953      {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12954       &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12955      // and (register)
12956      {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12957       &EmulateInstructionARM::EmulateANDReg,
12958       "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12959      // bic (immediate)
12960      {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12961       &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12962      // bic (register)
12963      {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12964       &EmulateInstructionARM::EmulateBICReg,
12965       "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12966      // eor (immediate)
12967      {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12968       &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12969      // eor (register)
12970      {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12971       &EmulateInstructionARM::EmulateEORReg,
12972       "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12973      // orr (immediate)
12974      {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12975       &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12976      // orr (register)
12977      {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12978       &EmulateInstructionARM::EmulateORRReg,
12979       "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12980      // rsb (immediate)
12981      {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12982       &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12983      // rsb (register)
12984      {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12985       &EmulateInstructionARM::EmulateRSBReg,
12986       "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12987      // rsc (immediate)
12988      {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12989       &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12990      // rsc (register)
12991      {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12992       &EmulateInstructionARM::EmulateRSCReg,
12993       "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12994      // sbc (immediate)
12995      {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12996       &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12997      // sbc (register)
12998      {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12999       &EmulateInstructionARM::EmulateSBCReg,
13000       "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13001      // sub (immediate, ARM)
13002      {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13003       &EmulateInstructionARM::EmulateSUBImmARM,
13004       "sub{s}<c> <Rd>, <Rn>, #<const>"},
13005      // sub (sp minus immediate)
13006      {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13007       &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
13008      // sub (register)
13009      {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13010       &EmulateInstructionARM::EmulateSUBReg,
13011       "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
13012      // teq (immediate)
13013      {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13014       &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
13015      // teq (register)
13016      {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13017       &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13018      // tst (immediate)
13019      {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13020       &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
13021      // tst (register)
13022      {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13023       &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
13024
13025      // mov (immediate)
13026      {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13027       &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
13028      {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
13029       &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
13030      // mov (register)
13031      {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13032       &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
13033      // mvn (immediate)
13034      {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13035       &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
13036      // mvn (register)
13037      {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13038       &EmulateInstructionARM::EmulateMVNReg,
13039       "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
13040      // cmn (immediate)
13041      {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13042       &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13043      // cmn (register)
13044      {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13045       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13046      // cmp (immediate)
13047      {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13048       &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
13049      // cmp (register)
13050      {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13051       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
13052      // asr (immediate)
13053      {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
13054       &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
13055      // asr (register)
13056      {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13057       &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
13058      // lsl (immediate)
13059      {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13060       &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
13061      // lsl (register)
13062      {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
13063       &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
13064      // lsr (immediate)
13065      {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
13066       &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
13067      // lsr (register)
13068      {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13069       &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
13070      // rrx is a special case encoding of ror (immediate)
13071      {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13072       &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
13073      // ror (immediate)
13074      {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13075       &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
13076      // ror (register)
13077      {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
13078       &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
13079      // mul
13080      {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
13081       &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
13082
13083      // subs pc, lr and related instructions
13084      {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13085       &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13086       "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
13087      {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
13088       &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13089       "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
13090
13091      // Load instructions
13092      {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13093       &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13094      {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13095       &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
13096      {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13097       &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13098      {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13099       &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
13100      {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13101       &EmulateInstructionARM::EmulateLDRImmediateARM,
13102       "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
13103      {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13104       &EmulateInstructionARM::EmulateLDRRegister,
13105       "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
13106      {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13107       &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
13108      {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13109       &EmulateInstructionARM::EmulateLDRBRegister,
13110       "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
13111      {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13112       &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13113      {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13114       &EmulateInstructionARM::EmulateLDRHRegister,
13115       "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13116      {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13117       &EmulateInstructionARM::EmulateLDRSBImmediate,
13118       "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
13119      {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13120       &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
13121      {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13122       &EmulateInstructionARM::EmulateLDRSBRegister,
13123       "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13124      {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13125       &EmulateInstructionARM::EmulateLDRSHImmediate,
13126       "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
13127      {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13128       &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13129      {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13130       &EmulateInstructionARM::EmulateLDRSHRegister,
13131       "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13132      {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13133       &EmulateInstructionARM::EmulateLDRDImmediate,
13134       "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
13135      {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13136       &EmulateInstructionARM::EmulateLDRDRegister,
13137       "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13138      {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13139       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13140      {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13141       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13142      {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13143       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13144      {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13145       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13146      {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13147       &EmulateInstructionARM::EmulateVLD1Multiple,
13148       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13149      {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13150       &EmulateInstructionARM::EmulateVLD1Single,
13151       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13152      {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13153       &EmulateInstructionARM::EmulateVLD1SingleAll,
13154       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13155
13156      // Store instructions
13157      {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13158       &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13159      {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13160       &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
13161      {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13162       &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13163      {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13164       &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
13165      {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13166       &EmulateInstructionARM::EmulateSTRRegister,
13167       "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
13168      {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13169       &EmulateInstructionARM::EmulateSTRHRegister,
13170       "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
13171      {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13172       &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
13173      {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13174       &EmulateInstructionARM::EmulateSTRBImmARM,
13175       "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13176      {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13177       &EmulateInstructionARM::EmulateSTRImmARM,
13178       "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13179      {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13180       &EmulateInstructionARM::EmulateSTRDImm,
13181       "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
13182      {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13183       &EmulateInstructionARM::EmulateSTRDReg,
13184       "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13185      {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13186       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13187      {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13188       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13189      {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13190       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
13191      {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13192       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
13193      {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13194       &EmulateInstructionARM::EmulateVST1Multiple,
13195       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13196      {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13197       &EmulateInstructionARM::EmulateVST1Single,
13198       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13199
13200      // Other instructions
13201      {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13202       &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
13203      {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13204       &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
13205      {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13206       &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
13207      {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13208       &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
13209      {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13210       &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
13211
13212  };
13213  static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
13214
13215  for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
13216    if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
13217        (g_arm_opcodes[i].variants & arm_isa) != 0)
13218      return &g_arm_opcodes[i];
13219  }
13220  return nullptr;
13221}
13222
13223EmulateInstructionARM::ARMOpcode *
13224EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
13225                                                    uint32_t arm_isa) {
13226
13227  static ARMOpcode g_thumb_opcodes[] = {
13228      // Prologue instructions
13229
13230      // push register(s)
13231      {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
13232       &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
13233      {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13234       &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
13235      {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13236       &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
13237
13238      // set r7 to point to a stack offset
13239      {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13240       &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
13241      // copy the stack pointer to r7
13242      {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
13243       &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
13244      // move from high register to low register (comes after "mov r7, sp" to
13245      // resolve ambiguity)
13246      {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
13247       &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
13248
13249      // PC-relative load into register (see also EmulateADDSPRm)
13250      {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13251       &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
13252
13253      // adjust the stack pointer
13254      {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
13255       &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
13256      {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13257       &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
13258      {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13259       &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
13260      {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13261       &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
13262      {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13263       &EmulateInstructionARM::EmulateSUBSPReg,
13264       "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
13265
13266      // vector push consecutive extension register(s)
13267      {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13268       &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
13269      {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13270       &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
13271
13272      // Epilogue instructions
13273
13274      {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13275       &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
13276      {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13277       &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
13278      {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13279       &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
13280      {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13281       &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
13282      {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13283       &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
13284      {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13285       &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
13286      {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13287       &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
13288
13289      // Supervisor Call (previously Software Interrupt)
13290      {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13291       &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
13292
13293      // If Then makes up to four following instructions conditional.
13294      // The next 5 opcode _must_ come before the if then instruction
13295      {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13296       &EmulateInstructionARM::EmulateNop, "nop"},
13297      {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13298       &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
13299      {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13300       &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
13301      {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13302       &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
13303      {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13304       &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
13305      {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13306       &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
13307
13308      // Branch instructions
13309      // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
13310      {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13311       &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
13312      {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13313       &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
13314      {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13315       &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
13316      {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13317       &EmulateInstructionARM::EmulateB,
13318       "b<c>.w #imm8 (outside or last in IT)"},
13319      // J1 == J2 == 1
13320      {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
13321       &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
13322      // J1 == J2 == 1
13323      {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
13324       &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
13325      {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
13326       &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
13327      // for example, "bx lr"
13328      {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
13329       &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
13330      // bxj
13331      {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
13332       &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
13333      // compare and branch
13334      {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13335       &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
13336      // table branch byte
13337      {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13338       &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
13339      // table branch halfword
13340      {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13341       &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
13342
13343      // Data-processing instructions
13344      // adc (immediate)
13345      {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13346       &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
13347      // adc (register)
13348      {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
13349       &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
13350      {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13351       &EmulateInstructionARM::EmulateADCReg,
13352       "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13353      // add (register)
13354      {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13355       &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
13356      // Make sure "add sp, <Rm>" comes before this instruction, so there's no
13357      // ambiguity decoding the two.
13358      {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
13359       &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
13360      // adr
13361      {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13362       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13363      {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13364       &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
13365      {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13366       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13367      // and (immediate)
13368      {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13369       &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
13370      // and (register)
13371      {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13372       &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
13373      {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13374       &EmulateInstructionARM::EmulateANDReg,
13375       "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13376      // bic (immediate)
13377      {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13378       &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
13379      // bic (register)
13380      {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
13381       &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
13382      {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13383       &EmulateInstructionARM::EmulateBICReg,
13384       "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13385      // eor (immediate)
13386      {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13387       &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
13388      // eor (register)
13389      {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
13390       &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
13391      {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13392       &EmulateInstructionARM::EmulateEORReg,
13393       "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13394      // orr (immediate)
13395      {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13396       &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
13397      // orr (register)
13398      {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
13399       &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
13400      {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13401       &EmulateInstructionARM::EmulateORRReg,
13402       "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13403      // rsb (immediate)
13404      {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
13405       &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
13406      {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13407       &EmulateInstructionARM::EmulateRSBImm,
13408       "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
13409      // rsb (register)
13410      {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13411       &EmulateInstructionARM::EmulateRSBReg,
13412       "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13413      // sbc (immediate)
13414      {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13415       &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13416      // sbc (register)
13417      {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
13418       &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
13419      {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13420       &EmulateInstructionARM::EmulateSBCReg,
13421       "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13422      // add (immediate, Thumb)
13423      {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13424       &EmulateInstructionARM::EmulateADDImmThumb,
13425       "adds|add<c> <Rd>,<Rn>,#<imm3>"},
13426      {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13427       &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
13428      {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13429       &EmulateInstructionARM::EmulateADDImmThumb,
13430       "add{s}<c>.w <Rd>,<Rn>,#<const>"},
13431      {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13432       &EmulateInstructionARM::EmulateADDImmThumb,
13433       "addw<c> <Rd>,<Rn>,#<imm12>"},
13434      // sub (immediate, Thumb)
13435      {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13436       &EmulateInstructionARM::EmulateSUBImmThumb,
13437       "subs|sub<c> <Rd>, <Rn> #imm3"},
13438      {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
13439       &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
13440      {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13441       &EmulateInstructionARM::EmulateSUBImmThumb,
13442       "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13443      {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13444       &EmulateInstructionARM::EmulateSUBImmThumb,
13445       "subw<c> <Rd>, <Rn>, #imm12"},
13446      // sub (sp minus immediate)
13447      {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13448       &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
13449      {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13450       &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
13451      // sub (register)
13452      {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13453       &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
13454      {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13455       &EmulateInstructionARM::EmulateSUBReg,
13456       "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13457      // teq (immediate)
13458      {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13459       &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
13460      // teq (register)
13461      {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13462       &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13463      // tst (immediate)
13464      {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13465       &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
13466      // tst (register)
13467      {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
13468       &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
13469      {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13470       &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
13471
13472      // move from high register to high register
13473      {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
13474       &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
13475      // move from low register to low register
13476      {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13477       &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
13478      // mov{s}<c>.w <Rd>, <Rm>
13479      {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13480       &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
13481      // move immediate
13482      {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13483       &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
13484      {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13485       &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
13486      {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13487       &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
13488      // mvn (immediate)
13489      {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13490       &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
13491      // mvn (register)
13492      {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13493       &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
13494      {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13495       &EmulateInstructionARM::EmulateMVNReg,
13496       "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13497      // cmn (immediate)
13498      {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13499       &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13500      // cmn (register)
13501      {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13502       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
13503      {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13504       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13505      // cmp (immediate)
13506      {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13507       &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
13508      {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13509       &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
13510      // cmp (register) (Rn and Rm both from r0-r7)
13511      {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
13512       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13513      // cmp (register) (Rn and Rm not both from r0-r7)
13514      {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
13515       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13516      {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
13517       &EmulateInstructionARM::EmulateCMPReg,
13518       "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13519      // asr (immediate)
13520      {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13521       &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
13522      {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13523       &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
13524      // asr (register)
13525      {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
13526       &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
13527      {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13528       &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13529      // lsl (immediate)
13530      {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13531       &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
13532      {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13533       &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
13534      // lsl (register)
13535      {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13536       &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
13537      {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13538       &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
13539      // lsr (immediate)
13540      {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13541       &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
13542      {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13543       &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
13544      // lsr (register)
13545      {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13546       &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
13547      {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13548       &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13549      // rrx is a special case encoding of ror (immediate)
13550      {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13551       &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
13552      // ror (immediate)
13553      {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13554       &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
13555      // ror (register)
13556      {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13557       &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
13558      {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13559       &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
13560      // mul
13561      {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13562       &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
13563      // mul
13564      {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13565       &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
13566
13567      // subs pc, lr and related instructions
13568      {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13569       &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
13570
13571      // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
13572      // LDM.. Instructions in this table;
13573      // otherwise the wrong instructions will be selected.
13574
13575      {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13576       &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
13577      {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13578       &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
13579
13580      // Load instructions
13581      {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13582       &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13583      {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13584       &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
13585      {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13586       &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13587      {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13588       &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
13589      {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13590       &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
13591      {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13592       &EmulateInstructionARM::EmulateLDRRtRnImm,
13593       "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13594      {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13595       &EmulateInstructionARM::EmulateLDRRtRnImm,
13596       "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13597      // Thumb2 PC-relative load into register
13598      {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13599       &EmulateInstructionARM::EmulateLDRRtPCRelative,
13600       "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13601      {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13602       &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
13603      {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13604       &EmulateInstructionARM::EmulateLDRRegister,
13605       "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13606      {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13607       &EmulateInstructionARM::EmulateLDRBImmediate,
13608       "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13609      {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13610       &EmulateInstructionARM::EmulateLDRBImmediate,
13611       "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13612      {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13613       &EmulateInstructionARM::EmulateLDRBImmediate,
13614       "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13615      {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13616       &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
13617      {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13618       &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
13619      {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13620       &EmulateInstructionARM::EmulateLDRBRegister,
13621       "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13622      {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13623       &EmulateInstructionARM::EmulateLDRHImmediate,
13624       "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13625      {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13626       &EmulateInstructionARM::EmulateLDRHImmediate,
13627       "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13628      {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13629       &EmulateInstructionARM::EmulateLDRHImmediate,
13630       "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13631      {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13632       &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13633      {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13634       &EmulateInstructionARM::EmulateLDRHRegister,
13635       "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13636      {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13637       &EmulateInstructionARM::EmulateLDRHRegister,
13638       "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13639      {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13640       &EmulateInstructionARM::EmulateLDRSBImmediate,
13641       "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13642      {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13643       &EmulateInstructionARM::EmulateLDRSBImmediate,
13644       "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13645      {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13646       &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
13647      {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13648       &EmulateInstructionARM::EmulateLDRSBRegister,
13649       "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13650      {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13651       &EmulateInstructionARM::EmulateLDRSBRegister,
13652       "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13653      {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13654       &EmulateInstructionARM::EmulateLDRSHImmediate,
13655       "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13656      {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13657       &EmulateInstructionARM::EmulateLDRSHImmediate,
13658       "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13659      {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13660       &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13661      {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13662       &EmulateInstructionARM::EmulateLDRSHRegister,
13663       "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13664      {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13665       &EmulateInstructionARM::EmulateLDRSHRegister,
13666       "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13667      {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13668       &EmulateInstructionARM::EmulateLDRDImmediate,
13669       "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13670      {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13671       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13672      {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13673       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13674      {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13675       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13676      {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13677       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
13678      {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13679       &EmulateInstructionARM::EmulateVLD1Multiple,
13680       "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13681      {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13682       &EmulateInstructionARM::EmulateVLD1Single,
13683       "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13684      {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13685       &EmulateInstructionARM::EmulateVLD1SingleAll,
13686       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13687
13688      // Store instructions
13689      {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13690       &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13691      {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13692       &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
13693      {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13694       &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13695      {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13696       &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
13697      {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13698       &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
13699      {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13700       &EmulateInstructionARM::EmulateSTRThumb,
13701       "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13702      {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13703       &EmulateInstructionARM::EmulateSTRThumb,
13704       "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13705      {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13706       &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
13707      {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13708       &EmulateInstructionARM::EmulateSTRRegister,
13709       "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13710      {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13711       &EmulateInstructionARM::EmulateSTRBThumb,
13712       "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13713      {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13714       &EmulateInstructionARM::EmulateSTRBThumb,
13715       "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13716      {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13717       &EmulateInstructionARM::EmulateSTRBThumb,
13718       "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13719      {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13720       &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
13721      {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13722       &EmulateInstructionARM::EmulateSTRHRegister,
13723       "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13724      {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13725       &EmulateInstructionARM::EmulateSTREX,
13726       "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13727      {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13728       &EmulateInstructionARM::EmulateSTRDImm,
13729       "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13730      {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13731       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13732      {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13733       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13734      {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13735       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13736      {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13737       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13738      {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13739       &EmulateInstructionARM::EmulateVST1Multiple,
13740       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13741      {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13742       &EmulateInstructionARM::EmulateVST1Single,
13743       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13744
13745      // Other instructions
13746      {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13747       &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
13748      {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
13749       &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13750      {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13751       &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
13752      {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13753       &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13754      {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13755       &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
13756      {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13757       &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13758      {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13759       &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
13760      {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13761       &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13762  };
13763
13764  const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
13765  for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13766    if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13767        (g_thumb_opcodes[i].variants & arm_isa) != 0)
13768      return &g_thumb_opcodes[i];
13769  }
13770  return nullptr;
13771}
13772
13773bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
13774  m_arch = arch;
13775  m_arm_isa = 0;
13776  const char *arch_cstr = arch.GetArchitectureName();
13777  if (arch_cstr) {
13778    if (0 == ::strcasecmp(arch_cstr, "armv4t"))
13779      m_arm_isa = ARMv4T;
13780    else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))
13781      m_arm_isa = ARMv5TEJ;
13782    else if (0 == ::strcasecmp(arch_cstr, "armv5te"))
13783      m_arm_isa = ARMv5TE;
13784    else if (0 == ::strcasecmp(arch_cstr, "armv5t"))
13785      m_arm_isa = ARMv5T;
13786    else if (0 == ::strcasecmp(arch_cstr, "armv6k"))
13787      m_arm_isa = ARMv6K;
13788    else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))
13789      m_arm_isa = ARMv6T2;
13790    else if (0 == ::strcasecmp(arch_cstr, "armv7s"))
13791      m_arm_isa = ARMv7S;
13792    else if (0 == ::strcasecmp(arch_cstr, "arm"))
13793      m_arm_isa = ARMvAll;
13794    else if (0 == ::strcasecmp(arch_cstr, "thumb"))
13795      m_arm_isa = ARMvAll;
13796    else if (0 == ::strncasecmp(arch_cstr, "armv4", 5))
13797      m_arm_isa = ARMv4;
13798    else if (0 == ::strncasecmp(arch_cstr, "armv6", 5))
13799      m_arm_isa = ARMv6;
13800    else if (0 == ::strncasecmp(arch_cstr, "armv7", 5))
13801      m_arm_isa = ARMv7;
13802    else if (0 == ::strncasecmp(arch_cstr, "armv8", 5))
13803      m_arm_isa = ARMv8;
13804  }
13805  return m_arm_isa != 0;
13806}
13807
13808bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
13809                                           const Address &inst_addr,
13810                                           Target *target) {
13811  if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
13812    if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
13813        m_arch.IsAlwaysThumbInstructions())
13814      m_opcode_mode = eModeThumb;
13815    else {
13816      AddressClass addr_class = inst_addr.GetAddressClass();
13817
13818      if ((addr_class == AddressClass::eCode) ||
13819          (addr_class == AddressClass::eUnknown))
13820        m_opcode_mode = eModeARM;
13821      else if (addr_class == AddressClass::eCodeAlternateISA)
13822        m_opcode_mode = eModeThumb;
13823      else
13824        return false;
13825    }
13826    if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
13827      m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13828    else
13829      m_opcode_cpsr = CPSR_MODE_USR;
13830    return true;
13831  }
13832  return false;
13833}
13834
13835bool EmulateInstructionARM::ReadInstruction() {
13836  bool success = false;
13837  m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
13838                                       LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13839  if (success) {
13840    addr_t pc =
13841        ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
13842                             LLDB_INVALID_ADDRESS, &success);
13843    if (success) {
13844      Context read_inst_context;
13845      read_inst_context.type = eContextReadOpcode;
13846      read_inst_context.SetNoArgs();
13847
13848      if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
13849        m_opcode_mode = eModeThumb;
13850        uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13851
13852        if (success) {
13853          if ((thumb_opcode & 0xe000) != 0xe000 ||
13854              ((thumb_opcode & 0x1800u) == 0)) {
13855            m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
13856          } else {
13857            m_opcode.SetOpcode32(
13858                (thumb_opcode << 16) |
13859                    MemARead(read_inst_context, pc + 2, 2, 0, &success),
13860                GetByteOrder());
13861          }
13862        }
13863      } else {
13864        m_opcode_mode = eModeARM;
13865        m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
13866                             GetByteOrder());
13867      }
13868
13869      if (!m_ignore_conditions) {
13870        // If we are not ignoreing the conditions then init the it session from
13871        // the current value of cpsr.
13872        uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
13873                      Bits32(m_opcode_cpsr, 26, 25);
13874        if (it != 0)
13875          m_it_session.InitIT(it);
13876      }
13877    }
13878  }
13879  if (!success) {
13880    m_opcode_mode = eModeInvalid;
13881    m_addr = LLDB_INVALID_ADDRESS;
13882  }
13883  return success;
13884}
13885
13886uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
13887
13888bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
13889  // If we are ignoring conditions, then always return true. this allows us to
13890  // iterate over disassembly code and still emulate an instruction even if we
13891  // don't have all the right bits set in the CPSR register...
13892  if (m_ignore_conditions)
13893    return true;
13894
13895  const uint32_t cond = CurrentCond(opcode);
13896  if (cond == UINT32_MAX)
13897    return false;
13898
13899  bool result = false;
13900  switch (UnsignedBits(cond, 3, 1)) {
13901  case 0:
13902    if (m_opcode_cpsr == 0)
13903      result = true;
13904    else
13905      result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13906    break;
13907  case 1:
13908    if (m_opcode_cpsr == 0)
13909      result = true;
13910    else
13911      result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13912    break;
13913  case 2:
13914    if (m_opcode_cpsr == 0)
13915      result = true;
13916    else
13917      result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13918    break;
13919  case 3:
13920    if (m_opcode_cpsr == 0)
13921      result = true;
13922    else
13923      result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13924    break;
13925  case 4:
13926    if (m_opcode_cpsr == 0)
13927      result = true;
13928    else
13929      result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
13930               ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13931    break;
13932  case 5:
13933    if (m_opcode_cpsr == 0)
13934      result = true;
13935    else {
13936      bool n = (m_opcode_cpsr & MASK_CPSR_N);
13937      bool v = (m_opcode_cpsr & MASK_CPSR_V);
13938      result = n == v;
13939    }
13940    break;
13941  case 6:
13942    if (m_opcode_cpsr == 0)
13943      result = true;
13944    else {
13945      bool n = (m_opcode_cpsr & MASK_CPSR_N);
13946      bool v = (m_opcode_cpsr & MASK_CPSR_V);
13947      result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13948    }
13949    break;
13950  case 7:
13951    // Always execute (cond == 0b1110, or the special 0b1111 which gives
13952    // opcodes different meanings, but always means execution happens.
13953    return true;
13954  }
13955
13956  if (cond & 1)
13957    result = !result;
13958  return result;
13959}
13960
13961uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
13962  switch (m_opcode_mode) {
13963  case eModeInvalid:
13964    break;
13965
13966  case eModeARM:
13967    return UnsignedBits(opcode, 31, 28);
13968
13969  case eModeThumb:
13970    // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13971    // 'cond' field of the encoding.
13972    {
13973      const uint32_t byte_size = m_opcode.GetByteSize();
13974      if (byte_size == 2) {
13975        if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13976          return Bits32(opcode, 11, 8);
13977      } else if (byte_size == 4) {
13978        if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
13979            Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
13980          return Bits32(opcode, 25, 22);
13981        }
13982      } else
13983        // We have an invalid thumb instruction, let's bail out.
13984        break;
13985
13986      return m_it_session.GetCond();
13987    }
13988  }
13989  return UINT32_MAX; // Return invalid value
13990}
13991
13992bool EmulateInstructionARM::InITBlock() {
13993  return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13994}
13995
13996bool EmulateInstructionARM::LastInITBlock() {
13997  return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13998}
13999
14000bool EmulateInstructionARM::BadMode(uint32_t mode) {
14001
14002  switch (mode) {
14003  case 16:
14004    return false; // '10000'
14005  case 17:
14006    return false; // '10001'
14007  case 18:
14008    return false; // '10010'
14009  case 19:
14010    return false; // '10011'
14011  case 22:
14012    return false; // '10110'
14013  case 23:
14014    return false; // '10111'
14015  case 27:
14016    return false; // '11011'
14017  case 31:
14018    return false; // '11111'
14019  default:
14020    return true;
14021  }
14022  return true;
14023}
14024
14025bool EmulateInstructionARM::CurrentModeIsPrivileged() {
14026  uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
14027
14028  if (BadMode(mode))
14029    return false;
14030
14031  if (mode == 16)
14032    return false;
14033
14034  return true;
14035}
14036
14037void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
14038                                             bool affect_execstate) {
14039  bool privileged = CurrentModeIsPrivileged();
14040
14041  uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
14042
14043  if (BitIsSet(bytemask, 3)) {
14044    tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
14045    if (affect_execstate)
14046      tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
14047  }
14048
14049  if (BitIsSet(bytemask, 2)) {
14050    tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
14051  }
14052
14053  if (BitIsSet(bytemask, 1)) {
14054    if (affect_execstate)
14055      tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
14056    tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
14057    if (privileged)
14058      tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
14059  }
14060
14061  if (BitIsSet(bytemask, 0)) {
14062    if (privileged)
14063      tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
14064    if (affect_execstate)
14065      tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
14066    if (privileged)
14067      tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
14068  }
14069
14070  m_opcode_cpsr = tmp_cpsr;
14071}
14072
14073bool EmulateInstructionARM::BranchWritePC(const Context &context,
14074                                          uint32_t addr) {
14075  addr_t target;
14076
14077  // Check the current instruction set.
14078  if (CurrentInstrSet() == eModeARM)
14079    target = addr & 0xfffffffc;
14080  else
14081    target = addr & 0xfffffffe;
14082
14083  return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14084                               LLDB_REGNUM_GENERIC_PC, target);
14085}
14086
14087// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
14088// inspecting addr.
14089bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
14090  addr_t target;
14091  // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
14092  // we want to record it and issue a WriteRegister callback so the clients can
14093  // track the mode changes accordingly.
14094  bool cpsr_changed = false;
14095
14096  if (BitIsSet(addr, 0)) {
14097    if (CurrentInstrSet() != eModeThumb) {
14098      SelectInstrSet(eModeThumb);
14099      cpsr_changed = true;
14100    }
14101    target = addr & 0xfffffffe;
14102    context.SetISA(eModeThumb);
14103  } else if (BitIsClear(addr, 1)) {
14104    if (CurrentInstrSet() != eModeARM) {
14105      SelectInstrSet(eModeARM);
14106      cpsr_changed = true;
14107    }
14108    target = addr & 0xfffffffc;
14109    context.SetISA(eModeARM);
14110  } else
14111    return false; // address<1:0> == '10' => UNPREDICTABLE
14112
14113  if (cpsr_changed) {
14114    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14115                               LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14116      return false;
14117  }
14118  return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14119                               LLDB_REGNUM_GENERIC_PC, target);
14120}
14121
14122// Dispatches to either BXWritePC or BranchWritePC based on architecture
14123// versions.
14124bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
14125  if (ArchVersion() >= ARMv5T)
14126    return BXWritePC(context, addr);
14127  else
14128    return BranchWritePC((const Context)context, addr);
14129}
14130
14131// Dispatches to either BXWritePC or BranchWritePC based on architecture
14132// versions and current instruction set.
14133bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
14134  if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
14135    return BXWritePC(context, addr);
14136  else
14137    return BranchWritePC((const Context)context, addr);
14138}
14139
14140EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
14141  return m_opcode_mode;
14142}
14143
14144// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
14145// ReadInstruction() is performed.  This function has a side effect of updating
14146// the m_new_inst_cpsr member variable if necessary.
14147bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
14148  m_new_inst_cpsr = m_opcode_cpsr;
14149  switch (arm_or_thumb) {
14150  default:
14151    return false;
14152  case eModeARM:
14153    // Clear the T bit.
14154    m_new_inst_cpsr &= ~MASK_CPSR_T;
14155    break;
14156  case eModeThumb:
14157    // Set the T bit.
14158    m_new_inst_cpsr |= MASK_CPSR_T;
14159    break;
14160  }
14161  return true;
14162}
14163
14164// This function returns TRUE if the processor currently provides support for
14165// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
14166// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
14167bool EmulateInstructionARM::UnalignedSupport() {
14168  return (ArchVersion() >= ARMv7);
14169}
14170
14171// The main addition and subtraction instructions can produce status
14172// information about both unsigned carry and signed overflow conditions.  This
14173// status information can be used to synthesize multi-word additions and
14174// subtractions.
14175EmulateInstructionARM::AddWithCarryResult
14176EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
14177  uint32_t result;
14178  uint8_t carry_out;
14179  uint8_t overflow;
14180
14181  uint64_t unsigned_sum = x + y + carry_in;
14182  int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
14183
14184  result = UnsignedBits(unsigned_sum, 31, 0);
14185  //    carry_out = (result == unsigned_sum ? 0 : 1);
14186  overflow = ((int32_t)result == signed_sum ? 0 : 1);
14187
14188  if (carry_in)
14189    carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
14190  else
14191    carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
14192
14193  AddWithCarryResult res = {result, carry_out, overflow};
14194  return res;
14195}
14196
14197uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
14198  lldb::RegisterKind reg_kind;
14199  uint32_t reg_num;
14200  switch (num) {
14201  case SP_REG:
14202    reg_kind = eRegisterKindGeneric;
14203    reg_num = LLDB_REGNUM_GENERIC_SP;
14204    break;
14205  case LR_REG:
14206    reg_kind = eRegisterKindGeneric;
14207    reg_num = LLDB_REGNUM_GENERIC_RA;
14208    break;
14209  case PC_REG:
14210    reg_kind = eRegisterKindGeneric;
14211    reg_num = LLDB_REGNUM_GENERIC_PC;
14212    break;
14213  default:
14214    if (num < SP_REG) {
14215      reg_kind = eRegisterKindDWARF;
14216      reg_num = dwarf_r0 + num;
14217    } else {
14218      // assert(0 && "Invalid register number");
14219      *success = false;
14220      return UINT32_MAX;
14221    }
14222    break;
14223  }
14224
14225  // Read our register.
14226  uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
14227
14228  // When executing an ARM instruction , PC reads as the address of the current
14229  // instruction plus 8. When executing a Thumb instruction , PC reads as the
14230  // address of the current instruction plus 4.
14231  if (num == 15) {
14232    if (CurrentInstrSet() == eModeARM)
14233      val += 8;
14234    else
14235      val += 4;
14236  }
14237
14238  return val;
14239}
14240
14241// Write the result to the ARM core register Rd, and optionally update the
14242// condition flags based on the result.
14243//
14244// This helper method tries to encapsulate the following pseudocode from the
14245// ARM Architecture Reference Manual:
14246//
14247// if d == 15 then         // Can only occur for encoding A1
14248//     ALUWritePC(result); // setflags is always FALSE here
14249// else
14250//     R[d] = result;
14251//     if setflags then
14252//         APSR.N = result<31>;
14253//         APSR.Z = IsZeroBit(result);
14254//         APSR.C = carry;
14255//         // APSR.V unchanged
14256//
14257// In the above case, the API client does not pass in the overflow arg, which
14258// defaults to ~0u.
14259bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
14260    Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
14261    const uint32_t carry, const uint32_t overflow) {
14262  if (Rd == 15) {
14263    if (!ALUWritePC(context, result))
14264      return false;
14265  } else {
14266    lldb::RegisterKind reg_kind;
14267    uint32_t reg_num;
14268    switch (Rd) {
14269    case SP_REG:
14270      reg_kind = eRegisterKindGeneric;
14271      reg_num = LLDB_REGNUM_GENERIC_SP;
14272      break;
14273    case LR_REG:
14274      reg_kind = eRegisterKindGeneric;
14275      reg_num = LLDB_REGNUM_GENERIC_RA;
14276      break;
14277    default:
14278      reg_kind = eRegisterKindDWARF;
14279      reg_num = dwarf_r0 + Rd;
14280    }
14281    if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
14282      return false;
14283    if (setflags)
14284      return WriteFlags(context, result, carry, overflow);
14285  }
14286  return true;
14287}
14288
14289// This helper method tries to encapsulate the following pseudocode from the
14290// ARM Architecture Reference Manual:
14291//
14292// APSR.N = result<31>;
14293// APSR.Z = IsZeroBit(result);
14294// APSR.C = carry;
14295// APSR.V = overflow
14296//
14297// Default arguments can be specified for carry and overflow parameters, which
14298// means not to update the respective flags.
14299bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
14300                                       const uint32_t carry,
14301                                       const uint32_t overflow) {
14302  m_new_inst_cpsr = m_opcode_cpsr;
14303  SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
14304  SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
14305  if (carry != ~0u)
14306    SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
14307  if (overflow != ~0u)
14308    SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
14309  if (m_new_inst_cpsr != m_opcode_cpsr) {
14310    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14311                               LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14312      return false;
14313  }
14314  return true;
14315}
14316
14317bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
14318  ARMOpcode *opcode_data = nullptr;
14319
14320  if (m_opcode_mode == eModeThumb)
14321    opcode_data =
14322        GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14323  else if (m_opcode_mode == eModeARM)
14324    opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14325
14326  const bool auto_advance_pc =
14327      evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
14328  m_ignore_conditions =
14329      evaluate_options & eEmulateInstructionOptionIgnoreConditions;
14330
14331  bool success = false;
14332  if (m_opcode_cpsr == 0 || !m_ignore_conditions) {
14333    m_opcode_cpsr =
14334        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
14335  }
14336
14337  // Only return false if we are unable to read the CPSR if we care about
14338  // conditions
14339  if (!success && !m_ignore_conditions)
14340    return false;
14341
14342  uint32_t orig_pc_value = 0;
14343  if (auto_advance_pc) {
14344    orig_pc_value =
14345        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14346    if (!success)
14347      return false;
14348  }
14349
14350  // Call the Emulate... function if we managed to decode the opcode.
14351  if (opcode_data) {
14352    success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
14353                                             opcode_data->encoding);
14354    if (!success)
14355      return false;
14356  }
14357
14358  // Advance the ITSTATE bits to their values for the next instruction if we
14359  // haven't just executed an IT instruction what initialized it.
14360  if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
14361      (opcode_data == nullptr ||
14362       opcode_data->callback != &EmulateInstructionARM::EmulateIT))
14363    m_it_session.ITAdvance();
14364
14365  if (auto_advance_pc) {
14366    uint32_t after_pc_value =
14367        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14368    if (!success)
14369      return false;
14370
14371    if (auto_advance_pc && (after_pc_value == orig_pc_value)) {
14372      after_pc_value += m_opcode.GetByteSize();
14373
14374      EmulateInstruction::Context context;
14375      context.type = eContextAdvancePC;
14376      context.SetNoArgs();
14377      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
14378                                 after_pc_value))
14379        return false;
14380    }
14381  }
14382  return true;
14383}
14384
14385EmulateInstruction::InstructionCondition
14386EmulateInstructionARM::GetInstructionCondition() {
14387  const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
14388  if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
14389    return EmulateInstruction::UnconditionalCondition;
14390  return cond;
14391}
14392
14393bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch,
14394                                          OptionValueDictionary *test_data) {
14395  if (!test_data) {
14396    out_stream->Printf("TestEmulation: Missing test data.\n");
14397    return false;
14398  }
14399
14400  static ConstString opcode_key("opcode");
14401  static ConstString before_key("before_state");
14402  static ConstString after_key("after_state");
14403
14404  OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
14405
14406  uint32_t test_opcode;
14407  if ((value_sp.get() == nullptr) ||
14408      (value_sp->GetType() != OptionValue::eTypeUInt64)) {
14409    out_stream->Printf("TestEmulation: Error reading opcode from test file.\n");
14410    return false;
14411  }
14412  test_opcode = value_sp->GetUInt64Value();
14413
14414  if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
14415      arch.IsAlwaysThumbInstructions()) {
14416    m_opcode_mode = eModeThumb;
14417    if (test_opcode < 0x10000)
14418      m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
14419    else
14420      m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14421  } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
14422    m_opcode_mode = eModeARM;
14423    m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14424  } else {
14425    out_stream->Printf("TestEmulation:  Invalid arch.\n");
14426    return false;
14427  }
14428
14429  EmulationStateARM before_state;
14430  EmulationStateARM after_state;
14431
14432  value_sp = test_data->GetValueForKey(before_key);
14433  if ((value_sp.get() == nullptr) ||
14434      (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14435    out_stream->Printf("TestEmulation:  Failed to find 'before' state.\n");
14436    return false;
14437  }
14438
14439  OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
14440  if (!before_state.LoadStateFromDictionary(state_dictionary)) {
14441    out_stream->Printf("TestEmulation:  Failed loading 'before' state.\n");
14442    return false;
14443  }
14444
14445  value_sp = test_data->GetValueForKey(after_key);
14446  if ((value_sp.get() == nullptr) ||
14447      (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14448    out_stream->Printf("TestEmulation:  Failed to find 'after' state.\n");
14449    return false;
14450  }
14451
14452  state_dictionary = value_sp->GetAsDictionary();
14453  if (!after_state.LoadStateFromDictionary(state_dictionary)) {
14454    out_stream->Printf("TestEmulation: Failed loading 'after' state.\n");
14455    return false;
14456  }
14457
14458  SetBaton((void *)&before_state);
14459  SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
14460               &EmulationStateARM::WritePseudoMemory,
14461               &EmulationStateARM::ReadPseudoRegister,
14462               &EmulationStateARM::WritePseudoRegister);
14463
14464  bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
14465  if (!success) {
14466    out_stream->Printf("TestEmulation:  EvaluateInstruction() failed.\n");
14467    return false;
14468  }
14469
14470  success = before_state.CompareState(after_state);
14471  if (!success)
14472    out_stream->Printf(
14473        "TestEmulation:  'before' and 'after' states do not match.\n");
14474
14475  return success;
14476}
14477//
14478//
14479// const char *
14480// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
14481//{
14482//    if (reg_kind == eRegisterKindGeneric)
14483//    {
14484//        switch (reg_num)
14485//        {
14486//        case LLDB_REGNUM_GENERIC_PC:    return "pc";
14487//        case LLDB_REGNUM_GENERIC_SP:    return "sp";
14488//        case LLDB_REGNUM_GENERIC_FP:    return "fp";
14489//        case LLDB_REGNUM_GENERIC_RA:    return "lr";
14490//        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
14491//        default: return NULL;
14492//        }
14493//    }
14494//    else if (reg_kind == eRegisterKindDWARF)
14495//    {
14496//        return GetARMDWARFRegisterName (reg_num);
14497//    }
14498//    return NULL;
14499//}
14500//
14501bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
14502  unwind_plan.Clear();
14503  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
14504
14505  UnwindPlan::RowSP row(new UnwindPlan::Row);
14506
14507  // Our previous Call Frame Address is the stack pointer
14508  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
14509
14510  unwind_plan.AppendRow(row);
14511  unwind_plan.SetSourceName("EmulateInstructionARM");
14512  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
14513  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
14514  unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
14515  unwind_plan.SetReturnAddressRegister(dwarf_lr);
14516  return true;
14517}
14518