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

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

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

result = 0LL;
if ( *(_QWORD *)(a1 + 24) )
result = time(0LL) >= *(_QWORD *)(a1 + 24);
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; }


repo: jazzyb/libforchess

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: 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); } *

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 *

return_type: void

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); }

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; }

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 return_move(__int64 a1)
{
unsigned int v1; // ebp
__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; // ebp
__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));
}

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 append_remaining_moves_onto_list(__int64 a1, __int64 a2)
{
int v2; // eax
__int64 v3; // rax
unsigned int v4; // er12
__int64 v5; // rax
__int64 result; // rax

v2 = fc_mlist_length();
v3 = fc_mlist_get(a1, (unsigned int)(v2 - 1));
v4 = 0;
if ( v3 )
v4 = *(_DWORD *)(v3 + 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, v4);
}
return result;
}

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

v2 = fc_mlist_length();
v3 = fc_mlist_get(a1, (unsigned int)(v2 - 1));
v4 = 0;
if ( v3 )
v4 = *(_DWORD *)(v3 + 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, v4);
}
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; } *

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); } *


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 v10; // r13
int v11; // eax
__int64 v12; // r15
char v13; // r14
int v14; // eax
unsigned int v15; // er8
unsigned int v16; // ebx
__int64 v17; // rbx
unsigned int v18; // eax
int v19; // er14
int v21; // [rsp+0h] [rbp-98h]
int v23; // [rsp+8h] [rbp-90h]
unsigned int v24; // [rsp+Ch] [rbp-8Ch] BYREF
char v25[48]; // [rsp+10h] [rbp-88h] BYREF
char v26[88]; // [rsp+40h] [rbp-58h] BYREF

v24 = a6;
if ( time_up(a1) )
{
if ( a8 )
result = a7;
else
result = v24;
}
else
{
v10 = *(_QWORD *)(a1 + 8) + ((__int64)a5 << 8);
v11 = fc_board_game_over(v10);
if ( !a5 || v11 )
{
v14 = fc_board_score_position(v10, a4);
v15 = v14 - a5;
v16 = a5 - v14;
result = v15;
if ( !a8 )
result = v16;
}
else if ( (unsigned int)fc_board_is_player_out(v10, a4) )
{
result = alphabeta(a1, 0, 0, ((_BYTE)a4 + 1) & 3, a5, v24, a7, a8 == 0);
}
else
{
v12 = *(_QWORD *)(a1 + 8) + ((__int64)a5 << 8) - 256;
v13 = a4;
create_mlist_iterator((__int64)v25, a3, (__int64)v26, *(_QWORD *)(a1 + 16) + 16LL * a5 - 16, v10, a4);
v23 = a5 - 1;
v21 = (v13 + 1) & 3;
do
{
if ( !fc_mlist_iter_next(v25) )
break;
fc_board_copy(v12, v10);
v17 = fc_mlist_iter_get_move(v25);
fc_board_make_move(v12, v17);
v18 = alphabeta(a1, 0, 0, v21, v23, v24, a7, a8 == 0);
v19 = v18;
if ( a2 )
fc_mlist_insert(a2, v17, v18);
}
while ( !alphabeta_cutoff(v19, &v24, &a7, a8) );
if ( a2 )
append_remaining_moves_onto_list(a2, (__int64)v25);
result = v24;
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 v10; // r13
int v11; // eax
__int64 v12; // r15
char v13; // r14
int v14; // eax
unsigned int v15; // er8
unsigned int v16; // ebx
__int64 v17; // rbx
unsigned int v18; // eax
int v19; // er14
int v21; // [rsp+0h] [rbp-98h]
int v23; // [rsp+8h] [rbp-90h]
unsigned int v24; // [rsp+Ch] [rbp-8Ch] BYREF
char v25[48]; // [rsp+10h] [rbp-88h] BYREF
char v26[88]; // [rsp+40h] [rbp-58h] BYREF

v24 = a6;
if ( func2(a1) )
{
if ( a8 )
result = a7;
else
result = v24;
}
else
{
v10 = *(_QWORD *)(a1 + 8) + ((__int64)a5 << 8);
v11 = fc_board_game_over(v10);
if ( !a5 || v11 )
{
v14 = fc_board_score_position(v10, a4);
v15 = v14 - a5;
v16 = a5 - v14;
result = v15;
if ( !a8 )
result = v16;
}
else if ( (unsigned int)fc_board_is_player_out(v10, a4) )
{
result = func6(a1, 0, 0, ((_BYTE)a4 + 1) & 3, a5, v24, a7, a8 == 0);
}
else
{
v12 = *(_QWORD *)(a1 + 8) + ((__int64)a5 << 8) - 256;
v13 = a4;
func3((__int64)v25, a3, (__int64)v26, *(_QWORD *)(a1 + 16) + 16LL * a5 - 16, v10, a4);
v23 = a5 - 1;
v21 = (v13 + 1) & 3;
do
{
if ( !fc_mlist_iter_next(v25) )
break;
fc_board_copy(v12, v10);
v17 = fc_mlist_iter_get_move(v25);
fc_board_make_move(v12, v17);
v18 = func6(a1, 0, 0, v21, v23, v24, a7, a8 == 0);
v19 = v18;
if ( a2 )
fc_mlist_insert(a2, v17, v18);
}
while ( !func0(v19, &v24, &a7, a8) );
if ( a2 )
func5(a2, (__int64)v25);
result = v24;
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: max int

variable_types: score 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); }

return_type: int

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 v9; // r14
int v10; // eax
unsigned int v11; // er15
_BOOL4 v12; // er13
int v13; // ebp
__int64 v15; // [rsp+0h] [rbp-A8h]
int v17; // [rsp+8h] [rbp-A0h]
__int64 v18; // [rsp+10h] [rbp-98h]
int v19; // [rsp+18h] [rbp-90h]
unsigned int v20; // [rsp+1Ch] [rbp-8Ch] BYREF
char v21[48]; // [rsp+20h] [rbp-88h] BYREF
char v22[88]; // [rsp+50h] [rbp-58h] BYREF

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

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: 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; } *

variable_types: b int

variable_types: first int


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]; }

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 initialize_ai_boards(_QWORD *a1, int a2)
{
char *v2; // rax

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

canonical_decompiled_code:
__int64 __fastcall func9(_QWORD *a1, int a2)
{
char *v2; // rax

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

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);
}


decompiled_code:
void __fastcall free_ai_mlists(__int64 a1, int a2)
{
__int64 v2; // rbx

if ( a2 > 0 )
{
v2 = 0LL;
do
{
fc_mlist_free(*(_QWORD *)(a1 + 16) + v2);
v2 += 16LL;
}
while ( v2 != 16LL * (unsigned int)a2 );
}
free(*(void **)(a1 + 16));
*(_QWORD *)(a1 + 16) = 0LL;
}

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:
void *__fastcall initialize_ai_mlists(__int64 a1, int a2)
{
void *result; // rax
__int64 v3; // rbx

if ( *(_QWORD *)(a1 + 16) )
free_ai_mlists(a1, a2);
result = calloc(a2, 0x10uLL);
*(_QWORD *)(a1 + 16) = result;
if ( a2 > 0 )
{
v3 = 0LL;
do
{
result = (void *)fc_mlist_init(*(_QWORD *)(a1 + 16) + v3);
v3 += 16LL;
}
while ( v3 != 16LL * (unsigned int)a2 );
}
return result;
}

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

if ( *(_QWORD *)(a1 + 16) )
func10(a1, a2);
result = calloc(a2, 0x10uLL);
*(_QWORD *)(a1 + 16) = result;
if ( a2 > 0 )
{
v3 = 0LL;
do
{
result = (void *)fc_mlist_init(*(_QWORD *)(a1 + 16) + v3);
v3 += 16LL;
}
while ( v3 != 16LL * (unsigned int)a2 );
}
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]));
 }
}


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(_QWORD *a1, __int64 a2, __int64 a3, unsigned int a4, int a5, unsigned int a6)
{
int v10; // eax
time_t v11; // rax
int v12; // eax

v10 = fc_board_is_player_out(*a1, a4);
if ( a5 <= 0 || v10 )
return 0LL;
initialize_ai_mlists((__int64)a1, a5);
initialize_ai_boards(a1, a5);
v11 = 0LL;
if ( a6 )
v11 = a6 + time(0LL);
a1[3] = v11;
v12 = *((_DWORD *)a1 + 8);
if ( v12 )
{
if ( v12 == 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(_QWORD *a1, __int64 a2, __int64 a3, unsigned int a4, int a5, unsigned int a6)
{
unsigned int v10; // ebp
__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(_QWORD *a1, __int64 a2, __int64 a3, unsigned int a4, int a5, unsigned int a6)
{
unsigned int v10; // ebp
__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: struct fc_board_t { unsigned long bitb[-1]; int piece_value[-1]; } *

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_laterally(__int64 a1, __int64 a2, unsigned __int64 a3)
{
__int64 v4; // r13
int v5; // edx
_BOOL8 result; // rax
int v7; // edx
int v8; // edx

v4 = *(_QWORD *)(a1 + 8LL * (6 * (((_BYTE)a2 + 3) & 3u) + 3)) | *(_QWORD *)(a1 + 8LL
* (6 * (((_BYTE)a2 + 3) & 3u) + 4)) | *(_QWORD *)(a1 + 8LL * (6 * (((_BYTE)a2 + 1) & 3u) + 3)) | *(_QWORD *)(a1 + 8LL * (6 * (((_BYTE)a2 + 1) & 3u) + 4));
v5 = king_in_check_upward(a1, a2, a3, v4);
result = 1LL;
if ( !v5 )
{
v7 = king_in_check_downward(a1, (unsigned int)a2, a3, v4);
result = 1LL;
if ( !v7 )
{
v8 = king_in_check_leftward(a1, (unsigned int)a2, a3, v4);
result = 1LL;
if ( !v8 )
result = (unsigned int)king_in_check_rightward(a1, (unsigned int)a2, 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));
}

variable_types:
threats
unsigned long


decompiled_code:
_BOOL8 __fastcall king_in_check_diagonally(__int64 a1, __int64 a2, unsigned __int64 a3)
{
__int64 v4; // r13
int v5; // edx
_BOOL8 result; // rax
int v7; // edx
int v8; // edx

v4 = *(_QWORD *)(a1 + 8LL * (6 * (((_BYTE)a2 + 3) & 3u) + 1)) | *(_QWORD *)(a1 + 8LL
* (6 * (((_BYTE)a2 + 3) & 3u) + 4)) | *(_QWORD *)(a1 + 8LL * (6 * (((_BYTE)a2 + 1) & 3u) + 1)) | *(_QWORD *)(a1 + 8LL * (6 * (((_BYTE)a2 + 1) & 3u) + 4));
v5 = king_in_check_northwest(a1, a2, a3, v4);
result = 1LL;
if ( !v5 )
{
v7 = king_in_check_southwest(a1, (unsigned int)a2, a3, v4);
result = 1LL;
if ( !v7 )
{
v8 = king_in_check_northeast(a1, (unsigned int)a2, a3, v4);
result = 1LL;
if ( !v8 )
result = (unsigned int)king_in_check_southeast(a1, (unsigned int)a2, 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));
}


decompiled_code:
_BOOL8 __fastcall is_check(_QWORD *a1, __int64 a2)
{
unsigned __int64 v2; // r12
_BOOL8 result; // rax
_BOOL4 v4; // edx
_BOOL4 v5; // edx
_BOOL4 v6; // edx
_BOOL4 v7; // edx

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

canonical_decompiled_code:
_BOOL8 __fastcall func13(_QWORD *a1, __int64 a2)
{
unsigned __int64 v2; // r12
_BOOL8 result; // rax
_BOOL4 v4; // edx
_BOOL4 v5; // edx
_BOOL4 v6; // edx
_BOOL4 v7; // edx

v2 = a1[(unsigned int)(6 * a2 + 5)];
result = 0LL;
if ( v2 )
{
v4 = func7((__int64)a1, a2, a1[(unsigned int)(6 * a2 + 5)]);
result = 1LL;
if ( !v4 )
{
v5 = func12((__int64)a1, (unsigned int)a2, v2);
result = 1LL;
if ( !v5 )
{
v6 = func1(a1, a2, v2);
result = 1LL;
if ( !v6 )
{
v7 = func0((__int64)a1, a2, v2);
result = 1LL;
if ( !v7 )
result = func2((__int64)a1, a2, v2);
}
}
}
}
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, __int64 a2)
{
__int64 result; // rax
int i; // ebx
__int64 v4; // rax
_QWORD v5[32]; // [rsp+0h] [rbp-138h] BYREF
char v6[56]; // [rsp+100h] [rbp-38h] BYREF

result = is_check(a1, a2);
if ( (_DWORD)result )
{
fc_mlist_init(v6);
fc_board_get_all_moves(a1, v6, (unsigned int)a2);
for ( i = 0; (int)fc_mlist_length(v6) > i; ++i )
{
fc_board_copy(v5, a1);
v4 = fc_mlist_get(v6, (unsigned int)i);
fc_board_make_move(v5, v4);
if ( !is_check(v5, (unsigned int)a2) && (!is_check(v5, ((_BYTE)a2 + 2) & 3) || is_check(a1, ((_BYTE)a2 + 2) & 3)) )
{
fc_mlist_free(v6);
return 1LL;
}
}
fc_mlist_free(v6);
result = 2LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func14(_QWORD *a1, __int64 a2)
{
__int64 result; // rax
int i; // ebx
__int64 v4; // rax
_QWORD v5[32]; // [rsp+0h] [rbp-138h] BYREF
char v6[56]; // [rsp+100h] [rbp-38h] BYREF

result = func13(a1, a2);
if ( (_DWORD)result )
{
fc_mlist_init(v6);
fc_board_get_all_moves(a1, v6, (unsigned int)a2);
for ( i = 0; (int)fc_mlist_length(v6) > i; ++i )
{
fc_board_copy(v5, a1);
v4 = fc_mlist_get(v6, (unsigned int)i);
fc_board_make_move(v5, v4);
if ( !func13(v5, (unsigned int)a2) && (!func13(v5, ((_BYTE)a2 + 2) & 3) || func13(a1, ((_BYTE)a2 + 2) & 3)) )
{
fc_mlist_free(v6);
return 1LL;
}
}
fc_mlist_free(v6);
result = 2LL;
}
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]; }

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; } *


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

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

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

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; // ebp
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 <= 102 )
{
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 )
{
puts("\n[ERROR] parsing of data file failed.");
v4 = 5;
}
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; // ebp
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 <= 102 )
{
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 )
{
puts("\n[ERROR] parsing of data file failed.");
v4 = 5;
}
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()
{
_QWORD *v0; // r14
_QWORD *v1; // r13
unsigned int v2; // er12
char **v3; // rbx
char *v4; // rax
int v5; // eax
_QWORD *v6; // rbx
_QWORD *v7; // rax
char *v9; // [rsp+0h] [rbp-458h]
char *nptr[5]; // [rsp+8h] [rbp-450h] BYREF
char s[1064]; // [rsp+30h] [rbp-428h] BYREF

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

canonical_decompiled_code:
_QWORD *func7()
{
_QWORD *v0; // r14
_QWORD *v1; // r13
unsigned int v2; // er12
char **v3; // rbx
char *v4; // rax
int v5; // eax
_QWORD *v6; // rbx
_QWORD *v7; // rax
char *v9; // [rsp+0h] [rbp-458h]
char *nptr[5]; // [rsp+8h] [rbp-450h] BYREF
char s[1064]; // [rsp+30h] [rbp-428h] BYREF

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

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)
{
_QWORD *i; // rbx
__int64 v5; // rbp

startParsing("ut.dat");
for ( i = buildOperationList(); i[1]; i = (_QWORD *)i[1] )
{
v5 = i[2];
printf(">%s", *(const char **)(v5 + 8));
if ( !strcmp(*(const char **)(v5 + 8), "open") )
printf("[%s]", *(const char **)(v5 + 16));
putchar(10);
}
return 0;
}

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

startParsing("ut.dat");
for ( i = func7(); i[1]; i = (_QWORD *)i[1] )
{
v5 = i[2];
printf(">%s", *(const char **)(v5 + 8));
if ( !strcmp(*(const char **)(v5 + 8), "open") )
printf("[%s]", *(const char **)(v5 + 16));
putchar(10);
}
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_t)sighandler);
__sysv_signal(2, (__sighandler_t)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 = 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_t)sighandler);
__sysv_signal(2, (__sighandler_t)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 = 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)
{
void *v2; // r12
const char **v3; // rbp
_QWORD *v4; // r13
void *v5; // rbx

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

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

v2 = 0LL;
if ( a1 > 0 )
{
v2 = malloc(0x58uLL);
memset(v2, 0, 0x58uLL);
strcpy((char *)v2, *a2);
++machine_count;
v3 = a2 + 1;
v4 = v2;
while ( v3 != &a2[(unsigned int)(a1 - 1) + 1] )
{
v5 = malloc(0x58uLL);
memset(v5, 0, 0x58uLL);
strcpy((char *)v5, *v3);
++machine_count;
if ( v2 )
v4[10] = v5;
else
v2 = v5;
++v3;
v4 = v5;
}
}
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) )
{
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 )
{
close(*((_DWORD *)i + 18));
}
else
{
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) )
{
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 )
{
close(*((_DWORD *)i + 18));
}
else
{
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()
{
__int64 v0; // rax
int v1; // edx
__int64 v3[3]; // [rsp+0h] [rbp-28h] BYREF
__int16 v4; // [rsp+18h] [rbp-10h]
char v5; // [rsp+1Ah] [rbp-Eh]

v3[0] = 0LL;
v3[1] = 0LL;
v3[2] = 0LL;
v4 = 0;
v5 = 0;
v0 = 0LL;
v1 = 0;
do
{
if ( *((_BYTE *)&flags + v0) )
*((_BYTE *)v3 + v1++) = v0 + 97;
++v0;
}
while ( v0 != 26 );
move_to_flags();
wclrtoeol(stdscr__NCURSES6_TINFO_5_0_19991023);
waddnstr(stdscr__NCURSES6_TINFO_5_0_19991023, (const char *)v3, -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()
{
_DWORD *v0; // rbx
__int64 v1; // rcx
char v2; // si
int v3; // edx
ssize_t result; // rax
int buf[3]; // [rsp+Ch] [rbp-Ch] BYREF

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

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

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

__sysv_signal(2, finish);
__sysv_signal(15, finish);
__sysv_signal(17, finish);
__sysv_signal(13, finish);
flags = 0LL;
qword_404128 = 0LL;
qword_404130 = 0LL;
word_404138 = 0;
initialize_children(argc - 1, argv + 1);
launch_clients();
getchar();
initscr();
keypad(stdscr__NCURSES6_TINFO_5_0_19991023, 1);
nonl();
noecho();
cbreak();
curs_set(0);
v3 = 0LL;
v4 = " ____ ____ ____ ____ ____ ____ _________ ____ ____ ____ ____ ____ ";
do
{
wmove(stdscr__NCURSES6_TINFO_5_0_19991023, v3, 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 )
{
v5 = wgetch(stdscr__NCURSES6_TINFO_5_0_19991023) - 97;
if ( (unsigned int)v5 <= 0x19 )
break;
error("Unsupported character");
}
if ( *((_BYTE *)&flags + v5) )
stop_flag(v5);
else
start_flag(v5);
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; // eax

__sysv_signal(2, finish);
__sysv_signal(15, finish);
__sysv_signal(17, finish);
__sysv_signal(13, finish);
flags = 0LL;
qword_404128 = 0LL;
qword_404130 = 0LL;
word_404138 = 0;
func9(argc - 1, argv + 1);
func10();
getchar();
initscr();
keypad(stdscr__NCURSES6_TINFO_5_0_19991023, 1);
nonl();
noecho();
cbreak();
curs_set(0);
v3 = 0LL;
v4 = " ____ ____ ____ ____ ____ ____ _________ ____ ____ ____ ____ ____ ";
do
{
wmove(stdscr__NCURSES6_TINFO_5_0_19991023, v3, 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 )
{
v5 = wgetch(stdscr__NCURSES6_TINFO_5_0_19991023) - 97;
if ( (unsigned int)v5 <= 0x19 )
break;
func14("Unsupported character");
}
if ( *((_BYTE *)&flags + v5) )
func12(v5);
else
func13(v5);
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; // edx
__int64 result; // rax

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

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

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

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


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

result = a3;
if ( a2 == 2 )
{
*(_DWORD *)(a1 + 120) = 2;
if ( !(_BYTE)a3 )
LOBYTE(result) = 32;
result = (unsigned __int8)result;
*(_DWORD *)(a1 + 128) = (unsigned __int8)result;
}
else if ( a2 > 2u )
{
if ( a2 == 3 )
{
*(_DWORD *)(a1 + 120) = 3;
result = 1LL;
if ( !(_BYTE)a3 )
LOBYTE(a3) = 1;
*(_DWORD *)(a1 + 128) = (unsigned __int8)a3;
}
else
{
*(_DWORD *)(a1 + 120) = -1;
}
}
else if ( a2 )
{
*(_DWORD *)(a1 + 120) = 1;
if ( !(_BYTE)a3 )
LOBYTE(result) = 32;
result = (unsigned __int8)result;
*(_DWORD *)(a1 + 128) = (unsigned __int8)result;
}
else
{
*(_DWORD *)(a1 + 120) = 0;
*(_DWORD *)(a1 + 128) = (unsigned __int8)a3;
}
return result;
}

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

result = a3;
if ( a2 == 2 )
{
*(_DWORD *)(a1 + 120) = 2;
if ( !(_BYTE)a3 )
LOBYTE(result) = 32;
result = (unsigned __int8)result;
*(_DWORD *)(a1 + 128) = (unsigned __int8)result;
}
else if ( a2 > 2u )
{
if ( a2 == 3 )
{
*(_DWORD *)(a1 + 120) = 3;
result = 1LL;
if ( !(_BYTE)a3 )
LOBYTE(a3) = 1;
*(_DWORD *)(a1 + 128) = (unsigned __int8)a3;
}
else
{
*(_DWORD *)(a1 + 120) = -1;
}
}
else if ( a2 )
{
*(_DWORD *)(a1 + 120) = 1;
if ( !(_BYTE)a3 )
LOBYTE(result) = 32;
result = (unsigned __int8)result;
*(_DWORD *)(a1 + 128) = (unsigned __int8)result;
}
else
{
*(_DWORD *)(a1 + 120) = 0;
*(_DWORD *)(a1 + 128) = (unsigned __int8)a3;
}
return result;
}

original_code:
void thumb2_decode_immshift(darm_t *d, uint8_t type, uint8_t imm5)
{
    switch (type) {
    case 0:
        d->shift_type = S_LSL;
        d->shift = imm5;
        break;
    case 1:
        d->shift_type = S_LSR;
        d->shift = imm5 == 0 ? 32 : imm5;
        break;
    case 2:
        d->shift_type = S_ASR;
        d->shift = imm5 == 0 ? 32 : imm5;
        break;
    case 3:
        d->shift_type = S_ROR;
        d->shift = imm5 == 0 ? 1 : imm5;
        break;
    default:
        d->shift_type = S_INVLD;
        break;
    }
}

canonical_original_code:
void thumb2_decode_immshift(struct _darm_t *d, unsigned char type, unsigned char imm5)
{
    switch (type) {
    case 0:
        d->shift_type = S_LSL;
        d->shift = imm5;
        break;
    case 1:
        d->shift_type = S_LSR;
        d->shift = imm5 == 0 ? 32 : imm5;
        break;
    case 2:
        d->shift_type = S_ASR;
        d->shift = imm5 == 0 ? 32 : imm5;
        break;
    case 3:
        d->shift_type = S_ROR;
        d->shift = imm5 == 0 ? 1 : imm5;
        break;
    default:
        d->shift_type = S_INVLD;
        break;
    }
}

variable_types:
type
unsigned char

user_defined_types: struct _darm_t { unsigned int w; enum _darm_instr_t instr; enum _darm_enctype_t instr_type; enum _darm_enctype_t instr_imm_type; enum _darm_enctype_t instr_flag_type; enum _darm_cond_t cond; unsigned int B; unsigned int S; unsigned int E; unsigned int M; unsigned int N; enum _darm_option_t option; unsigned int U; unsigned int H; unsigned int P; unsigned int R; unsigned int T; unsigned int W; unsigned int I; unsigned int rotate; enum _darm_reg_t Rd; enum _darm_reg_t Rn; enum _darm_reg_t Rm; enum _darm_reg_t Ra; enum _darm_reg_t Rt; enum _darm_reg_t Rt2; enum _darm_reg_t RdHi; enum _darm_reg_t RdLo; unsigned int imm; unsigned int sat_imm; enum _darm_shift_type_t shift_type; enum _darm_reg_t Rs; unsigned int shift; unsigned int lsb; unsigned int msb; unsigned int width; unsigned short reglist; unsigned char coproc; unsigned char opc1; unsigned char opc2; enum _darm_reg_t CRd; enum _darm_reg_t CRn; enum _darm_reg_t CRm; unsigned int D; enum _darm_cond_t firstcond; unsigned char mask; }

user_defined_types: enum _darm_enctype_t { T_INVLD=0, T_ARM_ADR=1, T_ARM_UNCOND=2, T_ARM_MUL=3, T_ARM_STACK0=4, T_ARM_STACK1=5, T_ARM_STACK2=6, T_ARM_ARITH_SHIFT=7, T_ARM_ARITH_IMM=8, T_ARM_BITS=9, T_ARM_BRNCHSC=10, T_ARM_BRNCHMISC=11, T_ARM_MOV_IMM=12, T_ARM_CMP_OP=13, T_ARM_CMP_IMM=14, T_ARM_OPLESS=15, T_ARM_DST_SRC=16, T_ARM_LDSTREGS=17, T_ARM_BITREV=18, T_ARM_MISC=19, T_ARM_SM=20, T_ARM_PAS=21, T_ARM_SAT=22, T_ARM_SYNC=23, T_ARM_PUSR=24, T_ARM_MVCR=25, T_ARM_UDF=26, T_THUMB_ONLY_IMM8=27, T_THUMB_COND_BRANCH=28, T_THUMB_UNCOND_BRANCH=29, T_THUMB_SHIFT_IMM=30, T_THUMB_STACK=31, T_THUMB_LDR_PC=32, T_THUMB_GPI=33, T_THUMB_BRANCH_REG=34, T_THUMB_IT_HINTS=35, T_THUMB_HAS_IMM8=36, T_THUMB_EXTEND=37, T_THUMB_MOD_SP_IMM=38, T_THUMB_3REG=39, T_THUMB_2REG_IMM=40, T_THUMB_ADD_SP_IMM=41, T_THUMB_MOV4=42, T_THUMB_RW_MEMI=43, T_THUMB_RW_MEMO=44, T_THUMB_RW_REG=45, T_THUMB_REV=46, T_THUMB_SETEND=47, T_THUMB_PUSHPOP=48, T_THUMB_CMP=49, T_THUMB_MOD_SP_REG=50, T_THUMB_CBZ=51, T_THUMB2_NO_REG=52, T_THUMB2_RT_REG=53, T_THUMB2_RT_RT2_REG=54, T_THUMB2_RM_REG=55, T_THUMB2_RD_REG=56, T_THUMB2_RD_RM_REG=57, T_THUMB2_RN_REG=58, T_THUMB2_RN_RT_REG=59, T_THUMB2_RN_RT_RT2_REG=60, T_THUMB2_RN_RM_REG=61, T_THUMB2_RN_RM_RT_REG=62, T_THUMB2_RN_RD_REG=63, T_THUMB2_RN_RD_RT_REG=64, T_THUMB2_RN_RD_RT_RT2_REG=65, T_THUMB2_RN_RD_RM_REG=66, T_THUMB2_RN_RD_RM_RA_REG=67, T_THUMB2_NO_IMM=68, T_THUMB2_IMM12=69, T_THUMB2_IMM8=70, T_THUMB2_IMM2=71, T_THUMB2_IMM2_IMM3=72, T_THUMB2_IMM1_IMM3_IMM8=73, T_THUMB2_NO_FLAG=74, T_THUMB2_ROTATE_FLAG=75, T_THUMB2_U_FLAG=76, T_THUMB2_WUP_FLAG=77, T_THUMB2_TYPE_FLAG=78, T_THUMB2_REGLIST_FLAG=79, T_THUMB2_WP_REGLIST_FLAG=80, T_THUMB2_S_FLAG=81, T_THUMB2_S_TYPE_FLAG=82 }

user_defined_types: enum _darm_cond_t { C_EQ=0, C_NE=1, C_CS=2, C_CC=3, C_MI=4, C_PL=5, C_VS=6, C_VC=7, C_HI=8, C_LS=9, C_GE=10, C_LT=11, C_GT=12, C_LE=13, C_AL=14, C_HS=expr, C_LO=expr, C_UNCOND=15, C_INVLD=-1 }

user_defined_types: enum _darm_option_t { O_SY=15, O_ST=14, O_ISH=11, O_ISHST=10, O_NSH=7, O_NSHST=6, O_OSH=3, O_OSHST=2, O_INVLD=-1 }

user_defined_types: enum _darm_shift_type_t { S_LSL=0, S_LSR=1, S_ASR=2, S_ROR=3, S_INVLD=-1 }