mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-04 18:20:09 +01:00
Merge pull request #51 from RRZE-HPC/A64FX
A64FX support and several Arm bugfixes and enhancements including better TP scheduling
This commit is contained in:
@@ -5,7 +5,7 @@ import sys
|
||||
from io import StringIO
|
||||
|
||||
from osaca.frontend import Frontend
|
||||
from osaca.parser import ParserAArch64v81, ParserX86ATT
|
||||
from osaca.parser import ParserAArch64, ParserX86ATT
|
||||
from osaca.semantics import (INSTR_FLAGS, KernelDG, MachineModel,
|
||||
ArchSemantics, reduce_to_section)
|
||||
|
||||
@@ -29,7 +29,7 @@ class KerncraftAPI(object):
|
||||
self.semantics = ArchSemantics(self.machine_model)
|
||||
isa = self.machine_model.get_ISA().lower()
|
||||
if isa == 'aarch64':
|
||||
self.parser = ParserAArch64v81()
|
||||
self.parser = ParserAArch64()
|
||||
elif isa == 'x86':
|
||||
self.parser = ParserX86ATT()
|
||||
|
||||
|
||||
1031
osaca/data/a64fx.yml
Normal file
1031
osaca/data/a64fx.yml
Normal file
File diff suppressed because it is too large
Load Diff
36318
osaca/data/icl.yml
Normal file
36318
osaca/data/icl.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
osaca_version: 0.3.4
|
||||
osaca_version: 0.3.7
|
||||
isa: "AArch64"
|
||||
# Contains all operand-irregular instruction forms OSACA supports for AArch64.
|
||||
# Operand-regular for a AArch64 instruction form with N operands in the shape of
|
||||
|
||||
@@ -76,7 +76,7 @@ class Frontend(object):
|
||||
self._get_flag_symbols(instruction_form['flags'])
|
||||
if instruction_form['instruction'] is not None
|
||||
else ' ',
|
||||
instruction_form['line'].strip(),
|
||||
instruction_form['line'].strip().replace('\t', ' '),
|
||||
)
|
||||
line = line if show_lineno else col_sep + col_sep.join(line.split(col_sep)[1:])
|
||||
if show_cmnts is False and self._is_comment(instruction_form):
|
||||
@@ -138,7 +138,7 @@ class Frontend(object):
|
||||
separator,
|
||||
sum([instr_form['latency_lcd'] for instr_form in dep_dict[dep]['dependencies']]),
|
||||
separator,
|
||||
dep_dict[dep]['root']['line'],
|
||||
dep_dict[dep]['root']['line'].strip(),
|
||||
separator,
|
||||
[node['line_number'] for node in dep_dict[dep]['dependencies']],
|
||||
)
|
||||
@@ -246,7 +246,7 @@ class Frontend(object):
|
||||
self._get_flag_symbols(instruction_form['flags'])
|
||||
if instruction_form['instruction'] is not None
|
||||
else ' ',
|
||||
instruction_form['line'].strip(),
|
||||
instruction_form['line'].strip().replace('\t', ' '),
|
||||
)
|
||||
s += '\n'
|
||||
# check for unknown instructions and throw warning if called without --ignore-unknown
|
||||
|
||||
@@ -8,7 +8,7 @@ import sys
|
||||
|
||||
from osaca.db_interface import import_benchmark_output, sanity_check
|
||||
from osaca.frontend import Frontend
|
||||
from osaca.parser import BaseParser, ParserAArch64v81, ParserX86ATT
|
||||
from osaca.parser import BaseParser, ParserAArch64, ParserX86ATT
|
||||
from osaca.semantics import (INSTR_FLAGS, ArchSemantics, KernelDG,
|
||||
MachineModel, reduce_to_section)
|
||||
|
||||
@@ -17,7 +17,20 @@ MODULE_DATA_DIR = os.path.join(
|
||||
)
|
||||
LOCAL_OSACA_DIR = os.path.join(os.path.expanduser('~') + '/.osaca/')
|
||||
DATA_DIR = os.path.join(LOCAL_OSACA_DIR, 'data/')
|
||||
SUPPORTED_ARCHS = ['SNB', 'IVB', 'HSW', 'BDW', 'SKX', 'CSX', 'ZEN1', 'ZEN2', 'TX2', 'N1']
|
||||
SUPPORTED_ARCHS = [
|
||||
'SNB',
|
||||
'IVB',
|
||||
'HSW',
|
||||
'BDW',
|
||||
'SKX',
|
||||
'CSX',
|
||||
'ICL',
|
||||
'ZEN1',
|
||||
'ZEN2',
|
||||
'TX2',
|
||||
'N1',
|
||||
'A64FX',
|
||||
]
|
||||
|
||||
|
||||
# Stolen from pip
|
||||
@@ -71,7 +84,8 @@ def create_parser(parser=None):
|
||||
parser.add_argument(
|
||||
'--arch',
|
||||
type=str,
|
||||
help='Define architecture (SNB, IVB, HSW, BDW, SKX, CSX, ZEN1, ZEN2, TX2, N1).',
|
||||
help='Define architecture (SNB, IVB, HSW, BDW, SKX, CSX, ICL, ZEN1, ZEN2, TX2, N1, '
|
||||
'A64FX).',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--fixed',
|
||||
@@ -298,7 +312,7 @@ def get_asm_parser(arch) -> BaseParser:
|
||||
if isa == 'x86':
|
||||
return ParserX86ATT()
|
||||
elif isa == 'aarch64':
|
||||
return ParserAArch64v81()
|
||||
return ParserAArch64()
|
||||
|
||||
|
||||
def get_unmatched_instruction_ratio(kernel):
|
||||
|
||||
@@ -6,14 +6,14 @@ Only the parser below will be exported, so please add new parsers to __all__.
|
||||
from .attr_dict import AttrDict
|
||||
from .base_parser import BaseParser
|
||||
from .parser_x86att import ParserX86ATT
|
||||
from .parser_AArch64v81 import ParserAArch64v81
|
||||
from .parser_AArch64 import ParserAArch64
|
||||
|
||||
__all__ = ['AttrDict', 'BaseParser', 'ParserX86ATT', 'ParserAArch64v81', 'get_parser']
|
||||
__all__ = ['AttrDict', 'BaseParser', 'ParserX86ATT', 'ParserAArch64', 'get_parser']
|
||||
|
||||
def get_parser(isa):
|
||||
if isa.lower() == 'x86':
|
||||
return ParserX86ATT()
|
||||
elif isa.lower() == 'aarch64':
|
||||
return ParserAArch64v81()
|
||||
return ParserAArch64()
|
||||
else:
|
||||
raise ValueError("Unknown ISA {!r}.".format(isa))
|
||||
|
||||
@@ -6,7 +6,7 @@ import pyparsing as pp
|
||||
from osaca.parser import AttrDict, BaseParser
|
||||
|
||||
|
||||
class ParserAArch64v81(BaseParser):
|
||||
class ParserAArch64(BaseParser):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.isa = 'aarch64'
|
||||
@@ -92,31 +92,49 @@ class ParserAArch64v81(BaseParser):
|
||||
^ pp.CaselessLiteral('ror')
|
||||
^ pp.CaselessLiteral('sxtw')
|
||||
^ pp.CaselessLiteral('uxtw')
|
||||
^ pp.CaselessLiteral('mul vl')
|
||||
)
|
||||
arith_immediate = pp.Group(
|
||||
immediate.setResultsName('base_immediate')
|
||||
+ pp.Suppress(pp.Literal(','))
|
||||
+ shift_op.setResultsName('shift_op')
|
||||
+ immediate.setResultsName('shift')
|
||||
+ pp.Optional(immediate).setResultsName('shift')
|
||||
).setResultsName(self.IMMEDIATE_ID)
|
||||
# Register:
|
||||
# scalar: [XWBHSDQ][0-9]{1,2} | vector: V[0-9]{1,2}\.[12468]{1,2}[BHSD]()?
|
||||
# define SP and ZR register aliases as regex, due to pyparsing does not support
|
||||
# scalar: [XWBHSDQ][0-9]{1,2} | vector: [VZ][0-9]{1,2}(\.[12468]{1,2}[BHSD])?
|
||||
# | predicate: P[0-9]{1,2}(/[ZM])?
|
||||
# ignore vector len control ZCR_EL[123] for now
|
||||
# define SP, ZR register aliases as regex, due to pyparsing does not support
|
||||
# proper lookahead
|
||||
alias_r31_sp = pp.Regex('(?P<prefix>[a-zA-Z])?(?P<name>(sp|SP))')
|
||||
alias_r31_zr = pp.Regex('(?P<prefix>[a-zA-Z])?(?P<name>(zr|ZR))')
|
||||
scalar = pp.Word(pp.alphas, exact=1).setResultsName('prefix') + pp.Word(
|
||||
scalar = pp.Word('xwbhsdqXWBHSDQ', exact=1).setResultsName('prefix') + pp.Word(
|
||||
pp.nums
|
||||
).setResultsName('name')
|
||||
index = pp.Literal('[') + pp.Word(pp.nums).setResultsName('index') + pp.Literal(']')
|
||||
vector = (
|
||||
pp.CaselessLiteral('v').setResultsName('prefix')
|
||||
pp.oneOf('v z', caseless=True).setResultsName('prefix')
|
||||
+ pp.Word(pp.nums).setResultsName('name')
|
||||
+ pp.Literal('.')
|
||||
+ pp.Optional(pp.Word('12468')).setResultsName('lanes')
|
||||
+ pp.Word(pp.alphas, exact=1).setResultsName('shape')
|
||||
+ pp.Optional(index)
|
||||
)
|
||||
predicate = (
|
||||
pp.CaselessLiteral('p').setResultsName('prefix')
|
||||
+ pp.Word(pp.nums).setResultsName('name')
|
||||
+ pp.Optional(
|
||||
(
|
||||
pp.Suppress(pp.Literal('/'))
|
||||
+ pp.oneOf('z m', caseless=True).setResultsName('predication')
|
||||
)
|
||||
| (
|
||||
pp.Literal('.')
|
||||
+ pp.Optional(pp.Word('12468')).setResultsName('lanes')
|
||||
+ pp.Word(pp.alphas, exact=1).setResultsName('shape')
|
||||
)
|
||||
)
|
||||
)
|
||||
self.list_element = vector ^ scalar
|
||||
register_list = (
|
||||
pp.Literal('{')
|
||||
@@ -130,7 +148,8 @@ class ParserAArch64v81(BaseParser):
|
||||
+ pp.Optional(index)
|
||||
)
|
||||
register = pp.Group(
|
||||
(alias_r31_sp | alias_r31_zr | vector | scalar | register_list)
|
||||
(alias_r31_sp | alias_r31_zr | vector | scalar | predicate | register_list)
|
||||
#(alias_r31_sp | alias_r31_zr | vector | scalar | predicate | register_list)
|
||||
+ pp.Optional(
|
||||
pp.Suppress(pp.Literal(','))
|
||||
+ shift_op.setResultsName('shift_op')
|
||||
@@ -145,7 +164,7 @@ class ParserAArch64v81(BaseParser):
|
||||
pp.Literal('[')
|
||||
+ pp.Optional(register.setResultsName('base'))
|
||||
+ pp.Optional(pp.Suppress(pp.Literal(',')))
|
||||
+ pp.Optional(register_index ^ immediate.setResultsName('offset'))
|
||||
+ pp.Optional(register_index ^ (immediate ^ arith_immediate).setResultsName('offset'))
|
||||
+ pp.Literal(']')
|
||||
+ pp.Optional(
|
||||
pp.Literal('!').setResultsName('pre_indexed')
|
||||
@@ -178,6 +197,11 @@ class ParserAArch64v81(BaseParser):
|
||||
+ pp.Optional(self.comment)
|
||||
)
|
||||
|
||||
# for testing
|
||||
self.predicate = predicate
|
||||
self.vector = vector
|
||||
self.register = register
|
||||
|
||||
def parse_line(self, line, line_number=None):
|
||||
"""
|
||||
Parse line and return instruction form.
|
||||
@@ -194,7 +218,7 @@ class ParserAArch64v81(BaseParser):
|
||||
self.DIRECTIVE_ID: None,
|
||||
self.COMMENT_ID: None,
|
||||
self.LABEL_ID: None,
|
||||
'line': line.strip(),
|
||||
'line': line,
|
||||
'line_number': line_number,
|
||||
}
|
||||
)
|
||||
@@ -325,9 +349,11 @@ class ParserAArch64v81(BaseParser):
|
||||
def process_memory_address(self, memory_address):
|
||||
"""Post-process memory address operand"""
|
||||
# Remove unnecessarily created dictionary entries during parsing
|
||||
offset = None if 'offset' not in memory_address else memory_address['offset']
|
||||
base = None if 'base' not in memory_address else memory_address['base']
|
||||
index = None if 'index' not in memory_address else memory_address['index']
|
||||
offset = memory_address.get('offset', None)
|
||||
if isinstance(offset, list) and len(offset) == 1:
|
||||
offset = offset[0]
|
||||
base = memory_address.get('base', None)
|
||||
index = memory_address.get('index', None)
|
||||
scale = 1
|
||||
if base is not None and 'name' in base and base['name'] == 'sp':
|
||||
base['prefix'] = 'x'
|
||||
@@ -354,18 +380,20 @@ class ParserAArch64v81(BaseParser):
|
||||
def process_register_list(self, register_list):
|
||||
"""Post-process register lists (e.g., {r0,r3,r5}) and register ranges (e.g., {r0-r7})"""
|
||||
# Remove unnecessarily created dictionary entries during parsing
|
||||
vlist = []
|
||||
rlist = []
|
||||
dict_name = ''
|
||||
if 'list' in register_list:
|
||||
dict_name = 'list'
|
||||
if 'range' in register_list:
|
||||
dict_name = 'range'
|
||||
for v in register_list[dict_name]:
|
||||
vlist.append(
|
||||
AttrDict.convert_dict(self.list_element.parseString(v, parseAll=True).asDict())
|
||||
for r in register_list[dict_name]:
|
||||
rlist.append(
|
||||
AttrDict.convert_dict(self.list_element.parseString(r, parseAll=True).asDict())
|
||||
)
|
||||
index = None if 'index' not in register_list else register_list['index']
|
||||
new_dict = AttrDict({dict_name: vlist, 'index': index})
|
||||
index = register_list.get('index', None)
|
||||
new_dict = AttrDict({dict_name: rlist, 'index': index})
|
||||
if len(new_dict[dict_name]) == 1:
|
||||
return AttrDict({self.REGISTER_ID: new_dict[dict_name][0]})
|
||||
return AttrDict({self.REGISTER_ID: new_dict})
|
||||
|
||||
def process_immediate(self, immediate):
|
||||
@@ -450,7 +478,7 @@ class ParserAArch64v81(BaseParser):
|
||||
|
||||
def is_vector_register(self, register):
|
||||
"""Check if register is a vector register"""
|
||||
if register['prefix'] in 'bhsdqv':
|
||||
if register['prefix'] in 'bhsdqvz':
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -465,7 +493,7 @@ class ParserAArch64v81(BaseParser):
|
||||
def is_reg_dependend_of(self, reg_a, reg_b):
|
||||
"""Check if ``reg_a`` is dependent on ``reg_b``"""
|
||||
prefixes_gpr = 'wx'
|
||||
prefixes_vec = 'bhsdqv'
|
||||
prefixes_vec = 'bhsdqvz'
|
||||
if reg_a['name'] == reg_b['name']:
|
||||
if reg_a['prefix'].lower() in prefixes_gpr and reg_b['prefix'].lower() in prefixes_gpr:
|
||||
return True
|
||||
@@ -184,7 +184,7 @@ class ParserX86ATT(BaseParser):
|
||||
self.DIRECTIVE_ID: None,
|
||||
self.COMMENT_ID: None,
|
||||
self.LABEL_ID: None,
|
||||
'line': line.strip(),
|
||||
'line': line,
|
||||
'line_number': line_number,
|
||||
}
|
||||
)
|
||||
@@ -303,9 +303,9 @@ class ParserX86ATT(BaseParser):
|
||||
def process_memory_address(self, memory_address):
|
||||
"""Post-process memory address operand"""
|
||||
# Remove unecessarily created dictionary entries during memory address parsing
|
||||
offset = None if 'offset' not in memory_address else memory_address['offset']
|
||||
base = None if 'base' not in memory_address else memory_address['base']
|
||||
index = None if 'index' not in memory_address else memory_address['index']
|
||||
offset = memory_address.get('offset', None)
|
||||
base = memory_address.get('base', None)
|
||||
index = memory_address.get('index', None)
|
||||
scale = 1 if 'scale' not in memory_address else int(memory_address['scale'])
|
||||
if isinstance(offset, str) and base is None and index is None:
|
||||
offset = {'value': offset}
|
||||
|
||||
@@ -53,9 +53,18 @@ class ArchSemantics(ISASemantics):
|
||||
)
|
||||
if len(set(port_sums)) > 1:
|
||||
# balance ports
|
||||
for _ in range(cycles * 100):
|
||||
instr_ports[port_sums.index(max(port_sums))] -= INC
|
||||
instr_ports[port_sums.index(min(port_sums))] += INC
|
||||
# init list for keeping track of the current change
|
||||
differences = [cycles / len(ports) for p in ports]
|
||||
for _ in range(int(cycles * (1 / INC))):
|
||||
if len(instr_ports) == 1:
|
||||
# no balancing possible anymore
|
||||
break
|
||||
max_port_idx = port_sums.index(max(port_sums))
|
||||
min_port_idx = port_sums.index(min(port_sums))
|
||||
instr_ports[max_port_idx] -= INC
|
||||
instr_ports[min_port_idx] += INC
|
||||
differences[max_port_idx] -= INC
|
||||
differences[min_port_idx] += INC
|
||||
# instr_ports = [round(p, 2) for p in instr_ports]
|
||||
self._itemsetter(*indices)(instruction_form['port_pressure'], *instr_ports)
|
||||
# check if min port is zero
|
||||
@@ -63,7 +72,12 @@ class ArchSemantics(ISASemantics):
|
||||
# if port_pressure is not exactly 0.00, add the residual to
|
||||
# the former port
|
||||
if min(instr_ports) != 0.0:
|
||||
instr_ports[port_sums.index(min(port_sums))] += min(instr_ports)
|
||||
min_port_idx = port_sums.index(min(port_sums))
|
||||
instr_ports[min_port_idx] += min(instr_ports)
|
||||
differences[min_port_idx] += min(instr_ports)
|
||||
# we don't need to decrease difference for other port, just
|
||||
# delete it
|
||||
del differences[instr_ports.index(min(instr_ports))]
|
||||
self._itemsetter(*indices)(
|
||||
instruction_form['port_pressure'], *instr_ports
|
||||
)
|
||||
@@ -80,6 +94,17 @@ class ArchSemantics(ISASemantics):
|
||||
instr_ports = self._to_list(
|
||||
itemgetter(*indices)(instruction_form['port_pressure'])
|
||||
)
|
||||
# never remove more than the fixed utilization per uop and port, i.e.,
|
||||
# cycles/len(ports)
|
||||
if round(min(differences), 2) <= 0:
|
||||
# don't worry if port_pressure isn't exactly 0 and just
|
||||
# remove from further balancing by deleting index since
|
||||
# pressure is not 0
|
||||
del indices[differences.index(min(differences))]
|
||||
instr_ports = self._to_list(
|
||||
itemgetter(*indices)(instruction_form['port_pressure'])
|
||||
)
|
||||
del differences[differences.index(min(differences))]
|
||||
port_sums = self._to_list(
|
||||
itemgetter(*indices)(self.get_throughput_sum(kernel))
|
||||
)
|
||||
|
||||
@@ -240,6 +240,7 @@ class MachineModel(object):
|
||||
def get_isa_for_arch(arch):
|
||||
"""Return ISA for given micro-arch ``arch``."""
|
||||
arch_dict = {
|
||||
'a64fx': 'aarch64',
|
||||
'tx2': 'aarch64',
|
||||
'n1': 'aarch64',
|
||||
'zen1': 'x86',
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from itertools import chain
|
||||
|
||||
from osaca import utils
|
||||
from osaca.parser import AttrDict, ParserAArch64v81, ParserX86ATT
|
||||
from osaca.parser import AttrDict, ParserAArch64, ParserX86ATT
|
||||
|
||||
from .hw_model import MachineModel
|
||||
|
||||
@@ -31,7 +31,7 @@ class ISASemantics(object):
|
||||
if self._isa == 'x86':
|
||||
self._parser = ParserX86ATT()
|
||||
elif self._isa == 'aarch64':
|
||||
self._parser = ParserAArch64v81()
|
||||
self._parser = ParserAArch64()
|
||||
|
||||
def process(self, instruction_forms):
|
||||
"""Process a list of instruction forms."""
|
||||
@@ -52,7 +52,6 @@ class ISASemantics(object):
|
||||
return
|
||||
# check if instruction form is in ISA yaml, otherwise apply standard operand assignment
|
||||
# (one dest, others source)
|
||||
# import pdb; pdb.set_trace()
|
||||
isa_data = self._isa_model.get_instruction(
|
||||
instruction_form['instruction'], instruction_form['operands']
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
from collections import OrderedDict
|
||||
|
||||
from osaca.parser import ParserAArch64v81, ParserX86ATT, get_parser
|
||||
from osaca.parser import ParserAArch64, ParserX86ATT, get_parser
|
||||
|
||||
COMMENT_MARKER = {'start': 'OSACA-BEGIN', 'end': 'OSACA-END'}
|
||||
|
||||
@@ -38,7 +38,7 @@ def find_marked_kernel_AArch64(lines):
|
||||
nop_bytes = ['213', '3', '32', '31']
|
||||
return find_marked_section(
|
||||
lines,
|
||||
ParserAArch64v81(),
|
||||
ParserAArch64(),
|
||||
['mov'],
|
||||
'x1',
|
||||
[111, 222],
|
||||
@@ -277,6 +277,11 @@ def find_basic_loop_bodies(lines):
|
||||
current_block.append(line)
|
||||
# Find end of block by searching for references to valid jump labels
|
||||
if line['instruction'] and line['operands']:
|
||||
# Ignore `b.none` instructions (relevant von ARM SVE code)
|
||||
# This branch instruction is often present _within_ inner loop blocks, but usually
|
||||
# do not terminate
|
||||
if line['instruction'] == 'b.none':
|
||||
continue
|
||||
for operand in [o for o in line['operands'] if 'identifier' in o]:
|
||||
if operand['identifier']['name'] in valid_jump_labels:
|
||||
if operand['identifier']['name'] == label:
|
||||
|
||||
@@ -8,7 +8,7 @@ suite = unittest.TestLoader().loadTestsFromNames(
|
||||
[
|
||||
'test_base_parser',
|
||||
'test_parser_x86att',
|
||||
'test_parser_AArch64v81',
|
||||
'test_parser_AArch64',
|
||||
'test_marker_utils',
|
||||
'test_semantics',
|
||||
'test_frontend',
|
||||
|
||||
@@ -11,7 +11,7 @@ from shutil import copyfile
|
||||
from unittest.mock import patch
|
||||
|
||||
import osaca.osaca as osaca
|
||||
from osaca.parser import ParserAArch64v81, ParserX86ATT
|
||||
from osaca.parser import ParserAArch64, ParserX86ATT
|
||||
from osaca.semantics import MachineModel
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ class TestCLI(unittest.TestCase):
|
||||
|
||||
def test_get_parser(self):
|
||||
self.assertTrue(isinstance(osaca.get_asm_parser('csx'), ParserX86ATT))
|
||||
self.assertTrue(isinstance(osaca.get_asm_parser('tx2'), ParserAArch64v81))
|
||||
self.assertTrue(isinstance(osaca.get_asm_parser('tx2'), ParserAArch64))
|
||||
with self.assertRaises(ValueError):
|
||||
osaca.get_asm_parser('UNKNOWN')
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import os
|
||||
import unittest
|
||||
|
||||
from osaca.frontend import Frontend
|
||||
from osaca.parser import ParserAArch64v81, ParserX86ATT
|
||||
from osaca.parser import ParserAArch64, ParserX86ATT
|
||||
from osaca.semantics import ArchSemantics, KernelDG, MachineModel
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class TestFrontend(unittest.TestCase):
|
||||
def setUpClass(self):
|
||||
# set up parser and kernels
|
||||
self.parser_x86 = ParserX86ATT()
|
||||
self.parser_AArch64 = ParserAArch64v81()
|
||||
self.parser_AArch64 = ParserAArch64()
|
||||
with open(self._find_file('kernel_x86.s')) as f:
|
||||
code_x86 = f.read()
|
||||
with open(self._find_file('kernel_aarch64.s')) as f:
|
||||
|
||||
@@ -9,7 +9,7 @@ import unittest
|
||||
from collections import OrderedDict
|
||||
|
||||
from osaca.api import KerncraftAPI
|
||||
from osaca.parser import ParserAArch64v81, ParserX86ATT
|
||||
from osaca.parser import ParserAArch64, ParserX86ATT
|
||||
|
||||
|
||||
class TestKerncraftAPI(unittest.TestCase):
|
||||
@@ -17,7 +17,7 @@ class TestKerncraftAPI(unittest.TestCase):
|
||||
def setUpClass(self):
|
||||
# set up parser and kernels
|
||||
self.parser_x86 = ParserX86ATT()
|
||||
self.parser_AArch64 = ParserAArch64v81()
|
||||
self.parser_AArch64 = ParserAArch64()
|
||||
with open(self._find_file('triad_x86_iaca.s')) as f:
|
||||
self.code_x86 = f.read()
|
||||
with open(self._find_file('triad_arm_iaca.s')) as f:
|
||||
|
||||
@@ -8,13 +8,13 @@ from collections import OrderedDict
|
||||
|
||||
from osaca.semantics import reduce_to_section, find_basic_blocks, find_jump_labels, \
|
||||
find_basic_loop_bodies
|
||||
from osaca.parser import ParserAArch64v81, ParserX86ATT
|
||||
from osaca.parser import ParserAArch64, ParserX86ATT
|
||||
|
||||
|
||||
class TestMarkerUtils(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
self.parser_AArch = ParserAArch64v81()
|
||||
self.parser_AArch = ParserAArch64()
|
||||
self.parser_x86 = ParserX86ATT()
|
||||
with open(self._find_file('triad_arm_iaca.s')) as f:
|
||||
triad_code_arm = f.read()
|
||||
|
||||
@@ -8,13 +8,13 @@ import unittest
|
||||
|
||||
from pyparsing import ParseException
|
||||
|
||||
from osaca.parser import AttrDict, ParserAArch64v81
|
||||
from osaca.parser import AttrDict, ParserAArch64
|
||||
|
||||
|
||||
class TestParserAArch64v81(unittest.TestCase):
|
||||
class TestParserAArch64(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
self.parser = ParserAArch64v81()
|
||||
self.parser = ParserAArch64()
|
||||
with open(self._find_file('triad_arm_iaca.s')) as f:
|
||||
self.triad_code = f.read()
|
||||
|
||||
@@ -146,8 +146,8 @@ class TestParserAArch64v81(unittest.TestCase):
|
||||
def test_parse_line(self):
|
||||
line_comment = '// -- Begin main'
|
||||
line_label = '.LBB0_1: // =>This Inner Loop Header: Depth=1'
|
||||
line_directive = '\t.cfi_def_cfa w29, -16'
|
||||
line_instruction = '\tldr s0, [x11, w10, sxtw #2]\t\t// = <<2'
|
||||
line_directive = '.cfi_def_cfa w29, -16'
|
||||
line_instruction = 'ldr s0, [x11, w10, sxtw #2] // = <<2'
|
||||
line_prefetch = 'prfm pldl1keep, [x26, #2048] //HPL'
|
||||
line_preindexed = 'stp x29, x30, [sp, #-16]!'
|
||||
line_postindexed = 'ldp q2, q3, [x11], #64'
|
||||
@@ -201,7 +201,7 @@ class TestParserAArch64v81(unittest.TestCase):
|
||||
'directive': None,
|
||||
'comment': '= <<2',
|
||||
'label': None,
|
||||
'line': 'ldr s0, [x11, w10, sxtw #2]\t\t// = <<2',
|
||||
'line': 'ldr s0, [x11, w10, sxtw #2] // = <<2',
|
||||
'line_number': 4,
|
||||
}
|
||||
instruction_form_5 = {
|
||||
@@ -309,23 +309,23 @@ class TestParserAArch64v81(unittest.TestCase):
|
||||
self.assertEqual(self.parser.normalize_imd(identifier), identifier)
|
||||
|
||||
def test_multiple_regs(self):
|
||||
instr_range = 'PUSH {r5-r7}'
|
||||
instr_range = 'PUSH {x5-x7}'
|
||||
reg_range = AttrDict({
|
||||
'register': {
|
||||
'range': [
|
||||
{'prefix': 'r', 'name': '5'},
|
||||
{'prefix': 'r', 'name': '7'}
|
||||
{'prefix': 'x', 'name': '5'},
|
||||
{'prefix': 'x', 'name': '7'}
|
||||
],
|
||||
'index': None
|
||||
}
|
||||
})
|
||||
instr_list = 'POP {r5, r7, r9}'
|
||||
instr_list = 'POP {x5, x7, x9}'
|
||||
reg_list = AttrDict({
|
||||
'register': {
|
||||
'list': [
|
||||
{'prefix': 'r', 'name': '5'},
|
||||
{'prefix': 'r', 'name': '7'},
|
||||
{'prefix': 'r', 'name': '9'}
|
||||
{'prefix': 'x', 'name': '5'},
|
||||
{'prefix': 'x', 'name': '7'},
|
||||
{'prefix': 'x', 'name': '9'}
|
||||
],
|
||||
'index': None
|
||||
}
|
||||
@@ -411,5 +411,5 @@ class TestParserAArch64v81(unittest.TestCase):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestParserAArch64v81)
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestParserAArch64)
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
@@ -156,8 +156,8 @@ class TestParserX86ATT(unittest.TestCase):
|
||||
def test_parse_line(self):
|
||||
line_comment = '# -- Begin main'
|
||||
line_label = '..B1.7: # Preds ..B1.6'
|
||||
line_directive = '\t\t.quad .2.3_2__kmpc_loc_pack.2 #qed'
|
||||
line_instruction = '\t\tlea 2(%rax,%rax), %ecx #12.9'
|
||||
line_directive = '.quad .2.3_2__kmpc_loc_pack.2 #qed'
|
||||
line_instruction = 'lea 2(%rax,%rax), %ecx #12.9'
|
||||
|
||||
instruction_form_1 = {
|
||||
'instruction': None,
|
||||
|
||||
@@ -11,7 +11,7 @@ from subprocess import call
|
||||
import networkx as nx
|
||||
|
||||
from osaca.osaca import get_unmatched_instruction_ratio
|
||||
from osaca.parser import AttrDict, ParserAArch64v81, ParserX86ATT
|
||||
from osaca.parser import AttrDict, ParserAArch64, ParserX86ATT
|
||||
from osaca.semantics import (INSTR_FLAGS, ArchSemantics, KernelDG,
|
||||
MachineModel, reduce_to_section)
|
||||
|
||||
@@ -30,7 +30,7 @@ class TestSemanticTools(unittest.TestCase):
|
||||
call(['cp', '-r', self.MODULE_DATA_DIR, self.USER_DATA_DIR])
|
||||
# set up parser and kernels
|
||||
self.parser_x86 = ParserX86ATT()
|
||||
self.parser_AArch64 = ParserAArch64v81()
|
||||
self.parser_AArch64 = ParserAArch64()
|
||||
with open(self._find_file('kernel_x86.s')) as f:
|
||||
self.code_x86 = f.read()
|
||||
with open(self._find_file('kernel_aarch64.s')) as f:
|
||||
|
||||
Reference in New Issue
Block a user