debug

decompiled_code:
__int64 debug(__int64 a1, __int64 a2, ...)
{
__int64 result; // rax
gcc_va_list va; // [rsp+8h] [rbp-D0h] BYREF

result = debuglvl & (unsigned int)a1;
if ( (debuglvl & (unsigned int)a1) != 0 )
{
va_start(va, a2);
result = vdebug(a1, a2, va);
}
return result;
}

canonical_decompiled_code:
__int64 func0(__int64 a1, __int64 a2, ...)
{
__int64 result; // rax
gcc_va_list va; // [rsp+8h] [rbp-D0h] BYREF

result = debuglvl & (unsigned int)a1;
if ( (debuglvl & (unsigned int)a1) != 0 )
{
va_start(va, a2);
result = vdebug(a1, a2, va);
}
return result;
}

original_code:
static __inline__ void debug(unsigned int dtype, const char *fmt, ...)
{
    va_list ap;
    if (!(debuglvl & dtype))
 return;
    __builtin_va_start(ap,fmt);
    vdebug(dtype, fmt, ap);
    __builtin_va_end(ap);
}

canonical_original_code:
static __inline__ void debug(unsigned int dtype, char *fmt, ...)
{
    __builtin_va_list ap;
    if (!(debuglvl & dtype))
 return;
    __builtin_va_start(ap,fmt);
    vdebug(dtype, fmt, ap);
    __builtin_va_end(ap);
}

variable_types:
dtype
unsigned int

variable_types:
fmt
char *


repo: jleverenz/cvsps-esr

decompiled_code:
__int64 __fastcall tcp_create_socket(int a1)
{
int v1; // er12
int optval[7]; // [rsp+Ch] [rbp-1Ch] BYREF

optval[0] = 1;
v1 = socket(2, 1, 0);
if ( v1 < 0 )
debug(1LL, (__int64)"tcp: can't create socket");
if ( a1 )
setsockopt(v1, 1, 2, optval, 4u);
optval[0] = 1;
setsockopt(v1, 6, 1, optval, 4u);
debug(64LL, (__int64)"tcp: socket created");
return (unsigned int)v1;
}

canonical_decompiled_code:
__int64 __fastcall func3(int a1)
{
int v1; // er12
int optval[7]; // [rsp+Ch] [rbp-1Ch] BYREF

optval[0] = 1;
v1 = socket(2, 1, 0);
if ( v1 < 0 )
func0(1LL, (__int64)"tcp: can't create socket");
if ( a1 )
setsockopt(v1, 1, 2, optval, 4u);
optval[0] = 1;
setsockopt(v1, 6, 1, optval, 4u);
func0(64LL, (__int64)"tcp: socket created");
return (unsigned int)v1;
}

original_code:
int
tcp_create_socket(int reuse_addr)
{
  int retval;
  int yes = 1;
  if ((retval = socket(2, SOCK_STREAM, 0)) < 0)
  {
    debug(0x0001, "tcp: can't create socket");
  }
  if (reuse_addr)
  {
    setsockopt( retval, 1, 2, (char *)&yes, sizeof(int));
  }
  yes = 1;
  setsockopt (retval,
              IPPROTO_TCP,
              1,
              (char *) &yes,
              sizeof(int));
  debug(0x0040, "tcp: socket created");
  return retval;
}

variable_types: retval int

variable_types: yes int

return_type: int


decompiled_code:
__int64 __fastcall tcp_bind_and_listen(int fd, __int16 a2)
{
socklen_t v2; // edx
__int64 result; // rax
struct sockaddr v4; // [rsp+0h] [rbp-18h] BYREF

*(_DWORD *)&v4.sa_data[10] = 0;
v4.sa_family = 2;
*(_QWORD *)&v4.sa_data[2] = (unsigned int)_bswap_32(0);
*(_WORD *)v4.sa_data = _bswap_16(a2);
if ( bind(fd, &v4, v2) < 0 )
{
debug(1LL, (__int64)"tcp: can't bind to socket");
result = 0xFFFFFFFFLL;
}
else if ( listen(fd, 5) < 0 )
{
debug(1LL, (__int64)"tcp: can't listen on socket");
result = 0xFFFFFFFFLL;
}
else
{
debug(64LL, (__int64)"tcp: socket bound and listening");
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(int fd, __int16 a2)
{
socklen_t v2; // edx
__int64 result; // rax
struct sockaddr v4; // [rsp+0h] [rbp-18h] BYREF

*(_DWORD *)&v4.sa_data[10] = 0;
v4.sa_family = 2;
*(_QWORD *)&v4.sa_data[2] = (unsigned int)func1(0);
*(_WORD *)v4.sa_data = func2(a2);
if ( bind(fd, &v4, v2) < 0 )
{
func0(1LL, (__int64)"tcp: can't bind to socket");
result = 0xFFFFFFFFLL;
}
else if ( listen(fd, 5) < 0 )
{
func0(1LL, (__int64)"tcp: can't listen on socket");
result = 0xFFFFFFFFLL;
}
else
{
func0(64LL, (__int64)"tcp: socket bound and listening");
result = 0LL;
}
return result;
}

original_code:
int
tcp_bind_and_listen(int sockfd, unsigned short tcp_port)
{
  struct sockaddr_in addr;
  memset((char *) &addr, 0, sizeof(struct sockaddr_in));
  addr.sin_family = 2;
  addr.sin_addr.s_addr = htonl(((in_addr_t) 0x00000000));
  addr.sin_port = htons(tcp_port);
  if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
  {
    debug(0x0001, "tcp: can't bind to socket");
    return -1;
  }
  if (listen(sockfd, 5) < 0)
  {
    debug(0x0001, "tcp: can't listen on socket");
    return -1;
  }
  debug(0x0040, "tcp: socket bound and listening");
  return 0;
}

canonical_original_code:
int tcp_bind_and_listen(int sockfd, unsigned short tcp_port)
{
  struct sockaddr_in addr;
  memset((char *) &addr, 0, sizeof(struct sockaddr_in));
  addr.sin_family = 2;
  addr.sin_addr.s_addr = htonl(((unsigned int) 0x00000000));
  addr.sin_port = htons(tcp_port);
  if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
  {
    debug(0x0001, "tcp: can't bind to socket");
    return -1;
  }
  if (listen(sockfd, 5) < 0)
  {
    debug(0x0001, "tcp: can't listen on socket");
    return -1;
  }
  debug(0x0040, "tcp: socket bound and listening");
  return 0;
}

variable_types: sockfd int

variable_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr { unsigned int s_addr; } sin_addr; unsigned char sin_zero[-1]; }

user_defined_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr sin_addr; unsigned char sin_zero[-1]; }

user_defined_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; }


decompiled_code:
__int64 __fastcall tcp_accept_connection(int a1)
{
int v1; // eax
unsigned int v2; // er12
socklen_t addr_len; // [rsp+Ch] [rbp-1Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-18h] BYREF

addr_len = 16;
v1 = accept(a1, &addr, &addr_len);
if ( v1 < 0 )
{
v2 = -1;
if ( *_errno_location() != 4 )
debug(1LL, (__int64)"tcp: error accepting connection");
}
else
{
v2 = v1;
debug(64LL, (__int64)"tcp: got connection (fd=%d)", (unsigned int)v1);
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func5(int a1)
{
int v1; // eax
unsigned int v2; // er12
socklen_t addr_len; // [rsp+Ch] [rbp-1Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-18h] BYREF

addr_len = 16;
v1 = accept(a1, &addr, &addr_len);
if ( v1 < 0 )
{
v2 = -1;
if ( *_errno_location() != 4 )
func0(1LL, (__int64)"tcp: error accepting connection");
}
else
{
v2 = v1;
func0(64LL, (__int64)"tcp: got connection (fd=%d)", (unsigned int)v1);
}
return v2;
}

original_code:
int
tcp_accept_connection(int sockfd)
{
  struct sockaddr_in remaddr;
  socklen_t addrlen;
  int retval;
  addrlen = sizeof(struct sockaddr_in);
  if ((retval = accept(sockfd, (struct sockaddr *) &remaddr, &addrlen)) < 0)
  {
    if ((*__errno_location ()) != 4 )
      debug(0x0001, "tcp: error accepting connection");
    return -1;
  }
  debug(0x0040, "tcp: got connection (fd=%d)", retval);
  return retval;
}

canonical_original_code:
int tcp_accept_connection(int sockfd)
{
  struct sockaddr_in remaddr;
  unsigned int addrlen;
  int retval;
  addrlen = sizeof(struct sockaddr_in);
  if ((retval = accept(sockfd, (struct sockaddr *) &remaddr, &addrlen)) < 0)
  {
    if ((*__errno_location ()) != 4 )
      debug(0x0001, "tcp: error accepting connection");
    return -1;
  }
  debug(0x0040, "tcp: got connection (fd=%d)", retval);
  return retval;
}

variable_types:
addrlen
unsigned int


decompiled_code:
__int64 __fastcall tcp_get_client_ip(int a1)
{
socklen_t len; // [rsp+Ch] [rbp-1Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-18h] BYREF

len = 16;
if ( getpeername(a1, &addr, &len) >= 0 )
return _bswap_32(*(unsigned int *)&addr.sa_data[2]);
debug(1LL, (__int64)"tcp: error getting remote's ip address");
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func6(int a1)
{
socklen_t len; // [rsp+Ch] [rbp-1Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-18h] BYREF

len = 16;
if ( getpeername(a1, &addr, &len) >= 0 )
return func1(*(unsigned int *)&addr.sa_data[2]);
func0(1LL, (__int64)"tcp: error getting remote's ip address");
return 0LL;
}

original_code:
unsigned int
tcp_get_client_ip(int fd)
{
  struct sockaddr_in remaddr;
  socklen_t addrlen;
  int retval;
  unsigned int saddr;
  addrlen = sizeof(struct sockaddr_in);
  if ((retval = getpeername(fd, (struct sockaddr *) &remaddr, &addrlen)) < 0)
  {
    debug(0x0001, "tcp: error getting remote's ip address");
    return 0;
  }
  saddr = ntohl(remaddr.sin_addr.s_addr);
  return saddr;
}

canonical_original_code:
unsigned int tcp_get_client_ip(int fd)
{
  struct sockaddr_in remaddr;
  unsigned int addrlen;
  int retval;
  unsigned int saddr;
  addrlen = sizeof(struct sockaddr_in);
  if ((retval = getpeername(fd, (struct sockaddr *) &remaddr, &addrlen)) < 0)
  {
    debug(0x0001, "tcp: error getting remote's ip address");
    return 0;
  }
  saddr = ntohl(remaddr.sin_addr.s_addr);
  return saddr;
}

variable_types: fd int

variable_types:
saddr
unsigned int

return_type: unsigned int


decompiled_code:
__int64 __fastcall convert_address(struct in_addr *a1, const char *a2)
{
unsigned int v2; // er12
struct hostent *v4; // rbp
int v5; // eax
struct in_addr inp; // [rsp+Ch] [rbp-12Ch] BYREF
char v7[296]; // [rsp+10h] [rbp-128h] BYREF

if ( inet_aton(a2, &inp) )
{
v2 = 0;
a1->s_addr = inp.s_addr;
}
else
{
v2 = 0;
v4 = gethostbyname(a2);
if ( !v4 )
{
v5 = *_h_errno_location();
if ( v5 == 3 )
{
strcpy(v7, "NO_RECOVERY");
}
else if ( v5 > 3 )
{
if ( v5 == 4 )
strcpy(v7, "NO_ADDRESS");
}
else if ( v5 == 1 )
{
strcpy(v7, "HOST_NOT_FOUND");
}
else if ( v5 == 2 )
{
strcpy(v7, "TRY_AGAIN");
}
v2 = -1;
debug(1LL, (__int64)"gethostbyname failed for %s: %s", a2, v7);
}
*(_QWORD *)&a1->s_addr = **(_QWORD **)v4->h_addr_list;
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func7(struct in_addr *a1, const char *a2)
{
unsigned int v2; // er12
struct hostent *v4; // rbp
int v5; // eax
struct in_addr inp; // [rsp+Ch] [rbp-12Ch] BYREF
char v7[296]; // [rsp+10h] [rbp-128h] BYREF

if ( inet_aton(a2, &inp) )
{
v2 = 0;
a1->s_addr = inp.s_addr;
}
else
{
v2 = 0;
v4 = gethostbyname(a2);
if ( !v4 )
{
v5 = *_h_errno_location();
if ( v5 == 3 )
{
strcpy(v7, "NO_RECOVERY");
}
else if ( v5 > 3 )
{
if ( v5 == 4 )
strcpy(v7, "NO_ADDRESS");
}
else if ( v5 == 1 )
{
strcpy(v7, "HOST_NOT_FOUND");
}
else if ( v5 == 2 )
{
strcpy(v7, "TRY_AGAIN");
}
v2 = -1;
func0(1LL, (__int64)"gethostbyname failed for %s: %s", a2, v7);
}
*(_QWORD *)&a1->s_addr = **(_QWORD **)v4->h_addr_list;
}
return v2;
}

original_code:
int
convert_address(long *dest, const char *addr_str)
{
  struct in_addr ip;
  int retval = 0;
  char errstr[256];
  if ( inet_aton(addr_str, &ip) )
  {
    memcpy(dest, &ip.s_addr, sizeof(ip.s_addr));
  }
  else
  {
    struct hostent *host;
    if ((host = gethostbyname(addr_str)) == ((void *)0))
    {
      switch((*__h_errno_location ()))
      {
      case 1:
 strcpy(errstr, "HOST_NOT_FOUND");
 break;
      case 4:
 strcpy(errstr, "NO_ADDRESS");
 break;
      case 3:
 strcpy(errstr, "NO_RECOVERY");
 break;
      case 2:
 strcpy(errstr, "TRY_AGAIN");
 break;
      }
      debug(0x0001, "gethostbyname failed for %s: %s", addr_str, errstr);
      retval = -1;
    }
    memcpy(dest, host->h_addr_list[0], sizeof(unsigned long));
  }
  return retval;
}

canonical_original_code:
int convert_address(long *dest, char *addr_str)
{
  struct in_addr ip;
  int retval = 0;
  char errstr[256];
  if ( inet_aton(addr_str, &ip) )
  {
    memcpy(dest, &ip.s_addr, sizeof(ip.s_addr));
  }
  else
  {
    struct hostent *host;
    if ((host = gethostbyname(addr_str)) == ((void *)0))
    {
      switch((*__h_errno_location ()))
      {
      case 1:
 strcpy(errstr, "HOST_NOT_FOUND");
 break;
      case 4:
 strcpy(errstr, "NO_ADDRESS");
 break;
      case 3:
 strcpy(errstr, "NO_RECOVERY");
 break;
      case 2:
 strcpy(errstr, "TRY_AGAIN");
 break;
      }
      debug(0x0001, "gethostbyname failed for %s: %s", addr_str, errstr);
      retval = -1;
    }
    memcpy(dest, host->h_addr_list[0], sizeof(unsigned long));
  }
  return retval;
}

variable_types:
dest
long *

variable_types:
ip
struct in_addr { unsigned int s_addr; }

variable_types:
errstr
char [256]

variable_types: struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; } *


decompiled_code:
__int64 __fastcall tcp_connect(int fd, const char *a2, unsigned __int16 a3)
{
socklen_t v4; // edx
__int64 result; // rax
__int64 v6; // [rsp+8h] [rbp-30h] BYREF
struct sockaddr v7; // [rsp+10h] [rbp-28h] BYREF

if ( (int)convert_address((struct in_addr *)&v6, a2) < 0 )
return 0xFFFFFFFFLL;
*(_QWORD *)&v7.sa_data[6] = 0LL;
v7.sa_family = 2;
*(_DWORD *)&v7.sa_data[2] = v6;
*(_WORD *)v7.sa_data = _bswap_16(a3);
if ( connect(fd, &v7, v4) < 0 )
{
debug(1LL, (__int64)"connect error");
result = 0xFFFFFFFFLL;
}
else
{
debug(32LL, (__int64)"tcp: connection established on port %d", a3);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(int fd, const char *a2, unsigned __int16 a3)
{
socklen_t v4; // edx
__int64 result; // rax
__int64 v6; // [rsp+8h] [rbp-30h] BYREF
struct sockaddr v7; // [rsp+10h] [rbp-28h] BYREF

if ( (int)func7((struct in_addr *)&v6, a2) < 0 )
return 0xFFFFFFFFLL;
*(_QWORD *)&v7.sa_data[6] = 0LL;
v7.sa_family = 2;
*(_DWORD *)&v7.sa_data[2] = v6;
*(_WORD *)v7.sa_data = func2(a3);
if ( connect(fd, &v7, v4) < 0 )
{
func0(1LL, (__int64)"connect error");
result = 0xFFFFFFFFLL;
}
else
{
func0(32LL, (__int64)"tcp: connection established on port %d", a3);
result = 0LL;
}
return result;
}

original_code:
int
tcp_connect(int sockfd, const char *rem_addr, unsigned short port)
{
  struct sockaddr_in addr;
  int addrlen;
  long ipno;
  if ( convert_address(&ipno , rem_addr) < 0 )
  {
    return -1;
  }
  addrlen = sizeof(struct sockaddr_in);
  memset((char *) &addr, 0, sizeof(struct sockaddr_in));
  addr.sin_family = 2;
  addr.sin_addr.s_addr = ipno;
  addr.sin_port = htons(port);
  if (connect(sockfd, (struct sockaddr *)&addr, addrlen) < 0)
  {
    debug(0x0001, "connect error");
    return -1;
  }
  debug(0x0020, "tcp: connection established on port %d", port);
  return 0;
}

canonical_original_code:
int tcp_connect(int sockfd, char *rem_addr, unsigned short port)
{
  struct sockaddr_in addr;
  int addrlen;
  long ipno;
  if ( convert_address(&ipno , rem_addr) < 0 )
  {
    return -1;
  }
  addrlen = sizeof(struct sockaddr_in);
  memset((char *) &addr, 0, sizeof(struct sockaddr_in));
  addr.sin_family = 2;
  addr.sin_addr.s_addr = ipno;
  addr.sin_port = htons(port);
  if (connect(sockfd, (struct sockaddr *)&addr, addrlen) < 0)
  {
    debug(0x0001, "connect error");
    return -1;
  }
  debug(0x0020, "tcp: connection established on port %d", port);
  return 0;
}

variable_types:
port
unsigned short

variable_types: addrlen int

variable_types: ipno long


decompiled_code:
__int64 __fastcall tcp_get_local_address(int a1, _DWORD *a2, __int16 *a3)
{
int v4; // eax
__int16 v5; // di
__int64 result; // rax
socklen_t len; // [rsp+Ch] [rbp-2Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-28h] BYREF

len = 16;
if ( getsockname(a1, &addr, &len) < 0 )
{
debug(1LL, (__int64)"getsockname failed");
result = 0xFFFFFFFFLL;
}
else
{
v4 = _bswap_32(*(unsigned int *)&addr.sa_data[2]);
v5 = *(_WORD *)addr.sa_data;
*a2 = v4;
*a3 = _bswap_16(v5);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(int a1, _DWORD *a2, __int16 *a3)
{
int v4; // eax
__int16 v5; // di
__int64 result; // rax
socklen_t len; // [rsp+Ch] [rbp-2Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-28h] BYREF

len = 16;
if ( getsockname(a1, &addr, &len) < 0 )
{
func0(1LL, (__int64)"getsockname failed");
result = 0xFFFFFFFFLL;
}
else
{
v4 = func1(*(unsigned int *)&addr.sa_data[2]);
v5 = *(_WORD *)addr.sa_data;
*a2 = v4;
*a3 = func2(v5);
result = 0LL;
}
return result;
}

original_code:
int tcp_get_local_address(int sockfd, unsigned int *ip, unsigned short *port)
{
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(struct sockaddr_in);
    if(getsockname(sockfd, (struct sockaddr *)&addr, &addrlen) < 0)
    {
 debug(0x0001, "getsockname failed" );
 return -1;
    }
    *ip = ntohl( addr.sin_addr.s_addr );
    *port = ntohs( addr.sin_port );
    return 0;
}

canonical_original_code:
int tcp_get_local_address(int sockfd, unsigned int *ip, unsigned short *port)
{
    struct sockaddr_in addr;
    unsigned int addrlen = sizeof(struct sockaddr_in);
    if(getsockname(sockfd, (struct sockaddr *)&addr, &addrlen) < 0)
    {
 debug(0x0001, "getsockname failed" );
 return -1;
    }
    *ip = ntohl( addr.sin_addr.s_addr );
    *port = ntohs( addr.sin_port );
    return 0;
}

variable_types:
ip
unsigned int *

variable_types:
port
unsigned short *


original_code:
static int get_int_substr(const char * str, const regmatch_t * p)
{
    char buff[256];
    if(p->rm_so == -1)
     return 0;
    if(p->rm_eo - p->rm_so >= sizeof(buff))
     return 0;
    memcpy(buff, str + p->rm_so, p->rm_eo - p->rm_so);
    buff[p->rm_eo - p->rm_so] = 0;
    return atoi(buff);
}

canonical_original_code:
static int get_int_substr(char *str, struct regmatch_t *p)
{
    char buff[256];
    if(p->rm_so == -1)
     return 0;
    if(p->rm_eo - p->rm_so >= sizeof(buff))
     return 0;
    memcpy(buff, str + p->rm_so, p->rm_eo - p->rm_so);
    buff[p->rm_eo - p->rm_so] = 0;
    return atoi(buff);
}

variable_types:
str
char *

variable_types: struct regmatch_t { int rm_so; int rm_eo; } *

variable_types:
buff
char [256]


decompiled_code:
time_t __fastcall mktime_utc(struct tm *tp, char *value)
{
char *v2; // rbp
time_t v3; // r12

v2 = getenv("TZ");
setenv("TZ", value, 1);
tzset();
v3 = mktime(tp);
if ( v2 )
setenv("TZ", v2, 1);
else
unsetenv("TZ");
tzset();
return v3;
}

canonical_decompiled_code:
time_t __fastcall func2(struct tm *tp, char *value)
{
char *v2; // rbp
time_t v3; // r12

v2 = getenv("TZ");
setenv("TZ", value, 1);
tzset();
v3 = mktime(tp);
if ( v2 )
setenv("TZ", v2, 1);
else
unsetenv("TZ");
tzset();
return v3;
}

original_code:
static time_t mktime_utc(struct tm * tm, const char* tzbuf)
{
    char * old_tz = getenv("TZ");
    time_t ret;
    setenv("TZ", tzbuf, 1);
    tzset();
    ret = mktime(tm);
    if (old_tz)
 setenv("TZ", old_tz, 1);
    else
 unsetenv("TZ");
    tzset();
    return ret;
}

canonical_original_code:
static long mktime_utc(struct tm *tm, char *tzbuf)
{
    char *old_tz = getenv("TZ");
    long ret;
    setenv("TZ", tzbuf, 1);
    tzset();
    ret = mktime(tm);
    if (old_tz)
 setenv("TZ", old_tz, 1);
    else
 unsetenv("TZ");
    tzset();
    return ret;
}

variable_types: struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; long tm_gmtoff; char *tm_zone; } *

variable_types:
tzbuf
char *

variable_types: ret long

return_type: long


chop

decompiled_code:
const char *__fastcall chop(const char *a1)
{
const char *i; // rax

for ( i = &a1[strlen(a1) - 1]; a1 <= i; *i-- = 0 )
{
if ( *i != 10 && *i != 13 )
break;
}
return a1;
}

canonical_decompiled_code:
const char *__fastcall func3(const char *a1)
{
const char *i; // rax

for ( i = &a1[strlen(a1) - 1]; a1 <= i; *i-- = 0 )
{
if ( *i != 10 && *i != 13 )
break;
}
return a1;
}

original_code:
char *chop( char* src )
{
    char* p = src + strlen(src) - 1;
    while( p >= src )
    {
 if ( *p == '\n' || *p == '\r' )
 {
     *p-- = 0;
 }
 else
 {
     break;
 }
    }
    return( src );
}

canonical_original_code:
char *chop(char *src)
{
    char *p = src + strlen(src) - 1;
    while( p >= src )
    {
 if ( *p == '\n' || *p == '\r' )
 {
     *p-- = 0;
 }
 else
 {
     break;
 }
    }
    return( src );
}

variable_types:
src
char *

variable_types:
p
char *

return_type: char *


decompiled_code:
char *get_cvsps_dir()
{
char *v1; // rcx
struct stat v2; // [rsp-18h] [rbp-98h] BYREF

if ( prefix_4 )
return &prefix_4;
v1 = getenv("HOME");
if ( !v1 )
{
debug(2LL, (__int64)"HOME environment variable not set");
exit(1);
}
if ( snprintf(&prefix_4, 0x1000uLL, "%s/%s", v1, ".cvsps") > 4095 )
{
debug(2LL, (__int64)"prefix buffer overflow");
exit(1);
}
if ( stat(&prefix_4, &v2) < 0 )
{
if ( mkdir(&prefix_4, 0x1FFu) < 0 )
{
debug(1LL, (__int64)"Cannot create the cvsps directory '%s'", ".cvsps");
exit(1);
}
return &prefix_4;
}
if ( (v2.st_mode & 0xF000) == 0x4000 )
return &prefix_4;
debug(2LL, (__int64)"cvsps directory '%s' is not a directory!", ".cvsps");
return &prefix_4;
}

canonical_decompiled_code:
char *func5()
{
char *v1; // rcx
struct stat v2; // [rsp-18h] [rbp-98h] BYREF

if ( prefix_4 )
return &prefix_4;
v1 = getenv("HOME");
if ( !v1 )
{
func0(2LL, (__int64)"HOME environment variable not set");
exit(1);
}
if ( snprintf(&prefix_4, 0x1000uLL, "%s/%s", v1, ".cvsps") > 4095 )
{
func0(2LL, (__int64)"prefix buffer overflow");
exit(1);
}
if ( stat(&prefix_4, &v2) < 0 )
{
if ( mkdir(&prefix_4, 0x1FFu) < 0 )
{
func0(1LL, (__int64)"Cannot create the cvsps directory '%s'", ".cvsps");
exit(1);
}
return &prefix_4;
}
if ( (v2.st_mode & 0xF000) == 0x4000 )
return &prefix_4;
func0(2LL, (__int64)"cvsps directory '%s' is not a directory!", ".cvsps");
return &prefix_4;
}

original_code:
char *get_cvsps_dir()
{
    struct stat sbuf;
    static char prefix[4096];
    const char * home;
    if (prefix[0])
 return prefix;
    if (!(home = getenv("HOME")))
    {
 debug(0x0002, "HOME environment variable not set");
 exit(1);
    }
    if (snprintf(prefix, 4096, "%s/%s", home, ".cvsps") >= 4096)
    {
 debug(0x0002, "prefix buffer overflow");
 exit(1);
    }
    if (stat(prefix, &sbuf) < 0)
    {
 int ret;
 ret = mkdir(prefix, 0777);
 if (ret < 0)
 {
     debug(0x0001, "Cannot create the cvsps directory '%s'", ".cvsps");
     exit(1);
 }
    }
    else
    {
 if (!(((((sbuf.st_mode)) & 0170000) == (0040000))))
     debug(0x0002, "cvsps directory '%s' is not a directory!", ".cvsps");
    }
    return prefix;
}

canonical_original_code:
char *get_cvsps_dir()
{
    struct stat sbuf;
    static char prefix[4096];
    char *home;
    if (prefix[0])
 return prefix;
    if (!(home = getenv("HOME")))
    {
 debug(0x0002, "HOME environment variable not set");
 exit(1);
    }
    if (snprintf(prefix, 4096, "%s/%s", home, ".cvsps") >= 4096)
    {
 debug(0x0002, "prefix buffer overflow");
 exit(1);
    }
    if (stat(prefix, &sbuf) < 0)
    {
 int ret;
 ret = mkdir(prefix, 0777);
 if (ret < 0)
 {
     debug(0x0001, "Cannot create the cvsps directory '%s'", ".cvsps");
     exit(1);
 }
    }
    else
    {
 if (!(((((sbuf.st_mode)) & 0170000) == (0040000))))
     debug(0x0002, "cvsps directory '%s' is not a directory!", ".cvsps");
    }
    return prefix;
}

variable_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }

variable_types:
prefix
char [4096]

variable_types:
home
char *

variable_types: ret int

user_defined_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }


xstrdup

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

if ( !a1 )
_assert_fail("str", "util.c", 0x85u, "xstrdup");
result = strdup(a1);
if ( !result )
{
debug(1LL, (__int64)"strdup failed");
exit(1);
}
return result;
}

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

if ( !a1 )
_assert_fail("str", "util.c", 0x85u, "xstrdup");
result = strdup(a1);
if ( !result )
{
func0(1LL, (__int64)"strdup failed");
exit(1);
}
return result;
}

original_code:
char *xstrdup(char const *str)
{
    char *ret;
    ((void) sizeof ((str) ? 1 : 0), __extension__ ({ if (str) ; else __assert_fail ("str", "util.c", 133, __extension__ __PRETTY_FUNCTION__); }));
    ret = strdup(str);
    if (!ret)
    {
 debug(0x0001, "strdup failed");
 exit(1);
    }
    return ret;
}

canonical_original_code:
char *xstrdup(char *str)
{
    char *ret;
    ((void) sizeof ((str) ? 1 : 0), __extension__ ({ if (str) ; else __assert_fail ("str", "util.c", 133, __extension__ __PRETTY_FUNCTION__); }));
    ret = strdup(str);
    if (!ret)
    {
 debug(0x0001, "strdup failed");
 exit(1);
    }
    return ret;
}

variable_types:
ret
char *


strzncpy

decompiled_code:
char *__fastcall strzncpy(char *a1, const char *a2, int a3)
{
__int64 v3; // rbx
char *result; // rax

v3 = a3;
result = strncpy(a1, a2, a3);
result[v3 - 1] = 0;
return result;
}

canonical_decompiled_code:
char *__fastcall func7(char *a1, const char *a2, int a3)
{
__int64 v3; // rbx
char *result; // rax

v3 = a3;
result = strncpy(a1, a2, a3);
result[v3 - 1] = 0;
return result;
}

original_code:
void strzncpy(char * dst, const char * src, int n)
{
    strncpy(dst, src, n);
    dst[n - 1] = 0;
}

canonical_original_code:
void strzncpy(char *dst, char *src, int n)
{
    strncpy(dst, src, n);
    dst[n - 1] = 0;
}

variable_types:
dst
char *

variable_types: n int

return_type: void


decompiled_code:
char *__fastcall get_string(const void *a1)
{
void *v1; // rax
char *v3; // r12

if ( !a1 )
return 0LL;
v1 = tfind(a1, &string_tree, (__compar_fn_t)&strcmp);
if ( v1 )
return *(char **)v1;
v3 = xstrdup((const char *)a1);
*(_QWORD *)tsearch(v3, &string_tree, (__compar_fn_t)&strcmp) = v3;
return v3;
}

canonical_decompiled_code:
char *__fastcall func8(const void *a1)
{
void *v1; // rax
char *v3; // r12

if ( !a1 )
return 0LL;
v1 = tfind(a1, &string_tree, (__compar_fn_t)&strcmp);
if ( v1 )
return *(char **)v1;
v3 = func6((const char *)a1);
*(_QWORD *)tsearch(v3, &string_tree, (__compar_fn_t)&strcmp) = v3;
return v3;
}

original_code:
char *get_string(char const *str)
{
    char ** res;
    if (!str)
 return ((void *)0);
    res = (char **)tfind(str, &string_tree, (compare_func)strcmp);
    if (!res)
    {
 char *key = xstrdup(str);
 res = (char **)tsearch(key, &string_tree, (compare_func)strcmp);
 *res = key;
    }
    return *res;
}

canonical_original_code:
char *get_string(char *str)
{
    char **res;
    if (!str)
 return ((void *)0);
    res = (char **)tfind(str, &string_tree, (int (*)(void *, void *))strcmp);
    if (!res)
    {
 char *key = xstrdup(str);
 res = (char **)tsearch(key, &string_tree, (int (*)(void *, void *))strcmp);
 *res = key;
    }
    return *res;
}

variable_types:
res
char **

variable_types:
key
char *


decompiled_code:
int timing_start()
{
return gettimeofday(&start_time, 0LL);
}

canonical_decompiled_code:
int func10()
{
return gettimeofday(&start_time, 0LL);
}

original_code:
void timing_start()
{
    gettimeofday(&start_time, ((void *)0));
}


decompiled_code:
int __fastcall timing_stop(const char *a1)
{
__time_t v1; // rdx
bool v2; // sf
__suseconds_t v3; // rcx
struct timeval v5; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v5, 0LL);
v1 = v5.tv_sec - start_time.tv_sec;
v3 = v5.tv_usec - start_time.tv_usec;
v2 = v5.tv_usec - start_time.tv_usec < 0;
v5.tv_sec -= start_time.tv_sec;
v5.tv_usec -= start_time.tv_usec;
if ( v2 )
{
--v1;
v3 += 1000000LL;
v5.tv_sec = v1;
v5.tv_usec = v3;
}
return printf("Elapsed time for %s: %d.%06d\n", a1, v1, v3);
}

canonical_decompiled_code:
int __fastcall func11(const char *a1)
{
__time_t v1; // rdx
bool v2; // sf
__suseconds_t v3; // rcx
struct timeval v5; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v5, 0LL);
v1 = v5.tv_sec - start_time.tv_sec;
v3 = v5.tv_usec - start_time.tv_usec;
v2 = v5.tv_usec - start_time.tv_usec < 0;
v5.tv_sec -= start_time.tv_sec;
v5.tv_usec -= start_time.tv_usec;
if ( v2 )
{
--v1;
v3 += 1000000LL;
v5.tv_sec = v1;
v5.tv_usec = v3;
}
return printf("Elapsed time for %s: %d.%06d\n", a1, v1, v3);
}

original_code:
void timing_stop(const char * msg)
{
    struct timeval stop_time;
    gettimeofday(&stop_time, ((void *)0));
    stop_time.tv_sec -= start_time.tv_sec;
    stop_time.tv_usec -= start_time.tv_usec;
    if (stop_time.tv_usec < 0)
 stop_time.tv_sec--,stop_time.tv_usec += 1000000;
    printf("Elapsed time for %s: %d.%06d\n", msg, (int)stop_time.tv_sec, (int)stop_time.tv_usec);
}

canonical_original_code:
void timing_stop(char *msg)
{
    struct timeval stop_time;
    gettimeofday(&stop_time, ((void *)0));
    stop_time.tv_sec -= start_time.tv_sec;
    stop_time.tv_usec -= start_time.tv_usec;
    if (stop_time.tv_usec < 0)
 stop_time.tv_sec--,stop_time.tv_usec += 1000000;
    printf("Elapsed time for %s: %d.%06d\n", msg, (int)stop_time.tv_sec, (int)stop_time.tv_usec);
}

variable_types:
msg
char *

variable_types: struct timeval { long tv_sec; long tv_usec; }


original_code:
int escape_filename(char * dst, int len, const char * src)
{
    static char * naughty_chars = " \\\"'@<>=;|&()#$`?*[!:{";
    if (len > 0)
    {
 while (len > 1 && *src)
 {
     if (strchr(naughty_chars, *src))
     {
  if (len == 2)
      break;
  *dst++ = '\\';
  len--;
     }
     *dst++ = *src++;
     len--;
 }
 *dst = 0;
    }
    return (*src == 0) ? 0 : -1;
}

canonical_original_code:
int escape_filename(char *dst, int len, char *src)
{
    static char *naughty_chars = " \\\"'@<>=;|&()#$`?*[!:{";
    if (len > 0)
    {
 while (len > 1 && *src)
 {
     if (strchr(naughty_chars, *src))
     {
  if (len == 2)
      break;
  *dst++ = '\\';
  len--;
     }
     *dst++ = *src++;
     len--;
 }
 *dst = 0;
    }
    return (*src == 0) ? 0 : -1;
}

variable_types: len int


decompiled_code:
char *__fastcall strcpy_a(char *a1, const char *a2, int a3)
{
char *v3; // rbx
char *result; // rax

v3 = &a1[a3 - 1];
*v3 = 0;
result = strncpy(a1, a2, a3);
if ( *v3 )
{
debug(2LL, (__int64)"FATAL: internal buffer exhausted.");
exit(1);
}
return result;
}

canonical_decompiled_code:
char *__fastcall func13(char *a1, const char *a2, int a3)
{
char *v3; // rbx
char *result; // rax

v3 = &a1[a3 - 1];
*v3 = 0;
result = strncpy(a1, a2, a3);
if ( *v3 )
{
func0(2LL, (__int64)"FATAL: internal buffer exhausted.");
exit(1);
}
return result;
}

original_code:
void strcpy_a(char * dst, const char * src, int n)
{
    dst[n - 1] = 0;
    strncpy(dst, src, n);
    if (dst[n - 1] != 0) {
 debug(0x0002, "FATAL: internal buffer exhausted.");
 exit(1);
    }
}

canonical_original_code:
void strcpy_a(char *dst, char *src, int n)
{
    dst[n - 1] = 0;
    strncpy(dst, src, n);
    if (dst[n - 1] != 0) {
 debug(0x0002, "FATAL: internal buffer exhausted.");
 exit(1);
    }
}


decompiled_code:
__int64 __fastcall count_hash(__int64 a1, _DWORD *a2, unsigned int *a3)
{
unsigned int v4; // ebx
__int64 result; // rax

v4 = 0;
reset_hash_iterator();
while ( 1 )
{
result = next_hash_entry(a1);
if ( !result )
break;
++v4;
}
*a2 += v4;
if ( *a3 >= v4 )
v4 = *a3;
*a3 = v4;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, _DWORD *a2, unsigned int *a3)
{
unsigned int v4; // ebx
__int64 result; // rax

v4 = 0;
reset_hash_iterator();
while ( 1 )
{
result = next_hash_entry(a1);
if ( !result )
break;
++v4;
}
*a2 += v4;
if ( *a3 >= v4 )
v4 = *a3;
*a3 = v4;
return result;
}

original_code:
static void count_hash(struct hash_table *hash, unsigned int *total,
 unsigned int *max_val)
{
    int counter = 0;
    reset_hash_iterator(hash);
    while (next_hash_entry(hash))
 counter++;
    *total += counter;
    *max_val= ((*max_val) > (counter) ? (*max_val) : (counter));
}

variable_types: struct hash_table { int ht_size; struct list_head { struct list_head *next; } *ht_lists; int iterator; struct list_head *iterator_ptr; } *

variable_types:
total
unsigned int *

variable_types: counter int

user_defined_types: struct hash_table { int ht_size; struct list_head *ht_lists; int iterator; struct list_head *iterator_ptr; }


decompiled_code:
void __fastcall stat_ps_tree_node(const void *nodep, __int64 value, __int64 level)
{
__int64 v3; // rbx
unsigned int v4; // eax
int v5; // edx
unsigned int v6; // eax
_QWORD *v7; // rcx
int v8; // edx
_QWORD *v9; // rax
unsigned int i; // edx
__int64 v11[4]; // [rsp+8h] [rbp-20h] BYREF

if ( !author_hash )
author_hash = create_hash_table(1023LL, value, level);
if ( (value & 0xFFFFFFFD) == 1 )
{
v3 = *(_QWORD *)nodep;
++num_patch_sets;
v11[0] = 0LL;
if ( (int)put_hash_object_ex(author_hash, *(_QWORD *)(v3 + 40), *(_QWORD *)(v3 + 40), 0LL, 0LL, v11) >= 0 && !v11[0] )
{
v4 = strlen(*(const char **)(v3 + 40));
++num_authors;
v5 = v4;
if ( max_author_len >= v4 )
v5 = max_author_len;
total_author_len += v4;
max_author_len = v5;
}
v6 = strlen(*(const char **)(v3 + 32));
v7 = (_QWORD *)(v3 + 80);
v8 = v6;
if ( max_descr_len >= v6 )
v8 = max_descr_len;
total_descr_len += v6;
v9 = *(_QWORD **)(v3 + 80);
max_descr_len = v8;
for ( i = 0; v9 != v7; ++i )
v9 = (_QWORD *)*v9;
num_ps_member += i;
if ( max_ps_member_in_ps >= i )
i = max_ps_member_in_ps;
max_ps_member_in_ps = i;
}
}

canonical_decompiled_code:
void __fastcall func1(const void *nodep, __int64 value, __int64 level)
{
__int64 v3; // rbx
unsigned int v4; // eax
int v5; // edx
unsigned int v6; // eax
_QWORD *v7; // rcx
int v8; // edx
_QWORD *v9; // rax
unsigned int i; // edx
__int64 v11[4]; // [rsp+8h] [rbp-20h] BYREF

if ( !author_hash )
author_hash = create_hash_table(1023LL, value, level);
if ( (value & 0xFFFFFFFD) == 1 )
{
v3 = *(_QWORD *)nodep;
++num_patch_sets;
v11[0] = 0LL;
if ( (int)put_hash_object_ex(author_hash, *(_QWORD *)(v3 + 40), *(_QWORD *)(v3 + 40), 0LL, 0LL, v11) >= 0 && !v11[0] )
{
v4 = strlen(*(const char **)(v3 + 40));
++num_authors;
v5 = v4;
if ( max_author_len >= v4 )
v5 = max_author_len;
total_author_len += v4;
max_author_len = v5;
}
v6 = strlen(*(const char **)(v3 + 32));
v7 = (_QWORD *)(v3 + 80);
v8 = v6;
if ( max_descr_len >= v6 )
v8 = max_descr_len;
total_descr_len += v6;
v9 = *(_QWORD **)(v3 + 80);
max_descr_len = v8;
for ( i = 0; v9 != v7; ++i )
v9 = (_QWORD *)*v9;
num_ps_member += i;
if ( max_ps_member_in_ps >= i )
i = max_ps_member_in_ps;
max_ps_member_in_ps = i;
}
}

original_code:
static void stat_ps_tree_node(const void * nodep, const VISIT which, const int depth)
{
    int desc_len;
    PatchSet * ps;
    struct list_head * next;
    int counter;
    void * old;
    if (!author_hash)
 author_hash = create_hash_table(1023);
    switch(which)
    {
    case postorder:
    case leaf:
 ps = *(PatchSet**)nodep;
 num_patch_sets++;
 old = ((void *)0);
 if (put_hash_object_ex(author_hash, ps->author, ps->author, HT_NO_KEYCOPY, ((void *)0), &old) >= 0 && !old)
 {
     int len = strlen(ps->author);
     num_authors++;
     max_author_len = ((max_author_len) > (len) ? (max_author_len) : (len));
     total_author_len += len;
 }
 desc_len = strlen(ps->descr);
 max_descr_len = ((max_descr_len) > (desc_len) ? (max_descr_len) : (desc_len));
 total_descr_len += desc_len;
 counter = 0;
 next = ps->members.next;
 while (next != &ps->members)
 {
     counter++;
     next = next->next;
 }
 num_ps_member += counter;
 max_ps_member_in_ps = ((max_ps_member_in_ps) > (counter) ? (max_ps_member_in_ps) : (counter));
 break;
    default:
 break;
    }
}

canonical_original_code:
static void stat_ps_tree_node(void *nodep, enum VISIT which, int depth)
{
    int desc_len;
    struct _PatchSet *ps;
    struct list_head *next;
    int counter;
    void *old;
    if (!author_hash)
 author_hash = create_hash_table(1023);
    switch(which)
    {
    case postorder:
    case leaf:
 ps = *(struct _PatchSet **)nodep;
 num_patch_sets++;
 old = ((void *)0);
 if (put_hash_object_ex(author_hash, ps->author, ps->author, HT_NO_KEYCOPY, ((void *)0), &old) >= 0 && !old)
 {
     int len = strlen(ps->author);
     num_authors++;
     max_author_len = ((max_author_len) > (len) ? (max_author_len) : (len));
     total_author_len += len;
 }
 desc_len = strlen(ps->descr);
 max_descr_len = ((max_descr_len) > (desc_len) ? (max_descr_len) : (desc_len));
 total_descr_len += desc_len;
 counter = 0;
 next = ps->members.next;
 while (next != &ps->members)
 {
     counter++;
     next = next->next;
 }
 num_ps_member += counter;
 max_ps_member_in_ps = ((max_ps_member_in_ps) > (counter) ? (max_ps_member_in_ps) : (counter));
 break;
    default:
 break;
    }
}

variable_types:
nodep
void *

variable_types: enum VISIT { preorder=0, postorder=1, endorder=2, leaf=3 }

variable_types: depth int

variable_types: struct _PatchSet { int psid; long date; long min_date; long max_date; char *descr; char *author; char *commitid; struct list_head { struct list_head *next; } tags; char *branch; struct list_head members; _Bool branch_add; int funk_factor; int mark; struct list_head branches; struct list_head all_link; struct list_head collision_link; } *

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

variable_types:
old
void *

user_defined_types: struct _PatchSet { int psid; long date; long min_date; long max_date; char *descr; char *author; char *commitid; struct list_head tags; char *branch; struct list_head members; _Bool branch_add; int funk_factor; int mark; struct list_head branches; struct list_head all_link; struct list_head collision_link; }


decompiled_code:
int __fastcall print_statistics(void *root)
{
int v1; // er13
unsigned int v2; // er12
int v3; // ebp
unsigned int v4; // eax
__int64 *v5; // rbx
const char **v6; // rax
const char **v7; // rbx
int v9; // [rsp+18h] [rbp-40h] BYREF
unsigned int v10; // [rsp+1Ch] [rbp-3Ch] BYREF
int v11; // [rsp+20h] [rbp-38h] BYREF
unsigned int v12; // [rsp+24h] [rbp-34h] BYREF
int v13; // [rsp+28h] [rbp-30h] BYREF
unsigned int v14[11]; // [rsp+2Ch] [rbp-2Ch] BYREF

v1 = 0;
v2 = 0;
v3 = 0;
v9 = 0;
v10 = 0;
v11 = 0;
v12 = 0;
v13 = 0;
v14[0] = 0;
puts("Statistics:");
fflush(stdout);
reset_hash_iterator(file_hash);
while ( 1 )
{
v6 = (const char **)next_hash_entry(file_hash);
v7 = v6;
if ( !v6 )
break;
++v1;
v4 = strlen(*v6);
v5 = (__int64 *)v7[1];
if ( v2 < v4 )
v2 = v4;
v3 += v4;
count_hash(v5[1], &v9, &v10);
count_hash(v5[2], &v11, &v12);
count_hash(v5[3], &v13, v14);
}
printf(
"Num files: %u\nMax filename len: %u, Average filename len: %.2f\n",
(unsigned int)v1,
v2,
(float)((float)v3 / (float)v1));
printf("Max revisions for file: %u, Average revisions for file: %.2f\n", v10, (float)((float)v9 / (float)v1));
printf("Max branches for file: %u, Average branches for file: %.2f\n", v12, (float)((float)v11 / (float)v1));
printf(
"Max branches_sym for file: %u, Average branches_sym for file: %.2f\n",
v14[0],
(float)((float)v13 / (float)v1));
twalk(root, (__action_fn_t)stat_ps_tree_node);
printf("Num patchsets: %u\n", (unsigned int)num_patch_sets);
printf(
"Max PS members in PS: %u\nAverage PS members in PS: %.2f\n",
(unsigned int)max_ps_member_in_ps,
(float)((float)num_ps_member / (float)num_patch_sets));
printf(
"Num authors: %u, Max author len: %u, Avg. author len: %.2f\n",
(unsigned int)num_authors,
(unsigned int)max_author_len,
(float)((float)total_author_len / (float)num_authors));
return printf(
"Max desc len: %u, Avg. desc len: %.2f\n",
(unsigned int)max_descr_len,
(float)((float)total_descr_len / (float)num_patch_sets));
}

canonical_decompiled_code:
int __fastcall func2(void *root)
{
int v1; // er13
unsigned int v2; // er12
int v3; // ebp
unsigned int v4; // eax
__int64 *v5; // rbx
const char **v6; // rax
const char **v7; // rbx
int v9; // [rsp+18h] [rbp-40h] BYREF
unsigned int v10; // [rsp+1Ch] [rbp-3Ch] BYREF
int v11; // [rsp+20h] [rbp-38h] BYREF
unsigned int v12; // [rsp+24h] [rbp-34h] BYREF
int v13; // [rsp+28h] [rbp-30h] BYREF
unsigned int v14[11]; // [rsp+2Ch] [rbp-2Ch] BYREF

v1 = 0;
v2 = 0;
v3 = 0;
v9 = 0;
v10 = 0;
v11 = 0;
v12 = 0;
v13 = 0;
v14[0] = 0;
puts("Statistics:");
fflush(stdout);
reset_hash_iterator(file_hash);
while ( 1 )
{
v6 = (const char **)next_hash_entry(file_hash);
v7 = v6;
if ( !v6 )
break;
++v1;
v4 = strlen(*v6);
v5 = (__int64 *)v7[1];
if ( v2 < v4 )
v2 = v4;
v3 += v4;
func0(v5[1], &v9, &v10);
func0(v5[2], &v11, &v12);
func0(v5[3], &v13, v14);
}
printf(
"Num files: %u\nMax filename len: %u, Average filename len: %.2f\n",
(unsigned int)v1,
v2,
(float)((float)v3 / (float)v1));
printf("Max revisions for file: %u, Average revisions for file: %.2f\n", v10, (float)((float)v9 / (float)v1));
printf("Max branches for file: %u, Average branches for file: %.2f\n", v12, (float)((float)v11 / (float)v1));
printf(
"Max branches_sym for file: %u, Average branches_sym for file: %.2f\n",
v14[0],
(float)((float)v13 / (float)v1));
twalk(root, (__action_fn_t)stat_ps_tree_node);
printf("Num patchsets: %u\n", (unsigned int)num_patch_sets);
printf(
"Max PS members in PS: %u\nAverage PS members in PS: %.2f\n",
(unsigned int)max_ps_member_in_ps,
(float)((float)num_ps_member / (float)num_patch_sets));
printf(
"Num authors: %u, Max author len: %u, Avg. author len: %.2f\n",
(unsigned int)num_authors,
(unsigned int)max_author_len,
(float)((float)total_author_len / (float)num_authors));
return printf(
"Max desc len: %u, Avg. desc len: %.2f\n",
(unsigned int)max_descr_len,
(float)((float)total_descr_len / (float)num_patch_sets));
}

original_code:
void print_statistics(void * ps_tree)
{
    unsigned int num_files = 0, max_file_len = 0, total_file_len = 0;
    unsigned int total_revisions = 0, max_revisions_for_file = 0;
    unsigned int total_branches = 0, max_branches_for_file = 0;
    unsigned int total_branches_sym = 0, max_branches_sym_for_file = 0;
    struct hash_entry *he;
    printf("Statistics:\n");
    fflush(stdout);
    reset_hash_iterator(file_hash);
    while ((he=next_hash_entry(file_hash)))
    {
 int len = strlen(he->he_key);
 CvsFile *file = (CvsFile *)he->he_obj;
 num_files++;
 max_file_len = ((max_file_len) > (len) ? (max_file_len) : (len));
 total_file_len += len;
 count_hash(file->revisions, &total_revisions, &max_revisions_for_file);
 count_hash(file->branches, &total_branches, &max_branches_for_file);
 count_hash(file->branches_sym, &total_branches_sym,
     &max_branches_sym_for_file);
    }
    printf("Num files: %u\nMax filename len: %u, Average filename len: %.2f\n",
     num_files, max_file_len, (float)total_file_len/num_files);
    printf("Max revisions for file: %u, Average revisions for file: %.2f\n",
   max_revisions_for_file, (float)total_revisions/num_files);
    printf("Max branches for file: %u, Average branches for file: %.2f\n",
   max_branches_for_file, (float)total_branches/num_files);
    printf("Max branches_sym for file: %u, Average branches_sym for file: %.2f\n",
   max_branches_sym_for_file, (float)total_branches_sym/num_files);
    twalk(ps_tree, stat_ps_tree_node);
    printf("Num patchsets: %u\n", num_patch_sets);
    printf("Max PS members in PS: %u\nAverage PS members in PS: %.2f\n",
     max_ps_member_in_ps, (float)num_ps_member/num_patch_sets);
    printf("Num authors: %u, Max author len: %u, Avg. author len: %.2f\n",
     num_authors, max_author_len, (float)total_author_len/num_authors);
    printf("Max desc len: %u, Avg. desc len: %.2f\n",
     max_descr_len, (float)total_descr_len/num_patch_sets);
}

canonical_original_code:
void print_statistics(void *ps_tree)
{
    unsigned int num_files = 0; unsigned int max_file_len = 0; unsigned int total_file_len = 0;
    unsigned int total_revisions = 0; unsigned int max_revisions_for_file = 0;
    unsigned int total_branches = 0; unsigned int max_branches_for_file = 0;
    unsigned int total_branches_sym = 0; unsigned int max_branches_sym_for_file = 0;
    struct hash_entry *he;
    printf("Statistics:\n");
    fflush(stdout);
    reset_hash_iterator(file_hash);
    while ((he=next_hash_entry(file_hash)))
    {
 int len = strlen(he->he_key);
 struct _CvsFile *file = (CvsFile *)he->he_obj;
 num_files++;
 max_file_len = ((max_file_len) > (len) ? (max_file_len) : (len));
 total_file_len += len;
 count_hash(file->revisions, &total_revisions, &max_revisions_for_file);
 count_hash(file->branches, &total_branches, &max_branches_for_file);
 count_hash(file->branches_sym, &total_branches_sym,
     &max_branches_sym_for_file);
    }
    printf("Num files: %u\nMax filename len: %u, Average filename len: %.2f\n",
     num_files, max_file_len, (float)total_file_len/num_files);
    printf("Max revisions for file: %u, Average revisions for file: %.2f\n",
   max_revisions_for_file, (float)total_revisions/num_files);
    printf("Max branches for file: %u, Average branches for file: %.2f\n",
   max_branches_for_file, (float)total_branches/num_files);
    printf("Max branches_sym for file: %u, Average branches_sym for file: %.2f\n",
   max_branches_sym_for_file, (float)total_branches_sym/num_files);
    twalk(ps_tree, stat_ps_tree_node);
    printf("Num patchsets: %u\n", num_patch_sets);
    printf("Max PS members in PS: %u\nAverage PS members in PS: %.2f\n",
     max_ps_member_in_ps, (float)num_ps_member/num_patch_sets);
    printf("Num authors: %u, Max author len: %u, Avg. author len: %.2f\n",
     num_authors, max_author_len, (float)total_author_len/num_authors);
    printf("Max desc len: %u, Avg. desc len: %.2f\n",
     max_descr_len, (float)total_descr_len/num_patch_sets);
}

variable_types: struct hash_entry { char *he_key; void *he_obj; struct list_head { struct list_head *next; } he_list; } *

variable_types: struct _CvsFile { char *filename; struct hash_table { int ht_size; struct list_head { struct list_head *next; } *ht_lists; int iterator; struct list_head *iterator_ptr; } *revisions; struct hash_table *branches; struct hash_table *branches_sym; struct hash_table *symbols; _Bool have_branches; } *

user_defined_types: struct hash_entry { char *he_key; void *he_obj; struct list_head he_list; }

user_defined_types: struct _CvsFile { char *filename; struct hash_table *revisions; struct hash_table *branches; struct hash_table *branches_sym; struct hash_table *symbols; _Bool have_branches; }


main

canonical_name: main

repo: jlinnosa/mathprep

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
char *v3; // rax
char *v4; // r15
int v5; // er14
unsigned int v6; // er13
unsigned int i; // er12
unsigned int v8; // ebx
unsigned int v9; // ebp
int v10; // er10
unsigned int v11; // er12
__int64 v12; // r8
int v13; // [rsp+Ch] [rbp-3Ch]

puts("mathprep\n");
init_randomness("mathprep\n", argv);
v3 = (char *)malloc(0x64uLL);
if ( v3 )
{
v4 = v3;
v5 = 0;
v6 = 0;
for ( i = 0; ; i = v8 )
{
do
{
v8 = random_int(1LL, 8LL);
v9 = random_int(1LL, 3LL);
v10 = random_int(1LL, 2LL);
}
while ( v6 == v9 && i == v8 && v5 == v10 );
if ( v10 == 1 )
{
v11 = v8 + v9;
v12 = 43LL;
}
else
{
if ( v10 != 2 )
__assert_fail("0", "mathprep.c", 0x2Eu, "main");
v12 = 45LL;
v11 = v8 - v9;
}
v13 = v10;
snprintf(v4, 0x64uLL, "%i %c %i", v8, v12, v9);
if ( !(unsigned int)ask(v4, v11) )
{
free(v4);
exit(0);
}
v5 = v13;
v6 = v9;
}
}
exit(1);
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
char *v3; // rax
char *v4; // r15
int v5; // er14
unsigned int v6; // er13
unsigned int i; // er12
unsigned int v8; // ebx
unsigned int v9; // ebp
int v10; // er10
unsigned int v11; // er12
__int64 v12; // r8
int v13; // [rsp+Ch] [rbp-3Ch]

puts("mathprep\n");
func8("mathprep\n", argv);
v3 = (char *)malloc(0x64uLL);
if ( v3 )
{
v4 = v3;
v5 = 0;
v6 = 0;
for ( i = 0; ; i = v8 )
{
do
{
v8 = func9(1LL, 8LL);
v9 = func9(1LL, 3LL);
v10 = func9(1LL, 2LL);
}
while ( v6 == v9 && i == v8 && v5 == v10 );
if ( v10 == 1 )
{
v11 = v8 + v9;
v12 = 43LL;
}
else
{
if ( v10 != 2 )
__assert_fail("0", "mathprep.c", 0x2Eu, "main");
v12 = 45LL;
v11 = v8 - v9;
}
v13 = v10;
snprintf(v4, 0x64uLL, "%i %c %i", v8, v12, v9);
if ( !(unsigned int)func7(v4, v11) )
{
free(v4);
exit(0);
}
v5 = v13;
v6 = v9;
}
}
exit(1);
}

original_code:
int main(int argc, char *argv[])
{
 int x, y, op, prev_x, prev_y, prev_op, result;
 char operator, *str;
 printf("mathprep\n\n");
 init_randomness();
 x = y = op = 0;
 if ((str = malloc(100)) == ((void *)0))
  exit(1);
 for (;;) {
  prev_x = x;
  prev_y = y;
  prev_op = op;
  do {
   x = random_int(1, 8);
   y = random_int(1, 3);
   op = random_int(1, 2);
  } while (x == prev_x && y == prev_y && op == prev_op);
  switch (op) {
  case 1:
   operator = '+';
   result = x + y;
   break;
  case 2:
   operator = '-';
   result = x - y;
   break;
  default:
   ((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail ("0", "mathprep.c", 46, __extension__ __PRETTY_FUNCTION__); }));
  };
  snprintf(str, 100, "%i %c %i", x, operator, y);
  if (!ask(str, result))
   break;
 }
 free(str);
 exit(0);
}

canonical_original_code:
int main(int argc, char *argv[])
{
 int x; int y; int op; int prev_x; int prev_y; int prev_op; int result;
 char operator; char *str;
 printf("mathprep\n\n");
 init_randomness();
 x = y = op = 0;
 if ((str = malloc(100)) == ((void *)0))
  exit(1);
 for (;;) {
  prev_x = x;
  prev_y = y;
  prev_op = op;
  do {
   x = random_int(1, 8);
   y = random_int(1, 3);
   op = random_int(1, 2);
  } while (x == prev_x && y == prev_y && op == prev_op);
  switch (op) {
  case 1:
   operator = '+';
   result = x + y;
   break;
  case 2:
   operator = '-';
   result = x - y;
   break;
  default:
   ((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail ("0", "mathprep.c", 46, __extension__ __PRETTY_FUNCTION__); }));
  };
  snprintf(str, 100, "%i %c %i", x, operator, y);
  if (!ask(str, result))
   break;
 }
 free(str);
 exit(0);
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: x int

variable_types: y int

variable_types: op int

variable_types: result int

variable_types: operator char

variable_types:
str
char *


ask

decompiled_code:
__int64 __fastcall ask(const char *a1, int a2)
{
__int64 result; // rax
int v3; // [rsp+Ch] [rbp-1Ch]

while ( 1 )
{
printf("%s = ", a1);
result = __isoc99_scanf();
if ( !(_DWORD)result )
break;
if ( v3 == a2 )
{
puts("Oikein!\n");
return 1LL;
}
puts("Ei ihan. Koita uudestaan!");
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(const char *a1, int a2)
{
__int64 result; // rax
int v3; // [rsp+Ch] [rbp-1Ch]

while ( 1 )
{
printf("%s = ", a1);
result = __isoc99_scanf();
if ( !(_DWORD)result )
break;
if ( v3 == a2 )
{
puts("Oikein!\n");
return 1LL;
}
puts("Ei ihan. Koita uudestaan!");
}
return result;
}

original_code:
int ask(char *str, int result)
{
 int answer;
 for (;;) {
  printf("%s = ", str);
  if (!scanf("%i", &answer))
   return 0;
  if (result == answer) {
   printf("Oikein!\n\n");
   return 1;
  } else {
   printf("Ei ihan. Koita uudestaan!\n");
  }
 }
}

variable_types: answer int


decompiled_code:
void init_randomness()
{
struct timeval v0; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v0, 0LL);
srand(v0.tv_usec);
}

canonical_decompiled_code:
void func8()
{
struct timeval v0; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v0, 0LL);
srand(v0.tv_usec);
}

original_code:
void init_randomness()
{
 struct timeval t;
 gettimeofday(&t, 0);
 srand(t.tv_usec);
 return;
}

variable_types: struct timeval { long tv_sec; long tv_usec; }


decompiled_code:
__int64 __fastcall random_int(int a1, int a2)
{
if ( a2 <= a1 )
__assert_fail("max > min", "tools.c", 0xFu, "random_int");
return (unsigned int)(rand() % (a2 + 1 - a1) + a1);
}

canonical_decompiled_code:
__int64 __fastcall func9(int a1, int a2)
{
if ( a2 <= a1 )
__assert_fail("max > min", "tools.c", 0xFu, "random_int");
return (unsigned int)(rand() % (a2 + 1 - a1) + a1);
}

original_code:
int random_int(int min, int max)
{
 ((void) sizeof ((max > min) ? 1 : 0), __extension__ ({ if (max > min) ; else __assert_fail ("max > min", "tools.c", 15, __extension__ __PRETTY_FUNCTION__); }));
 int range = (max + 1) - min;
 return rand() % range + min;
}

variable_types: min int

variable_types: max int

variable_types: range int


decompiled_code:
void timer_reset()
{
*(&timer + 3) = 0;
}

original_code:
void timer_reset()
{
    timer.regs.div = 0;
    timer.regs.count = 0;
    timer.regs.mod = 0;
    timer.regs.ctrl = 0;
}


decompiled_code:
__int64 __fastcall timer_getbyte(unsigned __int16 a1)
{
__int64 result; // rax

if ( a1 == 0xFF06 )
return *((unsigned __int8 *)&timer + 14);
if ( a1 > 0xFF06u )
{
result = 0LL;
if ( a1 == 0xFF07 )
result = *((unsigned __int8 *)&timer + 15);
}
else
{
result = *((unsigned __int8 *)&timer + 12);
if ( a1 != 0xFF04 )
{
if ( a1 == 0xFF05 )
result = *((unsigned __int8 *)&timer + 13);
else
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned __int16 a1)
{
__int64 result; // rax

if ( a1 == 0xFF06 )
return *((unsigned __int8 *)&timer + 14);
if ( a1 > 0xFF06u )
{
result = 0LL;
if ( a1 == 0xFF07 )
result = *((unsigned __int8 *)&timer + 15);
}
else
{
result = *((unsigned __int8 *)&timer + 12);
if ( a1 != 0xFF04 )
{
if ( a1 == 0xFF05 )
result = *((unsigned __int8 *)&timer + 13);
else
result = 0LL;
}
}
return result;
}

original_code:
Byte timer_getbyte(Word addr)
{
    switch (addr)
    {
        case 0xFF04:
            return timer.regs.div;
        case 0xFF05:
            return timer.regs.count;
        case 0xFF06:
            return timer.regs.mod;
        case 0xFF07:
            return timer.regs.ctrl;
        default:
            return 0;
    }
}

canonical_original_code:
unsigned char timer_getbyte(unsigned short addr)
{
    switch (addr)
    {
        case 0xFF04:
            return timer.regs.div;
        case 0xFF05:
            return timer.regs.count;
        case 0xFF06:
            return timer.regs.mod;
        case 0xFF07:
            return timer.regs.ctrl;
        default:
            return 0;
    }
}

variable_types:
addr
unsigned short

return_type: unsigned char


decompiled_code:
void __fastcall timer_putbyte(unsigned __int16 a1, char a2)
{
if ( a1 == 0xFF06 )
{
*((_BYTE *)&timer + 14) = a2;
}
else if ( a1 > 0xFF06u )
{
if ( a1 == 0xFF07 )
*((_BYTE *)&timer + 15) = a2;
}
else if ( a1 == 0xFF04 )
{
*((_BYTE *)&timer + 12) = a2;
}
else if ( a1 == 0xFF05 )
{
*((_BYTE *)&timer + 13) = a2;
}
}

original_code:
void timer_putbyte(Word addr, Byte value)
{
    switch (addr)
    {
        case 0xFF04:
            timer.regs.div = value;
            break;
        case 0xFF05:
            timer.regs.count = value;
            break;
        case 0xFF06:
            timer.regs.mod = value;
            break;
        case 0xFF07:
            timer.regs.ctrl = value;
            break;
    }
}

canonical_original_code:
void timer_putbyte(unsigned short addr, unsigned char value)
{
    switch (addr)
    {
        case 0xFF04:
            timer.regs.div = value;
            break;
        case 0xFF05:
            timer.regs.count = value;
            break;
        case 0xFF06:
            timer.regs.mod = value;
            break;
        case 0xFF07:
            timer.regs.ctrl = value;
            break;
    }
}

variable_types:
value
unsigned char


decompiled_code:
__int64 __fastcall timer_update(unsigned __int8 a1)
{
int v1; // edi
int v2; // edx
char v3; // r8
int v4; // eax
char v5; // r9
char v6; // cl
int v7; // esi
__int64 result; // rax
bool v9; // zf

v1 = *(&timer + 1) + a1;
v2 = timer;
v3 = 0;
*(&timer + 1) = v1;
v4 = *(&timer + 2);
v5 = *((_BYTE *)&timer + 12);
LABEL_2:
v6 = v3;
v7 = v1 & 3;
while ( v1 != v7 )
{
++v4;
++v2;
v1 -= 4;
v6 = 1;
if ( v4 == 16 )
{
++v5;
v4 = 0;
v3 = 1;
goto LABEL_2;
}
}
if ( v6 )
{
timer = v2;
*(&timer + 2) = v4;
*(&timer + 1) = v1;
}
if ( v3 )
*((_BYTE *)&timer + 12) = v5;
result = *((unsigned __int8 *)&timer + 15);
if ( (result & 4) != 0 )
{
result = (unsigned int)(result & 3) - 1;
if ( (unsigned __int8)result <= 2u )
{
result = (unsigned __int8)result;
if ( timer < (unsigned int)(unsigned __int8)CSWTCH_4[(unsigned __int8)result] )
return result;
}
else if ( (unsigned int)timer < 0x40 )
{
return result;
}
v9 = (*((_BYTE *)&timer + 13))++ == 0xFF;
timer = 0;
if ( v9 )
{
result = *((unsigned __int8 *)&timer + 14);
mmu[258] |= 4u;
*((_BYTE *)&timer + 13) = result;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(unsigned __int8 a1)
{
int v1; // edi
int v2; // edx
char v3; // r8
int v4; // eax
char v5; // r9
char v6; // cl
int v7; // esi
__int64 result; // rax
bool v9; // zf

v1 = *(&timer + 1) + a1;
v2 = timer;
v3 = 0;
*(&timer + 1) = v1;
v4 = *(&timer + 2);
v5 = *((_BYTE *)&timer + 12);
LABEL_2:
v6 = v3;
v7 = v1 & 3;
while ( v1 != v7 )
{
++v4;
++v2;
v1 -= 4;
v6 = 1;
if ( v4 == 16 )
{
++v5;
v4 = 0;
v3 = 1;
goto LABEL_2;
}
}
if ( v6 )
{
timer = v2;
*(&timer + 2) = v4;
*(&timer + 1) = v1;
}
if ( v3 )
*((_BYTE *)&timer + 12) = v5;
result = *((unsigned __int8 *)&timer + 15);
if ( (result & 4) != 0 )
{
result = (unsigned int)(result & 3) - 1;
if ( (unsigned __int8)result <= 2u )
{
result = (unsigned __int8)result;
if ( timer < (unsigned int)(unsigned __int8)CSWTCH_4[(unsigned __int8)result] )
return result;
}
else if ( (unsigned int)timer < 0x40 )
{
return result;
}
v9 = (*((_BYTE *)&timer + 13))++ == 0xFF;
timer = 0;
if ( v9 )
{
result = *((unsigned __int8 *)&timer + 14);
mmu[258] |= 4u;
*((_BYTE *)&timer + 13) = result;
}
}
return result;
}

original_code:
void timer_update(Byte ticks)
{
    timer.clock.sub += ticks;
    while (timer.clock.sub >= 4)
    {
        timer.clock.main++;
        timer.clock.div++;
        timer.clock.sub -= 4;
        if (timer.clock.div == 16)
        {
            timer.regs.div++;
            timer.clock.div = 0;
        }
    }
    if (timer.regs.ctrl & 0x04)
    {
        Byte threshold;
        switch (timer.regs.ctrl & 0x03)
        {
            case 1:
                threshold = 1;
                break;
            case 2:
                threshold = 4;
                break;
            case 3:
                threshold = 16;
                break;
            default:
                threshold = 64;
                break;
        }
        if (timer.clock.main >= threshold)
        {
            timer.clock.main = 0;
            timer.regs.count++;
            if (timer.regs.count == 0)
            {
                timer.regs.count = timer.regs.mod;
                mmu.iflag |= 0x04;
            }
        }
    }
}

canonical_original_code:
void timer_update(unsigned char ticks)
{
    timer.clock.sub += ticks;
    while (timer.clock.sub >= 4)
    {
        timer.clock.main++;
        timer.clock.div++;
        timer.clock.sub -= 4;
        if (timer.clock.div == 16)
        {
            timer.regs.div++;
            timer.clock.div = 0;
        }
    }
    if (timer.regs.ctrl & 0x04)
    {
        unsigned char threshold;
        switch (timer.regs.ctrl & 0x03)
        {
            case 1:
                threshold = 1;
                break;
            case 2:
                threshold = 4;
                break;
            case 3:
                threshold = 16;
                break;
            default:
                threshold = 64;
                break;
        }
        if (timer.clock.main >= threshold)
        {
            timer.clock.main = 0;
            timer.regs.count++;
            if (timer.regs.count == 0)
            {
                timer.regs.count = timer.regs.mod;
                mmu.iflag |= 0x04;
            }
        }
    }
}

variable_types:
ticks
unsigned char

variable_types:
threshold
unsigned char


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
if ( argc == 2 )
{
SDL_Init(32LL, argv, envp);
gbe_reset(argv[1]);
gbe_run();
mbc_cleanup();
SDL_Quit();
}
else
{
fwrite("Syntax: gbe <rom-path>\n", 1uLL, 0x17uLL, stderr);
}
return 0;
}

original_code:
int main(int argc, char *argv[])
{
    if (argc == 2)
    {
        SDL_Init(0x00000020);
        gbe_reset(argv[1]);
        gbe_run();
        mbc_cleanup();
        SDL_Quit();
    }
    else
    {
        fprintf(stderr, "Syntax: gbe <rom-path>\n");
    }
    return 0;
}

variable_types: argc int


decompiled_code:
__int64 __fastcall dma_transfer(int a1)
{
unsigned __int64 v2; // rbx
unsigned __int16 v3; // r12
char v4; // al
unsigned __int16 v5; // di
__int64 result; // rax

v2 = (unsigned int)((_DWORD)&gpu + 8215);
do
{
v3 = a1 + 3;
v2 += 4LL;
*(_BYTE *)(v2 - 4) = mmu_getbyte((unsigned __int16)a1);
v4 = mmu_getbyte((unsigned __int16)(a1 + 1));
v5 = a1 + 2;
a1 += 4;
*(_BYTE *)(v2 - 3) = v4;
*(_BYTE *)(v2 - 2) = mmu_getbyte(v5);
result = mmu_getbyte(v3);
*(_BYTE *)(v2 - 1) = result;
}
while ( (__int64 *)v2 != (__int64 *)((char *)&gpu + 8375) );
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1)
{
unsigned __int64 v2; // rbx
unsigned __int16 v3; // r12
char v4; // al
unsigned __int16 v5; // di
__int64 result; // rax

v2 = (unsigned int)((_DWORD)&gpu + 8215);
do
{
v3 = a1 + 3;
v2 += 4LL;
*(_BYTE *)(v2 - 4) = mmu_getbyte((unsigned __int16)a1);
v4 = mmu_getbyte((unsigned __int16)(a1 + 1));
v5 = a1 + 2;
a1 += 4;
*(_BYTE *)(v2 - 3) = v4;
*(_BYTE *)(v2 - 2) = mmu_getbyte(v5);
result = mmu_getbyte(v3);
*(_BYTE *)(v2 - 1) = result;
}
while ( (__int64 *)v2 != (__int64 *)((char *)&gpu + 8375) );
return result;
}

original_code:
void dma_transfer(Word addr)
{
    Byte *oam = gpu.oam;
    for (Byte i = 0; i < 40; i++)
    {
        *oam++ = mmu_getbyte(addr++);
        *oam++ = mmu_getbyte(addr++);
        *oam++ = mmu_getbyte(addr++);
        *oam++ = mmu_getbyte(addr++);
    }
}

canonical_original_code:
void dma_transfer(unsigned short addr)
{
    unsigned char *oam = gpu.oam;
    for (unsigned char i = 0; i < 40; i++)
    {
        *oam++ = mmu_getbyte(addr++);
        *oam++ = mmu_getbyte(addr++);
        *oam++ = mmu_getbyte(addr++);
        *oam++ = mmu_getbyte(addr++);
    }
}

variable_types:
oam
unsigned char *

variable_types:
i
unsigned char


original_code:
void gpu_reset()
{
    gpu.screen = SDL_SetVideoMode(160, 144, 32,
            0x00000001 | 0x40000000);
    ((gpu.screen != ((void *)0)) ? (void) (0) : __assert_fail ("gpu.screen != NULL", "src/gpu.c", 28, __extension__ __PRETTY_FUNCTION__));
    gpu.mode = 0;
    gpu.modeclock = 0;
    gpu.regs.control = 0;
    gpu.regs.scrollx = 0;
    gpu.regs.scrolly = 0;
    gpu.regs.wndposx = 0;
    gpu.regs.wndposy = 0;
    gpu.regs.line = 0;
    gpu.regs.coincidence = 0;
    gpu.regs.status = 0;
    gpu.pal.bg = 0;
    gpu.pal.obj0 = 0;
    gpu.pal.obj1 = 0;
    for (Word i = 0; i < 8192; i++)
    {
        gpu.vram[i] = 0;
    }
    for (Word i = 0; i < 160; i++)
    {
        gpu.oam[i] = 0;
    }
    SDL_Rect rect = {0, 0, 160, 144};
    SDL_LockSurface(gpu.screen);
    SDL_FillRect(gpu.screen, &rect,
            SDL_MapRGBA(gpu.screen->format, 0xFF, 0xFF, 0xFF, 0xFF));
    SDL_UnlockSurface(gpu.screen);
    SDL_Flip(gpu.screen);
}

canonical_original_code:
void gpu_reset()
{
    gpu.screen = SDL_SetVideoMode(160, 144, 32,
            0x00000001 | 0x40000000);
    ((gpu.screen != ((void *)0)) ? (void) (0) : __assert_fail ("gpu.screen != NULL", "src/gpu.c", 28, __extension__ __PRETTY_FUNCTION__));
    gpu.mode = 0;
    gpu.modeclock = 0;
    gpu.regs.control = 0;
    gpu.regs.scrollx = 0;
    gpu.regs.scrolly = 0;
    gpu.regs.wndposx = 0;
    gpu.regs.wndposy = 0;
    gpu.regs.line = 0;
    gpu.regs.coincidence = 0;
    gpu.regs.status = 0;
    gpu.pal.bg = 0;
    gpu.pal.obj0 = 0;
    gpu.pal.obj1 = 0;
    for (unsigned short i = 0; i < 8192; i++)
    {
        gpu.vram[i] = 0;
    }
    for (unsigned short i = 0; i < 160; i++)
    {
        gpu.oam[i] = 0;
    }
    struct SDL_Rect rect = {0, 0, 160, 144};
    SDL_LockSurface(gpu.screen);
    SDL_FillRect(gpu.screen, &rect,
            SDL_MapRGBA(gpu.screen->format, 0xFF, 0xFF, 0xFF, 0xFF));
    SDL_UnlockSurface(gpu.screen);
    SDL_Flip(gpu.screen);
}

variable_types:
i
unsigned short

variable_types: struct SDL_Rect { short x; unsigned short w; }


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

switch ( a1 )
{
case -192:
*((_BYTE *)&gpu + 12) = a2;
break;
case -191:
result = *((_BYTE *)&gpu + 19) & 7;
*((_BYTE *)&gpu + 19) = result | a2 & 0x78;
break;
case -190:
*((_BYTE *)&gpu + 14) = a2;
break;
case -189:
*((_BYTE *)&gpu + 13) = a2;
break;
case -187:
*((_BYTE *)&gpu + 18) = a2;
break;
case -186:
result = dma_transfer((unsigned __int16)(a2 << 8));
break;
case -185:
*((_BYTE *)&gpu + 20) = a2;
break;
case -184:
*((_BYTE *)&gpu + 21) = a2;
break;
case -183:
*((_BYTE *)&gpu + 22) = a2;
break;
case -182:
*((_BYTE *)&gpu + 16) = a2;
break;
case -181:
*((_BYTE *)&gpu + 15) = a2;
break;
default:
return result;
}
return result;
}

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

switch ( a1 )
{
case -192:
*((_BYTE *)&gpu + 12) = a2;
break;
case -191:
result = *((_BYTE *)&gpu + 19) & 7;
*((_BYTE *)&gpu + 19) = result | a2 & 0x78;
break;
case -190:
*((_BYTE *)&gpu + 14) = a2;
break;
case -189:
*((_BYTE *)&gpu + 13) = a2;
break;
case -187:
*((_BYTE *)&gpu + 18) = a2;
break;
case -186:
result = func0((unsigned __int16)(a2 << 8));
break;
case -185:
*((_BYTE *)&gpu + 20) = a2;
break;
case -184:
*((_BYTE *)&gpu + 21) = a2;
break;
case -183:
*((_BYTE *)&gpu + 22) = a2;
break;
case -182:
*((_BYTE *)&gpu + 16) = a2;
break;
case -181:
*((_BYTE *)&gpu + 15) = a2;
break;
default:
return result;
}
return result;
}

original_code:
void gpu_putbyte(Word addr, Byte value)
{
    switch (addr)
    {
        case 0xFF40:
            gpu.regs.control = value;
            break;
        case 0xFF41:
            gpu.regs.status = (value & 0x78) | (gpu.regs.status & 0x07);
            break;
        case 0xFF42:
            gpu.regs.scrolly = value;
            break;
        case 0xFF43:
            gpu.regs.scrollx = value;
            break;
        case 0xFF45:
            gpu.regs.coincidence = value;
            break;
        case 0xFF46:
            dma_transfer(value << 8);
            break;
        case 0xFF47:
            gpu.pal.bg = value;
            break;
        case 0xFF48:
            gpu.pal.obj0 = value;
            break;
        case 0xFF49:
            gpu.pal.obj1 = value;
            break;
        case 0xFF4A:
            gpu.regs.wndposy = value;
            break;
        case 0xFF4B:
            gpu.regs.wndposx = value;
            break;
    }
}

canonical_original_code:
void gpu_putbyte(unsigned short addr, unsigned char value)
{
    switch (addr)
    {
        case 0xFF40:
            gpu.regs.control = value;
            break;
        case 0xFF41:
            gpu.regs.status = (value & 0x78) | (gpu.regs.status & 0x07);
            break;
        case 0xFF42:
            gpu.regs.scrolly = value;
            break;
        case 0xFF43:
            gpu.regs.scrollx = value;
            break;
        case 0xFF45:
            gpu.regs.coincidence = value;
            break;
        case 0xFF46:
            dma_transfer(value << 8);
            break;
        case 0xFF47:
            gpu.pal.bg = value;
            break;
        case 0xFF48:
            gpu.pal.obj0 = value;
            break;
        case 0xFF49:
            gpu.pal.obj1 = value;
            break;
        case 0xFF4A:
            gpu.regs.wndposy = value;
            break;
        case 0xFF4B:
            gpu.regs.wndposx = value;
            break;
    }
}


original_code:
Byte get_lcd_status()
{
    Byte status = gpu.regs.status;
    status |= (gpu.mode & 0x03);
    if (gpu.regs.line == gpu.regs.coincidence)
    {
        status |= 0x04;
    }
    return status;
}

canonical_original_code:
unsigned char get_lcd_status()
{
    unsigned char status = gpu.regs.status;
    status |= (gpu.mode & 0x03);
    if (gpu.regs.line == gpu.regs.coincidence)
    {
        status |= 0x04;
    }
    return status;
}

variable_types:
status
unsigned char


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

switch ( a1 )
{
case -192:
result = *((unsigned __int8 *)&gpu + 12);
break;
case -191:
result = get_lcd_status();
break;
case -190:
result = *((unsigned __int8 *)&gpu + 14);
break;
case -189:
result = *((unsigned __int8 *)&gpu + 13);
break;
case -188:
result = *((unsigned __int8 *)&gpu + 17);
break;
case -187:
result = *((unsigned __int8 *)&gpu + 18);
break;
case -185:
result = *((unsigned __int8 *)&gpu + 20);
break;
case -184:
result = *((unsigned __int8 *)&gpu + 21);
break;
case -183:
result = *((unsigned __int8 *)&gpu + 22);
break;
case -182:
result = *((unsigned __int8 *)&gpu + 16);
break;
case -181:
result = *((unsigned __int8 *)&gpu + 15);
break;
default:
result = 0LL;
break;
}
return result;
}

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

switch ( a1 )
{
case -192:
result = *((unsigned __int8 *)&gpu + 12);
break;
case -191:
result = func3();
break;
case -190:
result = *((unsigned __int8 *)&gpu + 14);
break;
case -189:
result = *((unsigned __int8 *)&gpu + 13);
break;
case -188:
result = *((unsigned __int8 *)&gpu + 17);
break;
case -187:
result = *((unsigned __int8 *)&gpu + 18);
break;
case -185:
result = *((unsigned __int8 *)&gpu + 20);
break;
case -184:
result = *((unsigned __int8 *)&gpu + 21);
break;
case -183:
result = *((unsigned __int8 *)&gpu + 22);
break;
case -182:
result = *((unsigned __int8 *)&gpu + 16);
break;
case -181:
result = *((unsigned __int8 *)&gpu + 15);
break;
default:
result = 0LL;
break;
}
return result;
}

original_code:
Byte gpu_getbyte(Word addr)
{
    switch (addr)
    {
        case 0xFF40:
            return gpu.regs.control;
        case 0xFF41:
            return get_lcd_status();
        case 0xFF42:
            return gpu.regs.scrolly;
        case 0xFF43:
            return gpu.regs.scrollx;
        case 0xFF44:
            return gpu.regs.line;
        case 0xFF45:
            return gpu.regs.coincidence;
        case 0xFF47:
            return gpu.pal.bg;
        case 0xFF48:
            return gpu.pal.obj0;
        case 0xFF49:
            return gpu.pal.obj1;
        case 0xFF4A:
            return gpu.regs.wndposy;
        case 0xFF4B:
            return gpu.regs.wndposx;
        default:
            return 0;
    }
}

canonical_original_code:
unsigned char gpu_getbyte(unsigned short addr)
{
    switch (addr)
    {
        case 0xFF40:
            return gpu.regs.control;
        case 0xFF41:
            return get_lcd_status();
        case 0xFF42:
            return gpu.regs.scrolly;
        case 0xFF43:
            return gpu.regs.scrollx;
        case 0xFF44:
            return gpu.regs.line;
        case 0xFF45:
            return gpu.regs.coincidence;
        case 0xFF47:
            return gpu.pal.bg;
        case 0xFF48:
            return gpu.pal.obj0;
        case 0xFF49:
            return gpu.pal.obj1;
        case 0xFF4A:
            return gpu.regs.wndposy;
        case 0xFF4B:
            return gpu.regs.wndposx;
        default:
            return 0;
    }
}


original_code:
void set_mode(Byte mode)
{
    gpu.mode = mode;
    gpu.modeclock = 0;
    switch (mode)
    {
        case 0:
            if (gpu.regs.status & 0x08)
            {
                mmu.iflag |= 0x02;
            }
            break;
        case 1:
            if (gpu.regs.status & 0x10)
            {
                mmu.iflag |= 0x02;
            }
            break;
        case 2:
            if (gpu.regs.status & 0x20)
            {
                mmu.iflag |= 0x02;
            }
            break;
    }
}

canonical_original_code:
void set_mode(unsigned char mode)
{
    gpu.mode = mode;
    gpu.modeclock = 0;
    switch (mode)
    {
        case 0:
            if (gpu.regs.status & 0x08)
            {
                mmu.iflag |= 0x02;
            }
            break;
        case 1:
            if (gpu.regs.status & 0x10)
            {
                mmu.iflag |= 0x02;
            }
            break;
        case 2:
            if (gpu.regs.status & 0x20)
            {
                mmu.iflag |= 0x02;
            }
            break;
    }
}

variable_types:
mode
unsigned char


decompiled_code:
__int64 next_line()
{
__int64 result; // rax

result = (unsigned int)(unsigned __int8)(*((_BYTE *)&gpu + 17))++ + 1;
if ( (*((_BYTE *)&gpu + 19) & 0x40) != 0 && (_BYTE)result == *((_BYTE *)&gpu + 18) )
mmu[258] |= 2u;
return result;
}

canonical_decompiled_code:
__int64 func6()
{
__int64 result; // rax

result = (unsigned int)(unsigned __int8)(*((_BYTE *)&gpu + 17))++ + 1;
if ( (*((_BYTE *)&gpu + 19) & 0x40) != 0 && (_BYTE)result == *((_BYTE *)&gpu + 18) )
mmu[258] |= 2u;
return result;
}

original_code:
void next_line()
{
    gpu.regs.line++;
    if ((gpu.regs.status & 0x40) &&
        gpu.regs.line == gpu.regs.coincidence)
    {
        mmu.iflag |= 0x02;
    }
}


decompiled_code:
__int64 __fastcall gpu_step(__int16 a1)
{
__int64 result; // rax
unsigned __int16 v2; // di

result = *((unsigned __int8 *)&gpu + 8);
v2 = *((_WORD *)&gpu + 5) + a1;
*((_WORD *)&gpu + 5) = v2;
if ( (_BYTE)result == 2 )
{
if ( v2 > 0x13u )
result = set_mode(3);
}
else if ( (unsigned __int8)result > 2u )
{
if ( (_BYTE)result != 3 )
_assert_fail("false", "src/gpu.c", 0xE3u, "gpu_step");
if ( v2 > 0x2Au )
{
render_scanline();
result = set_mode(0);
}
}
else if ( (_BYTE)result )
{
if ( v2 > 0x71u )
{
if ( *((_BYTE *)&gpu + 17) == 0x99 )
{
*((_BYTE *)&gpu + 17) = 0;
result = set_mode(2);
}
else
{
next_line();
result = 0LL;
*((_WORD *)&gpu + 5) = 0;
}
}
}
else if ( v2 > 0x32u )
{
if ( *((_BYTE *)&gpu + 17) == 0x8F )
{
SDL_Flip(gpu);
set_mode(1);
mmu[258] |= 1u;
}
else
{
set_mode(2);
}
result = next_line();
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int16 a1)
{
__int64 result; // rax
unsigned __int16 v2; // di

result = *((unsigned __int8 *)&gpu + 8);
v2 = *((_WORD *)&gpu + 5) + a1;
*((_WORD *)&gpu + 5) = v2;
if ( (_BYTE)result == 2 )
{
if ( v2 > 0x13u )
result = func5(3);
}
else if ( (unsigned __int8)result > 2u )
{
if ( (_BYTE)result != 3 )
_assert_fail("false", "src/gpu.c", 0xE3u, "gpu_step");
if ( v2 > 0x2Au )
{
render_scanline();
result = func5(0);
}
}
else if ( (_BYTE)result )
{
if ( v2 > 0x71u )
{
if ( *((_BYTE *)&gpu + 17) == 0x99 )
{
*((_BYTE *)&gpu + 17) = 0;
result = func5(2);
}
else
{
func6();
result = 0LL;
*((_WORD *)&gpu + 5) = 0;
}
}
}
else if ( v2 > 0x32u )
{
if ( *((_BYTE *)&gpu + 17) == 0x8F )
{
SDL_Flip(gpu);
func5(1);
mmu[258] |= 1u;
}
else
{
func5(2);
}
result = func6();
}
return result;
}

original_code:
void gpu_step(Word ticks)
{
    gpu.modeclock += ticks;
    switch (gpu.mode)
    {
        case 2:
            if (gpu.modeclock >= 20)
            {
                set_mode(3);
            }
            break;
        case 3:
            if (gpu.modeclock >= 43)
            {
                render_scanline();
                set_mode(0);
            }
            break;
        case 0:
            if (gpu.modeclock >= 51)
            {
                if (gpu.regs.line == (144 - 1))
                {
                    SDL_Flip(gpu.screen);
                    set_mode(1);
                    mmu.iflag |= 0x01;
                }
                else
                {
                    set_mode(2);
                }
                next_line();
            }
            break;
        case 1:
            if (gpu.modeclock >= 114)
            {
                if (gpu.regs.line == (144 + 9))
                {
                    gpu.regs.line = 0;
                    set_mode(2);
                }
                else
                {
                    next_line();
                    gpu.modeclock = 0;
                }
            }
            break;
        default:
            ((0) ? (void) (0) : __assert_fail ("false", "src/gpu.c", 227, __extension__ __PRETTY_FUNCTION__));
    }
}

canonical_original_code:
void gpu_step(unsigned short ticks)
{
    gpu.modeclock += ticks;
    switch (gpu.mode)
    {
        case 2:
            if (gpu.modeclock >= 20)
            {
                set_mode(3);
            }
            break;
        case 3:
            if (gpu.modeclock >= 43)
            {
                render_scanline();
                set_mode(0);
            }
            break;
        case 0:
            if (gpu.modeclock >= 51)
            {
                if (gpu.regs.line == (144 - 1))
                {
                    SDL_Flip(gpu.screen);
                    set_mode(1);
                    mmu.iflag |= 0x01;
                }
                else
                {
                    set_mode(2);
                }
                next_line();
            }
            break;
        case 1:
            if (gpu.modeclock >= 114)
            {
                if (gpu.regs.line == (144 + 9))
                {
                    gpu.regs.line = 0;
                    set_mode(2);
                }
                else
                {
                    next_line();
                    gpu.modeclock = 0;
                }
            }
            break;
        default:
            ((0) ? (void) (0) : __assert_fail ("false", "src/gpu.c", 227, __extension__ __PRETTY_FUNCTION__));
    }
}

variable_types:
ticks
unsigned short


decompiled_code:
bool is_battery()
{
return (mbc & 0xEF) == 3;
}

canonical_decompiled_code:
bool func0()
{
return (mbc & 0xEF) == 3;
}

original_code:
static inline _Bool is_battery()
{
    switch (mbc.cart_type)
    {
        case 0x03:
        case 0x13:
            return 1;
        default:
            return 0;
    }
}


decompiled_code:
void mbc_cleanup()
{
if ( is_battery() )
fclose(*((FILE **)&mbc + 5));
free(*((void **)&mbc + 3));
free(*((void **)&mbc + 1));
}

canonical_decompiled_code:
void func3()
{
if ( func0() )
fclose(*((FILE **)&mbc + 5));
free(*((void **)&mbc + 3));
free(*((void **)&mbc + 1));
}

original_code:
void mbc_cleanup()
{
    if (is_battery())
    {
        fclose(mbc.ram_file);
    }
    free(mbc.ram);
    free(mbc.rom);
}


decompiled_code:
__int64 __fastcall mbc_getbyte(unsigned __int16 a1)
{
unsigned __int16 v1; // ax
__int64 v3; // rdi

v1 = a1 & 0xF000;
if ( (a1 & 0xF000) == 24576 )
return *(unsigned __int8 *)(*((_QWORD *)&mbc + 1) + *((_DWORD *)&mbc + 4) + (a1 & 0x3FFFu));
if ( (a1 & 0xF000u) <= 0x6000 )
{
if ( v1 == 12288 )
return *(unsigned __int8 *)(*((_QWORD *)&mbc + 1) + a1);
if ( v1 <= 0x3000u )
{
if ( v1 == 0x2000 )
return *(unsigned __int8 *)(*((_QWORD *)&mbc + 1) + a1);
if ( (a1 & 0xE000) == 0 )
return *(unsigned __int8 *)(*((_QWORD *)&mbc + 1) + a1);
return 0LL;
}
if ( (a1 & 0xE000) != 0x4000 )
return 0LL;
return *(unsigned __int8 *)(*((_QWORD *)&mbc + 1) + *((_DWORD *)&mbc + 4) + (a1 & 0x3FFFu));
}
if ( (a1 & 0xE000) != 0xA000 )
{
if ( v1 != 28672 )
return 0LL;
return *(unsigned __int8 *)(*((_QWORD *)&mbc + 1) + *((_DWORD *)&mbc + 4) + (a1 & 0x3FFFu));
}
v3 = *((_DWORD *)&mbc + 9) + (a1 & 0x1FFFu);
if ( (unsigned int)v3 >= *((_DWORD *)&mbc + 8) )
_assert_fail("(mbc.ram_offset + (addr & 0x1FFF)) < mbc.ram_size", "src/mbc.c", 0xB6u, "mbc_getbyte");
return *(unsigned __int8 *)(*((_QWORD *)&mbc + 3) + v3);
}

original_code:
Byte mbc_getbyte(Word addr)
{
    switch (addr & 0xF000)
    {
        case 0x0000:
        case 0x1000:
        case 0x2000:
        case 0x3000:
            return mbc.rom[addr & 0x3FFF];
        case 0x4000:
        case 0x5000:
        case 0x6000:
        case 0x7000:
            return mbc.rom[mbc.rom_offset + (addr & 0x3FFF)];
        case 0xA000:
        case 0xB000:
            (((mbc.ram_offset + (addr & 0x1FFF)) < mbc.ram_size) ? (void) (0) : __assert_fail ("(mbc.ram_offset + (addr & 0x1FFF)) < mbc.ram_size", "src/mbc.c", 182, __extension__ __PRETTY_FUNCTION__));
            return mbc.ram[mbc.ram_offset + (addr & 0x1FFF)];
        default:
            return 0;
    }
}

canonical_original_code:
unsigned char mbc_getbyte(unsigned short addr)
{
    switch (addr & 0xF000)
    {
        case 0x0000:
        case 0x1000:
        case 0x2000:
        case 0x3000:
            return mbc.rom[addr & 0x3FFF];
        case 0x4000:
        case 0x5000:
        case 0x6000:
        case 0x7000:
            return mbc.rom[mbc.rom_offset + (addr & 0x3FFF)];
        case 0xA000:
        case 0xB000:
            (((mbc.ram_offset + (addr & 0x1FFF)) < mbc.ram_size) ? (void) (0) : __assert_fail ("(mbc.ram_offset + (addr & 0x1FFF)) < mbc.ram_size", "src/mbc.c", 182, __extension__ __PRETTY_FUNCTION__));
            return mbc.ram[mbc.ram_offset + (addr & 0x1FFF)];
        default:
            return 0;
    }
}


original_code:
void mbc_putbyte(Word addr, Byte value)
{
    switch (addr & 0xF000)
    {
        case 0x0000:
        case 0x1000:
            switch (mbc.cart_type)
            {
                case 0x02:
                case 0x03:
                case 0x12:
                case 0x13:
                    mbc.regs.ram_on = ((value & 0x0F) == 0x0A) ? 1 : 0;
                    break;
            }
            break;
        case 0x2000:
        case 0x3000:
            switch (mbc.cart_type)
            {
                case 0x01:
                case 0x02:
                case 0x03:
                    mbc.regs.rom_bank = (mbc.regs.rom_bank & 0x60) + (value & 0x1F);
                    break;
                case 0x11:
                case 0x12:
                case 0x13:
                    mbc.regs.rom_bank = value & 0x7F;
                    break;
            }
            mbc.rom_offset = (mbc.regs.rom_bank ? mbc.regs.rom_bank : 1) * 0x4000;
            break;
        case 0x4000:
        case 0x5000:
            switch (mbc.cart_type)
            {
                case 0x01:
                case 0x02:
                case 0x03:
                    if (mbc.regs.mode)
                    {
                        mbc.regs.ram_bank = value & 0x03;
                        mbc.ram_offset = mbc.regs.ram_bank * 0x2000;
                    }
                    else
                    {
                        mbc.regs.rom_bank = (mbc.regs.rom_bank & 0x1F) +
                            ((value & 0x03) << 5);
                        mbc.rom_offset = mbc.regs.rom_bank * 0x4000;
                    }
                    break;
                case 0x11:
                case 0x12:
                case 0x13:
                    if (value <= 0x03)
                    {
                        mbc.regs.ram_bank = value & 0x03;
                        mbc.ram_offset = mbc.regs.ram_bank * 0x2000;
                    }
                    else
                    {
                    }
                    break;
            }
            break;
        case 0x6000:
        case 0x7000:
            switch (mbc.cart_type)
            {
                case 0x02:
                case 0x03:
                    mbc.regs.mode = value & 0x01;
                    break;
                case 0x11:
                case 0x12:
                case 0x13:
                    break;
            }
            break;
        case 0xA000:
        case 0xB000:
            {
                uint32_t offset = mbc.ram_offset + (addr & 0x1FFF);
                if (offset < mbc.ram_size)
                {
                    mbc.ram[offset] = value;
                    if (is_battery())
                    {
                        fseek(mbc.ram_file, offset, 0);
                        fputc(value, mbc.ram_file);
                    }
                }
            }
            break;
    }
}

canonical_original_code:
void mbc_putbyte(unsigned short addr, unsigned char value)
{
    switch (addr & 0xF000)
    {
        case 0x0000:
        case 0x1000:
            switch (mbc.cart_type)
            {
                case 0x02:
                case 0x03:
                case 0x12:
                case 0x13:
                    mbc.regs.ram_on = ((value & 0x0F) == 0x0A) ? 1 : 0;
                    break;
            }
            break;
        case 0x2000:
        case 0x3000:
            switch (mbc.cart_type)
            {
                case 0x01:
                case 0x02:
                case 0x03:
                    mbc.regs.rom_bank = (mbc.regs.rom_bank & 0x60) + (value & 0x1F);
                    break;
                case 0x11:
                case 0x12:
                case 0x13:
                    mbc.regs.rom_bank = value & 0x7F;
                    break;
            }
            mbc.rom_offset = (mbc.regs.rom_bank ? mbc.regs.rom_bank : 1) * 0x4000;
            break;
        case 0x4000:
        case 0x5000:
            switch (mbc.cart_type)
            {
                case 0x01:
                case 0x02:
                case 0x03:
                    if (mbc.regs.mode)
                    {
                        mbc.regs.ram_bank = value & 0x03;
                        mbc.ram_offset = mbc.regs.ram_bank * 0x2000;
                    }
                    else
                    {
                        mbc.regs.rom_bank = (mbc.regs.rom_bank & 0x1F) +
                            ((value & 0x03) << 5);
                        mbc.rom_offset = mbc.regs.rom_bank * 0x4000;
                    }
                    break;
                case 0x11:
                case 0x12:
                case 0x13:
                    if (value <= 0x03)
                    {
                        mbc.regs.ram_bank = value & 0x03;
                        mbc.ram_offset = mbc.regs.ram_bank * 0x2000;
                    }
                    else
                    {
                    }
                    break;
            }
            break;
        case 0x6000:
        case 0x7000:
            switch (mbc.cart_type)
            {
                case 0x02:
                case 0x03:
                    mbc.regs.mode = value & 0x01;
                    break;
                case 0x11:
                case 0x12:
                case 0x13:
                    break;
            }
            break;
        case 0xA000:
        case 0xB000:
            {
                unsigned int offset = mbc.ram_offset + (addr & 0x1FFF);
                if (offset < mbc.ram_size)
                {
                    mbc.ram[offset] = value;
                    if (is_battery())
                    {
                        fseek(mbc.ram_file, offset, 0);
                        fputc(value, mbc.ram_file);
                    }
                }
            }
            break;
    }
}

variable_types:
offset
unsigned int


original_code:
void mmu_reset()
{
    mmu.in_bios = 1;
    mmu.ienable = 0;
    mmu.iflag = 0;
    for (Word i = 0; i < 8192; i++)
    {
        mmu.wram[i] = 0;
    }
    for (Word i = 0; i < 127; i++)
    {
        mmu.zram[i] = 0;
    }
}

canonical_original_code:
void mmu_reset()
{
    mmu.in_bios = 1;
    mmu.ienable = 0;
    mmu.iflag = 0;
    for (unsigned short i = 0; i < 8192; i++)
    {
        mmu.wram[i] = 0;
    }
    for (unsigned short i = 0; i < 127; i++)
    {
        mmu.zram[i] = 0;
    }
}


decompiled_code:
__int64 __fastcall mmu_getbyte(__int64 a1, __int64 a2, __int64 a3, __int64 a4)
{
unsigned __int16 v4; // ax
unsigned __int16 v5; // ax
__int64 result; // rax

v4 = a1 & 0xF000;
if ( (a1 & 0xF000) == 0x9000 )
return gpu[(a1 & 0x1FFF) + 23];
if ( ((unsigned __int16)a1 & 0xF000u) <= 0x9000 )
{
if ( v4 == 12288 )
return mbc_getbyte((unsigned __int16)a1);
if ( v4 <= 0x3000u )
{
if ( v4 )
{
if ( ((v4 - 4096) & 0xE000) != 0 )
goto LABEL_32;
}
else if ( mmu[0] )
{
if ( (unsigned __int16)a1 <= 0xFFu )
return (unsigned __int8)mmu[(unsigned __int16)a1 + 1];
if ( z80[4] == 256 )
mmu[0] = 0;
}
return mbc_getbyte((unsigned __int16)a1);
}
if ( v4 == 28672 )
return mbc_getbyte((unsigned __int16)a1);
if ( v4 <= 0x7000u )
{
if ( v4 != 24576 && (a1 & 0xE000) != 0x4000 )
goto LABEL_32;
return mbc_getbyte((unsigned __int16)a1);
}
if ( v4 != 0x8000 )
goto LABEL_32;
return gpu[(a1 & 0x1FFF) + 23];
}
if ( v4 == 0xE000 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( v4 <= 0xE000u )
{
if ( v4 == 0xC000 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( v4 > 0xC000u )
{
if ( v4 != 0xD000 )
goto LABEL_32;
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
}
if ( (a1 & 0xE000) != 0xA000 )
goto LABEL_32;
return mbc_getbyte((unsigned __int16)a1);
}
if ( v4 != 0xF000 )
goto LABEL_32;
v5 = a1 & 0xF00;
if ( (a1 & 0xF00) == 3584 )
{
result = 0LL;
if ( (unsigned __int16)a1 <= 0xFE9Fu )
result = gpu[(unsigned __int8)a1 + 8215];
return result;
}
if ( ((unsigned __int16)a1 & 0xF00u) > 0xE00 )
{
if ( v5 != 3840 )
goto LABEL_32;
if ( (_WORD)a1 == 0xFFFF )
{
result = (unsigned __int8)mmu[257];
}
else if ( (unsigned __int16)a1 > 0xFF7Fu )
{
result = (unsigned __int8)mmu[(a1 & 0x7F) + 8451];
}
else if ( (unsigned __int16)a1 > 0xFF3Fu )
{
result = gpu_getbyte((unsigned __int16)a1);
}
else if ( (unsigned __int16)a1 > 0xFF07u )
{
result = 0LL;
if ( (_WORD)a1 == 0xFF0F )
result = (unsigned __int8)mmu[258];
}
else if ( (unsigned __int16)a1 > 0xFF03u )
{
result = timer_getbyte((unsigned __int16)a1);
}
else
{
result = 0LL;
if ( (_WORD)a1 == 0xFF00 )
result = joypad_getbyte(a1, a2, a3, a4, 65280LL);
}
}
else
{
if ( v5 == 1792 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( v5 > 0x700u )
{
if ( v5 != 2816 )
{
if ( v5 > 0xB00u )
{
if ( (a1 & 0xE00) == 3072 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
LABEL_32:
_assert_fail("false", "src/mmu.c", 0xA8u, "mmu_getbyte");
}
if ( v5 != 2560 )
{
if ( (a1 & 0xE00) != 2048 )
goto LABEL_32;
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
}
}
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
}
if ( v5 == 768 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( v5 <= 0x300u )
{
if ( v5 == 512 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( (a1 & 0xE00) != 0 )
goto LABEL_32;
result = (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
}
else
{
if ( v5 == 1536 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( (a1 & 0xE00) != 1024 )
goto LABEL_32;
result = (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2, __int64 a3, __int64 a4)
{
unsigned __int16 v4; // ax
unsigned __int16 v5; // ax
__int64 result; // rax

v4 = a1 & 0xF000;
if ( (a1 & 0xF000) == 0x9000 )
return gpu[(a1 & 0x1FFF) + 23];
if ( ((unsigned __int16)a1 & 0xF000u) <= 0x9000 )
{
if ( v4 == 12288 )
return mbc_getbyte((unsigned __int16)a1);
if ( v4 <= 0x3000u )
{
if ( v4 )
{
if ( ((v4 - 4096) & 0xE000) != 0 )
goto LABEL_32;
}
else if ( mmu[0] )
{
if ( (unsigned __int16)a1 <= 0xFFu )
return (unsigned __int8)mmu[(unsigned __int16)a1 + 1];
if ( z80[4] == 256 )
mmu[0] = 0;
}
return mbc_getbyte((unsigned __int16)a1);
}
if ( v4 == 28672 )
return mbc_getbyte((unsigned __int16)a1);
if ( v4 <= 0x7000u )
{
if ( v4 != 24576 && (a1 & 0xE000) != 0x4000 )
goto LABEL_32;
return mbc_getbyte((unsigned __int16)a1);
}
if ( v4 != 0x8000 )
goto LABEL_32;
return gpu[(a1 & 0x1FFF) + 23];
}
if ( v4 == 0xE000 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( v4 <= 0xE000u )
{
if ( v4 == 0xC000 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( v4 > 0xC000u )
{
if ( v4 != 0xD000 )
goto LABEL_32;
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
}
if ( (a1 & 0xE000) != 0xA000 )
goto LABEL_32;
return mbc_getbyte((unsigned __int16)a1);
}
if ( v4 != 0xF000 )
goto LABEL_32;
v5 = a1 & 0xF00;
if ( (a1 & 0xF00) == 3584 )
{
result = 0LL;
if ( (unsigned __int16)a1 <= 0xFE9Fu )
result = gpu[(unsigned __int8)a1 + 8215];
return result;
}
if ( ((unsigned __int16)a1 & 0xF00u) > 0xE00 )
{
if ( v5 != 3840 )
goto LABEL_32;
if ( (_WORD)a1 == 0xFFFF )
{
result = (unsigned __int8)mmu[257];
}
else if ( (unsigned __int16)a1 > 0xFF7Fu )
{
result = (unsigned __int8)mmu[(a1 & 0x7F) + 8451];
}
else if ( (unsigned __int16)a1 > 0xFF3Fu )
{
result = gpu_getbyte((unsigned __int16)a1);
}
else if ( (unsigned __int16)a1 > 0xFF07u )
{
result = 0LL;
if ( (_WORD)a1 == 0xFF0F )
result = (unsigned __int8)mmu[258];
}
else if ( (unsigned __int16)a1 > 0xFF03u )
{
result = timer_getbyte((unsigned __int16)a1);
}
else
{
result = 0LL;
if ( (_WORD)a1 == 0xFF00 )
result = joypad_getbyte(a1, a2, a3, a4, 65280LL);
}
}
else
{
if ( v5 == 1792 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( v5 > 0x700u )
{
if ( v5 != 2816 )
{
if ( v5 > 0xB00u )
{
if ( (a1 & 0xE00) == 3072 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
LABEL_32:
_assert_fail("false", "src/mmu.c", 0xA8u, "mmu_getbyte");
}
if ( v5 != 2560 )
{
if ( (a1 & 0xE00) != 2048 )
goto LABEL_32;
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
}
}
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
}
if ( v5 == 768 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( v5 <= 0x300u )
{
if ( v5 == 512 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( (a1 & 0xE00) != 0 )
goto LABEL_32;
result = (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
}
else
{
if ( v5 == 1536 )
return (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
if ( (a1 & 0xE00) != 1024 )
goto LABEL_32;
result = (unsigned __int8)mmu[(a1 & 0x1FFF) + 259];
}
}
return result;
}

original_code:
Byte mmu_getbyte(Word addr)
{
    switch (addr & 0xF000)
    {
        case 0x0000:
            if (mmu.in_bios)
            {
                if (addr < 0x0100)
                {
                    return mmu.bios[addr];
                }
                else if (z80.regs.pc == 0x0100)
                {
                    mmu.in_bios = 0;
                }
            }
            return mbc_getbyte(addr);
        case 0x1000:
        case 0x2000:
        case 0x3000:
        case 0x4000:
        case 0x5000:
        case 0x6000:
        case 0x7000:
            return mbc_getbyte(addr);
        case 0x8000:
        case 0x9000:
            return gpu.vram[addr & 0x1FFF];
        case 0xA000:
        case 0xB000:
            return mbc_getbyte(addr);
        case 0xC000:
        case 0xD000:
            return mmu.wram[addr & 0x1FFF];
        case 0xE000:
            return mmu.wram[addr & 0x1FFF];
        case 0xF000:
            switch (addr & 0x0F00)
            {
                case 0x000: case 0x100: case 0x200: case 0x300:
                case 0x400: case 0x500: case 0x600: case 0x700:
                case 0x800: case 0x900: case 0xA00: case 0xB00:
                case 0xC00: case 0xD00:
                    return mmu.wram[addr & 0x1FFF];
                case 0xE00:
                    if (addr < 0xFEA0)
                    {
                        return gpu.oam[addr & 0xFF];
                    }
                    else
                    {
                        return 0;
                    }
                case 0xF00:
                    if (addr == 0xFFFF)
                    {
                        return mmu.ienable;
                    }
                    else if (addr >= 0xFF80)
                    {
                        return mmu.zram[addr & 0x7F];
                    }
                    else if (addr >= 0xFF40)
                    {
                        return gpu_getbyte(addr);
                    }
                    else
                    {
                        switch (addr)
                        {
                            case 0xFF00:
                                return joypad_getbyte();
                            case 0xFF04:
                            case 0xFF05:
                            case 0xFF06:
                            case 0xFF07:
                                return timer_getbyte(addr);
                            case 0xFF0F:
                                return mmu.iflag;
                            default:
                                return 0;
                        }
                    }
            }
        default:
            ((0) ? (void) (0) : __assert_fail ("false", "src/mmu.c", 168, __extension__ __PRETTY_FUNCTION__));
            return 0;
    }
}

canonical_original_code:
unsigned char mmu_getbyte(unsigned short addr)
{
    switch (addr & 0xF000)
    {
        case 0x0000:
            if (mmu.in_bios)
            {
                if (addr < 0x0100)
                {
                    return mmu.bios[addr];
                }
                else if (z80.regs.pc == 0x0100)
                {
                    mmu.in_bios = 0;
                }
            }
            return mbc_getbyte(addr);
        case 0x1000:
        case 0x2000:
        case 0x3000:
        case 0x4000:
        case 0x5000:
        case 0x6000:
        case 0x7000:
            return mbc_getbyte(addr);
        case 0x8000:
        case 0x9000:
            return gpu.vram[addr & 0x1FFF];
        case 0xA000:
        case 0xB000:
            return mbc_getbyte(addr);
        case 0xC000:
        case 0xD000:
            return mmu.wram[addr & 0x1FFF];
        case 0xE000:
            return mmu.wram[addr & 0x1FFF];
        case 0xF000:
            switch (addr & 0x0F00)
            {
                case 0x000: case 0x100: case 0x200: case 0x300:
                case 0x400: case 0x500: case 0x600: case 0x700:
                case 0x800: case 0x900: case 0xA00: case 0xB00:
                case 0xC00: case 0xD00:
                    return mmu.wram[addr & 0x1FFF];
                case 0xE00:
                    if (addr < 0xFEA0)
                    {
                        return gpu.oam[addr & 0xFF];
                    }
                    else
                    {
                        return 0;
                    }
                case 0xF00:
                    if (addr == 0xFFFF)
                    {
                        return mmu.ienable;
                    }
                    else if (addr >= 0xFF80)
                    {
                        return mmu.zram[addr & 0x7F];
                    }
                    else if (addr >= 0xFF40)
                    {
                        return gpu_getbyte(addr);
                    }
                    else
                    {
                        switch (addr)
                        {
                            case 0xFF00:
                                return joypad_getbyte();
                            case 0xFF04:
                            case 0xFF05:
                            case 0xFF06:
                            case 0xFF07:
                                return timer_getbyte(addr);
                            case 0xFF0F:
                                return mmu.iflag;
                            default:
                                return 0;
                        }
                    }
            }
        default:
            ((0) ? (void) (0) : __assert_fail ("false", "src/mmu.c", 168, __extension__ __PRETTY_FUNCTION__));
            return 0;
    }
}


decompiled_code:
__int64 __fastcall mmu_getword(unsigned __int16 a1, __int64 a2, __int64 a3, __int64 a4)
{
int v4; // ebp
__int64 v5; // rdx
__int64 v6; // rcx

v4 = (unsigned __int8)mmu_getbyte(a1, a2, a3, a4);
return v4 + ((unsigned int)mmu_getbyte((unsigned __int16)(a1 + 1), a2, v5, v6) << 8);
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned __int16 a1, __int64 a2, __int64 a3, __int64 a4)
{
int v4; // ebp
__int64 v5; // rdx
__int64 v6; // rcx

v4 = (unsigned __int8)func1(a1, a2, a3, a4);
return v4 + ((unsigned int)func1((unsigned __int16)(a1 + 1), a2, v5, v6) << 8);
}

original_code:
Word mmu_getword(Word addr)
{
    return mmu_getbyte(addr) + (mmu_getbyte(addr + 1) << 8);
}

canonical_original_code:
unsigned short mmu_getword(unsigned short addr)
{
    return mmu_getbyte(addr) + (mmu_getbyte(addr + 1) << 8);
}

return_type: unsigned short