diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
| commit | 044eb2f6afba375a914ac9d8024f8f5142bb912e (patch) | |
| tree | 1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/Target/ARM/ARMInstrInfo.td | |
| parent | eb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff) | |
Notes
Diffstat (limited to 'lib/Target/ARM/ARMInstrInfo.td')
| -rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 112 |
1 files changed, 67 insertions, 45 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index c488cd347fe1..4e13af596300 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -241,6 +241,8 @@ def HasV8_1a : Predicate<"Subtarget->hasV8_1aOps()">, AssemblerPredicate<"HasV8_1aOps", "armv8.1a">; def HasV8_2a : Predicate<"Subtarget->hasV8_2aOps()">, AssemblerPredicate<"HasV8_2aOps", "armv8.2a">; +def HasV8_3a : Predicate<"Subtarget->hasV8_3aOps()">, + AssemblerPredicate<"HasV8_3aOps", "armv8.3a">; def NoVFP : Predicate<"!Subtarget->hasVFP2()">; def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate<"FeatureVFP2", "VFP2">; @@ -257,6 +259,8 @@ def HasNEON : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate<"FeatureNEON", "NEON">; def HasCrypto : Predicate<"Subtarget->hasCrypto()">, AssemblerPredicate<"FeatureCrypto", "crypto">; +def HasDotProd : Predicate<"Subtarget->hasDotProd()">, + AssemblerPredicate<"FeatureDotProd", "dotprod">; def HasCRC : Predicate<"Subtarget->hasCRC()">, AssemblerPredicate<"FeatureCRC", "crc">; def HasRAS : Predicate<"Subtarget->hasRAS()">, @@ -313,6 +317,8 @@ def IsNotMachO : Predicate<"!Subtarget->isTargetMachO()">; def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">; def IsWindows : Predicate<"Subtarget->isTargetWindows()">; def IsNotWindows : Predicate<"!Subtarget->isTargetWindows()">; +def IsReadTPHard : Predicate<"Subtarget->isReadTPHard()">; +def IsReadTPSoft : Predicate<"!Subtarget->isReadTPHard()">; def UseNaClTrap : Predicate<"Subtarget->useNaClTrap()">, AssemblerPredicate<"FeatureNaClTrap", "NaCl">; def DontUseNaClTrap : Predicate<"!Subtarget->useNaClTrap()">; @@ -326,6 +332,8 @@ def UseNegativeImmediates : let RecomputePerFunction = 1 in { def UseMovt : Predicate<"Subtarget->useMovt(*MF)">; def DontUseMovt : Predicate<"!Subtarget->useMovt(*MF)">; + def UseMovtInPic : Predicate<"Subtarget->useMovt(*MF) && Subtarget->allowPositionIndependentMovt()">; + def DontUseMovtInPic : Predicate<"!Subtarget->useMovt(*MF) || !Subtarget->allowPositionIndependentMovt()">; } def UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">; def UseMulOps : Predicate<"Subtarget->useMulOps()">; @@ -454,12 +462,13 @@ def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{ class ImmAsmOperand<int Low, int High> : AsmOperandClass { let RenderMethod = "addImmOperands"; let PredicateMethod = "isImmediate<" # Low # "," # High # ">"; - let DiagnosticType = "ImmRange" # Low # "_" # High; + let DiagnosticString = "operand must be an immediate in the range [" # Low # "," # High # "]"; } class ImmAsmOperandMinusOne<int Low, int High> : AsmOperandClass { let PredicateMethod = "isImmediate<" # Low # "," # High # ">"; let DiagnosticType = "ImmRange" # Low # "_" # High; + let DiagnosticString = "operand must be an immediate in the range [" # Low # "," # High # "]"; } // Operands that are part of a memory addressing mode. @@ -517,7 +526,10 @@ def reglist : Operand<i32> { def GPRPairOp : RegisterOperand<GPRPair, "printGPRPairOperand">; -def DPRRegListAsmOperand : AsmOperandClass { let Name = "DPRRegList"; } +def DPRRegListAsmOperand : AsmOperandClass { + let Name = "DPRRegList"; + let DiagnosticType = "DPR_RegList"; +} def dpr_reglist : Operand<i32> { let EncoderMethod = "getRegisterListOpValue"; let ParserMatchClass = DPRRegListAsmOperand; @@ -525,7 +537,10 @@ def dpr_reglist : Operand<i32> { let DecoderMethod = "DecodeDPRRegListOperand"; } -def SPRRegListAsmOperand : AsmOperandClass { let Name = "SPRRegList"; } +def SPRRegListAsmOperand : AsmOperandClass { + let Name = "SPRRegList"; + let DiagnosticString = "operand must be a list of registers in range [s0, s31]"; +} def spr_reglist : Operand<i32> { let EncoderMethod = "getRegisterListOpValue"; let ParserMatchClass = SPRRegListAsmOperand; @@ -748,7 +763,6 @@ def imm1_31 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 32; }]> { /// imm0_15 predicate - Immediate in the range [0,15]. def Imm0_15AsmOperand: ImmAsmOperand<0,15> { let Name = "Imm0_15"; - let DiagnosticType = "ImmRange0_15"; } def imm0_15 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 16; @@ -783,7 +797,6 @@ def imm0_63 : Operand<i32>, ImmLeaf<i32, [{ /// imm0_239 predicate - Immediate in the range [0,239]. def Imm0_239AsmOperand : ImmAsmOperand<0,239> { let Name = "Imm0_239"; - let DiagnosticType = "ImmRange0_239"; } def imm0_239 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 240; }]> { let ParserMatchClass = Imm0_239AsmOperand; @@ -817,6 +830,7 @@ def imm0_65535_neg : Operand<i32>, ImmLeaf<i32, [{ def Imm0_65535ExprAsmOperand: AsmOperandClass { let Name = "Imm0_65535Expr"; let RenderMethod = "addImmOperands"; + let DiagnosticString = "operand must be an immediate in the range [0,0xffff] or a relocatable expression"; } def imm0_65535_expr : Operand<i32> { @@ -830,7 +844,10 @@ def imm256_65535_expr : Operand<i32> { } /// imm24b - True if the 32-bit immediate is encodable in 24 bits. -def Imm24bitAsmOperand: ImmAsmOperand<0,0xffffff> { let Name = "Imm24bit"; } +def Imm24bitAsmOperand: ImmAsmOperand<0,0xffffff> { + let Name = "Imm24bit"; + let DiagnosticString = "operand must be an immediate in the range [0,0xffffff]"; +} def imm24b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm <= 0xffffff; }]> { @@ -960,21 +977,6 @@ def postidx_reg : MemOperand { let MIOperandInfo = (ops GPRnopc, i32imm); } - -// addrmode2 := reg +/- imm12 -// := reg +/- reg shop imm -// -// FIXME: addrmode2 should be refactored the rest of the way to always -// use explicit imm vs. reg versions above (addrmode_imm12 and ldst_so_reg). -def AddrMode2AsmOperand : AsmOperandClass { let Name = "AddrMode2"; } -def addrmode2 : MemOperand, - ComplexPattern<i32, 3, "SelectAddrMode2", []> { - let EncoderMethod = "getAddrMode2OpValue"; - let PrintMethod = "printAddrMode2Operand"; - let ParserMatchClass = AddrMode2AsmOperand; - let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); -} - def PostIdxRegShiftedAsmOperand : AsmOperandClass { let Name = "PostIdxRegShifted"; let ParserMethod = "parsePostIdxReg"; @@ -1123,7 +1125,7 @@ class AddrMode6Align : MemOperand, // VLD/VST instructions and checking the alignment is not specified. def AddrMode6AlignNoneAsmOperand : AsmOperandClass { let Name = "AlignedMemoryNone"; - let DiagnosticType = "AlignedMemoryRequiresNone"; + let DiagnosticString = "alignment must be omitted"; } def addrmode6alignNone : AddrMode6Align { // The alignment specifier can only be omitted. @@ -1134,7 +1136,7 @@ def addrmode6alignNone : AddrMode6Align { // VLD/VST instructions and checking the alignment value. def AddrMode6Align16AsmOperand : AsmOperandClass { let Name = "AlignedMemory16"; - let DiagnosticType = "AlignedMemoryRequires16"; + let DiagnosticString = "alignment must be 16 or omitted"; } def addrmode6align16 : AddrMode6Align { // The alignment specifier can only be 16 or omitted. @@ -1145,7 +1147,7 @@ def addrmode6align16 : AddrMode6Align { // VLD/VST instructions and checking the alignment value. def AddrMode6Align32AsmOperand : AsmOperandClass { let Name = "AlignedMemory32"; - let DiagnosticType = "AlignedMemoryRequires32"; + let DiagnosticString = "alignment must be 32 or omitted"; } def addrmode6align32 : AddrMode6Align { // The alignment specifier can only be 32 or omitted. @@ -1156,7 +1158,7 @@ def addrmode6align32 : AddrMode6Align { // VLD/VST instructions and checking the alignment value. def AddrMode6Align64AsmOperand : AsmOperandClass { let Name = "AlignedMemory64"; - let DiagnosticType = "AlignedMemoryRequires64"; + let DiagnosticString = "alignment must be 64 or omitted"; } def addrmode6align64 : AddrMode6Align { // The alignment specifier can only be 64 or omitted. @@ -1167,7 +1169,7 @@ def addrmode6align64 : AddrMode6Align { // for VLD/VST instructions and checking the alignment value. def AddrMode6Align64or128AsmOperand : AsmOperandClass { let Name = "AlignedMemory64or128"; - let DiagnosticType = "AlignedMemoryRequires64or128"; + let DiagnosticString = "alignment must be 64, 128 or omitted"; } def addrmode6align64or128 : AddrMode6Align { // The alignment specifier can only be 64, 128 or omitted. @@ -1178,7 +1180,7 @@ def addrmode6align64or128 : AddrMode6Align { // encoding for VLD/VST instructions and checking the alignment value. def AddrMode6Align64or128or256AsmOperand : AsmOperandClass { let Name = "AlignedMemory64or128or256"; - let DiagnosticType = "AlignedMemoryRequires64or128or256"; + let DiagnosticString = "alignment must be 64, 128, 256 or omitted"; } def addrmode6align64or128or256 : AddrMode6Align { // The alignment specifier can only be 64, 128, 256 or omitted. @@ -1209,7 +1211,7 @@ class AddrMode6DupAlign : MemOperand, // VLD-dup instruction and checking the alignment is not specified. def AddrMode6dupAlignNoneAsmOperand : AsmOperandClass { let Name = "DupAlignedMemoryNone"; - let DiagnosticType = "DupAlignedMemoryRequiresNone"; + let DiagnosticString = "alignment must be omitted"; } def addrmode6dupalignNone : AddrMode6DupAlign { // The alignment specifier can only be omitted. @@ -1220,7 +1222,7 @@ def addrmode6dupalignNone : AddrMode6DupAlign { // instruction and checking the alignment value. def AddrMode6dupAlign16AsmOperand : AsmOperandClass { let Name = "DupAlignedMemory16"; - let DiagnosticType = "DupAlignedMemoryRequires16"; + let DiagnosticString = "alignment must be 16 or omitted"; } def addrmode6dupalign16 : AddrMode6DupAlign { // The alignment specifier can only be 16 or omitted. @@ -1231,7 +1233,7 @@ def addrmode6dupalign16 : AddrMode6DupAlign { // instruction and checking the alignment value. def AddrMode6dupAlign32AsmOperand : AsmOperandClass { let Name = "DupAlignedMemory32"; - let DiagnosticType = "DupAlignedMemoryRequires32"; + let DiagnosticString = "alignment must be 32 or omitted"; } def addrmode6dupalign32 : AddrMode6DupAlign { // The alignment specifier can only be 32 or omitted. @@ -1242,7 +1244,7 @@ def addrmode6dupalign32 : AddrMode6DupAlign { // instructions and checking the alignment value. def AddrMode6dupAlign64AsmOperand : AsmOperandClass { let Name = "DupAlignedMemory64"; - let DiagnosticType = "DupAlignedMemoryRequires64"; + let DiagnosticString = "alignment must be 64 or omitted"; } def addrmode6dupalign64 : AddrMode6DupAlign { // The alignment specifier can only be 64 or omitted. @@ -1253,7 +1255,7 @@ def addrmode6dupalign64 : AddrMode6DupAlign { // for VLD instructions and checking the alignment value. def AddrMode6dupAlign64or128AsmOperand : AsmOperandClass { let Name = "DupAlignedMemory64or128"; - let DiagnosticType = "DupAlignedMemoryRequires64or128"; + let DiagnosticString = "alignment must be 64, 128 or omitted"; } def addrmode6dupalign64or128 : AddrMode6DupAlign { // The alignment specifier can only be 64, 128 or omitted. @@ -2369,12 +2371,15 @@ let isBranch = 1, isTerminator = 1 in { 0, IIC_Br, [(ARMbrjt GPR:$target, tjumptable:$jt)]>, Sched<[WriteBr]>; - // FIXME: This shouldn't use the generic "addrmode2," but rather be split - // into i12 and rs suffixed versions. - def BR_JTm : ARMPseudoInst<(outs), - (ins addrmode2:$target, i32imm:$jt), + def BR_JTm_i12 : ARMPseudoInst<(outs), + (ins addrmode_imm12:$target, i32imm:$jt), 0, IIC_Br, - [(ARMbrjt (i32 (load addrmode2:$target)), + [(ARMbrjt (i32 (load addrmode_imm12:$target)), + tjumptable:$jt)]>, Sched<[WriteBrTbl]>; + def BR_JTm_rs : ARMPseudoInst<(outs), + (ins ldst_so_reg:$target, i32imm:$jt), + 0, IIC_Br, + [(ARMbrjt (i32 (load ldst_so_reg:$target)), tjumptable:$jt)]>, Sched<[WriteBrTbl]>; def BR_JTadd : ARMPseudoInst<(outs), (ins GPR:$target, GPR:$idx, i32imm:$jt), @@ -5033,6 +5038,8 @@ def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, let Inst{15-12} = CRd; let Inst{19-16} = CRn; let Inst{23-20} = opc1; + + let DecoderNamespace = "CoProc"; } def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, @@ -5056,6 +5063,8 @@ def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, let Inst{15-12} = CRd; let Inst{19-16} = CRn; let Inst{23-20} = opc1; + + let DecoderNamespace = "CoProc"; } class ACI<dag oops, dag iops, string opc, string asm, @@ -5071,6 +5080,8 @@ class ACInoP<dag oops, dag iops, string opc, string asm, let Inst{31-28} = 0b1111; let Inst{27-25} = 0b110; } + +let DecoderNamespace = "CoProc" in { multiclass LdStCop<bit load, bit Dbit, string asm, list<dag> pattern> { def _OFFSET : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), asm, "\t$cop, $CRd, $addr", pattern> { @@ -5224,6 +5235,8 @@ defm STCL : LdStCop <0, 1, "stcl", [(int_arm_stcl imm:$cop, imm:$CRd, addrmode5 defm STC2 : LdSt2Cop<0, 0, "stc2", [(int_arm_stc2 imm:$cop, imm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>; defm STC2L : LdSt2Cop<0, 1, "stc2l", [(int_arm_stc2l imm:$cop, imm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>; +} // DecoderNamespace = "CoProc" + //===----------------------------------------------------------------------===// // Move between coprocessor and ARM core register. // @@ -5248,6 +5261,8 @@ class MovRCopro<string opc, bit direction, dag oops, dag iops, let Inst{7-5} = opc2; let Inst{3-0} = CRm; let Inst{19-16} = CRn; + + let DecoderNamespace = "CoProc"; } def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */, @@ -5292,6 +5307,8 @@ class MovRCopro2<string opc, bit direction, dag oops, dag iops, let Inst{7-5} = opc2; let Inst{3-0} = CRm; let Inst{19-16} = CRn; + + let DecoderNamespace = "CoProc"; } def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */, @@ -5519,9 +5536,14 @@ let usesCustomInserter = 1, Defs = [CPSR] in let isCall = 1, Defs = [R0, R12, LR, CPSR], Uses = [SP] in { def TPsoft : ARMPseudoInst<(outs), (ins), 4, IIC_Br, - [(set R0, ARMthread_pointer)]>, Sched<[WriteBr]>; + [(set R0, ARMthread_pointer)]>, Sched<[WriteBr]>, + Requires<[IsARM, IsReadTPSoft]>; } +// Reading thread pointer from coprocessor register +def : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 3)>, + Requires<[IsARM, IsReadTPHard]>; + //===----------------------------------------------------------------------===// // SJLJ Exception handling intrinsics // eh_sjlj_setjmp() is an instruction sequence to store the return @@ -5618,26 +5640,26 @@ let isReMaterializable = 1 in { def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), IIC_iMOVix2addpc, [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, - Requires<[IsARM, UseMovt]>; + Requires<[IsARM, UseMovtInPic]>; def LDRLIT_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadiALU, [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, - Requires<[IsARM, DontUseMovt]>; + Requires<[IsARM, DontUseMovtInPic]>; let AddedComplexity = 10 in def LDRLIT_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), NoItinerary, [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>, - Requires<[IsARM, DontUseMovt]>; + Requires<[IsARM, DontUseMovtInPic]>; let AddedComplexity = 10 in def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), IIC_iMOVix2ld, [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>, - Requires<[IsARM, UseMovt]>; + Requires<[IsARM, UseMovtInPic]>; } // isReMaterializable // The many different faces of TLS access. @@ -5650,15 +5672,15 @@ def : Pat<(ARMWrapper tglobaltlsaddr:$src), Requires<[IsARM, DontUseMovt]>; def : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr), - (MOV_ga_pcrel tglobaltlsaddr:$addr)>, Requires<[IsARM, UseMovt]>; + (MOV_ga_pcrel tglobaltlsaddr:$addr)>, Requires<[IsARM, UseMovtInPic]>; def : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr), (LDRLIT_ga_pcrel tglobaltlsaddr:$addr)>, - Requires<[IsARM, DontUseMovt]>; + Requires<[IsARM, DontUseMovtInPic]>; let AddedComplexity = 10 in def : Pat<(load (ARMWrapperPIC tglobaltlsaddr:$addr)), (MOV_ga_pcrel_ldr tglobaltlsaddr:$addr)>, - Requires<[IsARM, UseMovt]>; + Requires<[IsARM, UseMovtInPic]>; // ConstantPool, GlobalAddress, and JumpTable |
