mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-07 19:50:09 +01:00
Changed style to conform to PEP-8 conventions; Added source and destination attributes to parent Operand class
This commit is contained in:
@@ -7,12 +7,12 @@ from .attr_dict import AttrDict
|
||||
from .base_parser import BaseParser
|
||||
from .parser_x86att import ParserX86ATT
|
||||
from .parser_AArch64 import ParserAArch64
|
||||
from .instruction_form import InstructionForm
|
||||
from .instruction_form import instructionForm
|
||||
from .operand import Operand
|
||||
|
||||
__all__ = [
|
||||
"Operand",
|
||||
"InstructionForm",
|
||||
"instructionForm",
|
||||
"AttrDict",
|
||||
"BaseParser",
|
||||
"ParserX86ATT",
|
||||
|
||||
@@ -6,16 +6,16 @@ import re
|
||||
|
||||
class BaseParser(object):
|
||||
# Identifiers for operand types
|
||||
COMMENT_ID = "comment"
|
||||
DIRECTIVE_ID = "directive"
|
||||
comment_id = "comment"
|
||||
directive_id = "directive"
|
||||
IMMEDIATE_ID = "immediate"
|
||||
LABEL_ID = "label"
|
||||
label_id = "label"
|
||||
IDENTIFIER_ID = "identifier"
|
||||
MEMORY_ID = "memory"
|
||||
REGISTER_ID = "register"
|
||||
SEGMENT_EXT_ID = "segment_extension"
|
||||
INSTRUCTION_ID = "instruction"
|
||||
OPERANDS_ID = "operands"
|
||||
segment_ext_id = "segment_extension"
|
||||
instruction_id = "instruction"
|
||||
operands_id = "operands"
|
||||
_parser_constructed = False
|
||||
|
||||
def __init__(self):
|
||||
|
||||
@@ -3,49 +3,49 @@
|
||||
from osaca.parser.operand import Operand
|
||||
|
||||
|
||||
class DirectiveOperand(Operand):
|
||||
def __init__(self, NAME_ID=None, PARAMETER_ID=None, COMMENT_ID=None):
|
||||
super().__init__(NAME_ID)
|
||||
self._PARAMETER_ID = PARAMETER_ID
|
||||
self._COMMENT_ID = COMMENT_ID
|
||||
class directiveOperand(Operand):
|
||||
def __init__(self, name_id=None, parameter_id=None, comment_id=None):
|
||||
super().__init__(name_id)
|
||||
self._parameter_id = parameter_id
|
||||
self._comment_id = comment_id
|
||||
|
||||
@property
|
||||
def parameters(self):
|
||||
return self._PARAMETER_ID
|
||||
return self._parameter_id
|
||||
|
||||
@property
|
||||
def comment(self):
|
||||
return self._COMMENT_ID
|
||||
return self._comment_id
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if not self._COMMENT_ID:
|
||||
if not self._comment_id:
|
||||
raise StopIteration
|
||||
return self._COMMENT_ID.pop(0)
|
||||
return self._comment_id.pop(0)
|
||||
|
||||
@parameters.setter
|
||||
def parameters(self, parameters):
|
||||
self._PARAMETER_ID = parameters
|
||||
self._parameter_id = parameters
|
||||
|
||||
@comment.setter
|
||||
def comment(self, comment):
|
||||
self._COMMENT_ID = comment
|
||||
self._comment_id = comment
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, DirectiveOperand):
|
||||
if isinstance(other, directiveOperand):
|
||||
return (
|
||||
self._NAME_ID == other._NAME_ID
|
||||
and self._PARAMETER_ID == other._PARAMETER_ID
|
||||
and self._COMMENT_ID == other._COMMENT_ID
|
||||
self._name_id == other._name_id
|
||||
and self._parameter_id == other._parameter_id
|
||||
and self._comment_id == other._comment_id
|
||||
)
|
||||
elif isinstance(other, dict):
|
||||
return self._NAME_ID == other["name"] and self._PARAMETER_ID == other["parameters"]
|
||||
return self._name_id == other["name"] and self._parameter_id == other["parameters"]
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return f"Directive(NAME_ID={self._NAME_ID}, PARAMETERS={self._PARAMETER_ID}, COMMENT={self._COMMENT_ID})"
|
||||
return f"Directive(name_id={self._name_id}, parameters={self._parameter_id}, comment={self._comment_id})"
|
||||
|
||||
def __repr__(self):
|
||||
return f"DirectiveOperand(NAME_ID={self._NAME_ID}, PARAMETERS={self._PARAMETER_ID}, COMMENT={self._COMMENT_ID})"
|
||||
return f"directiveOperand(name_id={self._name_id}, parameters={self._parameter_id}, comment={self._comment_id})"
|
||||
|
||||
@@ -3,32 +3,32 @@
|
||||
from osaca.parser.operand import Operand
|
||||
|
||||
|
||||
class IdentifierOperand(Operand):
|
||||
def __init__(self, name=None, OFFSET=None, RELOCATION=None):
|
||||
class identifierOperand(Operand):
|
||||
def __init__(self, name=None, offset=None, relocation=None):
|
||||
super().__init__(name)
|
||||
self._OFFSET = OFFSET
|
||||
self._RELOCATION = RELOCATION
|
||||
self._offset = offset
|
||||
self._relocation = relocation
|
||||
|
||||
@property
|
||||
def offset(self):
|
||||
return self._OFFSET
|
||||
return self._offset
|
||||
|
||||
@offset.setter
|
||||
def offset(self, offset):
|
||||
self._OFFSET = offset
|
||||
self._offset = offset
|
||||
|
||||
@property
|
||||
def relocation(self):
|
||||
return self._RELOCATION
|
||||
return self._relocation
|
||||
|
||||
@relocation.setter
|
||||
def relocation(self, relocation):
|
||||
self._RELOCATION = relocation
|
||||
self._relocation = relocation
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
f"IdentifierOperand({self.name}, offset={self.offset}, relocation={self.relocation})"
|
||||
f"identifierOperand({self.name}, offset={self.offset}, relocation={self.relocation})"
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return f"IdentifierOperand(name={self.name}, offset={self.offset}, relocation={self.relocation})"
|
||||
return f"identifierOperand(name={self.name}, offset={self.offset}, relocation={self.relocation})"
|
||||
|
||||
@@ -3,90 +3,72 @@
|
||||
from osaca.parser.operand import Operand
|
||||
|
||||
|
||||
class ImmediateOperand(Operand):
|
||||
class immediateOperand(Operand):
|
||||
def __init__(
|
||||
self,
|
||||
IDENTIFIER_ID=None,
|
||||
TYPE_ID=None,
|
||||
VALUE_ID=None,
|
||||
SHIFT_ID=None,
|
||||
SOURCE=False,
|
||||
DESTINATION=False
|
||||
identifier_id=None,
|
||||
type_id=None,
|
||||
value_id=None,
|
||||
shift_id=None,
|
||||
source=False,
|
||||
destination=False,
|
||||
):
|
||||
super().__init__(str(VALUE_ID))
|
||||
self._IDENTIFIER_ID = IDENTIFIER_ID
|
||||
self._TYPE_ID = TYPE_ID
|
||||
self._VALUE_ID = VALUE_ID
|
||||
self._SHIFT_ID = SHIFT_ID
|
||||
self._SOURCE = SOURCE
|
||||
self._DESTINATION = DESTINATION
|
||||
super().__init__(str(value_id), source, destination)
|
||||
self._identifier_id = identifier_id
|
||||
self._type_id = type_id
|
||||
self._value_id = value_id
|
||||
self._shift_id = shift_id
|
||||
|
||||
@property
|
||||
def identifier(self):
|
||||
return self._IDENTIFIER_ID
|
||||
return self._identifier_id
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return self._TYPE_ID
|
||||
return self._type_id
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._VALUE_ID
|
||||
return self._value_id
|
||||
|
||||
@property
|
||||
def shift(self):
|
||||
return self._TYPE_ID
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
return self._SOURCE
|
||||
|
||||
@source.setter
|
||||
def source(self, source):
|
||||
self._SOURCE = source
|
||||
|
||||
@property
|
||||
def destination(self):
|
||||
return self._DESTINATION
|
||||
|
||||
@destination.setter
|
||||
def destination(self, destination):
|
||||
self._DESTINATION = destination
|
||||
return self._type_id
|
||||
|
||||
@identifier.setter
|
||||
def identifier(self, identifier):
|
||||
self._IDENTIFIER_ID = identifier
|
||||
self._identifier_id = identifier
|
||||
|
||||
@type.setter
|
||||
def type(self, type):
|
||||
self._TYPE_ID = type
|
||||
self._type_id = type
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
self._VALUE_ID = value
|
||||
self._value_id = value
|
||||
|
||||
@shift.setter
|
||||
def index(self, shift):
|
||||
self._SHIFT_ID = shift
|
||||
self._shift_id = shift
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
f"ImmediateOperand(IDENTIFIER_ID={self._IDENTIFIER_ID}, TYPE_ID={self._TYPE_ID}, "
|
||||
f"VALUE_ID={self._VALUE_ID}, SHIFT_ID={self._SHIFT_ID})"
|
||||
f"immediateOperand(identifier_id={self._identifier_id}, type_id={self._type_id}, "
|
||||
f"value_id={self._value_id}, shift_id={self._shift_id})"
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"ImmediateOperand(IDENTIFIER_ID={self._IDENTIFIER_ID}, TYPE_ID={self._TYPE_ID}, "
|
||||
f"VALUE_ID={self._VALUE_ID}, SHIFT_ID={self._SHIFT_ID})"
|
||||
f"immediateOperand(identifier_id={self._identifier_id}, type_id={self._type_id}, "
|
||||
f"value_id={self._value_id}, shift_id={self._shift_id})"
|
||||
)
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, ImmediateOperand):
|
||||
if isinstance(other, immediateOperand):
|
||||
return (
|
||||
self._IDENTIFIER_ID == other._IDENTIFIER_ID
|
||||
and self._TYPE_ID == other._TYPE_ID
|
||||
and self._VALUE_ID == other._VALUE_ID
|
||||
and self._SHIFT_ID == other._SHIFT_ID
|
||||
self._identifier_id == other._identifier_id
|
||||
and self._type_id == other._type_id
|
||||
and self._value_id == other._value_id
|
||||
and self._shift_id == other._shift_id
|
||||
)
|
||||
return False
|
||||
|
||||
@@ -1,200 +1,200 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from osaca.parser.directive import DirectiveOperand
|
||||
from osaca.parser.directive import directiveOperand
|
||||
|
||||
|
||||
class InstructionForm:
|
||||
class instructionForm:
|
||||
def __init__(
|
||||
self,
|
||||
INSTRUCTION_ID=None,
|
||||
OPERANDS_ID=[],
|
||||
HIDDEN_OPERANDS=[],
|
||||
DIRECTIVE_ID=None,
|
||||
COMMENT_ID=None,
|
||||
LABEL_ID=None,
|
||||
LINE=None,
|
||||
LINE_NUMBER=None,
|
||||
SEMANTIC_OPERANDS={"source": [], "destination": [], "src_dst": []},
|
||||
THROUGHPUT = None,
|
||||
LATENCY = None,
|
||||
UOPS = None,
|
||||
PORT_PRESSURE = None,
|
||||
BREAKS_DEP = False
|
||||
instruction_id=None,
|
||||
operands_id=[],
|
||||
hidden_operands=[],
|
||||
directive_id=None,
|
||||
comment_id=None,
|
||||
label_id=None,
|
||||
line=None,
|
||||
line_number=None,
|
||||
semantic_operands={"source": [], "destination": [], "src_dst": []},
|
||||
throughput=None,
|
||||
latency=None,
|
||||
uops=None,
|
||||
port_pressure=None,
|
||||
breaks_dep=False,
|
||||
):
|
||||
self._INSTRUCTION_ID = INSTRUCTION_ID
|
||||
self._OPERANDS_ID = OPERANDS_ID
|
||||
self._HIDDEN_OPERANDS = HIDDEN_OPERANDS
|
||||
self._DIRECTIVE_ID = DIRECTIVE_ID
|
||||
self._COMMENT_ID = COMMENT_ID
|
||||
self._LABEL_ID = LABEL_ID
|
||||
self._LINE = LINE
|
||||
self._LINE_NUMBER = LINE_NUMBER
|
||||
self._instruction_id = instruction_id
|
||||
self._operands_id = operands_id
|
||||
self._hidden_operands = hidden_operands
|
||||
self._directive_id = directive_id
|
||||
self._comment_id = comment_id
|
||||
self._label_id = label_id
|
||||
self._line = line
|
||||
self._line_number = line_number
|
||||
|
||||
self._SEMANTIC_OPERANDS = SEMANTIC_OPERANDS
|
||||
self._UOPS = UOPS
|
||||
self._BREAKS_DEP = BREAKS_DEP
|
||||
self._semantic_operands = semantic_operands
|
||||
self._uops = uops
|
||||
self._breaks_dep = breaks_dep
|
||||
# self.semantic_operands = {"source": [], "destination": [], "src_dst": []}
|
||||
self._LATENCY = LATENCY
|
||||
self._THROUGHPUT = THROUGHPUT
|
||||
self._LATENCY_CP = []
|
||||
self._LATENCY_LCD = []
|
||||
self._LATENCY_WO_LOAD = None
|
||||
self._PORT_PRESSURE = PORT_PRESSURE
|
||||
self._PORT_UOPS = []
|
||||
self._FLAGS = []
|
||||
self._latency = latency
|
||||
self._throughput = throughput
|
||||
self._latency_cp = []
|
||||
self._latency_lcd = []
|
||||
self._latency_wo_load = None
|
||||
self._port_pressure = port_pressure
|
||||
self._port_uops = []
|
||||
self._flags = []
|
||||
|
||||
@property
|
||||
def semantic_operands(self):
|
||||
return self._SEMANTIC_OPERANDS
|
||||
return self._semantic_operands
|
||||
|
||||
@property
|
||||
def instruction(self):
|
||||
return self._INSTRUCTION_ID
|
||||
return self._instruction_id
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
return self._LABEL_ID
|
||||
return self._label_id
|
||||
|
||||
@property
|
||||
def comment(self):
|
||||
return self._COMMENT_ID
|
||||
return self._comment_id
|
||||
|
||||
@property
|
||||
def directive(self):
|
||||
return self._DIRECTIVE_ID
|
||||
return self._directive_id
|
||||
|
||||
@property
|
||||
def line_number(self):
|
||||
return self._LINE_NUMBER
|
||||
return self._line_number
|
||||
|
||||
@property
|
||||
def line(self):
|
||||
return self._LINE
|
||||
return self._line
|
||||
|
||||
@property
|
||||
def operands(self):
|
||||
return self._OPERANDS_ID
|
||||
return self._operands_id
|
||||
|
||||
@property
|
||||
def hidden_operands(self):
|
||||
return self._HIDDEN_OPERANDS
|
||||
return self._hidden_operands
|
||||
|
||||
@property
|
||||
def port_pressure(self):
|
||||
return self._PORT_PRESSURE
|
||||
return self._port_pressure
|
||||
|
||||
@property
|
||||
def port_uops(self):
|
||||
return self._PORT_UOPS
|
||||
return self._port_uops
|
||||
|
||||
@property
|
||||
def flags(self):
|
||||
return self._FLAGS
|
||||
return self._flags
|
||||
|
||||
@property
|
||||
def uops(self):
|
||||
return self._UOPS
|
||||
return self._uops
|
||||
|
||||
@property
|
||||
def throughput(self):
|
||||
return self._THROUGHPUT
|
||||
return self._throughput
|
||||
|
||||
@property
|
||||
def latency(self):
|
||||
return self._LATENCY
|
||||
return self._latency
|
||||
|
||||
@property
|
||||
def latency_wo_load(self):
|
||||
return self._LATENCY_WO_LOAD
|
||||
return self._latency_wo_load
|
||||
|
||||
@property
|
||||
def breaks_dep(self):
|
||||
return self._BREAKS_DEP
|
||||
return self._breaks_dep
|
||||
|
||||
@semantic_operands.setter
|
||||
def semantic_operands(self, semantic_operands):
|
||||
self._SEMANTIC_OPERANDS = semantic_operands
|
||||
self._semantic_operands = semantic_operands
|
||||
|
||||
@directive.setter
|
||||
def directive(self, directive):
|
||||
self._DIRECTIVE_ID = directive
|
||||
self._directive_id = directive
|
||||
|
||||
@line_number.setter
|
||||
def line_number(self, line_number):
|
||||
self._LINE_NUMBER = line_number
|
||||
self._line_number = line_number
|
||||
|
||||
@line.setter
|
||||
def line(self, line):
|
||||
self._LINE = line
|
||||
self._line = line
|
||||
|
||||
@operands.setter
|
||||
def operands(self, operands):
|
||||
self._OPERANDS_ID = operands
|
||||
self._operands_id = operands
|
||||
|
||||
@hidden_operands.setter
|
||||
def hidden_operands(self, hidden_operands):
|
||||
self._HIDDEN_OPERANDS = hidden_operands
|
||||
self._hidden_operands = hidden_operands
|
||||
|
||||
@breaks_dep.setter
|
||||
def breaks_dep(self, boolean):
|
||||
self._BREAKS_DEP = boolean
|
||||
self._breaks_dep = boolean
|
||||
|
||||
@instruction.setter
|
||||
def instruction(self, instruction):
|
||||
self._INSTRUCTION_ID = instruction
|
||||
self._instruction_id = instruction
|
||||
|
||||
@label.setter
|
||||
def label(self, label):
|
||||
self._LABEL_ID = label
|
||||
self._label_id = label
|
||||
|
||||
@comment.setter
|
||||
def comment(self, comment):
|
||||
self._COMMENT_ID = comment
|
||||
self._comment_id = comment
|
||||
|
||||
@port_pressure.setter
|
||||
def port_pressure(self, port_pressure):
|
||||
self._PORT_PRESSURE = port_pressure
|
||||
self._port_pressure = port_pressure
|
||||
|
||||
@port_uops.setter
|
||||
def port_uops(self, port_uops):
|
||||
self._PORT_UOPS = port_uops
|
||||
self._port_uops = port_uops
|
||||
|
||||
@flags.setter
|
||||
def flags(self, flags):
|
||||
self._FLAGS = flags
|
||||
self._flags = flags
|
||||
|
||||
@uops.setter
|
||||
def uops(self, uops):
|
||||
self._UOPS = uops
|
||||
self._uops = uops
|
||||
|
||||
@throughput.setter
|
||||
def throughput(self, throughput):
|
||||
self._THROUGHPUT = throughput
|
||||
self._throughput = throughput
|
||||
|
||||
@latency.setter
|
||||
def latency(self, latency):
|
||||
self._LATENCY = latency
|
||||
self._latency = latency
|
||||
|
||||
@latency_wo_load.setter
|
||||
def latency_wo_load(self, latency_wo_load):
|
||||
self._LATENCY_WO_LOAD = latency_wo_load
|
||||
self._latency_wo_load = latency_wo_load
|
||||
|
||||
def __repr__(self):
|
||||
return f"InstructionForm(INSTRUCTION_ID={self._INSTRUCTION_ID}, OPERANDS_ID={self._OPERANDS_ID}, DIRECTIVE_ID={self._DIRECTIVE_ID}, COMMENT_ID={self._COMMENT_ID}, LABEL_ID={self._LABEL_ID}, LINE={self._LINE}, LINE_NUMBER={self._LINE_NUMBER}, SEMANTIC_OPERANDS={self._SEMANTIC_OPERANDS})"
|
||||
return f"instructionForm(instruction_id={self._instruction_id}, operands_id={self._operands_id}, directive_id={self._directive_id}, comment_id={self._comment_id}, label_id={self._label_id}, line={self._line}, line_number={self._line_number}, semantic_operands={self._semantic_operands})"
|
||||
|
||||
def __str__(self):
|
||||
return f"Instruction: {self._INSTRUCTION_ID}\nOperands: {self._OPERANDS_ID}\nDirective: {self._DIRECTIVE_ID}\nComment: {self._COMMENT_ID}\nLabel: {self._LABEL_ID}\nLine: {self._LINE}\nLine Number: {self._LINE_NUMBER}\nSemantic Operands: {self._SEMANTIC_OPERANDS}\nFlags: {self._FLAGS}"
|
||||
return f"Instruction: {self._instruction_id}\nOperands: {self._operands_id}\nDirective: {self._directive_id}\nComment: {self._comment_id}\nLabel: {self._label_id}\nLine: {self._line}\nLine Number: {self._line_number}\nSemantic Operands: {self._semantic_operands}\nFlags: {self._flags}"
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, InstructionForm):
|
||||
if isinstance(other, instructionForm):
|
||||
return (
|
||||
self._INSTRUCTION_ID == other._INSTRUCTION_ID
|
||||
and self._OPERANDS_ID == other._OPERANDS_ID
|
||||
and self._DIRECTIVE_ID == other._DIRECTIVE_ID
|
||||
and self._COMMENT_ID == other._COMMENT_ID
|
||||
and self._LABEL_ID == other._LABEL_ID
|
||||
and self._LINE == other._LINE
|
||||
and self._LINE_NUMBER == other._LINE_NUMBER
|
||||
and self._SEMANTIC_OPERANDS == other._SEMANTIC_OPERANDS
|
||||
self._instruction_id == other._instruction_id
|
||||
and self._operands_id == other._operands_id
|
||||
and self._directive_id == other._directive_id
|
||||
and self._comment_id == other._comment_id
|
||||
and self._label_id == other._label_id
|
||||
and self._line == other._line
|
||||
and self._line_number == other._line_number
|
||||
and self._semantic_operands == other._semantic_operands
|
||||
)
|
||||
return False
|
||||
|
||||
@@ -3,29 +3,29 @@
|
||||
from osaca.parser.operand import Operand
|
||||
|
||||
|
||||
class LabelOperand(Operand):
|
||||
def __init__(self, NAME_ID=None, COMMENT_ID=None):
|
||||
super().__init__(NAME_ID)
|
||||
self._COMMENT_ID = COMMENT_ID
|
||||
class labelOperand(Operand):
|
||||
def __init__(self, name_id=None, comment_id=None):
|
||||
super().__init__(name_id)
|
||||
self._comment_id = comment_id
|
||||
|
||||
@property
|
||||
def comment(self):
|
||||
return self._COMMENT_ID
|
||||
return self._comment_id
|
||||
|
||||
@comment.setter
|
||||
def comment(self, comment):
|
||||
self._COMMENT_ID = comment
|
||||
self._comment_id = comment
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if not self._COMMENT_ID:
|
||||
if not self._comment_id:
|
||||
raise StopIteration
|
||||
return self._COMMENT_ID.pop(0)
|
||||
return self._comment_id.pop(0)
|
||||
|
||||
def __str__(self):
|
||||
return f"LabelOperand(NAME_ID={self._NAME_ID}, COMMENT={self._COMMENT_ID})"
|
||||
return f"labelOperand(name_id={self._name_id}, comment={self._comment_id})"
|
||||
|
||||
def __repr__(self):
|
||||
return f"LabelOperand(NAME_ID={self._NAME_ID}, COMMENT={self._COMMENT_ID})"
|
||||
return f"labelOperand(name_id={self._name_id}, comment={self._comment_id})"
|
||||
|
||||
@@ -3,41 +3,39 @@
|
||||
from osaca.parser.operand import Operand
|
||||
|
||||
|
||||
class MemoryOperand(Operand):
|
||||
class memoryOperand(Operand):
|
||||
def __init__(
|
||||
self,
|
||||
OFFSET_ID=None,
|
||||
BASE_ID=None,
|
||||
INDEX_ID=None,
|
||||
SCALE_ID=1,
|
||||
SEGMENT_EXT_ID=None,
|
||||
MASK=None,
|
||||
PRE_INDEXED=False,
|
||||
POST_INDEXED=False,
|
||||
INDEXED_VAL=None,
|
||||
PORT_PRESSURE=[],
|
||||
DST=None,
|
||||
SOURCE=False,
|
||||
DESTINATION=False,
|
||||
offset_ID=None,
|
||||
base_id=None,
|
||||
index_id=None,
|
||||
scale_id=1,
|
||||
segment_ext_id=None,
|
||||
mask=None,
|
||||
pre_indexed=False,
|
||||
post_indexed=False,
|
||||
indexed_val=None,
|
||||
port_pressure=[],
|
||||
dst=None,
|
||||
source=False,
|
||||
destination=False,
|
||||
):
|
||||
super().__init__("memory")
|
||||
self._OFFSET_ID = OFFSET_ID
|
||||
self._BASE_ID = BASE_ID
|
||||
self._INDEX_ID = INDEX_ID
|
||||
self._SCALE_ID = SCALE_ID
|
||||
self._SEGMENT_EXT_ID = SEGMENT_EXT_ID
|
||||
self._MASK = MASK
|
||||
self._PRE_INDEXED = PRE_INDEXED
|
||||
self._POST_INDEXED = POST_INDEXED
|
||||
self._INDEXED_VAL = INDEXED_VAL
|
||||
self._PORT_PRESSURE = PORT_PRESSURE
|
||||
self._DST = DST
|
||||
self._SOURCE = SOURCE
|
||||
self._DESTINATION = DESTINATION
|
||||
super().__init__("memory", source, destination)
|
||||
self._offset_ID = offset_ID
|
||||
self._base_id = base_id
|
||||
self._index_id = index_id
|
||||
self._scale_id = scale_id
|
||||
self._segment_ext_id = segment_ext_id
|
||||
self._mask = mask
|
||||
self._pre_indexed = pre_indexed
|
||||
self._post_indexed = post_indexed
|
||||
self._indexed_val = indexed_val
|
||||
self._port_pressure = port_pressure
|
||||
self._dst = dst
|
||||
|
||||
@property
|
||||
def offset(self):
|
||||
return self._OFFSET_ID
|
||||
return self._offset_ID
|
||||
|
||||
@property
|
||||
def immediate(self):
|
||||
@@ -45,135 +43,119 @@ class MemoryOperand(Operand):
|
||||
|
||||
@property
|
||||
def base(self):
|
||||
return self._BASE_ID
|
||||
return self._base_id
|
||||
|
||||
@property
|
||||
def index(self):
|
||||
return self._INDEX_ID
|
||||
return self._index_id
|
||||
|
||||
@property
|
||||
def scale(self):
|
||||
return self._SCALE_ID
|
||||
return self._scale_id
|
||||
|
||||
@property
|
||||
def segment_ext_id(self):
|
||||
return self._SEGMENT_EXT_ID
|
||||
return self._segment_ext_id
|
||||
|
||||
@property
|
||||
def mask(self):
|
||||
return self._MASK
|
||||
return self._mask
|
||||
|
||||
@property
|
||||
def pre_indexed(self):
|
||||
return self._PRE_INDEXED
|
||||
return self._pre_indexed
|
||||
|
||||
@property
|
||||
def post_indexed(self):
|
||||
return self._POST_INDEXED
|
||||
return self._post_indexed
|
||||
|
||||
@property
|
||||
def indexed_val(self):
|
||||
return self._INDEXED_VAL
|
||||
return self._indexed_val
|
||||
|
||||
@property
|
||||
def port_pressure(self):
|
||||
return self._PORT_PRESSURE
|
||||
return self._port_pressure
|
||||
|
||||
@property
|
||||
def dst(self):
|
||||
return self._DST
|
||||
return self._dst
|
||||
|
||||
@dst.setter
|
||||
def dst(self, dst):
|
||||
self._DST = dst
|
||||
self._dst = dst
|
||||
|
||||
@port_pressure.setter
|
||||
def port_pressure(self, port_pressure):
|
||||
self._PORT_PRESSURE = port_pressure
|
||||
self._port_pressure = port_pressure
|
||||
|
||||
@segment_ext_id.setter
|
||||
def segment_ext_id(self, segment):
|
||||
self._SEGMENT_EXT_ID = segment
|
||||
self._segment_ext_id = segment
|
||||
|
||||
@offset.setter
|
||||
def offset(self, offset):
|
||||
self._OFFSET_ID = offset
|
||||
self._offset_ID = offset
|
||||
|
||||
@base.setter
|
||||
def base(self, base):
|
||||
self._BASE_ID = base
|
||||
self._base_id = base
|
||||
|
||||
@index.setter
|
||||
def index(self, index):
|
||||
self._INDEX_ID = index
|
||||
self._index_id = index
|
||||
|
||||
@scale.setter
|
||||
def scale(self, scale):
|
||||
self._SCALE_ID = scale
|
||||
self._scale_id = scale
|
||||
|
||||
@mask.setter
|
||||
def mask(self, mask):
|
||||
self._MASK = mask
|
||||
self._mask = mask
|
||||
|
||||
@pre_indexed.setter
|
||||
def pre_indexed(self, pre_indexed):
|
||||
self._PRE_INDEXED = pre_indexed
|
||||
self._pre_indexed = pre_indexed
|
||||
|
||||
@post_indexed.setter
|
||||
def post_indexed(self, post_indexed):
|
||||
self._POST_INDEXED = post_indexed
|
||||
self._post_indexed = post_indexed
|
||||
|
||||
@indexed_val.setter
|
||||
def indexed_val(self, value):
|
||||
self._INDEXED_VAL = value
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
return self._SOURCE
|
||||
|
||||
@source.setter
|
||||
def source(self, source):
|
||||
self._SOURCE = source
|
||||
|
||||
@property
|
||||
def destination(self):
|
||||
return self._DESTINATION
|
||||
|
||||
@destination.setter
|
||||
def destination(self, destination):
|
||||
self._DESTINATION = destination
|
||||
self._indexed_val = value
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
f"MemoryOperand(NAME_ID={self._NAME_ID}, OFFSET_ID={self._OFFSET_ID}, "
|
||||
f"BASE_ID={self._BASE_ID}, INDEX_ID={self._INDEX_ID}, SCALE_ID={self._SCALE_ID}, "
|
||||
f"SEGMENT_EXT_ID={self._SEGMENT_EXT_ID}, MASK={self._MASK}, "
|
||||
f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, "
|
||||
f"INDEXED_VAL={self._INDEXED_VAL}, PORT_PRESSURE={self._PORT_PRESSURE}),"
|
||||
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
|
||||
f"memoryOperand(name_id={self._name_id}, offset_ID={self._offset_ID}, "
|
||||
f"base_id={self._base_id}, index_id={self._index_id}, scale_id={self._scale_id}, "
|
||||
f"segment_ext_id={self._segment_ext_id}, mask={self._mask}, "
|
||||
f"pre_indexed={self._pre_indexed}, post_indexed={self._post_indexed}, "
|
||||
f"indexed_val={self._indexed_val}, port_pressure={self._port_pressure}),"
|
||||
f"source={self._source}, destination={self._destination})"
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"MemoryOperand(NAME_ID={self._NAME_ID}, OFFSET_ID={self._OFFSET_ID}, "
|
||||
f"BASE_ID={self._BASE_ID}, INDEX_ID={self._INDEX_ID}, SCALE_ID={self._SCALE_ID}, "
|
||||
f"SEGMENT_EXT_ID={self._SEGMENT_EXT_ID}, MASK={self._MASK}, "
|
||||
f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, "
|
||||
f"INDEXED_VAL={self._INDEXED_VAL}, PORT_PRESSURE={self._PORT_PRESSURE}),"
|
||||
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
|
||||
f"memoryOperand(name_id={self._name_id}, offset_ID={self._offset_ID}, "
|
||||
f"base_id={self._base_id}, index_id={self._index_id}, scale_id={self._scale_id}, "
|
||||
f"segment_ext_id={self._segment_ext_id}, mask={self._mask}, "
|
||||
f"pre_indexed={self._pre_indexed}, post_indexed={self._post_indexed}, "
|
||||
f"indexed_val={self._indexed_val}, port_pressure={self._port_pressure}),"
|
||||
f"source={self._source}, destination={self._destination})"
|
||||
)
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, MemoryOperand):
|
||||
if isinstance(other, memoryOperand):
|
||||
return (
|
||||
self._OFFSET_ID == other._OFFSET_ID
|
||||
and self._BASE_ID == other._BASE_ID
|
||||
and self._INDEX_ID == other._INDEX_ID
|
||||
and self._SCALE_ID == other._SCALE_ID
|
||||
and self._SEGMENT_EXT_ID == other._SEGMENT_EXT_ID
|
||||
and self._MASK == other._MASK
|
||||
and self._PRE_INDEXED == other._PRE_INDEXED
|
||||
and self._POST_INDEXED == other._POST_INDEXED
|
||||
and self._INDEXED_VAL == other._INDEXED_VAL
|
||||
self._offset_ID == other._offset_ID
|
||||
and self._base_id == other._base_id
|
||||
and self._index_id == other._index_id
|
||||
and self._scale_id == other._scale_id
|
||||
and self._segment_ext_id == other._segment_ext_id
|
||||
and self._mask == other._mask
|
||||
and self._pre_indexed == other._pre_indexed
|
||||
and self._post_indexed == other._post_indexed
|
||||
and self._indexed_val == other._indexed_val
|
||||
)
|
||||
return False
|
||||
|
||||
@@ -2,19 +2,37 @@
|
||||
|
||||
|
||||
class Operand:
|
||||
def __init__(self, NAME_ID):
|
||||
self._NAME_ID = NAME_ID
|
||||
def __init__(self, name_id, source=False, destination=False):
|
||||
self._name_id = name_id
|
||||
self._source = source
|
||||
self._destination = destination
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._NAME_ID
|
||||
return self._name_id
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
return self._source
|
||||
|
||||
@property
|
||||
def destination(self):
|
||||
return self._destination
|
||||
|
||||
@name.setter
|
||||
def name(self, name):
|
||||
self._NAME_ID = name
|
||||
self._name_id = name
|
||||
|
||||
@name.setter
|
||||
def source(self, source):
|
||||
self._source = source
|
||||
|
||||
@destination.setter
|
||||
def destination(self, destination):
|
||||
self._destination = destination
|
||||
|
||||
def __repr__(self):
|
||||
return f"Operand(NAME_ID={self._NAME_ID}"
|
||||
return f"Operand(name_id={self._name_id},source={self._source},destination={self._destination})"
|
||||
|
||||
def __str__(self):
|
||||
return f"Name: {self._NAME_ID}"
|
||||
return f"Name: {self._name_id}, Source: {self._source}, Destination: {self._destination}"
|
||||
|
||||
@@ -3,14 +3,14 @@ from copy import deepcopy
|
||||
import pyparsing as pp
|
||||
|
||||
from osaca.parser import BaseParser
|
||||
from osaca.parser.instruction_form import InstructionForm
|
||||
from osaca.parser.instruction_form import instructionForm
|
||||
from osaca.parser.operand import Operand
|
||||
from osaca.parser.directive import DirectiveOperand
|
||||
from osaca.parser.memory import MemoryOperand
|
||||
from osaca.parser.label import LabelOperand
|
||||
from osaca.parser.register import RegisterOperand
|
||||
from osaca.parser.identifier import IdentifierOperand
|
||||
from osaca.parser.immediate import ImmediateOperand
|
||||
from osaca.parser.directive import directiveOperand
|
||||
from osaca.parser.memory import memoryOperand
|
||||
from osaca.parser.label import labelOperand
|
||||
from osaca.parser.register import registerOperand
|
||||
from osaca.parser.identifier import identifierOperand
|
||||
from osaca.parser.immediate import immediateOperand
|
||||
|
||||
|
||||
class ParserAArch64(BaseParser):
|
||||
@@ -32,7 +32,7 @@ class ParserAArch64(BaseParser):
|
||||
symbol_comment = "//"
|
||||
self.comment = pp.Literal(symbol_comment) + pp.Group(
|
||||
pp.ZeroOrMore(pp.Word(pp.printables))
|
||||
).setResultsName(self.COMMENT_ID)
|
||||
).setResultsName(self.comment_id)
|
||||
# Define ARM assembly identifier
|
||||
decimal_number = pp.Combine(
|
||||
pp.Optional(pp.Literal("-")) + pp.Word(pp.nums)
|
||||
@@ -54,7 +54,7 @@ class ParserAArch64(BaseParser):
|
||||
# Label
|
||||
self.label = pp.Group(
|
||||
identifier.setResultsName("name") + pp.Literal(":") + pp.Optional(self.comment)
|
||||
).setResultsName(self.LABEL_ID)
|
||||
).setResultsName(self.label_id)
|
||||
# Directive
|
||||
directive_option = pp.Combine(
|
||||
pp.Word(pp.alphas + "#@.%", exact=1)
|
||||
@@ -69,7 +69,7 @@ class ParserAArch64(BaseParser):
|
||||
+ pp.Word(pp.alphanums + "_").setResultsName("name")
|
||||
+ (pp.OneOrMore(directive_parameter) ^ commaSeparatedList).setResultsName("parameters")
|
||||
+ pp.Optional(self.comment)
|
||||
).setResultsName(self.DIRECTIVE_ID)
|
||||
).setResultsName(self.directive_id)
|
||||
# LLVM-MCA markers
|
||||
self.llvm_markers = pp.Group(
|
||||
pp.Literal("#")
|
||||
@@ -78,7 +78,7 @@ class ParserAArch64(BaseParser):
|
||||
+ (pp.CaselessLiteral("BEGIN") | pp.CaselessLiteral("END"))
|
||||
)
|
||||
+ pp.Optional(self.comment)
|
||||
).setResultsName(self.COMMENT_ID)
|
||||
).setResultsName(self.comment_id)
|
||||
|
||||
##############################
|
||||
# Instructions
|
||||
@@ -260,21 +260,21 @@ class ParserAArch64(BaseParser):
|
||||
:type line_number: int, optional
|
||||
:return: `dict` -- parsed asm line (comment, label, directive or instruction form)
|
||||
"""
|
||||
instruction_form = InstructionForm(
|
||||
INSTRUCTION_ID=None,
|
||||
OPERANDS_ID=[],
|
||||
DIRECTIVE_ID=None,
|
||||
COMMENT_ID=None,
|
||||
LABEL_ID=None,
|
||||
LINE=line,
|
||||
LINE_NUMBER=line_number,
|
||||
instruction_form = instructionForm(
|
||||
instruction_id=None,
|
||||
operands_id=[],
|
||||
directive_id=None,
|
||||
comment_id=None,
|
||||
label_id=None,
|
||||
line=line,
|
||||
line_number=line_number,
|
||||
)
|
||||
result = None
|
||||
|
||||
# 1. Parse comment
|
||||
try:
|
||||
result = self.process_operand(self.comment.parseString(line, parseAll=True).asDict())
|
||||
instruction_form.comment = " ".join(result[self.COMMENT_ID])
|
||||
instruction_form.comment = " ".join(result[self.comment_id])
|
||||
except pp.ParseException:
|
||||
pass
|
||||
# 1.2 check for llvm-mca marker
|
||||
@@ -282,7 +282,7 @@ class ParserAArch64(BaseParser):
|
||||
result = self.process_operand(
|
||||
self.llvm_markers.parseString(line, parseAll=True).asDict()
|
||||
)
|
||||
instruction_form.comment = " ".join(result[self.COMMENT_ID])
|
||||
instruction_form.comment = " ".join(result[self.comment_id])
|
||||
except pp.ParseException:
|
||||
pass
|
||||
# 2. Parse label
|
||||
@@ -301,8 +301,8 @@ class ParserAArch64(BaseParser):
|
||||
result = self.process_operand(
|
||||
self.directive.parseString(line, parseAll=True).asDict()
|
||||
)
|
||||
instruction_form.directive = DirectiveOperand(
|
||||
NAME_ID=result.name, PARAMETER_ID=result.parameters
|
||||
instruction_form.directive = directiveOperand(
|
||||
name_id=result.name, parameter_id=result.parameters
|
||||
)
|
||||
if result.comment is not None:
|
||||
instruction_form.comment = " ".join(result.comment)
|
||||
@@ -353,10 +353,10 @@ class ParserAArch64(BaseParser):
|
||||
if "operand5" in result:
|
||||
operand = self.process_operand(result["operand5"])
|
||||
operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
|
||||
return_dict = InstructionForm(
|
||||
INSTRUCTION_ID=result["mnemonic"],
|
||||
OPERANDS_ID=operands,
|
||||
COMMENT_ID=" ".join(result[self.COMMENT_ID]) if self.COMMENT_ID in result else None,
|
||||
return_dict = instructionForm(
|
||||
instruction_id=result["mnemonic"],
|
||||
operands_id=operands,
|
||||
comment_id=" ".join(result[self.comment_id]) if self.comment_id in result else None,
|
||||
)
|
||||
return return_dict
|
||||
|
||||
@@ -376,30 +376,30 @@ class ParserAArch64(BaseParser):
|
||||
# add value attribute to floating point immediates without exponent
|
||||
if self.IMMEDIATE_ID in operand:
|
||||
return self.process_immediate(operand[self.IMMEDIATE_ID])
|
||||
if self.LABEL_ID in operand:
|
||||
return self.process_label(operand[self.LABEL_ID])
|
||||
if self.label_id in operand:
|
||||
return self.process_label(operand[self.label_id])
|
||||
if self.IDENTIFIER_ID in operand:
|
||||
return self.process_identifier(operand[self.IDENTIFIER_ID])
|
||||
if self.REGISTER_ID in operand:
|
||||
return self.process_register_operand(operand[self.REGISTER_ID])
|
||||
if self.DIRECTIVE_ID in operand:
|
||||
return DirectiveOperand(
|
||||
NAME_ID=operand["directive"]["name"],
|
||||
PARAMETER_ID=operand["directive"]["parameters"],
|
||||
COMMENT_ID=operand["directive"]["comment"]
|
||||
if self.directive_id in operand:
|
||||
return directiveOperand(
|
||||
name_id=operand["directive"]["name"],
|
||||
parameter_id=operand["directive"]["parameters"],
|
||||
comment_id=operand["directive"]["comment"]
|
||||
if "comment" in operand["directive"]
|
||||
else None,
|
||||
)
|
||||
return operand
|
||||
|
||||
def process_register_operand(self, operand):
|
||||
return RegisterOperand(
|
||||
PREFIX_ID=operand["prefix"],
|
||||
NAME_ID=operand["name"],
|
||||
SHAPE=operand["shape"] if "shape" in operand else None,
|
||||
LANES=operand["lanes"] if "lanes" in operand else None,
|
||||
INDEX=operand["index"] if "index" in operand else None,
|
||||
PREDICATION=operand["predication"] if "predication" in operand else None,
|
||||
return registerOperand(
|
||||
prefix_id=operand["prefix"],
|
||||
name_id=operand["name"],
|
||||
shape=operand["shape"] if "shape" in operand else None,
|
||||
lanes=operand["lanes"] if "lanes" in operand else None,
|
||||
index=operand["index"] if "index" in operand else None,
|
||||
predication=operand["predication"] if "predication" in operand else None,
|
||||
)
|
||||
|
||||
def process_memory_address(self, memory_address):
|
||||
@@ -422,11 +422,11 @@ class ParserAArch64(BaseParser):
|
||||
if "shift" in memory_address["index"]:
|
||||
if memory_address["index"]["shift_op"].lower() in valid_shift_ops:
|
||||
scale = 2 ** int(memory_address["index"]["shift"][0]["value"])
|
||||
new_dict = MemoryOperand(
|
||||
OFFSET_ID=offset,
|
||||
BASE_ID=RegisterOperand(NAME_ID=base["name"], PREFIX_ID=base["prefix"]),
|
||||
INDEX_ID=index,
|
||||
SCALE_ID=scale,
|
||||
new_dict = memoryOperand(
|
||||
offset_ID=offset,
|
||||
base_id=registerOperand(name_id=base["name"], prefix_id=base["prefix"]),
|
||||
index_id=index,
|
||||
scale_id=scale,
|
||||
)
|
||||
if "pre_indexed" in memory_address:
|
||||
new_dict.pre_indexed = True
|
||||
@@ -440,7 +440,7 @@ class ParserAArch64(BaseParser):
|
||||
def process_sp_register(self, register):
|
||||
"""Post-process stack pointer register"""
|
||||
# reg = register
|
||||
new_reg = RegisterOperand(PREFIX_ID="x", NAME_ID="sp")
|
||||
new_reg = registerOperand(prefix_id="x", name_id="sp")
|
||||
# reg["prefix"] = "x"
|
||||
return new_reg
|
||||
|
||||
@@ -509,7 +509,7 @@ class ParserAArch64(BaseParser):
|
||||
immediate["type"] = "int"
|
||||
# convert hex/bin immediates to dec
|
||||
immediate["value"] = self.normalize_imd(immediate)
|
||||
return ImmediateOperand(TYPE_ID=immediate["type"], VALUE_ID=immediate["value"])
|
||||
return immediateOperand(type_id=immediate["type"], value_id=immediate["value"])
|
||||
if "base_immediate" in immediate:
|
||||
# arithmetic immediate, add calculated value as value
|
||||
immediate["shift"] = immediate["shift"][0]
|
||||
@@ -517,8 +517,8 @@ class ParserAArch64(BaseParser):
|
||||
immediate["shift"]["value"]
|
||||
)
|
||||
immediate["type"] = "int"
|
||||
return ImmediateOperand(
|
||||
TYPE_ID=immediate["type"], VALUE_ID=immediate["value"], SHIFT_ID=immediate["shift"]
|
||||
return immediateOperand(
|
||||
type_id=immediate["type"], value_id=immediate["value"], shift_id=immediate["shift"]
|
||||
)
|
||||
if "float" in immediate:
|
||||
dict_name = "float"
|
||||
@@ -526,18 +526,18 @@ class ParserAArch64(BaseParser):
|
||||
dict_name = "double"
|
||||
if "exponent" in immediate[dict_name]:
|
||||
immediate["type"] = dict_name
|
||||
return ImmediateOperand(TYPE_ID=immediate["type"])
|
||||
return immediateOperand(type_id=immediate["type"])
|
||||
else:
|
||||
# change 'mantissa' key to 'value'
|
||||
return ImmediateOperand(VALUE_ID=immediate[dict_name]["mantissa"], TYPE_ID=dict_name)
|
||||
return immediateOperand(value_id=immediate[dict_name]["mantissa"], type_id=dict_name)
|
||||
|
||||
def process_label(self, label):
|
||||
"""Post-process label asm line"""
|
||||
# remove duplicated 'name' level due to identifier
|
||||
# label["name"] = label["name"]["name"]
|
||||
new_label = LabelOperand(
|
||||
NAME_ID=label["name"]["name"],
|
||||
COMMENT_ID=label["comment"] if self.COMMENT_ID in label else None,
|
||||
new_label = labelOperand(
|
||||
name_id=label["name"]["name"],
|
||||
comment_id=label["comment"] if self.comment_id in label else None,
|
||||
)
|
||||
return new_label
|
||||
|
||||
@@ -546,7 +546,7 @@ class ParserAArch64(BaseParser):
|
||||
# remove value if it consists of symbol+offset
|
||||
if "value" in identifier:
|
||||
del identifier["value"]
|
||||
return IdentifierOperand(OFFSET=identifier["offset"], RELOCATION=identifier["relocation"])
|
||||
return identifierOperand(offset=identifier["offset"], RELOCATION=identifier["relocation"])
|
||||
|
||||
def get_full_reg_name(self, register):
|
||||
"""Return one register name string including all attributes"""
|
||||
|
||||
@@ -6,14 +6,14 @@ import re
|
||||
import pyparsing as pp
|
||||
|
||||
from osaca.parser import BaseParser
|
||||
from osaca.parser.instruction_form import InstructionForm
|
||||
from osaca.parser.instruction_form import instructionForm
|
||||
from osaca.parser.operand import Operand
|
||||
from osaca.parser.directive import DirectiveOperand
|
||||
from osaca.parser.memory import MemoryOperand
|
||||
from osaca.parser.label import LabelOperand
|
||||
from osaca.parser.register import RegisterOperand
|
||||
from osaca.parser.identifier import IdentifierOperand
|
||||
from osaca.parser.immediate import ImmediateOperand
|
||||
from osaca.parser.directive import directiveOperand
|
||||
from osaca.parser.memory import memoryOperand
|
||||
from osaca.parser.label import labelOperand
|
||||
from osaca.parser.register import registerOperand
|
||||
from osaca.parser.identifier import identifierOperand
|
||||
from osaca.parser.immediate import immediateOperand
|
||||
|
||||
|
||||
class ParserX86ATT(BaseParser):
|
||||
@@ -40,7 +40,7 @@ class ParserX86ATT(BaseParser):
|
||||
# Comment - either '#' or '//' (icc)
|
||||
self.comment = (pp.Literal("#") | pp.Literal("//")) + pp.Group(
|
||||
pp.ZeroOrMore(pp.Word(pp.printables))
|
||||
).setResultsName(self.COMMENT_ID)
|
||||
).setResultsName(self.comment_id)
|
||||
# Define x86 assembly identifier
|
||||
relocation = pp.Combine(pp.Literal("@") + pp.Word(pp.alphas))
|
||||
id_offset = pp.Word(pp.nums) + pp.Suppress(pp.Literal("+"))
|
||||
@@ -72,7 +72,7 @@ class ParserX86ATT(BaseParser):
|
||||
(label_identifier | numeric_identifier).setResultsName("name")
|
||||
+ pp.Literal(":")
|
||||
+ pp.Optional(self.comment)
|
||||
).setResultsName(self.LABEL_ID)
|
||||
).setResultsName(self.label_id)
|
||||
# Register: pp.Regex('^%[0-9a-zA-Z]+{}{z},?')
|
||||
self.register = pp.Group(
|
||||
pp.Literal("%")
|
||||
@@ -120,7 +120,7 @@ class ParserX86ATT(BaseParser):
|
||||
pp.Optional(pp.Suppress(pp.Literal("*")))
|
||||
+ self.register.setResultsName("base")
|
||||
+ pp.Literal(":")
|
||||
+ segment_extension.setResultsName(self.SEGMENT_EXT_ID)
|
||||
+ segment_extension.setResultsName(self.segment_ext_id)
|
||||
)
|
||||
# Memory: offset | seg:seg_ext | offset(base, index, scale){mask}
|
||||
memory_abs = pp.Suppress(pp.Literal("*")) + (offset | self.register).setResultsName(
|
||||
@@ -165,7 +165,7 @@ class ParserX86ATT(BaseParser):
|
||||
+ pp.Word(pp.alphanums + "_").setResultsName("name")
|
||||
+ pp.ZeroOrMore(directive_parameter).setResultsName("parameters")
|
||||
+ pp.Optional(self.comment)
|
||||
).setResultsName(self.DIRECTIVE_ID)
|
||||
).setResultsName(self.directive_id)
|
||||
|
||||
# Instructions
|
||||
# Mnemonic
|
||||
@@ -207,13 +207,13 @@ class ParserX86ATT(BaseParser):
|
||||
:type line_number: int, optional
|
||||
:return: ``dict`` -- parsed asm line (comment, label, directive or instruction form)
|
||||
"""
|
||||
instruction_form = InstructionForm(LINE=line, LINE_NUMBER=line_number)
|
||||
instruction_form = instructionForm(line=line, line_number=line_number)
|
||||
result = None
|
||||
|
||||
# 1. Parse comment
|
||||
try:
|
||||
result = self.process_operand(self.comment.parseString(line, parseAll=True).asDict())
|
||||
instruction_form.comment = " ".join(result[self.COMMENT_ID])
|
||||
instruction_form.comment = " ".join(result[self.comment_id])
|
||||
except pp.ParseException:
|
||||
pass
|
||||
|
||||
@@ -233,9 +233,9 @@ class ParserX86ATT(BaseParser):
|
||||
result = self.process_operand(
|
||||
self.directive.parseString(line, parseAll=True).asDict()
|
||||
)
|
||||
instruction_form.directive = DirectiveOperand(
|
||||
NAME_ID=result.name,
|
||||
PARAMETER_ID=result.parameters,
|
||||
instruction_form.directive = directiveOperand(
|
||||
name_id=result.name,
|
||||
parameter_id=result.parameters,
|
||||
)
|
||||
|
||||
if result.comment != None:
|
||||
@@ -279,10 +279,10 @@ class ParserX86ATT(BaseParser):
|
||||
# Check fourth operand
|
||||
if "operand4" in result:
|
||||
operands.append(self.process_operand(result["operand4"]))
|
||||
return_dict = InstructionForm(
|
||||
INSTRUCTION_ID=result["mnemonic"].split(",")[0],
|
||||
OPERANDS_ID=operands,
|
||||
COMMENT_ID=" ".join(result[self.COMMENT_ID]) if self.COMMENT_ID in result else None,
|
||||
return_dict = instructionForm(
|
||||
instruction_id=result["mnemonic"].split(",")[0],
|
||||
operands_id=operands,
|
||||
comment_id=" ".join(result[self.comment_id]) if self.comment_id in result else None,
|
||||
)
|
||||
|
||||
return return_dict
|
||||
@@ -294,27 +294,27 @@ class ParserX86ATT(BaseParser):
|
||||
return self.process_memory_address(operand[self.MEMORY_ID])
|
||||
if self.IMMEDIATE_ID in operand:
|
||||
return self.process_immediate(operand[self.IMMEDIATE_ID])
|
||||
if self.LABEL_ID in operand:
|
||||
return self.process_label(operand[self.LABEL_ID])
|
||||
if self.DIRECTIVE_ID in operand:
|
||||
return self.process_directive(operand[self.DIRECTIVE_ID])
|
||||
if self.label_id in operand:
|
||||
return self.process_label(operand[self.label_id])
|
||||
if self.directive_id in operand:
|
||||
return self.process_directive(operand[self.directive_id])
|
||||
if self.REGISTER_ID in operand:
|
||||
return RegisterOperand(
|
||||
PREFIX_ID=operand["register"]["prefix"]
|
||||
return registerOperand(
|
||||
prefix_id=operand["register"]["prefix"]
|
||||
if "prefix" in operand["register"]
|
||||
else None,
|
||||
NAME_ID=operand["register"]["name"],
|
||||
SHAPE=operand["register"]["shape"] if "shape" in operand["register"] else None,
|
||||
LANES=operand["register"]["lanes"] if "lanes" in operand["register"] else None,
|
||||
INDEX=operand["register"]["index"] if "index" in operand["register"] else None,
|
||||
PREDICATION=operand["register"]["predication"]
|
||||
name_id=operand["register"]["name"],
|
||||
shape=operand["register"]["shape"] if "shape" in operand["register"] else None,
|
||||
lanes=operand["register"]["lanes"] if "lanes" in operand["register"] else None,
|
||||
index=operand["register"]["index"] if "index" in operand["register"] else None,
|
||||
predication=operand["register"]["predication"]
|
||||
if "predication" in operand["register"]
|
||||
else None,
|
||||
)
|
||||
return operand
|
||||
|
||||
def process_directive(self, directive):
|
||||
directive_new = DirectiveOperand(NAME_ID=directive["name"], PARAMETER_ID=[])
|
||||
directive_new = directiveOperand(name_id=directive["name"], parameter_id=[])
|
||||
if "parameters" in directive:
|
||||
directive_new.parameters = directive["parameters"]
|
||||
if "comment" in directive:
|
||||
@@ -338,27 +338,27 @@ class ParserX86ATT(BaseParser):
|
||||
elif offset is not None and "value" in offset:
|
||||
offset["value"] = int(offset["value"], 0)
|
||||
if base != None:
|
||||
baseOp = RegisterOperand(
|
||||
NAME_ID=base["name"], PREFIX_ID=base["prefix"] if "prefix" in base else None
|
||||
baseOp = registerOperand(
|
||||
name_id=base["name"], prefix_id=base["prefix"] if "prefix" in base else None
|
||||
)
|
||||
if index != None:
|
||||
indexOp = RegisterOperand(
|
||||
NAME_ID=index["name"], PREFIX_ID=index["prefix"] if "prefix" in index else None
|
||||
indexOp = registerOperand(
|
||||
name_id=index["name"], prefix_id=index["prefix"] if "prefix" in index else None
|
||||
)
|
||||
new_dict = MemoryOperand(
|
||||
OFFSET_ID=offset, BASE_ID=baseOp, INDEX_ID=indexOp, SCALE_ID=scale
|
||||
new_dict = memoryOperand(
|
||||
offset_ID=offset, base_id=baseOp, index_id=indexOp, scale_id=scale
|
||||
)
|
||||
# Add segmentation extension if existing
|
||||
if self.SEGMENT_EXT_ID in memory_address:
|
||||
new_dict.segment_ext_id = memory_address[self.SEGMENT_EXT_ID]
|
||||
if self.segment_ext_id in memory_address:
|
||||
new_dict.segment_ext_id = memory_address[self.segment_ext_id]
|
||||
return new_dict
|
||||
|
||||
def process_label(self, label):
|
||||
"""Post-process label asm line"""
|
||||
# remove duplicated 'name' level due to identifier
|
||||
label["name"] = label["name"][0]["name"]
|
||||
new_label = LabelOperand(
|
||||
NAME_ID=label["name"], COMMENT_ID=label["comment"] if "comment" in label else None
|
||||
new_label = labelOperand(
|
||||
name_id=label["name"], comment_id=label["comment"] if "comment" in label else None
|
||||
)
|
||||
return new_label
|
||||
|
||||
|
||||
@@ -3,163 +3,143 @@
|
||||
from osaca.parser.operand import Operand
|
||||
|
||||
|
||||
class RegisterOperand(Operand):
|
||||
class registerOperand(Operand):
|
||||
def __init__(
|
||||
self,
|
||||
NAME_ID=None,
|
||||
WIDTH_ID=None,
|
||||
PREFIX_ID=None,
|
||||
REG_ID=None,
|
||||
REGTYPE_ID=None,
|
||||
LANES=None,
|
||||
SHAPE=None,
|
||||
INDEX=None,
|
||||
MASK=False,
|
||||
ZEROING=False,
|
||||
PREDICATION=None,
|
||||
SOURCE=False,
|
||||
DESTINATION=False,
|
||||
name_id=None,
|
||||
width_id=None,
|
||||
prefix_id=None,
|
||||
reg_id=None,
|
||||
regtype_id=None,
|
||||
lanes=None,
|
||||
shape=None,
|
||||
index=None,
|
||||
mask=False,
|
||||
zeroing=False,
|
||||
predication=None,
|
||||
source=False,
|
||||
destination=False,
|
||||
):
|
||||
super().__init__(NAME_ID)
|
||||
self._WIDTH_ID = WIDTH_ID
|
||||
self._PREFIX_ID = PREFIX_ID
|
||||
self._REG_ID = REG_ID
|
||||
self._REGTYPE_ID = REGTYPE_ID
|
||||
self._LANES = LANES
|
||||
self._SHAPE = SHAPE
|
||||
self._INDEX = INDEX
|
||||
self._MASK = MASK
|
||||
self._ZEROING = ZEROING
|
||||
self._PREDICATION = PREDICATION
|
||||
self._SOURCE = SOURCE
|
||||
self._DESTINATION = DESTINATION
|
||||
super().__init__(name_id, source, destination)
|
||||
self._width_id = width_id
|
||||
self._prefix_id = prefix_id
|
||||
self._reg_id = reg_id
|
||||
self._regtype_id = regtype_id
|
||||
self._lanes = lanes
|
||||
self._shape = shape
|
||||
self._index = index
|
||||
self._mask = mask
|
||||
self._zeroing = zeroing
|
||||
self._predication = predication
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
return self._WIDTH_ID
|
||||
return self._width_id
|
||||
|
||||
@width.setter
|
||||
def width(self, width):
|
||||
self._WIDTH_ID = width
|
||||
self._width_id = width
|
||||
|
||||
@property
|
||||
def predication(self):
|
||||
return self._PREDICATION
|
||||
return self._predication
|
||||
|
||||
@predication.setter
|
||||
def predication(self, predication):
|
||||
self._PREDICATION = predication
|
||||
self._predication = predication
|
||||
|
||||
@property
|
||||
def regtype(self):
|
||||
return self._REGTYPE_ID
|
||||
return self._regtype_id
|
||||
|
||||
@regtype.setter
|
||||
def regtype(self, regtype):
|
||||
self._REGTYPE_ID = regtype
|
||||
self._regtype_id = regtype
|
||||
|
||||
@property
|
||||
def prefix(self):
|
||||
return self._PREFIX_ID
|
||||
return self._prefix_id
|
||||
|
||||
@prefix.setter
|
||||
def prefix(self, prefix):
|
||||
self._PREFIX = prefix
|
||||
self._prefix = prefix
|
||||
|
||||
@property
|
||||
def reg_id(self):
|
||||
return self._REG_ID
|
||||
return self._reg_id
|
||||
|
||||
@reg_id.setter
|
||||
def reg_id(self, reg_id):
|
||||
self._REG_ID = reg_id
|
||||
self._reg_id = reg_id
|
||||
|
||||
@property
|
||||
def lanes(self):
|
||||
return self._LANES
|
||||
return self._lanes
|
||||
|
||||
@lanes.setter
|
||||
def lanes(self, lanes):
|
||||
self._LANES = lanes
|
||||
self._lanes = lanes
|
||||
|
||||
@property
|
||||
def shape(self):
|
||||
return self._SHAPE
|
||||
return self._shape
|
||||
|
||||
@shape.setter
|
||||
def shape(self, shape):
|
||||
self._SHAPE = shape
|
||||
self._shape = shape
|
||||
|
||||
@property
|
||||
def index(self):
|
||||
return self._INDEX
|
||||
return self._index
|
||||
|
||||
@index.setter
|
||||
def index(self, index):
|
||||
self._INDEX = index
|
||||
self._index = index
|
||||
|
||||
@property
|
||||
def mask(self):
|
||||
return self._MASK
|
||||
return self._mask
|
||||
|
||||
@mask.setter
|
||||
def mask(self, mask):
|
||||
self._MASK = mask
|
||||
self._mask = mask
|
||||
|
||||
@property
|
||||
def zeroing(self):
|
||||
return self._ZEROING
|
||||
return self._zeroing
|
||||
|
||||
@zeroing.setter
|
||||
def zeroing(self, zeroing):
|
||||
self._ZEROING = zeroing
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
return self._SOURCE
|
||||
|
||||
@source.setter
|
||||
def source(self, source):
|
||||
self._SOURCE = source
|
||||
|
||||
@property
|
||||
def destination(self):
|
||||
return self._DESTINATION
|
||||
|
||||
@destination.setter
|
||||
def destination(self, destination):
|
||||
self._DESTINATION = destination
|
||||
self._zeroing = zeroing
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
f"RegisterOperand(NAME_ID={self._NAME_ID}, WIDTH_ID={self._WIDTH_ID}, "
|
||||
f"PREFIX_ID={self._PREFIX_ID}, REG_ID={self._REG_ID}, REGTYPE_ID={self._REGTYPE_ID}, "
|
||||
f"LANES={self._LANES}, SHAPE={self._SHAPE}, INDEX={self._INDEX}, "
|
||||
f"MASK={self._MASK}, ZEROING={self._ZEROING}),"
|
||||
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
|
||||
f"registerOperand(name_id={self._name_id}, width_id={self._width_id}, "
|
||||
f"prefix_id={self._prefix_id}, reg_id={self._reg_id}, REGtype_id={self._regtype_id}, "
|
||||
f"lanes={self._lanes}, shape={self._shape}, index={self._index}, "
|
||||
f"mask={self._mask}, zeroing={self._zeroing})"
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"RegisterOperand(NAME_ID={self._NAME_ID}, WIDTH_ID={self._WIDTH_ID}, "
|
||||
f"PREFIX_ID={self._PREFIX_ID}, REG_ID={self._REG_ID}, REGTYPE_ID={self._REGTYPE_ID}, "
|
||||
f"LANES={self._LANES}, SHAPE={self._SHAPE}, INDEX={self._INDEX}, "
|
||||
f"MASK={self._MASK}, ZEROING={self._ZEROING}),"
|
||||
f"SOURCE={self._SOURCE}, DESTINATION={self._DESTINATION})"
|
||||
f"registerOperand(name_id={self._name_id}, width_id={self._width_id}, "
|
||||
f"prefix_id={self._prefix_id}, reg_id={self._reg_id}, REGtype_id={self._regtype_id}, "
|
||||
f"lanes={self._lanes}, shape={self._shape}, index={self._index}, "
|
||||
f"mask={self._mask}, zeroing={self._zeroing})"
|
||||
)
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, RegisterOperand):
|
||||
if isinstance(other, registerOperand):
|
||||
return (
|
||||
self._NAME_ID == other._NAME_ID
|
||||
and self._WIDTH_ID == other._WIDTH_ID
|
||||
and self._PREFIX_ID == other._PREFIX_ID
|
||||
and self._REG_ID == other._REG_ID
|
||||
and self._REGTYPE_ID == other._REGTYPE_ID
|
||||
and self._LANES == other._LANES
|
||||
and self._SHAPE == other._SHAPE
|
||||
and self._INDEX == other._INDEX
|
||||
and self._MASK == other._MASK
|
||||
and self._ZEROING == other._ZEROING
|
||||
self._name_id == other._name_id
|
||||
and self._width_id == other._width_id
|
||||
and self._prefix_id == other._prefix_id
|
||||
and self._reg_id == other._reg_id
|
||||
and self._regtype_id == other._regtype_id
|
||||
and self._lanes == other._lanes
|
||||
and self._shape == other._shape
|
||||
and self._index == other._index
|
||||
and self._mask == other._mask
|
||||
and self._zeroing == other._zeroing
|
||||
)
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user