1263320SdimPull in r198591 from upstream llvm trunk (by Venkatraman Govindaraju):
2263320Sdim
3263320Sdim  [Sparc] Add initial implementation of disassembler for sparc
4263320Sdim
5269012SemasteIntroduced here: http://svnweb.freebsd.org/changeset/base/262261
6263320Sdim
7263320SdimIndex: lib/Target/Sparc/SparcInstrFormats.td
8263320Sdim===================================================================
9263320Sdim--- lib/Target/Sparc/SparcInstrFormats.td
10263320Sdim+++ lib/Target/Sparc/SparcInstrFormats.td
11263320Sdim@@ -12,6 +12,7 @@ class InstSP<dag outs, dag ins, string asmstr, lis
12263320Sdim   field bits<32> Inst;
13263320Sdim 
14263320Sdim   let Namespace = "SP";
15263320Sdim+  let Size = 4;
16263320Sdim 
17263320Sdim   bits<2> op;
18263320Sdim   let Inst{31-30} = op;               // Top two bits are the 'op' field
19263320Sdim@@ -20,6 +21,9 @@ class InstSP<dag outs, dag ins, string asmstr, lis
20263320Sdim   dag InOperandList = ins;
21263320Sdim   let AsmString   = asmstr;
22263320Sdim   let Pattern = pattern;
23263320Sdim+
24263320Sdim+  let DecoderNamespace = "Sparc";
25263320Sdim+  field bits<32> SoftFail = 0;
26263320Sdim }
27263320Sdim 
28263320Sdim //===----------------------------------------------------------------------===//
29263320Sdim@@ -58,6 +62,27 @@ class F2_2<bits<3> op2Val, dag outs, dag ins, stri
30263320Sdim   let Inst{28-25} = cond;
31263320Sdim }
32263320Sdim 
33263320Sdim+class F2_3<bits<3> op2Val, bits<2> ccVal, dag outs, dag ins, string asmstr,
34263320Sdim+           list<dag> pattern>
35263320Sdim+   : InstSP<outs, ins, asmstr, pattern> {
36263320Sdim+  bit      annul;
37263320Sdim+  bits<4>  cond;
38263320Sdim+  bit      pred;
39263320Sdim+  bits<19> imm19;
40263320Sdim+
41263320Sdim+  let op          = 0;    // op = 0
42263320Sdim+
43263320Sdim+  bit annul       = 0;    // currently unused
44263320Sdim+  let pred        = 1;    // default is predict taken
45263320Sdim+
46263320Sdim+  let Inst{29}    = annul;
47263320Sdim+  let Inst{28-25} = cond;
48263320Sdim+  let Inst{24-22} = op2Val;
49263320Sdim+  let Inst{21-20} = ccVal;
50263320Sdim+  let Inst{19}    = pred;
51263320Sdim+  let Inst{18-0}  = imm19;
52263320Sdim+}
53263320Sdim+
54263320Sdim //===----------------------------------------------------------------------===//
55263320Sdim // Format #3 instruction classes in the Sparc
56263320Sdim //===----------------------------------------------------------------------===//
57263320SdimIndex: lib/Target/Sparc/LLVMBuild.txt
58263320Sdim===================================================================
59263320Sdim--- lib/Target/Sparc/LLVMBuild.txt
60263320Sdim+++ lib/Target/Sparc/LLVMBuild.txt
61263320Sdim@@ -16,13 +16,15 @@
62263320Sdim ;===------------------------------------------------------------------------===;
63263320Sdim 
64263320Sdim [common]
65263320Sdim-subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo
66263320Sdim+subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
67263320Sdim 
68263320Sdim [component_0]
69263320Sdim type = TargetGroup
70263320Sdim name = Sparc
71263320Sdim parent = Target
72263320Sdim+has_asmparser = 1
73263320Sdim has_asmprinter = 1
74263320Sdim+has_disassembler = 1
75263320Sdim has_jit = 1
76263320Sdim 
77263320Sdim [component_1]
78263320SdimIndex: lib/Target/Sparc/SparcInstrInfo.td
79263320Sdim===================================================================
80263320Sdim--- lib/Target/Sparc/SparcInstrInfo.td
81263320Sdim+++ lib/Target/Sparc/SparcInstrInfo.td
82263320Sdim@@ -230,13 +230,13 @@ def FCC_O   : FCC_VAL<29>;  // Ordered
83263320Sdim multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode,
84263320Sdim                  RegisterClass RC, ValueType Ty, Operand immOp> {
85263320Sdim   def rr  : F3_1<2, Op3Val,
86263320Sdim-                 (outs RC:$dst), (ins RC:$b, RC:$c),
87263320Sdim-                 !strconcat(OpcStr, " $b, $c, $dst"),
88263320Sdim-                 [(set Ty:$dst, (OpNode Ty:$b, Ty:$c))]>;
89263320Sdim+                 (outs RC:$rd), (ins RC:$rs1, RC:$rs2),
90263320Sdim+                 !strconcat(OpcStr, " $rs1, $rs2, $rd"),
91263320Sdim+                 [(set Ty:$rd, (OpNode Ty:$rs1, Ty:$rs2))]>;
92263320Sdim   def ri  : F3_2<2, Op3Val,
93263320Sdim-                 (outs RC:$dst), (ins RC:$b, immOp:$c),
94263320Sdim-                 !strconcat(OpcStr, " $b, $c, $dst"),
95263320Sdim-                 [(set Ty:$dst, (OpNode Ty:$b, (Ty simm13:$c)))]>;
96263320Sdim+                 (outs RC:$rd), (ins RC:$rs1, immOp:$simm13),
97263320Sdim+                 !strconcat(OpcStr, " $rs1, $simm13, $rd"),
98263320Sdim+                 [(set Ty:$rd, (OpNode Ty:$rs1, (Ty simm13:$simm13)))]>;
99263320Sdim }
100263320Sdim 
101263320Sdim /// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no
102263320Sdim@@ -243,11 +243,11 @@ multiclass F3_12<string OpcStr, bits<6> Op3Val, SD
103263320Sdim /// pattern.
104263320Sdim multiclass F3_12np<string OpcStr, bits<6> Op3Val> {
105263320Sdim   def rr  : F3_1<2, Op3Val,
106263320Sdim-                 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
107263320Sdim-                 !strconcat(OpcStr, " $b, $c, $dst"), []>;
108263320Sdim+                 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
109263320Sdim+                 !strconcat(OpcStr, " $rs1, $rs2, $rd"), []>;
110263320Sdim   def ri  : F3_2<2, Op3Val,
111263320Sdim-                 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
112263320Sdim-                 !strconcat(OpcStr, " $b, $c, $dst"), []>;
113263320Sdim+                 (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
114263320Sdim+                 !strconcat(OpcStr, " $rs1, $simm13, $rd"), []>;
115263320Sdim }
116263320Sdim 
117263320Sdim //===----------------------------------------------------------------------===//
118263320Sdim@@ -488,31 +488,31 @@ let rd = 0, imm22 = 0 in
119263320Sdim defm AND    : F3_12<"and", 0b000001, and, IntRegs, i32, i32imm>;
120263320Sdim 
121263320Sdim def ANDNrr  : F3_1<2, 0b000101,
122263320Sdim-                   (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
123263320Sdim-                   "andn $b, $c, $dst",
124263320Sdim-                   [(set i32:$dst, (and i32:$b, (not i32:$c)))]>;
125263320Sdim+                   (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
126263320Sdim+                   "andn $rs1, $rs2, $rd",
127263320Sdim+                   [(set i32:$rd, (and i32:$rs1, (not i32:$rs2)))]>;
128263320Sdim def ANDNri  : F3_2<2, 0b000101,
129263320Sdim-                   (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
130263320Sdim-                   "andn $b, $c, $dst", []>;
131263320Sdim+                   (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
132263320Sdim+                   "andn $rs1, $simm13, $rd", []>;
133263320Sdim 
134263320Sdim defm OR     : F3_12<"or", 0b000010, or, IntRegs, i32, i32imm>;
135263320Sdim 
136263320Sdim def ORNrr   : F3_1<2, 0b000110,
137263320Sdim-                   (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
138263320Sdim-                   "orn $b, $c, $dst",
139263320Sdim-                   [(set i32:$dst, (or i32:$b, (not i32:$c)))]>;
140263320Sdim+                   (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
141263320Sdim+                   "orn $rs1, $rs2, $rd",
142263320Sdim+                   [(set i32:$rd, (or i32:$rs1, (not i32:$rs2)))]>;
143263320Sdim def ORNri   : F3_2<2, 0b000110,
144263320Sdim-                   (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
145263320Sdim-                   "orn $b, $c, $dst", []>;
146263320Sdim+                   (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
147263320Sdim+                   "orn $rs1, $simm13, $rd", []>;
148263320Sdim defm XOR    : F3_12<"xor", 0b000011, xor, IntRegs, i32, i32imm>;
149263320Sdim 
150263320Sdim def XNORrr  : F3_1<2, 0b000111,
151263320Sdim-                   (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
152263320Sdim-                   "xnor $b, $c, $dst",
153263320Sdim-                   [(set i32:$dst, (not (xor i32:$b, i32:$c)))]>;
154263320Sdim+                   (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
155263320Sdim+                   "xnor $rs1, $rs2, $rd",
156263320Sdim+                   [(set i32:$rd, (not (xor i32:$rs1, i32:$rs2)))]>;
157263320Sdim def XNORri  : F3_2<2, 0b000111,
158263320Sdim-                   (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
159263320Sdim-                   "xnor $b, $c, $dst", []>;
160263320Sdim+                   (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
161263320Sdim+                   "xnor $rs1, $simm13, $rd", []>;
162263320Sdim 
163263320Sdim // Section B.12 - Shift Instructions, p. 107
164263320Sdim defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, i32imm>;
165263320Sdim@@ -545,21 +545,15 @@ let Defs = [ICC] in
166263320Sdim 
167263320Sdim let Defs = [ICC], rd = 0 in {
168263320Sdim   def CMPrr   : F3_1<2, 0b010100,
169263320Sdim-                     (outs), (ins IntRegs:$b, IntRegs:$c),
170263320Sdim-                     "cmp $b, $c",
171263320Sdim-                     [(SPcmpicc i32:$b, i32:$c)]>;
172263320Sdim+                     (outs), (ins IntRegs:$rs1, IntRegs:$rs2),
173263320Sdim+                     "cmp $rs1, $rs2",
174263320Sdim+                     [(SPcmpicc i32:$rs1, i32:$rs2)]>;
175263320Sdim   def CMPri   : F3_2<2, 0b010100,
176263320Sdim-                     (outs), (ins IntRegs:$b, i32imm:$c),
177263320Sdim-                     "cmp $b, $c",
178263320Sdim-                     [(SPcmpicc i32:$b, (i32 simm13:$c))]>;
179263320Sdim+                     (outs), (ins IntRegs:$rs1, i32imm:$simm13),
180263320Sdim+                     "cmp $rs1, $simm13",
181263320Sdim+                     [(SPcmpicc i32:$rs1, (i32 simm13:$simm13))]>;
182263320Sdim }
183263320Sdim 
184263320Sdim-let Uses = [ICC], Defs = [ICC] in
185263320Sdim-  def SUBXCCrr: F3_1<2, 0b011100,
186263320Sdim-                (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
187263320Sdim-                "subxcc $b, $c, $dst", []>;
188263320Sdim-
189263320Sdim-
190263320Sdim // Section B.18 - Multiply Instructions, p. 113
191263320Sdim let Defs = [Y] in {
192263320Sdim   defm UMUL : F3_12np<"umul", 0b001010>;
193263320Sdim@@ -858,7 +852,7 @@ let Defs = [FCC] in {
194263320Sdim //===----------------------------------------------------------------------===//
195263320Sdim // Instructions for Thread Local Storage(TLS).
196263320Sdim //===----------------------------------------------------------------------===//
197263320Sdim-
198263320Sdim+let isCodeGenOnly = 1, isAsmParserOnly = 1 in {
199263320Sdim def TLS_ADDrr : F3_1<2, 0b000000,
200263320Sdim                     (outs IntRegs:$rd),
201263320Sdim                     (ins IntRegs:$rs1, IntRegs:$rs2, TLSSym:$sym),
202263320Sdim@@ -882,6 +876,7 @@ let Uses = [O6], isCall = 1, hasDelaySlot = 1 in
203263320Sdim   let op = 1;
204263320Sdim   let Inst{29-0} = disp;
205263320Sdim }
206263320Sdim+}
207263320Sdim 
208263320Sdim //===----------------------------------------------------------------------===//
209263320Sdim // V9 Instructions
210263320SdimIndex: lib/Target/Sparc/CMakeLists.txt
211263320Sdim===================================================================
212263320Sdim--- lib/Target/Sparc/CMakeLists.txt
213263320Sdim+++ lib/Target/Sparc/CMakeLists.txt
214263320Sdim@@ -3,6 +3,7 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td)
215263320Sdim tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
216263320Sdim tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
217263320Sdim tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter)
218263320Sdim+tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler)
219263320Sdim tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter -mc-emitter)
220263320Sdim tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
221263320Sdim tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
222263320Sdim@@ -34,3 +35,4 @@ add_subdirectory(TargetInfo)
223263320Sdim add_subdirectory(MCTargetDesc)
224263320Sdim add_subdirectory(InstPrinter)
225263320Sdim add_subdirectory(AsmParser)
226263320Sdim+add_subdirectory(Disassembler)
227263320SdimIndex: lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
228263320Sdim===================================================================
229263320Sdim--- lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
230263320Sdim+++ lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
231263320Sdim@@ -0,0 +1,228 @@
232263320Sdim+//===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===//
233263320Sdim+//
234263320Sdim+//                     The LLVM Compiler Infrastructure
235263320Sdim+//
236263320Sdim+// This file is distributed under the University of Illinois Open Source
237263320Sdim+// License. See LICENSE.TXT for details.
238263320Sdim+//
239263320Sdim+//===----------------------------------------------------------------------===//
240263320Sdim+//
241263320Sdim+// This file is part of the Sparc Disassembler.
242263320Sdim+//
243263320Sdim+//===----------------------------------------------------------------------===//
244263320Sdim+
245263320Sdim+#define DEBUG_TYPE "sparc-disassembler"
246263320Sdim+
247263320Sdim+#include "Sparc.h"
248263320Sdim+#include "SparcRegisterInfo.h"
249263320Sdim+#include "SparcSubtarget.h"
250263320Sdim+#include "llvm/MC/MCDisassembler.h"
251263320Sdim+#include "llvm/MC/MCFixedLenDisassembler.h"
252263320Sdim+#include "llvm/Support/MemoryObject.h"
253263320Sdim+#include "llvm/Support/TargetRegistry.h"
254263320Sdim+
255263320Sdim+using namespace llvm;
256263320Sdim+
257263320Sdim+typedef MCDisassembler::DecodeStatus DecodeStatus;
258263320Sdim+
259263320Sdim+namespace {
260263320Sdim+
261263320Sdim+/// SparcDisassembler - a disassembler class for Sparc.
262263320Sdim+class SparcDisassembler : public MCDisassembler {
263263320Sdim+public:
264263320Sdim+  /// Constructor     - Initializes the disassembler.
265263320Sdim+  ///
266263320Sdim+  SparcDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) :
267263320Sdim+    MCDisassembler(STI), RegInfo(Info)
268263320Sdim+  {}
269263320Sdim+  virtual ~SparcDisassembler() {}
270263320Sdim+
271263320Sdim+  const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
272263320Sdim+
273263320Sdim+  /// getInstruction - See MCDisassembler.
274263320Sdim+  virtual DecodeStatus getInstruction(MCInst &instr,
275263320Sdim+                                      uint64_t &size,
276263320Sdim+                                      const MemoryObject &region,
277263320Sdim+                                      uint64_t address,
278263320Sdim+                                      raw_ostream &vStream,
279263320Sdim+                                      raw_ostream &cStream) const;
280263320Sdim+private:
281263320Sdim+  OwningPtr<const MCRegisterInfo> RegInfo;
282263320Sdim+};
283263320Sdim+
284263320Sdim+}
285263320Sdim+
286263320Sdim+namespace llvm {
287263320Sdim+  extern Target TheSparcTarget, TheSparcV9Target;
288263320Sdim+}
289263320Sdim+
290263320Sdim+static MCDisassembler *createSparcDisassembler(
291263320Sdim+                       const Target &T,
292263320Sdim+                       const MCSubtargetInfo &STI) {
293263320Sdim+  return new SparcDisassembler(STI, T.createMCRegInfo(""));
294263320Sdim+}
295263320Sdim+
296263320Sdim+
297263320Sdim+extern "C" void LLVMInitializeSparcDisassembler() {
298263320Sdim+  // Register the disassembler.
299263320Sdim+  TargetRegistry::RegisterMCDisassembler(TheSparcTarget,
300263320Sdim+                                         createSparcDisassembler);
301263320Sdim+  TargetRegistry::RegisterMCDisassembler(TheSparcV9Target,
302263320Sdim+                                         createSparcDisassembler);
303263320Sdim+}
304263320Sdim+
305263320Sdim+
306263320Sdim+
307263320Sdim+static const unsigned IntRegDecoderTable[] = {
308263320Sdim+  SP::G0,  SP::G1,  SP::G2,  SP::G3,
309263320Sdim+  SP::G4,  SP::G5,  SP::G6,  SP::G7,
310263320Sdim+  SP::O0,  SP::O1,  SP::O2,  SP::O3,
311263320Sdim+  SP::O4,  SP::O5,  SP::O6,  SP::O7,
312263320Sdim+  SP::L0,  SP::L1,  SP::L2,  SP::L3,
313263320Sdim+  SP::L4,  SP::L5,  SP::L6,  SP::L7,
314263320Sdim+  SP::I0,  SP::I1,  SP::I2,  SP::I3,
315263320Sdim+  SP::I4,  SP::I5,  SP::I6,  SP::I7 };
316263320Sdim+
317263320Sdim+static const unsigned FPRegDecoderTable[] = {
318263320Sdim+  SP::F0,   SP::F1,   SP::F2,   SP::F3,
319263320Sdim+  SP::F4,   SP::F5,   SP::F6,   SP::F7,
320263320Sdim+  SP::F8,   SP::F9,   SP::F10,  SP::F11,
321263320Sdim+  SP::F12,  SP::F13,  SP::F14,  SP::F15,
322263320Sdim+  SP::F16,  SP::F17,  SP::F18,  SP::F19,
323263320Sdim+  SP::F20,  SP::F21,  SP::F22,  SP::F23,
324263320Sdim+  SP::F24,  SP::F25,  SP::F26,  SP::F27,
325263320Sdim+  SP::F28,  SP::F29,  SP::F30,  SP::F31 };
326263320Sdim+
327263320Sdim+static const unsigned DFPRegDecoderTable[] = {
328263320Sdim+  SP::D0,   SP::D16,  SP::D1,   SP::D17,
329263320Sdim+  SP::D2,   SP::D18,  SP::D3,   SP::D19,
330263320Sdim+  SP::D4,   SP::D20,  SP::D5,   SP::D21,
331263320Sdim+  SP::D6,   SP::D22,  SP::D7,   SP::D23,
332263320Sdim+  SP::D8,   SP::D24,  SP::D9,   SP::D25,
333263320Sdim+  SP::D10,  SP::D26,  SP::D11,  SP::D27,
334263320Sdim+  SP::D12,  SP::D28,  SP::D13,  SP::D29,
335263320Sdim+  SP::D14,  SP::D30,  SP::D15,  SP::D31 };
336263320Sdim+
337263320Sdim+static const unsigned QFPRegDecoderTable[] = {
338263320Sdim+  SP::Q0,  SP::Q8,   -1, -1,
339263320Sdim+  SP::Q1,  SP::Q9,   -1, -1,
340263320Sdim+  SP::Q2,  SP::Q10,  -1, -1,
341263320Sdim+  SP::Q3,  SP::Q11,  -1, -1,
342263320Sdim+  SP::Q4,  SP::Q12,  -1, -1,
343263320Sdim+  SP::Q5,  SP::Q13,  -1, -1,
344263320Sdim+  SP::Q6,  SP::Q14,  -1, -1,
345263320Sdim+  SP::Q7,  SP::Q15,  -1, -1 } ;
346263320Sdim+
347263320Sdim+static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
348263320Sdim+                                               unsigned RegNo,
349263320Sdim+                                               uint64_t Address,
350263320Sdim+                                               const void *Decoder) {
351263320Sdim+  if (RegNo > 31)
352263320Sdim+    return MCDisassembler::Fail;
353263320Sdim+  unsigned Reg = IntRegDecoderTable[RegNo];
354263320Sdim+  Inst.addOperand(MCOperand::CreateReg(Reg));
355263320Sdim+  return MCDisassembler::Success;
356263320Sdim+}
357263320Sdim+
358263320Sdim+static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst,
359263320Sdim+                                               unsigned RegNo,
360263320Sdim+                                               uint64_t Address,
361263320Sdim+                                               const void *Decoder) {
362263320Sdim+  if (RegNo > 31)
363263320Sdim+    return MCDisassembler::Fail;
364263320Sdim+  unsigned Reg = IntRegDecoderTable[RegNo];
365263320Sdim+  Inst.addOperand(MCOperand::CreateReg(Reg));
366263320Sdim+  return MCDisassembler::Success;
367263320Sdim+}
368263320Sdim+
369263320Sdim+
370263320Sdim+static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst,
371263320Sdim+                                              unsigned RegNo,
372263320Sdim+                                              uint64_t Address,
373263320Sdim+                                              const void *Decoder) {
374263320Sdim+  if (RegNo > 31)
375263320Sdim+    return MCDisassembler::Fail;
376263320Sdim+  unsigned Reg = FPRegDecoderTable[RegNo];
377263320Sdim+  Inst.addOperand(MCOperand::CreateReg(Reg));
378263320Sdim+  return MCDisassembler::Success;
379263320Sdim+}
380263320Sdim+
381263320Sdim+
382263320Sdim+static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst,
383263320Sdim+                                               unsigned RegNo,
384263320Sdim+                                               uint64_t Address,
385263320Sdim+                                               const void *Decoder) {
386263320Sdim+  if (RegNo > 31)
387263320Sdim+    return MCDisassembler::Fail;
388263320Sdim+  unsigned Reg = DFPRegDecoderTable[RegNo];
389263320Sdim+  Inst.addOperand(MCOperand::CreateReg(Reg));
390263320Sdim+  return MCDisassembler::Success;
391263320Sdim+}
392263320Sdim+
393263320Sdim+
394263320Sdim+static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst,
395263320Sdim+                                               unsigned RegNo,
396263320Sdim+                                               uint64_t Address,
397263320Sdim+                                               const void *Decoder) {
398263320Sdim+  if (RegNo > 31)
399263320Sdim+    return MCDisassembler::Fail;
400263320Sdim+
401263320Sdim+  unsigned Reg = QFPRegDecoderTable[RegNo];
402263320Sdim+  if (Reg == (unsigned)-1)
403263320Sdim+    return MCDisassembler::Fail;
404263320Sdim+  Inst.addOperand(MCOperand::CreateReg(Reg));
405263320Sdim+  return MCDisassembler::Success;
406263320Sdim+}
407263320Sdim+
408263320Sdim+
409263320Sdim+#include "SparcGenDisassemblerTables.inc"
410263320Sdim+
411263320Sdim+/// readInstruction - read four bytes from the MemoryObject
412263320Sdim+/// and return 32 bit word.
413263320Sdim+static DecodeStatus readInstruction32(const MemoryObject &region,
414263320Sdim+                                      uint64_t address,
415263320Sdim+                                      uint64_t &size,
416263320Sdim+                                      uint32_t &insn) {
417263320Sdim+  uint8_t Bytes[4];
418263320Sdim+
419263320Sdim+  // We want to read exactly 4 Bytes of data.
420263320Sdim+  if (region.readBytes(address, 4, Bytes) == -1) {
421263320Sdim+    size = 0;
422263320Sdim+    return MCDisassembler::Fail;
423263320Sdim+  }
424263320Sdim+
425263320Sdim+  // Encoded as a big-endian 32-bit word in the stream.
426263320Sdim+  insn = (Bytes[3] <<  0) |
427263320Sdim+    (Bytes[2] <<  8) |
428263320Sdim+    (Bytes[1] << 16) |
429263320Sdim+    (Bytes[0] << 24);
430263320Sdim+
431263320Sdim+  return MCDisassembler::Success;
432263320Sdim+}
433263320Sdim+
434263320Sdim+
435263320Sdim+DecodeStatus
436263320Sdim+SparcDisassembler::getInstruction(MCInst &instr,
437263320Sdim+                                 uint64_t &Size,
438263320Sdim+                                 const MemoryObject &Region,
439263320Sdim+                                 uint64_t Address,
440263320Sdim+                                 raw_ostream &vStream,
441263320Sdim+                                 raw_ostream &cStream) const {
442263320Sdim+  uint32_t Insn;
443263320Sdim+
444263320Sdim+  DecodeStatus Result = readInstruction32(Region, Address, Size, Insn);
445263320Sdim+  if (Result == MCDisassembler::Fail)
446263320Sdim+    return MCDisassembler::Fail;
447263320Sdim+
448263320Sdim+
449263320Sdim+  // Calling the auto-generated decoder function.
450263320Sdim+  Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address,
451263320Sdim+                             this, STI);
452263320Sdim+
453263320Sdim+  if (Result != MCDisassembler::Fail) {
454263320Sdim+    Size = 4;
455263320Sdim+    return Result;
456263320Sdim+  }
457263320Sdim+
458263320Sdim+  return MCDisassembler::Fail;
459263320Sdim+}
460263320SdimIndex: lib/Target/Sparc/Disassembler/LLVMBuild.txt
461263320Sdim===================================================================
462263320Sdim--- lib/Target/Sparc/Disassembler/LLVMBuild.txt
463263320Sdim+++ lib/Target/Sparc/Disassembler/LLVMBuild.txt
464263320Sdim@@ -0,0 +1,23 @@
465263320Sdim+;===- ./lib/Target/Sparc/Disassembler/LLVMBuild.txt ------------*- Conf -*--===;
466263320Sdim+;
467263320Sdim+;                     The LLVM Compiler Infrastructure
468263320Sdim+;
469263320Sdim+; This file is distributed under the University of Illinois Open Source
470263320Sdim+; License. See LICENSE.TXT for details.
471263320Sdim+;
472263320Sdim+;===------------------------------------------------------------------------===;
473263320Sdim+;
474263320Sdim+; This is an LLVMBuild description file for the components in this subdirectory.
475263320Sdim+;
476263320Sdim+; For more information on the LLVMBuild system, please see:
477263320Sdim+;
478263320Sdim+;   http://llvm.org/docs/LLVMBuild.html
479263320Sdim+;
480263320Sdim+;===------------------------------------------------------------------------===;
481263320Sdim+
482263320Sdim+[component_0]
483263320Sdim+type = Library
484263320Sdim+name = SparcDisassembler
485263320Sdim+parent = Sparc
486263320Sdim+required_libraries = MC Support SparcInfo
487263320Sdim+add_to_library_groups = Sparc
488263320SdimIndex: lib/Target/Sparc/Disassembler/CMakeLists.txt
489263320Sdim===================================================================
490263320Sdim--- lib/Target/Sparc/Disassembler/CMakeLists.txt
491263320Sdim+++ lib/Target/Sparc/Disassembler/CMakeLists.txt
492263320Sdim@@ -0,0 +1,12 @@
493263320Sdim+add_llvm_library(LLVMSparcDisassembler
494263320Sdim+  SparcDisassembler.cpp
495263320Sdim+  )
496263320Sdim+
497263320Sdim+# workaround for hanging compilation on MSVC9 and 10
498263320Sdim+if( MSVC_VERSION EQUAL 1400 OR MSVC_VERSION EQUAL 1500
499263320Sdim+           OR MSVC_VERSION EQUAL 1600 )
500263320Sdim+set_property(
501263320Sdim+  SOURCE SparcDisassembler.cpp
502263320Sdim+  PROPERTY COMPILE_FLAGS "/Od"
503263320Sdim+  )
504263320Sdim+endif()
505263320SdimIndex: lib/Target/Sparc/Disassembler/Makefile
506263320Sdim===================================================================
507263320Sdim--- lib/Target/Sparc/Disassembler/Makefile
508263320Sdim+++ lib/Target/Sparc/Disassembler/Makefile
509263320Sdim@@ -0,0 +1,16 @@
510263320Sdim+##===- lib/Target/Sparc/Disassembler/Makefile --------------*- Makefile -*-===##
511263320Sdim+#
512263320Sdim+#                     The LLVM Compiler Infrastructure
513263320Sdim+#
514263320Sdim+# This file is distributed under the University of Illinois Open Source
515263320Sdim+# License. See LICENSE.TXT for details.
516263320Sdim+#
517263320Sdim+##===----------------------------------------------------------------------===##
518263320Sdim+
519263320Sdim+LEVEL = ../../../..
520263320Sdim+LIBRARYNAME = LLVMSparcDisassembler
521263320Sdim+
522263320Sdim+# Hack: we need to include 'main' Sparc target directory to grab private headers
523263320Sdim+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
524263320Sdim+
525263320Sdim+include $(LEVEL)/Makefile.common
526263320SdimIndex: lib/Target/Sparc/Makefile
527263320Sdim===================================================================
528263320Sdim--- lib/Target/Sparc/Makefile
529263320Sdim+++ lib/Target/Sparc/Makefile
530263320Sdim@@ -14,11 +14,11 @@ TARGET = Sparc
531263320Sdim # Make sure that tblgen is run, first thing.
532263320Sdim BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenInstrInfo.inc \
533263320Sdim 		SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \
534263320Sdim-		SparcGenDAGISel.inc \
535263320Sdim+		SparcGenDAGISel.inc SparcGenDisassemblerTables.inc \
536263320Sdim 		SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
537263320Sdim 		SparcGenCodeEmitter.inc SparcGenMCCodeEmitter.inc
538263320Sdim 
539263320Sdim-DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc
540263320Sdim+DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
541263320Sdim 
542263320Sdim include $(LEVEL)/Makefile.common
543263320Sdim 
544263320SdimIndex: lib/Target/Sparc/SparcInstr64Bit.td
545263320Sdim===================================================================
546263320Sdim--- lib/Target/Sparc/SparcInstr64Bit.td
547263320Sdim+++ lib/Target/Sparc/SparcInstr64Bit.td
548263320Sdim@@ -141,6 +141,7 @@ def : Pat<(i64 imm:$val),
549263320Sdim let Predicates = [Is64Bit] in {
550263320Sdim 
551263320Sdim // Register-register instructions.
552263320Sdim+let isCodeGenOnly = 1 in {
553263320Sdim defm ANDX    : F3_12<"and", 0b000001, and, I64Regs, i64, i64imm>;
554263320Sdim defm ORX     : F3_12<"or",  0b000010, or,  I64Regs, i64, i64imm>;
555263320Sdim defm XORX    : F3_12<"xor", 0b000011, xor, I64Regs, i64, i64imm>;
556263320Sdim@@ -161,8 +162,6 @@ def XNORXrr  : F3_1<2, 0b000111,
557263320Sdim defm ADDX    : F3_12<"add", 0b000000, add, I64Regs, i64, i64imm>;
558263320Sdim defm SUBX    : F3_12<"sub", 0b000100, sub, I64Regs, i64, i64imm>;
559263320Sdim 
560263320Sdim-def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>;
561263320Sdim-
562263320Sdim def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$rd),
563263320Sdim                    (ins I64Regs:$rs1, I64Regs:$rs2, TLSSym:$sym),
564263320Sdim                    "add $rs1, $rs2, $rd, $sym",
565263320Sdim@@ -169,18 +168,17 @@ def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$
566263320Sdim                    [(set i64:$rd,
567263320Sdim                        (tlsadd i64:$rs1, i64:$rs2, tglobaltlsaddr:$sym))]>;
568263320Sdim 
569263320Sdim-// Register-immediate instructions.
570263320Sdim-
571263320Sdim-def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>;
572263320Sdim-
573263320Sdim-def : Pat<(ctpop i64:$src), (POPCrr $src)>;
574263320Sdim-
575263320Sdim // "LEA" form of add
576263320Sdim-let isCodeGenOnly = 1 in
577263320Sdim def LEAX_ADDri : F3_2<2, 0b000000,
578263320Sdim                      (outs I64Regs:$dst), (ins MEMri:$addr),
579263320Sdim                      "add ${addr:arith}, $dst",
580263320Sdim                      [(set iPTR:$dst, ADDRri:$addr)]>;
581263320Sdim+}
582263320Sdim+
583263320Sdim+def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>;
584263320Sdim+def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>;
585263320Sdim+def : Pat<(ctpop i64:$src), (POPCrr $src)>;
586263320Sdim+
587263320Sdim } // Predicates = [Is64Bit]
588263320Sdim 
589263320Sdim 
590263320Sdim@@ -245,7 +243,7 @@ def LDXri  : F3_2<3, 0b001011,
591263320Sdim                   (outs I64Regs:$dst), (ins MEMri:$addr),
592263320Sdim                   "ldx [$addr], $dst",
593263320Sdim                   [(set i64:$dst, (load ADDRri:$addr))]>;
594263320Sdim-let mayLoad = 1 in
595263320Sdim+let mayLoad = 1, isCodeGenOnly = 1, isAsmParserOnly = 1 in
596263320Sdim   def TLS_LDXrr : F3_1<3, 0b001011,
597263320Sdim                        (outs IntRegs:$dst), (ins MEMrr:$addr, TLSSym:$sym),
598263320Sdim                        "ldx [$addr], $dst, $sym",
599263320Sdim@@ -278,11 +276,11 @@ def : Pat<(i64 (extloadi32 ADDRrr:$addr)),  (LDrr
600263320Sdim def : Pat<(i64 (extloadi32 ADDRri:$addr)),  (LDri ADDRri:$addr)>;
601263320Sdim 
602263320Sdim // Sign-extending load of i32 into i64 is a new SPARC v9 instruction.
603263320Sdim-def LDSWrr : F3_1<3, 0b001011,
604263320Sdim+def LDSWrr : F3_1<3, 0b001000,
605263320Sdim                  (outs I64Regs:$dst), (ins MEMrr:$addr),
606263320Sdim                  "ldsw [$addr], $dst",
607263320Sdim                  [(set i64:$dst, (sextloadi32 ADDRrr:$addr))]>;
608263320Sdim-def LDSWri : F3_2<3, 0b001011,
609263320Sdim+def LDSWri : F3_2<3, 0b001000,
610263320Sdim                  (outs I64Regs:$dst), (ins MEMri:$addr),
611263320Sdim                  "ldsw [$addr], $dst",
612263320Sdim                  [(set i64:$dst, (sextloadi32 ADDRri:$addr))]>;
613263320Sdim@@ -289,13 +287,13 @@ def : Pat<(i64 (extloadi32 ADDRri:$addr)),  (LDri
614263320Sdim 
615263320Sdim // 64-bit stores.
616263320Sdim def STXrr  : F3_1<3, 0b001110,
617263320Sdim-                 (outs), (ins MEMrr:$addr, I64Regs:$src),
618263320Sdim-                 "stx $src, [$addr]",
619263320Sdim-                 [(store i64:$src, ADDRrr:$addr)]>;
620263320Sdim+                 (outs), (ins MEMrr:$addr, I64Regs:$rd),
621263320Sdim+                 "stx $rd, [$addr]",
622263320Sdim+                 [(store i64:$rd, ADDRrr:$addr)]>;
623263320Sdim def STXri  : F3_2<3, 0b001110,
624263320Sdim-                 (outs), (ins MEMri:$addr, I64Regs:$src),
625263320Sdim-                 "stx $src, [$addr]",
626263320Sdim-                 [(store i64:$src, ADDRri:$addr)]>;
627263320Sdim+                 (outs), (ins MEMri:$addr, I64Regs:$rd),
628263320Sdim+                 "stx $rd, [$addr]",
629263320Sdim+                 [(store i64:$rd, ADDRri:$addr)]>;
630263320Sdim 
631263320Sdim // Truncating stores from i64 are identical to the i32 stores.
632263320Sdim def : Pat<(truncstorei8  i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>;
633263320Sdim@@ -315,6 +313,15 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADD
634263320Sdim //===----------------------------------------------------------------------===//
635263320Sdim // 64-bit Conditionals.
636263320Sdim //===----------------------------------------------------------------------===//
637263320Sdim+
638263320Sdim+// Conditional branch class on %xcc:
639263320Sdim+class XBranchSP<dag ins, string asmstr, list<dag> pattern>
640263320Sdim+  : F2_3<0b001, 0b10, (outs), ins, asmstr, pattern> {
641263320Sdim+  let isBranch = 1;
642263320Sdim+  let isTerminator = 1;
643263320Sdim+  let hasDelaySlot = 1;
644263320Sdim+}
645263320Sdim+
646263320Sdim //
647263320Sdim // Flag-setting instructions like subcc and addcc set both icc and xcc flags.
648263320Sdim // The icc flags correspond to the 32-bit result, and the xcc are for the
649263320Sdim@@ -326,7 +333,7 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADD
650263320Sdim let Predicates = [Is64Bit] in {
651263320Sdim 
652263320Sdim let Uses = [ICC] in
653263320Sdim-def BPXCC : BranchSP<(ins brtarget:$imm22, CCOp:$cond),
654263320Sdim+def BPXCC : XBranchSP<(ins brtarget:$imm22, CCOp:$cond),
655263320Sdim                      "b$cond %xcc, $imm22",
656263320Sdim                      [(SPbrxcc bb:$imm22, imm:$cond)]>;
657263320Sdim 
658263320Sdim@@ -409,7 +416,7 @@ def : Pat<(SPselectfcc (i64 simm11:$t), i64:$f, im
659263320Sdim 
660263320Sdim 
661263320Sdim // 64 bit SETHI
662263320Sdim-let Predicates = [Is64Bit] in {
663263320Sdim+let Predicates = [Is64Bit], isCodeGenOnly = 1 in {
664263320Sdim def SETHIXi : F2_1<0b100,
665263320Sdim                    (outs IntRegs:$rd), (ins i64imm:$imm22),
666263320Sdim                    "sethi $imm22, $rd",
667263320SdimIndex: test/MC/Disassembler/Sparc/lit.local.cfg
668263320Sdim===================================================================
669263320Sdim--- test/MC/Disassembler/Sparc/lit.local.cfg
670263320Sdim+++ test/MC/Disassembler/Sparc/lit.local.cfg
671263320Sdim@@ -0,0 +1,4 @@
672263320Sdim+targets = set(config.root.targets_to_build.split())
673263320Sdim+if not 'Sparc' in targets:
674263320Sdim+    config.unsupported = True
675263320Sdim+
676263320SdimIndex: test/MC/Disassembler/Sparc/sparc.txt
677263320Sdim===================================================================
678263320Sdim--- test/MC/Disassembler/Sparc/sparc.txt
679263320Sdim+++ test/MC/Disassembler/Sparc/sparc.txt
680263320Sdim@@ -0,0 +1,82 @@
681263320Sdim+# RUN: llvm-mc --disassemble %s -triple=sparc-unknown-linux | FileCheck %s
682263320Sdim+
683263320Sdim+# CHECK: add %g0, %g0, %g0
684263320Sdim+0x80 0x00 0x00 0x00
685263320Sdim+
686263320Sdim+# CHECK: add %g1, %g2, %g3
687263320Sdim+0x86 0x00 0x40 0x02
688263320Sdim+
689263320Sdim+# CHECK: add %o0, %o1, %l0
690263320Sdim+0xa0 0x02 0x00 0x09
691263320Sdim+
692263320Sdim+# CHECK: add %o0, 10,  %l0
693263320Sdim+0xa0 0x02 0x20 0x0a
694263320Sdim+
695263320Sdim+# CHECK: addcc %g1, %g2, %g3
696263320Sdim+0x86 0x80 0x40 0x02
697263320Sdim+
698263320Sdim+# CHECK: addxcc %g1, %g2, %g3
699263320Sdim+0x86 0xc0 0x40 0x02
700263320Sdim+
701263320Sdim+# CHECK: udiv %g1, %g2, %g3
702263320Sdim+0x86 0x70 0x40 0x02
703263320Sdim+
704263320Sdim+# CHECK: sdiv %g1, %g2, %g3
705263320Sdim+0x86 0x78 0x40 0x02
706263320Sdim+
707263320Sdim+# CHECK: and %g1, %g2, %g3
708263320Sdim+0x86 0x08 0x40 0x02
709263320Sdim+
710263320Sdim+# CHECK: andn %g1, %g2, %g3
711263320Sdim+0x86 0x28 0x40 0x02
712263320Sdim+
713263320Sdim+# CHECK: or %g1, %g2, %g3
714263320Sdim+0x86 0x10 0x40 0x02
715263320Sdim+
716263320Sdim+# CHECK: orn %g1, %g2, %g3
717263320Sdim+0x86 0x30 0x40 0x02
718263320Sdim+
719263320Sdim+# CHECK: xor %g1, %g2, %g3
720263320Sdim+0x86 0x18 0x40 0x02
721263320Sdim+
722263320Sdim+# CHECK: xnor %g1, %g2, %g3
723263320Sdim+0x86 0x38 0x40 0x02
724263320Sdim+
725263320Sdim+# CHECK: umul %g1, %g2, %g3
726263320Sdim+0x86 0x50 0x40 0x02
727263320Sdim+
728263320Sdim+# CHECK: smul %g1, %g2, %g3
729263320Sdim+0x86 0x58 0x40 0x02
730263320Sdim+
731263320Sdim+# CHECK: nop
732263320Sdim+0x01 0x00 0x00 0x00
733263320Sdim+
734263320Sdim+# CHECK: sethi 10, %l0
735263320Sdim+0x21 0x00 0x00 0x0a
736263320Sdim+
737263320Sdim+# CHECK: sll %g1, %g2, %g3
738263320Sdim+0x87 0x28 0x40 0x02
739263320Sdim+
740263320Sdim+# CHECK: sll %g1, 31, %g3
741263320Sdim+0x87 0x28 0x60 0x1f
742263320Sdim+
743263320Sdim+# CHECK: srl %g1, %g2, %g3
744263320Sdim+0x87 0x30 0x40 0x02
745263320Sdim+
746263320Sdim+# CHECK: srl %g1, 31, %g3
747263320Sdim+0x87 0x30 0x60 0x1f
748263320Sdim+
749263320Sdim+# CHECK: sra %g1, %g2, %g3
750263320Sdim+0x87 0x38 0x40 0x02
751263320Sdim+
752263320Sdim+# CHECK: sra %g1, 31, %g3
753263320Sdim+0x87 0x38 0x60 0x1f
754263320Sdim+
755263320Sdim+# CHECK: sub %g1, %g2, %g3
756263320Sdim+0x86 0x20 0x40 0x02
757263320Sdim+
758263320Sdim+# CHECK: subcc %g1, %g2, %g3
759263320Sdim+0x86 0xa0 0x40 0x02
760263320Sdim+
761263320Sdim+# CHECK: subxcc %g1, %g2, %g3
762263320Sdim+0x86 0xe0 0x40 0x02
763