diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMAddressingModes.h | 20 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrFormats.td | 43 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrNEON.td | 495 | ||||
-rw-r--r-- | lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 46 | ||||
-rw-r--r-- | lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp | 433 | ||||
-rw-r--r-- | lib/Target/ARM/AsmPrinter/ARMInstPrinter.h | 40 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 513 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.h | 71 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp | 3351 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassemblerCore.h | 301 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/Makefile | 17 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ThumbDisassemblerCore.cpp.inc | 2158 | ||||
-rw-r--r-- | lib/Target/ARM/Makefile | 5 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb2ITBlockPass.cpp | 8 |
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 |