mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Hexagon: Remove duplicate instructions to handle global/immediate values
for absolute/absolute-set addressing modes. llvm-svn: 180120
This commit is contained in:
parent
d8a8d1d02f
commit
20903a7aba
@ -746,11 +746,6 @@ bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
|
||||
case Hexagon::STrib_abs_cdnPt_nv_V4:
|
||||
case Hexagon::STrib_abs_cNotPt_nv_V4:
|
||||
case Hexagon::STrib_abs_cdnNotPt_nv_V4:
|
||||
case Hexagon::STrib_imm_abs_nv_V4:
|
||||
case Hexagon::STrib_imm_abs_cPt_nv_V4:
|
||||
case Hexagon::STrib_imm_abs_cdnPt_nv_V4:
|
||||
case Hexagon::STrib_imm_abs_cNotPt_nv_V4:
|
||||
case Hexagon::STrib_imm_abs_cdnNotPt_nv_V4:
|
||||
|
||||
// Store Halfword
|
||||
case Hexagon::STrih_nv_V4:
|
||||
@ -784,11 +779,6 @@ bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
|
||||
case Hexagon::STrih_abs_cdnPt_nv_V4:
|
||||
case Hexagon::STrih_abs_cNotPt_nv_V4:
|
||||
case Hexagon::STrih_abs_cdnNotPt_nv_V4:
|
||||
case Hexagon::STrih_imm_abs_nv_V4:
|
||||
case Hexagon::STrih_imm_abs_cPt_nv_V4:
|
||||
case Hexagon::STrih_imm_abs_cdnPt_nv_V4:
|
||||
case Hexagon::STrih_imm_abs_cNotPt_nv_V4:
|
||||
case Hexagon::STrih_imm_abs_cdnNotPt_nv_V4:
|
||||
|
||||
// Store Word
|
||||
case Hexagon::STriw_nv_V4:
|
||||
@ -822,11 +812,6 @@ bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
|
||||
case Hexagon::STriw_abs_cdnPt_nv_V4:
|
||||
case Hexagon::STriw_abs_cNotPt_nv_V4:
|
||||
case Hexagon::STriw_abs_cdnNotPt_nv_V4:
|
||||
case Hexagon::STriw_imm_abs_nv_V4:
|
||||
case Hexagon::STriw_imm_abs_cPt_nv_V4:
|
||||
case Hexagon::STriw_imm_abs_cdnPt_nv_V4:
|
||||
case Hexagon::STriw_imm_abs_cNotPt_nv_V4:
|
||||
case Hexagon::STriw_imm_abs_cdnNotPt_nv_V4:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -209,99 +209,25 @@ def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst),
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LD +
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// These absolute set addressing mode instructions accept immediate as
|
||||
// an operand. We have duplicated these patterns to take global address.
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Template class for load instructions with Absolute set addressing mode.
|
||||
//===----------------------------------------------------------------------===//
|
||||
let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
|
||||
validSubTargets = HasV4SubT in {
|
||||
def LDrid_abs_setimm_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
|
||||
validSubTargets = HasV4SubT in
|
||||
class T_LD_abs_set<string mnemonic, RegisterClass RC>:
|
||||
LDInst2<(outs RC:$dst1, IntRegs:$dst2),
|
||||
(ins u0AlwaysExt:$addr),
|
||||
"$dst1 = memd($dst2=##$addr)",
|
||||
"$dst1 = "#mnemonic#"($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// Rd=memb(Re=#U6)
|
||||
def LDrib_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins u0AlwaysExt:$addr),
|
||||
"$dst1 = memb($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
def LDrid_abs_set_V4 : T_LD_abs_set <"memd", DoubleRegs>;
|
||||
def LDrib_abs_set_V4 : T_LD_abs_set <"memb", IntRegs>;
|
||||
def LDriub_abs_set_V4 : T_LD_abs_set <"memub", IntRegs>;
|
||||
def LDrih_abs_set_V4 : T_LD_abs_set <"memh", IntRegs>;
|
||||
def LDriw_abs_set_V4 : T_LD_abs_set <"memw", IntRegs>;
|
||||
def LDriuh_abs_set_V4 : T_LD_abs_set <"memuh", IntRegs>;
|
||||
|
||||
// Rd=memh(Re=#U6)
|
||||
def LDrih_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins u0AlwaysExt:$addr),
|
||||
"$dst1 = memh($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// Rd=memub(Re=#U6)
|
||||
def LDriub_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins u0AlwaysExt:$addr),
|
||||
"$dst1 = memub($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// Rd=memuh(Re=#U6)
|
||||
def LDriuh_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins u0AlwaysExt:$addr),
|
||||
"$dst1 = memuh($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// Rd=memw(Re=#U6)
|
||||
def LDriw_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins u0AlwaysExt:$addr),
|
||||
"$dst1 = memw($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
}
|
||||
|
||||
// Following patterns are defined for absolute set addressing mode
|
||||
// instruction which take global address as operand.
|
||||
let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
|
||||
validSubTargets = HasV4SubT in {
|
||||
def LDrid_abs_set_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
|
||||
(ins globaladdressExt:$addr),
|
||||
"$dst1 = memd($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// Rd=memb(Re=#U6)
|
||||
def LDrib_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins globaladdressExt:$addr),
|
||||
"$dst1 = memb($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// Rd=memh(Re=#U6)
|
||||
def LDrih_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins globaladdressExt:$addr),
|
||||
"$dst1 = memh($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// Rd=memub(Re=#U6)
|
||||
def LDriub_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins globaladdressExt:$addr),
|
||||
"$dst1 = memub($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// Rd=memuh(Re=#U6)
|
||||
def LDriuh_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins globaladdressExt:$addr),
|
||||
"$dst1 = memuh($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// Rd=memw(Re=#U6)
|
||||
def LDriw_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins globaladdressExt:$addr),
|
||||
"$dst1 = memw($dst2=##$addr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
}
|
||||
|
||||
// multiclass for load instructions with base + register offset
|
||||
// addressing mode
|
||||
@ -527,75 +453,26 @@ def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
|
||||
// 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.
|
||||
///
|
||||
|
||||
// memd(Re=#U)=Rtt
|
||||
let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
|
||||
def STrid_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
|
||||
(ins DoubleRegs:$src1, u0AlwaysExt:$src2),
|
||||
"memd($dst1=##$src2) = $src1",
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Template class for store instructions with Absolute set addressing mode.
|
||||
//===----------------------------------------------------------------------===//
|
||||
let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in
|
||||
class T_ST_abs_set<string mnemonic, RegisterClass RC>:
|
||||
STInst2<(outs IntRegs:$dst1),
|
||||
(ins RC:$src1, u0AlwaysExt:$src2),
|
||||
mnemonic#"($dst1=##$src2) = $src1",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// memb(Re=#U)=Rs
|
||||
def STrib_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
|
||||
(ins IntRegs:$src1, u0AlwaysExt:$src2),
|
||||
"memb($dst1=##$src2) = $src1",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// memh(Re=#U)=Rs
|
||||
def STrih_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
|
||||
(ins IntRegs:$src1, u0AlwaysExt:$src2),
|
||||
"memh($dst1=##$src2) = $src1",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// memw(Re=#U)=Rs
|
||||
def STriw_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
|
||||
(ins IntRegs:$src1, u0AlwaysExt:$src2),
|
||||
"memw($dst1=##$src2) = $src1",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
}
|
||||
|
||||
// memd(Re=#U)=Rtt
|
||||
let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
|
||||
def STrid_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
|
||||
(ins DoubleRegs:$src1, globaladdressExt:$src2),
|
||||
"memd($dst1=##$src2) = $src1",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// memb(Re=#U)=Rs
|
||||
def STrib_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
|
||||
(ins IntRegs:$src1, globaladdressExt:$src2),
|
||||
"memb($dst1=##$src2) = $src1",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// memh(Re=#U)=Rs
|
||||
def STrih_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
|
||||
(ins IntRegs:$src1, globaladdressExt:$src2),
|
||||
"memh($dst1=##$src2) = $src1",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// memw(Re=#U)=Rs
|
||||
def STriw_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
|
||||
(ins IntRegs:$src1, globaladdressExt:$src2),
|
||||
"memw($dst1=##$src2) = $src1",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
}
|
||||
def STrid_abs_set_V4 : T_ST_abs_set <"memd", DoubleRegs>;
|
||||
def STrib_abs_set_V4 : T_ST_abs_set <"memb", IntRegs>;
|
||||
def STrih_abs_set_V4 : T_ST_abs_set <"memh", IntRegs>;
|
||||
def STriw_abs_set_V4 : T_ST_abs_set <"memw", IntRegs>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// multiclass for store instructions with base + register offset addressing
|
||||
// mode
|
||||
//===----------------------------------------------------------------------===//
|
||||
multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
|
||||
bit isPredNew> {
|
||||
let isPredicatedNew = isPredNew in
|
||||
@ -2771,7 +2648,7 @@ multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
|
||||
bit isPredNew> {
|
||||
let isPredicatedNew = isPredNew in
|
||||
def NAME#_V4 : STInst2<(outs),
|
||||
(ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
|
||||
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
|
||||
") ")#mnemonic#"(##$absaddr) = $src2",
|
||||
[]>,
|
||||
@ -2791,7 +2668,7 @@ multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
|
||||
let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
|
||||
let opExtendable = 0, isPredicable = 1 in
|
||||
def NAME#_V4 : STInst2<(outs),
|
||||
(ins globaladdressExt:$absaddr, RC:$src),
|
||||
(ins u0AlwaysExt:$absaddr, RC:$src),
|
||||
mnemonic#"(##$absaddr) = $src",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
@ -2807,7 +2684,7 @@ multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
|
||||
bit isPredNew> {
|
||||
let isPredicatedNew = isPredNew in
|
||||
def NAME#_nv_V4 : NVInst_V4<(outs),
|
||||
(ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
|
||||
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
|
||||
") ")#mnemonic#"(##$absaddr) = $src2.new",
|
||||
[]>,
|
||||
@ -2827,7 +2704,7 @@ multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
|
||||
let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
|
||||
let opExtendable = 0, isPredicable = 1 in
|
||||
def NAME#_nv_V4 : NVInst_V4<(outs),
|
||||
(ins globaladdressExt:$absaddr, RC:$src),
|
||||
(ins u0AlwaysExt:$absaddr, RC:$src),
|
||||
mnemonic#"(##$absaddr) = $src.new",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
@ -2840,16 +2717,19 @@ multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
|
||||
}
|
||||
|
||||
let addrMode = Absolute in {
|
||||
let accessSize = ByteAccess in
|
||||
defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
|
||||
ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
|
||||
|
||||
let accessSize = HalfWordAccess in
|
||||
defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
|
||||
ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
|
||||
|
||||
let accessSize = WordAccess in
|
||||
defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
|
||||
ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
|
||||
|
||||
let isNVStorable = 0 in
|
||||
let accessSize = DoubleWordAccess, isNVStorable = 0 in
|
||||
defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
|
||||
}
|
||||
|
||||
@ -2976,7 +2856,7 @@ multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
|
||||
bit isPredNew> {
|
||||
let isPredicatedNew = isPredNew in
|
||||
def NAME : LDInst2<(outs RC:$dst),
|
||||
(ins PredRegs:$src1, globaladdressExt:$absaddr),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$absaddr),
|
||||
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
|
||||
") ")#"$dst = "#mnemonic#"(##$absaddr)",
|
||||
[]>,
|
||||
@ -2996,7 +2876,7 @@ multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
|
||||
let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
|
||||
let opExtendable = 1, isPredicable = 1 in
|
||||
def NAME#_V4 : LDInst2<(outs RC:$dst),
|
||||
(ins globaladdressExt:$absaddr),
|
||||
(ins u0AlwaysExt:$absaddr),
|
||||
"$dst = "#mnemonic#"(##$absaddr)",
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
@ -3009,33 +2889,37 @@ multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
|
||||
}
|
||||
|
||||
let addrMode = Absolute in {
|
||||
let accessSize = ByteAccess in {
|
||||
defm LDrib_abs : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
|
||||
defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
|
||||
}
|
||||
let accessSize = HalfWordAccess in {
|
||||
defm LDrih_abs : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
|
||||
defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
|
||||
}
|
||||
let accessSize = WordAccess in
|
||||
defm LDriw_abs : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
|
||||
|
||||
let accessSize = DoubleWordAccess in
|
||||
defm LDrid_abs : LD_Abs<"memd", "LDrid", DoubleRegs>, AddrModeRel;
|
||||
}
|
||||
|
||||
let Predicates = [HasV4T], AddedComplexity = 30 in
|
||||
let Predicates = [HasV4T], AddedComplexity = 30 in {
|
||||
def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
|
||||
(LDriw_abs_V4 tglobaladdr: $absaddr)>;
|
||||
|
||||
let Predicates = [HasV4T], AddedComplexity=30 in
|
||||
def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
|
||||
(LDrib_abs_V4 tglobaladdr:$absaddr)>;
|
||||
|
||||
let Predicates = [HasV4T], AddedComplexity=30 in
|
||||
def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
|
||||
(LDriub_abs_V4 tglobaladdr:$absaddr)>;
|
||||
|
||||
let Predicates = [HasV4T], AddedComplexity=30 in
|
||||
def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
|
||||
(LDrih_abs_V4 tglobaladdr:$absaddr)>;
|
||||
|
||||
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.
|
||||
@ -3240,170 +3124,35 @@ defm STrib_ind : ST_indirect_lo<"memb", truncstorei8>;
|
||||
defm STrih_ind : ST_indirect_lo<"memh", truncstorei16>;
|
||||
defm STriw_ind : ST_indirect_lo<"memw", store>;
|
||||
|
||||
// Store - absolute addressing mode: These instruction take constant
|
||||
// value as the extended operand.
|
||||
multiclass ST_absimm<string OpcStr> {
|
||||
let isExtended = 1, opExtendable = 0, isPredicable = 1,
|
||||
validSubTargets = HasV4SubT in
|
||||
def _abs_V4 : STInst2<(outs),
|
||||
(ins u0AlwaysExt:$src1, IntRegs:$src2),
|
||||
!strconcat(OpcStr, "(##$src1) = $src2"),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let isExtended = 1, opExtendable = 1, isPredicated = 1,
|
||||
validSubTargets = HasV4SubT in {
|
||||
def _abs_cPt_V4 : STInst2<(outs),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
|
||||
!strconcat("if ($src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def _abs_cNotPt_V4 : STInst2<(outs),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
|
||||
!strconcat("if (!$src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def _abs_cdnPt_V4 : STInst2<(outs),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
|
||||
!strconcat("if ($src1.new)",
|
||||
!strconcat(OpcStr, "(##$src2) = $src3")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def _abs_cdnNotPt_V4 : STInst2<(outs),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
|
||||
!strconcat("if (!$src1.new)",
|
||||
!strconcat(OpcStr, "(##$src2) = $src3")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
}
|
||||
|
||||
let isExtended = 1, opExtendable = 0, mayStore = 1, isNVStore = 1,
|
||||
validSubTargets = HasV4SubT in
|
||||
def _abs_nv_V4 : NVInst_V4<(outs),
|
||||
(ins u0AlwaysExt:$src1, IntRegs:$src2),
|
||||
!strconcat(OpcStr, "(##$src1) = $src2.new"),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let isExtended = 1, opExtendable = 1, mayStore = 1, isPredicated = 1,
|
||||
isNVStore = 1, validSubTargets = HasV4SubT in {
|
||||
def _abs_cPt_nv_V4 : NVInst_V4<(outs),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
|
||||
!strconcat("if ($src1)",
|
||||
!strconcat(OpcStr, "(##$src2) = $src3.new")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def _abs_cNotPt_nv_V4 : NVInst_V4<(outs),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
|
||||
!strconcat("if (!$src1)",
|
||||
!strconcat(OpcStr, "(##$src2) = $src3.new")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def _abs_cdnPt_nv_V4 : NVInst_V4<(outs),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
|
||||
!strconcat("if ($src1.new)",
|
||||
!strconcat(OpcStr, "(##$src2) = $src3.new")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def _abs_cdnNotPt_nv_V4 : NVInst_V4<(outs),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
|
||||
!strconcat("if (!$src1.new)",
|
||||
!strconcat(OpcStr, "(##$src2) = $src3.new")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
}
|
||||
}
|
||||
|
||||
defm STrib_imm : ST_absimm<"memb">;
|
||||
defm STrih_imm : ST_absimm<"memh">;
|
||||
defm STriw_imm : ST_absimm<"memw">;
|
||||
|
||||
let Predicates = [HasV4T], AddedComplexity = 30 in {
|
||||
def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
|
||||
(STrib_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
|
||||
(STrib_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
|
||||
|
||||
def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
|
||||
(STrih_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
|
||||
(STrih_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
|
||||
|
||||
def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
|
||||
(STriw_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
|
||||
(STriw_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
|
||||
}
|
||||
|
||||
// Load - absolute addressing mode: These instruction take constant
|
||||
// value as the extended operand
|
||||
|
||||
multiclass LD_absimm<string OpcStr> {
|
||||
let isExtended = 1, opExtendable = 1, isPredicable = 1,
|
||||
validSubTargets = HasV4SubT in
|
||||
def _abs_V4 : LDInst2<(outs IntRegs:$dst),
|
||||
(ins u0AlwaysExt:$src),
|
||||
!strconcat("$dst = ",
|
||||
!strconcat(OpcStr, "(##$src)")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let isExtended = 1, opExtendable = 2, isPredicated = 1,
|
||||
validSubTargets = HasV4SubT in {
|
||||
def _abs_cPt_V4 : LDInst2<(outs IntRegs:$dst),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2),
|
||||
!strconcat("if ($src1) $dst = ",
|
||||
!strconcat(OpcStr, "(##$src2)")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def _abs_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2),
|
||||
!strconcat("if (!$src1) $dst = ",
|
||||
!strconcat(OpcStr, "(##$src2)")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def _abs_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2),
|
||||
!strconcat("if ($src1.new) $dst = ",
|
||||
!strconcat(OpcStr, "(##$src2)")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
def _abs_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
|
||||
(ins PredRegs:$src1, u0AlwaysExt:$src2),
|
||||
!strconcat("if (!$src1.new) $dst = ",
|
||||
!strconcat(OpcStr, "(##$src2)")),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
}
|
||||
}
|
||||
|
||||
defm LDrib_imm : LD_absimm<"memb">;
|
||||
defm LDriub_imm : LD_absimm<"memub">;
|
||||
defm LDrih_imm : LD_absimm<"memh">;
|
||||
defm LDriuh_imm : LD_absimm<"memuh">;
|
||||
defm LDriw_imm : LD_absimm<"memw">;
|
||||
|
||||
let Predicates = [HasV4T], AddedComplexity = 30 in {
|
||||
def : Pat<(i32 (load u0AlwaysExtPred:$src)),
|
||||
(LDriw_imm_abs_V4 u0AlwaysExtPred:$src)>;
|
||||
(LDriw_abs_V4 u0AlwaysExtPred:$src)>;
|
||||
|
||||
def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
|
||||
(LDrib_imm_abs_V4 u0AlwaysExtPred:$src)>;
|
||||
(LDrib_abs_V4 u0AlwaysExtPred:$src)>;
|
||||
|
||||
def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
|
||||
(LDriub_imm_abs_V4 u0AlwaysExtPred:$src)>;
|
||||
(LDriub_abs_V4 u0AlwaysExtPred:$src)>;
|
||||
|
||||
def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
|
||||
(LDrih_imm_abs_V4 u0AlwaysExtPred:$src)>;
|
||||
(LDrih_abs_V4 u0AlwaysExtPred:$src)>;
|
||||
|
||||
def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
|
||||
(LDriuh_imm_abs_V4 u0AlwaysExtPred:$src)>;
|
||||
(LDriuh_abs_V4 u0AlwaysExtPred:$src)>;
|
||||
}
|
||||
|
||||
// Indexed store double word - global address.
|
||||
// Indexed store word - global address.
|
||||
// memw(Rs+#u6:2)=#S8
|
||||
let AddedComplexity = 10 in
|
||||
def STriw_offset_ext_V4 : STInst<(outs),
|
||||
|
18
test/CodeGen/Hexagon/absimm.ll
Normal file
18
test/CodeGen/Hexagon/absimm.ll
Normal file
@ -0,0 +1,18 @@
|
||||
; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
|
||||
; Check that we generate absolute addressing mode instructions
|
||||
; with immediate value.
|
||||
|
||||
define i32 @f1(i32 %i) nounwind {
|
||||
; CHECK: memw(##786432){{ *}}={{ *}}r{{[0-9]+}}
|
||||
entry:
|
||||
store volatile i32 %i, i32* inttoptr (i32 786432 to i32*), align 262144
|
||||
ret i32 %i
|
||||
}
|
||||
|
||||
define i32* @f2(i32* nocapture %i) nounwind {
|
||||
entry:
|
||||
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memw(##786432)
|
||||
%0 = load volatile i32* inttoptr (i32 786432 to i32*), align 262144
|
||||
%1 = inttoptr i32 %0 to i32*
|
||||
ret i32* %1
|
||||
}
|
Loading…
Reference in New Issue
Block a user