mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2025-12-15 16:40:05 +01:00
Changed style to conform to PEP-8 conventions; Added source and destination attributes to parent Operand class
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = ""
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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})"
|
||||
|
||||
@@ -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})"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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})"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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"""
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user