summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMInstrInfo.td
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/Target/ARM/ARMInstrInfo.td
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'lib/Target/ARM/ARMInstrInfo.td')
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td112
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