mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-07 03:30:06 +01:00
supports hidden operands now (for flags or special instructions)
This commit is contained in:
@@ -408,6 +408,13 @@ class ParserAArch64v81(BaseParser):
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_flag_dependend_of(self, flag_a, flag_b):
|
||||
# we assume flags are independent of each other, e.g., CF can be read while ZF gets written
|
||||
# TODO validate this assumption
|
||||
if flag_a.name == flag_b.name:
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_reg_dependend_of(self, reg_a, reg_b):
|
||||
prefixes_gpr = 'wx'
|
||||
prefixes_vec = 'bhsdqv'
|
||||
|
||||
@@ -295,6 +295,13 @@ class ParserX86ATT(BaseParser):
|
||||
# identifier
|
||||
return imd
|
||||
|
||||
def is_flag_dependend_of(self, flag_a, flag_b):
|
||||
# we assume flags are independent of each other, e.g., CF can be read while ZF gets written
|
||||
# TODO validate this assumption
|
||||
if flag_a.name == flag_b.name:
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_reg_dependend_of(self, reg_a, reg_b):
|
||||
# Check if they are the same registers
|
||||
if reg_a.name == reg_b.name:
|
||||
|
||||
@@ -86,6 +86,23 @@ class ISASemantics(object):
|
||||
if op['destination']:
|
||||
op_dict['destination'].append(operands[i])
|
||||
continue
|
||||
# check for hidden operands like flags or registers
|
||||
if 'hidden_operands' in isa_data:
|
||||
# add operand(s) to semantic_operands of instruction form
|
||||
for op in isa_data['hidden_operands']:
|
||||
dict_key = (
|
||||
'src_dst'
|
||||
if op['source'] and op['destination']
|
||||
else 'source'
|
||||
if op['source']
|
||||
else 'destination'
|
||||
)
|
||||
hidden_op = {op['class']: {}}
|
||||
key_filter = ['class', 'source', 'destination']
|
||||
for key in [k for k in op.keys() if k not in key_filter]:
|
||||
hidden_op[op['class']][key] = op[key]
|
||||
hidden_op = AttrDict.convert_dict(hidden_op)
|
||||
op_dict[dict_key].append(hidden_op)
|
||||
# post-process pre- and post-indexing for aarch64 memory operands
|
||||
if self._isa == 'aarch64':
|
||||
for operand in [op for op in op_dict['source'] if 'memory' in op]:
|
||||
|
||||
@@ -6,7 +6,7 @@ from itertools import chain, product
|
||||
import networkx as nx
|
||||
|
||||
from osaca.parser import AttrDict
|
||||
from osaca.semantics import MachineModel
|
||||
from osaca.semantics import INSTR_FLAGS, MachineModel
|
||||
|
||||
|
||||
class KernelDG(nx.DiGraph):
|
||||
@@ -26,10 +26,9 @@ class KernelDG(nx.DiGraph):
|
||||
dg.add_node(instruction_form['line_number'])
|
||||
dg.nodes[instruction_form['line_number']]['instruction_form'] = instruction_form
|
||||
# add load as separate node if existent
|
||||
# TODO use INSTR_FLAGS here
|
||||
if (
|
||||
'performs_load' in instruction_form['flags']
|
||||
and 'is_load_instruction' not in instruction_form['flags']
|
||||
INSTR_FLAGS.HAS_LD in instruction_form['flags']
|
||||
and INSTR_FLAGS.LD not in instruction_form['flags']
|
||||
):
|
||||
# add new node
|
||||
dg.add_node(instruction_form['line_number'] + 0.1)
|
||||
@@ -167,6 +166,20 @@ class KernelDG(nx.DiGraph):
|
||||
if include_write:
|
||||
yield instr_form
|
||||
break
|
||||
if 'flag' in dst:
|
||||
# Check for read of flag until overwrite
|
||||
for instr_form in kernel:
|
||||
if self.is_read(dst.flag, instr_form):
|
||||
yield instr_form
|
||||
if self.is_written(dst.flag, instr_form):
|
||||
# operand in src_dst list
|
||||
if include_write:
|
||||
yield instr_form
|
||||
break
|
||||
elif self.is_written(dst.flag, instr_form):
|
||||
if include_write:
|
||||
yield instr_form
|
||||
break
|
||||
elif 'memory' in dst:
|
||||
# Check if base register is altered during memory access
|
||||
if 'pre_indexed' in dst.memory or 'post_indexed' in dst.memory:
|
||||
@@ -206,6 +219,8 @@ class KernelDG(nx.DiGraph):
|
||||
instruction_form.semantic_operands.src_dst):
|
||||
if 'register' in src:
|
||||
is_read = self.parser.is_reg_dependend_of(register, src.register) or is_read
|
||||
if 'flag' in src:
|
||||
is_read = self.parser.is_flag_dependend_of(register, src.flag) or is_read
|
||||
if 'memory' in src:
|
||||
if src.memory.base is not None:
|
||||
is_read = self.parser.is_reg_dependend_of(register, src.memory.base) or is_read
|
||||
@@ -233,6 +248,8 @@ class KernelDG(nx.DiGraph):
|
||||
instruction_form.semantic_operands.src_dst):
|
||||
if 'register' in dst:
|
||||
is_written = self.parser.is_reg_dependend_of(register, dst.register) or is_written
|
||||
if 'flag' in dst:
|
||||
is_written = self.parser.is_flag_dependend_of(register, dst.flag) or is_written
|
||||
if 'memory' in dst:
|
||||
if 'pre_indexed' in dst.memory or 'post_indexed' in dst.memory:
|
||||
is_written = (
|
||||
|
||||
Reference in New Issue
Block a user