mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-29 22:52:18 +00:00
Added multiclass for post-increment load instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167974 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7c6e8cd7cc
commit
cb02fa9d7f
@ -27,6 +27,34 @@ def TypeSYSTEM : Type<7>;
|
||||
def TypeXTYPE : Type<8>;
|
||||
def TypeMARKER : Type<31>;
|
||||
|
||||
// Maintain list of valid subtargets for each instruction.
|
||||
class SubTarget<bits<4> value> {
|
||||
bits<4> Value = value;
|
||||
}
|
||||
|
||||
def HasV2SubT : SubTarget<0xf>;
|
||||
def HasV2SubTOnly : SubTarget<0x1>;
|
||||
def NoV2SubT : SubTarget<0x0>;
|
||||
def HasV3SubT : SubTarget<0xe>;
|
||||
def HasV3SubTOnly : SubTarget<0x2>;
|
||||
def NoV3SubT : SubTarget<0x1>;
|
||||
def HasV4SubT : SubTarget<0xc>;
|
||||
def NoV4SubT : SubTarget<0x3>;
|
||||
def HasV5SubT : SubTarget<0x8>;
|
||||
def NoV5SubT : SubTarget<0x7>;
|
||||
|
||||
// Addressing modes for load/store instructions
|
||||
class AddrModeType<bits<4> value> {
|
||||
bits<4> Value = value;
|
||||
}
|
||||
|
||||
def NoAddrMode : AddrModeType<0>; // No addressing mode
|
||||
def Absolute : AddrModeType<1>; // Absolute addressing mode
|
||||
def AbsoluteSet : AddrModeType<2>; // Absolute set addressing mode
|
||||
def BaseImmOffset : AddrModeType<3>; // Indirect with offset
|
||||
def BaseLongOffset : AddrModeType<4>; // Indirect with long offset
|
||||
def BaseRegOffset : AddrModeType<5>; // Indirect with register offset
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Intruction Class Declaration +
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -55,10 +83,38 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
// Predicated instructions.
|
||||
bits<1> isPredicated = 0;
|
||||
let TSFlags{6} = isPredicated;
|
||||
bits<1> isPredicatedNew = 0;
|
||||
let TSFlags{7} = isPredicatedNew;
|
||||
|
||||
// Dot new value store instructions.
|
||||
// Stores that can be newified.
|
||||
bits<1> isNVStorable = 0;
|
||||
let TSFlags{8} = isNVStorable;
|
||||
|
||||
// New-value store instructions.
|
||||
bits<1> isNVStore = 0;
|
||||
let TSFlags{8} = isNVStore;
|
||||
let TSFlags{9} = isNVStore;
|
||||
|
||||
// Immediate extender helper fields.
|
||||
bits<1> isExtendable = 0;
|
||||
let TSFlags{10} = isExtendable; // Insn may be extended.
|
||||
bits<1> isExtended = 0;
|
||||
let TSFlags{11} = isExtended; // Insn must be extended.
|
||||
bits<3> opExtendable = 0;
|
||||
let TSFlags{14-12} = opExtendable; // Which operand may be extended.
|
||||
bits<1> isExtentSigned = 0;
|
||||
let TSFlags{15} = isExtentSigned; // Signed or unsigned range.
|
||||
bits<5> opExtentBits = 0;
|
||||
let TSFlags{20-16} = opExtentBits; //Number of bits of range before extending.
|
||||
|
||||
// If an instruction is valid on a subtarget (v2-v5), set the corresponding
|
||||
// bit from validSubTargets. v2 is the least significant bit.
|
||||
// By default, instruction is valid on all subtargets.
|
||||
SubTarget validSubTargets = HasV2SubT;
|
||||
let TSFlags{24-21} = validSubTargets.Value;
|
||||
|
||||
// Addressing mode for load/store instrutions.
|
||||
AddrModeType addrMode = NoAddrMode;
|
||||
let TSFlags{28-25} = addrMode.Value;
|
||||
|
||||
// Fields used for relation models.
|
||||
string BaseOpcode = "";
|
||||
@ -66,7 +122,10 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
string PredSense = "";
|
||||
string PNewValue = "";
|
||||
string InputType = ""; // Input is "imm" or "reg" type.
|
||||
// *** The code above must match HexagonBaseInfo.h ***
|
||||
string isMEMri = "false"; // Set to "true" for load/store with MEMri operand.
|
||||
string isFloat = "false"; // Set to "true" for the floating-point load/store.
|
||||
|
||||
// *** Must match MCTargetDesc/HexagonBaseInfo.h ***
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -26,6 +26,12 @@ class PredNewRel: PredRel;
|
||||
// ImmRegRel - Filter class used to relate instructions having reg-reg form
|
||||
// with their reg-imm counterparts.
|
||||
class ImmRegRel;
|
||||
// NewValueRel - Filter class used to relate regular store instructions with
|
||||
// their new-value store form.
|
||||
class NewValueRel: PredNewRel;
|
||||
// NewValueRel - Filter class used to relate load/store instructions having
|
||||
// different addressing modes with each other.
|
||||
class AddrModeRel: NewValueRel;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Hexagon Instruction Predicate Definitions.
|
||||
@ -819,8 +825,6 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicated = 1,
|
||||
// LD +
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// Make sure that in post increment load, the first operand is always the post
|
||||
/// increment operand.
|
||||
///
|
||||
// Load doubleword.
|
||||
let isPredicable = 1 in
|
||||
@ -851,12 +855,65 @@ def LDd_GP : LDInst2<(outs DoubleRegs:$dst),
|
||||
[]>,
|
||||
Requires<[NoV4T]>;
|
||||
|
||||
let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
|
||||
def POST_LDrid : LDInst2PI<(outs DoubleRegs:$dst, IntRegs:$dst2),
|
||||
(ins IntRegs:$src1, s4Imm:$offset),
|
||||
"$dst = memd($src1++#$offset)",
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Post increment load
|
||||
// Make sure that in post increment load, the first operand is always the post
|
||||
// increment operand.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
multiclass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
|
||||
bit isNot, bit isPredNew> {
|
||||
let PNewValue = #!if(isPredNew, "new", "") in
|
||||
def #NAME# : LDInst2PI<(outs RC:$dst, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset),
|
||||
#!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
|
||||
") ")#"$dst = "#mnemonic#"($src2++#$offset)",
|
||||
[],
|
||||
"$src1 = $dst2">;
|
||||
"$src2 = $dst2">;
|
||||
}
|
||||
|
||||
multiclass LD_PostInc_Pred<string mnemonic, RegisterClass RC,
|
||||
Operand ImmOp, bit PredNot> {
|
||||
let PredSense = #!if(PredNot, "false", "true") in {
|
||||
defm _c#NAME# : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
|
||||
// Predicate new
|
||||
let Predicates = [HasV4T], validSubTargets = HasV4SubT in
|
||||
defm _cdn#NAME#_V4 : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>;
|
||||
}
|
||||
}
|
||||
|
||||
multiclass LD_PostInc<string mnemonic, string BaseOp, RegisterClass RC,
|
||||
Operand ImmOp> {
|
||||
|
||||
let BaseOpcode = "POST_"#BaseOp in {
|
||||
let isPredicable = 1 in
|
||||
def #NAME# : LDInst2PI<(outs RC:$dst, IntRegs:$dst2),
|
||||
(ins IntRegs:$src1, ImmOp:$offset),
|
||||
"$dst = "#mnemonic#"($src1++#$offset)",
|
||||
[],
|
||||
"$src1 = $dst2">;
|
||||
|
||||
let isPredicated = 1 in {
|
||||
defm Pt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 0 >;
|
||||
defm NotPt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 1 >;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1 in {
|
||||
defm POST_LDrib : LD_PostInc<"memb", "LDrib", IntRegs, s4_0Imm>,
|
||||
PredNewRel;
|
||||
defm POST_LDriub : LD_PostInc<"memub", "LDriub", IntRegs, s4_0Imm>,
|
||||
PredNewRel;
|
||||
defm POST_LDrih : LD_PostInc<"memh", "LDrih", IntRegs, s4_1Imm>,
|
||||
PredNewRel;
|
||||
defm POST_LDriuh : LD_PostInc<"memuh", "LDriuh", IntRegs, s4_1Imm>,
|
||||
PredNewRel;
|
||||
defm POST_LDriw : LD_PostInc<"memw", "LDriw", IntRegs, s4_2Imm>,
|
||||
PredNewRel;
|
||||
defm POST_LDrid : LD_PostInc<"memd", "LDrid", DoubleRegs, s4_3Imm>,
|
||||
PredNewRel;
|
||||
}
|
||||
|
||||
// Load doubleword conditionally.
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
@ -884,20 +941,6 @@ def LDrid_indexed_cNotPt : LDInst2<(outs DoubleRegs:$dst),
|
||||
"if (!$src1) $dst = memd($src2+#$src3)",
|
||||
[]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrid_cPt : LDInst2PI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3),
|
||||
"if ($src1) $dst1 = memd($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrid_cNotPt : LDInst2PI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3),
|
||||
"if (!$src1) $dst1 = memd($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def LDrid_cdnPt : LDInst2<(outs DoubleRegs:$dst),
|
||||
(ins PredRegs:$src1, MEMri:$addr),
|
||||
@ -969,13 +1012,6 @@ def LDub_GP : LDInst2<(outs IntRegs:$dst),
|
||||
[]>,
|
||||
Requires<[NoV4T]>;
|
||||
|
||||
let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
|
||||
def POST_LDrib : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
|
||||
(ins IntRegs:$src1, s4Imm:$offset),
|
||||
"$dst = memb($src1++#$offset)",
|
||||
[],
|
||||
"$src1 = $dst2">;
|
||||
|
||||
// Load byte conditionally.
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def LDrib_cPt : LDInst2<(outs IntRegs:$dst),
|
||||
@ -1001,20 +1037,6 @@ def LDrib_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
|
||||
"if (!$src1) $dst = memb($src2+#$src3)",
|
||||
[]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrib_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
|
||||
"if ($src1) $dst1 = memb($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrib_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
|
||||
"if (!$src1) $dst1 = memb($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def LDrib_cdnPt : LDInst2<(outs IntRegs:$dst),
|
||||
(ins PredRegs:$src1, MEMri:$addr),
|
||||
@ -1083,13 +1105,6 @@ def LDuh_GP : LDInst2<(outs IntRegs:$dst),
|
||||
[]>,
|
||||
Requires<[NoV4T]>;
|
||||
|
||||
let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
|
||||
def POST_LDrih : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
|
||||
(ins IntRegs:$src1, s4Imm:$offset),
|
||||
"$dst = memh($src1++#$offset)",
|
||||
[],
|
||||
"$src1 = $dst2">;
|
||||
|
||||
// Load halfword conditionally.
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def LDrih_cPt : LDInst2<(outs IntRegs:$dst),
|
||||
@ -1115,20 +1130,6 @@ def LDrih_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
|
||||
"if (!$src1) $dst = memh($src2+#$src3)",
|
||||
[]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrih_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
|
||||
"if ($src1) $dst1 = memh($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrih_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
|
||||
"if (!$src1) $dst1 = memh($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def LDrih_cdnPt : LDInst2<(outs IntRegs:$dst),
|
||||
(ins PredRegs:$src1, MEMri:$addr),
|
||||
@ -1182,13 +1183,6 @@ def LDriub_GP : LDInst2<(outs IntRegs:$dst),
|
||||
[]>,
|
||||
Requires<[NoV4T]>;
|
||||
|
||||
let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
|
||||
def POST_LDriub : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
|
||||
(ins IntRegs:$src1, s4Imm:$offset),
|
||||
"$dst = memub($src1++#$offset)",
|
||||
[],
|
||||
"$src1 = $dst2">;
|
||||
|
||||
// Load unsigned byte conditionally.
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def LDriub_cPt : LDInst2<(outs IntRegs:$dst),
|
||||
@ -1214,20 +1208,6 @@ def LDriub_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
|
||||
"if (!$src1) $dst = memub($src2+#$src3)",
|
||||
[]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriub_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
|
||||
"if ($src1) $dst1 = memub($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriub_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
|
||||
"if (!$src1) $dst1 = memub($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def LDriub_cdnPt : LDInst2<(outs IntRegs:$dst),
|
||||
(ins PredRegs:$src1, MEMri:$addr),
|
||||
@ -1275,13 +1255,6 @@ def LDriuh_GP : LDInst2<(outs IntRegs:$dst),
|
||||
[]>,
|
||||
Requires<[NoV4T]>;
|
||||
|
||||
let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
|
||||
def POST_LDriuh : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
|
||||
(ins IntRegs:$src1, s4Imm:$offset),
|
||||
"$dst = memuh($src1++#$offset)",
|
||||
[],
|
||||
"$src1 = $dst2">;
|
||||
|
||||
// Load unsigned halfword conditionally.
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def LDriuh_cPt : LDInst2<(outs IntRegs:$dst),
|
||||
@ -1307,20 +1280,6 @@ def LDriuh_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
|
||||
"if (!$src1) $dst = memuh($src2+#$src3)",
|
||||
[]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriuh_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
|
||||
"if ($src1) $dst1 = memuh($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriuh_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
|
||||
"if (!$src1) $dst1 = memuh($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def LDriuh_cdnPt : LDInst2<(outs IntRegs:$dst),
|
||||
(ins PredRegs:$src1, MEMri:$addr),
|
||||
@ -1381,13 +1340,6 @@ def LDw_GP : LDInst2<(outs IntRegs:$dst),
|
||||
[]>,
|
||||
Requires<[NoV4T]>;
|
||||
|
||||
let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
|
||||
def POST_LDriw : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
|
||||
(ins IntRegs:$src1, s4Imm:$offset),
|
||||
"$dst = memw($src1++#$offset)",
|
||||
[],
|
||||
"$src1 = $dst2">;
|
||||
|
||||
// Load word conditionally.
|
||||
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
@ -1414,20 +1366,6 @@ def LDriw_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
|
||||
"if (!$src1) $dst = memw($src2+#$src3)",
|
||||
[]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriw_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3),
|
||||
"if ($src1) $dst1 = memw($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriw_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3),
|
||||
"if (!$src1) $dst1 = memw($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">;
|
||||
|
||||
let neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def LDriw_cdnPt : LDInst2<(outs IntRegs:$dst),
|
||||
(ins PredRegs:$src1, MEMri:$addr),
|
||||
|
@ -1002,108 +1002,6 @@ def LDriw_indexed_shl_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
|
||||
[]>,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
// Rd=memw(Rt<<#u2+#U6)
|
||||
|
||||
|
||||
// Post-inc Load, Predicated, Dot new
|
||||
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrid_cdnPt_V4 : LDInst2PI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3),
|
||||
"if ($src1.new) $dst1 = memd($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrid_cdnNotPt_V4 : LDInst2PI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3),
|
||||
"if (!$src1.new) $dst1 = memd($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrib_cdnPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
|
||||
"if ($src1.new) $dst1 = memb($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrib_cdnNotPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
|
||||
"if (!$src1.new) $dst1 = memb($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrih_cdnPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
|
||||
"if ($src1.new) $dst1 = memh($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDrih_cdnNotPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
|
||||
"if (!$src1.new) $dst1 = memh($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriub_cdnPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
|
||||
"if ($src1.new) $dst1 = memub($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriub_cdnNotPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
|
||||
"if (!$src1.new) $dst1 = memub($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriuh_cdnPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
|
||||
"if ($src1.new) $dst1 = memuh($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriuh_cdnNotPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
|
||||
"if (!$src1.new) $dst1 = memuh($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriw_cdnPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3),
|
||||
"if ($src1.new) $dst1 = memw($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
|
||||
def POST_LDriw_cdnNotPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
|
||||
(ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3),
|
||||
"if (!$src1.new) $dst1 = memw($src2++#$src3)",
|
||||
[],
|
||||
"$src2 = $dst2">,
|
||||
Requires<[HasV4T]>;
|
||||
|
||||
/// Load from global offset
|
||||
|
||||
let isPredicable = 1, neverHasSideEffects = 1 in
|
||||
|
@ -43,7 +43,27 @@ namespace HexagonII {
|
||||
TypeMARKER = 31 // Such as end of a HW loop.
|
||||
};
|
||||
|
||||
enum SubTarget {
|
||||
HasV2SubT = 0xf,
|
||||
HasV2SubTOnly = 0x1,
|
||||
NoV2SubT = 0x0,
|
||||
HasV3SubT = 0xe,
|
||||
HasV3SubTOnly = 0x2,
|
||||
NoV3SubT = 0x1,
|
||||
HasV4SubT = 0xc,
|
||||
NoV4SubT = 0x3,
|
||||
HasV5SubT = 0x8,
|
||||
NoV5SubT = 0x7
|
||||
};
|
||||
|
||||
enum AddrMode {
|
||||
NoAddrMode = 0, // No addressing mode
|
||||
Absolute = 1, // Absolute addressing mode
|
||||
AbsoluteSet = 2, // Absolute set addressing mode
|
||||
BaseImmOffset = 3, // Indirect with offset
|
||||
BaseLongOffset = 4, // Indirect with long offset
|
||||
BaseRegOffset = 5 // Indirect with register offset
|
||||
};
|
||||
|
||||
// MCInstrDesc TSFlags
|
||||
// *** Must match HexagonInstrFormat*.td ***
|
||||
@ -58,8 +78,47 @@ namespace HexagonII {
|
||||
|
||||
// Predicated instructions.
|
||||
PredicatedPos = 6,
|
||||
PredicatedMask = 0x1
|
||||
};
|
||||
PredicatedMask = 0x1,
|
||||
PredicatedNewPos = 7,
|
||||
PredicatedNewMask = 0x1,
|
||||
|
||||
// Stores that can be newified.
|
||||
mayNVStorePos = 8,
|
||||
mayNVStoreMask = 0x1,
|
||||
|
||||
// Dot new value store instructions.
|
||||
NVStorePos = 9,
|
||||
NVStoreMask = 0x1,
|
||||
|
||||
// Extendable insns.
|
||||
ExtendablePos = 10,
|
||||
ExtendableMask = 0x1,
|
||||
|
||||
// Insns must be extended.
|
||||
ExtendedPos = 11,
|
||||
ExtendedMask = 0x1,
|
||||
|
||||
// Which operand may be extended.
|
||||
ExtendableOpPos = 12,
|
||||
ExtendableOpMask = 0x7,
|
||||
|
||||
// Signed or unsigned range.
|
||||
ExtentSignedPos = 15,
|
||||
ExtentSignedMask = 0x1,
|
||||
|
||||
// Number of bits of range before extending operand.
|
||||
ExtentBitsPos = 16,
|
||||
ExtentBitsMask = 0x1f,
|
||||
|
||||
// Valid subtargets
|
||||
validSubTargetPos = 21,
|
||||
validSubTargetMask = 0xf,
|
||||
|
||||
// Addressing mode for load/store instructions
|
||||
AddrModePos = 25,
|
||||
AddrModeMask = 0xf
|
||||
|
||||
};
|
||||
|
||||
// *** The code above must match HexagonInstrFormat*.td *** //
|
||||
|
||||
|
29
test/CodeGen/Hexagon/postinc-load.ll
Normal file
29
test/CodeGen/Hexagon/postinc-load.ll
Normal file
@ -0,0 +1,29 @@
|
||||
; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
|
||||
|
||||
; Check that post-increment load instructions are being generated.
|
||||
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memw(r{{[0-9]+}}{{ *}}++{{ *}}#4{{ *}})
|
||||
|
||||
define i32 @sum(i32* nocapture %a, i16* nocapture %b, i32 %n) nounwind {
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
for.body:
|
||||
%lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 10, %entry ]
|
||||
%arrayidx.phi = phi i32* [ %a, %entry ], [ %arrayidx.inc, %for.body ]
|
||||
%arrayidx1.phi = phi i16* [ %b, %entry ], [ %arrayidx1.inc, %for.body ]
|
||||
%sum.03 = phi i32 [ 0, %entry ], [ %add2, %for.body ]
|
||||
%0 = load i32* %arrayidx.phi, align 4
|
||||
%1 = load i16* %arrayidx1.phi, align 2
|
||||
%conv = sext i16 %1 to i32
|
||||
%add = add i32 %0, %sum.03
|
||||
%add2 = add i32 %add, %conv
|
||||
%arrayidx.inc = getelementptr i32* %arrayidx.phi, i32 1
|
||||
%arrayidx1.inc = getelementptr i16* %arrayidx1.phi, i32 1
|
||||
%lsr.iv.next = add i32 %lsr.iv, -1
|
||||
%exitcond = icmp eq i32 %lsr.iv.next, 0
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end:
|
||||
ret i32 %add2
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user