aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM
diff options
context:
space:
mode:
authorJohnny Chen <johnny.chen@apple.com>2010-03-16 16:36:54 +0000
committerJohnny Chen <johnny.chen@apple.com>2010-03-16 16:36:54 +0000
commitd30a98e43ae18e1fc70a7dc748edf669d809c685 (patch)
tree808136df95741812c7297abfb604a5696499dad0 /lib/Target/ARM
parentea7f22c31d0d12923eaab6840322431cc0222ae9 (diff)
Initial ARM/Thumb disassembler check-in. It consists of a tablgen backend
(RISCDisassemblerEmitter) which emits the decoder functions for ARM and Thumb, and the disassembler core which invokes the decoder function and builds up the MCInst based on the decoded Opcode. Added sub-formats to the NeonI/NeonXI instructions to further refine the NEONFrm instructions to help disassembly. We also changed the output of the addressing modes to omit the '+' from the assembler syntax #+/-<imm> or +/-<Rm>. See, for example, A8.6.57/58/60. And modified test cases to not expect '+' in +reg or #+num. For example, ; CHECK: ldr.w r9, [r7, #28] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98637 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-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 : N3V