blob: 38d0e8eddefd1f5bf057df88bac6e65ddc874582 [file] [log] [blame]
Tim Northovere0e3aef2013-01-31 12:12:40 +00001//===- AArch64Disassembler.cpp - Disassembler for AArch64/Thumb ISA -------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#define DEBUG_TYPE "arm-disassembler"
11
12#include "AArch64.h"
13#include "AArch64RegisterInfo.h"
14#include "AArch64Subtarget.h"
Tim Northover969afbe2013-02-05 13:24:47 +000015#include "Utils/AArch64BaseInfo.h"
Tim Northovere0e3aef2013-01-31 12:12:40 +000016#include "llvm/MC/MCInst.h"
17#include "llvm/MC/MCInstrDesc.h"
18#include "llvm/MC/MCExpr.h"
19#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCDisassembler.h"
21#include "llvm/MC/MCFixedLenDisassembler.h"
22#include "llvm/Support/Debug.h"
23#include "llvm/Support/MemoryObject.h"
24#include "llvm/Support/ErrorHandling.h"
25#include "llvm/Support/TargetRegistry.h"
26#include "llvm/Support/raw_ostream.h"
27
28using namespace llvm;
29
30typedef MCDisassembler::DecodeStatus DecodeStatus;
31
32namespace {
33/// AArch64 disassembler for all AArch64 platforms.
34class AArch64Disassembler : public MCDisassembler {
35 const MCRegisterInfo *RegInfo;
36public:
37 /// Initializes the disassembler.
38 ///
39 AArch64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info)
40 : MCDisassembler(STI), RegInfo(Info) {
41 }
42
43 ~AArch64Disassembler() {
44 }
45
46 /// See MCDisassembler.
47 DecodeStatus getInstruction(MCInst &instr,
48 uint64_t &size,
49 const MemoryObject &region,
50 uint64_t address,
51 raw_ostream &vStream,
52 raw_ostream &cStream) const;
53
54 const MCRegisterInfo *getRegInfo() const { return RegInfo; }
55};
56
57}
58
59// Forward-declarations used in the auto-generated files.
60static DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
61 uint64_t Address, const void *Decoder);
62static DecodeStatus
63DecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
64 uint64_t Address, const void *Decoder);
65
66static DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
67 uint64_t Address, const void *Decoder);
68static DecodeStatus
69DecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
70 uint64_t Address, const void *Decoder);
71
72static DecodeStatus DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
73 uint64_t Address, const void *Decoder);
74static DecodeStatus DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
75 uint64_t Address, const void *Decoder);
76static DecodeStatus DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
77 uint64_t Address, const void *Decoder);
78static DecodeStatus DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
79 uint64_t Address, const void *Decoder);
Tim Northoverbcaca872013-02-05 13:24:56 +000080static DecodeStatus DecodeFPR128RegisterClass(llvm::MCInst &Inst,
81 unsigned RegNo, uint64_t Address,
82 const void *Decoder);
83static DecodeStatus DecodeVPR128RegisterClass(llvm::MCInst &Inst,
84 unsigned RegNo, uint64_t Address,
85 const void *Decoder);
Tim Northovere0e3aef2013-01-31 12:12:40 +000086
87static DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst,
88 unsigned OptionHiS,
89 uint64_t Address,
90 const void *Decoder);
91
92
93static DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst,
94 unsigned Imm6Bits,
95 uint64_t Address,
96 const void *Decoder);
97
98static DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst,
99 unsigned Imm6Bits,
100 uint64_t Address,
101 const void *Decoder);
102
103template<int RegWidth>
104static DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst,
105 unsigned FullImm,
106 uint64_t Address,
107 const void *Decoder);
108
109template<int RegWidth>
110static DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst,
111 unsigned Bits,
112 uint64_t Address,
113 const void *Decoder);
114
115static DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst,
116 unsigned ShiftAmount,
117 uint64_t Address,
118 const void *Decoder);
119
120static DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst,
121 unsigned ShiftAmount,
122 uint64_t Address,
123 const void *Decoder);
124static DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn,
125 uint64_t Address,
126 const void *Decoder);
127
128static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
129 uint64_t Address,
130 const void *Decoder);
131
132static DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst,
133 unsigned Insn,
134 uint64_t Address,
135 const void *Decoder);
136
137static DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst,
138 unsigned Val,
139 uint64_t Address,
140 const void *Decoder);
141
142template<typename SomeNamedImmMapper>
143static DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst,
144 unsigned Val,
145 uint64_t Address,
146 const void *Decoder);
147
Tim Northoverbcaca872013-02-05 13:24:56 +0000148static DecodeStatus
149DecodeSysRegOperand(const A64SysReg::SysRegMapper &InstMapper,
150 llvm::MCInst &Inst, unsigned Val,
151 uint64_t Address, const void *Decoder);
Tim Northovere0e3aef2013-01-31 12:12:40 +0000152
153static DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst,
154 unsigned Val,
155 uint64_t Address,
156 const void *Decoder);
157
158static DecodeStatus DecodeMSROperand(llvm::MCInst &Inst,
159 unsigned Val,
160 uint64_t Address,
161 const void *Decoder);
162
163
164static DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst,
165 unsigned Val,
166 uint64_t Address,
167 const void *Decoder);
168
169
170static bool Check(DecodeStatus &Out, DecodeStatus In);
171
172#include "AArch64GenDisassemblerTables.inc"
173#include "AArch64GenInstrInfo.inc"
174
175static bool Check(DecodeStatus &Out, DecodeStatus In) {
176 switch (In) {
177 case MCDisassembler::Success:
178 // Out stays the same.
179 return true;
180 case MCDisassembler::SoftFail:
181 Out = In;
182 return true;
183 case MCDisassembler::Fail:
184 Out = In;
185 return false;
186 }
187 llvm_unreachable("Invalid DecodeStatus!");
188}
189
190DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
191 const MemoryObject &Region,
192 uint64_t Address,
193 raw_ostream &os,
194 raw_ostream &cs) const {
195 CommentStream = &cs;
196
197 uint8_t bytes[4];
198
199 // We want to read exactly 4 bytes of data.
200 if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
201 Size = 0;
202 return MCDisassembler::Fail;
203 }
204
205 // Encoded as a small-endian 32-bit word in the stream.
206 uint32_t insn = (bytes[3] << 24) |
207 (bytes[2] << 16) |
208 (bytes[1] << 8) |
209 (bytes[0] << 0);
210
211 // Calling the auto-generated decoder function.
212 DecodeStatus result = decodeInstruction(DecoderTableA6432, MI, insn, Address,
213 this, STI);
214 if (result != MCDisassembler::Fail) {
215 Size = 4;
216 return result;
217 }
218
219 MI.clear();
220 Size = 0;
221 return MCDisassembler::Fail;
222}
223
224static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
225 const AArch64Disassembler *Dis = static_cast<const AArch64Disassembler*>(D);
226 return Dis->getRegInfo()->getRegClass(RC).getRegister(RegNo);
227}
228
229static DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
230 uint64_t Address, const void *Decoder) {
231 if (RegNo > 31)
232 return MCDisassembler::Fail;
233
234 uint16_t Register = getReg(Decoder, AArch64::GPR64RegClassID, RegNo);
235 Inst.addOperand(MCOperand::CreateReg(Register));
236 return MCDisassembler::Success;
237}
238
239static DecodeStatus
240DecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
241 uint64_t Address, const void *Decoder) {
242 if (RegNo > 31)
243 return MCDisassembler::Fail;
244
245 uint16_t Register = getReg(Decoder, AArch64::GPR64xspRegClassID, RegNo);
246 Inst.addOperand(MCOperand::CreateReg(Register));
247 return MCDisassembler::Success;
248}
249
250static DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Tim Northoverbcaca872013-02-05 13:24:56 +0000251 uint64_t Address,
252 const void *Decoder) {
Tim Northovere0e3aef2013-01-31 12:12:40 +0000253 if (RegNo > 31)
254 return MCDisassembler::Fail;
255
256 uint16_t Register = getReg(Decoder, AArch64::GPR32RegClassID, RegNo);
257 Inst.addOperand(MCOperand::CreateReg(Register));
258 return MCDisassembler::Success;
259}
260
261static DecodeStatus
262DecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
263 uint64_t Address, const void *Decoder) {
264 if (RegNo > 31)
265 return MCDisassembler::Fail;
266
267 uint16_t Register = getReg(Decoder, AArch64::GPR32wspRegClassID, RegNo);
268 Inst.addOperand(MCOperand::CreateReg(Register));
269 return MCDisassembler::Success;
270}
271
272static DecodeStatus
273DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
274 uint64_t Address, const void *Decoder) {
275 if (RegNo > 31)
276 return MCDisassembler::Fail;
277
278 uint16_t Register = getReg(Decoder, AArch64::FPR8RegClassID, RegNo);
279 Inst.addOperand(MCOperand::CreateReg(Register));
280 return MCDisassembler::Success;
281}
282
283static DecodeStatus
284DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
285 uint64_t Address, const void *Decoder) {
286 if (RegNo > 31)
287 return MCDisassembler::Fail;
288
289 uint16_t Register = getReg(Decoder, AArch64::FPR16RegClassID, RegNo);
290 Inst.addOperand(MCOperand::CreateReg(Register));
291 return MCDisassembler::Success;
292}
293
294
295static DecodeStatus
296DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
297 uint64_t Address, const void *Decoder) {
298 if (RegNo > 31)
299 return MCDisassembler::Fail;
300
301 uint16_t Register = getReg(Decoder, AArch64::FPR32RegClassID, RegNo);
302 Inst.addOperand(MCOperand::CreateReg(Register));
303 return MCDisassembler::Success;
304}
305
306static DecodeStatus
307DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
308 uint64_t Address, const void *Decoder) {
309 if (RegNo > 31)
310 return MCDisassembler::Fail;
311
312 uint16_t Register = getReg(Decoder, AArch64::FPR64RegClassID, RegNo);
313 Inst.addOperand(MCOperand::CreateReg(Register));
314 return MCDisassembler::Success;
315}
316
317
318static DecodeStatus
319DecodeFPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
320 uint64_t Address, const void *Decoder) {
321 if (RegNo > 31)
322 return MCDisassembler::Fail;
323
324 uint16_t Register = getReg(Decoder, AArch64::FPR128RegClassID, RegNo);
325 Inst.addOperand(MCOperand::CreateReg(Register));
326 return MCDisassembler::Success;
327}
328
Tim Northovere0e3aef2013-01-31 12:12:40 +0000329static DecodeStatus
330DecodeVPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
331 uint64_t Address, const void *Decoder) {
332 if (RegNo > 31)
333 return MCDisassembler::Fail;
334
335 uint16_t Register = getReg(Decoder, AArch64::VPR128RegClassID, RegNo);
336 Inst.addOperand(MCOperand::CreateReg(Register));
337 return MCDisassembler::Success;
338}
339
340static DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst,
341 unsigned OptionHiS,
342 uint64_t Address,
343 const void *Decoder) {
344 // Option{1} must be 1. OptionHiS is made up of {Option{2}, Option{1},
345 // S}. Hence we want to check bit 1.
346 if (!(OptionHiS & 2))
347 return MCDisassembler::Fail;
348
349 Inst.addOperand(MCOperand::CreateImm(OptionHiS));
350 return MCDisassembler::Success;
351}
352
353static DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst,
354 unsigned Imm6Bits,
355 uint64_t Address,
356 const void *Decoder) {
357 // In the 32-bit variant, bit 6 must be zero. I.e. the immediate must be
358 // between 0 and 31.
359 if (Imm6Bits > 31)
360 return MCDisassembler::Fail;
361
362 Inst.addOperand(MCOperand::CreateImm(Imm6Bits));
363 return MCDisassembler::Success;
364}
365
366static DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst,
367 unsigned Imm6Bits,
368 uint64_t Address,
369 const void *Decoder) {
370 // 1 <= Imm <= 32. Encoded as 64 - Imm so: 63 >= Encoded >= 32.
371 if (Imm6Bits < 32)
372 return MCDisassembler::Fail;
373
374 Inst.addOperand(MCOperand::CreateImm(Imm6Bits));
375 return MCDisassembler::Success;
376}
377
378
379template<int RegWidth>
380static DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst,
381 unsigned FullImm,
382 uint64_t Address,
383 const void *Decoder) {
384 unsigned Imm16 = FullImm & 0xffff;
385 unsigned Shift = FullImm >> 16;
386
387 if (RegWidth == 32 && Shift > 1) return MCDisassembler::Fail;
388
389 Inst.addOperand(MCOperand::CreateImm(Imm16));
390 Inst.addOperand(MCOperand::CreateImm(Shift));
391 return MCDisassembler::Success;
392}
393
394template<int RegWidth>
395static DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst,
396 unsigned Bits,
397 uint64_t Address,
398 const void *Decoder) {
399 uint64_t Imm;
400 if (!A64Imms::isLogicalImmBits(RegWidth, Bits, Imm))
401 return MCDisassembler::Fail;
402
403 Inst.addOperand(MCOperand::CreateImm(Bits));
404 return MCDisassembler::Success;
405}
406
407
408static DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst,
409 unsigned ShiftAmount,
410 uint64_t Address,
411 const void *Decoder) {
412 // Only values 0-4 are valid for this 3-bit field
413 if (ShiftAmount > 4)
414 return MCDisassembler::Fail;
415
416 Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
417 return MCDisassembler::Success;
418}
419
420static DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst,
421 unsigned ShiftAmount,
422 uint64_t Address,
423 const void *Decoder) {
424 // Only values below 32 are valid for a 32-bit register
425 if (ShiftAmount > 31)
426 return MCDisassembler::Fail;
427
428 Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
429 return MCDisassembler::Success;
430}
431
432static DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn,
433 uint64_t Address,
434 const void *Decoder) {
435 unsigned Rd = fieldFromInstruction(Insn, 0, 5);
436 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
437 unsigned ImmS = fieldFromInstruction(Insn, 10, 6);
438 unsigned ImmR = fieldFromInstruction(Insn, 16, 6);
439 unsigned SF = fieldFromInstruction(Insn, 31, 1);
440
441 // Undef for 0b11 just in case it occurs. Don't want the compiler to optimise
442 // out assertions that it thinks should never be hit.
443 enum OpcTypes { SBFM = 0, BFM, UBFM, Undef } Opc;
444 Opc = (OpcTypes)fieldFromInstruction(Insn, 29, 2);
445
446 if (!SF) {
447 // ImmR and ImmS must be between 0 and 31 for 32-bit instructions.
448 if (ImmR > 31 || ImmS > 31)
449 return MCDisassembler::Fail;
450 }
451
452 if (SF) {
453 DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
454 // BFM MCInsts use Rd as a source too.
455 if (Opc == BFM) DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
456 DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
457 } else {
458 DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
459 // BFM MCInsts use Rd as a source too.
460 if (Opc == BFM) DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
461 DecodeGPR32RegisterClass(Inst, Rn, Address, Decoder);
462 }
463
464 // ASR and LSR have more specific patterns so they won't get here:
Tim Northoverbcaca872013-02-05 13:24:56 +0000465 assert(!(ImmS == 31 && !SF && Opc != BFM)
466 && "shift should have used auto decode");
467 assert(!(ImmS == 63 && SF && Opc != BFM)
468 && "shift should have used auto decode");
Tim Northovere0e3aef2013-01-31 12:12:40 +0000469
470 // Extension instructions similarly:
471 if (Opc == SBFM && ImmR == 0) {
472 assert((ImmS != 7 && ImmS != 15) && "extension got here");
473 assert((ImmS != 31 || SF == 0) && "extension got here");
474 } else if (Opc == UBFM && ImmR == 0) {
475 assert((SF != 0 || (ImmS != 7 && ImmS != 15)) && "extension got here");
476 }
477
478 if (Opc == UBFM) {
479 // It might be a LSL instruction, which actually takes the shift amount
480 // itself as an MCInst operand.
481 if (SF && (ImmS + 1) % 64 == ImmR) {
482 Inst.setOpcode(AArch64::LSLxxi);
483 Inst.addOperand(MCOperand::CreateImm(63 - ImmS));
484 return MCDisassembler::Success;
485 } else if (!SF && (ImmS + 1) % 32 == ImmR) {
486 Inst.setOpcode(AArch64::LSLwwi);
487 Inst.addOperand(MCOperand::CreateImm(31 - ImmS));
488 return MCDisassembler::Success;
489 }
490 }
491
492 // Otherwise it's definitely either an extract or an insert depending on which
493 // of ImmR or ImmS is larger.
494 unsigned ExtractOp, InsertOp;
495 switch (Opc) {
496 default: llvm_unreachable("unexpected instruction trying to decode bitfield");
497 case SBFM:
498 ExtractOp = SF ? AArch64::SBFXxxii : AArch64::SBFXwwii;
499 InsertOp = SF ? AArch64::SBFIZxxii : AArch64::SBFIZwwii;
500 break;
501 case BFM:
502 ExtractOp = SF ? AArch64::BFXILxxii : AArch64::BFXILwwii;
503 InsertOp = SF ? AArch64::BFIxxii : AArch64::BFIwwii;
504 break;
505 case UBFM:
506 ExtractOp = SF ? AArch64::UBFXxxii : AArch64::UBFXwwii;
507 InsertOp = SF ? AArch64::UBFIZxxii : AArch64::UBFIZwwii;
508 break;
509 }
510
511 // Otherwise it's a boring insert or extract
512 Inst.addOperand(MCOperand::CreateImm(ImmR));
513 Inst.addOperand(MCOperand::CreateImm(ImmS));
514
515
516 if (ImmS < ImmR)
517 Inst.setOpcode(InsertOp);
518 else
519 Inst.setOpcode(ExtractOp);
520
521 return MCDisassembler::Success;
522}
523
524static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
525 uint64_t Address,
526 const void *Decoder) {
527 // This decoder exists to add the dummy Lane operand to the MCInst, which must
528 // be 1 in assembly but has no other real manifestation.
529 unsigned Rd = fieldFromInstruction(Insn, 0, 5);
530 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
531 unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
532
533 if (IsToVec) {
534 DecodeVPR128RegisterClass(Inst, Rd, Address, Decoder);
535 DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
536 } else {
537 DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
538 DecodeVPR128RegisterClass(Inst, Rn, Address, Decoder);
539 }
540
541 // Add the lane
542 Inst.addOperand(MCOperand::CreateImm(1));
543
544 return MCDisassembler::Success;
545}
546
547
548static DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst,
549 unsigned Insn,
550 uint64_t Address,
551 const void *Decoder) {
552 DecodeStatus Result = MCDisassembler::Success;
553 unsigned Rt = fieldFromInstruction(Insn, 0, 5);
554 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
555 unsigned Rt2 = fieldFromInstruction(Insn, 10, 5);
556 unsigned SImm7 = fieldFromInstruction(Insn, 15, 7);
557 unsigned L = fieldFromInstruction(Insn, 22, 1);
558 unsigned V = fieldFromInstruction(Insn, 26, 1);
559 unsigned Opc = fieldFromInstruction(Insn, 30, 2);
560
561 // Not an official name, but it turns out that bit 23 distinguishes indexed
562 // from non-indexed operations.
563 unsigned Indexed = fieldFromInstruction(Insn, 23, 1);
564
565 if (Indexed && L == 0) {
566 // The MCInst for an indexed store has an out operand and 4 ins:
567 // Rn_wb, Rt, Rt2, Rn, Imm
568 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
569 }
570
571 // You shouldn't load to the same register twice in an instruction...
572 if (L && Rt == Rt2)
573 Result = MCDisassembler::SoftFail;
574
575 // ... or do any operation that writes-back to a transfer register. But note
576 // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
577 if (Indexed && V == 0 && Rn != 31 && (Rt == Rn || Rt2 == Rn))
578 Result = MCDisassembler::SoftFail;
579
580 // Exactly how we decode the MCInst's registers depends on the Opc and V
581 // fields of the instruction. These also obviously determine the size of the
582 // operation so we can fill in that information while we're at it.
583 if (V) {
584 // The instruction operates on the FP/SIMD registers
585 switch (Opc) {
586 default: return MCDisassembler::Fail;
587 case 0:
588 DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
589 DecodeFPR32RegisterClass(Inst, Rt2, Address, Decoder);
590 break;
591 case 1:
592 DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
593 DecodeFPR64RegisterClass(Inst, Rt2, Address, Decoder);
594 break;
595 case 2:
596 DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
597 DecodeFPR128RegisterClass(Inst, Rt2, Address, Decoder);
598 break;
599 }
600 } else {
601 switch (Opc) {
602 default: return MCDisassembler::Fail;
603 case 0:
604 DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
605 DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder);
606 break;
607 case 1:
608 assert(L && "unexpected \"store signed\" attempt");
609 DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
610 DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
611 break;
612 case 2:
613 DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
614 DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
615 break;
616 }
617 }
618
619 if (Indexed && L == 1) {
620 // The MCInst for an indexed load has 3 out operands and an 3 ins:
621 // Rt, Rt2, Rn_wb, Rt2, Rn, Imm
622 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
623 }
624
625
626 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
627 Inst.addOperand(MCOperand::CreateImm(SImm7));
628
629 return Result;
630}
631
632static DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst,
633 uint32_t Val,
634 uint64_t Address,
635 const void *Decoder) {
636 unsigned Rt = fieldFromInstruction(Val, 0, 5);
637 unsigned Rn = fieldFromInstruction(Val, 5, 5);
638 unsigned Rt2 = fieldFromInstruction(Val, 10, 5);
639 unsigned MemSize = fieldFromInstruction(Val, 30, 2);
640
641 DecodeStatus S = MCDisassembler::Success;
642 if (Rt == Rt2) S = MCDisassembler::SoftFail;
643
644 switch (MemSize) {
645 case 2:
646 if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder)))
647 return MCDisassembler::Fail;
648 if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder)))
649 return MCDisassembler::Fail;
650 break;
651 case 3:
652 if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder)))
653 return MCDisassembler::Fail;
654 if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder)))
655 return MCDisassembler::Fail;
656 break;
657 default:
658 llvm_unreachable("Invalid MemSize in DecodeLoadPairExclusiveInstruction");
659 }
660
661 if (!Check(S, DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder)))
662 return MCDisassembler::Fail;
663
664 return S;
665}
666
667template<typename SomeNamedImmMapper>
668static DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst,
669 unsigned Val,
670 uint64_t Address,
671 const void *Decoder) {
672 SomeNamedImmMapper Mapper;
673 bool ValidNamed;
674 Mapper.toString(Val, ValidNamed);
675 if (ValidNamed || Mapper.validImm(Val)) {
676 Inst.addOperand(MCOperand::CreateImm(Val));
677 return MCDisassembler::Success;
678 }
679
680 return MCDisassembler::Fail;
681}
682
683static DecodeStatus DecodeSysRegOperand(const A64SysReg::SysRegMapper &Mapper,
684 llvm::MCInst &Inst,
685 unsigned Val,
686 uint64_t Address,
687 const void *Decoder) {
688 bool ValidNamed;
689 Mapper.toString(Val, ValidNamed);
690
691 Inst.addOperand(MCOperand::CreateImm(Val));
692
693 return ValidNamed ? MCDisassembler::Success : MCDisassembler::Fail;
694}
695
696static DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst,
697 unsigned Val,
698 uint64_t Address,
699 const void *Decoder) {
700 return DecodeSysRegOperand(A64SysReg::MRSMapper(), Inst, Val, Address,
701 Decoder);
702}
703
704static DecodeStatus DecodeMSROperand(llvm::MCInst &Inst,
705 unsigned Val,
706 uint64_t Address,
707 const void *Decoder) {
708 return DecodeSysRegOperand(A64SysReg::MSRMapper(), Inst, Val, Address,
709 Decoder);
710}
711
712static DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst,
713 unsigned Insn,
714 uint64_t Address,
715 const void *Decoder) {
716 unsigned Rt = fieldFromInstruction(Insn, 0, 5);
717 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
718 unsigned Imm9 = fieldFromInstruction(Insn, 12, 9);
719
720 unsigned Opc = fieldFromInstruction(Insn, 22, 2);
721 unsigned V = fieldFromInstruction(Insn, 26, 1);
722 unsigned Size = fieldFromInstruction(Insn, 30, 2);
723
724 if (Opc == 0 || (V == 1 && Opc == 2)) {
725 // It's a store, the MCInst gets: Rn_wb, Rt, Rn, Imm
726 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
727 }
728
729 if (V == 0 && (Opc == 2 || Size == 3)) {
730 DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
731 } else if (V == 0) {
732 DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
733 } else if (V == 1 && (Opc & 2)) {
734 DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
735 } else {
736 switch (Size) {
737 case 0:
738 DecodeFPR8RegisterClass(Inst, Rt, Address, Decoder);
739 break;
740 case 1:
741 DecodeFPR16RegisterClass(Inst, Rt, Address, Decoder);
742 break;
743 case 2:
744 DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
745 break;
746 case 3:
747 DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
748 break;
749 }
750 }
751
752 if (Opc != 0 && (V != 1 || Opc != 2)) {
753 // It's a load, the MCInst gets: Rt, Rn_wb, Rn, Imm
754 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
755 }
756
757 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
758
759 Inst.addOperand(MCOperand::CreateImm(Imm9));
760
761 // N.b. The official documentation says undpredictable if Rt == Rn, but this
762 // takes place at the architectural rather than encoding level:
763 //
764 // "STR xzr, [sp], #4" is perfectly valid.
765 if (V == 0 && Rt == Rn && Rn != 31)
766 return MCDisassembler::SoftFail;
767 else
768 return MCDisassembler::Success;
769}
770
771static MCDisassembler *createAArch64Disassembler(const Target &T,
772 const MCSubtargetInfo &STI) {
773 return new AArch64Disassembler(STI, T.createMCRegInfo(""));
774}
775
776extern "C" void LLVMInitializeAArch64Disassembler() {
777 TargetRegistry::RegisterMCDisassembler(TheAArch64Target,
778 createAArch64Disassembler);
779}
780
781