mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
Add support for generating reg+reg (indexed) pre-inc loads on PPC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158823 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d65e463ff9
commit
0fcdd8b2cc
@ -927,12 +927,44 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
|||||||
SDValue Chain = LD->getChain();
|
SDValue Chain = LD->getChain();
|
||||||
SDValue Base = LD->getBasePtr();
|
SDValue Base = LD->getBasePtr();
|
||||||
SDValue Ops[] = { Offset, Base, Chain };
|
SDValue Ops[] = { Offset, Base, Chain };
|
||||||
// FIXME: PPC64
|
|
||||||
return CurDAG->getMachineNode(Opcode, dl, LD->getValueType(0),
|
return CurDAG->getMachineNode(Opcode, dl, LD->getValueType(0),
|
||||||
PPCLowering.getPointerTy(),
|
PPCLowering.getPointerTy(),
|
||||||
MVT::Other, Ops, 3);
|
MVT::Other, Ops, 3);
|
||||||
} else {
|
} 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;
|
return false;
|
||||||
|
|
||||||
if (SelectAddressRegReg(Ptr, Offset, Base, DAG)) {
|
if (SelectAddressRegReg(Ptr, Offset, Base, DAG)) {
|
||||||
if (isa<StoreSDNode>(N)) {
|
AM = ISD::PRE_INC;
|
||||||
AM = ISD::PRE_INC;
|
return true;
|
||||||
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.
|
||||||
|
@ -533,6 +533,16 @@ def LHAU8 : DForm_1a<43, (outs G8RC:$rD, ptr_rc:$ea_result), (ins symbolLo:$disp
|
|||||||
NoEncode<"$ea_result">;
|
NoEncode<"$ea_result">;
|
||||||
// NO LWAU!
|
// 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.
|
// 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,
|
"lwzu $rD, $addr", LdStLoad,
|
||||||
[]>, RegConstraint<"$addr.reg = $ea_result">,
|
[]>, RegConstraint<"$addr.reg = $ea_result">,
|
||||||
NoEncode<"$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,
|
[]>, RegConstraint<"$addr.reg = $ea_result">, isPPC64,
|
||||||
NoEncode<"$ea_result">;
|
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),
|
def : Pat<(PPCload ixaddr:$src),
|
||||||
|
@ -323,7 +323,7 @@ def memri : Operand<iPTR> {
|
|||||||
}
|
}
|
||||||
def memrr : Operand<iPTR> {
|
def memrr : Operand<iPTR> {
|
||||||
let PrintMethod = "printMemRegReg";
|
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.
|
def memrix : Operand<iPTR> { // memri where the imm is shifted 2 bits.
|
||||||
let PrintMethod = "printMemRegImmShifted";
|
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,
|
"lfd $rD, $addr", LdStLFD,
|
||||||
[]>, RegConstraint<"$addr.reg = $ea_result">,
|
[]>, RegConstraint<"$addr.reg = $ea_result">,
|
||||||
NoEncode<"$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">;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
49
test/CodeGen/PowerPC/lbzux.ll
Normal file
49
test/CodeGen/PowerPC/lbzux.ll
Normal file
@ -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
Block a user