diff options
| author | Andrew Lenharth <andrewl@lenharth.org> | 2008-03-01 21:52:34 +0000 | 
|---|---|---|
| committer | Andrew Lenharth <andrewl@lenharth.org> | 2008-03-01 21:52:34 +0000 | 
| commit | d032c33300fd6915e59f06a478f3d38ace39957a (patch) | |
| tree | aeb6b07d442844c0697770ae3968db5180557752 /llvm/lib | |
| parent | 36c00f834a21ca912a8e1c636f80a9bfaa387546 (diff) | |
| download | bcm5719-llvm-d032c33300fd6915e59f06a478f3d38ace39957a.tar.gz bcm5719-llvm-d032c33300fd6915e59f06a478f3d38ace39957a.zip  | |
all but CAS working on x86
llvm-svn: 47798
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 27 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 28 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.h | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 57 | 
4 files changed, 70 insertions, 46 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index bd9e2302fb6..c28c2f9236d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1165,23 +1165,24 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {      assert(((Node->getNumOperands() == 4 && Node->getOpcode() == ISD::ATOMIC_LCS) ||              (Node->getNumOperands() == 3 && Node->getOpcode() == ISD::ATOMIC_LAS) ||              (Node->getNumOperands() == 3 && Node->getOpcode() == ISD::ATOMIC_SWAP)) && -           "Invalid MemBarrier node!"); +           "Invalid Atomic node!");      int num = Node->getOpcode() == ISD::ATOMIC_LCS ? 4 : 3; -    MVT::ValueType VT = Node->getValueType(0); -    switch (TLI.getOperationAction(ISD::ATOMIC_LCS, VT)) { +    SDOperand Ops[4]; +    for (int x = 0; x < num; ++x) +      Ops[x] = LegalizeOp(Node->getOperand(x)); +    Result = DAG.UpdateNodeOperands(Result, &Ops[0], num); +     +    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {      default: assert(0 && "This action is not supported yet!"); -    case TargetLowering::Legal: { -      SDOperand Ops[4]; -      for (int x = 0; x < num; ++x) -        Ops[x] = LegalizeOp(Node->getOperand(x)); -      Result = DAG.UpdateNodeOperands(Result, &Ops[0], num); -      AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0)); -      AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); -      return Result.getValue(Op.ResNo); +    case TargetLowering::Custom: +      Result = TLI.LowerOperation(Result, DAG); +      break; +    case TargetLowering::Legal:        break;      } -    } -    break; +    AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0)); +    AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); +    return Result.getValue(Op.ResNo);    }    case ISD::Constant: { diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 8acf779676e..4cb94916138 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -283,6 +283,9 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)    if (!Subtarget->hasSSE2())      setOperationAction(ISD::MEMBARRIER    , MVT::Other, Expand); +  setOperationAction(ISD::ATOMIC_LCS     , MVT::i8, Custom); +  setOperationAction(ISD::ATOMIC_LCS     , MVT::i16, Custom); +  setOperationAction(ISD::ATOMIC_LCS     , MVT::i32, Custom);    // Use the default ISD::LOCATION, ISD::DECLARE expansion.    setOperationAction(ISD::LOCATION, MVT::Other, Expand); @@ -5345,11 +5348,35 @@ SDOperand X86TargetLowering::LowerCTTZ(SDOperand Op, SelectionDAG &DAG) {    return Op;  } +SDOperand X86TargetLowering::LowerCAS(SDOperand Op, SelectionDAG &DAG) { +  MVT::ValueType T = cast<AtomicSDNode>(Op.Val)->getVT(); +  unsigned Reg; +  unsigned size; +  switch(T) { +  case MVT::i8:  Reg = X86::AL;  size = 1; break; +  case MVT::i16: Reg = X86::AX;  size = 2; break; +  case MVT::i32: Reg = X86::EAX; size = 4; break; +  }; +  SDOperand cpIn = DAG.getCopyToReg(Op.getOperand(0), Reg, +                                    Op.getOperand(2), SDOperand()); +  SDOperand Ops[] = { cpIn.getValue(0), +                       Op.getOperand(1), +                       Op.getOperand(3), +                       DAG.getTargetConstant(size, MVT::i8), +                       cpIn.getValue(1) }; +  SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); +  SDOperand Result = DAG.getNode(X86ISD::LCMPXCHG_DAG, Tys, Ops, 5); +  SDOperand cpOut =  +    DAG.getCopyFromReg(Result.getValue(0), Reg, T, Result.getValue(1)); +  return cpOut; +} +  /// LowerOperation - Provide custom lowering hooks for some operations.  ///  SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {    switch (Op.getOpcode()) {    default: assert(0 && "Should not custom lower this!"); +  case ISD::ATOMIC_LCS:         return LowerCAS(Op,DAG);    case ISD::BUILD_VECTOR:       return LowerBUILD_VECTOR(Op, DAG);    case ISD::VECTOR_SHUFFLE:     return LowerVECTOR_SHUFFLE(Op, DAG);    case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG); @@ -5454,6 +5481,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {    case X86ISD::EH_RETURN:          return "X86ISD::EH_RETURN";    case X86ISD::TC_RETURN:          return "X86ISD::TC_RETURN";    case X86ISD::FNSTCW16m:          return "X86ISD::FNSTCW16m"; +  case X86ISD::LCMPXCHG_DAG:       return "x86ISD::LCMPXCHG_DAG";    }  } diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 5e8a32f5a6e..345aa01e211 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -208,6 +208,9 @@ namespace llvm {        //   operand #3 optional in flag        TC_RETURN, +      // compare and swap +      LCMPXCHG_DAG, +        // Store FP control world into i16 memory        FNSTCW16m      }; @@ -540,6 +543,7 @@ namespace llvm {      SDOperand LowerFLT_ROUNDS_(SDOperand Op, SelectionDAG &DAG);      SDOperand LowerCTLZ(SDOperand Op, SelectionDAG &DAG);      SDOperand LowerCTTZ(SDOperand Op, SelectionDAG &DAG); +    SDOperand LowerCAS(SDOperand Op, SelectionDAG &DAG);      SDNode *ExpandFP_TO_SINT(SDNode *N, SelectionDAG &DAG);      SDNode *ExpandREADCYCLECOUNTER(SDNode *N, SelectionDAG &DAG);    }; diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 87a001af89c..a109dc64887 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -35,6 +35,9 @@ def SDTX86SetCC   : SDTypeProfile<1, 2,                                    [SDTCisVT<0, i8>,                                     SDTCisVT<1, i8>, SDTCisVT<2, i32>]>; +def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>,  +                                     SDTCisVT<2, i8>]>; +  def SDTX86Ret     : SDTypeProfile<0, 1, [SDTCisVT<0, i16>]>;  def SDT_X86CallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; @@ -69,6 +72,10 @@ def X86brcond  : SDNode<"X86ISD::BRCOND",   SDTX86BrCond,                          [SDNPHasChain]>;  def X86setcc   : SDNode<"X86ISD::SETCC",    SDTX86SetCC>; +def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas, +                        [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore, +                         SDNPMayLoad]>; +  def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,                          [SDNPHasChain, SDNPOptInFlag]>; @@ -2539,28 +2546,29 @@ def EH_RETURN   : I<0xC3, RawFrm, (outs), (ins GR32:$addr),  // Atomic support  // -//FIXME: Please check the format - -let Defs = [EAX], Uses = [EAX] in { -def CMPXCHG32 : I<0xB1, Pseudo, (outs), (ins GR32:$ptr, GR32:$swap), -               "cmpxchgl $swap,($ptr)", []>, TB; -def LCMPXCHG32 : I<0xB1, Pseudo, (outs), (ins GR32:$ptr, GR32:$swap), -               "lock cmpxchgl $swap,($ptr)", []>, TB, LOCK; +//FIXME: Please check the format Pseudo is certainly wrong, but the opcode and +//       prefixes should be correct +let Defs = [EAX, EFLAGS], Uses = [EAX] in { +def CMPXCHG32 : I<0xB1, Pseudo, (outs), (ins i32mem:$ptr, GR32:$swap), +               "cmpxchgl $swap,$ptr", []>, TB; +def LCMPXCHG32 : I<0xB1, Pseudo, (outs), (ins i32mem:$ptr, GR32:$swap), +               "lock cmpxchgl $swap,$ptr", [(X86cas addr:$ptr, GR32:$swap, 4)]>, TB, LOCK;  } -let Defs = [AX], Uses = [AX] in { -def CMPXCHG16 : I<0xB1, Pseudo, (outs), (ins GR32:$ptr, GR16:$swap), + +let Defs = [AX, EFLAGS], Uses = [AX] in { +def CMPXCHG16 : I<0xB1, Pseudo, (outs), (ins i16mem:$ptr, GR16:$swap),                 "cmpxchgw $swap,($ptr)", []>, TB, OpSize; -def LCMPXCHG16 : I<0xB1, Pseudo, (outs), (ins GR32:$ptr, GR16:$swap), -               "cmpxchgw $swap,($ptr)", []>, TB, OpSize, LOCK; +def LCMPXCHG16 : I<0xB1, Pseudo, (outs), (ins i16mem:$ptr, GR16:$swap), +               "lock cmpxchgw $swap,$ptr", [(X86cas addr:$ptr, GR16:$swap, 2)]>, TB, OpSize, LOCK;  } -let Defs = [AL], Uses = [AL] in { -def CMPXCHG8 : I<0xB0, Pseudo, (outs), (ins GR32:$ptr, GR8:$swap), +let Defs = [AL, EFLAGS], Uses = [AL] in { +def CMPXCHG8 : I<0xB0, Pseudo, (outs), (ins i8mem:$ptr, GR8:$swap),                 "cmpxchgb $swap,($ptr)", []>, TB; -def LCMPXCHG8 : I<0xB0, Pseudo, (outs), (ins GR32:$ptr, GR8:$swap), -               "cmpxchgb $swap,($ptr)", []>, TB, LOCK; +def LCMPXCHG8 : I<0xB0, Pseudo, (outs), (ins i8mem:$ptr, GR8:$swap), +               "lock cmpxchgb $swap,$ptr", [(X86cas addr:$ptr, GR8:$swap, 1)]>, TB, LOCK;  } -let Constraints = "$val = $dst" in { +let Constraints = "$val = $dst", Defs = [EFLAGS] in {  def LXADD32 : I<0xC1, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val),                 "lock xadd $val, $ptr",                  [(set GR32:$dst, (atomic_las_32 addr:$ptr, GR32:$val))]>, @@ -2598,23 +2606,6 @@ def XCHG8  : I<0x86, Pseudo, (outs GR8:$dst), (ins i8mem:$ptr, GR8:$val),                 "lock xchg $val, $ptr", []>;  } -//FIXME: these are a hack until the patterns using the LCMPXCHG written -let Defs = [EAX], Uses = [EAX] in -def PLCMPXCHG32 : I<0, Pseudo, (outs GR32:$dst),  -                  (ins i32mem:$ptr, GR32:$cmp, GR32:$swap), -                  "movl $cmp, %eax \n lock \n cmpxchgl $swap,$ptr \n movl %eax, $dst", -                  [(set GR32:$dst, (atomic_lcs_32 addr:$ptr, GR32:$cmp, GR32:$swap))]>; -let Defs = [AX] in -def PLCMPXCHG16 : I<0, Pseudo, (outs GR16:$dst),  -                  (ins i16mem:$ptr, GR16:$cmp, GR16:$swap), -                  "movw $cmp, %ax \n lock \n cmpxchgw $swap,$ptr \n movw %ax, $dst", -                  [(set GR16:$dst, (atomic_lcs_16 addr:$ptr, GR16:$cmp, GR16:$swap))]>; -let Defs = [AL] in -def PLCMPXCHG8 : I<0, Pseudo, (outs GR8:$dst),  -                  (ins i8mem:$ptr, GR8:$cmp, GR8:$swap), -                  "movb $cmp, %al \n lock cmpxchgb $swap,$ptr \n movb %al, $dst", -                  [(set GR8:$dst, (atomic_lcs_8 addr:$ptr, GR8:$cmp, GR8:$swap))]>; -  //===----------------------------------------------------------------------===//  // Non-Instruction Patterns  //===----------------------------------------------------------------------===//  | 

