X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FARMInstrFormats.td;h=ea9cdc9ca6144ba5ca32aec56cdadf1a7bcb3a6b;hb=adb561d4e0a37c21159405dde90d2ef2d1a5eef9;hp=ce39a3f737676af471de3a2191c9b99c8edb975f;hpb=53e4471adcf34cac253d2486e6b29c331e2d973e;p=oota-llvm.git diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index ce39a3f7376..ea9cdc9ca61 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -33,6 +33,8 @@ def LdMiscFrm : Format<8>; def StMiscFrm : Format<9>; def LdStMulFrm : Format<10>; +def LdStExFrm : Format<28>; + def ArithMiscFrm : Format<11>; def ExtFrm : Format<12>; @@ -54,6 +56,9 @@ def NEONGetLnFrm : Format<25>; def NEONSetLnFrm : Format<26>; def NEONDupFrm : Format<27>; +def MiscFrm : Format<29>; +def ThumbMiscFrm : Format<30>; + // Misc flags. // the instruction has a Rn register operand. @@ -108,6 +113,15 @@ def IndexModeNone : IndexMode<0>; def IndexModePre : IndexMode<1>; def IndexModePost : IndexMode<2>; +// Instruction execution domain. +class Domain val> { + bits<2> Value = val; +} +def GenericDomain : Domain<0>; +def VFPDomain : Domain<1>; // Instructions in VFP domain only +def NeonDomain : Domain<2>; // Instructions in Neon domain only +def VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains + //===----------------------------------------------------------------------===// // ARM special operands. @@ -135,11 +149,9 @@ def s_cc_out : OptionalDefOperand { // ARM Instruction templates. // -class InstARM +class InstTemplate : Instruction { - field bits<32> Inst; - let Namespace = "ARM"; // TSFlagsFields @@ -155,6 +167,9 @@ class InstARM Form = F.Value; + Domain D = d; + bits<2> Dom = D.Value; + // // Attributes specific to ARM instructions... // @@ -162,10 +177,27 @@ class InstARM Inst; } -class PseudoInst pattern> - : InstARM { +class InstARM + : InstTemplate, Encoding; + +// This Encoding-less class is used by Thumb1 to specify the encoding bits later +// on by adding flavors to specific instructions. +class InstThumb + : InstTemplate; + +class PseudoInst pattern> + : InstARM { let OutOperandList = oops; let InOperandList = iops; let AsmString = asm; @@ -174,23 +206,38 @@ class PseudoInst pattern> // Almost all ARM instructions are predicable. class I pattern> - : InstARM { + : InstARM { let OutOperandList = oops; let InOperandList = !con(iops, (ops pred:$p)); let AsmString = !strconcat(opc, !strconcat("${p}", asm)); let Pattern = pattern; list Predicates = [IsARM]; } +// A few are not predicable +class InoP pattern> + : InstARM { + let OutOperandList = oops; + let InOperandList = iops; + let AsmString = !strconcat(opc, asm); + let Pattern = pattern; + let isPredicable = 0; + list Predicates = [IsARM]; +} // Same as I except it can optionally modify CPSR. Note it's modeled as // an input operand since by default it's a zero register. It will // become an implicit def once it's "flipped". class sI pattern> - : InstARM { + : InstARM { let OutOperandList = oops; let InOperandList = !con(iops, (ops pred:$p, cc_out:$s)); let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm)); @@ -200,8 +247,9 @@ class sI pattern> - : InstARM { + IndexMode im, Format f, InstrItinClass itin, + string asm, string cstr, list pattern> + : InstARM { let OutOperandList = oops; let InOperandList = iops; let AsmString = asm; @@ -209,90 +257,119 @@ class XI Predicates = [IsARM]; } -class AI pattern> - : I; -class AsI pattern> + : I; +class AsI pattern> + : sI; +class AXI pattern> - : sI; -class AXI pattern> - : XI; +class AInoP pattern> + : InoP; // Ctrl flow instructions -class ABI opcod, dag oops, dag iops, string opc, - string asm, list pattern> - : I { +class ABI opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : I { let Inst{27-24} = opcod; } -class ABXI opcod, dag oops, dag iops, string asm, list pattern> - : XI { +class ABXI opcod, dag oops, dag iops, InstrItinClass itin, + string asm, list pattern> + : XI { let Inst{27-24} = opcod; } -class ABXIx2 pattern> - : XI; +class ABXIx2 pattern> + : XI; // BR_JT instructions -class JTI pattern> - : XI pattern> + : XI; + +// Atomic load/store instructions + +class AIldrex opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : I { + let Inst{27-23} = 0b00011; + let Inst{22-21} = opcod; + let Inst{20} = 1; + let Inst{11-0} = 0b111110011111; +} +class AIstrex opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : I { + let Inst{27-23} = 0b00011; + let Inst{22-21} = opcod; + let Inst{20} = 0; + let Inst{11-4} = 0b11111001; +} + // addrmode1 instructions -class AI1 opcod, dag oops, dag iops, Format f, string opc, - string asm, list pattern> - : I { +class AI1 opcod, dag oops, dag iops, Format f, InstrItinClass itin, + string opc, string asm, list pattern> + : I { let Inst{24-21} = opcod; let Inst{27-26} = {0,0}; } -class AsI1 opcod, dag oops, dag iops, Format f, string opc, - string asm, list pattern> - : sI { +class AsI1 opcod, dag oops, dag iops, Format f, InstrItinClass itin, + string opc, string asm, list pattern> + : sI { let Inst{24-21} = opcod; let Inst{27-26} = {0,0}; } -class AXI1 opcod, dag oops, dag iops, Format f, string asm, - list pattern> - : XI { +class AXI1 opcod, dag oops, dag iops, Format f, InstrItinClass itin, + string asm, list pattern> + : XI { let Inst{24-21} = opcod; let Inst{27-26} = {0,0}; } -class AI1x2 pattern> - : I; +class AI1x2 pattern> + : I; // addrmode2 loads and stores -class AI2 pattern> - : I { +class AI2 pattern> + : I { let Inst{27-26} = {0,1}; } // loads -class AI2ldw pattern> - : I { +class AI2ldw pattern> + : I { let Inst{20} = 1; // L bit let Inst{21} = 0; // W bit let Inst{22} = 0; // B bit let Inst{24} = 1; // P bit let Inst{27-26} = {0,1}; } -class AXI2ldw pattern> - : XI pattern> + : XI { let Inst{20} = 1; // L bit let Inst{21} = 0; // W bit @@ -300,19 +377,19 @@ class AXI2ldw pattern> - : I { +class AI2ldb pattern> + : I { let Inst{20} = 1; // L bit let Inst{21} = 0; // W bit let Inst{22} = 1; // B bit let Inst{24} = 1; // P bit let Inst{27-26} = {0,1}; } -class AXI2ldb pattern> - : XI pattern> + : XI { let Inst{20} = 1; // L bit let Inst{21} = 0; // W bit @@ -322,19 +399,19 @@ class AXI2ldb pattern> - : I { +class AI2stw pattern> + : I { let Inst{20} = 0; // L bit let Inst{21} = 0; // W bit let Inst{22} = 0; // B bit let Inst{24} = 1; // P bit let Inst{27-26} = {0,1}; } -class AXI2stw pattern> - : XI pattern> + : XI { let Inst{20} = 0; // L bit let Inst{21} = 0; // W bit @@ -342,19 +419,19 @@ class AXI2stw pattern> - : I { +class AI2stb pattern> + : I { let Inst{20} = 0; // L bit let Inst{21} = 0; // W bit let Inst{22} = 1; // B bit let Inst{24} = 1; // P bit let Inst{27-26} = {0,1}; } -class AXI2stb pattern> - : XI pattern> + : XI { let Inst{20} = 0; // L bit let Inst{21} = 0; // W bit @@ -364,20 +441,20 @@ class AXI2stb pattern> - : I { +class AI2ldwpr pattern> + : I { let Inst{20} = 1; // L bit let Inst{21} = 1; // W bit let Inst{22} = 0; // B bit let Inst{24} = 1; // P bit let Inst{27-26} = {0,1}; } -class AI2ldbpr pattern> - : I { +class AI2ldbpr pattern> + : I { let Inst{20} = 1; // L bit let Inst{21} = 1; // W bit let Inst{22} = 1; // B bit @@ -386,20 +463,20 @@ class AI2ldbpr pattern> - : I { +class AI2stwpr pattern> + : I { let Inst{20} = 0; // L bit let Inst{21} = 1; // W bit let Inst{22} = 0; // B bit let Inst{24} = 1; // P bit let Inst{27-26} = {0,1}; } -class AI2stbpr pattern> - : I { +class AI2stbpr pattern> + : I { let Inst{20} = 0; // L bit let Inst{21} = 1; // W bit let Inst{22} = 1; // B bit @@ -408,20 +485,20 @@ class AI2stbpr pattern> - : I { +class AI2ldwpo pattern> + : I { let Inst{20} = 1; // L bit let Inst{21} = 0; // W bit let Inst{22} = 0; // B bit let Inst{24} = 0; // P bit let Inst{27-26} = {0,1}; } -class AI2ldbpo pattern> - : I { +class AI2ldbpo pattern> + : I { let Inst{20} = 1; // L bit let Inst{21} = 0; // W bit let Inst{22} = 1; // B bit @@ -430,20 +507,20 @@ class AI2ldbpo pattern> - : I { +class AI2stwpo pattern> + : I { let Inst{20} = 0; // L bit let Inst{21} = 0; // W bit let Inst{22} = 0; // B bit let Inst{24} = 0; // P bit let Inst{27-26} = {0,1}; } -class AI2stbpo pattern> - : I { +class AI2stbpo pattern> + : I { let Inst{20} = 0; // L bit let Inst{21} = 0; // W bit let Inst{22} = 1; // B bit @@ -452,20 +529,20 @@ class AI2stbpo pattern> - : I; -class AXI3 pattern> - : XI; +class AI3 pattern> + : I; +class AXI3 pattern> + : XI; // loads -class AI3ldh pattern> - : I { +class AI3ldh pattern> + : I { let Inst{4} = 1; let Inst{5} = 1; // H bit let Inst{6} = 0; // S bit @@ -475,9 +552,9 @@ class AI3ldh pattern> - : XI pattern> + : XI { let Inst{4} = 1; let Inst{5} = 1; // H bit @@ -487,10 +564,10 @@ class AXI3ldh pattern> - : I { +class AI3ldsh pattern> + : I { let Inst{4} = 1; let Inst{5} = 1; // H bit let Inst{6} = 1; // S bit @@ -500,9 +577,9 @@ class AI3ldsh pattern> - : XI pattern> + : XI { let Inst{4} = 1; let Inst{5} = 1; // H bit @@ -512,10 +589,10 @@ class AXI3ldsh pattern> - : I { +class AI3ldsb pattern> + : I { let Inst{4} = 1; let Inst{5} = 0; // H bit let Inst{6} = 1; // S bit @@ -525,9 +602,9 @@ class AI3ldsb pattern> - : XI pattern> + : XI { let Inst{4} = 1; let Inst{5} = 0; // H bit @@ -537,10 +614,10 @@ class AXI3ldsb pattern> - : I { +class AI3ldd pattern> + : I { let Inst{4} = 1; let Inst{5} = 0; // H bit let Inst{6} = 1; // S bit @@ -552,10 +629,10 @@ class AI3ldd pattern> - : I { +class AI3sth pattern> + : I { let Inst{4} = 1; let Inst{5} = 1; // H bit let Inst{6} = 0; // S bit @@ -565,9 +642,9 @@ class AI3sth pattern> - : XI pattern> + : XI { let Inst{4} = 1; let Inst{5} = 1; // H bit @@ -577,10 +654,10 @@ class AXI3sth pattern> - : I { +class AI3std pattern> + : I { let Inst{4} = 1; let Inst{5} = 1; // H bit let Inst{6} = 1; // S bit @@ -592,10 +669,10 @@ class AI3std pattern> - : I { +class AI3ldhpr pattern> + : I { let Inst{4} = 1; let Inst{5} = 1; // H bit let Inst{6} = 0; // S bit @@ -605,10 +682,10 @@ class AI3ldhpr pattern> - : I { +class AI3ldshpr pattern> + : I { let Inst{4} = 1; let Inst{5} = 1; // H bit let Inst{6} = 1; // S bit @@ -618,10 +695,10 @@ class AI3ldshpr pattern> - : I { +class AI3ldsbpr pattern> + : I { let Inst{4} = 1; let Inst{5} = 0; // H bit let Inst{6} = 1; // S bit @@ -633,10 +710,10 @@ class AI3ldsbpr pattern> - : I { +class AI3sthpr pattern> + : I { let Inst{4} = 1; let Inst{5} = 1; // H bit let Inst{6} = 0; // S bit @@ -648,51 +725,51 @@ class AI3sthpr pattern> - : I { +class AI3ldhpo pattern> + : I { let Inst{4} = 1; let Inst{5} = 1; // H bit let Inst{6} = 0; // S bit let Inst{7} = 1; let Inst{20} = 1; // L bit - let Inst{21} = 1; // W bit + let Inst{21} = 0; // W bit let Inst{24} = 0; // P bit let Inst{27-25} = 0b000; } -class AI3ldshpo pattern> - : I { +class AI3ldshpo pattern> + : I { let Inst{4} = 1; let Inst{5} = 1; // H bit let Inst{6} = 1; // S bit let Inst{7} = 1; let Inst{20} = 1; // L bit - let Inst{21} = 1; // W bit + let Inst{21} = 0; // W bit let Inst{24} = 0; // P bit let Inst{27-25} = 0b000; } -class AI3ldsbpo pattern> - : I { +class AI3ldsbpo pattern> + : I { let Inst{4} = 1; let Inst{5} = 0; // H bit let Inst{6} = 1; // S bit let Inst{7} = 1; let Inst{20} = 1; // L bit - let Inst{21} = 1; // W bit + let Inst{21} = 0; // W bit let Inst{24} = 0; // P bit let Inst{27-25} = 0b000; } // Post-indexed stores -class AI3sthpo pattern> - : I { +class AI3sthpo pattern> + : I { let Inst{4} = 1; let Inst{5} = 1; // H bit let Inst{6} = 0; // S bit @@ -705,53 +782,55 @@ class AI3sthpo pattern> - : XI { +class AXI4ld pattern> + : XI { let Inst{20} = 1; // L bit let Inst{22} = 0; // S bit let Inst{27-25} = 0b100; } -class AXI4st pattern> - : XI { +class AXI4st pattern> + : XI { let Inst{20} = 0; // L bit let Inst{22} = 0; // S bit let Inst{27-25} = 0b100; } // Unsigned multiply, multiply-accumulate instructions. -class AMul1I opcod, dag oops, dag iops, string opc, - string asm, list pattern> - : I { +class AMul1I opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : I { let Inst{7-4} = 0b1001; let Inst{20} = 0; // S bit let Inst{27-21} = opcod; } -class AsMul1I opcod, dag oops, dag iops, string opc, - string asm, list pattern> - : sI { +class AsMul1I opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : sI { let Inst{7-4} = 0b1001; let Inst{27-21} = opcod; } // Most significant word multiply -class AMul2I opcod, dag oops, dag iops, string opc, - string asm, list pattern> - : I { +class AMul2I opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : I { let Inst{7-4} = 0b1001; let Inst{20} = 1; let Inst{27-21} = opcod; } // SMUL / SMULW / SMLA / SMLAW -class AMulxyI opcod, dag oops, dag iops, string opc, - string asm, list pattern> - : I { +class AMulxyI opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : I { let Inst{4} = 0; let Inst{7} = 1; let Inst{20} = 0; @@ -759,19 +838,19 @@ class AMulxyI opcod, dag oops, dag iops, string opc, } // Extend instructions. -class AExtI opcod, dag oops, dag iops, string opc, - string asm, list pattern> - : I { +class AExtI opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : I { let Inst{7-4} = 0b0111; let Inst{27-20} = opcod; } // Misc Arithmetic instructions. -class AMiscA1I opcod, dag oops, dag iops, string opc, - string asm, list pattern> - : I { +class AMiscA1I opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : I { let Inst{27-20} = opcod; } @@ -796,8 +875,8 @@ class ARMV6Pat : Pat { // TI - Thumb instruction. class ThumbI pattern> - : InstARM { + InstrItinClass itin, string asm, string cstr, list pattern> + : InstThumb { let OutOperandList = oops; let InOperandList = iops; let AsmString = asm; @@ -805,21 +884,30 @@ class ThumbI Predicates = [IsThumb]; } -class TI pattern> - : ThumbI; +class TI pattern> + : ThumbI; -// tBL, tBX instructions -class TIx2 pattern> - : ThumbI; +// Two-address instructions +class TIt pattern> + : ThumbI; + +// tBL, tBX 32-bit instructions +class TIx2 opcod1, bits<2> opcod2, bit opcod3, + dag oops, dag iops, InstrItinClass itin, string asm, list pattern> + : ThumbI, Encoding { + let Inst{31-27} = opcod1; + let Inst{15-14} = opcod2; + let Inst{12} = opcod3; +} // BR_JT instructions -class TJTI pattern> - : ThumbI; +class TJTI pattern> + : ThumbI; // Thumb1 only class Thumb1I pattern> - : InstARM { + InstrItinClass itin, string asm, string cstr, list pattern> + : InstThumb { let OutOperandList = oops; let InOperandList = iops; let AsmString = asm; @@ -827,21 +915,27 @@ class Thumb1I Predicates = [IsThumb1Only]; } -class T1I pattern> - : Thumb1I; -class T1Ix2 pattern> - : Thumb1I; -class T1JTI pattern> - : Thumb1I; +class T1I pattern> + : Thumb1I; +class T1Ix2 pattern> + : Thumb1I; +class T1JTI pattern> + : Thumb1I; // Two-address instructions -class T1It pattern> - : Thumb1I; +class T1It pattern> + : Thumb1I; // Thumb1 instruction that can either be predicated or set CPSR. class Thumb1sI pattern> - : InstARM { + : InstThumb { let OutOperandList = !con(oops, (ops s_cc_out:$s)); let InOperandList = !con(iops, (ops pred:$p)); let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm)); @@ -849,18 +943,21 @@ class Thumb1sI Predicates = [IsThumb1Only]; } -class T1sI pattern> - : Thumb1sI; +class T1sI pattern> + : Thumb1sI; // Two-address instructions -class T1sIt pattern> - : Thumb1sI pattern> + : Thumb1sI; // Thumb1 instruction that can be predicated. class Thumb1pI pattern> - : InstARM { + : InstThumb { let OutOperandList = oops; let InOperandList = !con(iops, (ops pred:$p)); let AsmString = !strconcat(opc, !strconcat("${p}", asm)); @@ -868,27 +965,78 @@ class Thumb1pI Predicates = [IsThumb1Only]; } -class T1pI pattern> - : Thumb1pI; +class T1pI pattern> + : Thumb1pI; // Two-address instructions -class T1pIt pattern> - : Thumb1pI pattern> + : Thumb1pI; -class T1pI1 pattern> - : Thumb1pI; -class T1pI2 pattern> - : Thumb1pI; -class T1pI4 pattern> - : Thumb1pI; -class T1pIs pattern> - : Thumb1pI; +class T1pI1 pattern> + : Thumb1pI; +class T1pI2 pattern> + : Thumb1pI; +class T1pI4 pattern> + : Thumb1pI; +class T1pIs pattern> + : Thumb1pI; + +class Encoding16 : Encoding { + let Inst{31-16} = 0x0000; +} + +// A6.2 16-bit Thumb instruction encoding +class T1Encoding opcode> : Encoding16 { + let Inst{15-10} = opcode; +} + +// A6.2.1 Shift (immediate), add, subtract, move, and compare encoding. +class T1General opcode> : Encoding16 { + let Inst{15-14} = 0b00; + let Inst{13-9} = opcode; +} + +// A6.2.2 Data-processing encoding. +class T1DataProcessing opcode> : Encoding16 { + let Inst{15-10} = 0b010000; + let Inst{9-6} = opcode; +} + +// A6.2.3 Special data instructions and branch and exchange encoding. +class T1Special opcode> : Encoding16 { + let Inst{15-10} = 0b010001; + let Inst{9-6} = opcode; +} + +// A6.2.4 Load/store single data item encoding. +class T1LoadStore opA, bits<3> opB> : Encoding16 { + let Inst{15-12} = opA; + let Inst{11-9} = opB; +} +class T1LdSt opB> : T1LoadStore<0b0101, opB>; +class T1LdSt4Imm opB> : T1LoadStore<0b0110, opB>; // Immediate, 4 bytes +class T1LdSt1Imm opB> : T1LoadStore<0b0111, opB>; // Immediate, 1 byte +class T1LdSt2Imm opB> : T1LoadStore<0b1000, opB>; // Immediate, 2 bytes +class T1LdStSP opB> : T1LoadStore<0b1001, opB>; // SP relative + +// A6.2.5 Miscellaneous 16-bit instructions encoding. +class T1Misc opcode> : Encoding16 { + let Inst{15-12} = 0b1011; + let Inst{11-5} = opcode; +} // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable. class Thumb2I pattern> - : InstARM { + : InstARM { let OutOperandList = oops; let InOperandList = !con(iops, (ops pred:$p)); let AsmString = !strconcat(opc, !strconcat("${p}", asm)); @@ -902,8 +1050,9 @@ class Thumb2I pattern> - : InstARM { + : InstARM { let OutOperandList = oops; let InOperandList = !con(iops, (ops pred:$p, cc_out:$s)); let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm)); @@ -913,8 +1062,9 @@ class Thumb2sI pattern> - : InstARM { + : InstARM { let OutOperandList = oops; let InOperandList = iops; let AsmString = asm; @@ -922,36 +1072,82 @@ class Thumb2XI Predicates = [IsThumb2]; } -class T2I pattern> - : Thumb2I; -class T2Ii12 pattern> - : Thumb2I; -class T2Ii8 pattern> - : Thumb2I; -class T2Iso pattern> - : Thumb2I; -class T2Ipc pattern> - : Thumb2I; -class T2Ii8s4 pattern> - : Thumb2I; +class ThumbXI pattern> + : InstARM { + let OutOperandList = oops; + let InOperandList = iops; + let AsmString = asm; + let Pattern = pattern; + list Predicates = [IsThumb1Only]; +} + +class T2I pattern> + : Thumb2I; +class T2Ii12 pattern> + : Thumb2I; +class T2Ii8 pattern> + : Thumb2I; +class T2Iso pattern> + : Thumb2I; +class T2Ipc pattern> + : Thumb2I; +class T2Ii8s4 pattern> + : Thumb2I { + let Inst{31-27} = 0b11101; + let Inst{26-25} = 0b00; + let Inst{24} = P; + let Inst{23} = ?; // The U bit. + let Inst{22} = 1; + let Inst{21} = W; + let Inst{20} = load; +} + +class T2sI pattern> + : Thumb2sI; + +class T2XI pattern> + : Thumb2XI; +class T2JTI pattern> + : Thumb2XI; -class T2sI pattern> - : Thumb2sI; +class T2Ix2 pattern> + : Thumb2I; -class T2XI pattern> - : Thumb2XI; -class T2JTI pattern> - : Thumb2XI; // T2Iidxldst - Thumb2 indexed load / store instructions. -class T2Iidxldst opcod, bit load, bit pre, + dag oops, dag iops, + AddrMode am, IndexMode im, InstrItinClass itin, string opc, string asm, string cstr, list pattern> - : InstARM { + : InstARM { let OutOperandList = oops; let InOperandList = !con(iops, (ops pred:$p)); let AsmString = !strconcat(opc, !strconcat("${p}", asm)); let Pattern = pattern; list Predicates = [IsThumb2]; + let Inst{31-27} = 0b11111; + let Inst{26-25} = 0b00; + let Inst{24} = signed; + let Inst{23} = 0; + let Inst{22-21} = opcod; + let Inst{20} = load; + let Inst{11} = 1; + // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed + let Inst{10} = pre; // The P bit. + let Inst{8} = 1; // The W bit. } // Tv5Pat - Same as Pat<>, but requires V5T Thumb mode. @@ -977,9 +1173,9 @@ class T2Pat : Pat { // Almost all VFP instructions are predicable. class VFPI pattern> - : InstARM { + IndexMode im, Format f, InstrItinClass itin, + string opc, string asm, string cstr, list pattern> + : InstARM { let OutOperandList = oops; let InOperandList = !con(iops, (ops pred:$p)); let AsmString = !strconcat(opc, !strconcat("${p}", asm)); @@ -989,8 +1185,9 @@ class VFPI pattern> - : InstARM { + IndexMode im, Format f, InstrItinClass itin, + string asm, string cstr, list pattern> + : InstARM { let OutOperandList = oops; let InOperandList = iops; let AsmString = asm; @@ -998,26 +1195,31 @@ class VFPXI Predicates = [HasVFP2]; } -class VFPAI pattern> - : VFPI; +class VFPAI pattern> + : VFPI; // ARM VFP addrmode5 loads and stores class ADI5 opcod1, bits<2> opcod2, dag oops, dag iops, + InstrItinClass itin, string opc, string asm, list pattern> : VFPI { + VFPLdStFrm, itin, opc, asm, "", pattern> { // TODO: Mark the instructions with the appropriate subtarget info. let Inst{27-24} = opcod1; let Inst{21-20} = opcod2; let Inst{11-8} = 0b1011; + + // 64-bit loads & stores operate on both NEON and VFP pipelines. + let Dom = VFPNeonDomain.Value; } class ASI5 opcod1, bits<2> opcod2, dag oops, dag iops, + InstrItinClass itin, string opc, string asm, list pattern> : VFPI { + VFPLdStFrm, itin, opc, asm, "", pattern> { // TODO: Mark the instructions with the appropriate subtarget info. let Inst{27-24} = opcod1; let Inst{21-20} = opcod2; @@ -1025,110 +1227,148 @@ class ASI5 opcod1, bits<2> opcod2, dag oops, dag iops, } // Load / store multiple -class AXSI5 pattern> +class AXDI5 pattern> : VFPXI { + VFPLdStMulFrm, itin, asm, "", pattern> { // TODO: Mark the instructions with the appropriate subtarget info. let Inst{27-25} = 0b110; let Inst{11-8} = 0b1011; + + // 64-bit loads & stores operate on both NEON and VFP pipelines. + let Dom = VFPNeonDomain.Value; } -class AXDI5 pattern> +class AXSI5 pattern> : VFPXI { + VFPLdStMulFrm, itin, asm, "", pattern> { // TODO: Mark the instructions with the appropriate subtarget info. let Inst{27-25} = 0b110; let Inst{11-8} = 0b1010; } - // Double precision, unary -class ADuI opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops, - string opc, string asm, list pattern> - : VFPAI { - let Inst{27-20} = opcod1; - let Inst{19-16} = opcod2; +class ADuI opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, + bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, + string asm, list pattern> + : VFPAI { + let Inst{27-23} = opcod1; + let Inst{21-20} = opcod2; + let Inst{19-16} = opcod3; let Inst{11-8} = 0b1011; - let Inst{7-4} = opcod3; + let Inst{7-6} = opcod4; + let Inst{4} = opcod5; } // Double precision, binary -class ADbI opcod, dag oops, dag iops, string opc, - string asm, list pattern> - : VFPAI { - let Inst{27-20} = opcod; +class ADbI opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, + dag iops, InstrItinClass itin, string opc, string asm, list pattern> + : VFPAI { + let Inst{27-23} = opcod1; + let Inst{21-20} = opcod2; let Inst{11-8} = 0b1011; + let Inst{6} = op6; + let Inst{4} = op4; } // Single precision, unary -class ASuI opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops, - string opc, string asm, list pattern> - : VFPAI { - // Bits 22 (D bit) and 5 (M bit) will be changed during instruction encoding. - let Inst{27-20} = opcod1; - let Inst{19-16} = opcod2; +class ASuI opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, + bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, + string asm, list pattern> + : VFPAI { + let Inst{27-23} = opcod1; + let Inst{21-20} = opcod2; + let Inst{19-16} = opcod3; let Inst{11-8} = 0b1010; - let Inst{7-4} = opcod3; + let Inst{7-6} = opcod4; + let Inst{4} = opcod5; } -// Single precision, unary if no NEON +// Single precision unary, if no NEON // Same as ASuI except not available if NEON is enabled -class ASuIn opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops, - string opc, string asm, list pattern> - : ASuI { +class ASuIn opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, + bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, + string asm, list pattern> + : ASuI { list Predicates = [HasVFP2,DontUseNEONForFP]; } // Single precision, binary -class ASbI opcod, dag oops, dag iops, string opc, - string asm, list pattern> - : VFPAI { - // Bit 22 (D bit) can be changed during instruction encoding. - let Inst{27-20} = opcod; +class ASbI opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, + InstrItinClass itin, string opc, string asm, list pattern> + : VFPAI { + let Inst{27-23} = opcod1; + let Inst{21-20} = opcod2; let Inst{11-8} = 0b1010; + let Inst{6} = op6; + let Inst{4} = op4; } -// Single precision, binary if no NEON +// Single precision binary, if no NEON // Same as ASbI except not available if NEON is enabled -class ASbIn opcod, dag oops, dag iops, string opc, - string asm, list pattern> - : ASbI { +class ASbIn opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, + dag iops, InstrItinClass itin, string opc, string asm, list pattern> + : ASbI { list Predicates = [HasVFP2,DontUseNEONForFP]; } // VFP conversion instructions -class AVConv1I opcod1, bits<4> opcod2, bits<4> opcod3, - dag oops, dag iops, string opc, string asm, list pattern> - : VFPAI { - let Inst{27-20} = opcod1; - let Inst{19-16} = opcod2; - let Inst{11-8} = opcod3; +class AVConv1I opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, + dag oops, dag iops, InstrItinClass itin, string opc, string asm, + list pattern> + : VFPAI { + let Inst{27-23} = opcod1; + let Inst{21-20} = opcod2; + let Inst{19-16} = opcod3; + let Inst{11-8} = opcod4; let Inst{6} = 1; + let Inst{4} = 0; +} + +// VFP conversion between floating-point and fixed-point +class AVConv1XI op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5, + dag oops, dag iops, InstrItinClass itin, string opc, string asm, + list pattern> + : AVConv1I { + // size (fixed-point number): sx == 0 ? 16 : 32 + let Inst{7} = op5; // sx +} + +// VFP conversion instructions, if no NEON +class AVConv1In opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, + dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : AVConv1I { + list Predicates = [HasVFP2,DontUseNEONForFP]; } class AVConvXI opcod1, bits<4> opcod2, dag oops, dag iops, Format f, - string opc, string asm, list pattern> - : VFPAI { + InstrItinClass itin, + string opc, string asm, list pattern> + : VFPAI { let Inst{27-20} = opcod1; let Inst{11-8} = opcod2; let Inst{4} = 1; } -class AVConv2I opcod1, bits<4> opcod2, dag oops, dag iops, string opc, - string asm, list pattern> - : AVConvXI; +class AVConv2I opcod1, bits<4> opcod2, dag oops, dag iops, + InstrItinClass itin, string opc, string asm, list pattern> + : AVConvXI; -class AVConv3I opcod1, bits<4> opcod2, dag oops, dag iops, string opc, - string asm, list pattern> - : AVConvXI; +class AVConv3I opcod1, bits<4> opcod2, dag oops, dag iops, + InstrItinClass itin, string opc, string asm, list pattern> + : AVConvXI; -class AVConv4I opcod1, bits<4> opcod2, dag oops, dag iops, string opc, - string asm, list pattern> - : AVConvXI; +class AVConv4I opcod1, bits<4> opcod2, dag oops, dag iops, + InstrItinClass itin, string opc, string asm, list pattern> + : AVConvXI; -class AVConv5I opcod1, bits<4> opcod2, dag oops, dag iops, string opc, - string asm, list pattern> - : AVConvXI; +class AVConv5I opcod1, bits<4> opcod2, dag oops, dag iops, + InstrItinClass itin, string opc, string asm, list pattern> + : AVConvXI; //===----------------------------------------------------------------------===// @@ -1136,35 +1376,73 @@ class AVConv5I opcod1, bits<4> opcod2, dag oops, dag iops, string opc, // ARM NEON Instruction templates. // -class NeonI pattern> - : InstARM { +class NeonI pattern> + : InstARM { let OutOperandList = oops; - let InOperandList = iops; - let AsmString = asm; + let InOperandList = !con(iops, (ops pred:$p)); + let AsmString = !strconcat( + !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)), + !strconcat("\t", asm)); + let Pattern = pattern; + list Predicates = [HasNEON]; +} + +// Same as NeonI except it does not have a "data type" specifier. +class NeonXI pattern> + : InstARM { + let OutOperandList = oops; + let InOperandList = !con(iops, (ops pred:$p)); + let AsmString = !strconcat(!strconcat(opc, "${p}"), !strconcat("\t", asm)); let Pattern = pattern; list Predicates = [HasNEON]; } -class NI pattern> - : NeonI { +class NI pattern> + : NeonXI { } -class NLdSt pattern> - : NeonI { +class NI4 pattern> + : NeonXI { +} + +class NLdSt op21_20, bits<4> op11_8, bits<4> op7_4, + dag oops, dag iops, InstrItinClass itin, + string opc, string dt, string asm, string cstr, list pattern> + : NeonI { let Inst{31-24} = 0b11110100; + let Inst{23} = op23; + let Inst{21-20} = op21_20; + let Inst{11-8} = op11_8; + let Inst{7-4} = op7_4; } -class NDataI pattern> - : NeonI { +class NDataI pattern> + : NeonI { + let Inst{31-25} = 0b1111001; +} + +class NDataXI pattern> + : NeonXI { let Inst{31-25} = 0b1111001; } // NEON "one register and a modified immediate" format. class N1ModImm op21_19, bits<4> op11_8, bit op7, bit op6, bit op5, bit op4, - dag oops, dag iops, string asm, string cstr, list pattern> - : NDataI { + dag oops, dag iops, InstrItinClass itin, + string opc, string dt, string asm, string cstr, list pattern> + : NDataI { let Inst{23} = op23; let Inst{21-19} = op21_19; let Inst{11-8} = op11_8; @@ -1177,8 +1455,24 @@ class N1ModImm op21_19, bits<4> op11_8, bit op7, bit op6, // NEON 2 vector register format. class N2V op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, bits<5> op11_7, bit op6, bit op4, - dag oops, dag iops, string asm, string cstr, list pattern> - : NDataI { + dag oops, dag iops, InstrItinClass itin, + string opc, string dt, string asm, string cstr, list pattern> + : NDataI { + let Inst{24-23} = op24_23; + let Inst{21-20} = op21_20; + let Inst{19-18} = op19_18; + let Inst{17-16} = op17_16; + let Inst{11-7} = op11_7; + let Inst{6} = op6; + let Inst{4} = op4; +} + +// Same as N2V except it doesn't have a datatype suffix. +class N2VX op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, + bits<5> op11_7, bit op6, bit op4, + dag oops, dag iops, InstrItinClass itin, + string opc, string asm, string cstr, list pattern> + : NDataXI { let Inst{24-23} = op24_23; let Inst{21-20} = op21_20; let Inst{19-18} = op19_18; @@ -1189,13 +1483,12 @@ class N2V op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, } // NEON 2 vector register with immediate. -class N2VImm op21_16, bits<4> op11_8, bit op7, - bit op6, bit op4, - dag oops, dag iops, string asm, string cstr, list pattern> - : NDataI { +class N2VImm op11_8, bit op7, bit op6, bit op4, + dag oops, dag iops, InstrItinClass itin, + string opc, string dt, string asm, string cstr, list pattern> + : NDataI { let Inst{24} = op24; let Inst{23} = op23; - let Inst{21-16} = op21_16; let Inst{11-8} = op11_8; let Inst{7} = op7; let Inst{6} = op6; @@ -1204,8 +1497,22 @@ class N2VImm op21_16, bits<4> op11_8, bit op7, // NEON 3 vector register format. class N3V op21_20, bits<4> op11_8, bit op6, bit op4, - dag oops, dag iops, string asm, string cstr, list pattern> - : NDataI { + dag oops, dag iops, InstrItinClass itin, + string opc, string dt, string asm, string cstr, list pattern> + : NDataI { + let Inst{24} = op24; + let Inst{23} = op23; + let Inst{21-20} = op21_20; + let Inst{11-8} = op11_8; + let Inst{6} = op6; + let Inst{4} = op4; +} + +// Same as N3VX except it doesn't have a data type suffix. +class N3VX op21_20, bits<4> op11_8, bit op6, bit op4, + dag oops, dag iops, InstrItinClass itin, + string opc, string asm, string cstr, list pattern> + : NDataXI { let Inst{24} = op24; let Inst{23} = op23; let Inst{21-20} = op21_20; @@ -1216,26 +1523,38 @@ class N3V op21_20, bits<4> op11_8, bit op6, bit op4, // NEON VMOVs between scalar and core registers. class NVLaneOp opcod1, bits<4> opcod2, bits<2> opcod3, - dag oops, dag iops, Format f, string opc, string asm, - list pattern> - : AI { + dag oops, dag iops, Format f, InstrItinClass itin, + string opc, string dt, string asm, list pattern> + : InstARM { let Inst{27-20} = opcod1; let Inst{11-8} = opcod2; let Inst{6-5} = opcod3; let Inst{4} = 1; + + let OutOperandList = oops; + let InOperandList = !con(iops, (ops pred:$p)); + let AsmString = !strconcat( + !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)), + !strconcat("\t", asm)); + let Pattern = pattern; list Predicates = [HasNEON]; } class NVGetLane opcod1, bits<4> opcod2, bits<2> opcod3, - dag oops, dag iops, string opc, string asm, list pattern> - : NVLaneOp; + dag oops, dag iops, InstrItinClass itin, + string opc, string dt, string asm, list pattern> + : NVLaneOp; class NVSetLane opcod1, bits<4> opcod2, bits<2> opcod3, - dag oops, dag iops, string opc, string asm, list pattern> - : NVLaneOp; + dag oops, dag iops, InstrItinClass itin, + string opc, string dt, string asm, list pattern> + : NVLaneOp; class NVDup opcod1, bits<4> opcod2, bits<2> opcod3, - dag oops, dag iops, string opc, string asm, list pattern> - : NVLaneOp; + dag oops, dag iops, InstrItinClass itin, + string opc, string dt, string asm, list pattern> + : NVLaneOp; // NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON // for single-precision FP.