Compare commits

...

4 Commits

Author SHA1 Message Date
JanLJL
aca5511d6a Black formatting 2024-05-02 17:04:56 +02:00
JanLJL
c9e38631d1 Flake8 formatting 2024-05-02 17:00:12 +02:00
JanLJL
d623115b1b formattign 2024-05-02 16:30:11 +02:00
JanLJL
5da00d0ae6 moved get_full_instruction_name() from HardwareModel to DBInterface 2024-05-02 16:25:41 +02:00
14 changed files with 69 additions and 61 deletions

View File

@@ -1,4 +1,5 @@
"""Open Source Architecture Code Analyzer"""
name = "osaca"
__version__ = "0.5.3"

View File

@@ -602,6 +602,12 @@ def _get_full_instruction_name(instruction_form):
if op.shape is not None:
op_attrs.append("shape:" + op.shape)
operands.append("{}({})".format("register", ",".join(op_attrs)))
elif isinstance(op, MemoryOperand):
operands.append("mem")
elif isinstance(op, ImmediateOperand):
operands.append("imd")
else:
operands.append("<op>")
return "{} {}".format(instruction_form["name"].lower(), ",".join(operands))

View File

@@ -85,9 +85,11 @@ class Frontend(object):
self._get_port_pressure(
instruction_form.port_pressure, port_len, separator=sep_list
),
self._get_flag_symbols(instruction_form.flags)
if instruction_form.mnemonic is not None
else " ",
(
self._get_flag_symbols(instruction_form.flags)
if instruction_form.mnemonic is not None
else " "
),
instruction_form.line.strip().replace("\t", " "),
)
line = line if show_lineno else col_sep + col_sep.join(line.split(col_sep)[1:])
@@ -366,9 +368,11 @@ class Frontend(object):
cp_kernel if line_number in cp_lines else None,
lcd_lines.get(line_number),
),
self._get_flag_symbols(instruction_form.flags)
if instruction_form.mnemonic is not None
else " ",
(
self._get_flag_symbols(instruction_form.flags)
if instruction_form.mnemonic is not None
else " "
),
instruction_form.line.strip().replace("\t", " "),
)
s += "\n"

View File

@@ -3,6 +3,7 @@ Collection of parsers supported by OSACA.
Only the parser below will be exported, so please add new parsers to __all__.
"""
from .base_parser import BaseParser
from .parser_x86att import ParserX86ATT
from .parser_AArch64 import ParserAArch64

View File

@@ -36,8 +36,8 @@ class ImmediateOperand(Operand):
return self._imd_type
@imd_type.setter
def imd_type(self, type):
self._imd_type = imd_type
def imd_type(self, itype):
self._imd_type = itype
@identifier.setter
def identifier(self, identifier):

View File

@@ -12,7 +12,6 @@ from osaca.parser.register import RegisterOperand
from osaca.parser.identifier import IdentifierOperand
from osaca.parser.immediate import ImmediateOperand
from osaca.parser.condition import ConditionOperand
from osaca.parser.flag import FlagOperand
from osaca.parser.prefetch import PrefetchOperand

View File

@@ -7,14 +7,12 @@ import pyparsing as pp
from osaca.parser import BaseParser
from osaca.parser.instruction_form import InstructionForm
from osaca.parser.operand import Operand
from osaca.parser.directive import DirectiveOperand
from osaca.parser.memory import MemoryOperand
from osaca.parser.label import LabelOperand
from osaca.parser.register import RegisterOperand
from osaca.parser.identifier import IdentifierOperand
from osaca.parser.immediate import ImmediateOperand
from osaca.parser.flag import FlagOperand
class ParserX86ATT(BaseParser):

View File

@@ -3,6 +3,7 @@ Tools for semantic analysis of parser result.
Only the classes below will be exported, so please add new semantic tools to __all__.
"""
from .isa_semantics import ISASemantics, INSTR_FLAGS
from .arch_semantics import ArchSemantics
from .hw_model import MachineModel

View File

@@ -11,7 +11,6 @@ from pathlib import Path
import ruamel.yaml
from osaca import __version__, utils
from copy import deepcopy
from osaca.parser import ParserX86ATT
from osaca.parser.instruction_form import InstructionForm
from osaca.parser.operand import Operand
@@ -125,9 +124,9 @@ class MachineModel(object):
new_iform = InstructionForm(
mnemonic=iform["name"].upper() if "name" in iform else None,
operands=iform["operands"] if "operands" in iform else [],
hidden_operands=iform["hidden_operands"]
if "hidden_operands" in iform
else [],
hidden_operands=(
iform["hidden_operands"] if "hidden_operands" in iform else []
),
directive_id=iform["directive"] if "directive" in iform else None,
comment_id=iform["comment"] if "comment" in iform else None,
line=iform["line"] if "line" in iform else None,
@@ -137,14 +136,16 @@ class MachineModel(object):
uops=iform["uops"] if "uops" in iform else None,
port_pressure=iform["port_pressure"] if "port_pressure" in iform else None,
operation=iform["operation"] if "operation" in iform else None,
breaks_dependency_on_equal_operands=iform[
"breaks_dependency_on_equal_operands"
]
if "breaks_dependency_on_equal_operands" in iform
else False,
semantic_operands=iform["semantic_operands"]
if "semantic_operands" in iform
else {"source": [], "destination": [], "src_dst": []},
breaks_dependency_on_equal_operands=(
iform["breaks_dependency_on_equal_operands"]
if "breaks_dependency_on_equal_operands" in iform
else False
),
semantic_operands=(
iform["semantic_operands"]
if "semantic_operands" in iform
else {"source": [], "destination": [], "src_dst": []}
),
)
# List containing classes with same name/instruction
self._data["instruction_forms_dict"][iform["name"]].append(new_iform)
@@ -261,10 +262,10 @@ class MachineModel(object):
elif o["class"] == "prfop":
new_operands.append(
PrefetchOperand(
type_id=o["type"] if "type" in o else None,
target=o["target"] if "target" in o else None,
policy=o["policy"] if "policy" in o else None,
)
type_id=o["type"] if "type" in o else None,
target=o["target"] if "target" in o else None,
policy=o["policy"] if "policy" in o else None,
)
)
else:
new_operands.append(o)
@@ -427,21 +428,6 @@ class MachineModel(object):
data_ports = [x for x in filter(data_port.match, self._data["ports"])]
return data_ports
@staticmethod
def get_full_instruction_name(instruction_form):
"""Get one instruction name string including the mnemonic and all operands."""
operands = []
for op in instruction_form.operands:
op_attrs = []
if op.name is not None:
op_attrs.append("name:" + op.name)
if op.prefix is not None:
op_attrs.append("prefix:" + op.prefix)
if op.shape is not None:
op_attrs.append("shape:" + op.shape)
operands.append("{}({})".format("register", ",".join(op_attrs)))
return "{} {}".format(instruction_form.mnemonic.lower(), ",".join(operands))
@staticmethod
def get_isa_for_arch(arch):
"""Return ISA for given micro-arch ``arch``."""

View File

@@ -287,17 +287,13 @@ class ISASemantics(object):
dict_key = (
"src_dst"
if op.source and op.destination
else "source"
if op.source
else "destination"
else "source" if op.source else "destination"
)
else:
dict_key = (
"src_dst"
if op["source"] and op["destination"]
else "source"
if op["source"]
else "destination"
else "source" if op["source"] else "destination"
)
op_dict[dict_key].append(op)

View File

@@ -12,7 +12,6 @@ from osaca.semantics import INSTR_FLAGS, ArchSemantics, MachineModel
from osaca.parser.memory import MemoryOperand
from osaca.parser.register import RegisterOperand
from osaca.parser.immediate import ImmediateOperand
from osaca.parser.operand import Operand
from osaca.parser.flag import FlagOperand

View File

@@ -146,6 +146,34 @@ class TestDBInterface(unittest.TestCase):
instr_3 = ["vfmadd132pd", (True, "")]
self.assertEqual(dbi._scrape_from_felixcloutier(instr_3[0]), instr_3[1])
def test_human_readable_instr_name(self):
instr_form_x86 = dict(
name="vaddpd",
operands=[
RegisterOperand(name="xmm"),
RegisterOperand(name="xmm"),
RegisterOperand(name="xmm"),
],
)
instr_form_arm = dict(
name="fadd",
operands=[
RegisterOperand(prefix="v", shape="s"),
RegisterOperand(prefix="v", shape="s"),
RegisterOperand(prefix="v", shape="s"),
],
)
# test full instruction name
self.assertEqual(
_get_full_instruction_name(instr_form_x86),
"vaddpd register(name:xmm),register(name:xmm),register(name:xmm)",
)
self.assertEqual(
_get_full_instruction_name(instr_form_arm),
"fadd register(prefix:v,shape:s),register(prefix:v,shape:s),"
+ "register(prefix:v,shape:s)",
)
##################
# Helper functions
##################

View File

@@ -234,7 +234,7 @@ class TestParserAArch64(unittest.TestCase):
instruction_form_5 = InstructionForm(
mnemonic="prfm",
operands=[
PrefetchOperand(type_id=["PLD"],target=["L1"],policy=["KEEP"]),
PrefetchOperand(type_id=["PLD"], target=["L1"], policy=["KEEP"]),
MemoryOperand(
offset=ImmediateOperand(value=2048),
base=RegisterOperand(prefix="x", name="26"),

View File

@@ -175,17 +175,6 @@ class TestSemanticTools(unittest.TestCase):
test_mm_arm.get_instruction("b.someOtherName", [IdentifierOperand()]),
)
# test full instruction name
self.assertEqual(
MachineModel.get_full_instruction_name(instr_form_x86_1),
"vaddpd register(name:xmm),register(name:xmm),register(name:xmm)",
)
self.assertEqual(
MachineModel.get_full_instruction_name(instr_form_arm_1),
"fadd register(prefix:v,shape:s),register(prefix:v,shape:s),"
+ "register(prefix:v,shape:s)",
)
# test get_store_tp
self.assertEqual(
test_mm_x86.get_store_throughput(