# 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)
                    if (((not is_mov_ebp(ps_lst, 0, pos)) and
                        is_mov_ebp(ps_lst, 0, len(ps_lst)-1)) or
                        not has_loc):
                        val_arr.append(PI.PseudoOperand(PI.EXP_T, 'RET_ADDR', 0))
                        val_arr.append(PI.PseudoOperand(PI.EXP_T, 'ARGS', 0))
                new_op = PI.ArrayOperand(
                            PI.ARRAY_T, ps_lst[push_poss[0]].size,
                            len(val_arr), val_arr)
                new_inst = PI.PseudoInstruction(
                    item.mnem, item.addr,
                    [new_op], item.size,
                    item.inst_type, item.inst_class)
                #new_inst.comment = comment
                ret.append(new_inst)
        else:
            ret.append(item)
    return ret


#just do this after reduction
def return_push_ebp(ps_lst):
    """
    @brief Replace all array operands, which are not part of an assignement,
    with 'push ebp' or 'push rbp'
    @param ps_lst List of PseudoInstructions
    @remark Just do this after 'replace_push_ebp' and 'reduce_assignements'
    """
    for inst in ps_lst:
        if (inst.inst_type == PI.PUSH_T and
            inst.op_lst[0].type == PI.ARRAY_T):

# 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)

                    if (((not is_mov_ebp(ps_lst, 0, pos)) and
                        is_mov_ebp(ps_lst, 0, len(ps_lst)-1)) or
                        not has_loc):
                        val_arr.append(PI.PseudoOperand(PI.EXP_T, 'RET_ADDR', 0))
                        val_arr.append(PI.PseudoOperand(PI.EXP_T, 'ARGS', 0))
                new_op = PI.ArrayOperand(
                            PI.ARRAY_T, ps_lst[push_poss[0]].size,
                            len(val_arr), val_arr)
                new_inst = PI.PseudoInstruction(
                    item.mnem, item.addr,
                    [new_op], item.size,
                    item.inst_type, item.inst_class)
                #new_inst.comment = comment
                ret.append(new_inst)
        else:
            ret.append(item)
    return ret


#just do this after reduction
def return_push_ebp(ps_lst):
    """
    @brief Replace all array operands, which are not part of an assignement,
    with 'push ebp' or 'push rbp'
    @param ps_lst List of PseudoInstructions
    @remark Just do this after 'replace_push_ebp' and 'reduce_assignements'
    """
    for inst in ps_lst:
        if (inst.inst_type == PI.PUSH_T and
            inst.op_lst[0].type == PI.ARRAY_T):

            reg_class = get_reg_class('ebp')