original_code:
int range_parse_next(char *rangeString, FileRange *range) {
 char numbuffer[256];
 int i, j;
 j = 0;
 for(i = 0; i < 256; i++) {
  if((rangeString[i] >= '0' && rangeString[i] <= '9')) {
   numbuffer[i] = rangeString[i];
  } else if(rangeString[i] == '-') {
   numbuffer[i] = '\0';
   range->start = (off64_t)atol(numbuffer);
   i++;
   for(j = 0; j < 256; j++) {
    if((rangeString[i + j] >= '0' && rangeString[i + j] <= '9')) {
     numbuffer[j] = rangeString[i + j];
    } else if(rangeString[i + j] == '\0' || rangeString[i + j] == ',') {
     numbuffer[j] = '\0';
     range->end = (off64_t)atol(numbuffer);
     if(rangeString[i + j] != '\0') {
      j++;
     }
     break;
    } else {
     return(-1);
    }
   }
   break;
  } else if(rangeString[i] == '\0' || rangeString[i] == ',') {
   numbuffer[i] = '\0';
   range->start = (off64_t)atol(numbuffer);
   range->end = range->start;
   if(rangeString[i] != '\0') {
    i++;
   }
   break;
  } else {
   return(-1);
  }
 }
 return(i + j);
}

canonical_original_code:
int range_parse_next(char *rangeString, struct FileRange *range) {
 char numbuffer[256];
 int i; int j;
 j = 0;
 for(i = 0; i < 256; i++) {
  if((rangeString[i] >= '0' && rangeString[i] <= '9')) {
   numbuffer[i] = rangeString[i];
  } else if(rangeString[i] == '-') {
   numbuffer[i] = '\0';
   range->start = (long)atol(numbuffer);
   i++;
   for(j = 0; j < 256; j++) {
    if((rangeString[i + j] >= '0' && rangeString[i + j] <= '9')) {
     numbuffer[j] = rangeString[i + j];
    } else if(rangeString[i + j] == '\0' || rangeString[i + j] == ',') {
     numbuffer[j] = '\0';
     range->end = (long)atol(numbuffer);
     if(rangeString[i + j] != '\0') {
      j++;
     }
     break;
    } else {
     return(-1);
    }
   }
   break;
  } else if(rangeString[i] == '\0' || rangeString[i] == ',') {
   numbuffer[i] = '\0';
   range->start = (long)atol(numbuffer);
   range->end = range->start;
   if(rangeString[i] != '\0') {
    i++;
   }
   break;
  } else {
   return(-1);
  }
 }
 return(i + j);
}

variable_types: struct FileRange { long start; long end; long totalstart; long totalend; } *

variable_types:
numbuffer
char [256]

variable_types: i int

variable_types: j int


repo: paulguy/filesmasher

original_code:
int range_parse(char *rangeString, FileRange ***ranges) {
 int count;
 int i;
 int ret;
 int parsepos;
 count = range_verify(rangeString);
 if(count < 1) {
  return(count);
 }
 *ranges = range_new(count);
 if(*ranges == ((void *)0)) {
  return(-3);
 }
 parsepos = 0;
 for(i = 0; i < count; i++) {
  ret = range_parse_next(&(rangeString[parsepos]), (*ranges)[i]);
  if(ret < 1) {
   range_delete(*ranges, count);
   return(-4);
  }
  parsepos += ret;
  if(rangeString[parsepos] == '\0' && i < count - 1) {
   range_delete(*ranges, count);
   return(-5);
  }
  if(i == 0) {
   (*ranges)[i]->totalstart = 0;
   (*ranges)[i]->totalend = (*ranges)[i]->end - (*ranges)[i]->start;
  } else {
   (*ranges)[i]->totalstart = (*ranges)[i - 1]->totalend + 1;
   (*ranges)[i]->totalend = (*ranges)[i]->totalstart + ((*ranges)[i]->end - (*ranges)[i]->start);
  }
 }
 return(count);
}

canonical_original_code:
int range_parse(char *rangeString, struct FileRange ***ranges) {
 int count;
 int i;
 int ret;
 int parsepos;
 count = range_verify(rangeString);
 if(count < 1) {
  return(count);
 }
 *ranges = range_new(count);
 if(*ranges == ((void *)0)) {
  return(-3);
 }
 parsepos = 0;
 for(i = 0; i < count; i++) {
  ret = range_parse_next(&(rangeString[parsepos]), (*ranges)[i]);
  if(ret < 1) {
   range_delete(*ranges, count);
   return(-4);
  }
  parsepos += ret;
  if(rangeString[parsepos] == '\0' && i < count - 1) {
   range_delete(*ranges, count);
   return(-5);
  }
  if(i == 0) {
   (*ranges)[i]->totalstart = 0;
   (*ranges)[i]->totalend = (*ranges)[i]->end - (*ranges)[i]->start;
  } else {
   (*ranges)[i]->totalstart = (*ranges)[i - 1]->totalend + 1;
   (*ranges)[i]->totalend = (*ranges)[i]->totalstart + ((*ranges)[i]->end - (*ranges)[i]->start);
  }
 }
 return(count);
}

variable_types:
rangeString
char *

variable_types: struct FileRange { long start; long end; long totalstart; long totalend; } ***

variable_types: count int

variable_types: ret int

variable_types: parsepos int

return_type: int


decompiled_code:
void *__fastcall range_error_string(int a1)
{
void *result; // rax

if ( (unsigned int)(a1 + 5) > 4 )
result = RANGE_ERRORCODES;
else
result = *(&RANGE_ERRORCODES - a1);
return result;
}

canonical_decompiled_code:
void *__fastcall func5(int a1)
{
void *result; // rax

if ( (unsigned int)(a1 + 5) > 4 )
result = RANGE_ERRORCODES;
else
result = *(&RANGE_ERRORCODES - a1);
return result;
}

original_code:
const char *range_error_string(int errorcode) {
 if(errorcode > -1 || errorcode < RANGE_ERRORMAX) {
  return(RANGE_ERRORCODES[0]);
 }
 return(RANGE_ERRORCODES[-errorcode]);
}

variable_types: errorcode int

return_type: char *


initstr

repo: paulguy/pcspkrplay

decompiled_code:
_DWORD *initstr()
{
_DWORD *v0; // rbx
_BYTE *v1; // rax

v0 = malloc(0x10uLL);
v1 = malloc(1uLL);
*(_QWORD *)v0 = v1;
*v1 = 0;
v0[2] = 1;
v0[3] = 1;
return v0;
}

canonical_decompiled_code:
_DWORD *func0()
{
_DWORD *v0; // rbx
_BYTE *v1; // rax

v0 = malloc(0x10uLL);
v1 = malloc(1uLL);
*(_QWORD *)v0 = v1;
*v1 = 0;
v0[2] = 1;
v0[3] = 1;
return v0;
}

original_code:
str *initstr() {
 str *t;
 t = malloc(sizeof(str));
 t->data = malloc(1);
 t->data[0] = '\0';
 t->strsize = 1;
 t->memsize = 1;
 return(t);
}

canonical_original_code:
struct str *initstr() {
 struct str *t;
 t = malloc(sizeof(str));
 t->data = malloc(1);
 t->data[0] = '\0';
 t->strsize = 1;
 t->memsize = 1;
 return(t);
}

variable_types: struct str { char *data; int strsize; int memsize; } *


freestr

decompiled_code:
void __fastcall freestr(void *ptr)
{
free(*(void **)ptr);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
free(*(void **)ptr);
free(ptr);
}

original_code:
void freestr(str *t) {
 free(t->data);
 free(t);
}

canonical_original_code:
void freestr(struct str *t) {
 free(t->data);
 free(t);
}

return_type: void

user_defined_types: struct str { char *data; int strsize; int memsize; }


concatchar

decompiled_code:
__int64 __fastcall concatchar(__int64 a1, const void *a2, int a3)
{
int v4; // ebp
int v5; // ebx
void *v6; // rax

v4 = *(_DWORD *)(a1 + 8) + a3;
v5 = *(_DWORD *)(a1 + 12);
if ( v5 >= v4 )
goto LABEL_5;
do
v5 *= 2;
while ( v4 > v5 );
v6 = realloc(*(void **)a1, v5);
if ( v6 )
{
*(_QWORD *)a1 = v6;
LABEL_5:
memcpy((void *)(*(_QWORD *)a1 + *(int *)(a1 + 8) - 1LL), a2, a3);
*(_DWORD *)(a1 + 8) = v4;
*(_DWORD *)(a1 + 12) = v5;
*(_BYTE *)(*(_QWORD *)a1 + v4 - 1LL) = 0;
return 0LL;
}
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, const void *a2, int a3)
{
int v4; // ebp
int v5; // ebx
void *v6; // rax

v4 = *(_DWORD *)(a1 + 8) + a3;
v5 = *(_DWORD *)(a1 + 12);
if ( v5 >= v4 )
goto LABEL_5;
do
v5 *= 2;
while ( v4 > v5 );
v6 = realloc(*(void **)a1, v5);
if ( v6 )
{
*(_QWORD *)a1 = v6;
LABEL_5:
memcpy((void *)(*(_QWORD *)a1 + *(int *)(a1 + 8) - 1LL), a2, a3);
*(_DWORD *)(a1 + 8) = v4;
*(_DWORD *)(a1 + 12) = v5;
*(_BYTE *)(*(_QWORD *)a1 + v4 - 1LL) = 0;
return 0LL;
}
return 0xFFFFFFFFLL;
}

original_code:
int concatchar(str* s, char *data, int len) {
 int target;
 int newsize;
 char *t;
 target = len + s->strsize;
 if(target > s->memsize) {
  newsize = s->memsize;
  while(newsize < target)
   newsize *= 2;
  t = realloc(s->data, newsize);
  if(t == ((void *)0))
   return(-1);
  s->data = t;
 } else {
  newsize = s->memsize;
 }
 memcpy(&(s->data[s->strsize - 1]), data, len);
 s->strsize = target;
 s->memsize = newsize;
 s->data[s->strsize - 1] = '\0';
 return(0);
}

canonical_original_code:
int concatchar(struct str *s, char *data, int len) {
 int target;
 int newsize;
 char *t;
 target = len + s->strsize;
 if(target > s->memsize) {
  newsize = s->memsize;
  while(newsize < target)
   newsize *= 2;
  t = realloc(s->data, newsize);
  if(t == ((void *)0))
   return(-1);
  s->data = t;
 } else {
  newsize = s->memsize;
 }
 memcpy(&(s->data[s->strsize - 1]), data, len);
 s->strsize = target;
 s->memsize = newsize;
 s->data[s->strsize - 1] = '\0';
 return(0);
}

variable_types:
data
char *

variable_types: len int

variable_types: target int

variable_types: newsize int

variable_types:
t
char *


statusout

decompiled_code:
int __fastcall statusout(unsigned int a1, unsigned int a2)
{
return fprintf(stderr, "%u/%u\r", a1, a2);
}

canonical_decompiled_code:
int __fastcall func0(unsigned int a1, unsigned int a2)
{
return fprintf(stderr, "%u/%u\r", a1, a2);
}

original_code:
void statusout(int cur, int max) {
 fprintf(stderr, "%u/%u\r", cur, max);
}

variable_types: cur int

variable_types: max int


signalhandler

decompiled_code:
void __fastcall __noreturn signalhandler(unsigned int a1)
{
fprintf(stderr, "\n\nSignal %i received.\n", a1);
playnote((unsigned int)speaker, 0LL, 0LL);
close(speaker);
exit(0);
}

canonical_decompiled_code:
void __fastcall __noreturn func1(unsigned int a1)
{
fprintf(stderr, "\n\nSignal %i received.\n", a1);
playnote((unsigned int)speaker, 0LL, 0LL);
close(speaker);
exit(0);
}

original_code:
void signalhandler(int signum) {
 fprintf(stderr, "\n\nSignal %i received.\n", signum);
 playnote(speaker, 0, 0);
 close(speaker);
 exit(0);
}

variable_types: signum int


usage

decompiled_code:
void __fastcall __noreturn usage(const char *a1)
{
fprintf(
stderr,
"USAGE: %s <options>\n"
"Options:\n"
"--decompile / -d - Decompile string, used for outputting size-optimized code. (Currently disabled)\n"
"--device / -e device - Select event device, default is %s.\n"
"--filename / -f filename - Read from filename instead of standard input.\n"
"--quiet / -q - Don't play, only compile (and optionally decompile) then quit.\n"
"--display / -s - Display playback status.\n"
"--help / -h - Print help/usage. Refer to README for more information.\n"
"--debug - Enable debug mode.\n",
a1,
DEFAULT_DEVICE);
exit(-1);
}

canonical_decompiled_code:
void __fastcall __noreturn func2(const char *a1)
{
fprintf(
stderr,
"USAGE: %s <options>\n"
"Options:\n"
"--decompile / -d - Decompile string, used for outputting size-optimized code. (Currently disabled)\n"
"--device / -e device - Select event device, default is %s.\n"
"--filename / -f filename - Read from filename instead of standard input.\n"
"--quiet / -q - Don't play, only compile (and optionally decompile) then quit.\n"
"--display / -s - Display playback status.\n"
"--help / -h - Print help/usage. Refer to README for more information.\n"
"--debug - Enable debug mode.\n",
a1,
DEFAULT_DEVICE);
exit(-1);
}

original_code:
void usage(char *name) {
 fprintf(stderr, "USAGE: %s <options>\nOptions:\n--decompile / -d          - Decompile string, used for outputting size-optimized code. (Currently disabled)\n--device    / -e device   - Select event device, default is %s.\n--filename  / -f filename - Read from filename instead of standard input.\n--quiet     / -q          - Don't play, only compile (and optionally decompile) then quit.\n--display   / -s          - Display playback status.\n--help      / -h          - Print help/usage.  Refer to README for more information.\n--debug                   - Enable debug mode.\n", name, DEFAULT_DEVICE);
 exit(-1);
}

variable_types:
name
char *


initsong

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

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

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

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

original_code:
song *initsong() {
 song *s;
 s = malloc(sizeof(song));
 if(s == ((void *)0)) {
  return(((void *)0));
 }
 s->count = 0;
 s->first = ((void *)0);
 s->last = ((void *)0);
 s->current = ((void *)0);
 return(s);
}

canonical_original_code:
struct song *initsong() {
 struct song *s;
 s = malloc(sizeof(song));
 if(s == ((void *)0)) {
  return(((void *)0));
 }
 s->count = 0;
 s->first = ((void *)0);
 s->last = ((void *)0);
 s->current = ((void *)0);
 return(s);
}

variable_types: struct song { unsigned int count; struct command { enum instruction { NOTE=0, MOV=1, ADD=2, SUB=3, CMP=4, JNE=5, JE=6, JL=7, JG=8, JMP=9, BRA=10, RET=11, CFL=12, HALT=13, LABEL=14, JNEL=15, JEL=16, JLL=17, JGL=18, JMPL=19, BRAL=20, NOP=21 } cmd; unsigned int data; unsigned int reg; struct command *next; struct command *prev; } *first; struct command *last; struct command *current; struct command **offsets; int nlabels; int *labels; } *

user_defined_types: struct song { unsigned int count; struct command *first; struct command *last; struct command *current; struct command **offsets; int nlabels; int *labels; }

user_defined_types: struct command { enum instruction cmd; unsigned int data; unsigned int reg; struct command *next; struct command *prev; }


seeksong

decompiled_code:
__int64 __fastcall seeksong(__int64 a1, unsigned int a2)
{
if ( *(_DWORD *)a1 < a2 )
return 4294967294LL;
*(_QWORD *)(a1 + 24) = *(_QWORD *)(*(_QWORD *)(a1 + 32) + 8LL * (int)a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned int a2)
{
if ( *(_DWORD *)a1 < a2 )
return 4294967294LL;
*(_QWORD *)(a1 + 24) = *(_QWORD *)(*(_QWORD *)(a1 + 32) + 8LL * (int)a2);
return 0LL;
}

original_code:
int seeksong(song *s, int pos) {
 int i;
 if(pos > s->count)
  return(-2);
 s->current = s->offsets[pos];
 return(0);
}

canonical_original_code:
int seeksong(struct song *s, int pos) {
 int i;
 if(pos > s->count)
  return(-2);
 s->current = s->offsets[pos];
 return(0);
}

variable_types: pos int

variable_types: i int

user_defined_types: enum instruction { NOTE=0, MOV=1, ADD=2, SUB=3, CMP=4, JNE=5, JE=6, JL=7, JG=8, JMP=9, BRA=10, RET=11, CFL=12, HALT=13, LABEL=14, JNEL=15, JEL=16, JLL=17, JGL=18, JMPL=19, BRAL=20, NOP=21 }


initcommand

decompiled_code:
_DWORD *initcommand()
{
_DWORD *result; // rax

result = malloc(0x20uLL);
if ( result )
{
*result = 21;
result[2] = 0;
result[1] = 255;
*((_QWORD *)result + 3) = 0LL;
*((_QWORD *)result + 2) = 0LL;
}
return result;
}

canonical_decompiled_code:
_DWORD *func2()
{
_DWORD *result; // rax

result = malloc(0x20uLL);
if ( result )
{
*result = 21;
result[2] = 0;
result[1] = 255;
*((_QWORD *)result + 3) = 0LL;
*((_QWORD *)result + 2) = 0LL;
}
return result;
}

original_code:
command *initcommand() {
 command *c;
 c = malloc(sizeof(command));
 if(c == ((void *)0)) {
  return(((void *)0));
 }
 c->cmd = NOP;
 c->reg = (0);
 c->data = (0 << 8 | 0xFF);
 c->prev = ((void *)0);
 c->next = ((void *)0);
 return(c);
}

canonical_original_code:
struct command *initcommand() {
 struct command *c;
 c = malloc(sizeof(command));
 if(c == ((void *)0)) {
  return(((void *)0));
 }
 c->cmd = NOP;
 c->reg = (0);
 c->data = (0 << 8 | 0xFF);
 c->prev = ((void *)0);
 c->next = ((void *)0);
 return(c);
}

variable_types: struct command { enum instruction { NOTE=0, MOV=1, ADD=2, SUB=3, CMP=4, JNE=5, JE=6, JL=7, JG=8, JMP=9, BRA=10, RET=11, CFL=12, HALT=13, LABEL=14, JNEL=15, JEL=16, JLL=17, JGL=18, JMPL=19, BRAL=20, NOP=21 } cmd; unsigned int data; unsigned int reg; struct command *next; struct command *prev; } *


freecommand

decompiled_code:
__int64 __fastcall freecommand(void *a1)
{
if ( !a1 )
return 4294967294LL;
free(a1);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(void *a1)
{
if ( !a1 )
return 4294967294LL;
free(a1);
return 0LL;
}

original_code:
int freecommand(command *c) {
 if(c == ((void *)0))
  return(-2);
 free(c);
 return(0);
}

canonical_original_code:
int freecommand(struct command *c) {
 if(c == ((void *)0))
  return(-2);
 free(c);
 return(0);
}


freesong

decompiled_code:
__int64 __fastcall freesong(void *ptr)
{
_QWORD *i; // rdi
_QWORD *v3; // rbx

for ( i = (_QWORD *)*((_QWORD *)ptr + 1); ; i = v3 )
{
if ( !i )
{
free(*((void **)ptr + 4));
free(ptr);
return 0LL;
}
v3 = (_QWORD *)i[2];
if ( (int)freecommand(i) < 0 )
break;
}
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func4(void *ptr)
{
_QWORD *i; // rdi
_QWORD *v3; // rbx

for ( i = (_QWORD *)*((_QWORD *)ptr + 1); ; i = v3 )
{
if ( !i )
{
free(*((void **)ptr + 4));
free(ptr);
return 0LL;
}
v3 = (_QWORD *)i[2];
if ( (int)func3(i) < 0 )
break;
}
return 0xFFFFFFFFLL;
}

original_code:
int freesong(song *s) {
 command *cur;
 command *next;
 cur = s->first;
 while(cur != ((void *)0)) {
  next = cur->next;
  if(freecommand(cur) < 0)
   return(-1);
  cur = next;
 }
 free(s->offsets);
 free(s);
 return(0);
}

canonical_original_code:
int freesong(struct song *s) {
 struct command *cur;
 struct command *next;
 cur = s->first;
 while(cur != ((void *)0)) {
  next = cur->next;
  if(freecommand(cur) < 0)
   return(-1);
  cur = next;
 }
 free(s->offsets);
 free(s);
 return(0);
}


addcmd

original_code:
int addcmd(command *c, song *s) {
 if(s->current == ((void *)0)) {
  if(s->first == ((void *)0)) {
   s->first = c;
   s->last = c;
   s->current = ((void *)0);
  } else {
   s->last->next = c;
   c->prev = s->last;
   s->last = c;
   s->current = ((void *)0);
  }
 } else {
  if(s->current == s->first) {
   s->current->prev = c;
   c->next = s->current;
   s->first = c;
  } else {
   c->prev = s->current->prev;
   c->next = s->current;
   s->current->prev->next = c;
   s->current->prev = c;
  }
 }
 s->count++;
 return(0);
}

canonical_original_code:
int addcmd(struct command *c, struct song *s) {
 if(s->current == ((void *)0)) {
  if(s->first == ((void *)0)) {
   s->first = c;
   s->last = c;
   s->current = ((void *)0);
  } else {
   s->last->next = c;
   c->prev = s->last;
   s->last = c;
   s->current = ((void *)0);
  }
 } else {
  if(s->current == s->first) {
   s->current->prev = c;
   c->next = s->current;
   s->first = c;
  } else {
   c->prev = s->current->prev;
   c->next = s->current;
   s->current->prev->next = c;
   s->current->prev = c;
  }
 }
 s->count++;
 return(0);
}

variable_types: struct song { unsigned int count; struct command *first; struct command *last; struct command *current; struct command **offsets; int nlabels; int *labels; } *


delcmd

original_code:
command *delcmd(song *s) {
 command *cur, *set;
 if(s->current == ((void *)0))
  return(((void *)0));
 cur = s->current;
 if(s->current == s->first) {
  if(s->current == s->last) {
   s->first = ((void *)0);
   s->last = ((void *)0);
   s->current = ((void *)0);
  } else {
   set = s->current->next;
   s->first = s->current->next;
   s->current->next->prev = ((void *)0);
   s->current->next = ((void *)0);
   s->current = set;
  }
 } else {
  if(s->current == s->last) {
   s->last = s->current->prev;
   s->current->prev->next = ((void *)0);
   s->current->prev = ((void *)0);
   s->current = ((void *)0);
  } else {
   set = s->current->next;
   s->current->prev->next = s->current->next;
   s->current->next->prev = s->current->prev;
   s->current = set;
  }
 }
 return(cur);
}

canonical_original_code:
struct command *delcmd(struct song *s) {
 struct command *cur; struct command *set;
 if(s->current == ((void *)0))
  return(((void *)0));
 cur = s->current;
 if(s->current == s->first) {
  if(s->current == s->last) {
   s->first = ((void *)0);
   s->last = ((void *)0);
   s->current = ((void *)0);
  } else {
   set = s->current->next;
   s->first = s->current->next;
   s->current->next->prev = ((void *)0);
   s->current->next = ((void *)0);
   s->current = set;
  }
 } else {
  if(s->current == s->last) {
   s->last = s->current->prev;
   s->current->prev->next = ((void *)0);
   s->current->prev = ((void *)0);
   s->current = ((void *)0);
  } else {
   set = s->current->next;
   s->current->prev->next = s->current->next;
   s->current->next->prev = s->current->prev;
   s->current = set;
  }
 }
 return(cur);
}

return_type: struct command { enum instruction { NOTE=0, MOV=1, ADD=2, SUB=3, CMP=4, JNE=5, JE=6, JL=7, JG=8, JMP=9, BRA=10, RET=11, CFL=12, HALT=13, LABEL=14, JNEL=15, JEL=16, JLL=17, JGL=18, JMPL=19, BRAL=20, NOP=21 } cmd; unsigned int data; unsigned int reg; struct command *next; struct command *prev; } *


rewindsong

decompiled_code:
__int64 __fastcall rewindsong(__int64 a1)
{
*(_QWORD *)(a1 + 24) = *(_QWORD *)(a1 + 8);
return 0LL;
}

original_code:
int rewindsong(song *s) {
 s->current = s->first;
 return(0);
}

canonical_original_code:
int rewindsong(struct song *s) {
 s->current = s->first;
 return(0);
}


nextcommand

original_code:
int nextcommand(song *s) {
 if(s->current == ((void *)0))
  return(-2);
 s->current = s->current->next;
 if(s->current == ((void *)0))
  return(1);
 return(0);
}

canonical_original_code:
int nextcommand(struct song *s) {
 if(s->current == ((void *)0))
  return(-2);
 s->current = s->current->next;
 if(s->current == ((void *)0))
  return(1);
 return(0);
}


prevcommand

original_code:
int prevcommand(song *s) {
 if(s->current->prev == ((void *)0))
  return(-2);
 s->current = s->current->prev;
 return(0);
}

canonical_original_code:
int prevcommand(struct song *s) {
 if(s->current->prev == ((void *)0))
  return(-2);
 s->current = s->current->prev;
 return(0);
}


playsong

decompiled_code:
__int64 __fastcall playsong(int a1, unsigned int *a2, __int64 a3, void (__fastcall *a4)(_QWORD, _QWORD), int a5)
{
int i; // er12
unsigned int v10; // esi
unsigned __int64 v11; // rax
unsigned __int64 v12; // rcx
int v13; // edx
unsigned int v14; // edx
unsigned int v15; // edx
unsigned int v16; // eax
unsigned int v17; // eax
int v18; // eax
unsigned int v19; // ecx
unsigned int v20; // eax
unsigned int v21; // ecx
unsigned int v22; // eax
unsigned int v23; // edx
unsigned int v24; // eax
unsigned int v25; // eax
unsigned int v26; // esi
__int64 v27; // rdx
__int64 v28; // rcx
unsigned int v29; // eax
unsigned int v30; // eax
unsigned int v31; // eax
unsigned int v32; // eax
unsigned int v33; // eax
unsigned int v34; // eax
__int64 v35; // rcx
__int64 v36; // rax
unsigned int v37; // eax
int v38; // eax
unsigned int v39; // eax
int v40; // er15
__int64 v41; // rax
struct timespec remaining; // [rsp+10h] [rbp-58h] BYREF
struct timespec requested_time; // [rsp+20h] [rbp-48h] BYREF

for ( i = 2; ; ++i )
{
LABEL_146:
if ( a4 )
a4((unsigned int)(i - 1), *a2);
v41 = *((_QWORD *)a2 + 3);
*(_QWORD *)(a3 + 248) = v41;
if ( v41 )
break;
LABEL_193:
if ( v41 != *((_QWORD *)a2 + 3) )
return 4 * ((unsigned int)playnote(a1, 0, 0) >> 31);
v40 = 0;
LABEL_151:
if ( (unsigned int)nextcommand(a2) == 1 )
return 4 * ((unsigned int)playnote(a1, 0, 0) >> 31);
if ( v40 && a5 == 1 )
return 6;
if ( v40 != 1 )
return 4 * ((unsigned int)playnote(a1, 0, 0) >> 31);
}
v14 = *(_DWORD *)v41;
switch ( *(_DWORD *)v41 )
{
case 0:
v10 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v10 == 0xFF )
{
if ( (int)playnote(a1, v10 >> 8, *(_DWORD *)(a3 + 56)) >= 0 )
goto LABEL_5;
v14 = 4;
}
else if ( v10 > 0x19 )
{
v14 = 2;
}
else
{
if ( (int)playnote(a1, *(_DWORD *)(a3 + 4LL * v10), *(_DWORD *)(a3 + 56)) >= 0 )
{
LABEL_5:
v11 = 0xDF8475800uLL / *(unsigned int *)(a3 + 4) / *(unsigned int *)(a3 + 12);
v12 = v11;
v13 = *(_DWORD *)(a3 + 44);
if ( v13 == 1 )
{
v12 = (3 * v11) >> 1;
}
else if ( v13 == 2 )
{
v12 = v11 / 3;
}
requested_time.tv_sec = v12 / 0x3B9ACA00;
requested_time.tv_nsec = v12 % 0x3B9ACA00;
while ( nanosleep(&requested_time, &remaining) == -1 )
requested_time = remaining;
goto LABEL_143;
}
v14 = 4;
}
return v14;
case 1:
v15 = *(_DWORD *)(v41 + 8);
if ( v15 > 0x19 )
return 3;
v16 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v16 == 0xFF )
{
if ( v15 == 11 )
{
v17 = v16 >> 8;
if ( *(_DWORD *)(a3 + 44) == v17 )
v17 = 0;
*(_DWORD *)(a3 + 44) = v17;
}
else
{
*(_DWORD *)(a3 + 4LL * v15) = v16 >> 8;
}
goto LABEL_20;
}
if ( v16 <= 0x19 )
{
if ( v15 == 11 )
{
v18 = *(_DWORD *)(a3 + 4LL * v16);
if ( *(_DWORD *)(a3 + 44) == v18 )
v18 = 0;
*(_DWORD *)(a3 + 44) = v18;
}
else
{
*(_DWORD *)(a3 + 4LL * v15) = *(_DWORD *)(a3 + 4LL * v16);
}
LABEL_20:
if ( *(_DWORD *)(a3 + 56) > 6u )
*(_DWORD *)(a3 + 56) = 6;
if ( !*(_DWORD *)(a3 + 12) )
*(_DWORD *)(a3 + 12) = 1;
if ( !*(_DWORD *)(a3 + 4) )
*(_DWORD *)(a3 + 4) = 1;
if ( *(_DWORD *)(a3 + 44) > 2u )
*(_DWORD *)(a3 + 44) = 0;
goto LABEL_143;
}
return 2;
case 2:
v19 = *(_DWORD *)(v41 + 8);
if ( v19 > 0x19 )
return 3;
v20 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v20 == 0xFF )
{
*(_DWORD *)(a3 + 4LL * v19) += v20 >> 8;
}
else
{
if ( v20 > 0x19 )
return v14;
*(_DWORD *)(a3 + 4LL * v19) += *(_DWORD *)(a3 + 4LL * v20);
}
if ( *(_DWORD *)(a3 + 56) > 6u )
*(_DWORD *)(a3 + 56) = 6;
if ( *(_DWORD *)(a3 + 44) > 2u )
*(_DWORD *)(a3 + 44) = 0;
LABEL_143:
v40 = 1;
if ( *((_QWORD *)a2 + 3) == *(_QWORD *)(a3 + 248) )
goto LABEL_151;
if ( a5 == 1 )
return 6;
++i;
goto LABEL_146;
case 3:
v21 = *(_DWORD *)(v41 + 8);
if ( v21 > 0x19 )
return v14;
v22 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v22 == 0xFF )
{
*(_DWORD *)(a3 + 4LL * v21) -= v22 >> 8;
}
else
{
if ( v22 > 0x19 )
return 2;
*(_DWORD *)(a3 + 4LL * v21) -= *(_DWORD *)(a3 + 4LL * v22);
}
if ( !*(_DWORD *)(a3 + 12) )
*(_DWORD *)(a3 + 12) = 1;
goto LABEL_143;
case 4:
v23 = *(_DWORD *)(v41 + 8);
if ( v23 > 0x19 )
return 3;
v24 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v24 == 0xFF )
{
v25 = v24 >> 8;
if ( *(_DWORD *)(a3 + 4LL * v23) < v25 )
*(_DWORD *)(a3 + 104) |= 2u;
if ( *(_DWORD *)(a3 + 4LL * *(unsigned int *)(*((_QWORD *)a2 + 3) + 8LL)) == v25 )
*(_DWORD *)(a3 + 104) |= 1u;
}
else
{
if ( v24 > 0x19 )
return 2;
if ( *(_DWORD *)(a3 + 4LL * v24) > *(_DWORD *)(a3 + 4LL * v23) )
*(_DWORD *)(a3 + 104) |= 2u;
if ( *(_DWORD *)(a3 + 4LL * *(unsigned int *)(*((_QWORD *)a2 + 3) + 4LL)) == *(_DWORD *)(a3
+ 4LL
* *(unsigned int *)(*((_QWORD *)a2 + 3) + 8LL)) )
*(_DWORD *)(a3 + 104) |= 1u;
}
goto LABEL_143;
case 5:
v26 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v26 != 0xFF )
{
if ( v26 <= 0x19 )
{
if ( (*(_BYTE *)(a3 + 104) & 1) != 0 )
goto LABEL_143;
LABEL_94:
seeksong(a2, *(unsigned int *)(a3 + 4LL * v26));
goto LABEL_143;
}
return 2;
}
if ( (*(_BYTE *)(a3 + 104) & 1) != 0 )
goto LABEL_143;
goto LABEL_86;
case 6:
v26 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v26 == 0xFF )
{
if ( (*(_BYTE *)(a3 + 104) & 1) == 0 )
goto LABEL_143;
LABEL_86:
seeksong(a2, v26 >> 8);
goto LABEL_143;
}
if ( v26 <= 0x19 )
{
if ( (*(_BYTE *)(a3 + 104) & 1) == 0 )
goto LABEL_143;
goto LABEL_94;
}
return 2;
case 7:
v26 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v26 != 0xFF )
{
if ( v26 <= 0x19 )
{
if ( (*(_BYTE *)(a3 + 104) & 2) != 0 )
goto LABEL_143;
goto LABEL_94;
}
return 2;
}
if ( (*(_BYTE *)(a3 + 104) & 2) != 0 )
goto LABEL_143;
goto LABEL_86;
case 8:
v26 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v26 != 0xFF )
{
if ( v26 <= 0x19 )
{
if ( (*(_BYTE *)(a3 + 104) & 2) == 0 )
goto LABEL_143;
goto LABEL_94;
}
return 2;
}
if ( (*(_BYTE *)(a3 + 104) & 2) == 0 )
goto LABEL_143;
goto LABEL_86;
case 9:
v26 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v26 == 0xFF )
goto LABEL_86;
if ( v26 <= 0x19 )
goto LABEL_94;
return 2;
case 0xA:
v27 = *(_QWORD *)(v41 + 16);
if ( v27 )
{
v28 = *(unsigned int *)(a3 + 240);
*(_QWORD *)(a3 + 8 * v28 + 112) = v27;
*(_DWORD *)(a3 + 240) = v28 + 1;
v26 = *(_DWORD *)(*((_QWORD *)a2 + 3) + 4LL);
if ( (_BYTE)v26 == 0xFF )
goto LABEL_86;
if ( v26 > 0x19 )
return 2;
goto LABEL_94;
}
return 1;
case 0xB:
v38 = *(_DWORD *)(a3 + 240);
if ( !v38 )
return 1;
v39 = v38 - 1;
*(_DWORD *)(a3 + 240) = v39;
*((_QWORD *)a2 + 3) = *(_QWORD *)(a3 + 8LL * v39 + 112);
goto LABEL_143;
case 0xC:
*(_DWORD *)(a3 + 104) = 0;
goto LABEL_143;
case 0xD:
goto LABEL_193;
case 0xE:
goto LABEL_143;
case 0xF:
v29 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v29 == 0xFF )
{
if ( (*(_BYTE *)(a3 + 104) & 1) != 0 )
goto LABEL_143;
v30 = v29 >> 8;
if ( a2[10] < v30 )
return 2;
goto LABEL_139;
}
if ( v29 > 0x19 )
return 2;
if ( (*(_BYTE *)(a3 + 104) & 1) == 0 )
{
v30 = *(_DWORD *)(a3 + 4LL * v29);
if ( v30 > a2[10] )
return 2;
LABEL_139:
seeksong(a2, *(unsigned int *)(*((_QWORD *)a2 + 6) + 4LL * v30));
goto LABEL_143;
}
goto LABEL_143;
case 0x10:
v31 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v31 == 0xFF )
{
if ( (*(_BYTE *)(a3 + 104) & 1) == 0 )
goto LABEL_143;
v30 = v31 >> 8;
if ( a2[10] < v30 )
return 2;
goto LABEL_139;
}
if ( v31 > 0x19 )
return 2;
if ( (*(_BYTE *)(a3 + 104) & 1) != 0 )
{
v30 = *(_DWORD *)(a3 + 4LL * v31);
if ( v30 > a2[10] )
return 2;
goto LABEL_139;
}
goto LABEL_143;
case 0x11:
v32 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v32 == 0xFF )
{
if ( (*(_BYTE *)(a3 + 104) & 2) != 0 )
goto LABEL_143;
v30 = v32 >> 8;
if ( a2[10] < v30 )
return 2;
goto LABEL_139;
}
if ( v32 > 0x19 )
return 2;
if ( (*(_BYTE *)(a3 + 104) & 2) == 0 )
{
v30 = *(_DWORD *)(a3 + 4LL * v32);
if ( v30 > a2[10] )
return 2;
goto LABEL_139;
}
goto LABEL_143;
case 0x12:
v33 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v33 == 0xFF )
{
if ( (*(_BYTE *)(a3 + 104) & 2) == 0 )
goto LABEL_143;
v30 = v33 >> 8;
if ( a2[10] < v30 )
return 2;
goto LABEL_139;
}
if ( v33 > 0x19 )
return 2;
if ( (*(_BYTE *)(a3 + 104) & 2) != 0 )
{
v30 = *(_DWORD *)(a3 + 4LL * v33);
if ( v30 > a2[10] )
return 2;
goto LABEL_139;
}
goto LABEL_143;
case 0x13:
v34 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v34 == 0xFF )
{
v30 = v34 >> 8;
if ( a2[10] < v30 )
return 2;
}
else
{
if ( v34 > 0x19 )
return 2;
v30 = *(_DWORD *)(a3 + 4LL * v34);
if ( v30 > a2[10] )
return 2;
}
goto LABEL_139;
case 0x14:
v35 = *(_QWORD *)(v41 + 16);
v36 = *(unsigned int *)(a3 + 240);
*(_QWORD *)(a3 + 8 * v36 + 112) = v35;
*(_DWORD *)(a3 + 240) = v36 + 1;
v37 = *(_DWORD *)(*((_QWORD *)a2 + 3) + 4LL);
if ( (_BYTE)v37 == 0xFF )
{
v30 = v37 >> 8;
if ( a2[10] < v30 )
return 2;
}
else
{
if ( v37 > 0x19 )
return 2;
v30 = *(_DWORD *)(a3 + 4LL * v37);
if ( v30 > a2[10] )
return 2;
}
goto LABEL_139;
default:
return 1;
}
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1, unsigned int *a2, __int64 a3, void (__fastcall *a4)(_QWORD, _QWORD), int a5)
{
int i; // er12
unsigned int v10; // esi
unsigned __int64 v11; // rax
unsigned __int64 v12; // rcx
int v13; // edx
unsigned int v14; // edx
unsigned int v15; // edx
unsigned int v16; // eax
unsigned int v17; // eax
int v18; // eax
unsigned int v19; // ecx
unsigned int v20; // eax
unsigned int v21; // ecx
unsigned int v22; // eax
unsigned int v23; // edx
unsigned int v24; // eax
unsigned int v25; // eax
unsigned int v26; // esi
__int64 v27; // rdx
__int64 v28; // rcx
unsigned int v29; // eax
unsigned int v30; // eax
unsigned int v31; // eax
unsigned int v32; // eax
unsigned int v33; // eax
unsigned int v34; // eax
__int64 v35; // rcx
__int64 v36; // rax
unsigned int v37; // eax
int v38; // eax
unsigned int v39; // eax
int v40; // er15
__int64 v41; // rax
struct timespec remaining; // [rsp+10h] [rbp-58h] BYREF
struct timespec requested_time; // [rsp+20h] [rbp-48h] BYREF

for ( i = 2; ; ++i )
{
LABEL_146:
if ( a4 )
a4((unsigned int)(i - 1), *a2);
v41 = *((_QWORD *)a2 + 3);
*(_QWORD *)(a3 + 248) = v41;
if ( v41 )
break;
LABEL_193:
if ( v41 != *((_QWORD *)a2 + 3) )
return 4 * ((unsigned int)func0(a1, 0, 0) >> 31);
v40 = 0;
LABEL_151:
if ( (unsigned int)nextcommand(a2) == 1 )
return 4 * ((unsigned int)func0(a1, 0, 0) >> 31);
if ( v40 && a5 == 1 )
return 6;
if ( v40 != 1 )
return 4 * ((unsigned int)func0(a1, 0, 0) >> 31);
}
v14 = *(_DWORD *)v41;
switch ( *(_DWORD *)v41 )
{
case 0:
v10 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v10 == 0xFF )
{
if ( (int)func0(a1, v10 >> 8, *(_DWORD *)(a3 + 56)) >= 0 )
goto LABEL_5;
v14 = 4;
}
else if ( v10 > 0x19 )
{
v14 = 2;
}
else
{
if ( (int)func0(a1, *(_DWORD *)(a3 + 4LL * v10), *(_DWORD *)(a3 + 56)) >= 0 )
{
LABEL_5:
v11 = 0xDF8475800uLL / *(unsigned int *)(a3 + 4) / *(unsigned int *)(a3 + 12);
v12 = v11;
v13 = *(_DWORD *)(a3 + 44);
if ( v13 == 1 )
{
v12 = (3 * v11) >> 1;
}
else if ( v13 == 2 )
{
v12 = v11 / 3;
}
requested_time.tv_sec = v12 / 0x3B9ACA00;
requested_time.tv_nsec = v12 % 0x3B9ACA00;
while ( nanosleep(&requested_time, &remaining) == -1 )
requested_time = remaining;
goto LABEL_143;
}
v14 = 4;
}
return v14;
case 1:
v15 = *(_DWORD *)(v41 + 8);
if ( v15 > 0x19 )
return 3;
v16 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v16 == 0xFF )
{
if ( v15 == 11 )
{
v17 = v16 >> 8;
if ( *(_DWORD *)(a3 + 44) == v17 )
v17 = 0;
*(_DWORD *)(a3 + 44) = v17;
}
else
{
*(_DWORD *)(a3 + 4LL * v15) = v16 >> 8;
}
goto LABEL_20;
}
if ( v16 <= 0x19 )
{
if ( v15 == 11 )
{
v18 = *(_DWORD *)(a3 + 4LL * v16);
if ( *(_DWORD *)(a3 + 44) == v18 )
v18 = 0;
*(_DWORD *)(a3 + 44) = v18;
}
else
{
*(_DWORD *)(a3 + 4LL * v15) = *(_DWORD *)(a3 + 4LL * v16);
}
LABEL_20:
if ( *(_DWORD *)(a3 + 56) > 6u )
*(_DWORD *)(a3 + 56) = 6;
if ( !*(_DWORD *)(a3 + 12) )
*(_DWORD *)(a3 + 12) = 1;
if ( !*(_DWORD *)(a3 + 4) )
*(_DWORD *)(a3 + 4) = 1;
if ( *(_DWORD *)(a3 + 44) > 2u )
*(_DWORD *)(a3 + 44) = 0;
goto LABEL_143;
}
return 2;
case 2:
v19 = *(_DWORD *)(v41 + 8);
if ( v19 > 0x19 )
return 3;
v20 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v20 == 0xFF )
{
*(_DWORD *)(a3 + 4LL * v19) += v20 >> 8;
}
else
{
if ( v20 > 0x19 )
return v14;
*(_DWORD *)(a3 + 4LL * v19) += *(_DWORD *)(a3 + 4LL * v20);
}
if ( *(_DWORD *)(a3 + 56) > 6u )
*(_DWORD *)(a3 + 56) = 6;
if ( *(_DWORD *)(a3 + 44) > 2u )
*(_DWORD *)(a3 + 44) = 0;
LABEL_143:
v40 = 1;
if ( *((_QWORD *)a2 + 3) == *(_QWORD *)(a3 + 248) )
goto LABEL_151;
if ( a5 == 1 )
return 6;
++i;
goto LABEL_146;
case 3:
v21 = *(_DWORD *)(v41 + 8);
if ( v21 > 0x19 )
return v14;
v22 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v22 == 0xFF )
{
*(_DWORD *)(a3 + 4LL * v21) -= v22 >> 8;
}
else
{
if ( v22 > 0x19 )
return 2;
*(_DWORD *)(a3 + 4LL * v21) -= *(_DWORD *)(a3 + 4LL * v22);
}
if ( !*(_DWORD *)(a3 + 12) )
*(_DWORD *)(a3 + 12) = 1;
goto LABEL_143;
case 4:
v23 = *(_DWORD *)(v41 + 8);
if ( v23 > 0x19 )
return 3;
v24 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v24 == 0xFF )
{
v25 = v24 >> 8;
if ( *(_DWORD *)(a3 + 4LL * v23) < v25 )
*(_DWORD *)(a3 + 104) |= 2u;
if ( *(_DWORD *)(a3 + 4LL * *(unsigned int *)(*((_QWORD *)a2 + 3) + 8LL)) == v25 )
*(_DWORD *)(a3 + 104) |= 1u;
}
else
{
if ( v24 > 0x19 )
return 2;
if ( *(_DWORD *)(a3 + 4LL * v24) > *(_DWORD *)(a3 + 4LL * v23) )
*(_DWORD *)(a3 + 104) |= 2u;
if ( *(_DWORD *)(a3 + 4LL * *(unsigned int *)(*((_QWORD *)a2 + 3) + 4LL)) == *(_DWORD *)(a3
+ 4LL
* *(unsigned int *)(*((_QWORD *)a2 + 3) + 8LL)) )
*(_DWORD *)(a3 + 104) |= 1u;
}
goto LABEL_143;
case 5:
v26 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v26 != 0xFF )
{
if ( v26 <= 0x19 )
{
if ( (*(_BYTE *)(a3 + 104) & 1) != 0 )
goto LABEL_143;
LABEL_94:
seeksong(a2, *(unsigned int *)(a3 + 4LL * v26));
goto LABEL_143;
}
return 2;
}
if ( (*(_BYTE *)(a3 + 104) & 1) != 0 )
goto LABEL_143;
goto LABEL_86;
case 6:
v26 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v26 == 0xFF )
{
if ( (*(_BYTE *)(a3 + 104) & 1) == 0 )
goto LABEL_143;
LABEL_86:
seeksong(a2, v26 >> 8);
goto LABEL_143;
}
if ( v26 <= 0x19 )
{
if ( (*(_BYTE *)(a3 + 104) & 1) == 0 )
goto LABEL_143;
goto LABEL_94;
}
return 2;
case 7:
v26 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v26 != 0xFF )
{
if ( v26 <= 0x19 )
{
if ( (*(_BYTE *)(a3 + 104) & 2) != 0 )
goto LABEL_143;
goto LABEL_94;
}
return 2;
}
if ( (*(_BYTE *)(a3 + 104) & 2) != 0 )
goto LABEL_143;
goto LABEL_86;
case 8:
v26 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v26 != 0xFF )
{
if ( v26 <= 0x19 )
{
if ( (*(_BYTE *)(a3 + 104) & 2) == 0 )
goto LABEL_143;
goto LABEL_94;
}
return 2;
}
if ( (*(_BYTE *)(a3 + 104) & 2) == 0 )
goto LABEL_143;
goto LABEL_86;
case 9:
v26 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v26 == 0xFF )
goto LABEL_86;
if ( v26 <= 0x19 )
goto LABEL_94;
return 2;
case 0xA:
v27 = *(_QWORD *)(v41 + 16);
if ( v27 )
{
v28 = *(unsigned int *)(a3 + 240);
*(_QWORD *)(a3 + 8 * v28 + 112) = v27;
*(_DWORD *)(a3 + 240) = v28 + 1;
v26 = *(_DWORD *)(*((_QWORD *)a2 + 3) + 4LL);
if ( (_BYTE)v26 == 0xFF )
goto LABEL_86;
if ( v26 > 0x19 )
return 2;
goto LABEL_94;
}
return 1;
case 0xB:
v38 = *(_DWORD *)(a3 + 240);
if ( !v38 )
return 1;
v39 = v38 - 1;
*(_DWORD *)(a3 + 240) = v39;
*((_QWORD *)a2 + 3) = *(_QWORD *)(a3 + 8LL * v39 + 112);
goto LABEL_143;
case 0xC:
*(_DWORD *)(a3 + 104) = 0;
goto LABEL_143;
case 0xD:
goto LABEL_193;
case 0xE:
goto LABEL_143;
case 0xF:
v29 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v29 == 0xFF )
{
if ( (*(_BYTE *)(a3 + 104) & 1) != 0 )
goto LABEL_143;
v30 = v29 >> 8;
if ( a2[10] < v30 )
return 2;
goto LABEL_139;
}
if ( v29 > 0x19 )
return 2;
if ( (*(_BYTE *)(a3 + 104) & 1) == 0 )
{
v30 = *(_DWORD *)(a3 + 4LL * v29);
if ( v30 > a2[10] )
return 2;
LABEL_139:
seeksong(a2, *(unsigned int *)(*((_QWORD *)a2 + 6) + 4LL * v30));
goto LABEL_143;
}
goto LABEL_143;
case 0x10:
v31 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v31 == 0xFF )
{
if ( (*(_BYTE *)(a3 + 104) & 1) == 0 )
goto LABEL_143;
v30 = v31 >> 8;
if ( a2[10] < v30 )
return 2;
goto LABEL_139;
}
if ( v31 > 0x19 )
return 2;
if ( (*(_BYTE *)(a3 + 104) & 1) != 0 )
{
v30 = *(_DWORD *)(a3 + 4LL * v31);
if ( v30 > a2[10] )
return 2;
goto LABEL_139;
}
goto LABEL_143;
case 0x11:
v32 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v32 == 0xFF )
{
if ( (*(_BYTE *)(a3 + 104) & 2) != 0 )
goto LABEL_143;
v30 = v32 >> 8;
if ( a2[10] < v30 )
return 2;
goto LABEL_139;
}
if ( v32 > 0x19 )
return 2;
if ( (*(_BYTE *)(a3 + 104) & 2) == 0 )
{
v30 = *(_DWORD *)(a3 + 4LL * v32);
if ( v30 > a2[10] )
return 2;
goto LABEL_139;
}
goto LABEL_143;
case 0x12:
v33 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v33 == 0xFF )
{
if ( (*(_BYTE *)(a3 + 104) & 2) == 0 )
goto LABEL_143;
v30 = v33 >> 8;
if ( a2[10] < v30 )
return 2;
goto LABEL_139;
}
if ( v33 > 0x19 )
return 2;
if ( (*(_BYTE *)(a3 + 104) & 2) != 0 )
{
v30 = *(_DWORD *)(a3 + 4LL * v33);
if ( v30 > a2[10] )
return 2;
goto LABEL_139;
}
goto LABEL_143;
case 0x13:
v34 = *(_DWORD *)(v41 + 4);
if ( (_BYTE)v34 == 0xFF )
{
v30 = v34 >> 8;
if ( a2[10] < v30 )
return 2;
}
else
{
if ( v34 > 0x19 )
return 2;
v30 = *(_DWORD *)(a3 + 4LL * v34);
if ( v30 > a2[10] )
return 2;
}
goto LABEL_139;
case 0x14:
v35 = *(_QWORD *)(v41 + 16);
v36 = *(unsigned int *)(a3 + 240);
*(_QWORD *)(a3 + 8 * v36 + 112) = v35;
*(_DWORD *)(a3 + 240) = v36 + 1;
v37 = *(_DWORD *)(*((_QWORD *)a2 + 3) + 4LL);
if ( (_BYTE)v37 == 0xFF )
{
v30 = v37 >> 8;
if ( a2[10] < v30 )
return 2;
}
else
{
if ( v37 > 0x19 )
return 2;
v30 = *(_DWORD *)(a3 + 4LL * v37);
if ( v30 > a2[10] )
return 2;
}
goto LABEL_139;
default:
return 1;
}
}

original_code:
vmexception playsong(int fd, song *s, vmstate *vm, void (*status)(int cur, int max), int step) {
 int i;
 struct timespec req, rem;
 unsigned long int notelen;
 unsigned int t;
 int running;
 i = 1;
 running = 1;
 while(running == 1) {
  if(status != ((void *)0))
   status(i, s->count);
  vm->last = s->current;
  if(s->current != ((void *)0)) {
   switch(s->current->cmd) {
    case NOTE:
      if((s->current->data & 0xFF) == 0xFF) {
       t = (s->current->data >> 8);
       if(playnote(fd, (s->current->data >> 8), vm->regs[(14)]) < 0)
        return(DEVICE_ERROR);
      } else if(s->current->data < 26) {
       if(playnote(fd, vm->regs[s->current->data], vm->regs[(14)]) < 0)
        return(DEVICE_ERROR);
      } else {
       return(BAD_ARGUMENT);
      }
     notelen = 60000000000ul / vm->regs[(1)] / vm->regs[(3)];
     if(vm->regs[(11)] == (1)) {
      notelen = notelen * 3 / 2;
     } else if(vm->regs[(11)] == (2)) {
      notelen = notelen / 3;
     }
     req.tv_sec = notelen / 1000000000ul;
     req.tv_nsec = notelen % 1000000000ul;
     while(nanosleep(&req, &rem) == -1) {
      req.tv_sec = rem.tv_sec;
      req.tv_nsec = rem.tv_nsec;
     }
     break;
    case MOV:
     if(s->current->reg < 26) {
      if((s->current->data & 0xFF) == 0xFF) {
       if(s->current->reg == (11)) {
        if(vm->regs[(11)] == (s->current->data >> 8)) {
         vm->regs[(11)] = 0;
        } else {
         vm->regs[s->current->reg] = (s->current->data >> 8);
        }
       } else {
        vm->regs[s->current->reg] = (s->current->data >> 8);
       }
      } else if(s->current->data < 26) {
       if(s->current->reg == (11)) {
        if(vm->regs[(11)] == vm->regs[s->current->data]) {
         vm->regs[(11)] = 0;
        } else {
         vm->regs[s->current->reg] = vm->regs[s->current->data];
        }
       } else {
        vm->regs[s->current->reg] = vm->regs[s->current->data];
       }
      } else {
       return(BAD_ARGUMENT);
      }
     } else {
      return(BAD_REGISTER);
     }
     if(vm->regs[(14)] > 6)
      vm->regs[(14)] = 6;
     if(vm->regs[(3)] < 1)
      vm->regs[(3)] = 1;
     if(vm->regs[(1)] < 1)
      vm->regs[(1)] = 1;
     if(vm->regs[(11)] > 2)
      vm->regs[(11)] = 0;
     break;
    case ADD:
     if(s->current->reg < 26) {
      if((s->current->data & 0xFF) == 0xFF) {
       vm->regs[s->current->reg] += (s->current->data >> 8);
      } else if(s->current->data < 26) {
       vm->regs[s->current->reg] += vm->regs[s->current->data];
      } else {
       return(BAD_ARGUMENT);
      }
     } else {
      return(BAD_REGISTER);
     }
     if(vm->regs[(14)] > 6)
      vm->regs[(14)] = 6;
     if(vm->regs[(11)] > 2)
      vm->regs[(11)] = 0;
     break;
    case SUB:
     if(s->current->reg < 26) {
      if((s->current->data & 0xFF) == 0xFF) {
       vm->regs[s->current->reg] -= (s->current->data >> 8);
      } else if(s->current->data < 26) {
       vm->regs[s->current->reg] -= vm->regs[s->current->data];
      } else {
       return(BAD_ARGUMENT);
      }
     } else {
      return(BAD_REGISTER);
     }
     if(vm->regs[(3)] < 1)
      vm->regs[(3)] = 1;
     break;
    case CMP:
     if(s->current->reg < 26) {
      if((s->current->data & 0xFF) == 0xFF) {
       t = (s->current->data >> 8);
       if(t > vm->regs[s->current->reg])
        vm->flags |= (2);
       if(t == vm->regs[s->current->reg])
        vm->flags |= (1);
      } else if(s->current->data < 26) {
       if(vm->regs[s->current->data] > vm->regs[s->current->reg])
        vm->flags |= (2);
       if(vm->regs[s->current->data] == vm->regs[s->current->reg])
        vm->flags |= (1);
      } else {
       return(BAD_ARGUMENT);
      }
     } else {
      return(BAD_REGISTER);
     }
     break;
    case JNE:
     if((s->current->data & 0xFF) == 0xFF) {
      if(!(vm->flags & (1))) {
       t = (s->current->data >> 8);
       seeksong(s, t);
      }
     } else if(s->current->data < 26) {
      if(!(vm->flags & (1)))
       seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JE:
     if((s->current->data & 0xFF) == 0xFF) {
      if(vm->flags & (1)) {
       t = (s->current->data >> 8);
       seeksong(s, t);
      }
     } else if(s->current->data < 26) {
      if(vm->flags & (1))
       seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JL:
     if((s->current->data & 0xFF) == 0xFF) {
      if(!(vm->flags & (2))) {
       t = (s->current->data >> 8);
       seeksong(s, t);
      }
     } else if(s->current->data < 26) {
      if(!(vm->flags & (2)))
       seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JG:
     if((s->current->data & 0xFF) == 0xFF) {
      if(vm->flags & (2)) {
       t = (s->current->data >> 8);
       seeksong(s, t);
      }
     } else if(s->current->data < 26) {
      if(vm->flags & (2))
       seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JMP:
     if((s->current->data & 0xFF) == 0xFF) {
      t = (s->current->data >> 8);
      seeksong(s, t);
     } else if(s->current->data < 26) {
      seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case BRA:
     if(s->current->next == ((void *)0))
      return(ILLEGAL_INSTRUCTION);
     vm->stack[vm->sp] = s->current->next;
     vm->sp++;
     if((s->current->data & 0xFF) == 0xFF) {
      t = (s->current->data >> 8);
      seeksong(s, t);
     } else if(s->current->data < 26) {
      seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JNEL:
     if((s->current->data & 0xFF) == 0xFF) {
      if(!(vm->flags & (1))) {
       t = (s->current->data >> 8);
       if(t > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[t]);
      }
     } else if(s->current->data < 26) {
      if(!(vm->flags & (1))) {
       if(vm->regs[s->current->data] > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[vm->regs[s->current->data]]);
      }
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JEL:
     if((s->current->data & 0xFF) == 0xFF) {
      if(vm->flags & (1)) {
       t = (s->current->data >> 8);
       if(t > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[t]);
      }
     } else if(s->current->data < 26) {
      if(vm->flags & (1)) {
       if(vm->regs[s->current->data] > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[vm->regs[s->current->data]]);
      }
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JLL:
     if((s->current->data & 0xFF) == 0xFF) {
      if(!(vm->flags & (2))) {
       t = (s->current->data >> 8);
       if(t > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[t]);
      }
     } else if(s->current->data < 26) {
      if(!(vm->flags & (2))) {
       if(vm->regs[s->current->data] > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[vm->regs[s->current->data]]);
      }
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JGL:
     if((s->current->data & 0xFF) == 0xFF) {
      if(vm->flags & (2)) {
       t = (s->current->data >> 8);
       if(t > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[t]);
      }
     } else if(s->current->data < 26) {
      if(vm->flags & (2)) {
       if(vm->regs[s->current->data] > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[vm->regs[s->current->data]]);
      }
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JMPL:
     if((s->current->data & 0xFF) == 0xFF) {
      t = (s->current->data >> 8);
      if(t > s->nlabels)
       return(BAD_ARGUMENT);
      seeksong(s, s->labels[t]);
     } else if(s->current->data < 26) {
       if(vm->regs[s->current->data] > s->nlabels)
       return(BAD_ARGUMENT);
      seeksong(s, s->labels[vm->regs[s->current->data]]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case BRAL:
     vm->stack[vm->sp] = s->current->next;
     vm->sp++;
     if((s->current->data & 0xFF) == 0xFF) {
      t = (s->current->data >> 8);
      if(t > s->nlabels)
       return(BAD_ARGUMENT);
      seeksong(s, s->labels[t]);
     } else if(s->current->data < 26) {
       if(vm->regs[s->current->data] > s->nlabels)
       return(BAD_ARGUMENT);
      seeksong(s, s->labels[vm->regs[s->current->data]]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case RET:
     if(vm->sp == 0)
      return(ILLEGAL_INSTRUCTION);
     vm->sp--;
     s->current = vm->stack[vm->sp];
     break;
    case CFL:
     vm->flags = 0;
     break;
    case HALT:
     running = 0;
     break;
    case LABEL:
     break;
    default:
     return(ILLEGAL_INSTRUCTION);
     break;
   }
  } else {
   running = 0;
  }
  i++;
  if(s->current == vm->last)
   if(nextcommand(s) == 1)
    running = 0;
  if(running == 1 && step == 1) {
   return(BREAKPOINT);
  }
 }
 if(playnote(fd, 0, 0) < 0)
  return(DEVICE_ERROR);
 return(PROGRAM_ENDED);
}

canonical_original_code:
enum vmexception playsong(int fd, struct song *s, struct vmstate *vm, void (*status)(int cur, int max), int step) {
 int i;
 struct timespec req; struct timespec rem;
 unsigned long notelen;
 unsigned int t;
 int running;
 i = 1;
 running = 1;
 while(running == 1) {
  if(status != ((void *)0))
   status(i, s->count);
  vm->last = s->current;
  if(s->current != ((void *)0)) {
   switch(s->current->cmd) {
    case NOTE:
      if((s->current->data & 0xFF) == 0xFF) {
       t = (s->current->data >> 8);
       if(playnote(fd, (s->current->data >> 8), vm->regs[(14)]) < 0)
        return(DEVICE_ERROR);
      } else if(s->current->data < 26) {
       if(playnote(fd, vm->regs[s->current->data], vm->regs[(14)]) < 0)
        return(DEVICE_ERROR);
      } else {
       return(BAD_ARGUMENT);
      }
     notelen = 60000000000ul / vm->regs[(1)] / vm->regs[(3)];
     if(vm->regs[(11)] == (1)) {
      notelen = notelen * 3 / 2;
     } else if(vm->regs[(11)] == (2)) {
      notelen = notelen / 3;
     }
     req.tv_sec = notelen / 1000000000ul;
     req.tv_nsec = notelen % 1000000000ul;
     while(nanosleep(&req, &rem) == -1) {
      req.tv_sec = rem.tv_sec;
      req.tv_nsec = rem.tv_nsec;
     }
     break;
    case MOV:
     if(s->current->reg < 26) {
      if((s->current->data & 0xFF) == 0xFF) {
       if(s->current->reg == (11)) {
        if(vm->regs[(11)] == (s->current->data >> 8)) {
         vm->regs[(11)] = 0;
        } else {
         vm->regs[s->current->reg] = (s->current->data >> 8);
        }
       } else {
        vm->regs[s->current->reg] = (s->current->data >> 8);
       }
      } else if(s->current->data < 26) {
       if(s->current->reg == (11)) {
        if(vm->regs[(11)] == vm->regs[s->current->data]) {
         vm->regs[(11)] = 0;
        } else {
         vm->regs[s->current->reg] = vm->regs[s->current->data];
        }
       } else {
        vm->regs[s->current->reg] = vm->regs[s->current->data];
       }
      } else {
       return(BAD_ARGUMENT);
      }
     } else {
      return(BAD_REGISTER);
     }
     if(vm->regs[(14)] > 6)
      vm->regs[(14)] = 6;
     if(vm->regs[(3)] < 1)
      vm->regs[(3)] = 1;
     if(vm->regs[(1)] < 1)
      vm->regs[(1)] = 1;
     if(vm->regs[(11)] > 2)
      vm->regs[(11)] = 0;
     break;
    case ADD:
     if(s->current->reg < 26) {
      if((s->current->data & 0xFF) == 0xFF) {
       vm->regs[s->current->reg] += (s->current->data >> 8);
      } else if(s->current->data < 26) {
       vm->regs[s->current->reg] += vm->regs[s->current->data];
      } else {
       return(BAD_ARGUMENT);
      }
     } else {
      return(BAD_REGISTER);
     }
     if(vm->regs[(14)] > 6)
      vm->regs[(14)] = 6;
     if(vm->regs[(11)] > 2)
      vm->regs[(11)] = 0;
     break;
    case SUB:
     if(s->current->reg < 26) {
      if((s->current->data & 0xFF) == 0xFF) {
       vm->regs[s->current->reg] -= (s->current->data >> 8);
      } else if(s->current->data < 26) {
       vm->regs[s->current->reg] -= vm->regs[s->current->data];
      } else {
       return(BAD_ARGUMENT);
      }
     } else {
      return(BAD_REGISTER);
     }
     if(vm->regs[(3)] < 1)
      vm->regs[(3)] = 1;
     break;
    case CMP:
     if(s->current->reg < 26) {
      if((s->current->data & 0xFF) == 0xFF) {
       t = (s->current->data >> 8);
       if(t > vm->regs[s->current->reg])
        vm->flags |= (2);
       if(t == vm->regs[s->current->reg])
        vm->flags |= (1);
      } else if(s->current->data < 26) {
       if(vm->regs[s->current->data] > vm->regs[s->current->reg])
        vm->flags |= (2);
       if(vm->regs[s->current->data] == vm->regs[s->current->reg])
        vm->flags |= (1);
      } else {
       return(BAD_ARGUMENT);
      }
     } else {
      return(BAD_REGISTER);
     }
     break;
    case JNE:
     if((s->current->data & 0xFF) == 0xFF) {
      if(!(vm->flags & (1))) {
       t = (s->current->data >> 8);
       seeksong(s, t);
      }
     } else if(s->current->data < 26) {
      if(!(vm->flags & (1)))
       seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JE:
     if((s->current->data & 0xFF) == 0xFF) {
      if(vm->flags & (1)) {
       t = (s->current->data >> 8);
       seeksong(s, t);
      }
     } else if(s->current->data < 26) {
      if(vm->flags & (1))
       seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JL:
     if((s->current->data & 0xFF) == 0xFF) {
      if(!(vm->flags & (2))) {
       t = (s->current->data >> 8);
       seeksong(s, t);
      }
     } else if(s->current->data < 26) {
      if(!(vm->flags & (2)))
       seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JG:
     if((s->current->data & 0xFF) == 0xFF) {
      if(vm->flags & (2)) {
       t = (s->current->data >> 8);
       seeksong(s, t);
      }
     } else if(s->current->data < 26) {
      if(vm->flags & (2))
       seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JMP:
     if((s->current->data & 0xFF) == 0xFF) {
      t = (s->current->data >> 8);
      seeksong(s, t);
     } else if(s->current->data < 26) {
      seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case BRA:
     if(s->current->next == ((void *)0))
      return(ILLEGAL_INSTRUCTION);
     vm->stack[vm->sp] = s->current->next;
     vm->sp++;
     if((s->current->data & 0xFF) == 0xFF) {
      t = (s->current->data >> 8);
      seeksong(s, t);
     } else if(s->current->data < 26) {
      seeksong(s, vm->regs[s->current->data]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JNEL:
     if((s->current->data & 0xFF) == 0xFF) {
      if(!(vm->flags & (1))) {
       t = (s->current->data >> 8);
       if(t > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[t]);
      }
     } else if(s->current->data < 26) {
      if(!(vm->flags & (1))) {
       if(vm->regs[s->current->data] > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[vm->regs[s->current->data]]);
      }
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JEL:
     if((s->current->data & 0xFF) == 0xFF) {
      if(vm->flags & (1)) {
       t = (s->current->data >> 8);
       if(t > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[t]);
      }
     } else if(s->current->data < 26) {
      if(vm->flags & (1)) {
       if(vm->regs[s->current->data] > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[vm->regs[s->current->data]]);
      }
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JLL:
     if((s->current->data & 0xFF) == 0xFF) {
      if(!(vm->flags & (2))) {
       t = (s->current->data >> 8);
       if(t > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[t]);
      }
     } else if(s->current->data < 26) {
      if(!(vm->flags & (2))) {
       if(vm->regs[s->current->data] > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[vm->regs[s->current->data]]);
      }
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JGL:
     if((s->current->data & 0xFF) == 0xFF) {
      if(vm->flags & (2)) {
       t = (s->current->data >> 8);
       if(t > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[t]);
      }
     } else if(s->current->data < 26) {
      if(vm->flags & (2)) {
       if(vm->regs[s->current->data] > s->nlabels)
        return(BAD_ARGUMENT);
       seeksong(s, s->labels[vm->regs[s->current->data]]);
      }
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case JMPL:
     if((s->current->data & 0xFF) == 0xFF) {
      t = (s->current->data >> 8);
      if(t > s->nlabels)
       return(BAD_ARGUMENT);
      seeksong(s, s->labels[t]);
     } else if(s->current->data < 26) {
       if(vm->regs[s->current->data] > s->nlabels)
       return(BAD_ARGUMENT);
      seeksong(s, s->labels[vm->regs[s->current->data]]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case BRAL:
     vm->stack[vm->sp] = s->current->next;
     vm->sp++;
     if((s->current->data & 0xFF) == 0xFF) {
      t = (s->current->data >> 8);
      if(t > s->nlabels)
       return(BAD_ARGUMENT);
      seeksong(s, s->labels[t]);
     } else if(s->current->data < 26) {
       if(vm->regs[s->current->data] > s->nlabels)
       return(BAD_ARGUMENT);
      seeksong(s, s->labels[vm->regs[s->current->data]]);
     } else {
      return(BAD_ARGUMENT);
     }
     break;
    case RET:
     if(vm->sp == 0)
      return(ILLEGAL_INSTRUCTION);
     vm->sp--;
     s->current = vm->stack[vm->sp];
     break;
    case CFL:
     vm->flags = 0;
     break;
    case HALT:
     running = 0;
     break;
    case LABEL:
     break;
    default:
     return(ILLEGAL_INSTRUCTION);
     break;
   }
  } else {
   running = 0;
  }
  i++;
  if(s->current == vm->last)
   if(nextcommand(s) == 1)
    running = 0;
  if(running == 1 && step == 1) {
   return(BREAKPOINT);
  }
 }
 if(playnote(fd, 0, 0) < 0)
  return(DEVICE_ERROR);
 return(PROGRAM_ENDED);
}

variable_types: fd int

variable_types: struct vmstate { unsigned int regs[26]; unsigned int flags; struct command *stack[16]; unsigned int sp; struct command *last; } *

variable_types:
status
void (*)(int cur, int max)

variable_types: step int

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

variable_types:
notelen
unsigned long

variable_types:
t
unsigned int

variable_types: running int

return_type: enum vmexception { PROGRAM_ENDED=0, ILLEGAL_INSTRUCTION=1, BAD_ARGUMENT=2, BAD_REGISTER=3, DEVICE_ERROR=4, VM_ERROR=5, BREAKPOINT=6 }


initvm

canonical_original_code:
struct vmstate *initvm() {
 int i;
 struct vmstate *vm;
 vm = malloc(sizeof(vmstate));
 if(vm == ((void *)0))
  return(((void *)0));
 for(i = 0; i < 26; i++) {
  vm->regs[i] = 0;
 }
 vm->flags = 0;
 vm->regs[(14)] = (3);
 vm->regs[(3)] = (32);
 vm->regs[(1)] = (50);
 vm->regs[(11)] = (0);
 for(i = 0; i < 16; i++) {
  vm->stack[i] = 0;
 }
 vm->sp = 0;
 return(vm);
}

variable_types: struct vmstate { unsigned int regs[26]; unsigned int flags; struct command { enum instruction { NOTE=0, MOV=1, ADD=2, SUB=3, CMP=4, JNE=5, JE=6, JL=7, JG=8, JMP=9, BRA=10, RET=11, CFL=12, HALT=13, LABEL=14, JNEL=15, JEL=16, JLL=17, JGL=18, JMPL=19, BRAL=20, NOP=21 } cmd; unsigned int data; unsigned int reg; struct command *next; struct command *prev; } *stack[16]; unsigned int sp; struct command *last; } *

user_defined_types: struct vmstate { unsigned int regs[26]; unsigned int flags; struct command *stack[16]; unsigned int sp; struct command *last; }


original_code:
int read1arg(int *pos, int *data, int length, char *songstr) {
 int t;
 int t2;
 char tmpstr[11] = "00000000";
 if(*pos + 1 < length) {
  ++*pos;
  if(*pos + 1 < length) {
   if(songstr[*pos] >= 'a' && songstr[*pos] <= 'z' ) {
    *data = (songstr[*pos] - 'a');
   } else if(songstr[*pos] >= '0' && songstr[*pos] <= '9') {
    t2 = readnum(&(songstr[*pos]), length - *pos, tmpstr, 8, '^');
    t = atoi(tmpstr);
    *data = (t << 8 | 0xFF);
    *pos += t2;
   } else {
    return(1);
   }
  }
 } else {
  return(1);
 }
 return(0);
}

variable_types:
pos
int *

variable_types:
data
int *

variable_types: length int

variable_types:
songstr
char *

variable_types: t int

variable_types:
tmpstr
char [11]


original_code:
int read2arg(int *pos, int *data, int *reg, int length, char *songstr) {
 int t;
 int t2;
 char tmpstr[11] = "00000000";
 if(*pos + 1 < length) {
  ++*pos;
  if(songstr[*pos] >= 'a' && songstr[*pos] <= 'z') {
   *reg = (songstr[*pos] - 'a');
   ++*pos;
  } else {
   return(1);
  }
  if(*pos + 1 < length) {
   if(songstr[*pos] >= 'a' && songstr[*pos] <= 'z' ) {
    *data = (songstr[*pos] - 'a');
   } else if(songstr[*pos] >= '0' && songstr[*pos] <= '9') {
    t2 = readnum(&(songstr[*pos]), length - *pos, tmpstr, 8, '^');
    t = atoi(tmpstr);
    *data = (t << 8 | 0xFF);
    *pos += t2;
   } else {
    return(1);
   }
  }
 } else {
  return(1);
 }
 return(0);
}

variable_types:
reg
int *


islabel

decompiled_code:
_BOOL8 __fastcall islabel(__int64 a1, int *a2)
{
int v2; // eax

v2 = *a2 + 1;
*a2 = v2;
return *(_BYTE *)(a1 + v2) == 58;
}

original_code:
int islabel(char *songstr, int *pos) {
 ++*pos;
 if(songstr[*pos] == ':')
  return(1);
 return(0);
}


compilesong

decompiled_code:
int *__fastcall compilesong(int *a1, __int64 a2)
{
__int64 v2; // r13
int v3; // ebp
int *v4; // r12
int v5; // eax
int v6; // er15
__int64 v7; // rcx
bool v8; // cf
bool v9; // zf
char v10; // cl
bool v11; // cf
bool v12; // zf
__int64 v13; // rcx
char v14; // cl
bool v15; // cf
bool v16; // zf
__int64 v17; // rcx
char v18; // cl
bool v19; // cf
bool v20; // zf
__int64 v21; // rcx
char v22; // cl
bool v23; // cf
bool v24; // zf
__int64 v25; // rcx
char v26; // cl
bool v27; // cf
bool v28; // zf
__int64 v29; // rcx
char v30; // cl
bool v31; // cf
bool v32; // zf
__int64 v33; // rcx
char v34; // cl
bool v35; // cf
bool v36; // zf
__int64 v37; // rcx
char v38; // cl
bool v39; // cf
bool v40; // zf
__int64 v41; // rcx
char v42; // cl
bool v43; // cf
bool v44; // zf
__int64 v45; // rcx
char v46; // cl
bool v47; // cf
bool v48; // zf
__int64 v49; // rcx
char v50; // cl
bool v51; // cf
bool v52; // zf
__int64 v53; // rcx
char v54; // cl
bool v55; // cf
bool v56; // zf
__int64 v57; // rcx
int v58; // er14
int v59; // eax
void *v61; // rax
void *v62; // rax
int v63; // ebx
int v64; // eax
__int64 v65; // rax
char v66; // dl
int v67; // ecx
bool v68; // cf
bool v69; // zf
__int64 v70; // rcx
char v71; // cl
int *v72; // rax
int v73; // [rsp+Ch] [rbp-4Ch]
int v74; // [rsp+14h] [rbp-44h] BYREF
int v75; // [rsp+18h] [rbp-40h] BYREF
int v76[15]; // [rsp+1Ch] [rbp-3Ch] BYREF

v2 = (__int64)a1;
v3 = a2;
v4 = (int *)initsong();
if ( v4 )
{
a2 = (unsigned int)a2;
chartolower(a1, (unsigned int)a2);
v76[0] = 0;
if ( (int)a2 > 0 )
{
v73 = 0;
v5 = 0;
v6 = a2 - 1;
while ( 1 )
{
v74 = 0;
v75 = 0;
v68 = v6 < (unsigned int)v5;
v69 = v6 == v5;
if ( v6 > v5 )
{
a1 = (int *)&unk_C55;
v70 = 2LL;
a2 = v2 + v5;
do
{
if ( !v70 )
break;
v68 = *(_BYTE *)a2 < *(_BYTE *)a1;
v69 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v70;
}
while ( v69 );
v71 = (!v68 && !v69) - v68;
v8 = 0;
v9 = v71 == 0;
if ( !v71 )
{
v75 = 767;
goto LABEL_174;
}
a1 = (int *)&unk_C58;
v7 = 2LL;
a2 = v2 + v5;
do
{
if ( !v7 )
break;
v8 = *(_BYTE *)a2 < *(_BYTE *)a1;
v9 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v7;
}
while ( v9 );
v10 = (!v8 && !v9) - v8;
v11 = 0;
v12 = v10 == 0;
if ( !v10 )
{
v75 = 3839;
LABEL_174:
v76[0] = v5 + 1;
v58 = 0;
goto LABEL_175;
}
a1 = (int *)&unk_C5B;
v13 = 2LL;
a2 = v2 + v5;
do
{
if ( !v13 )
break;
v11 = *(_BYTE *)a2 < *(_BYTE *)a1;
v12 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v13;
}
while ( v12 );
v14 = (!v11 && !v12) - v11;
v15 = 0;
v16 = v14 == 0;
if ( !v14 )
{
v75 = 1279;
goto LABEL_174;
}
a1 = (int *)&unk_C5E;
v17 = 2LL;
a2 = v2 + v5;
do
{
if ( !v17 )
break;
v15 = *(_BYTE *)a2 < *(_BYTE *)a1;
v16 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v17;
}
while ( v16 );
v18 = (!v15 && !v16) - v15;
v19 = 0;
v20 = v18 == 0;
if ( !v18 )
{
v75 = 767;
goto LABEL_174;
}
a1 = (int *)&unk_C61;
v21 = 2LL;
a2 = v2 + v5;
do
{
if ( !v21 )
break;
v19 = *(_BYTE *)a2 < *(_BYTE *)a1;
v20 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v21;
}
while ( v20 );
v22 = (!v19 && !v20) - v19;
v23 = 0;
v24 = v22 == 0;
if ( !v22 )
{
v75 = 1791;
goto LABEL_174;
}
a1 = (int *)&unk_C64;
v25 = 2LL;
a2 = v2 + v5;
do
{
if ( !v25 )
break;
v23 = *(_BYTE *)a2 < *(_BYTE *)a1;
v24 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v25;
}
while ( v24 );
v26 = (!v23 && !v24) - v23;
v27 = 0;
v28 = v26 == 0;
if ( !v26 )
{
v75 = 1279;
goto LABEL_174;
}
a1 = (int *)&unk_C67;
v29 = 2LL;
a2 = v2 + v5;
do
{
if ( !v29 )
break;
v27 = *(_BYTE *)a2 < *(_BYTE *)a1;
v28 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v29;
}
while ( v28 );
v30 = (!v27 && !v28) - v27;
v31 = 0;
v32 = v30 == 0;
if ( !v30 )
{
v75 = 2047;
goto LABEL_174;
}
a1 = (int *)&unk_C6A;
v33 = 2LL;
a2 = v2 + v5;
do
{
if ( !v33 )
break;
v31 = *(_BYTE *)a2 < *(_BYTE *)a1;
v32 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v33;
}
while ( v32 );
v34 = (!v31 && !v32) - v31;
v35 = 0;
v36 = v34 == 0;
if ( !v34 )
{
v75 = 1535;
goto LABEL_174;
}
a1 = (int *)&unk_C6D;
v37 = 2LL;
a2 = v2 + v5;
do
{
if ( !v37 )
break;
v35 = *(_BYTE *)a2 < *(_BYTE *)a1;
v36 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v37;
}
while ( v36 );
v38 = (!v35 && !v36) - v35;
v39 = 0;
v40 = v38 == 0;
if ( !v38 )
{
v75 = 2559;
goto LABEL_174;
}
a1 = (int *)&unk_C70;
v41 = 2LL;
a2 = v2 + v5;
do
{
if ( !v41 )
break;
v39 = *(_BYTE *)a2 < *(_BYTE *)a1;
v40 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v41;
}
while ( v40 );
v42 = (!v39 && !v40) - v39;
v43 = 0;
v44 = v42 == 0;
if ( !v42 )
{
v75 = 2047;
goto LABEL_174;
}
a1 = (int *)&unk_C73;
v45 = 2LL;
a2 = v2 + v5;
do
{
if ( !v45 )
break;
v43 = *(_BYTE *)a2 < *(_BYTE *)a1;
v44 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v45;
}
while ( v44 );
v46 = (!v43 && !v44) - v43;
v47 = 0;
v48 = v46 == 0;
if ( !v46 )
{
v75 = 3071;
goto LABEL_174;
}
a1 = (int *)&unk_C76;
v49 = 2LL;
a2 = v2 + v5;
do
{
if ( !v49 )
break;
v47 = *(_BYTE *)a2 < *(_BYTE *)a1;
v48 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v49;
}
while ( v48 );
v50 = (!v47 && !v48) - v47;
v51 = 0;
v52 = v50 == 0;
if ( !v50 )
{
v75 = 2559;
goto LABEL_174;
}
a1 = (int *)&unk_C79;
v53 = 2LL;
a2 = v2 + v5;
do
{
if ( !v53 )
break;
v51 = *(_BYTE *)a2 < *(_BYTE *)a1;
v52 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v53;
}
while ( v52 );
v54 = (!v51 && !v52) - v51;
v55 = 0;
v56 = v54 == 0;
if ( !v54 )
{
v75 = 3583;
goto LABEL_174;
}
a1 = (int *)&unk_C7C;
v57 = 2LL;
a2 = v2 + v5;
do
{
if ( !v57 )
break;
v55 = *(_BYTE *)a2 < *(_BYTE *)a1;
v56 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v57;
}
while ( v56 );
if ( (!v55 && !v56) == v55 )
{
v75 = 3071;
goto LABEL_174;
}
}
switch ( *(_BYTE *)(v2 + v5) )
{
case '!':
v74 = 11;
v75 = 767;
v58 = 1;
goto LABEL_175;
case '&':
v65 = v76[0];
v66 = 0;
while ( v3 > (int)v65 )
{
v67 = ++v65;
v66 = 1;
if ( *(_BYTE *)(v2 + v65) == 38 )
{
v76[0] = v67;
goto LABEL_167;
}
}
if ( v66 )
v76[0] = v65;
goto LABEL_167;
case '*':
if ( v5 + 1 >= v3 )
goto LABEL_167;
break;
case '+':
v74 = 14;
v75 = 511;
v58 = 2;
goto LABEL_175;
case '-':
v74 = 14;
v75 = 511;
v58 = 3;
goto LABEL_175;
case '.':
v74 = 11;
v75 = 511;
v58 = 1;
goto LABEL_175;
case '0':
v74 = 14;
v75 = 255;
v58 = 1;
goto LABEL_175;
case '1':
v74 = 14;
v75 = 511;
v58 = 1;
goto LABEL_175;
case '2':
v74 = 14;
v75 = 767;
v58 = 1;
goto LABEL_175;
case '3':
v74 = 14;
v75 = 1023;
v58 = 1;
goto LABEL_175;
case '4':
v74 = 14;
v75 = 1279;
v58 = 1;
goto LABEL_175;
case '5':
v74 = 14;
v75 = 1535;
v58 = 1;
goto LABEL_175;
case '6':
v74 = 14;
v75 = 1791;
v58 = 1;
goto LABEL_175;
case 'a':
v75 = 2815;
v58 = 0;
goto LABEL_175;
case 'b':
v75 = 3327;
v58 = 0;
goto LABEL_175;
case 'c':
v75 = 511;
v58 = 0;
goto LABEL_175;
case 'd':
v75 = 1023;
v58 = 0;
goto LABEL_175;
case 'e':
v75 = 1535;
v58 = 0;
goto LABEL_175;
case 'f':
v75 = 1791;
v58 = 0;
goto LABEL_175;
case 'g':
v75 = 2303;
v58 = 0;
goto LABEL_175;
case 'h':
v74 = 3;
v75 = 767;
v58 = 1;
goto LABEL_175;
case 'i':
v74 = 3;
v75 = 2303;
v58 = 1;
goto LABEL_175;
case 'q':
v74 = 3;
v75 = 1279;
v58 = 1;
goto LABEL_175;
case 's':
v74 = 3;
v75 = 4351;
v58 = 1;
goto LABEL_175;
case 't':
v74 = 3;
v75 = 8447;
v58 = 1;
goto LABEL_175;
case 'w':
v74 = 3;
v75 = 511;
v58 = 1;
goto LABEL_175;
case 'x':
v75 = 255;
v58 = 0;
goto LABEL_175;
case 'z':
v74 = 3;
v75 = 16639;
v58 = 1;
goto LABEL_175;
default:
goto LABEL_167;
}
v76[0] = v5 + 1;
switch ( *(_BYTE *)(v2 + v5 + 1) )
{
case ':':
v59 = v73 << 8;
LOBYTE(v59) = -1;
v75 = v59;
++v73;
v58 = 14;
break;
case '>':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !islabel(v2, v76) ? 10 : 20;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read1arg(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'a':
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read2arg(v76, &v75, &v74, v3, v2) == 1 )
return 0LL;
v58 = 2;
break;
case 'b':
v74 = 1;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read1arg(v76, &v75, v3, v2) == 1 )
return 0LL;
v58 = 1;
break;
case 'c':
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read2arg(v76, &v75, &v74, v3, v2) == 1 )
return 0LL;
v58 = 4;
break;
case 'd':
v74 = 3;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read1arg(v76, &v75, v3, v2) == 1 )
return 0LL;
v58 = 1;
break;
case 'e':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !islabel(v2, v76) ? 6 : 16;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read1arg(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'f':
v58 = 12;
break;
case 'g':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !islabel(v2, v76) ? 8 : 18;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read1arg(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'h':
v58 = 13;
break;
case 'i':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !islabel(v2, v76) ? 5 : 15;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read1arg(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'j':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !islabel(v2, v76) ? 9 : 19;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read1arg(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'l':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !islabel(v2, v76) ? 7 : 17;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read1arg(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'm':
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read2arg(v76, &v75, &v74, v3, v2) == 1 )
return 0LL;
v58 = 1;
break;
case 'n':
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read1arg(v76, &v75, v3, v2) == 1 )
return 0LL;
v58 = 0;
break;
case 'r':
v58 = 11;
break;
case 's':
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)read2arg(v76, &v75, &v74, v3, v2) == 1 )
return 0LL;
v58 = 3;
break;
default:
goto LABEL_167;
}
LABEL_175:
v72 = (int *)initcommand(a1, a2);
if ( !v72 )
goto LABEL_131;
*v72 = v58;
v72[1] = v75;
v72[2] = v74;
a2 = (__int64)v4;
a1 = v72;
addcmd(v72, v4);
LABEL_167:
v5 = v76[0] + 1;
v76[0] = v5;
if ( v5 >= v3 )
goto LABEL_134;
}
}
v73 = 0;
LABEL_134:
if ( *((_QWORD *)v4 + 1) )
{
rewindsong(v4);
v61 = malloc(8LL * (unsigned int)*v4);
*((_QWORD *)v4 + 4) = v61;
if ( v61 )
{
v62 = malloc(4LL * v73);
*((_QWORD *)v4 + 6) = v62;
if ( v62 )
{
v4[10] = v73 - 1;
v76[0] = 0;
if ( *v4 )
{
v63 = 0;
v64 = 0;
do
{
*(_QWORD *)(*((_QWORD *)v4 + 4) + 8LL * v64) = *((_QWORD *)v4 + 3);
if ( **(_DWORD **)(*((_QWORD *)v4 + 4) + 8LL * v76[0]) == 14 )
*(_DWORD *)(*((_QWORD *)v4 + 6) + 4LL * v63++) = v76[0];
nextcommand(v4);
v64 = v76[0] + 1;
v76[0] = v64;
}
while ( *v4 > (unsigned int)v64 );
}
}
else
{
v4 = 0LL;
}
}
else
{
v4 = 0LL;
}
}
else
{
LABEL_131:
freesong(v4);
v4 = 0LL;
}
}
return v4;
}

canonical_decompiled_code:
int *__fastcall func3(int *a1, __int64 a2)
{
__int64 v2; // r13
int v3; // ebp
int *v4; // r12
int v5; // eax
int v6; // er15
__int64 v7; // rcx
bool v8; // cf
bool v9; // zf
char v10; // cl
bool v11; // cf
bool v12; // zf
__int64 v13; // rcx
char v14; // cl
bool v15; // cf
bool v16; // zf
__int64 v17; // rcx
char v18; // cl
bool v19; // cf
bool v20; // zf
__int64 v21; // rcx
char v22; // cl
bool v23; // cf
bool v24; // zf
__int64 v25; // rcx
char v26; // cl
bool v27; // cf
bool v28; // zf
__int64 v29; // rcx
char v30; // cl
bool v31; // cf
bool v32; // zf
__int64 v33; // rcx
char v34; // cl
bool v35; // cf
bool v36; // zf
__int64 v37; // rcx
char v38; // cl
bool v39; // cf
bool v40; // zf
__int64 v41; // rcx
char v42; // cl
bool v43; // cf
bool v44; // zf
__int64 v45; // rcx
char v46; // cl
bool v47; // cf
bool v48; // zf
__int64 v49; // rcx
char v50; // cl
bool v51; // cf
bool v52; // zf
__int64 v53; // rcx
char v54; // cl
bool v55; // cf
bool v56; // zf
__int64 v57; // rcx
int v58; // er14
int v59; // eax
void *v61; // rax
void *v62; // rax
int v63; // ebx
int v64; // eax
__int64 v65; // rax
char v66; // dl
int v67; // ecx
bool v68; // cf
bool v69; // zf
__int64 v70; // rcx
char v71; // cl
int *v72; // rax
int v73; // [rsp+Ch] [rbp-4Ch]
int v74; // [rsp+14h] [rbp-44h] BYREF
int v75; // [rsp+18h] [rbp-40h] BYREF
int v76[15]; // [rsp+1Ch] [rbp-3Ch] BYREF

v2 = (__int64)a1;
v3 = a2;
v4 = (int *)initsong();
if ( v4 )
{
a2 = (unsigned int)a2;
chartolower(a1, (unsigned int)a2);
v76[0] = 0;
if ( (int)a2 > 0 )
{
v73 = 0;
v5 = 0;
v6 = a2 - 1;
while ( 1 )
{
v74 = 0;
v75 = 0;
v68 = v6 < (unsigned int)v5;
v69 = v6 == v5;
if ( v6 > v5 )
{
a1 = (int *)&unk_C55;
v70 = 2LL;
a2 = v2 + v5;
do
{
if ( !v70 )
break;
v68 = *(_BYTE *)a2 < *(_BYTE *)a1;
v69 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v70;
}
while ( v69 );
v71 = (!v68 && !v69) - v68;
v8 = 0;
v9 = v71 == 0;
if ( !v71 )
{
v75 = 767;
goto LABEL_174;
}
a1 = (int *)&unk_C58;
v7 = 2LL;
a2 = v2 + v5;
do
{
if ( !v7 )
break;
v8 = *(_BYTE *)a2 < *(_BYTE *)a1;
v9 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v7;
}
while ( v9 );
v10 = (!v8 && !v9) - v8;
v11 = 0;
v12 = v10 == 0;
if ( !v10 )
{
v75 = 3839;
LABEL_174:
v76[0] = v5 + 1;
v58 = 0;
goto LABEL_175;
}
a1 = (int *)&unk_C5B;
v13 = 2LL;
a2 = v2 + v5;
do
{
if ( !v13 )
break;
v11 = *(_BYTE *)a2 < *(_BYTE *)a1;
v12 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v13;
}
while ( v12 );
v14 = (!v11 && !v12) - v11;
v15 = 0;
v16 = v14 == 0;
if ( !v14 )
{
v75 = 1279;
goto LABEL_174;
}
a1 = (int *)&unk_C5E;
v17 = 2LL;
a2 = v2 + v5;
do
{
if ( !v17 )
break;
v15 = *(_BYTE *)a2 < *(_BYTE *)a1;
v16 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v17;
}
while ( v16 );
v18 = (!v15 && !v16) - v15;
v19 = 0;
v20 = v18 == 0;
if ( !v18 )
{
v75 = 767;
goto LABEL_174;
}
a1 = (int *)&unk_C61;
v21 = 2LL;
a2 = v2 + v5;
do
{
if ( !v21 )
break;
v19 = *(_BYTE *)a2 < *(_BYTE *)a1;
v20 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v21;
}
while ( v20 );
v22 = (!v19 && !v20) - v19;
v23 = 0;
v24 = v22 == 0;
if ( !v22 )
{
v75 = 1791;
goto LABEL_174;
}
a1 = (int *)&unk_C64;
v25 = 2LL;
a2 = v2 + v5;
do
{
if ( !v25 )
break;
v23 = *(_BYTE *)a2 < *(_BYTE *)a1;
v24 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v25;
}
while ( v24 );
v26 = (!v23 && !v24) - v23;
v27 = 0;
v28 = v26 == 0;
if ( !v26 )
{
v75 = 1279;
goto LABEL_174;
}
a1 = (int *)&unk_C67;
v29 = 2LL;
a2 = v2 + v5;
do
{
if ( !v29 )
break;
v27 = *(_BYTE *)a2 < *(_BYTE *)a1;
v28 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v29;
}
while ( v28 );
v30 = (!v27 && !v28) - v27;
v31 = 0;
v32 = v30 == 0;
if ( !v30 )
{
v75 = 2047;
goto LABEL_174;
}
a1 = (int *)&unk_C6A;
v33 = 2LL;
a2 = v2 + v5;
do
{
if ( !v33 )
break;
v31 = *(_BYTE *)a2 < *(_BYTE *)a1;
v32 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v33;
}
while ( v32 );
v34 = (!v31 && !v32) - v31;
v35 = 0;
v36 = v34 == 0;
if ( !v34 )
{
v75 = 1535;
goto LABEL_174;
}
a1 = (int *)&unk_C6D;
v37 = 2LL;
a2 = v2 + v5;
do
{
if ( !v37 )
break;
v35 = *(_BYTE *)a2 < *(_BYTE *)a1;
v36 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v37;
}
while ( v36 );
v38 = (!v35 && !v36) - v35;
v39 = 0;
v40 = v38 == 0;
if ( !v38 )
{
v75 = 2559;
goto LABEL_174;
}
a1 = (int *)&unk_C70;
v41 = 2LL;
a2 = v2 + v5;
do
{
if ( !v41 )
break;
v39 = *(_BYTE *)a2 < *(_BYTE *)a1;
v40 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v41;
}
while ( v40 );
v42 = (!v39 && !v40) - v39;
v43 = 0;
v44 = v42 == 0;
if ( !v42 )
{
v75 = 2047;
goto LABEL_174;
}
a1 = (int *)&unk_C73;
v45 = 2LL;
a2 = v2 + v5;
do
{
if ( !v45 )
break;
v43 = *(_BYTE *)a2 < *(_BYTE *)a1;
v44 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v45;
}
while ( v44 );
v46 = (!v43 && !v44) - v43;
v47 = 0;
v48 = v46 == 0;
if ( !v46 )
{
v75 = 3071;
goto LABEL_174;
}
a1 = (int *)&unk_C76;
v49 = 2LL;
a2 = v2 + v5;
do
{
if ( !v49 )
break;
v47 = *(_BYTE *)a2 < *(_BYTE *)a1;
v48 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v49;
}
while ( v48 );
v50 = (!v47 && !v48) - v47;
v51 = 0;
v52 = v50 == 0;
if ( !v50 )
{
v75 = 2559;
goto LABEL_174;
}
a1 = (int *)&unk_C79;
v53 = 2LL;
a2 = v2 + v5;
do
{
if ( !v53 )
break;
v51 = *(_BYTE *)a2 < *(_BYTE *)a1;
v52 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v53;
}
while ( v52 );
v54 = (!v51 && !v52) - v51;
v55 = 0;
v56 = v54 == 0;
if ( !v54 )
{
v75 = 3583;
goto LABEL_174;
}
a1 = (int *)&unk_C7C;
v57 = 2LL;
a2 = v2 + v5;
do
{
if ( !v57 )
break;
v55 = *(_BYTE *)a2 < *(_BYTE *)a1;
v56 = *(_BYTE *)a2++ == *(_BYTE *)a1;
a1 = (int *)((char *)a1 + 1);
--v57;
}
while ( v56 );
if ( (!v55 && !v56) == v55 )
{
v75 = 3071;
goto LABEL_174;
}
}
switch ( *(_BYTE *)(v2 + v5) )
{
case '!':
v74 = 11;
v75 = 767;
v58 = 1;
goto LABEL_175;
case '&':
v65 = v76[0];
v66 = 0;
while ( v3 > (int)v65 )
{
v67 = ++v65;
v66 = 1;
if ( *(_BYTE *)(v2 + v65) == 38 )
{
v76[0] = v67;
goto LABEL_167;
}
}
if ( v66 )
v76[0] = v65;
goto LABEL_167;
case '*':
if ( v5 + 1 >= v3 )
goto LABEL_167;
break;
case '+':
v74 = 14;
v75 = 511;
v58 = 2;
goto LABEL_175;
case '-':
v74 = 14;
v75 = 511;
v58 = 3;
goto LABEL_175;
case '.':
v74 = 11;
v75 = 511;
v58 = 1;
goto LABEL_175;
case '0':
v74 = 14;
v75 = 255;
v58 = 1;
goto LABEL_175;
case '1':
v74 = 14;
v75 = 511;
v58 = 1;
goto LABEL_175;
case '2':
v74 = 14;
v75 = 767;
v58 = 1;
goto LABEL_175;
case '3':
v74 = 14;
v75 = 1023;
v58 = 1;
goto LABEL_175;
case '4':
v74 = 14;
v75 = 1279;
v58 = 1;
goto LABEL_175;
case '5':
v74 = 14;
v75 = 1535;
v58 = 1;
goto LABEL_175;
case '6':
v74 = 14;
v75 = 1791;
v58 = 1;
goto LABEL_175;
case 'a':
v75 = 2815;
v58 = 0;
goto LABEL_175;
case 'b':
v75 = 3327;
v58 = 0;
goto LABEL_175;
case 'c':
v75 = 511;
v58 = 0;
goto LABEL_175;
case 'd':
v75 = 1023;
v58 = 0;
goto LABEL_175;
case 'e':
v75 = 1535;
v58 = 0;
goto LABEL_175;
case 'f':
v75 = 1791;
v58 = 0;
goto LABEL_175;
case 'g':
v75 = 2303;
v58 = 0;
goto LABEL_175;
case 'h':
v74 = 3;
v75 = 767;
v58 = 1;
goto LABEL_175;
case 'i':
v74 = 3;
v75 = 2303;
v58 = 1;
goto LABEL_175;
case 'q':
v74 = 3;
v75 = 1279;
v58 = 1;
goto LABEL_175;
case 's':
v74 = 3;
v75 = 4351;
v58 = 1;
goto LABEL_175;
case 't':
v74 = 3;
v75 = 8447;
v58 = 1;
goto LABEL_175;
case 'w':
v74 = 3;
v75 = 511;
v58 = 1;
goto LABEL_175;
case 'x':
v75 = 255;
v58 = 0;
goto LABEL_175;
case 'z':
v74 = 3;
v75 = 16639;
v58 = 1;
goto LABEL_175;
default:
goto LABEL_167;
}
v76[0] = v5 + 1;
switch ( *(_BYTE *)(v2 + v5 + 1) )
{
case ':':
v59 = v73 << 8;
LOBYTE(v59) = -1;
v75 = v59;
++v73;
v58 = 14;
break;
case '>':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !func2(v2, v76) ? 10 : 20;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func0(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'a':
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func1(v76, &v75, &v74, v3, v2) == 1 )
return 0LL;
v58 = 2;
break;
case 'b':
v74 = 1;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func0(v76, &v75, v3, v2) == 1 )
return 0LL;
v58 = 1;
break;
case 'c':
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func1(v76, &v75, &v74, v3, v2) == 1 )
return 0LL;
v58 = 4;
break;
case 'd':
v74 = 3;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func0(v76, &v75, v3, v2) == 1 )
return 0LL;
v58 = 1;
break;
case 'e':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !func2(v2, v76) ? 6 : 16;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func0(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'f':
v58 = 12;
break;
case 'g':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !func2(v2, v76) ? 8 : 18;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func0(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'h':
v58 = 13;
break;
case 'i':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !func2(v2, v76) ? 5 : 15;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func0(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'j':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !func2(v2, v76) ? 9 : 19;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func0(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'l':
if ( v5 + 2 >= v3 )
return 0LL;
v58 = !func2(v2, v76) ? 7 : 17;
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func0(v76, &v75, v3, v2) != 1 )
break;
return 0LL;
case 'm':
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func1(v76, &v75, &v74, v3, v2) == 1 )
return 0LL;
v58 = 1;
break;
case 'n':
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func0(v76, &v75, v3, v2) == 1 )
return 0LL;
v58 = 0;
break;
case 'r':
v58 = 11;
break;
case 's':
a2 = (__int64)&v75;
a1 = v76;
if ( (unsigned int)func1(v76, &v75, &v74, v3, v2) == 1 )
return 0LL;
v58 = 3;
break;
default:
goto LABEL_167;
}
LABEL_175:
v72 = (int *)initcommand(a1, a2);
if ( !v72 )
goto LABEL_131;
*v72 = v58;
v72[1] = v75;
v72[2] = v74;
a2 = (__int64)v4;
a1 = v72;
addcmd(v72, v4);
LABEL_167:
v5 = v76[0] + 1;
v76[0] = v5;
if ( v5 >= v3 )
goto LABEL_134;
}
}
v73 = 0;
LABEL_134:
if ( *((_QWORD *)v4 + 1) )
{
rewindsong(v4);
v61 = malloc(8LL * (unsigned int)*v4);
*((_QWORD *)v4 + 4) = v61;
if ( v61 )
{
v62 = malloc(4LL * v73);
*((_QWORD *)v4 + 6) = v62;
if ( v62 )
{
v4[10] = v73 - 1;
v76[0] = 0;
if ( *v4 )
{
v63 = 0;
v64 = 0;
do
{
*(_QWORD *)(*((_QWORD *)v4 + 4) + 8LL * v64) = *((_QWORD *)v4 + 3);
if ( **(_DWORD **)(*((_QWORD *)v4 + 4) + 8LL * v76[0]) == 14 )
*(_DWORD *)(*((_QWORD *)v4 + 6) + 4LL * v63++) = v76[0];
nextcommand(v4);
v64 = v76[0] + 1;
v76[0] = v64;
}
while ( *v4 > (unsigned int)v64 );
}
}
else
{
v4 = 0LL;
}
}
else
{
v4 = 0LL;
}
}
else
{
LABEL_131:
freesong(v4);
v4 = 0LL;
}
}
return v4;
}

original_code:
song *compilesong(char *songstr, int length) {
 char cur;
 int pos;
 int labels;
 song *s;
 command *c;
 int addnew;
 int cmd;
 int data;
 int reg;
 s = initsong();
 if(s == ((void *)0))
  return(((void *)0));
 labels = 0;
 chartolower(songstr, length);
 for(pos = 0; pos < length; pos++) {
  addnew = 0;
  cmd = 0;
  reg = 0;
  data = 0;
  cur = songstr[pos];
  if(pos < length - 1) {
   if(strncmp(&(songstr[pos]), "c#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((2) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "c$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((14) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "d#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((4) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "d$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((2) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "e#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((6) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "e$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((4) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "f#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((7) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "f$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((5) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "g#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((9) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "g$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((7) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "a#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((11) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "a$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((9) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "b#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((13) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "b$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((11) << 8 | 0xFF);
   }
  }
  if(addnew == 1) {
   pos++;
  } else {
   switch(songstr[pos]) {
   case 'c':
    addnew = 1;
    cmd = NOTE;
    data = ((1) << 8 | 0xFF);
    break;
   case 'd':
    addnew = 1;
    cmd = NOTE;
    data = ((3) << 8 | 0xFF);
    break;
   case 'e':
    addnew = 1;
    cmd = NOTE;
    data = ((5) << 8 | 0xFF);
    break;
   case 'f':
    addnew = 1;
    cmd = NOTE;
    data = ((6) << 8 | 0xFF);
    break;
   case 'g':
    addnew = 1;
    cmd = NOTE;
    data = ((8) << 8 | 0xFF);
    break;
   case 'a':
    addnew = 1;
    cmd = NOTE;
    data = ((10) << 8 | 0xFF);
    break;
   case 'b':
    addnew = 1;
    cmd = NOTE;
    data = ((12) << 8 | 0xFF);
    break;
   case 'x':
    addnew = 1;
    cmd = NOTE;
    data = ((0) << 8 | 0xFF);
    break;
   case '0':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (0 << 8 | 0xFF);
    break;
   case '1':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (1 << 8 | 0xFF);
    break;
   case '2':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (2 << 8 | 0xFF);
    break;
   case '3':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (3 << 8 | 0xFF);
    break;
   case '4':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (4 << 8 | 0xFF);
    break;
   case '5':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (5 << 8 | 0xFF);
    break;
   case '6':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (6 << 8 | 0xFF);
    break;
   case '-':
    addnew = 1;
    cmd = SUB;
    reg = (14);
    data = (1 << 8 | 0xFF);
    break;
   case '+':
    addnew = 1;
    cmd = ADD;
    reg = (14);
    data = (1 << 8 | 0xFF);
    break;
   case 'z':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (64 << 8 | 0xFF);
    break;
   case 't':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (32 << 8 | 0xFF);
    break;
   case 's':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (16 << 8 | 0xFF);
    break;
   case 'i':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (8 << 8 | 0xFF);
    break;
   case 'q':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (4 << 8 | 0xFF);
    break;
   case 'h':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (2 << 8 | 0xFF);
    break;
   case 'w':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (1 << 8 | 0xFF);
    break;
   case '.':
    addnew = 1;
    cmd = MOV;
    reg = (11);
    data = ((1) << 8 | 0xFF);
    break;
   case '!':
    addnew = 1;
    cmd = MOV;
    reg = (11);
    data = ((2) << 8 | 0xFF);
    break;
   case '&':
    while(pos < length) {
     pos++;
     if(songstr[pos] == '&') {
      break;
     }
    }
    break;
   case '*':
    if(pos + 1 < length) {
     pos++;
     switch(songstr[pos]) {
      case 'b':
       addnew = 1;
       cmd = MOV;
       reg = (1);
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'd':
       addnew = 1;
       cmd = MOV;
       reg = (3);
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'n':
       addnew = 1;
       cmd = NOTE;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'm':
       addnew = 1;
       cmd = MOV;
       if(read2arg(&pos, &data, &reg, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'a':
       addnew = 1;
       cmd = ADD;
       if(read2arg(&pos, &data, &reg, length, songstr) == 1)
        return(((void *)0));
       break;
      case 's':
       addnew = 1;
       cmd = SUB;
       if(read2arg(&pos, &data, &reg, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'c':
       addnew = 1;
       cmd = CMP;
       if(read2arg(&pos, &data, &reg, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'i':
       addnew = 1;
       cmd = JNE;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = JNEL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'e':
       addnew = 1;
       cmd = JE;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = JEL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'g':
       addnew = 1;
       cmd = JG;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = JGL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'l':
       addnew = 1;
       cmd = JL;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = JLL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'j':
       addnew = 1;
       cmd = JMP;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = JMPL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case '>':
       addnew = 1;
       cmd = BRA;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = BRAL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'r':
       addnew = 1;
       cmd = RET;
       break;
      case 'f':
       addnew = 1;
       cmd = CFL;
       break;
      case 'h':
       addnew = 1;
       cmd = HALT;
       break;
      case ':':
       addnew = 1;
       cmd = LABEL;
       data = (labels << 8 | 0xFF);
       labels++;
       break;
      default:
       break;
     }
    }
    break;
   default:
    break;
   }
  }
  if(addnew == 1) {
   c = initcommand();
   if(c == ((void *)0)) {
    freesong(s);
    return(((void *)0));
   }
   c->cmd = cmd;
   c->data = data;
   c->reg = reg;
   addcmd(c, s);
  }
 }
 if(s->first == ((void *)0)) {
  freesong(s);
  return(((void *)0));
 }
 rewindsong(s);
 s->offsets = malloc(sizeof(command *) * s->count);
 if(s->offsets == ((void *)0))
  return(((void *)0));
 s->labels = malloc(sizeof(int) * labels);
 if(s->labels == ((void *)0))
  return(((void *)0));
 s->nlabels = labels - 1;
 labels = 0;
 for(pos = 0; pos < s->count; pos++) {
  s->offsets[pos] = s->current;
  if(s->offsets[pos]->cmd == LABEL) {
   s->labels[labels] = pos;
   labels++;
  }
  nextcommand(s);
 }
 return(s);
}

canonical_original_code:
struct song *compilesong(char *songstr, int length) {
 char cur;
 int pos;
 int labels;
 struct song *s;
 struct command *c;
 int addnew;
 int cmd;
 int data;
 int reg;
 s = initsong();
 if(s == ((void *)0))
  return(((void *)0));
 labels = 0;
 chartolower(songstr, length);
 for(pos = 0; pos < length; pos++) {
  addnew = 0;
  cmd = 0;
  reg = 0;
  data = 0;
  cur = songstr[pos];
  if(pos < length - 1) {
   if(strncmp(&(songstr[pos]), "c#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((2) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "c$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((14) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "d#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((4) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "d$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((2) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "e#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((6) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "e$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((4) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "f#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((7) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "f$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((5) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "g#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((9) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "g$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((7) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "a#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((11) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "a$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((9) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "b#", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((13) << 8 | 0xFF);
   } else if(strncmp(&(songstr[pos]), "b$", 2) == 0) {
    addnew = 1;
    cmd = NOTE;
    data = ((11) << 8 | 0xFF);
   }
  }
  if(addnew == 1) {
   pos++;
  } else {
   switch(songstr[pos]) {
   case 'c':
    addnew = 1;
    cmd = NOTE;
    data = ((1) << 8 | 0xFF);
    break;
   case 'd':
    addnew = 1;
    cmd = NOTE;
    data = ((3) << 8 | 0xFF);
    break;
   case 'e':
    addnew = 1;
    cmd = NOTE;
    data = ((5) << 8 | 0xFF);
    break;
   case 'f':
    addnew = 1;
    cmd = NOTE;
    data = ((6) << 8 | 0xFF);
    break;
   case 'g':
    addnew = 1;
    cmd = NOTE;
    data = ((8) << 8 | 0xFF);
    break;
   case 'a':
    addnew = 1;
    cmd = NOTE;
    data = ((10) << 8 | 0xFF);
    break;
   case 'b':
    addnew = 1;
    cmd = NOTE;
    data = ((12) << 8 | 0xFF);
    break;
   case 'x':
    addnew = 1;
    cmd = NOTE;
    data = ((0) << 8 | 0xFF);
    break;
   case '0':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (0 << 8 | 0xFF);
    break;
   case '1':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (1 << 8 | 0xFF);
    break;
   case '2':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (2 << 8 | 0xFF);
    break;
   case '3':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (3 << 8 | 0xFF);
    break;
   case '4':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (4 << 8 | 0xFF);
    break;
   case '5':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (5 << 8 | 0xFF);
    break;
   case '6':
    addnew = 1;
    cmd = MOV;
    reg = (14);
    data = (6 << 8 | 0xFF);
    break;
   case '-':
    addnew = 1;
    cmd = SUB;
    reg = (14);
    data = (1 << 8 | 0xFF);
    break;
   case '+':
    addnew = 1;
    cmd = ADD;
    reg = (14);
    data = (1 << 8 | 0xFF);
    break;
   case 'z':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (64 << 8 | 0xFF);
    break;
   case 't':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (32 << 8 | 0xFF);
    break;
   case 's':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (16 << 8 | 0xFF);
    break;
   case 'i':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (8 << 8 | 0xFF);
    break;
   case 'q':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (4 << 8 | 0xFF);
    break;
   case 'h':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (2 << 8 | 0xFF);
    break;
   case 'w':
    addnew = 1;
    cmd = MOV;
    reg = (3);
    data = (1 << 8 | 0xFF);
    break;
   case '.':
    addnew = 1;
    cmd = MOV;
    reg = (11);
    data = ((1) << 8 | 0xFF);
    break;
   case '!':
    addnew = 1;
    cmd = MOV;
    reg = (11);
    data = ((2) << 8 | 0xFF);
    break;
   case '&':
    while(pos < length) {
     pos++;
     if(songstr[pos] == '&') {
      break;
     }
    }
    break;
   case '*':
    if(pos + 1 < length) {
     pos++;
     switch(songstr[pos]) {
      case 'b':
       addnew = 1;
       cmd = MOV;
       reg = (1);
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'd':
       addnew = 1;
       cmd = MOV;
       reg = (3);
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'n':
       addnew = 1;
       cmd = NOTE;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'm':
       addnew = 1;
       cmd = MOV;
       if(read2arg(&pos, &data, &reg, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'a':
       addnew = 1;
       cmd = ADD;
       if(read2arg(&pos, &data, &reg, length, songstr) == 1)
        return(((void *)0));
       break;
      case 's':
       addnew = 1;
       cmd = SUB;
       if(read2arg(&pos, &data, &reg, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'c':
       addnew = 1;
       cmd = CMP;
       if(read2arg(&pos, &data, &reg, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'i':
       addnew = 1;
       cmd = JNE;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = JNEL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'e':
       addnew = 1;
       cmd = JE;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = JEL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'g':
       addnew = 1;
       cmd = JG;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = JGL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'l':
       addnew = 1;
       cmd = JL;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = JLL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'j':
       addnew = 1;
       cmd = JMP;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = JMPL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case '>':
       addnew = 1;
       cmd = BRA;
       if(pos + 1 >= length)
        return(((void *)0));
       if(islabel(songstr, &pos))
        cmd = BRAL;
       if(read1arg(&pos, &data, length, songstr) == 1)
        return(((void *)0));
       break;
      case 'r':
       addnew = 1;
       cmd = RET;
       break;
      case 'f':
       addnew = 1;
       cmd = CFL;
       break;
      case 'h':
       addnew = 1;
       cmd = HALT;
       break;
      case ':':
       addnew = 1;
       cmd = LABEL;
       data = (labels << 8 | 0xFF);
       labels++;
       break;
      default:
       break;
     }
    }
    break;
   default:
    break;
   }
  }
  if(addnew == 1) {
   c = initcommand();
   if(c == ((void *)0)) {
    freesong(s);
    return(((void *)0));
   }
   c->cmd = cmd;
   c->data = data;
   c->reg = reg;
   addcmd(c, s);
  }
 }
 if(s->first == ((void *)0)) {
  freesong(s);
  return(((void *)0));
 }
 rewindsong(s);
 s->offsets = malloc(sizeof(struct command *) * s->count);
 if(s->offsets == ((void *)0))
  return(((void *)0));
 s->labels = malloc(sizeof(int) * labels);
 if(s->labels == ((void *)0))
  return(((void *)0));
 s->nlabels = labels - 1;
 labels = 0;
 for(pos = 0; pos < s->count; pos++) {
  s->offsets[pos] = s->current;
  if(s->offsets[pos]->cmd == LABEL) {
   s->labels[labels] = pos;
   labels++;
  }
  nextcommand(s);
 }
 return(s);
}

variable_types: cur char

variable_types: pos int

variable_types: labels int

variable_types: struct song { unsigned int count; struct command { enum instruction { NOTE=0, MOV=1, ADD=2, SUB=3, CMP=4, JNE=5, JE=6, JL=7, JG=8, JMP=9, BRA=10, RET=11, CFL=12, HALT=13, LABEL=14, JNEL=15, JEL=16, JLL=17, JGL=18, JMPL=19, BRAL=20, NOP=21 } cmd; unsigned int data; unsigned int reg; struct command *next; struct command *prev; } *first; struct command *last; struct command *current; struct command **offsets; int nlabels; int *labels; } *

variable_types: addnew int

variable_types: cmd int

variable_types: data int

variable_types: reg int