diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2013-04-03 04:41:44 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2013-04-03 04:41:44 +0000 |
commit | 8534e9998c53efae49e4555ba394f39808fb83e0 (patch) | |
tree | 1bd8ac4c1e69663722c552a7692b4640924c3377 /lib/Target/Sparc | |
parent | 2d8f62017d6223444564f79fc8044cc35d9d5678 (diff) |
Add 64-bit compare + branch for SPARC v9.
The same compare instruction is used for 32-bit and 64-bit compares. It
sets two different sets of flags: icc and xcc.
This patch adds a conditional branch instruction using the xcc flags for
64-bit compares.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178621 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r-- | lib/Target/Sparc/SparcISelLowering.cpp | 12 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcISelLowering.h | 3 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstr64Bit.td | 21 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstrInfo.td | 1 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcRegisterInfo.td | 2 |
5 files changed, 34 insertions, 5 deletions
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index 789ef0c072..a9ce75a7eb 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/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/lib/Target/Sparc/SparcISelLowering.h b/lib/Target/Sparc/SparcISelLowering.h index 08e6f211bf..274673cd4d 100644 --- a/lib/Target/Sparc/SparcISelLowering.h +++ b/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/lib/Target/Sparc/SparcInstr64Bit.td b/lib/Target/Sparc/SparcInstr64Bit.td index e7c505c854..a726b358a1 100644 --- a/lib/Target/Sparc/SparcInstr64Bit.td +++ b/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/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index b5a02780fb..c2453fa04b 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/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/lib/Target/Sparc/SparcRegisterInfo.td b/lib/Target/Sparc/SparcRegisterInfo.td index e8ccd20af8..497e7c5d56 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.td +++ b/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 |