diff options
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcISelLowering.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcISelLowering.h | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcInstr64Bit.td | 21 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcInstrInfo.td | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcRegisterInfo.td | 2 | 
5 files changed, 34 insertions, 5 deletions
| diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 789ef0c0721..a9ce75a7eb8 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -824,6 +824,10 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)    setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);    setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); +  if (Subtarget->is64Bit()) { +    setOperationAction(ISD::BR_CC, MVT::i64, Custom); +  } +    // FIXME: There are instructions available for ATOMIC_FENCE    // on SparcV8 and later.    setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); @@ -893,6 +897,7 @@ const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {    case SPISD::CMPICC:     return "SPISD::CMPICC";    case SPISD::CMPFCC:     return "SPISD::CMPFCC";    case SPISD::BRICC:      return "SPISD::BRICC"; +  case SPISD::BRXCC:      return "SPISD::BRXCC";    case SPISD::BRFCC:      return "SPISD::BRFCC";    case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC";    case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC"; @@ -1029,12 +1034,13 @@ static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) {    // Get the condition flag.    SDValue CompareFlag; -  if (LHS.getValueType() == MVT::i32) { -    EVT VTs[] = { MVT::i32, MVT::Glue }; +  if (LHS.getValueType().isInteger()) { +    EVT VTs[] = { LHS.getValueType(), MVT::Glue };      SDValue Ops[2] = { LHS, RHS };      CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1);      if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); -    Opc = SPISD::BRICC; +    // 32-bit compares use the icc flags, 64-bit uses the xcc flags. +    Opc = LHS.getValueType() == MVT::i32 ? SPISD::BRICC : SPISD::BRXCC;    } else {      CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS);      if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h index 08e6f211bf3..274673cd4da 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.h +++ b/llvm/lib/Target/Sparc/SparcISelLowering.h @@ -24,9 +24,10 @@ namespace llvm {    namespace SPISD {      enum {        FIRST_NUMBER = ISD::BUILTIN_OP_END, -      CMPICC,      // Compare two GPR operands, set icc. +      CMPICC,      // Compare two GPR operands, set icc+xcc.        CMPFCC,      // Compare two FP operands, set fcc.        BRICC,       // Branch to dest on icc condition +      BRXCC,       // Branch to dest on xcc condition (64-bit only).        BRFCC,       // Branch to dest on fcc condition        SELECT_ICC,  // Select between two values using the current ICC flags.        SELECT_FCC,  // Select between two values using the current FCC flags. diff --git a/llvm/lib/Target/Sparc/SparcInstr64Bit.td b/llvm/lib/Target/Sparc/SparcInstr64Bit.td index e7c505c8546..a726b358a10 100644 --- a/llvm/lib/Target/Sparc/SparcInstr64Bit.td +++ b/llvm/lib/Target/Sparc/SparcInstr64Bit.td @@ -161,6 +161,8 @@ def : Pat<(sube i64:$a, i64:$b), (SUBXrr $a, $b)>;  def : Pat<(addc i64:$a, i64:$b), (ADDCCrr $a, $b)>;  def : Pat<(subc i64:$a, i64:$b), (SUBCCrr $a, $b)>; +def : Pat<(SPcmpicc i64:$a, i64:$b), (SUBCCrr $a, $b)>; +  // Register-immediate instructions.  def : Pat<(and i64:$a, (i64 simm13:$b)), (ANDri $a, (as_i32imm $b))>; @@ -170,6 +172,8 @@ def : Pat<(xor i64:$a, (i64 simm13:$b)), (XORri $a, (as_i32imm $b))>;  def : Pat<(add i64:$a, (i64 simm13:$b)), (ADDri $a, (as_i32imm $b))>;  def : Pat<(sub i64:$a, (i64 simm13:$b)), (SUBri $a, (as_i32imm $b))>; +def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (SUBCCri $a, (as_i32imm $b))>; +  } // Predicates = [Is64Bit] @@ -239,3 +243,20 @@ def : Pat<(truncstorei32 i64:$src, ADDRrr:$addr), (STrr  ADDRrr:$addr, $src)>;  def : Pat<(truncstorei32 i64:$src, ADDRri:$addr), (STri  ADDRri:$addr, $src)>;  } // Predicates = [Is64Bit] + + +//===----------------------------------------------------------------------===// +// 64-bit Conditionals. +//===----------------------------------------------------------------------===// +// +// Flag-setting instructions like subcc and addcc set both icc and xcc flags. +// The icc flags correspond to the 32-bit result, and the xcc are for the +// full 64-bit result. +// +// We reuse CMPICC SDNodes for compares, but use new BRXCC branch nodes for +// 64-bit compares. See LowerBR_CC. + +let Uses = [ICC] in +def BPXCC : BranchSP<0, (ins brtarget:$dst, CCOp:$cc), +                     "bp$cc %xcc, $dst", +                     [(SPbrxcc bb:$dst, imm:$cc)]>; diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td index b5a02780fb8..c2453fa04b5 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -104,6 +104,7 @@ SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;  def SPcmpicc : SDNode<"SPISD::CMPICC", SDTIntBinOp, [SDNPOutGlue]>;  def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>;  def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; +def SPbrxcc : SDNode<"SPISD::BRXCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;  def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;  def SPhi    : SDNode<"SPISD::Hi", SDTIntUnaryOp>; diff --git a/llvm/lib/Target/Sparc/SparcRegisterInfo.td b/llvm/lib/Target/Sparc/SparcRegisterInfo.td index e8ccd20af8b..497e7c5d561 100644 --- a/llvm/lib/Target/Sparc/SparcRegisterInfo.td +++ b/llvm/lib/Target/Sparc/SparcRegisterInfo.td @@ -43,7 +43,7 @@ class Rd<bits<5> num, string n, list<Register> subregs> : SparcReg<n> {  }  // Control Registers -def ICC : SparcCtrlReg<"ICC">; +def ICC : SparcCtrlReg<"ICC">; // This represents icc and xcc in 64-bit code.  def FCC : SparcCtrlReg<"FCC">;  // Y register | 

