decompiled_code:
void __fastcall x86_trace_cache_flush_trace(__int64 a1)
{
int *v1; // r8
__int64 v2; // r9
unsigned int v4; // edi
int v5; // er10
size_t v6; // r11
int v7; // edx
int *v8; // rsi
int *v9; // rax
int v10; // ecx
int *v11; // rbp
int v12; // eax
int v13; // ecx
int v14; // ecx
int v15; // eax
int v16; // edx
int v17; // ecx

v1 = *(int **)(a1 + 8);
v2 = v1[2];
if ( (_DWORD)v2 )
{
v4 = v1[1];
if ( !v4 )
_assert_fail("trace->tag", "trace-cache.c", 0xAAu, "x86_trace_cache_flush_trace");
if ( v1[8] )
{
v13 = v1[6];
if ( !v13 )
_assert_fail("trace->branch_count", "trace-cache.c", 0xB1u, "x86_trace_cache_flush_trace");
v14 = v13 - 1;
v15 = __ROL4__(-2, v14);
v1[6] = v14;
v1[4] &= v15;
v1[5] &= v15;
}
v5 = x86_trace_cache_assoc;
if ( x86_trace_cache_assoc <= 0 )
goto LABEL_20;
v6 = 4LL * x86_trace_cache_trace_size + 36;
v7 = 0;
v8 = (int *)(*(_QWORD *)a1 + v6 * (int)(x86_trace_cache_assoc * (v4 % x86_trace_cache_num_sets)));
v9 = v8;
do
{
v10 = v9[1];
v11 = v9;
if ( v4 == v10 )
{
if ( v9[4] == v1[4] && v9[5] == v1[5] )
goto LABEL_11;
}
else if ( !v10 )
{
goto LABEL_11;
}
++v7;
v9 = (int *)((char *)v9 + v6);
}
while ( v7 != x86_trace_cache_assoc );
v16 = 0;
v11 = 0LL;
v17 = x86_trace_cache_assoc - 1;
do
{
while ( *v8 - 1 >= 0 )
{
++v16;
--*v8;
v8 = (int *)((char *)v8 + v6);
if ( v16 == v5 )
goto LABEL_19;
}
++v16;
*v8 = v17;
v11 = v8;
v8 = (int *)((char *)v8 + v6);
}
while ( v16 != v5 );
LABEL_19:
if ( !v11 )
LABEL_20:
_assert_fail("found", "trace-cache.c", 0xD9u, "x86_trace_cache_flush_trace");
LABEL_11:
v12 = *v11;
*(_QWORD *)(a1 + 72) += v2;
++*(_QWORD *)(a1 + 80);
*v1 = v12;
memcpy(v11, v1, v6);
memset(*(void **)(a1 + 8), 0, 4LL * x86_trace_cache_trace_size + 36);
}
}

canonical_decompiled_code:
void __fastcall func0(__int64 a1)
{
int *v1; // r8
__int64 v2; // r9
unsigned int v4; // edi
int v5; // er10
size_t v6; // r11
int v7; // edx
int *v8; // rsi
int *v9; // rax
int v10; // ecx
int *v11; // rbp
int v12; // eax
int v13; // ecx
int v14; // ecx
int v15; // eax
int v16; // edx
int v17; // ecx

v1 = *(int **)(a1 + 8);
v2 = v1[2];
if ( (_DWORD)v2 )
{
v4 = v1[1];
if ( !v4 )
_assert_fail("trace->tag", "trace-cache.c", 0xAAu, "x86_trace_cache_flush_trace");
if ( v1[8] )
{
v13 = v1[6];
if ( !v13 )
_assert_fail("trace->branch_count", "trace-cache.c", 0xB1u, "x86_trace_cache_flush_trace");
v14 = v13 - 1;
v15 = __ROL4__(-2, v14);
v1[6] = v14;
v1[4] &= v15;
v1[5] &= v15;
}
v5 = x86_trace_cache_assoc;
if ( x86_trace_cache_assoc <= 0 )
goto LABEL_20;
v6 = 4LL * x86_trace_cache_trace_size + 36;
v7 = 0;
v8 = (int *)(*(_QWORD *)a1 + v6 * (int)(x86_trace_cache_assoc * (v4 % x86_trace_cache_num_sets)));
v9 = v8;
do
{
v10 = v9[1];
v11 = v9;
if ( v4 == v10 )
{
if ( v9[4] == v1[4] && v9[5] == v1[5] )
goto LABEL_11;
}
else if ( !v10 )
{
goto LABEL_11;
}
++v7;
v9 = (int *)((char *)v9 + v6);
}
while ( v7 != x86_trace_cache_assoc );
v16 = 0;
v11 = 0LL;
v17 = x86_trace_cache_assoc - 1;
do
{
while ( *v8 - 1 >= 0 )
{
++v16;
--*v8;
v8 = (int *)((char *)v8 + v6);
if ( v16 == v5 )
goto LABEL_19;
}
++v16;
*v8 = v17;
v11 = v8;
v8 = (int *)((char *)v8 + v6);
}
while ( v16 != v5 );
LABEL_19:
if ( !v11 )
LABEL_20:
_assert_fail("found", "trace-cache.c", 0xD9u, "x86_trace_cache_flush_trace");
LABEL_11:
v12 = *v11;
*(_QWORD *)(a1 + 72) += v2;
++*(_QWORD *)(a1 + 80);
*v1 = v12;
memcpy(v11, v1, v6);
memset(*(void **)(a1 + 8), 0, 4LL * x86_trace_cache_trace_size + 36);
}
}

original_code:
static void x86_trace_cache_flush_trace(struct x86_trace_cache_t *trace_cache)
{
 struct x86_trace_cache_entry_t *entry, *found = ((void *)0);
 struct x86_trace_cache_entry_t *trace = trace_cache->temp;
 int set;
 int way;
 if (!trace->uop_count)
  return;
 ((void) sizeof ((trace->tag) ? 1 : 0), __extension__ ({ if (trace->tag) ; else __assert_fail ("trace->tag", "trace-cache.c", 170, __extension__ __PRETTY_FUNCTION__); }));
 if (trace->target)
 {
  ((void) sizeof ((trace->branch_count) ? 1 : 0), __extension__ ({ if (trace->branch_count) ; else __assert_fail ("trace->branch_count", "trace-cache.c", 177, __extension__ __PRETTY_FUNCTION__); }));
  trace->branch_count--;
  trace->branch_mask &= ~(1 << trace->branch_count);
  trace->branch_flags &= ~(1 << trace->branch_count);
 }
 set = trace->tag % x86_trace_cache_num_sets;
 for (way = 0; way < x86_trace_cache_assoc; way++)
 {
  entry = ((struct x86_trace_cache_entry_t *) (((unsigned char *) trace_cache->entry) + (sizeof(struct x86_trace_cache_entry_t) + sizeof(uint32_t) * x86_trace_cache_trace_size) * ((set) * x86_trace_cache_assoc + (way))));
  if (entry->tag == trace->tag && entry->branch_mask == trace->branch_mask
   && entry->branch_flags == trace->branch_flags)
  {
   found = entry;
   break;
  }
  if (!entry->tag) {
   found = entry;
   break;
  }
 }
 if (!found)
 {
  for (way = 0; way < x86_trace_cache_assoc; way++)
  {
   entry = ((struct x86_trace_cache_entry_t *) (((unsigned char *) trace_cache->entry) + (sizeof(struct x86_trace_cache_entry_t) + sizeof(uint32_t) * x86_trace_cache_trace_size) * ((set) * x86_trace_cache_assoc + (way))));
   entry->counter--;
   if (entry->counter < 0) {
    entry->counter = x86_trace_cache_assoc - 1;
    found = entry;
   }
  }
 }
 ((void) sizeof ((found) ? 1 : 0), __extension__ ({ if (found) ; else __assert_fail ("found", "trace-cache.c", 217, __extension__ __PRETTY_FUNCTION__); }));
 trace_cache->trace_length_acc += trace->uop_count;
 trace_cache->trace_length_count++;
 trace->counter = found->counter;
 memcpy(found, trace, (sizeof(struct x86_trace_cache_entry_t) + sizeof(uint32_t) * x86_trace_cache_trace_size));
 memset(trace_cache->temp, 0, (sizeof(struct x86_trace_cache_entry_t) + sizeof(uint32_t) * x86_trace_cache_trace_size));
}

canonical_original_code:
static void x86_trace_cache_flush_trace(struct x86_trace_cache_t *trace_cache)
{
 struct x86_trace_cache_entry_t *entry; struct x86_trace_cache_entry_t *found = ((void *)0);
 struct x86_trace_cache_entry_t *trace = trace_cache->temp;
 int set;
 int way;
 if (!trace->uop_count)
  return;
 ((void) sizeof ((trace->tag) ? 1 : 0), __extension__ ({ if (trace->tag) ; else __assert_fail ("trace->tag", "trace-cache.c", 170, __extension__ __PRETTY_FUNCTION__); }));
 if (trace->target)
 {
  ((void) sizeof ((trace->branch_count) ? 1 : 0), __extension__ ({ if (trace->branch_count) ; else __assert_fail ("trace->branch_count", "trace-cache.c", 177, __extension__ __PRETTY_FUNCTION__); }));
  trace->branch_count--;
  trace->branch_mask &= ~(1 << trace->branch_count);
  trace->branch_flags &= ~(1 << trace->branch_count);
 }
 set = trace->tag % x86_trace_cache_num_sets;
 for (way = 0; way < x86_trace_cache_assoc; way++)
 {
  entry = ((struct x86_trace_cache_entry_t *) (((unsigned char *) trace_cache->entry) + (sizeof(struct x86_trace_cache_entry_t) + sizeof(unsigned int) * x86_trace_cache_trace_size) * ((set) * x86_trace_cache_assoc + (way))));
  if (entry->tag == trace->tag && entry->branch_mask == trace->branch_mask
   && entry->branch_flags == trace->branch_flags)
  {
   found = entry;
   break;
  }
  if (!entry->tag) {
   found = entry;
   break;
  }
 }
 if (!found)
 {
  for (way = 0; way < x86_trace_cache_assoc; way++)
  {
   entry = ((struct x86_trace_cache_entry_t *) (((unsigned char *) trace_cache->entry) + (sizeof(struct x86_trace_cache_entry_t) + sizeof(unsigned int) * x86_trace_cache_trace_size) * ((set) * x86_trace_cache_assoc + (way))));
   entry->counter--;
   if (entry->counter < 0) {
    entry->counter = x86_trace_cache_assoc - 1;
    found = entry;
   }
  }
 }
 ((void) sizeof ((found) ? 1 : 0), __extension__ ({ if (found) ; else __assert_fail ("found", "trace-cache.c", 217, __extension__ __PRETTY_FUNCTION__); }));
 trace_cache->trace_length_acc += trace->uop_count;
 trace_cache->trace_length_count++;
 trace->counter = found->counter;
 memcpy(found, trace, (sizeof(struct x86_trace_cache_entry_t) + sizeof(unsigned int) * x86_trace_cache_trace_size));
 memset(trace_cache->temp, 0, (sizeof(struct x86_trace_cache_entry_t) + sizeof(unsigned int) * x86_trace_cache_trace_size));
}

variable_types: struct x86_trace_cache_t { struct x86_trace_cache_entry_t { int counter; unsigned int tag; int uop_count; int branch_mask; unsigned int fall_through; unsigned int target; unsigned int mop_array[]; } *entry; struct x86_trace_cache_entry_t *temp; char name[20]; long long accesses; long long hits; long long committed; long long squashed; long long trace_length_acc; long long trace_length_count; } *

variable_types: set int

variable_types: way int

user_defined_types: struct x86_trace_cache_t { struct x86_trace_cache_entry_t *entry; struct x86_trace_cache_entry_t *temp; char name[20]; long long accesses; long long hits; long long committed; long long squashed; long long trace_length_acc; long long trace_length_count; }


decompiled_code:
__int64 *x86_trace_cache_create()
{
__int64 *v0; // r12
__int64 v1; // rax
__int64 v2; // rax
int v3; // er9
int v4; // ecx
int v5; // er8
int v6; // edi
__int64 v7; // rsi
int v8; // eax
_DWORD *v9; // rdx

v0 = (__int64 *)mhandle_calloc(1LL, 88LL, "trace-cache.c:97");
if ( !v0 )
fatal("%s: out of memory", "x86_trace_cache_create");
v1 = mhandle_calloc(
x86_trace_cache_assoc * x86_trace_cache_num_sets,
4LL * x86_trace_cache_trace_size + 36,
"trace-cache.c:102");
*v0 = v1;
if ( !v1 )
fatal("%s: out of memory", "x86_trace_cache_create");
v2 = mhandle_calloc(1LL, 4LL * x86_trace_cache_trace_size + 36, "trace-cache.c:107");
v0[1] = v2;
if ( !v2 )
fatal("%s: out of memory", "x86_trace_cache_create");
v3 = x86_trace_cache_num_sets;
if ( x86_trace_cache_num_sets > 0 )
{
v4 = x86_trace_cache_assoc;
v5 = 0;
v6 = 0;
v7 = 4LL * x86_trace_cache_trace_size + 36;
do
{
if ( v4 > 0 )
{
v8 = 0;
v9 = (_DWORD *)(*v0 + v7 * v5);
do
{
*v9 = v8++;
v9 = (_DWORD *)((char *)v9 + v7);
}
while ( v4 != v8 );
}
++v6;
v5 += v4;
}
while ( v6 != v3 );
}
return v0;
}

canonical_decompiled_code:
__int64 *func1()
{
__int64 *v0; // r12
__int64 v1; // rax
__int64 v2; // rax
int v3; // er9
int v4; // ecx
int v5; // er8
int v6; // edi
__int64 v7; // rsi
int v8; // eax
_DWORD *v9; // rdx

v0 = (__int64 *)mhandle_calloc(1LL, 88LL, "trace-cache.c:97");
if ( !v0 )
fatal("%s: out of memory", "x86_trace_cache_create");
v1 = mhandle_calloc(
x86_trace_cache_assoc * x86_trace_cache_num_sets,
4LL * x86_trace_cache_trace_size + 36,
"trace-cache.c:102");
*v0 = v1;
if ( !v1 )
fatal("%s: out of memory", "x86_trace_cache_create");
v2 = mhandle_calloc(1LL, 4LL * x86_trace_cache_trace_size + 36, "trace-cache.c:107");
v0[1] = v2;
if ( !v2 )
fatal("%s: out of memory", "x86_trace_cache_create");
v3 = x86_trace_cache_num_sets;
if ( x86_trace_cache_num_sets > 0 )
{
v4 = x86_trace_cache_assoc;
v5 = 0;
v6 = 0;
v7 = 4LL * x86_trace_cache_trace_size + 36;
do
{
if ( v4 > 0 )
{
v8 = 0;
v9 = (_DWORD *)(*v0 + v7 * v5);
do
{
*v9 = v8++;
v9 = (_DWORD *)((char *)v9 + v7);
}
while ( v4 != v8 );
}
++v6;
v5 += v4;
}
while ( v6 != v3 );
}
return v0;
}

original_code:
struct x86_trace_cache_t *x86_trace_cache_create()
{
 struct x86_trace_cache_t *trace_cache;
 struct x86_trace_cache_entry_t *entry;
 int set;
 int way;
 trace_cache = (mhandle_calloc(1, sizeof(struct x86_trace_cache_t), "trace-cache.c" ":" "97"));
 if (!trace_cache)
  fatal("%s: out of memory", __FUNCTION__);
 trace_cache->entry = (mhandle_calloc(x86_trace_cache_num_sets * x86_trace_cache_assoc, (sizeof(struct x86_trace_cache_entry_t) + sizeof(uint32_t) * x86_trace_cache_trace_size), "trace-cache.c" ":" "102"));
 if (!trace_cache->entry)
  fatal("%s: out of memory", __FUNCTION__);
 trace_cache->temp = (mhandle_calloc(1, (sizeof(struct x86_trace_cache_entry_t) + sizeof(uint32_t) * x86_trace_cache_trace_size), "trace-cache.c" ":" "107"));
 if (!trace_cache->temp)
  fatal("%s: out of memory", __FUNCTION__);
 for (set = 0; set < x86_trace_cache_num_sets; set++)
 {
  for (way = 0; way < x86_trace_cache_assoc; way++)
  {
   entry = ((struct x86_trace_cache_entry_t *) (((unsigned char *) trace_cache->entry) + (sizeof(struct x86_trace_cache_entry_t) + sizeof(uint32_t) * x86_trace_cache_trace_size) * ((set) * x86_trace_cache_assoc + (way))));
   entry->counter = way;
  }
 }
 return trace_cache;
}

canonical_original_code:
struct x86_trace_cache_t *x86_trace_cache_create()
{
 struct x86_trace_cache_t *trace_cache;
 struct x86_trace_cache_entry_t *entry;
 int set;
 int way;
 trace_cache = (mhandle_calloc(1, sizeof(struct x86_trace_cache_t), "trace-cache.c" ":" "97"));
 if (!trace_cache)
  fatal("%s: out of memory", __FUNCTION__);
 trace_cache->entry = (mhandle_calloc(x86_trace_cache_num_sets * x86_trace_cache_assoc, (sizeof(struct x86_trace_cache_entry_t) + sizeof(unsigned int) * x86_trace_cache_trace_size), "trace-cache.c" ":" "102"));
 if (!trace_cache->entry)
  fatal("%s: out of memory", __FUNCTION__);
 trace_cache->temp = (mhandle_calloc(1, (sizeof(struct x86_trace_cache_entry_t) + sizeof(unsigned int) * x86_trace_cache_trace_size), "trace-cache.c" ":" "107"));
 if (!trace_cache->temp)
  fatal("%s: out of memory", __FUNCTION__);
 for (set = 0; set < x86_trace_cache_num_sets; set++)
 {
  for (way = 0; way < x86_trace_cache_assoc; way++)
  {
   entry = ((struct x86_trace_cache_entry_t *) (((unsigned char *) trace_cache->entry) + (sizeof(struct x86_trace_cache_entry_t) + sizeof(unsigned int) * x86_trace_cache_trace_size) * ((set) * x86_trace_cache_assoc + (way))));
   entry->counter = way;
  }
 }
 return trace_cache;
}

return_type: struct x86_trace_cache_t { struct x86_trace_cache_entry_t { int counter; unsigned int tag; int uop_count; int branch_mask; unsigned int fall_through; unsigned int target; unsigned int mop_array[]; } *entry; struct x86_trace_cache_entry_t *temp; char name[20]; long long accesses; long long hits; long long committed; long long squashed; long long trace_length_acc; long long trace_length_count; } *


decompiled_code:
void x86_trace_cache_init()
{
int v0; // eax
__int64 v1; // r12
int i; // er13
__int64 v3; // rbp
int v4; // ebx
__int64 v5; // r14
__int64 *v6; // rax
__int64 v7; // rcx
__int64 v8; // rdi

if ( !x86_trace_cache_present )
return;
fatal(
"trace cache temporarily not supported.\n"
"\tAs of SVN Rev. 330, a new mechanism has been implemented for x86 CISC\n"
"\tinstructions decoding. This is a more accurate mechanism that is not\n"
"\tcompatible with the old trace cache model. To request this update, please\n"
"\temail development@multi2sim.org, or use the Multi2Sim forum.\n");
if ( (x86_trace_cache_num_sets & (x86_trace_cache_num_sets - 1)) != 0 || !x86_trace_cache_num_sets )
fatal("trace cache sets must be power of 2 and > 0");
if ( (x86_trace_cache_assoc & (x86_trace_cache_assoc - 1)) != 0 || !x86_trace_cache_assoc )
fatal("trace cache associativity must be power of 2 and > 0");
if ( x86_trace_cache_trace_size )
{
v0 = x86_trace_cache_branch_max;
if ( x86_trace_cache_branch_max )
{
if ( x86_trace_cache_branch_max <= x86_trace_cache_trace_size )
goto LABEL_9;
LABEL_16:
fatal("max branches in trace cache cannot be greater than trace size");
if ( x86_trace_cache_branch_max <= 31 )
goto LABEL_10;
goto LABEL_17;
}
}
fatal("trace cache: max number of branches and micro-instructions must be > 0");
v0 = x86_trace_cache_branch_max;
if ( x86_trace_cache_branch_max > x86_trace_cache_trace_size )
goto LABEL_16;
LABEL_9:
if ( v0 <= 31 )
goto LABEL_10;
LABEL_17:
fatal("max branches must be less than 32");
LABEL_10:
v1 = 0LL;
for ( i = 0; x86_cpu_num_cores > i; v1 += 1824LL )
{
v3 = 0LL;
v4 = 0;
while ( x86_cpu_num_threads > v4 )
{
v5 = *(_QWORD *)(*x86_cpu + v1);
v6 = x86_trace_cache_create();
v7 = (unsigned int)v4++;
*(_QWORD *)(v3 + v5 + 104) = v6;
v8 = *(_QWORD *)(*(_QWORD *)(*x86_cpu + v1) + v3 + 104);
v3 += 1904LL;
sprintf((char *)(v8 + 16), "c%dt%d.trace_cache", (unsigned int)i, v7);
}
++i;
}
}

canonical_decompiled_code:
void func2()
{
int v0; // eax
__int64 v1; // r12
int i; // er13
__int64 v3; // rbp
int v4; // ebx
__int64 v5; // r14
__int64 *v6; // rax
__int64 v7; // rcx
__int64 v8; // rdi

if ( !x86_trace_cache_present )
return;
fatal(
"trace cache temporarily not supported.\n"
"\tAs of SVN Rev. 330, a new mechanism has been implemented for x86 CISC\n"
"\tinstructions decoding. This is a more accurate mechanism that is not\n"
"\tcompatible with the old trace cache model. To request this update, please\n"
"\temail development@multi2sim.org, or use the Multi2Sim forum.\n");
if ( (x86_trace_cache_num_sets & (x86_trace_cache_num_sets - 1)) != 0 || !x86_trace_cache_num_sets )
fatal("trace cache sets must be power of 2 and > 0");
if ( (x86_trace_cache_assoc & (x86_trace_cache_assoc - 1)) != 0 || !x86_trace_cache_assoc )
fatal("trace cache associativity must be power of 2 and > 0");
if ( x86_trace_cache_trace_size )
{
v0 = x86_trace_cache_branch_max;
if ( x86_trace_cache_branch_max )
{
if ( x86_trace_cache_branch_max <= x86_trace_cache_trace_size )
goto LABEL_9;
LABEL_16:
fatal("max branches in trace cache cannot be greater than trace size");
if ( x86_trace_cache_branch_max <= 31 )
goto LABEL_10;
goto LABEL_17;
}
}
fatal("trace cache: max number of branches and micro-instructions must be > 0");
v0 = x86_trace_cache_branch_max;
if ( x86_trace_cache_branch_max > x86_trace_cache_trace_size )
goto LABEL_16;
LABEL_9:
if ( v0 <= 31 )
goto LABEL_10;
LABEL_17:
fatal("max branches must be less than 32");
LABEL_10:
v1 = 0LL;
for ( i = 0; x86_cpu_num_cores > i; v1 += 1824LL )
{
v3 = 0LL;
v4 = 0;
while ( x86_cpu_num_threads > v4 )
{
v5 = *(_QWORD *)(*x86_cpu + v1);
v6 = func1();
v7 = (unsigned int)v4++;
*(_QWORD *)(v3 + v5 + 104) = v6;
v8 = *(_QWORD *)(*(_QWORD *)(*x86_cpu + v1) + v3 + 104);
v3 += 1904LL;
sprintf((char *)(v8 + 16), "c%dt%d.trace_cache", (unsigned int)i, v7);
}
++i;
}
}

original_code:
void x86_trace_cache_init()
{
 int core;
 int thread;
 if (!x86_trace_cache_present)
  return;
 fatal("trace cache temporarily not supported.\n"
  "\tAs of SVN Rev. 330, a new mechanism has been implemented for x86 CISC\n"
  "\tinstructions decoding. This is a more accurate mechanism that is not\n"
  "\tcompatible with the old trace cache model. To request this update, please\n"
  "\temail development@multi2sim.org, or use the Multi2Sim forum.\n");
 if ((x86_trace_cache_num_sets & (x86_trace_cache_num_sets - 1)) || !x86_trace_cache_num_sets)
  fatal("trace cache sets must be power of 2 and > 0");
 if ((x86_trace_cache_assoc & (x86_trace_cache_assoc - 1)) || !x86_trace_cache_assoc)
  fatal("trace cache associativity must be power of 2 and > 0");
 if (!x86_trace_cache_trace_size || !x86_trace_cache_branch_max)
  fatal("trace cache: max number of branches and micro-instructions must be > 0");
 if (x86_trace_cache_branch_max > x86_trace_cache_trace_size)
  fatal("max branches in trace cache cannot be greater than trace size");
 if (x86_trace_cache_branch_max > 31)
  fatal("max branches must be less than 32");
 for (core = 0; core < x86_cpu_num_cores; core++) for (thread = 0; thread < x86_cpu_num_threads; thread++)
 {
  (x86_cpu->core[core].thread[thread]).trace_cache = x86_trace_cache_create();
  sprintf((x86_cpu->core[core].thread[thread]).trace_cache->name, "c%dt%d.trace_cache", core, thread);
 }
}

variable_types: core int

variable_types: thread int

return_type: void


decompiled_code:
__int64 __fastcall x86_trace_cache_free(_QWORD *a1)
{
mhandle_free(*a1, "trace-cache.c:128");
mhandle_free(a1[1], "trace-cache.c:129");
return mhandle_free(a1, "trace-cache.c:130");
}

canonical_decompiled_code:
__int64 __fastcall func3(_QWORD *a1)
{
mhandle_free(*a1, "trace-cache.c:128");
mhandle_free(a1[1], "trace-cache.c:129");
return mhandle_free(a1, "trace-cache.c:130");
}

original_code:
void x86_trace_cache_free(struct x86_trace_cache_t *trace_cache)
{
 (mhandle_free(trace_cache->entry, "trace-cache.c" ":" "128"));
 (mhandle_free(trace_cache->temp, "trace-cache.c" ":" "129"));
 (mhandle_free(trace_cache, "trace-cache.c" ":" "130"));
}

user_defined_types: struct x86_trace_cache_entry_t { int counter; unsigned int tag; int uop_count; int branch_mask; unsigned int fall_through; unsigned int target; unsigned int mop_array[]; }


decompiled_code:
__int64 x86_trace_cache_done()
{
int v0; // er12
__int64 i; // rbp
__int64 result; // rax
__int64 j; // rbx
__int64 v4; // rax

if ( x86_trace_cache_present )
{
v0 = 0;
for ( i = 0LL; x86_cpu_num_cores > v0; i += 1824LL )
{
result = x86_cpu_num_threads;
for ( j = 0LL;
x86_cpu_num_threads > (int)j;
result = x86_trace_cache_free(*(_QWORD **)(*(_QWORD *)(*x86_cpu + i) + v4 + 104)) )
{
v4 = 1904 * j++;
}
++v0;
}
}
return result;
}

canonical_decompiled_code:
__int64 func4()
{
int v0; // er12
__int64 i; // rbp
__int64 result; // rax
__int64 j; // rbx
__int64 v4; // rax

if ( x86_trace_cache_present )
{
v0 = 0;
for ( i = 0LL; x86_cpu_num_cores > v0; i += 1824LL )
{
result = x86_cpu_num_threads;
for ( j = 0LL;
x86_cpu_num_threads > (int)j;
result = func3(*(_QWORD **)(*(_QWORD *)(*x86_cpu + i) + v4 + 104)) )
{
v4 = 1904 * j++;
}
++v0;
}
}
return result;
}

original_code:
void x86_trace_cache_done()
{
 int core;
 int thread;
 if (!x86_trace_cache_present)
  return;
 for (core = 0; core < x86_cpu_num_cores; core++) for (thread = 0; thread < x86_cpu_num_threads; thread++)
  x86_trace_cache_free((x86_cpu->core[core].thread[thread]).trace_cache);
}


decompiled_code:
__int64 __fastcall x86_trace_cache_lookup(_QWORD *a1, unsigned int a2, int a3, _DWORD *a4, _QWORD *a5, _DWORD *a6)
{
__int64 v9; // rbx
int v10; // ecx
_DWORD *v11; // rdx
int v12; // eax
__int64 result; // rax

if ( x86_trace_cache_assoc <= 0 )
{
++a1[5];
result = 0LL;
}
else
{
v9 = 4LL * x86_trace_cache_trace_size + 36;
v10 = 0;
v11 = (_DWORD *)(*a1 + v9 * (int)(x86_trace_cache_assoc * (a2 % x86_trace_cache_num_sets)));
while ( v11[1] != a2 || (a3 & v11[4]) != v11[5] )
{
++v10;
v11 = (_DWORD *)((char *)v11 + v9);
if ( x86_trace_cache_assoc == v10 )
{
++a1[5];
return 0LL;
}
}
v12 = v11[8];
++a1[5];
++a1[6];
if ( !v12 || !_bittest(&a3, v11[6]) )
v12 = v11[7];
if ( a4 )
*a4 = v11[3];
if ( a5 )
*a5 = v11 + 9;
if ( a6 )
*a6 = v12;
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(_QWORD *a1, unsigned int a2, int a3, _DWORD *a4, _QWORD *a5, _DWORD *a6)
{
__int64 v9; // rbx
int v10; // ecx
_DWORD *v11; // rdx
int v12; // eax
__int64 result; // rax

if ( x86_trace_cache_assoc <= 0 )
{
++a1[5];
result = 0LL;
}
else
{
v9 = 4LL * x86_trace_cache_trace_size + 36;
v10 = 0;
v11 = (_DWORD *)(*a1 + v9 * (int)(x86_trace_cache_assoc * (a2 % x86_trace_cache_num_sets)));
while ( v11[1] != a2 || (a3 & v11[4]) != v11[5] )
{
++v10;
v11 = (_DWORD *)((char *)v11 + v9);
if ( x86_trace_cache_assoc == v10 )
{
++a1[5];
return 0LL;
}
}
v12 = v11[8];
++a1[5];
++a1[6];
if ( !v12 || !_bittest(&a3, v11[6]) )
v12 = v11[7];
if ( a4 )
*a4 = v11[3];
if ( a5 )
*a5 = v11 + 9;
if ( a6 )
*a6 = v12;
result = 1LL;
}
return result;
}

original_code:
int x86_trace_cache_lookup(struct x86_trace_cache_t *trace_cache, uint32_t eip, int pred,
 int *ptr_mop_count, uint32_t **ptr_mop_array, uint32_t *ptr_neip)
{
 struct x86_trace_cache_entry_t *entry = ((void *)0), *found = ((void *)0);
 int set, way;
 uint32_t neip;
 set = eip % x86_trace_cache_num_sets;
 for (way = 0; way < x86_trace_cache_assoc; way++)
 {
  entry = ((struct x86_trace_cache_entry_t *) (((unsigned char *) trace_cache->entry) + (sizeof(struct x86_trace_cache_entry_t) + sizeof(uint32_t) * x86_trace_cache_trace_size) * ((set) * x86_trace_cache_assoc + (way))));
  if (entry->tag == eip && ((pred & entry->branch_mask) == entry->branch_flags))
  {
   found = entry;
   break;
  }
 }
 trace_cache->accesses++;
 if (!found)
  return 0;
 trace_cache->hits++;
 neip = entry->target && (pred & (1 << entry->branch_count)) ?
  entry->target : entry->fall_through;
 if (ptr_mop_count) *(ptr_mop_count) = (entry->mop_count);
 if (ptr_mop_array) *(ptr_mop_array) = (entry->mop_array);
 if (ptr_neip) *(ptr_neip) = (neip);
 return 1;
}

canonical_original_code:
int x86_trace_cache_lookup(struct x86_trace_cache_t *trace_cache, unsigned int eip, int pred, int *ptr_mop_count, unsigned int **ptr_mop_array, unsigned int *ptr_neip)
{
 struct x86_trace_cache_entry_t *entry = ((void *)0); struct x86_trace_cache_entry_t *found = ((void *)0);
 int set; int way;
 unsigned int neip;
 set = eip % x86_trace_cache_num_sets;
 for (way = 0; way < x86_trace_cache_assoc; way++)
 {
  entry = ((struct x86_trace_cache_entry_t *) (((unsigned char *) trace_cache->entry) + (sizeof(struct x86_trace_cache_entry_t) + sizeof(unsigned int) * x86_trace_cache_trace_size) * ((set) * x86_trace_cache_assoc + (way))));
  if (entry->tag == eip && ((pred & entry->branch_mask) == entry->branch_flags))
  {
   found = entry;
   break;
  }
 }
 trace_cache->accesses++;
 if (!found)
  return 0;
 trace_cache->hits++;
 neip = entry->target && (pred & (1 << entry->branch_count)) ?
  entry->target : entry->fall_through;
 if (ptr_mop_count) *(ptr_mop_count) = (entry->mop_count);
 if (ptr_mop_array) *(ptr_mop_array) = (entry->mop_array);
 if (ptr_neip) *(ptr_neip) = (neip);
 return 1;
}

variable_types:
eip
unsigned int

variable_types: pred int

variable_types: struct x86_trace_cache_entry_t { int counter; unsigned int tag; int uop_count; int branch_mask; unsigned int fall_through; unsigned int target; unsigned int mop_array[]; } *

variable_types:
neip
unsigned int

return_type: int


decompiled_code:
__int64 __fastcall heap_grow(__int64 a1)
{
int v1; // ebp
__int64 v2; // rax
__int64 result; // rax

v1 = 2 * *(_DWORD *)a1;
v2 = mhandle_realloc(*(_QWORD *)(a1 + 32), 24LL * v1, "heap.c:69");
if ( !v2 )
return 0LL;
*(_QWORD *)(a1 + 32) = v2;
result = 1LL;
*(_DWORD *)a1 = v1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
int v1; // ebp
__int64 v2; // rax
__int64 result; // rax

v1 = 2 * *(_DWORD *)a1;
v2 = mhandle_realloc(*(_QWORD *)(a1 + 32), 24LL * v1, "heap.c:69");
if ( !v2 )
return 0LL;
*(_QWORD *)(a1 + 32) = v2;
result = 1LL;
*(_DWORD *)a1 = v1;
return result;
}

original_code:
static int heap_grow(struct heap_t *heap)
{
 struct heap_elem_t *nelem;
 int nsize = heap->size * 2;
 nelem = (mhandle_realloc(heap->elem, nsize * sizeof(struct heap_elem_t), "heap.c" ":" "69"));
 if (!nelem)
  return 0;
 heap->elem = nelem;
 heap->size = nsize;
 return 1;
}

variable_types: struct heap_t { int size; int error; long long time; enum heap_time_policy_enum { heap_time_policy_fifo=0, heap_time_policy_lifo=1 } time_policy; struct heap_elem_t { long long time; void *data; } *elem; } *

variable_types: nsize int

user_defined_types: struct heap_t { int size; int error; long long time; enum heap_time_policy_enum time_policy; struct heap_elem_t *elem; }


decompiled_code:
int *__fastcall heap_create(int a1)
{
int v1; // ebx
int *v2; // rax
int *v3; // r12
__int64 v4; // rax
int *v6; // rdi

v1 = a1;
v2 = (int *)mhandle_calloc(1LL, 40LL, "heap.c:111");
if ( a1 < 10 )
v1 = 10;
v3 = v2;
*v2 = v1;
v4 = mhandle_calloc(v1, 24LL, "heap.c:113");
*((_QWORD *)v3 + 4) = v4;
if ( !v4 )
{
v6 = v3;
v3 = 0LL;
mhandle_free(v6, "heap.c:115");
}
return v3;
}

canonical_decompiled_code:
int *__fastcall func3(int a1)
{
int v1; // ebx
int *v2; // rax
int *v3; // r12
__int64 v4; // rax
int *v6; // rdi

v1 = a1;
v2 = (int *)mhandle_calloc(1LL, 40LL, "heap.c:111");
if ( a1 < 10 )
v1 = 10;
v3 = v2;
*v2 = v1;
v4 = mhandle_calloc(v1, 24LL, "heap.c:113");
*((_QWORD *)v3 + 4) = v4;
if ( !v4 )
{
v6 = v3;
v3 = 0LL;
mhandle_free(v6, "heap.c:115");
}
return v3;
}

original_code:
struct heap_t *heap_create(int size)
{
 struct heap_t *heap;
 heap = (mhandle_calloc(1, sizeof(struct heap_t), "heap.c" ":" "111"));
 heap->size = size < 10 ? 10 : size;
 heap->elem = (mhandle_calloc(heap->size, sizeof(struct heap_elem_t), "heap.c" ":" "113"));
 if (!heap->elem) {
  (mhandle_free(heap, "heap.c" ":" "115"));
  return ((void *)0);
 }
 return heap;
}

variable_types: size int

return_type: struct heap_t { int size; int error; long long time; enum heap_time_policy_enum { heap_time_policy_fifo=0, heap_time_policy_lifo=1 } time_policy; struct heap_elem_t { long long time; void *data; } *elem; } *


decompiled_code:
__int64 __fastcall heap_free(__int64 a1)
{
mhandle_free(*(_QWORD *)(a1 + 32), "heap.c:125");
return mhandle_free(a1, "heap.c:126");
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
mhandle_free(*(_QWORD *)(a1 + 32), "heap.c:125");
return mhandle_free(a1, "heap.c:126");
}

original_code:
void heap_free(struct heap_t *heap)
{
 (mhandle_free(heap->elem, "heap.c" ":" "125"));
 (mhandle_free(heap, "heap.c" ":" "126"));
}

user_defined_types: enum heap_time_policy_enum { heap_time_policy_fifo=0, heap_time_policy_lifo=1 }

user_defined_types: struct heap_elem_t { long long time; void *data; }


decompiled_code:
__int64 __fastcall heap_error(__int64 a1)
{
return *(unsigned int *)(a1 + 12);
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
return *(unsigned int *)(a1 + 12);
}

original_code:
int heap_error(struct heap_t *heap)
{
 return heap->error;
}


decompiled_code:
const char *__fastcall heap_error_msg(__int64 a1)
{
int v1; // edx
const char *result; // rax

v1 = *(_DWORD *)(a1 + 12);
result = "out of memory";
if ( v1 != 1 )
{
result = (const char *)&unk_4B9;
if ( v1 == 2 )
result = "heap is empty";
}
return result;
}

canonical_decompiled_code:
const char *__fastcall func6(__int64 a1)
{
int v1; // edx
const char *result; // rax

v1 = *(_DWORD *)(a1 + 12);
result = "out of memory";
if ( v1 != 1 )
{
result = (const char *)&unk_4B9;
if ( v1 == 2 )
result = "heap is empty";
}
return result;
}

original_code:
char *heap_error_msg(struct heap_t *heap)
{
 switch (heap->error) {
 case 1: return "out of memory";
 case 2: return "heap is empty";
 }
 return "";
}

return_type: char *


decompiled_code:
__int64 __fastcall heap_count(__int64 a1)
{
return *(unsigned int *)(a1 + 4);
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
return *(unsigned int *)(a1 + 4);
}

original_code:
int heap_count(struct heap_t *heap)
{
 return heap->count;
}


original_code:
long long heap_peek(struct heap_t *heap, void **data)
{
 long long value;
 if (!heap->count) {
  heap->error = 2;
  if (data)
   *data = ((void *)0);
  return 0;
 }
 value = heap->elem[0].value;
 if (data)
  *data = heap->elem[0].data;
 heap->error = 0;
 return value;
}

variable_types:
data
void **

variable_types:
value
long long

return_type: long long


original_code:
long long heap_extract(struct heap_t *heap, void **data)
{
 long long value;
 value = heap_peek(heap, data);
 if (heap->error)
  return 0;
 heap->count--;
 heap->elem[0] = heap->elem[heap->count];
 heapify(heap, 0);
 return value;
}


decompiled_code:
void __fastcall heap_time_policy(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 24) = a2;
*(_DWORD *)(a1 + 12) = 0;
}

original_code:
void heap_time_policy(struct heap_t *heap, enum heap_time_policy_enum policy)
{
 heap->time_policy = policy;
 heap->error = 0;
}

variable_types: enum heap_time_policy_enum { heap_time_policy_fifo=0, heap_time_policy_lifo=1 }


original_code:
long long heap_first(struct heap_t *heap, void **data)
{
 if (!heap->count) {
  heap->error = 3;
  if (data)
   *data = ((void *)0);
  return 0;
 }
 heap->current = 0;
 heap->error = 0;
 if (data)
  *data = heap->elem[0].data;
 return heap->elem[0].value;
}


original_code:
long long heap_next(struct heap_t *heap, void **data)
{
 if (heap->current >= heap->count - 1) {
  heap->error = 3;
  if (data)
   *data = ((void *)0);
  return 0;
 }
 heap->current++;
 heap->error = 0;
 if (data)
  *data = heap->elem[heap->current].data;
 return heap->elem[heap->current].value;
}


decompiled_code:
__int64 __fastcall evg_opencl_event_free(__int64 a1)
{
evg_opencl_repo_remove_object(*(_QWORD *)(evg_emu + 8LL), a1);
return mhandle_free(a1, "opencl-event.c:53");
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
evg_opencl_repo_remove_object(*(_QWORD *)(evg_emu + 8LL), a1);
return mhandle_free(a1, "opencl-event.c:53");
}

original_code:
void evg_opencl_event_free(struct evg_opencl_event_t *event)
{
 evg_opencl_repo_remove_object(evg_emu->opencl_repo, event);
 (mhandle_free(event, "opencl-event.c" ":" "53"));
}

variable_types: struct evg_opencl_event_t { unsigned int id; int ref_count; enum evg_opencl_event_kind_t { EVG_OPENCL_EVENT_NONE=0, EVG_OPENCL_EVENT_NDRANGE_KERNEL=1, EVG_OPENCL_EVENT_TASK=2, EVG_OPENCL_EVENT_NATIVE_KERNEL=3, EVG_OPENCL_EVENT_READ_BUFFER=4, EVG_OPENCL_EVENT_WRITE_BUFFER=5, EVG_OPENCL_EVENT_MAP_BUFFER=6, EVG_OPENCL_EVENT_UNMAP_MEM_OBJECT=7, EVG_OPENCL_EVENT_READ_BUFFER_RECT=8, EVG_OPENCL_EVENT_WRITE_BUFFER_RECT=9, EVG_OPENCL_EVENT_READ_IMAGE=10, EVG_OPENCL_EVENT_WRITE_IMAGE=11, EVG_OPENCL_EVENT_MAP_IMAGE=12, EVG_OPENCL_EVENT_COPY_BUFFER=13, EVG_OPENCL_EVENT_COPY_IMAGE=14, EVG_OPENCL_EVENT_COPY_BUFFER_RECT=15, EVG_OPENCL_EVENT_COPY_BUFFER_TO_IMAGE=16, EVG_OPENCL_EVENT_COPY_IMAGE_TO_BUFFER=17, EVG_OPENCL_EVENT_MARKER=18, EVG_OPENCL_EVENT_COUNT=19 } kind; enum evg_opencl_event_status_t { EVG_OPENCL_EVENT_STATUS_NONE=0, EVG_OPENCL_EVENT_STATUS_QUEUED=1, EVG_OPENCL_EVENT_STATUS_SUBMITTED=2, EVG_OPENCL_EVENT_STATUS_RUNNING=3, EVG_OPENCL_EVENT_STATUS_COMPLETE=4 } status; long long time_queued; long long time_submit; long long time_start; long long time_end; } *

user_defined_types: struct evg_opencl_event_t { unsigned int id; int ref_count; enum evg_opencl_event_kind_t kind; enum evg_opencl_event_status_t status; long long time_queued; long long time_submit; long long time_start; long long time_end; }


decompiled_code:
__int64 __fastcall evg_opencl_event_get_profiling_info(__int64 a1, unsigned int a2, __int64 a3, unsigned int a4, unsigned int a5)
{
__int64 v6; // rcx

if ( a2 == 4738 )
{
v6 = a1 + 32;
goto LABEL_6;
}
if ( a2 > 0x1282 )
{
if ( a2 == 4739 )
{
v6 = a1 + 40;
goto LABEL_6;
}
LABEL_14:
fatal(
"%s: invalid or not implemented value for 'name' (0x%x)\n%s",
"evg_opencl_event_get_profiling_info",
a2,
evg_err_opencl_param_note);
_assert_fail("info", "opencl-event.c", 0x5Cu, "evg_opencl_event_get_profiling_info");
}
if ( a2 == 4736 )
{
v6 = a1 + 16;
goto LABEL_6;
}
if ( a2 != 4737 )
goto LABEL_14;
v6 = a1 + 24;
LABEL_6:
if ( !a4 || a5 <= 7 )
return 8LL;
mem_write(a3, a4, 8LL, v6);
return 8LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned int a2, __int64 a3, unsigned int a4, unsigned int a5)
{
__int64 v6; // rcx

if ( a2 == 4738 )
{
v6 = a1 + 32;
goto LABEL_6;
}
if ( a2 > 0x1282 )
{
if ( a2 == 4739 )
{
v6 = a1 + 40;
goto LABEL_6;
}
LABEL_14:
fatal(
"%s: invalid or not implemented value for 'name' (0x%x)\n%s",
"evg_opencl_event_get_profiling_info",
a2,
evg_err_opencl_param_note);
_assert_fail("info", "opencl-event.c", 0x5Cu, "evg_opencl_event_get_profiling_info");
}
if ( a2 == 4736 )
{
v6 = a1 + 16;
goto LABEL_6;
}
if ( a2 != 4737 )
goto LABEL_14;
v6 = a1 + 24;
LABEL_6:
if ( !a4 || a5 <= 7 )
return 8LL;
mem_write(a3, a4, 8LL, v6);
return 8LL;
}

original_code:
uint32_t evg_opencl_event_get_profiling_info(struct evg_opencl_event_t *event, uint32_t name,
 struct mem_t *mem, uint32_t addr, uint32_t size)
{
 uint32_t size_ret = 0;
 void *info = ((void *)0);
 switch (name)
 {
 case 0x1280:
  size_ret = 8;
  info = &event->time_queued;
  break;
 case 0x1281:
  size_ret = 8;
  info = &event->time_submit;
  break;
 case 0x1282:
  size_ret = 8;
  info = &event->time_start;
  break;
 case 0x1283:
  size_ret = 8;
  info = &event->time_end;
  break;
 default:
  fatal("%s: invalid or not implemented value for 'name' (0x%x)\n%s",
   __FUNCTION__, name, evg_err_opencl_param_note);
 }
 ((void) sizeof ((info) ? 1 : 0), __extension__ ({ if (info) ; else __assert_fail ("info", "opencl-event.c", 92, __extension__ __PRETTY_FUNCTION__); }));
 if (addr && size >= size_ret)
  mem_write(mem, addr, size_ret, info);
 return size_ret;
}

canonical_original_code:
unsigned int evg_opencl_event_get_profiling_info(struct evg_opencl_event_t *event, unsigned int name, struct mem_t *mem, unsigned int addr, unsigned int size)
{
 unsigned int size_ret = 0;
 void *info = ((void *)0);
 switch (name)
 {
 case 0x1280:
  size_ret = 8;
  info = &event->time_queued;
  break;
 case 0x1281:
  size_ret = 8;
  info = &event->time_submit;
  break;
 case 0x1282:
  size_ret = 8;
  info = &event->time_start;
  break;
 case 0x1283:
  size_ret = 8;
  info = &event->time_end;
  break;
 default:
  fatal("%s: invalid or not implemented value for 'name' (0x%x)\n%s",
   __FUNCTION__, name, evg_err_opencl_param_note);
 }
 ((void) sizeof ((info) ? 1 : 0), __extension__ ({ if (info) ; else __assert_fail ("info", "opencl-event.c", 92, __extension__ __PRETTY_FUNCTION__); }));
 if (addr && size >= size_ret)
  mem_write(mem, addr, size_ret, info);
 return size_ret;
}

variable_types:
name
unsigned int

variable_types: struct mem_t { int num_links; struct mem_page_t { unsigned int tag; enum mem_access_t { mem_access_none=0, mem_access_read=1, mem_access_write=2, mem_access_exec=4, mem_access_init=8, mem_access_modif=16 } perm; struct mem_page_t *next; unsigned char *data; } *pages[1024]; int safe; unsigned int heap_break; unsigned int last_address; } *

variable_types:
addr
unsigned int

variable_types:
size
unsigned int

variable_types:
info
void *

return_type: unsigned int

user_defined_types: struct mem_t { int num_links; struct mem_page_t *pages[1024]; int safe; unsigned int heap_break; unsigned int last_address; }

user_defined_types: enum evg_opencl_event_kind_t { EVG_OPENCL_EVENT_NONE=0, EVG_OPENCL_EVENT_NDRANGE_KERNEL=1, EVG_OPENCL_EVENT_TASK=2, EVG_OPENCL_EVENT_NATIVE_KERNEL=3, EVG_OPENCL_EVENT_READ_BUFFER=4, EVG_OPENCL_EVENT_WRITE_BUFFER=5, EVG_OPENCL_EVENT_MAP_BUFFER=6, EVG_OPENCL_EVENT_UNMAP_MEM_OBJECT=7, EVG_OPENCL_EVENT_READ_BUFFER_RECT=8, EVG_OPENCL_EVENT_WRITE_BUFFER_RECT=9, EVG_OPENCL_EVENT_READ_IMAGE=10, EVG_OPENCL_EVENT_WRITE_IMAGE=11, EVG_OPENCL_EVENT_MAP_IMAGE=12, EVG_OPENCL_EVENT_COPY_BUFFER=13, EVG_OPENCL_EVENT_COPY_IMAGE=14, EVG_OPENCL_EVENT_COPY_BUFFER_RECT=15, EVG_OPENCL_EVENT_COPY_BUFFER_TO_IMAGE=16, EVG_OPENCL_EVENT_COPY_IMAGE_TO_BUFFER=17, EVG_OPENCL_EVENT_MARKER=18, EVG_OPENCL_EVENT_COUNT=19 }

user_defined_types: enum evg_opencl_event_status_t { EVG_OPENCL_EVENT_STATUS_NONE=0, EVG_OPENCL_EVENT_STATUS_QUEUED=1, EVG_OPENCL_EVENT_STATUS_SUBMITTED=2, EVG_OPENCL_EVENT_STATUS_RUNNING=3, EVG_OPENCL_EVENT_STATUS_COMPLETE=4 }

user_defined_types: struct mem_page_t { unsigned int tag; enum mem_access_t perm; struct mem_page_t *next; unsigned char *data; }


decompiled_code:
__int64 evg_opencl_event_timer()
{
return 1000 * esim_real_time();
}

canonical_decompiled_code:
__int64 func2()
{
return 1000 * esim_real_time();
}

original_code:
long long evg_opencl_event_timer(void)
{
 return esim_real_time() * 1000;
}

canonical_original_code:
long long evg_opencl_event_timer()
{
 return esim_real_time() * 1000;
}


decompiled_code:
// write access to const memory has been detected, the output may be wrong!
_QWORD *evg_opencl_repo_create()
{
_QWORD *v0; // r12
_QWORD *result; // rax

v0 = (_QWORD *)mhandle_calloc(1LL, 8LL, "opencl-repo.c:40");
if ( v0 )
{
*v0 = linked_list_create();
result = v0;
}
else
{
fatal("%s: out of memory", "evg_opencl_repo_create");
*(_QWORD *)evg_opencl_repo_create = linked_list_create();
result = 0LL;
}
return result;
}

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

v0 = (_QWORD *)mhandle_calloc(1LL, 8LL, "opencl-repo.c:40");
if ( v0 )
{
*v0 = linked_list_create();
result = v0;
}
else
{
fatal("%s: out of memory", "evg_opencl_repo_create");
*(_QWORD *)evg_opencl_repo_create = linked_list_create();
result = 0LL;
}
return result;
}

original_code:
struct evg_opencl_repo_t *evg_opencl_repo_create(void)
{
 struct evg_opencl_repo_t *repo;
 repo = (mhandle_calloc(1, sizeof(struct evg_opencl_repo_t), "opencl-repo.c" ":" "40"));
 if (!repo)
  fatal("%s: out of memory", __FUNCTION__);
 repo->object_list = linked_list_create();
 return repo;
}

canonical_original_code:
struct evg_opencl_repo_t *evg_opencl_repo_create()
{
 struct evg_opencl_repo_t *repo;
 repo = (mhandle_calloc(1, sizeof(struct evg_opencl_repo_t), "opencl-repo.c" ":" "40"));
 if (!repo)
  fatal("%s: out of memory", __FUNCTION__);
 repo->object_list = linked_list_create();
 return repo;
}

variable_types: struct evg_opencl_repo_t { struct linked_list_t { int count; int error_code; struct linked_list_elem_t { struct linked_list_elem_t *prev; struct linked_list_elem_t *next; void *data; } *head; int current_index; } *object_list; } *

user_defined_types: struct evg_opencl_repo_t { struct linked_list_t *object_list; }

user_defined_types: struct linked_list_t { int count; int error_code; struct linked_list_elem_t *head; int current_index; }


decompiled_code:
__int64 __fastcall evg_opencl_repo_free(_QWORD *a1)
{
linked_list_free(*a1);
return mhandle_free(a1, "opencl-repo.c:55");
}

canonical_decompiled_code:
__int64 __fastcall func1(_QWORD *a1)
{
linked_list_free(*a1);
return mhandle_free(a1, "opencl-repo.c:55");
}

original_code:
void evg_opencl_repo_free(struct evg_opencl_repo_t *repo)
{
 linked_list_free(repo->object_list);
 (mhandle_free(repo, "opencl-repo.c" ":" "55"));
}

user_defined_types: struct linked_list_elem_t { struct linked_list_elem_t *prev; struct linked_list_elem_t *next; void *data; }


decompiled_code:
__int64 __fastcall evg_opencl_repo_add_object(_QWORD *a1, __int64 a2)
{
__int64 v2; // r12

v2 = *a1;
linked_list_find(*a1);
if ( !*(_DWORD *)(v2 + 4) )
fatal("%s: object already exists", "evg_opencl_repo_add_object");
return linked_list_add(v2, a2);
}

canonical_decompiled_code:
__int64 __fastcall func2(_QWORD *a1, __int64 a2)
{
__int64 v2; // r12

v2 = *a1;
linked_list_find(*a1);
if ( !*(_DWORD *)(v2 + 4) )
fatal("%s: object already exists", "evg_opencl_repo_add_object");
return linked_list_add(v2, a2);
}

original_code:
void evg_opencl_repo_add_object(struct evg_opencl_repo_t *repo,
 void *object)
{
 struct linked_list_t *object_list = repo->object_list;
 linked_list_find(object_list, object);
 if (!object_list->error_code)
  fatal("%s: object already exists", __FUNCTION__);
 linked_list_add(object_list, object);
}

variable_types:
object
void *

variable_types: struct linked_list_t { int count; int error_code; struct linked_list_elem_t { struct linked_list_elem_t *prev; struct linked_list_elem_t *next; void *data; } *head; int current_index; } *


decompiled_code:
__int64 __fastcall evg_opencl_repo_remove_object(_QWORD *a1)
{
__int64 v1; // rbp

v1 = *a1;
linked_list_find(*a1);
if ( *(_DWORD *)(v1 + 4) )
fatal("%s: object does not exist", "evg_opencl_repo_remove_object");
return linked_list_remove(v1);
}

canonical_decompiled_code:
__int64 __fastcall func3(_QWORD *a1)
{
__int64 v1; // rbp

v1 = *a1;
linked_list_find(*a1);
if ( *(_DWORD *)(v1 + 4) )
fatal("%s: object does not exist", "evg_opencl_repo_remove_object");
return linked_list_remove(v1);
}

original_code:
void evg_opencl_repo_remove_object(struct evg_opencl_repo_t *repo,
 void *object)
{
 struct linked_list_t *object_list = repo->object_list;
 linked_list_find(object_list, object);
 if (object_list->error_code)
  fatal("%s: object does not exist", __FUNCTION__);
 linked_list_remove(object_list);
}


decompiled_code:
__int64 __fastcall evg_opencl_repo_new_object_id(__int64 a1, int a2)
{
unsigned int v2; // er12

v2 = evg_opencl_object_id_counter_2++ | (a2 << 16);
if ( (unsigned int)evg_opencl_object_id_counter_2 > 0xFFFF )
fatal("%s: limit of OpenCL objects exceeded\n", "evg_opencl_repo_new_object_id");
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, int a2)
{
unsigned int v2; // er12

v2 = evg_opencl_object_id_counter_2++ | (a2 << 16);
if ( (unsigned int)evg_opencl_object_id_counter_2 > 0xFFFF )
fatal("%s: limit of OpenCL objects exceeded\n", "evg_opencl_repo_new_object_id");
return v2;
}

original_code:
unsigned int evg_opencl_repo_new_object_id(struct evg_opencl_repo_t *repo,
 enum evg_opencl_object_type_t type)
{
 static unsigned int evg_opencl_object_id_counter;
 unsigned int object_id;
 object_id = (type << 16) | evg_opencl_object_id_counter;
 evg_opencl_object_id_counter++;
 if (evg_opencl_object_id_counter > 0xffff)
  fatal("%s: limit of OpenCL objects exceeded\n", __FUNCTION__);
 return object_id;
}

variable_types: enum evg_opencl_object_type_t { evg_opencl_object_invalid=0, evg_opencl_object_platform=1, evg_opencl_object_device=2, evg_opencl_object_context=3, evg_opencl_object_command_queue=4, evg_opencl_object_program=5, evg_opencl_object_kernel=6, evg_opencl_object_mem=7, evg_opencl_object_event=8, evg_opencl_object_sampler=9 }


decompiled_code:
__int64 evg_opencl_command_queue_create()
{
__int64 v0; // r12
int v1; // eax

v0 = mhandle_calloc(1LL, 32LL, "opencl-command-queue.c:36");
if ( !v0 )
fatal("%s: out of memory", "evg_opencl_command_queue_create");
v1 = evg_opencl_repo_new_object_id(*(_QWORD *)(evg_emu + 8LL), 4LL);
*(_DWORD *)(v0 + 4) = 1;
*(_DWORD *)v0 = v1;
*(_QWORD *)(v0 + 24) = linked_list_create();
evg_opencl_repo_add_object(*(_QWORD *)(evg_emu + 8LL), v0);
return v0;
}

canonical_decompiled_code:
__int64 func0()
{
__int64 v0; // r12
int v1; // eax

v0 = mhandle_calloc(1LL, 32LL, "opencl-command-queue.c:36");
if ( !v0 )
fatal("%s: out of memory", "evg_opencl_command_queue_create");
v1 = evg_opencl_repo_new_object_id(*(_QWORD *)(evg_emu + 8LL), 4LL);
*(_DWORD *)(v0 + 4) = 1;
*(_DWORD *)v0 = v1;
*(_QWORD *)(v0 + 24) = linked_list_create();
evg_opencl_repo_add_object(*(_QWORD *)(evg_emu + 8LL), v0);
return v0;
}

original_code:
struct evg_opencl_command_queue_t *evg_opencl_command_queue_create()
{
 struct evg_opencl_command_queue_t *command_queue;
 command_queue = (mhandle_calloc(1, sizeof(struct evg_opencl_command_queue_t), "opencl-command-queue.c" ":" "36"));
 if (!command_queue)
  fatal("%s: out of memory", __FUNCTION__);
 command_queue->id = evg_opencl_repo_new_object_id(evg_emu->opencl_repo,
  evg_opencl_object_command_queue);
 command_queue->ref_count = 1;
 command_queue->command_list = linked_list_create();
 evg_opencl_repo_add_object(evg_emu->opencl_repo, command_queue);
 return command_queue;
}

variable_types: struct evg_opencl_command_queue_t { unsigned int id; int ref_count; unsigned int device_id; unsigned int context_id; unsigned int properties; struct linked_list_t { int count; int error_code; struct linked_list_elem_t { struct linked_list_elem_t *prev; struct linked_list_elem_t *next; void *data; } *head; int current_index; } *command_list; } *

user_defined_types: struct evg_opencl_command_queue_t { unsigned int id; int ref_count; unsigned int device_id; unsigned int context_id; unsigned int properties; struct linked_list_t *command_list; }


decompiled_code:
__int64 __fastcall evg_opencl_command_queue_free(__int64 a1)
{
if ( (unsigned int)linked_list_count(*(_QWORD *)(a1 + 24)) )
fatal("%s: freed command queue is not empty", "evg_opencl_command_queue_free");
evg_opencl_repo_remove_object(*(_QWORD *)(evg_emu + 8LL), a1);
linked_list_free(*(_QWORD *)(a1 + 24));
return mhandle_free(a1, "opencl-command-queue.c:62");
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
if ( (unsigned int)linked_list_count(*(_QWORD *)(a1 + 24)) )
fatal("%s: freed command queue is not empty", "evg_opencl_command_queue_free");
evg_opencl_repo_remove_object(*(_QWORD *)(evg_emu + 8LL), a1);
linked_list_free(*(_QWORD *)(a1 + 24));
return mhandle_free(a1, "opencl-command-queue.c:62");
}

original_code:
void evg_opencl_command_queue_free(struct evg_opencl_command_queue_t *command_queue)
{
 if (linked_list_count(command_queue->command_list))
  fatal("%s: freed command queue is not empty", __FUNCTION__);
 evg_opencl_repo_remove_object(evg_emu->opencl_repo, command_queue);
 linked_list_free(command_queue->command_list);
 (mhandle_free(command_queue, "opencl-command-queue.c" ":" "62"));
}


decompiled_code:
__int64 __fastcall x86_cpu_dispatch_core(int a1)
{
__int64 result; // rax
int v3; // ebx
unsigned int v4; // er12
__int64 v5; // r13
int v6; // edi
__int64 v7; // r13
__int64 v8; // rcx
int v9; // edx
int v10; // esi
__int64 v11; // r13
int v12; // edi
__int64 v13; // r13
__int64 v14; // rcx
int v15; // edx

result = x86_cpu_dispatch_kind;
v3 = x86_cpu_num_threads;
v4 = x86_cpu_dispatch_width;
if ( x86_cpu_dispatch_kind )
{
if ( x86_cpu_dispatch_kind == 1 )
{
v5 = a1;
v6 = x86_cpu_num_threads;
v7 = 1824 * v5;
while ( 1 )
{
v8 = v7 + *x86_cpu;
v9 = (*(_DWORD *)(v8 + 100) + 1) % v6;
*(_DWORD *)(v8 + 100) = v9;
v10 = v9;
if ( !--v3 )
break;
if ( !(unsigned int)x86_cpu_can_dispatch_thread(a1, v9) )
{
v10 = *(_DWORD *)(*x86_cpu + v7 + 100);
break;
}
v6 = x86_cpu_num_threads;
}
result = x86_cpu_dispatch_thread(a1, v10, v4);
}
}
else
{
v11 = a1;
v12 = x86_cpu_num_threads;
v13 = 1824 * v11;
while ( 1 )
{
--v3;
v14 = v13 + *x86_cpu;
v15 = (*(_DWORD *)(v14 + 100) + 1) % v12;
*(_DWORD *)(v14 + 100) = v15;
result = x86_cpu_dispatch_thread(a1, v15, 1u);
if ( !(_DWORD)result )
{
v3 = x86_cpu_num_threads;
--v4;
}
if ( !v4 || !v3 )
break;
v12 = x86_cpu_num_threads;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1)
{
__int64 result; // rax
int v3; // ebx
unsigned int v4; // er12
__int64 v5; // r13
int v6; // edi
__int64 v7; // r13
__int64 v8; // rcx
int v9; // edx
int v10; // esi
__int64 v11; // r13
int v12; // edi
__int64 v13; // r13
__int64 v14; // rcx
int v15; // edx

result = x86_cpu_dispatch_kind;
v3 = x86_cpu_num_threads;
v4 = x86_cpu_dispatch_width;
if ( x86_cpu_dispatch_kind )
{
if ( x86_cpu_dispatch_kind == 1 )
{
v5 = a1;
v6 = x86_cpu_num_threads;
v7 = 1824 * v5;
while ( 1 )
{
v8 = v7 + *x86_cpu;
v9 = (*(_DWORD *)(v8 + 100) + 1) % v6;
*(_DWORD *)(v8 + 100) = v9;
v10 = v9;
if ( !--v3 )
break;
if ( !(unsigned int)func0(a1, v9) )
{
v10 = *(_DWORD *)(*x86_cpu + v7 + 100);
break;
}
v6 = x86_cpu_num_threads;
}
result = func1(a1, v10, v4);
}
}
else
{
v11 = a1;
v12 = x86_cpu_num_threads;
v13 = 1824 * v11;
while ( 1 )
{
--v3;
v14 = v13 + *x86_cpu;
v15 = (*(_DWORD *)(v14 + 100) + 1) % v12;
*(_DWORD *)(v14 + 100) = v15;
result = func1(a1, v15, 1u);
if ( !(_DWORD)result )
{
v3 = x86_cpu_num_threads;
--v4;
}
if ( !v4 || !v3 )
break;
v12 = x86_cpu_num_threads;
}
}
return result;
}

original_code:
static void x86_cpu_dispatch_core(int core)
{
 int skip = x86_cpu_num_threads;
 int quant = x86_cpu_dispatch_width;
 int remain;
 switch (x86_cpu_dispatch_kind)
 {
 case x86_cpu_dispatch_kind_shared:
  do {
   (x86_cpu->core[core]).dispatch_current = ((x86_cpu->core[core]).dispatch_current + 1) % x86_cpu_num_threads;
   remain = x86_cpu_dispatch_thread(core, (x86_cpu->core[core]).dispatch_current, 1);
   skip = remain ? skip - 1 : x86_cpu_num_threads;
   quant = remain ? quant : quant - 1;
  } while (quant && skip);
  break;
 case x86_cpu_dispatch_kind_timeslice:
  do {
   (x86_cpu->core[core]).dispatch_current = ((x86_cpu->core[core]).dispatch_current + 1) % x86_cpu_num_threads;
   skip--;
  } while (skip && x86_cpu_can_dispatch_thread(core, (x86_cpu->core[core]).dispatch_current) != x86_dispatch_stall_used);
  x86_cpu_dispatch_thread(core, (x86_cpu->core[core]).dispatch_current, quant);
  break;
 }
}

variable_types: core int

variable_types: skip int

variable_types: quant int

variable_types: remain int


decompiled_code:
__int64 x86_cpu_dispatch()
{
__int64 result; // rax
int v1; // ebx
int v2; // edi

*(_QWORD *)(x86_cpu + 32LL) = "dispatch";
result = x86_cpu_num_cores;
if ( x86_cpu_num_cores > 0 )
{
v1 = 0;
do
{
v2 = v1++;
result = x86_cpu_dispatch_core(v2);
}
while ( x86_cpu_num_cores > v1 );
}
return result;
}

canonical_decompiled_code:
__int64 func3()
{
__int64 result; // rax
int v1; // ebx
int v2; // edi

*(_QWORD *)(x86_cpu + 32LL) = "dispatch";
result = x86_cpu_num_cores;
if ( x86_cpu_num_cores > 0 )
{
v1 = 0;
do
{
v2 = v1++;
result = func2(v2);
}
while ( x86_cpu_num_cores > v1 );
}
return result;
}

original_code:
void x86_cpu_dispatch()
{
 int core;
 x86_cpu->stage = "dispatch";
 for (core = 0; core < x86_cpu_num_cores; core++)
  x86_cpu_dispatch_core(core);
}


decompiled_code:
__int64 __fastcall dir_free(_QWORD *a1)
{
mhandle_free(*a1, "directory.c:88");
mhandle_free(a1[3], "directory.c:89");
return mhandle_free(a1, "directory.c:90");
}

canonical_decompiled_code:
__int64 __fastcall func0(_QWORD *a1)
{
mhandle_free(*a1, "directory.c:88");
mhandle_free(a1[3], "directory.c:89");
return mhandle_free(a1, "directory.c:90");
}

original_code:
void dir_free(struct dir_t *dir)
{
 (mhandle_free(dir->name, "directory.c" ":" "88"));
 (mhandle_free(dir->dir_lock, "directory.c" ":" "89"));
 (mhandle_free(dir, "directory.c" ":" "90"));
}

variable_types: struct dir_t { char *name; int num_nodes; int xsize; struct dir_lock_t { int lock; long long stack_id; struct mod_stack_t { long long id; enum mod_access_kind_t { mod_access_invalid=0, mod_access_load=1, mod_access_store=2, mod_access_nc_store=3 } access_kind; int *witness_ptr; struct linked_list_t { int count; int error_code; struct linked_list_elem_t { struct linked_list_elem_t *prev; struct linked_list_elem_t *next; void *data; } *head; int current_index; } *event_queue; void *event_queue_item; struct mod_t { enum mod_kind_t { mod_kind_invalid=0, mod_kind_cache=1, mod_kind_main_memory=2, mod_kind_local_memory=3 } kind; char *name; int block_size; int log_block_size; int latency; int dir_latency; int mshr_size; int level; enum mod_range_kind_t { mod_range_invalid=0, mod_range_bounds=1, mod_range_interleaved=2 } range_kind; union { struct { unsigned int low; unsigned int high; } bounds; struct { unsigned int mod; unsigned int div; unsigned int eq; } interleaved; } range; struct mod_port_t { int locked; long long lock_when; struct mod_stack_t *stack; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; } *ports; int num_ports; int num_locked_ports; struct mod_stack_t *port_waiting_list_head; struct mod_stack_t *port_waiting_list_tail; int port_waiting_list_count; int port_waiting_list_max; struct dir_t *dir; int dir_size; int dir_assoc; int dir_num_sets; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; struct cache_t { char *name; unsigned int num_sets; unsigned int block_size; unsigned int assoc; enum cache_policy_t { cache_policy_invalid=0, cache_policy_lru=1, cache_policy_fifo=2, cache_policy_random=3 } policy; struct cache_set_t { struct cache_block_t { struct cache_block_t *way_next; struct cache_block_t *way_prev; int tag; int transient_tag; int way; enum cache_block_state_t { cache_block_invalid=0, cache_block_noncoherent=1, cache_block_modified=2, cache_block_owned=3, cache_block_exclusive=4, cache_block_shared=5 } state; } *way_head; struct cache_block_t *way_tail; struct cache_block_t *blocks; } *sets; unsigned int block_mask; int log_block_size; } *cache; struct linked_list_t *high_mod_list; struct linked_list_t *low_mod_list; int sub_block_size; int num_sub_blocks; struct net_t { char *name; long long msg_id_counter; struct list_t { int count; int error_code; int size; int head; int tail; void **elem; } *node_list; int node_count; int end_node_count; struct list_t *link_list; struct net_routing_table_t { struct net_t *net; int dim; struct net_routing_table_entry_t { int cost; struct net_node_t { struct net_t *net; enum net_node_kind_t { net_node_invalid=0, net_node_end=1, net_node_switch=2, net_node_bus=3 } kind; int index; char *name; void *user_data; int bandwidth; long long bus_busy; int input_buffer_size; int output_buffer_size; struct list_t *input_buffer_list; struct list_t *output_buffer_list; long long bytes_received; long long msgs_received; long long bytes_sent; long long msgs_sent; } *next_node; struct net_buffer_t { struct net_t *net; struct net_node_t *node; char *name; int index; int size; int count; long long read_busy; long long write_busy; struct net_link_t { struct net_t *net; char *name; struct net_node_t *src_node; struct net_node_t *dst_node; struct net_buffer_t *dst_buffer; struct net_buffer_t *src_buffer; int bandwidth; long long busy; int virtual_channel; long long sched_when; struct net_buffer_t *sched_buffer; long long busy_cycles; long long transferred_bytes; long long transferred_msgs; } *link; struct list_t *msg_list; long long sched_when; struct net_buffer_t *sched_buffer; struct linked_list_t *wakeup_list; int occupancy_bytes_value; int occupancy_msgs_value; long long occupancy_measured_cycle; long long occupancy_bytes_acc; long long occupancy_msgs_acc; } *output_buffer; } *entries; int has_cycle; } *routing_table; struct net_msg_t { struct net_t *net; long long id; int size; long long send_cycle; long long busy; struct net_node_t *src_node; struct net_node_t *dst_node; void *data; struct net_node_t *node; struct net_buffer_t *buffer; struct net_buffer_t *src_buffer; struct net_buffer_t *dst_buffer; struct net_msg_t *bucket_next; } *msg_table[32]; long long transfers; long long lat_acc; long long msg_size_acc; } *high_net; struct net_t *low_net; struct net_node_t *high_net_node; struct net_node_t *low_net_node; struct mod_stack_t *access_list_head; struct mod_stack_t *access_list_tail; int access_list_count; int access_list_max; struct mod_stack_t *write_access_list_head; struct mod_stack_t *write_access_list_tail; int write_access_list_count; int write_access_list_max; int access_list_coalesced_count; struct { struct mod_stack_t *bucket_list_head; struct mod_stack_t *bucket_list_tail; int bucket_list_count; int bucket_list_max; } access_hash_table[17]; int color; long long accesses; long long hits; long long reads; long long effective_reads; long long effective_read_hits; long long writes; long long effective_writes; long long effective_write_hits; long long nc_writes; long long effective_nc_writes; long long effective_nc_write_hits; long long evictions; long long blocking_reads; long long non_blocking_reads; long long read_hits; long long blocking_writes; long long non_blocking_writes; long long write_hits; long long blocking_nc_writes; long long non_blocking_nc_writes; long long nc_write_hits; long long read_retries; long long write_retries; long long nc_write_retries; long long no_retry_accesses; long long no_retry_hits; long long no_retry_reads; long long no_retry_read_hits; long long no_retry_writes; long long no_retry_write_hits; long long no_retry_nc_writes; long long no_retry_nc_write_hits; } *mod; struct mod_t *target_mod; struct mod_t *except_mod; struct mod_t *peer; struct mod_port_t *port; unsigned int addr; int tag; int set; int way; int state; int src_set; int src_way; int src_tag; enum mod_request_dir_t { mod_request_invalid=0, mod_request_up_down=1, mod_request_down_up=2 } request_dir; enum mod_message_type_t { message_none=0, message_clear_owner=1 } message; enum mod_reply_type_t { reply_none=0, reply_ack=1, reply_ack_data=2, reply_ack_data_sent_to_peer=3, reply_ack_error=4 } reply; int reply_size; int retain_owner; int pending; struct mod_stack_t *access_list_prev; struct mod_stack_t *access_list_next; struct mod_stack_t *write_access_list_prev; struct mod_stack_t *write_access_list_next; struct mod_stack_t *bucket_list_prev; struct mod_stack_t *bucket_list_next; int hit; int err; int shared; int read; int write; int nc_write; int blocking; int writeback; int eviction; int retry; int coalesced; int port_locked; struct net_msg_t *msg; int waiting_list_event; struct mod_stack_t *waiting_list_prev; struct mod_stack_t *waiting_list_next; int port_waiting_list_event; struct mod_stack_t *port_waiting_list_prev; struct mod_stack_t *port_waiting_list_next; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; struct mod_stack_t *master_stack; int dir_lock_event; struct mod_stack_t *dir_lock_next; struct mod_stack_t *ret_stack; int ret_event; } *lock_queue; } *dir_lock; unsigned char data[]; } *

user_defined_types: struct dir_t { char *name; int num_nodes; int xsize; struct dir_lock_t *dir_lock; unsigned char data[]; }

user_defined_types: struct dir_lock_t { int lock; long long stack_id; struct mod_stack_t *lock_queue; }

user_defined_types: struct mod_stack_t { long long id; enum mod_access_kind_t access_kind; int *witness_ptr; struct linked_list_t *event_queue; void *event_queue_item; struct mod_t *mod; struct mod_t *target_mod; struct mod_t *except_mod; struct mod_t *peer; struct mod_port_t *port; unsigned int addr; int tag; int set; int way; int state; int src_set; int src_way; int src_tag; enum mod_request_dir_t request_dir; enum mod_message_type_t message; enum mod_reply_type_t reply; int reply_size; int retain_owner; int pending; struct mod_stack_t *access_list_prev; struct mod_stack_t *access_list_next; struct mod_stack_t *write_access_list_prev; struct mod_stack_t *write_access_list_next; struct mod_stack_t *bucket_list_prev; struct mod_stack_t *bucket_list_next; int hit; int err; int shared; int read; int write; int nc_write; int blocking; int writeback; int eviction; int retry; int coalesced; int port_locked; struct net_msg_t *msg; int waiting_list_event; struct mod_stack_t *waiting_list_prev; struct mod_stack_t *waiting_list_next; int port_waiting_list_event; struct mod_stack_t *port_waiting_list_prev; struct mod_stack_t *port_waiting_list_next; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; struct mod_stack_t *master_stack; int dir_lock_event; struct mod_stack_t *dir_lock_next; struct mod_stack_t *ret_stack; int ret_event; }

user_defined_types: struct mod_t { enum mod_kind_t kind; char *name; int block_size; int log_block_size; int latency; int dir_latency; int mshr_size; int level; enum mod_range_kind_t range_kind; union { struct { unsigned int low; unsigned int high; } bounds; struct { unsigned int mod; unsigned int div; unsigned int eq; } interleaved; } range; struct mod_port_t *ports; int num_ports; int num_locked_ports; struct mod_stack_t *port_waiting_list_head; struct mod_stack_t *port_waiting_list_tail; int port_waiting_list_count; int port_waiting_list_max; struct dir_t *dir; int dir_size; int dir_assoc; int dir_num_sets; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; struct cache_t *cache; struct linked_list_t *high_mod_list; struct linked_list_t *low_mod_list; int sub_block_size; int num_sub_blocks; struct net_t *high_net; struct net_t *low_net; struct net_node_t *high_net_node; struct net_node_t *low_net_node; struct mod_stack_t *access_list_head; struct mod_stack_t *access_list_tail; int access_list_count; int access_list_max; struct mod_stack_t *write_access_list_head; struct mod_stack_t *write_access_list_tail; int write_access_list_count; int write_access_list_max; int access_list_coalesced_count; struct { struct mod_stack_t *bucket_list_head; struct mod_stack_t *bucket_list_tail; int bucket_list_count; int bucket_list_max; } access_hash_table[17]; int color; long long accesses; long long hits; long long reads; long long effective_reads; long long effective_read_hits; long long writes; long long effective_writes; long long effective_write_hits; long long nc_writes; long long effective_nc_writes; long long effective_nc_write_hits; long long evictions; long long blocking_reads; long long non_blocking_reads; long long read_hits; long long blocking_writes; long long non_blocking_writes; long long write_hits; long long blocking_nc_writes; long long non_blocking_nc_writes; long long nc_write_hits; long long read_retries; long long write_retries; long long nc_write_retries; long long no_retry_accesses; long long no_retry_hits; long long no_retry_reads; long long no_retry_read_hits; long long no_retry_writes; long long no_retry_write_hits; long long no_retry_nc_writes; long long no_retry_nc_write_hits; }

user_defined_types: struct cache_t { char *name; unsigned int num_sets; unsigned int block_size; unsigned int assoc; enum cache_policy_t policy; struct cache_set_t *sets; unsigned int block_mask; int log_block_size; }

user_defined_types: struct net_t { char *name; long long msg_id_counter; struct list_t *node_list; int node_count; int end_node_count; struct list_t *link_list; struct net_routing_table_t *routing_table; struct net_msg_t *msg_table[32]; long long transfers; long long lat_acc; long long msg_size_acc; }

user_defined_types: struct cache_set_t { struct cache_block_t *way_head; struct cache_block_t *way_tail; struct cache_block_t *blocks; }

user_defined_types: struct net_routing_table_t { struct net_t *net; int dim; struct net_routing_table_entry_t *entries; int has_cycle; }

user_defined_types: struct cache_block_t { struct cache_block_t *way_next; struct cache_block_t *way_prev; int tag; int transient_tag; int way; enum cache_block_state_t state; }

user_defined_types: struct net_routing_table_entry_t { int cost; struct net_node_t *next_node; struct net_buffer_t *output_buffer; }

user_defined_types: struct net_node_t { struct net_t *net; enum net_node_kind_t kind; int index; char *name; void *user_data; int bandwidth; long long bus_busy; int input_buffer_size; int output_buffer_size; struct list_t *input_buffer_list; struct list_t *output_buffer_list; long long bytes_received; long long msgs_received; long long bytes_sent; long long msgs_sent; }

user_defined_types: struct net_buffer_t { struct net_t *net; struct net_node_t *node; char *name; int index; int size; int count; long long read_busy; long long write_busy; struct net_link_t *link; struct list_t *msg_list; long long sched_when; struct net_buffer_t *sched_buffer; struct linked_list_t *wakeup_list; int occupancy_bytes_value; int occupancy_msgs_value; long long occupancy_measured_cycle; long long occupancy_bytes_acc; long long occupancy_msgs_acc; }


decompiled_code:
__int64 __fastcall dir_entry_get(_DWORD *a1, int a2, int a3, int a4)
{
int v5; // esi
int v6; // er11
int v7; // eax
int v8; // er8
int v9; // eax

if ( a2 < 0 || a1[3] <= a2 )
_assert_fail("IN_RANGE(x, 0, dir->xsize - 1)", "directory.c", 0x60u, "dir_entry_get");
if ( a3 < 0 || (v5 = a1[4], v5 <= a3) )
_assert_fail("IN_RANGE(y, 0, dir->ysize - 1)", "directory.c", 0x61u, "dir_entry_get");
if ( a4 < 0 || (v6 = a1[5], v6 <= a4) )
_assert_fail("IN_RANGE(z, 0, dir->zsize - 1)", "directory.c", 0x62u, "dir_entry_get");
v7 = a1[2];
v8 = v7 + 14;
v9 = v7 + 7;
if ( v9 < 0 )
v9 = v8;
return (__int64)a1 + ((v9 >> 3) + 8) * (__int64)(a4 + v6 * (a2 * v5 + a3)) + 32;
}

canonical_decompiled_code:
__int64 __fastcall func1(_DWORD *a1, int a2, int a3, int a4)
{
int v5; // esi
int v6; // er11
int v7; // eax
int v8; // er8
int v9; // eax

if ( a2 < 0 || a1[3] <= a2 )
_assert_fail("IN_RANGE(x, 0, dir->xsize - 1)", "directory.c", 0x60u, "dir_entry_get");
if ( a3 < 0 || (v5 = a1[4], v5 <= a3) )
_assert_fail("IN_RANGE(y, 0, dir->ysize - 1)", "directory.c", 0x61u, "dir_entry_get");
if ( a4 < 0 || (v6 = a1[5], v6 <= a4) )
_assert_fail("IN_RANGE(z, 0, dir->zsize - 1)", "directory.c", 0x62u, "dir_entry_get");
v7 = a1[2];
v8 = v7 + 14;
v9 = v7 + 7;
if ( v9 < 0 )
v9 = v8;
return (__int64)a1 + ((v9 >> 3) + 8) * (__int64)(a4 + v6 * (a2 * v5 + a3)) + 32;
}

original_code:
struct dir_entry_t *dir_entry_get(struct dir_t *dir, int x, int y, int z)
{
 ((void) sizeof ((((x)>=(0)&&(x)<=(dir->xsize - 1))) ? 1 : 0), __extension__ ({ if (((x)>=(0)&&(x)<=(dir->xsize - 1))) ; else __assert_fail ("IN_RANGE(x, 0, dir->xsize - 1)", "directory.c", 96, __extension__ __PRETTY_FUNCTION__); }));
 ((void) sizeof ((((y)>=(0)&&(y)<=(dir->ysize - 1))) ? 1 : 0), __extension__ ({ if (((y)>=(0)&&(y)<=(dir->ysize - 1))) ; else __assert_fail ("IN_RANGE(y, 0, dir->ysize - 1)", "directory.c", 97, __extension__ __PRETTY_FUNCTION__); }));
 ((void) sizeof ((((z)>=(0)&&(z)<=(dir->zsize - 1))) ? 1 : 0), __extension__ ({ if (((z)>=(0)&&(z)<=(dir->zsize - 1))) ; else __assert_fail ("IN_RANGE(z, 0, dir->zsize - 1)", "directory.c", 98, __extension__ __PRETTY_FUNCTION__); }));
 return ((struct dir_entry_t *) (((void *) &dir->data) + (sizeof(struct dir_entry_t) + ((dir->num_nodes + 7) / 8)) * ((x) * dir->ysize * dir->zsize + (y) * dir->zsize + (z))));
}

variable_types: x int

variable_types: y int

variable_types: z int

return_type: struct dir_entry_t { int owner; int num_sharers; unsigned char sharer[]; } *

user_defined_types: enum mod_access_kind_t { mod_access_invalid=0, mod_access_load=1, mod_access_store=2, mod_access_nc_store=3 }

user_defined_types: enum mod_request_dir_t { mod_request_invalid=0, mod_request_up_down=1, mod_request_down_up=2 }

user_defined_types: enum mod_message_type_t { message_none=0, message_clear_owner=1 }

user_defined_types: enum mod_reply_type_t { reply_none=0, reply_ack=1, reply_ack_data=2, reply_ack_data_sent_to_peer=3, reply_ack_error=4 }

user_defined_types: enum mod_kind_t { mod_kind_invalid=0, mod_kind_cache=1, mod_kind_main_memory=2, mod_kind_local_memory=3 }

user_defined_types: enum mod_range_kind_t { mod_range_invalid=0, mod_range_bounds=1, mod_range_interleaved=2 }

user_defined_types: struct mod_port_t { int locked; long long lock_when; struct mod_stack_t *stack; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; }

user_defined_types: enum cache_policy_t { cache_policy_invalid=0, cache_policy_lru=1, cache_policy_fifo=2, cache_policy_random=3 }

user_defined_types: struct list_t { int count; int error_code; int size; int head; int tail; void **elem; }

user_defined_types: struct net_msg_t { struct net_t *net; long long id; int size; long long send_cycle; long long busy; struct net_node_t *src_node; struct net_node_t *dst_node; void *data; struct net_node_t *node; struct net_buffer_t *buffer; struct net_buffer_t *src_buffer; struct net_buffer_t *dst_buffer; struct net_msg_t *bucket_next; }

user_defined_types: enum cache_block_state_t { cache_block_invalid=0, cache_block_noncoherent=1, cache_block_modified=2, cache_block_owned=3, cache_block_exclusive=4, cache_block_shared=5 }

user_defined_types: enum net_node_kind_t { net_node_invalid=0, net_node_end=1, net_node_switch=2, net_node_bus=3 }

user_defined_types: struct net_link_t { struct net_t *net; char *name; struct net_node_t *src_node; struct net_node_t *dst_node; struct net_buffer_t *dst_buffer; struct net_buffer_t *src_buffer; int bandwidth; long long busy; int virtual_channel; long long sched_when; struct net_buffer_t *sched_buffer; long long busy_cycles; long long transferred_bytes; long long transferred_msgs; }


decompiled_code:
__int64 __fastcall dir_create(__int64 a1, int a2, int a3, int a4, int a5)
{
__int64 v8; // r13
__int64 v9; // rax
__int64 v10; // rax
int v11; // er12
int v12; // ebx
int v13; // er15
_DWORD *v14; // rax

if ( a5 <= 0 )
_assert_fail("num_nodes > 0", "directory.c", 0x2Bu, "dir_create");
v8 = mhandle_calloc(1LL, a4 * a3 * a2 * (((a5 + 7) >> 3) + 8) + 32, "directory.c:48");
if ( !v8 )
fatal("%s: out of memory", "dir_create");
v9 = mhandle_strdup(a1, "directory.c:53");
*(_QWORD *)v8 = v9;
if ( !v9 )
fatal("%s: out of memory", "dir_create");
v10 = mhandle_calloc(a3 * a2, 24LL, "directory.c:58");
*(_QWORD *)(v8 + 24) = v10;
if ( !v10 )
fatal("%s: out of memory", "dir_create");
*(_DWORD *)(v8 + 8) = a5;
v11 = 0;
*(_DWORD *)(v8 + 16) = a3;
*(_DWORD *)(v8 + 12) = a2;
*(_DWORD *)(v8 + 20) = a4;
if ( a2 > 0 )
{
do
{
v12 = 0;
if ( a3 > 0 )
{
do
{
v13 = 0;
if ( a4 > 0 )
{
do
{
v14 = (_DWORD *)dir_entry_get((_DWORD *)v8, v11, v12, v13++);
*v14 = -1;
}
while ( a4 != v13 );
}
++v12;
}
while ( a3 != v12 );
}
++v11;
}
while ( a2 != v11 );
}
return v8;
}

original_code:
struct dir_t *dir_create(char *name, int xsize, int ysize, int zsize, int num_nodes)
{
 struct dir_t *dir;
 struct dir_entry_t *dir_entry;
 int dir_size;
 int dir_entry_size;
 int x;
 int y;
 int z;
 ((void) sizeof ((num_nodes > 0) ? 1 : 0), __extension__ ({ if (num_nodes > 0) ; else __assert_fail ("num_nodes > 0", "directory.c", 43, __extension__ __PRETTY_FUNCTION__); }));
 dir_entry_size = sizeof(struct dir_entry_t) + (num_nodes + 7) / 8;
 dir_size = sizeof(struct dir_t) + dir_entry_size * xsize * ysize * zsize;
 dir = (mhandle_calloc(1, dir_size, "directory.c" ":" "48"));
 if (!dir)
  fatal("%s: out of memory", __FUNCTION__);
 dir->name = (mhandle_strdup(name, "directory.c" ":" "53"));
 if (!dir->name)
  fatal("%s: out of memory", __FUNCTION__);
 dir->dir_lock = (mhandle_calloc(xsize * ysize, sizeof(struct dir_lock_t), "directory.c" ":" "58"));
 if (!dir->dir_lock)
  fatal("%s: out of memory", __FUNCTION__);
 dir->num_nodes = num_nodes;
 dir->xsize = xsize;
 dir->ysize = ysize;
 dir->zsize = zsize;
 for (x = 0; x < xsize; x++)
 {
  for (y = 0; y < ysize; y++)
  {
   for (z = 0; z < zsize; z++)
   {
    dir_entry = dir_entry_get(dir, x, y, z);
    dir_entry->owner = (-1);
   }
  }
 }
 return dir;
}

variable_types:
name
char *

variable_types: xsize int

variable_types: ysize int

variable_types: zsize int

variable_types: struct dir_entry_t { int owner; int num_sharers; unsigned char sharer[]; } *

return_type: struct dir_t { char *name; int num_nodes; int xsize; struct dir_lock_t { int lock; long long stack_id; struct mod_stack_t { long long id; enum mod_access_kind_t { mod_access_invalid=0, mod_access_load=1, mod_access_store=2, mod_access_nc_store=3 } access_kind; int *witness_ptr; struct linked_list_t { int count; int error_code; struct linked_list_elem_t { struct linked_list_elem_t *prev; struct linked_list_elem_t *next; void *data; } *head; int current_index; } *event_queue; void *event_queue_item; struct mod_t { enum mod_kind_t { mod_kind_invalid=0, mod_kind_cache=1, mod_kind_main_memory=2, mod_kind_local_memory=3 } kind; char *name; int block_size; int log_block_size; int latency; int dir_latency; int mshr_size; int level; enum mod_range_kind_t { mod_range_invalid=0, mod_range_bounds=1, mod_range_interleaved=2 } range_kind; union { struct { unsigned int low; unsigned int high; } bounds; struct { unsigned int mod; unsigned int div; unsigned int eq; } interleaved; } range; struct mod_port_t { int locked; long long lock_when; struct mod_stack_t *stack; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; } *ports; int num_ports; int num_locked_ports; struct mod_stack_t *port_waiting_list_head; struct mod_stack_t *port_waiting_list_tail; int port_waiting_list_count; int port_waiting_list_max; struct dir_t *dir; int dir_size; int dir_assoc; int dir_num_sets; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; struct cache_t { char *name; unsigned int num_sets; unsigned int block_size; unsigned int assoc; enum cache_policy_t { cache_policy_invalid=0, cache_policy_lru=1, cache_policy_fifo=2, cache_policy_random=3 } policy; struct cache_set_t { struct cache_block_t { struct cache_block_t *way_next; struct cache_block_t *way_prev; int tag; int transient_tag; int way; enum cache_block_state_t { cache_block_invalid=0, cache_block_noncoherent=1, cache_block_modified=2, cache_block_owned=3, cache_block_exclusive=4, cache_block_shared=5 } state; } *way_head; struct cache_block_t *way_tail; struct cache_block_t *blocks; } *sets; unsigned int block_mask; int log_block_size; } *cache; struct linked_list_t *high_mod_list; struct linked_list_t *low_mod_list; int sub_block_size; int num_sub_blocks; struct net_t { char *name; long long msg_id_counter; struct list_t { int count; int error_code; int size; int head; int tail; void **elem; } *node_list; int node_count; int end_node_count; struct list_t *link_list; struct net_routing_table_t { struct net_t *net; int dim; struct net_routing_table_entry_t { int cost; struct net_node_t { struct net_t *net; enum net_node_kind_t { net_node_invalid=0, net_node_end=1, net_node_switch=2, net_node_bus=3 } kind; int index; char *name; void *user_data; int bandwidth; long long bus_busy; int input_buffer_size; int output_buffer_size; struct list_t *input_buffer_list; struct list_t *output_buffer_list; long long bytes_received; long long msgs_received; long long bytes_sent; long long msgs_sent; } *next_node; struct net_buffer_t { struct net_t *net; struct net_node_t *node; char *name; int index; int size; int count; long long read_busy; long long write_busy; struct net_link_t { struct net_t *net; char *name; struct net_node_t *src_node; struct net_node_t *dst_node; struct net_buffer_t *dst_buffer; struct net_buffer_t *src_buffer; int bandwidth; long long busy; int virtual_channel; long long sched_when; struct net_buffer_t *sched_buffer; long long busy_cycles; long long transferred_bytes; long long transferred_msgs; } *link; struct list_t *msg_list; long long sched_when; struct net_buffer_t *sched_buffer; struct linked_list_t *wakeup_list; int occupancy_bytes_value; int occupancy_msgs_value; long long occupancy_measured_cycle; long long occupancy_bytes_acc; long long occupancy_msgs_acc; } *output_buffer; } *entries; int has_cycle; } *routing_table; struct net_msg_t { struct net_t *net; long long id; int size; long long send_cycle; long long busy; struct net_node_t *src_node; struct net_node_t *dst_node; void *data; struct net_node_t *node; struct net_buffer_t *buffer; struct net_buffer_t *src_buffer; struct net_buffer_t *dst_buffer; struct net_msg_t *bucket_next; } *msg_table[32]; long long transfers; long long lat_acc; long long msg_size_acc; } *high_net; struct net_t *low_net; struct net_node_t *high_net_node; struct net_node_t *low_net_node; struct mod_stack_t *access_list_head; struct mod_stack_t *access_list_tail; int access_list_count; int access_list_max; struct mod_stack_t *write_access_list_head; struct mod_stack_t *write_access_list_tail; int write_access_list_count; int write_access_list_max; int access_list_coalesced_count; struct { struct mod_stack_t *bucket_list_head; struct mod_stack_t *bucket_list_tail; int bucket_list_count; int bucket_list_max; } access_hash_table[17]; int color; long long accesses; long long hits; long long reads; long long effective_reads; long long effective_read_hits; long long writes; long long effective_writes; long long effective_write_hits; long long nc_writes; long long effective_nc_writes; long long effective_nc_write_hits; long long evictions; long long blocking_reads; long long non_blocking_reads; long long read_hits; long long blocking_writes; long long non_blocking_writes; long long write_hits; long long blocking_nc_writes; long long non_blocking_nc_writes; long long nc_write_hits; long long read_retries; long long write_retries; long long nc_write_retries; long long no_retry_accesses; long long no_retry_hits; long long no_retry_reads; long long no_retry_read_hits; long long no_retry_writes; long long no_retry_write_hits; long long no_retry_nc_writes; long long no_retry_nc_write_hits; } *mod; struct mod_t *target_mod; struct mod_t *except_mod; struct mod_t *peer; struct mod_port_t *port; unsigned int addr; int tag; int set; int way; int state; int src_set; int src_way; int src_tag; enum mod_request_dir_t { mod_request_invalid=0, mod_request_up_down=1, mod_request_down_up=2 } request_dir; enum mod_message_type_t { message_none=0, message_clear_owner=1 } message; enum mod_reply_type_t { reply_none=0, reply_ack=1, reply_ack_data=2, reply_ack_data_sent_to_peer=3, reply_ack_error=4 } reply; int reply_size; int retain_owner; int pending; struct mod_stack_t *access_list_prev; struct mod_stack_t *access_list_next; struct mod_stack_t *write_access_list_prev; struct mod_stack_t *write_access_list_next; struct mod_stack_t *bucket_list_prev; struct mod_stack_t *bucket_list_next; int hit; int err; int shared; int read; int write; int nc_write; int blocking; int writeback; int eviction; int retry; int coalesced; int port_locked; struct net_msg_t *msg; int waiting_list_event; struct mod_stack_t *waiting_list_prev; struct mod_stack_t *waiting_list_next; int port_waiting_list_event; struct mod_stack_t *port_waiting_list_prev; struct mod_stack_t *port_waiting_list_next; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; struct mod_stack_t *master_stack; int dir_lock_event; struct mod_stack_t *dir_lock_next; struct mod_stack_t *ret_stack; int ret_event; } *lock_queue; } *dir_lock; unsigned char data[]; } *

user_defined_types: struct dir_t { char *name; int num_nodes; int xsize; struct dir_lock_t *dir_lock; unsigned char data[]; }

user_defined_types: struct dir_lock_t { int lock; long long stack_id; struct mod_stack_t *lock_queue; }

user_defined_types: struct mod_stack_t { long long id; enum mod_access_kind_t access_kind; int *witness_ptr; struct linked_list_t *event_queue; void *event_queue_item; struct mod_t *mod; struct mod_t *target_mod; struct mod_t *except_mod; struct mod_t *peer; struct mod_port_t *port; unsigned int addr; int tag; int set; int way; int state; int src_set; int src_way; int src_tag; enum mod_request_dir_t request_dir; enum mod_message_type_t message; enum mod_reply_type_t reply; int reply_size; int retain_owner; int pending; struct mod_stack_t *access_list_prev; struct mod_stack_t *access_list_next; struct mod_stack_t *write_access_list_prev; struct mod_stack_t *write_access_list_next; struct mod_stack_t *bucket_list_prev; struct mod_stack_t *bucket_list_next; int hit; int err; int shared; int read; int write; int nc_write; int blocking; int writeback; int eviction; int retry; int coalesced; int port_locked; struct net_msg_t *msg; int waiting_list_event; struct mod_stack_t *waiting_list_prev; struct mod_stack_t *waiting_list_next; int port_waiting_list_event; struct mod_stack_t *port_waiting_list_prev; struct mod_stack_t *port_waiting_list_next; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; struct mod_stack_t *master_stack; int dir_lock_event; struct mod_stack_t *dir_lock_next; struct mod_stack_t *ret_stack; int ret_event; }

user_defined_types: struct linked_list_t { int count; int error_code; struct linked_list_elem_t *head; int current_index; }

user_defined_types: struct mod_t { enum mod_kind_t kind; char *name; int block_size; int log_block_size; int latency; int dir_latency; int mshr_size; int level; enum mod_range_kind_t range_kind; union { struct { unsigned int low; unsigned int high; } bounds; struct { unsigned int mod; unsigned int div; unsigned int eq; } interleaved; } range; struct mod_port_t *ports; int num_ports; int num_locked_ports; struct mod_stack_t *port_waiting_list_head; struct mod_stack_t *port_waiting_list_tail; int port_waiting_list_count; int port_waiting_list_max; struct dir_t *dir; int dir_size; int dir_assoc; int dir_num_sets; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; struct cache_t *cache; struct linked_list_t *high_mod_list; struct linked_list_t *low_mod_list; int sub_block_size; int num_sub_blocks; struct net_t *high_net; struct net_t *low_net; struct net_node_t *high_net_node; struct net_node_t *low_net_node; struct mod_stack_t *access_list_head; struct mod_stack_t *access_list_tail; int access_list_count; int access_list_max; struct mod_stack_t *write_access_list_head; struct mod_stack_t *write_access_list_tail; int write_access_list_count; int write_access_list_max; int access_list_coalesced_count; struct { struct mod_stack_t *bucket_list_head; struct mod_stack_t *bucket_list_tail; int bucket_list_count; int bucket_list_max; } access_hash_table[17]; int color; long long accesses; long long hits; long long reads; long long effective_reads; long long effective_read_hits; long long writes; long long effective_writes; long long effective_write_hits; long long nc_writes; long long effective_nc_writes; long long effective_nc_write_hits; long long evictions; long long blocking_reads; long long non_blocking_reads; long long read_hits; long long blocking_writes; long long non_blocking_writes; long long write_hits; long long blocking_nc_writes; long long non_blocking_nc_writes; long long nc_write_hits; long long read_retries; long long write_retries; long long nc_write_retries; long long no_retry_accesses; long long no_retry_hits; long long no_retry_reads; long long no_retry_read_hits; long long no_retry_writes; long long no_retry_write_hits; long long no_retry_nc_writes; long long no_retry_nc_write_hits; }

user_defined_types: struct cache_t { char *name; unsigned int num_sets; unsigned int block_size; unsigned int assoc; enum cache_policy_t policy; struct cache_set_t *sets; unsigned int block_mask; int log_block_size; }

user_defined_types: struct net_t { char *name; long long msg_id_counter; struct list_t *node_list; int node_count; int end_node_count; struct list_t *link_list; struct net_routing_table_t *routing_table; struct net_msg_t *msg_table[32]; long long transfers; long long lat_acc; long long msg_size_acc; }

user_defined_types: struct cache_set_t { struct cache_block_t *way_head; struct cache_block_t *way_tail; struct cache_block_t *blocks; }

user_defined_types: struct net_routing_table_t { struct net_t *net; int dim; struct net_routing_table_entry_t *entries; int has_cycle; }

user_defined_types: struct cache_block_t { struct cache_block_t *way_next; struct cache_block_t *way_prev; int tag; int transient_tag; int way; enum cache_block_state_t state; }


decompiled_code:
__int64 __fastcall dir_entry_set_sharer(const char **a1, unsigned int a2, unsigned int a3, unsigned int a4, int a5)
{
int v5; // er15
__int64 v7; // rbx
__int64 v9; // r14
__int64 result; // rax
unsigned int v11; // ecx
__int64 v12; // rdx
int v13; // edi
int v14; // edx
__int64 v15; // [rsp-10h] [rbp-48h]

if ( a5 < 0 || (v5 = *((_DWORD *)a1 + 2), v7 = (unsigned int)a5, v5 <= a5) )
_assert_fail("IN_RANGE(node, 0, dir->num_nodes - 1)", "directory.c", 0x89u, "dir_entry_set_sharer");
v9 = a4;
result = dir_entry_get(a1, a2, a3, a4);
v11 = v7 & 7;
v12 = (int)v7 >> 3;
v13 = *(unsigned __int8 *)(result + v12 + 8);
if ( !_bittest(&v13, v11) )
{
*(_BYTE *)(result + v12 + 8) |= 1 << v11;
v14 = *(_DWORD *)(result + 4) + 1;
*(_DWORD *)(result + 4) = v14;
if ( v5 < v14 )
_assert_fail("dir_entry->num_sharers <= dir->num_nodes", "directory.c", 0x91u, "dir_entry_set_sharer");
if ( mem_trace_category )
{
_trace(mem_trace_category, 1LL, "mem.set_sharer dir=\"%s\" x=%d y=%d z=%d sharer=%d\n", *a1, a2, a3, v9, v7);
result = v15;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(const char **a1, unsigned int a2, unsigned int a3, unsigned int a4, int a5)
{
int v5; // er15
__int64 v7; // rbx
__int64 v9; // r14
__int64 result; // rax
unsigned int v11; // ecx
__int64 v12; // rdx
int v13; // edi
int v14; // edx
__int64 v15; // [rsp-10h] [rbp-48h]

if ( a5 < 0 || (v5 = *((_DWORD *)a1 + 2), v7 = (unsigned int)a5, v5 <= a5) )
_assert_fail("IN_RANGE(node, 0, dir->num_nodes - 1)", "directory.c", 0x89u, "dir_entry_set_sharer");
v9 = a4;
result = func1(a1, a2, a3, a4);
v11 = v7 & 7;
v12 = (int)v7 >> 3;
v13 = *(unsigned __int8 *)(result + v12 + 8);
if ( !_bittest(&v13, v11) )
{
*(_BYTE *)(result + v12 + 8) |= 1 << v11;
v14 = *(_DWORD *)(result + 4) + 1;
*(_DWORD *)(result + 4) = v14;
if ( v5 < v14 )
_assert_fail("dir_entry->num_sharers <= dir->num_nodes", "directory.c", 0x91u, "dir_entry_set_sharer");
if ( mem_trace_category )
{
_trace(mem_trace_category, 1LL, "mem.set_sharer dir=\"%s\" x=%d y=%d z=%d sharer=%d\n", *a1, a2, a3, v9, v7);
result = v15;
}
}
return result;
}

original_code:
void dir_entry_set_sharer(struct dir_t *dir, int x, int y, int z, int node)
{
 struct dir_entry_t *dir_entry;
 ((void) sizeof ((((node)>=(0)&&(node)<=(dir->num_nodes - 1))) ? 1 : 0), __extension__ ({ if (((node)>=(0)&&(node)<=(dir->num_nodes - 1))) ; else __assert_fail ("IN_RANGE(node, 0, dir->num_nodes - 1)", "directory.c", 137, __extension__ __PRETTY_FUNCTION__); }));
 dir_entry = dir_entry_get(dir, x, y, z);
 if (dir_entry->sharer[node / 8] & (1 << (node % 8)))
  return;
 dir_entry->sharer[node / 8] |= 1 << (node % 8);
 dir_entry->num_sharers++;
 ((void) sizeof ((dir_entry->num_sharers <= dir->num_nodes) ? 1 : 0), __extension__ ({ if (dir_entry->num_sharers <= dir->num_nodes) ; else __assert_fail ("dir_entry->num_sharers <= dir->num_nodes", "directory.c", 145, __extension__ __PRETTY_FUNCTION__); }));
 ((mem_trace_category) ? __trace((mem_trace_category), 1, "mem.set_sharer dir=\"%s\" x=%d y=%d z=%d sharer=%d\n", dir->name, x, y, z, node) : (void) 0);
}

variable_types: node int

user_defined_types: struct dir_entry_t { int owner; int num_sharers; unsigned char sharer[]; }

user_defined_types: enum mod_access_kind_t { mod_access_invalid=0, mod_access_load=1, mod_access_store=2, mod_access_nc_store=3 }

user_defined_types: enum mod_request_dir_t { mod_request_invalid=0, mod_request_up_down=1, mod_request_down_up=2 }

user_defined_types: enum mod_message_type_t { message_none=0, message_clear_owner=1 }

user_defined_types: enum mod_reply_type_t { reply_none=0, reply_ack=1, reply_ack_data=2, reply_ack_data_sent_to_peer=3, reply_ack_error=4 }

user_defined_types: enum mod_kind_t { mod_kind_invalid=0, mod_kind_cache=1, mod_kind_main_memory=2, mod_kind_local_memory=3 }

user_defined_types: enum mod_range_kind_t { mod_range_invalid=0, mod_range_bounds=1, mod_range_interleaved=2 }

user_defined_types: struct linked_list_elem_t { struct linked_list_elem_t *prev; struct linked_list_elem_t *next; void *data; }

user_defined_types: struct mod_port_t { int locked; long long lock_when; struct mod_stack_t *stack; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; }

user_defined_types: struct net_routing_table_entry_t { int cost; struct net_node_t *next_node; struct net_buffer_t *output_buffer; }

user_defined_types: struct net_node_t { struct net_t *net; enum net_node_kind_t kind; int index; char *name; void *user_data; int bandwidth; long long bus_busy; int input_buffer_size; int output_buffer_size; struct list_t *input_buffer_list; struct list_t *output_buffer_list; long long bytes_received; long long msgs_received; long long bytes_sent; long long msgs_sent; }

user_defined_types: struct net_buffer_t { struct net_t *net; struct net_node_t *node; char *name; int index; int size; int count; long long read_busy; long long write_busy; struct net_link_t *link; struct list_t *msg_list; long long sched_when; struct net_buffer_t *sched_buffer; struct linked_list_t *wakeup_list; int occupancy_bytes_value; int occupancy_msgs_value; long long occupancy_measured_cycle; long long occupancy_bytes_acc; long long occupancy_msgs_acc; }


decompiled_code:
__int64 __fastcall dir_entry_clear_sharer(const char **a1, unsigned int a2, unsigned int a3, unsigned int a4, unsigned int a5)
{
__int64 v6; // r13
__int64 v9; // rbx
__int64 result; // rax
unsigned int v11; // ecx
__int64 v12; // rsi
int v13; // edx
int v14; // edx
__int64 v15; // rdi
__int64 v16; // [rsp-10h] [rbp-38h]

v6 = a4;
v9 = a5;
result = dir_entry_get(a1, a2, a3, a4);
if ( (int)v9 < 0 || *((_DWORD *)a1 + 2) <= (int)v9 )
_assert_fail("IN_RANGE(node, 0, dir->num_nodes - 1)", "directory.c", 0x9Fu, "dir_entry_clear_sharer");
v11 = v9 & 7;
v12 = (int)v9 >> 3;
v13 = *(unsigned __int8 *)(result + v12 + 8);
if ( _bittest(&v13, v11) )
{
*(_BYTE *)(result + v12 + 8) &= ~(unsigned __int8)(1 << v11);
v14 = *(_DWORD *)(result + 4);
if ( v14 <= 0 )
_assert_fail("dir_entry->num_sharers > 0", "directory.c", 0xA5u, "dir_entry_clear_sharer");
v15 = mem_trace_category;
*(_DWORD *)(result + 4) = v14 - 1;
if ( (_DWORD)v15 )
{
_trace(v15, 1LL, "mem.clear_sharer dir=\"%s\" x=%d y=%d z=%d sharer=%d\n", *a1, a2, a3, v6, v9);
result = v16;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(const char **a1, unsigned int a2, unsigned int a3, unsigned int a4, unsigned int a5)
{
__int64 v6; // r13
__int64 v9; // rbx
__int64 result; // rax
unsigned int v11; // ecx
__int64 v12; // rsi
int v13; // edx
int v14; // edx
__int64 v15; // rdi
__int64 v16; // [rsp-10h] [rbp-38h]

v6 = a4;
v9 = a5;
result = func1(a1, a2, a3, a4);
if ( (int)v9 < 0 || *((_DWORD *)a1 + 2) <= (int)v9 )
_assert_fail("IN_RANGE(node, 0, dir->num_nodes - 1)", "directory.c", 0x9Fu, "dir_entry_clear_sharer");
v11 = v9 & 7;
v12 = (int)v9 >> 3;
v13 = *(unsigned __int8 *)(result + v12 + 8);
if ( _bittest(&v13, v11) )
{
*(_BYTE *)(result + v12 + 8) &= ~(unsigned __int8)(1 << v11);
v14 = *(_DWORD *)(result + 4);
if ( v14 <= 0 )
_assert_fail("dir_entry->num_sharers > 0", "directory.c", 0xA5u, "dir_entry_clear_sharer");
v15 = mem_trace_category;
*(_DWORD *)(result + 4) = v14 - 1;
if ( (_DWORD)v15 )
{
_trace(v15, 1LL, "mem.clear_sharer dir=\"%s\" x=%d y=%d z=%d sharer=%d\n", *a1, a2, a3, v6, v9);
result = v16;
}
}
return result;
}

original_code:
void dir_entry_clear_sharer(struct dir_t *dir, int x, int y, int z, int node)
{
 struct dir_entry_t *dir_entry;
 dir_entry = dir_entry_get(dir, x, y, z);
 ((void) sizeof ((((node)>=(0)&&(node)<=(dir->num_nodes - 1))) ? 1 : 0), __extension__ ({ if (((node)>=(0)&&(node)<=(dir->num_nodes - 1))) ; else __assert_fail ("IN_RANGE(node, 0, dir->num_nodes - 1)", "directory.c", 159, __extension__ __PRETTY_FUNCTION__); }));
 if (!(dir_entry->sharer[node / 8] & (1 << (node % 8))))
  return;
 dir_entry->sharer[node / 8] &= ~(1 << (node % 8));
 ((void) sizeof ((dir_entry->num_sharers > 0) ? 1 : 0), __extension__ ({ if (dir_entry->num_sharers > 0) ; else __assert_fail ("dir_entry->num_sharers > 0", "directory.c", 165, __extension__ __PRETTY_FUNCTION__); }));
 dir_entry->num_sharers--;
 ((mem_trace_category) ? __trace((mem_trace_category), 1, "mem.clear_sharer dir=\"%s\" x=%d y=%d z=%d sharer=%d\n", dir->name, x, y, z, node) : (void) 0);
}

user_defined_types: struct dir_t { char *name; int num_nodes; int xsize; struct dir_lock_t *dir_lock; unsigned char data[]; }

user_defined_types: struct dir_lock_t { int lock; long long stack_id; struct mod_stack_t *lock_queue; }

user_defined_types: struct mod_stack_t { long long id; enum mod_access_kind_t access_kind; int *witness_ptr; struct linked_list_t *event_queue; void *event_queue_item; struct mod_t *mod; struct mod_t *target_mod; struct mod_t *except_mod; struct mod_t *peer; struct mod_port_t *port; unsigned int addr; int tag; int set; int way; int state; int src_set; int src_way; int src_tag; enum mod_request_dir_t request_dir; enum mod_message_type_t message; enum mod_reply_type_t reply; int reply_size; int retain_owner; int pending; struct mod_stack_t *access_list_prev; struct mod_stack_t *access_list_next; struct mod_stack_t *write_access_list_prev; struct mod_stack_t *write_access_list_next; struct mod_stack_t *bucket_list_prev; struct mod_stack_t *bucket_list_next; int hit; int err; int shared; int read; int write; int nc_write; int blocking; int writeback; int eviction; int retry; int coalesced; int port_locked; struct net_msg_t *msg; int waiting_list_event; struct mod_stack_t *waiting_list_prev; struct mod_stack_t *waiting_list_next; int port_waiting_list_event; struct mod_stack_t *port_waiting_list_prev; struct mod_stack_t *port_waiting_list_next; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; struct mod_stack_t *master_stack; int dir_lock_event; struct mod_stack_t *dir_lock_next; struct mod_stack_t *ret_stack; int ret_event; }

user_defined_types: struct linked_list_t { int count; int error_code; struct linked_list_elem_t *head; int current_index; }

user_defined_types: struct mod_t { enum mod_kind_t kind; char *name; int block_size; int log_block_size; int latency; int dir_latency; int mshr_size; int level; enum mod_range_kind_t range_kind; union { struct { unsigned int low; unsigned int high; } bounds; struct { unsigned int mod; unsigned int div; unsigned int eq; } interleaved; } range; struct mod_port_t *ports; int num_ports; int num_locked_ports; struct mod_stack_t *port_waiting_list_head; struct mod_stack_t *port_waiting_list_tail; int port_waiting_list_count; int port_waiting_list_max; struct dir_t *dir; int dir_size; int dir_assoc; int dir_num_sets; struct mod_stack_t *waiting_list_head; struct mod_stack_t *waiting_list_tail; int waiting_list_count; int waiting_list_max; struct cache_t *cache; struct linked_list_t *high_mod_list; struct linked_list_t *low_mod_list; int sub_block_size; int num_sub_blocks; struct net_t *high_net; struct net_t *low_net; struct net_node_t *high_net_node; struct net_node_t *low_net_node; struct mod_stack_t *access_list_head; struct mod_stack_t *access_list_tail; int access_list_count; int access_list_max; struct mod_stack_t *write_access_list_head; struct mod_stack_t *write_access_list_tail; int write_access_list_count; int write_access_list_max; int access_list_coalesced_count; struct { struct mod_stack_t *bucket_list_head; struct mod_stack_t *bucket_list_tail; int bucket_list_count; int bucket_list_max; } access_hash_table[17]; int color; long long accesses; long long hits; long long reads; long long effective_reads; long long effective_read_hits; long long writes; long long effective_writes; long long effective_write_hits; long long nc_writes; long long effective_nc_writes; long long effective_nc_write_hits; long long evictions; long long blocking_reads; long long non_blocking_reads; long long read_hits; long long blocking_writes; long long non_blocking_writes; long long write_hits; long long blocking_nc_writes; long long non_blocking_nc_writes; long long nc_write_hits; long long read_retries; long long write_retries; long long nc_write_retries; long long no_retry_accesses; long long no_retry_hits; long long no_retry_reads; long long no_retry_read_hits; long long no_retry_writes; long long no_retry_write_hits; long long no_retry_nc_writes; long long no_retry_nc_write_hits; }

user_defined_types: struct cache_t { char *name; unsigned int num_sets; unsigned int block_size; unsigned int assoc; enum cache_policy_t policy; struct cache_set_t *sets; unsigned int block_mask; int log_block_size; }

user_defined_types: enum cache_policy_t { cache_policy_invalid=0, cache_policy_lru=1, cache_policy_fifo=2, cache_policy_random=3 }

user_defined_types: struct list_t { int count; int error_code; int size; int head; int tail; void **elem; }

user_defined_types: struct net_msg_t { struct net_t *net; long long id; int size; long long send_cycle; long long busy; struct net_node_t *src_node; struct net_node_t *dst_node; void *data; struct net_node_t *node; struct net_buffer_t *buffer; struct net_buffer_t *src_buffer; struct net_buffer_t *dst_buffer; struct net_msg_t *bucket_next; }

user_defined_types: enum cache_block_state_t { cache_block_invalid=0, cache_block_noncoherent=1, cache_block_modified=2, cache_block_owned=3, cache_block_exclusive=4, cache_block_shared=5 }

user_defined_types: enum net_node_kind_t { net_node_invalid=0, net_node_end=1, net_node_switch=2, net_node_bus=3 }

user_defined_types: struct net_link_t { struct net_t *net; char *name; struct net_node_t *src_node; struct net_node_t *dst_node; struct net_buffer_t *dst_buffer; struct net_buffer_t *src_buffer; int bandwidth; long long busy; int virtual_channel; long long sched_when; struct net_buffer_t *sched_buffer; long long busy_cycles; long long transferred_bytes; long long transferred_msgs; }