diff options
Diffstat (limited to 'lib/Target/Sparc/Disassembler/SparcDisassembler.cpp')
| -rw-r--r-- | lib/Target/Sparc/Disassembler/SparcDisassembler.cpp | 88 | 
1 files changed, 61 insertions, 27 deletions
| diff --git a/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index 8bc4ca981614b..3e56b9e9b8837 100644 --- a/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -16,6 +16,9 @@  #include "SparcSubtarget.h"  #include "llvm/MC/MCDisassembler.h"  #include "llvm/MC/MCFixedLenDisassembler.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCAsmInfo.h"  #include "llvm/Support/TargetRegistry.h"  using namespace llvm; @@ -38,17 +41,15 @@ public:                                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, -                       MCContext &Ctx) { +static MCDisassembler *createSparcDisassembler(const Target &T, +                                               const MCSubtargetInfo &STI, +                                               MCContext &Ctx) {    return new SparcDisassembler(STI, Ctx);  } @@ -59,10 +60,10 @@ extern "C" void LLVMInitializeSparcDisassembler() {                                           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, @@ -106,6 +107,16 @@ static const unsigned QFPRegDecoderTable[] = {  static const unsigned FCCRegDecoderTable[] = {    SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 }; +static const unsigned ASRRegDecoderTable[] = { +  SP::Y,     SP::ASR1,  SP::ASR2,  SP::ASR3, +  SP::ASR4,  SP::ASR5,  SP::ASR6,  SP::ASR7, +  SP::ASR8,  SP::ASR9,  SP::ASR10, SP::ASR11, +  SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15, +  SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19, +  SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23, +  SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27, +  SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31}; +  static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,                                                 unsigned RegNo,                                                 uint64_t Address, @@ -113,7 +124,7 @@ static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,    if (RegNo > 31)      return MCDisassembler::Fail;    unsigned Reg = IntRegDecoderTable[RegNo]; -  Inst.addOperand(MCOperand::CreateReg(Reg)); +  Inst.addOperand(MCOperand::createReg(Reg));    return MCDisassembler::Success;  } @@ -124,7 +135,7 @@ static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst,    if (RegNo > 31)      return MCDisassembler::Fail;    unsigned Reg = IntRegDecoderTable[RegNo]; -  Inst.addOperand(MCOperand::CreateReg(Reg)); +  Inst.addOperand(MCOperand::createReg(Reg));    return MCDisassembler::Success;  } @@ -136,7 +147,7 @@ static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst,    if (RegNo > 31)      return MCDisassembler::Fail;    unsigned Reg = FPRegDecoderTable[RegNo]; -  Inst.addOperand(MCOperand::CreateReg(Reg)); +  Inst.addOperand(MCOperand::createReg(Reg));    return MCDisassembler::Success;  } @@ -148,7 +159,7 @@ static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst,    if (RegNo > 31)      return MCDisassembler::Fail;    unsigned Reg = DFPRegDecoderTable[RegNo]; -  Inst.addOperand(MCOperand::CreateReg(Reg)); +  Inst.addOperand(MCOperand::createReg(Reg));    return MCDisassembler::Success;  } @@ -163,7 +174,7 @@ static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst,    unsigned Reg = QFPRegDecoderTable[RegNo];    if (Reg == ~0U)      return MCDisassembler::Fail; -  Inst.addOperand(MCOperand::CreateReg(Reg)); +  Inst.addOperand(MCOperand::createReg(Reg));    return MCDisassembler::Success;  } @@ -172,7 +183,16 @@ static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,                                                 const void *Decoder) {    if (RegNo > 3)      return MCDisassembler::Fail; -  Inst.addOperand(MCOperand::CreateReg(FCCRegDecoderTable[RegNo])); +  Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo])); +  return MCDisassembler::Success; +} + +static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo, +                                               uint64_t Address, +                                               const void *Decoder) { +  if (RegNo > 31) +    return MCDisassembler::Fail; +  Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo]));    return MCDisassembler::Success;  } @@ -208,16 +228,19 @@ static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address,  /// 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) { +                                      uint64_t &Size, uint32_t &Insn, +                                      bool IsLittleEndian) {    // We want to read exactly 4 Bytes of data.    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;  } @@ -228,12 +251,12 @@ DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,                                                 raw_ostream &VStream,                                                 raw_ostream &CStream) const {    uint32_t Insn; - -  DecodeStatus Result = readInstruction32(Bytes, 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); @@ -256,6 +279,8 @@ static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address,    unsigned rd = fieldFromInstruction(insn, 25, 5);    unsigned rs1 = fieldFromInstruction(insn, 14, 5);    bool isImm = fieldFromInstruction(insn, 13, 1); +  bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field) +  unsigned asi = fieldFromInstruction(insn, 5, 8);    unsigned rs2 = 0;    unsigned simm13 = 0;    if (isImm) @@ -277,13 +302,16 @@ static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address,    // 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)        return status;    } +  if (hasAsi) +    MI.addOperand(MCOperand::createImm(asi)); +    if (!isLoad) {      status = DecodeRD(MI, rd, Address, Decoder);      if (status != MCDisassembler::Success) @@ -355,14 +383,14 @@ static DecodeStatus DecodeCall(MCInst &MI, unsigned insn,    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;  } @@ -391,7 +419,7 @@ static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address,    // 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) @@ -419,7 +447,7 @@ static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,    // 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) @@ -434,6 +462,8 @@ static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address,    unsigned rd = fieldFromInstruction(insn, 25, 5);    unsigned rs1 = fieldFromInstruction(insn, 14, 5);    unsigned isImm = fieldFromInstruction(insn, 13, 1); +  bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field) +  unsigned asi = fieldFromInstruction(insn, 5, 8);    unsigned rs2 = 0;    unsigned simm13 = 0;    if (isImm) @@ -453,11 +483,15 @@ static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address,    // 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)        return status;    } + +  if (hasAsi) +    MI.addOperand(MCOperand::createImm(asi)); +    return MCDisassembler::Success;  } | 
