aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMAddressingModes.h20
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td43
-rw-r--r--lib/Target/ARM/ARMInstrNEON.td495
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp46
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp433
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMInstPrinter.h40
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp513
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.h71
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp3351
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassemblerCore.h301
-rw-r--r--lib/Target/ARM/Disassembler/Makefile17
-rw-r--r--lib/Target/ARM/Disassembler/ThumbDisassemblerCore.cpp.inc2158
-rw-r--r--lib/Target/ARM/Makefile5
-rw-r--r--lib/Target/ARM/Thumb2ITBlockPass.cpp8
14 files changed, 7355 insertions, 146 deletions
diff --git a/lib/Target/ARM/ARMAddressingModes.h b/lib/Target/ARM/ARMAddressingModes.h
index 9e086ca5c5..1798768ea4 100644
--- a/lib/Target/ARM/ARMAddressingModes.h
+++ b/lib/Target/ARM/ARMAddressingModes.h
@@ -35,6 +35,10 @@ namespace ARM_AM {
add = '+', sub = '-'
};
+ static inline const char *getAddrOpcStr(AddrOpc Op) {
+ return Op == sub ? "-" : "";
+ }
+
static inline const char *getShiftOpcStr(ShiftOpc Op) {
switch (Op) {
default: assert(0 && "Unknown shift opc!");
@@ -127,6 +131,20 @@ namespace ARM_AM {
return (Imm >> 8) * 2;
}
+ /// getSOImmValOneRotate - Try to handle Imm with an immediate shifter
+ /// operand, computing the rotate amount to use. If this immediate value
+ /// cannot be handled with a single shifter-op, return 0.
+ static inline unsigned getSOImmValOneRotate(unsigned Imm) {
+ // A5.2.4 Constants with multiple encodings
+ // The lowest unsigned value of rotation wins!
+ for (unsigned R = 1; R <= 15; ++R)
+ if ((Imm & rotr32(~255U, 2*R)) == 0)
+ return 2*R;
+
+ // Failed to find a suitable rotate amount.
+ return 0;
+ }
+
/// getSOImmValRotate - Try to handle Imm with an immediate shifter operand,
/// computing the rotate amount to use. If this immediate value cannot be
/// handled with a single shifter-op, determine a good rotate amount that will
@@ -179,7 +197,7 @@ namespace ARM_AM {
// of zero.
if ((Arg & ~255U) == 0) return Arg;
- unsigned RotAmt = getSOImmValRotate(Arg);
+ unsigned RotAmt = getSOImmValOneRotate(Arg);
// If this cannot be handled with a single shifter_op, bail out.
if (rotr32(~255U, RotAmt) & Arg)
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 258a96b921..52553f5477 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -1464,6 +1464,29 @@ class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
// ARM NEON Instruction templates.
//
+// NSFormat specifies further details of a NEON instruction. This is used by
+// the disassembler to classify NEONFrm instructions for disassembly purpose.
+class NSFormat<bits<5> val> {
+ bits<5> Value = val;
+}
+def NSFormatNone : NSFormat<0>;
+def VLDSTLaneFrm : NSFormat<1>;
+def VLDSTLaneDblFrm : NSFormat<2>;
+def VLDSTRQFrm : NSFormat<3>;
+def NVdImmFrm : NSFormat<4>;
+def NVdVmImmFrm : NSFormat<5>;
+def NVdVmImmVCVTFrm : NSFormat<6>;
+def NVdVmImmVDupLaneFrm : NSFormat<7>;
+def NVdVmImmVSHLLFrm : NSFormat<8>;
+def NVectorShuffleFrm : NSFormat<9>;
+def NVectorShiftFrm : NSFormat<10>;
+def NVectorShift2Frm : NSFormat<11>;
+def NVdVnVmImmFrm : NSFormat<12>;
+def NVdVnVmImmVectorShiftFrm : NSFormat<13>;
+def NVdVnVmImmVectorExtractFrm : NSFormat<14>;
+def NVdVnVmImmMulScalarFrm : NSFormat<15>;
+def VTBLFrm : NSFormat<16>;
+
class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin,
string opc, string dt, string asm, string cstr, list<dag> pattern>
: InstARM<am, Size4Bytes, im, NEONFrm, NeonDomain, cstr, itin> {
@@ -1474,6 +1497,8 @@ class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin,
!strconcat("\t", asm));
let Pattern = pattern;
list<Predicate> Predicates = [HasNEON];
+ NSFormat NSF = NSFormatNone; // For disassembly.
+ bits<5> NSForm = NSFormatNone.Value; // For disassembly.
}
// Same as NeonI except it does not have a "data type" specifier.
@@ -1485,6 +1510,8 @@ class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin,
let AsmString = !strconcat(!strconcat(opc, "${p}"), !strconcat("\t", asm));
let Pattern = pattern;
list<Predicate> Predicates = [HasNEON];
+ NSFormat NSF = NSFormatNone; // For disassembly.
+ bits<5> NSForm = NSFormatNone.Value; // For disassembly.
}
class NI<dag oops, dag iops, InstrItinClass itin, string opc, string asm,
@@ -1497,6 +1524,8 @@ class NI4<dag oops, dag iops, InstrItinClass itin, string opc,
string asm, list<dag> pattern>
: NeonXI<oops, iops, AddrMode4, IndexModeNone, itin, opc, asm, "",
pattern> {
+ let NSF = VLDSTRQFrm; // For disassembly.
+ let NSForm = VLDSTRQFrm.Value; // For disassembly.
}
class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
@@ -1509,6 +1538,8 @@ class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
let Inst{21-20} = op21_20;
let Inst{11-8} = op11_8;
let Inst{7-4} = op7_4;
+ let NSF = VLDSTLaneFrm; // For disassembly.
+ let NSForm = VLDSTLaneFrm.Value; // For disassembly.
}
class NDataI<dag oops, dag iops, InstrItinClass itin,
@@ -1538,6 +1569,8 @@ class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
let Inst{6} = op6;
let Inst{5} = op5;
let Inst{4} = op4;
+ let NSF = NVdImmFrm; // For disassembly.
+ let NSForm = NVdImmFrm.Value; // For disassembly.
}
// NEON 2 vector register format.
@@ -1553,6 +1586,8 @@ class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
let Inst{11-7} = op11_7;
let Inst{6} = op6;
let Inst{4} = op4;
+ let NSF = NVdVmImmFrm; // For disassembly.
+ let NSForm = NVdVmImmFrm.Value; // For disassembly.
}
// Same as N2V except it doesn't have a datatype suffix.
@@ -1568,6 +1603,8 @@ class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
let Inst{11-7} = op11_7;
let Inst{6} = op6;
let Inst{4} = op4;
+ let NSF = NVdVmImmFrm; // For disassembly.
+ let NSForm = NVdVmImmFrm.Value; // For disassembly.
}
// NEON 2 vector register with immediate.
@@ -1581,6 +1618,8 @@ class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
let Inst{7} = op7;
let Inst{6} = op6;
let Inst{4} = op4;
+ let NSF = NVdVmImmFrm; // For disassembly.
+ let NSForm = NVdVmImmFrm.Value; // For disassembly.
}
// NEON 3 vector register format.
@@ -1594,6 +1633,8 @@ class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
let Inst{11-8} = op11_8;
let Inst{6} = op6;
let Inst{4} = op4;
+ let NSF = NVdVnVmImmFrm; // For disassembly.
+ let NSForm = NVdVnVmImmFrm.Value; // For disassembly.
}
// Same as N3VX except it doesn't have a data type suffix.
@@ -1607,6 +1648,8 @@ class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4
let Inst{11-8} = op11_8;
let Inst{6} = op6;
let Inst{4} = op4;
+ let NSF = NVdVnVmImmFrm; // For disassembly.
+ let NSForm = NVdVnVmImmFrm.Value; // For disassembly.
}
// NEON VMOVs between scalar and core registers.
diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td
index 8fee6fa952..da2babf05d 100644
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -213,7 +213,10 @@ def VLD2q32 : VLD2Q<0b1000, "vld2", "32">;
class VLD2Ddbl<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b1001,op7_4, (outs DPR:$dst1, DPR:$dst2),
(ins addrmode6:$addr), IIC_VLD2,
- OpcodeStr, Dt, "\\{$dst1, $dst2\\}, $addr", "", []>;
+ OpcodeStr, Dt, "\\{$dst1, $dst2\\}, $addr", "", []> {
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
def VLD2d8D : VLD2Ddbl<0b0000, "vld2", "8">;
def VLD2d16D : VLD2Ddbl<0b0100, "vld2", "16">;
@@ -228,7 +231,10 @@ class VLD3WB<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0101,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, GPR:$wb),
(ins addrmode6:$addr), IIC_VLD3,
OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3\\}, $addr",
- "$addr.addr = $wb", []>;
+ "$addr.addr = $wb", []> {
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
def VLD3d8 : VLD3D<0b0000, "vld3", "8">;
def VLD3d16 : VLD3D<0b0100, "vld3", "16">;
@@ -260,7 +266,10 @@ class VLD4WB<bits<4> op7_4, string OpcodeStr, string Dt>
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),
(ins addrmode6:$addr), IIC_VLD4,
OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
- "$addr.addr = $wb", []>;
+ "$addr.addr = $wb", []> {
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
def VLD4d8 : VLD4D<0b0000, "vld4", "8">;
def VLD4d16 : VLD4D<0b0100, "vld4", "16">;
@@ -297,12 +306,28 @@ def VLD2LNd16 : VLD2LN<0b0101, "vld2", "16"> { let Inst{5} = 0; }
def VLD2LNd32 : VLD2LN<0b1001, "vld2", "32"> { let Inst{6} = 0; }
// vld2 to double-spaced even registers.
-def VLD2LNq16a: VLD2LN<0b0101, "vld2", "16"> { let Inst{5} = 1; }
-def VLD2LNq32a: VLD2LN<0b1001, "vld2", "32"> { let Inst{6} = 1; }
+def VLD2LNq16a: VLD2LN<0b0101, "vld2", "16"> {
+ let Inst{5} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
+def VLD2LNq32a: VLD2LN<0b1001, "vld2", "32"> {
+ let Inst{6} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
// vld2 to double-spaced odd registers.
-def VLD2LNq16b: VLD2LN<0b0101, "vld2", "16"> { let Inst{5} = 1; }
-def VLD2LNq32b: VLD2LN<0b1001, "vld2", "32"> { let Inst{6} = 1; }
+def VLD2LNq16b: VLD2LN<0b0101, "vld2", "16"> {
+ let Inst{5} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
+def VLD2LNq32b: VLD2LN<0b1001, "vld2", "32"> {
+ let Inst{6} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
// VLD3LN : Vector Load (single 3-element structure to one lane)
class VLD3LN<bits<4> op11_8, string OpcodeStr, string Dt>
@@ -318,7 +343,11 @@ def VLD3LNd16 : VLD3LN<0b0110, "vld3", "16"> { let Inst{5-4} = 0b00; }
def VLD3LNd32 : VLD3LN<0b1010, "vld3", "32"> { let Inst{6-4} = 0b000; }
// vld3 to double-spaced even registers.
-def VLD3LNq16a: VLD3LN<0b0110, "vld3", "16"> { let Inst{5-4} = 0b10; }
+def VLD3LNq16a: VLD3LN<0b0110, "vld3", "16"> {
+ let Inst{5-4} = 0b10;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
def VLD3LNq32a: VLD3LN<0b1010, "vld3", "32"> { let Inst{6-4} = 0b100; }
// vld3 to double-spaced odd registers.
@@ -340,12 +369,28 @@ def VLD4LNd16 : VLD4LN<0b0111, "vld4", "16"> { let Inst{5} = 0; }
def VLD4LNd32 : VLD4LN<0b1011, "vld4", "32"> { let Inst{6} = 0; }
// vld4 to double-spaced even registers.
-def VLD4LNq16a: VLD4LN<0b0111, "vld4", "16"> { let Inst{5} = 1; }
-def VLD4LNq32a: VLD4LN<0b1011, "vld4", "32"> { let Inst{6} = 1; }
+def VLD4LNq16a: VLD4LN<0b0111, "vld4", "16"> {
+ let Inst{5} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
+def VLD4LNq32a: VLD4LN<0b1011, "vld4", "32"> {
+ let Inst{6} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
// vld4 to double-spaced odd registers.
-def VLD4LNq16b: VLD4LN<0b0111, "vld4", "16"> { let Inst{5} = 1; }
-def VLD4LNq32b: VLD4LN<0b1011, "vld4", "32"> { let Inst{6} = 1; }
+def VLD4LNq16b: VLD4LN<0b0111, "vld4", "16"> {
+ let Inst{5} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
+def VLD4LNq32b: VLD4LN<0b1011, "vld4", "32"> {
+ let Inst{6} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
// VLD1DUP : Vector Load (single element to all lanes)
// VLD2DUP : Vector Load (single 2-element structure to all lanes)
@@ -433,7 +478,10 @@ def VST2q32 : VST2Q<0b1000, "vst2", "32">;
class VST2Ddbl<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0, 0b00, 0b1001, op7_4, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2), IIC_VST,
- OpcodeStr, Dt, "\\{$src1, $src2\\}, $addr", "", []>;
+ OpcodeStr, Dt, "\\{$src1, $src2\\}, $addr", "", []> {
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
def VST2d8D : VST2Ddbl<0b0000, "vst2", "8">;
def VST2d16D : VST2Ddbl<0b0100, "vst2", "16">;
@@ -448,7 +496,10 @@ class VST3WB<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0101,op7_4, (outs GPR:$wb),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST,
OpcodeStr, Dt, "\\{$src1, $src2, $src3\\}, $addr",
- "$addr.addr = $wb", []>;
+ "$addr.addr = $wb", []> {
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
def VST3d8 : VST3D<0b0000, "vst3", "8">;
def VST3d16 : VST3D<0b0100, "vst3", "16">;
@@ -478,7 +529,10 @@ class VST4WB<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0001,op7_4, (outs GPR:$wb),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
IIC_VST, OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
- "$addr.addr = $wb", []>;
+ "$addr.addr = $wb", []> {
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
def VST4d8 : VST4D<0b0000, "vst4", "8">;
def VST4d16 : VST4D<0b0100, "vst4", "16">;
@@ -515,12 +569,28 @@ def VST2LNd16 : VST2LN<0b0101, "vst2", "16"> { let Inst{5} = 0; }
def VST2LNd32 : VST2LN<0b1001, "vst2", "32"> { let Inst{6} = 0; }
// vst2 to double-spaced even registers.
-def VST2LNq16a: VST2LN<0b0101, "vst2", "16"> { let Inst{5} = 1; }
-def VST2LNq32a: VST2LN<0b1001, "vst2", "32"> { let Inst{6} = 1; }
+def VST2LNq16a: VST2LN<0b0101, "vst2", "16"> {
+ let Inst{5} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
+def VST2LNq32a: VST2LN<0b1001, "vst2", "32"> {
+ let Inst{6} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
// vst2 to double-spaced odd registers.
-def VST2LNq16b: VST2LN<0b0101, "vst2", "16"> { let Inst{5} = 1; }
-def VST2LNq32b: VST2LN<0b1001, "vst2", "32"> { let Inst{6} = 1; }
+def VST2LNq16b: VST2LN<0b0101, "vst2", "16"> {
+ let Inst{5} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
+def VST2LNq32b: VST2LN<0b1001, "vst2", "32"> {
+ let Inst{6} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
// VST3LN : Vector Store (single 3-element structure from one lane)
class VST3LN<bits<4> op11_8, string OpcodeStr, string Dt>
@@ -535,12 +605,28 @@ def VST3LNd16 : VST3LN<0b0110, "vst3", "16"> { let Inst{5-4} = 0b00; }
def VST3LNd32 : VST3LN<0b1010, "vst3", "32"> { let Inst{6-4} = 0b000; }
// vst3 to double-spaced even registers.
-def VST3LNq16a: VST3LN<0b0110, "vst3", "16"> { let Inst{5-4} = 0b10; }
-def VST3LNq32a: VST3LN<0b1010, "vst3", "32"> { let Inst{6-4} = 0b100; }
+def VST3LNq16a: VST3LN<0b0110, "vst3", "16"> {
+ let Inst{5-4} = 0b10;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
+def VST3LNq32a: VST3LN<0b1010, "vst3", "32"> {
+ let Inst{6-4} = 0b100;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
// vst3 to double-spaced odd registers.
-def VST3LNq16b: VST3LN<0b0110, "vst3", "16"> { let Inst{5-4} = 0b10; }
-def VST3LNq32b: VST3LN<0b1010, "vst3", "32"> { let Inst{6-4} = 0b100; }
+def VST3LNq16b: VST3LN<0b0110, "vst3", "16"> {
+ let Inst{5-4} = 0b10;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
+def VST3LNq32b: VST3LN<0b1010, "vst3", "32"> {
+ let Inst{6-4} = 0b100;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
// VST4LN : Vector Store (single 4-element structure from one lane)
class VST4LN<bits<4> op11_8, string OpcodeStr, string Dt>
@@ -556,12 +642,28 @@ def VST4LNd16 : VST4LN<0b0111, "vst4", "16"> { let Inst{5} = 0; }
def VST4LNd32 : VST4LN<0b1011, "vst4", "32"> { let Inst{6} = 0; }
// vst4 to double-spaced even registers.
-def VST4LNq16a: VST4LN<0b0111, "vst4", "16"> { let Inst{5} = 1; }
-def VST4LNq32a: VST4LN<0b1011, "vst4", "32"> { let Inst{6} = 1; }
+def VST4LNq16a: VST4LN<0b0111, "vst4", "16"> {
+ let Inst{5} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
+def VST4LNq32a: VST4LN<0b1011, "vst4", "32"> {
+ let Inst{6} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
// vst4 to double-spaced odd registers.
-def VST4LNq16b: VST4LN<0b0111, "vst4", "16"> { let Inst{5} = 1; }
-def VST4LNq32b: VST4LN<0b1011, "vst4", "32"> { let Inst{6} = 1; }
+def VST4LNq16b: VST4LN<0b0111, "vst4", "16"> {
+ let Inst{5} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
+def VST4LNq32b: VST4LN<0b1011, "vst4", "32"> {
+ let Inst{6} = 1;
+ let NSF = VLDSTLaneDblFrm; // For disassembly.
+ let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
+}
} // mayStore = 1, hasExtraSrcRegAllocReq = 1
@@ -668,12 +770,18 @@ class N2VDShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr, string Dt>
: N2V<0b11, 0b11, op19_18, 0b10, op11_7, 0, 0, (outs DPR:$dst1, DPR:$dst2),
(ins DPR:$src1, DPR:$src2), IIC_VPERMD,
OpcodeStr, Dt, "$dst1, $dst2",
- "$src1 = $dst1, $src2 = $dst2", []>;
+ "$src1 = $dst1, $src2 = $dst2", []> {
+ let NSF = NVectorShuffleFrm; // For disassembly.
+ let NSForm = NVectorShuffleFrm.Value; // For disassembly.
+}
class N2VQShuffle<bits<2> op19_18, bits<5> op11_7,
InstrItinClass itin, string OpcodeStr, string Dt>
: N2V<0b11, 0b11, op19_18, 0b10, op11_7, 1, 0, (outs QPR:$dst1, QPR:$dst2),
(ins QPR:$src1, QPR:$src2), itin, OpcodeStr, Dt, "$dst1, $dst2",
- "$src1 = $dst1, $src2 = $dst2", []>;
+ "$src1 = $dst1, $src2 = $dst2", []> {
+ let NSF = NVectorShuffleFrm; // For disassembly.
+ let NSForm = NVectorShuffleFrm.Value; // For disassembly.
+}
// Basic 3-register operations: single-, double- and quad-register.
class N3VS<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
@@ -715,6 +823,8 @@ class N3VDSL<bits<2> op21_20, bits<4> op11_8,
(Ty (ShOp (Ty DPR:$src1),
(Ty (NEONvduplane (Ty DPR_VFP2:$src2), imm:$lane)))))]>{
let isCommutable = 0;
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
}
class N3VDSL16<bits<2> op21_20, bits<4> op11_8,
string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>
@@ -725,6 +835,8 @@ class N3VDSL16<bits<2> op21_20, bits<4> op11_8,
(Ty (ShOp (Ty DPR:$src1),
(Ty (NEONvduplane (Ty DPR_8:$src2), imm:$lane)))))]> {
let isCommutable = 0;
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
}
class N3VQ<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
@@ -756,6 +868,8 @@ class N3VQSL<bits<2> op21_20, bits<4> op11_8,
(ResTy (NEONvduplane (OpTy DPR_VFP2:$src2),
imm:$lane)))))]> {
let isCommutable = 0;
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
}
class N3VQSL16<bits<2> op21_20, bits<4> op11_8, string OpcodeStr, string Dt,
ValueType ResTy, ValueType OpTy, SDNode ShOp>
@@ -767,6 +881,8 @@ class N3VQSL16<bits<2> op21_20, bits<4> op11_8, string OpcodeStr, string Dt,
(ResTy (NEONvduplane (OpTy DPR_8:$src2),
imm:$lane)))))]> {
let isCommutable = 0;
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
}
// Basic 3-register intrinsics, both double- and quad-register.
@@ -789,6 +905,8 @@ class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
(Ty (NEONvduplane (Ty DPR_VFP2:$src2),
imm:$lane)))))]> {
let isCommutable = 0;
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
}
class N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp>
@@ -800,6 +918,8 @@ class N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
(Ty (NEONvduplane (Ty DPR_8:$src2),
imm:$lane)))))]> {
let isCommutable = 0;
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
}
class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
@@ -822,6 +942,8 @@ class N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
(ResTy (NEONvduplane (OpTy DPR_VFP2:$src2),
imm:$lane)))))]> {
let isCommutable = 0;
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
}
class N3VQIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
string OpcodeStr, string Dt,
@@ -834,6 +956,8 @@ class N3VQIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
(ResTy (NEONvduplane (OpTy DPR_8:$src2),
imm:$lane)))))]> {
let isCommutable = 0;
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
}
// Multiply-Add/Sub operations: single-, double- and quad-register.
@@ -864,7 +988,10 @@ class N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
(Ty (ShOp (Ty DPR:$src1),
(Ty (MulOp DPR:$src2,
(Ty (NEONvduplane (Ty DPR_VFP2:$src3),
- imm:$lane)))))))]>;
+ imm:$lane)))))))]> {
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
+}
class N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
string OpcodeStr, string Dt,
ValueType Ty, SDNode MulOp, SDNode ShOp>
@@ -876,7 +1003,10 @@ class N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
(Ty (ShOp (Ty DPR:$src1),
(Ty (MulOp DPR:$src2,
(Ty (NEONvduplane (Ty DPR_8:$src3),
- imm:$lane)))))))]>;
+ imm:$lane)))))))]> {
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
+}
class N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty,
@@ -897,7 +1027,10 @@ class N3VQMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
(ResTy (ShOp (ResTy QPR:$src1),
(ResTy (MulOp QPR:$src2,
(ResTy (NEONvduplane (OpTy DPR_VFP2:$src3),
- imm:$lane)))))))]>;
+ imm:$lane)))))))]> {
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
+}
class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
string OpcodeStr, string Dt,
ValueType ResTy, ValueType OpTy,
@@ -910,7 +1043,10 @@ class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
(ResTy (ShOp (ResTy QPR:$src1),
(ResTy (MulOp QPR:$src2,
(ResTy (NEONvduplane (OpTy DPR_8:$src3),
- imm:$lane)))))))]>;
+ imm:$lane)))))))]> {
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
+}
// Neon 3-argument intrinsics, both double- and quad-register.
// The destination register is also used as the first source operand register.
@@ -996,7 +1132,10 @@ class N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
[(set (ResTy QPR:$dst),
(ResTy (IntOp (OpTy DPR:$src1),
(OpTy (NEONvduplane (OpTy DPR_VFP2:$src2),
- imm:$lane)))))]>;
+ imm:$lane)))))]> {
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
+}
class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
InstrItinClass itin, string OpcodeStr, string Dt,
ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
@@ -1006,7 +1145,10 @@ class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
[(set (ResTy QPR:$dst),
(ResTy (IntOp (OpTy DPR:$src1),
(OpTy (NEONvduplane (OpTy DPR_8:$src2),
- imm:$lane)))))]>;
+ imm:$lane)))))]> {
+ let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
+ let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
+}
// Wide 3-register intrinsics.
class N3VWInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
@@ -1055,6 +1197,10 @@ class N2VQPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
OpcodeStr, Dt, "$dst, $src2", "$src1 = $dst",
[(set QPR:$dst, (ResTy (IntOp (ResTy QPR:$src1), (OpTy QPR:$src2))))]>;
+// This is a big let * in block to mark these instructions NVectorShiftFrm to
+// help the disassembler.
+let NSF = NVectorShiftFrm, NSForm = NVectorShiftFrm.Value in {
+
// Shift by immediate,
// both double- and quad-register.
class N2VDSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
@@ -1072,16 +1218,6 @@ class N2VQSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
OpcodeStr, Dt, "$dst, $src, $SIMM", "",
[(set QPR:$dst, (Ty (OpNode (Ty QPR:$src), (i32 imm:$SIMM))))]>;
-// Long shift by immediate.
-class N2VLSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
- string OpcodeStr, string Dt,
- ValueType ResTy, ValueType OpTy, SDNode OpNode>
- : N2VImm<op24, op23, op11_8, op7, op6, op4,
- (outs QPR:$dst), (ins DPR:$src, i32imm:$SIMM), IIC_VSHLiD,
- OpcodeStr, Dt, "$dst, $src, $SIMM", "",
- [(set QPR:$dst, (ResTy (OpNode (OpTy DPR:$src),
- (i32 imm:$SIMM))))]>;
-
// Narrow shift by immediate.
class N2VNSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
InstrItinClass itin, string OpcodeStr, string Dt,
@@ -1124,8 +1260,26 @@ class N2VQShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
OpcodeStr, Dt, "$dst, $src2, $SIMM", "$src1 = $dst",
[(set QPR:$dst, (Ty (ShOp QPR:$src1, QPR:$src2, (i32 imm:$SIMM))))]>;
+} // End of "let NSF = NVectorShiftFrm, ..."
+
+// Long shift by immediate.
+class N2VLSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
+ string OpcodeStr, string Dt,
+ ValueType ResTy, ValueType OpTy, SDNode OpNode>
+ : N2VImm<op24, op23, op11_8, op7, op6, op4,
+ (outs QPR:$dst), (ins DPR:$src, i32imm:$SIMM), IIC_VSHLiD,
+ OpcodeStr, Dt, "$dst, $src, $SIMM", "",
+ [(set QPR:$dst, (ResTy (OpNode (OpTy DPR:$src),
+ (i32 imm:$SIMM))))]> {
+ // This has a different interpretation of the shift amount encoding than
+ // NVectorShiftFrm.
+ let NSF = NVectorShift2Frm; // For disassembly.
+ let NSForm = NVectorShift2Frm.Value; // For disassembly.
+}
+
// Convert, with fractional bits immediate,
// both double- and quad-register.
+let NSF = NVdVmImmVCVTFrm, NSForm = NVdVmImmVCVTFrm.Value in {
class N2VCvtD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
Intrinsic IntOp>
@@ -1140,6 +1294,7 @@ class N2VCvtQ<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
(outs QPR:$dst), (ins QPR:$src, i32imm:$SIMM), IIC_VUNAQ,
OpcodeStr, Dt, "$dst, $src, $SIMM", "",
[(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src), (i32 imm:$SIMM))))]>;
+}
//===----------------------------------------------------------------------===//
// Multiclasses
@@ -1350,6 +1505,60 @@ multiclass N3VInt_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
v2i64, v2i64, IntOp, Commutable>;
}
+// Same as N3VInt_QHSD, except they're for Vector Shift (Register) Instructions.
+// D:Vd M:Vm N:Vn (notice that M:Vm is the first operand)
+// This helps the disassembler.
+let NSF = NVdVnVmImmVectorShiftFrm, NSForm = NVdVnVmImmVectorShiftFrm.Value in {
+multiclass N3VInt_HS2<bit op24, bit op23, bits<4> op11_8, bit op4,
+ InstrItinClass itinD16, InstrItinClass itinD32,
+ InstrItinClass itinQ16, InstrItinClass itinQ32,
+ string OpcodeStr, string Dt,
+ Intrinsic IntOp, bit Commutable = 0> {
+ // 64-bit vector types.
+ def v4i16 : N3VDInt<op24, op23, 0b01, op11_8, op4, itinD16,
+ OpcodeStr, !strconcat(Dt, "16"),
+ v4i16, v4i16, IntOp, Commutable>;
+ def v2i32 : N3VDInt<op24, op23, 0b10, op11_8, op4, itinD32,
+ OpcodeStr, !strconcat(Dt, "32"),
+ v2i32, v2i32, IntOp, Commutable>;
+
+ // 128-bit vector types.
+ def v8i16 : N3VQInt<op24, op23, 0b01, op11_8, op4, itinQ16,
+ OpcodeStr, !strconcat(Dt, "16"),
+ v8i16, v8i16, IntOp, Commutable>;
+ def v4i32 : N3VQInt<op24, op23, 0b10, op11_8, op4, itinQ32,
+ OpcodeStr, !strconcat(Dt, "32"),
+ v4i32, v4i32, IntOp, Commutable>;
+}
+multiclass N3VInt_QHS2<bit op24, bit op23, bits<4> op11_8, bit op4,
+ InstrItinClass itinD16, InstrItinClass itinD32,
+ InstrItinClass itinQ16, InstrItinClass itinQ32,
+ string OpcodeStr, string Dt,
+ Intrinsic IntOp, bit Commutable = 0>
+ : N3VInt_HS2<op24, op23, op11_8, op4, itinD16, itinD32, itinQ16, itinQ32,
+ OpcodeStr, Dt, IntOp, Commutable> {
+ def v8i8 : N3VDInt<op24, op23, 0b00, op11_8, op4, itinD16,
+ OpcodeStr, !strconcat(Dt, "8"),
+ v8i8, v8i8, IntOp, Commutable>;
+ def v16i8 : N3VQInt<op24, op23, 0b00, op11_8, op4, itinQ16,
+ OpcodeStr, !strconcat(Dt, "8"),
+ v16i8, v16i8, IntOp, Commutable>;
+}
+multiclass N3VInt_QHSD2<bit op24, bit op23, bits<4> op11_8, bit op4,
+ InstrItinClass itinD16, InstrItinClass itinD32,
+ InstrItinClass itinQ16, InstrItinClass itinQ32,
+ string OpcodeStr, string Dt,
+ Intrinsic IntOp, bit Commutable = 0>
+ : N3VInt_QHS2<op24, op23, op11_8, op4, itinD16, itinD32, itinQ16, itinQ32,
+ OpcodeStr, Dt, IntOp, Commutable> {
+ def v1i64 : N3VDInt<op24, op23, 0b11, op11_8, op4, itinD32,
+ OpcodeStr, !strconcat(Dt, "64"),
+ v1i64, v1i64, IntOp, Commutable>;
+ def v2i64 : N3VQInt<op24, op23, 0b11, op11_8, op4, itinQ32,
+ OpcodeStr, !strconcat(Dt, "64"),
+ v2i64, v2i64, IntOp, Commutable>;
+}
+}
// Neon Narrowing 3-register vector intrinsics,
// source operand element sizes of 16, 32 and 64 bits:
@@ -1619,6 +1828,47 @@ multiclass N2VSh_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
// imm6 = xxxxxx
}
+// Same as N2VSh_QHSD, except the instructions have a differnt interpretation of
+// the shift amount. This helps the disassembler.
+let NSF = NVectorShift2Frm, NSForm = NVectorShift2Frm.Value in {
+multiclass N2VSh_QHSD2<bit op24, bit op23, bits<4> op11_8, bit op4,
+ InstrItinClass itin, string OpcodeStr, string Dt,
+ SDNode OpNode> {
+ // 64-bit vector types.
+ def v8i8 : N2VDSh<op24, op23, op11_8, 0, op4, itin,
+ OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> {
+ let Inst{21-19} = 0b001; // imm6 = 001xxx
+ }
+ def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, itin,
+ OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> {
+ let Inst{21-20} = 0b01; // imm6 = 01xxxx
+ }
+ def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, itin,
+ OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> {
+ let Inst{21} = 0b1; // imm6 = 1xxxxx
+ }
+ def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, itin,
+ OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>;
+ // imm6 = xxxxxx
+
+ // 128-bit vector types.
+ def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, itin,
+ OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> {
+ let Inst{21-19} = 0b001; // imm6 = 001xxx
+ }
+ def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, itin,
+ OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> {
+ let Inst{21-20} = 0b01; // imm6 = 01xxxx
+ }
+ def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, itin,
+ OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> {
+ let Inst{21} = 0b1; // imm6 = 1xxxxx
+ }
+ def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, itin,
+ OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>;
+ // imm6 = xxxxxx
+}
+}
// Neon Shift-Accumulate vector operations,
// element sizes of 8, 16, 32 and 64 bits:
@@ -1699,6 +1949,47 @@ multiclass N2VShIns_QHSD<bit