mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 21:32:39 +00:00
Add address computation stuff
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75935 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dfd0dffa36
commit
711d5b68e0
@ -107,6 +107,9 @@ namespace {
|
||||
private:
|
||||
bool SelectAddrRRI(SDValue Op, SDValue Addr,
|
||||
SDValue &Base, SDValue &Index, SDValue &Disp);
|
||||
bool SelectLAAddr(SDValue Op, SDValue Addr,
|
||||
SDValue &Base, SDValue &Index, SDValue &Disp);
|
||||
|
||||
SDNode *Select(SDValue Op);
|
||||
bool SelectAddrRI(const SDValue& Op, SDValue& Addr,
|
||||
SDValue &Base, SDValue &Disp);
|
||||
@ -369,8 +372,24 @@ bool SystemZDAGToDAGISel::SelectAddrRRI(SDValue Op, SDValue Addr,
|
||||
SystemZRRIAddressMode AM;
|
||||
bool Done = false;
|
||||
|
||||
// FIXME: Should we better use lay instruction for non-single uses?
|
||||
|
||||
if (!Addr.hasOneUse()) {
|
||||
unsigned Opcode = Addr.getOpcode();
|
||||
if (Opcode != ISD::Constant && Opcode != ISD::FrameIndex) {
|
||||
// If we are able to fold N into addressing mode, then we'll allow it even
|
||||
// if N has multiple uses. In general, addressing computation is used as
|
||||
// addresses by all of its uses. But watch out for CopyToReg uses, that
|
||||
// means the address computation is liveout. It will be computed by a LA
|
||||
// so we want to avoid computing the address twice.
|
||||
for (SDNode::use_iterator UI = Addr.getNode()->use_begin(),
|
||||
UE = Addr.getNode()->use_end(); UI != UE; ++UI) {
|
||||
if (UI->getOpcode() == ISD::CopyToReg) {
|
||||
MatchAddressBase(Addr, AM);
|
||||
Done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Done && MatchAddress(Addr, AM))
|
||||
return false;
|
||||
|
||||
@ -388,11 +407,52 @@ bool SystemZDAGToDAGISel::SelectAddrRRI(SDValue Op, SDValue Addr,
|
||||
else
|
||||
Base = CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, TLI.getPointerTy());
|
||||
Index = AM.IndexReg;
|
||||
Disp = Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32);
|
||||
Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// SelectLAAddr - it calls SelectAddr and determines if the maximal addressing
|
||||
/// mode it matches can be cost effectively emitted as an LA/LAY instruction.
|
||||
bool SystemZDAGToDAGISel::SelectLAAddr(SDValue Op, SDValue Addr,
|
||||
SDValue &Base, SDValue &Index, SDValue &Disp) {
|
||||
SystemZRRIAddressMode AM;
|
||||
|
||||
if (MatchAddress(Addr, AM))
|
||||
return false;
|
||||
|
||||
MVT VT = Addr.getValueType();
|
||||
unsigned Complexity = 0;
|
||||
if (AM.BaseType == SystemZRRIAddressMode::RegBase)
|
||||
if (AM.Base.Reg.getNode())
|
||||
Complexity = 1;
|
||||
else
|
||||
AM.Base.Reg = CurDAG->getRegister(0, VT);
|
||||
else if (AM.BaseType == SystemZRRIAddressMode::FrameIndexBase)
|
||||
Complexity = 4;
|
||||
|
||||
if (AM.IndexReg.getNode())
|
||||
Complexity += 1;
|
||||
else
|
||||
AM.IndexReg = CurDAG->getRegister(0, VT);
|
||||
|
||||
if (AM.Disp && (AM.Base.Reg.getNode() || AM.IndexReg.getNode()))
|
||||
Complexity += 1;
|
||||
|
||||
if (Complexity > 2) {
|
||||
if (AM.BaseType == SystemZRRIAddressMode::RegBase)
|
||||
Base = AM.Base.Reg;
|
||||
else
|
||||
Base = CurDAG->getTargetFrameIndex(AM.Base.FrameIndex,
|
||||
TLI.getPointerTy());
|
||||
Index = AM.IndexReg;
|
||||
Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// InstructionSelect - This callback is invoked by
|
||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||
void SystemZDAGToDAGISel::InstructionSelect() {
|
||||
|
@ -162,10 +162,16 @@ def riaddr : Operand<i64>,
|
||||
|
||||
// rriaddr := reg + reg + imm
|
||||
def rriaddr : Operand<i64>,
|
||||
ComplexPattern<i64, 3, "SelectAddrRRI", []> {
|
||||
ComplexPattern<i64, 3, "SelectAddrRRI", [], []> {
|
||||
let PrintMethod = "printRRIAddrOperand";
|
||||
let MIOperandInfo = (ops ADDR64:$base, ADDR64:$index, i32imm:$disp);
|
||||
}
|
||||
def laaddr : Operand<i64>,
|
||||
ComplexPattern<i64, 3, "SelectLAAddr", [add, sub, or, frameindex], []> {
|
||||
let PrintMethod = "printRRIAddrOperand";
|
||||
let MIOperandInfo = (ops ADDR64:$base, ADDR64:$index, i32imm:$disp);
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Control Flow Instructions...
|
||||
@ -176,6 +182,18 @@ let isReturn = 1, isTerminator = 1 in {
|
||||
def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Miscellaneous Instructions.
|
||||
//
|
||||
|
||||
let isReMaterializable = 1 in
|
||||
// FIXME: Provide imm12 variant
|
||||
def LA64r : Pseudo<(outs GR64:$dst), (ins laaddr:$src),
|
||||
"lay\t{$dst, $src}",
|
||||
[(set GR64:$dst, laaddr:$src)]>;
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Move Instructions
|
||||
|
||||
|
12
test/CodeGen/SystemZ/05-LoadAddr.ll
Normal file
12
test/CodeGen/SystemZ/05-LoadAddr.ll
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.globl foo
|
||||
.type foo,@function
|
||||
foo:
|
||||
.BB1_0: # entry
|
||||
sllg %r1, %r3, 3
|
||||
lay %r2, 8(%r1,%r2)
|
||||
br %r14
|
||||
.size foo, .-foo
|
Loading…
x
Reference in New Issue
Block a user