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 ®ion, 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