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

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

View File

@@ -7,12 +7,12 @@ from .attr_dict import AttrDict
from .base_parser import BaseParser
from .parser_x86att import ParserX86ATT
from .parser_AArch64 import ParserAArch64
from .instruction_form import InstructionForm
from .instruction_form import instructionForm
from .operand import Operand
__all__ = [
"Operand",
"InstructionForm",
"instructionForm",
"AttrDict",
"BaseParser",
"ParserX86ATT",

View File

@@ -6,16 +6,16 @@ import re
class BaseParser(object):
# Identifiers for operand types
COMMENT_ID = "comment"
DIRECTIVE_ID = "directive"
comment_id = "comment"
directive_id = "directive"
IMMEDIATE_ID = "immediate"
LABEL_ID = "label"
label_id = "label"
IDENTIFIER_ID = "identifier"
MEMORY_ID = "memory"
REGISTER_ID = "register"
SEGMENT_EXT_ID = "segment_extension"
INSTRUCTION_ID = "instruction"
OPERANDS_ID = "operands"
segment_ext_id = "segment_extension"
instruction_id = "instruction"
operands_id = "operands"
_parser_constructed = False
def __init__(self):

View File

@@ -3,49 +3,49 @@
from osaca.parser.operand import Operand
class DirectiveOperand(Operand):
def __init__(self, NAME_ID=None, PARAMETER_ID=None, COMMENT_ID=None):
super().__init__(NAME_ID)
self._PARAMETER_ID = PARAMETER_ID
self._COMMENT_ID = COMMENT_ID
class directiveOperand(Operand):
def __init__(self, name_id=None, parameter_id=None, comment_id=None):
super().__init__(name_id)
self._parameter_id = parameter_id
self._comment_id = comment_id
@property
def parameters(self):
return self._PARAMETER_ID
return self._parameter_id
@property
def comment(self):
return self._COMMENT_ID
return self._comment_id
def __iter__(self):
return self
def __next__(self):
if not self._COMMENT_ID:
if not self._comment_id:
raise StopIteration
return self._COMMENT_ID.pop(0)
return self._comment_id.pop(0)
@parameters.setter
def parameters(self, parameters):
self._PARAMETER_ID = parameters
self._parameter_id = parameters
@comment.setter
def comment(self, comment):
self._COMMENT_ID = comment
self._comment_id = comment
def __eq__(self, other):
if isinstance(other, DirectiveOperand):
if isinstance(other, directiveOperand):
return (
self._NAME_ID == other._NAME_ID
and self._PARAMETER_ID == other._PARAMETER_ID
and self._COMMENT_ID == other._COMMENT_ID
self._name_id == other._name_id
and self._parameter_id == other._parameter_id
and self._comment_id == other._comment_id
)
elif isinstance(other, dict):
return self._NAME_ID == other["name"] and self._PARAMETER_ID == other["parameters"]
return self._name_id == other["name"] and self._parameter_id == other["parameters"]
return False
def __str__(self):
return f"Directive(NAME_ID={self._NAME_ID}, PARAMETERS={self._PARAMETER_ID}, COMMENT={self._COMMENT_ID})"
return f"Directive(name_id={self._name_id}, parameters={self._parameter_id}, comment={self._comment_id})"
def __repr__(self):
return f"DirectiveOperand(NAME_ID={self._NAME_ID}, PARAMETERS={self._PARAMETER_ID}, COMMENT={self._COMMENT_ID})"
return f"directiveOperand(name_id={self._name_id}, parameters={self._parameter_id}, comment={self._comment_id})"

View File

@@ -3,32 +3,32 @@
from osaca.parser.operand import Operand
class IdentifierOperand(Operand):
def __init__(self, name=None, OFFSET=None, RELOCATION=None):
class identifierOperand(Operand):
def __init__(self, name=None, offset=None, relocation=None):
super().__init__(name)
self._OFFSET = OFFSET
self._RELOCATION = RELOCATION
self._offset = offset
self._relocation = relocation
@property
def offset(self):
return self._OFFSET
return self._offset
@offset.setter
def offset(self, offset):
self._OFFSET = offset
self._offset = offset
@property
def relocation(self):
return self._RELOCATION
return self._relocation
@relocation.setter
def relocation(self, relocation):
self._RELOCATION = relocation
self._relocation = relocation
def __str__(self):
return (
f"IdentifierOperand({self.name}, offset={self.offset}, relocation={self.relocation})"
f"identifierOperand({self.name}, offset={self.offset}, relocation={self.relocation})"
)
def __repr__(self):
return f"IdentifierOperand(name={self.name}, offset={self.offset}, relocation={self.relocation})"
return f"identifierOperand(name={self.name}, offset={self.offset}, relocation={self.relocation})"

View File

@@ -3,90 +3,72 @@
from osaca.parser.operand import Operand
class ImmediateOperand(Operand):
class immediateOperand(Operand):
def __init__(
self,
IDENTIFIER_ID=None,
TYPE_ID=None,
VALUE_ID=None,
SHIFT_ID=None,
SOURCE=False,
DESTINATION=False
identifier_id=None,
type_id=None,
value_id=None,
shift_id=None,
source=False,
destination=False,
):
super().__init__(str(VALUE_ID))
self._IDENTIFIER_ID = IDENTIFIER_ID
self._TYPE_ID = TYPE_ID
self._VALUE_ID = VALUE_ID
self._SHIFT_ID = SHIFT_ID
self._SOURCE = SOURCE
self._DESTINATION = DESTINATION
super().__init__(str(value_id), source, destination)
self._identifier_id = identifier_id
self._type_id = type_id
self._value_id = value_id
self._shift_id = shift_id
@property
def identifier(self):
return self._IDENTIFIER_ID
return self._identifier_id
@property
def type(self):
return self._TYPE_ID
return self._type_id
@property
def value(self):
return self._VALUE_ID
return self._value_id
@property
def shift(self):
return self._TYPE_ID
@property
def source(self):
return self._SOURCE
@source.setter
def source(self, source):
self._SOURCE = source
@property
def destination(self):
return self._DESTINATION
@destination.setter
def destination(self, destination):
self._DESTINATION = destination
return self._type_id
@identifier.setter
def identifier(self, identifier):
self._IDENTIFIER_ID = identifier
self._identifier_id = identifier
@type.setter
def type(self, type):
self._TYPE_ID = type
self._type_id = type
@value.setter
def value(self, value):
self._VALUE_ID = value
self._value_id = value
@shift.setter
def index(self, shift):
self._SHIFT_ID = shift
self._shift_id = shift
def __str__(self):
return (
f"ImmediateOperand(IDENTIFIER_ID={self._IDENTIFIER_ID}, TYPE_ID={self._TYPE_ID}, "
f"VALUE_ID={self._VALUE_ID}, SHIFT_ID={self._SHIFT_ID})"
f"immediateOperand(identifier_id={self._identifier_id}, type_id={self._type_id}, "
f"value_id={self._value_id}, shift_id={self._shift_id})"
)
def __repr__(self):
return (
f"ImmediateOperand(IDENTIFIER_ID={self._IDENTIFIER_ID}, TYPE_ID={self._TYPE_ID}, "
f"VALUE_ID={self._VALUE_ID}, SHIFT_ID={self._SHIFT_ID})"
f"immediateOperand(identifier_id={self._identifier_id}, type_id={self._type_id}, "
f"value_id={self._value_id}, shift_id={self._shift_id})"
)
def __eq__(self, other):
if isinstance(other, ImmediateOperand):
if isinstance(other, immediateOperand):
return (
self._IDENTIFIER_ID == other._IDENTIFIER_ID
and self._TYPE_ID == other._TYPE_ID
and self._VALUE_ID == other._VALUE_ID
and self._SHIFT_ID == other._SHIFT_ID
self._identifier_id == other._identifier_id
and self._type_id == other._type_id
and self._value_id == other._value_id
and self._shift_id == other._shift_id
)
return False

View File

@@ -1,200 +1,200 @@
#!/usr/bin/env python3
from osaca.parser.directive import DirectiveOperand
from osaca.parser.directive import directiveOperand
class InstructionForm:
class instructionForm:
def __init__(
self,
INSTRUCTION_ID=None,
OPERANDS_ID=[],
HIDDEN_OPERANDS=[],
DIRECTIVE_ID=None,
COMMENT_ID=None,
LABEL_ID=None,
LINE=None,
LINE_NUMBER=None,
SEMANTIC_OPERANDS={"source": [], "destination": [], "src_dst": []},
THROUGHPUT = None,
LATENCY = None,
UOPS = None,
PORT_PRESSURE = None,
BREAKS_DEP = False
instruction_id=None,
operands_id=[],
hidden_operands=[],
directive_id=None,
comment_id=None,
label_id=None,
line=None,
line_number=None,
semantic_operands={"source": [], "destination": [], "src_dst": []},
throughput=None,
latency=None,
uops=None,
port_pressure=None,
breaks_dep=False,
):
self._INSTRUCTION_ID = INSTRUCTION_ID
self._OPERANDS_ID = OPERANDS_ID
self._HIDDEN_OPERANDS = HIDDEN_OPERANDS
self._DIRECTIVE_ID = DIRECTIVE_ID
self._COMMENT_ID = COMMENT_ID
self._LABEL_ID = LABEL_ID
self._LINE = LINE
self._LINE_NUMBER = LINE_NUMBER
self._instruction_id = instruction_id
self._operands_id = operands_id
self._hidden_operands = hidden_operands
self._directive_id = directive_id
self._comment_id = comment_id
self._label_id = label_id
self._line = line
self._line_number = line_number
self._SEMANTIC_OPERANDS = SEMANTIC_OPERANDS
self._UOPS = UOPS
self._BREAKS_DEP = BREAKS_DEP
self._semantic_operands = semantic_operands
self._uops = uops
self._breaks_dep = breaks_dep
# self.semantic_operands = {"source": [], "destination": [], "src_dst": []}
self._LATENCY = LATENCY
self._THROUGHPUT = THROUGHPUT
self._LATENCY_CP = []
self._LATENCY_LCD = []
self._LATENCY_WO_LOAD = None
self._PORT_PRESSURE = PORT_PRESSURE
self._PORT_UOPS = []
self._FLAGS = []
self._latency = latency
self._throughput = throughput
self._latency_cp = []
self._latency_lcd = []
self._latency_wo_load = None
self._port_pressure = port_pressure
self._port_uops = []
self._flags = []
@property
def semantic_operands(self):
return self._SEMANTIC_OPERANDS
return self._semantic_operands
@property
def instruction(self):
return self._INSTRUCTION_ID
return self._instruction_id
@property
def label(self):
return self._LABEL_ID
return self._label_id
@property
def comment(self):
return self._COMMENT_ID
return self._comment_id
@property
def directive(self):
return self._DIRECTIVE_ID
return self._directive_id
@property
def line_number(self):
return self._LINE_NUMBER
return self._line_number
@property
def line(self):
return self._LINE
return self._line
@property
def operands(self):
return self._OPERANDS_ID
return self._operands_id
@property
def hidden_operands(self):
return self._HIDDEN_OPERANDS
return self._hidden_operands
@property
def port_pressure(self):
return self._PORT_PRESSURE
return self._port_pressure
@property
def port_uops(self):
return self._PORT_UOPS
return self._port_uops
@property
def flags(self):
return self._FLAGS
return self._flags
@property
def uops(self):
return self._UOPS
return self._uops
@property
def throughput(self):
return self._THROUGHPUT
return self._throughput
@property
def latency(self):
return self._LATENCY
return self._latency
@property
def latency_wo_load(self):
return self._LATENCY_WO_LOAD
return self._latency_wo_load
@property
def breaks_dep(self):
return self._BREAKS_DEP
return self._breaks_dep
@semantic_operands.setter
def semantic_operands(self, semantic_operands):
self._SEMANTIC_OPERANDS = semantic_operands
self._semantic_operands = semantic_operands
@directive.setter
def directive(self, directive):
self._DIRECTIVE_ID = directive
self._directive_id = directive
@line_number.setter
def line_number(self, line_number):
self._LINE_NUMBER = line_number
self._line_number = line_number
@line.setter
def line(self, line):
self._LINE = line
self._line = line
@operands.setter
def operands(self, operands):
self._OPERANDS_ID = operands
self._operands_id = operands
@hidden_operands.setter
def hidden_operands(self, hidden_operands):
self._HIDDEN_OPERANDS = hidden_operands
self._hidden_operands = hidden_operands
@breaks_dep.setter
def breaks_dep(self, boolean):
self._BREAKS_DEP = boolean
self._breaks_dep = boolean
@instruction.setter
def instruction(self, instruction):
self._INSTRUCTION_ID = instruction
self._instruction_id = instruction
@label.setter
def label(self, label):
self._LABEL_ID = label
self._label_id = label
@comment.setter
def comment(self, comment):
self._COMMENT_ID = comment
self._comment_id = comment
@port_pressure.setter
def port_pressure(self, port_pressure):
self._PORT_PRESSURE = port_pressure
self._port_pressure = port_pressure
@port_uops.setter
def port_uops(self, port_uops):
self._PORT_UOPS = port_uops
self._port_uops = port_uops
@flags.setter
def flags(self, flags):
self._FLAGS = flags
self._flags = flags
@uops.setter
def uops(self, uops):
self._UOPS = uops
self._uops = uops
@throughput.setter
def throughput(self, throughput):
self._THROUGHPUT = throughput
self._throughput = throughput
@latency.setter
def latency(self, latency):
self._LATENCY = latency
self._latency = latency
@latency_wo_load.setter
def latency_wo_load(self, latency_wo_load):
self._LATENCY_WO_LOAD = latency_wo_load
self._latency_wo_load = latency_wo_load
def __repr__(self):
return f"InstructionForm(INSTRUCTION_ID={self._INSTRUCTION_ID}, OPERANDS_ID={self._OPERANDS_ID}, DIRECTIVE_ID={self._DIRECTIVE_ID}, COMMENT_ID={self._COMMENT_ID}, LABEL_ID={self._LABEL_ID}, LINE={self._LINE}, LINE_NUMBER={self._LINE_NUMBER}, SEMANTIC_OPERANDS={self._SEMANTIC_OPERANDS})"
return f"instructionForm(instruction_id={self._instruction_id}, operands_id={self._operands_id}, directive_id={self._directive_id}, comment_id={self._comment_id}, label_id={self._label_id}, line={self._line}, line_number={self._line_number}, semantic_operands={self._semantic_operands})"
def __str__(self):
return f"Instruction: {self._INSTRUCTION_ID}\nOperands: {self._OPERANDS_ID}\nDirective: {self._DIRECTIVE_ID}\nComment: {self._COMMENT_ID}\nLabel: {self._LABEL_ID}\nLine: {self._LINE}\nLine Number: {self._LINE_NUMBER}\nSemantic Operands: {self._SEMANTIC_OPERANDS}\nFlags: {self._FLAGS}"
return f"Instruction: {self._instruction_id}\nOperands: {self._operands_id}\nDirective: {self._directive_id}\nComment: {self._comment_id}\nLabel: {self._label_id}\nLine: {self._line}\nLine Number: {self._line_number}\nSemantic Operands: {self._semantic_operands}\nFlags: {self._flags}"
def __eq__(self, other):
if isinstance(other, InstructionForm):
if isinstance(other, instructionForm):
return (
self._INSTRUCTION_ID == other._INSTRUCTION_ID
and self._OPERANDS_ID == other._OPERANDS_ID
and self._DIRECTIVE_ID == other._DIRECTIVE_ID
and self._COMMENT_ID == other._COMMENT_ID
and self._LABEL_ID == other._LABEL_ID
and self._LINE == other._LINE
and self._LINE_NUMBER == other._LINE_NUMBER
and self._SEMANTIC_OPERANDS == other._SEMANTIC_OPERANDS
self._instruction_id == other._instruction_id
and self._operands_id == other._operands_id
and self._directive_id == other._directive_id
and self._comment_id == other._comment_id
and self._label_id == other._label_id
and self._line == other._line
and self._line_number == other._line_number
and self._semantic_operands == other._semantic_operands
)
return False

View File

@@ -3,29 +3,29 @@
from osaca.parser.operand import Operand
class LabelOperand(Operand):
def __init__(self, NAME_ID=None, COMMENT_ID=None):
super().__init__(NAME_ID)
self._COMMENT_ID = COMMENT_ID
class labelOperand(Operand):
def __init__(self, name_id=None, comment_id=None):
super().__init__(name_id)
self._comment_id = comment_id
@property
def comment(self):
return self._COMMENT_ID
return self._comment_id
@comment.setter
def comment(self, comment):
self._COMMENT_ID = comment
self._comment_id = comment
def __iter__(self):
return self
def __next__(self):
if not self._COMMENT_ID:
if not self._comment_id:
raise StopIteration
return self._COMMENT_ID.pop(0)
return self._comment_id.pop(0)
def __str__(self):
return f"LabelOperand(NAME_ID={self._NAME_ID}, COMMENT={self._COMMENT_ID})"
return f"labelOperand(name_id={self._name_id}, comment={self._comment_id})"
def __repr__(self):
return f"LabelOperand(NAME_ID={self._NAME_ID}, COMMENT={self._COMMENT_ID})"
return f"labelOperand(name_id={self._name_id}, comment={self._comment_id})"

View File

@@ -3,41 +3,39 @@
from osaca.parser.operand import Operand
class MemoryOperand(Operand):
class memoryOperand(Operand):
def __init__(
self,
OFFSET_ID=None,
BASE_ID=None,
INDEX_ID=None,
SCALE_ID=1,
SEGMENT_EXT_ID=None,
MASK=None,
PRE_INDEXED=False,
POST_INDEXED=False,
INDEXED_VAL=None,
PORT_PRESSURE=[],
DST=None,
SOURCE=False,
DESTINATION=False,
offset_ID=None,
base_id=None,
index_id=None,
scale_id=1,
segment_ext_id=None,
mask=None,
pre_indexed=False,
post_indexed=False,
indexed_val=None,
port_pressure=[],
dst=None,
source=False,
destination=False,
):
super().__init__("memory")
self._OFFSET_ID = OFFSET_ID
self._BASE_ID = BASE_ID
self._INDEX_ID = INDEX_ID
self._SCALE_ID = SCALE_ID
self._SEGMENT_EXT_ID = SEGMENT_EXT_ID
self._MASK = MASK
self._PRE_INDEXED = PRE_INDEXED
self._POST_INDEXED = POST_INDEXED
self._INDEXED_VAL = INDEXED_VAL
self._PORT_PRESSURE = PORT_PRESSURE
self._DST = DST
self._SOURCE = SOURCE
self._DESTINATION = DESTINATION
super().__init__("memory", source, destination)
self._offset_ID = offset_ID
self._base_id = base_id
self._index_id = index_id
self._scale_id = scale_id
self._segment_ext_id = segment_ext_id
self._mask = mask
self._pre_indexed = pre_indexed
self._post_indexed = post_indexed
self._indexed_val = indexed_val
self._port_pressure = port_pressure
self._dst = dst
@property
def offset(self):
return self._OFFSET_ID
return self._offset_ID
@property
def immediate(self):
@@ -45,135 +43,119 @@ class MemoryOperand(Operand):
@property
def base(self):
return self._BASE_ID
return self._base_id
@property
def index(self):
return self._INDEX_ID
return self._index_id
@property
def scale(self):
return self._SCALE_ID
return self._scale_id
@property
def segment_ext_id(self):
return self._SEGMENT_EXT_ID
return self._segment_ext_id
@property
def mask(self):
return self._MASK
return self._mask
@property
def pre_indexed(self):
return self._PRE_INDEXED
return self._pre_indexed
@property
def post_indexed(self):
return self._POST_INDEXED
return self._post_indexed
@property
def indexed_val(self):
return self._INDEXED_VAL
return self._indexed_val
@property
def port_pressure(self):
return self._PORT_PRESSURE
return self._port_pressure
@property
def dst(self):
return self._DST
return self._dst
@dst.setter
def dst(self, dst):
self._DST = dst
self._dst = dst
@port_pressure.setter
def port_pressure(self, port_pressure):
self._PORT_PRESSURE = port_pressure
self._port_pressure = port_pressure
@segment_ext_id.setter
def segment_ext_id(self, segment):
self._SEGMENT_EXT_ID = segment
self._segment_ext_id = segment
@offset.setter
def offset(self, offset):
self._OFFSET_ID = offset
self._offset_ID = offset
@base.setter
def base(self, base):
self._BASE_ID = base
self._base_id = base
@index.setter
def index(self, index):
self._INDEX_ID = index
self._index_id = index
@scale.setter
def scale(self, scale):
self._SCALE_ID = scale
self._scale_id = scale
@mask.setter
def mask(self, mask):
self._MASK = mask
self._mask = mask
@pre_indexed.setter
def pre_indexed(self, pre_indexed):
self._PRE_INDEXED = pre_indexed
self._pre_indexed = pre_indexed
@post_indexed.setter
def post_indexed(self, post_indexed):
self._POST_INDEXED = post_indexed
self._post_indexed = post_indexed
@indexed_val.setter
def indexed_val(self, value):
self._INDEXED_VAL = value
@property
def source(self):
return self._SOURCE
@source.setter
def source(self, source):
self._SOURCE = source
@property
def destination(self):
return self._DESTINATION
@destination.setter
def destination(self, destination):
self._DESTINATION = destination
self._indexed_val = value
def __str__(self):
return (
f"MemoryOperand(NAME_ID={self._NAME_ID}, OFFSET_ID={self._OFFSET_ID}, "
f"BASE_ID={self._BASE_ID}, INDEX_ID={self._INDEX_ID}, SCALE_ID={self._SCALE_ID}, "
f"SEGMENT_EXT_ID={self._SEGMENT_EXT_ID}, MASK={self._MASK}, "
f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, "
f"INDEXED_VAL={self._INDEXED_VAL}, PORT_PRESSURE={self._PORT_PRESSURE}),"
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
f"memoryOperand(name_id={self._name_id}, offset_ID={self._offset_ID}, "
f"base_id={self._base_id}, index_id={self._index_id}, scale_id={self._scale_id}, "
f"segment_ext_id={self._segment_ext_id}, mask={self._mask}, "
f"pre_indexed={self._pre_indexed}, post_indexed={self._post_indexed}, "
f"indexed_val={self._indexed_val}, port_pressure={self._port_pressure}),"
f"source={self._source}, destination={self._destination})"
)
def __repr__(self):
return (
f"MemoryOperand(NAME_ID={self._NAME_ID}, OFFSET_ID={self._OFFSET_ID}, "
f"BASE_ID={self._BASE_ID}, INDEX_ID={self._INDEX_ID}, SCALE_ID={self._SCALE_ID}, "
f"SEGMENT_EXT_ID={self._SEGMENT_EXT_ID}, MASK={self._MASK}, "
f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, "
f"INDEXED_VAL={self._INDEXED_VAL}, PORT_PRESSURE={self._PORT_PRESSURE}),"
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
f"memoryOperand(name_id={self._name_id}, offset_ID={self._offset_ID}, "
f"base_id={self._base_id}, index_id={self._index_id}, scale_id={self._scale_id}, "
f"segment_ext_id={self._segment_ext_id}, mask={self._mask}, "
f"pre_indexed={self._pre_indexed}, post_indexed={self._post_indexed}, "
f"indexed_val={self._indexed_val}, port_pressure={self._port_pressure}),"
f"source={self._source}, destination={self._destination})"
)
def __eq__(self, other):
if isinstance(other, MemoryOperand):
if isinstance(other, memoryOperand):
return (
self._OFFSET_ID == other._OFFSET_ID
and self._BASE_ID == other._BASE_ID
and self._INDEX_ID == other._INDEX_ID
and self._SCALE_ID == other._SCALE_ID
and self._SEGMENT_EXT_ID == other._SEGMENT_EXT_ID
and self._MASK == other._MASK
and self._PRE_INDEXED == other._PRE_INDEXED
and self._POST_INDEXED == other._POST_INDEXED
and self._INDEXED_VAL == other._INDEXED_VAL
self._offset_ID == other._offset_ID
and self._base_id == other._base_id
and self._index_id == other._index_id
and self._scale_id == other._scale_id
and self._segment_ext_id == other._segment_ext_id
and self._mask == other._mask
and self._pre_indexed == other._pre_indexed
and self._post_indexed == other._post_indexed
and self._indexed_val == other._indexed_val
)
return False

View File

@@ -2,19 +2,37 @@
class Operand:
def __init__(self, NAME_ID):
self._NAME_ID = NAME_ID
def __init__(self, name_id, source=False, destination=False):
self._name_id = name_id
self._source = source
self._destination = destination
@property
def name(self):
return self._NAME_ID
return self._name_id
@property
def source(self):
return self._source
@property
def destination(self):
return self._destination
@name.setter
def name(self, name):
self._NAME_ID = name
self._name_id = name
@name.setter
def source(self, source):
self._source = source
@destination.setter
def destination(self, destination):
self._destination = destination
def __repr__(self):
return f"Operand(NAME_ID={self._NAME_ID}"
return f"Operand(name_id={self._name_id},source={self._source},destination={self._destination})"
def __str__(self):
return f"Name: {self._NAME_ID}"
return f"Name: {self._name_id}, Source: {self._source}, Destination: {self._destination}"

View File

@@ -3,14 +3,14 @@ from copy import deepcopy
import pyparsing as pp
from osaca.parser import BaseParser
from osaca.parser.instruction_form import InstructionForm
from osaca.parser.instruction_form import instructionForm
from osaca.parser.operand import Operand
from osaca.parser.directive import DirectiveOperand
from osaca.parser.memory import MemoryOperand
from osaca.parser.label import LabelOperand
from osaca.parser.register import RegisterOperand
from osaca.parser.identifier import IdentifierOperand
from osaca.parser.immediate import ImmediateOperand
from osaca.parser.directive import directiveOperand
from osaca.parser.memory import memoryOperand
from osaca.parser.label import labelOperand
from osaca.parser.register import registerOperand
from osaca.parser.identifier import identifierOperand
from osaca.parser.immediate import immediateOperand
class ParserAArch64(BaseParser):
@@ -32,7 +32,7 @@ class ParserAArch64(BaseParser):
symbol_comment = "//"
self.comment = pp.Literal(symbol_comment) + pp.Group(
pp.ZeroOrMore(pp.Word(pp.printables))
).setResultsName(self.COMMENT_ID)
).setResultsName(self.comment_id)
# Define ARM assembly identifier
decimal_number = pp.Combine(
pp.Optional(pp.Literal("-")) + pp.Word(pp.nums)
@@ -54,7 +54,7 @@ class ParserAArch64(BaseParser):
# Label
self.label = pp.Group(
identifier.setResultsName("name") + pp.Literal(":") + pp.Optional(self.comment)
).setResultsName(self.LABEL_ID)
).setResultsName(self.label_id)
# Directive
directive_option = pp.Combine(
pp.Word(pp.alphas + "#@.%", exact=1)
@@ -69,7 +69,7 @@ class ParserAArch64(BaseParser):
+ pp.Word(pp.alphanums + "_").setResultsName("name")
+ (pp.OneOrMore(directive_parameter) ^ commaSeparatedList).setResultsName("parameters")
+ pp.Optional(self.comment)
).setResultsName(self.DIRECTIVE_ID)
).setResultsName(self.directive_id)
# LLVM-MCA markers
self.llvm_markers = pp.Group(
pp.Literal("#")
@@ -78,7 +78,7 @@ class ParserAArch64(BaseParser):
+ (pp.CaselessLiteral("BEGIN") | pp.CaselessLiteral("END"))
)
+ pp.Optional(self.comment)
).setResultsName(self.COMMENT_ID)
).setResultsName(self.comment_id)
##############################
# Instructions
@@ -260,21 +260,21 @@ class ParserAArch64(BaseParser):
:type line_number: int, optional
:return: `dict` -- parsed asm line (comment, label, directive or instruction form)
"""
instruction_form = InstructionForm(
INSTRUCTION_ID=None,
OPERANDS_ID=[],
DIRECTIVE_ID=None,
COMMENT_ID=None,
LABEL_ID=None,
LINE=line,
LINE_NUMBER=line_number,
instruction_form = instructionForm(
instruction_id=None,
operands_id=[],
directive_id=None,
comment_id=None,
label_id=None,
line=line,
line_number=line_number,
)
result = None
# 1. Parse comment
try:
result = self.process_operand(self.comment.parseString(line, parseAll=True).asDict())
instruction_form.comment = " ".join(result[self.COMMENT_ID])
instruction_form.comment = " ".join(result[self.comment_id])
except pp.ParseException:
pass
# 1.2 check for llvm-mca marker
@@ -282,7 +282,7 @@ class ParserAArch64(BaseParser):
result = self.process_operand(
self.llvm_markers.parseString(line, parseAll=True).asDict()
)
instruction_form.comment = " ".join(result[self.COMMENT_ID])
instruction_form.comment = " ".join(result[self.comment_id])
except pp.ParseException:
pass
# 2. Parse label
@@ -301,8 +301,8 @@ class ParserAArch64(BaseParser):
result = self.process_operand(
self.directive.parseString(line, parseAll=True).asDict()
)
instruction_form.directive = DirectiveOperand(
NAME_ID=result.name, PARAMETER_ID=result.parameters
instruction_form.directive = directiveOperand(
name_id=result.name, parameter_id=result.parameters
)
if result.comment is not None:
instruction_form.comment = " ".join(result.comment)
@@ -353,10 +353,10 @@ class ParserAArch64(BaseParser):
if "operand5" in result:
operand = self.process_operand(result["operand5"])
operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
return_dict = InstructionForm(
INSTRUCTION_ID=result["mnemonic"],
OPERANDS_ID=operands,
COMMENT_ID=" ".join(result[self.COMMENT_ID]) if self.COMMENT_ID in result else None,
return_dict = instructionForm(
instruction_id=result["mnemonic"],
operands_id=operands,
comment_id=" ".join(result[self.comment_id]) if self.comment_id in result else None,
)
return return_dict
@@ -376,30 +376,30 @@ class ParserAArch64(BaseParser):
# add value attribute to floating point immediates without exponent
if self.IMMEDIATE_ID in operand:
return self.process_immediate(operand[self.IMMEDIATE_ID])
if self.LABEL_ID in operand:
return self.process_label(operand[self.LABEL_ID])
if self.label_id in operand:
return self.process_label(operand[self.label_id])
if self.IDENTIFIER_ID in operand:
return self.process_identifier(operand[self.IDENTIFIER_ID])
if self.REGISTER_ID in operand:
return self.process_register_operand(operand[self.REGISTER_ID])
if self.DIRECTIVE_ID in operand:
return DirectiveOperand(
NAME_ID=operand["directive"]["name"],
PARAMETER_ID=operand["directive"]["parameters"],
COMMENT_ID=operand["directive"]["comment"]
if self.directive_id in operand:
return directiveOperand(
name_id=operand["directive"]["name"],
parameter_id=operand["directive"]["parameters"],
comment_id=operand["directive"]["comment"]
if "comment" in operand["directive"]
else None,
)
return operand
def process_register_operand(self, operand):
return RegisterOperand(
PREFIX_ID=operand["prefix"],
NAME_ID=operand["name"],
SHAPE=operand["shape"] if "shape" in operand else None,
LANES=operand["lanes"] if "lanes" in operand else None,
INDEX=operand["index"] if "index" in operand else None,
PREDICATION=operand["predication"] if "predication" in operand else None,
return registerOperand(
prefix_id=operand["prefix"],
name_id=operand["name"],
shape=operand["shape"] if "shape" in operand else None,
lanes=operand["lanes"] if "lanes" in operand else None,
index=operand["index"] if "index" in operand else None,
predication=operand["predication"] if "predication" in operand else None,
)
def process_memory_address(self, memory_address):
@@ -422,11 +422,11 @@ class ParserAArch64(BaseParser):
if "shift" in memory_address["index"]:
if memory_address["index"]["shift_op"].lower() in valid_shift_ops:
scale = 2 ** int(memory_address["index"]["shift"][0]["value"])
new_dict = MemoryOperand(
OFFSET_ID=offset,
BASE_ID=RegisterOperand(NAME_ID=base["name"], PREFIX_ID=base["prefix"]),
INDEX_ID=index,
SCALE_ID=scale,
new_dict = memoryOperand(
offset_ID=offset,
base_id=registerOperand(name_id=base["name"], prefix_id=base["prefix"]),
index_id=index,
scale_id=scale,
)
if "pre_indexed" in memory_address:
new_dict.pre_indexed = True
@@ -440,7 +440,7 @@ class ParserAArch64(BaseParser):
def process_sp_register(self, register):
"""Post-process stack pointer register"""
# reg = register
new_reg = RegisterOperand(PREFIX_ID="x", NAME_ID="sp")
new_reg = registerOperand(prefix_id="x", name_id="sp")
# reg["prefix"] = "x"
return new_reg
@@ -509,7 +509,7 @@ class ParserAArch64(BaseParser):
immediate["type"] = "int"
# convert hex/bin immediates to dec
immediate["value"] = self.normalize_imd(immediate)
return ImmediateOperand(TYPE_ID=immediate["type"], VALUE_ID=immediate["value"])
return immediateOperand(type_id=immediate["type"], value_id=immediate["value"])
if "base_immediate" in immediate:
# arithmetic immediate, add calculated value as value
immediate["shift"] = immediate["shift"][0]
@@ -517,8 +517,8 @@ class ParserAArch64(BaseParser):
immediate["shift"]["value"]
)
immediate["type"] = "int"
return ImmediateOperand(
TYPE_ID=immediate["type"], VALUE_ID=immediate["value"], SHIFT_ID=immediate["shift"]
return immediateOperand(
type_id=immediate["type"], value_id=immediate["value"], shift_id=immediate["shift"]
)
if "float" in immediate:
dict_name = "float"
@@ -526,18 +526,18 @@ class ParserAArch64(BaseParser):
dict_name = "double"
if "exponent" in immediate[dict_name]:
immediate["type"] = dict_name
return ImmediateOperand(TYPE_ID=immediate["type"])
return immediateOperand(type_id=immediate["type"])
else:
# change 'mantissa' key to 'value'
return ImmediateOperand(VALUE_ID=immediate[dict_name]["mantissa"], TYPE_ID=dict_name)
return immediateOperand(value_id=immediate[dict_name]["mantissa"], type_id=dict_name)
def process_label(self, label):
"""Post-process label asm line"""
# remove duplicated 'name' level due to identifier
# label["name"] = label["name"]["name"]
new_label = LabelOperand(
NAME_ID=label["name"]["name"],
COMMENT_ID=label["comment"] if self.COMMENT_ID in label else None,
new_label = labelOperand(
name_id=label["name"]["name"],
comment_id=label["comment"] if self.comment_id in label else None,
)
return new_label
@@ -546,7 +546,7 @@ class ParserAArch64(BaseParser):
# remove value if it consists of symbol+offset
if "value" in identifier:
del identifier["value"]
return IdentifierOperand(OFFSET=identifier["offset"], RELOCATION=identifier["relocation"])
return identifierOperand(offset=identifier["offset"], RELOCATION=identifier["relocation"])
def get_full_reg_name(self, register):
"""Return one register name string including all attributes"""

View File

@@ -6,14 +6,14 @@ import re
import pyparsing as pp
from osaca.parser import BaseParser
from osaca.parser.instruction_form import InstructionForm
from osaca.parser.instruction_form import instructionForm
from osaca.parser.operand import Operand
from osaca.parser.directive import DirectiveOperand
from osaca.parser.memory import MemoryOperand
from osaca.parser.label import LabelOperand
from osaca.parser.register import RegisterOperand
from osaca.parser.identifier import IdentifierOperand
from osaca.parser.immediate import ImmediateOperand
from osaca.parser.directive import directiveOperand
from osaca.parser.memory import memoryOperand
from osaca.parser.label import labelOperand
from osaca.parser.register import registerOperand
from osaca.parser.identifier import identifierOperand
from osaca.parser.immediate import immediateOperand
class ParserX86ATT(BaseParser):
@@ -40,7 +40,7 @@ class ParserX86ATT(BaseParser):
# Comment - either '#' or '//' (icc)
self.comment = (pp.Literal("#") | pp.Literal("//")) + pp.Group(
pp.ZeroOrMore(pp.Word(pp.printables))
).setResultsName(self.COMMENT_ID)
).setResultsName(self.comment_id)
# Define x86 assembly identifier
relocation = pp.Combine(pp.Literal("@") + pp.Word(pp.alphas))
id_offset = pp.Word(pp.nums) + pp.Suppress(pp.Literal("+"))
@@ -72,7 +72,7 @@ class ParserX86ATT(BaseParser):
(label_identifier | numeric_identifier).setResultsName("name")
+ pp.Literal(":")
+ pp.Optional(self.comment)
).setResultsName(self.LABEL_ID)
).setResultsName(self.label_id)
# Register: pp.Regex('^%[0-9a-zA-Z]+{}{z},?')
self.register = pp.Group(
pp.Literal("%")
@@ -120,7 +120,7 @@ class ParserX86ATT(BaseParser):
pp.Optional(pp.Suppress(pp.Literal("*")))
+ self.register.setResultsName("base")
+ pp.Literal(":")
+ segment_extension.setResultsName(self.SEGMENT_EXT_ID)
+ segment_extension.setResultsName(self.segment_ext_id)
)
# Memory: offset | seg:seg_ext | offset(base, index, scale){mask}
memory_abs = pp.Suppress(pp.Literal("*")) + (offset | self.register).setResultsName(
@@ -165,7 +165,7 @@ class ParserX86ATT(BaseParser):
+ pp.Word(pp.alphanums + "_").setResultsName("name")
+ pp.ZeroOrMore(directive_parameter).setResultsName("parameters")
+ pp.Optional(self.comment)
).setResultsName(self.DIRECTIVE_ID)
).setResultsName(self.directive_id)
# Instructions
# Mnemonic
@@ -207,13 +207,13 @@ class ParserX86ATT(BaseParser):
:type line_number: int, optional
:return: ``dict`` -- parsed asm line (comment, label, directive or instruction form)
"""
instruction_form = InstructionForm(LINE=line, LINE_NUMBER=line_number)
instruction_form = instructionForm(line=line, line_number=line_number)
result = None
# 1. Parse comment
try:
result = self.process_operand(self.comment.parseString(line, parseAll=True).asDict())
instruction_form.comment = " ".join(result[self.COMMENT_ID])
instruction_form.comment = " ".join(result[self.comment_id])
except pp.ParseException:
pass
@@ -233,9 +233,9 @@ class ParserX86ATT(BaseParser):
result = self.process_operand(
self.directive.parseString(line, parseAll=True).asDict()
)
instruction_form.directive = DirectiveOperand(
NAME_ID=result.name,
PARAMETER_ID=result.parameters,
instruction_form.directive = directiveOperand(
name_id=result.name,
parameter_id=result.parameters,
)
if result.comment != None:
@@ -279,10 +279,10 @@ class ParserX86ATT(BaseParser):
# Check fourth operand
if "operand4" in result:
operands.append(self.process_operand(result["operand4"]))
return_dict = InstructionForm(
INSTRUCTION_ID=result["mnemonic"].split(",")[0],
OPERANDS_ID=operands,
COMMENT_ID=" ".join(result[self.COMMENT_ID]) if self.COMMENT_ID in result else None,
return_dict = instructionForm(
instruction_id=result["mnemonic"].split(",")[0],
operands_id=operands,
comment_id=" ".join(result[self.comment_id]) if self.comment_id in result else None,
)
return return_dict
@@ -294,27 +294,27 @@ class ParserX86ATT(BaseParser):
return self.process_memory_address(operand[self.MEMORY_ID])
if self.IMMEDIATE_ID in operand:
return self.process_immediate(operand[self.IMMEDIATE_ID])
if self.LABEL_ID in operand:
return self.process_label(operand[self.LABEL_ID])
if self.DIRECTIVE_ID in operand:
return self.process_directive(operand[self.DIRECTIVE_ID])
if self.label_id in operand:
return self.process_label(operand[self.label_id])
if self.directive_id in operand:
return self.process_directive(operand[self.directive_id])
if self.REGISTER_ID in operand:
return RegisterOperand(
PREFIX_ID=operand["register"]["prefix"]
return registerOperand(
prefix_id=operand["register"]["prefix"]
if "prefix" in operand["register"]
else None,
NAME_ID=operand["register"]["name"],
SHAPE=operand["register"]["shape"] if "shape" in operand["register"] else None,
LANES=operand["register"]["lanes"] if "lanes" in operand["register"] else None,
INDEX=operand["register"]["index"] if "index" in operand["register"] else None,
PREDICATION=operand["register"]["predication"]
name_id=operand["register"]["name"],
shape=operand["register"]["shape"] if "shape" in operand["register"] else None,
lanes=operand["register"]["lanes"] if "lanes" in operand["register"] else None,
index=operand["register"]["index"] if "index" in operand["register"] else None,
predication=operand["register"]["predication"]
if "predication" in operand["register"]
else None,
)
return operand
def process_directive(self, directive):
directive_new = DirectiveOperand(NAME_ID=directive["name"], PARAMETER_ID=[])
directive_new = directiveOperand(name_id=directive["name"], parameter_id=[])
if "parameters" in directive:
directive_new.parameters = directive["parameters"]
if "comment" in directive:
@@ -338,27 +338,27 @@ class ParserX86ATT(BaseParser):
elif offset is not None and "value" in offset:
offset["value"] = int(offset["value"], 0)
if base != None:
baseOp = RegisterOperand(
NAME_ID=base["name"], PREFIX_ID=base["prefix"] if "prefix" in base else None
baseOp = registerOperand(
name_id=base["name"], prefix_id=base["prefix"] if "prefix" in base else None
)
if index != None:
indexOp = RegisterOperand(
NAME_ID=index["name"], PREFIX_ID=index["prefix"] if "prefix" in index else None
indexOp = registerOperand(
name_id=index["name"], prefix_id=index["prefix"] if "prefix" in index else None
)
new_dict = MemoryOperand(
OFFSET_ID=offset, BASE_ID=baseOp, INDEX_ID=indexOp, SCALE_ID=scale
new_dict = memoryOperand(
offset_ID=offset, base_id=baseOp, index_id=indexOp, scale_id=scale
)
# Add segmentation extension if existing
if self.SEGMENT_EXT_ID in memory_address:
new_dict.segment_ext_id = memory_address[self.SEGMENT_EXT_ID]
if self.segment_ext_id in memory_address:
new_dict.segment_ext_id = memory_address[self.segment_ext_id]
return new_dict
def process_label(self, label):
"""Post-process label asm line"""
# remove duplicated 'name' level due to identifier
label["name"] = label["name"][0]["name"]
new_label = LabelOperand(
NAME_ID=label["name"], COMMENT_ID=label["comment"] if "comment" in label else None
new_label = labelOperand(
name_id=label["name"], comment_id=label["comment"] if "comment" in label else None
)
return new_label

View File

@@ -3,163 +3,143 @@
from osaca.parser.operand import Operand
class RegisterOperand(Operand):
class registerOperand(Operand):
def __init__(
self,
NAME_ID=None,
WIDTH_ID=None,
PREFIX_ID=None,
REG_ID=None,
REGTYPE_ID=None,
LANES=None,
SHAPE=None,
INDEX=None,
MASK=False,
ZEROING=False,
PREDICATION=None,
SOURCE=False,
DESTINATION=False,
name_id=None,
width_id=None,
prefix_id=None,
reg_id=None,
regtype_id=None,
lanes=None,
shape=None,
index=None,
mask=False,
zeroing=False,
predication=None,
source=False,
destination=False,
):
super().__init__(NAME_ID)
self._WIDTH_ID = WIDTH_ID
self._PREFIX_ID = PREFIX_ID
self._REG_ID = REG_ID
self._REGTYPE_ID = REGTYPE_ID
self._LANES = LANES
self._SHAPE = SHAPE
self._INDEX = INDEX
self._MASK = MASK
self._ZEROING = ZEROING
self._PREDICATION = PREDICATION
self._SOURCE = SOURCE
self._DESTINATION = DESTINATION
super().__init__(name_id, source, destination)
self._width_id = width_id
self._prefix_id = prefix_id
self._reg_id = reg_id
self._regtype_id = regtype_id
self._lanes = lanes
self._shape = shape
self._index = index
self._mask = mask
self._zeroing = zeroing
self._predication = predication
@property
def width(self):
return self._WIDTH_ID
return self._width_id
@width.setter
def width(self, width):
self._WIDTH_ID = width
self._width_id = width
@property
def predication(self):
return self._PREDICATION
return self._predication
@predication.setter
def predication(self, predication):
self._PREDICATION = predication
self._predication = predication
@property
def regtype(self):
return self._REGTYPE_ID
return self._regtype_id
@regtype.setter
def regtype(self, regtype):
self._REGTYPE_ID = regtype
self._regtype_id = regtype
@property
def prefix(self):
return self._PREFIX_ID
return self._prefix_id
@prefix.setter
def prefix(self, prefix):
self._PREFIX = prefix
self._prefix = prefix
@property
def reg_id(self):
return self._REG_ID
return self._reg_id
@reg_id.setter
def reg_id(self, reg_id):
self._REG_ID = reg_id
self._reg_id = reg_id
@property
def lanes(self):
return self._LANES
return self._lanes
@lanes.setter
def lanes(self, lanes):
self._LANES = lanes
self._lanes = lanes
@property
def shape(self):
return self._SHAPE
return self._shape
@shape.setter
def shape(self, shape):
self._SHAPE = shape
self._shape = shape
@property
def index(self):
return self._INDEX
return self._index
@index.setter
def index(self, index):
self._INDEX = index
self._index = index
@property
def mask(self):
return self._MASK
return self._mask
@mask.setter
def mask(self, mask):
self._MASK = mask
self._mask = mask
@property
def zeroing(self):
return self._ZEROING
return self._zeroing
@zeroing.setter
def zeroing(self, zeroing):
self._ZEROING = zeroing
@property
def source(self):
return self._SOURCE
@source.setter
def source(self, source):
self._SOURCE = source
@property
def destination(self):
return self._DESTINATION
@destination.setter
def destination(self, destination):
self._DESTINATION = destination
self._zeroing = zeroing
def __str__(self):
return (
f"RegisterOperand(NAME_ID={self._NAME_ID}, WIDTH_ID={self._WIDTH_ID}, "
f"PREFIX_ID={self._PREFIX_ID}, REG_ID={self._REG_ID}, REGTYPE_ID={self._REGTYPE_ID}, "
f"LANES={self._LANES}, SHAPE={self._SHAPE}, INDEX={self._INDEX}, "
f"MASK={self._MASK}, ZEROING={self._ZEROING}),"
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
f"registerOperand(name_id={self._name_id}, width_id={self._width_id}, "
f"prefix_id={self._prefix_id}, reg_id={self._reg_id}, REGtype_id={self._regtype_id}, "
f"lanes={self._lanes}, shape={self._shape}, index={self._index}, "
f"mask={self._mask}, zeroing={self._zeroing})"
)
def __repr__(self):
return (
f"RegisterOperand(NAME_ID={self._NAME_ID}, WIDTH_ID={self._WIDTH_ID}, "
f"PREFIX_ID={self._PREFIX_ID}, REG_ID={self._REG_ID}, REGTYPE_ID={self._REGTYPE_ID}, "
f"LANES={self._LANES}, SHAPE={self._SHAPE}, INDEX={self._INDEX}, "
f"MASK={self._MASK}, ZEROING={self._ZEROING}),"
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
f"registerOperand(name_id={self._name_id}, width_id={self._width_id}, "
f"prefix_id={self._prefix_id}, reg_id={self._reg_id}, REGtype_id={self._regtype_id}, "
f"lanes={self._lanes}, shape={self._shape}, index={self._index}, "
f"mask={self._mask}, zeroing={self._zeroing})"
)
def __eq__(self, other):
if isinstance(other, RegisterOperand):
if isinstance(other, registerOperand):
return (
self._NAME_ID == other._NAME_ID
and self._WIDTH_ID == other._WIDTH_ID
and self._PREFIX_ID == other._PREFIX_ID
and self._REG_ID == other._REG_ID
and self._REGTYPE_ID == other._REGTYPE_ID
and self._LANES == other._LANES
and self._SHAPE == other._SHAPE
and self._INDEX == other._INDEX
and self._MASK == other._MASK
and self._ZEROING == other._ZEROING
self._name_id == other._name_id
and self._width_id == other._width_id
and self._prefix_id == other._prefix_id
and self._reg_id == other._reg_id
and self._regtype_id == other._regtype_id
and self._lanes == other._lanes
and self._shape == other._shape
and self._index == other._index
and self._mask == other._mask
and self._zeroing == other._zeroing
)
return False