mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +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 TypeXTYPE  : Type<8>; | ||||||
| def TypeMARKER : Type<31>; | 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 + | //                         Intruction Class Declaration + | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
| @@ -55,10 +83,38 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern, | |||||||
|   // Predicated instructions. |   // Predicated instructions. | ||||||
|   bits<1> isPredicated = 0; |   bits<1> isPredicated = 0; | ||||||
|   let TSFlags{6} = isPredicated; |   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; |   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. |   // Fields used for relation models. | ||||||
|   string BaseOpcode = ""; |   string BaseOpcode = ""; | ||||||
| @@ -66,7 +122,10 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern, | |||||||
|   string PredSense = ""; |   string PredSense = ""; | ||||||
|   string PNewValue = ""; |   string PNewValue = ""; | ||||||
|   string InputType = "";    // Input is "imm" or "reg" type. |   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 | // ImmRegRel - Filter class used to relate instructions having reg-reg form | ||||||
| // with their reg-imm counterparts. | // with their reg-imm counterparts. | ||||||
| class ImmRegRel; | 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. | // Hexagon Instruction Predicate Definitions. | ||||||
| @@ -819,8 +825,6 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicated = 1, | |||||||
| // LD + | // LD + | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
| /// | /// | ||||||
| /// Make sure that in post increment load, the first operand is always the post |  | ||||||
| /// increment operand. |  | ||||||
| /// | /// | ||||||
| // Load doubleword. | // Load doubleword. | ||||||
| let isPredicable = 1 in | let isPredicable = 1 in | ||||||
| @@ -851,13 +855,66 @@ def LDd_GP : LDInst2<(outs DoubleRegs:$dst), | |||||||
|             []>, |             []>, | ||||||
|             Requires<[NoV4T]>; |             Requires<[NoV4T]>; | ||||||
|  |  | ||||||
| let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in | //===----------------------------------------------------------------------===// | ||||||
| def POST_LDrid : LDInst2PI<(outs DoubleRegs:$dst, IntRegs:$dst2), | // Post increment load | ||||||
|             (ins IntRegs:$src1, s4Imm:$offset), | // Make sure that in post increment load, the first operand is always the post | ||||||
|             "$dst = memd($src1++#$offset)", | // 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)", | ||||||
|  |             [], | ||||||
|  |             "$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">; |                  "$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. | // Load doubleword conditionally. | ||||||
| let neverHasSideEffects = 1, isPredicated = 1 in | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| def LDrid_cPt : LDInst2<(outs DoubleRegs:$dst), | def LDrid_cPt : LDInst2<(outs DoubleRegs:$dst), | ||||||
| @@ -884,20 +941,6 @@ def LDrid_indexed_cNotPt : LDInst2<(outs DoubleRegs:$dst), | |||||||
|             "if (!$src1) $dst = memd($src2+#$src3)", |             "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 | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| def LDrid_cdnPt : LDInst2<(outs DoubleRegs:$dst), | def LDrid_cdnPt : LDInst2<(outs DoubleRegs:$dst), | ||||||
|             (ins PredRegs:$src1, MEMri:$addr), |             (ins PredRegs:$src1, MEMri:$addr), | ||||||
| @@ -969,13 +1012,6 @@ def LDub_GP : LDInst2<(outs IntRegs:$dst), | |||||||
|             []>, |             []>, | ||||||
|             Requires<[NoV4T]>; |             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. | // Load byte conditionally. | ||||||
| let neverHasSideEffects = 1, isPredicated = 1 in | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| def LDrib_cPt : LDInst2<(outs IntRegs:$dst), | 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)", |             "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 | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| def LDrib_cdnPt : LDInst2<(outs IntRegs:$dst), | def LDrib_cdnPt : LDInst2<(outs IntRegs:$dst), | ||||||
|             (ins PredRegs:$src1, MEMri:$addr), |             (ins PredRegs:$src1, MEMri:$addr), | ||||||
| @@ -1083,13 +1105,6 @@ def LDuh_GP : LDInst2<(outs IntRegs:$dst), | |||||||
|             []>, |             []>, | ||||||
|             Requires<[NoV4T]>; |             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. | // Load halfword conditionally. | ||||||
| let neverHasSideEffects = 1, isPredicated = 1 in | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| def LDrih_cPt : LDInst2<(outs IntRegs:$dst), | 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)", |             "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 | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| def LDrih_cdnPt : LDInst2<(outs IntRegs:$dst), | def LDrih_cdnPt : LDInst2<(outs IntRegs:$dst), | ||||||
|             (ins PredRegs:$src1, MEMri:$addr), |             (ins PredRegs:$src1, MEMri:$addr), | ||||||
| @@ -1182,13 +1183,6 @@ def LDriub_GP : LDInst2<(outs IntRegs:$dst), | |||||||
|             []>, |             []>, | ||||||
|             Requires<[NoV4T]>; |             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. | // Load unsigned byte conditionally. | ||||||
| let neverHasSideEffects = 1, isPredicated = 1 in | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| def LDriub_cPt : LDInst2<(outs IntRegs:$dst), | 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)", |             "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 | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| def LDriub_cdnPt : LDInst2<(outs IntRegs:$dst), | def LDriub_cdnPt : LDInst2<(outs IntRegs:$dst), | ||||||
|             (ins PredRegs:$src1, MEMri:$addr), |             (ins PredRegs:$src1, MEMri:$addr), | ||||||
| @@ -1275,13 +1255,6 @@ def LDriuh_GP : LDInst2<(outs IntRegs:$dst), | |||||||
|             []>, |             []>, | ||||||
|             Requires<[NoV4T]>; |             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. | // Load unsigned halfword conditionally. | ||||||
| let neverHasSideEffects = 1, isPredicated = 1 in | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| def LDriuh_cPt : LDInst2<(outs IntRegs:$dst), | 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)", |             "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 | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| def LDriuh_cdnPt : LDInst2<(outs IntRegs:$dst), | def LDriuh_cdnPt : LDInst2<(outs IntRegs:$dst), | ||||||
|             (ins PredRegs:$src1, MEMri:$addr), |             (ins PredRegs:$src1, MEMri:$addr), | ||||||
| @@ -1381,13 +1340,6 @@ def LDw_GP : LDInst2<(outs IntRegs:$dst), | |||||||
|             []>, |             []>, | ||||||
|             Requires<[NoV4T]>; |             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. | // Load word conditionally. | ||||||
|  |  | ||||||
| let neverHasSideEffects = 1, isPredicated = 1 in | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| @@ -1414,20 +1366,6 @@ def LDriw_indexed_cNotPt : LDInst2<(outs IntRegs:$dst), | |||||||
|             "if (!$src1) $dst = memw($src2+#$src3)", |             "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 | let neverHasSideEffects = 1, isPredicated = 1 in | ||||||
| def LDriw_cdnPt : LDInst2<(outs IntRegs:$dst), | def LDriw_cdnPt : LDInst2<(outs IntRegs:$dst), | ||||||
|             (ins PredRegs:$src1, MEMri:$addr), |             (ins PredRegs:$src1, MEMri:$addr), | ||||||
|   | |||||||
| @@ -1002,108 +1002,6 @@ def LDriw_indexed_shl_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst), | |||||||
|                     []>, |                     []>, | ||||||
|                     Requires<[HasV4T]>; |                     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 | /// Load from global offset | ||||||
|  |  | ||||||
| let isPredicable = 1, neverHasSideEffects = 1 in | let isPredicable = 1, neverHasSideEffects = 1 in | ||||||
|   | |||||||
| @@ -43,7 +43,27 @@ namespace HexagonII { | |||||||
|     TypeMARKER = 31  // Such as end of a HW loop. |     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 |   // MCInstrDesc TSFlags | ||||||
|   // *** Must match HexagonInstrFormat*.td *** |   // *** Must match HexagonInstrFormat*.td *** | ||||||
| @@ -58,7 +78,46 @@ namespace HexagonII { | |||||||
|  |  | ||||||
|     // Predicated instructions. |     // Predicated instructions. | ||||||
|     PredicatedPos  = 6, |     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 *** // |   // *** 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