10b57cec5SDimitry Andric //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "MCTargetDesc/SystemZMCTargetDesc.h" 100b57cec5SDimitry Andric #include "SystemZ.h" 110b57cec5SDimitry Andric #include "TargetInfo/SystemZTargetInfo.h" 1281ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h" 130b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h" 140b57cec5SDimitry Andric #include "llvm/MC/MCInst.h" 150b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 16349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 170b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 180b57cec5SDimitry Andric #include <cassert> 190b57cec5SDimitry Andric #include <cstdint> 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric using namespace llvm; 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric #define DEBUG_TYPE "systemz-disassembler" 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus; 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric namespace { 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric class SystemZDisassembler : public MCDisassembler { 300b57cec5SDimitry Andric public: 310b57cec5SDimitry Andric SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 320b57cec5SDimitry Andric : MCDisassembler(STI, Ctx) {} 330b57cec5SDimitry Andric ~SystemZDisassembler() override = default; 340b57cec5SDimitry Andric 35*5f757f3fSDimitry Andric DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 360b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address, 370b57cec5SDimitry Andric raw_ostream &CStream) const override; 380b57cec5SDimitry Andric }; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric } // end anonymous namespace 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric static MCDisassembler *createSystemZDisassembler(const Target &T, 430b57cec5SDimitry Andric const MCSubtargetInfo &STI, 440b57cec5SDimitry Andric MCContext &Ctx) { 450b57cec5SDimitry Andric return new SystemZDisassembler(STI, Ctx); 460b57cec5SDimitry Andric } 470b57cec5SDimitry Andric 48*5f757f3fSDimitry Andric // NOLINTNEXTLINE(readability-identifier-naming) 49480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZDisassembler() { 500b57cec5SDimitry Andric // Register the disassembler. 510b57cec5SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheSystemZTarget(), 520b57cec5SDimitry Andric createSystemZDisassembler); 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the 560b57cec5SDimitry Andric /// immediate Value in the MCInst. 570b57cec5SDimitry Andric /// 580b57cec5SDimitry Andric /// @param Value - The immediate Value, has had any PC adjustment made by 590b57cec5SDimitry Andric /// the caller. 600b57cec5SDimitry Andric /// @param isBranch - If the instruction is a branch instruction 610b57cec5SDimitry Andric /// @param Address - The starting address of the instruction 620b57cec5SDimitry Andric /// @param Offset - The byte offset to this immediate in the instruction 630b57cec5SDimitry Andric /// @param Width - The byte width of this immediate in the instruction 640b57cec5SDimitry Andric /// 650b57cec5SDimitry Andric /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was 660b57cec5SDimitry Andric /// called then that function is called to get any symbolic information for the 670b57cec5SDimitry Andric /// immediate in the instruction using the Address, Offset and Width. If that 680b57cec5SDimitry Andric /// returns non-zero then the symbolic information it returns is used to create 690b57cec5SDimitry Andric /// an MCExpr and that is added as an operand to the MCInst. If getOpInfo() 700b57cec5SDimitry Andric /// returns zero and isBranch is true then a symbol look up for immediate Value 710b57cec5SDimitry Andric /// is done and if a symbol is found an MCExpr is created with that, else 720b57cec5SDimitry Andric /// an MCExpr with the immediate Value is created. This function returns true 730b57cec5SDimitry Andric /// if it adds an operand to the MCInst and false otherwise. 74*5f757f3fSDimitry Andric static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch, 750b57cec5SDimitry Andric uint64_t Address, uint64_t Offset, 760b57cec5SDimitry Andric uint64_t Width, MCInst &MI, 7781ad6265SDimitry Andric const MCDisassembler *Decoder) { 78*5f757f3fSDimitry Andric return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset, 7981ad6265SDimitry Andric Width, /*InstSize=*/0); 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 8306c3fb27SDimitry Andric const unsigned *Regs, unsigned Size, 8406c3fb27SDimitry Andric bool IsAddr = false) { 850b57cec5SDimitry Andric assert(RegNo < Size && "Invalid register"); 8606c3fb27SDimitry Andric if (IsAddr && RegNo == 0) { 8706c3fb27SDimitry Andric RegNo = SystemZ::NoRegister; 8806c3fb27SDimitry Andric } else { 890b57cec5SDimitry Andric RegNo = Regs[RegNo]; 900b57cec5SDimitry Andric if (RegNo == 0) 910b57cec5SDimitry Andric return MCDisassembler::Fail; 9206c3fb27SDimitry Andric } 930b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(RegNo)); 940b57cec5SDimitry Andric return MCDisassembler::Success; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 980b57cec5SDimitry Andric uint64_t Address, 9981ad6265SDimitry Andric const MCDisassembler *Decoder) { 1000b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16); 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 1040b57cec5SDimitry Andric uint64_t Address, 10581ad6265SDimitry Andric const MCDisassembler *Decoder) { 1060b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16); 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 1100b57cec5SDimitry Andric uint64_t Address, 11181ad6265SDimitry Andric const MCDisassembler *Decoder) { 1120b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 1160b57cec5SDimitry Andric uint64_t Address, 11781ad6265SDimitry Andric const MCDisassembler *Decoder) { 1180b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16); 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 12181ad6265SDimitry Andric static DecodeStatus 12206c3fb27SDimitry Andric DecodeADDR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, 12306c3fb27SDimitry Andric const MCDisassembler *Decoder) { 12406c3fb27SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16, true); 12506c3fb27SDimitry Andric } 12606c3fb27SDimitry Andric 12706c3fb27SDimitry Andric static DecodeStatus 12881ad6265SDimitry Andric DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, 12981ad6265SDimitry Andric const MCDisassembler *Decoder) { 13006c3fb27SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16, true); 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 1340b57cec5SDimitry Andric uint64_t Address, 13581ad6265SDimitry Andric const MCDisassembler *Decoder) { 1360b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16); 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 1400b57cec5SDimitry Andric uint64_t Address, 14181ad6265SDimitry Andric const MCDisassembler *Decoder) { 1420b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16); 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 1460b57cec5SDimitry Andric uint64_t Address, 14781ad6265SDimitry Andric const MCDisassembler *Decoder) { 1480b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16); 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 1520b57cec5SDimitry Andric uint64_t Address, 15381ad6265SDimitry Andric const MCDisassembler *Decoder) { 1540b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32); 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 1580b57cec5SDimitry Andric uint64_t Address, 15981ad6265SDimitry Andric const MCDisassembler *Decoder) { 1600b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32); 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 1640b57cec5SDimitry Andric uint64_t Address, 16581ad6265SDimitry Andric const MCDisassembler *Decoder) { 1660b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32); 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 1700b57cec5SDimitry Andric uint64_t Address, 17181ad6265SDimitry Andric const MCDisassembler *Decoder) { 1720b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16); 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric static DecodeStatus DecodeCR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 1760b57cec5SDimitry Andric uint64_t Address, 17781ad6265SDimitry Andric const MCDisassembler *Decoder) { 1780b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16); 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric template<unsigned N> 1820b57cec5SDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) { 1830b57cec5SDimitry Andric if (!isUInt<N>(Imm)) 1840b57cec5SDimitry Andric return MCDisassembler::Fail; 1850b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm)); 1860b57cec5SDimitry Andric return MCDisassembler::Success; 1870b57cec5SDimitry Andric } 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric template<unsigned N> 1900b57cec5SDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) { 1910b57cec5SDimitry Andric if (!isUInt<N>(Imm)) 1920b57cec5SDimitry Andric return MCDisassembler::Fail; 1930b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 1940b57cec5SDimitry Andric return MCDisassembler::Success; 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm, 19881ad6265SDimitry Andric uint64_t Address, 19981ad6265SDimitry Andric const MCDisassembler *Decoder) { 2000b57cec5SDimitry Andric return decodeUImmOperand<1>(Inst, Imm); 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm, 20481ad6265SDimitry Andric uint64_t Address, 20581ad6265SDimitry Andric const MCDisassembler *Decoder) { 2060b57cec5SDimitry Andric return decodeUImmOperand<2>(Inst, Imm); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm, 21081ad6265SDimitry Andric uint64_t Address, 21181ad6265SDimitry Andric const MCDisassembler *Decoder) { 2120b57cec5SDimitry Andric return decodeUImmOperand<3>(Inst, Imm); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, 21681ad6265SDimitry Andric uint64_t Address, 21781ad6265SDimitry Andric const MCDisassembler *Decoder) { 2180b57cec5SDimitry Andric return decodeUImmOperand<4>(Inst, Imm); 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, 22281ad6265SDimitry Andric uint64_t Address, 22381ad6265SDimitry Andric const MCDisassembler *Decoder) { 2240b57cec5SDimitry Andric return decodeUImmOperand<8>(Inst, Imm); 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm, 22881ad6265SDimitry Andric uint64_t Address, 22981ad6265SDimitry Andric const MCDisassembler *Decoder) { 2300b57cec5SDimitry Andric return decodeUImmOperand<12>(Inst, Imm); 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, 23481ad6265SDimitry Andric uint64_t Address, 23581ad6265SDimitry Andric const MCDisassembler *Decoder) { 2360b57cec5SDimitry Andric return decodeUImmOperand<16>(Inst, Imm); 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, 24081ad6265SDimitry Andric uint64_t Address, 24181ad6265SDimitry Andric const MCDisassembler *Decoder) { 2420b57cec5SDimitry Andric return decodeUImmOperand<32>(Inst, Imm); 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, 24681ad6265SDimitry Andric uint64_t Address, 24781ad6265SDimitry Andric const MCDisassembler *Decoder) { 2480b57cec5SDimitry Andric return decodeSImmOperand<8>(Inst, Imm); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, 25281ad6265SDimitry Andric uint64_t Address, 25381ad6265SDimitry Andric const MCDisassembler *Decoder) { 2540b57cec5SDimitry Andric return decodeSImmOperand<16>(Inst, Imm); 2550b57cec5SDimitry Andric } 2560b57cec5SDimitry Andric 25706c3fb27SDimitry Andric static DecodeStatus decodeS20ImmOperand(MCInst &Inst, uint64_t Imm, 25806c3fb27SDimitry Andric uint64_t Address, 25906c3fb27SDimitry Andric const MCDisassembler *Decoder) { 26006c3fb27SDimitry Andric return decodeSImmOperand<20>(Inst, Imm); 26106c3fb27SDimitry Andric } 26206c3fb27SDimitry Andric 2630b57cec5SDimitry Andric static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, 26481ad6265SDimitry Andric uint64_t Address, 26581ad6265SDimitry Andric const MCDisassembler *Decoder) { 2660b57cec5SDimitry Andric return decodeSImmOperand<32>(Inst, Imm); 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric template <unsigned N> 27006c3fb27SDimitry Andric static DecodeStatus decodeLenOperand(MCInst &Inst, uint64_t Imm, 27106c3fb27SDimitry Andric uint64_t Address, 27206c3fb27SDimitry Andric const MCDisassembler *Decoder) { 27306c3fb27SDimitry Andric if (!isUInt<N>(Imm)) 27406c3fb27SDimitry Andric return MCDisassembler::Fail; 27506c3fb27SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm + 1)); 27606c3fb27SDimitry Andric return MCDisassembler::Success; 27706c3fb27SDimitry Andric } 27806c3fb27SDimitry Andric 27906c3fb27SDimitry Andric template <unsigned N> 2800b57cec5SDimitry Andric static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, 28181ad6265SDimitry Andric uint64_t Address, bool isBranch, 28281ad6265SDimitry Andric const MCDisassembler *Decoder) { 2830b57cec5SDimitry Andric assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); 2840b57cec5SDimitry Andric uint64_t Value = SignExtend64<N>(Imm) * 2 + Address; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8, 2870b57cec5SDimitry Andric Inst, Decoder)) 2880b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Value)); 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric return MCDisassembler::Success; 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm, 2940b57cec5SDimitry Andric uint64_t Address, 29581ad6265SDimitry Andric const MCDisassembler *Decoder) { 2960b57cec5SDimitry Andric return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder); 2970b57cec5SDimitry Andric } 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm, 3000b57cec5SDimitry Andric uint64_t Address, 30181ad6265SDimitry Andric const MCDisassembler *Decoder) { 3020b57cec5SDimitry Andric return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder); 3030b57cec5SDimitry Andric } 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm, 3060b57cec5SDimitry Andric uint64_t Address, 30781ad6265SDimitry Andric const MCDisassembler *Decoder) { 3080b57cec5SDimitry Andric return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder); 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm, 3120b57cec5SDimitry Andric uint64_t Address, 31381ad6265SDimitry Andric const MCDisassembler *Decoder) { 3140b57cec5SDimitry Andric return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder); 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, 3180b57cec5SDimitry Andric uint64_t Address, 31981ad6265SDimitry Andric const MCDisassembler *Decoder) { 3200b57cec5SDimitry Andric return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder); 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric #include "SystemZGenDisassemblerTables.inc" 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 3260b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes, 3270b57cec5SDimitry Andric uint64_t Address, 3280b57cec5SDimitry Andric raw_ostream &CS) const { 3290b57cec5SDimitry Andric // Get the first two bytes of the instruction. 3300b57cec5SDimitry Andric Size = 0; 3310b57cec5SDimitry Andric if (Bytes.size() < 2) 3320b57cec5SDimitry Andric return MCDisassembler::Fail; 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric // The top 2 bits of the first byte specify the size. 3350b57cec5SDimitry Andric const uint8_t *Table; 3360b57cec5SDimitry Andric if (Bytes[0] < 0x40) { 3370b57cec5SDimitry Andric Size = 2; 3380b57cec5SDimitry Andric Table = DecoderTable16; 3390b57cec5SDimitry Andric } else if (Bytes[0] < 0xc0) { 3400b57cec5SDimitry Andric Size = 4; 3410b57cec5SDimitry Andric Table = DecoderTable32; 3420b57cec5SDimitry Andric } else { 3430b57cec5SDimitry Andric Size = 6; 3440b57cec5SDimitry Andric Table = DecoderTable48; 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric // Read any remaining bytes. 348e8d8bef9SDimitry Andric if (Bytes.size() < Size) { 349e8d8bef9SDimitry Andric Size = Bytes.size(); 3500b57cec5SDimitry Andric return MCDisassembler::Fail; 351e8d8bef9SDimitry Andric } 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric // Construct the instruction. 3540b57cec5SDimitry Andric uint64_t Inst = 0; 3550b57cec5SDimitry Andric for (uint64_t I = 0; I < Size; ++I) 3560b57cec5SDimitry Andric Inst = (Inst << 8) | Bytes[I]; 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric return decodeInstruction(Table, MI, Inst, Address, this, STI); 3590b57cec5SDimitry Andric } 360