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 { @@ -871,7 +871,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(); @@ -1037,10 +1037,10 @@ // Although SGI documentation just cuts out t0-t3 for n32/n64, // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. - if (isMips64() && 8 <= CC && CC <= 11) + if (isGP64() && 8 <= CC && CC <= 11) CC += 4; - if (CC == -1 && isMips64()) + if (CC == -1 && isGP64()) CC = StringSwitch(Name) .Case("a4", 8) .Case("a5", 9) @@ -1263,7 +1263,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)); @@ -1272,7 +1272,7 @@ return true; Parser.Lex(); // Eat the dollar - if (tryParseRegisterOperand(Operands, isMips64())) + if (tryParseRegisterOperand(Operands, isGP64())) return true; if (!getLexer().is(AsmToken::RParen)) @@ -1479,7 +1479,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); } @@ -1546,7 +1546,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"); @@ -1556,8 +1556,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; @@ -1949,7 +1949,7 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseGPR64(SmallVectorImpl &Operands) { - if (!isMips64()) + if (!isGP64()) return MatchOperand_NoMatch; return parseRegs(Operands, (int)MipsOperand::Kind_GPR64); } @@ -2131,8 +2131,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, IsN64, IsO32; + bool IsGP64bit, IsN64, IsO32; private: // Create a TargetGlobalAddress node. Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -206,7 +206,7 @@ MipsTargetLowering(MipsTargetMachine &TM) : TargetLowering(TM, new MipsTargetObjectFile()), Subtarget(&TM.getSubtarget()), - HasMips64(Subtarget->hasMips64()), IsN64(Subtarget->isABI_N64()), + IsGP64bit(Subtarget->isGP64bit()), IsN64(Subtarget->isABI_N64()), IsO32(Subtarget->isABI_O32()) { // Mips does not have i1 type, so use i32 for // setcc operations results (slt, sgt, ...). @@ -253,7 +253,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); @@ -265,14 +265,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); @@ -374,7 +374,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); @@ -390,7 +390,7 @@ setTargetDAGCombine(ISD::OR); setTargetDAGCombine(ISD::ADD); - setMinFunctionAlignment(HasMips64 ? 3 : 2); + setMinFunctionAlignment(IsGP64bit ? 3 : 2); setStackPointerRegisterToSaveRestore(IsN64 ? Mips::SP_64 : Mips::SP); @@ -1519,7 +1519,7 @@ } if (GV->hasInternalLinkage() || (GV->hasLocalLinkage() && !isa(GV))) - return getAddrLocal(N, Ty, DAG, HasMips64); + return getAddrLocal(N, Ty, DAG, IsGP64bit); if (LargeGOT) return getAddrGlobalLargeGOT(N, Ty, DAG, MipsII::MO_GOT_HI16, @@ -1527,7 +1527,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()); } @@ -1539,7 +1539,7 @@ if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) return getAddrNonPIC(N, Ty, DAG); - return getAddrLocal(N, Ty, DAG, HasMips64); + return getAddrLocal(N, Ty, DAG, IsGP64bit); } SDValue MipsTargetLowering:: @@ -1632,7 +1632,7 @@ if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) return getAddrNonPIC(N, Ty, DAG); - return getAddrLocal(N, Ty, DAG, HasMips64); + return getAddrLocal(N, Ty, DAG, IsGP64bit); } SDValue MipsTargetLowering:: @@ -1653,7 +1653,7 @@ if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) return getAddrNonPIC(N, Ty, DAG); - return getAddrLocal(N, Ty, DAG, HasMips64); + return getAddrLocal(N, Ty, DAG, IsGP64bit); } SDValue MipsTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const { @@ -2510,7 +2510,7 @@ InternalLinkage = Val->hasInternalLinkage(); if (InternalLinkage) - Callee = getAddrLocal(G, Ty, DAG, HasMips64); + Callee = getAddrLocal(G, Ty, DAG, IsGP64bit); else if (LargeGOT) Callee = getAddrGlobalLargeGOT(G, Ty, DAG, MipsII::MO_CALL_HI16, MipsII::MO_CALL_LO16, Chain, @@ -3032,9 +3032,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; }