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:
Jyotsna Verma 2012-11-14 20:38:48 +00:00
parent 7c6e8cd7cc
commit cb02fa9d7f
5 changed files with 216 additions and 233 deletions

View File

@ -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 ***
}
//===----------------------------------------------------------------------===//

View File

@ -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),

View File

@ -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

View File

@ -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 *** //

View 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
}