diff options
author | Jim Laskey <jlaskey@mac.com> | 2006-12-12 13:23:43 +0000 |
---|---|---|
committer | Jim Laskey <jlaskey@mac.com> | 2006-12-12 13:23:43 +0000 |
commit | 78f97f3118c0d7fbebf4084e24689c596d5e4fb7 (patch) | |
tree | d2fc1d4dbb6ee9e6cdd958fb42be7d2206768200 /lib/Target/PowerPC/PPCISelDAGToDAG.cpp | |
parent | 17212df0ee5b6a1d5b3afe8913eed845b59b72e2 (diff) | |
download | llvm-78f97f3118c0d7fbebf4084e24689c596d5e4fb7.tar.gz llvm-78f97f3118c0d7fbebf4084e24689c596d5e4fb7.tar.bz2 llvm-78f97f3118c0d7fbebf4084e24689c596d5e4fb7.tar.xz |
Reduce number of instructions to load 64-bit constants.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32481 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCISelDAGToDAG.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index d45c255d66..08cceecb5b 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -766,6 +766,81 @@ SDNode *PPCDAGToDAGISel::Select(SDOperand Op) { switch (N->getOpcode()) { default: break; + + case ISD::Constant: { + if (N->getValueType(0) == MVT::i64) { + // Get 64 bit value. + int64_t Imm = cast<ConstantSDNode>(N)->getValue(); + // Assume no remaining bits. + unsigned Remainder = 0; + // Assume no shift required. + unsigned Shift = 0; + + // If it can't be represented as a 32 bit value. + if (!isInt32(Imm)) { + Shift = CountTrailingZeros_64(Imm); + int64_t ImmSh = static_cast<uint64_t>(Imm) >> Shift; + + // If the shifted value fits 32 bits. + if (isInt32(ImmSh)) { + // Go with the shifted value. + Imm = ImmSh; + } else { + // Still stuck with a 64 bit value. + Remainder = Imm; + Shift = 32; + Imm >>= 32; + } + } + + // Intermediate operand. + SDNode *Result; + + // Handle first 32 bits. + unsigned Lo = Imm & 0xFFFF; + unsigned Hi = (Imm >> 16) & 0xFFFF; + + // Simple value. + if (isInt16(Imm)) { + // Just the Lo bits. + Result = CurDAG->getTargetNode(PPC::LI8, MVT::i64, getI32Imm(Lo)); + } else if (Lo) { + // Handle the Hi bits. + unsigned OpC = Hi ? PPC::LIS8 : PPC::LI8; + Result = CurDAG->getTargetNode(OpC, MVT::i64, getI32Imm(Hi)); + // And Lo bits. + Result = CurDAG->getTargetNode(PPC::ORI8, MVT::i64, + SDOperand(Result, 0), getI32Imm(Lo)); + } else { + // Just the Hi bits. + Result = CurDAG->getTargetNode(PPC::LIS8, MVT::i64, getI32Imm(Hi)); + } + + // If no shift, we're done. + if (!Shift) return Result; + + // Shift for next step if the upper 32-bits were not zero. + if (Imm) { + Result = CurDAG->getTargetNode(PPC::RLDICR, MVT::i64, + SDOperand(Result, 0), + getI32Imm(Shift), getI32Imm(63 - Shift)); + } + + // Add in the last bits as required. + if ((Hi = (Remainder >> 16) & 0xFFFF)) { + Result = CurDAG->getTargetNode(PPC::ORIS8, MVT::i64, + SDOperand(Result, 0), getI32Imm(Hi)); + } + if ((Lo = Remainder & 0xFFFF)) { + Result = CurDAG->getTargetNode(PPC::ORI8, MVT::i64, + SDOperand(Result, 0), getI32Imm(Lo)); + } + + return Result; + } + break; + } + case ISD::SETCC: return SelectSETCC(Op); case PPCISD::GlobalBaseReg: |