1ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//===-EDDisassembler.cpp - LLVM Enhanced Disassembler ---------------------===//
2ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//
3ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//                     The LLVM Compiler Infrastructure
4ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//
5ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// This file is distributed under the University of Illinois Open Source
6ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// License. See LICENSE.TXT for details.
7ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//
8ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//===----------------------------------------------------------------------===//
9ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//
10ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// This file implements the Enhanced Disassembly library's  disassembler class.
11ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// The disassembler is responsible for vending individual instructions according
12ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// to a given architecture and disassembly syntax.
13ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//
14ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//===----------------------------------------------------------------------===//
15ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
168f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan#include "EDDisassembler.h"
178f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan#include "EDInst.h"
189899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan#include "llvm/MC/EDInstInfo.h"
19ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCAsmInfo.h"
20ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCContext.h"
21ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCDisassembler.h"
22ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCExpr.h"
23ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCInst.h"
24ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCInstPrinter.h"
2517463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper#include "llvm/MC/MCInstrInfo.h"
260e6a052331f674dd70e28af41f654a7874405eabEvan Cheng#include "llvm/MC/MCRegisterInfo.h"
27ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCStreamer.h"
28ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng#include "llvm/MC/MCSubtargetInfo.h"
29ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/AsmLexer.h"
30ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/MCAsmParser.h"
31ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
3294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmLexer.h"
3394b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h"
34ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/MemoryBuffer.h"
35ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/MemoryObject.h"
36ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/SourceMgr.h"
373e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
38ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananusing namespace llvm;
39ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
40ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::DisassemblerMap_t EDDisassembler::sDisassemblers;
41ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
429899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callananstruct TripleMap {
43ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  Triple::ArchType Arch;
44ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  const char *String;
45ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan};
46ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
47e32981048244ecfa67d0bdc211af1bac2020a555Craig Topperstatic const struct TripleMap triplemap[] = {
489899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  { Triple::x86,          "i386-unknown-unknown"    },
499899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  { Triple::x86_64,       "x86_64-unknown-unknown"  },
509899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  { Triple::arm,          "arm-unknown-unknown"     },
51124e51c0d2b521b0fb3aaaf2443403cd451b7857Chandler Carruth  { Triple::thumb,        "thumb-unknown-unknown"   }
52ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan};
53ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
549899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan/// infoFromArch - Returns the TripleMap corresponding to a given architecture,
55ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan///   or NULL if there is an error
56ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan///
57ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg arch - The Triple::ArchType for the desired architecture
589899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callananstatic const char *tripleFromArch(Triple::ArchType arch) {
59ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  unsigned int infoIndex;
60ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
619899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  for (infoIndex = 0; triplemap[infoIndex].String != NULL; ++infoIndex) {
629899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan    if (arch == triplemap[infoIndex].Arch)
639899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan      return triplemap[infoIndex].String;
64ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
65ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
66ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return NULL;
67ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
68ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
69ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// getLLVMSyntaxVariant - gets the constant to use to get an assembly printer
70ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan///   for the desired assembly syntax, suitable for passing to
71ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan///   Target::createMCInstPrinter()
72ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan///
73ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg arch   - The target architecture
74ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg syntax - The assembly syntax in sd form
75ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananstatic int getLLVMSyntaxVariant(Triple::ArchType arch,
76847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner                                EDDisassembler::AssemblySyntax syntax) {
77ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  switch (syntax) {
78ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  // Mappings below from X86AsmPrinter.cpp
79847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner  case EDDisassembler::kEDAssemblySyntaxX86ATT:
80ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    if (arch == Triple::x86 || arch == Triple::x86_64)
81ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      return 0;
82e4ad58272970ecd850d233862f40a72d15649639Benjamin Kramer    break;
83847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner  case EDDisassembler::kEDAssemblySyntaxX86Intel:
84ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    if (arch == Triple::x86 || arch == Triple::x86_64)
85ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      return 1;
86e4ad58272970ecd850d233862f40a72d15649639Benjamin Kramer    break;
87847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner  case EDDisassembler::kEDAssemblySyntaxARMUAL:
888f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    if (arch == Triple::arm || arch == Triple::thumb)
898f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan      return 0;
90e4ad58272970ecd850d233862f40a72d15649639Benjamin Kramer    break;
91ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
92e4ad58272970ecd850d233862f40a72d15649639Benjamin Kramer
93e4ad58272970ecd850d233862f40a72d15649639Benjamin Kramer  return -1;
94ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
95ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
96ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
97847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner                                                AssemblySyntax syntax) {
983f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  const char *triple = tripleFromArch(arch);
993f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  return getDisassembler(StringRef(triple), syntax);
1003f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan}
1013f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan
1023f4f34c7ba24c3703a0cddf778183f7d876ac83fSean CallananEDDisassembler *EDDisassembler::getDisassembler(StringRef str,
1033f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan                                                AssemblySyntax syntax) {
104ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  CPUKey key;
1053f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  key.Triple = str.str();
106ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  key.Syntax = syntax;
107b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles
108ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  EDDisassembler::DisassemblerMap_t::iterator i = sDisassemblers.find(key);
109b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles
110ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (i != sDisassemblers.end()) {
1113f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan    return i->second;
1123f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  }
113b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles
114b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles  EDDisassembler *sdd = new EDDisassembler(key);
115b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles  if (!sdd->valid()) {
116b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles    delete sdd;
117b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles    return NULL;
118ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
119b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles
120b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles  sDisassemblers[key] = sdd;
121b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles
122b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles  return sdd;
123ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
124ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
125ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::EDDisassembler(CPUKey &key) :
1268f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  Valid(false),
1278f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  HasSemantics(false),
1288f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  ErrorStream(nulls()),
1293f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  Key(key),
1303f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  TgtTriple(key.Triple.c_str()) {
131ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
1323f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  LLVMSyntaxVariant = getLLVMSyntaxVariant(TgtTriple.getArch(), key.Syntax);
133ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
1344285b294a86f507822b8c00d85888e78f69672e5Sean Callanan  if (LLVMSyntaxVariant < 0)
135ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
136ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
1373f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  std::string tripleString(key.Triple);
138ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  std::string errorString;
139ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
1403f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  Tgt = TargetRegistry::lookupTarget(key.Triple,
141ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                                     errorString);
142ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
143ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (!Tgt)
144ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
145ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
1461b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng  MRI.reset(Tgt->createMCRegInfo(tripleString));
147ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
1481b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng  if (!MRI)
149ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
1501b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng
1511b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng  initMaps(*MRI);
152ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
1531abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng  AsmInfo.reset(Tgt->createMCAsmInfo(tripleString));
154ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
155ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (!AsmInfo)
156ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
157ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
158b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy  STI.reset(Tgt->createMCSubtargetInfo(tripleString, "", ""));
159b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy
160b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy  if (!STI)
161b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy    return;
162b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy
163b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy  Disassembler.reset(Tgt->createMCDisassembler(*STI));
164ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
165ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (!Disassembler)
166ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
1679899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan
1689899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  InstInfos = Disassembler->getEDInfo();
16917463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper
17017463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper  MII.reset(Tgt->createMCInstrInfo());
17117463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper
17217463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper  if (!MII)
17317463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper    return;
17417463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper
175ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  InstString.reset(new std::string);
176ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  InstStream.reset(new raw_string_ostream(*InstString));
177c6449b636f4984be88f128d0375c056ad05e7e8fJim Grosbach  InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo,
17817463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper                                             *MII, *MRI, *STI));
179ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
180ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (!InstPrinter)
181ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
182ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
183ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  GenericAsmLexer.reset(new AsmLexer(*AsmInfo));
18494b9550a32d189704a8eae55505edf62662c0534Evan Cheng  SpecificAsmLexer.reset(Tgt->createMCAsmLexer(*MRI, *AsmInfo));
185ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  SpecificAsmLexer->InstallLexer(*GenericAsmLexer);
186d74667e226c3053128f34c6f2c6c9ebfe5b98e50Sean Callanan
1871b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng  initMaps(*MRI);
188ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
189ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  Valid = true;
190ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
191ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
192ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::~EDDisassembler() {
1938f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  if (!valid())
194ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
195ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
196ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
197ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanannamespace {
198ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  /// EDMemoryObject - a subclass of MemoryObject that allows use of a callback
199ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  ///   as provided by the sd interface.  See MemoryObject.
200ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  class EDMemoryObject : public llvm::MemoryObject {
201ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  private:
202ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    EDByteReaderCallback Callback;
203ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    void *Arg;
204ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  public:
205ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    EDMemoryObject(EDByteReaderCallback callback,
206ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                   void *arg) : Callback(callback), Arg(arg) { }
207ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    ~EDMemoryObject() { }
208ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    uint64_t getBase() const { return 0x0; }
209adef06a71458ded0716935a61b3d43d164d4df12Derek Schuff    uint64_t getExtent() const { return (uint64_t)-1; }
210adef06a71458ded0716935a61b3d43d164d4df12Derek Schuff    int readByte(uint64_t address, uint8_t *ptr) const {
2118f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan      if (!Callback)
212ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan        return -1;
213ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
2148f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan      if (Callback(ptr, address, Arg))
215ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan        return -1;
216ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
217ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      return 0;
218ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    }
219ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  };
220ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
221ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
222ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDInst *EDDisassembler::createInst(EDByteReaderCallback byteReader,
223ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                                   uint64_t address,
224ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                                   void *arg) {
225ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  EDMemoryObject memoryObject(byteReader, arg);
226ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
227ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  MCInst* inst = new MCInst;
228ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  uint64_t byteSize;
229ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
230ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy  MCDisassembler::DecodeStatus S;
231ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy  S = Disassembler->getInstruction(*inst, byteSize, memoryObject, address,
23298c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson                                   ErrorStream, nulls());
233ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy  switch (S) {
234ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy  case MCDisassembler::Fail:
235ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy  case MCDisassembler::SoftFail:
236c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    // FIXME: Do something different on soft failure mode?
237ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    delete inst;
238ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return NULL;
239ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy
240ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy  case MCDisassembler::Success: {
241ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy    const llvm::EDInstInfo *thisInstInfo = NULL;
242833a003da082ab0db343e0e640069dfc6813e7d6Nick Lewycky
243ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy    if (InstInfos) {
244ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy      thisInstInfo = &InstInfos[inst->getOpcode()];
245ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy    }
246833a003da082ab0db343e0e640069dfc6813e7d6Nick Lewycky
247ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy    EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo);
248ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy    return sdInst;
249ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy  }
250ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy  }
251ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy  return NULL;
252ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
253ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
2541b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Chengvoid EDDisassembler::initMaps(const MCRegisterInfo &registerInfo) {
255ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  unsigned numRegisters = registerInfo.getNumRegs();
256ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  unsigned registerIndex;
257ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
258ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  for (registerIndex = 0; registerIndex < numRegisters; ++registerIndex) {
259d5ce3ffa67698b9d21f58011f370a210a214d301Jakob Stoklund Olesen    const char* registerName = registerInfo.getName(registerIndex);
260ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
261ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    RegVec.push_back(registerName);
262ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    RegRMap[registerName] = registerIndex;
263ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
264ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
2653f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  switch (TgtTriple.getArch()) {
2668f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  default:
2678f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    break;
2688f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::x86:
2698f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::x86_64:
270ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    stackPointers.insert(registerIDWithName("SP"));
271ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    stackPointers.insert(registerIDWithName("ESP"));
272ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    stackPointers.insert(registerIDWithName("RSP"));
273ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
274ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    programCounters.insert(registerIDWithName("IP"));
275ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    programCounters.insert(registerIDWithName("EIP"));
276ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    programCounters.insert(registerIDWithName("RIP"));
2778f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    break;
2788f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::arm:
2798f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::thumb:
2808f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    stackPointers.insert(registerIDWithName("SP"));
2818f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan
2828f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    programCounters.insert(registerIDWithName("PC"));
2838f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    break;
284ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
285ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
286ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
287ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananconst char *EDDisassembler::nameWithRegisterID(unsigned registerID) const {
288ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (registerID >= RegVec.size())
289ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return NULL;
290ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  else
291ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return RegVec[registerID].c_str();
292ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
293ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
294ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananunsigned EDDisassembler::registerIDWithName(const char *name) const {
295ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  regrmap_t::const_iterator iter = RegRMap.find(std::string(name));
296ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (iter == RegRMap.end())
297ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return 0;
298ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  else
299ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return (*iter).second;
300ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
301ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
302ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananbool EDDisassembler::registerIsStackPointer(unsigned registerID) {
303ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return (stackPointers.find(registerID) != stackPointers.end());
304ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
305ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
306ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananbool EDDisassembler::registerIsProgramCounter(unsigned registerID) {
307ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return (programCounters.find(registerID) != programCounters.end());
308ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
309ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
310d374087be5360a353a4239a155b1227057145f48Chris Lattnerint EDDisassembler::printInst(std::string &str, MCInst &inst) {
311ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  PrinterMutex.acquire();
312ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
31398c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson  InstPrinter->printInst(&inst, *InstStream, "");
314ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  InstStream->flush();
315ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  str = *InstString;
316ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  InstString->clear();
317ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
318ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  PrinterMutex.release();
319ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
320ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return 0;
321ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
322ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
323d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattnerstatic void diag_handler(const SMDiagnostic &diag, void *context) {
324d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner  if (context)
325d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner    diag.print("", static_cast<EDDisassembler*>(context)->ErrorStream);
326457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan}
327457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan
328ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananint EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
329ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                              SmallVectorImpl<AsmToken> &tokens,
330ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                              const std::string &str) {
331ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  int ret = 0;
332ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
3333f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  switch (TgtTriple.getArch()) {
3348f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  default:
3358f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    return -1;
3368f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::x86:
3378f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::x86_64:
3388f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::arm:
3398f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::thumb:
3408f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    break;
3418f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  }
3428f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan
343ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  const char *cStr = str.c_str();
344ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr));
345ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
346ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  StringRef instName;
347ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  SMLoc instLoc;
348ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
349ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  SourceMgr sourceMgr;
350457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan  sourceMgr.setDiagHandler(diag_handler, static_cast<void*>(this));
351ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over
352203576aa0cb9d8bf2d2e4d910ebab4b7a63262aeEvan Cheng  MCContext context(*AsmInfo, *MRI, NULL);
353c18409aed80ba1c6c5998befd3c3c8edc865c423Chris Lattner  OwningPtr<MCStreamer> streamer(createNullStreamer(context));
3541b84cce77f8bccc905b4800927ce9016f76c1c40Jim Grosbach  OwningPtr<MCAsmParser> genericParser(createMCAsmParser(sourceMgr,
3559fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar                                                         context, *streamer,
3569fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar                                                         *AsmInfo));
357ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
3583f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan  OwningPtr<MCSubtargetInfo> STI(Tgt->createMCSubtargetInfo(Key.Triple.c_str(), "", ""));
35994b9550a32d189704a8eae55505edf62662c0534Evan Cheng  OwningPtr<MCTargetAsmParser>
36094b9550a32d189704a8eae55505edf62662c0534Evan Cheng    TargetParser(Tgt->createMCAsmParser(*STI, *genericParser));
361ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
3629fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar  AsmToken OpcodeToken = genericParser->Lex();
3639fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar  AsmToken NextToken = genericParser->Lex();  // consume next token, because specificParser expects us to
364a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan
3658f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  if (OpcodeToken.is(AsmToken::Identifier)) {
366ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    instName = OpcodeToken.getString();
367ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    instLoc = OpcodeToken.getLoc();
368a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan
369a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan    if (NextToken.isNot(AsmToken::Eof) &&
370a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan        TargetParser->ParseInstruction(instName, instLoc, operands))
371ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      ret = -1;
3728f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  } else {
373ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    ret = -1;
374ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
375ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
376ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  ParserMutex.acquire();
377ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
378ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (!ret) {
379ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    GenericAsmLexer->setBuffer(buf);
380ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
381ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    while (SpecificAsmLexer->Lex(),
382ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan           SpecificAsmLexer->isNot(AsmToken::Eof) &&
383ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan           SpecificAsmLexer->isNot(AsmToken::EndOfStatement)) {
384ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      if (SpecificAsmLexer->is(AsmToken::Error)) {
385ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan        ret = -1;
386ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan        break;
387ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      }
388ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      tokens.push_back(SpecificAsmLexer->getTok());
389ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    }
390ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
391ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
392ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  ParserMutex.release();
393ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
394ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return ret;
395ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
396ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
397ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananint EDDisassembler::llvmSyntaxVariant() const {
398ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return LLVMSyntaxVariant;
399ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
400