diff options
author | Zoran Jovanovic <zoran.jovanovic@imgtec.com> | 2014-12-16 14:59:10 +0000 |
---|---|---|
committer | Zoran Jovanovic <zoran.jovanovic@imgtec.com> | 2014-12-16 14:59:10 +0000 |
commit | 2deca34803b75ec3d7943b2718ac2869e6442416 (patch) | |
tree | 273e869af10aa9cb4f8fb1449e44166a24965a89 /llvm/lib/Target | |
parent | 0d6a010c13de508107d2331c215f08e7f0eee927 (diff) | |
download | bcm5719-llvm-2deca34803b75ec3d7943b2718ac2869e6442416.tar.gz bcm5719-llvm-2deca34803b75ec3d7943b2718ac2869e6442416.zip |
[mips][microMIPS] Implement SWP and LWP instructions
Differential Revision: http://reviews.llvm.org/D5667
llvm-svn: 224338
Diffstat (limited to 'llvm/lib/Target')
7 files changed, 101 insertions, 1 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 67725cb7ffa..44e0532f413 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -147,6 +147,9 @@ class MipsAsmParser : public MCTargetAsmParser { MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands); MipsAsmParser::OperandMatchResultTy + parseRegisterPair (OperandVector &Operands); + + MipsAsmParser::OperandMatchResultTy parseRegisterList (OperandVector &Operands); bool searchSymbolAlias(OperandVector &Operands); @@ -428,7 +431,8 @@ private: k_PhysRegister, /// A physical register from the Mips namespace k_RegisterIndex, /// A register index in one or more RegKind. k_Token, /// A simple token - k_RegList /// A physical register list + k_RegList, /// A physical register list + k_RegPair /// A pair of physical register } Kind; public: @@ -781,6 +785,13 @@ public: Inst.addOperand(MCOperand::CreateReg(RegNo)); } + void addRegPairOperands(MCInst &Inst, unsigned N) const { + assert(N == 2 && "Invalid number of operands!"); + unsigned RegNo = getRegPair(); + Inst.addOperand(MCOperand::CreateReg(RegNo++)); + Inst.addOperand(MCOperand::CreateReg(RegNo)); + } + bool isReg() const override { // As a special case until we sort out the definition of div/divu, pretend // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. @@ -845,6 +856,7 @@ public: assert(Kind == k_Token && "Invalid access!"); return StringRef(Tok.Data, Tok.Length); } + bool isRegPair() const { return Kind == k_RegPair; } unsigned getReg() const override { // As a special case until we sort out the definition of div/divu, pretend @@ -886,6 +898,11 @@ public: return *(RegList.List); } + unsigned getRegPair() const { + assert((Kind == k_RegPair) && "Invalid access!"); + return RegIdx.Index; + } + static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S, MipsAsmParser &Parser) { auto Op = make_unique<MipsOperand>(k_Token, Parser); @@ -995,6 +1012,15 @@ public: return Op; } + static std::unique_ptr<MipsOperand> + CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) { + auto Op = make_unique<MipsOperand>(k_RegPair, Parser); + Op->RegIdx.Index = RegNo; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; + } + bool isGPRAsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; } @@ -1061,6 +1087,7 @@ public: case k_PhysRegister: case k_RegisterIndex: case k_Token: + case k_RegPair: break; } } @@ -1094,6 +1121,9 @@ public: OS << Reg << " "; OS << ">"; break; + case k_RegPair: + OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">"; + break; } } }; // class MipsOperand @@ -2723,6 +2753,22 @@ MipsAsmParser::parseRegisterList(OperandVector &Operands) { return MatchOperand_Success; } +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseRegisterPair(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); + + SMLoc S = Parser.getTok().getLoc(); + if (parseAnyRegister(Operands) != MatchOperand_Success) + return MatchOperand_ParseFail; + + SMLoc E = Parser.getTok().getLoc(); + MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back()); + unsigned Reg = Op.getGPR32Reg(); + Operands.pop_back(); + Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this)); + return MatchOperand_Success; +} + MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { MCSymbolRefExpr::VariantKind VK = diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index ec90781f629..d29347d6213 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -1222,6 +1222,9 @@ static DecodeStatus DecodeMemMMImm12(MCInst &Inst, // fallthrough default: Inst.addOperand(MCOperand::CreateReg(Reg)); + if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) + Inst.addOperand(MCOperand::CreateReg(Reg+1)); + Inst.addOperand(MCOperand::CreateReg(Base)); Inst.addOperand(MCOperand::CreateImm(Offset)); } diff --git a/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp b/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp index e8366290c16..80e555e5f5c 100644 --- a/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp +++ b/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp @@ -262,6 +262,11 @@ printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O) { } void MipsInstPrinter:: +printRegisterPair(const MCInst *MI, int opNum, raw_ostream &O) { + printRegName(O, MI->getOperand(opNum).getReg()); +} + +void MipsInstPrinter:: printSHFMask(const MCInst *MI, int opNum, raw_ostream &O) { llvm_unreachable("TODO"); } diff --git a/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.h b/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.h index 42df0131d0a..468dc07818e 100644 --- a/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.h +++ b/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.h @@ -99,6 +99,7 @@ private: void printMemOperand(const MCInst *MI, int opNum, raw_ostream &O); void printMemOperandEA(const MCInst *MI, int opNum, raw_ostream &O); void printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O); + void printRegisterPair(const MCInst *MI, int opNum, raw_ostream &O); void printSHFMask(const MCInst *MI, int opNum, raw_ostream &O); bool printAlias(const char *Str, const MCInst &MI, unsigned OpNo, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 0c86d11659c..689248b065f 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -862,4 +862,11 @@ MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, return (MI.getNumOperands() - 4); } +unsigned +MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); +} + #include "MipsGenMCCodeEmitter.inc" diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index b557f740430..4a4c9f6e0d3 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -184,6 +184,10 @@ public: SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; + unsigned getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td index 9675ef21411..3fae97c32ef 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td @@ -148,6 +148,36 @@ class StoreLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO, let DecoderMethod = "DecodeMemMMImm12"; } +/// A register pair used by load/store pair instructions. +def RegPairAsmOperand : AsmOperandClass { + let Name = "RegPair"; + let ParserMethod = "parseRegisterPair"; +} + +def regpair : Operand<i32> { + let EncoderMethod = "getRegisterPairOpValue"; + let ParserMatchClass = RegPairAsmOperand; + let PrintMethod = "printRegisterPair"; + let DecoderMethod = "DecodeRegPairOperand"; + let MIOperandInfo = (ops GPR32Opnd, GPR32Opnd); +} + +class StorePairMM<string opstr, InstrItinClass Itin = NoItinerary, + ComplexPattern Addr = addr> : + InstSE<(outs), (ins regpair:$rt, mem_mm_12:$addr), + !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> { + let DecoderMethod = "DecodeMemMMImm12"; + let mayStore = 1; +} + +class LoadPairMM<string opstr, InstrItinClass Itin = NoItinerary, + ComplexPattern Addr = addr> : + InstSE<(outs regpair:$rt), (ins mem_mm_12:$addr), + !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> { + let DecoderMethod = "DecodeMemMMImm12"; + let mayLoad = 1; +} + class LLBaseMM<string opstr, RegisterOperand RO> : InstSE<(outs RO:$rt), (ins mem_mm_12:$addr), !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> { @@ -555,6 +585,10 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def SWM16_MM : StoreMultMM16<"swm16">, LWM_FM_MM16<0x5>; def LWM16_MM : LoadMultMM16<"lwm16">, LWM_FM_MM16<0x4>; + /// Load and Store Pair Instructions + def SWP_MM : StorePairMM<"swp">, LWM_FM_MM<0x9>; + def LWP_MM : LoadPairMM<"lwp">, LWM_FM_MM<0x1>; + /// Move Conditional def MOVZ_I_MM : MMRel, CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd, NoItinerary>, ADD_FM_MM<0, 0x58>; |