mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-10 04:57:06 +01:00
added tests for pre/post-indexed addr and prefetching
This commit is contained in:
@@ -151,7 +151,7 @@ class ParserAArch64v81(BaseParser):
|
||||
).setResultsName('prfop')
|
||||
# Combine to instruction form
|
||||
operand_first = pp.Group(
|
||||
register ^ immediate ^ memory ^ arith_immediate ^ (prefetch_op | identifier)
|
||||
register ^ (prefetch_op | immediate) ^ memory ^ arith_immediate ^ identifier
|
||||
)
|
||||
operand_rest = pp.Group((register ^ immediate ^ memory ^ arith_immediate) | identifier)
|
||||
self.instruction_parser = (
|
||||
@@ -165,14 +165,6 @@ class ParserAArch64v81(BaseParser):
|
||||
+ pp.Optional(operand_rest.setResultsName('operand4'))
|
||||
+ pp.Optional(self.comment)
|
||||
)
|
||||
self.opf = operand_first
|
||||
self.opr = operand_rest
|
||||
self.mem = memory
|
||||
self.reg = register
|
||||
self.idf = identifier
|
||||
self.prfop = prefetch_op
|
||||
self.imd = immediate
|
||||
self.aimd = arith_immediate
|
||||
|
||||
def parse_line(self, line, line_number=None):
|
||||
"""
|
||||
@@ -247,33 +239,33 @@ class ParserAArch64v81(BaseParser):
|
||||
def parse_instruction(self, instruction):
|
||||
result = self.instruction_parser.parseString(instruction, parseAll=True).asDict()
|
||||
operands = {'source': [], 'destination': []}
|
||||
# ARM specific store flags
|
||||
# ARM specific load store flags
|
||||
is_store = False
|
||||
store_ex = False
|
||||
is_load = False
|
||||
if result['mnemonic'].lower().startswith('st'):
|
||||
# Store instruction --> swap source and destination
|
||||
is_store = True
|
||||
if result['mnemonic'].lower().startswith('strex'):
|
||||
# Store exclusive --> first reg ist used for return state
|
||||
store_ex = True
|
||||
if result['mnemonic'].lower().startswith('ld'):
|
||||
# Load instruction --> keep in mind for possible multiple loads
|
||||
is_load = True
|
||||
|
||||
# Check from left to right
|
||||
# Check first operand
|
||||
if 'operand1' in result:
|
||||
if is_store and not store_ex:
|
||||
if is_store:
|
||||
operands['source'].append(self._process_operand(result['operand1']))
|
||||
else:
|
||||
operands['destination'].append(self._process_operand(result['operand1']))
|
||||
# Check second operand
|
||||
if 'operand2' in result:
|
||||
if is_store and 'operand3' not in result:
|
||||
if is_store and 'operand3' not in result or is_load and 'operand3' in result:
|
||||
# destination
|
||||
operands['destination'].append(self._process_operand(result['operand2']))
|
||||
else:
|
||||
operands['source'].append(self._process_operand(result['operand2']))
|
||||
# Check third operand
|
||||
if 'operand3' in result:
|
||||
if is_store and 'operand4' not in result:
|
||||
if is_store and 'operand4' not in result or is_load and 'operand4' in result:
|
||||
operands['destination'].append(self._process_operand(result['operand3']))
|
||||
else:
|
||||
operands['source'].append(self._process_operand(result['operand3']))
|
||||
@@ -320,6 +312,10 @@ class ParserAArch64v81(BaseParser):
|
||||
if memory_address['index']['shift_op'].lower() in valid_shift_ops:
|
||||
scale = str(2 ** int(memory_address['index']['shift']['value']))
|
||||
new_dict = {'offset': offset, 'base': base, 'index': index, 'scale': scale}
|
||||
if 'pre-indexed' in memory_address:
|
||||
new_dict['pre-indexed'] = True
|
||||
if 'post-indexed' in memory_address:
|
||||
new_dict['post-indexed'] = memory_address['post-indexed']
|
||||
return {'memory': new_dict}
|
||||
|
||||
def substitute_register_list(self, register_list):
|
||||
|
||||
@@ -143,7 +143,9 @@ class TestParserAArch64v81(unittest.TestCase):
|
||||
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'
|
||||
# STREXD/STREX/STRD?
|
||||
line_prefetch = 'prfm pldl1keep, [x26, #2048] //HPL'
|
||||
line_preindexed = 'stp x29, x30, [sp, #-16]!'
|
||||
line_postindexed = 'ldp q2, q3, [x11], #64'
|
||||
|
||||
instruction_form_1 = {
|
||||
'instruction': None,
|
||||
@@ -195,15 +197,91 @@ class TestParserAArch64v81(unittest.TestCase):
|
||||
'label': None,
|
||||
'line_number': 4,
|
||||
}
|
||||
instruction_form_5 = {
|
||||
'instruction': 'prfm',
|
||||
'operands': {
|
||||
'source': [
|
||||
{
|
||||
'memory': {
|
||||
'offset': {'value': '2048'},
|
||||
'base': {'prefix': 'x', 'name': '26'},
|
||||
'index': None,
|
||||
'scale': '1',
|
||||
}
|
||||
}
|
||||
],
|
||||
'destination': [
|
||||
{'prfop': {'type': ['PLD'], 'target': ['L1'], 'policy': ['KEEP']}}
|
||||
],
|
||||
},
|
||||
'directive': None,
|
||||
'comment': 'HPL',
|
||||
'label': None,
|
||||
'line_number': 5,
|
||||
}
|
||||
instruction_form_6 = {
|
||||
'instruction': 'stp',
|
||||
'operands': {
|
||||
'source': [
|
||||
{'register': {'prefix': 'x', 'name': '29'}},
|
||||
{'register': {'prefix': 'x', 'name': '30'}}
|
||||
],
|
||||
'destination': [
|
||||
{
|
||||
'memory': {
|
||||
'offset': {'value': '-16'},
|
||||
'base': {'name': 'sp', 'prefix': None},
|
||||
'index': None,
|
||||
'scale': '1',
|
||||
'pre-indexed': True
|
||||
}
|
||||
}
|
||||
],
|
||||
},
|
||||
'directive': None,
|
||||
'comment': None,
|
||||
'label': None,
|
||||
'line_number': 6
|
||||
}
|
||||
instruction_form_7 = {
|
||||
'instruction': 'ldp',
|
||||
'operands': {
|
||||
'source': [
|
||||
{
|
||||
'memory': {
|
||||
'offset': None,
|
||||
'base': {'prefix': 'x', 'name': '11'},
|
||||
'index': None,
|
||||
'scale': '1',
|
||||
'post-indexed': {'value': '64'},
|
||||
}
|
||||
}
|
||||
],
|
||||
'destination': [
|
||||
{'register': {'prefix': 'q', 'name': '2'}},
|
||||
{'register': {'prefix': 'q', 'name': '3'}},
|
||||
],
|
||||
},
|
||||
'directive': None,
|
||||
'comment': None,
|
||||
'label': None,
|
||||
'line_number': 7,
|
||||
}
|
||||
parsed_1 = self.parser.parse_line(line_comment, 1)
|
||||
parsed_2 = self.parser.parse_line(line_label, 2)
|
||||
parsed_3 = self.parser.parse_line(line_directive, 3)
|
||||
parsed_4 = self.parser.parse_line(line_instruction, 4)
|
||||
parsed_5 = self.parser.parse_line(line_prefetch, 5)
|
||||
parsed_6 = self.parser.parse_line(line_preindexed, 6)
|
||||
parsed_7 = self.parser.parse_line(line_postindexed, 7)
|
||||
|
||||
self.assertEqual(parsed_1, instruction_form_1)
|
||||
self.assertEqual(parsed_2, instruction_form_2)
|
||||
self.assertEqual(parsed_3, instruction_form_3)
|
||||
self.assertEqual(parsed_4['operands'], instruction_form_4['operands'])
|
||||
self.assertEqual(parsed_4, instruction_form_4)
|
||||
self.assertEqual(parsed_5, instruction_form_5)
|
||||
self.assertEqual(parsed_6, instruction_form_6)
|
||||
self.assertEqual(parsed_7, instruction_form_7)
|
||||
|
||||
def test_parse_file(self):
|
||||
parsed = self.parser.parse_file(self.triad_code)
|
||||
|
||||
Reference in New Issue
Block a user