diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 30149d30ac0..4d805a7f114 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -104,6 +104,15 @@ class MipsAsmParser : public MCTargetAsmParser { MipsAsmParser::OperandMatchResultTy parseCCRRegs(SmallVectorImpl &Operands); + MipsAsmParser::OperandMatchResultTy + parseAFGR64Regs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseFGR64Regs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseFGR32Regs(SmallVectorImpl &Operands); + bool searchSymbolAlias(SmallVectorImpl &Operands, unsigned RegKind); @@ -177,8 +186,6 @@ class MipsAsmParser : public MCTargetAsmParser { FpFormatTy getFpFormat() {return FpFormat;} - bool requestsDoubleOperand(StringRef Mnemonic); - unsigned getReg(int RC, int RegNo); int getATReg(); @@ -385,6 +392,18 @@ public: return Reg.Kind == Kind_CCRRegs; } + bool isAFGR64Asm() const { + return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs; + } + + bool isFGR64Asm() const { + return Kind == k_Register && Reg.Kind == Kind_FGR64Regs; + } + + bool isFGR32Asm() const { + return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs; + } + /// getStartLoc - Get the location of the first token of this operand. SMLoc getStartLoc() const { return StartLoc; @@ -838,18 +857,6 @@ void MipsAsmParser::setDefaultFpFormat() { FpFormat = FP_FORMAT_S; } -bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){ - - bool IsDouble = StringSwitch(Mnemonic.lower()) - .Case("ldxc1", true) - .Case("ldc1", true) - .Case("sdxc1", true) - .Case("sdc1", true) - .Default(false); - - return IsDouble; -} - void MipsAsmParser::setFpFormat(StringRef Format) { FpFormat = StringSwitch(Format.lower()) @@ -1280,6 +1287,34 @@ MipsAsmParser::parseCPURegs(SmallVectorImpl &Operands) { return parseRegs(Operands, (int) MipsOperand::Kind_CPURegs); } +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseAFGR64Regs(SmallVectorImpl &Operands) { + + if (isFP64()) + return MatchOperand_NoMatch; + // Double operand is expected, set appropriate format + setFpFormat(FP_FORMAT_D); + + return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs); +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseFGR64Regs(SmallVectorImpl &Operands) { + if (!isFP64()) + return MatchOperand_NoMatch; + // Double operand is expected, set appropriate format + setFpFormat(FP_FORMAT_D); + + return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs); +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseFGR32Regs(SmallVectorImpl &Operands) { + // Single operand is expected, set appropriate format + setFpFormat(FP_FORMAT_S); + return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs); +} + bool MipsAsmParser::searchSymbolAlias( SmallVectorImpl &Operands, unsigned RegKind) { @@ -1537,50 +1572,44 @@ bool MipsAsmParser:: ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, SmallVectorImpl &Operands) { StringRef Mnemonic; - // Floating point instructions: Should the register be treated as a double? - if (requestsDoubleOperand(Name)) { - setFpFormat(FP_FORMAT_D); - Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); - Mnemonic = Name; - } else { - setDefaultFpFormat(); - // Create the leading tokens for the mnemonic, split by '.' characters. - size_t Start = 0, Next = Name.find('.'); - Mnemonic = Name.slice(Start, Next); - Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); + setDefaultFpFormat(); + // Create the leading tokens for the mnemonic, split by '.' characters. + size_t Start = 0, Next = Name.find('.'); + Mnemonic = Name.slice(Start, Next); - if (Next != StringRef::npos) { - // There is a format token in mnemonic. - size_t Dot = Name.find('.', Next + 1); - StringRef Format = Name.slice(Next, Dot); - if (Dot == StringRef::npos) // Only one '.' in a string, it's a format. - Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); - else { - if (Name.startswith("c.")) { - // Floating point compare, add '.' and immediate represent for cc. - Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); - int Cc = ConvertCcString(Format); - if (Cc == -1) { - return Error(NameLoc, "Invalid conditional code"); - } - SMLoc E = SMLoc::getFromPointer( - Parser.getTok().getLoc().getPointer() - 1); - Operands.push_back( - MipsOperand::CreateImm(MCConstantExpr::Create(Cc, getContext()), - NameLoc, E)); - } else { - // trunc, ceil, floor ... - return parseMathOperation(Name, NameLoc, Operands); + Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); + + if (Next != StringRef::npos) { + // There is a format token in mnemonic. + size_t Dot = Name.find('.', Next + 1); + StringRef Format = Name.slice(Next, Dot); + if (Dot == StringRef::npos) // Only one '.' in a string, it's a format. + Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); + else { + if (Name.startswith("c.")) { + // Floating point compare, add '.' and immediate represent for cc. + Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); + int Cc = ConvertCcString(Format); + if (Cc == -1) { + return Error(NameLoc, "Invalid conditional code"); } - - // The rest is a format. - Format = Name.slice(Dot, StringRef::npos); - Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); + SMLoc E = SMLoc::getFromPointer( + Parser.getTok().getLoc().getPointer() - 1); + Operands.push_back( + MipsOperand::CreateImm(MCConstantExpr::Create(Cc, getContext()), + NameLoc, E)); + } else { + // trunc, ceil, floor ... + return parseMathOperation(Name, NameLoc, Operands); } - setFpFormat(Format); + // The rest is a format. + Format = Name.slice(Dot, StringRef::npos); + Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); } + + setFpFormat(Format); } // Read the remaining operands. diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index e2acf284da3..6b2b85963a3 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -151,7 +151,7 @@ class MTC1_FT_CCR; -class LW_FT : InstSE<(outs RC:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI> { @@ -159,7 +159,7 @@ class LW_FT : InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI> { @@ -180,7 +180,7 @@ class NMADDS_FT; -class LWXC1_FT : InstSE<(outs DRC:$fd), (ins PRC:$base, PRC:$index), !strconcat(opstr, "\t$fd, ${index}(${base})"), @@ -188,7 +188,7 @@ class LWXC1_FT : InstSE<(outs), (ins DRC:$fs, PRC:$base, PRC:$index), !strconcat(opstr, "\t$fs, ${index}(${base})"), @@ -304,73 +304,87 @@ def FMOV_D64 : ABSS_FT<"mov.d", FGR64, FGR64, IIFmove>, ABSS_FM<0x6, 17>, /// Floating Point Memory Instructions let Predicates = [IsN64, HasStdEnc], DecoderNamespace = "Mips64" in { - def LWC1_P8 : LW_FT<"lwc1", FGR32, IILoad, mem64, load>, LW_FM<0x31>; - def SWC1_P8 : SW_FT<"swc1", FGR32, IIStore, mem64, store>, LW_FM<0x39>; - def LDC164_P8 : LW_FT<"ldc1", FGR64, IILoad, mem64, load>, LW_FM<0x35> { + def LWC1_P8 : LW_FT<"lwc1", FGR32RegsOpnd, IILoad, mem64, load>, LW_FM<0x31>; + def SWC1_P8 : SW_FT<"swc1", FGR32RegsOpnd, IIStore, mem64, store>, + LW_FM<0x39>; + def LDC164_P8 : LW_FT<"ldc1", FGR64RegsOpnd, IILoad, mem64, load>, + LW_FM<0x35> { let isCodeGenOnly =1; } - def SDC164_P8 : SW_FT<"sdc1", FGR64, IIStore, mem64, store>, LW_FM<0x3d> { + def SDC164_P8 : SW_FT<"sdc1", FGR64RegsOpnd, IIStore, mem64, store>, + LW_FM<0x3d> { let isCodeGenOnly =1; } } let Predicates = [NotN64, HasStdEnc] in { - def LWC1 : LW_FT<"lwc1", FGR32, IILoad, mem, load>, LW_FM<0x31>; - def SWC1 : SW_FT<"swc1", FGR32, IIStore, mem, store>, LW_FM<0x39>; + def LWC1 : LW_FT<"lwc1", FGR32RegsOpnd, IILoad, mem, load>, LW_FM<0x31>; + def SWC1 : SW_FT<"swc1", FGR32RegsOpnd, IIStore, mem, store>, LW_FM<0x39>; } let Predicates = [NotN64, HasMips64, HasStdEnc], DecoderNamespace = "Mips64" in { - def LDC164 : LW_FT<"ldc1", FGR64, IILoad, mem, load>, LW_FM<0x35>; - def SDC164 : SW_FT<"sdc1", FGR64, IIStore, mem, store>, LW_FM<0x3d>; + def LDC164 : LW_FT<"ldc1", FGR64RegsOpnd, IILoad, mem, load>, LW_FM<0x35>; + def SDC164 : SW_FT<"sdc1", FGR64RegsOpnd, IIStore, mem, store>, LW_FM<0x3d>; } let Predicates = [NotN64, NotMips64, HasStdEnc] in { let isPseudo = 1, isCodeGenOnly = 1 in { - def PseudoLDC1 : LW_FT<"", AFGR64, IILoad, mem, load>; - def PseudoSDC1 : SW_FT<"", AFGR64, IIStore, mem, store>; + def PseudoLDC1 : LW_FT<"", AFGR64RegsOpnd, IILoad, mem, load>; + def PseudoSDC1 : SW_FT<"", AFGR64RegsOpnd, IIStore, mem, store>; } - def LDC1 : LW_FT<"ldc1", AFGR64, IILoad, mem>, LW_FM<0x35>; - def SDC1 : SW_FT<"sdc1", AFGR64, IIStore, mem>, LW_FM<0x3d>; + def LDC1 : LW_FT<"ldc1", AFGR64RegsOpnd, IILoad, mem>, LW_FM<0x35>; + def SDC1 : SW_FT<"sdc1", AFGR64RegsOpnd, IIStore, mem>, LW_FM<0x3d>; } // Indexed loads and stores. let Predicates = [HasFPIdx, HasStdEnc] in { - def LWXC1 : LWXC1_FT<"lwxc1", FGR32, CPURegs, IILoad, load>, LWXC1_FM<0>; - def SWXC1 : SWXC1_FT<"swxc1", FGR32, CPURegs, IIStore, store>, SWXC1_FM<8>; + def LWXC1 : LWXC1_FT<"lwxc1", FGR32RegsOpnd, CPURegsOpnd, IILoad, load>, + LWXC1_FM<0>; + def SWXC1 : SWXC1_FT<"swxc1", FGR32RegsOpnd, CPURegsOpnd, IIStore, store>, + SWXC1_FM<8>; } let Predicates = [HasMips32r2, NotMips64, HasStdEnc] in { - def LDXC1 : LWXC1_FT<"ldxc1", AFGR64, CPURegs, IILoad, load>, LWXC1_FM<1>; - def SDXC1 : SWXC1_FT<"sdxc1", AFGR64, CPURegs, IIStore, store>, SWXC1_FM<9>; + def LDXC1 : LWXC1_FT<"ldxc1", AFGR64RegsOpnd, CPURegsOpnd, IILoad, load>, + LWXC1_FM<1>; + def SDXC1 : SWXC1_FT<"sdxc1", AFGR64RegsOpnd, CPURegsOpnd, IIStore, store>, + SWXC1_FM<9>; } let Predicates = [HasMips64, NotN64, HasStdEnc], DecoderNamespace="Mips64" in { - def LDXC164 : LWXC1_FT<"ldxc1", FGR64, CPURegs, IILoad, load>, LWXC1_FM<1>; - def SDXC164 : SWXC1_FT<"sdxc1", FGR64, CPURegs, IIStore, store>, SWXC1_FM<9>; + def LDXC164 : LWXC1_FT<"ldxc1", FGR64RegsOpnd, CPURegsOpnd, IILoad, load>, + LWXC1_FM<1>; + def SDXC164 : SWXC1_FT<"sdxc1", FGR64RegsOpnd, CPURegsOpnd, IIStore, store>, + SWXC1_FM<9>; } // n64 let Predicates = [IsN64, HasStdEnc], isCodeGenOnly=1 in { - def LWXC1_P8 : LWXC1_FT<"lwxc1", FGR32, CPU64Regs, IILoad, load>, LWXC1_FM<0>; - def LDXC164_P8 : LWXC1_FT<"ldxc1", FGR64, CPU64Regs, IILoad, load>, - LWXC1_FM<1>; - def SWXC1_P8 : SWXC1_FT<"swxc1", FGR32, CPU64Regs, IIStore, store>, - SWXC1_FM<8>; - def SDXC164_P8 : SWXC1_FT<"sdxc1", FGR64, CPU64Regs, IIStore, store>, - SWXC1_FM<9>; + def LWXC1_P8 : LWXC1_FT<"lwxc1", FGR32RegsOpnd, CPU64RegsOpnd, IILoad, load>, + LWXC1_FM<0>; + def LDXC164_P8 : LWXC1_FT<"ldxc1", FGR64RegsOpnd, CPU64RegsOpnd, IILoad, + load>, LWXC1_FM<1>; + def SWXC1_P8 : SWXC1_FT<"swxc1", FGR32RegsOpnd, CPU64RegsOpnd, IIStore, + store>, SWXC1_FM<8>; + def SDXC164_P8 : SWXC1_FT<"sdxc1", FGR64RegsOpnd, CPU64RegsOpnd, IIStore, + store>, SWXC1_FM<9>; } // Load/store doubleword indexed unaligned. let Predicates = [NotMips64, HasStdEnc] in { - def LUXC1 : LWXC1_FT<"luxc1", AFGR64, CPURegs, IILoad>, LWXC1_FM<0x5>; - def SUXC1 : SWXC1_FT<"suxc1", AFGR64, CPURegs, IIStore>, SWXC1_FM<0xd>; + def LUXC1 : LWXC1_FT<"luxc1", AFGR64RegsOpnd, CPURegsOpnd, IILoad>, + LWXC1_FM<0x5>; + def SUXC1 : SWXC1_FT<"suxc1", AFGR64RegsOpnd, CPURegsOpnd, IIStore>, + SWXC1_FM<0xd>; } let Predicates = [HasMips64, HasStdEnc], DecoderNamespace="Mips64" in { - def LUXC164 : LWXC1_FT<"luxc1", FGR64, CPURegs, IILoad>, LWXC1_FM<0x5>; - def SUXC164 : SWXC1_FT<"suxc1", FGR64, CPURegs, IIStore>, SWXC1_FM<0xd>; + def LUXC164 : LWXC1_FT<"luxc1", FGR64RegsOpnd, CPURegsOpnd, IILoad>, + LWXC1_FM<0x5>; + def SUXC164 : SWXC1_FT<"suxc1", FGR64RegsOpnd, CPURegsOpnd, IIStore>, + SWXC1_FM<0xd>; } /// Floating-point Aritmetic diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td index d98cb2179b5..36870842e6b 100644 --- a/lib/Target/Mips/MipsRegisterInfo.td +++ b/lib/Target/Mips/MipsRegisterInfo.td @@ -407,6 +407,21 @@ def CCRAsmOperand : MipsAsmRegOperand { let ParserMethod = "parseCCRRegs"; } +def AFGR64AsmOperand : MipsAsmRegOperand { + let Name = "AFGR64Asm"; + let ParserMethod = "parseAFGR64Regs"; +} + +def FGR64AsmOperand : MipsAsmRegOperand { + let Name = "FGR64Asm"; + let ParserMethod = "parseFGR64Regs"; +} + +def FGR32AsmOperand : MipsAsmRegOperand { + let Name = "FGR32Asm"; + let ParserMethod = "parseFGR32Regs"; +} + def CPURegsOpnd : RegisterOperand { let ParserMatchClass = CPURegsAsmOperand; } @@ -436,3 +451,15 @@ def HWRegsOpnd : RegisterOperand { def HW64RegsOpnd : RegisterOperand { let ParserMatchClass = HW64RegsAsmOperand; } + +def AFGR64RegsOpnd : RegisterOperand { + let ParserMatchClass = AFGR64AsmOperand; +} + +def FGR64RegsOpnd : RegisterOperand { + let ParserMatchClass = FGR64AsmOperand; +} + +def FGR32RegsOpnd : RegisterOperand { + let ParserMatchClass = FGR32AsmOperand; +} \ No newline at end of file