Coverage Report

Created: 2023-09-12 09:32

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