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 +
//===----------------------------------------------------------------------===//
// Predicated instructions.
bits<1> isPredicated = 0;
let TSFlags{6} = isPredicated;
+ bits<1> isPredicatedNew = 0;
+ let TSFlags{7} = isPredicatedNew;
+
+ // Stores that can be newified.
+ bits<1> isNVStorable = 0;
+ let TSFlags{8} = isNVStorable;
- // Dot new value store instructions.
+ // 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 = "";
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 ***
}
//===----------------------------------------------------------------------===//
// 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.
// LD +
//===----------------------------------------------------------------------===//
///
-/// Make sure that in post increment load, the first operand is always the post
-/// increment operand.
///
// Load doubleword.
let isPredicable = 1 in
[]>,
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
"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),
[]>,
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),
"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),
[]>,
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),
"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),
[]>,
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),
"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),
[]>,
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),
"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),
[]>,
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
"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),
[]>,
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