forked from OSchip/llvm-project
Add support for generating reg+reg preinc stores on PPC.
PPC will now generate STWUX and friends. llvm-svn: 158698
This commit is contained in:
parent
a3fcbeb908
commit
1cc27e44a4
|
@ -368,9 +368,9 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC) ,PPC::R0)
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC) ,PPC::R0)
|
||||||
.addReg(PPC::R0, RegState::Kill)
|
.addReg(PPC::R0, RegState::Kill)
|
||||||
.addImm(NegFrameSize);
|
.addImm(NegFrameSize);
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX))
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX), PPC::R1)
|
||||||
.addReg(PPC::R1, RegState::Kill)
|
.addReg(PPC::R1, RegState::Kill)
|
||||||
.addReg(PPC::R1, RegState::Define)
|
.addReg(PPC::R1)
|
||||||
.addReg(PPC::R0);
|
.addReg(PPC::R0);
|
||||||
} else if (isInt<16>(NegFrameSize)) {
|
} else if (isInt<16>(NegFrameSize)) {
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::STWU), PPC::R1)
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::STWU), PPC::R1)
|
||||||
|
@ -383,9 +383,9 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0)
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0)
|
||||||
.addReg(PPC::R0, RegState::Kill)
|
.addReg(PPC::R0, RegState::Kill)
|
||||||
.addImm(NegFrameSize & 0xFFFF);
|
.addImm(NegFrameSize & 0xFFFF);
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX))
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX), PPC::R1)
|
||||||
.addReg(PPC::R1, RegState::Kill)
|
.addReg(PPC::R1, RegState::Kill)
|
||||||
.addReg(PPC::R1, RegState::Define)
|
.addReg(PPC::R1)
|
||||||
.addReg(PPC::R0);
|
.addReg(PPC::R0);
|
||||||
}
|
}
|
||||||
} else { // PPC64.
|
} else { // PPC64.
|
||||||
|
@ -401,9 +401,9 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC8), PPC::X0)
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC8), PPC::X0)
|
||||||
.addReg(PPC::X0)
|
.addReg(PPC::X0)
|
||||||
.addImm(NegFrameSize);
|
.addImm(NegFrameSize);
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX))
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX), PPC::X1)
|
||||||
.addReg(PPC::X1, RegState::Kill)
|
.addReg(PPC::X1, RegState::Kill)
|
||||||
.addReg(PPC::X1, RegState::Define)
|
.addReg(PPC::X1)
|
||||||
.addReg(PPC::X0);
|
.addReg(PPC::X0);
|
||||||
} else if (isInt<16>(NegFrameSize)) {
|
} else if (isInt<16>(NegFrameSize)) {
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::STDU), PPC::X1)
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::STDU), PPC::X1)
|
||||||
|
@ -416,9 +416,9 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0)
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0)
|
||||||
.addReg(PPC::X0, RegState::Kill)
|
.addReg(PPC::X0, RegState::Kill)
|
||||||
.addImm(NegFrameSize & 0xFFFF);
|
.addImm(NegFrameSize & 0xFFFF);
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX))
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX), PPC::X1)
|
||||||
.addReg(PPC::X1, RegState::Kill)
|
.addReg(PPC::X1, RegState::Kill)
|
||||||
.addReg(PPC::X1, RegState::Define)
|
.addReg(PPC::X1)
|
||||||
.addReg(PPC::X0);
|
.addReg(PPC::X0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,18 @@ namespace {
|
||||||
/// immediate field. Because preinc imms have already been validated, just
|
/// immediate field. Because preinc imms have already been validated, just
|
||||||
/// accept it.
|
/// accept it.
|
||||||
bool SelectAddrImmOffs(SDValue N, SDValue &Out) const {
|
bool SelectAddrImmOffs(SDValue N, SDValue &Out) const {
|
||||||
|
if (isa<ConstantSDNode>(N)) {
|
||||||
|
Out = N;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// SelectAddrIdxOffs - Return true if the operand is valid for a preinc
|
||||||
|
/// index field. Because preinc imms have already been validated, just
|
||||||
|
/// accept it.
|
||||||
|
bool SelectAddrIdxOffs(SDValue N, SDValue &Out) const {
|
||||||
Out = N;
|
Out = N;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1105,7 +1105,15 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base,
|
||||||
if (VT.isVector())
|
if (VT.isVector())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TODO: Check reg+reg first.
|
if (SelectAddressRegReg(Ptr, Offset, Base, DAG)) {
|
||||||
|
if (isa<StoreSDNode>(N)) {
|
||||||
|
AM = ISD::PRE_INC;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: reg+reg preinc loads
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// LDU/STU use reg+imm*4, others use reg+imm.
|
// LDU/STU use reg+imm*4, others use reg+imm.
|
||||||
if (VT != MVT::i64) {
|
if (VT != MVT::i64) {
|
||||||
|
|
|
@ -680,10 +680,41 @@ def STDU : DSForm_1a<62, 1, (outs ptr_rc:$ea_res), (ins G8RC:$rS,
|
||||||
RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">,
|
RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">,
|
||||||
isPPC64;
|
isPPC64;
|
||||||
|
|
||||||
let mayStore = 1 in
|
|
||||||
def STDUX : XForm_8<31, 181, (outs), (ins G8RC:$rS, memrr:$dst),
|
def STBUX8 : XForm_8<31, 247, (outs ptr_rc:$ea_res),
|
||||||
"stdux $rS, $dst", LdStSTD,
|
(ins G8RC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg),
|
||||||
[]>, isPPC64;
|
"stbux $rS, $ptroff, $ptrreg", LdStStore,
|
||||||
|
[(set ptr_rc:$ea_res,
|
||||||
|
(pre_truncsti8 G8RC:$rS,
|
||||||
|
ptr_rc:$ptrreg, xaddroff:$ptroff))]>,
|
||||||
|
RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">,
|
||||||
|
PPC970_DGroup_Cracked;
|
||||||
|
|
||||||
|
def STHUX8 : XForm_8<31, 439, (outs ptr_rc:$ea_res),
|
||||||
|
(ins G8RC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg),
|
||||||
|
"sthux $rS, $ptroff, $ptrreg", LdStStore,
|
||||||
|
[(set ptr_rc:$ea_res,
|
||||||
|
(pre_truncsti16 G8RC:$rS,
|
||||||
|
ptr_rc:$ptrreg, xaddroff:$ptroff))]>,
|
||||||
|
RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">,
|
||||||
|
PPC970_DGroup_Cracked;
|
||||||
|
|
||||||
|
def STWUX8 : XForm_8<31, 183, (outs ptr_rc:$ea_res),
|
||||||
|
(ins G8RC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg),
|
||||||
|
"stwux $rS, $ptroff, $ptrreg", LdStStore,
|
||||||
|
[(set ptr_rc:$ea_res,
|
||||||
|
(pre_truncsti32 G8RC:$rS,
|
||||||
|
ptr_rc:$ptrreg, xaddroff:$ptroff))]>,
|
||||||
|
RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">,
|
||||||
|
PPC970_DGroup_Cracked;
|
||||||
|
|
||||||
|
def STDUX : XForm_8<31, 181, (outs ptr_rc:$ea_res),
|
||||||
|
(ins G8RC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg),
|
||||||
|
"stdux $rS, $ptroff, $ptrreg", LdStStore,
|
||||||
|
[(set ptr_rc:$ea_res,
|
||||||
|
(pre_store G8RC:$rS, ptr_rc:$ptrreg, xaddroff:$ptroff))]>,
|
||||||
|
RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">,
|
||||||
|
PPC970_DGroup_Cracked, isPPC64;
|
||||||
|
|
||||||
// STD_32/STDX_32 - Just like STD/STDX, but uses a '32-bit' input register.
|
// STD_32/STDX_32 - Just like STD/STDX, but uses a '32-bit' input register.
|
||||||
def STD_32 : DSForm_1<62, 0, (outs), (ins GPRC:$rT, memrix:$dst),
|
def STD_32 : DSForm_1<62, 0, (outs), (ins GPRC:$rT, memrix:$dst),
|
||||||
|
|
|
@ -349,6 +349,7 @@ def ixaddr : ComplexPattern<iPTR, 2, "SelectAddrImmShift", [], []>; // "std"
|
||||||
|
|
||||||
/// This is just the offset part of iaddr, used for preinc.
|
/// This is just the offset part of iaddr, used for preinc.
|
||||||
def iaddroff : ComplexPattern<iPTR, 1, "SelectAddrImmOffs", [], []>;
|
def iaddroff : ComplexPattern<iPTR, 1, "SelectAddrImmOffs", [], []>;
|
||||||
|
def xaddroff : ComplexPattern<iPTR, 1, "SelectAddrIdxOffs", [], []>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// PowerPC Instruction Predicate Definitions.
|
// PowerPC Instruction Predicate Definitions.
|
||||||
|
@ -822,12 +823,49 @@ def STWX : XForm_8<31, 151, (outs), (ins GPRC:$rS, memrr:$dst),
|
||||||
"stwx $rS, $dst", LdStStore,
|
"stwx $rS, $dst", LdStStore,
|
||||||
[(store GPRC:$rS, xaddr:$dst)]>,
|
[(store GPRC:$rS, xaddr:$dst)]>,
|
||||||
PPC970_DGroup_Cracked;
|
PPC970_DGroup_Cracked;
|
||||||
|
|
||||||
let mayStore = 1 in {
|
def STBUX : XForm_8<31, 247, (outs ptr_rc:$ea_res),
|
||||||
def STWUX : XForm_8<31, 183, (outs), (ins GPRC:$rS, GPRC:$rA, GPRC:$rB),
|
(ins GPRC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg),
|
||||||
"stwux $rS, $rA, $rB", LdStStore,
|
"stbux $rS, $ptroff, $ptrreg", LdStStore,
|
||||||
[]>;
|
[(set ptr_rc:$ea_res,
|
||||||
}
|
(pre_truncsti8 GPRC:$rS,
|
||||||
|
ptr_rc:$ptrreg, xaddroff:$ptroff))]>,
|
||||||
|
RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">,
|
||||||
|
PPC970_DGroup_Cracked;
|
||||||
|
|
||||||
|
def STHUX : XForm_8<31, 439, (outs ptr_rc:$ea_res),
|
||||||
|
(ins GPRC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg),
|
||||||
|
"sthux $rS, $ptroff, $ptrreg", LdStStore,
|
||||||
|
[(set ptr_rc:$ea_res,
|
||||||
|
(pre_truncsti16 GPRC:$rS,
|
||||||
|
ptr_rc:$ptrreg, xaddroff:$ptroff))]>,
|
||||||
|
RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">,
|
||||||
|
PPC970_DGroup_Cracked;
|
||||||
|
|
||||||
|
def STWUX : XForm_8<31, 183, (outs ptr_rc:$ea_res),
|
||||||
|
(ins GPRC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg),
|
||||||
|
"stwux $rS, $ptroff, $ptrreg", LdStStore,
|
||||||
|
[(set ptr_rc:$ea_res,
|
||||||
|
(pre_store GPRC:$rS, ptr_rc:$ptrreg, xaddroff:$ptroff))]>,
|
||||||
|
RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">,
|
||||||
|
PPC970_DGroup_Cracked;
|
||||||
|
|
||||||
|
def STFSUX : XForm_8<31, 695, (outs ptr_rc:$ea_res),
|
||||||
|
(ins F4RC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg),
|
||||||
|
"stfsux $rS, $ptroff, $ptrreg", LdStStore,
|
||||||
|
[(set ptr_rc:$ea_res,
|
||||||
|
(pre_store F4RC:$rS, ptr_rc:$ptrreg, xaddroff:$ptroff))]>,
|
||||||
|
RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">,
|
||||||
|
PPC970_DGroup_Cracked;
|
||||||
|
|
||||||
|
def STFDUX : XForm_8<31, 759, (outs ptr_rc:$ea_res),
|
||||||
|
(ins F8RC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg),
|
||||||
|
"stfdux $rS, $ptroff, $ptrreg", LdStStore,
|
||||||
|
[(set ptr_rc:$ea_res,
|
||||||
|
(pre_store F8RC:$rS, ptr_rc:$ptrreg, xaddroff:$ptroff))]>,
|
||||||
|
RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">,
|
||||||
|
PPC970_DGroup_Cracked;
|
||||||
|
|
||||||
def STHBRX: XForm_8<31, 918, (outs), (ins GPRC:$rS, memrr:$dst),
|
def STHBRX: XForm_8<31, 918, (outs), (ins GPRC:$rS, memrr:$dst),
|
||||||
"sthbrx $rS, $dst", LdStStore,
|
"sthbrx $rS, $dst", LdStStore,
|
||||||
[(PPCstbrx GPRC:$rS, xoaddr:$dst, i16)]>,
|
[(PPCstbrx GPRC:$rS, xoaddr:$dst, i16)]>,
|
||||||
|
|
|
@ -328,14 +328,14 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II,
|
||||||
// address of new allocated space.
|
// address of new allocated space.
|
||||||
if (LP64) {
|
if (LP64) {
|
||||||
if (requiresRegisterScavenging(MF)) // FIXME (64-bit): Use "true" part.
|
if (requiresRegisterScavenging(MF)) // FIXME (64-bit): Use "true" part.
|
||||||
BuildMI(MBB, II, dl, TII.get(PPC::STDUX))
|
BuildMI(MBB, II, dl, TII.get(PPC::STDUX), PPC::X1)
|
||||||
.addReg(Reg, RegState::Kill)
|
.addReg(Reg, RegState::Kill)
|
||||||
.addReg(PPC::X1, RegState::Define)
|
.addReg(PPC::X1)
|
||||||
.addReg(MI.getOperand(1).getReg());
|
.addReg(MI.getOperand(1).getReg());
|
||||||
else
|
else
|
||||||
BuildMI(MBB, II, dl, TII.get(PPC::STDUX))
|
BuildMI(MBB, II, dl, TII.get(PPC::STDUX), PPC::X1)
|
||||||
.addReg(PPC::X0, RegState::Kill)
|
.addReg(PPC::X0, RegState::Kill)
|
||||||
.addReg(PPC::X1, RegState::Define)
|
.addReg(PPC::X1)
|
||||||
.addReg(MI.getOperand(1).getReg());
|
.addReg(MI.getOperand(1).getReg());
|
||||||
|
|
||||||
if (!MI.getOperand(1).isKill())
|
if (!MI.getOperand(1).isKill())
|
||||||
|
@ -349,9 +349,9 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II,
|
||||||
.addImm(maxCallFrameSize)
|
.addImm(maxCallFrameSize)
|
||||||
.addReg(MI.getOperand(1).getReg(), RegState::ImplicitKill);
|
.addReg(MI.getOperand(1).getReg(), RegState::ImplicitKill);
|
||||||
} else {
|
} else {
|
||||||
BuildMI(MBB, II, dl, TII.get(PPC::STWUX))
|
BuildMI(MBB, II, dl, TII.get(PPC::STWUX), PPC::R1)
|
||||||
.addReg(Reg, RegState::Kill)
|
.addReg(Reg, RegState::Kill)
|
||||||
.addReg(PPC::R1, RegState::Define)
|
.addReg(PPC::R1)
|
||||||
.addReg(MI.getOperand(1).getReg());
|
.addReg(MI.getOperand(1).getReg());
|
||||||
|
|
||||||
if (!MI.getOperand(1).isKill())
|
if (!MI.getOperand(1).isKill())
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
@multvec_i = external unnamed_addr global [100 x i32], align 4
|
||||||
|
|
||||||
|
define fastcc void @subs_STMultiExceptIntern() nounwind {
|
||||||
|
entry:
|
||||||
|
br i1 undef, label %while.body.lr.ph, label %return
|
||||||
|
|
||||||
|
while.body.lr.ph: ; preds = %entry
|
||||||
|
br label %while.body
|
||||||
|
|
||||||
|
while.body: ; preds = %if.end12, %while.body.lr.ph
|
||||||
|
%i.0240 = phi i32 [ -1, %while.body.lr.ph ], [ %i.1, %if.end12 ]
|
||||||
|
br i1 undef, label %if.end12, label %if.then
|
||||||
|
|
||||||
|
if.then: ; preds = %while.body
|
||||||
|
br label %if.end12
|
||||||
|
|
||||||
|
if.end12: ; preds = %if.then, %while.body
|
||||||
|
%i.1 = phi i32 [ %i.0240, %while.body ], [ undef, %if.then ]
|
||||||
|
br i1 undef, label %while.body, label %while.end
|
||||||
|
|
||||||
|
while.end: ; preds = %if.end12
|
||||||
|
br i1 undef, label %return, label %if.end15
|
||||||
|
|
||||||
|
if.end15: ; preds = %while.end
|
||||||
|
%idxprom.i.i230 = sext i32 %i.1 to i64
|
||||||
|
%arrayidx18 = getelementptr inbounds [100 x i32]* @multvec_i, i64 0, i64 %idxprom.i.i230
|
||||||
|
store i32 0, i32* %arrayidx18, align 4
|
||||||
|
br i1 undef, label %while.body21, label %while.end90
|
||||||
|
|
||||||
|
while.body21: ; preds = %if.end15
|
||||||
|
unreachable
|
||||||
|
|
||||||
|
while.end90: ; preds = %if.end15
|
||||||
|
store i32 0, i32* %arrayidx18, align 4
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
return: ; preds = %while.end90, %while.end, %entry
|
||||||
|
ret void
|
||||||
|
|
||||||
|
; CHECK: @subs_STMultiExceptIntern
|
||||||
|
; CHECK: stwux
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue