1171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//===- MCModuleYAML.cpp - MCModule YAMLIO implementation ------------------===//
2171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//
3171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//                     The LLVM Compiler Infrastructure
4171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//
5171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// This file is distributed under the University of Illinois Open Source
6171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// License. See LICENSE.TXT for details.
7171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//
8171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//===----------------------------------------------------------------------===//
9171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//
10171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// This file defines classes for handling the YAML representation of MCModule.
11171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//
12171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//===----------------------------------------------------------------------===//
13171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
14cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCAnalysis/MCModuleYAML.h"
15171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha#include "llvm/ADT/StringMap.h"
16cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCAnalysis/MCAtom.h"
17cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCAnalysis/MCFunction.h"
18171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha#include "llvm/MC/MCInstrInfo.h"
19171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha#include "llvm/MC/MCRegisterInfo.h"
20cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/YAML.h"
21171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha#include "llvm/Support/Allocator.h"
22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/Casting.h"
23171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha#include "llvm/Support/MathExtras.h"
24171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha#include "llvm/Support/YAMLTraits.h"
25171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha#include <vector>
26171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
27171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachanamespace llvm {
28171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
29171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachanamespace {
30171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
31171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// This class is used to map opcode and register names to enum values.
32171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//
33171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// There are at least 3 obvious ways to do this:
34171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// 1- Generate an MII/MRI method using a tablegen StringMatcher
35171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// 2- Write an MII/MRI method using std::lower_bound and the assumption that
36171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//    the enums are sorted (starting at a fixed value).
37171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// 3- Do the matching manually as is done here.
38171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//
39171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// Why 3?
40171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// 1- A StringMatcher function for thousands of entries would incur
41171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//    a non-negligible binary size overhead.
42171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// 2- The lower_bound comparators would be somewhat involved and aren't
43171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//    obviously reusable (see LessRecordRegister in llvm/TableGen/Record.h)
44171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// 3- This isn't actually something useful outside tests (but the same argument
45171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//    can be made against having {MII,MRI}::getName).
46171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//
47171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// If this becomes useful outside this specific situation, feel free to do
48171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// the Right Thing (tm) and move the functionality to MII/MRI.
49171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha//
50171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachaclass InstrRegInfoHolder {
51171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  typedef StringMap<unsigned, BumpPtrAllocator> EnumValByNameTy;
52171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  EnumValByNameTy InstEnumValueByName;
53171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  EnumValByNameTy RegEnumValueByName;
54171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
55171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachapublic:
56171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  const MCInstrInfo &MII;
57171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  const MCRegisterInfo &MRI;
58171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  InstrRegInfoHolder(const MCInstrInfo &MII, const MCRegisterInfo &MRI)
59171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      : InstEnumValueByName(NextPowerOf2(MII.getNumOpcodes())),
60171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        RegEnumValueByName(NextPowerOf2(MRI.getNumRegs())), MII(MII), MRI(MRI) {
61171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    for (int i = 0, e = MII.getNumOpcodes(); i != e; ++i)
62171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      InstEnumValueByName[MII.getName(i)] = i;
63171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    for (int i = 0, e = MRI.getNumRegs(); i != e; ++i)
64171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      RegEnumValueByName[MRI.getName(i)] = i;
65171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  }
66171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
67171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  bool matchRegister(StringRef Name, unsigned &Reg) {
68171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    EnumValByNameTy::const_iterator It = RegEnumValueByName.find(Name);
69171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    if (It == RegEnumValueByName.end())
70171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      return false;
71171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    Reg = It->getValue();
72171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    return true;
73171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  }
74171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  bool matchOpcode(StringRef Name, unsigned &Opc) {
75171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    EnumValByNameTy::const_iterator It = InstEnumValueByName.find(Name);
76171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    if (It == InstEnumValueByName.end())
77171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      return false;
78171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    Opc = It->getValue();
79171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    return true;
80171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  }
81171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
82171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
83171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha} // end unnamed namespace
84171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
85171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachanamespace MCModuleYAML {
86171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
87171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaLLVM_YAML_STRONG_TYPEDEF(unsigned, OpcodeEnum)
88171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
89171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachastruct Operand {
90171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  MCOperand MCOp;
91171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
92171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
93171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachastruct Inst {
94171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  OpcodeEnum Opcode;
95171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  std::vector<Operand> Operands;
96171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  uint64_t Size;
97171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
98171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
99171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachastruct Atom {
100171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  MCAtom::AtomKind Type;
101171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  yaml::Hex64 StartAddress;
102171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  uint64_t Size;
103171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
104171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  std::vector<Inst> Insts;
105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  yaml::BinaryRef Data;
106171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
107171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
108171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachastruct BasicBlock {
109171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  yaml::Hex64 Address;
110171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  std::vector<yaml::Hex64> Preds;
111171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  std::vector<yaml::Hex64> Succs;
112171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
113171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
114171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachastruct Function {
115171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  StringRef Name;
116171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  std::vector<BasicBlock> BasicBlocks;
117171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
118171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
119171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachastruct Module {
120171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  std::vector<Atom> Atoms;
121171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  std::vector<Function> Functions;
122171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
123171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
124171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha} // end namespace MCModuleYAML
125171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha} // end namespace llvm
126171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
127171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaLLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex64)
128171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaLLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::MCModuleYAML::Operand)
129171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Inst)
130171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Atom)
131171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::BasicBlock)
132171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Function)
133171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
134171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachanamespace llvm {
135171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
136171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachanamespace yaml {
137171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
138171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachatemplate <> struct ScalarEnumerationTraits<MCAtom::AtomKind> {
139171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  static void enumeration(IO &IO, MCAtom::AtomKind &Kind);
140171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
141171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
142171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachatemplate <> struct MappingTraits<MCModuleYAML::Atom> {
143171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  static void mapping(IO &IO, MCModuleYAML::Atom &A);
144171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
145171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
146171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachatemplate <> struct MappingTraits<MCModuleYAML::Inst> {
147171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  static void mapping(IO &IO, MCModuleYAML::Inst &I);
148171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
149171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
150171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachatemplate <> struct MappingTraits<MCModuleYAML::BasicBlock> {
151171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  static void mapping(IO &IO, MCModuleYAML::BasicBlock &BB);
152171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
153171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
154171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachatemplate <> struct MappingTraits<MCModuleYAML::Function> {
155171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  static void mapping(IO &IO, MCModuleYAML::Function &Fn);
156171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
157171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
158171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachatemplate <> struct MappingTraits<MCModuleYAML::Module> {
159171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  static void mapping(IO &IO, MCModuleYAML::Module &M);
160171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
161171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
162171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachatemplate <> struct ScalarTraits<MCModuleYAML::Operand> {
163171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  static void output(const MCModuleYAML::Operand &, void *,
164171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha                     llvm::raw_ostream &);
165171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  static StringRef input(StringRef, void *, MCModuleYAML::Operand &);
166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  static bool mustQuote(StringRef) { return false; }
167171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
168171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
169171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachatemplate <> struct ScalarTraits<MCModuleYAML::OpcodeEnum> {
170171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  static void output(const MCModuleYAML::OpcodeEnum &, void *,
171171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha                     llvm::raw_ostream &);
172171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  static StringRef input(StringRef, void *, MCModuleYAML::OpcodeEnum &);
173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  static bool mustQuote(StringRef) { return false; }
174171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
175171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
176171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachavoid ScalarEnumerationTraits<MCAtom::AtomKind>::enumeration(
177171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    IO &IO, MCAtom::AtomKind &Value) {
178171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.enumCase(Value, "Text", MCAtom::TextAtom);
179171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.enumCase(Value, "Data", MCAtom::DataAtom);
180171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
181171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
182171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachavoid MappingTraits<MCModuleYAML::Atom>::mapping(IO &IO, MCModuleYAML::Atom &A) {
183171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("StartAddress", A.StartAddress);
184171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("Size", A.Size);
185171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("Type", A.Type);
186171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  if (A.Type == MCAtom::TextAtom)
187171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    IO.mapRequired("Content", A.Insts);
188171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  else if (A.Type == MCAtom::DataAtom)
189171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    IO.mapRequired("Content", A.Data);
190171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
191171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
192171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachavoid MappingTraits<MCModuleYAML::Inst>::mapping(IO &IO, MCModuleYAML::Inst &I) {
193171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("Inst", I.Opcode);
194171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("Size", I.Size);
195171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("Ops", I.Operands);
196171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
197171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
198171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachavoid
199171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaMappingTraits<MCModuleYAML::BasicBlock>::mapping(IO &IO,
200171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha                                                 MCModuleYAML::BasicBlock &BB) {
201171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("Address", BB.Address);
202171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("Preds", BB.Preds);
203171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("Succs", BB.Succs);
204171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
205171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
206171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachavoid MappingTraits<MCModuleYAML::Function>::mapping(IO &IO,
207171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha                                                    MCModuleYAML::Function &F) {
208171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("Name", F.Name);
209171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("BasicBlocks", F.BasicBlocks);
210171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
211171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
212171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachavoid MappingTraits<MCModuleYAML::Module>::mapping(IO &IO,
213171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha                                                  MCModuleYAML::Module &M) {
214171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapRequired("Atoms", M.Atoms);
215171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  IO.mapOptional("Functions", M.Functions);
216171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
217171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
218171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachavoid
219171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaScalarTraits<MCModuleYAML::Operand>::output(const MCModuleYAML::Operand &Val,
220171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha                                            void *Ctx, raw_ostream &Out) {
221171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
222171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
223171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  // FIXME: Doesn't support FPImm and expr/inst, but do these make sense?
224171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  if (Val.MCOp.isImm())
225171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    Out << "I" << Val.MCOp.getImm();
226171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  else if (Val.MCOp.isReg())
227171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    Out << "R" << IRI->MRI.getName(Val.MCOp.getReg());
228171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  else
229171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    llvm_unreachable("Trying to output invalid MCOperand!");
230171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
231171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
232171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaStringRef
233171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaScalarTraits<MCModuleYAML::Operand>::input(StringRef Scalar, void *Ctx,
234171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha                                           MCModuleYAML::Operand &Val) {
235171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
236171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  char Type = 0;
237171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  if (Scalar.size() >= 1)
238171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    Type = Scalar.front();
239171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  if (Type != 'R' && Type != 'I')
240171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    return "Operand must start with 'R' (register) or 'I' (immediate).";
241171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  if (Type == 'R') {
242171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    unsigned Reg;
243171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    if (!IRI->matchRegister(Scalar.substr(1), Reg))
244171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      return "Invalid register name.";
245171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    Val.MCOp = MCOperand::CreateReg(Reg);
246171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  } else if (Type == 'I') {
247171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    int64_t RIVal;
248171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    if (Scalar.substr(1).getAsInteger(10, RIVal))
249171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      return "Invalid immediate value.";
250171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    Val.MCOp = MCOperand::CreateImm(RIVal);
251171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  } else {
252171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    Val.MCOp = MCOperand();
253171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  }
254171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  return StringRef();
255171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
256171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
257171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachavoid ScalarTraits<MCModuleYAML::OpcodeEnum>::output(
258171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    const MCModuleYAML::OpcodeEnum &Val, void *Ctx, raw_ostream &Out) {
259171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
260171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  Out << IRI->MII.getName(Val);
261171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
262171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
263171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaStringRef
264171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaScalarTraits<MCModuleYAML::OpcodeEnum>::input(StringRef Scalar, void *Ctx,
265171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha                                              MCModuleYAML::OpcodeEnum &Val) {
266171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
267171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  unsigned Opc;
268171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  if (!IRI->matchOpcode(Scalar, Opc))
269171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    return "Invalid instruction opcode.";
270171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  Val = Opc;
271171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  return "";
272171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
273171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
274171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha} // end namespace yaml
275171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
276171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachanamespace {
277171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
278171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachaclass MCModule2YAML {
279171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  const MCModule &MCM;
280171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  MCModuleYAML::Module YAMLModule;
281171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  void dumpAtom(const MCAtom *MCA);
282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void dumpFunction(const MCFunction &MCF);
283171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  void dumpBasicBlock(const MCBasicBlock *MCBB);
284171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
285171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachapublic:
286171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  MCModule2YAML(const MCModule &MCM);
287171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  MCModuleYAML::Module &getYAMLModule();
288171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
289171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
290171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachaclass YAML2MCModule {
291171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  MCModule &MCM;
292171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
293171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachapublic:
294171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  YAML2MCModule(MCModule &MCM);
295171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  StringRef parse(const MCModuleYAML::Module &YAMLModule);
296171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha};
297171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
298171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha} // end unnamed namespace
299171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
300171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaMCModule2YAML::MCModule2YAML(const MCModule &MCM) : MCM(MCM), YAMLModule() {
301171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  for (MCModule::const_atom_iterator AI = MCM.atom_begin(), AE = MCM.atom_end();
302171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha       AI != AE; ++AI)
303171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    dumpAtom(*AI);
304171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  for (MCModule::const_func_iterator FI = MCM.func_begin(), FE = MCM.func_end();
305171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha       FI != FE; ++FI)
306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    dumpFunction(**FI);
307171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
308171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
309171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachavoid MCModule2YAML::dumpAtom(const MCAtom *MCA) {
310171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  YAMLModule.Atoms.resize(YAMLModule.Atoms.size() + 1);
311171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  MCModuleYAML::Atom &A = YAMLModule.Atoms.back();
312171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  A.Type = MCA->getKind();
313171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  A.StartAddress = MCA->getBeginAddr();
314171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  A.Size = MCA->getEndAddr() - MCA->getBeginAddr() + 1;
315171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  if (const MCTextAtom *TA = dyn_cast<MCTextAtom>(MCA)) {
316171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    const size_t InstCount = TA->size();
317171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    A.Insts.resize(InstCount);
318171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    for (size_t i = 0; i != InstCount; ++i) {
319171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      const MCDecodedInst &MCDI = TA->at(i);
320171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      A.Insts[i].Opcode = MCDI.Inst.getOpcode();
321171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      A.Insts[i].Size = MCDI.Size;
322171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      const unsigned OpCount = MCDI.Inst.getNumOperands();
323171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      A.Insts[i].Operands.resize(OpCount);
324171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      for (unsigned oi = 0; oi != OpCount; ++oi)
325171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        A.Insts[i].Operands[oi].MCOp = MCDI.Inst.getOperand(oi);
326171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    }
327171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  } else if (const MCDataAtom *DA = dyn_cast<MCDataAtom>(MCA)) {
328171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    A.Data = DA->getData();
329171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  } else {
330171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    llvm_unreachable("Unknown atom type.");
331171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  }
332171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
333171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MCModule2YAML::dumpFunction(const MCFunction &MCF) {
335171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  YAMLModule.Functions.resize(YAMLModule.Functions.size() + 1);
336171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  MCModuleYAML::Function &F = YAMLModule.Functions.back();
337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  F.Name = MCF.getName();
338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (MCFunction::const_iterator BBI = MCF.begin(), BBE = MCF.end();
339171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha       BBI != BBE; ++BBI) {
340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCBasicBlock &MCBB = **BBI;
341171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    F.BasicBlocks.resize(F.BasicBlocks.size() + 1);
342171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    MCModuleYAML::BasicBlock &BB = F.BasicBlocks.back();
343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BB.Address = MCBB.getInsts()->getBeginAddr();
344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (MCBasicBlock::pred_const_iterator PI = MCBB.pred_begin(),
345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                           PE = MCBB.pred_end();
346171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha         PI != PE; ++PI)
347171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      BB.Preds.push_back((*PI)->getInsts()->getBeginAddr());
348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (MCBasicBlock::succ_const_iterator SI = MCBB.succ_begin(),
349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                           SE = MCBB.succ_end();
350171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha         SI != SE; ++SI)
351171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      BB.Succs.push_back((*SI)->getInsts()->getBeginAddr());
352171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  }
353171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
354171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
355171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaMCModuleYAML::Module &MCModule2YAML::getYAMLModule() { return YAMLModule; }
356171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
357171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaYAML2MCModule::YAML2MCModule(MCModule &MCM) : MCM(MCM) {}
358171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
359171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaStringRef YAML2MCModule::parse(const MCModuleYAML::Module &YAMLModule) {
360171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  typedef std::vector<MCModuleYAML::Atom>::const_iterator AtomIt;
361171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  typedef std::vector<MCModuleYAML::Inst>::const_iterator InstIt;
362171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  typedef std::vector<MCModuleYAML::Operand>::const_iterator OpIt;
363171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
364171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  typedef DenseMap<uint64_t, MCTextAtom *> AddrToTextAtomTy;
365171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  AddrToTextAtomTy TAByAddr;
366171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
367171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  for (AtomIt AI = YAMLModule.Atoms.begin(), AE = YAMLModule.Atoms.end();
368171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha       AI != AE; ++AI) {
369171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    uint64_t StartAddress = AI->StartAddress;
370171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    if (AI->Size == 0)
371171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      return "Atoms can't be empty!";
372171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    uint64_t EndAddress = StartAddress + AI->Size - 1;
373171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    switch (AI->Type) {
374171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    case MCAtom::TextAtom: {
375171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      MCTextAtom *TA = MCM.createTextAtom(StartAddress, EndAddress);
376171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      TAByAddr[StartAddress] = TA;
377171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      for (InstIt II = AI->Insts.begin(), IE = AI->Insts.end(); II != IE;
378171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha           ++II) {
379171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        MCInst MI;
380171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        MI.setOpcode(II->Opcode);
381171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        for (OpIt OI = II->Operands.begin(), OE = II->Operands.end(); OI != OE;
382171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha             ++OI)
383171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha          MI.addOperand(OI->MCOp);
384171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        TA->addInst(MI, II->Size);
385171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      }
386171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      break;
387171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    }
388171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    case MCAtom::DataAtom: {
389171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      MCDataAtom *DA = MCM.createDataAtom(StartAddress, EndAddress);
390171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      SmallVector<char, 64> Data;
391171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      raw_svector_ostream OS(Data);
392171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      AI->Data.writeAsBinary(OS);
393171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      OS.flush();
394171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      for (size_t i = 0, e = Data.size(); i != e; ++i)
395171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        DA->addData((uint8_t)Data[i]);
396171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      break;
397171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    }
398171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    }
399171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  }
400171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
401171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  typedef std::vector<MCModuleYAML::Function>::const_iterator FuncIt;
402171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  typedef std::vector<MCModuleYAML::BasicBlock>::const_iterator BBIt;
403171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  typedef std::vector<yaml::Hex64>::const_iterator AddrIt;
404171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  for (FuncIt FI = YAMLModule.Functions.begin(),
405171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha              FE = YAMLModule.Functions.end();
406171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha       FI != FE; ++FI) {
407171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    MCFunction *MCFN = MCM.createFunction(FI->Name);
408171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    for (BBIt BBI = FI->BasicBlocks.begin(), BBE = FI->BasicBlocks.end();
409171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha         BBI != BBE; ++BBI) {
410171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      AddrToTextAtomTy::const_iterator It = TAByAddr.find(BBI->Address);
411171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      if (It == TAByAddr.end())
412171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        return "Basic block start address doesn't match any text atom!";
413171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      MCFN->createBlock(*It->second);
414171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    }
415171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    for (BBIt BBI = FI->BasicBlocks.begin(), BBE = FI->BasicBlocks.end();
416171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha         BBI != BBE; ++BBI) {
417171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      MCBasicBlock *MCBB = MCFN->find(BBI->Address);
418171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      if (!MCBB)
419171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        return "Couldn't find matching basic block in function.";
420171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      for (AddrIt PI = BBI->Preds.begin(), PE = BBI->Preds.end(); PI != PE;
421171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha           ++PI) {
422171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        MCBasicBlock *Pred = MCFN->find(*PI);
423171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        if (!Pred)
424171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha          return "Couldn't find predecessor basic block.";
425171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        MCBB->addPredecessor(Pred);
426171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      }
427171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      for (AddrIt SI = BBI->Succs.begin(), SE = BBI->Succs.end(); SI != SE;
428171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha           ++SI) {
429171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        MCBasicBlock *Succ = MCFN->find(*SI);
430171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        if (!Succ)
431171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha          return "Couldn't find predecessor basic block.";
432171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha        MCBB->addSuccessor(Succ);
433171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha      }
434171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    }
435171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  }
436171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  return "";
437171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
438171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
439171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaStringRef mcmodule2yaml(raw_ostream &OS, const MCModule &MCM,
440171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha                        const MCInstrInfo &MII, const MCRegisterInfo &MRI) {
441171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  MCModule2YAML Dumper(MCM);
442171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  InstrRegInfoHolder IRI(MII, MRI);
443171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  yaml::Output YOut(OS, (void *)&IRI);
444171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  YOut << Dumper.getYAMLModule();
445171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  return "";
446171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
447171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesStringRef yaml2mcmodule(std::unique_ptr<MCModule> &MCM, StringRef YamlContent,
449171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha                        const MCInstrInfo &MII, const MCRegisterInfo &MRI) {
450171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  MCM.reset(new MCModule);
451171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  YAML2MCModule Parser(*MCM);
452171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  MCModuleYAML::Module YAMLModule;
453171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  InstrRegInfoHolder IRI(MII, MRI);
454171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  yaml::Input YIn(YamlContent, (void *)&IRI);
455171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  YIn >> YAMLModule;
456cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (std::error_code ec = YIn.error())
457171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    return ec.message();
458171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  StringRef err = Parser.parse(YAMLModule);
459171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  if (!err.empty())
460171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha    return err;
461171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha  return "";
462171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha}
463171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
464171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha} // end namespace llvm
465