aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp94
-rw-r--r--lib/Target/MBlaze/MBlazeInstrInfo.td4
-rw-r--r--lib/Target/MBlaze/TODO3
-rw-r--r--test/MC/MBlaze/mblaze_pattern.s8
4 files changed, 91 insertions, 18 deletions
diff --git a/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp
index e09829c70e..c2b5a9f1a8 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 1059fba08d..7c6c9aa000 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 bbdf4f3112..cc0aa48288 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 d9c56011f4..6bbc234e3d 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