Hexagon: Use multiclass for gp-relative instructions.

Remove noV4T gp-relative instructions.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178246 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jyotsna Verma 2013-03-28 16:25:57 +00:00
parent aab2305454
commit 4f2ef94d6a
3 changed files with 237 additions and 1094 deletions

View File

@ -1029,20 +1029,6 @@ def : Pat < (i64 (load (add IntRegs:$src1, s11_3ExtPred:$offset))),
(LDrid_indexed IntRegs:$src1, s11_3ExtPred:$offset) >;
}
let neverHasSideEffects = 1 in
def LDrid_GP : LDInst2<(outs DoubleRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst = memd(#$global+$offset)",
[]>,
Requires<[NoV4T]>;
let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDd_GP : LDInst2<(outs DoubleRegs:$dst),
(ins globaladdress:$global),
"$dst = memd(#$global)",
[]>,
Requires<[NoV4T]>;
//===----------------------------------------------------------------------===//
// Post increment load
// Make sure that in post increment load, the first operand is always the post
@ -1115,27 +1101,6 @@ let AddedComplexity = 20 in
def : Pat < (i32 (extloadi8 (add IntRegs:$src1, s11_0ImmPred:$offset))),
(i32 (LDrib_indexed IntRegs:$src1, s11_0ImmPred:$offset)) >;
let neverHasSideEffects = 1 in
def LDrib_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst = memb(#$global+$offset)",
[]>,
Requires<[NoV4T]>;
let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDb_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst = memb(#$global)",
[]>,
Requires<[NoV4T]>;
let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDub_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst = memub(#$global)",
[]>,
Requires<[NoV4T]>;
def : Pat < (i32 (extloadi16 ADDRriS11_1:$addr)),
(i32 (LDrih ADDRriS11_1:$addr))>;
@ -1143,27 +1108,6 @@ let AddedComplexity = 20 in
def : Pat < (i32 (extloadi16 (add IntRegs:$src1, s11_1ImmPred:$offset))),
(i32 (LDrih_indexed IntRegs:$src1, s11_1ImmPred:$offset)) >;
let neverHasSideEffects = 1 in
def LDrih_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst = memh(#$global+$offset)",
[]>,
Requires<[NoV4T]>;
let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDh_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst = memh(#$global)",
[]>,
Requires<[NoV4T]>;
let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDuh_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst = memuh(#$global)",
[]>,
Requires<[NoV4T]>;
let AddedComplexity = 10 in
def : Pat < (i32 (zextloadi1 ADDRriS11_0:$addr)),
(i32 (LDriub ADDRriS11_0:$addr))>;
@ -1172,21 +1116,6 @@ let AddedComplexity = 20 in
def : Pat < (i32 (zextloadi1 (add IntRegs:$src1, s11_0ImmPred:$offset))),
(i32 (LDriub_indexed IntRegs:$src1, s11_0ImmPred:$offset))>;
let neverHasSideEffects = 1 in
def LDriub_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst = memub(#$global+$offset)",
[]>,
Requires<[NoV4T]>;
// Load unsigned halfword.
let neverHasSideEffects = 1 in
def LDriuh_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst = memuh(#$global+$offset)",
[]>,
Requires<[NoV4T]>;
// Load predicate.
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
isPseudo = 1, Defs = [R10,R11,D5], neverHasSideEffects = 1 in
@ -1195,21 +1124,6 @@ def LDriw_pred : LDInst2<(outs PredRegs:$dst),
"Error; should not emit",
[]>;
// Indexed load.
let neverHasSideEffects = 1 in
def LDriw_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst = memw(#$global+$offset)",
[]>,
Requires<[NoV4T]>;
let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDw_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst = memw(#$global)",
[]>,
Requires<[NoV4T]>;
// Deallocate stack frame.
let Defs = [R29, R30, R31], Uses = [R29], neverHasSideEffects = 1 in {
def DEALLOCFRAME : LDInst2<(outs), (ins),
@ -1443,28 +1357,8 @@ def SUBri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
// ST +
//===----------------------------------------------------------------------===//
///
/// Assumptions::: ****** DO NOT IGNORE ********
/// 1. Make sure that in post increment store, the zero'th operand is always the
/// post increment operand.
/// 2. Make sure that the store value operand(Rt/Rtt) in a store is always the
/// last operand.
///
// Store doubleword.
let neverHasSideEffects = 1 in
def STrid_GP : STInst2<(outs),
(ins globaladdress:$global, u16Imm:$offset, DoubleRegs:$src),
"memd(#$global+$offset) = $src",
[]>,
Requires<[NoV4T]>;
let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def STd_GP : STInst2<(outs),
(ins globaladdress:$global, DoubleRegs:$src),
"memd(#$global) = $src",
[]>,
Requires<[NoV4T]>;
//===----------------------------------------------------------------------===//
// Post increment store
//===----------------------------------------------------------------------===//
@ -1675,36 +1569,6 @@ def : Pat<(store (i64 DoubleRegs:$src1), (add IntRegs:$src2,
(i64 DoubleRegs:$src1))>;
}
// memb(gp+#u16:0)=Rt
let neverHasSideEffects = 1 in
def STrib_GP : STInst2<(outs),
(ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
"memb(#$global+$offset) = $src",
[]>,
Requires<[NoV4T]>;
// memb(#global)=Rt
let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def STb_GP : STInst2<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memb(#$global) = $src",
[]>,
Requires<[NoV4T]>;
let neverHasSideEffects = 1 in
def STrih_GP : STInst2<(outs),
(ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
"memh(#$global+$offset) = $src",
[]>,
Requires<[NoV4T]>;
let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def STh_GP : STInst2<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memh(#$global) = $src",
[]>,
Requires<[NoV4T]>;
// memh(Rx++#s4:1)=Rt.H
// Store word.
@ -1715,20 +1579,6 @@ def STriw_pred : STInst2<(outs),
"Error; should not emit",
[]>;
let neverHasSideEffects = 1 in
def STriw_GP : STInst2<(outs),
(ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
"memw(#$global+$offset) = $src",
[]>,
Requires<[NoV4T]>;
let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def STw_GP : STInst2<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memw(#$global) = $src",
[]>,
Requires<[NoV4T]>;
// Allocate stack frame.
let Defs = [R29, R30], Uses = [R31, R30], neverHasSideEffects = 1 in {
def ALLOCFRAME : STInst2<(outs),
@ -2203,68 +2053,26 @@ def : Pat<(HexagonTCRet (i32 IntRegs:$dst)),
// Atomic load and store support
// 8 bit atomic load
def : Pat<(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
(i32 (LDub_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
def : Pat<(atomic_load_8 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset)),
(i32 (LDriub_GP tglobaladdr:$global, u16ImmPred:$offset))>,
Requires<[NoV4T]>;
def : Pat<(atomic_load_8 ADDRriS11_0:$src1),
(i32 (LDriub ADDRriS11_0:$src1))>;
def : Pat<(atomic_load_8 (add (i32 IntRegs:$src1), s11_0ImmPred:$offset)),
(i32 (LDriub_indexed (i32 IntRegs:$src1), s11_0ImmPred:$offset))>;
// 16 bit atomic load
def : Pat<(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
(i32 (LDuh_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
def : Pat<(atomic_load_16 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset)),
(i32 (LDriuh_GP tglobaladdr:$global, u16ImmPred:$offset))>,
Requires<[NoV4T]>;
def : Pat<(atomic_load_16 ADDRriS11_1:$src1),
(i32 (LDriuh ADDRriS11_1:$src1))>;
def : Pat<(atomic_load_16 (add (i32 IntRegs:$src1), s11_1ImmPred:$offset)),
(i32 (LDriuh_indexed (i32 IntRegs:$src1), s11_1ImmPred:$offset))>;
// 32 bit atomic load
def : Pat<(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
(i32 (LDw_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
def : Pat<(atomic_load_32 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset)),
(i32 (LDriw_GP tglobaladdr:$global, u16ImmPred:$offset))>,
Requires<[NoV4T]>;
def : Pat<(atomic_load_32 ADDRriS11_2:$src1),
(i32 (LDriw ADDRriS11_2:$src1))>;
def : Pat<(atomic_load_32 (add (i32 IntRegs:$src1), s11_2ImmPred:$offset)),
(i32 (LDriw_indexed (i32 IntRegs:$src1), s11_2ImmPred:$offset))>;
// 64 bit atomic load
def : Pat<(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
(i64 (LDd_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
def : Pat<(atomic_load_64 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset)),
(i64 (LDrid_GP tglobaladdr:$global, u16ImmPred:$offset))>,
Requires<[NoV4T]>;
def : Pat<(atomic_load_64 ADDRriS11_3:$src1),
(i64 (LDrid ADDRriS11_3:$src1))>;
@ -2272,30 +2080,6 @@ def : Pat<(atomic_load_64 (add (i32 IntRegs:$src1), s11_3ImmPred:$offset)),
(i64 (LDrid_indexed (i32 IntRegs:$src1), s11_3ImmPred:$offset))>;
// 64 bit atomic store
def : Pat<(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
(i64 DoubleRegs:$src1)),
(STd_GP tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
Requires<[NoV4T]>;
def : Pat<(atomic_store_64 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset),
(i64 DoubleRegs:$src1)),
(STrid_GP tglobaladdr:$global, u16ImmPred:$offset,
(i64 DoubleRegs:$src1))>, Requires<[NoV4T]>;
// 8 bit atomic store
def : Pat<(atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
(STb_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
Requires<[NoV4T]>;
def : Pat<(atomic_store_8 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset),
(i32 IntRegs:$src1)),
(STrib_GP tglobaladdr:$global, u16ImmPred:$offset,
(i32 IntRegs:$src1))>, Requires<[NoV4T]>;
def : Pat<(atomic_store_8 ADDRriS11_0:$src2, (i32 IntRegs:$src1)),
(STrib ADDRriS11_0:$src2, (i32 IntRegs:$src1))>;
@ -2305,18 +2089,6 @@ def : Pat<(atomic_store_8 (add (i32 IntRegs:$src2), s11_0ImmPred:$offset),
(i32 IntRegs:$src1))>;
// 16 bit atomic store
def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
(STh_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
Requires<[NoV4T]>;
def : Pat<(atomic_store_16 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset),
(i32 IntRegs:$src1)),
(STrih_GP tglobaladdr:$global, u16ImmPred:$offset,
(i32 IntRegs:$src1))>, Requires<[NoV4T]>;
def : Pat<(atomic_store_16 ADDRriS11_1:$src2, (i32 IntRegs:$src1)),
(STrih ADDRriS11_1:$src2, (i32 IntRegs:$src1))>;
@ -2325,20 +2097,6 @@ def : Pat<(atomic_store_16 (i32 IntRegs:$src1),
(STrih_indexed (i32 IntRegs:$src2), s11_1ImmPred:$offset,
(i32 IntRegs:$src1))>;
// 32 bit atomic store
def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
(STw_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
Requires<[NoV4T]>;
def : Pat<(atomic_store_32 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset),
(i32 IntRegs:$src1)),
(STriw_GP tglobaladdr:$global, u16ImmPred:$offset,
(i32 IntRegs:$src1))>,
Requires<[NoV4T]>;
def : Pat<(atomic_store_32 ADDRriS11_2:$src2, (i32 IntRegs:$src1)),
(STriw ADDRriS11_2:$src2, (i32 IntRegs:$src1))>;
@ -2407,198 +2165,8 @@ def : Pat <(brcond (not PredRegs:$src1), bb:$offset),
def : Pat <(and PredRegs:$src1, (not PredRegs:$src2)),
(i1 (AND_pnotp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
// Map from store(globaladdress + x) -> memd(#foo + x).
let AddedComplexity = 100 in
def : Pat <(store (i64 DoubleRegs:$src1),
(add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset)),
(STrid_GP tglobaladdr:$global, u16ImmPred:$offset,
(i64 DoubleRegs:$src1))>, Requires<[NoV4T]>;
// Map from store(globaladdress) -> memd(#foo).
let AddedComplexity = 100 in
def : Pat <(store (i64 DoubleRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
(STd_GP tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
Requires<[NoV4T]>;
// Map from store(globaladdress + x) -> memw(#foo + x).
let AddedComplexity = 100 in
def : Pat <(store (i32 IntRegs:$src1),
(add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset)),
(STriw_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
Requires<[NoV4T]>;
// Map from store(globaladdress) -> memw(#foo + 0).
let AddedComplexity = 100 in
def : Pat <(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
(STriw_GP tglobaladdr:$global, 0, (i32 IntRegs:$src1))>;
// Map from store(globaladdress) -> memw(#foo).
let AddedComplexity = 100 in
def : Pat <(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
(STriw_GP tglobaladdr:$global, 0, (i32 IntRegs:$src1))>,
Requires<[NoV4T]>;
// Map from store(globaladdress + x) -> memh(#foo + x).
let AddedComplexity = 100 in
def : Pat <(truncstorei16 (i32 IntRegs:$src1),
(add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset)),
(STrih_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
Requires<[NoV4T]>;
// Map from store(globaladdress) -> memh(#foo).
let AddedComplexity = 100 in
def : Pat <(truncstorei16 (i32 IntRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
(STh_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
Requires<[NoV4T]>;
// Map from store(globaladdress + x) -> memb(#foo + x).
let AddedComplexity = 100 in
def : Pat <(truncstorei8 (i32 IntRegs:$src1),
(add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset)),
(STrib_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
Requires<[NoV4T]>;
// Map from store(globaladdress) -> memb(#foo).
let AddedComplexity = 100 in
def : Pat <(truncstorei8 (i32 IntRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
(STb_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
Requires<[NoV4T]>;
// Map from load(globaladdress + x) -> memw(#foo + x).
let AddedComplexity = 100 in
def : Pat <(i32 (load (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset))),
(i32 (LDriw_GP tglobaladdr:$global, u16ImmPred:$offset))>,
Requires<[NoV4T]>;
// Map from load(globaladdress) -> memw(#foo).
let AddedComplexity = 100 in
def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDw_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
// Map from load(globaladdress + x) -> memd(#foo + x).
let AddedComplexity = 100 in
def : Pat <(i64 (load (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset))),
(i64 (LDrid_GP tglobaladdr:$global, u16ImmPred:$offset))>,
Requires<[NoV4T]>;
// Map from load(globaladdress) -> memw(#foo + 0).
let AddedComplexity = 100 in
def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
(i64 (LDd_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd.
let AddedComplexity = 100 in
def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
(i1 (TFR_PdRs (i32 (LDb_GP tglobaladdr:$global))))>,
Requires<[NoV4T]>;
// Map from load(globaladdress + x) -> memh(#foo + x).
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi16 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset))),
(i32 (LDrih_GP tglobaladdr:$global, u16ImmPred:$offset))>,
Requires<[NoV4T]>;
// Map from load(globaladdress + x) -> memh(#foo + x).
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDrih_GP tglobaladdr:$global, 0))>,
Requires<[NoV4T]>;
// Map from load(globaladdress + x) -> memuh(#foo + x).
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi16 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset))),
(i32 (LDriuh_GP tglobaladdr:$global, u16ImmPred:$offset))>,
Requires<[NoV4T]>;
// Map from load(globaladdress) -> memuh(#foo).
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDriuh_GP tglobaladdr:$global, 0))>,
Requires<[NoV4T]>;
// Map from load(globaladdress) -> memh(#foo).
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDh_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
// Map from load(globaladdress) -> memuh(#foo).
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDuh_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
// Map from load(globaladdress + x) -> memb(#foo + x).
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset))),
(i32 (LDrib_GP tglobaladdr:$global, u16ImmPred:$offset))>,
Requires<[NoV4T]>;
// Map from load(globaladdress + x) -> memb(#foo + x).
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset))),
(i32 (LDrib_GP tglobaladdr:$global, u16ImmPred:$offset))>,
Requires<[NoV4T]>;
// Map from load(globaladdress + x) -> memub(#foo + x).
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
u16ImmPred:$offset))),
(i32 (LDriub_GP tglobaladdr:$global, u16ImmPred:$offset))>,
Requires<[NoV4T]>;
// Map from load(globaladdress) -> memb(#foo).
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
// Map from load(globaladdress) -> memb(#foo).
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
// Map from load(globaladdress) -> memub(#foo).
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDub_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
// When the Interprocedural Global Variable optimizer realizes that a
// certain global variable takes only two constant values, it shrinks the
// global to a boolean. Catch those loads here in the following 3 patterns.
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDub_GP tglobaladdr:$global))>,
Requires<[NoV4T]>;
// Map from i1 loads to 32 bits. This assumes that the i1* is byte aligned.
let AddedComplexity = 10 in
def : Pat <(i32 (zextloadi1 ADDRriS11_0:$addr)),
(i32 (AND_rr (i32 (LDrib ADDRriS11_0:$addr)), (TFRI 0x1)))>;
@ -2714,12 +2282,6 @@ def : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
(STrib ADDRriS11_2:$addr, (TFRI 1))>;
let AddedComplexity = 100 in
// Map from i1 = constant<-1>; memw(CONST32(#foo)) = i1 -> r0 = 1;
// memw(#foo) = r0
def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
(STb_GP tglobaladdr:$global, (TFRI 1))>,
Requires<[NoV4T]>;
// Map from i1 = constant<-1>; store i1 -> r0 = 1; store r0.
def : Pat<(store (i1 -1), ADDRriS11_2:$addr),

View File

@ -438,329 +438,6 @@ def : Pat <(i32 (load (add IntRegs:$src1, IntRegs:$src2))),
Requires<[HasV4T]>;
}
let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDd_GP_V4 : LDInst2<(outs DoubleRegs:$dst),
(ins globaladdress:$global),
"$dst=memd(#$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rtt=memd(##global)
let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
validSubTargets = HasV4SubT in {
def LDd_GP_cPt_V4 : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1) $dst=memd(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rtt=memd(##global)
def LDd_GP_cNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memd(##$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rtt=memd(##global)
def LDd_GP_cdnPt_V4 : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memd(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rtt=memd(##global)
def LDd_GP_cdnNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1.new) $dst=memd(##$global)",
[]>,
Requires<[HasV4T]>;
}
let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDb_GP_V4 : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memb(#$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rt=memb(##global)
let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
validSubTargets = HasV4SubT in {
def LDb_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1) $dst=memb(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rt=memb(##global)
def LDb_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memb(##$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rt=memb(##global)
def LDb_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memb(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rt=memb(##global)
def LDb_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1.new) $dst=memb(##$global)",
[]>,
Requires<[HasV4T]>;
}
let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDub_GP_V4 : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memub(#$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rt=memub(##global)
let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
validSubTargets = HasV4SubT in {
def LDub_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1) $dst=memub(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rt=memub(##global)
def LDub_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memub(##$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rt=memub(##global)
def LDub_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memub(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rt=memub(##global)
def LDub_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1.new) $dst=memub(##$global)",
[]>,
Requires<[HasV4T]>;
}
let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDh_GP_V4 : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memh(#$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rt=memh(##global)
let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
validSubTargets = HasV4SubT in {
def LDh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1) $dst=memh(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rt=memh(##global)
def LDh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memh(##$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rt=memh(##global)
def LDh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memh(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rt=memh(##global)
def LDh_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1.new) $dst=memh(##$global)",
[]>,
Requires<[HasV4T]>;
}
let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDuh_GP_V4 : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memuh(#$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rt=memuh(##global)
let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
validSubTargets = HasV4SubT in {
def LDuh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1) $dst=memuh(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rt=memuh(##global)
def LDuh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memuh(##$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rt=memuh(##global)
def LDuh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memuh(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rt=memuh(##global)
def LDuh_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1.new) $dst=memuh(##$global)",
[]>,
Requires<[HasV4T]>;
}
let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDw_GP_V4 : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memw(#$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rt=memw(##global)
let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
validSubTargets = HasV4SubT in {
def LDw_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1) $dst=memw(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rt=memw(##global)
def LDw_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memw(##$global)",
[]>,
Requires<[HasV4T]>;
// if (Pv) Rt=memw(##global)
def LDw_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memw(##$global)",
[]>,
Requires<[HasV4T]>;
// if (!Pv) Rt=memw(##global)
def LDw_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1.new) $dst=memw(##$global)",
[]>,
Requires<[HasV4T]>;
}
def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
(i64 (LDd_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
(i32 (LDw_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
(i32 (LDuh_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
(i32 (LDub_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
// Map from load(globaladdress) -> memw(#foo + 0)
let AddedComplexity = 100 in
def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
(i64 (LDd_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
let AddedComplexity = 100 in
def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
(i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>,
Requires<[HasV4T]>;
// When the Interprocedural Global Variable optimizer realizes that a certain
// global variable takes only two constant values, it shrinks the global to
// a boolean. Catch those loads here in the following 3 patterns.
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
// Map from load(globaladdress) -> memb(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
// Map from load(globaladdress) -> memb(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDub_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
// Map from load(globaladdress) -> memub(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDub_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
// Map from load(globaladdress) -> memh(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDh_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
// Map from load(globaladdress) -> memh(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDh_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
// Map from load(globaladdress) -> memuh(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDuh_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
// Map from load(globaladdress) -> memw(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDw_GP_V4 tglobaladdr:$global))>,
Requires<[HasV4T]>;
// zext i1->i64
def : Pat <(i64 (zext (i1 PredRegs:$src1))),
(i64 (COMBINE_Ir_V4 0, (MUX_ii (i1 PredRegs:$src1), 1, 0)))>,
@ -1216,225 +893,6 @@ def STriw_shl_V4 : STInst<(outs),
// memw(Rx++I:circ(Mu))=Rt
// memw(Rx++Mu)=Rt
// memw(Rx++Mu:brev)=Rt
// memw(gp+#u16:2)=Rt
// memd(#global)=Rtt
let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1,
validSubTargets = HasV4SubT in
def STd_GP_V4 : STInst2<(outs),
(ins globaladdress:$global, DoubleRegs:$src),
"memd(#$global) = $src",
[]>,
Requires<[HasV4T]>;
// if (Pv) memd(##global) = Rtt
let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1,
isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
def STd_GP_cPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
"if ($src1) memd(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memd(##global) = Rtt
def STd_GP_cNotPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
"if (!$src1) memd(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (Pv) memd(##global) = Rtt
def STd_GP_cdnPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
"if ($src1.new) memd(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memd(##global) = Rtt
def STd_GP_cdnNotPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
"if (!$src1.new) memd(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
}
// memb(#global)=Rt
let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
validSubTargets = HasV4SubT in
def STb_GP_V4 : STInst2<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memb(#$global) = $src",
[]>,
Requires<[HasV4T]>;
// if (Pv) memb(##global) = Rt
let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
def STb_GP_cPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1) memb(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memb(##global) = Rt
def STb_GP_cNotPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1) memb(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (Pv) memb(##global) = Rt
def STb_GP_cdnPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1.new) memb(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memb(##global) = Rt
def STb_GP_cdnNotPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1.new) memb(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
}
// memh(#global)=Rt
let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
validSubTargets = HasV4SubT in
def STh_GP_V4 : STInst2<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memh(#$global) = $src",
[]>,
Requires<[HasV4T]>;
// if (Pv) memh(##global) = Rt
let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
def STh_GP_cPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1) memh(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memh(##global) = Rt
def STh_GP_cNotPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1) memh(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (Pv) memh(##global) = Rt
def STh_GP_cdnPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1.new) memh(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memh(##global) = Rt
def STh_GP_cdnNotPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1.new) memh(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
}
// memw(#global)=Rt
let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
validSubTargets = HasV4SubT in
def STw_GP_V4 : STInst2<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memw(#$global) = $src",
[]>,
Requires<[HasV4T]>;
// if (Pv) memw(##global) = Rt
let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
def STw_GP_cPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1) memw(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memw(##global) = Rt
def STw_GP_cNotPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1) memw(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (Pv) memw(##global) = Rt
def STw_GP_cdnPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1.new) memw(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memw(##global) = Rt
def STw_GP_cdnNotPt_V4 : STInst2<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1.new) memw(##$global) = $src2",
[]>,
Requires<[HasV4T]>;
}
// 64 bit atomic store
def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
(i64 DoubleRegs:$src1)),
(STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
Requires<[HasV4T]>;
// Map from store(globaladdress) -> memd(#foo)
let AddedComplexity = 100 in
def : Pat <(store (i64 DoubleRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
(STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
Requires<[HasV4T]>;
// 8 bit atomic store
def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
(STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
// Map from store(globaladdress) -> memb(#foo)
let AddedComplexity = 100 in
def : Pat<(truncstorei8 (i32 IntRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
(STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
// to "r0 = 1; memw(#foo) = r0"
let AddedComplexity = 100 in
def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
(STb_GP_V4 tglobaladdr:$global, (TFRI 1))>,
Requires<[HasV4T]>;
def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
(STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
// Map from store(globaladdress) -> memh(#foo)
let AddedComplexity = 100 in
def : Pat<(truncstorei16 (i32 IntRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
(STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
// 32 bit atomic store
def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
(STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
// Map from store(globaladdress) -> memw(#foo)
let AddedComplexity = 100 in
def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
(STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
//===----------------------------------------------------------------------===
// ST -
@ -1614,15 +1072,6 @@ defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
// memb(Rx++I:circ(Mu))=Nt.new
// memb(Rx++Mu)=Nt.new
// memb(Rx++Mu:brev)=Nt.new
// memb(#global)=Nt.new
let mayStore = 1, neverHasSideEffects = 1 in
def STb_GP_nv_V4 : NVInst_V4<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memb(#$global) = $src.new",
[]>,
Requires<[HasV4T]>;
// memh(Ru<<#u2+#U6)=Nt.new
let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
isNVStore = 1, validSubTargets = HasV4SubT in
@ -1637,14 +1086,6 @@ def STrih_shl_nv_V4 : NVInst_V4<(outs),
// memh(Rx++Mu)=Nt.new
// memh(Rx++Mu:brev)=Nt.new
// memh(#global)=Nt.new
let mayStore = 1, neverHasSideEffects = 1 in
def STh_GP_nv_V4 : NVInst_V4<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memh(#$global) = $src.new",
[]>,
Requires<[HasV4T]>;
// memw(Ru<<#u2+#U6)=Nt.new
let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
isNVStore = 1, validSubTargets = HasV4SubT in
@ -1658,102 +1099,6 @@ def STriw_shl_nv_V4 : NVInst_V4<(outs),
// memw(Rx++I:circ(Mu))=Nt.new
// memw(Rx++Mu)=Nt.new
// memw(Rx++Mu:brev)=Nt.new
// memw(gp+#u16:2)=Nt.new
let mayStore = 1, neverHasSideEffects = 1, isNVStore = 1,
validSubTargets = HasV4SubT in
def STw_GP_nv_V4 : NVInst_V4<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memw(#$global) = $src.new",
[]>,
Requires<[HasV4T]>;
// if (Pv) memb(##global) = Rt
let mayStore = 1, neverHasSideEffects = 1, isNVStore = 1,
isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
def STb_GP_cPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1) memb(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memb(##global) = Rt
def STb_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1) memb(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
// if (Pv) memb(##global) = Rt
def STb_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1.new) memb(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memb(##global) = Rt
def STb_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1.new) memb(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
// if (Pv) memh(##global) = Rt
def STh_GP_cPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1) memh(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memh(##global) = Rt
def STh_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1) memh(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
// if (Pv) memh(##global) = Rt
def STh_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1.new) memh(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memh(##global) = Rt
def STh_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1.new) memh(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
// if (Pv) memw(##global) = Rt
def STw_GP_cPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1) memw(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memw(##global) = Rt
def STw_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1) memw(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
// if (Pv) memw(##global) = Rt
def STw_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if ($src1.new) memw(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
// if (!Pv) memw(##global) = Rt
def STw_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
"if (!$src1.new) memw(##$global) = $src2.new",
[]>,
Requires<[HasV4T]>;
}
//===----------------------------------------------------------------------===//
// NV/ST -
@ -3525,6 +2870,108 @@ def : Pat<(store (i64 DoubleRegs:$src1),
(STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>;
}
//===----------------------------------------------------------------------===//
// multiclass for store instructions with GP-relative addressing mode.
// mem[bhwd](#global)=Rt
// if ([!]Pv[.new]) mem[bhwd](##global) = Rt
//===----------------------------------------------------------------------===//
multiclass ST_GP<string mnemonic, string BaseOp, RegisterClass RC> {
let BaseOpcode = BaseOp, isPredicable = 1 in
def NAME#_V4 : STInst2<(outs),
(ins globaladdress:$global, RC:$src),
mnemonic#"(#$global) = $src",
[]>;
// When GP-relative instructions are predicated, their addressing mode is
// changed to absolute and they are always constant extended.
let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
isPredicated = 1 in {
defm Pt : ST_Abs_Pred <mnemonic, RC, 0>;
defm NotPt : ST_Abs_Pred <mnemonic, RC, 1>;
}
}
let mayStore = 1, isNVStore = 1 in
multiclass ST_GP_nv<string mnemonic, string BaseOp, RegisterClass RC> {
let BaseOpcode = BaseOp, isPredicable = 1 in
def NAME#_nv_V4 : NVInst_V4<(outs),
(ins u0AlwaysExt:$global, RC:$src),
mnemonic#"(#$global) = $src.new",
[]>,
Requires<[HasV4T]>;
// When GP-relative instructions are predicated, their addressing mode is
// changed to absolute and they are always constant extended.
let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
isPredicated = 1 in {
defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
}
}
let validSubTargets = HasV4SubT, validSubTargets = HasV4SubT in {
defm STd_GP : ST_GP <"memd", "STd_GP", DoubleRegs>,
ST_GP_nv<"memd", "STd_GP", DoubleRegs>, NewValueRel ;
defm STb_GP : ST_GP<"memb", "STb_GP", IntRegs>,
ST_GP_nv<"memb", "STb_GP", IntRegs>, NewValueRel ;
defm STh_GP : ST_GP<"memh", "STh_GP", IntRegs>,
ST_GP_nv<"memh", "STh_GP", IntRegs>, NewValueRel ;
defm STw_GP : ST_GP<"memw", "STw_GP", IntRegs>,
ST_GP_nv<"memw", "STw_GP", IntRegs>, NewValueRel ;
}
// 64 bit atomic store
def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
(i64 DoubleRegs:$src1)),
(STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
Requires<[HasV4T]>;
// Map from store(globaladdress) -> memd(#foo)
let AddedComplexity = 100 in
def : Pat <(store (i64 DoubleRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
(STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>;
// 8 bit atomic store
def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
(STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
// Map from store(globaladdress) -> memb(#foo)
let AddedComplexity = 100 in
def : Pat<(truncstorei8 (i32 IntRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
(STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
// to "r0 = 1; memw(#foo) = r0"
let AddedComplexity = 100 in
def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
(STb_GP_V4 tglobaladdr:$global, (TFRI 1))>;
def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
(STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
// Map from store(globaladdress) -> memh(#foo)
let AddedComplexity = 100 in
def : Pat<(truncstorei16 (i32 IntRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
(STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
// 32 bit atomic store
def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
(STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
// Map from store(globaladdress) -> memw(#foo)
let AddedComplexity = 100 in
def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
(STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
//===----------------------------------------------------------------------===//
// Multiclass for the load instructions with absolute addressing mode.
//===----------------------------------------------------------------------===//
multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
let PNewValue = !if(isPredNew, "new", "") in
@ -3590,6 +3037,107 @@ let Predicates = [HasV4T], AddedComplexity=30 in
def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
(LDriuh_abs_V4 tglobaladdr:$absaddr)>;
//===----------------------------------------------------------------------===//
// multiclass for load instructions with GP-relative addressing mode.
// Rx=mem[bhwd](##global)
// if ([!]Pv[.new]) Rx=mem[bhwd](##global)
//===----------------------------------------------------------------------===//
let neverHasSideEffects = 1, validSubTargets = HasV4SubT in
multiclass LD_GP<string mnemonic, string BaseOp, RegisterClass RC> {
let BaseOpcode = BaseOp in {
let isPredicable = 1 in
def NAME#_V4 : LDInst2<(outs RC:$dst),
(ins globaladdress:$global),
"$dst = "#mnemonic#"(#$global)",
[]>;
let isExtended = 1, opExtendable = 2, isPredicated = 1 in {
defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
}
}
}
defm LDd_GP : LD_GP<"memd", "LDd_GP", DoubleRegs>;
defm LDb_GP : LD_GP<"memb", "LDb_GP", IntRegs>;
defm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>;
defm LDh_GP : LD_GP<"memh", "LDh_GP", IntRegs>;
defm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>;
defm LDw_GP : LD_GP<"memw", "LDw_GP", IntRegs>;
def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
(i64 (LDd_GP_V4 tglobaladdr:$global))>;
def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
(i32 (LDw_GP_V4 tglobaladdr:$global))>;
def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
(i32 (LDuh_GP_V4 tglobaladdr:$global))>;
def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
(i32 (LDub_GP_V4 tglobaladdr:$global))>;
// Map from load(globaladdress) -> memw(#foo + 0)
let AddedComplexity = 100 in
def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
(i64 (LDd_GP_V4 tglobaladdr:$global))>;
// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
let AddedComplexity = 100 in
def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
(i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>;
// When the Interprocedural Global Variable optimizer realizes that a certain
// global variable takes only two constant values, it shrinks the global to
// a boolean. Catch those loads here in the following 3 patterns.
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP_V4 tglobaladdr:$global))>;
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP_V4 tglobaladdr:$global))>;
// Map from load(globaladdress) -> memb(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP_V4 tglobaladdr:$global))>;
// Map from load(globaladdress) -> memb(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDb_GP_V4 tglobaladdr:$global))>;
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDub_GP_V4 tglobaladdr:$global))>;
// Map from load(globaladdress) -> memub(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDub_GP_V4 tglobaladdr:$global))>;
// Map from load(globaladdress) -> memh(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDh_GP_V4 tglobaladdr:$global))>;
// Map from load(globaladdress) -> memh(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDh_GP_V4 tglobaladdr:$global))>;
// Map from load(globaladdress) -> memuh(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDuh_GP_V4 tglobaladdr:$global))>;
// Map from load(globaladdress) -> memw(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
(i32 (LDw_GP_V4 tglobaladdr:$global))>;
// Transfer global address into a register
let AddedComplexity=50, isMoveImm = 1, isReMaterializable = 1 in
def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$src1),

View File

@ -0,0 +1,33 @@
; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
; Check that gp-relative instructions are being generated.
@a = common global i32 0, align 4
@b = common global i32 0, align 4
@c = common global i32 0, align 4
define i32 @foo(i32 %p) #0 {
entry:
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memw(#a)
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memw(#b)
; CHECK: if{{ *}}(p{{[0-3]}}) memw(##c){{ *}}={{ *}}r{{[0-9]+}}
%0 = load i32* @a, align 4
%1 = load i32* @b, align 4
%add = add nsw i32 %1, %0
%cmp = icmp eq i32 %0, %1
br i1 %cmp, label %if.then, label %entry.if.end_crit_edge
entry.if.end_crit_edge:
%.pre = load i32* @c, align 4
br label %if.end
if.then:
%add1 = add nsw i32 %add, %0
store i32 %add1, i32* @c, align 4
br label %if.end
if.end:
%2 = phi i32 [ %.pre, %entry.if.end_crit_edge ], [ %add1, %if.then ]
%cmp2 = icmp eq i32 %add, %2
%sel1 = select i1 %cmp2, i32 %2, i32 %1
ret i32 %sel1
}