Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -214,8 +214,8 @@ MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); - bool isMips64() const { - return (STI.getFeatureBits() & Mips::FeatureMips64) != 0; + bool isGP64() const { + return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0; } bool isFP64() const { @@ -872,7 +872,7 @@ const MCExpr *ExprOffset; unsigned TmpRegNum; unsigned AtRegNum = getReg( - (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg()); + (isGP64()) ? 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(); @@ -1266,7 +1266,7 @@ SMLoc S = Parser.getTok().getLoc(); Parser.Lex(); // Eat dollar token. // Parse the register operand. - if (!tryParseRegisterOperand(Operands, isMips64())) { + if (!tryParseRegisterOperand(Operands, isGP64())) { if (getLexer().is(AsmToken::LParen)) { // Check if it is indexed addressing operand. Operands.push_back(MipsOperand::CreateToken("(", S)); @@ -1275,7 +1275,7 @@ return true; Parser.Lex(); // Eat the dollar - if (tryParseRegisterOperand(Operands, isMips64())) + if (tryParseRegisterOperand(Operands, isGP64())) return true; if (!getLexer().is(AsmToken::RParen)) @@ -1482,7 +1482,7 @@ bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { StartLoc = Parser.getTok().getLoc(); - RegNo = tryParseRegister(isMips64()); + RegNo = tryParseRegister(isGP64()); EndLoc = Parser.getTok().getLoc(); return (RegNo == (unsigned)-1); } @@ -1549,7 +1549,7 @@ // Zero register assumed, add a memory operand with ZERO as its base. Operands.push_back(MipsOperand::CreateMem( - isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E)); + isGP64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E)); return MatchOperand_Success; } Error(Parser.getTok().getLoc(), "'(' expected"); @@ -1559,8 +1559,8 @@ Parser.Lex(); // Eat the '(' token. } - Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64 - : (int)MipsOperand::Kind_GPR32); + Res = parseRegs(Operands, isGP64() ? (int)MipsOperand::Kind_GPR64 + : (int)MipsOperand::Kind_GPR32); if (Res != MatchOperand_Success) return Res; @@ -1952,7 +1952,7 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseGPR64(SmallVectorImpl &Operands) { - if (!isMips64()) + if (!isGP64()) return MatchOperand_NoMatch; return parseRegs(Operands, (int)MipsOperand::Kind_GPR64); } @@ -2134,8 +2134,8 @@ APInt IntVal(32, -1); if (!DefSymbol.substr(1).getAsInteger(10, IntVal)) RegNum = matchRegisterByNumber(IntVal.getZExtValue(), - isMips64() ? Mips::GPR64RegClassID - : Mips::GPR32RegClassID); + isGP64() ? Mips::GPR64RegClassID + : Mips::GPR32RegClassID); else { // Lookup for the register with the corresponding name. switch (Kind) { Index: lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -141,6 +141,8 @@ EFlags |= ELF::EF_MIPS_ARCH_64R2; else if (Features & Mips::FeatureMips64) EFlags |= ELF::EF_MIPS_ARCH_64; + else if (Features & Mips::FeatureMips4) + EFlags |= ELF::EF_MIPS_ARCH_4; else if (Features & Mips::FeatureMips32r2) EFlags |= ELF::EF_MIPS_ARCH_32R2; else if (Features & Mips::FeatureMips32) Index: lib/Target/Mips/Mips.td =================================================================== --- lib/Target/Mips/Mips.td +++ lib/Target/Mips/Mips.td @@ -63,9 +63,12 @@ "Mips32r2", "Mips32r2 ISA Support", [FeatureMips32, FeatureSEInReg, FeatureSwap, FeatureFPIdx]>; +def FeatureMips4 : SubtargetFeature<"mips4", "MipsArchVersion", + "Mips4", "MIPS IV ISA Support", + [FeatureGP64Bit, FeatureFP64Bit, FeatureCondMov]>; def FeatureMips64 : SubtargetFeature<"mips64", "MipsArchVersion", "Mips64", "Mips64 ISA Support", - [FeatureGP64Bit, FeatureFP64Bit, + [FeatureMips4, FeatureGP64Bit, FeatureFP64Bit, FeatureMips32, FeatureFPIdx]>; def FeatureMips64r2 : SubtargetFeature<"mips64r2", "MipsArchVersion", "Mips64r2", "Mips64r2 ISA Support", Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -199,13 +199,15 @@ def SEH64 : SignExtInReg<"seh", i16, GPR64Opnd, II_SEH>, SEB_FM<0x18, 0x20>; } -/// Count Leading -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", GPR64Opnd>, SEB_FM<2, 0x24>; -def DSHD : SubwordSwap<"dshd", GPR64Opnd>, SEB_FM<5, 0x24>; +let Predicates = [HasMips64] in { + /// Count Leading + 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", GPR64Opnd>, SEB_FM<2, 0x24>; + def DSHD : SubwordSwap<"dshd", GPR64Opnd>, SEB_FM<5, 0x24>; +} def LEA_ADDiu64 : EffectiveAddress<"daddiu", GPR64Opnd>, LW_FM<0x19>; Index: lib/Target/Mips/MipsCondMov.td =================================================================== --- lib/Target/Mips/MipsCondMov.td +++ lib/Target/Mips/MipsCondMov.td @@ -139,7 +139,7 @@ let isCodeGenOnly = 1 in def MOVN_I64_S : CMov_I_F_FT<"movn.s", GPR64Opnd, FGR32Opnd, II_MOVN_S>, - CMov_I_F_FM<19, 16>, Requires<[HasMips64, HasStdEnc]>; + CMov_I_F_FM<19, 16>, Requires<[IsGP64bit, HasStdEnc]>; let Predicates = [NotFP64bit, HasStdEnc] in { def MOVZ_I_D32 : MMRel, CMov_I_F_FT<"movz.d", GPR32Opnd, AFGR64Opnd, @@ -166,14 +166,14 @@ let isCodeGenOnly = 1 in def MOVT_I64 : CMov_F_I_FT<"movt", GPR64Opnd, II_MOVT, MipsCMovFP_T>, - CMov_F_I_FM<1>, Requires<[HasMips64, HasStdEnc]>; + CMov_F_I_FM<1>, Requires<[IsGP64bit, HasStdEnc]>; def MOVF_I : MMRel, CMov_F_I_FT<"movf", GPR32Opnd, II_MOVF, MipsCMovFP_F>, CMov_F_I_FM<0>; let isCodeGenOnly = 1 in def MOVF_I64 : CMov_F_I_FT<"movf", GPR64Opnd, II_MOVF, MipsCMovFP_F>, - CMov_F_I_FM<0>, Requires<[HasMips64, HasStdEnc]>; + CMov_F_I_FM<0>, Requires<[IsGP64bit, HasStdEnc]>; def MOVT_S : MMRel, CMov_F_F_FT<"movt.s", FGR32Opnd, II_MOVT_S, MipsCMovFP_T>, CMov_F_F_FM<16, 1>; @@ -198,7 +198,7 @@ defm : MovzPats0; defm : MovzPats1; defm : MovzPats2; -let Predicates = [HasMips64, HasStdEnc] in { +let Predicates = [IsGP64bit, HasStdEnc] in { defm : MovzPats0; defm : MovzPats0; @@ -213,7 +213,7 @@ } defm : MovnPats; -let Predicates = [HasMips64, HasStdEnc] in { +let Predicates = [IsGP64bit, HasStdEnc] in { defm : MovnPats; defm : MovnPats; defm : MovnPats; @@ -222,7 +222,7 @@ defm : MovzPats0; defm : MovzPats1; defm : MovnPats; -let Predicates = [HasMips64, HasStdEnc] in { +let Predicates = [IsGP64bit, HasStdEnc] in { defm : MovzPats0; defm : MovzPats1; Index: lib/Target/Mips/MipsISelLowering.h =================================================================== --- lib/Target/Mips/MipsISelLowering.h +++ lib/Target/Mips/MipsISelLowering.h @@ -432,7 +432,7 @@ // Subtarget Info const MipsSubtarget *Subtarget; - bool hasMips64() const { return Subtarget->hasMips64(); } + bool isGP64bit() const { return Subtarget->isGP64bit(); } bool isO32() const { return Subtarget->isABI_O32(); } bool isN32() const { return Subtarget->isABI_N32(); } bool isN64() const { return Subtarget->isABI_N64(); } Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -250,7 +250,7 @@ setOperationAction(ISD::FABS, MVT::f64, Custom); } - if (hasMips64()) { + if (isGP64bit()) { setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); setOperationAction(ISD::BlockAddress, MVT::i64, Custom); setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom); @@ -262,14 +262,14 @@ setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); } - if (!hasMips64()) { + if (!isGP64bit()) { setOperationAction(ISD::SHL_PARTS, MVT::i32, Custom); setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom); setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom); } setOperationAction(ISD::ADD, MVT::i32, Custom); - if (hasMips64()) + if (isGP64bit()) setOperationAction(ISD::ADD, MVT::i64, Custom); setOperationAction(ISD::SDIV, MVT::i32, Expand); @@ -371,7 +371,7 @@ setOperationAction(ISD::BSWAP, MVT::i64, Expand); } - if (hasMips64()) { + if (isGP64bit()) { setLoadExtAction(ISD::SEXTLOAD, MVT::i32, Custom); setLoadExtAction(ISD::ZEXTLOAD, MVT::i32, Custom); setLoadExtAction(ISD::EXTLOAD, MVT::i32, Custom); @@ -387,7 +387,7 @@ setTargetDAGCombine(ISD::OR); setTargetDAGCombine(ISD::ADD); - setMinFunctionAlignment(hasMips64() ? 3 : 2); + setMinFunctionAlignment(isGP64bit() ? 3 : 2); setStackPointerRegisterToSaveRestore(isN64() ? Mips::SP_64 : Mips::SP); @@ -1524,7 +1524,7 @@ MachinePointerInfo::getGOT()); return getAddrGlobal(N, Ty, DAG, - hasMips64() ? MipsII::MO_GOT_DISP : MipsII::MO_GOT16, + isGP64bit() ? MipsII::MO_GOT_DISP : MipsII::MO_GOT16, DAG.getEntryNode(), MachinePointerInfo::getGOT()); } @@ -3029,9 +3029,9 @@ return std::make_pair(0U, &Mips::CPU16RegsRegClass); return std::make_pair(0U, &Mips::GPR32RegClass); } - if (VT == MVT::i64 && !hasMips64()) + if (VT == MVT::i64 && !isGP64bit()) return std::make_pair(0U, &Mips::GPR32RegClass); - if (VT == MVT::i64 && hasMips64()) + if (VT == MVT::i64 && isGP64bit()) return std::make_pair(0U, &Mips::GPR64RegClass); // This will generate an error message return std::make_pair(0u, static_cast(0)); Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -160,6 +160,10 @@ AssemblerPredicate<"FeatureMips32">; def HasMips32r2 : Predicate<"Subtarget.hasMips32r2()">, AssemblerPredicate<"FeatureMips32r2">; +def IsGP64bit : Predicate<"Subtarget.isGP64bit()">, + AssemblerPredicate<"FeatureGP64Bit">; +def IsGP32bit : Predicate<"!Subtarget.isGP64bit()">, + AssemblerPredicate<"!FeatureGP64Bit">; def HasMips64 : Predicate<"Subtarget.hasMips64()">, AssemblerPredicate<"FeatureMips64">; def NotMips64 : Predicate<"!Subtarget.hasMips64()">, Index: lib/Target/Mips/MipsSEISelDAGToDAG.cpp =================================================================== --- lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -657,7 +657,7 @@ case ISD::ConstantFP: { ConstantFPSDNode *CN = dyn_cast(Node); if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) { - if (Subtarget.hasMips64()) { + if (Subtarget.isGP64bit()) { SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, Mips::ZERO_64, MVT::i64); Result = CurDAG->getMachineNode(Mips::DMTC1, DL, MVT::f64, Zero); Index: lib/Target/Mips/MipsSEISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsSEISelLowering.cpp +++ lib/Target/Mips/MipsSEISelLowering.cpp @@ -38,7 +38,7 @@ // Set up the register classes addRegisterClass(MVT::i32, &Mips::GPR32RegClass); - if (hasMips64()) + if (isGP64bit()) addRegisterClass(MVT::i64, &Mips::GPR64RegClass); if (Subtarget->hasDSP() || Subtarget->hasMSA()) { @@ -119,10 +119,10 @@ if (Subtarget->hasCnMips()) setOperationAction(ISD::MUL, MVT::i64, Legal); - else if (hasMips64()) + else if (isGP64bit()) setOperationAction(ISD::MUL, MVT::i64, Custom); - if (hasMips64()) { + if (isGP64bit()) { setOperationAction(ISD::MULHS, MVT::i64, Custom); setOperationAction(ISD::MULHU, MVT::i64, Custom); } @@ -1626,7 +1626,7 @@ case Intrinsic::mips_copy_s_w: return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_SEXT_ELT); case Intrinsic::mips_copy_s_d: - if (hasMips64()) + if (isGP64bit()) // Lower directly into VEXTRACT_SEXT_ELT since i64 is legal on Mips64. return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_SEXT_ELT); else { @@ -1641,7 +1641,7 @@ case Intrinsic::mips_copy_u_w: return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_ZEXT_ELT); case Intrinsic::mips_copy_u_d: - if (hasMips64()) + if (isGP64bit()) // Lower directly into VEXTRACT_ZEXT_ELT since i64 is legal on Mips64. return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_ZEXT_ELT); else { Index: lib/Target/Mips/MipsSubtarget.h =================================================================== --- lib/Target/Mips/MipsSubtarget.h +++ lib/Target/Mips/MipsSubtarget.h @@ -39,7 +39,7 @@ protected: enum MipsArchEnum { - Mips32, Mips32r2, Mips64, Mips64r2 + Mips32, Mips32r2, Mips4, Mips64, Mips64r2 }; // Mips architecture version Index: lib/Target/Mips/MipsSubtarget.cpp =================================================================== --- lib/Target/Mips/MipsSubtarget.cpp +++ lib/Target/Mips/MipsSubtarget.cpp @@ -117,8 +117,8 @@ ((getFeatureBits() & Mips::FeatureN64) != 0)) == 1); // Check if Architecture and ABI are compatible. - assert(((!hasMips64() && (isABI_O32() || isABI_EABI())) || - (hasMips64() && (isABI_N32() || isABI_N64()))) && + assert(((!isGP64bit() && (isABI_O32() || isABI_EABI())) || + (isGP64bit() && (isABI_N32() || isABI_N64()))) && "Invalid Arch & ABI pair."); if (hasMSA() && !isFP64bit()) @@ -143,7 +143,7 @@ RegClassVector &CriticalPathRCs) const { Mode = TargetSubtargetInfo::ANTIDEP_NONE; CriticalPathRCs.clear(); - CriticalPathRCs.push_back(hasMips64() ? + CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass); return OptLevel >= CodeGenOpt::Aggressive; }