forked from OSchip/llvm-project
Add support for generating reg+reg (indexed) pre-inc loads on PPC.
llvm-svn: 158823
This commit is contained in:
parent
8a31138521
commit
ca542beffe
|
@ -927,12 +927,44 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
|||
SDValue Chain = LD->getChain();
|
||||
SDValue Base = LD->getBasePtr();
|
||||
SDValue Ops[] = { Offset, Base, Chain };
|
||||
// FIXME: PPC64
|
||||
return CurDAG->getMachineNode(Opcode, dl, LD->getValueType(0),
|
||||
PPCLowering.getPointerTy(),
|
||||
MVT::Other, Ops, 3);
|
||||
} else {
|
||||
llvm_unreachable("R+R preindex loads not supported yet!");
|
||||
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.getSimpleVT().SimpleTy) {
|
||||
default: llvm_unreachable("Invalid PPC load type!");
|
||||
case MVT::f64: Opcode = PPC::LFDUX; break;
|
||||
case MVT::f32: Opcode = PPC::LFSUX; break;
|
||||
case MVT::i32: Opcode = PPC::LWZUX; break;
|
||||
case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX; break;
|
||||
case MVT::i1:
|
||||
case MVT::i8: Opcode = PPC::LBZUX; break;
|
||||
}
|
||||
} else {
|
||||
assert(LD->getValueType(0) == MVT::i64 && "Unknown load result type!");
|
||||
assert((!isSExt || LoadedVT == MVT::i16 || LoadedVT == MVT::i32) &&
|
||||
"Invalid sext update load");
|
||||
switch (LoadedVT.getSimpleVT().SimpleTy) {
|
||||
default: llvm_unreachable("Invalid PPC load type!");
|
||||
case MVT::i64: Opcode = PPC::LDUX; break;
|
||||
case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8; break;
|
||||
case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8; break;
|
||||
case MVT::i1:
|
||||
case MVT::i8: Opcode = PPC::LBZUX8; break;
|
||||
}
|
||||
}
|
||||
|
||||
SDValue Chain = LD->getChain();
|
||||
SDValue Base = LD->getBasePtr();
|
||||
SDValue Ops[] = { Offset, Base, Chain };
|
||||
return CurDAG->getMachineNode(Opcode, dl, LD->getValueType(0),
|
||||
PPCLowering.getPointerTy(),
|
||||
MVT::Other, Ops, 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1106,13 +1106,8 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base,
|
|||
return false;
|
||||
|
||||
if (SelectAddressRegReg(Ptr, Offset, Base, DAG)) {
|
||||
if (isa<StoreSDNode>(N)) {
|
||||
AM = ISD::PRE_INC;
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME: reg+reg preinc loads
|
||||
return false;
|
||||
AM = ISD::PRE_INC;
|
||||
return true;
|
||||
}
|
||||
|
||||
// LDU/STU use reg+imm*4, others use reg+imm.
|
||||
|
|
|
@ -533,6 +533,16 @@ def LHAU8 : DForm_1a<43, (outs G8RC:$rD, ptr_rc:$ea_result), (ins symbolLo:$disp
|
|||
NoEncode<"$ea_result">;
|
||||
// NO LWAU!
|
||||
|
||||
def LHAUX8 : XForm_1<31, 375, (outs G8RC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"lhaux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
def LWAUX : XForm_1<31, 375, (outs G8RC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"lwaux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">, isPPC64;
|
||||
}
|
||||
|
||||
// Zero extending loads.
|
||||
|
@ -572,6 +582,22 @@ def LWZU8 : DForm_1<33, (outs G8RC:$rD, ptr_rc:$ea_result), (ins memri:$addr),
|
|||
"lwzu $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.reg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
|
||||
def LBZUX8 : XForm_1<31, 119, (outs G8RC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"lbzux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
def LHZUX8 : XForm_1<31, 331, (outs G8RC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"lhzux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
def LWZUX8 : XForm_1<31, 55, (outs G8RC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"lwzux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,6 +633,11 @@ def LDU : DSForm_1<58, 1, (outs G8RC:$rD, ptr_rc:$ea_result), (ins memrix:$addr
|
|||
[]>, RegConstraint<"$addr.reg = $ea_result">, isPPC64,
|
||||
NoEncode<"$ea_result">;
|
||||
|
||||
def LDUX : XForm_1<31, 53, (outs G8RC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"ldux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">, isPPC64;
|
||||
}
|
||||
|
||||
def : Pat<(PPCload ixaddr:$src),
|
||||
|
|
|
@ -323,7 +323,7 @@ def memri : Operand<iPTR> {
|
|||
}
|
||||
def memrr : Operand<iPTR> {
|
||||
let PrintMethod = "printMemRegReg";
|
||||
let MIOperandInfo = (ops ptr_rc, ptr_rc);
|
||||
let MIOperandInfo = (ops ptr_rc:$offreg, ptr_rc:$ptrreg);
|
||||
}
|
||||
def memrix : Operand<iPTR> { // memri where the imm is shifted 2 bits.
|
||||
let PrintMethod = "printMemRegImmShifted";
|
||||
|
@ -712,6 +712,44 @@ def LFDU : DForm_1<51, (outs F8RC:$rD, ptr_rc:$ea_result), (ins memri:$addr),
|
|||
"lfd $rD, $addr", LdStLFD,
|
||||
[]>, RegConstraint<"$addr.reg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
|
||||
|
||||
// Indexed (r+r) Loads with Update (preinc).
|
||||
def LBZUX : XForm_1<31, 119, (outs GPRC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"lbzux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
|
||||
def LHAUX : XForm_1<31, 375, (outs GPRC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"lhaux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
|
||||
def LHZUX : XForm_1<31, 331, (outs GPRC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"lhzux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
|
||||
def LWZUX : XForm_1<31, 55, (outs GPRC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"lwzux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
|
||||
def LFSUX : XForm_1<31, 567, (outs F4RC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"lfsux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
|
||||
def LFDUX : XForm_1<31, 631, (outs F8RC:$rD, ptr_rc:$ea_result),
|
||||
(ins memrr:$addr),
|
||||
"lfdux $rD, $addr", LdStLoad,
|
||||
[]>, RegConstraint<"$addr.offreg = $ea_result">,
|
||||
NoEncode<"$ea_result">;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
; RUN: llc < %s | FileCheck %s
|
||||
|
||||
define fastcc void @allocateSpace() nounwind {
|
||||
entry:
|
||||
%0 = load i8** undef, align 8, !tbaa !0
|
||||
br i1 undef, label %return, label %lor.lhs.false
|
||||
|
||||
lor.lhs.false: ; preds = %entry
|
||||
br i1 undef, label %if.end7, label %return
|
||||
|
||||
if.end7: ; preds = %lor.lhs.false
|
||||
br i1 undef, label %if.then15, label %if.end71
|
||||
|
||||
if.then15: ; preds = %if.end7
|
||||
br label %while.cond
|
||||
|
||||
while.cond: ; preds = %while.body, %if.then15
|
||||
%idxprom17 = sext i32 0 to i64
|
||||
%arrayidx18 = getelementptr inbounds i8* %0, i64 %idxprom17
|
||||
%or = or i32 undef, undef
|
||||
br i1 false, label %if.end71, label %while.body
|
||||
|
||||
while.body: ; preds = %while.cond
|
||||
br i1 undef, label %while.cond, label %if.then45
|
||||
|
||||
if.then45: ; preds = %while.body
|
||||
%idxprom48139 = zext i32 %or to i64
|
||||
%arrayidx49 = getelementptr inbounds i8* %0, i64 %idxprom48139
|
||||
%1 = bitcast i8* %arrayidx49 to i16*
|
||||
%2 = bitcast i8* %arrayidx18 to i16*
|
||||
%3 = load i16* %1, align 1
|
||||
store i16 %3, i16* %2, align 1
|
||||
br label %return
|
||||
|
||||
if.end71: ; preds = %while.cond, %if.end7
|
||||
unreachable
|
||||
|
||||
return: ; preds = %if.then45, %lor.lhs.false, %entry
|
||||
ret void
|
||||
|
||||
; CHECK: @allocateSpace
|
||||
; CHECK: lbzux
|
||||
}
|
||||
|
||||
!0 = metadata !{metadata !"any pointer", metadata !1}
|
||||
!1 = metadata !{metadata !"omnipotent char", metadata !2}
|
||||
!2 = metadata !{metadata !"Simple C/C++ TBAA"}
|
Loading…
Reference in New Issue