decompiled_code:
_QWORD *empty_symbol()
{
_QWORD *result; // rax

result = malloc(0x38uLL);
*(_DWORD *)result = 0;
result[1] = 0LL;
result[6] = 0LL;
result[2] = 0LL;
return result;
}

canonical_decompiled_code:
_QWORD *func1()
{
_QWORD *result; // rax

result = malloc(0x38uLL);
*(_DWORD *)result = 0;
result[1] = 0LL;
result[6] = 0LL;
result[2] = 0LL;
return result;
}

original_code:
static symbol_info* empty_symbol(void)
{
    symbol_info* sym = malloc(sizeof(symbol_info));
    sym->symbol_type = SYM_NONE;
    sym->name = ((void *)0);
    sym->next = ((void *)0);
    sym->scope = ((void *)0);
    return sym;
}

canonical_original_code:
static struct symbol_info *empty_symbol()
{
    struct symbol_info *sym = malloc(sizeof(symbol_info));
    sym->symbol_type = SYM_NONE;
    sym->name = ((void *)0);
    sym->next = ((void *)0);
    sym->scope = ((void *)0);
    return sym;
}

return_type: struct symbol_info { enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 } symbol_type; char *name; struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; } *scope; union { struct { struct type { enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 } type; int elements; } var_type; struct codegen_info { enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 } storage; int size; union { int reg; int offset; }; } codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; } *


repo: marcinlos/cmm-compiler

decompiled_code:
void __fastcall free_symbol_info(void *a1)
{
__int64 v1; // rbp

if ( !a1 )
_assert_fail("sym && \"free_symbol_info: NULL argument\"", "symbol_table.c", 0x4Bu, "free_symbol_info");
v1 = *((_QWORD *)a1 + 6);
free(*((void **)a1 + 1));
if ( *(_DWORD *)a1 == 3 )
free(*((void **)a1 + 3));
free(a1);
if ( v1 )
free_symbol_info(v1);
}

canonical_decompiled_code:
void __fastcall func2(void *a1)
{
__int64 v1; // rbp

if ( !a1 )
_assert_fail("sym && \"free_symbol_info: NULL argument\"", "symbol_table.c", 0x4Bu, "free_symbol_info");
v1 = *((_QWORD *)a1 + 6);
free(*((void **)a1 + 1));
if ( *(_DWORD *)a1 == 3 )
free(*((void **)a1 + 3));
free(a1);
if ( v1 )
func2(v1);
}

original_code:
void free_symbol_info(symbol_info* sym)
{
    ((void) sizeof ((sym && "free_symbol_info: NULL argument") ? 1 : 0), __extension__ ({ if (sym && "free_symbol_info: NULL argument") ; else __assert_fail ("sym && \"free_symbol_info: NULL argument\"", "symbol_table.c", 75, __extension__ __PRETTY_FUNCTION__); }));
    symbol_info* next = sym->next;
    free(sym->name);
    if (sym->symbol_type == SYM_LITERAL)
    {
        free(sym->literal);
    }
    free(sym);
    if (next)
    {
        free_symbol_info(next);
    }
}

canonical_original_code:
void free_symbol_info(struct symbol_info *sym)
{
    ((void) sizeof ((sym && "free_symbol_info: NULL argument") ? 1 : 0), __extension__ ({ if (sym && "free_symbol_info: NULL argument") ; else __assert_fail ("sym && \"free_symbol_info: NULL argument\"", "symbol_table.c", 75, __extension__ __PRETTY_FUNCTION__); }));
    struct symbol_info *next = sym->next;
    free(sym->name);
    if (sym->symbol_type == SYM_LITERAL)
    {
        free(sym->literal);
    }
    free(sym);
    if (next)
    {
        free_symbol_info(next);
    }
}

variable_types: struct symbol_info { enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 } symbol_type; char *name; struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; } *scope; union { struct { struct type { enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 } type; int elements; } var_type; struct codegen_info { enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 } storage; int size; union { int reg; int offset; }; } codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; } *

return_type: void

user_defined_types: struct symbol_info { enum symbol_type symbol_type; char *name; struct scope_info *scope; union { struct { struct type var_type; struct codegen_info codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; }

user_defined_types: struct type { enum basic_type type; int elements; }

user_defined_types: struct codegen_info { enum storage_type storage; int size; union { int reg; int offset; }; }


decompiled_code:
__int64 __fastcall sym_add_symbol(__int64 *a1, __int64 a2)
{
__int64 result; // rax

if ( !a1 )
_assert_fail("scope && \"sym_add_symbol: NULL scope\"", "symbol_table.c", 0x66u, "sym_add_symbol");
if ( !a2 )
_assert_fail("symbol && \"sym_add_symbol: NULL symbol\"", "symbol_table.c", 0x67u, "sym_add_symbol");
result = append_symbol(*a1, a2);
*a1 = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 *a1, __int64 a2)
{
__int64 result; // rax

if ( !a1 )
_assert_fail("scope && \"sym_add_symbol: NULL scope\"", "symbol_table.c", 0x66u, "sym_add_symbol");
if ( !a2 )
_assert_fail("symbol && \"sym_add_symbol: NULL symbol\"", "symbol_table.c", 0x67u, "sym_add_symbol");
result = func0(*a1, a2);
*a1 = result;
return result;
}

original_code:
void sym_add_symbol(scope_info* scope, symbol_info* symbol)
{
    ((void) sizeof ((scope && "sym_add_symbol: NULL scope") ? 1 : 0), __extension__ ({ if (scope && "sym_add_symbol: NULL scope") ; else __assert_fail ("scope && \"sym_add_symbol: NULL scope\"", "symbol_table.c", 102, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((symbol && "sym_add_symbol: NULL symbol") ? 1 : 0), __extension__ ({ if (symbol && "sym_add_symbol: NULL symbol") ; else __assert_fail ("symbol && \"sym_add_symbol: NULL symbol\"", "symbol_table.c", 103, __extension__ __PRETTY_FUNCTION__); }));
    scope->symbols = append_symbol(scope->symbols, symbol);
}

canonical_original_code:
void sym_add_symbol(struct scope_info *scope, struct symbol_info *symbol)
{
    ((void) sizeof ((scope && "sym_add_symbol: NULL scope") ? 1 : 0), __extension__ ({ if (scope && "sym_add_symbol: NULL scope") ; else __assert_fail ("scope && \"sym_add_symbol: NULL scope\"", "symbol_table.c", 102, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((symbol && "sym_add_symbol: NULL symbol") ? 1 : 0), __extension__ ({ if (symbol && "sym_add_symbol: NULL symbol") ; else __assert_fail ("symbol && \"sym_add_symbol: NULL symbol\"", "symbol_table.c", 103, __extension__ __PRETTY_FUNCTION__); }));
    scope->symbols = append_symbol(scope->symbols, symbol);
}

variable_types: struct scope_info { struct symbol_info { enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 } symbol_type; char *name; struct scope_info *scope; union { struct { struct type { enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 } type; int elements; } var_type; struct codegen_info { enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 } storage; int size; union { int reg; int offset; }; } codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; } *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; } *

variable_types:
symbol
struct symbol_info *

user_defined_types: struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; }


decompiled_code:
__int64 __fastcall sym_add_param(__int64 a1, __int64 a2)
{
if ( !a1 )
_assert_fail("fun && \"sym_add_param: NULL function\"", "symbol_table.c", 0x44u, "sym_add_param");
return sym_add_symbol(*(__int64 **)(a1 + 32), a2);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, __int64 a2)
{
if ( !a1 )
_assert_fail("fun && \"sym_add_param: NULL function\"", "symbol_table.c", 0x44u, "sym_add_param");
return func3(*(__int64 **)(a1 + 32), a2);
}

original_code:
void sym_add_param(symbol_info* fun, symbol_info* param)
{
    ((void) sizeof ((fun && "sym_add_param: NULL function") ? 1 : 0), __extension__ ({ if (fun && "sym_add_param: NULL function") ; else __assert_fail ("fun && \"sym_add_param: NULL function\"", "symbol_table.c", 68, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((fun && "sym_add_param: NULL param") ? 1 : 0), __extension__ ({ if (fun && "sym_add_param: NULL param") ; else __assert_fail ("fun && \"sym_add_param: NULL param\"", "symbol_table.c", 69, __extension__ __PRETTY_FUNCTION__); }));
    sym_add_symbol(fun->params, param);
}

canonical_original_code:
void sym_add_param(struct symbol_info *fun, struct symbol_info *param)
{
    ((void) sizeof ((fun && "sym_add_param: NULL function") ? 1 : 0), __extension__ ({ if (fun && "sym_add_param: NULL function") ; else __assert_fail ("fun && \"sym_add_param: NULL function\"", "symbol_table.c", 68, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((fun && "sym_add_param: NULL param") ? 1 : 0), __extension__ ({ if (fun && "sym_add_param: NULL param") ; else __assert_fail ("fun && \"sym_add_param: NULL param\"", "symbol_table.c", 69, __extension__ __PRETTY_FUNCTION__); }));
    sym_add_symbol(fun->params, param);
}

variable_types:
param
struct symbol_info *

user_defined_types: enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 }

user_defined_types: enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 }

user_defined_types: enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 }


decompiled_code:
__int64 __fastcall sym_add_child_scope(__int64 a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rdx

if ( !a1 )
_assert_fail("parent && \"sym_add_child_scope: NULL parent\"", "symbol_table.c", 0x6Du, "sym_add_child_scope");
if ( !a2 )
_assert_fail("child && \"sym_add_child_scope: NULL child\"", "symbol_table.c", 0x6Eu, "sym_add_child_scope");
result = *(_QWORD *)(a1 + 24);
if ( result )
{
do
{
v3 = result;
result = *(_QWORD *)(result + 16);
}
while ( result );
*(_QWORD *)(v3 + 16) = a2;
}
else
{
*(_QWORD *)(a1 + 24) = a2;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rdx

if ( !a1 )
_assert_fail("parent && \"sym_add_child_scope: NULL parent\"", "symbol_table.c", 0x6Du, "sym_add_child_scope");
if ( !a2 )
_assert_fail("child && \"sym_add_child_scope: NULL child\"", "symbol_table.c", 0x6Eu, "sym_add_child_scope");
result = *(_QWORD *)(a1 + 24);
if ( result )
{
do
{
v3 = result;
result = *(_QWORD *)(result + 16);
}
while ( result );
*(_QWORD *)(v3 + 16) = a2;
}
else
{
*(_QWORD *)(a1 + 24) = a2;
}
return result;
}

original_code:
void sym_add_child_scope(scope_info* parent, scope_info* child)
{
    ((void) sizeof ((parent && "sym_add_child_scope: NULL parent") ? 1 : 0), __extension__ ({ if (parent && "sym_add_child_scope: NULL parent") ; else __assert_fail ("parent && \"sym_add_child_scope: NULL parent\"", "symbol_table.c", 109, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((child && "sym_add_child_scope: NULL child") ? 1 : 0), __extension__ ({ if (child && "sym_add_child_scope: NULL child") ; else __assert_fail ("child && \"sym_add_child_scope: NULL child\"", "symbol_table.c", 110, __extension__ __PRETTY_FUNCTION__); }));
    if (parent->children == ((void *)0))
        parent->children = child;
    else
    {
        scope_info* i = parent->children;
        while (i ->next != ((void *)0))
            i = i->next;
        i->next = child;
    }
}

canonical_original_code:
void sym_add_child_scope(struct scope_info *parent, struct scope_info *child)
{
    ((void) sizeof ((parent && "sym_add_child_scope: NULL parent") ? 1 : 0), __extension__ ({ if (parent && "sym_add_child_scope: NULL parent") ; else __assert_fail ("parent && \"sym_add_child_scope: NULL parent\"", "symbol_table.c", 109, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((child && "sym_add_child_scope: NULL child") ? 1 : 0), __extension__ ({ if (child && "sym_add_child_scope: NULL child") ; else __assert_fail ("child && \"sym_add_child_scope: NULL child\"", "symbol_table.c", 110, __extension__ __PRETTY_FUNCTION__); }));
    if (parent->children == ((void *)0))
        parent->children = child;
    else
    {
        struct scope_info *i = parent->children;
        while (i ->next != ((void *)0))
            i = i->next;
        i->next = child;
    }
}

variable_types:
child
struct scope_info *


decompiled_code:
void __fastcall free_scope_info(void **a1)
{
void *v2; // rdi

if ( !a1 )
_assert_fail("scope && \"free_scope_info: NULL argument\"", "symbol_table.c", 0x7Du, "free_scope_info");
v2 = *a1;
if ( v2 )
free_symbol_info(v2);
if ( a1[3] )
free_scope_info();
if ( a1[2] )
free_scope_info();
free(a1);
}

canonical_decompiled_code:
void __fastcall func6(void **a1)
{
void *v2; // rdi

if ( !a1 )
_assert_fail("scope && \"free_scope_info: NULL argument\"", "symbol_table.c", 0x7Du, "free_scope_info");
v2 = *a1;
if ( v2 )
func2(v2);
if ( a1[3] )
func6();
if ( a1[2] )
func6();
free(a1);
}

original_code:
void free_scope_info(scope_info* scope)
{
    ((void) sizeof ((scope && "free_scope_info: NULL argument") ? 1 : 0), __extension__ ({ if (scope && "free_scope_info: NULL argument") ; else __assert_fail ("scope && \"free_scope_info: NULL argument\"", "symbol_table.c", 125, __extension__ __PRETTY_FUNCTION__); }));
    if (scope->symbols != ((void *)0))
        free_symbol_info(scope->symbols);
    if (scope->children != ((void *)0))
        free_scope_info(scope->children);
    if (scope->next != ((void *)0))
        free_scope_info(scope->next);
    free(scope);
}

canonical_original_code:
void free_scope_info(struct scope_info *scope)
{
    ((void) sizeof ((scope && "free_scope_info: NULL argument") ? 1 : 0), __extension__ ({ if (scope && "free_scope_info: NULL argument") ; else __assert_fail ("scope && \"free_scope_info: NULL argument\"", "symbol_table.c", 125, __extension__ __PRETTY_FUNCTION__); }));
    if (scope->symbols != ((void *)0))
        free_symbol_info(scope->symbols);
    if (scope->children != ((void *)0))
        free_scope_info(scope->children);
    if (scope->next != ((void *)0))
        free_scope_info(scope->next);
    free(scope);
}


decompiled_code:
__int64 __fastcall sym_find_no_traverse(char *s2, __int64 *a2)
{
__int64 i; // rbx

for ( i = *a2; i; i = *(_QWORD *)(i + 48) )
{
if ( !strcmp(*(const char **)(i + 8), s2) )
break;
}
return i;
}

canonical_decompiled_code:
__int64 __fastcall func7(char *s2, __int64 *a2)
{
__int64 i; // rbx

for ( i = *a2; i; i = *(_QWORD *)(i + 48) )
{
if ( !strcmp(*(const char **)(i + 8), s2) )
break;
}
return i;
}

original_code:
symbol_info* sym_find_no_traverse(const char* name, scope_info* scope)
{
    symbol_info* info = scope->symbols;
    while (info != ((void *)0))
    {
        if (strcmp(info->name, name) == 0)
            return info;
        else
            info = info->next;
    }
    return ((void *)0);
}

canonical_original_code:
struct symbol_info *sym_find_no_traverse(char *name, struct scope_info *scope)
{
    struct symbol_info *info = scope->symbols;
    while (info != ((void *)0))
    {
        if (strcmp(info->name, name) == 0)
            return info;
        else
            info = info->next;
    }
    return ((void *)0);
}

variable_types:
name
char *

variable_types:
scope
struct scope_info *


decompiled_code:
__int64 __fastcall sym_find(char *a1, __int64 *a2)
{
__int64 result; // rax

result = sym_find_no_traverse(a1, a2);
if ( !result )
{
result = a2[1];
if ( result )
result = sym_find(a1, a2[1]);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(char *a1, __int64 *a2)
{
__int64 result; // rax

result = func7(a1, a2);
if ( !result )
{
result = a2[1];
if ( result )
result = func8(a1, a2[1]);
}
return result;
}

original_code:
symbol_info* sym_find(const char* name, scope_info* scope)
{
    symbol_info* info = sym_find_no_traverse(name, scope);
    if (info == ((void *)0) && scope->parent != ((void *)0))
    {
        return sym_find(name, scope->parent);
    }
    return info;
}

canonical_original_code:
struct symbol_info *sym_find(char *name, struct scope_info *scope)
{
    struct symbol_info *info = sym_find_no_traverse(name, scope);
    if (info == ((void *)0) && scope->parent != ((void *)0))
    {
        return sym_find(name, scope->parent);
    }
    return info;
}


decompiled_code:
void __fastcall free_symbol_table(void *ptr)
{
void **v2; // rdi
void *v3; // rdi

v2 = *(void ***)ptr;
if ( v2 )
free_scope_info(v2);
v3 = (void *)*((_QWORD *)ptr + 1);
if ( v3 )
free_symbol_info(v3);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func10(void *ptr)
{
void **v2; // rdi
void *v3; // rdi

v2 = *(void ***)ptr;
if ( v2 )
func6(v2);
v3 = (void *)*((_QWORD *)ptr + 1);
if ( v3 )
func2(v3);
free(ptr);
}

original_code:
void free_symbol_table(symbol_table* table)
{
    if (table->top_level)
        free_scope_info(table->top_level);
    if (table->literals)
        free_symbol_info(table->literals);
    free(table);
}

canonical_original_code:
void free_symbol_table(struct symbol_table *table)
{
    if (table->top_level)
        free_scope_info(table->top_level);
    if (table->literals)
        free_symbol_info(table->literals);
    free(table);
}

variable_types: struct symbol_table { struct scope_info { struct symbol_info { enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 } symbol_type; char *name; struct scope_info *scope; union { struct { struct type { enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 } type; int elements; } var_type; struct codegen_info { enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 } storage; int size; union { int reg; int offset; }; } codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; } *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; } *top_level; struct symbol_info *literals; } *

user_defined_types: struct symbol_table { struct scope_info *top_level; struct symbol_info *literals; }


decompiled_code:
void sym_print_strings()
{
;
}

canonical_decompiled_code:
void func11()
{
;
}

original_code:
int sym_print_strings(char* buffer, symbol_table* table)
{
}

canonical_original_code:
int sym_print_strings(char *buffer, struct symbol_table *table)
{
}

variable_types:
buffer
char *

return_type: int


decompiled_code:
signed __int64 __fastcall sym_print_symbol(char *a1, __int64 a2)
{
char *v2; // rbx
char v4[280]; // [rsp+0h] [rbp-118h] BYREF

if ( !a2 )
_assert_fail("info && \"sym_print_symbol: NULL info\"", "symbol_table.c", 0xF4u, "sym_print_symbol");
v2 = &a1[sprintf(a1, "%s:\t", *(const char **)(a2 + 8))];
if ( *(_DWORD *)a2 == 1 )
{
type_print(v4, *(_QWORD *)(a2 + 24));
v2 += sprintf(v2, "() -> %s", v4);
}
else if ( *(_DWORD *)a2 == 2 )
{
type_print(v4, *(_QWORD *)(a2 + 24));
v2 += sprintf(v2, "%s", v4);
}
return v2 - a1;
}

canonical_decompiled_code:
signed __int64 __fastcall func12(char *a1, __int64 a2)
{
char *v2; // rbx
char v4[280]; // [rsp+0h] [rbp-118h] BYREF

if ( !a2 )
_assert_fail("info && \"sym_print_symbol: NULL info\"", "symbol_table.c", 0xF4u, "sym_print_symbol");
v2 = &a1[sprintf(a1, "%s:\t", *(const char **)(a2 + 8))];
if ( *(_DWORD *)a2 == 1 )
{
type_print(v4, *(_QWORD *)(a2 + 24));
v2 += sprintf(v2, "() -> %s", v4);
}
else if ( *(_DWORD *)a2 == 2 )
{
type_print(v4, *(_QWORD *)(a2 + 24));
v2 += sprintf(v2, "%s", v4);
}
return v2 - a1;
}

original_code:
int sym_print_symbol(char* buffer, symbol_info* info)
{
    ((void) sizeof ((info && "sym_print_symbol: NULL info") ? 1 : 0), __extension__ ({ if (info && "sym_print_symbol: NULL info") ; else __assert_fail ("info && \"sym_print_symbol: NULL info\"", "symbol_table.c", 244, __extension__ __PRETTY_FUNCTION__); }));
    char* p = buffer;
    p += sprintf(p, "%s:\t", info->name);
    char type_buffer[256];
    switch (info->symbol_type)
    {
    case SYM_FUN:
        type_print(type_buffer, info->ret_type);
        p += sprintf(p, "() -> %s", type_buffer);
        break;
    case SYM_VAR:
        type_print(type_buffer, info->var_type);
        p += sprintf(p, "%s", type_buffer);
        break;
    }
    return p - buffer;
}

canonical_original_code:
int sym_print_symbol(char *buffer, struct symbol_info *info)
{
    ((void) sizeof ((info && "sym_print_symbol: NULL info") ? 1 : 0), __extension__ ({ if (info && "sym_print_symbol: NULL info") ; else __assert_fail ("info && \"sym_print_symbol: NULL info\"", "symbol_table.c", 244, __extension__ __PRETTY_FUNCTION__); }));
    char *p = buffer;
    p += sprintf(p, "%s:\t", info->name);
    char type_buffer[256];
    switch (info->symbol_type)
    {
    case SYM_FUN:
        type_print(type_buffer, info->ret_type);
        p += sprintf(p, "() -> %s", type_buffer);
        break;
    case SYM_VAR:
        type_print(type_buffer, info->var_type);
        p += sprintf(p, "%s", type_buffer);
        break;
    }
    return p - buffer;
}

variable_types:
p
char *


decompiled_code:
signed __int64 __fastcall sym_print_scope(char *a1, const void **a2)
{
char *v2; // rbx
__int64 v3; // r12
char *v4; // rbx

if ( !a2 )
_assert_fail("scope && \"sym_print_scope: NULL scope\"", "symbol_table.c", 0xE5u, "sym_print_scope");
v2 = &a1[sprintf(a1, "scope: %p (parent %p)\n", a2, a2[1])];
v3 = (__int64)*a2;
if ( *a2 )
{
do
{
v4 = &v2[(int)sym_print_symbol(v2, v3)];
*(_WORD *)v4 = 10;
v2 = v4 + 1;
v3 = *(_QWORD *)(v3 + 48);
}
while ( v3 );
}
return v2 - a1;
}

canonical_decompiled_code:
signed __int64 __fastcall func13(char *a1, const void **a2)
{
char *v2; // rbx
__int64 v3; // r12
char *v4; // rbx

if ( !a2 )
_assert_fail("scope && \"sym_print_scope: NULL scope\"", "symbol_table.c", 0xE5u, "sym_print_scope");
v2 = &a1[sprintf(a1, "scope: %p (parent %p)\n", a2, a2[1])];
v3 = (__int64)*a2;
if ( *a2 )
{
do
{
v4 = &v2[(int)func12(v2, v3)];
*(_WORD *)v4 = 10;
v2 = v4 + 1;
v3 = *(_QWORD *)(v3 + 48);
}
while ( v3 );
}
return v2 - a1;
}

original_code:
int sym_print_scope(char* buffer, scope_info* scope)
{
    ((void) sizeof ((scope && "sym_print_scope: NULL scope") ? 1 : 0), __extension__ ({ if (scope && "sym_print_scope: NULL scope") ; else __assert_fail ("scope && \"sym_print_scope: NULL scope\"", "symbol_table.c", 229, __extension__ __PRETTY_FUNCTION__); }));
    char* p = buffer;
    p += sprintf(p, "scope: %p (parent %p)\n", scope, scope->parent);
    symbol_info* symbol = scope->symbols;
    while (symbol != ((void *)0))
    {
        p += sym_print_symbol(p, symbol);
        p += sprintf(p, "\n");
        symbol = symbol->next;
    }
    return p - buffer;
}

canonical_original_code:
int sym_print_scope(char *buffer, struct scope_info *scope)
{
    ((void) sizeof ((scope && "sym_print_scope: NULL scope") ? 1 : 0), __extension__ ({ if (scope && "sym_print_scope: NULL scope") ; else __assert_fail ("scope && \"sym_print_scope: NULL scope\"", "symbol_table.c", 229, __extension__ __PRETTY_FUNCTION__); }));
    char *p = buffer;
    p += sprintf(p, "scope: %p (parent %p)\n", scope, scope->parent);
    struct symbol_info *symbol = scope->symbols;
    while (symbol != ((void *)0))
    {
        p += sym_print_symbol(p, symbol);
        p += sprintf(p, "\n");
        symbol = symbol->next;
    }
    return p - buffer;
}


decompiled_code:
signed __int64 __fastcall print_scope_tree(char *a1, __int64 a2)
{
char *v2; // rbx
__int64 i; // rbp

if ( !a2 )
_assert_fail("scope && \"print_scope_tree: NULL scope\"", "symbol_table.c", 0xCBu, "print_scope_tree");
v2 = &a1[(int)sym_print_scope(a1, (const void **)a2)];
for ( i = *(_QWORD *)(a2 + 24); i; i = *(_QWORD *)(i + 16) )
v2 += (int)print_scope_tree(v2, i);
return v2 - a1;
}

canonical_decompiled_code:
signed __int64 __fastcall func14(char *a1, __int64 a2)
{
char *v2; // rbx
__int64 i; // rbp

if ( !a2 )
_assert_fail("scope && \"print_scope_tree: NULL scope\"", "symbol_table.c", 0xCBu, "print_scope_tree");
v2 = &a1[(int)func13(a1, (const void **)a2)];
for ( i = *(_QWORD *)(a2 + 24); i; i = *(_QWORD *)(i + 16) )
v2 += (int)func14(v2, i);
return v2 - a1;
}

original_code:
static int print_scope_tree(char* buffer, scope_info* scope)
{
    ((void) sizeof ((scope && "print_scope_tree: NULL scope") ? 1 : 0), __extension__ ({ if (scope && "print_scope_tree: NULL scope") ; else __assert_fail ("scope && \"print_scope_tree: NULL scope\"", "symbol_table.c", 203, __extension__ __PRETTY_FUNCTION__); }));
    char* p = buffer;
    p += sym_print_scope(buffer, scope);
    scope_info* child = scope->children;
    while (child != ((void *)0))
    {
        p += print_scope_tree(p, child);
        child = child->next;
    }
    return p - buffer;
}

canonical_original_code:
static int print_scope_tree(char *buffer, struct scope_info *scope)
{
    ((void) sizeof ((scope && "print_scope_tree: NULL scope") ? 1 : 0), __extension__ ({ if (scope && "print_scope_tree: NULL scope") ; else __assert_fail ("scope && \"print_scope_tree: NULL scope\"", "symbol_table.c", 203, __extension__ __PRETTY_FUNCTION__); }));
    char *p = buffer;
    p += sym_print_scope(buffer, scope);
    struct scope_info *child = scope->children;
    while (child != ((void *)0))
    {
        p += print_scope_tree(p, child);
        child = child->next;
    }
    return p - buffer;
}


decompiled_code:
signed __int64 __fastcall sym_print_table(char *a1, __int64 *a2)
{
if ( !a2 )
_assert_fail("table && \"sym_print_table: NULL table\"", "symbol_table.c", 0xDFu, "sym_print_table");
return print_scope_tree(a1, *a2);
}

canonical_decompiled_code:
signed __int64 __fastcall func15(char *a1, __int64 *a2)
{
if ( !a2 )
_assert_fail("table && \"sym_print_table: NULL table\"", "symbol_table.c", 0xDFu, "sym_print_table");
return func14(a1, *a2);
}

original_code:
int sym_print_table(char* buffer, symbol_table* table)
{
    ((void) sizeof ((table && "sym_print_table: NULL table") ? 1 : 0), __extension__ ({ if (table && "sym_print_table: NULL table") ; else __assert_fail ("table && \"sym_print_table: NULL table\"", "symbol_table.c", 223, __extension__ __PRETTY_FUNCTION__); }));
    return print_scope_tree(buffer, table->top_level);
}

canonical_original_code:
int sym_print_table(char *buffer, struct symbol_table *table)
{
    ((void) sizeof ((table && "sym_print_table: NULL table") ? 1 : 0), __extension__ ({ if (table && "sym_print_table: NULL table") ; else __assert_fail ("table && \"sym_print_table: NULL table\"", "symbol_table.c", 223, __extension__ __PRETTY_FUNCTION__); }));
    return print_scope_tree(buffer, table->top_level);
}


decompiled_code:
void MIPS_make_binop()
{
;
}

canonical_decompiled_code:
void func0()
{
;
}

original_code:
MIPS_list* MIPS_make_binop(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_binop(struct ir_item *item)
{
}

variable_types: struct ir_item { enum ir_type { IR_EMPTY=0, IR_DATA=1, IR_BINOP=2, IR_UNOP=3, IR_COPY=4, IR_GOTO=5, IR_BRANCH=6, IR_LABEL=7, IR_LIDX=8, IR_RIDX=9, IR_ADDR=10, IR_LDEREF=11, IR_RDEREF=12, IR_ENTER=13, IR_LEAVE=14, IR_PARAM=15, IR_CALL=16, IR_RET=17, IR_RET_VAL=18, IR_RETRIEVE=19 } type; union { struct { struct address { enum addr_type { ADDR_EMPTY=0, ADDR_SYMBOL=1, ADDR_SYMBOL_NAME=2, ADDR_IMM_INT=3, ADDR_IMM_CHAR=4, ADDR_IMM_STRING=5 } type; union { int integer; char character; char *string; struct symbol_info { enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 } symbol_type; char *name; struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; } *scope; union { struct { struct type { enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 } type; int elements; } var_type; struct codegen_info { enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 } storage; int size; union { int reg; int offset; }; } codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; } *symbol; char *symbol_name; }; } x; union { enum ir_binop { IR_PLUS=0, IR_MINUS=1, IR_TIMES=2, IR_DIV=3, IR_AND=4, IR_OR=5 } binop; enum ir_unop { IR_NEG=0 } unop; enum ir_relop { IR_EQ=0, IR_NEQ=1, IR_GT=2, IR_GTE=3, IR_LT=4, IR_LTE=5 } relop; }; }; struct { char *name; enum ir_data { DATA_RAW=0, DATA_STRING=1 } data_type; union { int bytes; char *text; }; }; struct { char *label; int offset; }; }; } *

return_type: struct MIPS_list { struct MIPS_instruction { enum MIPS_opcode { MIPS_add=0, MIPS_sub=1, MIPS_addi=2, MIPS_mult=3, MIPS_div=4, MIPS_lw=5, MIPS_lb=6, MIPS_sw=7, MIPS_sb=8, MIPS_mfhi=9, MIPS_mflo=10, MIPS_and=11, MIPS_andi=12, MIPS_or=13, MIPS_ori=14, MIPS_slt=15, MIPS_slti=16, MIPS_bgt=17, MIPS_bge=18, MIPS_blt=19, MIPS_ble=20, MIPS_sll=21, MIPS_srl=22, MIPS_beq=23, MIPS_bne=24, MIPS_jal=25, MIPS_jr=26, MIPS_b=27, MIPS_la=28, MIPS_li=29 } opcode; struct MIPS_operand { enum MIPS_operand_type { MIPS_OPERAND_NONE=0, MIPS_REG=1, MIPS_IMM_32=2, MIPS_IMM_8=3, MIPS_OFFSET=4, MIPS_SYMBOL=5 } type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; } x; } instr; struct MIPS_list *next; } *

user_defined_types: struct ir_item { enum ir_type type; union { struct { struct address x; union { enum ir_binop binop; enum ir_unop unop; enum ir_relop relop; }; }; struct { char *name; enum ir_data data_type; union { int bytes; char *text; }; }; struct { char *label; int offset; }; }; }

user_defined_types: struct MIPS_list { struct MIPS_instruction instr; struct MIPS_list *next; }

user_defined_types: struct MIPS_instruction { enum MIPS_opcode opcode; struct MIPS_operand x; }

user_defined_types: struct MIPS_operand { enum MIPS_operand_type type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; }

user_defined_types: struct address { enum addr_type type; union { int integer; char character; char *string; struct symbol_info *symbol; char *symbol_name; }; }


decompiled_code:
void MIPS_make_unop()
{
;
}

canonical_decompiled_code:
void func1()
{
;
}

original_code:
MIPS_list* MIPS_make_unop(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_unop(struct ir_item *item)
{
}

user_defined_types: enum ir_type { IR_EMPTY=0, IR_DATA=1, IR_BINOP=2, IR_UNOP=3, IR_COPY=4, IR_GOTO=5, IR_BRANCH=6, IR_LABEL=7, IR_LIDX=8, IR_RIDX=9, IR_ADDR=10, IR_LDEREF=11, IR_RDEREF=12, IR_ENTER=13, IR_LEAVE=14, IR_PARAM=15, IR_CALL=16, IR_RET=17, IR_RET_VAL=18, IR_RETRIEVE=19 }

user_defined_types: enum MIPS_opcode { MIPS_add=0, MIPS_sub=1, MIPS_addi=2, MIPS_mult=3, MIPS_div=4, MIPS_lw=5, MIPS_lb=6, MIPS_sw=7, MIPS_sb=8, MIPS_mfhi=9, MIPS_mflo=10, MIPS_and=11, MIPS_andi=12, MIPS_or=13, MIPS_ori=14, MIPS_slt=15, MIPS_slti=16, MIPS_bgt=17, MIPS_bge=18, MIPS_blt=19, MIPS_ble=20, MIPS_sll=21, MIPS_srl=22, MIPS_beq=23, MIPS_bne=24, MIPS_jal=25, MIPS_jr=26, MIPS_b=27, MIPS_la=28, MIPS_li=29 }

user_defined_types: enum ir_data { DATA_RAW=0, DATA_STRING=1 }

user_defined_types: enum MIPS_operand_type { MIPS_OPERAND_NONE=0, MIPS_REG=1, MIPS_IMM_32=2, MIPS_IMM_8=3, MIPS_OFFSET=4, MIPS_SYMBOL=5 }

user_defined_types: enum addr_type { ADDR_EMPTY=0, ADDR_SYMBOL=1, ADDR_SYMBOL_NAME=2, ADDR_IMM_INT=3, ADDR_IMM_CHAR=4, ADDR_IMM_STRING=5 }

user_defined_types: enum ir_binop { IR_PLUS=0, IR_MINUS=1, IR_TIMES=2, IR_DIV=3, IR_AND=4, IR_OR=5 }

user_defined_types: enum ir_relop { IR_EQ=0, IR_NEQ=1, IR_GT=2, IR_GTE=3, IR_LT=4, IR_LTE=5 }


decompiled_code:
void MIPS_make_copy()
{
;
}

canonical_decompiled_code:
void func2()
{
;
}

original_code:
MIPS_list* MIPS_make_copy(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_copy(struct ir_item *item)
{
}

user_defined_types: struct symbol_info { enum symbol_type symbol_type; char *name; struct scope_info *scope; union { struct { struct type var_type; struct codegen_info codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; }

user_defined_types: struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; }

user_defined_types: struct type { enum basic_type type; int elements; }

user_defined_types: struct codegen_info { enum storage_type storage; int size; union { int reg; int offset; }; }


decompiled_code:
__int64 __fastcall MIPS_make_goto(__int64 a1)
{
unsigned int v1; // eax
__int64 v2; // rdx
__int64 v3; // rdx
__int64 v4; // rcx
__int64 v5; // r8
__int64 v6; // r9
__int64 v8; // [rsp+0h] [rbp-48h] BYREF

v1 = MIPS_mksymbol(*(_QWORD *)(a1 + 16));
MIPS_mk1(&v8, 27LL, v1, v2);
return MIPS_single_code(&v8, 27LL, v3, v4, v5, v6, v8);
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
unsigned int v1; // eax
__int64 v2; // rdx
__int64 v3; // rdx
__int64 v4; // rcx
__int64 v5; // r8
__int64 v6; // r9
__int64 v8; // [rsp+0h] [rbp-48h] BYREF

v1 = MIPS_mksymbol(*(_QWORD *)(a1 + 16));
MIPS_mk1(&v8, 27LL, v1, v2);
return MIPS_single_code(&v8, 27LL, v3, v4, v5, v6, v8);
}

original_code:
MIPS_list* MIPS_make_goto(ir_item* item)
{
    return MIPS_single_code(MIPS_mk1(
            MIPS_b,
            MIPS_mksymbol(item->x.symbol_name)));
}

canonical_original_code:
struct MIPS_list *MIPS_make_goto(struct ir_item *item)
{
    return MIPS_single_code(MIPS_mk1(
            MIPS_b,
            MIPS_mksymbol(item->x.symbol_name)));
}

user_defined_types: enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 }

user_defined_types: enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 }

user_defined_types: enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 }


decompiled_code:
void MIPS_make_branch()
{
;
}

canonical_decompiled_code:
void func4()
{
;
}

original_code:
MIPS_list* MIPS_make_branch(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_branch(struct ir_item *item)
{
}

user_defined_types: struct ir_item { enum ir_type type; union { struct { struct address x; union { enum ir_binop binop; enum ir_unop unop; enum ir_relop relop; }; }; struct { char *name; enum ir_data data_type; union { int bytes; char *text; }; }; struct { char *label; int offset; }; }; }

user_defined_types: struct MIPS_list { struct MIPS_instruction instr; struct MIPS_list *next; }

user_defined_types: struct MIPS_instruction { enum MIPS_opcode opcode; struct MIPS_operand x; }


decompiled_code:
void MIPS_make_lidx()
{
;
}

canonical_decompiled_code:
void func5()
{
;
}

original_code:
MIPS_list* MIPS_make_lidx(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_lidx(struct ir_item *item)
{
}

user_defined_types: enum ir_type { IR_EMPTY=0, IR_DATA=1, IR_BINOP=2, IR_UNOP=3, IR_COPY=4, IR_GOTO=5, IR_BRANCH=6, IR_LABEL=7, IR_LIDX=8, IR_RIDX=9, IR_ADDR=10, IR_LDEREF=11, IR_RDEREF=12, IR_ENTER=13, IR_LEAVE=14, IR_PARAM=15, IR_CALL=16, IR_RET=17, IR_RET_VAL=18, IR_RETRIEVE=19 }

user_defined_types: struct MIPS_operand { enum MIPS_operand_type type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; }

user_defined_types: struct address { enum addr_type type; union { int integer; char character; char *string; struct symbol_info *symbol; char *symbol_name; }; }


decompiled_code:
void MIPS_make_ridx()
{
;
}

canonical_decompiled_code:
void func6()
{
;
}

original_code:
MIPS_list* MIPS_make_ridx(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_ridx(struct ir_item *item)
{
}

user_defined_types: enum MIPS_opcode { MIPS_add=0, MIPS_sub=1, MIPS_addi=2, MIPS_mult=3, MIPS_div=4, MIPS_lw=5, MIPS_lb=6, MIPS_sw=7, MIPS_sb=8, MIPS_mfhi=9, MIPS_mflo=10, MIPS_and=11, MIPS_andi=12, MIPS_or=13, MIPS_ori=14, MIPS_slt=15, MIPS_slti=16, MIPS_bgt=17, MIPS_bge=18, MIPS_blt=19, MIPS_ble=20, MIPS_sll=21, MIPS_srl=22, MIPS_beq=23, MIPS_bne=24, MIPS_jal=25, MIPS_jr=26, MIPS_b=27, MIPS_la=28, MIPS_li=29 }

user_defined_types: enum ir_data { DATA_RAW=0, DATA_STRING=1 }

user_defined_types: enum MIPS_operand_type { MIPS_OPERAND_NONE=0, MIPS_REG=1, MIPS_IMM_32=2, MIPS_IMM_8=3, MIPS_OFFSET=4, MIPS_SYMBOL=5 }


decompiled_code:
void MIPS_make_addr()
{
;
}

canonical_decompiled_code:
void func7()
{
;
}

original_code:
MIPS_list* MIPS_make_addr(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_addr(struct ir_item *item)
{
}

user_defined_types: enum addr_type { ADDR_EMPTY=0, ADDR_SYMBOL=1, ADDR_SYMBOL_NAME=2, ADDR_IMM_INT=3, ADDR_IMM_CHAR=4, ADDR_IMM_STRING=5 }

user_defined_types: enum ir_binop { IR_PLUS=0, IR_MINUS=1, IR_TIMES=2, IR_DIV=3, IR_AND=4, IR_OR=5 }

user_defined_types: enum ir_relop { IR_EQ=0, IR_NEQ=1, IR_GT=2, IR_GTE=3, IR_LT=4, IR_LTE=5 }


decompiled_code:
void MIPS_make_lderef()
{
;
}

canonical_decompiled_code:
void func8()
{
;
}

original_code:
MIPS_list* MIPS_make_lderef(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_lderef(struct ir_item *item)
{
}

user_defined_types: struct symbol_info { enum symbol_type symbol_type; char *name; struct scope_info *scope; union { struct { struct type var_type; struct codegen_info codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; }

user_defined_types: struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; }

user_defined_types: struct type { enum basic_type type; int elements; }


decompiled_code:
void MIPS_make_rderef()
{
;
}

canonical_decompiled_code:
void func9()
{
;
}

original_code:
MIPS_list* MIPS_make_rderef(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_rderef(struct ir_item *item)
{
}

user_defined_types: enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 }

user_defined_types: struct codegen_info { enum storage_type storage; int size; union { int reg; int offset; }; }

user_defined_types: enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 }


original_code:
MIPS_list* MIPS_make_enter(ir_item* item)
{
    MIPS_list* node = MIPS_empty_list();
    node->instr = MIPS_mk3(
            MIPS_sw,
            MIPS_mkreg(30),
            MIPS_mkreg(29),
            MIPS_mkoffset(-4));
    MIPS_append_item(node, MIPS_mk3(
            MIPS_sw,
            MIPS_mkreg(31),
            MIPS_mkreg(29),
            MIPS_mkoffset(-8)));
    MIPS_append_item(node, MIPS_mk3(
            MIPS_la,
            MIPS_mkreg(30),
            MIPS_mkreg(29),
            MIPS_mkoffset(0)));
    int n = 3;
    MIPS_append_item(node, MIPS_mk3(
            MIPS_la,
            MIPS_mkreg(29),
            MIPS_mkreg(29),
            MIPS_mkoffset(-n)));
    return node;
}

canonical_original_code:
struct MIPS_list *MIPS_make_enter(struct ir_item *item)
{
    struct MIPS_list *node = MIPS_empty_list();
    node->instr = MIPS_mk3(
            MIPS_sw,
            MIPS_mkreg(30),
            MIPS_mkreg(29),
            MIPS_mkoffset(-4));
    MIPS_append_item(node, MIPS_mk3(
            MIPS_sw,
            MIPS_mkreg(31),
            MIPS_mkreg(29),
            MIPS_mkoffset(-8)));
    MIPS_append_item(node, MIPS_mk3(
            MIPS_la,
            MIPS_mkreg(30),
            MIPS_mkreg(29),
            MIPS_mkoffset(0)));
    int n = 3;
    MIPS_append_item(node, MIPS_mk3(
            MIPS_la,
            MIPS_mkreg(29),
            MIPS_mkreg(29),
            MIPS_mkoffset(-n)));
    return node;
}

variable_types: struct MIPS_list { struct MIPS_instruction { enum MIPS_opcode { MIPS_add=0, MIPS_sub=1, MIPS_addi=2, MIPS_mult=3, MIPS_div=4, MIPS_lw=5, MIPS_lb=6, MIPS_sw=7, MIPS_sb=8, MIPS_mfhi=9, MIPS_mflo=10, MIPS_and=11, MIPS_andi=12, MIPS_or=13, MIPS_ori=14, MIPS_slt=15, MIPS_slti=16, MIPS_bgt=17, MIPS_bge=18, MIPS_blt=19, MIPS_ble=20, MIPS_sll=21, MIPS_srl=22, MIPS_beq=23, MIPS_bne=24, MIPS_jal=25, MIPS_jr=26, MIPS_b=27, MIPS_la=28, MIPS_li=29 } opcode; struct MIPS_operand { enum MIPS_operand_type { MIPS_OPERAND_NONE=0, MIPS_REG=1, MIPS_IMM_32=2, MIPS_IMM_8=3, MIPS_OFFSET=4, MIPS_SYMBOL=5 } type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; } x; } instr; struct MIPS_list *next; } *

variable_types: n int

user_defined_types: struct ir_item { enum ir_type type; union { struct { struct address x; union { enum ir_binop binop; enum ir_unop unop; enum ir_relop relop; }; }; struct { char *name; enum ir_data data_type; union { int bytes; char *text; }; }; struct { char *label; int offset; }; }; }

user_defined_types: struct MIPS_list { struct MIPS_instruction instr; struct MIPS_list *next; }

user_defined_types: enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 }


decompiled_code:
void MIPS_make_leave()
{
;
}

original_code:
MIPS_list* MIPS_make_leave(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_leave(struct ir_item *item)
{
}

user_defined_types: enum ir_type { IR_EMPTY=0, IR_DATA=1, IR_BINOP=2, IR_UNOP=3, IR_COPY=4, IR_GOTO=5, IR_BRANCH=6, IR_LABEL=7, IR_LIDX=8, IR_RIDX=9, IR_ADDR=10, IR_LDEREF=11, IR_RDEREF=12, IR_ENTER=13, IR_LEAVE=14, IR_PARAM=15, IR_CALL=16, IR_RET=17, IR_RET_VAL=18, IR_RETRIEVE=19 }

user_defined_types: struct MIPS_instruction { enum MIPS_opcode opcode; struct MIPS_operand x; }

user_defined_types: struct MIPS_operand { enum MIPS_operand_type type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; }


decompiled_code:
void MIPS_make_param()
{
;
}

canonical_decompiled_code:
void func12()
{
;
}

original_code:
MIPS_list* MIPS_make_param(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_param(struct ir_item *item)
{
}

user_defined_types: enum MIPS_opcode { MIPS_add=0, MIPS_sub=1, MIPS_addi=2, MIPS_mult=3, MIPS_div=4, MIPS_lw=5, MIPS_lb=6, MIPS_sw=7, MIPS_sb=8, MIPS_mfhi=9, MIPS_mflo=10, MIPS_and=11, MIPS_andi=12, MIPS_or=13, MIPS_ori=14, MIPS_slt=15, MIPS_slti=16, MIPS_bgt=17, MIPS_bge=18, MIPS_blt=19, MIPS_ble=20, MIPS_sll=21, MIPS_srl=22, MIPS_beq=23, MIPS_bne=24, MIPS_jal=25, MIPS_jr=26, MIPS_b=27, MIPS_la=28, MIPS_li=29 }

user_defined_types: struct address { enum addr_type type; union { int integer; char character; char *string; struct symbol_info *symbol; char *symbol_name; }; }

user_defined_types: enum ir_data { DATA_RAW=0, DATA_STRING=1 }


decompiled_code:
void MIPS_make_call()
{
;
}

canonical_decompiled_code:
void func13()
{
;
}

original_code:
MIPS_list* MIPS_make_call(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_call(struct ir_item *item)
{
}

user_defined_types: enum MIPS_operand_type { MIPS_OPERAND_NONE=0, MIPS_REG=1, MIPS_IMM_32=2, MIPS_IMM_8=3, MIPS_OFFSET=4, MIPS_SYMBOL=5 }

user_defined_types: enum addr_type { ADDR_EMPTY=0, ADDR_SYMBOL=1, ADDR_SYMBOL_NAME=2, ADDR_IMM_INT=3, ADDR_IMM_CHAR=4, ADDR_IMM_STRING=5 }

user_defined_types: enum ir_binop { IR_PLUS=0, IR_MINUS=1, IR_TIMES=2, IR_DIV=3, IR_AND=4, IR_OR=5 }


decompiled_code:
void MIPS_make_ret()
{
;
}

canonical_decompiled_code:
void func14()
{
;
}

original_code:
MIPS_list* MIPS_make_ret(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_ret(struct ir_item *item)
{
}

user_defined_types: enum ir_relop { IR_EQ=0, IR_NEQ=1, IR_GT=2, IR_GTE=3, IR_LT=4, IR_LTE=5 }

user_defined_types: struct symbol_info { enum symbol_type symbol_type; char *name; struct scope_info *scope; union { struct { struct type var_type; struct codegen_info codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; }

user_defined_types: struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; }


decompiled_code:
void MIPS_make_ret_val()
{
;
}

canonical_decompiled_code:
void func15()
{
;
}

original_code:
MIPS_list* MIPS_make_ret_val(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_ret_val(struct ir_item *item)
{
}

user_defined_types: enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 }

user_defined_types: struct type { enum basic_type type; int elements; }

user_defined_types: struct codegen_info { enum storage_type storage; int size; union { int reg; int offset; }; }


decompiled_code:
void MIPS_make_retrieve()
{
;
}

canonical_decompiled_code:
void func16()
{
;
}

original_code:
MIPS_list* MIPS_make_retrieve(ir_item* item)
{
}

canonical_original_code:
struct MIPS_list *MIPS_make_retrieve(struct ir_item *item)
{
}

user_defined_types: struct ir_item { enum ir_type type; union { struct { struct address x; union { enum ir_binop binop; enum ir_unop unop; enum ir_relop relop; }; }; struct { char *name; enum ir_data data_type; union { int bytes; char *text; }; }; struct { char *label; int offset; }; }; }

user_defined_types: struct MIPS_list { struct MIPS_instruction instr; struct MIPS_list *next; }

user_defined_types: enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 }


decompiled_code:
__int64 empty_operand()
{
return 0LL;
}

canonical_decompiled_code:
__int64 func0()
{
return 0LL;
}

original_code:
static MIPS_operand empty_operand(void)
{
    MIPS_operand op;
    op.type = MIPS_OPERAND_NONE;
    return op;
}

canonical_original_code:
static struct MIPS_operand empty_operand()
{
    struct MIPS_operand op;
    op.type = MIPS_OPERAND_NONE;
    return op;
}

variable_types: struct MIPS_operand { enum MIPS_operand_type { MIPS_OPERAND_NONE=0, MIPS_REG=1, MIPS_IMM_32=2, MIPS_IMM_8=3, MIPS_OFFSET=4, MIPS_SYMBOL=5 } type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; }


decompiled_code:
const char *__fastcall MIPS_op_name(int a1)
{
const char *result; // rax

switch ( a1 )
{
case 0:
result = (const char *)&unk_51D;
break;
case 1:
result = "sub";
break;
case 2:
result = "addi";
break;
case 3:
result = "mult";
break;
case 4:
result = "div";
break;
case 5:
result = "lw";
break;
case 6:
result = "lb";
break;
case 7:
result = "sw";
break;
case 8:
result = "sb";
break;
case 9:
result = "mhfi";
break;
case 10:
result = "mflo";
break;
case 11:
result = "and";
break;
case 12:
result = "andi";
break;
case 13:
result = "or";
break;
case 14:
result = "ori";
break;
case 15:
result = "slt";
break;
case 16:
result = "slti";
break;
case 17:
result = "bgt";
break;
case 18:
result = "bge";
break;
case 19:
result = "blt";
break;
case 20:
result = "ble";
break;
case 21:
result = "sll";
break;
case 22:
result = "srl";
break;
case 23:
result = "beq";
break;
case 24:
result = "bne";
break;
case 25:
result = "jal";
break;
case 26:
result = "jr";
break;
case 27:
result = "b";
break;
case 28:
result = "la";
break;
case 29:
result = (const char *)&unk_51A;
break;
default:
_assert_fail("0 && \"MIPS_op_name: invalid opcode\"", "mips.c", 0x2Au, "MIPS_op_name");
}
return result;
}

canonical_decompiled_code:
const char *__fastcall func1(int a1)
{
const char *result; // rax

switch ( a1 )
{
case 0:
result = (const char *)&unk_51D;
break;
case 1:
result = "sub";
break;
case 2:
result = "addi";
break;
case 3:
result = "mult";
break;
case 4:
result = "div";
break;
case 5:
result = "lw";
break;
case 6:
result = "lb";
break;
case 7:
result = "sw";
break;
case 8:
result = "sb";
break;
case 9:
result = "mhfi";
break;
case 10:
result = "mflo";
break;
case 11:
result = "and";
break;
case 12:
result = "andi";
break;
case 13:
result = "or";
break;
case 14:
result = "ori";
break;
case 15:
result = "slt";
break;
case 16:
result = "slti";
break;
case 17:
result = "bgt";
break;
case 18:
result = "bge";
break;
case 19:
result = "blt";
break;
case 20:
result = "ble";
break;
case 21:
result = "sll";
break;
case 22:
result = "srl";
break;
case 23:
result = "beq";
break;
case 24:
result = "bne";
break;
case 25:
result = "jal";
break;
case 26:
result = "jr";
break;
case 27:
result = "b";
break;
case 28:
result = "la";
break;
case 29:
result = (const char *)&unk_51A;
break;
default:
_assert_fail("0 && \"MIPS_op_name: invalid opcode\"", "mips.c", 0x2Au, "MIPS_op_name");
}
return result;
}

original_code:
const char* MIPS_op_name(MIPS_opcode opcode)
{
    switch (opcode)
    {
    case MIPS_add: return "add"; break;
    case MIPS_sub: return "sub"; break;
    case MIPS_addi: return "addi"; break;
    case MIPS_mult: return "mult"; break;
    case MIPS_div: return "div"; break;
    case MIPS_lw: return "lw"; break;
    case MIPS_lb: return "lb"; break;
    case MIPS_sw: return "sw"; break;
    case MIPS_sb: return "sb"; break;
    case MIPS_mfhi: return "mhfi"; break;
    case MIPS_mflo: return "mflo"; break;
    case MIPS_and: return "and"; break;
    case MIPS_andi: return "andi"; break;
    case MIPS_or: return "or"; break;
    case MIPS_ori: return "ori"; break;
    case MIPS_slt: return "slt"; break;
    case MIPS_slti: return "slti"; break;
    case MIPS_bgt: return "bgt"; break;
    case MIPS_bge: return "bge"; break;
    case MIPS_blt: return "blt"; break;
    case MIPS_ble: return "ble"; break;
    case MIPS_sll: return "sll"; break;
    case MIPS_srl: return "srl"; break;
    case MIPS_beq: return "beq"; break;
    case MIPS_bne: return "bne"; break;
    case MIPS_jal: return "jal"; break;
    case MIPS_jr: return "jr"; break;
    case MIPS_b: return "b"; break;
    case MIPS_la: return "la"; break;
    case MIPS_li: return "li"; break;
    }
    ((void) sizeof ((0 && "MIPS_op_name: invalid opcode") ? 1 : 0), __extension__ ({ if (0 && "MIPS_op_name: invalid opcode") ; else __assert_fail ("0 && \"MIPS_op_name: invalid opcode\"", "mips.c", 42, __extension__ __PRETTY_FUNCTION__); }));
    return "INVALID";
}

canonical_original_code:
char *MIPS_op_name(enum MIPS_opcode opcode)
{
    switch (opcode)
    {
    case MIPS_add: return "add"; break;
    case MIPS_sub: return "sub"; break;
    case MIPS_addi: return "addi"; break;
    case MIPS_mult: return "mult"; break;
    case MIPS_div: return "div"; break;
    case MIPS_lw: return "lw"; break;
    case MIPS_lb: return "lb"; break;
    case MIPS_sw: return "sw"; break;
    case MIPS_sb: return "sb"; break;
    case MIPS_mfhi: return "mhfi"; break;
    case MIPS_mflo: return "mflo"; break;
    case MIPS_and: return "and"; break;
    case MIPS_andi: return "andi"; break;
    case MIPS_or: return "or"; break;
    case MIPS_ori: return "ori"; break;
    case MIPS_slt: return "slt"; break;
    case MIPS_slti: return "slti"; break;
    case MIPS_bgt: return "bgt"; break;
    case MIPS_bge: return "bge"; break;
    case MIPS_blt: return "blt"; break;
    case MIPS_ble: return "ble"; break;
    case MIPS_sll: return "sll"; break;
    case MIPS_srl: return "srl"; break;
    case MIPS_beq: return "beq"; break;
    case MIPS_bne: return "bne"; break;
    case MIPS_jal: return "jal"; break;
    case MIPS_jr: return "jr"; break;
    case MIPS_b: return "b"; break;
    case MIPS_la: return "la"; break;
    case MIPS_li: return "li"; break;
    }
    ((void) sizeof ((0 && "MIPS_op_name: invalid opcode") ? 1 : 0), __extension__ ({ if (0 && "MIPS_op_name: invalid opcode") ; else __assert_fail ("0 && \"MIPS_op_name: invalid opcode\"", "mips.c", 42, __extension__ __PRETTY_FUNCTION__); }));
    return "INVALID";
}

variable_types: enum MIPS_opcode { MIPS_add=0, MIPS_sub=1, MIPS_addi=2, MIPS_mult=3, MIPS_div=4, MIPS_lw=5, MIPS_lb=6, MIPS_sw=7, MIPS_sb=8, MIPS_mfhi=9, MIPS_mflo=10, MIPS_and=11, MIPS_andi=12, MIPS_or=13, MIPS_ori=14, MIPS_slt=15, MIPS_slti=16, MIPS_bgt=17, MIPS_bge=18, MIPS_blt=19, MIPS_ble=20, MIPS_sll=21, MIPS_srl=22, MIPS_beq=23, MIPS_bne=24, MIPS_jal=25, MIPS_jr=26, MIPS_b=27, MIPS_la=28, MIPS_li=29 }

return_type: char *


decompiled_code:
__int64 MIPS_mkimm32()
{
return 2LL;
}

canonical_decompiled_code:
__int64 func2()
{
return 2LL;
}

original_code:
MIPS_operand MIPS_mkimm32(int n)
{
    MIPS_operand op;
    op.type = MIPS_IMM_32;
    op.imm32 = n;
    return op;
}

canonical_original_code:
struct MIPS_operand MIPS_mkimm32(int n)
{
    struct MIPS_operand op;
    op.type = MIPS_IMM_32;
    op.imm32 = n;
    return op;
}

return_type: struct MIPS_operand { enum MIPS_operand_type { MIPS_OPERAND_NONE=0, MIPS_REG=1, MIPS_IMM_32=2, MIPS_IMM_8=3, MIPS_OFFSET=4, MIPS_SYMBOL=5 } type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; }


decompiled_code:
__int64 MIPS_mkimm8()
{
return 3LL;
}

canonical_decompiled_code:
__int64 func3()
{
return 3LL;
}

original_code:
MIPS_operand MIPS_mkimm8(char c)
{
    MIPS_operand op;
    op.type = MIPS_IMM_8;
    op.imm8 = c;
    return op;
}

canonical_original_code:
struct MIPS_operand MIPS_mkimm8(char c)
{
    struct MIPS_operand op;
    op.type = MIPS_IMM_8;
    op.imm8 = c;
    return op;
}

variable_types: c char


decompiled_code:
__int64 MIPS_mkreg()
{
return 1LL;
}

canonical_decompiled_code:
__int64 func4()
{
return 1LL;
}

original_code:
MIPS_operand MIPS_mkreg(int reg)
{
    MIPS_operand op;
    op.type = MIPS_REG;
    op.reg = reg;
    return op;
}

canonical_original_code:
struct MIPS_operand MIPS_mkreg(int reg)
{
    struct MIPS_operand op;
    op.type = MIPS_REG;
    op.reg = reg;
    return op;
}

variable_types: reg int


decompiled_code:
__int64 MIPS_mkoffset()
{
return 4LL;
}

canonical_decompiled_code:
__int64 func5()
{
return 4LL;
}

original_code:
MIPS_operand MIPS_mkoffset(int offset)
{
    MIPS_operand op;
    op.type = MIPS_OFFSET;
    op.offset = offset;
    return op;
}

canonical_original_code:
struct MIPS_operand MIPS_mkoffset(int offset)
{
    struct MIPS_operand op;
    op.type = MIPS_OFFSET;
    op.offset = offset;
    return op;
}

variable_types: offset int


decompiled_code:
__int64 __fastcall MIPS_mksymbol(const char *a1)
{
strdup(a1);
return 5LL;
}

canonical_decompiled_code:
__int64 __fastcall func6(const char *a1)
{
strdup(a1);
return 5LL;
}

original_code:
MIPS_operand MIPS_mksymbol(const char* symbol)
{
    MIPS_operand op;
    op.type = MIPS_SYMBOL;
    op.symbol = strdup(symbol);
    return op;
}

canonical_original_code:
struct MIPS_operand MIPS_mksymbol(char *symbol)
{
    struct MIPS_operand op;
    op.type = MIPS_SYMBOL;
    op.symbol = strdup(symbol);
    return op;
}

variable_types:
symbol
char *


decompiled_code:
void __fastcall MIPS_free_operand(__int64 a1)
{
if ( !a1 )
_assert_fail("operand && \"MIPS_free_operand: NULL argument\"", "mips.c", 0x60u, "MIPS_free_operand");
if ( *(_DWORD *)a1 == 5 )
free(*(void **)(a1 + 8));
}

canonical_decompiled_code:
void __fastcall func7(__int64 a1)
{
if ( !a1 )
_assert_fail("operand && \"MIPS_free_operand: NULL argument\"", "mips.c", 0x60u, "MIPS_free_operand");
if ( *(_DWORD *)a1 == 5 )
free(*(void **)(a1 + 8));
}

original_code:
void MIPS_free_operand(MIPS_operand* operand)
{
    ((void) sizeof ((operand && "MIPS_free_operand: NULL argument") ? 1 : 0), __extension__ ({ if (operand && "MIPS_free_operand: NULL argument") ; else __assert_fail ("operand && \"MIPS_free_operand: NULL argument\"", "mips.c", 96, __extension__ __PRETTY_FUNCTION__); }));
    switch (operand->type)
    {
    case MIPS_SYMBOL: free(operand->symbol); break;
    }
}

canonical_original_code:
void MIPS_free_operand(struct MIPS_operand *operand)
{
    ((void) sizeof ((operand && "MIPS_free_operand: NULL argument") ? 1 : 0), __extension__ ({ if (operand && "MIPS_free_operand: NULL argument") ; else __assert_fail ("operand && \"MIPS_free_operand: NULL argument\"", "mips.c", 96, __extension__ __PRETTY_FUNCTION__); }));
    switch (operand->type)
    {
    case MIPS_SYMBOL: free(operand->symbol); break;
    }
}

variable_types: struct MIPS_operand { enum MIPS_operand_type { MIPS_OPERAND_NONE=0, MIPS_REG=1, MIPS_IMM_32=2, MIPS_IMM_8=3, MIPS_OFFSET=4, MIPS_SYMBOL=5 } type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; } *


decompiled_code:
int __fastcall MIPS_write_operand(char *a1, int a2, const char *a3)
{
int result; // eax

switch ( a2 )
{
case 0:
result = -1;
break;
case 1:
switch ( (int)a3 )
{
case 0:
strcpy(a1, "$zero");
result = 5;
break;
case 1:
*(_DWORD *)a1 = 7627044;
result = 3;
break;
case 28:
*(_DWORD *)a1 = 7366436;
result = 3;
break;
case 29:
*(_DWORD *)a1 = 7369508;
result = 3;
break;
case 30:
*(_DWORD *)a1 = 7366180;
result = 3;
break;
case 31:
*(_DWORD *)a1 = 6386212;
result = 3;
break;
default:
if ( (unsigned int)((_DWORD)a3 - 2) <= 1 )
{
sprintf(a1, "$v%d", (unsigned int)((_DWORD)a3 - 2));
result = 3;
}
else if ( (unsigned int)((_DWORD)a3 - 4) <= 3 )
{
sprintf(a1, "$a%d", (unsigned int)((_DWORD)a3 - 4));
result = 3;
}
else if ( (unsigned int)((_DWORD)a3 - 8) <= 7 )
{
sprintf(a1, "$t%d", (unsigned int)((_DWORD)a3 - 8));
result = 3;
}
else if ( (unsigned int)((_DWORD)a3 - 16) <= 7 )
{
sprintf(a1, "$s%d", (unsigned int)((_DWORD)a3 - 16));
result = 3;
}
else if ( (unsigned int)((_DWORD)a3 - 24) <= 1 )
{
sprintf(a1, "$t%d", (unsigned int)((_DWORD)a3 - 16));
result = 3;
}
else
{
if ( (unsigned int)((_DWORD)a3 - 26) > 1 )
_assert_fail("0 && \"MIPS_write_operand: invalid operand type\"", "mips.c", 0xB2u, "MIPS_write_operand");
sprintf(a1, "$k%d", (unsigned int)((_DWORD)a3 - 26));
result = 3;
}
break;
}
break;
case 2:
case 4:
result = sprintf(a1, "%d", a3);
break;
case 3:
result = sprintf(a1, "%d", (unsigned int)(char)a3);
break;
case 5:
result = sprintf(a1, "%s", a3);
break;
default:
result = -1;
break;
}
return result;
}

canonical_decompiled_code:
int __fastcall func11(char *a1, int a2, const char *a3)
{
int result; // eax

switch ( a2 )
{
case 0:
result = -1;
break;
case 1:
switch ( (int)a3 )
{
case 0:
strcpy(a1, "$zero");
result = 5;
break;
case 1:
*(_DWORD *)a1 = 7627044;
result = 3;
break;
case 28:
*(_DWORD *)a1 = 7366436;
result = 3;
break;
case 29:
*(_DWORD *)a1 = 7369508;
result = 3;
break;
case 30:
*(_DWORD *)a1 = 7366180;
result = 3;
break;
case 31:
*(_DWORD *)a1 = 6386212;
result = 3;
break;
default:
if ( (unsigned int)((_DWORD)a3 - 2) <= 1 )
{
sprintf(a1, "$v%d", (unsigned int)((_DWORD)a3 - 2));
result = 3;
}
else if ( (unsigned int)((_DWORD)a3 - 4) <= 3 )
{
sprintf(a1, "$a%d", (unsigned int)((_DWORD)a3 - 4));
result = 3;
}
else if ( (unsigned int)((_DWORD)a3 - 8) <= 7 )
{
sprintf(a1, "$t%d", (unsigned int)((_DWORD)a3 - 8));
result = 3;
}
else if ( (unsigned int)((_DWORD)a3 - 16) <= 7 )
{
sprintf(a1, "$s%d", (unsigned int)((_DWORD)a3 - 16));
result = 3;
}
else if ( (unsigned int)((_DWORD)a3 - 24) <= 1 )
{
sprintf(a1, "$t%d", (unsigned int)((_DWORD)a3 - 16));
result = 3;
}
else
{
if ( (unsigned int)((_DWORD)a3 - 26) > 1 )
_assert_fail("0 && \"MIPS_write_operand: invalid operand type\"", "mips.c", 0xB2u, "MIPS_write_operand");
sprintf(a1, "$k%d", (unsigned int)((_DWORD)a3 - 26));
result = 3;
}
break;
}
break;
case 2:
case 4:
result = sprintf(a1, "%d", a3);
break;
case 3:
result = sprintf(a1, "%d", (unsigned int)(char)a3);
break;
case 5:
result = sprintf(a1, "%s", a3);
break;
default:
result = -1;
break;
}
return result;
}

original_code:
int MIPS_write_operand(char* buffer, MIPS_operand operand)
{
    switch (operand.type)
    {
    case MIPS_SYMBOL:
        return sprintf(buffer, "%s", operand.symbol);
        break;
    case MIPS_OFFSET:
    case MIPS_IMM_32:
        return sprintf(buffer, "%d", operand.imm32);
        break;
    case MIPS_IMM_8:
        return sprintf(buffer, "%d", (int) operand.imm8);
        break;
    case MIPS_REG:
        switch (operand.reg)
        {
        case 0: return sprintf(buffer, "$zero");
        case 1: return sprintf(buffer, "$at");
        case 28: return sprintf(buffer, "$gp");
        case 29: return sprintf(buffer, "$sp");
        case 30: return sprintf(buffer, "$fp");
        case 31: return sprintf(buffer, "$ra");
        default:
        {
            int r = operand.reg;
            if (r >= 2 && r <= 3)
                return sprintf(buffer, "$v%d", r - 2);
            else if (r >= 4 && r <= 7)
                return sprintf(buffer, "$a%d", r - 4);
            else if (r >= 8 && r <= 15)
                return sprintf(buffer, "$t%d", r - 8);
            else if (r >= 16 && r <= 23)
                return sprintf(buffer, "$s%d", r - 16);
            else if (r >= 24 && r <= 25)
                return sprintf(buffer, "$t%d", r - 16);
            else if (r >= 26 && r <= 27)
                return sprintf(buffer, "$k%d", r - 26);
            else
                ((void) sizeof ((0 && "MIPS_write_operand: invalid operand type") ? 1 : 0), __extension__ ({ if (0 && "MIPS_write_operand: invalid operand type") ; else __assert_fail ("0 && \"MIPS_write_operand: invalid operand type\"", "mips.c", 178, __extension__ __PRETTY_FUNCTION__); }));
        }
        break;
        }
        break;
    }
    return -1;
}

canonical_original_code:
int MIPS_write_operand(char *buffer, struct MIPS_operand operand)
{
    switch (operand.type)
    {
    case MIPS_SYMBOL:
        return sprintf(buffer, "%s", operand.symbol);
        break;
    case MIPS_OFFSET:
    case MIPS_IMM_32:
        return sprintf(buffer, "%d", operand.imm32);
        break;
    case MIPS_IMM_8:
        return sprintf(buffer, "%d", (int) operand.imm8);
        break;
    case MIPS_REG:
        switch (operand.reg)
        {
        case 0: return sprintf(buffer, "$zero");
        case 1: return sprintf(buffer, "$at");
        case 28: return sprintf(buffer, "$gp");
        case 29: return sprintf(buffer, "$sp");
        case 30: return sprintf(buffer, "$fp");
        case 31: return sprintf(buffer, "$ra");
        default:
        {
            int r = operand.reg;
            if (r >= 2 && r <= 3)
                return sprintf(buffer, "$v%d", r - 2);
            else if (r >= 4 && r <= 7)
                return sprintf(buffer, "$a%d", r - 4);
            else if (r >= 8 && r <= 15)
                return sprintf(buffer, "$t%d", r - 8);
            else if (r >= 16 && r <= 23)
                return sprintf(buffer, "$s%d", r - 16);
            else if (r >= 24 && r <= 25)
                return sprintf(buffer, "$t%d", r - 16);
            else if (r >= 26 && r <= 27)
                return sprintf(buffer, "$k%d", r - 26);
            else
                ((void) sizeof ((0 && "MIPS_write_operand: invalid operand type") ? 1 : 0), __extension__ ({ if (0 && "MIPS_write_operand: invalid operand type") ; else __assert_fail ("0 && \"MIPS_write_operand: invalid operand type\"", "mips.c", 178, __extension__ __PRETTY_FUNCTION__); }));
        }
        break;
        }
        break;
    }
    return -1;
}

variable_types: r int


decompiled_code:
char *__fastcall MIPS_write_instr(char *s, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, int a7, int a8, __int64 a9, int a10, __int64 a11, int a12, __int64 a13)
{
const char *v14; // rax
char *v15; // rbx
char *v16; // rbx
char *v17; // rdi
char *v19; // rbx
char *v20; // rbx
__int64 v21; // rbx

v14 = MIPS_op_name(a7);
v15 = &s[sprintf(s, " %s ", v14)];
switch ( a7 )
{
case 0:
case 1:
case 2:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
v16 = &v15[MIPS_write_operand(v15, a8, (const char *)a9)];
strcpy(v16, ", ");
v17 = &v16[MIPS_write_operand(v16 + 2, a10, (const char *)a11) + 2];
strcpy(v17, ", ");
MIPS_write_operand(v17 + 2, a12, (const char *)a13);
break;
case 3:
case 4:
case 29:
v19 = &v15[MIPS_write_operand(v15, a8, (const char *)a9)];
strcpy(v19, ", ");
MIPS_write_operand(v19 + 2, a10, (const char *)a11);
break;
case 5:
case 6:
case 7:
case 8:
case 28:
v20 = &v15[MIPS_write_operand(v15, a8, (const char *)a9)];
strcpy(v20, ", ");
v21 = (__int64)&v20[MIPS_write_operand(v20 + 2, a12, (const char *)a13) + 2];
*(_WORD *)v21 = 40;
*(_WORD *)(v21 + 1 + MIPS_write_operand((char *)(v21 + 1), a10, (const char *)a11)) = 41;
break;
case 9:
case 10:
case 25:
case 26:
case 27:
MIPS_write_operand(v15, a8, (const char *)a9);
break;
default:
return s;
}
return s;
}

canonical_decompiled_code:
char *__fastcall func12(char *s, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, int a7, int a8, __int64 a9, int a10, __int64 a11, int a12, __int64 a13)
{
const char *v14; // rax
char *v15; // rbx
char *v16; // rbx
char *v17; // rdi
char *v19; // rbx
char *v20; // rbx
__int64 v21; // rbx

v14 = func1(a7);
v15 = &s[sprintf(s, " %s ", v14)];
switch ( a7 )
{
case 0:
case 1:
case 2:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
v16 = &v15[func11(v15, a8, (const char *)a9)];
strcpy(v16, ", ");
v17 = &v16[func11(v16 + 2, a10, (const char *)a11) + 2];
strcpy(v17, ", ");
func11(v17 + 2, a12, (const char *)a13);
break;
case 3:
case 4:
case 29:
v19 = &v15[func11(v15, a8, (const char *)a9)];
strcpy(v19, ", ");
func11(v19 + 2, a10, (const char *)a11);
break;
case 5:
case 6:
case 7:
case 8:
case 28:
v20 = &v15[func11(v15, a8, (const char *)a9)];
strcpy(v20, ", ");
v21 = (__int64)&v20[func11(v20 + 2, a12, (const char *)a13) + 2];
*(_WORD *)v21 = 40;
*(_WORD *)(v21 + 1 + func11((char *)(v21 + 1), a10, (const char *)a11)) = 41;
break;
case 9:
case 10:
case 25:
case 26:
case 27:
func11(v15, a8, (const char *)a9);
break;
default:
return s;
}
return s;
}

original_code:
char* MIPS_write_instr(char* buffer, MIPS_instruction instr)
{
    char* p = buffer;
    p += sprintf(buffer, "    %s ", MIPS_op_name(instr.opcode));
    switch (instr.opcode)
    {
    case MIPS_add:
    case MIPS_sub:
    case MIPS_addi:
    case MIPS_and:
    case MIPS_andi:
    case MIPS_or:
    case MIPS_ori:
    case MIPS_slt:
    case MIPS_slti:
    case MIPS_sll:
    case MIPS_srl:
    case MIPS_bgt:
    case MIPS_bge:
    case MIPS_blt:
    case MIPS_ble:
    case MIPS_beq:
    case MIPS_bne:
        p += MIPS_write_operand(p, instr.x);
        p += sprintf(p, ", ");
        p += MIPS_write_operand(p, instr.y);
        p += sprintf(p, ", ");
        p += MIPS_write_operand(p, instr.z);
        break;
    case MIPS_mult:
    case MIPS_div:
    case MIPS_li:
        p += MIPS_write_operand(p, instr.x);
        p += sprintf(p, ", ");
        p += MIPS_write_operand(p, instr.y);
        break;
    case MIPS_lw:
    case MIPS_lb:
    case MIPS_la:
    case MIPS_sw:
    case MIPS_sb:
        p += MIPS_write_operand(p, instr.x);
        p += sprintf(p, ", ");
        p += MIPS_write_operand(p, instr.z);
        p += sprintf(p, "(");
        p += MIPS_write_operand(p, instr.y);
        p += sprintf(p, ")");
        break;
    case MIPS_mfhi:
    case MIPS_mflo:
    case MIPS_jal:
    case MIPS_jr:
    case MIPS_b:
        MIPS_write_operand(p, instr.x);
        break;
    }
    return buffer;
}

canonical_original_code:
char *MIPS_write_instr(char *buffer, struct MIPS_instruction instr)
{
    char *p = buffer;
    p += sprintf(buffer, "    %s ", MIPS_op_name(instr.opcode));
    switch (instr.opcode)
    {
    case MIPS_add:
    case MIPS_sub:
    case MIPS_addi:
    case MIPS_and:
    case MIPS_andi:
    case MIPS_or:
    case MIPS_ori:
    case MIPS_slt:
    case MIPS_slti:
    case MIPS_sll:
    case MIPS_srl:
    case MIPS_bgt:
    case MIPS_bge:
    case MIPS_blt:
    case MIPS_ble:
    case MIPS_beq:
    case MIPS_bne:
        p += MIPS_write_operand(p, instr.x);
        p += sprintf(p, ", ");
        p += MIPS_write_operand(p, instr.y);
        p += sprintf(p, ", ");
        p += MIPS_write_operand(p, instr.z);
        break;
    case MIPS_mult:
    case MIPS_div:
    case MIPS_li:
        p += MIPS_write_operand(p, instr.x);
        p += sprintf(p, ", ");
        p += MIPS_write_operand(p, instr.y);
        break;
    case MIPS_lw:
    case MIPS_lb:
    case MIPS_la:
    case MIPS_sw:
    case MIPS_sb:
        p += MIPS_write_operand(p, instr.x);
        p += sprintf(p, ", ");
        p += MIPS_write_operand(p, instr.z);
        p += sprintf(p, "(");
        p += MIPS_write_operand(p, instr.y);
        p += sprintf(p, ")");
        break;
    case MIPS_mfhi:
    case MIPS_mflo:
    case MIPS_jal:
    case MIPS_jr:
    case MIPS_b:
        MIPS_write_operand(p, instr.x);
        break;
    }
    return buffer;
}

variable_types: struct MIPS_instruction { enum MIPS_opcode { MIPS_add=0, MIPS_sub=1, MIPS_addi=2, MIPS_mult=3, MIPS_div=4, MIPS_lw=5, MIPS_lb=6, MIPS_sw=7, MIPS_sb=8, MIPS_mfhi=9, MIPS_mflo=10, MIPS_and=11, MIPS_andi=12, MIPS_or=13, MIPS_ori=14, MIPS_slt=15, MIPS_slti=16, MIPS_bgt=17, MIPS_bge=18, MIPS_blt=19, MIPS_ble=20, MIPS_sll=21, MIPS_srl=22, MIPS_beq=23, MIPS_bne=24, MIPS_jal=25, MIPS_jr=26, MIPS_b=27, MIPS_la=28, MIPS_li=29 } opcode; struct MIPS_operand { enum MIPS_operand_type { MIPS_OPERAND_NONE=0, MIPS_REG=1, MIPS_IMM_32=2, MIPS_IMM_8=3, MIPS_OFFSET=4, MIPS_SYMBOL=5 } type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; } x; }

user_defined_types: struct MIPS_instruction { enum MIPS_opcode opcode; struct MIPS_operand x; }


decompiled_code:
void __fastcall MIPS_free_instr(__int64 a1)
{
if ( !a1 )
_assert_fail("instruction && \"MIPS_free_instr: NULL argument passed\"", "mips.c", 0xFDu, "MIPS_free_instr");
MIPS_free_operand(a1 + 8);
MIPS_free_operand(a1 + 24);
MIPS_free_operand(a1 + 40);
}

canonical_decompiled_code:
void __fastcall func13(__int64 a1)
{
if ( !a1 )
_assert_fail("instruction && \"MIPS_free_instr: NULL argument passed\"", "mips.c", 0xFDu, "MIPS_free_instr");
func7(a1 + 8);
func7(a1 + 24);
func7(a1 + 40);
}

original_code:
void MIPS_free_instr(MIPS_instruction* instruction)
{
    ((void) sizeof ((instruction && "MIPS_free_instr: NULL argument passed") ? 1 : 0), __extension__ ({ if (instruction && "MIPS_free_instr: NULL argument passed") ; else __assert_fail ("instruction && \"MIPS_free_instr: NULL argument passed\"", "mips.c", 253, __extension__ __PRETTY_FUNCTION__); }));
    MIPS_free_operand(&instruction->x);
    MIPS_free_operand(&instruction->y);
    MIPS_free_operand(&instruction->z);
}

canonical_original_code:
void MIPS_free_instr(struct MIPS_instruction *instruction)
{
    ((void) sizeof ((instruction && "MIPS_free_instr: NULL argument passed") ? 1 : 0), __extension__ ({ if (instruction && "MIPS_free_instr: NULL argument passed") ; else __assert_fail ("instruction && \"MIPS_free_instr: NULL argument passed\"", "mips.c", 253, __extension__ __PRETTY_FUNCTION__); }));
    MIPS_free_operand(&instruction->x);
    MIPS_free_operand(&instruction->y);
    MIPS_free_operand(&instruction->z);
}

variable_types: struct MIPS_instruction { enum MIPS_opcode { MIPS_add=0, MIPS_sub=1, MIPS_addi=2, MIPS_mult=3, MIPS_div=4, MIPS_lw=5, MIPS_lb=6, MIPS_sw=7, MIPS_sb=8, MIPS_mfhi=9, MIPS_mflo=10, MIPS_and=11, MIPS_andi=12, MIPS_or=13, MIPS_ori=14, MIPS_slt=15, MIPS_slti=16, MIPS_bgt=17, MIPS_bge=18, MIPS_blt=19, MIPS_ble=20, MIPS_sll=21, MIPS_srl=22, MIPS_beq=23, MIPS_bne=24, MIPS_jal=25, MIPS_jr=26, MIPS_b=27, MIPS_la=28, MIPS_li=29 } opcode; struct MIPS_operand { enum MIPS_operand_type { MIPS_OPERAND_NONE=0, MIPS_REG=1, MIPS_IMM_32=2, MIPS_IMM_8=3, MIPS_OFFSET=4, MIPS_SYMBOL=5 } type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; } x; } *

user_defined_types: struct MIPS_operand { enum MIPS_operand_type type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; }


original_code:
int calc_escaped_size(const char* text)
{
    int n = 0;
    while (*text)
    {
        switch(*text++)
        {
        case '\t': n += 2; break;
        case '\n': n += 2; break;
        case '\"': n += 2; break;
        case '\\': n += 2; break;
        case '\r': n += 2; break;
        default: ++ n; break;
        }
    }
    return n;
}

canonical_original_code:
int calc_escaped_size(char *text)
{
    int n = 0;
    while (*text)
    {
        switch(*text++)
        {
        case '\t': n += 2; break;
        case '\n': n += 2; break;
        case '\"': n += 2; break;
        case '\\': n += 2; break;
        case '\r': n += 2; break;
        default: ++ n; break;
        }
    }
    return n;
}

variable_types:
text
char *


original_code:
char* escape_string(char* dest, const char* src)
{
    char* p = dest;
    while (*src)
    {
        switch(*src)
        {
        case '\t': strcpy(p, "\\t"); p += 2; break;
        case '\n': strcpy(p, "\\n"); p += 2; break;
        case '\"': strcpy(p, "\\\""); p += 2; break;
        case '\\': strcpy(p, "\\\\"); p += 2; break;
        case '\r': strcpy(p, "\\r"); p += 2; break;
        default: *p ++ = *src; break;
        }
        ++ src;
    }
    return dest;
}

canonical_original_code:
char *escape_string(char *dest, char *src)
{
    char *p = dest;
    while (*src)
    {
        switch(*src)
        {
        case '\t': strcpy(p, "\\t"); p += 2; break;
        case '\n': strcpy(p, "\\n"); p += 2; break;
        case '\"': strcpy(p, "\\\""); p += 2; break;
        case '\\': strcpy(p, "\\\\"); p += 2; break;
        case '\r': strcpy(p, "\\r"); p += 2; break;
        default: *p ++ = *src; break;
        }
        ++ src;
    }
    return dest;
}

variable_types:
dest
char *

variable_types:
src
char *


decompiled_code:
char *__fastcall escape_alloc(char *a1)
{
int v1; // eax
char *v2; // rax

v1 = calc_escaped_size(a1);
v2 = (char *)malloc(v1);
return escape_string(v2, a1);
}

canonical_decompiled_code:
char *__fastcall func2(char *a1)
{
int v1; // eax
char *v2; // rax

v1 = func0(a1);
v2 = (char *)malloc(v1);
return func1(v2, a1);
}

original_code:
char* escape_alloc(const char* text)
{
    char* buffer = malloc(calc_escaped_size(text));
    return escape_string(buffer, text);
}

canonical_original_code:
char *escape_alloc(char *text)
{
    char *buffer = malloc(calc_escaped_size(text));
    return escape_string(buffer, text);
}

variable_types:
buffer
char *


decompiled_code:
__int64 __fastcall ctx_pop_scope(__int64 a1)
{
__int64 result; // rax

result = *(_QWORD *)(*(_QWORD *)(a1 + 16) + 8LL);
*(_QWORD *)(a1 + 16) = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
__int64 result; // rax

result = *(_QWORD *)(*(_QWORD *)(a1 + 16) + 8LL);
*(_QWORD *)(a1 + 16) = result;
return result;
}

original_code:
static void ctx_pop_scope(context* ctx)
{
    ctx->scope = ctx->scope->parent;
}

canonical_original_code:
static void ctx_pop_scope(struct context *ctx)
{
    ctx->scope = ctx->scope->parent;
}

variable_types: struct context { struct ir_code { struct ir_list { struct ir_item { enum ir_type { IR_EMPTY=0, IR_DATA=1, IR_BINOP=2, IR_UNOP=3, IR_COPY=4, IR_GOTO=5, IR_BRANCH=6, IR_LABEL=7, IR_LIDX=8, IR_RIDX=9, IR_ADDR=10, IR_LDEREF=11, IR_RDEREF=12, IR_ENTER=13, IR_LEAVE=14, IR_PARAM=15, IR_CALL=16, IR_RET=17, IR_RET_VAL=18, IR_RETRIEVE=19 } type; union { struct { struct address { enum addr_type { ADDR_EMPTY=0, ADDR_SYMBOL=1, ADDR_SYMBOL_NAME=2, ADDR_IMM_INT=3, ADDR_IMM_CHAR=4, ADDR_IMM_STRING=5 } type; union { int integer; char character; char *string; struct symbol_info { enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 } symbol_type; char *name; struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; } *scope; union { struct { struct type { enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 } type; int elements; } var_type; struct codegen_info { enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 } storage; int size; union { int reg; int offset; }; } codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; } *symbol; char *symbol_name; }; } x; union { enum ir_binop { IR_PLUS=0, IR_MINUS=1, IR_TIMES=2, IR_DIV=3, IR_AND=4, IR_OR=5 } binop; enum ir_unop { IR_NEG=0 } unop; enum ir_relop { IR_EQ=0, IR_NEQ=1, IR_GT=2, IR_GTE=3, IR_LT=4, IR_LTE=5 } relop; }; }; struct { char *name; enum ir_data { DATA_RAW=0, DATA_STRING=1 } data_type; union { int bytes; char *text; }; }; struct { char *label; int offset; }; }; } item; struct ir_list *next; } *codes; struct symbol_table { struct scope_info *top_level; struct symbol_info *literals; } table; } *code; struct ir_list *last; struct scope_info *scope; int tmp_counter; int label_counter; } *

user_defined_types: struct context { struct ir_code *code; struct ir_list *last; struct scope_info *scope; int tmp_counter; int label_counter; }

user_defined_types: struct ir_code { struct ir_list *codes; struct symbol_table table; }

user_defined_types: struct ir_list { struct ir_item item; struct ir_list *next; }


decompiled_code:
_QWORD *make_code_struct()
{
_QWORD *v0; // rbx

v0 = malloc(0x18uLL);
*v0 = 0LL;
clean_symbol_table(v0 + 1);
return v0;
}

canonical_decompiled_code:
_QWORD *func1()
{
_QWORD *v0; // rbx

v0 = malloc(0x18uLL);
*v0 = 0LL;
clean_symbol_table(v0 + 1);
return v0;
}

original_code:
static ir_code* make_code_struct(void)
{
    ir_code* code = malloc(sizeof(ir_code));
    code->codes = ((void *)0);
    clean_symbol_table(&code->table);
    return code;
}

canonical_original_code:
static struct ir_code *make_code_struct()
{
    struct ir_code *code = malloc(sizeof(ir_code));
    code->codes = ((void *)0);
    clean_symbol_table(&code->table);
    return code;
}

variable_types: struct ir_code { struct ir_list { struct ir_item { enum ir_type { IR_EMPTY=0, IR_DATA=1, IR_BINOP=2, IR_UNOP=3, IR_COPY=4, IR_GOTO=5, IR_BRANCH=6, IR_LABEL=7, IR_LIDX=8, IR_RIDX=9, IR_ADDR=10, IR_LDEREF=11, IR_RDEREF=12, IR_ENTER=13, IR_LEAVE=14, IR_PARAM=15, IR_CALL=16, IR_RET=17, IR_RET_VAL=18, IR_RETRIEVE=19 } type; union { struct { struct address { enum addr_type { ADDR_EMPTY=0, ADDR_SYMBOL=1, ADDR_SYMBOL_NAME=2, ADDR_IMM_INT=3, ADDR_IMM_CHAR=4, ADDR_IMM_STRING=5 } type; union { int integer; char character; char *string; struct symbol_info { enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 } symbol_type; char *name; struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; } *scope; union { struct { struct type { enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 } type; int elements; } var_type; struct codegen_info { enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 } storage; int size; union { int reg; int offset; }; } codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; } *symbol; char *symbol_name; }; } x; union { enum ir_binop { IR_PLUS=0, IR_MINUS=1, IR_TIMES=2, IR_DIV=3, IR_AND=4, IR_OR=5 } binop; enum ir_unop { IR_NEG=0 } unop; enum ir_relop { IR_EQ=0, IR_NEQ=1, IR_GT=2, IR_GTE=3, IR_LT=4, IR_LTE=5 } relop; }; }; struct { char *name; enum ir_data { DATA_RAW=0, DATA_STRING=1 } data_type; union { int bytes; char *text; }; }; struct { char *label; int offset; }; }; } item; struct ir_list *next; } *codes; struct symbol_table { struct scope_info *top_level; struct symbol_info *literals; } table; } *

user_defined_types: struct address { enum addr_type type; union { int integer; char character; char *string; struct symbol_info *symbol; char *symbol_name; }; }


decompiled_code:
__int64 __fastcall ctx_push_scope(__int64 a1, __int64 a2)
{
__int64 result; // rax

result = sym_add_child_scope(*(_QWORD *)(a1 + 16));
*(_QWORD *)(a1 + 16) = a2;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, __int64 a2)
{
__int64 result; // rax

result = sym_add_child_scope(*(_QWORD *)(a1 + 16));
*(_QWORD *)(a1 + 16) = a2;
return result;
}

original_code:
static void ctx_push_scope(context* ctx, scope_info* scope)
{
    sym_add_child_scope(ctx->scope, scope);
    ctx->scope = scope;
}

canonical_original_code:
static void ctx_push_scope(struct context *ctx, struct scope_info *scope)
{
    sym_add_child_scope(ctx->scope, scope);
    ctx->scope = scope;
}

variable_types:
scope
struct scope_info *

user_defined_types: struct symbol_table { struct scope_info *top_level; struct symbol_info *literals; }

user_defined_types: enum ir_type { IR_EMPTY=0, IR_DATA=1, IR_BINOP=2, IR_UNOP=3, IR_COPY=4, IR_GOTO=5, IR_BRANCH=6, IR_LABEL=7, IR_LIDX=8, IR_RIDX=9, IR_ADDR=10, IR_LDEREF=11, IR_RDEREF=12, IR_ENTER=13, IR_LEAVE=14, IR_PARAM=15, IR_CALL=16, IR_RET=17, IR_RET_VAL=18, IR_RETRIEVE=19 }

user_defined_types: enum ir_data { DATA_RAW=0, DATA_STRING=1 }

user_defined_types: enum addr_type { ADDR_EMPTY=0, ADDR_SYMBOL=1, ADDR_SYMBOL_NAME=2, ADDR_IMM_INT=3, ADDR_IMM_CHAR=4, ADDR_IMM_STRING=5 }

user_defined_types: enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 }


decompiled_code:
__int64 __fastcall ctx_push_new_scope(__int64 a1)
{
__int64 v1; // r12
__int64 v2; // rbp
__int64 result; // rax

v1 = *(_QWORD *)(a1 + 16);
v2 = sym_mkscope(v1);
result = sym_add_child_scope(v1);
*(_QWORD *)(a1 + 16) = v2;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
__int64 v1; // r12
__int64 v2; // rbp
__int64 result; // rax

v1 = *(_QWORD *)(a1 + 16);
v2 = sym_mkscope(v1);
result = sym_add_child_scope(v1);
*(_QWORD *)(a1 + 16) = v2;
return result;
}

original_code:
static void ctx_push_new_scope(context* ctx)
{
    scope_info* parent = ctx->scope;
    scope_info* scope = sym_mkscope(parent);
    sym_add_child_scope(parent, scope);
    ctx->scope = scope;
}

canonical_original_code:
static void ctx_push_new_scope(struct context *ctx)
{
    struct scope_info *parent = ctx->scope;
    struct scope_info *scope = sym_mkscope(parent);
    sym_add_child_scope(parent, scope);
    ctx->scope = scope;
}

variable_types: struct scope_info { struct symbol_info { enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 } symbol_type; char *name; struct scope_info *scope; union { struct { struct type { enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 } type; int elements; } var_type; struct codegen_info { enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 } storage; int size; union { int reg; int offset; }; } codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; } *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; } *

user_defined_types: struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; }

user_defined_types: struct symbol_info { enum symbol_type symbol_type; char *name; struct scope_info *scope; union { struct { struct type var_type; struct codegen_info codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; }

user_defined_types: enum ir_binop { IR_PLUS=0, IR_MINUS=1, IR_TIMES=2, IR_DIV=3, IR_AND=4, IR_OR=5 }

user_defined_types: enum ir_relop { IR_EQ=0, IR_NEQ=1, IR_GT=2, IR_GTE=3, IR_LT=4, IR_LTE=5 }


decompiled_code:
__int64 __fastcall process_expr_id(__int64 a1, __int64 a2)
{
__int64 v2; // rax

printf("expr_id (%s)\n", *(const char **)(a1 + 8));
v2 = ctx_lookup(*(_QWORD *)(a1 + 8), a2);
if ( v2 )
return ir_mksymbol(v2);
fprintf(stderr, "[%s]: Error: unknown identifier `%s'\n", "???", *(const char **)(a1 + 8));
return ir_mkempty();
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1, __int64 a2)
{
__int64 v2; // rax

printf("expr_id (%s)\n", *(const char **)(a1 + 8));
v2 = func9(*(_QWORD *)(a1 + 8), a2);
if ( v2 )
return ir_mksymbol(v2);
fprintf(stderr, "[%s]: Error: unknown identifier `%s'\n", "???", *(const char **)(a1 + 8));
return ir_mkempty();
}

original_code:
static address process_expr_id(expr* exp, context* ctx)
{
    printf("expr_id (%s)\n", exp->id);
    symbol_info* info = ctx_lookup(exp->id, ctx);
    if (info == ((void *)0))
    {
        fprintf(stderr, "[%s]: Error: unknown identifier `%s'\n",
                "???", exp->id);
        return ir_mkempty();
    }
    else
        return ir_mksymbol(info);
}

canonical_original_code:
static struct address process_expr_id(struct expr *exp, struct context *ctx)
{
    printf("expr_id (%s)\n", exp->id);
    struct symbol_info *info = ctx_lookup(exp->id, ctx);
    if (info == ((void *)0))
    {
        fprintf(stderr, "[%s]: Error: unknown identifier `%s'\n",
                "???", exp->id);
        return ir_mkempty();
    }
    else
        return ir_mksymbol(info);
}

variable_types: struct expr { enum expr_type { EXP_ID=0, EXP_INT=1, EXP_CHAR=2, EXP_STRING=3, EXP_PLUS=100, EXP_MINUS=101, EXP_TIMES=102, EXP_DIV=103, EXP_EQ=104, EXP_NEQ=105, EXP_LTE=106, EXP_GTE=107, EXP_LT=108, EXP_GT=109, EXP_AND=110, EXP_OR=111, EXP_UNMINUS=150, EXP_NEG=151, EXP_INDEX=200, EXP_CALL=201 } type; union { union { struct { struct expr *left; struct expr *right; }; struct { char *id; struct expr_list { struct expr *expression; struct expr_list *next; } *args; }; struct { struct expr *expression; struct expr *index; }; }; union { char *string; int integer; char character; }; }; } *

variable_types: struct context { struct ir_code { struct ir_list { struct ir_item { enum ir_type { IR_EMPTY=0, IR_DATA=1, IR_BINOP=2, IR_UNOP=3, IR_COPY=4, IR_GOTO=5, IR_BRANCH=6, IR_LABEL=7, IR_LIDX=8, IR_RIDX=9, IR_ADDR=10, IR_LDEREF=11, IR_RDEREF=12, IR_ENTER=13, IR_LEAVE=14, IR_PARAM=15, IR_CALL=16, IR_RET=17, IR_RET_VAL=18, IR_RETRIEVE=19 } type; union { struct { struct address x; union { enum ir_binop { IR_PLUS=0, IR_MINUS=1, IR_TIMES=2, IR_DIV=3, IR_AND=4, IR_OR=5 } binop; enum ir_unop { IR_NEG=0 } unop; enum ir_relop { IR_EQ=0, IR_NEQ=1, IR_GT=2, IR_GTE=3, IR_LT=4, IR_LTE=5 } relop; }; }; struct { char *name; enum ir_data { DATA_RAW=0, DATA_STRING=1 } data_type; union { int bytes; char *text; }; }; struct { char *label; int offset; }; }; } item; struct ir_list *next; } *codes; struct symbol_table { struct scope_info *top_level; struct symbol_info *literals; } table; } *code; struct ir_list *last; struct scope_info *scope; int tmp_counter; int label_counter; } *

return_type: struct address { enum addr_type { ADDR_EMPTY=0, ADDR_SYMBOL=1, ADDR_SYMBOL_NAME=2, ADDR_IMM_INT=3, ADDR_IMM_CHAR=4, ADDR_IMM_STRING=5 } type; union { int integer; char character; char *string; struct symbol_info { enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 } symbol_type; char *name; struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; } *scope; union { struct { struct type { enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 } type; int elements; } var_type; struct codegen_info { enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 } storage; int size; union { int reg; int offset; }; } codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; } *symbol; char *symbol_name; }; }

user_defined_types: struct expr { enum expr_type type; union { union { struct { struct expr *left; struct expr *right; }; struct { char *id; struct expr_list *args; }; struct { struct expr *expression; struct expr *index; }; }; union { char *string; int integer; char character; }; }; }

user_defined_types: struct type { enum basic_type type; int elements; }

user_defined_types: struct codegen_info { enum storage_type storage; int size; union { int reg; int offset; }; }

user_defined_types: struct ir_item { enum ir_type type; union { struct { struct address x; union { enum ir_binop binop; enum ir_unop unop; enum ir_relop relop; }; }; struct { char *name; enum ir_data data_type; union { int bytes; char *text; }; }; struct { char *label; int offset; }; }; }


decompiled_code:
__int64 __fastcall process_expr_string(__int64 a1, _QWORD *a2)
{
printf("expr_string (%s)\n", *(const char **)(a1 + 8));
return ctx_mkliteral(*(_QWORD *)(a1 + 8), a2);
}

canonical_decompiled_code:
__int64 __fastcall func12(__int64 a1, _QWORD *a2)
{
printf("expr_string (%s)\n", *(const char **)(a1 + 8));
return func11(*(_QWORD *)(a1 + 8), a2);
}

original_code:
static address process_expr_string(expr* exp, context* ctx)
{
    printf("expr_string (%s)\n", exp->string);
    return ctx_mkliteral(exp->string, ctx);
}

canonical_original_code:
static struct address process_expr_string(struct expr *exp, struct context *ctx)
{
    printf("expr_string (%s)\n", exp->string);
    return ctx_mkliteral(exp->string, ctx);
}

user_defined_types: struct context { struct ir_code *code; struct ir_list *last; struct scope_info *scope; int tmp_counter; int label_counter; }

user_defined_types: enum expr_type { EXP_ID=0, EXP_INT=1, EXP_CHAR=2, EXP_STRING=3, EXP_PLUS=100, EXP_MINUS=101, EXP_TIMES=102, EXP_DIV=103, EXP_EQ=104, EXP_NEQ=105, EXP_LTE=106, EXP_GTE=107, EXP_LT=108, EXP_GT=109, EXP_AND=110, EXP_OR=111, EXP_UNMINUS=150, EXP_NEG=151, EXP_INDEX=200, EXP_CALL=201 }

user_defined_types: enum symbol_type { SYM_NONE=0, SYM_FUN=1, SYM_VAR=2, SYM_LITERAL=3 }

user_defined_types: struct expr_list { struct expr *expression; struct expr_list *next; }

user_defined_types: enum basic_type { T_VOID=0, T_INT=1, T_CHAR=2, T_INT_ARRAY=3, T_CHAR_ARRAY=4 }


decompiled_code:
unsigned int __fastcall process_statement(__int64 a1, _QWORD *a2, __int64 a3, __int64 a4, unsigned int a5)
{
unsigned int result; // eax

result = *(_DWORD *)a1;
if ( *(_DWORD *)a1 == 101 )
return process_return(*(const void **)(a1 + 24));
if ( result > 0x65 )
{
if ( result != 102 && result != 200 )
goto LABEL_10;
}
else if ( result > 2 )
{
if ( result == 100 )
return process_expr(*(_QWORD *)(a1 + 24), a2, a3, a4, a5);
LABEL_10:
_assert_fail("0 && \"process_statement: unknown statement type\"", "ir_generator.c", 0xA0u, "process_statement");
}
return result;
}

canonical_decompiled_code:
unsigned int __fastcall func14(__int64 a1, _QWORD *a2, __int64 a3, __int64 a4, unsigned int a5)
{
unsigned int result; // eax

result = *(_DWORD *)a1;
if ( *(_DWORD *)a1 == 101 )
return func8(*(const void **)(a1 + 24));
if ( result > 0x65 )
{
if ( result != 102 && result != 200 )
goto LABEL_10;
}
else if ( result > 2 )
{
if ( result == 100 )
return func13(*(_QWORD *)(a1 + 24), a2, a3, a4, a5);
LABEL_10:
_assert_fail("0 && \"process_statement: unknown statement type\"", "ir_generator.c", 0xA0u, "process_statement");
}
return result;
}

original_code:
static void process_statement(stmt* statement, context* ctx)
{
    switch (statement->type)
    {
    case STM_ASSIGN: break;
    case STM_COMPOUND: break;
    case STM_EXP:
        process_expr(statement->expression, ctx);
        break;
    case STM_FOR: break;
    case STM_IF: break;
    case STM_RETURN:
        process_return(statement->expression, ctx);
        break;
    case STM_WHILE: break;
    default:
        ((void) sizeof ((0 && "process_statement: unknown statement type") ? 1 : 0), __extension__ ({ if (0 && "process_statement: unknown statement type") ; else __assert_fail ("0 && \"process_statement: unknown statement type\"", "ir_generator.c", 160, __extension__ __PRETTY_FUNCTION__); }));
        break;
    }
}

canonical_original_code:
static void process_statement(struct stmt *statement, struct context *ctx)
{
    switch (statement->type)
    {
    case STM_ASSIGN: break;
    case STM_COMPOUND: break;
    case STM_EXP:
        process_expr(statement->expression, ctx);
        break;
    case STM_FOR: break;
    case STM_IF: break;
    case STM_RETURN:
        process_return(statement->expression, ctx);
        break;
    case STM_WHILE: break;
    default:
        ((void) sizeof ((0 && "process_statement: unknown statement type") ? 1 : 0), __extension__ ({ if (0 && "process_statement: unknown statement type") ; else __assert_fail ("0 && \"process_statement: unknown statement type\"", "ir_generator.c", 160, __extension__ __PRETTY_FUNCTION__); }));
        break;
    }
}

variable_types: struct stmt { enum stmt_type { STM_IF=0, STM_WHILE=1, STM_FOR=2, STM_EXP=100, STM_RETURN=101, STM_ASSIGN=102, STM_COMPOUND=200 } type; union { struct { char *name; struct expr { enum expr_type { EXP_ID=0, EXP_INT=1, EXP_CHAR=2, EXP_STRING=3, EXP_PLUS=100, EXP_MINUS=101, EXP_TIMES=102, EXP_DIV=103, EXP_EQ=104, EXP_NEQ=105, EXP_LTE=106, EXP_GTE=107, EXP_LT=108, EXP_GT=109, EXP_AND=110, EXP_OR=111, EXP_UNMINUS=150, EXP_NEG=151, EXP_INDEX=200, EXP_CALL=201 } type; union { union { struct { struct expr *left; struct expr *right; }; struct { char *id; struct expr_list { struct expr *expression; struct expr_list *next; } *args; }; struct { struct expr *expression; struct expr *index; }; }; union { char *string; int integer; char character; }; }; } *index; struct expr *expression; }; struct { struct stmt *init; struct expr *condition; struct stmt *update; struct stmt *body; struct stmt *else_body; }; struct stmt_list { struct stmt *statement; struct stmt_list *next; } *list; }; } *

user_defined_types: struct stmt { enum stmt_type type; union { struct { char *name; struct expr *index; struct expr *expression; }; struct { struct stmt *init; struct expr *condition; struct stmt *update; struct stmt *body; struct stmt *else_body; }; struct stmt_list *list; }; }

user_defined_types: struct ir_code { struct ir_list *codes; struct symbol_table table; }

user_defined_types: struct symbol_table { struct scope_info *top_level; struct symbol_info *literals; }

user_defined_types: struct ir_list { struct ir_item item; struct ir_list *next; }

user_defined_types: enum ir_type { IR_EMPTY=0, IR_DATA=1, IR_BINOP=2, IR_UNOP=3, IR_COPY=4, IR_GOTO=5, IR_BRANCH=6, IR_LABEL=7, IR_LIDX=8, IR_RIDX=9, IR_ADDR=10, IR_LDEREF=11, IR_RDEREF=12, IR_ENTER=13, IR_LEAVE=14, IR_PARAM=15, IR_CALL=16, IR_RET=17, IR_RET_VAL=18, IR_RETRIEVE=19 }

user_defined_types: struct address { enum addr_type type; union { int integer; char character; char *string; struct symbol_info *symbol; char *symbol_name; }; }


decompiled_code:
__int64 __fastcall process_toplevel(_DWORD *a1, _QWORD *a2)
{
__int64 result; // rax

if ( *a1 == 1 )
result = process_fun((__int64)a1, a2);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func17(_DWORD *a1, _QWORD *a2)
{
__int64 result; // rax

if ( *a1 == 1 )
result = func16((__int64)a1, a2);
return result;
}

original_code:
static void process_toplevel(node* node, context* ctx)
{
    switch (node->type)
    {
    case NODE_DECL: process_decl(node, ctx); break;
    case NODE_FUN: process_fun(node, ctx); break;
    }
}

canonical_original_code:
static void process_toplevel(struct node *node, struct context *ctx)
{
    switch (node->type)
    {
    case NODE_DECL: process_decl(node, ctx); break;
    case NODE_FUN: process_fun(node, ctx); break;
    }
}

variable_types: struct node { enum node_type { NODE_DECL=0, NODE_FUN=1 } type; union { struct fun_def { struct decl { enum value_type { TYPE_INT=0, TYPE_CHAR=1, TYPE_VOID=2 } type; int is_extern; struct decltor_list { struct decltor { enum decltor_type { DECLTOR_FUN=0, DECLTOR_ARRAY=1, DECLTOR_SIMPLE=2 } type; char *name; union { struct decl_list { struct decl *declaration; struct decl_list *next; } *params; struct expr { enum expr_type { EXP_ID=0, EXP_INT=1, EXP_CHAR=2, EXP_STRING=3, EXP_PLUS=100, EXP_MINUS=101, EXP_TIMES=102, EXP_DIV=103, EXP_EQ=104, EXP_NEQ=105, EXP_LTE=106, EXP_GTE=107, EXP_LT=108, EXP_GT=109, EXP_AND=110, EXP_OR=111, EXP_UNMINUS=150, EXP_NEG=151, EXP_INDEX=200, EXP_CALL=201 } type; union { union { struct { struct expr *left; struct expr *right; }; struct { char *id; struct expr_list { struct expr *expression; struct expr_list *next; } *args; }; struct { struct expr *expression; struct expr *index; }; }; union { char *string; int integer; char character; }; }; } *elements; }; } *declarator; struct decltor_list *next; } *declarators; } *signature; struct decl_list *declarations; struct stmt_list { struct stmt { enum stmt_type { STM_IF=0, STM_WHILE=1, STM_FOR=2, STM_EXP=100, STM_RETURN=101, STM_ASSIGN=102, STM_COMPOUND=200 } type; union { struct { char *name; struct expr *index; struct expr *expression; }; struct { struct stmt *init; struct expr *condition; struct stmt *update; struct stmt *body; struct stmt *else_body; }; struct stmt_list *list; }; } *statement; struct stmt_list *next; } *statements; } *function; struct decl *declaration; }; struct node *next; } *

user_defined_types: struct node { enum node_type type; union { struct fun_def *function; struct decl *declaration; }; struct node *next; }

user_defined_types: struct fun_def { struct decl *signature; struct decl_list *declarations; struct stmt_list *statements; }

user_defined_types: struct decl { enum value_type type; int is_extern; struct decltor_list *declarators; }

user_defined_types: struct stmt_list { struct stmt *statement; struct stmt_list *next; }

user_defined_types: struct decltor_list { struct decltor *declarator; struct decltor_list *next; }

user_defined_types: enum ir_data { DATA_RAW=0, DATA_STRING=1 }

user_defined_types: struct decltor { enum decltor_type type; char *name; union { struct decl_list *params; struct expr *elements; }; }

user_defined_types: enum addr_type { ADDR_EMPTY=0, ADDR_SYMBOL=1, ADDR_SYMBOL_NAME=2, ADDR_IMM_INT=3, ADDR_IMM_CHAR=4, ADDR_IMM_STRING=5 }

user_defined_types: enum ir_binop { IR_PLUS=0, IR_MINUS=1, IR_TIMES=2, IR_DIV=3, IR_AND=4, IR_OR=5 }

user_defined_types: struct symbol_info { enum symbol_type symbol_type; char *name; struct scope_info *scope; union { struct { struct type var_type; struct codegen_info codegen; }; struct { struct type ret_type; struct scope_info *params; }; char *literal; }; struct symbol_info *next; }

user_defined_types: struct scope_info { struct symbol_info *symbols; struct scope_info *parent; struct scope_info *next; struct scope_info *children; }

user_defined_types: enum storage_type { ST_UNKNOWN=0, ST_REG=1, ST_LOCAL=2, ST_GLOBAL=3 }


decompiled_code:
int __fastcall next_label(char *a1)
{
__int64 v1; // rdx

v1 = (unsigned int)label_counter++;
return sprintf(a1, "__L%d__", v1);
}

canonical_decompiled_code:
int __fastcall func0(char *a1)
{
__int64 v1; // rdx

v1 = (unsigned int)label_counter++;
return sprintf(a1, "__L%d__", v1);
}

original_code:
void next_label(char* buffer)
{
    sprintf(buffer, "__L%d__", label_counter++);
}

canonical_original_code:
void next_label(char *buffer)
{
    sprintf(buffer, "__L%d__", label_counter++);
}


decompiled_code:
_QWORD *MIPS_empty_list()
{
_QWORD *result; // rax

result = malloc(0x40uLL);
result[7] = 0LL;
return result;
}

canonical_decompiled_code:
_QWORD *func0()
{
_QWORD *result; // rax

result = malloc(0x40uLL);
result[7] = 0LL;
return result;
}

original_code:
MIPS_list* MIPS_empty_list(void)
{
    MIPS_list* node = malloc(sizeof(MIPS_list));
    node->next = ((void *)0);
    return node;
}

canonical_original_code:
struct MIPS_list *MIPS_empty_list()
{
    struct MIPS_list *node = malloc(sizeof(MIPS_list));
    node->next = ((void *)0);
    return node;
}

variable_types: struct MIPS_list { struct MIPS_instruction { enum MIPS_opcode { MIPS_add=0, MIPS_sub=1, MIPS_addi=2, MIPS_mult=3, MIPS_div=4, MIPS_lw=5, MIPS_lb=6, MIPS_sw=7, MIPS_sb=8, MIPS_mfhi=9, MIPS_mflo=10, MIPS_and=11, MIPS_andi=12, MIPS_or=13, MIPS_ori=14, MIPS_slt=15, MIPS_slti=16, MIPS_bgt=17, MIPS_bge=18, MIPS_blt=19, MIPS_ble=20, MIPS_sll=21, MIPS_srl=22, MIPS_beq=23, MIPS_bne=24, MIPS_jal=25, MIPS_jr=26, MIPS_b=27, MIPS_la=28, MIPS_li=29 } opcode; struct MIPS_operand { enum MIPS_operand_type { MIPS_OPERAND_NONE=0, MIPS_REG=1, MIPS_IMM_32=2, MIPS_IMM_8=3, MIPS_OFFSET=4, MIPS_SYMBOL=5 } type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; } x; } instr; struct MIPS_list *next; } *

user_defined_types: struct MIPS_list { struct MIPS_instruction instr; struct MIPS_list *next; }

user_defined_types: struct MIPS_instruction { enum MIPS_opcode opcode; struct MIPS_operand x; }

user_defined_types: struct MIPS_operand { enum MIPS_operand_type type; union { int reg; int imm32; char imm8; int offset; char *symbol; }; }