mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-20 05:38:50 +00:00
implement preinc support for r+i loads on ppc64
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31654 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
de2b6605ba
commit
94e509caea
@ -830,14 +830,29 @@ SDNode *PPCDAGToDAGISel::Select(SDOperand Op) {
|
|||||||
|
|
||||||
unsigned Opcode;
|
unsigned Opcode;
|
||||||
bool isSExt = LD->getExtensionType() == ISD::SEXTLOAD;
|
bool isSExt = LD->getExtensionType() == ISD::SEXTLOAD;
|
||||||
assert(!isSExt || LoadedVT == MVT::i16 && "Invalid sext update load");
|
if (LD->getValueType(0) != MVT::i64) {
|
||||||
switch (LoadedVT) {
|
// Handle PPC32 integer and normal FP loads.
|
||||||
default: assert(0 && "Invalid PPC load type!");
|
assert(!isSExt || LoadedVT == MVT::i16 && "Invalid sext update load");
|
||||||
case MVT::f64: Opcode = PPC::LFDU; break;
|
switch (LoadedVT) {
|
||||||
case MVT::f32: Opcode = PPC::LFSU; break;
|
default: assert(0 && "Invalid PPC load type!");
|
||||||
case MVT::i32: Opcode = PPC::LWZU; break;
|
case MVT::f64: Opcode = PPC::LFDU; break;
|
||||||
case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU; break;
|
case MVT::f32: Opcode = PPC::LFSU; break;
|
||||||
case MVT::i8: Opcode = PPC::LBZU; 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();
|
SDOperand Offset = LD->getOffset();
|
||||||
|
@ -53,9 +53,15 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
|
|||||||
// PowerPC does not have truncstore for i1.
|
// PowerPC does not have truncstore for i1.
|
||||||
setStoreXAction(MVT::i1, Promote);
|
setStoreXAction(MVT::i1, Promote);
|
||||||
|
|
||||||
// PowerPC has i32 and i64 pre-inc load and store's.
|
// PowerPC has pre-inc load and store's.
|
||||||
|
setIndexedLoadAction(ISD::PRE_INC, MVT::i1, Legal);
|
||||||
|
setIndexedLoadAction(ISD::PRE_INC, MVT::i8, Legal);
|
||||||
|
setIndexedLoadAction(ISD::PRE_INC, MVT::i16, Legal);
|
||||||
setIndexedLoadAction(ISD::PRE_INC, MVT::i32, Legal);
|
setIndexedLoadAction(ISD::PRE_INC, MVT::i32, Legal);
|
||||||
setIndexedLoadAction(ISD::PRE_INC, MVT::i64, Legal);
|
setIndexedLoadAction(ISD::PRE_INC, MVT::i64, Legal);
|
||||||
|
setIndexedStoreAction(ISD::PRE_INC, MVT::i1, Legal);
|
||||||
|
setIndexedStoreAction(ISD::PRE_INC, MVT::i8, Legal);
|
||||||
|
setIndexedStoreAction(ISD::PRE_INC, MVT::i16, Legal);
|
||||||
setIndexedStoreAction(ISD::PRE_INC, MVT::i32, Legal);
|
setIndexedStoreAction(ISD::PRE_INC, MVT::i32, Legal);
|
||||||
setIndexedStoreAction(ISD::PRE_INC, MVT::i64, Legal);
|
setIndexedStoreAction(ISD::PRE_INC, MVT::i64, Legal);
|
||||||
|
|
||||||
@ -870,6 +876,9 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDOperand &Base,
|
|||||||
SDOperand Ptr;
|
SDOperand Ptr;
|
||||||
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
|
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
|
||||||
Ptr = LD->getBasePtr();
|
Ptr = LD->getBasePtr();
|
||||||
|
|
||||||
|
// FIXME: PPC has no LWAU!
|
||||||
|
|
||||||
} else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
|
} else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
|
||||||
ST = ST;
|
ST = ST;
|
||||||
//Ptr = ST->getBasePtr();
|
//Ptr = ST->getBasePtr();
|
||||||
|
@ -229,8 +229,8 @@ def RLDICR : MDForm_1<30, 1,
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
let isLoad = 1, PPC970_Unit = 2 in {
|
|
||||||
// Sign extending loads.
|
// Sign extending loads.
|
||||||
|
let isLoad = 1, PPC970_Unit = 2 in {
|
||||||
def LHA8: DForm_1<42, (ops G8RC:$rD, memri:$src),
|
def LHA8: DForm_1<42, (ops G8RC:$rD, memri:$src),
|
||||||
"lha $rD, $src", LdStLHA,
|
"lha $rD, $src", LdStLHA,
|
||||||
[(set G8RC:$rD, (sextloadi16 iaddr:$src))]>,
|
[(set G8RC:$rD, (sextloadi16 iaddr:$src))]>,
|
||||||
@ -248,7 +248,17 @@ def LWAX : XForm_1<31, 341, (ops G8RC:$rD, memrr:$src),
|
|||||||
[(set G8RC:$rD, (sextloadi32 xaddr:$src))]>, isPPC64,
|
[(set G8RC:$rD, (sextloadi32 xaddr:$src))]>, isPPC64,
|
||||||
PPC970_DGroup_Cracked;
|
PPC970_DGroup_Cracked;
|
||||||
|
|
||||||
|
// Update forms.
|
||||||
|
def LHAU8 : DForm_1<43, (ops G8RC:$rD, ptr_rc:$rA_result, i32imm:$disp,
|
||||||
|
ptr_rc:$rA),
|
||||||
|
"lhau $rD, $disp($rA)", LdStGeneral,
|
||||||
|
[]>, RegConstraint<"$rA = $rA_result">;
|
||||||
|
// NO LWAU!
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Zero extending loads.
|
// Zero extending loads.
|
||||||
|
let isLoad = 1, PPC970_Unit = 2 in {
|
||||||
def LBZ8 : DForm_1<34, (ops G8RC:$rD, memri:$src),
|
def LBZ8 : DForm_1<34, (ops G8RC:$rD, memri:$src),
|
||||||
"lbz $rD, $src", LdStGeneral,
|
"lbz $rD, $src", LdStGeneral,
|
||||||
[(set G8RC:$rD, (zextloadi8 iaddr:$src))]>;
|
[(set G8RC:$rD, (zextloadi8 iaddr:$src))]>;
|
||||||
@ -268,20 +278,44 @@ def LHZX8 : XForm_1<31, 279, (ops G8RC:$rD, memrr:$src),
|
|||||||
def LWZX8 : XForm_1<31, 23, (ops G8RC:$rD, memrr:$src),
|
def LWZX8 : XForm_1<31, 23, (ops G8RC:$rD, memrr:$src),
|
||||||
"lwzx $rD, $src", LdStGeneral,
|
"lwzx $rD, $src", LdStGeneral,
|
||||||
[(set G8RC:$rD, (zextloadi32 xaddr:$src))]>;
|
[(set G8RC:$rD, (zextloadi32 xaddr:$src))]>;
|
||||||
|
|
||||||
|
|
||||||
|
// Update forms.
|
||||||
|
def LBZU8 : DForm_1<35, (ops G8RC:$rD, ptr_rc:$rA_result, i32imm:$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, i32imm:$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, i32imm:$disp,
|
||||||
|
ptr_rc:$rA),
|
||||||
|
"lwzu $rD, $disp($rA)", LdStGeneral,
|
||||||
|
[]>, RegConstraint<"$rA = $rA_result">;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Full 8-byte loads.
|
// Full 8-byte loads.
|
||||||
def LD : DSForm_2<58, 0, (ops G8RC:$rD, memrix:$src),
|
let isLoad = 1, PPC970_Unit = 2 in {
|
||||||
|
def LD : DSForm_1<58, 0, (ops G8RC:$rD, memrix:$src),
|
||||||
"ld $rD, $src", LdStLD,
|
"ld $rD, $src", LdStLD,
|
||||||
[(set G8RC:$rD, (load ixaddr:$src))]>, isPPC64;
|
[(set G8RC:$rD, (load ixaddr:$src))]>, isPPC64;
|
||||||
def LDX : XForm_1<31, 21, (ops G8RC:$rD, memrr:$src),
|
def LDX : XForm_1<31, 21, (ops G8RC:$rD, memrr:$src),
|
||||||
"ldx $rD, $src", LdStLD,
|
"ldx $rD, $src", LdStLD,
|
||||||
[(set G8RC:$rD, (load xaddr:$src))]>, isPPC64;
|
[(set G8RC:$rD, (load xaddr:$src))]>, isPPC64;
|
||||||
|
|
||||||
|
def LDU : DSForm_1<58, 1, (ops G8RC:$rD, ptr_rc:$rA_result, i32imm:$disp,
|
||||||
|
ptr_rc:$rA),
|
||||||
|
"ldu $rD, $disp($rA)", LdStLD,
|
||||||
|
[]>, RegConstraint<"$rA = $rA_result">, isPPC64;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let isStore = 1, noResults = 1, PPC970_Unit = 2 in {
|
let isStore = 1, noResults = 1, PPC970_Unit = 2 in {
|
||||||
// Normal stores.
|
// Normal stores.
|
||||||
def STD : DSForm_2<62, 0, (ops G8RC:$rS, memrix:$dst),
|
def STD : DSForm_1<62, 0, (ops G8RC:$rS, memrix:$dst),
|
||||||
"std $rS, $dst", LdStSTD,
|
"std $rS, $dst", LdStSTD,
|
||||||
[(store G8RC:$rS, ixaddr:$dst)]>, isPPC64;
|
[(store G8RC:$rS, ixaddr:$dst)]>, isPPC64;
|
||||||
def STDX : XForm_8<31, 149, (ops G8RC:$rS, memrr:$dst),
|
def STDX : XForm_8<31, 149, (ops G8RC:$rS, memrr:$dst),
|
||||||
@ -293,7 +327,7 @@ def STDUX : XForm_8<31, 181, (ops G8RC:$rS, memrr:$dst),
|
|||||||
[]>, isPPC64;
|
[]>, 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_2<62, 0, (ops GPRC:$rT, memrix:$dst),
|
def STD_32 : DSForm_1<62, 0, (ops GPRC:$rT, memrix:$dst),
|
||||||
"std $rT, $dst", LdStSTD,
|
"std $rT, $dst", LdStSTD,
|
||||||
[(PPCstd_32 GPRC:$rT, ixaddr:$dst)]>, isPPC64;
|
[(PPCstd_32 GPRC:$rT, ixaddr:$dst)]>, isPPC64;
|
||||||
def STDX_32 : XForm_8<31, 149, (ops GPRC:$rT, memrr:$dst),
|
def STDX_32 : XForm_8<31, 149, (ops GPRC:$rT, memrr:$dst),
|
||||||
|
@ -191,10 +191,6 @@ class DSForm_1<bits<6> opcode, bits<2> xo, dag OL, string asmstr,
|
|||||||
let Inst{30-31} = xo;
|
let Inst{30-31} = xo;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DSForm_2<bits<6> opcode, bits<2> xo, dag OL, string asmstr,
|
|
||||||
InstrItinClass itin, list<dag> pattern>
|
|
||||||
: DSForm_1<opcode, xo, OL, asmstr, itin, pattern>;
|
|
||||||
|
|
||||||
// 1.7.6 X-Form
|
// 1.7.6 X-Form
|
||||||
class XForm_base_r3xo<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
|
class XForm_base_r3xo<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
|
||||||
InstrItinClass itin, list<dag> pattern>
|
InstrItinClass itin, list<dag> pattern>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user