original_code:
void update_raycreator(Raycreator* rc){
  Coord eye = rc->eye;
  float eye_screen_d = 0.1;
  rc->pixel_width = 2*eye_screen_d*tan(rc->fov)/((float)rc->resolution);
  Coord forward = rc->forward;
  Coord right;
  Coord up;
  if(forward.x == 0 && forward.y == 0){
    right.x = 1; right.y = 0; right.z = 0;
    up.x = 0; up.y = 1; up.z = 0;
  }
  else{
    right.x = forward.y;
    right.y = -forward.x;
    right.z = 0;
    up.x = right.y*forward.z - right.z*forward.y;
    up.y = right.z*forward.x - right.x*forward.z;
    up.z = right.x*forward.y - right.y*forward.x;
  }
  normalize_Coord(&right);
  normalize_Coord(&up);
  normalize_Coord(&forward);
  rc->eye = eye;
  rc->forward = forward;
  rc->right = right;
  rc->up = up;
  rc->screen_center = add_scaled_Coord(eye, forward, eye_screen_d);
}

canonical_original_code:
void update_raycreator(struct rcstruct *rc){
  struct Coord eye = rc->eye;
  float eye_screen_d = 0.1;
  rc->pixel_width = 2*eye_screen_d*tan(rc->fov)/((float)rc->resolution);
  struct Coord forward = rc->forward;
  struct Coord right;
  struct Coord up;
  if(forward.x == 0 && forward.y == 0){
    right.x = 1; right.y = 0; right.z = 0;
    up.x = 0; up.y = 1; up.z = 0;
  }
  else{
    right.x = forward.y;
    right.y = -forward.x;
    right.z = 0;
    up.x = right.y*forward.z - right.z*forward.y;
    up.y = right.z*forward.x - right.x*forward.z;
    up.z = right.x*forward.y - right.y*forward.x;
  }
  normalize_Coord(&right);
  normalize_Coord(&up);
  normalize_Coord(&forward);
  rc->eye = eye;
  rc->forward = forward;
  rc->right = right;
  rc->up = up;
  rc->screen_center = add_scaled_Coord(eye, forward, eye_screen_d);
}

variable_types: struct Coord { float x; float y; float z; }

user_defined_types: struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; }


repo: acelster/scatter-pt-viz

original_code:
void create_rays(Raycreator* rc, Ray* rays){
 Coord screen_center = rc->screen_center;
 Coord up = rc->up;
 Coord right = rc->right;
 Coord eye = rc->eye;
 float pixel_width = rc->pixel_width;
  Color color = {-1,-1,-1,-1};
  int half_res = rc->resolution/2;

#pragma omp parallel for
  for(int c = -half_res; c < half_res; c++){
    for(int d = -half_res; d < half_res; d++){
      int i = (c+half_res)*rc->resolution + (d + half_res);
      Coord end;
      end.x = screen_center.x + c*pixel_width*up.x + d*pixel_width*right.x;
      end.y = screen_center.y + c*pixel_width*up.y + d*pixel_width*right.y;
      end.z = screen_center.z + c*pixel_width*up.z + d*pixel_width*right.z;
      rays[i].start = end;
      rays[i].dir = sub_Coord(end, eye);
      rays[i].color = color;
      find_intersections(&rays[i], rc->ranges);
    }
  }
}

canonical_original_code:
void create_rays(struct rcstruct *rc, struct Ray *rays){
 struct Coord screen_center = rc->screen_center;
 struct Coord up = rc->up;
 struct Coord right = rc->right;
 struct Coord eye = rc->eye;
 float pixel_width = rc->pixel_width;
  struct Color color = {-1,-1,-1,-1};
  int half_res = rc->resolution/2;

#pragma omp parallel for
  for(int c = -half_res; c < half_res; c++){
    for(int d = -half_res; d < half_res; d++){
      int i = (c+half_res)*rc->resolution + (d + half_res);
      struct Coord end;
      end.x = screen_center.x + c*pixel_width*up.x + d*pixel_width*right.x;
      end.y = screen_center.y + c*pixel_width*up.y + d*pixel_width*right.y;
      end.z = screen_center.z + c*pixel_width*up.z + d*pixel_width*right.z;
      rays[i].start = end;
      rays[i].dir = sub_Coord(end, eye);
      rays[i].color = color;
      find_intersections(&rays[i], rc->ranges);
    }
  }
}

variable_types: struct rcstruct { int resolution; struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; } *ranges; float fov; struct Coord { float x; float y; float z; } eye; struct Coord forward; struct Coord right; struct Coord up; struct Coord screen_center; float pixel_width; } *

variable_types: struct Ray { struct Coord start; struct Coord dir; float distance; struct Color { float a; float b; float g; float r; } color; } *

variable_types: c int

variable_types: d int

variable_types: i int

return_type: void

user_defined_types: struct rcstruct { int resolution; struct Ranges *ranges; float fov; struct Coord eye; struct Coord forward; struct Coord right; struct Coord up; struct Coord screen_center; float pixel_width; }

user_defined_types: struct Ray { struct Coord start; struct Coord dir; float distance; struct Color color; }


original_code:
void find_intersections(Ray* ray, Ranges* ranges){
  Coord top = {ranges->xmax, ranges->ymax, ranges->zmax};
  Coord bottom = {ranges->xmin, ranges->ymin, ranges->zmin};
  Coord t1 = div_Coord(sub_Coord(top, ray->start), ray->dir, 1);
  Coord t2 = div_Coord(sub_Coord(bottom, ray->start), ray->dir, -1);
  Coord tmin = min_Coord(t1, t2);
  Coord tmax = max_Coord(t1, t2);
  float tnear = fmax(fmax(tmin.x, tmin.y), fmax(tmin.x, tmin.z));
  float tfar = fmin(fmin(tmax.x, tmax.y), fmin(tmax.x, tmax.z));
  if(tfar <= tnear){
    ray->distance = 0;
    return;
  }
  if(tfar <=0){
    ray->distance = -1;
    return;
  }
  Coord far = add_scaled_Coord(ray->start, ray->dir, tfar);
  tnear = fmax(0, tnear);
  ray->start = add_scaled_Coord(ray->start, ray->dir, tnear);
  ray->distance = distance_Coord(ray->start, far);
}

canonical_original_code:
void find_intersections(struct Ray *ray, struct Ranges *ranges){
  struct Coord top = {ranges->xmax, ranges->ymax, ranges->zmax};
  struct Coord bottom = {ranges->xmin, ranges->ymin, ranges->zmin};
  struct Coord t1 = div_Coord(sub_Coord(top, ray->start), ray->dir, 1);
  struct Coord t2 = div_Coord(sub_Coord(bottom, ray->start), ray->dir, -1);
  struct Coord tmin = min_Coord(t1, t2);
  struct Coord tmax = max_Coord(t1, t2);
  float tnear = fmax(fmax(tmin.x, tmin.y), fmax(tmin.x, tmin.z));
  float tfar = fmin(fmin(tmax.x, tmax.y), fmin(tmax.x, tmax.z));
  if(tfar <= tnear){
    ray->distance = 0;
    return;
  }
  if(tfar <=0){
    ray->distance = -1;
    return;
  }
  struct Coord far = add_scaled_Coord(ray->start, ray->dir, tfar);
  tnear = fmax(0, tnear);
  ray->start = add_scaled_Coord(ray->start, ray->dir, tnear);
  ray->distance = distance_Coord(ray->start, far);
}

variable_types: struct Ray { struct Coord { float x; float y; float z; } start; struct Coord dir; float distance; struct Color { float a; float b; float g; float r; } color; } *

variable_types: struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; } *

variable_types: tnear float

variable_types: tfar float


original_code:
void normalize_ray(Ray* r){
  float length = sqrt(r->dir.x*r->dir.x + r->dir.y*r->dir.y + r->dir.z*r->dir.z);
  r->dir.x = r->dir.x/length;
  r->dir.y = r->dir.y/length;
  r->dir.z = r->dir.z/length;
}

canonical_original_code:
void normalize_ray(struct Ray *r){
  float length = sqrt(r->dir.x*r->dir.x + r->dir.y*r->dir.y + r->dir.z*r->dir.z);
  r->dir.x = r->dir.x/length;
  r->dir.y = r->dir.y/length;
  r->dir.z = r->dir.z/length;
}

variable_types: length float

user_defined_types: struct Coord { float x; float y; float z; }

user_defined_types: struct Color { float a; float b; float g; float r; }


decompiled_code:
__int64 __fastcall trace_rays(int a1, int a2, int a3)
{
__int64 v5; // rbp
double v6; // xmm0_8
int v7; // ecx
__int64 v8; // rsi
__int64 result; // rax
int v10; // ebp
__int64 v11; // r14
int v12; // eax

v5 = images;
v6 = log2((double)a1);
v7 = RESOLUTION;
v8 = *(_QWORD *)(v5 + 8LL * (int)v6 - 32);
result = (unsigned int)(RESOLUTION / a1);
if ( a2 < a3 )
{
v10 = RESOLUTION / a1;
v11 = v8 + 4LL * a2;
while ( 1 )
{
v12 = a2++;
v11 += 4LL;
result = trace_ray(rays + 44LL * (v7 * v10 * (v12 / a1) + v10 * (v12 % a1)), root, 0);
*(_DWORD *)(v11 - 4) = result;
if ( a3 == a2 )
break;
v7 = RESOLUTION;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, int a2, int a3)
{
__int64 v5; // rbp
double v6; // xmm0_8
int v7; // ecx
__int64 v8; // rsi
__int64 result; // rax
int v10; // ebp
__int64 v11; // r14
int v12; // eax

v5 = images;
v6 = log2((double)a1);
v7 = RESOLUTION;
v8 = *(_QWORD *)(v5 + 8LL * (int)v6 - 32);
result = (unsigned int)(RESOLUTION / a1);
if ( a2 < a3 )
{
v10 = RESOLUTION / a1;
v11 = v8 + 4LL * a2;
while ( 1 )
{
v12 = a2++;
v11 += 4LL;
result = func1(rays + 44LL * (v7 * v10 * (v12 / a1) + v10 * (v12 % a1)), root, 0);
*(_DWORD *)(v11 - 4) = result;
if ( a3 == a2 )
break;
v7 = RESOLUTION;
}
}
return result;
}

original_code:
void* trace_rays(int resolution, int start, int stop){
  Display_color* image = images[(int)log2(resolution) - 4];
  int limit = resolution*resolution/64;
  int factor = RESOLUTION/resolution;
  for(int c = start; c < stop; c++){
    int row = c/resolution;
    int col = c%resolution;
    row *= factor;
    col *= factor;
    image[c] = trace_ray(&rays[row*RESOLUTION + col], root, 0);
  }
}

canonical_original_code:
void *trace_rays(int resolution, int start, int stop){
  struct Display_color *image = images[(int)log2(resolution) - 4];
  int limit = resolution*resolution/64;
  int factor = RESOLUTION/resolution;
  for(int c = start; c < stop; c++){
    int row = c/resolution;
    int col = c%resolution;
    row *= factor;
    col *= factor;
    image[c] = trace_ray(&rays[row*RESOLUTION + col], root, 0);
  }
}

variable_types: resolution int

variable_types: start int

variable_types: stop int

variable_types: struct Display_color { unsigned char a; unsigned char b; unsigned char g; unsigned char r; } *

variable_types: limit int

variable_types: factor int

variable_types: row int

variable_types: col int

return_type: void *


decompiled_code:
int __fastcall print_ray(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, double a7, double a8, double a9, double a10, double a11, double a12, double a13, double a14, __int64 a15, __int64 a16, __int64 a17, float a18)
{
printf("Start: ");
printf("%f,%f,%f\n", *(float *)&a15, *((float *)&a15 + 1), *(float *)&a16);
printf("Dir: ");
printf("%f,%f,%f\n", *((float *)&a16 + 1), *(float *)&a17, *((float *)&a17 + 1));
printf("Dist: ");
return printf("%f\n", a18);
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, double a7, double a8, double a9, double a10, double a11, double a12, double a13, double a14, __int64 a15, __int64 a16, __int64 a17, float a18)
{
printf("Start: ");
printf("%f,%f,%f\n", *(float *)&a15, *((float *)&a15 + 1), *(float *)&a16);
printf("Dir: ");
printf("%f,%f,%f\n", *((float *)&a16 + 1), *(float *)&a17, *((float *)&a17 + 1));
printf("Dist: ");
return printf("%f\n", a18);
}

original_code:
void print_ray(Ray r){
  printf("Start: ");
  printf("%f,%f,%f\n", r.start.x, r.start.y, r.start.z);
  printf("Dir: ");
  printf("%f,%f,%f\n", r.dir.x, r.dir.y, r.dir.z);
  printf("Dist: ");
  printf("%f\n", r.distance);
}

canonical_original_code:
void print_ray(struct Ray r){
  printf("Start: ");
  printf("%f,%f,%f\n", r.start.x, r.start.y, r.start.z);
  printf("Dir: ");
  printf("%f,%f,%f\n", r.dir.x, r.dir.y, r.dir.z);
  printf("Dist: ");
  printf("%f\n", r.distance);
}

variable_types: struct Ray { struct Coord { float x; float y; float z; } start; struct Coord dir; float distance; struct Color { float a; float b; float g; float r; } color; }


decompiled_code:
_BOOL8 __fastcall batch_has_next(__int64 a1)
{
return *(_DWORD *)(a1 + 20) < *(_DWORD *)(a1 + 16);
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(__int64 a1)
{
return *(_DWORD *)(a1 + 20) < *(_DWORD *)(a1 + 16);
}

original_code:
int batch_has_next(Batch* b){
  if(b->current_pos < b->num_positions){
    return 1;
  }
  else{
    return 0;
  }
}

canonical_original_code:
int batch_has_next(struct Batch *b){
  if(b->current_pos < b->num_positions){
    return 1;
  }
  else{
    return 0;
  }
}

variable_types: struct Batch { struct Coord { float x; float y; float z; } *positions; int *transitions; int num_positions; int current_pos; int current_pos_progress; int pic_number; } *

return_type: int

user_defined_types: struct Batch { struct Coord *positions; int *transitions; int num_positions; int current_pos; int current_pos_progress; int pic_number; }


rotate

original_code:
Coord rotate(Coord v1, Coord v2, double fraction){
  double angle = angle_between_Coords(v1,v2);
  angle = angle*fraction;
  Coord axis = cross_product(v1,v2);
  if(length_Coord(axis) == 0){
    fprintf(stderr, "ERROR: Plane undefined. Exiting\n");
    exit(-1);
  }
  normalize_Coord(&axis);
  Coord r;
  double u = axis.x; double v = axis.y; double w = axis.z;
  double x = v1.x; double y = v1.y; double z = v1.z;
  r.x = u*(u*x+v*y+w*z)*(1-cos(angle)) + x*cos(angle) + (-w*y+v*z)*sin(angle);
  r.y = v*(u*x+v*y+w*z)*(1-cos(angle)) + y*cos(angle) + (w*x-u*z)*sin(angle);
  r.z = w*(u*x+v*y+w*z)*(1-cos(angle)) + z*cos(angle) + (-v*x+u*y)*sin(angle);
  return r;
}

canonical_original_code:
struct Coord rotate(struct Coord v1, struct Coord v2, double fraction){
  double angle = angle_between_Coords(v1,v2);
  angle = angle*fraction;
  struct Coord axis = cross_product(v1,v2);
  if(length_Coord(axis) == 0){
    fprintf(stderr, "ERROR: Plane undefined. Exiting\n");
    exit(-1);
  }
  normalize_Coord(&axis);
  struct Coord r;
  double u = axis.x; double v = axis.y; double w = axis.z;
  double x = v1.x; double y = v1.y; double z = v1.z;
  r.x = u*(u*x+v*y+w*z)*(1-cos(angle)) + x*cos(angle) + (-w*y+v*z)*sin(angle);
  r.y = v*(u*x+v*y+w*z)*(1-cos(angle)) + y*cos(angle) + (w*x-u*z)*sin(angle);
  r.z = w*(u*x+v*y+w*z)*(1-cos(angle)) + z*cos(angle) + (-v*x+u*y)*sin(angle);
  return r;
}

variable_types: fraction double

variable_types: angle double

variable_types: struct Coord { float x; float y; float z; }

variable_types: u double

variable_types: v double

variable_types: w double

variable_types: x double

variable_types: y double

variable_types: z double


original_code:
void batch_next(Batch* b, Raycreator* rc){
  b->pic_number++;
  if(b->current_pos == b->num_positions -1){
    rc->eye = b->positions[b->current_pos * 2];
    rc->forward = b->positions[b->current_pos* 2 + 1];
    b->current_pos++;
  }
  else{
    Coord pos;
    Coord dir;
    double aaa = (double)(b->current_pos_progress);
    double bbb = (double)(b->transitions[b->current_pos]);
    double weight = aaa / bbb;
    pos.x = (1-weight)*b->positions[b->current_pos*2].x + weight*b->positions[(b->current_pos + 1)*2].x;
    pos.y = (1-weight)*b->positions[b->current_pos*2].y + weight*b->positions[(b->current_pos + 1)*2].y;
    pos.z = (1-weight)*b->positions[b->current_pos*2].z + weight*b->positions[(b->current_pos + 1)*2].z;
    dir = rotate(b->positions[b->current_pos*2 + 1],b->positions[(b->current_pos+1)*2 + 1], weight);
    rc->eye = pos;
    rc->forward = dir;
    print_coord(dir);
    b->current_pos_progress++;
    if(b->current_pos_progress == b->transitions[b->current_pos]){
      b->current_pos_progress = 0;
      b->current_pos++;
    }
  }
}

canonical_original_code:
void batch_next(struct Batch *b, struct rcstruct *rc){
  b->pic_number++;
  if(b->current_pos == b->num_positions -1){
    rc->eye = b->positions[b->current_pos * 2];
    rc->forward = b->positions[b->current_pos* 2 + 1];
    b->current_pos++;
  }
  else{
    struct Coord pos;
    struct Coord dir;
    double aaa = (double)(b->current_pos_progress);
    double bbb = (double)(b->transitions[b->current_pos]);
    double weight = aaa / bbb;
    pos.x = (1-weight)*b->positions[b->current_pos*2].x + weight*b->positions[(b->current_pos + 1)*2].x;
    pos.y = (1-weight)*b->positions[b->current_pos*2].y + weight*b->positions[(b->current_pos + 1)*2].y;
    pos.z = (1-weight)*b->positions[b->current_pos*2].z + weight*b->positions[(b->current_pos + 1)*2].z;
    dir = rotate(b->positions[b->current_pos*2 + 1],b->positions[(b->current_pos+1)*2 + 1], weight);
    rc->eye = pos;
    rc->forward = dir;
    print_coord(dir);
    b->current_pos_progress++;
    if(b->current_pos_progress == b->transitions[b->current_pos]){
      b->current_pos_progress = 0;
      b->current_pos++;
    }
  }
}

variable_types: struct rcstruct { int resolution; struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; } *ranges; float fov; struct Coord eye; struct Coord forward; struct Coord right; struct Coord up; struct Coord screen_center; float pixel_width; } *

variable_types: aaa double

variable_types: bbb double

variable_types: weight double


decompiled_code:
__int64 __fastcall print_batch(__int64 a1)
{
__int64 result; // rax
int v2; // er12
__int64 v3; // rbx
double v4; // xmm0_8
float v5; // xmm1_4
__int64 v6; // rbx
__int64 v7; // rsi

result = *(unsigned int *)(a1 + 16);
if ( (int)result > 0 )
{
v2 = 0;
v3 = 0LL;
do
{
++v2;
print_coord(*(double *)(*(_QWORD *)a1 + v3), *(float *)(*(_QWORD *)a1 + v3 + 8));
v4 = *(double *)(*(_QWORD *)a1 + v3 + 12);
v5 = *(float *)(*(_QWORD *)a1 + v3 + 20);
v3 += 24LL;
print_coord(v4, v5);
putchar(10);
result = *(unsigned int *)(a1 + 16);
}
while ( (int)result > v2 );
if ( (int)result > 1 )
{
v6 = 0LL;
do
{
v7 = *(unsigned int *)(*(_QWORD *)(a1 + 8) + 4 * v6++);
printf("%d\n", v7);
result = (unsigned int)(*(_DWORD *)(a1 + 16) - 1);
}
while ( (int)result > (int)v6 );
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
__int64 result; // rax
int v2; // er12
__int64 v3; // rbx
double v4; // xmm0_8
float v5; // xmm1_4
__int64 v6; // rbx
__int64 v7; // rsi

result = *(unsigned int *)(a1 + 16);
if ( (int)result > 0 )
{
v2 = 0;
v3 = 0LL;
do
{
++v2;
print_coord(*(double *)(*(_QWORD *)a1 + v3), *(float *)(*(_QWORD *)a1 + v3 + 8));
v4 = *(double *)(*(_QWORD *)a1 + v3 + 12);
v5 = *(float *)(*(_QWORD *)a1 + v3 + 20);
v3 += 24LL;
print_coord(v4, v5);
putchar(10);
result = *(unsigned int *)(a1 + 16);
}
while ( (int)result > v2 );
if ( (int)result > 1 )
{
v6 = 0LL;
do
{
v7 = *(unsigned int *)(*(_QWORD *)(a1 + 8) + 4 * v6++);
printf("%d\n", v7);
result = (unsigned int)(*(_DWORD *)(a1 + 16) - 1);
}
while ( (int)result > (int)v6 );
}
}
return result;
}

original_code:
void print_batch(Batch* b){
  for(int c = 0; c < b->num_positions; c++){
    print_coord(b->positions[2*c]);
    print_coord(b->positions[2*c+1]);
    printf("\n");
  }
  for(int c = 0; c < b->num_positions -1; c++){
    printf("%d\n", b->transitions[c]);
  }
}

canonical_original_code:
void print_batch(struct Batch *b){
  for(int c = 0; c < b->num_positions; c++){
    print_coord(b->positions[2*c]);
    print_coord(b->positions[2*c+1]);
    printf("\n");
  }
  for(int c = 0; c < b->num_positions -1; c++){
    printf("%d\n", b->transitions[c]);
  }
}

variable_types: c int


original_code:
Display_color to_display_color(Color c){
  Display_color dc;
  if(c.r > 1.0){
    c.r = 1.0;
  }
  if(c.b > 1.0){
    c.b = 1.0;
  }
  if(c.g > 1.0){
    c.g = 1.0;
  }
  dc.a = (unsigned char)(c.a*255);
  dc.r = (unsigned char)(c.r*255);
  dc.g = (unsigned char)(c.g*255);
  dc.b = (unsigned char)(c.b*255);
  return dc;
}

canonical_original_code:
struct Display_color to_display_color(struct Color c){
  struct Display_color dc;
  if(c.r > 1.0){
    c.r = 1.0;
  }
  if(c.b > 1.0){
    c.b = 1.0;
  }
  if(c.g > 1.0){
    c.g = 1.0;
  }
  dc.a = (unsigned char)(c.a*255);
  dc.r = (unsigned char)(c.r*255);
  dc.g = (unsigned char)(c.g*255);
  dc.b = (unsigned char)(c.b*255);
  return dc;
}

variable_types: struct Color { float a; float b; float g; float r; }

variable_types: struct Display_color { unsigned char a; unsigned char b; unsigned char g; unsigned char r; }


blend

decompiled_code:
__int64 __fastcall blend(float *a1, float a2)
{
__int64 result; // rax
float v3; // xmm1_4
float v4; // xmm0_4
float v5; // xmm2_4
int v6[6]; // [rsp+0h] [rbp-18h] BYREF

result = set_color_from_table(transfer_overlay, v6, a2 / *(float *)(transfer_overlay + 40LL));
v3 = *a1;
v4 = (float)(1.0 - *a1) * *(float *)v6;
a1[3] = (float)(*(float *)&v6[3] * v4) + a1[3];
a1[2] = (float)(*(float *)&v6[2] * v4) + a1[2];
v5 = (float)(*(float *)&v6[1] * v4) + a1[1];
*a1 = v4 + v3;
a1[1] = v5;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(float *a1, float a2)
{
__int64 result; // rax
float v3; // xmm1_4
float v4; // xmm0_4
float v5; // xmm2_4
int v6[6]; // [rsp+0h] [rbp-18h] BYREF

result = set_color_from_table(transfer_overlay, v6, a2 / *(float *)(transfer_overlay + 40LL));
v3 = *a1;
v4 = (float)(1.0 - *a1) * *(float *)v6;
a1[3] = (float)(*(float *)&v6[3] * v4) + a1[3];
a1[2] = (float)(*(float *)&v6[2] * v4) + a1[2];
v5 = (float)(*(float *)&v6[1] * v4) + a1[1];
*a1 = v4 + v3;
a1[1] = v5;
return result;
}

original_code:
void blend(Color* output, float intensity){
  Color new_color;
  set_color_from_table(transfer_overlay, intensity/transfer_overlay->max_intensity, &new_color);
  output->r = output->r + (1-output->a)*new_color.a*new_color.r;
  output->g = output->g + (1-output->a)*new_color.a*new_color.g;
  output->b = output->b + (1-output->a)*new_color.a*new_color.b;
  output->a = output->a + (1-output->a)*new_color.a;
}

canonical_original_code:
void blend(struct Color *output, float intensity){
  struct Color new_color;
  set_color_from_table(transfer_overlay, intensity/transfer_overlay->max_intensity, &new_color);
  output->r = output->r + (1-output->a)*new_color.a*new_color.r;
  output->g = output->g + (1-output->a)*new_color.a*new_color.g;
  output->b = output->b + (1-output->a)*new_color.a*new_color.b;
  output->a = output->a + (1-output->a)*new_color.a;
}

variable_types: struct Color { float a; float b; float g; float r; } *

variable_types: intensity float


decompiled_code:
int __fastcall print_color(__m128i a1, __m128i a2)
{
return printf(
"%f, %f, %f, %f\n",
*(float *)&a2.m128i_i32[1],
COERCE_FLOAT(_mm_cvtsi128_si32(a2)),
*(float *)&a1.m128i_i32[1],
COERCE_FLOAT(_mm_cvtsi128_si32(a1)));
}

canonical_decompiled_code:
int __fastcall func2(__m128i a1, __m128i a2)
{
return printf(
"%f, %f, %f, %f\n",
*(float *)&a2.m128i_i32[1],
COERCE_FLOAT(_mm_cvtsi128_si32(a2)),
*(float *)&a1.m128i_i32[1],
COERCE_FLOAT(_mm_cvtsi128_si32(a1)));
}

original_code:
void print_color(Color c){
  printf("%f, %f, %f, %f\n", c.r, c.g, c.b, c.a);
}

canonical_original_code:
void print_color(struct Color c){
  printf("%f, %f, %f, %f\n", c.r, c.g, c.b, c.a);
}


hashHC

repo: acharal/mhtransf-lar

decompiled_code:
__int64 __fastcall hashHC(unsigned __int8 a1, int a2)
{
return (HCTABLESIZE - 1) & ((a2 ^ (a1 << 13)) + 177573);
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned __int8 a1, int a2)
{
return (HCTABLESIZE - 1) & ((a2 ^ (a1 << 13)) + 177573);
}

original_code:
static tagHC hashHC (tag h, list l)
{
  register tagHC hash = 5381;
  hash = ((hash << 5) + hash) + (((tagHC) l)^((tagHC) h<<13));
  return hash & ((tagHC) (HCTABLESIZE - 1));
}

canonical_original_code:
static unsigned int hashHC(unsigned char h, unsigned int l)
{
  register unsigned int hash = 5381;
  hash = ((hash << 5) + hash) + (((unsigned int) l)^((unsigned int) h<<13));
  return hash & ((tagHC) (HCTABLESIZE - 1));
}

variable_types:
h
unsigned char

variable_types:
l
unsigned int

variable_types:
hash
unsigned int

return_type: unsigned int


hashCons

decompiled_code:
__int64 __fastcall hashCons(unsigned __int8 a1, int a2)
{
unsigned int *v2; // rdi
char v3; // r8
char v4; // r9
__int64 result; // rax
char *v6; // rdx
char *v7; // rdx
int v8; // ecx

v2 = (unsigned int *)((char *)tableHC + 4 * (unsigned int)hashHC(a1, a2));
result = *v2;
if ( (_DWORD)result == -1 )
{
LABEL_7:
++entriesHC;
result = (unsigned int)freeHC;
v7 = (char *)heapHC + 12 * (unsigned int)freeHC;
freeHC = *((_DWORD *)v7 + 2);
v8 = *v2;
*v7 = v4;
*((_DWORD *)v7 + 2) = v8;
*((_DWORD *)v7 + 1) = a2;
*v2 = result;
}
else
{
while ( 1 )
{
v6 = (char *)heapHC + 12 * (unsigned int)result;
if ( *v6 == v3 && *((_DWORD *)v6 + 1) == a2 )
break;
result = *((unsigned int *)v6 + 2);
if ( (_DWORD)result == -1 )
goto LABEL_7;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned __int8 a1, int a2)
{
unsigned int *v2; // rdi
char v3; // r8
char v4; // r9
__int64 result; // rax
char *v6; // rdx
char *v7; // rdx
int v8; // ecx

v2 = (unsigned int *)((char *)tableHC + 4 * (unsigned int)func0(a1, a2));
result = *v2;
if ( (_DWORD)result == -1 )
{
LABEL_7:
++entriesHC;
result = (unsigned int)freeHC;
v7 = (char *)heapHC + 12 * (unsigned int)freeHC;
freeHC = *((_DWORD *)v7 + 2);
v8 = *v2;
*v7 = v4;
*((_DWORD *)v7 + 2) = v8;
*((_DWORD *)v7 + 1) = a2;
*v2 = result;
}
else
{
while ( 1 )
{
v6 = (char *)heapHC + 12 * (unsigned int)result;
if ( *v6 == v3 && *((_DWORD *)v6 + 1) == a2 )
break;
result = *((unsigned int *)v6 + 2);
if ( (_DWORD)result == -1 )
goto LABEL_7;
}
}
return result;
}

original_code:
static list hashCons (tag h, list l)
{
  tagHC hashval = hashHC(h, l);
  tagHC ptr;
  for (ptr = tableHC[hashval].ptr; ptr != ((tagHC) (-1)); ptr = heapHC[ptr].ptr)
    if (heapHC[ptr].head == h && heapHC[ptr].tail == l) {
      return ptr;
    }
    else {
      ;
    }
  ptr = freeHC;
  freeHC = heapHC[freeHC].ptr;
  entriesHC++;
  heapHC[ptr].ptr = tableHC[hashval].ptr;
  heapHC[ptr].head = h;
  heapHC[ptr].tail = l;
  tableHC[hashval].ptr = ptr;
  return ptr;
}

canonical_original_code:
static unsigned int hashCons(unsigned char h, unsigned int l)
{
  unsigned int hashval = hashHC(h, l);
  unsigned int ptr;
  for (ptr = tableHC[hashval].ptr; ptr != ((tagHC) (-1)); ptr = heapHC[ptr].ptr)
    if (heapHC[ptr].head == h && heapHC[ptr].tail == l) {
      return ptr;
    }
    else {
      ;
    }
  ptr = freeHC;
  freeHC = heapHC[freeHC].ptr;
  entriesHC++;
  heapHC[ptr].ptr = tableHC[hashval].ptr;
  heapHC[ptr].head = h;
  heapHC[ptr].tail = l;
  tableHC[hashval].ptr = ptr;
  return ptr;
}

variable_types:
hashval
unsigned int

variable_types:
ptr
unsigned int


initializeHC

decompiled_code:
int initializeHC()
{
__int64 v0; // rbp
size_t v1; // r12
__int64 v2; // r12
_BYTE *v3; // rax
_BYTE *v4; // rsi
int v5; // ecx
_BYTE *v6; // rdx
int v7; // eax

if ( tableHC )
free(tableHC);
v0 = HCTABLESIZE;
v1 = 4LL * HCTABLESIZE;
tableHC = malloc(v1);
if ( !tableHC )
{
fwrite("Out of memory: allocating the table for hash consing\n", 1uLL, 0x35uLL, stderr);
exit(1);
}
if ( (_DWORD)v0 )
memset(tableHC, 255, v1);
if ( heapHC )
free(heapHC);
v2 = HCHEAPSIZE;
v3 = malloc(12LL * HCHEAPSIZE);
heapHC = v3;
v4 = v3;
if ( !v3 )
{
fwrite("Out of memory: allocating the heap for hash consing\n", 1uLL, 0x34uLL, stderr);
exit(1);
}
v5 = v2 - 1;
*v3 = 0;
*(_QWORD *)(v3 + 4) = -1LL;
if ( (unsigned int)(v2 - 1) > 1 )
{
v6 = v3 + 20;
v7 = 1;
do
{
++v7;
v6 += 12;
*((_DWORD *)v6 - 3) = v7;
}
while ( v7 != v5 );
}
entriesHC = 1;
*(_DWORD *)&v4[12 * v5 + 8] = -1;
freeHC = 1;
HCGCLIMIT = (int)((double)(int)v2 * 0.98 - (double)MAXDIM);
return printf("HC memory: %u bytes\n", 4 * (v0 + 3 * v2));
}

canonical_decompiled_code:
int func2()
{
__int64 v0; // rbp
size_t v1; // r12
__int64 v2; // r12
_BYTE *v3; // rax
_BYTE *v4; // rsi
int v5; // ecx
_BYTE *v6; // rdx
int v7; // eax

if ( tableHC )
free(tableHC);
v0 = HCTABLESIZE;
v1 = 4LL * HCTABLESIZE;
tableHC = malloc(v1);
if ( !tableHC )
{
fwrite("Out of memory: allocating the table for hash consing\n", 1uLL, 0x35uLL, stderr);
exit(1);
}
if ( (_DWORD)v0 )
memset(tableHC, 255, v1);
if ( heapHC )
free(heapHC);
v2 = HCHEAPSIZE;
v3 = malloc(12LL * HCHEAPSIZE);
heapHC = v3;
v4 = v3;
if ( !v3 )
{
fwrite("Out of memory: allocating the heap for hash consing\n", 1uLL, 0x34uLL, stderr);
exit(1);
}
v5 = v2 - 1;
*v3 = 0;
*(_QWORD *)(v3 + 4) = -1LL;
if ( (unsigned int)(v2 - 1) > 1 )
{
v6 = v3 + 20;
v7 = 1;
do
{
++v7;
v6 += 12;
*((_DWORD *)v6 - 3) = v7;
}
while ( v7 != v5 );
}
entriesHC = 1;
*(_DWORD *)&v4[12 * v5 + 8] = -1;
freeHC = 1;
HCGCLIMIT = (int)((double)(int)v2 * 0.98 - (double)MAXDIM);
return printf("HC memory: %u bytes\n", 4 * (v0 + 3 * v2));
}

original_code:
void initializeHC ()
{
  if (tableHC != ((void *)0))
    free(tableHC);
  tableHC = (struct bucketHC *) malloc(HCTABLESIZE * sizeof(struct bucketHC));
  if (tableHC == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the table for hash consing\n");
    exit(1);
  }
  for (tagHC i = 0; i < HCTABLESIZE; i++)
    tableHC[i].ptr = ((tagHC) (-1));
  if (heapHC != ((void *)0))
    free(heapHC);
  heapHC = (struct nodeHC *) malloc(HCHEAPSIZE * sizeof(struct nodeHC));
  if (heapHC == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the heap for hash consing\n");
    exit(1);
  }
  heapHC[0].head = 0;
  heapHC[0].tail = ((tagHC) (-1));
  heapHC[0].ptr = ((tagHC) (-1));
  for (tagHC i = 1; i < HCHEAPSIZE-1; i++)
    heapHC[i].ptr = i+1;
  heapHC[HCHEAPSIZE-1].ptr = ((tagHC) (-1));
  entriesHC = 1;
  HCGCLIMIT = HCHEAPSIZE * 0.98 - MAXDIM;
  freeHC = 1;
  printf("HC memory: %u bytes\n", HCTABLESIZE * sizeof(struct bucketHC)
  + HCHEAPSIZE * sizeof(struct nodeHC));
}

canonical_original_code:
void initializeHC()
{
  if (tableHC != ((void *)0))
    free(tableHC);
  tableHC = (struct bucketHC *) malloc(HCTABLESIZE * sizeof(struct bucketHC));
  if (tableHC == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the table for hash consing\n");
    exit(1);
  }
  for (unsigned int i = 0; i < HCTABLESIZE; i++)
    tableHC[i].ptr = ((tagHC) (-1));
  if (heapHC != ((void *)0))
    free(heapHC);
  heapHC = (struct nodeHC *) malloc(HCHEAPSIZE * sizeof(struct nodeHC));
  if (heapHC == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the heap for hash consing\n");
    exit(1);
  }
  heapHC[0].head = 0;
  heapHC[0].tail = ((tagHC) (-1));
  heapHC[0].ptr = ((tagHC) (-1));
  for (unsigned int i = 1; i < HCHEAPSIZE-1; i++)
    heapHC[i].ptr = i+1;
  heapHC[HCHEAPSIZE-1].ptr = ((tagHC) (-1));
  entriesHC = 1;
  HCGCLIMIT = HCHEAPSIZE * 0.98 - MAXDIM;
  freeHC = 1;
  printf("HC memory: %u bytes\n", HCTABLESIZE * sizeof(struct bucketHC)
  + HCHEAPSIZE * sizeof(struct nodeHC));
}

variable_types:
i
unsigned int

user_defined_types: struct nodeHC { unsigned char head; unsigned int tail; unsigned int ptr; }


gcollectHC

decompiled_code:
unsigned __int64 __fastcall gcollectHC(_QWORD *a1)
{
int v2; // edi
char *v3; // rcx
unsigned int *v4; // rsi
__int64 i; // rax
char *v6; // rdx
unsigned __int64 result; // rax
unsigned int v8; // edx
__int64 v9; // rdi
char v10; // cl
unsigned int *v11; // rsi
__int64 v12; // r8
__int64 v13; // rcx
unsigned int *v14; // rsi
char *v15; // r8
unsigned int *v16; // r9
char *v17; // r10
unsigned int v18; // edx
char *v19; // rax

v2 = MAXDIM;
if ( a1 )
{
v3 = (char *)heapHC;
do
{
v4 = (unsigned int *)(a1 + 1);
if ( (_BYTE)v2 )
{
do
{
for ( i = *v4; (_DWORD)i; i = *((unsigned int *)v6 + 1) )
{
v6 = &v3[12 * i];
if ( *v6 < 0 )
break;
*v6 |= 0x80u;
}
++v4;
}
while ( (unsigned int *)((char *)a1 + 4 * (unsigned __int8)(v2 - 1) + 12) != v4 );
}
a1 = (_QWORD *)*a1;
}
while ( a1 );
}
if ( WHTABLESIZE )
{
result = tableWH;
while ( 1 )
{
v8 = *(_DWORD *)result;
if ( *(_DWORD *)result != -1 )
break;
result += 4LL;
if ( result == tableWH + 4LL * (unsigned int)(WHTABLESIZE - 1) + 4 )
goto LABEL_21;
}
v9 = rawHeapWH + 4 * v8 * ((unsigned __int8)v2 + 5LL);
if ( *(_DWORD *)(v9 + 4) != 0x80000000 )
{
v10 = *(_BYTE *)(v9 + 16);
if ( v10 )
{
v11 = (unsigned int *)(v9 + 20);
v12 = v9 + 4LL * (unsigned __int8)(v10 - 1) + 24;
while ( 1 )
{
v13 = *v11;
if ( (_DWORD)v13 )
{
if ( *((char *)heapHC + 12 * v13) >= 0 )
break;
}
if ( (unsigned int *)v12 == ++v11 )
return result;
}
*(_DWORD *)result = *(_DWORD *)(v9 + 12);
result = freeWH;
--entriesWH;
*(_DWORD *)(v9 + 12) = freeWH;
freeWH = v8;
}
}
}
else
{
LABEL_21:
if ( HCTABLESIZE )
{
v14 = (unsigned int *)tableHC;
v15 = (char *)heapHC;
v16 = (unsigned int *)((char *)tableHC + 4);
v17 = (char *)tableHC + 4 * (unsigned int)(HCTABLESIZE - 1) + 4;
while ( 1 )
{
while ( 1 )
{
v18 = *v14;
if ( *v14 == -1 )
break;
while ( 1 )
{
v19 = &v15[12 * v18];
if ( *v19 < 0 )
break;
*v14 = *((_DWORD *)v19 + 2);
--entriesHC;
*((_DWORD *)v19 + 2) = freeHC;
freeHC = v18;
v18 = *v14;
if ( *v14 == -1 )
goto LABEL_26;
}
v14 = (unsigned int *)(v19 + 8);
*v19 &= 0x7Fu;
}
LABEL_26:
v14 = v16;
if ( v17 == (char *)v16 )
break;
++v16;
}
}
result = (unsigned int)(HCHEAPSIZE - v2);
if ( (unsigned int)result <= entriesHC )
{
fwrite("FATAL ERROR: Out of heap space for hash consing\n", 1uLL, 0x30uLL, stderr);
exit(1);
}
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func3(_QWORD *a1)
{
int v2; // edi
char *v3; // rcx
unsigned int *v4; // rsi
__int64 i; // rax
char *v6; // rdx
unsigned __int64 result; // rax
unsigned int v8; // edx
__int64 v9; // rdi
char v10; // cl
unsigned int *v11; // rsi
__int64 v12; // r8
__int64 v13; // rcx
unsigned int *v14; // rsi
char *v15; // r8
unsigned int *v16; // r9
char *v17; // r10
unsigned int v18; // edx
char *v19; // rax

v2 = MAXDIM;
if ( a1 )
{
v3 = (char *)heapHC;
do
{
v4 = (unsigned int *)(a1 + 1);
if ( (_BYTE)v2 )
{
do
{
for ( i = *v4; (_DWORD)i; i = *((unsigned int *)v6 + 1) )
{
v6 = &v3[12 * i];
if ( *v6 < 0 )
break;
*v6 |= 0x80u;
}
++v4;
}
while ( (unsigned int *)((char *)a1 + 4 * (unsigned __int8)(v2 - 1) + 12) != v4 );
}
a1 = (_QWORD *)*a1;
}
while ( a1 );
}
if ( WHTABLESIZE )
{
result = tableWH;
while ( 1 )
{
v8 = *(_DWORD *)result;
if ( *(_DWORD *)result != -1 )
break;
result += 4LL;
if ( result == tableWH + 4LL * (unsigned int)(WHTABLESIZE - 1) + 4 )
goto LABEL_21;
}
v9 = rawHeapWH + 4 * v8 * ((unsigned __int8)v2 + 5LL);
if ( *(_DWORD *)(v9 + 4) != 0x80000000 )
{
v10 = *(_BYTE *)(v9 + 16);
if ( v10 )
{
v11 = (unsigned int *)(v9 + 20);
v12 = v9 + 4LL * (unsigned __int8)(v10 - 1) + 24;
while ( 1 )
{
v13 = *v11;
if ( (_DWORD)v13 )
{
if ( *((char *)heapHC + 12 * v13) >= 0 )
break;
}
if ( (unsigned int *)v12 == ++v11 )
return result;
}
*(_DWORD *)result = *(_DWORD *)(v9 + 12);
result = freeWH;
--entriesWH;
*(_DWORD *)(v9 + 12) = freeWH;
freeWH = v8;
}
}
}
else
{
LABEL_21:
if ( HCTABLESIZE )
{
v14 = (unsigned int *)tableHC;
v15 = (char *)heapHC;
v16 = (unsigned int *)((char *)tableHC + 4);
v17 = (char *)tableHC + 4 * (unsigned int)(HCTABLESIZE - 1) + 4;
while ( 1 )
{
while ( 1 )
{
v18 = *v14;
if ( *v14 == -1 )
break;
while ( 1 )
{
v19 = &v15[12 * v18];
if ( *v19 < 0 )
break;
*v14 = *((_DWORD *)v19 + 2);
--entriesHC;
*((_DWORD *)v19 + 2) = freeHC;
freeHC = v18;
v18 = *v14;
if ( *v14 == -1 )
goto LABEL_26;
}
v14 = (unsigned int *)(v19 + 8);
*v19 &= 0x7Fu;
}
LABEL_26:
v14 = v16;
if ( v17 == (char *)v16 )
break;
++v16;
}
}
result = (unsigned int)(HCHEAPSIZE - v2);
if ( (unsigned int)result <= entriesHC )
{
fwrite("FATAL ERROR: Out of heap space for hash consing\n", 1uLL, 0x30uLL, stderr);
exit(1);
}
}
return result;
}

original_code:
void gcollectHC (World *w)
{
  for (; w != ((void *)0); w = w->prev)
    for (dimension d = 0; d < MAXDIM; d++)
      for (list l = w->l[d];
    l != 0 && !(heapHC[l].head & ((tag) 1 << (8 * sizeof(tag) - 1)));
    l = heapHC[l].tail) {
 heapHC[l].head |= ((tag) 1 << (8 * sizeof(tag) - 1));
      }
  for (tagWH i = 0; i < WHTABLESIZE; i++)
    for (tagWH * ptr = &(tableWH[i].ptr); *ptr != ((tagWH) (-1));) {
      if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val != ((value) 1 << (8 * sizeof(value) - 1)))
        for (dimension d = 0; d < ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->depDim; d++) {
          list l = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d];
          if (l != 0 && !(heapHC[l].head & ((tag) 1 << (8 * sizeof(tag) - 1)))) {
            tagWH prev = *ptr;
            *ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
            ((struct nodeWH *) ((unsigned char *) rawHeapWH + (prev) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = freeWH;
            freeWH = prev;
            entriesWH--;
            goto skipForwardingPtr;
          }
        }
      ptr = &(((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr);
skipForwardingPtr:
 return;
    }
  for (tagHC i = 0; i < HCTABLESIZE; i++)
    for (tagHC * ptr = &(tableHC[i].ptr); *ptr != ((tagHC) (-1)); )
      if (heapHC[*ptr].head & ((tag) 1 << (8 * sizeof(tag) - 1))) {
 heapHC[*ptr].head &= ~((tag) 1 << (8 * sizeof(tag) - 1));
 ptr = &(heapHC[*ptr].ptr);
      }
      else {
 tagHC prev = *ptr;
 *ptr = heapHC[*ptr].ptr;
 heapHC[prev].ptr = freeHC;
 freeHC = prev;
 entriesHC--;
      }
    if (entriesHC >= HCHEAPSIZE - MAXDIM) {
      fprintf(stderr, "FATAL ERROR: Out of heap space for hash consing\n");
      exit(1);
    }
}

canonical_original_code:
void gcollectHC(struct world_tag *w)
{
  for (; w != ((void *)0); w = w->prev)
    for (unsigned char d = 0; d < MAXDIM; d++)
      for (unsigned int l = w->l[d];
    l != 0 && !(heapHC[l].head & ((unsigned char) 1 << (8 * sizeof(tag) - 1)));
    l = heapHC[l].tail) {
 heapHC[l].head |= ((unsigned char) 1 << (8 * sizeof(tag) - 1));
      }
  for (unsigned int i = 0; i < WHTABLESIZE; i++)
    for (unsigned int *ptr = &(tableWH[i].ptr); *ptr != ((tagWH) (-1));) {
      if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val != ((int) 1 << (8 * sizeof(value) - 1)))
        for (unsigned char d = 0; d < ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->depDim; d++) {
          unsigned int l = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d];
          if (l != 0 && !(heapHC[l].head & ((unsigned char) 1 << (8 * sizeof(tag) - 1)))) {
            unsigned int prev = *ptr;
            *ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
            ((struct nodeWH *) ((unsigned char *) rawHeapWH + (prev) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = freeWH;
            freeWH = prev;
            entriesWH--;
            goto skipForwardingPtr;
          }
        }
      ptr = &(((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr);
skipForwardingPtr:
 return;
    }
  for (unsigned int i = 0; i < HCTABLESIZE; i++)
    for (unsigned int *ptr = &(tableHC[i].ptr); *ptr != ((tagHC) (-1)); )
      if (heapHC[*ptr].head & ((unsigned char) 1 << (8 * sizeof(tag) - 1))) {
 heapHC[*ptr].head &= ~((unsigned char) 1 << (8 * sizeof(tag) - 1));
 ptr = &(heapHC[*ptr].ptr);
      }
      else {
 unsigned int prev = *ptr;
 *ptr = heapHC[*ptr].ptr;
 heapHC[prev].ptr = freeHC;
 freeHC = prev;
 entriesHC--;
      }
    if (entriesHC >= HCHEAPSIZE - MAXDIM) {
      fprintf(stderr, "FATAL ERROR: Out of heap space for hash consing\n");
      exit(1);
    }
}

variable_types: struct world_tag { struct world_tag *prev; unsigned int l[]; } *

variable_types:
d
unsigned char

variable_types:
ptr
unsigned int *

variable_types:
prev
unsigned int

user_defined_types: struct nodeWH { unsigned int id; int val; unsigned int age; unsigned int ptr; unsigned char depDim; unsigned int l[]; }


call

decompiled_code:
__int64 __fastcall call(unsigned __int8 a1, int a2)
{
return hashCons(a1, a2);
}

canonical_decompiled_code:
__int64 __fastcall func4(unsigned __int8 a1, int a2)
{
return func1(a1, a2);
}

original_code:
list call (tag i, list l)
{
  return hashCons(i, l);
}

canonical_original_code:
unsigned int call(unsigned char i, unsigned int l)
{
  return hashCons(i, l);
}

variable_types:
i
unsigned char


actuals

decompiled_code:
__int64 __fastcall actuals(unsigned __int8 a1, unsigned int a2)
{
unsigned __int8 *v2; // rax
__int64 v3; // rdx

v2 = (unsigned __int8 *)heapHC + 12 * a2;
v3 = *v2;
if ( (_BYTE)v3 != a1 )
{
fprintf(stderr, "Internal error: wrong actuals (%u instead of %u)\n", v3, a1);
exit(1);
}
return *((unsigned int *)v2 + 1);
}

canonical_decompiled_code:
__int64 __fastcall func5(unsigned __int8 a1, unsigned int a2)
{
unsigned __int8 *v2; // rax
__int64 v3; // rdx

v2 = (unsigned __int8 *)heapHC + 12 * a2;
v3 = *v2;
if ( (_BYTE)v3 != a1 )
{
fprintf(stderr, "Internal error: wrong actuals (%u instead of %u)\n", v3, a1);
exit(1);
}
return *((unsigned int *)v2 + 1);
}

original_code:
list actuals (tag i, list l)
{
  if (heapHC[l].head == i)
    return heapHC[l].tail;
  fprintf(stderr, "Internal error: wrong actuals (%u instead of %u)\n",
   heapHC[l].head, i);
  exit(1);
}

canonical_original_code:
unsigned int actuals(unsigned char i, unsigned int l)
{
  if (heapHC[l].head == i)
    return heapHC[l].tail;
  fprintf(stderr, "Internal error: wrong actuals (%u instead of %u)\n",
   heapHC[l].head, i);
  exit(1);
}


cases

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

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

original_code:
tag cases (list l)
{
  return heapHC[l].head;
}

canonical_original_code:
unsigned char cases(unsigned int l)
{
  return heapHC[l].head;
}

return_type: unsigned char


statsHC

decompiled_code:
int statsHC()
{
return printf(
"\n\nHC heapsize:\t%u\nHC freerecs:\t%.2lf%%\n\n",
HCHEAPSIZE,
(double)(HCHEAPSIZE - entriesHC) / (double)HCHEAPSIZE * 100.0);
}

canonical_decompiled_code:
int func7()
{
return printf(
"\n\nHC heapsize:\t%u\nHC freerecs:\t%.2lf%%\n\n",
HCHEAPSIZE,
(double)(HCHEAPSIZE - entriesHC) / (double)HCHEAPSIZE * 100.0);
}

original_code:
void statsHC ()
{
  printf("\n\nHC heapsize:\t%u\nHC freerecs:\t%.2lf%%\n\n",
  HCHEAPSIZE, ((double) (HCHEAPSIZE - entriesHC) / HCHEAPSIZE) * 100);
}

canonical_original_code:
void statsHC()
{
  printf("\n\nHC heapsize:\t%u\nHC freerecs:\t%.2lf%%\n\n",
  HCHEAPSIZE, ((double) (HCHEAPSIZE - entriesHC) / HCHEAPSIZE) * 100);
}


printList

decompiled_code:
int __fastcall printList(unsigned int a1)
{
__int64 v1; // rbx
__int64 v2; // rbx

v1 = a1;
putchar(91);
if ( a1 )
{
while ( 1 )
{
v2 = 12 * v1;
printf("%d", *((unsigned __int8 *)heapHC + v2));
v1 = *(unsigned int *)((char *)heapHC + v2 + 4);
if ( !(_DWORD)v1 )
break;
putchar(44);
}
}
return putchar(93);
}

canonical_decompiled_code:
int __fastcall func8(unsigned int a1)
{
__int64 v1; // rbx
__int64 v2; // rbx

v1 = a1;
putchar(91);
if ( a1 )
{
while ( 1 )
{
v2 = 12 * v1;
printf("%d", *((unsigned __int8 *)heapHC + v2));
v1 = *(unsigned int *)((char *)heapHC + v2 + 4);
if ( !(_DWORD)v1 )
break;
putchar(44);
}
}
return putchar(93);
}

original_code:
void printList (list l)
{
   printf("[");
 while (l != 0) {
      printf("%d", heapHC[l].head);
      l = heapHC[l].tail;
      if (l != 0)
         printf(",");
   }
 printf("]");
}

canonical_original_code:
void printList(unsigned int l)
{
   printf("[");
 while (l != 0) {
      printf("%d", heapHC[l].head);
      l = heapHC[l].tail;
      if (l != 0)
         printf(",");
   }
 printf("]");
}


hashWH

original_code:
static tagWH hashWH (identifier id, dimension depdim, World *w)
{
  register tagWH hash = 0x811c9dc5;
  for (register dimension d=0; d<depdim; d++)
    for (register int i=0; i<sizeof(list); ++i) {
       hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
       hash ^= *((unsigned char *) &(w->l[d]) + i);
    }
  for (register int i=0; i<sizeof(identifier); ++i) {
     hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
     hash ^= *((unsigned char *) &id + i);
  }
  return hash & ((tagWH) (WHTABLESIZE - 1));
}

canonical_original_code:
static unsigned int hashWH(unsigned int id, unsigned char depdim, struct world_tag *w)
{
  register unsigned int hash = 0x811c9dc5;
  for (register unsigned char d = 0; d<depdim; d++)
    for (register int i = 0; i<sizeof(list); ++i) {
       hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
       hash ^= *((unsigned char *) &(w->l[d]) + i);
    }
  for (register int i = 0; i<sizeof(identifier); ++i) {
     hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
     hash ^= *((unsigned char *) &id + i);
  }
  return hash & ((tagWH) (WHTABLESIZE - 1));
}

variable_types:
id
unsigned int

variable_types:
depdim
unsigned char

variable_types: i int

user_defined_types: struct world_tag { struct world_tag *prev; unsigned int l[]; }


match

decompiled_code:
__int64 __fastcall match(unsigned int a1, int a2, unsigned __int8 a3, __int64 a4)
{
unsigned __int8 v5; // r8
_DWORD *v7; // rdx
__int64 result; // rax
__int64 v9; // rax

v5 = a3;
v7 = (char *)rawHeapWH + 4 * a1 * (MAXDIM + 5LL);
result = 0LL;
if ( *v7 == a2 )
{
if ( v5 )
{
v9 = 0LL;
while ( v7[v9 + 5] == *(_DWORD *)(a4 + 4 * v9 + 8) )
{
if ( a3 <= (unsigned __int8)++v9 )
goto LABEL_8;
}
result = 0LL;
}
else
{
LABEL_8:
result = 1LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int a1, int a2, unsigned __int8 a3, __int64 a4)
{
unsigned __int8 v5; // r8
_DWORD *v7; // rdx
__int64 result; // rax
__int64 v9; // rax

v5 = a3;
v7 = (char *)rawHeapWH + 4 * a1 * (MAXDIM + 5LL);
result = 0LL;
if ( *v7 == a2 )
{
if ( v5 )
{
v9 = 0LL;
while ( v7[v9 + 5] == *(_DWORD *)(a4 + 4 * v9 + 8) )
{
if ( a3 <= (unsigned __int8)++v9 )
goto LABEL_8;
}
result = 0LL;
}
else
{
LABEL_8:
result = 1LL;
}
}
return result;
}

original_code:
static _Bool match (tagWH hV, identifier id, dimension depdim, World *w)
{
  if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->id != id)
    return 0;
  for (register dimension d = 0; d < depdim; d++)
    if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d] != w->l[d])
      return 0;
  return 1;
}

canonical_original_code:
static _Bool match(unsigned int hV, unsigned int id, unsigned char depdim, struct world_tag *w)
{
  if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->id != id)
    return 0;
  for (register unsigned char d = 0; d < depdim; d++)
    if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d] != w->l[d])
      return 0;
  return 1;
}

variable_types:
hV
unsigned int


initializeWH

decompiled_code:
int initializeWH()
{
int v0; // ebp
size_t v1; // rbx
__int64 v2; // r13
int v3; // ebp
size_t v4; // r12
unsigned __int64 v5; // rax
unsigned __int64 v6; // rdi
_DWORD *v7; // rdx

if ( tableWH )
free(tableWH);
v0 = WHTABLESIZE;
v1 = 4LL * WHTABLESIZE;
tableWH = malloc(v1);
if ( !tableWH )
{
fwrite("Out of memory: allocating the warehouse table\n", 1uLL, 0x2EuLL, stderr);
exit(1);
}
if ( v0 )
memset(tableWH, 255, v1);
if ( rawHeapWH )
free(rawHeapWH);
v2 = MAXDIM + 5LL;
v3 = WHHEAPSIZE;
v4 = 4 * v2 * WHHEAPSIZE;
v5 = (unsigned __int64)malloc(v4);
rawHeapWH = (void *)v5;
v6 = v5;
if ( !v5 )
{
fwrite("Out of memory: allocating the warehouse heap\n", 1uLL, 0x2DuLL, stderr);
exit(1);
}
v7 = (_DWORD *)(v5 + 12);
LODWORD(v5) = 0;
if ( v3 != 1 )
{
do
{
v5 = (unsigned int)(v5 + 1);
*v7 = v5;
v7 += v2;
}
while ( (_DWORD)v5 != v3 - 1 );
v6 += 4 * v2 * v5;
}
*(_DWORD *)(v6 + 12) = -1;
entriesWH = 0;
freeWH = 0;
hits = 0;
globalAge = 0;
return printf("WH memory: %u bytes\n", v1 + v4);
}

canonical_decompiled_code:
int func2()
{
int v0; // ebp
size_t v1; // rbx
__int64 v2; // r13
int v3; // ebp
size_t v4; // r12
unsigned __int64 v5; // rax
unsigned __int64 v6; // rdi
_DWORD *v7; // rdx

if ( tableWH )
free(tableWH);
v0 = WHTABLESIZE;
v1 = 4LL * WHTABLESIZE;
tableWH = malloc(v1);
if ( !tableWH )
{
fwrite("Out of memory: allocating the warehouse table\n", 1uLL, 0x2EuLL, stderr);
exit(1);
}
if ( v0 )
memset(tableWH, 255, v1);
if ( rawHeapWH )
free(rawHeapWH);
v2 = MAXDIM + 5LL;
v3 = WHHEAPSIZE;
v4 = 4 * v2 * WHHEAPSIZE;
v5 = (unsigned __int64)malloc(v4);
rawHeapWH = (void *)v5;
v6 = v5;
if ( !v5 )
{
fwrite("Out of memory: allocating the warehouse heap\n", 1uLL, 0x2DuLL, stderr);
exit(1);
}
v7 = (_DWORD *)(v5 + 12);
LODWORD(v5) = 0;
if ( v3 != 1 )
{
do
{
v5 = (unsigned int)(v5 + 1);
*v7 = v5;
v7 += v2;
}
while ( (_DWORD)v5 != v3 - 1 );
v6 += 4 * v2 * v5;
}
*(_DWORD *)(v6 + 12) = -1;
entriesWH = 0;
freeWH = 0;
hits = 0;
globalAge = 0;
return printf("WH memory: %u bytes\n", v1 + v4);
}

original_code:
void initializeWH ()
{
  if (tableWH != ((void *)0))
    free(tableWH);
  tableWH = (struct bucketWH *) malloc(WHTABLESIZE * sizeof(struct bucketWH));
  if (tableWH == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the warehouse table\n");
    exit(1);
  }
  for (tagWH i = 0; i < WHTABLESIZE; i++)
    tableWH[i].ptr = ((tagWH) (-1));
  if (rawHeapWH != ((void *)0))
    free(rawHeapWH);
  sizeOfHeapWH = WHHEAPSIZE * (sizeof(struct nodeWH) + MAXDIM * sizeof(list));
  rawHeapWH = malloc(sizeOfHeapWH);
  if (rawHeapWH == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the warehouse heap\n");
    exit(1);
  }
  for (tagWH i = 0; i < WHHEAPSIZE-1; i++)
    ((struct nodeWH *) ((unsigned char *) rawHeapWH + (i) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = i+1;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (WHHEAPSIZE-1) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = ((tagWH) (-1));
  entriesWH = 0;
  freeWH = 0;
  hits = 0;
  globalAge = 0;
  printf("WH memory: %u bytes\n", WHTABLESIZE * sizeof(struct bucketWH)
  + sizeOfHeapWH);
}

canonical_original_code:
void initializeWH()
{
  if (tableWH != ((void *)0))
    free(tableWH);
  tableWH = (struct bucketWH *) malloc(WHTABLESIZE * sizeof(struct bucketWH));
  if (tableWH == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the warehouse table\n");
    exit(1);
  }
  for (unsigned int i = 0; i < WHTABLESIZE; i++)
    tableWH[i].ptr = ((tagWH) (-1));
  if (rawHeapWH != ((void *)0))
    free(rawHeapWH);
  sizeOfHeapWH = WHHEAPSIZE * (sizeof(struct nodeWH) + MAXDIM * sizeof(list));
  rawHeapWH = malloc(sizeOfHeapWH);
  if (rawHeapWH == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the warehouse heap\n");
    exit(1);
  }
  for (unsigned int i = 0; i < WHHEAPSIZE-1; i++)
    ((struct nodeWH *) ((unsigned char *) rawHeapWH + (i) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = i+1;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (WHHEAPSIZE-1) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = ((tagWH) (-1));
  entriesWH = 0;
  freeWH = 0;
  hits = 0;
  globalAge = 0;
  printf("WH memory: %u bytes\n", WHTABLESIZE * sizeof(struct bucketWH)
  + sizeOfHeapWH);
}


getWH

decompiled_code:
__int64 __fastcall getWH(unsigned int a1)
{
return *((unsigned int *)rawHeapWH + a1 * (MAXDIM + 5LL) + 1);
}

canonical_decompiled_code:
__int64 __fastcall func3(unsigned int a1)
{
return *((unsigned int *)rawHeapWH + a1 * (MAXDIM + 5LL) + 1);
}

original_code:
value getWH (tagWH hV)
{
  return ((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val;
}

canonical_original_code:
int getWH(unsigned int hV)
{
  return ((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val;
}


putWH

decompiled_code:
__int64 __fastcall putWH(unsigned int a1, int a2)
{
__int64 result; // rax

result = a1 * (MAXDIM + 5LL);
*((_DWORD *)rawHeapWH + result + 1) = a2;
return result;
}

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

result = a1 * (MAXDIM + 5LL);
*((_DWORD *)rawHeapWH + result + 1) = a2;
return result;
}

original_code:
void putWH (tagWH hV, value val)
{
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val = val;
}

canonical_original_code:
void putWH(unsigned int hV, int val)
{
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val = val;
}

variable_types: val int


gcollectWH

decompiled_code:
__int64 gcollectWH()
{
int v0; // eax
unsigned int v1; // ebp
unsigned int *v2; // r10
char *v3; // r9
unsigned int *v4; // rbx
__int64 v5; // r8
unsigned int v6; // er11
unsigned int v7; // ecx
unsigned int *i; // rsi
char *v9; // rax
unsigned int v10; // edx
__int64 result; // rax

v0 = globalAge;
v1 = (int)((double)(globalAge - hits) * 0.5);
if ( WHTABLESIZE )
{
v2 = (unsigned int *)tableWH;
v3 = (char *)rawHeapWH;
v4 = (unsigned int *)((char *)tableWH + 4 * (unsigned int)(WHTABLESIZE - 1) + 4);
v5 = 4LL * MAXDIM + 20;
v6 = (int)((double)WHHEAPSIZE * 0.0);
do
{
if ( v6 >= entriesWH )
break;
v7 = *v2;
for ( i = v2; *i != -1; v7 = *i )
{
while ( 1 )
{
v9 = &v3[v5 * v7];
v10 = *((_DWORD *)v9 + 2);
if ( v10 >= v1 || *((_DWORD *)v9 + 1) == 0x80000000 )
break;
*i = *((_DWORD *)v9 + 3);
--entriesWH;
*((_DWORD *)v9 + 3) = freeWH;
freeWH = v7;
v7 = *i;
if ( *i == -1 )
goto LABEL_10;
}
*((_DWORD *)v9 + 2) = v10 - v1;
i = (unsigned int *)&v3[v5 * *i + 12];
}
LABEL_10:
++v2;
}
while ( v4 != v2 );
v0 = globalAge;
}
hits = 0;
result = v0 - v1;
globalAge = result;
return result;
}

canonical_decompiled_code:
__int64 func5()
{
int v0; // eax
unsigned int v1; // ebp
unsigned int *v2; // r10
char *v3; // r9
unsigned int *v4; // rbx
__int64 v5; // r8
unsigned int v6; // er11
unsigned int v7; // ecx
unsigned int *i; // rsi
char *v9; // rax
unsigned int v10; // edx
__int64 result; // rax

v0 = globalAge;
v1 = (int)((double)(globalAge - hits) * 0.5);
if ( WHTABLESIZE )
{
v2 = (unsigned int *)tableWH;
v3 = (char *)rawHeapWH;
v4 = (unsigned int *)((char *)tableWH + 4 * (unsigned int)(WHTABLESIZE - 1) + 4);
v5 = 4LL * MAXDIM + 20;
v6 = (int)((double)WHHEAPSIZE * 0.0);
do
{
if ( v6 >= entriesWH )
break;
v7 = *v2;
for ( i = v2; *i != -1; v7 = *i )
{
while ( 1 )
{
v9 = &v3[v5 * v7];
v10 = *((_DWORD *)v9 + 2);
if ( v10 >= v1 || *((_DWORD *)v9 + 1) == 0x80000000 )
break;
*i = *((_DWORD *)v9 + 3);
--entriesWH;
*((_DWORD *)v9 + 3) = freeWH;
freeWH = v7;
v7 = *i;
if ( *i == -1 )
goto LABEL_10;
}
*((_DWORD *)v9 + 2) = v10 - v1;
i = (unsigned int *)&v3[v5 * *i + 12];
}
LABEL_10:
++v2;
}
while ( v4 != v2 );
v0 = globalAge;
}
hits = 0;
result = v0 - v1;
globalAge = result;
return result;
}

original_code:
void gcollectWH ()
{
  tagAge ageLimit = (tagAge) ((globalAge - hits) * 0.5);
  for (tagWH i = 0; i < WHTABLESIZE && entriesWH > ((tagWH) (WHHEAPSIZE * 0.0)); i++)
    for (tagWH * ptr = &(tableWH[i].ptr); *ptr != ((tagWH) (-1)); )
      if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age < ageLimit && ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val != ((value) 1 << (8 * sizeof(value) - 1))) {
 tagWH prev = *ptr;
 *ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
 ((struct nodeWH *) ((unsigned char *) rawHeapWH + (prev) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = freeWH;
 freeWH = prev;
 entriesWH--;
      }
      else {
 ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age -= ageLimit;
 ptr = &(((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr);
      }
  globalAge -= ageLimit;
  hits = 0;
}

canonical_original_code:
void gcollectWH()
{
  unsigned int ageLimit = (tagAge) ((globalAge - hits) * 0.5);
  for (unsigned int i = 0; i < WHTABLESIZE && entriesWH > ((tagWH) (WHHEAPSIZE * 0.0)); i++)
    for (unsigned int *ptr = &(tableWH[i].ptr); *ptr != ((tagWH) (-1)); )
      if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age < ageLimit && ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val != ((int) 1 << (8 * sizeof(value) - 1))) {
 unsigned int prev = *ptr;
 *ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
 ((struct nodeWH *) ((unsigned char *) rawHeapWH + (prev) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = freeWH;
 freeWH = prev;
 entriesWH--;
      }
      else {
 ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age -= ageLimit;
 ptr = &(((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr);
      }
  globalAge -= ageLimit;
  hits = 0;
}

variable_types:
ageLimit
unsigned int


seekWH

decompiled_code:
__int64 __fastcall seekWH(int a1, char a2, __int64 a3, _DWORD *a4)
{
unsigned __int8 v5; // r12
unsigned int v7; // eax
unsigned __int8 v8; // r11
char *v9; // r14
unsigned int *v10; // rax
__int64 v11; // r10
unsigned int v12; // er15
__int64 result; // rax
char *v14; // rdx
int v15; // ecx
int v16; // esi
char *v17; // rcx
__int64 v18; // rax
int v19; // eax
int v20; // eax
int *v22; // [rsp+8h] [rbp-40h]

v5 = a2;
if ( (int)((double)WHHEAPSIZE * 0.98) <= (unsigned int)entriesWH )
{
gcollectWH();
if ( WHHEAPSIZE <= (unsigned int)entriesWH )
{
fwrite("FATAL ERROR: Out of heap space for the warehouse\n", 1uLL, 0x31uLL, stderr);
exit(1);
}
}
v7 = hashWH(a1, a2, a3);
v9 = (char *)rawHeapWH;
v10 = (unsigned int *)((char *)tableWH + 4 * v7);
v11 = MAXDIM + 5LL;
v12 = *v10;
v22 = (int *)v10;
if ( *v10 == -1 )
{
LABEL_7:
++entriesWH;
v16 = freeWH;
v17 = &v9[4 * (unsigned int)freeWH * v11];
freeWH = *((_DWORD *)v17 + 3);
v18 = 0LL;
*(_DWORD *)v17 = a1;
if ( a2 )
{
do
{
*(_DWORD *)&v17[4 * v18 + 20] = *(_DWORD *)(a3 + 4 * v18 + 8);
++v18;
}
while ( v5 > (unsigned __int8)v18 );
}
v19 = globalAge + 1;
*((_DWORD *)v17 + 2) = globalAge + 1;
globalAge = v19;
v20 = *v22;
*((_DWORD *)v17 + 1) = 0x80000000;
*((_DWORD *)v17 + 3) = v20;
v17[16] = a2;
*v22 = v16;
*a4 = v16;
result = 0LL;
}
else
{
while ( 1 )
{
result = match(v12, a1, v8, a3);
v14 = &v9[4 * v11 * v12];
if ( (_BYTE)result )
break;
v12 = *((_DWORD *)v14 + 3);
if ( v12 == -1 )
goto LABEL_7;
}
++hits;
v15 = globalAge + 1;
*((_DWORD *)v14 + 2) = globalAge + 1;
globalAge = v15;
*a4 = v12;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(int a1, char a2, __int64 a3, _DWORD *a4)
{
unsigned __int8 v5; // r12
unsigned int v7; // eax
unsigned __int8 v8; // r11
char *v9; // r14
unsigned int *v10; // rax
__int64 v11; // r10
unsigned int v12; // er15
__int64 result; // rax
char *v14; // rdx
int v15; // ecx
int v16; // esi
char *v17; // rcx
__int64 v18; // rax
int v19; // eax
int v20; // eax
int *v22; // [rsp+8h] [rbp-40h]

v5 = a2;
if ( (int)((double)WHHEAPSIZE * 0.98) <= (unsigned int)entriesWH )
{
func5();
if ( WHHEAPSIZE <= (unsigned int)entriesWH )
{
fwrite("FATAL ERROR: Out of heap space for the warehouse\n", 1uLL, 0x31uLL, stderr);
exit(1);
}
}
v7 = func0(a1, a2, a3);
v9 = (char *)rawHeapWH;
v10 = (unsigned int *)((char *)tableWH + 4 * v7);
v11 = MAXDIM + 5LL;
v12 = *v10;
v22 = (int *)v10;
if ( *v10 == -1 )
{
LABEL_7:
++entriesWH;
v16 = freeWH;
v17 = &v9[4 * (unsigned int)freeWH * v11];
freeWH = *((_DWORD *)v17 + 3);
v18 = 0LL;
*(_DWORD *)v17 = a1;
if ( a2 )
{
do
{
*(_DWORD *)&v17[4 * v18 + 20] = *(_DWORD *)(a3 + 4 * v18 + 8);
++v18;
}
while ( v5 > (unsigned __int8)v18 );
}
v19 = globalAge + 1;
*((_DWORD *)v17 + 2) = globalAge + 1;
globalAge = v19;
v20 = *v22;
*((_DWORD *)v17 + 1) = 0x80000000;
*((_DWORD *)v17 + 3) = v20;
v17[16] = a2;
*v22 = v16;
*a4 = v16;
result = 0LL;
}
else
{
while ( 1 )
{
result = func1(v12, a1, v8, a3);
v14 = &v9[4 * v11 * v12];
if ( (_BYTE)result )
break;
v12 = *((_DWORD *)v14 + 3);
if ( v12 == -1 )
goto LABEL_7;
}
++hits;
v15 = globalAge + 1;
*((_DWORD *)v14 + 2) = globalAge + 1;
globalAge = v15;
*a4 = v12;
}
return result;
}

original_code:
_Bool seekWH (identifier id, dimension depdim, World *w, tagWH *hV)
{
  if (entriesWH >= ((tagWH) (WHHEAPSIZE * 0.98))) {
    gcollectWH();
    if (entriesWH >= WHHEAPSIZE) {
      fprintf(stderr, "FATAL ERROR: Out of heap space for the warehouse\n");
      exit(1);
    }
  }
  tagWH hashval = hashWH(id, depdim, w);
  tagWH ptr;
  for (ptr = tableWH[hashval].ptr; ptr != ((tagWH) (-1)); ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr)
    if (match(ptr, id, depdim, w)) {
      hits++;
      ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age = ++globalAge;
      *hV = ptr;
      return 1;
    }
    else {
      ;
    }
  ptr = freeWH;
  freeWH = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (freeWH) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
  entriesWH++;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->id = id;
  for (register dimension d = 0; d < depdim; d++)
    ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d] = w->l[d];
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age = ++globalAge;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = tableWH[hashval].ptr;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val = ((value) 1 << (8 * sizeof(value) - 1));
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->depDim = depdim;
  tableWH[hashval].ptr = ptr;
  *hV=ptr;
  return 0;
}

canonical_original_code:
_Bool seekWH(unsigned int id, unsigned char depdim, struct world_tag *w, unsigned int *hV)
{
  if (entriesWH >= ((tagWH) (WHHEAPSIZE * 0.98))) {
    gcollectWH();
    if (entriesWH >= WHHEAPSIZE) {
      fprintf(stderr, "FATAL ERROR: Out of heap space for the warehouse\n");
      exit(1);
    }
  }
  unsigned int hashval = hashWH(id, depdim, w);
  unsigned int ptr;
  for (ptr = tableWH[hashval].ptr; ptr != ((tagWH) (-1)); ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr)
    if (match(ptr, id, depdim, w)) {
      hits++;
      ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age = ++globalAge;
      *hV = ptr;
      return 1;
    }
    else {
      ;
    }
  ptr = freeWH;
  freeWH = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (freeWH) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
  entriesWH++;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->id = id;
  for (register unsigned char d = 0; d < depdim; d++)
    ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d] = w->l[d];
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age = ++globalAge;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = tableWH[hashval].ptr;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val = ((int) 1 << (8 * sizeof(value) - 1));
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->depDim = depdim;
  tableWH[hashval].ptr = ptr;
  *hV=ptr;
  return 0;
}

variable_types:
hV
unsigned int *


statsWH

decompiled_code:
int statsWH()
{
return printf(
"\n\nWH heapsize:\t%u\nWH freerecs:\t%.2lf%%\n\n",
WHHEAPSIZE,
(double)(WHHEAPSIZE - entriesWH) / (double)WHHEAPSIZE * 100.0);
}

canonical_decompiled_code:
int func7()
{
return printf(
"\n\nWH heapsize:\t%u\nWH freerecs:\t%.2lf%%\n\n",
WHHEAPSIZE,
(double)(WHHEAPSIZE - entriesWH) / (double)WHHEAPSIZE * 100.0);
}

original_code:
void statsWH ()
{
  printf("\n\nWH heapsize:\t%u\nWH freerecs:\t%.2lf%%\n\n",
  WHHEAPSIZE, ((double) (WHHEAPSIZE - entriesWH) / WHHEAPSIZE) * 100);
}

canonical_original_code:
void statsWH()
{
  printf("\n\nWH heapsize:\t%u\nWH freerecs:\t%.2lf%%\n\n",
  WHHEAPSIZE, ((double) (WHHEAPSIZE - entriesWH) / WHHEAPSIZE) * 100);
}


printWorld

decompiled_code:
__int64 __fastcall printWorld(__int64 a1)
{
__int64 result; // rax
unsigned int *v2; // rbx
__int64 v3; // rbp
__int64 v4; // rdi

result = MAXDIM;
if ( MAXDIM )
{
v2 = (unsigned int *)(a1 + 8);
v3 = a1 + 4LL * (unsigned __int8)(MAXDIM - 1) + 12;
do
{
v4 = *v2++;
result = printList(v4);
}
while ( v2 != (unsigned int *)v3 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
__int64 result; // rax
unsigned int *v2; // rbx
__int64 v3; // rbp
__int64 v4; // rdi

result = MAXDIM;
if ( MAXDIM )
{
v2 = (unsigned int *)(a1 + 8);
v3 = a1 + 4LL * (unsigned __int8)(MAXDIM - 1) + 12;
do
{
v4 = *v2++;
result = printList(v4);
}
while ( v2 != (unsigned int *)v3 );
}
return result;
}

original_code:
void printWorld (World *w)
{
   for (register dimension d = 0; d < MAXDIM; d++)
      printList(w->l[d]);
}

canonical_original_code:
void printWorld(struct world_tag *w)
{
   for (register unsigned char d = 0; d < MAXDIM; d++)
      printList(w->l[d]);
}


repo: aconbere/c-PID

decompiled_code:
_BOOL8 __fastcall PID_should_compute(__int64 a1, double a2)
{
double v2; // xmm1_8
__int64 v4; // rdx

getCurrentMilliseconds();
if ( *(__int64 *)a1 < 0 )
{
v4 = *(_QWORD *)a1 & 1LL | (*(_QWORD *)a1 >> 1);
v2 = (double)(int)v4 + (double)(int)v4;
}
else
{
v2 = (double)(int)*(_QWORD *)a1;
}
return *(double *)(a1 + 48) <= a2 - v2;
}

canonical_decompiled_code:
_BOOL8 __fastcall func0(__int64 a1, double a2)
{
double v2; // xmm1_8
__int64 v4; // rdx

getCurrentMilliseconds();
if ( *(__int64 *)a1 < 0 )
{
v4 = *(_QWORD *)a1 & 1LL | (*(_QWORD *)a1 >> 1);
v2 = (double)(int)v4 + (double)(int)v4;
}
else
{
v2 = (double)(int)*(_QWORD *)a1;
}
return *(double *)(a1 + 48) <= a2 - v2;
}

original_code:
bool_t PID_should_compute(PID *pid) {
  if (getCurrentMilliseconds() - pid->last_computed < pid->sample_time) {
    return false_t;
  }
  return true_t;
}

canonical_original_code:
int PID_should_compute(struct PID *pid) {
  if (getCurrentMilliseconds() - pid->last_computed < pid->sample_time) {
    return false_t;
  }
  return true_t;
}

variable_types: struct PID { unsigned long last_computed; double setpoint; double out_min; double out_max; double current_integral_value; double last_process_value; double sample_time; double Kp; double Ki; double Kd; } *


decompiled_code:
double __fastcall PID_clamp_output(__int64 a1, double a2)
{
double result; // xmm0_8

result = *(double *)(a1 + 24);
if ( a2 <= result )
result = fmax(*(double *)(a1 + 16), a2);
return result;
}

canonical_decompiled_code:
double __fastcall func1(__int64 a1, double a2)
{
double result; // xmm0_8

result = *(double *)(a1 + 24);
if ( a2 <= result )
result = fmax(*(double *)(a1 + 16), a2);
return result;
}

original_code:
double PID_clamp_output(PID *pid, double output) {
  if (output > pid->out_max) {
    return pid->out_max;
  } else if (output < pid->out_min) {
    return pid->out_min;
  } else {
    return output;
  }
}

canonical_original_code:
double PID_clamp_output(struct PID *pid, double output) {
  if (output > pid->out_max) {
    return pid->out_max;
  } else if (output < pid->out_min) {
    return pid->out_min;
  } else {
    return output;
  }
}

variable_types: output double

return_type: double

user_defined_types: struct PID { unsigned long last_computed; double setpoint; double out_min; double out_max; double current_integral_value; double last_process_value; double sample_time; double Kp; double Ki; double Kd; }


decompiled_code:
__int64 __fastcall PID_create(double a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8)
{
double *v10; // rax
__int64 v11; // r12
int *v13; // rax
const char *v14; // r8
int *v15; // rbx

v10 = (double *)calloc(1uLL, 0x50uLL);
v11 = (__int64)v10;
if ( v10 )
{
v10[1] = a2;
v10[6] = a3;
v10[3] = a5;
v10[2] = a4;
v10[7] = a6;
v10[8] = a7;
v10[9] = a8;
v10[4] = PID_clamp_output((__int64)v10, 0.0);
*(double *)(v11 + 40) = PID_clamp_output(v11, a1);
*(_QWORD *)(v11 + 48) = LC5;
}
else
{
v13 = _errno_location();
v14 = "None";
v15 = v13;
if ( *v13 )
v14 = "ERR:";
fprintf(stderr, "[ERROR] (%s:%d: errno: %s) Out of memory.\n", "src/pid.c", 25LL, v14);
*v15 = 0;
}
return v11;
}

original_code:
PID *PID_create(
    double current_input,
    double setpoint,
    double sample_time,
    double out_min,
    double out_max,
    double Kp,
    double Ki,
    double Kd
) {
  PID *pid = (PID *)calloc(1, sizeof(PID));
  if(!((pid))) { fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " "Out of memory." "\n", "src/pid.c", 25, ((*__errno_location ()) == 0 ? "None" : "ERR:")); (*__errno_location ())=0; goto error; };
  pid->setpoint = setpoint;
  pid->sample_time = sample_time;
  pid->out_max = out_max;
  pid->out_min = out_min;
  pid->Kp = Kp;
  pid->Ki = Ki;
  pid->Kd = Kd;
  pid->current_integral_value = PID_clamp_output(pid, 0);
  pid->last_process_value = PID_clamp_output(pid, current_input);
  pid->sample_time = 300;
  return pid;
error:
  return ((void *)0);
}

canonical_original_code:
struct PID *PID_create(double current_input, double setpoint, double sample_time, double out_min, double out_max, double Kp, double Ki, double Kd) {
  struct PID *pid = (PID *)calloc(1, sizeof(PID));
  if(!((pid))) { fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " "Out of memory." "\n", "src/pid.c", 25, ((*__errno_location ()) == 0 ? "None" : "ERR:")); (*__errno_location ())=0; goto error; };
  pid->setpoint = setpoint;
  pid->sample_time = sample_time;
  pid->out_max = out_max;
  pid->out_min = out_min;
  pid->Kp = Kp;
  pid->Ki = Ki;
  pid->Kd = Kd;
  pid->current_integral_value = PID_clamp_output(pid, 0);
  pid->last_process_value = PID_clamp_output(pid, current_input);
  pid->sample_time = 300;
  return pid;
error:
  return ((void *)0);
}

variable_types: setpoint double

variable_types: Kp double

variable_types: Ki double

variable_types: Kd double

return_type: struct PID { unsigned long last_computed; double setpoint; double out_min; double out_max; double current_integral_value; double last_process_value; double sample_time; double Kp; double Ki; double Kd; } *


decompiled_code:
void __fastcall PID_tune(double *a1, double a2, double a3, double a4)
{
double v5; // xmm0_8

v5 = a1[6] / 1000.0;
a1[7] = a2;
a1[8] = a3 * v5;
a1[9] = a4 / v5;
}

canonical_decompiled_code:
void __fastcall func3(double *a1, double a2, double a3, double a4)
{
double v5; // xmm0_8

v5 = a1[6] / 1000.0;
a1[7] = a2;
a1[8] = a3 * v5;
a1[9] = a4 / v5;
}

original_code:
void PID_tune(PID *pid, double Kp, double Ki, double Kd) {
  double sample_time = (double)(pid->sample_time / 1000);
  pid->Kp = Kp;
  pid->Ki = Ki * sample_time;
  pid->Kd = Kd / sample_time;
}

canonical_original_code:
void PID_tune(struct PID *pid, double Kp, double Ki, double Kd) {
  double sample_time = (double)(pid->sample_time / 1000);
  pid->Kp = Kp;
  pid->Ki = Ki * sample_time;
  pid->Kd = Kd / sample_time;
}


decompiled_code:
__int64 __fastcall PID_next(__int64 a1, double a2)
{
double v2; // xmm0_8
double v3; // xmm1_8
double v4; // xmm0_8
__int64 result; // rax
double v7; // [rsp+8h] [rbp-10h]

v7 = *(double *)(a1 + 8) - a2;
v2 = PID_clamp_output(a1, v7 * *(double *)(a1 + 64) + *(double *)(a1 + 32));
v3 = v7 * *(double *)(a1 + 56);
*(double *)(a1 + 32) = v2;
PID_clamp_output(a1, v3 + v2 - (*(double *)(a1 + 40) - a2) * *(double *)(a1 + 72));
*(double *)(a1 + 40) = a2;
v4 = getCurrentMilliseconds();
if ( v4 >= 9.223372036854776e18 )
{
result = (unsigned int)(int)(v4 - 9.223372036854776e18);
*(_QWORD *)a1 = result;
*(_QWORD *)a1 ^= 0x8000000000000000LL;
}
else
{
result = (unsigned int)(int)v4;
*(_QWORD *)a1 = result;
}
return result;
}

original_code:
double PID_next(PID *pid, double process_value) {
  double error = pid->setpoint - process_value;
  pid->current_integral_value = PID_clamp_output( pid,
    pid->current_integral_value + (pid->Ki * error)
  );
  double input_derivative = pid->last_process_value - process_value;
  double output = PID_clamp_output( pid,
    (pid->Kp * error) + pid->current_integral_value - (pid->Kd * input_derivative)
  );
  pid->last_process_value = process_value;
  pid->last_computed = getCurrentMilliseconds();
  return output;
}

canonical_original_code:
double PID_next(struct PID *pid, double process_value) {
  double error = pid->setpoint - process_value;
  pid->current_integral_value = PID_clamp_output( pid,
    pid->current_integral_value + (pid->Ki * error)
  );
  double input_derivative = pid->last_process_value - process_value;
  double output = PID_clamp_output( pid,
    (pid->Kp * error) + pid->current_integral_value - (pid->Kd * input_derivative)
  );
  pid->last_process_value = process_value;
  pid->last_computed = getCurrentMilliseconds();
  return output;
}

variable_types: error double


repo: acourt/OS-Assignments

decompiled_code:
int *load_FAT_from_disk()
{
int *result; // rax
_BYTE savedregs[4104]; // [rsp+0h] [rbp+0h] BYREF

memset(savedregs, 0, 0x1000uLL);
read_blocks(1LL, 1LL, savedregs);
result = &FAT;
qmemcpy(&FAT, savedregs, 0x7E8uLL);
return result;
}

canonical_decompiled_code:
int *func0()
{
int *result; // rax
_BYTE savedregs[4104]; // [rsp+0h] [rbp+0h] BYREF

memset(savedregs, 0, 0x1000uLL);
read_blocks(1LL, 1LL, savedregs);
result = &FAT;
qmemcpy(&FAT, savedregs, 0x7E8uLL);
return result;
}

original_code:
void load_FAT_from_disk()
{
 char disk_FAT[4096];
 memset(disk_FAT, 0, 4096);
 read_blocks(1, 1, disk_FAT);
 memcpy(FAT, disk_FAT, (256 - 3)*sizeof(FAT_entry));
}


decompiled_code:
__int64 write_FAT_to_disk()
{
_BYTE v1[4096]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, sizeof(v1));
qmemcpy(v1, &FAT, 0x7E8uLL);
return write_blocks(1LL, 1LL);
}

canonical_decompiled_code:
__int64 func1()
{
_BYTE v1[4096]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, sizeof(v1));
qmemcpy(v1, &FAT, 0x7E8uLL);
return write_blocks(1LL, 1LL);
}

original_code:
void write_FAT_to_disk()
{
 char disk_FAT[4096];
 memset(disk_FAT, 0, 4096);
 memcpy(disk_FAT, FAT, (256 - 3)*sizeof(FAT_entry));
 write_blocks(1, 1, disk_FAT);
}


decompiled_code:
__int64 load_directory_from_disk()
{
__int64 result; // rax
int v1[1026]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, 0x1000uLL);
read_blocks(0LL, 1LL, v1);
file_count = v1[0];
qmemcpy(&directory, &v1[1], 0xFF8uLL);
result = (unsigned int)v1[1023];
*((_DWORD *)&directory + 1022) = v1[1023];
return result;
}

canonical_decompiled_code:
__int64 func2()
{
__int64 result; // rax
int v1[1026]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, 0x1000uLL);
read_blocks(0LL, 1LL, v1);
file_count = v1[0];
qmemcpy(&directory, &v1[1], 0xFF8uLL);
result = (unsigned int)v1[1023];
*((_DWORD *)&directory + 1022) = v1[1023];
return result;
}

original_code:
void load_directory_from_disk()
{
 char disk_directory[4096];
 memset(disk_directory,0, 4096);
 read_blocks(0, 1, disk_directory);
 memcpy(&file_count, disk_directory, sizeof(int));
 memcpy(directory, disk_directory+4, 93*sizeof(dir_entry));
}


decompiled_code:
__int64 write_directory_to_disk()
{
return write_blocks(0LL, 1LL);
}

canonical_decompiled_code:
__int64 func3()
{
return write_blocks(0LL, 1LL);
}

original_code:
void write_directory_to_disk()
{
 char disk_directory[4096];
 memset(disk_directory,0, 4096);
 memcpy(disk_directory, &file_count, sizeof(int));
 memcpy(disk_directory+4, directory, 93*sizeof(dir_entry));
 write_blocks(0, 1, directory);
}


decompiled_code:
__int64 load_free_list_from_disk()
{
__int64 result; // rax
_BYTE savedregs[4104]; // [rsp+0h] [rbp+0h] BYREF

memset(savedregs, 0, 0x1000uLL);
read_blocks(2LL, 1LL, savedregs);
qmemcpy(&free_list, savedregs, 0xF8uLL);
*(&free_list + 62) = *(_DWORD *)&savedregs[248];
result = savedregs[252];
*((_BYTE *)&free_list + 252) = savedregs[252];
return result;
}

canonical_decompiled_code:
__int64 func4()
{
__int64 result; // rax
_BYTE savedregs[4104]; // [rsp+0h] [rbp+0h] BYREF

memset(savedregs, 0, 0x1000uLL);
read_blocks(2LL, 1LL, savedregs);
qmemcpy(&free_list, savedregs, 0xF8uLL);
*(&free_list + 62) = *(_DWORD *)&savedregs[248];
result = savedregs[252];
*((_BYTE *)&free_list + 252) = savedregs[252];
return result;
}

original_code:
void load_free_list_from_disk()
{
 char disk_free_list[4096];
 memset(disk_free_list,0, 4096);
 read_blocks(2, 1, disk_free_list);
 memcpy(free_list, disk_free_list, 256 - 3);
}


decompiled_code:
__int64 write_free_list_to_disk()
{
_BYTE v1[4096]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, sizeof(v1));
qmemcpy(v1, &free_list, 0xFDuLL);
return write_blocks(2LL, 1LL);
}

canonical_decompiled_code:
__int64 func5()
{
_BYTE v1[4096]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, sizeof(v1));
qmemcpy(v1, &free_list, 0xFDuLL);
return write_blocks(2LL, 1LL);
}

original_code:
void write_free_list_to_disk()
{
 char disk_free_list[4096];
 memset(disk_free_list,0, 4096);
 memcpy(disk_free_list, free_list, 256 - 3);
 write_blocks(2, 1, disk_free_list);
}


decompiled_code:
_BOOL8 __fastcall dir_entry_is_null(int a1)
{
return *((_BYTE *)&directory + 44 * a1) == 0;
}

canonical_decompiled_code:
_BOOL8 __fastcall func6(int a1)
{
return *((_BYTE *)&directory + 44 * a1) == 0;
}

original_code:
int dir_entry_is_null(int entry)
{
 return directory[entry].fname[0] == '\0';
}

variable_types: entry int


decompiled_code:
__int64 get_current_time()
{
time_t timer; // [rsp+8h] [rbp-10h] BYREF

time(&timer);
return (unsigned int)timer;
}

canonical_decompiled_code:
__int64 func7()
{
time_t timer; // [rsp+8h] [rbp-10h] BYREF

time(&timer);
return (unsigned int)timer;
}

original_code:
int get_current_time()
{
 time_t current_time;
 time(&current_time);
 return (int)current_time;
}

canonical_original_code:
int get_current_time()
{
 long current_time;
 time(&current_time);
 return (int)current_time;
}


decompiled_code:
__int64 get_free_block()
{
__int64 i; // rax
unsigned int v1; // er8

for ( i = 0LL; i != 253; ++i )
{
v1 = i;
if ( free_list[i] )
{
free_list[(int)i] = 0;
return v1;
}
}
return (unsigned int)-1;
}

canonical_decompiled_code:
__int64 func8()
{
__int64 i; // rax
unsigned int v1; // er8

for ( i = 0LL; i != 253; ++i )
{
v1 = i;
if ( free_list[i] )
{
free_list[(int)i] = 0;
return v1;
}
}
return (unsigned int)-1;
}

original_code:
int get_free_block()
{
 int i=0, found_free_block = 0, free_block_index = -1;
 for (i=0; i < 256 -3 && !found_free_block; i++) {
  if (free_list[i]) {
   free_list[i] = 0;
   found_free_block = 1;
   free_block_index = i;
  }
 }
 return free_block_index;
}

canonical_original_code:
int get_free_block()
{
 int i = 0; int found_free_block = 0; int free_block_index = -1;
 for (i=0; i < 256 -3 && !found_free_block; i++) {
  if (free_list[i]) {
   free_list[i] = 0;
   found_free_block = 1;
   free_block_index = i;
  }
 }
 return free_block_index;
}


decompiled_code:
__int64 get_free_dir_index()
{
int v0; // er8
unsigned int v1; // er8

v0 = 0;
while ( !dir_entry_is_null(v0) )
{
v0 = v1 + 1;
if ( v0 == 93 )
return (unsigned int)-1;
}
return v1;
}

canonical_decompiled_code:
__int64 func9()
{
int v0; // er8
unsigned int v1; // er8

v0 = 0;
while ( !func6(v0) )
{
v0 = v1 + 1;
if ( v0 == 93 )
return (unsigned int)-1;
}
return v1;
}

original_code:
int get_free_dir_index()
{
 int i, index = -1, found_free_index = 0;
 for ( i=0; i < 93 && !found_free_index; i++) {
  if (dir_entry_is_null(i)) {
   found_free_index = 1;
   index = i;
  }
 }
 return index;
}

canonical_original_code:
int get_free_dir_index()
{
 int i; int index = -1; int found_free_index = 0;
 for ( i=0; i < 93 && !found_free_index; i++) {
  if (dir_entry_is_null(i)) {
   found_free_index = 1;
   index = i;
  }
 }
 return index;
}

variable_types: index int


mksfs

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

if ( a1 )
{
memset(&FAT, 0, 0x7E8uLL);
memset(free_list, 1u, 0x3F0uLL);
free_list[252] = 16843009;
memset(&directory, 0, 0xFF8uLL);
*((_DWORD *)&directory + 1022) = 0;
init_fresh_disk("DISK_FILE.txt", 4096LL, 256LL);
}
else
{
init_disk("DISK_FILE.txt", 4096LL, 256LL);
load_FAT_from_disk();
load_directory_from_disk();
load_free_list_from_disk();
}
result = -1LL;
memset(file_descriptors, 0xFFu, 0x740uLL);
file_descriptors[464] = -1;
return result;
}

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

if ( a1 )
{
memset(&FAT, 0, 0x7E8uLL);
memset(free_list, 1u, 0x3F0uLL);
free_list[252] = 16843009;
memset(&directory, 0, 0xFF8uLL);
*((_DWORD *)&directory + 1022) = 0;
init_fresh_disk("DISK_FILE.txt", 4096LL, 256LL);
}
else
{
init_disk("DISK_FILE.txt", 4096LL, 256LL);
func0();
func2();
func4();
}
result = -1LL;
memset(file_descriptors, 0xFFu, 0x740uLL);
file_descriptors[464] = -1;
return result;
}

original_code:
void mksfs(int fresh)
{
 if (fresh) {
  memset(FAT,0, sizeof(FAT_entry)*(256 -3));
  memset(free_list,1, sizeof(int)*(256 -3));
  memset(directory, 0, sizeof(dir_entry)*93);
  init_fresh_disk("DISK_FILE.txt", 4096, 256);
 }
 else
 {
  init_disk("DISK_FILE.txt", 4096, 256);
  load_FAT_from_disk();
  load_directory_from_disk();
  load_free_list_from_disk();
 }
 memset(file_descriptors, -1, sizeof(fd_entry)*93);
}

variable_types: fresh int


decompiled_code:
int sfs_ls()
{
const time_t *v0; // rbp
int v1; // ebx
int result; // eax
__int64 v3; // rdx
const char *v4; // rsi

v0 = (const time_t *)(unsigned int)((_DWORD)&directory + 36);
v1 = 0;
do
{
while ( 1 )
{
result = dir_entry_is_null(v1);
if ( !result )
break;
++v1;
v0 = (const time_t *)((char *)v0 + 44);
if ( v1 == 93 )
return result;
}
++v1;
ctime(v0);
v3 = *((unsigned int *)v0 - 1);
v4 = (char *)v0 - 36;
v0 = (const time_t *)((char *)v0 + 44);
result = printf("Name: %s\tSize: %d\t\n", v4, v3);
}
while ( v1 != 93 );
return result;
}

canonical_decompiled_code:
int func11()
{
const time_t *v0; // rbp
int v1; // ebx
int result; // eax
__int64 v3; // rdx
const char *v4; // rsi

v0 = (const time_t *)(unsigned int)((_DWORD)&directory + 36);
v1 = 0;
do
{
while ( 1 )
{
result = func6(v1);
if ( !result )
break;
++v1;
v0 = (const time_t *)((char *)v0 + 44);
if ( v1 == 93 )
return result;
}
++v1;
ctime(v0);
v3 = *((unsigned int *)v0 - 1);
v4 = (char *)v0 - 36;
v0 = (const time_t *)((char *)v0 + 44);
result = printf("Name: %s\tSize: %d\t\n", v4, v3);
}
while ( v1 != 93 );
return result;
}

original_code:
void sfs_ls()
{
 int i=0;
 for (i=0; i < 93; i++) {
  if(!dir_entry_is_null(i))
  {
   char* time = ctime((time_t*)&(directory[i].time));
   printf("Name: %s\tSize: %d\t\n", directory[i].fname, directory[i].size);
  }
 }
}

canonical_original_code:
void sfs_ls()
{
 int i = 0;
 for (i=0; i < 93; i++) {
  if(!dir_entry_is_null(i))
  {
   char *time = ctime((time_t*)&(directory[i].time));
   printf("Name: %s\tSize: %d\t\n", directory[i].fname, directory[i].size);
  }
 }
}

variable_types:
time
char *


decompiled_code:
__int64 __fastcall get_block_count(int a1)
{
unsigned int v1; // er8
__int64 i; // rax

v1 = 0;
for ( i = FAT[2 * file_descriptors[5 * a1] + 1]; (_DWORD)i != -1; ++v1 )
LODWORD(i) = FAT[2 * i + 1];
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func12(int a1)
{
unsigned int v1; // er8
__int64 i; // rax

v1 = 0;
for ( i = FAT[2 * file_descriptors[5 * a1] + 1]; (_DWORD)i != -1; ++v1 )
LODWORD(i) = FAT[2 * i + 1];
return v1;
}

original_code:
int get_block_count(int dir_index)
{
 int block_count=0;
 int next_FAT_index = file_descriptors[dir_index].root;
 while (FAT[next_FAT_index].next != -1) {
  next_FAT_index = FAT[next_FAT_index].next;
  block_count++;
 }
 return block_count;
}

canonical_original_code:
int get_block_count(int dir_index)
{
 int block_count = 0;
 int next_FAT_index = file_descriptors[dir_index].root;
 while (FAT[next_FAT_index].next != -1) {
  next_FAT_index = FAT[next_FAT_index].next;
  block_count++;
 }
 return block_count;
}


decompiled_code:
__int64 __fastcall create_file_in_mem(__int64 a1, int *a2)
{
int v2; // eax
__int64 v3; // rdx
__int64 v4; // rcx
__int64 v5; // r8
unsigned int v6; // er12
int v7; // eax
const char *v8; // r9
int v9; // ebx

v2 = get_free_block();
v6 = v2;
if ( v2 == -1 )
{
puts("Error: No more free blocks");
goto LABEL_4;
}
FAT[2 * v2] = v2;
FAT[2 * v2 + 1] = -1;
v7 = get_free_dir_index(a1, a2, v3, v4, v5, a1);
*a2 = v7;
if ( v7 != -1 )
{
strncpy((char *)&directory + 44 * v7, v8, 0x20uLL);
*((_DWORD *)&directory + 11 * *a2 + 10) = v6;
v6 = 1;
*((_DWORD *)&directory + 11 * *a2 + 8) = 0;
v9 = *a2;
*((_DWORD *)&directory + 11 * v9 + 9) = get_current_time();
LABEL_4:
write_directory_to_disk();
write_FAT_to_disk();
write_free_list_to_disk();
return v6;
}
puts("No more space in the directory for more files");
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func13(__int64 a1, int *a2)
{
int v2; // eax
__int64 v3; // rdx
__int64 v4; // rcx
__int64 v5; // r8
unsigned int v6; // er12
int v7; // eax
const char *v8; // r9
int v9; // ebx

v2 = func8();
v6 = v2;
if ( v2 == -1 )
{
puts("Error: No more free blocks");
goto LABEL_4;
}
FAT[2 * v2] = v2;
FAT[2 * v2 + 1] = -1;
v7 = func9(a1, a2, v3, v4, v5, a1);
*a2 = v7;
if ( v7 != -1 )
{
strncpy((char *)&directory + 44 * v7, v8, 0x20uLL);
*((_DWORD *)&directory + 11 * *a2 + 10) = v6;
v6 = 1;
*((_DWORD *)&directory + 11 * *a2 + 8) = 0;
v9 = *a2;
*((_DWORD *)&directory + 11 * v9 + 9) = func7();
LABEL_4:
func3();
func1();
func5();
return v6;
}
puts("No more space in the directory for more files");
return 0xFFFFFFFFLL;
}

original_code:
int create_file_in_mem(char* name, int* dir_index )
{
 int block_index = get_free_block();
 int errorcode = 1;
 if (block_index == -1) {
  printf("Error: No more free blocks\n");
  errorcode = -1;
 }
 else
 {
  FAT[block_index].start = block_index;
  FAT[block_index].next = -1;
  *dir_index = get_free_dir_index();
  if (*dir_index == -1) {
   printf("No more space in the directory for more files\n");
   return -1;
  }
  strncpy(directory[*dir_index].fname, name, 32);
  directory[*dir_index].FAT_index = block_index;
  directory[*dir_index].size = 0;
  directory[*dir_index].time = get_current_time();
 }
 write_directory_to_disk();
 write_FAT_to_disk();
 write_free_list_to_disk();
 return errorcode;
}

canonical_original_code:
int create_file_in_mem(char *name, int *dir_index)
{
 int block_index = get_free_block();
 int errorcode = 1;
 if (block_index == -1) {
  printf("Error: No more free blocks\n");
  errorcode = -1;
 }
 else
 {
  FAT[block_index].start = block_index;
  FAT[block_index].next = -1;
  *dir_index = get_free_dir_index();
  if (*dir_index == -1) {
   printf("No more space in the directory for more files\n");
   return -1;
  }
  strncpy(directory[*dir_index].fname, name, 32);
  directory[*dir_index].FAT_index = block_index;
  directory[*dir_index].size = 0;
  directory[*dir_index].time = get_current_time();
 }
 write_directory_to_disk();
 write_FAT_to_disk();
 write_free_list_to_disk();
 return errorcode;
}

variable_types:
name
char *

variable_types: errorcode int


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

result = 0xFFFFFFFFLL;
if ( a1 <= 0x5D )
result = file_descriptors[5 * a1] != -1;
return result;
}

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

result = 0xFFFFFFFFLL;
if ( a1 <= 0x5D )
result = file_descriptors[5 * a1] != -1;
return result;
}

original_code:
int is_file_open(int dir_index)
{
 if (dir_index > 93 ||
  dir_index < 0) {
  return -1;
 }
 return (file_descriptors[dir_index].root != -1);
}


decompiled_code:
__int64 __fastcall sfs_fopen(char *s2)
{
const char *v1; // rbp
unsigned int v2; // ebx
unsigned int v4[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v1 = (const char *)&directory;
v2 = 0;
v4[0] = -1;
do
{
if ( !strcmp(v1, s2) )
{
v4[0] = v2;
return get_fd(v4[0]);
}
++v2;
v1 += 44;
}
while ( v2 != 93 );
create_file_in_mem((__int64)s2, (int *)v4);
return get_fd(v4[0]);
}

canonical_decompiled_code:
__int64 __fastcall func17(char *s2)
{
const char *v1; // rbp
unsigned int v2; // ebx
unsigned int v4[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v1 = (const char *)&directory;
v2 = 0;
v4[0] = -1;
do
{
if ( !strcmp(v1, s2) )
{
v4[0] = v2;
return func16(v4[0]);
}
++v2;
v1 += 44;
}
while ( v2 != 93 );
func13((__int64)s2, (int *)v4);
return func16(v4[0]);
}

original_code:
int sfs_fopen(char *name)
{
 int i=0;
 int dir_index = -1;
 int file_exists = 0;
 for (i=0; i < 93 && !file_exists; i++) {
  if(!strcmp(directory[i].fname, name))
  {
   dir_index = i;
   file_exists = 1;
  }
 }
 if (!file_exists) {
  create_file_in_mem(name, &dir_index);
 }
 dir_index = get_fd(dir_index);
 return dir_index;
}

canonical_original_code:
int sfs_fopen(char *name)
{
 int i = 0;
 int dir_index = -1;
 int file_exists = 0;
 for (i=0; i < 93 && !file_exists; i++) {
  if(!strcmp(directory[i].fname, name))
  {
   dir_index = i;
   file_exists = 1;
  }
 }
 if (!file_exists) {
  create_file_in_mem(name, &dir_index);
 }
 dir_index = get_fd(dir_index);
 return dir_index;
}

variable_types: i int


decompiled_code:
int __fastcall sfs_fwrite(unsigned int a1, __int64 a2)
{
int v2; // edx
int v3; // ebx
int *v4; // r14
int v5; // edx
int v6; // er15
__int64 v7; // rdi
int v8; // ecx
int v9; // er13
__int64 v10; // rdi
__int64 v11; // rdx
bool v12; // zf
__int64 v13; // rcx
int v14; // eax
int v15; // eax
__int64 v16; // rdx
int v17; // eax
int v18; // edx
int v20; // [rsp+8h] [rbp-1050h]
int v22; // [rsp+18h] [rbp-1040h]
int v23; // [rsp+1Ch] [rbp-103Ch]
char v24[4152]; // [rsp+20h] [rbp-1038h] BYREF

if ( !(unsigned int)is_file_open(a1) )
return puts("Error: Tried to write to a file without having it opened");
v3 = v2;
v4 = &file_descriptors[5 * a1];
v23 = v4[4];
v22 = get_block_count(a1);
if ( v5 <= 0 )
goto LABEL_15;
v20 = 0;
v6 = v5;
do
{
while ( 1 )
{
read_blocks((unsigned int)(FAT[2 * v4[3]] + 3), 1LL, v24);
v7 = v4[4];
v8 = 4096 - v7;
if ( 4096 - (int)v7 > v6 )
v8 = v6;
v9 = v8;
memcpy(&v24[v7], (const void *)(a2 + v3 - v6), v8);
v6 -= v9;
v10 = (unsigned int)(FAT[2 * v4[3]] + 3);
write_blocks(v10, 1LL);
v11 = (unsigned int)((v9 + v4[4]) >> 31) >> 20;
v12 = ((v9 + v4[4]) & 0xFFF) == 0;
v13 = (v9 + v4[4]) & 0xFFF;
v4[4] = (v9 + v4[4]) % 4096;
if ( !v12 )
goto LABEL_5;
v14 = FAT[2 * v4[3] + 1];
if ( v14 == -1 )
break;
v4[3] = v14;
LABEL_5:
if ( v6 <= 0 )
goto LABEL_12;
}
v15 = get_free_block(v10, 1LL, v11, v13);
if ( v15 == -1 )
return puts("Error: No more free blocks!!");
v16 = v4[3];
v20 = 1;
v4[3] = v15;
FAT[2 * v16 + 1] = v15;
FAT[2 * v15] = v15;
FAT[2 * v15 + 1] = -1;
}
while ( v6 > 0 );
LABEL_12:
v17 = get_block_count(a1);
if ( v20 )
{
v18 = file_descriptors[5 * a1 + 4];
LABEL_14:
*((_DWORD *)&directory + 11 * (int)a1 + 8) = v18 + (v17 << 12);
goto LABEL_15;
}
if ( v22 == v17 )
{
v18 = file_descriptors[5 * a1 + 4];
if ( v23 < v18 )
goto LABEL_14;
}
LABEL_15:
write_directory_to_disk();
write_FAT_to_disk();
return write_free_list_to_disk();
}

original_code:
void sfs_fwrite(int fileID, char *buf, int length)
{
 if (!is_file_open(fileID)) {
  printf("Error: Tried to write to a file without having it opened\n");
  return;
 }
 fd_entry* fd = &file_descriptors[fileID];
 int total_length = length;
 int file_has_new_blocks = 0;
 int old_write_offset = fd->write_offset;
 int old_block_offset = get_block_count(fileID);
 while (length > 0)
 {
  char current_block[4096];
  read_blocks(FAT[fd->write_block].start + 3, 1, current_block);
  int available_space = 4096 - fd->write_offset;
  int min = available_space > length ? length : available_space;
  memcpy(current_block+fd->write_offset , buf+(total_length-length) , min);
  write_blocks(FAT[fd->write_block].start + 3, 1,current_block);
  length -= min;
  fd->write_offset = (fd->write_offset +min ) % 4096;
  if (fd->write_offset == 0) {
   int next_write_block = FAT[fd->write_block].next;
   if (next_write_block != -1) {
    fd->write_block = next_write_block;
   }
   else
   {
    int next_free_block = get_free_block();
    if (next_free_block ==-1) {
     printf("Error: No more free blocks!!\n");
     return ;
    }
    FAT[fd->write_block].next = next_free_block;
    FAT[next_free_block].start = next_free_block;
    FAT[next_free_block].next = -1;
    fd->write_block = next_free_block;
    file_has_new_blocks = 1;
   }
  }
 }
 int current_block_count = get_block_count(fileID);
 if (file_has_new_blocks
  || (old_block_offset == current_block_count && old_write_offset < fd->write_offset))
 {
  directory[fileID].size = (current_block_count * 4096) + fd->write_offset;
 }
 write_directory_to_disk();
 write_FAT_to_disk();
 write_free_list_to_disk();
}

canonical_original_code:
void sfs_fwrite(int fileID, char *buf, int length)
{
 if (!is_file_open(fileID)) {
  printf("Error: Tried to write to a file without having it opened\n");
  return;
 }
 struct fd_entry *fd = &file_descriptors[fileID];
 int total_length = length;
 int file_has_new_blocks = 0;
 int old_write_offset = fd->write_offset;
 int old_block_offset = get_block_count(fileID);
 while (length > 0)
 {
  char current_block[4096];
  read_blocks(FAT[fd->write_block].start + 3, 1, current_block);
  int available_space = 4096 - fd->write_offset;
  int min = available_space > length ? length : available_space;
  memcpy(current_block+fd->write_offset , buf+(total_length-length) , min);
  write_blocks(FAT[fd->write_block].start + 3, 1,current_block);
  length -= min;
  fd->write_offset = (fd->write_offset +min ) % 4096;
  if (fd->write_offset == 0) {
   int next_write_block = FAT[fd->write_block].next;
   if (next_write_block != -1) {
    fd->write_block = next_write_block;
   }
   else
   {
    int next_free_block = get_free_block();
    if (next_free_block ==-1) {
     printf("Error: No more free blocks!!\n");
     return ;
    }
    FAT[fd->write_block].next = next_free_block;
    FAT[next_free_block].start = next_free_block;
    FAT[next_free_block].next = -1;
    fd->write_block = next_free_block;
    file_has_new_blocks = 1;
   }
  }
 }
 int current_block_count = get_block_count(fileID);
 if (file_has_new_blocks
  || (old_block_offset == current_block_count && old_write_offset < fd->write_offset))
 {
  directory[fileID].size = (current_block_count * 4096) + fd->write_offset;
 }
 write_directory_to_disk();
 write_FAT_to_disk();
 write_free_list_to_disk();
}

variable_types: fileID int

variable_types:
buf
char *

variable_types: length int

variable_types: struct fd_entry { int root; int read_block; int read_offset; int write_block; int write_offset; } *

variable_types: min int


decompiled_code:
int __fastcall sfs_fread(unsigned int a1, __int64 a2)
{
int v2; // edx
unsigned int v3; // er8
int v4; // ebp
int result; // eax
int v7; // er14
int *v8; // r15
__int64 v9; // rsi
int v10; // ebx
void *v11; // rdi
int v12; // ebx
_BYTE v13[4152]; // [rsp+0h] [rbp-1038h] BYREF

if ( !(unsigned int)is_file_open(a1) )
return puts("Error: Tried to read a file without having it opened");
v4 = v2;
result = get_fd(v3);
if ( v4 > 0 )
{
v7 = v4;
v8 = &file_descriptors[5 * result];
do
{
read_blocks((unsigned int)(FAT[2 * v8[1]] + 3), 1LL, v13);
v9 = v8[2];
v10 = 4096 - v9;
if ( 4096 - (int)v9 > v7 )
v10 = v7;
v11 = (void *)(a2 + v4 - v7);
v7 -= v10;
memcpy(v11, &v13[v9], v10);
v12 = v8[2] + v10;
result = v12 % 4096;
v8[2] = v12 % 4096;
if ( (v12 & 0xFFF) == 0 )
{
result = FAT[2 * v8[1] + 1];
if ( result == -1 )
return puts("ERROR: No more blocks");
v8[1] = result;
}
}
while ( v7 > 0 );
}
return result;
}

canonical_decompiled_code:
int __fastcall func19(unsigned int a1, __int64 a2)
{
int v2; // edx
unsigned int v3; // er8
int v4; // ebp
int result; // eax
int v7; // er14
int *v8; // r15
__int64 v9; // rsi
int v10; // ebx
void *v11; // rdi
int v12; // ebx
_BYTE v13[4152]; // [rsp+0h] [rbp-1038h] BYREF

if ( !(unsigned int)func15(a1) )
return puts("Error: Tried to read a file without having it opened");
v4 = v2;
result = func16(v3);
if ( v4 > 0 )
{
v7 = v4;
v8 = &file_descriptors[5 * result];
do
{
read_blocks((unsigned int)(FAT[2 * v8[1]] + 3), 1LL, v13);
v9 = v8[2];
v10 = 4096 - v9;
if ( 4096 - (int)v9 > v7 )
v10 = v7;
v11 = (void *)(a2 + v4 - v7);
v7 -= v10;
memcpy(v11, &v13[v9], v10);
v12 = v8[2] + v10;
result = v12 % 4096;
v8[2] = v12 % 4096;
if ( (v12 & 0xFFF) == 0 )
{
result = FAT[2 * v8[1] + 1];
if ( result == -1 )
return puts("ERROR: No more blocks");
v8[1] = result;
}
}
while ( v7 > 0 );
}
return result;
}

original_code:
void sfs_fread(int fileID, char *buf, int length)
{
 if (!is_file_open(fileID)) {
  printf("Error: Tried to read a file without having it opened\n");
  return;
 }
 fd_entry* fd = &file_descriptors[get_fd(fileID)];
 int total_length = length;
 while (length > 0)
 {
  char current_block[4096];
  read_blocks(FAT[fd->read_block].start + 3, 1, current_block);
  int min = 4096 - fd->read_offset > length ? length : 4096 - fd->read_offset;
  memcpy(buf+(total_length-length), current_block+fd->read_offset, min);
  length -= min;
  fd->read_offset = (fd->read_offset + min) % 4096;
  if (fd->read_offset == 0) {
   int next_read_block = FAT[fd->read_block].next;
   if (next_read_block == -1) {
    printf("ERROR: No more blocks\n");
    return;
   }
   fd->read_block = next_read_block;
  }
 }
}

canonical_original_code:
void sfs_fread(int fileID, char *buf, int length)
{
 if (!is_file_open(fileID)) {
  printf("Error: Tried to read a file without having it opened\n");
  return;
 }
 struct fd_entry *fd = &file_descriptors[get_fd(fileID)];
 int total_length = length;
 while (length > 0)
 {
  char current_block[4096];
  read_blocks(FAT[fd->read_block].start + 3, 1, current_block);
  int min = 4096 - fd->read_offset > length ? length : 4096 - fd->read_offset;
  memcpy(buf+(total_length-length), current_block+fd->read_offset, min);
  length -= min;
  fd->read_offset = (fd->read_offset + min) % 4096;
  if (fd->read_offset == 0) {
   int next_read_block = FAT[fd->read_block].next;
   if (next_read_block == -1) {
    printf("ERROR: No more blocks\n");
    return;
   }
   fd->read_block = next_read_block;
  }
 }
}

user_defined_types: struct fd_entry { int root; int read_block; int read_offset; int write_block; int write_offset; }