forked from OSchip/llvm-project
Reduce number of instructions to load 64-bit constants.
llvm-svn: 32481
This commit is contained in:
parent
13bc5d7b57
commit
095e6f3044
|
@ -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:
|
||||
|
|
|
@ -474,48 +474,6 @@ def FCTIDZ : XForm_26<63, 815, (ops F8RC:$frD, F8RC:$frB),
|
|||
// Instruction Patterns
|
||||
//
|
||||
|
||||
// Immediate support.
|
||||
// Handled above:
|
||||
// sext(0x0000_0000_0000_FFFF, i8) -> li imm
|
||||
// sext(0x0000_0000_FFFF_0000, i16) -> lis imm>>16
|
||||
|
||||
// sext(0x0000_0000_FFFF_FFFF, i16) -> lis + ori
|
||||
def sext_0x0000_0000_FFFF_FFFF_i16 : PatLeaf<(imm), [{
|
||||
return N->getValue() == (uint64_t)(int32_t)N->getValue();
|
||||
}]>;
|
||||
def : Pat<(i64 sext_0x0000_0000_FFFF_FFFF_i16:$imm),
|
||||
(ORI8 (LIS8 (HI16 imm:$imm)), (LO16 imm:$imm))>;
|
||||
|
||||
// zext(0x0000_0000_FFFF_7FFF, i16) -> oris (li lo16(imm)), imm>>16
|
||||
def zext_0x0000_0000_FFFF_7FFF_i16 : PatLeaf<(imm), [{
|
||||
return (N->getValue() & 0xFFFFFFFF00008000ULL) == 0;
|
||||
}]>;
|
||||
def : Pat<(i64 zext_0x0000_0000_FFFF_7FFF_i16:$imm),
|
||||
(ORIS8 (LI8 (LO16 imm:$imm)), (HI16 imm:$imm))>;
|
||||
|
||||
// zext(0x0000_0000_FFFF_FFFF, i16) -> oris (ori (li 0), lo16(imm)), imm>>16
|
||||
def zext_0x0000_0000_FFFF_FFFF_i16 : PatLeaf<(imm), [{
|
||||
return (N->getValue() & 0xFFFFFFFF00000000ULL) == 0;
|
||||
}]>;
|
||||
def : Pat<(i64 zext_0x0000_0000_FFFF_FFFF_i16:$imm),
|
||||
(ORIS8 (ORI8 (LI8 0), (LO16 imm:$imm)), (HI16 imm:$imm))>;
|
||||
|
||||
// FIXME: Handle smart forms where the top 32-bits are set. Right now, stuff
|
||||
// like 0xABCD0123BCDE0000 hits the case below, which produces ORI R, R, 0's!
|
||||
|
||||
// Fully general (and most expensive: 6 instructions!) immediate pattern.
|
||||
def : Pat<(i64 imm:$imm),
|
||||
(ORI8
|
||||
(ORIS8
|
||||
(RLDICR
|
||||
(ORI8
|
||||
(LIS8 (HI48_64 imm:$imm)),
|
||||
(HI32_48 imm:$imm)),
|
||||
32, 31),
|
||||
(HI16 imm:$imm)),
|
||||
(LO16 imm:$imm))>;
|
||||
|
||||
|
||||
// Extensions and truncates to/from 32-bit regs.
|
||||
def : Pat<(i64 (zext GPRC:$in)),
|
||||
(RLDICL (OR4To8 GPRC:$in, GPRC:$in), 0, 32)>;
|
||||
|
|
Loading…
Reference in New Issue