1. Adding test cases for MBlaze MC disassembler.

2. Fixing several errors in disassembler uncovered by test cases.
3. Fixing invalid encoding of PCMPEQ and PCMPNE uncovered by test cases.

llvm-svn: 118969
This commit is contained in:
Wesley Peck 2010-11-13 02:37:59 +00:00
parent 2bcb8daa44
commit b3099e6863
4 changed files with 91 additions and 18 deletions

View File

@ -103,7 +103,7 @@ static unsigned decodeMUL(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;
@ -118,7 +118,7 @@ static unsigned decodeSEXT(uint32_t insn) {
}
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;
@ -136,7 +136,7 @@ static unsigned decodeBEQ(uint32_t insn) {
}
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;
@ -342,6 +342,22 @@ static unsigned decodeIDIV(uint32_t insn) {
}
}
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;
@ -351,6 +367,22 @@ static unsigned decodeLW(uint32_t insn) {
}
}
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;
@ -364,10 +396,10 @@ static unsigned decodeMFS(uint32_t insn) {
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) {
@ -389,7 +421,7 @@ static unsigned decodeOR(uint32_t insn) {
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;
}
}
@ -397,7 +429,7 @@ static unsigned decodeXOR(uint32_t insn) {
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;
}
}
@ -428,7 +460,11 @@ static unsigned getOPCODE(uint32_t insn) {
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);
@ -455,7 +491,7 @@ bool MBlazeDisassembler::getInstruction(MCInst &instr,
// The machine instruction.
uint32_t insn;
uint8_t bytes[4];
// We want to read exactly 4 bytes of data.
if (region.readBytes(address, 4, (uint8_t*)bytes, NULL) == -1)
return false;
@ -475,16 +511,50 @@ bool MBlazeDisassembler::getInstruction(MCInst &instr,
switch ((tsFlags & MBlazeII::FormMask)) {
default: llvm_unreachable("unknown instruction encoding");
case MBlazeII::FRRRR:
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
instr.addOperand(MCOperand::CreateReg(getRB(insn)));
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
break;
case MBlazeII::FRRR:
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
instr.addOperand(MCOperand::CreateReg(getRB(insn)));
break;
case MBlazeII::FRI:
switch (opcode) {
default: llvm_unreachable("unknown instruction encoding");
case MBlaze::MFS:
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
break;
case MBlaze::MTS:
instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
break;
case MBlaze::MSRSET:
case MBlaze::MSRCLR:
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
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)));
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:
@ -568,8 +638,8 @@ static MCDisassembler *createMBlazeDisassembler(const Target &T) {
return new MBlazeDisassembler;
}
extern "C" void LLVMInitializeMBlazeDisassembler() {
extern "C" void LLVMInitializeMBlazeDisassembler() {
// Register the disassembler.
TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
createMBlazeDisassembler);
}

View File

@ -325,8 +325,8 @@ let isCommutable = 1, isAsCheapAsAMove = 1 in {
def OR : Logic<0x20, 0x000, "or ", or>;
def XOR : Logic<0x22, 0x000, "xor ", xor>;
def PCMPBF : PatCmp<0x20, 0x400, "pcmpbf ">;
def PCMPEQ : PatCmp<0x23, 0x400, "pcmpeq ">;
def PCMPNE : PatCmp<0x22, 0x400, "pcmpne ">;
def PCMPEQ : PatCmp<0x22, 0x400, "pcmpeq ">;
def PCMPNE : PatCmp<0x23, 0x400, "pcmpne ">;
}
let isAsCheapAsAMove = 1 in {

View File

@ -37,3 +37,6 @@
- The assembly parser does not use any MicroBlaze specific directives.
I should investigate if there are MicroBlaze specific directive and,
if there are, add them.
- The instruction MFS and MTS use special names for some of the
special registers that can be accessed. These special register
names should be parsed by the assembly parser.

View File

@ -11,12 +11,12 @@
# CHECK: encoding: [0x80,0x01,0x14,0x00]
pcmpbf r0, r1, r2
# CHECK: pcmpeq
# CHECK: pcmpne
# BINARY: 100011 00000 00001 00010 10000000000
# CHECK: encoding: [0x8c,0x01,0x14,0x00]
pcmpeq r0, r1, r2
pcmpne r0, r1, r2
# CHECK: pcmpne
# CHECK: pcmpeq
# BINARY: 100010 00000 00001 00010 10000000000
# CHECK: encoding: [0x88,0x01,0x14,0x00]
pcmpne r0, r1, r2
pcmpeq r0, r1, r2