//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "sparc-disassembler"
-
#include "Sparc.h"
#include "SparcRegisterInfo.h"
#include "SparcSubtarget.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCFixedLenDisassembler.h"
-#include "llvm/Support/MemoryObject.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
+#define DEBUG_TYPE "sparc-disassembler"
+
typedef MCDisassembler::DecodeStatus DecodeStatus;
namespace {
-/// SparcDisassembler - a disassembler class for Sparc.
+/// A disassembler class for Sparc.
class SparcDisassembler : public MCDisassembler {
public:
- /// Constructor - Initializes the disassembler.
- ///
- SparcDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) :
- MCDisassembler(STI), RegInfo(Info)
- {}
+ SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
+ : MCDisassembler(STI, Ctx) {}
virtual ~SparcDisassembler() {}
- const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
-
- /// getInstruction - See MCDisassembler.
- virtual DecodeStatus getInstruction(MCInst &instr,
- uint64_t &size,
- const MemoryObject ®ion,
- uint64_t address,
- raw_ostream &vStream,
- raw_ostream &cStream) const;
-private:
- OwningPtr<const MCRegisterInfo> RegInfo;
+ DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
+ ArrayRef<uint8_t> Bytes, uint64_t Address,
+ raw_ostream &VStream,
+ raw_ostream &CStream) const override;
};
-
}
namespace llvm {
- extern Target TheSparcTarget, TheSparcV9Target;
+extern Target TheSparcTarget, TheSparcV9Target, TheSparcelTarget;
}
-static MCDisassembler *createSparcDisassembler(
- const Target &T,
- const MCSubtargetInfo &STI) {
- return new SparcDisassembler(STI, T.createMCRegInfo(""));
+static MCDisassembler *createSparcDisassembler(const Target &T,
+ const MCSubtargetInfo &STI,
+ MCContext &Ctx) {
+ return new SparcDisassembler(STI, Ctx);
}
createSparcDisassembler);
TargetRegistry::RegisterMCDisassembler(TheSparcV9Target,
createSparcDisassembler);
+ TargetRegistry::RegisterMCDisassembler(TheSparcelTarget,
+ createSparcDisassembler);
}
-
-
static const unsigned IntRegDecoderTable[] = {
SP::G0, SP::G1, SP::G2, SP::G3,
SP::G4, SP::G5, SP::G6, SP::G7,
if (RegNo > 31)
return MCDisassembler::Fail;
unsigned Reg = IntRegDecoderTable[RegNo];
- Inst.addOperand(MCOperand::CreateReg(Reg));
+ Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
if (RegNo > 31)
return MCDisassembler::Fail;
unsigned Reg = IntRegDecoderTable[RegNo];
- Inst.addOperand(MCOperand::CreateReg(Reg));
+ Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
if (RegNo > 31)
return MCDisassembler::Fail;
unsigned Reg = FPRegDecoderTable[RegNo];
- Inst.addOperand(MCOperand::CreateReg(Reg));
+ Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
if (RegNo > 31)
return MCDisassembler::Fail;
unsigned Reg = DFPRegDecoderTable[RegNo];
- Inst.addOperand(MCOperand::CreateReg(Reg));
+ Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
unsigned Reg = QFPRegDecoderTable[RegNo];
if (Reg == ~0U)
return MCDisassembler::Fail;
- Inst.addOperand(MCOperand::CreateReg(Reg));
+ Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
const void *Decoder) {
if (RegNo > 3)
return MCDisassembler::Fail;
- Inst.addOperand(MCOperand::CreateReg(FCCRegDecoderTable[RegNo]));
+ Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo]));
return MCDisassembler::Success;
}
const void *Decoder);
static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address,
+ const void *Decoder);
#include "SparcGenDisassemblerTables.inc"
-/// readInstruction - read four bytes from the MemoryObject
-/// and return 32 bit word.
-static DecodeStatus readInstruction32(const MemoryObject ®ion,
- uint64_t address,
- uint64_t &size,
- uint32_t &insn) {
- uint8_t Bytes[4];
-
+/// Read four bytes from the ArrayRef and return 32 bit word.
+static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
+ uint64_t &Size, uint32_t &Insn,
+ bool IsLittleEndian) {
// We want to read exactly 4 Bytes of data.
- if (region.readBytes(address, 4, Bytes) == -1) {
- size = 0;
+ if (Bytes.size() < 4) {
+ Size = 0;
return MCDisassembler::Fail;
}
- // Encoded as a big-endian 32-bit word in the stream.
- insn = (Bytes[3] << 0) |
- (Bytes[2] << 8) |
- (Bytes[1] << 16) |
- (Bytes[0] << 24);
+ Insn = IsLittleEndian
+ ? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
+ (Bytes[3] << 24)
+ : (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) |
+ (Bytes[0] << 24);
return MCDisassembler::Success;
}
-
-DecodeStatus
-SparcDisassembler::getInstruction(MCInst &instr,
- uint64_t &Size,
- const MemoryObject &Region,
- uint64_t Address,
- raw_ostream &vStream,
- raw_ostream &cStream) const {
+DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
+ ArrayRef<uint8_t> Bytes,
+ uint64_t Address,
+ raw_ostream &VStream,
+ raw_ostream &CStream) const {
uint32_t Insn;
-
- DecodeStatus Result = readInstruction32(Region, Address, Size, Insn);
+ bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();
+ DecodeStatus Result =
+ readInstruction32(Bytes, Address, Size, Insn, isLittleEndian);
if (Result == MCDisassembler::Fail)
return MCDisassembler::Fail;
-
// Calling the auto-generated decoder function.
- Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address,
- this, STI);
+ Result =
+ decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
// Decode imm|rs2.
if (isImm)
- MI.addOperand(MCOperand::CreateImm(simm13));
+ MI.addOperand(MCOperand::createImm(simm13));
else {
status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
if (status != MCDisassembler::Success)
tgt <<= 2;
if (!tryAddingSymbolicOperand(tgt+Address, false, Address,
0, 30, MI, Decoder))
- MI.addOperand(MCOperand::CreateImm(tgt));
+ MI.addOperand(MCOperand::createImm(tgt));
return MCDisassembler::Success;
}
static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn,
uint64_t Address, const void *Decoder) {
unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
- MI.addOperand(MCOperand::CreateImm(tgt));
+ MI.addOperand(MCOperand::createImm(tgt));
return MCDisassembler::Success;
}
// Decode RS1 | SIMM13.
if (isImm)
- MI.addOperand(MCOperand::CreateImm(simm13));
+ MI.addOperand(MCOperand::createImm(simm13));
else {
status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
if (status != MCDisassembler::Success)
// Decode RS2 | SIMM13.
if (isImm)
- MI.addOperand(MCOperand::CreateImm(simm13));
+ MI.addOperand(MCOperand::createImm(simm13));
+ else {
+ status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
+ if (status != MCDisassembler::Success)
+ return status;
+ }
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address,
+ const void *Decoder) {
+
+ unsigned rd = fieldFromInstruction(insn, 25, 5);
+ unsigned rs1 = fieldFromInstruction(insn, 14, 5);
+ unsigned isImm = fieldFromInstruction(insn, 13, 1);
+ unsigned rs2 = 0;
+ unsigned simm13 = 0;
+ if (isImm)
+ simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
+ else
+ rs2 = fieldFromInstruction(insn, 0, 5);
+
+ // Decode RD.
+ DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
+ if (status != MCDisassembler::Success)
+ return status;
+
+ // Decode RS1.
+ status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
+ if (status != MCDisassembler::Success)
+ return status;
+
+ // Decode RS1 | SIMM13.
+ if (isImm)
+ MI.addOperand(MCOperand::createImm(simm13));
else {
status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
if (status != MCDisassembler::Success)