decompiled_code:
__int64 __fastcall fc_mlist_merge(char **a1, __int64 a2)
{
unsigned int v3; // ebx
unsigned int v4; // esi
const __m128i *v5; // rax

if ( !*(_DWORD *)(a2 + 8) )
return 1LL;
v3 = 0;
do
{
v4 = v3++;
v5 = (const __m128i *)fc_mlist_get(a2, v4);
fc_mlist_insert(a1, v5, v5[2].m128i_i32[0]);
}
while ( *(_DWORD *)(a2 + 8) > v3 );
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func11(char **a1, __int64 a2)
{
unsigned int v3; // ebx
unsigned int v4; // esi
const __m128i *v5; // rax

if ( !*(_DWORD *)(a2 + 8) )
return 1LL;
v3 = 0;
do
{
v4 = v3++;
v5 = (const __m128i *)func10(a2, v4);
func5(a1, v5, v5[2].m128i_i32[0]);
}
while ( *(_DWORD *)(a2 + 8) > v3 );
return 1LL;
}

original_code:
int fc_mlist_merge (fc_mlist_t *dst, fc_mlist_t *src)
{
 uint32_t i;
 fc_move_t *move;
 ((void) (0));
 for (i = 0; i < src->index; i++) {
  move = fc_mlist_get(src, i);
  fc_mlist_insert(dst, move, move->value);
 }
 return 1;
}

canonical_original_code:
int fc_mlist_merge(struct fc_mlist_t *dst, struct fc_mlist_t *src)
{
 unsigned int i;
 struct fc_move_t *move;
 ((void) (0));
 for (i = 0; i < src->index; i++) {
  move = fc_mlist_get(src, i);
  fc_mlist_insert(dst, move, move->value);
 }
 return 1;
}


repo: jazzyb/libforchess

decompiled_code:
__int64 __fastcall fc_mlist_iter_init(__int64 a1, __int64 a2, __int64 a3)
{
__int64 result; // rax

*(_QWORD *)a2 = a1;
result = 1LL;
*(_DWORD *)(a2 + 16) = 0;
*(_QWORD *)(a2 + 8) = 0LL;
*(_QWORD *)(a2 + 24) = 0LL;
*(_QWORD *)(a2 + 32) = a3;
return result;
}

original_code:
int fc_mlist_iter_init (fc_mlist_t *list, fc_mlist_iter_t *iter,
  fc_move_t *(*callback) (fc_mlist_iter_t *iter))
{
 iter->list = list;
 iter->current_index = 0;
 iter->state = ((void *)0);
 iter->move = ((void *)0);
 iter->callback = callback;
 return 1;
}

canonical_original_code:
int fc_mlist_iter_init(struct fc_mlist_t *list, struct fc_mlist_iter_ *iter, struct fc_move_t *(*callback)(struct fc_mlist_iter_ *iter))
{
 iter->list = list;
 iter->current_index = 0;
 iter->state = ((void *)0);
 iter->move = ((void *)0);
 iter->callback = callback;
 return 1;
}

variable_types: struct fc_mlist_t { struct fc_move_t { enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } piece; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } opp_player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } opp_piece; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } promote; unsigned long move; int value; } *moves; unsigned int index; } *

variable_types: struct fc_mlist_iter_ { struct fc_mlist_t *list; void *state; int current_index; struct fc_move_t *move; struct fc_move_t *(*callback)(struct fc_mlist_iter_ *iter); } *

variable_types: struct fc_move_t *(*)(struct fc_mlist_iter_ *iter)

return_type: int

user_defined_types: struct fc_mlist_t { struct fc_move_t *moves; unsigned int index; }

user_defined_types: struct fc_move_t { enum fc_player_t player; enum fc_piece_t piece; enum fc_player_t opp_player; enum fc_piece_t opp_piece; enum fc_piece_t promote; unsigned long move; int value; }


decompiled_code:
__int64 __fastcall fc_mlist_iter_next(__int64 a1)
{
int v1; // eax
int v2; // edx
__int64 v3; // rax
__int64 result; // rax

if ( *(_DWORD *)(a1 + 16) )
{
v1 = fc_mlist_length(*(_QWORD *)a1);
if ( v2 >= v1 )
return 0LL;
}
v3 = (*(__int64 (__fastcall **)(__int64))(a1 + 32))(a1);
*(_QWORD *)(a1 + 24) = v3;
if ( !v3 )
return 0LL;
result = a1;
++*(_DWORD *)(a1 + 16);
return result;
}

original_code:
fc_mlist_iter_t *fc_mlist_iter_next (fc_mlist_iter_t *iter)
{
 if (iter->current_index != 0 &&
   iter->current_index >= fc_mlist_length(iter->list)) {
  return ((void *)0);
 }
 iter->move = iter->callback(iter);
 if (iter->move == ((void *)0)) {
  return ((void *)0);
 }
 iter->current_index += 1;
 return iter;
}

canonical_original_code:
struct fc_mlist_iter_ *fc_mlist_iter_next(struct fc_mlist_iter_ *iter)
{
 if (iter->current_index != 0 &&
   iter->current_index >= fc_mlist_length(iter->list)) {
  return ((void *)0);
 }
 iter->move = iter->callback(iter);
 if (iter->move == ((void *)0)) {
  return ((void *)0);
 }
 iter->current_index += 1;
 return iter;
}

variable_types:
iter
struct fc_mlist_iter_ *

return_type: struct fc_mlist_iter_ { struct fc_mlist_t { struct fc_move_t { enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } piece; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } opp_player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } opp_piece; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } promote; unsigned long move; int value; } *moves; unsigned int index; } *list; void *state; int current_index; struct fc_move_t *move; struct fc_move_t *(*callback)(struct fc_mlist_iter_ *iter); } *

user_defined_types: struct fc_mlist_iter_ { struct fc_mlist_t *list; void *state; int current_index; struct fc_move_t *move; struct fc_move_t *(*callback)(struct fc_mlist_iter_ *iter); }


decompiled_code:
__int64 __fastcall fc_mlist_iter_get_move(__int64 a1)
{
return *(_QWORD *)(a1 + 24);
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1)
{
return *(_QWORD *)(a1 + 24);
}

original_code:
fc_move_t *fc_mlist_iter_get_move (fc_mlist_iter_t *iter)
{
 return iter->move;
}

canonical_original_code:
struct fc_move_t *fc_mlist_iter_get_move(struct fc_mlist_iter_ *iter)
{
 return iter->move;
}

variable_types: struct fc_mlist_iter_ { struct fc_mlist_t { struct fc_move_t *moves; unsigned int index; } *list; void *state; int current_index; struct fc_move_t *move; struct fc_move_t *(*callback)(struct fc_mlist_iter_ *iter); } *

return_type: struct fc_move_t { enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } piece; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } opp_player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } opp_piece; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } promote; unsigned long move; int value; } *


decompiled_code:
__int64 __fastcall fc_mlist_iter_get_state(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

original_code:
void *fc_mlist_iter_get_state (fc_mlist_iter_t *iter)
{
 return iter->state;
}

canonical_original_code:
void *fc_mlist_iter_get_state(struct fc_mlist_iter_ *iter)
{
 return iter->state;
}

variable_types: struct fc_mlist_iter_ { struct fc_mlist_t { struct fc_move_t { enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } piece; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } opp_player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } opp_piece; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } promote; unsigned long move; int value; } *moves; unsigned int index; } *list; void *state; int current_index; struct fc_move_t *move; struct fc_move_t *(*callback)(struct fc_mlist_iter_ *iter); } *

return_type: void *


decompiled_code:
void __fastcall fc_mlist_iter_set_state(__int64 a1, __int64 a2)
{
*(_QWORD *)(a1 + 8) = a2;
}

original_code:
void fc_mlist_iter_set_state (fc_mlist_iter_t *iter, void *state)
{
 iter->state = state;
}

canonical_original_code:
void fc_mlist_iter_set_state(struct fc_mlist_iter_ *iter, void *state)
{
 iter->state = state;
}

variable_types:
state
void *

return_type: void

user_defined_types: enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 }

user_defined_types: enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 }


decompiled_code:
__int64 __fastcall fc_mlist_iter_get_mlist(__int64 a1)
{
return *(_QWORD *)a1;
}

canonical_decompiled_code:
__int64 __fastcall func17(__int64 a1)
{
return *(_QWORD *)a1;
}

original_code:
fc_mlist_t *fc_mlist_iter_get_mlist (fc_mlist_iter_t *iter)
{
 return iter->list;
}

canonical_original_code:
struct fc_mlist_t *fc_mlist_iter_get_mlist(struct fc_mlist_iter_ *iter)
{
 return iter->list;
}

return_type: struct fc_mlist_t { struct fc_move_t { enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } piece; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } opp_player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } opp_piece; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } promote; unsigned long move; int value; } *moves; unsigned int index; } *


decompiled_code:
__int64 __fastcall fc_mlist_iter_get_index(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

canonical_decompiled_code:
__int64 __fastcall func18(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

original_code:
int fc_mlist_iter_get_index (fc_mlist_iter_t *iter)
{
 return iter->current_index;
}

canonical_original_code:
int fc_mlist_iter_get_index(struct fc_mlist_iter_ *iter)
{
 return iter->current_index;
}


decompiled_code:
void __fastcall fc_mlist_iter_set_index(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 16) = a2;
}

canonical_decompiled_code:
void __fastcall func19(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 16) = a2;
}

original_code:
void fc_mlist_iter_set_index (fc_mlist_iter_t *iter, int index)
{
 iter->current_index = index;
}

canonical_original_code:
void fc_mlist_iter_set_index(struct fc_mlist_iter_ *iter, int index)
{
 iter->current_index = index;
}

variable_types: index int


decompiled_code:
_BOOL8 __fastcall alphabeta_cutoff(int a1, _DWORD *a2, _DWORD *a3, int a4)
{
_BOOL8 result; // rax

if ( a4 )
{
if ( *a2 < a1 )
{
*a2 = a1;
result = *a3 <= a1;
}
else
{
result = *a3 <= *a2;
}
}
else if ( *a3 <= a1 )
{
result = *a3 <= *a2;
}
else
{
*a3 = a1;
result = a1 <= *a2;
}
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func0(int a1, _DWORD *a2, _DWORD *a3, int a4)
{
_BOOL8 result; // rax

if ( a4 )
{
if ( *a2 < a1 )
{
*a2 = a1;
result = *a3 <= a1;
}
else
{
result = *a3 <= *a2;
}
}
else if ( *a3 <= a1 )
{
result = *a3 <= *a2;
}
else
{
*a3 = a1;
result = a1 <= *a2;
}
return result;
}

original_code:
static int alphabeta_cutoff (int score, int *alpha, int *beta, int max)
{
 if (max && score > *alpha) {
  *alpha = score;
 } else if (!max && score < *beta) {
  *beta = score;
 }
 if (*beta <= *alpha) {
  return 1;
 }
 return 0;
}

canonical_original_code:
static int alphabeta_cutoff(int score, int *alpha, int *beta, int max)
{
 if (max && score > *alpha) {
  *alpha = score;
 } else if (!max && score < *beta) {
  *beta = score;
 }
 if (*beta <= *alpha) {
  return 1;
 }
 return 0;
}

variable_types: score int

variable_types:
alpha
int *

variable_types:
beta
int *

variable_types: max int


decompiled_code:
_BOOL8 __fastcall negascout_cutoff(int a1, _DWORD *a2, _DWORD *a3)
{
return alphabeta_cutoff(a1, a2, a3, 1);
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(int a1, _DWORD *a2, _DWORD *a3)
{
return func0(a1, a2, a3, 1);
}

original_code:
static int negascout_cutoff (int score, int *alpha, int *beta)
{
 return alphabeta_cutoff(score, alpha, beta, 1);
}

canonical_original_code:
static int negascout_cutoff(int score, int *alpha, int *beta)
{
 return alphabeta_cutoff(score, alpha, beta, 1);
}


decompiled_code:
_BOOL8 __fastcall time_up(__int64 a1)
{
_BOOL8 result; // rax

if ( *(_QWORD *)(a1 + 24) )
result = time(0LL) >= *(_QWORD *)(a1 + 24);
else
result = 0LL;
return result;
}

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

if ( *(_QWORD *)(a1 + 24) )
result = time(0LL) >= *(_QWORD *)(a1 + 24);
else
result = 0LL;
return result;
}

original_code:
static int time_up (fc_ai_t *ai)
{
 if (ai->timeout == 0) {
  return 0;
 }
 return time(((void *)0)) >= ai->timeout;
}

canonical_original_code:
static int time_up(struct fc_ai_t *ai)
{
 if (ai->timeout == 0) {
  return 0;
 }
 return time(((void *)0)) >= ai->timeout;
}

variable_types: struct fc_ai_t { struct fc_board_t { unsigned long bitb[-1]; int piece_value[-1]; } *board; struct fc_board_t *bv; struct fc_mlist_t { struct fc_move_t { enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } piece; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } opp_player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } opp_piece; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } promote; unsigned long move; int value; } *moves; unsigned int index; } *mlv; long timeout; enum fc_ai_algo_t { FC_ALPHABETA=0, FC_NEGASCOUT=1 } algo; } *

user_defined_types: struct fc_ai_t { struct fc_board_t *board; struct fc_board_t *bv; struct fc_mlist_t *mlv; long timeout; enum fc_ai_algo_t algo; }


decompiled_code:
__int64 __fastcall create_mlist_iterator(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, unsigned int a6)
{
if ( a2 )
return fc_mlist_iter_init(a2, a1, return_move);
fc_mlist_clear(a4);
fc_board_get_all_moves(a5, a4, a6);
fc_board_state_init(a3, a5, a6);
fc_mlist_iter_init(a4, a1, &fc_board_get_next_move);
return fc_mlist_iter_set_state(a1, a3);
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, unsigned int a6)
{
if ( a2 )
return fc_mlist_iter_init(a2, a1, return_move);
fc_mlist_clear(a4);
fc_board_get_all_moves(a5, a4, a6);
fc_board_state_init(a3, a5, a6);
fc_mlist_iter_init(a4, a1, &fc_board_get_next_move);
return fc_mlist_iter_set_state(a1, a3);
}

original_code:
static void create_mlist_iterator (fc_mlist_iter_t *iter, fc_mlist_t *given,
  fc_board_state_t *state, fc_mlist_t *list, fc_board_t *board,
  fc_player_t player)
{
 if (given) {
  fc_mlist_iter_init(given, iter, return_move);
 } else {
  fc_mlist_clear(list);
  fc_board_get_all_moves(board, list, player);
  fc_board_state_init(state, board, player);
  fc_mlist_iter_init(list, iter, fc_board_get_next_move);
  fc_mlist_iter_set_state(iter, state);
 }
}

canonical_original_code:
static void create_mlist_iterator(struct fc_mlist_iter_ *iter, struct fc_mlist_t *given, struct fc_board_state_t *state, struct fc_mlist_t *list, struct fc_board_t *board, enum fc_player_t player)
{
 if (given) {
  fc_mlist_iter_init(given, iter, return_move);
 } else {
  fc_mlist_clear(list);
  fc_board_get_all_moves(board, list, player);
  fc_board_state_init(state, board, player);
  fc_mlist_iter_init(list, iter, fc_board_get_next_move);
  fc_mlist_iter_set_state(iter, state);
 }
}

variable_types:
given
struct fc_mlist_t *

variable_types: struct fc_board_state_t { struct fc_board_t { unsigned long bitb[-1]; int piece_value[-1]; } *board; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; int current_check_status; int partner_check_status; int all_moves_are_invalid; int initial_flag; } *

variable_types:
list
struct fc_mlist_t *

variable_types:
board
struct fc_board_t *

user_defined_types: struct fc_board_state_t { struct fc_board_t *board; enum fc_player_t player; int current_check_status; int partner_check_status; int all_moves_are_invalid; int initial_flag; }


decompiled_code:
__int64 __fastcall return_move(__int64 a1)
{
unsigned int v1; // er12
__int64 v2; // rax

v1 = fc_mlist_iter_get_index();
v2 = fc_mlist_iter_get_mlist(a1);
return fc_mlist_get(v2, v1);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
unsigned int v1; // er12
__int64 v2; // rax

v1 = fc_mlist_iter_get_index();
v2 = fc_mlist_iter_get_mlist(a1);
return fc_mlist_get(v2, v1);
}

original_code:
static fc_move_t *return_move (fc_mlist_iter_t *iter)
{
 return fc_mlist_get(fc_mlist_iter_get_mlist(iter),
   fc_mlist_iter_get_index(iter));
}

canonical_original_code:
static struct fc_move_t *return_move(struct fc_mlist_iter_ *iter)
{
 return fc_mlist_get(fc_mlist_iter_get_mlist(iter),
   fc_mlist_iter_get_index(iter));
}


decompiled_code:
__int64 __fastcall append_remaining_moves_onto_list(__int64 a1, __int64 a2)
{
unsigned int v2; // er12
int v3; // eax
__int64 v4; // rax
__int64 v5; // rax
__int64 result; // rax

v2 = 0;
v3 = fc_mlist_length();
v4 = fc_mlist_get(a1, (unsigned int)(v3 - 1));
if ( v4 )
v2 = *(_DWORD *)(v4 + 32) - 1;
while ( 1 )
{
result = fc_mlist_iter_next(a2);
if ( !result )
break;
v5 = fc_mlist_iter_get_move(a2);
fc_mlist_insert(a1, v5, v2);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2)
{
unsigned int v2; // er12
int v3; // eax
__int64 v4; // rax
__int64 v5; // rax
__int64 result; // rax

v2 = 0;
v3 = fc_mlist_length();
v4 = fc_mlist_get(a1, (unsigned int)(v3 - 1));
if ( v4 )
v2 = *(_DWORD *)(v4 + 32) - 1;
while ( 1 )
{
result = fc_mlist_iter_next(a2);
if ( !result )
break;
v5 = fc_mlist_iter_get_move(a2);
fc_mlist_insert(a1, v5, v2);
}
return result;
}

original_code:
static void append_remaining_moves_onto_list (fc_mlist_t *list,
  fc_mlist_iter_t *iter)
{
 int32_t min_val;
 fc_move_t *last;
 last = fc_mlist_get(list, fc_mlist_length(list) - 1);
 min_val = (last) ? last->value - 1 : 0;
 while (fc_mlist_iter_next(iter)) {
  fc_move_t *move = fc_mlist_iter_get_move(iter);
  fc_mlist_insert(list, move, min_val);
 }
}

canonical_original_code:
static void append_remaining_moves_onto_list(struct fc_mlist_t *list, struct fc_mlist_iter_ *iter)
{
 int min_val;
 struct fc_move_t *last;
 last = fc_mlist_get(list, fc_mlist_length(list) - 1);
 min_val = (last) ? last->value - 1 : 0;
 while (fc_mlist_iter_next(iter)) {
  struct fc_move_t *move = fc_mlist_iter_get_move(iter);
  fc_mlist_insert(list, move, min_val);
 }
}

variable_types: struct fc_mlist_t { struct fc_move_t { enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } piece; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } opp_player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } opp_piece; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } promote; unsigned long move; int value; } *moves; unsigned int index; } *


alphabeta

decompiled_code:
__int64 __fastcall alphabeta(__int64 a1, __int64 a2, __int64 a3, unsigned int a4, int a5, unsigned int a6, unsigned int a7, int a8)
{
__int64 result; // rax
__int64 v11; // r15
__int64 v12; // r14
int v13; // ebx
__int64 v14; // r15
__int64 v15; // r12
unsigned int v16; // eax
int v17; // er8
int v18; // eax
unsigned int v19; // er8
unsigned int v20; // ebx
int v22; // [rsp+8h] [rbp-A0h]
__int64 v23; // [rsp+10h] [rbp-98h]
int v24; // [rsp+10h] [rbp-98h]
int v25; // [rsp+18h] [rbp-90h]
unsigned int v26; // [rsp+1Ch] [rbp-8Ch] BYREF
char v27[32]; // [rsp+20h] [rbp-88h] BYREF
char v28[104]; // [rsp+40h] [rbp-68h] BYREF

v26 = a6;
if ( time_up(a1) )
{
result = a7;
if ( !a8 )
result = v26;
}
else
{
v23 = a5;
v11 = (__int64)a5 << 8;
v12 = v11 + *(_QWORD *)(a1 + 8);
if ( (unsigned int)fc_board_game_over(v12) || !a5 )
{
v18 = fc_board_score_position(v12, a4);
v19 = v18 - a5;
v20 = a5 - v18;
result = v19;
if ( !a8 )
result = v20;
}
else if ( (unsigned int)fc_board_is_player_out(v12, a4) )
{
result = alphabeta(a1, 0, 0, ((_BYTE)a4 + 1) & 3, a5, v26, a7, a8 ^ 1u);
}
else
{
v13 = a5 - 1;
v14 = *(_QWORD *)(a1 + 8) + v11 - 256;
create_mlist_iterator((__int64)v28, a3, (__int64)v27, *(_QWORD *)(a1 + 16) + 16 * v23 - 16, v12, a4);
v22 = ((_BYTE)a4 + 1) & 3;
v24 = a8 ^ 1;
do
{
if ( !fc_mlist_iter_next(v28) )
break;
fc_board_copy(v14, v12);
v15 = fc_mlist_iter_get_move(v28);
fc_board_make_move(v14, v15);
v16 = alphabeta(a1, 0, 0, v22, v13, v26, a7, v24);
v17 = v16;
if ( a2 )
{
v25 = v16;
fc_mlist_insert(a2, v15, v16);
v17 = v25;
}
}
while ( !alphabeta_cutoff(v17, &v26, &a7, a8) );
if ( a2 )
append_remaining_moves_onto_list(a2, (__int64)v28);
result = v26;
if ( !a8 )
result = a7;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2, __int64 a3, unsigned int a4, int a5, unsigned int a6, unsigned int a7, int a8)
{
__int64 result; // rax
__int64 v11; // r15
__int64 v12; // r14
int v13; // ebx
__int64 v14; // r15
__int64 v15; // r12
unsigned int v16; // eax
int v17; // er8
int v18; // eax
unsigned int v19; // er8
unsigned int v20; // ebx
int v22; // [rsp+8h] [rbp-A0h]
__int64 v23; // [rsp+10h] [rbp-98h]
int v24; // [rsp+10h] [rbp-98h]
int v25; // [rsp+18h] [rbp-90h]
unsigned int v26; // [rsp+1Ch] [rbp-8Ch] BYREF
char v27[32]; // [rsp+20h] [rbp-88h] BYREF
char v28[104]; // [rsp+40h] [rbp-68h] BYREF

v26 = a6;
if ( func2(a1) )
{
result = a7;
if ( !a8 )
result = v26;
}
else
{
v23 = a5;
v11 = (__int64)a5 << 8;
v12 = v11 + *(_QWORD *)(a1 + 8);
if ( (unsigned int)fc_board_game_over(v12) || !a5 )
{
v18 = fc_board_score_position(v12, a4);
v19 = v18 - a5;
v20 = a5 - v18;
result = v19;
if ( !a8 )
result = v20;
}
else if ( (unsigned int)fc_board_is_player_out(v12, a4) )
{
result = func6(a1, 0, 0, ((_BYTE)a4 + 1) & 3, a5, v26, a7, a8 ^ 1u);
}
else
{
v13 = a5 - 1;
v14 = *(_QWORD *)(a1 + 8) + v11 - 256;
func3((__int64)v28, a3, (__int64)v27, *(_QWORD *)(a1 + 16) + 16 * v23 - 16, v12, a4);
v22 = ((_BYTE)a4 + 1) & 3;
v24 = a8 ^ 1;
do
{
if ( !fc_mlist_iter_next(v28) )
break;
fc_board_copy(v14, v12);
v15 = fc_mlist_iter_get_move(v28);
fc_board_make_move(v14, v15);
v16 = func6(a1, 0, 0, v22, v13, v26, a7, v24);
v17 = v16;
if ( a2 )
{
v25 = v16;
fc_mlist_insert(a2, v15, v16);
v17 = v25;
}
}
while ( !func0(v17, &v26, &a7, a8) );
if ( a2 )
func5(a2, (__int64)v28);
result = v26;
if ( !a8 )
result = a7;
}
}
return result;
}

original_code:
static int alphabeta (fc_ai_t *ai, fc_mlist_t *ret, fc_mlist_t *given,
  fc_player_t player, int depth, int alpha, int beta, int max)
{
 int score;
 fc_board_t *board, *copy;
 fc_board_state_t state;
 fc_move_t *move;
 fc_mlist_t *list;
 fc_mlist_iter_t iter;
 if (time_up(ai)) {
  return (max) ? beta : alpha;
 }
 board = &(ai->bv[depth]);
 if (fc_board_game_over(board) || depth == 0) {
  score = fc_board_score_position(board, player);
  return (max) ? score - depth : depth - score;
 }
 if (fc_board_is_player_out(board, player)) {
  return alphabeta(ai, ((void *)0), ((void *)0), ((player + 1) % 4), depth,
    alpha, beta, !max);
 }
 copy = &(ai->bv[depth - 1]);
 list = &(ai->mlv[depth - 1]);
 create_mlist_iterator(&iter, given, &state, list, board, player);
 while (fc_mlist_iter_next(&iter)) {
  fc_board_copy(copy, board);
  move = fc_mlist_iter_get_move(&iter);
  fc_board_make_move(copy, move);
  score = alphabeta(ai, ((void *)0), ((void *)0), ((player + 1) % 4),
    depth - 1, alpha, beta, !max);
  if (ret) {
   fc_mlist_insert(ret, move, score);
  }
  if (alphabeta_cutoff(score, &alpha, &beta, max)) {
   break;
  }
 }
 if (ret) {
  append_remaining_moves_onto_list(ret, &iter);
 }
 return (max) ? alpha : beta;
}

canonical_original_code:
static int alphabeta(struct fc_ai_t *ai, struct fc_mlist_t *ret, struct fc_mlist_t *given, enum fc_player_t player, int depth, int alpha, int beta, int max)
{
 int score;
 struct fc_board_t *board; struct fc_board_t *copy;
 struct fc_board_state_t state;
 struct fc_move_t *move;
 struct fc_mlist_t *list;
 struct fc_mlist_iter_ iter;
 if (time_up(ai)) {
  return (max) ? beta : alpha;
 }
 board = &(ai->bv[depth]);
 if (fc_board_game_over(board) || depth == 0) {
  score = fc_board_score_position(board, player);
  return (max) ? score - depth : depth - score;
 }
 if (fc_board_is_player_out(board, player)) {
  return alphabeta(ai, ((void *)0), ((void *)0), ((player + 1) % 4), depth,
    alpha, beta, !max);
 }
 copy = &(ai->bv[depth - 1]);
 list = &(ai->mlv[depth - 1]);
 create_mlist_iterator(&iter, given, &state, list, board, player);
 while (fc_mlist_iter_next(&iter)) {
  fc_board_copy(copy, board);
  move = fc_mlist_iter_get_move(&iter);
  fc_board_make_move(copy, move);
  score = alphabeta(ai, ((void *)0), ((void *)0), ((player + 1) % 4),
    depth - 1, alpha, beta, !max);
  if (ret) {
   fc_mlist_insert(ret, move, score);
  }
  if (alphabeta_cutoff(score, &alpha, &beta, max)) {
   break;
  }
 }
 if (ret) {
  append_remaining_moves_onto_list(ret, &iter);
 }
 return (max) ? alpha : beta;
}

variable_types:
ret
struct fc_mlist_t *

variable_types: depth int

variable_types: alpha int

variable_types: beta int

variable_types: struct fc_board_state_t { struct fc_board_t { unsigned long bitb[-1]; int piece_value[-1]; } *board; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; int current_check_status; int partner_check_status; int all_moves_are_invalid; int initial_flag; }

variable_types: struct fc_mlist_iter_ { struct fc_mlist_t { struct fc_move_t { enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } piece; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } opp_player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } opp_piece; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } promote; unsigned long move; int value; } *moves; unsigned int index; } *list; void *state; int current_index; struct fc_move_t *move; struct fc_move_t *(*callback)(struct fc_mlist_iter_ *iter); }

user_defined_types: enum fc_ai_algo_t { FC_ALPHABETA=0, FC_NEGASCOUT=1 }


negascout

decompiled_code:
__int64 __fastcall negascout(__int64 a1, __int64 a2, __int64 a3, unsigned int a4, int a5, unsigned int a6, int a7)
{
__int64 v10; // r15
__int64 v11; // r14
int v12; // ebx
__int64 v13; // r15
__int64 v14; // r12
int v15; // er8
int v17; // [rsp+8h] [rbp-A0h]
__int64 v18; // [rsp+10h] [rbp-98h]
unsigned int i; // [rsp+10h] [rbp-98h]
int v20; // [rsp+18h] [rbp-90h]
unsigned int v21; // [rsp+1Ch] [rbp-8Ch] BYREF
char v22[32]; // [rsp+20h] [rbp-88h] BYREF
char v23[104]; // [rsp+40h] [rbp-68h] BYREF

v21 = a6;
if ( time_up(a1) )
return (unsigned int)a7;
v18 = a5;
v10 = (__int64)a5 << 8;
v11 = v10 + *(_QWORD *)(a1 + 8);
if ( (unsigned int)fc_board_game_over(v11) || !a5 )
return fc_board_score_position(v11, a4);
if ( (unsigned int)fc_board_is_player_out(v11, a4) )
return (unsigned int)-negascout(a1, 0, 0, ((_BYTE)a4 + 1) & 3, a5, -a7, -v21);
v12 = a5 - 1;
v13 = *(_QWORD *)(a1 + 8) + v10 - 256;
create_mlist_iterator((__int64)v23, a3, (__int64)v22, *(_QWORD *)(a1 + 16) + 16 * v18 - 16, v11, a4);
v20 = ((_BYTE)a4 + 1) & 3;
LOBYTE(a3) = 1;
for ( i = a7; fc_mlist_iter_next(v23); i = v21 + 1 )
{
fc_board_copy(v13, v11);
v14 = fc_mlist_iter_get_move(v23);
fc_board_make_move(v13, v14);
v15 = -(int)negascout(a1, 0, 0, v20, v12, -i, -v21);
if ( (a3 & 1) == 0 && (int)v21 < v15 && a7 > v15 )
v15 = -(int)negascout(a1, 0, 0, v20, v12, -a7, -v21);
if ( a2 )
{
v17 = v15;
fc_mlist_insert(a2, v14, (unsigned int)v15);
v15 = v17;
}
LODWORD(a3) = negascout_cutoff(v15, &v21, &a7);
if ( (_DWORD)a3 )
break;
}
if ( a2 )
append_remaining_moves_onto_list(a2, (__int64)v23);
return v21;
}

original_code:
static int negascout (fc_ai_t *ai, fc_mlist_t *ret, fc_mlist_t *given,
  fc_player_t player, int depth, int alpha, int beta)
{
 int b, first, score;
 fc_board_t *board, *copy;
 fc_board_state_t state;
 fc_move_t *move;
 fc_mlist_t *list;
 fc_mlist_iter_t iter;
 if (time_up(ai)) {
  return beta;
 }
 board = &(ai->bv[depth]);
 if (fc_board_game_over(board) || depth == 0) {
  score = fc_board_score_position(board, player);
  return score;
 }
 if (fc_board_is_player_out(board, player)) {
  return -negascout(ai, ((void *)0), ((void *)0), ((player + 1) % 4),
    depth, -beta, -alpha);
 }
 copy = &(ai->bv[depth - 1]);
 list = &(ai->mlv[depth - 1]);
 create_mlist_iterator(&iter, given, &state, list, board, player);
 for (first = 1, b = beta; fc_mlist_iter_next(&iter); b = alpha + 1) {
  fc_board_copy(copy, board);
  move = fc_mlist_iter_get_move(&iter);
  fc_board_make_move(copy, move);
  score = -negascout(ai, ((void *)0), ((void *)0), ((player + 1) % 4),
    depth - 1, -b, -alpha);
  if (!first && alpha < score && score < beta) {
   score = -negascout(ai, ((void *)0), ((void *)0),
     ((player + 1) % 4), depth - 1,
     -beta, -alpha);
  }
  first = 0;
  if (ret) {
   fc_mlist_insert(ret, move, score);
  }
  if (negascout_cutoff(score, &alpha, &beta)) {
   break;
  }
 }
 if (ret) {
  append_remaining_moves_onto_list(ret, &iter);
 }
 return alpha;
}

canonical_original_code:
static int negascout(struct fc_ai_t *ai, struct fc_mlist_t *ret, struct fc_mlist_t *given, enum fc_player_t player, int depth, int alpha, int beta)
{
 int b; int first; int score;
 struct fc_board_t *board; struct fc_board_t *copy;
 struct fc_board_state_t state;
 struct fc_move_t *move;
 struct fc_mlist_t *list;
 struct fc_mlist_iter_ iter;
 if (time_up(ai)) {
  return beta;
 }
 board = &(ai->bv[depth]);
 if (fc_board_game_over(board) || depth == 0) {
  score = fc_board_score_position(board, player);
  return score;
 }
 if (fc_board_is_player_out(board, player)) {
  return -negascout(ai, ((void *)0), ((void *)0), ((player + 1) % 4),
    depth, -beta, -alpha);
 }
 copy = &(ai->bv[depth - 1]);
 list = &(ai->mlv[depth - 1]);
 create_mlist_iterator(&iter, given, &state, list, board, player);
 for (first = 1, b = beta; fc_mlist_iter_next(&iter); b = alpha + 1) {
  fc_board_copy(copy, board);
  move = fc_mlist_iter_get_move(&iter);
  fc_board_make_move(copy, move);
  score = -negascout(ai, ((void *)0), ((void *)0), ((player + 1) % 4),
    depth - 1, -b, -alpha);
  if (!first && alpha < score && score < beta) {
   score = -negascout(ai, ((void *)0), ((void *)0),
     ((player + 1) % 4), depth - 1,
     -beta, -alpha);
  }
  first = 0;
  if (ret) {
   fc_mlist_insert(ret, move, score);
  }
  if (negascout_cutoff(score, &alpha, &beta)) {
   break;
  }
 }
 if (ret) {
  append_remaining_moves_onto_list(ret, &iter);
 }
 return alpha;
}

variable_types: b int

variable_types: first int

variable_types: struct fc_board_t { unsigned long bitb[-1]; int piece_value[-1]; } *

variable_types: struct fc_move_t { enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } piece; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } opp_player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } opp_piece; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } promote; unsigned long move; int value; } *


decompiled_code:
void __fastcall free_ai_boards(__int64 a1)
{
free(*(void **)(a1 + 8));
*(_QWORD *)(a1 + 8) = 0LL;
}

original_code:
static void free_ai_boards (fc_ai_t *ai)
{
 free(ai->bv);
 ai->bv = ((void *)0);
}

canonical_original_code:
static void free_ai_boards(struct fc_ai_t *ai)
{
 free(ai->bv);
 ai->bv = ((void *)0);
}

user_defined_types: struct fc_board_t { unsigned long bitb[-1]; int piece_value[-1]; }


decompiled_code:
__int64 __fastcall initialize_ai_boards(__int64 *a1, int a2)
{
__int64 v2; // rbx
char *v3; // rax
__int64 v4; // rsi

v2 = a2;
if ( a1[1] )
free_ai_boards((__int64)a1);
v3 = (char *)calloc(a2 + 1, 0x100uLL);
v4 = *a1;
a1[1] = (__int64)v3;
return fc_board_copy(&v3[256 * v2], v4);
}

original_code:
static void initialize_ai_boards (fc_ai_t *ai, int depth)
{
 if (ai->bv != ((void *)0)) {
  free_ai_boards(ai);
 }
 ai->bv = calloc(depth + 1, sizeof(fc_board_t));
 fc_board_copy(&(ai->bv[depth]), ai->board);
}

canonical_original_code:
static void initialize_ai_boards(struct fc_ai_t *ai, int depth)
{
 if (ai->bv != ((void *)0)) {
  free_ai_boards(ai);
 }
 ai->bv = calloc(depth + 1, sizeof(fc_board_t));
 fc_board_copy(&(ai->bv[depth]), ai->board);
}


original_code:
static void free_ai_mlists (fc_ai_t *ai, int depth)
{
 int i;
 for (i = 0; i < depth; i++) {
  fc_mlist_free(&(ai->mlv[i]));
 }
 free(ai->mlv);
 ai->mlv = ((void *)0);
}

canonical_original_code:
static void free_ai_mlists(struct fc_ai_t *ai, int depth)
{
 int i;
 for (i = 0; i < depth; i++) {
  fc_mlist_free(&(ai->mlv[i]));
 }
 free(ai->mlv);
 ai->mlv = ((void *)0);
}

variable_types: i int


decompiled_code:
char *__fastcall initialize_ai_mlists(__int64 a1, int a2)
{
char *result; // rax
__int64 i; // rbx

if ( *(_QWORD *)(a1 + 16) )
free_ai_mlists(a1, a2);
result = (char *)calloc(a2, 0x10uLL);
*(_QWORD *)(a1 + 16) = result;
if ( a2 > 0 )
{
for ( i = 0LL; ; i += 16LL )
{
result = (char *)fc_mlist_init(&result[i]);
if ( i == 16LL * (unsigned int)(a2 - 1) )
break;
result = *(char **)(a1 + 16);
}
}
return result;
}

canonical_decompiled_code:
char *__fastcall func11(__int64 a1, int a2)
{
char *result; // rax
__int64 i; // rbx

if ( *(_QWORD *)(a1 + 16) )
func10(a1, a2);
result = (char *)calloc(a2, 0x10uLL);
*(_QWORD *)(a1 + 16) = result;
if ( a2 > 0 )
{
for ( i = 0LL; ; i += 16LL )
{
result = (char *)fc_mlist_init(&result[i]);
if ( i == 16LL * (unsigned int)(a2 - 1) )
break;
result = *(char **)(a1 + 16);
}
}
return result;
}

original_code:
static void initialize_ai_mlists (fc_ai_t *ai, int depth)
{
 int i;
 if (ai->mlv != ((void *)0)) {
  free_ai_mlists(ai, depth);
 }
 ai->mlv = calloc(depth, sizeof(fc_mlist_t));
 for (i = 0; i < depth; i++) {
  fc_mlist_init(&(ai->mlv[i]));
 }
}

canonical_original_code:
static void initialize_ai_mlists(struct fc_ai_t *ai, int depth)
{
 int i;
 if (ai->mlv != ((void *)0)) {
  free_ai_mlists(ai, depth);
 }
 ai->mlv = calloc(depth, sizeof(fc_mlist_t));
 for (i = 0; i < depth; i++) {
  fc_mlist_init(&(ai->mlv[i]));
 }
}

variable_types: struct fc_ai_t { struct fc_board_t { unsigned long bitb[-1]; int piece_value[-1]; } *board; struct fc_board_t *bv; struct fc_mlist_t { struct fc_move_t { enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } piece; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } opp_player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } opp_piece; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } promote; unsigned long move; int value; } *moves; unsigned int index; } *mlv; long timeout; enum fc_ai_algo_t { FC_ALPHABETA=0, FC_NEGASCOUT=1 } algo; } *


original_code:
void fc_ai_init (fc_ai_t *ai, fc_board_t *board)
{
 ((void) (0));
 ai->board = board;
 ai->bv = ((void *)0);
 ai->mlv = ((void *)0);
 ai->algo = FC_NEGASCOUT;
}

canonical_original_code:
void fc_ai_init(struct fc_ai_t *ai, struct fc_board_t *board)
{
 ((void) (0));
 ai->board = board;
 ai->bv = ((void *)0);
 ai->mlv = ((void *)0);
 ai->algo = FC_NEGASCOUT;
}


decompiled_code:
void __fastcall fc_ai_set_algorithm(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 32) = a2;
}

canonical_decompiled_code:
void __fastcall func13(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 32) = a2;
}

original_code:
void fc_ai_set_algorithm (fc_ai_t *ai, fc_ai_algo_t algo)
{
 ((void) (0));
 ai->algo = algo;
}

canonical_original_code:
void fc_ai_set_algorithm(struct fc_ai_t *ai, enum fc_ai_algo_t algo)
{
 ((void) (0));
 ai->algo = algo;
}

variable_types: enum fc_ai_algo_t { FC_ALPHABETA=0, FC_NEGASCOUT=1 }


decompiled_code:
__int64 __fastcall fc_ai_next_ranked_moves(__int64 *a1, __int64 a2, __int64 a3, unsigned int a4, int a5, unsigned int a6)
{
__int64 v9; // rbx
__int64 v10; // rax
int v11; // eax

v9 = a6;
if ( (unsigned int)fc_board_is_player_out(*a1, a4) || a5 <= 0 )
return 0LL;
initialize_ai_mlists((__int64)a1, a5);
initialize_ai_boards(a1, a5);
v10 = 0LL;
if ( (_DWORD)v9 )
v10 = v9 + time(0LL);
a1[3] = v10;
v11 = *((_DWORD *)a1 + 8);
if ( v11 )
{
if ( v11 == 1 )
negascout((__int64)a1, a2, a3, a4, a5, 0x80000001, 0x7FFFFFFF);
}
else
{
alphabeta((__int64)a1, a2, a3, a4, a5, 0x80000000, 0x7FFFFFFFu, 1);
}
free_ai_boards((__int64)a1);
free_ai_mlists((__int64)a1, a5);
return 1LL;
}

original_code:
int fc_ai_next_ranked_moves (fc_ai_t *ai, fc_mlist_t *ret, fc_mlist_t *given,
  fc_player_t player, int depth, unsigned int seconds)
{
 ((void) (0));
 if (fc_board_is_player_out(ai->board, player) || depth < 1) {
  return 0;
 }
 initialize_ai_mlists(ai, depth);
 initialize_ai_boards(ai, depth);
 ai->timeout = (seconds) ? time(((void *)0)) + seconds : 0;
 switch (ai->algo) {
 case FC_ALPHABETA:
  alphabeta(ai, ret, given, player, depth, (-0x7fffffff - 1), 0x7fffffff,
    1);
  break;
 case FC_NEGASCOUT:
  negascout(ai, ret, given, player, depth, (-0x7fffffff - 1) + 1,
    0x7fffffff);
  break;
 default:
  ((void) (0));
 }
 free_ai_boards(ai);
 free_ai_mlists(ai, depth);
 return 1;
}

canonical_original_code:
int fc_ai_next_ranked_moves(struct fc_ai_t *ai, struct fc_mlist_t *ret, struct fc_mlist_t *given, enum fc_player_t player, int depth, unsigned int seconds)
{
 ((void) (0));
 if (fc_board_is_player_out(ai->board, player) || depth < 1) {
  return 0;
 }
 initialize_ai_mlists(ai, depth);
 initialize_ai_boards(ai, depth);
 ai->timeout = (seconds) ? time(((void *)0)) + seconds : 0;
 switch (ai->algo) {
 case FC_ALPHABETA:
  alphabeta(ai, ret, given, player, depth, (-0x7fffffff - 1), 0x7fffffff,
    1);
  break;
 case FC_NEGASCOUT:
  negascout(ai, ret, given, player, depth, (-0x7fffffff - 1) + 1,
    0x7fffffff);
  break;
 default:
  ((void) (0));
 }
 free_ai_boards(ai);
 free_ai_mlists(ai, depth);
 return 1;
}

variable_types:
given
struct fc_mlist_t *

variable_types: enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 }

variable_types:
seconds
unsigned int


decompiled_code:
__int64 __fastcall fc_ai_next_move(__int64 *a1, __int64 a2, __int64 a3, unsigned int a4, int a5, unsigned int a6)
{
unsigned int v10; // er12
__int64 v11; // rax
_BYTE v13[72]; // [rsp+0h] [rbp-48h] BYREF

fc_mlist_init(v13);
v10 = fc_ai_next_ranked_moves(a1, (__int64)v13, a3, a4, a5, a6);
if ( a2 )
{
v11 = fc_mlist_get(v13, 0LL);
fc_move_copy(a2, v11);
}
fc_mlist_free(v13);
return v10;
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 *a1, __int64 a2, __int64 a3, unsigned int a4, int a5, unsigned int a6)
{
unsigned int v10; // er12
__int64 v11; // rax
_BYTE v13[72]; // [rsp+0h] [rbp-48h] BYREF

fc_mlist_init(v13);
v10 = func14(a1, (__int64)v13, a3, a4, a5, a6);
if ( a2 )
{
v11 = fc_mlist_get(v13, 0LL);
fc_move_copy(a2, v11);
}
fc_mlist_free(v13);
return v10;
}

original_code:
int fc_ai_next_move (fc_ai_t *ai, fc_move_t *ret, fc_mlist_t *given,
  fc_player_t player, int depth, unsigned int seconds)
{
 int rc;
 fc_mlist_t list;
 fc_mlist_init(&list);
 rc = fc_ai_next_ranked_moves(ai, &list, given, player, depth, seconds);
 if (ret) {
  fc_move_copy(ret, fc_mlist_get(&list, 0));
 }
 fc_mlist_free(&list);
 return rc;
}

canonical_original_code:
int fc_ai_next_move(struct fc_ai_t *ai, struct fc_move_t *ret, struct fc_mlist_t *given, enum fc_player_t player, int depth, unsigned int seconds)
{
 int rc;
 struct fc_mlist_t list;
 fc_mlist_init(&list);
 rc = fc_ai_next_ranked_moves(ai, &list, given, player, depth, seconds);
 if (ret) {
  fc_move_copy(ret, fc_mlist_get(&list, 0));
 }
 fc_mlist_free(&list);
 return rc;
}

variable_types:
ret
struct fc_move_t *

variable_types: rc int

variable_types: struct fc_mlist_t { struct fc_move_t { enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } piece; enum fc_player_t { FC_FIRST=0, FC_SECOND=1, FC_THIRD=2, FC_FOURTH=3 } opp_player; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } opp_piece; enum fc_piece_t { FC_PAWN=0, FC_BISHOP=1, FC_KNIGHT=2, FC_ROOK=3, FC_QUEEN=4, FC_KING=5 } promote; unsigned long move; int value; } *moves; unsigned int index; }


original_code:
static int is_threatened_by_king (fc_board_t *board, fc_player_t player,
  uint64_t king)
{
 uint64_t enemy_kings;
 enemy_kings = (board->bitb[((player + 1) % 4) * 6 + FC_KING]) |
  (board->bitb[((((player + 1) % 4) + 2) % 4) * 6 + FC_KING]);
 if (!(king & ((((uint64_t)0x01010101) << 32) | ((uint64_t)0x01010101)))) {
  if (((king << 7) & enemy_kings) ||
      ((king >> 9) & enemy_kings) ||
      ((king >> 1) & enemy_kings)) {
   return 1;
  }
 }
 if (((king >> 8) & enemy_kings) || ((king << 8) & enemy_kings)) {
  return 1;
 }
 if (!(king & ((((uint64_t)0x80808080) << 32) | ((uint64_t)0x80808080)))) {
  if (((king << 9) & enemy_kings) ||
      ((king >> 7) & enemy_kings) ||
      ((king << 1) & enemy_kings)) {
   return 1;
  }
 }
 return 0;
}

canonical_original_code:
static int is_threatened_by_king(struct fc_board_t *board, enum fc_player_t player, unsigned long king)
{
 unsigned long enemy_kings;
 enemy_kings = (board->bitb[((player + 1) % 4) * 6 + FC_KING]) |
  (board->bitb[((((player + 1) % 4) + 2) % 4) * 6 + FC_KING]);
 if (!(king & ((((unsigned long)0x01010101) << 32) | ((unsigned long)0x01010101)))) {
  if (((king << 7) & enemy_kings) ||
      ((king >> 9) & enemy_kings) ||
      ((king >> 1) & enemy_kings)) {
   return 1;
  }
 }
 if (((king >> 8) & enemy_kings) || ((king << 8) & enemy_kings)) {
  return 1;
 }
 if (!(king & ((((unsigned long)0x80808080) << 32) | ((unsigned long)0x80808080)))) {
  if (((king << 9) & enemy_kings) ||
      ((king >> 7) & enemy_kings) ||
      ((king << 1) & enemy_kings)) {
   return 1;
  }
 }
 return 0;
}

variable_types:
king
unsigned long


original_code:
static int is_threatened_by_pawn (fc_board_t *board, fc_player_t player,
  uint64_t king)
{
 uint64_t pawns1, pawns2, pawns3, pawns4;
 switch (player) {
 case FC_FIRST:
  pawns2 = (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns2 |= (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns3 = (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  pawns3 |= (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  pawns4 = (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  pawns4 |= (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  if (!(king & ((((uint64_t)0x01010101) << 32) | ((uint64_t)0x01010101))) && ((king >> 1) & pawns2)) {
   return 1;
  }
  if (!(king & ((((uint64_t)0x80808080) << 32) | ((uint64_t)0x80808080))) &&
   (((king << 1) & pawns4) || ((king << 1) & pawns3))) {
   return 1;
  }
  if (((king << 8) & pawns2) || ((king << 8) & pawns3)) {
   return 1;
  }
  if ((king >> 8) & pawns4) {
   return 1;
  }
  break;
 case FC_SECOND:
  pawns1 = (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns1 |= (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns4 = (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  pawns4 |= (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  pawns3 = (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  pawns3 |= (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  if (!(king & ((((uint64_t)0x01010101) << 32) | ((uint64_t)0x01010101))) && ((king >> 1) & pawns1)) {
   return 1;
  }
  if (!(king & ((((uint64_t)0x80808080) << 32) | ((uint64_t)0x80808080))) &&
   (((king << 1) & pawns3) || ((king << 1) & pawns4))) {
   return 1;
  }
  if ((king << 8) & pawns3) {
   return 1;
  }
  if (((king >> 8) & pawns1) || ((king >> 8) & pawns4)) {
   return 1;
  }
  break;
 case FC_THIRD:
  pawns2 = (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns2 |= (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns1 = (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns1 |= (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns4 = (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  pawns4 |= (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  if (!(king & ((((uint64_t)0x01010101) << 32) | ((uint64_t)0x01010101))) &&
   (((king >> 1) & pawns2) || ((king >> 1) & pawns1))) {
   return 1;
  }
  if (!(king & ((((uint64_t)0x80808080) << 32) | ((uint64_t)0x80808080))) && ((king << 1) & pawns4)) {
   return 1;
  }
  if ((king << 8) & pawns2) {
   return 1;
  }
  if (((king >> 8) & pawns4) || ((king >> 8) & pawns1)) {
   return 1;
  }
  break;
 case FC_FOURTH:
  pawns1 = (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns1 |= (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns2 = (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns2 |= (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns3 = (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  pawns3 |= (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  if (!(king & ((((uint64_t)0x01010101) << 32) | ((uint64_t)0x01010101))) &&
   (((king >> 1) & pawns1) || ((king >> 1) & pawns2))) {
   return 1;
  }
  if (!(king & ((((uint64_t)0x80808080) << 32) | ((uint64_t)0x80808080))) && ((king << 1) & pawns3)) {
   return 1;
  }
  if (((king << 8) & pawns3) || ((king << 8) & pawns2)) {
   return 1;
  }
  if ((king >> 8) & pawns1) {
   return 1;
  }
  break;
 }
 return 0;
}

canonical_original_code:
static int is_threatened_by_pawn(struct fc_board_t *board, enum fc_player_t player, unsigned long king)
{
 unsigned long pawns1; unsigned long pawns2; unsigned long pawns3; unsigned long pawns4;
 switch (player) {
 case FC_FIRST:
  pawns2 = (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns2 |= (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns3 = (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  pawns3 |= (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  pawns4 = (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  pawns4 |= (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  if (!(king & ((((unsigned long)0x01010101) << 32) | ((unsigned long)0x01010101))) && ((king >> 1) & pawns2)) {
   return 1;
  }
  if (!(king & ((((unsigned long)0x80808080) << 32) | ((unsigned long)0x80808080))) &&
   (((king << 1) & pawns4) || ((king << 1) & pawns3))) {
   return 1;
  }
  if (((king << 8) & pawns2) || ((king << 8) & pawns3)) {
   return 1;
  }
  if ((king >> 8) & pawns4) {
   return 1;
  }
  break;
 case FC_SECOND:
  pawns1 = (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns1 |= (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns4 = (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  pawns4 |= (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  pawns3 = (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  pawns3 |= (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  if (!(king & ((((unsigned long)0x01010101) << 32) | ((unsigned long)0x01010101))) && ((king >> 1) & pawns1)) {
   return 1;
  }
  if (!(king & ((((unsigned long)0x80808080) << 32) | ((unsigned long)0x80808080))) &&
   (((king << 1) & pawns3) || ((king << 1) & pawns4))) {
   return 1;
  }
  if ((king << 8) & pawns3) {
   return 1;
  }
  if (((king >> 8) & pawns1) || ((king >> 8) & pawns4)) {
   return 1;
  }
  break;
 case FC_THIRD:
  pawns2 = (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns2 |= (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns1 = (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns1 |= (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns4 = (board->bitb[FC_FOURTH * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  pawns4 |= (board->bitb[FC_SECOND * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FOURTH]);
  if (!(king & ((((unsigned long)0x01010101) << 32) | ((unsigned long)0x01010101))) &&
   (((king >> 1) & pawns2) || ((king >> 1) & pawns1))) {
   return 1;
  }
  if (!(king & ((((unsigned long)0x80808080) << 32) | ((unsigned long)0x80808080))) && ((king << 1) & pawns4)) {
   return 1;
  }
  if ((king << 8) & pawns2) {
   return 1;
  }
  if (((king >> 8) & pawns4) || ((king >> 8) & pawns1)) {
   return 1;
  }
  break;
 case FC_FOURTH:
  pawns1 = (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns1 |= (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_FIRST]);
  pawns2 = (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns2 |= (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_SECOND]);
  pawns3 = (board->bitb[FC_THIRD * 6 + FC_PAWN]) &
    (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  pawns3 |= (board->bitb[FC_FIRST * 6 + FC_PAWN]) &
     (board->bitb[FC_FIRST_PAWNS + FC_THIRD]);
  if (!(king & ((((unsigned long)0x01010101) << 32) | ((unsigned long)0x01010101))) &&
   (((king >> 1) & pawns1) || ((king >> 1) & pawns2))) {
   return 1;
  }
  if (!(king & ((((unsigned long)0x80808080) << 32) | ((unsigned long)0x80808080))) && ((king << 1) & pawns3)) {
   return 1;
  }
  if (((king << 8) & pawns3) || ((king << 8) & pawns2)) {
   return 1;
  }
  if ((king >> 8) & pawns1) {
   return 1;
  }
  break;
 }
 return 0;
}


canonical_original_code:
static int king_in_check_by_knight(struct fc_board_t *board, enum fc_player_t player, unsigned long king)
{
 unsigned long knights;
 knights = (board->bitb[((player + 1) % 4) * 6 + FC_KNIGHT]) |
    (board->bitb[((((player + 1) % 4) + 2) % 4) * 6 + FC_KNIGHT]);
 if (!(king & (((((unsigned long)0x01010101) << 32) | ((unsigned long)0x01010101)) | ((((unsigned long)0x02020202) << 32) | ((unsigned long)0x02020202))))) {
  if (((king << 6) & knights) || ((king >> 10) & knights)) {
   return 1;
  }
 }
 if (!(king & ((((unsigned long)0x01010101) << 32) | ((unsigned long)0x01010101)))) {
  if (((king << 15) & knights) || ((king >> 17) & knights)) {
   return 1;
  }
 }
 if (!(king & (((((unsigned long)0x80808080) << 32) | ((unsigned long)0x80808080)) | ((((unsigned long)0x40404040) << 32) | ((unsigned long)0x40404040))))) {
  if (((king << 10) & knights) || ((king >> 6) & knights)) {
   return 1;
  }
 }
 if (!(king & ((((unsigned long)0x80808080) << 32) | ((unsigned long)0x80808080)))) {
  if (((king << 17) & knights) || ((king >> 15) & knights)) {
   return 1;
  }
 }
 return 0;
}

variable_types:
knights
unsigned long


decompiled_code:
_BOOL8 __fastcall king_in_check_diagonally(__int64 a1, char a2, unsigned __int64 a3)
{
__int64 v4; // r13
_BOOL8 result; // rax

v4 = *(_QWORD *)(a1 + 8LL * (6 * ((a2 + 3) & 3u) + 1)) | *(_QWORD *)(a1 + 8LL * (6 * ((a2 + 3) & 3u) + 4)) | *(_QWORD *)(a1 + 8LL * (6 * ((a2 + 1) & 3u) + 1)) | *(_QWORD *)(a1 + 8LL * (6 * ((a2 + 1) & 3u) + 4));
if ( (unsigned int)king_in_check_northwest_constprop_0(a1, a3, v4)
|| (unsigned int)king_in_check_southwest_constprop_0(a1, a3, v4)
|| (unsigned int)king_in_check_northeast_constprop_0(a1, a3, v4) )
{
result = 1LL;
}
else
{
result = (unsigned int)king_in_check_southeast_constprop_0(a1, a3, v4) != 0;
}
return result;
}

original_code:
static int king_in_check_diagonally (fc_board_t *board, fc_player_t player,
  uint64_t king)
{
 uint64_t threats;
 threats = (board->bitb[((player + 1) % 4) * 6 + FC_QUEEN]);
 threats |= (board->bitb[((player + 1) % 4) * 6 + FC_BISHOP]);
 threats |= (board->bitb[((((player + 1) % 4) + 2) % 4) * 6 + FC_QUEEN]);
 threats |= (board->bitb[((((player + 1) % 4) + 2) % 4) * 6 + FC_BISHOP]);
 return (king_in_check_northwest(board, player, king, threats) ||
  king_in_check_southwest(board, player, king, threats) ||
  king_in_check_northeast(board, player, king, threats) ||
  king_in_check_southeast(board, player, king, threats));
}

canonical_original_code:
static int king_in_check_diagonally(struct fc_board_t *board, enum fc_player_t player, unsigned long king)
{
 unsigned long threats;
 threats = (board->bitb[((player + 1) % 4) * 6 + FC_QUEEN]);
 threats |= (board->bitb[((player + 1) % 4) * 6 + FC_BISHOP]);
 threats |= (board->bitb[((((player + 1) % 4) + 2) % 4) * 6 + FC_QUEEN]);
 threats |= (board->bitb[((((player + 1) % 4) + 2) % 4) * 6 + FC_BISHOP]);
 return (king_in_check_northwest(board, player, king, threats) ||
  king_in_check_southwest(board, player, king, threats) ||
  king_in_check_northeast(board, player, king, threats) ||
  king_in_check_southeast(board, player, king, threats));
}

variable_types:
threats
unsigned long


decompiled_code:
_BOOL8 __fastcall king_in_check_laterally(__int64 a1, char a2, unsigned __int64 a3)
{
__int64 v4; // r13
_BOOL8 result; // rax

v4 = *(_QWORD *)(a1 + 8LL * (6 * ((a2 + 3) & 3u) + 3)) | *(_QWORD *)(a1 + 8LL * (6 * ((a2 + 3) & 3u) + 4)) | *(_QWORD *)(a1 + 8LL * (6 * ((a2 + 1) & 3u) + 3)) | *(_QWORD *)(a1 + 8LL * (6 * ((a2 + 1) & 3u) + 4));
if ( (unsigned int)king_in_check_upward_constprop_0(a1, a3, v4)
|| (unsigned int)king_in_check_downward_constprop_0(a1, a3, v4)
|| (unsigned int)king_in_check_leftward_constprop_0(a1, a3, v4) )
{
result = 1LL;
}
else
{
result = (unsigned int)king_in_check_rightward_constprop_0(a1, a3, v4) != 0;
}
return result;
}

original_code:
static int king_in_check_laterally (fc_board_t *board, fc_player_t player,
  uint64_t king)
{
 uint64_t threats;
 threats = (board->bitb[((player + 1) % 4) * 6 + FC_QUEEN]);
 threats |= (board->bitb[((player + 1) % 4) * 6 + FC_ROOK]);
 threats |= (board->bitb[((((player + 1) % 4) + 2) % 4) * 6 + FC_QUEEN]);
 threats |= (board->bitb[((((player + 1) % 4) + 2) % 4) * 6 + FC_ROOK]);
 return (king_in_check_upward(board, player, king, threats) ||
  king_in_check_downward(board, player, king, threats) ||
  king_in_check_leftward(board, player, king, threats) ||
  king_in_check_rightward(board, player, king, threats));
}

canonical_original_code:
static int king_in_check_laterally(struct fc_board_t *board, enum fc_player_t player, unsigned long king)
{
 unsigned long threats;
 threats = (board->bitb[((player + 1) % 4) * 6 + FC_QUEEN]);
 threats |= (board->bitb[((player + 1) % 4) * 6 + FC_ROOK]);
 threats |= (board->bitb[((((player + 1) % 4) + 2) % 4) * 6 + FC_QUEEN]);
 threats |= (board->bitb[((((player + 1) % 4) + 2) % 4) * 6 + FC_ROOK]);
 return (king_in_check_upward(board, player, king, threats) ||
  king_in_check_downward(board, player, king, threats) ||
  king_in_check_leftward(board, player, king, threats) ||
  king_in_check_rightward(board, player, king, threats));
}


decompiled_code:
_BOOL8 __fastcall is_check(_QWORD *a1, unsigned int a2)
{
unsigned __int64 v2; // r13
_BOOL8 result; // rax

v2 = a1[6 * a2 + 5];
result = 0LL;
if ( v2 )
{
if ( king_in_check_laterally((__int64)a1, a2, a1[6 * a2 + 5])
|| king_in_check_diagonally((__int64)a1, a2, v2)
|| is_threatened_by_pawn(a1, a2, v2)
|| (unsigned int)is_threatened_by_king((__int64)a1, a2, v2) )
{
result = 1LL;
}
else
{
result = (unsigned int)king_in_check_by_knight((__int64)a1, a2, v2) != 0;
}
}
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func13(_QWORD *a1, unsigned int a2)
{
unsigned __int64 v2; // r13
_BOOL8 result; // rax

v2 = a1[6 * a2 + 5];
result = 0LL;
if ( v2 )
{
if ( func12((__int64)a1, a2, a1[6 * a2 + 5])
|| func7((__int64)a1, a2, v2)
|| func1(a1, a2, v2)
|| (unsigned int)func0((__int64)a1, a2, v2) )
{
result = 1LL;
}
else
{
result = (unsigned int)func2((__int64)a1, a2, v2) != 0;
}
}
return result;
}

original_code:
static int is_check (fc_board_t *board, fc_player_t player)
{
 uint64_t king;
 king = (board->bitb[player * 6 + FC_KING]);
 if (!king) {
  return 0;
 }
 return (king_in_check_laterally(board, player, king) ||
  king_in_check_diagonally(board, player, king) ||
  is_threatened_by_pawn(board, player, king) ||
  is_threatened_by_king(board, player, king) ||
  king_in_check_by_knight(board, player, king));
}

canonical_original_code:
static int is_check(struct fc_board_t *board, enum fc_player_t player)
{
 unsigned long king;
 king = (board->bitb[player * 6 + FC_KING]);
 if (!king) {
  return 0;
 }
 return (king_in_check_laterally(board, player, king) ||
  king_in_check_diagonally(board, player, king) ||
  is_threatened_by_pawn(board, player, king) ||
  is_threatened_by_king(board, player, king) ||
  king_in_check_by_knight(board, player, king));
}


decompiled_code:
__int64 __fastcall fc_board_check_status(_QWORD *a1, unsigned int a2)
{
__int64 result; // rax
unsigned int v3; // ebx
int v4; // er13
__int64 v5; // rax
_BYTE v6[16]; // [rsp+0h] [rbp-138h] BYREF
_QWORD v7[37]; // [rsp+10h] [rbp-128h] BYREF

result = is_check(a1, a2);
if ( (_DWORD)result )
{
v3 = 0;
fc_mlist_init(v6);
fc_board_get_all_moves(a1, v6, a2);
v4 = ((_BYTE)a2 + 2) & 3;
if ( (int)fc_mlist_length(v6) <= 0 )
{
LABEL_5:
fc_mlist_free(v6);
result = 2LL;
}
else
{
while ( 1 )
{
fc_board_copy(v7, a1);
v5 = fc_mlist_get(v6, v3);
fc_board_make_move(v7, v5);
if ( !is_check(v7, a2) && (!is_check(v7, v4) || is_check(a1, v4)) )
break;
if ( (int)fc_mlist_length(v6) <= (int)++v3 )
goto LABEL_5;
}
fc_mlist_free(v6);
result = 1LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func14(_QWORD *a1, unsigned int a2)
{
__int64 result; // rax
unsigned int v3; // ebx
int v4; // er13
__int64 v5; // rax
_BYTE v6[16]; // [rsp+0h] [rbp-138h] BYREF
_QWORD v7[37]; // [rsp+10h] [rbp-128h] BYREF

result = func13(a1, a2);
if ( (_DWORD)result )
{
v3 = 0;
fc_mlist_init(v6);
fc_board_get_all_moves(a1, v6, a2);
v4 = ((_BYTE)a2 + 2) & 3;
if ( (int)fc_mlist_length(v6) <= 0 )
{
LABEL_5:
fc_mlist_free(v6);
result = 2LL;
}
else
{
while ( 1 )
{
fc_board_copy(v7, a1);
v5 = fc_mlist_get(v6, v3);
fc_board_make_move(v7, v5);
if ( !func13(v7, a2) && (!func13(v7, v4) || func13(a1, v4)) )
break;
if ( (int)fc_mlist_length(v6) <= (int)++v3 )
goto LABEL_5;
}
fc_mlist_free(v6);
result = 1LL;
}
}
return result;
}

original_code:
int fc_board_check_status (fc_board_t *board, fc_player_t player)
{
 int i;
 fc_mlist_t moves;
 fc_board_t copy;
 fc_move_t *move;
 ((void) (0));
 if (!is_check(board, player)) {
  return 0;
 }
 fc_mlist_init(&moves);
 fc_board_get_all_moves(board, &moves, player);
 for (i = 0; i < fc_mlist_length(&moves); i++) {
  fc_board_copy(&copy, board);
  move = fc_mlist_get(&moves, i);
  fc_board_make_move(&copy, move);
  if (!is_check(&copy, player)) {
   if (is_check(&copy, ((player + 2) % 4)) &&
       !is_check(board, ((player + 2) % 4))) {
    continue;
   }
   fc_mlist_free(&moves);
   return 1;
  }
 }
 fc_mlist_free(&moves);
 return 2;
}

canonical_original_code:
int fc_board_check_status(struct fc_board_t *board, enum fc_player_t player)
{
 int i;
 struct fc_mlist_t moves;
 struct fc_board_t copy;
 struct fc_move_t *move;
 ((void) (0));
 if (!is_check(board, player)) {
  return 0;
 }
 fc_mlist_init(&moves);
 fc_board_get_all_moves(board, &moves, player);
 for (i = 0; i < fc_mlist_length(&moves); i++) {
  fc_board_copy(&copy, board);
  move = fc_mlist_get(&moves, i);
  fc_board_make_move(&copy, move);
  if (!is_check(&copy, player)) {
   if (is_check(&copy, ((player + 2) % 4)) &&
       !is_check(board, ((player + 2) % 4))) {
    continue;
   }
   fc_mlist_free(&moves);
   return 1;
  }
 }
 fc_mlist_free(&moves);
 return 2;
}

variable_types: struct fc_board_t { unsigned long bitb[-1]; int piece_value[-1]; }


repo: jbanier/psychic-tribble

decompiled_code:
int __fastcall replay_error(const char *a1, unsigned int a2, unsigned int *a3)
{
return printf("[ERROR] line:%d \"%s\" -- (%d)\n", *a3, a1, a2);
}

canonical_decompiled_code:
int __fastcall func0(const char *a1, unsigned int a2, unsigned int *a3)
{
return printf("[ERROR] line:%d \"%s\" -- (%d)\n", *a3, a1, a2);
}

original_code:
void replay_error(const char* a_message, int syserror, void* operation){
 closeOperation *t = (closeOperation*) operation;
 printf("[ERROR] line:%d \"%s\" -- (%d)\n", (*t).lineNumber, a_message, syserror);
}

canonical_original_code:
void replay_error(char *a_message, int syserror, void *operation){
 struct closeOperation *t = (closeOperation*) operation;
 printf("[ERROR] line:%d \"%s\" -- (%d)\n", (*t).lineNumber, a_message, syserror);
}

variable_types: syserror int

variable_types:
operation
void *

variable_types: struct closeOperation { unsigned int lineNumber; unsigned int targetFD; char *operation; } *


verbosePrint

decompiled_code:
int __fastcall verbosePrint(const char *a1)
{
int result; // eax

result = gb_verbose;
if ( gb_verbose )
result = printf(a1);
return result;
}

canonical_decompiled_code:
int __fastcall func0(const char *a1)
{
int result; // eax

result = gb_verbose;
if ( gb_verbose )
result = printf(a1);
return result;
}

original_code:
void
verbosePrint (const char *s)
{
  if (gb_verbose)
    {
      printf (s);
    }
}

canonical_original_code:
void verbosePrint(char *s)
{
  if (gb_verbose)
    {
      printf (s);
    }
}

variable_types:
s
char *


usage

decompiled_code:
int usage()
{
puts("Usage: ioreplay [vh] -f <filename>");
puts("v verbose h help");
puts("Where <filename> is the name of the data file,\nThe data file can contain the following instruction:");
puts("open, close, read, write, lseek. 1 instruction per line, arguments are colon separated.");
puts("ie: one would easily implements a copy with the following instructions:");
puts("open,1,/etc/passwd\nread,1,1024\nclose,1\nopen,2,test/copy O_CREAT|O_WRONLY\nwrite,2,1024\nclose,2");
puts("Limitations: 1024 fd max. you've been warned ... set ulimit -n accordingly (+4)");
puts("You can also use the truss2replay perl script to generate files from live excutable");
puts(" On Linux: strace cat /etc/passwd 2>&1 | perl truss2replay.pl > <filename>");
return puts("\nioreplay 0.2 by jbanier\n");
}

canonical_decompiled_code:
int func1()
{
puts("Usage: ioreplay [vh] -f <filename>");
puts("v verbose h help");
puts("Where <filename> is the name of the data file,\nThe data file can contain the following instruction:");
puts("open, close, read, write, lseek. 1 instruction per line, arguments are colon separated.");
puts("ie: one would easily implements a copy with the following instructions:");
puts("open,1,/etc/passwd\nread,1,1024\nclose,1\nopen,2,test/copy O_CREAT|O_WRONLY\nwrite,2,1024\nclose,2");
puts("Limitations: 1024 fd max. you've been warned ... set ulimit -n accordingly (+4)");
puts("You can also use the truss2replay perl script to generate files from live excutable");
puts(" On Linux: strace cat /etc/passwd 2>&1 | perl truss2replay.pl > <filename>");
return puts("\nioreplay 0.2 by jbanier\n");
}

original_code:
void
usage ()
{
  printf ("Usage: ioreplay [vh] -f <filename>\n");
  printf ("v verbose   h help\n");
  printf
    ("Where <filename> is the name of the data file,\nThe data file can contain the following instruction:\n");
  printf
    ("open, close, read, write, lseek. 1 instruction per line, arguments are colon separated.\n");
  printf
    ("ie: one would easily implements a copy with the following instructions:\n");
  printf
    ("open,1,/etc/passwd\nread,1,1024\nclose,1\nopen,2,test/copy O_CREAT|O_WRONLY\nwrite,2,1024\nclose,2\n");
  printf
    ("Limitations: 1024 fd max. you've been warned ... set ulimit -n accordingly (+4)\n");
  printf("You can also use the truss2replay perl script to generate files from live excutable\n");
  printf("  On Linux: strace cat /etc/passwd 2>&1 | perl truss2replay.pl > <filename>\n");
  printf ("\nioreplay " "0.2" " by " "jbanier" "\n\n");
}

canonical_original_code:
void usage()
{
  printf ("Usage: ioreplay [vh] -f <filename>\n");
  printf ("v verbose   h help\n");
  printf
    ("Where <filename> is the name of the data file,\nThe data file can contain the following instruction:\n");
  printf
    ("open, close, read, write, lseek. 1 instruction per line, arguments are colon separated.\n");
  printf
    ("ie: one would easily implements a copy with the following instructions:\n");
  printf
    ("open,1,/etc/passwd\nread,1,1024\nclose,1\nopen,2,test/copy O_CREAT|O_WRONLY\nwrite,2,1024\nclose,2\n");
  printf
    ("Limitations: 1024 fd max. you've been warned ... set ulimit -n accordingly (+4)\n");
  printf("You can also use the truss2replay perl script to generate files from live excutable\n");
  printf("  On Linux: strace cat /etc/passwd 2>&1 | perl truss2replay.pl > <filename>\n");
  printf ("\nioreplay " "0.2" " by " "jbanier" "\n\n");
}


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // r13
int v4; // er12
int v5; // eax
__int64 v6; // rbx

if ( argc == 1 )
{
usage();
exit(1);
}
v4 = 0;
while ( 1 )
{
v5 = getopt(argc, (char *const *)argv, "f:hv");
if ( v5 == -1 )
break;
if ( v5 == 104 )
{
++v4;
}
else if ( v5 > 104 )
{
if ( v5 == 118 )
++gb_verbose;
}
else if ( v5 == 102 )
{
v3 = optarg;
}
else if ( v5 != 103 )
{
if ( v5 == 58 )
{
usage();
exit(2);
}
if ( v5 == 63 )
{
usage();
exit(3);
}
}
}
if ( v4 )
{
usage();
exit(4);
}
verbosePrint("ioreplay 0.2 by jbanier\n\n");
verbosePrint("StartParsing ...");
if ( (unsigned int)startParsing(v3) == -1 )
{
v4 = 5;
puts("\n[ERROR] parsing of data file failed.");
}
else
{
v6 = buildOperationList();
verbosePrint("...Done\n");
verbosePrint("Starting replay...\n");
do
{
replaySyscall(*(_QWORD *)(v6 + 16));
v6 = *(_QWORD *)(v6 + 8);
}
while ( *(_QWORD *)(v6 + 8) );
verbosePrint("Replay completed.\n");
}
return v4;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // r13
int v4; // er12
int v5; // eax
__int64 v6; // rbx

if ( argc == 1 )
{
func1();
exit(1);
}
v4 = 0;
while ( 1 )
{
v5 = getopt(argc, (char *const *)argv, "f:hv");
if ( v5 == -1 )
break;
if ( v5 == 104 )
{
++v4;
}
else if ( v5 > 104 )
{
if ( v5 == 118 )
++gb_verbose;
}
else if ( v5 == 102 )
{
v3 = optarg;
}
else if ( v5 != 103 )
{
if ( v5 == 58 )
{
func1();
exit(2);
}
if ( v5 == 63 )
{
func1();
exit(3);
}
}
}
if ( v4 )
{
func1();
exit(4);
}
func0("ioreplay 0.2 by jbanier\n\n");
func0("StartParsing ...");
if ( (unsigned int)startParsing(v3) == -1 )
{
v4 = 5;
puts("\n[ERROR] parsing of data file failed.");
}
else
{
v6 = buildOperationList();
func0("...Done\n");
func0("Starting replay...\n");
do
{
replaySyscall(*(_QWORD *)(v6 + 16));
v6 = *(_QWORD *)(v6 + 8);
}
while ( *(_QWORD *)(v6 + 8) );
func0("Replay completed.\n");
}
return v4;
}

original_code:
int
main (int argc, char **argv)
{
  int c;
  int errflg = 0;
  extern char *optarg;
  char *fileName;
  if (argc == 1)
    {
      usage ();
      exit (1);
    }
  while ((c = getopt (argc, argv, "f:hv")) != -1)
    {
      switch (c)
 {
 case 'h':
   errflg++;
   break;
 case 'v':
   gb_verbose++;
   break;
 case 'f':
   fileName = optarg;
   break;
 case ':':
   usage ();
   exit (2);
   break;
 case '?':
   usage ();
   exit (3);
   break;
 }
    }
  if (errflg)
    {
      usage ();
      exit (4);
    }
  verbosePrint ("ioreplay " "0.2" " by " "jbanier" "\n\n");
  verbosePrint ("StartParsing ...");
  if (startParsing (fileName) == -1)
    {
      printf ("\n[ERROR] parsing of data file failed.\n");
      return 5;
    }
  listItem *p = buildOperationList ();
  verbosePrint ("...Done\n");
  verbosePrint ("Starting replay...\n");
  do
    {
      openOperation *t = (openOperation *) (*p).item;
      replaySyscall (t);
      p = (*p).next;
    }
  while ((*p).next != ((void *)0));
  verbosePrint ("Replay completed.\n");
  return 0;
}

canonical_original_code:
int main(int argc, char **argv)
{
  int c;
  int errflg = 0;
  extern char *optarg;
  char *fileName;
  if (argc == 1)
    {
      usage ();
      exit (1);
    }
  while ((c = getopt (argc, argv, "f:hv")) != -1)
    {
      switch (c)
 {
 case 'h':
   errflg++;
   break;
 case 'v':
   gb_verbose++;
   break;
 case 'f':
   fileName = optarg;
   break;
 case ':':
   usage ();
   exit (2);
   break;
 case '?':
   usage ();
   exit (3);
   break;
 }
    }
  if (errflg)
    {
      usage ();
      exit (4);
    }
  verbosePrint ("ioreplay " "0.2" " by " "jbanier" "\n\n");
  verbosePrint ("StartParsing ...");
  if (startParsing (fileName) == -1)
    {
      printf ("\n[ERROR] parsing of data file failed.\n");
      return 5;
    }
  struct listItem *p = buildOperationList ();
  verbosePrint ("...Done\n");
  verbosePrint ("Starting replay...\n");
  do
    {
      struct openOperation *t = (openOperation *) (*p).item;
      replaySyscall (t);
      p = (*p).next;
    }
  while ((*p).next != ((void *)0));
  verbosePrint ("Replay completed.\n");
  return 0;
}

variable_types: argc int

variable_types:
argv
char **

variable_types: c int

variable_types: errflg int

variable_types:
optarg
char *

variable_types:
fileName
char *

variable_types: struct listItem { void *prev; void *next; void *item; } *

variable_types: struct openOperation { unsigned int lineNumber; unsigned int targetFD; char *operation; char *fileName; int oflags; char *mode; } *


buildOperationList

decompiled_code:
_QWORD *buildOperationList()
{
unsigned int v0; // ebx
_QWORD *v1; // r14
_QWORD *v2; // r13
char **v3; // r15
char *v4; // r12
char *v5; // rax
int v6; // eax
_QWORD *v7; // r12
_QWORD *v8; // rax
char *nptr[5]; // [rsp+8h] [rbp-460h] BYREF
char s[1080]; // [rsp+30h] [rbp-438h] BYREF

v0 = 1;
v1 = calloc(0x18uLL, 1uLL);
memset(s, 0, 0x400uLL);
v2 = v1;
while ( fgets(s, 1024, g_fdDataFile) )
{
v3 = nptr;
*((_BYTE *)&nptr[4] + strlen(s) + 7) = 0;
v4 = strtok(s, ",");
do
{
++v3;
v5 = strtok(0LL, ",");
*(v3 - 1) = v5;
}
while ( v5 );
v6 = atoi(nptr[0]);
v7 = buildOperation(v4, v6, nptr[1], v0);
if ( v7 )
{
v8 = malloc(0x18uLL);
v8[2] = 0LL;
v8[1] = 0LL;
v2[2] = v7;
v2[1] = v8;
*v8 = v2;
v2 = v8;
}
else
{
printf("[WARNING] Unrecognized operation line %d [%s]\n", v0, s);
}
++v0;
memset(s, 0, 0x400uLL);
}
fclose(g_fdDataFile);
return v1;
}

canonical_decompiled_code:
_QWORD *func7()
{
unsigned int v0; // ebx
_QWORD *v1; // r14
_QWORD *v2; // r13
char **v3; // r15
char *v4; // r12
char *v5; // rax
int v6; // eax
_QWORD *v7; // r12
_QWORD *v8; // rax
char *nptr[5]; // [rsp+8h] [rbp-460h] BYREF
char s[1080]; // [rsp+30h] [rbp-438h] BYREF

v0 = 1;
v1 = calloc(0x18uLL, 1uLL);
memset(s, 0, 0x400uLL);
v2 = v1;
while ( fgets(s, 1024, g_fdDataFile) )
{
v3 = nptr;
*((_BYTE *)&nptr[4] + strlen(s) + 7) = 0;
v4 = strtok(s, ",");
do
{
++v3;
v5 = strtok(0LL, ",");
*(v3 - 1) = v5;
}
while ( v5 );
v6 = atoi(nptr[0]);
v7 = buildOperation(v4, v6, nptr[1], v0);
if ( v7 )
{
v8 = malloc(0x18uLL);
v8[2] = 0LL;
v8[1] = 0LL;
v2[2] = v7;
v2[1] = v8;
*v8 = v2;
v2 = v8;
}
else
{
printf("[WARNING] Unrecognized operation line %d [%s]\n", v0, s);
}
++v0;
memset(s, 0, 0x400uLL);
}
fclose(g_fdDataFile);
return v1;
}

original_code:
listItem* buildOperationList(){
 unsigned int i_lineNumber = 1;
 void *currentOperation;
 listItem *currListOperation = (listItem*) malloc(sizeof(listItem));
 listItem *startOfList = currListOperation;
 char s[1024];
 memset(currListOperation, 0, sizeof(listItem));
 memset(s, 0, 1024);
 while(fgets(s, 1024, g_fdDataFile) != ((void *)0)) {
  char *s_operation, *s_argument;
  int i = 0;
  char *last, *tok[6];
  unsigned int i_fileDescriptor = 0;
  s[ strlen(s) - 1 ] = '\0';
  tok[0] = strtok(s, ",");
  while (tok[++i] = strtok(((void *)0), ","));
  s_operation = tok[0];
  i_fileDescriptor = atoi( tok[1] );
  s_argument = tok[2];
  currentOperation = buildOperation(s_operation,
     i_fileDescriptor,
     s_argument,
     i_lineNumber);
  if (currentOperation != ((void *)0)) {
   listItem *t = (listItem*) malloc(sizeof(listItem));
   (*t).item = ((void *)0);
   (*t).next = ((void *)0);
   (*currListOperation).item = currentOperation;
   (*currListOperation).next = t;
   (*t).prev = currListOperation;
   currListOperation = t;
  }
  else {
   printf("[WARNING] Unrecognized operation line %d [%s]\n", i_lineNumber, (s == ((void *)0) ? "null" : s) );
  }
  i_lineNumber ++;
  memset(s, 0, 1024);
 }
 fclose(g_fdDataFile);
 return startOfList;
}

canonical_original_code:
struct listItem *buildOperationList(){
 unsigned int i_lineNumber = 1;
 void *currentOperation;
 struct listItem *currListOperation = (listItem*) malloc(sizeof(listItem));
 struct listItem *startOfList = currListOperation;
 char s[1024];
 memset(currListOperation, 0, sizeof(listItem));
 memset(s, 0, 1024);
 while(fgets(s, 1024, g_fdDataFile) != ((void *)0)) {
  char *s_operation; char *s_argument;
  int i = 0;
  char *last; char *tok[6];
  unsigned int i_fileDescriptor = 0;
  s[ strlen(s) - 1 ] = '\0';
  tok[0] = strtok(s, ",");
  while (tok[++i] = strtok(((void *)0), ","));
  s_operation = tok[0];
  i_fileDescriptor = atoi( tok[1] );
  s_argument = tok[2];
  currentOperation = buildOperation(s_operation,
     i_fileDescriptor,
     s_argument,
     i_lineNumber);
  if (currentOperation != ((void *)0)) {
   struct listItem *t = (listItem*) malloc(sizeof(listItem));
   (*t).item = ((void *)0);
   (*t).next = ((void *)0);
   (*currListOperation).item = currentOperation;
   (*currListOperation).next = t;
   (*t).prev = currListOperation;
   currListOperation = t;
  }
  else {
   printf("[WARNING] Unrecognized operation line %d [%s]\n", i_lineNumber, (s == ((void *)0) ? "null" : s) );
  }
  i_lineNumber ++;
  memset(s, 0, 1024);
 }
 fclose(g_fdDataFile);
 return startOfList;
}

variable_types:
currentOperation
void *

variable_types: i int

variable_types:
last
char *

variable_types:
tok
char *[6]

return_type: struct listItem { void *prev; void *next; void *item; } *


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rax
__int64 v4; // rbx
__int64 v5; // rbp

startParsing("ut.dat", argv, envp);
v3 = buildOperationList();
if ( *(_QWORD *)(v3 + 8) )
{
v4 = v3;
do
{
v5 = *(_QWORD *)(v4 + 16);
printf(">%s", *(const char **)(v5 + 8));
if ( !strcmp(*(const char **)(v5 + 8), "open") )
printf("[%s]", *(const char **)(v5 + 16));
putchar(10);
v4 = *(_QWORD *)(v4 + 8);
}
while ( *(_QWORD *)(v4 + 8) );
}
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rax
__int64 v4; // rbx
__int64 v5; // rbp

startParsing("ut.dat", argv, envp);
v3 = func7();
if ( *(_QWORD *)(v3 + 8) )
{
v4 = v3;
do
{
v5 = *(_QWORD *)(v4 + 16);
printf(">%s", *(const char **)(v5 + 8));
if ( !strcmp(*(const char **)(v5 + 8), "open") )
printf("[%s]", *(const char **)(v5 + 16));
putchar(10);
v4 = *(_QWORD *)(v4 + 8);
}
while ( *(_QWORD *)(v4 + 8) );
}
return 0;
}

original_code:
int main(int argc, char** argv) {
 startParsing("ut.dat");
 listItem *p = buildOperationList();
 while((*p).next != ((void *)0)) {
  openOperation *t = (openOperation*) (*p).item;
  printf(">%s", (*t).operation);
  if (strcmp((*t).operation, "open") == 0) {
   printf("[%s]", (*t).fileName);
  }
  printf("\n");
  p = (*p).next;
 }
}

canonical_original_code:
int main(int argc, char **argv) {
 startParsing("ut.dat");
 struct listItem *p = buildOperationList();
 while((*p).next != ((void *)0)) {
  struct openOperation *t = (openOperation*) (*p).item;
  printf(">%s", (*t).operation);
  if (strcmp((*t).operation, "open") == 0) {
   printf("[%s]", (*t).fileName);
  }
  printf("\n");
  p = (*p).next;
 }
}

user_defined_types: struct listItem { void *prev; void *next; void *item; }

user_defined_types: struct openOperation { unsigned int lineNumber; unsigned int targetFD; char *operation; char *fileName; int oflags; char *mode; }


repo: jbowens/sunlab-organ

decompiled_code:
void __fastcall end_beep(void *ptr)
{
kill(*(_DWORD *)ptr, 2);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func7(void *ptr)
{
kill(*(_DWORD *)ptr, 2);
free(ptr);
}

original_code:
void end_beep(a_beep *beep)
{
    kill(beep->pid, 2);
    free(beep);
}

canonical_original_code:
void end_beep(struct a_beep *beep)
{
    kill(beep->pid, 2);
    free(beep);
}

variable_types:
beep
struct a_beep { int pid; } *


sighandler

decompiled_code:
void sighandler()
{
if ( current_beep )
end_beep(current_beep);
}

canonical_decompiled_code:
void func8()
{
if ( current_beep )
func7(current_beep);
}

original_code:
void sighandler(int sig)
{
    if (current_beep)
        end_beep(current_beep);
}

variable_types: sig int


decompiled_code:
__int64 __fastcall get_freq(_DWORD *a1)
{
__int64 result; // rax

result = 440LL;
if ( !*a1 )
{
result = 494LL;
if ( !a1[1] )
{
result = 262LL;
if ( !a1[2] )
{
result = 294LL;
if ( !a1[3] )
{
result = 330LL;
if ( !a1[4] )
{
result = 349LL;
if ( !a1[5] )
result = a1[6] == 0 ? 400 : 392;
}
}
}
}
}
return result;
}

original_code:
int get_freq(int *flags)
{
    if (flags['a'-'a'])
        return 440;
    else if (flags['b'-'a'])
        return 494;
    else if(flags['c'-'a'])
        return 262;
    else if(flags['d'-'a'])
        return 294;
    else if(flags['e'-'a'])
        return 330;
    else if(flags['f'-'a'])
        return 349;
    else if(flags['g'-'a'])
        return 392;
    return 400;
}

variable_types:
flags
int *


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // edx
__int64 v4; // rcx
int v5; // ebx
unsigned int v6; // eax
int buf; // [rsp+Ch] [rbp-8Ch] BYREF
int v9[34]; // [rsp+10h] [rbp-88h] BYREF

__sysv_signal(15, sighandler);
__sysv_signal(2, sighandler);
buf = 0;
while ( read(0, &buf, 4uLL) > 0 )
{
v3 = buf;
v4 = 0LL;
v5 = 0;
do
{
v9[v4] = v3 & (1 << v4);
if ( (v3 & (1 << v4)) != 0 )
v5 = 1;
++v4;
}
while ( v4 != 26 );
if ( current_beep )
{
end_beep(current_beep);
current_beep = 0LL;
}
if ( v5 )
{
v6 = get_freq(v9);
current_beep = (void *)begin_beep(v6);
}
}
if ( current_beep )
{
end_beep(current_beep);
current_beep = 0LL;
}
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // edx
__int64 v4; // rcx
int v5; // ebx
unsigned int v6; // eax
int buf; // [rsp+Ch] [rbp-8Ch] BYREF
int v9[34]; // [rsp+10h] [rbp-88h] BYREF

__sysv_signal(15, sighandler);
__sysv_signal(2, sighandler);
buf = 0;
while ( read(0, &buf, 4uLL) > 0 )
{
v3 = buf;
v4 = 0LL;
v5 = 0;
do
{
v9[v4] = v3 & (1 << v4);
if ( (v3 & (1 << v4)) != 0 )
v5 = 1;
++v4;
}
while ( v4 != 26 );
if ( current_beep )
{
func7(current_beep);
current_beep = 0LL;
}
if ( v5 )
{
v6 = func9(v9);
current_beep = (void *)begin_beep(v6);
}
}
if ( current_beep )
{
func7(current_beep);
current_beep = 0LL;
}
return 0;
}

original_code:
int main(int argc, char **argv)
{
    signal(15, sighandler);
    signal(2 , sighandler);
    int flags[26];
    int buf = 0;
    while (read(0, (char *) &buf, 4) > 0)
    {
        int a_flag_down = 0;
        for (int i = 0; i < 26; i++) {
            flags[i] = (1 << i) & buf;
            if (flags[i])
                a_flag_down = 1;
        }
        if (current_beep) {
            end_beep(current_beep);
            current_beep = 0;
        }
        if (a_flag_down) {
            int freq = get_freq(flags);
            current_beep = begin_beep(freq);
        }
    }
    if (current_beep) {
        end_beep(current_beep);
        current_beep = 0;
    }
}

variable_types:
flags
int [26]

variable_types: buf int

variable_types: freq int


decompiled_code:
int move_to_flags()
{
return wmove(stdscr__NCURSES6_TINFO_5_0_19991023, 6, 0);
}

canonical_decompiled_code:
int func7()
{
return wmove(stdscr__NCURSES6_TINFO_5_0_19991023, 6, 0);
}

original_code:
static void move_to_flags()
{
    wmove(stdscr,(6),(0));
}


finish

decompiled_code:
void __fastcall finish(int a1)
{
_QWORD *v1; // rbx
_QWORD *v2; // rax

if ( ((a1 - 13) & 0xFFFFFFFB) != 0 )
{
endwin();
v1 = child_head;
if ( child_head )
{
do
{
v2 = v1;
v1 = (_QWORD *)v1[10];
close(*((_DWORD *)v2 + 19));
waitpid(*((_DWORD *)child_head + 17), 0LL, 0);
free(child_head);
child_head = v1;
}
while ( v1 );
}
exit(0);
}
}

canonical_decompiled_code:
void __fastcall func8(int a1)
{
_QWORD *v1; // rbx
_QWORD *v2; // rax

if ( ((a1 - 13) & 0xFFFFFFFB) != 0 )
{
endwin();
v1 = child_head;
if ( child_head )
{
do
{
v2 = v1;
v1 = (_QWORD *)v1[10];
close(*((_DWORD *)v2 + 19));
waitpid(*((_DWORD *)child_head + 17), 0LL, 0);
free(child_head);
child_head = v1;
}
while ( v1 );
}
exit(0);
}
}

original_code:
static void finish(int signal)
{
    if (signal == 17 || signal == 13)
    {
    }
    else
    {
        endwin();
        while (child_head)
        {
            remote_child *next = child_head->next;
            close(child_head->write_fd);
            waitpid(child_head->pid, 0, 0);
            free(child_head);
            child_head = next;
        }
        exit(0);
    }
}

canonical_original_code:
static void finish(int signal)
{
    if (signal == 17 || signal == 13)
    {
    }
    else
    {
        endwin();
        while (child_head)
        {
            struct remote_child *next = child_head->next;
            close(child_head->write_fd);
            waitpid(child_head->pid, 0, 0);
            free(child_head);
            child_head = next;
        }
        exit(0);
    }
}

variable_types: signal int

variable_types: struct remote_child { char hostname[64]; int dead; int pid; int read_fd; int write_fd; struct remote_child *next; } *


decompiled_code:
void __fastcall initialize_children(int a1, const char **a2)
{
char *v2; // rbp
const char **v3; // rbx
char *v4; // r12
char *v5; // rax
char *v6; // rax

v2 = 0LL;
if ( a1 > 0 )
{
v3 = a2 + 1;
v2 = (char *)calloc(0x58uLL, 1uLL);
strcpy(v2, *a2);
v4 = v2;
++machine_count;
while ( v3 != &a2[(unsigned int)(a1 - 1) + 1] )
{
v5 = (char *)calloc(0x58uLL, 1uLL);
v6 = strcpy(v5, *v3);
++machine_count;
if ( v2 )
*((_QWORD *)v4 + 10) = v6;
else
v2 = v6;
++v3;
v4 = v6;
}
}
child_head = v2;
}

canonical_decompiled_code:
void __fastcall func9(int a1, const char **a2)
{
char *v2; // rbp
const char **v3; // rbx
char *v4; // r12
char *v5; // rax
char *v6; // rax

v2 = 0LL;
if ( a1 > 0 )
{
v3 = a2 + 1;
v2 = (char *)calloc(0x58uLL, 1uLL);
strcpy(v2, *a2);
v4 = v2;
++machine_count;
while ( v3 != &a2[(unsigned int)(a1 - 1) + 1] )
{
v5 = (char *)calloc(0x58uLL, 1uLL);
v6 = strcpy(v5, *v3);
++machine_count;
if ( v2 )
*((_QWORD *)v4 + 10) = v6;
else
v2 = v6;
++v3;
v4 = v6;
}
}
child_head = v2;
}

original_code:
static void initialize_children(int hostname_count, char **hostnames)
{
    remote_child *head = 0;
    remote_child *tail = 0;
    for (int i = 0; i < hostname_count; i++)
    {
        remote_child *new_child = malloc(sizeof(remote_child));
        memset(new_child, 0, sizeof(remote_child));
        strcpy(new_child->hostname, hostnames[i]);
        machine_count++;
        if (!head) {
            head = new_child;
            tail = new_child;
        } else {
            tail->next = new_child;
            tail = new_child;
        }
    }
    child_head = head;
}

canonical_original_code:
static void initialize_children(int hostname_count, char **hostnames)
{
    struct remote_child *head = 0;
    struct remote_child *tail = 0;
    for (int i = 0; i < hostname_count; i++)
    {
        struct remote_child *new_child = malloc(sizeof(remote_child));
        memset(new_child, 0, sizeof(remote_child));
        strcpy(new_child->hostname, hostnames[i]);
        machine_count++;
        if (!head) {
            head = new_child;
            tail = new_child;
        } else {
            tail->next = new_child;
            tail = new_child;
        }
    }
    child_head = head;
}

variable_types:
hostnames
char **

user_defined_types: struct remote_child { char hostname[64]; int dead; int pid; int read_fd; int write_fd; struct remote_child *next; }


decompiled_code:
void launch_clients()
{
void *i; // rbx
__pid_t v1; // eax
__pid_t v2; // ebp
char *envp; // [rsp+8h] [rbp-40h] BYREF
char *argv[7]; // [rsp+10h] [rbp-38h] BYREF

for ( i = child_head; i; i = (void *)*((_QWORD *)i + 10) )
{
while ( 1 )
{
if ( pipe((int *)i + 18) == -1 )
{
perror("client pipe");
exit(1);
}
v1 = fork();
v2 = v1;
if ( v1 < 0 )
{
perror("client fork");
exit(1);
}
if ( !v1 )
break;
close(*((_DWORD *)i + 18));
*((_DWORD *)i + 17) = v2;
i = (void *)*((_QWORD *)i + 10);
if ( !i )
return;
}
close(*((_DWORD *)i + 19));
close(0);
dup2(*((_DWORD *)i + 18), 0);
argv[0] = "/usr/bin/ssh";
argv[1] = (char *)i;
argv[2] = "/home/jbowens/scratch/sunlab-organ/organ-client";
argv[3] = 0LL;
envp = 0LL;
if ( execve("/usr/bin/ssh", argv, &envp) < 0 )
{
perror("ssh client");
exit(1);
}
*((_DWORD *)i + 17) = v2;
}
}

canonical_decompiled_code:
void func10()
{
void *i; // rbx
__pid_t v1; // eax
__pid_t v2; // ebp
char *envp; // [rsp+8h] [rbp-40h] BYREF
char *argv[7]; // [rsp+10h] [rbp-38h] BYREF

for ( i = child_head; i; i = (void *)*((_QWORD *)i + 10) )
{
while ( 1 )
{
if ( pipe((int *)i + 18) == -1 )
{
perror("client pipe");
exit(1);
}
v1 = fork();
v2 = v1;
if ( v1 < 0 )
{
perror("client fork");
exit(1);
}
if ( !v1 )
break;
close(*((_DWORD *)i + 18));
*((_DWORD *)i + 17) = v2;
i = (void *)*((_QWORD *)i + 10);
if ( !i )
return;
}
close(*((_DWORD *)i + 19));
close(0);
dup2(*((_DWORD *)i + 18), 0);
argv[0] = "/usr/bin/ssh";
argv[1] = (char *)i;
argv[2] = "/home/jbowens/scratch/sunlab-organ/organ-client";
argv[3] = 0LL;
envp = 0LL;
if ( execve("/usr/bin/ssh", argv, &envp) < 0 )
{
perror("ssh client");
exit(1);
}
*((_DWORD *)i + 17) = v2;
}
}

original_code:
static void launch_clients()
{
    remote_child *curr_head = child_head;
    while (curr_head)
    {
        if (pipe(&curr_head->read_fd) == -1) {
            perror("client pipe");
            exit(1);
        }
        int pid = fork();
        if (pid < 0) {
            perror("client fork");
            exit(1);
        }
        if (!pid) {
            close(curr_head->write_fd);
            close(0);
            dup2(curr_head->read_fd, 0);
            char * const argv[] = { "/usr/bin/ssh", curr_head->hostname, "/home/jbowens/scratch/sunlab-organ/organ-client", ((void *)0) };
            char * const envp[] = { ((void *)0) };
            if (execve(argv[0], argv, envp) < 0) {
                perror("ssh client");
                exit(1);
            }
        } else {
            close(curr_head->read_fd);
        }
        curr_head->pid = pid;
        curr_head = curr_head->next;
    }
}

canonical_original_code:
static void launch_clients()
{
    struct remote_child *curr_head = child_head;
    while (curr_head)
    {
        if (pipe(&curr_head->read_fd) == -1) {
            perror("client pipe");
            exit(1);
        }
        int pid = fork();
        if (pid < 0) {
            perror("client fork");
            exit(1);
        }
        if (!pid) {
            close(curr_head->write_fd);
            close(0);
            dup2(curr_head->read_fd, 0);
            char *argv[] = { "/usr/bin/ssh", curr_head->hostname, "/home/jbowens/scratch/sunlab-organ/organ-client", ((void *)0) };
            char *envp[] = { ((void *)0) };
            if (execve(argv[0], argv, envp) < 0) {
                perror("ssh client");
                exit(1);
            }
        } else {
            close(curr_head->read_fd);
        }
        curr_head->pid = pid;
        curr_head = curr_head->next;
    }
}

variable_types: pid int

variable_types:
argv
char *[]

variable_types:
envp
char *[]


decompiled_code:
int print_current_flags()
{
int v0; // edx
__int64 v1; // rax
__int64 v2; // rcx
__int128 v4; // [rsp+0h] [rbp-28h] BYREF
__int64 v5; // [rsp+10h] [rbp-18h]
__int16 v6; // [rsp+18h] [rbp-10h]
char v7; // [rsp+1Ah] [rbp-Eh]

v0 = 0;
v5 = 0LL;
v7 = 0;
v6 = 0;
v1 = 0LL;
v4 = 0LL;
do
{
if ( *((_BYTE *)&flags + v1) )
{
v2 = v0++;
*((_BYTE *)&v4 + v2) = v1 + 97;
}
++v1;
}
while ( v1 != 26 );
move_to_flags();
wclrtoeol(stdscr__NCURSES6_TINFO_5_0_19991023);
waddnstr(stdscr__NCURSES6_TINFO_5_0_19991023, (const char *)&v4, -1);
return wrefresh(stdscr__NCURSES6_TINFO_5_0_19991023);
}

original_code:
static void print_current_flags()
{
    char buffer[27];
    memset(buffer, 0, 27);
    int buffer_index = 0;
    for (int i = 0; i < 26; i++)
    {
        if (flags[i]) {
            buffer[buffer_index++] = i + 'a';
        }
    }
    move_to_flags();
    wclrtoeol(stdscr);
    waddnstr(stdscr,(buffer),-1);
    wrefresh(stdscr);
}

variable_types:
buffer
char [27]


decompiled_code:
int __fastcall stop_flag(char a1)
{
*((_BYTE *)&flags + a1) = 0;
return print_current_flags();
}

canonical_decompiled_code:
int __fastcall func12(char a1)
{
*((_BYTE *)&flags + a1) = 0;
return func11();
}

original_code:
static void stop_flag(char c)
{
    flags[c] = 0;
    print_current_flags();
}

variable_types: c char


decompiled_code:
int __fastcall start_flag(char a1)
{
*((_BYTE *)&flags + a1) = 1;
return print_current_flags();
}

canonical_decompiled_code:
int __fastcall func13(char a1)
{
*((_BYTE *)&flags + a1) = 1;
return func11();
}

original_code:
static void start_flag(char c)
{
    flags[c] = 1;
    print_current_flags();
}


error

decompiled_code:
int __fastcall error(char *a1)
{
wmove(stdscr__NCURSES6_TINFO_5_0_19991023, 4, 0);
wclrtoeol(stdscr__NCURSES6_TINFO_5_0_19991023);
waddnstr(stdscr__NCURSES6_TINFO_5_0_19991023, a1, -1);
return print_current_flags();
}

canonical_decompiled_code:
int __fastcall func14(char *a1)
{
wmove(stdscr__NCURSES6_TINFO_5_0_19991023, 4, 0);
wclrtoeol(stdscr__NCURSES6_TINFO_5_0_19991023);
waddnstr(stdscr__NCURSES6_TINFO_5_0_19991023, a1, -1);
return func11();
}

original_code:
static void error(const char *msg)
{
    wmove(stdscr,(4),(0));
    wclrtoeol(stdscr);
    waddnstr(stdscr,(msg),-1);
    print_current_flags();
}

canonical_original_code:
static void error(char *msg)
{
    wmove(stdscr,(4),(0));
    wclrtoeol(stdscr);
    waddnstr(stdscr,(msg),-1);
    print_current_flags();
}

variable_types:
msg
char *


decompiled_code:
ssize_t broadcast_state()
{
__int64 v0; // rcx
char v1; // si
int v2; // edx
unsigned int *v3; // rbx
ssize_t result; // rax
int buf[3]; // [rsp+Ch] [rbp-Ch] BYREF

v0 = 0LL;
v1 = 0;
v2 = 0;
v3 = (unsigned int *)child_head;
buf[0] = 0;
do
{
result = *((unsigned __int8 *)&flags + v0);
if ( (_BYTE)result )
{
v2 |= 1 << v0;
v1 = *((_BYTE *)&flags + v0);
}
++v0;
}
while ( v0 != 26 );
if ( v1 )
buf[0] = v2;
while ( v3 )
{
result = v3[16];
if ( !(_DWORD)result )
{
result = write(v3[19], buf, 4uLL);
if ( result == -1 )
v3[16] = 1;
}
v3 = (unsigned int *)*((_QWORD *)v3 + 10);
}
return result;
}

canonical_decompiled_code:
ssize_t func15()
{
__int64 v0; // rcx
char v1; // si
int v2; // edx
unsigned int *v3; // rbx
ssize_t result; // rax
int buf[3]; // [rsp+Ch] [rbp-Ch] BYREF

v0 = 0LL;
v1 = 0;
v2 = 0;
v3 = (unsigned int *)child_head;
buf[0] = 0;
do
{
result = *((unsigned __int8 *)&flags + v0);
if ( (_BYTE)result )
{
v2 |= 1 << v0;
v1 = *((_BYTE *)&flags + v0);
}
++v0;
}
while ( v0 != 26 );
if ( v1 )
buf[0] = v2;
while ( v3 )
{
result = v3[16];
if ( !(_DWORD)result )
{
result = write(v3[19], buf, 4uLL);
if ( result == -1 )
v3[16] = 1;
}
v3 = (unsigned int *)*((_QWORD *)v3 + 10);
}
return result;
}

original_code:
static void broadcast_state()
{
    remote_child *client = child_head;
    int bitmap = 0;
    for (int i = 0; i < 26; i++)
    {
        if (flags[i])
            bitmap |= (1 << i);
    }
    while (client)
    {
        if (!client->dead)
        {
            if (write(client->write_fd, (char *) &bitmap, 4) == -1)
            {
                client->dead = 1;
            }
        }
        client = client->next;
    }
}

canonical_original_code:
static void broadcast_state()
{
    struct remote_child *client = child_head;
    int bitmap = 0;
    for (int i = 0; i < 26; i++)
    {
        if (flags[i])
            bitmap |= (1 << i);
    }
    while (client)
    {
        if (!client->dead)
        {
            if (write(client->write_fd, (char *) &bitmap, 4) == -1)
            {
                client->dead = 1;
            }
        }
        client = client->next;
    }
}

variable_types: bitmap int

variable_types: i int


main

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbx
const char *v4; // rbp
int v5; // esi
int v6; // edi

__sysv_signal(2, finish);
__sysv_signal(15, finish);
__sysv_signal(17, finish);
__sysv_signal(13, finish);
flags = 0LL;
v3 = 0LL;
v4 = " ____ ____ ____ ____ ____ ____ _________ ____ ____ ____ ____ ____ ";
word_404138 = 0;
qword_404130 = 0LL;
initialize_children((unsigned int)(argc - 1), argv + 1);
launch_clients();
getchar();
initscr();
keypad(stdscr__NCURSES6_TINFO_5_0_19991023, 1);
nonl();
noecho();
cbreak();
curs_set(0);
do
{
v5 = v3++;
wmove(stdscr__NCURSES6_TINFO_5_0_19991023, v5, 0);
waddnstr(stdscr__NCURSES6_TINFO_5_0_19991023, v4, -1);
v4 = STR_HEADER[v3];
}
while ( v4 );
wmove(stdscr__NCURSES6_TINFO_5_0_19991023, 5, 0);
waddnstr(stdscr__NCURSES6_TINFO_5_0_19991023, "Currently enabled flags:", -1);
move_to_flags();
wrefresh(stdscr__NCURSES6_TINFO_5_0_19991023);
while ( 1 )
{
while ( 1 )
{
v6 = wgetch(stdscr__NCURSES6_TINFO_5_0_19991023) - 97;
if ( (unsigned int)v6 <= 0x19 )
break;
error("Unsupported character");
}
if ( *((_BYTE *)&flags + v6) )
stop_flag();
else
start_flag();
broadcast_state();
}
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbx
const char *v4; // rbp
int v5; // esi
int v6; // edi

__sysv_signal(2, finish);
__sysv_signal(15, finish);
__sysv_signal(17, finish);
__sysv_signal(13, finish);
flags = 0LL;
v3 = 0LL;
v4 = " ____ ____ ____ ____ ____ ____ _________ ____ ____ ____ ____ ____ ";
word_404138 = 0;
qword_404130 = 0LL;
func9((unsigned int)(argc - 1), argv + 1);
func10();
getchar();
initscr();
keypad(stdscr__NCURSES6_TINFO_5_0_19991023, 1);
nonl();
noecho();
cbreak();
curs_set(0);
do
{
v5 = v3++;
wmove(stdscr__NCURSES6_TINFO_5_0_19991023, v5, 0);
waddnstr(stdscr__NCURSES6_TINFO_5_0_19991023, v4, -1);
v4 = STR_HEADER[v3];
}
while ( v4 );
wmove(stdscr__NCURSES6_TINFO_5_0_19991023, 5, 0);
waddnstr(stdscr__NCURSES6_TINFO_5_0_19991023, "Currently enabled flags:", -1);
func7();
wrefresh(stdscr__NCURSES6_TINFO_5_0_19991023);
while ( 1 )
{
while ( 1 )
{
v6 = wgetch(stdscr__NCURSES6_TINFO_5_0_19991023) - 97;
if ( (unsigned int)v6 <= 0x19 )
break;
func14("Unsupported character");
}
if ( *((_BYTE *)&flags + v6) )
func12();
else
func13();
func15();
}
}

original_code:
int main(int argc, char **args)
{
    signal(2 , finish);
    signal(15, finish);
    signal(17, finish);
    signal(13, finish);
    memset(flags, 0, 26);
    initialize_children(argc-1, args+1);
    launch_clients();
    getchar();
    initscr();
    keypad(stdscr, 1);
    nonl();
    noecho();
    cbreak();
    curs_set(0);
    int i;
    for (i = 0; STR_HEADER[i] != 0; i++)
    {
        wmove(stdscr,(i),(0));
        waddnstr(stdscr,(STR_HEADER[i]),-1);
    }
    wmove(stdscr,(5),(0));
    waddnstr(stdscr,(STR_FLAGS_HEADER),-1);
    move_to_flags();
    wrefresh(stdscr);
    for (;;)
    {
        int c = wgetch(stdscr) - 'a';
        if (c < 0 || c > 25) {
            error(BAD_CHARACTER_ERROR_MSG);
            continue;
        }
        if (flags[c])
            stop_flag(c);
        else
            start_flag(c);
        broadcast_state();
    }
}

variable_types: argc int

variable_types:
args
char **

variable_types: c int


repo: jbremer/darm

decompiled_code:
__int64 __fastcall thumb_expand_imm(__int16 a1)
{
int v1; // ecx
int v2; // eax

v1 = a1 & 0xFFF;
if ( (a1 & 0xC00) != 0 )
return (unsigned int)__ROR4__((unsigned __int8)a1 | 0x80, v1 >> 7);
v2 = (v1 >> 8) & 3;
switch ( v2 )
{
case 2:
return (unsigned __int16)((_WORD)v1 << 8) | (unsigned int)(v1 << 24);
case 3:
return ((unsigned __int8)a1 << 24) | (unsigned __int8)a1 | ((unsigned __int8)a1 << 16) | ((unsigned __int8)a1 << 8);
case 1:
return (unsigned __int8)a1 | (v1 << 16) & 0xFF0000u;
}
return (unsigned __int8)a1;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int16 a1)
{
int v1; // ecx
int v2; // eax

v1 = a1 & 0xFFF;
if ( (a1 & 0xC00) != 0 )
return (unsigned int)__ROR4__((unsigned __int8)a1 | 0x80, v1 >> 7);
v2 = (v1 >> 8) & 3;
switch ( v2 )
{
case 2:
return (unsigned __int16)((_WORD)v1 << 8) | (unsigned int)(v1 << 24);
case 3:
return ((unsigned __int8)a1 << 24) | (unsigned __int8)a1 | ((unsigned __int8)a1 << 16) | ((unsigned __int8)a1 << 8);
case 1:
return (unsigned __int8)a1 | (v1 << 16) & 0xFF0000u;
}
return (unsigned __int8)a1;
}

original_code:
uint32_t thumb_expand_imm(uint16_t imm12)
{
    uint32_t value;
    imm12 &= 0xfff;
    if((imm12 & 0xc00) == 0) {
        switch ((imm12 & 0x300) >> 8) {
        case 0:
            value = imm12 & 0xff;
            break;
        case 1:
            value = ((imm12 & 0xff) << 16) | (imm12 & 0xff);
            break;
        case 2:
            value = ((imm12 & 0xff) << 24) | ((imm12 & 0xff) << 8);
            break;
        case 3:
            imm12 &= 0xff;
            value = imm12 | (imm12 << 8) | (imm12 << 16) | (imm12 << 24);
            break;
        }
    }
    else {
        uint32_t unrotated = 0x80 | (imm12 & 0x7F);
        value = (((unrotated) >> ((imm12 & 0xF80) >> 7)) | ((unrotated) << (32 - ((imm12 & 0xF80) >> 7))));
    }
    return value;
}

canonical_original_code:
unsigned int thumb_expand_imm(unsigned short imm12)
{
    unsigned int value;
    imm12 &= 0xfff;
    if((imm12 & 0xc00) == 0) {
        switch ((imm12 & 0x300) >> 8) {
        case 0:
            value = imm12 & 0xff;
            break;
        case 1:
            value = ((imm12 & 0xff) << 16) | (imm12 & 0xff);
            break;
        case 2:
            value = ((imm12 & 0xff) << 24) | ((imm12 & 0xff) << 8);
            break;
        case 3:
            imm12 &= 0xff;
            value = imm12 | (imm12 << 8) | (imm12 << 16) | (imm12 << 24);
            break;
        }
    }
    else {
        unsigned int unrotated = 0x80 | (imm12 & 0x7F);
        value = (((unrotated) >> ((imm12 & 0xF80) >> 7)) | ((unrotated) << (32 - ((imm12 & 0xF80) >> 7))));
    }
    return value;
}

variable_types:
value
unsigned int

variable_types:
unrotated
unsigned int

return_type: unsigned int