49 class InstrRegInfoHolder {
50 typedef StringMap<unsigned, BumpPtrAllocator> EnumValByNameTy;
55 const MCInstrInfo &
MII;
56 const MCRegisterInfo &
MRI;
57 InstrRegInfoHolder(
const MCInstrInfo &
MII,
const MCRegisterInfo &
MRI)
60 for (
int i = 0, e = MII.getNumOpcodes(); i != e; ++i)
62 for (
int i = 0, e = MRI.getNumRegs(); i != e; ++i)
66 bool matchRegister(StringRef
Name,
unsigned &
Reg) {
73 bool matchOpcode(StringRef Name,
unsigned &Opc) {
84 namespace MCModuleYAML {
168 static void output(
const MCModuleYAML::OpcodeEnum &,
void *,
175 IO.
enumCase(Value,
"Text", MCAtom::TextAtom);
176 IO.
enumCase(Value,
"Data", MCAtom::DataAtom);
183 if (A.
Type == MCAtom::TextAtom)
185 else if (A.
Type == MCAtom::DataAtom)
218 InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
224 Out <<
"R" << IRI->MRI.getName(Val.
MCOp.
getReg());
232 InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
234 if (Scalar.
size() >= 1)
235 Type = Scalar.
front();
236 if (Type !=
'R' && Type !=
'I')
237 return "Operand must start with 'R' (register) or 'I' (immediate).";
240 if (!IRI->matchRegister(Scalar.
substr(1),
Reg))
241 return "Invalid register name.";
242 Val.
MCOp = MCOperand::CreateReg(Reg);
243 }
else if (Type ==
'I') {
246 return "Invalid immediate value.";
247 Val.
MCOp = MCOperand::CreateImm(RIVal);
255 const MCModuleYAML::OpcodeEnum &Val,
void *Ctx,
raw_ostream &Out) {
256 InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
257 Out << IRI->MII.getName(Val);
262 MCModuleYAML::OpcodeEnum &Val) {
263 InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
265 if (!IRI->matchOpcode(Scalar, Opc))
266 return "Invalid instruction opcode.";
275 class MCModule2YAML {
278 void dumpAtom(
const MCAtom *MCA);
279 void dumpFunction(
const MCFunction *MCF);
280 void dumpBasicBlock(
const MCBasicBlock *MCBB);
283 MCModule2YAML(
const MCModule &
MCM);
284 MCModuleYAML::Module &getYAMLModule();
287 class YAML2MCModule {
291 YAML2MCModule(MCModule &
MCM);
297 MCModule2YAML::MCModule2YAML(
const MCModule &
MCM) : MCM(MCM),
YAMLModule() {
298 for (MCModule::const_atom_iterator AI = MCM.atom_begin(), AE = MCM.atom_end();
301 for (MCModule::const_func_iterator FI = MCM.func_begin(), FE = MCM.func_end();
306 void MCModule2YAML::dumpAtom(
const MCAtom *MCA) {
309 A.Type = MCA->getKind();
310 A.StartAddress = MCA->getBeginAddr();
311 A.Size = MCA->getEndAddr() - MCA->getBeginAddr() + 1;
312 if (
const MCTextAtom *
TA = dyn_cast<MCTextAtom>(MCA)) {
313 const size_t InstCount =
TA->size();
314 A.Insts.resize(InstCount);
315 for (
size_t i = 0; i != InstCount; ++i) {
316 const MCDecodedInst &MCDI =
TA->at(i);
317 A.Insts[i].Opcode = MCDI.Inst.getOpcode();
318 A.Insts[i].Size = MCDI.Size;
319 const unsigned OpCount = MCDI.Inst.getNumOperands();
320 A.Insts[i].Operands.resize(OpCount);
321 for (
unsigned oi = 0; oi != OpCount; ++oi)
322 A.Insts[i].Operands[oi].MCOp = MCDI.Inst.getOperand(oi);
324 }
else if (
const MCDataAtom *
DA = dyn_cast<MCDataAtom>(MCA)) {
325 A.Data =
DA->getData();
331 void MCModule2YAML::dumpFunction(
const MCFunction *MCF) {
333 MCModuleYAML::Function &
F =
YAMLModule.Functions.back();
334 F.Name = MCF->getName();
335 for (MCFunction::const_iterator BBI = MCF->begin(), BBE = MCF->end();
337 const MCBasicBlock *MCBB = *BBI;
338 F.BasicBlocks.resize(F.BasicBlocks.size() + 1);
340 BB.Address = MCBB->getInsts()->getBeginAddr();
341 for (MCBasicBlock::pred_const_iterator PI = MCBB->pred_begin(),
342 PE = MCBB->pred_end();
344 BB.Preds.push_back((*PI)->getInsts()->getBeginAddr());
346 SE = MCBB->succ_end();
348 BB.Succs.push_back((*SI)->getInsts()->getBeginAddr());
352 MCModuleYAML::Module &MCModule2YAML::getYAMLModule() {
return YAMLModule; }
354 YAML2MCModule::YAML2MCModule(MCModule &MCM) : MCM(MCM) {}
356 StringRef YAML2MCModule::parse(
const MCModuleYAML::Module &
YAMLModule) {
357 typedef std::vector<MCModuleYAML::Atom>::const_iterator AtomIt;
358 typedef std::vector<MCModuleYAML::Inst>::const_iterator InstIt;
359 typedef std::vector<MCModuleYAML::Operand>::const_iterator OpIt;
361 typedef DenseMap<uint64_t, MCTextAtom *> AddrToTextAtomTy;
362 AddrToTextAtomTy TAByAddr;
364 for (AtomIt AI = YAMLModule.Atoms.begin(), AE = YAMLModule.Atoms.end();
366 uint64_t StartAddress = AI->StartAddress;
368 return "Atoms can't be empty!";
369 uint64_t EndAddress = StartAddress + AI->Size - 1;
371 case MCAtom::TextAtom: {
372 MCTextAtom *
TA = MCM.createTextAtom(StartAddress, EndAddress);
373 TAByAddr[StartAddress] =
TA;
374 for (InstIt II = AI->Insts.begin(),
IE = AI->Insts.end(); II !=
IE;
377 MI.setOpcode(II->Opcode);
378 for (OpIt OI = II->Operands.begin(), OE = II->Operands.end(); OI != OE;
380 MI.addOperand(OI->MCOp);
381 TA->addInst(MI, II->Size);
385 case MCAtom::DataAtom: {
386 MCDataAtom *
DA = MCM.createDataAtom(StartAddress, EndAddress);
387 SmallVector<char, 64> Data;
388 raw_svector_ostream OS(Data);
389 AI->Data.writeAsBinary(OS);
391 for (
size_t i = 0, e = Data.size(); i != e; ++i)
392 DA->addData((uint8_t)Data[i]);
398 typedef std::vector<MCModuleYAML::Function>::const_iterator FuncIt;
399 typedef std::vector<MCModuleYAML::BasicBlock>::const_iterator BBIt;
400 typedef std::vector<yaml::Hex64>::const_iterator AddrIt;
401 for (FuncIt FI = YAMLModule.Functions.begin(),
402 FE = YAMLModule.Functions.end();
404 MCFunction *MCFN = MCM.createFunction(FI->Name);
405 for (BBIt BBI = FI->BasicBlocks.begin(), BBE = FI->BasicBlocks.end();
407 AddrToTextAtomTy::const_iterator It = TAByAddr.find(BBI->Address);
408 if (It == TAByAddr.end())
409 return "Basic block start address doesn't match any text atom!";
410 MCFN->createBlock(*It->second);
412 for (BBIt BBI = FI->BasicBlocks.begin(), BBE = FI->BasicBlocks.end();
414 MCBasicBlock *MCBB = MCFN->find(BBI->Address);
416 return "Couldn't find matching basic block in function.";
417 for (AddrIt PI = BBI->Preds.begin(), PE = BBI->Preds.end(); PI != PE;
419 MCBasicBlock *Pred = MCFN->find(*PI);
421 return "Couldn't find predecessor basic block.";
422 MCBB->addPredecessor(Pred);
424 for (AddrIt SI = BBI->Succs.begin(), SE = BBI->Succs.end(); SI != SE;
426 MCBasicBlock *Succ = MCFN->find(*SI);
428 return "Couldn't find predecessor basic block.";
429 MCBB->addSuccessor(Succ);
438 MCModule2YAML Dumper(MCM);
439 InstrRegInfoHolder IRI(MII, MRI);
441 YOut << Dumper.getYAMLModule();
448 YAML2MCModule Parser(*MCM);
450 InstrRegInfoHolder IRI(MII, MRI);
455 StringRef err = Parser.parse(YAMLModule);
SuccIterator< const TerminatorInst *, const BasicBlock > succ_const_iterator
EnumValByNameTy RegEnumValueByName
size_t size() const
size - Get the string size.
The main container class for the LLVM Intermediate Representation.
StringRef substr(size_t Start, size_t N=npos) const
iterator find(StringRef Key)
#define LLVM_YAML_IS_SEQUENCE_VECTOR(_type)
std::vector< BasicBlock > BasicBlocks
Specialized YAMLIO scalar type for representing a binary blob.
#define llvm_unreachable(msg)
std::vector< Atom > Atoms
std::vector< yaml::Hex64 > Succs
unsigned getReg() const
getReg - Returns the register number.
llvm::enable_if_c< has_SequenceTraits< T >::value, void >::type mapOptional(const char *Key, T &Val)
StringMapConstIterator< ValueTy > const_iterator
void enumCase(T &Val, const char *Str, const T ConstVal)
object::yaml::BinaryRef Data
LLVM Basic Block Representation.
This file declares classes for handling the YAML representation of MCModule.
std::vector< Function > Functions
enable_if_c< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
uint64_t NextPowerOf2(uint64_t A)
std::vector< Inst > Insts
#define LLVM_YAML_STRONG_TYPEDEF(_base, _type)
std::vector< yaml::Hex64 > Preds
std::vector< Operand > Operands
Represents a contiguous range of either instructions (a TextAtom) or data (a DataAtom). Address ranges are expressed as closed intervals.
StringRef mcmodule2yaml(raw_ostream &OS, const MCModule &MCM, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
Dump a YAML representation of the MCModule MCM to OS.
A completely disassembled object file or executable. It comprises a list of MCAtom's, each representing a contiguous range of either instructions or data. An MCModule is created using MCObjectDisassembler::buildModule.
#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type)
char front() const
front - Get the first character in the string.
StringRef yaml2mcmodule(OwningPtr< MCModule > &MCM, StringRef YamlContent, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
Creates a new module and returns it in MCM.
LLVM Value Representation.
MCModuleYAML::Module YAMLModule
void mapRequired(const char *Key, T &Val)
const MCRegisterInfo & MRI
bool empty() const
empty - Check if the string is empty.
EnumValByNameTy InstEnumValueByName