aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/modules/LLVMLibDeps.cmake2
-rw-r--r--lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp70
-rw-r--r--lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp75
-rw-r--r--lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h3
-rw-r--r--lib/Target/MBlaze/MBlazeAsmPrinter.cpp4
-rw-r--r--lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp8
-rw-r--r--lib/Target/MBlaze/MBlazeInstrFPU.td16
-rw-r--r--lib/Target/MBlaze/MBlazeInstrFormats.td80
-rw-r--r--lib/Target/MBlaze/MBlazeInstrInfo.cpp20
-rw-r--r--lib/Target/MBlaze/MBlazeInstrInfo.h2
-rw-r--r--lib/Target/MBlaze/MBlazeInstrInfo.td104
-rw-r--r--lib/Target/MBlaze/MBlazeRegisterInfo.cpp10
-rw-r--r--test/MC/MBlaze/mblaze_branch.s197
-rw-r--r--test/MC/MBlaze/mblaze_fpu.s77
-rw-r--r--test/MC/MBlaze/mblaze_fsl.s323
-rw-r--r--test/MC/MBlaze/mblaze_memory.s107
-rw-r--r--test/MC/MBlaze/mblaze_pattern.s22
-rw-r--r--test/MC/MBlaze/mblaze_shift.s47
-rw-r--r--test/MC/MBlaze/mblaze_special.s47
-rw-r--r--test/MC/MBlaze/mblaze_typea.s108
20 files changed, 1122 insertions, 200 deletions
diff --git a/cmake/modules/LLVMLibDeps.cmake b/cmake/modules/LLVMLibDeps.cmake
index 1530b42ce8..d18d4a3ef9 100644
--- a/cmake/modules/LLVMLibDeps.cmake
+++ b/cmake/modules/LLVMLibDeps.cmake
@@ -30,7 +30,7 @@ set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMAnalysis LLVMCore LLVMSupport LLVMSyst
set(MSVC_LIB_DEPS_LLVMInterpreter LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMSupport LLVMSystem LLVMTarget)
set(MSVC_LIB_DEPS_LLVMJIT LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMMC LLVMSupport LLVMSystem LLVMTarget)
set(MSVC_LIB_DEPS_LLVMLinker LLVMArchive LLVMBitReader LLVMCore LLVMSupport LLVMSystem LLVMTransformUtils)
-set(MSVC_LIB_DEPS_LLVMMBlazeAsmParser LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMSupport LLVMSystem LLVMTarget)
+set(MSVC_LIB_DEPS_LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMSupport LLVMSystem LLVMTarget)
set(MSVC_LIB_DEPS_LLVMMBlazeAsmPrinter LLVMMC LLVMSupport LLVMSystem)
set(MSVC_LIB_DEPS_LLVMMBlazeCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMBlazeAsmPrinter LLVMMBlazeInfo LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget)
set(MSVC_LIB_DEPS_LLVMMBlazeDisassembler LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMSupport)
diff --git a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp
index 2534691faf..4fc3b65c83 100644
--- a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp
+++ b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp
@@ -9,6 +9,7 @@
#include "MBlaze.h"
#include "MBlazeSubtarget.h"
+#include "MBlazeRegisterInfo.h"
#include "MBlazeISelLowering.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
@@ -45,6 +46,8 @@ class MBlazeAsmParser : public TargetAsmParser {
MBlazeOperand *ParseFsl();
MBlazeOperand* ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+ bool ParseDirectiveWord(unsigned Size, SMLoc L);
+
bool MatchAndEmitInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out);
@@ -201,13 +204,13 @@ public:
void addMemOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(getMemBase()));
+
unsigned RegOff = getMemOffReg();
if (RegOff)
Inst.addOperand(MCOperand::CreateReg(RegOff));
else
addExpr(Inst, getMemOff());
-
- Inst.addOperand(MCOperand::CreateReg(getMemBase()));
}
StringRef getToken() const {
@@ -281,13 +284,24 @@ void MBlazeOperand::dump(raw_ostream &OS) const {
getImm()->print(OS);
break;
case Register:
- OS << "<register " << getReg() << ">";
+ OS << "<register R";
+ OS << MBlazeRegisterInfo::getRegisterNumbering(getReg()) << ">";
break;
case Token:
OS << "'" << getToken() << "'";
break;
- case Memory:
- OS << "MEMORY";
+ case Memory: {
+ OS << "<memory R";
+ OS << MBlazeRegisterInfo::getRegisterNumbering(getMemBase());
+ OS << ", ";
+
+ unsigned RegOff = getMemOffReg();
+ if (RegOff)
+ OS << "R" << MBlazeRegisterInfo::getRegisterNumbering(RegOff);
+ else
+ OS << getMemOff();
+ OS << ">";
+ }
break;
case Fsl:
getFslImm()->print(OS);
@@ -381,6 +395,7 @@ MBlazeOperand *MBlazeAsmParser::ParseRegister() {
if (RegNo == 0)
return 0;
+ getLexer().Lex();
return MBlazeOperand::CreateReg(RegNo, S, E);
}
}
@@ -407,6 +422,7 @@ MBlazeOperand *MBlazeAsmParser::ParseFsl() {
if (reg >= 16)
return 0;
+ getLexer().Lex();
const MCExpr *EVal = MCConstantExpr::Create(reg,getContext());
return MBlazeOperand::CreateFslImm(EVal,S,E);
}
@@ -452,9 +468,6 @@ ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return 0;
}
- // Move past the parsed token in the token stream
- getLexer().Lex();
-
// Push the parsed operand into the list of operands
Operands.push_back(Op);
return Op;
@@ -464,8 +477,11 @@ ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
bool MBlazeAsmParser::
ParseInstruction(StringRef Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- // The first operand is the token for the instruction name
- Operands.push_back(MBlazeOperand::CreateToken(Name, NameLoc));
+ // The first operands is the token for the instruction name
+ size_t dotLoc = Name.find('.');
+ Operands.push_back(MBlazeOperand::CreateToken(Name.substr(0,dotLoc),NameLoc));
+ if (dotLoc < Name.size())
+ Operands.push_back(MBlazeOperand::CreateToken(Name.substr(dotLoc),NameLoc));
// If there are no more operands then finish
if (getLexer().is(AsmToken::EndOfStatement))
@@ -477,10 +493,6 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
while (getLexer().isNot(AsmToken::EndOfStatement) &&
getLexer().is(AsmToken::Comma)) {
- // Make sure there is a comma separating operands
- // if (getLexer().isNot(AsmToken::Comma))
- // return false;
-
// Consume the comma token
getLexer().Lex();
@@ -495,16 +507,44 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
if (Name.startswith("lw") || Name.startswith("sw") ||
Name.startswith("lh") || Name.startswith("sh") ||
Name.startswith("lb") || Name.startswith("sb"))
- return ParseMemory(Operands);
+ return (ParseMemory(Operands) == NULL);
return false;
}
/// ParseDirective parses the arm specific directives
bool MBlazeAsmParser::ParseDirective(AsmToken DirectiveID) {
+ StringRef IDVal = DirectiveID.getIdentifier();
+ if (IDVal == ".word")
+ return ParseDirectiveWord(2, DirectiveID.getLoc());
return true;
}
+/// ParseDirectiveWord
+/// ::= .word [ expression (, expression)* ]
+bool MBlazeAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ for (;;) {
+ const MCExpr *Value;
+ if (getParser().ParseExpression(Value))
+ return true;
+
+ getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
+
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ // FIXME: Improve diagnostic.
+ if (getLexer().isNot(AsmToken::Comma))
+ return Error(L, "unexpected token in directive");
+ Parser.Lex();
+ }
+ }
+
+ Parser.Lex();
+ return false;
+}
+
extern "C" void LLVMInitializeMBlazeAsmLexer();
/// Force static initialization.
diff --git a/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp b/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp
index 30745c694b..704f81cfd8 100644
--- a/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp
+++ b/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp
@@ -29,17 +29,6 @@ void MBlazeInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
printInstruction(MI, O);
}
-void MBlazeInstPrinter::printPCRelImmOperand(const MCInst *MI, unsigned OpNo,
- raw_ostream &O) {
- const MCOperand &Op = MI->getOperand(OpNo);
- if (Op.isImm())
- O << Op.getImm();
- else {
- assert(Op.isExpr() && "unknown pcrel immediate operand");
- O << *Op.getExpr();
- }
-}
-
void MBlazeInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O, const char *Modifier) {
assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
@@ -54,35 +43,6 @@ void MBlazeInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
}
}
-void MBlazeInstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo,
- raw_ostream &O,
- const char *Modifier) {
- const MCOperand &Base = MI->getOperand(OpNo);
- const MCOperand &Disp = MI->getOperand(OpNo+1);
-
- // Print displacement first
-
- // If the global address expression is a part of displacement field with a
- // register base, we should not emit any prefix symbol here, e.g.
- // mov.w &foo, r1
- // vs
- // mov.w glb(r1), r2
- // Otherwise (!) msp430-as will silently miscompile the output :(
- if (!Base.getReg())
- O << '&';
-
- if (Disp.isExpr())
- O << *Disp.getExpr();
- else {
- assert(Disp.isImm() && "Expected immediate in displacement field");
- O << Disp.getImm();
- }
-
- // Print register base field
- if (Base.getReg())
- O << getRegisterName(Base.getReg());
-}
-
void MBlazeInstPrinter::printFSLImm(const MCInst *MI, int OpNo,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNo);
@@ -103,38 +63,7 @@ void MBlazeInstPrinter::printUnsignedImm(const MCInst *MI, int OpNo,
void MBlazeInstPrinter::printMemOperand(const MCInst *MI, int OpNo,
raw_ostream &O, const char *Modifier) {
- printOperand(MI, OpNo+1, O, NULL);
- O << ", ";
printOperand(MI, OpNo, O, NULL);
+ O << ", ";
+ printOperand(MI, OpNo+1, O, NULL);
}
-
-/*
-void MBlazeInstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo,
- raw_ostream &O) {
- unsigned CC = MI->getOperand(OpNo).getImm();
-
- switch (CC) {
- default:
- llvm_unreachable("Unsupported CC code");
- break;
- case MBlazeCC::COND_E:
- O << "eq";
- break;
- case MBlazeCC::COND_NE:
- O << "ne";
- break;
- case MBlazeCC::COND_HS:
- O << "hs";
- break;
- case MBlazeCC::COND_LO:
- O << "lo";
- break;
- case MBlazeCC::COND_GE:
- O << "ge";
- break;
- case MBlazeCC::COND_L:
- O << 'l';
- break;
- }
-}
-*/
diff --git a/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h b/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h
index 2b80689eaf..bebc6c83d5 100644
--- a/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h
+++ b/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h
@@ -33,9 +33,6 @@ namespace llvm {
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
const char *Modifier = 0);
- void printPCRelImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
- void printSrcMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
- const char *Modifier = 0);
void printFSLImm(const MCInst *MI, int OpNo, raw_ostream &O);
void printUnsignedImm(const MCInst *MI, int OpNo, raw_ostream &O);
void printMemOperand(const MCInst *MI, int OpNo,raw_ostream &O,
diff --git a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
index 9c9ec751b6..d919d437cc 100644
--- a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
+++ b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
@@ -205,9 +205,9 @@ void MBlazeAsmPrinter::printFSLImm(const MachineInstr *MI, int opNum,
void MBlazeAsmPrinter::
printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
const char *Modifier) {
- printOperand(MI, opNum+1, O);
- O << ", ";
printOperand(MI, opNum, O);
+ O << ", ";
+ printOperand(MI, opNum+1, O);
}
static MCInstPrinter *createMBlazeMCInstPrinter(const Target &T,
diff --git a/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp b/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp
index 29350d2c3d..9924e67b63 100644
--- a/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp
+++ b/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp
@@ -133,8 +133,8 @@ SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index) {
N.getOperand(1).getOpcode() == ISD::TargetJumpTable)
return false; // jump tables.
- Base = N.getOperand(1);
- Index = N.getOperand(0);
+ Base = N.getOperand(0);
+ Index = N.getOperand(1);
return true;
}
@@ -145,9 +145,9 @@ SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index) {
/// a signed 32-bit displacement [r+imm], and if it is not better
/// represented as reg+reg.
bool MBlazeDAGToDAGISel::
-SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base) {
+SelectAddrRegImm(SDValue N, SDValue &Base, SDValue &Disp) {
// If this can be more profitably realized as r+r, fail.
- if (SelectAddrRegReg(N, Disp, Base))
+ if (SelectAddrRegReg(N, Base, Disp))
return false;
if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
diff --git a/lib/Target/MBlaze/MBlazeInstrFPU.td b/lib/Target/MBlaze/MBlazeInstrFPU.td
index 1793fabbb5..8f3733244a 100644
--- a/lib/Target/MBlaze/MBlazeInstrFPU.td
+++ b/lib/Target/MBlaze/MBlazeInstrFPU.td
@@ -52,9 +52,9 @@ class CmpFN<bits<6> op, bits<11> flags, string instr_asm,
class ArithFR<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode,
InstrItinClass itin> :
- TA<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c),
- !strconcat(instr_asm, " $dst, $c, $b"),
- [(set GPR:$dst, (OpNode GPR:$b, GPR:$c))], itin>;
+ TAR<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c),
+ !strconcat(instr_asm, " $dst, $c, $b"),
+ [(set GPR:$dst, (OpNode GPR:$b, GPR:$c))], itin>;
class LogicF<bits<6> op, string instr_asm> :
TB<op, (outs GPR:$dst), (ins GPR:$b, GPR:$c),
@@ -99,18 +99,20 @@ let Predicates=[HasFPU] in {
def FRSUB : ArithFR<0x16, 0x080, "frsub ", fsub, IIAlu>;
def FMUL : ArithF<0x16, 0x100, "fmul ", fmul, IIAlu>;
def FDIV : ArithF<0x16, 0x180, "fdiv ", fdiv, IIAlu>;
+}
+let Predicates=[HasFPU], isCodeGenOnly=1 in {
def LWF : LoadFM<0x32, "lw ", load>;
- def LWFI : LoadFMI<0x32, "lwi ", load>;
+ def LWFI : LoadFMI<0x3A, "lwi ", load>;
- def SWF : StoreFM<0x32, "sw ", store>;
- def SWFI : StoreFMI<0x32, "swi ", store>;
+ def SWF : StoreFM<0x36, "sw ", store>;
+ def SWFI : StoreFMI<0x3E, "swi ", store>;
}
let Predicates=[HasFPU,HasSqrt] in {
def FLT : ArithIF<0x16, 0x280, "flt ", IIAlu>;
def FINT : ArithFI<0x16, 0x300, "fint ", IIAlu>;
- def FSQRT : ArithF2<0x16, 0x300, "fsqrt ", IIAlu>;
+ def FSQRT : ArithF2<0x16, 0x380, "fsqrt ", IIAlu>;
}
let isAsCheapAsAMove = 1 in {
diff --git a/lib/Target/MBlaze/MBlazeInstrFormats.td b/lib/Target/MBlaze/MBlazeInstrFormats.td
index 383dc5690f..27fa049f80 100644
--- a/lib/Target/MBlaze/MBlazeInstrFormats.td
+++ b/lib/Target/MBlaze/MBlazeInstrFormats.td
@@ -15,8 +15,8 @@ class Format<bits<6> val> {
}
def FPseudo : Format<0>;
-def FRRR : Format<1>; // ADD, RSUB, OR, etc.
-def FRRI : Format<2>; // ADDI, RSUBI, ORI, etc.
+def FRRR : Format<1>; // ADD, OR, etc.
+def FRRI : Format<2>; // ADDI, ORI, etc.
def FCRR : Format<3>; // PUTD, WDC, WIC, BEQ, BNE, BGE, etc.
def FCRI : Format<4>; // RTID, RTED, RTSD, BEQI, BNEI, BGEI, etc.
def FRCR : Format<5>; // BRLD, BRALD, GETD
@@ -32,7 +32,9 @@ def FCRCX : Format<14>; // PUT
def FCX : Format<15>; // TPUT
def FCR : Format<16>; // TPUTD
def FRIR : Format<17>; // RSUBI
-def FC : Format<18>; // NOP
+def FRRRR : Format<18>; // RSUB, FRSUB
+def FRI : Format<19>; // RSUB, FRSUB
+def FC : Format<20>; // NOP
//===----------------------------------------------------------------------===//
// Describe MBlaze instructions format
@@ -48,7 +50,7 @@ def FC : Format<18>; // NOP
//===----------------------------------------------------------------------===//
// Generic MBlaze Format
-class MBlazeInst<bits<6> op, Format form, dag outs, dag ins, string asmstr,
+class MBlazeInst<bits<6> op, Format form, dag outs, dag ins, string asmstr,
list<dag> pattern, InstrItinClass itin> : Instruction {
let Namespace = "MBlaze";
field bits<32> Inst;
@@ -63,7 +65,7 @@ class MBlazeInst<bits<6> op, Format form, dag outs, dag ins, string asmstr,
// If the instruction is marked as a pseudo, set isCodeGenOnly so that the
// assembler and disassmbler ignore it.
let isCodeGenOnly = !eq(!cast<string>(form), "FPseudo");
-
+
dag OutOperandList = outs;
dag InOperandList = ins;
@@ -117,6 +119,27 @@ class TB<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
}
//===----------------------------------------------------------------------===//
+// Type A instruction class in MBlaze but with the operands reversed
+// in the LLVM DAG : <|opcode|rd|ra|rb|flags|>
+//===----------------------------------------------------------------------===//
+
+class TAR<bits<6> op, bits<11> flags, dag outs, dag ins, string asmstr,
+ list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<op,FRRR,outs, ins, asmstr, pattern, itin>
+{
+ bits<5> rd;
+ bits<5> rb;
+ bits<5> ra;
+
+ let Form = FRRRR;
+
+ let Inst{6-10} = rd;
+ let Inst{11-15} = ra;
+ let Inst{16-20} = rb;
+ let Inst{21-31} = flags;
+}
+
+//===----------------------------------------------------------------------===//
// Type B instruction class in MBlaze but with the operands reversed in
// the LLVM DAG : <|opcode|rd|ra|immediate|>
//===----------------------------------------------------------------------===//
@@ -133,3 +156,50 @@ class TBR<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
let ra = rra;
let imm16 = rimm16;
}
+
+//===----------------------------------------------------------------------===//
+// Shift immediate instruction class in MBlaze : <|opcode|rd|ra|immediate|>
+//===----------------------------------------------------------------------===//
+class SHT<bits<6> op, bits<2> flags, dag outs, dag ins, string asmstr,
+ list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<op, FRRI, outs, ins, asmstr, pattern, itin> {
+ bits<5> rd;
+ bits<5> ra;
+ bits<5> imm5;
+
+ let Inst{6-10} = rd;
+ let Inst{11-15} = ra;
+ let Inst{16-20} = 0x0;
+ let Inst{21-22} = flags;
+ let Inst{23-26} = 0x0;
+ let Inst{27-31} = imm5;
+}
+
+//===----------------------------------------------------------------------===//
+// Special instruction class in MBlaze : <|opcode|rd|imm14|>
+//===----------------------------------------------------------------------===//
+class SPC<bits<6> op, bits<2> flags, dag outs, dag ins, string asmstr,
+ list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<op, FRI, outs, ins, asmstr, pattern, itin> {
+ bits<5> rd;
+ bits<14> imm14;
+
+ let Inst{6-10} = rd;
+ let Inst{11-15} = 0x0;
+ let Inst{16-17} = flags;
+ let Inst{18-31} = imm14;
+}
+
+//===----------------------------------------------------------------------===//
+// MSR instruction class in MBlaze : <|opcode|rd|imm15|>
+//===----------------------------------------------------------------------===//
+class MSR<bits<6> op, bits<6> flags, dag outs, dag ins, string asmstr,
+ list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<op, FRI, outs, ins, asmstr, pattern, itin> {
+ bits<5> rd;
+ bits<15> imm15;
+
+ let Inst{6-10} = rd;
+ let Inst{11-16} = flags;
+ let Inst{17-31} = imm15;
+}
diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.cpp b/lib/Target/MBlaze/MBlazeInstrInfo.cpp
index f259d5d603..10bba972b0 100644
--- a/lib/Target/MBlaze/MBlazeInstrInfo.cpp
+++ b/lib/Target/MBlaze/MBlazeInstrInfo.cpp
@@ -38,10 +38,10 @@ static bool isZeroImm(const MachineOperand &op) {
unsigned MBlazeInstrInfo::
isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const {
if (MI->getOpcode() == MBlaze::LWI) {
- if ((MI->getOperand(2).isFI()) && // is a stack slot
- (MI->getOperand(1).isImm()) && // the imm is zero
- (isZeroImm(MI->getOperand(1)))) {
- FrameIndex = MI->getOperand(2).getIndex();
+ if ((MI->getOperand(1).isFI()) && // is a stack slot
+ (MI->getOperand(2).isImm()) && // the imm is zero
+ (isZeroImm(MI->getOperand(2)))) {
+ FrameIndex = MI->getOperand(1).getIndex();
return MI->getOperand(0).getReg();
}
}
@@ -57,10 +57,10 @@ isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const {
unsigned MBlazeInstrInfo::
isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const {
if (MI->getOpcode() == MBlaze::SWI) {
- if ((MI->getOperand(2).isFI()) && // is a stack slot
- (MI->getOperand(1).isImm()) && // the imm is zero
- (isZeroImm(MI->getOperand(1)))) {
- FrameIndex = MI->getOperand(2).getIndex();
+ if ((MI->getOperand(1).isFI()) && // is a stack slot
+ (MI->getOperand(2).isImm()) && // the imm is zero
+ (isZeroImm(MI->getOperand(2)))) {
+ FrameIndex = MI->getOperand(1).getIndex();
return MI->getOperand(0).getReg();
}
}
@@ -91,7 +91,7 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
const TargetRegisterInfo *TRI) const {
DebugLoc DL;
BuildMI(MBB, I, DL, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill))
- .addImm(0).addFrameIndex(FI);
+ .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
}
void MBlazeInstrInfo::
@@ -101,7 +101,7 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
const TargetRegisterInfo *TRI) const {
DebugLoc DL;
BuildMI(MBB, I, DL, get(MBlaze::LWI), DestReg)
- .addImm(0).addFrameIndex(FI);
+ .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.h b/lib/Target/MBlaze/MBlazeInstrInfo.h
index d2cc921fc0..af1842fc9d 100644
--- a/lib/Target/MBlaze/MBlazeInstrInfo.h
+++ b/lib/Target/MBlaze/MBlazeInstrInfo.h
@@ -156,6 +156,8 @@ namespace MBlazeII {
FCX,
FCR,
FRIR,
+ FRRRR,
+ FRI,
FC,
FormMask = 63
diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td
index 98724f94ba..9802361c51 100644
--- a/lib/Target/MBlaze/MBlazeInstrInfo.td
+++ b/lib/Target/MBlaze/MBlazeInstrInfo.td
@@ -79,6 +79,8 @@ def brtarget : Operand<OtherVT>;
def calltarget : Operand<i32>;
def simm16 : Operand<i32>;
def uimm5 : Operand<i32>;
+def uimm14 : Operand<i32>;
+def uimm15 : Operand<i32>;
def fimm : Operand<f32>;
// Unsigned Operand
@@ -95,7 +97,7 @@ def fslimm : Operand<i32> {
// Address operand
def memri : Operand<i32> {
let PrintMethod = "printMemOperand";
- let MIOperandInfo = (ops simm16, GPR);
+ let MIOperandInfo = (ops GPR, simm16);
let ParserMatchClass = MBlazeMemAsmOperand;
}
@@ -167,9 +169,15 @@ class ArithI<bits<6> op, string instr_asm, SDNode OpNode,
!strconcat(instr_asm, " $dst, $b, $c"),
[(set GPR:$dst, (OpNode GPR:$b, imm_type:$c))], IIAlu>;
+class ShiftI<bits<6> op, bits<2> flags, string instr_asm, SDNode OpNode,
+ Operand Od, PatLeaf imm_type> :
+ SHT<op, flags, (outs GPR:$dst), (ins GPR:$b, Od:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [(set GPR:$dst, (OpNode GPR:$b, imm_type:$c))], IIAlu>;
+
class ArithR<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode,
InstrItinClass itin> :
- TA<op, flags, (outs GPR:$dst), (ins GPR:$c, GPR:$b),
+ TAR<op, flags, (outs GPR:$dst), (ins GPR:$c, GPR:$b),
!strconcat(instr_asm, " $dst, $c, $b"),
[(set GPR:$dst, (OpNode GPR:$b, GPR:$c))], itin>;
@@ -192,14 +200,14 @@ class ArithNI<bits<6> op, string instr_asm,Operand Od, PatLeaf imm_type> :
class ArithRN<bits<6> op, bits<11> flags, string instr_asm,
InstrItinClass itin> :
- TA<op, flags, (outs GPR:$dst), (ins GPR:$c, GPR:$b),
- !strconcat(instr_asm, " $dst, $b, $c"),
- [], itin>;
+ TAR<op, flags, (outs GPR:$dst), (ins GPR:$c, GPR:$b),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [], itin>;
class ArithRNI<bits<6> op, string instr_asm,Operand Od, PatLeaf imm_type> :
- TB<op, (outs GPR:$dst), (ins Od:$c, GPR:$b),
- !strconcat(instr_asm, " $dst, $b, $c"),
- [], IIAlu>;
+ TBR<op, (outs GPR:$dst), (ins Od:$c, GPR:$b),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [], IIAlu>;
//===----------------------------------------------------------------------===//
// Misc Arithmetic Instructions
@@ -224,35 +232,25 @@ class PatCmp<bits<6> op, bits<11> flags, string instr_asm> :
//===----------------------------------------------------------------------===//
// Memory Access Instructions
//===----------------------------------------------------------------------===//
-class LoadM<bits<6> op, string instr_asm, PatFrag OpNode> :
- TA<op, 0x000, (outs GPR:$dst), (ins memrr:$addr),
- !strconcat(instr_asm, " $dst, $addr"),
- [(set (i32 GPR:$dst), (OpNode xaddr:$addr))], IILoad>;
-
-class LoadW<bits<6> op, bits<11> flags, string instr_asm> :
+class LoadM<bits<6> op, bits<11> flags, string instr_asm> :
TA<op, flags, (outs GPR:$dst), (ins memrr:$addr),
!strconcat(instr_asm, " $dst, $addr"),
[], IILoad>;
class LoadMI<bits<6> op, string instr_asm, PatFrag OpNode> :
- TBR<op, (outs GPR:$dst), (ins memri:$addr),
- !strconcat(instr_asm, " $dst, $addr"),
- [(set (i32 GPR:$dst), (OpNode iaddr:$addr))], IILoad>;
-
-class StoreM<bits<6> op, string instr_asm, PatFrag OpNode> :
- TA<op, 0x000, (outs), (ins GPR:$dst, memrr:$addr),
+ TB<op, (outs GPR:$dst), (ins memri:$addr),
!strconcat(instr_asm, " $dst, $addr"),
- [(OpNode (i32 GPR:$dst), xaddr:$addr)], IIStore>;
+ [(set (i32 GPR:$dst), (OpNode iaddr:$addr))], IILoad>;
-class StoreW<bits<6> op, bits<11> flags, string instr_asm> :
+class StoreM<bits<6> op, bits<11> flags, string instr_asm> :
TA<op, flags, (outs), (ins GPR:$dst, memrr:$addr),
!strconcat(instr_asm, " $dst, $addr"),
[], IIStore>;
class StoreMI<bits<6> op, string instr_asm, PatFrag OpNode> :
- TBR<op, (outs), (ins GPR:$dst, memri:$addr),
- !strconcat(instr_asm, " $dst, $addr"),
- [(OpNode (i32 GPR:$dst), iaddr:$addr)], IIStore>;
+ TB<op, (outs), (ins GPR:$dst, memri:$addr),
+ !strconcat(instr_asm, " $dst, $addr"),
+ [(OpNode (i32 GPR:$dst), iaddr:$addr)], IIStore>;
//===----------------------------------------------------------------------===//
// Branch Instructions
@@ -358,9 +356,9 @@ let Predicates=[HasBarrel] in {
def BSRL : Arith<0x11, 0x000, "bsrl ", srl, IIAlu>;
def BSRA : Arith<0x11, 0x200, "bsra ", sra, IIAlu>;
def BSLL : Arith<0x11, 0x400, "bsll ", shl, IIAlu>;
- def BSRLI : ArithI<0x11, "bsrli ", srl, uimm5, immZExt5>;
- def BSRAI : ArithI<0x11, "bsrai ", sra, uimm5, immZExt5>;
- def BSLLI : ArithI<0x11, "bslli ", shl, uimm5, immZExt5>;
+ def BSRLI : ShiftI<0x19, 0x0, "bsrli ", srl, uimm5, immZExt5>;
+ def BSRAI : ShiftI<0x19, 0x1, "bsrai ", sra, uimm5, immZExt5>;
+ def BSLLI : ShiftI<0x19, 0x2, "bslli ", shl, uimm5, immZExt5>;
}
let Predicates=[HasDiv] in {
@@ -396,24 +394,30 @@ let Predicates=[HasMul] in {
//===----------------------------------------------------------------------===//
let canFoldAsLoad = 1, isReMaterializable = 1 in {
- def LBU : LoadM<0x30, "lbu ", zextloadi8>;
- def LHU : LoadM<0x31, "lhu ", zextloadi16>;
+ def LBU : LoadM<0x30, 0x000, "lbu ">;
+ def LBUR : LoadM<0x30, 0x200, "lbur ">;
+
+ def LHU : LoadM<0x31, 0x000, "lhu ">;
+ def LHUR : LoadM<0x31, 0x200, "lhur ">;
- def LW : LoadW<0x32, 0x0, "lw ">;
- def LWR : LoadW<0x32, 0x2, "lwr ">;
- def LWX : LoadW<0x32, 0x4, "lwx ">;
+ def LW : LoadM<0x32, 0x000, "lw ">;
+ def LWR : LoadM<0x32, 0x200, "lwr ">;
+ def LWX : LoadM<0x32, 0x400, "lwx ">;
def LBUI : LoadMI<0x38, "lbui ", zextloadi8>;
def LHUI : LoadMI<0x39, "lhui ", zextloadi16>;
def LWI : LoadMI<0x3A, "lwi ", load>;
}
- def SB : StoreM<0x34, "sb ", truncstorei8>;
- def SH : StoreM<0x35, "sh ", truncstorei16>;
+ def SB : StoreM<0x34, 0x000, "sb ">;
+ def SBR : StoreM<0x34, 0x200, "sbr ">;
- def SW : StoreW<0x36, 0x0, "sw ">;
- def SWR : StoreW<0x36, 0x2, "swr ">;
- def SWX : StoreW<0x36, 0x4, "swx ">;
+ def SH : StoreM<0x35, 0x000, "sh ">;
+ def SHR : StoreM<0x35, 0x200, "shr ">;
+
+ def SW : StoreM<0x36, 0x000, "sw ">;
+ def SWR : StoreM<0x36, 0x200, "swr ">;
+ def SWX : StoreM<0x36, 0x400, "swx ">;
def SBI : StoreMI<0x3C, "sbi ", truncstorei8>;
def SHI : StoreMI<0x3D, "shi ", truncstorei16>;
@@ -583,17 +587,17 @@ let opcode=0x08, isCodeGenOnly=1 in {
//===----------------------------------------------------------------------===//
// Misc. instructions
//===----------------------------------------------------------------------===//
-def MFS : MBlazeInst<0x25, FPseudo, (outs), (ins), "mfs", [], IIAlu> {
-}
+def MFS : SPC<0x25, 0x2, (outs GPR:$dst), (ins uimm14:$rg),
+ "mfs $dst, $rg", [], IIAlu>;
-def MTS : MBlazeInst<0x25, FPseudo, (outs), (ins), "mts", [], IIAlu> {
-}
+def MTS : SPC<0x25, 0x3, (outs), (ins uimm14:$dst, GPR:$rg),
+ "mts $dst, $rg", [], IIAlu>;
-def MSRSET : MBlazeInst<0x25, FPseudo, (outs), (ins), "msrset", [], IIAlu> {
-}
+def MSRSET : MSR<0x25, 0x20, (outs GPR:$dst), (ins uimm15:$set),
+ "msrset $dst, $set", [], IIAlu>;
-def MSRCLR : MBlazeInst<0x25, FPseudo, (outs), (ins), "msrclr", [], IIAlu> {
-}
+def MSRCLR : MSR<0x25, 0x22, (outs GPR:$dst), (ins uimm15:$clr),
+ "msrclr $dst, $clr", [], IIAlu>;
let rd=0x0, Form=FCRR in {
def WDC : TA<0x24, 0x64, (outs), (ins GPR:$a, GPR:$b),
@@ -765,6 +769,14 @@ def : Pat<(extloadi16 xaddr:$src), (i32 (LHU xaddr:$src))>;
def : Pat<(store (i32 GPR:$dst), xaddr:$addr), (SW GPR:$dst, xaddr:$addr)>;
def : Pat<(load xaddr:$addr), (i32 (LW xaddr:$addr))>;
+// 16-bit load and store
+def : Pat<(truncstorei16 (i32 GPR:$dst), xaddr:$addr), (SH GPR:$dst, xaddr:$addr)>;
+def : Pat<(zextloadi16 xaddr:$addr), (i32 (LHU xaddr:$addr))>;
+
+// 8-bit load and store
+def : Pat<(truncstorei8 (i32 GPR:$dst), xaddr:$addr), (SB GPR:$dst, xaddr:$addr)>;
+def : Pat<(zextlo