diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
commit | 094b96ca1df4a035b5f93c351f773306c0241f3f (patch) | |
tree | 95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/DumpIR.c | |
parent | fc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff) | |
download | MWCC-main.tar.gz MWCC-main.zip |
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/DumpIR.c')
-rw-r--r-- | compiler_and_linker/unsorted/DumpIR.c | 729 |
1 files changed, 729 insertions, 0 deletions
diff --git a/compiler_and_linker/unsorted/DumpIR.c b/compiler_and_linker/unsorted/DumpIR.c new file mode 100644 index 0000000..5f6eea4 --- /dev/null +++ b/compiler_and_linker/unsorted/DumpIR.c @@ -0,0 +1,729 @@ +#include "compiler/DumpIR.h" +#include "compiler/CFunc.h" +#include "compiler/CInt64.h" +#include "compiler/CMachine.h" +#include "compiler/CMangler.h" +#include "compiler/CParser.h" +#include "compiler/Exceptions.h" +#include "compiler/Switch.h" +#include "compiler/enode.h" +#include "compiler/objects.h" +#include "compiler/types.h" + +static FILE *outfile; + +// forward decls +static void spell(Type *type, char *buf); + +static void WritePString(FILE *file, char *str, int len) { + while (len--) { + switch (*str) { + case 0: + fputs("\\x00", file); + break; + case 7: + fputs("\\a", file); + break; + case 8: + fputs("\\b", file); + break; + case 12: + fputs("\\f", file); + break; + case 10: + fputs("\\n", file); + break; + case 13: + fputs("\\r", file); + break; + case 9: + fputs("\\t", file); + break; + case 11: + fputs("\\v", file); + break; + case '"': + case '\'': + case '?': + case '\\': + fputc('\\', file); + default: + fputc(*str, file); + break; + } + str++; + } +} + +static void WriteCString(FILE *file, char *str) { + WritePString(file, str, strlen(str)); +} + +static void StaticSetupDumpIR(void) { +} + +void SetupDumpIR(void) { + // unknown args + StaticSetupDumpIR(); +} + +void CleanupDumpIR(void) { +#ifdef CW_ENABLE_PCODE_DEBUG + // this code is not based on the original as we don't have it + if (outfile) { + fclose(outfile); + outfile = NULL; + } +#endif +} + +void DumpIR(Statement *statements, Object *func) { +#ifdef CW_ENABLE_PCODE_DEBUG + // this code is not based on the original as we don't have it + if (copts.debuglisting) { + if (!outfile) + outfile = fopen("irdump.txt", "a"); + + fputs("--- BEGIN IR DUMP ---\r", outfile); + while (statements) { + switch (statements->type) { + case ST_NOP: + fputs("ST_NOP\r", outfile); + break; + case ST_LABEL: + fputs("ST_LABEL\r", outfile); + break; + case ST_GOTO: + fputs("ST_GOTO\r", outfile); + break; + case ST_EXPRESSION: + fputs("ST_EXPRESSION\r", outfile); + DumpExpression(statements->expr, 1); + break; + case ST_SWITCH: + fputs("ST_SWITCH\r", outfile); + DumpExpression(statements->expr, 1); + break; + case ST_IFGOTO: + fputs("ST_IFGOTO\r", outfile); + DumpExpression(statements->expr, 1); + break; + case ST_IFNGOTO: + fputs("ST_IFNGOTO\r", outfile); + DumpExpression(statements->expr, 1); + break; + case ST_RETURN: + fputs("ST_RETURN\r", outfile); + if (statements->expr) + DumpExpression(statements->expr, 1); + break; + case ST_OVF: + fputs("ST_OVF\r", outfile); + break; + case ST_EXIT: + fputs("ST_EXIT\r", outfile); + break; + case ST_ENTRY: + fputs("ST_ENTRY\r", outfile); + break; + case ST_BEGINCATCH: + fputs("ST_BEGINCATCH\r", outfile); + break; + case ST_ENDCATCH: + fputs("ST_ENDCATCH\r", outfile); + break; + case ST_ENDCATCHDTOR: + fputs("ST_ENDCATCHDTOR\r", outfile); + break; + case ST_GOTOEXPR: + fputs("ST_GOTOEXPR\r", outfile); + break; + case ST_ASM: + fputs("ST_ASM\r", outfile); + break; + case ST_BEGINLOOP: + fputs("ST_BEGINLOOP\r", outfile); + break; + case ST_ENDLOOP: + fputs("ST_ENDLOOP\r", outfile); + break; + } + statements = statements->next; + } + fputs("--- END IR DUMP ---\r", outfile); + fflush(outfile); + } +#endif +} + +void DumpExpression(ENode *expr, int indent) { + static int bt; + static int i; + static char *nodenames[] = { + "EPOSTINC", + "EPOSTDEC", + "EPREINC", + "EPREDEC", + "EINDIRECT", + "EMONMIN", + "EBINNOT", + "ELOGNOT", + "EFORCELOAD", + "EMUL", + "EMULV", + "EDIV", + "EMODULO", + "EADDV", + "ESUBV", + "EADD", + "ESUB", + "ESHL", + "ESHR", + "ELESS", + "EGREATER", + "ELESSEQU", + "EGREATEREQU", + "EEQU", + "ENOTEQU", + "EAND", + "EXOR", + "EOR", + "ELAND", + "ELOR", + "EASS", + "EMULASS", + "EDIVASS", + "EMODASS", + "EADDASS", + "ESUBASS", + "ESHLASS", + "ESHRASS", + "EANDASS", + "EXORASS", + "EORASS", + "ECOMMA", + "EPMODULO", + "EROTL", + "EROTR", + "EBCLR", + "EBTST", + "EBSET", + "ETYPCON", + "EBITFIELD", + "EINTCONST", + "EFLOATCONST", + "ESTRINGCONST", + "ECOND", + "EFUNCCALL", + "EFUNCCALLP", + "EOBJREF", + "EMFPOINTER", + "ENULLCHECK", + "EPRECOMP", + "ETEMP", + "EARGOBJ", + "ELOCOBJ", + "ELABEL", + "ESETCONST", + "ENEWEXCEPTION", + "ENEWEXCEPTIONARRAY", + "EINITTRYCATCH", + "EOBJLIST", + "EMEMBER", + "ETEMPLDEP", + "EINSTRUCTION", + "EDEFINE", + "EREUSE", + "EASSBLK", + "EVECTOR128CONST", + "ECONDASS", + NULL + }; + char buf[64]; + ENodeList *list; + + while (1) { + for (i = 0; i < indent; i++) + fputc('\t', outfile); + + if (expr->flags) + fprintf(outfile, "%s {%02X}", nodenames[expr->type], expr->flags); + else + fprintf(outfile, "%s", nodenames[expr->type]); + + switch (expr->type) { + case EINTCONST: + if (expr->rtype->size > 4) { + fprintf(outfile, + "[0x%.8" PRIX32 "%.8" PRIX32 "]", + expr->data.intval.hi, expr->data.intval.lo); + } else { + fprintf(outfile, + "[%" PRId32 "]", + expr->data.intval.lo); + } + DumpType(expr->rtype); + fprintf(outfile, "\r"); + return; + + case EFLOATCONST: + CMach_PrintFloat(buf, expr->data.floatval); + fprintf(outfile, "[%s]", buf); + DumpType(expr->rtype); + fprintf(outfile, "\r"); + return; + + case ESTRINGCONST: + if (expr->data.string.ispascal) { + fputs("[\"", outfile); + WritePString(outfile, expr->data.string.data, expr->data.string.size); + fputs("\"]", outfile); + } else { + fputs("[\"", outfile); + WriteCString(outfile, expr->data.string.data); + fputs("\"]", outfile); + } + DumpType(expr->rtype); + fprintf(outfile, "\r"); + return; + + case EVECTOR128CONST: + fprintf(outfile, + "[0x%.8" PRIX32 "%.8" PRIX32 "%.8" PRIX32 "%.8" PRIX32 "]", + expr->data.vector128val.ul[0], + expr->data.vector128val.ul[1], + expr->data.vector128val.ul[2], + expr->data.vector128val.ul[3]); + DumpType(expr->rtype); + fprintf(outfile, "\r"); + return; + + case ECOND: + case ECONDASS: + DumpType(expr->rtype); + fprintf(outfile, "\r"); + DumpExpression(expr->data.cond.cond, indent + 1); + DumpExpression(expr->data.cond.expr1, indent + 1); + expr = expr->data.cond.expr2; + indent++; + break; + + case EFUNCCALL: + case EFUNCCALLP: + DumpType(expr->rtype); + fprintf(outfile, "\r"); + DumpExpression(expr->data.funccall.funcref, indent + 1); + for (list = expr->data.funccall.args; list; list = list->next) + DumpExpression(list->node, indent + 1); + return; + + case EOBJREF: + switch (expr->data.objref->datatype) { + case DFUNC: + fprintf(outfile, "[%s{PR}]", CMangler_GetLinkName(expr->data.objref)->name); + break; + case DDATA: + fprintf(outfile, "[%s{RW}]", CMangler_GetLinkName(expr->data.objref)->name); + break; + case DNONLAZYPTR: + fprintf(outfile, "[%s{NL}]", CMangler_GetLinkName(expr->data.objref)->name); + break; + default: + fprintf(outfile, "[%s]", expr->data.objref->name->name); + break; + } + DumpType(expr->rtype); + fprintf(outfile, "\r"); + return; + + ENODE_CASE_DIADIC_1: + case ELAND: + case ELOR: + ENODE_CASE_ASSIGN: + case ECOMMA: + case EPMODULO: + case EROTL: + case EROTR: + case EBTST: + DumpType(expr->rtype); + fprintf(outfile, "\r"); + DumpExpression(expr->data.diadic.left, indent + 1); + expr = expr->data.diadic.right; + indent++; + break; + + ENODE_CASE_MONADIC: + DumpType(expr->rtype); + fprintf(outfile, "\r"); + expr = expr->data.monadic; + indent++; + break; + + case EMFPOINTER: + DumpType(expr->rtype); + fprintf(outfile, "\r"); + DumpExpression(expr->data.mfpointer.accessnode, indent + 1); + expr = expr->data.mfpointer.mfpointer; + indent++; + break; + + case ENULLCHECK: + fprintf(outfile, " unique [%" PRId32 "]", expr->data.nullcheck.precompid); + DumpType(expr->rtype); + fprintf(outfile, "\r"); + DumpExpression(expr->data.nullcheck.nullcheckexpr, indent + 1); + expr = expr->data.nullcheck.condexpr; + indent++; + break; + + case EPRECOMP: + fprintf(outfile, " unique [%" PRId32 "]", expr->data.precompid); + DumpType(expr->rtype); + fprintf(outfile, "\r"); + return; + + case ELABEL: + fprintf(outfile, "[%s]", expr->data.label->uniquename->name); + DumpType(expr->rtype); + fprintf(outfile, "\r"); + return; + + case ETEMP: + DumpType(expr->data.temp.type); + fprintf(outfile, "\r"); + return; + + case EINITTRYCATCH: + DumpType(expr->rtype); + fprintf(outfile, "\r"); + if (expr->data.itc.initexpr) + DumpExpression(expr->data.itc.initexpr, indent + 1); + if (expr->data.itc.tryexpr) + DumpExpression(expr->data.itc.tryexpr, indent + 1); + if (expr->data.itc.catchexpr) + DumpExpression(expr->data.itc.catchexpr, indent + 1); + if (expr->data.itc.result) + DumpExpression(expr->data.itc.result, indent + 1); + return; + + case EDEFINE: + fprintf(outfile, "[%.8" PRIX32 "]", expr); + DumpType(expr->rtype); + fputs("\r", outfile); + expr = expr->data.monadic; + indent++; + break; + + case EREUSE: + fprintf(outfile, "[%.8" PRIX32 "]", expr->data.monadic); + DumpType(expr->rtype); + fputs("\r", outfile); + return; + + default: + return; + } + } +} + +void DumpSwitch(SwitchInfo *info) { + char buf[32]; + SwitchCase *cs; + + for (cs = info->cases; cs; cs = cs->next) { + CInt64_PrintDec(buf, cs->min); + CInt64_PrintDec(buf, cs->min); + fprintf(outfile, "\t\t%11s: %s\r", buf, cs->label->uniquename->name); + } + + fprintf(outfile, "\t\t default: %s\r", info->defaultlabel->uniquename->name); +} + +void DumpType(Type *type) { + char buf[256]; + + spell(type, buf); + fprintf(outfile, " (%s)", buf); +} + +static void spell(Type *type, char *buf) { + char mybuf[256]; + char mybuf2[256]; + + switch (type->type) { + case TYPEVOID: + strcpy(buf, "void"); + break; + case TYPEINT: + switch (TYPE_INTEGRAL(type)->integral) { + case IT_BOOL: + strcpy(buf, "bool"); + break; + case IT_CHAR: + strcpy(buf, "char"); + break; + case IT_WCHAR_T: + strcpy(buf, "wchar_t"); + break; + case IT_SCHAR: + strcpy(buf, "signed char"); + break; + case IT_UCHAR: + strcpy(buf, "unsigned char"); + break; + case IT_SHORT: + strcpy(buf, "short"); + break; + case IT_USHORT: + strcpy(buf, "unsigned short"); + break; + case IT_INT: + strcpy(buf, "int"); + break; + case IT_UINT: + strcpy(buf, "unsigned int"); + break; + case IT_LONG: + strcpy(buf, "long"); + break; + case IT_ULONG: + strcpy(buf, "unsigned long"); + break; + case IT_LONGLONG: + strcpy(buf, "long long"); + break; + case IT_ULONGLONG: + strcpy(buf, "unsigned long long"); + break; + } + break; + case TYPEFLOAT: + switch (TYPE_INTEGRAL(type)->integral) { + case IT_FLOAT: + strcpy(buf, "float"); + break; + case IT_SHORTDOUBLE: + strcpy(buf, "short double"); + break; + case IT_DOUBLE: + strcpy(buf, "double"); + break; + case IT_LONGDOUBLE: + strcpy(buf, "long double"); + break; + } + break; + case TYPEENUM: + strcpy(buf, "enum "); + if (TYPE_ENUM(type)->enumname) + strcat(buf, TYPE_ENUM(type)->enumname->name); + break; + case TYPESTRUCT: + if (IS_TYPESTRUCT_VECTOR(TYPE_STRUCT(type))) { + switch (TYPE_STRUCT(type)->stype) { + case STRUCT_VECTOR_UCHAR: + strcpy(buf, "vector unsigned char "); + break; + case STRUCT_VECTOR_SCHAR: + strcpy(buf, "vector signed char "); + break; + case STRUCT_VECTOR_BCHAR: + strcpy(buf, "vector bool char "); + break; + case STRUCT_VECTOR_USHORT: + strcpy(buf, "vector unsigned short "); + break; + case STRUCT_VECTOR_SSHORT: + strcpy(buf, "vector signed short "); + break; + case STRUCT_VECTOR_BSHORT: + strcpy(buf, "vector bool short "); + break; + case STRUCT_VECTOR_UINT: + strcpy(buf, "vector unsigned int "); + break; + case STRUCT_VECTOR_SINT: + strcpy(buf, "vector signed int "); + break; + case STRUCT_VECTOR_BINT: + strcpy(buf, "vector bool int "); + break; + case STRUCT_VECTOR_FLOAT: + strcpy(buf, "vector float "); + break; + case STRUCT_VECTOR_PIXEL: + strcpy(buf, "vector pixel "); + break; + } + } else { + strcpy(buf, "struct "); + if (TYPE_STRUCT(type)->name) + strcat(buf, TYPE_STRUCT(type)->name->name); + } + break; + case TYPECLASS: + strcpy(buf, "class "); + if (TYPE_CLASS(type)->classname) + strcat(buf, TYPE_CLASS(type)->classname->name); + break; + case TYPEFUNC: + spell(TYPE_FUNC(type)->functype, mybuf); + strcpy(buf, "freturns("); + strcat(buf, mybuf); + strcat(buf, ")"); + break; + case TYPEBITFIELD: + spell(TYPE_BITFIELD(type)->bitfieldtype, mybuf); + sprintf(buf, + "bitfield(%s){%d:%d}", + mybuf, + TYPE_BITFIELD(type)->offset, + TYPE_BITFIELD(type)->bitlength); + break; + case TYPELABEL: + strcpy(buf, "label"); + break; + case TYPEPOINTER: + spell(TPTR_TARGET(type), mybuf); + strcpy(buf, "pointer("); + strcat(buf, mybuf); + strcat(buf, ")"); + break; + case TYPEARRAY: + spell(TPTR_TARGET(type), mybuf); + strcpy(buf, "array("); + strcat(buf, mybuf); + strcat(buf, ")"); + break; + case TYPEMEMBERPOINTER: + spell(TYPE_MEMBER_POINTER(type)->ty2, mybuf); + spell(TYPE_MEMBER_POINTER(type)->ty1, mybuf2); + strcpy(buf, "memberpointer("); + strcat(buf, mybuf); + strcat(buf, ","); + strcat(buf, mybuf2); + strcat(buf, ")"); + break; + } +} + +void DumpStack(ExceptionAction *act) { + while (act) { + fprintf(outfile, "\t\t:"); + switch (act->type) { + case EAT_DESTROYLOCAL: + fprintf(outfile, + "EAT_DESTROYLOCAL %s(&%s)%s", + CMangler_GetLinkName(act->data.destroy_local.dtor)->name, + act->data.destroy_local.local->name->name, + "\r"); + break; + case EAT_DESTROYLOCALCOND: + fprintf(outfile, + "EAT_DESTROYLOCALCOND%s", + "\r"); + break; + case EAT_DESTROYLOCALOFFSET: + fprintf(outfile, + "EAT_DESTROYLOCALOFFSET %s(&%s+%" PRId32 ")%s", + CMangler_GetLinkName(act->data.destroy_local_offset.dtor)->name, + act->data.destroy_local_offset.local->name->name, + act->data.destroy_local_offset.offset, + "\r"); + break; + case EAT_DESTROYLOCALPOINTER: + fprintf(outfile, + "EAT_DESTROYLOCALPOINTER%s", + "\r"); + break; + case EAT_DESTROYLOCALARRAY: + fprintf(outfile, + "EAT_DESTROYLOCALARRAY%s", + "\r"); + break; + case EAT_DESTROYBASE: + fprintf(outfile, + "EAT_DESTROYBASE %s(this+%" PRId32 ")%s", + CMangler_GetLinkName(act->data.destroy_base.dtor)->name, + act->data.destroy_base.offset, + "\r"); + break; + case EAT_DESTROYMEMBER: + fprintf(outfile, + "EAT_DESTROYMEMBER %s(%s+%" PRId32 ")%s", + CMangler_GetLinkName(act->data.destroy_member.dtor)->name, + act->data.destroy_member.objectptr->name->name, + act->data.destroy_member.offset, + "\r"); + break; + case EAT_DESTROYMEMBERCOND: + fprintf(outfile, + "EAT_DESTROYMEMBERCOND if(%s) %s(this+%" PRId32 ")%s", + act->data.destroy_member_cond.cond->name->name, + CMangler_GetLinkName(act->data.destroy_member_cond.dtor)->name, + act->data.destroy_member_cond.offset, + "\r"); + break; + case EAT_DESTROYMEMBERARRAY: + fprintf(outfile, + "EAT_DESTROYMEMBERARRAY %s(this+%" PRId32 ")[%" PRId32 "] size: %" PRId32 "%s", + CMangler_GetLinkName(act->data.destroy_member_array.dtor)->name, + act->data.destroy_member_array.offset, + act->data.destroy_member_array.elements, + act->data.destroy_member_array.element_size, + "\r"); + break; + case EAT_DELETEPOINTER: + fprintf(outfile, + "EAT_DELETEPOINTER(%s)%s", + act->data.delete_pointer.pointerobject->name->name, + "\r"); + break; + case EAT_DELETELOCALPOINTER: + fprintf(outfile, + "EAT_DELETELOCALPOINTER(%s)%s", + act->data.delete_pointer.pointerobject->name->name, + "\r"); + break; + case EAT_DELETEPOINTERCOND: + fprintf(outfile, + "EAT_DELETEPOINTERCOND if (%s)(%s)%s", + act->data.delete_pointer_cond.cond->name->name, + act->data.delete_pointer_cond.pointerobject->name->name, + "\r"); + break; + case EAT_CATCHBLOCK: + fprintf(outfile, "EAT_CATCHBLOCK "); + if (act->data.catch_block.catch_type) { + if (act->data.catch_block.catch_object) + fprintf(outfile, "[%s]", act->data.catch_block.catch_object->name->name); + else + fprintf(outfile, "[]"); + DumpType(act->data.catch_block.catch_type); + } else { + fprintf(outfile, "[...] "); + } + fprintf(outfile, + " Label: %s%s", + act->data.catch_block.catch_label->uniquename->name, + "\r"); + break; + case EAT_SPECIFICATION: + fprintf(outfile, + "EAT_SPECIFICATION%s", + "\r"); + break; + case EAT_ACTIVECATCHBLOCK: + fprintf(outfile, + "EAT_ACTIVECATCHBLOCK%s", + "\r"); + break; + case EAT_TERMINATE: + fprintf(outfile, + "EAT_TERMINATE%s", + "\r"); + break; + } + act = act->prev; + } +} |