aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-03-20 22:38:22 +0000
committerChris Lattner <sabre@nondot.org>2006-03-20 22:38:22 +0000
commitd97964457e972cc0c0ae0e293f975112c3d65c46 (patch)
tree1d7b0dab1721bd198bd93c7d3234eb081fa8868b
parent23baa1b3106993bc9e8a5807d8b1f9e486bdf845 (diff)
Handle constant addresses more efficiently, folding the low bits into the
disp field of the load/store if possible. This compiles CodeGen/PowerPC/load-constant-addr.ll to: _test: lis r2, 2838 lfs f1, 26848(r2) blr instead of: _test: lis r2, 2838 ori r2, r2, 26848 lfs f1, 0(r2) blr git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26908 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/PowerPC/PPCISelDAGToDAG.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 61e279c046..bc6573b13c 100644
--- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -535,7 +535,24 @@ bool PPCDAGToDAGISel::SelectAddrImm(SDOperand N, SDOperand &Disp,
return true;
}
}
+ } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
+ // Loading from a constant address.
+ int Addr = (int)CN->getValue();
+
+ // If this address fits entirely in a 16-bit sext immediate field, codegen
+ // this as "d, 0"
+ if (Addr == (short)Addr) {
+ Disp = getI32Imm(Addr);
+ Base = CurDAG->getRegister(PPC::R0, MVT::i32);
+ return true;
+ }
+
+ // Otherwise, break this down into an LIS + disp.
+ Disp = getI32Imm((short)Addr);
+ Base = CurDAG->getConstant(Addr - (signed short)Addr, MVT::i32);
+ return true;
}
+
Disp = getI32Imm(0);
if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N))
Base = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32);