1
// Copyright 2013, ARM Limited
2
// All rights reserved.
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are met:
7
// * Redistributions of source code must retain the above copyright notice,
8
// this list of conditions and the following disclaimer.
9
// * Redistributions in binary form must reproduce the above copyright notice,
10
// this list of conditions and the following disclaimer in the documentation
11
// and/or other materials provided with the distribution.
12
// * Neither the name of ARM Limited nor the names of its contributors may be
13
// used to endorse or promote products derived from this software without
14
// specific prior written permission.
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
#include "a64/decoder-a64.h"
32
// Top-level instruction decode function.
33
void Decoder::Decode(Instruction *instr) {
34
if (instr->Bits(28, 27) == 0) {
35
VisitUnallocated(instr);
37
switch (instr->Bits(27, 24)) {
38
// 0: PC relative addressing.
39
case 0x0: DecodePCRelAddressing(instr); break;
41
// 1: Add/sub immediate.
42
case 0x1: DecodeAddSubImmediate(instr); break;
44
// A: Logical shifted register.
45
// Add/sub with carry.
46
// Conditional compare register.
47
// Conditional compare immediate.
48
// Conditional select.
49
// Data processing 1 source.
50
// Data processing 2 source.
51
// B: Add/sub shifted register.
52
// Add/sub extended register.
53
// Data processing 3 source.
55
case 0xB: DecodeDataProcessing(instr); break;
57
// 2: Logical immediate.
58
// Move wide immediate.
59
case 0x2: DecodeLogical(instr); break;
63
case 0x3: DecodeBitfieldExtract(instr); break;
65
// 4: Unconditional branch immediate.
66
// Exception generation.
67
// Compare and branch immediate.
68
// 5: Compare and branch immediate.
69
// Conditional branch.
71
// 6,7: Unconditional branch.
72
// Test and branch immediate.
76
case 0x7: DecodeBranchSystemException(instr); break;
78
// 8,9: Load/store register pair post-index.
79
// Load register literal.
80
// Load/store register unscaled immediate.
81
// Load/store register immediate post-index.
82
// Load/store register immediate pre-index.
83
// Load/store register offset.
84
// Load/store exclusive.
85
// C,D: Load/store register pair offset.
86
// Load/store register pair pre-index.
87
// Load/store register unsigned immediate.
92
case 0xD: DecodeLoadStore(instr); break;
94
// E: FP fixed point conversion.
95
// FP integer conversion.
96
// FP data processing 1 source.
99
// FP data processing 2 source.
100
// FP conditional compare.
101
// FP conditional select.
103
// F: FP data processing 3 source.
106
case 0xF: DecodeFP(instr); break;
111
void Decoder::AppendVisitor(DecoderVisitor* new_visitor) {
112
visitors_.remove(new_visitor);
113
visitors_.push_front(new_visitor);
117
void Decoder::PrependVisitor(DecoderVisitor* new_visitor) {
118
visitors_.remove(new_visitor);
119
visitors_.push_back(new_visitor);
123
void Decoder::InsertVisitorBefore(DecoderVisitor* new_visitor,
124
DecoderVisitor* registered_visitor) {
125
visitors_.remove(new_visitor);
126
std::list<DecoderVisitor*>::iterator it;
127
for (it = visitors_.begin(); it != visitors_.end(); it++) {
128
if (*it == registered_visitor) {
129
visitors_.insert(it, new_visitor);
133
// We reached the end of the list. The last element must be
134
// registered_visitor.
135
ASSERT(*it == registered_visitor);
136
visitors_.insert(it, new_visitor);
140
void Decoder::InsertVisitorAfter(DecoderVisitor* new_visitor,
141
DecoderVisitor* registered_visitor) {
142
visitors_.remove(new_visitor);
143
std::list<DecoderVisitor*>::iterator it;
144
for (it = visitors_.begin(); it != visitors_.end(); it++) {
145
if (*it == registered_visitor) {
147
visitors_.insert(it, new_visitor);
151
// We reached the end of the list. The last element must be
152
// registered_visitor.
153
ASSERT(*it == registered_visitor);
154
visitors_.push_back(new_visitor);
158
void Decoder::RemoveVisitor(DecoderVisitor* visitor) {
159
visitors_.remove(visitor);
163
void Decoder::DecodePCRelAddressing(Instruction* instr) {
164
ASSERT(instr->Bits(27, 24) == 0x0);
165
// We know bit 28 is set, as <b28:b27> = 0 is filtered out at the top level
167
ASSERT(instr->Bit(28) == 0x1);
168
VisitPCRelAddressing(instr);
172
void Decoder::DecodeBranchSystemException(Instruction* instr) {
173
ASSERT((instr->Bits(27, 24) == 0x4) ||
174
(instr->Bits(27, 24) == 0x5) ||
175
(instr->Bits(27, 24) == 0x6) ||
176
(instr->Bits(27, 24) == 0x7) );
178
switch (instr->Bits(31, 29)) {
181
VisitUnconditionalBranch(instr);
186
if (instr->Bit(25) == 0) {
187
VisitCompareBranch(instr);
189
VisitTestBranch(instr);
194
if (instr->Bit(25) == 0) {
195
if ((instr->Bit(24) == 0x1) ||
196
(instr->Mask(0x01000010) == 0x00000010)) {
197
VisitUnallocated(instr);
199
VisitConditionalBranch(instr);
202
VisitUnallocated(instr);
207
if (instr->Bit(25) == 0) {
208
if (instr->Bit(24) == 0) {
209
if ((instr->Bits(4, 2) != 0) ||
210
(instr->Mask(0x00E0001D) == 0x00200001) ||
211
(instr->Mask(0x00E0001D) == 0x00400001) ||
212
(instr->Mask(0x00E0001E) == 0x00200002) ||
213
(instr->Mask(0x00E0001E) == 0x00400002) ||
214
(instr->Mask(0x00E0001C) == 0x00600000) ||
215
(instr->Mask(0x00E0001C) == 0x00800000) ||
216
(instr->Mask(0x00E0001F) == 0x00A00000) ||
217
(instr->Mask(0x00C0001C) == 0x00C00000)) {
218
VisitUnallocated(instr);
220
VisitException(instr);
223
if (instr->Bits(23, 22) == 0) {
224
const Instr masked_003FF0E0 = instr->Mask(0x003FF0E0);
225
if ((instr->Bits(21, 19) == 0x4) ||
226
(masked_003FF0E0 == 0x00033000) ||
227
(masked_003FF0E0 == 0x003FF020) ||
228
(masked_003FF0E0 == 0x003FF060) ||
229
(masked_003FF0E0 == 0x003FF0E0) ||
230
(instr->Mask(0x00388000) == 0x00008000) ||
231
(instr->Mask(0x0038E000) == 0x00000000) ||
232
(instr->Mask(0x0039E000) == 0x00002000) ||
233
(instr->Mask(0x003AE000) == 0x00002000) ||
234
(instr->Mask(0x003CE000) == 0x00042000) ||
235
(instr->Mask(0x003FFFC0) == 0x000320C0) ||
236
(instr->Mask(0x003FF100) == 0x00032100) ||
237
(instr->Mask(0x003FF200) == 0x00032200) ||
238
(instr->Mask(0x003FF400) == 0x00032400) ||
239
(instr->Mask(0x003FF800) == 0x00032800) ||
240
(instr->Mask(0x0038F000) == 0x00005000) ||
241
(instr->Mask(0x0038E000) == 0x00006000)) {
242
VisitUnallocated(instr);
247
VisitUnallocated(instr);
251
if ((instr->Bit(24) == 0x1) ||
252
(instr->Bits(20, 16) != 0x1F) ||
253
(instr->Bits(15, 10) != 0) ||
254
(instr->Bits(4, 0) != 0) ||
255
(instr->Bits(24, 21) == 0x3) ||
256
(instr->Bits(24, 22) == 0x3)) {
257
VisitUnallocated(instr);
259
VisitUnconditionalBranchToRegister(instr);
266
VisitUnallocated(instr);
273
void Decoder::DecodeLoadStore(Instruction* instr) {
274
ASSERT((instr->Bits(27, 24) == 0x8) ||
275
(instr->Bits(27, 24) == 0x9) ||
276
(instr->Bits(27, 24) == 0xC) ||
277
(instr->Bits(27, 24) == 0xD) );
279
if (instr->Bit(24) == 0) {
280
if (instr->Bit(28) == 0) {
281
if (instr->Bit(29) == 0) {
282
if (instr->Bit(26) == 0) {
283
// TODO: VisitLoadStoreExclusive.
284
VisitUnimplemented(instr);
286
DecodeAdvSIMDLoadStore(instr);
289
if ((instr->Bits(31, 30) == 0x3) ||
290
(instr->Mask(0xC4400000) == 0x40000000)) {
291
VisitUnallocated(instr);
293
if (instr->Bit(23) == 0) {
294
if (instr->Mask(0xC4400000) == 0xC0400000) {
295
VisitUnallocated(instr);
297
VisitLoadStorePairNonTemporal(instr);
300
VisitLoadStorePairPostIndex(instr);
305
if (instr->Bit(29) == 0) {
306
if (instr->Mask(0xC4000000) == 0xC4000000) {
307
VisitUnallocated(instr);
309
VisitLoadLiteral(instr);
312
if ((instr->Mask(0x84C00000) == 0x80C00000) ||
313
(instr->Mask(0x44800000) == 0x44800000) ||
314
(instr->Mask(0x84800000) == 0x84800000)) {
315
VisitUnallocated(instr);
317
if (instr->Bit(21) == 0) {
318
switch (instr->Bits(11, 10)) {
320
VisitLoadStoreUnscaledOffset(instr);
324
if (instr->Mask(0xC4C00000) == 0xC0800000) {
325
VisitUnallocated(instr);
327
VisitLoadStorePostIndex(instr);
332
// TODO: VisitLoadStoreRegisterOffsetUnpriv.
333
VisitUnimplemented(instr);
337
if (instr->Mask(0xC4C00000) == 0xC0800000) {
338
VisitUnallocated(instr);
340
VisitLoadStorePreIndex(instr);
346
if (instr->Bits(11, 10) == 0x2) {
347
if (instr->Bit(14) == 0) {
348
VisitUnallocated(instr);
350
VisitLoadStoreRegisterOffset(instr);
353
VisitUnallocated(instr);
360
if (instr->Bit(28) == 0) {
361
if (instr->Bit(29) == 0) {
362
VisitUnallocated(instr);
364
if ((instr->Bits(31, 30) == 0x3) ||
365
(instr->Mask(0xC4400000) == 0x40000000)) {
366
VisitUnallocated(instr);
368
if (instr->Bit(23) == 0) {
369
VisitLoadStorePairOffset(instr);
371
VisitLoadStorePairPreIndex(instr);
376
if (instr->Bit(29) == 0) {
377
VisitUnallocated(instr);
379
if ((instr->Mask(0x84C00000) == 0x80C00000) ||
380
(instr->Mask(0x44800000) == 0x44800000) ||
381
(instr->Mask(0x84800000) == 0x84800000)) {
382
VisitUnallocated(instr);
384
VisitLoadStoreUnsignedOffset(instr);
392
void Decoder::DecodeLogical(Instruction* instr) {
393
ASSERT(instr->Bits(27, 24) == 0x2);
395
if (instr->Mask(0x80400000) == 0x00400000) {
396
VisitUnallocated(instr);
398
if (instr->Bit(23) == 0) {
399
VisitLogicalImmediate(instr);
401
if (instr->Bits(30, 29) == 0x1) {
402
VisitUnallocated(instr);
404
VisitMoveWideImmediate(instr);
411
void Decoder::DecodeBitfieldExtract(Instruction* instr) {
412
ASSERT(instr->Bits(27, 24) == 0x3);
414
if ((instr->Mask(0x80400000) == 0x80000000) ||
415
(instr->Mask(0x80400000) == 0x00400000) ||
416
(instr->Mask(0x80008000) == 0x00008000)) {
417
VisitUnallocated(instr);
418
} else if (instr->Bit(23) == 0) {
419
if ((instr->Mask(0x80200000) == 0x00200000) ||
420
(instr->Mask(0x60000000) == 0x60000000)) {
421
VisitUnallocated(instr);
423
VisitBitfield(instr);
426
if ((instr->Mask(0x60200000) == 0x00200000) ||
427
(instr->Mask(0x60000000) != 0x00000000)) {
428
VisitUnallocated(instr);
436
void Decoder::DecodeAddSubImmediate(Instruction* instr) {
437
ASSERT(instr->Bits(27, 24) == 0x1);
438
if (instr->Bit(23) == 1) {
439
VisitUnallocated(instr);
441
VisitAddSubImmediate(instr);
446
void Decoder::DecodeDataProcessing(Instruction* instr) {
447
ASSERT((instr->Bits(27, 24) == 0xA) ||
448
(instr->Bits(27, 24) == 0xB) );
450
if (instr->Bit(24) == 0) {
451
if (instr->Bit(28) == 0) {
452
if (instr->Mask(0x80008000) == 0x00008000) {
453
VisitUnallocated(instr);
455
VisitLogicalShifted(instr);
458
switch (instr->Bits(23, 21)) {
460
if (instr->Mask(0x0000FC00) != 0) {
461
VisitUnallocated(instr);
463
VisitAddSubWithCarry(instr);
468
if ((instr->Bit(29) == 0) ||
469
(instr->Mask(0x00000410) != 0)) {
470
VisitUnallocated(instr);
472
if (instr->Bit(11) == 0) {
473
VisitConditionalCompareRegister(instr);
475
VisitConditionalCompareImmediate(instr);
481
if (instr->Mask(0x20000800) != 0x00000000) {
482
VisitUnallocated(instr);
484
VisitConditionalSelect(instr);
489
if (instr->Bit(29) == 0x1) {
490
VisitUnallocated(instr);
492
if (instr->Bit(30) == 0) {
493
if ((instr->Bit(15) == 0x1) ||
494
(instr->Bits(15, 11) == 0) ||
495
(instr->Bits(15, 12) == 0x1) ||
496
(instr->Bits(15, 12) == 0x3) ||
497
(instr->Bits(15, 13) == 0x3) ||
498
(instr->Mask(0x8000EC00) == 0x00004C00) ||
499
(instr->Mask(0x8000E800) == 0x80004000) ||
500
(instr->Mask(0x8000E400) == 0x80004000)) {
501
VisitUnallocated(instr);
503
VisitDataProcessing2Source(instr);
506
if ((instr->Bit(13) == 1) ||
507
(instr->Bits(20, 16) != 0) ||
508
(instr->Bits(15, 14) != 0) ||
509
(instr->Mask(0xA01FFC00) == 0x00000C00) ||
510
(instr->Mask(0x201FF800) == 0x00001800)) {
511
VisitUnallocated(instr);
513
VisitDataProcessing1Source(instr);
522
case 7: VisitUnallocated(instr); break;
526
if (instr->Bit(28) == 0) {
527
if (instr->Bit(21) == 0) {
528
if ((instr->Bits(23, 22) == 0x3) ||
529
(instr->Mask(0x80008000) == 0x00008000)) {
530
VisitUnallocated(instr);
532
VisitAddSubShifted(instr);
535
if ((instr->Mask(0x00C00000) != 0x00000000) ||
536
(instr->Mask(0x00001400) == 0x00001400) ||
537
(instr->Mask(0x00001800) == 0x00001800)) {
538
VisitUnallocated(instr);
540
VisitAddSubExtended(instr);
544
if ((instr->Bit(30) == 0x1) ||
545
(instr->Bits(30, 29) == 0x1) ||
546
(instr->Mask(0xE0600000) == 0x00200000) ||
547
(instr->Mask(0xE0608000) == 0x00400000) ||
548
(instr->Mask(0x60608000) == 0x00408000) ||
549
(instr->Mask(0x60E00000) == 0x00E00000) ||
550
(instr->Mask(0x60E00000) == 0x00800000) ||
551
(instr->Mask(0x60E00000) == 0x00600000)) {
552
VisitUnallocated(instr);
554
VisitDataProcessing3Source(instr);
561
void Decoder::DecodeFP(Instruction* instr) {
562
ASSERT((instr->Bits(27, 24) == 0xE) ||
563
(instr->Bits(27, 24) == 0xF) );
565
if (instr->Bit(28) == 0) {
566
DecodeAdvSIMDDataProcessing(instr);
568
if (instr->Bit(29) == 1) {
569
VisitUnallocated(instr);
571
if (instr->Bits(31, 30) == 0x3) {
572
VisitUnallocated(instr);
573
} else if (instr->Bits(31, 30) == 0x1) {
574
DecodeAdvSIMDDataProcessing(instr);
576
if (instr->Bit(24) == 0) {
577
if (instr->Bit(21) == 0) {
578
if ((instr->Bit(23) == 1) ||
579
(instr->Bit(18) == 1) ||
580
(instr->Mask(0x80008000) == 0x00000000) ||
581
(instr->Mask(0x000E0000) == 0x00000000) ||
582
(instr->Mask(0x000E0000) == 0x000A0000) ||
583
(instr->Mask(0x00160000) == 0x00000000) ||
584
(instr->Mask(0x00160000) == 0x00120000)) {
585
VisitUnallocated(instr);
587
VisitFPFixedPointConvert(instr);
590
if (instr->Bits(15, 10) == 32) {
591
VisitUnallocated(instr);
592
} else if (instr->Bits(15, 10) == 0) {
593
if ((instr->Bits(23, 22) == 0x3) ||
594
(instr->Mask(0x000E0000) == 0x000A0000) ||
595
(instr->Mask(0x000E0000) == 0x000C0000) ||
596
(instr->Mask(0x00160000) == 0x00120000) ||
597
(instr->Mask(0x00160000) == 0x00140000) ||
598
(instr->Mask(0x20C40000) == 0x00800000) ||
599
(instr->Mask(0x20C60000) == 0x00840000) ||
600
(instr->Mask(0xA0C60000) == 0x80060000) ||
601
(instr->Mask(0xA0C60000) == 0x00860000) ||
602
(instr->Mask(0xA0C60000) == 0x00460000) ||
603
(instr->Mask(0xA0CE0000) == 0x80860000) ||
604
(instr->Mask(0xA0CE0000) == 0x804E0000) ||
605
(instr->Mask(0xA0CE0000) == 0x000E0000) ||
606
(instr->Mask(0xA0D60000) == 0x00160000) ||
607
(instr->Mask(0xA0D60000) == 0x80560000) ||
608
(instr->Mask(0xA0D60000) == 0x80960000)) {
609
VisitUnallocated(instr);
611
VisitFPIntegerConvert(instr);
613
} else if (instr->Bits(14, 10) == 16) {
614
const Instr masked_A0DF8000 = instr->Mask(0xA0DF8000);
615
if ((instr->Mask(0x80180000) != 0) ||
616
(masked_A0DF8000 == 0x00020000) ||
617
(masked_A0DF8000 == 0x00030000) ||
618
(masked_A0DF8000 == 0x00068000) ||
619
(masked_A0DF8000 == 0x00428000) ||
620
(masked_A0DF8000 == 0x00430000) ||
621
(masked_A0DF8000 == 0x00468000) ||
622
(instr->Mask(0xA0D80000) == 0x00800000) ||
623
(instr->Mask(0xA0DE0000) == 0x00C00000) ||
624
(instr->Mask(0xA0DF0000) == 0x00C30000) ||
625
(instr->Mask(0xA0DC0000) == 0x00C40000)) {
626
VisitUnallocated(instr);
628
VisitFPDataProcessing1Source(instr);
630
} else if (instr->Bits(13, 10) == 8) {
631
if ((instr->Bits(15, 14) != 0) ||
632
(instr->Bits(2, 0) != 0) ||
633
(instr->Mask(0x80800000) != 0x00000000)) {
634
VisitUnallocated(instr);
636
VisitFPCompare(instr);
638
} else if (instr->Bits(12, 10) == 4) {
639
if ((instr->Bits(9, 5) != 0) ||
640
(instr->Mask(0x80800000) != 0x00000000)) {
641
VisitUnallocated(instr);
643
VisitFPImmediate(instr);
646
if (instr->Mask(0x80800000) != 0x00000000) {
647
VisitUnallocated(instr);
649
switch (instr->Bits(11, 10)) {
651
VisitFPConditionalCompare(instr);
655
if ((instr->Bits(15, 14) == 0x3) ||
656
(instr->Mask(0x00009000) == 0x00009000) ||
657
(instr->Mask(0x0000A000) == 0x0000A000)) {
658
VisitUnallocated(instr);
660
VisitFPDataProcessing2Source(instr);
665
VisitFPConditionalSelect(instr);
668
default: UNREACHABLE();
674
// Bit 30 == 1 has been handled earlier.
675
ASSERT(instr->Bit(30) == 0);
676
if (instr->Mask(0xA0800000) != 0) {
677
VisitUnallocated(instr);
679
VisitFPDataProcessing3Source(instr);
688
void Decoder::DecodeAdvSIMDLoadStore(Instruction* instr) {
689
// TODO: Implement Advanced SIMD load/store instruction decode.
690
ASSERT(instr->Bits(29, 25) == 0x6);
691
VisitUnimplemented(instr);
695
void Decoder::DecodeAdvSIMDDataProcessing(Instruction* instr) {
696
// TODO: Implement Advanced SIMD data processing instruction decode.
697
ASSERT(instr->Bits(27, 25) == 0x7);
698
VisitUnimplemented(instr);
702
#define DEFINE_VISITOR_CALLERS(A) \
703
void Decoder::Visit##A(Instruction *instr) { \
704
ASSERT(instr->Mask(A##FMask) == A##Fixed); \
705
std::list<DecoderVisitor*>::iterator it; \
706
for (it = visitors_.begin(); it != visitors_.end(); it++) { \
707
(*it)->Visit##A(instr); \
710
VISITOR_LIST(DEFINE_VISITOR_CALLERS)
711
#undef DEFINE_VISITOR_CALLERS