diff options
author | Chris Lattner <sabre@nondot.org> | 2007-02-17 06:57:26 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-02-17 06:57:26 +0000 |
commit | dee5a5a52c45d04aa9f64a7b6e2adae37878a304 (patch) | |
tree | 7c6ae95cfef4b9964d87bbbde5fac75a66c60338 | |
parent | 0f74372ebfd468fa39421b7cc56f0e84a55ac9f3 (diff) |
Fix ixaddrs as well, allowing ppc64 to compile to:
_test2:
li r2, 0
lis r3, 1
std r2, 9024(r3)
blr
instead of:
_test2:
lis r2, 1
li r3, 0
ori r2, r2, 9024
std r3, 0(r2)
blr
This implements CodeGen/PowerPC/LargeAbsoluteAddr.ll:test2
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34373 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 56f5d11f95..f8c970e88d 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -841,25 +841,30 @@ bool PPCTargetLowering::SelectAddressRegImmShift(SDOperand N, SDOperand &Disp, } } } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) { - // Loading from a constant address. - - // If this address fits entirely in a 14-bit sext immediate field, codegen - // this as "d, 0" - short Imm; - if (isIntS16Immediate(CN, Imm)) { - Disp = DAG.getTargetConstant((unsigned short)Imm >> 2, getPointerTy()); - Base = DAG.getRegister(PPC::R0, CN->getValueType(0)); - return true; - } + // Loading from a constant address. Verify low two bits are clear. + if ((CN->getValue() & 3) == 0) { + // If this address fits entirely in a 14-bit sext immediate field, codegen + // this as "d, 0" + short Imm; + if (isIntS16Immediate(CN, Imm)) { + Disp = DAG.getTargetConstant((unsigned short)Imm >> 2, getPointerTy()); + Base = DAG.getRegister(PPC::R0, CN->getValueType(0)); + return true; + } - // FIXME: Handle small sext constant offsets in PPC64 mode also! - if (CN->getValueType(0) == MVT::i32) { - int Addr = (int)CN->getValue(); + // Fold the low-part of 32-bit absolute addresses into addr mode. + if (CN->getValueType(0) == MVT::i32 || + (int64_t)CN->getValue() == (int)CN->getValue()) { + int Addr = (int)CN->getValue(); - // Otherwise, break this down into an LIS + disp. - Disp = DAG.getTargetConstant((short)Addr >> 2, MVT::i32); - Base = DAG.getConstant(Addr - (signed short)Addr, MVT::i32); - return true; + // Otherwise, break this down into an LIS + disp. + Disp = DAG.getTargetConstant((short)Addr >> 2, MVT::i32); + + Base = DAG.getTargetConstant((Addr-(signed short)Addr) >> 16, MVT::i32); + unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8; + Base = SDOperand(DAG.getTargetNode(Opc, CN->getValueType(0), Base), 0); + return true; + } } } |