mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
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
This commit is contained in:
@@ -103,7 +103,7 @@ static unsigned decodeMUL(uint32_t insn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned decodeSEXT(uint32_t insn) {
|
static unsigned decodeSEXT(uint32_t insn) {
|
||||||
switch (getIMM(insn)) {
|
switch (insn&0x7FF) {
|
||||||
default: return UNSUPPORTED;
|
default: return UNSUPPORTED;
|
||||||
case 0x60: return MBlaze::SEXT8;
|
case 0x60: return MBlaze::SEXT8;
|
||||||
case 0x68: return MBlaze::WIC;
|
case 0x68: return MBlaze::WIC;
|
||||||
@@ -118,7 +118,7 @@ static unsigned decodeSEXT(uint32_t insn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned decodeBEQ(uint32_t insn) {
|
static unsigned decodeBEQ(uint32_t insn) {
|
||||||
switch (getRD(insn)) {
|
switch ((insn>>21)&0x1F) {
|
||||||
default: return UNSUPPORTED;
|
default: return UNSUPPORTED;
|
||||||
case 0x00: return MBlaze::BEQ;
|
case 0x00: return MBlaze::BEQ;
|
||||||
case 0x10: return MBlaze::BEQD;
|
case 0x10: return MBlaze::BEQD;
|
||||||
@@ -136,7 +136,7 @@ static unsigned decodeBEQ(uint32_t insn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned decodeBEQI(uint32_t insn) {
|
static unsigned decodeBEQI(uint32_t insn) {
|
||||||
switch (getRD(insn)) {
|
switch ((insn>>21)&0x1F) {
|
||||||
default: return UNSUPPORTED;
|
default: return UNSUPPORTED;
|
||||||
case 0x00: return MBlaze::BEQI;
|
case 0x00: return MBlaze::BEQI;
|
||||||
case 0x10: return MBlaze::BEQID;
|
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) {
|
static unsigned decodeLW(uint32_t insn) {
|
||||||
switch ((insn>>9)&0x3) {
|
switch ((insn>>9)&0x3) {
|
||||||
default: return UNSUPPORTED;
|
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) {
|
static unsigned decodeSW(uint32_t insn) {
|
||||||
switch ((insn>>9)&0x3) {
|
switch ((insn>>9)&0x3) {
|
||||||
default: return UNSUPPORTED;
|
default: return UNSUPPORTED;
|
||||||
@@ -364,10 +396,10 @@ static unsigned decodeMFS(uint32_t insn) {
|
|||||||
switch ((insn>>15)&0x1) {
|
switch ((insn>>15)&0x1) {
|
||||||
default: return UNSUPPORTED;
|
default: return UNSUPPORTED;
|
||||||
case 0x0:
|
case 0x0:
|
||||||
switch ((insn>>16)&0x1F) {
|
switch ((insn>>16)&0x1) {
|
||||||
default: return UNSUPPORTED;
|
default: return UNSUPPORTED;
|
||||||
case 0x22: return MBlaze::MSRCLR;
|
case 0x0: return MBlaze::MSRSET;
|
||||||
case 0x20: return MBlaze::MSRSET;
|
case 0x1: return MBlaze::MSRCLR;
|
||||||
}
|
}
|
||||||
case 0x1:
|
case 0x1:
|
||||||
switch ((insn>>14)&0x1) {
|
switch ((insn>>14)&0x1) {
|
||||||
@@ -389,7 +421,7 @@ static unsigned decodeOR(uint32_t insn) {
|
|||||||
static unsigned decodeXOR(uint32_t insn) {
|
static unsigned decodeXOR(uint32_t insn) {
|
||||||
switch (getFLAGS(insn)) {
|
switch (getFLAGS(insn)) {
|
||||||
default: return UNSUPPORTED;
|
default: return UNSUPPORTED;
|
||||||
case 0x000: return MBlaze::OR;
|
case 0x000: return MBlaze::XOR;
|
||||||
case 0x400: return MBlaze::PCMPEQ;
|
case 0x400: return MBlaze::PCMPEQ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,7 +429,7 @@ static unsigned decodeXOR(uint32_t insn) {
|
|||||||
static unsigned decodeANDN(uint32_t insn) {
|
static unsigned decodeANDN(uint32_t insn) {
|
||||||
switch (getFLAGS(insn)) {
|
switch (getFLAGS(insn)) {
|
||||||
default: return UNSUPPORTED;
|
default: return UNSUPPORTED;
|
||||||
case 0x000: return MBlaze::OR;
|
case 0x000: return MBlaze::ANDN;
|
||||||
case 0x400: return MBlaze::PCMPNE;
|
case 0x400: return MBlaze::PCMPNE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -428,7 +460,11 @@ static unsigned getOPCODE(uint32_t insn) {
|
|||||||
case MBlaze::GET: return decodeGET(insn);
|
case MBlaze::GET: return decodeGET(insn);
|
||||||
case MBlaze::GETD: return decodeGETD(insn);
|
case MBlaze::GETD: return decodeGETD(insn);
|
||||||
case MBlaze::IDIV: return decodeIDIV(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::LW: return decodeLW(insn);
|
||||||
|
case MBlaze::SB: return decodeSB(insn);
|
||||||
|
case MBlaze::SH: return decodeSH(insn);
|
||||||
case MBlaze::SW: return decodeSW(insn);
|
case MBlaze::SW: return decodeSW(insn);
|
||||||
case MBlaze::MFS: return decodeMFS(insn);
|
case MBlaze::MFS: return decodeMFS(insn);
|
||||||
case MBlaze::OR: return decodeOR(insn);
|
case MBlaze::OR: return decodeOR(insn);
|
||||||
@@ -455,7 +491,7 @@ bool MBlazeDisassembler::getInstruction(MCInst &instr,
|
|||||||
// The machine instruction.
|
// The machine instruction.
|
||||||
uint32_t insn;
|
uint32_t insn;
|
||||||
uint8_t bytes[4];
|
uint8_t bytes[4];
|
||||||
|
|
||||||
// We want to read exactly 4 bytes of data.
|
// 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, NULL) == -1)
|
||||||
return false;
|
return false;
|
||||||
@@ -475,16 +511,50 @@ bool MBlazeDisassembler::getInstruction(MCInst &instr,
|
|||||||
switch ((tsFlags & MBlazeII::FormMask)) {
|
switch ((tsFlags & MBlazeII::FormMask)) {
|
||||||
default: llvm_unreachable("unknown instruction encoding");
|
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:
|
case MBlazeII::FRRR:
|
||||||
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
||||||
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
|
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
|
||||||
instr.addOperand(MCOperand::CreateReg(getRB(insn)));
|
instr.addOperand(MCOperand::CreateReg(getRB(insn)));
|
||||||
break;
|
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:
|
case MBlazeII::FRRI:
|
||||||
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
||||||
instr.addOperand(MCOperand::CreateReg(getRA(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;
|
break;
|
||||||
|
|
||||||
case MBlazeII::FCRR:
|
case MBlazeII::FCRR:
|
||||||
@@ -568,8 +638,8 @@ static MCDisassembler *createMBlazeDisassembler(const Target &T) {
|
|||||||
return new MBlazeDisassembler;
|
return new MBlazeDisassembler;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void LLVMInitializeMBlazeDisassembler() {
|
extern "C" void LLVMInitializeMBlazeDisassembler() {
|
||||||
// Register the disassembler.
|
// Register the disassembler.
|
||||||
TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
|
TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
|
||||||
createMBlazeDisassembler);
|
createMBlazeDisassembler);
|
||||||
}
|
}
|
||||||
|
@@ -325,8 +325,8 @@ let isCommutable = 1, isAsCheapAsAMove = 1 in {
|
|||||||
def OR : Logic<0x20, 0x000, "or ", or>;
|
def OR : Logic<0x20, 0x000, "or ", or>;
|
||||||
def XOR : Logic<0x22, 0x000, "xor ", xor>;
|
def XOR : Logic<0x22, 0x000, "xor ", xor>;
|
||||||
def PCMPBF : PatCmp<0x20, 0x400, "pcmpbf ">;
|
def PCMPBF : PatCmp<0x20, 0x400, "pcmpbf ">;
|
||||||
def PCMPEQ : PatCmp<0x23, 0x400, "pcmpeq ">;
|
def PCMPEQ : PatCmp<0x22, 0x400, "pcmpeq ">;
|
||||||
def PCMPNE : PatCmp<0x22, 0x400, "pcmpne ">;
|
def PCMPNE : PatCmp<0x23, 0x400, "pcmpne ">;
|
||||||
}
|
}
|
||||||
|
|
||||||
let isAsCheapAsAMove = 1 in {
|
let isAsCheapAsAMove = 1 in {
|
||||||
|
@@ -37,3 +37,6 @@
|
|||||||
- The assembly parser does not use any MicroBlaze specific directives.
|
- The assembly parser does not use any MicroBlaze specific directives.
|
||||||
I should investigate if there are MicroBlaze specific directive and,
|
I should investigate if there are MicroBlaze specific directive and,
|
||||||
if there are, add them.
|
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.
|
||||||
|
@@ -11,12 +11,12 @@
|
|||||||
# CHECK: encoding: [0x80,0x01,0x14,0x00]
|
# CHECK: encoding: [0x80,0x01,0x14,0x00]
|
||||||
pcmpbf r0, r1, r2
|
pcmpbf r0, r1, r2
|
||||||
|
|
||||||
# CHECK: pcmpeq
|
# CHECK: pcmpne
|
||||||
# BINARY: 100011 00000 00001 00010 10000000000
|
# BINARY: 100011 00000 00001 00010 10000000000
|
||||||
# CHECK: encoding: [0x8c,0x01,0x14,0x00]
|
# CHECK: encoding: [0x8c,0x01,0x14,0x00]
|
||||||
pcmpeq r0, r1, r2
|
pcmpne r0, r1, r2
|
||||||
|
|
||||||
# CHECK: pcmpne
|
# CHECK: pcmpeq
|
||||||
# BINARY: 100010 00000 00001 00010 10000000000
|
# BINARY: 100010 00000 00001 00010 10000000000
|
||||||
# CHECK: encoding: [0x88,0x01,0x14,0x00]
|
# CHECK: encoding: [0x88,0x01,0x14,0x00]
|
||||||
pcmpne r0, r1, r2
|
pcmpeq r0, r1, r2
|
||||||
|
Reference in New Issue
Block a user