1 //===- AArch64Disassembler.cpp - Disassembler for AArch64/Thumb ISA -------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #define DEBUG_TYPE "arm-disassembler"
13 #include "AArch64RegisterInfo.h"
14 #include "AArch64Subtarget.h"
15 #include "MCTargetDesc/AArch64BaseInfo.h"
16 #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"
30 typedef MCDisassembler::DecodeStatus DecodeStatus;
33 /// AArch64 disassembler for all AArch64 platforms.
34 class AArch64Disassembler : public MCDisassembler {
35 const MCRegisterInfo *RegInfo;
37 /// Initializes the disassembler.
39 AArch64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info)
40 : MCDisassembler(STI), RegInfo(Info) {
43 ~AArch64Disassembler() {
46 /// See MCDisassembler.
47 DecodeStatus getInstruction(MCInst &instr,
49 const MemoryObject ®ion,
52 raw_ostream &cStream) const;
54 const MCRegisterInfo *getRegInfo() const { return RegInfo; }
59 // Forward-declarations used in the auto-generated files.
60 static DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
61 uint64_t Address, const void *Decoder);
63 DecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
64 uint64_t Address, const void *Decoder);
66 static DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
67 uint64_t Address, const void *Decoder);
69 DecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
70 uint64_t Address, const void *Decoder);
72 static DecodeStatus DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
73 uint64_t Address, const void *Decoder);
74 static DecodeStatus DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
75 uint64_t Address, const void *Decoder);
76 static DecodeStatus DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
77 uint64_t Address, const void *Decoder);
78 static DecodeStatus DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
79 uint64_t Address, const void *Decoder);
80 static DecodeStatus DecodeFPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
81 uint64_t Address, const void *Decoder);
82 static DecodeStatus DecodeVPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
83 uint64_t Address, const void *Decoder);
84 static DecodeStatus DecodeVPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
85 uint64_t Address, const void *Decoder);
87 static DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst,
93 static DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst,
98 static DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst,
101 const void *Decoder);
103 template<int RegWidth>
104 static DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst,
107 const void *Decoder);
109 template<int RegWidth>
110 static DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst,
113 const void *Decoder);
115 static DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst,
116 unsigned ShiftAmount,
118 const void *Decoder);
120 static DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst,
121 unsigned ShiftAmount,
123 const void *Decoder);
124 static DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn,
126 const void *Decoder);
128 static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
130 const void *Decoder);
132 static DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst,
135 const void *Decoder);
137 static DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst,
140 const void *Decoder);
142 template<typename SomeNamedImmMapper>
143 static DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst,
146 const void *Decoder);
148 static DecodeStatus DecodeSysRegOperand(const A64SysReg::SysRegMapper &InstMapper,
152 const void *Decoder);
154 static DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst,
157 const void *Decoder);
159 static DecodeStatus DecodeMSROperand(llvm::MCInst &Inst,
162 const void *Decoder);
165 static DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst,
168 const void *Decoder);
171 static bool Check(DecodeStatus &Out, DecodeStatus In);
173 #include "AArch64GenDisassemblerTables.inc"
174 #include "AArch64GenInstrInfo.inc"
176 static bool Check(DecodeStatus &Out, DecodeStatus In) {
178 case MCDisassembler::Success:
179 // Out stays the same.
181 case MCDisassembler::SoftFail:
184 case MCDisassembler::Fail:
188 llvm_unreachable("Invalid DecodeStatus!");
191 DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
192 const MemoryObject &Region,
195 raw_ostream &cs) const {
200 // We want to read exactly 4 bytes of data.
201 if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
203 return MCDisassembler::Fail;
206 // Encoded as a small-endian 32-bit word in the stream.
207 uint32_t insn = (bytes[3] << 24) |
212 // Calling the auto-generated decoder function.
213 DecodeStatus result = decodeInstruction(DecoderTableA6432, MI, insn, Address,
215 if (result != MCDisassembler::Fail) {
222 return MCDisassembler::Fail;
225 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
226 const AArch64Disassembler *Dis = static_cast<const AArch64Disassembler*>(D);
227 return Dis->getRegInfo()->getRegClass(RC).getRegister(RegNo);
230 static DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
231 uint64_t Address, const void *Decoder) {
233 return MCDisassembler::Fail;
235 uint16_t Register = getReg(Decoder, AArch64::GPR64RegClassID, RegNo);
236 Inst.addOperand(MCOperand::CreateReg(Register));
237 return MCDisassembler::Success;
241 DecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
242 uint64_t Address, const void *Decoder) {
244 return MCDisassembler::Fail;
246 uint16_t Register = getReg(Decoder, AArch64::GPR64xspRegClassID, RegNo);
247 Inst.addOperand(MCOperand::CreateReg(Register));
248 return MCDisassembler::Success;
251 static DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
252 uint64_t Address, const void *Decoder) {
254 return MCDisassembler::Fail;
256 uint16_t Register = getReg(Decoder, AArch64::GPR32RegClassID, RegNo);
257 Inst.addOperand(MCOperand::CreateReg(Register));
258 return MCDisassembler::Success;
262 DecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
263 uint64_t Address, const void *Decoder) {
265 return MCDisassembler::Fail;
267 uint16_t Register = getReg(Decoder, AArch64::GPR32wspRegClassID, RegNo);
268 Inst.addOperand(MCOperand::CreateReg(Register));
269 return MCDisassembler::Success;
273 DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
274 uint64_t Address, const void *Decoder) {
276 return MCDisassembler::Fail;
278 uint16_t Register = getReg(Decoder, AArch64::FPR8RegClassID, RegNo);
279 Inst.addOperand(MCOperand::CreateReg(Register));
280 return MCDisassembler::Success;
284 DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
285 uint64_t Address, const void *Decoder) {
287 return MCDisassembler::Fail;
289 uint16_t Register = getReg(Decoder, AArch64::FPR16RegClassID, RegNo);
290 Inst.addOperand(MCOperand::CreateReg(Register));
291 return MCDisassembler::Success;
296 DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
297 uint64_t Address, const void *Decoder) {
299 return MCDisassembler::Fail;
301 uint16_t Register = getReg(Decoder, AArch64::FPR32RegClassID, RegNo);
302 Inst.addOperand(MCOperand::CreateReg(Register));
303 return MCDisassembler::Success;
307 DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
308 uint64_t Address, const void *Decoder) {
310 return MCDisassembler::Fail;
312 uint16_t Register = getReg(Decoder, AArch64::FPR64RegClassID, RegNo);
313 Inst.addOperand(MCOperand::CreateReg(Register));
314 return MCDisassembler::Success;
319 DecodeFPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
320 uint64_t Address, const void *Decoder) {
322 return MCDisassembler::Fail;
324 uint16_t Register = getReg(Decoder, AArch64::FPR128RegClassID, RegNo);
325 Inst.addOperand(MCOperand::CreateReg(Register));
326 return MCDisassembler::Success;
331 DecodeVPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
332 uint64_t Address, const void *Decoder) {
334 return MCDisassembler::Fail;
336 uint16_t Register = getReg(Decoder, AArch64::VPR64RegClassID, RegNo);
337 Inst.addOperand(MCOperand::CreateReg(Register));
338 return MCDisassembler::Success;
342 DecodeVPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
343 uint64_t Address, const void *Decoder) {
345 return MCDisassembler::Fail;
347 uint16_t Register = getReg(Decoder, AArch64::VPR128RegClassID, RegNo);
348 Inst.addOperand(MCOperand::CreateReg(Register));
349 return MCDisassembler::Success;
352 static DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst,
355 const void *Decoder) {
356 // Option{1} must be 1. OptionHiS is made up of {Option{2}, Option{1},
357 // S}. Hence we want to check bit 1.
358 if (!(OptionHiS & 2))
359 return MCDisassembler::Fail;
361 Inst.addOperand(MCOperand::CreateImm(OptionHiS));
362 return MCDisassembler::Success;
365 static DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst,
368 const void *Decoder) {
369 // In the 32-bit variant, bit 6 must be zero. I.e. the immediate must be
372 return MCDisassembler::Fail;
374 Inst.addOperand(MCOperand::CreateImm(Imm6Bits));
375 return MCDisassembler::Success;
378 static DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst,
381 const void *Decoder) {
382 // 1 <= Imm <= 32. Encoded as 64 - Imm so: 63 >= Encoded >= 32.
384 return MCDisassembler::Fail;
386 Inst.addOperand(MCOperand::CreateImm(Imm6Bits));
387 return MCDisassembler::Success;
391 template<int RegWidth>
392 static DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst,
395 const void *Decoder) {
396 unsigned Imm16 = FullImm & 0xffff;
397 unsigned Shift = FullImm >> 16;
399 if (RegWidth == 32 && Shift > 1) return MCDisassembler::Fail;
401 Inst.addOperand(MCOperand::CreateImm(Imm16));
402 Inst.addOperand(MCOperand::CreateImm(Shift));
403 return MCDisassembler::Success;
406 template<int RegWidth>
407 static DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst,
410 const void *Decoder) {
412 if (!A64Imms::isLogicalImmBits(RegWidth, Bits, Imm))
413 return MCDisassembler::Fail;
415 Inst.addOperand(MCOperand::CreateImm(Bits));
416 return MCDisassembler::Success;
420 static DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst,
421 unsigned ShiftAmount,
423 const void *Decoder) {
424 // Only values 0-4 are valid for this 3-bit field
426 return MCDisassembler::Fail;
428 Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
429 return MCDisassembler::Success;
432 static DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst,
433 unsigned ShiftAmount,
435 const void *Decoder) {
436 // Only values below 32 are valid for a 32-bit register
437 if (ShiftAmount > 31)
438 return MCDisassembler::Fail;
440 Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
441 return MCDisassembler::Success;
444 static DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn,
446 const void *Decoder) {
447 unsigned Rd = fieldFromInstruction(Insn, 0, 5);
448 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
449 unsigned ImmS = fieldFromInstruction(Insn, 10, 6);
450 unsigned ImmR = fieldFromInstruction(Insn, 16, 6);
451 unsigned SF = fieldFromInstruction(Insn, 31, 1);
453 // Undef for 0b11 just in case it occurs. Don't want the compiler to optimise
454 // out assertions that it thinks should never be hit.
455 enum OpcTypes { SBFM = 0, BFM, UBFM, Undef } Opc;
456 Opc = (OpcTypes)fieldFromInstruction(Insn, 29, 2);
459 // ImmR and ImmS must be between 0 and 31 for 32-bit instructions.
460 if (ImmR > 31 || ImmS > 31)
461 return MCDisassembler::Fail;
465 DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
466 // BFM MCInsts use Rd as a source too.
467 if (Opc == BFM) DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
468 DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
470 DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
471 // BFM MCInsts use Rd as a source too.
472 if (Opc == BFM) DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
473 DecodeGPR32RegisterClass(Inst, Rn, Address, Decoder);
476 // ASR and LSR have more specific patterns so they won't get here:
477 assert(!(ImmS == 31 && !SF && Opc != BFM) && "shift should have used auto decode");
478 assert(!(ImmS == 63 && SF && Opc != BFM) && "shift should have used auto decode");
480 // Extension instructions similarly:
481 if (Opc == SBFM && ImmR == 0) {
482 assert((ImmS != 7 && ImmS != 15) && "extension got here");
483 assert((ImmS != 31 || SF == 0) && "extension got here");
484 } else if (Opc == UBFM && ImmR == 0) {
485 assert((SF != 0 || (ImmS != 7 && ImmS != 15)) && "extension got here");
489 // It might be a LSL instruction, which actually takes the shift amount
490 // itself as an MCInst operand.
491 if (SF && (ImmS + 1) % 64 == ImmR) {
492 Inst.setOpcode(AArch64::LSLxxi);
493 Inst.addOperand(MCOperand::CreateImm(63 - ImmS));
494 return MCDisassembler::Success;
495 } else if (!SF && (ImmS + 1) % 32 == ImmR) {
496 Inst.setOpcode(AArch64::LSLwwi);
497 Inst.addOperand(MCOperand::CreateImm(31 - ImmS));
498 return MCDisassembler::Success;
502 // Otherwise it's definitely either an extract or an insert depending on which
503 // of ImmR or ImmS is larger.
504 unsigned ExtractOp, InsertOp;
506 default: llvm_unreachable("unexpected instruction trying to decode bitfield");
508 ExtractOp = SF ? AArch64::SBFXxxii : AArch64::SBFXwwii;
509 InsertOp = SF ? AArch64::SBFIZxxii : AArch64::SBFIZwwii;
512 ExtractOp = SF ? AArch64::BFXILxxii : AArch64::BFXILwwii;
513 InsertOp = SF ? AArch64::BFIxxii : AArch64::BFIwwii;
516 ExtractOp = SF ? AArch64::UBFXxxii : AArch64::UBFXwwii;
517 InsertOp = SF ? AArch64::UBFIZxxii : AArch64::UBFIZwwii;
521 // Otherwise it's a boring insert or extract
522 Inst.addOperand(MCOperand::CreateImm(ImmR));
523 Inst.addOperand(MCOperand::CreateImm(ImmS));
527 Inst.setOpcode(InsertOp);
529 Inst.setOpcode(ExtractOp);
531 return MCDisassembler::Success;
534 static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
536 const void *Decoder) {
537 // This decoder exists to add the dummy Lane operand to the MCInst, which must
538 // be 1 in assembly but has no other real manifestation.
539 unsigned Rd = fieldFromInstruction(Insn, 0, 5);
540 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
541 unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
544 DecodeVPR128RegisterClass(Inst, Rd, Address, Decoder);
545 DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
547 DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
548 DecodeVPR128RegisterClass(Inst, Rn, Address, Decoder);
552 Inst.addOperand(MCOperand::CreateImm(1));
554 return MCDisassembler::Success;
558 static DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst,
561 const void *Decoder) {
562 DecodeStatus Result = MCDisassembler::Success;
563 unsigned Rt = fieldFromInstruction(Insn, 0, 5);
564 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
565 unsigned Rt2 = fieldFromInstruction(Insn, 10, 5);
566 unsigned SImm7 = fieldFromInstruction(Insn, 15, 7);
567 unsigned L = fieldFromInstruction(Insn, 22, 1);
568 unsigned V = fieldFromInstruction(Insn, 26, 1);
569 unsigned Opc = fieldFromInstruction(Insn, 30, 2);
571 // Not an official name, but it turns out that bit 23 distinguishes indexed
572 // from non-indexed operations.
573 unsigned Indexed = fieldFromInstruction(Insn, 23, 1);
575 if (Indexed && L == 0) {
576 // The MCInst for an indexed store has an out operand and 4 ins:
577 // Rn_wb, Rt, Rt2, Rn, Imm
578 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
581 // You shouldn't load to the same register twice in an instruction...
583 Result = MCDisassembler::SoftFail;
585 // ... or do any operation that writes-back to a transfer register. But note
586 // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
587 if (Indexed && V == 0 && Rn != 31 && (Rt == Rn || Rt2 == Rn))
588 Result = MCDisassembler::SoftFail;
590 // Exactly how we decode the MCInst's registers depends on the Opc and V
591 // fields of the instruction. These also obviously determine the size of the
592 // operation so we can fill in that information while we're at it.
594 // The instruction operates on the FP/SIMD registers
596 default: return MCDisassembler::Fail;
598 DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
599 DecodeFPR32RegisterClass(Inst, Rt2, Address, Decoder);
602 DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
603 DecodeFPR64RegisterClass(Inst, Rt2, Address, Decoder);
606 DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
607 DecodeFPR128RegisterClass(Inst, Rt2, Address, Decoder);
612 default: return MCDisassembler::Fail;
614 DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
615 DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder);
618 assert(L && "unexpected \"store signed\" attempt");
619 DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
620 DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
623 DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
624 DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
629 if (Indexed && L == 1) {
630 // The MCInst for an indexed load has 3 out operands and an 3 ins:
631 // Rt, Rt2, Rn_wb, Rt2, Rn, Imm
632 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
636 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
637 Inst.addOperand(MCOperand::CreateImm(SImm7));
642 static DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst,
645 const void *Decoder) {
646 unsigned Rt = fieldFromInstruction(Val, 0, 5);
647 unsigned Rn = fieldFromInstruction(Val, 5, 5);
648 unsigned Rt2 = fieldFromInstruction(Val, 10, 5);
649 unsigned MemSize = fieldFromInstruction(Val, 30, 2);
651 DecodeStatus S = MCDisassembler::Success;
652 if (Rt == Rt2) S = MCDisassembler::SoftFail;
656 if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder)))
657 return MCDisassembler::Fail;
658 if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder)))
659 return MCDisassembler::Fail;
662 if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder)))
663 return MCDisassembler::Fail;
664 if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder)))
665 return MCDisassembler::Fail;
668 llvm_unreachable("Invalid MemSize in DecodeLoadPairExclusiveInstruction");
671 if (!Check(S, DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder)))
672 return MCDisassembler::Fail;
677 template<typename SomeNamedImmMapper>
678 static DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst,
681 const void *Decoder) {
682 SomeNamedImmMapper Mapper;
684 Mapper.toString(Val, ValidNamed);
685 if (ValidNamed || Mapper.validImm(Val)) {
686 Inst.addOperand(MCOperand::CreateImm(Val));
687 return MCDisassembler::Success;
690 return MCDisassembler::Fail;
693 static DecodeStatus DecodeSysRegOperand(const A64SysReg::SysRegMapper &Mapper,
697 const void *Decoder) {
699 Mapper.toString(Val, ValidNamed);
701 Inst.addOperand(MCOperand::CreateImm(Val));
703 return ValidNamed ? MCDisassembler::Success : MCDisassembler::Fail;
706 static DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst,
709 const void *Decoder) {
710 return DecodeSysRegOperand(A64SysReg::MRSMapper(), Inst, Val, Address,
714 static DecodeStatus DecodeMSROperand(llvm::MCInst &Inst,
717 const void *Decoder) {
718 return DecodeSysRegOperand(A64SysReg::MSRMapper(), Inst, Val, Address,
722 static DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst,
725 const void *Decoder) {
726 unsigned Rt = fieldFromInstruction(Insn, 0, 5);
727 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
728 unsigned Imm9 = fieldFromInstruction(Insn, 12, 9);
730 unsigned Opc = fieldFromInstruction(Insn, 22, 2);
731 unsigned V = fieldFromInstruction(Insn, 26, 1);
732 unsigned Size = fieldFromInstruction(Insn, 30, 2);
734 if (Opc == 0 || (V == 1 && Opc == 2)) {
735 // It's a store, the MCInst gets: Rn_wb, Rt, Rn, Imm
736 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
739 if (V == 0 && (Opc == 2 || Size == 3)) {
740 DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
742 DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
743 } else if (V == 1 && (Opc & 2)) {
744 DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
748 DecodeFPR8RegisterClass(Inst, Rt, Address, Decoder);
751 DecodeFPR16RegisterClass(Inst, Rt, Address, Decoder);
754 DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
757 DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
762 if (Opc != 0 && (V != 1 || Opc != 2)) {
763 // It's a load, the MCInst gets: Rt, Rn_wb, Rn, Imm
764 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
767 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
769 Inst.addOperand(MCOperand::CreateImm(Imm9));
771 // N.b. The official documentation says undpredictable if Rt == Rn, but this
772 // takes place at the architectural rather than encoding level:
774 // "STR xzr, [sp], #4" is perfectly valid.
775 if (V == 0 && Rt == Rn && Rn != 31)
776 return MCDisassembler::SoftFail;
778 return MCDisassembler::Success;
781 static MCDisassembler *createAArch64Disassembler(const Target &T,
782 const MCSubtargetInfo &STI) {
783 return new AArch64Disassembler(STI, T.createMCRegInfo(""));
786 extern "C" void LLVMInitializeAArch64Disassembler() {
787 TargetRegistry::RegisterMCDisassembler(TheAArch64Target,
788 createAArch64Disassembler);