[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp PPCCodeEmitter.cpp PPCISelDAGToDAG.cpp PPCISelPattern.cpp PPCInstrInfo.td
Nate Begeman
natebegeman at mac.com
Tue Nov 15 16:48:20 PST 2005
Changes in directory llvm/lib/Target/PowerPC:
PPCAsmPrinter.cpp updated: 1.109 -> 1.110
PPCCodeEmitter.cpp updated: 1.40 -> 1.41
PPCISelDAGToDAG.cpp updated: 1.125 -> 1.126
PPCISelPattern.cpp updated: 1.191 -> 1.192
PPCInstrInfo.td updated: 1.138 -> 1.139
---
Log message:
Patch to clean up function call pseudos and support the BLA instruction,
which branches to an absolute address. This is required to support objc
direct dispatch.
---
Diffs of the changes: (+31 -20)
PPCAsmPrinter.cpp | 4 ++++
PPCCodeEmitter.cpp | 2 +-
PPCISelDAGToDAG.cpp | 23 +++++++++++++++++------
PPCISelPattern.cpp | 9 +++------
PPCInstrInfo.td | 13 ++++++-------
5 files changed, 31 insertions(+), 20 deletions(-)
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.109 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.110
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.109 Mon Nov 14 19:45:01 2005
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Tue Nov 15 18:48:01 2005
@@ -152,6 +152,10 @@
TM.getInstrInfo()->isCall(MI->getOpcode()));
}
}
+ void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo,
+ MVT::ValueType VT) {
+ O << (int)MI->getOperand(OpNo).getImmedValue()*4;
+ }
void printPICLabel(const MachineInstr *MI, unsigned OpNo,
MVT::ValueType VT) {
// FIXME: should probably be converted to cout.width and cout.fill
Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp
diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.40 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.41
--- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.40 Sun Oct 16 00:39:50 2005
+++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Tue Nov 15 18:48:01 2005
@@ -196,7 +196,7 @@
MO.getGlobal()->hasWeakLinkage() ||
MO.getGlobal()->isExternal();
unsigned Reloc = 0;
- if (MI.getOpcode() == PPC::CALLpcrel)
+ if (MI.getOpcode() == PPC::BL)
Reloc = PPC::reloc_pcrel_bx;
else {
switch (MI.getOpcode()) {
Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.125 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.126
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.125 Fri Oct 28 17:58:07 2005
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Tue Nov 15 18:48:01 2005
@@ -735,6 +735,14 @@
return SDOperand(N, 0);
}
+/// isCallCompatibleAddress - Return true if the specified 32-bit value is
+/// representable in the immediate field of a Bx instruction.
+static bool isCallCompatibleAddress(ConstantSDNode *C) {
+ int Addr = C->getValue();
+ if (Addr & 3) return false; // Low 2 bits are implicitly zero.
+ return (Addr << 6 >> 6) == Addr; // Top 6 bits have to be sext of immediate.
+}
+
SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
SDNode *N = Op.Val;
SDOperand Chain = Select(N->getOperand(0));
@@ -744,13 +752,18 @@
if (GlobalAddressSDNode *GASD =
dyn_cast<GlobalAddressSDNode>(N->getOperand(1))) {
- CallOpcode = PPC::CALLpcrel;
+ CallOpcode = PPC::BL;
CallOperands.push_back(CurDAG->getTargetGlobalAddress(GASD->getGlobal(),
MVT::i32));
} else if (ExternalSymbolSDNode *ESSDN =
dyn_cast<ExternalSymbolSDNode>(N->getOperand(1))) {
- CallOpcode = PPC::CALLpcrel;
+ CallOpcode = PPC::BL;
CallOperands.push_back(N->getOperand(1));
+ } else if (isa<ConstantSDNode>(N->getOperand(1)) &&
+ isCallCompatibleAddress(cast<ConstantSDNode>(N->getOperand(1)))) {
+ ConstantSDNode *C = cast<ConstantSDNode>(N->getOperand(1));
+ CallOpcode = PPC::BLA;
+ CallOperands.push_back(getI32Imm((int)C->getValue() >> 2));
} else {
// Copy the callee address into the CTR register.
SDOperand Callee = Select(N->getOperand(1));
@@ -759,11 +772,9 @@
// Copy the callee address into R12 on darwin.
SDOperand R12 = CurDAG->getRegister(PPC::R12, MVT::i32);
Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R12, Callee);
-
- CallOperands.push_back(getI32Imm(20)); // Information to encode indcall
- CallOperands.push_back(getI32Imm(0)); // Information to encode indcall
+
CallOperands.push_back(R12);
- CallOpcode = PPC::CALLindirect;
+ CallOpcode = PPC::BCTRL;
}
unsigned GPR_idx = 0, FPR_idx = 0;
Index: llvm/lib/Target/PowerPC/PPCISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.191 llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.192
--- llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.191 Wed Oct 19 21:15:44 2005
+++ llvm/lib/Target/PowerPC/PPCISelPattern.cpp Tue Nov 15 18:48:01 2005
@@ -842,18 +842,15 @@
// Emit the correct call instruction based on the type of symbol called.
if (GlobalAddressSDNode *GASD =
dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) {
- CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(),
- true);
+ CallMI = BuildMI(PPC::BL, 1).addGlobalAddress(GASD->getGlobal(), true);
} else if (ExternalSymbolSDNode *ESSDN =
dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) {
- CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(),
- true);
+ CallMI = BuildMI(PPC::BL, 1).addExternalSymbol(ESSDN->getSymbol(), true);
} else {
Tmp1 = SelectExpr(N.getOperand(1));
BuildMI(BB, PPC::MTCTR, 1).addReg(Tmp1);
BuildMI(BB, PPC::OR4, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1);
- CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0)
- .addReg(PPC::R12);
+ CallMI = BuildMI(PPC::BCTRL, 1).addReg(PPC::R12);
}
// Load the register args to virtual regs
Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.138 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.139
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.138 Fri Oct 28 15:32:44 2005
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Tue Nov 15 18:48:01 2005
@@ -128,6 +128,9 @@
def target : Operand<i32> {
let PrintMethod = "printBranchOperand";
}
+def aaddr : Operand<i32> {
+ let PrintMethod = "printAbsAddrOperand";
+}
def piclabel: Operand<i32> {
let PrintMethod = "printPICLabel";
}
@@ -186,9 +189,6 @@
target:$true, target:$false),
"; COND_BRANCH", []>;
def B : IForm<18, 0, 0, (ops target:$func), "b $func", BrB>;
-//def BA : IForm<18, 1, 0, (ops target:$func), "ba $func", BrB>;
- def BL : IForm<18, 0, 1, (ops target:$func), "bl $func", BrB>;
-//def BLA : IForm<18, 1, 1, (ops target:$func), "bla $func", BrB>;
// FIXME: 4*CR# needs to be added to the BI field!
// This will only work for CR0 as it stands now
@@ -217,10 +217,9 @@
LR,CTR,
CR0,CR1,CR5,CR6,CR7] in {
// Convenient aliases for call instructions
- def CALLpcrel : IForm<18, 0, 1, (ops target:$func, variable_ops),
- "bl $func", BrB>;
- def CALLindirect : XLForm_2_ext<19, 528, 20, 0, 1,
- (ops variable_ops), "bctrl", BrB>;
+ def BL : IForm<18, 0, 1, (ops target:$func, variable_ops), "bl $func", BrB>;
+ def BLA : IForm<18, 1, 1, (ops aaddr:$func, variable_ops), "bla $func", BrB>;
+ def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops variable_ops), "bctrl", BrB>;
}
// D-Form instructions. Most instructions that perform an operation on a
More information about the llvm-commits
mailing list