Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -1414,8 +1414,15 @@ "Unsupported size for EmitAtomicCmpSwapPartial."); MachineFunction *MF = BB->getParent(); + bool ArePtrs64bit = ABI.ArePtrs64bit(); + bool AreInts64bit = ABI.AreGprs64bit(); MachineRegisterInfo &RegInfo = MF->getRegInfo(); - const TargetRegisterClass *RC = getRegClassFor(MVT::i32); + llvm::MVT PointerSize = ArePtrs64bit ? MVT::i64 : MVT::i32; + llvm::MVT IntValSize = AreInts64bit ? MVT::i64 : MVT::i32; + const TargetRegisterClass *RCp = getRegClassFor(PointerSize); + const TargetRegisterClass *RCi = getRegClassFor(IntValSize); + // RC32 for values known to fit into 32 bits to avoid spilling 2 words. + const TargetRegisterClass *RC32 = getRegClassFor(MVT::i32); const TargetInstrInfo *TII = Subtarget.getInstrInfo(); DebugLoc DL = MI->getDebugLoc(); @@ -1424,23 +1431,23 @@ unsigned CmpVal = MI->getOperand(2).getReg(); unsigned NewVal = MI->getOperand(3).getReg(); - unsigned AlignedAddr = RegInfo.createVirtualRegister(RC); - unsigned ShiftAmt = RegInfo.createVirtualRegister(RC); - unsigned Mask = RegInfo.createVirtualRegister(RC); - unsigned Mask2 = RegInfo.createVirtualRegister(RC); - unsigned ShiftedCmpVal = RegInfo.createVirtualRegister(RC); - unsigned OldVal = RegInfo.createVirtualRegister(RC); - unsigned MaskedOldVal0 = RegInfo.createVirtualRegister(RC); - unsigned ShiftedNewVal = RegInfo.createVirtualRegister(RC); - unsigned MaskLSB2 = RegInfo.createVirtualRegister(RC); - unsigned PtrLSB2 = RegInfo.createVirtualRegister(RC); - unsigned MaskUpper = RegInfo.createVirtualRegister(RC); - unsigned MaskedCmpVal = RegInfo.createVirtualRegister(RC); - unsigned MaskedNewVal = RegInfo.createVirtualRegister(RC); - unsigned MaskedOldVal1 = RegInfo.createVirtualRegister(RC); - unsigned StoreVal = RegInfo.createVirtualRegister(RC); - unsigned SrlRes = RegInfo.createVirtualRegister(RC); - unsigned Success = RegInfo.createVirtualRegister(RC); + unsigned AlignedAddr = RegInfo.createVirtualRegister(RCp); + unsigned ShiftAmt = RegInfo.createVirtualRegister(RC32); + unsigned Mask = RegInfo.createVirtualRegister(RCi); + unsigned Mask2 = RegInfo.createVirtualRegister(RCi); + unsigned ShiftedCmpVal = RegInfo.createVirtualRegister(RCi); + unsigned OldVal = RegInfo.createVirtualRegister(RCi); + unsigned MaskedOldVal0 = RegInfo.createVirtualRegister(RCi); + unsigned ShiftedNewVal = RegInfo.createVirtualRegister(RCi); + unsigned MaskLSB2 = RegInfo.createVirtualRegister(RCi); + unsigned PtrLSB2 = RegInfo.createVirtualRegister(RC32); + unsigned MaskUpper = RegInfo.createVirtualRegister(RC32); + unsigned MaskedCmpVal = RegInfo.createVirtualRegister(RCi); + unsigned MaskedNewVal = RegInfo.createVirtualRegister(RCi); + unsigned MaskedOldVal1 = RegInfo.createVirtualRegister(RCi); + unsigned StoreVal = RegInfo.createVirtualRegister(RCi); + unsigned SrlRes = RegInfo.createVirtualRegister(RCi); + unsigned Success = RegInfo.createVirtualRegister(RCi); // insert new blocks after the current block const BasicBlock *LLVM_BB = BB->getBasicBlock(); @@ -1480,32 +1487,34 @@ // andi maskednewval,newval,255 // sll shiftednewval,maskednewval,shiftamt int64_t MaskImm = (Size == 1) ? 255 : 65535; - BuildMI(BB, DL, TII->get(Mips::ADDiu), MaskLSB2) - .addReg(Mips::ZERO).addImm(-4); - BuildMI(BB, DL, TII->get(Mips::AND), AlignedAddr) - .addReg(Ptr).addReg(MaskLSB2); - BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2).addReg(Ptr).addImm(3); - if (Subtarget.isLittle()) { - BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3); - } else { - unsigned Off = RegInfo.createVirtualRegister(RC); - BuildMI(BB, DL, TII->get(Mips::XORi), Off) - .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2); - BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(Off).addImm(3); - } - BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper) - .addReg(Mips::ZERO).addImm(MaskImm); - BuildMI(BB, DL, TII->get(Mips::SLLV), Mask) - .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(MaskedCmpVal).addReg(ShiftAmt); - BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedNewVal) - .addReg(NewVal).addImm(MaskImm); - BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedNewVal) - .addReg(MaskedNewVal).addReg(ShiftAmt); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::DADDiu : Mips::ADDiu), MaskLSB2) + .addReg(ABI.GetZeroReg()).addImm(-4); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::AND64 : Mips::AND), AlignedAddr) + .addReg(Ptr).addReg(MaskLSB2); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::ANDi64 : Mips::ANDi), PtrLSB2) + .addReg(Ptr).addImm(3); + if (!Subtarget.isLittle()) { + unsigned Off = RegInfo.createVirtualRegister(RC32); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::XORi64 : Mips::XORi), Off) + .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2); + PtrLSB2 = Off; + } + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::DSLL : Mips::SLL), ShiftAmt) + .addReg(PtrLSB2).addImm(3); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::ORi64 : Mips::ORi), MaskUpper) + .addReg(ABI.GetZeroReg()).addImm(MaskImm); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::DSLLV : Mips::SLLV), Mask) + .addReg(MaskUpper).addReg(ShiftAmt); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::NOR64 : Mips::NOR), Mask2) + .addReg(ABI.GetZeroReg()).addReg(Mask); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::ANDi64 : Mips::ANDi), + MaskedCmpVal).addReg(CmpVal).addImm(MaskImm); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::DSLLV : Mips::SLLV), + ShiftedCmpVal).addReg(MaskedCmpVal).addReg(ShiftAmt); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::ANDi64 : Mips::ANDi), + MaskedNewVal).addReg(NewVal).addImm(MaskImm); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::DSLLV : Mips::SLLV), + ShiftedNewVal).addReg(MaskedNewVal).addReg(ShiftAmt); // loop1MBB: // ll oldval,0(alginedaddr) @@ -1514,10 +1523,10 @@ 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); - BuildMI(BB, DL, TII->get(Mips::BNE)) - .addReg(MaskedOldVal0).addReg(ShiftedCmpVal).addMBB(sinkMBB); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::AND64 : Mips::AND), + MaskedOldVal0).addReg(OldVal).addReg(Mask); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::BNE64 : Mips::BNE)) + .addReg(MaskedOldVal0).addReg(ShiftedCmpVal).addMBB(sinkMBB); // loop2MBB: // and maskedoldval1,oldval,mask2 @@ -1525,22 +1534,22 @@ // sc success,storeval,0(alignedaddr) // beq success,$0,loop1MBB BB = loop2MBB; - BuildMI(BB, DL, TII->get(Mips::AND), MaskedOldVal1) - .addReg(OldVal).addReg(Mask2); - BuildMI(BB, DL, TII->get(Mips::OR), StoreVal) - .addReg(MaskedOldVal1).addReg(ShiftedNewVal); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::AND64 : Mips::AND), + MaskedOldVal1).addReg(OldVal).addReg(Mask2); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::OR64 : 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)) - .addReg(Success).addReg(Mips::ZERO).addMBB(loop1MBB); + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::BEQ64 : Mips::BEQ)) + .addReg(Success).addReg(ABI.GetZeroReg()).addMBB(loop1MBB); // sinkMBB: // srl srlres,maskedoldval0,shiftamt // sign_extend dest,srlres BB = sinkMBB; - BuildMI(BB, DL, TII->get(Mips::SRLV), SrlRes) + BuildMI(BB, DL, TII->get(AreInts64bit ? Mips::DSRLV : Mips::SRLV), SrlRes) .addReg(MaskedOldVal0).addReg(ShiftAmt); BB = emitSignExtendToI32InReg(MI, BB, Size, Dest, SrlRes); Index: test/CodeGen/Mips/atomic.ll =================================================================== --- test/CodeGen/Mips/atomic.ll +++ test/CodeGen/Mips/atomic.ll @@ -1,10 +1,10 @@ ; 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=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 -check-prefix=MIPS32R6 ; 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=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 -check-prefix=MIPS64R6 ; 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 ; Keep one big-endian check so that we don't reduce testing, but don't add more @@ -298,14 +298,16 @@ ; ALL: and $[[R14:[0-9]+]], $[[R13]], $[[R7]] ; NOT-MICROMIPS: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] ; MICROMIPS: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] -; MIPSR6: bnec $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] +; MIPS32R6: bnec $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] +; MIPS64R6: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] ; ALL: and $[[R15:[0-9]+]], $[[R13]], $[[R8]] ; ALL: or $[[R16:[0-9]+]], $[[R15]], $[[R12]] ; ALL: sc $[[R16]], 0($[[R2]]) ; NOT-MICROMIPS: beqz $[[R16]], $[[BB0]] ; MICROMIPS: beqzc $[[R16]], $[[BB0]] -; MIPSR6: beqzc $[[R16]], $[[BB0]] +; MIPS32R6: beqzc $[[R16]], $[[BB0]] +; MIPS64R6: beqz $[[R16]], $[[BB0]] ; ALL: $[[BB1]]: ; ALL: srlv $[[R17:[0-9]+]], $[[R14]], $[[R5]] @@ -342,14 +344,16 @@ ; ALL: and $[[R14:[0-9]+]], $[[R13]], $[[R7]] ; NOT-MICROMIPS: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] ; MICROMIPS: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] -; MIPSR6: bnec $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] +; MIPS32R6: bnec $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] +; MIPS64R6: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] ; ALL: and $[[R15:[0-9]+]], $[[R13]], $[[R8]] ; ALL: or $[[R16:[0-9]+]], $[[R15]], $[[R12]] ; ALL: sc $[[R16]], 0($[[R2]]) ; NOT-MICROMIPS: beqz $[[R16]], $[[BB0]] ; MICROMIPS: beqzc $[[R16]], $[[BB0]] -; MIPSR6: beqzc $[[R16]], $[[BB0]] +; MIPS32R6: beqzc $[[R16]], $[[BB0]] +; MIPS64R6: beqz $[[R16]], $[[BB0]] ; ALL: $[[BB1]]: ; ALL: srlv $[[R17:[0-9]+]], $[[R14]], $[[R5]] @@ -440,7 +444,8 @@ ; ALL: sc $[[R8]], 0($[[R5]]) ; NOT-MICROMIPS: beqz $[[R8]], $[[BB0]] ; MICROMIPS: beqzc $[[R8]], $[[BB0]] -; MIPSR6: beqzc $[[R8]], $[[BB0]] +; MIPS32R6: beqzc $[[R8]], $[[BB0]] +; MIPS64R6: beqz $[[R8]], $[[BB0]] ; ALL: srlv $[[R9:[0-9]+]], $[[R6]], $ Index: test/CodeGen/Mips/atomicCmpSwapPW.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/atomicCmpSwapPW.ll @@ -0,0 +1,11 @@ +; RUN: llc -O0 -march=mips64el -mcpu=mips64r2 -target-abi=n64 < %s -filetype=asm -o - \ +; RUN: | FileCheck %s + +; CHECK: ld $[[R0:[0-9]+]] +; CHECK: ll ${{[0-9]+}}, 0($[[R0]]) + +define {i16, i1} @foo(i16* %addr, i16 signext %r, i16 zeroext %new) { + %res = cmpxchg i16* %addr, i16 %r, i16 %new seq_cst seq_cst + ret {i16, i1} %res +} +