diff options
Diffstat (limited to 'miasm/arch/mep/arch.py')
| -rw-r--r-- | miasm/arch/mep/arch.py | 2080 |
1 files changed, 0 insertions, 2080 deletions
diff --git a/miasm/arch/mep/arch.py b/miasm/arch/mep/arch.py deleted file mode 100644 index ed7813ca..00000000 --- a/miasm/arch/mep/arch.py +++ /dev/null @@ -1,2080 +0,0 @@ -# Toshiba MeP-c4 - miasm architecture definition -# Guillaume Valadon <guillaume@valadon.net> - -from builtins import range -from miasm.core.cpu import * -from miasm.core.utils import Disasm_Exception -from miasm.expression.expression import ExprId, ExprInt, ExprLoc, \ - ExprMem, ExprOp, is_expr -from miasm.core.asm_ast import AstId, AstMem - -from miasm.arch.mep.regs import * -import miasm.arch.mep.regs as mep_regs_module # will be used to set mn_mep.regs -from miasm.ir.ir import color_expr_html - - -# Note: pyparsing is used to alter the way special operands are parsed -from pyparsing import Literal, Group, Word, hexnums - - -# These definitions will help parsing dereferencing instructions (i.e. that uses -# parenthesis) with pyparsing -LPARENTHESIS = Literal("(") -RPARENTHESIS = Literal(")") -PLUSSIGN = Literal("+") -HEX_INTEGER = str_int_pos | str_int_neg - - -def ExprInt2SignedString(expr, pos_fmt="%d", neg_fmt="%d", size=None, offset=0): - """Return the signed string corresponding to an ExprInt - - Note: this function is only useful to mimic objdump output""" - - # Apply a mask to the integer - if size is None: - mask_length = expr.size - else: - mask_length = size - mask = (1 << mask_length) - 1 - value = int(expr) & mask - - # Return a signed integer if necessary - if (value >> mask_length - 1) == 1: - value = offset - ((value ^ mask) + 1) - if value < 0: - return "-" + neg_fmt % -value - else: - value += offset - - return pos_fmt % value - - -class instruction_mep(instruction): - """Generic MeP-c4 instruction - - Notes: - - this object is used to build internal miasm instructions based - on mnemonics - - it must be implemented ! - """ - - @staticmethod - def arg2str(expr, pos=None, loc_db=None): - """Convert mnemonics arguments into readable strings according to the - MeP-c4 architecture manual and their internal types - - Notes: - - it must be implemented ! However, a simple 'return str(expr)' - could do the trick. - - it is used to mimic objdump output - - Args: - expr: argument as a miasm expression - pos: position index in the arguments list - """ - - if isinstance(expr, ExprId) or isinstance(expr, ExprInt): - return str(expr) - - elif isinstance(expr, ExprLoc): - if loc_db is not None: - return loc_db.pretty_str(expr.loc_key) - else: - return str(expr) - - elif isinstance(expr, ExprMem) and (isinstance(expr.ptr, ExprId) or isinstance(expr.ptr, ExprInt)): - return "(%s)" % expr.ptr - - elif isinstance(expr, ExprMem) and isinstance(expr.ptr, ExprOp): - return "0x%X(%s)" % (int(expr.ptr.args[1]), expr.ptr.args[0]) - - # Raise an exception if the expression type was not processed - message = "instruction_mep.arg2str(): don't know what \ - to do with a '%s' instance." % type(expr) - raise Disasm_Exception(message) - - @staticmethod - def arg2html(expr, pos=None, loc_db=None): - """Convert mnemonics arguments into readable html strings according to the - MeP-c4 architecture manual and their internal types - - Notes: - - it must be implemented ! However, a simple 'return str(expr)' - could do the trick. - - it is used to mimic objdump output - - Args: - expr: argument as a miasm expression - pos: position index in the arguments list - """ - - if isinstance(expr, ExprId) or isinstance(expr, ExprInt) or isinstance(expr, ExprLoc): - return color_expr_html(expr, loc_db) - - elif isinstance(expr, ExprMem) and (isinstance(expr.ptr, ExprId) or isinstance(expr.ptr, ExprInt)): - return "(%s)" % color_expr_html(expr.ptr, loc_db) - - elif isinstance(expr, ExprMem) and isinstance(expr.ptr, ExprOp): - return "%s(%s)" % ( - color_expr_html(expr.ptr.args[1], loc_db), - color_expr_html(expr.ptr.args[0], loc_db) - ) - - # Raise an exception if the expression type was not processed - message = "instruction_mep.arg2str(): don't know what \ - to do with a '%s' instance." % type(expr) - raise Disasm_Exception(message) - - def __str__(self): - """Return the mnemonic as a string. - - Note: - - it is not mandatory as the instruction class already implement - it. It used to get rid of the padding between the opcode and the - arguments. - - most of this code is copied from miasm/core/cpu.py - """ - - o = "%s" % self.name - - if self.name == "SSARB": - # The first operand is displayed in decimal, not in hex - o += " %d" % int(self.args[0]) - o += self.arg2str(self.args[1]) - - elif self.name in ["MOV", "ADD"] and isinstance(self.args[1], ExprInt): - # The second operand is displayed in decimal, not in hex - o += " " + self.arg2str(self.args[0]) - o += ", %s" % ExprInt2SignedString(self.args[1]) - - elif "CPI" in self.name: - # The second operand ends with the '+' sign - o += " " + self.arg2str(self.args[0]) - deref_reg_str = self.arg2str(self.args[1]) - o += ", %s+)" % deref_reg_str[:-1] # GV: looks ugly - - elif self.name[0] in ["S", "L"] and self.name[-3:] in ["CPA", "PM0", "PM1"]: - # The second operand ends with the '+' sign - o += " " + self.arg2str(self.args[0]) - deref_reg_str = self.arg2str(self.args[1]) - o += ", %s+)" % deref_reg_str[:-1] # GV: looks ugly - # The third operand is displayed in decimal, not in hex - o += ", %s" % ExprInt2SignedString(self.args[2]) - - elif len(self.args) == 2 and self.name in ["SB", "SH", "LBU", "LB", "LH", "LW"] and \ - isinstance(self.args[1], ExprMem) and isinstance(self.args[1].ptr, ExprOp): # Major Opcodes #12 - # The second operand is an offset to a register - o += " " + self.arg2str(self.args[0]) - o += ", %s" % ExprInt2SignedString(self.args[1].ptr.args[1], "0x%X") - o += "(%s)" % self.arg2str(self.args[1].ptr.args[0]) - - elif len(self.args) == 2 and self.name in ["SWCP", "LWCP", "SMCP", "LMCP"] \ - and isinstance(self.args[1], ExprMem) and isinstance(self.args[1].ptr, ExprOp): # Major Opcodes #12 - # The second operand is an offset to a register - o += " " + self.arg2str(self.args[0]) - o += ", %s" % ExprInt2SignedString(self.args[1].ptr.args[1]) - o += "(%s)" % self.arg2str(self.args[1].ptr.args[0]) - - elif self.name == "SLL" and isinstance(self.args[1], ExprInt): # Major Opcodes #6 - # The second operand is displayed in hex, not in decimal - o += " " + self.arg2str(self.args[0]) - o += ", 0x%X" % int(self.args[1]) - - elif self.name in ["ADD3", "SLT3"] and isinstance(self.args[2], ExprInt): - o += " %s" % self.arg2str(self.args[0]) - o += ", %s" % self.arg2str(self.args[1]) - # The third operand is displayed in decimal, not in hex - o += ", %s" % ExprInt2SignedString(self.args[2], pos_fmt="0x%X") - - elif self.name == "(RI)": - return o - - else: - args = [] - if self.args: - o += " " - for i, arg in enumerate(self.args): - if not is_expr(arg): - raise ValueError('zarb arg type') - x = self.arg2str(arg, pos=i) - args.append(x) - o += self.gen_args(args) - - return o - - def breakflow(self): - """Instructions that stop a basic block.""" - - if self.name in ["BRA", "BEQZ", "BNEZ", "BEQI", "BNEI", "BLTI", "BGEI", "BEQ", "BNE", "BSR"]: - return True - - if self.name in ["JMP", "JSR", "RET"]: - return True - - if self.name in ["RETI", "HALT", "SLEEP"]: - return True - - return False - - def splitflow(self): - """Instructions that splits a basic block, i.e. the CPU can go somewhere else.""" - - if self.name in ["BEQZ", "BNEZ", "BEQI", "BNEI", "BLTI", "BGEI", "BEQ", "BNE", "BSR"]: - return True - - return False - - def dstflow(self): - """Instructions that explicitly provide the destination.""" - - if self.name in ["BRA", "BEQZ", "BNEZ", "BEQI", "BNEI", "BLTI", "BGEI", "BEQ", "BNE", "BSR"]: - return True - - if self.name in ["JMP"]: - return True - - return False - - def dstflow2label(self, loc_db): - """Set the label for the current destination. - - Note: it is used at disassembly""" - - if self.name == "JMP" and isinstance(self.args[0], ExprId): - # 'JMP RM' does not provide the destination - return - - # Compute the correct address - num = self.get_dst_num() - addr = int(self.args[num]) - if not self.name == "JMP": - addr += self.offset - - # Get a new label at the address - label = loc_db.get_or_create_offset_location(addr) - - # Assign the label to the correct instruction argument - self.args[num] = ExprLoc(label, self.args[num].size) - - def get_dst_num(self): - """Get the index of the argument that points to the instruction destination.""" - - if self.name[-1] == "Z": - num = 1 - elif self.name in ["BEQI", "BNEI", "BLTI", "BGEI", "BEQ", "BNE"]: - num = 2 - else: - num = 0 - - return num - - def getdstflow(self, loc_db): - """Get the argument that points to the instruction destination.""" - - num = self.get_dst_num() - return [self.args[num]] - - def is_subcall(self): - """Instructions used to call sub functions.""" - - return self.name in ["JSR", "BSR"] - - def fixDstOffset(self): - """Fix/correct the instruction immediate according to the current offset - - Note: - it is used at assembly - - code inspired by miasm/arch/mips32/arch.py""" - - if self.name == "JMP" and isinstance(self.args[0], ExprInt): - # 'JMP IMMEDIATE' does not need to be fixed - return - - # Get the argument that needs to be fixed - if not len(self.args): - return - num = self.get_dst_num() - expr = self.args[num] - - # Check that the argument can be fixed - if self.offset is None: - raise ValueError("Symbol not resolved %s" % self.l) - if not isinstance(expr, ExprInt): - return - - # Adjust the immediate according to the current instruction offset - off = expr.arg - self.offset - if int(off % 2): - raise ValueError("Strange offset! %r" % off) - self.args[num] = ExprInt(off, 32) - - -class mep_additional_info(object): - """Additional MeP instructions information - """ - - def __init__(self): - self.except_on_instr = False - - -class mn_mep(cls_mn): - """Toshiba MeP-c4 disassembler & assembler - """ - - # Define variables that stores information used to disassemble & assemble - # Notes: - these variables are mandatory - # - they could be moved to the cls_mn class - - num = 0 # holds the number of mnemonics - - all_mn = list() # list of mnenomnics, converted to metamn objects - - all_mn_mode = defaultdict(list) # mneomnics, converted to metamn objects - # Note: - # - the key is the mode # GV: what is it ? - # - the data is a list of mnemonics - - all_mn_name = defaultdict(list) # mnenomnics strings - # Note: - # - the key is the mnemonic string - # - the data is the corresponding - # metamn object - - all_mn_inst = defaultdict(list) # mnemonics objects - # Note: - # - the key is the mnemonic Python class - # - the data is an instantiated object - - bintree = dict() # Variable storing internal values used to guess a - # mnemonic during disassembly - - # Defines the instruction set that will be used - instruction = instruction_mep - - # Python module that stores registers information - regs = mep_regs_module - - # Default delay slot - # Note: - # - mandatory for the miasm Machine - delayslot = 0 - - # Architecture name - name = "mep" - - # PC name depending on architecture attributes (here, l or b) - pc = {'l': PC, 'b': PC} - - def additional_info(self): - """Define instruction side effects # GV: not fully understood yet - - When used, it must return an object that implements specific - variables, such as except_on_instr. - - Notes: - - it must be implemented ! - - it could be moved to the cls_mn class - """ - - return mep_additional_info() - - @classmethod - def gen_modes(cls, subcls, name, bases, dct, fields): - """Ease populating internal variables used to disassemble & assemble, such - as self.all_mn_mode, self.all_mn_name and self.all_mn_inst - - Notes: - - it must be implemented ! - - it could be moved to the cls_mn class. All miasm architectures - use the same code - - Args: - cls: ? - sublcs: - name: mnemonic name - bases: ? - dct: ? - fields: ? - - Returns: - a list of ? - - """ - - dct["mode"] = None - return [(subcls, name, bases, dct, fields)] - - @classmethod - def getmn(cls, name): - """Get the mnemonic name - - Notes: - - it must be implemented ! - - it could be moved to the cls_mn class. Most miasm architectures - use the same code - - Args: - cls: the mnemonic class - name: the mnemonic string - """ - - return name.upper() - - @classmethod - def getpc(cls, attrib=None): - """"Return the ExprId that represents the Program Counter. - - Notes: - - mandatory for the symbolic execution - - PC is defined in regs.py - - Args: - attrib: architecture dependent attributes (here, l or b) - """ - - return PC - - @classmethod - def getsp(cls, attrib=None): - """"Return the ExprId that represents the Stack Pointer. - - Notes: - - mandatory for the symbolic execution - - SP is defined in regs.py - - Args: - attrib: architecture dependent attributes (here, l or b) - """ - - return SP - - @classmethod - def getbits(cls, bitstream, attrib, start, n): - """Return an integer of n bits at the 'start' offset - - Note: code from miasm/arch/mips32/arch.py - """ - - # Return zero if zero bits are requested - if not n: - return 0 - - o = 0 # the returned value - while n: - # Get a byte, the offset is adjusted according to the endianness - offset = start // 8 # the offset in bytes - n_offset = cls.endian_offset(attrib, offset) # the adjusted offset - c = cls.getbytes(bitstream, n_offset, 1) - if not c: - raise IOError - - # Extract the bits value - c = ord(c) - r = 8 - start % 8 - c &= (1 << r) - 1 - l = min(r, n) - c >>= (r - l) - o <<= l - o |= c - n -= l - start += l - - return o - - @classmethod - def endian_offset(cls, attrib, offset): - """Adjust the byte offset according to the endianness""" - - if attrib == "l": # Little Endian - if offset % 2: - return offset - 1 - else: - return offset + 1 - - elif attrib == "b": # Big Endian - return offset - - else: - raise NotImplementedError("Bad MeP endianness") - - def value(self, mode): - """Adjust the assembled instruction based on the endianness - - Note: code inspired by miasm/arch/mips32/arch.py - """ - - # Get the candidated - candidates = super(mn_mep, self).value(mode) - - if mode == "l": - # Invert bytes per 16-bits - for i in range(len(candidates)): - tmp = candidates[i][1] + candidates[i][0] - if len(candidates[i]) == 4: - tmp += candidates[i][3] + candidates[i][2] - candidates[i] = tmp - return candidates - - elif mode == "b": - return candidates - - else: - raise NotImplementedError("Bad MeP endianness (%s)" % mode) - - -def addop(name, fields, args=None, alias=False): - """Dynamically create the "name" object - - Notes: - - it could be moved to a generic function such as: - addop(name, fields, cls_mn, args=None, alias=False). - - most architectures use the same code - - Args: - name: the mnemonic name - fields: used to fill the object.__dict__'fields' attribute # GV: not understood yet - args: used to fill the object.__dict__'fields' attribute # GV: not understood yet - alias: used to fill the object.__dict__'fields' attribute # GV: not understood yet - """ - - namespace = {"fields": fields, "alias": alias} - - if args is not None: - namespace["args"] = args - - # Dynamically create the "name" object - type(name, (mn_mep,), namespace) - - -# Define specific operand parsers & converters - -def deref2expr(s, l, parse_results): - """Convert a parsed dereferenced register to an ExprMem""" - - # Only use the first results - parse_results = parse_results[0] - - if type(parse_results[0]) == AstInt and isinstance(parse_results[2], AstId): - return AstMem(parse_results[2] + parse_results[0], 32) # 1 == "(" and 3 == ")" - - elif type(parse_results[0]) == int and isinstance(parse_results[2], AstId): - return AstMem(parse_results[2] + AstOp('-', AstInt(-parse_results[0])), 32) # 1 == "(" and 3 == ")" - - else: - return AstMem(parse_results[1], 32) # 0 == "(" and 2 == ")" - - -deref_reg_parser = Group(LPARENTHESIS + gpr_infos.parser + RPARENTHESIS).setParseAction(deref2expr) -deref_inc_reg_parser = Group(LPARENTHESIS + gpr_infos.parser + PLUSSIGN + RPARENTHESIS).setParseAction(deref2expr) -abs24_deref_parser = Group(LPARENTHESIS + HEX_INTEGER + RPARENTHESIS).setParseAction(deref2expr) -offset_deref_reg_parser = Group(HEX_INTEGER + LPARENTHESIS + gpr_infos.parser + RPARENTHESIS).setParseAction(deref2expr) - -# Define registers decoders and encoders - -class mep_arg(m_arg): - def asm_ast_to_expr(self, arg, loc_db): - """Convert AST to expressions - - Note: - code inspired by miasm/arch/mips32/arch.py""" - - if isinstance(arg, AstId): - if isinstance(arg.name, ExprId): - return arg.name - if isinstance(arg.name, str) and arg.name in gpr_names: - return None # GV: why? - loc_key = loc_db.get_or_create_name_location(arg.name) - return ExprLoc(loc_key, 32) - - elif isinstance(arg, AstMem): - addr = self.asm_ast_to_expr(arg.ptr, loc_db) - if addr is None: - return None - return ExprMem(addr, 32) - - elif isinstance(arg, AstInt): - return ExprInt(arg.value, 32) - - elif isinstance(arg, AstOp): - args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] - if None in args: - return None - return ExprOp(arg.op, *args) - - # Raise an exception if the argument was not processed - message = "mep_arg.asm_ast_to_expr(): don't know what \ - to do with a '%s' instance." % type(arg) - raise Exception(message) - -class mep_reg(reg_noarg, mep_arg): - """Generic Toshiba MeP-c4 register - - Note: - - the register size will be set using bs() - """ - reg_info = gpr_infos # the list of MeP-c4 registers defined in regs.py - parser = reg_info.parser # GV: not understood yet - - -class mep_deref_reg(mep_arg): - """Generic Toshiba MeP-c4 dereferenced register - - Note: - - the arg2str() method could be defined to change the output string - """ - parser = deref_reg_parser - - def decode(self, v): - """Transform the decoded value to a ExprMem(ExprId()) expression""" - r = gpr_infos.expr[v] # get the ExprId, i.e. the register expression - self.expr = ExprMem(r, 32) - return True - - def encode(self): - """Ensure that we have a ExprMem(ExprId()) expression, and return the - register value.""" - - if not isinstance(self.expr, ExprMem): - return False - if not isinstance(self.expr.ptr, ExprId): - return False - - # Get the ExprId index, i.e. its value - self.value = gpr_exprs.index(self.expr.ptr) - return True - - -class mep_reg_sp(mep_reg): - """Dummy Toshiba MeP-c4 register that represents SP. It is used in - instructions that implicitly use SP, such as ADD3. - """ - implicit_reg = SP - - def decode(self, v): - """Always return 'implicit_reg.""" - self.expr = self.implicit_reg - return True - - def encode(self): - """Do nothing""" - return True - - -class mep_reg_tp(mep_reg_sp): - """Dummy Toshiba MeP-c4 register that represents TP. - """ - implicit_reg = TP - - -class mep_deref_reg_offset(mep_arg): - """Toshiba MeP-c4 dereferenced register that represents SP, plus an - offset. - """ - parser = offset_deref_reg_parser - - def decode(self, v): - """Modify the decoded value using the previously decoded - register id. - """ - - # Apply the immediate mask - se = sign_ext(v & 0xFFFF, 16, 32) # GV: might not belong here - int_id = ExprInt(se, 32) - - # Get the register expression - reg_id = gpr_infos.expr[self.parent.reg04_deref.value] - - # Build the internal expression - self.expr = ExprMem(reg_id + int_id, 32) - - return True - - def encode(self): - """Modify the encoded value. One part is stored in this object, and - the other one in reg04_deref. - """ - - # Verify the expression - if not isinstance(self.expr, ExprMem): - return False - if not isinstance(self.expr.ptr, ExprOp): - return False - - # Get the integer and check the upper bound - v = int(self.expr.ptr.args[1]) & 0xFFFF - - # Encode the values - self.parent.reg04_deref.value = gpr_exprs.index(self.expr.ptr.args[0]) - self.value = v & 0xFFFF - return True - - -class mep_deref_sp_offset(mep_deref_reg): - """Dummy Toshiba MeP-c4 dereferenced register that represents SP, plus an - offset. - Note: it is as generic as possible to ease its use in different instructions - """ - implicit_reg = SP - parser = offset_deref_reg_parser - - def decode(self, v): - """Modify the decoded value using the previously decoded - immediate. - """ - - immediate = None - if getattr(self.parent, "imm7_align4", False): - # Apply the immediate mask - v = self.parent.imm7_align4.value & 0x1F - - # Shift value such as: - # imm7=iii_ii||00 - immediate = v << 2 - - elif getattr(self.parent, "imm7", False): - # Apply the immediate mask - immediate = self.parent.imm7.value & 0x7F - - elif getattr(self.parent, "disp7_align2", False): - # Apply the immediate mask - disp7_align2 = self.parent.disp7_align2.value & 0x3F - - # Shift value such as: - # disp7 = ddd_ddd||0 - immediate = disp7_align2 << 1 - - if immediate is not None: - self.expr = ExprMem(self.implicit_reg + ExprInt(immediate, 32), 32) - return True - else: - return False - - def encode(self): - """Modify the encoded value. One part is stored in this object, and - the other one in a parent immediate. - """ - - # Verify the expression - if not isinstance(self.expr, ExprMem): - return False - if not isinstance(self.expr.ptr, ExprOp): - return False - if self.expr.ptr.args[0] != self.implicit_reg: - return False - - if getattr(self.parent, "imm7_align4", False): - - # Get the integer and check the upper bound - v = int(self.expr.ptr.args[1].arg) - if v > 0x80: - return False - - # Encode the value - self.parent.imm7_align4.value = v >> 2 - - return True - - elif getattr(self.parent, "imm7", False): - - # Get the integer and check the upper bound - v = int(self.expr.ptr.args[1].arg) - if v > 0x80: - return False - - # Encode the value - self.parent.imm7.value = v - - return True - - elif getattr(self.parent, "disp7_align2", False): - - # Get the integer and check the upper bound - v = int(self.expr.ptr.args[1].arg) - if v > 0x80: - return False - - # Encode the value - self.parent.disp7_align2.value = v >> 1 - - return True - - return False - - -class mep_deref_tp_offset(mep_deref_sp_offset): - """Dummy Toshiba MeP-c4 dereferenced register that represents TP, plus an - offset. - """ - implicit_reg = TP - - -class mep_copro_reg(reg_noarg, mep_arg): - """Generic Toshiba MeP-c4 coprocessor register - """ - reg_info = copro_gpr_infos # the list of MeP-c4 coprocessor registers defined in regs.py - parser = reg_info.parser # GV: not understood yet - - -class mep_copro_reg_split(mep_copro_reg): - """Generic Toshiba MeP-c4 coprocessor register encode into different fields - """ - - def decode(self, v): - """Modify the decoded value using the previously decoded imm4_noarg. - """ - - # Apply the immediate mask - v = v & self.lmask - - # Shift values such as: - # CRn=NNnnnn - crn = (v << 4) + (self.parent.imm4.value & 0xF) - - # Build the internal expression - self.expr = ExprId("C%d" % crn, 32) - return True - - def encode(self): - """Modify the encoded value. One part is stored in this object, and - the other one in imm4_noarg. - """ - - if not isinstance(self.expr, ExprId): - return False - - # Get the register and check the upper bound - reg_name = self.expr.name - if reg_name[0] != "C": - return False - reg_value = copro_gpr_names.index(reg_name) - if reg_value > 0x3f: - return False - - # Encode the value into two parts - self.parent.imm4.value = (reg_value & 0xF) - self.value = (reg_value >> 4) & 0x3 - return True - - -class mep_deref_inc_reg(mep_deref_reg): - """Generic Toshiba MeP-c4 coprocess dereferenced & incremented register - """ - parser = deref_inc_reg_parser - - -# Immediate decoders and encoders - -class mep_int32_noarg(int32_noarg): - """Generic Toshiba MeP-c4 signed immediate - - Note: encode() is copied from int32_noarg.encode() and modified to allow - small (< 32 bits) signed immediate to be manipulated. - - """ - - def encode(self): - if not isinstance(self.expr, ExprInt): - return False - v = int(self.expr) - # Note: the following lines were commented on purpose - #if sign_ext(v & self.lmask, self.l, self.intsize) != v: - # return False - v = self.encodeval(v & self.lmask) - self.value = v & self.lmask - return True - - -class mep_imm(imm_noarg, mep_arg): - """Generic Toshiba MeP-c4 immediate - - Note: - - the immediate size will be set using bs() - """ - parser = base_expr - - -class mep_imm6(mep_int32_noarg): - """Toshiba MeP-c4 signed 6 bits immediate.""" - parser = base_expr - intsize = 6 - intmask = (1 << intsize) - 1 - int2expr = lambda self, x: ExprInt(sign_ext(x, self.l, 32), 32) - - -class mep_imm8(mep_int32_noarg): - """Toshiba MeP-c4 signed 8 bits immediate.""" - parser = base_expr - intsize = 8 - intmask = (1 << intsize) - 1 - int2expr = lambda self, x: ExprInt(sign_ext(x, self.l, 32), 32) - - -class mep_imm16(mep_int32_noarg): - """Toshiba MeP-c4 16 bits immediate.""" - parser = base_expr - intsize = 16 - intmask = (1 << intsize) - 1 - int2expr = lambda self, x: ExprInt(x, 32) - - -class mep_imm16_signed(mep_int32_noarg): - """Toshiba MeP-c4 signed 16 bits immediate.""" - parser = base_expr - intsize = 16 - intmask = (1 << intsize) - 1 - int2expr = lambda self, x: ExprInt(sign_ext(x, self.l, 32), 32) - - -class mep_target24(mep_imm): - """Toshiba MeP-c4 target24 immediate, as used in JMP - """ - - def decode(self, v): - """Modify the decoded value using the previously decoded imm7. - """ - - # Apply the immediate mask - v = v & self.lmask - - # Shift values such as: - # target24=tttt_tttt_tttt_tttt||TTT_TTTT||0 - target24 = (v << 8) + ((self.parent.imm7.value & 0x7F) << 1) - - # Build the internal expression - self.expr = ExprInt(target24, 32) - return True - - def encode(self): - """Modify the encoded value. One part is stored in this object, and - the other one in imm7. - """ - - if not isinstance(self.expr, ExprInt): - return False - - # Get the integer and apply a mask - v = int(self.expr) & 0x00FFFFFF - - # Encode the value into two parts - self.parent.imm7.value = (v & 0xFF) >> 1 - self.value = v >> 8 - return True - - -class mep_target24_signed(mep_target24): - """Toshiba MeP-c4 target24 signed immediate, as used in BSR - """ - - def decode(self, v): - """Perform sign extension - """ - - mep_target24.decode(self, v) - v = int(self.expr) - self.expr = ExprInt(sign_ext(v, 24, 32), 32) - - return True - - -class mep_code20(mep_imm): - """Toshiba MeP-c4 code20 immediate, as used in DSP1 - """ - - def decode(self, v): - """Modify the decoded value using the previously decoded imm4_noarg. - """ - - # Apply the immediate mask - v = v & self.lmask - - # Shift values such as: - # code20=mmmm_cccc_cccc_cccc_cccc - code20 = v + ((self.parent.imm4.value & 0xFF) << 16) - - # Build the internal expression - self.expr = ExprInt(code20, 32) - return True - - def encode(self): - """Modify the encoded value. One part is stored in this object, and - the other one in imm4_noarg. - """ - - if not isinstance(self.expr, ExprInt): - return False - - # Get the integer and check the upper bound - v = int(self.expr.arg) - if v > 0xffffff: - return False - - # Encode the value into two parts - self.parent.imm4 = ((v >> 16) & 0xFF) - self.value = v - return True - - -class mep_code24(mep_imm): - """Toshiba MeP-c4 code24 immediate, as used in CP - """ - - def decode(self, v): - """Modify the decoded value using the previously decoded imm8_CCCC_CCCC. - """ - - # Shift values such as: - # code24=CCCC_CCCC||cccc_cccc_cccc_cccc - code24 = v + ((self.parent.imm8_CCCC_CCCC.value & 0xFF) << 16) - - # Build the internal expression - self.expr = ExprInt(code24, 32) - return True - - def encode(self): - """Modify the encoded value. One part is stored in this object, and - the other one in imm8_CCCC_CCCC. - """ - - if not isinstance(self.expr, ExprInt): - return False - - # Get the integer and check the upper bound - v = int(self.expr.arg) - if v > 0xFFFFFF: - return False - - # Encode the value into two parts - self.parent.imm8_CCCC_CCCC.value = ((v >> 16) & 0xFF) - self.value = v & 0xFFFF - return True - - -class mep_imm7_align4(mep_imm): - """Toshiba MeP-c4 imm7.align4 immediate, as used in Major #4 opcodes - """ - - def decode(self, v): - """Modify the decoded value. - """ - - # Apply the immediate mask - v = v & self.lmask - - # Shift value such as: - # imm7=iii_ii||00 - imm7_align4 = v << 2 - - # Build the internal expression - self.expr = ExprInt(imm7_align4, 32) - return True - - def encode(self): - """Modify the encoded value. - """ - - if not isinstance(self.expr, ExprInt): - return False - - # Get the integer and check the upper bound - v = int(self.expr) - if v > 0x80: - return False - - # Encode the value - self.value = v >> 2 - return True - - -class mep_imm5_Iiiii (mep_imm): - """Toshiba MeP-c4 imm5 immediate, as used in STC & LDC. It encodes a - control/special register. - """ - - reg_info = csr_infos # the list of MeP-c4 control/special registers defined in regs.py - parser = reg_info.parser # GV: not understood yet - - def decode(self, v): - """Modify the decoded value using the previously decoded imm4_iiii - """ - - # Apply the immediate mask - I = v & self.lmask - - # Shift values such as: - # imm5=I||iiii - imm5 = (I << 4) + (self.parent.imm4_iiii.value & 0xF) - - # Build the internal register expression - self.expr = ExprId(csr_names[imm5], 32) - return True - - def encode(self): - """Modify the encoded value. One part is stored in this object, and - the other one in imm4_iiii. - """ - - if not isinstance(self.expr, ExprId): - return False - - # Get the register number and check the upper bound - v = csr_names.index(self.expr.name) - if v > 0x1F: - return False - - # Encode the value into two parts - self.parent.imm4_iiii.value = v & 0xF # iiii - self.value = (v >> 4) & 0b1 # I - return True - - -class mep_disp7_align2(mep_imm): - """Toshiba MeP-c4 disp7.align2 immediate, as used in Major #8 opcodes - """ - upper_bound = 0x7F - bits_shift = 1 - - def decode(self, v): - """Modify the decoded value. - """ - - # Apply the immediate mask - v = v & self.lmask - - # Shift value such as: - # disp7 = ddd_ddd||0 - disp7_align2 = (v << self.bits_shift) - - # Sign extension - disp7_align2 = sign_ext(disp7_align2, self.l + self.bits_shift, 32) - - # Build the internal expression - self.expr = ExprInt(disp7_align2, 32) - return True - - def encode(self): - """Modify the encoded value. - """ - - if not isinstance(self.expr, ExprInt): - return False - - # Get the integer - v = int(self.expr) & self.upper_bound - - # Encode the value - self.value = (v >> self.bits_shift) & self.upper_bound - self.value = (v & self.upper_bound) >> self.bits_shift - return True - - -class mep_disp8_align2(mep_disp7_align2): - upper_bound = 0xFF - - -class mep_disp8_align4(mep_disp7_align2): - upper_bound = 0xFF - bits_shift = 2 - - -class mep_imm8_align8(mep_disp7_align2): - upper_bound = 0xFF - bits_shift = 3 - - -class mep_disp12_align2(mep_disp7_align2): - upper_bound = 0xFFF - - -class mep_disp12_align2_signed(mep_disp12_align2): - - def decode(self, v): - """Perform sign extension. - """ - mep_disp12_align2.decode(self, v) - v = int(self.expr) - - self.expr = ExprInt(sign_ext(v, 12, 32), 32) - return True - - -class mep_disp17(mep_disp7_align2): - upper_bound = 0x1FFFF - - -class mep_imm24(mep_imm): - """Toshiba MeP-c4 imm24 immediate, as used in MOVU - """ - - def decode(self, v): - """Modify the decoded value. - """ - - # Apply the immediate mask - v = v & self.lmask - - # Shift values such as: - # imm24=iiii_iiii_iiii_iiii||IIII_IIIII - imm24 = ((v & 0xFFFF) << 8) + ((v & 0xFF0000) >> 16) - - # Build the internal expression - self.expr = ExprInt(imm24, 32) - return True - - def encode(self): - """Modify the encoded value. - """ - - if not isinstance(self.expr, ExprInt): - return False - - # Get the integer and check the upper bound - v = int(self.expr) - if v > 0xFFFFFF: - return False - - # Encode the value - self.value = ((v & 0xFFFF00) >> 8) + ((v & 0xFF) << 16) - return True - - -class mep_abs24(mep_imm): - """Toshiba MeP-c4 abs24 immediate - """ - parser = abs24_deref_parser - - def decode(self, v): - """Modify the decoded value using the previously decoded imm6. - """ - - # Apply the immediate mask - v = v & self.lmask - - # Shift values such as: - # abs24=dddd_dddd_dddd_dddd||DDDD_DD||00 - abs24 = (v << 8) + ((self.parent.imm6.value & 0x3F) << 2) - - # Build the internal expression - self.expr = ExprMem(ExprInt(abs24, 32), 32) - return True - - def encode(self): - """Modify the encoded value. One part is stored in this object, and - the other one in imm6. - """ - - if not (isinstance(self.expr, ExprMem) and isinstance(self.expr.ptr, ExprInt)): - return False - - # Get the integer and check the upper bound - v = int(self.expr.ptr) - if v > 0xffffff: - return False - - # Encode the value into two parts - self.parent.imm6.value = (v & 0xFF) >> 2 - self.value = v >> 8 - return True - - -# Define MeP-c4 assembly operands - -reg04 = bs(l=4, # length in bits - cls=(mep_reg, )) # class implementing decoding & encoding - -reg04_l = bs(l=4, cls=(mep_reg, )) - -reg04_m = bs(l=4, cls=(mep_reg, )) - -reg04_n = bs(l=4, cls=(mep_reg, )) - -reg00 = bs(l=0, cls=(mep_reg, )) - -reg00_sp = bs(l=0, cls=(mep_reg_sp, )) - -reg00_tp = bs(l=0, cls=(mep_reg_tp, )) - -reg00_deref_sp = bs(l=0, cls=(mep_deref_sp_offset, )) - -reg00_deref_tp = bs(l=0, cls=(mep_deref_tp_offset, )) - -reg03 = bs(l=3, cls=(mep_reg, )) - -reg04_deref = bs(l=4, cls=(mep_deref_reg,)) - -reg04_deref_noarg = bs(l=4, fname="reg04_deref") - -reg04_inc_deref = bs(l=4, cls=(mep_deref_inc_reg,)) - -copro_reg04 = bs(l=4, cls=(mep_copro_reg,)) - -copro_reg05 = bs(l=1, cls=(mep_copro_reg_split,)) - -copro_reg06 = bs(l=2, cls=(mep_copro_reg_split,)) - -disp2 = bs(l=2, cls=(mep_imm, )) - -imm2 = disp2 - -imm3 = bs(l=3, cls=(mep_imm, )) - -imm4 = bs(l=4, cls=(mep_imm, )) - -imm4_noarg = bs(l=4, fname="imm4") - -imm4_iiii_noarg = bs(l=4, fname="imm4_iiii") - -imm5 = bs(l=5, cls=(mep_imm, )) - -imm5_Iiiii = bs(l=1, cls=(mep_imm5_Iiiii, )) # it is not an immediate, but a - # control/special register. - -imm6 = bs(l=6, cls=(mep_imm6, mep_arg)) - -imm6_noarg = bs(l=6, fname="imm6") - -imm7 = bs(l=7, cls=(mep_imm, )) - -imm7_noarg = bs(l=7, fname="imm7") # Note: - # - will be decoded as a 7 bits immediate - # - fname is used to set the operand name - # used in mep_target24 to merge operands - # values. By default, the bs class fills - # fname with an hex string compute from - # arguments passed to __init__ - -imm7_align4 = bs(l=5, cls=(mep_imm7_align4,)) - -imm7_align4_noarg = bs(l=5, fname="imm7_align4") - -disp7_align2 = bs(l=6, cls=(mep_disp7_align2,)) - -disp7_align2_noarg = bs(l=6, fname="disp7_align2") - -imm8 = bs(l=8, cls=(mep_imm8, mep_arg)) - -imm8_noarg = bs(l=8, fname="imm8_CCCC_CCCC") - -disp8 = bs(l=7, cls=(mep_disp8_align2, )) - -imm8_align2 = bs(l=7, cls=(mep_disp8_align2, )) - -imm8_align4 = bs(l=6, cls=(mep_disp8_align4, )) - -imm8_align8 = bs(l=5, cls=(mep_imm8_align8, )) - -imm12 = bs(l=12, cls=(mep_imm, )) - -disp12_signed = bs(l=11, cls=(mep_disp12_align2_signed, )) - -imm16 = bs(l=16, cls=(mep_imm16, mep_arg)) -imm16_signed = bs(l=16, cls=(mep_imm16_signed, mep_arg)) - -disp16_reg_deref = bs(l=16, cls=(mep_deref_reg_offset,)) - -disp17 = bs(l=16, cls=(mep_disp17, )) - -imm18 = bs(l=19, cls=(mep_imm, )) - -imm_code20 = bs(l=16, cls=(mep_code20, )) - -imm24 = bs(l=24, cls=(mep_imm24, )) - -imm_target24 = bs(l=16, cls=(mep_target24, )) -imm_target24_signed = bs(l=16, cls=(mep_target24_signed, )) - -imm_code24 = bs(l=16, cls=(mep_code24, )) - -abs24 = bs(l=16, cls=(mep_abs24, )) - - -# MeP-c4 mnemonics objects - -### <Major Opcode #0> - -# MOV Rn,Rm - 0000_nnnn_mmmm_0000 -addop("MOV", [bs("0000"), reg04, reg04, bs("0000")]) - -# NEG Rn,Rm - 0000_nnnn_mmmm_0001 -addop("NEG", [bs("0000"), reg04, reg04, bs("0001")]) - -# SLT3 R0,Rn,Rm - 0000_nnnn_mmmm_0010 -addop("SLT3", [bs("0000"), reg00, reg04, reg04, bs("0010")]) - -# SLTU3 R0,Rn,Rm - 0000_nnnn_mmmm_0011 -addop("SLTU3", [bs("0000"), reg00, reg04, reg04, bs("0011")]) - -# SUB Rn,Rm - 0000_nnnn_mmmm_0100 -addop("SUB", [bs("0000"), reg04, reg04, bs("0100")]) - -# SBVCK3 R0,Rn,Rm - 0000_nnnn_mmmm_0101 -addop("SBVCK3", [bs("0000"), reg00, reg04, reg04, bs("0101")]) - -# (RI) - 0000_xxxx_xxxx_0110 -addop("(RI)", [bs("0000"), reg04, reg04, bs("0110")]) - -# ADVCK3 R0,Rn,Rm - 0000_nnnn_mmmm_0111 -addop("ADVCK3", [bs("0000"), reg00, reg04, reg04, bs("0111")]) - -# SB Rn,(Rm) - 0000_nnnn_mmmm_1000 -addop("SB", [bs("0000"), reg04, reg04_deref, bs("1000")]) - -# SH Rn,(Rm) - 0000_nnnn_mmmm_1001 -addop("SH", [bs("0000"), reg04, reg04_deref, bs("1001")]) - -# SW Rn,(Rm) - 0000_nnnn_mmmm_1010 -addop("SW", [bs("0000"), reg04, reg04_deref, bs("1010")]) - -# LBU Rn,(Rm) - 0000_nnnn_mmmm_1011 -addop("LBU", [bs("0000"), reg04, reg04_deref, bs("1011")]) - -# LB Rn,(Rm) - 0000_nnnn_mmmm_1100 -addop("LB", [bs("0000"), reg04, reg04_deref, bs("1100")]) - -# LH Rn,(Rm) - 0000_nnnn_mmmm_1101 -addop("LH", [bs("0000"), reg04, reg04_deref, bs("1101")]) - -# LW Rn,(Rm) - 0000_nnnn_mmmm_1110 -addop("LW", [bs("0000"), reg04, reg04_deref, bs("1110")]) - -# LHU Rn,(Rm) - 0000_nnnn_mmmm_1111 -addop("LHU", [bs("0000"), reg04, reg04_deref, bs("1111")]) - - -### <Major Opcode #1> - -# OR Rn,Rm - 0001_nnnn_mmmm_0000 -addop("OR", [bs("0001"), reg04, reg04, bs("0000")]) - -# AND Rn,Rm - 0001_nnnn_mmmm_0001 -addop("AND", [bs("0001"), reg04, reg04, bs("0001")]) - -# XOR Rn,Rm - 0001_nnnn_mmmm_0010 -addop("XOR", [bs("0001"), reg04, reg04, bs("0010")]) - -# NOR Rn,Rm - 0001_nnnn_mmmm_0011 -addop("NOR", [bs("0001"), reg04, reg04, bs("0011")]) - -# MUL Rn,Rm - 0001_nnnn_mmmm_0100 -addop("MUL", [bs("0001"), reg04, reg04, bs("0100")]) - -# MULU Rn,Rm - 0001_nnnn_mmmm_0101 -addop("MULU", [bs("0001"), reg04, reg04, bs("0101")]) - -# MULR Rn,Rm - 0001_nnnn_mmmm_0110 -addop("MULR", [bs("0001"), reg04, reg04, bs("0110")]) - -# MULRU Rn,Rm - 0001_nnnn_mmmm_0111 -addop("MULRU", [bs("0001"), reg04, reg04, bs("0111")]) - -# DIV Rn,Rm - 0001_nnnn_mmmm_1000 -addop("DIV", [bs("0001"), reg04, reg04, bs("1000")]) - -# DIVU Rn,Rm - 0001_nnnn_mmmm_1001 -addop("DIVU", [bs("0001"), reg04, reg04, bs("1001")]) - -# (RI) - 0001_xxxx_xxxx_1010 -addop("(RI)", [bs("0001"), reg04, reg04, bs("1010")]) - -# (RI) - 0001_xxxx_xxxx_1011 -addop("(RI)", [bs("0001"), reg04, reg04, bs("1011")]) - -# SSARB disp2(Rm) - 0001_00dd_mmmm_1100 -addop("SSARB", [bs("000100"), disp2, reg04_deref, bs("1100")]) - -# EXTB Rn - 0001_nnnn_0000_1101 -addop("EXTB", [bs("0001"), reg04, bs("00001101")]) - -# EXTH Rn - 0001_nnnn_0010_1101 -addop("EXTH", [bs("0001"), reg04, bs("00101101")]) - -# EXTUB Rn - 0001_nnnn_1000_1101 -addop("EXTUB", [bs("0001"), reg04, bs("10001101")]) - -# EXTUH Rn - 0001_nnnn_1010_1101 -addop("EXTUH", [bs("0001"), reg04, bs("10101101")]) - -# JMP Rm - 0001_0000_mmmm_1110 -addop("JMP", [bs("00010000"), reg04, bs("1110")]) - -# JSR Rm - 0001_0000_mmmm_1111 -addop("JSR", [bs("00010000"), reg04, bs("1111")]) - -# JSRV Rm - 0001_1000_mmmm_1111 -addop("JSRV", [bs("00011000"), reg04, bs("1111")]) - - -### <Major Opcode #2> - -# BSETM (Rm),imm3 - 0010_0iii_mmmm_0000 -addop("BSETM", [bs("00100"), imm3, reg04_deref, bs("0000")], [reg04_deref, imm3]) - -# BCLRM (Rn),imm3 - 0010_0iii_mmmm_0001 -addop("BCLRM", [bs("00100"), imm3, reg04_deref, bs("0001")], [reg04_deref, imm3]) - -# BNOTM (Rm),imm3 - 0010_0iii_mmmm_0010 -addop("BNOTM", [bs("00100"), imm3, reg04_deref, bs("0010")], [reg04_deref, imm3]) - -# BTSTM R0,(Rm),imm3 - 0010_0iii_mmmm_0011 -addop("BTSTM", [bs("00100"), reg00, imm3, reg04_deref, bs("0011")], [reg00, reg04_deref, imm3]) - -# TAS Rn,(Rm) - 0010_nnnn_mmmm_0100 -addop("TAS", [bs("0010"), reg04, reg04_deref, bs("0100")]) - -# (RI) - 0010_xxxx_xxxx_0101 -addop("(RI)", [bs("0010"), reg04, reg04, bs("0101")]) - -# SL1AD3 R0,Rn,Rm - 0010_nnnn_mmmm_0110 -addop("SL1AD3", [bs("0010"), reg00, reg04, reg04, bs("0110")]) - -# SL2AD3 R0,Rn,Rm - 0010_nnnn_mmmm_0111 -addop("SL2AD3", [bs("0010"), reg00, reg04, reg04, bs("0111")]) - -# (RI) - 0010_xxxx_xxxx_1000 -addop("(RI)", [bs("0010"), reg04, reg04, bs("1000")]) - -# (RI) - 0010_xxxx_xxxx_1001 -addop("(RI)", [bs("0010"), reg04, reg04, bs("1001")]) - -# (RI) - 0010_xxxx_xxxx_1010 -addop("(RI)", [bs("0010"), reg04, reg04, bs("1010")]) - -# (RI) - 0010_xxxx_xxxx_1011 -addop("(RI)", [bs("0010"), reg04, reg04, bs("1011")]) - -# SRL Rn,Rm - 0010_nnnn_mmmm_1100 -addop("SRL", [bs("0010"), reg04, reg04, bs("1100")]) - -# SRA Rn,Rm - 0010_nnnn_mmmm_1101 -addop("SRA", [bs("0010"), reg04, reg04, bs("1101")]) - -# SLL Rn,Rm - 0010_nnnn_mmmm_1110 -addop("SLL", [bs("0010"), reg04, reg04, bs("1110")]) - -# FSFT Rn,Rm - 0010_nnnn_mmmm_1111 -addop("FSFT", [bs("0010"), reg04, reg04, bs("1111")]) - - -### <Major Opcode #3> - -# SWCPI CRn,(Rm+) - 0011_nnnn_mmmm_0000 -addop("SWCPI", [bs("0011"), copro_reg04, reg04_inc_deref, bs("0000")]) - -# LWCPI CRn,(Rm+) - 0011_nnnn_mmmm_0001 -addop("LWCPI", [bs("0011"), copro_reg04, reg04_inc_deref, bs("0001")]) - -# SMCPI CRn,(Rm+) - 0011_nnnn_mmmm_0010 -addop("SMCPI", [bs("0011"), copro_reg04, reg04_inc_deref, bs("0010")]) - -# LMCPI CRn,(Rm+) - 0011_nnnn_mmmm_0011 -addop("LMCPI", [bs("0011"), copro_reg04, reg04_inc_deref, bs("0011")]) - -# SWCP CRn,(Rm) - 0011_nnnn_mmmm_1000 -addop("SWCP", [bs("0011"), copro_reg04, reg04_deref, bs("1000")]) - -# LWCP CRn,(Rm) - 0011_nnnn_mmmm_1001 -addop("LWCP", [bs("0011"), copro_reg04, reg04_deref, bs("1001")]) - -# SMCP CRn,(Rm) - 0011_nnnn_mmmm_1010 -addop("SMCP", [bs("0011"), copro_reg04, reg04_deref, bs("1010")]) - -# LMCP CRn,(Rm) - 0011_nnnn_mmmm_1011 -addop("LMCP", [bs("0011"), copro_reg04, reg04_deref, bs("1011")]) - - -### <Major Opcode #4> - -# ADD3 Rn,SP,imm7.align4 - 0100_nnnn_0iii_ii00 -addop("ADD3", [bs("0100"), reg04, reg00_sp, bs("0"), imm7_align4, bs("00")]) - -# SW Rn,disp7.align4(SP) - 0100_nnnn_0ddd_dd10 -# Note: disp7.align4 is the same as imm7.align4 -addop("SW", [bs("0100"), reg04, bs("0"), imm7_align4_noarg, reg00_deref_sp, bs("10")]) - -# LW Rn,disp7.align4(SP) - 0100_nnnn_0ddd_dd11 -addop("LW", [bs("0100"), reg04, bs("0"), imm7_align4_noarg, reg00_deref_sp, bs("11")]) - -# SW Rn[0-7],disp7.align4(TP) - 0100_0nnn_1ddd_dd10 -addop("SW", [bs("01000"), reg03, bs("1"), imm7_align4_noarg, reg00_deref_tp, bs("10")]) - -# LW Rn[0-7],disp7.align4(TP) - 0100_0nnn_1ddd_dd11 -addop("LW", [bs("01000"), reg03, bs("1"), imm7_align4_noarg, reg00_deref_tp, bs("11")]) - -# LBU Rn[0-7],disp7(TP) - 0100_1nnn_1ddd_dddd -addop("LBU", [bs("01001"), reg03, bs("1"), imm7_noarg, reg00_deref_tp], [reg03, reg00_deref_tp]) - -### <Major Opcode #5> - -# MOV Rn,imm8 - 0101_nnnn_iiii_iiii -addop("MOV", [bs("0101"), reg04, imm8]) - - -### <Major Opcode #6> - -# ADD Rn,imm6 - 0110_nnnn_iiii_ii00 -addop("ADD", # mnemonic name - [bs("0110"), reg04, imm6, bs("00")]) # mnemonic description - -# SLT3 R0,Rn,imm5 - 0110_nnnn_iiii_i001 -addop("SLT3", [bs("0110"), reg00, reg04, imm5, bs("001")]) - -# SRL Rn,imm5 - 0110_nnnn_iiii_i010 -addop("SRL", [bs("0110"), reg04, imm5, bs("010")]) - -# SRA Rn,imm5 - 0110_nnnn_iiii_i011 -addop("SRA", [bs("0110"), reg04, imm5, bs("011")]) - -# SLTU3 R0,Rn,imm5 - 0110_nnnn_iiii_i101 -addop("SLTU3", [bs("0110"), reg00, reg04, imm5, bs("101")]) - -# SLL Rn,imm5 - 0110_nnnn_iiii_i110 -addop("SLL", [bs("0110"), reg04, imm5, bs("110")]) - -# SLL3 R0,Rn,imm5 - 0110_nnnn_iiii_i111 -addop("SLL3", [bs("0110"), reg00, reg04, imm5, bs("111")]) - - -### <Major Opcode #7> - -# DI - 0111_0000_0000_0000 -addop("DI", [bs("0111000000000000")]) - -# EI - 0111_0000_0001_0000 -addop("EI", [bs("0111000000010000")]) - -# SYNCM - 0111_0000_0001_0001 -addop("SYNCM", [bs("0111000000010001")]) - -# SYNCCP - 0111_0000_0010_0001 -addop("SYNCCP", [bs("0111000000100001")]) - -# RET - 0111_0000_0000_0010 -addop("RET", [bs("0111000000000010")]) - -# RETI - 0111_0000_0001_0010 -addop("RETI", [bs("0111000000010010")]) - -# HALT - 0111_0000_0010_0010 -addop("HALT", [bs("0111000000100010")]) - -# BREAK - 0111_0000_0011_0010 -addop("BREAK", [bs("0111000000110010")]) - -# SLEEP - 0111_0000_0110_0010 -addop("SLEEP", [bs("0111000001100010")]) - -# DRET - 0111_0000_0001_0011 -addop("DRET", [bs("0111000000010011")]) - -# DBREAK - 0111_0000_0011_0011 -addop("DBREAK", [bs("0111000000110011")]) - -# CACHE imm4,(Rm) - 0111_iiii_mmmm_0100 -addop("CACHE", [bs("0111"), imm4, reg04_deref, bs("0100")]) - -# (RI) - 0111_xxxx_xxxx_0101 -addop("(RI)", [bs("0111"), reg04, reg04, bs("0101")]) - -# SWI imm2 - 0111_0000_00ii_0110 -addop("SWI", [bs("0111000000"), imm2, bs("0110")]) - -# (RI) - 0111_xxxx_xxxx_0111 -addop("(RI)", [bs("0111"), reg04, reg04, bs("0111")]) - -# STC Rn,imm5 - 0111_nnnn_iiii_100I -addop("STC", [bs("0111"), reg04, imm4_iiii_noarg, bs("100"), imm5_Iiiii]) - -# LDC Rn,imm5 - 0111_nnnn_iiii_101I -addop("LDC", [bs("0111"), reg04, imm4_iiii_noarg, bs("101"), imm5_Iiiii]) - -# (RI) - 0111_xxxx_xxxx_1100 -addop("(RI)", [bs("0111"), reg04, reg04, bs("1100")]) - -# (RI) - 0111_xxxx_xxxx_1101 -addop("(RI)", [bs("0111"), reg04, reg04, bs("1101")]) - -# (RI) - 0111_xxxx_xxxx_1110 -addop("(RI)", [bs("0111"), reg04, reg04, bs("1110")]) - -# (RI) - 0111_xxxx_xxxx_1111 -addop("(RI)", [bs("0111"), reg04, reg04, bs("1111")]) - - -### <Major Opcode #8> - -# SB Rn[0-7],disp7(TP) - 1000_0nnn_0ddd_dddd -addop("SB", [bs("10000"), reg03, bs("0"), imm7_noarg, reg00_deref_tp]) - -# SH Rn[0-7],disp7.align2(TP) - 1000_0nnn_1ddd_ddd0 -# (disp7.align2 = ddd_ddd||0) -addop("SH", [bs("10000"), reg03, bs("1"), disp7_align2_noarg, bs("0"), reg00_deref_tp]) - -# LB Rn[0-7],disp7(TP) - 1000_1nnn_0ddd_dddd -addop("LB", [bs("10001"), reg03, bs("0"), imm7_noarg, reg00_deref_tp]) - -# LH Rn[0-7],disp7.align2(TP) - 1000_1nnn_1ddd_ddd0 -addop("LH", [bs("10001"), reg03, bs("1"), disp7_align2_noarg, bs("0"), reg00_deref_tp]) - -# LHU Rn[0-7],disp7.align2(TP) - 1000_1nnn_1ddd_ddd1 -addop("LHU", [bs("10001"), reg03, bs("1"), disp7_align2_noarg, bs("1"), reg00_deref_tp]) - - -### <Major Opcode #9> - -# ADD3 Rl,Rn,Rm - 1001_nnnn_mmmm_llll -addop("ADD3", [bs("1001"), reg04_n, reg04_m, reg04_l], [reg04_l, reg04_n, reg04_m]) - - -### <Major Opcode #10> - -# BEQZ Rn,disp8.align2 - 1010_nnnn_dddd_ddd0 -# (disp8=dddd_ddd||0) -addop("BEQZ", [bs("1010"), reg04, disp8, bs("0")]) - -# BNEZ Rn,disp8.align2 - 1010_nnnn_dddd_ddd1 -addop("BNEZ", [bs("1010"), reg04, disp8, bs("1")]) - - -### <Major Opcode #11> - -# BRA disp12.align2 - 1011_dddd_dddd_ddd0 -# (disp12=dddd_dddd_ddd||0) -addop("BRA", [bs("1011"), disp12_signed, bs("0")]) - -# BSR disp12.align2 - 1011_dddd_dddd_ddd1 -addop("BSR", [bs("1011"), disp12_signed, bs("1")]) - - -### <Major Opcode #12> - -# ADD3 Rn,Rm,imm16 - 1100_nnnn_mmmm_0000 iiii_iiii_iiii_iiii -addop("ADD3", [bs("1100"), reg04, reg04, bs("0000"), imm16_signed]) - -# MOV Rn,imm16 - 1100_nnnn_0000_0001 iiii_iiii_iiii_iiii -addop("MOV", [bs("1100"), reg04, bs("00000001"), imm16]) - -# MOVU Rn,imm16 - 1100_nnnn_0001_0001 iiii_iiii_iiii_iiii -addop("MOVU", [bs("1100"), reg04, bs("00010001"), imm16]) - -# MOVH Rn,imm16 - 1100_nnnn_0010_0001 iiii_iiii_iiii_iiii -addop("MOVH", [bs("1100"), reg04, bs("00100001"), imm16]) - -# SLT3 Rn,Rm,imm16 - 1100_nnnn_mmmm_0010 iiii_iiii_iiii_iiii -addop("SLT3", [bs("1100"), reg04, reg04, bs("0010"), imm16_signed]) - -# SLTU3 Rn,Rm,imm16 - 1100_nnnn_mmmm_0011 iiii_iiii_iiii_iiii -addop("SLTU3", [bs("1100"), reg04, reg04, bs("0011"), imm16]) - -# OR3 Rn,Rm,imm16 - 1100_nnnn_mmmm_0100 iiii_iiii_iiii_iiii -addop("OR3", [bs("1100"), reg04, reg04, bs("0100"), imm16]) - -# AND3 Rn,Rm,imm16 - 1100_nnnn_mmmm_0101 iiii_iiii_iiii_iiii -addop("AND3", [bs("1100"), reg04, reg04, bs("0101"), imm16]) - -# XOR3 Rn,Rm,imm16 - 1100_nnnn_mmmm_0110 iiii_iiii_iiii_iiii -addop("XOR3", [bs("1100"), reg04, reg04, bs("0110"), imm16]) - -# (RI) - 1100_xxxx_xxxx_0111 xxxx_xxxx_xxxx_xxxx -addop("(RI)", [bs("1100"), imm8, bs("0111"), imm16]) - -# SB Rn,disp16(Rm) - 1100_nnnn_mmmm_1000 dddd_dddd_dddd_dddd -addop("SB", [bs("1100"), reg04, reg04_deref_noarg, bs("1000"), disp16_reg_deref], [reg04, disp16_reg_deref]) - -# SH Rn,disp16(Rm) - 1100_nnnn_mmmm_1001 dddd_dddd_dddd_dddd -addop("SH", [bs("1100"), reg04, reg04_deref_noarg, bs("1001"), disp16_reg_deref], [reg04, disp16_reg_deref]) - -# SW Rn,disp16(Rm) - 1100_nnnn_mmmm_1010 dddd_dddd_dddd_dddd -addop("SW", [bs("1100"), reg04, reg04_deref_noarg, bs("1010"), disp16_reg_deref], [reg04, disp16_reg_deref]) - -# LBU Rn,disp16(Rm) - 1100_nnnn_mmmm_1011 dddd_dddd_dddd_dddd -addop("LBU", [bs("1100"), reg04, reg04_deref_noarg, bs("1011"), disp16_reg_deref], [reg04, disp16_reg_deref]) - -# LB Rn,disp16(Rm) - 1100_nnnn_mmmm_1100 dddd_dddd_dddd_dddd -addop("LB", [bs("1100"), reg04, reg04_deref_noarg, bs("1100"), disp16_reg_deref], [reg04, disp16_reg_deref]) - -# LH Rn,disp16(Rm) - 1100_nnnn_mmmm_1101 dddd_dddd_dddd_dddd -addop("LH", [bs("1100"), reg04, reg04_deref_noarg, bs("1101"), disp16_reg_deref], [reg04, disp16_reg_deref]) - -# LW Rn,disp16(Rm) - 1100_nnnn_mmmm_1110 dddd_dddd_dddd_dddd -addop("LW", [bs("1100"), reg04, reg04_deref_noarg, bs("1110"), disp16_reg_deref], [reg04, disp16_reg_deref]) - -# LHU Rn,disp16(Rm) - 1100_nnnn_mmmm_1111 dddd_dddd_dddd_dddd -addop("LHU", [bs("1100"), reg04, reg04_deref_noarg, bs("1111"), disp16_reg_deref], [reg04, disp16_reg_deref]) - - -### <Major Opcode #13> - -# MOVU Rn[0-7],imm24 - 1101_0nnn_IIII_IIII iiii_iiii_iiii_iiii -addop("MOVU", [bs("11010"), reg03, imm24]) - -# BCPEQ cccc,disp17 - 1101_1000_cccc_0100 dddd_dddd_dddd_dddd -addop("BCPEQ", [bs("11011000"), imm4, bs("0100"), disp17]) - -# BCPNE cccc,disp17 - 1101_1000_cccc_0101 dddd_dddd_dddd_dddd -addop("BCPNE", [bs("11011000"), imm4, bs("0101"), disp17]) - -# BCPAT cccc,disp17 - 1101_1000_cccc_0110 dddd_dddd_dddd_dddd -addop("BCPAT", [bs("11011000"), imm4, bs("0110"), disp17]) - -# BCPAF cccc,disp17 - 1101_1000_cccc_0111 dddd_dddd_dddd_dddd -addop("BCPAF", [bs("11011000"), imm4, bs("0111"), disp17]) - -# JMP target24 - 1101_1TTT_TTTT_1000 tttt_tttt_tttt_tttt -addop("JMP", [bs("11011"), imm7_noarg, bs("1000"), imm_target24], - [imm_target24]) # the only interesting operand is imm_target24 - -# BSR disp24 - 1101_1DDD_DDDD_1001 dddd_dddd_dddd_dddd -addop("BSR", [bs("11011"), imm7_noarg, bs("1001"), imm_target24_signed], [imm_target24_signed]) - -# BSRV disp24 1101_1DDD_DDDD_1011 dddd_dddd_dddd_dddd -addop("BSRV", [bs("11011"), imm7_noarg, bs("1011"), imm_target24], [imm_target24]) - - -### <Major Opcode #14> - -# BEQI Rn,imm4,disp17 - 1110_nnnn_iiii_0000 dddd_dddd_dddd_dddd -addop("BEQI", [bs("1110"), reg04, imm4, bs("0000"), disp17]) - -# BEQ Rn,Rm,disp17 - 1110_nnnn_mmmm_0001 dddd_dddd_dddd_dddd -addop("BEQ", [bs("1110"), reg04, reg04, bs("0001"), disp17]) - -# BNEI Rn,imm4,disp17 - 1110_nnnn_iiii_0100 dddd_dddd_dddd_dddd -addop("BNEI", [bs("1110"), reg04, imm4, bs("0100"), disp17]) - -# BNE Rn,Rm,disp17 - 1110_nnnn_mmmm_0101 dddd_dddd_dddd_dddd -addop("BNE", [bs("1110"), reg04, reg04, bs("0101"), disp17]) - -# BGEI Rn,imm4,disp17 - 1110_nnnn_iiii_1000 dddd_dddd_dddd_dddd -addop("BGEI", [bs("1110"), reg04, imm4, bs("1000"), disp17]) - -# REPEAT Rn,disp17 - 1110_nnnn_0000_1001 dddd_dddd_dddd_dddd -addop("REPEAT", [bs("1110"), reg04, bs("00001001"), disp17]) - -# EREPEAT disp17 - 1110_0000_0001_1001 dddd_dddd_dddd_dddd -addop("EREPEAT", [bs("1110000000011001"), disp17]) - -# BLTI Rn,imm4,disp17 - 1110_nnnn_iiii_1100 dddd_dddd_dddd_dddd -addop("BLTI", [bs("1110"), reg04, imm4, bs("1100"), disp17]) - -# (RI) - 1110_xxxx_xxxx_1101 xxxx_xxxx_xxxx_xxxx -addop("(RI)", [bs("1110"), imm8, bs("1101"), imm16]) - -# SW Rn,(abs24) - 1110_nnnn_DDDD_DD10 dddd_dddd_dddd_dddd -addop("SW", [bs("1110"), reg04, imm6_noarg, bs("10"), abs24]) - -# LW Rn,(abs24) - 1110_nnnn_DDDD_DD11 dddd_dddd_dddd_dddd -addop("LW", [bs("1110"), reg04, imm6_noarg, bs("11"), abs24]) - - -### <Major Opcode #15> - -# DSP Rn,Rm,code16 - 1111_nnnn_mmmm_0000 cccc_cccc_cccc_cccc -addop("DSP", [bs("1111"), reg04, reg04, bs("0000"), imm16]) - -# Note: DSP, DSP0 & DSP1 look exactly the same. This is ambiguous, and prevent -# them for being correctly disassembled. DSP0 & DSP1 are arbitrarily -# disabled. - -# DSP0 code24 - 1111_nnnn_mmmm_0000 cccc_cccc_cccc_cccc -#addop("DSP0", [bs("1111"), imm8_noarg, bs("0000"), imm_code24], [imm_code24]) - -# DSP1 Rn,code20 - 1111_nnnn_mmmm_0000 cccc_cccc_cccc_cccc -#addop("DSP1", [bs("1111"), reg04, imm4_noarg, bs("0000"), imm_code20]) - -# LDZ Rn,Rm - 1111_nnnn_mmmm_0001 0000_0000_0000_0000 -addop("LDZ", [bs("1111"), reg04, reg04, bs("00010000000000000000")]) - -# AVE Rn,Rm - 1111_nnnn_mmmm_0001 0000_0000_0000_0010 -addop("AVE", [bs("1111"), reg04, reg04, bs("00010000000000000010")]) - -# ABS Rn,Rm - 1111_nnnn_mmmm_0001 0000_0000_0000_0011 -addop("ABS", [bs("1111"), reg04, reg04, bs("00010000000000000011")]) - -# MIN Rn,Rm - 1111_nnnn_mmmm_0001 0000_0000_0000_0100 -addop("MIN", [bs("1111"), reg04, reg04, bs("00010000000000000100")]) - -# MAX Rn,Rm - 1111_nnnn_mmmm_0001 0000_0000_0000_0101 -addop("MAX", [bs("1111"), reg04, reg04, bs("00010000000000000101")]) - -# MINU Rn,Rm - 1111_nnnn_mmmm_0001 0000_0000_0000_0110 -addop("MINU", [bs("1111"), reg04, reg04, bs("00010000000000000110")]) - -# MAXU Rn,Rm - 1111_nnnn_mmmm_0001 0000_0000_0000_0111 -addop("MAXU", [bs("1111"), reg04, reg04, bs("00010000000000000111")]) - -# SADD Rn,Rm - 1111_nnnn_mmmm_0001 0000_0000_0000_1000 -addop("SADD", [bs("1111"), reg04, reg04, bs("00010000000000001000")]) - -# SADDU Rn,Rm - 1111_nnnn_mmmm_0001 0000_0000_0000_1001 -addop("SADDU", [bs("1111"), reg04, reg04, bs("00010000000000001001")]) - -# SSUB Rn,Rm - 1111_nnnn_mmmm_0001 0000_0000_0000_1010 -addop("SSUB", [bs("1111"), reg04, reg04, bs("00010000000000001010")]) - -# SSUBU Rn,Rm - 1111_nnnn_mmmm_0001 0000_0000_0000_1011 -addop("SSUBU", [bs("1111"), reg04, reg04, bs("00010000000000001011")]) - -# CLIP Rn,imm5 - 1111_nnnn_0000_0001 0001_0000_iiii_i000 -addop("CLIP", [bs("1111"), reg04, bs("0000000100010000"), imm5, bs("000")]) - -# CLIPU Rn,imm5 - 1111_nnnn_0000_0001 0001_0000_iiii_i001 -addop("CLIPU", [bs("1111"), reg04, bs("0000000100010000"), imm5, bs("001")]) - -# (RI) - 1111_xxxx_xxxx_0001 0010_xxxx_xxxx_xxxx -addop("(RI)", [bs("1111"), imm8, bs("00010010"), imm12]) - -# MADD Rn,Rm - 1111_nnnn_mmmm_0001 0011_0000_0000_0100 -addop("MADD", [bs("1111"), reg04, reg04, bs("00010011000000000100")]) - -# MADDU Rn,Rm - 1111_nnnn_mmmm_0001 0011_0000_0000_0101 -addop("MADDU", [bs("1111"), reg04, reg04, bs("00010011000000000101")]) - -# MADDR Rn,Rm - 1111_nnnn_mmmm_0001 0011_0000_0000_0110 -addop("MADDR", [bs("1111"), reg04, reg04, bs("00010011000000000110")]) - -# MADDRU Rn,Rm - 1111_nnnn_mmmm_0001 0011_0000_0000_0111 -addop("MADDRU", [bs("1111"), reg04, reg04, bs("00010011000000000111")]) - -# UCI Rn,Rm,code16 - 1111_nnnn_mmmm_0010 cccc_cccc_cccc_cccc -addop("UCI", [bs("1111"), reg04, reg04, bs("0010"), imm16]) - -# (RI) - 1111_xxxx_xxxx_0011 xxxx_xxxx_xxxx_xxxx -addop("(RI)", [bs("1111"), imm8, bs("0011"), imm16]) - -# STCB Rn,abs16 - 1111_nnnn_0000_0100 aaaa_aaaa_aaaa_aaaa -addop("STCB", [bs("1111"), reg04, bs("00000100"), imm16]) - -# LDCB Rn,abs16 - 1111_nnnn_0001_0100 aaaa_aaaa_aaaa_aaaa -addop("LDCB", [bs("1111"), reg04, bs("00010100"), imm16]) - -# SBCPA CRn,(Rm+),imm8 - 1111_nnnn_mmmm_0101 0000_0000_iiii_iiii -addop("SBCPA", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100000000"), imm8]) - -# SHCPA CRn,(Rm+),imm8.align2 - 1111_nnnn_mmmm_0101 0001_0000_iiii_iii0 -addop("SHCPA", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100010000"), imm8_align2, bs("0")]) - -# SWCPA CRn,(Rm+),imm8.align4 - 1111_nnnn_mmmm_0101 0010_0000_iiii_ii00 -addop("SWCPA", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100100000"), imm8_align4, bs("00")]) - -# SMCPA CRn,(Rm+),imm8.align8 - 1111_nnnn_mmmm_0101 0011_0000_iiii_i000 -addop("SMCPA", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100110000"), imm8_align8, bs("000")]) - -# LBCPA CRn,(Rm+),imm8 - 1111_nnnn_mmmm_0101 0100_0000_iiii_iiii -addop("LBCPA", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101000000"), imm8]) - -# LHCPA CRn,(Rm+),imm8.align2 - 1111_nnnn_mmmm_0101 0101_0000_iiii_iii0 -addop("LHCPA", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101010000"), imm8_align2, bs("0")]) - -# LWCPA CRn,(Rm+),imm8.align4 - 1111_nnnn_mmmm_0101 0110_0000_iiii_ii00 -addop("LWCPA", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101100000"), imm8_align4, bs("00")]) - -# LMCPA CRn,(Rm+),imm8.align8 - 1111_nnnn_mmmm_0101 0111_0000_iiii_i000 -addop("LMCPA", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101110000"), imm8_align8, bs("000")]) - -# SBCPM0 CRn,(Rm+),imm8 - 1111_nnnn_mmmm_0101 0000_1000_iiii_iiii -addop("SBCPM0", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100001000"), imm8]) - -# SHCPM0 CRn,(Rm+),imm8.align2 - 1111_nnnn_mmmm_0101 0001_1000_iiii_iii0 -addop("SHCPM0", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100011000"), imm8_align2, bs("0")]) - -# SWCPM0 CRn,(Rm+),imm8.align4 - 1111_nnnn_mmmm_0101 0010_1000_iiii_ii00 -addop("SWCPM0", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100101000"), imm8_align4, bs("00")]) - -# SMCPM0 CRn,(Rm+),imm8.align8 - 1111_nnnn_mmmm_0101 0011_1000_iiii_i000 -addop("SMCPM0", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100111000"), imm8_align8, bs("000")]) - -# LBCPM0 CRn,(Rm+),imm8 - 1111_nnnn_mmmm_0101 0100_1000_iiii_iiii -addop("LBCPM0", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101001000"), imm8]) - -# LHCPM0 CRn,(Rm+),imm8.align2 - 1111_nnnn_mmmm_0101 0101_1000_iiii_iii0 -addop("LHCPM0", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101011000"), imm8_align2, bs("0")]) - -# LWCPM0 CRn,(Rm+),imm8.align4 - 1111_nnnn_mmmm_0101 0110_1000_iiii_ii00 -addop("LWCPM0", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101101000"), imm8_align4, bs("00")]) - -# LMCPM0 CRn,(Rm+),imm8.align8 - 1111_nnnn_mmmm_0101 0111_1000_iiii_i000 -addop("LMCPM0", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101111000"), imm8_align8, bs("000")]) - -# SBCPM1 CRn,(Rm+),imm8 - 1111_nnnn_mmmm_0101 0000_1100_iiii_iiii -addop("SBCPM1", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100001100"), imm8]) - -# SHCPM1 CRn,(Rm+),imm8.align2 - 1111_nnnn_mmmm_0101 0001_1100_iiii_iii0 -addop("SHCPM1", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100011100"), imm8_align2, bs("0")]) - -# SWCPM1 CRn,(Rm+),imm8.align4 - 1111_nnnn_mmmm_0101 0010_1100_iiii_ii00 -addop("SWCPM1", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100101100"), imm8_align4, bs("00")]) - -# SMCPM1 CRn,(Rm+),imm8.align8 - 1111_nnnn_mmmm_0101 0011_1100_iiii_i000 -addop("SMCPM1", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010100111100"), imm8_align8, bs("000")]) - -# LBCPM1 CRn,(Rm+),imm8 - 1111_nnnn_mmmm_0101 0100_1100_iiii_iiii -addop("LBCPM1", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101001100"), imm8]) - -# LHCPM1 CRn,(Rm+),imm8.align2 - 1111_nnnn_mmmm_0101 0101_1100_iiii_iii0 -addop("LHCPM1", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101011100"), imm8_align2, bs("0")]) - -# LWCPM1 CRn,(Rm+),imm8.align4 - 1111_nnnn_mmmm_0101 0110_1100_iiii_ii00 -addop("LWCPM1", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101101100"), imm8_align4, bs("00")]) - -# LMCPM1 CRn,(Rm+),imm8.align8 - 1111_nnnn_mmmm_0101 0111_1100_iiii_i000 -addop("LMCPM1", [bs("1111"), copro_reg04, reg04_inc_deref, bs("010101111100"), imm8_align8, bs("000")]) - -# (RI) - 1111_xxxx_xxxx_0110 xxxx_xxxx_xxxx_xxxx -addop("(RI)", [bs("1111"), imm8, bs("0110"), imm16]) - -# CP code24 - 1111_CCCC_CCCC_0111 cccc_cccc_cccc_cccc -#addop("CP", [bs("1111"), imm8_noarg, bs("0111"), imm_code24], [imm_code24]) -# Note: CP & CMOV* look exactly the same. This is ambiguous, and prevent -# them for being correctly disassembled. CP was arbitrarily disabled. - -# CP code56 - 1111_CCCC_CCCC_0111 cccc_cccc_cccc_cccc cccc_cccc_cccc_cccc -# 64-bit VLIW operation mode - not implemented - -# CMOV CRn,Rm - 1111_nnnn_mmmm_0111 1111_0000_0000_0000 -#addop("CMOV", [bs("1111"), copro_reg04, reg04, bs("01111111000000000000")]) - -# CMOV Rm,CRn - 1111_nnnn_mmmm_0111 1111_0000_0000_0001 -#addop("CMOV", [bs("1111"), copro_reg04, reg04, bs("01111111000000000001")], [reg04, copro_reg04]) - -# CMOVC CCRn,Rm - 1111_nnnn_mmmm_0111 1111_0000_0000_NN10 -# CRn=NNnnnn -addop("CMOVC", [bs("1111"), imm4_noarg, reg04, bs("0111111100000000"), copro_reg06, bs("10")], [copro_reg06, reg04]) - -# CMOVC Rm,CCRn - 1111_nnnn_mmmm_0111 1111_0000_0000_NN11 -# CRn=NNnnnn -addop("CMOVC", [bs("1111"), imm4_noarg, reg04, bs("0111111100000000"), copro_reg06, bs("11")], [reg04, copro_reg06]) - -# CMOVH CRn,Rm - 1111_nnnn_mmmm_0111 1111_0001_0000_0000 -#addop("CMOVH", [bs("1111"), copro_reg04, reg04, bs("01111111000100000000")]) - -# CMOVH Rm,CRn - 1111_nnnn_mmmm_0111 1111_0001_0000_0001 -#addop("CMOVH", [bs("1111"), copro_reg04, reg04, bs("01111111000100000001")], [reg04, copro_reg04]) - -# Note: the following CMOV* instructions are extensions used when the processor -# has more than 16 coprocessor general-purpose registers. They can be -# used to assemble and disassemble both CMOV* instructuons sets. - -# CMOV CRn,Rm - 1111_nnnn_mmmm_0111 1111_0000_0000_N000 -# CRn=Nnnnn -addop("CMOV", [bs("1111"), imm4_noarg, reg04, bs("0111111100000000"), copro_reg05, bs("000")], [copro_reg05, reg04]) - -# CMOV Rm,CRn - 1111_nnnn_mmmm_0111 1111_0000_0000_N001 -addop("CMOV", [bs("1111"), imm4_noarg, reg04, bs("0111111100000000"), copro_reg05, bs("001")], [reg04, copro_reg05]) - -# CMOVH CRn,Rm - 1111_nnnn_mmmm_0111 1111_0001_0000_N000 -addop("CMOVH", [bs("1111"), imm4_noarg, reg04, bs("0111111100010000"), copro_reg05, bs("000")], [copro_reg05, reg04]) - -# CMOVH Rm,CRn - 1111_nnnn_mmmm_0111 1111_0001_0000_N001 -addop("CMOVH", [bs("1111"), imm4_noarg, reg04, bs("0111111100010000"), copro_reg05, bs("001")], [reg04, copro_reg05]) - -# (RI) - 1111_xxxx_xxxx_10xx xxxx_xxxx_xxxx_xxxx -addop("(RI)", [bs("1111"), imm8, bs("10"), imm18]) - -# SWCP CRn,disp16(Rm) - 1111_nnnn_mmmm_1100 dddd_dddd_dddd_dddd -addop("SWCP", [bs("1111"), copro_reg04, reg04_deref_noarg, bs("1100"), disp16_reg_deref], [copro_reg04, disp16_reg_deref]) - -# LWCP CRn,disp16(Rm) - 1111_nnnn_mmmm_1101 dddd_dddd_dddd_dddd -addop("LWCP", [bs("1111"), copro_reg04, reg04_deref_noarg, bs("1101"), disp16_reg_deref], [copro_reg04, disp16_reg_deref, reg04_deref]) - -# SMCP CRn,disp16(Rm) - 1111_nnnn_mmmm_1110 dddd_dddd_dddd_dddd -addop("SMCP", [bs("1111"), copro_reg04, reg04_deref_noarg, bs("1110"), disp16_reg_deref], [copro_reg04, disp16_reg_deref, reg04_deref]) - -# LMCP CRn,disp16(Rm) - 1111_nnnn_mmmm_1111 dddd_dddd_dddd_dddd -addop("LMCP", [bs("1111"), copro_reg04, reg04_deref_noarg, bs("1111"), disp16_reg_deref], [copro_reg04, disp16_reg_deref]) |