mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-27 04:18:42 +00:00
Fix X86 codegen for 'atomicrmw nand' to generate *x = ~(*x & y), not *x = ~*x & y.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154705 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
1 parent
3423132f2e
commit
42fc29e717
3 files changed
+48
-27
No files matched your search
@@ -11298,14 +11298,15 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
|
||||
unsigned notOpc,
|
||||
unsigned EAXreg,
|
||||
const TargetRegisterClass *RC,
|
||||
bool invSrc) const {
|
||||
bool Invert) const {
|
||||
// For the atomic bitwise operator, we generate
|
||||
// thisMBB:
|
||||
// newMBB:
|
||||
// ld t1 = [bitinstr.addr]
|
||||
// op t2 = t1, [bitinstr.val]
|
||||
// not t3 = t2 (if Invert)
|
||||
// mov EAX = t1
|
||||
// lcs dest = [bitinstr.addr], t2 [EAX is implicit]
|
||||
// lcs dest = [bitinstr.addr], t3 [EAX is implicit]
|
||||
// bz newMBB
|
||||
// fallthrough -->nextMBB
|
||||
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
|
||||
@@ -11353,13 +11354,6 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
|
||||
for (int i=0; i <= lastAddrIndx; ++i)
|
||||
(*MIB).addOperand(*argOpers[i]);
|
||||
|
||||
unsigned tt = F->getRegInfo().createVirtualRegister(RC);
|
||||
if (invSrc) {
|
||||
MIB = BuildMI(newMBB, dl, TII->get(notOpc), tt).addReg(t1);
|
||||
}
|
||||
else
|
||||
tt = t1;
|
||||
|
||||
unsigned t2 = F->getRegInfo().createVirtualRegister(RC);
|
||||
assert((argOpers[valArgIndx]->isReg() ||
|
||||
argOpers[valArgIndx]->isImm()) &&
|
||||
@@ -11368,16 +11362,23 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
|
||||
MIB = BuildMI(newMBB, dl, TII->get(regOpc), t2);
|
||||
else
|
||||
MIB = BuildMI(newMBB, dl, TII->get(immOpc), t2);
|
||||
MIB.addReg(tt);
|
||||
MIB.addReg(t1);
|
||||
(*MIB).addOperand(*argOpers[valArgIndx]);
|
||||
|
||||
unsigned t3 = F->getRegInfo().createVirtualRegister(RC);
|
||||
if (Invert) {
|
||||
MIB = BuildMI(newMBB, dl, TII->get(notOpc), t3).addReg(t2);
|
||||
}
|
||||
else
|
||||
t3 = t2;
|
||||
|
||||
MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), EAXreg);
|
||||
MIB.addReg(t1);
|
||||
MIB.addReg(t3);
|
||||
|
||||
MIB = BuildMI(newMBB, dl, TII->get(CXchgOpc));
|
||||
for (int i=0; i <= lastAddrIndx; ++i)
|
||||
(*MIB).addOperand(*argOpers[i]);
|
||||
MIB.addReg(t2);
|
||||
MIB.addReg(t3);
|
||||
assert(bInstr->hasOneMemOperand() && "Unexpected number of memoperand");
|
||||
(*MIB).setMemRefs(bInstr->memoperands_begin(),
|
||||
bInstr->memoperands_end());
|
||||
@@ -11400,7 +11401,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr,
|
||||
unsigned regOpcH,
|
||||
unsigned immOpcL,
|
||||
unsigned immOpcH,
|
||||
bool invSrc) const {
|
||||
bool Invert) const {
|
||||
// For the atomic bitwise operator, we generate
|
||||
// thisMBB (instructions are in pairs, except cmpxchg8b)
|
||||
// ld t1,t2 = [bitinstr.addr]
|
||||
@@ -11408,6 +11409,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr,
|
||||
// out1, out2 = phi (thisMBB, t1/t2) (newMBB, t3/t4)
|
||||
// op t5, t6 <- out1, out2, [bitinstr.val]
|
||||
// (for SWAP, substitute: mov t5, t6 <- [bitinstr.val])
|
||||
// neg t7, t8 < t5, t6 (if Invert)
|
||||
// mov ECX, EBX <- t5, t6
|
||||
// mov EAX, EDX <- t1, t2
|
||||
// cmpxchg8b [bitinstr.addr] [EAX, EDX, EBX, ECX implicit]
|
||||
@@ -11491,16 +11493,9 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr,
|
||||
.addReg(t2).addMBB(thisMBB).addReg(t4).addMBB(newMBB);
|
||||
|
||||
// The subsequent operations should be using the destination registers of
|
||||
//the PHI instructions.
|
||||
if (invSrc) {
|
||||
t1 = F->getRegInfo().createVirtualRegister(RC);
|
||||
t2 = F->getRegInfo().createVirtualRegister(RC);
|
||||
MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t1).addReg(dest1Oper.getReg());
|
||||
MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t2).addReg(dest2Oper.getReg());
|
||||
} else {
|
||||
t1 = dest1Oper.getReg();
|
||||
t2 = dest2Oper.getReg();
|
||||
}
|
||||
// the PHI instructions.
|
||||
t1 = dest1Oper.getReg();
|
||||
t2 = dest2Oper.getReg();
|
||||
|
||||
int valArgIndx = lastAddrIndx + 1;
|
||||
assert((argOpers[valArgIndx]->isReg() ||
|
||||
@@ -11527,15 +11522,26 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr,
|
||||
MIB.addReg(t2);
|
||||
(*MIB).addOperand(*argOpers[valArgIndx + 1]);
|
||||
|
||||
unsigned t7, t8;
|
||||
if (Invert) {
|
||||
t7 = F->getRegInfo().createVirtualRegister(RC);
|
||||
t8 = F->getRegInfo().createVirtualRegister(RC);
|
||||
MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t7).addReg(t5);
|
||||
MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t8).addReg(t6);
|
||||
} else {
|
||||
t7 = t5;
|
||||
t8 = t6;
|
||||
}
|
||||
|
||||
MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::EAX);
|
||||
MIB.addReg(t1);
|
||||
MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::EDX);
|
||||
MIB.addReg(t2);
|
||||
|
||||
MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::EBX);
|
||||
MIB.addReg(t5);
|
||||
MIB.addReg(t7);
|
||||
MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::ECX);
|
||||
MIB.addReg(t6);
|
||||
MIB.addReg(t8);
|
||||
|
||||
MIB = BuildMI(newMBB, dl, TII->get(X86::LCMPXCHG8B));
|
||||
for (int i=0; i <= lastAddrIndx; ++i)
|
||||
|
||||
@@ -855,7 +855,7 @@ namespace llvm {
|
||||
unsigned notOpc,
|
||||
unsigned EAXreg,
|
||||
const TargetRegisterClass *RC,
|
||||
bool invSrc = false) const;
|
||||
bool Invert = false) const;
|
||||
|
||||
MachineBasicBlock *EmitAtomicBit6432WithCustomInserter(
|
||||
MachineInstr *BInstr,
|
||||
@@ -864,7 +864,7 @@ namespace llvm {
|
||||
unsigned regOpcH,
|
||||
unsigned immOpcL,
|
||||
unsigned immOpcH,
|
||||
bool invSrc = false) const;
|
||||
bool Invert = false) const;
|
||||
|
||||
/// Utility function to emit atomic min and max. It takes the min/max
|
||||
/// instruction to expand, the associated basic block, and the associated
|
||||
|
||||
@@ -13,6 +13,7 @@ entry:
|
||||
%xort = alloca i32 ; <i32*> [#uses=2]
|
||||
%old = alloca i32 ; <i32*> [#uses=18]
|
||||
%temp = alloca i32 ; <i32*> [#uses=2]
|
||||
%temp64 = alloca i64
|
||||
store i32 %argc, i32* %argc.addr
|
||||
store i8** %argv, i8*** %argv.addr
|
||||
store i32 0, i32* %val1
|
||||
@@ -106,6 +107,20 @@ entry:
|
||||
; CHECK: cmpxchgl
|
||||
%17 = cmpxchg i32* %val2, i32 1976, i32 1 monotonic
|
||||
store i32 %17, i32* %old
|
||||
; CHECK: andl
|
||||
; CHECK: notl
|
||||
; CHECK: lock
|
||||
; CHECK: cmpxchgl
|
||||
%18 = atomicrmw nand i32* %val2, i32 1401 monotonic
|
||||
store i32 %18, i32* %old
|
||||
; CHECK: andl
|
||||
; CHECK: andl
|
||||
; CHECK: notl
|
||||
; CHECK: notl
|
||||
; CHECK: lock
|
||||
; CHECK: cmpxchg8b
|
||||
%19 = atomicrmw nand i64* %temp64, i64 17361641481138401520 monotonic
|
||||
store i64 %19, i64* %temp64
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user