aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-12-24 01:00:15 +0000
committerNate Begeman <natebegeman@mac.com>2005-12-24 01:00:15 +0000
commit50fb3c498601a84e0d82d7bab3e28c820dd64598 (patch)
tree27edc49f3ae49f28b6e5d3886897e45d1c74d8d7
parent443045a816be7d7fdcf4ff8865e22d718d87a7d6 (diff)
Fix one of the things in the todo file, and get a bit closer to folding
constant offsets from statics into the address arithmetic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24999 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/PowerPC/PPCAsmPrinter.cpp1
-rw-r--r--lib/Target/PowerPC/PPCISelDAGToDAG.cpp16
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp5
-rw-r--r--lib/Target/PowerPC/README.txt42
4 files changed, 25 insertions, 39 deletions
diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp
index a5eb9182ee..f75e4aae22 100644
--- a/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -331,6 +331,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
// Computing the address of a global symbol, not calling it.
GlobalValue *GV = MO.getGlobal();
std::string Name = Mang->getValueName(GV);
+ int offset = MO.getOffset();
// External or weakly linked global variables need non-lazily-resolved stubs
if (!PPCGenerateStaticCode) {
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 4d9abdc9a7..47f73abebf 100644
--- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -927,7 +927,7 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
break;
}
case ISD::AND: {
- unsigned Imm;
+ unsigned Imm, Imm2;
// If this is an and of a value rotated between 0 and 31 bits and then and'd
// with a mask, emit rlwinm
if (isIntImmediate(N->getOperand(1), Imm) && (isShiftedMask_32(Imm) ||
@@ -947,6 +947,20 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Val, getI32Imm(SH),
getI32Imm(MB), getI32Imm(ME));
}
+ // ISD::OR doesn't get all the bitfield insertion fun.
+ // (and (or x, c1), c2) where isRunOfOnes(~(c1^c2)) is a bitfield insert
+ if (isIntImmediate(N->getOperand(1), Imm) &&
+ N->getOperand(0).getOpcode() == ISD::OR &&
+ isIntImmediate(N->getOperand(0).getOperand(1), Imm2)) {
+ unsigned SH, MB, ME;
+ Imm = ~(Imm^Imm2);
+ if (isRunOfOnes(Imm, MB, ME)) {
+ SDOperand Tmp1 = Select(N->getOperand(0).getOperand(0));
+ SDOperand Tmp2 = Select(N->getOperand(0).getOperand(1));
+ return CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32, Tmp1, Tmp2,
+ getI32Imm(SH), getI32Imm(MB), getI32Imm(ME));
+ }
+ }
// Other cases are autogenerated.
break;
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 565eb0a025..29507d00e3 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -362,8 +362,9 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
return Lo;
}
case ISD::GlobalAddress: {
- GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
- SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
+ GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
+ GlobalValue *GV = GSDN->getGlobal();
+ SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32, GSDN->getOffset());
SDOperand Zero = DAG.getConstant(0, MVT::i32);
if (PPCGenerateStaticCode) {
diff --git a/lib/Target/PowerPC/README.txt b/lib/Target/PowerPC/README.txt
index 58805562a8..1ba89aa448 100644
--- a/lib/Target/PowerPC/README.txt
+++ b/lib/Target/PowerPC/README.txt
@@ -3,10 +3,15 @@ TODO:
* implement do-loop -> bdnz transform
* implement powerpc-64 for darwin
* use stfiwx in float->int
-* be able to combine sequences like the following into 2 instructions:
+
+* Fold add and sub with constant into non-extern, non-weak addresses so this:
lis r2, ha16(l2__ZTV4Cell)
la r2, lo16(l2__ZTV4Cell)(r2)
addi r2, r2, 8
+becomes:
+ lis r2, ha16(l2__ZTV4Cell+8)
+ la r2, lo16(l2__ZTV4Cell+8)(r2)
+
* Teach LLVM how to codegen this:
unsigned short foo(float a) { return a; }
@@ -24,10 +29,6 @@ _foo:
rlwinm r3, r2, 0, 16, 31
blr
-and:
- extern int X, Y; int* test(int C) { return C? &X : &Y; }
-as one load when using --enable-pic.
-
* Support 'update' load/store instructions. These are cracked on the G5, but
are still a codesize win.
@@ -170,37 +171,6 @@ things like this, rather than forcing llvm to generate the equivalent
===-------------------------------------------------------------------------===
-Compile this (standard bitfield insert of a constant):
-void %test(uint* %tmp1) {
- %tmp2 = load uint* %tmp1 ; <uint> [#uses=1]
- %tmp5 = or uint %tmp2, 257949696 ; <uint> [#uses=1]
- %tmp6 = and uint %tmp5, 4018143231 ; <uint> [#uses=1]
- store uint %tmp6, uint* %tmp1
- ret void
-}
-
-to:
-
-_test:
- lwz r0,0(r3)
- li r2,123
- rlwimi r0,r2,21,3,10
- stw r0,0(r3)
- blr
-
-instead of:
-
-_test:
- lis r2, -4225
- lwz r4, 0(r3)
- ori r2, r2, 65535
- oris r4, r4, 3936
- and r2, r4, r2
- stw r2, 0(r3)
- blr
-
-===-------------------------------------------------------------------------===
-
Compile this:
int %f1(int %a, int %b) {