Coverage Report

Created: 2022-01-15 10:30

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