#include "compiler/PCodeListing.h" #include "compiler/CError.h" #include "compiler/CMangler.h" #include "compiler/CParser.h" #include "compiler/Alias.h" #include "compiler/BitVectors.h" #include "compiler/CompilerTools.h" #include "compiler/InterferenceGraph.h" #include "compiler/LiveInfo.h" #include "compiler/PCode.h" #include "compiler/PCodeAssembly.h" #include "compiler/Registers.h" #include "compiler/Scheduler.h" #include "compiler/objects.h" static FILE *pcfile; static int ptime; static int sourcetext; static int sourcetext_is_main; static int sourcelength; int pclist_bad_operand; static void formatdataflowset(char *name, UInt32 *vec, UInt32 size, char *format) { UInt32 i; UInt32 counter; char *separator; separator = ""; fprintf(pcfile, "%s = {", name); for (i = 0, counter = 0; i < size; i++) { if (bitvectorgetbit(i, vec)) { if (i) fprintf(pcfile, separator); if (counter++ == 10) { fprintf(pcfile, "\n\t\t"); counter = 0; } fprintf(pcfile, format, i); separator = ","; } } fprintf(pcfile, "}\n"); } static void pclistblock(PCodeBlock *block, char *format, UInt32 vecSize) { PCLink *link; PCodeLabel *label; int cpu; int chr; PCode *instr; int offset; int latency; UInt32 opcode; MachineInfo *mi; char buf[500]; WeirdOperand dummyArg; fprintf(pcfile, ":{%4.4x}::::::::::::::::::::::::::::::::::::::::LOOPWEIGHT=%" PRId32 "\n", block->flags, block->loopWeight); fprintf(pcfile, "B%" PRId32 ": ", block->blockIndex); fprintf(pcfile, "Successors = { "); for (link = block->successors; link; link = link->nextLink) { if (link->block) fprintf(pcfile, "B%" PRId32 " ", link->block->blockIndex); } fprintf(pcfile, "} "); fprintf(pcfile, "Predecessors = { "); for (link = block->predecessors; link; link = link->nextLink) { if (link->block) fprintf(pcfile, "B%" PRId32 " ", link->block->blockIndex); } if (block->labels) { fprintf(pcfile, "} Labels = { "); for (label = block->labels; label; label = label->nextLabel) fprintf(pcfile, "L%" PRId32 " ", label->index); } fprintf(pcfile, "}\n\n"); cpu = copts.scheduling; if (cpu == 10) { mi = &machine7450; } else if (copts.altivec_model != 0 || cpu == 7) { mi = &machine7400; } else if (cpu == 2) { mi = &machine603; } else if (cpu == 5) { mi = &machine603e; } else if (cpu == 3) { mi = &machine604; } else if (cpu == 6) { mi = &machine604; } else if (cpu == 4) { mi = &machine750; } else if (cpu == 1) { mi = &machine601; } else if (cpu == 9) { mi = &machine821; } else { mi = &machine603; } for (offset = block->codeOffset, instr = block->firstPCode; instr; instr = instr->nextPCode, offset += 4) { latency = mi->latency(instr); formatoperands(instr, buf, 1); chr = (PCODE_FLAG_SET_F(instr) & fRecordBit) ? '.' : ' '; if (coloring) opcode = 0; else opcode = assemblepcode(instr, offset, &dummyArg); fprintf( pcfile, " %.8" PRIX32 " %.8" PRIX32 " %4" PRId32 " %-7s%c %s\n", offset, CTool_EndianConvertWord32(opcode), latency, opcodeinfo[instr->op].name, chr, buf ); if (instr->alias) dumpalias(instr->alias, 0, 1, 0); } if (vecSize) { fprintf(pcfile, "............................................................\n"); formatdataflowset("use", liveinfo[block->blockIndex].use, vecSize, format); formatdataflowset("def", liveinfo[block->blockIndex].def, vecSize, format); formatdataflowset("in ", liveinfo[block->blockIndex].in, vecSize, format); formatdataflowset("out", liveinfo[block->blockIndex].out, vecSize, format); } fflush(pcfile); if (pclist_bad_operand) CError_FATAL(252); } static void pclistonoff(int flag) { if (flag) fprintf(pcfile, "On\n"); else fprintf(pcfile, "Off\n"); } void pcinitlisting() { // unknown args, etc } void pccleanuplisting(void) { #ifdef CW_ENABLE_PCODE_DEBUG // this code is not based on the original as we don't have it if (pcfile) { fclose(pcfile); pcfile = NULL; } #endif } void pclistblocks(char *name1, char *name2) { #ifdef CW_ENABLE_PCODE_DEBUG // this code is not based on the original as we don't have it PCodeBlock *block; if (copts.debuglisting) { if (!pcfile) pcfile = fopen("pcdump.txt", "a"); fprintf(pcfile, "\n%s\n%s\n", name1, name2); for (block = pcbasicblocks; block; block = block->nextBlock) pclistblock(block, NULL, 0); } #endif } void pclistdataflow() { // unknown args } void pclistinterferences(char *class_format, int regcount) { } void pclistspill() { // unknown args } void pclistcopypropitem() { // unknown args } void pclistcoalesce() { // unknown args } void pclistusedefs() { // unknown args } void pclistpropinfo() { // unknown args } static void listloop() { // unknown args } static void listloops() { // unknown args } void pclistloops() { // unknown args } static void listswitchtables() { // unknown args } void pclistswitchtables() { // unknown args } void pclistdominators() { // unknown args } void pclistbackedge() { // unknown args } static char *GetInterferenceFlags(IGNode *node) { char *buf; Boolean first; first = 1; buf = oalloc(512); buf[0] = 0; if (node->flags & fSpilled) { strcat(buf, "fSpilled"); first = 0; } if (node->flags & fPushed) { if (!first) strcat(buf, "|"); strcat(buf, "fPushed"); first = 0; } if (node->flags & fCoalesced) { if (!first) strcat(buf, "|"); strcat(buf, "fCoalesced"); first = 0; } if (node->flags & fCoalescedInto) { if (!first) strcat(buf, "|"); strcat(buf, "fCoalescedInto"); first = 0; } if (node->flags & fPairHigh) { if (!first) strcat(buf, "|"); strcat(buf, "fPairHigh"); first = 0; } if (node->flags & fPairLow) { if (!first) strcat(buf, "|"); strcat(buf, "fPairLow"); first = 0; } if (!*buf) strcat(buf, "no_flags"); return buf; } void pclistinterferencegraphnode() { // unknown args } void pclistinterferencegraph() { // unknown args } void pclistblock_scheduler() { // unknown args } void pclistblocks_start_scheduler(char *str1, char *str2) { } void pclistblocks_end_scheduler(void) { if (pclist_bad_operand) CError_FATAL(1318); } static void printheapsize() { // unknown args } void pctotalheap() { // unknown args } void pctotalmemory() { // unknown args } void pcmessage(char *probably_a_string, ...) { } int formatalias(Alias *alias, char *buf, int bufSize) { char *name; char *typestr; int len; int len2; if (bufSize < 16) return sprintf(buf, "..."); switch (alias->type) { case AliasType0: case AliasType1: name = CMangler_GetLinkName(alias->object)->name; if (!strlen(name) || name[0] < 0) CError_FATAL(1458); if (strlen(name) + 16 > bufSize) return sprintf(buf, "..."); switch (alias->object->datatype) { case DNONLAZYPTR: typestr = "{NL}"; break; case DDATA: typestr = "{RW}"; break; case DLOCAL: typestr = "{SP}"; break; default: typestr = ""; } len = sprintf(buf, "%0.*s%s", bufSize - 20, name, typestr, alias->size); buf += len; if (alias->type == AliasType0) return len; if (alias->offset == 0) len2 = sprintf(buf, ":%d", alias->size); else if (alias->offset > 0) len2 = sprintf(buf, "+%d:%d", alias->offset, alias->size); else len2 = sprintf(buf, "-%d:%d", -alias->offset, alias->size); return len + len2; case AliasType2: len = 0; len2 = sprintf(buf, "{"); buf += len2; len += len2; len2 = sprintf(buf, "*"); buf += len2; len += len2; len2 = sprintf(buf, "}"); buf += len2; len += len2; return len; default: CError_FATAL(1543); return 0; } } int dumpalias(Alias *alias, int len, Boolean flag1, Boolean flag2) { char *name; char *typestr; AliasMember *member; Boolean notFirst; if (!flag2 && alias == worst_case) { fprintf(pcfile, " ALIAS = {worst_case}"); if (flag1) fprintf(pcfile, "\n"); return 0; } if (flag1) { if (alias == worst_case) fprintf(pcfile, "ALIAS worst_case = "); else fprintf(pcfile, " ALIAS = "); } switch (alias->type) { case AliasType0: case AliasType1: name = CMangler_GetLinkName(alias->object)->name; if (!strlen(name) || name[0] < 0) CError_FATAL(1581); switch (alias->object->datatype) { case DNONLAZYPTR: typestr = "{NL}"; break; case DDATA: typestr = "{RW}"; break; case DLOCAL: typestr = "{SP}"; break; default: typestr = ""; } len += fprintf(pcfile, "%0.80s%s", name, typestr); if (alias->type == AliasType0) { if (flag1) fprintf(pcfile, "\n"); return len; } if (alias->offset == 0) len += fprintf(pcfile, ":%d", alias->size); else if (alias->offset > 0) len += fprintf(pcfile, "+%d:%d", alias->offset, alias->size); else len += fprintf(pcfile, "-%d:%d", -alias->offset, alias->size); if (flag1) fprintf(pcfile, "\n"); return len; case AliasType2: len += fprintf(pcfile, "{"); notFirst = 0; for (member = alias->parents; member; member = member->nextParent) { if (member->child->type == AliasType0) { if (notFirst) len += fprintf(pcfile, ","); if (len > 60) { fprintf(pcfile, "\n "); len = 0; } len = dumpalias(member->child, len, 0, 0); notFirst = 1; } } for (member = alias->parents; member; member = member->nextParent) { if (member->child->type != AliasType0) { if (notFirst) len += fprintf(pcfile, ","); if (len > 60) { fprintf(pcfile, "\n "); len = 0; } len = dumpalias(member->child, len, 0, 0); notFirst = 1; } } len += fprintf(pcfile, "}"); if (flag1) fprintf(pcfile, "\n"); return len; default: CError_FATAL(1661); return 0; } } void pcformatset() { // unknown args } int GetLineEndOffset(char *str, int lineNum, int len) { int offset; char *work; offset = GetLineOffset(str, lineNum, len); if (offset < 0) return offset; work = str + offset; while (*work) { if (*work == '\n') return work - str - 1; work++; } return -1; } int GetLineOffset(char *str, int lineNum, int len) { char *work = str; char *end; if (lineNum < 0) return -1; end = str + len; while (work < end) { if (*work == '\n' && --lineNum <= 0) return work - str; work++; } return 0; } void DumpSourceCode() { // unknown args } int DumpIR_SrcBreak() { // unknown args return 0; }