diff options
author | Wesley Peck <peckw@wesleypeck.com> | 2010-11-13 02:37:59 +0000 |
---|---|---|
committer | Wesley Peck <peckw@wesleypeck.com> | 2010-11-13 02:37:59 +0000 |
commit | ec57d53342827a17022b710cba9a9f4420d9ddce (patch) | |
tree | 463d27a6d2b732c18e8ab7329287c5f35ae4dee6 /lib/Target/MBlaze | |
parent | 63f3544a7f6ca09e7515d6b0e1bf9e8e884131e2 (diff) | |
download | external_llvm-ec57d53342827a17022b710cba9a9f4420d9ddce.zip external_llvm-ec57d53342827a17022b710cba9a9f4420d9ddce.tar.gz external_llvm-ec57d53342827a17022b710cba9a9f4420d9ddce.tar.bz2 |
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
Diffstat (limited to 'lib/Target/MBlaze')
-rw-r--r-- | lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp | 94 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeInstrInfo.td | 4 | ||||
-rw-r--r-- | lib/Target/MBlaze/TODO | 3 |
3 files changed, 87 insertions, 14 deletions
diff --git a/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp index e09829c..c2b5a9f 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 1059fba..7c6c9aa 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 bbdf4f3..cc0aa48 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. |