mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-21 19:32:16 +00:00
[Hexagon] Adding selection for GlobalAddress and converting [z/i]ext load patterns to make use of them.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228184 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b9fc61d031
commit
1d75b286e6
@ -77,6 +77,9 @@ public:
|
||||
bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
|
||||
bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
|
||||
|
||||
// Complex Pattern Selectors.
|
||||
inline bool SelectAddrGA(SDValue &N, SDValue &R);
|
||||
bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP);
|
||||
bool SelectAddrFI(SDValue &N, SDValue &R);
|
||||
|
||||
const char *getPassName() const override {
|
||||
@ -1630,6 +1633,51 @@ bool HexagonDAGToDAGISel::SelectAddrFI(SDValue& N, SDValue &R) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool HexagonDAGToDAGISel::SelectAddrGA(SDValue &N, SDValue &R) {
|
||||
return SelectGlobalAddress(N, R, false);
|
||||
}
|
||||
|
||||
bool HexagonDAGToDAGISel::SelectGlobalAddress(SDValue &N, SDValue &R,
|
||||
bool UseGP) {
|
||||
switch (N.getOpcode()) {
|
||||
case ISD::ADD: {
|
||||
SDValue N0 = N.getOperand(0);
|
||||
SDValue N1 = N.getOperand(1);
|
||||
unsigned GAOpc = N0.getOpcode();
|
||||
if (UseGP && GAOpc != HexagonISD::CONST32_GP)
|
||||
return false;
|
||||
if (!UseGP && GAOpc != HexagonISD::CONST32)
|
||||
return false;
|
||||
if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1)) {
|
||||
SDValue Addr = N0.getOperand(0);
|
||||
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Addr)) {
|
||||
if (GA->getOpcode() == ISD::TargetGlobalAddress) {
|
||||
uint64_t NewOff = GA->getOffset() + (uint64_t)Const->getSExtValue();
|
||||
R = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(Const),
|
||||
N.getValueType(), NewOff);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HexagonISD::CONST32:
|
||||
// The operand(0) of CONST32 is TargetGlobalAddress, which is what we
|
||||
// want in the instruction.
|
||||
if (!UseGP)
|
||||
R = N.getOperand(0);
|
||||
return !UseGP;
|
||||
case HexagonISD::CONST32_GP:
|
||||
if (UseGP)
|
||||
R = N.getOperand(0);
|
||||
return UseGP;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HexagonDAGToDAGISel::isValueExtension(SDValue const &Val,
|
||||
unsigned FromBits, SDValue &Src) {
|
||||
unsigned Opc = Val.getOpcode();
|
||||
|
@ -11,6 +11,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def addrga: PatLeaf<(i32 AddrGA:$Addr)>;
|
||||
|
||||
let hasSideEffects = 0 in
|
||||
class T_Immext<Operand ImmType>
|
||||
: EXTENDERInst<(outs), (ins ImmType:$imm),
|
||||
@ -332,6 +334,12 @@ def A4_combineii: ALU32Inst<(outs DoubleRegs:$Rdd), (ins s8Imm:$s8, u6Ext:$U6),
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LD +
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def Zext64: OutPatFrag<(ops node:$Rs),
|
||||
(i64 (A4_combineir 0, (i32 $Rs)))>;
|
||||
def Sext64: OutPatFrag<(ops node:$Rs),
|
||||
(i64 (A2_sxtw (i32 $Rs)))>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Template class for load instructions with Absolute set addressing mode.
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -3633,6 +3641,13 @@ let isNVStorable = 0, accessSize = HalfWordAccess in
|
||||
def S2_storerfgp : T_StoreGP <"memh", "STrif", IntRegs,
|
||||
u16_1Imm, 0b01, 1>, PredNewRel;
|
||||
|
||||
class Loada_pat<PatFrag Load, ValueType VT, PatFrag Addr, InstHexagon MI>
|
||||
: Pat<(VT (Load Addr:$addr)), (MI Addr:$addr)>;
|
||||
|
||||
class Loadam_pat<PatFrag Load, ValueType VT, PatFrag Addr, PatFrag ValueMod,
|
||||
InstHexagon MI>
|
||||
: Pat<(VT (Load Addr:$addr)), (ValueMod (MI Addr:$addr))>;
|
||||
|
||||
let Predicates = [HasV4T], AddedComplexity = 30 in {
|
||||
def : Pat<(truncstorei8 (i32 IntRegs:$src1),
|
||||
(HexagonCONST32 tglobaladdr:$absaddr)),
|
||||
@ -4019,84 +4034,21 @@ def : Pat<(i64 (cttz (i64 DoubleRegs:$src1))),
|
||||
(i64 (A4_combineir (i32 0), (i32 (S2_ct0p DoubleRegs:$src1))))>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
|
||||
// i8 -> i64 loads
|
||||
// i8/i16/i32 -> i64 loads
|
||||
// We need a complexity of 120 here to override preceding handling of
|
||||
// zextloadi8.
|
||||
let Predicates = [HasV4T], AddedComplexity = 120 in {
|
||||
def: Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
|
||||
(i64 (A4_combineir 0, (L4_loadrb_abs tglobaladdr:$addr)))>;
|
||||
|
||||
def: Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
|
||||
(i64 (A4_combineir 0, (L4_loadrub_abs tglobaladdr:$addr)))>;
|
||||
|
||||
def: Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
|
||||
(i64 (A2_sxtw (L4_loadrb_abs tglobaladdr:$addr)))>;
|
||||
|
||||
def: Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)),
|
||||
(i64 (A4_combineir 0, (L4_loadrb_abs FoldGlobalAddr:$addr)))>;
|
||||
|
||||
def: Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)),
|
||||
(i64 (A4_combineir 0, (L4_loadrub_abs FoldGlobalAddr:$addr)))>;
|
||||
|
||||
def: Pat <(i64 (sextloadi8 FoldGlobalAddr:$addr)),
|
||||
(i64 (A2_sxtw (L4_loadrb_abs FoldGlobalAddr:$addr)))>;
|
||||
}
|
||||
// i16 -> i64 loads
|
||||
// We need a complexity of 120 here to override preceding handling of
|
||||
// zextloadi16.
|
||||
// zextload.
|
||||
let AddedComplexity = 120 in {
|
||||
def: Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
|
||||
(i64 (A4_combineir 0, (L4_loadrh_abs tglobaladdr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
def: Loadam_pat<extloadi8, i64, addrga, Zext64, L4_loadrub_abs>;
|
||||
def: Loadam_pat<sextloadi8, i64, addrga, Sext64, L4_loadrb_abs>;
|
||||
def: Loadam_pat<zextloadi8, i64, addrga, Zext64, L4_loadrub_abs>;
|
||||
|
||||
def: Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
|
||||
(i64 (A4_combineir 0, (L4_loadruh_abs tglobaladdr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
def: Loadam_pat<extloadi16, i64, addrga, Zext64, L4_loadruh_abs>;
|
||||
def: Loadam_pat<sextloadi16, i64, addrga, Sext64, L4_loadrh_abs>;
|
||||
def: Loadam_pat<zextloadi16, i64, addrga, Zext64, L4_loadruh_abs>;
|
||||
|
||||
def: Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
|
||||
(i64 (A2_sxtw (L4_loadrh_abs tglobaladdr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def: Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)),
|
||||
(i64 (A4_combineir 0, (L4_loadrh_abs FoldGlobalAddr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def: Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)),
|
||||
(i64 (A4_combineir 0, (L4_loadruh_abs FoldGlobalAddr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def: Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)),
|
||||
(i64 (A2_sxtw (L4_loadrh_abs FoldGlobalAddr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
}
|
||||
// i32->i64 loads
|
||||
// We need a complexity of 120 here to override preceding handling of
|
||||
// zextloadi32.
|
||||
let AddedComplexity = 120 in {
|
||||
def: Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
|
||||
(i64 (A4_combineir 0, (L4_loadri_abs tglobaladdr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def: Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
|
||||
(i64 (A4_combineir 0, (L4_loadri_abs tglobaladdr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def: Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
|
||||
(i64 (A2_sxtw (L4_loadri_abs tglobaladdr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def: Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)),
|
||||
(i64 (A4_combineir 0, (L4_loadri_abs FoldGlobalAddr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def: Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)),
|
||||
(i64 (A4_combineir 0, (L4_loadri_abs FoldGlobalAddr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def: Pat <(i64 (sextloadi32 FoldGlobalAddr:$addr)),
|
||||
(i64 (A2_sxtw (L4_loadri_abs FoldGlobalAddr:$addr)))>,
|
||||
Requires<[HasV4T]>;
|
||||
def: Loadam_pat<extloadi32, i64, addrga, Zext64, L4_loadri_abs>;
|
||||
def: Loadam_pat<sextloadi32, i64, addrga, Sext64, L4_loadri_abs>;
|
||||
def: Loadam_pat<zextloadi32, i64, addrga, Zext64, L4_loadri_abs>;
|
||||
}
|
||||
|
||||
// Indexed store double word - global address.
|
||||
|
@ -826,6 +826,11 @@ def u6_3ExtPred : PatLeaf<(i32 imm), [{
|
||||
// in the patterns.
|
||||
def AddrFI : ComplexPattern<i32, 1, "SelectAddrFI", [frameindex], []>;
|
||||
|
||||
// These complex patterns are not strictly necessary, since global address
|
||||
// folding will happen during DAG combining. For distinguishing between GA
|
||||
// and GP, pat frags with HexagonCONST32 and HexagonCONST32_GP can be used.
|
||||
def AddrGA : ComplexPattern<i32, 1, "SelectAddrGA", [], []>;
|
||||
|
||||
// Addressing modes.
|
||||
|
||||
def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
|
||||
|
Loading…
x
Reference in New Issue
Block a user