diff options
Diffstat (limited to 'lib/Target/ARM/ARMInstrFormats.td')
-rw-r--r-- | lib/Target/ARM/ARMInstrFormats.td | 212 |
1 files changed, 177 insertions, 35 deletions
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index e79608d360ca..37a83f70a1fb 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -246,23 +246,33 @@ def shr_imm64 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 64; }]> { let ParserMatchClass = shr_imm64_asm_operand; } + +// ARM Assembler operand for ldr Rd, =expression which generates an offset +// to a constant pool entry or a MOV depending on the value of expression +def const_pool_asm_operand : AsmOperandClass { let Name = "ConstPoolAsmImm"; } +def const_pool_asm_imm : Operand<i32> { + let ParserMatchClass = const_pool_asm_operand; +} + + //===----------------------------------------------------------------------===// // ARM Assembler alias templates. // -class ARMInstAlias<string Asm, dag Result, bit Emit = 0b1> - : InstAlias<Asm, Result, Emit>, Requires<[IsARM]>; -class tInstAlias<string Asm, dag Result, bit Emit = 0b1> - : InstAlias<Asm, Result, Emit>, Requires<[IsThumb]>; -class t2InstAlias<string Asm, dag Result, bit Emit = 0b1> - : InstAlias<Asm, Result, Emit>, Requires<[IsThumb2]>; -class VFP2InstAlias<string Asm, dag Result, bit Emit = 0b1> - : InstAlias<Asm, Result, Emit>, Requires<[HasVFP2]>; -class VFP2DPInstAlias<string Asm, dag Result, bit Emit = 0b1> - : InstAlias<Asm, Result, Emit>, Requires<[HasVFP2,HasDPVFP]>; -class VFP3InstAlias<string Asm, dag Result, bit Emit = 0b1> - : InstAlias<Asm, Result, Emit>, Requires<[HasVFP3]>; -class NEONInstAlias<string Asm, dag Result, bit Emit = 0b1> - : InstAlias<Asm, Result, Emit>, Requires<[HasNEON]>; +// Note: When EmitPriority == 1, the alias will be used for printing +class ARMInstAlias<string Asm, dag Result, bit EmitPriority = 0> + : InstAlias<Asm, Result, EmitPriority>, Requires<[IsARM]>; +class tInstAlias<string Asm, dag Result, bit EmitPriority = 0> + : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb]>; +class t2InstAlias<string Asm, dag Result, bit EmitPriority = 0> + : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb2]>; +class VFP2InstAlias<string Asm, dag Result, bit EmitPriority = 0> + : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2]>; +class VFP2DPInstAlias<string Asm, dag Result, bit EmitPriority = 0> + : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2,HasDPVFP]>; +class VFP3InstAlias<string Asm, dag Result, bit EmitPriority = 0> + : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP3]>; +class NEONInstAlias<string Asm, dag Result, bit EmitPriority = 0> + : InstAlias<Asm, Result, EmitPriority>, Requires<[HasNEON]>; class VFP2MnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>, @@ -563,12 +573,12 @@ class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, class AIldaex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern> : AIldr_ex_or_acq<opcod, 0b10, oops, iops, itin, opc, asm, pattern>, - Requires<[IsARM, HasV8]>; + Requires<[IsARM, HasAcquireRelease, HasV7Clrex]>; class AIstlex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern> : AIstr_ex_or_rel<opcod, 0b10, oops, iops, itin, opc, asm, pattern>, - Requires<[IsARM, HasV8]> { + Requires<[IsARM, HasAcquireRelease, HasV7Clrex]> { bits<4> Rd; let Inst{15-12} = Rd; } @@ -593,12 +603,12 @@ class AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern> class AIldracq<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern> : AIldr_ex_or_acq<opcod, 0b00, oops, iops, itin, opc, asm, pattern>, - Requires<[IsARM, HasV8]>; + Requires<[IsARM, HasAcquireRelease]>; class AIstrrel<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern> : AIstr_ex_or_rel<opcod, 0b00, oops, iops, itin, opc, asm, pattern>, - Requires<[IsARM, HasV8]> { + Requires<[IsARM, HasAcquireRelease]> { let Inst{15-12} = 0b1111; } @@ -1379,11 +1389,6 @@ class T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre, let DecoderMethod = "DecodeT2LdStPre"; } -// Tv5Pat - Same as Pat<>, but requires V5T Thumb mode. -class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> { - list<Predicate> Predicates = [IsThumb, IsThumb1Only, HasV5T]; -} - // T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode. class T1Pat<dag pattern, dag result> : Pat<pattern, result> { list<Predicate> Predicates = [IsThumb, IsThumb1Only]; @@ -1495,6 +1500,32 @@ class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, let D = VFPNeonDomain; } +class AHI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, + InstrItinClass itin, + string opc, string asm, list<dag> pattern> + : VFPI<oops, iops, AddrMode5, 4, IndexModeNone, + VFPLdStFrm, itin, opc, asm, "", pattern> { + list<Predicate> Predicates = [HasFullFP16]; + + // Instruction operands. + bits<5> Sd; + bits<13> addr; + + // Encode instruction operands. + let Inst{23} = addr{8}; // U (add = (U == '1')) + let Inst{22} = Sd{0}; + let Inst{19-16} = addr{12-9}; // Rn + let Inst{15-12} = Sd{4-1}; + let Inst{7-0} = addr{7-0}; // imm8 + + let Inst{27-24} = opcod1; + let Inst{21-20} = opcod2; + let Inst{11-8} = 0b1001; // Half precision + + // Loads & stores operate on both NEON and VFP pipelines. + let D = VFPNeonDomain; +} + // VFP Load / store multiple pseudo instructions. class PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr, list<dag> pattern> @@ -1817,6 +1848,114 @@ class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, let Inst{22} = Sd{0}; } +// Half precision, unary, predicated +class AHuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, + bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, + string asm, list<dag> pattern> + : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { + list<Predicate> Predicates = [HasFullFP16]; + + // Instruction operands. + bits<5> Sd; + bits<5> Sm; + + // Encode instruction operands. + let Inst{3-0} = Sm{4-1}; + let Inst{5} = Sm{0}; + let Inst{15-12} = Sd{4-1}; + let Inst{22} = Sd{0}; + + let Inst{27-23} = opcod1; + let Inst{21-20} = opcod2; + let Inst{19-16} = opcod3; + let Inst{11-8} = 0b1001; // Half precision + let Inst{7-6} = opcod4; + let Inst{4} = opcod5; +} + +// Half precision, unary, non-predicated +class AHuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, + bit opcod5, dag oops, dag iops, InstrItinClass itin, + string asm, list<dag> pattern> + : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, + VFPUnaryFrm, itin, asm, "", pattern> { + list<Predicate> Predicates = [HasFullFP16]; + + // Instruction operands. + bits<5> Sd; + bits<5> Sm; + + let Inst{31-28} = 0b1111; + + // Encode instruction operands. + let Inst{3-0} = Sm{4-1}; + let Inst{5} = Sm{0}; + let Inst{15-12} = Sd{4-1}; + let Inst{22} = Sd{0}; + + let Inst{27-23} = opcod1; + let Inst{21-20} = opcod2; + let Inst{19-16} = opcod3; + let Inst{11-8} = 0b1001; // Half precision + let Inst{7-6} = opcod4; + let Inst{4} = opcod5; +} + +// Half precision, binary +class AHbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, + InstrItinClass itin, string opc, string asm, list<dag> pattern> + : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { + list<Predicate> Predicates = [HasFullFP16]; + + // Instruction operands. + bits<5> Sd; + bits<5> Sn; + bits<5> Sm; + + // Encode instruction operands. + let Inst{3-0} = Sm{4-1}; + let Inst{5} = Sm{0}; + let Inst{19-16} = Sn{4-1}; + let Inst{7} = Sn{0}; + let Inst{15-12} = Sd{4-1}; + let Inst{22} = Sd{0}; + + let Inst{27-23} = opcod1; + let Inst{21-20} = opcod2; + let Inst{11-8} = 0b1001; // Half precision + let Inst{6} = op6; + let Inst{4} = op4; +} + +// Half precision, binary, not predicated +class AHbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, + InstrItinClass itin, string asm, list<dag> pattern> + : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, + VFPBinaryFrm, itin, asm, "", pattern> { + list<Predicate> Predicates = [HasFullFP16]; + + // Instruction operands. + bits<5> Sd; + bits<5> Sn; + bits<5> Sm; + + let Inst{31-28} = 0b1111; + + // Encode instruction operands. + let Inst{3-0} = Sm{4-1}; + let Inst{5} = Sm{0}; + let Inst{19-16} = Sn{4-1}; + let Inst{7} = Sn{0}; + let Inst{15-12} = Sd{4-1}; + let Inst{22} = Sd{0}; + + let Inst{27-23} = opcod1; + let Inst{21-20} = opcod2; + let Inst{11-8} = 0b1001; // Half precision + let Inst{6} = opcod3; + let Inst{4} = 0; +} + // VFP conversion instructions class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, dag oops, dag iops, InstrItinClass itin, string opc, string asm, @@ -2321,22 +2460,25 @@ class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> { } // VFP/NEON Instruction aliases for type suffices. -class VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result> : - InstAlias<!strconcat(opc, dt, "\t", asm), Result>, Requires<[HasVFP2]>; +// Note: When EmitPriority == 1, the alias will be used for printing +class VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result, bit EmitPriority = 0> : + InstAlias<!strconcat(opc, dt, "\t", asm), Result, EmitPriority>, Requires<[HasVFP2]>; -multiclass VFPDTAnyInstAlias<string opc, string asm, dag Result> { - def : VFPDataTypeInstAlias<opc, ".8", asm, Result>; - def : VFPDataTypeInstAlias<opc, ".16", asm, Result>; - def : VFPDataTypeInstAlias<opc, ".32", asm, Result>; - def : VFPDataTypeInstAlias<opc, ".64", asm, Result>; +// Note: When EmitPriority == 1, the alias will be used for printing +multiclass VFPDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> { + def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>; + def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>; + def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>; + def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>; } -multiclass NEONDTAnyInstAlias<string opc, string asm, dag Result> { +// Note: When EmitPriority == 1, the alias will be used for printing +multiclass NEONDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> { let Predicates = [HasNEON] in { - def : VFPDataTypeInstAlias<opc, ".8", asm, Result>; - def : VFPDataTypeInstAlias<opc, ".16", asm, Result>; - def : VFPDataTypeInstAlias<opc, ".32", asm, Result>; - def : VFPDataTypeInstAlias<opc, ".64", asm, Result>; + def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>; + def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>; + def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>; + def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>; } } |