mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2025-12-16 00:50:06 +01:00
bugfixed x86 parser and tests for dep finder
This commit is contained in:
@@ -92,6 +92,8 @@ class ParserX86ATT(BaseParser):
|
||||
+ pp.Optional(operand_rest.setResultsName('operand2'))
|
||||
+ pp.Optional(pp.Suppress(pp.Literal(',')))
|
||||
+ pp.Optional(operand_rest.setResultsName('operand3'))
|
||||
+ pp.Optional(pp.Suppress(pp.Literal(',')))
|
||||
+ pp.Optional(operand_rest.setResultsName('operand4'))
|
||||
+ pp.Optional(self.comment)
|
||||
)
|
||||
|
||||
@@ -179,9 +181,15 @@ class ParserX86ATT(BaseParser):
|
||||
result = AttrDict.convert_dict(result)
|
||||
operands = AttrDict({'source': [], 'destination': []})
|
||||
# Check from right to left
|
||||
# Check fourth operand
|
||||
if 'operand4' in result:
|
||||
operands['destination'].append(self.process_operand(result['operand4']))
|
||||
# Check third operand
|
||||
if 'operand3' in result:
|
||||
operands['destination'].append(self.process_operand(result['operand3']))
|
||||
if len(operands['destination']) != 0:
|
||||
operands['source'].insert(0, self.process_operand(result['operand3']))
|
||||
else:
|
||||
operands['destination'].append(self.process_operand(result['operand3']))
|
||||
# Check second operand
|
||||
if 'operand2' in result:
|
||||
if len(operands['destination']) != 0:
|
||||
|
||||
@@ -8,7 +8,8 @@ suite = unittest.TestLoader().loadTestsFromNames(
|
||||
[
|
||||
'test_parser_x86att',
|
||||
'test_parser_AArch64v81',
|
||||
'test_marker_utils'
|
||||
'test_marker_utils',
|
||||
'test_dependency_finder'
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
99
tests/test_dependency_finder.py
Executable file
99
tests/test_dependency_finder.py
Executable file
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Unit tests for KernelDAG
|
||||
"""
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from osaca.dependency_finder import KernelDAG
|
||||
from osaca.parser import AttrDict, ParserAArch64v81, ParserX86ATT
|
||||
|
||||
|
||||
class TestDependencyFinder(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.parser_x86 = ParserX86ATT()
|
||||
self.parser_AArch64 = ParserAArch64v81()
|
||||
with open(self._find_file('kernel-x86.s')) as f:
|
||||
code_x86 = f.read()
|
||||
with open(self._find_file('kernel-AArch64.s')) as f:
|
||||
code_AArch64 = f.read()
|
||||
self.kernel_x86 = self.parser_x86.parse_file(code_x86)
|
||||
self.kernel_AArch64 = self.parser_AArch64.parse_file(code_AArch64)
|
||||
|
||||
###########
|
||||
# Tests
|
||||
###########
|
||||
|
||||
def test_is_read_is_written_x86(self):
|
||||
# independent form HW model
|
||||
dag = KernelDAG(self.kernel_x86, self.parser_x86, None)
|
||||
reg_rcx = AttrDict({'name': 'rcx'})
|
||||
reg_ymm1 = AttrDict({'name': 'ymm1'})
|
||||
|
||||
instr_form_r_c = self.parser_x86.parse_line('vmovsd %xmm0, (%r15,%rcx,8)')
|
||||
instr_form_non_r_c = self.parser_x86.parse_line('movl %xmm0, (%r15,%rax,8)')
|
||||
instr_form_w_c = self.parser_x86.parse_line('movi $0x05ACA, %rcx')
|
||||
|
||||
instr_form_rw_ymm_1 = self.parser_x86.parse_line('vinsertf128 $0x1, %xmm1, %ymm0, %ymm1')
|
||||
instr_form_rw_ymm_2 = self.parser_x86.parse_line('vinsertf128 $0x1, %xmm0, %ymm1, %ymm1')
|
||||
instr_form_r_ymm = self.parser_x86.parse_line('vmovapd %ymm1, %ymm0')
|
||||
|
||||
self.assertTrue(dag.is_read(reg_rcx, instr_form_r_c))
|
||||
self.assertFalse(dag.is_read(reg_rcx, instr_form_non_r_c))
|
||||
self.assertFalse(dag.is_read(reg_rcx, instr_form_w_c))
|
||||
self.assertTrue(dag.is_written(reg_rcx, instr_form_w_c))
|
||||
self.assertFalse(dag.is_written(reg_rcx, instr_form_r_c))
|
||||
|
||||
self.assertTrue(dag.is_read(reg_ymm1, instr_form_rw_ymm_1))
|
||||
self.assertTrue(dag.is_read(reg_ymm1, instr_form_rw_ymm_2))
|
||||
self.assertTrue(dag.is_read(reg_ymm1, instr_form_r_ymm))
|
||||
self.assertTrue(dag.is_written(reg_ymm1, instr_form_rw_ymm_1))
|
||||
self.assertTrue(dag.is_written(reg_ymm1, instr_form_rw_ymm_2))
|
||||
self.assertFalse(dag.is_written(reg_ymm1, instr_form_r_ymm))
|
||||
|
||||
def test_is_read_is_written_AArch64(self):
|
||||
# independent form HW model
|
||||
dag = KernelDAG(self.kernel_AArch64, self.parser_AArch64, None)
|
||||
reg_x1 = AttrDict({'prefix': 'x', 'name': '1'})
|
||||
reg_q1 = AttrDict({'prefix': 'q', 'name': '1'})
|
||||
reg_v1 = AttrDict({'prefix': 'v', 'name': '1', 'lanes': '2', 'shape': 'd'})
|
||||
regs = [reg_x1, reg_q1, reg_v1]
|
||||
|
||||
instr_form_r_1 = self.parser_AArch64.parse_line('stp q1, q3, [x12, #192]')
|
||||
instr_form_r_2 = self.parser_AArch64.parse_line('fadd v2.2d, v1.2d, v0.2d')
|
||||
instr_form_w_1 = self.parser_AArch64.parse_line('ldr x0, [x0, #:got_lo12:q2c]')
|
||||
instr_form_rw_1 = self.parser_AArch64.parse_line('fmul v1.2d, v1.2d, v0.2d')
|
||||
instr_form_rw_2 = self.parser_AArch64.parse_line('ldp q2, q4, [x1, #64]!')
|
||||
instr_form_rw_3 = self.parser_AArch64.parse_line('str x4, [x1], #64')
|
||||
instr_form_non_rw_1 = self.parser_AArch64.parse_line('adds x0, x11')
|
||||
|
||||
for reg in regs:
|
||||
with self.subTest(reg=reg):
|
||||
self.assertTrue(dag.is_read(reg, instr_form_r_1))
|
||||
self.assertTrue(dag.is_read(reg, instr_form_r_2))
|
||||
self.assertTrue(dag.is_read(reg, instr_form_rw_1))
|
||||
self.assertTrue(dag.is_read(reg, instr_form_rw_2))
|
||||
self.assertTrue(dag.is_read(reg, instr_form_rw_3))
|
||||
self.assertFalse(dag.is_read(reg, instr_form_w_1))
|
||||
self.assertTrue(dag.is_written(reg, instr_form_rw_1))
|
||||
self.assertTrue(dag.is_written(reg, instr_form_rw_2))
|
||||
self.assertTrue(dag.is_written(reg, instr_form_rw_3))
|
||||
self.assertFalse(dag.is_written(reg, instr_form_non_rw_1))
|
||||
self.assertFalse(dag.is_written(reg, instr_form_non_rw_1))
|
||||
|
||||
##################
|
||||
# Helper functions
|
||||
##################
|
||||
|
||||
@staticmethod
|
||||
def _find_file(name):
|
||||
testdir = os.path.dirname(__file__)
|
||||
name = os.path.join(testdir, 'test_files', name)
|
||||
assert os.path.exists(name)
|
||||
return name
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestDependencyFinder)
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
20
tests/test_files/kernel-AArch64.s
Normal file
20
tests/test_files/kernel-AArch64.s
Normal file
@@ -0,0 +1,20 @@
|
||||
.LBB0_32:
|
||||
ldp q4, q5, [x9, #-32]
|
||||
ldp q6, q7, [x9], #64
|
||||
ldp q16, q17, [x11, #-32]
|
||||
ldp q18, q19, [x11], #64
|
||||
fmul v4.2d, v4.2d, v16.2d
|
||||
fmul v5.2d, v5.2d, v17.2d
|
||||
fmul v6.2d, v6.2d, v18.2d
|
||||
fmul v7.2d, v7.2d, v19.2d
|
||||
ldp q0, q1, [x8, #-32]
|
||||
ldp q2, q3, [x8], #64
|
||||
fadd v0.2d, v0.2d, v4.2d
|
||||
fadd v1.2d, v1.2d, v5.2d
|
||||
stp q0, q1, [x10, #-32]
|
||||
fadd v2.2d, v2.2d, v6.2d
|
||||
fadd v3.2d, v3.2d, v7.2d
|
||||
stp q2, q3, [x10]
|
||||
add x10, x10, #64 // =64
|
||||
adds x12, x12, #1 // =1
|
||||
b.ne .LBB0_32
|
||||
9
tests/test_files/kernel-x86.s
Normal file
9
tests/test_files/kernel-x86.s
Normal file
@@ -0,0 +1,9 @@
|
||||
.L10:
|
||||
vmovapd (%r15,%rax), %ymm0
|
||||
vmovapd (%r12,%rax), %ymm3
|
||||
addl $1, %ecx
|
||||
vfmadd132pd 0(%r13,%rax), %ymm3, %ymm0
|
||||
vmovapd %ymm0, (%r14,%rax)
|
||||
addq $32, %rax
|
||||
cmpl %ecx, %r10d
|
||||
ja .L10
|
||||
@@ -75,6 +75,7 @@ class TestParserX86ATT(unittest.TestCase):
|
||||
instr4 = 'vmovss %xmm4, -4(%rsp,%rax,8) #12.9'
|
||||
instr5 = 'mov %ebx,var(,1)'
|
||||
instr6 = 'lea (,%rax,8),%rbx'
|
||||
instr7 = 'vinsertf128 $0x1, %xmm0, %ymm1, %ymm1'
|
||||
|
||||
parsed_1 = self.parser.parse_instruction(instr1)
|
||||
parsed_2 = self.parser.parse_instruction(instr2)
|
||||
@@ -82,6 +83,7 @@ class TestParserX86ATT(unittest.TestCase):
|
||||
parsed_4 = self.parser.parse_instruction(instr4)
|
||||
parsed_5 = self.parser.parse_instruction(instr5)
|
||||
parsed_6 = self.parser.parse_instruction(instr6)
|
||||
parsed_7 = self.parser.parse_instruction(instr7)
|
||||
|
||||
self.assertEqual(parsed_1.instruction, 'vcvtsi2ss')
|
||||
self.assertEqual(parsed_1.operands.destination[0].register.name, 'xmm2')
|
||||
@@ -120,6 +122,11 @@ class TestParserX86ATT(unittest.TestCase):
|
||||
self.assertEqual(parsed_6.operands.source[0].memory.scale, '8')
|
||||
self.assertEqual(parsed_6.operands.destination[0].register.name, 'rbx')
|
||||
|
||||
self.assertEqual(parsed_7.operands.source[0].immediate.value, '0x1')
|
||||
self.assertEqual(parsed_7.operands.source[1].register.name, 'xmm0')
|
||||
self.assertEqual(parsed_7.operands.source[2].register.name, 'ymm1')
|
||||
self.assertEqual(parsed_7.operands.destination[0].register.name, 'ymm1')
|
||||
|
||||
def test_parse_line(self):
|
||||
line_comment = '# -- Begin main'
|
||||
line_label = '..B1.7: # Preds ..B1.6'
|
||||
|
||||
Reference in New Issue
Block a user