main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

buffer = (__int64)malloc(0x50uLL);
counter = 0;
in = 0;
out = 0;
pthread_create(newthread, 0LL, producer, 0LL);
consumer();
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

buffer = (__int64)malloc(0x50uLL);
counter = 0;
in = 0;
out = 0;
pthread_create(newthread, 0LL, producer, 0LL);
func8();
return 0;
}

original_code:
int main() {
 pthread_t child;
 buffer = malloc(sizeof(int) * (20));
 counter = 0;
 in = 0;
 out = 0;
 pthread_create(&child, ((void *)0), producer, ((void *)0));
 consumer();
 return 0;
}

canonical_original_code:
int main() {
 unsigned long child;
 buffer = malloc(sizeof(int) * (20));
 counter = 0;
 in = 0;
 out = 0;
 pthread_create(&child, ((void *)0), producer, ((void *)0));
 consumer();
 return 0;
}

variable_types:
child
unsigned long


decompiled_code:
int __fastcall mutex_lock(pthread_mutex_t *a1)
{
int result; // eax

result = pthread_mutex_lock(a1);
if ( result )
{
fwrite("Failed to lock mutex\n", 1uLL, 0x15uLL, _bss_start);
exit(-1);
}
return result;
}

canonical_decompiled_code:
int __fastcall func7(pthread_mutex_t *a1)
{
int result; // eax

result = pthread_mutex_lock(a1);
if ( result )
{
fwrite("Failed to lock mutex\n", 1uLL, 0x15uLL, _bss_start);
exit(-1);
}
return result;
}

original_code:
void mutex_lock(pthread_mutex_t *lock) {
  int ret = pthread_mutex_lock(lock);
  if(ret != 0) {
    fprintf(stderr, "Failed to lock mutex\n");
    exit(-1);
  }
}

canonical_original_code:
void mutex_lock(union pthread_mutex_t *lock) {
  int ret = pthread_mutex_lock(lock);
  if(ret != 0) {
    fprintf(stderr, "Failed to lock mutex\n");
    exit(-1);
  }
}

variable_types: union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *

variable_types: ret int

return_type: void

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }


decompiled_code:
int __fastcall mutex_unlock(pthread_mutex_t *a1)
{
int result; // eax

result = pthread_mutex_unlock(a1);
if ( result )
{
fwrite("Failed to unlock mutex\n", 1uLL, 0x17uLL, _bss_start);
exit(-1);
}
return result;
}

canonical_decompiled_code:
int __fastcall func8(pthread_mutex_t *a1)
{
int result; // eax

result = pthread_mutex_unlock(a1);
if ( result )
{
fwrite("Failed to unlock mutex\n", 1uLL, 0x17uLL, _bss_start);
exit(-1);
}
return result;
}

original_code:
void mutex_unlock(pthread_mutex_t *lock) {
  int ret = pthread_mutex_unlock(lock);
  if(ret != 0) {
    fprintf(stderr, "Failed to unlock mutex\n");
    exit(-1);
  }
}

canonical_original_code:
void mutex_unlock(union pthread_mutex_t *lock) {
  int ret = pthread_mutex_unlock(lock);
  if(ret != 0) {
    fprintf(stderr, "Failed to unlock mutex\n");
    exit(-1);
  }
}

user_defined_types: struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; }


decompiled_code:
void *__fastcall inc_thread_func(void *a1)
{
int v1; // ebx

v1 = 1000000;
do
{
mutex_lock(&lock_var);
++*(_DWORD *)a1;
mutex_unlock(&lock_var);
--v1;
}
while ( v1 );
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func9(void *a1)
{
int v1; // ebx

v1 = 1000000;
do
{
func7(&lock_var);
++*(_DWORD *)a1;
func8(&lock_var);
--v1;
}
while ( v1 );
return 0LL;
}

original_code:
void *inc_thread_func(void *p) {
  int *num = (int *)p;
  int i, tid = 0;
  for(i = 0; i < (1000000); i++) {
    mutex_lock(&lock_var);
    (*num)++;
    mutex_unlock(&lock_var);
  }
  return ((void *)0);
}

canonical_original_code:
void *inc_thread_func(void *p) {
  int *num = (int *)p;
  int i; int tid = 0;
  for(i = 0; i < (1000000); i++) {
    mutex_lock(&lock_var);
    (*num)++;
    mutex_unlock(&lock_var);
  }
  return ((void *)0);
}

variable_types:
p
void *

variable_types:
num
int *

variable_types: i int

variable_types: tid int

return_type: void *


decompiled_code:
void *__fastcall dec_thread_func(void *a1)
{
int v1; // ebx

v1 = 1000000;
do
{
mutex_lock(&lock_var);
--*(_DWORD *)a1;
mutex_unlock(&lock_var);
--v1;
}
while ( v1 );
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func10(void *a1)
{
int v1; // ebx

v1 = 1000000;
do
{
func7(&lock_var);
--*(_DWORD *)a1;
func8(&lock_var);
--v1;
}
while ( v1 );
return 0LL;
}

original_code:
void *dec_thread_func(void *p) {
  int *num = (int *)p;
  int i, tid = 1;
  for(i = 0; i < (1000000); i++) {
    mutex_lock(&lock_var);
    (*num)--;
    mutex_unlock(&lock_var);
  }
  return ((void *)0);
}

canonical_original_code:
void *dec_thread_func(void *p) {
  int *num = (int *)p;
  int i; int tid = 1;
  for(i = 0; i < (1000000); i++) {
    mutex_lock(&lock_var);
    (*num)--;
    mutex_unlock(&lock_var);
  }
  return ((void *)0);
}


canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er12
unsigned int arg; // [rsp+Ch] [rbp-1Ch] BYREF
pthread_t newthread; // [rsp+10h] [rbp-18h] BYREF
pthread_t th[2]; // [rsp+18h] [rbp-10h] BYREF

arg = 0;
if ( pthread_create(&newthread, 0LL, inc_thread_func, &arg) )
{
v3 = -1;
fwrite("Unable to create increment thread\n", 1uLL, 0x22uLL, _bss_start);
}
else if ( pthread_create(th, 0LL, dec_thread_func, &arg) )
{
v3 = -1;
fwrite("Unable to create decrement thread\n", 1uLL, 0x22uLL, _bss_start);
}
else if ( pthread_join(newthread, 0LL) )
{
v3 = -1;
fwrite("Unable to join increment thread\n", 1uLL, 0x20uLL, _bss_start);
}
else
{
v3 = pthread_join(th[0], 0LL);
if ( v3 )
{
v3 = -1;
fwrite("Unable to join decrement thread\n", 1uLL, 0x20uLL, _bss_start);
}
else
{
printf("Final result: %d\n", arg);
}
}
return v3;
}

original_code:
int main(int argc, char *argv[]) {
  pthread_t ith, dth;
  int ret, num = 0;
  ret = pthread_create(&ith, ((void *)0), inc_thread_func, &num);
  if(ret != 0) {
    fprintf(stderr, "Unable to create increment thread\n");
    return -1;
  }
  ret = pthread_create(&dth, ((void *)0), dec_thread_func, &num);
  if(ret != 0) {
    fprintf(stderr, "Unable to create decrement thread\n");
    return -1;
  }
  ret = pthread_join(ith, ((void *)0));
  if(ret != 0) {
    fprintf(stderr, "Unable to join increment thread\n");
    return -1;
  }
  ret = pthread_join(dth, ((void *)0));
  if(ret != 0) {
    fprintf(stderr, "Unable to join decrement thread\n");
    return -1;
  }
  printf("Final result: %d\n", num);
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
  unsigned long ith; unsigned long dth;
  int ret; int num = 0;
  ret = pthread_create(&ith, ((void *)0), inc_thread_func, &num);
  if(ret != 0) {
    fprintf(stderr, "Unable to create increment thread\n");
    return -1;
  }
  ret = pthread_create(&dth, ((void *)0), dec_thread_func, &num);
  if(ret != 0) {
    fprintf(stderr, "Unable to create decrement thread\n");
    return -1;
  }
  ret = pthread_join(ith, ((void *)0));
  if(ret != 0) {
    fprintf(stderr, "Unable to join increment thread\n");
    return -1;
  }
  ret = pthread_join(dth, ((void *)0));
  if(ret != 0) {
    fprintf(stderr, "Unable to join decrement thread\n");
    return -1;
  }
  printf("Final result: %d\n", num);
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
ith
unsigned long

variable_types:
dth
unsigned long

variable_types: num int

return_type: int


decompiled_code:
void *__fastcall add_thread_func(void *a1)
{
int v1; // ebx

v1 = 0xFFFF;
do
{
pthread_mutex_lock((pthread_mutex_t *)a1);
++count;
pthread_mutex_unlock((pthread_mutex_t *)a1);
--v1;
}
while ( v1 );
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func7(void *a1)
{
int v1; // ebx

v1 = 0xFFFF;
do
{
pthread_mutex_lock((pthread_mutex_t *)a1);
++count;
pthread_mutex_unlock((pthread_mutex_t *)a1);
--v1;
}
while ( v1 );
return 0LL;
}

original_code:
void *add_thread_func(void *p) {
 pthread_mutex_t *pmutex = (pthread_mutex_t *)p;
 int i;
 for(i = 0; i < (0xFFFF); i++) {
  pthread_mutex_lock(pmutex);
  count++;
  pthread_mutex_unlock(pmutex);
 }
 return ((void *)0);
}

canonical_original_code:
void *add_thread_func(void *p) {
 union pthread_mutex_t *pmutex = (pthread_mutex_t *)p;
 int i;
 for(i = 0; i < (0xFFFF); i++) {
  pthread_mutex_lock(pmutex);
  count++;
  pthread_mutex_unlock(pmutex);
 }
 return ((void *)0);
}


decompiled_code:
void *__fastcall sub_thread_func(void *a1)
{
int v1; // ebx

v1 = 0xFFFF;
do
{
pthread_mutex_lock((pthread_mutex_t *)a1);
--count;
pthread_mutex_unlock((pthread_mutex_t *)a1);
--v1;
}
while ( v1 );
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func8(void *a1)
{
int v1; // ebx

v1 = 0xFFFF;
do
{
pthread_mutex_lock((pthread_mutex_t *)a1);
--count;
pthread_mutex_unlock((pthread_mutex_t *)a1);
--v1;
}
while ( v1 );
return 0LL;
}

original_code:
void *sub_thread_func(void *p) {
 pthread_mutex_t *pmutex = (pthread_mutex_t *)p;
 int i;
 for(i = 0; i < (0xFFFF); i++) {
  pthread_mutex_lock(pmutex);
  count--;
  pthread_mutex_unlock(pmutex);
 }
 return ((void *)0);
}

canonical_original_code:
void *sub_thread_func(void *p) {
 union pthread_mutex_t *pmutex = (pthread_mutex_t *)p;
 int i;
 for(i = 0; i < (0xFFFF); i++) {
  pthread_mutex_lock(pmutex);
  count--;
  pthread_mutex_unlock(pmutex);
 }
 return ((void *)0);
}


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
pthread_t *v3; // rbp
pthread_t *v4; // rbx
pthread_t *v5; // rdi
__int64 v6; // rbx
pthread_t v7; // rdi
__int128 v9[2]; // [rsp+0h] [rbp-198h] BYREF
__int64 v10; // [rsp+20h] [rbp-178h]
pthread_t newthread[20]; // [rsp+30h] [rbp-168h] BYREF
pthread_t v12[25]; // [rsp+D0h] [rbp-C8h] BYREF

v3 = v12;
v9[0] = 0LL;
v4 = newthread;
v10 = 0LL;
v9[1] = 0LL;
puts("Main thread started");
do
{
pthread_create(v4++, 0LL, add_thread_func, v9);
v5 = v3++;
pthread_create(v5, 0LL, sub_thread_func, v9);
}
while ( v4 != v12 );
v6 = 0LL;
puts("Main thread created child threads");
do
{
pthread_join(newthread[v6], 0LL);
v7 = v12[v6++];
pthread_join(v7, 0LL);
}
while ( v6 != 20 );
printf("Main thread count is %d\n", (unsigned int)count);
return 0;
}

original_code:
int main() {
 pthread_t add_threads[(20)];
 pthread_t sub_threads[(20)];
 int i;
 pthread_mutex_t count_mutex = { { 0, 0, 0, 0, 0, 0, 0, { 0, 0 } } };
 printf("Main thread started\n");
 for ( i = 0; i < (20); i++ ) {
  pthread_create(&add_threads[i], ((void *)0), add_thread_func, &count_mutex);
  pthread_create(&sub_threads[i], ((void *)0), sub_thread_func, &count_mutex);
 }
 printf("Main thread created child threads\n");
 for ( i = 0; i < (20); i++ ) {
  pthread_join(add_threads[i], ((void *)0));
  pthread_join(sub_threads[i], ((void *)0));
 }
 printf("Main thread count is %d\n", count);
 return 0;
}

canonical_original_code:
int main() {
 unsigned long add_threads[-1];
 unsigned long sub_threads[-1];
 int i;
 union pthread_mutex_t count_mutex = { { 0, 0, 0, 0, 0, 0, 0, { 0, 0 } } };
 printf("Main thread started\n");
 for ( i = 0; i < (20); i++ ) {
  pthread_create(&add_threads[i], ((void *)0), add_thread_func, &count_mutex);
  pthread_create(&sub_threads[i], ((void *)0), sub_thread_func, &count_mutex);
 }
 printf("Main thread created child threads\n");
 for ( i = 0; i < (20); i++ ) {
  pthread_join(add_threads[i], ((void *)0));
  pthread_join(sub_threads[i], ((void *)0));
 }
 printf("Main thread count is %d\n", count);
 return 0;
}

variable_types: union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; }


decompiled_code:
__int64 see_more()
{
int v0; // eax

printf("more?");
do
{
v0 = getchar();
if ( v0 == -1 || v0 == 113 )
return 0LL;
if ( v0 == 32 )
return 24LL;
}
while ( v0 != 10 );
return 1LL;
}

canonical_decompiled_code:
__int64 func7()
{
int v0; // eax

printf("more?");
do
{
v0 = getchar();
if ( v0 == -1 || v0 == 113 )
return 0LL;
if ( v0 == 32 )
return 24LL;
}
while ( v0 != 10 );
return 1LL;
}

original_code:
int see_more()
{
 int c;
 printf("more?");
 while((c = getchar()) != (-1))
 {
  if (c == 'q')
   return 0;
  if (c == ' ')
   return 24;
  if (c == '\n')
   return 1;
 }
 return 0;
}

variable_types: c int


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax

if ( argc <= 1 || (v3 = atoi(argv[1]), v3 <= 1) )
{
printf("Usage: %s <positive integer>\n", *argv);
exit(-1);
}
factor1((unsigned int)v3);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax

if ( argc <= 1 || (v3 = atoi(argv[1]), v3 <= 1) )
{
printf("Usage: %s <positive integer>\n", *argv);
exit(-1);
}
func7((unsigned int)v3);
return 0;
}

original_code:
int main(int argc, char *argv[]) {
 int n;
 if (argc < 2 || (n = atoi(argv[1])) < 2) {
  printf("Usage: %s <positive integer>\n", argv[0]);
  exit(-1);
 }
 factor1(n);
 return 0;
}

variable_types: n int


decompiled_code:
void __fastcall __noreturn pthread_ret_error(const char *a1)
{
fprintf(stderr, "%s\n", a1);
exit(-1);
}

canonical_decompiled_code:
void __fastcall __noreturn func8(const char *a1)
{
fprintf(stderr, "%s\n", a1);
exit(-1);
}

original_code:
void pthread_ret_error(const char *msg) {
  fprintf(stderr, "%s\n", msg);
  exit(-1);
}

canonical_original_code:
void pthread_ret_error(char *msg) {
  fprintf(stderr, "%s\n", msg);
  exit(-1);
}

variable_types:
msg
char *


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // r12
pthread_t newthread; // [rsp+8h] [rbp-20h] BYREF
pthread_t th; // [rsp+10h] [rbp-18h] BYREF
void *thread_return; // [rsp+18h] [rbp-10h] BYREF

v3 = (char *)malloc(0x90uLL);
sem_init((sem_t *)(v3 + 80), 0, 0);
sem_init((sem_t *)(v3 + 112), 0, 0x14u);
if ( pthread_create(&newthread, 0LL, producer_thread_func, v3) )
pthread_ret_error("Unable to create producer thread");
if ( pthread_create(&th, 0LL, consumer_thread_func, v3) )
pthread_ret_error("Unable to create consumer thread");
if ( pthread_join(newthread, 0LL) )
pthread_ret_error("Unable to join producer thread");
if ( pthread_join(th, &thread_return) )
pthread_ret_error("Unable to join consumer thread");
printf("Sum result: %d\n", *(unsigned int *)thread_return);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // r12
pthread_t newthread; // [rsp+8h] [rbp-20h] BYREF
pthread_t th; // [rsp+10h] [rbp-18h] BYREF
void *thread_return; // [rsp+18h] [rbp-10h] BYREF

v3 = (char *)malloc(0x90uLL);
sem_init((sem_t *)(v3 + 80), 0, 0);
sem_init((sem_t *)(v3 + 112), 0, 0x14u);
if ( pthread_create(&newthread, 0LL, producer_thread_func, v3) )
func8("Unable to create producer thread");
if ( pthread_create(&th, 0LL, consumer_thread_func, v3) )
func8("Unable to create consumer thread");
if ( pthread_join(newthread, 0LL) )
func8("Unable to join producer thread");
if ( pthread_join(th, &thread_return) )
func8("Unable to join consumer thread");
printf("Sum result: %d\n", *(unsigned int *)thread_return);
return 0;
}

original_code:
int main(int argc, char *argv[]) {
  pthread_t pth, cth;
  int sum, ret, i;
  void *result;
  struct pc_buff *pcb = malloc(sizeof(struct pc_buff));
  sem_init(&pcb->items, 0, 0);
  sem_init(&pcb->empty, 0, (20));
  ret = pthread_create(&pth, ((void *)0), producer_thread_func, pcb);
  if(ret != 0) pthread_ret_error("Unable to create producer thread");
  ret = pthread_create(&cth, ((void *)0), consumer_thread_func, pcb);
  if(ret != 0) pthread_ret_error("Unable to create consumer thread");
  ret = pthread_join(pth, ((void *)0));
  if(ret != 0) pthread_ret_error("Unable to join producer thread");
  sum = 0;
  ret = pthread_join(cth, &result);
  if(ret != 0) pthread_ret_error("Unable to join consumer thread");
  sum += *(int *)result;
  printf("Sum result: %d\n", sum);
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
  unsigned long pth; unsigned long cth;
  int sum; int ret; int i;
  void *result;
  struct pc_buff *pcb = malloc(sizeof(struct pc_buff));
  sem_init(&pcb->items, 0, 0);
  sem_init(&pcb->empty, 0, (20));
  ret = pthread_create(&pth, ((void *)0), producer_thread_func, pcb);
  if(ret != 0) pthread_ret_error("Unable to create producer thread");
  ret = pthread_create(&cth, ((void *)0), consumer_thread_func, pcb);
  if(ret != 0) pthread_ret_error("Unable to create consumer thread");
  ret = pthread_join(pth, ((void *)0));
  if(ret != 0) pthread_ret_error("Unable to join producer thread");
  sum = 0;
  ret = pthread_join(cth, &result);
  if(ret != 0) pthread_ret_error("Unable to join consumer thread");
  sum += *(int *)result;
  printf("Sum result: %d\n", sum);
  return 0;
}

variable_types:
pth
unsigned long

variable_types:
cth
unsigned long

variable_types: sum int

variable_types:
result
void *

variable_types: struct pc_buff { int buffer[-1]; union sem_t { char __size[32]; long __align; } items; } *

user_defined_types: struct pc_buff { int buffer[-1]; union sem_t items; }


decompiled_code:
void *__fastcall producer_thread_func(void *a1)
{
sem_t *v1; // r15
sem_t *v2; // r13
int v3; // ebp
__int64 v4; // rbx

v1 = (sem_t *)((char *)a1 + 112);
v2 = (sem_t *)((char *)a1 + 80);
v3 = 1000000;
LODWORD(v4) = 0;
do
{
sem_wait(v1);
*((_DWORD *)a1 + (int)v4) = 1;
v4 = ((int)v4 + 1) % 0x14u;
sem_post(v2);
--v3;
}
while ( v3 );
sem_wait(v1);
*((_DWORD *)a1 + v4) = -1;
sem_post(v2);
return 0LL;
}

original_code:
void *producer_thread_func(void *p) {
  struct pc_buff *pcb = (struct pc_buff *)p;
  int i, pi = 0;
  for(i = 0; i < (1000000); i++) {
    sem_wait(&pcb->empty);
    pcb->buffer[pi] = 1;
    pi = (pi + 1) % (20);
    sem_post(&pcb->items);
  }
  sem_wait(&pcb->empty);
  pcb->buffer[pi] = (-1);
  pi = (pi + 1) % (20);
  sem_post(&pcb->items);
  return ((void *)0);
}

canonical_original_code:
void *producer_thread_func(void *p) {
  struct pc_buff *pcb = (struct pc_buff *)p;
  int i; int pi = 0;
  for(i = 0; i < (1000000); i++) {
    sem_wait(&pcb->empty);
    pcb->buffer[pi] = 1;
    pi = (pi + 1) % (20);
    sem_post(&pcb->items);
  }
  sem_wait(&pcb->empty);
  pcb->buffer[pi] = (-1);
  pi = (pi + 1) % (20);
  sem_post(&pcb->items);
  return ((void *)0);
}

variable_types:
p
void *

variable_types: pi int

user_defined_types: union sem_t { char __size[32]; long __align; }


decompiled_code:
void *__fastcall funny_add(void *a1)
{
int v1; // ebx
int v2; // ebp

v1 = globalValue + 1;
v2 = globalValue + 11;
do
{
sleep(1u);
globalValue = v1++;
}
while ( v1 != v2 );
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func7(void *a1)
{
int v1; // ebx
int v2; // ebp

v1 = globalValue + 1;
v2 = globalValue + 11;
do
{
sleep(1u);
globalValue = v1++;
}
while ( v1 != v2 );
return 0LL;
}

original_code:
void *funny_add(void * m)
{
 int j;
 for ( j = 0; j < 10; j++ )
 {
  int temp = globalValue + 1;
  sleep(1);
  globalValue = temp;
 }
 return ((void *)0);
}

canonical_original_code:
void *funny_add(void *m)
{
 int j;
 for ( j = 0; j < 10; j++ )
 {
  int temp = globalValue + 1;
  sleep(1);
  globalValue = temp;
 }
 return ((void *)0);
}

variable_types:
m
void *

variable_types: j int

variable_types: temp int


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

v3 = 10;
pthread_create(newthread, 0LL, funny_add, 0LL);
do
{
++globalValue;
sleep(1u);
--v3;
}
while ( v3 );
pthread_join(newthread[0], 0LL);
printf("\nDone ...global value = %d\n", (unsigned int)globalValue);
return 0;
}

original_code:
int main()
{
 int i;
 pthread_t mythread;
 pthread_create(&mythread, ((void *)0), funny_add, ((void *)0));
 for ( i = 0; i < 10; i++ )
 {
  globalValue++;
  sleep(1);
 }
 pthread_join(mythread, ((void *)0));
 printf("\nDone ...global value = %d\n", globalValue);
 return 0;
}

canonical_original_code:
int main()
{
 int i;
 unsigned long mythread;
 pthread_create(&mythread, ((void *)0), funny_add, ((void *)0));
 for ( i = 0; i < 10; i++ )
 {
  globalValue++;
  sleep(1);
 }
 pthread_join(mythread, ((void *)0));
 printf("\nDone ...global value = %d\n", globalValue);
 return 0;
}

variable_types: i int

variable_types:
mythread
unsigned long


decompiled_code:
void *__fastcall char_print(void *a1)
{
int v1; // ebx

if ( *((int *)a1 + 1) <= 0 )
return 0LL;
v1 = 0;
do
{
++v1;
fputc(*(char *)a1, _bss_start);
}
while ( *((_DWORD *)a1 + 1) > v1 );
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func7(void *a1)
{
int v1; // ebx

if ( *((int *)a1 + 1) <= 0 )
return 0LL;
v1 = 0;
do
{
++v1;
fputc(*(char *)a1, _bss_start);
}
while ( *((_DWORD *)a1 + 1) > v1 );
return 0LL;
}

original_code:
void *char_print(void *params) {
  struct char_print_params *p;
  p = (struct char_print_params *) params;
  int i;
  for (i = 0; i < p->number_to_print; i++)
    fputc(p->print_char, stderr);
  return ((void *)0);
}

variable_types:
params
void *

variable_types: struct char_print_params { char print_char; int number_to_print; } *


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
pthread_t th; // [rsp+0h] [rbp-28h] BYREF
pthread_t newthread; // [rsp+8h] [rbp-20h] BYREF
char arg[4]; // [rsp+10h] [rbp-18h] BYREF
int v7; // [rsp+14h] [rbp-14h]
char v8[4]; // [rsp+18h] [rbp-10h] BYREF
int v9; // [rsp+1Ch] [rbp-Ch]

arg[0] = 120;
v7 = 3000;
pthread_create(&th, 0LL, char_print, arg);
v8[0] = 121;
v9 = 5000;
pthread_create(&newthread, 0LL, char_print, v8);
pthread_join(th, 0LL);
pthread_join(newthread, 0LL);
return 0;
}

original_code:
int main(int argc, char *argv[]) {
  pthread_t thread1_handle;
  pthread_t thread2_handle;
  struct char_print_params thread1_args;
  struct char_print_params thread2_args;
  thread1_args.print_char = 'x';
  thread1_args.number_to_print = 3000;
  pthread_create(&thread1_handle, ((void *)0), char_print, &thread1_args);
  thread2_args.print_char = 'y';
  thread2_args.number_to_print = 5000;
  pthread_create(&thread2_handle, ((void *)0), char_print, &thread2_args);
  pthread_join(thread1_handle, ((void *)0));
  pthread_join(thread2_handle, ((void *)0));
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
  unsigned long thread1_handle;
  unsigned long thread2_handle;
  struct char_print_params thread1_args;
  struct char_print_params thread2_args;
  thread1_args.print_char = 'x';
  thread1_args.number_to_print = 3000;
  pthread_create(&thread1_handle, ((void *)0), char_print, &thread1_args);
  thread2_args.print_char = 'y';
  thread2_args.number_to_print = 5000;
  pthread_create(&thread2_handle, ((void *)0), char_print, &thread2_args);
  pthread_join(thread1_handle, ((void *)0));
  pthread_join(thread2_handle, ((void *)0));
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: struct char_print_params { char print_char; int number_to_print; }


f

decompiled_code:
void f()
{
printf("\nOUCH");
}

canonical_decompiled_code:
void func7()
{
printf("\nOUCH");
}

original_code:
void f ( int signum )
{
    printf("\nOUCH");
}

canonical_original_code:
void f(int signum)
{
    printf("\nOUCH");
}

variable_types: signum int


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx

v3 = 10;
signal(2, f);
do
{
puts("hello");
sleep(1u);
--v3;
}
while ( v3 );
return 0;
}

original_code:
int main ( )
{
    int i;
    signal ( 2, f);
    for (i = 0; i < 10; i++)
    {
        printf("hello\n");
        sleep(1);
    }
    return 0;
}

canonical_original_code:
int main()
{
    int i;
    signal ( 2, f);
    for (i = 0; i < 10; i++)
    {
        printf("hello\n");
        sleep(1);
    }
    return 0;
}


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er12
unsigned int arg; // [rsp+Ch] [rbp-1Ch] BYREF
pthread_t newthread; // [rsp+10h] [rbp-18h] BYREF
void *thread_return; // [rsp+18h] [rbp-10h] BYREF

arg = 10;
if ( pthread_create(&newthread, 0LL, child_thread_func, &arg) )
{
v3 = -1;
fwrite("Error creating child thread\n", 1uLL, 0x1CuLL, _bss_start);
}
else
{
v3 = pthread_join(newthread, &thread_return);
if ( v3 )
{
v3 = -1;
fwrite("Error joining child thread\n", 1uLL, 0x1BuLL, _bss_start);
}
else
{
printf("Result of %d squared is %d\n", arg, *(unsigned int *)thread_return);
free(thread_return);
}
}
return v3;
}

original_code:
int main(int argc, char *argv[]) {
  pthread_t thread_handle;
  void *result;
  int ret;
  int number = 10;
  ret = pthread_create(&thread_handle, ((void *)0), child_thread_func, &number);
  if(ret != 0) {
    fprintf(stderr, "Error creating child thread\n");
    return -1;
  }
  ret = pthread_join(thread_handle, &result);
  if(ret != 0) {
    fprintf(stderr, "Error joining child thread\n");
    return -1;
  }
  printf("Result of %d squared is %d\n", number, *(int *)result);
  free(result);
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
  unsigned long thread_handle;
  void *result;
  int ret;
  int number = 10;
  ret = pthread_create(&thread_handle, ((void *)0), child_thread_func, &number);
  if(ret != 0) {
    fprintf(stderr, "Error creating child thread\n");
    return -1;
  }
  ret = pthread_join(thread_handle, &result);
  if(ret != 0) {
    fprintf(stderr, "Error joining child thread\n");
    return -1;
  }
  printf("Result of %d squared is %d\n", number, *(int *)result);
  free(result);
  return 0;
}

variable_types: ret int

variable_types: number int


repo: jjonir/alchem

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbp
unsigned __int64 v4; // rax
unsigned int v5; // edx
__int64 v6; // r12
unsigned __int64 v7; // rax
unsigned int v8; // edx
unsigned __int64 v9; // rax
unsigned int v10; // edx
__int64 v11; // r12
unsigned __int64 v12; // rax
unsigned int v13; // edx
unsigned __int64 v14; // rax
unsigned int v15; // edx
unsigned __int64 v16; // rax
unsigned int v17; // edx
__int64 v18; // r8
unsigned __int64 v19; // rax
unsigned int v20; // edx
unsigned __int64 v21; // rax
unsigned int v22; // edx
__int64 v23; // r8

init_io(argc, argv, envp);
v3 = new_workspace(5LL, 5LL, 5LL);
v4 = position_constprop_0(1u, 0);
v6 = new_manipulator(0LL, 2LL, v4, v5);
inst_add(v6, 9LL);
inst_add(v6, 2LL);
inst_add(v6, 8LL);
inst_add(v6, 5LL);
v7 = position_constprop_0(1u, 0);
add_manipulator(v3, v6, v7, v8);
v9 = position_constprop_0(0, 2u);
v11 = new_manipulator(0LL, 2LL, v9, v10);
inst_add(v11, 8LL);
inst_add(v11, 7LL);
inst_add(v11, 9LL);
inst_add(v11, 6LL);
v12 = position_constprop_0(0, 2u);
add_manipulator(v3, v11, v12, v13);
v14 = position_constprop_0(3u, 0);
new_glyph(2LL, 5LL, v14, v15);
v16 = position_constprop_0(3u, 0);
add_glyph(v3, v18, v16, v17);
v19 = position_constprop_0(1u, 2u);
new_glyph(0LL, 0LL, v19, v20);
v21 = position_constprop_0(1u, 2u);
add_glyph(v3, v23, v21, v22);
edit_workspace_loop(v3);
end_io();
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbp
unsigned __int64 v4; // rax
unsigned int v5; // edx
__int64 v6; // r12
unsigned __int64 v7; // rax
unsigned int v8; // edx
unsigned __int64 v9; // rax
unsigned int v10; // edx
__int64 v11; // r12
unsigned __int64 v12; // rax
unsigned int v13; // edx
unsigned __int64 v14; // rax
unsigned int v15; // edx
unsigned __int64 v16; // rax
unsigned int v17; // edx
__int64 v18; // r8
unsigned __int64 v19; // rax
unsigned int v20; // edx
unsigned __int64 v21; // rax
unsigned int v22; // edx
__int64 v23; // r8

init_io(argc, argv, envp);
v3 = new_workspace(5LL, 5LL, 5LL);
v4 = func0(1u, 0);
v6 = new_manipulator(0LL, 2LL, v4, v5);
inst_add(v6, 9LL);
inst_add(v6, 2LL);
inst_add(v6, 8LL);
inst_add(v6, 5LL);
v7 = func0(1u, 0);
add_manipulator(v3, v6, v7, v8);
v9 = func0(0, 2u);
v11 = new_manipulator(0LL, 2LL, v9, v10);
inst_add(v11, 8LL);
inst_add(v11, 7LL);
inst_add(v11, 9LL);
inst_add(v11, 6LL);
v12 = func0(0, 2u);
add_manipulator(v3, v11, v12, v13);
v14 = func0(3u, 0);
new_glyph(2LL, 5LL, v14, v15);
v16 = func0(3u, 0);
add_glyph(v3, v18, v16, v17);
v19 = func0(1u, 2u);
new_glyph(0LL, 0LL, v19, v20);
v21 = func0(1u, 2u);
add_glyph(v3, v23, v21, v22);
edit_workspace_loop(v3);
end_io();
return 0;
}

original_code:
int main() {
 struct workspace *w;
 struct manipulator *m;
 struct glyph *g;
 init_io();
 w = new_workspace(5, 5, 5);
 m = new_manipulator(PX, 2, position(1, 0, 0));
 inst_add(m, CLOSE_HEAD);
 inst_add(m, ROT_PZ);
 inst_add(m, OPEN_HEAD);
 inst_add(m, ROT_NZ);
 add_manipulator(w, m, position(1, 0, 0));
 m = new_manipulator(PX, 2, position(0, 2, 0));
 inst_add(m, OPEN_HEAD);
 inst_add(m, RETRACT);
 inst_add(m, CLOSE_HEAD);
 inst_add(m, EXTEND);
 add_manipulator(w, m, position(0, 2, 0));
 g = new_glyph(SOURCE, (int)ATOM_AL, position(3, 0, 0));
 add_glyph(w, g, position(3, 0, 0));
 g = new_glyph(BOND, (int)PX, position(1, 2, 0));
 add_glyph(w, g, position(1, 2, 0));
 edit_workspace_loop(w);
 end_io();
 return 0;
}

variable_types: struct workspace { struct position { int x; } size; struct item { enum item_type { ITEM_NONE=0, ITEM_ATOM=1, ITEM_MANIPULATOR=2, ITEM_GLYPH=3 } type; void *item; } *items; struct position pos; } *

variable_types: struct manipulator { struct position { int x; } pos; enum orientation { PX=0, NX=1, PY=2, NY=3, PZ=4, NZ=5, ORIENTATION_NUM=6 } orient; int length; enum head_state { HEAD_OPEN=0, HEAD_CLOSED=1 } head_state; int grabbed; struct list_head { struct list_head *next; } inst_list; struct inst { struct list_head list; enum op { ROT_PX=0, ROT_PY=1, ROT_PZ=2, ROT_NX=3, ROT_NY=4, ROT_NZ=5, EXTEND=6, RETRACT=7, OPEN_HEAD=8, CLOSE_HEAD=9, NOP=10 } op; } *pc; } *

variable_types: struct glyph { struct position { int x; } pos; enum glyph_op { BOND=0, UNBOND=1, SOURCE=2, TRANSMUTE=3 } op; int type; struct atom { struct list_head { struct list_head *next; } compound; int bonds[-1]; struct position pos; enum element { ATOM_NONE=0, ATOM_H=1, ATOM_HE=2, ATOM_LI=3, ATOM_BE=4, ATOM_AL=5, ATOM_C=6, ATOM_N=7, ATOM_O=8, ATOM_F=9, ATOM_AR=10, ATOM_END=11 } element; } *a; } *

user_defined_types: struct workspace { struct position size; struct item *items; struct position pos; }

user_defined_types: struct manipulator { struct position pos; enum orientation orient; int length; enum head_state head_state; int grabbed; struct list_head inst_list; struct inst *pc; }

user_defined_types: struct glyph { struct position pos; enum glyph_op op; int type; struct atom *a; }

user_defined_types: struct item { enum item_type type; void *item; }

user_defined_types: struct inst { struct list_head list; enum op op; }

user_defined_types: struct atom { struct list_head compound; int bonds[-1]; struct position pos; enum element element; }


decompiled_code:
void sim_stop()
{
;
}

canonical_decompiled_code:
void func4()
{
;
}

original_code:
void sim_stop(struct workspace *w)
{
}

canonical_original_code:
void sim_stop(struct workspace *w)
{
}

user_defined_types: enum item_type { ITEM_NONE=0, ITEM_ATOM=1, ITEM_MANIPULATOR=2, ITEM_GLYPH=3 }


original_code:
int add_atom(struct workspace *w, struct atom *a, struct position pos)
{
 return add_item(w, (void *)a, pos, ITEM_ATOM);
}

variable_types: struct atom { struct list_head { struct list_head *next; } compound; int bonds[-1]; struct position pos; enum element { ATOM_NONE=0, ATOM_H=1, ATOM_HE=2, ATOM_LI=3, ATOM_BE=4, ATOM_AL=5, ATOM_C=6, ATOM_N=7, ATOM_O=8, ATOM_F=9, ATOM_AR=10, ATOM_END=11 } element; } *

variable_types:
pos
struct position


decompiled_code:
__int64 __fastcall add_manipulator(__int64 a1, __int64 a2, __int64 a3, int a4)
{
return add_item_isra_0(*(_DWORD *)a1, *(_DWORD *)(a1 + 4), *(_QWORD *)(a1 + 16), a2, a3, a4, 2);
}

original_code:
int add_manipulator(struct workspace *w, struct manipulator *m, struct position pos)
{
 return add_item(w, (void *)m, pos, ITEM_MANIPULATOR);
}

variable_types: struct manipulator { struct position pos; enum orientation { PX=0, NX=1, PY=2, NY=3, PZ=4, NZ=5, ORIENTATION_NUM=6 } orient; int length; enum head_state { HEAD_OPEN=0, HEAD_CLOSED=1 } head_state; int grabbed; struct list_head { struct list_head *next; } inst_list; struct inst { struct list_head list; enum op { ROT_PX=0, ROT_PY=1, ROT_PZ=2, ROT_NX=3, ROT_NY=4, ROT_NZ=5, EXTEND=6, RETRACT=7, OPEN_HEAD=8, CLOSE_HEAD=9, NOP=10 } op; } *pc; } *


original_code:
int add_glyph(struct workspace *w, struct glyph *g, struct position pos)
{
 return add_item(w, (void *)g, pos, ITEM_GLYPH);
}

variable_types: struct glyph { struct position pos; enum glyph_op { BOND=0, UNBOND=1, SOURCE=2, TRANSMUTE=3 } op; int type; struct atom { struct list_head { struct list_head *next; } compound; int bonds[-1]; struct position pos; enum element { ATOM_NONE=0, ATOM_H=1, ATOM_HE=2, ATOM_LI=3, ATOM_BE=4, ATOM_AL=5, ATOM_C=6, ATOM_N=7, ATOM_O=8, ATOM_F=9, ATOM_AR=10, ATOM_END=11 } element; } *a; } *


decompiled_code:
__int64 __fastcall remove_atom(__int64 a1, __int64 a2, int a3)
{
return remove_item_isra_0(*(_DWORD *)a1, *(_DWORD *)(a1 + 4), *(_QWORD *)(a1 + 16), a2, a3);
}

original_code:
struct atom *remove_atom(struct workspace *w, struct position pos)
{
 return (struct atom *)remove_item(w, pos, ITEM_ATOM);
}

variable_types: struct workspace { struct position size; struct item { enum item_type { ITEM_NONE=0, ITEM_ATOM=1, ITEM_MANIPULATOR=2, ITEM_GLYPH=3 } type; void *item; } *items; struct position pos; } *

return_type: struct atom { struct list_head { struct list_head *next; } compound; int bonds[-1]; struct position { int x; } pos; enum element { ATOM_NONE=0, ATOM_H=1, ATOM_HE=2, ATOM_LI=3, ATOM_BE=4, ATOM_AL=5, ATOM_C=6, ATOM_N=7, ATOM_O=8, ATOM_F=9, ATOM_AR=10, ATOM_END=11 } element; } *


decompiled_code:
__int64 __fastcall remove_manipulator(__int64 a1, __int64 a2, int a3)
{
return remove_item_isra_0(*(_DWORD *)a1, *(_DWORD *)(a1 + 4), *(_QWORD *)(a1 + 16), a2, a3);
}

original_code:
struct manipulator *remove_manipulator(struct workspace *w, struct position pos)
{
 return (struct manipulator *)remove_item(w, pos, ITEM_MANIPULATOR);
}

return_type: struct manipulator { struct position { int x; } pos; enum orientation { PX=0, NX=1, PY=2, NY=3, PZ=4, NZ=5, ORIENTATION_NUM=6 } orient; int length; enum head_state { HEAD_OPEN=0, HEAD_CLOSED=1 } head_state; int grabbed; struct list_head { struct list_head *next; } inst_list; struct inst { struct list_head list; enum op { ROT_PX=0, ROT_PY=1, ROT_PZ=2, ROT_NX=3, ROT_NY=4, ROT_NZ=5, EXTEND=6, RETRACT=7, OPEN_HEAD=8, CLOSE_HEAD=9, NOP=10 } op; } *pc; } *


decompiled_code:
__int64 __fastcall remove_glyph(__int64 a1, __int64 a2, int a3)
{
return remove_item_isra_0(*(_DWORD *)a1, *(_DWORD *)(a1 + 4), *(_QWORD *)(a1 + 16), a2, a3);
}

original_code:
struct glyph *remove_glyph(struct workspace *w, struct position pos)
{
 return (struct glyph *)remove_item(w, pos, ITEM_GLYPH);
}

return_type: struct glyph { struct position { int x; } pos; enum glyph_op { BOND=0, UNBOND=1, SOURCE=2, TRANSMUTE=3 } op; int type; struct atom { struct list_head { struct list_head *next; } compound; int bonds[-1]; struct position pos; enum element { ATOM_NONE=0, ATOM_H=1, ATOM_HE=2, ATOM_LI=3, ATOM_BE=4, ATOM_AL=5, ATOM_C=6, ATOM_N=7, ATOM_O=8, ATOM_F=9, ATOM_AR=10, ATOM_END=11 } element; } *a; } *


original_code:
struct atom *atom_at(struct workspace *w, struct position pos)
{
 struct item *i = item_at(w, pos);
 if (i->type == ITEM_ATOM)
  return (struct atom *)i->item;
 else if (i->type == ITEM_GLYPH)
  return ((struct glyph *)i->item)->a;
 else
  return ((void *)0);
}

variable_types: struct item { enum item_type { ITEM_NONE=0, ITEM_ATOM=1, ITEM_MANIPULATOR=2, ITEM_GLYPH=3 } type; void *item; } *

user_defined_types: struct list_head { struct list_head *next; }

user_defined_types: enum element { ATOM_NONE=0, ATOM_H=1, ATOM_HE=2, ATOM_LI=3, ATOM_BE=4, ATOM_AL=5, ATOM_C=6, ATOM_N=7, ATOM_O=8, ATOM_F=9, ATOM_AR=10, ATOM_END=11 }

user_defined_types: enum glyph_op { BOND=0, UNBOND=1, SOURCE=2, TRANSMUTE=3 }


original_code:
struct manipulator *manipulator_at(struct workspace *w, struct position pos)
{
 struct item *i = item_at(w, pos);
 if (i->type == ITEM_MANIPULATOR)
  return (struct manipulator *)i->item;
 else
  return ((void *)0);
}

user_defined_types: enum orientation { PX=0, NX=1, PY=2, NY=3, PZ=4, NZ=5, ORIENTATION_NUM=6 }

user_defined_types: enum head_state { HEAD_OPEN=0, HEAD_CLOSED=1 }

user_defined_types: enum op { ROT_PX=0, ROT_PY=1, ROT_PZ=2, ROT_NX=3, ROT_NY=4, ROT_NZ=5, EXTEND=6, RETRACT=7, OPEN_HEAD=8, CLOSE_HEAD=9, NOP=10 }


original_code:
void sim_start(struct workspace *w)
{
 struct position pos;
 struct manipulator *m;
 for (pos.z = 0; pos.z < w->size.z; pos.z++) for (pos.y = 0; pos.y < w->size.y; pos.y++) for (pos.x = 0; pos.x < w->size.x; pos.x++) {
  if ((m = manipulator_at(w, pos)) != ((void *)0))
   m->pc = ((struct inst *)((char *)(m->inst_list.next)-(unsigned long)(&((struct inst *)0)->list)));
 }
}

variable_types:
pos
struct position { int x; }


original_code:
struct glyph *glyph_at(struct workspace *w, struct position pos)
{
 struct item *i = item_at(w, pos);
 if (i->type == ITEM_GLYPH)
  return (struct glyph *)i->item;
 else
  return ((void *)0);
}


decompiled_code:
void __fastcall sim_step(char *string)
{
int v1; // er13
signed int i; // er12
signed int j; // ebp
__int64 v4; // rsi
int v5; // eax
int v6; // er13
signed int k; // er12
signed int l; // ebp
const char *v9; // rsi

if ( *((int *)string + 2) > 0 )
{
v1 = 0;
do
{
for ( i = 0; *((_DWORD *)string + 1) > i; ++i )
{
for ( j = 0; *(_DWORD *)string > j; ++j )
{
v4 = glyph_at((__int64)string, __SPAIR64__(i, j), v1);
if ( v4 )
act(string, v4);
}
}
v5 = *((_DWORD *)string + 2);
++v1;
}
while ( v5 > v1 );
if ( v5 > 0 )
{
v6 = 0;
do
{
for ( k = 0; *((_DWORD *)string + 1) > k; ++k )
{
for ( l = 0; *(_DWORD *)string > l; ++l )
{
v9 = (const char *)manipulator_at((__int64)string, __SPAIR64__(k, l), v6);
if ( v9 )
step(string, v9);
}
}
++v6;
}
while ( *((_DWORD *)string + 2) > v6 );
}
}
}

canonical_decompiled_code:
void __fastcall func15(char *string)
{
int v1; // er13
signed int i; // er12
signed int j; // ebp
__int64 v4; // rsi
int v5; // eax
int v6; // er13
signed int k; // er12
signed int l; // ebp
const char *v9; // rsi

if ( *((int *)string + 2) > 0 )
{
v1 = 0;
do
{
for ( i = 0; *((_DWORD *)string + 1) > i; ++i )
{
for ( j = 0; *(_DWORD *)string > j; ++j )
{
v4 = func14((__int64)string, __SPAIR64__(i, j), v1);
if ( v4 )
act(string, v4);
}
}
v5 = *((_DWORD *)string + 2);
++v1;
}
while ( v5 > v1 );
if ( v5 > 0 )
{
v6 = 0;
do
{
for ( k = 0; *((_DWORD *)string + 1) > k; ++k )
{
for ( l = 0; *(_DWORD *)string > l; ++l )
{
v9 = (const char *)func12((__int64)string, __SPAIR64__(k, l), v6);
if ( v9 )
step(string, v9);
}
}
++v6;
}
while ( *((_DWORD *)string + 2) > v6 );
}
}
}

original_code:
void sim_step(struct workspace *w)
{
 struct position pos;
 struct manipulator *m;
 struct glyph *g;
 for (pos.z = 0; pos.z < w->size.z; pos.z++) for (pos.y = 0; pos.y < w->size.y; pos.y++) for (pos.x = 0; pos.x < w->size.x; pos.x++) {
  if ((g = glyph_at(w, pos)) != ((void *)0))
   act(w, g);
 }
 for (pos.z = 0; pos.z < w->size.z; pos.z++) for (pos.y = 0; pos.y < w->size.y; pos.y++) for (pos.x = 0; pos.x < w->size.x; pos.x++) {
  if ((m = manipulator_at(w, pos)) != ((void *)0))
   step(w, m);
 }
}


decompiled_code:
__int64 __fastcall move_manipulator(__int64 a1, __int64 a2, int a3, __int64 a4, int a5)
{
__int64 v5; // rax
__int64 result; // rax
__int64 v7; // r11

v5 = remove_manipulator(a1, a2, a3);
if ( !v5 )
return 0xFFFFFFFFLL;
result = add_manipulator(a1, v5, a4, a5);
if ( (_DWORD)result )
{
add_manipulator(a1, v7, a2, a3);
result = 4294967294LL;
}
else
{
*(_QWORD *)v7 = a4;
*(_DWORD *)(v7 + 8) = a5;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func16(__int64 a1, __int64 a2, int a3, __int64 a4, int a5)
{
__int64 v5; // rax
__int64 result; // rax
__int64 v7; // r11

v5 = func9(a1, a2, a3);
if ( !v5 )
return 0xFFFFFFFFLL;
result = func6(a1, v5, a4, a5);
if ( (_DWORD)result )
{
func6(a1, v7, a2, a3);
result = 4294967294LL;
}
else
{
*(_QWORD *)v7 = a4;
*(_DWORD *)(v7 + 8) = a5;
}
return result;
}

original_code:
int move_manipulator(struct workspace *w, struct position from, struct position to)
{
 struct manipulator *m = remove_manipulator(w, from);
 if (m != ((void *)0)) {
  if (add_manipulator(w, m, to) == 0) {
   m->pos = to;
   return 0;
  } else {
   add_manipulator(w, m, from);
   return -2;
  }
 } else {
  return -1;
 }
}

variable_types:
from
struct position

variable_types:
to
struct position


decompiled_code:
__int64 __fastcall pos_add(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v4; // [rsp+0h] [rbp-14h]

LODWORD(v4) = a1 + a3;
HIDWORD(v4) = HIDWORD(a3) + HIDWORD(a1);
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v4; // [rsp+0h] [rbp-14h]

LODWORD(v4) = a1 + a3;
HIDWORD(v4) = HIDWORD(a3) + HIDWORD(a1);
return v4;
}

original_code:
static inline struct position pos_add(struct position a, struct position b)
{
 struct position p = {
  a.x + b.x,
  a.y + b.y,
  a.z + b.z
 };
 return p;
}

variable_types:
a
struct position

variable_types:
b
struct position

variable_types:
p
struct position { int x; }

return_type: struct position { int x; }


decompiled_code:
__int64 __fastcall pos_shift(int a1, unsigned int a2)
{
__int64 result; // rax
__int64 v3; // [rsp+0h] [rbp-14h]
__int64 v4; // [rsp+0h] [rbp-14h]

switch ( a1 )
{
case 0:
result = a2;
break;
case 1:
result = -a2;
break;
case 2:
LODWORD(v3) = 0;
HIDWORD(v3) = a2;
result = v3;
break;
case 3:
LODWORD(v4) = 0;
HIDWORD(v4) = -a2;
result = v4;
break;
case 4:
result = 0LL;
break;
case 5:
result = 0LL;
break;
default:
JUMPOUT(0x839LL);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1, unsigned int a2)
{
__int64 result; // rax
__int64 v3; // [rsp+0h] [rbp-14h]
__int64 v4; // [rsp+0h] [rbp-14h]

switch ( a1 )
{
case 0:
result = a2;
break;
case 1:
result = -a2;
break;
case 2:
LODWORD(v3) = 0;
HIDWORD(v3) = a2;
result = v3;
break;
case 3:
LODWORD(v4) = 0;
HIDWORD(v4) = -a2;
result = v4;
break;
case 4:
result = 0LL;
break;
case 5:
result = 0LL;
break;
default:
JUMPOUT(0x839LL);
}
return result;
}

original_code:
static inline struct position pos_shift(enum orientation o, int dist)
{
 struct position dp = {0, 0, 0};
 switch (o) {
 case PX:
  dp.x = dist;
  break;
 case NX:
  dp.x = -dist;
  break;
 case PY:
  dp.y = dist;
  break;
 case NY:
  dp.y = -dist;
  break;
 case PZ:
  dp.z = dist;
  break;
 case NZ:
  dp.z = -dist;
  break;
 default: break;
 }
 return dp;
}

variable_types: enum orientation { PX=0, NX=1, PY=2, NY=3, PZ=4, NZ=5, ORIENTATION_NUM=6 }

variable_types: dist int

variable_types:
dp
struct position { int x; }


rotated

original_code:
static inline enum orientation rotated(enum orientation o, enum orientation dir)
{
 const enum orientation rot_tab[ORIENTATION_NUM][ORIENTATION_NUM] = {
  {PX, PX, PZ, NZ, PY, NY},
  {NX, NX, NZ, PZ, NY, PY},
  {PZ, NZ, PY, PY, NX, PX},
  {NZ, PZ, NY, NY, PX, NX},
  {NY, PY, NX, PX, PZ, PZ},
  {PY, NY, PX, NX, NZ, NZ}
 };
 return rot_tab[o][dir];
}

canonical_original_code:
static inline enum orientation rotated(enum orientation o, enum orientation dir)
{
 enum orientation rot_tab[-1][-1] = {
  {PX, PX, PZ, NZ, PY, NY},
  {NX, NX, NZ, PZ, NY, PY},
  {PZ, NZ, PY, PY, NX, PX},
  {NZ, PZ, NY, NY, PX, NX},
  {NY, PY, NX, PX, PZ, PZ},
  {PY, NY, PX, NX, NZ, NZ}
 };
 return rot_tab[o][dir];
}

variable_types: enum orientation { PX=0, NX=1, PY=2, NY=3, PZ=4, NZ=5, ORIENTATION_NUM=6 } [-1][-1]


decompiled_code:
void __fastcall list_del(__int64 a1)
{
_QWORD *v1; // rax

_list_del(*(_QWORD **)(a1 + 8), *(_QWORD *)a1);
*v1 = 0LL;
v1[1] = 0LL;
}

original_code:
static inline void list_del(struct list_head *entry)
{
 __list_del(entry->prev, entry->next);
 entry->next = (void *) 0;
 entry->prev = (void *) 0;
}

variable_types: struct list_head { struct list_head *next; } *


decompiled_code:
_BOOL8 __fastcall list_empty(_QWORD *a1)
{
return *a1 == (_QWORD)a1;
}

canonical_decompiled_code:
_BOOL8 __fastcall func8(_QWORD *a1)
{
return *a1 == (_QWORD)a1;
}

original_code:
static inline int list_empty(struct list_head *head)
{
 return head->next == head;
}


decompiled_code:
__int64 __fastcall get_head_pos(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // rcx

v1 = pos_shift(*(_DWORD *)(a1 + 12), *(_DWORD *)(a1 + 16));
return pos_add(*(_QWORD *)v2, *(unsigned int *)(v2 + 8), v1);
}

original_code:
struct position get_head_pos(struct manipulator *m) {
 struct position ret;
 ret = pos_add(m->pos, pos_shift(m->orient, m->length));
 return ret;
}

variable_types:
ret
struct position { int x; }


decompiled_code:
// attributes: thunk
void delete_glyph(void *ptr)
{
free(ptr);
}

canonical_decompiled_code:
void func0(void *ptr)
{
free(ptr);
}

original_code:
void delete_glyph(struct glyph *g)
{
 free(g);
}

variable_types: struct glyph { struct position { int x; } pos; enum glyph_op { BOND=0, UNBOND=1, SOURCE=2, TRANSMUTE=3 } op; int type; struct atom { struct list_head { struct list_head *next; } compound; int bonds[-1]; struct position pos; enum element { ATOM_NONE=0, ATOM_H=1, ATOM_HE=2, ATOM_LI=3, ATOM_BE=4, ATOM_AL=5, ATOM_C=6, ATOM_N=7, ATOM_O=8, ATOM_F=9, ATOM_AR=10, ATOM_END=11 } element; } *a; } *


act

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

result = *((unsigned int *)a2 + 3);
switch ( (_DWORD)result )
{
case 1:
return remove_bond(a1, *a2, *((unsigned int *)a2 + 2), *((unsigned int *)a2 + 4));
case 2:
if ( !a2[3] )
{
result = new_atom(*((unsigned int *)a2 + 4), *a2, *((unsigned int *)a2 + 2));
a2[3] = result;
}
break;
case 0:
result = add_bond(a1, *a2, *((unsigned int *)a2 + 2), *((unsigned int *)a2 + 4));
break;
}
return result;
}

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

result = *((unsigned int *)a2 + 3);
switch ( (_DWORD)result )
{
case 1:
return remove_bond(a1, *a2, *((unsigned int *)a2 + 2), *((unsigned int *)a2 + 4));
case 2:
if ( !a2[3] )
{
result = new_atom(*((unsigned int *)a2 + 4), *a2, *((unsigned int *)a2 + 2));
a2[3] = result;
}
break;
case 0:
result = add_bond(a1, *a2, *((unsigned int *)a2 + 2), *((unsigned int *)a2 + 4));
break;
}
return result;
}

original_code:
void act(struct workspace *w, struct glyph *g)
{
 switch(g->op) {
 case BOND:
  add_bond(w, g->pos, (enum orientation)g->type);
  break;
 case UNBOND:
  remove_bond(w, g->pos, (enum orientation)g->type);
  break;
 case SOURCE:
  if (g->a == ((void *)0))
   g->a = new_atom((enum element)g->type, g->pos);
  break;
 case TRANSMUTE:
  break;
 default:
  break;
 }
}

variable_types: struct workspace { struct position { int x; } size; struct item { enum item_type { ITEM_NONE=0, ITEM_ATOM=1, ITEM_MANIPULATOR=2, ITEM_GLYPH=3 } type; void *item; } *items; struct position pos; } *


decompiled_code:
__int64 init_io()
{
int v1; // [rsp+4h] [rbp-14h] BYREF
const char *v2; // [rsp+8h] [rbp-10h] BYREF

v1 = 1;
v2 = "alchem";
glutInit(&v1, &v2);
glutInitDisplayMode(18LL);
glutInitWindowPosition(100LL, 100LL);
glutInitWindowSize(1000LL, 700LL);
return glutCreateWindow("alchem");
}

canonical_decompiled_code:
__int64 func4()
{
int v1; // [rsp+4h] [rbp-14h] BYREF
const char *v2; // [rsp+8h] [rbp-10h] BYREF

v1 = 1;
v2 = "alchem";
glutInit(&v1, &v2);
glutInitDisplayMode(18LL);
glutInitWindowPosition(100LL, 100LL);
glutInitWindowSize(1000LL, 700LL);
return glutCreateWindow("alchem");
}

original_code:
void init_io(void)
{
 initscr();
 cbreak();
 noecho();
 keypad(stdscr, 1);
 curs_set(0);
}

canonical_original_code:
void init_io()
{
 initscr();
 cbreak();
 noecho();
 keypad(stdscr, 1);
 curs_set(0);
}


decompiled_code:
void end_io()
{
;
}

canonical_decompiled_code:
void func5()
{
;
}

original_code:
void end_io(void)
{
 endwin();
}

canonical_original_code:
void end_io()
{
 endwin();
}


decompiled_code:
__int64 __fastcall edit_workspace_loop(__int64 a1)
{
w_io = a1;
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(motion);
return glutMainLoop();
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
w_io = a1;
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(motion);
return glutMainLoop();
}

original_code:
void edit_workspace_loop(struct workspace *w)
{
 int cmd;
 do {
  display(w);
  cmd = process_input_blocking(w);
 } while (cmd != -1);
}

variable_types: cmd int


decompiled_code:
__int64 __fastcall draw_manipulator(int *a1)
{
glPushMatrix();
glTranslatef((float)*a1, (float)-a1[1], (float)a1[2]);
switch ( a1[3] )
{
case 0:
glRotatef(90.0, 0.0, 1.0);
break;
case 1:
glRotatef(-90.0, 0.0, 1.0);
break;
case 2:
glRotatef(90.0, COERCE_DOUBLE((unsigned __int64)LC5), 0.0);
break;
case 3:
glRotatef(-90.0, COERCE_DOUBLE((unsigned __int64)LC5), 0.0);
break;
case 5:
glRotatef(180.0, 0.0, 1.0);
break;
default:
break;
}
glColor3f(1.0, 0.0);
glutWireSphere(40LL, 40LL, 0.25);
glColor3f(0.0, COERCE_DOUBLE((unsigned __int64)LC5));
glutWireCone(20LL, 5LL, 0.125, (double)a1[4]);
return glPopMatrix();
}

canonical_decompiled_code:
__int64 __fastcall func7(int *a1)
{
glPushMatrix();
glTranslatef((float)*a1, (float)-a1[1], (float)a1[2]);
switch ( a1[3] )
{
case 0:
glRotatef(90.0, 0.0, 1.0);
break;
case 1:
glRotatef(-90.0, 0.0, 1.0);
break;
case 2:
glRotatef(90.0, COERCE_DOUBLE((unsigned __int64)LC5), 0.0);
break;
case 3:
glRotatef(-90.0, COERCE_DOUBLE((unsigned __int64)LC5), 0.0);
break;
case 5:
glRotatef(180.0, 0.0, 1.0);
break;
default:
break;
}
glColor3f(1.0, 0.0);
glutWireSphere(40LL, 40LL, 0.25);
glColor3f(0.0, COERCE_DOUBLE((unsigned __int64)LC5));
glutWireCone(20LL, 5LL, 0.125, (double)a1[4]);
return glPopMatrix();
}

variable_types: struct manipulator { struct position { int x; } pos; enum orientation { PX=0, NX=1, PY=2, NY=3, PZ=4, NZ=5, ORIENTATION_NUM=6 } orient; int length; enum head_state { HEAD_OPEN=0, HEAD_CLOSED=1 } head_state; int grabbed; struct list_head { struct list_head *next; } inst_list; struct inst { struct list_head list; enum op { ROT_PX=0, ROT_PY=1, ROT_PZ=2, ROT_NX=3, ROT_NY=4, ROT_NZ=5, EXTEND=6, RETRACT=7, OPEN_HEAD=8, CLOSE_HEAD=9, NOP=10 } op; } *pc; } *

variable_types: dx int

variable_types: dy int

variable_types: x int

variable_types: y int


decompiled_code:
__int64 __fastcall draw_glyph(int *a1)
{
int v1; // eax
float v3; // xmm0_4
double v4; // xmm1_8

glPushMatrix();
glTranslatef((float)*a1, (float)-a1[1], (float)a1[2]);
v1 = a1[3];
switch ( v1 )
{
case 1:
v3 = *(float *)&LC5;
v4 = 0.0;
LABEL_6:
glColor3f(v3, v4);
glutWireTorus(40LL, 40LL, 0.25, 0.5);
return glPopMatrix();
case 2:
glColor3f(0.0, 0.0);
glutWireCube(0.5, 0.0, 1.0);
return glPopMatrix();
case 0:
*(_QWORD *)&v4 = (unsigned int)LC5;
v3 = 0.0;
goto LABEL_6;
}
return glPopMatrix();
}

canonical_decompiled_code:
__int64 __fastcall func8(int *a1)
{
int v1; // eax
float v3; // xmm0_4
double v4; // xmm1_8

glPushMatrix();
glTranslatef((float)*a1, (float)-a1[1], (float)a1[2]);
v1 = a1[3];
switch ( v1 )
{
case 1:
v3 = *(float *)&LC5;
v4 = 0.0;
LABEL_6:
glColor3f(v3, v4);
glutWireTorus(40LL, 40LL, 0.25, 0.5);
return glPopMatrix();
case 2:
glColor3f(0.0, 0.0);
glutWireCube(0.5, 0.0, 1.0);
return glPopMatrix();
case 0:
*(_QWORD *)&v4 = (unsigned int)LC5;
v3 = 0.0;
goto LABEL_6;
}
return glPopMatrix();
}

original_code:
void draw_glyph(struct glyph *g)
{
 struct position adj;
 switch(g->op) {
 case BOND:
  (wmove((stdscr),((3*g->pos.y+2)),((4*g->pos.x+3))) == (-1) ? (-1) : waddch((stdscr),(('+'))));
  adj = pos_add(g->pos, pos_shift((enum orientation)g->type, 1));
  (wmove((stdscr),((3*adj.y+2)),((4*adj.x+3))) == (-1) ? (-1) : waddch((stdscr),(('+'))));
  break;
 case UNBOND:
  (wmove((stdscr),((3*g->pos.y+2)),((4*g->pos.x+3))) == (-1) ? (-1) : waddch((stdscr),(('-'))));
  adj = pos_add(g->pos, pos_shift((enum orientation)g->type, 1));
  (wmove((stdscr),((3*adj.y+2)),((4*adj.x+3))) == (-1) ? (-1) : waddch((stdscr),(('-'))));
  break;
 case SOURCE:
  (wmove((stdscr),((3*g->pos.y+1)),((4*g->pos.x))) == (-1) ? (-1) : waddch((stdscr),(('<'))));
  (wmove((stdscr),((3*g->pos.y+1)),((4*g->pos.x+3))) == (-1) ? (-1) : waddch((stdscr),(('>'))));
  break;
 case TRANSMUTE:
  break;
 default:
  break;
 }
}

variable_types:
adj
struct position { int x; }


decompiled_code:
__int64 __fastcall draw_atom(int *a1)
{
glPushMatrix();
glTranslatef((float)a1[10], (float)-a1[11], (float)a1[12]);
glColor3f(0.5, COERCE_DOUBLE((unsigned __int64)LC13));
glutSolidSphere(40LL, 40LL, 0.2);
return glPopMatrix();
}

canonical_decompiled_code:
__int64 __fastcall func9(int *a1)
{
glPushMatrix();
glTranslatef((float)a1[10], (float)-a1[11], (float)a1[12]);
glColor3f(0.5, COERCE_DOUBLE((unsigned __int64)LC13));
glutSolidSphere(40LL, 40LL, 0.2);
return glPopMatrix();
}

original_code:
void draw_atom(struct atom *a)
{
 enum orientation dir;
 struct position adj;
 (wmove((stdscr),((3*a->pos.y+1)),((4*a->pos.x+1))) == (-1) ? (-1) : waddnstr((stdscr),((element_string(a->element))),-1));
 for (dir = 0; dir < ORIENTATION_NUM; dir++) {
  if (a->bonds[dir] > 0) {
   adj = pos_add(a->pos, pos_shift(dir, 1));
   draw_bond(a->pos, adj);
  }
 }
}

variable_types: struct atom { struct list_head { struct list_head *next; } compound; int bonds[-1]; struct position { int x; } pos; enum element { ATOM_NONE=0, ATOM_H=1, ATOM_HE=2, ATOM_LI=3, ATOM_BE=4, ATOM_AL=5, ATOM_C=6, ATOM_N=7, ATOM_O=8, ATOM_F=9, ATOM_AR=10, ATOM_END=11 } element; } *


display

decompiled_code:
__int64 display()
{
unsigned int v0; // er12
int *v1; // rbp
unsigned int v2; // er13
unsigned int v3; // ebx
int *v4; // rdi
int *v5; // rdi
int *v6; // rdi

v0 = 0;
v1 = (int *)w_io;
glClear(16640LL);
glLoadIdentity();
glTranslatef(0.0, 0.0, -2.0);
draw_grid();
if ( v1[2] > 0 )
{
while ( 1 )
{
v2 = 0;
if ( v1[1] > 0 )
break;
LABEL_13:
if ( v1[2] <= (int)++v0 )
return glutSwapBuffers();
}
while ( 1 )
{
v3 = 0;
if ( *v1 > 0 )
break;
LABEL_12:
if ( v1[1] <= (int)++v2 )
goto LABEL_13;
}
while ( 1 )
{
while ( 1 )
{
v4 = (int *)atom_at(v1, __PAIR64__(v2, v3), v0);
if ( v4 )
draw_atom(v4);
v5 = (int *)glyph_at(v1, __PAIR64__(v2, v3), v0);
if ( !v5 )
break;
draw_glyph(v5);
LABEL_6:
if ( *v1 <= (int)++v3 )
goto LABEL_12;
}
v6 = (int *)manipulator_at(v1, __PAIR64__(v2, v3), v0);
if ( !v6 )
goto LABEL_6;
draw_manipulator(v6);
if ( *v1 <= (int)++v3 )
goto LABEL_12;
}
}
return glutSwapBuffers();
}

canonical_decompiled_code:
__int64 func11()
{
unsigned int v0; // er12
int *v1; // rbp
unsigned int v2; // er13
unsigned int v3; // ebx
int *v4; // rdi
int *v5; // rdi
int *v6; // rdi

v0 = 0;
v1 = (int *)w_io;
glClear(16640LL);
glLoadIdentity();
glTranslatef(0.0, 0.0, -2.0);
func10();
if ( v1[2] > 0 )
{
while ( 1 )
{
v2 = 0;
if ( v1[1] > 0 )
break;
LABEL_13:
if ( v1[2] <= (int)++v0 )
return glutSwapBuffers();
}
while ( 1 )
{
v3 = 0;
if ( *v1 > 0 )
break;
LABEL_12:
if ( v1[1] <= (int)++v2 )
goto LABEL_13;
}
while ( 1 )
{
while ( 1 )
{
v4 = (int *)atom_at(v1, __PAIR64__(v2, v3), v0);
if ( v4 )
func9(v4);
v5 = (int *)glyph_at(v1, __PAIR64__(v2, v3), v0);
if ( !v5 )
break;
func8(v5);
LABEL_6:
if ( *v1 <= (int)++v3 )
goto LABEL_12;
}
v6 = (int *)manipulator_at(v1, __PAIR64__(v2, v3), v0);
if ( !v6 )
goto LABEL_6;
func7(v6);
if ( *v1 <= (int)++v3 )
goto LABEL_12;
}
}
return glutSwapBuffers();
}

original_code:
void display(struct workspace *w)
{
 struct position pos;
 struct atom *a;
 struct manipulator *m;
 struct glyph *g;
 wclear(stdscr);
 for (pos.z = 0; pos.z < 1; pos.z++) for (pos.y = 0; pos.y < w->size.y; pos.y++) for (pos.x = 0; pos.x < w->size.x; pos.x++) {
  if (((pos.x == w->pos.x) && (pos.y == w->pos.y) && (pos.z == w->pos.z)))
   wattr_on(stdscr, (attr_t)((((chtype)((1U)) << ((8) + 8)))), ((void *)0));
  if ((a = atom_at(w, pos)) != ((void *)0)) {
   draw_atom(a);
  } else if ((m = manipulator_at(w, pos)) != ((void *)0)) {
   draw_manipulator(m);
  } else if ((g = glyph_at(w, pos)) != ((void *)0)) {
   draw_glyph(g);
  } else {
   (wmove((stdscr),((3*pos.y+1)),((4*pos.x+1))) == (-1) ? (-1) : waddch((stdscr),(('.'))));
  }
  if (((pos.x == w->pos.x) && (pos.y == w->pos.y) && (pos.z == w->pos.z)))
   wattr_off(stdscr, (attr_t)((((chtype)((1U)) << ((8) + 8)))), ((void *)0));
 }
 if ((m = manipulator_at(w, w->pos)) != ((void *)0)) {
  print_inst_list(m, 4 * w->size.x + 1);
  wattr_on(stdscr, (attr_t)((((chtype)((1U)) << ((8) + 8)))), ((void *)0));
  draw_manipulator(m);
  wattr_off(stdscr, (attr_t)((((chtype)((1U)) << ((8) + 8)))), ((void *)0));
 }
 wrefresh(stdscr);
}

variable_types:
pos
struct position { int x; }


canonical_original_code:
static inline struct position pos_add(struct position a, struct position b)
{
 struct position p = {
  a.x + b.x,
  a.y + b.y,
  a.z + b.z
 };
 return p;
}

variable_types:
a
struct position

variable_types:
b
struct position

variable_types:
p
struct position { int x; }


decompiled_code:
__int64 __fastcall pos_sub(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v4; // [rsp+0h] [rbp-14h]

LODWORD(v4) = a1 - a3;
HIDWORD(v4) = HIDWORD(a1) - HIDWORD(a3);
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v4; // [rsp+0h] [rbp-14h]

LODWORD(v4) = a1 - a3;
HIDWORD(v4) = HIDWORD(a1) - HIDWORD(a3);
return v4;
}

original_code:
static inline struct position pos_sub(struct position a, struct position b)
{
 struct position p = {
  a.x - b.x,
  a.y - b.y,
  a.z - b.z
 };
 return p;
}


opposite

decompiled_code:
__int64 __fastcall opposite(unsigned int a1)
{
__int64 result; // rax

result = 6LL;
if ( a1 <= 5 )
result = (unsigned int)CSWTCH_13[a1];
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned int a1)
{
__int64 result; // rax

result = 6LL;
if ( a1 <= 5 )
result = (unsigned int)CSWTCH_13[a1];
return result;
}

original_code:
static inline enum orientation opposite(enum orientation o)
{
 switch (o) {
 case PX: return NX;
 case NX: return PX;
 case PY: return NY;
 case NY: return PY;
 case PZ: return NZ;
 case NZ: return PZ;
 default: return ORIENTATION_NUM;
 }
}

variable_types: enum orientation { PX=0, NX=1, PY=2, NY=3, PZ=4, NZ=5, ORIENTATION_NUM=6 }


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const void **v3; // r15
unsigned __int16 v4; // bp
unsigned int v5; // ebx
const char **v6; // r13
const char *v7; // r14
const char *v8; // rax
FILE *v9; // r12
int v10; // er13
__int64 v11; // rcx
__int64 v12; // rax
__int64 v13; // rdx
int v14; // er12
int v15; // ebp
char v17[32]; // [rsp+0h] [rbp-20058h] BYREF
__int16 ptr[65564]; // [rsp+20h] [rbp-20038h] BYREF

if ( argc <= 1 )
{
LABEL_22:
fwrite("usage: disasm <fname> [--start=<start>] [--end=<end>]\n", 1uLL, 0x36uLL, _bss_start);
exit(1);
}
v3 = (const void **)(argv + 1);
v4 = -1;
v5 = 0;
v6 = &argv[(unsigned int)(argc - 2) + 2];
v7 = 0LL;
do
{
while ( 1 )
{
v8 = (const char *)*v3;
if ( memcmp(*v3, "--start=", 8uLL) )
break;
v5 = (unsigned __int16)atoi(v8 + 8);
LABEL_4:
if ( ++v3 == (const void **)v6 )
goto LABEL_8;
}
if ( memcmp(*v3, "--end=", 6uLL) )
{
v7 = (const char *)*v3;
goto LABEL_4;
}
++v3;
v4 = atoi(v8 + 6);
}
while ( v3 != (const void **)v6 );
LABEL_8:
if ( !v7 )
goto LABEL_22;
v9 = fopen(v7, "rb");
v10 = fread(ptr, 2uLL, 0x10000uLL, v9);
fclose(v9);
if ( v10 <= 0 )
{
v13 = 0LL;
}
else
{
v12 = 0LL;
v13 = 0LL;
while ( 1 )
{
v11 = v12 + 1;
if ( ptr[v12] )
v13 = (unsigned int)v12;
if ( v10 - 1 == v12 )
break;
++v12;
}
}
v14 = v4;
if ( (unsigned __int16)v13 + 1 < v4 )
v14 = (unsigned __int16)(v13 + 1);
for ( ; v14 >= (int)v5; v5 += v15 )
{
v15 = decode_inst(&ptr[v5], v17, v13, v11);
printf("0x%.4X: %s\n", v5, v17);
}
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const void **v3; // r15
unsigned __int16 v4; // bp
unsigned int v5; // ebx
const char **v6; // r13
const char *v7; // r14
const char *v8; // rax
FILE *v9; // r12
int v10; // er13
__int64 v11; // rcx
__int64 v12; // rax
__int64 v13; // rdx
int v14; // er12
int v15; // ebp
char v17[32]; // [rsp+0h] [rbp-20058h] BYREF
__int16 ptr[65564]; // [rsp+20h] [rbp-20038h] BYREF

if ( argc <= 1 )
{
LABEL_22:
fwrite("usage: disasm <fname> [--start=<start>] [--end=<end>]\n", 1uLL, 0x36uLL, _bss_start);
exit(1);
}
v3 = (const void **)(argv + 1);
v4 = -1;
v5 = 0;
v6 = &argv[(unsigned int)(argc - 2) + 2];
v7 = 0LL;
do
{
while ( 1 )
{
v8 = (const char *)*v3;
if ( memcmp(*v3, "--start=", 8uLL) )
break;
v5 = (unsigned __int16)atoi(v8 + 8);
LABEL_4:
if ( ++v3 == (const void **)v6 )
goto LABEL_8;
}
if ( memcmp(*v3, "--end=", 6uLL) )
{
v7 = (const char *)*v3;
goto LABEL_4;
}
++v3;
v4 = atoi(v8 + 6);
}
while ( v3 != (const void **)v6 );
LABEL_8:
if ( !v7 )
goto LABEL_22;
v9 = fopen(v7, "rb");
v10 = fread(ptr, 2uLL, 0x10000uLL, v9);
fclose(v9);
if ( v10 <= 0 )
{
v13 = 0LL;
}
else
{
v12 = 0LL;
v13 = 0LL;
while ( 1 )
{
v11 = v12 + 1;
if ( ptr[v12] )
v13 = (unsigned int)v12;
if ( v10 - 1 == v12 )
break;
++v12;
}
}
v14 = v4;
if ( (unsigned __int16)v13 + 1 < v4 )
v14 = (unsigned __int16)(v13 + 1);
for ( ; v14 >= (int)v5; v5 += v15 )
{
v15 = func9(&ptr[v5], v17, v13, v11);
printf("0x%.4X: %s\n", v5, v17);
}
return 0;
}

original_code:
int main(int argc, char *argv[])
{
 ++argv, --argc;
 if (argc > 0)
  yyin = fopen(argv[0], "r");
 else
  yyin = stdin;
 while(yylex());
 return 0;
}

variable_types: argc int

variable_types:
argv
char *[]


decompiled_code:
__int64 __fastcall decode_lval(unsigned __int16 a1, unsigned __int16 a2)
{
__int64 result; // rax

if ( a1 <= 7u )
{
strcpy(lval, (&gpr_table)[a1]);
result = 0LL;
}
else if ( a1 <= 0xFu )
{
sprintf(lval, "[%s]", (&gpr_table)[a1 - 8]);
result = 0LL;
}
else if ( a1 <= 0x17u )
{
sprintf(lval, "[0x%.4x+%s]", a2, (&gpr_table)[a1 - 16]);
result = 1LL;
}
else
{
switch ( a1 )
{
case 0x19u:
strcpy(lval, "peek");
result = 0LL;
break;
case 0x1Au:
sprintf(lval, "[sp+0x%.4x]", a2);
result = 1LL;
break;
case 0x1Bu:
result = 0LL;
strcpy(lval, "sp");
break;
case 0x1Cu:
result = 0LL;
strcpy(lval, "pc");
break;
case 0x1Du:
strcpy(lval, "ex");
result = 0LL;
break;
case 0x1Eu:
sprintf(lval, "[0x%.4x]", a2);
result = 1LL;
break;
case 0x1Fu:
sprintf(lval, "0x%.4x", a2);
result = 1LL;
break;
default:
strcpy(lval, "push");
result = 0LL;
break;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(unsigned __int16 a1, unsigned __int16 a2)
{
__int64 result; // rax

if ( a1 <= 7u )
{
strcpy(lval, (&gpr_table)[a1]);
result = 0LL;
}
else if ( a1 <= 0xFu )
{
sprintf(lval, "[%s]", (&gpr_table)[a1 - 8]);
result = 0LL;
}
else if ( a1 <= 0x17u )
{
sprintf(lval, "[0x%.4x+%s]", a2, (&gpr_table)[a1 - 16]);
result = 1LL;
}
else
{
switch ( a1 )
{
case 0x19u:
strcpy(lval, "peek");
result = 0LL;
break;
case 0x1Au:
sprintf(lval, "[sp+0x%.4x]", a2);
result = 1LL;
break;
case 0x1Bu:
result = 0LL;
strcpy(lval, "sp");
break;
case 0x1Cu:
result = 0LL;
strcpy(lval, "pc");
break;
case 0x1Du:
strcpy(lval, "ex");
result = 0LL;
break;
case 0x1Eu:
sprintf(lval, "[0x%.4x]", a2);
result = 1LL;
break;
case 0x1Fu:
sprintf(lval, "0x%.4x", a2);
result = 1LL;
break;
default:
strcpy(lval, "push");
result = 0LL;
break;
}
}
return result;
}

original_code:
int decode_lval(uint16_t val, uint16_t next)
{
 int rv = 0;
 if (val < 0x08) {
  sprintf(lval, "%s", gpr_table[val]);
 } else if (val < 0x10) {
  sprintf(lval, "[%s]", gpr_table[val - 0x08]);
 } else if (val < 0x18) {
  rv = 1;
  sprintf(lval, "[0x%.4x+%s]", next, gpr_table[val - 0x10]);
 } else {
  switch (val) {
  case 0x18:
   sprintf(lval, "push");
   break;
  case 0x19:
   sprintf(lval, "peek");
   break;
  case 0x1a:
   rv = 1;
   sprintf(lval, "[sp+0x%.4x]", next);
   break;
  case 0x1b:
   sprintf(lval, "sp");
   break;
  case 0x1c:
   sprintf(lval, "pc");
   break;
  case 0x1d:
   sprintf(lval, "ex");
   break;
  case 0x1e:
   rv = 1;
   sprintf(lval, "[0x%.4x]", next);
   break;
  case 0x1f:
   rv = 1;
   sprintf(lval, "0x%.4x", next);
   break;
  default:
   break;
  }
 }
 return rv;
}

canonical_original_code:
int decode_lval(unsigned short val, unsigned short next)
{
 int rv = 0;
 if (val < 0x08) {
  sprintf(lval, "%s", gpr_table[val]);
 } else if (val < 0x10) {
  sprintf(lval, "[%s]", gpr_table[val - 0x08]);
 } else if (val < 0x18) {
  rv = 1;
  sprintf(lval, "[0x%.4x+%s]", next, gpr_table[val - 0x10]);
 } else {
  switch (val) {
  case 0x18:
   sprintf(lval, "push");
   break;
  case 0x19:
   sprintf(lval, "peek");
   break;
  case 0x1a:
   rv = 1;
   sprintf(lval, "[sp+0x%.4x]", next);
   break;
  case 0x1b:
   sprintf(lval, "sp");
   break;
  case 0x1c:
   sprintf(lval, "pc");
   break;
  case 0x1d:
   sprintf(lval, "ex");
   break;
  case 0x1e:
   rv = 1;
   sprintf(lval, "[0x%.4x]", next);
   break;
  case 0x1f:
   rv = 1;
   sprintf(lval, "0x%.4x", next);
   break;
  default:
   break;
  }
 }
 return rv;
}

variable_types:
val
unsigned short

variable_types:
next
unsigned short

variable_types: rv int


decompiled_code:
__int64 __fastcall decode_rval(unsigned __int16 a1, unsigned __int16 a2)
{
unsigned int v2; // er12
__int64 result; // rax
char v4[40]; // [rsp+0h] [rbp-28h] BYREF

if ( a1 > 0x1Fu )
{
sprintf(rval, "0x%.4x", (unsigned int)a1 - 33);
result = 0LL;
}
else if ( a1 == 24 )
{
strcpy(rval, "pop");
result = 0LL;
}
else
{
strncpy(v4, lval, 0x10uLL);
v2 = decode_lval(a1, a2);
strncpy(rval, lval, 0x10uLL);
strncpy(lval, v4, 0x10uLL);
result = v2;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(unsigned __int16 a1, unsigned __int16 a2)
{
unsigned int v2; // er12
__int64 result; // rax
char v4[40]; // [rsp+0h] [rbp-28h] BYREF

if ( a1 > 0x1Fu )
{
sprintf(rval, "0x%.4x", (unsigned int)a1 - 33);
result = 0LL;
}
else if ( a1 == 24 )
{
strcpy(rval, "pop");
result = 0LL;
}
else
{
strncpy(v4, lval, 0x10uLL);
v2 = func7(a1, a2);
strncpy(rval, lval, 0x10uLL);
strncpy(lval, v4, 0x10uLL);
result = v2;
}
return result;
}

original_code:
int decode_rval(uint16_t val, uint16_t next)
{
 int rv = 0;
 char temp[16];
 if (val >= 0x20) {
  sprintf(rval, "0x%.4x", (int16_t)val - 0x21);
 } else if (val == 0x18) {
  sprintf(rval, "pop");
 } else {
  strncpy(temp, lval, 16);
  rv = decode_lval(val, next);
  strncpy(rval, lval, 16);
  strncpy(lval, temp, 16);
 }
 return rv;
}

canonical_original_code:
int decode_rval(unsigned short val, unsigned short next)
{
 int rv = 0;
 char temp[16];
 if (val >= 0x20) {
  sprintf(rval, "0x%.4x", (short)val - 0x21);
 } else if (val == 0x18) {
  sprintf(rval, "pop");
 } else {
  strncpy(temp, lval, 16);
  rv = decode_lval(val, next);
  strncpy(rval, lval, 16);
  strncpy(lval, temp, 16);
 }
 return rv;
}

variable_types:
temp
char [16]


decompiled_code:
__int64 __fastcall decode_inst(unsigned __int16 *a1, char *a2)
{
unsigned __int16 v3; // di
__int64 result; // rax
unsigned int v5; // er12
int v6; // er12
unsigned int v7; // er12

v3 = *a1;
if ( (v3 & 0x1F) != 0 )
{
v6 = decode_rval(v3 >> 10, a1[1]) + 1;
v7 = decode_lval((v3 >> 5) & 0x1F, a1[v6]) + v6;
sprintf(a2, "%s %s, %s", (const char *)*(&opcode_table + (v3 & 0x1F)), lval, rval);
result = v7;
}
else if ( ((v3 >> 5) & 0x1F) != 0 )
{
v5 = decode_rval(v3 >> 10, a1[1]) + 1;
sprintf(a2, "%s %s", (const char *)*(&spc_opcode_table + ((v3 >> 5) & 0x1F)), rval);
result = v5;
}
else
{
sprintf(a2, "dat 0x%.4x", v3);
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(unsigned __int16 *a1, char *a2)
{
unsigned __int16 v3; // di
__int64 result; // rax
unsigned int v5; // er12
int v6; // er12
unsigned int v7; // er12

v3 = *a1;
if ( (v3 & 0x1F) != 0 )
{
v6 = func8(v3 >> 10, a1[1]) + 1;
v7 = func7((v3 >> 5) & 0x1F, a1[v6]) + v6;
sprintf(a2, "%s %s, %s", (const char *)*(&opcode_table + (v3 & 0x1F)), lval, rval);
result = v7;
}
else if ( ((v3 >> 5) & 0x1F) != 0 )
{
v5 = func8(v3 >> 10, a1[1]) + 1;
sprintf(a2, "%s %s", (const char *)*(&spc_opcode_table + ((v3 >> 5) & 0x1F)), rval);
result = v5;
}
else
{
sprintf(a2, "dat 0x%.4x", v3);
result = 1LL;
}
return result;
}

original_code:
int decode_inst(uint16_t *inst, char *buf)
{
 int words = 1;
 uint16_t word;
 word = inst[0];
 if (word & 0x1F) {
  words += decode_rval((word >> 10) & 0x3F, inst[words]);
  words += decode_lval((word >> 5) & 0x1F, inst[words]);
  sprintf(buf, "%s %s, %s", opcode_table[word & 0x1F], lval, rval);
 } else if ((word >> 5) & 0x1F) {
  words += decode_rval((word >> 10) & 0x3F, inst[words]);
  sprintf(buf, "%s %s", spc_opcode_table[(word >> 5) & 0x1F], rval);
 } else {
  sprintf(buf, "dat 0x%.4x", word);
 }
 return words;
}

canonical_original_code:
int decode_inst(unsigned short *inst, char *buf)
{
 int words = 1;
 unsigned short word;
 word = inst[0];
 if (word & 0x1F) {
  words += decode_rval((word >> 10) & 0x3F, inst[words]);
  words += decode_lval((word >> 5) & 0x1F, inst[words]);
  sprintf(buf, "%s %s, %s", opcode_table[word & 0x1F], lval, rval);
 } else if ((word >> 5) & 0x1F) {
  words += decode_rval((word >> 10) & 0x3F, inst[words]);
  sprintf(buf, "%s %s", spc_opcode_table[(word >> 5) & 0x1F], rval);
 } else {
  sprintf(buf, "dat 0x%.4x", word);
 }
 return words;
}

variable_types:
inst
unsigned short *

variable_types:
buf
char *

variable_types: words int

variable_types:
word
unsigned short


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
__int64 v4; // rbx
int v6; // [rsp+0h] [rbp-38h] BYREF
char v7; // [rsp+4h] [rbp-34h]

v3 = fcntl(0, 3, envp);
BYTE1(v3) |= 8u;
fcntl(0, 4, v3);
v4 = get_hw();
puts(*argv);
fflush(stdout);
puts("ready");
fflush(stdout);
while ( !feof(stdin) )
{
(*(void (**)(void))(v4 + 32))();
if ( fgets((char *)&v6, 32, stdin) )
{
if ( v6 != 174684008 || v7 )
{
if ( !strcmp((const char *)&v6, "hwq\n") )
hwq(v4);
}
else
{
(*(void (**)(void))(v4 + 24))();
}
puts("done");
fflush(stdout);
}
}
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
__int64 v4; // rbx
int v6; // [rsp+0h] [rbp-38h] BYREF
char v7; // [rsp+4h] [rbp-34h]

v3 = fcntl(0, 3, envp);
BYTE1(v3) |= 8u;
fcntl(0, 4, v3);
v4 = func19();
puts(*argv);
fflush(stdout);
puts("ready");
fflush(stdout);
while ( !feof(stdin) )
{
(*(void (**)(void))(v4 + 32))();
if ( fgets((char *)&v6, 32, stdin) )
{
if ( v6 != 174684008 || v7 )
{
if ( !strcmp((const char *)&v6, "hwq\n") )
func7(v4);
}
else
{
(*(void (**)(void))(v4 + 24))();
}
puts("done");
fflush(stdout);
}
}
return 0;
}

original_code:
int main(int argc, char *argv[])
{
 struct hw_builtin *hw;
 char input[32];
 char *status;
 fcntl(0, 4, fcntl(0, 3) | 04000);
 hw = get_hw();
 printf("%s\n", argv[0]);
 fflush(stdout);
 printf("ready\n");
 fflush(stdout);
 while (!feof(stdin)) {
  (*hw->step)();
  status = fgets(input, 32, stdin);
  if (((void *)0) != status) {
   if (strcmp(input, "hwi\n") == 0)
    (*hw->interrupt)();
   else if (strcmp(input, "hwq\n") == 0)
    hwq(hw);
   printf("done\n");
   fflush(stdout);
  }
 }
 return 0;
}

variable_types: struct hw_builtin { unsigned int id; unsigned short version; unsigned int mfg; void (*init)(); int (*interrupt)(); void (*step)(); } *

variable_types:
input
char [32]

variable_types:
status
char *


hwq

decompiled_code:
__int64 __fastcall hwq(unsigned __int16 *a1)
{
write_register(0LL, *a1);
write_register(1LL, HIWORD(*(_DWORD *)a1));
write_register(2LL, a1[2]);
write_register(3LL, a1[4]);
return write_register(4LL, a1[5]);
}

canonical_decompiled_code:
__int64 __fastcall func7(unsigned __int16 *a1)
{
func13(0LL, *a1);
func13(1LL, HIWORD(*(_DWORD *)a1));
func13(2LL, a1[2]);
func13(3LL, a1[4]);
return func13(4LL, a1[5]);
}

original_code:
void hwq(struct hw_builtin *hw)
{
 write_register(REG_A, hw->id & 0xFFFF);
 write_register(REG_B, hw->id >> 16);
 write_register(REG_C, hw->version);
 write_register(REG_X, hw->mfg & 0xFFFF);
 write_register(REG_Y, hw->mfg >> 16);
}

user_defined_types: struct hw_builtin { unsigned int id; unsigned short version; unsigned int mfg; void (*init)(); int (*interrupt)(); void (*step)(); }


decompiled_code:
int set_input_blocking()
{
unsigned int v0; // eax

v0 = fcntl(0, 3);
BYTE1(v0) &= 0xF7u;
return fcntl(0, 4, v0);
}

canonical_decompiled_code:
int func8()
{
unsigned int v0; // eax

v0 = fcntl(0, 3);
BYTE1(v0) &= 0xF7u;
return fcntl(0, 4, v0);
}

original_code:
void set_input_blocking(void)
{
 int fl = fcntl(0, 3);
 fcntl(0, 4, fl & ~04000);
}

canonical_original_code:
void set_input_blocking()
{
 int fl = fcntl(0, 3);
 fcntl(0, 4, fl & ~04000);
}

variable_types: fl int


decompiled_code:
int set_input_nonblocking()
{
unsigned int v0; // eax

v0 = fcntl(0, 3);
BYTE1(v0) |= 8u;
return fcntl(0, 4, v0);
}

canonical_decompiled_code:
int func9()
{
unsigned int v0; // eax

v0 = fcntl(0, 3);
BYTE1(v0) |= 8u;
return fcntl(0, 4, v0);
}

original_code:
void set_input_nonblocking(void)
{
 int fl = fcntl(0, 3);
 fcntl(0, 4, fl | 04000);
}

canonical_original_code:
void set_input_nonblocking()
{
 int fl = fcntl(0, 3);
 fcntl(0, 4, fl | 04000);
}


decompiled_code:
__int64 get_uint16()
{
unsigned __int16 v1; // [rsp+Eh] [rbp-2Ah]
char s[40]; // [rsp+10h] [rbp-28h] BYREF

set_input_blocking();
fgets(s, 32, stdin);
set_input_nonblocking();
__isoc99_sscanf();
return v1;
}

canonical_decompiled_code:
__int64 func10()
{
unsigned __int16 v1; // [rsp+Eh] [rbp-2Ah]
char s[40]; // [rsp+10h] [rbp-28h] BYREF

func8();
fgets(s, 32, stdin);
func9();
__isoc99_sscanf();
return v1;
}

original_code:
uint16_t get_uint16(void)
{
 char buf[32];
 uint16_t ret;
 set_input_blocking();
 fgets(buf, 32, stdin);
 set_input_nonblocking();
 sscanf(buf, "%hu", &ret);
 return ret;
}

canonical_original_code:
unsigned short get_uint16()
{
 char buf[32];
 unsigned short ret;
 set_input_blocking();
 fgets(buf, 32, stdin);
 set_input_nonblocking();
 sscanf(buf, "%hu", &ret);
 return ret;
}

variable_types:
buf
char [32]

variable_types:
ret
unsigned short

return_type: unsigned short


decompiled_code:
int lem_init()
{
return clock_gettime(0, &tp_prev);
}

canonical_decompiled_code:
int func16()
{
return clock_gettime(0, &tp_prev);
}

original_code:
void lem_init(void)
{
 clock_gettime(0, &tp_prev);
}

canonical_original_code:
void lem_init()
{
 clock_gettime(0, &tp_prev);
}


original_code:
void lem_step(void)
{
 uint16_t row, col, index;
 char row_buf[33] = "                                ";
 uint16_t vram_buf[384];
 struct timespec tp_cur;
 uint64_t ns;
 clock_gettime(0, &tp_cur);
 ns = (tp_cur.tv_sec - tp_prev.tv_sec) * 1000000000;
 ns += (tp_cur.tv_nsec - tp_prev.tv_nsec);
 if ((ns * 60 / 1000000000) == 0)
  return;
 mvprintw(vram_top - 1, vram_left - 1, "+--------------------------------+");
 if (connected) {
  read_memory(vram, 384, vram_buf);
  if (custom_font)
   return;
  for (row = 0; row < 12; row++) {
   for (col = 0; col < 32; col++) {
    index = row * 32 + col;
    row_buf[col] = (char)vram_buf[index];
    if (row_buf[col] == 0)
     row_buf[col] = ' ';
   }
   row_buf[col] = 0;
   mvprintw(vram_top + row, vram_left - 1, "|%s|", row_buf);
  }
 } else {
  for (row = 0; row < 12; row++) {
   mvprintw(vram_top + row, vram_left - 1, "|%s|", row_buf);
  }
 }
 mvprintw(vram_top + 12, vram_left - 1, "+--------------------------------+");
 wrefresh(stdscr);
}

canonical_original_code:
void lem_step()
{
 unsigned short row; unsigned short col; unsigned short index;
 char row_buf[33] = "                                ";
 unsigned short vram_buf[384];
 struct timespec tp_cur;
 unsigned long ns;
 clock_gettime(0, &tp_cur);
 ns = (tp_cur.tv_sec - tp_prev.tv_sec) * 1000000000;
 ns += (tp_cur.tv_nsec - tp_prev.tv_nsec);
 if ((ns * 60 / 1000000000) == 0)
  return;
 mvprintw(vram_top - 1, vram_left - 1, "+--------------------------------+");
 if (connected) {
  read_memory(vram, 384, vram_buf);
  if (custom_font)
   return;
  for (row = 0; row < 12; row++) {
   for (col = 0; col < 32; col++) {
    index = row * 32 + col;
    row_buf[col] = (char)vram_buf[index];
    if (row_buf[col] == 0)
     row_buf[col] = ' ';
   }
   row_buf[col] = 0;
   mvprintw(vram_top + row, vram_left - 1, "|%s|", row_buf);
  }
 } else {
  for (row = 0; row < 12; row++) {
   mvprintw(vram_top + row, vram_left - 1, "|%s|", row_buf);
  }
 }
 mvprintw(vram_top + 12, vram_left - 1, "+--------------------------------+");
 wrefresh(stdscr);
}

variable_types:
row
unsigned short

variable_types:
col
unsigned short

variable_types:
index
unsigned short

variable_types: struct timespec { long tv_sec; long tv_nsec; }

variable_types:
ns
unsigned long


decompiled_code:
__int64 lem_interrupt()
{
unsigned __int16 v0; // bx
unsigned __int16 v1; // ax
__int64 result; // rax

v0 = read_register(1u);
v1 = read_register(0);
if ( v1 == 4 )
{
write_memory(v0, 0x100u, font);
result = 256LL;
}
else if ( v1 > 4u )
{
if ( v1 != 5 )
return 0LL;
write_memory(v0, 0x10u, pal);
result = 16LL;
}
else
{
if ( v1 )
{
if ( v1 == 1 )
custom_font = 1;
return 0LL;
}
if ( v0 )
{
if ( !connected )
clock_gettime(0, &tp_prev);
vram = v0;
result = 0LL;
connected = 1;
}
else
{
connected = 0;
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 func18()
{
unsigned __int16 v0; // bx
unsigned __int16 v1; // ax
__int64 result; // rax

v0 = func11(1u);
v1 = func11(0);
if ( v1 == 4 )
{
func14(v0, 0x100u, font);
result = 256LL;
}
else if ( v1 > 4u )
{
if ( v1 != 5 )
return 0LL;
func14(v0, 0x10u, pal);
result = 16LL;
}
else
{
if ( v1 )
{
if ( v1 == 1 )
custom_font = 1;
return 0LL;
}
if ( v0 )
{
if ( !connected )
clock_gettime(0, &tp_prev);
vram = v0;
result = 0LL;
connected = 1;
}
else
{
connected = 0;
result = 0LL;
}
}
return result;
}

original_code:
int lem_interrupt(void)
{
 uint16_t cycles = 0;
 uint16_t b = read_register(REG_B);
 switch (read_register(REG_A)) {
 case 0:
  if (b) {
   if (connected == 0) {
    clock_gettime(0, &tp_prev);
   }
   connected = 1;
   vram = b;
  } else {
   connected = 0;
  }
  break;
 case 1:
  if (b) {
   custom_font = 1;
   font_ram = b;
  } else {
   custom_font = 1;
  }
  break;
 case 2:
  if (b) {
   custom_pal = 1;
   pal_ram = b;
  } else {
   custom_pal = 1;
  }
  break;
 case 3:
  border_col = b;
  break;
 case 4:
  write_memory(b, 256, font);
  cycles = 256;
  break;
 case 5:
  write_memory(b, 16, pal);
  cycles = 16;
  break;
 default:
  break;
 }
 return cycles;
}

canonical_original_code:
int lem_interrupt()
{
 unsigned short cycles = 0;
 unsigned short b = read_register(REG_B);
 switch (read_register(REG_A)) {
 case 0:
  if (b) {
   if (connected == 0) {
    clock_gettime(0, &tp_prev);
   }
   connected = 1;
   vram = b;
  } else {
   connected = 0;
  }
  break;
 case 1:
  if (b) {
   custom_font = 1;
   font_ram = b;
  } else {
   custom_font = 1;
  }
  break;
 case 2:
  if (b) {
   custom_pal = 1;
   pal_ram = b;
  } else {
   custom_pal = 1;
  }
  break;
 case 3:
  border_col = b;
  break;
 case 4:
  write_memory(b, 256, font);
  cycles = 256;
  break;
 case 5:
  write_memory(b, 16, pal);
  cycles = 16;
  break;
 default:
  break;
 }
 return cycles;
}

variable_types:
cycles
unsigned short

variable_types:
b
unsigned short


decompiled_code:
__int64 __fastcall read_register(unsigned __int16 a1)
{
printf("reg r %hu\n", a1);
fflush(stdout);
return get_uint16();
}

canonical_decompiled_code:
__int64 __fastcall func11(unsigned __int16 a1)
{
printf("reg r %hu\n", a1);
fflush(stdout);
return func10();
}

original_code:
uint16_t read_register(uint16_t reg)
{
 printf("reg r %hu\n", reg);
 fflush(stdout);
 return get_uint16();
}

canonical_original_code:
unsigned short read_register(unsigned short reg)
{
 printf("reg r %hu\n", reg);
 fflush(stdout);
 return get_uint16();
}

variable_types:
reg
unsigned short


decompiled_code:
int __fastcall read_memory(unsigned __int16 a1, unsigned __int16 a2, __int64 a3)
{
int result; // eax
__int64 v5; // rbp

printf("mem r %hu %hu\n", a1, a2);
result = fflush(stdout);
if ( a2 )
{
v5 = a3 + 2LL * ((unsigned int)a2 - 1) + 2;
do
{
result = get_uint16();
a3 += 2LL;
*(_WORD *)(a3 - 2) = result;
}
while ( a3 != v5 );
}
return result;
}

canonical_decompiled_code:
int __fastcall func12(unsigned __int16 a1, unsigned __int16 a2, __int64 a3)
{
int result; // eax
__int64 v5; // rbp

printf("mem r %hu %hu\n", a1, a2);
result = fflush(stdout);
if ( a2 )
{
v5 = a3 + 2LL * ((unsigned int)a2 - 1) + 2;
do
{
result = func10();
a3 += 2LL;
*(_WORD *)(a3 - 2) = result;
}
while ( a3 != v5 );
}
return result;
}

original_code:
void read_memory(uint16_t addr, uint16_t len, uint16_t *buf)
{
 int i;
 printf("mem r %hu %hu\n", addr, len);
 fflush(stdout);
 for (i = 0; i < len; i++)
  buf[i] = get_uint16();
}

canonical_original_code:
void read_memory(unsigned short addr, unsigned short len, unsigned short *buf)
{
 int i;
 printf("mem r %hu %hu\n", addr, len);
 fflush(stdout);
 for (i = 0; i < len; i++)
  buf[i] = get_uint16();
}

variable_types:
addr
unsigned short

variable_types:
len
unsigned short

variable_types:
buf
unsigned short *

variable_types: i int


decompiled_code:
int __fastcall write_register(unsigned __int16 a1, unsigned __int16 a2)
{
printf("reg w %hu %hu\n", a1, a2);
return fflush(stdout);
}

canonical_decompiled_code:
int __fastcall func13(unsigned __int16 a1, unsigned __int16 a2)
{
printf("reg w %hu %hu\n", a1, a2);
return fflush(stdout);
}

original_code:
void write_register(uint16_t reg, uint16_t val)
{
 printf("reg w %hu %hu\n", reg, val);
 fflush(stdout);
}

canonical_original_code:
void write_register(unsigned short reg, unsigned short val)
{
 printf("reg w %hu %hu\n", reg, val);
 fflush(stdout);
}

variable_types:
val
unsigned short


decompiled_code:
int __fastcall write_memory(unsigned __int16 a1, unsigned __int16 a2, unsigned __int16 *a3)
{
__int64 v4; // rbp
__int64 v5; // rsi

printf("mem w %hu %hu", a1, a2);
fflush(stdout);
if ( a2 )
{
v4 = (__int64)&a3[a2];
do
{
v5 = *a3++;
printf(" %hu", v5);
fflush(stdout);
}
while ( a3 != (unsigned __int16 *)v4 );
}
putchar(10);
return fflush(stdout);
}

canonical_decompiled_code:
int __fastcall func14(unsigned __int16 a1, unsigned __int16 a2, unsigned __int16 *a3)
{
__int64 v4; // rbp
__int64 v5; // rsi

printf("mem w %hu %hu", a1, a2);
fflush(stdout);
if ( a2 )
{
v4 = (__int64)&a3[a2];
do
{
v5 = *a3++;
printf(" %hu", v5);
fflush(stdout);
}
while ( a3 != (unsigned __int16 *)v4 );
}
putchar(10);
return fflush(stdout);
}

original_code:
void write_memory(uint16_t addr, uint16_t len, uint16_t *buf)
{
 int i;
 printf("mem w %hu %hu", addr, len);
 fflush(stdout);
 for (i = 0; i < len; i++) {
  printf(" %hu", buf[i]);
  fflush(stdout);
 }
 printf("\n");
 fflush(stdout);
}

canonical_original_code:
void write_memory(unsigned short addr, unsigned short len, unsigned short *buf)
{
 int i;
 printf("mem w %hu %hu", addr, len);
 fflush(stdout);
 for (i = 0; i < len; i++) {
  printf(" %hu", buf[i]);
  fflush(stdout);
 }
 printf("\n");
 fflush(stdout);
}


decompiled_code:
int __fastcall raise_interrupt(unsigned __int16 a1)
{
printf("int %hu\n", a1);
return fflush(stdout);
}

canonical_decompiled_code:
int __fastcall func15(unsigned __int16 a1)
{
printf("int %hu\n", a1);
return fflush(stdout);
}

original_code:
void raise_interrupt(uint16_t msg)
{
 printf("int %hu\n", msg);
 fflush(stdout);
}

canonical_original_code:
void raise_interrupt(unsigned short msg)
{
 printf("int %hu\n", msg);
 fflush(stdout);
}

variable_types:
msg
unsigned short


original_code:
struct hw_builtin *get_hw(void)
{
 return lem1802(1, 1);
}

canonical_original_code:
struct hw_builtin *get_hw()
{
 return lem1802(1, 1);
}

return_type: struct hw_builtin { unsigned int id; unsigned short version; unsigned int mfg; void (*init)(); int (*interrupt)(); void (*step)(); } *


readline

decompiled_code:
ssize_t __fastcall readline(int fd, void *buf, unsigned int a3)
{
unsigned __int64 v3; // rcx
_BYTE *v5; // rbx
unsigned int v6; // edx
unsigned int v7; // eax
__int64 v8; // rsi
ssize_t result; // rax
_BYTE *v10; // r12

v3 = ((unsigned __int64)buf + 8) & 0xFFFFFFFFFFFFFFF8LL;
v5 = buf;
*(_QWORD *)buf = 0LL;
*(_QWORD *)((char *)buf + a3 - 8) = 0LL;
v6 = (a3 + (_DWORD)buf - v3) & 0xFFFFFFF8;
v7 = 0;
do
{
v8 = v7;
v7 += 8;
*(_QWORD *)(v3 + v8) = 0LL;
}
while ( v7 < v6 );
result = read(fd, v5, 1uLL);
v10 = &v5[a3 - 1];
do
{
if ( *v5 == 10 )
break;
result = read(fd, ++v5, 1uLL);
}
while ( v5 != v10 );
return result;
}

canonical_decompiled_code:
ssize_t __fastcall func0(int fd, void *buf, unsigned int a3)
{
unsigned __int64 v3; // rcx
_BYTE *v5; // rbx
unsigned int v6; // edx
unsigned int v7; // eax
__int64 v8; // rsi
ssize_t result; // rax
_BYTE *v10; // r12

v3 = ((unsigned __int64)buf + 8) & 0xFFFFFFFFFFFFFFF8LL;
v5 = buf;
*(_QWORD *)buf = 0LL;
*(_QWORD *)((char *)buf + a3 - 8) = 0LL;
v6 = (a3 + (_DWORD)buf - v3) & 0xFFFFFFF8;
v7 = 0;
do
{
v8 = v7;
v7 += 8;
*(_QWORD *)(v3 + v8) = 0LL;
}
while ( v7 < v6 );
result = read(fd, v5, 1uLL);
v10 = &v5[a3 - 1];
do
{
if ( *v5 == 10 )
break;
result = read(fd, ++v5, 1uLL);
}
while ( v5 != v10 );
return result;
}

original_code:
void readline(int fd, char *buf, int max)
{
 int i = 0;
 memset(buf, 0, max);
 do {
  read(fd, &buf[i], 1);
  i++;
 } while ((i < max) && (buf[i - 1] != '\n'));
}

variable_types: fd int

variable_types:
buf
char *

variable_types: max int


decompiled_code:
int __fastcall module_waitreply(int *a1)
{
int v2; // edi
int result; // eax
size_t v4; // rax
int v5; // edi
unsigned __int16 v6; // [rsp+Ch] [rbp-4Ch] BYREF
unsigned __int16 v7; // [rsp+Eh] [rbp-4Ah] BYREF
int buf; // [rsp+10h] [rbp-48h] BYREF
__int16 v9; // [rsp+14h] [rbp-44h]
char s[40]; // [rsp+30h] [rbp-28h] BYREF

do
{
readline(a1[1], &buf, 0x20u);
v2 = dbgline++;
mvprintw(v2, dbgrow, "from module: %s", (const char *)&buf);
if ( dbgline > 46 )
{
dbgrow += 30;
dbgline = 27;
}
result = refresh();
if ( buf == 543647090 && (_BYTE)v9 == 114 )
{
_isoc99_sscanf(&buf, "reg r %hu", &v6);
v6 = read_register(v6);
sprintf(s, format, v6);
v4 = strlen(s);
write(*a1, s, v4);
v5 = dbgline++;
mvprintw(v5, dbgrow, "to module: %s", s);
if ( dbgline > 46 )
{
dbgrow += 30;
dbgline = 27;
}
result = refresh();
}
else if ( buf == 543647090 && (_BYTE)v9 == 119 )
{
_isoc99_sscanf(&buf, "reg w %hu %hu", &v6, &v7);
result = write_register(v6, v7);
}
else if ( buf == 544040301 && (_BYTE)v9 == 114 )
{
result = _isoc99_sscanf(&buf, "mem r %hu %hu", &v6, &v7);
}
else if ( buf == 544040301 && (_BYTE)v9 == 119 )
{
result = _isoc99_sscanf(&buf, "mem w %hu %hu", &v6, &v7);
}
}
while ( buf != 1701736292 || v9 != 10 );
return result;
}

canonical_decompiled_code:
int __fastcall func1(int *a1)
{
int v2; // edi
int result; // eax
size_t v4; // rax
int v5; // edi
unsigned __int16 v6; // [rsp+Ch] [rbp-4Ch] BYREF
unsigned __int16 v7; // [rsp+Eh] [rbp-4Ah] BYREF
int buf; // [rsp+10h] [rbp-48h] BYREF
__int16 v9; // [rsp+14h] [rbp-44h]
char s[40]; // [rsp+30h] [rbp-28h] BYREF

do
{
func0(a1[1], &buf, 0x20u);
v2 = dbgline++;
mvprintw(v2, dbgrow, "from module: %s", (const char *)&buf);
if ( dbgline > 46 )
{
dbgrow += 30;
dbgline = 27;
}
result = refresh();
if ( buf == 543647090 && (_BYTE)v9 == 114 )
{
_isoc99_sscanf(&buf, "reg r %hu", &v6);
v6 = read_register(v6);
sprintf(s, format, v6);
v4 = strlen(s);
write(*a1, s, v4);
v5 = dbgline++;
mvprintw(v5, dbgrow, "to module: %s", s);
if ( dbgline > 46 )
{
dbgrow += 30;
dbgline = 27;
}
result = refresh();
}
else if ( buf == 543647090 && (_BYTE)v9 == 119 )
{
_isoc99_sscanf(&buf, "reg w %hu %hu", &v6, &v7);
result = write_register(v6, v7);
}
else if ( buf == 544040301 && (_BYTE)v9 == 114 )
{
result = _isoc99_sscanf(&buf, "mem r %hu %hu", &v6, &v7);
}
else if ( buf == 544040301 && (_BYTE)v9 == 119 )
{
result = _isoc99_sscanf(&buf, "mem w %hu %hu", &v6, &v7);
}
}
while ( buf != 1701736292 || v9 != 10 );
return result;
}

original_code:
void module_waitreply(struct hw_module *hw)
{
 uint16_t arg1, arg2;
 char buf[32], reply[32];
 do {
  readline(hw->rx, buf, 32);
  do { mvprintw(dbgline++, dbgrow, "from module: %s", buf); if (dbgline > 46) { dbgline = 27; dbgrow += 30; } refresh(); } while (0);;
  if (strncmp(buf, "reg r", 5) == 0) {
   sscanf(buf, "reg r %hu", &arg1);
   arg1 = read_register(arg1);
   sprintf(reply, "%i\n", arg1);
   write(hw->tx, reply, strlen(reply));
   do { mvprintw(dbgline++, dbgrow, "to module: %s", reply); if (dbgline > 46) { dbgline = 27; dbgrow += 30; } refresh(); } while (0);;
  } else if (strncmp(buf, "reg w", 5) == 0) {
   sscanf(buf, "reg w %hu %hu", &arg1, &arg2);
   write_register(arg1, arg2);
  } else if (strncmp(buf, "mem r", 5) == 0) {
   sscanf(buf, "mem r %hu %hu", &arg1, &arg2);
  } else if (strncmp(buf, "mem w", 5) == 0) {
   sscanf(buf, "mem w %hu %hu", &arg1, &arg2);
  }
 } while (strcmp(buf, "done\n") != 0);
}

canonical_original_code:
void module_waitreply(struct hw_module *hw)
{
 unsigned short arg1; unsigned short arg2;
 char buf[32]; char reply[32];
 do {
  readline(hw->rx, buf, 32);
  do { mvprintw(dbgline++, dbgrow, "from module: %s", buf); if (dbgline > 46) { dbgline = 27; dbgrow += 30; } refresh(); } while (0);;
  if (strncmp(buf, "reg r", 5) == 0) {
   sscanf(buf, "reg r %hu", &arg1);
   arg1 = read_register(arg1);
   sprintf(reply, "%i\n", arg1);
   write(hw->tx, reply, strlen(reply));
   do { mvprintw(dbgline++, dbgrow, "to module: %s", reply); if (dbgline > 46) { dbgline = 27; dbgrow += 30; } refresh(); } while (0);;
  } else if (strncmp(buf, "reg w", 5) == 0) {
   sscanf(buf, "reg w %hu %hu", &arg1, &arg2);
   write_register(arg1, arg2);
  } else if (strncmp(buf, "mem r", 5) == 0) {
   sscanf(buf, "mem r %hu %hu", &arg1, &arg2);
  } else if (strncmp(buf, "mem w", 5) == 0) {
   sscanf(buf, "mem w %hu %hu", &arg1, &arg2);
  }
 } while (strcmp(buf, "done\n") != 0);
}

variable_types:
hw
struct hw_module { int tx; } *

variable_types:
buf
char [32]

variable_types:
reply
char [32]


decompiled_code:
size_t __fastcall hardware_step(unsigned __int16 a1)
{
__int64 v1; // rdi
size_t result; // rax
int *v3; // rdx
int v4; // edi
unsigned __int16 v5; // [rsp+0h] [rbp-2Ah] BYREF
char s[2]; // [rsp+2h] [rbp-28h] BYREF
char v7; // [rsp+4h] [rbp-26h]

v1 = 4LL * a1;
result = (unsigned int)hardware[v1];
v3 = &hardware[v1];
if ( (_DWORD)result == 1 )
return (*(__int64 (**)(void))(*((_QWORD *)v3 + 1) + 32LL))();
if ( (_DWORD)result == 2 )
{
result = readline_async_constprop_0(*(_DWORD *)(*((_QWORD *)v3 + 1) + 4LL), s);
if ( (_DWORD)result )
{
if ( *(_WORD *)s == 28265 && v7 == 116 )
{
v4 = dbgline++;
mvprintw(v4, dbgrow, "from module: %s", s);
if ( dbgline > 46 )
{
dbgrow += 30;
dbgline = 27;
}
refresh();
_isoc99_sscanf(s, "int %hu", &v5);
result = raise_interrupt(v5);
}
}
}
return result;
}

canonical_decompiled_code:
size_t __fastcall func4(unsigned __int16 a1)
{
__int64 v1; // rdi
size_t result; // rax
int *v3; // rdx
int v4; // edi
unsigned __int16 v5; // [rsp+0h] [rbp-2Ah] BYREF
char s[2]; // [rsp+2h] [rbp-28h] BYREF
char v7; // [rsp+4h] [rbp-26h]

v1 = 4LL * a1;
result = (unsigned int)hardware[v1];
v3 = &hardware[v1];
if ( (_DWORD)result == 1 )
return (*(__int64 (**)(void))(*((_QWORD *)v3 + 1) + 32LL))();
if ( (_DWORD)result == 2 )
{
result = func3(*(_DWORD *)(*((_QWORD *)v3 + 1) + 4LL), s);
if ( (_DWORD)result )
{
if ( *(_WORD *)s == 28265 && v7 == 116 )
{
v4 = dbgline++;
mvprintw(v4, dbgrow, "from module: %s", s);
if ( dbgline > 46 )
{
dbgrow += 30;
dbgline = 27;
}
refresh();
_isoc99_sscanf(s, "int %hu", &v5);
result = raise_interrupt(v5);
}
}
}
return result;
}

original_code:
void hardware_step(uint16_t where)
{
 uint16_t arg;
 char buf[32];
 switch(hardware[where].type) {
 case HARDWARE_BUILTIN:
  hardware[where].hw.builtin->step();
  break;
 case HARDWARE_MODULE:
  if (readline_async(hardware[where].hw.module->rx, buf, 32)) {
   if (strncmp(buf, "int", 3) == 0) {
    do { mvprintw(dbgline++, dbgrow, "from module: %s", buf); if (dbgline > 46) { dbgline = 27; dbgrow += 30; } refresh(); } while (0);;
    sscanf(buf, "int %hu", &arg);
    raise_interrupt(arg);
   } else {
   }
  }
  break;
 default:
  break;
 }
}

canonical_original_code:
void hardware_step(unsigned short where)
{
 unsigned short arg;
 char buf[32];
 switch(hardware[where].type) {
 case HARDWARE_BUILTIN:
  hardware[where].hw.builtin->step();
  break;
 case HARDWARE_MODULE:
  if (readline_async(hardware[where].hw.module->rx, buf, 32)) {
   if (strncmp(buf, "int", 3) == 0) {
    do { mvprintw(dbgline++, dbgrow, "from module: %s", buf); if (dbgline > 46) { dbgline = 27; dbgrow += 30; } refresh(); } while (0);;
    sscanf(buf, "int %hu", &arg);
    raise_interrupt(arg);
   } else {
   }
  }
  break;
 default:
  break;
 }
}

variable_types:
where
unsigned short

variable_types:
arg
unsigned short


decompiled_code:
__int64 attach_hardware_builtin()
{
int *v0; // rbx
int *v1; // rbx
__int64 result; // rax

v0 = &hardware[4 * (unsigned __int16)attached++];
*v0 = 1;
*((_QWORD *)v0 + 1) = lem1802(2LL, 46LL);
v1 = &hardware[4 * (unsigned __int16)attached++];
*v1 = 1;
result = generic_clock();
*((_QWORD *)v1 + 1) = result;
return result;
}

canonical_decompiled_code:
__int64 func5()
{
int *v0; // rbx
int *v1; // rbx
__int64 result; // rax

v0 = &hardware[4 * (unsigned __int16)attached++];
*v0 = 1;
*((_QWORD *)v0 + 1) = lem1802(2LL, 46LL);
v1 = &hardware[4 * (unsigned __int16)attached++];
*v1 = 1;
result = generic_clock();
*((_QWORD *)v1 + 1) = result;
return result;
}

original_code:
void attach_hardware_builtin(void)
{
 uint16_t where;
 where = attached++;
 hardware[where].type = HARDWARE_BUILTIN;
 hardware[where].hw.builtin = lem1802(2, 46);
 where = attached++;
 hardware[where].type = HARDWARE_BUILTIN;
 hardware[where].hw.builtin = generic_clock();
}

canonical_original_code:
void attach_hardware_builtin()
{
 unsigned short where;
 where = attached++;
 hardware[where].type = HARDWARE_BUILTIN;
 hardware[where].hw.builtin = lem1802(2, 46);
 where = attached++;
 hardware[where].type = HARDWARE_BUILTIN;
 hardware[where].hw.builtin = generic_clock();
}


decompiled_code:
__int64 __fastcall attach_hardware_module(char *arg)
{
int *v1; // r12
_DWORD *v2; // rax
int v3; // edx
int v4; // edi
int fd; // [rsp+0h] [rbp-38h] BYREF
int v7; // [rsp+4h] [rbp-34h]
int pipedes[2]; // [rsp+8h] [rbp-30h] BYREF
char buf[40]; // [rsp+10h] [rbp-28h] BYREF

pipe(&fd);
pipe(pipedes);
if ( !fork() )
{
close(0);
dup(fd);
close(v7);
close(1);
dup(pipedes[1]);
close(pipedes[0]);
execlp(arg, arg, 0LL);
fprintf(stderr, "error exec'ing %s\n", arg);
perror("execlp");
}
close(fd);
close(pipedes[1]);
v1 = &hardware[4 * (unsigned __int16)attached++];
*v1 = 2;
v2 = malloc(8uLL);
v3 = v7;
v4 = pipedes[0];
*((_QWORD *)v1 + 1) = v2;
*v2 = v3;
v2[1] = v4;
readline(v4, buf, 0x20u);
readline(pipedes[0], buf, 0x20u);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func6(char *arg)
{
int *v1; // r12
_DWORD *v2; // rax
int v3; // edx
int v4; // edi
int fd; // [rsp+0h] [rbp-38h] BYREF
int v7; // [rsp+4h] [rbp-34h]
int pipedes[2]; // [rsp+8h] [rbp-30h] BYREF
char buf[40]; // [rsp+10h] [rbp-28h] BYREF

pipe(&fd);
pipe(pipedes);
if ( !fork() )
{
close(0);
dup(fd);
close(v7);
close(1);
dup(pipedes[1]);
close(pipedes[0]);
execlp(arg, arg, 0LL);
fprintf(stderr, "error exec'ing %s\n", arg);
perror("execlp");
}
close(fd);
close(pipedes[1]);
v1 = &hardware[4 * (unsigned __int16)attached++];
*v1 = 2;
v2 = malloc(8uLL);
v3 = v7;
v4 = pipedes[0];
*((_QWORD *)v1 + 1) = v2;
*v2 = v3;
v2[1] = v4;
func0(v4, buf, 0x20u);
func0(pipedes[0], buf, 0x20u);
return 0LL;
}

original_code:
int attach_hardware_module(const char *name)
{
 uint16_t where;
 int tx_fds[2], rx_fds[2];
 char buf[32];
 pipe(tx_fds);
 pipe(rx_fds);
 if (fork() == 0) {
  close(0);
  dup(tx_fds[0]);
  close(tx_fds[1]);
  close(1);
  dup(rx_fds[1]);
  close(rx_fds[0]);
  execlp(name, name, ((void *)0));
  fprintf(stderr, "error exec\'ing %s\n", name);
  perror("execlp");
 }
 close(tx_fds[0]);
 close(rx_fds[1]);
 where = attached++;
 hardware[where].type = HARDWARE_MODULE;
 hardware[where].hw.module = (struct hw_module *)malloc(sizeof(struct hw_module));
 hardware[where].hw.module->tx = tx_fds[1];
 hardware[where].hw.module->rx = rx_fds[0];
 readline(rx_fds[0], buf, 32);
 readline(rx_fds[0], buf, 32);
 return 0;
}

canonical_original_code:
int attach_hardware_module(char *name)
{
 unsigned short where;
 int tx_fds[2]; int rx_fds[2];
 char buf[32];
 pipe(tx_fds);
 pipe(rx_fds);
 if (fork() == 0) {
  close(0);
  dup(tx_fds[0]);
  close(tx_fds[1]);
  close(1);
  dup(rx_fds[1]);
  close(rx_fds[0]);
  execlp(name, name, ((void *)0));
  fprintf(stderr, "error exec\'ing %s\n", name);
  perror("execlp");
 }
 close(tx_fds[0]);
 close(rx_fds[1]);
 where = attached++;
 hardware[where].type = HARDWARE_MODULE;
 hardware[where].hw.module = (struct hw_module *)malloc(sizeof(struct hw_module));
 hardware[where].hw.module->tx = tx_fds[1];
 hardware[where].hw.module->rx = rx_fds[0];
 readline(rx_fds[0], buf, 32);
 readline(rx_fds[0], buf, 32);
 return 0;
}

variable_types:
name
char *


decompiled_code:
int __fastcall hardware_hwi(unsigned __int16 a1)
{
__int64 v1; // rdi
int result; // eax
int *v3; // rdx

v1 = 4LL * a1;
result = hardware[v1];
v3 = &hardware[v1];
if ( result )
{
if ( result == 1 )
{
result = (*(__int64 (**)(void))(*((_QWORD *)v3 + 1) + 24LL))();
}
else if ( result == 2 )
{
result = module_cmd_constprop_0(*((int **)v3 + 1), "hwi\n");
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func7(unsigned __int16 a1)
{
__int64 v1; // rdi
int result; // eax
int *v3; // rdx

v1 = 4LL * a1;
result = hardware[v1];
v3 = &hardware[v1];
if ( result )
{
if ( result == 1 )
{
result = (*(__int64 (**)(void))(*((_QWORD *)v3 + 1) + 24LL))();
}
else if ( result == 2 )
{
result = func2(*((int **)v3 + 1), "hwi\n");
}
}
return result;
}

original_code:
void hardware_hwi(uint16_t where)
{
 if (hardware[where].type != HARDWARE_NONE) {
  switch(hardware[where].type) {
  case HARDWARE_BUILTIN:
   hardware[where].hw.builtin->interrupt();
   break;
  case HARDWARE_MODULE:
   module_cmd(hardware[where].hw.module, "hwi\n", 4);
   break;
  default:
   break;
  }
 }
}

canonical_original_code:
void hardware_hwi(unsigned short where)
{
 if (hardware[where].type != HARDWARE_NONE) {
  switch(hardware[where].type) {
  case HARDWARE_BUILTIN:
   hardware[where].hw.builtin->interrupt();
   break;
  case HARDWARE_MODULE:
   module_cmd(hardware[where].hw.module, "hwi\n", 4);
   break;
  default:
   break;
  }
 }
}