mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 15:33:33 +00:00
add an initial cut at preinc loads for ppc32. This is broken for ppc64
(because the 64-bit reg target versions aren't implemented yet), doesn't support r+r addr modes, and doesn't handle stores, but it works otherwise. :) This is disabled unless -enable-ppc-preinc is passed to llc for now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31621 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
42b51e4ae2
commit
4eab71497d
@ -818,6 +818,44 @@ SDNode *PPCDAGToDAGISel::Select(SDOperand Op) {
|
|||||||
// Other cases are autogenerated.
|
// Other cases are autogenerated.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ISD::LOAD: {
|
||||||
|
// Handle preincrement loads.
|
||||||
|
LoadSDNode *LD = cast<LoadSDNode>(Op);
|
||||||
|
MVT::ValueType LoadedVT = LD->getLoadedVT();
|
||||||
|
|
||||||
|
// Normal loads are handled by code generated from the .td file.
|
||||||
|
if (LD->getAddressingMode() != ISD::PRE_INC)
|
||||||
|
break;
|
||||||
|
|
||||||
|
unsigned Opcode;
|
||||||
|
bool isSExt = LD->getExtensionType() == ISD::SEXTLOAD;
|
||||||
|
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::i8: Opcode = PPC::LBZU; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDOperand Offset = LD->getOffset();
|
||||||
|
if (isa<ConstantSDNode>(Offset)) {
|
||||||
|
SDOperand Chain = LD->getChain();
|
||||||
|
SDOperand Base = LD->getBasePtr();
|
||||||
|
AddToISelQueue(Chain);
|
||||||
|
AddToISelQueue(Base);
|
||||||
|
AddToISelQueue(Offset);
|
||||||
|
SDOperand Ops[] = { Offset, Base, Chain };
|
||||||
|
// FIXME: PPC64
|
||||||
|
return CurDAG->getTargetNode(Opcode, MVT::i32, MVT::i32,
|
||||||
|
MVT::Other, Ops, 3);
|
||||||
|
} else {
|
||||||
|
assert(0 && "R+R preindex loads not supported yet!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case ISD::AND: {
|
case ISD::AND: {
|
||||||
unsigned Imm, Imm2, SH, MB, ME;
|
unsigned Imm, Imm2, SH, MB, ME;
|
||||||
|
|
||||||
|
@ -26,8 +26,11 @@
|
|||||||
#include "llvm/Intrinsics.h"
|
#include "llvm/Intrinsics.h"
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Target/TargetOptions.h"
|
#include "llvm/Target/TargetOptions.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
static cl::opt<bool> EnablePPCPreinc("enable-ppc-preinc");
|
||||||
|
|
||||||
PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
|
PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
|
||||||
: TargetLowering(TM), PPCSubTarget(*TM.getSubtargetImpl()) {
|
: TargetLowering(TM), PPCSubTarget(*TM.getSubtargetImpl()) {
|
||||||
|
|
||||||
@ -861,29 +864,27 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDOperand &Base,
|
|||||||
SDOperand &Offset,
|
SDOperand &Offset,
|
||||||
ISD::MemIndexedMode &AM,
|
ISD::MemIndexedMode &AM,
|
||||||
SelectionDAG &DAG) {
|
SelectionDAG &DAG) {
|
||||||
return false;
|
// Disabled by default for now.
|
||||||
|
if (!EnablePPCPreinc) return false;
|
||||||
|
|
||||||
#if 0
|
|
||||||
MVT::ValueType VT;
|
|
||||||
SDOperand Ptr;
|
SDOperand Ptr;
|
||||||
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
|
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
|
||||||
Ptr = LD->getBasePtr();
|
Ptr = LD->getBasePtr();
|
||||||
VT = LD->getLoadedVT();
|
|
||||||
|
|
||||||
// TODO: handle other cases.
|
|
||||||
if (VT != MVT::i32) return false;
|
|
||||||
} else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
|
} else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
|
||||||
Ptr = ST->getBasePtr();
|
ST = ST;
|
||||||
VT = ST->getStoredVT();
|
//Ptr = ST->getBasePtr();
|
||||||
// TODO: handle other cases.
|
//VT = ST->getStoredVT();
|
||||||
|
// TODO: handle stores.
|
||||||
return false;
|
return false;
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// TODO: Handle reg+reg.
|
||||||
|
if (!SelectAddressRegImm(Ptr, Offset, Base, DAG))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
AM = ISD::PRE_INC;
|
||||||
return false;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -422,9 +422,44 @@ def LWZ : DForm_1<32, (ops GPRC:$rD, memri:$src),
|
|||||||
"lwz $rD, $src", LdStGeneral,
|
"lwz $rD, $src", LdStGeneral,
|
||||||
[(set GPRC:$rD, (load iaddr:$src))]>;
|
[(set GPRC:$rD, (load iaddr:$src))]>;
|
||||||
|
|
||||||
def LWZU : DForm_1<33, (ops GPRC:$rD, GPRC:$rA_result, i32imm:$disp, GPRC:$rA),
|
def LFS : DForm_8<48, (ops F4RC:$rD, memri:$src),
|
||||||
|
"lfs $rD, $src", LdStLFDU,
|
||||||
|
[(set F4RC:$rD, (load iaddr:$src))]>;
|
||||||
|
def LFD : DForm_8<50, (ops F8RC:$rD, memri:$src),
|
||||||
|
"lfd $rD, $src", LdStLFD,
|
||||||
|
[(set F8RC:$rD, (load iaddr:$src))]>;
|
||||||
|
|
||||||
|
// FIXME: PTRRC for Pointer regs for ppc64.
|
||||||
|
|
||||||
|
// 'Update' load forms.
|
||||||
|
def LBZU : DForm_1<35, (ops GPRC:$rD, ptr_rc:$rA_result, i32imm:$disp,
|
||||||
|
ptr_rc:$rA),
|
||||||
|
"lbzu $rD, $disp($rA)", LdStGeneral,
|
||||||
|
[]>, RegConstraint<"$rA = $rA_result">;
|
||||||
|
|
||||||
|
def LHAU : DForm_1<43, (ops GPRC:$rD, ptr_rc:$rA_result, i32imm:$disp,
|
||||||
|
ptr_rc:$rA),
|
||||||
|
"lhau $rD, $disp($rA)", LdStGeneral,
|
||||||
|
[]>, RegConstraint<"$rA = $rA_result">;
|
||||||
|
|
||||||
|
def LHZU : DForm_1<41, (ops GPRC:$rD, ptr_rc:$rA_result, i32imm:$disp,
|
||||||
|
ptr_rc:$rA),
|
||||||
|
"lhzu $rD, $disp($rA)", LdStGeneral,
|
||||||
|
[]>, RegConstraint<"$rA = $rA_result">;
|
||||||
|
|
||||||
|
def LWZU : DForm_1<33, (ops GPRC:$rD, ptr_rc:$rA_result, i32imm:$disp,
|
||||||
|
ptr_rc:$rA),
|
||||||
"lwzu $rD, $disp($rA)", LdStGeneral,
|
"lwzu $rD, $disp($rA)", LdStGeneral,
|
||||||
[]>, RegConstraint<"$rA = $rA_result">;
|
[]>, RegConstraint<"$rA = $rA_result">;
|
||||||
|
|
||||||
|
def LFSU : DForm_8<49, (ops F4RC:$rD, ptr_rc:$rA_result, i32imm:$disp,
|
||||||
|
ptr_rc:$rA),
|
||||||
|
"lfs $rD, $disp($rA)", LdStLFDU,
|
||||||
|
[]>, RegConstraint<"$rA = $rA_result">;
|
||||||
|
def LFDU : DForm_8<51, (ops F8RC:$rD, ptr_rc:$rA_result, i32imm:$disp,
|
||||||
|
ptr_rc:$rA),
|
||||||
|
"lfd $rD, $disp($rA)", LdStLFD,
|
||||||
|
[]>, RegConstraint<"$rA = $rA_result">;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -501,14 +536,6 @@ def CMPWI : DForm_5_ext<11, (ops CRRC:$crD, GPRC:$rA, s16imm:$imm),
|
|||||||
def CMPLWI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
|
def CMPLWI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
|
||||||
"cmplwi $dst, $src1, $src2", IntCompare>;
|
"cmplwi $dst, $src1, $src2", IntCompare>;
|
||||||
}
|
}
|
||||||
let isLoad = 1, PPC970_Unit = 2 in {
|
|
||||||
def LFS : DForm_8<48, (ops F4RC:$rD, memri:$src),
|
|
||||||
"lfs $rD, $src", LdStLFDU,
|
|
||||||
[(set F4RC:$rD, (load iaddr:$src))]>;
|
|
||||||
def LFD : DForm_8<50, (ops F8RC:$rD, memri:$src),
|
|
||||||
"lfd $rD, $src", LdStLFD,
|
|
||||||
[(set F8RC:$rD, (load iaddr:$src))]>;
|
|
||||||
}
|
|
||||||
let isStore = 1, noResults = 1, PPC970_Unit = 2 in {
|
let isStore = 1, noResults = 1, PPC970_Unit = 2 in {
|
||||||
def STFS : DForm_9<52, (ops F4RC:$rS, memri:$dst),
|
def STFS : DForm_9<52, (ops F4RC:$rS, memri:$dst),
|
||||||
"stfs $rS, $dst", LdStUX,
|
"stfs $rS, $dst", LdStUX,
|
||||||
|
Loading…
Reference in New Issue
Block a user