# Path: python/disassemblylib/util.py
# def memoize(function):
#     def wrapper(*args):
# def make_operand_mask(mask_string):
# def _make_specification(format):
#     def get_substitution_vars(s):
# def process_instruction_list(_A, _list):
#     def __init__(self, api_state):
# def _unimplemented_function(*args, **kwargs): raise NotImplementedError("arch-function-undefined")
#     def function_get_match_addresses(self, match: Match) -> List[Tuple[int, int, int]]: _unimplemented_function()
#     def function_disassemble_one_line(self, data, data_idx, data_abs_idx):
#     def function_is_operand_pointer_sized(self, instruction):
#     def set_instruction_table(self, table_data):
#     def set_operand_type_table(self, table_data):
#     def create_duplicated_instruction_entries(self, entry, new_name, operands_string):
#     def get_extra_words_for_size_char(self, size_char):
#     def _signed_value(self, value, bits):
#     def _get_word(self, data, data_idx):
#     def _get_value(self, data, data_idx, bits, signed):
#     def _match_instructions(self, data, data_idx, data_abs_idx):
#         def get_instruction_format_parts(instr_format):
#     def _disassemble_vars_pass(self, I):
#         def copy_values(mask_char_vars, char_vars):
#     def binary2number(s):
# def number2binary(v, dynamic_padding=False, padded_length=None):
# def signed_hex_string(_arch, v):
# def get_mask_and_shift_from_mask_string(mask_string, mask_char):
# def get_masked_value_for_variable(base_value, mask_string, mask_char):
# def set_masked_value_for_variable(base_value, mask_string, mask_char, value):
# def update_mask_string(mask_string, mask_char, value):
# def get_mask_variables(mask_string):
# def get_masked_values_for_variables(value, mask_string, variable_chars=None):
# def generate_all():
# II_MASK = 0
# II_NAME = 1
# II_FLAGS = 2
# II_TEXT = 3
# II_ANDMASK = 4
# II_CMPMASK = 5
# II_EXTRAWORDS = 6
# II_OPERANDMASKS = 7
# II_LENGTH = 8
# IFX_BRANCH    = 1<<29       # Indicates points to code reference to follow when disassembling.  TODO: Better name?
# IFX_ENDSEQ    = 1<<30       # Indicates the end of a sequence of instructions.
# IFX_ENDSEQ_BD = 1<<31       # Indicates the end of a sequence of instructions.  Next instruction is still executed on the way (the branch delay slot).
# EAMI_LABEL = 0
# EAMI_FORMAT = 1
# EAMI_MATCH_FIELDS = 2
# EAMI_DATA_FIELDS = 3
# EAMI_DESCRIPTION = 4
#         M = None
#                 M = Match()
#                     T = MatchOpcode()
# MAF_CODE = 1
# MAF_ABSOLUTE_ADDRESS = 2
# MAF_CONSTANT_VALUE = 4
# MAF_UNCERTAIN = 8
# MAF_CERTAIN = 16
# class Match(object):
# class MatchOpcode(object):
# class Specification(object):
# class IntrospectionHelperInterface(object):
# class ArchInterface(object):


import logging
from typing import List
from .util import ArchInterface, _b2n, _n2b, IFX_ENDSEQ_BD, IFX_BRANCH, IFX_ENDSEQ, II_NAME, II_MASK, MAF_CERTAIN, MAF_CODE, EAMI_FORMAT
"""
    Peasauce - interactive disassembler
    Copyright (C) 2012-2017 Richard Tew
    Licensed using the MIT license.
"""

# TODO: Support MIPS16
# TODO: is_final_instruction() - Work out if there are any instructions other than branches and jumps, where PC or LR or whatever is changed directly.  ra?



logger = logging.getLogger("disassembler-mips")

# Flags to indicate which architecture variant the instruction belongs to.
IF_MIPS32     = 1<<0
IF_MIPS32R2   = 1<<1
IF_MIPS64     = 1<<2
IF_SMARTMIPS  = 1<<3
IF_EJTAG      = 1<<4



# Path: python/disassemblylib/util.py
# def memoize(function):
#     def wrapper(*args):
# def make_operand_mask(mask_string):
# def _make_specification(format):
#     def get_substitution_vars(s):
# def process_instruction_list(_A, _list):
#     def __init__(self, api_state):
# def _unimplemented_function(*args, **kwargs): raise NotImplementedError("arch-function-undefined")
#     def function_get_match_addresses(self, match: Match) -> List[Tuple[int, int, int]]: _unimplemented_function()
#     def function_disassemble_one_line(self, data, data_idx, data_abs_idx):
#     def function_is_operand_pointer_sized(self, instruction):
#     def set_instruction_table(self, table_data):
#     def set_operand_type_table(self, table_data):
#     def create_duplicated_instruction_entries(self, entry, new_name, operands_string):
#     def get_extra_words_for_size_char(self, size_char):
#     def _signed_value(self, value, bits):
#     def _get_word(self, data, data_idx):
#     def _get_value(self, data, data_idx, bits, signed):
#     def _match_instructions(self, data, data_idx, data_abs_idx):
#         def get_instruction_format_parts(instr_format):
#     def _disassemble_vars_pass(self, I):
#         def copy_values(mask_char_vars, char_vars):
#     def binary2number(s):
# def number2binary(v, dynamic_padding=False, padded_length=None):
# def signed_hex_string(_arch, v):
# def get_mask_and_shift_from_mask_string(mask_string, mask_char):
# def get_masked_value_for_variable(base_value, mask_string, mask_char):
# def set_masked_value_for_variable(base_value, mask_string, mask_char, value):
# def update_mask_string(mask_string, mask_char, value):
# def get_mask_variables(mask_string):
# def get_masked_values_for_variables(value, mask_string, variable_chars=None):
# def generate_all():
# II_MASK = 0
# II_NAME = 1
# II_FLAGS = 2
# II_TEXT = 3
# II_ANDMASK = 4
# II_CMPMASK = 5
# II_EXTRAWORDS = 6
# II_OPERANDMASKS = 7
# II_LENGTH = 8
# IFX_BRANCH    = 1<<29       # Indicates points to code reference to follow when disassembling.  TODO: Better name?
# IFX_ENDSEQ    = 1<<30       # Indicates the end of a sequence of instructions.
# IFX_ENDSEQ_BD = 1<<31       # Indicates the end of a sequence of instructions.  Next instruction is still executed on the way (the branch delay slot).
# EAMI_LABEL = 0
# EAMI_FORMAT = 1
# EAMI_MATCH_FIELDS = 2
# EAMI_DATA_FIELDS = 3
# EAMI_DESCRIPTION = 4
#         M = None
#                 M = Match()
#                     T = MatchOpcode()
# MAF_CODE = 1
# MAF_ABSOLUTE_ADDRESS = 2
# MAF_CONSTANT_VALUE = 4
# MAF_UNCERTAIN = 8
# MAF_CERTAIN = 16
# class Match(object):
# class MatchOpcode(object):
# class Specification(object):
# class IntrospectionHelperInterface(object):
# class ArchInterface(object):


# Path: python/disassemblylib/archmips.py
import logging
from typing import List
from .util import ArchInterface, _b2n, _n2b, IFX_ENDSEQ_BD, IFX_BRANCH, IFX_ENDSEQ, II_NAME, II_MASK, MAF_CERTAIN, MAF_CODE, EAMI_FORMAT

"""
    Peasauce - interactive disassembler
    Copyright (C) 2012-2017 Richard Tew
    Licensed using the MIT license.
"""

# TODO: Support MIPS16
# TODO: is_final_instruction() - Work out if there are any instructions other than branches and jumps, where PC or LR or whatever is changed directly.  ra?



logger = logging.getLogger("disassembler-mips")

# Flags to indicate which architecture variant the instruction belongs to.
IF_MIPS32     = 1<<0
IF_MIPS32R2   = 1<<1
IF_MIPS64     = 1<<2
IF_SMARTMIPS  = 1<<3
IF_EJTAG      = 1<<4



class ArchMIPS(ArchInterface):