diff options
author | Chris Lattner <sabre@nondot.org> | 2006-01-30 06:14:02 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-01-30 06:14:02 +0000 |
commit | 9072c05cd8b1739244d8c669fb92c3415d01dccc (patch) | |
tree | bc8977ebc960696f8ceafb6da12f91f134c14fae /lib/Target/Sparc | |
parent | d7e9f30a22059fb8ad4bacf2771c39ae9845afaf (diff) |
Compile:
uint %test(uint %X) {
%Y = call uint %llvm.ctpop.i32(uint %X)
ret uint %Y
}
to:
test:
save -96, %o6, %o6
sll %i0, 0, %l0
popc %l0, %i0
restore %g0, %g0, %g0
retl
nop
instead of to 40 logical ops. Note the shift-by-zero that clears the top
part of the 64-bit V9 register.
Testcase here: CodeGen/SparcV8/ctpop.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25814 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r-- | lib/Target/Sparc/SparcISelDAGToDAG.cpp | 35 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstrInfo.td | 8 |
2 files changed, 27 insertions, 16 deletions
diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index 9718801a8a..d9423e224d 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -33,21 +33,20 @@ using namespace llvm; namespace V8ISD { enum { FIRST_NUMBER = ISD::BUILTIN_OP_END+V8::INSTRUCTION_LIST_END, - CMPICC, // Compare two GPR operands, set icc. - CMPFCC, // Compare two FP operands, set fcc. - BRICC, // Branch to dest on icc condition - BRFCC, // Branch to dest on fcc condition + CMPICC, // Compare two GPR operands, set icc. + CMPFCC, // Compare two FP operands, set fcc. + BRICC, // Branch to dest on icc condition + 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. - Hi, Lo, // Hi/Lo operations, typically on a global address. + Hi, Lo, // Hi/Lo operations, typically on a global address. - FTOI, // FP to Int within a FP register. - ITOF, // Int to FP within a FP register. - - SELECT_ICC, // Select between two values using the current ICC flags. - SELECT_FCC, // Select between two values using the current FCC flags. - - CALL, // A V8 call instruction. - RET_FLAG, // Return with a flag operand. + FTOI, // FP to Int within a FP register. + ITOF, // Int to FP within a FP register. + + CALL, // A V8 call instruction. + RET_FLAG, // Return with a flag operand. }; } @@ -173,10 +172,14 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) setOperationAction(ISD::VAEND , MVT::Other, Expand); setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); - setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); + setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); setStackPointerRegisterToSaveRestore(V8::O6); + if (TM.getSubtarget<SparcV8Subtarget>().isV9()) { + setOperationAction(ISD::CTPOP, MVT::i32, Legal); + } + computeRegisterProperties(); } @@ -187,12 +190,12 @@ const char *SparcV8TargetLowering::getTargetNodeName(unsigned Opcode) const { case V8ISD::CMPFCC: return "V8ISD::CMPFCC"; case V8ISD::BRICC: return "V8ISD::BRICC"; case V8ISD::BRFCC: return "V8ISD::BRFCC"; + case V8ISD::SELECT_ICC: return "V8ISD::SELECT_ICC"; + case V8ISD::SELECT_FCC: return "V8ISD::SELECT_FCC"; case V8ISD::Hi: return "V8ISD::Hi"; case V8ISD::Lo: return "V8ISD::Lo"; case V8ISD::FTOI: return "V8ISD::FTOI"; case V8ISD::ITOF: return "V8ISD::ITOF"; - case V8ISD::SELECT_ICC: return "V8ISD::SELECT_ICC"; - case V8ISD::SELECT_FCC: return "V8ISD::SELECT_FCC"; case V8ISD::CALL: return "V8ISD::CALL"; case V8ISD::RET_FLAG: return "V8ISD::RET_FLAG"; } diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index bf8d6f4ec0..abdbbcc6c0 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -764,6 +764,14 @@ let Predicates = [HasV9] in { [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>; } +// POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear +// the top 32-bits before using it. To do this clearing, we use a SLLri X,0. +def POPCrr : F3_1<2, 0b101110, + (ops IntRegs:$dst, IntRegs:$src), + "popc $src, $dst", []>, Requires<[HasV9]>; +def : Pat<(ctpop IntRegs:$src), + (POPCrr (SLLri IntRegs:$src, 0))>; + //===----------------------------------------------------------------------===// // Non-Instruction Patterns //===----------------------------------------------------------------------===// |