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 {
418be527901ac87d49f7b0b56c96dbc6dadabb5069Rafael Espindola  OwningPtr<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
498be527901ac87d49f7b0b56c96dbc6dadabb5069Rafael Espindola  ~AArch64Disassembler() {}
5072062f5744557e270a38192554c3126ea5f97434Tim Northover
5172062f5744557e270a38192554c3126ea5f97434Tim Northover  /// See MCDisassembler.
5272062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeStatus getInstruction(MCInst &instr,
5372062f5744557e270a38192554c3126ea5f97434Tim Northover                              uint64_t &size,
5472062f5744557e270a38192554c3126ea5f97434Tim Northover                              const MemoryObject &region,
5572062f5744557e270a38192554c3126ea5f97434Tim Northover                              uint64_t address,
5672062f5744557e270a38192554c3126ea5f97434Tim Northover                              raw_ostream &vStream,
5772062f5744557e270a38192554c3126ea5f97434Tim Northover                              raw_ostream &cStream) const;
5872062f5744557e270a38192554c3126ea5f97434Tim Northover
598be527901ac87d49f7b0b56c96dbc6dadabb5069Rafael Espindola  const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
6072062f5744557e270a38192554c3126ea5f97434Tim Northover};
6172062f5744557e270a38192554c3126ea5f97434Tim Northover
6272062f5744557e270a38192554c3126ea5f97434Tim Northover}
6372062f5744557e270a38192554c3126ea5f97434Tim Northover
6472062f5744557e270a38192554c3126ea5f97434Tim Northover// Forward-declarations used in the auto-generated files.
6572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
6672062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
6772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
6872062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
6972062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder);
7072062f5744557e270a38192554c3126ea5f97434Tim Northover
7172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
7272062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
7372062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
7472062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
7572062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder);
7672062f5744557e270a38192554c3126ea5f97434Tim Northover
7772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
7872062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
7972062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
8072062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
8172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
8272062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
8372062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
8472062f5744557e270a38192554c3126ea5f97434Tim Northover                                         uint64_t Address, const void *Decoder);
85dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northoverstatic DecodeStatus DecodeFPR128RegisterClass(llvm::MCInst &Inst,
86dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                              unsigned RegNo, uint64_t Address,
87dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                              const void *Decoder);
8887773c318fcee853fb34a80a10c4347d523bdafbTim Northoverstatic DecodeStatus DecodeVPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
8987773c318fcee853fb34a80a10c4347d523bdafbTim Northover                                             uint64_t Address,
9087773c318fcee853fb34a80a10c4347d523bdafbTim Northover                                             const void *Decoder);
91dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northoverstatic DecodeStatus DecodeVPR128RegisterClass(llvm::MCInst &Inst,
92dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                              unsigned RegNo, uint64_t Address,
93dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                              const void *Decoder);
9472062f5744557e270a38192554c3126ea5f97434Tim Northover
9572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst,
9672062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned OptionHiS,
9772062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
9872062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder);
9972062f5744557e270a38192554c3126ea5f97434Tim Northover
10072062f5744557e270a38192554c3126ea5f97434Tim Northover
10172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst,
10272062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned Imm6Bits,
10372062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
10472062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder);
10572062f5744557e270a38192554c3126ea5f97434Tim Northover
10672062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst,
10772062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned Imm6Bits,
10872062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
10972062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder);
11072062f5744557e270a38192554c3126ea5f97434Tim Northover
11154a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northoverstatic DecodeStatus DecodeFPZeroOperand(llvm::MCInst &Inst,
11254a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        unsigned RmBits,
11354a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        uint64_t Address,
11454a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        const void *Decoder);
11554a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover
11672062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<int RegWidth>
11772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst,
11872062f5744557e270a38192554c3126ea5f97434Tim Northover                                             unsigned FullImm,
11972062f5744557e270a38192554c3126ea5f97434Tim Northover                                             uint64_t Address,
12072062f5744557e270a38192554c3126ea5f97434Tim Northover                                             const void *Decoder);
12172062f5744557e270a38192554c3126ea5f97434Tim Northover
12272062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<int RegWidth>
12372062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst,
12472062f5744557e270a38192554c3126ea5f97434Tim Northover                                            unsigned Bits,
12572062f5744557e270a38192554c3126ea5f97434Tim Northover                                            uint64_t Address,
12672062f5744557e270a38192554c3126ea5f97434Tim Northover                                            const void *Decoder);
12772062f5744557e270a38192554c3126ea5f97434Tim Northover
12872062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst,
12972062f5744557e270a38192554c3126ea5f97434Tim Northover                                           unsigned ShiftAmount,
13072062f5744557e270a38192554c3126ea5f97434Tim Northover                                           uint64_t Address,
13172062f5744557e270a38192554c3126ea5f97434Tim Northover                                           const void *Decoder);
13287773c318fcee853fb34a80a10c4347d523bdafbTim Northovertemplate <A64SE::ShiftExtSpecifiers Ext, bool IsHalf>
13387773c318fcee853fb34a80a10c4347d523bdafbTim Northoverstatic DecodeStatus
13487773c318fcee853fb34a80a10c4347d523bdafbTim NorthoverDecodeNeonMovImmShiftOperand(llvm::MCInst &Inst, unsigned ShiftAmount,
13587773c318fcee853fb34a80a10c4347d523bdafbTim Northover                             uint64_t Address, const void *Decoder);
13672062f5744557e270a38192554c3126ea5f97434Tim Northover
13772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst,
13872062f5744557e270a38192554c3126ea5f97434Tim Northover                                            unsigned ShiftAmount,
13972062f5744557e270a38192554c3126ea5f97434Tim Northover                                            uint64_t Address,
14072062f5744557e270a38192554c3126ea5f97434Tim Northover                                            const void *Decoder);
14172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn,
14272062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
14372062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder);
14472062f5744557e270a38192554c3126ea5f97434Tim Northover
14572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
14672062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
14772062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder);
14872062f5744557e270a38192554c3126ea5f97434Tim Northover
14972062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst,
15072062f5744557e270a38192554c3126ea5f97434Tim Northover                                              unsigned Insn,
15172062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
15272062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder);
15372062f5744557e270a38192554c3126ea5f97434Tim Northover
15472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst,
15572062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       unsigned Val,
15672062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       uint64_t Address,
15772062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       const void *Decoder);
15872062f5744557e270a38192554c3126ea5f97434Tim Northover
15972062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<typename SomeNamedImmMapper>
16072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst,
16172062f5744557e270a38192554c3126ea5f97434Tim Northover                                          unsigned Val,
16272062f5744557e270a38192554c3126ea5f97434Tim Northover                                          uint64_t Address,
16372062f5744557e270a38192554c3126ea5f97434Tim Northover                                          const void *Decoder);
16472062f5744557e270a38192554c3126ea5f97434Tim Northover
165dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northoverstatic DecodeStatus
166dfe076af9879eb68a7b8331f9c02eecf563d85beTim NorthoverDecodeSysRegOperand(const A64SysReg::SysRegMapper &InstMapper,
167dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                    llvm::MCInst &Inst, unsigned Val,
168dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                    uint64_t Address, const void *Decoder);
16972062f5744557e270a38192554c3126ea5f97434Tim Northover
17072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst,
17172062f5744557e270a38192554c3126ea5f97434Tim Northover                                     unsigned Val,
17272062f5744557e270a38192554c3126ea5f97434Tim Northover                                     uint64_t Address,
17372062f5744557e270a38192554c3126ea5f97434Tim Northover                                     const void *Decoder);
17472062f5744557e270a38192554c3126ea5f97434Tim Northover
17572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMSROperand(llvm::MCInst &Inst,
17672062f5744557e270a38192554c3126ea5f97434Tim Northover                                     unsigned Val,
17772062f5744557e270a38192554c3126ea5f97434Tim Northover                                     uint64_t Address,
17872062f5744557e270a38192554c3126ea5f97434Tim Northover                                     const void *Decoder);
17972062f5744557e270a38192554c3126ea5f97434Tim Northover
18072062f5744557e270a38192554c3126ea5f97434Tim Northover
18172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst,
18272062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   unsigned Val,
18372062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   uint64_t Address,
18472062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   const void *Decoder);
18572062f5744557e270a38192554c3126ea5f97434Tim Northover
18672062f5744557e270a38192554c3126ea5f97434Tim Northover
18772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic bool Check(DecodeStatus &Out, DecodeStatus In);
18872062f5744557e270a38192554c3126ea5f97434Tim Northover
18972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenDisassemblerTables.inc"
19072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenInstrInfo.inc"
19172062f5744557e270a38192554c3126ea5f97434Tim Northover
19272062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic bool Check(DecodeStatus &Out, DecodeStatus In) {
19372062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (In) {
19472062f5744557e270a38192554c3126ea5f97434Tim Northover    case MCDisassembler::Success:
19572062f5744557e270a38192554c3126ea5f97434Tim Northover      // Out stays the same.
19672062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
19772062f5744557e270a38192554c3126ea5f97434Tim Northover    case MCDisassembler::SoftFail:
19872062f5744557e270a38192554c3126ea5f97434Tim Northover      Out = In;
19972062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
20072062f5744557e270a38192554c3126ea5f97434Tim Northover    case MCDisassembler::Fail:
20172062f5744557e270a38192554c3126ea5f97434Tim Northover      Out = In;
20272062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
20372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
20472062f5744557e270a38192554c3126ea5f97434Tim Northover  llvm_unreachable("Invalid DecodeStatus!");
20572062f5744557e270a38192554c3126ea5f97434Tim Northover}
20672062f5744557e270a38192554c3126ea5f97434Tim Northover
20772062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
20872062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 const MemoryObject &Region,
20972062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 uint64_t Address,
21072062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 raw_ostream &os,
21172062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 raw_ostream &cs) const {
21272062f5744557e270a38192554c3126ea5f97434Tim Northover  CommentStream = &cs;
21372062f5744557e270a38192554c3126ea5f97434Tim Northover
21472062f5744557e270a38192554c3126ea5f97434Tim Northover  uint8_t bytes[4];
21572062f5744557e270a38192554c3126ea5f97434Tim Northover
21672062f5744557e270a38192554c3126ea5f97434Tim Northover  // We want to read exactly 4 bytes of data.
21749a6a8d8f2994249c81b7914b07015714748a55cBenjamin Kramer  if (Region.readBytes(Address, 4, bytes) == -1) {
21872062f5744557e270a38192554c3126ea5f97434Tim Northover    Size = 0;
21972062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
22072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
22172062f5744557e270a38192554c3126ea5f97434Tim Northover
22272062f5744557e270a38192554c3126ea5f97434Tim Northover  // Encoded as a small-endian 32-bit word in the stream.
22372062f5744557e270a38192554c3126ea5f97434Tim Northover  uint32_t insn = (bytes[3] << 24) |
22472062f5744557e270a38192554c3126ea5f97434Tim Northover    (bytes[2] << 16) |
22572062f5744557e270a38192554c3126ea5f97434Tim Northover    (bytes[1] <<  8) |
22672062f5744557e270a38192554c3126ea5f97434Tim Northover    (bytes[0] <<  0);
22772062f5744557e270a38192554c3126ea5f97434Tim Northover
22872062f5744557e270a38192554c3126ea5f97434Tim Northover  // Calling the auto-generated decoder function.
22972062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeStatus result = decodeInstruction(DecoderTableA6432, MI, insn, Address,
23072062f5744557e270a38192554c3126ea5f97434Tim Northover                                          this, STI);
23172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (result != MCDisassembler::Fail) {
23272062f5744557e270a38192554c3126ea5f97434Tim Northover    Size = 4;
23372062f5744557e270a38192554c3126ea5f97434Tim Northover    return result;
23472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
23572062f5744557e270a38192554c3126ea5f97434Tim Northover
23672062f5744557e270a38192554c3126ea5f97434Tim Northover  MI.clear();
23772062f5744557e270a38192554c3126ea5f97434Tim Northover  Size = 0;
23872062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Fail;
23972062f5744557e270a38192554c3126ea5f97434Tim Northover}
24072062f5744557e270a38192554c3126ea5f97434Tim Northover
24172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
24272062f5744557e270a38192554c3126ea5f97434Tim Northover  const AArch64Disassembler *Dis = static_cast<const AArch64Disassembler*>(D);
24372062f5744557e270a38192554c3126ea5f97434Tim Northover  return Dis->getRegInfo()->getRegClass(RC).getRegister(RegNo);
24472062f5744557e270a38192554c3126ea5f97434Tim Northover}
24572062f5744557e270a38192554c3126ea5f97434Tim Northover
24672062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
24772062f5744557e270a38192554c3126ea5f97434Tim Northover                                        uint64_t Address, const void *Decoder) {
24872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
24972062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
25072062f5744557e270a38192554c3126ea5f97434Tim Northover
25172062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::GPR64RegClassID, RegNo);
25272062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
25372062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
25472062f5744557e270a38192554c3126ea5f97434Tim Northover}
25572062f5744557e270a38192554c3126ea5f97434Tim Northover
25672062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
25772062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
25872062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
25972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
26072062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
26172062f5744557e270a38192554c3126ea5f97434Tim Northover
26272062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::GPR64xspRegClassID, RegNo);
26372062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
26472062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
26572062f5744557e270a38192554c3126ea5f97434Tim Northover}
26672062f5744557e270a38192554c3126ea5f97434Tim Northover
26772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
268dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                             uint64_t Address,
269dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                             const void *Decoder) {
27072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
27172062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
27272062f5744557e270a38192554c3126ea5f97434Tim Northover
27372062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::GPR32RegClassID, RegNo);
27472062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
27572062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
27672062f5744557e270a38192554c3126ea5f97434Tim Northover}
27772062f5744557e270a38192554c3126ea5f97434Tim Northover
27872062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
27972062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
28072062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
28172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
28272062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
28372062f5744557e270a38192554c3126ea5f97434Tim Northover
28472062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::GPR32wspRegClassID, RegNo);
28572062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
28672062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
28772062f5744557e270a38192554c3126ea5f97434Tim Northover}
28872062f5744557e270a38192554c3126ea5f97434Tim Northover
28972062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
29072062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
29172062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
29272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
29372062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
29472062f5744557e270a38192554c3126ea5f97434Tim Northover
29572062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::FPR8RegClassID, RegNo);
29672062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
29772062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
29872062f5744557e270a38192554c3126ea5f97434Tim Northover}
29972062f5744557e270a38192554c3126ea5f97434Tim Northover
30072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
30172062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
30272062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
30372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
30472062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
30572062f5744557e270a38192554c3126ea5f97434Tim Northover
30672062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::FPR16RegClassID, RegNo);
30772062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
30872062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
30972062f5744557e270a38192554c3126ea5f97434Tim Northover}
31072062f5744557e270a38192554c3126ea5f97434Tim Northover
31172062f5744557e270a38192554c3126ea5f97434Tim Northover
31272062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
31372062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
31472062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
31572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
31672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
31772062f5744557e270a38192554c3126ea5f97434Tim Northover
31872062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::FPR32RegClassID, RegNo);
31972062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
32072062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
32172062f5744557e270a38192554c3126ea5f97434Tim Northover}
32272062f5744557e270a38192554c3126ea5f97434Tim Northover
32372062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
32472062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
32572062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
32672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
32772062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
32872062f5744557e270a38192554c3126ea5f97434Tim Northover
32972062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::FPR64RegClassID, RegNo);
33072062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
33172062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
33272062f5744557e270a38192554c3126ea5f97434Tim Northover}
33372062f5744557e270a38192554c3126ea5f97434Tim Northover
33472062f5744557e270a38192554c3126ea5f97434Tim Northover
33572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
33672062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeFPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
33772062f5744557e270a38192554c3126ea5f97434Tim Northover                            uint64_t Address, const void *Decoder) {
33872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
33972062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
34072062f5744557e270a38192554c3126ea5f97434Tim Northover
34172062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::FPR128RegClassID, RegNo);
34272062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
34372062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
34472062f5744557e270a38192554c3126ea5f97434Tim Northover}
34572062f5744557e270a38192554c3126ea5f97434Tim Northover
34687773c318fcee853fb34a80a10c4347d523bdafbTim Northoverstatic DecodeStatus DecodeVPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
34787773c318fcee853fb34a80a10c4347d523bdafbTim Northover                                             uint64_t Address,
34887773c318fcee853fb34a80a10c4347d523bdafbTim Northover                                             const void *Decoder) {
34987773c318fcee853fb34a80a10c4347d523bdafbTim Northover  if (RegNo > 31)
35087773c318fcee853fb34a80a10c4347d523bdafbTim Northover    return MCDisassembler::Fail;
35187773c318fcee853fb34a80a10c4347d523bdafbTim Northover
35287773c318fcee853fb34a80a10c4347d523bdafbTim Northover  uint16_t Register = getReg(Decoder, AArch64::VPR64RegClassID, RegNo);
35387773c318fcee853fb34a80a10c4347d523bdafbTim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
35487773c318fcee853fb34a80a10c4347d523bdafbTim Northover  return MCDisassembler::Success;
35587773c318fcee853fb34a80a10c4347d523bdafbTim Northover}
35687773c318fcee853fb34a80a10c4347d523bdafbTim Northover
35772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus
35872062f5744557e270a38192554c3126ea5f97434Tim NorthoverDecodeVPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
35987773c318fcee853fb34a80a10c4347d523bdafbTim Northover						  uint64_t Address, const void *Decoder) {
36072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNo > 31)
36172062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
36272062f5744557e270a38192554c3126ea5f97434Tim Northover
36372062f5744557e270a38192554c3126ea5f97434Tim Northover  uint16_t Register = getReg(Decoder, AArch64::VPR128RegClassID, RegNo);
36472062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateReg(Register));
36572062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
36672062f5744557e270a38192554c3126ea5f97434Tim Northover}
36772062f5744557e270a38192554c3126ea5f97434Tim Northover
36872062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst,
36972062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned OptionHiS,
37072062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
37172062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder) {
37272062f5744557e270a38192554c3126ea5f97434Tim Northover  // Option{1} must be 1. OptionHiS is made up of {Option{2}, Option{1},
37372062f5744557e270a38192554c3126ea5f97434Tim Northover  // S}. Hence we want to check bit 1.
37472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!(OptionHiS & 2))
37572062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
37672062f5744557e270a38192554c3126ea5f97434Tim Northover
37772062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(OptionHiS));
37872062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
37972062f5744557e270a38192554c3126ea5f97434Tim Northover}
38072062f5744557e270a38192554c3126ea5f97434Tim Northover
38172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst,
38272062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned Imm6Bits,
38372062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
38472062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder) {
38572062f5744557e270a38192554c3126ea5f97434Tim Northover  // In the 32-bit variant, bit 6 must be zero. I.e. the immediate must be
38672062f5744557e270a38192554c3126ea5f97434Tim Northover  // between 0 and 31.
38772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Imm6Bits > 31)
38872062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
38972062f5744557e270a38192554c3126ea5f97434Tim Northover
39072062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Imm6Bits));
39172062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
39272062f5744557e270a38192554c3126ea5f97434Tim Northover}
39372062f5744557e270a38192554c3126ea5f97434Tim Northover
39472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst,
39572062f5744557e270a38192554c3126ea5f97434Tim Northover                                               unsigned Imm6Bits,
39672062f5744557e270a38192554c3126ea5f97434Tim Northover                                               uint64_t Address,
39772062f5744557e270a38192554c3126ea5f97434Tim Northover                                               const void *Decoder) {
39872062f5744557e270a38192554c3126ea5f97434Tim Northover  // 1 <= Imm <= 32. Encoded as 64 - Imm so: 63 >= Encoded >= 32.
39972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Imm6Bits < 32)
40072062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
40172062f5744557e270a38192554c3126ea5f97434Tim Northover
40272062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Imm6Bits));
40372062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
40472062f5744557e270a38192554c3126ea5f97434Tim Northover}
40572062f5744557e270a38192554c3126ea5f97434Tim Northover
40654a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northoverstatic DecodeStatus DecodeFPZeroOperand(llvm::MCInst &Inst,
40754a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        unsigned RmBits,
40854a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        uint64_t Address,
40954a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover                                        const void *Decoder) {
41054a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover  // Any bits are valid in the instruction (they're architecturally ignored),
41154a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover  // but a code generator should insert 0.
41254a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover  Inst.addOperand(MCOperand::CreateImm(0));
41354a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover  return MCDisassembler::Success;
41454a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover}
41554a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover
41654a1cf75d2b32cd96ec78f61af5c1bed8d81524dTim Northover
41772062f5744557e270a38192554c3126ea5f97434Tim Northover
41872062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<int RegWidth>
41972062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst,
42072062f5744557e270a38192554c3126ea5f97434Tim Northover                                             unsigned FullImm,
42172062f5744557e270a38192554c3126ea5f97434Tim Northover                                             uint64_t Address,
42272062f5744557e270a38192554c3126ea5f97434Tim Northover                                             const void *Decoder) {
42372062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Imm16 = FullImm & 0xffff;
42472062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Shift = FullImm >> 16;
42572062f5744557e270a38192554c3126ea5f97434Tim Northover
42672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegWidth == 32 && Shift > 1) return MCDisassembler::Fail;
42772062f5744557e270a38192554c3126ea5f97434Tim Northover
42872062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Imm16));
42972062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Shift));
43072062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
43172062f5744557e270a38192554c3126ea5f97434Tim Northover}
43272062f5744557e270a38192554c3126ea5f97434Tim Northover
43372062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<int RegWidth>
43472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst,
43572062f5744557e270a38192554c3126ea5f97434Tim Northover                                            unsigned Bits,
43672062f5744557e270a38192554c3126ea5f97434Tim Northover                                            uint64_t Address,
43772062f5744557e270a38192554c3126ea5f97434Tim Northover                                            const void *Decoder) {
43872062f5744557e270a38192554c3126ea5f97434Tim Northover  uint64_t Imm;
43972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!A64Imms::isLogicalImmBits(RegWidth, Bits, Imm))
44072062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
44172062f5744557e270a38192554c3126ea5f97434Tim Northover
44272062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Bits));
44372062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
44472062f5744557e270a38192554c3126ea5f97434Tim Northover}
44572062f5744557e270a38192554c3126ea5f97434Tim Northover
44672062f5744557e270a38192554c3126ea5f97434Tim Northover
44772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst,
44872062f5744557e270a38192554c3126ea5f97434Tim Northover                                           unsigned ShiftAmount,
44972062f5744557e270a38192554c3126ea5f97434Tim Northover                                           uint64_t Address,
45072062f5744557e270a38192554c3126ea5f97434Tim Northover                                           const void *Decoder) {
45172062f5744557e270a38192554c3126ea5f97434Tim Northover  // Only values 0-4 are valid for this 3-bit field
45272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (ShiftAmount > 4)
45372062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
45472062f5744557e270a38192554c3126ea5f97434Tim Northover
45572062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
45672062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
45772062f5744557e270a38192554c3126ea5f97434Tim Northover}
45872062f5744557e270a38192554c3126ea5f97434Tim Northover
45972062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst,
46072062f5744557e270a38192554c3126ea5f97434Tim Northover                                            unsigned ShiftAmount,
46172062f5744557e270a38192554c3126ea5f97434Tim Northover                                            uint64_t Address,
46272062f5744557e270a38192554c3126ea5f97434Tim Northover                                            const void *Decoder) {
46372062f5744557e270a38192554c3126ea5f97434Tim Northover  // Only values below 32 are valid for a 32-bit register
46472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (ShiftAmount > 31)
46572062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
46672062f5744557e270a38192554c3126ea5f97434Tim Northover
46772062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
46872062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
46972062f5744557e270a38192554c3126ea5f97434Tim Northover}
47072062f5744557e270a38192554c3126ea5f97434Tim Northover
47172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn,
47272062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
47372062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder) {
47472062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rd = fieldFromInstruction(Insn, 0, 5);
47572062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rn = fieldFromInstruction(Insn, 5, 5);
47672062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned ImmS = fieldFromInstruction(Insn, 10, 6);
47772062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned ImmR = fieldFromInstruction(Insn, 16, 6);
47872062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned SF = fieldFromInstruction(Insn, 31, 1);
47972062f5744557e270a38192554c3126ea5f97434Tim Northover
48072062f5744557e270a38192554c3126ea5f97434Tim Northover  // Undef for 0b11 just in case it occurs. Don't want the compiler to optimise
48172062f5744557e270a38192554c3126ea5f97434Tim Northover  // out assertions that it thinks should never be hit.
48272062f5744557e270a38192554c3126ea5f97434Tim Northover  enum OpcTypes { SBFM = 0, BFM, UBFM, Undef } Opc;
48372062f5744557e270a38192554c3126ea5f97434Tim Northover  Opc = (OpcTypes)fieldFromInstruction(Insn, 29, 2);
48472062f5744557e270a38192554c3126ea5f97434Tim Northover
48572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!SF) {
48672062f5744557e270a38192554c3126ea5f97434Tim Northover    // ImmR and ImmS must be between 0 and 31 for 32-bit instructions.
48772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ImmR > 31 || ImmS > 31)
48872062f5744557e270a38192554c3126ea5f97434Tim Northover      return MCDisassembler::Fail;
48972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
49072062f5744557e270a38192554c3126ea5f97434Tim Northover
49172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (SF) {
49272062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
49372062f5744557e270a38192554c3126ea5f97434Tim Northover    // BFM MCInsts use Rd as a source too.
49472062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Opc == BFM) DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
49572062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
49672062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
49772062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
49872062f5744557e270a38192554c3126ea5f97434Tim Northover    // BFM MCInsts use Rd as a source too.
49972062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Opc == BFM) DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
50072062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR32RegisterClass(Inst, Rn, Address, Decoder);
50172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
50272062f5744557e270a38192554c3126ea5f97434Tim Northover
50372062f5744557e270a38192554c3126ea5f97434Tim Northover  // ASR and LSR have more specific patterns so they won't get here:
504dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover  assert(!(ImmS == 31 && !SF && Opc != BFM)
505dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover         && "shift should have used auto decode");
506dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover  assert(!(ImmS == 63 && SF && Opc != BFM)
507dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover         && "shift should have used auto decode");
50872062f5744557e270a38192554c3126ea5f97434Tim Northover
50972062f5744557e270a38192554c3126ea5f97434Tim Northover  // Extension instructions similarly:
51072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Opc == SBFM && ImmR == 0) {
51172062f5744557e270a38192554c3126ea5f97434Tim Northover    assert((ImmS != 7 && ImmS != 15) && "extension got here");
51272062f5744557e270a38192554c3126ea5f97434Tim Northover    assert((ImmS != 31 || SF == 0) && "extension got here");
51372062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (Opc == UBFM && ImmR == 0) {
51472062f5744557e270a38192554c3126ea5f97434Tim Northover    assert((SF != 0 || (ImmS != 7 && ImmS != 15)) && "extension got here");
51572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
51672062f5744557e270a38192554c3126ea5f97434Tim Northover
51772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Opc == UBFM) {
51872062f5744557e270a38192554c3126ea5f97434Tim Northover    // It might be a LSL instruction, which actually takes the shift amount
51972062f5744557e270a38192554c3126ea5f97434Tim Northover    // itself as an MCInst operand.
52072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (SF && (ImmS + 1) % 64 == ImmR) {
52172062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.setOpcode(AArch64::LSLxxi);
52272062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateImm(63 - ImmS));
52372062f5744557e270a38192554c3126ea5f97434Tim Northover      return MCDisassembler::Success;
52472062f5744557e270a38192554c3126ea5f97434Tim Northover    } else if (!SF && (ImmS + 1) % 32 == ImmR) {
52572062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.setOpcode(AArch64::LSLwwi);
52672062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateImm(31 - ImmS));
52772062f5744557e270a38192554c3126ea5f97434Tim Northover      return MCDisassembler::Success;
52872062f5744557e270a38192554c3126ea5f97434Tim Northover    }
52972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
53072062f5744557e270a38192554c3126ea5f97434Tim Northover
53172062f5744557e270a38192554c3126ea5f97434Tim Northover  // Otherwise it's definitely either an extract or an insert depending on which
53272062f5744557e270a38192554c3126ea5f97434Tim Northover  // of ImmR or ImmS is larger.
53372062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned ExtractOp, InsertOp;
53472062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Opc) {
53572062f5744557e270a38192554c3126ea5f97434Tim Northover  default: llvm_unreachable("unexpected instruction trying to decode bitfield");
53672062f5744557e270a38192554c3126ea5f97434Tim Northover  case SBFM:
53772062f5744557e270a38192554c3126ea5f97434Tim Northover    ExtractOp = SF ? AArch64::SBFXxxii : AArch64::SBFXwwii;
53872062f5744557e270a38192554c3126ea5f97434Tim Northover    InsertOp = SF ? AArch64::SBFIZxxii : AArch64::SBFIZwwii;
53972062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
54072062f5744557e270a38192554c3126ea5f97434Tim Northover  case BFM:
54172062f5744557e270a38192554c3126ea5f97434Tim Northover    ExtractOp = SF ? AArch64::BFXILxxii : AArch64::BFXILwwii;
54272062f5744557e270a38192554c3126ea5f97434Tim Northover    InsertOp = SF ? AArch64::BFIxxii : AArch64::BFIwwii;
54372062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
54472062f5744557e270a38192554c3126ea5f97434Tim Northover  case UBFM:
54572062f5744557e270a38192554c3126ea5f97434Tim Northover    ExtractOp = SF ? AArch64::UBFXxxii : AArch64::UBFXwwii;
54672062f5744557e270a38192554c3126ea5f97434Tim Northover    InsertOp = SF ? AArch64::UBFIZxxii : AArch64::UBFIZwwii;
54772062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
54872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
54972062f5744557e270a38192554c3126ea5f97434Tim Northover
55072062f5744557e270a38192554c3126ea5f97434Tim Northover  // Otherwise it's a boring insert or extract
55172062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(ImmR));
55272062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(ImmS));
55372062f5744557e270a38192554c3126ea5f97434Tim Northover
55472062f5744557e270a38192554c3126ea5f97434Tim Northover
55572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (ImmS < ImmR)
55672062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.setOpcode(InsertOp);
55772062f5744557e270a38192554c3126ea5f97434Tim Northover  else
55872062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.setOpcode(ExtractOp);
55972062f5744557e270a38192554c3126ea5f97434Tim Northover
56072062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
56172062f5744557e270a38192554c3126ea5f97434Tim Northover}
56272062f5744557e270a38192554c3126ea5f97434Tim Northover
56372062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
56472062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
56572062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder) {
56672062f5744557e270a38192554c3126ea5f97434Tim Northover  // This decoder exists to add the dummy Lane operand to the MCInst, which must
56772062f5744557e270a38192554c3126ea5f97434Tim Northover  // be 1 in assembly but has no other real manifestation.
56872062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rd = fieldFromInstruction(Insn, 0, 5);
56972062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rn = fieldFromInstruction(Insn, 5, 5);
57072062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
57172062f5744557e270a38192554c3126ea5f97434Tim Northover
57272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (IsToVec) {
57372062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeVPR128RegisterClass(Inst, Rd, Address, Decoder);
57472062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
57572062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
57672062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
57772062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeVPR128RegisterClass(Inst, Rn, Address, Decoder);
57872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
57972062f5744557e270a38192554c3126ea5f97434Tim Northover
58072062f5744557e270a38192554c3126ea5f97434Tim Northover  // Add the lane
58172062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(1));
58272062f5744557e270a38192554c3126ea5f97434Tim Northover
58372062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Success;
58472062f5744557e270a38192554c3126ea5f97434Tim Northover}
58572062f5744557e270a38192554c3126ea5f97434Tim Northover
58672062f5744557e270a38192554c3126ea5f97434Tim Northover
58772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst,
58872062f5744557e270a38192554c3126ea5f97434Tim Northover                                              unsigned Insn,
58972062f5744557e270a38192554c3126ea5f97434Tim Northover                                              uint64_t Address,
59072062f5744557e270a38192554c3126ea5f97434Tim Northover                                              const void *Decoder) {
59172062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeStatus Result = MCDisassembler::Success;
59272062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rt = fieldFromInstruction(Insn, 0, 5);
59372062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rn = fieldFromInstruction(Insn, 5, 5);
59472062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rt2 = fieldFromInstruction(Insn, 10, 5);
59572062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned SImm7 = fieldFromInstruction(Insn, 15, 7);
59672062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned L = fieldFromInstruction(Insn, 22, 1);
59772062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned V = fieldFromInstruction(Insn, 26, 1);
59872062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Opc = fieldFromInstruction(Insn, 30, 2);
59972062f5744557e270a38192554c3126ea5f97434Tim Northover
60072062f5744557e270a38192554c3126ea5f97434Tim Northover  // Not an official name, but it turns out that bit 23 distinguishes indexed
60172062f5744557e270a38192554c3126ea5f97434Tim Northover  // from non-indexed operations.
60272062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Indexed = fieldFromInstruction(Insn, 23, 1);
60372062f5744557e270a38192554c3126ea5f97434Tim Northover
60472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Indexed && L == 0) {
60572062f5744557e270a38192554c3126ea5f97434Tim Northover    // The MCInst for an indexed store has an out operand and 4 ins:
60672062f5744557e270a38192554c3126ea5f97434Tim Northover    //    Rn_wb, Rt, Rt2, Rn, Imm
60772062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
60872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
60972062f5744557e270a38192554c3126ea5f97434Tim Northover
61072062f5744557e270a38192554c3126ea5f97434Tim Northover  // You shouldn't load to the same register twice in an instruction...
61172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (L && Rt == Rt2)
61272062f5744557e270a38192554c3126ea5f97434Tim Northover    Result = MCDisassembler::SoftFail;
61372062f5744557e270a38192554c3126ea5f97434Tim Northover
61472062f5744557e270a38192554c3126ea5f97434Tim Northover  // ... or do any operation that writes-back to a transfer register. But note
61572062f5744557e270a38192554c3126ea5f97434Tim Northover  // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
61672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Indexed && V == 0 && Rn != 31 && (Rt == Rn || Rt2 == Rn))
61772062f5744557e270a38192554c3126ea5f97434Tim Northover    Result = MCDisassembler::SoftFail;
61872062f5744557e270a38192554c3126ea5f97434Tim Northover
61972062f5744557e270a38192554c3126ea5f97434Tim Northover  // Exactly how we decode the MCInst's registers depends on the Opc and V
62072062f5744557e270a38192554c3126ea5f97434Tim Northover  // fields of the instruction. These also obviously determine the size of the
62172062f5744557e270a38192554c3126ea5f97434Tim Northover  // operation so we can fill in that information while we're at it.
62272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (V) {
62372062f5744557e270a38192554c3126ea5f97434Tim Northover    // The instruction operates on the FP/SIMD registers
62472062f5744557e270a38192554c3126ea5f97434Tim Northover    switch (Opc) {
62572062f5744557e270a38192554c3126ea5f97434Tim Northover    default: return MCDisassembler::Fail;
62672062f5744557e270a38192554c3126ea5f97434Tim Northover    case 0:
62772062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
62872062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR32RegisterClass(Inst, Rt2, Address, Decoder);
62972062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
63072062f5744557e270a38192554c3126ea5f97434Tim Northover    case 1:
63172062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
63272062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR64RegisterClass(Inst, Rt2, Address, Decoder);
63372062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
63472062f5744557e270a38192554c3126ea5f97434Tim Northover    case 2:
63572062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
63672062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR128RegisterClass(Inst, Rt2, Address, Decoder);
63772062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
63872062f5744557e270a38192554c3126ea5f97434Tim Northover    }
63972062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
64072062f5744557e270a38192554c3126ea5f97434Tim Northover    switch (Opc) {
64172062f5744557e270a38192554c3126ea5f97434Tim Northover    default: return MCDisassembler::Fail;
64272062f5744557e270a38192554c3126ea5f97434Tim Northover    case 0:
64372062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
64472062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder);
64572062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
64672062f5744557e270a38192554c3126ea5f97434Tim Northover    case 1:
64772062f5744557e270a38192554c3126ea5f97434Tim Northover      assert(L && "unexpected \"store signed\" attempt");
64872062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
64972062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
65072062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
65172062f5744557e270a38192554c3126ea5f97434Tim Northover    case 2:
65272062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
65372062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
65472062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
65572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
65672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
65772062f5744557e270a38192554c3126ea5f97434Tim Northover
65872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Indexed && L == 1) {
65972062f5744557e270a38192554c3126ea5f97434Tim Northover    // The MCInst for an indexed load has 3 out operands and an 3 ins:
66072062f5744557e270a38192554c3126ea5f97434Tim Northover    //    Rt, Rt2, Rn_wb, Rt2, Rn, Imm
66172062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
66272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
66372062f5744557e270a38192554c3126ea5f97434Tim Northover
66472062f5744557e270a38192554c3126ea5f97434Tim Northover
66572062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
66672062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(SImm7));
66772062f5744557e270a38192554c3126ea5f97434Tim Northover
66872062f5744557e270a38192554c3126ea5f97434Tim Northover  return Result;
66972062f5744557e270a38192554c3126ea5f97434Tim Northover}
67072062f5744557e270a38192554c3126ea5f97434Tim Northover
67172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst,
67272062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       uint32_t Val,
67372062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       uint64_t Address,
67472062f5744557e270a38192554c3126ea5f97434Tim Northover                                                       const void *Decoder) {
67572062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rt = fieldFromInstruction(Val, 0, 5);
67672062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rn = fieldFromInstruction(Val, 5, 5);
67772062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rt2 = fieldFromInstruction(Val, 10, 5);
67872062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned MemSize = fieldFromInstruction(Val, 30, 2);
67972062f5744557e270a38192554c3126ea5f97434Tim Northover
68072062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeStatus S = MCDisassembler::Success;
68172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Rt == Rt2) S = MCDisassembler::SoftFail;
68272062f5744557e270a38192554c3126ea5f97434Tim Northover
68372062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (MemSize) {
68472062f5744557e270a38192554c3126ea5f97434Tim Northover    case 2:
68572062f5744557e270a38192554c3126ea5f97434Tim Northover      if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder)))
68672062f5744557e270a38192554c3126ea5f97434Tim Northover        return MCDisassembler::Fail;
68772062f5744557e270a38192554c3126ea5f97434Tim Northover      if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder)))
68872062f5744557e270a38192554c3126ea5f97434Tim Northover        return MCDisassembler::Fail;
68972062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
69072062f5744557e270a38192554c3126ea5f97434Tim Northover    case 3:
69172062f5744557e270a38192554c3126ea5f97434Tim Northover      if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder)))
69272062f5744557e270a38192554c3126ea5f97434Tim Northover        return MCDisassembler::Fail;
69372062f5744557e270a38192554c3126ea5f97434Tim Northover      if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder)))
69472062f5744557e270a38192554c3126ea5f97434Tim Northover        return MCDisassembler::Fail;
69572062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
69672062f5744557e270a38192554c3126ea5f97434Tim Northover    default:
69772062f5744557e270a38192554c3126ea5f97434Tim Northover      llvm_unreachable("Invalid MemSize in DecodeLoadPairExclusiveInstruction");
69872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
69972062f5744557e270a38192554c3126ea5f97434Tim Northover
70072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!Check(S, DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder)))
70172062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Fail;
70272062f5744557e270a38192554c3126ea5f97434Tim Northover
70372062f5744557e270a38192554c3126ea5f97434Tim Northover  return S;
70472062f5744557e270a38192554c3126ea5f97434Tim Northover}
70572062f5744557e270a38192554c3126ea5f97434Tim Northover
70672062f5744557e270a38192554c3126ea5f97434Tim Northovertemplate<typename SomeNamedImmMapper>
70772062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst,
70872062f5744557e270a38192554c3126ea5f97434Tim Northover                                          unsigned Val,
70972062f5744557e270a38192554c3126ea5f97434Tim Northover                                          uint64_t Address,
71072062f5744557e270a38192554c3126ea5f97434Tim Northover                                          const void *Decoder) {
71172062f5744557e270a38192554c3126ea5f97434Tim Northover  SomeNamedImmMapper Mapper;
71272062f5744557e270a38192554c3126ea5f97434Tim Northover  bool ValidNamed;
71372062f5744557e270a38192554c3126ea5f97434Tim Northover  Mapper.toString(Val, ValidNamed);
71472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (ValidNamed || Mapper.validImm(Val)) {
71572062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(Val));
71672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Success;
71772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
71872062f5744557e270a38192554c3126ea5f97434Tim Northover
71972062f5744557e270a38192554c3126ea5f97434Tim Northover  return MCDisassembler::Fail;
72072062f5744557e270a38192554c3126ea5f97434Tim Northover}
72172062f5744557e270a38192554c3126ea5f97434Tim Northover
72272062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeSysRegOperand(const A64SysReg::SysRegMapper &Mapper,
72372062f5744557e270a38192554c3126ea5f97434Tim Northover                                        llvm::MCInst &Inst,
72472062f5744557e270a38192554c3126ea5f97434Tim Northover                                        unsigned Val,
72572062f5744557e270a38192554c3126ea5f97434Tim Northover                                        uint64_t Address,
72672062f5744557e270a38192554c3126ea5f97434Tim Northover                                        const void *Decoder) {
72772062f5744557e270a38192554c3126ea5f97434Tim Northover  bool ValidNamed;
72872062f5744557e270a38192554c3126ea5f97434Tim Northover  Mapper.toString(Val, ValidNamed);
72972062f5744557e270a38192554c3126ea5f97434Tim Northover
73072062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Val));
73172062f5744557e270a38192554c3126ea5f97434Tim Northover
73272062f5744557e270a38192554c3126ea5f97434Tim Northover  return ValidNamed ? MCDisassembler::Success : MCDisassembler::Fail;
73372062f5744557e270a38192554c3126ea5f97434Tim Northover}
73472062f5744557e270a38192554c3126ea5f97434Tim Northover
73572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst,
73672062f5744557e270a38192554c3126ea5f97434Tim Northover                                     unsigned Val,
73772062f5744557e270a38192554c3126ea5f97434Tim Northover                                     uint64_t Address,
73872062f5744557e270a38192554c3126ea5f97434Tim Northover                                     const void *Decoder) {
73972062f5744557e270a38192554c3126ea5f97434Tim Northover  return DecodeSysRegOperand(A64SysReg::MRSMapper(), Inst, Val, Address,
74072062f5744557e270a38192554c3126ea5f97434Tim Northover                             Decoder);
74172062f5744557e270a38192554c3126ea5f97434Tim Northover}
74272062f5744557e270a38192554c3126ea5f97434Tim Northover
74372062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeMSROperand(llvm::MCInst &Inst,
74472062f5744557e270a38192554c3126ea5f97434Tim Northover                                     unsigned Val,
74572062f5744557e270a38192554c3126ea5f97434Tim Northover                                     uint64_t Address,
74672062f5744557e270a38192554c3126ea5f97434Tim Northover                                     const void *Decoder) {
74772062f5744557e270a38192554c3126ea5f97434Tim Northover  return DecodeSysRegOperand(A64SysReg::MSRMapper(), Inst, Val, Address,
74872062f5744557e270a38192554c3126ea5f97434Tim Northover                             Decoder);
74972062f5744557e270a38192554c3126ea5f97434Tim Northover}
75072062f5744557e270a38192554c3126ea5f97434Tim Northover
75172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst,
75272062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   unsigned Insn,
75372062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   uint64_t Address,
75472062f5744557e270a38192554c3126ea5f97434Tim Northover                                                   const void *Decoder) {
75572062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rt = fieldFromInstruction(Insn, 0, 5);
75672062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Rn = fieldFromInstruction(Insn, 5, 5);
75772062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Imm9 = fieldFromInstruction(Insn, 12, 9);
75872062f5744557e270a38192554c3126ea5f97434Tim Northover
75972062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Opc = fieldFromInstruction(Insn, 22, 2);
76072062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned V = fieldFromInstruction(Insn, 26, 1);
76172062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Size = fieldFromInstruction(Insn, 30, 2);
76272062f5744557e270a38192554c3126ea5f97434Tim Northover
76372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Opc == 0 || (V == 1 && Opc == 2)) {
76472062f5744557e270a38192554c3126ea5f97434Tim Northover    // It's a store, the MCInst gets: Rn_wb, Rt, Rn, Imm
76572062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
76672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
76772062f5744557e270a38192554c3126ea5f97434Tim Northover
76872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (V == 0 && (Opc == 2 || Size == 3)) {
76972062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
77072062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (V == 0) {
77172062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
77272062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (V == 1 && (Opc & 2)) {
77372062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
77472062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
77572062f5744557e270a38192554c3126ea5f97434Tim Northover    switch (Size) {
77672062f5744557e270a38192554c3126ea5f97434Tim Northover    case 0:
77772062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR8RegisterClass(Inst, Rt, Address, Decoder);
77872062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
77972062f5744557e270a38192554c3126ea5f97434Tim Northover    case 1:
78072062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR16RegisterClass(Inst, Rt, Address, Decoder);
78172062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
78272062f5744557e270a38192554c3126ea5f97434Tim Northover    case 2:
78372062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
78472062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
78572062f5744557e270a38192554c3126ea5f97434Tim Northover    case 3:
78672062f5744557e270a38192554c3126ea5f97434Tim Northover      DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
78772062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
78872062f5744557e270a38192554c3126ea5f97434Tim Northover    }
78972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
79072062f5744557e270a38192554c3126ea5f97434Tim Northover
79172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Opc != 0 && (V != 1 || Opc != 2)) {
79272062f5744557e270a38192554c3126ea5f97434Tim Northover    // It's a load, the MCInst gets: Rt, Rn_wb, Rn, Imm
79372062f5744557e270a38192554c3126ea5f97434Tim Northover    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
79472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
79572062f5744557e270a38192554c3126ea5f97434Tim Northover
79672062f5744557e270a38192554c3126ea5f97434Tim Northover  DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
79772062f5744557e270a38192554c3126ea5f97434Tim Northover
79872062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateImm(Imm9));
79972062f5744557e270a38192554c3126ea5f97434Tim Northover
80072062f5744557e270a38192554c3126ea5f97434Tim Northover  // N.b. The official documentation says undpredictable if Rt == Rn, but this
80172062f5744557e270a38192554c3126ea5f97434Tim Northover  // takes place at the architectural rather than encoding level:
80272062f5744557e270a38192554c3126ea5f97434Tim Northover  //
80372062f5744557e270a38192554c3126ea5f97434Tim Northover  // "STR xzr, [sp], #4" is perfectly valid.
80472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (V == 0 && Rt == Rn && Rn != 31)
80572062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::SoftFail;
80672062f5744557e270a38192554c3126ea5f97434Tim Northover  else
80772062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCDisassembler::Success;
80872062f5744557e270a38192554c3126ea5f97434Tim Northover}
80972062f5744557e270a38192554c3126ea5f97434Tim Northover
81072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic MCDisassembler *createAArch64Disassembler(const Target &T,
81172062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 const MCSubtargetInfo &STI) {
81272062f5744557e270a38192554c3126ea5f97434Tim Northover  return new AArch64Disassembler(STI, T.createMCRegInfo(""));
81372062f5744557e270a38192554c3126ea5f97434Tim Northover}
81472062f5744557e270a38192554c3126ea5f97434Tim Northover
81572062f5744557e270a38192554c3126ea5f97434Tim Northoverextern "C" void LLVMInitializeAArch64Disassembler() {
81672062f5744557e270a38192554c3126ea5f97434Tim Northover  TargetRegistry::RegisterMCDisassembler(TheAArch64Target,
81772062f5744557e270a38192554c3126ea5f97434Tim Northover                                         createAArch64Disassembler);
81872062f5744557e270a38192554c3126ea5f97434Tim Northover}
81972062f5744557e270a38192554c3126ea5f97434Tim Northover
82087773c318fcee853fb34a80a10c4347d523bdafbTim Northovertemplate <A64SE::ShiftExtSpecifiers Ext, bool IsHalf>
82187773c318fcee853fb34a80a10c4347d523bdafbTim Northoverstatic DecodeStatus
82287773c318fcee853fb34a80a10c4347d523bdafbTim NorthoverDecodeNeonMovImmShiftOperand(llvm::MCInst &Inst, unsigned ShiftAmount,
82387773c318fcee853fb34a80a10c4347d523bdafbTim Northover                             uint64_t Address, const void *Decoder) {
82487773c318fcee853fb34a80a10c4347d523bdafbTim Northover  bool IsLSL = false;
82587773c318fcee853fb34a80a10c4347d523bdafbTim Northover  if (Ext == A64SE::LSL)
82687773c318fcee853fb34a80a10c4347d523bdafbTim Northover    IsLSL = true;
82787773c318fcee853fb34a80a10c4347d523bdafbTim Northover  else if (Ext != A64SE::MSL)
82887773c318fcee853fb34a80a10c4347d523bdafbTim Northover    return MCDisassembler::Fail;
82987773c318fcee853fb34a80a10c4347d523bdafbTim Northover
83087773c318fcee853fb34a80a10c4347d523bdafbTim Northover  // MSL and LSLH accepts encoded shift amount 0 or 1.
83187773c318fcee853fb34a80a10c4347d523bdafbTim Northover  if ((!IsLSL || (IsLSL && IsHalf)) && ShiftAmount != 0 && ShiftAmount != 1)
83287773c318fcee853fb34a80a10c4347d523bdafbTim Northover    return MCDisassembler::Fail;
83387773c318fcee853fb34a80a10c4347d523bdafbTim Northover
83487773c318fcee853fb34a80a10c4347d523bdafbTim Northover  // LSL  accepts encoded shift amount 0, 1, 2 or 3.
83587773c318fcee853fb34a80a10c4347d523bdafbTim Northover  if (IsLSL && ShiftAmount > 3)
83687773c318fcee853fb34a80a10c4347d523bdafbTim Northover    return MCDisassembler::Fail;
83772062f5744557e270a38192554c3126ea5f97434Tim Northover
83887773c318fcee853fb34a80a10c4347d523bdafbTim Northover  Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
83987773c318fcee853fb34a80a10c4347d523bdafbTim Northover  return MCDisassembler::Success;
84087773c318fcee853fb34a80a10c4347d523bdafbTim Northover}
841