# Path: lib/StartVal.py
# ASSEMBLER_64 = 64
# ASSEMBLER_32 = 32
# 
# Path: lib/Register.py
# def get_reg_class(reg):
#     """
#     @brief Determines the register class of a given reg.
#     All different register names that address the same register
#     belong to the same register class e.g.: 'ax' and 'eax'
#     @param reg name of register
#     @return register class
#     """
#     lreg = reg.lower()
#     ret_value = None
#     for pos, reg_list in enumerate(_registerClasses):
#         for reg in reg_list:
#             found = False
#             if reg == lreg:
#                 found = True
#                 ret_value = pos
#                 break
#         if found:
#             break
#     return ret_value
# 
# def get_reg_by_size(reg_class, reg_size):
#     """
#     @brief Determines the register by its size and class
#     @param reg_class The register class of the register
#     @param reg_size The size of the register
#     @return Name of the register
#     """
#     if reg_class >= len(_registerClasses):
#         return None
#     num_regs = len(_registerClasses[reg_class])
#     if num_regs < 4:
#         return None
#     reg_index = -1
#     if reg_size > 32: # 64-bit regs
#         reg_index = num_regs - 1
#     elif reg_size > 16: # 32-bit regs
#         reg_index = num_regs - 2
#     elif reg_size > 8: # 16-bit regs
#         reg_index = num_regs - 3
#     elif reg_size > 0: # 8-bit regs
#         reg_index = 0
#     else:
#         return None
#     return _registerClasses[reg_class][reg_index]


import lib.PseudoInstruction as PI
from lib import StartVal as SV
from lib.Register import (get_reg_class, get_reg_by_size)
    @brief Starts recursiv search for jmp addresses
    @param pp_lst List of PseudoInstructions push/pop represtentation
    @param jmp_pos Index of jump instruction
    @return List of Tuple: (position of jump addr, address of jump instruction)
    """
    jmp_inst = pp_lst[jmp_pos]
    if jmp_inst.list_len == 0:
        print 'could not find jmp address'
        return []
    jmp_op = jmp_inst.op_lst[0]
    pos_lst = rec_find_addr(pp_lst, jmp_pos, jmp_op, 20)
    ret_lst = []
    for x in pos_lst:
        ret_lst.append((x, pp_lst[jmp_pos].addr))
    return ret_lst


def rec_find_addr(pp_lst, pos, op, max_rec_depth):
    """
    @brief Recursiv search for finding jmp addresses
    @param pp_lst List of PseudoInstructions push/pop represtentation
    @param pos Index of jump instruction
    @param op Operand of jump instruction
    @param max_rec_depth Maximal recursion depth
    @return List positions which are used to calc jump address
    """
    if max_rec_depth == 0:
        return []
    if(op.type == PI.IMMEDIATE_T or
       (op.type == PI.REGISTER_T and

# Path: lib/StartVal.py
# ASSEMBLER_64 = 64
# ASSEMBLER_32 = 32
# 
# Path: lib/Register.py
# def get_reg_class(reg):
#     """
#     @brief Determines the register class of a given reg.
#     All different register names that address the same register
#     belong to the same register class e.g.: 'ax' and 'eax'
#     @param reg name of register
#     @return register class
#     """
#     lreg = reg.lower()
#     ret_value = None
#     for pos, reg_list in enumerate(_registerClasses):
#         for reg in reg_list:
#             found = False
#             if reg == lreg:
#                 found = True
#                 ret_value = pos
#                 break
#         if found:
#             break
#     return ret_value
# 
# def get_reg_by_size(reg_class, reg_size):
#     """
#     @brief Determines the register by its size and class
#     @param reg_class The register class of the register
#     @param reg_size The size of the register
#     @return Name of the register
#     """
#     if reg_class >= len(_registerClasses):
#         return None
#     num_regs = len(_registerClasses[reg_class])
#     if num_regs < 4:
#         return None
#     reg_index = -1
#     if reg_size > 32: # 64-bit regs
#         reg_index = num_regs - 1
#     elif reg_size > 16: # 32-bit regs
#         reg_index = num_regs - 2
#     elif reg_size > 8: # 16-bit regs
#         reg_index = num_regs - 3
#     elif reg_size > 0: # 8-bit regs
#         reg_index = 0
#     else:
#         return None
#     return _registerClasses[reg_class][reg_index]


# Path: lib/Optimize.py
import lib.PseudoInstruction as PI
from lib import StartVal as SV
from lib.Register import (get_reg_class, get_reg_by_size)

    @brief Starts recursiv search for jmp addresses
    @param pp_lst List of PseudoInstructions push/pop represtentation
    @param jmp_pos Index of jump instruction
    @return List of Tuple: (position of jump addr, address of jump instruction)
    """
    jmp_inst = pp_lst[jmp_pos]
    if jmp_inst.list_len == 0:
        print 'could not find jmp address'
        return []
    jmp_op = jmp_inst.op_lst[0]
    pos_lst = rec_find_addr(pp_lst, jmp_pos, jmp_op, 20)
    ret_lst = []
    for x in pos_lst:
        ret_lst.append((x, pp_lst[jmp_pos].addr))
    return ret_lst


def rec_find_addr(pp_lst, pos, op, max_rec_depth):
    """
    @brief Recursiv search for finding jmp addresses
    @param pp_lst List of PseudoInstructions push/pop represtentation
    @param pos Index of jump instruction
    @param op Operand of jump instruction
    @param max_rec_depth Maximal recursion depth
    @return List positions which are used to calc jump address
    """
    if max_rec_depth == 0:
        return []
    if(op.type == PI.IMMEDIATE_T or
       (op.type == PI.REGISTER_T and

        get_reg_class(op.register) == get_reg_class('ebp'))):