From 14a2aa0b52148f607fbfe7fa149a8b255571ac54 Mon Sep 17 00:00:00 2001 From: stefandesouza Date: Sun, 29 Oct 2023 13:52:49 +0100 Subject: [PATCH] Changed style to conform to PEP-8 conventions; Added source and destination attributes to parent Operand class --- README.rst | 2 +- osaca/data/isa/x86.yml | 2 +- osaca/db_interface.py | 20 +-- osaca/frontend.py | 22 +-- osaca/osaca.py | 4 +- osaca/parser/__init__.py | 4 +- osaca/parser/base_parser.py | 12 +- osaca/parser/directive.py | 36 ++-- osaca/parser/identifier.py | 20 +-- osaca/parser/immediate.py | 76 ++++----- osaca/parser/instruction_form.py | 160 +++++++++--------- osaca/parser/label.py | 20 +-- osaca/parser/memory.py | 158 ++++++++--------- osaca/parser/operand.py | 30 +++- osaca/parser/parser_AArch64.py | 112 ++++++------- osaca/parser/parser_x86att.py | 84 +++++----- osaca/parser/register.py | 148 +++++++--------- osaca/semantics/__init__.py | 4 +- osaca/semantics/arch_semantics.py | 64 +++---- osaca/semantics/hw_model.py | 211 +++++++++++------------ osaca/semantics/isa_semantics.py | 36 ++-- osaca/semantics/kernel_dg.py | 46 ++--- tests/test_db_interface.py | 26 +-- tests/test_parser_AArch64.py | 270 +++++++++++++++--------------- tests/test_parser_x86att.py | 106 ++++++------ tests/test_semantics.py | 119 +++++++------ 26 files changed, 876 insertions(+), 916 deletions(-) diff --git a/README.rst b/README.rst index d0ff0e6..3496bff 100644 --- a/README.rst +++ b/README.rst @@ -87,7 +87,7 @@ The usage of OSACA can be listed as: .. code:: bash - osaca [-h] [-V] [--arch ARCH] [--fixed] [--lines LINES] + osaca [-h] [-V] [--arch ARCH] [--fixed] [--lines lineS] [--ignore-unknown] [--lcd-timeout SECONDS] [--db-check] [--import MICROBENCH] [--insert-marker] [--export-graph GRAPHNAME] [--consider-flag-deps] diff --git a/osaca/data/isa/x86.yml b/osaca/data/isa/x86.yml index f995102..eadf512 100644 --- a/osaca/data/isa/x86.yml +++ b/osaca/data/isa/x86.yml @@ -3363,7 +3363,7 @@ instruction_forms: name: "rsp" source: true destination: true - # All of EFLAGS and RFLAGS, without VM and RF + # All of Eflags and Rflags, without VM and RF - class: "flag" name: "CF" source: true diff --git a/osaca/db_interface.py b/osaca/db_interface.py index e7c8a92..96bae9c 100644 --- a/osaca/db_interface.py +++ b/osaca/db_interface.py @@ -10,10 +10,10 @@ from collections import OrderedDict import ruamel.yaml from osaca.semantics import MachineModel -from osaca.parser import InstructionForm -from osaca.parser.memory import MemoryOperand -from osaca.parser.register import RegisterOperand -from osaca.parser.immediate import ImmediateOperand +from osaca.parser import instructionForm +from osaca.parser.memory import memoryOperand +from osaca.parser.register import registerOperand +from osaca.parser.immediate import immediateOperand def sanity_check(arch: str, verbose=False, internet_check=False, output_file=sys.stdout): @@ -190,14 +190,14 @@ def _get_ibench_output(input_data, isa): entry["throughput"] = _validate_measurement(float(line.split()[1]), "tp") if not entry["throughput"]: warnings.warn( - "Your THROUGHPUT measurement for {} looks suspicious".format(key) + "Your throughput measurement for {} looks suspicious".format(key) + " and was not added. Please inspect your benchmark." ) elif "LT" in instruction: entry["latency"] = _validate_measurement(float(line.split()[1]), "lt") if not entry["latency"]: warnings.warn( - "Your LATENCY measurement for {} looks suspicious".format(key) + "Your latency measurement for {} looks suspicious".format(key) + " and was not added. Please inspect your benchmark." ) db_entries[key] = entry @@ -436,12 +436,12 @@ def _check_sanity_arch_db(arch_mm, isa_mm, internet_check=True): # Check operands for operand in instr_form["operands"]: - if isinstance(operand, RegisterOperand) and not ( + if isinstance(operand, registerOperand) and not ( operand.name != None or operand.prefix != None ): # Missing 'name' key bad_operand.append(instr_form) - elif isinstance(operand, MemoryOperand) and ( + elif isinstance(operand, memoryOperand) and ( operand.base is None or operand.offset is None or operand.index is None @@ -449,7 +449,7 @@ def _check_sanity_arch_db(arch_mm, isa_mm, internet_check=True): ): # Missing at least one key necessary for memory operands bad_operand.append(instr_form) - elif isinstance(operand, ImmediateOperand) and operand.type == None: + elif isinstance(operand, immediateOperand) and operand.type == None: # Missing 'imd' key bad_operand.append(instr_form) # every entry exists twice --> uniquify @@ -611,7 +611,7 @@ def _get_full_instruction_name(instruction_form): """Get one instruction name string including the mnemonic and all operands.""" operands = [] for op in instruction_form["operands"]: - if isinstance(op, RegisterOperand): + if isinstance(op, registerOperand): op_attrs = [] if op.name != None: op_attrs.append("name:" + op.name) diff --git a/osaca/frontend.py b/osaca/frontend.py index 839d115..974ee9e 100644 --- a/osaca/frontend.py +++ b/osaca/frontend.py @@ -7,7 +7,7 @@ import os import re from datetime import datetime as dt -from osaca.semantics import INSTR_FLAGS, ArchSemantics, KernelDG, MachineModel +from osaca.semantics import INSTR_flags, ArchSemantics, KernelDG, MachineModel def _get_version(*file_paths): @@ -116,7 +116,7 @@ class Frontend(object): separator, instruction_form.latency_cp, separator, - "X" if INSTR_FLAGS.LT_UNKWN in instruction_form.flags else " ", + "X" if INSTR_flags.LT_UNKWN in instruction_form.flags else " ", separator, instruction_form.line, ) @@ -237,7 +237,7 @@ class Frontend(object): if lcd_warning: warnings.append("LCDWarning") - # if INSTR_FLAGS.TP_UNKWN in [flag for instr in kernel for flag in instr.flags]: + # if INSTR_flags.TP_UNKWN in [flag for instr in kernel for flag in instr.flags]: # warnings.append("UnknownInstrWarning") tp_sum = ArchSemantics.get_throughput_sum(kernel) or kernel[0].port_pressure @@ -373,11 +373,11 @@ class Frontend(object): ) s += "\n" # check for unknown instructions and throw warning if called without --ignore-unknown - if not ignore_unknown and INSTR_FLAGS.TP_UNKWN in [ + if not ignore_unknown and INSTR_flags.TP_UNKWN in [ flag for instr in kernel for flag in instr.flags ]: num_missing = len( - [instr.flags for instr in kernel if INSTR_FLAGS.TP_UNKWN in instr.flags] + [instr.flags for instr in kernel if INSTR_flags.TP_UNKWN in instr.flags] ) s += self._missing_instruction_error(num_missing) else: @@ -471,9 +471,9 @@ class Frontend(object): def _get_flag_symbols(self, flag_obj): """Returns flags for a flag object of an instruction""" string_result = "" - string_result += "*" if INSTR_FLAGS.NOT_BOUND in flag_obj else "" - string_result += "X" if INSTR_FLAGS.TP_UNKWN in flag_obj else "" - string_result += "P" if INSTR_FLAGS.HIDDEN_LD in flag_obj else "" + string_result += "*" if INSTR_flags.NOT_BOUND in flag_obj else "" + string_result += "X" if INSTR_flags.TP_UNKWN in flag_obj else "" + string_result += "P" if INSTR_flags.HIDDEN_LD in flag_obj else "" # TODO add other flags string_result += " " if len(string_result) == 0 else "" return string_result @@ -554,10 +554,10 @@ class Frontend(object): def _symbol_map(self): """Prints instruction flag map.""" symbol_dict = { - INSTR_FLAGS.NOT_BOUND: "Instruction micro-ops not bound to a port", - INSTR_FLAGS.TP_UNKWN: "No throughput/latency information for this instruction in " + INSTR_flags.NOT_BOUND: "Instruction micro-ops not bound to a port", + INSTR_flags.TP_UNKWN: "No throughput/latency information for this instruction in " + "data file", - INSTR_FLAGS.HIDDEN_LD: "Throughput of LOAD operation can be hidden behind a past " + INSTR_flags.HIDDEN_LD: "Throughput of LOAD operation can be hidden behind a past " + "or future STORE instruction", } symbol_map = "" diff --git a/osaca/osaca.py b/osaca/osaca.py index 55b70eb..1f3f3f7 100644 --- a/osaca/osaca.py +++ b/osaca/osaca.py @@ -13,7 +13,7 @@ from osaca.db_interface import import_benchmark_output, sanity_check from osaca.frontend import Frontend from osaca.parser import BaseParser, ParserAArch64, ParserX86ATT from osaca.semantics import ( - INSTR_FLAGS, + INSTR_flags, ArchSemantics, KernelDG, MachineModel, @@ -430,7 +430,7 @@ def get_unmatched_instruction_ratio(kernel): """Return ratio of unmatched from total instructions in kernel.""" unmatched_counter = 0 for instruction in kernel: - if INSTR_FLAGS.TP_UNKWN in instruction.flags and INSTR_FLAGS.LT_UNKWN in instruction.flags: + if INSTR_flags.TP_UNKWN in instruction.flags and INSTR_flags.LT_UNKWN in instruction.flags: unmatched_counter += 1 return unmatched_counter / len(kernel) diff --git a/osaca/parser/__init__.py b/osaca/parser/__init__.py index fd4236b..96d7cf9 100644 --- a/osaca/parser/__init__.py +++ b/osaca/parser/__init__.py @@ -7,12 +7,12 @@ from .attr_dict import AttrDict from .base_parser import BaseParser from .parser_x86att import ParserX86ATT from .parser_AArch64 import ParserAArch64 -from .instruction_form import InstructionForm +from .instruction_form import instructionForm from .operand import Operand __all__ = [ "Operand", - "InstructionForm", + "instructionForm", "AttrDict", "BaseParser", "ParserX86ATT", diff --git a/osaca/parser/base_parser.py b/osaca/parser/base_parser.py index b55c9b7..5aba2ae 100644 --- a/osaca/parser/base_parser.py +++ b/osaca/parser/base_parser.py @@ -6,16 +6,16 @@ import re class BaseParser(object): # Identifiers for operand types - COMMENT_ID = "comment" - DIRECTIVE_ID = "directive" + comment_id = "comment" + directive_id = "directive" IMMEDIATE_ID = "immediate" - LABEL_ID = "label" + label_id = "label" IDENTIFIER_ID = "identifier" MEMORY_ID = "memory" REGISTER_ID = "register" - SEGMENT_EXT_ID = "segment_extension" - INSTRUCTION_ID = "instruction" - OPERANDS_ID = "operands" + segment_ext_id = "segment_extension" + instruction_id = "instruction" + operands_id = "operands" _parser_constructed = False def __init__(self): diff --git a/osaca/parser/directive.py b/osaca/parser/directive.py index cdca918..8161cc4 100644 --- a/osaca/parser/directive.py +++ b/osaca/parser/directive.py @@ -3,49 +3,49 @@ from osaca.parser.operand import Operand -class DirectiveOperand(Operand): - 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 +class directiveOperand(Operand): + 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 + return self._parameter_id @property def comment(self): - return self._COMMENT_ID + return self._comment_id def __iter__(self): return self def __next__(self): - if not self._COMMENT_ID: + if not self._comment_id: raise StopIteration - return self._COMMENT_ID.pop(0) + return self._comment_id.pop(0) @parameters.setter def parameters(self, parameters): - self._PARAMETER_ID = parameters + self._parameter_id = parameters @comment.setter def comment(self, comment): - self._COMMENT_ID = comment + self._comment_id = comment def __eq__(self, other): - if isinstance(other, DirectiveOperand): + 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})" + 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})" + 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 f85c260..e98358c 100644 --- a/osaca/parser/identifier.py +++ b/osaca/parser/identifier.py @@ -3,32 +3,32 @@ from osaca.parser.operand import Operand -class IdentifierOperand(Operand): - def __init__(self, name=None, OFFSET=None, RELOCATION=None): +class identifierOperand(Operand): + def __init__(self, name=None, offset=None, relocation=None): super().__init__(name) - self._OFFSET = OFFSET - self._RELOCATION = RELOCATION + self._offset = offset + self._relocation = relocation @property def offset(self): - return self._OFFSET + return self._offset @offset.setter def offset(self, offset): - self._OFFSET = offset + self._offset = offset @property def relocation(self): - return self._RELOCATION + return self._relocation @relocation.setter def relocation(self, relocation): - self._RELOCATION = relocation + self._relocation = relocation def __str__(self): return ( - f"IdentifierOperand({self.name}, offset={self.offset}, relocation={self.relocation})" + 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})" + 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 9879ad2..2aad292 100644 --- a/osaca/parser/immediate.py +++ b/osaca/parser/immediate.py @@ -3,90 +3,72 @@ from osaca.parser.operand import Operand -class ImmediateOperand(Operand): +class immediateOperand(Operand): def __init__( self, - IDENTIFIER_ID=None, - TYPE_ID=None, - VALUE_ID=None, - SHIFT_ID=None, - SOURCE=False, - DESTINATION=False + identifier_id=None, + type_id=None, + value_id=None, + shift_id=None, + source=False, + destination=False, ): - super().__init__(str(VALUE_ID)) - self._IDENTIFIER_ID = IDENTIFIER_ID - self._TYPE_ID = TYPE_ID - self._VALUE_ID = VALUE_ID - self._SHIFT_ID = SHIFT_ID - self._SOURCE = SOURCE - self._DESTINATION = DESTINATION + super().__init__(str(value_id), source, destination) + self._identifier_id = identifier_id + self._type_id = type_id + self._value_id = value_id + self._shift_id = shift_id @property def identifier(self): - return self._IDENTIFIER_ID + return self._identifier_id @property def type(self): - return self._TYPE_ID + return self._type_id @property def value(self): - return self._VALUE_ID + return self._value_id @property def shift(self): - return self._TYPE_ID - - @property - def source(self): - return self._SOURCE - - @source.setter - def source(self, source): - self._SOURCE = source - - @property - def destination(self): - return self._DESTINATION - - @destination.setter - def destination(self, destination): - self._DESTINATION = destination + return self._type_id @identifier.setter def identifier(self, identifier): - self._IDENTIFIER_ID = identifier + self._identifier_id = identifier @type.setter def type(self, type): - self._TYPE_ID = type + self._type_id = type @value.setter def value(self, value): - self._VALUE_ID = value + self._value_id = value @shift.setter def index(self, shift): - self._SHIFT_ID = shift + self._shift_id = shift def __str__(self): return ( - f"ImmediateOperand(IDENTIFIER_ID={self._IDENTIFIER_ID}, TYPE_ID={self._TYPE_ID}, " - f"VALUE_ID={self._VALUE_ID}, SHIFT_ID={self._SHIFT_ID})" + f"immediateOperand(identifier_id={self._identifier_id}, type_id={self._type_id}, " + f"value_id={self._value_id}, shift_id={self._shift_id})" ) def __repr__(self): return ( - f"ImmediateOperand(IDENTIFIER_ID={self._IDENTIFIER_ID}, TYPE_ID={self._TYPE_ID}, " - f"VALUE_ID={self._VALUE_ID}, SHIFT_ID={self._SHIFT_ID})" + f"immediateOperand(identifier_id={self._identifier_id}, type_id={self._type_id}, " + f"value_id={self._value_id}, shift_id={self._shift_id})" ) def __eq__(self, other): - if isinstance(other, ImmediateOperand): + 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 diff --git a/osaca/parser/instruction_form.py b/osaca/parser/instruction_form.py index 4e1c4e2..07c3d59 100644 --- a/osaca/parser/instruction_form.py +++ b/osaca/parser/instruction_form.py @@ -1,200 +1,200 @@ #!/usr/bin/env python3 -from osaca.parser.directive import DirectiveOperand +from osaca.parser.directive import directiveOperand -class InstructionForm: +class instructionForm: def __init__( self, - INSTRUCTION_ID=None, - OPERANDS_ID=[], - HIDDEN_OPERANDS=[], - DIRECTIVE_ID=None, - COMMENT_ID=None, - LABEL_ID=None, - LINE=None, - LINE_NUMBER=None, - SEMANTIC_OPERANDS={"source": [], "destination": [], "src_dst": []}, - THROUGHPUT = None, - LATENCY = None, - UOPS = None, - PORT_PRESSURE = None, - BREAKS_DEP = False + instruction_id=None, + operands_id=[], + hidden_operands=[], + directive_id=None, + comment_id=None, + label_id=None, + line=None, + line_number=None, + semantic_operands={"source": [], "destination": [], "src_dst": []}, + throughput=None, + latency=None, + uops=None, + port_pressure=None, + breaks_dep=False, ): - self._INSTRUCTION_ID = INSTRUCTION_ID - self._OPERANDS_ID = OPERANDS_ID - self._HIDDEN_OPERANDS = HIDDEN_OPERANDS - self._DIRECTIVE_ID = DIRECTIVE_ID - self._COMMENT_ID = COMMENT_ID - self._LABEL_ID = LABEL_ID - self._LINE = LINE - self._LINE_NUMBER = LINE_NUMBER + self._instruction_id = instruction_id + self._operands_id = operands_id + self._hidden_operands = hidden_operands + self._directive_id = directive_id + self._comment_id = comment_id + self._label_id = label_id + self._line = line + self._line_number = line_number - self._SEMANTIC_OPERANDS = SEMANTIC_OPERANDS - self._UOPS = UOPS - self._BREAKS_DEP = BREAKS_DEP + self._semantic_operands = semantic_operands + self._uops = uops + self._breaks_dep = breaks_dep # self.semantic_operands = {"source": [], "destination": [], "src_dst": []} - self._LATENCY = LATENCY - self._THROUGHPUT = THROUGHPUT - self._LATENCY_CP = [] - self._LATENCY_LCD = [] - self._LATENCY_WO_LOAD = None - self._PORT_PRESSURE = PORT_PRESSURE - self._PORT_UOPS = [] - self._FLAGS = [] + self._latency = latency + self._throughput = throughput + self._latency_cp = [] + self._latency_lcd = [] + self._latency_wo_load = None + self._port_pressure = port_pressure + self._port_uops = [] + self._flags = [] @property def semantic_operands(self): - return self._SEMANTIC_OPERANDS + return self._semantic_operands @property def instruction(self): - return self._INSTRUCTION_ID + return self._instruction_id @property def label(self): - return self._LABEL_ID + return self._label_id @property def comment(self): - return self._COMMENT_ID + return self._comment_id @property def directive(self): - return self._DIRECTIVE_ID + return self._directive_id @property def line_number(self): - return self._LINE_NUMBER + return self._line_number @property def line(self): - return self._LINE + return self._line @property def operands(self): - return self._OPERANDS_ID + return self._operands_id @property def hidden_operands(self): - return self._HIDDEN_OPERANDS + return self._hidden_operands @property def port_pressure(self): - return self._PORT_PRESSURE + return self._port_pressure @property def port_uops(self): - return self._PORT_UOPS + return self._port_uops @property def flags(self): - return self._FLAGS + return self._flags @property def uops(self): - return self._UOPS + return self._uops @property def throughput(self): - return self._THROUGHPUT + return self._throughput @property def latency(self): - return self._LATENCY + return self._latency @property def latency_wo_load(self): - return self._LATENCY_WO_LOAD + return self._latency_wo_load @property def breaks_dep(self): - return self._BREAKS_DEP + return self._breaks_dep @semantic_operands.setter def semantic_operands(self, semantic_operands): - self._SEMANTIC_OPERANDS = semantic_operands + self._semantic_operands = semantic_operands @directive.setter def directive(self, directive): - self._DIRECTIVE_ID = directive + self._directive_id = directive @line_number.setter def line_number(self, line_number): - self._LINE_NUMBER = line_number + self._line_number = line_number @line.setter def line(self, line): - self._LINE = line + self._line = line @operands.setter def operands(self, operands): - self._OPERANDS_ID = operands + self._operands_id = operands @hidden_operands.setter def hidden_operands(self, hidden_operands): - self._HIDDEN_OPERANDS = hidden_operands + self._hidden_operands = hidden_operands @breaks_dep.setter def breaks_dep(self, boolean): - self._BREAKS_DEP = boolean + self._breaks_dep = boolean @instruction.setter def instruction(self, instruction): - self._INSTRUCTION_ID = instruction + self._instruction_id = instruction @label.setter def label(self, label): - self._LABEL_ID = 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 + self._port_pressure = port_pressure @port_uops.setter def port_uops(self, port_uops): - self._PORT_UOPS = port_uops + self._port_uops = port_uops @flags.setter def flags(self, flags): - self._FLAGS = flags + self._flags = flags @uops.setter def uops(self, uops): - self._UOPS = uops + self._uops = uops @throughput.setter def throughput(self, throughput): - self._THROUGHPUT = throughput + self._throughput = throughput @latency.setter def latency(self, latency): - self._LATENCY = latency + self._latency = latency @latency_wo_load.setter def latency_wo_load(self, latency_wo_load): - self._LATENCY_WO_LOAD = latency_wo_load + self._latency_wo_load = latency_wo_load def __repr__(self): - return f"InstructionForm(INSTRUCTION_ID={self._INSTRUCTION_ID}, OPERANDS_ID={self._OPERANDS_ID}, DIRECTIVE_ID={self._DIRECTIVE_ID}, COMMENT_ID={self._COMMENT_ID}, LABEL_ID={self._LABEL_ID}, LINE={self._LINE}, LINE_NUMBER={self._LINE_NUMBER}, SEMANTIC_OPERANDS={self._SEMANTIC_OPERANDS})" + return f"instructionForm(instruction_id={self._instruction_id}, operands_id={self._operands_id}, directive_id={self._directive_id}, comment_id={self._comment_id}, label_id={self._label_id}, line={self._line}, line_number={self._line_number}, semantic_operands={self._semantic_operands})" def __str__(self): - return f"Instruction: {self._INSTRUCTION_ID}\nOperands: {self._OPERANDS_ID}\nDirective: {self._DIRECTIVE_ID}\nComment: {self._COMMENT_ID}\nLabel: {self._LABEL_ID}\nLine: {self._LINE}\nLine Number: {self._LINE_NUMBER}\nSemantic Operands: {self._SEMANTIC_OPERANDS}\nFlags: {self._FLAGS}" + return f"Instruction: {self._instruction_id}\nOperands: {self._operands_id}\nDirective: {self._directive_id}\nComment: {self._comment_id}\nLabel: {self._label_id}\nLine: {self._line}\nLine Number: {self._line_number}\nSemantic Operands: {self._semantic_operands}\nFlags: {self._flags}" def __eq__(self, other): - if isinstance(other, InstructionForm): + 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 diff --git a/osaca/parser/label.py b/osaca/parser/label.py index 3a2d261..b456113 100644 --- a/osaca/parser/label.py +++ b/osaca/parser/label.py @@ -3,29 +3,29 @@ from osaca.parser.operand import Operand -class LabelOperand(Operand): - def __init__(self, NAME_ID=None, COMMENT_ID=None): - super().__init__(NAME_ID) - self._COMMENT_ID = COMMENT_ID +class labelOperand(Operand): + 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 + return self._comment_id @comment.setter def comment(self, comment): - self._COMMENT_ID = comment + self._comment_id = comment def __iter__(self): return self def __next__(self): - if not self._COMMENT_ID: + if not self._comment_id: raise StopIteration - return self._COMMENT_ID.pop(0) + return self._comment_id.pop(0) def __str__(self): - return f"LabelOperand(NAME_ID={self._NAME_ID}, COMMENT={self._COMMENT_ID})" + return f"labelOperand(name_id={self._name_id}, comment={self._comment_id})" def __repr__(self): - return f"LabelOperand(NAME_ID={self._NAME_ID}, COMMENT={self._COMMENT_ID})" + return f"labelOperand(name_id={self._name_id}, comment={self._comment_id})" diff --git a/osaca/parser/memory.py b/osaca/parser/memory.py index bac0e7a..5e66565 100644 --- a/osaca/parser/memory.py +++ b/osaca/parser/memory.py @@ -3,41 +3,39 @@ from osaca.parser.operand import Operand -class MemoryOperand(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, - PORT_PRESSURE=[], - DST=None, - SOURCE=False, - DESTINATION=False, + 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, + port_pressure=[], + dst=None, + source=False, + destination=False, ): - 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._PRE_INDEXED = PRE_INDEXED - self._POST_INDEXED = POST_INDEXED - self._INDEXED_VAL = INDEXED_VAL - self._PORT_PRESSURE = PORT_PRESSURE - self._DST = DST - self._SOURCE = SOURCE - self._DESTINATION = DESTINATION + super().__init__("memory", source, destination) + 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._pre_indexed = pre_indexed + self._post_indexed = post_indexed + self._indexed_val = indexed_val + self._port_pressure = port_pressure + self._dst = dst @property def offset(self): - return self._OFFSET_ID + return self._offset_ID @property def immediate(self): @@ -45,135 +43,119 @@ class MemoryOperand(Operand): @property def base(self): - return self._BASE_ID + return self._base_id @property def index(self): - return self._INDEX_ID + return self._index_id @property def scale(self): - return self._SCALE_ID + return self._scale_id @property def segment_ext_id(self): - return self._SEGMENT_EXT_ID + return self._segment_ext_id @property def mask(self): - return self._MASK + return self._mask @property def pre_indexed(self): - return self._PRE_INDEXED + return self._pre_indexed @property def post_indexed(self): - return self._POST_INDEXED + return self._post_indexed @property def indexed_val(self): - return self._INDEXED_VAL + return self._indexed_val @property def port_pressure(self): - return self._PORT_PRESSURE + return self._port_pressure @property def dst(self): - return self._DST + return self._dst @dst.setter def dst(self, dst): - self._DST = dst + self._dst = dst @port_pressure.setter def port_pressure(self, port_pressure): - self._PORT_PRESSURE = port_pressure + self._port_pressure = port_pressure @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): - self._OFFSET_ID = offset + self._offset_ID = offset @base.setter def base(self, base): - self._BASE_ID = base + self._base_id = base @index.setter def index(self, index): - self._INDEX_ID = index + self._index_id = index @scale.setter def scale(self, scale): - self._SCALE_ID = scale + self._scale_id = scale @mask.setter def mask(self, mask): - self._MASK = mask + self._mask = mask @pre_indexed.setter def pre_indexed(self, pre_indexed): - self._PRE_INDEXED = pre_indexed + self._pre_indexed = pre_indexed @post_indexed.setter def post_indexed(self, post_indexed): - self._POST_INDEXED = post_indexed + self._post_indexed = post_indexed @indexed_val.setter def indexed_val(self, value): - self._INDEXED_VAL = value - - @property - def source(self): - return self._SOURCE - - @source.setter - def source(self, source): - self._SOURCE = source - - @property - def destination(self): - return self._DESTINATION - - @destination.setter - def destination(self, destination): - self._DESTINATION = destination + self._indexed_val = value def __str__(self): return ( - f"MemoryOperand(NAME_ID={self._NAME_ID}, OFFSET_ID={self._OFFSET_ID}, " - f"BASE_ID={self._BASE_ID}, INDEX_ID={self._INDEX_ID}, SCALE_ID={self._SCALE_ID}, " - f"SEGMENT_EXT_ID={self._SEGMENT_EXT_ID}, MASK={self._MASK}, " - f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, " - f"INDEXED_VAL={self._INDEXED_VAL}, PORT_PRESSURE={self._PORT_PRESSURE})," - f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})" + f"memoryOperand(name_id={self._name_id}, offset_ID={self._offset_ID}, " + f"base_id={self._base_id}, index_id={self._index_id}, scale_id={self._scale_id}, " + f"segment_ext_id={self._segment_ext_id}, mask={self._mask}, " + f"pre_indexed={self._pre_indexed}, post_indexed={self._post_indexed}, " + f"indexed_val={self._indexed_val}, port_pressure={self._port_pressure})," + f"source={self._source}, destination={self._destination})" ) def __repr__(self): return ( - f"MemoryOperand(NAME_ID={self._NAME_ID}, OFFSET_ID={self._OFFSET_ID}, " - f"BASE_ID={self._BASE_ID}, INDEX_ID={self._INDEX_ID}, SCALE_ID={self._SCALE_ID}, " - f"SEGMENT_EXT_ID={self._SEGMENT_EXT_ID}, MASK={self._MASK}, " - f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, " - f"INDEXED_VAL={self._INDEXED_VAL}, PORT_PRESSURE={self._PORT_PRESSURE})," - f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})" + f"memoryOperand(name_id={self._name_id}, offset_ID={self._offset_ID}, " + f"base_id={self._base_id}, index_id={self._index_id}, scale_id={self._scale_id}, " + f"segment_ext_id={self._segment_ext_id}, mask={self._mask}, " + f"pre_indexed={self._pre_indexed}, post_indexed={self._post_indexed}, " + f"indexed_val={self._indexed_val}, port_pressure={self._port_pressure})," + f"source={self._source}, destination={self._destination})" ) def __eq__(self, other): - if isinstance(other, MemoryOperand): + 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 diff --git a/osaca/parser/operand.py b/osaca/parser/operand.py index ca7bd39..5f61558 100644 --- a/osaca/parser/operand.py +++ b/osaca/parser/operand.py @@ -2,19 +2,37 @@ class Operand: - def __init__(self, NAME_ID): - self._NAME_ID = NAME_ID + def __init__(self, name_id, source=False, destination=False): + self._name_id = name_id + self._source = source + self._destination = destination @property def name(self): - return self._NAME_ID + return self._name_id + + @property + def source(self): + return self._source + + @property + def destination(self): + return self._destination @name.setter def name(self, name): - self._NAME_ID = name + self._name_id = name + + @name.setter + def source(self, source): + self._source = source + + @destination.setter + def destination(self, destination): + self._destination = destination def __repr__(self): - return f"Operand(NAME_ID={self._NAME_ID}" + return f"Operand(name_id={self._name_id},source={self._source},destination={self._destination})" def __str__(self): - return f"Name: {self._NAME_ID}" + return f"Name: {self._name_id}, Source: {self._source}, Destination: {self._destination}" diff --git a/osaca/parser/parser_AArch64.py b/osaca/parser/parser_AArch64.py index f47ef82..a3855cb 100644 --- a/osaca/parser/parser_AArch64.py +++ b/osaca/parser/parser_AArch64.py @@ -3,14 +3,14 @@ from copy import deepcopy import pyparsing as pp from osaca.parser import BaseParser -from osaca.parser.instruction_form import InstructionForm +from osaca.parser.instruction_form import instructionForm from osaca.parser.operand import Operand -from osaca.parser.directive import DirectiveOperand -from osaca.parser.memory import MemoryOperand -from osaca.parser.label import LabelOperand -from osaca.parser.register import RegisterOperand -from osaca.parser.identifier import IdentifierOperand -from osaca.parser.immediate import ImmediateOperand +from osaca.parser.directive import directiveOperand +from osaca.parser.memory import memoryOperand +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 ParserAArch64(BaseParser): @@ -32,7 +32,7 @@ class ParserAArch64(BaseParser): symbol_comment = "//" self.comment = pp.Literal(symbol_comment) + pp.Group( pp.ZeroOrMore(pp.Word(pp.printables)) - ).setResultsName(self.COMMENT_ID) + ).setResultsName(self.comment_id) # Define ARM assembly identifier decimal_number = pp.Combine( pp.Optional(pp.Literal("-")) + pp.Word(pp.nums) @@ -54,7 +54,7 @@ class ParserAArch64(BaseParser): # Label self.label = pp.Group( identifier.setResultsName("name") + pp.Literal(":") + pp.Optional(self.comment) - ).setResultsName(self.LABEL_ID) + ).setResultsName(self.label_id) # Directive directive_option = pp.Combine( pp.Word(pp.alphas + "#@.%", exact=1) @@ -69,7 +69,7 @@ class ParserAArch64(BaseParser): + pp.Word(pp.alphanums + "_").setResultsName("name") + (pp.OneOrMore(directive_parameter) ^ commaSeparatedList).setResultsName("parameters") + pp.Optional(self.comment) - ).setResultsName(self.DIRECTIVE_ID) + ).setResultsName(self.directive_id) # LLVM-MCA markers self.llvm_markers = pp.Group( pp.Literal("#") @@ -78,7 +78,7 @@ class ParserAArch64(BaseParser): + (pp.CaselessLiteral("BEGIN") | pp.CaselessLiteral("END")) ) + pp.Optional(self.comment) - ).setResultsName(self.COMMENT_ID) + ).setResultsName(self.comment_id) ############################## # Instructions @@ -260,21 +260,21 @@ class ParserAArch64(BaseParser): :type line_number: int, optional :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_form = instructionForm( + instruction_id=None, + operands_id=[], + directive_id=None, + comment_id=None, + label_id=None, + line=line, + line_number=line_number, ) result = None # 1. Parse comment try: result = self.process_operand(self.comment.parseString(line, parseAll=True).asDict()) - instruction_form.comment = " ".join(result[self.COMMENT_ID]) + instruction_form.comment = " ".join(result[self.comment_id]) except pp.ParseException: pass # 1.2 check for llvm-mca marker @@ -282,7 +282,7 @@ class ParserAArch64(BaseParser): result = self.process_operand( self.llvm_markers.parseString(line, parseAll=True).asDict() ) - instruction_form.comment = " ".join(result[self.COMMENT_ID]) + instruction_form.comment = " ".join(result[self.comment_id]) except pp.ParseException: pass # 2. Parse label @@ -301,8 +301,8 @@ class ParserAArch64(BaseParser): result = self.process_operand( self.directive.parseString(line, parseAll=True).asDict() ) - instruction_form.directive = DirectiveOperand( - NAME_ID=result.name, PARAMETER_ID=result.parameters + instruction_form.directive = directiveOperand( + name_id=result.name, parameter_id=result.parameters ) if result.comment is not None: instruction_form.comment = " ".join(result.comment) @@ -353,10 +353,10 @@ class ParserAArch64(BaseParser): if "operand5" in result: 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, + 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, ) return return_dict @@ -376,30 +376,30 @@ class ParserAArch64(BaseParser): # add value attribute to floating point immediates without exponent if self.IMMEDIATE_ID in operand: return self.process_immediate(operand[self.IMMEDIATE_ID]) - if self.LABEL_ID in operand: - return self.process_label(operand[self.LABEL_ID]) + if self.label_id in operand: + return self.process_label(operand[self.label_id]) if self.IDENTIFIER_ID in operand: return self.process_identifier(operand[self.IDENTIFIER_ID]) if self.REGISTER_ID in operand: 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 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 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, + 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): @@ -422,11 +422,11 @@ 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=RegisterOperand(NAME_ID=base["name"], PREFIX_ID=base["prefix"]), - INDEX_ID=index, - SCALE_ID=scale, + new_dict = memoryOperand( + offset_ID=offset, + base_id=registerOperand(name_id=base["name"], prefix_id=base["prefix"]), + index_id=index, + scale_id=scale, ) if "pre_indexed" in memory_address: new_dict.pre_indexed = True @@ -440,7 +440,7 @@ class ParserAArch64(BaseParser): def process_sp_register(self, register): """Post-process stack pointer register""" # reg = register - new_reg = RegisterOperand(PREFIX_ID="x", NAME_ID="sp") + new_reg = registerOperand(prefix_id="x", name_id="sp") # reg["prefix"] = "x" return new_reg @@ -509,7 +509,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] @@ -517,8 +517,8 @@ 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" @@ -526,18 +526,18 @@ class ParserAArch64(BaseParser): 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, + new_label = labelOperand( + name_id=label["name"]["name"], + comment_id=label["comment"] if self.comment_id in label else None, ) return new_label @@ -546,7 +546,7 @@ 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""" diff --git a/osaca/parser/parser_x86att.py b/osaca/parser/parser_x86att.py index f9841fe..bf9eaf5 100644 --- a/osaca/parser/parser_x86att.py +++ b/osaca/parser/parser_x86att.py @@ -6,14 +6,14 @@ import re import pyparsing as pp from osaca.parser import BaseParser -from osaca.parser.instruction_form import InstructionForm +from osaca.parser.instruction_form import instructionForm from osaca.parser.operand import Operand -from osaca.parser.directive import DirectiveOperand -from osaca.parser.memory import MemoryOperand -from osaca.parser.label import LabelOperand -from osaca.parser.register import RegisterOperand -from osaca.parser.identifier import IdentifierOperand -from osaca.parser.immediate import ImmediateOperand +from osaca.parser.directive import directiveOperand +from osaca.parser.memory import memoryOperand +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): @@ -40,7 +40,7 @@ class ParserX86ATT(BaseParser): # Comment - either '#' or '//' (icc) self.comment = (pp.Literal("#") | pp.Literal("//")) + pp.Group( pp.ZeroOrMore(pp.Word(pp.printables)) - ).setResultsName(self.COMMENT_ID) + ).setResultsName(self.comment_id) # Define x86 assembly identifier relocation = pp.Combine(pp.Literal("@") + pp.Word(pp.alphas)) id_offset = pp.Word(pp.nums) + pp.Suppress(pp.Literal("+")) @@ -72,7 +72,7 @@ class ParserX86ATT(BaseParser): (label_identifier | numeric_identifier).setResultsName("name") + pp.Literal(":") + pp.Optional(self.comment) - ).setResultsName(self.LABEL_ID) + ).setResultsName(self.label_id) # Register: pp.Regex('^%[0-9a-zA-Z]+{}{z},?') self.register = pp.Group( pp.Literal("%") @@ -120,7 +120,7 @@ class ParserX86ATT(BaseParser): pp.Optional(pp.Suppress(pp.Literal("*"))) + self.register.setResultsName("base") + pp.Literal(":") - + segment_extension.setResultsName(self.SEGMENT_EXT_ID) + + segment_extension.setResultsName(self.segment_ext_id) ) # Memory: offset | seg:seg_ext | offset(base, index, scale){mask} memory_abs = pp.Suppress(pp.Literal("*")) + (offset | self.register).setResultsName( @@ -165,7 +165,7 @@ class ParserX86ATT(BaseParser): + pp.Word(pp.alphanums + "_").setResultsName("name") + pp.ZeroOrMore(directive_parameter).setResultsName("parameters") + pp.Optional(self.comment) - ).setResultsName(self.DIRECTIVE_ID) + ).setResultsName(self.directive_id) # Instructions # Mnemonic @@ -207,13 +207,13 @@ 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 try: result = self.process_operand(self.comment.parseString(line, parseAll=True).asDict()) - instruction_form.comment = " ".join(result[self.COMMENT_ID]) + instruction_form.comment = " ".join(result[self.comment_id]) except pp.ParseException: pass @@ -233,9 +233,9 @@ class ParserX86ATT(BaseParser): result = self.process_operand( self.directive.parseString(line, parseAll=True).asDict() ) - instruction_form.directive = DirectiveOperand( - NAME_ID=result.name, - PARAMETER_ID=result.parameters, + instruction_form.directive = directiveOperand( + name_id=result.name, + parameter_id=result.parameters, ) if result.comment != None: @@ -279,10 +279,10 @@ class ParserX86ATT(BaseParser): # Check fourth operand 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, + 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, ) return return_dict @@ -294,27 +294,27 @@ class ParserX86ATT(BaseParser): return self.process_memory_address(operand[self.MEMORY_ID]) if self.IMMEDIATE_ID in operand: return self.process_immediate(operand[self.IMMEDIATE_ID]) - if self.LABEL_ID in operand: - return self.process_label(operand[self.LABEL_ID]) - if self.DIRECTIVE_ID in operand: - return self.process_directive(operand[self.DIRECTIVE_ID]) + if self.label_id in operand: + return self.process_label(operand[self.label_id]) + 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"] + 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"] + 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: @@ -338,27 +338,27 @@ class ParserX86ATT(BaseParser): elif offset is not None and "value" in offset: offset["value"] = int(offset["value"], 0) if base != None: - baseOp = RegisterOperand( - NAME_ID=base["name"], PREFIX_ID=base["prefix"] if "prefix" in base else None + baseOp = registerOperand( + name_id=base["name"], prefix_id=base["prefix"] if "prefix" in base else None ) if index != None: - indexOp = RegisterOperand( - NAME_ID=index["name"], PREFIX_ID=index["prefix"] if "prefix" in index else None + indexOp = registerOperand( + name_id=index["name"], prefix_id=index["prefix"] if "prefix" in index else None ) - new_dict = MemoryOperand( - OFFSET_ID=offset, BASE_ID=baseOp, INDEX_ID=indexOp, SCALE_ID=scale + new_dict = memoryOperand( + offset_ID=offset, base_id=baseOp, index_id=indexOp, 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] + if self.segment_ext_id in memory_address: + new_dict.segment_ext_id = memory_address[self.segment_ext_id] return new_dict def process_label(self, label): """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 diff --git a/osaca/parser/register.py b/osaca/parser/register.py index 2cf004c..83b9e90 100644 --- a/osaca/parser/register.py +++ b/osaca/parser/register.py @@ -3,163 +3,143 @@ from osaca.parser.operand import Operand -class RegisterOperand(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, - SOURCE=False, - DESTINATION=False, + 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, + source=False, + destination=False, ): - super().__init__(NAME_ID) - self._WIDTH_ID = WIDTH_ID - self._PREFIX_ID = PREFIX_ID - self._REG_ID = REG_ID - self._REGTYPE_ID = REGTYPE_ID - self._LANES = LANES - self._SHAPE = SHAPE - self._INDEX = INDEX - self._MASK = MASK - self._ZEROING = ZEROING - self._PREDICATION = PREDICATION - self._SOURCE = SOURCE - self._DESTINATION = DESTINATION + super().__init__(name_id, source, destination) + self._width_id = width_id + self._prefix_id = prefix_id + self._reg_id = reg_id + self._regtype_id = regtype_id + self._lanes = lanes + self._shape = shape + self._index = index + self._mask = mask + self._zeroing = zeroing + self._predication = predication @property def width(self): - return self._WIDTH_ID + return self._width_id @width.setter def width(self, width): - self._WIDTH_ID = width + self._width_id = width @property def predication(self): - return self._PREDICATION + return self._predication @predication.setter def predication(self, predication): - self._PREDICATION = predication + self._predication = predication @property def regtype(self): - return self._REGTYPE_ID + return self._regtype_id @regtype.setter def regtype(self, regtype): - self._REGTYPE_ID = regtype + self._regtype_id = regtype @property def prefix(self): - return self._PREFIX_ID + return self._prefix_id @prefix.setter def prefix(self, prefix): - self._PREFIX = prefix + self._prefix = prefix @property def reg_id(self): - return self._REG_ID + return self._reg_id @reg_id.setter def reg_id(self, reg_id): - self._REG_ID = reg_id + self._reg_id = reg_id @property def lanes(self): - return self._LANES + return self._lanes @lanes.setter def lanes(self, lanes): - self._LANES = lanes + self._lanes = lanes @property def shape(self): - return self._SHAPE + return self._shape @shape.setter def shape(self, shape): - self._SHAPE = shape + self._shape = shape @property def index(self): - return self._INDEX + return self._index @index.setter def index(self, index): - self._INDEX = index + self._index = index @property def mask(self): - return self._MASK + return self._mask @mask.setter def mask(self, mask): - self._MASK = mask + self._mask = mask @property def zeroing(self): - return self._ZEROING + return self._zeroing @zeroing.setter def zeroing(self, zeroing): - self._ZEROING = zeroing - - @property - def source(self): - return self._SOURCE - - @source.setter - def source(self, source): - self._SOURCE = source - - @property - def destination(self): - return self._DESTINATION - - @destination.setter - def destination(self, destination): - self._DESTINATION = destination + self._zeroing = zeroing def __str__(self): return ( - f"RegisterOperand(NAME_ID={self._NAME_ID}, WIDTH_ID={self._WIDTH_ID}, " - f"PREFIX_ID={self._PREFIX_ID}, REG_ID={self._REG_ID}, REGTYPE_ID={self._REGTYPE_ID}, " - f"LANES={self._LANES}, SHAPE={self._SHAPE}, INDEX={self._INDEX}, " - f"MASK={self._MASK}, ZEROING={self._ZEROING})," - f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})" + f"registerOperand(name_id={self._name_id}, width_id={self._width_id}, " + f"prefix_id={self._prefix_id}, reg_id={self._reg_id}, REGtype_id={self._regtype_id}, " + f"lanes={self._lanes}, shape={self._shape}, index={self._index}, " + f"mask={self._mask}, zeroing={self._zeroing})" ) def __repr__(self): return ( - f"RegisterOperand(NAME_ID={self._NAME_ID}, WIDTH_ID={self._WIDTH_ID}, " - f"PREFIX_ID={self._PREFIX_ID}, REG_ID={self._REG_ID}, REGTYPE_ID={self._REGTYPE_ID}, " - f"LANES={self._LANES}, SHAPE={self._SHAPE}, INDEX={self._INDEX}, " - f"MASK={self._MASK}, ZEROING={self._ZEROING})," - f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})" + f"registerOperand(name_id={self._name_id}, width_id={self._width_id}, " + f"prefix_id={self._prefix_id}, reg_id={self._reg_id}, REGtype_id={self._regtype_id}, " + 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): + 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 diff --git a/osaca/semantics/__init__.py b/osaca/semantics/__init__.py index 8a0b000..5e1ceb9 100644 --- a/osaca/semantics/__init__.py +++ b/osaca/semantics/__init__.py @@ -3,7 +3,7 @@ Tools for semantic analysis of parser result. Only the classes below will be exported, so please add new semantic tools to __all__. """ -from .isa_semantics import ISASemantics, INSTR_FLAGS +from .isa_semantics import ISASemantics, INSTR_flags from .arch_semantics import ArchSemantics from .hw_model import MachineModel from .kernel_dg import KernelDG @@ -16,7 +16,7 @@ __all__ = [ "reduce_to_section", "ArchSemantics", "ISASemantics", - "INSTR_FLAGS", + "INSTR_flags", "find_basic_blocks", "find_basic_loop_bodies", "find_jump_labels", diff --git a/osaca/semantics/arch_semantics.py b/osaca/semantics/arch_semantics.py index 73db734..1bd3d38 100644 --- a/osaca/semantics/arch_semantics.py +++ b/osaca/semantics/arch_semantics.py @@ -8,11 +8,11 @@ from operator import itemgetter from copy import deepcopy from .hw_model import MachineModel -from .isa_semantics import INSTR_FLAGS, ISASemantics -from osaca.parser.memory import MemoryOperand -from osaca.parser.register import RegisterOperand -from osaca.parser.immediate import ImmediateOperand -from osaca.parser.identifier import IdentifierOperand +from .isa_semantics import INSTR_flags, ISASemantics +from osaca.parser.memory import memoryOperand +from osaca.parser.register import registerOperand +from osaca.parser.immediate import immediateOperand +from osaca.parser.identifier import identifierOperand class ArchSemantics(ISASemantics): @@ -139,8 +139,8 @@ class ArchSemantics(ISASemantics): def set_hidden_loads(self, kernel): """Hide loads behind stores if architecture supports hidden loads (depricated)""" - loads = [instr for instr in kernel if INSTR_FLAGS.HAS_LD in instr.flags] - stores = [instr for instr in kernel if INSTR_FLAGS.HAS_ST in instr.flags] + loads = [instr for instr in kernel if INSTR_flags.HAS_LD in instr.flags] + stores = [instr for instr in kernel if INSTR_flags.HAS_ST in instr.flags] # Filter instructions including load and store load_ids = [instr.line_number for instr in loads] store_ids = [instr.line_number for instr in stores] @@ -154,7 +154,7 @@ class ArchSemantics(ISASemantics): if len(loads) <= len(stores): # Hide all loads for load in loads: - load.flags += [INSTR_FLAGS.HIDDEN_LD] + load.flags += [INSTR_flags.HIDDEN_LD] load.port_pressure = self._nullify_data_ports(load.port_pressure) else: for store in stores: @@ -166,12 +166,12 @@ class ArchSemantics(ISASemantics): load_instr.line_number, ) for load_instr in loads - if INSTR_FLAGS.HIDDEN_LD not in load_instr.flags + if INSTR_flags.HIDDEN_LD not in load_instr.flags ] ) load = [instr for instr in kernel if instr.line_number == min_distance_load[1]][0] # Hide load - load.flags += [INSTR_FLAGS.HIDDEN_LD] + load.flags += [INSTR_flags.HIDDEN_LD] load.port_pressure = self._nullify_data_ports(load.port_pressure) # get parser result and assign throughput and latency value to instruction form @@ -226,8 +226,8 @@ class ArchSemantics(ISASemantics): assign_unknown = True # check for equivalent register-operands DB entry if LD if ( - INSTR_FLAGS.HAS_LD in instruction_form.flags - or INSTR_FLAGS.HAS_ST in instruction_form.flags + INSTR_flags.HAS_LD in instruction_form.flags + or INSTR_flags.HAS_ST in instruction_form.flags ): # dynamically combine LD/ST and reg form of instruction form # substitute mem and look for reg-only variant @@ -262,17 +262,17 @@ class ArchSemantics(ISASemantics): ] ) # dummy_reg = {"class": "register", "name": reg_type} - dummy_reg = RegisterOperand(NAME_ID=reg_type) + dummy_reg = registerOperand(name_id=reg_type) data_port_pressure = [0.0 for _ in range(port_number)] data_port_uops = [] - if INSTR_FLAGS.HAS_LD in instruction_form.flags: + if INSTR_flags.HAS_LD in instruction_form.flags: # LOAD performance data load_perf_data = self._machine_model.get_load_throughput( [ x for x in instruction_form.semantic_operands["source"] + instruction_form.semantic_operands["src_dst"] - if isinstance(x, MemoryOperand) + if isinstance(x, memoryOperand) ][0] ) # if multiple options, choose based on reg type @@ -281,7 +281,7 @@ class ArchSemantics(ISASemantics): for ldp in load_perf_data if ldp.dst != None and self._machine_model._check_operands( - dummy_reg, RegisterOperand(NAME_ID=ldp.dst) + dummy_reg, registerOperand(name_id=ldp.dst) ) ] if len(data_port_uops) < 1: @@ -296,14 +296,14 @@ class ArchSemantics(ISASemantics): reg_type ] data_port_pressure = [pp * multiplier for pp in data_port_pressure] - if INSTR_FLAGS.HAS_ST in instruction_form.flags: + if INSTR_flags.HAS_ST in instruction_form.flags: # STORE performance data destinations = ( instruction_form.semantic_operands["destination"] + instruction_form.semantic_operands["src_dst"] ) store_perf_data = self._machine_model.get_store_throughput( - [x for x in destinations if isinstance(x, MemoryOperand)][0], + [x for x in destinations if isinstance(x, memoryOperand)][0], dummy_reg, ) st_data_port_uops = store_perf_data[0].port_pressure @@ -320,12 +320,12 @@ class ArchSemantics(ISASemantics): [ op.post_indexed or op.pre_indexed for op in instruction_form.semantic_operands["src_dst"] - if isinstance(op, MemoryOperand) + if isinstance(op, memoryOperand) ] ) ): st_data_port_uops = [] - instruction_form.flags.remove(INSTR_FLAGS.HAS_ST) + instruction_form.flags.remove(INSTR_flags.HAS_ST) # sum up all data ports in case for LOAD and STORE st_data_port_pressure = self._machine_model.average_port_pressure( @@ -347,12 +347,12 @@ class ArchSemantics(ISASemantics): # Add LD and ST latency latency += ( self._machine_model.get_load_latency(reg_type) - if INSTR_FLAGS.HAS_LD in instruction_form.flags + if INSTR_flags.HAS_LD in instruction_form.flags else 0 ) latency += ( self._machine_model.get_store_latency(reg_type) - if INSTR_FLAGS.HAS_ST in instruction_form.flags + if INSTR_flags.HAS_ST in instruction_form.flags else 0 ) latency_wo_load = instruction_data_reg.latency @@ -391,7 +391,7 @@ class ArchSemantics(ISASemantics): latency_wo_load = latency instruction_form.port_pressure = [0.0 for i in range(port_number)] instruction_formport_uops = [] - flags += [INSTR_FLAGS.TP_UNKWN, INSTR_FLAGS.LT_UNKWN] + flags += [INSTR_flags.TP_UNKWN, INSTR_flags.LT_UNKWN] # flatten flag list flags = list(set(flags)) if instruction_form.flags == []: @@ -416,7 +416,7 @@ class ArchSemantics(ISASemantics): instruction_form.port_pressure = port_pressure if sum(port_pressure) == 0 and throughput is not None: # port pressure on all ports 0 --> not bound to a port - flags.append(INSTR_FLAGS.NOT_BOUND) + flags.append(INSTR_flags.NOT_BOUND) except AssertionError: warnings.warn( "Port pressure could not be imported correctly from database. " @@ -424,31 +424,31 @@ class ArchSemantics(ISASemantics): ) instruction_form.port_pressure = [0.0 for i in range(port_number)] instruction_form.port_uops = [] - flags.append(INSTR_FLAGS.TP_UNKWN) + flags.append(INSTR_flags.TP_UNKWN) if throughput is None: # assume 0 cy and mark as unknown throughput = 0.0 - flags.append(INSTR_FLAGS.TP_UNKWN) + flags.append(INSTR_flags.TP_UNKWN) latency = instruction_data.latency latency_wo_load = latency if latency is None: # assume 0 cy and mark as unknown latency = 0.0 latency_wo_load = latency - flags.append(INSTR_FLAGS.LT_UNKWN) - if INSTR_FLAGS.HAS_LD in instruction_form.flags: - flags.append(INSTR_FLAGS.LD) + flags.append(INSTR_flags.LT_UNKWN) + if INSTR_flags.HAS_LD in instruction_form.flags: + flags.append(INSTR_flags.LD) return throughput, port_pressure, latency, latency_wo_load def convert_op_to_reg(self, reg_type, reg_id="0"): """Create register operand for a memory addressing operand""" if self._isa == "x86": if reg_type == "gpr": - register = RegisterOperand(NAME_ID="r" + str(int(reg_id) + 9)) + register = registerOperand(name_id="r" + str(int(reg_id) + 9)) else: - register = RegisterOperand(NAME_ID=reg_type + reg_id) + register = registerOperand(name_id=reg_type + reg_id) elif self._isa == "aarch64": - register = RegisterOperand(NAME_ID=reg_id, PREFIX_ID=reg_type) + register = registerOperand(name_id=reg_id, prefix_id=reg_type) return register def _nullify_data_ports(self, port_pressure): diff --git a/osaca/semantics/hw_model.py b/osaca/semantics/hw_model.py index 8b3f7f0..1dc8e69 100644 --- a/osaca/semantics/hw_model.py +++ b/osaca/semantics/hw_model.py @@ -14,12 +14,12 @@ import ruamel.yaml from osaca import __version__, utils from osaca.parser import ParserX86ATT from ruamel.yaml.compat import StringIO -from osaca.parser.instruction_form import InstructionForm +from osaca.parser.instruction_form import instructionForm from osaca.parser.operand import Operand -from osaca.parser.memory import MemoryOperand -from osaca.parser.register import RegisterOperand -from osaca.parser.immediate import ImmediateOperand -from osaca.parser.identifier import IdentifierOperand +from osaca.parser.memory import memoryOperand +from osaca.parser.register import registerOperand +from osaca.parser.immediate import immediateOperand +from osaca.parser.identifier import identifierOperand class MachineModel(object): @@ -73,7 +73,7 @@ class MachineModel(object): self._data = MachineModel._runtime_cache[self._path] # check if file is cached cached = self._get_cached(self._path) if not lazy else False - if False: + if cached: self._data = cached else: yaml = self._create_yaml_object() @@ -104,8 +104,6 @@ class MachineModel(object): self._data["instruction_forms_dict"] = defaultdict(list) for iform in self._data["instruction_forms"]: - if "breaks_dependency_on_equal_operands" in iform: - print(iform["breaks_dependency_on_equal_operands"],"\n") iform["name"] = iform["name"].upper() if iform["operands"] != []: new_operands = [] @@ -114,34 +112,37 @@ class MachineModel(object): self.operand_to_class(o, new_operands) iform["operands"] = new_operands # Do the same for hidden operands - if iform["hidden_operands"] != []: + if "hidden_operands" in iform: new_operands = [] # Change operand types from dicts to classes for o in iform["hidden_operands"]: self.operand_to_class(o, new_operands) - iform["hidden_operands"] = new_operands + iform["hidden_operands"] = new_operands # Change dict iform style to class style - new_iform = InstructionForm( - INSTRUCTION_ID=iform["name"].upper() if "name" in iform else None, - OPERANDS_ID=iform["operands"] if "operands" in iform else [], - HIDDEN_OPERANDS=iform["hidden_operands"] if "hidden_operansd" in iform else [], - DIRECTIVE_ID=iform["directive"] if "directive" in iform else None, - COMMENT_ID=iform["comment"] if "comment" in iform else None, - LINE=iform["line"] if "line" in iform else None, - LINE_NUMBER=iform["line_number"] if "line_number" in iform else None, - LATENCY=iform["latency"] if "latency" in iform else None, - THROUGHPUT=iform["throughput"] if "throughput" in iform else None, - UOPS=iform["uops"] if "uops" in iform else None, - PORT_PRESSURE=iform["port_pressure"] if "port_pressure" in iform else None, - BREAKS_DEP=iform["breaks_dependency_on_equal_operands"] if "breaks_dependency_on_equal_operands" in iform else False, - SEMANTIC_OPERANDS=iform["semantic_operands"] + new_iform = instructionForm( + instruction_id=iform["name"].upper() if "name" in iform else None, + operands_id=iform["operands"] if "operands" in iform else [], + hidden_operands=iform["hidden_operands"] + if "hidden_operansd" in iform + else [], + directive_id=iform["directive"] if "directive" in iform else None, + comment_id=iform["comment"] if "comment" in iform else None, + line=iform["line"] if "line" in iform else None, + line_number=iform["line_number"] if "line_number" in iform else None, + latency=iform["latency"] if "latency" in iform else None, + throughput=iform["throughput"] if "throughput" in iform else None, + uops=iform["uops"] if "uops" in iform else None, + port_pressure=iform["port_pressure"] if "port_pressure" in iform else None, + breaks_dep=iform["breaks_dependency_on_equal_operands"] + if "breaks_dependency_on_equal_operands" in iform + else False, + semantic_operands=iform["semantic_operands"] if "semantic_operands" in iform else {"source": [], "destination": [], "src_dst": []}, ) # List containing classes with same name/instruction self._data["instruction_forms_dict"][iform["name"]].append(new_iform) - self._data["internal_version"] = self.INTERNAL_VERSION if not lazy: @@ -156,13 +157,13 @@ class MachineModel(object): if "load_throughput" in self._data: for m in self._data["load_throughput"]: new_throughputs.append( - MemoryOperand( - BASE_ID=m["base"], - OFFSET_ID=m["offset"], - SCALE_ID=m["scale"], - INDEX_ID=m["index"], - PORT_PRESSURE=m["port_pressure"], - DST=m["dst"] if "dst" in m else None, + memoryOperand( + base_id=m["base"], + offset_ID=m["offset"], + scale_id=m["scale"], + index_id=m["index"], + port_pressure=m["port_pressure"], + ds=m["dst"] if "dst" in m else None, ) ) self._data["load_throughput"] = new_throughputs @@ -171,12 +172,12 @@ class MachineModel(object): if "store_throughput" in self._data: for m in self._data["store_throughput"]: new_throughputs.append( - MemoryOperand( - BASE_ID=m["base"], - OFFSET_ID=m["offset"], - SCALE_ID=m["scale"], - INDEX_ID=m["index"], - PORT_PRESSURE=m["port_pressure"], + memoryOperand( + base_id=m["base"], + offset_ID=m["offset"], + scale_id=m["scale"], + index_id=m["index"], + port_pressure=m["port_pressure"], ) ) self._data["store_throughput"] = new_throughputs @@ -185,36 +186,36 @@ class MachineModel(object): """Convert an operand from dict type to class""" if o["class"] == "register": new_operands.append( - RegisterOperand( - NAME_ID=o["name"] if "name" in o else None, - PREFIX_ID=o["prefix"] if "prefix" in o else None, - SHAPE=o["shape"] if "shape" in o else None, - MASK=o["mask"] if "mask" in o else False, - SOURCE=o["source"] if "source" in o else False, - DESTINATION=o["destination"] if "destination" in o else False, + registerOperand( + name_id=o["name"] if "name" in o else None, + prefix_id=o["prefix"] if "prefix" in o else None, + shape=o["shape"] if "shape" in o else None, + mask=o["mask"] if "mask" in o else False, + source=o["source"] if "source" in o else False, + destination=o["destination"] if "destination" in o else False, ) ) elif o["class"] == "memory": new_operands.append( - MemoryOperand( - BASE_ID=o["base"], - OFFSET_ID=o["offset"], - INDEX_ID=o["index"], - SCALE_ID=o["scale"], - SOURCE=o["source"] if "source" in o else False, - DESTINATION=o["destination"] if "destination" in o else False, + memoryOperand( + base_id=o["base"], + offset_ID=o["offset"], + index_id=o["index"], + scale_id=o["scale"], + source=o["source"] if "source" in o else False, + destination=o["destination"] if "destination" in o else False, ) ) elif o["class"] == "immediate": new_operands.append( - ImmediateOperand( - TYPE_ID=o["imd"], - SOURCE=o["source"] if "source" in o else False, - DESTINATION=o["destination"] if "destination" in o else False, + immediateOperand( + type_id=o["imd"], + source=o["source"] if "source" in o else False, + destination=o["destination"] if "destination" in o else False, ) ) elif o["class"] == "identifier": - new_operands.append(IdentifierOperand()) + new_operands.append(identifierOperand()) else: new_operands.append(o) @@ -283,7 +284,7 @@ class MachineModel(object): # If it already exists. Overwrite information. instr_data = self.get_instruction(instruction, operands) if instr_data is None: - instr_data = InstructionForm() + instr_data = instructionForm() self._data["instruction_forms"].append(instr_data) self._data["instruction_forms_dict"][instruction].append(instr_data) @@ -339,7 +340,7 @@ class MachineModel(object): ld_tp = [m for m in self._data["load_throughput"] if self._match_mem_entries(memory, m)] if len(ld_tp) > 0: return ld_tp.copy() - return [MemoryOperand(PORT_PRESSURE=self._data["load_throughput_default"].copy())] + return [memoryOperand(port_pressure=self._data["load_throughput_default"].copy())] def get_store_latency(self, reg_type): """Return store latency for given register type.""" @@ -354,11 +355,11 @@ class MachineModel(object): tp for tp in st_tp if "src" in tp - and self._check_operands(src_reg, RegisterOperand(NAME_ID=tp["src"])) + and self._check_operands(src_reg, registerOperand(name_id=tp["src"])) ] if len(st_tp) > 0: return st_tp.copy() - return [MemoryOperand(PORT_PRESSURE=self._data["store_throughput_default"].copy())] + return [memoryOperand(port_pressure=self._data["store_throughput_default"].copy())] def _match_mem_entries(self, mem, i_mem): """Check if memory addressing ``mem`` and ``i_mem`` are of the same type.""" @@ -570,19 +571,19 @@ class MachineModel(object): def _create_db_operand_aarch64(self, operand): """Create instruction form operand for DB out of operand string.""" if operand == "i": - return ImmediateOperand(TYPE_ID="int") + return immediateOperand(type_id="int") elif operand in "wxbhsdq": - return RegisterOperand(PREFIX_ID=operand) + return registerOperand(prefix_id=operand) elif operand.startswith("v"): - return RegisterOperand(PREFIX_ID="v", SHAPE=operand[1:2]) + return registerOperand(prefix_id="v", shape=operand[1:2]) elif operand.startswith("m"): - return MemoryOperand( - BASE_ID="x" if "b" in operand else None, - OFFSET_ID="imd" if "o" in operand else None, - INDEX_ID="gpr" if "i" in operand else None, - SCALE_ID=8 if "s" in operand else 1, - PRE_INDEXED=True if "r" in operand else False, - POST_INDEXED=True if "p" in operand else False, + return memoryOperand( + base_id="x" if "b" in operand else None, + offset_ID="imd" if "o" in operand else None, + index_id="gpr" if "i" in operand else None, + scale_id=8 if "s" in operand else 1, + pre_indexed=True if "r" in operand else False, + post_indexed=True if "p" in operand else False, ) else: raise ValueError("Parameter {} is not a valid operand code".format(operand)) @@ -590,17 +591,17 @@ class MachineModel(object): def _create_db_operand_x86(self, operand): """Create instruction form operand for DB out of operand string.""" if operand == "r": - return RegisterOperand(NAME_ID="gpr") + return registerOperand(name_id="gpr") elif operand in "xyz": - return RegisterOperand(NAME_ID=operand + "mm") + return registerOperand(name_id=operand + "mm") elif operand == "i": - return ImmediateOperand(TYPE_ID="int") + return immediateOperand(type_id="int") elif operand.startswith("m"): - return MemoryOperand( - BASE_ID="gpr" if "b" in operand else None, - OFFSET_ID="imd" if "o" in operand else None, - INDEX_ID="gpr" if "i" in operand else None, - SCALE_ID=8 if "s" in operand else 1, + return memoryOperand( + base_id="gpr" if "b" in operand else None, + offset_ID="imd" if "o" in operand else None, + index_id="gpr" if "i" in operand else None, + scale_id=8 if "s" in operand else 1, ) else: raise ValueError("Parameter {} is not a valid operand code".format(operand)) @@ -643,7 +644,7 @@ class MachineModel(object): if (isinstance(operand, Operand) and operand.name == self.WILDCARD) or ( not isinstance(operand, Operand) and self.WILDCARD in operand ): - if isinstance(i_operand, RegisterOperand): + if isinstance(i_operand, registerOperand): return True else: return False @@ -659,45 +660,45 @@ class MachineModel(object): # return self._compare_db_entries(i_operand, operand) # TODO support class wildcards # register - if isinstance(operand, RegisterOperand): - if not isinstance(i_operand, RegisterOperand): + if isinstance(operand, registerOperand): + if not isinstance(i_operand, registerOperand): return False return self._is_AArch64_reg_type(i_operand, operand) # memory - if isinstance(operand, MemoryOperand): - if not isinstance(i_operand, MemoryOperand): + if isinstance(operand, memoryOperand): + if not isinstance(i_operand, memoryOperand): return False return self._is_AArch64_mem_type(i_operand, operand) # immediate - if isinstance(i_operand, ImmediateOperand) and i_operand.type == self.WILDCARD: - return isinstance(operand, ImmediateOperand) and (operand.value != None) + if isinstance(i_operand, immediateOperand) and i_operand.type == self.WILDCARD: + return isinstance(operand, immediateOperand) and (operand.value != None) - if isinstance(i_operand, ImmediateOperand) and i_operand.type == "int": + if isinstance(i_operand, immediateOperand) and i_operand.type == "int": return ( - isinstance(operand, ImmediateOperand) + isinstance(operand, immediateOperand) and operand.type == "int" and operand.value != None ) - if isinstance(i_operand, ImmediateOperand) and i_operand.type == "float": + if isinstance(i_operand, immediateOperand) and i_operand.type == "float": return ( - isinstance(operand, ImmediateOperand) + isinstance(operand, immediateOperand) and operand.type == "float" and operand.value != None ) - if isinstance(i_operand, ImmediateOperand) and i_operand.type == "double": + if isinstance(i_operand, immediateOperand) and i_operand.type == "double": return ( - isinstance(operand, ImmediateOperand) + isinstance(operand, immediateOperand) and operand.type == "double" and operand.value != None ) # identifier - if isinstance(operand, IdentifierOperand) or ( - isinstance(operand, ImmediateOperand) and operand.identifier != None + if isinstance(operand, identifierOperand) or ( + isinstance(operand, immediateOperand) and operand.identifier != None ): - return isinstance(i_operand, IdentifierOperand) + return isinstance(i_operand, identifierOperand) # prefetch option if not isinstance(operand, Operand) and "prfop" in operand: return i_operand["class"] == "prfop" @@ -719,22 +720,22 @@ class MachineModel(object): # compare two DB entries # return self._compare_db_entries(i_operand, operand) # register - if isinstance(operand, RegisterOperand): - if not isinstance(i_operand, RegisterOperand): + if isinstance(operand, registerOperand): + if not isinstance(i_operand, registerOperand): return False return self._is_x86_reg_type(i_operand, operand, consider_masking=False) # memory - if isinstance(operand, MemoryOperand): - if not isinstance(i_operand, MemoryOperand): + if isinstance(operand, memoryOperand): + if not isinstance(i_operand, memoryOperand): return False return self._is_x86_mem_type(i_operand, operand) # immediate - if isinstance(operand, ImmediateOperand): + if isinstance(operand, immediateOperand): # if "immediate" in operand.name or operand.value != None: - return isinstance(i_operand, ImmediateOperand) and i_operand.type == "int" + return isinstance(i_operand, immediateOperand) and i_operand.type == "int" # identifier (e.g., labels) - if isinstance(operand, IdentifierOperand): - return isinstance(i_operand, IdentifierOperand) + if isinstance(operand, identifierOperand): + return isinstance(i_operand, identifierOperand) return self._compare_db_entries(i_operand, operand) def _compare_db_entries(self, operand_1, operand_2): @@ -790,7 +791,7 @@ class MachineModel(object): if i_reg is None: return True return False - if isinstance(i_reg, RegisterOperand): + if isinstance(i_reg, registerOperand): i_reg_name = i_reg.name else: i_reg_name = i_reg @@ -842,7 +843,7 @@ class MachineModel(object): ( (mem.base is None and i_mem.base is None) or i_mem.base == self.WILDCARD - or (isinstance(mem.base, RegisterOperand) and (mem.base.prefix == i_mem.base)) + or (isinstance(mem.base, registerOperand) and (mem.base.prefix == i_mem.base)) ) # check offset and ( diff --git a/osaca/semantics/isa_semantics.py b/osaca/semantics/isa_semantics.py index eaf578d..ba37cbf 100644 --- a/osaca/semantics/isa_semantics.py +++ b/osaca/semantics/isa_semantics.py @@ -3,14 +3,14 @@ from itertools import chain from osaca import utils from osaca.parser import AttrDict, ParserAArch64, ParserX86ATT -from osaca.parser.memory import MemoryOperand -from osaca.parser.register import RegisterOperand -from osaca.parser.immediate import ImmediateOperand +from osaca.parser.memory import memoryOperand +from osaca.parser.register import registerOperand +from osaca.parser.immediate import immediateOperand from .hw_model import MachineModel -class INSTR_FLAGS: +class INSTR_flags: """ Flags used for unknown or special instructions """ @@ -81,7 +81,7 @@ class ISASemantics(object): # Couldn't found instruction form in ISA DB assign_default = True # check for equivalent register-operands DB entry if LD/ST - if any([isinstance(op, MemoryOperand) for op in operands]): + if any([isinstance(op, memoryOperand) for op in operands]): operands_reg = self.substitute_mem_address(instruction_form.operands) isa_data_reg = self._isa_model.get_instruction( instruction_form.instruction, operands_reg @@ -116,7 +116,7 @@ class ISASemantics(object): op_dict["src_dst"] = [] # post-process pre- and post-indexing for aarch64 memory operands if self._isa == "aarch64": - for operand in [op for op in op_dict["source"] if isinstance(op, MemoryOperand)]: + for operand in [op for op in op_dict["source"] if isinstance(op, memoryOperand)]: post_indexed = operand.post_indexed pre_indexed = operand.pre_indexed if post_indexed or pre_indexed: @@ -127,7 +127,7 @@ class ISASemantics(object): "post_indexed": post_indexed, } ) - for operand in [op for op in op_dict["destination"] if isinstance(op, MemoryOperand)]: + for operand in [op for op in op_dict["destination"] if isinstance(op, memoryOperand)]: post_indexed = operand.post_indexed pre_indexed = operand.pre_indexed if post_indexed or pre_indexed: @@ -146,9 +146,9 @@ class ISASemantics(object): # ) if self._has_load(instruction_form): - instruction_form.flags += [INSTR_FLAGS.HAS_LD] + instruction_form.flags += [INSTR_flags.HAS_LD] if self._has_store(instruction_form): - instruction_form.flags += [INSTR_FLAGS.HAS_ST] + instruction_form.flags += [INSTR_flags.HAS_ST] def get_reg_changes(self, instruction_form, only_postindexed=False): """ @@ -165,7 +165,7 @@ class ISASemantics(object): instruction_form.semantic_operands["destination"], instruction_form.semantic_operands["src_dst"], ) - if isinstance(op, RegisterOperand) + if isinstance(op, registerOperand) ] isa_data = self._isa_model.get_instruction( instruction_form.instruction, instruction_form.operands @@ -188,7 +188,7 @@ class ISASemantics(object): if only_postindexed: for o in instruction_form.operands: - if isinstance(o, MemoryOperand) and o.base != None and o.post_indexed != False: + if isinstance(o, memoryOperand) and o.base != None and o.post_indexed != False: base_name = o.base.prefix if o.base.prefix != None else "" + o.base.name return { base_name: { @@ -202,7 +202,7 @@ class ISASemantics(object): operand_state = {} # e.g., {'op1': {'name': 'rax', 'value': 0}} 0 means unchanged for o in instruction_form.operands: - if isinstance(o, MemoryOperand) and o.pre_indexed: + if isinstance(o, memoryOperand) and o.pre_indexed: # Assuming no isa_data.operation if isa_data is not None and isa_data.get("operation", None) is not None: raise ValueError( @@ -216,13 +216,13 @@ class ISASemantics(object): if isa_data is not None: for i, o in enumerate(instruction_form.operands): operand_name = "op{}".format(i + 1) - if isinstance(o, RegisterOperand): + if isinstance(o, registerOperand): o_reg_name = o.prefix if o.prefix != None else "" + o.name reg_operand_names[o_reg_name] = operand_name operand_state[operand_name] = {"name": o_reg_name, "value": 0} - elif isinstance(o, ImmediateOperand): + elif isinstance(o, immediateOperand): operand_state[operand_name] = {"value": o.value} - elif isinstance(o, MemoryOperand): + elif isinstance(o, memoryOperand): # TODO lea needs some thinking about pass @@ -301,7 +301,7 @@ class ISASemantics(object): instruction_form.semantic_operands["source"], instruction_form.semantic_operands["src_dst"], ): - if isinstance(operand, MemoryOperand): + if isinstance(operand, memoryOperand): return True return False @@ -311,7 +311,7 @@ class ISASemantics(object): instruction_form.semantic_operands["destination"], instruction_form.semantic_operands["src_dst"], ): - if isinstance(operand, MemoryOperand): + if isinstance(operand, memoryOperand): return True return False @@ -345,7 +345,7 @@ class ISASemantics(object): def substitute_mem_address(self, operands): """Create memory wildcard for all memory operands""" return [ - self._create_reg_wildcard() if isinstance(op, MemoryOperand) else op for op in operands + self._create_reg_wildcard() if isinstance(op, memoryOperand) else op for op in operands ] def _create_reg_wildcard(self): diff --git a/osaca/semantics/kernel_dg.py b/osaca/semantics/kernel_dg.py index b686941..b3c9d31 100644 --- a/osaca/semantics/kernel_dg.py +++ b/osaca/semantics/kernel_dg.py @@ -8,10 +8,10 @@ from itertools import chain from multiprocessing import Manager, Process, cpu_count import networkx as nx -from osaca.semantics import INSTR_FLAGS, ArchSemantics, MachineModel -from osaca.parser.memory import MemoryOperand -from osaca.parser.register import RegisterOperand -from osaca.parser.immediate import ImmediateOperand +from osaca.semantics import INSTR_flags, ArchSemantics, MachineModel +from osaca.parser.memory import memoryOperand +from osaca.parser.register import registerOperand +from osaca.parser.immediate import immediateOperand class KernelDG(nx.DiGraph): @@ -66,8 +66,8 @@ class KernelDG(nx.DiGraph): dg.nodes[instruction_form.line_number]["instruction_form"] = instruction_form # add load as separate node if existent if ( - INSTR_FLAGS.HAS_LD in instruction_form.flags - and INSTR_FLAGS.LD not in instruction_form.flags + INSTR_flags.HAS_LD in instruction_form.flags + and INSTR_flags.LD not in instruction_form.flags ): # add new node dg.add_node(instruction_form.line_number + 0.1) @@ -283,7 +283,7 @@ class KernelDG(nx.DiGraph): for i, instr_form in enumerate(instructions): self._update_reg_changes(instr_form, register_changes) # print(" TO", instr_form.line, register_changes) - if isinstance(dst, RegisterOperand): + if isinstance(dst, registerOperand): # read of register if self.is_read(dst, instr_form): # if dst.pre_indexed or dst.post_indexed: @@ -294,8 +294,8 @@ class KernelDG(nx.DiGraph): if self.is_written(dst, instr_form): break if ( - not isinstance(dst, RegisterOperand) - and not isinstance(dst, MemoryOperand) + not isinstance(dst, registerOperand) + and not isinstance(dst, memoryOperand) and "flag" in dst and flag_dependencies ): @@ -305,7 +305,7 @@ class KernelDG(nx.DiGraph): # write to flag -> abort if self.is_written(dst.flag, instr_form): break - if isinstance(dst, MemoryOperand): + if isinstance(dst, memoryOperand): # base register is altered during memory access if dst.pre_indexed != None: if self.is_written(dst.base, instr_form): @@ -374,16 +374,16 @@ class KernelDG(nx.DiGraph): instruction_form.semantic_operands["source"], instruction_form.semantic_operands["src_dst"], ): - if isinstance(src, RegisterOperand): + if isinstance(src, registerOperand): is_read = self.parser.is_reg_dependend_of(register, src) or is_read if ( - not isinstance(src, RegisterOperand) - and not isinstance(src, MemoryOperand) - and not isinstance(src, ImmediateOperand) + not isinstance(src, registerOperand) + and not isinstance(src, memoryOperand) + and not isinstance(src, immediateOperand) and "flag" in src ): is_read = self.parser.is_flag_dependend_of(register, src.flag) or is_read - if isinstance(src, MemoryOperand): + if isinstance(src, memoryOperand): if src.base is not None: is_read = self.parser.is_reg_dependend_of(register, src.base) or is_read if src.index is not None: @@ -393,7 +393,7 @@ class KernelDG(nx.DiGraph): instruction_form.semantic_operands["destination"], instruction_form.semantic_operands["src_dst"], ): - if isinstance(dst, MemoryOperand): + if isinstance(dst, memoryOperand): if dst.base is not None: is_read = self.parser.is_reg_dependend_of(register, dst.base) or is_read if dst.index is not None: @@ -409,7 +409,7 @@ class KernelDG(nx.DiGraph): instruction_form.semantic_operands["src_dst"], ): # Here we check for mem dependecies only - if not isinstance(src, MemoryOperand): + if not isinstance(src, memoryOperand): continue # src = src.memory @@ -482,15 +482,15 @@ class KernelDG(nx.DiGraph): instruction_form.semantic_operands["destination"], instruction_form.semantic_operands["src_dst"], ): - if isinstance(dst, RegisterOperand): + if isinstance(dst, registerOperand): is_written = self.parser.is_reg_dependend_of(register, dst) or is_written if ( - not isinstance(dst, RegisterOperand) - and not isinstance(dst, MemoryOperand) + not isinstance(dst, registerOperand) + and not isinstance(dst, memoryOperand) and "flag" in dst ): is_written = self.parser.is_flag_dependend_of(register, dst.flag) or is_written - if isinstance(dst, MemoryOperand): + if isinstance(dst, memoryOperand): if dst.pre_indexed or dst.post_indexed: is_written = self.parser.is_reg_dependend_of(register, dst.base) or is_written # Check also for possible pre- or post-indexing in memory addresses @@ -498,7 +498,7 @@ class KernelDG(nx.DiGraph): instruction_form.semantic_operands["source"], instruction_form.semantic_operands["src_dst"], ): - if isinstance(src, MemoryOperand): + if isinstance(src, memoryOperand): if src.pre_indexed or src.post_indexed: is_written = self.parser.is_reg_dependend_of(register, src.base) or is_written return is_written @@ -512,7 +512,7 @@ class KernelDG(nx.DiGraph): instruction_form.semantic_operands["destination"], instruction_form.semantic_operands["src_dst"], ): - if isinstance(dst, MemoryOperand): + if isinstance(dst, memoryOperand): is_store = mem == dst or is_store return is_store diff --git a/tests/test_db_interface.py b/tests/test_db_interface.py index 8bb47d3..a85d738 100755 --- a/tests/test_db_interface.py +++ b/tests/test_db_interface.py @@ -9,24 +9,24 @@ from io import StringIO import osaca.db_interface as dbi from osaca.db_interface import sanity_check from osaca.semantics import MachineModel -from osaca.parser import InstructionForm -from osaca.parser.memory import MemoryOperand -from osaca.parser.register import RegisterOperand +from osaca.parser import instructionForm +from osaca.parser.memory import memoryOperand +from osaca.parser.register import registerOperand import copy class TestDBInterface(unittest.TestCase): @classmethod def setUpClass(self): - sample_entry = InstructionForm( - INSTRUCTION_ID="DoItRightAndDoItFast", - OPERANDS_ID=[ - MemoryOperand(OFFSET_ID="imd", BASE_ID="gpr", INDEX_ID="gpr", SCALE_ID=8), - RegisterOperand(NAME_ID="xmm"), + sample_entry = instructionForm( + instruction_id="DoItRightAndDoItFast", + operands_id=[ + memoryOperand(offset_ID="imd", base_id="gpr", index_id="gpr", scale_id=8), + registerOperand(name_id="xmm"), ], - THROUGHPUT=1.25, - LATENCY=125, - UOPS=6, + throughput=1.25, + latency=125, + uops=6, ) self.entry_csx = copy.copy(sample_entry) @@ -61,7 +61,7 @@ class TestDBInterface(unittest.TestCase): mm_csx.set_instruction_entry(self.entry_csx) mm_tx2.set_instruction_entry(self.entry_tx2) - mm_zen1.set_instruction_entry(InstructionForm(INSTRUCTION_ID="empty_operation")) + mm_zen1.set_instruction_entry(instructionForm(instruction_id="empty_operation")) num_entries_csx = len(mm_csx["instruction_forms"]) - num_entries_csx num_entries_tx2 = len(mm_tx2["instruction_forms"]) - num_entries_tx2 @@ -72,7 +72,7 @@ class TestDBInterface(unittest.TestCase): self.assertEqual(num_entries_zen1, 1) def test_invalid_add(self): - entry = InstructionForm() + entry = instructionForm() # with self.assertRaises(KeyError): # MachineModel("csx").set_instruction_entry(entry) with self.assertRaises(TypeError): diff --git a/tests/test_parser_AArch64.py b/tests/test_parser_AArch64.py index 2845d2e..4bddee2 100755 --- a/tests/test_parser_AArch64.py +++ b/tests/test_parser_AArch64.py @@ -8,12 +8,12 @@ import unittest from pyparsing import ParseException -from osaca.parser import ParserAArch64, InstructionForm +from osaca.parser import ParserAArch64, instructionForm from osaca.parser.operand import Operand -from osaca.parser.directive import DirectiveOperand -from osaca.parser.memory import MemoryOperand -from osaca.parser.register import RegisterOperand -from osaca.parser.immediate import ImmediateOperand +from osaca.parser.directive import directiveOperand +from osaca.parser.memory import memoryOperand +from osaca.parser.register import registerOperand +from osaca.parser.immediate import immediateOperand class TestParserAArch64(unittest.TestCase): @@ -181,140 +181,140 @@ class TestParserAArch64(unittest.TestCase): line_5_operands = "fcmla z26.d, p0/m, z29.d, z21.d, #90" 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_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_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_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_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_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_form_4 = InstructionForm( - INSTRUCTION_ID="ldr", - OPERANDS_ID=[ - RegisterOperand(PREFIX_ID="s", NAME_ID="0"), - MemoryOperand( - OFFSET_ID=None, - BASE_ID=RegisterOperand(PREFIX_ID="x", NAME_ID="11"), - INDEX_ID={ + instruction_form_4 = instructionForm( + instruction_id="ldr", + operands_id=[ + registerOperand(prefix_id="s", name_id="0"), + memoryOperand( + offset_ID=None, + base_id=registerOperand(prefix_id="x", name_id="11"), + index_id={ "prefix": "w", "name": "10", "shift_op": "sxtw", "immediate": {"value": "2"}, "shift": [{"value": "2"}], }, - SCALE_ID=4, + scale_id=4, ), ], - DIRECTIVE_ID=None, - COMMENT_ID="= <<2", - LABEL_ID=None, - LINE="ldr s0, [x11, w10, sxtw #2] // = <<2", - LINE_NUMBER=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_form_5 = instructionForm( + instruction_id="prfm", + operands_id=[ {"prfop": {"type": ["PLD"], "target": ["L1"], "policy": ["KEEP"]}}, - MemoryOperand( - OFFSET_ID={"value": 2048}, - BASE_ID=RegisterOperand(PREFIX_ID="x", NAME_ID="26"), - INDEX_ID=None, - SCALE_ID=1, + memoryOperand( + offset_ID={"value": 2048}, + base_id=registerOperand(prefix_id="x", name_id="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=RegisterOperand(NAME_ID="sp", PREFIX_ID="x"), - INDEX_ID=None, - SCALE_ID=1, - PRE_INDEXED=True, + 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=registerOperand(name_id="sp", prefix_id="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=RegisterOperand(NAME_ID="11", PREFIX_ID="x"), - INDEX_ID=None, - SCALE_ID=1, - POST_INDEXED={"value": 64}, + 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=registerOperand(name_id="11", prefix_id="x"), + 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_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"), ], - 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_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"), {"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) @@ -372,17 +372,17 @@ class TestParserAArch64(unittest.TestCase): instr_list_with_index = "ld4 {v0.S, v1.S, v2.S, v3.S}[2]" instr_range_single = "dummy { z1.d }" reg_list = [ - RegisterOperand(PREFIX_ID="x", NAME_ID="5"), - RegisterOperand(PREFIX_ID="x", NAME_ID="6"), - RegisterOperand(PREFIX_ID="x", NAME_ID="7"), + registerOperand(prefix_id="x", name_id="5"), + registerOperand(prefix_id="x", name_id="6"), + registerOperand(prefix_id="x", name_id="7"), ] 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) @@ -397,22 +397,22 @@ class TestParserAArch64(unittest.TestCase): # self.assertEqual(p_single.operands, reg_list_single) def test_reg_dependency(self): - reg_1_1 = RegisterOperand(PREFIX_ID="b", NAME_ID="1") - reg_1_2 = RegisterOperand(PREFIX_ID="h", NAME_ID="1") - reg_1_3 = RegisterOperand(PREFIX_ID="s", NAME_ID="1") - reg_1_4 = RegisterOperand(PREFIX_ID="d", NAME_ID="1") - reg_1_4 = RegisterOperand(PREFIX_ID="q", NAME_ID="1") - reg_2_1 = RegisterOperand(PREFIX_ID="w", NAME_ID="2") - reg_2_2 = RegisterOperand(PREFIX_ID="x", NAME_ID="2") - reg_v1_1 = RegisterOperand(PREFIX_ID="v", NAME_ID="11", LANES="16", SHAPE="b") - reg_v1_2 = RegisterOperand(PREFIX_ID="v", NAME_ID="11", LANES="8", SHAPE="h") - reg_v1_3 = RegisterOperand(PREFIX_ID="v", NAME_ID="11", LANES="4", SHAPE="s") - reg_v1_4 = RegisterOperand(PREFIX_ID="v", NAME_ID="11", LANES="2", SHAPE="d") + reg_1_1 = registerOperand(prefix_id="b", name_id="1") + reg_1_2 = registerOperand(prefix_id="h", name_id="1") + reg_1_3 = registerOperand(prefix_id="s", name_id="1") + reg_1_4 = registerOperand(prefix_id="d", name_id="1") + reg_1_4 = registerOperand(prefix_id="q", name_id="1") + reg_2_1 = registerOperand(prefix_id="w", name_id="2") + reg_2_2 = registerOperand(prefix_id="x", name_id="2") + reg_v1_1 = registerOperand(prefix_id="v", name_id="11", lanes="16", shape="b") + reg_v1_2 = registerOperand(prefix_id="v", name_id="11", lanes="8", shape="h") + reg_v1_3 = registerOperand(prefix_id="v", name_id="11", lanes="4", shape="s") + reg_v1_4 = registerOperand(prefix_id="v", name_id="11", lanes="2", shape="d") - reg_b5 = RegisterOperand(PREFIX_ID="b", NAME_ID="5") - reg_q15 = RegisterOperand(PREFIX_ID="q", NAME_ID="15") - reg_v10 = RegisterOperand(PREFIX_ID="v", NAME_ID="10", LANES="2", SHAPE="s") - reg_v20 = RegisterOperand(PREFIX_ID="v", NAME_ID="20", LANES="2", SHAPE="d") + reg_b5 = registerOperand(prefix_id="b", name_id="5") + reg_q15 = registerOperand(prefix_id="q", name_id="15") + reg_v10 = registerOperand(prefix_id="v", name_id="10", lanes="2", shape="s") + reg_v20 = registerOperand(prefix_id="v", name_id="20", lanes="2", shape="d") reg_1 = [reg_1_1, reg_1_2, reg_1_3, reg_1_4] reg_2 = [reg_2_1, reg_2_2] diff --git a/tests/test_parser_x86att.py b/tests/test_parser_x86att.py index e62b996..6766e56 100755 --- a/tests/test_parser_x86att.py +++ b/tests/test_parser_x86att.py @@ -8,8 +8,8 @@ import unittest from pyparsing import ParseException -from osaca.parser import ParserX86ATT, InstructionForm -from osaca.parser.register import RegisterOperand +from osaca.parser import ParserX86ATT, instructionForm +from osaca.parser.register import registerOperand class TestParserX86ATT(unittest.TestCase): @@ -165,36 +165,36 @@ class TestParserX86ATT(unittest.TestCase): line_directive = ".quad .2.3_2__kmpc_loc_pack.2 #qed" 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_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_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}, @@ -205,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) @@ -233,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) @@ -259,22 +259,22 @@ class TestParserX86ATT(unittest.TestCase): ) def test_reg_dependency(self): - reg_a1 = RegisterOperand(NAME_ID="rax") - reg_a2 = RegisterOperand(NAME_ID="eax") - reg_a3 = RegisterOperand(NAME_ID="ax") - reg_a4 = RegisterOperand(NAME_ID="al") - reg_r11 = RegisterOperand(NAME_ID="r11") - reg_r11b = RegisterOperand(NAME_ID="r11b") - reg_r11d = RegisterOperand(NAME_ID="r11d") - reg_r11w = RegisterOperand(NAME_ID="r11w") - reg_xmm1 = RegisterOperand(NAME_ID="xmm1") - reg_ymm1 = RegisterOperand(NAME_ID="ymm1") - reg_zmm1 = RegisterOperand(NAME_ID="zmm1") + reg_a1 = registerOperand(name_id="rax") + reg_a2 = registerOperand(name_id="eax") + reg_a3 = registerOperand(name_id="ax") + reg_a4 = registerOperand(name_id="al") + reg_r11 = registerOperand(name_id="r11") + reg_r11b = registerOperand(name_id="r11b") + reg_r11d = registerOperand(name_id="r11d") + reg_r11w = registerOperand(name_id="r11w") + reg_xmm1 = registerOperand(name_id="xmm1") + reg_ymm1 = registerOperand(name_id="ymm1") + reg_zmm1 = registerOperand(name_id="zmm1") - reg_b1 = RegisterOperand(NAME_ID="rbx") - reg_r15 = RegisterOperand(NAME_ID="r15") - reg_xmm2 = RegisterOperand(NAME_ID="xmm2") - reg_ymm3 = RegisterOperand(NAME_ID="ymm3") + reg_b1 = registerOperand(name_id="rbx") + reg_r15 = registerOperand(name_id="r15") + reg_xmm2 = registerOperand(name_id="xmm2") + reg_ymm3 = registerOperand(name_id="ymm3") reg_a = [reg_a1, reg_a2, reg_a3, reg_a4] reg_r = [reg_r11, reg_r11b, reg_r11d, reg_r11w] diff --git a/tests/test_semantics.py b/tests/test_semantics.py index 6df89a5..1653c15 100755 --- a/tests/test_semantics.py +++ b/tests/test_semantics.py @@ -12,16 +12,16 @@ import networkx as nx from osaca.osaca import get_unmatched_instruction_ratio from osaca.parser import AttrDict, ParserAArch64, ParserX86ATT from osaca.semantics import ( - INSTR_FLAGS, + INSTR_flags, ArchSemantics, ISASemantics, KernelDG, MachineModel, reduce_to_section, ) -from osaca.parser.register import RegisterOperand -from osaca.parser.memory import MemoryOperand -from osaca.parser.identifier import IdentifierOperand +from osaca.parser.register import registerOperand +from osaca.parser.memory import memoryOperand +from osaca.parser.identifier import identifierOperand class TestSemanticTools(unittest.TestCase): @@ -148,31 +148,31 @@ class TestSemanticTools(unittest.TestCase): self.assertIsNone(test_mm_arm.get_instruction("NOT_IN_DB", [])) name_x86_1 = "vaddpd" operands_x86_1 = [ - RegisterOperand(NAME_ID="xmm"), - RegisterOperand(NAME_ID="xmm"), - RegisterOperand(NAME_ID="xmm"), + registerOperand(name_id="xmm"), + registerOperand(name_id="xmm"), + registerOperand(name_id="xmm"), ] instr_form_x86_1 = test_mm_x86.get_instruction(name_x86_1, operands_x86_1) self.assertEqual(instr_form_x86_1, test_mm_x86.get_instruction(name_x86_1, operands_x86_1)) self.assertEqual( - test_mm_x86.get_instruction("jg", [IdentifierOperand()]), - test_mm_x86.get_instruction("jg", [IdentifierOperand()]), + test_mm_x86.get_instruction("jg", [identifierOperand()]), + test_mm_x86.get_instruction("jg", [identifierOperand()]), ) name_arm_1 = "fadd" operands_arm_1 = [ - RegisterOperand(PREFIX_ID="v", SHAPE="s"), - RegisterOperand(PREFIX_ID="v", SHAPE="s"), - RegisterOperand(PREFIX_ID="v", SHAPE="s"), + registerOperand(prefix_id="v", shape="s"), + registerOperand(prefix_id="v", shape="s"), + registerOperand(prefix_id="v", shape="s"), ] instr_form_arm_1 = test_mm_arm.get_instruction(name_arm_1, operands_arm_1) self.assertEqual(instr_form_arm_1, test_mm_arm.get_instruction(name_arm_1, operands_arm_1)) self.assertEqual( - test_mm_arm.get_instruction("b.ne", [IdentifierOperand()]), - test_mm_arm.get_instruction("b.ne", [IdentifierOperand()]), + test_mm_arm.get_instruction("b.ne", [identifierOperand()]), + test_mm_arm.get_instruction("b.ne", [identifierOperand()]), ) self.assertEqual( - test_mm_arm.get_instruction("b.someNameThatDoesNotExist", [IdentifierOperand()]), - test_mm_arm.get_instruction("b.someOtherName", [IdentifierOperand()]), + test_mm_arm.get_instruction("b.someNameThatDoesNotExist", [identifierOperand()]), + test_mm_arm.get_instruction("b.someOtherName", [identifierOperand()]), ) # test full instruction name @@ -189,8 +189,8 @@ class TestSemanticTools(unittest.TestCase): # test get_store_tp self.assertEqual( test_mm_x86.get_store_throughput( - MemoryOperand( - BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None, INDEX_ID=None, SCALE_ID=1 + memoryOperand( + base_id=registerOperand(name_id="x"), offset_ID=None, index_id=None, scale_id=1 ) )[0].port_pressure, [[2, "237"], [2, "4"]], @@ -198,11 +198,11 @@ class TestSemanticTools(unittest.TestCase): self.assertEqual( test_mm_x86.get_store_throughput( - MemoryOperand( - BASE_ID=RegisterOperand(PREFIX_ID="NOT_IN_DB"), - OFFSET_ID=None, - INDEX_ID="NOT_NONE", - SCALE_ID=1, + memoryOperand( + base_id=registerOperand(prefix_id="NOT_IN_DB"), + offset_ID=None, + index_id="NOT_NONE", + scale_id=1, ) )[0].port_pressure, [[1, "23"], [1, "4"]], @@ -210,11 +210,11 @@ class TestSemanticTools(unittest.TestCase): self.assertEqual( test_mm_arm.get_store_throughput( - MemoryOperand( - BASE_ID=RegisterOperand(PREFIX_ID="x"), - OFFSET_ID=None, - INDEX_ID=None, - SCALE_ID=1, + memoryOperand( + base_id=registerOperand(prefix_id="x"), + offset_ID=None, + index_id=None, + scale_id=1, ) )[0].port_pressure, [[2, "34"], [2, "5"]], @@ -222,11 +222,11 @@ class TestSemanticTools(unittest.TestCase): self.assertEqual( test_mm_arm.get_store_throughput( - MemoryOperand( - BASE_ID=RegisterOperand(PREFIX_ID="NOT_IN_DB"), - OFFSET_ID=None, - INDEX_ID=None, - SCALE_ID=1, + memoryOperand( + base_id=registerOperand(prefix_id="NOT_IN_DB"), + offset_ID=None, + index_id=None, + scale_id=1, ) )[0].port_pressure, [[1, "34"], [1, "5"]], @@ -234,19 +234,19 @@ class TestSemanticTools(unittest.TestCase): # test get_store_lt self.assertEqual( test_mm_x86.get_store_latency( - MemoryOperand( - BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None, INDEX_ID=None, SCALE_ID=1 + memoryOperand( + base_id=registerOperand(name_id="x"), offset_ID=None, index_id=None, scale_id=1 ) ), 0, ) self.assertEqual( test_mm_arm.get_store_latency( - MemoryOperand( - BASE_ID=RegisterOperand(PREFIX_ID="x"), - OFFSET_ID=None, - INDEX_ID=None, - SCALE_ID=1, + memoryOperand( + base_id=registerOperand(prefix_id="x"), + offset_ID=None, + index_id=None, + scale_id=1, ) ), 0, @@ -258,8 +258,8 @@ class TestSemanticTools(unittest.TestCase): # test default load tp self.assertEqual( test_mm_x86.get_load_throughput( - MemoryOperand( - BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None, INDEX_ID=None, SCALE_ID=1 + memoryOperand( + base_id=registerOperand(name_id="x"), offset_ID=None, index_id=None, scale_id=1 ) )[0].port_pressure, [[1, "23"], [1, ["2D", "3D"]]], @@ -389,7 +389,7 @@ class TestSemanticTools(unittest.TestCase): dg.get_dependent_instruction_forms() # test dot creation dg.export_graph(filepath="/dev/null") - + def test_kernelDG_AArch64(self): dg = KernelDG( self.kernel_AArch64, @@ -421,7 +421,6 @@ class TestSemanticTools(unittest.TestCase): # test dot creation dg.export_graph(filepath="/dev/null") - def test_kernelDG_SVE(self): KernelDG( self.kernel_aarch64_SVE, @@ -446,9 +445,9 @@ class TestSemanticTools(unittest.TestCase): semantics_hld.add_semantics(kernel_hld_2) semantics_hld.add_semantics(kernel_hld_3) - num_hidden_loads = len([x for x in kernel_hld if INSTR_FLAGS.HIDDEN_LD in x.flags]) - num_hidden_loads_2 = len([x for x in kernel_hld_2 if INSTR_FLAGS.HIDDEN_LD in x.flags]) - num_hidden_loads_3 = len([x for x in kernel_hld_3 if INSTR_FLAGS.HIDDEN_LD in x.flags]) + num_hidden_loads = len([x for x in kernel_hld if INSTR_flags.HIDDEN_LD in x.flags]) + num_hidden_loads_2 = len([x for x in kernel_hld_2 if INSTR_flags.HIDDEN_LD in x.flags]) + num_hidden_loads_3 = len([x for x in kernel_hld_3 if INSTR_flags.HIDDEN_LD in x.flags]) self.assertEqual(num_hidden_loads, 1) self.assertEqual(num_hidden_loads_2, 0) self.assertEqual(num_hidden_loads_3, 1) @@ -463,7 +462,6 @@ class TestSemanticTools(unittest.TestCase): with self.assertRaises(NotImplementedError): dg.get_loopcarried_dependencies() - def test_loop_carried_dependency_aarch64(self): dg = KernelDG( self.kernel_aarch64_memdep, @@ -513,7 +511,6 @@ class TestSemanticTools(unittest.TestCase): [(4, 1.0), (5, 1.0), (10, 1.0), (11, 1.0), (12, 1.0)], ) - def test_loop_carried_dependency_x86(self): lcd_id = "8" lcd_id2 = "5" @@ -571,8 +568,8 @@ class TestSemanticTools(unittest.TestCase): def test_is_read_is_written_x86(self): # independent form HW model dag = KernelDG(self.kernel_x86, self.parser_x86, None, None) - reg_rcx = RegisterOperand(NAME_ID="rcx") - reg_ymm1 = RegisterOperand(NAME_ID="ymm1") + reg_rcx = registerOperand(name_id="rcx") + reg_ymm1 = registerOperand(name_id="ymm1") instr_form_r_c = self.parser_x86.parse_line("vmovsd %xmm0, (%r15,%rcx,8)") self.semantics_csx.assign_src_dst(instr_form_r_c) @@ -602,11 +599,11 @@ class TestSemanticTools(unittest.TestCase): def test_is_read_is_written_AArch64(self): # independent form HW model dag = KernelDG(self.kernel_AArch64, self.parser_AArch64, None, None) - reg_x1 = RegisterOperand(PREFIX_ID="x", NAME_ID="1") - reg_w1 = RegisterOperand(PREFIX_ID="w", NAME_ID="1") - reg_d1 = RegisterOperand(PREFIX_ID="d", NAME_ID="1") - reg_q1 = RegisterOperand(PREFIX_ID="q", NAME_ID="1") - reg_v1 = RegisterOperand(PREFIX_ID="v", NAME_ID="1", LANES="2", SHAPE="d") + reg_x1 = registerOperand(prefix_id="x", name_id="1") + reg_w1 = registerOperand(prefix_id="w", name_id="1") + reg_d1 = registerOperand(prefix_id="d", name_id="1") + reg_q1 = registerOperand(prefix_id="q", name_id="1") + reg_v1 = registerOperand(prefix_id="v", name_id="1", lanes="2", shape="d") regs = [reg_d1, reg_q1, reg_v1] regs_gp = [reg_w1, reg_x1] @@ -671,11 +668,11 @@ class TestSemanticTools(unittest.TestCase): def test_MachineModel_getter(self): sample_operands = [ - MemoryOperand( - OFFSET_ID=None, - BASE_ID=RegisterOperand(NAME_ID="r12"), - INDEX_ID=RegisterOperand(NAME_ID="rcx"), - SCALE_ID=8, + memoryOperand( + offset_ID=None, + base_id=registerOperand(name_id="r12"), + index_id=registerOperand(name_id="rcx"), + scale_id=8, ) ] self.assertIsNone(self.machine_model_csx.get_instruction("GETRESULT", sample_operands))