186 const std::string& programName,
187 std::ostream& stream,
191 if (mausPerLine < 0) {
192 string errorMsg =
"Negative number of MAUs printed per line.";
200 size_t instructionCount =
205 "%s: %d instructions\n"
206 "uncompressed total size %d bits (%d bytes),\n")
207 % programName % instructionCount
208 % (uncompressedWidth * instructionCount)
209 %
int(std::ceil(uncompressedWidth * instructionCount / 8.0))).
214 "compressed total size %d bits (%d bytes)\n")
215 % programBits->size()
216 % size_t(std::ceil(programBits->size() / 8.0))).str();
229 std::size_t NOPCount = maxMoves - moves;
233 "number of NOP moves: %d (%.1f%% of total move slots)\n")
234 % NOPCount % (float(NOPCount) * 100 / maxMoves)).str();
238 int totalImmediates = 0;
239 int totalLongImmediates = 0;
240 std::set<int> allImmediates;
241 std::set<int> programAddresses;
242 std::set<int> dataAddresses;
244 for (
int m = 0; m < prog.
moveCount(); ++m) {
249 allImmediates.insert(value);
251 dataAddresses.insert(value);
253 programAddresses.insert(value);
258 for (TTAProgram::Program::InstructionVector::const_iterator i =
259 instructions.begin(); i != instructions.end(); ++i) {
265 ++totalLongImmediates;
266 allImmediates.insert(value);
268 dataAddresses.insert(value);
270 programAddresses.insert(value);
277 int totalFullNOPs = 0;
278 int totalTwoConsNOPs = 0;
279 int totalThreeConsNOPs = 0;
280 int totalFourConsNOPs = 0;
281 bool oneConsecutiveNOP =
false;
282 bool twoConsecutiveNOPs =
false;
283 bool threeConsecutiveNOPs =
false;
284 bool fourConsecutiveNOPs =
false;
287 for (TTAProgram::Program::InstructionVector::const_iterator i =
288 instructions.begin(); i != instructions.end(); ++i) {
290 if (instruction.
isNOP()) {
297 if (fourConsecutiveNOPs) {
300 }
else if (threeConsecutiveNOPs) {
301 fourConsecutiveNOPs =
true;
303 --totalThreeConsNOPs;
304 }
else if (twoConsecutiveNOPs) {
305 threeConsecutiveNOPs =
true;
306 ++totalThreeConsNOPs;
308 }
else if (oneConsecutiveNOP) {
309 twoConsecutiveNOPs =
true;
312 oneConsecutiveNOP =
true;
314 oneConsecutiveNOP =
false;
315 twoConsecutiveNOPs =
false;
316 threeConsecutiveNOPs =
false;
317 fourConsecutiveNOPs =
false;
324 "total immediates: %d (long %.1f%%), "
325 "different immediate values: %d,\n"
326 "instr. addresses %d (%.1f%%), "
327 "data addresses %d (%.1f%%),\n"
328 "total full instruction NOPs: %d (%.1f%% of instructions),\n"
329 "two consecutive full instruction NOPs: %d,\n"
330 "three consecutive full instruction NOPs: %d,\n"
331 "four consecutive full instruction NOPs: %d\n")
333 % (totalLongImmediates * 100.0 / totalImmediates)
334 % allImmediates.size() % programAddresses.size()
335 % (programAddresses.size() * 100.0 / allImmediates.size())
336 % dataAddresses.size()
337 % (dataAddresses.size() * 100.0 / allImmediates.size())
339 % (totalFullNOPs * 100.0 / instructionCount)
349 }
else if (format ==
ASCII) {
352 if (mausPerLine > 1) {
357 }
else if (format ==
ARRAY) {
358 if (mausPerLine > 1) {
363 }
else if (format ==
MIF) {
365 }
else if (format ==
VHDL) {
367 }
else if (format ==
COE) {
369 }
else if (format ==
HEX) {
371 }
else if (format ==
BIN2N) {
406 const std::string& addressSpace, std::ostream& stream,
OutputFormat format,
407 int mausPerLine,
bool usePregeneratedImage) {
408 if (mausPerLine < 1) {
409 string errorMsg =
"Data memory width in MAUs must be positive.";
422 if (!navigator.
hasItem(addressSpace)) {
423 const string procName =
"ProgramImageGenerator::generateDataImage";
427 int memWidth = mausPerLine * as->
width();
429 if (!usePregeneratedImage) {
437 for (
unsigned int i = 0; i <
program.sectionCount(Section::ST_DATA);
440 *
program.section(Section::ST_DATA, i));
442 for (
unsigned int i = 0; i <
program.sectionCount(Section::ST_LEDATA);
445 unsigned int lineOffset = dataBits.size();
448 *
program.section(Section::ST_LEDATA, i));
454 while (lineOffset < dataBits.size()) {
458 if ((dataBits.size() % memWidth &&
459 lineOffset > (dataBits.size() - memWidth))) {
460 unsigned int preferredSize =
461 ((dataBits.size() / (memWidth))+1) *
463 while (dataBits.size() < preferredSize) {
464 dataBits.push_back(0);
468 for (
int k = 0; k < mausPerLine/2; k++) {
469 int bitOffset0 = k * as->
width();
470 int bitOffset1 = (mausPerLine-k-1) * as->
width();
472 for (
int j = 0; j < as->
width(); j++) {
473 bool bit0 = dataBits[lineOffset+bitOffset0 + j];
474 dataBits[lineOffset+bitOffset0+j] =
475 dataBits[lineOffset+bitOffset1+j];
476 dataBits[lineOffset+bitOffset1+j] = bit0;
479 lineOffset += memWidth;
486 }
else if (format ==
ASCII) {
488 }
else if (format ==
ARRAY) {
490 }
else if (format ==
MIF) {
492 }
else if (format ==
VHDL) {
495 }
else if (format ==
COE) {
497 }
else if (format ==
HEX) {
499 }
else if (format ==
BIN2N) {
512 const std::string& addressSpace,
519 program.section(Section::ST_CODE, 0));
531 unsigned int zeroFillStart = dataBits.size() / 8;
532 for (
AddressImage i = zeroFillStart; i < startingAddress; i++) {
535 if (zeroFillStart > startingAddress) {
537 __FILE__,__LINE__,
__func__,
"Illegal order of data sections.");
541 Word sectionLength = dataSection.
length();
542 for (Word offset = 0; offset < sectionLength;) {
546 Word indexOfInstruction =
556 unsigned int num = memAddress;
557 memAddress = ((num>>24)&0xff) |
558 ((num<<8)&0xff0000) |
560 ((num<<24)&0xff000000);
566 "Program image must be generated before "
567 "generating data image.";
569 __FILE__, __LINE__,
__func__, errorMsg);
572 Byte byte = dataSection.
byte(offset);
593 std::ostream& stream,
608 std::vector<std::string>
612 std::vector<string> files;
613 for (std::vector<string>::const_iterator iter = paths.begin();
614 iter != paths.end(); iter++) {
618 for (std::vector<string>::const_iterator iter =
620 iter != filesInPath.end(); iter++) {
623 files.push_back(*iter);
646 const std::string& fileName, std::ostream& stream) {
649 fileName, pluginTool);
667 const std::string& fileName,
PluginTools& pluginTool) {
669 for (vector<string>::const_iterator iter = searchPaths.begin();
670 iter != searchPaths.end(); iter++) {
679 "create_code_compressor", pluginCreator, fileName);
681 return pluginCreator();
697 Word dataSectionOffset)
const {
700 for (
unsigned int i = 0; i <
program.sectionCount(Section::ST_RELOC);
703 program.section(Section::ST_RELOC, i));
708 for (Word elemIndex = 0; elemIndex < elemCount; elemIndex++) {
711 assert(relocElem != NULL);
715 if (location->
offset() == dataSectionOffset) {
719 if (destination != NULL) {