Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -1139,36 +1139,6 @@ return exitMBB; } -MachineBasicBlock *MipsTargetLowering::emitSignExtendToI32InReg( - MachineInstr *MI, MachineBasicBlock *BB, unsigned Size, unsigned DstReg, - unsigned SrcReg) const { - const TargetInstrInfo *TII = Subtarget.getInstrInfo(); - DebugLoc DL = MI->getDebugLoc(); - - if (Subtarget.hasMips32r2() && Size == 1) { - BuildMI(BB, DL, TII->get(Mips::SEB), DstReg).addReg(SrcReg); - return BB; - } - - if (Subtarget.hasMips32r2() && Size == 2) { - BuildMI(BB, DL, TII->get(Mips::SEH), DstReg).addReg(SrcReg); - return BB; - } - - MachineFunction *MF = BB->getParent(); - MachineRegisterInfo &RegInfo = MF->getRegInfo(); - const TargetRegisterClass *RC = getRegClassFor(MVT::i32); - unsigned ScrReg = RegInfo.createVirtualRegister(RC); - - assert(Size < 32); - int64_t ShiftImm = 32 - (Size * 8); - - BuildMI(BB, DL, TII->get(Mips::SLL), ScrReg).addReg(SrcReg).addImm(ShiftImm); - BuildMI(BB, DL, TII->get(Mips::SRA), DstReg).addReg(ScrReg).addImm(ShiftImm); - - return BB; -} - MachineBasicBlock *MipsTargetLowering::emitAtomicBinaryPartword( MachineInstr *MI, MachineBasicBlock *BB, unsigned Size, unsigned BinOpcode, bool Nand) const { @@ -1200,7 +1170,6 @@ unsigned MaskedOldVal0 = RegInfo.createVirtualRegister(RC); unsigned StoreVal = RegInfo.createVirtualRegister(RC); unsigned MaskedOldVal1 = RegInfo.createVirtualRegister(RC); - unsigned SrlRes = RegInfo.createVirtualRegister(RC); unsigned Success = RegInfo.createVirtualRegister(RC); // insert new blocks after the current block @@ -1306,15 +1275,13 @@ // sinkMBB: // and maskedoldval1,oldval,mask - // srl srlres,maskedoldval1,shiftamt - // sign_extend dest,srlres + // srl dest,maskedoldval1,shiftamt BB = sinkMBB; BuildMI(BB, DL, TII->get(Mips::AND), MaskedOldVal1) .addReg(OldVal).addReg(Mask); - BuildMI(BB, DL, TII->get(Mips::SRLV), SrlRes) + BuildMI(BB, DL, TII->get(Mips::SRLV), Dest) .addReg(MaskedOldVal1).addReg(ShiftAmt); - BB = emitSignExtendToI32InReg(MI, BB, Size, Dest, SrlRes); MI->eraseFromParent(); // The instruction is gone now. @@ -1438,7 +1405,6 @@ 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); // insert new blocks after the current block @@ -1535,13 +1501,11 @@ .addReg(Success).addReg(Mips::ZERO).addMBB(loop1MBB); // sinkMBB: - // srl srlres,maskedoldval0,shiftamt - // sign_extend dest,srlres + // srl dest,maskedoldval0,shiftamt BB = sinkMBB; - BuildMI(BB, DL, TII->get(Mips::SRLV), SrlRes) + BuildMI(BB, DL, TII->get(Mips::SRLV), Dest) .addReg(MaskedOldVal0).addReg(ShiftAmt); - BB = emitSignExtendToI32InReg(MI, BB, Size, Dest, SrlRes); MI->eraseFromParent(); // The instruction is gone now. Index: test/CodeGen/Mips/atomic.ll =================================================================== --- test/CodeGen/Mips/atomic.ll +++ test/CodeGen/Mips/atomic.ll @@ -218,6 +218,47 @@ ; HAS-SEB-SEH: seb $2, $[[R16]] } +define zeroext i16 @AtomicLoadNand16Unsigned(i16 zeroext %incr) nounwind { +entry: + %0 = atomicrmw nand i16* @z, i16 %incr monotonic + ret i16 %0 + +; ALL-LABEL: AtomicLoadNand16Unsigned: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(z) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(z)( + +; ALL: addiu $[[R1:[0-9]+]], $zero, -4 +; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] +; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 +; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 +; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 2 +; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 +; ALL: ori $[[R6:[0-9]+]], $zero, 65535 +; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] +; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] +; ALL: sllv $[[R9:[0-9]+]], $4, $[[R5]] + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R10:[0-9]+]], 0($[[R2]]) +; ALL: and $[[R18:[0-9]+]], $[[R10]], $[[R9]] +; ALL: nor $[[R11:[0-9]+]], $zero, $[[R18]] +; ALL: and $[[R12:[0-9]+]], $[[R11]], $[[R7]] +; ALL: and $[[R13:[0-9]+]], $[[R10]], $[[R8]] +; ALL: or $[[R14:[0-9]+]], $[[R13]], $[[R12]] +; ALL: sc $[[R14]], 0($[[R2]]) +; NOT-MICROMIPS: beqz $[[R14]], $[[BB0]] +; MICROMIPS: beqzc $[[R14]], $[[BB0]] + +; ALL: and $[[R15:[0-9]+]], $[[R10]], $[[R7]] +; ALL: srlv $[[R16:[0-9]+]], $[[R15]], $[[R5]] + +; ALL-NOT: sll $[[R17:[0-9]+]], $[[R16]], 16 +; ALL-NOT: sra $2, $[[R17]], 16 + +; ALL-NOT: seb $2, $[[R16]] +} + define signext i8 @AtomicSwap8(i8 signext %newval) nounwind { entry: %0 = atomicrmw xchg i8* @y, i8 %newval monotonic @@ -303,6 +344,51 @@ ; HAS-SEB-SEH: seb $2, $[[R17]] } +define zeroext i8 @AtomicCmpSwap8Unsigned(i8 zeroext %oldval, i8 zeroext %newval) nounwind { +entry: + %pair0 = cmpxchg i8* @y, i8 %oldval, i8 %newval monotonic monotonic + %0 = extractvalue { i8, i1 } %pair0, 0 + ret i8 %0 + +; ALL-LABEL: AtomicCmpSwap8Unsigned: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(y) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(y)( + +; ALL: addiu $[[R1:[0-9]+]], $zero, -4 +; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] +; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 +; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 +; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 +; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 +; ALL: ori $[[R6:[0-9]+]], $zero, 255 +; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] +; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] +; ALL: andi $[[R9:[0-9]+]], $4, 255 +; ALL: sllv $[[R10:[0-9]+]], $[[R9]], $[[R5]] +; ALL: andi $[[R11:[0-9]+]], $5, 255 +; ALL: sllv $[[R12:[0-9]+]], $[[R11]], $[[R5]] + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R13:[0-9]+]], 0($[[R2]]) +; ALL: and $[[R14:[0-9]+]], $[[R13]], $[[R7]] +; ALL: 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]] + +; ALL: $[[BB1]]: +; ALL: srlv $[[R17:[0-9]+]], $[[R14]], $[[R5]] + +; ALL-NOT: sll $[[R18:[0-9]+]], $[[R17]], 24 +; ALL-NOT: sra $2, $[[R18]], 24 + +; ALL-NOT: seb $2, $[[R17]] +} + define i1 @AtomicCmpSwapRes8(i8* %ptr, i8 signext %oldval, i8 signext %newval) nounwind { entry: %0 = cmpxchg i8* %ptr, i8 %oldval, i8 %newval monotonic monotonic @@ -338,18 +424,58 @@ ; ALL: $[[BB1]]: ; ALL: srlv $[[R17:[0-9]+]], $[[R14]], $[[R5]] -; NO-SEB-SEH: sll $[[R18:[0-9]+]], $[[R17]], 24 -; NO-SEB-SEH: sra $[[R19:[0-9]+]], $[[R18]], 24 - -; HAS-SEB-SEH: seb $[[R19:[0-9]+]], $[[R17]] - -; ALL: xor $[[R20:[0-9]+]], $[[R19]], $5 -; ALL: sltiu $2, $[[R20]], 1 +; ALL: xor $[[R18:[0-9]+]], $[[R17]], $5 +; ALL: sltiu $2, $[[R18]], 1 } -; Check one i16 so that we cover the seh sign extend @z = common global i16 0, align 1 +; Check one unsigned i16 so we cover the zero extend case +define zeroext i16 @AtomicCmpSwap16Unsigned(i16 zeroext %oldval, i16 zeroext %newval) nounwind { +entry: + %pair0 = cmpxchg i16* @z, i16 %oldval, i16 %newval monotonic monotonic + %0 = extractvalue { i16, i1 } %pair0, 0 + ret i16 %0 + +; ALL-LABEL: AtomicCmpSwap16Unsigned: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(z) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(z)( + +; ALL: addiu $[[R1:[0-9]+]], $zero, -4 +; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] +; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 +; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 +; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 2 +; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 +; ALL: ori $[[R6:[0-9]+]], $zero, 65535 +; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] +; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] +; ALL: andi $[[R9:[0-9]+]], $4, 65535 +; ALL: sllv $[[R10:[0-9]+]], $[[R9]], $[[R5]] +; ALL: andi $[[R11:[0-9]+]], $5, 65535 +; ALL: sllv $[[R12:[0-9]+]], $[[R11]], $[[R5]] + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R13:[0-9]+]], 0($[[R2]]) +; ALL: and $[[R14:[0-9]+]], $[[R13]], $[[R7]] +; ALL: 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]] + +; ALL: $[[BB1]]: +; ALL: srlv $[[R17:[0-9]+]], $[[R14]], $[[R5]] + +; ALL-NOT: sll $[[R18:[0-9]+]], $[[R17]], 16 +; ALL-NOT: sra $2, $[[R18]], 16 + +; ALL-NOT: seb $2, $[[R17]] +} +; Check one signed i16 so that we cover the seh sign extend case define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind { entry: %0 = atomicrmw add i16* @z, i16 %incr monotonic