aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86')
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp19
-rw-r--r--lib/Target/X86/X86ISelLowering.h3
-rw-r--r--lib/Target/X86/X86InstrInfo.td26
3 files changed, 20 insertions, 28 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 53f42b9c0d..11442b5fa5 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -5963,7 +5963,8 @@ MachineBasicBlock *
X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
MachineBasicBlock *MBB,
unsigned regOpc,
- unsigned immOpc) {
+ unsigned immOpc,
+ bool invSrc) {
// For the atomic bitwise operator, we generate
// thisMBB:
// newMBB:
@@ -6012,7 +6013,14 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
MachineInstrBuilder MIB = BuildMI(newMBB, TII->get(X86::MOV32rm), t1);
for (int i=0; i <= lastAddrIndx; ++i)
(*MIB).addOperand(*argOpers[i]);
-
+
+ unsigned tt = F->getRegInfo().createVirtualRegister(X86::GR32RegisterClass);
+ if (invSrc) {
+ MIB = BuildMI(newMBB, TII->get(X86::NOT32r), tt).addReg(t1);
+ }
+ else
+ tt = t1;
+
unsigned t2 = F->getRegInfo().createVirtualRegister(X86::GR32RegisterClass);
assert( (argOpers[valArgIndx]->isReg() || argOpers[valArgIndx]->isImm())
&& "invalid operand");
@@ -6020,9 +6028,9 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
MIB = BuildMI(newMBB, TII->get(regOpc), t2);
else
MIB = BuildMI(newMBB, TII->get(immOpc), t2);
- MIB.addReg(t1);
+ MIB.addReg(tt);
(*MIB).addOperand(*argOpers[valArgIndx]);
-
+
MIB = BuildMI(newMBB, TII->get(X86::MOV32rr), X86::EAX);
MIB.addReg(t1);
@@ -6286,6 +6294,9 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
case X86::ATOMXOR32:
return EmitAtomicBitwiseWithCustomInserter(MI, BB, X86::XOR32rr,
X86::XOR32ri);
+ case X86::ATOMNAND32:
+ return EmitAtomicBitwiseWithCustomInserter(MI, BB, X86::AND32rr,
+ X86::AND32ri, true);
case X86::ATOMMIN32:
return EmitAtomicMinMaxWithCustomInserter(MI, BB, X86::CMOVL32rr);
case X86::ATOMMAX32:
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index c7a43a47a6..f2b851e66e 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -567,7 +567,8 @@ namespace llvm {
MachineInstr *BInstr,
MachineBasicBlock *BB,
unsigned regOpc,
- unsigned immOpc);
+ unsigned immOpc,
+ bool invSrc = false);
/// Utility function to emit atomic min and max. It takes the min/max
// instruction to expand, the associated basic block, and the associated
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 4b8dc100b9..2630834b6a 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -2633,45 +2633,25 @@ let Constraints = "$val = $dst", Defs = [EFLAGS],
def ATOMAND32 : I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
"#ATOMAND32 PSUEDO!",
[(set GR32:$dst, (atomic_load_and addr:$ptr, GR32:$val))]>;
-}
-
-let Constraints = "$val = $dst", Defs = [EFLAGS],
- usesCustomDAGSchedInserter = 1 in {
def ATOMOR32 : I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
"#ATOMOR32 PSUEDO!",
[(set GR32:$dst, (atomic_load_or addr:$ptr, GR32:$val))]>;
-}
-
-let Constraints = "$val = $dst", Defs = [EFLAGS],
- usesCustomDAGSchedInserter = 1 in {
def ATOMXOR32 : I<0, Pseudo,(outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
"#ATOMXOR32 PSUEDO!",
[(set GR32:$dst, (atomic_load_xor addr:$ptr, GR32:$val))]>;
-}
+def ATOMNAND32 : I<0, Pseudo,(outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
+ "#ATOMXOR32 PSUEDO!",
+ [(set GR32:$dst, (atomic_load_nand addr:$ptr, GR32:$val))]>;
-let Constraints = "$val = $dst", Defs = [EFLAGS],
- usesCustomDAGSchedInserter = 1 in {
def ATOMMIN32: I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val),
"#ATOMMIN32 PSUEDO!",
[(set GR32:$dst, (atomic_load_min addr:$ptr, GR32:$val))]>;
-}
-
-let Constraints = "$val = $dst", Defs = [EFLAGS],
- usesCustomDAGSchedInserter = 1 in {
def ATOMMAX32: I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
"#ATOMMAX32 PSUEDO!",
[(set GR32:$dst, (atomic_load_max addr:$ptr, GR32:$val))]>;
-}
-
-let Constraints = "$val = $dst", Defs = [EFLAGS],
- usesCustomDAGSchedInserter = 1 in {
def ATOMUMIN32: I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
"#ATOMUMIN32 PSUEDO!",
[(set GR32:$dst, (atomic_load_umin addr:$ptr, GR32:$val))]>;
-}
-
-let Constraints = "$val = $dst", Defs = [EFLAGS],
- usesCustomDAGSchedInserter = 1 in {
def ATOMUMAX32: I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
"#ATOMUMAX32 PSUEDO!",
[(set GR32:$dst, (atomic_load_umax addr:$ptr, GR32:$val))]>;