From: Wesley Peck Date: Sat, 13 Nov 2010 02:37:59 +0000 (+0000) Subject: 1. Adding test cases for MBlaze MC disassembler. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ec57d53342827a17022b710cba9a9f4420d9ddce;p=oota-llvm.git 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118969 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp index e09829c70e8..c2b5a9f1a8f 100644 --- a/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp +++ b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp @@ -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); } diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td index 1059fba08d6..7c6c9aa0009 100644 --- a/lib/Target/MBlaze/MBlazeInstrInfo.td +++ b/lib/Target/MBlaze/MBlazeInstrInfo.td @@ -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 { diff --git a/lib/Target/MBlaze/TODO b/lib/Target/MBlaze/TODO index bbdf4f31124..cc0aa48288c 100644 --- a/lib/Target/MBlaze/TODO +++ b/lib/Target/MBlaze/TODO @@ -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. diff --git a/test/MC/MBlaze/mblaze_pattern.s b/test/MC/MBlaze/mblaze_pattern.s index d9c56011f4f..6bbc234e3d4 100644 --- a/test/MC/MBlaze/mblaze_pattern.s +++ b/test/MC/MBlaze/mblaze_pattern.s @@ -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