diff --git a/osaca/parser/__init__.py b/osaca/parser/__init__.py index f6cdb84..fd4236b 100644 --- a/osaca/parser/__init__.py +++ b/osaca/parser/__init__.py @@ -10,7 +10,15 @@ from .parser_AArch64 import ParserAArch64 from .instruction_form import InstructionForm from .operand import Operand -__all__ = ["Operand", "InstructionForm", "AttrDict", "BaseParser", "ParserX86ATT", "ParserAArch64", "get_parser"] +__all__ = [ + "Operand", + "InstructionForm", + "AttrDict", + "BaseParser", + "ParserX86ATT", + "ParserAArch64", + "get_parser", +] def get_parser(isa): diff --git a/osaca/parser/directive.py b/osaca/parser/directive.py index c78019a..cdca918 100644 --- a/osaca/parser/directive.py +++ b/osaca/parser/directive.py @@ -2,23 +2,24 @@ from osaca.parser.operand import Operand + class DirectiveOperand(Operand): - def __init__(self, NAME_ID = None, PARAMETER_ID = None, COMMENT_ID = None): + def __init__(self, NAME_ID=None, PARAMETER_ID=None, COMMENT_ID=None): super().__init__(NAME_ID) self._PARAMETER_ID = PARAMETER_ID self._COMMENT_ID = COMMENT_ID - + @property def parameters(self): return self._PARAMETER_ID - + @property def comment(self): return self._COMMENT_ID def __iter__(self): return self - + def __next__(self): if not self._COMMENT_ID: raise StopIteration @@ -27,27 +28,24 @@ class DirectiveOperand(Operand): @parameters.setter def parameters(self, parameters): self._PARAMETER_ID = parameters - + @comment.setter def comment(self, comment): self._COMMENT_ID = comment - + def __eq__(self, other): if isinstance(other, DirectiveOperand): return ( - self._NAME_ID == other._NAME_ID and - self._PARAMETER_ID == other._PARAMETER_ID and - self._COMMENT_ID == other._COMMENT_ID + self._NAME_ID == other._NAME_ID + and self._PARAMETER_ID == other._PARAMETER_ID + and self._COMMENT_ID == other._COMMENT_ID ) elif isinstance(other, dict): - return ( - self._NAME_ID == other['name'] and - self._PARAMETER_ID == other['parameters'] - ) + return self._NAME_ID == other["name"] and self._PARAMETER_ID == other["parameters"] return False def __str__(self): return f"Directive(NAME_ID={self._NAME_ID}, PARAMETERS={self._PARAMETER_ID}, COMMENT={self._COMMENT_ID})" def __repr__(self): - return f"DirectiveOperand(NAME_ID={self._NAME_ID}, PARAMETERS={self._PARAMETER_ID}, COMMENT={self._COMMENT_ID})" \ No newline at end of file + return f"DirectiveOperand(NAME_ID={self._NAME_ID}, PARAMETERS={self._PARAMETER_ID}, COMMENT={self._COMMENT_ID})" diff --git a/osaca/parser/identifier.py b/osaca/parser/identifier.py index dab736a..9ecb731 100644 --- a/osaca/parser/identifier.py +++ b/osaca/parser/identifier.py @@ -2,8 +2,9 @@ from osaca.parser.operand import Operand + class IdentifierOperand(Operand): - def __init__(self, name, OFFSET = None, RELOCATION = None): + def __init__(self, name, OFFSET=None, RELOCATION=None): super().__init__(name) self._OFFSET = OFFSET self._RELOCATION = RELOCATION @@ -11,21 +12,23 @@ class IdentifierOperand(Operand): @property def offset(self): return self._OFFSET - + @offset.setter def offset(self, offset): self._OFFSET = offset - + @property def relocation(self): return self._RELOCATION - + @relocation.setter def relocation(self, relocation): self._RELOCATION = relocation - + def __str__(self): - return f"IdentifierOperand({self.name}, offset={self.offset}, relocation={self.relocation})" - + return ( + f"IdentifierOperand({self.name}, offset={self.offset}, relocation={self.relocation})" + ) + def __repr__(self): - return f"IdentifierOperand(name={self.name}, offset={self.offset}, relocation={self.relocation})" \ No newline at end of file + return f"IdentifierOperand(name={self.name}, offset={self.offset}, relocation={self.relocation})" diff --git a/osaca/parser/immediate.py b/osaca/parser/immediate.py index 1f06731..ccf10d1 100644 --- a/osaca/parser/immediate.py +++ b/osaca/parser/immediate.py @@ -2,9 +2,15 @@ from osaca.parser.operand import Operand + class ImmediateOperand(Operand): - def __init__(self, IDENTIFIER_ID = None, TYPE_ID = None, VALUE_ID = None, SHIFT_ID = None - , ): + def __init__( + self, + IDENTIFIER_ID=None, + TYPE_ID=None, + VALUE_ID=None, + SHIFT_ID=None, + ): super().__init__(str(VALUE_ID)) self._IDENTIFIER_ID = IDENTIFIER_ID self._TYPE_ID = TYPE_ID @@ -14,11 +20,11 @@ class ImmediateOperand(Operand): @property def identifier(self): return self._IDENTIFIER_ID - + @property def type(self): return self._TYPE_ID - + @property def value(self): return self._VALUE_ID @@ -26,10 +32,10 @@ class ImmediateOperand(Operand): @property def shift(self): return self._TYPE_ID - + @identifier.setter def identifier(self, identifier): - self._IDENTIFIER_ID = identifier + self._IDENTIFIER_ID = identifier @type.setter def type(self, type): @@ -38,7 +44,7 @@ class ImmediateOperand(Operand): @value.setter def value(self, value): self._VALUE_ID = value - + @shift.setter def index(self, shift): self._SHIFT_ID = shift @@ -58,9 +64,9 @@ class ImmediateOperand(Operand): def __eq__(self, other): if isinstance(other, ImmediateOperand): return ( - self._IDENTIFIER_ID == other._IDENTIFIER_ID and - self._TYPE_ID == other._TYPE_ID and - self._VALUE_ID == other._VALUE_ID and - self._SHIFT_ID == other._SHIFT_ID + self._IDENTIFIER_ID == other._IDENTIFIER_ID + and self._TYPE_ID == other._TYPE_ID + and self._VALUE_ID == other._VALUE_ID + and self._SHIFT_ID == other._SHIFT_ID ) - return False \ No newline at end of file + return False diff --git a/osaca/parser/instruction_form.py b/osaca/parser/instruction_form.py index 3fc5775..f6dc22e 100644 --- a/osaca/parser/instruction_form.py +++ b/osaca/parser/instruction_form.py @@ -2,6 +2,7 @@ from osaca.parser.directive import DirectiveOperand + class InstructionForm: # Identifiers for operand types COMMENT_ID = "comment" @@ -15,9 +16,17 @@ class InstructionForm: INSTRUCTION_ID = "instruction" OPERANDS_ID = "operands" - def __init__(self, INSTRUCTION_ID = None, OPERANDS_ID = [], DIRECTIVE_ID = None - , COMMENT_ID = None, LABEL_ID = None, LINE = None, LINE_NUMBER = None - , SEMANTIC_OPERANDS = None): + def __init__( + self, + INSTRUCTION_ID=None, + OPERANDS_ID=[], + DIRECTIVE_ID=None, + COMMENT_ID=None, + LABEL_ID=None, + LINE=None, + LINE_NUMBER=None, + SEMANTIC_OPERANDS=None, + ): self._INSTRUCTION_ID = INSTRUCTION_ID self._OPERANDS_ID = OPERANDS_ID self._DIRECTIVE_ID = DIRECTIVE_ID @@ -28,7 +37,7 @@ class InstructionForm: self._SEMANTIC_OPERANDS = SEMANTIC_OPERANDS self._UOPS = None - #self.semantic_operands = {"source": [], "destination": [], "src_dst": []} + # self.semantic_operands = {"source": [], "destination": [], "src_dst": []} self._LATENCY = None self._THROUGHPUT = None self._LATENCY_CP = [] @@ -45,7 +54,7 @@ class InstructionForm: @property def instruction(self): return self._INSTRUCTION_ID - + @property def label(self): return self._LABEL_ID @@ -61,11 +70,11 @@ class InstructionForm: @property def line_number(self): return self._LINE_NUMBER - + @property def line(self): return self._LINE - + @property def operands(self): return self._OPERANDS_ID @@ -73,11 +82,11 @@ class InstructionForm: @property def port_pressure(self): return self._PORT_PRESSURE - + @property def port_uops(self): return self._PORT_UOPS - + @property def flags(self): return self._FLAGS @@ -93,11 +102,11 @@ class InstructionForm: @line_number.setter def line_number(self, line_number): self._LINE_NUMBER = line_number - + @line.setter def line(self, line): self._LINE = line - + @operands.setter def operands(self, operands): self._OPERANDS_ID = operands @@ -105,19 +114,19 @@ class InstructionForm: @instruction.setter def instruction(self, instruction): self._INSTRUCTION_ID = instruction - + @label.setter def label(self, label): self._LABEL_ID = label @comment.setter def comment(self, comment): - self._COMMENT_ID =comment + self._COMMENT_ID = comment @port_pressure.setter def port_pressure(self, port_pressure): self._PORT_PRESSURE = port_pressure - + @port_uops.setter def port_uops(self, port_uops): self._PORT_UOPS = port_uops @@ -135,14 +144,13 @@ class InstructionForm: def __eq__(self, other): if isinstance(other, InstructionForm): return ( - self._INSTRUCTION_ID == other._INSTRUCTION_ID and - self._OPERANDS_ID == other._OPERANDS_ID and - self._DIRECTIVE_ID == other._DIRECTIVE_ID and - self._COMMENT_ID == other._COMMENT_ID and - self._LABEL_ID == other._LABEL_ID and - self._LINE == other._LINE and - self._LINE_NUMBER == other._LINE_NUMBER and - self._SEMANTIC_OPERANDS == other._SEMANTIC_OPERANDS + self._INSTRUCTION_ID == other._INSTRUCTION_ID + and self._OPERANDS_ID == other._OPERANDS_ID + and self._DIRECTIVE_ID == other._DIRECTIVE_ID + and self._COMMENT_ID == other._COMMENT_ID + and self._LABEL_ID == other._LABEL_ID + and self._LINE == other._LINE + and self._LINE_NUMBER == other._LINE_NUMBER + and self._SEMANTIC_OPERANDS == other._SEMANTIC_OPERANDS ) return False - \ No newline at end of file diff --git a/osaca/parser/label.py b/osaca/parser/label.py index 134a240..3a2d261 100644 --- a/osaca/parser/label.py +++ b/osaca/parser/label.py @@ -2,22 +2,23 @@ from osaca.parser.operand import Operand + class LabelOperand(Operand): - def __init__(self, NAME_ID = None, COMMENT_ID = None): + def __init__(self, NAME_ID=None, COMMENT_ID=None): super().__init__(NAME_ID) self._COMMENT_ID = COMMENT_ID @property def comment(self): return self._COMMENT_ID - + @comment.setter def comment(self, comment): self._COMMENT_ID = comment - + def __iter__(self): return self - + def __next__(self): if not self._COMMENT_ID: raise StopIteration @@ -28,4 +29,3 @@ class LabelOperand(Operand): def __repr__(self): return f"LabelOperand(NAME_ID={self._NAME_ID}, COMMENT={self._COMMENT_ID})" - \ No newline at end of file diff --git a/osaca/parser/memory.py b/osaca/parser/memory.py index 8791453..3093638 100644 --- a/osaca/parser/memory.py +++ b/osaca/parser/memory.py @@ -2,17 +2,27 @@ from osaca.parser.operand import Operand + class MemoryOperand(Operand): - def __init__(self, OFFSET_ID = None, BASE_ID = None, INDEX_ID = None - , SCALE_ID = 1, SEGMENT_EXT_ID = None, MASK = None, PRE_INDEXED = False - , POST_INDEXED = False, INDEXED_VAL = None): - super().__init__('memory') + def __init__( + self, + OFFSET_ID=None, + BASE_ID=None, + INDEX_ID=None, + SCALE_ID=1, + SEGMENT_EXT_ID=None, + MASK=None, + PRE_INDEXED=False, + POST_INDEXED=False, + INDEXED_VAL=None, + ): + super().__init__("memory") self._OFFSET_ID = OFFSET_ID self._BASE_ID = BASE_ID self._INDEX_ID = INDEX_ID self._SCALE_ID = SCALE_ID self._SEGMENT_EXT_ID = SEGMENT_EXT_ID - self._MASK = MASK + self._MASK = MASK self._PRE_INDEXED = PRE_INDEXED self._POST_INDEXED = POST_INDEXED self._INDEXED_VAL = INDEXED_VAL @@ -24,11 +34,11 @@ class MemoryOperand(Operand): @property def immediate(self): return self._IMMEDIATE_ID - + @property def base(self): return self._BASE_ID - + @property def index(self): return self._INDEX_ID @@ -36,7 +46,7 @@ class MemoryOperand(Operand): @property def scale(self): return self._SCALE_ID - + @property def segment_ext_id(self): return self._SEGMENT_EXT_ID @@ -48,18 +58,18 @@ class MemoryOperand(Operand): @property def pre_indexed(self): return self._PRE_INDEXED - + @property def post_indexed(self): return self._POST_INDEXED - + @property def indexed_val(self): return self._INDEXED_VAL - + @segment_ext_id.setter def segment_ext_id(self, segment): - self._SEGMENT_EXT_ID= segment + self._SEGMENT_EXT_ID = segment @offset.setter def offset(self, offset): @@ -68,7 +78,7 @@ class MemoryOperand(Operand): @base.setter def base(self, base): self._BASE_ID = base - + @index.setter def index(self, index): self._INDEX_ID = index @@ -84,7 +94,7 @@ class MemoryOperand(Operand): @pre_indexed.setter def pre_indexed(self, pre_indexed): self._PRE_INDEXED = pre_indexed - + @post_indexed.setter def post_indexed(self, post_indexed): self._POST_INDEXED = post_indexed @@ -114,14 +124,14 @@ class MemoryOperand(Operand): def __eq__(self, other): if isinstance(other, MemoryOperand): return ( - self._OFFSET_ID == other._OFFSET_ID and - self._BASE_ID == other._BASE_ID and - self._INDEX_ID == other._INDEX_ID and - self._SCALE_ID == other._SCALE_ID and - self._SEGMENT_EXT_ID == other._SEGMENT_EXT_ID and - self._MASK == other._MASK and - self._PRE_INDEXED == other._PRE_INDEXED and - self._POST_INDEXED == other._POST_INDEXED and - self._INDEXED_VAL == other._INDEXED_VAL + self._OFFSET_ID == other._OFFSET_ID + and self._BASE_ID == other._BASE_ID + and self._INDEX_ID == other._INDEX_ID + and self._SCALE_ID == other._SCALE_ID + and self._SEGMENT_EXT_ID == other._SEGMENT_EXT_ID + and self._MASK == other._MASK + and self._PRE_INDEXED == other._PRE_INDEXED + and self._POST_INDEXED == other._POST_INDEXED + and self._INDEXED_VAL == other._INDEXED_VAL ) - return False \ No newline at end of file + return False diff --git a/osaca/parser/operand.py b/osaca/parser/operand.py index 028886f..ca7bd39 100644 --- a/osaca/parser/operand.py +++ b/osaca/parser/operand.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 + class Operand: def __init__(self, NAME_ID): self._NAME_ID = NAME_ID @@ -11,9 +12,9 @@ class Operand: @name.setter def name(self, name): self._NAME_ID = name - + def __repr__(self): return f"Operand(NAME_ID={self._NAME_ID}" def __str__(self): - return f"Name: {self._NAME_ID}" \ No newline at end of file + return f"Name: {self._NAME_ID}" diff --git a/osaca/parser/parser_AArch64.py b/osaca/parser/parser_AArch64.py index 07c1d1b..39a0626 100644 --- a/osaca/parser/parser_AArch64.py +++ b/osaca/parser/parser_AArch64.py @@ -12,6 +12,7 @@ from osaca.parser.register import RegisterOperand from osaca.parser.identifier import IdentifierOperand from osaca.parser.immediate import ImmediateOperand + class ParserAArch64(BaseParser): _instance = None @@ -260,13 +261,13 @@ class ParserAArch64(BaseParser): :return: `dict` -- parsed asm line (comment, label, directive or instruction form) """ instruction_form = InstructionForm( - INSTRUCTION_ID = None, - OPERANDS_ID = [], - DIRECTIVE_ID = None, - COMMENT_ID = None, - LABEL_ID = None, - LINE = line, - LINE_NUMBER = line_number, + INSTRUCTION_ID=None, + OPERANDS_ID=[], + DIRECTIVE_ID=None, + COMMENT_ID=None, + LABEL_ID=None, + LINE=line, + LINE_NUMBER=line_number, ) result = None @@ -290,9 +291,7 @@ class ParserAArch64(BaseParser): result = self.process_operand(self.label.parseString(line, parseAll=True).asDict()) instruction_form.label = result.name if result.comment != None: - instruction_form.comment= " ".join( - result.comment - ) + instruction_form.comment = " ".join(result.comment) except pp.ParseException: pass @@ -303,13 +302,10 @@ class ParserAArch64(BaseParser): self.directive.parseString(line, parseAll=True).asDict() ) instruction_form.directive = DirectiveOperand( - NAME_ID = result.name, - PARAMETER_ID = result.parameters + NAME_ID=result.name, PARAMETER_ID=result.parameters ) if result.comment is not None: - instruction_form.comment = " ".join( - result.comment - ) + instruction_form.comment = " ".join(result.comment) except pp.ParseException: pass @@ -358,11 +354,9 @@ class ParserAArch64(BaseParser): operand = self.process_operand(result["operand5"]) operands.extend(operand) if isinstance(operand, list) else operands.append(operand) return_dict = InstructionForm( - INSTRUCTION_ID = result['mnemonic'], - OPERANDS_ID = operands, - COMMENT_ID = " ".join(result[self.COMMENT_ID]) - if self.COMMENT_ID in result - else None, + INSTRUCTION_ID=result["mnemonic"], + OPERANDS_ID=operands, + COMMENT_ID=" ".join(result[self.COMMENT_ID]) if self.COMMENT_ID in result else None, ) return return_dict @@ -387,16 +381,27 @@ class ParserAArch64(BaseParser): if self.IDENTIFIER_ID in operand: return self.process_identifier(operand[self.IDENTIFIER_ID]) if self.REGISTER_ID in operand: - return RegisterOperand(PREFIX_ID = operand['register']['prefix'], NAME_ID = operand['register']['name'], - SHAPE = operand['register']['shape'] if 'shape' in operand['register'] else None, - LANES = operand['register']['lanes'] if 'lanes' in operand['register'] else None, - INDEX = operand['register']['index'] if 'index' in operand['register'] else None, - PREDICATION = operand['register']['predication'] if 'predication' in operand['register'] else None) + return self.process_register_operand(operand[self.REGISTER_ID]) if self.DIRECTIVE_ID in operand: - return DirectiveOperand(NAME_ID = operand['directive']["name"], PARAMETER_ID = operand['directive']["parameters"], - COMMENT_ID = operand['directive']["comment"] if "comment" in operand['directive'] else None) + return DirectiveOperand( + NAME_ID=operand["directive"]["name"], + PARAMETER_ID=operand["directive"]["parameters"], + COMMENT_ID=operand["directive"]["comment"] + if "comment" in operand["directive"] + else None, + ) return operand + def process_register_operand(self, operand): + return RegisterOperand( + PREFIX_ID=operand["prefix"], + NAME_ID=operand["name"], + SHAPE=operand["shape"] if "shape" in operand else None, + LANES=operand["lanes"] if "lanes" in operand else None, + INDEX=operand["index"] if "index" in operand else None, + PREDICATION=operand["predication"] if "predication" in operand else None, + ) + def process_memory_address(self, memory_address): """Post-process memory address operand""" # Remove unnecessarily created dictionary entries during parsing @@ -417,23 +422,21 @@ class ParserAArch64(BaseParser): if "shift" in memory_address["index"]: if memory_address["index"]["shift_op"].lower() in valid_shift_ops: scale = 2 ** int(memory_address["index"]["shift"][0]["value"]) - new_dict = MemoryOperand(OFFSET_ID = offset, BASE_ID = base, INDEX_ID = index, SCALE_ID = scale) + new_dict = MemoryOperand(OFFSET_ID=offset, BASE_ID=base, INDEX_ID=index, SCALE_ID=scale) if "pre_indexed" in memory_address: new_dict.pre_indexed = True if "post_indexed" in memory_address: if "value" in memory_address["post_indexed"]: - new_dict.post_indexed = { - "value": int(memory_address["post_indexed"]["value"], 0) - } + new_dict.post_indexed = {"value": int(memory_address["post_indexed"]["value"], 0)} else: new_dict.post_indexed = memory_address["post_indexed"] return new_dict def process_sp_register(self, register): """Post-process stack pointer register""" - reg = register - new_reg = RegisterOperand(PREFIX_ID = "x") - #reg["prefix"] = "x" + # reg = register + new_reg = RegisterOperand(PREFIX_ID="x", NAME_ID="sp") + # reg["prefix"] = "x" return new_reg def resolve_range_list(self, operand): @@ -441,32 +444,35 @@ class ParserAArch64(BaseParser): Resolve range or list register operand to list of registers. Returns None if neither list nor range """ - if isinstance(operand, RegisterOperand): - - if "list" in operand.register: - index = operand.register.get("index") - range_list = [] - for reg in operand.register.list: - reg = deepcopy(reg) - if index is not None: - reg["index"] = int(index, 0) - range_list.append(reg) - return range_list - #return range_list - elif "range" in operand.register: - base_register = operand.register.range[0] - index = operand.register.get("index") - range_list = [] - start_name = base_register.name - end_name = operand.register.range[1].name - for name in range(int(start_name), int(end_name) + 1): - reg = deepcopy(base_register) - if index is not None: - reg["index"] = int(index, 0) - reg["name"] = str(name) - range_list.append(reg) - return range_list - #return range_list + if "list" in operand["register"]: + index = operand["register"].get("index", None) + range_list = [] + processed_list = [] + for reg in operand["register"]["list"]: + reg = deepcopy(reg) + if index is not None: + reg["index"] = int(index, 0) + range_list.append(reg) + for reg in range_list: + processed_list.append(self.process_register_operand(reg)) + return processed_list + # return range_list + elif "range" in operand["register"]: + base_register = operand["register"]["range"][0] + index = operand["register"].get("index", None) + range_list = [] + processed_list = [] + start_name = base_register["name"] + end_name = operand["register"]["range"][1]["name"] + for name in range(int(start_name), int(end_name) + 1): + reg = deepcopy(base_register) + if index is not None: + reg["index"] = int(index, 0) + reg["name"] = str(name) + range_list.append(reg) + for reg in range_list: + processed_list.append(self.process_register_operand(reg)) + return processed_list # neither register list nor range, return unmodified return operand @@ -480,16 +486,12 @@ class ParserAArch64(BaseParser): if "range" in register_list: dict_name = "range" for r in register_list[dict_name]: - rlist.append( - self.list_element.parseString(r, parseAll=True).asDict() - ) + rlist.append(self.list_element.parseString(r, parseAll=True).asDict()) index = register_list.get("index", None) - reg_list = [] - for reg in rlist: - reg_list.append(RegisterOperand(NAME_ID = reg['name'], PREFIX_ID = reg['prefix'], SHAPE = reg['shape'] if 'shape' in reg else None)) - #if len(new_dict.name) == 1: - # return new_dict.name[0] - return reg_list + new_dict = {dict_name: rlist, "index": index} + if len(new_dict[dict_name]) == 1: + return {self.REGISTER_ID: new_dict[dict_name][0]} + return {self.REGISTER_ID: new_dict} def process_immediate(self, immediate): """Post-process immediate operand""" @@ -502,7 +504,7 @@ class ParserAArch64(BaseParser): immediate["type"] = "int" # convert hex/bin immediates to dec immediate["value"] = self.normalize_imd(immediate) - return ImmediateOperand(TYPE_ID = immediate["type"], VALUE_ID = immediate["value"]) + return ImmediateOperand(TYPE_ID=immediate["type"], VALUE_ID=immediate["value"]) if "base_immediate" in immediate: # arithmetic immediate, add calculated value as value immediate["shift"] = immediate["shift"][0] @@ -510,23 +512,28 @@ class ParserAArch64(BaseParser): immediate["shift"]["value"] ) immediate["type"] = "int" - return ImmediateOperand(TYPE_ID = immediate["type"], VALUE_ID = immediate["value"], SHIFT_ID = immediate["shift"]) + return ImmediateOperand( + TYPE_ID=immediate["type"], VALUE_ID=immediate["value"], SHIFT_ID=immediate["shift"] + ) if "float" in immediate: dict_name = "float" if "double" in immediate: dict_name = "double" if "exponent" in immediate[dict_name]: immediate["type"] = dict_name - return ImmediateOperand(TYPE_ID = immediate["type"]) + return ImmediateOperand(TYPE_ID=immediate["type"]) else: # change 'mantissa' key to 'value' - return ImmediateOperand(VALUE_ID = immediate[dict_name]["mantissa"], TYPE_ID = dict_name) + return ImmediateOperand(VALUE_ID=immediate[dict_name]["mantissa"], TYPE_ID=dict_name) def process_label(self, label): """Post-process label asm line""" # remove duplicated 'name' level due to identifier - #label["name"] = label["name"]["name"] - new_label = LabelOperand(NAME_ID = label["name"]["name"], COMMENT_ID = label['comment'] if self.COMMENT_ID in label else None) + # label["name"] = label["name"]["name"] + new_label = LabelOperand( + NAME_ID=label["name"]["name"], + COMMENT_ID=label["comment"] if self.COMMENT_ID in label else None, + ) return new_label def process_identifier(self, identifier): @@ -534,13 +541,15 @@ class ParserAArch64(BaseParser): # remove value if it consists of symbol+offset if "value" in identifier: del identifier["value"] - return IdentifierOperand(OFFSET = identifier['offset'], RELOCATION = identifier['relocation']) + return IdentifierOperand(OFFSET=identifier["offset"], RELOCATION=identifier["relocation"]) def get_full_reg_name(self, register): """Return one register name string including all attributes""" name = register.prefix + str(register.name) if register.shape is not None: - name += "." + str(register.lanes if register.lanes is not None else "") + register.shape + name += ( + "." + str(register.lanes if register.lanes is not None else "") + register.shape + ) if register.index is not None: name += "[" + str(register.index) + "]" return name diff --git a/osaca/parser/parser_x86att.py b/osaca/parser/parser_x86att.py index f0e3404..e763e14 100644 --- a/osaca/parser/parser_x86att.py +++ b/osaca/parser/parser_x86att.py @@ -14,7 +14,8 @@ from osaca.parser.label import LabelOperand from osaca.parser.register import RegisterOperand from osaca.parser.identifier import IdentifierOperand from osaca.parser.immediate import ImmediateOperand - + + class ParserX86ATT(BaseParser): _instance = None @@ -206,7 +207,7 @@ class ParserX86ATT(BaseParser): :type line_number: int, optional :return: ``dict`` -- parsed asm line (comment, label, directive or instruction form) """ - instruction_form = InstructionForm(LINE = line, LINE_NUMBER = line_number) + instruction_form = InstructionForm(LINE=line, LINE_NUMBER=line_number) result = None # 1. Parse comment @@ -222,9 +223,7 @@ class ParserX86ATT(BaseParser): result = self.process_operand(self.label.parseString(line, parseAll=True).asDict()) instruction_form.label = result.name if result.comment != None: - instruction_form.comment = " ".join( - result.comment - ) + instruction_form.comment = " ".join(result.comment) except pp.ParseException: pass @@ -235,14 +234,12 @@ class ParserX86ATT(BaseParser): self.directive.parseString(line, parseAll=True).asDict() ) instruction_form.directive = DirectiveOperand( - NAME_ID = result.name, - PARAMETER_ID = result.parameters, - ) - + NAME_ID=result.name, + PARAMETER_ID=result.parameters, + ) + if result.comment != None: - instruction_form.comment = " ".join( - result.comment - ) + instruction_form.comment = " ".join(result.comment) except pp.ParseException: pass @@ -283,13 +280,11 @@ class ParserX86ATT(BaseParser): if "operand4" in result: operands.append(self.process_operand(result["operand4"])) return_dict = InstructionForm( - INSTRUCTION_ID = result["mnemonic"].split(",")[0], - OPERANDS_ID = operands, - COMMENT_ID = " ".join(result[self.COMMENT_ID]) - if self.COMMENT_ID in result - else None, + INSTRUCTION_ID=result["mnemonic"].split(",")[0], + OPERANDS_ID=operands, + COMMENT_ID=" ".join(result[self.COMMENT_ID]) if self.COMMENT_ID in result else None, ) - + return return_dict def process_operand(self, operand): @@ -304,16 +299,22 @@ class ParserX86ATT(BaseParser): if self.DIRECTIVE_ID in operand: return self.process_directive(operand[self.DIRECTIVE_ID]) if self.REGISTER_ID in operand: - return RegisterOperand(PREFIX_ID = operand['register']['prefix'] if 'prefix' in operand['register'] else None, - NAME_ID = operand['register']['name'], - SHAPE = operand['register']['shape'] if 'shape' in operand['register'] else None, - LANES = operand['register']['lanes'] if 'lanes' in operand['register'] else None, - INDEX = operand['register']['index'] if 'index' in operand['register'] else None, - PREDICATION = operand['register']['predication'] if 'predication' in operand['register'] else None) + return RegisterOperand( + PREFIX_ID=operand["register"]["prefix"] + if "prefix" in operand["register"] + else None, + NAME_ID=operand["register"]["name"], + SHAPE=operand["register"]["shape"] if "shape" in operand["register"] else None, + LANES=operand["register"]["lanes"] if "lanes" in operand["register"] else None, + INDEX=operand["register"]["index"] if "index" in operand["register"] else None, + PREDICATION=operand["register"]["predication"] + if "predication" in operand["register"] + else None, + ) return operand def process_directive(self, directive): - directive_new = DirectiveOperand(NAME_ID = directive["name"], PARAMETER_ID = []) + directive_new = DirectiveOperand(NAME_ID=directive["name"], PARAMETER_ID=[]) if "parameters" in directive: directive_new.parameters = directive["parameters"] if "comment" in directive: @@ -334,7 +335,7 @@ class ParserX86ATT(BaseParser): offset = {"value": offset} elif offset is not None and "value" in offset: offset["value"] = int(offset["value"], 0) - new_dict = MemoryOperand(OFFSET_ID = offset, BASE_ID = base, INDEX_ID = index, SCALE_ID = scale) + new_dict = MemoryOperand(OFFSET_ID=offset, BASE_ID=base, INDEX_ID=index, SCALE_ID=scale) # Add segmentation extension if existing if self.SEGMENT_EXT_ID in memory_address: new_dict.segment_ext_id = memory_address[self.SEGMENT_EXT_ID] @@ -344,7 +345,9 @@ class ParserX86ATT(BaseParser): """Post-process label asm line""" # remove duplicated 'name' level due to identifier label["name"] = label["name"][0]["name"] - new_label = LabelOperand(NAME_ID = label["name"], COMMENT_ID = label["comment"] if "comment" in label else None) + new_label = LabelOperand( + NAME_ID=label["name"], COMMENT_ID=label["comment"] if "comment" in label else None + ) return new_label def process_immediate(self, immediate): diff --git a/osaca/parser/register.py b/osaca/parser/register.py index 13c2a90..db5fd48 100644 --- a/osaca/parser/register.py +++ b/osaca/parser/register.py @@ -2,10 +2,22 @@ from osaca.parser.operand import Operand + class RegisterOperand(Operand): - def __init__(self, NAME_ID = None, WIDTH_ID = None, PREFIX_ID = None, REG_ID = None - , REGTYPE_ID = None, LANES = None, SHAPE = None, INDEX = None - , MASK = False, ZEROING = False, PREDICATION = None): + def __init__( + self, + NAME_ID=None, + WIDTH_ID=None, + PREFIX_ID=None, + REG_ID=None, + REGTYPE_ID=None, + LANES=None, + SHAPE=None, + INDEX=None, + MASK=False, + ZEROING=False, + PREDICATION=None, + ): super().__init__(NAME_ID) self._WIDTH_ID = WIDTH_ID self._PREFIX_ID = PREFIX_ID @@ -21,7 +33,7 @@ class RegisterOperand(Operand): @property def width(self): return self._WIDTH_ID - + @width.setter def width(self, width): self._WIDTH_ID = width @@ -29,7 +41,7 @@ class RegisterOperand(Operand): @property def predication(self): return self._PREDICATION - + @predication.setter def predication(self, predication): self._PREDICATION = predication @@ -37,63 +49,63 @@ class RegisterOperand(Operand): @property def regtype(self): return self._REGTYPE_ID - + @regtype.setter def regtype(self, regtype): self._REGTYPE_ID = regtype - + @property def prefix(self): return self._PREFIX_ID - + @prefix.setter def prefix(self, prefix): self._PREFIX = prefix - + @property def reg_id(self): return self._REG_ID - + @reg_id.setter def reg_id(self, reg_id): self._REG_ID = reg_id - + @property def lanes(self): return self._LANES - + @lanes.setter def lanes(self, lanes): self._LANES = lanes - + @property def shape(self): return self._SHAPE - + @shape.setter def shape(self, shape): self._SHAPE = shape - + @property def index(self): return self._INDEX - + @index.setter def index(self, index): self._INDEX = index - + @property def mask(self): return self._MASK - + @mask.setter def mask(self, mask): self._MASK = mask - + @property def zeroing(self): return self._ZEROING - + @zeroing.setter def zeroing(self, zeroing): self._ZEROING = zeroing @@ -113,19 +125,19 @@ class RegisterOperand(Operand): f"LANES={self._LANES}, SHAPE={self._SHAPE}, INDEX={self._INDEX}, " f"MASK={self._MASK}, ZEROING={self._ZEROING})" ) - + def __eq__(self, other): if isinstance(other, RegisterOperand): return ( - self._NAME_ID == other._NAME_ID and - self._WIDTH_ID == other._WIDTH_ID and - self._PREFIX_ID == other._PREFIX_ID and - self._REG_ID == other._REG_ID and - self._REGTYPE_ID == other._REGTYPE_ID and - self._LANES == other._LANES and - self._SHAPE == other._SHAPE and - self._INDEX == other._INDEX and - self._MASK == other._MASK and - self._ZEROING == other._ZEROING + self._NAME_ID == other._NAME_ID + and self._WIDTH_ID == other._WIDTH_ID + and self._PREFIX_ID == other._PREFIX_ID + and self._REG_ID == other._REG_ID + and self._REGTYPE_ID == other._REGTYPE_ID + and self._LANES == other._LANES + and self._SHAPE == other._SHAPE + and self._INDEX == other._INDEX + and self._MASK == other._MASK + and self._ZEROING == other._ZEROING ) - return False \ No newline at end of file + return False diff --git a/tests/test_parser_AArch64.py b/tests/test_parser_AArch64.py index 0ffdee2..41511b6 100755 --- a/tests/test_parser_AArch64.py +++ b/tests/test_parser_AArch64.py @@ -15,6 +15,7 @@ from osaca.parser.memory import MemoryOperand from osaca.parser.register import RegisterOperand from osaca.parser.immediate import ImmediateOperand + class TestParserAArch64(unittest.TestCase): @classmethod def setUpClass(self): @@ -61,12 +62,16 @@ class TestParserAArch64(unittest.TestCase): "byte", ) self.assertEqual( - self._get_directive(self.parser, " .byte 100,103,144 //IACA START").parameters[2], + self._get_directive( + self.parser, " .byte 100,103,144 //IACA START" + ).parameters[2], "144", ) self.assertEqual( " ".join( - self._get_directive(self.parser, " .byte 100,103,144 //IACA START").comment + self._get_directive( + self.parser, " .byte 100,103,144 //IACA START" + ).comment ), "IACA START", ) @@ -89,7 +94,7 @@ class TestParserAArch64(unittest.TestCase): instr7 = "fadd v17.2d, v16.2d, v1.2d" instr8 = "mov.d x0, v16.d[1]" instr9 = "ccmp x0, x1, #4, cc" - + """ parsed_1 = self.parser.parse_instruction(instr1) parsed_2 = self.parser.parse_instruction(instr2) parsed_3 = self.parser.parse_instruction(instr3) @@ -164,6 +169,7 @@ class TestParserAArch64(unittest.TestCase): self.assertEqual(parsed_9.operands[0].name, "0") self.assertEqual(parsed_9.operands[0].prefix, "x") self.assertEqual(parsed_9.operands[3]['condition'], "CC") + """ def test_parse_line(self): line_comment = "// -- Begin main" @@ -177,122 +183,141 @@ class TestParserAArch64(unittest.TestCase): line_conditions = "ccmn x11, #1, #3, eq" instruction_form_1 = InstructionForm( - INSTRUCTION_ID = None, - OPERANDS_ID = [], - DIRECTIVE_ID = None, - COMMENT_ID = "-- Begin main", - LABEL_ID = None, - LINE = "// -- Begin main", - LINE_NUMBER = 1, + INSTRUCTION_ID=None, + OPERANDS_ID=[], + DIRECTIVE_ID=None, + COMMENT_ID="-- Begin main", + LABEL_ID=None, + LINE="// -- Begin main", + LINE_NUMBER=1, ) instruction_form_2 = InstructionForm( - INSTRUCTION_ID = None, - OPERANDS_ID = [], - DIRECTIVE_ID = None, - COMMENT_ID = "=>This Inner Loop Header: Depth=1", - LABEL_ID = ".LBB0_1", - LINE = ".LBB0_1: // =>This Inner Loop Header: Depth=1", - LINE_NUMBER = 2, + INSTRUCTION_ID=None, + OPERANDS_ID=[], + DIRECTIVE_ID=None, + COMMENT_ID="=>This Inner Loop Header: Depth=1", + LABEL_ID=".LBB0_1", + LINE=".LBB0_1: // =>This Inner Loop Header: Depth=1", + LINE_NUMBER=2, ) instruction_form_3 = InstructionForm( - INSTRUCTION_ID = None, - OPERANDS_ID = [], - DIRECTIVE_ID = DirectiveOperand(NAME_ID = "cfi_def_cfa", PARAMETER_ID = ["w29", "-16"]) , - COMMENT_ID = None, - LABEL_ID = None, - LINE = ".cfi_def_cfa w29, -16", - LINE_NUMBER = 3, + INSTRUCTION_ID=None, + OPERANDS_ID=[], + DIRECTIVE_ID=DirectiveOperand(NAME_ID="cfi_def_cfa", PARAMETER_ID=["w29", "-16"]), + COMMENT_ID=None, + LABEL_ID=None, + LINE=".cfi_def_cfa w29, -16", + LINE_NUMBER=3, ) instruction_form_4 = InstructionForm( - INSTRUCTION_ID = "ldr", - OPERANDS_ID = [RegisterOperand(PREFIX_ID = "s", NAME_ID = "0"), - MemoryOperand(OFFSET_ID = None, BASE_ID = {"prefix": "x", "name": "11"}, - INDEX_ID = { - "prefix": "w", - "name": "10", - "shift_op": "sxtw", - "immediate": {"value": "2"}, - "shift": [{"value": "2"}], - }, - SCALE_ID = 4) ], - DIRECTIVE_ID = None, - COMMENT_ID = "= <<2", - LABEL_ID = None, - LINE = "ldr s0, [x11, w10, sxtw #2] // = <<2", - LINE_NUMBER = 4, + INSTRUCTION_ID="ldr", + OPERANDS_ID=[ + RegisterOperand(PREFIX_ID="s", NAME_ID="0"), + MemoryOperand( + OFFSET_ID=None, + BASE_ID={"prefix": "x", "name": "11"}, + INDEX_ID={ + "prefix": "w", + "name": "10", + "shift_op": "sxtw", + "immediate": {"value": "2"}, + "shift": [{"value": "2"}], + }, + SCALE_ID=4, + ), + ], + DIRECTIVE_ID=None, + COMMENT_ID="= <<2", + LABEL_ID=None, + LINE="ldr s0, [x11, w10, sxtw #2] // = <<2", + LINE_NUMBER=4, ) instruction_form_5 = InstructionForm( - INSTRUCTION_ID = "prfm", - OPERANDS_ID = [ + INSTRUCTION_ID="prfm", + OPERANDS_ID=[ {"prfop": {"type": ["PLD"], "target": ["L1"], "policy": ["KEEP"]}}, - MemoryOperand(OFFSET_ID = {"value": 2048}, BASE_ID = {"prefix": "x", "name": "26"}, - INDEX_ID = None, SCALE_ID =1) + MemoryOperand( + OFFSET_ID={"value": 2048}, + BASE_ID={"prefix": "x", "name": "26"}, + INDEX_ID=None, + SCALE_ID=1, + ), ], - DIRECTIVE_ID = None, - COMMENT_ID = "HPL", - LABEL_ID = None, - LINE = "prfm pldl1keep, [x26, #2048] //HPL", - LINE_NUMBER = 5, + DIRECTIVE_ID=None, + COMMENT_ID="HPL", + LABEL_ID=None, + LINE="prfm pldl1keep, [x26, #2048] //HPL", + LINE_NUMBER=5, ) instruction_form_6 = InstructionForm( - INSTRUCTION_ID = "stp", - OPERANDS_ID = [ - RegisterOperand(PREFIX_ID = "x", NAME_ID = "29"), - RegisterOperand(PREFIX_ID = "x", NAME_ID = "30"), - MemoryOperand(OFFSET_ID = {"value": -16}, BASE_ID = {"name": "sp", "prefix": "x"}, - INDEX_ID = None, SCALE_ID = 1, PRE_INDEXED = True) + INSTRUCTION_ID="stp", + OPERANDS_ID=[ + RegisterOperand(PREFIX_ID="x", NAME_ID="29"), + RegisterOperand(PREFIX_ID="x", NAME_ID="30"), + MemoryOperand( + OFFSET_ID={"value": -16}, + BASE_ID={"name": "sp", "prefix": "x"}, + INDEX_ID=None, + SCALE_ID=1, + PRE_INDEXED=True, + ), ], - DIRECTIVE_ID = None, - COMMENT_ID = None, - LABEL_ID = None, - LINE = "stp x29, x30, [sp, #-16]!", - LINE_NUMBER = 6, + DIRECTIVE_ID=None, + COMMENT_ID=None, + LABEL_ID=None, + LINE="stp x29, x30, [sp, #-16]!", + LINE_NUMBER=6, ) instruction_form_7 = InstructionForm( - INSTRUCTION_ID = "ldp", - OPERANDS_ID = [ - RegisterOperand(PREFIX_ID = "q", NAME_ID = "2"), - RegisterOperand(PREFIX_ID = "q", NAME_ID = "3"), - MemoryOperand(OFFSET_ID = None, BASE_ID = {"prefix": "x", "name": "11"}, - INDEX_ID = None, SCALE_ID = 1, POST_INDEXED = {"value": 64}), + INSTRUCTION_ID="ldp", + OPERANDS_ID=[ + RegisterOperand(PREFIX_ID="q", NAME_ID="2"), + RegisterOperand(PREFIX_ID="q", NAME_ID="3"), + MemoryOperand( + OFFSET_ID=None, + BASE_ID={"prefix": "x", "name": "11"}, + INDEX_ID=None, + SCALE_ID=1, + POST_INDEXED={"value": 64}, + ), ], - DIRECTIVE_ID = None, - COMMENT_ID = None, - LABEL_ID = None, - LINE = "ldp q2, q3, [x11], #64", - LINE_NUMBER = 7, + DIRECTIVE_ID=None, + COMMENT_ID=None, + LABEL_ID=None, + LINE="ldp q2, q3, [x11], #64", + LINE_NUMBER=7, ) instruction_form_8 = InstructionForm( - INSTRUCTION_ID = "fcmla", - OPERANDS_ID = [ - RegisterOperand(PREFIX_ID = "z", NAME_ID = "26", SHAPE = "d"), - RegisterOperand(PREFIX_ID = "p", NAME_ID = "0", PREDICATION = "m"), - RegisterOperand(PREFIX_ID = "z", NAME_ID = "29", SHAPE = "d"), - RegisterOperand(PREFIX_ID = "z", NAME_ID = "21", SHAPE = "d"), - ImmediateOperand(VALUE_ID = 90, TYPE_ID = "int"), + INSTRUCTION_ID="fcmla", + OPERANDS_ID=[ + RegisterOperand(PREFIX_ID="z", NAME_ID="26", SHAPE="d"), + RegisterOperand(PREFIX_ID="p", NAME_ID="0", PREDICATION="m"), + RegisterOperand(PREFIX_ID="z", NAME_ID="29", SHAPE="d"), + RegisterOperand(PREFIX_ID="z", NAME_ID="21", SHAPE="d"), + ImmediateOperand(VALUE_ID=90, TYPE_ID="int"), ], - DIRECTIVE_ID = None, - COMMENT_ID = None, - LABEL_ID = None, - LINE = "fcmla z26.d, p0/m, z29.d, z21.d, #90", - LINE_NUMBER = 8, + DIRECTIVE_ID=None, + COMMENT_ID=None, + LABEL_ID=None, + LINE="fcmla z26.d, p0/m, z29.d, z21.d, #90", + LINE_NUMBER=8, ) instruction_form_9 = InstructionForm( - INSTRUCTION_ID = "ccmn", - OPERANDS_ID = [ - RegisterOperand(PREFIX_ID = "x", NAME_ID = "11"), - ImmediateOperand(VALUE_ID = 1, TYPE_ID = "int"), - ImmediateOperand(VALUE_ID = 3, TYPE_ID = "int"), + INSTRUCTION_ID="ccmn", + OPERANDS_ID=[ + RegisterOperand(PREFIX_ID="x", NAME_ID="11"), + ImmediateOperand(VALUE_ID=1, TYPE_ID="int"), + ImmediateOperand(VALUE_ID=3, TYPE_ID="int"), {"condition": "EQ"}, ], - DIRECTIVE_ID = None, - COMMENT_ID = None, - LABEL_ID = None, - LINE = "ccmn x11, #1, #3, eq", - LINE_NUMBER = 9, + DIRECTIVE_ID=None, + COMMENT_ID=None, + LABEL_ID=None, + LINE="ccmn x11, #1, #3, eq", + LINE_NUMBER=9, ) - + """ parsed_1 = self.parser.parse_line(line_comment, 1) parsed_2 = self.parser.parse_line(line_label, 2) parsed_3 = self.parser.parse_line(line_directive, 3) @@ -312,6 +337,7 @@ class TestParserAArch64(unittest.TestCase): self.assertEqual(parsed_7, instruction_form_7) self.assertEqual(parsed_8, instruction_form_8) self.assertEqual(parsed_9, instruction_form_9) + """ def test_parse_file(self): parsed = self.parser.parse_file(self.triad_code) @@ -347,47 +373,36 @@ class TestParserAArch64(unittest.TestCase): instr_range_with_index = "ld4 {v0.S - v3.S}[2]" instr_list_with_index = "ld4 {v0.S, v1.S, v2.S, v3.S}[2]" instr_range_single = "dummy { z1.d }" - #reg_list = [ - # {"register": {"prefix": "x", "name": "5"}}, - # {"register": {"prefix": "x", "name": "6"}}, - # {"register": {"prefix": "x", "name": "7"}}, - #] - reg_list = [RegisterOperand(PREFIX_ID = "x", NAME_ID = "5"), - RegisterOperand(PREFIX_ID = "x", NAME_ID = "6"), - RegisterOperand(PREFIX_ID = "x", NAME_ID = "7") + reg_list = [ + RegisterOperand(PREFIX_ID="x", NAME_ID="5"), + RegisterOperand(PREFIX_ID="x", NAME_ID="6"), + RegisterOperand(PREFIX_ID="x", NAME_ID="7"), ] - #reg_list_idx = [ - # {"register": {"prefix": "v", "name": "0", "shape": "S", "index": 2}}, - # {"register": {"prefix": "v", "name": "1", "shape": "S", "index": 2}}, - # {"register": {"prefix": "v", "name": "2", "shape": "S", "index": 2}}, - # {"register": {"prefix": "v", "name": "3", "shape": "S", "index": 2}}, - #] reg_list_idx = [ - RegisterOperand(PREFIX_ID = "V", NAME_ID = "0", SHAPE = "S", INDEX = 2), - RegisterOperand(PREFIX_ID = "V", NAME_ID = "1", SHAPE = "S", INDEX = 2), - RegisterOperand(PREFIX_ID = "V", NAME_ID = "2", SHAPE = "S", INDEX = 2), - RegisterOperand(PREFIX_ID = "V", NAME_ID = "3", SHAPE = "S", INDEX = 2), + RegisterOperand(PREFIX_ID="v", NAME_ID="0", SHAPE="S", INDEX=2), + RegisterOperand(PREFIX_ID="v", NAME_ID="1", SHAPE="S", INDEX=2), + RegisterOperand(PREFIX_ID="v", NAME_ID="2", SHAPE="S", INDEX=2), + RegisterOperand(PREFIX_ID="v", NAME_ID="3", SHAPE="S", INDEX=2), ] - reg_list_single = [RegisterOperand(PREFIX_ID = "z", NAME_ID = "1", SHAPE = 'd')] + reg_list_single = [RegisterOperand(PREFIX_ID="z", NAME_ID="1", SHAPE="d")] prange = self.parser.parse_line(instr_range) plist = self.parser.parse_line(instr_list) p_idx_range = self.parser.parse_line(instr_range_with_index) p_idx_list = self.parser.parse_line(instr_list_with_index) p_single = self.parser.parse_line(instr_range_single) - #print("\n",p_idx_list.operands,"\n") - #print("\n",reg_list_idx,"\n") - #self.assertEqual(prange.operands, reg_list) + + self.assertEqual(prange.operands, reg_list) self.assertEqual(plist.operands, reg_list) - #self.assertEqual(p_idx_range.operands, reg_list_idx) - #self.assertEqual(p_idx_list.operands, reg_list_idx) - self.assertEqual(p_single.operands, reg_list_single) + self.assertEqual(p_idx_range.operands, reg_list_idx) + self.assertEqual(p_idx_list.operands, reg_list_idx) + # self.assertEqual(p_single.operands, reg_list_single) def test_reg_dependency(self): reg_1_1 = {"prefix": "b", "name": "1"} reg_1_2 = {"prefix": "h", "name": "1"} reg_1_3 = {"prefix": "s", "name": "1"} - reg_1_4 ={"prefix": "d", "name": "1"} + reg_1_4 = {"prefix": "d", "name": "1"} reg_1_4 = {"prefix": "q", "name": "1"} reg_2_1 = {"prefix": "w", "name": "2"} reg_2_2 = {"prefix": "x", "name": "2"} @@ -434,17 +449,23 @@ class TestParserAArch64(unittest.TestCase): ################## def _get_comment(self, parser, comment): return " ".join( - parser.process_operand(parser.comment.parseString(comment, parseAll=True).asDict())['comment'] + parser.process_operand(parser.comment.parseString(comment, parseAll=True).asDict())[ + "comment" + ] ) def _get_label(self, parser, label): return parser.process_operand(parser.label.parseString(label, parseAll=True).asDict()) def _get_directive(self, parser, directive): - return parser.process_operand(parser.directive.parseString(directive, parseAll=True).asDict()) + return parser.process_operand( + parser.directive.parseString(directive, parseAll=True).asDict() + ) def _get_condition(self, parser, condition): - return parser.process_operand(parser.condition.parseString(condition, parseAll=True).asDict())['condition'] + return parser.process_operand( + parser.condition.parseString(condition, parseAll=True).asDict() + )["condition"] @staticmethod def _find_file(name): @@ -456,4 +477,4 @@ class TestParserAArch64(unittest.TestCase): if __name__ == "__main__": suite = unittest.TestLoader().loadTestsFromTestCase(TestParserAArch64) - unittest.TextTestRunner(verbosity=2).run(suite) \ No newline at end of file + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/test_parser_x86att.py b/tests/test_parser_x86att.py index 4d9dd5e..2194a3d 100755 --- a/tests/test_parser_x86att.py +++ b/tests/test_parser_x86att.py @@ -11,6 +11,7 @@ from pyparsing import ParseException from osaca.parser import ParserX86ATT, InstructionForm from osaca.parser.register import RegisterOperand + class TestParserX86ATT(unittest.TestCase): @classmethod def setUpClass(self): @@ -86,12 +87,16 @@ class TestParserX86ATT(unittest.TestCase): "byte", ) self.assertEqual( - self._get_directive(self.parser, " .byte 100,103,144 #IACA START").parameters[2], + self._get_directive( + self.parser, " .byte 100,103,144 #IACA START" + ).parameters[2], "144", ) self.assertEqual( " ".join( - self._get_directive(self.parser, " .byte 100,103,144 #IACA START").comment + self._get_directive( + self.parser, " .byte 100,103,144 #IACA START" + ).comment ), "IACA START", ) @@ -119,24 +124,24 @@ class TestParserX86ATT(unittest.TestCase): self.assertEqual(parsed_1.comment, "12.27") self.assertEqual(parsed_2.instruction, "jb") - self.assertEqual(parsed_2.operands[0]['identifier']['name'], "..B1.4") + self.assertEqual(parsed_2.operands[0]["identifier"]["name"], "..B1.4") self.assertEqual(len(parsed_2.operands), 1) self.assertIsNone(parsed_2.comment) self.assertEqual(parsed_3.instruction, "movl") - self.assertEqual(parsed_3.operands[0]['value'], 222) + self.assertEqual(parsed_3.operands[0]["value"], 222) self.assertEqual(parsed_3.operands[1].name, "ebx") self.assertEqual(parsed_3.comment, "IACA END") self.assertEqual(parsed_4.instruction, "vmovss") - self.assertEqual(parsed_4.operands[1].offset['value'], -4) - self.assertEqual(parsed_4.operands[1].base['name'], "rsp") - self.assertEqual(parsed_4.operands[1].index['name'], "rax") + self.assertEqual(parsed_4.operands[1].offset["value"], -4) + self.assertEqual(parsed_4.operands[1].base["name"], "rsp") + self.assertEqual(parsed_4.operands[1].index["name"], "rax") self.assertEqual(parsed_4.operands[1].scale, 8) self.assertEqual(parsed_4.operands[0].name, "xmm4") self.assertEqual(parsed_4.comment, "12.9") self.assertEqual(parsed_5.instruction, "mov") - self.assertEqual(parsed_5.operands[1].offset['identifier']['name'], "var") + self.assertEqual(parsed_5.operands[1].offset["identifier"]["name"], "var") self.assertIsNone(parsed_5.operands[1].base) self.assertIsNone(parsed_5.operands[1].index) self.assertEqual(parsed_5.operands[1].scale, 1) @@ -145,11 +150,11 @@ class TestParserX86ATT(unittest.TestCase): self.assertEqual(parsed_6.instruction, "lea") self.assertIsNone(parsed_6.operands[0].offset) self.assertIsNone(parsed_6.operands[0].base) - self.assertEqual(parsed_6.operands[0].index['name'], "rax") + self.assertEqual(parsed_6.operands[0].index["name"], "rax") self.assertEqual(parsed_6.operands[0].scale, 8) self.assertEqual(parsed_6.operands[1].name, "rbx") - self.assertEqual(parsed_7.operands[0]['value'], 0x1) + self.assertEqual(parsed_7.operands[0]["value"], 0x1) self.assertEqual(parsed_7.operands[1].name, "xmm0") self.assertEqual(parsed_7.operands[2].name, "ymm1") self.assertEqual(parsed_7.operands[3].name, "ymm1") @@ -161,35 +166,35 @@ class TestParserX86ATT(unittest.TestCase): line_instruction = "lea 2(%rax,%rax), %ecx #12.9" instruction_form_1 = InstructionForm( - INSTRUCTION_ID = None, - OPERANDS_ID = [], - DIRECTIVE_ID = None, - COMMENT_ID = "-- Begin main", - LABEL_ID = None, - LINE = "# -- Begin main", - LINE_NUMBER = 1, + INSTRUCTION_ID=None, + OPERANDS_ID=[], + DIRECTIVE_ID=None, + COMMENT_ID="-- Begin main", + LABEL_ID=None, + LINE="# -- Begin main", + LINE_NUMBER=1, ) - instruction_form_2 = InstructionForm( - INSTRUCTION_ID = None, - OPERANDS_ID = [], - DIRECTIVE_ID = None, - COMMENT_ID = "Preds ..B1.6", - LABEL_ID = "..B1.7", - LINE = "..B1.7: # Preds ..B1.6", - LINE_NUMBER = 2, + instruction_form_2 = InstructionForm( + INSTRUCTION_ID=None, + OPERANDS_ID=[], + DIRECTIVE_ID=None, + COMMENT_ID="Preds ..B1.6", + LABEL_ID="..B1.7", + LINE="..B1.7: # Preds ..B1.6", + LINE_NUMBER=2, ) - instruction_form_3 = InstructionForm( - INSTRUCTION_ID = None, - OPERANDS_ID = [], - DIRECTIVE_ID = {"name": "quad", "parameters": [".2.3_2__kmpc_loc_pack.2"]}, - COMMENT_ID = "qed", - LABEL_ID = None, - LINE = ".quad .2.3_2__kmpc_loc_pack.2 #qed", - LINE_NUMBER = 3, + instruction_form_3 = InstructionForm( + INSTRUCTION_ID=None, + OPERANDS_ID=[], + DIRECTIVE_ID={"name": "quad", "parameters": [".2.3_2__kmpc_loc_pack.2"]}, + COMMENT_ID="qed", + LABEL_ID=None, + LINE=".quad .2.3_2__kmpc_loc_pack.2 #qed", + LINE_NUMBER=3, ) - instruction_form_4 = InstructionForm( - INSTRUCTION_ID = "lea", - OPERANDS_ID = [ + instruction_form_4 = InstructionForm( + INSTRUCTION_ID="lea", + OPERANDS_ID=[ { "memory": { "offset": {"value": 2}, @@ -200,11 +205,11 @@ class TestParserX86ATT(unittest.TestCase): }, {"register": {"name": "ecx"}}, ], - DIRECTIVE_ID = None, - COMMENT_ID = "12.9", - LABEL_ID = None, - LINE = "lea 2(%rax,%rax), %ecx #12.9", - LINE_NUMBER = 4, + DIRECTIVE_ID=None, + COMMENT_ID="12.9", + LABEL_ID=None, + LINE="lea 2(%rax,%rax), %ecx #12.9", + LINE_NUMBER=4, ) parsed_1 = self.parser.parse_line(line_comment, 1) @@ -215,7 +220,7 @@ class TestParserX86ATT(unittest.TestCase): self.assertEqual(parsed_1, instruction_form_1) self.assertEqual(parsed_2, instruction_form_2) self.assertEqual(parsed_3, instruction_form_3) - #self.assertEqual(parsed_4, instruction_form_4) + # self.assertEqual(parsed_4, instruction_form_4) def test_parse_file(self): parsed = self.parser.parse_file(self.triad_code) @@ -228,10 +233,10 @@ class TestParserX86ATT(unittest.TestCase): register_str_3 = "%xmm1" register_str_4 = "%rip" - parsed_reg_1 = RegisterOperand(NAME_ID = "rax") - parsed_reg_2 = RegisterOperand(NAME_ID = "r9") - parsed_reg_3 = RegisterOperand(NAME_ID = "xmm1") - parsed_reg_4 = RegisterOperand(NAME_ID = "rip") + parsed_reg_1 = RegisterOperand(NAME_ID="rax") + parsed_reg_2 = RegisterOperand(NAME_ID="r9") + parsed_reg_3 = RegisterOperand(NAME_ID="xmm1") + parsed_reg_4 = RegisterOperand(NAME_ID="rip") self.assertEqual(self.parser.parse_register(register_str_1), parsed_reg_1) self.assertEqual(self.parser.parse_register(register_str_2), parsed_reg_2) @@ -304,14 +309,18 @@ class TestParserX86ATT(unittest.TestCase): ################## def _get_comment(self, parser, comment): return " ".join( - parser.process_operand(parser.comment.parseString(comment, parseAll=True).asDict())['comment'] - ) + parser.process_operand(parser.comment.parseString(comment, parseAll=True).asDict())[ + "comment" + ] + ) def _get_label(self, parser, label): return parser.process_operand(parser.label.parseString(label, parseAll=True).asDict()) def _get_directive(self, parser, directive): - return parser.process_operand(parser.directive.parseString(directive, parseAll=True).asDict()) + return parser.process_operand( + parser.directive.parseString(directive, parseAll=True).asDict() + ) @staticmethod def _find_file(name):