AArch64Disassembler.cpp revision 54a1cf75d2b32cd96ec78f61af5c1bed8d81524d
15bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//===- AArch64Disassembler.cpp - Disassembler for AArch64 ISA -------------===//
272062f5744557e270a38192554c3126ea5f97434Tim Northover//
372062f5744557e270a38192554c3126ea5f97434Tim Northover//                     The LLVM Compiler Infrastructure
472062f5744557e270a38192554c3126ea5f97434Tim Northover//
572062f5744557e270a38192554c3126ea5f97434Tim Northover// This file is distributed under the University of Illinois Open Source
672062f5744557e270a38192554c3126ea5f97434Tim Northover// License. See LICENSE.TXT for details.
772062f5744557e270a38192554c3126ea5f97434Tim Northover//
872062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
95bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//
105bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover// This file contains the functions necessary to decode AArch64 instruction
115bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover// bitpatterns into MCInsts (with the help of TableGenerated information from
125bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover// the instruction definitions).
135bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//
145bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//===----------------------------------------------------------------------===//
1572062f5744557e270a38192554c3126ea5f97434Tim Northover
1672062f5744557e270a38192554c3126ea5f97434Tim Northover#define DEBUG_TYPE "arm-disassembler"
1772062f5744557e270a38192554c3126ea5f97434Tim Northover
1872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64.h"
1972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64RegisterInfo.h"
2072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64Subtarget.h"
2119254c49a8752fe8c6fa648a6eb29f20a1f62c8bTim Northover#include "Utils/AArch64BaseInfo.h"
2272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCInst.h"
2372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCInstrDesc.h"
2472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCExpr.h"
2572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCContext.h"
2672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCDisassembler.h"
2772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCFixedLenDisassembler.h"
2872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/Debug.h"
2972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/MemoryObject.h"
3072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/ErrorHandling.h"
3172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/TargetRegistry.h"
3272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/raw_ostream.h"
3372062f5744557e270a38192554c3126ea5f97434Tim Northover
3472062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm;
3572062f5744557e270a38192554c3126ea5f97434Tim Northover
3672062f5744557e270a38192554c3126ea5f97434Tim Northovertypedef MCDisassembler::DecodeStatus DecodeStatus;
3772062f5744557e270a38192554c3126ea5f97434Tim Northover
3872062f5744557e270a38192554c3126ea5f97434Tim Northovernamespace {
3972062f5744557e270a38192554c3126ea5f97434Tim Northover/// AArch64 disassembler for all AArch64 platforms.
4072062f5744557e270a38192554c3126ea5f97434Tim Northoverclass AArch64Disassembler : public MCDisassembler {
4172062f5744557e270a38192554c3126ea5f97434Tim Northover  const MCRegisterInfo *RegInfo;
4272062f5744557e270a38192554c3126ea5f97434Tim Northoverpublic:
4372062f5744557e270a38192554c3126ea5f97434Tim Northover  /// Initializes the disassembler.
4472062f5744557e270a38192554c3126ea5f97434Tim Northover  ///
4572062f5744557e270a38192554c3126ea5f97434Tim Northover  AArch64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info)
4672062f5744557e270a38192554c3126ea5f97434Tim Northover    : MCDisassembler(STI), RegInfo(Info) {
4772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
4872062f5744557e270a38192554c3126ea5f97434Tim Northover
4972062f5744557e270a38192554c3126ea5f97434Tim Northover  ~AArch64Disassembler() {
5072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
5172062f5744557e270a38192554c3126ea5f97434Tim Northover
5272062f5744557e270a38192554c3126ea5f97434Tim Northover  /// See MCDisassembler.
5372062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeStatus getInstruction(MCInst &instr,
5472062f5744557e270a38192554c3126ea5f97434Tim Northover                              uint64_t &size,
5572062f5744557e270a38192554c3126ea5f97434Tim Northover                              const MemoryObject &region,
5672062f5744557e270a38192554c3126ea5f97434Tim Northover                              uint64_t address,
5772062f5744557e270a38192554c3126ea5f97434Tim Northover                              raw_ostream &vStream,
5872062f5744557e270a38192554c3126ea5f97434Tim Northover                              raw_ostream &cStream) const;
5972062f5744557e270a38192554c3126ea5f97434Tim Northover
6072062f5744557e270a38192554c3126ea5f97434Tim Northover  const MCRegisterInfo *getRegInfo() const { return RegInfo; }
6172062f5744557e270a38192554c3126ea5f97434Tim Northover};
6272062f5744557e270a38192554c3126ea5f97434Tim Northover
6372062f5744557e270a38192554c3126ea5f97434Tim Northover}
6472062f5744557e270a38192554c3126ea5f97434Tim Northover
6572062f5744557e270a38192554c3126ea5f97434Tim Northover// Forward-declarations used in the auto-generated files.
6672062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
6772062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
6872062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
6972062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
7072062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder);
7172062f5744557e270a38192554c3126ea5f97434Tim Northover
7272062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
7372062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
7472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
7572062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
7672062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder);
7772062f5744557e270a38192554c3126ea5f97434Tim Northover
7872062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
7972062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
8072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
8172062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
8272062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
8372062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
8472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
8572062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
86dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northoverstatic DecodeStatus DecodeFPR128RegisterClass(llvm::MCInst &Inst,
87dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                              unsigned RegNo, uint64_t Address,
88dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                              const void *Decoder);
89dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northoverstatic DecodeStatus DecodeVPR128RegisterClass(llvm::MCInst &Inst,
90dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                              unsigned RegNo, uint64_t Address,
91dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                              const void *Decoder);
9272062f5744557e270a38192554c3126ea5f97434Tim Northover
9372062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst,
9472062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned OptionHiS,
9572062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
9672062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder);
9772062f5744557e270a38192554c3126ea5f97434Tim Northover
9872062f5744557e270a38192554c3126ea5f97434Tim Northover
9972062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst,
10072062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned Imm6Bits,
10172062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
10272062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder);
10372062f5744557e270a38192554c3126ea5f97434Tim Northover
10472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst,
10572062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned Imm6Bits,
10672062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
10772062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder);
10872062f5744557e270a38192554c3126ea5f97434Tim Northover
10954a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northoverstatic DecodeStatus DecodeFPZeroOperand(llvm::MCInst &Inst,
11054a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        unsigned RmBits,
11154a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        uint64_t Address,
11254a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        const void *Decoder);
11354a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover
11472062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<int RegWidth>
11572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst,
11672062f5744557e270a38192554c3126ea5f97434Tim Northover                                             unsigned FullImm,
11772062f5744557e270a38192554c3126ea5f97434Tim Northover                                             uint64_t Address,
11872062f5744557e270a38192554c3126ea5f97434Tim Northover                                             const void *Decoder);
11972062f5744557e270a38192554c3126ea5f97434Tim Northover
12072062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<int RegWidth>
12172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst,
12272062f5744557e270a38192554c3126ea5f97434Tim Northover                                            unsigned Bits,
12372062f5744557e270a38192554c3126ea5f97434Tim Northover                                            uint64_t Address,
12472062f5744557e270a38192554c3126ea5f97434Tim Northover                                            const void *Decoder);
12572062f5744557e270a38192554c3126ea5f97434Tim Northover
12672062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst,
12772062f5744557e270a38192554c3126ea5f97434Tim Northover                                           unsigned ShiftAmount,
12872062f5744557e270a38192554c3126ea5f97434Tim Northover                                           uint64_t Address,
12972062f5744557e270a38192554c3126ea5f97434Tim Northover                                           const void *Decoder);
13072062f5744557e270a38192554c3126ea5f97434Tim Northover
13172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst,
13272062f5744557e270a38192554c3126ea5f97434Tim Northover                                            unsigned ShiftAmount,
13372062f5744557e270a38192554c3126ea5f97434Tim Northover                                            uint64_t Address,
13472062f5744557e270a38192554c3126ea5f97434Tim Northover                                            const void *Decoder);
13572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn,
13672062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
13772062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder);
13872062f5744557e270a38192554c3126ea5f97434Tim Northover
13972062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
14072062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
14172062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder);
14272062f5744557e270a38192554c3126ea5f97434Tim Northover
14372062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst,
14472062f5744557e270a38192554c3126ea5f97434Tim Northover                                              unsigned Insn,
14572062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
14672062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder);
14772062f5744557e270a38192554c3126ea5f97434Tim Northover
14872062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst,
14972062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       unsigned Val,
15072062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       uint64_t Address,
15172062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       const void *Decoder);
15272062f5744557e270a38192554c3126ea5f97434Tim Northover
15372062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<typename SomeNamedImmMapper>
15472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst,
15572062f5744557e270a38192554c3126ea5f97434Tim Northover                                          unsigned Val,
15672062f5744557e270a38192554c3126ea5f97434Tim Northover                                          uint64_t Address,
15772062f5744557e270a38192554c3126ea5f97434Tim Northover                                          const void *Decoder);
15872062f5744557e270a38192554c3126ea5f97434Tim Northover
159dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northoverstatic DecodeStatus
160dfe076af9879eb68a7b8331f9c02eecf563d85beTim NorthoverDecodeSysRegOperand(const A64SysReg::SysRegMapper &InstMapper,
161dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                    llvm::MCInst &Inst, unsigned Val,
162dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                    uint64_t Address, const void *Decoder);
16372062f5744557e270a38192554c3126ea5f97434Tim Northover
16472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst,
16572062f5744557e270a38192554c3126ea5f97434Tim Northover                                     unsigned Val,
16672062f5744557e270a38192554c3126ea5f97434Tim Northover                                     uint64_t Address,
16772062f5744557e270a38192554c3126ea5f97434Tim Northover                                     const void *Decoder);
16872062f5744557e270a38192554c3126ea5f97434Tim Northover
16972062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMSROperand(llvm::MCInst &Inst,
17072062f5744557e270a38192554c3126ea5f97434Tim Northover                                     unsigned Val,
17172062f5744557e270a38192554c3126ea5f97434Tim Northover                                     uint64_t Address,
17272062f5744557e270a38192554c3126ea5f97434Tim Northover                                     const void *Decoder);
17372062f5744557e270a38192554c3126ea5f97434Tim Northover
17472062f5744557e270a38192554c3126ea5f97434Tim Northover
17572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst,
17672062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   unsigned Val,
17772062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   uint64_t Address,
17872062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   const void *Decoder);
17972062f5744557e270a38192554c3126ea5f97434Tim Northover
18072062f5744557e270a38192554c3126ea5f97434Tim Northover
18172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic bool Check(DecodeStatus &Out, DecodeStatus In);
18272062f5744557e270a38192554c3126ea5f97434Tim Northover
18372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenDisassemblerTables.inc"
18472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenInstrInfo.inc"
18572062f5744557e270a38192554c3126ea5f97434Tim Northover
18672062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic bool Check(DecodeStatus &Out, DecodeStatus In) {
18772062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (In) {
18872062f5744557e270a38192554c3126ea5f97434Tim Northover    case MCDisassembler::Success:
18972062f5744557e270a38192554c3126ea5f97434Tim Northover      // Out stays the same.
19072062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
19172062f5744557e270a38192554c3126ea5f97434Tim Northover    case MCDisassembler::SoftFail:
19272062f5744557e270a38192554c3126ea5f97434Tim Northover      Out = In;
19372062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
19472062f5744557e270a38192554c3126ea5f97434Tim Northover    case MCDisassembler::Fail:
19572062f5744557e270a38192554c3126ea5f97434Tim Northover      Out = In;
19672062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
19772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
19872062f5744557e270a38192554c3126ea5f97434Tim Northover  llvm_unreachable("Invalid DecodeStatus!");
19972062f5744557e270a38192554c3126ea5f97434Tim Northover}
20072062f5744557e270a38192554c3126ea5f97434Tim Northover
20172062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
20272062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 const MemoryObject &Region,
20372062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 uint64_t Address,
20472062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 raw_ostream &os,
20572062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 raw_ostream &cs) const {
20672062f5744557e270a38192554c3126ea5f97434Tim Northover  CommentStream = &cs;
20772062f5744557e270a38192554c3126ea5f97434Tim Northover
20872062f5744557e270a38192554c3126ea5f97434Tim Northover  uint8_t bytes[4];
20972062f5744557e270a38192554c3126ea5f97434Tim Northover
21072062f5744557e270a38192554c3126ea5f97434Tim Northover  // We want to read exactly 4 bytes of data.
21172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
21272062f5744557e270a38192554c3126ea5f97434Tim Northover    Size = 0;
21372062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
21472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
21572062f5744557e270a38192554c3126ea5f97434Tim Northover
21672062f5744557e270a38192554c3126ea5f97434Tim Northover  // Encoded as a small-endian 32-bit word in the stream.
21772062f5744557e270a38192554c3126ea5f97434Tim Northover  uint32_t insn = (bytes[3] << 24) |
21872062f5744557e270a38192554c3126ea5f97434Tim Northover    (bytes[2] << 16) |
21972062f5744557e270a38192554c3126ea5f97434Tim Northover    (bytes[1] <<  8) |
22072062f5744557e270a38192554c3126ea5f97434Tim Northover    (bytes[0] <<  0);
22172062f5744557e270a38192554c3126ea5f97434Tim Northover
22272062f5744557e270a38192554c3126ea5f97434Tim Northover  // Calling the auto-generated decoder function.
22372062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeStatus result = decodeInstruction(DecoderTableA6432, MI, insn, Address,
22472062f5744557e270a38192554c3126ea5f97434Tim Northover                                          this, STI);
22572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (result != MCDisassembler::Fail) {
22672062f5744557e270a38192554c3126ea5f97434Tim Northover    Size = 4;
22772062f5744557e270a38192554c3126ea5f97434Tim Northover    return result;
22872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
22972062f5744557e270a38192554c3126ea5f97434Tim Northover
23072062f5744557e270a38192554c3126ea5f97434Tim Northover  MI.clear();
23172062f5744557e270a38192554c3126ea5f97434Tim Northover  Size = 0;
23272062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Fail;
23372062f5744557e270a38192554c3126ea5f97434Tim Northover}
23472062f5744557e270a38192554c3126ea5f97434Tim Northover
23572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
23672062f5744557e270a38192554c3126ea5f97434Tim Northover  const AArch64Disassembler *Dis = static_cast<const AArch64Disassembler*>(D);
23772062f5744557e270a38192554c3126ea5f97434Tim Northover  return Dis->getRegInfo()->getRegClass(RC).getRegister(RegNo);
23872062f5744557e270a38192554c3126ea5f97434Tim Northover}
23972062f5744557e270a38192554c3126ea5f97434Tim Northover
24072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
24172062f5744557e270a38192554c3126ea5f97434Tim Northover                                        uint64_t Address, const void *Decoder) {
24272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
24372062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
24472062f5744557e270a38192554c3126ea5f97434Tim Northover
24572062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::GPR64RegClassID, RegNo);
24672062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
24772062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
24872062f5744557e270a38192554c3126ea5f97434Tim Northover}
24972062f5744557e270a38192554c3126ea5f97434Tim Northover
25072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
25172062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
25272062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
25372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
25472062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
25572062f5744557e270a38192554c3126ea5f97434Tim Northover
25672062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::GPR64xspRegClassID, RegNo);
25772062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
25872062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
25972062f5744557e270a38192554c3126ea5f97434Tim Northover}
26072062f5744557e270a38192554c3126ea5f97434Tim Northover
26172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
262dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                             uint64_t Address,
263dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                             const void *Decoder) {
26472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
26572062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
26672062f5744557e270a38192554c3126ea5f97434Tim Northover
26772062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::GPR32RegClassID, RegNo);
26872062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
26972062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
27072062f5744557e270a38192554c3126ea5f97434Tim Northover}
27172062f5744557e270a38192554c3126ea5f97434Tim Northover
27272062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
27372062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
27472062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
27572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
27672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
27772062f5744557e270a38192554c3126ea5f97434Tim Northover
27872062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::GPR32wspRegClassID, RegNo);
27972062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
28072062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
28172062f5744557e270a38192554c3126ea5f97434Tim Northover}
28272062f5744557e270a38192554c3126ea5f97434Tim Northover
28372062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
28472062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
28572062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
28672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
28772062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
28872062f5744557e270a38192554c3126ea5f97434Tim Northover
28972062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::FPR8RegClassID, RegNo);
29072062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
29172062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
29272062f5744557e270a38192554c3126ea5f97434Tim Northover}
29372062f5744557e270a38192554c3126ea5f97434Tim Northover
29472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
29572062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
29672062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
29772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
29872062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
29972062f5744557e270a38192554c3126ea5f97434Tim Northover
30072062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::FPR16RegClassID, RegNo);
30172062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
30272062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
30372062f5744557e270a38192554c3126ea5f97434Tim Northover}
30472062f5744557e270a38192554c3126ea5f97434Tim Northover
30572062f5744557e270a38192554c3126ea5f97434Tim Northover
30672062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
30772062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
30872062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
30972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
31072062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
31172062f5744557e270a38192554c3126ea5f97434Tim Northover
31272062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::FPR32RegClassID, RegNo);
31372062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
31472062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
31572062f5744557e270a38192554c3126ea5f97434Tim Northover}
31672062f5744557e270a38192554c3126ea5f97434Tim Northover
31772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
31872062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
31972062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
32072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
32172062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
32272062f5744557e270a38192554c3126ea5f97434Tim Northover
32372062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::FPR64RegClassID, RegNo);
32472062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
32572062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
32672062f5744557e270a38192554c3126ea5f97434Tim Northover}
32772062f5744557e270a38192554c3126ea5f97434Tim Northover
32872062f5744557e270a38192554c3126ea5f97434Tim Northover
32972062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
33072062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeFPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
33172062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
33272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
33372062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
33472062f5744557e270a38192554c3126ea5f97434Tim Northover
33572062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::FPR128RegClassID, RegNo);
33672062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
33772062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
33872062f5744557e270a38192554c3126ea5f97434Tim Northover}
33972062f5744557e270a38192554c3126ea5f97434Tim Northover
34072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
34172062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeVPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
34272062f5744557e270a38192554c3126ea5f97434Tim Northover                         uint64_t Address, const void *Decoder) {
34372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
34472062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
34572062f5744557e270a38192554c3126ea5f97434Tim Northover
34672062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::VPR128RegClassID, RegNo);
34772062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
34872062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
34972062f5744557e270a38192554c3126ea5f97434Tim Northover}
35072062f5744557e270a38192554c3126ea5f97434Tim Northover
35172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst,
35272062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned OptionHiS,
35372062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
35472062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder) {
35572062f5744557e270a38192554c3126ea5f97434Tim Northover  // Option{1} must be 1. OptionHiS is made up of {Option{2}, Option{1},
35672062f5744557e270a38192554c3126ea5f97434Tim Northover  // S}. Hence we want to check bit 1.
35772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!(OptionHiS & 2))
35872062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
35972062f5744557e270a38192554c3126ea5f97434Tim Northover
36072062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(OptionHiS));
36172062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
36272062f5744557e270a38192554c3126ea5f97434Tim Northover}
36372062f5744557e270a38192554c3126ea5f97434Tim Northover
36472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst,
36572062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned Imm6Bits,
36672062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
36772062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder) {
36872062f5744557e270a38192554c3126ea5f97434Tim Northover  // In the 32-bit variant, bit 6 must be zero. I.e. the immediate must be
36972062f5744557e270a38192554c3126ea5f97434Tim Northover  // between 0 and 31.
37072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Imm6Bits > 31)
37172062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
37272062f5744557e270a38192554c3126ea5f97434Tim Northover
37372062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Imm6Bits));
37472062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
37572062f5744557e270a38192554c3126ea5f97434Tim Northover}
37672062f5744557e270a38192554c3126ea5f97434Tim Northover
37772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst,
37872062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned Imm6Bits,
37972062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
38072062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder) {
38172062f5744557e270a38192554c3126ea5f97434Tim Northover  // 1 <= Imm <= 32. Encoded as 64 - Imm so: 63 >= Encoded >= 32.
38272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Imm6Bits < 32)
38372062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
38472062f5744557e270a38192554c3126ea5f97434Tim Northover
38572062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Imm6Bits));
38672062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
38772062f5744557e270a38192554c3126ea5f97434Tim Northover}
38872062f5744557e270a38192554c3126ea5f97434Tim Northover
38954a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northoverstatic DecodeStatus DecodeFPZeroOperand(llvm::MCInst &Inst,
39054a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        unsigned RmBits,
39154a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        uint64_t Address,
39254a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        const void *Decoder) {
39354a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover  // Any bits are valid in the instruction (they're architecturally ignored),
39454a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover  // but a code generator should insert 0.
39554a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover  Inst.addOperand(MCOperand::CreateImm(0));
39654a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover  return MCDisassembler::Success;
39754a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover}
39854a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover
39954a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover
40072062f5744557e270a38192554c3126ea5f97434Tim Northover
40172062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<int RegWidth>
40272062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst,
40372062f5744557e270a38192554c3126ea5f97434Tim Northover                                             unsigned FullImm,
40472062f5744557e270a38192554c3126ea5f97434Tim Northover                                             uint64_t Address,
40572062f5744557e270a38192554c3126ea5f97434Tim Northover                                             const void *Decoder) {
40672062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Imm16 = FullImm & 0xffff;
40772062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Shift = FullImm >> 16;
40872062f5744557e270a38192554c3126ea5f97434Tim Northover
40972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegWidth == 32 && Shift > 1) return MCDisassembler::Fail;
41072062f5744557e270a38192554c3126ea5f97434Tim Northover
41172062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Imm16));
41272062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Shift));
41372062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
41472062f5744557e270a38192554c3126ea5f97434Tim Northover}
41572062f5744557e270a38192554c3126ea5f97434Tim Northover
41672062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<int RegWidth>
41772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst,
41872062f5744557e270a38192554c3126ea5f97434Tim Northover                                            unsigned Bits,
41972062f5744557e270a38192554c3126ea5f97434Tim Northover                                            uint64_t Address,
42072062f5744557e270a38192554c3126ea5f97434Tim Northover                                            const void *Decoder) {
42172062f5744557e270a38192554c3126ea5f97434Tim Northover  uint64_t Imm;
42272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!A64Imms::isLogicalImmBits(RegWidth, Bits, Imm))
42372062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
42472062f5744557e270a38192554c3126ea5f97434Tim Northover
42572062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Bits));
42672062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
42772062f5744557e270a38192554c3126ea5f97434Tim Northover}
42872062f5744557e270a38192554c3126ea5f97434Tim Northover
42972062f5744557e270a38192554c3126ea5f97434Tim Northover
43072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst,
43172062f5744557e270a38192554c3126ea5f97434Tim Northover                                           unsigned ShiftAmount,
43272062f5744557e270a38192554c3126ea5f97434Tim Northover                                           uint64_t Address,
43372062f5744557e270a38192554c3126ea5f97434Tim Northover                                           const void *Decoder) {
43472062f5744557e270a38192554c3126ea5f97434Tim Northover  // Only values 0-4 are valid for this 3-bit field
43572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (ShiftAmount > 4)
43672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
43772062f5744557e270a38192554c3126ea5f97434Tim Northover
43872062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
43972062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
44072062f5744557e270a38192554c3126ea5f97434Tim Northover}
44172062f5744557e270a38192554c3126ea5f97434Tim Northover
44272062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst,
44372062f5744557e270a38192554c3126ea5f97434Tim Northover                                            unsigned ShiftAmount,
44472062f5744557e270a38192554c3126ea5f97434Tim Northover                                            uint64_t Address,
44572062f5744557e270a38192554c3126ea5f97434Tim Northover                                            const void *Decoder) {
44672062f5744557e270a38192554c3126ea5f97434Tim Northover  // Only values below 32 are valid for a 32-bit register
44772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (ShiftAmount > 31)
44872062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
44972062f5744557e270a38192554c3126ea5f97434Tim Northover
45072062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
45172062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
45272062f5744557e270a38192554c3126ea5f97434Tim Northover}
45372062f5744557e270a38192554c3126ea5f97434Tim Northover
45472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn,
45572062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
45672062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder) {
45772062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rd = fieldFromInstruction(Insn, 0, 5);
45872062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rn = fieldFromInstruction(Insn, 5, 5);
45972062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned ImmS = fieldFromInstruction(Insn, 10, 6);
46072062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned ImmR = fieldFromInstruction(Insn, 16, 6);
46172062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned SF = fieldFromInstruction(Insn, 31, 1);
46272062f5744557e270a38192554c3126ea5f97434Tim Northover
46372062f5744557e270a38192554c3126ea5f97434Tim Northover  // Undef for 0b11 just in case it occurs. Don't want the compiler to optimise
46472062f5744557e270a38192554c3126ea5f97434Tim Northover  // out assertions that it thinks should never be hit.
46572062f5744557e270a38192554c3126ea5f97434Tim Northover  enum OpcTypes { SBFM = 0, BFM, UBFM, Undef } Opc;
46672062f5744557e270a38192554c3126ea5f97434Tim Northover  Opc = (OpcTypes)fieldFromInstruction(Insn, 29, 2);
46772062f5744557e270a38192554c3126ea5f97434Tim Northover
46872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!SF) {
46972062f5744557e270a38192554c3126ea5f97434Tim Northover    // ImmR and ImmS must be between 0 and 31 for 32-bit instructions.
47072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ImmR > 31 || ImmS > 31)
47172062f5744557e270a38192554c3126ea5f97434Tim Northover      return MCDisassembler::Fail;
47272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
47372062f5744557e270a38192554c3126ea5f97434Tim Northover
47472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (SF) {
47572062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
47672062f5744557e270a38192554c3126ea5f97434Tim Northover    // BFM MCInsts use Rd as a source too.
47772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Opc == BFM) DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
47872062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
47972062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
48072062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
48172062f5744557e270a38192554c3126ea5f97434Tim Northover    // BFM MCInsts use Rd as a source too.
48272062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Opc == BFM) DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
48372062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR32RegisterClass(Inst, Rn, Address, Decoder);
48472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
48572062f5744557e270a38192554c3126ea5f97434Tim Northover
48672062f5744557e270a38192554c3126ea5f97434Tim Northover  // ASR and LSR have more specific patterns so they won't get here:
487dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover  assert(!(ImmS == 31 && !SF && Opc != BFM)
488dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover         && "shift should have used auto decode");
489dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover  assert(!(ImmS == 63 && SF && Opc != BFM)
490dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover         && "shift should have used auto decode");
49172062f5744557e270a38192554c3126ea5f97434Tim Northover
49272062f5744557e270a38192554c3126ea5f97434Tim Northover  // Extension instructions similarly:
49372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Opc == SBFM && ImmR == 0) {
49472062f5744557e270a38192554c3126ea5f97434Tim Northover    assert((ImmS != 7 && ImmS != 15) && "extension got here");
49572062f5744557e270a38192554c3126ea5f97434Tim Northover    assert((ImmS != 31 || SF == 0) && "extension got here");
49672062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (Opc == UBFM && ImmR == 0) {
49772062f5744557e270a38192554c3126ea5f97434Tim Northover    assert((SF != 0 || (ImmS != 7 && ImmS != 15)) && "extension got here");
49872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
49972062f5744557e270a38192554c3126ea5f97434Tim Northover
50072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Opc == UBFM) {
50172062f5744557e270a38192554c3126ea5f97434Tim Northover    // It might be a LSL instruction, which actually takes the shift amount
50272062f5744557e270a38192554c3126ea5f97434Tim Northover    // itself as an MCInst operand.
50372062f5744557e270a38192554c3126ea5f97434Tim Northover    if (SF && (ImmS + 1) % 64 == ImmR) {
50472062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.setOpcode(AArch64::LSLxxi);
50572062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateImm(63 - ImmS));
50672062f5744557e270a38192554c3126ea5f97434Tim Northover      return MCDisassembler::Success;
50772062f5744557e270a38192554c3126ea5f97434Tim Northover    } else if (!SF && (ImmS + 1) % 32 == ImmR) {
50872062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.setOpcode(AArch64::LSLwwi);
50972062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateImm(31 - ImmS));
51072062f5744557e270a38192554c3126ea5f97434Tim Northover      return MCDisassembler::Success;
51172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
51272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
51372062f5744557e270a38192554c3126ea5f97434Tim Northover
51472062f5744557e270a38192554c3126ea5f97434Tim Northover  // Otherwise it's definitely either an extract or an insert depending on which
51572062f5744557e270a38192554c3126ea5f97434Tim Northover  // of ImmR or ImmS is larger.
51672062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned ExtractOp, InsertOp;
51772062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Opc) {
51872062f5744557e270a38192554c3126ea5f97434Tim Northover  default: llvm_unreachable("unexpected instruction trying to decode bitfield");
51972062f5744557e270a38192554c3126ea5f97434Tim Northover  case SBFM:
52072062f5744557e270a38192554c3126ea5f97434Tim Northover    ExtractOp = SF ? AArch64::SBFXxxii : AArch64::SBFXwwii;
52172062f5744557e270a38192554c3126ea5f97434Tim Northover    InsertOp = SF ? AArch64::SBFIZxxii : AArch64::SBFIZwwii;
52272062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
52372062f5744557e270a38192554c3126ea5f97434Tim Northover  case BFM:
52472062f5744557e270a38192554c3126ea5f97434Tim Northover    ExtractOp = SF ? AArch64::BFXILxxii : AArch64::BFXILwwii;
52572062f5744557e270a38192554c3126ea5f97434Tim Northover    InsertOp = SF ? AArch64::BFIxxii : AArch64::BFIwwii;
52672062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
52772062f5744557e270a38192554c3126ea5f97434Tim Northover  case UBFM:
52872062f5744557e270a38192554c3126ea5f97434Tim Northover    ExtractOp = SF ? AArch64::UBFXxxii : AArch64::UBFXwwii;
52972062f5744557e270a38192554c3126ea5f97434Tim Northover    InsertOp = SF ? AArch64::UBFIZxxii : AArch64::UBFIZwwii;
53072062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
53172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
53272062f5744557e270a38192554c3126ea5f97434Tim Northover
53372062f5744557e270a38192554c3126ea5f97434Tim Northover  // Otherwise it's a boring insert or extract
53472062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(ImmR));
53572062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(ImmS));
53672062f5744557e270a38192554c3126ea5f97434Tim Northover
53772062f5744557e270a38192554c3126ea5f97434Tim Northover
53872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (ImmS < ImmR)
53972062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.setOpcode(InsertOp);
54072062f5744557e270a38192554c3126ea5f97434Tim Northover  else
54172062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.setOpcode(ExtractOp);
54272062f5744557e270a38192554c3126ea5f97434Tim Northover
54372062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
54472062f5744557e270a38192554c3126ea5f97434Tim Northover}
54572062f5744557e270a38192554c3126ea5f97434Tim Northover
54672062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
54772062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
54872062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder) {
54972062f5744557e270a38192554c3126ea5f97434Tim Northover  // This decoder exists to add the dummy Lane operand to the MCInst, which must
55072062f5744557e270a38192554c3126ea5f97434Tim Northover  // be 1 in assembly but has no other real manifestation.
55172062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rd = fieldFromInstruction(Insn, 0, 5);
55272062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rn = fieldFromInstruction(Insn, 5, 5);
55372062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
55472062f5744557e270a38192554c3126ea5f97434Tim Northover
55572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (IsToVec) {
55672062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeVPR128RegisterClass(Inst, Rd, Address, Decoder);
55772062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
55872062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
55972062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
56072062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeVPR128RegisterClass(Inst, Rn, Address, Decoder);
56172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
56272062f5744557e270a38192554c3126ea5f97434Tim Northover
56372062f5744557e270a38192554c3126ea5f97434Tim Northover  // Add the lane
56472062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(1));
56572062f5744557e270a38192554c3126ea5f97434Tim Northover
56672062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
56772062f5744557e270a38192554c3126ea5f97434Tim Northover}
56872062f5744557e270a38192554c3126ea5f97434Tim Northover
56972062f5744557e270a38192554c3126ea5f97434Tim Northover
57072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst,
57172062f5744557e270a38192554c3126ea5f97434Tim Northover                                              unsigned Insn,
57272062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
57372062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder) {
57472062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeStatus Result = MCDisassembler::Success;
57572062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rt = fieldFromInstruction(Insn, 0, 5);
57672062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rn = fieldFromInstruction(Insn, 5, 5);
57772062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rt2 = fieldFromInstruction(Insn, 10, 5);
57872062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned SImm7 = fieldFromInstruction(Insn, 15, 7);
57972062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned L = fieldFromInstruction(Insn, 22, 1);
58072062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned V = fieldFromInstruction(Insn, 26, 1);
58172062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Opc = fieldFromInstruction(Insn, 30, 2);
58272062f5744557e270a38192554c3126ea5f97434Tim Northover
58372062f5744557e270a38192554c3126ea5f97434Tim Northover  // Not an official name, but it turns out that bit 23 distinguishes indexed
58472062f5744557e270a38192554c3126ea5f97434Tim Northover  // from non-indexed operations.
58572062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Indexed = fieldFromInstruction(Insn, 23, 1);
58672062f5744557e270a38192554c3126ea5f97434Tim Northover
58772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Indexed && L == 0) {
58872062f5744557e270a38192554c3126ea5f97434Tim Northover    // The MCInst for an indexed store has an out operand and 4 ins:
58972062f5744557e270a38192554c3126ea5f97434Tim Northover    //    Rn_wb, Rt, Rt2, Rn, Imm
59072062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
59172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
59272062f5744557e270a38192554c3126ea5f97434Tim Northover
59372062f5744557e270a38192554c3126ea5f97434Tim Northover  // You shouldn't load to the same register twice in an instruction...
59472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (L && Rt == Rt2)
59572062f5744557e270a38192554c3126ea5f97434Tim Northover    Result = MCDisassembler::SoftFail;
59672062f5744557e270a38192554c3126ea5f97434Tim Northover
59772062f5744557e270a38192554c3126ea5f97434Tim Northover  // ... or do any operation that writes-back to a transfer register. But note
59872062f5744557e270a38192554c3126ea5f97434Tim Northover  // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
59972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Indexed && V == 0 && Rn != 31 && (Rt == Rn || Rt2 == Rn))
60072062f5744557e270a38192554c3126ea5f97434Tim Northover    Result = MCDisassembler::SoftFail;
60172062f5744557e270a38192554c3126ea5f97434Tim Northover
60272062f5744557e270a38192554c3126ea5f97434Tim Northover  // Exactly how we decode the MCInst's registers depends on the Opc and V
60372062f5744557e270a38192554c3126ea5f97434Tim Northover  // fields of the instruction. These also obviously determine the size of the
60472062f5744557e270a38192554c3126ea5f97434Tim Northover  // operation so we can fill in that information while we're at it.
60572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (V) {
60672062f5744557e270a38192554c3126ea5f97434Tim Northover    // The instruction operates on the FP/SIMD registers
60772062f5744557e270a38192554c3126ea5f97434Tim Northover    switch (Opc) {
60872062f5744557e270a38192554c3126ea5f97434Tim Northover    default: return MCDisassembler::Fail;
60972062f5744557e270a38192554c3126ea5f97434Tim Northover    case 0:
61072062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
61172062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR32RegisterClass(Inst, Rt2, Address, Decoder);
61272062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
61372062f5744557e270a38192554c3126ea5f97434Tim Northover    case 1:
61472062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
61572062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR64RegisterClass(Inst, Rt2, Address, Decoder);
61672062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
61772062f5744557e270a38192554c3126ea5f97434Tim Northover    case 2:
61872062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
61972062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR128RegisterClass(Inst, Rt2, Address, Decoder);
62072062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
62172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
62272062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
62372062f5744557e270a38192554c3126ea5f97434Tim Northover    switch (Opc) {
62472062f5744557e270a38192554c3126ea5f97434Tim Northover    default: return MCDisassembler::Fail;
62572062f5744557e270a38192554c3126ea5f97434Tim Northover    case 0:
62672062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
62772062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder);
62872062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
62972062f5744557e270a38192554c3126ea5f97434Tim Northover    case 1:
63072062f5744557e270a38192554c3126ea5f97434Tim Northover      assert(L && "unexpected \"store signed\" attempt");
63172062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
63272062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
63372062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
63472062f5744557e270a38192554c3126ea5f97434Tim Northover    case 2:
63572062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
63672062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
63772062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
63872062f5744557e270a38192554c3126ea5f97434Tim Northover    }
63972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
64072062f5744557e270a38192554c3126ea5f97434Tim Northover
64172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Indexed && L == 1) {
64272062f5744557e270a38192554c3126ea5f97434Tim Northover    // The MCInst for an indexed load has 3 out operands and an 3 ins:
64372062f5744557e270a38192554c3126ea5f97434Tim Northover    //    Rt, Rt2, Rn_wb, Rt2, Rn, Imm
64472062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
64572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
64672062f5744557e270a38192554c3126ea5f97434Tim Northover
64772062f5744557e270a38192554c3126ea5f97434Tim Northover
64872062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
64972062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(SImm7));
65072062f5744557e270a38192554c3126ea5f97434Tim Northover
65172062f5744557e270a38192554c3126ea5f97434Tim Northover  return Result;
65272062f5744557e270a38192554c3126ea5f97434Tim Northover}
65372062f5744557e270a38192554c3126ea5f97434Tim Northover
65472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst,
65572062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       uint32_t Val,
65672062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       uint64_t Address,
65772062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       const void *Decoder) {
65872062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rt = fieldFromInstruction(Val, 0, 5);
65972062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rn = fieldFromInstruction(Val, 5, 5);
66072062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rt2 = fieldFromInstruction(Val, 10, 5);
66172062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned MemSize = fieldFromInstruction(Val, 30, 2);
66272062f5744557e270a38192554c3126ea5f97434Tim Northover
66372062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeStatus S = MCDisassembler::Success;
66472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Rt == Rt2) S = MCDisassembler::SoftFail;
66572062f5744557e270a38192554c3126ea5f97434Tim Northover
66672062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (MemSize) {
66772062f5744557e270a38192554c3126ea5f97434Tim Northover    case 2:
66872062f5744557e270a38192554c3126ea5f97434Tim Northover      if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder)))
66972062f5744557e270a38192554c3126ea5f97434Tim Northover        return MCDisassembler::Fail;
67072062f5744557e270a38192554c3126ea5f97434Tim Northover      if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder)))
67172062f5744557e270a38192554c3126ea5f97434Tim Northover        return MCDisassembler::Fail;
67272062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
67372062f5744557e270a38192554c3126ea5f97434Tim Northover    case 3:
67472062f5744557e270a38192554c3126ea5f97434Tim Northover      if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder)))
67572062f5744557e270a38192554c3126ea5f97434Tim Northover        return MCDisassembler::Fail;
67672062f5744557e270a38192554c3126ea5f97434Tim Northover      if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder)))
67772062f5744557e270a38192554c3126ea5f97434Tim Northover        return MCDisassembler::Fail;
67872062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
67972062f5744557e270a38192554c3126ea5f97434Tim Northover    default:
68072062f5744557e270a38192554c3126ea5f97434Tim Northover      llvm_unreachable("Invalid MemSize in DecodeLoadPairExclusiveInstruction");
68172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
68272062f5744557e270a38192554c3126ea5f97434Tim Northover
68372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!Check(S, DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder)))
68472062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
68572062f5744557e270a38192554c3126ea5f97434Tim Northover
68672062f5744557e270a38192554c3126ea5f97434Tim Northover  return S;
68772062f5744557e270a38192554c3126ea5f97434Tim Northover}
68872062f5744557e270a38192554c3126ea5f97434Tim Northover
68972062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<typename SomeNamedImmMapper>
69072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst,
69172062f5744557e270a38192554c3126ea5f97434Tim Northover                                          unsigned Val,
69272062f5744557e270a38192554c3126ea5f97434Tim Northover                                          uint64_t Address,
69372062f5744557e270a38192554c3126ea5f97434Tim Northover                                          const void *Decoder) {
69472062f5744557e270a38192554c3126ea5f97434Tim Northover  SomeNamedImmMapper Mapper;
69572062f5744557e270a38192554c3126ea5f97434Tim Northover  bool ValidNamed;
69672062f5744557e270a38192554c3126ea5f97434Tim Northover  Mapper.toString(Val, ValidNamed);
69772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (ValidNamed || Mapper.validImm(Val)) {
69872062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(Val));
69972062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Success;
70072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
70172062f5744557e270a38192554c3126ea5f97434Tim Northover
70272062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Fail;
70372062f5744557e270a38192554c3126ea5f97434Tim Northover}
70472062f5744557e270a38192554c3126ea5f97434Tim Northover
70572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeSysRegOperand(const A64SysReg::SysRegMapper &Mapper,
70672062f5744557e270a38192554c3126ea5f97434Tim Northover                                        llvm::MCInst &Inst,
70772062f5744557e270a38192554c3126ea5f97434Tim Northover                                        unsigned Val,
70872062f5744557e270a38192554c3126ea5f97434Tim Northover                                        uint64_t Address,
70972062f5744557e270a38192554c3126ea5f97434Tim Northover                                        const void *Decoder) {
71072062f5744557e270a38192554c3126ea5f97434Tim Northover  bool ValidNamed;
71172062f5744557e270a38192554c3126ea5f97434Tim Northover  Mapper.toString(Val, ValidNamed);
71272062f5744557e270a38192554c3126ea5f97434Tim Northover
71372062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Val));
71472062f5744557e270a38192554c3126ea5f97434Tim Northover
71572062f5744557e270a38192554c3126ea5f97434Tim Northover  return ValidNamed ? MCDisassembler::Success : MCDisassembler::Fail;
71672062f5744557e270a38192554c3126ea5f97434Tim Northover}
71772062f5744557e270a38192554c3126ea5f97434Tim Northover
71872062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst,
71972062f5744557e270a38192554c3126ea5f97434Tim Northover                                     unsigned Val,
72072062f5744557e270a38192554c3126ea5f97434Tim Northover                                     uint64_t Address,
72172062f5744557e270a38192554c3126ea5f97434Tim Northover                                     const void *Decoder) {
72272062f5744557e270a38192554c3126ea5f97434Tim Northover  return DecodeSysRegOperand(A64SysReg::MRSMapper(), Inst, Val, Address,
72372062f5744557e270a38192554c3126ea5f97434Tim Northover                             Decoder);
72472062f5744557e270a38192554c3126ea5f97434Tim Northover}
72572062f5744557e270a38192554c3126ea5f97434Tim Northover
72672062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMSROperand(llvm::MCInst &Inst,
72772062f5744557e270a38192554c3126ea5f97434Tim Northover                                     unsigned Val,
72872062f5744557e270a38192554c3126ea5f97434Tim Northover                                     uint64_t Address,
72972062f5744557e270a38192554c3126ea5f97434Tim Northover                                     const void *Decoder) {
73072062f5744557e270a38192554c3126ea5f97434Tim Northover  return DecodeSysRegOperand(A64SysReg::MSRMapper(), Inst, Val, Address,
73172062f5744557e270a38192554c3126ea5f97434Tim Northover                             Decoder);
73272062f5744557e270a38192554c3126ea5f97434Tim Northover}
73372062f5744557e270a38192554c3126ea5f97434Tim Northover
73472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst,
73572062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   unsigned Insn,
73672062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   uint64_t Address,
73772062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   const void *Decoder) {
73872062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rt = fieldFromInstruction(Insn, 0, 5);
73972062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rn = fieldFromInstruction(Insn, 5, 5);
74072062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Imm9 = fieldFromInstruction(Insn, 12, 9);
74172062f5744557e270a38192554c3126ea5f97434Tim Northover
74272062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Opc = fieldFromInstruction(Insn, 22, 2);
74372062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned V = fieldFromInstruction(Insn, 26, 1);
74472062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Size = fieldFromInstruction(Insn, 30, 2);
74572062f5744557e270a38192554c3126ea5f97434Tim Northover
74672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Opc == 0 || (V == 1 && Opc == 2)) {
74772062f5744557e270a38192554c3126ea5f97434Tim Northover    // It's a store, the MCInst gets: Rn_wb, Rt, Rn, Imm
74872062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
74972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
75072062f5744557e270a38192554c3126ea5f97434Tim Northover
75172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (V == 0 && (Opc == 2 || Size == 3)) {
75272062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
75372062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (V == 0) {
75472062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
75572062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (V == 1 && (Opc & 2)) {
75672062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
75772062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
75872062f5744557e270a38192554c3126ea5f97434Tim Northover    switch (Size) {
75972062f5744557e270a38192554c3126ea5f97434Tim Northover    case 0:
76072062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR8RegisterClass(Inst, Rt, Address, Decoder);
76172062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
76272062f5744557e270a38192554c3126ea5f97434Tim Northover    case 1:
76372062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR16RegisterClass(Inst, Rt, Address, Decoder);
76472062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
76572062f5744557e270a38192554c3126ea5f97434Tim Northover    case 2:
76672062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
76772062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
76872062f5744557e270a38192554c3126ea5f97434Tim Northover    case 3:
76972062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
77072062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
77172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
77272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
77372062f5744557e270a38192554c3126ea5f97434Tim Northover
77472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Opc != 0 && (V != 1 || Opc != 2)) {
77572062f5744557e270a38192554c3126ea5f97434Tim Northover    // It's a load, the MCInst gets: Rt, Rn_wb, Rn, Imm
77672062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
77772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
77872062f5744557e270a38192554c3126ea5f97434Tim Northover
77972062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
78072062f5744557e270a38192554c3126ea5f97434Tim Northover
78172062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Imm9));
78272062f5744557e270a38192554c3126ea5f97434Tim Northover
78372062f5744557e270a38192554c3126ea5f97434Tim Northover  // N.b. The official documentation says undpredictable if Rt == Rn, but this
78472062f5744557e270a38192554c3126ea5f97434Tim Northover  // takes place at the architectural rather than encoding level:
78572062f5744557e270a38192554c3126ea5f97434Tim Northover  //
78672062f5744557e270a38192554c3126ea5f97434Tim Northover  // "STR xzr, [sp], #4" is perfectly valid.
78772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (V == 0 && Rt == Rn && Rn != 31)
78872062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::SoftFail;
78972062f5744557e270a38192554c3126ea5f97434Tim Northover  else
79072062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Success;
79172062f5744557e270a38192554c3126ea5f97434Tim Northover}
79272062f5744557e270a38192554c3126ea5f97434Tim Northover
79372062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic MCDisassembler *createAArch64Disassembler(const Target &T,
79472062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 const MCSubtargetInfo &STI) {
79572062f5744557e270a38192554c3126ea5f97434Tim Northover  return new AArch64Disassembler(STI, T.createMCRegInfo(""));
79672062f5744557e270a38192554c3126ea5f97434Tim Northover}
79772062f5744557e270a38192554c3126ea5f97434Tim Northover
79872062f5744557e270a38192554c3126ea5f97434Tim Northoverextern "C" void LLVMInitializeAArch64Disassembler() {
79972062f5744557e270a38192554c3126ea5f97434Tim Northover  TargetRegistry::RegisterMCDisassembler(TheAArch64Target,
80072062f5744557e270a38192554c3126ea5f97434Tim Northover                                         createAArch64Disassembler);
80172062f5744557e270a38192554c3126ea5f97434Tim Northover}
80272062f5744557e270a38192554c3126ea5f97434Tim Northover
80372062f5744557e270a38192554c3126ea5f97434Tim Northover
804