mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-05 02:30:08 +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
|
.. code:: bash
|
||||||
|
|
||||||
osaca [-h] [-V] [--arch ARCH] [--fixed] [--lines LINES]
|
osaca [-h] [-V] [--arch ARCH] [--fixed] [--lines lineS]
|
||||||
[--ignore-unknown] [--lcd-timeout SECONDS]
|
[--ignore-unknown] [--lcd-timeout SECONDS]
|
||||||
[--db-check] [--import MICROBENCH] [--insert-marker]
|
[--db-check] [--import MICROBENCH] [--insert-marker]
|
||||||
[--export-graph GRAPHNAME] [--consider-flag-deps]
|
[--export-graph GRAPHNAME] [--consider-flag-deps]
|
||||||
|
|||||||
@@ -3363,7 +3363,7 @@ instruction_forms:
|
|||||||
name: "rsp"
|
name: "rsp"
|
||||||
source: true
|
source: true
|
||||||
destination: true
|
destination: true
|
||||||
# All of EFLAGS and RFLAGS, without VM and RF
|
# All of Eflags and Rflags, without VM and RF
|
||||||
- class: "flag"
|
- class: "flag"
|
||||||
name: "CF"
|
name: "CF"
|
||||||
source: true
|
source: true
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ from collections import OrderedDict
|
|||||||
import ruamel.yaml
|
import ruamel.yaml
|
||||||
|
|
||||||
from osaca.semantics import MachineModel
|
from osaca.semantics import MachineModel
|
||||||
from osaca.parser import InstructionForm
|
from osaca.parser import instructionForm
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import memoryOperand
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import registerOperand
|
||||||
from osaca.parser.immediate import ImmediateOperand
|
from osaca.parser.immediate import immediateOperand
|
||||||
|
|
||||||
|
|
||||||
def sanity_check(arch: str, verbose=False, internet_check=False, output_file=sys.stdout):
|
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")
|
entry["throughput"] = _validate_measurement(float(line.split()[1]), "tp")
|
||||||
if not entry["throughput"]:
|
if not entry["throughput"]:
|
||||||
warnings.warn(
|
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."
|
+ " and was not added. Please inspect your benchmark."
|
||||||
)
|
)
|
||||||
elif "LT" in instruction:
|
elif "LT" in instruction:
|
||||||
entry["latency"] = _validate_measurement(float(line.split()[1]), "lt")
|
entry["latency"] = _validate_measurement(float(line.split()[1]), "lt")
|
||||||
if not entry["latency"]:
|
if not entry["latency"]:
|
||||||
warnings.warn(
|
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."
|
+ " and was not added. Please inspect your benchmark."
|
||||||
)
|
)
|
||||||
db_entries[key] = entry
|
db_entries[key] = entry
|
||||||
@@ -436,12 +436,12 @@ def _check_sanity_arch_db(arch_mm, isa_mm, internet_check=True):
|
|||||||
|
|
||||||
# Check operands
|
# Check operands
|
||||||
for operand in instr_form["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
|
operand.name != None or operand.prefix != None
|
||||||
):
|
):
|
||||||
# Missing 'name' key
|
# Missing 'name' key
|
||||||
bad_operand.append(instr_form)
|
bad_operand.append(instr_form)
|
||||||
elif isinstance(operand, MemoryOperand) and (
|
elif isinstance(operand, memoryOperand) and (
|
||||||
operand.base is None
|
operand.base is None
|
||||||
or operand.offset is None
|
or operand.offset is None
|
||||||
or operand.index 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
|
# Missing at least one key necessary for memory operands
|
||||||
bad_operand.append(instr_form)
|
bad_operand.append(instr_form)
|
||||||
elif isinstance(operand, ImmediateOperand) and operand.type == None:
|
elif isinstance(operand, immediateOperand) and operand.type == None:
|
||||||
# Missing 'imd' key
|
# Missing 'imd' key
|
||||||
bad_operand.append(instr_form)
|
bad_operand.append(instr_form)
|
||||||
# every entry exists twice --> uniquify
|
# 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."""
|
"""Get one instruction name string including the mnemonic and all operands."""
|
||||||
operands = []
|
operands = []
|
||||||
for op in instruction_form["operands"]:
|
for op in instruction_form["operands"]:
|
||||||
if isinstance(op, RegisterOperand):
|
if isinstance(op, registerOperand):
|
||||||
op_attrs = []
|
op_attrs = []
|
||||||
if op.name != None:
|
if op.name != None:
|
||||||
op_attrs.append("name:" + op.name)
|
op_attrs.append("name:" + op.name)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
from datetime import datetime as dt
|
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):
|
def _get_version(*file_paths):
|
||||||
@@ -116,7 +116,7 @@ class Frontend(object):
|
|||||||
separator,
|
separator,
|
||||||
instruction_form.latency_cp,
|
instruction_form.latency_cp,
|
||||||
separator,
|
separator,
|
||||||
"X" if INSTR_FLAGS.LT_UNKWN in instruction_form.flags else " ",
|
"X" if INSTR_flags.LT_UNKWN in instruction_form.flags else " ",
|
||||||
separator,
|
separator,
|
||||||
instruction_form.line,
|
instruction_form.line,
|
||||||
)
|
)
|
||||||
@@ -237,7 +237,7 @@ class Frontend(object):
|
|||||||
if lcd_warning:
|
if lcd_warning:
|
||||||
warnings.append("LCDWarning")
|
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")
|
# warnings.append("UnknownInstrWarning")
|
||||||
|
|
||||||
tp_sum = ArchSemantics.get_throughput_sum(kernel) or kernel[0].port_pressure
|
tp_sum = ArchSemantics.get_throughput_sum(kernel) or kernel[0].port_pressure
|
||||||
@@ -373,11 +373,11 @@ class Frontend(object):
|
|||||||
)
|
)
|
||||||
s += "\n"
|
s += "\n"
|
||||||
# check for unknown instructions and throw warning if called without --ignore-unknown
|
# 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
|
flag for instr in kernel for flag in instr.flags
|
||||||
]:
|
]:
|
||||||
num_missing = len(
|
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)
|
s += self._missing_instruction_error(num_missing)
|
||||||
else:
|
else:
|
||||||
@@ -471,9 +471,9 @@ class Frontend(object):
|
|||||||
def _get_flag_symbols(self, flag_obj):
|
def _get_flag_symbols(self, flag_obj):
|
||||||
"""Returns flags for a flag object of an instruction"""
|
"""Returns flags for a flag object of an instruction"""
|
||||||
string_result = ""
|
string_result = ""
|
||||||
string_result += "*" if INSTR_FLAGS.NOT_BOUND 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 += "X" if INSTR_flags.TP_UNKWN in flag_obj else ""
|
||||||
string_result += "P" if INSTR_FLAGS.HIDDEN_LD in flag_obj else ""
|
string_result += "P" if INSTR_flags.HIDDEN_LD in flag_obj else ""
|
||||||
# TODO add other flags
|
# TODO add other flags
|
||||||
string_result += " " if len(string_result) == 0 else ""
|
string_result += " " if len(string_result) == 0 else ""
|
||||||
return string_result
|
return string_result
|
||||||
@@ -554,10 +554,10 @@ class Frontend(object):
|
|||||||
def _symbol_map(self):
|
def _symbol_map(self):
|
||||||
"""Prints instruction flag map."""
|
"""Prints instruction flag map."""
|
||||||
symbol_dict = {
|
symbol_dict = {
|
||||||
INSTR_FLAGS.NOT_BOUND: "Instruction micro-ops not bound to a port",
|
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.TP_UNKWN: "No throughput/latency information for this instruction in "
|
||||||
+ "data file",
|
+ "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",
|
+ "or future STORE instruction",
|
||||||
}
|
}
|
||||||
symbol_map = ""
|
symbol_map = ""
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from osaca.db_interface import import_benchmark_output, sanity_check
|
|||||||
from osaca.frontend import Frontend
|
from osaca.frontend import Frontend
|
||||||
from osaca.parser import BaseParser, ParserAArch64, ParserX86ATT
|
from osaca.parser import BaseParser, ParserAArch64, ParserX86ATT
|
||||||
from osaca.semantics import (
|
from osaca.semantics import (
|
||||||
INSTR_FLAGS,
|
INSTR_flags,
|
||||||
ArchSemantics,
|
ArchSemantics,
|
||||||
KernelDG,
|
KernelDG,
|
||||||
MachineModel,
|
MachineModel,
|
||||||
@@ -430,7 +430,7 @@ def get_unmatched_instruction_ratio(kernel):
|
|||||||
"""Return ratio of unmatched from total instructions in kernel."""
|
"""Return ratio of unmatched from total instructions in kernel."""
|
||||||
unmatched_counter = 0
|
unmatched_counter = 0
|
||||||
for instruction in kernel:
|
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
|
unmatched_counter += 1
|
||||||
return unmatched_counter / len(kernel)
|
return unmatched_counter / len(kernel)
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ from .attr_dict import AttrDict
|
|||||||
from .base_parser import BaseParser
|
from .base_parser import BaseParser
|
||||||
from .parser_x86att import ParserX86ATT
|
from .parser_x86att import ParserX86ATT
|
||||||
from .parser_AArch64 import ParserAArch64
|
from .parser_AArch64 import ParserAArch64
|
||||||
from .instruction_form import InstructionForm
|
from .instruction_form import instructionForm
|
||||||
from .operand import Operand
|
from .operand import Operand
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Operand",
|
"Operand",
|
||||||
"InstructionForm",
|
"instructionForm",
|
||||||
"AttrDict",
|
"AttrDict",
|
||||||
"BaseParser",
|
"BaseParser",
|
||||||
"ParserX86ATT",
|
"ParserX86ATT",
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ import re
|
|||||||
|
|
||||||
class BaseParser(object):
|
class BaseParser(object):
|
||||||
# Identifiers for operand types
|
# Identifiers for operand types
|
||||||
COMMENT_ID = "comment"
|
comment_id = "comment"
|
||||||
DIRECTIVE_ID = "directive"
|
directive_id = "directive"
|
||||||
IMMEDIATE_ID = "immediate"
|
IMMEDIATE_ID = "immediate"
|
||||||
LABEL_ID = "label"
|
label_id = "label"
|
||||||
IDENTIFIER_ID = "identifier"
|
IDENTIFIER_ID = "identifier"
|
||||||
MEMORY_ID = "memory"
|
MEMORY_ID = "memory"
|
||||||
REGISTER_ID = "register"
|
REGISTER_ID = "register"
|
||||||
SEGMENT_EXT_ID = "segment_extension"
|
segment_ext_id = "segment_extension"
|
||||||
INSTRUCTION_ID = "instruction"
|
instruction_id = "instruction"
|
||||||
OPERANDS_ID = "operands"
|
operands_id = "operands"
|
||||||
_parser_constructed = False
|
_parser_constructed = False
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|||||||
@@ -3,49 +3,49 @@
|
|||||||
from osaca.parser.operand import Operand
|
from osaca.parser.operand import Operand
|
||||||
|
|
||||||
|
|
||||||
class DirectiveOperand(Operand):
|
class directiveOperand(Operand):
|
||||||
def __init__(self, NAME_ID=None, PARAMETER_ID=None, COMMENT_ID=None):
|
def __init__(self, name_id=None, parameter_id=None, comment_id=None):
|
||||||
super().__init__(NAME_ID)
|
super().__init__(name_id)
|
||||||
self._PARAMETER_ID = PARAMETER_ID
|
self._parameter_id = parameter_id
|
||||||
self._COMMENT_ID = COMMENT_ID
|
self._comment_id = comment_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parameters(self):
|
def parameters(self):
|
||||||
return self._PARAMETER_ID
|
return self._parameter_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def comment(self):
|
def comment(self):
|
||||||
return self._COMMENT_ID
|
return self._comment_id
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __next__(self):
|
def __next__(self):
|
||||||
if not self._COMMENT_ID:
|
if not self._comment_id:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
return self._COMMENT_ID.pop(0)
|
return self._comment_id.pop(0)
|
||||||
|
|
||||||
@parameters.setter
|
@parameters.setter
|
||||||
def parameters(self, parameters):
|
def parameters(self, parameters):
|
||||||
self._PARAMETER_ID = parameters
|
self._parameter_id = parameters
|
||||||
|
|
||||||
@comment.setter
|
@comment.setter
|
||||||
def comment(self, comment):
|
def comment(self, comment):
|
||||||
self._COMMENT_ID = comment
|
self._comment_id = comment
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if isinstance(other, DirectiveOperand):
|
if isinstance(other, directiveOperand):
|
||||||
return (
|
return (
|
||||||
self._NAME_ID == other._NAME_ID
|
self._name_id == other._name_id
|
||||||
and self._PARAMETER_ID == other._PARAMETER_ID
|
and self._parameter_id == other._parameter_id
|
||||||
and self._COMMENT_ID == other._COMMENT_ID
|
and self._comment_id == other._comment_id
|
||||||
)
|
)
|
||||||
elif isinstance(other, dict):
|
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
|
return False
|
||||||
|
|
||||||
def __str__(self):
|
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):
|
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
|
from osaca.parser.operand import Operand
|
||||||
|
|
||||||
|
|
||||||
class IdentifierOperand(Operand):
|
class identifierOperand(Operand):
|
||||||
def __init__(self, name=None, OFFSET=None, RELOCATION=None):
|
def __init__(self, name=None, offset=None, relocation=None):
|
||||||
super().__init__(name)
|
super().__init__(name)
|
||||||
self._OFFSET = OFFSET
|
self._offset = offset
|
||||||
self._RELOCATION = RELOCATION
|
self._relocation = relocation
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def offset(self):
|
def offset(self):
|
||||||
return self._OFFSET
|
return self._offset
|
||||||
|
|
||||||
@offset.setter
|
@offset.setter
|
||||||
def offset(self, offset):
|
def offset(self, offset):
|
||||||
self._OFFSET = offset
|
self._offset = offset
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def relocation(self):
|
def relocation(self):
|
||||||
return self._RELOCATION
|
return self._relocation
|
||||||
|
|
||||||
@relocation.setter
|
@relocation.setter
|
||||||
def relocation(self, relocation):
|
def relocation(self, relocation):
|
||||||
self._RELOCATION = relocation
|
self._relocation = relocation
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return (
|
return (
|
||||||
f"IdentifierOperand({self.name}, offset={self.offset}, relocation={self.relocation})"
|
f"identifierOperand({self.name}, offset={self.offset}, relocation={self.relocation})"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
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
|
from osaca.parser.operand import Operand
|
||||||
|
|
||||||
|
|
||||||
class ImmediateOperand(Operand):
|
class immediateOperand(Operand):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
IDENTIFIER_ID=None,
|
identifier_id=None,
|
||||||
TYPE_ID=None,
|
type_id=None,
|
||||||
VALUE_ID=None,
|
value_id=None,
|
||||||
SHIFT_ID=None,
|
shift_id=None,
|
||||||
SOURCE=False,
|
source=False,
|
||||||
DESTINATION=False
|
destination=False,
|
||||||
):
|
):
|
||||||
super().__init__(str(VALUE_ID))
|
super().__init__(str(value_id), source, destination)
|
||||||
self._IDENTIFIER_ID = IDENTIFIER_ID
|
self._identifier_id = identifier_id
|
||||||
self._TYPE_ID = TYPE_ID
|
self._type_id = type_id
|
||||||
self._VALUE_ID = VALUE_ID
|
self._value_id = value_id
|
||||||
self._SHIFT_ID = SHIFT_ID
|
self._shift_id = shift_id
|
||||||
self._SOURCE = SOURCE
|
|
||||||
self._DESTINATION = DESTINATION
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self):
|
def identifier(self):
|
||||||
return self._IDENTIFIER_ID
|
return self._identifier_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self):
|
def type(self):
|
||||||
return self._TYPE_ID
|
return self._type_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
return self._VALUE_ID
|
return self._value_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def shift(self):
|
def shift(self):
|
||||||
return self._TYPE_ID
|
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
|
|
||||||
|
|
||||||
@identifier.setter
|
@identifier.setter
|
||||||
def identifier(self, identifier):
|
def identifier(self, identifier):
|
||||||
self._IDENTIFIER_ID = identifier
|
self._identifier_id = identifier
|
||||||
|
|
||||||
@type.setter
|
@type.setter
|
||||||
def type(self, type):
|
def type(self, type):
|
||||||
self._TYPE_ID = type
|
self._type_id = type
|
||||||
|
|
||||||
@value.setter
|
@value.setter
|
||||||
def value(self, value):
|
def value(self, value):
|
||||||
self._VALUE_ID = value
|
self._value_id = value
|
||||||
|
|
||||||
@shift.setter
|
@shift.setter
|
||||||
def index(self, shift):
|
def index(self, shift):
|
||||||
self._SHIFT_ID = shift
|
self._shift_id = shift
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return (
|
return (
|
||||||
f"ImmediateOperand(IDENTIFIER_ID={self._IDENTIFIER_ID}, TYPE_ID={self._TYPE_ID}, "
|
f"immediateOperand(identifier_id={self._identifier_id}, type_id={self._type_id}, "
|
||||||
f"VALUE_ID={self._VALUE_ID}, SHIFT_ID={self._SHIFT_ID})"
|
f"value_id={self._value_id}, shift_id={self._shift_id})"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return (
|
return (
|
||||||
f"ImmediateOperand(IDENTIFIER_ID={self._IDENTIFIER_ID}, TYPE_ID={self._TYPE_ID}, "
|
f"immediateOperand(identifier_id={self._identifier_id}, type_id={self._type_id}, "
|
||||||
f"VALUE_ID={self._VALUE_ID}, SHIFT_ID={self._SHIFT_ID})"
|
f"value_id={self._value_id}, shift_id={self._shift_id})"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if isinstance(other, ImmediateOperand):
|
if isinstance(other, immediateOperand):
|
||||||
return (
|
return (
|
||||||
self._IDENTIFIER_ID == other._IDENTIFIER_ID
|
self._identifier_id == other._identifier_id
|
||||||
and self._TYPE_ID == other._TYPE_ID
|
and self._type_id == other._type_id
|
||||||
and self._VALUE_ID == other._VALUE_ID
|
and self._value_id == other._value_id
|
||||||
and self._SHIFT_ID == other._SHIFT_ID
|
and self._shift_id == other._shift_id
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -1,200 +1,200 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
from osaca.parser.directive import DirectiveOperand
|
from osaca.parser.directive import directiveOperand
|
||||||
|
|
||||||
|
|
||||||
class InstructionForm:
|
class instructionForm:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
INSTRUCTION_ID=None,
|
instruction_id=None,
|
||||||
OPERANDS_ID=[],
|
operands_id=[],
|
||||||
HIDDEN_OPERANDS=[],
|
hidden_operands=[],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID=None,
|
comment_id=None,
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE=None,
|
line=None,
|
||||||
LINE_NUMBER=None,
|
line_number=None,
|
||||||
SEMANTIC_OPERANDS={"source": [], "destination": [], "src_dst": []},
|
semantic_operands={"source": [], "destination": [], "src_dst": []},
|
||||||
THROUGHPUT = None,
|
throughput=None,
|
||||||
LATENCY = None,
|
latency=None,
|
||||||
UOPS = None,
|
uops=None,
|
||||||
PORT_PRESSURE = None,
|
port_pressure=None,
|
||||||
BREAKS_DEP = False
|
breaks_dep=False,
|
||||||
):
|
):
|
||||||
self._INSTRUCTION_ID = INSTRUCTION_ID
|
self._instruction_id = instruction_id
|
||||||
self._OPERANDS_ID = OPERANDS_ID
|
self._operands_id = operands_id
|
||||||
self._HIDDEN_OPERANDS = HIDDEN_OPERANDS
|
self._hidden_operands = hidden_operands
|
||||||
self._DIRECTIVE_ID = DIRECTIVE_ID
|
self._directive_id = directive_id
|
||||||
self._COMMENT_ID = COMMENT_ID
|
self._comment_id = comment_id
|
||||||
self._LABEL_ID = LABEL_ID
|
self._label_id = label_id
|
||||||
self._LINE = LINE
|
self._line = line
|
||||||
self._LINE_NUMBER = LINE_NUMBER
|
self._line_number = line_number
|
||||||
|
|
||||||
self._SEMANTIC_OPERANDS = SEMANTIC_OPERANDS
|
self._semantic_operands = semantic_operands
|
||||||
self._UOPS = UOPS
|
self._uops = uops
|
||||||
self._BREAKS_DEP = BREAKS_DEP
|
self._breaks_dep = breaks_dep
|
||||||
# self.semantic_operands = {"source": [], "destination": [], "src_dst": []}
|
# self.semantic_operands = {"source": [], "destination": [], "src_dst": []}
|
||||||
self._LATENCY = LATENCY
|
self._latency = latency
|
||||||
self._THROUGHPUT = THROUGHPUT
|
self._throughput = throughput
|
||||||
self._LATENCY_CP = []
|
self._latency_cp = []
|
||||||
self._LATENCY_LCD = []
|
self._latency_lcd = []
|
||||||
self._LATENCY_WO_LOAD = None
|
self._latency_wo_load = None
|
||||||
self._PORT_PRESSURE = PORT_PRESSURE
|
self._port_pressure = port_pressure
|
||||||
self._PORT_UOPS = []
|
self._port_uops = []
|
||||||
self._FLAGS = []
|
self._flags = []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def semantic_operands(self):
|
def semantic_operands(self):
|
||||||
return self._SEMANTIC_OPERANDS
|
return self._semantic_operands
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def instruction(self):
|
def instruction(self):
|
||||||
return self._INSTRUCTION_ID
|
return self._instruction_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def label(self):
|
def label(self):
|
||||||
return self._LABEL_ID
|
return self._label_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def comment(self):
|
def comment(self):
|
||||||
return self._COMMENT_ID
|
return self._comment_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def directive(self):
|
def directive(self):
|
||||||
return self._DIRECTIVE_ID
|
return self._directive_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def line_number(self):
|
def line_number(self):
|
||||||
return self._LINE_NUMBER
|
return self._line_number
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def line(self):
|
def line(self):
|
||||||
return self._LINE
|
return self._line
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def operands(self):
|
def operands(self):
|
||||||
return self._OPERANDS_ID
|
return self._operands_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hidden_operands(self):
|
def hidden_operands(self):
|
||||||
return self._HIDDEN_OPERANDS
|
return self._hidden_operands
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def port_pressure(self):
|
def port_pressure(self):
|
||||||
return self._PORT_PRESSURE
|
return self._port_pressure
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def port_uops(self):
|
def port_uops(self):
|
||||||
return self._PORT_UOPS
|
return self._port_uops
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def flags(self):
|
def flags(self):
|
||||||
return self._FLAGS
|
return self._flags
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def uops(self):
|
def uops(self):
|
||||||
return self._UOPS
|
return self._uops
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def throughput(self):
|
def throughput(self):
|
||||||
return self._THROUGHPUT
|
return self._throughput
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def latency(self):
|
def latency(self):
|
||||||
return self._LATENCY
|
return self._latency
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def latency_wo_load(self):
|
def latency_wo_load(self):
|
||||||
return self._LATENCY_WO_LOAD
|
return self._latency_wo_load
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def breaks_dep(self):
|
def breaks_dep(self):
|
||||||
return self._BREAKS_DEP
|
return self._breaks_dep
|
||||||
|
|
||||||
@semantic_operands.setter
|
@semantic_operands.setter
|
||||||
def semantic_operands(self, semantic_operands):
|
def semantic_operands(self, semantic_operands):
|
||||||
self._SEMANTIC_OPERANDS = semantic_operands
|
self._semantic_operands = semantic_operands
|
||||||
|
|
||||||
@directive.setter
|
@directive.setter
|
||||||
def directive(self, directive):
|
def directive(self, directive):
|
||||||
self._DIRECTIVE_ID = directive
|
self._directive_id = directive
|
||||||
|
|
||||||
@line_number.setter
|
@line_number.setter
|
||||||
def line_number(self, line_number):
|
def line_number(self, line_number):
|
||||||
self._LINE_NUMBER = line_number
|
self._line_number = line_number
|
||||||
|
|
||||||
@line.setter
|
@line.setter
|
||||||
def line(self, line):
|
def line(self, line):
|
||||||
self._LINE = line
|
self._line = line
|
||||||
|
|
||||||
@operands.setter
|
@operands.setter
|
||||||
def operands(self, operands):
|
def operands(self, operands):
|
||||||
self._OPERANDS_ID = operands
|
self._operands_id = operands
|
||||||
|
|
||||||
@hidden_operands.setter
|
@hidden_operands.setter
|
||||||
def hidden_operands(self, hidden_operands):
|
def hidden_operands(self, hidden_operands):
|
||||||
self._HIDDEN_OPERANDS = hidden_operands
|
self._hidden_operands = hidden_operands
|
||||||
|
|
||||||
@breaks_dep.setter
|
@breaks_dep.setter
|
||||||
def breaks_dep(self, boolean):
|
def breaks_dep(self, boolean):
|
||||||
self._BREAKS_DEP = boolean
|
self._breaks_dep = boolean
|
||||||
|
|
||||||
@instruction.setter
|
@instruction.setter
|
||||||
def instruction(self, instruction):
|
def instruction(self, instruction):
|
||||||
self._INSTRUCTION_ID = instruction
|
self._instruction_id = instruction
|
||||||
|
|
||||||
@label.setter
|
@label.setter
|
||||||
def label(self, label):
|
def label(self, label):
|
||||||
self._LABEL_ID = label
|
self._label_id = label
|
||||||
|
|
||||||
@comment.setter
|
@comment.setter
|
||||||
def comment(self, comment):
|
def comment(self, comment):
|
||||||
self._COMMENT_ID = comment
|
self._comment_id = comment
|
||||||
|
|
||||||
@port_pressure.setter
|
@port_pressure.setter
|
||||||
def port_pressure(self, port_pressure):
|
def port_pressure(self, port_pressure):
|
||||||
self._PORT_PRESSURE = port_pressure
|
self._port_pressure = port_pressure
|
||||||
|
|
||||||
@port_uops.setter
|
@port_uops.setter
|
||||||
def port_uops(self, port_uops):
|
def port_uops(self, port_uops):
|
||||||
self._PORT_UOPS = port_uops
|
self._port_uops = port_uops
|
||||||
|
|
||||||
@flags.setter
|
@flags.setter
|
||||||
def flags(self, flags):
|
def flags(self, flags):
|
||||||
self._FLAGS = flags
|
self._flags = flags
|
||||||
|
|
||||||
@uops.setter
|
@uops.setter
|
||||||
def uops(self, uops):
|
def uops(self, uops):
|
||||||
self._UOPS = uops
|
self._uops = uops
|
||||||
|
|
||||||
@throughput.setter
|
@throughput.setter
|
||||||
def throughput(self, throughput):
|
def throughput(self, throughput):
|
||||||
self._THROUGHPUT = throughput
|
self._throughput = throughput
|
||||||
|
|
||||||
@latency.setter
|
@latency.setter
|
||||||
def latency(self, latency):
|
def latency(self, latency):
|
||||||
self._LATENCY = latency
|
self._latency = latency
|
||||||
|
|
||||||
@latency_wo_load.setter
|
@latency_wo_load.setter
|
||||||
def latency_wo_load(self, latency_wo_load):
|
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):
|
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):
|
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):
|
def __eq__(self, other):
|
||||||
if isinstance(other, InstructionForm):
|
if isinstance(other, instructionForm):
|
||||||
return (
|
return (
|
||||||
self._INSTRUCTION_ID == other._INSTRUCTION_ID
|
self._instruction_id == other._instruction_id
|
||||||
and self._OPERANDS_ID == other._OPERANDS_ID
|
and self._operands_id == other._operands_id
|
||||||
and self._DIRECTIVE_ID == other._DIRECTIVE_ID
|
and self._directive_id == other._directive_id
|
||||||
and self._COMMENT_ID == other._COMMENT_ID
|
and self._comment_id == other._comment_id
|
||||||
and self._LABEL_ID == other._LABEL_ID
|
and self._label_id == other._label_id
|
||||||
and self._LINE == other._LINE
|
and self._line == other._line
|
||||||
and self._LINE_NUMBER == other._LINE_NUMBER
|
and self._line_number == other._line_number
|
||||||
and self._SEMANTIC_OPERANDS == other._SEMANTIC_OPERANDS
|
and self._semantic_operands == other._semantic_operands
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -3,29 +3,29 @@
|
|||||||
from osaca.parser.operand import Operand
|
from osaca.parser.operand import Operand
|
||||||
|
|
||||||
|
|
||||||
class LabelOperand(Operand):
|
class labelOperand(Operand):
|
||||||
def __init__(self, NAME_ID=None, COMMENT_ID=None):
|
def __init__(self, name_id=None, comment_id=None):
|
||||||
super().__init__(NAME_ID)
|
super().__init__(name_id)
|
||||||
self._COMMENT_ID = COMMENT_ID
|
self._comment_id = comment_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def comment(self):
|
def comment(self):
|
||||||
return self._COMMENT_ID
|
return self._comment_id
|
||||||
|
|
||||||
@comment.setter
|
@comment.setter
|
||||||
def comment(self, comment):
|
def comment(self, comment):
|
||||||
self._COMMENT_ID = comment
|
self._comment_id = comment
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __next__(self):
|
def __next__(self):
|
||||||
if not self._COMMENT_ID:
|
if not self._comment_id:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
return self._COMMENT_ID.pop(0)
|
return self._comment_id.pop(0)
|
||||||
|
|
||||||
def __str__(self):
|
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):
|
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
|
from osaca.parser.operand import Operand
|
||||||
|
|
||||||
|
|
||||||
class MemoryOperand(Operand):
|
class memoryOperand(Operand):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
OFFSET_ID=None,
|
offset_ID=None,
|
||||||
BASE_ID=None,
|
base_id=None,
|
||||||
INDEX_ID=None,
|
index_id=None,
|
||||||
SCALE_ID=1,
|
scale_id=1,
|
||||||
SEGMENT_EXT_ID=None,
|
segment_ext_id=None,
|
||||||
MASK=None,
|
mask=None,
|
||||||
PRE_INDEXED=False,
|
pre_indexed=False,
|
||||||
POST_INDEXED=False,
|
post_indexed=False,
|
||||||
INDEXED_VAL=None,
|
indexed_val=None,
|
||||||
PORT_PRESSURE=[],
|
port_pressure=[],
|
||||||
DST=None,
|
dst=None,
|
||||||
SOURCE=False,
|
source=False,
|
||||||
DESTINATION=False,
|
destination=False,
|
||||||
):
|
):
|
||||||
super().__init__("memory")
|
super().__init__("memory", source, destination)
|
||||||
self._OFFSET_ID = OFFSET_ID
|
self._offset_ID = offset_ID
|
||||||
self._BASE_ID = BASE_ID
|
self._base_id = base_id
|
||||||
self._INDEX_ID = INDEX_ID
|
self._index_id = index_id
|
||||||
self._SCALE_ID = SCALE_ID
|
self._scale_id = scale_id
|
||||||
self._SEGMENT_EXT_ID = SEGMENT_EXT_ID
|
self._segment_ext_id = segment_ext_id
|
||||||
self._MASK = MASK
|
self._mask = mask
|
||||||
self._PRE_INDEXED = PRE_INDEXED
|
self._pre_indexed = pre_indexed
|
||||||
self._POST_INDEXED = POST_INDEXED
|
self._post_indexed = post_indexed
|
||||||
self._INDEXED_VAL = INDEXED_VAL
|
self._indexed_val = indexed_val
|
||||||
self._PORT_PRESSURE = PORT_PRESSURE
|
self._port_pressure = port_pressure
|
||||||
self._DST = DST
|
self._dst = dst
|
||||||
self._SOURCE = SOURCE
|
|
||||||
self._DESTINATION = DESTINATION
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def offset(self):
|
def offset(self):
|
||||||
return self._OFFSET_ID
|
return self._offset_ID
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def immediate(self):
|
def immediate(self):
|
||||||
@@ -45,135 +43,119 @@ class MemoryOperand(Operand):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def base(self):
|
def base(self):
|
||||||
return self._BASE_ID
|
return self._base_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def index(self):
|
def index(self):
|
||||||
return self._INDEX_ID
|
return self._index_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def scale(self):
|
def scale(self):
|
||||||
return self._SCALE_ID
|
return self._scale_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def segment_ext_id(self):
|
def segment_ext_id(self):
|
||||||
return self._SEGMENT_EXT_ID
|
return self._segment_ext_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mask(self):
|
def mask(self):
|
||||||
return self._MASK
|
return self._mask
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pre_indexed(self):
|
def pre_indexed(self):
|
||||||
return self._PRE_INDEXED
|
return self._pre_indexed
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def post_indexed(self):
|
def post_indexed(self):
|
||||||
return self._POST_INDEXED
|
return self._post_indexed
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def indexed_val(self):
|
def indexed_val(self):
|
||||||
return self._INDEXED_VAL
|
return self._indexed_val
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def port_pressure(self):
|
def port_pressure(self):
|
||||||
return self._PORT_PRESSURE
|
return self._port_pressure
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dst(self):
|
def dst(self):
|
||||||
return self._DST
|
return self._dst
|
||||||
|
|
||||||
@dst.setter
|
@dst.setter
|
||||||
def dst(self, dst):
|
def dst(self, dst):
|
||||||
self._DST = dst
|
self._dst = dst
|
||||||
|
|
||||||
@port_pressure.setter
|
@port_pressure.setter
|
||||||
def port_pressure(self, port_pressure):
|
def port_pressure(self, port_pressure):
|
||||||
self._PORT_PRESSURE = port_pressure
|
self._port_pressure = port_pressure
|
||||||
|
|
||||||
@segment_ext_id.setter
|
@segment_ext_id.setter
|
||||||
def segment_ext_id(self, segment):
|
def segment_ext_id(self, segment):
|
||||||
self._SEGMENT_EXT_ID = segment
|
self._segment_ext_id = segment
|
||||||
|
|
||||||
@offset.setter
|
@offset.setter
|
||||||
def offset(self, offset):
|
def offset(self, offset):
|
||||||
self._OFFSET_ID = offset
|
self._offset_ID = offset
|
||||||
|
|
||||||
@base.setter
|
@base.setter
|
||||||
def base(self, base):
|
def base(self, base):
|
||||||
self._BASE_ID = base
|
self._base_id = base
|
||||||
|
|
||||||
@index.setter
|
@index.setter
|
||||||
def index(self, index):
|
def index(self, index):
|
||||||
self._INDEX_ID = index
|
self._index_id = index
|
||||||
|
|
||||||
@scale.setter
|
@scale.setter
|
||||||
def scale(self, scale):
|
def scale(self, scale):
|
||||||
self._SCALE_ID = scale
|
self._scale_id = scale
|
||||||
|
|
||||||
@mask.setter
|
@mask.setter
|
||||||
def mask(self, mask):
|
def mask(self, mask):
|
||||||
self._MASK = mask
|
self._mask = mask
|
||||||
|
|
||||||
@pre_indexed.setter
|
@pre_indexed.setter
|
||||||
def pre_indexed(self, pre_indexed):
|
def pre_indexed(self, pre_indexed):
|
||||||
self._PRE_INDEXED = pre_indexed
|
self._pre_indexed = pre_indexed
|
||||||
|
|
||||||
@post_indexed.setter
|
@post_indexed.setter
|
||||||
def post_indexed(self, post_indexed):
|
def post_indexed(self, post_indexed):
|
||||||
self._POST_INDEXED = post_indexed
|
self._post_indexed = post_indexed
|
||||||
|
|
||||||
@indexed_val.setter
|
@indexed_val.setter
|
||||||
def indexed_val(self, value):
|
def indexed_val(self, value):
|
||||||
self._INDEXED_VAL = 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
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return (
|
return (
|
||||||
f"MemoryOperand(NAME_ID={self._NAME_ID}, OFFSET_ID={self._OFFSET_ID}, "
|
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"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"segment_ext_id={self._segment_ext_id}, mask={self._mask}, "
|
||||||
f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, "
|
f"pre_indexed={self._pre_indexed}, post_indexed={self._post_indexed}, "
|
||||||
f"INDEXED_VAL={self._INDEXED_VAL}, PORT_PRESSURE={self._PORT_PRESSURE}),"
|
f"indexed_val={self._indexed_val}, port_pressure={self._port_pressure}),"
|
||||||
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
|
f"source={self._source}, destination={self._destination})"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return (
|
return (
|
||||||
f"MemoryOperand(NAME_ID={self._NAME_ID}, OFFSET_ID={self._OFFSET_ID}, "
|
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"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"segment_ext_id={self._segment_ext_id}, mask={self._mask}, "
|
||||||
f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, "
|
f"pre_indexed={self._pre_indexed}, post_indexed={self._post_indexed}, "
|
||||||
f"INDEXED_VAL={self._INDEXED_VAL}, PORT_PRESSURE={self._PORT_PRESSURE}),"
|
f"indexed_val={self._indexed_val}, port_pressure={self._port_pressure}),"
|
||||||
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
|
f"source={self._source}, destination={self._destination})"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if isinstance(other, MemoryOperand):
|
if isinstance(other, memoryOperand):
|
||||||
return (
|
return (
|
||||||
self._OFFSET_ID == other._OFFSET_ID
|
self._offset_ID == other._offset_ID
|
||||||
and self._BASE_ID == other._BASE_ID
|
and self._base_id == other._base_id
|
||||||
and self._INDEX_ID == other._INDEX_ID
|
and self._index_id == other._index_id
|
||||||
and self._SCALE_ID == other._SCALE_ID
|
and self._scale_id == other._scale_id
|
||||||
and self._SEGMENT_EXT_ID == other._SEGMENT_EXT_ID
|
and self._segment_ext_id == other._segment_ext_id
|
||||||
and self._MASK == other._MASK
|
and self._mask == other._mask
|
||||||
and self._PRE_INDEXED == other._PRE_INDEXED
|
and self._pre_indexed == other._pre_indexed
|
||||||
and self._POST_INDEXED == other._POST_INDEXED
|
and self._post_indexed == other._post_indexed
|
||||||
and self._INDEXED_VAL == other._INDEXED_VAL
|
and self._indexed_val == other._indexed_val
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -2,19 +2,37 @@
|
|||||||
|
|
||||||
|
|
||||||
class Operand:
|
class Operand:
|
||||||
def __init__(self, NAME_ID):
|
def __init__(self, name_id, source=False, destination=False):
|
||||||
self._NAME_ID = NAME_ID
|
self._name_id = name_id
|
||||||
|
self._source = source
|
||||||
|
self._destination = destination
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
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
|
@name.setter
|
||||||
def name(self, name):
|
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):
|
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):
|
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
|
import pyparsing as pp
|
||||||
|
|
||||||
from osaca.parser import BaseParser
|
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.operand import Operand
|
||||||
from osaca.parser.directive import DirectiveOperand
|
from osaca.parser.directive import directiveOperand
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import memoryOperand
|
||||||
from osaca.parser.label import LabelOperand
|
from osaca.parser.label import labelOperand
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import registerOperand
|
||||||
from osaca.parser.identifier import IdentifierOperand
|
from osaca.parser.identifier import identifierOperand
|
||||||
from osaca.parser.immediate import ImmediateOperand
|
from osaca.parser.immediate import immediateOperand
|
||||||
|
|
||||||
|
|
||||||
class ParserAArch64(BaseParser):
|
class ParserAArch64(BaseParser):
|
||||||
@@ -32,7 +32,7 @@ class ParserAArch64(BaseParser):
|
|||||||
symbol_comment = "//"
|
symbol_comment = "//"
|
||||||
self.comment = pp.Literal(symbol_comment) + pp.Group(
|
self.comment = pp.Literal(symbol_comment) + pp.Group(
|
||||||
pp.ZeroOrMore(pp.Word(pp.printables))
|
pp.ZeroOrMore(pp.Word(pp.printables))
|
||||||
).setResultsName(self.COMMENT_ID)
|
).setResultsName(self.comment_id)
|
||||||
# Define ARM assembly identifier
|
# Define ARM assembly identifier
|
||||||
decimal_number = pp.Combine(
|
decimal_number = pp.Combine(
|
||||||
pp.Optional(pp.Literal("-")) + pp.Word(pp.nums)
|
pp.Optional(pp.Literal("-")) + pp.Word(pp.nums)
|
||||||
@@ -54,7 +54,7 @@ class ParserAArch64(BaseParser):
|
|||||||
# Label
|
# Label
|
||||||
self.label = pp.Group(
|
self.label = pp.Group(
|
||||||
identifier.setResultsName("name") + pp.Literal(":") + pp.Optional(self.comment)
|
identifier.setResultsName("name") + pp.Literal(":") + pp.Optional(self.comment)
|
||||||
).setResultsName(self.LABEL_ID)
|
).setResultsName(self.label_id)
|
||||||
# Directive
|
# Directive
|
||||||
directive_option = pp.Combine(
|
directive_option = pp.Combine(
|
||||||
pp.Word(pp.alphas + "#@.%", exact=1)
|
pp.Word(pp.alphas + "#@.%", exact=1)
|
||||||
@@ -69,7 +69,7 @@ class ParserAArch64(BaseParser):
|
|||||||
+ pp.Word(pp.alphanums + "_").setResultsName("name")
|
+ pp.Word(pp.alphanums + "_").setResultsName("name")
|
||||||
+ (pp.OneOrMore(directive_parameter) ^ commaSeparatedList).setResultsName("parameters")
|
+ (pp.OneOrMore(directive_parameter) ^ commaSeparatedList).setResultsName("parameters")
|
||||||
+ pp.Optional(self.comment)
|
+ pp.Optional(self.comment)
|
||||||
).setResultsName(self.DIRECTIVE_ID)
|
).setResultsName(self.directive_id)
|
||||||
# LLVM-MCA markers
|
# LLVM-MCA markers
|
||||||
self.llvm_markers = pp.Group(
|
self.llvm_markers = pp.Group(
|
||||||
pp.Literal("#")
|
pp.Literal("#")
|
||||||
@@ -78,7 +78,7 @@ class ParserAArch64(BaseParser):
|
|||||||
+ (pp.CaselessLiteral("BEGIN") | pp.CaselessLiteral("END"))
|
+ (pp.CaselessLiteral("BEGIN") | pp.CaselessLiteral("END"))
|
||||||
)
|
)
|
||||||
+ pp.Optional(self.comment)
|
+ pp.Optional(self.comment)
|
||||||
).setResultsName(self.COMMENT_ID)
|
).setResultsName(self.comment_id)
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
# Instructions
|
# Instructions
|
||||||
@@ -260,21 +260,21 @@ class ParserAArch64(BaseParser):
|
|||||||
:type line_number: int, optional
|
:type line_number: int, optional
|
||||||
:return: `dict` -- parsed asm line (comment, label, directive or instruction form)
|
:return: `dict` -- parsed asm line (comment, label, directive or instruction form)
|
||||||
"""
|
"""
|
||||||
instruction_form = InstructionForm(
|
instruction_form = instructionForm(
|
||||||
INSTRUCTION_ID=None,
|
instruction_id=None,
|
||||||
OPERANDS_ID=[],
|
operands_id=[],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID=None,
|
comment_id=None,
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE=line,
|
line=line,
|
||||||
LINE_NUMBER=line_number,
|
line_number=line_number,
|
||||||
)
|
)
|
||||||
result = None
|
result = None
|
||||||
|
|
||||||
# 1. Parse comment
|
# 1. Parse comment
|
||||||
try:
|
try:
|
||||||
result = self.process_operand(self.comment.parseString(line, parseAll=True).asDict())
|
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:
|
except pp.ParseException:
|
||||||
pass
|
pass
|
||||||
# 1.2 check for llvm-mca marker
|
# 1.2 check for llvm-mca marker
|
||||||
@@ -282,7 +282,7 @@ class ParserAArch64(BaseParser):
|
|||||||
result = self.process_operand(
|
result = self.process_operand(
|
||||||
self.llvm_markers.parseString(line, parseAll=True).asDict()
|
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:
|
except pp.ParseException:
|
||||||
pass
|
pass
|
||||||
# 2. Parse label
|
# 2. Parse label
|
||||||
@@ -301,8 +301,8 @@ class ParserAArch64(BaseParser):
|
|||||||
result = self.process_operand(
|
result = self.process_operand(
|
||||||
self.directive.parseString(line, parseAll=True).asDict()
|
self.directive.parseString(line, parseAll=True).asDict()
|
||||||
)
|
)
|
||||||
instruction_form.directive = DirectiveOperand(
|
instruction_form.directive = directiveOperand(
|
||||||
NAME_ID=result.name, PARAMETER_ID=result.parameters
|
name_id=result.name, parameter_id=result.parameters
|
||||||
)
|
)
|
||||||
if result.comment is not None:
|
if result.comment is not None:
|
||||||
instruction_form.comment = " ".join(result.comment)
|
instruction_form.comment = " ".join(result.comment)
|
||||||
@@ -353,10 +353,10 @@ class ParserAArch64(BaseParser):
|
|||||||
if "operand5" in result:
|
if "operand5" in result:
|
||||||
operand = self.process_operand(result["operand5"])
|
operand = self.process_operand(result["operand5"])
|
||||||
operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
|
operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
|
||||||
return_dict = InstructionForm(
|
return_dict = instructionForm(
|
||||||
INSTRUCTION_ID=result["mnemonic"],
|
instruction_id=result["mnemonic"],
|
||||||
OPERANDS_ID=operands,
|
operands_id=operands,
|
||||||
COMMENT_ID=" ".join(result[self.COMMENT_ID]) if self.COMMENT_ID in result else None,
|
comment_id=" ".join(result[self.comment_id]) if self.comment_id in result else None,
|
||||||
)
|
)
|
||||||
return return_dict
|
return return_dict
|
||||||
|
|
||||||
@@ -376,30 +376,30 @@ class ParserAArch64(BaseParser):
|
|||||||
# add value attribute to floating point immediates without exponent
|
# add value attribute to floating point immediates without exponent
|
||||||
if self.IMMEDIATE_ID in operand:
|
if self.IMMEDIATE_ID in operand:
|
||||||
return self.process_immediate(operand[self.IMMEDIATE_ID])
|
return self.process_immediate(operand[self.IMMEDIATE_ID])
|
||||||
if self.LABEL_ID in operand:
|
if self.label_id in operand:
|
||||||
return self.process_label(operand[self.LABEL_ID])
|
return self.process_label(operand[self.label_id])
|
||||||
if self.IDENTIFIER_ID in operand:
|
if self.IDENTIFIER_ID in operand:
|
||||||
return self.process_identifier(operand[self.IDENTIFIER_ID])
|
return self.process_identifier(operand[self.IDENTIFIER_ID])
|
||||||
if self.REGISTER_ID in operand:
|
if self.REGISTER_ID in operand:
|
||||||
return self.process_register_operand(operand[self.REGISTER_ID])
|
return self.process_register_operand(operand[self.REGISTER_ID])
|
||||||
if self.DIRECTIVE_ID in operand:
|
if self.directive_id in operand:
|
||||||
return DirectiveOperand(
|
return directiveOperand(
|
||||||
NAME_ID=operand["directive"]["name"],
|
name_id=operand["directive"]["name"],
|
||||||
PARAMETER_ID=operand["directive"]["parameters"],
|
parameter_id=operand["directive"]["parameters"],
|
||||||
COMMENT_ID=operand["directive"]["comment"]
|
comment_id=operand["directive"]["comment"]
|
||||||
if "comment" in operand["directive"]
|
if "comment" in operand["directive"]
|
||||||
else None,
|
else None,
|
||||||
)
|
)
|
||||||
return operand
|
return operand
|
||||||
|
|
||||||
def process_register_operand(self, operand):
|
def process_register_operand(self, operand):
|
||||||
return RegisterOperand(
|
return registerOperand(
|
||||||
PREFIX_ID=operand["prefix"],
|
prefix_id=operand["prefix"],
|
||||||
NAME_ID=operand["name"],
|
name_id=operand["name"],
|
||||||
SHAPE=operand["shape"] if "shape" in operand else None,
|
shape=operand["shape"] if "shape" in operand else None,
|
||||||
LANES=operand["lanes"] if "lanes" in operand else None,
|
lanes=operand["lanes"] if "lanes" in operand else None,
|
||||||
INDEX=operand["index"] if "index" in operand else None,
|
index=operand["index"] if "index" in operand else None,
|
||||||
PREDICATION=operand["predication"] if "predication" in operand else None,
|
predication=operand["predication"] if "predication" in operand else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def process_memory_address(self, memory_address):
|
def process_memory_address(self, memory_address):
|
||||||
@@ -422,11 +422,11 @@ class ParserAArch64(BaseParser):
|
|||||||
if "shift" in memory_address["index"]:
|
if "shift" in memory_address["index"]:
|
||||||
if memory_address["index"]["shift_op"].lower() in valid_shift_ops:
|
if memory_address["index"]["shift_op"].lower() in valid_shift_ops:
|
||||||
scale = 2 ** int(memory_address["index"]["shift"][0]["value"])
|
scale = 2 ** int(memory_address["index"]["shift"][0]["value"])
|
||||||
new_dict = MemoryOperand(
|
new_dict = memoryOperand(
|
||||||
OFFSET_ID=offset,
|
offset_ID=offset,
|
||||||
BASE_ID=RegisterOperand(NAME_ID=base["name"], PREFIX_ID=base["prefix"]),
|
base_id=registerOperand(name_id=base["name"], prefix_id=base["prefix"]),
|
||||||
INDEX_ID=index,
|
index_id=index,
|
||||||
SCALE_ID=scale,
|
scale_id=scale,
|
||||||
)
|
)
|
||||||
if "pre_indexed" in memory_address:
|
if "pre_indexed" in memory_address:
|
||||||
new_dict.pre_indexed = True
|
new_dict.pre_indexed = True
|
||||||
@@ -440,7 +440,7 @@ class ParserAArch64(BaseParser):
|
|||||||
def process_sp_register(self, register):
|
def process_sp_register(self, register):
|
||||||
"""Post-process stack pointer register"""
|
"""Post-process stack pointer register"""
|
||||||
# reg = register
|
# reg = register
|
||||||
new_reg = RegisterOperand(PREFIX_ID="x", NAME_ID="sp")
|
new_reg = registerOperand(prefix_id="x", name_id="sp")
|
||||||
# reg["prefix"] = "x"
|
# reg["prefix"] = "x"
|
||||||
return new_reg
|
return new_reg
|
||||||
|
|
||||||
@@ -509,7 +509,7 @@ class ParserAArch64(BaseParser):
|
|||||||
immediate["type"] = "int"
|
immediate["type"] = "int"
|
||||||
# convert hex/bin immediates to dec
|
# convert hex/bin immediates to dec
|
||||||
immediate["value"] = self.normalize_imd(immediate)
|
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:
|
if "base_immediate" in immediate:
|
||||||
# arithmetic immediate, add calculated value as value
|
# arithmetic immediate, add calculated value as value
|
||||||
immediate["shift"] = immediate["shift"][0]
|
immediate["shift"] = immediate["shift"][0]
|
||||||
@@ -517,8 +517,8 @@ class ParserAArch64(BaseParser):
|
|||||||
immediate["shift"]["value"]
|
immediate["shift"]["value"]
|
||||||
)
|
)
|
||||||
immediate["type"] = "int"
|
immediate["type"] = "int"
|
||||||
return ImmediateOperand(
|
return immediateOperand(
|
||||||
TYPE_ID=immediate["type"], VALUE_ID=immediate["value"], SHIFT_ID=immediate["shift"]
|
type_id=immediate["type"], value_id=immediate["value"], shift_id=immediate["shift"]
|
||||||
)
|
)
|
||||||
if "float" in immediate:
|
if "float" in immediate:
|
||||||
dict_name = "float"
|
dict_name = "float"
|
||||||
@@ -526,18 +526,18 @@ class ParserAArch64(BaseParser):
|
|||||||
dict_name = "double"
|
dict_name = "double"
|
||||||
if "exponent" in immediate[dict_name]:
|
if "exponent" in immediate[dict_name]:
|
||||||
immediate["type"] = dict_name
|
immediate["type"] = dict_name
|
||||||
return ImmediateOperand(TYPE_ID=immediate["type"])
|
return immediateOperand(type_id=immediate["type"])
|
||||||
else:
|
else:
|
||||||
# change 'mantissa' key to 'value'
|
# 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):
|
def process_label(self, label):
|
||||||
"""Post-process label asm line"""
|
"""Post-process label asm line"""
|
||||||
# remove duplicated 'name' level due to identifier
|
# remove duplicated 'name' level due to identifier
|
||||||
# label["name"] = label["name"]["name"]
|
# label["name"] = label["name"]["name"]
|
||||||
new_label = LabelOperand(
|
new_label = labelOperand(
|
||||||
NAME_ID=label["name"]["name"],
|
name_id=label["name"]["name"],
|
||||||
COMMENT_ID=label["comment"] if self.COMMENT_ID in label else None,
|
comment_id=label["comment"] if self.comment_id in label else None,
|
||||||
)
|
)
|
||||||
return new_label
|
return new_label
|
||||||
|
|
||||||
@@ -546,7 +546,7 @@ class ParserAArch64(BaseParser):
|
|||||||
# remove value if it consists of symbol+offset
|
# remove value if it consists of symbol+offset
|
||||||
if "value" in identifier:
|
if "value" in identifier:
|
||||||
del identifier["value"]
|
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):
|
def get_full_reg_name(self, register):
|
||||||
"""Return one register name string including all attributes"""
|
"""Return one register name string including all attributes"""
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ import re
|
|||||||
import pyparsing as pp
|
import pyparsing as pp
|
||||||
|
|
||||||
from osaca.parser import BaseParser
|
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.operand import Operand
|
||||||
from osaca.parser.directive import DirectiveOperand
|
from osaca.parser.directive import directiveOperand
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import memoryOperand
|
||||||
from osaca.parser.label import LabelOperand
|
from osaca.parser.label import labelOperand
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import registerOperand
|
||||||
from osaca.parser.identifier import IdentifierOperand
|
from osaca.parser.identifier import identifierOperand
|
||||||
from osaca.parser.immediate import ImmediateOperand
|
from osaca.parser.immediate import immediateOperand
|
||||||
|
|
||||||
|
|
||||||
class ParserX86ATT(BaseParser):
|
class ParserX86ATT(BaseParser):
|
||||||
@@ -40,7 +40,7 @@ class ParserX86ATT(BaseParser):
|
|||||||
# Comment - either '#' or '//' (icc)
|
# Comment - either '#' or '//' (icc)
|
||||||
self.comment = (pp.Literal("#") | pp.Literal("//")) + pp.Group(
|
self.comment = (pp.Literal("#") | pp.Literal("//")) + pp.Group(
|
||||||
pp.ZeroOrMore(pp.Word(pp.printables))
|
pp.ZeroOrMore(pp.Word(pp.printables))
|
||||||
).setResultsName(self.COMMENT_ID)
|
).setResultsName(self.comment_id)
|
||||||
# Define x86 assembly identifier
|
# Define x86 assembly identifier
|
||||||
relocation = pp.Combine(pp.Literal("@") + pp.Word(pp.alphas))
|
relocation = pp.Combine(pp.Literal("@") + pp.Word(pp.alphas))
|
||||||
id_offset = pp.Word(pp.nums) + pp.Suppress(pp.Literal("+"))
|
id_offset = pp.Word(pp.nums) + pp.Suppress(pp.Literal("+"))
|
||||||
@@ -72,7 +72,7 @@ class ParserX86ATT(BaseParser):
|
|||||||
(label_identifier | numeric_identifier).setResultsName("name")
|
(label_identifier | numeric_identifier).setResultsName("name")
|
||||||
+ pp.Literal(":")
|
+ pp.Literal(":")
|
||||||
+ pp.Optional(self.comment)
|
+ pp.Optional(self.comment)
|
||||||
).setResultsName(self.LABEL_ID)
|
).setResultsName(self.label_id)
|
||||||
# Register: pp.Regex('^%[0-9a-zA-Z]+{}{z},?')
|
# Register: pp.Regex('^%[0-9a-zA-Z]+{}{z},?')
|
||||||
self.register = pp.Group(
|
self.register = pp.Group(
|
||||||
pp.Literal("%")
|
pp.Literal("%")
|
||||||
@@ -120,7 +120,7 @@ class ParserX86ATT(BaseParser):
|
|||||||
pp.Optional(pp.Suppress(pp.Literal("*")))
|
pp.Optional(pp.Suppress(pp.Literal("*")))
|
||||||
+ self.register.setResultsName("base")
|
+ self.register.setResultsName("base")
|
||||||
+ pp.Literal(":")
|
+ 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: offset | seg:seg_ext | offset(base, index, scale){mask}
|
||||||
memory_abs = pp.Suppress(pp.Literal("*")) + (offset | self.register).setResultsName(
|
memory_abs = pp.Suppress(pp.Literal("*")) + (offset | self.register).setResultsName(
|
||||||
@@ -165,7 +165,7 @@ class ParserX86ATT(BaseParser):
|
|||||||
+ pp.Word(pp.alphanums + "_").setResultsName("name")
|
+ pp.Word(pp.alphanums + "_").setResultsName("name")
|
||||||
+ pp.ZeroOrMore(directive_parameter).setResultsName("parameters")
|
+ pp.ZeroOrMore(directive_parameter).setResultsName("parameters")
|
||||||
+ pp.Optional(self.comment)
|
+ pp.Optional(self.comment)
|
||||||
).setResultsName(self.DIRECTIVE_ID)
|
).setResultsName(self.directive_id)
|
||||||
|
|
||||||
# Instructions
|
# Instructions
|
||||||
# Mnemonic
|
# Mnemonic
|
||||||
@@ -207,13 +207,13 @@ class ParserX86ATT(BaseParser):
|
|||||||
:type line_number: int, optional
|
:type line_number: int, optional
|
||||||
:return: ``dict`` -- parsed asm line (comment, label, directive or instruction form)
|
: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
|
result = None
|
||||||
|
|
||||||
# 1. Parse comment
|
# 1. Parse comment
|
||||||
try:
|
try:
|
||||||
result = self.process_operand(self.comment.parseString(line, parseAll=True).asDict())
|
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:
|
except pp.ParseException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -233,9 +233,9 @@ class ParserX86ATT(BaseParser):
|
|||||||
result = self.process_operand(
|
result = self.process_operand(
|
||||||
self.directive.parseString(line, parseAll=True).asDict()
|
self.directive.parseString(line, parseAll=True).asDict()
|
||||||
)
|
)
|
||||||
instruction_form.directive = DirectiveOperand(
|
instruction_form.directive = directiveOperand(
|
||||||
NAME_ID=result.name,
|
name_id=result.name,
|
||||||
PARAMETER_ID=result.parameters,
|
parameter_id=result.parameters,
|
||||||
)
|
)
|
||||||
|
|
||||||
if result.comment != None:
|
if result.comment != None:
|
||||||
@@ -279,10 +279,10 @@ class ParserX86ATT(BaseParser):
|
|||||||
# Check fourth operand
|
# Check fourth operand
|
||||||
if "operand4" in result:
|
if "operand4" in result:
|
||||||
operands.append(self.process_operand(result["operand4"]))
|
operands.append(self.process_operand(result["operand4"]))
|
||||||
return_dict = InstructionForm(
|
return_dict = instructionForm(
|
||||||
INSTRUCTION_ID=result["mnemonic"].split(",")[0],
|
instruction_id=result["mnemonic"].split(",")[0],
|
||||||
OPERANDS_ID=operands,
|
operands_id=operands,
|
||||||
COMMENT_ID=" ".join(result[self.COMMENT_ID]) if self.COMMENT_ID in result else None,
|
comment_id=" ".join(result[self.comment_id]) if self.comment_id in result else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
return return_dict
|
return return_dict
|
||||||
@@ -294,27 +294,27 @@ class ParserX86ATT(BaseParser):
|
|||||||
return self.process_memory_address(operand[self.MEMORY_ID])
|
return self.process_memory_address(operand[self.MEMORY_ID])
|
||||||
if self.IMMEDIATE_ID in operand:
|
if self.IMMEDIATE_ID in operand:
|
||||||
return self.process_immediate(operand[self.IMMEDIATE_ID])
|
return self.process_immediate(operand[self.IMMEDIATE_ID])
|
||||||
if self.LABEL_ID in operand:
|
if self.label_id in operand:
|
||||||
return self.process_label(operand[self.LABEL_ID])
|
return self.process_label(operand[self.label_id])
|
||||||
if self.DIRECTIVE_ID in operand:
|
if self.directive_id in operand:
|
||||||
return self.process_directive(operand[self.DIRECTIVE_ID])
|
return self.process_directive(operand[self.directive_id])
|
||||||
if self.REGISTER_ID in operand:
|
if self.REGISTER_ID in operand:
|
||||||
return RegisterOperand(
|
return registerOperand(
|
||||||
PREFIX_ID=operand["register"]["prefix"]
|
prefix_id=operand["register"]["prefix"]
|
||||||
if "prefix" in operand["register"]
|
if "prefix" in operand["register"]
|
||||||
else None,
|
else None,
|
||||||
NAME_ID=operand["register"]["name"],
|
name_id=operand["register"]["name"],
|
||||||
SHAPE=operand["register"]["shape"] if "shape" in operand["register"] else None,
|
shape=operand["register"]["shape"] if "shape" in operand["register"] else None,
|
||||||
LANES=operand["register"]["lanes"] if "lanes" 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,
|
index=operand["register"]["index"] if "index" in operand["register"] else None,
|
||||||
PREDICATION=operand["register"]["predication"]
|
predication=operand["register"]["predication"]
|
||||||
if "predication" in operand["register"]
|
if "predication" in operand["register"]
|
||||||
else None,
|
else None,
|
||||||
)
|
)
|
||||||
return operand
|
return operand
|
||||||
|
|
||||||
def process_directive(self, directive):
|
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:
|
if "parameters" in directive:
|
||||||
directive_new.parameters = directive["parameters"]
|
directive_new.parameters = directive["parameters"]
|
||||||
if "comment" in directive:
|
if "comment" in directive:
|
||||||
@@ -338,27 +338,27 @@ class ParserX86ATT(BaseParser):
|
|||||||
elif offset is not None and "value" in offset:
|
elif offset is not None and "value" in offset:
|
||||||
offset["value"] = int(offset["value"], 0)
|
offset["value"] = int(offset["value"], 0)
|
||||||
if base != None:
|
if base != None:
|
||||||
baseOp = RegisterOperand(
|
baseOp = registerOperand(
|
||||||
NAME_ID=base["name"], PREFIX_ID=base["prefix"] if "prefix" in base else None
|
name_id=base["name"], prefix_id=base["prefix"] if "prefix" in base else None
|
||||||
)
|
)
|
||||||
if index != None:
|
if index != None:
|
||||||
indexOp = RegisterOperand(
|
indexOp = registerOperand(
|
||||||
NAME_ID=index["name"], PREFIX_ID=index["prefix"] if "prefix" in index else None
|
name_id=index["name"], prefix_id=index["prefix"] if "prefix" in index else None
|
||||||
)
|
)
|
||||||
new_dict = MemoryOperand(
|
new_dict = memoryOperand(
|
||||||
OFFSET_ID=offset, BASE_ID=baseOp, INDEX_ID=indexOp, SCALE_ID=scale
|
offset_ID=offset, base_id=baseOp, index_id=indexOp, scale_id=scale
|
||||||
)
|
)
|
||||||
# Add segmentation extension if existing
|
# Add segmentation extension if existing
|
||||||
if self.SEGMENT_EXT_ID in memory_address:
|
if self.segment_ext_id in memory_address:
|
||||||
new_dict.segment_ext_id = memory_address[self.SEGMENT_EXT_ID]
|
new_dict.segment_ext_id = memory_address[self.segment_ext_id]
|
||||||
return new_dict
|
return new_dict
|
||||||
|
|
||||||
def process_label(self, label):
|
def process_label(self, label):
|
||||||
"""Post-process label asm line"""
|
"""Post-process label asm line"""
|
||||||
# remove duplicated 'name' level due to identifier
|
# remove duplicated 'name' level due to identifier
|
||||||
label["name"] = label["name"][0]["name"]
|
label["name"] = label["name"][0]["name"]
|
||||||
new_label = LabelOperand(
|
new_label = labelOperand(
|
||||||
NAME_ID=label["name"], COMMENT_ID=label["comment"] if "comment" in label else None
|
name_id=label["name"], comment_id=label["comment"] if "comment" in label else None
|
||||||
)
|
)
|
||||||
return new_label
|
return new_label
|
||||||
|
|
||||||
|
|||||||
@@ -3,163 +3,143 @@
|
|||||||
from osaca.parser.operand import Operand
|
from osaca.parser.operand import Operand
|
||||||
|
|
||||||
|
|
||||||
class RegisterOperand(Operand):
|
class registerOperand(Operand):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
NAME_ID=None,
|
name_id=None,
|
||||||
WIDTH_ID=None,
|
width_id=None,
|
||||||
PREFIX_ID=None,
|
prefix_id=None,
|
||||||
REG_ID=None,
|
reg_id=None,
|
||||||
REGTYPE_ID=None,
|
regtype_id=None,
|
||||||
LANES=None,
|
lanes=None,
|
||||||
SHAPE=None,
|
shape=None,
|
||||||
INDEX=None,
|
index=None,
|
||||||
MASK=False,
|
mask=False,
|
||||||
ZEROING=False,
|
zeroing=False,
|
||||||
PREDICATION=None,
|
predication=None,
|
||||||
SOURCE=False,
|
source=False,
|
||||||
DESTINATION=False,
|
destination=False,
|
||||||
):
|
):
|
||||||
super().__init__(NAME_ID)
|
super().__init__(name_id, source, destination)
|
||||||
self._WIDTH_ID = WIDTH_ID
|
self._width_id = width_id
|
||||||
self._PREFIX_ID = PREFIX_ID
|
self._prefix_id = prefix_id
|
||||||
self._REG_ID = REG_ID
|
self._reg_id = reg_id
|
||||||
self._REGTYPE_ID = REGTYPE_ID
|
self._regtype_id = regtype_id
|
||||||
self._LANES = LANES
|
self._lanes = lanes
|
||||||
self._SHAPE = SHAPE
|
self._shape = shape
|
||||||
self._INDEX = INDEX
|
self._index = index
|
||||||
self._MASK = MASK
|
self._mask = mask
|
||||||
self._ZEROING = ZEROING
|
self._zeroing = zeroing
|
||||||
self._PREDICATION = PREDICATION
|
self._predication = predication
|
||||||
self._SOURCE = SOURCE
|
|
||||||
self._DESTINATION = DESTINATION
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def width(self):
|
def width(self):
|
||||||
return self._WIDTH_ID
|
return self._width_id
|
||||||
|
|
||||||
@width.setter
|
@width.setter
|
||||||
def width(self, width):
|
def width(self, width):
|
||||||
self._WIDTH_ID = width
|
self._width_id = width
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def predication(self):
|
def predication(self):
|
||||||
return self._PREDICATION
|
return self._predication
|
||||||
|
|
||||||
@predication.setter
|
@predication.setter
|
||||||
def predication(self, predication):
|
def predication(self, predication):
|
||||||
self._PREDICATION = predication
|
self._predication = predication
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def regtype(self):
|
def regtype(self):
|
||||||
return self._REGTYPE_ID
|
return self._regtype_id
|
||||||
|
|
||||||
@regtype.setter
|
@regtype.setter
|
||||||
def regtype(self, regtype):
|
def regtype(self, regtype):
|
||||||
self._REGTYPE_ID = regtype
|
self._regtype_id = regtype
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def prefix(self):
|
def prefix(self):
|
||||||
return self._PREFIX_ID
|
return self._prefix_id
|
||||||
|
|
||||||
@prefix.setter
|
@prefix.setter
|
||||||
def prefix(self, prefix):
|
def prefix(self, prefix):
|
||||||
self._PREFIX = prefix
|
self._prefix = prefix
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def reg_id(self):
|
def reg_id(self):
|
||||||
return self._REG_ID
|
return self._reg_id
|
||||||
|
|
||||||
@reg_id.setter
|
@reg_id.setter
|
||||||
def reg_id(self, reg_id):
|
def reg_id(self, reg_id):
|
||||||
self._REG_ID = reg_id
|
self._reg_id = reg_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def lanes(self):
|
def lanes(self):
|
||||||
return self._LANES
|
return self._lanes
|
||||||
|
|
||||||
@lanes.setter
|
@lanes.setter
|
||||||
def lanes(self, lanes):
|
def lanes(self, lanes):
|
||||||
self._LANES = lanes
|
self._lanes = lanes
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def shape(self):
|
def shape(self):
|
||||||
return self._SHAPE
|
return self._shape
|
||||||
|
|
||||||
@shape.setter
|
@shape.setter
|
||||||
def shape(self, shape):
|
def shape(self, shape):
|
||||||
self._SHAPE = shape
|
self._shape = shape
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def index(self):
|
def index(self):
|
||||||
return self._INDEX
|
return self._index
|
||||||
|
|
||||||
@index.setter
|
@index.setter
|
||||||
def index(self, index):
|
def index(self, index):
|
||||||
self._INDEX = index
|
self._index = index
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mask(self):
|
def mask(self):
|
||||||
return self._MASK
|
return self._mask
|
||||||
|
|
||||||
@mask.setter
|
@mask.setter
|
||||||
def mask(self, mask):
|
def mask(self, mask):
|
||||||
self._MASK = mask
|
self._mask = mask
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def zeroing(self):
|
def zeroing(self):
|
||||||
return self._ZEROING
|
return self._zeroing
|
||||||
|
|
||||||
@zeroing.setter
|
@zeroing.setter
|
||||||
def zeroing(self, zeroing):
|
def zeroing(self, zeroing):
|
||||||
self._ZEROING = 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
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return (
|
return (
|
||||||
f"RegisterOperand(NAME_ID={self._NAME_ID}, WIDTH_ID={self._WIDTH_ID}, "
|
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"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"lanes={self._lanes}, shape={self._shape}, index={self._index}, "
|
||||||
f"MASK={self._MASK}, ZEROING={self._ZEROING}),"
|
f"mask={self._mask}, zeroing={self._zeroing})"
|
||||||
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return (
|
return (
|
||||||
f"RegisterOperand(NAME_ID={self._NAME_ID}, WIDTH_ID={self._WIDTH_ID}, "
|
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"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"lanes={self._lanes}, shape={self._shape}, index={self._index}, "
|
||||||
f"MASK={self._MASK}, ZEROING={self._ZEROING}),"
|
f"mask={self._mask}, zeroing={self._zeroing})"
|
||||||
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if isinstance(other, RegisterOperand):
|
if isinstance(other, registerOperand):
|
||||||
return (
|
return (
|
||||||
self._NAME_ID == other._NAME_ID
|
self._name_id == other._name_id
|
||||||
and self._WIDTH_ID == other._WIDTH_ID
|
and self._width_id == other._width_id
|
||||||
and self._PREFIX_ID == other._PREFIX_ID
|
and self._prefix_id == other._prefix_id
|
||||||
and self._REG_ID == other._REG_ID
|
and self._reg_id == other._reg_id
|
||||||
and self._REGTYPE_ID == other._REGTYPE_ID
|
and self._regtype_id == other._regtype_id
|
||||||
and self._LANES == other._LANES
|
and self._lanes == other._lanes
|
||||||
and self._SHAPE == other._SHAPE
|
and self._shape == other._shape
|
||||||
and self._INDEX == other._INDEX
|
and self._index == other._index
|
||||||
and self._MASK == other._MASK
|
and self._mask == other._mask
|
||||||
and self._ZEROING == other._ZEROING
|
and self._zeroing == other._zeroing
|
||||||
)
|
)
|
||||||
return False
|
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__.
|
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 .arch_semantics import ArchSemantics
|
||||||
from .hw_model import MachineModel
|
from .hw_model import MachineModel
|
||||||
from .kernel_dg import KernelDG
|
from .kernel_dg import KernelDG
|
||||||
@@ -16,7 +16,7 @@ __all__ = [
|
|||||||
"reduce_to_section",
|
"reduce_to_section",
|
||||||
"ArchSemantics",
|
"ArchSemantics",
|
||||||
"ISASemantics",
|
"ISASemantics",
|
||||||
"INSTR_FLAGS",
|
"INSTR_flags",
|
||||||
"find_basic_blocks",
|
"find_basic_blocks",
|
||||||
"find_basic_loop_bodies",
|
"find_basic_loop_bodies",
|
||||||
"find_jump_labels",
|
"find_jump_labels",
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ from operator import itemgetter
|
|||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
from .hw_model import MachineModel
|
from .hw_model import MachineModel
|
||||||
from .isa_semantics import INSTR_FLAGS, ISASemantics
|
from .isa_semantics import INSTR_flags, ISASemantics
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import memoryOperand
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import registerOperand
|
||||||
from osaca.parser.immediate import ImmediateOperand
|
from osaca.parser.immediate import immediateOperand
|
||||||
from osaca.parser.identifier import IdentifierOperand
|
from osaca.parser.identifier import identifierOperand
|
||||||
|
|
||||||
|
|
||||||
class ArchSemantics(ISASemantics):
|
class ArchSemantics(ISASemantics):
|
||||||
@@ -139,8 +139,8 @@ class ArchSemantics(ISASemantics):
|
|||||||
|
|
||||||
def set_hidden_loads(self, kernel):
|
def set_hidden_loads(self, kernel):
|
||||||
"""Hide loads behind stores if architecture supports hidden loads (depricated)"""
|
"""Hide loads behind stores if architecture supports hidden loads (depricated)"""
|
||||||
loads = [instr for instr in kernel if INSTR_FLAGS.HAS_LD 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]
|
stores = [instr for instr in kernel if INSTR_flags.HAS_ST in instr.flags]
|
||||||
# Filter instructions including load and store
|
# Filter instructions including load and store
|
||||||
load_ids = [instr.line_number for instr in loads]
|
load_ids = [instr.line_number for instr in loads]
|
||||||
store_ids = [instr.line_number for instr in stores]
|
store_ids = [instr.line_number for instr in stores]
|
||||||
@@ -154,7 +154,7 @@ class ArchSemantics(ISASemantics):
|
|||||||
if len(loads) <= len(stores):
|
if len(loads) <= len(stores):
|
||||||
# Hide all loads
|
# Hide all loads
|
||||||
for load in 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)
|
load.port_pressure = self._nullify_data_ports(load.port_pressure)
|
||||||
else:
|
else:
|
||||||
for store in stores:
|
for store in stores:
|
||||||
@@ -166,12 +166,12 @@ class ArchSemantics(ISASemantics):
|
|||||||
load_instr.line_number,
|
load_instr.line_number,
|
||||||
)
|
)
|
||||||
for load_instr in loads
|
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]
|
load = [instr for instr in kernel if instr.line_number == min_distance_load[1]][0]
|
||||||
# Hide load
|
# Hide load
|
||||||
load.flags += [INSTR_FLAGS.HIDDEN_LD]
|
load.flags += [INSTR_flags.HIDDEN_LD]
|
||||||
load.port_pressure = self._nullify_data_ports(load.port_pressure)
|
load.port_pressure = self._nullify_data_ports(load.port_pressure)
|
||||||
|
|
||||||
# get parser result and assign throughput and latency value to instruction form
|
# get parser result and assign throughput and latency value to instruction form
|
||||||
@@ -226,8 +226,8 @@ class ArchSemantics(ISASemantics):
|
|||||||
assign_unknown = True
|
assign_unknown = True
|
||||||
# check for equivalent register-operands DB entry if LD
|
# check for equivalent register-operands DB entry if LD
|
||||||
if (
|
if (
|
||||||
INSTR_FLAGS.HAS_LD in instruction_form.flags
|
INSTR_flags.HAS_LD in instruction_form.flags
|
||||||
or INSTR_FLAGS.HAS_ST in instruction_form.flags
|
or INSTR_flags.HAS_ST in instruction_form.flags
|
||||||
):
|
):
|
||||||
# dynamically combine LD/ST and reg form of instruction form
|
# dynamically combine LD/ST and reg form of instruction form
|
||||||
# substitute mem and look for reg-only variant
|
# substitute mem and look for reg-only variant
|
||||||
@@ -262,17 +262,17 @@ class ArchSemantics(ISASemantics):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
# dummy_reg = {"class": "register", "name": reg_type}
|
# 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_pressure = [0.0 for _ in range(port_number)]
|
||||||
data_port_uops = []
|
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 performance data
|
||||||
load_perf_data = self._machine_model.get_load_throughput(
|
load_perf_data = self._machine_model.get_load_throughput(
|
||||||
[
|
[
|
||||||
x
|
x
|
||||||
for x in instruction_form.semantic_operands["source"]
|
for x in instruction_form.semantic_operands["source"]
|
||||||
+ instruction_form.semantic_operands["src_dst"]
|
+ instruction_form.semantic_operands["src_dst"]
|
||||||
if isinstance(x, MemoryOperand)
|
if isinstance(x, memoryOperand)
|
||||||
][0]
|
][0]
|
||||||
)
|
)
|
||||||
# if multiple options, choose based on reg type
|
# if multiple options, choose based on reg type
|
||||||
@@ -281,7 +281,7 @@ class ArchSemantics(ISASemantics):
|
|||||||
for ldp in load_perf_data
|
for ldp in load_perf_data
|
||||||
if ldp.dst != None
|
if ldp.dst != None
|
||||||
and self._machine_model._check_operands(
|
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:
|
if len(data_port_uops) < 1:
|
||||||
@@ -296,14 +296,14 @@ class ArchSemantics(ISASemantics):
|
|||||||
reg_type
|
reg_type
|
||||||
]
|
]
|
||||||
data_port_pressure = [pp * multiplier for pp in data_port_pressure]
|
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
|
# STORE performance data
|
||||||
destinations = (
|
destinations = (
|
||||||
instruction_form.semantic_operands["destination"]
|
instruction_form.semantic_operands["destination"]
|
||||||
+ instruction_form.semantic_operands["src_dst"]
|
+ instruction_form.semantic_operands["src_dst"]
|
||||||
)
|
)
|
||||||
store_perf_data = self._machine_model.get_store_throughput(
|
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,
|
dummy_reg,
|
||||||
)
|
)
|
||||||
st_data_port_uops = store_perf_data[0].port_pressure
|
st_data_port_uops = store_perf_data[0].port_pressure
|
||||||
@@ -320,12 +320,12 @@ class ArchSemantics(ISASemantics):
|
|||||||
[
|
[
|
||||||
op.post_indexed or op.pre_indexed
|
op.post_indexed or op.pre_indexed
|
||||||
for op in instruction_form.semantic_operands["src_dst"]
|
for op in instruction_form.semantic_operands["src_dst"]
|
||||||
if isinstance(op, MemoryOperand)
|
if isinstance(op, memoryOperand)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
st_data_port_uops = []
|
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
|
# sum up all data ports in case for LOAD and STORE
|
||||||
st_data_port_pressure = self._machine_model.average_port_pressure(
|
st_data_port_pressure = self._machine_model.average_port_pressure(
|
||||||
@@ -347,12 +347,12 @@ class ArchSemantics(ISASemantics):
|
|||||||
# Add LD and ST latency
|
# Add LD and ST latency
|
||||||
latency += (
|
latency += (
|
||||||
self._machine_model.get_load_latency(reg_type)
|
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
|
else 0
|
||||||
)
|
)
|
||||||
latency += (
|
latency += (
|
||||||
self._machine_model.get_store_latency(reg_type)
|
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
|
else 0
|
||||||
)
|
)
|
||||||
latency_wo_load = instruction_data_reg.latency
|
latency_wo_load = instruction_data_reg.latency
|
||||||
@@ -391,7 +391,7 @@ class ArchSemantics(ISASemantics):
|
|||||||
latency_wo_load = latency
|
latency_wo_load = latency
|
||||||
instruction_form.port_pressure = [0.0 for i in range(port_number)]
|
instruction_form.port_pressure = [0.0 for i in range(port_number)]
|
||||||
instruction_formport_uops = []
|
instruction_formport_uops = []
|
||||||
flags += [INSTR_FLAGS.TP_UNKWN, INSTR_FLAGS.LT_UNKWN]
|
flags += [INSTR_flags.TP_UNKWN, INSTR_flags.LT_UNKWN]
|
||||||
# flatten flag list
|
# flatten flag list
|
||||||
flags = list(set(flags))
|
flags = list(set(flags))
|
||||||
if instruction_form.flags == []:
|
if instruction_form.flags == []:
|
||||||
@@ -416,7 +416,7 @@ class ArchSemantics(ISASemantics):
|
|||||||
instruction_form.port_pressure = port_pressure
|
instruction_form.port_pressure = port_pressure
|
||||||
if sum(port_pressure) == 0 and throughput is not None:
|
if sum(port_pressure) == 0 and throughput is not None:
|
||||||
# port pressure on all ports 0 --> not bound to a port
|
# 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:
|
except AssertionError:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"Port pressure could not be imported correctly from database. "
|
"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_pressure = [0.0 for i in range(port_number)]
|
||||||
instruction_form.port_uops = []
|
instruction_form.port_uops = []
|
||||||
flags.append(INSTR_FLAGS.TP_UNKWN)
|
flags.append(INSTR_flags.TP_UNKWN)
|
||||||
if throughput is None:
|
if throughput is None:
|
||||||
# assume 0 cy and mark as unknown
|
# assume 0 cy and mark as unknown
|
||||||
throughput = 0.0
|
throughput = 0.0
|
||||||
flags.append(INSTR_FLAGS.TP_UNKWN)
|
flags.append(INSTR_flags.TP_UNKWN)
|
||||||
latency = instruction_data.latency
|
latency = instruction_data.latency
|
||||||
latency_wo_load = latency
|
latency_wo_load = latency
|
||||||
if latency is None:
|
if latency is None:
|
||||||
# assume 0 cy and mark as unknown
|
# assume 0 cy and mark as unknown
|
||||||
latency = 0.0
|
latency = 0.0
|
||||||
latency_wo_load = latency
|
latency_wo_load = latency
|
||||||
flags.append(INSTR_FLAGS.LT_UNKWN)
|
flags.append(INSTR_flags.LT_UNKWN)
|
||||||
if INSTR_FLAGS.HAS_LD in instruction_form.flags:
|
if INSTR_flags.HAS_LD in instruction_form.flags:
|
||||||
flags.append(INSTR_FLAGS.LD)
|
flags.append(INSTR_flags.LD)
|
||||||
return throughput, port_pressure, latency, latency_wo_load
|
return throughput, port_pressure, latency, latency_wo_load
|
||||||
|
|
||||||
def convert_op_to_reg(self, reg_type, reg_id="0"):
|
def convert_op_to_reg(self, reg_type, reg_id="0"):
|
||||||
"""Create register operand for a memory addressing operand"""
|
"""Create register operand for a memory addressing operand"""
|
||||||
if self._isa == "x86":
|
if self._isa == "x86":
|
||||||
if reg_type == "gpr":
|
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:
|
else:
|
||||||
register = RegisterOperand(NAME_ID=reg_type + reg_id)
|
register = registerOperand(name_id=reg_type + reg_id)
|
||||||
elif self._isa == "aarch64":
|
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
|
return register
|
||||||
|
|
||||||
def _nullify_data_ports(self, port_pressure):
|
def _nullify_data_ports(self, port_pressure):
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ import ruamel.yaml
|
|||||||
from osaca import __version__, utils
|
from osaca import __version__, utils
|
||||||
from osaca.parser import ParserX86ATT
|
from osaca.parser import ParserX86ATT
|
||||||
from ruamel.yaml.compat import StringIO
|
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.operand import Operand
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import memoryOperand
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import registerOperand
|
||||||
from osaca.parser.immediate import ImmediateOperand
|
from osaca.parser.immediate import immediateOperand
|
||||||
from osaca.parser.identifier import IdentifierOperand
|
from osaca.parser.identifier import identifierOperand
|
||||||
|
|
||||||
|
|
||||||
class MachineModel(object):
|
class MachineModel(object):
|
||||||
@@ -73,7 +73,7 @@ class MachineModel(object):
|
|||||||
self._data = MachineModel._runtime_cache[self._path]
|
self._data = MachineModel._runtime_cache[self._path]
|
||||||
# check if file is cached
|
# check if file is cached
|
||||||
cached = self._get_cached(self._path) if not lazy else False
|
cached = self._get_cached(self._path) if not lazy else False
|
||||||
if False:
|
if cached:
|
||||||
self._data = cached
|
self._data = cached
|
||||||
else:
|
else:
|
||||||
yaml = self._create_yaml_object()
|
yaml = self._create_yaml_object()
|
||||||
@@ -104,8 +104,6 @@ class MachineModel(object):
|
|||||||
self._data["instruction_forms_dict"] = defaultdict(list)
|
self._data["instruction_forms_dict"] = defaultdict(list)
|
||||||
|
|
||||||
for iform in self._data["instruction_forms"]:
|
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()
|
iform["name"] = iform["name"].upper()
|
||||||
if iform["operands"] != []:
|
if iform["operands"] != []:
|
||||||
new_operands = []
|
new_operands = []
|
||||||
@@ -114,34 +112,37 @@ class MachineModel(object):
|
|||||||
self.operand_to_class(o, new_operands)
|
self.operand_to_class(o, new_operands)
|
||||||
iform["operands"] = new_operands
|
iform["operands"] = new_operands
|
||||||
# Do the same for hidden operands
|
# Do the same for hidden operands
|
||||||
if iform["hidden_operands"] != []:
|
if "hidden_operands" in iform:
|
||||||
new_operands = []
|
new_operands = []
|
||||||
# Change operand types from dicts to classes
|
# Change operand types from dicts to classes
|
||||||
for o in iform["hidden_operands"]:
|
for o in iform["hidden_operands"]:
|
||||||
self.operand_to_class(o, new_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
|
# Change dict iform style to class style
|
||||||
new_iform = InstructionForm(
|
new_iform = instructionForm(
|
||||||
INSTRUCTION_ID=iform["name"].upper() if "name" in iform else None,
|
instruction_id=iform["name"].upper() if "name" in iform else None,
|
||||||
OPERANDS_ID=iform["operands"] if "operands" in iform else [],
|
operands_id=iform["operands"] if "operands" in iform else [],
|
||||||
HIDDEN_OPERANDS=iform["hidden_operands"] if "hidden_operansd" in iform else [],
|
hidden_operands=iform["hidden_operands"]
|
||||||
DIRECTIVE_ID=iform["directive"] if "directive" in iform else None,
|
if "hidden_operansd" in iform
|
||||||
COMMENT_ID=iform["comment"] if "comment" in iform else None,
|
else [],
|
||||||
LINE=iform["line"] if "line" in iform else None,
|
directive_id=iform["directive"] if "directive" in iform else None,
|
||||||
LINE_NUMBER=iform["line_number"] if "line_number" in iform else None,
|
comment_id=iform["comment"] if "comment" in iform else None,
|
||||||
LATENCY=iform["latency"] if "latency" in iform else None,
|
line=iform["line"] if "line" in iform else None,
|
||||||
THROUGHPUT=iform["throughput"] if "throughput" in iform else None,
|
line_number=iform["line_number"] if "line_number" in iform else None,
|
||||||
UOPS=iform["uops"] if "uops" in iform else None,
|
latency=iform["latency"] if "latency" in iform else None,
|
||||||
PORT_PRESSURE=iform["port_pressure"] if "port_pressure" in iform else None,
|
throughput=iform["throughput"] if "throughput" in iform else None,
|
||||||
BREAKS_DEP=iform["breaks_dependency_on_equal_operands"] if "breaks_dependency_on_equal_operands" in iform else False,
|
uops=iform["uops"] if "uops" in iform else None,
|
||||||
SEMANTIC_OPERANDS=iform["semantic_operands"]
|
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
|
if "semantic_operands" in iform
|
||||||
else {"source": [], "destination": [], "src_dst": []},
|
else {"source": [], "destination": [], "src_dst": []},
|
||||||
)
|
)
|
||||||
# List containing classes with same name/instruction
|
# List containing classes with same name/instruction
|
||||||
self._data["instruction_forms_dict"][iform["name"]].append(new_iform)
|
self._data["instruction_forms_dict"][iform["name"]].append(new_iform)
|
||||||
|
|
||||||
self._data["internal_version"] = self.INTERNAL_VERSION
|
self._data["internal_version"] = self.INTERNAL_VERSION
|
||||||
|
|
||||||
if not lazy:
|
if not lazy:
|
||||||
@@ -156,13 +157,13 @@ class MachineModel(object):
|
|||||||
if "load_throughput" in self._data:
|
if "load_throughput" in self._data:
|
||||||
for m in self._data["load_throughput"]:
|
for m in self._data["load_throughput"]:
|
||||||
new_throughputs.append(
|
new_throughputs.append(
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
BASE_ID=m["base"],
|
base_id=m["base"],
|
||||||
OFFSET_ID=m["offset"],
|
offset_ID=m["offset"],
|
||||||
SCALE_ID=m["scale"],
|
scale_id=m["scale"],
|
||||||
INDEX_ID=m["index"],
|
index_id=m["index"],
|
||||||
PORT_PRESSURE=m["port_pressure"],
|
port_pressure=m["port_pressure"],
|
||||||
DST=m["dst"] if "dst" in m else None,
|
ds=m["dst"] if "dst" in m else None,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self._data["load_throughput"] = new_throughputs
|
self._data["load_throughput"] = new_throughputs
|
||||||
@@ -171,12 +172,12 @@ class MachineModel(object):
|
|||||||
if "store_throughput" in self._data:
|
if "store_throughput" in self._data:
|
||||||
for m in self._data["store_throughput"]:
|
for m in self._data["store_throughput"]:
|
||||||
new_throughputs.append(
|
new_throughputs.append(
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
BASE_ID=m["base"],
|
base_id=m["base"],
|
||||||
OFFSET_ID=m["offset"],
|
offset_ID=m["offset"],
|
||||||
SCALE_ID=m["scale"],
|
scale_id=m["scale"],
|
||||||
INDEX_ID=m["index"],
|
index_id=m["index"],
|
||||||
PORT_PRESSURE=m["port_pressure"],
|
port_pressure=m["port_pressure"],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self._data["store_throughput"] = new_throughputs
|
self._data["store_throughput"] = new_throughputs
|
||||||
@@ -185,36 +186,36 @@ class MachineModel(object):
|
|||||||
"""Convert an operand from dict type to class"""
|
"""Convert an operand from dict type to class"""
|
||||||
if o["class"] == "register":
|
if o["class"] == "register":
|
||||||
new_operands.append(
|
new_operands.append(
|
||||||
RegisterOperand(
|
registerOperand(
|
||||||
NAME_ID=o["name"] if "name" in o else None,
|
name_id=o["name"] if "name" in o else None,
|
||||||
PREFIX_ID=o["prefix"] if "prefix" in o else None,
|
prefix_id=o["prefix"] if "prefix" in o else None,
|
||||||
SHAPE=o["shape"] if "shape" in o else None,
|
shape=o["shape"] if "shape" in o else None,
|
||||||
MASK=o["mask"] if "mask" in o else False,
|
mask=o["mask"] if "mask" in o else False,
|
||||||
SOURCE=o["source"] if "source" in o else False,
|
source=o["source"] if "source" in o else False,
|
||||||
DESTINATION=o["destination"] if "destination" in o else False,
|
destination=o["destination"] if "destination" in o else False,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif o["class"] == "memory":
|
elif o["class"] == "memory":
|
||||||
new_operands.append(
|
new_operands.append(
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
BASE_ID=o["base"],
|
base_id=o["base"],
|
||||||
OFFSET_ID=o["offset"],
|
offset_ID=o["offset"],
|
||||||
INDEX_ID=o["index"],
|
index_id=o["index"],
|
||||||
SCALE_ID=o["scale"],
|
scale_id=o["scale"],
|
||||||
SOURCE=o["source"] if "source" in o else False,
|
source=o["source"] if "source" in o else False,
|
||||||
DESTINATION=o["destination"] if "destination" in o else False,
|
destination=o["destination"] if "destination" in o else False,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif o["class"] == "immediate":
|
elif o["class"] == "immediate":
|
||||||
new_operands.append(
|
new_operands.append(
|
||||||
ImmediateOperand(
|
immediateOperand(
|
||||||
TYPE_ID=o["imd"],
|
type_id=o["imd"],
|
||||||
SOURCE=o["source"] if "source" in o else False,
|
source=o["source"] if "source" in o else False,
|
||||||
DESTINATION=o["destination"] if "destination" in o else False,
|
destination=o["destination"] if "destination" in o else False,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif o["class"] == "identifier":
|
elif o["class"] == "identifier":
|
||||||
new_operands.append(IdentifierOperand())
|
new_operands.append(identifierOperand())
|
||||||
else:
|
else:
|
||||||
new_operands.append(o)
|
new_operands.append(o)
|
||||||
|
|
||||||
@@ -283,7 +284,7 @@ class MachineModel(object):
|
|||||||
# If it already exists. Overwrite information.
|
# If it already exists. Overwrite information.
|
||||||
instr_data = self.get_instruction(instruction, operands)
|
instr_data = self.get_instruction(instruction, operands)
|
||||||
if instr_data is None:
|
if instr_data is None:
|
||||||
instr_data = InstructionForm()
|
instr_data = instructionForm()
|
||||||
self._data["instruction_forms"].append(instr_data)
|
self._data["instruction_forms"].append(instr_data)
|
||||||
self._data["instruction_forms_dict"][instruction].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)]
|
ld_tp = [m for m in self._data["load_throughput"] if self._match_mem_entries(memory, m)]
|
||||||
if len(ld_tp) > 0:
|
if len(ld_tp) > 0:
|
||||||
return ld_tp.copy()
|
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):
|
def get_store_latency(self, reg_type):
|
||||||
"""Return store latency for given register type."""
|
"""Return store latency for given register type."""
|
||||||
@@ -354,11 +355,11 @@ class MachineModel(object):
|
|||||||
tp
|
tp
|
||||||
for tp in st_tp
|
for tp in st_tp
|
||||||
if "src" in 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:
|
if len(st_tp) > 0:
|
||||||
return st_tp.copy()
|
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):
|
def _match_mem_entries(self, mem, i_mem):
|
||||||
"""Check if memory addressing ``mem`` and ``i_mem`` are of the same type."""
|
"""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):
|
def _create_db_operand_aarch64(self, operand):
|
||||||
"""Create instruction form operand for DB out of operand string."""
|
"""Create instruction form operand for DB out of operand string."""
|
||||||
if operand == "i":
|
if operand == "i":
|
||||||
return ImmediateOperand(TYPE_ID="int")
|
return immediateOperand(type_id="int")
|
||||||
elif operand in "wxbhsdq":
|
elif operand in "wxbhsdq":
|
||||||
return RegisterOperand(PREFIX_ID=operand)
|
return registerOperand(prefix_id=operand)
|
||||||
elif operand.startswith("v"):
|
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"):
|
elif operand.startswith("m"):
|
||||||
return MemoryOperand(
|
return memoryOperand(
|
||||||
BASE_ID="x" if "b" in operand else None,
|
base_id="x" if "b" in operand else None,
|
||||||
OFFSET_ID="imd" if "o" in operand else None,
|
offset_ID="imd" if "o" in operand else None,
|
||||||
INDEX_ID="gpr" if "i" in operand else None,
|
index_id="gpr" if "i" in operand else None,
|
||||||
SCALE_ID=8 if "s" in operand else 1,
|
scale_id=8 if "s" in operand else 1,
|
||||||
PRE_INDEXED=True if "r" in operand else False,
|
pre_indexed=True if "r" in operand else False,
|
||||||
POST_INDEXED=True if "p" in operand else False,
|
post_indexed=True if "p" in operand else False,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Parameter {} is not a valid operand code".format(operand))
|
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):
|
def _create_db_operand_x86(self, operand):
|
||||||
"""Create instruction form operand for DB out of operand string."""
|
"""Create instruction form operand for DB out of operand string."""
|
||||||
if operand == "r":
|
if operand == "r":
|
||||||
return RegisterOperand(NAME_ID="gpr")
|
return registerOperand(name_id="gpr")
|
||||||
elif operand in "xyz":
|
elif operand in "xyz":
|
||||||
return RegisterOperand(NAME_ID=operand + "mm")
|
return registerOperand(name_id=operand + "mm")
|
||||||
elif operand == "i":
|
elif operand == "i":
|
||||||
return ImmediateOperand(TYPE_ID="int")
|
return immediateOperand(type_id="int")
|
||||||
elif operand.startswith("m"):
|
elif operand.startswith("m"):
|
||||||
return MemoryOperand(
|
return memoryOperand(
|
||||||
BASE_ID="gpr" if "b" in operand else None,
|
base_id="gpr" if "b" in operand else None,
|
||||||
OFFSET_ID="imd" if "o" in operand else None,
|
offset_ID="imd" if "o" in operand else None,
|
||||||
INDEX_ID="gpr" if "i" in operand else None,
|
index_id="gpr" if "i" in operand else None,
|
||||||
SCALE_ID=8 if "s" in operand else 1,
|
scale_id=8 if "s" in operand else 1,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Parameter {} is not a valid operand code".format(operand))
|
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 (
|
if (isinstance(operand, Operand) and operand.name == self.WILDCARD) or (
|
||||||
not isinstance(operand, Operand) and self.WILDCARD in operand
|
not isinstance(operand, Operand) and self.WILDCARD in operand
|
||||||
):
|
):
|
||||||
if isinstance(i_operand, RegisterOperand):
|
if isinstance(i_operand, registerOperand):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@@ -659,45 +660,45 @@ class MachineModel(object):
|
|||||||
# return self._compare_db_entries(i_operand, operand)
|
# return self._compare_db_entries(i_operand, operand)
|
||||||
# TODO support class wildcards
|
# TODO support class wildcards
|
||||||
# register
|
# register
|
||||||
if isinstance(operand, RegisterOperand):
|
if isinstance(operand, registerOperand):
|
||||||
if not isinstance(i_operand, RegisterOperand):
|
if not isinstance(i_operand, registerOperand):
|
||||||
return False
|
return False
|
||||||
return self._is_AArch64_reg_type(i_operand, operand)
|
return self._is_AArch64_reg_type(i_operand, operand)
|
||||||
# memory
|
# memory
|
||||||
if isinstance(operand, MemoryOperand):
|
if isinstance(operand, memoryOperand):
|
||||||
if not isinstance(i_operand, MemoryOperand):
|
if not isinstance(i_operand, memoryOperand):
|
||||||
return False
|
return False
|
||||||
return self._is_AArch64_mem_type(i_operand, operand)
|
return self._is_AArch64_mem_type(i_operand, operand)
|
||||||
# immediate
|
# immediate
|
||||||
if isinstance(i_operand, ImmediateOperand) and i_operand.type == self.WILDCARD:
|
if isinstance(i_operand, immediateOperand) and i_operand.type == self.WILDCARD:
|
||||||
return isinstance(operand, ImmediateOperand) and (operand.value != None)
|
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 (
|
return (
|
||||||
isinstance(operand, ImmediateOperand)
|
isinstance(operand, immediateOperand)
|
||||||
and operand.type == "int"
|
and operand.type == "int"
|
||||||
and operand.value != None
|
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 (
|
return (
|
||||||
isinstance(operand, ImmediateOperand)
|
isinstance(operand, immediateOperand)
|
||||||
and operand.type == "float"
|
and operand.type == "float"
|
||||||
and operand.value != None
|
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 (
|
return (
|
||||||
isinstance(operand, ImmediateOperand)
|
isinstance(operand, immediateOperand)
|
||||||
and operand.type == "double"
|
and operand.type == "double"
|
||||||
and operand.value != None
|
and operand.value != None
|
||||||
)
|
)
|
||||||
|
|
||||||
# identifier
|
# identifier
|
||||||
if isinstance(operand, IdentifierOperand) or (
|
if isinstance(operand, identifierOperand) or (
|
||||||
isinstance(operand, ImmediateOperand) and operand.identifier != None
|
isinstance(operand, immediateOperand) and operand.identifier != None
|
||||||
):
|
):
|
||||||
return isinstance(i_operand, IdentifierOperand)
|
return isinstance(i_operand, identifierOperand)
|
||||||
# prefetch option
|
# prefetch option
|
||||||
if not isinstance(operand, Operand) and "prfop" in operand:
|
if not isinstance(operand, Operand) and "prfop" in operand:
|
||||||
return i_operand["class"] == "prfop"
|
return i_operand["class"] == "prfop"
|
||||||
@@ -719,22 +720,22 @@ class MachineModel(object):
|
|||||||
# compare two DB entries
|
# compare two DB entries
|
||||||
# return self._compare_db_entries(i_operand, operand)
|
# return self._compare_db_entries(i_operand, operand)
|
||||||
# register
|
# register
|
||||||
if isinstance(operand, RegisterOperand):
|
if isinstance(operand, registerOperand):
|
||||||
if not isinstance(i_operand, RegisterOperand):
|
if not isinstance(i_operand, registerOperand):
|
||||||
return False
|
return False
|
||||||
return self._is_x86_reg_type(i_operand, operand, consider_masking=False)
|
return self._is_x86_reg_type(i_operand, operand, consider_masking=False)
|
||||||
# memory
|
# memory
|
||||||
if isinstance(operand, MemoryOperand):
|
if isinstance(operand, memoryOperand):
|
||||||
if not isinstance(i_operand, MemoryOperand):
|
if not isinstance(i_operand, memoryOperand):
|
||||||
return False
|
return False
|
||||||
return self._is_x86_mem_type(i_operand, operand)
|
return self._is_x86_mem_type(i_operand, operand)
|
||||||
# immediate
|
# immediate
|
||||||
if isinstance(operand, ImmediateOperand):
|
if isinstance(operand, immediateOperand):
|
||||||
# if "immediate" in operand.name or operand.value != None:
|
# 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)
|
# identifier (e.g., labels)
|
||||||
if isinstance(operand, IdentifierOperand):
|
if isinstance(operand, identifierOperand):
|
||||||
return isinstance(i_operand, IdentifierOperand)
|
return isinstance(i_operand, identifierOperand)
|
||||||
return self._compare_db_entries(i_operand, operand)
|
return self._compare_db_entries(i_operand, operand)
|
||||||
|
|
||||||
def _compare_db_entries(self, operand_1, operand_2):
|
def _compare_db_entries(self, operand_1, operand_2):
|
||||||
@@ -790,7 +791,7 @@ class MachineModel(object):
|
|||||||
if i_reg is None:
|
if i_reg is None:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
if isinstance(i_reg, RegisterOperand):
|
if isinstance(i_reg, registerOperand):
|
||||||
i_reg_name = i_reg.name
|
i_reg_name = i_reg.name
|
||||||
else:
|
else:
|
||||||
i_reg_name = i_reg
|
i_reg_name = i_reg
|
||||||
@@ -842,7 +843,7 @@ class MachineModel(object):
|
|||||||
(
|
(
|
||||||
(mem.base is None and i_mem.base is None)
|
(mem.base is None and i_mem.base is None)
|
||||||
or i_mem.base == self.WILDCARD
|
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
|
# check offset
|
||||||
and (
|
and (
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ from itertools import chain
|
|||||||
|
|
||||||
from osaca import utils
|
from osaca import utils
|
||||||
from osaca.parser import AttrDict, ParserAArch64, ParserX86ATT
|
from osaca.parser import AttrDict, ParserAArch64, ParserX86ATT
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import memoryOperand
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import registerOperand
|
||||||
from osaca.parser.immediate import ImmediateOperand
|
from osaca.parser.immediate import immediateOperand
|
||||||
|
|
||||||
from .hw_model import MachineModel
|
from .hw_model import MachineModel
|
||||||
|
|
||||||
|
|
||||||
class INSTR_FLAGS:
|
class INSTR_flags:
|
||||||
"""
|
"""
|
||||||
Flags used for unknown or special instructions
|
Flags used for unknown or special instructions
|
||||||
"""
|
"""
|
||||||
@@ -81,7 +81,7 @@ class ISASemantics(object):
|
|||||||
# Couldn't found instruction form in ISA DB
|
# Couldn't found instruction form in ISA DB
|
||||||
assign_default = True
|
assign_default = True
|
||||||
# check for equivalent register-operands DB entry if LD/ST
|
# 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)
|
operands_reg = self.substitute_mem_address(instruction_form.operands)
|
||||||
isa_data_reg = self._isa_model.get_instruction(
|
isa_data_reg = self._isa_model.get_instruction(
|
||||||
instruction_form.instruction, operands_reg
|
instruction_form.instruction, operands_reg
|
||||||
@@ -116,7 +116,7 @@ class ISASemantics(object):
|
|||||||
op_dict["src_dst"] = []
|
op_dict["src_dst"] = []
|
||||||
# post-process pre- and post-indexing for aarch64 memory operands
|
# post-process pre- and post-indexing for aarch64 memory operands
|
||||||
if self._isa == "aarch64":
|
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
|
post_indexed = operand.post_indexed
|
||||||
pre_indexed = operand.pre_indexed
|
pre_indexed = operand.pre_indexed
|
||||||
if post_indexed or pre_indexed:
|
if post_indexed or pre_indexed:
|
||||||
@@ -127,7 +127,7 @@ class ISASemantics(object):
|
|||||||
"post_indexed": post_indexed,
|
"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
|
post_indexed = operand.post_indexed
|
||||||
pre_indexed = operand.pre_indexed
|
pre_indexed = operand.pre_indexed
|
||||||
if post_indexed or pre_indexed:
|
if post_indexed or pre_indexed:
|
||||||
@@ -146,9 +146,9 @@ class ISASemantics(object):
|
|||||||
# )
|
# )
|
||||||
|
|
||||||
if self._has_load(instruction_form):
|
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):
|
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):
|
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["destination"],
|
||||||
instruction_form.semantic_operands["src_dst"],
|
instruction_form.semantic_operands["src_dst"],
|
||||||
)
|
)
|
||||||
if isinstance(op, RegisterOperand)
|
if isinstance(op, registerOperand)
|
||||||
]
|
]
|
||||||
isa_data = self._isa_model.get_instruction(
|
isa_data = self._isa_model.get_instruction(
|
||||||
instruction_form.instruction, instruction_form.operands
|
instruction_form.instruction, instruction_form.operands
|
||||||
@@ -188,7 +188,7 @@ class ISASemantics(object):
|
|||||||
|
|
||||||
if only_postindexed:
|
if only_postindexed:
|
||||||
for o in instruction_form.operands:
|
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
|
base_name = o.base.prefix if o.base.prefix != None else "" + o.base.name
|
||||||
return {
|
return {
|
||||||
base_name: {
|
base_name: {
|
||||||
@@ -202,7 +202,7 @@ class ISASemantics(object):
|
|||||||
operand_state = {} # e.g., {'op1': {'name': 'rax', 'value': 0}} 0 means unchanged
|
operand_state = {} # e.g., {'op1': {'name': 'rax', 'value': 0}} 0 means unchanged
|
||||||
|
|
||||||
for o in instruction_form.operands:
|
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
|
# Assuming no isa_data.operation
|
||||||
if isa_data is not None and isa_data.get("operation", None) is not None:
|
if isa_data is not None and isa_data.get("operation", None) is not None:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
@@ -216,13 +216,13 @@ class ISASemantics(object):
|
|||||||
if isa_data is not None:
|
if isa_data is not None:
|
||||||
for i, o in enumerate(instruction_form.operands):
|
for i, o in enumerate(instruction_form.operands):
|
||||||
operand_name = "op{}".format(i + 1)
|
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
|
o_reg_name = o.prefix if o.prefix != None else "" + o.name
|
||||||
reg_operand_names[o_reg_name] = operand_name
|
reg_operand_names[o_reg_name] = operand_name
|
||||||
operand_state[operand_name] = {"name": o_reg_name, "value": 0}
|
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}
|
operand_state[operand_name] = {"value": o.value}
|
||||||
elif isinstance(o, MemoryOperand):
|
elif isinstance(o, memoryOperand):
|
||||||
# TODO lea needs some thinking about
|
# TODO lea needs some thinking about
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -301,7 +301,7 @@ class ISASemantics(object):
|
|||||||
instruction_form.semantic_operands["source"],
|
instruction_form.semantic_operands["source"],
|
||||||
instruction_form.semantic_operands["src_dst"],
|
instruction_form.semantic_operands["src_dst"],
|
||||||
):
|
):
|
||||||
if isinstance(operand, MemoryOperand):
|
if isinstance(operand, memoryOperand):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -311,7 +311,7 @@ class ISASemantics(object):
|
|||||||
instruction_form.semantic_operands["destination"],
|
instruction_form.semantic_operands["destination"],
|
||||||
instruction_form.semantic_operands["src_dst"],
|
instruction_form.semantic_operands["src_dst"],
|
||||||
):
|
):
|
||||||
if isinstance(operand, MemoryOperand):
|
if isinstance(operand, memoryOperand):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ class ISASemantics(object):
|
|||||||
def substitute_mem_address(self, operands):
|
def substitute_mem_address(self, operands):
|
||||||
"""Create memory wildcard for all memory operands"""
|
"""Create memory wildcard for all memory operands"""
|
||||||
return [
|
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):
|
def _create_reg_wildcard(self):
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ from itertools import chain
|
|||||||
from multiprocessing import Manager, Process, cpu_count
|
from multiprocessing import Manager, Process, cpu_count
|
||||||
|
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
from osaca.semantics import INSTR_FLAGS, ArchSemantics, MachineModel
|
from osaca.semantics import INSTR_flags, ArchSemantics, MachineModel
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import memoryOperand
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import registerOperand
|
||||||
from osaca.parser.immediate import ImmediateOperand
|
from osaca.parser.immediate import immediateOperand
|
||||||
|
|
||||||
|
|
||||||
class KernelDG(nx.DiGraph):
|
class KernelDG(nx.DiGraph):
|
||||||
@@ -66,8 +66,8 @@ class KernelDG(nx.DiGraph):
|
|||||||
dg.nodes[instruction_form.line_number]["instruction_form"] = instruction_form
|
dg.nodes[instruction_form.line_number]["instruction_form"] = instruction_form
|
||||||
# add load as separate node if existent
|
# add load as separate node if existent
|
||||||
if (
|
if (
|
||||||
INSTR_FLAGS.HAS_LD in instruction_form.flags
|
INSTR_flags.HAS_LD in instruction_form.flags
|
||||||
and INSTR_FLAGS.LD not in instruction_form.flags
|
and INSTR_flags.LD not in instruction_form.flags
|
||||||
):
|
):
|
||||||
# add new node
|
# add new node
|
||||||
dg.add_node(instruction_form.line_number + 0.1)
|
dg.add_node(instruction_form.line_number + 0.1)
|
||||||
@@ -283,7 +283,7 @@ class KernelDG(nx.DiGraph):
|
|||||||
for i, instr_form in enumerate(instructions):
|
for i, instr_form in enumerate(instructions):
|
||||||
self._update_reg_changes(instr_form, register_changes)
|
self._update_reg_changes(instr_form, register_changes)
|
||||||
# print(" TO", instr_form.line, register_changes)
|
# print(" TO", instr_form.line, register_changes)
|
||||||
if isinstance(dst, RegisterOperand):
|
if isinstance(dst, registerOperand):
|
||||||
# read of register
|
# read of register
|
||||||
if self.is_read(dst, instr_form):
|
if self.is_read(dst, instr_form):
|
||||||
# if dst.pre_indexed or dst.post_indexed:
|
# if dst.pre_indexed or dst.post_indexed:
|
||||||
@@ -294,8 +294,8 @@ class KernelDG(nx.DiGraph):
|
|||||||
if self.is_written(dst, instr_form):
|
if self.is_written(dst, instr_form):
|
||||||
break
|
break
|
||||||
if (
|
if (
|
||||||
not isinstance(dst, RegisterOperand)
|
not isinstance(dst, registerOperand)
|
||||||
and not isinstance(dst, MemoryOperand)
|
and not isinstance(dst, memoryOperand)
|
||||||
and "flag" in dst
|
and "flag" in dst
|
||||||
and flag_dependencies
|
and flag_dependencies
|
||||||
):
|
):
|
||||||
@@ -305,7 +305,7 @@ class KernelDG(nx.DiGraph):
|
|||||||
# write to flag -> abort
|
# write to flag -> abort
|
||||||
if self.is_written(dst.flag, instr_form):
|
if self.is_written(dst.flag, instr_form):
|
||||||
break
|
break
|
||||||
if isinstance(dst, MemoryOperand):
|
if isinstance(dst, memoryOperand):
|
||||||
# base register is altered during memory access
|
# base register is altered during memory access
|
||||||
if dst.pre_indexed != None:
|
if dst.pre_indexed != None:
|
||||||
if self.is_written(dst.base, instr_form):
|
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["source"],
|
||||||
instruction_form.semantic_operands["src_dst"],
|
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
|
is_read = self.parser.is_reg_dependend_of(register, src) or is_read
|
||||||
if (
|
if (
|
||||||
not isinstance(src, RegisterOperand)
|
not isinstance(src, registerOperand)
|
||||||
and not isinstance(src, MemoryOperand)
|
and not isinstance(src, memoryOperand)
|
||||||
and not isinstance(src, ImmediateOperand)
|
and not isinstance(src, immediateOperand)
|
||||||
and "flag" in src
|
and "flag" in src
|
||||||
):
|
):
|
||||||
is_read = self.parser.is_flag_dependend_of(register, src.flag) or is_read
|
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:
|
if src.base is not None:
|
||||||
is_read = self.parser.is_reg_dependend_of(register, src.base) or is_read
|
is_read = self.parser.is_reg_dependend_of(register, src.base) or is_read
|
||||||
if src.index is not None:
|
if src.index is not None:
|
||||||
@@ -393,7 +393,7 @@ class KernelDG(nx.DiGraph):
|
|||||||
instruction_form.semantic_operands["destination"],
|
instruction_form.semantic_operands["destination"],
|
||||||
instruction_form.semantic_operands["src_dst"],
|
instruction_form.semantic_operands["src_dst"],
|
||||||
):
|
):
|
||||||
if isinstance(dst, MemoryOperand):
|
if isinstance(dst, memoryOperand):
|
||||||
if dst.base is not None:
|
if dst.base is not None:
|
||||||
is_read = self.parser.is_reg_dependend_of(register, dst.base) or is_read
|
is_read = self.parser.is_reg_dependend_of(register, dst.base) or is_read
|
||||||
if dst.index is not None:
|
if dst.index is not None:
|
||||||
@@ -409,7 +409,7 @@ class KernelDG(nx.DiGraph):
|
|||||||
instruction_form.semantic_operands["src_dst"],
|
instruction_form.semantic_operands["src_dst"],
|
||||||
):
|
):
|
||||||
# Here we check for mem dependecies only
|
# Here we check for mem dependecies only
|
||||||
if not isinstance(src, MemoryOperand):
|
if not isinstance(src, memoryOperand):
|
||||||
continue
|
continue
|
||||||
# src = src.memory
|
# src = src.memory
|
||||||
|
|
||||||
@@ -482,15 +482,15 @@ class KernelDG(nx.DiGraph):
|
|||||||
instruction_form.semantic_operands["destination"],
|
instruction_form.semantic_operands["destination"],
|
||||||
instruction_form.semantic_operands["src_dst"],
|
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
|
is_written = self.parser.is_reg_dependend_of(register, dst) or is_written
|
||||||
if (
|
if (
|
||||||
not isinstance(dst, RegisterOperand)
|
not isinstance(dst, registerOperand)
|
||||||
and not isinstance(dst, MemoryOperand)
|
and not isinstance(dst, memoryOperand)
|
||||||
and "flag" in dst
|
and "flag" in dst
|
||||||
):
|
):
|
||||||
is_written = self.parser.is_flag_dependend_of(register, dst.flag) or is_written
|
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:
|
if dst.pre_indexed or dst.post_indexed:
|
||||||
is_written = self.parser.is_reg_dependend_of(register, dst.base) or is_written
|
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
|
# 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["source"],
|
||||||
instruction_form.semantic_operands["src_dst"],
|
instruction_form.semantic_operands["src_dst"],
|
||||||
):
|
):
|
||||||
if isinstance(src, MemoryOperand):
|
if isinstance(src, memoryOperand):
|
||||||
if src.pre_indexed or src.post_indexed:
|
if src.pre_indexed or src.post_indexed:
|
||||||
is_written = self.parser.is_reg_dependend_of(register, src.base) or is_written
|
is_written = self.parser.is_reg_dependend_of(register, src.base) or is_written
|
||||||
return is_written
|
return is_written
|
||||||
@@ -512,7 +512,7 @@ class KernelDG(nx.DiGraph):
|
|||||||
instruction_form.semantic_operands["destination"],
|
instruction_form.semantic_operands["destination"],
|
||||||
instruction_form.semantic_operands["src_dst"],
|
instruction_form.semantic_operands["src_dst"],
|
||||||
):
|
):
|
||||||
if isinstance(dst, MemoryOperand):
|
if isinstance(dst, memoryOperand):
|
||||||
is_store = mem == dst or is_store
|
is_store = mem == dst or is_store
|
||||||
return is_store
|
return is_store
|
||||||
|
|
||||||
|
|||||||
@@ -9,24 +9,24 @@ from io import StringIO
|
|||||||
import osaca.db_interface as dbi
|
import osaca.db_interface as dbi
|
||||||
from osaca.db_interface import sanity_check
|
from osaca.db_interface import sanity_check
|
||||||
from osaca.semantics import MachineModel
|
from osaca.semantics import MachineModel
|
||||||
from osaca.parser import InstructionForm
|
from osaca.parser import instructionForm
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import memoryOperand
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import registerOperand
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
|
||||||
class TestDBInterface(unittest.TestCase):
|
class TestDBInterface(unittest.TestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(self):
|
def setUpClass(self):
|
||||||
sample_entry = InstructionForm(
|
sample_entry = instructionForm(
|
||||||
INSTRUCTION_ID="DoItRightAndDoItFast",
|
instruction_id="DoItRightAndDoItFast",
|
||||||
OPERANDS_ID=[
|
operands_id=[
|
||||||
MemoryOperand(OFFSET_ID="imd", BASE_ID="gpr", INDEX_ID="gpr", SCALE_ID=8),
|
memoryOperand(offset_ID="imd", base_id="gpr", index_id="gpr", scale_id=8),
|
||||||
RegisterOperand(NAME_ID="xmm"),
|
registerOperand(name_id="xmm"),
|
||||||
],
|
],
|
||||||
THROUGHPUT=1.25,
|
throughput=1.25,
|
||||||
LATENCY=125,
|
latency=125,
|
||||||
UOPS=6,
|
uops=6,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.entry_csx = copy.copy(sample_entry)
|
self.entry_csx = copy.copy(sample_entry)
|
||||||
@@ -61,7 +61,7 @@ class TestDBInterface(unittest.TestCase):
|
|||||||
|
|
||||||
mm_csx.set_instruction_entry(self.entry_csx)
|
mm_csx.set_instruction_entry(self.entry_csx)
|
||||||
mm_tx2.set_instruction_entry(self.entry_tx2)
|
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_csx = len(mm_csx["instruction_forms"]) - num_entries_csx
|
||||||
num_entries_tx2 = len(mm_tx2["instruction_forms"]) - num_entries_tx2
|
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)
|
self.assertEqual(num_entries_zen1, 1)
|
||||||
|
|
||||||
def test_invalid_add(self):
|
def test_invalid_add(self):
|
||||||
entry = InstructionForm()
|
entry = instructionForm()
|
||||||
# with self.assertRaises(KeyError):
|
# with self.assertRaises(KeyError):
|
||||||
# MachineModel("csx").set_instruction_entry(entry)
|
# MachineModel("csx").set_instruction_entry(entry)
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import unittest
|
|||||||
|
|
||||||
from pyparsing import ParseException
|
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.operand import Operand
|
||||||
from osaca.parser.directive import DirectiveOperand
|
from osaca.parser.directive import directiveOperand
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import memoryOperand
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import registerOperand
|
||||||
from osaca.parser.immediate import ImmediateOperand
|
from osaca.parser.immediate import immediateOperand
|
||||||
|
|
||||||
|
|
||||||
class TestParserAArch64(unittest.TestCase):
|
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_5_operands = "fcmla z26.d, p0/m, z29.d, z21.d, #90"
|
||||||
line_conditions = "ccmn x11, #1, #3, eq"
|
line_conditions = "ccmn x11, #1, #3, eq"
|
||||||
|
|
||||||
instruction_form_1 = InstructionForm(
|
instruction_form_1 = instructionForm(
|
||||||
INSTRUCTION_ID=None,
|
instruction_id=None,
|
||||||
OPERANDS_ID=[],
|
operands_id=[],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID="-- Begin main",
|
comment_id="-- Begin main",
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE="// -- Begin main",
|
line="// -- Begin main",
|
||||||
LINE_NUMBER=1,
|
line_number=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
instruction_form_2 = InstructionForm(
|
instruction_form_2 = instructionForm(
|
||||||
INSTRUCTION_ID=None,
|
instruction_id=None,
|
||||||
OPERANDS_ID=[],
|
operands_id=[],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID="=>This Inner Loop Header: Depth=1",
|
comment_id="=>This Inner Loop Header: Depth=1",
|
||||||
LABEL_ID=".LBB0_1",
|
label_id=".LBB0_1",
|
||||||
LINE=".LBB0_1: // =>This Inner Loop Header: Depth=1",
|
line=".LBB0_1: // =>This Inner Loop Header: Depth=1",
|
||||||
LINE_NUMBER=2,
|
line_number=2,
|
||||||
)
|
)
|
||||||
instruction_form_3 = InstructionForm(
|
instruction_form_3 = instructionForm(
|
||||||
INSTRUCTION_ID=None,
|
instruction_id=None,
|
||||||
OPERANDS_ID=[],
|
operands_id=[],
|
||||||
DIRECTIVE_ID=DirectiveOperand(NAME_ID="cfi_def_cfa", PARAMETER_ID=["w29", "-16"]),
|
directive_id=directiveOperand(name_id="cfi_def_cfa", parameter_id=["w29", "-16"]),
|
||||||
COMMENT_ID=None,
|
comment_id=None,
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE=".cfi_def_cfa w29, -16",
|
line=".cfi_def_cfa w29, -16",
|
||||||
LINE_NUMBER=3,
|
line_number=3,
|
||||||
)
|
)
|
||||||
instruction_form_4 = InstructionForm(
|
instruction_form_4 = instructionForm(
|
||||||
INSTRUCTION_ID="ldr",
|
instruction_id="ldr",
|
||||||
OPERANDS_ID=[
|
operands_id=[
|
||||||
RegisterOperand(PREFIX_ID="s", NAME_ID="0"),
|
registerOperand(prefix_id="s", name_id="0"),
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
OFFSET_ID=None,
|
offset_ID=None,
|
||||||
BASE_ID=RegisterOperand(PREFIX_ID="x", NAME_ID="11"),
|
base_id=registerOperand(prefix_id="x", name_id="11"),
|
||||||
INDEX_ID={
|
index_id={
|
||||||
"prefix": "w",
|
"prefix": "w",
|
||||||
"name": "10",
|
"name": "10",
|
||||||
"shift_op": "sxtw",
|
"shift_op": "sxtw",
|
||||||
"immediate": {"value": "2"},
|
"immediate": {"value": "2"},
|
||||||
"shift": [{"value": "2"}],
|
"shift": [{"value": "2"}],
|
||||||
},
|
},
|
||||||
SCALE_ID=4,
|
scale_id=4,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID="= <<2",
|
comment_id="= <<2",
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE="ldr s0, [x11, w10, sxtw #2] // = <<2",
|
line="ldr s0, [x11, w10, sxtw #2] // = <<2",
|
||||||
LINE_NUMBER=4,
|
line_number=4,
|
||||||
)
|
)
|
||||||
instruction_form_5 = InstructionForm(
|
instruction_form_5 = instructionForm(
|
||||||
INSTRUCTION_ID="prfm",
|
instruction_id="prfm",
|
||||||
OPERANDS_ID=[
|
operands_id=[
|
||||||
{"prfop": {"type": ["PLD"], "target": ["L1"], "policy": ["KEEP"]}},
|
{"prfop": {"type": ["PLD"], "target": ["L1"], "policy": ["KEEP"]}},
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
OFFSET_ID={"value": 2048},
|
offset_ID={"value": 2048},
|
||||||
BASE_ID=RegisterOperand(PREFIX_ID="x", NAME_ID="26"),
|
base_id=registerOperand(prefix_id="x", name_id="26"),
|
||||||
INDEX_ID=None,
|
index_id=None,
|
||||||
SCALE_ID=1,
|
scale_id=1,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID="HPL",
|
comment_id="HPL",
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE="prfm pldl1keep, [x26, #2048] //HPL",
|
line="prfm pldl1keep, [x26, #2048] //HPL",
|
||||||
LINE_NUMBER=5,
|
line_number=5,
|
||||||
)
|
)
|
||||||
instruction_form_6 = InstructionForm(
|
instruction_form_6 = instructionForm(
|
||||||
INSTRUCTION_ID="stp",
|
instruction_id="stp",
|
||||||
OPERANDS_ID=[
|
operands_id=[
|
||||||
RegisterOperand(PREFIX_ID="x", NAME_ID="29"),
|
registerOperand(prefix_id="x", name_id="29"),
|
||||||
RegisterOperand(PREFIX_ID="x", NAME_ID="30"),
|
registerOperand(prefix_id="x", name_id="30"),
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
OFFSET_ID={"value": -16},
|
offset_ID={"value": -16},
|
||||||
BASE_ID=RegisterOperand(NAME_ID="sp", PREFIX_ID="x"),
|
base_id=registerOperand(name_id="sp", prefix_id="x"),
|
||||||
INDEX_ID=None,
|
index_id=None,
|
||||||
SCALE_ID=1,
|
scale_id=1,
|
||||||
PRE_INDEXED=True,
|
pre_indexed=True,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID=None,
|
comment_id=None,
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE="stp x29, x30, [sp, #-16]!",
|
line="stp x29, x30, [sp, #-16]!",
|
||||||
LINE_NUMBER=6,
|
line_number=6,
|
||||||
)
|
)
|
||||||
instruction_form_7 = InstructionForm(
|
instruction_form_7 = instructionForm(
|
||||||
INSTRUCTION_ID="ldp",
|
instruction_id="ldp",
|
||||||
OPERANDS_ID=[
|
operands_id=[
|
||||||
RegisterOperand(PREFIX_ID="q", NAME_ID="2"),
|
registerOperand(prefix_id="q", name_id="2"),
|
||||||
RegisterOperand(PREFIX_ID="q", NAME_ID="3"),
|
registerOperand(prefix_id="q", name_id="3"),
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
OFFSET_ID=None,
|
offset_ID=None,
|
||||||
BASE_ID=RegisterOperand(NAME_ID="11", PREFIX_ID="x"),
|
base_id=registerOperand(name_id="11", prefix_id="x"),
|
||||||
INDEX_ID=None,
|
index_id=None,
|
||||||
SCALE_ID=1,
|
scale_id=1,
|
||||||
POST_INDEXED={"value": 64},
|
post_indexed={"value": 64},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID=None,
|
comment_id=None,
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE="ldp q2, q3, [x11], #64",
|
line="ldp q2, q3, [x11], #64",
|
||||||
LINE_NUMBER=7,
|
line_number=7,
|
||||||
)
|
)
|
||||||
instruction_form_8 = InstructionForm(
|
instruction_form_8 = instructionForm(
|
||||||
INSTRUCTION_ID="fcmla",
|
instruction_id="fcmla",
|
||||||
OPERANDS_ID=[
|
operands_id=[
|
||||||
RegisterOperand(PREFIX_ID="z", NAME_ID="26", SHAPE="d"),
|
registerOperand(prefix_id="z", name_id="26", shape="d"),
|
||||||
RegisterOperand(PREFIX_ID="p", NAME_ID="0", PREDICATION="m"),
|
registerOperand(prefix_id="p", name_id="0", predication="m"),
|
||||||
RegisterOperand(PREFIX_ID="z", NAME_ID="29", SHAPE="d"),
|
registerOperand(prefix_id="z", name_id="29", shape="d"),
|
||||||
RegisterOperand(PREFIX_ID="z", NAME_ID="21", SHAPE="d"),
|
registerOperand(prefix_id="z", name_id="21", shape="d"),
|
||||||
ImmediateOperand(VALUE_ID=90, TYPE_ID="int"),
|
immediateOperand(value_id=90, type_id="int"),
|
||||||
],
|
],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID=None,
|
comment_id=None,
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE="fcmla z26.d, p0/m, z29.d, z21.d, #90",
|
line="fcmla z26.d, p0/m, z29.d, z21.d, #90",
|
||||||
LINE_NUMBER=8,
|
line_number=8,
|
||||||
)
|
)
|
||||||
instruction_form_9 = InstructionForm(
|
instruction_form_9 = instructionForm(
|
||||||
INSTRUCTION_ID="ccmn",
|
instruction_id="ccmn",
|
||||||
OPERANDS_ID=[
|
operands_id=[
|
||||||
RegisterOperand(PREFIX_ID="x", NAME_ID="11"),
|
registerOperand(prefix_id="x", name_id="11"),
|
||||||
ImmediateOperand(VALUE_ID=1, TYPE_ID="int"),
|
immediateOperand(value_id=1, type_id="int"),
|
||||||
ImmediateOperand(VALUE_ID=3, TYPE_ID="int"),
|
immediateOperand(value_id=3, type_id="int"),
|
||||||
{"condition": "EQ"},
|
{"condition": "EQ"},
|
||||||
],
|
],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID=None,
|
comment_id=None,
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE="ccmn x11, #1, #3, eq",
|
line="ccmn x11, #1, #3, eq",
|
||||||
LINE_NUMBER=9,
|
line_number=9,
|
||||||
)
|
)
|
||||||
|
|
||||||
parsed_1 = self.parser.parse_line(line_comment, 1)
|
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_list_with_index = "ld4 {v0.S, v1.S, v2.S, v3.S}[2]"
|
||||||
instr_range_single = "dummy { z1.d }"
|
instr_range_single = "dummy { z1.d }"
|
||||||
reg_list = [
|
reg_list = [
|
||||||
RegisterOperand(PREFIX_ID="x", NAME_ID="5"),
|
registerOperand(prefix_id="x", name_id="5"),
|
||||||
RegisterOperand(PREFIX_ID="x", NAME_ID="6"),
|
registerOperand(prefix_id="x", name_id="6"),
|
||||||
RegisterOperand(PREFIX_ID="x", NAME_ID="7"),
|
registerOperand(prefix_id="x", name_id="7"),
|
||||||
]
|
]
|
||||||
reg_list_idx = [
|
reg_list_idx = [
|
||||||
RegisterOperand(PREFIX_ID="v", NAME_ID="0", 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="1", shape="S", index=2),
|
||||||
RegisterOperand(PREFIX_ID="v", NAME_ID="2", 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="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)
|
prange = self.parser.parse_line(instr_range)
|
||||||
plist = self.parser.parse_line(instr_list)
|
plist = self.parser.parse_line(instr_list)
|
||||||
@@ -397,22 +397,22 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
# self.assertEqual(p_single.operands, reg_list_single)
|
# self.assertEqual(p_single.operands, reg_list_single)
|
||||||
|
|
||||||
def test_reg_dependency(self):
|
def test_reg_dependency(self):
|
||||||
reg_1_1 = RegisterOperand(PREFIX_ID="b", NAME_ID="1")
|
reg_1_1 = registerOperand(prefix_id="b", name_id="1")
|
||||||
reg_1_2 = RegisterOperand(PREFIX_ID="h", 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_3 = registerOperand(prefix_id="s", name_id="1")
|
||||||
reg_1_4 = RegisterOperand(PREFIX_ID="d", NAME_ID="1")
|
reg_1_4 = registerOperand(prefix_id="d", name_id="1")
|
||||||
reg_1_4 = RegisterOperand(PREFIX_ID="q", 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_1 = registerOperand(prefix_id="w", name_id="2")
|
||||||
reg_2_2 = RegisterOperand(PREFIX_ID="x", 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_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_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_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_v1_4 = registerOperand(prefix_id="v", name_id="11", lanes="2", shape="d")
|
||||||
|
|
||||||
reg_b5 = RegisterOperand(PREFIX_ID="b", NAME_ID="5")
|
reg_b5 = registerOperand(prefix_id="b", name_id="5")
|
||||||
reg_q15 = RegisterOperand(PREFIX_ID="q", NAME_ID="15")
|
reg_q15 = registerOperand(prefix_id="q", name_id="15")
|
||||||
reg_v10 = RegisterOperand(PREFIX_ID="v", NAME_ID="10", LANES="2", SHAPE="s")
|
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_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_1 = [reg_1_1, reg_1_2, reg_1_3, reg_1_4]
|
||||||
reg_2 = [reg_2_1, reg_2_2]
|
reg_2 = [reg_2_1, reg_2_2]
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import unittest
|
|||||||
|
|
||||||
from pyparsing import ParseException
|
from pyparsing import ParseException
|
||||||
|
|
||||||
from osaca.parser import ParserX86ATT, InstructionForm
|
from osaca.parser import ParserX86ATT, instructionForm
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import registerOperand
|
||||||
|
|
||||||
|
|
||||||
class TestParserX86ATT(unittest.TestCase):
|
class TestParserX86ATT(unittest.TestCase):
|
||||||
@@ -165,36 +165,36 @@ class TestParserX86ATT(unittest.TestCase):
|
|||||||
line_directive = ".quad .2.3_2__kmpc_loc_pack.2 #qed"
|
line_directive = ".quad .2.3_2__kmpc_loc_pack.2 #qed"
|
||||||
line_instruction = "lea 2(%rax,%rax), %ecx #12.9"
|
line_instruction = "lea 2(%rax,%rax), %ecx #12.9"
|
||||||
|
|
||||||
instruction_form_1 = InstructionForm(
|
instruction_form_1 = instructionForm(
|
||||||
INSTRUCTION_ID=None,
|
instruction_id=None,
|
||||||
OPERANDS_ID=[],
|
operands_id=[],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID="-- Begin main",
|
comment_id="-- Begin main",
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE="# -- Begin main",
|
line="# -- Begin main",
|
||||||
LINE_NUMBER=1,
|
line_number=1,
|
||||||
)
|
)
|
||||||
instruction_form_2 = InstructionForm(
|
instruction_form_2 = instructionForm(
|
||||||
INSTRUCTION_ID=None,
|
instruction_id=None,
|
||||||
OPERANDS_ID=[],
|
operands_id=[],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID="Preds ..B1.6",
|
comment_id="Preds ..B1.6",
|
||||||
LABEL_ID="..B1.7",
|
label_id="..B1.7",
|
||||||
LINE="..B1.7: # Preds ..B1.6",
|
line="..B1.7: # Preds ..B1.6",
|
||||||
LINE_NUMBER=2,
|
line_number=2,
|
||||||
)
|
)
|
||||||
instruction_form_3 = InstructionForm(
|
instruction_form_3 = instructionForm(
|
||||||
INSTRUCTION_ID=None,
|
instruction_id=None,
|
||||||
OPERANDS_ID=[],
|
operands_id=[],
|
||||||
DIRECTIVE_ID={"name": "quad", "parameters": [".2.3_2__kmpc_loc_pack.2"]},
|
directive_id={"name": "quad", "parameters": [".2.3_2__kmpc_loc_pack.2"]},
|
||||||
COMMENT_ID="qed",
|
comment_id="qed",
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE=".quad .2.3_2__kmpc_loc_pack.2 #qed",
|
line=".quad .2.3_2__kmpc_loc_pack.2 #qed",
|
||||||
LINE_NUMBER=3,
|
line_number=3,
|
||||||
)
|
)
|
||||||
instruction_form_4 = InstructionForm(
|
instruction_form_4 = instructionForm(
|
||||||
INSTRUCTION_ID="lea",
|
instruction_id="lea",
|
||||||
OPERANDS_ID=[
|
operands_id=[
|
||||||
{
|
{
|
||||||
"memory": {
|
"memory": {
|
||||||
"offset": {"value": 2},
|
"offset": {"value": 2},
|
||||||
@@ -205,11 +205,11 @@ class TestParserX86ATT(unittest.TestCase):
|
|||||||
},
|
},
|
||||||
{"register": {"name": "ecx"}},
|
{"register": {"name": "ecx"}},
|
||||||
],
|
],
|
||||||
DIRECTIVE_ID=None,
|
directive_id=None,
|
||||||
COMMENT_ID="12.9",
|
comment_id="12.9",
|
||||||
LABEL_ID=None,
|
label_id=None,
|
||||||
LINE="lea 2(%rax,%rax), %ecx #12.9",
|
line="lea 2(%rax,%rax), %ecx #12.9",
|
||||||
LINE_NUMBER=4,
|
line_number=4,
|
||||||
)
|
)
|
||||||
|
|
||||||
parsed_1 = self.parser.parse_line(line_comment, 1)
|
parsed_1 = self.parser.parse_line(line_comment, 1)
|
||||||
@@ -233,10 +233,10 @@ class TestParserX86ATT(unittest.TestCase):
|
|||||||
register_str_3 = "%xmm1"
|
register_str_3 = "%xmm1"
|
||||||
register_str_4 = "%rip"
|
register_str_4 = "%rip"
|
||||||
|
|
||||||
parsed_reg_1 = RegisterOperand(NAME_ID="rax")
|
parsed_reg_1 = registerOperand(name_id="rax")
|
||||||
parsed_reg_2 = RegisterOperand(NAME_ID="r9")
|
parsed_reg_2 = registerOperand(name_id="r9")
|
||||||
parsed_reg_3 = RegisterOperand(NAME_ID="xmm1")
|
parsed_reg_3 = registerOperand(name_id="xmm1")
|
||||||
parsed_reg_4 = RegisterOperand(NAME_ID="rip")
|
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_1), parsed_reg_1)
|
||||||
self.assertEqual(self.parser.parse_register(register_str_2), parsed_reg_2)
|
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):
|
def test_reg_dependency(self):
|
||||||
reg_a1 = RegisterOperand(NAME_ID="rax")
|
reg_a1 = registerOperand(name_id="rax")
|
||||||
reg_a2 = RegisterOperand(NAME_ID="eax")
|
reg_a2 = registerOperand(name_id="eax")
|
||||||
reg_a3 = RegisterOperand(NAME_ID="ax")
|
reg_a3 = registerOperand(name_id="ax")
|
||||||
reg_a4 = RegisterOperand(NAME_ID="al")
|
reg_a4 = registerOperand(name_id="al")
|
||||||
reg_r11 = RegisterOperand(NAME_ID="r11")
|
reg_r11 = registerOperand(name_id="r11")
|
||||||
reg_r11b = RegisterOperand(NAME_ID="r11b")
|
reg_r11b = registerOperand(name_id="r11b")
|
||||||
reg_r11d = RegisterOperand(NAME_ID="r11d")
|
reg_r11d = registerOperand(name_id="r11d")
|
||||||
reg_r11w = RegisterOperand(NAME_ID="r11w")
|
reg_r11w = registerOperand(name_id="r11w")
|
||||||
reg_xmm1 = RegisterOperand(NAME_ID="xmm1")
|
reg_xmm1 = registerOperand(name_id="xmm1")
|
||||||
reg_ymm1 = RegisterOperand(NAME_ID="ymm1")
|
reg_ymm1 = registerOperand(name_id="ymm1")
|
||||||
reg_zmm1 = RegisterOperand(NAME_ID="zmm1")
|
reg_zmm1 = registerOperand(name_id="zmm1")
|
||||||
|
|
||||||
reg_b1 = RegisterOperand(NAME_ID="rbx")
|
reg_b1 = registerOperand(name_id="rbx")
|
||||||
reg_r15 = RegisterOperand(NAME_ID="r15")
|
reg_r15 = registerOperand(name_id="r15")
|
||||||
reg_xmm2 = RegisterOperand(NAME_ID="xmm2")
|
reg_xmm2 = registerOperand(name_id="xmm2")
|
||||||
reg_ymm3 = RegisterOperand(NAME_ID="ymm3")
|
reg_ymm3 = registerOperand(name_id="ymm3")
|
||||||
|
|
||||||
reg_a = [reg_a1, reg_a2, reg_a3, reg_a4]
|
reg_a = [reg_a1, reg_a2, reg_a3, reg_a4]
|
||||||
reg_r = [reg_r11, reg_r11b, reg_r11d, reg_r11w]
|
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.osaca import get_unmatched_instruction_ratio
|
||||||
from osaca.parser import AttrDict, ParserAArch64, ParserX86ATT
|
from osaca.parser import AttrDict, ParserAArch64, ParserX86ATT
|
||||||
from osaca.semantics import (
|
from osaca.semantics import (
|
||||||
INSTR_FLAGS,
|
INSTR_flags,
|
||||||
ArchSemantics,
|
ArchSemantics,
|
||||||
ISASemantics,
|
ISASemantics,
|
||||||
KernelDG,
|
KernelDG,
|
||||||
MachineModel,
|
MachineModel,
|
||||||
reduce_to_section,
|
reduce_to_section,
|
||||||
)
|
)
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import registerOperand
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import memoryOperand
|
||||||
from osaca.parser.identifier import IdentifierOperand
|
from osaca.parser.identifier import identifierOperand
|
||||||
|
|
||||||
|
|
||||||
class TestSemanticTools(unittest.TestCase):
|
class TestSemanticTools(unittest.TestCase):
|
||||||
@@ -148,31 +148,31 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
self.assertIsNone(test_mm_arm.get_instruction("NOT_IN_DB", []))
|
self.assertIsNone(test_mm_arm.get_instruction("NOT_IN_DB", []))
|
||||||
name_x86_1 = "vaddpd"
|
name_x86_1 = "vaddpd"
|
||||||
operands_x86_1 = [
|
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)
|
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(instr_form_x86_1, test_mm_x86.get_instruction(name_x86_1, operands_x86_1))
|
||||||
self.assertEqual(
|
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"
|
name_arm_1 = "fadd"
|
||||||
operands_arm_1 = [
|
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)
|
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(instr_form_arm_1, test_mm_arm.get_instruction(name_arm_1, operands_arm_1))
|
||||||
self.assertEqual(
|
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(
|
self.assertEqual(
|
||||||
test_mm_arm.get_instruction("b.someNameThatDoesNotExist", [IdentifierOperand()]),
|
test_mm_arm.get_instruction("b.someNameThatDoesNotExist", [identifierOperand()]),
|
||||||
test_mm_arm.get_instruction("b.someOtherName", [IdentifierOperand()]),
|
test_mm_arm.get_instruction("b.someOtherName", [identifierOperand()]),
|
||||||
)
|
)
|
||||||
|
|
||||||
# test full instruction name
|
# test full instruction name
|
||||||
@@ -189,8 +189,8 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
# test get_store_tp
|
# test get_store_tp
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_x86.get_store_throughput(
|
test_mm_x86.get_store_throughput(
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None, INDEX_ID=None, SCALE_ID=1
|
base_id=registerOperand(name_id="x"), offset_ID=None, index_id=None, scale_id=1
|
||||||
)
|
)
|
||||||
)[0].port_pressure,
|
)[0].port_pressure,
|
||||||
[[2, "237"], [2, "4"]],
|
[[2, "237"], [2, "4"]],
|
||||||
@@ -198,11 +198,11 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_x86.get_store_throughput(
|
test_mm_x86.get_store_throughput(
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
BASE_ID=RegisterOperand(PREFIX_ID="NOT_IN_DB"),
|
base_id=registerOperand(prefix_id="NOT_IN_DB"),
|
||||||
OFFSET_ID=None,
|
offset_ID=None,
|
||||||
INDEX_ID="NOT_NONE",
|
index_id="NOT_NONE",
|
||||||
SCALE_ID=1,
|
scale_id=1,
|
||||||
)
|
)
|
||||||
)[0].port_pressure,
|
)[0].port_pressure,
|
||||||
[[1, "23"], [1, "4"]],
|
[[1, "23"], [1, "4"]],
|
||||||
@@ -210,11 +210,11 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_arm.get_store_throughput(
|
test_mm_arm.get_store_throughput(
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
BASE_ID=RegisterOperand(PREFIX_ID="x"),
|
base_id=registerOperand(prefix_id="x"),
|
||||||
OFFSET_ID=None,
|
offset_ID=None,
|
||||||
INDEX_ID=None,
|
index_id=None,
|
||||||
SCALE_ID=1,
|
scale_id=1,
|
||||||
)
|
)
|
||||||
)[0].port_pressure,
|
)[0].port_pressure,
|
||||||
[[2, "34"], [2, "5"]],
|
[[2, "34"], [2, "5"]],
|
||||||
@@ -222,11 +222,11 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_arm.get_store_throughput(
|
test_mm_arm.get_store_throughput(
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
BASE_ID=RegisterOperand(PREFIX_ID="NOT_IN_DB"),
|
base_id=registerOperand(prefix_id="NOT_IN_DB"),
|
||||||
OFFSET_ID=None,
|
offset_ID=None,
|
||||||
INDEX_ID=None,
|
index_id=None,
|
||||||
SCALE_ID=1,
|
scale_id=1,
|
||||||
)
|
)
|
||||||
)[0].port_pressure,
|
)[0].port_pressure,
|
||||||
[[1, "34"], [1, "5"]],
|
[[1, "34"], [1, "5"]],
|
||||||
@@ -234,19 +234,19 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
# test get_store_lt
|
# test get_store_lt
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_x86.get_store_latency(
|
test_mm_x86.get_store_latency(
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None, INDEX_ID=None, SCALE_ID=1
|
base_id=registerOperand(name_id="x"), offset_ID=None, index_id=None, scale_id=1
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_arm.get_store_latency(
|
test_mm_arm.get_store_latency(
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
BASE_ID=RegisterOperand(PREFIX_ID="x"),
|
base_id=registerOperand(prefix_id="x"),
|
||||||
OFFSET_ID=None,
|
offset_ID=None,
|
||||||
INDEX_ID=None,
|
index_id=None,
|
||||||
SCALE_ID=1,
|
scale_id=1,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
0,
|
0,
|
||||||
@@ -258,8 +258,8 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
# test default load tp
|
# test default load tp
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_x86.get_load_throughput(
|
test_mm_x86.get_load_throughput(
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None, INDEX_ID=None, SCALE_ID=1
|
base_id=registerOperand(name_id="x"), offset_ID=None, index_id=None, scale_id=1
|
||||||
)
|
)
|
||||||
)[0].port_pressure,
|
)[0].port_pressure,
|
||||||
[[1, "23"], [1, ["2D", "3D"]]],
|
[[1, "23"], [1, ["2D", "3D"]]],
|
||||||
@@ -389,7 +389,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
dg.get_dependent_instruction_forms()
|
dg.get_dependent_instruction_forms()
|
||||||
# test dot creation
|
# test dot creation
|
||||||
dg.export_graph(filepath="/dev/null")
|
dg.export_graph(filepath="/dev/null")
|
||||||
|
|
||||||
def test_kernelDG_AArch64(self):
|
def test_kernelDG_AArch64(self):
|
||||||
dg = KernelDG(
|
dg = KernelDG(
|
||||||
self.kernel_AArch64,
|
self.kernel_AArch64,
|
||||||
@@ -421,7 +421,6 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
# test dot creation
|
# test dot creation
|
||||||
dg.export_graph(filepath="/dev/null")
|
dg.export_graph(filepath="/dev/null")
|
||||||
|
|
||||||
|
|
||||||
def test_kernelDG_SVE(self):
|
def test_kernelDG_SVE(self):
|
||||||
KernelDG(
|
KernelDG(
|
||||||
self.kernel_aarch64_SVE,
|
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_2)
|
||||||
semantics_hld.add_semantics(kernel_hld_3)
|
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 = 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_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_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, 1)
|
||||||
self.assertEqual(num_hidden_loads_2, 0)
|
self.assertEqual(num_hidden_loads_2, 0)
|
||||||
self.assertEqual(num_hidden_loads_3, 1)
|
self.assertEqual(num_hidden_loads_3, 1)
|
||||||
@@ -463,7 +462,6 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
with self.assertRaises(NotImplementedError):
|
with self.assertRaises(NotImplementedError):
|
||||||
dg.get_loopcarried_dependencies()
|
dg.get_loopcarried_dependencies()
|
||||||
|
|
||||||
|
|
||||||
def test_loop_carried_dependency_aarch64(self):
|
def test_loop_carried_dependency_aarch64(self):
|
||||||
dg = KernelDG(
|
dg = KernelDG(
|
||||||
self.kernel_aarch64_memdep,
|
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)],
|
[(4, 1.0), (5, 1.0), (10, 1.0), (11, 1.0), (12, 1.0)],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_loop_carried_dependency_x86(self):
|
def test_loop_carried_dependency_x86(self):
|
||||||
lcd_id = "8"
|
lcd_id = "8"
|
||||||
lcd_id2 = "5"
|
lcd_id2 = "5"
|
||||||
@@ -571,8 +568,8 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
def test_is_read_is_written_x86(self):
|
def test_is_read_is_written_x86(self):
|
||||||
# independent form HW model
|
# independent form HW model
|
||||||
dag = KernelDG(self.kernel_x86, self.parser_x86, None, None)
|
dag = KernelDG(self.kernel_x86, self.parser_x86, None, None)
|
||||||
reg_rcx = RegisterOperand(NAME_ID="rcx")
|
reg_rcx = registerOperand(name_id="rcx")
|
||||||
reg_ymm1 = RegisterOperand(NAME_ID="ymm1")
|
reg_ymm1 = registerOperand(name_id="ymm1")
|
||||||
|
|
||||||
instr_form_r_c = self.parser_x86.parse_line("vmovsd %xmm0, (%r15,%rcx,8)")
|
instr_form_r_c = self.parser_x86.parse_line("vmovsd %xmm0, (%r15,%rcx,8)")
|
||||||
self.semantics_csx.assign_src_dst(instr_form_r_c)
|
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):
|
def test_is_read_is_written_AArch64(self):
|
||||||
# independent form HW model
|
# independent form HW model
|
||||||
dag = KernelDG(self.kernel_AArch64, self.parser_AArch64, None, None)
|
dag = KernelDG(self.kernel_AArch64, self.parser_AArch64, None, None)
|
||||||
reg_x1 = RegisterOperand(PREFIX_ID="x", NAME_ID="1")
|
reg_x1 = registerOperand(prefix_id="x", name_id="1")
|
||||||
reg_w1 = RegisterOperand(PREFIX_ID="w", NAME_ID="1")
|
reg_w1 = registerOperand(prefix_id="w", name_id="1")
|
||||||
reg_d1 = RegisterOperand(PREFIX_ID="d", NAME_ID="1")
|
reg_d1 = registerOperand(prefix_id="d", name_id="1")
|
||||||
reg_q1 = RegisterOperand(PREFIX_ID="q", 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_v1 = registerOperand(prefix_id="v", name_id="1", lanes="2", shape="d")
|
||||||
regs = [reg_d1, reg_q1, reg_v1]
|
regs = [reg_d1, reg_q1, reg_v1]
|
||||||
regs_gp = [reg_w1, reg_x1]
|
regs_gp = [reg_w1, reg_x1]
|
||||||
|
|
||||||
@@ -671,11 +668,11 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
|
|
||||||
def test_MachineModel_getter(self):
|
def test_MachineModel_getter(self):
|
||||||
sample_operands = [
|
sample_operands = [
|
||||||
MemoryOperand(
|
memoryOperand(
|
||||||
OFFSET_ID=None,
|
offset_ID=None,
|
||||||
BASE_ID=RegisterOperand(NAME_ID="r12"),
|
base_id=registerOperand(name_id="r12"),
|
||||||
INDEX_ID=RegisterOperand(NAME_ID="rcx"),
|
index_id=registerOperand(name_id="rcx"),
|
||||||
SCALE_ID=8,
|
scale_id=8,
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.assertIsNone(self.machine_model_csx.get_instruction("GETRESULT", sample_operands))
|
self.assertIsNone(self.machine_model_csx.get_instruction("GETRESULT", sample_operands))
|
||||||
|
|||||||
Reference in New Issue
Block a user