1259698Sdim//===- MCModuleYAML.cpp - MCModule YAMLIO implementation ------------------===// 2259698Sdim// 3259698Sdim// The LLVM Compiler Infrastructure 4259698Sdim// 5259698Sdim// This file is distributed under the University of Illinois Open Source 6259698Sdim// License. See LICENSE.TXT for details. 7259698Sdim// 8259698Sdim//===----------------------------------------------------------------------===// 9259698Sdim// 10259698Sdim// This file defines classes for handling the YAML representation of MCModule. 11259698Sdim// 12259698Sdim//===----------------------------------------------------------------------===// 13259698Sdim 14259698Sdim#include "llvm/MC/MCModuleYAML.h" 15259698Sdim#include "llvm/ADT/StringMap.h" 16259698Sdim#include "llvm/MC/MCAtom.h" 17259698Sdim#include "llvm/MC/MCFunction.h" 18259698Sdim#include "llvm/MC/MCInstrInfo.h" 19259698Sdim#include "llvm/MC/MCRegisterInfo.h" 20259698Sdim#include "llvm/Object/YAML.h" 21259698Sdim#include "llvm/Support/Allocator.h" 22259698Sdim#include "llvm/Support/MathExtras.h" 23259698Sdim#include "llvm/Support/YAMLTraits.h" 24259698Sdim#include <vector> 25259698Sdim 26259698Sdimnamespace llvm { 27259698Sdim 28259698Sdimnamespace { 29259698Sdim 30259698Sdim// This class is used to map opcode and register names to enum values. 31259698Sdim// 32259698Sdim// There are at least 3 obvious ways to do this: 33259698Sdim// 1- Generate an MII/MRI method using a tablegen StringMatcher 34259698Sdim// 2- Write an MII/MRI method using std::lower_bound and the assumption that 35259698Sdim// the enums are sorted (starting at a fixed value). 36259698Sdim// 3- Do the matching manually as is done here. 37259698Sdim// 38259698Sdim// Why 3? 39259698Sdim// 1- A StringMatcher function for thousands of entries would incur 40259698Sdim// a non-negligible binary size overhead. 41259698Sdim// 2- The lower_bound comparators would be somewhat involved and aren't 42259698Sdim// obviously reusable (see LessRecordRegister in llvm/TableGen/Record.h) 43259698Sdim// 3- This isn't actually something useful outside tests (but the same argument 44259698Sdim// can be made against having {MII,MRI}::getName). 45259698Sdim// 46259698Sdim// If this becomes useful outside this specific situation, feel free to do 47259698Sdim// the Right Thing (tm) and move the functionality to MII/MRI. 48259698Sdim// 49259698Sdimclass InstrRegInfoHolder { 50259698Sdim typedef StringMap<unsigned, BumpPtrAllocator> EnumValByNameTy; 51259698Sdim EnumValByNameTy InstEnumValueByName; 52259698Sdim EnumValByNameTy RegEnumValueByName; 53259698Sdim 54259698Sdimpublic: 55259698Sdim const MCInstrInfo &MII; 56259698Sdim const MCRegisterInfo &MRI; 57259698Sdim InstrRegInfoHolder(const MCInstrInfo &MII, const MCRegisterInfo &MRI) 58259698Sdim : InstEnumValueByName(NextPowerOf2(MII.getNumOpcodes())), 59259698Sdim RegEnumValueByName(NextPowerOf2(MRI.getNumRegs())), MII(MII), MRI(MRI) { 60259698Sdim for (int i = 0, e = MII.getNumOpcodes(); i != e; ++i) 61259698Sdim InstEnumValueByName[MII.getName(i)] = i; 62259698Sdim for (int i = 0, e = MRI.getNumRegs(); i != e; ++i) 63259698Sdim RegEnumValueByName[MRI.getName(i)] = i; 64259698Sdim } 65259698Sdim 66259698Sdim bool matchRegister(StringRef Name, unsigned &Reg) { 67259698Sdim EnumValByNameTy::const_iterator It = RegEnumValueByName.find(Name); 68259698Sdim if (It == RegEnumValueByName.end()) 69259698Sdim return false; 70259698Sdim Reg = It->getValue(); 71259698Sdim return true; 72259698Sdim } 73259698Sdim bool matchOpcode(StringRef Name, unsigned &Opc) { 74259698Sdim EnumValByNameTy::const_iterator It = InstEnumValueByName.find(Name); 75259698Sdim if (It == InstEnumValueByName.end()) 76259698Sdim return false; 77259698Sdim Opc = It->getValue(); 78259698Sdim return true; 79259698Sdim } 80259698Sdim}; 81259698Sdim 82259698Sdim} // end unnamed namespace 83259698Sdim 84259698Sdimnamespace MCModuleYAML { 85259698Sdim 86259698SdimLLVM_YAML_STRONG_TYPEDEF(unsigned, OpcodeEnum) 87259698Sdim 88259698Sdimstruct Operand { 89259698Sdim MCOperand MCOp; 90259698Sdim}; 91259698Sdim 92259698Sdimstruct Inst { 93259698Sdim OpcodeEnum Opcode; 94259698Sdim std::vector<Operand> Operands; 95259698Sdim uint64_t Size; 96259698Sdim}; 97259698Sdim 98259698Sdimstruct Atom { 99259698Sdim MCAtom::AtomKind Type; 100259698Sdim yaml::Hex64 StartAddress; 101259698Sdim uint64_t Size; 102259698Sdim 103259698Sdim std::vector<Inst> Insts; 104259698Sdim object::yaml::BinaryRef Data; 105259698Sdim}; 106259698Sdim 107259698Sdimstruct BasicBlock { 108259698Sdim yaml::Hex64 Address; 109259698Sdim std::vector<yaml::Hex64> Preds; 110259698Sdim std::vector<yaml::Hex64> Succs; 111259698Sdim}; 112259698Sdim 113259698Sdimstruct Function { 114259698Sdim StringRef Name; 115259698Sdim std::vector<BasicBlock> BasicBlocks; 116259698Sdim}; 117259698Sdim 118259698Sdimstruct Module { 119259698Sdim std::vector<Atom> Atoms; 120259698Sdim std::vector<Function> Functions; 121259698Sdim}; 122259698Sdim 123259698Sdim} // end namespace MCModuleYAML 124259698Sdim} // end namespace llvm 125259698Sdim 126259698SdimLLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex64) 127259698SdimLLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::MCModuleYAML::Operand) 128259698SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Inst) 129259698SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Atom) 130259698SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::BasicBlock) 131259698SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Function) 132259698Sdim 133259698Sdimnamespace llvm { 134259698Sdim 135259698Sdimnamespace yaml { 136259698Sdim 137259698Sdimtemplate <> struct ScalarEnumerationTraits<MCAtom::AtomKind> { 138259698Sdim static void enumeration(IO &IO, MCAtom::AtomKind &Kind); 139259698Sdim}; 140259698Sdim 141259698Sdimtemplate <> struct MappingTraits<MCModuleYAML::Atom> { 142259698Sdim static void mapping(IO &IO, MCModuleYAML::Atom &A); 143259698Sdim}; 144259698Sdim 145259698Sdimtemplate <> struct MappingTraits<MCModuleYAML::Inst> { 146259698Sdim static void mapping(IO &IO, MCModuleYAML::Inst &I); 147259698Sdim}; 148259698Sdim 149259698Sdimtemplate <> struct MappingTraits<MCModuleYAML::BasicBlock> { 150259698Sdim static void mapping(IO &IO, MCModuleYAML::BasicBlock &BB); 151259698Sdim}; 152259698Sdim 153259698Sdimtemplate <> struct MappingTraits<MCModuleYAML::Function> { 154259698Sdim static void mapping(IO &IO, MCModuleYAML::Function &Fn); 155259698Sdim}; 156259698Sdim 157259698Sdimtemplate <> struct MappingTraits<MCModuleYAML::Module> { 158259698Sdim static void mapping(IO &IO, MCModuleYAML::Module &M); 159259698Sdim}; 160259698Sdim 161259698Sdimtemplate <> struct ScalarTraits<MCModuleYAML::Operand> { 162259698Sdim static void output(const MCModuleYAML::Operand &, void *, 163259698Sdim llvm::raw_ostream &); 164259698Sdim static StringRef input(StringRef, void *, MCModuleYAML::Operand &); 165259698Sdim}; 166259698Sdim 167259698Sdimtemplate <> struct ScalarTraits<MCModuleYAML::OpcodeEnum> { 168259698Sdim static void output(const MCModuleYAML::OpcodeEnum &, void *, 169259698Sdim llvm::raw_ostream &); 170259698Sdim static StringRef input(StringRef, void *, MCModuleYAML::OpcodeEnum &); 171259698Sdim}; 172259698Sdim 173259698Sdimvoid ScalarEnumerationTraits<MCAtom::AtomKind>::enumeration( 174259698Sdim IO &IO, MCAtom::AtomKind &Value) { 175259698Sdim IO.enumCase(Value, "Text", MCAtom::TextAtom); 176259698Sdim IO.enumCase(Value, "Data", MCAtom::DataAtom); 177259698Sdim} 178259698Sdim 179259698Sdimvoid MappingTraits<MCModuleYAML::Atom>::mapping(IO &IO, MCModuleYAML::Atom &A) { 180259698Sdim IO.mapRequired("StartAddress", A.StartAddress); 181259698Sdim IO.mapRequired("Size", A.Size); 182259698Sdim IO.mapRequired("Type", A.Type); 183259698Sdim if (A.Type == MCAtom::TextAtom) 184259698Sdim IO.mapRequired("Content", A.Insts); 185259698Sdim else if (A.Type == MCAtom::DataAtom) 186259698Sdim IO.mapRequired("Content", A.Data); 187259698Sdim} 188259698Sdim 189259698Sdimvoid MappingTraits<MCModuleYAML::Inst>::mapping(IO &IO, MCModuleYAML::Inst &I) { 190259698Sdim IO.mapRequired("Inst", I.Opcode); 191259698Sdim IO.mapRequired("Size", I.Size); 192259698Sdim IO.mapRequired("Ops", I.Operands); 193259698Sdim} 194259698Sdim 195259698Sdimvoid 196259698SdimMappingTraits<MCModuleYAML::BasicBlock>::mapping(IO &IO, 197259698Sdim MCModuleYAML::BasicBlock &BB) { 198259698Sdim IO.mapRequired("Address", BB.Address); 199259698Sdim IO.mapRequired("Preds", BB.Preds); 200259698Sdim IO.mapRequired("Succs", BB.Succs); 201259698Sdim} 202259698Sdim 203259698Sdimvoid MappingTraits<MCModuleYAML::Function>::mapping(IO &IO, 204259698Sdim MCModuleYAML::Function &F) { 205259698Sdim IO.mapRequired("Name", F.Name); 206259698Sdim IO.mapRequired("BasicBlocks", F.BasicBlocks); 207259698Sdim} 208259698Sdim 209259698Sdimvoid MappingTraits<MCModuleYAML::Module>::mapping(IO &IO, 210259698Sdim MCModuleYAML::Module &M) { 211259698Sdim IO.mapRequired("Atoms", M.Atoms); 212259698Sdim IO.mapOptional("Functions", M.Functions); 213259698Sdim} 214259698Sdim 215259698Sdimvoid 216259698SdimScalarTraits<MCModuleYAML::Operand>::output(const MCModuleYAML::Operand &Val, 217259698Sdim void *Ctx, raw_ostream &Out) { 218259698Sdim InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx; 219259698Sdim 220259698Sdim // FIXME: Doesn't support FPImm and expr/inst, but do these make sense? 221259698Sdim if (Val.MCOp.isImm()) 222259698Sdim Out << "I" << Val.MCOp.getImm(); 223259698Sdim else if (Val.MCOp.isReg()) 224259698Sdim Out << "R" << IRI->MRI.getName(Val.MCOp.getReg()); 225259698Sdim else 226259698Sdim llvm_unreachable("Trying to output invalid MCOperand!"); 227259698Sdim} 228259698Sdim 229259698SdimStringRef 230259698SdimScalarTraits<MCModuleYAML::Operand>::input(StringRef Scalar, void *Ctx, 231259698Sdim MCModuleYAML::Operand &Val) { 232259698Sdim InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx; 233259698Sdim char Type = 0; 234259698Sdim if (Scalar.size() >= 1) 235259698Sdim Type = Scalar.front(); 236259698Sdim if (Type != 'R' && Type != 'I') 237259698Sdim return "Operand must start with 'R' (register) or 'I' (immediate)."; 238259698Sdim if (Type == 'R') { 239259698Sdim unsigned Reg; 240259698Sdim if (!IRI->matchRegister(Scalar.substr(1), Reg)) 241259698Sdim return "Invalid register name."; 242259698Sdim Val.MCOp = MCOperand::CreateReg(Reg); 243259698Sdim } else if (Type == 'I') { 244259698Sdim int64_t RIVal; 245259698Sdim if (Scalar.substr(1).getAsInteger(10, RIVal)) 246259698Sdim return "Invalid immediate value."; 247259698Sdim Val.MCOp = MCOperand::CreateImm(RIVal); 248259698Sdim } else { 249259698Sdim Val.MCOp = MCOperand(); 250259698Sdim } 251259698Sdim return StringRef(); 252259698Sdim} 253259698Sdim 254259698Sdimvoid ScalarTraits<MCModuleYAML::OpcodeEnum>::output( 255259698Sdim const MCModuleYAML::OpcodeEnum &Val, void *Ctx, raw_ostream &Out) { 256259698Sdim InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx; 257259698Sdim Out << IRI->MII.getName(Val); 258259698Sdim} 259259698Sdim 260259698SdimStringRef 261259698SdimScalarTraits<MCModuleYAML::OpcodeEnum>::input(StringRef Scalar, void *Ctx, 262259698Sdim MCModuleYAML::OpcodeEnum &Val) { 263259698Sdim InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx; 264259698Sdim unsigned Opc; 265259698Sdim if (!IRI->matchOpcode(Scalar, Opc)) 266259698Sdim return "Invalid instruction opcode."; 267259698Sdim Val = Opc; 268259698Sdim return ""; 269259698Sdim} 270259698Sdim 271259698Sdim} // end namespace yaml 272259698Sdim 273259698Sdimnamespace { 274259698Sdim 275259698Sdimclass MCModule2YAML { 276259698Sdim const MCModule &MCM; 277259698Sdim MCModuleYAML::Module YAMLModule; 278259698Sdim void dumpAtom(const MCAtom *MCA); 279259698Sdim void dumpFunction(const MCFunction *MCF); 280259698Sdim void dumpBasicBlock(const MCBasicBlock *MCBB); 281259698Sdim 282259698Sdimpublic: 283259698Sdim MCModule2YAML(const MCModule &MCM); 284259698Sdim MCModuleYAML::Module &getYAMLModule(); 285259698Sdim}; 286259698Sdim 287259698Sdimclass YAML2MCModule { 288259698Sdim MCModule &MCM; 289259698Sdim 290259698Sdimpublic: 291259698Sdim YAML2MCModule(MCModule &MCM); 292259698Sdim StringRef parse(const MCModuleYAML::Module &YAMLModule); 293259698Sdim}; 294259698Sdim 295259698Sdim} // end unnamed namespace 296259698Sdim 297259698SdimMCModule2YAML::MCModule2YAML(const MCModule &MCM) : MCM(MCM), YAMLModule() { 298259698Sdim for (MCModule::const_atom_iterator AI = MCM.atom_begin(), AE = MCM.atom_end(); 299259698Sdim AI != AE; ++AI) 300259698Sdim dumpAtom(*AI); 301259698Sdim for (MCModule::const_func_iterator FI = MCM.func_begin(), FE = MCM.func_end(); 302259698Sdim FI != FE; ++FI) 303259698Sdim dumpFunction(*FI); 304259698Sdim} 305259698Sdim 306259698Sdimvoid MCModule2YAML::dumpAtom(const MCAtom *MCA) { 307259698Sdim YAMLModule.Atoms.resize(YAMLModule.Atoms.size() + 1); 308259698Sdim MCModuleYAML::Atom &A = YAMLModule.Atoms.back(); 309259698Sdim A.Type = MCA->getKind(); 310259698Sdim A.StartAddress = MCA->getBeginAddr(); 311259698Sdim A.Size = MCA->getEndAddr() - MCA->getBeginAddr() + 1; 312259698Sdim if (const MCTextAtom *TA = dyn_cast<MCTextAtom>(MCA)) { 313259698Sdim const size_t InstCount = TA->size(); 314259698Sdim A.Insts.resize(InstCount); 315259698Sdim for (size_t i = 0; i != InstCount; ++i) { 316259698Sdim const MCDecodedInst &MCDI = TA->at(i); 317259698Sdim A.Insts[i].Opcode = MCDI.Inst.getOpcode(); 318259698Sdim A.Insts[i].Size = MCDI.Size; 319259698Sdim const unsigned OpCount = MCDI.Inst.getNumOperands(); 320259698Sdim A.Insts[i].Operands.resize(OpCount); 321259698Sdim for (unsigned oi = 0; oi != OpCount; ++oi) 322259698Sdim A.Insts[i].Operands[oi].MCOp = MCDI.Inst.getOperand(oi); 323259698Sdim } 324259698Sdim } else if (const MCDataAtom *DA = dyn_cast<MCDataAtom>(MCA)) { 325259698Sdim A.Data = DA->getData(); 326259698Sdim } else { 327259698Sdim llvm_unreachable("Unknown atom type."); 328259698Sdim } 329259698Sdim} 330259698Sdim 331259698Sdimvoid MCModule2YAML::dumpFunction(const MCFunction *MCF) { 332259698Sdim YAMLModule.Functions.resize(YAMLModule.Functions.size() + 1); 333259698Sdim MCModuleYAML::Function &F = YAMLModule.Functions.back(); 334259698Sdim F.Name = MCF->getName(); 335259698Sdim for (MCFunction::const_iterator BBI = MCF->begin(), BBE = MCF->end(); 336259698Sdim BBI != BBE; ++BBI) { 337259698Sdim const MCBasicBlock *MCBB = *BBI; 338259698Sdim F.BasicBlocks.resize(F.BasicBlocks.size() + 1); 339259698Sdim MCModuleYAML::BasicBlock &BB = F.BasicBlocks.back(); 340259698Sdim BB.Address = MCBB->getInsts()->getBeginAddr(); 341259698Sdim for (MCBasicBlock::pred_const_iterator PI = MCBB->pred_begin(), 342259698Sdim PE = MCBB->pred_end(); 343259698Sdim PI != PE; ++PI) 344259698Sdim BB.Preds.push_back((*PI)->getInsts()->getBeginAddr()); 345259698Sdim for (MCBasicBlock::succ_const_iterator SI = MCBB->succ_begin(), 346259698Sdim SE = MCBB->succ_end(); 347259698Sdim SI != SE; ++SI) 348259698Sdim BB.Succs.push_back((*SI)->getInsts()->getBeginAddr()); 349259698Sdim } 350259698Sdim} 351259698Sdim 352259698SdimMCModuleYAML::Module &MCModule2YAML::getYAMLModule() { return YAMLModule; } 353259698Sdim 354259698SdimYAML2MCModule::YAML2MCModule(MCModule &MCM) : MCM(MCM) {} 355259698Sdim 356259698SdimStringRef YAML2MCModule::parse(const MCModuleYAML::Module &YAMLModule) { 357259698Sdim typedef std::vector<MCModuleYAML::Atom>::const_iterator AtomIt; 358259698Sdim typedef std::vector<MCModuleYAML::Inst>::const_iterator InstIt; 359259698Sdim typedef std::vector<MCModuleYAML::Operand>::const_iterator OpIt; 360259698Sdim 361259698Sdim typedef DenseMap<uint64_t, MCTextAtom *> AddrToTextAtomTy; 362259698Sdim AddrToTextAtomTy TAByAddr; 363259698Sdim 364259698Sdim for (AtomIt AI = YAMLModule.Atoms.begin(), AE = YAMLModule.Atoms.end(); 365259698Sdim AI != AE; ++AI) { 366259698Sdim uint64_t StartAddress = AI->StartAddress; 367259698Sdim if (AI->Size == 0) 368259698Sdim return "Atoms can't be empty!"; 369259698Sdim uint64_t EndAddress = StartAddress + AI->Size - 1; 370259698Sdim switch (AI->Type) { 371259698Sdim case MCAtom::TextAtom: { 372259698Sdim MCTextAtom *TA = MCM.createTextAtom(StartAddress, EndAddress); 373259698Sdim TAByAddr[StartAddress] = TA; 374259698Sdim for (InstIt II = AI->Insts.begin(), IE = AI->Insts.end(); II != IE; 375259698Sdim ++II) { 376259698Sdim MCInst MI; 377259698Sdim MI.setOpcode(II->Opcode); 378259698Sdim for (OpIt OI = II->Operands.begin(), OE = II->Operands.end(); OI != OE; 379259698Sdim ++OI) 380259698Sdim MI.addOperand(OI->MCOp); 381259698Sdim TA->addInst(MI, II->Size); 382259698Sdim } 383259698Sdim break; 384259698Sdim } 385259698Sdim case MCAtom::DataAtom: { 386259698Sdim MCDataAtom *DA = MCM.createDataAtom(StartAddress, EndAddress); 387259698Sdim SmallVector<char, 64> Data; 388259698Sdim raw_svector_ostream OS(Data); 389259698Sdim AI->Data.writeAsBinary(OS); 390259698Sdim OS.flush(); 391259698Sdim for (size_t i = 0, e = Data.size(); i != e; ++i) 392259698Sdim DA->addData((uint8_t)Data[i]); 393259698Sdim break; 394259698Sdim } 395259698Sdim } 396259698Sdim } 397259698Sdim 398259698Sdim typedef std::vector<MCModuleYAML::Function>::const_iterator FuncIt; 399259698Sdim typedef std::vector<MCModuleYAML::BasicBlock>::const_iterator BBIt; 400259698Sdim typedef std::vector<yaml::Hex64>::const_iterator AddrIt; 401259698Sdim for (FuncIt FI = YAMLModule.Functions.begin(), 402259698Sdim FE = YAMLModule.Functions.end(); 403259698Sdim FI != FE; ++FI) { 404259698Sdim MCFunction *MCFN = MCM.createFunction(FI->Name); 405259698Sdim for (BBIt BBI = FI->BasicBlocks.begin(), BBE = FI->BasicBlocks.end(); 406259698Sdim BBI != BBE; ++BBI) { 407259698Sdim AddrToTextAtomTy::const_iterator It = TAByAddr.find(BBI->Address); 408259698Sdim if (It == TAByAddr.end()) 409259698Sdim return "Basic block start address doesn't match any text atom!"; 410259698Sdim MCFN->createBlock(*It->second); 411259698Sdim } 412259698Sdim for (BBIt BBI = FI->BasicBlocks.begin(), BBE = FI->BasicBlocks.end(); 413259698Sdim BBI != BBE; ++BBI) { 414259698Sdim MCBasicBlock *MCBB = MCFN->find(BBI->Address); 415259698Sdim if (!MCBB) 416259698Sdim return "Couldn't find matching basic block in function."; 417259698Sdim for (AddrIt PI = BBI->Preds.begin(), PE = BBI->Preds.end(); PI != PE; 418259698Sdim ++PI) { 419259698Sdim MCBasicBlock *Pred = MCFN->find(*PI); 420259698Sdim if (!Pred) 421259698Sdim return "Couldn't find predecessor basic block."; 422259698Sdim MCBB->addPredecessor(Pred); 423259698Sdim } 424259698Sdim for (AddrIt SI = BBI->Succs.begin(), SE = BBI->Succs.end(); SI != SE; 425259698Sdim ++SI) { 426259698Sdim MCBasicBlock *Succ = MCFN->find(*SI); 427259698Sdim if (!Succ) 428259698Sdim return "Couldn't find predecessor basic block."; 429259698Sdim MCBB->addSuccessor(Succ); 430259698Sdim } 431259698Sdim } 432259698Sdim } 433259698Sdim return ""; 434259698Sdim} 435259698Sdim 436259698SdimStringRef mcmodule2yaml(raw_ostream &OS, const MCModule &MCM, 437259698Sdim const MCInstrInfo &MII, const MCRegisterInfo &MRI) { 438259698Sdim MCModule2YAML Dumper(MCM); 439259698Sdim InstrRegInfoHolder IRI(MII, MRI); 440259698Sdim yaml::Output YOut(OS, (void *)&IRI); 441259698Sdim YOut << Dumper.getYAMLModule(); 442259698Sdim return ""; 443259698Sdim} 444259698Sdim 445259698SdimStringRef yaml2mcmodule(OwningPtr<MCModule> &MCM, StringRef YamlContent, 446259698Sdim const MCInstrInfo &MII, const MCRegisterInfo &MRI) { 447259698Sdim MCM.reset(new MCModule); 448259698Sdim YAML2MCModule Parser(*MCM); 449259698Sdim MCModuleYAML::Module YAMLModule; 450259698Sdim InstrRegInfoHolder IRI(MII, MRI); 451259698Sdim yaml::Input YIn(YamlContent, (void *)&IRI); 452259698Sdim YIn >> YAMLModule; 453259698Sdim if (error_code ec = YIn.error()) 454259698Sdim return ec.message(); 455259698Sdim StringRef err = Parser.parse(YAMLModule); 456259698Sdim if (!err.empty()) 457259698Sdim return err; 458259698Sdim return ""; 459259698Sdim} 460259698Sdim 461259698Sdim} // end namespace llvm 462