1262261Sdim//===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===// 2262261Sdim// 3262261Sdim// The LLVM Compiler Infrastructure 4262261Sdim// 5262261Sdim// This file is distributed under the University of Illinois Open Source 6262261Sdim// License. See LICENSE.TXT for details. 7262261Sdim// 8262261Sdim//===----------------------------------------------------------------------===// 9262261Sdim// 10262261Sdim// This file is part of the Sparc Disassembler. 11262261Sdim// 12262261Sdim//===----------------------------------------------------------------------===// 13262261Sdim 14262261Sdim#define DEBUG_TYPE "sparc-disassembler" 15262261Sdim 16262261Sdim#include "Sparc.h" 17262261Sdim#include "SparcRegisterInfo.h" 18262261Sdim#include "SparcSubtarget.h" 19262261Sdim#include "llvm/MC/MCDisassembler.h" 20262261Sdim#include "llvm/MC/MCFixedLenDisassembler.h" 21262261Sdim#include "llvm/Support/MemoryObject.h" 22262261Sdim#include "llvm/Support/TargetRegistry.h" 23262261Sdim 24262261Sdimusing namespace llvm; 25262261Sdim 26262261Sdimtypedef MCDisassembler::DecodeStatus DecodeStatus; 27262261Sdim 28262261Sdimnamespace { 29262261Sdim 30262261Sdim/// SparcDisassembler - a disassembler class for Sparc. 31262261Sdimclass SparcDisassembler : public MCDisassembler { 32262261Sdimpublic: 33262261Sdim /// Constructor - Initializes the disassembler. 34262261Sdim /// 35262261Sdim SparcDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) : 36262261Sdim MCDisassembler(STI), RegInfo(Info) 37262261Sdim {} 38262261Sdim virtual ~SparcDisassembler() {} 39262261Sdim 40262261Sdim const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } 41262261Sdim 42262261Sdim /// getInstruction - See MCDisassembler. 43262261Sdim virtual DecodeStatus getInstruction(MCInst &instr, 44262261Sdim uint64_t &size, 45262261Sdim const MemoryObject ®ion, 46262261Sdim uint64_t address, 47262261Sdim raw_ostream &vStream, 48262261Sdim raw_ostream &cStream) const; 49262261Sdimprivate: 50262261Sdim OwningPtr<const MCRegisterInfo> RegInfo; 51262261Sdim}; 52262261Sdim 53262261Sdim} 54262261Sdim 55262261Sdimnamespace llvm { 56262261Sdim extern Target TheSparcTarget, TheSparcV9Target; 57262261Sdim} 58262261Sdim 59262261Sdimstatic MCDisassembler *createSparcDisassembler( 60262261Sdim const Target &T, 61262261Sdim const MCSubtargetInfo &STI) { 62262261Sdim return new SparcDisassembler(STI, T.createMCRegInfo("")); 63262261Sdim} 64262261Sdim 65262261Sdim 66262261Sdimextern "C" void LLVMInitializeSparcDisassembler() { 67262261Sdim // Register the disassembler. 68262261Sdim TargetRegistry::RegisterMCDisassembler(TheSparcTarget, 69262261Sdim createSparcDisassembler); 70262261Sdim TargetRegistry::RegisterMCDisassembler(TheSparcV9Target, 71262261Sdim createSparcDisassembler); 72262261Sdim} 73262261Sdim 74262261Sdim 75262261Sdim 76262261Sdimstatic const unsigned IntRegDecoderTable[] = { 77262261Sdim SP::G0, SP::G1, SP::G2, SP::G3, 78262261Sdim SP::G4, SP::G5, SP::G6, SP::G7, 79262261Sdim SP::O0, SP::O1, SP::O2, SP::O3, 80262261Sdim SP::O4, SP::O5, SP::O6, SP::O7, 81262261Sdim SP::L0, SP::L1, SP::L2, SP::L3, 82262261Sdim SP::L4, SP::L5, SP::L6, SP::L7, 83262261Sdim SP::I0, SP::I1, SP::I2, SP::I3, 84262261Sdim SP::I4, SP::I5, SP::I6, SP::I7 }; 85262261Sdim 86262261Sdimstatic const unsigned FPRegDecoderTable[] = { 87262261Sdim SP::F0, SP::F1, SP::F2, SP::F3, 88262261Sdim SP::F4, SP::F5, SP::F6, SP::F7, 89262261Sdim SP::F8, SP::F9, SP::F10, SP::F11, 90262261Sdim SP::F12, SP::F13, SP::F14, SP::F15, 91262261Sdim SP::F16, SP::F17, SP::F18, SP::F19, 92262261Sdim SP::F20, SP::F21, SP::F22, SP::F23, 93262261Sdim SP::F24, SP::F25, SP::F26, SP::F27, 94262261Sdim SP::F28, SP::F29, SP::F30, SP::F31 }; 95262261Sdim 96262261Sdimstatic const unsigned DFPRegDecoderTable[] = { 97262261Sdim SP::D0, SP::D16, SP::D1, SP::D17, 98262261Sdim SP::D2, SP::D18, SP::D3, SP::D19, 99262261Sdim SP::D4, SP::D20, SP::D5, SP::D21, 100262261Sdim SP::D6, SP::D22, SP::D7, SP::D23, 101262261Sdim SP::D8, SP::D24, SP::D9, SP::D25, 102262261Sdim SP::D10, SP::D26, SP::D11, SP::D27, 103262261Sdim SP::D12, SP::D28, SP::D13, SP::D29, 104262261Sdim SP::D14, SP::D30, SP::D15, SP::D31 }; 105262261Sdim 106262261Sdimstatic const unsigned QFPRegDecoderTable[] = { 107262261Sdim SP::Q0, SP::Q8, ~0U, ~0U, 108262261Sdim SP::Q1, SP::Q9, ~0U, ~0U, 109262261Sdim SP::Q2, SP::Q10, ~0U, ~0U, 110262261Sdim SP::Q3, SP::Q11, ~0U, ~0U, 111262261Sdim SP::Q4, SP::Q12, ~0U, ~0U, 112262261Sdim SP::Q5, SP::Q13, ~0U, ~0U, 113262261Sdim SP::Q6, SP::Q14, ~0U, ~0U, 114262261Sdim SP::Q7, SP::Q15, ~0U, ~0U } ; 115262261Sdim 116262261Sdimstatic DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, 117262261Sdim unsigned RegNo, 118262261Sdim uint64_t Address, 119262261Sdim const void *Decoder) { 120262261Sdim if (RegNo > 31) 121262261Sdim return MCDisassembler::Fail; 122262261Sdim unsigned Reg = IntRegDecoderTable[RegNo]; 123262261Sdim Inst.addOperand(MCOperand::CreateReg(Reg)); 124262261Sdim return MCDisassembler::Success; 125262261Sdim} 126262261Sdim 127262261Sdimstatic DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, 128262261Sdim unsigned RegNo, 129262261Sdim uint64_t Address, 130262261Sdim const void *Decoder) { 131262261Sdim if (RegNo > 31) 132262261Sdim return MCDisassembler::Fail; 133262261Sdim unsigned Reg = IntRegDecoderTable[RegNo]; 134262261Sdim Inst.addOperand(MCOperand::CreateReg(Reg)); 135262261Sdim return MCDisassembler::Success; 136262261Sdim} 137262261Sdim 138262261Sdim 139262261Sdimstatic DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, 140262261Sdim unsigned RegNo, 141262261Sdim uint64_t Address, 142262261Sdim const void *Decoder) { 143262261Sdim if (RegNo > 31) 144262261Sdim return MCDisassembler::Fail; 145262261Sdim unsigned Reg = FPRegDecoderTable[RegNo]; 146262261Sdim Inst.addOperand(MCOperand::CreateReg(Reg)); 147262261Sdim return MCDisassembler::Success; 148262261Sdim} 149262261Sdim 150262261Sdim 151262261Sdimstatic DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, 152262261Sdim unsigned RegNo, 153262261Sdim uint64_t Address, 154262261Sdim const void *Decoder) { 155262261Sdim if (RegNo > 31) 156262261Sdim return MCDisassembler::Fail; 157262261Sdim unsigned Reg = DFPRegDecoderTable[RegNo]; 158262261Sdim Inst.addOperand(MCOperand::CreateReg(Reg)); 159262261Sdim return MCDisassembler::Success; 160262261Sdim} 161262261Sdim 162262261Sdim 163262261Sdimstatic DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, 164262261Sdim unsigned RegNo, 165262261Sdim uint64_t Address, 166262261Sdim const void *Decoder) { 167262261Sdim if (RegNo > 31) 168262261Sdim return MCDisassembler::Fail; 169262261Sdim 170262261Sdim unsigned Reg = QFPRegDecoderTable[RegNo]; 171262261Sdim if (Reg == ~0U) 172262261Sdim return MCDisassembler::Fail; 173262261Sdim Inst.addOperand(MCOperand::CreateReg(Reg)); 174262261Sdim return MCDisassembler::Success; 175262261Sdim} 176262261Sdim 177262261Sdim 178262261Sdim#include "SparcGenDisassemblerTables.inc" 179262261Sdim 180262261Sdim/// readInstruction - read four bytes from the MemoryObject 181262261Sdim/// and return 32 bit word. 182262261Sdimstatic DecodeStatus readInstruction32(const MemoryObject ®ion, 183262261Sdim uint64_t address, 184262261Sdim uint64_t &size, 185262261Sdim uint32_t &insn) { 186262261Sdim uint8_t Bytes[4]; 187262261Sdim 188262261Sdim // We want to read exactly 4 Bytes of data. 189262261Sdim if (region.readBytes(address, 4, Bytes) == -1) { 190262261Sdim size = 0; 191262261Sdim return MCDisassembler::Fail; 192262261Sdim } 193262261Sdim 194262261Sdim // Encoded as a big-endian 32-bit word in the stream. 195262261Sdim insn = (Bytes[3] << 0) | 196262261Sdim (Bytes[2] << 8) | 197262261Sdim (Bytes[1] << 16) | 198262261Sdim (Bytes[0] << 24); 199262261Sdim 200262261Sdim return MCDisassembler::Success; 201262261Sdim} 202262261Sdim 203262261Sdim 204262261SdimDecodeStatus 205262261SdimSparcDisassembler::getInstruction(MCInst &instr, 206262261Sdim uint64_t &Size, 207262261Sdim const MemoryObject &Region, 208262261Sdim uint64_t Address, 209262261Sdim raw_ostream &vStream, 210262261Sdim raw_ostream &cStream) const { 211262261Sdim uint32_t Insn; 212262261Sdim 213262261Sdim DecodeStatus Result = readInstruction32(Region, Address, Size, Insn); 214262261Sdim if (Result == MCDisassembler::Fail) 215262261Sdim return MCDisassembler::Fail; 216262261Sdim 217262261Sdim 218262261Sdim // Calling the auto-generated decoder function. 219262261Sdim Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address, 220262261Sdim this, STI); 221262261Sdim 222262261Sdim if (Result != MCDisassembler::Fail) { 223262261Sdim Size = 4; 224262261Sdim return Result; 225262261Sdim } 226262261Sdim 227262261Sdim return MCDisassembler::Fail; 228262261Sdim} 229