OpenASIP 2.2
Loading...
Searching...
No Matches
Classes | Typedefs | Functions
tpef2pasm.cc File Reference
#include <fstream>
#include <iostream>
#include <map>
#include "CompilerWarnings.hh"
#include "ADFSerializer.hh"
#include "Binary.hh"
#include "BinaryReader.hh"
#include "BinaryStream.hh"
#include "CmdLineOptions.hh"
#include "ControlUnit.hh"
#include "DataDefinition.hh"
#include "DataMemory.hh"
#include "DisassemblyInstruction.hh"
#include "FUPort.hh"
#include "FileSystem.hh"
#include "FunctionUnit.hh"
#include "HWOperation.hh"
#include "Immediate.hh"
#include "Instruction.hh"
#include "Move.hh"
#include "Operation.hh"
#include "POMDisassembler.hh"
#include "Procedure.hh"
#include "Program.hh"
#include "RegisterFile.hh"
#include "TPEFProgramFactory.hh"
#include "Terminal.hh"
#include "TerminalImmediate.hh"
#include "UniversalMachine.hh"
#include "tce_config.h"
Include dependency graph for tpef2pasm.cc:

Go to the source code of this file.

Classes

class  DisasmCmdLineOptions
 

Typedefs

typedef std::map< TCEString, std::map< int, TCEString > > PasmPacket
 

Functions

TTAMachine::FunctionUnitgetFunctionUnit (TTAMachine::Machine *machine, TCEString fuName)
 
TTAMachine::RegisterFilegetRegisterFile (TTAMachine::Machine *machine, TCEString rfName)
 
TCEString getPasmPacket (PasmPacket pkt, std::set< TCEString > fuSet, TCEString label="", bool printHeader=false)
 
TCEString getOutputPort (TTAMachine::FunctionUnit *fu, TCEString op)
 
int main (int argc, char *argv[])
 

Detailed Description

Blocks parallel disassembler.

Author
Kanishkan Vadivel 2021 (k.vadivel-no.spam-tue.nl)
Barry de Bruin 2021 (e.d.bruin-no.spam-tue.nl)
Note
rating: red

Definition in file tpef2pasm.cc.

Typedef Documentation

◆ PasmPacket

typedef std::map<TCEString, std::map<int, TCEString> > PasmPacket

Definition at line 74 of file tpef2pasm.cc.

Function Documentation

◆ getFunctionUnit()

TTAMachine::FunctionUnit * getFunctionUnit ( TTAMachine::Machine machine,
TCEString  fuName 
)

Get FunctionUnit object from FU name

Parameters
machineMachine for the search
fuNameName of the FU to search
Returns
FunctionUnit object

Definition at line 125 of file tpef2pasm.cc.

125 {
128 for (int i = 0; i < fuNav.count(); i++) {
129 if (fuNav.item(i)->name().ciEqual(fuName)) return fuNav.item(i);
130 }
131 return nullptr;
132}
TTAMachine::Machine * machine
the architecture definition of the estimated processor
ComponentType * item(int index) const
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380

References TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::Machine::Navigator< ComponentType >::item(), and machine.

Referenced by main().

Here is the call graph for this function:

◆ getOutputPort()

TCEString getOutputPort ( TTAMachine::FunctionUnit fu,
TCEString  op 
)

Get FU output Port name for operation

Parameters
fuFunctionUnit to search for instruction
opInstruction name to search
Returns
TCEString Output port name

Definition at line 251 of file tpef2pasm.cc.

251 {
252 TTAMachine::HWOperation* hwOp = fu->operation(op);
253 for (int i = hwOp->operandCount(); i > 0; i--) {
254 TTAMachine::FUPort* p = hwOp->port(i);
255 if (p->isOutput()) return p->name();
256 }
257 return "";
258}
virtual HWOperation * operation(const std::string &name) const
virtual FUPort * port(int operand) const
virtual bool isOutput() const
Definition Port.cc:308
virtual std::string name() const
Definition Port.cc:141

References TTAMachine::Port::isOutput(), TTAMachine::Port::name(), TTAMachine::HWOperation::operandCount(), TTAMachine::FunctionUnit::operation(), and TTAMachine::HWOperation::port().

Referenced by main().

Here is the call graph for this function:

◆ getPasmPacket()

TCEString getPasmPacket ( PasmPacket  pkt,
std::set< TCEString fuSet,
TCEString  label = "",
bool  printHeader = false 
)

Get RegisterFile object from RF name

Parameters
pktPASM instructions in map form
fuSetPasm header, list of FU names
labelProcedure start label
printHeaderName of the RF to search
Returns
TCEString PASM string

Definition at line 161 of file tpef2pasm.cc.

163 {
164 const int width = 32; // column width in spaces
165 TCEString pasm = "";
166 if (printHeader) {
167 // first row with FU names
168 pasm += "|";
169 for (auto& fu : fuSet) {
170 TCEString pasm_col = " " + fu;
171 int ntabs = width/4 - (pasm_col.size()+1)/4; // 1 tab = 4 spaces
172 for (int i = 0; i < ntabs; i++) pasm_col += "\t";
173 pasm += pasm_col + "|";
174 }
175 pasm += "\n";
176
177 // empty row
178 pasm += "|";
179 for (auto& fu : fuSet) {
180 int ntabs = width/4;
181 for (int i = 0; i < ntabs; i++) pasm += "\t";
182 pasm += "|";
183 }
184 pasm += "\n";
185
186 // .text row
187 pasm += "|";
188 for (auto& fu : fuSet) {
189 TCEString pasm_col = " .text";
190 int ntabs = width/4 - (pasm_col.size()+1)/4;
191 for (int i = 0; i < ntabs; i++) pasm_col += "\t";
192 pasm += pasm_col + "|";
193 }
194 pasm += "\n";
195
196 // empty row
197 pasm += "|";
198 for (auto& fu : fuSet) {
199 int ntabs = width/4;
200 for (int i = 0; i < ntabs; i++) pasm += "\t";
201 pasm += "|";
202 }
203 pasm += "\n";
204
205 } else {
206 pasm += "|";
207
208 int col_idx = 0;
209 for (auto& fu : fuSet) {
210 TCEString pasm_col = "";
211
212 if (!pkt.count(fu))
213 pasm_col += " nop";
214 else {
215 pkt[fu][0].replaceString("copy", "pass");
216 if (pkt[fu][0] == "jump" && pkt[fu][1] == fu+".ra") {
217 pkt[fu][0].replaceString("jump", "ret");
218 pkt[fu][1] = "";
219 }
220 TCEString instr = " " + pkt[fu][0] + " ";
221 for (unsigned op = 1; op < pkt[fu].size(); op++) {
222 instr += pkt[fu][op].replaceString(".ra", ".0"); // .ra register is mapped to out0 (non-registered)
223 if (pkt[fu][op] != "" && op < pkt[fu].size() - 1) instr += ", ";
224 }
225 pasm_col += instr;
226 }
227
228 // Add label to first column, when available
229 if (!label.empty() && col_idx++ == 0) {
230 pasm_col += " ; " + label;
231 }
232
233 // Fix length of column
234 int ntabs = width/4 - (pasm_col.size()+1)/4;
235 for (int i = 0; i < ntabs; i++) pasm_col += "\t"; // 1 tab = 4 spaces
236 pasm += pasm_col + "|";
237 }
238 pasm += "\n";
239 }
240 return pasm;
241}
TCEString & replaceString(const std::string &old, const std::string &newString)
Definition TCEString.cc:94

References TCEString::replaceString().

Referenced by main().

Here is the call graph for this function:

◆ getRegisterFile()

TTAMachine::RegisterFile * getRegisterFile ( TTAMachine::Machine machine,
TCEString  rfName 
)

Get RegisterFile object from RF name

Parameters
machineMachine for the search
rfNameName of the RF to search
Returns
RegisterFile object

Definition at line 142 of file tpef2pasm.cc.

142 {
145 for (int i = 0; i < rfNav.count(); i++) {
146 if (rfNav.item(i)->name().ciEqual(rfName)) return rfNav.item(i);
147 }
148 return nullptr;
149}
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450

References TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine, and TTAMachine::Machine::registerFileNavigator().

Referenced by main().

Here is the call graph for this function:

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 261 of file tpef2pasm.cc.

261 {
263
264 try {
265 options.parse(argv, argc);
266 } catch (ParserStopRequest const&) {
267 return 0;
268 } catch (IllegalCommandLine& e) {
269 std::cerr << "Error: Illegal commandline: " << e.errorMessage()
270 << endl
271 << endl;
272
274 return 1;
275 }
276
277 if (options.numberOfArguments() != 2) {
278 std::cerr << "Error: Illegal number of parameters." << endl << endl;
280 return 1;
281 }
282
283 std::string inputFileName = options.argument(2);
284 // Load TPEF.
285 TPEF::BinaryStream stream(inputFileName);
286 TPEF::Binary* tpef = NULL;
287 try {
288 tpef = TPEF::BinaryReader::readBinary(stream);
289 } catch (Exception& e) {
290 cerr << "Can't read TPEF binary file: " << options.argument(2) << endl
291 << e.errorMessage() << endl;
292 return 1;
293 }
294
295 // Load machine.
297 ADFSerializer machineReader;
298 machineReader.setSourceFile(options.argument(1));
299 try {
300 machine = machineReader.readMachine();
301 } catch (Exception& e) {
302 cerr << "Error: " << options.argument(1) << " is not a valid ADF File"
303 << endl
304 << e.errorMessage() << endl;
305
306 delete tpef;
307 return 1;
308 }
309
310 // Create blocks instruction packet header
311 std::set<TCEString> blocksFU;
319 for (int i = 0; i < fuNav.count(); i++) {
320 TCEString fuName = fuNav.item(i)->name();
321 blocksFU.insert(fuName.split("_out")[0]);
322 }
323 for (int i = 0; i < rfNav.count(); i++)
324 blocksFU.insert(rfNav.item(i)->name());
325 for (int i = 0; i < immNav.count(); i++)
326 blocksFU.insert(immNav.item(i)->name());
327 blocksFU.insert(abu->name());
328
329 // Create POM.
331
332 try {
334 program = factory.build();
335 } catch (Exception& e) {
336 // Try if mixed code
337 try {
340 program = factory.build();
341 } catch (Exception& e1) {
342 cerr << "Error: " << e.errorMessage() << " and "
343 << e1.errorMessage() << endl;
344 delete tpef;
345 delete machine;
346 return 1;
347 }
348 }
349
350 std::ostream* output = &std::cout;
351 std::fstream file;
352 std::string outputFileName = options.outputFileDefined()
353 ? options.outputFile()
354 : inputFileName + ".pasm";
355 if (!options.printToStdout()) {
359 file.open(
360 outputFileName.c_str(),
361 std::fstream::trunc | std::fstream::out);
362 output = &file;
364 file.open(
365 outputFileName.c_str(),
366 std::fstream::trunc | std::fstream::out);
367 if (file.is_open()) output = &file;
368 }
369 }
370
371 // Write code section disassembly.
372 POMDisassembler disassembler(*program);
373
374 // assumes instruction addresses always start from 0
375 PasmPacket pasmHeader;
376 TCEString pasm = getPasmPacket(pasmHeader, blocksFU, "", true);
377
378 // Write code section disassembly.
379 for (int p = 0; p < program->procedureCount(); p++) {
380 const TTAProgram::Procedure& proc = program->procedureAtIndex(p);
381 TCEString label = proc.name();
382
383 // Process each instruction
384 for (int i = 0; i < proc.instructionCount(); i++) {
386 // ASM map: {FU: {operand: asm}}
387 PasmPacket asmMap;
388
389 // Generate immediates
390 for (int j = 0; j < instr->immediateCount(); j++) {
391 TTAProgram::Immediate& imm = instr->immediate(j);
392 asmMap[imm.destination().immediateUnit().name()][0] = "imm";
393 asmMap[imm.destination().immediateUnit().name()][1] =
394 std::to_string(imm.value().value().intValue()); // signed value
395 }
396
397 // Generate instructions
398 for (int j = 0; j < instr->moveCount(); j++) {
399 TTAProgram::Move& m = instr->move(j);
400 TTAProgram::Terminal& src = m.source();
402
403 // Input source (bypass) of an operation
404 TCEString srcFUName =
405 src.port().parentUnit()->name().split("_out")[0];
406 TCEString srcPortName = src.port().name();
407 srcPortName = srcPortName.replaceString("out", "");
408 TCEString srcPort = srcFUName + "." + srcPortName;
409
410 // Operand port of FU
417
418 if (srcRF) { // found a load
419 if (!asmMap.count(srcRF->name())) {
420 asmMap[srcRF->name()][0] = "lrm";
421 } else if(asmMap[srcRF->name()][0] == "srm") { // if there is already a store
422 asmMap[srcRF->name()][0] = "lrm_srm";
423 }
424 asmMap[srcRF->name()][1] =
425 "r" + src.toString().split(".")[1];
426 }
427
428 if (dstRF) { // found a store
429 if (!asmMap.count(dstRF->name())) {
430 asmMap[dstRF->name()][0] = "srm";
431 } else if (asmMap[dstRF->name()][0] == "lrm") { // if there is already a load
432 asmMap[dstRF->name()][0] = "lrm_srm";
433 }
434 asmMap[dstRF->name()][2] =
435 "r" + dst.toString().split(".")[1];
436 asmMap[dstRF->name()][3] = srcPort;
437 } else if (dstFU) {
438 TCEString dstPort = dst.port().name();
439 dstPort = dstPort.replaceString("in", "");
440 TCEString dstFUName = dstFU->name().split("_out")[0];
441 if (dst.isTriggering()) {
442 TCEString opName = dst.toString().split(".")[2];
443 asmMap[dstFUName][0] = opName;
444 TCEString outPort = getOutputPort(dstFU, opName);
445 if (!outPort.empty())
446 asmMap[dstFUName][0] += " " + outPort + ",";
447 }
448 int inputPortID = std::stoi(dstPort.split("t")[0]);
449 asmMap[dstFUName][inputPortID] = srcPort;
450 } else {
451 // ABU move. Handle it based on Blocks assumptions
452 std::vector<TCEString> abuParm =
453 dst.toString().split(".");
454 TCEString dstFUName = abu->name().split("_out")[0];
455 if (dst.isRA()) {
456 // Convert to store to RF
457 asmMap[dstFUName][0] = "srm";
458 asmMap[dstFUName][1] = "r1"; // $RA
459 asmMap[dstFUName][2] = srcPort;
460 } else if (dst.isTriggering()) {
461 // Handle control flow calls
462 asmMap[dstFUName][0] = abuParm[2];
463 asmMap[dstFUName][1] = srcPort;
464 } else if (abuParm[1].ciEqual("value")) {
465 // Handle additional param
466 asmMap[dstFUName][2] = srcPort;
467 } else {
468 std::cout << "Parsing failed for: " + dst.toString()
469 << std::endl;
470 assert(false && "unknown format for abu op\n");
471 }
472 }
473 }
474 pasm += getPasmPacket(asmMap, blocksFU, label);
475 label.clear();
476 }
477 }
478 *output << pasm;
479 return 0;
480}
#define assert(condition)
static std::string outputFileName(const std::string &adfFile)
Definition CreateBEM.cc:77
find Finds info of the inner loops in the program
static MachInfoCmdLineOptions options
Definition MachInfo.cc:46
TTAMachine::Machine * readMachine()
void parse(char *argv[], int argc)
virtual std::string argument(int index) const
virtual int numberOfArguments() const
std::string errorMessage() const
Definition Exception.cc:123
static bool createFile(const std::string &file)
static bool fileIsWritable(const std::string fileName)
static bool fileIsCreatable(const std::string fileName)
static bool fileExists(const std::string fileName)
virtual void printHelp() const
int intValue() const
Definition SimValue.cc:895
std::vector< TCEString > split(const std::string &delim) const
Definition TCEString.cc:114
static Binary * readBinary(BinaryStream &stream)
virtual TCEString name() const
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition Machine.cc:416
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
Unit * parentUnit() const
virtual int instructionCount() const
virtual Instruction & instructionAtIndex(int index) const
TerminalImmediate & value() const
Definition Immediate.cc:103
const Terminal & destination() const
Definition Immediate.cc:92
Move & move(int i) const
Immediate & immediate(int i) const
Terminal & source() const
Definition Move.cc:302
Terminal & destination() const
Definition Move.cc:323
TCEString name() const
Definition Procedure.hh:66
virtual SimValue value() const
virtual bool isRA() const
Definition Terminal.cc:129
virtual bool isTriggering() const
Definition Terminal.cc:298
virtual TCEString toString() const =0
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
Definition Terminal.cc:240
static UniversalMachine & instance()
void setSourceFile(const std::string &fileName)
TCEString getPasmPacket(PasmPacket pkt, std::set< TCEString > fuSet, TCEString label="", bool printHeader=false)
Definition tpef2pasm.cc:161
TCEString getOutputPort(TTAMachine::FunctionUnit *fu, TCEString op)
Definition tpef2pasm.cc:251
std::map< TCEString, std::map< int, TCEString > > PasmPacket
Definition tpef2pasm.cc:74
TTAMachine::RegisterFile * getRegisterFile(TTAMachine::Machine *machine, TCEString rfName)
Definition tpef2pasm.cc:142
TTAMachine::FunctionUnit * getFunctionUnit(TTAMachine::Machine *machine, TCEString fuName)
Definition tpef2pasm.cc:125

References CmdLineParser::argument(), assert, TTAProgram::TPEFProgramFactory::build(), TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), FileSystem::createFile(), TTAProgram::Immediate::destination(), TTAProgram::Move::destination(), Exception::errorMessage(), FileSystem::fileExists(), FileSystem::fileIsCreatable(), FileSystem::fileIsWritable(), TTAMachine::Machine::functionUnitNavigator(), getFunctionUnit(), getOutputPort(), getPasmPacket(), getRegisterFile(), TTAProgram::Instruction::immediate(), TTAProgram::Instruction::immediateCount(), TTAProgram::Terminal::immediateUnit(), TTAMachine::Machine::immediateUnitNavigator(), UniversalMachine::instance(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), SimValue::intValue(), TTAProgram::Terminal::isRA(), TTAProgram::Terminal::isTriggering(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine, TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), TTAMachine::Component::name(), TTAMachine::Port::name(), TTAProgram::Procedure::name(), CmdLineParser::numberOfArguments(), options, outputFileName(), TTAMachine::Port::parentUnit(), CmdLineOptions::parse(), TTAProgram::Terminal::port(), MachInfoCmdLineOptions::printHelp(), program, TPEF::BinaryReader::readBinary(), ADFSerializer::readMachine(), TTAMachine::Machine::registerFileNavigator(), TCEString::replaceString(), XMLSerializer::setSourceFile(), TTAProgram::Move::source(), TCEString::split(), TTAProgram::Terminal::toString(), TTAProgram::Immediate::value(), and TTAProgram::TerminalImmediate::value().

Here is the call graph for this function: