diff options
author | Stephen Hines <srhines@google.com> | 2013-08-07 15:07:10 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2013-08-07 15:07:10 -0700 |
commit | fab2daa4a1127ecb217abe2b07c1769122b6fee1 (patch) | |
tree | 268ebfd1963fd98ba412e76819afdf95a7d4267b /lib/Target/Mips | |
parent | 8197ac1c1a0a91baa70c4dea8cb488f254ef974c (diff) | |
parent | 10251753b6897adcd22cc981c0cc42f348c109de (diff) | |
download | external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.zip external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.tar.gz external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.tar.bz2 |
Merge commit '10251753b6897adcd22cc981c0cc42f348c109de' into merge-20130807
Conflicts:
lib/Archive/ArchiveReader.cpp
lib/Support/Unix/PathV2.inc
Change-Id: I29d8c1e321a4a380b6013f00bac6a8e4b593cc4e
Diffstat (limited to 'lib/Target/Mips')
48 files changed, 1947 insertions, 1521 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index d1d69d8..3dd6562 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -78,19 +78,20 @@ class MipsAsmParser : public MCTargetAsmParser { SMLoc NameLoc, SmallVectorImpl<MCParsedAsmOperand*> &Operands); - bool parseMathOperation(StringRef Name, SMLoc NameLoc, - SmallVectorImpl<MCParsedAsmOperand*> &Operands); - bool ParseDirective(AsmToken DirectiveID); MipsAsmParser::OperandMatchResultTy + parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands, + int RegKind); + + MipsAsmParser::OperandMatchResultTy parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); MipsAsmParser::OperandMatchResultTy - parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands); MipsAsmParser::OperandMatchResultTy - parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands); MipsAsmParser::OperandMatchResultTy parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); @@ -101,8 +102,23 @@ class MipsAsmParser : public MCTargetAsmParser { MipsAsmParser::OperandMatchResultTy parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + MipsAsmParser::OperandMatchResultTy + parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + + MipsAsmParser::OperandMatchResultTy + parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + + MipsAsmParser::OperandMatchResultTy + parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + + MipsAsmParser::OperandMatchResultTy + parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + + MipsAsmParser::OperandMatchResultTy + parseACRegsDSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands, - unsigned RegisterClass); + unsigned RegKind); bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); @@ -162,6 +178,8 @@ class MipsAsmParser : public MCTargetAsmParser { int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); + int matchFPURegisterName(StringRef Name, FpFormatTy Format); + void setFpFormat(FpFormatTy Format) { FpFormat = Format; } @@ -172,8 +190,6 @@ class MipsAsmParser : public MCTargetAsmParser { FpFormatTy getFpFormat() {return FpFormat;} - bool requestsDoubleOperand(StringRef Mnemonic); - unsigned getReg(int RC, int RegNo); int getATReg(); @@ -202,14 +218,16 @@ class MipsOperand : public MCParsedAsmOperand { public: enum RegisterKind { Kind_None, - Kind_CPURegs, - Kind_CPU64Regs, + Kind_GPR32, + Kind_GPR64, Kind_HWRegs, Kind_HW64Regs, Kind_FGR32Regs, Kind_FGR64Regs, Kind_AFGR64Regs, - Kind_CCRRegs + Kind_CCRRegs, + Kind_FCCRegs, + Kind_ACRegsDSP }; private: @@ -354,45 +372,52 @@ public: return Op; } - bool isCPURegsAsm() const { - return Kind == k_Register && Reg.Kind == Kind_CPURegs; + bool isGPR32Asm() const { + return Kind == k_Register && Reg.Kind == Kind_GPR32; } - void addCPURegsAsmOperands(MCInst &Inst, unsigned N) const { + void addRegAsmOperands(MCInst &Inst, unsigned N) const { Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); } - bool isCPU64RegsAsm() const { - return Kind == k_Register && Reg.Kind == Kind_CPU64Regs; - } - void addCPU64RegsAsmOperands(MCInst &Inst, unsigned N) const { - Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); + bool isGPR64Asm() const { + return Kind == k_Register && Reg.Kind == Kind_GPR64; } bool isHWRegsAsm() const { assert((Kind == k_Register) && "Invalid access!"); return Reg.Kind == Kind_HWRegs; } - void addHWRegsAsmOperands(MCInst &Inst, unsigned N) const { - Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); - } bool isHW64RegsAsm() const { assert((Kind == k_Register) && "Invalid access!"); return Reg.Kind == Kind_HW64Regs; } - void addHW64RegsAsmOperands(MCInst &Inst, unsigned N) const { - Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); - } - - void addCCRAsmOperands(MCInst &Inst, unsigned N) const { - Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); - } bool isCCRAsm() const { assert((Kind == k_Register) && "Invalid access!"); 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; + } + + bool isFCCRegsAsm() const { + return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs; + } + + bool isACRegsDSPAsm() const { + return Kind == k_Register && Reg.Kind == Kind_ACRegsDSP; + } + /// getStartLoc - Get the location of the first token of this operand. SMLoc getStartLoc() const { return StartLoc; @@ -624,8 +649,8 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, unsigned ImmOffset, HiOffset, LoOffset; const MCExpr *ExprOffset; unsigned TmpRegNum; - unsigned AtRegNum = getReg((isMips64()) ? Mips::CPU64RegsRegClassID - : Mips::CPURegsRegClassID, getATReg()); + unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID + : Mips::GPR32RegClassID, getATReg()); // 1st operand is either the source or destination register. assert(Inst.getOperand(0).isReg() && "expected register operand kind"); unsigned RegOpNum = Inst.getOperand(0).getReg(); @@ -800,16 +825,7 @@ int MipsAsmParser::matchCPURegisterName(StringRef Name) { return CC; } -int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { - - if (Name.equals("fcc0")) - return Mips::FCC0; - - int CC; - CC = matchCPURegisterName(Name); - if (CC != -1) - return matchRegisterByNumber(CC, is64BitReg ? Mips::CPU64RegsRegClassID - : Mips::CPURegsRegClassID); +int MipsAsmParser::matchFPURegisterName(StringRef Name, FpFormatTy Format) { if (Name[0] == 'f') { StringRef NumString = Name.substr(1); @@ -819,8 +835,6 @@ int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { if (IntVal > 31) return -1; - FpFormatTy Format = getFpFormat(); - if (Format == FP_FORMAT_S || Format == FP_FORMAT_W) return getReg(Mips::FGR32RegClassID, IntVal); if (Format == FP_FORMAT_D) { @@ -833,10 +847,22 @@ int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { return getReg(Mips::AFGR64RegClassID, IntVal / 2); } } - return -1; } +int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { + + if (Name.equals("fcc0")) + return Mips::FCC0; + + int CC; + CC = matchCPURegisterName(Name); + if (CC != -1) + return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID + : Mips::GPR32RegClassID); + return matchFPURegisterName(Name, getFpFormat()); +} + void MipsAsmParser::setDefaultFpFormat() { if (isMips64() || isFP64()) @@ -845,18 +871,6 @@ void MipsAsmParser::setDefaultFpFormat() { 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()) @@ -880,7 +894,7 @@ int MipsAsmParser::getATReg() { } unsigned MipsAsmParser::getReg(int RC, int RegNo) { - return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo); + return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); } int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { @@ -900,7 +914,7 @@ int MipsAsmParser::tryParseRegister(bool is64BitReg) { RegNum = matchRegisterName(lowerCase, is64BitReg); } else if (Tok.is(AsmToken::Integer)) RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()), - is64BitReg ? Mips::CPU64RegsRegClassID : Mips::CPURegsRegClassID); + is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID); return RegNum; } @@ -1253,12 +1267,11 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( } MipsAsmParser::OperandMatchResultTy -MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { - - if (!isMips64()) - return MatchOperand_NoMatch; +MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands, + int RegKind) { + MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; if (getLexer().getKind() == AsmToken::Identifier) { - if (searchSymbolAlias(Operands, MipsOperand::Kind_CPU64Regs)) + if (searchSymbolAlias(Operands, Kind)) return MatchOperand_Success; return MatchOperand_NoMatch; } @@ -1267,17 +1280,137 @@ MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { return MatchOperand_NoMatch; Parser.Lex(); // Eat $ - if (!tryParseRegisterOperand(Operands, true)) { + if (!tryParseRegisterOperand(Operands, + RegKind == MipsOperand::Kind_GPR64)) { // Set the proper register kind. MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); - op->setRegKind(MipsOperand::Kind_CPU64Regs); + op->setRegKind(Kind); + if ((Kind == MipsOperand::Kind_GPR32) + && (getLexer().is(AsmToken::LParen))) { + // Check if it is indexed addressing operand. + Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); + Parser.Lex(); // Eat the parenthesis. + if (parseRegs(Operands,RegKind) != MatchOperand_Success) + return MatchOperand_NoMatch; + if (getLexer().isNot(AsmToken::RParen)) + return MatchOperand_NoMatch; + Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); + Parser.Lex(); + } return MatchOperand_Success; } return MatchOperand_NoMatch; } +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { + + if (!isMips64()) + return MatchOperand_NoMatch; + return parseRegs(Operands, (int) MipsOperand::Kind_GPR64); +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { + return parseRegs(Operands, (int) MipsOperand::Kind_GPR32); +} + +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); +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { + // If the first token is not '$' we have an error. + if (Parser.getTok().isNot(AsmToken::Dollar)) + return MatchOperand_NoMatch; + + SMLoc S = Parser.getTok().getLoc(); + Parser.Lex(); // Eat the '$' + + const AsmToken &Tok = Parser.getTok(); // Get next token. + + if (Tok.isNot(AsmToken::Identifier)) + return MatchOperand_NoMatch; + + if (!Tok.getIdentifier().startswith("fcc")) + return MatchOperand_NoMatch; + + StringRef NumString = Tok.getIdentifier().substr(3); + + unsigned IntVal; + if (NumString.getAsInteger(10, IntVal)) + return MatchOperand_NoMatch; + + unsigned Reg = matchRegisterByNumber(IntVal, Mips::FCCRegClassID); + + MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); + Op->setRegKind(MipsOperand::Kind_FCCRegs); + Operands.push_back(Op); + + Parser.Lex(); // Eat the register number. + return MatchOperand_Success; +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseACRegsDSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { + // If the first token is not '$' we have an error. + if (Parser.getTok().isNot(AsmToken::Dollar)) + return MatchOperand_NoMatch; + + SMLoc S = Parser.getTok().getLoc(); + Parser.Lex(); // Eat the '$' + + const AsmToken &Tok = Parser.getTok(); // Get next token. + + if (Tok.isNot(AsmToken::Identifier)) + return MatchOperand_NoMatch; + + if (!Tok.getIdentifier().startswith("acc")) + return MatchOperand_NoMatch; + + StringRef NumString = Tok.getIdentifier().substr(3); + + unsigned IntVal; + if (NumString.getAsInteger(10, IntVal)) + return MatchOperand_NoMatch; + + unsigned Reg = matchRegisterByNumber(IntVal, Mips::ACRegsDSPRegClassID); + + MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); + Op->setRegKind(MipsOperand::Kind_ACRegsDSP); + Operands.push_back(Op); + + Parser.Lex(); // Eat the register number. + return MatchOperand_Success; +} + bool MipsAsmParser::searchSymbolAlias( - SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegisterKind) { + SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) { MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); if (Sym) { @@ -1288,6 +1421,7 @@ bool MipsAsmParser::searchSymbolAlias( else return false; if (Expr->getKind() == MCExpr::SymbolRef) { + MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind; const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); const StringRef DefSymbol = Ref->getSymbol().getName(); if (DefSymbol.startswith("$")) { @@ -1295,17 +1429,31 @@ bool MipsAsmParser::searchSymbolAlias( APInt IntVal(32, -1); if (!DefSymbol.substr(1).getAsInteger(10, IntVal)) RegNum = matchRegisterByNumber(IntVal.getZExtValue(), - isMips64() - ? Mips::CPU64RegsRegClassID - : Mips::CPURegsRegClassID); - else - // Lookup for the register with corresponding name - RegNum = matchRegisterName(DefSymbol.substr(1), isMips64()); + isMips64() + ? Mips::GPR64RegClassID + : Mips::GPR32RegClassID); + else { + // Lookup for the register with the corresponding name. + switch (Kind) { + case MipsOperand::Kind_AFGR64Regs: + case MipsOperand::Kind_FGR64Regs: + RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_D); + break; + case MipsOperand::Kind_FGR32Regs: + RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_S); + break; + case MipsOperand::Kind_GPR64: + case MipsOperand::Kind_GPR32: + default: + RegNum = matchRegisterName(DefSymbol.substr(1), isMips64()); + break; + } + } if (RegNum > -1) { Parser.Lex(); MipsOperand *op = MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc()); - op->setRegKind((MipsOperand::RegisterKind) RegisterKind); + op->setRegKind(Kind); Operands.push_back(op); return true; } @@ -1314,7 +1462,7 @@ bool MipsAsmParser::searchSymbolAlias( Parser.Lex(); const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr); MipsOperand *op = MipsOperand::CreateImm(Const, S, - Parser.getTok().getLoc()); + Parser.getTok().getLoc()); Operands.push_back(op); return true; } @@ -1323,33 +1471,8 @@ bool MipsAsmParser::searchSymbolAlias( } MipsAsmParser::OperandMatchResultTy -MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { - - if (getLexer().getKind() == AsmToken::Identifier) { - if (searchSymbolAlias(Operands, MipsOperand::Kind_CPURegs)) - return MatchOperand_Success; - return MatchOperand_NoMatch; - } - // If the first token is not '$' we have an error. - if (Parser.getTok().isNot(AsmToken::Dollar)) - return MatchOperand_NoMatch; - - Parser.Lex(); // Eat $ - if (!tryParseRegisterOperand(Operands, false)) { - // Set the proper register kind. - MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); - op->setRegKind(MipsOperand::Kind_CPURegs); - return MatchOperand_Success; - } - return MatchOperand_NoMatch; -} - -MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { - if (isMips64()) - return MatchOperand_NoMatch; - // If the first token is not '$' we have error. if (Parser.getTok().isNot(AsmToken::Dollar)) return MatchOperand_NoMatch; @@ -1406,30 +1529,23 @@ MipsAsmParser::parseHW64Regs( MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { - unsigned RegNum; // If the first token is not '$' we have an error. if (Parser.getTok().isNot(AsmToken::Dollar)) return MatchOperand_NoMatch; + SMLoc S = Parser.getTok().getLoc(); Parser.Lex(); // Eat the '$' const AsmToken &Tok = Parser.getTok(); // Get next token. - if (Tok.is(AsmToken::Integer)) { - RegNum = Tok.getIntVal(); - // At the moment only fcc0 is supported. - if (RegNum != 0) - return MatchOperand_ParseFail; - } else if (Tok.is(AsmToken::Identifier)) { - // At the moment only fcc0 is supported. - if (Tok.getIdentifier() != "fcc0") - return MatchOperand_ParseFail; - } else + + if (Tok.isNot(AsmToken::Integer)) return MatchOperand_NoMatch; - MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S, - Parser.getTok().getLoc()); - op->setRegKind(MipsOperand::Kind_CCRRegs); - Operands.push_back(op); + unsigned Reg = matchRegisterByNumber(Tok.getIntVal(), Mips::CCRRegClassID); + + MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); + Op->setRegKind(MipsOperand::Kind_CCRRegs); + Operands.push_back(Op); Parser.Lex(); // Eat the register number. return MatchOperand_Success; @@ -1460,136 +1576,22 @@ MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { return VK; } -// Converts condition string to immediate operand value. -static int ConvertCcString(StringRef CondString) { - int CC = StringSwitch<unsigned>(CondString) - .Case(".f", 0) - .Case(".un", 1) - .Case(".eq", 2) - .Case(".ueq", 3) - .Case(".olt", 4) - .Case(".ult", 5) - .Case(".ole", 6) - .Case(".ule", 7) - .Case(".sf", 8) - .Case(".ngle", 9) - .Case(".seq", 10) - .Case(".ngl", 11) - .Case(".lt", 12) - .Case(".nge", 13) - .Case(".le", 14) - .Case(".ngt", 15) - .Default(-1); - - return CC; -} - -bool MipsAsmParser:: -parseMathOperation(StringRef Name, SMLoc NameLoc, - SmallVectorImpl<MCParsedAsmOperand*> &Operands) { - // Split the format. - size_t Start = Name.find('.'), Next = Name.rfind('.'); - StringRef Format1 = Name.slice(Start, Next); - // Add the first format to the operands. - Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc)); - // Now for the second format. - StringRef Format2 = Name.slice(Next, StringRef::npos); - Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc)); - - // Set the format for the first register. - setFpFormat(Format1); - - // Read the remaining operands. - if (getLexer().isNot(AsmToken::EndOfStatement)) { - // Read the first operand. - if (ParseOperand(Operands, Name)) { - SMLoc Loc = getLexer().getLoc(); - Parser.eatToEndOfStatement(); - return Error(Loc, "unexpected token in argument list"); - } - - if (getLexer().isNot(AsmToken::Comma)) { - SMLoc Loc = getLexer().getLoc(); - Parser.eatToEndOfStatement(); - return Error(Loc, "unexpected token in argument list"); - } - Parser.Lex(); // Eat the comma. - - // Set the format for the first register - setFpFormat(Format2); - - // Parse and remember the operand. - if (ParseOperand(Operands, Name)) { - SMLoc Loc = getLexer().getLoc(); - Parser.eatToEndOfStatement(); - return Error(Loc, "unexpected token in argument list"); - } - } - - if (getLexer().isNot(AsmToken::EndOfStatement)) { - SMLoc Loc = getLexer().getLoc(); - Parser.eatToEndOfStatement(); - return Error(Loc, "unexpected token in argument list"); - } - - Parser.Lex(); // Consume the EndOfStatement. - return false; -} bool MipsAsmParser:: 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)); - } - - setFpFormat(Format); - } + // Check if we have valid mnemonic + if (!mnemonicIsValid(Name, 0)) { + Parser.eatToEndOfStatement(); + return Error(NameLoc, "Unknown instruction"); } + // First operand in MCInst is instruction mnemonic. + Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); // Read the remaining operands. if (getLexer().isNot(AsmToken::EndOfStatement)) { // Read the first operand. - if (ParseOperand(Operands, Mnemonic)) { + if (ParseOperand(Operands, Name)) { SMLoc Loc = getLexer().getLoc(); Parser.eatToEndOfStatement(); return Error(Loc, "unexpected token in argument list"); @@ -1597,7 +1599,6 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, while (getLexer().is(AsmToken::Comma)) { Parser.Lex(); // Eat the comma. - // Parse and remember the operand. if (ParseOperand(Operands, Name)) { SMLoc Loc = getLexer().getLoc(); @@ -1606,13 +1607,11 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, } } } - if (getLexer().isNot(AsmToken::EndOfStatement)) { SMLoc Loc = getLexer().getLoc(); Parser.eatToEndOfStatement(); return Error(Loc, "unexpected token in argument list"); } - Parser.Lex(); // Consume the EndOfStatement. return false; } diff --git a/lib/Target/Mips/CMakeLists.txt b/lib/Target/Mips/CMakeLists.txt index 834a998..aedb78b 100644 --- a/lib/Target/Mips/CMakeLists.txt +++ b/lib/Target/Mips/CMakeLists.txt @@ -48,10 +48,11 @@ add_llvm_target(MipsCodeGen MipsSelectionDAGInfo.cpp ) -add_dependencies(LLVMMipsCodeGen intrinsics_gen) +add_dependencies(LLVMMipsCodeGen MipsCommonTableGen intrinsics_gen) add_subdirectory(InstPrinter) add_subdirectory(Disassembler) add_subdirectory(TargetInfo) add_subdirectory(MCTargetDesc) add_subdirectory(AsmParser) + diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 4af6703..d99df4d 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -39,10 +39,10 @@ public: virtual ~MipsDisassemblerBase() {} - const MCRegisterInfo *getRegInfo() const { return RegInfo; } + const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } private: - const MCRegisterInfo *RegInfo; + OwningPtr<const MCRegisterInfo> RegInfo; protected: bool isBigEndian; }; @@ -88,20 +88,20 @@ public: // Forward declare these because the autogenerated code will reference them. // Definitions are further down. -static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); +static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); -static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); +static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst, unsigned RegNo, @@ -123,6 +123,11 @@ static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -133,11 +138,6 @@ static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); -static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -158,12 +158,6 @@ static DecodeStatus DecodeBranchTarget(MCInst &Inst, uint64_t Address, const void *Decoder); -static DecodeStatus DecodeBC1(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - - static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -183,11 +177,6 @@ static DecodeStatus DecodeSimm16(MCInst &Inst, uint64_t Address, const void *Decoder); -static DecodeStatus DecodeCondCode(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -346,26 +335,26 @@ static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, } -static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { +static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { if (RegNo > 31) return MCDisassembler::Fail; - unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo); + unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); Inst.addOperand(MCOperand::CreateReg(Reg)); return MCDisassembler::Success; } -static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { +static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { if (RegNo > 31) return MCDisassembler::Fail; - unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo); + unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); Inst.addOperand(MCOperand::CreateReg(Reg)); return MCDisassembler::Success; } @@ -374,7 +363,7 @@ static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder); + return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); } static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, @@ -405,7 +394,21 @@ static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - Inst.addOperand(MCOperand::CreateReg(RegNo)); + if (RegNo > 31) + return MCDisassembler::Fail; + unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); + Inst.addOperand(MCOperand::CreateReg(Reg)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 7) + return MCDisassembler::Fail; + unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); + Inst.addOperand(MCOperand::CreateReg(Reg)); return MCDisassembler::Success; } @@ -417,8 +420,8 @@ static DecodeStatus DecodeMem(MCInst &Inst, unsigned Reg = fieldFromInstruction(Insn, 16, 5); unsigned Base = fieldFromInstruction(Insn, 21, 5); - Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg); - Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); + Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); if(Inst.getOpcode() == Mips::SC){ Inst.addOperand(MCOperand::CreateReg(Reg)); @@ -440,7 +443,7 @@ static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Base = fieldFromInstruction(Insn, 21, 5); Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); - Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); Inst.addOperand(MCOperand::CreateReg(Reg)); Inst.addOperand(MCOperand::CreateReg(Base)); @@ -461,15 +464,6 @@ static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, return MCDisassembler::Success; } -static DecodeStatus DecodeCondCode(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - int CondCode = Insn & 0xf; - Inst.addOperand(MCOperand::CreateImm(CondCode)); - return MCDisassembler::Success; -} - static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -483,17 +477,6 @@ static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, return MCDisassembler::Success; } -static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - //Currently only hardware register 29 is supported - if (RegNo != 29) - return MCDisassembler::Fail; - Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64)); - return MCDisassembler::Success; -} - static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -540,16 +523,6 @@ static DecodeStatus DecodeBranchTarget(MCInst &Inst, return MCDisassembler::Success; } -static DecodeStatus DecodeBC1(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - unsigned BranchOffset = Insn & 0xffff; - BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; - Inst.addOperand(MCOperand::CreateImm(BranchOffset)); - return MCDisassembler::Success; -} - static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp index fc23cd3..369fece 100644 --- a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp +++ b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp @@ -26,6 +26,12 @@ using namespace llvm; #define PRINT_ALIAS_INSTR #include "MipsGenAsmWriter.inc" +template<unsigned R> +static bool isReg(const MCInst &MI, unsigned OpNo) { + assert(MI.getOperand(OpNo).isReg() && "Register operand expected."); + return MI.getOperand(OpNo).getReg() == R; +} + const char* Mips::MipsFCCToString(Mips::CondCode CC) { switch (CC) { case FCOND_F: @@ -80,7 +86,7 @@ void MipsInstPrinter::printInst(const MCInst *MI, raw_ostream &O, } // Try to print any aliases first. - if (!printAliasInstr(MI, O)) + if (!printAliasInstr(MI, O) && !printAlias(*MI, O)) printInstruction(MI, O); printAnnotation(O, Annot); @@ -152,11 +158,6 @@ static void printExpr(const MCExpr *Expr, raw_ostream &OS) { OS << ')'; } -void MipsInstPrinter::printCPURegs(const MCInst *MI, unsigned OpNo, - raw_ostream &O) { - printRegName(O, MI->getOperand(OpNo).getReg()); -} - void MipsInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); @@ -209,3 +210,61 @@ printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O) { const MCOperand& MO = MI->getOperand(opNum); O << MipsFCCToString((Mips::CondCode)MO.getImm()); } + +bool MipsInstPrinter::printAlias(const char *Str, const MCInst &MI, + unsigned OpNo, raw_ostream &OS) { + OS << "\t" << Str << "\t"; + printOperand(&MI, OpNo, OS); + return true; +} + +bool MipsInstPrinter::printAlias(const char *Str, const MCInst &MI, + unsigned OpNo0, unsigned OpNo1, + raw_ostream &OS) { + printAlias(Str, MI, OpNo0, OS); + OS << ", "; + printOperand(&MI, OpNo1, OS); + return true; +} + +bool MipsInstPrinter::printAlias(const MCInst &MI, raw_ostream &OS) { + switch (MI.getOpcode()) { + case Mips::BEQ: + // beq $r0, $zero, $L2 => beqz $r0, $L2 + return isReg<Mips::ZERO>(MI, 1) && printAlias("beqz", MI, 0, 2, OS); + case Mips::BEQ64: + // beq $r0, $zero, $L2 => beqz $r0, $L2 + return isReg<Mips::ZERO_64>(MI, 1) && printAlias("beqz", MI, 0, 2, OS); + case Mips::BNE: + // bne $r0, $zero, $L2 => bnez $r0, $L2 + return isReg<Mips::ZERO>(MI, 1) && printAlias("bnez", MI, 0, 2, OS); + case Mips::BNE64: + // bne $r0, $zero, $L2 => bnez $r0, $L2 + return isReg<Mips::ZERO_64>(MI, 1) && printAlias("bnez", MI, 0, 2, OS); + case Mips::BGEZAL: + // bgezal $zero, $L1 => bal $L1 + return isReg<Mips::ZERO>(MI, 0) && printAlias("bal", MI, 1, OS); + case Mips::BC1T: + // bc1t $fcc0, $L1 => bc1t $L1 + return isReg<Mips::FCC0>(MI, 0) && printAlias("bc1t", MI, 1, OS); + case Mips::BC1F: + // bc1f $fcc0, $L1 => bc1f $L1 + return isReg<Mips::FCC0>(MI, 0) && printAlias("bc1f", MI, 1, OS); + case Mips::JALR: + // jalr $ra, $r1 => jalr $r1 + return isReg<Mips::RA>(MI, 0) && printAlias("jalr", MI, 1, OS); + case Mips::JALR64: + // jalr $ra, $r1 => jalr $r1 + return isReg<Mips::RA_64>(MI, 0) && printAlias("jalr", MI, 1, OS); + case Mips::NOR: + // nor $r0, $r1, $zero => not $r0, $r1 + return isReg<Mips::ZERO>(MI, 2) && printAlias("not", MI, 0, 1, OS); + case Mips::NOR64: + // nor $r0, $r1, $zero => not $r0, $r1 + return isReg<Mips::ZERO_64>(MI, 2) && printAlias("not", MI, 0, 1, OS); + case Mips::OR: + // or $r0, $r1, $zero => move $r0, $r1 + return isReg<Mips::ZERO>(MI, 2) && printAlias("move", MI, 0, 1, OS); + default: return false; + } +} diff --git a/lib/Target/Mips/InstPrinter/MipsInstPrinter.h b/lib/Target/Mips/InstPrinter/MipsInstPrinter.h index d1b561f..1253ab0 100644 --- a/lib/Target/Mips/InstPrinter/MipsInstPrinter.h +++ b/lib/Target/Mips/InstPrinter/MipsInstPrinter.h @@ -87,7 +87,6 @@ public: virtual void printRegName(raw_ostream &OS, unsigned RegNo) const; virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot); - void printCPURegs(const MCInst *MI, unsigned OpNo, raw_ostream &O); bool printAliasInstr(const MCInst *MI, raw_ostream &OS); @@ -97,6 +96,12 @@ 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); + + bool printAlias(const char *Str, const MCInst &MI, unsigned OpNo, + raw_ostream &OS); + bool printAlias(const char *Str, const MCInst &MI, unsigned OpNo0, + unsigned OpNo1, raw_ostream &OS); + bool printAlias(const MCInst &MI, raw_ostream &OS); }; } // end namespace llvm diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp index c33bc9a..cfcb877 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp @@ -36,6 +36,10 @@ namespace llvm { MCAssembler& MCA = getAssembler(); unsigned EFlags = MCA.getELFHeaderEFlags(); + // TODO: Need to add -mabicalls and -mno-abicalls flags. + // Currently we assume that -mabicalls is the default. + EFlags |= ELF::EF_MIPS_CPIC; + if (Subtarget.inMips16Mode()) EFlags |= ELF::EF_MIPS_ARCH_ASE_M16; else diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index a464dfe..4dc6917 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -380,7 +380,7 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO, SmallVectorImpl<MCFixup> &Fixups) const { if (MO.isReg()) { unsigned Reg = MO.getReg(); - unsigned RegNo = Ctx.getRegisterInfo().getEncodingValue(Reg); + unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); return RegNo; } else if (MO.isImm()) { return static_cast<unsigned>(MO.getImm()); diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 7a42719..249d712 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -1,69 +1,67 @@ let isCodeGenOnly = 1 in { /// Arithmetic Instructions (ALU Immediate) - def ADDiu_MM : MMRel, ArithLogicI<"addiu", simm16, CPURegsOpnd>, + def ADDiu_MM : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd>, ADDI_FM_MM<0xc>; - def ADDi_MM : MMRel, ArithLogicI<"addi", simm16, CPURegsOpnd>, + def ADDi_MM : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM_MM<0x4>; - def SLTi_MM : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>, + def SLTi_MM : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>, SLTI_FM_MM<0x24>; - def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>, + def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>, SLTI_FM_MM<0x2c>; - def ANDi_MM : MMRel, ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, - and>, + def ANDi_MM : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd>, ADDI_FM_MM<0x34>; - def ORi_MM : MMRel, ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>, + def ORi_MM : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd>, ADDI_FM_MM<0x14>; - def XORi_MM : MMRel, ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, - xor>, + def XORi_MM : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd>, ADDI_FM_MM<0x1c>; - def LUi_MM : MMRel, LoadUpper<"lui", CPURegs, uimm16>, LUI_FM_MM; + def LUi_MM : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM_MM; /// Arithmetic Instructions (3-Operand, R-Type) - def ADDu_MM : MMRel, ArithLogicR<"addu", CPURegsOpnd>, ADD_FM_MM<0, 0x150>; - def SUBu_MM : MMRel, ArithLogicR<"subu", CPURegsOpnd>, ADD_FM_MM<0, 0x1d0>; - def MUL_MM : MMRel, ArithLogicR<"mul", CPURegsOpnd>, ADD_FM_MM<0, 0x210>; - def ADD_MM : MMRel, ArithLogicR<"add", CPURegsOpnd>, ADD_FM_MM<0, 0x110>; - def SUB_MM : MMRel, ArithLogicR<"sub", CPURegsOpnd>, ADD_FM_MM<0, 0x190>; - def SLT_MM : MMRel, SetCC_R<"slt", setlt, CPURegs>, ADD_FM_MM<0, 0x350>; - def SLTu_MM : MMRel, SetCC_R<"sltu", setult, CPURegs>, + def ADDu_MM : MMRel, ArithLogicR<"addu", GPR32Opnd>, ADD_FM_MM<0, 0x150>; + def SUBu_MM : MMRel, ArithLogicR<"subu", GPR32Opnd>, ADD_FM_MM<0, 0x1d0>; + def MUL_MM : MMRel, ArithLogicR<"mul", GPR32Opnd>, ADD_FM_MM<0, 0x210>; + def ADD_MM : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM_MM<0, 0x110>; + def SUB_MM : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM_MM<0, 0x190>; + def SLT_MM : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM_MM<0, 0x350>; + def SLTu_MM : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM_MM<0, 0x390>; - def AND_MM : MMRel, ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>, + def AND_MM : MMRel, ArithLogicR<"and", GPR32Opnd, 1, IIAlu, and>, ADD_FM_MM<0, 0x250>; - def OR_MM : MMRel, ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>, + def OR_MM : MMRel, ArithLogicR<"or", GPR32Opnd, 1, IIAlu, or>, ADD_FM_MM<0, 0x290>; - def XOR_MM : MMRel, ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>, + def XOR_MM : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, IIAlu, xor>, ADD_FM_MM<0, 0x310>; - def NOR_MM : MMRel, LogicNOR<"nor", CPURegsOpnd>, ADD_FM_MM<0, 0x2d0>; - def MULT_MM : MMRel, Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>, + def NOR_MM : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM_MM<0, 0x2d0>; + def MULT_MM : MMRel, Mult<"mult", IIImul, GPR32Opnd, [HI, LO]>, MULT_FM_MM<0x22c>; - def MULTu_MM : MMRel, Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>, + def MULTu_MM : MMRel, Mult<"multu", IIImul, GPR32Opnd, [HI, LO]>, MULT_FM_MM<0x26c>; /// Shift Instructions - def SLL_MM : MMRel, shift_rotate_imm<"sll", shamt, CPURegsOpnd>, + def SLL_MM : MMRel, shift_rotate_imm<"sll", shamt, GPR32Opnd>, SRA_FM_MM<0, 0>; - def SRL_MM : MMRel, shift_rotate_imm<"srl", shamt, CPURegsOpnd>, + def SRL_MM : MMRel, shift_rotate_imm<"srl", shamt, GPR32Opnd>, SRA_FM_MM<0x40, 0>; - def SRA_MM : MMRel, shift_rotate_imm<"sra", shamt, CPURegsOpnd>, + def SRA_MM : MMRel, shift_rotate_imm<"sra", shamt, GPR32Opnd>, SRA_FM_MM<0x80, 0>; - def SLLV_MM : MMRel, shift_rotate_reg<"sllv", CPURegsOpnd>, + def SLLV_MM : MMRel, shift_rotate_reg<"sllv", GPR32Opnd>, SRLV_FM_MM<0x10, 0>; - def SRLV_MM : MMRel, shift_rotate_reg<"srlv", CPURegsOpnd>, + def SRLV_MM : MMRel, shift_rotate_reg<"srlv", GPR32Opnd>, SRLV_FM_MM<0x50, 0>; - def SRAV_MM : MMRel, shift_rotate_reg<"srav", CPURegsOpnd>, + def SRAV_MM : MMRel, shift_rotate_reg<"srav", GPR32Opnd>, SRLV_FM_MM<0x90, 0>; - def ROTR_MM : MMRel, shift_rotate_imm<"rotr", shamt, CPURegsOpnd>, + def ROTR_MM : MMRel, shift_rotate_imm<"rotr", shamt, GPR32Opnd>, SRA_FM_MM<0xc0, 0>; - def ROTRV_MM : MMRel, shift_rotate_reg<"rotrv", CPURegsOpnd>, + def ROTRV_MM : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd>, SRLV_FM_MM<0xd0, 0>; /// Load and Store Instructions - aligned - defm LB_MM : LoadM<"lb", CPURegs, sextloadi8>, MMRel, LW_FM_MM<0x7>; - defm LBu_MM : LoadM<"lbu", CPURegs, zextloadi8>, MMRel, LW_FM_MM<0x5>; - defm LH_MM : LoadM<"lh", CPURegs, sextloadi16>, MMRel, LW_FM_MM<0xf>; - defm LHu_MM : LoadM<"lhu", CPURegs, zextloadi16>, MMRel, LW_FM_MM<0xd>; - defm LW_MM : LoadM<"lw", CPURegs>, MMRel, LW_FM_MM<0x3f>; - defm SB_MM : StoreM<"sb", CPURegs, truncstorei8>, MMRel, LW_FM_MM<0x6>; - defm SH_MM : StoreM<"sh", CPURegs, truncstorei16>, MMRel, LW_FM_MM<0xe>; - defm SW_MM : StoreM<"sw", CPURegs>, MMRel, LW_FM_MM<0x3e>; + defm LB_MM : LoadM<"lb", GPR32Opnd, sextloadi8>, MMRel, LW_FM_MM<0x7>; + defm LBu_MM : LoadM<"lbu", GPR32Opnd, zextloadi8>, MMRel, LW_FM_MM<0x5>; + defm LH_MM : LoadM<"lh", GPR32Opnd, sextloadi16>, MMRel, LW_FM_MM<0xf>; + defm LHu_MM : LoadM<"lhu", GPR32Opnd, zextloadi16>, MMRel, LW_FM_MM<0xd>; + defm LW_MM : LoadM<"lw", GPR32Opnd>, MMRel, LW_FM_MM<0x3f>; + defm SB_MM : StoreM<"sb", GPR32Opnd, truncstorei8>, MMRel, LW_FM_MM<0x6>; + defm SH_MM : StoreM<"sh", GPR32Opnd, truncstorei16>, MMRel, LW_FM_MM<0xe>; + defm SW_MM : StoreM<"sw", GPR32Opnd>, MMRel, LW_FM_MM<0x3e>; } diff --git a/lib/Target/Mips/Mips.td b/lib/Target/Mips/Mips.td index eefb02a..2595e41 100644 --- a/lib/Target/Mips/Mips.td +++ b/lib/Target/Mips/Mips.td @@ -101,6 +101,7 @@ def MipsAsmWriter : AsmWriter { def MipsAsmParser : AsmParser { let ShouldEmitMatchRegisterName = 0; + let MnemonicContainsDot = 1; } def MipsAsmParserVariant : AsmParserVariant { diff --git a/lib/Target/Mips/Mips16FrameLowering.cpp b/lib/Target/Mips/Mips16FrameLowering.cpp index e180c49..6655ff9 100644 --- a/lib/Target/Mips/Mips16FrameLowering.cpp +++ b/lib/Target/Mips/Mips16FrameLowering.cpp @@ -40,7 +40,7 @@ void Mips16FrameLowering::emitPrologue(MachineFunction &MF) const { if (StackSize == 0 && !MFI->adjustsStack()) return; MachineModuleInfo &MMI = MF.getMMI(); - const MCRegisterInfo &MRI = MMI.getContext().getRegisterInfo(); + const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); MachineLocation DstML, SrcML; // Adjust stack. @@ -56,13 +56,16 @@ void Mips16FrameLowering::emitPrologue(MachineFunction &MF) const { MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); - unsigned S1 = MRI.getDwarfRegNum(Mips::S1, true); - MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S1, -8)); + unsigned S2 = MRI->getDwarfRegNum(Mips::S2, true); + MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S2, -8)); - unsigned S0 = MRI.getDwarfRegNum(Mips::S0, true); - MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S0, -12)); + unsigned S1 = MRI->getDwarfRegNum(Mips::S1, true); + MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S1, -12)); - unsigned RA = MRI.getDwarfRegNum(Mips::RA, true); + unsigned S0 = MRI->getDwarfRegNum(Mips::S0, true); + MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S0, -16)); + + unsigned RA = MRI->getDwarfRegNum(Mips::RA, true); MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, RA, -4)); if (hasFP(MF)) @@ -168,6 +171,7 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF, MF.getRegInfo().setPhysRegUsed(Mips::RA); MF.getRegInfo().setPhysRegUsed(Mips::S0); MF.getRegInfo().setPhysRegUsed(Mips::S1); + MF.getRegInfo().setPhysRegUsed(Mips::S2); } const MipsFrameLowering * diff --git a/lib/Target/Mips/Mips16HardFloat.cpp b/lib/Target/Mips/Mips16HardFloat.cpp index 45dd5d7..7e456aa 100644 --- a/lib/Target/Mips/Mips16HardFloat.cpp +++ b/lib/Target/Mips/Mips16HardFloat.cpp @@ -247,7 +247,7 @@ static void assureFPCallStub(Function &F, Module *M, bool LE = Subtarget.isLittle(); std::string Name = F.getName(); std::string SectionName = ".mips16.call.fp." + Name; - std::string StubName = "__call_stub_" + Name; + std::string StubName = "__call_stub_fp_" + Name; // // see if we already have the stub // @@ -257,11 +257,13 @@ static void assureFPCallStub(Function &F, Module *M, Function::InternalLinkage, StubName, M); FStub->addFnAttr("mips16_fp_stub"); FStub->addFnAttr(llvm::Attribute::Naked); + FStub->addFnAttr(llvm::Attribute::NoInline); FStub->addFnAttr(llvm::Attribute::NoUnwind); FStub->addFnAttr("nomips16"); FStub->setSection(SectionName); BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub); InlineAsmHelper IAH(Context, BB); + IAH.Out(".set reorder"); FPReturnVariant RV = whichFPReturnVariant(FStub->getReturnType()); FPParamVariant PV = whichFPParamVariantNeeded(F); swapFPIntParams(PV, M, IAH, LE, true); @@ -361,6 +363,8 @@ static bool fixupFPReturnAndCall "__Mips16RetHelper"); A = A.addAttribute(C, AttributeSet::FunctionIndex, Attribute::ReadNone); + A = A.addAttribute(C, AttributeSet::FunctionIndex, + Attribute::NoInline); Value *F = (M->getOrInsertFunction(Name, A, MyVoid, T, NULL)); CallInst::Create(F, Params, "", &Inst ); } else if (const CallInst *CI = dyn_cast<CallInst>(I)) { @@ -389,10 +393,11 @@ static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, std::string LocalName = "__fn_local_" + Name; Function *FStub = Function::Create (F->getFunctionType(), - Function::ExternalLinkage, StubName, M); + Function::InternalLinkage, StubName, M); FStub->addFnAttr("mips16_fp_stub"); FStub->addFnAttr(llvm::Attribute::Naked); FStub->addFnAttr(llvm::Attribute::NoUnwind); + FStub->addFnAttr(llvm::Attribute::NoInline); FStub->addFnAttr("nomips16"); FStub->setSection(SectionName); BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub); diff --git a/lib/Target/Mips/Mips16ISelDAGToDAG.cpp b/lib/Target/Mips/Mips16ISelDAGToDAG.cpp index f70abda..0caa277 100644 --- a/lib/Target/Mips/Mips16ISelDAGToDAG.cpp +++ b/lib/Target/Mips/Mips16ISelDAGToDAG.cpp @@ -118,11 +118,13 @@ void Mips16DAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) { SDValue Mips16DAGToDAGISel::getMips16SPAliasReg() { unsigned Mips16SPAliasReg = MF->getInfo<MipsFunctionInfo>()->getMips16SPAliasReg(); - return CurDAG->getRegister(Mips16SPAliasReg, TLI->getPointerTy()); + return CurDAG->getRegister(Mips16SPAliasReg, + getTargetLowering()->getPointerTy()); } void Mips16DAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) { - SDValue AliasFPReg = CurDAG->getRegister(Mips::S0, TLI->getPointerTy()); + SDValue AliasFPReg = CurDAG->getRegister(Mips::S0, + getTargetLowering()->getPointerTy()); if (Parent) { switch (Parent->getOpcode()) { case ISD::LOAD: { @@ -149,7 +151,7 @@ void Mips16DAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) { } } } - AliasReg = CurDAG->getRegister(Mips::SP, TLI->getPointerTy()); + AliasReg = CurDAG->getRegister(Mips::SP, getTargetLowering()->getPointerTy()); return; } diff --git a/lib/Target/Mips/Mips16ISelLowering.cpp b/lib/Target/Mips/Mips16ISelLowering.cpp index d8dd88c..6ed1d9e 100644 --- a/lib/Target/Mips/Mips16ISelLowering.cpp +++ b/lib/Target/Mips/Mips16ISelLowering.cpp @@ -18,7 +18,6 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetInstrInfo.h" -#include <set> using namespace llvm; @@ -30,15 +29,97 @@ static cl::opt<bool> DontExpandCondPseudos16( cl::Hidden); namespace { - std::set<const char*, MipsTargetLowering::LTStr> NoHelperNeeded; +struct Mips16Libcall { + RTLIB::Libcall Libcall; + const char *Name; + + bool operator<(const Mips16Libcall &RHS) const { + return std::strcmp(Name, RHS.Name) < 0; + } +}; + +struct Mips16IntrinsicHelperType{ + const char* Name; + const char* Helper; + + bool operator<(const Mips16IntrinsicHelperType &RHS) const { + return std::strcmp(Name, RHS.Name) < 0; + } + bool operator==(const Mips16IntrinsicHelperType &RHS) const { + return std::strcmp(Name, RHS.Name) == 0; + } +}; } +// Libcalls for which no helper is generated. Sorted by name for binary search. +static const Mips16Libcall HardFloatLibCalls[] = { + { RTLIB::ADD_F64, "__mips16_adddf3" }, + { RTLIB::ADD_F32, "__mips16_addsf3" }, + { RTLIB::DIV_F64, "__mips16_divdf3" }, + { RTLIB::DIV_F32, "__mips16_divsf3" }, + { RTLIB::OEQ_F64, "__mips16_eqdf2" }, + { RTLIB::OEQ_F32, "__mips16_eqsf2" }, + { RTLIB::FPEXT_F32_F64, "__mips16_extendsfdf2" }, + { RTLIB::FPTOSINT_F64_I32, "__mips16_fix_truncdfsi" }, + { RTLIB::FPTOSINT_F32_I32, "__mips16_fix_truncsfsi" }, + { RTLIB::SINTTOFP_I32_F64, "__mips16_floatsidf" }, + { RTLIB::SINTTOFP_I32_F32, "__mips16_floatsisf" }, + { RTLIB::UINTTOFP_I32_F64, "__mips16_floatunsidf" }, + { RTLIB::UINTTOFP_I32_F32, "__mips16_floatunsisf" }, + { RTLIB::OGE_F64, "__mips16_gedf2" }, + { RTLIB::OGE_F32, "__mips16_gesf2" }, + { RTLIB::OGT_F64, "__mips16_gtdf2" }, + { RTLIB::OGT_F32, "__mips16_gtsf2" }, + { RTLIB::OLE_F64, "__mips16_ledf2" }, + { RTLIB::OLE_F32, "__mips16_lesf2" }, + { RTLIB::OLT_F64, "__mips16_ltdf2" }, + { RTLIB::OLT_F32, "__mips16_ltsf2" }, + { RTLIB::MUL_F64, "__mips16_muldf3" }, + { RTLIB::MUL_F32, "__mips16_mulsf3" }, + { RTLIB::UNE_F64, "__mips16_nedf2" }, + { RTLIB::UNE_F32, "__mips16_nesf2" }, + { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_dc" }, // No associated libcall. + { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_df" }, // No associated libcall. + { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sc" }, // No associated libcall. + { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sf" }, // No associated libcall. + { RTLIB::SUB_F64, "__mips16_subdf3" }, + { RTLIB::SUB_F32, "__mips16_subsf3" }, + { RTLIB::FPROUND_F64_F32, "__mips16_truncdfsf2" }, + { RTLIB::UO_F64, "__mips16_unorddf2" }, + { RTLIB::UO_F32, "__mips16_unordsf2" } +}; + +static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = { + {"ceil", "__mips16_call_stub_df_2"}, + {"ceilf", "__mips16_call_stub_sf_1"}, + {"copysign", "__mips16_call_stub_df_10"}, + {"copysignf", "__mips16_call_stub_sf_5"}, + {"cos", "__mips16_call_stub_df_2"}, + {"cosf", "__mips16_call_stub_sf_1"}, + {"exp2", "__mips16_call_stub_df_2"}, + {"exp2f", "__mips16_call_stub_sf_1"}, + {"floor", "__mips16_call_stub_df_2"}, + {"floorf", "__mips16_call_stub_sf_1"}, + {"log2", "__mips16_call_stub_df_2"}, + {"log2f", "__mips16_call_stub_sf_1"}, + {"nearbyint", "__mips16_call_stub_df_2"}, + {"nearbyintf", "__mips16_call_stub_sf_1"}, + {"rint", "__mips16_call_stub_df_2"}, + {"rintf", "__mips16_call_stub_sf_1"}, + {"sin", "__mips16_call_stub_df_2"}, + {"sinf", "__mips16_call_stub_sf_1"}, + {"sqrt", "__mips16_call_stub_df_2"}, + {"sqrtf", "__mips16_call_stub_sf_1"}, + {"trunc", "__mips16_call_stub_df_2"}, + {"truncf", "__mips16_call_stub_sf_1"}, +}; + Mips16TargetLowering::Mips16TargetLowering(MipsTargetMachine &TM) : MipsTargetLowering(TM) { // // set up as if mips32 and then revert so we can test the mechanism // for switching - addRegisterClass(MVT::i32, &Mips::CPURegsRegClass); + addRegisterClass(MVT::i32, &Mips::GPR32RegClass); addRegisterClass(MVT::f32, &Mips::FGR32RegClass); computeRegisterProperties(); clearRegisterClasses(); @@ -46,13 +127,9 @@ Mips16TargetLowering::Mips16TargetLowering(MipsTargetMachine &TM) // Set up the register classes addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass); - if (Subtarget->inMips16HardFloat()) { + if (Subtarget->inMips16HardFloat()) setMips16HardFloatLibCalls(); - NoHelperNeeded.insert("__mips16_ret_sf"); - NoHelperNeeded.insert("__mips16_ret_df"); - NoHelperNeeded.insert("__mips16_ret_sc"); - NoHelperNeeded.insert("__mips16_ret_dc"); - } + setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand); setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, Expand); setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Expand); @@ -166,47 +243,17 @@ isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, return false; } -void Mips16TargetLowering::setMips16LibcallName - (RTLIB::Libcall L, const char *Name) { - setLibcallName(L, Name); - NoHelperNeeded.insert(Name); -} - void Mips16TargetLowering::setMips16HardFloatLibCalls() { - setMips16LibcallName(RTLIB::ADD_F32, "__mips16_addsf3"); - setMips16LibcallName(RTLIB::ADD_F64, "__mips16_adddf3"); - setMips16LibcallName(RTLIB::SUB_F32, "__mips16_subsf3"); - setMips16LibcallName(RTLIB::SUB_F64, "__mips16_subdf3"); - setMips16LibcallName(RTLIB::MUL_F32, "__mips16_mulsf3"); - setMips16LibcallName(RTLIB::MUL_F64, "__mips16_muldf3"); - setMips16LibcallName(RTLIB::DIV_F32, "__mips16_divsf3"); - setMips16LibcallName(RTLIB::DIV_F64, "__mips16_divdf3"); - setMips16LibcallName(RTLIB::FPEXT_F32_F64, "__mips16_extendsfdf2"); - setMips16LibcallName(RTLIB::FPROUND_F64_F32, "__mips16_truncdfsf2"); - setMips16LibcallName(RTLIB::FPTOSINT_F32_I32, "__mips16_fix_truncsfsi"); - setMips16LibcallName(RTLIB::FPTOSINT_F64_I32, "__mips16_fix_truncdfsi"); - setMips16LibcallName(RTLIB::SINTTOFP_I32_F32, "__mips16_floatsisf"); - setMips16LibcallName(RTLIB::SINTTOFP_I32_F64, "__mips16_floatsidf"); - setMips16LibcallName(RTLIB::UINTTOFP_I32_F32, "__mips16_floatunsisf"); - setMips16LibcallName(RTLIB::UINTTOFP_I32_F64, "__mips16_floatunsidf"); - setMips16LibcallName(RTLIB::OEQ_F32, "__mips16_eqsf2"); - setMips16LibcallName(RTLIB::OEQ_F64, "__mips16_eqdf2"); - setMips16LibcallName(RTLIB::UNE_F32, "__mips16_nesf2"); - setMips16LibcallName(RTLIB::UNE_F64, "__mips16_nedf2"); - setMips16LibcallName(RTLIB::OGE_F32, "__mips16_gesf2"); - setMips16LibcallName(RTLIB::OGE_F64, "__mips16_gedf2"); - setMips16LibcallName(RTLIB::OLT_F32, "__mips16_ltsf2"); - setMips16LibcallName(RTLIB::OLT_F64, "__mips16_ltdf2"); - setMips16LibcallName(RTLIB::OLE_F32, "__mips16_lesf2"); - setMips16LibcallName(RTLIB::OLE_F64, "__mips16_ledf2"); - setMips16LibcallName(RTLIB::OGT_F32, "__mips16_gtsf2"); - setMips16LibcallName(RTLIB::OGT_F64, "__mips16_gtdf2"); - setMips16LibcallName(RTLIB::UO_F32, "__mips16_unordsf2"); - setMips16LibcallName(RTLIB::UO_F64, "__mips16_unorddf2"); - setMips16LibcallName(RTLIB::O_F32, "__mips16_unordsf2"); - setMips16LibcallName(RTLIB::O_F64, "__mips16_unorddf2"); -} + for (unsigned I = 0; I != array_lengthof(HardFloatLibCalls); ++I) { + assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) && + "Array not sorted!"); + if (HardFloatLibCalls[I].Libcall != RTLIB::UNKNOWN_LIBCALL) + setLibcallName(HardFloatLibCalls[I].Libcall, HardFloatLibCalls[I].Name); + } + setLibcallName(RTLIB::O_F64, "__mips16_unorddf2"); + setLibcallName(RTLIB::O_F32, "__mips16_unordsf2"); +} // // The Mips16 hard float is a crazy quilt inherited from gcc. I have a much @@ -383,16 +430,34 @@ getOpndList(SmallVectorImpl<SDValue> &Ops, // bool LookupHelper = true; if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) { - if (NoHelperNeeded.find(S->getSymbol()) != NoHelperNeeded.end()) { + Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() }; + + if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls), + Find)) LookupHelper = false; + else { + Mips16IntrinsicHelperType IntrinsicFind = {S->getSymbol(), ""}; + // one more look at list of intrinsics + if (std::binary_search(Mips16IntrinsicHelper, + array_endof(Mips16IntrinsicHelper), + IntrinsicFind)) { + const Mips16IntrinsicHelperType *h =(std::find(Mips16IntrinsicHelper, + array_endof(Mips16IntrinsicHelper), + IntrinsicFind)); + Mips16HelperFunction = h->Helper; + NeedMips16Helper = true; + LookupHelper = false; + } + } - } - else if (GlobalAddressSDNode *G = - dyn_cast<GlobalAddressSDNode>(CLI.Callee)) { - if (NoHelperNeeded.find(G->getGlobal()->getName().data()) != - NoHelperNeeded.end()) { + } else if (GlobalAddressSDNode *G = + dyn_cast<GlobalAddressSDNode>(CLI.Callee)) { + Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, + G->getGlobal()->getName().data() }; + + if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls), + Find)) LookupHelper = false; - } } if (LookupHelper) Mips16HelperFunction = getMips16HelperFunction(CLI.RetTy, CLI.Args, NeedMips16Helper); diff --git a/lib/Target/Mips/Mips16ISelLowering.h b/lib/Target/Mips/Mips16ISelLowering.h index d3c7028..33b953f 100644 --- a/lib/Target/Mips/Mips16ISelLowering.h +++ b/lib/Target/Mips/Mips16ISelLowering.h @@ -32,8 +32,6 @@ namespace llvm { unsigned NextStackOffset, const MipsFunctionInfo& FI) const; - void setMips16LibcallName(RTLIB::Libcall, const char *Name); - void setMips16HardFloatLibCalls(); unsigned int diff --git a/lib/Target/Mips/Mips16InstrFormats.td b/lib/Target/Mips/Mips16InstrFormats.td index 1e49934..da3a1f1 100644 --- a/lib/Target/Mips/Mips16InstrFormats.td +++ b/lib/Target/Mips/Mips16InstrFormats.td @@ -148,6 +148,20 @@ class FRR16<bits<5> _funct, dag outs, dag ins, string asmstr, let Inst{4-0} = funct; } +class FRRBreak16<dag outs, dag ins, string asmstr, + list<dag> pattern, InstrItinClass itin>: + MipsInst16<outs, ins, asmstr, pattern, itin> +{ + bits<6> Code; + bits<5> funct; + + let Opcode = 0b11101; + let funct = 0b00101; + + let Inst{10-5} = Code; + let Inst{4-0} = funct; +} + // // For conversion functions. // diff --git a/lib/Target/Mips/Mips16InstrInfo.cpp b/lib/Target/Mips/Mips16InstrInfo.cpp index c2a496c..05e70ab 100644 --- a/lib/Target/Mips/Mips16InstrInfo.cpp +++ b/lib/Target/Mips/Mips16InstrInfo.cpp @@ -10,7 +10,7 @@ // This file contains the Mips16 implementation of the TargetInstrInfo class. // //===----------------------------------------------------------------------===// - +#include <stdio.h> #include "Mips16InstrInfo.h" #include "InstPrinter/MipsInstPrinter.h" #include "MipsMachineFunction.h" @@ -72,9 +72,9 @@ void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB, unsigned Opc = 0; if (Mips::CPU16RegsRegClass.contains(DestReg) && - Mips::CPURegsRegClass.contains(SrcReg)) + Mips::GPR32RegClass.contains(SrcReg)) Opc = Mips::MoveR3216; - else if (Mips::CPURegsRegClass.contains(DestReg) && + else if (Mips::GPR32RegClass.contains(DestReg) && Mips::CPU16RegsRegClass.contains(SrcReg)) Opc = Mips::Move32R16; else if ((SrcReg == Mips::HI) && @@ -109,8 +109,9 @@ storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) Opc = Mips::SwRxSpImmX16; assert(Opc && "Register class not handled!"); - BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)) - .addFrameIndex(FI).addImm(Offset).addMemOperand(MMO); + BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)). + addFrameIndex(FI).addImm(Offset) + .addMemOperand(MMO); } void Mips16InstrInfo:: @@ -323,48 +324,88 @@ Mips16InstrInfo::loadImmediate(unsigned FrameReg, // RegScavenger rs; int32_t lo = Imm & 0xFFFF; - int32_t hi = ((Imm >> 16) + (lo >> 15)) & 0xFFFF; NewImm = lo; - unsigned Reg =0; - unsigned SpReg = 0; + int Reg =0; + int SpReg = 0; + rs.enterBasicBlock(&MBB); rs.forward(II); // + // We need to know which registers can be used, in the case where there + // are not enough free registers. We exclude all registers that + // are used in the instruction that we are helping. + // // Consider all allocatable registers in the register class initially + BitVector Candidates = + RI.getAllocatableSet + (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass); + // Exclude all the registers being used by the instruction. + for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { + MachineOperand &MO = II->getOperand(i); + if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() && + !TargetRegisterInfo::isVirtualRegister(MO.getReg())) + Candidates.reset(MO.getReg()); + } + // + // If the same register was used and defined in an instruction, then + // it will not be in the list of candidates. + // + // we need to analyze the instruction that we are helping. + // we need to know if it defines register x but register x is not + // present as an operand of the instruction. this tells + // whether the register is live before the instruction. if it's not + // then we don't need to save it in case there are no free registers. + // + int DefReg = 0; + for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { + MachineOperand &MO = II->getOperand(i); + if (MO.isReg() && MO.isDef()) { + DefReg = MO.getReg(); + break; + } + } + // + BitVector Available = rs.getRegsAvailable(&Mips::CPU16RegsRegClass); + + Available &= Candidates; + // // we use T0 for the first register, if we need to save something away. // we use T1 for the second register, if we need to save something away. // unsigned FirstRegSaved =0, SecondRegSaved=0; unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0; - Reg = rs.FindUnusedReg(&Mips::CPU16RegsRegClass); - if (Reg == 0) { - FirstRegSaved = Reg = Mips::V0; - FirstRegSavedTo = Mips::T0; - copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true); + + Reg = Available.find_first(); + + if (Reg == -1) { + Reg = Candidates.find_first(); + Candidates.reset(Reg); + if (DefReg != Reg) { + FirstRegSaved = Reg; + FirstRegSavedTo = Mips::T0; + copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true); + } } else - rs.setUsed(Reg); - BuildMI(MBB, II, DL, get(Mips::LiRxImmX16), Reg).addImm(hi); - BuildMI(MBB, II, DL, get(Mips::SllX16), Reg).addReg(Reg). - addImm(16); + Available.reset(Reg); + BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm); + NewImm = 0; if (FrameReg == Mips::SP) { - SpReg = rs.FindUnusedReg(&Mips::CPU16RegsRegClass); - if (SpReg == 0) { - if (Reg != Mips::V1) { - SecondRegSaved = SpReg = Mips::V1; + SpReg = Available.find_first(); + if (SpReg == -1) { + SpReg = Candidates.find_first(); + // Candidates.reset(SpReg); // not really needed + if (DefReg!= SpReg) { + SecondRegSaved = SpReg; SecondRegSavedTo = Mips::T1; } - else { - SecondRegSaved = SpReg = Mips::V0; - SecondRegSavedTo = Mips::T0; - } - copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true); + if (SecondRegSaved) + copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true); } - else - rs.setUsed(SpReg); - + else + Available.reset(SpReg); copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false); - BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg) + BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg, RegState::Kill) .addReg(Reg); } else @@ -380,6 +421,22 @@ Mips16InstrInfo::loadImmediate(unsigned FrameReg, return Reg; } +/// This function generates the sequence of instructions needed to get the +/// result of adding register REG and immediate IMM. +unsigned +Mips16InstrInfo::basicLoadImmediate( + unsigned FrameReg, + int64_t Imm, MachineBasicBlock &MBB, + MachineBasicBlock::iterator II, DebugLoc DL, + unsigned &NewImm) const { + const TargetRegisterClass *RC = &Mips::CPU16RegsRegClass; + MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); + unsigned Reg = RegInfo.createVirtualRegister(RC); + BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm); + NewImm = 0; + return Reg; +} + unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc) const { return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 || Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 || @@ -415,3 +472,27 @@ void Mips16InstrInfo::BuildAddiuSpImm const MipsInstrInfo *llvm::createMips16InstrInfo(MipsTargetMachine &TM) { return new Mips16InstrInfo(TM); } + +#include <stdio.h> +bool Mips16InstrInfo::validImmediate(unsigned Opcode, unsigned Reg, + int64_t Amount) { + switch (Opcode) { + case Mips::LbRxRyOffMemX16: + case Mips::LbuRxRyOffMemX16: + case Mips::LhRxRyOffMemX16: + case Mips::LhuRxRyOffMemX16: + case Mips::SbRxRyOffMemX16: + case Mips::ShRxRyOffMemX16: + case Mips::LwRxRyOffMemX16: + case Mips::SwRxRyOffMemX16: + case Mips::SwRxSpImmX16: + case Mips::LwRxSpImmX16: + return isInt<16>(Amount); + case Mips::AddiuRxRyOffMemX16: + if ((Reg == Mips::PC) || (Reg == Mips::SP)) + return isInt<16>(Amount); + return isInt<15>(Amount); + } + printf("Unexpected opcode %i \n", Opcode); + llvm_unreachable("unexpected Opcode in validImmediate"); +} diff --git a/lib/Target/Mips/Mips16InstrInfo.h b/lib/Target/Mips/Mips16InstrInfo.h index a3bd31e..118d258 100644 --- a/lib/Target/Mips/Mips16InstrInfo.h +++ b/lib/Target/Mips/Mips16InstrInfo.h @@ -68,7 +68,7 @@ public: // Adjust SP by FrameSize bytes. Save RA, S0, S1 void makeFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const; + MachineBasicBlock::iterator I) const; // Adjust SP by FrameSize bytes. Restore RA, S0, S1 void restoreFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, @@ -88,6 +88,13 @@ public: MachineBasicBlock::iterator II, DebugLoc DL, unsigned &NewImm) const; + unsigned basicLoadImmediate(unsigned FrameReg, + int64_t Imm, MachineBasicBlock &MBB, + MachineBasicBlock::iterator II, DebugLoc DL, + unsigned &NewImm) const; + + static bool validImmediate(unsigned Opcode, unsigned Reg, int64_t Amount); + static bool validSpImm8(int offset) { return ((offset & 7) == 0) && isInt<11>(offset); } diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td index aa51aaf..aef4e92 100644 --- a/lib/Target/Mips/Mips16InstrInfo.td +++ b/lib/Target/Mips/Mips16InstrInfo.td @@ -21,13 +21,13 @@ def addr16 : // Address operand def mem16 : Operand<i32> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops CPU16Regs, simm16, CPU16Regs); + let MIOperandInfo = (ops CPU16Regs, simm16, CPU16RegsPlusSP); let EncoderMethod = "getMemEncoding"; } def mem16_ea : Operand<i32> { let PrintMethod = "printMemOperandEA"; - let MIOperandInfo = (ops CPU16Regs, simm16); + let MIOperandInfo = (ops CPU16RegsPlusSP, simm16); let EncoderMethod = "getMemEncoding"; } @@ -187,6 +187,11 @@ class FEXT_RI16_SP_explicit_ins<bits<5> _op, string asmstr, FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPUSPReg:$ry, simm16:$imm), !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>; +class FEXT_RI16_SP_Store_explicit_ins<bits<5> _op, string asmstr, + InstrItinClass itin>: + FEXT_RI16<_op, (outs), (ins CPU16Regs:$rx, CPUSPReg:$ry, simm16:$imm), + !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>; + // // EXT-RRI instruction format // @@ -248,7 +253,7 @@ class FEXT_T8I8I16_ins<string asmstr, string asmstr2>: // I8_MOVR32 instruction format (used only by the MOVR32 instructio // class FI8_MOVR3216_ins<string asmstr, InstrItinClass itin>: - FI8_MOVR3216<(outs CPU16Regs:$rz), (ins CPURegs:$r32), + FI8_MOVR3216<(outs CPU16Regs:$rz), (ins GPR32:$r32), !strconcat(asmstr, "\t$rz, $r32"), [], itin>; // @@ -256,7 +261,7 @@ class FI8_MOVR3216_ins<string asmstr, InstrItinClass itin>: // class FI8_MOV32R16_ins<string asmstr, InstrItinClass itin>: - FI8_MOV32R16<(outs CPURegs:$r32), (ins CPU16Regs:$rz), + FI8_MOV32R16<(outs GPR32:$r32), (ins CPU16Regs:$rz), !strconcat(asmstr, "\t$r32, $rz"), [], itin>; // @@ -287,6 +292,11 @@ class FRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> : !strconcat(asmstr, "\t$rx, $ry"), [], itin> { } +class FRRBreakNull16_ins<string asmstr, InstrItinClass itin> : + FRRBreak16<(outs), (ins), asmstr, [], itin> { + let Code=0; +} + class FRR16R_ins<bits<5> f, string asmstr, InstrItinClass itin> : FRR16<f, (outs), (ins CPU16Regs:$rx, CPU16Regs:$ry), !strconcat(asmstr, "\t$rx, $ry"), [], itin> { @@ -437,7 +447,7 @@ def Constant32: MipsPseudo16<(outs), (ins imm32:$imm), "\t.word $imm", []>; def LwConstant32: - MipsPseudo16<(outs), (ins CPU16Regs:$rx, imm32:$imm), + MipsPseudo16<(outs CPU16Regs:$rx), (ins imm32:$imm), "lw\t$rx, 1f\n\tb\t2f\n\t.align\t2\n1: \t.word\t$imm\n2:", []>; @@ -569,6 +579,13 @@ def BnezRxImm16: FRI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16; // def BnezRxImmX16: FEXT_RI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16; + +// +//Format: BREAK immediate +// Purpose: Breakpoint +// To cause a Breakpoint exception. + +def Break16: FRRBreakNull16_ins<"break 0", NoItinerary>; // // Format: BTEQZ offset MIPS16e // Purpose: Branch on T Equal to Zero (Extended) @@ -671,6 +688,7 @@ def Jal16 : FJAL16_ins<0b0, "jal", IIAlu> { let hasDelaySlot = 0; // not true, but we add the nop for now let isTerminator=1; let isBarrier=1; + let isCall=1; } // @@ -878,9 +896,9 @@ def OrRxRxRy16: FRxRxRy16_ins<0b01101, "or", IIAlu>, ArithLogic16Defs<1>; let ra=1, s=0,s0=1,s1=1 in def RestoreRaF16: FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), - "restore\t$$ra, $$s0, $$s1, $frame_size", [], IILoad >, MayLoad { + "restore\t$$ra, $$s0, $$s1, $$s2, $frame_size", [], IILoad >, MayLoad { let isCodeGenOnly = 1; - let Defs = [S0, S1, RA, SP]; + let Defs = [S0, S1, S2, RA, SP]; let Uses = [SP]; } @@ -906,9 +924,9 @@ def RestoreIncSpF16: let ra=1, s=1,s0=1,s1=1 in def SaveRaF16: FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), - "save\t$$ra, $$s0, $$s1, $frame_size", [], IIStore >, MayStore { + "save\t$$ra, $$s0, $$s1, $$s2, $frame_size", [], IIStore >, MayStore { let isCodeGenOnly = 1; - let Uses = [RA, SP, S0, S1]; + let Uses = [RA, SP, S0, S1, S2]; let Defs = [SP]; } @@ -1195,7 +1213,8 @@ def SwRxRyOffMemX16: // Purpose: Store Word rx (SP-Relative) // To store an SP-relative word to memory. // -def SwRxSpImmX16: FEXT_RI16_SP_explicit_ins<0b11010, "sw", IIStore>, MayStore; +def SwRxSpImmX16: FEXT_RI16_SP_Store_explicit_ins + <0b11010, "sw", IIStore>, MayStore; // // @@ -1789,3 +1808,6 @@ def : Mips16Pat<(i32 (extloadi8 addr16:$src)), (LbuRxRyOffMemX16 addr16:$src)>; def : Mips16Pat<(i32 (extloadi16 addr16:$src)), (LhuRxRyOffMemX16 addr16:$src)>; + +def: Mips16Pat<(trap), (Break16)>; + diff --git a/lib/Target/Mips/Mips16RegisterInfo.cpp b/lib/Target/Mips/Mips16RegisterInfo.cpp index 018f56c..9d0f2c9 100644 --- a/lib/Target/Mips/Mips16RegisterInfo.cpp +++ b/lib/Target/Mips/Mips16RegisterInfo.cpp @@ -134,8 +134,8 @@ void Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II, DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n"); - if (!MI.isDebugValue() && ( ((FrameReg != Mips::SP) && !isInt<16>(Offset)) || - ((FrameReg == Mips::SP) && !isInt<15>(Offset)) )) { + if (!MI.isDebugValue() && + !Mips16InstrInfo::validImmediate(MI.getOpcode(), FrameReg, Offset)) { MachineBasicBlock &MBB = *MI.getParent(); DebugLoc DL = II->getDebugLoc(); unsigned NewImm; diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index df717fe..a752ab8 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -37,21 +37,15 @@ def immZExt6 : ImmLeaf<i32, [{return Imm == (Imm & 0x3f);}]>; let DecoderNamespace = "Mips64" in { multiclass Atomic2Ops64<PatFrag Op> { - def NAME : Atomic2Ops<Op, CPU64Regs, CPURegs>, - Requires<[NotN64, HasStdEnc]>; - def _P8 : Atomic2Ops<Op, CPU64Regs, CPU64Regs>, - Requires<[IsN64, HasStdEnc]> { - let isCodeGenOnly = 1; - } + def NAME : Atomic2Ops<Op, GPR64, GPR32>, Requires<[NotN64, HasStdEnc]>; + def _P8 : Atomic2Ops<Op, GPR64, GPR64>, Requires<[IsN64, HasStdEnc]>; } multiclass AtomicCmpSwap64<PatFrag Op> { - def NAME : AtomicCmpSwap<Op, CPU64Regs, CPURegs>, + def NAME : AtomicCmpSwap<Op, GPR64, GPR32>, Requires<[NotN64, HasStdEnc]>; - def _P8 : AtomicCmpSwap<Op, CPU64Regs, CPU64Regs>, - Requires<[IsN64, HasStdEnc]> { - let isCodeGenOnly = 1; - } + def _P8 : AtomicCmpSwap<Op, GPR64, GPR64>, + Requires<[IsN64, HasStdEnc]>; } } let usesCustomInserter = 1, Predicates = [HasStdEnc], @@ -67,9 +61,9 @@ let usesCustomInserter = 1, Predicates = [HasStdEnc], } /// Pseudo instructions for loading and storing accumulator registers. -let isPseudo = 1 in { - defm LOAD_AC128 : LoadM<"load_ac128", ACRegs128>; - defm STORE_AC128 : StoreM<"store_ac128", ACRegs128>; +let isPseudo = 1, isCodeGenOnly = 1 in { + defm LOAD_AC128 : LoadM<"", ACRegs128>; + defm STORE_AC128 : StoreM<"", ACRegs128>; } //===----------------------------------------------------------------------===// @@ -77,166 +71,179 @@ let isPseudo = 1 in { //===----------------------------------------------------------------------===// let DecoderNamespace = "Mips64" in { /// Arithmetic Instructions (ALU Immediate) -def DADDi : ArithLogicI<"daddi", simm16_64, CPU64RegsOpnd>, ADDI_FM<0x18>; -def DADDiu : ArithLogicI<"daddiu", simm16_64, CPU64RegsOpnd, immSExt16, add>, +def DADDi : ArithLogicI<"daddi", simm16_64, GPR64Opnd>, ADDI_FM<0x18>; +def DADDiu : ArithLogicI<"daddiu", simm16_64, GPR64Opnd, IIArith, + immSExt16, add>, ADDI_FM<0x19>, IsAsCheapAsAMove; -def DANDi : ArithLogicI<"andi", uimm16_64, CPU64RegsOpnd, immZExt16, and>, - ADDI_FM<0xc>; -def SLTi64 : SetCC_I<"slti", setlt, simm16_64, immSExt16, CPU64Regs>, + +let isCodeGenOnly = 1 in { +def SLTi64 : SetCC_I<"slti", setlt, simm16_64, immSExt16, GPR64Opnd>, SLTI_FM<0xa>; -def SLTiu64 : SetCC_I<"sltiu", setult, simm16_64, immSExt16, CPU64Regs>, +def SLTiu64 : SetCC_I<"sltiu", setult, simm16_64, immSExt16, GPR64Opnd>, SLTI_FM<0xb>; -def ORi64 : ArithLogicI<"ori", uimm16_64, CPU64RegsOpnd, immZExt16, or>, +def ANDi64 : ArithLogicI<"andi", uimm16_64, GPR64Opnd, IILogic, immZExt16, + and>, + ADDI_FM<0xc>; +def ORi64 : ArithLogicI<"ori", uimm16_64, GPR64Opnd, IILogic, immZExt16, + or>, ADDI_FM<0xd>; -def XORi64 : ArithLogicI<"xori", uimm16_64, CPU64RegsOpnd, immZExt16, xor>, +def XORi64 : ArithLogicI<"xori", uimm16_64, GPR64Opnd, IILogic, immZExt16, + xor>, ADDI_FM<0xe>; -def LUi64 : LoadUpper<"lui", CPU64Regs, uimm16_64>, LUI_FM; +def LUi64 : LoadUpper<"lui", GPR64Opnd, uimm16_64>, LUI_FM; +} /// Arithmetic Instructions (3-Operand, R-Type) -def DADD : ArithLogicR<"dadd", CPU64RegsOpnd>, ADD_FM<0, 0x2c>; -def DADDu : ArithLogicR<"daddu", CPU64RegsOpnd, 1, IIAlu, add>, +def DADD : ArithLogicR<"dadd", GPR64Opnd>, ADD_FM<0, 0x2c>; +def DADDu : ArithLogicR<"daddu", GPR64Opnd, 1, IIArith, add>, ADD_FM<0, 0x2d>; -def DSUBu : ArithLogicR<"dsubu", CPU64RegsOpnd, 0, IIAlu, sub>, +def DSUBu : ArithLogicR<"dsubu", GPR64Opnd, 0, IIArith, sub>, ADD_FM<0, 0x2f>; -def SLT64 : SetCC_R<"slt", setlt, CPU64Regs>, ADD_FM<0, 0x2a>; -def SLTu64 : SetCC_R<"sltu", setult, CPU64Regs>, ADD_FM<0, 0x2b>; -def AND64 : ArithLogicR<"and", CPU64RegsOpnd, 1, IIAlu, and>, ADD_FM<0, 0x24>; -def OR64 : ArithLogicR<"or", CPU64RegsOpnd, 1, IIAlu, or>, ADD_FM<0, 0x25>; -def XOR64 : ArithLogicR<"xor", CPU64RegsOpnd, 1, IIAlu, xor>, ADD_FM<0, 0x26>; -def NOR64 : LogicNOR<"nor", CPU64RegsOpnd>, ADD_FM<0, 0x27>; + +let isCodeGenOnly = 1 in { +def SLT64 : SetCC_R<"slt", setlt, GPR64Opnd>, ADD_FM<0, 0x2a>; +def SLTu64 : SetCC_R<"sltu", setult, GPR64Opnd>, ADD_FM<0, 0x2b>; +def AND64 : ArithLogicR<"and", GPR64Opnd, 1, IIArith, and>, ADD_FM<0, 0x24>; +def OR64 : ArithLogicR<"or", GPR64Opnd, 1, IIArith, or>, ADD_FM<0, 0x25>; +def XOR64 : ArithLogicR<"xor", GPR64Opnd, 1, IIArith, xor>, ADD_FM<0, 0x26>; +def NOR64 : LogicNOR<"nor", GPR64Opnd>, ADD_FM<0, 0x27>; +} /// Shift Instructions -def DSLL : shift_rotate_imm<"dsll", shamt, CPU64RegsOpnd, shl, immZExt6>, +def DSLL : shift_rotate_imm<"dsll", shamt, GPR64Opnd, shl, immZExt6>, SRA_FM<0x38, 0>; -def DSRL : shift_rotate_imm<"dsrl", shamt, CPU64RegsOpnd, srl, immZExt6>, +def DSRL : shift_rotate_imm<"dsrl", shamt, GPR64Opnd, srl, immZExt6>, SRA_FM<0x3a, 0>; -def DSRA : shift_rotate_imm<"dsra", shamt, CPU64RegsOpnd, sra, immZExt6>, +def DSRA : shift_rotate_imm<"dsra", shamt, GPR64Opnd, sra, immZExt6>, SRA_FM<0x3b, 0>; -def DSLLV : shift_rotate_reg<"dsllv", CPU64RegsOpnd, shl>, SRLV_FM<0x14, 0>; -def DSRLV : shift_rotate_reg<"dsrlv", CPU64RegsOpnd, srl>, SRLV_FM<0x16, 0>; -def DSRAV : shift_rotate_reg<"dsrav", CPU64RegsOpnd, sra>, SRLV_FM<0x17, 0>; -def DSLL32 : shift_rotate_imm<"dsll32", shamt, CPU64RegsOpnd>, SRA_FM<0x3c, 0>; -def DSRL32 : shift_rotate_imm<"dsrl32", shamt, CPU64RegsOpnd>, SRA_FM<0x3e, 0>; -def DSRA32 : shift_rotate_imm<"dsra32", shamt, CPU64RegsOpnd>, SRA_FM<0x3f, 0>; -} +def DSLLV : shift_rotate_reg<"dsllv", GPR64Opnd, shl>, SRLV_FM<0x14, 0>; +def DSRLV : shift_rotate_reg<"dsrlv", GPR64Opnd, srl>, SRLV_FM<0x16, 0>; +def DSRAV : shift_rotate_reg<"dsrav", GPR64Opnd, sra>, SRLV_FM<0x17, 0>; +def DSLL32 : shift_rotate_imm<"dsll32", shamt, GPR64Opnd>, SRA_FM<0x3c, 0>; +def DSRL32 : shift_rotate_imm<"dsrl32", shamt, GPR64Opnd>, SRA_FM<0x3e, 0>; +def DSRA32 : shift_rotate_imm<"dsra32", shamt, GPR64Opnd>, SRA_FM<0x3f, 0>; + // Rotate Instructions -let Predicates = [HasMips64r2, HasStdEnc], - DecoderNamespace = "Mips64" in { - def DROTR : shift_rotate_imm<"drotr", shamt, CPU64RegsOpnd, rotr, immZExt6>, +let Predicates = [HasMips64r2, HasStdEnc] in { + def DROTR : shift_rotate_imm<"drotr", shamt, GPR64Opnd, rotr, immZExt6>, SRA_FM<0x3a, 1>; - def DROTRV : shift_rotate_reg<"drotrv", CPU64RegsOpnd, rotr>, + def DROTRV : shift_rotate_reg<"drotrv", GPR64Opnd, rotr>, SRLV_FM<0x16, 1>; } -let DecoderNamespace = "Mips64" in { /// Load and Store Instructions /// aligned -defm LB64 : LoadM<"lb", CPU64Regs, sextloadi8>, LW_FM<0x20>; -defm LBu64 : LoadM<"lbu", CPU64Regs, zextloadi8>, LW_FM<0x24>; -defm LH64 : LoadM<"lh", CPU64Regs, sextloadi16>, LW_FM<0x21>; -defm LHu64 : LoadM<"lhu", CPU64Regs, zextloadi16>, LW_FM<0x25>; -defm LW64 : LoadM<"lw", CPU64Regs, sextloadi32>, LW_FM<0x23>; -defm LWu64 : LoadM<"lwu", CPU64Regs, zextloadi32>, LW_FM<0x27>; -defm SB64 : StoreM<"sb", CPU64Regs, truncstorei8>, LW_FM<0x28>; -defm SH64 : StoreM<"sh", CPU64Regs, truncstorei16>, LW_FM<0x29>; -defm SW64 : StoreM<"sw", CPU64Regs, truncstorei32>, LW_FM<0x2b>; -defm LD : LoadM<"ld", CPU64Regs, load>, LW_FM<0x37>; -defm SD : StoreM<"sd", CPU64Regs, store>, LW_FM<0x3f>; +let isCodeGenOnly = 1 in { +defm LB64 : LoadM<"lb", GPR64Opnd, sextloadi8, IILoad>, LW_FM<0x20>; +defm LBu64 : LoadM<"lbu", GPR64Opnd, zextloadi8, IILoad>, LW_FM<0x24>; +defm LH64 : LoadM<"lh", GPR64Opnd, sextloadi16, IILoad>, LW_FM<0x21>; +defm LHu64 : LoadM<"lhu", GPR64Opnd, zextloadi16, IILoad>, LW_FM<0x25>; +defm LW64 : LoadM<"lw", GPR64Opnd, sextloadi32, IILoad>, LW_FM<0x23>; +defm SB64 : StoreM<"sb", GPR64Opnd, truncstorei8, IIStore>, LW_FM<0x28>; +defm SH64 : StoreM<"sh", GPR64Opnd, truncstorei16, IIStore>, LW_FM<0x29>; +defm SW64 : StoreM<"sw", GPR64Opnd, truncstorei32, IIStore>, LW_FM<0x2b>; +} + +defm LWu : LoadM<"lwu", GPR64Opnd, zextloadi32, IILoad>, LW_FM<0x27>; +defm LD : LoadM<"ld", GPR64Opnd, load, IILoad>, LW_FM<0x37>; +defm SD : StoreM<"sd", GPR64Opnd, store, IIStore>, LW_FM<0x3f>; /// load/store left/right -defm LWL64 : LoadLeftRightM<"lwl", MipsLWL, CPU64Regs>, LW_FM<0x22>; -defm LWR64 : LoadLeftRightM<"lwr", MipsLWR, CPU64Regs>, LW_FM<0x26>; -defm SWL64 : StoreLeftRightM<"swl", MipsSWL, CPU64Regs>, LW_FM<0x2a>; -defm SWR64 : StoreLeftRightM<"swr", MipsSWR, CPU64Regs>, LW_FM<0x2e>; +let isCodeGenOnly = 1 in { +defm LWL64 : LoadLeftRightM<"lwl", MipsLWL, GPR64Opnd>, LW_FM<0x22>; +defm LWR64 : LoadLeftRightM<"lwr", MipsLWR, GPR64Opnd>, LW_FM<0x26>; +defm SWL64 : StoreLeftRightM<"swl", MipsSWL, GPR64Opnd>, LW_FM<0x2a>; +defm SWR64 : StoreLeftRightM<"swr", MipsSWR, GPR64Opnd>, LW_FM<0x2e>; +} -defm LDL : LoadLeftRightM<"ldl", MipsLDL, CPU64Regs>, LW_FM<0x1a>; -defm LDR : LoadLeftRightM<"ldr", MipsLDR, CPU64Regs>, LW_FM<0x1b>; -defm SDL : StoreLeftRightM<"sdl", MipsSDL, CPU64Regs>, LW_FM<0x2c>; -defm SDR : StoreLeftRightM<"sdr", MipsSDR, CPU64Regs>, LW_FM<0x2d>; +defm LDL : LoadLeftRightM<"ldl", MipsLDL, GPR64Opnd>, LW_FM<0x1a>; +defm LDR : LoadLeftRightM<"ldr", MipsLDR, GPR64Opnd>, LW_FM<0x1b>; +defm SDL : StoreLeftRightM<"sdl", MipsSDL, GPR64Opnd>, LW_FM<0x2c>; +defm SDR : StoreLeftRightM<"sdr", MipsSDR, GPR64Opnd>, LW_FM<0x2d>; /// Load-linked, Store-conditional let Predicates = [NotN64, HasStdEnc] in { - def LLD : LLBase<"lld", CPU64RegsOpnd, mem>, LW_FM<0x34>; - def SCD : SCBase<"scd", CPU64RegsOpnd, mem>, LW_FM<0x3c>; + def LLD : LLBase<"lld", GPR64Opnd, mem>, LW_FM<0x34>; + def SCD : SCBase<"scd", GPR64Opnd, mem>, LW_FM<0x3c>; } let Predicates = [IsN64, HasStdEnc], isCodeGenOnly = 1 in { - def LLD_P8 : LLBase<"lld", CPU64RegsOpnd, mem64>, LW_FM<0x34>; - def SCD_P8 : SCBase<"scd", CPU64RegsOpnd, mem64>, LW_FM<0x3c>; + def LLD_P8 : LLBase<"lld", GPR64Opnd, mem64>, LW_FM<0x34>; + def SCD_P8 : SCBase<"scd", GPR64Opnd, mem64>, LW_FM<0x3c>; } /// Jump and Branch Instructions -def JR64 : IndirectBranch<CPU64Regs>, MTLO_FM<8>; -def BEQ64 : CBranch<"beq", seteq, CPU64RegsOpnd>, BEQ_FM<4>; -def BNE64 : CBranch<"bne", setne, CPU64RegsOpnd>, BEQ_FM<5>; -def BGEZ64 : CBranchZero<"bgez", setge, CPU64RegsOpnd>, BGEZ_FM<1, 1>; -def BGTZ64 : CBranchZero<"bgtz", setgt, CPU64RegsOpnd>, BGEZ_FM<7, 0>; -def BLEZ64 : CBranchZero<"blez", setle, CPU64RegsOpnd>, BGEZ_FM<6, 0>; -def BLTZ64 : CBranchZero<"bltz", setlt, CPU64RegsOpnd>, BGEZ_FM<1, 0>; +let isCodeGenOnly = 1 in { +def JR64 : IndirectBranch<GPR64Opnd>, MTLO_FM<8>; +def BEQ64 : CBranch<"beq", seteq, GPR64Opnd>, BEQ_FM<4>; +def BNE64 : CBranch<"bne", setne, GPR64Opnd>, BEQ_FM<5>; +def BGEZ64 : CBranchZero<"bgez", setge, GPR64Opnd>, BGEZ_FM<1, 1>; +def BGTZ64 : CBranchZero<"bgtz", setgt, GPR64Opnd>, BGEZ_FM<7, 0>; +def BLEZ64 : CBranchZero<"blez", setle, GPR64Opnd>, BGEZ_FM<6, 0>; +def BLTZ64 : CBranchZero<"bltz", setlt, GPR64Opnd>, BGEZ_FM<1, 0>; +def JALR64 : JumpLinkReg<"jalr", GPR64Opnd>, JALR_FM; +def JALR64Pseudo : JumpLinkRegPseudo<GPR64Opnd, JALR, RA, GPR32Opnd>; +def TAILCALL64_R : JumpFR<GPR64Opnd, MipsTailCall>, MTLO_FM<8>, IsTailCall; } -let DecoderNamespace = "Mips64" in -def JALR64 : JumpLinkReg<"jalr", CPU64Regs>, JALR_FM; -def JALR64Pseudo : JumpLinkRegPseudo<CPU64Regs, JALR64, RA_64>; -def TAILCALL64_R : JumpFR<CPU64Regs, MipsTailCall>, MTLO_FM<8>, IsTailCall; -let DecoderNamespace = "Mips64" in { /// Multiply and Divide Instructions. -def DMULT : Mult<"dmult", IIImul, CPU64RegsOpnd, [HI64, LO64]>, +def DMULT : Mult<"dmult", IIImult, GPR64Opnd, [HI64, LO64]>, MULT_FM<0, 0x1c>; -def DMULTu : Mult<"dmultu", IIImul, CPU64RegsOpnd, [HI64, LO64]>, +def DMULTu : Mult<"dmultu", IIImult, GPR64Opnd, [HI64, LO64]>, MULT_FM<0, 0x1d>; -def PseudoDMULT : MultDivPseudo<DMULT, ACRegs128, CPU64RegsOpnd, MipsMult, - IIImul>; -def PseudoDMULTu : MultDivPseudo<DMULTu, ACRegs128, CPU64RegsOpnd, MipsMultu, - IIImul>; -def DSDIV : Div<"ddiv", IIIdiv, CPU64RegsOpnd, [HI64, LO64]>, MULT_FM<0, 0x1e>; -def DUDIV : Div<"ddivu", IIIdiv, CPU64RegsOpnd, [HI64, LO64]>, MULT_FM<0, 0x1f>; -def PseudoDSDIV : MultDivPseudo<DSDIV, ACRegs128, CPU64RegsOpnd, MipsDivRem, +def PseudoDMULT : MultDivPseudo<DMULT, ACRegs128, GPR64Opnd, MipsMult, + IIImult>; +def PseudoDMULTu : MultDivPseudo<DMULTu, ACRegs128, GPR64Opnd, MipsMultu, + IIImult>; +def DSDIV : Div<"ddiv", IIIdiv, GPR64Opnd, [HI64, LO64]>, MULT_FM<0, 0x1e>; +def DUDIV : Div<"ddivu", IIIdiv, GPR64Opnd, [HI64, LO64]>, MULT_FM<0, 0x1f>; +def PseudoDSDIV : MultDivPseudo<DSDIV, ACRegs128, GPR64Opnd, MipsDivRem, IIIdiv, 0, 1, 1>; -def PseudoDUDIV : MultDivPseudo<DUDIV, ACRegs128, CPU64RegsOpnd, MipsDivRemU, +def PseudoDUDIV : MultDivPseudo<DUDIV, ACRegs128, GPR64Opnd, MipsDivRemU, IIIdiv, 0, 1, 1>; -def MTHI64 : MoveToLOHI<"mthi", CPU64Regs, [HI64]>, MTLO_FM<0x11>; -def MTLO64 : MoveToLOHI<"mtlo", CPU64Regs, [LO64]>, MTLO_FM<0x13>; -def MFHI64 : MoveFromLOHI<"mfhi", CPU64Regs, [HI64]>, MFLO_FM<0x10>; -def MFLO64 : MoveFromLOHI<"mflo", CPU64Regs, [LO64]>, MFLO_FM<0x12>; +let isCodeGenOnly = 1 in { +def MTHI64 : MoveToLOHI<"mthi", GPR64Opnd, [HI64]>, MTLO_FM<0x11>; +def MTLO64 : MoveToLOHI<"mtlo", GPR64Opnd, [LO64]>, MTLO_FM<0x13>; +def MFHI64 : MoveFromLOHI<"mfhi", GPR64Opnd, [HI64]>, MFLO_FM<0x10>; +def MFLO64 : MoveFromLOHI<"mflo", GPR64Opnd, [LO64]>, MFLO_FM<0x12>; /// Sign Ext In Register Instructions. -def SEB64 : SignExtInReg<"seb", i8, CPU64Regs>, SEB_FM<0x10, 0x20>; -def SEH64 : SignExtInReg<"seh", i16, CPU64Regs>, SEB_FM<0x18, 0x20>; +def SEB64 : SignExtInReg<"seb", i8, GPR64Opnd>, SEB_FM<0x10, 0x20>; +def SEH64 : SignExtInReg<"seh", i16, GPR64Opnd>, SEB_FM<0x18, 0x20>; +} /// Count Leading -def DCLZ : CountLeading0<"dclz", CPU64RegsOpnd>, CLO_FM<0x24>; -def DCLO : CountLeading1<"dclo", CPU64RegsOpnd>, CLO_FM<0x25>; +def DCLZ : CountLeading0<"dclz", GPR64Opnd>, CLO_FM<0x24>; +def DCLO : CountLeading1<"dclo", GPR64Opnd>, CLO_FM<0x25>; /// Double Word Swap Bytes/HalfWords -def DSBH : SubwordSwap<"dsbh", CPU64RegsOpnd>, SEB_FM<2, 0x24>; -def DSHD : SubwordSwap<"dshd", CPU64RegsOpnd>, SEB_FM<5, 0x24>; +def DSBH : SubwordSwap<"dsbh", GPR64Opnd>, SEB_FM<2, 0x24>; +def DSHD : SubwordSwap<"dshd", GPR64Opnd>, SEB_FM<5, 0x24>; -def LEA_ADDiu64 : EffectiveAddress<"daddiu", CPU64Regs, mem_ea_64>, LW_FM<0x19>; +def LEA_ADDiu64 : EffectiveAddress<"daddiu", GPR64Opnd, mem_ea_64>, LW_FM<0x19>; -} -let DecoderNamespace = "Mips64" in { -def RDHWR64 : ReadHardware<CPU64Regs, HW64RegsOpnd>, RDHWR_FM; +let isCodeGenOnly = 1 in +def RDHWR64 : ReadHardware<GPR64Opnd, HW64RegsOpnd>, RDHWR_FM; -def DEXT : ExtBase<"dext", CPU64RegsOpnd>, EXT_FM<3>; +def DEXT : ExtBase<"dext", GPR64Opnd>, EXT_FM<3>; let Pattern = []<dag> in { - def DEXTU : ExtBase<"dextu", CPU64RegsOpnd>, EXT_FM<2>; - def DEXTM : ExtBase<"dextm", CPU64RegsOpnd>, EXT_FM<1>; + def DEXTU : ExtBase<"dextu", GPR64Opnd>, EXT_FM<2>; + def DEXTM : ExtBase<"dextm", GPR64Opnd>, EXT_FM<1>; } -def DINS : InsBase<"dins", CPU64RegsOpnd>, EXT_FM<7>; +def DINS : InsBase<"dins", GPR64Opnd>, EXT_FM<7>; let Pattern = []<dag> in { - def DINSU : InsBase<"dinsu", CPU64RegsOpnd>, EXT_FM<6>; - def DINSM : InsBase<"dinsm", CPU64RegsOpnd>, EXT_FM<5>; + def DINSU : InsBase<"dinsu", GPR64Opnd>, EXT_FM<6>; + def DINSM : InsBase<"dinsm", GPR64Opnd>, EXT_FM<5>; } let isCodeGenOnly = 1, rs = 0, shamt = 0 in { - def DSLL64_32 : FR<0x00, 0x3c, (outs CPU64Regs:$rd), (ins CPURegs:$rt), - "dsll\t$rd, $rt, 32", [], IIAlu>; - def SLL64_32 : FR<0x0, 0x00, (outs CPU64Regs:$rd), (ins CPURegs:$rt), - "sll\t$rd, $rt, 0", [], IIAlu>; - def SLL64_64 : FR<0x0, 0x00, (outs CPU64Regs:$rd), (ins CPU64Regs:$rt), - "sll\t$rd, $rt, 0", [], IIAlu>; + def DSLL64_32 : FR<0x00, 0x3c, (outs GPR64:$rd), (ins GPR32:$rt), + "dsll\t$rd, $rt, 32", [], IIArith>; + def SLL64_32 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR32:$rt), + "sll\t$rd, $rt, 0", [], IIArith>; + def SLL64_64 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR64:$rt), + "sll\t$rd, $rt, 0", [], IIArith>; } } //===----------------------------------------------------------------------===// @@ -273,25 +280,25 @@ def : MipsPat<(MipsLo tglobaltlsaddr:$in), (DADDiu ZERO_64, tglobaltlsaddr:$in)>; def : MipsPat<(MipsLo texternalsym:$in), (DADDiu ZERO_64, texternalsym:$in)>; -def : MipsPat<(add CPU64Regs:$hi, (MipsLo tglobaladdr:$lo)), - (DADDiu CPU64Regs:$hi, tglobaladdr:$lo)>; -def : MipsPat<(add CPU64Regs:$hi, (MipsLo tblockaddress:$lo)), - (DADDiu CPU64Regs:$hi, tblockaddress:$lo)>; -def : MipsPat<(add CPU64Regs:$hi, (MipsLo tjumptable:$lo)), - (DADDiu CPU64Regs:$hi, tjumptable:$lo)>; -def : MipsPat<(add CPU64Regs:$hi, (MipsLo tconstpool:$lo)), - (DADDiu CPU64Regs:$hi, tconstpool:$lo)>; -def : MipsPat<(add CPU64Regs:$hi, (MipsLo tglobaltlsaddr:$lo)), - (DADDiu CPU64Regs:$hi, tglobaltlsaddr:$lo)>; - -def : WrapperPat<tglobaladdr, DADDiu, CPU64Regs>; -def : WrapperPat<tconstpool, DADDiu, CPU64Regs>; -def : WrapperPat<texternalsym, DADDiu, CPU64Regs>; -def : WrapperPat<tblockaddress, DADDiu, CPU64Regs>; -def : WrapperPat<tjumptable, DADDiu, CPU64Regs>; -def : WrapperPat<tglobaltlsaddr, DADDiu, CPU64Regs>; - -defm : BrcondPats<CPU64Regs, BEQ64, BNE64, SLT64, SLTu64, SLTi64, SLTiu64, +def : MipsPat<(add GPR64:$hi, (MipsLo tglobaladdr:$lo)), + (DADDiu GPR64:$hi, tglobaladdr:$lo)>; +def : MipsPat<(add GPR64:$hi, (MipsLo tblockaddress:$lo)), + (DADDiu GPR64:$hi, tblockaddress:$lo)>; +def : MipsPat<(add GPR64:$hi, (MipsLo tjumptable:$lo)), + (DADDiu GPR64:$hi, tjumptable:$lo)>; +def : MipsPat<(add GPR64:$hi, (MipsLo tconstpool:$lo)), + (DADDiu GPR64:$hi, tconstpool:$lo)>; +def : MipsPat<(add GPR64:$hi, (MipsLo tglobaltlsaddr:$lo)), + (DADDiu GPR64:$hi, tglobaltlsaddr:$lo)>; + +def : WrapperPat<tglobaladdr, DADDiu, GPR64>; +def : WrapperPat<tconstpool, DADDiu, GPR64>; +def : WrapperPat<texternalsym, DADDiu, GPR64>; +def : WrapperPat<tblockaddress, DADDiu, GPR64>; +def : WrapperPat<tjumptable, DADDiu, GPR64>; +def : WrapperPat<tglobaltlsaddr, DADDiu, GPR64>; + +defm : BrcondPats<GPR64, BEQ64, BNE64, SLT64, SLTu64, SLTi64, SLTiu64, ZERO_64>; def : MipsPat<(brcond (i32 (setlt i64:$lhs, 1)), bb:$dst), @@ -300,28 +307,28 @@ def : MipsPat<(brcond (i32 (setgt i64:$lhs, -1)), bb:$dst), (BGEZ64 i64:$lhs, bb:$dst)>; // setcc patterns -defm : SeteqPats<CPU64Regs, SLTiu64, XOR64, SLTu64, ZERO_64>; -defm : SetlePats<CPU64Regs, SLT64, SLTu64>; -defm : SetgtPats<CPU64Regs, SLT64, SLTu64>; -defm : SetgePats<CPU64Regs, SLT64, SLTu64>; -defm : SetgeImmPats<CPU64Regs, SLTi64, SLTiu64>; +defm : SeteqPats<GPR64, SLTiu64, XOR64, SLTu64, ZERO_64>; +defm : SetlePats<GPR64, SLT64, SLTu64>; +defm : SetgtPats<GPR64, SLT64, SLTu64>; +defm : SetgePats<GPR64, SLT64, SLTu64>; +defm : SetgeImmPats<GPR64, SLTi64, SLTiu64>; // truncate -def : MipsPat<(i32 (trunc CPU64Regs:$src)), - (SLL (EXTRACT_SUBREG CPU64Regs:$src, sub_32), 0)>, +def : MipsPat<(i32 (trunc GPR64:$src)), + (SLL (EXTRACT_SUBREG GPR64:$src, sub_32), 0)>, Requires<[IsN64, HasStdEnc]>; // 32-to-64-bit extension -def : MipsPat<(i64 (anyext CPURegs:$src)), (SLL64_32 CPURegs:$src)>; -def : MipsPat<(i64 (zext CPURegs:$src)), (DSRL (DSLL64_32 CPURegs:$src), 32)>; -def : MipsPat<(i64 (sext CPURegs:$src)), (SLL64_32 CPURegs:$src)>; +def : MipsPat<(i64 (anyext GPR32:$src)), (SLL64_32 GPR32:$src)>; +def : MipsPat<(i64 (zext GPR32:$src)), (DSRL (DSLL64_32 GPR32:$src), 32)>; +def : MipsPat<(i64 (sext GPR32:$src)), (SLL64_32 GPR32:$src)>; // Sign extend in register -def : MipsPat<(i64 (sext_inreg CPU64Regs:$src, i32)), - (SLL64_64 CPU64Regs:$src)>; +def : MipsPat<(i64 (sext_inreg GPR64:$src, i32)), + (SLL64_64 GPR64:$src)>; // bswap MipsPattern -def : MipsPat<(bswap CPU64Regs:$rt), (DSHD (DSBH CPU64Regs:$rt))>; +def : MipsPat<(bswap GPR64:$rt), (DSHD (DSBH GPR64:$rt))>; // mflo/hi patterns. def : MipsPat<(i64 (ExtractLOHI ACRegs128:$ac, imm:$lohi_idx)), @@ -331,71 +338,38 @@ def : MipsPat<(i64 (ExtractLOHI ACRegs128:$ac, imm:$lohi_idx)), // Instruction aliases //===----------------------------------------------------------------------===// def : InstAlias<"move $dst, $src", - (DADDu CPU64RegsOpnd:$dst, CPU64RegsOpnd:$src, ZERO_64), 1>, - Requires<[HasMips64]>; -def : InstAlias<"move $dst, $src", - (OR64 CPU64RegsOpnd:$dst, CPU64RegsOpnd:$src, ZERO_64), 1>, - Requires<[HasMips64]>; -def : InstAlias<"and $rs, $rt, $imm", - (DANDi CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, uimm16_64:$imm), - 1>, - Requires<[HasMips64]>; -def : InstAlias<"slt $rs, $rt, $imm", - (SLTi64 CPURegsOpnd:$rs, CPU64Regs:$rt, simm16_64:$imm), 1>, - Requires<[HasMips64]>; -def : InstAlias<"xor $rs, $rt, $imm", - (XORi64 CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, uimm16_64:$imm), - 1>, - Requires<[HasMips64]>; -def : InstAlias<"not $rt, $rs", - (NOR64 CPU64RegsOpnd:$rt, CPU64RegsOpnd:$rs, ZERO_64), 1>, - Requires<[HasMips64]>; -def : InstAlias<"j $rs", (JR64 CPU64Regs:$rs), 0>, Requires<[HasMips64]>; -def : InstAlias<"jalr $rs", (JALR64 RA_64, CPU64Regs:$rs)>, + (DADDu GPR64Opnd:$dst, GPR64Opnd:$src, ZERO_64), 1>, Requires<[HasMips64]>; -def : InstAlias<"jal $rs", (JALR64 RA_64, CPU64Regs:$rs), 0>, - Requires<[HasMips64]>; -def : InstAlias<"jal $rd,$rs", (JALR64 CPU64Regs:$rd, CPU64Regs:$rs), 0>, - Requires<[HasMips64]>; def : InstAlias<"daddu $rs, $rt, $imm", - (DADDiu CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, simm16_64:$imm), - 1>; + (DADDiu GPR64Opnd:$rs, GPR64Opnd:$rt, simm16_64:$imm), + 0>; def : InstAlias<"dadd $rs, $rt, $imm", - (DADDi CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, simm16_64:$imm), - 1>; -def : InstAlias<"or $rs, $rt, $imm", - (ORi64 CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, uimm16_64:$imm), - 1>, Requires<[HasMips64]>; -def : InstAlias<"bnez $rs,$offset", - (BNE64 CPU64RegsOpnd:$rs, ZERO_64, brtarget:$offset), 1>, - Requires<[HasMips64]>; -def : InstAlias<"beqz $rs,$offset", - (BEQ64 CPU64RegsOpnd:$rs, ZERO_64, brtarget:$offset), 1>, - Requires<[HasMips64]>; + (DADDi GPR64Opnd:$rs, GPR64Opnd:$rt, simm16_64:$imm), + 0>; /// Move between CPU and coprocessor registers let DecoderNamespace = "Mips64" in { -def DMFC0_3OP64 : MFC3OP<(outs CPU64RegsOpnd:$rt), - (ins CPU64RegsOpnd:$rd, uimm16:$sel), +def DMFC0_3OP64 : MFC3OP<(outs GPR64Opnd:$rt), + (ins GPR64Opnd:$rd, uimm16:$sel), "dmfc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 1>; -def DMTC0_3OP64 : MFC3OP<(outs CPU64RegsOpnd:$rd, uimm16:$sel), - (ins CPU64RegsOpnd:$rt), +def DMTC0_3OP64 : MFC3OP<(outs GPR64Opnd:$rd, uimm16:$sel), + (ins GPR64Opnd:$rt), "dmtc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 5>; -def DMFC2_3OP64 : MFC3OP<(outs CPU64RegsOpnd:$rt), - (ins CPU64RegsOpnd:$rd, uimm16:$sel), +def DMFC2_3OP64 : MFC3OP<(outs GPR64Opnd:$rt), + (ins GPR64Opnd:$rd, uimm16:$sel), "dmfc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 1>; -def DMTC2_3OP64 : MFC3OP<(outs CPU64RegsOpnd:$rd, uimm16:$sel), - (ins CPU64RegsOpnd:$rt), +def DMTC2_3OP64 : MFC3OP<(outs GPR64Opnd:$rd, uimm16:$sel), + (ins GPR64Opnd:$rt), "dmtc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 5>; } // Two operand (implicit 0 selector) versions: def : InstAlias<"dmfc0 $rt, $rd", - (DMFC0_3OP64 CPU64RegsOpnd:$rt, CPU64RegsOpnd:$rd, 0), 0>; + (DMFC0_3OP64 GPR64Opnd:$rt, GPR64Opnd:$rd, 0), 0>; def : InstAlias<"dmtc0 $rt, $rd", - (DMTC0_3OP64 CPU64RegsOpnd:$rd, 0, CPU64RegsOpnd:$rt), 0>; + (DMTC0_3OP64 GPR64Opnd:$rd, 0, GPR64Opnd:$rt), 0>; def : InstAlias<"dmfc2 $rt, $rd", - (DMFC2_3OP64 CPU64RegsOpnd:$rt, CPU64RegsOpnd:$rd, 0), 0>; + (DMFC2_3OP64 GPR64Opnd:$rt, GPR64Opnd:$rd, 0), 0>; def : InstAlias<"dmtc2 $rt, $rd", - (DMTC2_3OP64 CPU64RegsOpnd:$rd, 0, CPU64RegsOpnd:$rt), 0>; + (DMTC2_3OP64 GPR64Opnd:$rd, 0, GPR64Opnd:$rt), 0>; diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index 6e4feda..1dc3326 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -141,7 +141,7 @@ void MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) { const MachineFrameInfo *MFI = MF->getFrameInfo(); const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); // size of stack area to which FP callee-saved regs are saved. - unsigned CPURegSize = Mips::CPURegsRegClass.getSize(); + unsigned CPURegSize = Mips::GPR32RegClass.getSize(); unsigned FGR32RegSize = Mips::FGR32RegClass.getSize(); unsigned AFGR64RegSize = Mips::AFGR64RegClass.getSize(); bool HasAFGR64Reg = false; @@ -151,7 +151,7 @@ void MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) { // Set FPU Bitmask. for (i = 0; i != e; ++i) { unsigned Reg = CSI[i].getReg(); - if (Mips::CPURegsRegClass.contains(Reg)) + if (Mips::GPR32RegClass.contains(Reg)) break; unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg); @@ -557,6 +557,15 @@ printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { // FIXME: Use SwitchSection. + // TODO: Need to add -mabicalls and -mno-abicalls flags. + // Currently we assume that -mabicalls is the default. + if (OutStreamer.hasRawTextSupport()) { + OutStreamer.EmitRawText(StringRef("\t.abicalls")); + Reloc::Model RM = Subtarget->getRelocationModel(); + if (RM == Reloc::Static && !Subtarget->hasMips64()) + OutStreamer.EmitRawText(StringRef("\t.option\tpic0")); + } + // Tell the assembler which ABI we are using if (OutStreamer.hasRawTextSupport()) OutStreamer.EmitRawText("\t.section .mdebug." + @@ -589,16 +598,6 @@ void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) { MES->emitELFHeaderFlagsCG(*Subtarget); } -MachineLocation -MipsAsmPrinter::getDebugValueLocation(const MachineInstr *MI) const { - // Handles frame addresses emitted in MipsInstrInfo::emitFrameIndexDebugValue. - assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); - assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm() && - "Unexpected MachineOperand types"); - return MachineLocation(MI->getOperand(0).getReg(), - MI->getOperand(1).getImm()); -} - void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS) { // TODO: implement diff --git a/lib/Target/Mips/MipsAsmPrinter.h b/lib/Target/Mips/MipsAsmPrinter.h index dbdaf26..4d1d624 100644 --- a/lib/Target/Mips/MipsAsmPrinter.h +++ b/lib/Target/Mips/MipsAsmPrinter.h @@ -81,7 +81,6 @@ public: const char *Modifier = 0); void EmitStartOfAsmFile(Module &M); void EmitEndOfAsmFile(Module &M); - virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const; void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); }; } diff --git a/lib/Target/Mips/MipsCondMov.td b/lib/Target/Mips/MipsCondMov.td index 42e4c99..39862b3 100644 --- a/lib/Target/Mips/MipsCondMov.td +++ b/lib/Target/Mips/MipsCondMov.td @@ -16,7 +16,7 @@ // MipsISelLowering::EmitInstrWithCustomInserter if target does not have // conditional move instructions. // cond:int, data:int -class CMov_I_I_FT<string opstr, RegisterClass CRC, RegisterClass DRC, +class CMov_I_I_FT<string opstr, RegisterOperand CRC, RegisterOperand DRC, InstrItinClass Itin> : InstSE<(outs DRC:$rd), (ins DRC:$rs, CRC:$rt, DRC:$F), !strconcat(opstr, "\t$rd, $rs, $rt"), [], Itin, FrmFR> { @@ -24,7 +24,7 @@ class CMov_I_I_FT<string opstr, RegisterClass CRC, RegisterClass DRC, } // cond:int, data:float -class CMov_I_F_FT<string opstr, RegisterClass CRC, RegisterClass DRC, +class CMov_I_F_FT<string opstr, RegisterOperand CRC, RegisterOperand DRC, InstrItinClass Itin> : InstSE<(outs DRC:$fd), (ins DRC:$fs, CRC:$rt, DRC:$F), !strconcat(opstr, "\t$fd, $fs, $rt"), [], Itin, FrmFR> { @@ -32,22 +32,22 @@ class CMov_I_F_FT<string opstr, RegisterClass CRC, RegisterClass DRC, } // cond:float, data:int -class CMov_F_I_FT<string opstr, RegisterClass RC, InstrItinClass Itin, +class CMov_F_I_FT<string opstr, RegisterOperand RC, InstrItinClass Itin, SDPatternOperator OpNode = null_frag> : - InstSE<(outs RC:$rd), (ins RC:$rs, RC:$F), - !strconcat(opstr, "\t$rd, $rs, $$fcc0"), - [(set RC:$rd, (OpNode RC:$rs, RC:$F))], Itin, FrmFR> { - let Uses = [FCR31]; + InstSE<(outs RC:$rd), (ins RC:$rs, FCCRegsOpnd:$fcc, RC:$F), + !strconcat(opstr, "\t$rd, $rs, $fcc"), + [(set RC:$rd, (OpNode RC:$rs, FCCRegsOpnd:$fcc, RC:$F))], + Itin, FrmFR> { let Constraints = "$F = $rd"; } // cond:float, data:float -class CMov_F_F_FT<string opstr, RegisterClass RC, InstrItinClass Itin, +class CMov_F_F_FT<string opstr, RegisterOperand RC, InstrItinClass Itin, SDPatternOperator OpNode = null_frag> : - InstSE<(outs RC:$fd), (ins RC:$fs, RC:$F), - !strconcat(opstr, "\t$fd, $fs, $$fcc0"), - [(set RC:$fd, (OpNode RC:$fs, RC:$F))], Itin, FrmFR> { - let Uses = [FCR31]; + InstSE<(outs RC:$fd), (ins RC:$fs, FCCRegsOpnd:$fcc, RC:$F), + !strconcat(opstr, "\t$fd, $fs, $fcc"), + [(set RC:$fd, (OpNode RC:$fs, FCCRegsOpnd:$fcc, RC:$F))], + Itin, FrmFR> { let Constraints = "$F = $fd"; } @@ -103,151 +103,140 @@ multiclass MovnPats<RegisterClass CRC, RegisterClass DRC, Instruction MOVNInst, } // Instantiation of instructions. -def MOVZ_I_I : CMov_I_I_FT<"movz", CPURegs, CPURegs, NoItinerary>, +def MOVZ_I_I : CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd, NoItinerary>, ADD_FM<0, 0xa>; -let Predicates = [HasStdEnc], - DecoderNamespace = "Mips64" in { - def MOVZ_I_I64 : CMov_I_I_FT<"movz", CPURegs, CPU64Regs, NoItinerary>, - ADD_FM<0, 0xa>; - def MOVZ_I64_I : CMov_I_I_FT<"movz", CPU64Regs, CPURegs, NoItinerary>, - ADD_FM<0, 0xa> { - let isCodeGenOnly = 1; - } - def MOVZ_I64_I64 : CMov_I_I_FT<"movz", CPU64Regs, CPU64Regs, NoItinerary>, - ADD_FM<0, 0xa> { - let isCodeGenOnly = 1; - } -} - -def MOVN_I_I : CMov_I_I_FT<"movn", CPURegs, CPURegs, NoItinerary>, - ADD_FM<0, 0xb>; -let Predicates = [HasStdEnc], - DecoderNamespace = "Mips64" in { - def MOVN_I_I64 : CMov_I_I_FT<"movn", CPURegs, CPU64Regs, NoItinerary>, - ADD_FM<0, 0xb>; - def MOVN_I64_I : CMov_I_I_FT<"movn", CPU64Regs, CPURegs, NoItinerary>, - ADD_FM<0, 0xb> { - let isCodeGenOnly = 1; - } - def MOVN_I64_I64 : CMov_I_I_FT<"movn", CPU64Regs, CPU64Regs, NoItinerary>, - ADD_FM<0, 0xb> { - let isCodeGenOnly = 1; - } -} - -def MOVZ_I_S : CMov_I_F_FT<"movz.s", CPURegs, FGR32, IIFmove>, - CMov_I_F_FM<18, 16>; -def MOVZ_I64_S : CMov_I_F_FT<"movz.s", CPU64Regs, FGR32, IIFmove>, - CMov_I_F_FM<18, 16>, Requires<[HasMips64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; + +let Predicates = [HasStdEnc], isCodeGenOnly = 1 in { + def MOVZ_I_I64 : CMov_I_I_FT<"movz", GPR32Opnd, GPR64Opnd, + NoItinerary>, ADD_FM<0, 0xa>; + def MOVZ_I64_I : CMov_I_I_FT<"movz", GPR64Opnd, GPR32Opnd, + NoItinerary>, ADD_FM<0, 0xa>; + def MOVZ_I64_I64 : CMov_I_I_FT<"movz", GPR64Opnd, GPR64Opnd, + NoItinerary>, ADD_FM<0, 0xa>; } -def MOVN_I_S : CMov_I_F_FT<"movn.s", CPURegs, FGR32, IIFmove>, - CMov_I_F_FM<19, 16>; -def MOVN_I64_S : CMov_I_F_FT<"movn.s", CPU64Regs, FGR32, IIFmove>, - CMov_I_F_FM<19, 16>, Requires<[HasMips64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; +def MOVN_I_I : CMov_I_I_FT<"movn", GPR32Opnd, GPR32Opnd, + NoItinerary>, ADD_FM<0, 0xb>; + +let Predicates = [HasStdEnc], isCodeGenOnly = 1 in { + def MOVN_I_I64 : CMov_I_I_FT<"movn", GPR32Opnd, GPR64Opnd, + NoItinerary>, ADD_FM<0, 0xb>; + def MOVN_I64_I : CMov_I_I_FT<"movn", GPR64Opnd, GPR32Opnd, + NoItinerary>, ADD_FM<0, 0xb>; + def MOVN_I64_I64 : CMov_I_I_FT<"movn", GPR64Opnd, GPR64Opnd, + NoItinerary>, ADD_FM<0, 0xb>; } +def MOVZ_I_S : CMov_I_F_FT<"movz.s", GPR32Opnd, FGR32RegsOpnd, IIFmove>, + CMov_I_F_FM<18, 16>; + +let isCodeGenOnly = 1 in +def MOVZ_I64_S : CMov_I_F_FT<"movz.s", GPR64Opnd, FGR32RegsOpnd, IIFmove>, + CMov_I_F_FM<18, 16>, Requires<[HasMips64, HasStdEnc]>; + +def MOVN_I_S : CMov_I_F_FT<"movn.s", GPR32Opnd, FGR32RegsOpnd, IIFmove>, + CMov_I_F_FM<19, 16>; + +let isCodeGenOnly = 1 in +def MOVN_I64_S : CMov_I_F_FT<"movn.s", GPR64Opnd, FGR32RegsOpnd, IIFmove>, + CMov_I_F_FM<19, 16>, Requires<[HasMips64, HasStdEnc]>; + let Predicates = [NotFP64bit, HasStdEnc] in { - def MOVZ_I_D32 : CMov_I_F_FT<"movz.d", CPURegs, AFGR64, IIFmove>, + def MOVZ_I_D32 : CMov_I_F_FT<"movz.d", GPR32Opnd, AFGR64RegsOpnd, IIFmove>, CMov_I_F_FM<18, 17>; - def MOVN_I_D32 : CMov_I_F_FT<"movn.d", CPURegs, AFGR64, IIFmove>, + def MOVN_I_D32 : CMov_I_F_FT<"movn.d", GPR32Opnd, AFGR64RegsOpnd, IIFmove>, CMov_I_F_FM<19, 17>; } -let Predicates = [IsFP64bit, HasStdEnc], - DecoderNamespace = "Mips64" in { - def MOVZ_I_D64 : CMov_I_F_FT<"movz.d", CPURegs, FGR64, IIFmove>, + +let Predicates = [IsFP64bit, HasStdEnc], isCodeGenOnly = 1 in { + def MOVZ_I_D64 : CMov_I_F_FT<"movz.d", GPR32Opnd, FGR64RegsOpnd, IIFmove>, CMov_I_F_FM<18, 17>; - def MOVZ_I64_D64 : CMov_I_F_FT<"movz.d", CPU64Regs, FGR64, IIFmove>, - CMov_I_F_FM<18, 17> { - let isCodeGenOnly = 1; - } - def MOVN_I_D64 : CMov_I_F_FT<"movn.d", CPURegs, FGR64, IIFmove>, + def MOVZ_I64_D64 : CMov_I_F_FT<"movz.d", GPR64Opnd, FGR64RegsOpnd, + IIFmove>, CMov_I_F_FM<18, 17>; + def MOVN_I_D64 : CMov_I_F_FT<"movn.d", GPR32Opnd, FGR64RegsOpnd, IIFmove>, CMov_I_F_FM<19, 17>; - def MOVN_I64_D64 : CMov_I_F_FT<"movn.d", CPU64Regs, FGR64, IIFmove>, - CMov_I_F_FM<19, 17> { - let isCodeGenOnly = 1; - } + def MOVN_I64_D64 : CMov_I_F_FT<"movn.d", GPR64Opnd, FGR64RegsOpnd, + IIFmove>, CMov_I_F_FM<19, 17>; } -def MOVT_I : CMov_F_I_FT<"movt", CPURegs, IIAlu, MipsCMovFP_T>, CMov_F_I_FM<1>; -def MOVT_I64 : CMov_F_I_FT<"movt", CPU64Regs, IIAlu, MipsCMovFP_T>, - CMov_F_I_FM<1>, Requires<[HasMips64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; -} +def MOVT_I : CMov_F_I_FT<"movt", GPR32Opnd, IIArith, MipsCMovFP_T>, + CMov_F_I_FM<1>; -def MOVF_I : CMov_F_I_FT<"movf", CPURegs, IIAlu, MipsCMovFP_F>, CMov_F_I_FM<0>; -def MOVF_I64 : CMov_F_I_FT<"movf", CPU64Regs, IIAlu, MipsCMovFP_F>, - CMov_F_I_FM<0>, Requires<[HasMips64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; -} +let isCodeGenOnly = 1 in +def MOVT_I64 : CMov_F_I_FT<"movt", GPR64Opnd, IIArith, MipsCMovFP_T>, + CMov_F_I_FM<1>, Requires<[HasMips64, HasStdEnc]>; + +def MOVF_I : CMov_F_I_FT<"movf", GPR32Opnd, IIArith, MipsCMovFP_F>, + CMov_F_I_FM<0>; + +let isCodeGenOnly = 1 in +def MOVF_I64 : CMov_F_I_FT<"movf", GPR64Opnd, IIArith, MipsCMovFP_F>, + CMov_F_I_FM<0>, Requires<[HasMips64, HasStdEnc]>; -def MOVT_S : CMov_F_F_FT<"movt.s", FGR32, IIFmove, MipsCMovFP_T>, +def MOVT_S : CMov_F_F_FT<"movt.s", FGR32RegsOpnd, IIFmove, MipsCMovFP_T>, CMov_F_F_FM<16, 1>; -def MOVF_S : CMov_F_F_FT<"movf.s", FGR32, IIFmove, MipsCMovFP_F>, +def MOVF_S : CMov_F_F_FT<"movf.s", FGR32RegsOpnd, IIFmove, MipsCMovFP_F>, CMov_F_F_FM<16, 0>; let Predicates = [NotFP64bit, HasStdEnc] in { - def MOVT_D32 : CMov_F_F_FT<"movt.d", AFGR64, IIFmove, MipsCMovFP_T>, + def MOVT_D32 : CMov_F_F_FT<"movt.d", AFGR64RegsOpnd, IIFmove, MipsCMovFP_T>, CMov_F_F_FM<17, 1>; - def MOVF_D32 : CMov_F_F_FT<"movf.d", AFGR64, IIFmove, MipsCMovFP_F>, + def MOVF_D32 : CMov_F_F_FT<"movf.d", AFGR64RegsOpnd, IIFmove, MipsCMovFP_F>, CMov_F_F_FM<17, 0>; } -let Predicates = [IsFP64bit, HasStdEnc], - DecoderNamespace = "Mips64" in { - def MOVT_D64 : CMov_F_F_FT<"movt.d", FGR64, IIFmove, MipsCMovFP_T>, +let Predicates = [IsFP64bit, HasStdEnc], isCodeGenOnly = 1 in { + def MOVT_D64 : CMov_F_F_FT<"movt.d", FGR64RegsOpnd, IIFmove, MipsCMovFP_T>, CMov_F_F_FM<17, 1>; - def MOVF_D64 : CMov_F_F_FT<"movf.d", FGR64, IIFmove, MipsCMovFP_F>, + def MOVF_D64 : CMov_F_F_FT<"movf.d", FGR64RegsOpnd, IIFmove, MipsCMovFP_F>, CMov_F_F_FM<17, 0>; } // Instantiation of conditional move patterns. -defm : MovzPats0<CPURegs, CPURegs, MOVZ_I_I, SLT, SLTu, SLTi, SLTiu>; -defm : MovzPats1<CPURegs, CPURegs, MOVZ_I_I, XOR>; -defm : MovzPats2<CPURegs, CPURegs, MOVZ_I_I, XORi>; +defm : MovzPats0<GPR32, GPR32, MOVZ_I_I, SLT, SLTu, SLTi, SLTiu>; +defm : MovzPats1<GPR32, GPR32, MOVZ_I_I, XOR>; +defm : MovzPats2<GPR32, GPR32, MOVZ_I_I, XORi>; let Predicates = [HasMips64, HasStdEnc] in { - defm : MovzPats0<CPURegs, CPU64Regs, MOVZ_I_I64, SLT, SLTu, SLTi, SLTiu>; - defm : MovzPats0<CPU64Regs, CPURegs, MOVZ_I_I, SLT64, SLTu64, SLTi64, + defm : MovzPats0<GPR32, GPR64, MOVZ_I_I64, SLT, SLTu, SLTi, SLTiu>; + defm : MovzPats0<GPR64, GPR32, MOVZ_I_I, SLT64, SLTu64, SLTi64, SLTiu64>; - defm : MovzPats0<CPU64Regs, CPU64Regs, MOVZ_I_I64, SLT64, SLTu64, SLTi64, + defm : MovzPats0<GPR64, GPR64, MOVZ_I_I64, SLT64, SLTu64, SLTi64, SLTiu64>; - defm : MovzPats1<CPURegs, CPU64Regs, MOVZ_I_I64, XOR>; - defm : MovzPats1<CPU64Regs, CPURegs, MOVZ_I64_I, XOR64>; - defm : MovzPats1<CPU64Regs, CPU64Regs, MOVZ_I64_I64, XOR64>; - defm : MovzPats2<CPURegs, CPU64Regs, MOVZ_I_I64, XORi>; - defm : MovzPats2<CPU64Regs, CPURegs, MOVZ_I64_I, XORi64>; - defm : MovzPats2<CPU64Regs, CPU64Regs, MOVZ_I64_I64, XORi64>; + defm : MovzPats1<GPR32, GPR64, MOVZ_I_I64, XOR>; + defm : MovzPats1<GPR64, GPR32, MOVZ_I64_I, XOR64>; + defm : MovzPats1<GPR64, GPR64, MOVZ_I64_I64, XOR64>; + defm : MovzPats2<GPR32, GPR64, MOVZ_I_I64, XORi>; + defm : MovzPats2<GPR64, GPR32, MOVZ_I64_I, XORi64>; + defm : MovzPats2<GPR64, GPR64, MOVZ_I64_I64, XORi64>; } -defm : MovnPats<CPURegs, CPURegs, MOVN_I_I, XOR>; +defm : MovnPats<GPR32, GPR32, MOVN_I_I, XOR>; let Predicates = [HasMips64, HasStdEnc] in { - defm : MovnPats<CPURegs, CPU64Regs, MOVN_I_I64, XOR>; - defm : MovnPats<CPU64Regs, CPURegs, MOVN_I64_I, XOR64>; - defm : MovnPats<CPU64Regs, CPU64Regs, MOVN_I64_I64, XOR64>; + defm : MovnPats<GPR32, GPR64, MOVN_I_I64, XOR>; + defm : MovnPats<GPR64, GPR32, MOVN_I64_I, XOR64>; + defm : MovnPats<GPR64, GPR64, MOVN_I64_I64, XOR64>; } -defm : MovzPats0<CPURegs, FGR32, MOVZ_I_S, SLT, SLTu, SLTi, SLTiu>; -defm : MovzPats1<CPURegs, FGR32, MOVZ_I_S, XOR>; -defm : MovnPats<CPURegs, FGR32, MOVN_I_S, XOR>; +defm : MovzPats0<GPR32, FGR32, MOVZ_I_S, SLT, SLTu, SLTi, SLTiu>; +defm : MovzPats1<GPR32, FGR32, MOVZ_I_S, XOR>; +defm : MovnPats<GPR32, FGR32, MOVN_I_S, XOR>; let Predicates = [HasMips64, HasStdEnc] in { - defm : MovzPats0<CPU64Regs, FGR32, MOVZ_I_S, SLT64, SLTu64, SLTi64, + defm : MovzPats0<GPR64, FGR32, MOVZ_I_S, SLT64, SLTu64, SLTi64, SLTiu64>; - defm : MovzPats1<CPU64Regs, FGR32, MOVZ_I64_S, XOR64>; - defm : MovnPats<CPU64Regs, FGR32, MOVN_I64_S, XOR64>; + defm : MovzPats1<GPR64, FGR32, MOVZ_I64_S, XOR64>; + defm : MovnPats<GPR64, FGR32, MOVN_I64_S, XOR64>; } let Predicates = [NotFP64bit, HasStdEnc] in { - defm : MovzPats0<CPURegs, AFGR64, MOVZ_I_D32, SLT, SLTu, SLTi, SLTiu>; - defm : MovzPats1<CPURegs, AFGR64, MOVZ_I_D32, XOR>; - defm : MovnPats<CPURegs, AFGR64, MOVN_I_D32, XOR>; + defm : MovzPats0<GPR32, AFGR64, MOVZ_I_D32, SLT, SLTu, SLTi, SLTiu>; + defm : MovzPats1<GPR32, AFGR64, MOVZ_I_D32, XOR>; + defm : MovnPats<GPR32, AFGR64, MOVN_I_D32, XOR>; } let Predicates = [IsFP64bit, HasStdEnc] in { - defm : MovzPats0<CPURegs, FGR64, MOVZ_I_D64, SLT, SLTu, SLTi, SLTiu>; - defm : MovzPats0<CPU64Regs, FGR64, MOVZ_I_D64, SLT64, SLTu64, SLTi64, + defm : MovzPats0<GPR32, FGR64, MOVZ_I_D64, SLT, SLTu, SLTi, SLTiu>; + defm : MovzPats0<GPR64, FGR64, MOVZ_I_D64, SLT64, SLTu64, SLTi64, SLTiu64>; - defm : MovzPats1<CPURegs, FGR64, MOVZ_I_D64, XOR>; - defm : MovzPats1<CPU64Regs, FGR64, MOVZ_I64_D64, XOR64>; - defm : MovnPats<CPURegs, FGR64, MOVN_I_D64, XOR>; - defm : MovnPats<CPU64Regs, FGR64, MOVN_I64_D64, XOR64>; + defm : MovzPats1<GPR32, FGR64, MOVZ_I_D64, XOR>; + defm : MovzPats1<GPR64, FGR64, MOVZ_I64_D64, XOR64>; + defm : MovnPats<GPR32, FGR64, MOVN_I_D64, XOR>; + defm : MovnPats<GPR64, FGR64, MOVN_I64_D64, XOR64>; } diff --git a/lib/Target/Mips/MipsDSPInstrInfo.td b/lib/Target/Mips/MipsDSPInstrInfo.td index c12878a..526821a 100644 --- a/lib/Target/Mips/MipsDSPInstrInfo.td +++ b/lib/Target/Mips/MipsDSPInstrInfo.td @@ -328,9 +328,9 @@ class REPL_DESC_BASE<string instr_asm, SDPatternOperator OpNode, class SHLL_QB_R3_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass itin, RegisterClass RC> { dag OutOperandList = (outs RC:$rd); - dag InOperandList = (ins RC:$rt, CPURegs:$rs_sa); + dag InOperandList = (ins RC:$rt, GPR32:$rs_sa); string AsmString = !strconcat(instr_asm, "\t$rd, $rt, $rs_sa"); - list<dag> Pattern = [(set RC:$rd, (OpNode RC:$rt, CPURegs:$rs_sa))]; + list<dag> Pattern = [(set RC:$rd, (OpNode RC:$rt, GPR32:$rs_sa))]; InstrItinClass Itinerary = itin; } @@ -347,11 +347,11 @@ 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 CPURegs:$rd); - dag InOperandList = (ins CPURegs:$base, CPURegs:$index); + dag OutOperandList = (outs GPR32:$rd); + dag InOperandList = (ins GPR32:$base, GPR32:$index); string AsmString = !strconcat(instr_asm, "\t$rd, ${index}(${base})"); - list<dag> Pattern = [(set CPURegs:$rd, - (OpNode CPURegs:$base, CPURegs:$index))]; + list<dag> Pattern = [(set GPR32:$rd, + (OpNode GPR32:$base, GPR32:$index))]; InstrItinClass Itinerary = itin; bit mayLoad = 1; } @@ -368,26 +368,26 @@ class ADDUH_QB_DESC_BASE<string instr_asm, SDPatternOperator OpNode, class APPEND_DESC_BASE<string instr_asm, SDPatternOperator OpNode, SDPatternOperator ImmOp, InstrItinClass itin> { - dag OutOperandList = (outs CPURegs:$rt); - dag InOperandList = (ins CPURegs:$rs, shamt:$sa, CPURegs:$src); + dag OutOperandList = (outs GPR32:$rt); + dag InOperandList = (ins GPR32:$rs, shamt:$sa, GPR32:$src); string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa"); - list<dag> Pattern = [(set CPURegs:$rt, - (OpNode CPURegs:$src, CPURegs:$rs, ImmOp:$sa))]; + list<dag> Pattern = [(set GPR32:$rt, + (OpNode GPR32:$src, GPR32:$rs, ImmOp:$sa))]; InstrItinClass Itinerary = itin; string Constraints = "$src = $rt"; } class EXTR_W_TY1_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass itin> { - dag OutOperandList = (outs CPURegs:$rt); - dag InOperandList = (ins ACRegsDSP:$ac, CPURegs:$shift_rs); + dag OutOperandList = (outs GPR32:$rt); + dag InOperandList = (ins ACRegsDSP:$ac, GPR32:$shift_rs); string AsmString = !strconcat(instr_asm, "\t$rt, $ac, $shift_rs"); InstrItinClass Itinerary = itin; } class EXTR_W_TY1_R1_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass itin> { - dag OutOperandList = (outs CPURegs:$rt); + dag OutOperandList = (outs GPR32:$rt); dag InOperandList = (ins ACRegsDSP:$ac, uimm16:$shift_rs); string AsmString = !strconcat(instr_asm, "\t$rt, $ac, $shift_rs"); InstrItinClass Itinerary = itin; @@ -404,55 +404,55 @@ class SHILO_R1_DESC_BASE<string instr_asm, SDPatternOperator OpNode> { class SHILO_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode> { dag OutOperandList = (outs ACRegsDSP:$ac); - dag InOperandList = (ins CPURegs:$rs, ACRegsDSP:$acin); + dag InOperandList = (ins GPR32:$rs, ACRegsDSP:$acin); string AsmString = !strconcat(instr_asm, "\t$ac, $rs"); list<dag> Pattern = [(set ACRegsDSP:$ac, - (OpNode CPURegs:$rs, ACRegsDSP:$acin))]; + (OpNode GPR32:$rs, ACRegsDSP:$acin))]; string Constraints = "$acin = $ac"; } class MTHLIP_DESC_BASE<string instr_asm, SDPatternOperator OpNode> { dag OutOperandList = (outs ACRegsDSP:$ac); - dag InOperandList = (ins CPURegs:$rs, ACRegsDSP:$acin); + dag InOperandList = (ins GPR32:$rs, ACRegsDSP:$acin); string AsmString = !strconcat(instr_asm, "\t$rs, $ac"); list<dag> Pattern = [(set ACRegsDSP:$ac, - (OpNode CPURegs:$rs, ACRegsDSP:$acin))]; + (OpNode GPR32:$rs, ACRegsDSP:$acin))]; string Constraints = "$acin = $ac"; } class RDDSP_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass itin> { - dag OutOperandList = (outs CPURegs:$rd); + dag OutOperandList = (outs GPR32:$rd); dag InOperandList = (ins uimm16:$mask); string AsmString = !strconcat(instr_asm, "\t$rd, $mask"); - list<dag> Pattern = [(set CPURegs:$rd, (OpNode immZExt10:$mask))]; + list<dag> Pattern = [(set GPR32:$rd, (OpNode immZExt10:$mask))]; InstrItinClass Itinerary = itin; } class WRDSP_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass itin> { dag OutOperandList = (outs); - dag InOperandList = (ins CPURegs:$rs, uimm16:$mask); + dag InOperandList = (ins GPR32:$rs, uimm16:$mask); string AsmString = !strconcat(instr_asm, "\t$rs, $mask"); - list<dag> Pattern = [(OpNode CPURegs:$rs, immZExt10:$mask)]; + list<dag> Pattern = [(OpNode GPR32:$rs, immZExt10:$mask)]; InstrItinClass Itinerary = itin; } class DPA_W_PH_DESC_BASE<string instr_asm, SDPatternOperator OpNode> { dag OutOperandList = (outs ACRegsDSP:$ac); - dag InOperandList = (ins CPURegs:$rs, CPURegs:$rt, ACRegsDSP:$acin); + dag InOperandList = (ins GPR32:$rs, GPR32:$rt, ACRegsDSP:$acin); string AsmString = !strconcat(instr_asm, "\t$ac, $rs, $rt"); list<dag> Pattern = [(set ACRegsDSP:$ac, - (OpNode CPURegs:$rs, CPURegs:$rt, ACRegsDSP:$acin))]; + (OpNode GPR32:$rs, GPR32:$rt, ACRegsDSP:$acin))]; string Constraints = "$acin = $ac"; } class MULT_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass itin> { dag OutOperandList = (outs ACRegsDSP:$ac); - dag InOperandList = (ins CPURegs:$rs, CPURegs:$rt); + dag InOperandList = (ins GPR32:$rs, GPR32:$rt); string AsmString = !strconcat(instr_asm, "\t$ac, $rs, $rt"); - list<dag> Pattern = [(set ACRegsDSP:$ac, (OpNode CPURegs:$rs, CPURegs:$rt))]; + list<dag> Pattern = [(set ACRegsDSP:$ac, (OpNode GPR32:$rs, GPR32:$rt))]; InstrItinClass Itinerary = itin; int AddedComplexity = 20; bit isCommutable = 1; @@ -461,17 +461,17 @@ class MULT_DESC_BASE<string instr_asm, SDPatternOperator OpNode, class MADD_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass itin> { dag OutOperandList = (outs ACRegsDSP:$ac); - dag InOperandList = (ins CPURegs:$rs, CPURegs:$rt, ACRegsDSP:$acin); + dag InOperandList = (ins GPR32:$rs, GPR32:$rt, ACRegsDSP:$acin); string AsmString = !strconcat(instr_asm, "\t$ac, $rs, $rt"); list<dag> Pattern = [(set ACRegsDSP:$ac, - (OpNode CPURegs:$rs, CPURegs:$rt, ACRegsDSP:$acin))]; + (OpNode GPR32:$rs, GPR32:$rt, ACRegsDSP:$acin))]; InstrItinClass Itinerary = itin; int AddedComplexity = 20; string Constraints = "$acin = $ac"; } class MFHI_DESC_BASE<string instr_asm, RegisterClass RC, InstrItinClass itin> { - dag OutOperandList = (outs CPURegs:$rd); + dag OutOperandList = (outs GPR32:$rd); dag InOperandList = (ins RC:$ac); string AsmString = !strconcat(instr_asm, "\t$rd, $ac"); InstrItinClass Itinerary = itin; @@ -479,13 +479,13 @@ class MFHI_DESC_BASE<string instr_asm, RegisterClass RC, InstrItinClass itin> { class MTHI_DESC_BASE<string instr_asm, RegisterClass RC, InstrItinClass itin> { dag OutOperandList = (outs RC:$ac); - dag InOperandList = (ins CPURegs:$rs); + dag InOperandList = (ins GPR32:$rs); string AsmString = !strconcat(instr_asm, "\t$rs, $ac"); InstrItinClass Itinerary = itin; } class BPOSGE32_PSEUDO_DESC_BASE<SDPatternOperator OpNode, InstrItinClass itin> : - MipsPseudo<(outs CPURegs:$dst), (ins), [(set CPURegs:$dst, (OpNode))]> { + MipsPseudo<(outs GPR32:$dst), (ins), [(set GPR32:$dst, (OpNode))]> { bit usesCustomInserter = 1; } @@ -501,10 +501,10 @@ class BPOSGE32_DESC_BASE<string instr_asm, InstrItinClass itin> { class INSV_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass itin> { - dag OutOperandList = (outs CPURegs:$rt); - dag InOperandList = (ins CPURegs:$src, CPURegs:$rs); + dag OutOperandList = (outs GPR32:$rt); + dag InOperandList = (ins GPR32:$src, GPR32:$rs); string AsmString = !strconcat(instr_asm, "\t$rt, $rs"); - list<dag> Pattern = [(set CPURegs:$rt, (OpNode CPURegs:$src, CPURegs:$rs))]; + list<dag> Pattern = [(set GPR32:$rt, (OpNode GPR32:$src, GPR32:$rs))]; InstrItinClass Itinerary = itin; string Constraints = "$src = $rt"; } @@ -547,26 +547,26 @@ class SUBQ_S_PH_DESC : ADDU_QB_DESC_BASE<"subq_s.ph", int_mips_subq_s_ph, Defs<[DSPOutFlag20]>; class ADDQ_S_W_DESC : ADDU_QB_DESC_BASE<"addq_s.w", int_mips_addq_s_w, - NoItinerary, CPURegs, CPURegs>, + NoItinerary, GPR32, GPR32>, IsCommutable, Defs<[DSPOutFlag20]>; class SUBQ_S_W_DESC : ADDU_QB_DESC_BASE<"subq_s.w", int_mips_subq_s_w, - NoItinerary, CPURegs, CPURegs>, + NoItinerary, GPR32, GPR32>, Defs<[DSPOutFlag20]>; class ADDSC_DESC : ADDU_QB_DESC_BASE<"addsc", null_frag, NoItinerary, - CPURegs, CPURegs>, IsCommutable, + GPR32, GPR32>, IsCommutable, Defs<[DSPCarry]>; class ADDWC_DESC : ADDU_QB_DESC_BASE<"addwc", null_frag, NoItinerary, - CPURegs, CPURegs>, + GPR32, GPR32>, IsCommutable, Uses<[DSPCarry]>, Defs<[DSPOutFlag20]>; class MODSUB_DESC : ADDU_QB_DESC_BASE<"modsub", int_mips_modsub, NoItinerary, - CPURegs, CPURegs>; + GPR32, GPR32>; class RADDU_W_QB_DESC : RADDU_W_QB_DESC_BASE<"raddu.w.qb", int_mips_raddu_w_qb, - NoItinerary, CPURegs, DSPRegs>; + NoItinerary, GPR32, DSPRegs>; // Absolute value class ABSQ_S_PH_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.ph", int_mips_absq_s_ph, @@ -574,7 +574,7 @@ class ABSQ_S_PH_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.ph", int_mips_absq_s_ph, Defs<[DSPOutFlag20]>; class ABSQ_S_W_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.w", int_mips_absq_s_w, - NoItinerary, CPURegs>, + NoItinerary, GPR32>, Defs<[DSPOutFlag20]>; // Precision reduce/expand @@ -584,12 +584,12 @@ class PRECRQ_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrq.qb.ph", class PRECRQ_PH_W_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrq.ph.w", int_mips_precrq_ph_w, - NoItinerary, DSPRegs, CPURegs>; + NoItinerary, DSPRegs, GPR32>; class PRECRQ_RS_PH_W_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrq_rs.ph.w", int_mips_precrq_rs_ph_w, NoItinerary, DSPRegs, - CPURegs>, + GPR32>, Defs<[DSPOutFlag22]>; class PRECRQU_S_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrqu_s.qb.ph", @@ -600,11 +600,11 @@ class PRECRQU_S_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrqu_s.qb.ph", class PRECEQ_W_PHL_DESC : ABSQ_S_PH_R2_DESC_BASE<"preceq.w.phl", int_mips_preceq_w_phl, - NoItinerary, CPURegs, DSPRegs>; + NoItinerary, GPR32, DSPRegs>; class PRECEQ_W_PHR_DESC : ABSQ_S_PH_R2_DESC_BASE<"preceq.w.phr", int_mips_preceq_w_phr, - NoItinerary, CPURegs, DSPRegs>; + NoItinerary, GPR32, DSPRegs>; class PRECEQU_PH_QBL_DESC : ABSQ_S_PH_R2_DESC_BASE<"precequ.ph.qbl", int_mips_precequ_ph_qbl, @@ -682,18 +682,18 @@ class SHRAV_R_PH_DESC : SHLL_QB_R3_DESC_BASE<"shrav_r.ph", int_mips_shra_r_ph, NoItinerary, DSPRegs>; class SHLL_S_W_DESC : SHLL_QB_R2_DESC_BASE<"shll_s.w", int_mips_shll_s_w, - immZExt5, NoItinerary, CPURegs>, + immZExt5, NoItinerary, GPR32>, Defs<[DSPOutFlag22]>; class SHLLV_S_W_DESC : SHLL_QB_R3_DESC_BASE<"shllv_s.w", int_mips_shll_s_w, - NoItinerary, CPURegs>, + NoItinerary, GPR32>, Defs<[DSPOutFlag22]>; class SHRA_R_W_DESC : SHLL_QB_R2_DESC_BASE<"shra_r.w", int_mips_shra_r_w, - immZExt5, NoItinerary, CPURegs>; + immZExt5, NoItinerary, GPR32>; class SHRAV_R_W_DESC : SHLL_QB_R3_DESC_BASE<"shrav_r.w", int_mips_shra_r_w, - NoItinerary, CPURegs>; + NoItinerary, GPR32>; // Multiplication class MULEU_S_PH_QBL_DESC : ADDU_QB_DESC_BASE<"muleu_s.ph.qbl", @@ -708,12 +708,12 @@ class MULEU_S_PH_QBR_DESC : ADDU_QB_DESC_BASE<"muleu_s.ph.qbr", class MULEQ_S_W_PHL_DESC : ADDU_QB_DESC_BASE<"muleq_s.w.phl", int_mips_muleq_s_w_phl, - NoItinerary, CPURegs, DSPRegs>, + NoItinerary, GPR32, DSPRegs>, IsCommutable, Defs<[DSPOutFlag21]>; class MULEQ_S_W_PHR_DESC : ADDU_QB_DESC_BASE<"muleq_s.w.phr", int_mips_muleq_s_w_phr, - NoItinerary, CPURegs, DSPRegs>, + NoItinerary, GPR32, DSPRegs>, IsCommutable, Defs<[DSPOutFlag21]>; class MULQ_RS_PH_DESC : ADDU_QB_DESC_BASE<"mulq_rs.ph", int_mips_mulq_rs_ph, @@ -786,16 +786,16 @@ class CMPU_LE_QB_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmpu.le.qb", class CMPGU_EQ_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgu.eq.qb", int_mips_cmpgu_eq_qb, - NoItinerary, CPURegs, DSPRegs>, + NoItinerary, GPR32, DSPRegs>, IsCommutable; class CMPGU_LT_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgu.lt.qb", int_mips_cmpgu_lt_qb, - NoItinerary, CPURegs, DSPRegs>; + NoItinerary, GPR32, DSPRegs>; class CMPGU_LE_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgu.le.qb", int_mips_cmpgu_le_qb, - NoItinerary, CPURegs, DSPRegs>; + NoItinerary, GPR32, DSPRegs>; class CMP_EQ_PH_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmp.eq.ph", int_mips_cmp_eq_ph, NoItinerary, DSPRegs>, @@ -811,7 +811,7 @@ class CMP_LE_PH_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmp.le.ph", int_mips_cmp_le_ph, // Misc class BITREV_DESC : ABSQ_S_PH_R2_DESC_BASE<"bitrev", int_mips_bitrev, - NoItinerary, CPURegs>; + NoItinerary, GPR32>; class PACKRL_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"packrl.ph", int_mips_packrl_ph, NoItinerary, DSPRegs, DSPRegs>; @@ -823,10 +823,10 @@ class REPL_PH_DESC : REPL_DESC_BASE<"repl.ph", int_mips_repl_ph, immZExt10, NoItinerary, DSPRegs>; class REPLV_QB_DESC : ABSQ_S_PH_R2_DESC_BASE<"replv.qb", int_mips_repl_qb, - NoItinerary, DSPRegs, CPURegs>; + NoItinerary, DSPRegs, GPR32>; class REPLV_PH_DESC : ABSQ_S_PH_R2_DESC_BASE<"replv.ph", int_mips_repl_ph, - NoItinerary, DSPRegs, CPURegs>; + NoItinerary, DSPRegs, GPR32>; class PICK_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"pick.qb", int_mips_pick_qb, NoItinerary, DSPRegs, DSPRegs>, @@ -945,31 +945,31 @@ class SUBQH_R_PH_DESC : ADDUH_QB_DESC_BASE<"subqh_r.ph", int_mips_subqh_r_ph, NoItinerary, DSPRegs>; class ADDQH_W_DESC : ADDUH_QB_DESC_BASE<"addqh.w", int_mips_addqh_w, - NoItinerary, CPURegs>, IsCommutable; + NoItinerary, GPR32>, IsCommutable; class ADDQH_R_W_DESC : ADDUH_QB_DESC_BASE<"addqh_r.w", int_mips_addqh_r_w, - NoItinerary, CPURegs>, IsCommutable; + NoItinerary, GPR32>, IsCommutable; class SUBQH_W_DESC : ADDUH_QB_DESC_BASE<"subqh.w", int_mips_subqh_w, - NoItinerary, CPURegs>; + NoItinerary, GPR32>; class SUBQH_R_W_DESC : ADDUH_QB_DESC_BASE<"subqh_r.w", int_mips_subqh_r_w, - NoItinerary, CPURegs>; + NoItinerary, GPR32>; // Comparison class CMPGDU_EQ_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.eq.qb", int_mips_cmpgdu_eq_qb, - NoItinerary, CPURegs, DSPRegs>, + NoItinerary, GPR32, DSPRegs>, IsCommutable, Defs<[DSPCCond]>; class CMPGDU_LT_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.lt.qb", int_mips_cmpgdu_lt_qb, - NoItinerary, CPURegs, DSPRegs>, + NoItinerary, GPR32, DSPRegs>, Defs<[DSPCCond]>; class CMPGDU_LE_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.le.qb", int_mips_cmpgdu_le_qb, - NoItinerary, CPURegs, DSPRegs>, + NoItinerary, GPR32, DSPRegs>, Defs<[DSPCCond]>; // Absolute @@ -987,11 +987,11 @@ class MUL_S_PH_DESC : ADDUH_QB_DESC_BASE<"mul_s.ph", int_mips_mul_s_ph, Defs<[DSPOutFlag21]>; class MULQ_S_W_DESC : ADDUH_QB_DESC_BASE<"mulq_s.w", int_mips_mulq_s_w, - NoItinerary, CPURegs>, IsCommutable, + NoItinerary, GPR32>, IsCommutable, Defs<[DSPOutFlag21]>; class MULQ_RS_W_DESC : ADDUH_QB_DESC_BASE<"mulq_rs.w", int_mips_mulq_rs_w, - NoItinerary, CPURegs>, IsCommutable, + NoItinerary, GPR32>, IsCommutable, Defs<[DSPOutFlag21]>; class MULQ_S_PH_DESC : ADDU_QB_DESC_BASE<"mulq_s.ph", int_mips_mulq_s_ph, @@ -1031,12 +1031,12 @@ class PRECR_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precr.qb.ph", class PRECR_SRA_PH_W_DESC : PRECR_SRA_PH_W_DESC_BASE<"precr_sra.ph.w", int_mips_precr_sra_ph_w, NoItinerary, DSPRegs, - CPURegs>; + GPR32>; class PRECR_SRA_R_PH_W_DESC : PRECR_SRA_PH_W_DESC_BASE<"precr_sra_r.ph.w", int_mips_precr_sra_r_ph_w, NoItinerary, DSPRegs, - CPURegs>; + GPR32>; // Shift class SHRA_QB_DESC : SHLL_QB_R2_DESC_BASE<"shra.qb", null_frag, immZExt3, @@ -1242,8 +1242,8 @@ def PREPEND : PREPEND_ENC, PREPEND_DESC; // Pseudos. let isPseudo = 1 in { // Pseudo instructions for loading and storing accumulator registers. - defm LOAD_AC_DSP : LoadM<"load_ac_dsp", ACRegsDSP>; - defm STORE_AC_DSP : StoreM<"store_ac_dsp", ACRegsDSP>; + defm LOAD_AC_DSP : LoadM<"load_ac_dsp", ACRegsDSPOpnd>; + defm STORE_AC_DSP : StoreM<"store_ac_dsp", ACRegsDSPOpnd>; // Pseudos for loading and storing ccond field of DSP control register. defm LOAD_CCOND_DSP : LoadM<"load_ccond_dsp", DSPCC>; @@ -1279,19 +1279,19 @@ class BitconvertPat<ValueType DstVT, ValueType SrcVT, RegisterClass DstRC, DSPPat<(DstVT (bitconvert (SrcVT SrcRC:$src))), (COPY_TO_REGCLASS SrcRC:$src, DstRC)>; -def : BitconvertPat<i32, v2i16, CPURegs, DSPRegs>; -def : BitconvertPat<i32, v4i8, CPURegs, DSPRegs>; -def : BitconvertPat<v2i16, i32, DSPRegs, CPURegs>; -def : BitconvertPat<v4i8, i32, DSPRegs, CPURegs>; +def : BitconvertPat<i32, v2i16, GPR32, DSPRegs>; +def : BitconvertPat<i32, v4i8, GPR32, DSPRegs>; +def : BitconvertPat<v2i16, i32, DSPRegs, GPR32>; +def : BitconvertPat<v4i8, i32, DSPRegs, GPR32>; def : DSPPat<(v2i16 (load addr:$a)), (v2i16 (COPY_TO_REGCLASS (LW addr:$a), DSPRegs))>; def : DSPPat<(v4i8 (load addr:$a)), (v4i8 (COPY_TO_REGCLASS (LW addr:$a), DSPRegs))>; def : DSPPat<(store (v2i16 DSPRegs:$val), addr:$a), - (SW (COPY_TO_REGCLASS DSPRegs:$val, CPURegs), addr:$a)>; + (SW (COPY_TO_REGCLASS DSPRegs:$val, GPR32), addr:$a)>; def : DSPPat<(store (v4i8 DSPRegs:$val), addr:$a), - (SW (COPY_TO_REGCLASS DSPRegs:$val, CPURegs), addr:$a)>; + (SW (COPY_TO_REGCLASS DSPRegs:$val, GPR32), addr:$a)>; // Binary operations. class DSPBinPat<Instruction Inst, ValueType ValTy, SDPatternOperator Node, @@ -1384,8 +1384,8 @@ def : DSPSelectCCPatInv<PseudoCMPU_LE_QB, PseudoPICK_QB, v4i8, SETUGT>; // Extr patterns. class EXTR_W_TY1_R2_Pat<SDPatternOperator OpNode, Instruction Instr> : - DSPPat<(i32 (OpNode CPURegs:$rs, ACRegsDSP:$ac)), - (Instr ACRegsDSP:$ac, CPURegs:$rs)>; + DSPPat<(i32 (OpNode GPR32:$rs, ACRegsDSP:$ac)), + (Instr ACRegsDSP:$ac, GPR32:$rs)>; class EXTR_W_TY1_R1_Pat<SDPatternOperator OpNode, Instruction Instr> : DSPPat<(i32 (OpNode immZExt5:$shift, ACRegsDSP:$ac)), diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp index 928a43d..545a38d 100644 --- a/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -437,7 +437,7 @@ bool MemDefsUses::hasHazard_(const MachineInstr &MI) { // Check underlying object list. if (getUnderlyingObjects(MI, Objs)) { - for (SmallVector<const Value *, 4>::const_iterator I = Objs.begin(); + for (SmallVectorImpl<const Value *>::const_iterator I = Objs.begin(); I != Objs.end(); ++I) HasHazard |= updateDefsUses(*I, MI.mayStore()); @@ -473,7 +473,7 @@ getUnderlyingObjects(const MachineInstr &MI, SmallVector<Value *, 4> Objs; GetUnderlyingObjects(const_cast<Value *>(V), Objs); - for (SmallVector<Value*, 4>::iterator I = Objs.begin(), E = Objs.end(); + for (SmallVectorImpl<Value *>::iterator I = Objs.begin(), E = Objs.end(); I != E; ++I) { if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(*I)) { if (PSV->isAliased(MFI)) diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index a1de174..0002a5f 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -57,7 +57,8 @@ bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { /// GOT address into a register. SDNode *MipsDAGToDAGISel::getGlobalBaseReg() { unsigned GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg(); - return CurDAG->getRegister(GlobalBaseReg, TLI->getPointerTy()).getNode(); + return CurDAG->getRegister(GlobalBaseReg, + getTargetLowering()->getPointerTy()).getNode(); } /// ComplexPattern used on MipsInstrInfo diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 6351073..a62e84f 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -346,11 +346,6 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::FNEG, MVT::f64, Expand); } - setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand); - setOperationAction(ISD::EXCEPTIONADDR, MVT::i64, Expand); - setOperationAction(ISD::EHSELECTION, MVT::i32, Expand); - setOperationAction(ISD::EHSELECTION, MVT::i64, Expand); - setOperationAction(ISD::EH_RETURN, MVT::Other, Custom); setOperationAction(ISD::VAARG, MVT::Other, Expand); @@ -390,6 +385,8 @@ MipsTargetLowering(MipsTargetMachine &TM) setTruncStoreAction(MVT::i64, MVT::i32, Custom); } + setOperationAction(ISD::TRAP, MVT::Other, Legal); + setTargetDAGCombine(ISD::SDIVREM); setTargetDAGCombine(ISD::UDIVREM); setTargetDAGCombine(ISD::SELECT); @@ -524,9 +521,10 @@ static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True, SDValue False, SDLoc DL) { ConstantSDNode *CC = cast<ConstantSDNode>(Cond.getOperand(2)); bool invert = invertFPCondCodeUser((Mips::CondCode)CC->getSExtValue()); + SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32); return DAG.getNode((invert ? MipsISD::CMovFP_F : MipsISD::CMovFP_T), DL, - True.getValueType(), True, False, Cond); + True.getValueType(), True, FCC0, False, Cond); } static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG, @@ -1084,9 +1082,9 @@ MipsTargetLowering::emitAtomicBinaryPartword(MachineInstr *MI, BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper) .addReg(Mips::ZERO).addImm(MaskImm); BuildMI(BB, DL, TII->get(Mips::SLLV), Mask) - .addReg(ShiftAmt).addReg(MaskUpper); + .addReg(MaskUpper).addReg(ShiftAmt); BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask); - BuildMI(BB, DL, TII->get(Mips::SLLV), Incr2).addReg(ShiftAmt).addReg(Incr); + BuildMI(BB, DL, TII->get(Mips::SLLV), Incr2).addReg(Incr).addReg(ShiftAmt); // atomic.load.binop // loopMBB: @@ -1147,7 +1145,7 @@ MipsTargetLowering::emitAtomicBinaryPartword(MachineInstr *MI, BuildMI(BB, DL, TII->get(Mips::AND), MaskedOldVal1) .addReg(OldVal).addReg(Mask); BuildMI(BB, DL, TII->get(Mips::SRLV), SrlRes) - .addReg(ShiftAmt).addReg(MaskedOldVal1); + .addReg(MaskedOldVal1).addReg(ShiftAmt); BuildMI(BB, DL, TII->get(Mips::SLL), SllRes) .addReg(SrlRes).addImm(ShiftImm); BuildMI(BB, DL, TII->get(Mips::SRA), Dest) @@ -1334,16 +1332,16 @@ MipsTargetLowering::emitAtomicCmpSwapPartword(MachineInstr *MI, BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper) .addReg(Mips::ZERO).addImm(MaskImm); BuildMI(BB, DL, TII->get(Mips::SLLV), Mask) - .addReg(ShiftAmt).addReg(MaskUpper); + .addReg(MaskUpper).addReg(ShiftAmt); BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask); BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedCmpVal) .addReg(CmpVal).addImm(MaskImm); BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedCmpVal) - .addReg(ShiftAmt).addReg(MaskedCmpVal); + .addReg(MaskedCmpVal).addReg(ShiftAmt); BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedNewVal) .addReg(NewVal).addImm(MaskImm); BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedNewVal) - .addReg(ShiftAmt).addReg(MaskedNewVal); + .addReg(MaskedNewVal).addReg(ShiftAmt); // loop1MBB: // ll oldval,0(alginedaddr) @@ -1379,7 +1377,7 @@ MipsTargetLowering::emitAtomicCmpSwapPartword(MachineInstr *MI, int64_t ShiftImm = (Size == 1) ? 24 : 16; BuildMI(BB, DL, TII->get(Mips::SRLV), SrlRes) - .addReg(ShiftAmt).addReg(MaskedOldVal0); + .addReg(MaskedOldVal0).addReg(ShiftAmt); BuildMI(BB, DL, TII->get(Mips::SLL), SllRes) .addReg(SrlRes).addImm(ShiftImm); BuildMI(BB, DL, TII->get(Mips::SRA), Dest) @@ -1443,8 +1441,9 @@ lowerBRCOND(SDValue Op, SelectionDAG &DAG) const (Mips::CondCode)cast<ConstantSDNode>(CCNode)->getZExtValue(); unsigned Opc = invertFPCondCodeUser(CC) ? Mips::BRANCH_F : Mips::BRANCH_T; SDValue BrCode = DAG.getConstant(Opc, MVT::i32); + SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32); return DAG.getNode(MipsISD::FPBrcond, DL, Op.getValueType(), Chain, BrCode, - Dest, CondRes); + FCC0, Dest, CondRes); } SDValue MipsTargetLowering:: @@ -2328,9 +2327,9 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const { SelectionDAG &DAG = CLI.DAG; SDLoc DL = CLI.DL; - SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs; - SmallVector<SDValue, 32> &OutVals = CLI.OutVals; - SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins; + SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; + SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; + SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; SDValue Chain = CLI.Chain; SDValue Callee = CLI.Callee; bool &IsTailCall = CLI.IsTailCall; @@ -2620,9 +2619,9 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, if (RegVT == MVT::i32) RC = Subtarget->inMips16Mode()? &Mips::CPU16RegsRegClass : - &Mips::CPURegsRegClass; + &Mips::GPR32RegClass; else if (RegVT == MVT::i64) - RC = &Mips::CPU64RegsRegClass; + RC = &Mips::GPR64RegClass; else if (RegVT == MVT::f32) RC = &Mips::FGR32RegClass; else if (RegVT == MVT::f64) @@ -2885,7 +2884,7 @@ MipsTargetLowering::getSingleConstraintMatchWeight( /// to an LLVM register class, return a register of 0 and the register class /// pointer. std::pair<unsigned, const TargetRegisterClass*> MipsTargetLowering:: -getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const +getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const { if (Constraint.size() == 1) { switch (Constraint[0]) { @@ -2895,12 +2894,12 @@ getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8) { if (Subtarget->inMips16Mode()) return std::make_pair(0U, &Mips::CPU16RegsRegClass); - return std::make_pair(0U, &Mips::CPURegsRegClass); + return std::make_pair(0U, &Mips::GPR32RegClass); } if (VT == MVT::i64 && !HasMips64) - return std::make_pair(0U, &Mips::CPURegsRegClass); + return std::make_pair(0U, &Mips::GPR32RegClass); if (VT == MVT::i64 && HasMips64) - return std::make_pair(0U, &Mips::CPU64RegsRegClass); + return std::make_pair(0U, &Mips::GPR64RegClass); // This will generate an error message return std::make_pair(0u, static_cast<const TargetRegisterClass*>(0)); case 'f': @@ -2914,9 +2913,9 @@ getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const break; case 'c': // register suitable for indirect jump if (VT == MVT::i32) - return std::make_pair((unsigned)Mips::T9, &Mips::CPURegsRegClass); + return std::make_pair((unsigned)Mips::T9, &Mips::GPR32RegClass); assert(VT == MVT::i64 && "Unexpected type."); - return std::make_pair((unsigned)Mips::T9_64, &Mips::CPU64RegsRegClass); + return std::make_pair((unsigned)Mips::T9_64, &Mips::GPR64RegClass); case 'l': // register suitable for indirect jump if (VT == MVT::i32) return std::make_pair((unsigned)Mips::LO, &Mips::LORegsRegClass); @@ -3388,7 +3387,7 @@ copyByValRegs(SDValue Chain, SDLoc DL, std::vector<SDValue> &OutChains, void MipsTargetLowering:: passByValArg(SDValue Chain, SDLoc DL, std::deque< std::pair<unsigned, SDValue> > &RegsToPass, - SmallVector<SDValue, 8> &MemOpChains, SDValue StackPtr, + SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr, MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, const MipsCC &CC, const ByValArgInfo &ByVal, const ISD::ArgFlagsTy &Flags, bool isLittle) const { diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index fe043ae..123a2a6 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -282,7 +282,7 @@ namespace llvm { /// Return pointer to array of integer argument registers. const uint16_t *intArgRegs() const; - typedef SmallVector<ByValArgInfo, 2>::const_iterator byval_iterator; + typedef SmallVectorImpl<ByValArgInfo>::const_iterator byval_iterator; byval_iterator byval_begin() const { return ByValArgs.begin(); } byval_iterator byval_end() const { return ByValArgs.end(); } @@ -386,7 +386,7 @@ namespace llvm { /// passByValArg - Pass a byval argument in registers or on stack. void passByValArg(SDValue Chain, SDLoc DL, std::deque< std::pair<unsigned, SDValue> > &RegsToPass, - SmallVector<SDValue, 8> &MemOpChains, SDValue StackPtr, + SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr, MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, const MipsCC &CC, const ByValArgInfo &ByVal, const ISD::ArgFlagsTy &Flags, bool isLittle) const; @@ -435,7 +435,7 @@ namespace llvm { std::pair<unsigned, const TargetRegisterClass*> getRegForInlineAsmConstraint(const std::string &Constraint, - EVT VT) const; + MVT VT) const; /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops /// vector. If it is invalid, don't add anything to Ops. If hasMemory is diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index e2acf28..b992e77 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -24,12 +24,13 @@ //===----------------------------------------------------------------------===// // Floating Point Compare and Branch -def SDT_MipsFPBrcond : SDTypeProfile<0, 2, [SDTCisInt<0>, - SDTCisVT<1, OtherVT>]>; +def SDT_MipsFPBrcond : SDTypeProfile<0, 3, [SDTCisInt<0>, + SDTCisVT<1, i32>, + SDTCisVT<2, OtherVT>]>; def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<1>, SDTCisVT<2, i32>]>; -def SDT_MipsCMovFP : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, - SDTCisSameAs<1, 2>]>; +def SDT_MipsCMovFP : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisVT<2, i32>, + SDTCisSameAs<1, 3>]>; def SDT_MipsTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>; def SDT_MipsBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>, @@ -88,7 +89,7 @@ def fpimm0neg : PatLeaf<(fpimm), [{ // Only S32 and D32 are supported right now. //===----------------------------------------------------------------------===// -class ADDS_FT<string opstr, RegisterClass RC, InstrItinClass Itin, bit IsComm, +class ADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin, bit IsComm, SDPatternOperator OpNode= null_frag> : InstSE<(outs RC:$fd), (ins RC:$fs, RC:$ft), !strconcat(opstr, "\t$fd, $fs, $ft"), @@ -98,15 +99,15 @@ class ADDS_FT<string opstr, RegisterClass RC, InstrItinClass Itin, bit IsComm, multiclass ADDS_M<string opstr, InstrItinClass Itin, bit IsComm, SDPatternOperator OpNode = null_frag> { - def _D32 : ADDS_FT<opstr, AFGR64, Itin, IsComm, OpNode>, + def _D32 : ADDS_FT<opstr, AFGR64RegsOpnd, Itin, IsComm, OpNode>, Requires<[NotFP64bit, HasStdEnc]>; - def _D64 : ADDS_FT<opstr, FGR64, Itin, IsComm, OpNode>, + def _D64 : ADDS_FT<opstr, FGR64RegsOpnd, Itin, IsComm, OpNode>, Requires<[IsFP64bit, HasStdEnc]> { string DecoderNamespace = "Mips64"; } } -class ABSS_FT<string opstr, RegisterClass DstRC, RegisterClass SrcRC, +class ABSS_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC, InstrItinClass Itin, SDPatternOperator OpNode= null_frag> : InstSE<(outs DstRC:$fd), (ins SrcRC:$fs), !strconcat(opstr, "\t$fd, $fs"), [(set DstRC:$fd, (OpNode SrcRC:$fs))], Itin, FrmFR>, @@ -114,44 +115,34 @@ class ABSS_FT<string opstr, RegisterClass DstRC, RegisterClass SrcRC, multiclass ABSS_M<string opstr, InstrItinClass Itin, SDPatternOperator OpNode= null_frag> { - def _D32 : ABSS_FT<opstr, AFGR64, AFGR64, Itin, OpNode>, + def _D32 : ABSS_FT<opstr, AFGR64RegsOpnd, AFGR64RegsOpnd, Itin, OpNode>, Requires<[NotFP64bit, HasStdEnc]>; - def _D64 : ABSS_FT<opstr, FGR64, FGR64, Itin, OpNode>, + def _D64 : ABSS_FT<opstr, FGR64RegsOpnd, FGR64RegsOpnd, Itin, OpNode>, Requires<[IsFP64bit, HasStdEnc]> { string DecoderNamespace = "Mips64"; } } multiclass ROUND_M<string opstr, InstrItinClass Itin> { - def _D32 : ABSS_FT<opstr, FGR32, AFGR64, Itin>, + def _D32 : ABSS_FT<opstr, FGR32RegsOpnd, AFGR64RegsOpnd, Itin>, Requires<[NotFP64bit, HasStdEnc]>; - def _D64 : ABSS_FT<opstr, FGR32, FGR64, Itin>, + def _D64 : ABSS_FT<opstr, FGR32RegsOpnd, FGR64RegsOpnd, Itin>, Requires<[IsFP64bit, HasStdEnc]> { let DecoderNamespace = "Mips64"; } } -class MFC1_FT<string opstr, RegisterClass DstRC, RegisterClass SrcRC, +class MFC1_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC, InstrItinClass Itin, SDPatternOperator OpNode= null_frag> : InstSE<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"), [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR>; -class MTC1_FT<string opstr, RegisterClass DstRC, RegisterClass SrcRC, +class MTC1_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC, InstrItinClass Itin, SDPatternOperator OpNode= null_frag> : InstSE<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"), [(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR>; -class MFC1_FT_CCR<string opstr, RegisterClass DstRC, RegisterOperand SrcRC, - InstrItinClass Itin, SDPatternOperator OpNode= null_frag> : - InstSE<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"), - [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR>; - -class MTC1_FT_CCR<string opstr, RegisterOperand DstRC, RegisterClass SrcRC, - InstrItinClass Itin, SDPatternOperator OpNode= null_frag> : - 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> { @@ -159,7 +150,7 @@ class LW_FT<string opstr, RegisterClass RC, InstrItinClass Itin, 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> { @@ -167,20 +158,20 @@ class SW_FT<string opstr, RegisterClass RC, InstrItinClass Itin, let mayStore = 1; } -class MADDS_FT<string opstr, RegisterClass RC, InstrItinClass Itin, +class MADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin, SDPatternOperator OpNode = null_frag> : InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft), !strconcat(opstr, "\t$fd, $fr, $fs, $ft"), [(set RC:$fd, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr))], Itin, FrmFR>; -class NMADDS_FT<string opstr, RegisterClass RC, InstrItinClass Itin, +class NMADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin, SDPatternOperator OpNode = null_frag> : InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft), !strconcat(opstr, "\t$fd, $fr, $fs, $ft"), [(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})"), @@ -188,7 +179,7 @@ class LWXC1_FT<string opstr, RegisterClass DRC, RegisterClass PRC, 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})"), @@ -198,13 +189,13 @@ class SWXC1_FT<string opstr, RegisterClass DRC, RegisterClass PRC, class BC1F_FT<string opstr, InstrItinClass Itin, SDPatternOperator Op = null_frag> : - InstSE<(outs), (ins brtarget:$offset), !strconcat(opstr, "\t$offset"), - [(MipsFPBrcond Op, bb:$offset)], Itin, FrmFI> { + InstSE<(outs), (ins FCCRegsOpnd:$fcc, brtarget:$offset), + !strconcat(opstr, "\t$fcc, $offset"), + [(MipsFPBrcond Op, FCCRegsOpnd:$fcc, bb:$offset)], Itin, FrmFI> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; let Defs = [AT]; - let Uses = [FCR31]; } class CEQS_FT<string typestr, RegisterClass RC, InstrItinClass Itin, @@ -212,17 +203,53 @@ class CEQS_FT<string typestr, RegisterClass RC, InstrItinClass Itin, InstSE<(outs), (ins RC:$fs, RC:$ft, condcode:$cond), !strconcat("c.$cond.", typestr, "\t$fs, $ft"), [(OpNode RC:$fs, RC:$ft, imm:$cond)], Itin, FrmFR> { - let Defs = [FCR31]; -} + let Defs = [FCC0]; + let isCodeGenOnly = 1; +} + +class C_COND_FT<string CondStr, string Typestr, RegisterOperand RC> : + InstSE<(outs), (ins RC:$fs, RC:$ft), + !strconcat("c.", CondStr, ".", Typestr, "\t$fs, $ft"), [], IIFcmp, + FrmFR>; + +multiclass C_COND_M<string TypeStr, RegisterOperand RC, bits<5> fmt> { + def C_F_#NAME : C_COND_FT<"f", TypeStr, RC>, C_COND_FM<fmt, 0>; + def C_UN_#NAME : C_COND_FT<"un", TypeStr, RC>, C_COND_FM<fmt, 1>; + def C_EQ_#NAME : C_COND_FT<"eq", TypeStr, RC>, C_COND_FM<fmt, 2>; + def C_UEQ_#NAME : C_COND_FT<"ueq", TypeStr, RC>, C_COND_FM<fmt, 3>; + def C_OLT_#NAME : C_COND_FT<"olt", TypeStr, RC>, C_COND_FM<fmt, 4>; + def C_ULT_#NAME : C_COND_FT<"ult", TypeStr, RC>, C_COND_FM<fmt, 5>; + def C_OLE_#NAME : C_COND_FT<"ole", TypeStr, RC>, C_COND_FM<fmt, 6>; + def C_ULE_#NAME : C_COND_FT<"ule", TypeStr, RC>, C_COND_FM<fmt, 7>; + def C_SF_#NAME : C_COND_FT<"sf", TypeStr, RC>, C_COND_FM<fmt, 8>; + def C_NGLE_#NAME : C_COND_FT<"ngle", TypeStr, RC>, C_COND_FM<fmt, 9>; + def C_SEQ_#NAME : C_COND_FT<"seq", TypeStr, RC>, C_COND_FM<fmt, 10>; + def C_NGL_#NAME : C_COND_FT<"ngl", TypeStr, RC>, C_COND_FM<fmt, 11>; + def C_LT_#NAME : C_COND_FT<"lt", TypeStr, RC>, C_COND_FM<fmt, 12>; + def C_NGE_#NAME : C_COND_FT<"nge", TypeStr, RC>, C_COND_FM<fmt, 13>; + def C_LE_#NAME : C_COND_FT<"le", TypeStr, RC>, C_COND_FM<fmt, 14>; + def C_NGT_#NAME : C_COND_FT<"ngt", TypeStr, RC>, C_COND_FM<fmt, 15>; +} + +defm S : C_COND_M<"s", FGR32RegsOpnd, 16>; +defm D32 : C_COND_M<"d", AFGR64RegsOpnd, 17>, + Requires<[NotFP64bit, HasStdEnc]>; +let DecoderNamespace = "Mips64" in +defm D64 : C_COND_M<"d", FGR64RegsOpnd, 17>, Requires<[IsFP64bit, HasStdEnc]>; //===----------------------------------------------------------------------===// // Floating Point Instructions //===----------------------------------------------------------------------===// -def ROUND_W_S : ABSS_FT<"round.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xc, 16>; -def TRUNC_W_S : ABSS_FT<"trunc.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xd, 16>; -def CEIL_W_S : ABSS_FT<"ceil.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xe, 16>; -def FLOOR_W_S : ABSS_FT<"floor.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xf, 16>; -def CVT_W_S : ABSS_FT<"cvt.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0x24, 16>; +def ROUND_W_S : ABSS_FT<"round.w.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0xc, 16>; +def TRUNC_W_S : ABSS_FT<"trunc.w.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0xd, 16>; +def CEIL_W_S : ABSS_FT<"ceil.w.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0xe, 16>; +def FLOOR_W_S : ABSS_FT<"floor.w.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0xf, 16>; +def CVT_W_S : ABSS_FT<"cvt.w.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0x24, 16>; defm ROUND_W : ROUND_M<"round.w.d", IIFcvt>, ABSS_FM<0xc, 17>; defm TRUNC_W : ROUND_M<"trunc.w.d", IIFcvt>, ABSS_FM<0xd, 17>; @@ -231,54 +258,72 @@ defm FLOOR_W : ROUND_M<"floor.w.d", IIFcvt>, ABSS_FM<0xf, 17>; defm CVT_W : ROUND_M<"cvt.w.d", IIFcvt>, ABSS_FM<0x24, 17>; let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace = "Mips64" in { - def ROUND_L_S : ABSS_FT<"round.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x8, 16>; - def ROUND_L_D64 : ABSS_FT<"round.l.d", FGR64, FGR64, IIFcvt>, + def ROUND_L_S : ABSS_FT<"round.l.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0x8, 16>; + def ROUND_L_D64 : ABSS_FT<"round.l.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>, ABSS_FM<0x8, 17>; - def TRUNC_L_S : ABSS_FT<"trunc.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x9, 16>; - def TRUNC_L_D64 : ABSS_FT<"trunc.l.d", FGR64, FGR64, IIFcvt>, + def TRUNC_L_S : ABSS_FT<"trunc.l.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0x9, 16>; + def TRUNC_L_D64 : ABSS_FT<"trunc.l.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>, ABSS_FM<0x9, 17>; - def CEIL_L_S : ABSS_FT<"ceil.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0xa, 16>; - def CEIL_L_D64 : ABSS_FT<"ceil.l.d", FGR64, FGR64, IIFcvt>, ABSS_FM<0xa, 17>; - def FLOOR_L_S : ABSS_FT<"floor.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0xb, 16>; - def FLOOR_L_D64 : ABSS_FT<"floor.l.d", FGR64, FGR64, IIFcvt>, + def CEIL_L_S : ABSS_FT<"ceil.l.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0xa, 16>; + def CEIL_L_D64 : ABSS_FT<"ceil.l.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>, + ABSS_FM<0xa, 17>; + def FLOOR_L_S : ABSS_FT<"floor.l.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0xb, 16>; + def FLOOR_L_D64 : ABSS_FT<"floor.l.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>, ABSS_FM<0xb, 17>; } -def CVT_S_W : ABSS_FT<"cvt.s.w", FGR32, FGR32, IIFcvt>, ABSS_FM<0x20, 20>; -def CVT_L_S : ABSS_FT<"cvt.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x25, 16>; -def CVT_L_D64: ABSS_FT<"cvt.l.d", FGR64, FGR64, IIFcvt>, ABSS_FM<0x25, 17>; +def CVT_S_W : ABSS_FT<"cvt.s.w", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0x20, 20>; +def CVT_L_S : ABSS_FT<"cvt.l.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0x25, 16>; +def CVT_L_D64: ABSS_FT<"cvt.l.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>, + ABSS_FM<0x25, 17>; let Predicates = [NotFP64bit, HasStdEnc] in { - def CVT_S_D32 : ABSS_FT<"cvt.s.d", FGR32, AFGR64, IIFcvt>, ABSS_FM<0x20, 17>; - def CVT_D32_W : ABSS_FT<"cvt.d.w", AFGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 20>; - def CVT_D32_S : ABSS_FT<"cvt.d.s", AFGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 16>; + def CVT_S_D32 : ABSS_FT<"cvt.s.d", FGR32RegsOpnd, AFGR64RegsOpnd, IIFcvt>, + ABSS_FM<0x20, 17>; + def CVT_D32_W : ABSS_FT<"cvt.d.w", AFGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0x21, 20>; + def CVT_D32_S : ABSS_FT<"cvt.d.s", AFGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0x21, 16>; } let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace = "Mips64" in { - def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32, FGR64, IIFcvt>, ABSS_FM<0x20, 17>; - def CVT_S_L : ABSS_FT<"cvt.s.l", FGR32, FGR64, IIFcvt>, ABSS_FM<0x20, 21>; - def CVT_D64_W : ABSS_FT<"cvt.d.w", FGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 20>; - def CVT_D64_S : ABSS_FT<"cvt.d.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 16>; - def CVT_D64_L : ABSS_FT<"cvt.d.l", FGR64, FGR64, IIFcvt>, ABSS_FM<0x21, 21>; + def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32RegsOpnd, FGR64RegsOpnd, IIFcvt>, + ABSS_FM<0x20, 17>; + def CVT_S_L : ABSS_FT<"cvt.s.l", FGR32RegsOpnd, FGR64RegsOpnd, IIFcvt>, + ABSS_FM<0x20, 21>; + def CVT_D64_W : ABSS_FT<"cvt.d.w", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0x21, 20>; + def CVT_D64_S : ABSS_FT<"cvt.d.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>, + ABSS_FM<0x21, 16>; + def CVT_D64_L : ABSS_FT<"cvt.d.l", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>, + ABSS_FM<0x21, 21>; } let isPseudo = 1, isCodeGenOnly = 1 in { - def PseudoCVT_S_W : ABSS_FT<"", FGR32, CPURegs, IIFcvt>; - def PseudoCVT_D32_W : ABSS_FT<"", AFGR64, CPURegs, IIFcvt>; - def PseudoCVT_S_L : ABSS_FT<"", FGR64, CPU64Regs, IIFcvt>; - def PseudoCVT_D64_W : ABSS_FT<"", FGR64, CPURegs, IIFcvt>; - def PseudoCVT_D64_L : ABSS_FT<"", FGR64, CPU64Regs, IIFcvt>; + def PseudoCVT_S_W : ABSS_FT<"", FGR32RegsOpnd, GPR32Opnd, IIFcvt>; + def PseudoCVT_D32_W : ABSS_FT<"", AFGR64RegsOpnd, GPR32Opnd, IIFcvt>; + def PseudoCVT_S_L : ABSS_FT<"", FGR64RegsOpnd, GPR64Opnd, IIFcvt>; + def PseudoCVT_D64_W : ABSS_FT<"", FGR64RegsOpnd, GPR32Opnd, IIFcvt>; + def PseudoCVT_D64_L : ABSS_FT<"", FGR64RegsOpnd, GPR64Opnd, IIFcvt>; } let Predicates = [NoNaNsFPMath, HasStdEnc] in { - def FABS_S : ABSS_FT<"abs.s", FGR32, FGR32, IIFcvt, fabs>, ABSS_FM<0x5, 16>; - def FNEG_S : ABSS_FT<"neg.s", FGR32, FGR32, IIFcvt, fneg>, ABSS_FM<0x7, 16>; + def FABS_S : ABSS_FT<"abs.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt, fabs>, + ABSS_FM<0x5, 16>; + def FNEG_S : ABSS_FT<"neg.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt, fneg>, + ABSS_FM<0x7, 16>; defm FABS : ABSS_M<"abs.d", IIFcvt, fabs>, ABSS_FM<0x5, 17>; defm FNEG : ABSS_M<"neg.d", IIFcvt, fneg>, ABSS_FM<0x7, 17>; } -def FSQRT_S : ABSS_FT<"sqrt.s", FGR32, FGR32, IIFsqrtSingle, fsqrt>, - ABSS_FM<0x4, 16>; +def FSQRT_S : ABSS_FT<"sqrt.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFsqrtSingle, + fsqrt>, ABSS_FM<0x4, 16>; defm FSQRT : ABSS_M<"sqrt.d", IIFsqrtDouble, fsqrt>, ABSS_FM<0x4, 17>; // The odd-numbered registers are only referenced when doing loads, @@ -287,134 +332,166 @@ defm FSQRT : ABSS_M<"sqrt.d", IIFsqrtDouble, fsqrt>, ABSS_FM<0x4, 17>; // regardless of register aliasing. /// Move Control Registers From/To CPU Registers -def CFC1 : MFC1_FT_CCR<"cfc1", CPURegs, CCROpnd, IIFmove>, MFC1_FM<2>; -def CTC1 : MTC1_FT_CCR<"ctc1", CCROpnd, CPURegs, IIFmove>, MFC1_FM<6>; -def MFC1 : MFC1_FT<"mfc1", CPURegs, FGR32, IIFmove, bitconvert>, MFC1_FM<0>; -def MTC1 : MTC1_FT<"mtc1", FGR32, CPURegs, IIFmove, bitconvert>, MFC1_FM<4>; -def DMFC1 : MFC1_FT<"dmfc1", CPU64Regs, FGR64, IIFmove, bitconvert>, MFC1_FM<1>; -def DMTC1 : MTC1_FT<"dmtc1", FGR64, CPU64Regs, IIFmove, bitconvert>, MFC1_FM<5>; - -def FMOV_S : ABSS_FT<"mov.s", FGR32, FGR32, IIFmove>, ABSS_FM<0x6, 16>; -def FMOV_D32 : ABSS_FT<"mov.d", AFGR64, AFGR64, IIFmove>, ABSS_FM<0x6, 17>, - Requires<[NotFP64bit, HasStdEnc]>; -def FMOV_D64 : ABSS_FT<"mov.d", FGR64, FGR64, IIFmove>, ABSS_FM<0x6, 17>, - Requires<[IsFP64bit, HasStdEnc]> { - let DecoderNamespace = "Mips64"; +def CFC1 : MFC1_FT<"cfc1", GPR32Opnd, CCROpnd, IIFmove>, MFC1_FM<2>; +def CTC1 : MTC1_FT<"ctc1", CCROpnd, GPR32Opnd, IIFmove>, MFC1_FM<6>; +def MFC1 : MFC1_FT<"mfc1", GPR32Opnd, FGR32RegsOpnd, IIFmoveC1, bitconvert>, + MFC1_FM<0>; +def MTC1 : MTC1_FT<"mtc1", FGR32RegsOpnd, GPR32Opnd, IIFmoveC1, bitconvert>, + MFC1_FM<4>; +def DMFC1 : MFC1_FT<"dmfc1", GPR64Opnd, FGR64RegsOpnd, IIFmoveC1, + bitconvert>, MFC1_FM<1>; +def DMTC1 : MTC1_FT<"dmtc1", FGR64RegsOpnd, GPR64Opnd, IIFmoveC1, + bitconvert>, MFC1_FM<5>; + +def FMOV_S : ABSS_FT<"mov.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFmove>, + ABSS_FM<0x6, 16>; +def FMOV_D32 : ABSS_FT<"mov.d", AFGR64RegsOpnd, AFGR64RegsOpnd, IIFmove>, + ABSS_FM<0x6, 17>, Requires<[NotFP64bit, HasStdEnc]>; +def FMOV_D64 : ABSS_FT<"mov.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFmove>, + ABSS_FM<0x6, 17>, Requires<[IsFP64bit, HasStdEnc]> { + let DecoderNamespace = "Mips64"; } /// 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, IIFLoad, mem64, load>, + LW_FM<0x31>; + def SWC1_P8 : SW_FT<"swc1", FGR32RegsOpnd, IIFStore, mem64, store>, + LW_FM<0x39>; + def LDC164_P8 : LW_FT<"ldc1", FGR64RegsOpnd, IIFLoad, 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, IIFStore, 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, IIFLoad, mem, load>, LW_FM<0x31>; + def SWC1 : SW_FT<"swc1", FGR32RegsOpnd, IIFStore, 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, IIFLoad, mem, load>, LW_FM<0x35>; + def SDC164 : SW_FT<"sdc1", FGR64RegsOpnd, IIFStore, 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, IIFLoad, mem, load>; + def PseudoSDC1 : SW_FT<"", AFGR64RegsOpnd, IIFStore, 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, IIFLoad, mem>, LW_FM<0x35>; + def SDC1 : SW_FT<"sdc1", AFGR64RegsOpnd, IIFStore, 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, GPR32Opnd, IIFLoad, load>, + LWXC1_FM<0>; + def SWXC1 : SWXC1_FT<"swxc1", FGR32RegsOpnd, GPR32Opnd, IIFStore, 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, GPR32Opnd, IIFLoad, load>, + LWXC1_FM<1>; + def SDXC1 : SWXC1_FT<"sdxc1", AFGR64RegsOpnd, GPR32Opnd, IIFStore, 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, GPR32Opnd, IIFLoad, load>, + LWXC1_FM<1>; + def SDXC164 : SWXC1_FT<"sdxc1", FGR64RegsOpnd, GPR32Opnd, IIFStore, 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, GPR64Opnd, IIFLoad, load>, + LWXC1_FM<0>; + def LDXC164_P8 : LWXC1_FT<"ldxc1", FGR64RegsOpnd, GPR64Opnd, IIFLoad, + load>, LWXC1_FM<1>; + def SWXC1_P8 : SWXC1_FT<"swxc1", FGR32RegsOpnd, GPR64Opnd, IIFStore, + store>, SWXC1_FM<8>; + def SDXC164_P8 : SWXC1_FT<"sdxc1", FGR64RegsOpnd, GPR64Opnd, IIFStore, + 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, GPR32Opnd, IIFLoad>, + LWXC1_FM<0x5>; + def SUXC1 : SWXC1_FT<"suxc1", AFGR64RegsOpnd, GPR32Opnd, IIFStore>, + 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, GPR32Opnd, IIFLoad>, + LWXC1_FM<0x5>; + def SUXC164 : SWXC1_FT<"suxc1", FGR64RegsOpnd, GPR32Opnd, IIFStore>, + SWXC1_FM<0xd>; } /// Floating-point Aritmetic -def FADD_S : ADDS_FT<"add.s", FGR32, IIFadd, 1, fadd>, ADDS_FM<0x00, 16>; -defm FADD : ADDS_M<"add.d", IIFadd, 1, fadd>, ADDS_FM<0x00, 17>; -def FDIV_S : ADDS_FT<"div.s", FGR32, IIFdivSingle, 0, fdiv>, ADDS_FM<0x03, 16>; -defm FDIV : ADDS_M<"div.d", IIFdivDouble, 0, fdiv>, ADDS_FM<0x03, 17>; -def FMUL_S : ADDS_FT<"mul.s", FGR32, IIFmulSingle, 1, fmul>, ADDS_FM<0x02, 16>; -defm FMUL : ADDS_M<"mul.d", IIFmulDouble, 1, fmul>, ADDS_FM<0x02, 17>; -def FSUB_S : ADDS_FT<"sub.s", FGR32, IIFadd, 0, fsub>, ADDS_FM<0x01, 16>; -defm FSUB : ADDS_M<"sub.d", IIFadd, 0, fsub>, ADDS_FM<0x01, 17>; +def FADD_S : ADDS_FT<"add.s", FGR32RegsOpnd, IIFadd, 1, fadd>, + ADDS_FM<0x00, 16>; +defm FADD : ADDS_M<"add.d", IIFadd, 1, fadd>, ADDS_FM<0x00, 17>; +def FDIV_S : ADDS_FT<"div.s", FGR32RegsOpnd, IIFdivSingle, 0, fdiv>, + ADDS_FM<0x03, 16>; +defm FDIV : ADDS_M<"div.d", IIFdivDouble, 0, fdiv>, ADDS_FM<0x03, 17>; +def FMUL_S : ADDS_FT<"mul.s", FGR32RegsOpnd, IIFmulSingle, 1, fmul>, + ADDS_FM<0x02, 16>; +defm FMUL : ADDS_M<"mul.d", IIFmulDouble, 1, fmul>, ADDS_FM<0x02, 17>; +def FSUB_S : ADDS_FT<"sub.s", FGR32RegsOpnd, IIFadd, 0, fsub>, + ADDS_FM<0x01, 16>; +defm FSUB : ADDS_M<"sub.d", IIFadd, 0, fsub>, ADDS_FM<0x01, 17>; let Predicates = [HasMips32r2, HasStdEnc] in { - def MADD_S : MADDS_FT<"madd.s", FGR32, IIFmulSingle, fadd>, MADDS_FM<4, 0>; - def MSUB_S : MADDS_FT<"msub.s", FGR32, IIFmulSingle, fsub>, MADDS_FM<5, 0>; + def MADD_S : MADDS_FT<"madd.s", FGR32RegsOpnd, IIFmulSingle, fadd>, + MADDS_FM<4, 0>; + def MSUB_S : MADDS_FT<"msub.s", FGR32RegsOpnd, IIFmulSingle, fsub>, + MADDS_FM<5, 0>; } let Predicates = [HasMips32r2, NoNaNsFPMath, HasStdEnc] in { - def NMADD_S : NMADDS_FT<"nmadd.s", FGR32, IIFmulSingle, fadd>, MADDS_FM<6, 0>; - def NMSUB_S : NMADDS_FT<"nmsub.s", FGR32, IIFmulSingle, fsub>, MADDS_FM<7, 0>; + def NMADD_S : NMADDS_FT<"nmadd.s", FGR32RegsOpnd, IIFmulSingle, fadd>, + MADDS_FM<6, 0>; + def NMSUB_S : NMADDS_FT<"nmsub.s", FGR32RegsOpnd, IIFmulSingle, fsub>, + MADDS_FM<7, 0>; } let Predicates = [HasMips32r2, NotFP64bit, HasStdEnc] in { - def MADD_D32 : MADDS_FT<"madd.d", AFGR64, IIFmulDouble, fadd>, MADDS_FM<4, 1>; - def MSUB_D32 : MADDS_FT<"msub.d", AFGR64, IIFmulDouble, fsub>, MADDS_FM<5, 1>; + def MADD_D32 : MADDS_FT<"madd.d", AFGR64RegsOpnd, IIFmulDouble, fadd>, + MADDS_FM<4, 1>; + def MSUB_D32 : MADDS_FT<"msub.d", AFGR64RegsOpnd, IIFmulDouble, fsub>, + MADDS_FM<5, 1>; } let Predicates = [HasMips32r2, NotFP64bit, NoNaNsFPMath, HasStdEnc] in { - def NMADD_D32 : NMADDS_FT<"nmadd.d", AFGR64, IIFmulDouble, fadd>, + def NMADD_D32 : NMADDS_FT<"nmadd.d", AFGR64RegsOpnd, IIFmulDouble, fadd>, MADDS_FM<6, 1>; - def NMSUB_D32 : NMADDS_FT<"nmsub.d", AFGR64, IIFmulDouble, fsub>, + def NMSUB_D32 : NMADDS_FT<"nmsub.d", AFGR64RegsOpnd, IIFmulDouble, fsub>, MADDS_FM<7, 1>; } let Predicates = [HasMips32r2, IsFP64bit, HasStdEnc], isCodeGenOnly=1 in { - def MADD_D64 : MADDS_FT<"madd.d", FGR64, IIFmulDouble, fadd>, MADDS_FM<4, 1>; - def MSUB_D64 : MADDS_FT<"msub.d", FGR64, IIFmulDouble, fsub>, MADDS_FM<5, 1>; + def MADD_D64 : MADDS_FT<"madd.d", FGR64RegsOpnd, IIFmulDouble, fadd>, + MADDS_FM<4, 1>; + def MSUB_D64 : MADDS_FT<"msub.d", FGR64RegsOpnd, IIFmulDouble, fsub>, + MADDS_FM<5, 1>; } let Predicates = [HasMips32r2, IsFP64bit, NoNaNsFPMath, HasStdEnc], isCodeGenOnly=1 in { - def NMADD_D64 : NMADDS_FT<"nmadd.d", FGR64, IIFmulDouble, fadd>, + def NMADD_D64 : NMADDS_FT<"nmadd.d", FGR64RegsOpnd, IIFmulDouble, fadd>, MADDS_FM<6, 1>; - def NMSUB_D64 : NMADDS_FT<"nmsub.d", FGR64, IIFmulDouble, fsub>, + def NMSUB_D64 : NMADDS_FT<"nmsub.d", FGR64RegsOpnd, IIFmulDouble, fsub>, MADDS_FM<7, 1>; } @@ -426,10 +503,9 @@ let Predicates = [HasMips32r2, IsFP64bit, NoNaNsFPMath, HasStdEnc], def MIPS_BRANCH_F : PatLeaf<(i32 0)>; def MIPS_BRANCH_T : PatLeaf<(i32 1)>; -let DecoderMethod = "DecodeBC1" in { def BC1F : BC1F_FT<"bc1f", IIBranch, MIPS_BRANCH_F>, BC1F_FM<0, 0>; def BC1T : BC1F_FT<"bc1t", IIBranch, MIPS_BRANCH_T>, BC1F_FM<0, 1>; -} + //===----------------------------------------------------------------------===// // Floating Point Flag Conditions //===----------------------------------------------------------------------===// @@ -463,22 +539,29 @@ def FCMP_D64 : CEQS_FT<"d", FGR64, IIFcmp, MipsFPCmp>, CEQS_FM<17>, //===----------------------------------------------------------------------===// // Floating Point Pseudo-Instructions //===----------------------------------------------------------------------===// -def MOVCCRToCCR : PseudoSE<(outs CCR:$dst), (ins CCROpnd:$src), []>; // This pseudo instr gets expanded into 2 mtc1 instrs after register // allocation. def BuildPairF64 : - PseudoSE<(outs AFGR64:$dst), - (ins CPURegs:$lo, CPURegs:$hi), - [(set AFGR64:$dst, (MipsBuildPairF64 CPURegs:$lo, CPURegs:$hi))]>; + PseudoSE<(outs AFGR64RegsOpnd:$dst), + (ins GPR32Opnd:$lo, GPR32Opnd:$hi), + [(set AFGR64RegsOpnd:$dst, + (MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))]>; // This pseudo instr gets expanded into 2 mfc1 instrs after register // allocation. // if n is 0, lower part of src is extracted. // if n is 1, higher part of src is extracted. def ExtractElementF64 : - PseudoSE<(outs CPURegs:$dst), (ins AFGR64:$src, i32imm:$n), - [(set CPURegs:$dst, (MipsExtractElementF64 AFGR64:$src, imm:$n))]>; + PseudoSE<(outs GPR32Opnd:$dst), (ins AFGR64RegsOpnd:$src, i32imm:$n), + [(set GPR32Opnd:$dst, + (MipsExtractElementF64 AFGR64RegsOpnd:$src, imm:$n))]>; + +//===----------------------------------------------------------------------===// +// InstAliases. +//===----------------------------------------------------------------------===// +def : InstAlias<"bc1t $offset", (BC1T FCC0, brtarget:$offset)>; +def : InstAlias<"bc1f $offset", (BC1F FCC0, brtarget:$offset)>; //===----------------------------------------------------------------------===// // Floating Point Patterns @@ -486,34 +569,44 @@ def ExtractElementF64 : def : MipsPat<(f32 fpimm0), (MTC1 ZERO)>; def : MipsPat<(f32 fpimm0neg), (FNEG_S (MTC1 ZERO))>; -def : MipsPat<(f32 (sint_to_fp CPURegs:$src)), (PseudoCVT_S_W CPURegs:$src)>; -def : MipsPat<(MipsTruncIntFP FGR32:$src), (TRUNC_W_S FGR32:$src)>; +def : MipsPat<(f32 (sint_to_fp GPR32Opnd:$src)), + (PseudoCVT_S_W GPR32Opnd:$src)>; +def : MipsPat<(MipsTruncIntFP FGR32RegsOpnd:$src), + (TRUNC_W_S FGR32RegsOpnd:$src)>; let Predicates = [NotFP64bit, HasStdEnc] in { - def : MipsPat<(f64 (sint_to_fp CPURegs:$src)), - (PseudoCVT_D32_W CPURegs:$src)>; - def : MipsPat<(MipsTruncIntFP AFGR64:$src), (TRUNC_W_D32 AFGR64:$src)>; - def : MipsPat<(f32 (fround AFGR64:$src)), (CVT_S_D32 AFGR64:$src)>; - def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D32_S FGR32:$src)>; + def : MipsPat<(f64 (sint_to_fp GPR32Opnd:$src)), + (PseudoCVT_D32_W GPR32Opnd:$src)>; + def : MipsPat<(MipsTruncIntFP AFGR64RegsOpnd:$src), + (TRUNC_W_D32 AFGR64RegsOpnd:$src)>; + def : MipsPat<(f32 (fround AFGR64RegsOpnd:$src)), + (CVT_S_D32 AFGR64RegsOpnd:$src)>; + def : MipsPat<(f64 (fextend FGR32RegsOpnd:$src)), + (CVT_D32_S FGR32RegsOpnd:$src)>; } let Predicates = [IsFP64bit, HasStdEnc] in { def : MipsPat<(f64 fpimm0), (DMTC1 ZERO_64)>; def : MipsPat<(f64 fpimm0neg), (FNEG_D64 (DMTC1 ZERO_64))>; - def : MipsPat<(f64 (sint_to_fp CPURegs:$src)), - (PseudoCVT_D64_W CPURegs:$src)>; - def : MipsPat<(f32 (sint_to_fp CPU64Regs:$src)), - (EXTRACT_SUBREG (PseudoCVT_S_L CPU64Regs:$src), sub_32)>; - def : MipsPat<(f64 (sint_to_fp CPU64Regs:$src)), - (PseudoCVT_D64_L CPU64Regs:$src)>; - - def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_W_D64 FGR64:$src)>; - def : MipsPat<(MipsTruncIntFP FGR32:$src), (TRUNC_L_S FGR32:$src)>; - def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_L_D64 FGR64:$src)>; - - def : MipsPat<(f32 (fround FGR64:$src)), (CVT_S_D64 FGR64:$src)>; - def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D64_S FGR32:$src)>; + def : MipsPat<(f64 (sint_to_fp GPR32Opnd:$src)), + (PseudoCVT_D64_W GPR32Opnd:$src)>; + def : MipsPat<(f32 (sint_to_fp GPR64Opnd:$src)), + (EXTRACT_SUBREG (PseudoCVT_S_L GPR64Opnd:$src), sub_32)>; + def : MipsPat<(f64 (sint_to_fp GPR64Opnd:$src)), + (PseudoCVT_D64_L GPR64Opnd:$src)>; + + def : MipsPat<(MipsTruncIntFP FGR64RegsOpnd:$src), + (TRUNC_W_D64 FGR64RegsOpnd:$src)>; + def : MipsPat<(MipsTruncIntFP FGR32RegsOpnd:$src), + (TRUNC_L_S FGR32RegsOpnd:$src)>; + def : MipsPat<(MipsTruncIntFP FGR64RegsOpnd:$src), + (TRUNC_L_D64 FGR64RegsOpnd:$src)>; + + def : MipsPat<(f32 (fround FGR64RegsOpnd:$src)), + (CVT_S_D64 FGR64RegsOpnd:$src)>; + def : MipsPat<(f64 (fextend FGR32RegsOpnd:$src)), + (CVT_D64_S FGR32RegsOpnd:$src)>; } // Patterns for loads/stores with a reg+imm operand. diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td index 14cfcf9..1322784 100644 --- a/lib/Target/Mips/MipsInstrFormats.td +++ b/lib/Target/Mips/MipsInstrFormats.td @@ -400,17 +400,6 @@ class JALR_FM { let Inst{5-0} = 9; } -class BAL_FM { - bits<16> offset; - - bits<32> Inst; - - let Inst{31-26} = 1; - let Inst{25-21} = 0; - let Inst{20-16} = 0x11; - let Inst{15-0} = offset; -} - class BGEZAL_FM<bits<5> funct> { bits<5> rs; bits<16> offset; @@ -491,6 +480,47 @@ class TEQ_FM<bits<6> funct> { } //===----------------------------------------------------------------------===// +// System calls format <op|code_|funct> +//===----------------------------------------------------------------------===// + +class SYS_FM<bits<6> funct> +{ + bits<20> code_; + bits<32> Inst; + let Inst{31-26} = 0x0; + let Inst{25-6} = code_; + let Inst{5-0} = funct; +} + +//===----------------------------------------------------------------------===// +// Break instruction format <op|code_1|funct> +//===----------------------------------------------------------------------===// + +class BRK_FM<bits<6> funct> +{ + bits<10> code_1; + bits<10> code_2; + bits<32> Inst; + let Inst{31-26} = 0x0; + let Inst{25-16} = code_1; + let Inst{15-6} = code_2; + let Inst{5-0} = funct; +} + +//===----------------------------------------------------------------------===// +// Exception return format <Cop0|1|0|funct> +//===----------------------------------------------------------------------===// + +class ER_FM<bits<6> funct> +{ + bits<32> Inst; + let Inst{31-26} = 0x10; + let Inst{25} = 1; + let Inst{24-6} = 0; + let Inst{5-0} = funct; +} + +//===----------------------------------------------------------------------===// // // FLOATING POINT INSTRUCTION FORMATS // @@ -623,13 +653,14 @@ class SWXC1_FM<bits<6> funct> { } class BC1F_FM<bit nd, bit tf> { + bits<3> fcc; bits<16> offset; bits<32> Inst; let Inst{31-26} = 0x11; let Inst{25-21} = 0x8; - let Inst{20-18} = 0; // cc + let Inst{20-18} = fcc; let Inst{17} = nd; let Inst{16} = tf; let Inst{15-0} = offset; @@ -651,6 +682,10 @@ class CEQS_FM<bits<5> fmt> { let Inst{3-0} = cond; } +class C_COND_FM<bits<5> fmt, bits<4> c> : CEQS_FM<fmt> { + let cond = c; +} + class CMov_I_F_FM<bits<6> funct, bits<5> fmt> { bits<5> fd; bits<5> fs; @@ -669,12 +704,13 @@ class CMov_I_F_FM<bits<6> funct, bits<5> fmt> { class CMov_F_I_FM<bit tf> { bits<5> rd; bits<5> rs; + bits<3> fcc; bits<32> Inst; let Inst{31-26} = 0; let Inst{25-21} = rs; - let Inst{20-18} = 0; // cc + let Inst{20-18} = fcc; let Inst{17} = 0; let Inst{16} = tf; let Inst{15-11} = rd; @@ -685,12 +721,13 @@ class CMov_F_I_FM<bit tf> { class CMov_F_F_FM<bits<5> fmt, bit tf> { bits<5> fd; bits<5> fs; + bits<3> fcc; bits<32> Inst; let Inst{31-26} = 0x11; let Inst{25-21} = fmt; - let Inst{20-18} = 0; // cc + let Inst{20-18} = fcc; let Inst{17} = 0; let Inst{16} = tf; let Inst{15-11} = fs; diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index 3144dae..eae05a3 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -61,15 +61,6 @@ MachineMemOperand *MipsInstrInfo::GetMemOperand(MachineBasicBlock &MBB, int FI, MFI.getObjectSize(FI), Align); } -MachineInstr* -MipsInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, - uint64_t Offset, const MDNode *MDPtr, - DebugLoc DL) const { - MachineInstrBuilder MIB = BuildMI(MF, DL, get(Mips::DBG_VALUE)) - .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr); - return &*MIB; -} - //===----------------------------------------------------------------------===// // Branch Analysis //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h index 0f075ec..b6480ef 100644 --- a/lib/Target/Mips/MipsInstrInfo.h +++ b/lib/Target/Mips/MipsInstrInfo.h @@ -67,11 +67,6 @@ public: bool AllowModify, SmallVectorImpl<MachineInstr*> &BranchInstrs) const; - virtual MachineInstr* emitFrameIndexDebugValue(MachineFunction &MF, - int FrameIx, uint64_t Offset, - const MDNode *MDPtr, - DebugLoc DL) const; - /// Insert nop instruction when hazard condition is found virtual void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const; diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index dc3e4be..b9e8895 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -250,6 +250,12 @@ def simm16 : Operand<i32> { def simm20 : Operand<i32> { } +def uimm20 : Operand<i32> { +} + +def uimm10 : Operand<i32> { +} + def simm16_64 : Operand<i64>; def shamt : Operand<i32>; @@ -266,7 +272,7 @@ def MipsMemAsmOperand : AsmOperandClass { // Address operand def mem : Operand<i32> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops CPURegs, simm16); + let MIOperandInfo = (ops GPR32, simm16); let EncoderMethod = "getMemEncoding"; let ParserMatchClass = MipsMemAsmOperand; let OperandType = "OPERAND_MEMORY"; @@ -274,7 +280,7 @@ def mem : Operand<i32> { def mem64 : Operand<i64> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops CPU64Regs, simm16_64); + let MIOperandInfo = (ops GPR64, simm16_64); let EncoderMethod = "getMemEncoding"; let ParserMatchClass = MipsMemAsmOperand; let OperandType = "OPERAND_MEMORY"; @@ -282,14 +288,14 @@ def mem64 : Operand<i64> { def mem_ea : Operand<i32> { let PrintMethod = "printMemOperandEA"; - let MIOperandInfo = (ops CPURegs, simm16); + let MIOperandInfo = (ops GPR32, simm16); let EncoderMethod = "getMemEncoding"; let OperandType = "OPERAND_MEMORY"; } def mem_ea_64 : Operand<i64> { let PrintMethod = "printMemOperandEA"; - let MIOperandInfo = (ops CPU64Regs, simm16_64); + let MIOperandInfo = (ops GPR64, simm16_64); let EncoderMethod = "getMemEncoding"; let OperandType = "OPERAND_MEMORY"; } @@ -384,51 +390,52 @@ class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0, // Arithmetic and logical instructions with 2 register operands. class ArithLogicI<string opstr, Operand Od, RegisterOperand RO, + InstrItinClass Itin = NoItinerary, SDPatternOperator imm_type = null_frag, SDPatternOperator OpNode = null_frag> : InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16), !strconcat(opstr, "\t$rt, $rs, $imm16"), [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))], - IIAlu, FrmI, opstr> { + Itin, FrmI, opstr> { let isReMaterializable = 1; let TwoOperandAliasConstraint = "$rs = $rt"; } // Arithmetic Multiply ADD/SUB class MArithR<string opstr, bit isComm = 0> : - InstSE<(outs), (ins CPURegsOpnd:$rs, CPURegsOpnd:$rt), - !strconcat(opstr, "\t$rs, $rt"), [], IIImul, FrmR> { + InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), + !strconcat(opstr, "\t$rs, $rt"), [], IIImult, FrmR> { let Defs = [HI, LO]; let Uses = [HI, LO]; let isCommutable = isComm; } // Logical -class LogicNOR<string opstr, RegisterOperand RC>: - InstSE<(outs RC:$rd), (ins RC:$rs, RC:$rt), +class LogicNOR<string opstr, RegisterOperand RO>: + InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RC:$rd, (not (or RC:$rs, RC:$rt)))], IIAlu, FrmR, opstr> { + [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], IIArith, FrmR, opstr> { let isCommutable = 1; } // Shifts class shift_rotate_imm<string opstr, Operand ImmOpnd, - RegisterOperand RC, SDPatternOperator OpNode = null_frag, + RegisterOperand RO, SDPatternOperator OpNode = null_frag, SDPatternOperator PF = null_frag> : - InstSE<(outs RC:$rd), (ins RC:$rt, ImmOpnd:$shamt), + InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt), !strconcat(opstr, "\t$rd, $rt, $shamt"), - [(set RC:$rd, (OpNode RC:$rt, PF:$shamt))], IIAlu, FrmR, opstr>; + [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], IIArith, FrmR, opstr>; -class shift_rotate_reg<string opstr, RegisterOperand RC, +class shift_rotate_reg<string opstr, RegisterOperand RO, SDPatternOperator OpNode = null_frag>: - InstSE<(outs RC:$rd), (ins CPURegsOpnd:$rs, RC:$rt), + InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs), !strconcat(opstr, "\t$rd, $rt, $rs"), - [(set RC:$rd, (OpNode RC:$rt, CPURegsOpnd:$rs))], IIAlu, FrmR, opstr>; + [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], IIArith, FrmR, opstr>; // Load Upper Imediate -class LoadUpper<string opstr, RegisterClass RC, Operand Imm>: - InstSE<(outs RC:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"), - [], IIAlu, FrmI>, IsAsCheapAsAMove { +class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>: + InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"), + [], IIArith, FrmI>, IsAsCheapAsAMove { let neverHasSideEffects = 1; let isReMaterializable = 1; } @@ -442,43 +449,47 @@ class FMem<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern, } // Memory Load/Store -class Load<string opstr, SDPatternOperator OpNode, RegisterClass RC, - Operand MemOpnd, ComplexPattern Addr, string ofsuffix> : - InstSE<(outs RC:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(set RC:$rt, (OpNode Addr:$addr))], NoItinerary, FrmI, +class Load<string opstr, SDPatternOperator OpNode, DAGOperand RO, + InstrItinClass Itin, Operand MemOpnd, ComplexPattern Addr, + string ofsuffix> : + InstSE<(outs RO:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set RO:$rt, (OpNode Addr:$addr))], NoItinerary, FrmI, !strconcat(opstr, ofsuffix)> { let DecoderMethod = "DecodeMem"; let canFoldAsLoad = 1; let mayLoad = 1; } -class Store<string opstr, SDPatternOperator OpNode, RegisterClass RC, - Operand MemOpnd, ComplexPattern Addr, string ofsuffix> : - InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode RC:$rt, Addr:$addr)], NoItinerary, FrmI, +class Store<string opstr, SDPatternOperator OpNode, DAGOperand RO, + InstrItinClass Itin, Operand MemOpnd, ComplexPattern Addr, + string ofsuffix> : + InstSE<(outs), (ins RO:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode RO:$rt, Addr:$addr)], NoItinerary, FrmI, !strconcat(opstr, ofsuffix)> { let DecoderMethod = "DecodeMem"; let mayStore = 1; } -multiclass LoadM<string opstr, RegisterClass RC, +multiclass LoadM<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag, + InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> { - def NAME : Load<opstr, OpNode, RC, mem, Addr, "">, + def NAME : Load<opstr, OpNode, RO, Itin, mem, Addr, "">, Requires<[NotN64, HasStdEnc]>; - def _P8 : Load<opstr, OpNode, RC, mem64, Addr, "_p8">, + def _P8 : Load<opstr, OpNode, RO, Itin, mem64, Addr, "_p8">, Requires<[IsN64, HasStdEnc]> { let DecoderNamespace = "Mips64"; let isCodeGenOnly = 1; } } -multiclass StoreM<string opstr, RegisterClass RC, +multiclass StoreM<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag, + InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> { - def NAME : Store<opstr, OpNode, RC, mem, Addr, "">, + def NAME : Store<opstr, OpNode, RO, Itin, mem, Addr, "">, Requires<[NotN64, HasStdEnc]>; - def _P8 : Store<opstr, OpNode, RC, mem64, Addr, "_p8">, + def _P8 : Store<opstr, OpNode, RO, Itin, mem64, Addr, "_p8">, Requires<[IsN64, HasStdEnc]> { let DecoderNamespace = "Mips64"; let isCodeGenOnly = 1; @@ -487,36 +498,36 @@ multiclass StoreM<string opstr, RegisterClass RC, // Load/Store Left/Right let canFoldAsLoad = 1 in -class LoadLeftRight<string opstr, SDNode OpNode, RegisterClass RC, +class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO, Operand MemOpnd> : - InstSE<(outs RC:$rt), (ins MemOpnd:$addr, RC:$src), + InstSE<(outs RO:$rt), (ins MemOpnd:$addr, RO:$src), !strconcat(opstr, "\t$rt, $addr"), - [(set RC:$rt, (OpNode addr:$addr, RC:$src))], NoItinerary, FrmI> { + [(set RO:$rt, (OpNode addr:$addr, RO:$src))], NoItinerary, FrmI> { let DecoderMethod = "DecodeMem"; string Constraints = "$src = $rt"; } -class StoreLeftRight<string opstr, SDNode OpNode, RegisterClass RC, +class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO, Operand MemOpnd>: - InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode RC:$rt, addr:$addr)], NoItinerary, FrmI> { + InstSE<(outs), (ins RO:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode RO:$rt, addr:$addr)], NoItinerary, FrmI> { let DecoderMethod = "DecodeMem"; } -multiclass LoadLeftRightM<string opstr, SDNode OpNode, RegisterClass RC> { - def NAME : LoadLeftRight<opstr, OpNode, RC, mem>, +multiclass LoadLeftRightM<string opstr, SDNode OpNode, RegisterOperand RO> { + def NAME : LoadLeftRight<opstr, OpNode, RO, mem>, Requires<[NotN64, HasStdEnc]>; - def _P8 : LoadLeftRight<opstr, OpNode, RC, mem64>, + def _P8 : LoadLeftRight<opstr, OpNode, RO, mem64>, Requires<[IsN64, HasStdEnc]> { let DecoderNamespace = "Mips64"; let isCodeGenOnly = 1; } } -multiclass StoreLeftRightM<string opstr, SDNode OpNode, RegisterClass RC> { - def NAME : StoreLeftRight<opstr, OpNode, RC, mem>, +multiclass StoreLeftRightM<string opstr, SDNode OpNode, RegisterOperand RO> { + def NAME : StoreLeftRight<opstr, OpNode, RO, mem>, Requires<[NotN64, HasStdEnc]>; - def _P8 : StoreLeftRight<opstr, OpNode, RC, mem64>, + def _P8 : StoreLeftRight<opstr, OpNode, RO, mem64>, Requires<[IsN64, HasStdEnc]> { let DecoderNamespace = "Mips64"; let isCodeGenOnly = 1; @@ -524,10 +535,10 @@ multiclass StoreLeftRightM<string opstr, SDNode OpNode, RegisterClass RC> { } // Conditional Branch -class CBranch<string opstr, PatFrag cond_op, RegisterOperand RC> : - InstSE<(outs), (ins RC:$rs, RC:$rt, brtarget:$offset), +class CBranch<string opstr, PatFrag cond_op, RegisterOperand RO> : + InstSE<(outs), (ins RO:$rs, RO:$rt, brtarget:$offset), !strconcat(opstr, "\t$rs, $rt, $offset"), - [(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$offset)], IIBranch, + [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch, FrmI> { let isBranch = 1; let isTerminator = 1; @@ -535,10 +546,10 @@ class CBranch<string opstr, PatFrag cond_op, RegisterOperand RC> : let Defs = [AT]; } -class CBranchZero<string opstr, PatFrag cond_op, RegisterOperand RC> : - InstSE<(outs), (ins RC:$rs, brtarget:$offset), +class CBranchZero<string opstr, PatFrag cond_op, RegisterOperand RO> : + InstSE<(outs), (ins RO:$rs, brtarget:$offset), !strconcat(opstr, "\t$rs, $offset"), - [(brcond (i32 (cond_op RC:$rs, 0)), bb:$offset)], IIBranch, FrmI> { + [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch, FrmI> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; @@ -546,18 +557,18 @@ class CBranchZero<string opstr, PatFrag cond_op, RegisterOperand RC> : } // SetCC -class SetCC_R<string opstr, PatFrag cond_op, RegisterClass RC> : - InstSE<(outs CPURegsOpnd:$rd), (ins RC:$rs, RC:$rt), +class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> : + InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set CPURegsOpnd:$rd, (cond_op RC:$rs, RC:$rt))], - IIAlu, FrmR, opstr>; + [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))], + IIslt, FrmR, opstr>; class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type, - RegisterClass RC>: - InstSE<(outs CPURegsOpnd:$rt), (ins RC:$rs, Od:$imm16), + RegisterOperand RO>: + InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16), !strconcat(opstr, "\t$rt, $rs, $imm16"), - [(set CPURegsOpnd:$rt, (cond_op RC:$rs, imm_type:$imm16))], - IIAlu, FrmI, opstr>; + [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))], + IIslt, FrmI, opstr>; // Jump class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator, @@ -585,17 +596,17 @@ class UncondBranch<string opstr> : // Base class for indirect branch and return instruction classes. let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in -class JumpFR<RegisterClass RC, SDPatternOperator operator = null_frag>: - InstSE<(outs), (ins RC:$rs), "jr\t$rs", [(operator RC:$rs)], IIBranch, FrmR>; +class JumpFR<RegisterOperand RO, SDPatternOperator operator = null_frag>: + InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch, FrmR>; // Indirect branch -class IndirectBranch<RegisterClass RC>: JumpFR<RC, brind> { +class IndirectBranch<RegisterOperand RO>: JumpFR<RO, brind> { let isBranch = 1; let isIndirectBranch = 1; } // Return instruction -class RetBase<RegisterClass RC>: JumpFR<RC> { +class RetBase<RegisterOperand RO>: JumpFR<RO> { let isReturn = 1; let isCodeGenOnly = 1; let hasCtrlDep = 1; @@ -610,13 +621,13 @@ let isCall=1, hasDelaySlot=1, Defs = [RA] in { let DecoderMethod = "DecodeJumpTarget"; } - class JumpLinkRegPseudo<RegisterClass RC, Instruction JALRInst, - Register RetReg>: - PseudoSE<(outs), (ins RC:$rs), [(MipsJmpLink RC:$rs)], IIBranch>, - PseudoInstExpansion<(JALRInst RetReg, RC:$rs)>; + class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst, + Register RetReg, RegisterOperand ResRO = RO>: + PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], IIBranch>, + PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>; - class JumpLinkReg<string opstr, RegisterClass RC>: - InstSE<(outs RC:$rd), (ins RC:$rs), !strconcat(opstr, "\t$rd, $rs"), + class JumpLinkReg<string opstr, RegisterOperand RO>: + InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), [], IIBranch, FrmR>; class BGEZAL_FT<string opstr, RegisterOperand RO> : @@ -625,8 +636,9 @@ let isCall=1, hasDelaySlot=1, Defs = [RA] in { } -class BAL_FT : - InstSE<(outs), (ins brtarget:$offset), "bal\t$offset", [], IIBranch, FrmI> { +class BAL_BR_Pseudo<Instruction RealInst> : + PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>, + PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> { let isBranch = 1; let isTerminator = 1; let isBarrier = 1; @@ -634,6 +646,20 @@ class BAL_FT : let Defs = [RA]; } +// Syscall +class SYS_FT<string opstr> : + InstSE<(outs), (ins uimm20:$code_), + !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI>; +// Break +class BRK_FT<string opstr> : + InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2), + !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary, FrmOther>; + +// (D)Eret +class ER_FT<string opstr> : + InstSE<(outs), (ins), + opstr, [], NoItinerary, FrmOther>; + // Sync let hasSideEffects = 1 in class SYNC_FT : @@ -673,11 +699,11 @@ class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1, // operands. class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode> : PseudoSE<(outs ACRegs:$ac), - (ins CPURegsOpnd:$rs, CPURegsOpnd:$rt, ACRegs:$acin), + (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACRegs:$acin), [(set ACRegs:$ac, - (OpNode CPURegsOpnd:$rs, CPURegsOpnd:$rt, ACRegs:$acin))], - IIImul>, - PseudoInstExpansion<(RealInst CPURegsOpnd:$rs, CPURegsOpnd:$rt)> { + (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACRegs:$acin))], + IIImult>, + PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> { string Constraints = "$acin = $ac"; } @@ -689,21 +715,21 @@ class Div<string opstr, InstrItinClass itin, RegisterOperand RO, } // Move from Hi/Lo -class MoveFromLOHI<string opstr, RegisterClass RC, list<Register> UseRegs>: - InstSE<(outs RC:$rd), (ins), !strconcat(opstr, "\t$rd"), [], IIHiLo, FrmR> { +class MoveFromLOHI<string opstr, RegisterOperand RO, list<Register> UseRegs>: + InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], IIHiLo, FrmR> { let Uses = UseRegs; let neverHasSideEffects = 1; } -class MoveToLOHI<string opstr, RegisterClass RC, list<Register> DefRegs>: - InstSE<(outs), (ins RC:$rs), !strconcat(opstr, "\t$rs"), [], IIHiLo, FrmR> { +class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>: + InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], IIHiLo, FrmR> { let Defs = DefRegs; let neverHasSideEffects = 1; } -class EffectiveAddress<string opstr, RegisterClass RC, Operand Mem> : - InstSE<(outs RC:$rt), (ins Mem:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(set RC:$rt, addr:$addr)], NoItinerary, FrmI> { +class EffectiveAddress<string opstr, RegisterOperand RO, Operand Mem> : + InstSE<(outs RO:$rt), (ins Mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set RO:$rt, addr:$addr)], NoItinerary, FrmI> { let isCodeGenOnly = 1; let DecoderMethod = "DecodeMem"; } @@ -711,19 +737,19 @@ class EffectiveAddress<string opstr, RegisterClass RC, Operand Mem> : // Count Leading Ones/Zeros in Word class CountLeading0<string opstr, RegisterOperand RO>: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RO:$rd, (ctlz RO:$rs))], IIAlu, FrmR>, + [(set RO:$rd, (ctlz RO:$rs))], IIArith, FrmR>, Requires<[HasBitCount, HasStdEnc]>; class CountLeading1<string opstr, RegisterOperand RO>: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RO:$rd, (ctlz (not RO:$rs)))], IIAlu, FrmR>, + [(set RO:$rd, (ctlz (not RO:$rs)))], IIArith, FrmR>, Requires<[HasBitCount, HasStdEnc]>; // Sign Extend in Register. -class SignExtInReg<string opstr, ValueType vt, RegisterClass RC> : - InstSE<(outs RC:$rd), (ins RC:$rt), !strconcat(opstr, "\t$rd, $rt"), - [(set RC:$rd, (sext_inreg RC:$rt, vt))], NoItinerary, FrmR> { +class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO> : + InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), + [(set RO:$rd, (sext_inreg RO:$rt, vt))], IIseb, FrmR> { let Predicates = [HasSEInReg, HasStdEnc]; } @@ -736,9 +762,9 @@ class SubwordSwap<string opstr, RegisterOperand RO>: } // Read Hardware -class ReadHardware<RegisterClass CPURegClass, RegisterOperand RO> : - InstSE<(outs CPURegClass:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [], - IIAlu, FrmR>; +class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> : + InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [], + IIArith, FrmR>; // Ext and Ins class ExtBase<string opstr, RegisterOperand RO>: @@ -764,11 +790,8 @@ class Atomic2Ops<PatFrag Op, RegisterClass DRC, RegisterClass PRC> : [(set DRC:$dst, (Op PRC:$ptr, DRC:$incr))]>; multiclass Atomic2Ops32<PatFrag Op> { - def NAME : Atomic2Ops<Op, CPURegs, CPURegs>, Requires<[NotN64, HasStdEnc]>; - def _P8 : Atomic2Ops<Op, CPURegs, CPU64Regs>, - Requires<[IsN64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; - } + def NAME : Atomic2Ops<Op, GPR32, GPR32>, Requires<[NotN64, HasStdEnc]>; + def _P8 : Atomic2Ops<Op, GPR32, GPR64>, Requires<[IsN64, HasStdEnc]>; } // Atomic Compare & Swap. @@ -777,12 +800,10 @@ class AtomicCmpSwap<PatFrag Op, RegisterClass DRC, RegisterClass PRC> : [(set DRC:$dst, (Op PRC:$ptr, DRC:$cmp, DRC:$swap))]>; multiclass AtomicCmpSwap32<PatFrag Op> { - def NAME : AtomicCmpSwap<Op, CPURegs, CPURegs>, + def NAME : AtomicCmpSwap<Op, GPR32, GPR32>, Requires<[NotN64, HasStdEnc]>; - def _P8 : AtomicCmpSwap<Op, CPURegs, CPU64Regs>, - Requires<[IsN64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; - } + def _P8 : AtomicCmpSwap<Op, GPR32, GPR64>, + Requires<[IsN64, HasStdEnc]>; } class LLBase<string opstr, RegisterOperand RO, Operand Mem> : @@ -803,6 +824,11 @@ class SCBase<string opstr, RegisterOperand RO, Operand Mem> : class MFC3OP<dag outs, dag ins, string asmstr> : InstSE<outs, ins, asmstr, [], NoItinerary, FrmFR>; +let isBarrier = 1, isTerminator = 1, isCodeGenOnly = 1 in +def TRAP : InstSE<(outs), (ins), "break", [(trap)], NoItinerary, FrmOther> { + let Inst = 0x0000000d; +} + //===----------------------------------------------------------------------===// // Pseudo instructions //===----------------------------------------------------------------------===// @@ -848,9 +874,9 @@ let usesCustomInserter = 1 in { } /// Pseudo instructions for loading and storing accumulator registers. -let isPseudo = 1 in { - defm LOAD_AC64 : LoadM<"load_ac64", ACRegs>; - defm STORE_AC64 : StoreM<"store_ac64", ACRegs>; +let isPseudo = 1, isCodeGenOnly = 1 in { + defm LOAD_AC64 : LoadM<"", ACRegs>; + defm STORE_AC64 : StoreM<"", ACRegs>; } //===----------------------------------------------------------------------===// @@ -861,114 +887,125 @@ let isPseudo = 1 in { //===----------------------------------------------------------------------===// /// Arithmetic Instructions (ALU Immediate) -def ADDiu : MMRel, ArithLogicI<"addiu", simm16, CPURegsOpnd, immSExt16, add>, +def ADDiu : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd, IIArith, immSExt16, + add>, ADDI_FM<0x9>, IsAsCheapAsAMove; -def ADDi : MMRel, ArithLogicI<"addi", simm16, CPURegsOpnd>, ADDI_FM<0x8>; -def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>, +def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>; +def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>, SLTI_FM<0xa>; -def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>, +def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>, SLTI_FM<0xb>; -def ANDi : MMRel, ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, and>, +def ANDi : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd, IILogic, immZExt16, + and>, ADDI_FM<0xc>; -def ORi : MMRel, ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>, +def ORi : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, IILogic, immZExt16, + or>, ADDI_FM<0xd>; -def XORi : MMRel, ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, xor>, +def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, IILogic, immZExt16, + xor>, ADDI_FM<0xe>; -def LUi : MMRel, LoadUpper<"lui", CPURegs, uimm16>, LUI_FM; +def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM; /// Arithmetic Instructions (3-Operand, R-Type) -def ADDu : MMRel, ArithLogicR<"addu", CPURegsOpnd, 1, IIAlu, add>, +def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, IIArith, add>, ADD_FM<0, 0x21>; -def SUBu : MMRel, ArithLogicR<"subu", CPURegsOpnd, 0, IIAlu, sub>, +def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, IIArith, sub>, ADD_FM<0, 0x23>; -def MUL : MMRel, ArithLogicR<"mul", CPURegsOpnd, 1, IIImul, mul>, +def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, IIImul, mul>, ADD_FM<0x1c, 2>; -def ADD : MMRel, ArithLogicR<"add", CPURegsOpnd>, ADD_FM<0, 0x20>; -def SUB : MMRel, ArithLogicR<"sub", CPURegsOpnd>, ADD_FM<0, 0x22>; -def SLT : MMRel, SetCC_R<"slt", setlt, CPURegs>, ADD_FM<0, 0x2a>; -def SLTu : MMRel, SetCC_R<"sltu", setult, CPURegs>, ADD_FM<0, 0x2b>; -def AND : MMRel, ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>, +def ADD : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>; +def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>; +def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>; +def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>; +def AND : MMRel, ArithLogicR<"and", GPR32Opnd, 1, IILogic, and>, ADD_FM<0, 0x24>; -def OR : MMRel, ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>, +def OR : MMRel, ArithLogicR<"or", GPR32Opnd, 1, IILogic, or>, ADD_FM<0, 0x25>; -def XOR : MMRel, ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>, +def XOR : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, IILogic, xor>, ADD_FM<0, 0x26>; -def NOR : MMRel, LogicNOR<"nor", CPURegsOpnd>, ADD_FM<0, 0x27>; +def NOR : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>; /// Shift Instructions -def SLL : MMRel, shift_rotate_imm<"sll", shamt, CPURegsOpnd, shl, immZExt5>, +def SLL : MMRel, shift_rotate_imm<"sll", shamt, GPR32Opnd, shl, immZExt5>, SRA_FM<0, 0>; -def SRL : MMRel, shift_rotate_imm<"srl", shamt, CPURegsOpnd, srl, immZExt5>, +def SRL : MMRel, shift_rotate_imm<"srl", shamt, GPR32Opnd, srl, immZExt5>, SRA_FM<2, 0>; -def SRA : MMRel, shift_rotate_imm<"sra", shamt, CPURegsOpnd, sra, immZExt5>, +def SRA : MMRel, shift_rotate_imm<"sra", shamt, GPR32Opnd, sra, immZExt5>, SRA_FM<3, 0>; -def SLLV : MMRel, shift_rotate_reg<"sllv", CPURegsOpnd, shl>, SRLV_FM<4, 0>; -def SRLV : MMRel, shift_rotate_reg<"srlv", CPURegsOpnd, srl>, SRLV_FM<6, 0>; -def SRAV : MMRel, shift_rotate_reg<"srav", CPURegsOpnd, sra>, SRLV_FM<7, 0>; +def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, shl>, SRLV_FM<4, 0>; +def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, srl>, SRLV_FM<6, 0>; +def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, sra>, SRLV_FM<7, 0>; // Rotate Instructions let Predicates = [HasMips32r2, HasStdEnc] in { - def ROTR : MMRel, shift_rotate_imm<"rotr", shamt, CPURegsOpnd, rotr, + def ROTR : MMRel, shift_rotate_imm<"rotr", shamt, GPR32Opnd, rotr, immZExt5>, SRA_FM<2, 1>; - def ROTRV : MMRel, shift_rotate_reg<"rotrv", CPURegsOpnd, rotr>, + def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, rotr>, SRLV_FM<6, 1>; } /// Load and Store Instructions /// aligned -defm LB : LoadM<"lb", CPURegs, sextloadi8>, MMRel, LW_FM<0x20>; -defm LBu : LoadM<"lbu", CPURegs, zextloadi8, addrDefault>, MMRel, LW_FM<0x24>; -defm LH : LoadM<"lh", CPURegs, sextloadi16, addrDefault>, MMRel, LW_FM<0x21>; -defm LHu : LoadM<"lhu", CPURegs, zextloadi16>, MMRel, LW_FM<0x25>; -defm LW : LoadM<"lw", CPURegs, load, addrDefault>, MMRel, LW_FM<0x23>; -defm SB : StoreM<"sb", CPURegs, truncstorei8>, MMRel, LW_FM<0x28>; -defm SH : StoreM<"sh", CPURegs, truncstorei16>, MMRel, LW_FM<0x29>; -defm SW : StoreM<"sw", CPURegs, store>, MMRel, LW_FM<0x2b>; +defm LB : LoadM<"lb", GPR32Opnd, sextloadi8, IILoad>, MMRel, LW_FM<0x20>; +defm LBu : LoadM<"lbu", GPR32Opnd, zextloadi8, IILoad, addrDefault>, MMRel, + LW_FM<0x24>; +defm LH : LoadM<"lh", GPR32Opnd, sextloadi16, IILoad, addrDefault>, MMRel, + LW_FM<0x21>; +defm LHu : LoadM<"lhu", GPR32Opnd, zextloadi16, IILoad>, MMRel, LW_FM<0x25>; +defm LW : LoadM<"lw", GPR32Opnd, load, IILoad, addrDefault>, MMRel, LW_FM<0x23>; +defm SB : StoreM<"sb", GPR32Opnd, truncstorei8, IIStore>, MMRel, LW_FM<0x28>; +defm SH : StoreM<"sh", GPR32Opnd, truncstorei16, IIStore>, MMRel, LW_FM<0x29>; +defm SW : StoreM<"sw", GPR32Opnd, store, IIStore>, MMRel, LW_FM<0x2b>; /// load/store left/right -defm LWL : LoadLeftRightM<"lwl", MipsLWL, CPURegs>, LW_FM<0x22>; -defm LWR : LoadLeftRightM<"lwr", MipsLWR, CPURegs>, LW_FM<0x26>; -defm SWL : StoreLeftRightM<"swl", MipsSWL, CPURegs>, LW_FM<0x2a>; -defm SWR : StoreLeftRightM<"swr", MipsSWR, CPURegs>, LW_FM<0x2e>; +defm LWL : LoadLeftRightM<"lwl", MipsLWL, GPR32Opnd>, LW_FM<0x22>; +defm LWR : LoadLeftRightM<"lwr", MipsLWR, GPR32Opnd>, LW_FM<0x26>; +defm SWL : StoreLeftRightM<"swl", MipsSWL, GPR32Opnd>, LW_FM<0x2a>; +defm SWR : StoreLeftRightM<"swr", MipsSWR, GPR32Opnd>, LW_FM<0x2e>; def SYNC : SYNC_FT, SYNC_FM; -def TEQ : TEQ_FT<"teq", CPURegsOpnd>, TEQ_FM<0x34>; +def TEQ : TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>; + +def BREAK : BRK_FT<"break">, BRK_FM<0xd>; +def SYSCALL : SYS_FT<"syscall">, SYS_FM<0xc>; + +def ERET : ER_FT<"eret">, ER_FM<0x18>; +def DERET : ER_FT<"deret">, ER_FM<0x1f>; /// Load-linked, Store-conditional let Predicates = [NotN64, HasStdEnc] in { - def LL : LLBase<"ll", CPURegsOpnd, mem>, LW_FM<0x30>; - def SC : SCBase<"sc", CPURegsOpnd, mem>, LW_FM<0x38>; + def LL : LLBase<"ll", GPR32Opnd, mem>, LW_FM<0x30>; + def SC : SCBase<"sc", GPR32Opnd, mem>, LW_FM<0x38>; } let Predicates = [IsN64, HasStdEnc], DecoderNamespace = "Mips64" in { - def LL_P8 : LLBase<"ll", CPURegsOpnd, mem64>, LW_FM<0x30>; - def SC_P8 : SCBase<"sc", CPURegsOpnd, mem64>, LW_FM<0x38>; + def LL_P8 : LLBase<"ll", GPR32Opnd, mem64>, LW_FM<0x30>; + def SC_P8 : SCBase<"sc", GPR32Opnd, mem64>, LW_FM<0x38>; } /// Jump and Branch Instructions def J : JumpFJ<jmptarget, "j", br, bb>, FJ<2>, Requires<[RelocStatic, HasStdEnc]>, IsBranch; -def JR : IndirectBranch<CPURegs>, MTLO_FM<8>; +def JR : IndirectBranch<GPR32Opnd>, MTLO_FM<8>; def B : UncondBranch<"b">, B_FM; -def BEQ : CBranch<"beq", seteq, CPURegsOpnd>, BEQ_FM<4>; -def BNE : CBranch<"bne", setne, CPURegsOpnd>, BEQ_FM<5>; -def BGEZ : CBranchZero<"bgez", setge, CPURegsOpnd>, BGEZ_FM<1, 1>; -def BGTZ : CBranchZero<"bgtz", setgt, CPURegsOpnd>, BGEZ_FM<7, 0>; -def BLEZ : CBranchZero<"blez", setle, CPURegsOpnd>, BGEZ_FM<6, 0>; -def BLTZ : CBranchZero<"bltz", setlt, CPURegsOpnd>, BGEZ_FM<1, 0>; - -def BAL_BR: BAL_FT, BAL_FM; +def BEQ : CBranch<"beq", seteq, GPR32Opnd>, BEQ_FM<4>; +def BNE : CBranch<"bne", setne, GPR32Opnd>, BEQ_FM<5>; +def BGEZ : CBranchZero<"bgez", setge, GPR32Opnd>, BGEZ_FM<1, 1>; +def BGTZ : CBranchZero<"bgtz", setgt, GPR32Opnd>, BGEZ_FM<7, 0>; +def BLEZ : CBranchZero<"blez", setle, GPR32Opnd>, BGEZ_FM<6, 0>; +def BLTZ : CBranchZero<"bltz", setlt, GPR32Opnd>, BGEZ_FM<1, 0>; def JAL : JumpLink<"jal">, FJ<3>; -def JALR : JumpLinkReg<"jalr", CPURegs>, JALR_FM; -def JALRPseudo : JumpLinkRegPseudo<CPURegs, JALR, RA>; -def BGEZAL : BGEZAL_FT<"bgezal", CPURegsOpnd>, BGEZAL_FM<0x11>; -def BLTZAL : BGEZAL_FT<"bltzal", CPURegsOpnd>, BGEZAL_FM<0x10>; +def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM; +def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>; +def BGEZAL : BGEZAL_FT<"bgezal", GPR32Opnd>, BGEZAL_FM<0x11>; +def BLTZAL : BGEZAL_FT<"bltzal", GPR32Opnd>, BGEZAL_FM<0x10>; +def BAL_BR : BAL_BR_Pseudo<BGEZAL>; def TAILCALL : JumpFJ<calltarget, "j", MipsTailCall, imm>, FJ<2>, IsTailCall; -def TAILCALL_R : JumpFR<CPURegs, MipsTailCall>, MTLO_FM<8>, IsTailCall; +def TAILCALL_R : JumpFR<GPR32Opnd, MipsTailCall>, MTLO_FM<8>, IsTailCall; -def RET : RetBase<CPURegs>, MTLO_FM<8>; +def RET : RetBase<GPR32Opnd>, MTLO_FM<8>; // Exception handling related node and instructions. // The conversion sequence is: @@ -984,42 +1021,42 @@ def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET, [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in { - def MIPSeh_return32 : MipsPseudo<(outs), (ins CPURegs:$spoff, CPURegs:$dst), - [(MIPSehret CPURegs:$spoff, CPURegs:$dst)]>; - def MIPSeh_return64 : MipsPseudo<(outs), (ins CPU64Regs:$spoff, - CPU64Regs:$dst), - [(MIPSehret CPU64Regs:$spoff, CPU64Regs:$dst)]>; + def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst), + [(MIPSehret GPR32:$spoff, GPR32:$dst)]>; + def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff, + GPR64:$dst), + [(MIPSehret GPR64:$spoff, GPR64:$dst)]>; } /// Multiply and Divide Instructions. -def MULT : MMRel, Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>, +def MULT : MMRel, Mult<"mult", IIImult, GPR32Opnd, [HI, LO]>, MULT_FM<0, 0x18>; -def MULTu : MMRel, Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>, +def MULTu : MMRel, Mult<"multu", IIImult, GPR32Opnd, [HI, LO]>, MULT_FM<0, 0x19>; -def PseudoMULT : MultDivPseudo<MULT, ACRegs, CPURegsOpnd, MipsMult, IIImul>; -def PseudoMULTu : MultDivPseudo<MULTu, ACRegs, CPURegsOpnd, MipsMultu, IIImul>; -def SDIV : Div<"div", IIIdiv, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x1a>; -def UDIV : Div<"divu", IIIdiv, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x1b>; -def PseudoSDIV : MultDivPseudo<SDIV, ACRegs, CPURegsOpnd, MipsDivRem, IIIdiv, +def PseudoMULT : MultDivPseudo<MULT, ACRegs, GPR32Opnd, MipsMult, IIImult>; +def PseudoMULTu : MultDivPseudo<MULTu, ACRegs, GPR32Opnd, MipsMultu, IIImult>; +def SDIV : Div<"div", IIIdiv, GPR32Opnd, [HI, LO]>, MULT_FM<0, 0x1a>; +def UDIV : Div<"divu", IIIdiv, GPR32Opnd, [HI, LO]>, MULT_FM<0, 0x1b>; +def PseudoSDIV : MultDivPseudo<SDIV, ACRegs, GPR32Opnd, MipsDivRem, IIIdiv, 0, 1, 1>; -def PseudoUDIV : MultDivPseudo<UDIV, ACRegs, CPURegsOpnd, MipsDivRemU, IIIdiv, +def PseudoUDIV : MultDivPseudo<UDIV, ACRegs, GPR32Opnd, MipsDivRemU, IIIdiv, 0, 1, 1>; -def MTHI : MoveToLOHI<"mthi", CPURegs, [HI]>, MTLO_FM<0x11>; -def MTLO : MoveToLOHI<"mtlo", CPURegs, [LO]>, MTLO_FM<0x13>; -def MFHI : MoveFromLOHI<"mfhi", CPURegs, [HI]>, MFLO_FM<0x10>; -def MFLO : MoveFromLOHI<"mflo", CPURegs, [LO]>, MFLO_FM<0x12>; +def MTHI : MoveToLOHI<"mthi", GPR32Opnd, [HI]>, MTLO_FM<0x11>; +def MTLO : MoveToLOHI<"mtlo", GPR32Opnd, [LO]>, MTLO_FM<0x13>; +def MFHI : MoveFromLOHI<"mfhi", GPR32Opnd, [HI]>, MFLO_FM<0x10>; +def MFLO : MoveFromLOHI<"mflo", GPR32Opnd, [LO]>, MFLO_FM<0x12>; /// Sign Ext In Register Instructions. -def SEB : SignExtInReg<"seb", i8, CPURegs>, SEB_FM<0x10, 0x20>; -def SEH : SignExtInReg<"seh", i16, CPURegs>, SEB_FM<0x18, 0x20>; +def SEB : SignExtInReg<"seb", i8, GPR32Opnd>, SEB_FM<0x10, 0x20>; +def SEH : SignExtInReg<"seh", i16, GPR32Opnd>, SEB_FM<0x18, 0x20>; /// Count Leading -def CLZ : CountLeading0<"clz", CPURegsOpnd>, CLO_FM<0x20>; -def CLO : CountLeading1<"clo", CPURegsOpnd>, CLO_FM<0x21>; +def CLZ : CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>; +def CLO : CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>; /// Word Swap Bytes Within Halfwords -def WSBH : SubwordSwap<"wsbh", CPURegsOpnd>, SEB_FM<2, 0x20>; +def WSBH : SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>; /// No operation. def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>; @@ -1028,7 +1065,7 @@ def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>; // instructions. The same not happens for stack address copies, so an // add op with mem ComplexPattern is used and the stack address copy // can be matched. It's similar to Sparc LEA_ADDRi -def LEA_ADDiu : EffectiveAddress<"addiu", CPURegs, mem_ea>, LW_FM<9>; +def LEA_ADDiu : EffectiveAddress<"addiu", GPR32Opnd, mem_ea>, LW_FM<9>; // MADD*/MSUB* def MADD : MArithR<"madd", 1>, MULT_FM<0x1c, 0>; @@ -1040,79 +1077,74 @@ def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu>; def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub>; def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu>; -def RDHWR : ReadHardware<CPURegs, HWRegsOpnd>, RDHWR_FM; +def RDHWR : ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM; -def EXT : ExtBase<"ext", CPURegsOpnd>, EXT_FM<0>; -def INS : InsBase<"ins", CPURegsOpnd>, EXT_FM<4>; +def EXT : ExtBase<"ext", GPR32Opnd>, EXT_FM<0>; +def INS : InsBase<"ins", GPR32Opnd>, EXT_FM<4>; /// Move Control Registers From/To CPU Registers -def MFC0_3OP : MFC3OP<(outs CPURegsOpnd:$rt), - (ins CPURegsOpnd:$rd, uimm16:$sel), +def MFC0_3OP : MFC3OP<(outs GPR32Opnd:$rt), + (ins GPR32Opnd:$rd, uimm16:$sel), "mfc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 0>; -def MTC0_3OP : MFC3OP<(outs CPURegsOpnd:$rd, uimm16:$sel), - (ins CPURegsOpnd:$rt), +def MTC0_3OP : MFC3OP<(outs GPR32Opnd:$rd, uimm16:$sel), + (ins GPR32Opnd:$rt), "mtc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 4>; -def MFC2_3OP : MFC3OP<(outs CPURegsOpnd:$rt), - (ins CPURegsOpnd:$rd, uimm16:$sel), +def MFC2_3OP : MFC3OP<(outs GPR32Opnd:$rt), + (ins GPR32Opnd:$rd, uimm16:$sel), "mfc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 0>; -def MTC2_3OP : MFC3OP<(outs CPURegsOpnd:$rd, uimm16:$sel), - (ins CPURegsOpnd:$rt), +def MTC2_3OP : MFC3OP<(outs GPR32Opnd:$rd, uimm16:$sel), + (ins GPR32Opnd:$rt), "mtc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 4>; //===----------------------------------------------------------------------===// // Instruction aliases //===----------------------------------------------------------------------===// def : InstAlias<"move $dst, $src", - (ADDu CPURegsOpnd:$dst, CPURegsOpnd:$src,ZERO), 1>, - Requires<[NotMips64]>; -def : InstAlias<"move $dst, $src", - (OR CPURegsOpnd:$dst, CPURegsOpnd:$src,ZERO), 1>, + (ADDu GPR32Opnd:$dst, GPR32Opnd:$src,ZERO), 1>, Requires<[NotMips64]>; -def : InstAlias<"bal $offset", (BGEZAL RA, brtarget:$offset), 1>; +def : InstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>; def : InstAlias<"addu $rs, $rt, $imm", - (ADDiu CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm), 0>; + (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; def : InstAlias<"add $rs, $rt, $imm", - (ADDi CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm), 0>; + (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; def : InstAlias<"and $rs, $rt, $imm", - (ANDi CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm), 0>; -def : InstAlias<"j $rs", (JR CPURegs:$rs), 0>, - Requires<[NotMips64]>; -def : InstAlias<"jalr $rs", (JALR RA, CPURegs:$rs)>, Requires<[NotMips64]>; -def : InstAlias<"jal $rs", (JALR RA, CPURegs:$rs), 0>, Requires<[NotMips64]>; -def : InstAlias<"jal $rd,$rs", (JALR CPURegs:$rd, CPURegs:$rs), 0>, - Requires<[NotMips64]>; + (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; +def : InstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>; +def : InstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>; +def : InstAlias<"jal $rs", (JALR RA, GPR32Opnd:$rs), 0>; +def : InstAlias<"jal $rd,$rs", (JALR GPR32Opnd:$rd, GPR32Opnd:$rs), 0>; def : InstAlias<"not $rt, $rs", - (NOR CPURegsOpnd:$rt, CPURegsOpnd:$rs, ZERO), 1>; + (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>; def : InstAlias<"neg $rt, $rs", - (SUB CPURegsOpnd:$rt, ZERO, CPURegsOpnd:$rs), 1>; + (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>; def : InstAlias<"negu $rt, $rs", - (SUBu CPURegsOpnd:$rt, ZERO, CPURegsOpnd:$rs), 1>; + (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>; def : InstAlias<"slt $rs, $rt, $imm", - (SLTi CPURegsOpnd:$rs, CPURegs:$rt, simm16:$imm), 0>; + (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; def : InstAlias<"xor $rs, $rt, $imm", - (XORi CPURegsOpnd:$rs, CPURegsOpnd:$rt, uimm16:$imm), 1>, - Requires<[NotMips64]>; + (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>; def : InstAlias<"or $rs, $rt, $imm", - (ORi CPURegsOpnd:$rs, CPURegsOpnd:$rt, uimm16:$imm), 1>, - Requires<[NotMips64]>; + (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>; def : InstAlias<"nop", (SLL ZERO, ZERO, 0), 1>; def : InstAlias<"mfc0 $rt, $rd", - (MFC0_3OP CPURegsOpnd:$rt, CPURegsOpnd:$rd, 0), 0>; + (MFC0_3OP GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; def : InstAlias<"mtc0 $rt, $rd", - (MTC0_3OP CPURegsOpnd:$rd, 0, CPURegsOpnd:$rt), 0>; + (MTC0_3OP GPR32Opnd:$rd, 0, GPR32Opnd:$rt), 0>; def : InstAlias<"mfc2 $rt, $rd", - (MFC2_3OP CPURegsOpnd:$rt, CPURegsOpnd:$rd, 0), 0>; + (MFC2_3OP GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; def : InstAlias<"mtc2 $rt, $rd", - (MTC2_3OP CPURegsOpnd:$rd, 0, CPURegsOpnd:$rt), 0>; + (MTC2_3OP GPR32Opnd:$rd, 0, GPR32Opnd:$rt), 0>; def : InstAlias<"bnez $rs,$offset", - (BNE CPURegsOpnd:$rs, ZERO, brtarget:$offset), 1>, - Requires<[NotMips64]>; + (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; def : InstAlias<"beqz $rs,$offset", - (BEQ CPURegsOpnd:$rs, ZERO, brtarget:$offset), 1>, - Requires<[NotMips64]>; + (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; +def : InstAlias<"syscall", (SYSCALL 0), 1>; + +def : InstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>; +def : InstAlias<"break", (BREAK 0, 0), 1>; //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions //===----------------------------------------------------------------------===// @@ -1120,17 +1152,17 @@ def : InstAlias<"beqz $rs,$offset", class LoadImm32< string instr_asm, Operand Od, RegisterOperand RO> : MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), !strconcat(instr_asm, "\t$rt, $imm32")> ; -def LoadImm32Reg : LoadImm32<"li", shamt,CPURegsOpnd>; +def LoadImm32Reg : LoadImm32<"li", shamt,GPR32Opnd>; class LoadAddress<string instr_asm, Operand MemOpnd, RegisterOperand RO> : MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr), !strconcat(instr_asm, "\t$rt, $addr")> ; -def LoadAddr32Reg : LoadAddress<"la", mem, CPURegsOpnd>; +def LoadAddr32Reg : LoadAddress<"la", mem, GPR32Opnd>; class LoadAddressImm<string instr_asm, Operand Od, RegisterOperand RO> : MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), !strconcat(instr_asm, "\t$rt, $imm32")> ; -def LoadAddr32Imm : LoadAddressImm<"la", shamt,CPURegsOpnd>; +def LoadAddr32Imm : LoadAddressImm<"la", shamt,GPR32Opnd>; @@ -1158,13 +1190,13 @@ def : MipsPat<(i32 imm:$imm), (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>; // Carry MipsPatterns -def : MipsPat<(subc CPURegs:$lhs, CPURegs:$rhs), - (SUBu CPURegs:$lhs, CPURegs:$rhs)>; +def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs), + (SUBu GPR32:$lhs, GPR32:$rhs)>; let Predicates = [HasStdEnc, NotDSP] in { - def : MipsPat<(addc CPURegs:$lhs, CPURegs:$rhs), - (ADDu CPURegs:$lhs, CPURegs:$rhs)>; - def : MipsPat<(addc CPURegs:$src, immSExt16:$imm), - (ADDiu CPURegs:$src, imm:$imm)>; + def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs), + (ADDu GPR32:$lhs, GPR32:$rhs)>; + def : MipsPat<(addc GPR32:$src, immSExt16:$imm), + (ADDiu GPR32:$src, imm:$imm)>; } // Call @@ -1172,8 +1204,8 @@ def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)), (JAL tglobaladdr:$dst)>; def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)), (JAL texternalsym:$dst)>; -//def : MipsPat<(MipsJmpLink CPURegs:$dst), -// (JALR CPURegs:$dst)>; +//def : MipsPat<(MipsJmpLink GPR32:$dst), +// (JALR GPR32:$dst)>; // Tail call def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)), @@ -1195,38 +1227,38 @@ def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>; def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>; def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>; -def : MipsPat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)), - (ADDiu CPURegs:$hi, tglobaladdr:$lo)>; -def : MipsPat<(add CPURegs:$hi, (MipsLo tblockaddress:$lo)), - (ADDiu CPURegs:$hi, tblockaddress:$lo)>; -def : MipsPat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)), - (ADDiu CPURegs:$hi, tjumptable:$lo)>; -def : MipsPat<(add CPURegs:$hi, (MipsLo tconstpool:$lo)), - (ADDiu CPURegs:$hi, tconstpool:$lo)>; -def : MipsPat<(add CPURegs:$hi, (MipsLo tglobaltlsaddr:$lo)), - (ADDiu CPURegs:$hi, tglobaltlsaddr:$lo)>; +def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)), + (ADDiu GPR32:$hi, tglobaladdr:$lo)>; +def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)), + (ADDiu GPR32:$hi, tblockaddress:$lo)>; +def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)), + (ADDiu GPR32:$hi, tjumptable:$lo)>; +def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)), + (ADDiu GPR32:$hi, tconstpool:$lo)>; +def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)), + (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>; // gp_rel relocs -def : MipsPat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)), - (ADDiu CPURegs:$gp, tglobaladdr:$in)>; -def : MipsPat<(add CPURegs:$gp, (MipsGPRel tconstpool:$in)), - (ADDiu CPURegs:$gp, tconstpool:$in)>; +def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)), + (ADDiu GPR32:$gp, tglobaladdr:$in)>; +def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)), + (ADDiu GPR32:$gp, tconstpool:$in)>; // wrapper_pic class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>: MipsPat<(MipsWrapper RC:$gp, node:$in), (ADDiuOp RC:$gp, node:$in)>; -def : WrapperPat<tglobaladdr, ADDiu, CPURegs>; -def : WrapperPat<tconstpool, ADDiu, CPURegs>; -def : WrapperPat<texternalsym, ADDiu, CPURegs>; -def : WrapperPat<tblockaddress, ADDiu, CPURegs>; -def : WrapperPat<tjumptable, ADDiu, CPURegs>; -def : WrapperPat<tglobaltlsaddr, ADDiu, CPURegs>; +def : WrapperPat<tglobaladdr, ADDiu, GPR32>; +def : WrapperPat<tconstpool, ADDiu, GPR32>; +def : WrapperPat<texternalsym, ADDiu, GPR32>; +def : WrapperPat<tblockaddress, ADDiu, GPR32>; +def : WrapperPat<tjumptable, ADDiu, GPR32>; +def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>; // Mips does not have "not", so we expand our way -def : MipsPat<(not CPURegs:$in), - (NOR CPURegsOpnd:$in, ZERO)>; +def : MipsPat<(not GPR32:$in), + (NOR GPR32Opnd:$in, ZERO)>; // extended loads let Predicates = [NotN64, HasStdEnc] in { @@ -1279,7 +1311,7 @@ def : MipsPat<(brcond RC:$cond, bb:$dst), (BNEOp RC:$cond, ZEROReg, bb:$dst)>; } -defm : BrcondPats<CPURegs, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>; +defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>; def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst), (BLEZ i32:$lhs, bb:$dst)>; @@ -1328,14 +1360,14 @@ multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp, (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>; } -defm : SeteqPats<CPURegs, SLTiu, XOR, SLTu, ZERO>; -defm : SetlePats<CPURegs, SLT, SLTu>; -defm : SetgtPats<CPURegs, SLT, SLTu>; -defm : SetgePats<CPURegs, SLT, SLTu>; -defm : SetgeImmPats<CPURegs, SLTi, SLTiu>; +defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>; +defm : SetlePats<GPR32, SLT, SLTu>; +defm : SetgtPats<GPR32, SLT, SLTu>; +defm : SetgePats<GPR32, SLT, SLTu>; +defm : SetgeImmPats<GPR32, SLTi, SLTiu>; // bswap pattern -def : MipsPat<(bswap CPURegs:$rt), (ROTR (WSBH CPURegs:$rt), 16)>; +def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>; // mflo/hi patterns. def : MipsPat<(i32 (ExtractLOHI ACRegs:$ac, imm:$lohi_idx)), diff --git a/lib/Target/Mips/MipsJITInfo.cpp b/lib/Target/Mips/MipsJITInfo.cpp index 1b2a325..d76cb1d 100644 --- a/lib/Target/Mips/MipsJITInfo.cpp +++ b/lib/Target/Mips/MipsJITInfo.cpp @@ -218,9 +218,9 @@ void *MipsJITInfo::emitFunctionStub(const Function *F, void *Fn, Hi++; int Lo = (int)(EmittedAddr & 0xffff); - // lui t9, %hi(EmittedAddr) - // addiu t9, t9, %lo(EmittedAddr) - // jalr t8, t9 + // lui $t9, %hi(EmittedAddr) + // addiu $t9, $t9, %lo(EmittedAddr) + // jalr $t8, $t9 // nop if (IsLittleEndian) { JCE.emitWordLE(0xf << 26 | 25 << 16 | Hi); diff --git a/lib/Target/Mips/MipsLongBranch.cpp b/lib/Target/Mips/MipsLongBranch.cpp index 073daba..971176e 100644 --- a/lib/Target/Mips/MipsLongBranch.cpp +++ b/lib/Target/Mips/MipsLongBranch.cpp @@ -420,7 +420,7 @@ bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) { MF = &F; initMBBInfo(); - SmallVector<MBBInfo, 16>::iterator I, E = MBBInfos.end(); + SmallVectorImpl<MBBInfo>::iterator I, E = MBBInfos.end(); bool EverMadeChange = false, MadeChange = true; while (MadeChange) { diff --git a/lib/Target/Mips/MipsMachineFunction.cpp b/lib/Target/Mips/MipsMachineFunction.cpp index 59b23f7..a7299d7 100644 --- a/lib/Target/Mips/MipsMachineFunction.cpp +++ b/lib/Target/Mips/MipsMachineFunction.cpp @@ -38,8 +38,8 @@ unsigned MipsFunctionInfo::getGlobalBaseReg() { RC=(const TargetRegisterClass*)&Mips::CPU16RegsRegClass; else RC = ST.isABI_N64() ? - (const TargetRegisterClass*)&Mips::CPU64RegsRegClass : - (const TargetRegisterClass*)&Mips::CPURegsRegClass; + (const TargetRegisterClass*)&Mips::GPR64RegClass : + (const TargetRegisterClass*)&Mips::GPR32RegClass; return GlobalBaseReg = MF.getRegInfo().createVirtualRegister(RC); } @@ -60,7 +60,7 @@ void MipsFunctionInfo::createEhDataRegsFI() { for (int I = 0; I < 4; ++I) { const MipsSubtarget &ST = MF.getTarget().getSubtarget<MipsSubtarget>(); const TargetRegisterClass *RC = ST.isABI_N64() ? - &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; + &Mips::GPR64RegClass : &Mips::GPR32RegClass; EhDataRegFI[I] = MF.getFrameInfo()->CreateStackObject(RC->getSize(), RC->getAlignment(), false); diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index ae25e45..0b5fc33 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -54,8 +54,8 @@ MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, switch (RC->getID()) { default: return 0; - case Mips::CPURegsRegClassID: - case Mips::CPU64RegsRegClassID: + case Mips::GPR32RegClassID: + case Mips::GPR64RegClassID: case Mips::DSPRegsRegClassID: { const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); return 28 - TFI->hasFP(MF); @@ -106,22 +106,22 @@ const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() { BitVector MipsRegisterInfo:: getReservedRegs(const MachineFunction &MF) const { - static const uint16_t ReservedCPURegs[] = { + static const uint16_t ReservedGPR32[] = { Mips::ZERO, Mips::K0, Mips::K1, Mips::SP }; - static const uint16_t ReservedCPU64Regs[] = { + static const uint16_t ReservedGPR64[] = { Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64 }; BitVector Reserved(getNumRegs()); typedef TargetRegisterClass::const_iterator RegIter; - for (unsigned I = 0; I < array_lengthof(ReservedCPURegs); ++I) - Reserved.set(ReservedCPURegs[I]); + for (unsigned I = 0; I < array_lengthof(ReservedGPR32); ++I) + Reserved.set(ReservedGPR32[I]); - for (unsigned I = 0; I < array_lengthof(ReservedCPU64Regs); ++I) - Reserved.set(ReservedCPU64Regs[I]); + for (unsigned I = 0; I < array_lengthof(ReservedGPR64); ++I) + Reserved.set(ReservedGPR64[I]); if (Subtarget.hasMips64()) { // Reserve all registers in AFGR64. @@ -159,6 +159,8 @@ getReservedRegs(const MachineFunction &MF) const { if (Subtarget.inMips16Mode()) { Reserved.set(Mips::RA); Reserved.set(Mips::RA_64); + Reserved.set(Mips::T0); + Reserved.set(Mips::T1); } // Reserve GP if small section is used. diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td index ad6912c..c72c30d 100644 --- a/lib/Target/Mips/MipsRegisterInfo.td +++ b/lib/Target/Mips/MipsRegisterInfo.td @@ -147,91 +147,20 @@ let Namespace = "Mips" in { def RA_64 : Mips64GPRReg< 31, "ra", [RA]>, DwarfRegNum<[31]>; /// Mips Single point precision FPU Registers - def F0 : FPR< 0, "f0">, DwarfRegNum<[32]>; - def F1 : FPR< 1, "f1">, DwarfRegNum<[33]>; - def F2 : FPR< 2, "f2">, DwarfRegNum<[34]>; - def F3 : FPR< 3, "f3">, DwarfRegNum<[35]>; - def F4 : FPR< 4, "f4">, DwarfRegNum<[36]>; - def F5 : FPR< 5, "f5">, DwarfRegNum<[37]>; - def F6 : FPR< 6, "f6">, DwarfRegNum<[38]>; - def F7 : FPR< 7, "f7">, DwarfRegNum<[39]>; - def F8 : FPR< 8, "f8">, DwarfRegNum<[40]>; - def F9 : FPR< 9, "f9">, DwarfRegNum<[41]>; - def F10 : FPR<10, "f10">, DwarfRegNum<[42]>; - def F11 : FPR<11, "f11">, DwarfRegNum<[43]>; - def F12 : FPR<12, "f12">, DwarfRegNum<[44]>; - def F13 : FPR<13, "f13">, DwarfRegNum<[45]>; - def F14 : FPR<14, "f14">, DwarfRegNum<[46]>; - def F15 : FPR<15, "f15">, DwarfRegNum<[47]>; - def F16 : FPR<16, "f16">, DwarfRegNum<[48]>; - def F17 : FPR<17, "f17">, DwarfRegNum<[49]>; - def F18 : FPR<18, "f18">, DwarfRegNum<[50]>; - def F19 : FPR<19, "f19">, DwarfRegNum<[51]>; - def F20 : FPR<20, "f20">, DwarfRegNum<[52]>; - def F21 : FPR<21, "f21">, DwarfRegNum<[53]>; - def F22 : FPR<22, "f22">, DwarfRegNum<[54]>; - def F23 : FPR<23, "f23">, DwarfRegNum<[55]>; - def F24 : FPR<24, "f24">, DwarfRegNum<[56]>; - def F25 : FPR<25, "f25">, DwarfRegNum<[57]>; - def F26 : FPR<26, "f26">, DwarfRegNum<[58]>; - def F27 : FPR<27, "f27">, DwarfRegNum<[59]>; - def F28 : FPR<28, "f28">, DwarfRegNum<[60]>; - def F29 : FPR<29, "f29">, DwarfRegNum<[61]>; - def F30 : FPR<30, "f30">, DwarfRegNum<[62]>; - def F31 : FPR<31, "f31">, DwarfRegNum<[63]>; + foreach I = 0-31 in + def F#I : FPR<I, "f"#I>, DwarfRegNum<[!add(I, 32)]>; /// Mips Double point precision FPU Registers (aliased /// with the single precision to hold 64 bit values) - def D0 : AFPR< 0, "f0", [F0, F1]>; - def D1 : AFPR< 2, "f2", [F2, F3]>; - def D2 : AFPR< 4, "f4", [F4, F5]>; - def D3 : AFPR< 6, "f6", [F6, F7]>; - def D4 : AFPR< 8, "f8", [F8, F9]>; - def D5 : AFPR<10, "f10", [F10, F11]>; - def D6 : AFPR<12, "f12", [F12, F13]>; - def D7 : AFPR<14, "f14", [F14, F15]>; - def D8 : AFPR<16, "f16", [F16, F17]>; - def D9 : AFPR<18, "f18", [F18, F19]>; - def D10 : AFPR<20, "f20", [F20, F21]>; - def D11 : AFPR<22, "f22", [F22, F23]>; - def D12 : AFPR<24, "f24", [F24, F25]>; - def D13 : AFPR<26, "f26", [F26, F27]>; - def D14 : AFPR<28, "f28", [F28, F29]>; - def D15 : AFPR<30, "f30", [F30, F31]>; + foreach I = 0-15 in + def D#I : AFPR<!shl(I, 1), "f"#!shl(I, 1), + [!cast<FPR>("F"#!shl(I, 1)), + !cast<FPR>("F"#!add(!shl(I, 1), 1))]>; /// Mips Double point precision FPU Registers in MFP64 mode. - def D0_64 : AFPR64<0, "f0", [F0]>, DwarfRegNum<[32]>; - def D1_64 : AFPR64<1, "f1", [F1]>, DwarfRegNum<[33]>; - def D2_64 : AFPR64<2, "f2", [F2]>, DwarfRegNum<[34]>; - def D3_64 : AFPR64<3, "f3", [F3]>, DwarfRegNum<[35]>; - def D4_64 : AFPR64<4, "f4", [F4]>, DwarfRegNum<[36]>; - def D5_64 : AFPR64<5, "f5", [F5]>, DwarfRegNum<[37]>; - def D6_64 : AFPR64<6, "f6", [F6]>, DwarfRegNum<[38]>; - def D7_64 : AFPR64<7, "f7", [F7]>, DwarfRegNum<[39]>; - def D8_64 : AFPR64<8, "f8", [F8]>, DwarfRegNum<[40]>; - def D9_64 : AFPR64<9, "f9", [F9]>, DwarfRegNum<[41]>; - def D10_64 : AFPR64<10, "f10", [F10]>, DwarfRegNum<[42]>; - def D11_64 : AFPR64<11, "f11", [F11]>, DwarfRegNum<[43]>; - def D12_64 : AFPR64<12, "f12", [F12]>, DwarfRegNum<[44]>; - def D13_64 : AFPR64<13, "f13", [F13]>, DwarfRegNum<[45]>; - def D14_64 : AFPR64<14, "f14", [F14]>, DwarfRegNum<[46]>; - def D15_64 : AFPR64<15, "f15", [F15]>, DwarfRegNum<[47]>; - def D16_64 : AFPR64<16, "f16", [F16]>, DwarfRegNum<[48]>; - def D17_64 : AFPR64<17, "f17", [F17]>, DwarfRegNum<[49]>; - def D18_64 : AFPR64<18, "f18", [F18]>, DwarfRegNum<[50]>; - def D19_64 : AFPR64<19, "f19", [F19]>, DwarfRegNum<[51]>; - def D20_64 : AFPR64<20, "f20", [F20]>, DwarfRegNum<[52]>; - def D21_64 : AFPR64<21, "f21", [F21]>, DwarfRegNum<[53]>; - def D22_64 : AFPR64<22, "f22", [F22]>, DwarfRegNum<[54]>; - def D23_64 : AFPR64<23, "f23", [F23]>, DwarfRegNum<[55]>; - def D24_64 : AFPR64<24, "f24", [F24]>, DwarfRegNum<[56]>; - def D25_64 : AFPR64<25, "f25", [F25]>, DwarfRegNum<[57]>; - def D26_64 : AFPR64<26, "f26", [F26]>, DwarfRegNum<[58]>; - def D27_64 : AFPR64<27, "f27", [F27]>, DwarfRegNum<[59]>; - def D28_64 : AFPR64<28, "f28", [F28]>, DwarfRegNum<[60]>; - def D29_64 : AFPR64<29, "f29", [F29]>, DwarfRegNum<[61]>; - def D30_64 : AFPR64<30, "f30", [F30]>, DwarfRegNum<[62]>; - def D31_64 : AFPR64<31, "f31", [F31]>, DwarfRegNum<[63]>; + foreach I = 0-31 in + def D#I#_64 : AFPR64<I, "f"#I, [!cast<FPR>("F"#I)]>, + DwarfRegNum<[!add(I, 32)]>; // Hi/Lo registers def HI : Register<"ac0">, DwarfRegNum<[64]>; @@ -248,11 +177,13 @@ let Namespace = "Mips" in { def LO64 : RegisterWithSubRegs<"lo", [LO]>; } - // Status flags register - def FCR31 : Register<"31">; + // FP control registers. + foreach I = 0-31 in + def FCR#I : MipsReg<#I, ""#I>; - // fcc0 register - def FCC0 : MipsReg<0, "fcc0">; + // FP condition code registers. + foreach I = 0-7 in + def FCC#I : MipsReg<#I, "fcc"#I>; // PC register def PC : Register<"pc">; @@ -292,7 +223,7 @@ let Namespace = "Mips" in { // Register Classes //===----------------------------------------------------------------------===// -class CPURegsClass<list<ValueType> regTypes> : +class GPR32Class<list<ValueType> regTypes> : RegisterClass<"Mips", regTypes, 32, (add // Reserved ZERO, AT, @@ -307,10 +238,10 @@ class CPURegsClass<list<ValueType> regTypes> : // Reserved K0, K1, GP, SP, FP, RA)>; -def CPURegs : CPURegsClass<[i32]>; -def DSPRegs : CPURegsClass<[v4i8, v2i16]>; +def GPR32 : GPR32Class<[i32]>; +def DSPRegs : GPR32Class<[v4i8, v2i16]>; -def CPU64Regs : RegisterClass<"Mips", [i64], 64, (add +def GPR64 : RegisterClass<"Mips", [i64], 64, (add // Reserved ZERO_64, AT_64, // Return Values and Arguments @@ -330,6 +261,13 @@ def CPU16Regs : RegisterClass<"Mips", [i32], 32, (add // Callee save S0, S1)>; +def CPU16RegsPlusSP : RegisterClass<"Mips", [i32], 32, (add + // Return Values and Arguments + V0, V1, A0, A1, A2, A3, + // Callee save + S0, S1, + SP)>; + def CPURAReg : RegisterClass<"Mips", [i32], 32, (add RA)>, Unallocatable; def CPUSPReg : RegisterClass<"Mips", [i32], 32, (add SP)>, Unallocatable; @@ -357,8 +295,13 @@ def AFGR64 : RegisterClass<"Mips", [f64], 64, (add def FGR64 : RegisterClass<"Mips", [f64], 64, (sequence "D%u_64", 0, 31)>; -// Condition Register for floating point operations -def CCR : RegisterClass<"Mips", [i32], 32, (add FCR31,FCC0)>, Unallocatable; +// FP control registers. +def CCR : RegisterClass<"Mips", [i32], 32, (sequence "FCR%u", 0, 31)>, + Unallocatable; + +// FP condition code registers. +def FCC : RegisterClass<"Mips", [i32], 32, (sequence "FCC%u", 0, 7)>, + Unallocatable; // Hi/Lo Registers def LORegs : RegisterClass<"Mips", [i32], 32, (add LO)>; @@ -388,47 +331,96 @@ def ACRegsDSP : RegisterClass<"Mips", [untyped], 64, (sequence "AC%u", 0, 3)> { def DSPCC : RegisterClass<"Mips", [v4i8, v2i16], 32, (add DSPCCond)>; // Register Operands. -def CPURegsAsmOperand : AsmOperandClass { - let Name = "CPURegsAsm"; - let ParserMethod = "parseCPURegs"; + +class MipsAsmRegOperand : AsmOperandClass { + let RenderMethod = "addRegAsmOperands"; +} +def GPR32AsmOperand : MipsAsmRegOperand { + let Name = "GPR32Asm"; + let ParserMethod = "parseGPR32"; } -def CPU64RegsAsmOperand : AsmOperandClass { - let Name = "CPU64RegsAsm"; - let ParserMethod = "parseCPU64Regs"; +def GPR64AsmOperand : MipsAsmRegOperand { + let Name = "GPR64Asm"; + let ParserMethod = "parseGPR64"; } -def CCRAsmOperand : AsmOperandClass { +def ACRegsDSPAsmOperand : MipsAsmRegOperand { + let Name = "ACRegsDSPAsm"; + let ParserMethod = "parseACRegsDSP"; +} + +def CCRAsmOperand : MipsAsmRegOperand { let Name = "CCRAsm"; let ParserMethod = "parseCCRRegs"; } -def CPURegsOpnd : RegisterOperand<CPURegs, "printCPURegs"> { - let ParserMatchClass = CPURegsAsmOperand; +def AFGR64AsmOperand : MipsAsmRegOperand { + let Name = "AFGR64Asm"; + let ParserMethod = "parseAFGR64Regs"; +} + +def FGR64AsmOperand : MipsAsmRegOperand { + let Name = "FGR64Asm"; + let ParserMethod = "parseFGR64Regs"; } -def CPU64RegsOpnd : RegisterOperand<CPU64Regs, "printCPURegs"> { - let ParserMatchClass = CPU64RegsAsmOperand; +def FGR32AsmOperand : MipsAsmRegOperand { + let Name = "FGR32Asm"; + let ParserMethod = "parseFGR32Regs"; } -def CCROpnd : RegisterOperand<CCR, "printCPURegs"> { +def FCCRegsAsmOperand : MipsAsmRegOperand { + let Name = "FCCRegsAsm"; + let ParserMethod = "parseFCCRegs"; +} + +def GPR32Opnd : RegisterOperand<GPR32> { + let ParserMatchClass = GPR32AsmOperand; +} + +def GPR64Opnd : RegisterOperand<GPR64> { + let ParserMatchClass = GPR64AsmOperand; +} + +def CCROpnd : RegisterOperand<CCR> { let ParserMatchClass = CCRAsmOperand; } -def HWRegsAsmOperand : AsmOperandClass { +def HWRegsAsmOperand : MipsAsmRegOperand { let Name = "HWRegsAsm"; let ParserMethod = "parseHWRegs"; } -def HW64RegsAsmOperand : AsmOperandClass { +def HW64RegsAsmOperand : MipsAsmRegOperand { let Name = "HW64RegsAsm"; let ParserMethod = "parseHW64Regs"; } -def HWRegsOpnd : RegisterOperand<HWRegs, "printCPURegs"> { +def HWRegsOpnd : RegisterOperand<HWRegs> { let ParserMatchClass = HWRegsAsmOperand; } -def HW64RegsOpnd : RegisterOperand<HWRegs64, "printCPURegs"> { +def HW64RegsOpnd : RegisterOperand<HWRegs64> { let ParserMatchClass = HW64RegsAsmOperand; } + +def AFGR64RegsOpnd : RegisterOperand<AFGR64> { + let ParserMatchClass = AFGR64AsmOperand; +} + +def FGR64RegsOpnd : RegisterOperand<FGR64> { + let ParserMatchClass = FGR64AsmOperand; +} + +def FGR32RegsOpnd : RegisterOperand<FGR32> { + let ParserMatchClass = FGR32AsmOperand; +} + +def FCCRegsOpnd : RegisterOperand<FCC> { + let ParserMatchClass = FCCRegsAsmOperand; +} + +def ACRegsDSPOpnd : RegisterOperand<ACRegsDSP> { + let ParserMatchClass = ACRegsDSPAsmOperand; +} diff --git a/lib/Target/Mips/MipsSEFrameLowering.cpp b/lib/Target/Mips/MipsSEFrameLowering.cpp index 91ffb94..d9e0fa4 100644 --- a/lib/Target/Mips/MipsSEFrameLowering.cpp +++ b/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -285,7 +285,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { if (StackSize == 0 && !MFI->adjustsStack()) return; MachineModuleInfo &MMI = MF.getMMI(); - const MCRegisterInfo &MRI = MMI.getContext().getRegisterInfo(); + const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); MachineLocation DstML, SrcML; // Adjust stack. @@ -321,9 +321,9 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { // one for each of the paired single precision registers. if (Mips::AFGR64RegClass.contains(Reg)) { unsigned Reg0 = - MRI.getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpeven), true); + MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpeven), true); unsigned Reg1 = - MRI.getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpodd), true); + MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpodd), true); if (!STI.isLittle()) std::swap(Reg0, Reg1); @@ -333,16 +333,16 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { MMI.addFrameInst( MCCFIInstruction::createOffset(CSLabel, Reg1, Offset + 4)); } else { - // Reg is either in CPURegs or FGR32. + // Reg is either in GPR32 or FGR32. MMI.addFrameInst(MCCFIInstruction::createOffset( - CSLabel, MRI.getDwarfRegNum(Reg, 1), Offset)); + CSLabel, MRI->getDwarfRegNum(Reg, 1), Offset)); } } } if (MipsFI->callsEhReturn()) { const TargetRegisterClass *RC = STI.isABI_N64() ? - &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; + &Mips::GPR64RegClass : &Mips::GPR32RegClass; // Insert instructions that spill eh data registers. for (int I = 0; I < 4; ++I) { @@ -358,7 +358,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2); for (int I = 0; I < 4; ++I) { int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I)); - unsigned Reg = MRI.getDwarfRegNum(ehDataReg(I), true); + unsigned Reg = MRI->getDwarfRegNum(ehDataReg(I), true); MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel2, Reg, Offset)); } } @@ -373,7 +373,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister( - SetFPLabel, MRI.getDwarfRegNum(FP, true))); + SetFPLabel, MRI->getDwarfRegNum(FP, true))); } } @@ -408,7 +408,7 @@ void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, if (MipsFI->callsEhReturn()) { const TargetRegisterClass *RC = STI.isABI_N64() ? - &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; + &Mips::GPR64RegClass : &Mips::GPR32RegClass; // Find first instruction that restores a callee-saved register. MachineBasicBlock::iterator I = MBBI; @@ -516,7 +516,7 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF, // The spill slot should be half the size of the accumulator. If target is // mips64, it should be 64-bit, otherwise it should be 32-bt. const TargetRegisterClass *RC = STI.hasMips64() ? - &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; + &Mips::GPR64RegClass : &Mips::GPR32RegClass; int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(), RC->getAlignment(), false); RS->addScavengingFrameIndex(FI); @@ -530,7 +530,7 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF, return; const TargetRegisterClass *RC = STI.isABI_N64() ? - &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; + &Mips::GPR64RegClass : &Mips::GPR32RegClass; int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(), RC->getAlignment(), false); RS->addScavengingFrameIndex(FI); diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 7684bec..3b6480a 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -119,9 +119,9 @@ void MipsSEDAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) { const TargetRegisterClass *RC; if (Subtarget.isABI_N64()) - RC = (const TargetRegisterClass*)&Mips::CPU64RegsRegClass; + RC = (const TargetRegisterClass*)&Mips::GPR64RegClass; else - RC = (const TargetRegisterClass*)&Mips::CPURegsRegClass; + RC = (const TargetRegisterClass*)&Mips::GPR32RegClass; V0 = RegInfo.createVirtualRegister(RC); V1 = RegInfo.createVirtualRegister(RC); @@ -402,7 +402,7 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) { } case MipsISD::ThreadPointer: { - EVT PtrVT = TLI->getPointerTy(); + EVT PtrVT = getTargetLowering()->getPointerTy(); unsigned RdhwrOpc, SrcReg, DestReg; if (PtrVT == MVT::i32) { diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp index f640ecc..a0aacb5 100644 --- a/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/lib/Target/Mips/MipsSEISelLowering.cpp @@ -31,10 +31,10 @@ MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM) clearRegisterClasses(); - addRegisterClass(MVT::i32, &Mips::CPURegsRegClass); + addRegisterClass(MVT::i32, &Mips::GPR32RegClass); if (HasMips64) - addRegisterClass(MVT::i64, &Mips::CPU64RegsRegClass); + addRegisterClass(MVT::i64, &Mips::GPR64RegClass); if (Subtarget->hasDSP()) { MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8}; @@ -53,6 +53,20 @@ MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::BITCAST, VecTys[i], Legal); } + // Expand all truncating stores and extending loads. + unsigned FirstVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE; + unsigned LastVT = (unsigned)MVT::LAST_VECTOR_VALUETYPE; + + for (unsigned VT0 = FirstVT; VT0 <= LastVT; ++VT0) { + for (unsigned VT1 = FirstVT; VT1 <= LastVT; ++VT1) + setTruncStoreAction((MVT::SimpleValueType)VT0, + (MVT::SimpleValueType)VT1, Expand); + + setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT0, Expand); + setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT0, Expand); + setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT0, Expand); + } + setTargetDAGCombine(ISD::SHL); setTargetDAGCombine(ISD::SRA); setTargetDAGCombine(ISD::SRL); @@ -99,6 +113,7 @@ MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM) setTargetDAGCombine(ISD::ADDE); setTargetDAGCombine(ISD::SUBE); + setTargetDAGCombine(ISD::MUL); computeRegisterProperties(); } @@ -320,6 +335,57 @@ static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG, return SDValue(); } +static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT, + EVT ShiftTy, SelectionDAG &DAG) { + // Clear the upper (64 - VT.sizeInBits) bits. + C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits()); + + // Return 0. + if (C == 0) + return DAG.getConstant(0, VT); + + // Return x. + if (C == 1) + return X; + + // If c is power of 2, return (shl x, log2(c)). + if (isPowerOf2_64(C)) + return DAG.getNode(ISD::SHL, DL, VT, X, + DAG.getConstant(Log2_64(C), ShiftTy)); + + unsigned Log2Ceil = Log2_64_Ceil(C); + uint64_t Floor = 1LL << Log2_64(C); + uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil; + + // If |c - floor_c| <= |c - ceil_c|, + // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))), + // return (add constMult(x, floor_c), constMult(x, c - floor_c)). + if (C - Floor <= Ceil - C) { + SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG); + SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG); + return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1); + } + + // If |c - floor_c| > |c - ceil_c|, + // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)). + SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG); + SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG); + return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1); +} + +static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG, + const TargetLowering::DAGCombinerInfo &DCI, + const MipsSETargetLowering *TL) { + EVT VT = N->getValueType(0); + + if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) + if (!VT.isVector()) + return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N), + VT, TL->getScalarShiftAmountTy(VT), DAG); + + return SDValue(N, 0); +} + static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty, SelectionDAG &DAG, const MipsSubtarget *Subtarget) { @@ -432,6 +498,8 @@ MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { return performADDECombine(N, DAG, DCI, Subtarget); case ISD::SUBE: return performSUBECombine(N, DAG, DCI, Subtarget); + case ISD::MUL: + return performMULCombine(N, DAG, DCI, this); case ISD::SHL: return performSHLCombine(N, DAG, DCI, Subtarget); case ISD::SRA: @@ -701,7 +769,7 @@ emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); - const TargetRegisterClass *RC = &Mips::CPURegsRegClass; + const TargetRegisterClass *RC = &Mips::GPR32RegClass; DebugLoc DL = MI->getDebugLoc(); const BasicBlock *LLVM_BB = BB->getBasicBlock(); MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB)); diff --git a/lib/Target/Mips/MipsSEInstrInfo.cpp b/lib/Target/Mips/MipsSEInstrInfo.cpp index e2a33dd..9521043 100644 --- a/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -94,9 +94,9 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, bool KillSrc) const { unsigned Opc = 0, ZeroReg = 0; - if (Mips::CPURegsRegClass.contains(DestReg)) { // Copy to CPU Reg. - if (Mips::CPURegsRegClass.contains(SrcReg)) - Opc = Mips::OR, ZeroReg = Mips::ZERO; + if (Mips::GPR32RegClass.contains(DestReg)) { // Copy to CPU Reg. + if (Mips::GPR32RegClass.contains(SrcReg)) + Opc = Mips::ADDu, ZeroReg = Mips::ZERO; else if (Mips::CCRRegClass.contains(SrcReg)) Opc = Mips::CFC1; else if (Mips::FGR32RegClass.contains(SrcReg)) @@ -115,7 +115,7 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, return; } } - else if (Mips::CPURegsRegClass.contains(SrcReg)) { // Copy from CPU Reg. + else if (Mips::GPR32RegClass.contains(SrcReg)) { // Copy from CPU Reg. if (Mips::CCRRegClass.contains(DestReg)) Opc = Mips::CTC1; else if (Mips::FGR32RegClass.contains(DestReg)) @@ -141,11 +141,9 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, Opc = Mips::FMOV_D32; else if (Mips::FGR64RegClass.contains(DestReg, SrcReg)) Opc = Mips::FMOV_D64; - else if (Mips::CCRRegClass.contains(DestReg, SrcReg)) - Opc = Mips::MOVCCRToCCR; - else if (Mips::CPU64RegsRegClass.contains(DestReg)) { // Copy to CPU64 Reg. - if (Mips::CPU64RegsRegClass.contains(SrcReg)) - Opc = Mips::OR64, ZeroReg = Mips::ZERO_64; + else if (Mips::GPR64RegClass.contains(DestReg)) { // Copy to CPU64 Reg. + if (Mips::GPR64RegClass.contains(SrcReg)) + Opc = Mips::DADDu, ZeroReg = Mips::ZERO_64; else if (Mips::HIRegs64RegClass.contains(SrcReg)) Opc = Mips::MFHI64, SrcReg = 0; else if (Mips::LORegs64RegClass.contains(SrcReg)) @@ -153,7 +151,7 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, else if (Mips::FGR64RegClass.contains(SrcReg)) Opc = Mips::DMFC1; } - else if (Mips::CPU64RegsRegClass.contains(SrcReg)) { // Copy from CPU64 Reg. + else if (Mips::GPR64RegClass.contains(SrcReg)) { // Copy from CPU64 Reg. if (Mips::HIRegs64RegClass.contains(DestReg)) Opc = Mips::MTHI64, DestReg = 0; else if (Mips::LORegs64RegClass.contains(DestReg)) @@ -187,9 +185,9 @@ storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned Opc = 0; - if (Mips::CPURegsRegClass.hasSubClassEq(RC)) + if (Mips::GPR32RegClass.hasSubClassEq(RC)) Opc = IsN64 ? Mips::SW_P8 : Mips::SW; - else if (Mips::CPU64RegsRegClass.hasSubClassEq(RC)) + else if (Mips::GPR64RegClass.hasSubClassEq(RC)) Opc = IsN64 ? Mips::SD_P8 : Mips::SD; else if (Mips::ACRegsRegClass.hasSubClassEq(RC)) Opc = IsN64 ? Mips::STORE_AC64_P8 : Mips::STORE_AC64; @@ -220,9 +218,9 @@ loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); unsigned Opc = 0; - if (Mips::CPURegsRegClass.hasSubClassEq(RC)) + if (Mips::GPR32RegClass.hasSubClassEq(RC)) Opc = IsN64 ? Mips::LW_P8 : Mips::LW; - else if (Mips::CPU64RegsRegClass.hasSubClassEq(RC)) + else if (Mips::GPR64RegClass.hasSubClassEq(RC)) Opc = IsN64 ? Mips::LD_P8 : Mips::LD; else if (Mips::ACRegsRegClass.hasSubClassEq(RC)) Opc = IsN64 ? Mips::LOAD_AC64_P8 : Mips::LOAD_AC64; @@ -342,7 +340,7 @@ MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB, unsigned LUi = STI.isABI_N64() ? Mips::LUi64 : Mips::LUi; unsigned ZEROReg = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; const TargetRegisterClass *RC = STI.isABI_N64() ? - &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; + &Mips::GPR64RegClass : &Mips::GPR32RegClass; bool LastInstrIsADDiu = NewImm; const MipsAnalyzeImmediate::InstSeq &Seq = @@ -513,7 +511,6 @@ void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB, // indirect jump to TargetReg const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>(); unsigned ADDU = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; - unsigned OR = STI.isABI_N64() ? Mips::OR64 : Mips::OR; unsigned JR = STI.isABI_N64() ? Mips::JR64 : Mips::JR; unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; unsigned RA = STI.isABI_N64() ? Mips::RA_64 : Mips::RA; @@ -522,13 +519,13 @@ void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB, unsigned OffsetReg = I->getOperand(0).getReg(); unsigned TargetReg = I->getOperand(1).getReg(); - // or $ra, $v0, $zero + // addu $ra, $v0, $zero // addu $sp, $sp, $v1 // jr $ra if (TM.getRelocationModel() == Reloc::PIC_) - BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(OR), T9) + BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), T9) .addReg(TargetReg).addReg(ZERO); - BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(OR), RA) + BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), RA) .addReg(TargetReg).addReg(ZERO); BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), SP) .addReg(SP).addReg(OffsetReg); diff --git a/lib/Target/Mips/MipsSERegisterInfo.cpp b/lib/Target/Mips/MipsSERegisterInfo.cpp index 9763f85..286a2e2 100644 --- a/lib/Target/Mips/MipsSERegisterInfo.cpp +++ b/lib/Target/Mips/MipsSERegisterInfo.cpp @@ -56,10 +56,10 @@ requiresFrameIndexScavenging(const MachineFunction &MF) const { const TargetRegisterClass * MipsSERegisterInfo::intRegClass(unsigned Size) const { if (Size == 4) - return &Mips::CPURegsRegClass; + return &Mips::GPR32RegClass; assert(Size == 8); - return &Mips::CPU64RegsRegClass; + return &Mips::GPR64RegClass; } void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II, diff --git a/lib/Target/Mips/MipsSchedule.td b/lib/Target/Mips/MipsSchedule.td index 1add02f..2779064 100644 --- a/lib/Target/Mips/MipsSchedule.td +++ b/lib/Target/Mips/MipsSchedule.td @@ -17,13 +17,18 @@ def IMULDIV : FuncUnit; // Instruction Itinerary classes used for Mips //===----------------------------------------------------------------------===// def IIAlu : InstrItinClass; +def IIArith : InstrItinClass; +def IILogic : InstrItinClass; def IILoad : InstrItinClass; def IIStore : InstrItinClass; def IIXfer : InstrItinClass; def IIBranch : InstrItinClass; def IIHiLo : InstrItinClass; def IIImul : InstrItinClass; +def IIImult : InstrItinClass; def IIIdiv : InstrItinClass; +def IIseb : InstrItinClass; +def IIslt : InstrItinClass; def IIFcvt : InstrItinClass; def IIFmove : InstrItinClass; def IIFcmp : InstrItinClass; @@ -35,6 +40,9 @@ def IIFdivDouble : InstrItinClass; def IIFsqrtSingle : InstrItinClass; def IIFsqrtDouble : InstrItinClass; def IIFrecipFsqrtStep : InstrItinClass; +def IIFLoad : InstrItinClass; +def IIFStore : InstrItinClass; +def IIFmoveC1 : InstrItinClass; def IIPseudo : InstrItinClass; //===----------------------------------------------------------------------===// @@ -42,6 +50,8 @@ def IIPseudo : InstrItinClass; //===----------------------------------------------------------------------===// def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [ InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>, + InstrItinData<IIArith , [InstrStage<1, [ALU]>]>, + InstrItinData<IILogic , [InstrStage<1, [ALU]>]>, InstrItinData<IILoad , [InstrStage<3, [ALU]>]>, InstrItinData<IIStore , [InstrStage<1, [ALU]>]>, InstrItinData<IIXfer , [InstrStage<2, [ALU]>]>, @@ -59,5 +69,8 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [ InstrItinData<IIFdivDouble , [InstrStage<36, [ALU]>]>, InstrItinData<IIFsqrtSingle , [InstrStage<54, [ALU]>]>, InstrItinData<IIFsqrtDouble , [InstrStage<12, [ALU]>]>, - InstrItinData<IIFrecipFsqrtStep , [InstrStage<5, [ALU]>]> + InstrItinData<IIFrecipFsqrtStep , [InstrStage<5, [ALU]>]>, + InstrItinData<IIFLoad , [InstrStage<3, [ALU]>]>, + InstrItinData<IIFStore , [InstrStage<1, [ALU]>]>, + InstrItinData<IIFmoveC1 , [InstrStage<2, [ALU]>]> ]>; diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp index 259e68d..541e2ca 100644 --- a/lib/Target/Mips/MipsSubtarget.cpp +++ b/lib/Target/Mips/MipsSubtarget.cpp @@ -104,7 +104,7 @@ MipsSubtarget::enablePostRAScheduler(CodeGenOpt::Level OptLevel, Mode = TargetSubtargetInfo::ANTIDEP_NONE; CriticalPathRCs.clear(); CriticalPathRCs.push_back(hasMips64() ? - &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass); + &Mips::GPR64RegClass : &Mips::GPR32RegClass); return OptLevel >= CodeGenOpt::Aggressive; } diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index ef7568a..bfb13bb 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -194,6 +194,7 @@ public: bool hasBitCount() const { return HasBitCount; } bool hasFPIdx() const { return HasFPIdx; } + const InstrItineraryData &getInstrItineraryData() const { return InstrItins; } bool allowMixed16_32() const { return inMips16ModeDefault() | AllowMixed16_32;} diff --git a/lib/Target/Mips/MipsTargetMachine.cpp b/lib/Target/Mips/MipsTargetMachine.cpp index 9af2f1b..ced6a09 100644 --- a/lib/Target/Mips/MipsTargetMachine.cpp +++ b/lib/Target/Mips/MipsTargetMachine.cpp @@ -70,8 +70,8 @@ MipsTargetMachine(const Target &T, StringRef TT, "E-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32-S64")), InstrInfo(MipsInstrInfo::create(*this)), FrameLowering(MipsFrameLowering::create(*this, Subtarget)), - TLInfo(MipsTargetLowering::create(*this)), - TSInfo(*this), JITInfo() { + TLInfo(MipsTargetLowering::create(*this)), TSInfo(*this), + InstrItins(Subtarget.getInstrItineraryData()), JITInfo() { initAsmInfo(); } diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h index ee55708..5a9a11d 100644 --- a/lib/Target/Mips/MipsTargetMachine.h +++ b/lib/Target/Mips/MipsTargetMachine.h @@ -44,6 +44,7 @@ class MipsTargetMachine : public LLVMTargetMachine { OwningPtr<const MipsFrameLowering> FrameLoweringSE; OwningPtr<const MipsTargetLowering> TLInfoSE; MipsSelectionDAGInfo TSInfo; + const InstrItineraryData &InstrItins; MipsJITInfo JITInfo; public: @@ -65,6 +66,11 @@ public: { return &Subtarget; } virtual const DataLayout *getDataLayout() const { return &DL;} + + virtual const InstrItineraryData *getInstrItineraryData() const { + return Subtarget.inMips16Mode() ? 0 : &InstrItins; + } + virtual MipsJITInfo *getJITInfo() { return &JITInfo; } |