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