diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 93 | ||||
-rw-r--r-- | lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 21 | ||||
-rw-r--r-- | lib/Target/Mips/MipsDSPInstrInfo.td | 5 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrFPU.td | 66 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 7 |
5 files changed, 143 insertions, 49 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index e92d58a..7214cb5 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -88,6 +88,11 @@ class MipsAsmParser : public MCTargetAsmParser { MipsAsmParser::OperandMatchResultTy parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind); + + MipsAsmParser::OperandMatchResultTy + parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + MipsAsmParser::OperandMatchResultTy parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands); @@ -179,6 +184,10 @@ class MipsAsmParser : public MCTargetAsmParser { return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; } + bool isN64() const { + return STI.getFeatureBits() & Mips::FeatureN64; + } + int matchRegisterName(StringRef Symbol, bool is64BitReg); int matchCPURegisterName(StringRef Symbol); @@ -245,6 +254,7 @@ private: k_Memory, k_PostIndexRegister, k_Register, + k_PtrReg, k_Token } Kind; @@ -284,6 +294,11 @@ public: Inst.addOperand(MCOperand::CreateReg(getReg())); } + void addPtrRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::CreateReg(getPtrReg())); + } + void addExpr(MCInst &Inst, const MCExpr *Expr) const{ // Add as immediate when possible. Null MCExpr = 0. if (Expr == 0) @@ -313,6 +328,7 @@ public: bool isImm() const { return Kind == k_Immediate; } bool isToken() const { return Kind == k_Token; } bool isMem() const { return Kind == k_Memory; } + bool isPtrReg() const { return Kind == k_PtrReg; } StringRef getToken() const { assert(Kind == k_Token && "Invalid access!"); @@ -324,8 +340,13 @@ public: return Reg.RegNum; } + unsigned getPtrReg() const { + assert((Kind == k_PtrReg) && "Invalid access!"); + return Reg.RegNum; + } + void setRegKind(RegisterKind RegKind) { - assert((Kind == k_Register) && "Invalid access!"); + assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!"); Reg.Kind = RegKind; } @@ -361,6 +382,14 @@ public: return Op; } + static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) { + MipsOperand *Op = new MipsOperand(k_PtrReg); + Op->Reg.RegNum = RegNum; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; + } + static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { MipsOperand *Op = new MipsOperand(k_Immediate); Op->Imm.Val = Val; @@ -1289,6 +1318,68 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( return MatchOperand_Success; } +bool +MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, + int RegKind) { + // If the first token is not '$' we have an error. + if (Parser.getTok().isNot(AsmToken::Dollar)) + return false; + + SMLoc S = Parser.getTok().getLoc(); + Parser.Lex(); + AsmToken::TokenKind TkKind = getLexer().getKind(); + int Reg; + + if (TkKind == AsmToken::Integer) { + Reg = matchRegisterByNumber(Parser.getTok().getIntVal(), + regKindToRegClass(RegKind)); + if (Reg == -1) + return false; + } else if (TkKind == AsmToken::Identifier) { + if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1) + return false; + Reg = getReg(regKindToRegClass(RegKind), Reg); + } else { + return false; + } + + MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc()); + Op->setRegKind((MipsOperand::RegisterKind)RegKind); + Operands.push_back(Op); + Parser.Lex(); + return true; +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { + MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 : + MipsOperand::Kind_GPR32; + + // Parse index register. + if (!parsePtrReg(Operands, RegKind)) + return MatchOperand_NoMatch; + + // Parse '('. + if (Parser.getTok().isNot(AsmToken::LParen)) + return MatchOperand_NoMatch; + + Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); + Parser.Lex(); + + // Parse base register. + if (!parsePtrReg(Operands, RegKind)) + return MatchOperand_NoMatch; + + // Parse ')'. + if (Parser.getTok().isNot(AsmToken::RParen)) + return MatchOperand_NoMatch; + + Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); + Parser.Lex(); + + return MatchOperand_Success; +} + MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind) { diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index c6f3bab..6e12a5d 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -35,14 +35,18 @@ public: /// MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, bool bigEndian) : - MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {} + MCDisassembler(STI), RegInfo(Info), + IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {} virtual ~MipsDisassemblerBase() {} const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } + bool isN64() const { return IsN64; } + private: OwningPtr<const MCRegisterInfo> RegInfo; + bool IsN64; protected: bool isBigEndian; }; @@ -103,6 +107,11 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -364,6 +373,16 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (static_cast<const MipsDisassembler *>(Decoder)->isN64()) + return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); + + return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); +} + static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, diff --git a/lib/Target/Mips/MipsDSPInstrInfo.td b/lib/Target/Mips/MipsDSPInstrInfo.td index 53e3389..b3e01b1 100644 --- a/lib/Target/Mips/MipsDSPInstrInfo.td +++ b/lib/Target/Mips/MipsDSPInstrInfo.td @@ -348,10 +348,9 @@ class SHLL_QB_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode, class LX_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass itin> { dag OutOperandList = (outs GPR32Opnd:$rd); - dag InOperandList = (ins GPR32Opnd:$base, GPR32Opnd:$index); + dag InOperandList = (ins PtrRC:$base, PtrRC:$index); string AsmString = !strconcat(instr_asm, "\t$rd, ${index}(${base})"); - list<dag> Pattern = [(set GPR32Opnd:$rd, - (OpNode GPR32Opnd:$base, GPR32Opnd:$index))]; + list<dag> Pattern = [(set GPR32Opnd:$rd, (OpNode iPTR:$base, iPTR:$index))]; InstrItinClass Itinerary = itin; bit mayLoad = 1; } diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index ccf3458..536dff6 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -171,19 +171,19 @@ class NMADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin, [(set RC:$fd, (fsub fpimm0, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr)))], Itin, FrmFR>; -class LWXC1_FT<string opstr, RegisterOperand DRC, RegisterOperand PRC, +class LWXC1_FT<string opstr, RegisterOperand DRC, InstrItinClass Itin, SDPatternOperator OpNode = null_frag> : - InstSE<(outs DRC:$fd), (ins PRC:$base, PRC:$index), + InstSE<(outs DRC:$fd), (ins PtrRC:$base, PtrRC:$index), !strconcat(opstr, "\t$fd, ${index}(${base})"), - [(set DRC:$fd, (OpNode (add PRC:$base, PRC:$index)))], Itin, FrmFI> { + [(set DRC:$fd, (OpNode (add iPTR:$base, iPTR:$index)))], Itin, FrmFI> { let AddedComplexity = 20; } -class SWXC1_FT<string opstr, RegisterOperand DRC, RegisterOperand PRC, +class SWXC1_FT<string opstr, RegisterOperand DRC, InstrItinClass Itin, SDPatternOperator OpNode = null_frag> : - InstSE<(outs), (ins DRC:$fs, PRC:$base, PRC:$index), + InstSE<(outs), (ins DRC:$fs, PtrRC:$base, PtrRC:$index), !strconcat(opstr, "\t$fs, ${index}(${base})"), - [(OpNode DRC:$fs, (add PRC:$base, PRC:$index))], Itin, FrmFI> { + [(OpNode DRC:$fs, (add iPTR:$base, iPTR:$index))], Itin, FrmFI> { let AddedComplexity = 20; } @@ -378,52 +378,30 @@ let Predicates = [NotFP64bit, HasStdEnc] in { // Indexed loads and stores. let Predicates = [HasFPIdx, HasStdEnc] in { - def LWXC1 : LWXC1_FT<"lwxc1", FGR32Opnd, GPR32Opnd, IIFLoad, load>, - LWXC1_FM<0>; - def SWXC1 : SWXC1_FT<"swxc1", FGR32Opnd, GPR32Opnd, IIFStore, store>, - SWXC1_FM<8>; + def LWXC1 : LWXC1_FT<"lwxc1", FGR32Opnd, IIFLoad, load>, LWXC1_FM<0>; + def SWXC1 : SWXC1_FT<"swxc1", FGR32Opnd, IIFStore, store>, SWXC1_FM<8>; } -let Predicates = [HasMips32r2, NotMips64, HasStdEnc] in { - def LDXC1 : LWXC1_FT<"ldxc1", AFGR64Opnd, GPR32Opnd, IIFLoad, load>, - LWXC1_FM<1>; - def SDXC1 : SWXC1_FT<"sdxc1", AFGR64Opnd, GPR32Opnd, IIFStore, store>, - SWXC1_FM<9>; +let Predicates = [HasFPIdx, NotFP64bit, HasStdEnc] in { + def LDXC1 : LWXC1_FT<"ldxc1", AFGR64Opnd, IIFLoad, load>, LWXC1_FM<1>; + def SDXC1 : SWXC1_FT<"sdxc1", AFGR64Opnd, IIFStore, store>, SWXC1_FM<9>; } -let Predicates = [HasMips64, NotN64, HasStdEnc], DecoderNamespace="Mips64" in { - def LDXC164 : LWXC1_FT<"ldxc1", FGR64Opnd, GPR32Opnd, IIFLoad, load>, - LWXC1_FM<1>; - def SDXC164 : SWXC1_FT<"sdxc1", FGR64Opnd, GPR32Opnd, IIFStore, store>, - SWXC1_FM<9>; +let Predicates = [HasFPIdx, IsFP64bit, HasStdEnc], + DecoderNamespace="Mips64" in { + def LDXC164 : LWXC1_FT<"ldxc1", FGR64Opnd, IIFLoad, load>, LWXC1_FM<1>; + def SDXC164 : SWXC1_FT<"sdxc1", FGR64Opnd, IIFStore, store>, SWXC1_FM<9>; } -// n64 -let Predicates = [IsN64, HasStdEnc], isCodeGenOnly=1 in { - def LWXC1_P8 : LWXC1_FT<"lwxc1", FGR32Opnd, GPR64Opnd, IIFLoad, load>, - LWXC1_FM<0>; - def LDXC164_P8 : LWXC1_FT<"ldxc1", FGR64Opnd, GPR64Opnd, IIFLoad, - load>, LWXC1_FM<1>; - def SWXC1_P8 : SWXC1_FT<"swxc1", FGR32Opnd, GPR64Opnd, IIFStore, - store>, SWXC1_FM<8>; - def SDXC164_P8 : SWXC1_FT<"sdxc1", FGR64Opnd, GPR64Opnd, IIFStore, - store>, SWXC1_FM<9>; +// Load/store doubleword indexed unaligned. +let Predicates = [NotFP64bit, HasStdEnc] in { + def LUXC1 : LWXC1_FT<"luxc1", AFGR64Opnd, IIFLoad>, LWXC1_FM<0x5>; + def SUXC1 : SWXC1_FT<"suxc1", AFGR64Opnd, IIFStore>, SWXC1_FM<0xd>; } -// Load/store doubleword indexed unaligned. -let Predicates = [NotMips64, HasStdEnc] in { - def LUXC1 : LWXC1_FT<"luxc1", AFGR64Opnd, GPR32Opnd, IIFLoad>, - LWXC1_FM<0x5>; - def SUXC1 : SWXC1_FT<"suxc1", AFGR64Opnd, GPR32Opnd, IIFStore>, - SWXC1_FM<0xd>; -} - -let Predicates = [HasMips64, HasStdEnc], - DecoderNamespace="Mips64" in { - def LUXC164 : LWXC1_FT<"luxc1", FGR64Opnd, GPR32Opnd, IIFLoad>, - LWXC1_FM<0x5>; - def SUXC164 : SWXC1_FT<"suxc1", FGR64Opnd, GPR32Opnd, IIFStore>, - SWXC1_FM<0xd>; +let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace="Mips64" in { + def LUXC164 : LWXC1_FT<"luxc1", FGR64Opnd, IIFLoad>, LWXC1_FM<0x5>; + def SUXC164 : SWXC1_FT<"suxc1", FGR64Opnd, IIFStore>, SWXC1_FM<0xd>; } /// Floating-point Aritmetic diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 714c7a8..5518b8c 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -279,6 +279,11 @@ def MipsMemAsmOperand : AsmOperandClass { let ParserMethod = "parseMemOperand"; } +def PtrRegAsmOperand : AsmOperandClass { + let Name = "PtrReg"; + let ParserMethod = "parsePtrReg"; +} + // Address operand def mem : Operand<iPTR> { let PrintMethod = "printMemOperand"; @@ -297,6 +302,8 @@ def mem_ea : Operand<iPTR> { def PtrRC : Operand<iPTR> { let MIOperandInfo = (ops ptr_rc); + let DecoderMethod = "DecodePtrRegisterClass"; + let ParserMatchClass = PtrRegAsmOperand; } // size operand of ext instruction |