Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
39648 views
1
//===-- EmulateInstructionMIPS.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 "EmulateInstructionMIPS.h"
10
11
#include <cstdlib>
12
#include <optional>
13
14
#include "lldb/Core/Address.h"
15
#include "lldb/Core/Opcode.h"
16
#include "lldb/Core/PluginManager.h"
17
#include "lldb/Symbol/UnwindPlan.h"
18
#include "lldb/Target/Target.h"
19
#include "lldb/Utility/ArchSpec.h"
20
#include "lldb/Utility/ConstString.h"
21
#include "lldb/Utility/DataExtractor.h"
22
#include "lldb/Utility/RegisterValue.h"
23
#include "lldb/Utility/Stream.h"
24
#include "llvm-c/Disassembler.h"
25
#include "llvm/MC/MCAsmInfo.h"
26
#include "llvm/MC/MCContext.h"
27
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
28
#include "llvm/MC/MCInst.h"
29
#include "llvm/MC/MCInstrInfo.h"
30
#include "llvm/MC/MCRegisterInfo.h"
31
#include "llvm/MC/MCSubtargetInfo.h"
32
#include "llvm/MC/MCTargetOptions.h"
33
#include "llvm/MC/TargetRegistry.h"
34
#include "llvm/Support/TargetSelect.h"
35
36
#include "llvm/ADT/STLExtras.h"
37
38
#include "Plugins/Process/Utility/InstructionUtils.h"
39
#include "Plugins/Process/Utility/RegisterContext_mips.h"
40
41
using namespace lldb;
42
using namespace lldb_private;
43
44
LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionMIPS, InstructionMIPS)
45
46
#define UInt(x) ((uint64_t)x)
47
#define integer int64_t
48
49
//
50
// EmulateInstructionMIPS implementation
51
//
52
53
#ifdef __mips__
54
extern "C" {
55
void LLVMInitializeMipsTargetInfo();
56
void LLVMInitializeMipsTarget();
57
void LLVMInitializeMipsAsmPrinter();
58
void LLVMInitializeMipsTargetMC();
59
void LLVMInitializeMipsDisassembler();
60
}
61
#endif
62
63
EmulateInstructionMIPS::EmulateInstructionMIPS(
64
const lldb_private::ArchSpec &arch)
65
: EmulateInstruction(arch) {
66
/* Create instance of llvm::MCDisassembler */
67
std::string Status;
68
llvm::Triple triple = arch.GetTriple();
69
const llvm::Target *target =
70
llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status);
71
72
/*
73
* If we fail to get the target then we haven't registered it. The
74
* SystemInitializerCommon
75
* does not initialize targets, MCs and disassemblers. However we need the
76
* MCDisassembler
77
* to decode the instructions so that the decoding complexity stays with LLVM.
78
* Initialize the MIPS targets and disassemblers.
79
*/
80
#ifdef __mips__
81
if (!target) {
82
LLVMInitializeMipsTargetInfo();
83
LLVMInitializeMipsTarget();
84
LLVMInitializeMipsAsmPrinter();
85
LLVMInitializeMipsTargetMC();
86
LLVMInitializeMipsDisassembler();
87
target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status);
88
}
89
#endif
90
91
assert(target);
92
93
llvm::StringRef cpu;
94
95
switch (arch.GetCore()) {
96
case ArchSpec::eCore_mips32:
97
case ArchSpec::eCore_mips32el:
98
cpu = "mips32";
99
break;
100
case ArchSpec::eCore_mips32r2:
101
case ArchSpec::eCore_mips32r2el:
102
cpu = "mips32r2";
103
break;
104
case ArchSpec::eCore_mips32r3:
105
case ArchSpec::eCore_mips32r3el:
106
cpu = "mips32r3";
107
break;
108
case ArchSpec::eCore_mips32r5:
109
case ArchSpec::eCore_mips32r5el:
110
cpu = "mips32r5";
111
break;
112
case ArchSpec::eCore_mips32r6:
113
case ArchSpec::eCore_mips32r6el:
114
cpu = "mips32r6";
115
break;
116
case ArchSpec::eCore_mips64:
117
case ArchSpec::eCore_mips64el:
118
cpu = "mips64";
119
break;
120
case ArchSpec::eCore_mips64r2:
121
case ArchSpec::eCore_mips64r2el:
122
cpu = "mips64r2";
123
break;
124
case ArchSpec::eCore_mips64r3:
125
case ArchSpec::eCore_mips64r3el:
126
cpu = "mips64r3";
127
break;
128
case ArchSpec::eCore_mips64r5:
129
case ArchSpec::eCore_mips64r5el:
130
cpu = "mips64r5";
131
break;
132
case ArchSpec::eCore_mips64r6:
133
case ArchSpec::eCore_mips64r6el:
134
cpu = "mips64r6";
135
break;
136
default:
137
cpu = "generic";
138
break;
139
}
140
141
std::string features;
142
uint32_t arch_flags = arch.GetFlags();
143
if (arch_flags & ArchSpec::eMIPSAse_msa)
144
features += "+msa,";
145
if (arch_flags & ArchSpec::eMIPSAse_dsp)
146
features += "+dsp,";
147
if (arch_flags & ArchSpec::eMIPSAse_dspr2)
148
features += "+dspr2,";
149
150
m_reg_info.reset(target->createMCRegInfo(triple.getTriple()));
151
assert(m_reg_info.get());
152
153
m_insn_info.reset(target->createMCInstrInfo());
154
assert(m_insn_info.get());
155
156
llvm::MCTargetOptions MCOptions;
157
m_asm_info.reset(
158
target->createMCAsmInfo(*m_reg_info, triple.getTriple(), MCOptions));
159
m_subtype_info.reset(
160
target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
161
assert(m_asm_info.get() && m_subtype_info.get());
162
163
m_context = std::make_unique<llvm::MCContext>(
164
triple, m_asm_info.get(), m_reg_info.get(), m_subtype_info.get());
165
assert(m_context.get());
166
167
m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
168
assert(m_disasm.get());
169
170
/* Create alternate disassembler for microMIPS */
171
if (arch_flags & ArchSpec::eMIPSAse_mips16)
172
features += "+mips16,";
173
else if (arch_flags & ArchSpec::eMIPSAse_micromips)
174
features += "+micromips,";
175
176
m_alt_subtype_info.reset(
177
target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
178
assert(m_alt_subtype_info.get());
179
180
m_alt_disasm.reset(
181
target->createMCDisassembler(*m_alt_subtype_info, *m_context));
182
assert(m_alt_disasm.get());
183
184
m_next_inst_size = 0;
185
m_use_alt_disaasm = false;
186
}
187
188
void EmulateInstructionMIPS::Initialize() {
189
PluginManager::RegisterPlugin(GetPluginNameStatic(),
190
GetPluginDescriptionStatic(), CreateInstance);
191
}
192
193
void EmulateInstructionMIPS::Terminate() {
194
PluginManager::UnregisterPlugin(CreateInstance);
195
}
196
197
llvm::StringRef EmulateInstructionMIPS::GetPluginDescriptionStatic() {
198
return "Emulate instructions for the MIPS32 architecture.";
199
}
200
201
EmulateInstruction *
202
EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch,
203
InstructionType inst_type) {
204
if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(
205
inst_type)) {
206
if (arch.GetTriple().getArch() == llvm::Triple::mips ||
207
arch.GetTriple().getArch() == llvm::Triple::mipsel) {
208
return new EmulateInstructionMIPS(arch);
209
}
210
}
211
212
return nullptr;
213
}
214
215
bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) {
216
return arch.GetTriple().getArch() == llvm::Triple::mips ||
217
arch.GetTriple().getArch() == llvm::Triple::mipsel;
218
}
219
220
const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num,
221
bool alternate_name) {
222
if (alternate_name) {
223
switch (reg_num) {
224
case dwarf_sp_mips:
225
return "r29";
226
case dwarf_r30_mips:
227
return "r30";
228
case dwarf_ra_mips:
229
return "r31";
230
case dwarf_f0_mips:
231
return "f0";
232
case dwarf_f1_mips:
233
return "f1";
234
case dwarf_f2_mips:
235
return "f2";
236
case dwarf_f3_mips:
237
return "f3";
238
case dwarf_f4_mips:
239
return "f4";
240
case dwarf_f5_mips:
241
return "f5";
242
case dwarf_f6_mips:
243
return "f6";
244
case dwarf_f7_mips:
245
return "f7";
246
case dwarf_f8_mips:
247
return "f8";
248
case dwarf_f9_mips:
249
return "f9";
250
case dwarf_f10_mips:
251
return "f10";
252
case dwarf_f11_mips:
253
return "f11";
254
case dwarf_f12_mips:
255
return "f12";
256
case dwarf_f13_mips:
257
return "f13";
258
case dwarf_f14_mips:
259
return "f14";
260
case dwarf_f15_mips:
261
return "f15";
262
case dwarf_f16_mips:
263
return "f16";
264
case dwarf_f17_mips:
265
return "f17";
266
case dwarf_f18_mips:
267
return "f18";
268
case dwarf_f19_mips:
269
return "f19";
270
case dwarf_f20_mips:
271
return "f20";
272
case dwarf_f21_mips:
273
return "f21";
274
case dwarf_f22_mips:
275
return "f22";
276
case dwarf_f23_mips:
277
return "f23";
278
case dwarf_f24_mips:
279
return "f24";
280
case dwarf_f25_mips:
281
return "f25";
282
case dwarf_f26_mips:
283
return "f26";
284
case dwarf_f27_mips:
285
return "f27";
286
case dwarf_f28_mips:
287
return "f28";
288
case dwarf_f29_mips:
289
return "f29";
290
case dwarf_f30_mips:
291
return "f30";
292
case dwarf_f31_mips:
293
return "f31";
294
case dwarf_w0_mips:
295
return "w0";
296
case dwarf_w1_mips:
297
return "w1";
298
case dwarf_w2_mips:
299
return "w2";
300
case dwarf_w3_mips:
301
return "w3";
302
case dwarf_w4_mips:
303
return "w4";
304
case dwarf_w5_mips:
305
return "w5";
306
case dwarf_w6_mips:
307
return "w6";
308
case dwarf_w7_mips:
309
return "w7";
310
case dwarf_w8_mips:
311
return "w8";
312
case dwarf_w9_mips:
313
return "w9";
314
case dwarf_w10_mips:
315
return "w10";
316
case dwarf_w11_mips:
317
return "w11";
318
case dwarf_w12_mips:
319
return "w12";
320
case dwarf_w13_mips:
321
return "w13";
322
case dwarf_w14_mips:
323
return "w14";
324
case dwarf_w15_mips:
325
return "w15";
326
case dwarf_w16_mips:
327
return "w16";
328
case dwarf_w17_mips:
329
return "w17";
330
case dwarf_w18_mips:
331
return "w18";
332
case dwarf_w19_mips:
333
return "w19";
334
case dwarf_w20_mips:
335
return "w20";
336
case dwarf_w21_mips:
337
return "w21";
338
case dwarf_w22_mips:
339
return "w22";
340
case dwarf_w23_mips:
341
return "w23";
342
case dwarf_w24_mips:
343
return "w24";
344
case dwarf_w25_mips:
345
return "w25";
346
case dwarf_w26_mips:
347
return "w26";
348
case dwarf_w27_mips:
349
return "w27";
350
case dwarf_w28_mips:
351
return "w28";
352
case dwarf_w29_mips:
353
return "w29";
354
case dwarf_w30_mips:
355
return "w30";
356
case dwarf_w31_mips:
357
return "w31";
358
case dwarf_mir_mips:
359
return "mir";
360
case dwarf_mcsr_mips:
361
return "mcsr";
362
case dwarf_config5_mips:
363
return "config5";
364
default:
365
break;
366
}
367
return nullptr;
368
}
369
370
switch (reg_num) {
371
case dwarf_zero_mips:
372
return "r0";
373
case dwarf_r1_mips:
374
return "r1";
375
case dwarf_r2_mips:
376
return "r2";
377
case dwarf_r3_mips:
378
return "r3";
379
case dwarf_r4_mips:
380
return "r4";
381
case dwarf_r5_mips:
382
return "r5";
383
case dwarf_r6_mips:
384
return "r6";
385
case dwarf_r7_mips:
386
return "r7";
387
case dwarf_r8_mips:
388
return "r8";
389
case dwarf_r9_mips:
390
return "r9";
391
case dwarf_r10_mips:
392
return "r10";
393
case dwarf_r11_mips:
394
return "r11";
395
case dwarf_r12_mips:
396
return "r12";
397
case dwarf_r13_mips:
398
return "r13";
399
case dwarf_r14_mips:
400
return "r14";
401
case dwarf_r15_mips:
402
return "r15";
403
case dwarf_r16_mips:
404
return "r16";
405
case dwarf_r17_mips:
406
return "r17";
407
case dwarf_r18_mips:
408
return "r18";
409
case dwarf_r19_mips:
410
return "r19";
411
case dwarf_r20_mips:
412
return "r20";
413
case dwarf_r21_mips:
414
return "r21";
415
case dwarf_r22_mips:
416
return "r22";
417
case dwarf_r23_mips:
418
return "r23";
419
case dwarf_r24_mips:
420
return "r24";
421
case dwarf_r25_mips:
422
return "r25";
423
case dwarf_r26_mips:
424
return "r26";
425
case dwarf_r27_mips:
426
return "r27";
427
case dwarf_gp_mips:
428
return "gp";
429
case dwarf_sp_mips:
430
return "sp";
431
case dwarf_r30_mips:
432
return "fp";
433
case dwarf_ra_mips:
434
return "ra";
435
case dwarf_sr_mips:
436
return "sr";
437
case dwarf_lo_mips:
438
return "lo";
439
case dwarf_hi_mips:
440
return "hi";
441
case dwarf_bad_mips:
442
return "bad";
443
case dwarf_cause_mips:
444
return "cause";
445
case dwarf_pc_mips:
446
return "pc";
447
case dwarf_f0_mips:
448
return "f0";
449
case dwarf_f1_mips:
450
return "f1";
451
case dwarf_f2_mips:
452
return "f2";
453
case dwarf_f3_mips:
454
return "f3";
455
case dwarf_f4_mips:
456
return "f4";
457
case dwarf_f5_mips:
458
return "f5";
459
case dwarf_f6_mips:
460
return "f6";
461
case dwarf_f7_mips:
462
return "f7";
463
case dwarf_f8_mips:
464
return "f8";
465
case dwarf_f9_mips:
466
return "f9";
467
case dwarf_f10_mips:
468
return "f10";
469
case dwarf_f11_mips:
470
return "f11";
471
case dwarf_f12_mips:
472
return "f12";
473
case dwarf_f13_mips:
474
return "f13";
475
case dwarf_f14_mips:
476
return "f14";
477
case dwarf_f15_mips:
478
return "f15";
479
case dwarf_f16_mips:
480
return "f16";
481
case dwarf_f17_mips:
482
return "f17";
483
case dwarf_f18_mips:
484
return "f18";
485
case dwarf_f19_mips:
486
return "f19";
487
case dwarf_f20_mips:
488
return "f20";
489
case dwarf_f21_mips:
490
return "f21";
491
case dwarf_f22_mips:
492
return "f22";
493
case dwarf_f23_mips:
494
return "f23";
495
case dwarf_f24_mips:
496
return "f24";
497
case dwarf_f25_mips:
498
return "f25";
499
case dwarf_f26_mips:
500
return "f26";
501
case dwarf_f27_mips:
502
return "f27";
503
case dwarf_f28_mips:
504
return "f28";
505
case dwarf_f29_mips:
506
return "f29";
507
case dwarf_f30_mips:
508
return "f30";
509
case dwarf_f31_mips:
510
return "f31";
511
case dwarf_fcsr_mips:
512
return "fcsr";
513
case dwarf_fir_mips:
514
return "fir";
515
case dwarf_w0_mips:
516
return "w0";
517
case dwarf_w1_mips:
518
return "w1";
519
case dwarf_w2_mips:
520
return "w2";
521
case dwarf_w3_mips:
522
return "w3";
523
case dwarf_w4_mips:
524
return "w4";
525
case dwarf_w5_mips:
526
return "w5";
527
case dwarf_w6_mips:
528
return "w6";
529
case dwarf_w7_mips:
530
return "w7";
531
case dwarf_w8_mips:
532
return "w8";
533
case dwarf_w9_mips:
534
return "w9";
535
case dwarf_w10_mips:
536
return "w10";
537
case dwarf_w11_mips:
538
return "w11";
539
case dwarf_w12_mips:
540
return "w12";
541
case dwarf_w13_mips:
542
return "w13";
543
case dwarf_w14_mips:
544
return "w14";
545
case dwarf_w15_mips:
546
return "w15";
547
case dwarf_w16_mips:
548
return "w16";
549
case dwarf_w17_mips:
550
return "w17";
551
case dwarf_w18_mips:
552
return "w18";
553
case dwarf_w19_mips:
554
return "w19";
555
case dwarf_w20_mips:
556
return "w20";
557
case dwarf_w21_mips:
558
return "w21";
559
case dwarf_w22_mips:
560
return "w22";
561
case dwarf_w23_mips:
562
return "w23";
563
case dwarf_w24_mips:
564
return "w24";
565
case dwarf_w25_mips:
566
return "w25";
567
case dwarf_w26_mips:
568
return "w26";
569
case dwarf_w27_mips:
570
return "w27";
571
case dwarf_w28_mips:
572
return "w28";
573
case dwarf_w29_mips:
574
return "w29";
575
case dwarf_w30_mips:
576
return "w30";
577
case dwarf_w31_mips:
578
return "w31";
579
case dwarf_mcsr_mips:
580
return "mcsr";
581
case dwarf_mir_mips:
582
return "mir";
583
case dwarf_config5_mips:
584
return "config5";
585
}
586
return nullptr;
587
}
588
589
std::optional<RegisterInfo>
590
EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind,
591
uint32_t reg_num) {
592
if (reg_kind == eRegisterKindGeneric) {
593
switch (reg_num) {
594
case LLDB_REGNUM_GENERIC_PC:
595
reg_kind = eRegisterKindDWARF;
596
reg_num = dwarf_pc_mips;
597
break;
598
case LLDB_REGNUM_GENERIC_SP:
599
reg_kind = eRegisterKindDWARF;
600
reg_num = dwarf_sp_mips;
601
break;
602
case LLDB_REGNUM_GENERIC_FP:
603
reg_kind = eRegisterKindDWARF;
604
reg_num = dwarf_r30_mips;
605
break;
606
case LLDB_REGNUM_GENERIC_RA:
607
reg_kind = eRegisterKindDWARF;
608
reg_num = dwarf_ra_mips;
609
break;
610
case LLDB_REGNUM_GENERIC_FLAGS:
611
reg_kind = eRegisterKindDWARF;
612
reg_num = dwarf_sr_mips;
613
break;
614
default:
615
return {};
616
}
617
}
618
619
if (reg_kind == eRegisterKindDWARF) {
620
RegisterInfo reg_info;
621
::memset(&reg_info, 0, sizeof(RegisterInfo));
622
::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
623
624
if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips ||
625
reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips ||
626
reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) {
627
reg_info.byte_size = 4;
628
reg_info.format = eFormatHex;
629
reg_info.encoding = eEncodingUint;
630
} else if ((int)reg_num >= dwarf_zero_mips &&
631
(int)reg_num <= dwarf_f31_mips) {
632
reg_info.byte_size = 4;
633
reg_info.format = eFormatHex;
634
reg_info.encoding = eEncodingUint;
635
} else if ((int)reg_num >= dwarf_w0_mips &&
636
(int)reg_num <= dwarf_w31_mips) {
637
reg_info.byte_size = 16;
638
reg_info.format = eFormatVectorOfUInt8;
639
reg_info.encoding = eEncodingVector;
640
} else {
641
return {};
642
}
643
644
reg_info.name = GetRegisterName(reg_num, false);
645
reg_info.alt_name = GetRegisterName(reg_num, true);
646
reg_info.kinds[eRegisterKindDWARF] = reg_num;
647
648
switch (reg_num) {
649
case dwarf_r30_mips:
650
reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
651
break;
652
case dwarf_ra_mips:
653
reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
654
break;
655
case dwarf_sp_mips:
656
reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
657
break;
658
case dwarf_pc_mips:
659
reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
660
break;
661
case dwarf_sr_mips:
662
reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
663
break;
664
default:
665
break;
666
}
667
return reg_info;
668
}
669
return {};
670
}
671
672
EmulateInstructionMIPS::MipsOpcode *
673
EmulateInstructionMIPS::GetOpcodeForInstruction(llvm::StringRef name) {
674
static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = {
675
// Prologue/Epilogue instructions
676
{"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu,
677
"ADDIU rt, rs, immediate"},
678
{"SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)"},
679
{"LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)"},
680
{"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt"},
681
{"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt"},
682
{"LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate"},
683
684
// MicroMIPS Prologue/Epilogue instructions
685
{"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP,
686
"ADDIU immediate"},
687
{"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5,
688
"ADDIUS5 rd,immediate"},
689
{"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"},
690
{"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
691
"SWM16 reglist,offset(sp)"},
692
{"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
693
"SWM32 reglist,offset(base)"},
694
{"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
695
"SWP rs1,offset(base)"},
696
{"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"},
697
{"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
698
"LWM16 reglist,offset(sp)"},
699
{"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
700
"LWM32 reglist,offset(base)"},
701
{"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
702
"LWP rd,offset(base)"},
703
{"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP,
704
"JRADDIUSP immediate"},
705
706
// Load/Store instructions
707
/* Following list of emulated instructions are required by implementation
708
of hardware watchpoint
709
for MIPS in lldb. As we just need the address accessed by instructions,
710
we have generalised
711
all these instructions in 2 functions depending on their addressing
712
modes */
713
714
{"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
715
"LB rt, offset(base)"},
716
{"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
717
"LBE rt, offset(base)"},
718
{"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
719
"LBU rt, offset(base)"},
720
{"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
721
"LBUE rt, offset(base)"},
722
{"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
723
"LDC1 ft, offset(base)"},
724
{"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
725
"LD rt, offset(base)"},
726
{"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
727
"LDL rt, offset(base)"},
728
{"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
729
"LDR rt, offset(base)"},
730
{"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
731
"LLD rt, offset(base)"},
732
{"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
733
"LDC2 rt, offset(base)"},
734
{"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
735
"LDXC1 fd, index (base)"},
736
{"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
737
"LH rt, offset(base)"},
738
{"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
739
"LHE rt, offset(base)"},
740
{"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
741
"LHU rt, offset(base)"},
742
{"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
743
"LHUE rt, offset(base)"},
744
{"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
745
"LL rt, offset(base)"},
746
{"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
747
"LLE rt, offset(base)"},
748
{"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
749
"LUXC1 fd, index (base)"},
750
{"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm,
751
"LW rt, offset(base)"},
752
{"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
753
"LWC1 ft, offset(base)"},
754
{"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
755
"LWC2 rt, offset(base)"},
756
{"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
757
"LWE rt, offset(base)"},
758
{"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
759
"LWL rt, offset(base)"},
760
{"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
761
"LWLE rt, offset(base)"},
762
{"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
763
"LWR rt, offset(base)"},
764
{"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
765
"LWRE rt, offset(base)"},
766
{"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
767
"LWXC1 fd, index (base)"},
768
{"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
769
"LLX rt, offset(base)"},
770
{"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
771
"LLXE rt, offset(base)"},
772
{"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
773
"LLDX rt, offset(base)"},
774
775
{"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
776
"SB rt, offset(base)"},
777
{"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
778
"SBE rt, offset(base)"},
779
{"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm,
780
"SC rt, offset(base)"},
781
{"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
782
"SCE rt, offset(base)"},
783
{"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
784
"SCD rt, offset(base)"},
785
{"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
786
"SD rt, offset(base)"},
787
{"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
788
"SDL rt, offset(base)"},
789
{"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
790
"SDR rt, offset(base)"},
791
{"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
792
"SDC1 ft, offset(base)"},
793
{"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
794
"SDC2 rt, offset(base)"},
795
{"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
796
"SDXC1 fs, index(base)"},
797
{"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
798
"SH rt, offset(base)"},
799
{"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
800
"SHE rt, offset(base)"},
801
{"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
802
"SUXC1 fs, index (base)"},
803
{"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
804
"SWC1 ft, offset(base)"},
805
{"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
806
"SWC2 rt, offset(base)"},
807
{"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
808
"SWE rt, offset(base)"},
809
{"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
810
"SWL rt, offset(base)"},
811
{"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
812
"SWLE rt, offset(base)"},
813
{"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
814
"SWR rt, offset(base)"},
815
{"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
816
"SWRE rt, offset(base)"},
817
{"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
818
"SWXC1 fs, index (base)"},
819
{"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
820
"SCX rt, offset(base)"},
821
{"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
822
"SCXE rt, offset(base)"},
823
{"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
824
"SCDX rt, offset(base)"},
825
826
// MicroMIPS Load/Store instructions
827
{"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
828
"LBU16 rt, decoded_offset(base)"},
829
{"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
830
"LHU16 rt, left_shifted_offset(base)"},
831
{"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
832
"LW16 rt, left_shifted_offset(base)"},
833
{"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
834
"LWGP rt, left_shifted_offset(gp)"},
835
{"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
836
"SH16 rt, left_shifted_offset(base)"},
837
{"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
838
"SW16 rt, left_shifted_offset(base)"},
839
{"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
840
"SWSP rt, left_shifted_offset(base)"},
841
{"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
842
"SB16 rt, offset(base)"},
843
844
// Branch instructions
845
{"BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
846
{"BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset"},
847
{"BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset"},
848
{"BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset"},
849
{"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
850
"BGEZALL rt,offset"},
851
{"BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset"},
852
{"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
853
"BGEZAL rs,offset"},
854
{"BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset"},
855
{"BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset"},
856
{"BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset"},
857
{"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
858
"BLEZALC rs,offset"},
859
{"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
860
"BGEZALC rs,offset"},
861
{"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
862
"BLTZALC rs,offset"},
863
{"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
864
"BGTZALC rs,offset"},
865
{"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
866
"BEQZALC rs,offset"},
867
{"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
868
"BNEZALC rs,offset"},
869
{"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
870
"BEQC rs,rt,offset"},
871
{"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
872
"BNEC rs,rt,offset"},
873
{"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
874
"BLTC rs,rt,offset"},
875
{"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
876
"BGEC rs,rt,offset"},
877
{"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
878
"BLTUC rs,rt,offset"},
879
{"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
880
"BGEUC rs,rt,offset"},
881
{"BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset"},
882
{"BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset"},
883
{"BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset"},
884
{"BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset"},
885
{"BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset"},
886
{"BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset"},
887
{"BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset"},
888
{"BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset"},
889
{"BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset"},
890
{"BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset"},
891
{"BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset"},
892
{"BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset"},
893
{"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
894
"BLTZAL rt,offset"},
895
{"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
896
"BLTZALL rt,offset"},
897
{"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset"},
898
{"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
899
"BOVC rs,rt,offset"},
900
{"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
901
"BNVC rs,rt,offset"},
902
{"J", &EmulateInstructionMIPS::Emulate_J, "J target"},
903
{"JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target"},
904
{"JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target"},
905
{"JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target"},
906
{"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target"},
907
{"JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset"},
908
{"JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset"},
909
{"JR", &EmulateInstructionMIPS::Emulate_JR, "JR target"},
910
{"JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target"},
911
{"BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset"},
912
{"BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset"},
913
{"BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset"},
914
{"BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset"},
915
{"BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset"},
916
{"BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset"},
917
{"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch,
918
"BC1ANY2F cc, offset"},
919
{"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch,
920
"BC1ANY2T cc, offset"},
921
{"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch,
922
"BC1ANY4F cc, offset"},
923
{"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch,
924
"BC1ANY4T cc, offset"},
925
{"BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16"},
926
{"BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16"},
927
{"BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16"},
928
{"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16"},
929
{"BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16"},
930
{"BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16"},
931
{"BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16"},
932
{"BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16"},
933
{"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16"},
934
{"BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16"},
935
936
// MicroMIPS Branch instructions
937
{"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset"},
938
{"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
939
"BEQZ16 rs, offset"},
940
{"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
941
"BNEZ16 rs, offset"},
942
{"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
943
"BEQZC rs, offset"},
944
{"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
945
"BNEZC rs, offset"},
946
{"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
947
"BGEZALS rs, offset"},
948
{"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
949
"BLTZALS rs, offset"},
950
{"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs"},
951
{"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs"},
952
{"JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs"},
953
{"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs"},
954
{"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target"},
955
{"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target"},
956
{"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"},
957
};
958
959
for (MipsOpcode &opcode : g_opcodes) {
960
if (name.equals_insensitive(opcode.op_name))
961
return &opcode;
962
}
963
return nullptr;
964
}
965
966
uint32_t
967
EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data,
968
uint64_t inst_addr) {
969
uint64_t next_inst_size = 0;
970
llvm::MCInst mc_insn;
971
llvm::MCDisassembler::DecodeStatus decode_status;
972
llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
973
974
if (m_use_alt_disaasm)
975
decode_status = m_alt_disasm->getInstruction(
976
mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls());
977
else
978
decode_status = m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn,
979
inst_addr, llvm::nulls());
980
981
if (decode_status != llvm::MCDisassembler::Success)
982
return false;
983
984
return m_insn_info->get(mc_insn.getOpcode()).getSize();
985
}
986
987
bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
988
const Address &inst_addr,
989
Target *target) {
990
m_use_alt_disaasm = false;
991
992
if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
993
if (inst_addr.GetAddressClass() == AddressClass::eCodeAlternateISA) {
994
Status error;
995
lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
996
997
/*
998
* The address belongs to microMIPS function. To find the size of
999
* next instruction use microMIPS disassembler.
1000
*/
1001
m_use_alt_disaasm = true;
1002
1003
uint32_t current_inst_size = insn_opcode.GetByteSize();
1004
uint8_t buf[sizeof(uint32_t)];
1005
uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size;
1006
Address next_addr(next_inst_addr);
1007
1008
const size_t bytes_read =
1009
target->ReadMemory(next_addr, /* Address of next instruction */
1010
buf, sizeof(uint32_t), error,
1011
false, /* force_live_memory */
1012
&load_addr);
1013
1014
if (bytes_read == 0)
1015
return true;
1016
1017
DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(),
1018
GetAddressByteSize());
1019
m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr);
1020
return true;
1021
} else {
1022
/*
1023
* If the address class is not AddressClass::eCodeAlternateISA then
1024
* the function is not microMIPS. In this case instruction size is
1025
* always 4 bytes.
1026
*/
1027
m_next_inst_size = 4;
1028
return true;
1029
}
1030
}
1031
return false;
1032
}
1033
1034
bool EmulateInstructionMIPS::ReadInstruction() {
1035
bool success = false;
1036
m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
1037
LLDB_INVALID_ADDRESS, &success);
1038
if (success) {
1039
Context read_inst_context;
1040
read_inst_context.type = eContextReadOpcode;
1041
read_inst_context.SetNoArgs();
1042
m_opcode.SetOpcode32(
1043
ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
1044
GetByteOrder());
1045
}
1046
if (!success)
1047
m_addr = LLDB_INVALID_ADDRESS;
1048
return success;
1049
}
1050
1051
bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) {
1052
bool success = false;
1053
llvm::MCInst mc_insn;
1054
uint64_t insn_size;
1055
DataExtractor data;
1056
1057
/* Keep the complexity of the decode logic with the llvm::MCDisassembler
1058
* class. */
1059
if (m_opcode.GetData(data)) {
1060
llvm::MCDisassembler::DecodeStatus decode_status;
1061
llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
1062
if (m_use_alt_disaasm)
1063
decode_status = m_alt_disasm->getInstruction(mc_insn, insn_size, raw_insn,
1064
m_addr, llvm::nulls());
1065
else
1066
decode_status = m_disasm->getInstruction(mc_insn, insn_size, raw_insn,
1067
m_addr, llvm::nulls());
1068
1069
if (decode_status != llvm::MCDisassembler::Success)
1070
return false;
1071
}
1072
1073
/*
1074
* mc_insn.getOpcode() returns decoded opcode. However to make use
1075
* of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
1076
*/
1077
const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
1078
1079
if (op_name == nullptr)
1080
return false;
1081
1082
/*
1083
* Decoding has been done already. Just get the call-back function
1084
* and emulate the instruction.
1085
*/
1086
MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
1087
1088
if (opcode_data == nullptr)
1089
return false;
1090
1091
uint64_t old_pc = 0, new_pc = 0;
1092
const bool auto_advance_pc =
1093
evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
1094
1095
if (auto_advance_pc) {
1096
old_pc =
1097
ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1098
if (!success)
1099
return false;
1100
}
1101
1102
/* emulate instruction */
1103
success = (this->*opcode_data->callback)(mc_insn);
1104
if (!success)
1105
return false;
1106
1107
if (auto_advance_pc) {
1108
new_pc =
1109
ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1110
if (!success)
1111
return false;
1112
1113
/* If we haven't changed the PC, change it here */
1114
if (old_pc == new_pc) {
1115
new_pc += 4;
1116
Context context;
1117
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1118
new_pc))
1119
return false;
1120
}
1121
}
1122
1123
return true;
1124
}
1125
1126
bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
1127
UnwindPlan &unwind_plan) {
1128
unwind_plan.Clear();
1129
unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1130
1131
UnwindPlan::RowSP row(new UnwindPlan::Row);
1132
const bool can_replace = false;
1133
1134
// Our previous Call Frame Address is the stack pointer
1135
row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
1136
1137
// Our previous PC is in the RA
1138
row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
1139
1140
unwind_plan.AppendRow(row);
1141
1142
// All other registers are the same.
1143
unwind_plan.SetSourceName("EmulateInstructionMIPS");
1144
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1145
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1146
unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1147
unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
1148
1149
return true;
1150
}
1151
1152
bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) {
1153
switch (regnum) {
1154
case dwarf_r16_mips:
1155
case dwarf_r17_mips:
1156
case dwarf_r18_mips:
1157
case dwarf_r19_mips:
1158
case dwarf_r20_mips:
1159
case dwarf_r21_mips:
1160
case dwarf_r22_mips:
1161
case dwarf_r23_mips:
1162
case dwarf_gp_mips:
1163
case dwarf_sp_mips:
1164
case dwarf_r30_mips:
1165
case dwarf_ra_mips:
1166
return true;
1167
default:
1168
return false;
1169
}
1170
return false;
1171
}
1172
1173
bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) {
1174
// ADDIU rt, rs, immediate
1175
// GPR[rt] <- GPR[rs] + sign_extend(immediate)
1176
1177
uint8_t dst, src;
1178
bool success = false;
1179
const uint32_t imm16 = insn.getOperand(2).getImm();
1180
int64_t imm = SignedBits(imm16, 15, 0);
1181
1182
dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1183
src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1184
1185
// If immediate value is greater then 2^16 - 1 then clang generate LUI,
1186
// ADDIU, SUBU instructions in prolog. Example lui $1, 0x2 addiu $1, $1,
1187
// -0x5920 subu $sp, $sp, $1 In this case, ADDIU dst and src will be same
1188
// and not equal to sp
1189
if (dst == src) {
1190
Context context;
1191
1192
/* read <src> register */
1193
const int64_t src_opd_val = ReadRegisterUnsigned(
1194
eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1195
if (!success)
1196
return false;
1197
1198
/* Check if this is daddiu sp, sp, imm16 */
1199
if (dst == dwarf_sp_mips) {
1200
uint64_t result = src_opd_val + imm;
1201
std::optional<RegisterInfo> reg_info_sp =
1202
GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips);
1203
if (reg_info_sp)
1204
context.SetRegisterPlusOffset(*reg_info_sp, imm);
1205
1206
/* We are allocating bytes on stack */
1207
context.type = eContextAdjustStackPointer;
1208
1209
WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1210
return true;
1211
}
1212
1213
imm += src_opd_val;
1214
context.SetImmediateSigned(imm);
1215
context.type = eContextImmediate;
1216
1217
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1218
dwarf_zero_mips + dst, imm))
1219
return false;
1220
}
1221
1222
return true;
1223
}
1224
1225
bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) {
1226
bool success = false;
1227
uint32_t imm16 = insn.getOperand(2).getImm();
1228
uint32_t imm = SignedBits(imm16, 15, 0);
1229
uint32_t src, base;
1230
int32_t address;
1231
Context bad_vaddr_context;
1232
1233
src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1234
base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1235
1236
std::optional<RegisterInfo> reg_info_base =
1237
GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base);
1238
if (!reg_info_base)
1239
return false;
1240
1241
/* read base register */
1242
address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1243
dwarf_zero_mips + base, 0, &success);
1244
if (!success)
1245
return false;
1246
1247
/* destination address */
1248
address = address + imm;
1249
1250
/* Set the bad_vaddr register with base address used in the instruction */
1251
bad_vaddr_context.type = eContextInvalid;
1252
WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1253
address);
1254
1255
/* We look for sp based non-volatile register stores */
1256
if (nonvolatile_reg_p(src)) {
1257
std::optional<RegisterInfo> reg_info_src =
1258
GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src);
1259
if (!reg_info_src)
1260
return false;
1261
1262
Context context;
1263
context.type = eContextPushRegisterOnStack;
1264
context.SetRegisterToRegisterPlusOffset(*reg_info_src, *reg_info_base, 0);
1265
1266
RegisterValue::BytesContainer buffer(reg_info_src->byte_size);
1267
Status error;
1268
1269
std::optional<RegisterValue> data_src = ReadRegister(*reg_info_base);
1270
if (!data_src)
1271
return false;
1272
1273
if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(),
1274
reg_info_src->byte_size, eByteOrderLittle,
1275
error) == 0)
1276
return false;
1277
1278
if (!WriteMemory(context, address, buffer.data(), reg_info_src->byte_size))
1279
return false;
1280
1281
return true;
1282
}
1283
1284
return false;
1285
}
1286
1287
bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) {
1288
bool success = false;
1289
uint32_t src, base;
1290
int32_t imm, address;
1291
Context bad_vaddr_context;
1292
1293
src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1294
base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1295
imm = insn.getOperand(2).getImm();
1296
1297
if (GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base))
1298
return false;
1299
1300
/* read base register */
1301
address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1302
dwarf_zero_mips + base, 0, &success);
1303
if (!success)
1304
return false;
1305
1306
/* destination address */
1307
address = address + imm;
1308
1309
/* Set the bad_vaddr register with base address used in the instruction */
1310
bad_vaddr_context.type = eContextInvalid;
1311
WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1312
address);
1313
1314
if (nonvolatile_reg_p(src)) {
1315
RegisterValue data_src;
1316
std::optional<RegisterInfo> reg_info_src =
1317
GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src);
1318
if (!reg_info_src)
1319
return false;
1320
1321
Context context;
1322
context.type = eContextPopRegisterOffStack;
1323
context.SetAddress(address);
1324
1325
return WriteRegister(context, *reg_info_src, data_src);
1326
}
1327
1328
return false;
1329
}
1330
1331
bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) {
1332
// SUBU sp, <src>, <rt>
1333
// ADDU sp, <src>, <rt>
1334
// ADDU dst, sp, <rt>
1335
1336
bool success = false;
1337
uint64_t result;
1338
uint8_t src, dst, rt;
1339
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1340
1341
dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1342
src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1343
1344
/* Check if sp is destination register */
1345
if (dst == dwarf_sp_mips) {
1346
rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1347
1348
/* read <src> register */
1349
uint64_t src_opd_val = ReadRegisterUnsigned(
1350
eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1351
if (!success)
1352
return false;
1353
1354
/* read <rt > register */
1355
uint64_t rt_opd_val = ReadRegisterUnsigned(
1356
eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1357
if (!success)
1358
return false;
1359
1360
if (op_name.equals_insensitive("SUBU"))
1361
result = src_opd_val - rt_opd_val;
1362
else
1363
result = src_opd_val + rt_opd_val;
1364
1365
Context context;
1366
std::optional<RegisterInfo> reg_info_sp =
1367
GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips);
1368
if (reg_info_sp)
1369
context.SetRegisterPlusOffset(*reg_info_sp, rt_opd_val);
1370
1371
/* We are allocating bytes on stack */
1372
context.type = eContextAdjustStackPointer;
1373
1374
WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1375
1376
return true;
1377
} else if (src == dwarf_sp_mips) {
1378
rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1379
1380
/* read <src> register */
1381
uint64_t src_opd_val = ReadRegisterUnsigned(
1382
eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1383
if (!success)
1384
return false;
1385
1386
/* read <rt> register */
1387
uint64_t rt_opd_val = ReadRegisterUnsigned(
1388
eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1389
if (!success)
1390
return false;
1391
1392
Context context;
1393
1394
if (op_name.equals_insensitive("SUBU"))
1395
result = src_opd_val - rt_opd_val;
1396
else
1397
result = src_opd_val + rt_opd_val;
1398
1399
context.SetImmediateSigned(result);
1400
context.type = eContextImmediate;
1401
1402
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1403
dwarf_zero_mips + dst, result))
1404
return false;
1405
}
1406
1407
return true;
1408
}
1409
1410
bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) {
1411
// LUI rt, immediate
1412
// GPR[rt] <- sign_extend(immediate << 16)
1413
1414
const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1415
int64_t imm = SignedBits(imm32, 31, 0);
1416
uint8_t rt;
1417
Context context;
1418
1419
rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1420
context.SetImmediateSigned(imm);
1421
context.type = eContextImmediate;
1422
1423
return WriteRegisterUnsigned(context, eRegisterKindDWARF,
1424
dwarf_zero_mips + rt, imm);
1425
}
1426
1427
bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) {
1428
bool success = false;
1429
const uint32_t imm9 = insn.getOperand(0).getImm();
1430
uint64_t result;
1431
1432
// This instruction operates implicitly on stack pointer, so read <sp>
1433
// register.
1434
uint64_t src_opd_val =
1435
ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1436
if (!success)
1437
return false;
1438
1439
result = src_opd_val + imm9;
1440
1441
Context context;
1442
std::optional<RegisterInfo> reg_info_sp =
1443
GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips);
1444
if (reg_info_sp)
1445
context.SetRegisterPlusOffset(*reg_info_sp, imm9);
1446
1447
// We are adjusting the stack.
1448
context.type = eContextAdjustStackPointer;
1449
1450
WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1451
return true;
1452
}
1453
1454
bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) {
1455
bool success = false;
1456
uint32_t base;
1457
const uint32_t imm4 = insn.getOperand(2).getImm();
1458
uint64_t result;
1459
1460
// The source and destination register is same for this instruction.
1461
base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1462
1463
// We are looking for stack adjustment only
1464
if (base == dwarf_sp_mips) {
1465
// Read stack pointer register
1466
uint64_t src_opd_val = ReadRegisterUnsigned(
1467
eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1468
if (!success)
1469
return false;
1470
1471
result = src_opd_val + imm4;
1472
1473
Context context;
1474
std::optional<RegisterInfo> reg_info_sp =
1475
GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips);
1476
if (reg_info_sp)
1477
context.SetRegisterPlusOffset(*reg_info_sp, imm4);
1478
1479
// We are adjusting the stack.
1480
context.type = eContextAdjustStackPointer;
1481
1482
WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1483
}
1484
1485
return true;
1486
}
1487
1488
bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) {
1489
bool success = false;
1490
uint32_t imm5 = insn.getOperand(2).getImm();
1491
uint32_t src, base;
1492
Context bad_vaddr_context;
1493
uint32_t address;
1494
1495
src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1496
base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1497
1498
std::optional<RegisterInfo> reg_info_base =
1499
GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base);
1500
if (!reg_info_base)
1501
return false;
1502
1503
// read base register
1504
address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
1505
&success);
1506
if (!success)
1507
return false;
1508
1509
// destination address
1510
address = address + imm5;
1511
1512
// We use bad_vaddr_context to store base address which is used by H/W
1513
// watchpoint Set the bad_vaddr register with base address used in the
1514
// instruction
1515
bad_vaddr_context.type = eContextInvalid;
1516
WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1517
address);
1518
1519
// We look for sp based non-volatile register stores.
1520
if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1521
RegisterInfo reg_info_src = {};
1522
Context context;
1523
context.type = eContextPushRegisterOnStack;
1524
context.SetRegisterToRegisterPlusOffset(reg_info_src, *reg_info_base, 0);
1525
1526
RegisterValue::BytesContainer buffer(reg_info_src.byte_size);
1527
Status error;
1528
1529
std::optional<RegisterValue> data_src = ReadRegister(*reg_info_base);
1530
if (!data_src)
1531
return false;
1532
1533
if (data_src->GetAsMemoryData(reg_info_src, buffer.data(),
1534
reg_info_src.byte_size, eByteOrderLittle,
1535
error) == 0)
1536
return false;
1537
1538
if (!WriteMemory(context, address, buffer.data(), reg_info_src.byte_size))
1539
return false;
1540
1541
return true;
1542
}
1543
1544
return false;
1545
}
1546
1547
/* Emulate SWM16,SWM32 and SWP instruction.
1548
1549
SWM16 always has stack pointer as a base register (but it is still available
1550
in MCInst as an operand).
1551
SWM32 and SWP can have base register other than stack pointer.
1552
*/
1553
bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) {
1554
bool success = false;
1555
uint32_t src, base;
1556
uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1557
// no of regs to store.
1558
1559
// Base register is second last operand of the instruction.
1560
base =
1561
m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1562
1563
// We are looking for sp based stores so if base is not a stack pointer then
1564
// don't proceed.
1565
if (base != dwarf_sp_mips)
1566
return false;
1567
1568
// offset is always the last operand.
1569
uint32_t offset = insn.getOperand(num_operands - 1).getImm();
1570
1571
std::optional<RegisterInfo> reg_info_base =
1572
GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base);
1573
if (!reg_info_base)
1574
return false;
1575
1576
// read SP
1577
uint32_t base_address = ReadRegisterUnsigned(
1578
eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1579
if (!success)
1580
return false;
1581
1582
// Resulting base addrss
1583
base_address = base_address + offset;
1584
1585
// Total no of registers to be stored are num_operands-2.
1586
for (uint32_t i = 0; i < num_operands - 2; i++) {
1587
// Get the register number to be stored.
1588
src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1589
1590
/*
1591
Record only non-volatile stores.
1592
This check is required for SWP instruction because source operand could
1593
be any register.
1594
SWM16 and SWM32 instruction always has saved registers as source
1595
operands.
1596
*/
1597
if (!nonvolatile_reg_p(src))
1598
return false;
1599
1600
std::optional<RegisterInfo> reg_info_src =
1601
GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src);
1602
if (!reg_info_src)
1603
return false;
1604
1605
Context context;
1606
context.type = eContextPushRegisterOnStack;
1607
context.SetRegisterToRegisterPlusOffset(*reg_info_src, *reg_info_base, 0);
1608
1609
RegisterValue::BytesContainer buffer(reg_info_src->byte_size);
1610
Status error;
1611
1612
std::optional<RegisterValue> data_src = ReadRegister(*reg_info_base);
1613
if (!data_src)
1614
return false;
1615
1616
if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(),
1617
reg_info_src->byte_size, eByteOrderLittle,
1618
error) == 0)
1619
return false;
1620
1621
if (!WriteMemory(context, base_address, buffer.data(),
1622
reg_info_src->byte_size))
1623
return false;
1624
1625
// Stack address for next register
1626
base_address = base_address + reg_info_src->byte_size;
1627
}
1628
return true;
1629
}
1630
1631
bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
1632
bool success = false;
1633
uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1634
uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1635
uint32_t imm5 = insn.getOperand(2).getImm();
1636
Context bad_vaddr_context;
1637
1638
if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base))
1639
return false;
1640
1641
// read base register
1642
uint32_t base_address = ReadRegisterUnsigned(
1643
eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1644
if (!success)
1645
return false;
1646
1647
base_address = base_address + imm5;
1648
1649
// We use bad_vaddr_context to store base address which is used by H/W
1650
// watchpoint Set the bad_vaddr register with base address used in the
1651
// instruction
1652
bad_vaddr_context.type = eContextInvalid;
1653
WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1654
base_address);
1655
1656
if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1657
RegisterValue data_src;
1658
std::optional<RegisterInfo> reg_info_src =
1659
GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src);
1660
if (!reg_info_src)
1661
return false;
1662
1663
Context context;
1664
context.type = eContextPopRegisterOffStack;
1665
context.SetAddress(base_address);
1666
1667
return WriteRegister(context, *reg_info_src, data_src);
1668
}
1669
1670
return false;
1671
}
1672
1673
/* Emulate LWM16, LWM32 and LWP instructions.
1674
1675
LWM16 always has stack pointer as a base register (but it is still available
1676
in MCInst as an operand).
1677
LWM32 and LWP can have base register other than stack pointer.
1678
*/
1679
bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) {
1680
bool success = false;
1681
uint32_t dst, base;
1682
uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1683
// no of regs to store.
1684
uint32_t imm = insn.getOperand(num_operands - 1)
1685
.getImm(); // imm is the last operand in the instruction.
1686
1687
// Base register is second last operand of the instruction.
1688
base =
1689
m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1690
1691
// We are looking for sp based loads so if base is not a stack pointer then
1692
// don't proceed.
1693
if (base != dwarf_sp_mips)
1694
return false;
1695
1696
uint32_t base_address = ReadRegisterUnsigned(
1697
eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1698
if (!success)
1699
return false;
1700
1701
base_address = base_address + imm;
1702
1703
RegisterValue data_dst;
1704
1705
// Total no of registers to be re-stored are num_operands-2.
1706
for (uint32_t i = 0; i < num_operands - 2; i++) {
1707
// Get the register number to be re-stored.
1708
dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1709
1710
/*
1711
Record only non-volatile loads.
1712
This check is required for LWP instruction because destination operand
1713
could be any register.
1714
LWM16 and LWM32 instruction always has saved registers as destination
1715
operands.
1716
*/
1717
if (!nonvolatile_reg_p(dst))
1718
return false;
1719
1720
std::optional<RegisterInfo> reg_info_dst =
1721
GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst);
1722
if (!reg_info_dst)
1723
return false;
1724
1725
Context context;
1726
context.type = eContextPopRegisterOffStack;
1727
context.SetAddress(base_address + (i * 4));
1728
1729
if (!WriteRegister(context, *reg_info_dst, data_dst))
1730
return false;
1731
}
1732
1733
return true;
1734
}
1735
1736
bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) {
1737
bool success = false;
1738
int32_t imm5 = insn.getOperand(0).getImm();
1739
1740
/* JRADDIUSP immediate
1741
* PC <- RA
1742
* SP <- SP + zero_extend(Immediate << 2)
1743
*/
1744
1745
// This instruction operates implicitly on stack pointer, so read <sp>
1746
// register.
1747
int32_t src_opd_val =
1748
ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1749
if (!success)
1750
return false;
1751
1752
int32_t ra_val =
1753
ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
1754
if (!success)
1755
return false;
1756
1757
int32_t result = src_opd_val + imm5;
1758
1759
Context context;
1760
1761
// Update the PC
1762
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1763
ra_val))
1764
return false;
1765
1766
std::optional<RegisterInfo> reg_info_sp =
1767
GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips);
1768
if (reg_info_sp)
1769
context.SetRegisterPlusOffset(*reg_info_sp, imm5);
1770
1771
// We are adjusting stack
1772
context.type = eContextAdjustStackPointer;
1773
1774
// update SP
1775
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
1776
result);
1777
}
1778
1779
static int IsAdd64bitOverflow(int32_t a, int32_t b) {
1780
int32_t r = (uint32_t)a + (uint32_t)b;
1781
return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1782
}
1783
1784
/*
1785
Emulate below MIPS branch instructions.
1786
BEQ, BNE : Branch on condition
1787
BEQL, BNEL : Branch likely
1788
*/
1789
bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) {
1790
bool success = false;
1791
uint32_t rs, rt;
1792
int32_t offset, pc, target = 0, rs_val, rt_val;
1793
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1794
1795
rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1796
rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1797
offset = insn.getOperand(2).getImm();
1798
1799
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1800
if (!success)
1801
return false;
1802
1803
rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1804
dwarf_zero_mips + rs, 0, &success);
1805
if (!success)
1806
return false;
1807
1808
rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1809
dwarf_zero_mips + rt, 0, &success);
1810
if (!success)
1811
return false;
1812
1813
if (op_name.equals_insensitive("BEQ") || op_name.equals_insensitive("BEQL")) {
1814
if (rs_val == rt_val)
1815
target = pc + offset;
1816
else
1817
target = pc + 8;
1818
} else if (op_name.equals_insensitive("BNE") ||
1819
op_name.equals_insensitive("BNEL")) {
1820
if (rs_val != rt_val)
1821
target = pc + offset;
1822
else
1823
target = pc + 8;
1824
}
1825
1826
Context context;
1827
context.type = eContextRelativeBranchImmediate;
1828
context.SetImmediate(offset);
1829
1830
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1831
target);
1832
}
1833
1834
/*
1835
Emulate below MIPS branch instructions.
1836
BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1837
instructions with no delay slot
1838
*/
1839
bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
1840
bool success = false;
1841
uint32_t rs, rt;
1842
int32_t offset, pc, target = 0, rs_val, rt_val;
1843
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1844
uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1845
1846
rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1847
rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1848
offset = insn.getOperand(2).getImm();
1849
1850
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1851
if (!success)
1852
return false;
1853
1854
rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1855
dwarf_zero_mips + rs, 0, &success);
1856
if (!success)
1857
return false;
1858
1859
rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1860
dwarf_zero_mips + rt, 0, &success);
1861
if (!success)
1862
return false;
1863
1864
if (op_name.equals_insensitive("BEQC")) {
1865
if (rs_val == rt_val)
1866
target = pc + offset;
1867
else
1868
target = pc + 4;
1869
} else if (op_name.equals_insensitive("BNEC")) {
1870
if (rs_val != rt_val)
1871
target = pc + offset;
1872
else
1873
target = pc + 4;
1874
} else if (op_name.equals_insensitive("BLTC")) {
1875
if (rs_val < rt_val)
1876
target = pc + offset;
1877
else
1878
target = pc + 4;
1879
} else if (op_name.equals_insensitive("BGEC")) {
1880
if (rs_val >= rt_val)
1881
target = pc + offset;
1882
else
1883
target = pc + 4;
1884
} else if (op_name.equals_insensitive("BLTUC")) {
1885
if (rs_val < rt_val)
1886
target = pc + offset;
1887
else
1888
target = pc + 4;
1889
} else if (op_name.equals_insensitive("BGEUC")) {
1890
if ((uint32_t)rs_val >= (uint32_t)rt_val)
1891
target = pc + offset;
1892
else
1893
target = pc + 4;
1894
} else if (op_name.equals_insensitive("BOVC")) {
1895
if (IsAdd64bitOverflow(rs_val, rt_val))
1896
target = pc + offset;
1897
else
1898
target = pc + 4;
1899
} else if (op_name.equals_insensitive("BNVC")) {
1900
if (!IsAdd64bitOverflow(rs_val, rt_val))
1901
target = pc + offset;
1902
else
1903
target = pc + 4;
1904
}
1905
1906
Context context;
1907
context.type = eContextRelativeBranchImmediate;
1908
context.SetImmediate(current_inst_size + offset);
1909
1910
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1911
target);
1912
}
1913
1914
/*
1915
Emulate below MIPS conditional branch and link instructions.
1916
BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1917
*/
1918
bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
1919
bool success = false;
1920
uint32_t rs;
1921
int32_t offset, pc, target = 0;
1922
int32_t rs_val;
1923
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1924
1925
rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1926
offset = insn.getOperand(1).getImm();
1927
1928
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1929
if (!success)
1930
return false;
1931
1932
rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1933
dwarf_zero_mips + rs, 0, &success);
1934
if (!success)
1935
return false;
1936
1937
if (op_name.equals_insensitive("BLEZALC")) {
1938
if (rs_val <= 0)
1939
target = pc + offset;
1940
else
1941
target = pc + 4;
1942
} else if (op_name.equals_insensitive("BGEZALC")) {
1943
if (rs_val >= 0)
1944
target = pc + offset;
1945
else
1946
target = pc + 4;
1947
} else if (op_name.equals_insensitive("BLTZALC")) {
1948
if (rs_val < 0)
1949
target = pc + offset;
1950
else
1951
target = pc + 4;
1952
} else if (op_name.equals_insensitive("BGTZALC")) {
1953
if (rs_val > 0)
1954
target = pc + offset;
1955
else
1956
target = pc + 4;
1957
} else if (op_name.equals_insensitive("BEQZALC")) {
1958
if (rs_val == 0)
1959
target = pc + offset;
1960
else
1961
target = pc + 4;
1962
} else if (op_name.equals_insensitive("BNEZALC")) {
1963
if (rs_val != 0)
1964
target = pc + offset;
1965
else
1966
target = pc + 4;
1967
}
1968
1969
Context context;
1970
1971
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1972
target))
1973
return false;
1974
1975
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
1976
pc + 4))
1977
return false;
1978
1979
return true;
1980
}
1981
1982
/*
1983
Emulate below MIPS Non-Compact conditional branch and link instructions.
1984
BLTZAL, BGEZAL :
1985
BLTZALL, BGEZALL : Branch likely
1986
*/
1987
bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) {
1988
bool success = false;
1989
uint32_t rs;
1990
int32_t offset, pc, target = 0;
1991
int32_t rs_val;
1992
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1993
1994
rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1995
offset = insn.getOperand(1).getImm();
1996
1997
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1998
if (!success)
1999
return false;
2000
2001
rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2002
dwarf_zero_mips + rs, 0, &success);
2003
if (!success)
2004
return false;
2005
2006
if (op_name.equals_insensitive("BLTZAL") ||
2007
op_name.equals_insensitive("BLTZALL")) {
2008
if ((int32_t)rs_val < 0)
2009
target = pc + offset;
2010
else
2011
target = pc + 8;
2012
} else if (op_name.equals_insensitive("BGEZAL") ||
2013
op_name.equals_insensitive("BGEZALL")) {
2014
if ((int32_t)rs_val >= 0)
2015
target = pc + offset;
2016
else
2017
target = pc + 8;
2018
}
2019
2020
Context context;
2021
2022
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2023
target))
2024
return false;
2025
2026
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2027
pc + 8))
2028
return false;
2029
2030
return true;
2031
}
2032
2033
/*
2034
Emulate below MIPS branch instructions.
2035
BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
2036
BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
2037
*/
2038
bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) {
2039
bool success = false;
2040
uint32_t rs;
2041
int32_t offset, pc, target = 0;
2042
int32_t rs_val;
2043
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
2044
2045
rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2046
offset = insn.getOperand(1).getImm();
2047
2048
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2049
if (!success)
2050
return false;
2051
2052
rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2053
dwarf_zero_mips + rs, 0, &success);
2054
if (!success)
2055
return false;
2056
2057
if (op_name.equals_insensitive("BLTZL") ||
2058
op_name.equals_insensitive("BLTZ")) {
2059
if (rs_val < 0)
2060
target = pc + offset;
2061
else
2062
target = pc + 8;
2063
} else if (op_name.equals_insensitive("BGEZL") ||
2064
op_name.equals_insensitive("BGEZ")) {
2065
if (rs_val >= 0)
2066
target = pc + offset;
2067
else
2068
target = pc + 8;
2069
} else if (op_name.equals_insensitive("BGTZL") ||
2070
op_name.equals_insensitive("BGTZ")) {
2071
if (rs_val > 0)
2072
target = pc + offset;
2073
else
2074
target = pc + 8;
2075
} else if (op_name.equals_insensitive("BLEZL") ||
2076
op_name.equals_insensitive("BLEZ")) {
2077
if (rs_val <= 0)
2078
target = pc + offset;
2079
else
2080
target = pc + 8;
2081
}
2082
2083
Context context;
2084
context.type = eContextRelativeBranchImmediate;
2085
context.SetImmediate(offset);
2086
2087
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2088
target);
2089
}
2090
2091
/*
2092
Emulate below MIPS branch instructions.
2093
BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
2094
*/
2095
bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
2096
bool success = false;
2097
uint32_t rs;
2098
int32_t offset, pc, target = 0;
2099
int32_t rs_val;
2100
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
2101
uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2102
2103
rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2104
offset = insn.getOperand(1).getImm();
2105
2106
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2107
if (!success)
2108
return false;
2109
2110
rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2111
dwarf_zero_mips + rs, 0, &success);
2112
if (!success)
2113
return false;
2114
2115
if (op_name.equals_insensitive("BLTZC")) {
2116
if (rs_val < 0)
2117
target = pc + offset;
2118
else
2119
target = pc + 4;
2120
} else if (op_name.equals_insensitive("BLEZC")) {
2121
if (rs_val <= 0)
2122
target = pc + offset;
2123
else
2124
target = pc + 4;
2125
} else if (op_name.equals_insensitive("BGEZC")) {
2126
if (rs_val >= 0)
2127
target = pc + offset;
2128
else
2129
target = pc + 4;
2130
} else if (op_name.equals_insensitive("BGTZC")) {
2131
if (rs_val > 0)
2132
target = pc + offset;
2133
else
2134
target = pc + 4;
2135
} else if (op_name.equals_insensitive("BEQZC")) {
2136
if (rs_val == 0)
2137
target = pc + offset;
2138
else
2139
target = pc + 4;
2140
} else if (op_name.equals_insensitive("BNEZC")) {
2141
if (rs_val != 0)
2142
target = pc + offset;
2143
else
2144
target = pc + 4;
2145
}
2146
2147
Context context;
2148
context.type = eContextRelativeBranchImmediate;
2149
context.SetImmediate(current_inst_size + offset);
2150
2151
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2152
target);
2153
}
2154
2155
bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
2156
bool success = false;
2157
int32_t offset, pc, target;
2158
uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2159
2160
offset = insn.getOperand(0).getImm();
2161
2162
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2163
if (!success)
2164
return false;
2165
2166
// unconditional branch
2167
target = pc + offset;
2168
2169
Context context;
2170
context.type = eContextRelativeBranchImmediate;
2171
context.SetImmediate(current_inst_size + offset);
2172
2173
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2174
target);
2175
}
2176
2177
/*
2178
BEQZC, BNEZC are 32 bit compact instructions without a delay slot.
2179
BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
2180
BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
2181
*/
2182
bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) {
2183
bool success = false;
2184
int32_t target = 0;
2185
uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2186
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
2187
bool update_ra = false;
2188
uint32_t ra_offset = 0;
2189
2190
/*
2191
* BEQZ16 rs, offset
2192
* condition <- (GPR[rs] = 0)
2193
* if condition then
2194
* PC = PC + sign_ext (offset || 0)
2195
*
2196
* BNEZ16 rs, offset
2197
* condition <- (GPR[rs] != 0)
2198
* if condition then
2199
* PC = PC + sign_ext (offset || 0)
2200
*
2201
* BEQZC rs, offset (compact instruction: No delay slot)
2202
* condition <- (GPR[rs] == 0)
2203
* if condition then
2204
* PC = PC + 4 + sign_ext (offset || 0)
2205
*/
2206
2207
uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2208
int32_t offset = insn.getOperand(1).getImm();
2209
2210
int32_t pc =
2211
ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2212
if (!success)
2213
return false;
2214
2215
int32_t rs_val = (int32_t)ReadRegisterUnsigned(
2216
eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2217
if (!success)
2218
return false;
2219
2220
if (op_name.equals_insensitive("BEQZ16_MM")) {
2221
if (rs_val == 0)
2222
target = pc + offset;
2223
else
2224
target = pc + current_inst_size +
2225
m_next_inst_size; // Skip delay slot instruction.
2226
} else if (op_name.equals_insensitive("BNEZ16_MM")) {
2227
if (rs_val != 0)
2228
target = pc + offset;
2229
else
2230
target = pc + current_inst_size +
2231
m_next_inst_size; // Skip delay slot instruction.
2232
} else if (op_name.equals_insensitive("BEQZC_MM")) {
2233
if (rs_val == 0)
2234
target = pc + 4 + offset;
2235
else
2236
target =
2237
pc +
2238
4; // 32 bit instruction and does not have delay slot instruction.
2239
} else if (op_name.equals_insensitive("BNEZC_MM")) {
2240
if (rs_val != 0)
2241
target = pc + 4 + offset;
2242
else
2243
target =
2244
pc +
2245
4; // 32 bit instruction and does not have delay slot instruction.
2246
} else if (op_name.equals_insensitive("BGEZALS_MM")) {
2247
if (rs_val >= 0)
2248
target = pc + offset;
2249
else
2250
target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2251
2252
update_ra = true;
2253
ra_offset = 6;
2254
} else if (op_name.equals_insensitive("BLTZALS_MM")) {
2255
if (rs_val >= 0)
2256
target = pc + offset;
2257
else
2258
target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2259
2260
update_ra = true;
2261
ra_offset = 6;
2262
}
2263
2264
Context context;
2265
context.type = eContextRelativeBranchImmediate;
2266
context.SetImmediate(current_inst_size + offset);
2267
2268
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2269
target))
2270
return false;
2271
2272
if (update_ra) {
2273
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2274
pc + ra_offset))
2275
return false;
2276
}
2277
return true;
2278
}
2279
2280
/* Emulate micromips jump instructions.
2281
JALR16,JALRS16
2282
*/
2283
bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) {
2284
bool success = false;
2285
uint32_t ra_offset = 0;
2286
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
2287
2288
uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2289
2290
uint32_t pc =
2291
ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2292
if (!success)
2293
return false;
2294
2295
uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF,
2296
dwarf_zero_mips + rs, 0, &success);
2297
if (!success)
2298
return false;
2299
2300
if (op_name.equals_insensitive("JALR16_MM"))
2301
ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
2302
else if (op_name.equals_insensitive("JALRS16_MM"))
2303
ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
2304
2305
Context context;
2306
2307
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2308
rs_val))
2309
return false;
2310
2311
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2312
pc + ra_offset))
2313
return false;
2314
2315
return true;
2316
}
2317
2318
/* Emulate JALS and JALX instructions.
2319
JALS 32 bit instruction with short (2-byte) delay slot.
2320
JALX 32 bit instruction with 4-byte delay slot.
2321
*/
2322
bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) {
2323
bool success = false;
2324
uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0;
2325
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
2326
2327
/*
2328
* JALS target
2329
* RA = PC + 6
2330
* offset = sign_ext (offset << 1)
2331
* PC = PC[31-27] | offset
2332
* JALX target
2333
* RA = PC + 8
2334
* offset = sign_ext (offset << 2)
2335
* PC = PC[31-28] | offset
2336
*/
2337
offset = insn.getOperand(0).getImm();
2338
2339
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2340
if (!success)
2341
return false;
2342
2343
// These are PC-region branches and not PC-relative.
2344
if (op_name.equals_insensitive("JALS_MM")) {
2345
// target address is in the “current” 128 MB-aligned region
2346
target = (pc & 0xF8000000UL) | offset;
2347
ra_offset = 6;
2348
} else if (op_name.equals_insensitive("JALX_MM")) {
2349
// target address is in the “current” 256 MB-aligned region
2350
target = (pc & 0xF0000000UL) | offset;
2351
ra_offset = 8;
2352
}
2353
2354
Context context;
2355
2356
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2357
target))
2358
return false;
2359
2360
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2361
pc + ra_offset))
2362
return false;
2363
2364
return true;
2365
}
2366
2367
bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) {
2368
bool success = false;
2369
uint32_t rs = 0, rt = 0;
2370
int32_t pc = 0, rs_val = 0;
2371
2372
/*
2373
JALRS rt, rs
2374
GPR[rt] <- PC + 6
2375
PC <- GPR[rs]
2376
*/
2377
2378
rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2379
rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2380
2381
rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2382
dwarf_zero_mips + rs, 0, &success);
2383
if (!success)
2384
return false;
2385
2386
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2387
if (!success)
2388
return false;
2389
2390
Context context;
2391
2392
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2393
rs_val))
2394
return false;
2395
2396
// This is 4-byte instruction with 2-byte delay slot.
2397
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2398
pc + 6))
2399
return false;
2400
2401
return true;
2402
}
2403
2404
bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) {
2405
bool success = false;
2406
int32_t offset, pc, target;
2407
2408
/*
2409
* BAL offset
2410
* offset = sign_ext (offset << 2)
2411
* RA = PC + 8
2412
* PC = PC + offset
2413
*/
2414
offset = insn.getOperand(0).getImm();
2415
2416
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2417
if (!success)
2418
return false;
2419
2420
target = pc + offset;
2421
2422
Context context;
2423
2424
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2425
target))
2426
return false;
2427
2428
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2429
pc + 8))
2430
return false;
2431
2432
return true;
2433
}
2434
2435
bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) {
2436
bool success = false;
2437
int32_t offset, pc, target;
2438
2439
/*
2440
* BALC offset
2441
* offset = sign_ext (offset << 2)
2442
* RA = PC + 4
2443
* PC = PC + 4 + offset
2444
*/
2445
offset = insn.getOperand(0).getImm();
2446
2447
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2448
if (!success)
2449
return false;
2450
2451
target = pc + offset;
2452
2453
Context context;
2454
2455
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2456
target))
2457
return false;
2458
2459
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2460
pc + 4))
2461
return false;
2462
2463
return true;
2464
}
2465
2466
bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) {
2467
bool success = false;
2468
int32_t offset, pc, target;
2469
2470
/*
2471
* BC offset
2472
* offset = sign_ext (offset << 2)
2473
* PC = PC + 4 + offset
2474
*/
2475
offset = insn.getOperand(0).getImm();
2476
2477
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2478
if (!success)
2479
return false;
2480
2481
target = pc + offset;
2482
2483
Context context;
2484
2485
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2486
target);
2487
}
2488
2489
bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) {
2490
bool success = false;
2491
uint32_t offset, pc;
2492
2493
/*
2494
* J offset
2495
* offset = sign_ext (offset << 2)
2496
* PC = PC[63-28] | offset
2497
*/
2498
offset = insn.getOperand(0).getImm();
2499
2500
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2501
if (!success)
2502
return false;
2503
2504
/* This is a PC-region branch and not PC-relative */
2505
pc = (pc & 0xF0000000UL) | offset;
2506
2507
Context context;
2508
2509
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc);
2510
}
2511
2512
bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) {
2513
bool success = false;
2514
uint32_t offset, target, pc;
2515
2516
/*
2517
* JAL offset
2518
* offset = sign_ext (offset << 2)
2519
* PC = PC[63-28] | offset
2520
*/
2521
offset = insn.getOperand(0).getImm();
2522
2523
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2524
if (!success)
2525
return false;
2526
2527
/* This is a PC-region branch and not PC-relative */
2528
target = (pc & 0xF0000000UL) | offset;
2529
2530
Context context;
2531
2532
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2533
target))
2534
return false;
2535
2536
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2537
pc + 8))
2538
return false;
2539
2540
return true;
2541
}
2542
2543
bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) {
2544
bool success = false;
2545
uint32_t rs, rt;
2546
uint32_t pc, rs_val;
2547
2548
/*
2549
* JALR rt, rs
2550
* GPR[rt] = PC + 8
2551
* PC = GPR[rs]
2552
*/
2553
rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2554
rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2555
2556
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2557
if (!success)
2558
return false;
2559
2560
rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2561
&success);
2562
if (!success)
2563
return false;
2564
2565
Context context;
2566
2567
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2568
rs_val))
2569
return false;
2570
2571
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2572
pc + 8))
2573
return false;
2574
2575
return true;
2576
}
2577
2578
bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) {
2579
bool success = false;
2580
uint32_t rt;
2581
int32_t target, offset, pc, rt_val;
2582
2583
/*
2584
* JIALC rt, offset
2585
* offset = sign_ext (offset)
2586
* PC = GPR[rt] + offset
2587
* RA = PC + 4
2588
*/
2589
rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2590
offset = insn.getOperand(1).getImm();
2591
2592
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2593
if (!success)
2594
return false;
2595
2596
rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2597
dwarf_zero_mips + rt, 0, &success);
2598
if (!success)
2599
return false;
2600
2601
target = rt_val + offset;
2602
2603
Context context;
2604
2605
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2606
target))
2607
return false;
2608
2609
if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2610
pc + 4))
2611
return false;
2612
2613
return true;
2614
}
2615
2616
bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) {
2617
bool success = false;
2618
uint32_t rt;
2619
int32_t target, offset, rt_val;
2620
2621
/*
2622
* JIC rt, offset
2623
* offset = sign_ext (offset)
2624
* PC = GPR[rt] + offset
2625
*/
2626
rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2627
offset = insn.getOperand(1).getImm();
2628
2629
rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2630
dwarf_zero_mips + rt, 0, &success);
2631
if (!success)
2632
return false;
2633
2634
target = rt_val + offset;
2635
2636
Context context;
2637
2638
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2639
target);
2640
}
2641
2642
bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) {
2643
bool success = false;
2644
uint32_t rs;
2645
uint32_t rs_val;
2646
2647
/*
2648
* JR rs
2649
* PC = GPR[rs]
2650
*/
2651
rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2652
2653
rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2654
&success);
2655
if (!success)
2656
return false;
2657
2658
Context context;
2659
2660
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2661
rs_val);
2662
}
2663
2664
/*
2665
Emulate Branch on FP True/False
2666
BC1F, BC1FL : Branch on FP False (L stands for branch likely)
2667
BC1T, BC1TL : Branch on FP True (L stands for branch likely)
2668
*/
2669
bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) {
2670
bool success = false;
2671
uint32_t cc, fcsr;
2672
int32_t pc, offset, target = 0;
2673
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
2674
2675
cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2676
offset = insn.getOperand(1).getImm();
2677
2678
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2679
if (!success)
2680
return false;
2681
2682
fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
2683
if (!success)
2684
return false;
2685
2686
/* fcsr[23], fcsr[25-31] are vaild condition bits */
2687
fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2688
2689
if (op_name.equals_insensitive("BC1F") ||
2690
op_name.equals_insensitive("BC1FL")) {
2691
if ((fcsr & (1 << cc)) == 0)
2692
target = pc + offset;
2693
else
2694
target = pc + 8;
2695
} else if (op_name.equals_insensitive("BC1T") ||
2696
op_name.equals_insensitive("BC1TL")) {
2697
if ((fcsr & (1 << cc)) != 0)
2698
target = pc + offset;
2699
else
2700
target = pc + 8;
2701
}
2702
Context context;
2703
2704
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2705
target);
2706
}
2707
2708
bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
2709
bool success = false;
2710
uint32_t ft;
2711
uint32_t ft_val;
2712
int32_t target, pc, offset;
2713
2714
/*
2715
* BC1EQZ ft, offset
2716
* condition <- (FPR[ft].bit0 == 0)
2717
* if condition then
2718
* offset = sign_ext (offset)
2719
* PC = PC + 4 + offset
2720
*/
2721
ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2722
offset = insn.getOperand(1).getImm();
2723
2724
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2725
if (!success)
2726
return false;
2727
2728
ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2729
&success);
2730
if (!success)
2731
return false;
2732
2733
if ((ft_val & 1) == 0)
2734
target = pc + 4 + offset;
2735
else
2736
target = pc + 8;
2737
2738
Context context;
2739
2740
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2741
target);
2742
}
2743
2744
bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
2745
bool success = false;
2746
uint32_t ft;
2747
uint32_t ft_val;
2748
int32_t target, pc, offset;
2749
2750
/*
2751
* BC1NEZ ft, offset
2752
* condition <- (FPR[ft].bit0 != 0)
2753
* if condition then
2754
* offset = sign_ext (offset)
2755
* PC = PC + 4 + offset
2756
*/
2757
ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2758
offset = insn.getOperand(1).getImm();
2759
2760
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2761
if (!success)
2762
return false;
2763
2764
ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2765
&success);
2766
if (!success)
2767
return false;
2768
2769
if ((ft_val & 1) != 0)
2770
target = pc + 4 + offset;
2771
else
2772
target = pc + 8;
2773
2774
Context context;
2775
2776
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2777
target);
2778
}
2779
2780
/*
2781
Emulate MIPS-3D Branch instructions
2782
BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
2783
False/True
2784
BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
2785
False/True
2786
*/
2787
bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) {
2788
bool success = false;
2789
uint32_t cc, fcsr;
2790
int32_t pc, offset, target = 0;
2791
llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
2792
2793
cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2794
offset = insn.getOperand(1).getImm();
2795
2796
pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2797
if (!success)
2798
return false;
2799
2800
fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0,
2801
&success);
2802
if (!success)
2803
return false;
2804
2805
/* fcsr[23], fcsr[25-31] are vaild condition bits */
2806
fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2807
2808
if (op_name.equals_insensitive("BC1ANY2F")) {
2809
/* if any one bit is 0 */
2810
if (((fcsr >> cc) & 3) != 3)
2811
target = pc + offset;
2812
else
2813
target = pc + 8;
2814
} else if (op_name.equals_insensitive("BC1ANY2T")) {
2815
/* if any one bit is 1 */
2816
if (((fcsr >> cc) & 3) != 0)
2817
target = pc + offset;
2818
else
2819
target = pc + 8;
2820
} else if (op_name.equals_insensitive("BC1ANY4F")) {
2821
/* if any one bit is 0 */
2822
if (((fcsr >> cc) & 0xf) != 0xf)
2823
target = pc + offset;
2824
else
2825
target = pc + 8;
2826
} else if (op_name.equals_insensitive("BC1ANY4T")) {
2827
/* if any one bit is 1 */
2828
if (((fcsr >> cc) & 0xf) != 0)
2829
target = pc + offset;
2830
else
2831
target = pc + 8;
2832
}
2833
Context context;
2834
2835
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2836
target);
2837
}
2838
2839
bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) {
2840
return Emulate_MSA_Branch_DF(insn, 1, true);
2841
}
2842
2843
bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) {
2844
return Emulate_MSA_Branch_DF(insn, 2, true);
2845
}
2846
2847
bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) {
2848
return Emulate_MSA_Branch_DF(insn, 4, true);
2849
}
2850
2851
bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) {
2852
return Emulate_MSA_Branch_DF(insn, 8, true);
2853
}
2854
2855
bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) {
2856
return Emulate_MSA_Branch_DF(insn, 1, false);
2857
}
2858
2859
bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) {
2860
return Emulate_MSA_Branch_DF(insn, 2, false);
2861
}
2862
2863
bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) {
2864
return Emulate_MSA_Branch_DF(insn, 4, false);
2865
}
2866
2867
bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) {
2868
return Emulate_MSA_Branch_DF(insn, 8, false);
2869
}
2870
2871
bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
2872
int element_byte_size,
2873
bool bnz) {
2874
bool success = false, branch_hit = true;
2875
int32_t target = 0;
2876
RegisterValue reg_value;
2877
const uint8_t *ptr = nullptr;
2878
2879
uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2880
int32_t offset = insn.getOperand(1).getImm();
2881
2882
int32_t pc =
2883
ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2884
if (!success)
2885
return false;
2886
2887
if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2888
ptr = (const uint8_t *)reg_value.GetBytes();
2889
else
2890
return false;
2891
2892
for (int i = 0; i < 16 / element_byte_size; i++) {
2893
switch (element_byte_size) {
2894
case 1:
2895
if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2896
branch_hit = false;
2897
break;
2898
case 2:
2899
if ((*(const uint16_t *)ptr == 0 && bnz) ||
2900
(*(const uint16_t *)ptr != 0 && !bnz))
2901
branch_hit = false;
2902
break;
2903
case 4:
2904
if ((*(const uint32_t *)ptr == 0 && bnz) ||
2905
(*(const uint32_t *)ptr != 0 && !bnz))
2906
branch_hit = false;
2907
break;
2908
case 8:
2909
if ((*(const uint64_t *)ptr == 0 && bnz) ||
2910
(*(const uint64_t *)ptr != 0 && !bnz))
2911
branch_hit = false;
2912
break;
2913
}
2914
if (!branch_hit)
2915
break;
2916
ptr = ptr + element_byte_size;
2917
}
2918
2919
if (branch_hit)
2920
target = pc + offset;
2921
else
2922
target = pc + 8;
2923
2924
Context context;
2925
context.type = eContextRelativeBranchImmediate;
2926
2927
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2928
target);
2929
}
2930
2931
bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) {
2932
return Emulate_MSA_Branch_V(insn, true);
2933
}
2934
2935
bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) {
2936
return Emulate_MSA_Branch_V(insn, false);
2937
}
2938
2939
bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn,
2940
bool bnz) {
2941
bool success = false;
2942
int32_t target = 0;
2943
llvm::APInt wr_val = llvm::APInt::getZero(128);
2944
llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2945
llvm::APInt zero_value = llvm::APInt::getZero(128);
2946
RegisterValue reg_value;
2947
2948
uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2949
int32_t offset = insn.getOperand(1).getImm();
2950
2951
int32_t pc =
2952
ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2953
if (!success)
2954
return false;
2955
2956
if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2957
wr_val = reg_value.GetAsUInt128(fail_value);
2958
else
2959
return false;
2960
2961
if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2962
(!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2963
target = pc + offset;
2964
else
2965
target = pc + 8;
2966
2967
Context context;
2968
context.type = eContextRelativeBranchImmediate;
2969
2970
return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2971
target);
2972
}
2973
2974
bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) {
2975
bool success = false;
2976
uint32_t base;
2977
int32_t imm, address;
2978
Context bad_vaddr_context;
2979
2980
uint32_t num_operands = insn.getNumOperands();
2981
base =
2982
m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2983
imm = insn.getOperand(num_operands - 1).getImm();
2984
2985
if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base))
2986
return false;
2987
2988
/* read base register */
2989
address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2990
dwarf_zero_mips + base, 0, &success);
2991
if (!success)
2992
return false;
2993
2994
/* destination address */
2995
address = address + imm;
2996
2997
/* Set the bad_vaddr register with base address used in the instruction */
2998
bad_vaddr_context.type = eContextInvalid;
2999
WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3000
address);
3001
3002
return true;
3003
}
3004
3005
bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) {
3006
bool success = false;
3007
uint32_t base, index;
3008
int32_t address, index_address;
3009
Context bad_vaddr_context;
3010
3011
uint32_t num_operands = insn.getNumOperands();
3012
base =
3013
m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3014
index =
3015
m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
3016
3017
if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base))
3018
return false;
3019
3020
if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index))
3021
return false;
3022
3023
/* read base register */
3024
address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
3025
dwarf_zero_mips + base, 0, &success);
3026
if (!success)
3027
return false;
3028
3029
/* read index register */
3030
index_address = (int32_t)ReadRegisterUnsigned(
3031
eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
3032
if (!success)
3033
return false;
3034
3035
/* destination address */
3036
address = address + index_address;
3037
3038
/* Set the bad_vaddr register with base address used in the instruction */
3039
bad_vaddr_context.type = eContextInvalid;
3040
WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3041
address);
3042
3043
return true;
3044
}
3045
3046