diff options
-rw-r--r-- | lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 38 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 27 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.td | 45 |
3 files changed, 88 insertions, 22 deletions
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index aad579f659..91811a842f 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -818,6 +818,44 @@ SDNode *PPCDAGToDAGISel::Select(SDOperand Op) { // Other cases are autogenerated. break; } + + case ISD::LOAD: { + // Handle preincrement loads. + LoadSDNode *LD = cast<LoadSDNode>(Op); + MVT::ValueType LoadedVT = LD->getLoadedVT(); + + // Normal loads are handled by code generated from the .td file. + if (LD->getAddressingMode() != ISD::PRE_INC) + break; + + unsigned Opcode; + bool isSExt = LD->getExtensionType() == ISD::SEXTLOAD; + assert(!isSExt || LoadedVT == MVT::i16 && "Invalid sext update load"); + switch (LoadedVT) { + default: assert(0 && "Invalid PPC load type!"); + case MVT::f64: Opcode = PPC::LFDU; break; + case MVT::f32: Opcode = PPC::LFSU; break; + case MVT::i32: Opcode = PPC::LWZU; break; + case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU; break; + case MVT::i8: Opcode = PPC::LBZU; break; + } + + SDOperand Offset = LD->getOffset(); + if (isa<ConstantSDNode>(Offset)) { + SDOperand Chain = LD->getChain(); + SDOperand Base = LD->getBasePtr(); + AddToISelQueue(Chain); + AddToISelQueue(Base); + AddToISelQueue(Offset); + SDOperand Ops[] = { Offset, Base, Chain }; + // FIXME: PPC64 + return CurDAG->getTargetNode(Opcode, MVT::i32, MVT::i32, + MVT::Other, Ops, 3); + } else { + assert(0 && "R+R preindex loads not supported yet!"); + } + } + case ISD::AND: { unsigned Imm, Imm2, SH, MB, ME; diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index a748238217..3ad4bbcc57 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -26,8 +26,11 @@ #include "llvm/Intrinsics.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/Support/CommandLine.h" using namespace llvm; +static cl::opt<bool> EnablePPCPreinc("enable-ppc-preinc"); + PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) : TargetLowering(TM), PPCSubTarget(*TM.getSubtargetImpl()) { @@ -861,29 +864,27 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDOperand &Base, SDOperand &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) { - return false; + // Disabled by default for now. + if (!EnablePPCPreinc) return false; -#if 0 - MVT::ValueType VT; SDOperand Ptr; if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { Ptr = LD->getBasePtr(); - VT = LD->getLoadedVT(); - - // TODO: handle other cases. - if (VT != MVT::i32) return false; } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) { - Ptr = ST->getBasePtr(); - VT = ST->getStoredVT(); - // TODO: handle other cases. + ST = ST; + //Ptr = ST->getBasePtr(); + //VT = ST->getStoredVT(); + // TODO: handle stores. return false; } else return false; + // TODO: Handle reg+reg. + if (!SelectAddressRegImm(Ptr, Offset, Base, DAG)) + return false; - - return false; -#endif + AM = ISD::PRE_INC; + return true; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index cfe103de87..21035bedc2 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -422,9 +422,44 @@ def LWZ : DForm_1<32, (ops GPRC:$rD, memri:$src), "lwz $rD, $src", LdStGeneral, [(set GPRC:$rD, (load iaddr:$src))]>; -def LWZU : DForm_1<33, (ops GPRC:$rD, GPRC:$rA_result, i32imm:$disp, GPRC:$rA), +def LFS : DForm_8<48, (ops F4RC:$rD, memri:$src), + "lfs $rD, $src", LdStLFDU, + [(set F4RC:$rD, (load iaddr:$src))]>; +def LFD : DForm_8<50, (ops F8RC:$rD, memri:$src), + "lfd $rD, $src", LdStLFD, + [(set F8RC:$rD, (load iaddr:$src))]>; + +// FIXME: PTRRC for Pointer regs for ppc64. + +// 'Update' load forms. +def LBZU : DForm_1<35, (ops GPRC:$rD, ptr_rc:$rA_result, i32imm:$disp, + ptr_rc:$rA), + "lbzu $rD, $disp($rA)", LdStGeneral, + []>, RegConstraint<"$rA = $rA_result">; + +def LHAU : DForm_1<43, (ops GPRC:$rD, ptr_rc:$rA_result, i32imm:$disp, + ptr_rc:$rA), + "lhau $rD, $disp($rA)", LdStGeneral, + []>, RegConstraint<"$rA = $rA_result">; + +def LHZU : DForm_1<41, (ops GPRC:$rD, ptr_rc:$rA_result, i32imm:$disp, + ptr_rc:$rA), + "lhzu $rD, $disp($rA)", LdStGeneral, + []>, RegConstraint<"$rA = $rA_result">; + +def LWZU : DForm_1<33, (ops GPRC:$rD, ptr_rc:$rA_result, i32imm:$disp, + ptr_rc:$rA), "lwzu $rD, $disp($rA)", LdStGeneral, []>, RegConstraint<"$rA = $rA_result">; + +def LFSU : DForm_8<49, (ops F4RC:$rD, ptr_rc:$rA_result, i32imm:$disp, + ptr_rc:$rA), + "lfs $rD, $disp($rA)", LdStLFDU, + []>, RegConstraint<"$rA = $rA_result">; +def LFDU : DForm_8<51, (ops F8RC:$rD, ptr_rc:$rA_result, i32imm:$disp, + ptr_rc:$rA), + "lfd $rD, $disp($rA)", LdStLFD, + []>, RegConstraint<"$rA = $rA_result">; } @@ -501,14 +536,6 @@ def CMPWI : DForm_5_ext<11, (ops CRRC:$crD, GPRC:$rA, s16imm:$imm), def CMPLWI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2), "cmplwi $dst, $src1, $src2", IntCompare>; } -let isLoad = 1, PPC970_Unit = 2 in { -def LFS : DForm_8<48, (ops F4RC:$rD, memri:$src), - "lfs $rD, $src", LdStLFDU, - [(set F4RC:$rD, (load iaddr:$src))]>; -def LFD : DForm_8<50, (ops F8RC:$rD, memri:$src), - "lfd $rD, $src", LdStLFD, - [(set F8RC:$rD, (load iaddr:$src))]>; -} let isStore = 1, noResults = 1, PPC970_Unit = 2 in { def STFS : DForm_9<52, (ops F4RC:$rS, memri:$dst), "stfs $rS, $dst", LdStUX, |