From 0851b4f3eda110cc21c8d4b59f0d55bc84d9d088 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 15 Nov 2006 19:55:13 +0000 Subject: [PATCH] fix ldu/stu jit encoding. Swith 64-bit preinc load instrs to use memri addrmodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31757 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 55 +++++++++++++------------- lib/Target/PowerPC/PPCISelLowering.cpp | 25 ++++++++---- lib/Target/PowerPC/PPCInstr64Bit.td | 28 ++++++------- lib/Target/PowerPC/PPCInstrInfo.td | 2 +- 4 files changed, 58 insertions(+), 52 deletions(-) diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 1edfb5d249c..3ee5d12a820 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -828,36 +828,37 @@ SDNode *PPCDAGToDAGISel::Select(SDOperand Op) { if (LD->getAddressingMode() != ISD::PRE_INC) break; - unsigned Opcode; - bool isSExt = LD->getExtensionType() == ISD::SEXTLOAD; - if (LD->getValueType(0) != MVT::i64) { - // Handle PPC32 integer and normal FP loads. - 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::i1: - case MVT::i8: Opcode = PPC::LBZU; break; - } - } else { - assert(LD->getValueType(0) == MVT::i64 && "Unknown load result type!"); - assert(!isSExt || LoadedVT == MVT::i16 && "Invalid sext update load"); - switch (LoadedVT) { - default: assert(0 && "Invalid PPC load type!"); - case MVT::i64: Opcode = PPC::LDU; break; - case MVT::i32: Opcode = PPC::LWZU8; break; - case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8; break; - case MVT::i1: - case MVT::i8: Opcode = PPC::LBZU8; break; - } - } - SDOperand Offset = LD->getOffset(); if (isa(Offset) || Offset.getOpcode() == ISD::TargetGlobalAddress) { + + unsigned Opcode; + bool isSExt = LD->getExtensionType() == ISD::SEXTLOAD; + if (LD->getValueType(0) != MVT::i64) { + // Handle PPC32 integer and normal FP loads. + 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::i1: + case MVT::i8: Opcode = PPC::LBZU; break; + } + } else { + assert(LD->getValueType(0) == MVT::i64 && "Unknown load result type!"); + assert(!isSExt || LoadedVT == MVT::i16 && "Invalid sext update load"); + switch (LoadedVT) { + default: assert(0 && "Invalid PPC load type!"); + case MVT::i64: Opcode = PPC::LDU; break; + case MVT::i32: Opcode = PPC::LWZU8; break; + case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8; break; + case MVT::i1: + case MVT::i8: Opcode = PPC::LBZU8; break; + } + } + SDOperand Chain = LD->getChain(); SDOperand Base = LD->getBasePtr(); AddToISelQueue(Chain); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index e2419298b56..ae8240caae9 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -877,12 +877,12 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDOperand &Base, MVT::ValueType VT; if (LoadSDNode *LD = dyn_cast(N)) { Ptr = LD->getBasePtr(); - VT = LD->getValueType(0); + VT = LD->getLoadedVT(); + } else if (StoreSDNode *ST = dyn_cast(N)) { ST = ST; Ptr = ST->getBasePtr(); VT = ST->getStoredVT(); - return false; // TODO: Stores. } else return false; @@ -890,18 +890,27 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDOperand &Base, if (MVT::isVector(VT)) return false; - // TODO: Handle reg+reg. - if (!SelectAddressRegImm(Ptr, Offset, Base, DAG)) - return false; + // TODO: Check reg+reg first. + + // LDU/STU use reg+imm*4, others use reg+imm. + if (VT != MVT::i64) { + // reg + imm + if (!SelectAddressRegImm(Ptr, Offset, Base, DAG)) + return false; + } else { + // reg + imm * 4. + if (!SelectAddressRegImmShift(Ptr, Offset, Base, DAG)) + return false; + } - // PPC64 doesn't have lwau, but it does have lwaux. Reject preinc load of - // sext i32 to i64 when addr mode is r+i. if (LoadSDNode *LD = dyn_cast(N)) { + // PPC64 doesn't have lwau, but it does have lwaux. Reject preinc load of + // sext i32 to i64 when addr mode is r+i. if (LD->getValueType(0) == MVT::i64 && LD->getLoadedVT() == MVT::i32 && LD->getExtensionType() == ISD::SEXTLOAD && isa(Offset)) return false; - } + } AM = ISD::PRE_INC; return true; diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index 3a590f25ecb..0e3fa905bfe 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -322,18 +322,15 @@ def LWZX8 : XForm_1<31, 23, (ops G8RC:$rD, memrr:$src), // Update forms. -def LBZU8 : DForm_1<35, (ops G8RC:$rD, ptr_rc:$rA_result, symbolLo:$disp, - ptr_rc:$rA), - "lbzu $rD, $disp($rA)", LdStGeneral, - []>, RegConstraint<"$rA = $rA_result">; -def LHZU8 : DForm_1<41, (ops G8RC:$rD, ptr_rc:$rA_result, symbolLo:$disp, - ptr_rc:$rA), - "lhzu $rD, $disp($rA)", LdStGeneral, - []>, RegConstraint<"$rA = $rA_result">; -def LWZU8 : DForm_1<33, (ops G8RC:$rD, ptr_rc:$rA_result, symbolLo:$disp, - ptr_rc:$rA), - "lwzu $rD, $disp($rA)", LdStGeneral, - []>, RegConstraint<"$rA = $rA_result">; +def LBZU8 : DForm_1<35, (ops G8RC:$rD, ptr_rc:$ea_result, memri:$addr), + "lbzu $rD, $addr", LdStGeneral, + []>, RegConstraint<"$addr.reg = $ea_result">; +def LHZU8 : DForm_1<41, (ops G8RC:$rD, ptr_rc:$ea_result, memri:$addr), + "lhzu $rD, $addr", LdStGeneral, + []>, RegConstraint<"$addr.reg = $ea_result">; +def LWZU8 : DForm_1<33, (ops G8RC:$rD, ptr_rc:$ea_result, memri:$addr), + "lwzu $rD, $addr", LdStGeneral, + []>, RegConstraint<"$addr.reg = $ea_result">; } @@ -347,10 +344,9 @@ def LDX : XForm_1<31, 21, (ops G8RC:$rD, memrr:$src), "ldx $rD, $src", LdStLD, [(set G8RC:$rD, (load xaddr:$src))]>, isPPC64; -def LDU : DSForm_1<58, 1, (ops G8RC:$rD, ptr_rc:$rA_result, symbolLo:$disp, - ptr_rc:$rA), - "ldu $rD, $disp($rA)", LdStLD, - []>, RegConstraint<"$rA = $rA_result">, isPPC64; +def LDU : DSForm_1<58, 1, (ops G8RC:$rD, ptr_rc:$ea_result, memrix:$addr), + "ldu $rD, $addr", LdStLD, + []>, RegConstraint<"$addr.reg = $ea_result">, isPPC64; } diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 4c1f0dca4e8..480d587cfc2 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -255,7 +255,7 @@ def memrr : Operand { } def memrix : Operand { // memri where the imm is shifted 2 bits. let PrintMethod = "printMemRegImmShifted"; - let MIOperandInfo = (ops i32imm, ptr_rc); + let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg); } // PowerPC Predicate operand. 20 = (0<<5)|20 = always, CR0 is a dummy reg -- 2.34.1