diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 54 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrCompiler.td | 2 | 
2 files changed, 51 insertions, 5 deletions
| diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index d63af3c76a1..13f7cdace4a 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -189,7 +189,7 @@ namespace {      SDNode *Select(SDNode *N);      SDNode *SelectAtomic64(SDNode *Node, unsigned Opc);      SDNode *SelectAtomicLoadAdd(SDNode *Node, EVT NVT); -    SDNode *SelectAtomicLoadOr(SDNode *Node, EVT NVT); +    SDNode *SelectAtomicLoadArith(SDNode *Node, EVT NVT);      bool MatchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM);      bool MatchWrapper(SDValue N, X86ISelAddressMode &AM); @@ -1484,6 +1484,8 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) {  enum AtomicOpc {    OR, +  AND, +  XOR,    AtomicOpcEnd  }; @@ -1515,10 +1517,36 @@ static const unsigned int AtomicOpcTbl[AtomicOpcEnd][AtomicSzEnd] = {      X86::LOCK_OR64mi8,      X86::LOCK_OR64mi32,      X86::LOCK_OR64mr +  }, +  { +    X86::LOCK_AND8mi, +    X86::LOCK_AND8mr, +    X86::LOCK_AND16mi8, +    X86::LOCK_AND16mi, +    X86::LOCK_AND16mr, +    X86::LOCK_AND32mi8, +    X86::LOCK_AND32mi, +    X86::LOCK_AND32mr, +    X86::LOCK_AND64mi8, +    X86::LOCK_AND64mi32, +    X86::LOCK_AND64mr +  }, +  { +    X86::LOCK_XOR8mi, +    X86::LOCK_XOR8mr, +    X86::LOCK_XOR16mi8, +    X86::LOCK_XOR16mi, +    X86::LOCK_XOR16mr, +    X86::LOCK_XOR32mi8, +    X86::LOCK_XOR32mi, +    X86::LOCK_XOR32mr, +    X86::LOCK_XOR64mi8, +    X86::LOCK_XOR64mi32, +    X86::LOCK_XOR64mr    }  }; -SDNode *X86DAGToDAGISel::SelectAtomicLoadOr(SDNode *Node, EVT NVT) { +SDNode *X86DAGToDAGISel::SelectAtomicLoadArith(SDNode *Node, EVT NVT) {    if (Node->hasAnyUseOfValue(0))      return 0; @@ -1533,6 +1561,22 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadOr(SDNode *Node, EVT NVT) {    if (!SelectAddr(Node, Ptr, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))      return 0; +  // Which index into the table. +  enum AtomicOpc Op; +  switch (Node->getOpcode()) { +    case ISD::ATOMIC_LOAD_OR: +      Op = OR; +      break; +    case ISD::ATOMIC_LOAD_AND: +      Op = AND; +      break; +    case ISD::ATOMIC_LOAD_XOR: +      Op = XOR; +      break; +    default: +      return 0; +  } +      bool isCN = false;    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val);    if (CN) { @@ -1540,8 +1584,6 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadOr(SDNode *Node, EVT NVT) {      Val = CurDAG->getTargetConstant(CN->getSExtValue(), NVT);    } -  // Which index into the table. -  enum AtomicOpc Op = OR;      unsigned Opc = 0;    switch (NVT.getSimpleVT().SimpleTy) {      default: return 0; @@ -1693,8 +1735,10 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) {        return RetVal;      break;    } +  case ISD::ATOMIC_LOAD_XOR: +  case ISD::ATOMIC_LOAD_AND:    case ISD::ATOMIC_LOAD_OR: { -    SDNode *RetVal = SelectAtomicLoadOr(Node, NVT); +    SDNode *RetVal = SelectAtomicLoadArith(Node, NVT);      if (RetVal)        return RetVal;      break; diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index 31b33ab83a3..998dfcccf2e 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -630,6 +630,8 @@ def #NAME#64mi8 : RIi8<{ImmOpc8{7}, ImmOpc8{6}, ImmOpc8{5}, ImmOpc8{4},  defm LOCK_ADD : LOCK_ArithBinOp<0x00, 0x80, 0x83, MRM0m, "add">;  defm LOCK_SUB : LOCK_ArithBinOp<0x28, 0x80, 0x83, MRM5m, "sub">;  defm LOCK_OR  : LOCK_ArithBinOp<0x08, 0x80, 0x83, MRM1m, "or">; +defm LOCK_AND : LOCK_ArithBinOp<0x08, 0x80, 0x83, MRM4m, "and">; +defm LOCK_XOR : LOCK_ArithBinOp<0x08, 0x80, 0x83, MRM6m, "xor">;  // Optimized codegen when the non-memory output is not used.  let Defs = [EFLAGS], mayLoad = 1, mayStore = 1, isCodeGenOnly = 1 in { | 

