mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +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:
		| @@ -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 | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user