Changed style to conform to PEP-8 conventions; Added source and destination attributes to parent Operand class

This commit is contained in:
stefandesouza
2023-10-29 13:52:49 +01:00
parent 4186edbc03
commit 14a2aa0b52
26 changed files with 876 additions and 916 deletions

View File

@@ -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]

View File

@@ -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

View File

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

View File

@@ -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 = ""

View File

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

View File

@@ -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",

View File

@@ -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):

View File

@@ -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})"

View File

@@ -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})"

View File

@@ -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

View File

@@ -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

View File

@@ -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})"

View File

@@ -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

View File

@@ -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}"

View File

@@ -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"""

View File

@@ -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

View File

@@ -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

View File

@@ -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",

View File

@@ -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):

View File

@@ -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 (

View File

@@ -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):

View File

@@ -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

View File

@@ -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):

View File

@@ -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]

View File

@@ -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]

View File

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