MipsAsmParser::OperandMatchResultTy
parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+ MipsAsmParser::OperandMatchResultTy
+ parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
unsigned RegKind);
FpFormatTy getFpFormat() {return FpFormat;}
- bool requestsDoubleOperand(StringRef Mnemonic);
-
unsigned getReg(int RC, int RegNo);
int getATReg();
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;
FpFormat = FP_FORMAT_S;
}
-bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){
-
- bool IsDouble = StringSwitch<bool>(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<FpFormatTy>(Format.lower())
return parseRegs(Operands, (int) MipsOperand::Kind_CPURegs);
}
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &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<MCParsedAsmOperand*> &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<MCParsedAsmOperand*> &Operands) {
+ // Single operand is expected, set appropriate format
+ setFpFormat(FP_FORMAT_S);
+ return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
+}
+
bool MipsAsmParser::searchSymbolAlias(
SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &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));
-
- 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);
- }
- // The rest is a format.
- Format = Name.slice(Dot, StringRef::npos);
- Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
+ 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));
+
+ 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);
}
- 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.
InstSE<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"),
[(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR>;
-class LW_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
+class LW_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
Operand MemOpnd, SDPatternOperator OpNode= null_frag> :
InstSE<(outs RC:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
[(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI> {
let mayLoad = 1;
}
-class SW_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
+class SW_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
Operand MemOpnd, SDPatternOperator OpNode= null_frag> :
InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
[(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI> {
[(set RC:$fd, (fsub fpimm0, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr)))],
Itin, FrmFR>;
-class LWXC1_FT<string opstr, RegisterClass DRC, RegisterClass PRC,
+class LWXC1_FT<string opstr, RegisterOperand DRC, RegisterOperand PRC,
InstrItinClass Itin, SDPatternOperator OpNode = null_frag> :
InstSE<(outs DRC:$fd), (ins PRC:$base, PRC:$index),
!strconcat(opstr, "\t$fd, ${index}(${base})"),
let AddedComplexity = 20;
}
-class SWXC1_FT<string opstr, RegisterClass DRC, RegisterClass PRC,
+class SWXC1_FT<string opstr, RegisterOperand DRC, RegisterOperand PRC,
InstrItinClass Itin, SDPatternOperator OpNode = null_frag> :
InstSE<(outs), (ins DRC:$fs, PRC:$base, PRC:$index),
!strconcat(opstr, "\t$fs, ${index}(${base})"),
/// 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