};
static unsigned getRD(uint32_t insn) {
+ if (!MBlazeRegisterInfo::isRegister((insn>>21)&0x1F))
+ return UNSUPPORTED;
return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>21)&0x1F);
}
static unsigned getRA(uint32_t insn) {
+ if (!MBlazeRegisterInfo::getRegisterFromNumbering((insn>>16)&0x1F))
+ return UNSUPPORTED;
return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>16)&0x1F);
}
static unsigned getRB(uint32_t insn) {
+ if (!MBlazeRegisterInfo::getRegisterFromNumbering((insn>>11)&0x1F))
+ return UNSUPPORTED;
return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>11)&0x1F);
}
static int64_t getRS(uint32_t insn) {
- int16_t val = (insn & 0x3FFF);
- return val;
+ if (!MBlazeRegisterInfo::isSpecialRegister(insn&0x3FFF))
+ return UNSUPPORTED;
+ return MBlazeRegisterInfo::getSpecialRegisterFromNumbering(insn&0x3FFF);
}
static int64_t getIMM(uint32_t insn) {
}
static unsigned decodeSEXT(uint32_t insn) {
- switch (getIMM(insn)) {
+ switch (insn&0x7FF) {
default: return UNSUPPORTED;
case 0x60: return MBlaze::SEXT8;
case 0x68: return MBlaze::WIC;
}
static unsigned decodeBEQ(uint32_t insn) {
- switch (getRD(insn)) {
+ switch ((insn>>21)&0x1F) {
default: return UNSUPPORTED;
case 0x00: return MBlaze::BEQ;
case 0x10: return MBlaze::BEQD;
}
static unsigned decodeBEQI(uint32_t insn) {
- switch (getRD(insn)) {
+ switch ((insn>>21)&0x1F) {
default: return UNSUPPORTED;
case 0x00: return MBlaze::BEQI;
case 0x10: return MBlaze::BEQID;
}
}
+static unsigned decodeLBU(uint32_t insn) {
+ switch ((insn>>9)&0x1) {
+ default: return UNSUPPORTED;
+ case 0x0: return MBlaze::LBU;
+ case 0x1: return MBlaze::LBUR;
+ }
+}
+
+static unsigned decodeLHU(uint32_t insn) {
+ switch ((insn>>9)&0x1) {
+ default: return UNSUPPORTED;
+ case 0x0: return MBlaze::LHU;
+ case 0x1: return MBlaze::LHUR;
+ }
+}
+
static unsigned decodeLW(uint32_t insn) {
switch ((insn>>9)&0x3) {
default: return UNSUPPORTED;
}
}
+static unsigned decodeSB(uint32_t insn) {
+ switch ((insn>>9)&0x1) {
+ default: return UNSUPPORTED;
+ case 0x0: return MBlaze::SB;
+ case 0x1: return MBlaze::SBR;
+ }
+}
+
+static unsigned decodeSH(uint32_t insn) {
+ switch ((insn>>9)&0x1) {
+ default: return UNSUPPORTED;
+ case 0x0: return MBlaze::SH;
+ case 0x1: return MBlaze::SHR;
+ }
+}
+
static unsigned decodeSW(uint32_t insn) {
switch ((insn>>9)&0x3) {
default: return UNSUPPORTED;
switch ((insn>>15)&0x1) {
default: return UNSUPPORTED;
case 0x0:
- switch ((insn>>16)&0x1F) {
+ switch ((insn>>16)&0x1) {
default: return UNSUPPORTED;
- case 0x22: return MBlaze::MSRCLR;
- case 0x20: return MBlaze::MSRSET;
+ case 0x0: return MBlaze::MSRSET;
+ case 0x1: return MBlaze::MSRCLR;
}
case 0x1:
switch ((insn>>14)&0x1) {
static unsigned decodeXOR(uint32_t insn) {
switch (getFLAGS(insn)) {
default: return UNSUPPORTED;
- case 0x000: return MBlaze::OR;
+ case 0x000: return MBlaze::XOR;
case 0x400: return MBlaze::PCMPEQ;
}
}
static unsigned decodeANDN(uint32_t insn) {
switch (getFLAGS(insn)) {
default: return UNSUPPORTED;
- case 0x000: return MBlaze::OR;
+ case 0x000: return MBlaze::ANDN;
case 0x400: return MBlaze::PCMPNE;
}
}
case MBlaze::GET: return decodeGET(insn);
case MBlaze::GETD: return decodeGETD(insn);
case MBlaze::IDIV: return decodeIDIV(insn);
+ case MBlaze::LBU: return decodeLBU(insn);
+ case MBlaze::LHU: return decodeLHU(insn);
case MBlaze::LW: return decodeLW(insn);
+ case MBlaze::SB: return decodeSB(insn);
+ case MBlaze::SH: return decodeSH(insn);
case MBlaze::SW: return decodeSW(insn);
case MBlaze::MFS: return decodeMFS(insn);
case MBlaze::OR: return decodeOR(insn);
raw_ostream &vStream) const {
// The machine instruction.
uint32_t insn;
+ uint64_t read;
uint8_t bytes[4];
-
+
+ // By default we consume 1 byte on failure
+ size = 1;
+
// We want to read exactly 4 bytes of data.
- if (region.readBytes(address, 4, (uint8_t*)bytes, NULL) == -1)
+ if (region.readBytes(address, 4, (uint8_t*)bytes, &read) == -1 || read < 4)
return false;
// Encoded as a big-endian 32-bit word in the stream.
instr.setOpcode(opcode);
+ unsigned RD = getRD(insn);
+ unsigned RA = getRA(insn);
+ unsigned RB = getRB(insn);
+ unsigned RS = getRS(insn);
+
uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
switch ((tsFlags & MBlazeII::FormMask)) {
- default: llvm_unreachable("unknown instruction encoding");
+ default:
+ return false;
+
+ case MBlazeII::FRRRR:
+ if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
+ instr.addOperand(MCOperand::CreateReg(RB));
+ instr.addOperand(MCOperand::CreateReg(RA));
+ break;
case MBlazeII::FRRR:
- instr.addOperand(MCOperand::CreateReg(getRD(insn)));
- instr.addOperand(MCOperand::CreateReg(getRA(insn)));
- instr.addOperand(MCOperand::CreateReg(getRB(insn)));
+ if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
+ instr.addOperand(MCOperand::CreateReg(RA));
+ instr.addOperand(MCOperand::CreateReg(RB));
+ break;
+
+ case MBlazeII::FRI:
+ switch (opcode) {
+ default:
+ return false;
+ case MBlaze::MFS:
+ if (RD == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
+ instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
+ break;
+ case MBlaze::MTS:
+ if (RA == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
+ instr.addOperand(MCOperand::CreateReg(RA));
+ break;
+ case MBlaze::MSRSET:
+ case MBlaze::MSRCLR:
+ if (RD == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
+ instr.addOperand(MCOperand::CreateImm(insn&0x7FFF));
+ break;
+ }
break;
case MBlazeII::FRRI:
- instr.addOperand(MCOperand::CreateReg(getRD(insn)));
- instr.addOperand(MCOperand::CreateReg(getRA(insn)));
- instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
+ if (RD == UNSUPPORTED || RA == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
+ instr.addOperand(MCOperand::CreateReg(RA));
+ switch (opcode) {
+ default:
+ instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
+ break;
+ case MBlaze::BSRLI:
+ case MBlaze::BSRAI:
+ case MBlaze::BSLLI:
+ instr.addOperand(MCOperand::CreateImm(insn&0x1F));
+ break;
+ }
break;
case MBlazeII::FCRR:
- instr.addOperand(MCOperand::CreateReg(getRA(insn)));
- instr.addOperand(MCOperand::CreateReg(getRB(insn)));
+ if (RA == UNSUPPORTED || RB == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RA));
+ instr.addOperand(MCOperand::CreateReg(RB));
break;
case MBlazeII::FCRI:
- instr.addOperand(MCOperand::CreateReg(getRA(insn)));
+ if (RA == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RA));
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
break;
case MBlazeII::FRCR:
- instr.addOperand(MCOperand::CreateReg(getRD(insn)));
- instr.addOperand(MCOperand::CreateReg(getRB(insn)));
+ if (RD == UNSUPPORTED || RB == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
+ instr.addOperand(MCOperand::CreateReg(RB));
break;
case MBlazeII::FRCI:
- instr.addOperand(MCOperand::CreateReg(getRD(insn)));
+ if (RD == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
break;
case MBlazeII::FCCR:
- instr.addOperand(MCOperand::CreateReg(getRB(insn)));
+ if (RB == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RB));
break;
case MBlazeII::FCCI:
break;
case MBlazeII::FRRCI:
- instr.addOperand(MCOperand::CreateReg(getRD(insn)));
- instr.addOperand(MCOperand::CreateReg(getRA(insn)));
+ if (RD == UNSUPPORTED || RA == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
+ instr.addOperand(MCOperand::CreateReg(RA));
instr.addOperand(MCOperand::CreateImm(getSHT(insn)));
break;
case MBlazeII::FRRC:
- instr.addOperand(MCOperand::CreateReg(getRD(insn)));
- instr.addOperand(MCOperand::CreateReg(getRA(insn)));
+ if (RD == UNSUPPORTED || RA == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
+ instr.addOperand(MCOperand::CreateReg(RA));
break;
case MBlazeII::FRCX:
- instr.addOperand(MCOperand::CreateReg(getRD(insn)));
+ if (RD == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
break;
case MBlazeII::FRCS:
- instr.addOperand(MCOperand::CreateReg(getRD(insn)));
- instr.addOperand(MCOperand::CreateImm(getRS(insn)));
+ if (RD == UNSUPPORTED || RS == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
+ instr.addOperand(MCOperand::CreateReg(RS));
break;
case MBlazeII::FCRCS:
- instr.addOperand(MCOperand::CreateReg(getRA(insn)));
- instr.addOperand(MCOperand::CreateImm(getRS(insn)));
+ if (RS == UNSUPPORTED || RA == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RS));
+ instr.addOperand(MCOperand::CreateReg(RA));
break;
case MBlazeII::FCRCX:
- instr.addOperand(MCOperand::CreateReg(getRA(insn)));
+ if (RA == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RA));
instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
break;
break;
case MBlazeII::FCR:
- instr.addOperand(MCOperand::CreateReg(getRB(insn)));
+ if (RB == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RB));
break;
case MBlazeII::FRIR:
- instr.addOperand(MCOperand::CreateReg(getRD(insn)));
+ if (RD == UNSUPPORTED || RA == UNSUPPORTED)
+ return false;
+ instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
- instr.addOperand(MCOperand::CreateReg(getRA(insn)));
+ instr.addOperand(MCOperand::CreateReg(RA));
break;
}
+ // We always consume 4 bytes of data on success
+ size = 4;
+
return true;
}
return new MBlazeDisassembler;
}
-extern "C" void LLVMInitializeMBlazeDisassembler() {
+extern "C" void LLVMInitializeMBlazeDisassembler() {
// Register the disassembler.
- TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
+ TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
createMBlazeDisassembler);
}