Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -48,6 +48,8 @@ bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; } + bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; } + bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; } bool hasCOP3() const { @@ -977,6 +979,16 @@ } } + if (hasMips32r6() && isPTR64()) { + DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n"); + Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn, + Address, this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + } + if (hasMips32r6()) { DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n"); Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn, Index: lib/Target/Mips/Mips.td =================================================================== --- lib/Target/Mips/Mips.td +++ lib/Target/Mips/Mips.td @@ -62,6 +62,8 @@ def FeatureNoABICalls : SubtargetFeature<"noabicalls", "NoABICalls", "true", "Disable SVR4-style position-independent code">; +def FeaturePTR64Bit : SubtargetFeature<"ptr64", "IsPTR64bit", "true", + "Pointers are 64-bit wide">; def FeatureGP64Bit : SubtargetFeature<"gp64", "IsGP64bit", "true", "General Purpose Registers are 64-bit wide">; def FeatureFP64Bit : SubtargetFeature<"fp64", "IsFP64bit", "true", Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -760,8 +760,9 @@ def JIC : R6MMR6Rel, JIC_ENC, JIC_DESC, ISA_MIPS32R6; def JR_HB_R6 : JR_HB_R6_ENC, JR_HB_R6_DESC, ISA_MIPS32R6; def LDC2_R6 : LDC2_R6_ENC, LDC2_R6_DESC, ISA_MIPS32R6; -let AdditionalPredicates = [NotInMicroMips] in { +let AdditionalPredicates = [IsPTR32bit, NotInMicroMips] in { def LL_R6 : LL_R6_ENC, LL_R6_DESC, ISA_MIPS32R6; + def SC_R6 : SC_R6_ENC, SC_R6_DESC, ISA_MIPS32R6; } def LSA_R6 : R6MMR6Rel, LSA_R6_ENC, LSA_R6_DESC, ISA_MIPS32R6; def LWC2_R6 : LWC2_R6_ENC, LWC2_R6_DESC, ISA_MIPS32R6; @@ -795,7 +796,6 @@ let AdditionalPredicates = [NotInMicroMips] in { def RINT_D : RINT_D_ENC, RINT_D_DESC, ISA_MIPS32R6, HARDFLOAT; def RINT_S : RINT_S_ENC, RINT_S_DESC, ISA_MIPS32R6, HARDFLOAT; - def SC_R6 : SC_R6_ENC, SC_R6_DESC, ISA_MIPS32R6; def SDBBP_R6 : SDBBP_R6_ENC, SDBBP_R6_DESC, ISA_MIPS32R6; } def SDC2_R6 : SDC2_R6_ENC, SDC2_R6_DESC, ISA_MIPS32R6; Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -214,6 +214,11 @@ def LLD : LLBase<"lld", GPR64Opnd>, LW_FM<0x34>, ISA_MIPS3_NOT_32R6_64R6; def SCD : SCBase<"scd", GPR64Opnd>, LW_FM<0x3c>, ISA_MIPS3_NOT_32R6_64R6; +let AdditionalPredicates = [NotInMicroMips, IsPTR64bit] in { +def LL64 : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2_NOT_32R6_64R6; +def SC64 : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2_NOT_32R6_64R6; +} + /// Jump and Branch Instructions let isCodeGenOnly = 1 in { def JR64 : IndirectBranch<"jr", GPR64Opnd>, MTLO_FM<8>; Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -88,6 +88,8 @@ list Defs = [AT]; } +class LL64_R6_DESC : LL_R6_DESC_BASE<"ll", GPR32Opnd, II_LL>; +class SC64_R6_DESC : SC_R6_DESC_BASE<"sc", GPR32Opnd, II_SC>; //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -123,6 +125,11 @@ def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS32R6, GPR_64; def SELNEZ64 : SELNEZ_ENC, SELNEZ64_DESC, ISA_MIPS32R6, GPR_64; } +let DecoderNamespace = "Mips32r6_64r6_PTR64", + AdditionalPredicates = [IsPTR64bit] in { + def LL64_R6 : LL_R6_ENC, LL64_R6_DESC, ISA_MIPS64R6; + def SC64_R6 : SC_R6_ENC, SC64_R6_DESC, ISA_MIPS64R6; +} let isCodeGenOnly = 1 in { def JIALC64 : JIALC_ENC, JIALC64_DESC, ISA_MIPS64R6; def JIC64 : JIC_ENC, JIC64_DESC, ISA_MIPS64R6; Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -1106,19 +1106,23 @@ MachineRegisterInfo &RegInfo = MF->getRegInfo(); const TargetRegisterClass *RC = getRegClassFor(MVT::getIntegerVT(Size * 8)); const TargetInstrInfo *TII = Subtarget.getInstrInfo(); + const bool ArePtrs64bit = ABI.ArePtrs64bit(); DebugLoc DL = MI->getDebugLoc(); unsigned LL, SC, AND, NOR, ZERO, BEQ; - // FIXME: The below code should check for the ISA to emit the correct 64bit - // operations when the size is 4. if (Size == 4) { if (isMicroMips) { LL = Mips::LL_MM; SC = Mips::SC_MM; } else { - LL = Subtarget.hasMips32r6() ? Mips::LL_R6 : Mips::LL; - SC = Subtarget.hasMips32r6() ? Mips::SC_R6 : Mips::SC; + LL = Subtarget.hasMips32r6() + ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6) + : (ArePtrs64bit ? Mips::LL64 : Mips::LL); + SC = Subtarget.hasMips32r6() + ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6) + : (ArePtrs64bit ? Mips::SC64 : Mips::SC); } + AND = Mips::AND; NOR = Mips::NOR; ZERO = Mips::ZERO; @@ -1225,7 +1229,7 @@ MachineFunction *MF = BB->getParent(); MachineRegisterInfo &RegInfo = MF->getRegInfo(); const TargetRegisterClass *RC = getRegClassFor(MVT::i32); - bool ArePtrs64bit = ABI.ArePtrs64bit(); + const bool ArePtrs64bit = ABI.ArePtrs64bit(); const TargetRegisterClass *RCp = getRegClassFor(ArePtrs64bit ? MVT::i64 : MVT::i32); const TargetInstrInfo *TII = Subtarget.getInstrInfo(); @@ -1253,6 +1257,17 @@ unsigned SrlRes = RegInfo.createVirtualRegister(RC); unsigned Success = RegInfo.createVirtualRegister(RC); + unsigned LL, SC; + if (isMicroMips) { + LL = Mips::LL_MM; + SC = Mips::SC_MM; + } else { + LL = Subtarget.hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6) + : (ArePtrs64bit ? Mips::LL64 : Mips::LL); + SC = Subtarget.hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6) + : (ArePtrs64bit ? Mips::SC64 : Mips::SC); + } + // insert new blocks after the current block const BasicBlock *LLVM_BB = BB->getBasicBlock(); MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB); @@ -1325,7 +1340,6 @@ // beq success,$0,loopMBB BB = loopMBB; - unsigned LL = isMicroMips ? Mips::LL_MM : Mips::LL; BuildMI(BB, DL, TII->get(LL), OldVal).addReg(AlignedAddr).addImm(0); if (Nand) { // and andres, oldval, incr2 @@ -1349,7 +1363,6 @@ .addReg(OldVal).addReg(Mask2); BuildMI(BB, DL, TII->get(Mips::OR), StoreVal) .addReg(MaskedOldVal0).addReg(NewVal); - unsigned SC = isMicroMips ? Mips::SC_MM : Mips::SC; BuildMI(BB, DL, TII->get(SC), Success) .addReg(StoreVal).addReg(AlignedAddr).addImm(0); BuildMI(BB, DL, TII->get(Mips::BEQ)) @@ -1381,17 +1394,23 @@ MachineRegisterInfo &RegInfo = MF->getRegInfo(); const TargetRegisterClass *RC = getRegClassFor(MVT::getIntegerVT(Size * 8)); const TargetInstrInfo *TII = Subtarget.getInstrInfo(); + const bool ArePtrs64bit = ABI.ArePtrs64bit(); DebugLoc DL = MI->getDebugLoc(); unsigned LL, SC, ZERO, BNE, BEQ; - if (Size == 4) { - if (isMicroMips) { - LL = Mips::LL_MM; - SC = Mips::SC_MM; - } else { - LL = Subtarget.hasMips32r6() ? Mips::LL_R6 : Mips::LL; - SC = Subtarget.hasMips32r6() ? Mips::SC_R6 : Mips::SC; - } + if (Size == 4) { + if (isMicroMips) { + LL = Mips::LL_MM; + SC = Mips::SC_MM; + } else { + LL = Subtarget.hasMips32r6() + ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6) + : (ArePtrs64bit ? Mips::LL64 : Mips::LL); + SC = Subtarget.hasMips32r6() + ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6) + : (ArePtrs64bit ? Mips::SC64 : Mips::SC); + } + ZERO = Mips::ZERO; BNE = Mips::BNE; BEQ = Mips::BEQ; @@ -1466,7 +1485,7 @@ MachineFunction *MF = BB->getParent(); MachineRegisterInfo &RegInfo = MF->getRegInfo(); const TargetRegisterClass *RC = getRegClassFor(MVT::i32); - bool ArePtrs64bit = ABI.ArePtrs64bit(); + const bool ArePtrs64bit = ABI.ArePtrs64bit(); const TargetRegisterClass *RCp = getRegClassFor(ArePtrs64bit ? MVT::i64 : MVT::i32); const TargetInstrInfo *TII = Subtarget.getInstrInfo(); @@ -1494,6 +1513,17 @@ unsigned StoreVal = RegInfo.createVirtualRegister(RC); unsigned SrlRes = RegInfo.createVirtualRegister(RC); unsigned Success = RegInfo.createVirtualRegister(RC); + unsigned LL, SC; + + if (isMicroMips) { + LL = Mips::LL_MM; + SC = Mips::SC_MM; + } else { + LL = Subtarget.hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6) + : (ArePtrs64bit ? Mips::LL64 : Mips::LL); + SC = Subtarget.hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6) + : (ArePtrs64bit ? Mips::SC64 : Mips::SC); + } // insert new blocks after the current block const BasicBlock *LLVM_BB = BB->getBasicBlock(); @@ -1567,7 +1597,6 @@ // and maskedoldval0,oldval,mask // bne maskedoldval0,shiftedcmpval,sinkMBB BB = loop1MBB; - unsigned LL = isMicroMips ? Mips::LL_MM : Mips::LL; BuildMI(BB, DL, TII->get(LL), OldVal).addReg(AlignedAddr).addImm(0); BuildMI(BB, DL, TII->get(Mips::AND), MaskedOldVal0) .addReg(OldVal).addReg(Mask); @@ -1584,7 +1613,6 @@ .addReg(OldVal).addReg(Mask2); BuildMI(BB, DL, TII->get(Mips::OR), StoreVal) .addReg(MaskedOldVal1).addReg(ShiftedNewVal); - unsigned SC = isMicroMips ? Mips::SC_MM : Mips::SC; BuildMI(BB, DL, TII->get(SC), Success) .addReg(StoreVal).addReg(AlignedAddr).addImm(0); BuildMI(BB, DL, TII->get(Mips::BEQ)) Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -179,6 +179,10 @@ AssemblerPredicate<"FeatureGP64Bit">; def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">, AssemblerPredicate<"!FeatureGP64Bit">; +def IsPTR64bit : Predicate<"Subtarget->isABI_N64()">, + AssemblerPredicate<"FeaturePTR64Bit">; +def IsPTR32bit : Predicate<"!Subtarget->isABI_N64()">, + AssemblerPredicate<"!FeaturePTR64Bit">; def HasMips64 : Predicate<"Subtarget->hasMips64()">, AssemblerPredicate<"FeatureMips64">; def NotMips64 : Predicate<"!Subtarget->hasMips64()">, @@ -1814,7 +1818,9 @@ let EncodingPredicates = [], // FIXME: Lack of HasStdEnc is probably a bug AdditionalPredicates = [NotInMicroMips] in { def WAIT : WAIT_FT<"wait">, WAIT_FM; +} +let AdditionalPredicates = [NotInMicroMips, IsPTR32bit] in { /// Load-linked, Store-conditional def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2_NOT_32R6_64R6; def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2_NOT_32R6_64R6; Index: lib/Target/Mips/MipsSubtarget.h =================================================================== --- lib/Target/Mips/MipsSubtarget.h +++ lib/Target/Mips/MipsSubtarget.h @@ -81,6 +81,9 @@ // IsFP64bit - General-purpose registers are 64 bits wide bool IsGP64bit; + // IsPTR64bit - Pointers are 64 bit wide + bool IsPTR64bit; + // HasVFPU - Processor has a vector floating point unit. bool HasVFPU; @@ -223,6 +226,8 @@ bool isGP64bit() const { return IsGP64bit; } bool isGP32bit() const { return !IsGP64bit; } unsigned getGPRSizeInBytes() const { return isGP64bit() ? 8 : 4; } + bool isPTR64bit() const { return IsPTR64bit; } + bool isPTR32bit() const { return !IsPTR64bit; } bool isSingleFloat() const { return IsSingleFloat; } bool hasVFPU() const { return HasVFPU; } bool inMips16Mode() const { return InMips16Mode; } Index: test/CodeGen/Mips/atomic.ll =================================================================== --- test/CodeGen/Mips/atomic.ll +++ test/CodeGen/Mips/atomic.ll @@ -1,16 +1,26 @@ -; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS -; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r2 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS -; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r6 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=MIPSR6 -; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips4 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS -; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS -; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64r2 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS -; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64r6 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=MIPSR6 -; RUN: llc -march=mips64 -O0 -mcpu=mips64r6 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL-LABEL -check-prefix=MIPS64-ANY -check-prefix=O0 -;; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r2 -mattr=micromips -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=MICROMIPS +; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32 -relocation-model=pic < %s | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS +; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r2 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS +; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r6 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=MIPSR6 +; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips4 -relocation-model=pic < %s | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS +; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64 -relocation-model=pic < %s | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS +; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64r2 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS +; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64r6 -relocation-model=pic < %s | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=MIPSR6 +; RUN: llc -march=mips64 -O0 -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s \ +; RUN: -check-prefix=ALL-LABEL -check-prefix=MIPS64-ANY -check-prefix=O0 +; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r2 -mattr=micromips -relocation-model=pic < %s | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=MICROMIPS ; Keep one big-endian check so that we don't reduce testing, but don't add more ; since endianness doesn't affect the body of the atomic operations. -; RUN: llc -march=mips --disable-machine-licm -mcpu=mips32 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EB -check-prefix=NOT-MICROMIPS +; RUN: llc -march=mips --disable-machine-licm -mcpu=mips32 -relocation-model=pic < %s | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EB -check-prefix=NOT-MICROMIPS @x = common global i32 0, align 4