From cb02fa9d7f9058ec2efae39335cf559f1607893e Mon Sep 17 00:00:00 2001 From: Jyotsna Verma Date: Wed, 14 Nov 2012 20:38:48 +0000 Subject: [PATCH] Added multiclass for post-increment load instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167974 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/HexagonInstrFormats.td | 65 +++++- lib/Target/Hexagon/HexagonInstrInfo.td | 190 ++++++------------ lib/Target/Hexagon/HexagonInstrInfoV4.td | 102 ---------- .../Hexagon/MCTargetDesc/HexagonBaseInfo.h | 63 +++++- test/CodeGen/Hexagon/postinc-load.ll | 29 +++ 5 files changed, 216 insertions(+), 233 deletions(-) create mode 100644 test/CodeGen/Hexagon/postinc-load.ll diff --git a/lib/Target/Hexagon/HexagonInstrFormats.td b/lib/Target/Hexagon/HexagonInstrFormats.td index a64c7a18164..71c620b1317 100644 --- a/lib/Target/Hexagon/HexagonInstrFormats.td +++ b/lib/Target/Hexagon/HexagonInstrFormats.td @@ -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 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 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 pattern, // 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 = ""; @@ -66,7 +122,10 @@ class InstHexagon 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 *** } //===----------------------------------------------------------------------===// diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index 25ecea5bed5..3dad3aee96c 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -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 { + 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 { + let PredSense = #!if(PredNot, "false", "true") in { + defm _c#NAME# : LD_PostInc_Pbase; + // Predicate new + let Predicates = [HasV4T], validSubTargets = HasV4SubT in + defm _cdn#NAME#_V4 : LD_PostInc_Pbase; + } +} + +multiclass LD_PostInc { + + 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; + defm NotPt : LD_PostInc_Pred; + } + } +} + +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), diff --git a/lib/Target/Hexagon/HexagonInstrInfoV4.td b/lib/Target/Hexagon/HexagonInstrInfoV4.td index 70448fc7af3..a610168e343 100644 --- a/lib/Target/Hexagon/HexagonInstrInfoV4.td +++ b/lib/Target/Hexagon/HexagonInstrInfoV4.td @@ -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 diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h index 7221e906342..9fc826f412c 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h @@ -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 *** // diff --git a/test/CodeGen/Hexagon/postinc-load.ll b/test/CodeGen/Hexagon/postinc-load.ll new file mode 100644 index 00000000000..855a347d74f --- /dev/null +++ b/test/CodeGen/Hexagon/postinc-load.ll @@ -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 +} + -- 2.34.1