mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
[XCore] Make use of the target independent global address offset folding.
This let us to remove some custom code that matched constant offsets from globals at instruction selection time as a special addressing mode. No intended functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181126 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
40827bc716
commit
6ffbf6ea8f
@ -97,9 +97,6 @@ static DecodeStatus DecodeRRegsRegisterClass(MCInst &Inst,
|
||||
static DecodeStatus DecodeBitpOperand(MCInst &Inst, unsigned Val,
|
||||
uint64_t Address, const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeMEMiiOperand(MCInst &Inst, unsigned Val,
|
||||
uint64_t Address, const void *Decoder);
|
||||
|
||||
static DecodeStatus Decode2RInstruction(MCInst &Inst,
|
||||
unsigned Insn,
|
||||
uint64_t Address,
|
||||
@ -242,13 +239,6 @@ static DecodeStatus DecodeBitpOperand(MCInst &Inst, unsigned Val,
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeMEMiiOperand(MCInst &Inst, unsigned Val,
|
||||
uint64_t Address, const void *Decoder) {
|
||||
Inst.addOperand(MCOperand::CreateImm(Val));
|
||||
Inst.addOperand(MCOperand::CreateImm(0));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus
|
||||
Decode2OpInstruction(unsigned Insn, unsigned &Op1, unsigned &Op2) {
|
||||
unsigned Combined = fieldFromInstruction(Insn, 6, 5);
|
||||
|
@ -84,14 +84,3 @@ printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
assert(Op.isExpr() && "unknown operand kind in printOperand");
|
||||
printExpr(Op.getExpr(), O);
|
||||
}
|
||||
|
||||
void XCoreInstPrinter::
|
||||
printMemOperand(const MCInst *MI, int opNum, raw_ostream &O) {
|
||||
printOperand(MI, opNum, O);
|
||||
|
||||
if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
|
||||
return;
|
||||
|
||||
O << "+";
|
||||
printOperand(MI, opNum+1, O);
|
||||
}
|
||||
|
@ -68,8 +68,6 @@ namespace {
|
||||
|
||||
// Complex Pattern Selectors.
|
||||
bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset);
|
||||
bool SelectADDRdpii(SDValue Addr, SDValue &Base, SDValue &Offset);
|
||||
bool SelectADDRcpii(SDValue Addr, SDValue &Base, SDValue &Offset);
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "XCore DAG->DAG Pattern Instruction Selection";
|
||||
@ -110,48 +108,6 @@ bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Addr, SDValue &Base,
|
||||
SDValue &Offset) {
|
||||
if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) {
|
||||
Base = Addr.getOperand(0);
|
||||
Offset = CurDAG->getTargetConstant(0, MVT::i32);
|
||||
return true;
|
||||
}
|
||||
if (Addr.getOpcode() == ISD::ADD) {
|
||||
ConstantSDNode *CN = 0;
|
||||
if ((Addr.getOperand(0).getOpcode() == XCoreISD::DPRelativeWrapper)
|
||||
&& (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
|
||||
&& (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) {
|
||||
// Constant word offset from a object in the data region
|
||||
Base = Addr.getOperand(0).getOperand(0);
|
||||
Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XCoreDAGToDAGISel::SelectADDRcpii(SDValue Addr, SDValue &Base,
|
||||
SDValue &Offset) {
|
||||
if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) {
|
||||
Base = Addr.getOperand(0);
|
||||
Offset = CurDAG->getTargetConstant(0, MVT::i32);
|
||||
return true;
|
||||
}
|
||||
if (Addr.getOpcode() == ISD::ADD) {
|
||||
ConstantSDNode *CN = 0;
|
||||
if ((Addr.getOperand(0).getOpcode() == XCoreISD::CPRelativeWrapper)
|
||||
&& (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
|
||||
&& (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) {
|
||||
// Constant word offset from a object in the data region
|
||||
Base = Addr.getOperand(0).getOperand(0);
|
||||
Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SDNode *XCoreDAGToDAGISel::Select(SDNode *N) {
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
switch (N->getOpcode()) {
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
const char *XCoreTargetLowering::
|
||||
@ -241,9 +243,20 @@ getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV,
|
||||
SDValue XCoreTargetLowering::
|
||||
LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
|
||||
{
|
||||
const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
|
||||
SDValue GA = DAG.getTargetGlobalAddress(GV, Op.getDebugLoc(), MVT::i32);
|
||||
return getGlobalAddressWrapper(GA, GV, DAG);
|
||||
DebugLoc DL = Op.getDebugLoc();
|
||||
const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op);
|
||||
const GlobalValue *GV = GN->getGlobal();
|
||||
int64_t Offset = GN->getOffset();
|
||||
// We can only fold positive offsets that are a multiple of the word size.
|
||||
int64_t FoldedOffset = std::max(Offset & ~3, 0LL);
|
||||
SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, FoldedOffset);
|
||||
GA = getGlobalAddressWrapper(GA, GV, DAG);
|
||||
// Handle the rest of the offset.
|
||||
if (Offset != FoldedOffset) {
|
||||
SDValue Remaining = DAG.getConstant(Offset - FoldedOffset, MVT::i32);
|
||||
GA = DAG.getNode(ISD::ADD, DL, MVT::i32, GA, Remaining);
|
||||
}
|
||||
return GA;
|
||||
}
|
||||
|
||||
static inline SDValue BuildGetId(SelectionDAG &DAG, DebugLoc dl) {
|
||||
@ -319,10 +332,19 @@ lowerLoadWordFromAlignedBasePlusOffset(DebugLoc DL, SDValue Chain, SDValue Base,
|
||||
// Lower to pair of consecutive word aligned loads plus some bit shifting.
|
||||
int32_t HighOffset = RoundUpToAlignment(Offset, 4);
|
||||
int32_t LowOffset = HighOffset - 4;
|
||||
SDValue LowAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base,
|
||||
DAG.getConstant(LowOffset, MVT::i32));
|
||||
SDValue HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base,
|
||||
DAG.getConstant(HighOffset, MVT::i32));
|
||||
SDValue LowAddr, HighAddr;
|
||||
if (GlobalAddressSDNode *GASD =
|
||||
dyn_cast<GlobalAddressSDNode>(Base.getNode())) {
|
||||
LowAddr = DAG.getGlobalAddress(GASD->getGlobal(), DL, Base.getValueType(),
|
||||
LowOffset);
|
||||
HighAddr = DAG.getGlobalAddress(GASD->getGlobal(), DL, Base.getValueType(),
|
||||
HighOffset);
|
||||
} else {
|
||||
LowAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base,
|
||||
DAG.getConstant(LowOffset, MVT::i32));
|
||||
HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base,
|
||||
DAG.getConstant(HighOffset, MVT::i32));
|
||||
}
|
||||
SDValue LowShift = DAG.getConstant((Offset - LowOffset) * 8, MVT::i32);
|
||||
SDValue HighShift = DAG.getConstant((HighOffset - Offset) * 8, MVT::i32);
|
||||
|
||||
@ -1553,12 +1575,6 @@ XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM,
|
||||
}
|
||||
}
|
||||
|
||||
bool XCoreTargetLowering::
|
||||
isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
|
||||
// The XCore target isn't yet aware of offsets.
|
||||
return false;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// XCore Inline Assembly Support
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -106,8 +106,6 @@ namespace llvm {
|
||||
virtual bool isLegalAddressingMode(const AddrMode &AM,
|
||||
Type *Ty) const;
|
||||
|
||||
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
|
||||
|
||||
private:
|
||||
const XCoreTargetMachine &TM;
|
||||
const XCoreSubtarget &Subtarget;
|
||||
|
@ -174,15 +174,9 @@ def pclabel : Operand<i32>;
|
||||
|
||||
// Addressing modes
|
||||
def ADDRspii : ComplexPattern<i32, 2, "SelectADDRspii", [add, frameindex], []>;
|
||||
def ADDRdpii : ComplexPattern<i32, 2, "SelectADDRdpii", [add, dprelwrapper],
|
||||
[]>;
|
||||
def ADDRcpii : ComplexPattern<i32, 2, "SelectADDRcpii", [add, cprelwrapper],
|
||||
[]>;
|
||||
|
||||
// Address operands
|
||||
def MEMii : Operand<i32> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let DecoderMethod = "DecodeMEMiiOperand";
|
||||
let MIOperandInfo = (ops i32imm, i32imm);
|
||||
}
|
||||
|
||||
@ -515,29 +509,29 @@ def LMUL_l6r : _FL6R<
|
||||
|
||||
//let Uses = [DP] in ...
|
||||
let neverHasSideEffects = 1, isReMaterializable = 1 in
|
||||
def LDAWDP_ru6: _FRU6<0b011000, (outs RRegs:$a), (ins MEMii:$b),
|
||||
def LDAWDP_ru6: _FRU6<0b011000, (outs RRegs:$a), (ins i32imm:$b),
|
||||
"ldaw $a, dp[$b]", []>;
|
||||
|
||||
let isReMaterializable = 1 in
|
||||
def LDAWDP_lru6: _FLRU6<0b011000, (outs RRegs:$a), (ins MEMii:$b),
|
||||
def LDAWDP_lru6: _FLRU6<0b011000, (outs RRegs:$a), (ins i32imm:$b),
|
||||
"ldaw $a, dp[$b]",
|
||||
[(set RRegs:$a, ADDRdpii:$b)]>;
|
||||
[(set RRegs:$a, (dprelwrapper tglobaladdr:$b))]>;
|
||||
|
||||
let mayLoad=1 in
|
||||
def LDWDP_ru6: _FRU6<0b010110, (outs RRegs:$a), (ins MEMii:$b),
|
||||
def LDWDP_ru6: _FRU6<0b010110, (outs RRegs:$a), (ins i32imm:$b),
|
||||
"ldw $a, dp[$b]", []>;
|
||||
|
||||
def LDWDP_lru6: _FLRU6<0b010110, (outs RRegs:$a), (ins MEMii:$b),
|
||||
def LDWDP_lru6: _FLRU6<0b010110, (outs RRegs:$a), (ins i32imm:$b),
|
||||
"ldw $a, dp[$b]",
|
||||
[(set RRegs:$a, (load ADDRdpii:$b))]>;
|
||||
[(set RRegs:$a, (load (dprelwrapper tglobaladdr:$b)))]>;
|
||||
|
||||
let mayStore=1 in
|
||||
def STWDP_ru6 : _FRU6<0b010100, (outs), (ins RRegs:$a, MEMii:$b),
|
||||
def STWDP_ru6 : _FRU6<0b010100, (outs), (ins RRegs:$a, i32imm:$b),
|
||||
"stw $a, dp[$b]", []>;
|
||||
|
||||
def STWDP_lru6 : _FLRU6<0b010100, (outs), (ins RRegs:$a, MEMii:$b),
|
||||
def STWDP_lru6 : _FLRU6<0b010100, (outs), (ins RRegs:$a, i32imm:$b),
|
||||
"stw $a, dp[$b]",
|
||||
[(store RRegs:$a, ADDRdpii:$b)]>;
|
||||
[(store RRegs:$a, (dprelwrapper tglobaladdr:$b))]>;
|
||||
|
||||
//let Uses = [CP] in ..
|
||||
let mayLoad = 1, isReMaterializable = 1, neverHasSideEffects = 1 in
|
||||
@ -626,12 +620,12 @@ def BRFU_lu6 : _FLU6<0b0111001100, (outs), (ins brtarget:$a), "bu $a", []>;
|
||||
|
||||
//let Uses = [CP] in ...
|
||||
let Defs = [R11], neverHasSideEffects = 1, isReMaterializable = 1 in
|
||||
def LDAWCP_u6: _FU6<0b0111111101, (outs), (ins MEMii:$a), "ldaw r11, cp[$a]",
|
||||
def LDAWCP_u6: _FU6<0b0111111101, (outs), (ins i32imm:$a), "ldaw r11, cp[$a]",
|
||||
[]>;
|
||||
|
||||
let Defs = [R11], isReMaterializable = 1 in
|
||||
def LDAWCP_lu6: _FLU6<0b0111111101, (outs), (ins MEMii:$a), "ldaw r11, cp[$a]",
|
||||
[(set R11, ADDRcpii:$a)]>;
|
||||
def LDAWCP_lu6: _FLU6<0b0111111101, (outs), (ins i32imm:$a), "ldaw r11, cp[$a]",
|
||||
[(set R11, (cprelwrapper tglobaladdr:$a))]>;
|
||||
|
||||
let Defs = [R11] in
|
||||
defm GETSR : FU6_LU6_np<0b0111111100, "getsr r11,">;
|
||||
|
Loading…
Reference in New Issue
Block a user