[llvm-commits] [llvm] r98640 - in /llvm/trunk: ./ lib/Target/ARM/ lib/Target/ARM/AsmPrinter/ lib/Target/ARM/Disassembler/ test/CodeGen/ARM/ test/CodeGen/Thumb2/ utils/TableGen/
Bob Wilson
bob.wilson at apple.com
Tue Mar 16 09:59:47 PDT 2010
Author: bwilson
Date: Tue Mar 16 11:59:47 2010
New Revision: 98640
URL: http://llvm.org/viewvc/llvm-project?rev=98640&view=rev
Log:
--- Reverse-merging r98637 into '.':
U test/CodeGen/ARM/tls2.ll
U test/CodeGen/ARM/arm-negative-stride.ll
U test/CodeGen/ARM/2009-10-30.ll
U test/CodeGen/ARM/globals.ll
U test/CodeGen/ARM/str_pre-2.ll
U test/CodeGen/ARM/ldrd.ll
U test/CodeGen/ARM/2009-10-27-double-align.ll
U test/CodeGen/Thumb2/thumb2-strb.ll
U test/CodeGen/Thumb2/ldr-str-imm12.ll
U test/CodeGen/Thumb2/thumb2-strh.ll
U test/CodeGen/Thumb2/thumb2-ldr.ll
U test/CodeGen/Thumb2/thumb2-str_pre.ll
U test/CodeGen/Thumb2/thumb2-str.ll
U test/CodeGen/Thumb2/thumb2-ldrh.ll
U utils/TableGen/TableGen.cpp
U utils/TableGen/DisassemblerEmitter.cpp
D utils/TableGen/RISCDisassemblerEmitter.h
D utils/TableGen/RISCDisassemblerEmitter.cpp
U Makefile.rules
U lib/Target/ARM/ARMInstrNEON.td
U lib/Target/ARM/Makefile
U lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
U lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
U lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
D lib/Target/ARM/Disassembler
U lib/Target/ARM/ARMInstrFormats.td
U lib/Target/ARM/ARMAddressingModes.h
U lib/Target/ARM/Thumb2ITBlockPass.cpp
Removed:
llvm/trunk/lib/Target/ARM/Disassembler/
llvm/trunk/utils/TableGen/RISCDisassemblerEmitter.cpp
llvm/trunk/utils/TableGen/RISCDisassemblerEmitter.h
Modified:
llvm/trunk/Makefile.rules
llvm/trunk/lib/Target/ARM/ARMAddressingModes.h
llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
llvm/trunk/lib/Target/ARM/Makefile
llvm/trunk/lib/Target/ARM/Thumb2ITBlockPass.cpp
llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll
llvm/trunk/test/CodeGen/ARM/2009-10-30.ll
llvm/trunk/test/CodeGen/ARM/arm-negative-stride.ll
llvm/trunk/test/CodeGen/ARM/globals.ll
llvm/trunk/test/CodeGen/ARM/ldrd.ll
llvm/trunk/test/CodeGen/ARM/str_pre-2.ll
llvm/trunk/test/CodeGen/ARM/tls2.ll
llvm/trunk/test/CodeGen/Thumb2/ldr-str-imm12.ll
llvm/trunk/test/CodeGen/Thumb2/thumb2-ldr.ll
llvm/trunk/test/CodeGen/Thumb2/thumb2-ldrh.ll
llvm/trunk/test/CodeGen/Thumb2/thumb2-str.ll
llvm/trunk/test/CodeGen/Thumb2/thumb2-str_pre.ll
llvm/trunk/test/CodeGen/Thumb2/thumb2-strb.ll
llvm/trunk/test/CodeGen/Thumb2/thumb2-strh.ll
llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp
llvm/trunk/utils/TableGen/TableGen.cpp
Modified: llvm/trunk/Makefile.rules
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.rules?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/Makefile.rules (original)
+++ llvm/trunk/Makefile.rules Tue Mar 16 11:59:47 2010
@@ -1614,11 +1614,6 @@
$(Echo) "Building $(<F) intrinsics information with tblgen"
$(Verb) $(TableGen) -gen-tgt-intrinsic -o $(call SYSPATH, $@) $<
-$(ObjDir)/ARMDisassemblerTables.inc.tmp : ARM.td $(ObjDir)/.dir
- $(Echo) "Building ARM disassembly tables with tblgen"
- $(Verb) $(TableGen) -gen-risc-disassembler -o $(call SYSPATH, $@) $<
-
-
clean-local::
-$(Verb) $(RM) -f $(INCFiles)
Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAddressingModes.h?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAddressingModes.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMAddressingModes.h Tue Mar 16 11:59:47 2010
@@ -35,10 +35,6 @@
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!");
@@ -131,20 +127,6 @@
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
@@ -197,7 +179,7 @@
// of zero.
if ((Arg & ~255U) == 0) return Arg;
- unsigned RotAmt = getSOImmValOneRotate(Arg);
+ unsigned RotAmt = getSOImmValRotate(Arg);
// If this cannot be handled with a single shifter_op, bail out.
if (rotr32(~255U, RotAmt) & Arg)
Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Tue Mar 16 11:59:47 2010
@@ -1464,29 +1464,6 @@
// 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> {
@@ -1497,8 +1474,6 @@
!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.
@@ -1510,8 +1485,6 @@
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,
@@ -1524,8 +1497,6 @@
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,
@@ -1538,8 +1509,6 @@
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,
@@ -1569,8 +1538,6 @@
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.
@@ -1586,8 +1553,6 @@
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.
@@ -1603,8 +1568,6 @@
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.
@@ -1618,8 +1581,6 @@
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.
@@ -1633,8 +1594,6 @@
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.
@@ -1648,8 +1607,6 @@
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.
Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Tue Mar 16 11:59:47 2010
@@ -213,10 +213,7 @@
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", "", []> {
- let NSF = VLDSTLaneDblFrm; // For disassembly.
- let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
-}
+ OpcodeStr, Dt, "\\{$dst1, $dst2\\}, $addr", "", []>;
def VLD2d8D : VLD2Ddbl<0b0000, "vld2", "8">;
def VLD2d16D : VLD2Ddbl<0b0100, "vld2", "16">;
@@ -231,10 +228,7 @@
: 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", []> {
- let NSF = VLDSTLaneDblFrm; // For disassembly.
- let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
-}
+ "$addr.addr = $wb", []>;
def VLD3d8 : VLD3D<0b0000, "vld3", "8">;
def VLD3d16 : VLD3D<0b0100, "vld3", "16">;
@@ -266,10 +260,7 @@
(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", []> {
- let NSF = VLDSTLaneDblFrm; // For disassembly.
- let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
-}
+ "$addr.addr = $wb", []>;
def VLD4d8 : VLD4D<0b0000, "vld4", "8">;
def VLD4d16 : VLD4D<0b0100, "vld4", "16">;
@@ -306,28 +297,12 @@
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;
- 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.
-}
+def VLD2LNq16a: VLD2LN<0b0101, "vld2", "16"> { let Inst{5} = 1; }
+def VLD2LNq32a: VLD2LN<0b1001, "vld2", "32"> { let Inst{6} = 1; }
// vld2 to double-spaced odd registers.
-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.
-}
+def VLD2LNq16b: VLD2LN<0b0101, "vld2", "16"> { let Inst{5} = 1; }
+def VLD2LNq32b: VLD2LN<0b1001, "vld2", "32"> { let Inst{6} = 1; }
// VLD3LN : Vector Load (single 3-element structure to one lane)
class VLD3LN<bits<4> op11_8, string OpcodeStr, string Dt>
@@ -343,11 +318,7 @@
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;
- let NSF = VLDSTLaneDblFrm; // For disassembly.
- let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
-}
+def VLD3LNq16a: VLD3LN<0b0110, "vld3", "16"> { let Inst{5-4} = 0b10; }
def VLD3LNq32a: VLD3LN<0b1010, "vld3", "32"> { let Inst{6-4} = 0b100; }
// vld3 to double-spaced odd registers.
@@ -369,28 +340,12 @@
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;
- 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.
-}
+def VLD4LNq16a: VLD4LN<0b0111, "vld4", "16"> { let Inst{5} = 1; }
+def VLD4LNq32a: VLD4LN<0b1011, "vld4", "32"> { let Inst{6} = 1; }
// vld4 to double-spaced odd registers.
-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.
-}
+def VLD4LNq16b: VLD4LN<0b0111, "vld4", "16"> { let Inst{5} = 1; }
+def VLD4LNq32b: VLD4LN<0b1011, "vld4", "32"> { let Inst{6} = 1; }
// VLD1DUP : Vector Load (single element to all lanes)
// VLD2DUP : Vector Load (single 2-element structure to all lanes)
@@ -478,10 +433,7 @@
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", "", []> {
- let NSF = VLDSTLaneDblFrm; // For disassembly.
- let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
-}
+ OpcodeStr, Dt, "\\{$src1, $src2\\}, $addr", "", []>;
def VST2d8D : VST2Ddbl<0b0000, "vst2", "8">;
def VST2d16D : VST2Ddbl<0b0100, "vst2", "16">;
@@ -496,10 +448,7 @@
: 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", []> {
- let NSF = VLDSTLaneDblFrm; // For disassembly.
- let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
-}
+ "$addr.addr = $wb", []>;
def VST3d8 : VST3D<0b0000, "vst3", "8">;
def VST3d16 : VST3D<0b0100, "vst3", "16">;
@@ -529,10 +478,7 @@
: 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", []> {
- let NSF = VLDSTLaneDblFrm; // For disassembly.
- let NSForm = VLDSTLaneDblFrm.Value; // For disassembly.
-}
+ "$addr.addr = $wb", []>;
def VST4d8 : VST4D<0b0000, "vst4", "8">;
def VST4d16 : VST4D<0b0100, "vst4", "16">;
@@ -569,28 +515,12 @@
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;
- 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.
-}
+def VST2LNq16a: VST2LN<0b0101, "vst2", "16"> { let Inst{5} = 1; }
+def VST2LNq32a: VST2LN<0b1001, "vst2", "32"> { let Inst{6} = 1; }
// vst2 to double-spaced odd registers.
-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.
-}
+def VST2LNq16b: VST2LN<0b0101, "vst2", "16"> { let Inst{5} = 1; }
+def VST2LNq32b: VST2LN<0b1001, "vst2", "32"> { let Inst{6} = 1; }
// VST3LN : Vector Store (single 3-element structure from one lane)
class VST3LN<bits<4> op11_8, string OpcodeStr, string Dt>
@@ -605,28 +535,12 @@
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;
- 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.
-}
+def VST3LNq16a: VST3LN<0b0110, "vst3", "16"> { let Inst{5-4} = 0b10; }
+def VST3LNq32a: VST3LN<0b1010, "vst3", "32"> { let Inst{6-4} = 0b100; }
// vst3 to double-spaced odd registers.
-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.
-}
+def VST3LNq16b: VST3LN<0b0110, "vst3", "16"> { let Inst{5-4} = 0b10; }
+def VST3LNq32b: VST3LN<0b1010, "vst3", "32"> { let Inst{6-4} = 0b100; }
// VST4LN : Vector Store (single 4-element structure from one lane)
class VST4LN<bits<4> op11_8, string OpcodeStr, string Dt>
@@ -642,28 +556,12 @@
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;
- 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.
-}
+def VST4LNq16a: VST4LN<0b0111, "vst4", "16"> { let Inst{5} = 1; }
+def VST4LNq32a: VST4LN<0b1011, "vst4", "32"> { let Inst{6} = 1; }
// vst4 to double-spaced odd registers.
-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.
-}
+def VST4LNq16b: VST4LN<0b0111, "vst4", "16"> { let Inst{5} = 1; }
+def VST4LNq32b: VST4LN<0b1011, "vst4", "32"> { let Inst{6} = 1; }
} // mayStore = 1, hasExtraSrcRegAllocReq = 1
@@ -770,18 +668,12 @@
: 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", []> {
- let NSF = NVectorShuffleFrm; // For disassembly.
- let NSForm = NVectorShuffleFrm.Value; // For disassembly.
-}
+ "$src1 = $dst1, $src2 = $dst2", []>;
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", []> {
- let NSF = NVectorShuffleFrm; // For disassembly.
- let NSForm = NVectorShuffleFrm.Value; // For disassembly.
-}
+ "$src1 = $dst1, $src2 = $dst2", []>;
// 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,
@@ -823,8 +715,6 @@
(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>
@@ -835,8 +725,6 @@
(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,
@@ -868,8 +756,6 @@
(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>
@@ -881,8 +767,6 @@
(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.
@@ -905,8 +789,6 @@
(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>
@@ -918,8 +800,6 @@
(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,
@@ -942,8 +822,6 @@
(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,
@@ -956,8 +834,6 @@
(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.
@@ -988,10 +864,7 @@
(Ty (ShOp (Ty DPR:$src1),
(Ty (MulOp DPR:$src2,
(Ty (NEONvduplane (Ty DPR_VFP2:$src3),
- imm:$lane)))))))]> {
- let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
- let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
-}
+ imm:$lane)))))))]>;
class N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
string OpcodeStr, string Dt,
ValueType Ty, SDNode MulOp, SDNode ShOp>
@@ -1003,10 +876,7 @@
(Ty (ShOp (Ty DPR:$src1),
(Ty (MulOp DPR:$src2,
(Ty (NEONvduplane (Ty DPR_8:$src3),
- imm:$lane)))))))]> {
- let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
- let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
-}
+ imm:$lane)))))))]>;
class N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty,
@@ -1027,10 +897,7 @@
(ResTy (ShOp (ResTy QPR:$src1),
(ResTy (MulOp QPR:$src2,
(ResTy (NEONvduplane (OpTy DPR_VFP2:$src3),
- imm:$lane)))))))]> {
- let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
- let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
-}
+ imm:$lane)))))))]>;
class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
string OpcodeStr, string Dt,
ValueType ResTy, ValueType OpTy,
@@ -1043,10 +910,7 @@
(ResTy (ShOp (ResTy QPR:$src1),
(ResTy (MulOp QPR:$src2,
(ResTy (NEONvduplane (OpTy DPR_8:$src3),
- imm:$lane)))))))]> {
- let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
- let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
-}
+ imm:$lane)))))))]>;
// Neon 3-argument intrinsics, both double- and quad-register.
// The destination register is also used as the first source operand register.
@@ -1132,10 +996,7 @@
[(set (ResTy QPR:$dst),
(ResTy (IntOp (OpTy DPR:$src1),
(OpTy (NEONvduplane (OpTy DPR_VFP2:$src2),
- imm:$lane)))))]> {
- let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
- let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
-}
+ imm:$lane)))))]>;
class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
InstrItinClass itin, string OpcodeStr, string Dt,
ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
@@ -1145,10 +1006,7 @@
[(set (ResTy QPR:$dst),
(ResTy (IntOp (OpTy DPR:$src1),
(OpTy (NEONvduplane (OpTy DPR_8:$src2),
- imm:$lane)))))]> {
- let NSF = NVdVnVmImmMulScalarFrm; // For disassembly.
- let NSForm = NVdVnVmImmMulScalarFrm.Value; // For disassembly.
-}
+ imm:$lane)))))]>;
// Wide 3-register intrinsics.
class N3VWInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
@@ -1197,10 +1055,6 @@
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,
@@ -1218,6 +1072,16 @@
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,
@@ -1260,26 +1124,8 @@
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>
@@ -1294,7 +1140,6 @@
(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
@@ -1505,60 +1350,6 @@
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:
@@ -1828,47 +1619,6 @@
// 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:
@@ -1949,47 +1699,6 @@
// imm6 = xxxxxx
}
-// Same as N2VShIns_QHSD, except the instructions have a differnt interpretation
-// of the shift amount. This helps the disassembler.
-let NSF = NVectorShift2Frm, NSForm = NVectorShift2Frm.Value in {
-multiclass N2VShIns_QHSD2<bit op24, bit op23, bits<4> op11_8, bit op4,
- string OpcodeStr, SDNode ShOp> {
- // 64-bit vector types.
- def v8i8 : N2VDShIns<op24, op23, op11_8, 0, op4,
- OpcodeStr, "8", v8i8, ShOp> {
- let Inst{21-19} = 0b001; // imm6 = 001xxx
- }
- def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4,
- OpcodeStr, "16", v4i16, ShOp> {
- let Inst{21-20} = 0b01; // imm6 = 01xxxx
- }
- def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4,
- OpcodeStr, "32", v2i32, ShOp> {
- let Inst{21} = 0b1; // imm6 = 1xxxxx
- }
- def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4,
- OpcodeStr, "64", v1i64, ShOp>;
- // imm6 = xxxxxx
-
- // 128-bit vector types.
- def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4,
- OpcodeStr, "8", v16i8, ShOp> {
- let Inst{21-19} = 0b001; // imm6 = 001xxx
- }
- def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4,
- OpcodeStr, "16", v8i16, ShOp> {
- let Inst{21-20} = 0b01; // imm6 = 01xxxx
- }
- def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4,
- OpcodeStr, "32", v4i32, ShOp> {
- let Inst{21} = 0b1; // imm6 = 1xxxxx
- }
- def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4,
- OpcodeStr, "64", v2i64, ShOp>;
- // imm6 = xxxxxx
-}
-}
-
// Neon Shift Long operations,
// element sizes of 8, 16, 32 bits:
multiclass N2VLSh_QHS<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6,
@@ -2620,21 +2329,18 @@
// Vector Shifts.
// VSHL : Vector Shift
-defm VSHLs : N3VInt_QHSD2<0,0, 0b0100, 0, IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ,
- IIC_VSHLiQ, "vshl", "s", int_arm_neon_vshifts, 0>;
-defm VSHLu : N3VInt_QHSD2<1,0, 0b0100, 0, IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ,
- IIC_VSHLiQ, "vshl", "u", int_arm_neon_vshiftu, 0>;
+defm VSHLs : N3VInt_QHSD<0, 0, 0b0100, 0, IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ,
+ IIC_VSHLiQ, "vshl", "s", int_arm_neon_vshifts, 0>;
+defm VSHLu : N3VInt_QHSD<1, 0, 0b0100, 0, IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ,
+ IIC_VSHLiQ, "vshl", "u", int_arm_neon_vshiftu, 0>;
// VSHL : Vector Shift Left (Immediate)
-// (disassembly note: this has a different interpretation of the shift amont)
-defm VSHLi : N2VSh_QHSD2<0, 1, 0b0101, 1, IIC_VSHLiD, "vshl", "i", NEONvshl>;
+defm VSHLi : N2VSh_QHSD<0, 1, 0b0101, 1, IIC_VSHLiD, "vshl", "i", NEONvshl>;
// VSHR : Vector Shift Right (Immediate)
defm VSHRs : N2VSh_QHSD<0, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "s", NEONvshrs>;
defm VSHRu : N2VSh_QHSD<1, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "u", NEONvshru>;
// VSHLL : Vector Shift Left Long
-// (disassembly note: this has a different interpretation of the shift amont)
defm VSHLLs : N2VLSh_QHS<0, 1, 0b1010, 0, 0, 1, "vshll", "s", NEONvshlls>;
-// (disassembly note: this has a different interpretation of the shift amont)
defm VSHLLu : N2VLSh_QHS<1, 1, 0b1010, 0, 0, 1, "vshll", "u", NEONvshllu>;
// VSHLL : Vector Shift Left Long (with maximum shift count)
@@ -2644,8 +2350,6 @@
: N2VLSh<op24, op23, op11_8, op7, op6, op4, OpcodeStr, Dt,
ResTy, OpTy, OpNode> {
let Inst{21-16} = op21_16;
- let NSF = NVdVmImmVSHLLFrm; // For disassembly.
- let NSForm = NVdVmImmVSHLLFrm.Value; // For disassembly.
}
def VSHLLi8 : N2VLShMax<1, 1, 0b110010, 0b0011, 0, 0, 0, "vshll", "i8",
v8i16, v8i8, NEONvshlli>;
@@ -2659,10 +2363,10 @@
NEONvshrn>;
// VRSHL : Vector Rounding Shift
-defm VRSHLs : N3VInt_QHSD2<0,0,0b0101,0,IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
- IIC_VSHLi4Q,"vrshl", "s", int_arm_neon_vrshifts,0>;
-defm VRSHLu : N3VInt_QHSD2<1,0,0b0101,0,IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
- IIC_VSHLi4Q,"vrshl", "u", int_arm_neon_vrshiftu,0>;
+defm VRSHLs : N3VInt_QHSD<0,0,0b0101,0, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
+ IIC_VSHLi4Q, "vrshl", "s", int_arm_neon_vrshifts,0>;
+defm VRSHLu : N3VInt_QHSD<1,0,0b0101,0, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
+ IIC_VSHLi4Q, "vrshl", "u", int_arm_neon_vrshiftu,0>;
// VRSHR : Vector Rounding Shift Right
defm VRSHRs : N2VSh_QHSD<0,1,0b0010,1, IIC_VSHLi4D, "vrshr", "s", NEONvrshrs>;
defm VRSHRu : N2VSh_QHSD<1,1,0b0010,1, IIC_VSHLi4D, "vrshr", "u", NEONvrshru>;
@@ -2672,18 +2376,15 @@
NEONvrshrn>;
// VQSHL : Vector Saturating Shift
-defm VQSHLs : N3VInt_QHSD2<0,0,0b0100,1,IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
- IIC_VSHLi4Q, "vqshl", "s", int_arm_neon_vqshifts,0>;
-defm VQSHLu : N3VInt_QHSD2<1,0,0b0100,1,IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
- IIC_VSHLi4Q, "vqshl", "u", int_arm_neon_vqshiftu,0>;
+defm VQSHLs : N3VInt_QHSD<0,0,0b0100,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
+ IIC_VSHLi4Q, "vqshl", "s", int_arm_neon_vqshifts,0>;
+defm VQSHLu : N3VInt_QHSD<1,0,0b0100,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
+ IIC_VSHLi4Q, "vqshl", "u", int_arm_neon_vqshiftu,0>;
// VQSHL : Vector Saturating Shift Left (Immediate)
-// (disassembly note: this has a different interpretation of the shift amont)
-defm VQSHLsi : N2VSh_QHSD2<0,1,0b0111,1, IIC_VSHLi4D, "vqshl", "s", NEONvqshls>;
-// (disassembly note: this has a different interpretation of the shift amont)
-defm VQSHLui : N2VSh_QHSD2<1,1,0b0111,1, IIC_VSHLi4D, "vqshl", "u", NEONvqshlu>;
+defm VQSHLsi : N2VSh_QHSD<0,1,0b0111,1, IIC_VSHLi4D, "vqshl", "s", NEONvqshls>;
+defm VQSHLui : N2VSh_QHSD<1,1,0b0111,1, IIC_VSHLi4D, "vqshl", "u", NEONvqshlu>;
// VQSHLU : Vector Saturating Shift Left (Immediate, Unsigned)
-// (disassembly note: this has a different interpretation of the shift amont)
-defm VQSHLsu : N2VSh_QHSD2<1,1,0b0110,1, IIC_VSHLi4D, "vqshlu","s",NEONvqshlsu>;
+defm VQSHLsu : N2VSh_QHSD<1,1,0b0110,1, IIC_VSHLi4D, "vqshlu","s",NEONvqshlsu>;
// VQSHRN : Vector Saturating Shift Right and Narrow
defm VQSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "s",
@@ -2696,12 +2397,12 @@
NEONvqshrnsu>;
// VQRSHL : Vector Saturating Rounding Shift
-defm VQRSHLs : N3VInt_QHSD2<0,0,0b0101,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
- IIC_VSHLi4Q, "vqrshl", "s",
- int_arm_neon_vqrshifts, 0>;
-defm VQRSHLu : N3VInt_QHSD2<1,0,0b0101,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
- IIC_VSHLi4Q, "vqrshl", "u",
- int_arm_neon_vqrshiftu, 0>;
+defm VQRSHLs : N3VInt_QHSD<0,0,0b0101,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
+ IIC_VSHLi4Q, "vqrshl", "s",
+ int_arm_neon_vqrshifts, 0>;
+defm VQRSHLu : N3VInt_QHSD<1,0,0b0101,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
+ IIC_VSHLi4Q, "vqrshl", "u",
+ int_arm_neon_vqrshiftu, 0>;
// VQRSHRN : Vector Saturating Rounding Shift Right and Narrow
defm VQRSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "s",
@@ -2721,8 +2422,7 @@
defm VRSRAu : N2VShAdd_QHSD<1, 1, 0b0011, 1, "vrsra", "u", NEONvrshru>;
// VSLI : Vector Shift Left and Insert
-// (disassembly note: this has a different interpretation of the shift amont)
-defm VSLI : N2VShIns_QHSD2<1, 1, 0b0101, 1, "vsli", NEONvsli>;
+defm VSLI : N2VShIns_QHSD<1, 1, 0b0101, 1, "vsli", NEONvsli>;
// VSRI : Vector Shift Right and Insert
defm VSRI : N2VShIns_QHSD<1, 1, 0b0100, 1, "vsri", NEONvsri>;
@@ -2818,13 +2518,10 @@
// VMOV : Vector Move (Register)
-// Mark these instructions as 2-register instructions to help the disassembler.
-let NSF = NVdVmImmFrm, NSForm = NVdVmImmFrm.Value in {
def VMOVDneon: N3VX<0, 0, 0b10, 0b0001, 0, 1, (outs DPR:$dst), (ins DPR:$src),
IIC_VMOVD, "vmov", "$dst, $src", "", []>;
def VMOVQ : N3VX<0, 0, 0b10, 0b0001, 1, 1, (outs QPR:$dst), (ins QPR:$src),
IIC_VMOVD, "vmov", "$dst, $src", "", []>;
-}
// VMOV : Vector Move (Immediate)
@@ -3065,7 +2762,6 @@
// VDUP : Vector Duplicate Lane (from scalar to all elements)
-let NSF = NVdVmImmVDupLaneFrm, NSForm = NVdVmImmVDupLaneFrm.Value in {
class VDUPLND<bits<2> op19_18, bits<2> op17_16,
string OpcodeStr, string Dt, ValueType Ty>
: N2V<0b11, 0b11, op19_18, op17_16, 0b11000, 0, 0,
@@ -3079,7 +2775,6 @@
(outs QPR:$dst), (ins DPR:$src, nohash_imm:$lane), IIC_VMOVD,
OpcodeStr, Dt, "$dst, $src[$lane]", "",
[(set QPR:$dst, (ResTy (NEONvduplane (OpTy DPR:$src), imm:$lane)))]>;
-}
// Inst{19-16} is partially specified depending on the element size.
@@ -3148,37 +2843,24 @@
// Vector Conversions.
-let NSF = NVdVmImmVCVTFrm, NSForm = NVdVmImmVCVTFrm.Value in {
-class N2VDX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
- bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
- string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
- : N2VD<op24_23, op21_20, op19_18, op17_16, op11_7, op4, OpcodeStr, Dt,
- ResTy, OpTy, OpNode>;
-class N2VQX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
- bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
- string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
- : N2VQ<op24_23, op21_20, op19_18, op17_16, op11_7, op4, OpcodeStr, Dt,
- ResTy, OpTy, OpNode>;
-}
-
// VCVT : Vector Convert Between Floating-Point and Integers
-def VCVTf2sd : N2VDX<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
- v2i32, v2f32, fp_to_sint>;
-def VCVTf2ud : N2VDX<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
- v2i32, v2f32, fp_to_uint>;
-def VCVTs2fd : N2VDX<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
- v2f32, v2i32, sint_to_fp>;
-def VCVTu2fd : N2VDX<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
- v2f32, v2i32, uint_to_fp>;
-
-def VCVTf2sq : N2VQX<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
- v4i32, v4f32, fp_to_sint>;
-def VCVTf2uq : N2VQX<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
- v4i32, v4f32, fp_to_uint>;
-def VCVTs2fq : N2VQX<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
- v4f32, v4i32, sint_to_fp>;
-def VCVTu2fq : N2VQX<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
- v4f32, v4i32, uint_to_fp>;
+def VCVTf2sd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
+ v2i32, v2f32, fp_to_sint>;
+def VCVTf2ud : N2VD<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
+ v2i32, v2f32, fp_to_uint>;
+def VCVTs2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
+ v2f32, v2i32, sint_to_fp>;
+def VCVTu2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
+ v2f32, v2i32, uint_to_fp>;
+
+def VCVTf2sq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
+ v4i32, v4f32, fp_to_sint>;
+def VCVTf2uq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
+ v4i32, v4f32, fp_to_uint>;
+def VCVTs2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
+ v4f32, v4i32, sint_to_fp>;
+def VCVTu2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
+ v4f32, v4i32, uint_to_fp>;
// VCVT : Vector Convert Between Floating-Point and Fixed-Point.
def VCVTf2xsd : N2VCvtD<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32",
@@ -3263,8 +2945,6 @@
// VEXT : Vector Extract
-let NSF = NVdVnVmImmVectorExtractFrm,
- NSForm = NVdVnVmImmVectorExtractFrm.Value in {
class VEXTd<string OpcodeStr, string Dt, ValueType Ty>
: N3V<0,1,0b11,{?,?,?,?},0,0, (outs DPR:$dst),
(ins DPR:$lhs, DPR:$rhs, i32imm:$index), IIC_VEXTD,
@@ -3278,7 +2958,6 @@
OpcodeStr, Dt, "$dst, $lhs, $rhs, $index", "",
[(set QPR:$dst, (Ty (NEONvext (Ty QPR:$lhs),
(Ty QPR:$rhs), imm:$index)))]>;
-}
def VEXTd8 : VEXTd<"vext", "8", v8i8>;
def VEXTd16 : VEXTd<"vext", "16", v4i16>;
@@ -3322,8 +3001,6 @@
// Vector Table Lookup and Table Extension.
-let NSF = VTBLFrm, NSForm = VTBLFrm.Value in {
-
// VTBL : Vector Table Lookup
def VTBL1
: N3V<1,1,0b11,0b1000,0,0, (outs DPR:$dst),
@@ -3380,8 +3057,6 @@
DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src)))]>;
} // hasExtraSrcRegAllocReq = 1
-} // End of "let NSF = VTBLFrm, ..."
-
//===----------------------------------------------------------------------===//
// NEON instructions for single-precision FP math
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Tue Mar 16 11:59:47 2010
@@ -120,7 +120,7 @@
void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum);
void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum);
void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum);
- void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum);
+ void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum) {}
void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum);
void printCPSOptionOperand(const MachineInstr *MI, int OpNum) {}
@@ -431,16 +431,16 @@
O << "[" << getRegisterName(MO1.getReg());
if (!MO2.getReg()) {
- if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
+ if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
O << ", #"
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
+ << (char)ARM_AM::getAM2Op(MO3.getImm())
<< ARM_AM::getAM2Offset(MO3.getImm());
O << "]";
return;
}
O << ", "
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
+ << (char)ARM_AM::getAM2Op(MO3.getImm())
<< getRegisterName(MO2.getReg());
if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
@@ -458,12 +458,12 @@
unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
assert(ImmOffs && "Malformed indexed load / store!");
O << "#"
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
+ << (char)ARM_AM::getAM2Op(MO2.getImm())
<< ImmOffs;
return;
}
- O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
+ O << (char)ARM_AM::getAM2Op(MO2.getImm())
<< getRegisterName(MO1.getReg());
if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
@@ -490,7 +490,7 @@
if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
O << ", #"
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
+ << (char)ARM_AM::getAM3Op(MO3.getImm())
<< ImmOffs;
O << "]";
}
@@ -508,7 +508,7 @@
unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
assert(ImmOffs && "Malformed indexed load / store!");
O << "#"
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
+ << (char)ARM_AM::getAM3Op(MO2.getImm())
<< ImmOffs;
}
@@ -558,7 +558,7 @@
if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
O << ", #"
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
+ << (char)ARM_AM::getAM5Op(MO2.getImm())
<< ImmOffs*4;
}
O << "]";
@@ -594,7 +594,7 @@
const MachineOperand &MO1 = MI->getOperand(Op);
assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
- O << "[pc, " << getRegisterName(MO1.getReg()) << "]";
+ O << "[pc, +" << getRegisterName(MO1.getReg()) << "]";
}
void
@@ -617,11 +617,10 @@
ARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op) {
// (3 - the number of trailing zeros) is the number of then / else.
unsigned Mask = MI->getOperand(Op).getImm();
- unsigned CondBit0 = Mask >> 4 & 1;
unsigned NumTZ = CountTrailingZeros_32(Mask);
assert(NumTZ <= 3 && "Invalid IT mask!");
for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
- bool T = ((Mask >> Pos) & 1) == CondBit0;
+ bool T = (Mask & (1 << Pos)) == 0;
if (T)
O << 't';
else
@@ -653,7 +652,7 @@
if (MO3.getReg())
O << ", " << getRegisterName(MO3.getReg());
else if (unsigned ImmOffs = MO2.getImm())
- O << ", #" << ImmOffs * Scale;
+ O << ", #+" << ImmOffs * Scale;
O << "]";
}
@@ -675,7 +674,7 @@
const MachineOperand &MO2 = MI->getOperand(Op+1);
O << "[" << getRegisterName(MO1.getReg());
if (unsigned ImmOffs = MO2.getImm())
- O << ", #" << ImmOffs*4;
+ O << ", #+" << ImmOffs*4;
O << "]";
}
@@ -711,7 +710,7 @@
unsigned OffImm = MO2.getImm();
if (OffImm) // Don't print +0.
- O << ", #" << OffImm;
+ O << ", #+" << OffImm;
O << "]";
}
@@ -727,7 +726,7 @@
if (OffImm < 0)
O << ", #-" << -OffImm;
else if (OffImm > 0)
- O << ", #" << OffImm;
+ O << ", #+" << OffImm;
O << "]";
}
@@ -743,7 +742,7 @@
if (OffImm < 0)
O << ", #-" << -OffImm * 4;
else if (OffImm > 0)
- O << ", #" << OffImm * 4;
+ O << ", #+" << OffImm * 4;
O << "]";
}
@@ -755,18 +754,7 @@
if (OffImm < 0)
O << "#-" << -OffImm;
else if (OffImm > 0)
- O << "#" << OffImm;
-}
-
-void ARMAsmPrinter::printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI,
- int OpNum) {
- const MachineOperand &MO1 = MI->getOperand(OpNum);
- int32_t OffImm = (int32_t)MO1.getImm() / 4;
- // Don't print +0.
- if (OffImm < 0)
- O << "#-" << -OffImm * 4;
- else if (OffImm > 0)
- O << "#" << OffImm * 4;
+ O << "#+" << OffImm;
}
void ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,
Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp Tue Mar 16 11:59:47 2010
@@ -28,165 +28,7 @@
#undef MachineInstr
#undef ARMAsmPrinter
-static unsigned NextReg(unsigned Reg) {
- switch (Reg) {
- case ARM::D0:
- return ARM::D1;
- case ARM::D1:
- return ARM::D2;
- case ARM::D2:
- return ARM::D3;
- case ARM::D3:
- return ARM::D4;
- case ARM::D4:
- return ARM::D5;
- case ARM::D5:
- return ARM::D6;
- case ARM::D6:
- return ARM::D7;
- case ARM::D7:
- return ARM::D8;
- case ARM::D8:
- return ARM::D9;
- case ARM::D9:
- return ARM::D10;
- case ARM::D10:
- return ARM::D11;
- case ARM::D11:
- return ARM::D12;
- case ARM::D12:
- return ARM::D13;
- case ARM::D13:
- return ARM::D14;
- case ARM::D14:
- return ARM::D15;
- case ARM::D15:
- return ARM::D16;
- case ARM::D16:
- return ARM::D17;
- case ARM::D17:
- return ARM::D18;
- case ARM::D18:
- return ARM::D19;
- case ARM::D19:
- return ARM::D20;
- case ARM::D20:
- return ARM::D21;
- case ARM::D21:
- return ARM::D22;
- case ARM::D22:
- return ARM::D23;
- case ARM::D23:
- return ARM::D24;
- case ARM::D24:
- return ARM::D25;
- case ARM::D25:
- return ARM::D26;
- case ARM::D26:
- return ARM::D27;
- case ARM::D27:
- return ARM::D28;
- case ARM::D28:
- return ARM::D29;
- case ARM::D29:
- return ARM::D30;
- case ARM::D30:
- return ARM::D31;
-
- default:
- assert(0 && "Unexpected register enum");
- }
-}
-
-void ARMInstPrinter::printInst(const MCInst *MI) {
- // Check for MOVs and print canonical forms, instead.
- if (MI->getOpcode() == ARM::MOVs) {
- const MCOperand &Dst = MI->getOperand(0);
- const MCOperand &MO1 = MI->getOperand(1);
- const MCOperand &MO2 = MI->getOperand(2);
- const MCOperand &MO3 = MI->getOperand(3);
-
- O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
- printSBitModifierOperand(MI, 6);
- printPredicateOperand(MI, 4);
-
- O << '\t' << getRegisterName(Dst.getReg())
- << ", " << getRegisterName(MO1.getReg());
-
- if (ARM_AM::getSORegShOp(MO3.getImm()) == ARM_AM::rrx)
- return;
-
- O << ", ";
-
- if (MO2.getReg()) {
- O << getRegisterName(MO2.getReg());
- assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
- } else {
- O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
- }
- return;
- }
-
- // A8.6.123 PUSH
- if ((MI->getOpcode() == ARM::STM || MI->getOpcode() == ARM::t2STM_UPD) &&
- MI->getOperand(0).getReg() == ARM::SP) {
- const unsigned IdxOffset = MI->getOpcode() == ARM::STM ? 0 : 1;
- const MCOperand &MO1 = MI->getOperand(IdxOffset + 1);
- if (ARM_AM::getAM4WBFlag(MO1.getImm()) &&
- ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::db) {
- O << '\t' << "push";
- printPredicateOperand(MI, IdxOffset + 2);
- O << '\t';
- printRegisterList(MI, IdxOffset + 4);
- return;
- }
- }
-
- // A8.6.122 POP
- if ((MI->getOpcode() == ARM::LDM || MI->getOpcode() == ARM::t2LDM_UPD) &&
- MI->getOperand(0).getReg() == ARM::SP) {
- const unsigned IdxOffset = MI->getOpcode() == ARM::LDM ? 0 : 1;
- const MCOperand &MO1 = MI->getOperand(IdxOffset + 1);
- if (ARM_AM::getAM4WBFlag(MO1.getImm()) &&
- ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::ia) {
- O << '\t' << "pop";
- printPredicateOperand(MI, IdxOffset + 2);
- O << '\t';
- printRegisterList(MI, IdxOffset + 4);
- return;
- }
- }
-
- // A8.6.355 VPUSH
- if ((MI->getOpcode() == ARM::VSTMS || MI->getOpcode() == ARM::VSTMD) &&
- MI->getOperand(0).getReg() == ARM::SP) {
- const MCOperand &MO1 = MI->getOperand(1);
- if (ARM_AM::getAM5WBFlag(MO1.getImm()) &&
- ARM_AM::getAM5SubMode(MO1.getImm()) == ARM_AM::db) {
- O << '\t' << "vpush";
- printPredicateOperand(MI, 2);
- O << '\t';
- printRegisterList(MI, 4);
- return;
- }
- }
-
- // A8.6.354 VPOP
- if ((MI->getOpcode() == ARM::VLDMS || MI->getOpcode() == ARM::VLDMD) &&
- MI->getOperand(0).getReg() == ARM::SP) {
- const MCOperand &MO1 = MI->getOperand(1);
- if (ARM_AM::getAM5WBFlag(MO1.getImm()) &&
- ARM_AM::getAM5SubMode(MO1.getImm()) == ARM_AM::ia) {
- O << '\t' << "vpop";
- printPredicateOperand(MI, 2);
- O << '\t';
- printRegisterList(MI, 4);
- return;
- }
- }
-
- printInstruction(MI);
- }
+void ARMInstPrinter::printInst(const MCInst *MI) { printInstruction(MI); }
void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
const char *Modifier) {
@@ -194,9 +36,6 @@
if (Op.isReg()) {
unsigned Reg = Op.getReg();
if (Modifier && strcmp(Modifier, "dregpair") == 0) {
- O << '{' << getRegisterName(Reg) << ", "
- << getRegisterName(NextReg(Reg)) << '}';
-#if 0
// FIXME: Breaks e.g. ARM/vmul.ll.
assert(0);
/*
@@ -205,7 +44,6 @@
O << '{'
<< getRegisterName(DRegLo) << ',' << getRegisterName(DRegHi)
<< '}';*/
-#endif
} else if (Modifier && strcmp(Modifier, "lane") == 0) {
assert(0);
/*
@@ -218,9 +56,7 @@
O << getRegisterName(Reg);
}
} else if (Op.isImm()) {
- bool isCallOp = Modifier && !strcmp(Modifier, "call");
- assert(isCallOp ||
- ((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"));
+ assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
O << '#' << Op.getImm();
} else {
assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
@@ -306,17 +142,17 @@
O << "[" << getRegisterName(MO1.getReg());
if (!MO2.getReg()) {
- if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
+ if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
O << ", #"
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
- << ARM_AM::getAM2Offset(MO3.getImm());
+ << (char)ARM_AM::getAM2Op(MO3.getImm())
+ << ARM_AM::getAM2Offset(MO3.getImm());
O << "]";
return;
}
O << ", "
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
- << getRegisterName(MO2.getReg());
+ << (char)ARM_AM::getAM2Op(MO3.getImm())
+ << getRegisterName(MO2.getReg());
if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
O << ", "
@@ -333,14 +169,11 @@
if (!MO1.getReg()) {
unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
assert(ImmOffs && "Malformed indexed load / store!");
- O << '#'
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
- << ImmOffs;
+ O << '#' << (char)ARM_AM::getAM2Op(MO2.getImm()) << ImmOffs;
return;
}
- O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
- << getRegisterName(MO1.getReg());
+ O << (char)ARM_AM::getAM2Op(MO2.getImm()) << getRegisterName(MO1.getReg());
if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
O << ", "
@@ -363,8 +196,8 @@
if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
O << ", #"
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
- << ImmOffs;
+ << (char)ARM_AM::getAM3Op(MO3.getImm())
+ << ImmOffs;
O << ']';
}
@@ -381,9 +214,9 @@
unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
assert(ImmOffs && "Malformed indexed load / store!");
- O << '#'
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
- << ImmOffs;
+ O << "#"
+ << (char)ARM_AM::getAM3Op(MO2.getImm())
+ << ImmOffs;
}
@@ -431,7 +264,7 @@
if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
O << ", #"
- << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
+ << (char)ARM_AM::getAM5Op(MO2.getImm())
<< ImmOffs*4;
}
O << "]";
@@ -470,56 +303,14 @@
void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum) {
O << "{";
- for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
- if (i != OpNum) O << ", ";
+ // Always skip the first operand, it's the optional (and implicit writeback).
+ for (unsigned i = OpNum+1, e = MI->getNumOperands(); i != e; ++i) {
+ if (i != OpNum+1) O << ", ";
O << getRegisterName(MI->getOperand(i).getReg());
}
O << "}";
}
-void ARMInstPrinter::printCPSOptionOperand(const MCInst *MI, unsigned OpNum) {
- const MCOperand &Op = MI->getOperand(OpNum);
- unsigned option = Op.getImm();
- unsigned mode = option & 31;
- bool changemode = option >> 5 & 1;
- unsigned AIF = option >> 6 & 7;
- unsigned imod = option >> 9 & 3;
- if (imod == 2)
- O << "ie";
- else if (imod == 3)
- O << "id";
- O << '\t';
- if (imod > 1) {
- if (AIF & 4) O << 'a';
- if (AIF & 2) O << 'i';
- if (AIF & 1) O << 'f';
- if (AIF > 0 && changemode) O << ", ";
- }
- if (changemode)
- O << '#' << mode;
-}
-
-void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum) {
- const MCOperand &Op = MI->getOperand(OpNum);
- unsigned Mask = Op.getImm();
- if (Mask) {
- O << '_';
- if (Mask & 8) O << 'f';
- if (Mask & 4) O << 's';
- if (Mask & 2) O << 'x';
- if (Mask & 1) O << 'c';
- }
-}
-
-void ARMInstPrinter::printNegZeroOperand(const MCInst *MI, unsigned OpNum){
- const MCOperand &Op = MI->getOperand(OpNum);
- O << '#';
- if (Op.getImm() < 0)
- O << '-' << (-Op.getImm() - 1);
- else
- O << Op.getImm();
-}
-
void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum) {
ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
if (CC != ARMCC::AL)
@@ -561,191 +352,3 @@
void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum) {
O << "#" << MI->getOperand(OpNum).getImm() * 4;
}
-
-void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum) {
- // (3 - the number of trailing zeros) is the number of then / else.
- unsigned Mask = MI->getOperand(OpNum).getImm();
- unsigned CondBit0 = Mask >> 4 & 1;
- unsigned NumTZ = CountTrailingZeros_32(Mask);
- assert(NumTZ <= 3 && "Invalid IT mask!");
- for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
- bool T = ((Mask >> Pos) & 1) == CondBit0;
- if (T)
- O << 't';
- else
- O << 'e';
- }
-}
-
-void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op)
-{
- const MCOperand &MO1 = MI->getOperand(Op);
- const MCOperand &MO2 = MI->getOperand(Op+1);
- O << "[" << getRegisterName(MO1.getReg());
- O << ", " << getRegisterName(MO2.getReg()) << "]";
-}
-
-void ARMInstPrinter::printThumbAddrModeRI5Operand(const MCInst *MI, unsigned Op,
- unsigned Scale) {
- const MCOperand &MO1 = MI->getOperand(Op);
- const MCOperand &MO2 = MI->getOperand(Op+1);
- const MCOperand &MO3 = MI->getOperand(Op+2);
-
- if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
- printOperand(MI, Op);
- return;
- }
-
- O << "[" << getRegisterName(MO1.getReg());
- if (MO3.getReg())
- O << ", " << getRegisterName(MO3.getReg());
- else if (unsigned ImmOffs = MO2.getImm())
- O << ", #" << ImmOffs * Scale;
- O << "]";
-}
-
-void ARMInstPrinter::printThumbAddrModeS1Operand(const MCInst *MI, unsigned Op)
-{
- printThumbAddrModeRI5Operand(MI, Op, 1);
-}
-
-void ARMInstPrinter::printThumbAddrModeS2Operand(const MCInst *MI, unsigned Op)
-{
- printThumbAddrModeRI5Operand(MI, Op, 2);
-}
-
-void ARMInstPrinter::printThumbAddrModeS4Operand(const MCInst *MI, unsigned Op)
-{
- printThumbAddrModeRI5Operand(MI, Op, 4);
-}
-
-void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI,unsigned Op) {
- const MCOperand &MO1 = MI->getOperand(Op);
- const MCOperand &MO2 = MI->getOperand(Op+1);
- O << "[" << getRegisterName(MO1.getReg());
- if (unsigned ImmOffs = MO2.getImm())
- O << ", #" << ImmOffs*4;
- O << "]";
-}
-
-void ARMInstPrinter::printTBAddrMode(const MCInst *MI, unsigned OpNum) {
- O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
- if (MI->getOpcode() == ARM::t2TBH)
- O << ", lsl #1";
- O << ']';
-}
-
-// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
-// register with shift forms.
-// REG 0 0 - e.g. R5
-// REG IMM, SH_OPC - e.g. R5, LSL #3
-void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum) {
- const MCOperand &MO1 = MI->getOperand(OpNum);
- const MCOperand &MO2 = MI->getOperand(OpNum+1);
-
- unsigned Reg = MO1.getReg();
- O << getRegisterName(Reg);
-
- // Print the shift opc.
- O << ", "
- << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()))
- << " ";
-
- assert(MO2.isImm() && "Not a valid t2_so_reg value!");
- O << "#" << ARM_AM::getSORegOffset(MO2.getImm());
-}
-
-void ARMInstPrinter::printT2AddrModeImm12Operand(const MCInst *MI,
- unsigned OpNum) {
- const MCOperand &MO1 = MI->getOperand(OpNum);
- const MCOperand &MO2 = MI->getOperand(OpNum+1);
-
- O << "[" << getRegisterName(MO1.getReg());
-
- unsigned OffImm = MO2.getImm();
- if (OffImm) // Don't print +0.
- O << ", #" << OffImm;
- O << "]";
-}
-
-void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
- unsigned OpNum) {
- const MCOperand &MO1 = MI->getOperand(OpNum);
- const MCOperand &MO2 = MI->getOperand(OpNum+1);
-
- O << "[" << getRegisterName(MO1.getReg());
-
- int32_t OffImm = (int32_t)MO2.getImm();
- // Don't print +0.
- if (OffImm < 0)
- O << ", #-" << -OffImm;
- else if (OffImm > 0)
- O << ", #" << OffImm;
- O << "]";
-}
-
-void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
- unsigned OpNum) {
- const MCOperand &MO1 = MI->getOperand(OpNum);
- const MCOperand &MO2 = MI->getOperand(OpNum+1);
-
- O << "[" << getRegisterName(MO1.getReg());
-
- int32_t OffImm = (int32_t)MO2.getImm() / 4;
- // Don't print +0.
- if (OffImm < 0)
- O << ", #-" << -OffImm * 4;
- else if (OffImm > 0)
- O << ", #" << OffImm * 4;
- O << "]";
-}
-
-void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI,
- unsigned OpNum) {
- const MCOperand &MO1 = MI->getOperand(OpNum);
- int32_t OffImm = (int32_t)MO1.getImm();
- // Don't print +0.
- if (OffImm < 0)
- O << "#-" << -OffImm;
- else if (OffImm > 0)
- O << "#" << OffImm;
-}
-
-void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI,
- unsigned OpNum) {
- const MCOperand &MO1 = MI->getOperand(OpNum);
- int32_t OffImm = (int32_t)MO1.getImm() / 4;
- // Don't print +0.
- if (OffImm < 0)
- O << "#-" << -OffImm * 4;
- else if (OffImm > 0)
- O << "#" << OffImm * 4;
-}
-
-void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
- unsigned OpNum) {
- const MCOperand &MO1 = MI->getOperand(OpNum);
- const MCOperand &MO2 = MI->getOperand(OpNum+1);
- const MCOperand &MO3 = MI->getOperand(OpNum+2);
-
- O << "[" << getRegisterName(MO1.getReg());
-
- assert(MO2.getReg() && "Invalid so_reg load / store address!");
- O << ", " << getRegisterName(MO2.getReg());
-
- unsigned ShAmt = MO3.getImm();
- if (ShAmt) {
- assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
- O << ", lsl #" << ShAmt;
- }
- O << "]";
-}
-
-void ARMInstPrinter::printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum) {
- O << '#' << MI->getOperand(OpNum).getImm();
-}
-
-void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum) {
- O << '#' << MI->getOperand(OpNum).getImm();
-}
-
Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h (original)
+++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h Tue Mar 16 11:59:47 2010
@@ -54,26 +54,26 @@
void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum);
void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum);
- void printThumbITMask(const MCInst *MI, unsigned OpNum);
- void printThumbAddrModeRROperand(const MCInst *MI, unsigned OpNum);
+ void printThumbITMask(const MCInst *MI, unsigned OpNum) {}
+ void printThumbAddrModeRROperand(const MCInst *MI, unsigned OpNum) {}
void printThumbAddrModeRI5Operand(const MCInst *MI, unsigned OpNum,
- unsigned Scale);
- void printThumbAddrModeS1Operand(const MCInst *MI, unsigned OpNum);
- void printThumbAddrModeS2Operand(const MCInst *MI, unsigned OpNum);
- void printThumbAddrModeS4Operand(const MCInst *MI, unsigned OpNum);
- void printThumbAddrModeSPOperand(const MCInst *MI, unsigned OpNum);
+ unsigned Scale) {}
+ void printThumbAddrModeS1Operand(const MCInst *MI, unsigned OpNum) {}
+ void printThumbAddrModeS2Operand(const MCInst *MI, unsigned OpNum) {}
+ void printThumbAddrModeS4Operand(const MCInst *MI, unsigned OpNum) {}
+ void printThumbAddrModeSPOperand(const MCInst *MI, unsigned OpNum) {}
- void printT2SOOperand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeImm12Operand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeImm8OffsetOperand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum);
+ void printT2SOOperand(const MCInst *MI, unsigned OpNum) {}
+ void printT2AddrModeImm12Operand(const MCInst *MI, unsigned OpNum) {}
+ void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum) {}
+ void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum) {}
+ void printT2AddrModeImm8OffsetOperand(const MCInst *MI, unsigned OpNum) {}
+ void printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, unsigned OpNum) {}
+ void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum) {}
- void printCPSOptionOperand(const MCInst *MI, unsigned OpNum);
- void printMSRMaskOperand(const MCInst *MI, unsigned OpNum);
- void printNegZeroOperand(const MCInst *MI, unsigned OpNum);
+ void printCPSOptionOperand(const MCInst *MI, unsigned OpNum) {}
+ void printMSRMaskOperand(const MCInst *MI, unsigned OpNum) {}
+ void printNegZeroOperand(const MCInst *MI, unsigned OpNum) {}
void printPredicateOperand(const MCInst *MI, unsigned OpNum);
void printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum);
void printSBitModifierOperand(const MCInst *MI, unsigned OpNum);
@@ -82,10 +82,10 @@
const char *Modifier);
void printJTBlockOperand(const MCInst *MI, unsigned OpNum) {}
void printJT2BlockOperand(const MCInst *MI, unsigned OpNum) {}
- void printTBAddrMode(const MCInst *MI, unsigned OpNum);
+ void printTBAddrMode(const MCInst *MI, unsigned OpNum) {}
void printNoHashImmediate(const MCInst *MI, unsigned OpNum);
- void printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum);
- void printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum);
+ void printVFPf32ImmOperand(const MCInst *MI, int OpNum) {}
+ void printVFPf64ImmOperand(const MCInst *MI, int OpNum) {}
void printHex8ImmOperand(const MCInst *MI, int OpNum) {}
void printHex16ImmOperand(const MCInst *MI, int OpNum) {}
void printHex32ImmOperand(const MCInst *MI, int OpNum) {}
Modified: llvm/trunk/lib/Target/ARM/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Makefile?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Makefile (original)
+++ llvm/trunk/lib/Target/ARM/Makefile Tue Mar 16 11:59:47 2010
@@ -16,9 +16,8 @@
ARMGenRegisterInfo.inc ARMGenInstrNames.inc \
ARMGenInstrInfo.inc ARMGenAsmWriter.inc \
ARMGenDAGISel.inc ARMGenSubtarget.inc \
- ARMGenCodeEmitter.inc ARMGenCallingConv.inc \
- ARMGenDisassemblerTables.inc
+ ARMGenCodeEmitter.inc ARMGenCallingConv.inc
-DIRS = AsmPrinter AsmParser Disassembler TargetInfo
+DIRS = AsmPrinter AsmParser TargetInfo
include $(LEVEL)/Makefile.common
Modified: llvm/trunk/lib/Target/ARM/Thumb2ITBlockPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb2ITBlockPass.cpp?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Thumb2ITBlockPass.cpp (original)
+++ llvm/trunk/lib/Target/ARM/Thumb2ITBlockPass.cpp Tue Mar 16 11:59:47 2010
@@ -78,16 +78,14 @@
DebugLoc ndl = NMI->getDebugLoc();
unsigned NPredReg = 0;
ARMCC::CondCodes NCC = getPredicate(NMI, NPredReg);
- if (NCC == CC || NCC == OCC)
- Mask |= (NCC & 1) << Pos;
- else
+ if (NCC == OCC) {
+ Mask |= (1 << Pos);
+ } else if (NCC != CC)
break;
--Pos;
++MBBI;
}
Mask |= (1 << Pos);
- // Tag along (firstcond[0] << 4) with the mask.
- Mask |= (CC & 1) << 4;
MIB.addImm(Mask);
Modified = true;
++NumITs;
Modified: llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll Tue Mar 16 11:59:47 2010
@@ -4,8 +4,8 @@
define arm_aapcscc void @g() {
entry:
-;CHECK: [sp, #8]
-;CHECK: [sp, #12]
+;CHECK: [sp, #+8]
+;CHECK: [sp, #+12]
;CHECK: [sp]
tail call arm_aapcscc void (i8*, ...)* @f(i8* getelementptr ([1 x i8]* @.str, i32 0, i32 0), i32 1, double 2.000000e+00, i32 3, double 4.000000e+00)
ret void
Modified: llvm/trunk/test/CodeGen/ARM/2009-10-30.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-10-30.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/2009-10-30.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/2009-10-30.ll Tue Mar 16 11:59:47 2010
@@ -6,7 +6,7 @@
entry:
;CHECK: sub sp, sp, #4
;CHECK: add r{{[0-9]+}}, sp, #8
-;CHECK: str r{{[0-9]+}}, [sp], #4
+;CHECK: str r{{[0-9]+}}, [sp], #+4
;CHECK: bx lr
%ap = alloca i8*, align 4
%ap1 = bitcast i8** %ap to i8*
Modified: llvm/trunk/test/CodeGen/ARM/arm-negative-stride.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/arm-negative-stride.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/arm-negative-stride.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/arm-negative-stride.ll Tue Mar 16 11:59:47 2010
@@ -5,7 +5,7 @@
define void @test(i32* %P, i32 %A, i32 %i) nounwind {
entry:
-; CHECK: str r1, [{{r.*}}, {{r.*}}, lsl #2]
+; CHECK: str r1, [{{r.*}}, +{{r.*}}, lsl #2]
icmp eq i32 %i, 0 ; <i1>:0 [#uses=1]
br i1 %0, label %return, label %bb
Modified: llvm/trunk/test/CodeGen/ARM/globals.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/globals.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/globals.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/globals.ll Tue Mar 16 11:59:47 2010
@@ -41,7 +41,7 @@
; DarwinPIC: _test1:
; DarwinPIC: ldr r0, LCPI1_0
; DarwinPIC: LPC1_0:
-; DarwinPIC: ldr r0, [pc, r0]
+; DarwinPIC: ldr r0, [pc, +r0]
; DarwinPIC: ldr r0, [r0]
; DarwinPIC: bx lr
@@ -63,7 +63,7 @@
; LinuxPIC: .LPC1_0:
; LinuxPIC: add r0, pc, r0
-; LinuxPIC: ldr r0, [r1, r0]
+; LinuxPIC: ldr r0, [r1, +r0]
; LinuxPIC: ldr r0, [r0]
; LinuxPIC: bx lr
Modified: llvm/trunk/test/CodeGen/ARM/ldrd.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ldrd.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/ldrd.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/ldrd.ll Tue Mar 16 11:59:47 2010
@@ -10,10 +10,10 @@
;V6: ldrd r2, [r2]
;V5: ldr r3, [r2]
-;V5: ldr r2, [r2, #4]
+;V5: ldr r2, [r2, #+4]
;EABI: ldr r3, [r2]
-;EABI: ldr r2, [r2, #4]
+;EABI: ldr r2, [r2, #+4]
%0 = load i64** @b, align 4
%1 = load i64* %0, align 4
Modified: llvm/trunk/test/CodeGen/ARM/str_pre-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/str_pre-2.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/str_pre-2.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/str_pre-2.ll Tue Mar 16 11:59:47 2010
@@ -1,5 +1,5 @@
; RUN: llc < %s -mtriple=arm-linux-gnu | grep {str.*\\!}
-; RUN: llc < %s -mtriple=arm-linux-gnu | grep {ldr.*\\\[.*\], #4}
+; RUN: llc < %s -mtriple=arm-linux-gnu | grep {ldr.*\\\[.*\], #+4}
@b = external global i64*
Modified: llvm/trunk/test/CodeGen/ARM/tls2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/tls2.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/tls2.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/tls2.ll Tue Mar 16 11:59:47 2010
@@ -7,7 +7,7 @@
define i32 @f() {
; CHECK-NONPIC: f:
-; CHECK-NONPIC: ldr {{r.}}, [pc, {{r.}}]
+; CHECK-NONPIC: ldr {{r.}}, [pc, +{{r.}}]
; CHECK-NONPIC: i(gottpoff)
; CHECK-PIC: f:
; CHECK-PIC: __tls_get_addr
@@ -18,7 +18,7 @@
define i32* @g() {
; CHECK-NONPIC: g:
-; CHECK-NONPIC: ldr {{r.}}, [pc, {{r.}}]
+; CHECK-NONPIC: ldr {{r.}}, [pc, +{{r.}}]
; CHECK-NONPIC: i(gottpoff)
; CHECK-PIC: g:
; CHECK-PIC: __tls_get_addr
Modified: llvm/trunk/test/CodeGen/Thumb2/ldr-str-imm12.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/ldr-str-imm12.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/ldr-str-imm12.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/ldr-str-imm12.ll Tue Mar 16 11:59:47 2010
@@ -22,7 +22,7 @@
define arm_apcscc %union.rec* @Manifest(%union.rec* %x, %union.rec* %env, %struct.STYLE* %style, %union.rec** %bthr, %union.rec** %fthr, %union.rec** %target, %union.rec** %crs, i32 %ok, i32 %need_expand, %union.rec** %enclose, i32 %fcr) nounwind {
entry:
-; CHECK: ldr.w r9, [r7, #28]
+; CHECK: ldr.w r9, [r7, #+28]
%xgaps.i = alloca [32 x %union.rec*], align 4 ; <[32 x %union.rec*]*> [#uses=0]
%ycomp.i = alloca [32 x %union.rec*], align 4 ; <[32 x %union.rec*]*> [#uses=0]
br i1 false, label %bb, label %bb20
@@ -50,9 +50,9 @@
bb420: ; preds = %bb20, %bb20
; CHECK: bb420
; CHECK: str r{{[0-7]}}, [sp]
-; CHECK: str r{{[0-7]}}, [sp, #4]
-; CHECK: str r{{[0-7]}}, [sp, #8]
-; CHECK: str{{(.w)?}} r{{[0-9]+}}, [sp, #24]
+; CHECK: str r{{[0-7]}}, [sp, #+4]
+; CHECK: str r{{[0-7]}}, [sp, #+8]
+; CHECK: str{{(.w)?}} r{{[0-9]+}}, [sp, #+24]
store %union.rec* null, %union.rec** @zz_hold, align 4
store %union.rec* null, %union.rec** @zz_res, align 4
store %union.rec* %x, %union.rec** @zz_hold, align 4
Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-ldr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-ldr.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-ldr.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-ldr.ll Tue Mar 16 11:59:47 2010
@@ -11,7 +11,7 @@
define i32 @f2(i32* %v) {
entry:
; CHECK: f2:
-; CHECK: ldr.w r0, [r0, #4092]
+; CHECK: ldr.w r0, [r0, #+4092]
%tmp2 = getelementptr i32* %v, i32 1023
%tmp = load i32* %tmp2
ret i32 %tmp
Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-ldrh.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-ldrh.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-ldrh.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-ldrh.ll Tue Mar 16 11:59:47 2010
@@ -11,7 +11,7 @@
define i16 @f2(i16* %v) {
entry:
; CHECK: f2:
-; CHECK: ldrh.w r0, [r0, #2046]
+; CHECK: ldrh.w r0, [r0, #+2046]
%tmp2 = getelementptr i16* %v, i16 1023
%tmp = load i16* %tmp2
ret i16 %tmp
Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-str.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-str.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-str.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-str.ll Tue Mar 16 11:59:47 2010
@@ -9,7 +9,7 @@
define i32 @f2(i32 %a, i32* %v) {
; CHECK: f2:
-; CHECK: str.w r0, [r1, #4092]
+; CHECK: str.w r0, [r1, #+4092]
%tmp2 = getelementptr i32* %v, i32 1023
store i32 %a, i32* %tmp2
ret i32 %a
Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-str_pre.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-str_pre.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-str_pre.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-str_pre.ll Tue Mar 16 11:59:47 2010
@@ -2,7 +2,7 @@
define void @test1(i32* %X, i32* %A, i32** %dest) {
; CHECK: test1
-; CHECK: str r1, [r0, #16]!
+; CHECK: str r1, [r0, #+16]!
%B = load i32* %A ; <i32> [#uses=1]
%Y = getelementptr i32* %X, i32 4 ; <i32*> [#uses=2]
store i32 %B, i32* %Y
@@ -12,7 +12,7 @@
define i16* @test2(i16* %X, i32* %A) {
; CHECK: test2
-; CHECK: strh r1, [r0, #8]!
+; CHECK: strh r1, [r0, #+8]!
%B = load i32* %A ; <i32> [#uses=1]
%Y = getelementptr i16* %X, i32 4 ; <i16*> [#uses=2]
%tmp = trunc i32 %B to i16 ; <i16> [#uses=1]
Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-strb.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-strb.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-strb.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-strb.ll Tue Mar 16 11:59:47 2010
@@ -9,7 +9,7 @@
define i8 @f2(i8 %a, i8* %v) {
; CHECK: f2:
-; CHECK: strb.w r0, [r1, #4092]
+; CHECK: strb.w r0, [r1, #+4092]
%tmp2 = getelementptr i8* %v, i32 4092
store i8 %a, i8* %tmp2
ret i8 %a
Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-strh.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-strh.ll?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-strh.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-strh.ll Tue Mar 16 11:59:47 2010
@@ -9,7 +9,7 @@
define i16 @f2(i16 %a, i16* %v) {
; CHECK: f2:
-; CHECK: strh.w r0, [r1, #4092]
+; CHECK: strh.w r0, [r1, #+4092]
%tmp2 = getelementptr i16* %v, i32 2046
store i16 %a, i16* %tmp2
ret i16 %a
Modified: llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp Tue Mar 16 11:59:47 2010
@@ -12,8 +12,6 @@
#include "Record.h"
#include "X86DisassemblerTables.h"
#include "X86RecognizableInstr.h"
-#include "RISCDisassemblerEmitter.h"
-
using namespace llvm;
using namespace llvm::X86Disassembler;
@@ -126,12 +124,6 @@
return;
}
- // Fixed-instruction-length targets use a common disassembler.
- if (Target.getName() == "ARM") {
- RISCDisassemblerEmitter(Records).run(OS);
- return;
- }
-
throw TGError(Target.getTargetRecord()->getLoc(),
"Unable to generate disassembler for this target");
}
Removed: llvm/trunk/utils/TableGen/RISCDisassemblerEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RISCDisassemblerEmitter.cpp?rev=98639&view=auto
==============================================================================
--- llvm/trunk/utils/TableGen/RISCDisassemblerEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/RISCDisassemblerEmitter.cpp (removed)
@@ -1,1743 +0,0 @@
-//===- RISCDisassemblerEmitter.cpp - Disassembler Generator ---------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// FIXME: document
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "risc-disassembler-emitter"
-
-#include "RISCDisassemblerEmitter.h"
-#include "CodeGenTarget.h"
-#include "Record.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include <iomanip>
-#include <vector>
-#include <cstdio>
-#include <map>
-#include <string>
-#include <sstream>
-
-using namespace llvm;
-
-////////////////////////////////////
-// Utility classes / structures //
-////////////////////////////////////
-
-// LLVM coding style
-#define INDENT_LEVEL 2
-
-/// Indenter - A little helper class to keep track of the indentation depth,
-/// while the instance object is being passed around.
-class Indenter {
-public:
- Indenter() : depth(0) {}
-
- void push() {
- depth += INDENT_LEVEL;
- }
-
- void pop() {
- if (depth >= INDENT_LEVEL)
- depth -= INDENT_LEVEL;
- }
-
- // Conversion operator.
- operator int () {
- return depth;
- }
-private:
- uint8_t depth;
-};
-
-/////////////////////////
-// Utility functions //
-/////////////////////////
-
-static uint8_t byteFromBitsInit(BitsInit &init) {
- int width = init.getNumBits();
-
- assert(width <= 8 && "Field is too large for uint8_t!");
-
- int index;
- uint8_t mask = 0x01;
-
- uint8_t ret = 0;
-
- for (index = 0; index < width; index++) {
- if (static_cast<BitInit*>(init.getBit(index))->getValue())
- ret |= mask;
-
- mask <<= 1;
- }
-
- return ret;
-}
-
-static uint8_t getByteField(const Record &def, const char *str) {
- BitsInit *bits = def.getValueAsBitsInit(str);
- return byteFromBitsInit(*bits);
-}
-
-static BitsInit &getBitsField(const Record &def, const char *str) {
- BitsInit *bits = def.getValueAsBitsInit(str);
- return *bits;
-}
-
-/// sameStringExceptEndingChar - Return true if the two strings differ only in
-/// the ending char. ("VST4q8a", "VST4q8b", 'a', 'b') as input returns true.
-static
-bool sameStringExceptEndingChar(const std::string &LHS, const std::string &RHS,
- char lhc, char rhc) {
-
- if (LHS.length() > 1 && RHS.length() > 1 && LHS.length() == RHS.length()) {
- unsigned length = LHS.length();
- return LHS.substr(0, length - 1) == RHS.substr(0, length - 1)
- && LHS[length - 1] == lhc && RHS[length - 1] == rhc;
- }
-
- return false;
-}
-
-/// thumbInstruction - Determine whether we have a Thumb instruction.
-/// See also ARMInstrFormats.td.
-static bool thumbInstruction(uint8_t Form) {
- return Form == 23;
-}
-
-// The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
-// for a bit value.
-//
-// BIT_UNFILTERED is used as the init value for a filter position. It is used
-// only for filter processings.
-typedef enum {
- BIT_TRUE, // '1'
- BIT_FALSE, // '0'
- BIT_UNSET, // '?'
- BIT_UNFILTERED // unfiltered
-} bit_value_t;
-
-static bit_value_t bitFromBits(BitsInit &bits, unsigned index) {
- if (BitInit *bit = dynamic_cast<BitInit*>(bits.getBit(index)))
- return bit->getValue() ? BIT_TRUE : BIT_FALSE;
-
- // The bit is uninitialized.
- return BIT_UNSET;
-}
-
-static void dumpBits(raw_ostream &o, BitsInit &bits) {
- unsigned index;
-
- for (index = bits.getNumBits(); index > 0; index--) {
- switch (bitFromBits(bits, index - 1)) {
- case BIT_TRUE:
- o << "1";
- break;
- case BIT_FALSE:
- o << "0";
- break;
- case BIT_UNSET:
- o << "_";
- break;
- default:
- assert(0 && "unexpected return value from bitFromBits");
- }
- }
-}
-
-/////////////
-// Enums //
-/////////////
-
-#define ARM_FORMATS \
- ENTRY(ARM_FORMAT_PSEUDO, 0) \
- ENTRY(ARM_FORMAT_MULFRM, 1) \
- ENTRY(ARM_FORMAT_BRFRM, 2) \
- ENTRY(ARM_FORMAT_BRMISCFRM, 3) \
- ENTRY(ARM_FORMAT_DPFRM, 4) \
- ENTRY(ARM_FORMAT_DPSOREGFRM, 5) \
- ENTRY(ARM_FORMAT_LDFRM, 6) \
- ENTRY(ARM_FORMAT_STFRM, 7) \
- ENTRY(ARM_FORMAT_LDMISCFRM, 8) \
- ENTRY(ARM_FORMAT_STMISCFRM, 9) \
- ENTRY(ARM_FORMAT_LDSTMULFRM, 10) \
- ENTRY(ARM_FORMAT_ARITHMISCFRM, 11) \
- ENTRY(ARM_FORMAT_EXTFRM, 12) \
- ENTRY(ARM_FORMAT_VFPUNARYFRM, 13) \
- ENTRY(ARM_FORMAT_VFPBINARYFRM, 14) \
- ENTRY(ARM_FORMAT_VFPCONV1FRM, 15) \
- ENTRY(ARM_FORMAT_VFPCONV2FRM, 16) \
- ENTRY(ARM_FORMAT_VFPCONV3FRM, 17) \
- ENTRY(ARM_FORMAT_VFPCONV4FRM, 18) \
- ENTRY(ARM_FORMAT_VFPCONV5FRM, 19) \
- ENTRY(ARM_FORMAT_VFPLDSTFRM, 20) \
- ENTRY(ARM_FORMAT_VFPLDSTMULFRM, 21) \
- ENTRY(ARM_FORMAT_VFPMISCFRM, 22) \
- ENTRY(ARM_FORMAT_THUMBFRM, 23) \
- ENTRY(ARM_FORMAT_NEONFRM, 24) \
- ENTRY(ARM_FORMAT_NEONGETLNFRM, 25) \
- ENTRY(ARM_FORMAT_NEONSETLNFRM, 26) \
- ENTRY(ARM_FORMAT_NEONDUPFRM, 27) \
- ENTRY(ARM_FORMAT_LDSTEXFRM, 28) \
- ENTRY(ARM_FORMAT_MISCFRM, 29) \
- ENTRY(ARM_FORMAT_THUMBMISCFRM, 30)
-
-// ARM instruction format specifies the encoding used by the instruction.
-#define ENTRY(n, v) n = v,
-typedef enum {
- ARM_FORMATS
- ARM_FORMAT_NA
-} ARMFormat;
-#undef ENTRY
-
-// Converts enum to const char*.
-static const char *stringForARMFormat(ARMFormat form) {
-#define ENTRY(n, v) case n: return #n;
- switch(form) {
- ARM_FORMATS
- case ARM_FORMAT_NA:
- default:
- return "";
- }
-#undef ENTRY
-}
-
-#define NS_FORMATS \
- ENTRY(NS_FORMAT_NONE, 0) \
- ENTRY(NS_FORMAT_VLDSTLane, 1) \
- ENTRY(NS_FORMAT_VLDSTLaneDbl, 2) \
- ENTRY(NS_FORMAT_VLDSTRQ, 3) \
- ENTRY(NS_FORMAT_NVdImm, 4) \
- ENTRY(NS_FORMAT_NVdVmImm, 5) \
- ENTRY(NS_FORMAT_NVdVmImmVCVT, 6) \
- ENTRY(NS_FORMAT_NVdVmImmVDupLane, 7) \
- ENTRY(NS_FORMAT_NVdVmImmVSHLL, 8) \
- ENTRY(NS_FORMAT_NVectorShuffle, 9) \
- ENTRY(NS_FORMAT_NVectorShift, 10) \
- ENTRY(NS_FORMAT_NVectorShift2, 11) \
- ENTRY(NS_FORMAT_NVdVnVmImm, 12) \
- ENTRY(NS_FORMAT_NVdVnVmImmVectorShift, 13) \
- ENTRY(NS_FORMAT_NVdVnVmImmVectorExtract, 14) \
- ENTRY(NS_FORMAT_NVdVnVmImmMulScalar, 15) \
- ENTRY(NS_FORMAT_VTBL, 16)
-
-// NEON instruction sub-format further classify the NEONFrm instruction.
-#define ENTRY(n, v) n = v,
-typedef enum {
- NS_FORMATS
- NS_FORMAT_NA
-} NSFormat;
-#undef ENTRY
-
-// Converts enum to const char*.
-static const char *stringForNSFormat(NSFormat form) {
-#define ENTRY(n, v) case n: return #n;
- switch(form) {
- NS_FORMATS
- case NS_FORMAT_NA:
- default:
- return "";
- }
-#undef ENTRY
-}
-
-// Enums for the available target names.
-typedef enum {
- TARGET_ARM = 0,
- TARGET_THUMB
-} TARGET_NAME_t;
-
-class AbstractFilterChooser {
-public:
- static TARGET_NAME_t TargetName;
- static void setTargetName(TARGET_NAME_t tn) { TargetName = tn; }
- virtual ~AbstractFilterChooser() {}
- virtual void emitTop(raw_ostream &o, Indenter &i) = 0;
- virtual void emitBot(raw_ostream &o, Indenter &i) = 0;
-};
-
-// Define the symbol here.
-TARGET_NAME_t AbstractFilterChooser::TargetName;
-
-template <unsigned tBitWidth>
-class FilterChooser : public AbstractFilterChooser {
-protected:
- // Representation of the instruction to work on.
- typedef bit_value_t insn_t[tBitWidth];
-
- class Filter {
- protected:
- FilterChooser *Owner; // pointer without ownership
- unsigned StartBit; // the starting bit position
- unsigned NumBits; // number of bits to filter
- bool Mixed; // a mixed region contains both set and unset bits
-
- // Map of well-known segment value to the set of uid's with that value.
- std::map<uint64_t, std::vector<unsigned> > FilteredInstructions;
-
- // Set of uid's with non-constant segment values.
- std::vector<unsigned> VariableInstructions;
-
- // Map of well-known segment value to its delegate.
- std::map<unsigned, FilterChooser> FilterChooserMap;
-
- // Number of instructions which fall under FilteredInstructions category.
- unsigned NumFiltered;
-
- // Keeps track of the last opcode in the filtered bucket.
- unsigned LastOpcFiltered;
-
- // Number of instructions which fall under VariableInstructions category.
- unsigned NumVariable;
-
- public:
- unsigned getNumFiltered() { return NumFiltered; }
- unsigned getNumVariable() { return NumVariable; }
- unsigned getSingletonOpc() {
- assert(NumFiltered == 1);
- return LastOpcFiltered;
- }
- FilterChooser &getVariableFC() {
- assert(NumFiltered == 1);
- assert(FilterChooserMap.size() == 1);
- return FilterChooserMap.find(-1)->second;
- }
-
- Filter(const Filter &f) :
- Owner(f.Owner),
- StartBit(f.StartBit),
- NumBits(f.NumBits),
- Mixed(f.Mixed),
- FilteredInstructions(f.FilteredInstructions),
- VariableInstructions(f.VariableInstructions),
- FilterChooserMap(f.FilterChooserMap),
- NumFiltered(f.NumFiltered),
- LastOpcFiltered(f.LastOpcFiltered),
- NumVariable(f.NumVariable) { }
-
- Filter(FilterChooser &owner, unsigned startBit, unsigned numBits,
- bool mixed) :
- Owner(&owner),
- StartBit(startBit),
- NumBits(numBits),
- Mixed(mixed)
- {
- assert(StartBit + NumBits - 1 < tBitWidth);
-
- NumFiltered = 0;
- LastOpcFiltered = 0;
- NumVariable = 0;
-
- for (unsigned i = 0, e = Owner->Opcodes.size(); i != e; ++i) {
- insn_t Insn;
-
- // Populates the insn given the uid.
- Owner->insnWithID(Insn, Owner->Opcodes[i]);
-
- uint64_t Field;
- // Scans the segment for possibly well-specified encoding bits.
- bool ok = Owner->fieldFromInsn(Field, Insn, StartBit, NumBits);
-
- if (ok) {
- // The encoding bits are well-known. Lets add the uid of the
- // instruction into the bucket keyed off the constant field value.
- LastOpcFiltered = Owner->Opcodes[i];
- FilteredInstructions[Field].push_back(LastOpcFiltered);
- ++NumFiltered;
- } else {
- // Some of the encoding bit(s) are unspecfied. This contributes to
- // one additional member of "Variable" instructions.
- VariableInstructions.push_back(Owner->Opcodes[i]);
- ++NumVariable;
- }
- }
-
- assert((FilteredInstructions.size() + VariableInstructions.size() > 0)
- && "Filter returns no instruction categories");
- }
-
- // Divides the decoding task into sub tasks and delegates them to the
- // inferior FilterChooser's.
- //
- // A special case arises when there's only one entry in the filtered
- // instructions. In order to unambiguously decode the singleton, we need to
- // match the remaining undecoded encoding bits against the singleton.
- void recurse() {
- std::map<uint64_t, std::vector<unsigned> >::const_iterator mapIterator;
-
- bit_value_t BitValueArray[tBitWidth];
- // Starts by inheriting our parent filter chooser's filter bit values.
- memcpy(BitValueArray, Owner->FilterBitValues, sizeof(BitValueArray));
-
- unsigned bitIndex;
-
- if (VariableInstructions.size()) {
- // Conservatively marks each segment position as BIT_UNSET.
- for (bitIndex = 0; bitIndex < NumBits; bitIndex++)
- BitValueArray[StartBit + bitIndex] = BIT_UNSET;
-
- // Delegates to an inferior filter chooser for futher processing on this
- // group of instructions whose segment values are variable.
- FilterChooserMap.insert(std::pair<unsigned, FilterChooser>(
- (unsigned)-1,
- FilterChooser(Owner->AllInstructions,
- VariableInstructions,
- BitValueArray,
- *Owner)
- ));
- }
-
- // No need to recurse for a singleton filtered instruction.
- // See also Filter::emit().
- if (getNumFiltered() == 1) {
- //Owner->SingletonExists(LastOpcFiltered);
- assert(FilterChooserMap.size() == 1);
- return;
- }
-
- // Otherwise, create sub choosers.
- for (mapIterator = FilteredInstructions.begin();
- mapIterator != FilteredInstructions.end();
- mapIterator++) {
-
- // Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
- for (bitIndex = 0; bitIndex < NumBits; bitIndex++) {
- if (mapIterator->first & (1 << bitIndex))
- BitValueArray[StartBit + bitIndex] = BIT_TRUE;
- else
- BitValueArray[StartBit + bitIndex] = BIT_FALSE;
- }
-
- // Delegates to an inferior filter chooser for futher processing on this
- // category of instructions.
- FilterChooserMap.insert(std::pair<unsigned, FilterChooser>(
- mapIterator->first,
- FilterChooser(Owner->AllInstructions,
- mapIterator->second,
- BitValueArray,
- *Owner)
- ));
- }
- }
-
- // Emit code to decode instructions given a segment or segments of bits.
- void emit(raw_ostream &o, Indenter &i) {
- o.indent(i) << "// Check Inst{";
-
- if (NumBits > 1)
- o << (StartBit + NumBits - 1) << '-';
-
- o << StartBit << "} ...\n";
-
- o.indent(i) << "switch (fieldFromInstruction(insn, "
- << StartBit << ", " << NumBits << ")) {\n";
-
- typename std::map<unsigned, FilterChooser>::iterator filterIterator;
-
- bool DefaultCase = false;
- for (filterIterator = FilterChooserMap.begin();
- filterIterator != FilterChooserMap.end();
- filterIterator++) {
-
- // Field value -1 implies a non-empty set of variable instructions.
- // See also recurse().
- if (filterIterator->first == (unsigned)-1) {
- DefaultCase = true;
-
- o.indent(i) << "default:\n";
- o.indent(i) << " break; // fallthrough\n";
-
- // Closing curly brace for the switch statement.
- // This is unconventional because we want the default processing to be
- // performed for the fallthrough cases as well, i.e., when the "cases"
- // did not prove a decoded instruction.
- o.indent(i) << "}\n";
-
- } else {
- o.indent(i) << "case " << filterIterator->first << ":\n";
- }
-
- // We arrive at a category of instructions with the same segment value.
- // Now delegate to the sub filter chooser for further decodings.
- // The case may fallthrough, which happens if the remaining well-known
- // encoding bits do not match exactly.
- if (!DefaultCase) i.push();
- {
- bool finished = filterIterator->second.emit(o, i);
- // For top level default case, there's no need for a break statement.
- if (Owner->isTopLevel() && DefaultCase)
- break;
- if (!finished)
- o.indent(i) << "break;\n";
- }
- if (!DefaultCase) i.pop();
- }
-
- // If there is no default case, we still need to supply a closing brace.
- if (!DefaultCase) {
- // Closing curly brace for the switch statement.
- o.indent(i) << "}\n";
- }
- }
-
- // Returns the number of fanout produced by the filter. More fanout implies
- // the filter distinguishes more categories of instructions.
- unsigned usefulness() const {
- if (VariableInstructions.size())
- return FilteredInstructions.size();
- else
- return FilteredInstructions.size() + 1;
- }
- }; // End of inner class Filter
-
- friend class Filter;
-
- // Vector of codegen instructions to choose our filter.
- const std::vector<const CodeGenInstruction*> &AllInstructions;
-
- // Vector of uid's for this filter chooser to work on.
- const std::vector<unsigned> Opcodes;
-
- // Vector of candidate filters.
- std::vector<Filter> Filters;
-
- // Array of bit values passed down from our parent.
- // Set to all BIT_UNFILTERED's for Parent == NULL.
- bit_value_t FilterBitValues[tBitWidth];
-
- // Links to the FilterChooser above us in the decoding tree.
- FilterChooser *Parent;
-
- // Index of the best filter from Filters.
- int BestIndex;
-
-public:
- FilterChooser(const FilterChooser &FC) :
- AbstractFilterChooser(),
- AllInstructions(FC.AllInstructions),
- Opcodes(FC.Opcodes),
- Filters(FC.Filters),
- Parent(FC.Parent),
- BestIndex(FC.BestIndex)
- {
- memcpy(FilterBitValues, FC.FilterBitValues, sizeof(FilterBitValues));
- }
-
- FilterChooser(const std::vector<const CodeGenInstruction*> &Insts,
- const std::vector<unsigned> &IDs) :
- AllInstructions(Insts),
- Opcodes(IDs),
- Filters(),
- Parent(NULL),
- BestIndex(-1)
- {
- for (unsigned i = 0; i < tBitWidth; ++i)
- FilterBitValues[i] = BIT_UNFILTERED;
-
- doFilter();
- }
-
- FilterChooser(const std::vector<const CodeGenInstruction*> &Insts,
- const std::vector<unsigned> &IDs,
- bit_value_t (&ParentFilterBitValues)[tBitWidth],
- FilterChooser &parent) :
- AllInstructions(Insts),
- Opcodes(IDs),
- Filters(),
- Parent(&parent),
- BestIndex(-1)
- {
- for (unsigned i = 0; i < tBitWidth; ++i)
- FilterBitValues[i] = ParentFilterBitValues[i];
-
- doFilter();
- }
-
- // The top level filter chooser has NULL as its parent.
- bool isTopLevel() { return Parent == NULL; }
-
- // This provides an opportunity for target specific code emission.
- void emitTopHook(raw_ostream &o, Indenter &i) {
- if (TargetName == TARGET_ARM) {
- // Emit code that references the ARMFormat data type.
- o << "static const ARMFormat ARMFormats[] = {\n";
- for (unsigned i = 0, e = AllInstructions.size(); i != e; ++i) {
- const Record &Def = *(AllInstructions[i]->TheDef);
- const std::string &Name = Def.getName();
- if (Def.isSubClassOf("InstARM") || Def.isSubClassOf("InstThumb"))
- o.indent(2) <<
- stringForARMFormat((ARMFormat)getByteField(Def, "Form"));
- else
- o << " ARM_FORMAT_NA";
-
- o << ",\t// Inst #" << i << " = " << Name << '\n';
- }
- o << " ARM_FORMAT_NA\t// Unreachable.\n";
- o << "};\n\n";
-
- // And emit code that references the NSFormat data type.
- // This is meaningful only for NEONFrm instructions.
- o << "static const NSFormat NSFormats[] = {\n";
- for (unsigned i = 0, e = AllInstructions.size(); i != e; ++i) {
- const Record &Def = *(AllInstructions[i]->TheDef);
- const std::string &Name = Def.getName();
- if (Def.isSubClassOf("NeonI") || Def.isSubClassOf("NeonXI"))
- o.indent(2) <<
- stringForNSFormat((NSFormat)getByteField(Def, "NSForm"));
- else
- o << " NS_FORMAT_NA";
-
- o << ",\t// Inst #" << i << " = " << Name << '\n';
- }
- o << " NS_FORMAT_NA\t// Unreachable.\n";
- o << "};\n\n";
- }
- }
-
- // Emit the top level typedef and decodeInstruction() function.
- void emitTop(raw_ostream &o, Indenter &i) {
-
- // Run the target specific emit hook.
- emitTopHook(o, i);
-
- switch(tBitWidth) {
- case 8:
- o.indent(i) << "typedef uint8_t field_t;\n";
- break;
- case 16:
- o.indent(i) << "typedef uint16_t field_t;\n";
- break;
- case 32:
- o.indent(i) << "typedef uint32_t field_t;\n";
- break;
- case 64:
- o.indent(i) << "typedef uint64_t field_t;\n";
- break;
- default:
- assert(0 && "Unexpected instruction size!");
- }
-
- o << '\n';
-
- o.indent(i) << "static field_t " <<
- "fieldFromInstruction(field_t insn, unsigned startBit, unsigned numBits)\n";
-
- o.indent(i) << "{\n";
- i.push();
- {
- o.indent(i) << "assert(startBit + numBits <= " << tBitWidth
- << " && \"Instruction field out of bounds!\");\n";
- o << '\n';
- o.indent(i) << "field_t fieldMask;\n";
- o << '\n';
- o.indent(i) << "if (numBits == " << tBitWidth << ")\n";
-
- i.push();
- {
- o.indent(i) << "fieldMask = (field_t)-1;\n";
- }
- i.pop();
-
- o.indent(i) << "else\n";
-
- i.push();
- {
- o.indent(i) << "fieldMask = ((1 << numBits) - 1) << startBit;\n";
- }
- i.pop();
-
- o << '\n';
- o.indent(i) << "return (insn & fieldMask) >> startBit;\n";
- }
- i.pop();
- o.indent(i) << "}\n";
-
- o << '\n';
-
- o.indent(i) << "static uint16_t decodeInstruction(field_t insn) {\n";
-
- i.push();
- {
- // Emits code to decode the instructions.
- emit(o, i);
-
- o << '\n';
- o.indent(i) << "return 0;\n";
- }
- i.pop();
-
- o.indent(i) << "}\n";
-
- o << '\n';
-
- }
-
- // This provides an opportunity for target specific code emission after
- // emitTop().
- void emitBot(raw_ostream &o, Indenter &i) {
- if (TargetName == TARGET_THUMB) {
- // Emit code that decodes the Thumb ISA.
- o.indent(i)
- << "static uint16_t decodeThumbInstruction(field_t insn) {\n";
-
- i.push();
- {
- // Emits code to decode the instructions.
- emit(o, i);
-
- o << '\n';
- o.indent(i) << "return 0;\n";
- }
- i.pop();
-
- o.indent(i) << "}\n";
- }
- }
-
-protected:
- // Populates the insn given the uid.
- void insnWithID(insn_t &Insn, unsigned Opcode) const {
- assert(Opcode > 10);
- BitsInit &Bits = getBitsField(*AllInstructions[Opcode]->TheDef, "Inst");
-
- for (unsigned i = 0; i < tBitWidth; ++i)
- Insn[i] = bitFromBits(Bits, i);
- }
-
- // Returns the record name.
- const std::string &nameWithID(unsigned Opcode) const {
- return AllInstructions[Opcode]->TheDef->getName();
- }
-
- // Populates the field of the insn given the start position and the number of
- // consecutive bits to scan for.
- //
- // Returns false if and on the first uninitialized bit value encountered.
- // Returns true, otherwise.
- const bool fieldFromInsn(uint64_t &Field, insn_t &Insn, unsigned StartBit,
- unsigned NumBits) const {
- Field = 0;
-
- for (unsigned i = 0; i < NumBits; ++i) {
- if (Insn[StartBit + i] == BIT_UNSET)
- return false;
-
- if (Insn[StartBit + i] == BIT_TRUE)
- Field = Field | (1 << i);
- }
-
- return true;
- }
-
- void dumpFilterArray(raw_ostream &o, bit_value_t (&filter)[tBitWidth]) {
- unsigned bitIndex;
-
- for (bitIndex = tBitWidth; bitIndex > 0; bitIndex--) {
- switch (filter[bitIndex - 1]) {
- case BIT_UNFILTERED:
- o << ".";
- break;
- case BIT_UNSET:
- o << "_";
- break;
- case BIT_TRUE:
- o << "1";
- break;
- case BIT_FALSE:
- o << "0";
- break;
- }
- }
- }
-
- void dumpStack(raw_ostream &o, const char *prefix) {
- FilterChooser *current = this;
-
- while (current) {
- o << prefix;
-
- dumpFilterArray(o, current->FilterBitValues);
-
- o << '\n';
-
- current = current->Parent;
- }
- }
-
- Filter &bestFilter() {
- assert(BestIndex != -1 && "BestIndex not set");
- return Filters[BestIndex];
- }
-
- // States of our finite state machines.
- typedef enum {
- ATTR_NONE,
- ATTR_FILTERED,
- ATTR_ALL_SET,
- ATTR_ALL_UNSET,
- ATTR_MIXED
- } bitAttr_t;
-
- // Called from Filter::recurse() when singleton exists. For debug purpose.
- void SingletonExists(unsigned Opc) {
-
- insn_t Insn0;
- insnWithID(Insn0, Opc);
-
- errs() << "Singleton exists: " << nameWithID(Opc)
- << " with its decoding dominating ";
- for (unsigned i = 0; i < Opcodes.size(); ++i) {
- if (Opcodes[i] == Opc) continue;
- errs() << nameWithID(Opcodes[i]) << ' ';
- }
- errs() << '\n';
-
- dumpStack(errs(), "\t\t");
- for (unsigned i = 0; i < Opcodes.size(); i++) {
- const std::string &Name = nameWithID(Opcodes[i]);
-
- errs() << '\t' << Name << " ";
- dumpBits(errs(),
- getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst"));
- errs() << '\n';
- }
- }
-
- bool ValueSet(bit_value_t V) {
- return (V == BIT_TRUE || V == BIT_FALSE);
- }
- bool ValueNotSet(bit_value_t V) {
- return (V == BIT_UNSET);
- }
- int Value(bit_value_t V) {
- return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1);
- }
- bool PositionFiltered(unsigned i) {
- return ValueSet(FilterBitValues[i]);
- }
-
- // Calculates the island(s) needed to decode the instruction.
- unsigned getIslands(std::vector<unsigned> &StartBits,
- std::vector<unsigned> &EndBits,
- std::vector<uint64_t> &FieldVals, insn_t &Insn)
- {
- unsigned Num, BitNo;
- Num = BitNo = 0;
-
- uint64_t FieldVal = 0;
-
- // 0: Init
- // 1: Water
- // 2: Island
- int State = 0;
- int Val = -1;
-
- for (unsigned i = 0; i < tBitWidth; ++i) {
- Val = Value(Insn[i]);
- bool Filtered = PositionFiltered(i);
- switch (State) {
- default:
- assert(0 && "Unreachable code!");
- break;
- case 0:
- case 1:
- if (Filtered || Val == -1)
- State = 1; // Still in Water
- else {
- State = 2; // Into the Island
- BitNo = 0;
- StartBits.push_back(i);
- FieldVal = Val;
- }
- break;
- case 2:
- if (Filtered || Val == -1) {
- State = 1; // Into the Water
- EndBits.push_back(i - 1);
- FieldVals.push_back(FieldVal);
- ++Num;
- } else {
- State = 2; // Still in Island
- ++BitNo;
- FieldVal = FieldVal | Val << BitNo;
- }
- break;
- }
- }
- // If we are still in Island after the loop, do some housekeeping.
- if (State == 2) {
- EndBits.push_back(tBitWidth - 1);
- FieldVals.push_back(FieldVal);
- ++Num;
- }
-
- /*
- printf("StartBits.size()=%u,EndBits.size()=%u,FieldVals.size()=%u,Num=%u\n",
- (unsigned)StartBits.size(), (unsigned)EndBits.size(),
- (unsigned)FieldVals.size(), Num);
- */
-
- assert(StartBits.size() == Num && EndBits.size() == Num &&
- FieldVals.size() == Num);
-
- return Num;
- }
-
- bool LdStCopEncoding1(unsigned Opc) {
- const std::string &Name = nameWithID(Opc);
- if (Name == "LDC_OFFSET" || Name == "LDC_OPTION" ||
- Name == "LDC_POST" || Name == "LDC_PRE" ||
- Name == "LDCL_OFFSET" || Name == "LDCL_OPTION" ||
- Name == "LDCL_POST" || Name == "LDCL_PRE" ||
- Name == "STC_OFFSET" || Name == "STC_OPTION" ||
- Name == "STC_POST" || Name == "STC_PRE" ||
- Name == "STCL_OFFSET" || Name == "STCL_OPTION" ||
- Name == "STCL_POST" || Name == "STCL_PRE")
- return true;
- else
- return false;
- }
-
- // Emits code to decode the singleton. Return true if we have matched all the
- // well-known bits.
- bool emitSingletonDecoder(raw_ostream &o, Indenter &i, unsigned Opc) {
-
- std::vector<unsigned> StartBits;
- std::vector<unsigned> EndBits;
- std::vector<uint64_t> FieldVals;
- insn_t Insn;
- insnWithID(Insn, Opc);
-
- if (TargetName == TARGET_ARM && LdStCopEncoding1(Opc)) {
- o.indent(i);
- // A8.6.51 & A8.6.188
- // If coproc = 0b101?, i.e, slice(insn, 11, 8) = 10 or 11, escape.
- o << "if (fieldFromInstruction(insn, 9, 3) == 5) break; // fallthrough\n";
- }
-
- // Look for islands of undecoded bits of the singleton.
- getIslands(StartBits, EndBits, FieldVals, Insn);
-
- unsigned Size = StartBits.size();
- unsigned I, NumBits;
-
- // If we have matched all the well-known bits, just issue a return.
- if (Size == 0) {
- o.indent(i) << "return " << Opc << "; // " << nameWithID(Opc) << '\n';
- return true;
- }
-
- // Otherwise, there are more decodings to be done!
-
- // Emit code to match the island(s) for the singleton.
- o.indent(i) << "// Check ";
-
- for (I = Size; I != 0; --I) {
- o << "Inst{" << EndBits[I-1] << '-' << StartBits[I-1] << "} ";
- if (I > 1)
- o << "&& ";
- else
- o << "for singleton decoding...\n";
- }
-
- o.indent(i) << "if (";
-
- for (I = Size; I != 0; --I) {
- NumBits = EndBits[I-1] - StartBits[I-1] + 1;
- o << "fieldFromInstruction(insn, " << StartBits[I-1] << ", " << NumBits
- << ") == " << FieldVals[I-1];
- if (I > 1)
- o << " && ";
- else
- o << ")\n";
- }
-
- o.indent(i) << " return " << Opc << "; // " << nameWithID(Opc) << '\n';
-
- return false;
- }
-
- // Emits code to decode the singleton, and then to decode the rest.
- void emitSingletonDecoder(raw_ostream &o, Indenter &i, Filter & Best) {
-
- unsigned Opc = Best.getSingletonOpc();
-
- emitSingletonDecoder(o, i, Opc);
-
- // Emit code for the rest.
- o.indent(i) << "else\n";
- i.push();
- {
- Best.getVariableFC().emit(o, i);
- }
- i.pop();
- }
-
- // Assign a single filter and run with it.
- void runSingleFilter(FilterChooser &owner, unsigned startBit, unsigned numBit,
- bool mixed) {
- Filters.clear();
- Filter F(*this, startBit, numBit, true);
- Filters.push_back(F);
- BestIndex = 0; // Sole Filter instance to choose from.
- bestFilter().recurse();
- }
-
- bool filterProcessor(bool AllowMixed, bool Greedy = true) {
- Filters.clear();
- BestIndex = -1;
- unsigned numInstructions = Opcodes.size();
-
- assert(numInstructions && "Filter created with no instructions");
-
- // No further filtering is necessary.
- if (numInstructions == 1)
- return true;
-
- // Heuristics. See also doFilter()'s "Heuristics" comment when num of
- // instructions is 3.
- if (AllowMixed && !Greedy) {
- assert(numInstructions == 3);
-
- for (unsigned i = 0; i < Opcodes.size(); ++i) {
- std::vector<unsigned> StartBits;
- std::vector<unsigned> EndBits;
- std::vector<uint64_t> FieldVals;
- insn_t Insn;
-
- insnWithID(Insn, Opcodes[i]);
-
- // Look for islands of undecoded bits of any instruction.
- if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) {
- // Found an instruction with island(s). Now just assign a filter.
- runSingleFilter(*this, StartBits[0], EndBits[0] - StartBits[0] + 1,
- true);
- return true;
- }
- }
- }
-
- unsigned bitIndex, insnIndex;
-
- // We maintain tBitWidth copies of the bitAttrs automaton.
- // The automaton consumes the corresponding bit from each
- // instruction.
- //
- // Input symbols: 0, 1, and _ (unset).
- // States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED.
- // Initial state: NONE.
- //
- // (NONE) ------- [01] -> (ALL_SET)
- // (NONE) ------- _ ----> (ALL_UNSET)
- // (ALL_SET) ---- [01] -> (ALL_SET)
- // (ALL_SET) ---- _ ----> (MIXED)
- // (ALL_UNSET) -- [01] -> (MIXED)
- // (ALL_UNSET) -- _ ----> (ALL_UNSET)
- // (MIXED) ------ . ----> (MIXED)
- // (FILTERED)---- . ----> (FILTERED)
-
- bitAttr_t bitAttrs[tBitWidth];
-
- // FILTERED bit positions provide no entropy and are not worthy of pursuing.
- // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
- for (bitIndex = 0; bitIndex < tBitWidth; ++bitIndex)
- if (FilterBitValues[bitIndex] == BIT_TRUE ||
- FilterBitValues[bitIndex] == BIT_FALSE)
- bitAttrs[bitIndex] = ATTR_FILTERED;
- else
- bitAttrs[bitIndex] = ATTR_NONE;
-
- for (insnIndex = 0; insnIndex < numInstructions; ++insnIndex) {
- insn_t insn;
-
- insnWithID(insn, Opcodes[insnIndex]);
-
- for (bitIndex = 0; bitIndex < tBitWidth; ++bitIndex) {
- switch (bitAttrs[bitIndex]) {
- case ATTR_NONE:
- if (insn[bitIndex] == BIT_UNSET)
- bitAttrs[bitIndex] = ATTR_ALL_UNSET;
- else
- bitAttrs[bitIndex] = ATTR_ALL_SET;
- break;
- case ATTR_ALL_SET:
- if (insn[bitIndex] == BIT_UNSET)
- bitAttrs[bitIndex] = ATTR_MIXED;
- break;
- case ATTR_ALL_UNSET:
- if (insn[bitIndex] != BIT_UNSET)
- bitAttrs[bitIndex] = ATTR_MIXED;
- break;
- case ATTR_MIXED:
- case ATTR_FILTERED:
- break;
- }
- }
- }
-
- // The regionAttr automaton consumes the bitAttrs automatons' state,
- // lowest-to-highest.
- //
- // Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed)
- // States: NONE, ALL_SET, MIXED
- // Initial state: NONE
- //
- // (NONE) ----- F --> (NONE)
- // (NONE) ----- S --> (ALL_SET) ; and set region start
- // (NONE) ----- U --> (NONE)
- // (NONE) ----- M --> (MIXED) ; and set region start
- // (ALL_SET) -- F --> (NONE) ; and report an ALL_SET region
- // (ALL_SET) -- S --> (ALL_SET)
- // (ALL_SET) -- U --> (NONE) ; and report an ALL_SET region
- // (ALL_SET) -- M --> (MIXED) ; and report an ALL_SET region
- // (MIXED) ---- F --> (NONE) ; and report a MIXED region
- // (MIXED) ---- S --> (ALL_SET) ; and report a MIXED region
- // (MIXED) ---- U --> (NONE) ; and report a MIXED region
- // (MIXED) ---- M --> (MIXED)
-
- bitAttr_t regionAttr = ATTR_NONE;
- unsigned startBit = 0;
-
- for (bitIndex = 0; bitIndex < tBitWidth; bitIndex++) {
- bitAttr_t bitAttr = bitAttrs[bitIndex];
-
- assert(bitAttr != ATTR_NONE && "Bit without attributes");
-
-#define SET_START \
- startBit = bitIndex;
-
-#define REPORT_REGION \
- if (regionAttr == ATTR_MIXED && AllowMixed) \
- Filters.push_back(Filter(*this, startBit, bitIndex - startBit, true)); \
- else if (regionAttr == ATTR_ALL_SET && !AllowMixed) \
- Filters.push_back(Filter(*this, startBit, bitIndex - startBit, false));
-
- switch (regionAttr) {
- case ATTR_NONE:
- switch (bitAttr) {
- case ATTR_FILTERED:
- break;
- case ATTR_ALL_SET:
- SET_START
- regionAttr = ATTR_ALL_SET;
- break;
- case ATTR_ALL_UNSET:
- break;
- case ATTR_MIXED:
- SET_START
- regionAttr = ATTR_MIXED;
- break;
- default:
- assert(0 && "Unexpected bitAttr!");
- }
- break;
- case ATTR_ALL_SET:
- switch (bitAttr) {
- case ATTR_FILTERED:
- REPORT_REGION
- regionAttr = ATTR_NONE;
- break;
- case ATTR_ALL_SET:
- break;
- case ATTR_ALL_UNSET:
- REPORT_REGION
- regionAttr = ATTR_NONE;
- break;
- case ATTR_MIXED:
- REPORT_REGION
- SET_START
- regionAttr = ATTR_MIXED;
- break;
- default:
- assert(0 && "Unexpected bitAttr!");
- }
- break;
- case ATTR_MIXED:
- switch (bitAttr) {
- case ATTR_FILTERED:
- REPORT_REGION
- SET_START
- regionAttr = ATTR_NONE;
- break;
- case ATTR_ALL_SET:
- REPORT_REGION
- SET_START
- regionAttr = ATTR_ALL_SET;
- break;
- case ATTR_ALL_UNSET:
- REPORT_REGION
- regionAttr = ATTR_NONE;
- break;
- case ATTR_MIXED:
- break;
- default:
- assert(0 && "Unexpected bitAttr!");
- }
- break;
- case ATTR_ALL_UNSET:
- assert(0 && "regionAttr state machine has no ATTR_UNSET state");
- case ATTR_FILTERED:
- assert(0 && "regionAttr state machine has no ATTR_FILTERED state");
- }
- }
-
- // At the end, if we're still in ALL_SET or MIXED states, report a region
-
- switch (regionAttr) {
- case ATTR_NONE:
- break;
- case ATTR_FILTERED:
- break;
- case ATTR_ALL_SET:
- REPORT_REGION
- break;
- case ATTR_ALL_UNSET:
- break;
- case ATTR_MIXED:
- REPORT_REGION
- break;
- }
-
-#undef SET_START
-#undef REPORT_REGION
-
- // We have finished with the filter processings. Now it's time to choose
- // the best performing filter.
-
- BestIndex = 0;
- bool AllUseless = true;
- unsigned BestScore = 0;
-
- for (unsigned i = 0, e = Filters.size(); i != e; ++i) {
- unsigned Usefulness = Filters[i].usefulness();
-
- if (Usefulness)
- AllUseless = false;
-
- if (Usefulness > BestScore) {
- BestIndex = i;
- BestScore = Usefulness;
- }
- }
-
- if (!AllUseless) {
- bestFilter().recurse();
- }
-
- return !AllUseless;
- } // end of filterProcessor(bool)
-
- // Decides on the best configuration of filter(s) to use in order to decode
- // the instructions. A conflict of instructions may occur, in which case we
- // dump the conflict set to the standard error.
- void doFilter() {
- unsigned Num = Opcodes.size();
- assert(Num && "FilterChooser created with no instructions");
-
- // Heuristics: Use Inst{31-28} as the top level filter for ARM ISA.
- if (TargetName == TARGET_ARM && Parent == NULL) {
- runSingleFilter(*this, 28, 4, false);
- return;
- }
-
- if (filterProcessor(false))
- return;
-
- if (filterProcessor(true))
- return;
-
- // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where
- // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
- // well-known encoding pattern. In such case, we backtrack and scan for the
- // the very first consecutive ATTR_ALL_SET region and assign a filter to it.
- if (Num == 3 && filterProcessor(true, false))
- return;
-
- // If we come to here, the instruction decoding has failed.
- // Print out the instructions in the conflict set...
-
- BestIndex = -1;
-
- DEBUG({
- errs() << "Conflict:\n";
-
- dumpStack(errs(), "\t\t");
-
- for (unsigned i = 0; i < Num; i++) {
- const std::string &Name = nameWithID(Opcodes[i]);
-
- errs() << '\t' << Name << " ";
- dumpBits(errs(),
- getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst"));
- errs() << '\n';
- }
- });
- }
-
- // Emits code to decode our share of instructions. Returns true if the
- // emitted code causes a return, which occurs if we know how to decode
- // the instruction at this level or the instruction is not decodeable.
- bool emit(raw_ostream &o, Indenter &i) {
- if (Opcodes.size() == 1) {
- // There is only one instruction in the set, which is great!
- // Call emitSingletonDecoder() to see whether there are any remaining
- // encodings bits.
- return emitSingletonDecoder(o, i, Opcodes[0]);
-
- } else if (BestIndex == -1) {
- if (TargetName == TARGET_ARM && Opcodes.size() == 2) {
- // Resolve the known conflict sets:
- //
- // 1. source registers are identical => VMOVDneon; otherwise => VORRd
- // 2. source registers are identical => VMOVQ; otherwise => VORRq
- // 3. LDR, LDRcp => return LDR for now.
- // FIXME: How can we distinguish between LDR and LDRcp? Do we need to?
- // 4. VLD[234]LN*a/VST[234]LN*a vs. VLD[234]LN*b/VST[234]LN*b conflicts
- // are resolved returning the 'a' versions of the instructions. Note
- // that the difference between a/b is that the former is for double-
- // spaced even registers while the latter is for double-spaced odd
- // registers. This is for codegen instruction selection purpose.
- // For disassembly, it does not matter.
- const std::string &name1 = nameWithID(Opcodes[0]);
- const std::string &name2 = nameWithID(Opcodes[1]);
- if ((name1 == "VMOVDneon" && name2 == "VORRd") ||
- (name1 == "VMOVQ" && name2 == "VORRq")) {
- // Inserting the opening curly brace for this case block.
- i.pop();
- o.indent(i) << "{\n";
- i.push();
-
- o.indent(i) << "field_t N = fieldFromInstruction(insn, 7, 1), "
- << "M = fieldFromInstruction(insn, 5, 1);\n";
- o.indent(i) << "field_t Vn = fieldFromInstruction(insn, 16, 4), "
- << "Vm = fieldFromInstruction(insn, 0, 4);\n";
- o.indent(i) << "return (N == M && Vn == Vm) ? "
- << Opcodes[0] << " /* " << name1 << " */ : "
- << Opcodes[1] << " /* " << name2 << " */ ;\n";
-
- // Inserting the closing curly brace for this case block.
- i.pop();
- o.indent(i) << "}\n";
- i.push();
-
- return true;
- }
- if (name1 == "LDR" && name2 == "LDRcp") {
- o.indent(i) << "return " << Opcodes[0]
- << "; // Returning LDR for {LDR, LDRcp}\n";
- return true;
- }
- if (sameStringExceptEndingChar(name1, name2, 'a', 'b')) {
- o.indent(i) << "return " << Opcodes[0] << "; // Returning " << name1
- << " for {" << name1 << ", " << name2 << "}\n";
- return true;
- }
-
- // Otherwise, it does not belong to the known conflict sets.
- }
- // We don't know how to decode these instructions! Dump the conflict set!
- o.indent(i) << "return 0;" << " // Conflict set: ";
- for (int i = 0, N = Opcodes.size(); i < N; ++i) {
- o << nameWithID(Opcodes[i]);
- if (i < (N - 1))
- o << ", ";
- else
- o << '\n';
- }
- return true;
- } else {
- // Choose the best filter to do the decodings!
- Filter &Best = bestFilter();
- if (Best.getNumFiltered() == 1)
- emitSingletonDecoder(o, i, Best);
- else
- bestFilter().emit(o, i);
- return false;
- }
- }
-};
-
-///////////////
-// Backend //
-///////////////
-
-class RISCDisassemblerEmitter::RISCDEBackend {
-public:
- RISCDEBackend(RISCDisassemblerEmitter &frontend) :
- NumberedInstructions(),
- Opcodes(),
- Frontend(frontend),
- Target(),
- AFC(NULL)
- {
- populateInstructions();
-
- if (Target.getName() == "ARM") {
- TargetName = TARGET_ARM;
- } else {
- errs() << "Target name " << Target.getName() << " not recognized\n";
- assert(0 && "Unknown target");
- }
- }
-
- ~RISCDEBackend() {
- if (AFC) {
- delete AFC;
- AFC = NULL;
- }
- }
-
- void getInstructionsByEnumValue(std::vector<const CodeGenInstruction*>
- &NumberedInstructions) {
- // Dig down to the proper namespace. Code shamelessly stolen from
- // InstrEnumEmitter.cpp
- std::string Namespace;
- CodeGenTarget::inst_iterator II, E;
-
- for (II = Target.inst_begin(), E = Target.inst_end(); II != E; ++II)
- if (II->second.Namespace != "TargetInstrInfo") {
- Namespace = II->second.Namespace;
- break;
- }
-
- assert(!Namespace.empty() && "No instructions defined.");
-
- Target.getInstructionsByEnumValue(NumberedInstructions);
- }
-
- bool populateInstruction(const CodeGenInstruction &CGI, TARGET_NAME_t TN) {
- const Record &Def = *CGI.TheDef;
- const std::string &Name = Def.getName();
- uint8_t Form = getByteField(Def, "Form");
- BitsInit &Bits = getBitsField(Def, "Inst");
-
- if (TN == TARGET_ARM) {
- // FIXME: what about Int_MemBarrierV6 and Int_SyncBarrierV6?
- if ((Name != "Int_MemBarrierV7" && Name != "Int_SyncBarrierV7") &&
- Form == ARM_FORMAT_PSEUDO)
- return false;
- if (thumbInstruction(Form))
- return false;
- if (Name.find("CMPz") != std::string::npos /* ||
- Name.find("CMNz") != std::string::npos */)
- return false;
-
- // Ignore pseudo instructions.
- if (Name == "BXr9" || Name == "BMOVPCRX" || Name == "BMOVPCRXr9")
- return false;
-
- // VLDRQ/VSTRQ can be hanlded with the more generic VLDMD/VSTMD.
- if (Name == "VLDRQ" || Name == "VSTRQ")
- return false;
-
- //
- // The following special cases are for conflict resolutions.
- //
-
- // RSCSri and RSCSrs set the 's' bit, but are not predicated. We are
- // better off using the generic RSCri and RSCrs instructions.
- if (Name == "RSCSri" || Name == "RSCSrs") return false;
-
- // MOVCCr, MOVCCs, MOVCCi, FCYPScc, FCYPDcc, FNEGScc, and FNEGDcc are used
- // in the compiler to implement conditional moves. We can ignore them in
- // favor of their more generic versions of instructions.
- // See also SDNode *ARMDAGToDAGISel::Select(SDValue Op).
- if (Name == "MOVCCr" || Name == "MOVCCs" || Name == "MOVCCi" ||
- Name == "FCPYScc" || Name == "FCPYDcc" ||
- Name == "FNEGScc" || Name == "FNEGDcc")
- return false;
-
- // Ditto for VMOVDcc, VMOVScc, VNEGDcc, and VNEGScc.
- if (Name == "VMOVDcc" || Name == "VMOVScc" || Name == "VNEGDcc" ||
- Name == "VNEGScc")
- return false;
-
- // Ignore the *_sfp instructions when decoding. They are used by the
- // compiler to implement scalar floating point operations using vector
- // operations in order to work around some performance issues.
- if (Name.find("_sfp") != std::string::npos) return false;
-
- // LLVM added LDM/STM_UPD which conflicts with LDM/STM.
- // Ditto for VLDMS_UPD, VLDMD_UPD, VSTMS_UPD, VSTMD_UPD.
- if (Name == "LDM_UPD" || Name == "STM_UPD" || Name == "VLDMS_UPD" ||
- Name == "VLDMD_UPD" || Name == "VSTMS_UPD" || Name == "VSTMD_UPD")
- return false;
-
- // LDM_RET is a special case of LDM (Load Multiple) where the registers
- // loaded include the PC, causing a branch to a loaded address. Ignore
- // the LDM_RET instruction when decoding.
- if (Name == "LDM_RET") return false;
-
- // Bcc is in a more generic form than B. Ignore B when decoding.
- if (Name == "B") return false;
-
- // Ignore the non-Darwin BL instructions and the TPsoft (TLS) instruction.
- if (Name == "BL" || Name == "BL_pred" || Name == "BLX" || Name == "BX" ||
- Name == "TPsoft")
- return false;
-
- // Ignore VDUPf[d|q] instructions known to conflict with VDUP32[d-q] for
- // decoding. The instruction duplicates an element from an ARM core
- // register into every element of the destination vector. There is no
- // distinction between data types.
- if (Name == "VDUPfd" || Name == "VDUPfq") return false;
-
- // A8-598: VEXT
- // Vector Extract extracts elements from the bottom end of the second
- // operand vector and the top end of the first, concatenates them and
- // places the result in the destination vector. The elements of the
- // vectors are treated as being 8-bit bitfields. There is no distinction
- // between data types. The size of the operation can be specified in
- // assembler as vext.size. If the value is 16, 32, or 64, the syntax is
- // a pseudo-instruction for a VEXT instruction specifying the equivalent
- // number of bytes.
- //
- // Variants VEXTd16, VEXTd32, VEXTd8, and VEXTdf are reduced to VEXTd8;
- // variants VEXTq16, VEXTq32, VEXTq8, and VEXTqf are reduced to VEXTq8.
- if (Name == "VEXTd16" || Name == "VEXTd32" || Name == "VEXTdf" ||
- Name == "VEXTq16" || Name == "VEXTq32" || Name == "VEXTqf")
- return false;
-
- // Vector Reverse is similar to Vector Extract. There is no distinction
- // between data types, other than size.
- //
- // VREV64df is equivalent to VREV64d32.
- // VREV64qf is equivalent to VREV64q32.
- if (Name == "VREV64df" || Name == "VREV64qf") return false;
-
- // VDUPLNfd is equivalent to VDUPLN32d; VDUPfdf is specialized VDUPLN32d.
- // VDUPLNfq is equivalent to VDUPLN32q; VDUPfqf is specialized VDUPLN32q.
- // VLD1df is equivalent to VLD1d32.
- // VLD1qf is equivalent to VLD1q32.
- // VLD2d64 is equivalent to VLD1q64.
- // VST1df is equivalent to VST1d32.
- // VST1qf is equivalent to VST1q32.
- // VST2d64 is equivalent to VST1q64.
- if (Name == "VDUPLNfd" || Name == "VDUPfdf" ||
- Name == "VDUPLNfq" || Name == "VDUPfqf" ||
- Name == "VLD1df" || Name == "VLD1qf" || Name == "VLD2d64" ||
- Name == "VST1df" || Name == "VST1qf" || Name == "VST2d64")
- return false;
- } else if (TN == TARGET_THUMB) {
- if (!thumbInstruction(Form))
- return false;
-
- // Ignore pseudo instructions.
- if (Name == "tInt_eh_sjlj_setjmp" || Name == "t2Int_eh_sjlj_setjmp" ||
- Name == "t2MOVi32imm" || Name == "tBX" || Name == "tBXr9")
- return false;
-
- // LLVM added tLDM_UPD which conflicts with tLDM.
- if (Name == "tLDM_UPD")
- return false;
-
- // On Darwin R9 is call-clobbered. Ignore the non-Darwin counterparts.
- if (Name == "tBL" || Name == "tBLXi" || Name == "tBLXr")
- return false;
-
- // Ignore the TPsoft (TLS) instructions, which conflict with tBLr9.
- if (Name == "tTPsoft" || Name == "t2TPsoft")
- return false;
-
- // Ignore tLEApcrel and tLEApcrelJT, prefer tADDrPCi.
- if (Name == "tLEApcrel" || Name == "tLEApcrelJT")
- return false;
-
- // Ignore t2LEApcrel, prefer the generic t2ADD* for disassembly printing.
- if (Name == "t2LEApcrel")
- return false;
-
- // Ignore tADDrSP, tADDspr, and tPICADD, prefer the generic tADDhirr.
- // Ignore t2SUBrSPs, prefer the t2SUB[S]r[r|s].
- // Ignore t2ADDrSPs, prefer the t2ADD[S]r[r|s].
- if (Name == "tADDrSP" || Name == "tADDspr" || Name == "tPICADD" ||
- Name == "t2SUBrSPs" || Name == "t2ADDrSPs")
- return false;
-
- // Ignore t2LDRDpci, prefer the generic t2LDRDi8, t2LDRD_PRE, t2LDRD_POST.
- if (Name == "t2LDRDpci")
- return false;
-
- // Ignore t2TBB, t2TBH and prefer the generic t2TBBgen, t2TBHgen.
- if (Name == "t2TBB" || Name == "t2TBH")
- return false;
-
- // Resolve conflicts:
- //
- // tBfar conflicts with tBLr9
- // tCMNz conflicts with tCMN (with assembly format strings being equal)
- // tPOP_RET/t2LDM_RET conflict with tPOP/t2LDM (ditto)
- // tMOVCCi conflicts with tMOVi8
- // tMOVCCr conflicts with tMOVgpr2gpr
- // tBR_JTr conflicts with tBRIND
- // tSpill conflicts with tSTRspi
- // tLDRcp conflicts with tLDRspi
- // tRestore conflicts with tLDRspi
- // t2LEApcrelJT conflicts with t2LEApcrel
- // t2ADDrSPi/t2SUBrSPi have more generic couterparts
- if (Name == "tBfar" ||
- /* Name == "tCMNz" || */ Name == "tCMPzi8" || Name == "tCMPzr" ||
- Name == "tCMPzhir" || /* Name == "t2CMNzrr" || Name == "t2CMNzrs" ||
- Name == "t2CMNzri" || */ Name == "t2CMPzrr" || Name == "t2CMPzrs" ||
- Name == "t2CMPzri" || Name == "tPOP_RET" || Name == "t2LDM_RET" ||
- Name == "tMOVCCi" || Name == "tMOVCCr" || Name == "tBR_JTr" ||
- Name == "tSpill" || Name == "tLDRcp" || Name == "tRestore" ||
- Name == "t2LEApcrelJT" || Name == "t2ADDrSPi" || Name == "t2SUBrSPi")
- return false;
- }
-
- // Dumps the instruction encoding format.
- switch (TargetName) {
- case TARGET_ARM:
- case TARGET_THUMB:
- DEBUG(errs() << Name << " " << stringForARMFormat((ARMFormat)Form));
- break;
- }
-
- DEBUG({
- errs() << " ";
-
- // Dumps the instruction encoding bits.
- dumpBits(errs(), Bits);
-
- errs() << '\n';
-
- // Dumps the list of operand info.
- for (unsigned i = 0, e = CGI.OperandList.size(); i != e; ++i) {
- CodeGenInstruction::OperandInfo Info = CGI.OperandList[i];
- const std::string &OperandName = Info.Name;
- const Record &OperandDef = *Info.Rec;
-
- errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n";
- }
- });
-
- return true;
- }
-
- void populateInstructions() {
- getInstructionsByEnumValue(NumberedInstructions);
-
- uint16_t numUIDs = NumberedInstructions.size();
- uint16_t uid;
-
- const char *instClass = NULL;
-
- switch (TargetName) {
- case TARGET_ARM:
- instClass = "InstARM";
- break;
- default:
- assert(0 && "Unreachable code!");
- }
-
- for (uid = 0; uid < numUIDs; uid++) {
- // filter out intrinsics
- if (!NumberedInstructions[uid]->TheDef->isSubClassOf(instClass))
- continue;
-
- if (populateInstruction(*NumberedInstructions[uid], TargetName))
- Opcodes.push_back(uid);
- }
-
- // Special handling for the ARM chip, which supports two modes of execution.
- // This branch handles the Thumb opcodes.
- if (TargetName == TARGET_ARM) {
- for (uid = 0; uid < numUIDs; uid++) {
- // filter out intrinsics
- if (!NumberedInstructions[uid]->TheDef->isSubClassOf("InstARM")
- && !NumberedInstructions[uid]->TheDef->isSubClassOf("InstThumb"))
- continue;
-
- if (populateInstruction(*NumberedInstructions[uid], TARGET_THUMB))
- Opcodes2.push_back(uid);
- }
- }
- }
-
- // Emits disassembler code for instruction decoding. This delegates to the
- // FilterChooser instance to do the heavy lifting.
- void emit(raw_ostream &o) {
- Indenter i;
- std::string s;
- raw_string_ostream ro(s);
-
- switch (TargetName) {
- case TARGET_ARM:
- Frontend.EmitSourceFileHeader("ARM Disassembler", ro);
- break;
- default:
- assert(0 && "Unreachable code!");
- }
-
- ro.flush();
- o << s;
-
- o.indent(i) << "#include <inttypes.h>\n";
- o.indent(i) << "#include <assert.h>\n";
- o << '\n';
- o << "namespace llvm {\n\n";
-
- AbstractFilterChooser::setTargetName(TargetName);
-
- switch (TargetName) {
- case TARGET_ARM: {
- // Emit common utility and ARM ISA decoder.
- AFC = new FilterChooser<32>(NumberedInstructions, Opcodes);
- AFC->emitTop(o, i);
- delete AFC;
-
- // Emit Thumb ISA decoder as well.
- AbstractFilterChooser::setTargetName(TARGET_THUMB);
- AFC = new FilterChooser<32>(NumberedInstructions, Opcodes2);
- AFC->emitBot(o, i);
- break;
- }
- default:
- assert(0 && "Unreachable code!");
- }
-
- o << "\n} // End llvm namespace \n";
- }
-
-protected:
- std::vector<const CodeGenInstruction*> NumberedInstructions;
- std::vector<unsigned> Opcodes;
- // Special case for the ARM chip, which supports ARM and Thumb ISAs.
- // Opcodes2 will be populated with the Thumb opcodes.
- std::vector<unsigned> Opcodes2;
- RISCDisassemblerEmitter &Frontend;
- CodeGenTarget Target;
- AbstractFilterChooser *AFC;
-
- TARGET_NAME_t TargetName;
-};
-
-/////////////////////////
-// Backend interface //
-/////////////////////////
-
-void RISCDisassemblerEmitter::initBackend()
-{
- Backend = new RISCDEBackend(*this);
-}
-
-void RISCDisassemblerEmitter::run(raw_ostream &o)
-{
- Backend->emit(o);
-}
-
-void RISCDisassemblerEmitter::shutdownBackend()
-{
- delete Backend;
- Backend = NULL;
-}
Removed: llvm/trunk/utils/TableGen/RISCDisassemblerEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RISCDisassemblerEmitter.h?rev=98639&view=auto
==============================================================================
--- llvm/trunk/utils/TableGen/RISCDisassemblerEmitter.h (original)
+++ llvm/trunk/utils/TableGen/RISCDisassemblerEmitter.h (removed)
@@ -1,48 +0,0 @@
-//===- RISCDisassemblerEmitter.h - Disassembler Generator -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// FIXME: document
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef RISCDISASSEMBLEREMITTER_H
-#define RISCDISASSEMBLEREMITTER_H
-
-#include "TableGenBackend.h"
-
-#include <inttypes.h>
-
-namespace llvm {
-
-class RISCDisassemblerEmitter : public TableGenBackend {
- RecordKeeper &Records;
-public:
- RISCDisassemblerEmitter(RecordKeeper &R) : Records(R) {
- initBackend();
- }
-
- ~RISCDisassemblerEmitter() {
- shutdownBackend();
- }
-
- // run - Output the code emitter
- void run(raw_ostream &o);
-
-private:
- class RISCDEBackend;
-
- RISCDEBackend *Backend;
-
- void initBackend();
- void shutdownBackend();
-};
-
-} // end llvm namespace
-
-#endif
Modified: llvm/trunk/utils/TableGen/TableGen.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TableGen.cpp?rev=98640&r1=98639&r2=98640&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/TableGen.cpp (original)
+++ llvm/trunk/utils/TableGen/TableGen.cpp Tue Mar 16 11:59:47 2010
@@ -31,7 +31,6 @@
#include "OptParserEmitter.h"
#include "Record.h"
#include "RegisterInfoEmitter.h"
-#include "RISCDisassemblerEmitter.h"
#include "SubtargetEmitter.h"
#include "TGParser.h"
#include "llvm/Support/CommandLine.h"
@@ -49,7 +48,6 @@
GenEmitter,
GenRegisterEnums, GenRegister, GenRegisterHeader,
GenInstrEnums, GenInstrs, GenAsmWriter, GenAsmMatcher,
- GenRISCDisassembler,
GenDisassembler,
GenCallingConv,
GenClangDiagsDefs,
@@ -86,9 +84,6 @@
"Generate calling convention descriptions"),
clEnumValN(GenAsmWriter, "gen-asm-writer",
"Generate assembly writer"),
- clEnumValN(GenRISCDisassembler, "gen-risc-disassembler",
- "Generate disassembler for fixed instruction"
- " length"),
clEnumValN(GenDisassembler, "gen-disassembler",
"Generate disassembler"),
clEnumValN(GenAsmMatcher, "gen-asm-matcher",
@@ -234,9 +229,6 @@
case GenAsmWriter:
AsmWriterEmitter(Records).run(*Out);
break;
- case GenRISCDisassembler:
- RISCDisassemblerEmitter(Records).run(*Out);
- break;
case GenAsmMatcher:
AsmMatcherEmitter(Records).run(*Out);
break;
More information about the llvm-commits
mailing list