Add support for the Intel syntax supported by MSVC and ICC

This commit is contained in:
pleroy
2025-02-02 14:02:16 +01:00
parent 785a365c63
commit 1a7c1588f6
30 changed files with 2744 additions and 499 deletions

View File

@@ -20,6 +20,8 @@ class TestBaseParser(unittest.TestCase):
pass
with open(self._find_file("triad_x86_iaca.s")) as f:
self.triad_code = f.read()
with open(self._find_file("triad_x86_intel.asm")) as f:
self.triad_code_intel = f.read()
with open(self._find_file("triad_arm_iaca.s")) as f:
self.triad_code_arm = f.read()
with open(self._find_file("kernel_x86.s")) as f:
@@ -68,10 +70,11 @@ class TestBaseParser(unittest.TestCase):
self.parser.normalize_imd(imd_hex_1)
def test_detect_ISA(self):
self.assertEqual(BaseParser.detect_ISA(self.triad_code), "x86")
self.assertEqual(BaseParser.detect_ISA(self.triad_code_arm), "aarch64")
self.assertEqual(BaseParser.detect_ISA(self.x86_code), "x86")
self.assertEqual(BaseParser.detect_ISA(self.aarch64_code), "aarch64")
self.assertEqual(BaseParser.detect_ISA(self.triad_code), ("x86", "ATT"))
self.assertEqual(BaseParser.detect_ISA(self.triad_code_intel), ("x86", "INTEL"))
self.assertEqual(BaseParser.detect_ISA(self.triad_code_arm), ("aarch64", None))
self.assertEqual(BaseParser.detect_ISA(self.x86_code), ("x86", "ATT"))
self.assertEqual(BaseParser.detect_ISA(self.aarch64_code), ("aarch64", None))
##################
# Helper functions

View File

@@ -0,0 +1,227 @@
# Produced with ICC 2021.10.0 with -O3 -xcore-avx512, https://godbolt.org/z/87bYseh8r
..B1.1: # Preds ..B1.0
push rbp #5.32
mov rbp, rsp #5.32
and rsp, -128 #5.32
push r15 #5.32
push rbx #5.32
sub rsp, 112 #5.32
mov edi, 3 #5.32
mov rsi, 0x64199d9ffe #5.32
call __intel_new_feature_proc_init #5.32
..B1.34: # Preds ..B1.1
vstmxcsr DWORD PTR [rsp] #5.32
xor edi, edi #11.7
or DWORD PTR [rsp], 32832 #5.32
vldmxcsr DWORD PTR [rsp] #5.32
call time #11.7
..B1.2: # Preds ..B1.34
mov edi, eax #11.1
call srand #11.1
..B1.3: # Preds ..B1.2
mov edi, 1600 #13.16
call malloc #13.16
..B1.35: # Preds ..B1.3
mov rsi, rax #13.16
..B1.4: # Preds ..B1.35
xor eax, eax #14.1
mov rbx, rsi #14.1
mov r15, rax #14.1
..B1.5: # Preds ..B1.6 ..B1.4
mov edi, 1600 #15.22
call malloc #15.22
..B1.6: # Preds ..B1.5
mov QWORD PTR [rbx+r15*8], rax #15.5
inc r15 #14.1
cmp r15, 200 #14.1
jb ..B1.5 # Prob 82% #14.1
..B1.7: # Preds ..B1.6
xor eax, eax #17.1
mov rsi, rbx #
mov r15, rax #19.44
mov QWORD PTR [rsp], r13 #19.44[spill]
mov QWORD PTR [8+rsp], r14 #19.44[spill]
..B1.8: # Preds ..B1.11 ..B1.7
mov r13, QWORD PTR [8+rbx+r15*8] #19.5
xor r14d, r14d #18.3
..B1.9: # Preds ..B1.10 ..B1.8
call rand #19.26
..B1.37: # Preds ..B1.9
mov r8d, eax #19.26
..B1.10: # Preds ..B1.37
mov eax, 351843721 #19.33
mov ecx, r8d #19.33
imul r8d #19.33
sar ecx, 31 #19.33
vxorpd xmm0, xmm0, xmm0 #19.33
sar edx, 13 #19.33
sub edx, ecx #19.33
imul edi, edx, -100000 #19.33
add r8d, edi #19.33
vcvtsi2sd xmm0, xmm0, r8d #19.33
vdivsd xmm1, xmm0, QWORD PTR .L_2il0floatpacket.0[rip] #19.44
vmovsd QWORD PTR [8+r13+r14*8], xmm1 #19.5
inc r14 #18.3
cmp r14, 198 #18.3
jb ..B1.9 # Prob 82% #18.3
..B1.11: # Preds ..B1.10
inc r15 #17.1
cmp r15, 198 #17.1
jb ..B1.8 # Prob 91% #17.1
..B1.12: # Preds ..B1.11
mov r13, QWORD PTR [rsp] #[spill]
mov rsi, rbx #
mov r14, QWORD PTR [8+rsp] #[spill]
xor ecx, ecx #23.1
vmovsd xmm0, QWORD PTR .L_2il0floatpacket.1[rip] #10.14
xor dil, dil #10.14
mov edx, 196 #10.14
..B1.13: # Preds ..B1.27 ..B1.12
mov rax, QWORD PTR [8+rsi+rcx*8] #25.5
mov r8, rax #25.5
lea r9, QWORD PTR [8+rax] #25.5
sub r8, r9 #25.5
cmp r8, 1584 #24.3
jge ..B1.15 # Prob 50% #24.3
..B1.14: # Preds ..B1.13
neg r8 #26.7
cmp r8, 1584 #24.3
jl ..B1.22 # Prob 50% #24.3
..B1.15: # Preds ..B1.13 ..B1.14
lea r8, QWORD PTR [16+rax] #27.9
sub r9, r8 #27.9
cmp r9, 1584 #24.3
jge ..B1.17 # Prob 50% #24.3
..B1.16: # Preds ..B1.15
neg r9 #25.5
cmp r9, 1584 #24.3
jl ..B1.22 # Prob 50% #24.3
..B1.17: # Preds ..B1.15 ..B1.16
vmovsd xmm1, QWORD PTR [rax] #27.9
mov bl, dil #24.3
mov r9, QWORD PTR [rsi+rcx*8] #27.21
xor r11d, r11d #25.5
mov r10, QWORD PTR [16+rsi+rcx*8] #26.19
mov r8, QWORD PTR [8+rsi+rcx*8] #27.9
..B1.18: # Preds ..B1.18 ..B1.17
vmovsd xmm2, QWORD PTR [8+r11+r10] #26.19
inc bl #24.3
vaddsd xmm3, xmm2, QWORD PTR [16+r11+r8] #25.5
vaddsd xmm4, xmm3, QWORD PTR [8+r11+r9] #25.5
vaddsd xmm1, xmm4, xmm1 #25.5
vmulsd xmm8, xmm0, xmm1 #27.21
vmovsd QWORD PTR [8+r11+r8], xmm8 #25.5
vmovsd xmm5, QWORD PTR [16+r11+r10] #26.19
vaddsd xmm6, xmm5, QWORD PTR [24+r11+r8] #26.19
vaddsd xmm7, xmm6, QWORD PTR [16+r11+r9] #27.9
vaddsd xmm9, xmm7, xmm8 #27.21
vmulsd xmm13, xmm0, xmm9 #27.21
vmovsd QWORD PTR [16+r11+r8], xmm13 #25.5
vmovsd xmm10, QWORD PTR [24+r11+r10] #26.19
vaddsd xmm11, xmm10, QWORD PTR [32+r11+r8] #26.19
vaddsd xmm12, xmm11, QWORD PTR [24+r11+r9] #27.9
vaddsd xmm14, xmm12, xmm13 #27.21
vmulsd xmm18, xmm0, xmm14 #27.21
vmovsd QWORD PTR [24+r11+r8], xmm18 #25.5
vmovsd xmm15, QWORD PTR [32+r11+r10] #26.19
vaddsd xmm16, xmm15, QWORD PTR [40+r11+r8] #26.19
vaddsd xmm17, xmm16, QWORD PTR [32+r11+r9] #27.9
vaddsd xmm19, xmm17, xmm18 #27.21
vmulsd xmm1, xmm0, xmm19 #27.21
vmovsd QWORD PTR [32+r11+r8], xmm1 #25.5
add r11, 32 #24.3
cmp bl, 49 #24.3
jb ..B1.18 # Prob 27% #24.3
..B1.19: # Preds ..B1.18
mov r11, rdx #24.3
..B1.20: # Preds ..B1.20 ..B1.19
vmovsd xmm1, QWORD PTR [r8+r11*8] #26.7
vaddsd xmm2, xmm1, QWORD PTR [8+r10+r11*8] #26.19
vaddsd xmm3, xmm2, QWORD PTR [16+r8+r11*8] #27.9
vaddsd xmm4, xmm3, QWORD PTR [8+r9+r11*8] #27.21
vmulsd xmm5, xmm0, xmm4 #27.21
vmovsd QWORD PTR [8+r8+r11*8], xmm5 #25.5
inc r11 #24.3
cmp r11, 198 #24.3
jb ..B1.20 # Prob 66% #24.3
jmp ..B1.27 # Prob 100% #24.3
..B1.22: # Preds ..B1.14 ..B1.16
mov r9, QWORD PTR [rsi+rcx*8] #27.21
mov bl, dil #24.3
mov r10, QWORD PTR [16+rsi+rcx*8] #26.19
xor r11d, r11d #25.5
mov r8, QWORD PTR [8+rsi+rcx*8] #26.7
..B1.23: # Preds ..B1.23 ..B1.22
inc bl #24.3
vmovsd xmm1, QWORD PTR [r11+r8] #26.7
vaddsd xmm2, xmm1, QWORD PTR [8+r11+r10] #26.19
vaddsd xmm3, xmm2, QWORD PTR [16+r11+r8] #27.9
vaddsd xmm4, xmm3, QWORD PTR [8+r11+r9] #27.21
vmulsd xmm5, xmm0, xmm4 #27.21
vmovsd QWORD PTR [8+r11+r8], xmm5 #25.5
vaddsd xmm6, xmm5, QWORD PTR [16+r11+r10] #26.19
vaddsd xmm7, xmm6, QWORD PTR [24+r11+r8] #27.9
vaddsd xmm8, xmm7, QWORD PTR [16+r11+r9] #27.21
vmulsd xmm9, xmm0, xmm8 #27.21
vmovsd QWORD PTR [16+r11+r8], xmm9 #25.5
vaddsd xmm10, xmm9, QWORD PTR [24+r11+r10] #26.19
vaddsd xmm11, xmm10, QWORD PTR [32+r11+r8] #27.9
vaddsd xmm12, xmm11, QWORD PTR [24+r11+r9] #27.21
vmulsd xmm13, xmm0, xmm12 #27.21
vmovsd QWORD PTR [24+r11+r8], xmm13 #25.5
vaddsd xmm14, xmm13, QWORD PTR [32+r11+r10] #26.19
vaddsd xmm15, xmm14, QWORD PTR [40+r11+r8] #27.9
vaddsd xmm16, xmm15, QWORD PTR [32+r11+r9] #27.21
vmulsd xmm17, xmm0, xmm16 #27.21
vmovsd QWORD PTR [32+r11+r8], xmm17 #25.5
add r11, 32 #24.3
cmp bl, 49 #24.3
jb ..B1.23 # Prob 27% #24.3
..B1.24: # Preds ..B1.23
mov r11, rdx #24.3
..B1.25: # Preds ..B1.25 ..B1.24
vmovsd xmm1, QWORD PTR [r8+r11*8] #26.7
vaddsd xmm2, xmm1, QWORD PTR [8+r10+r11*8] #26.19
vaddsd xmm3, xmm2, QWORD PTR [16+r8+r11*8] #27.9
vaddsd xmm4, xmm3, QWORD PTR [8+r9+r11*8] #27.21
vmulsd xmm5, xmm0, xmm4 #27.21
vmovsd QWORD PTR [8+r8+r11*8], xmm5 #25.5
inc r11 #24.3
cmp r11, 198 #24.3
jb ..B1.25 # Prob 66% #24.3
..B1.27: # Preds ..B1.25 ..B1.20
mov r8, QWORD PTR [16+rsi+rcx*8] #30.3
inc rcx #23.1
mov rax, QWORD PTR [1592+rax] #30.15
mov QWORD PTR [8+r8], rax #30.3
cmp rcx, 198 #23.1
jb ..B1.13 # Prob 91% #23.1
..B1.28: # Preds ..B1.27
mov rax, QWORD PTR [1584+rsi] #33.4
vmovsd xmm0, QWORD PTR [1584+rax] #33.4
vucomisd xmm0, QWORD PTR .L_2il0floatpacket.2[rip] #33.29
jp ..B1.29 # Prob 0% #33.29
je ..B1.30 # Prob 5% #33.29
..B1.29: # Preds ..B1.28 ..B1.30
xor eax, eax #34.1
add rsp, 112 #34.1
pop rbx #34.1
pop r15 #34.1
mov rsp, rbp #34.1
pop rbp #34.1
ret #34.1
..B1.30: # Preds ..B1.28
mov rax, QWORD PTR [rsi] #33.39
mov edi, offset flat: .L_2__STRING.0 #33.39
vmovsd xmm0, QWORD PTR [rax] #33.39
mov eax, 1 #33.39
call printf #33.39
jmp ..B1.29 # Prob 100% #33.39
.L_2il0floatpacket.0:
.long 0x00000000,0x408f4000
.L_2il0floatpacket.1:
.long 0x7ae147ae,0x3ff3ae14
.L_2il0floatpacket.2:
.long 0xfc8f3238,0x3ff3c0c1
.L_2__STRING.0:
.long 681509

View File

@@ -0,0 +1,9 @@
; https://godbolt.org/z/o49jjojnx /std:c++latest /O1 /fp:contract /arch:AVX2
$LL13@foo:
vmovsd xmm1, QWORD PTR [rax]
vmovsd xmm0, QWORD PTR [rcx+rax]
vfmadd213sd xmm1, xmm0, QWORD PTR [rdx+rax]
vmovsd QWORD PTR [r8+rax], xmm1
lea rax, QWORD PTR [rax+8]
sub rbx, 1
jne SHORT $LL13@foo

View File

@@ -0,0 +1,19 @@
; Translated from kernel_x86_memdep.s
L4:
vmovsd [rax+8], xmm0
add rax, 8
vmovsd [rax+rcx*8+8], xmm0
vaddsd xmm0, xmm0, [rax]
sub rax, -8
vaddsd xmm0, xmm0, [rax-8]
dec rcx
vaddsd xmm0, xmm0, [rax+rcx*8+8]
mov rdx, rcx
vaddsd xmm0, xmm0, [rax+rdx*8+8]
vmulsd xmm0, xmm0, xmm1
add rax, 8
cmp rsi, rax
jne L4
; Added to test LOAD dependencies
shl rax, 5
subsd xmm10, QWORD PTR [rax+r8]

View File

@@ -0,0 +1,124 @@
; Listing generated by Microsoft (R) Optimizing Compiler Version 19.41.34123.0
include listing.inc
INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES
msvcjmc SEGMENT
__FAC6D534_triad@c DB 01H
msvcjmc ENDS
PUBLIC kernel
PUBLIC __JustMyCode_Default
EXTRN dummy:PROC
EXTRN _RTC_InitBase:PROC
EXTRN _RTC_Shutdown:PROC
EXTRN __CheckForDebuggerJustMyCode:PROC
EXTRN _fltused:DWORD
; COMDAT pdata
pdata SEGMENT
$pdata$kernel DD imagerel $LN9
DD imagerel $LN9+194
DD imagerel $unwind$kernel
pdata ENDS
; COMDAT rtc$TMZ
rtc$TMZ SEGMENT
_RTC_Shutdown.rtc$TMZ DQ FLAT:_RTC_Shutdown
rtc$TMZ ENDS
; COMDAT rtc$IMZ
rtc$IMZ SEGMENT
_RTC_InitBase.rtc$IMZ DQ FLAT:_RTC_InitBase
rtc$IMZ ENDS
; COMDAT xdata
xdata SEGMENT
$unwind$kernel DD 025052301H
DD 011e2323H
DD 070170025H
DD 05016H
xdata ENDS
; Function compile flags: /Odt
; COMDAT __JustMyCode_Default
_TEXT SEGMENT
__JustMyCode_Default PROC ; COMDAT
ret 0
__JustMyCode_Default ENDP
_TEXT ENDS
; Function compile flags: /Odtp /RTCsu /ZI
; COMDAT kernel
_TEXT SEGMENT
r$1 = 4
i$2 = 36
a$ = 288
b$ = 296
c$ = 304
s$ = 312
repeat$ = 320
cur_elements$ = 328
kernel PROC ; COMDAT
; File C:\Users\phl.bastiani\Projects\OSACA\validation\kernels\triad.c
; Line 16
$LN9:
movsd QWORD PTR [rsp+32], xmm3
mov QWORD PTR [rsp+24], r8
mov QWORD PTR [rsp+16], rdx
mov QWORD PTR [rsp+8], rcx
push rbp
push rdi
sub rsp, 296 ; 00000128H
lea rbp, QWORD PTR [rsp+32]
lea rcx, OFFSET FLAT:__FAC6D534_triad@c
call __CheckForDebuggerJustMyCode
npad 1
; Line 17
mov DWORD PTR r$1[rbp], 0
jmp SHORT $LN4@kernel
$LN2@kernel:
mov eax, DWORD PTR r$1[rbp]
inc eax
mov DWORD PTR r$1[rbp], eax
$LN4@kernel:
mov eax, DWORD PTR repeat$[rbp]
cmp DWORD PTR r$1[rbp], eax
jge SHORT $LN3@kernel
; Line 18
mov DWORD PTR i$2[rbp], 0
jmp SHORT $LN7@kernel
$LN5@kernel:
mov eax, DWORD PTR i$2[rbp]
inc eax
mov DWORD PTR i$2[rbp], eax
$LN7@kernel:
mov eax, DWORD PTR cur_elements$[rbp]
cmp DWORD PTR i$2[rbp], eax
jge SHORT $LN6@kernel
; Line 19
movsxd rax, DWORD PTR i$2[rbp]
movsxd rcx, DWORD PTR i$2[rbp]
mov rdx, QWORD PTR c$[rbp]
movsd xmm0, QWORD PTR s$[rbp]
mulsd xmm0, QWORD PTR [rdx+rcx*8]
mov rcx, QWORD PTR b$[rbp]
movsd xmm1, QWORD PTR [rcx+rax*8]
addsd xmm1, xmm0
movaps xmm0, xmm1
movsxd rax, DWORD PTR i$2[rbp]
mov rcx, QWORD PTR a$[rbp]
movsd QWORD PTR [rcx+rax*8], xmm0
; Line 20
jmp SHORT $LN5@kernel
$LN6@kernel:
; Line 21
mov rcx, QWORD PTR a$[rbp]
call dummy
npad 1
; Line 22
jmp SHORT $LN2@kernel
$LN3@kernel:
; Line 23
lea rsp, QWORD PTR [rbp+264]
pop rdi
pop rbp
ret 0
kernel ENDP
_TEXT ENDS
END

View File

@@ -0,0 +1,139 @@
; Listing generated by Microsoft (R) Optimizing Compiler Version 19.41.34123.0
include listing.inc
INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES
msvcjmc SEGMENT
__68D132EB_concurrencysal@h DB 01H
__4DC47379_sal@h DB 01H
__B6ADDB23_vadefs@h DB 01H
__A2A1025A_vcruntime@h DB 01H
__0EF3BC42_intrin0@inl@h DB 01H
__5EC35D46_setjmp@h DB 01H
__368E74E0_mmintrin@h DB 01H
__735960E1_corecrt@h DB 01H
__211DB995_corecrt_malloc@h DB 01H
__7CD62D9E_malloc@h DB 01H
__22746E0E_xmmintrin@h DB 01H
__4716E7C2_emmintrin@h DB 01H
__98B78F4B_pmmintrin@h DB 01H
__286EFCC9_tmmintrin@h DB 01H
__0155E94A_smmintrin@h DB 01H
__64376086_nmmintrin@h DB 01H
__B18C9AC8_wmmintrin@h DB 01H
__7A18D7CF_zmmintrin@h DB 01H
__4D0C7505_immintrin@h DB 01H
__F7CF9440_ammintrin@h DB 01H
__78F5E131_intrin@h DB 01H
__6A584D4A_iacaMarks@h DB 01H
__FAC6D534_triad@c DB 01H
msvcjmc ENDS
PUBLIC kernel
PUBLIC __JustMyCode_Default
EXTRN dummy:PROC
EXTRN __CheckForDebuggerJustMyCode:PROC
EXTRN _fltused:DWORD
; COMDAT pdata
pdata SEGMENT
$pdata$kernel DD imagerel $LN18
DD imagerel $LN18+182
DD imagerel $unwind$kernel
pdata ENDS
; COMDAT voltbl
voltbl SEGMENT
_volmd DB 05bH
DB 079H
voltbl ENDS
; COMDAT xdata
xdata SEGMENT
$unwind$kernel DD 0c2001H
DD 026820H
DD 0b7419H
DD 0a6419H
DD 095419H
DD 083419H
DD 0e0155219H
xdata ENDS
; Function compile flags: /Odt
; COMDAT __JustMyCode_Default
_TEXT SEGMENT
__JustMyCode_Default PROC ; COMDAT
ret 0
__JustMyCode_Default ENDP
_TEXT ENDS
; Function compile flags: /Ogspy
; COMDAT kernel
_TEXT SEGMENT
a$ = 64
b$ = 72
c$ = 80
s$ = 88
repeat$ = 96
cur_elements$ = 104
kernel PROC ; COMDAT
; File C:\Users\phl.bastiani\Projects\OSACA\validation\kernels\triad.c
; Line 22
$LN18:
mov rax, rsp
mov QWORD PTR [rax+8], rbx
mov QWORD PTR [rax+16], rbp
mov QWORD PTR [rax+24], rsi
mov QWORD PTR [rax+32], rdi
push r14
sub rsp, 48 ; 00000030H
mov rbp, rcx
movaps XMMWORD PTR [rax-24], xmm6
lea rcx, OFFSET FLAT:__FAC6D534_triad@c
movaps xmm6, xmm3
mov r14, r8
mov rdi, rdx
call __CheckForDebuggerJustMyCode
mov eax, DWORD PTR repeat$[rsp]
movsxd rsi, DWORD PTR cur_elements$[rsp]
test eax, eax
jle SHORT $LN3@kernel
mov ebx, eax
$LL4@kernel:
; Line 24
test rsi, rsi
jle SHORT $LN6@kernel
mov rcx, r14
mov rdx, rbp
sub rcx, rdi
mov rax, rdi
sub rdx, rdi
mov r8, rsi
$LL7@kernel:
; Line 26
mov BYTE PTR gs:111, 111 ; 0000006fH
; Line 28
movaps xmm0, xmm6
mulsd xmm0, QWORD PTR [rax+rcx]
addsd xmm0, QWORD PTR [rax]
movsd QWORD PTR [rdx+rax], xmm0
add rax, 8
; Line 30
mov BYTE PTR gs:222, 222 ; 000000deH
sub r8, 1
jne SHORT $LL7@kernel
$LN6@kernel:
; Line 33
mov rcx, rbp
call dummy
sub rbx, 1
jne SHORT $LL4@kernel
$LN3@kernel:
; Line 35
mov rbx, QWORD PTR [rsp+64]
mov rbp, QWORD PTR [rsp+72]
mov rsi, QWORD PTR [rsp+80]
mov rdi, QWORD PTR [rsp+88]
movaps xmm6, XMMWORD PTR [rsp+32]
add rsp, 48 ; 00000030H
pop r14
ret 0
kernel ENDP
_TEXT ENDS
END

View File

@@ -114,7 +114,7 @@ class TestFrontend(unittest.TestCase):
self.assertEqual(line.line_number, analysis_dict["Kernel"][i]["LineNumber"])
def test_dict_output_AArch64(self):
reduced_kernel = reduce_to_section(self.kernel_AArch64, self.semantics_tx2._isa)
reduced_kernel = reduce_to_section(self.kernel_AArch64, self.semantics_tx2._isa, None)
dg = KernelDG(
reduced_kernel,
self.parser_AArch64,

View File

@@ -12,37 +12,47 @@ from osaca.semantics import (
find_jump_labels,
find_basic_loop_bodies,
)
from osaca.parser import ParserAArch64, ParserX86ATT
from osaca.parser import ParserAArch64, ParserX86ATT, ParserX86Intel
class TestMarkerUtils(unittest.TestCase):
@classmethod
def setUpClass(self):
self.parser_AArch = ParserAArch64()
self.parser_x86 = ParserX86ATT()
self.parser_x86_att = ParserX86ATT()
self.parser_x86_intel = ParserX86Intel()
with open(self._find_file("triad_arm_iaca.s")) as f:
triad_code_arm = f.read()
with open(self._find_file("triad_x86_iaca.s")) as f:
triad_code_x86 = f.read()
triad_code_x86_att = f.read()
with open(self._find_file("triad_x86_intel_iaca.asm")) as f:
triad_code_x86_intel = f.read()
self.parsed_AArch = self.parser_AArch.parse_file(triad_code_arm)
self.parsed_x86 = self.parser_x86.parse_file(triad_code_x86)
self.parsed_x86_att = self.parser_x86_att.parse_file(triad_code_x86_att)
self.parsed_x86_intel = self.parser_x86_intel.parse_file(triad_code_x86_intel)
#################
# Test
#################
def test_marker_detection_AArch64(self):
kernel = reduce_to_section(self.parsed_AArch, "AArch64")
kernel = reduce_to_section(self.parsed_AArch, ParserAArch64())
self.assertEqual(len(kernel), 138)
self.assertEqual(kernel[0].line_number, 307)
self.assertEqual(kernel[-1].line_number, 444)
def test_marker_detection_x86(self):
kernel = reduce_to_section(self.parsed_x86, "x86")
def test_marker_detection_x86_att(self):
kernel = reduce_to_section(self.parsed_x86_att, ParserX86ATT())
self.assertEqual(len(kernel), 9)
self.assertEqual(kernel[0].line_number, 146)
self.assertEqual(kernel[-1].line_number, 154)
def test_marker_detection_x86_intel(self):
kernel = reduce_to_section(self.parsed_x86_intel, ParserX86Intel())
self.assertEqual(len(kernel), 7)
self.assertEqual(kernel[0].line_number, 111)
self.assertEqual(kernel[-1].line_number, 117)
def test_marker_matching_AArch64(self):
# preparation
bytes_1_line = ".byte 213,3,32,31\n"
@@ -108,7 +118,7 @@ class TestMarkerUtils(unittest.TestCase):
bytes_end=bytes_var_2,
):
sample_parsed = self.parser_AArch.parse_file(sample_code)
sample_kernel = reduce_to_section(sample_parsed, "AArch64")
sample_kernel = reduce_to_section(sample_parsed, ParserAArch64())
self.assertEqual(len(sample_kernel), kernel_length)
kernel_start = len(
list(
@@ -179,8 +189,8 @@ class TestMarkerUtils(unittest.TestCase):
mov_end=mov_end_var,
bytes_end=bytes_var_2,
):
sample_parsed = self.parser_x86.parse_file(sample_code)
sample_kernel = reduce_to_section(sample_parsed, "x86")
sample_parsed = self.parser_x86_att.parse_file(sample_code)
sample_kernel = reduce_to_section(sample_parsed, ParserX86ATT())
self.assertEqual(len(sample_kernel), kernel_length)
kernel_start = len(
list(
@@ -190,7 +200,7 @@ class TestMarkerUtils(unittest.TestCase):
)
)
)
parsed_kernel = self.parser_x86.parse_file(
parsed_kernel = self.parser_x86_att.parse_file(
kernel, start_line=kernel_start
)
self.assertEqual(sample_kernel, parsed_kernel)
@@ -222,7 +232,7 @@ class TestMarkerUtils(unittest.TestCase):
for test_name, pro, kernel, epi in samples:
code = pro + kernel + epi
parsed = self.parser_AArch.parse_file(code)
test_kernel = reduce_to_section(parsed, "AArch64")
test_kernel = reduce_to_section(parsed, ParserAArch64())
if kernel:
kernel_length = len(kernel.strip().split("\n"))
else:
@@ -230,7 +240,7 @@ class TestMarkerUtils(unittest.TestCase):
self.assertEqual(
len(test_kernel),
kernel_length,
msg="Invalid exctracted kernel length on {!r} sample".format(test_name),
msg="Invalid extracted kernel length on {!r} sample".format(test_name),
)
if pro:
kernel_start = len((pro).strip().split("\n"))
@@ -240,7 +250,7 @@ class TestMarkerUtils(unittest.TestCase):
self.assertEqual(
test_kernel,
parsed_kernel,
msg="Invalid exctracted kernel on {!r}".format(test_name),
msg="Invalid extracted kernel on {!r}".format(test_name),
)
def test_marker_special_cases_x86(self):
@@ -269,8 +279,8 @@ class TestMarkerUtils(unittest.TestCase):
for test_name, pro, kernel, epi in samples:
code = pro + kernel + epi
parsed = self.parser_x86.parse_file(code)
test_kernel = reduce_to_section(parsed, "x86")
parsed = self.parser_x86_att.parse_file(code)
test_kernel = reduce_to_section(parsed, ParserX86ATT())
if kernel:
kernel_length = len(kernel.strip().split("\n"))
else:
@@ -278,23 +288,23 @@ class TestMarkerUtils(unittest.TestCase):
self.assertEqual(
len(test_kernel),
kernel_length,
msg="Invalid exctracted kernel length on {!r} sample".format(test_name),
msg="Invalid extracted kernel length on {!r} sample".format(test_name),
)
if pro:
kernel_start = len((pro).strip().split("\n"))
else:
kernel_start = 0
parsed_kernel = self.parser_x86.parse_file(kernel, start_line=kernel_start)
parsed_kernel = self.parser_x86_att.parse_file(kernel, start_line=kernel_start)
self.assertEqual(
test_kernel,
parsed_kernel,
msg="Invalid exctracted kernel on {!r}".format(test_name),
msg="Invalid extracted kernel on {!r}".format(test_name),
)
def test_find_jump_labels(self):
self.assertEqual(
find_jump_labels(self.parsed_x86),
find_jump_labels(self.parsed_x86_att),
OrderedDict(
[
(".LFB24", 10),
@@ -358,7 +368,7 @@ class TestMarkerUtils(unittest.TestCase):
self.assertEqual(
[
(k, v[0].line_number, v[-1].line_number)
for k, v in find_basic_blocks(self.parsed_x86).items()
for k, v in find_basic_blocks(self.parsed_x86_att).items()
],
[
(".LFB24", 11, 56),
@@ -422,7 +432,7 @@ class TestMarkerUtils(unittest.TestCase):
self.assertEqual(
[
(k, v[0].line_number, v[-1].line_number)
for k, v in find_basic_loop_bodies(self.parsed_x86).items()
for k, v in find_basic_loop_bodies(self.parsed_x86_att).items()
],
[(".L4", 66, 74), (".L10", 146, 154), (".L28", 290, 300)],
)

View File

@@ -0,0 +1,365 @@
#!/usr/bin/env python3
"""
Unit tests for x86 Intel assembly parser
"""
import os
import unittest
from pyparsing import ParseException
from osaca.parser import ParserX86Intel, InstructionForm
from osaca.parser.directive import DirectiveOperand
from osaca.parser.identifier import IdentifierOperand
from osaca.parser.immediate import ImmediateOperand
from osaca.parser.label import LabelOperand
from osaca.parser.memory import MemoryOperand
from osaca.parser.register import RegisterOperand
class TestParserX86Intel(unittest.TestCase):
@classmethod
def setUpClass(self):
self.parser = ParserX86Intel()
with open(self._find_file("triad_x86_intel.asm")) as f:
self.triad_code = f.read()
with open(self._find_file("triad_x86_intel_iaca.asm")) as f:
self.triad_iaca_code = f.read()
with open(self._find_file("gs_x86_icc.asm")) as f:
self.gs_icc_code = f.read()
##################
# Test
##################
def test_comment_parser(self):
self.assertEqual(self._get_comment(self.parser, "; some comments"), "some comments")
self.assertEqual(self._get_comment(self.parser, "\t\t;AA BB CC \t end \t"), "AA BB CC end")
self.assertEqual(
self._get_comment(self.parser, "\t;; comment ;; comment"),
"; comment ;; comment",
)
def test_label_parser(self):
self.assertEqual(self._get_label(self.parser, "main:")[0].name, "main")
self.assertEqual(self._get_label(self.parser, "$$B1?10:")[0].name, "$$B1?10")
self.assertEqual(
self._get_label(self.parser, "$LN9:\tcall\t__CheckForDebuggerJustMyCode")[0].name,
"$LN9"
)
self.assertEqual(
self._get_label(self.parser, "$LN9:\tcall\t__CheckForDebuggerJustMyCode")[1],
InstructionForm(
mnemonic="call",
operands=[
{"identifier": {"name": "__CheckForDebuggerJustMyCode"}},
],
directive_id=None,
comment_id=None,
label_id=None,
line=None,
line_number=None,
)
)
def test_directive_parser(self):
self.assertEqual(self._get_directive(self.parser, "\t.allocstack 16")[0],
DirectiveOperand(name=".allocstack",
parameters=["16"]))
self.assertEqual(self._get_directive(self.parser, "INCLUDELIB MSVCRTD")[0],
DirectiveOperand(name="INCLUDELIB",
parameters=["MSVCRTD"]))
self.assertEqual(self._get_directive(self.parser, "msvcjmc\tSEGMENT")[0],
DirectiveOperand(name="SEGMENT",
parameters=["msvcjmc"]))
self.assertEqual(self._get_directive(self.parser, "EXTRN\t_RTC_InitBase:PROC")[0],
DirectiveOperand(name="EXTRN",
parameters=["_RTC_InitBase:PROC"]))
self.assertEqual(self._get_directive(self.parser, "$pdata$kernel DD imagerel $LN9")[0],
DirectiveOperand(name="DD",
parameters=["$pdata$kernel", "imagerel", "$LN9"]))
self.assertEqual(self._get_directive(self.parser, "repeat$ = 320")[0],
DirectiveOperand(name="=",
parameters=["repeat$", "320"]))
def test_parse_instruction(self):
instr1 = "\tsub\trsp, 296\t\t\t\t; 00000128H"
instr2 = " fst ST(3)\t; Good ol' x87."
instr3 = "\tmulsd\txmm0, QWORD PTR [rdx+rcx*8]"
instr4 = "\tmov\teax, DWORD PTR cur_elements$[rbp]"
instr5 = "\tmov\tQWORD PTR [rsp+24], r8"
instr6 = "\tjmp\tSHORT $LN2@kernel"
instr7 = "\tlea\trcx, OFFSET FLAT:__FAC6D534_triad@c"
instr8 = "\tmov\tBYTE PTR gs:111, al"
instr9 = "\tlea\tr8, QWORD PTR [r8*4]"
instr10 = "\tmovsd\txmm1, QWORD PTR boost@@XZ@4V456@A+16"
instr11 = "\tlea\trcx, OFFSET FLAT:??_R0N@8+8"
instr12 = "\tvfmadd213sd xmm0, xmm1, QWORD PTR __real@bfc5555555555555"
instr13 = "\tjmp\t$LN18@operator"
parsed_1 = self.parser.parse_instruction(instr1)
parsed_2 = self.parser.parse_instruction(instr2)
parsed_3 = self.parser.parse_instruction(instr3)
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)
parsed_8 = self.parser.parse_instruction(instr8)
parsed_9 = self.parser.parse_instruction(instr9)
parsed_10 = self.parser.parse_instruction(instr10)
parsed_11 = self.parser.parse_instruction(instr11)
parsed_12 = self.parser.parse_instruction(instr12)
parsed_13 = self.parser.parse_instruction(instr13)
self.assertEqual(parsed_1.mnemonic, "sub")
self.assertEqual(parsed_1.operands[0],
RegisterOperand(name="RSP"))
self.assertEqual(parsed_1.operands[1],
ImmediateOperand(value=296))
self.assertEqual(parsed_1.comment, "00000128H")
self.assertEqual(parsed_2.mnemonic, "fst")
self.assertEqual(parsed_2.operands[0],
RegisterOperand(name="ST(3)"))
self.assertEqual(parsed_2.comment, "Good ol' x87.")
self.assertEqual(parsed_3.mnemonic, "mulsd")
self.assertEqual(parsed_3.operands[0],
RegisterOperand(name="XMM0"))
self.assertEqual(parsed_3.operands[1],
MemoryOperand(base=RegisterOperand(name="RDX"),
index=RegisterOperand(name="RCX"),
scale=8))
self.assertEqual(parsed_4.mnemonic, "mov")
self.assertEqual(parsed_4.operands[0],
RegisterOperand(name="EAX"))
self.assertEqual(parsed_4.operands[1],
MemoryOperand(offset=ImmediateOperand(
identifier="cur_elements$",
value=104
),
base=RegisterOperand(name="RBP")))
self.assertEqual(parsed_5.mnemonic, "mov")
self.assertEqual(parsed_5.operands[0],
MemoryOperand(offset=ImmediateOperand(value=24),
base=RegisterOperand(name="RSP")))
self.assertEqual(parsed_5.operands[1],
RegisterOperand(name="R8"))
self.assertEqual(parsed_6.mnemonic, "jmp")
self.assertEqual(parsed_6.operands[0],
LabelOperand(name="$LN2@kernel"))
self.assertEqual(parsed_7.mnemonic, "lea")
self.assertEqual(parsed_7.operands[0],
RegisterOperand(name="RCX"))
self.assertEqual(parsed_7.operands[1],
MemoryOperand(offset=IdentifierOperand(name="__FAC6D534_triad@c")))
self.assertEqual(parsed_8.mnemonic, "mov")
self.assertEqual(parsed_8.operands[0],
MemoryOperand(
base=RegisterOperand(name="GS"),
offset=ImmediateOperand(value=111)))
self.assertEqual(parsed_8.operands[1],
RegisterOperand(name="AL"))
self.assertEqual(parsed_9.mnemonic, "lea")
self.assertEqual(parsed_9.operands[0],
RegisterOperand(name="R8"))
self.assertEqual(parsed_9.operands[1],
MemoryOperand(base=None,
index=RegisterOperand(name="R8"),
scale=4))
self.assertEqual(parsed_10.mnemonic, "movsd")
self.assertEqual(parsed_10.operands[0],
RegisterOperand(name="XMM1"))
self.assertEqual(parsed_10.operands[1],
MemoryOperand(offset=IdentifierOperand(name="boost@@XZ@4V456@A",
offset=ImmediateOperand(value=16))))
self.assertEqual(parsed_11.mnemonic, "lea")
self.assertEqual(parsed_11.operands[0],
RegisterOperand(name="RCX"))
self.assertEqual(parsed_11.operands[1],
MemoryOperand(offset=IdentifierOperand(name="??_R0N@8",
offset=ImmediateOperand(value=8))))
self.assertEqual(parsed_12.mnemonic, "vfmadd213sd")
self.assertEqual(parsed_12.operands[0],
RegisterOperand(name="XMM0"))
self.assertEqual(parsed_12.operands[1],
RegisterOperand(name="XMM1"))
self.assertEqual(parsed_12.operands[2],
MemoryOperand(offset=IdentifierOperand(name="__real@bfc5555555555555")))
self.assertEqual(parsed_13.mnemonic, "jmp")
self.assertEqual(parsed_13.operands[0],
IdentifierOperand(name="$LN18@operator"))
def test_parse_line(self):
line_comment = "; -- Begin main"
line_instruction = "\tret\t0"
instruction_form_1 = InstructionForm(
mnemonic=None,
operands=[],
directive_id=None,
comment_id="-- Begin main",
label_id=None,
line="; -- Begin main",
line_number=1,
)
instruction_form_2 = InstructionForm(
mnemonic="ret",
operands=[
{"immediate": {"value": 0}},
],
directive_id=None,
comment_id=None,
label_id=None,
line="\tret\t0",
line_number=2,
)
parsed_1 = self.parser.parse_line(line_comment, 1)
parsed_2 = self.parser.parse_line(line_instruction, 2)
self.assertEqual(parsed_1, instruction_form_1)
self.assertEqual(parsed_2, instruction_form_2)
def test_parse_register(self):
register_str_1 = "rax"
register_str_2 = "r9"
register_str_3 = "xmm1"
register_str_4 = "ST(4)"
parsed_reg_1 = RegisterOperand(name="RAX")
parsed_reg_2 = RegisterOperand(name="R9")
parsed_reg_3 = RegisterOperand(name="XMM1")
parsed_reg_4 = RegisterOperand(name="ST(4)")
self.assertEqual(self.parser.parse_register(register_str_1), parsed_reg_1)
self.assertEqual(self.parser.parse_register(register_str_2), parsed_reg_2)
self.assertEqual(self.parser.parse_register(register_str_3), parsed_reg_3)
self.assertEqual(self.parser.parse_register(register_str_4), parsed_reg_4)
def test_parse_file1(self):
parsed = self.parser.parse_file(self.triad_code)
self.assertEqual(parsed[0].line_number, 1)
# Check specifically that the values of the symbols defined by "=" were correctly
# propagated.
self.assertEqual(parsed[69],
InstructionForm(mnemonic="mov",
operands=[MemoryOperand(
base=RegisterOperand("RBP"),
offset=ImmediateOperand(
value=4,
identifier="r$1"
)
),
ImmediateOperand(value=0)],
line="\tmov\tDWORD PTR r$1[rbp], 0",
line_number=73))
# Check a few lines to make sure that we produced something reasonable.
self.assertEqual(parsed[60],
InstructionForm(mnemonic="mov",
operands=[MemoryOperand(base=RegisterOperand("RSP"),
offset=ImmediateOperand(value=8)),
RegisterOperand(name="RCX")],
line="\tmov\tQWORD PTR [rsp+8], rcx",
line_number=64))
self.assertEqual(parsed[120],
InstructionForm(directive_id=DirectiveOperand(name="END"),
line="END",
line_number=124))
self.assertEqual(len(parsed), 121)
def test_parse_file2(self):
parsed = self.parser.parse_file(self.triad_iaca_code)
self.assertEqual(parsed[0].line_number, 1)
# Check a few lines to make sure that we produced something reasonable.
self.assertEqual(parsed[68],
InstructionForm(directive_id=DirectiveOperand(name="=",
parameters=["s$", "88"]),
line="s$ = 88",
line_number=72))
self.assertEqual(parsed[135],
InstructionForm(directive_id=DirectiveOperand(name="END"),
line="END",
line_number=139))
self.assertEqual(len(parsed), 136)
def test_parse_file3(self):
parsed = self.parser.parse_file(self.gs_icc_code)
self.assertEqual(parsed[0].line_number, 1)
# Check a few lines to make sure that we produced something reasonable.
self.assertEqual(parsed[113],
InstructionForm(mnemonic="vmovsd",
operands=[RegisterOperand("XMM5"),
MemoryOperand(base=RegisterOperand("R11"),
index=RegisterOperand("R10"),
scale=1,
offset=ImmediateOperand(value=16))],
comment_id="26.19",
line=" vmovsd xmm5, QWORD PTR [16+r11+r10]"
+ " #26.19",
line_number=114))
self.assertEqual(parsed[226],
InstructionForm(directive_id=DirectiveOperand(name=".long",
parameters=["681509"]),
line=" .long 681509",
line_number=227))
self.assertEqual(len(parsed), 227)
def test_normalize_imd(self):
imd_binary = ImmediateOperand(value="1001111B")
imd_octal = ImmediateOperand(value="117O")
imd_decimal = ImmediateOperand(value="79")
imd_hex = ImmediateOperand(value="4fH")
imd_float = ImmediateOperand(value="-79.34")
self.assertEqual(
self.parser.normalize_imd(imd_binary),
self.parser.normalize_imd(imd_octal),
)
self.assertEqual(
self.parser.normalize_imd(imd_octal),
self.parser.normalize_imd(imd_decimal),
)
self.assertEqual(
self.parser.normalize_imd(imd_decimal),
self.parser.normalize_imd(imd_hex),
)
self.assertEqual(self.parser.normalize_imd(ImmediateOperand(value="-79")), -79)
self.assertEqual(self.parser.normalize_imd(imd_float), -79.34)
##################
# Helper functions
##################
def _get_comment(self, parser, comment):
return " ".join(
parser.process_operand(parser.comment.parseString(comment, parseAll=True))[
"comment"
]
)
def _get_label(self, parser, label):
return parser.process_operand(parser.label.parseString(label, parseAll=True))
def _get_directive(self, parser, directive):
return parser.process_operand(parser.directive.parseString(directive, parseAll=True))
@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(TestParserX86Intel)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -10,7 +10,7 @@ from copy import deepcopy
import networkx as nx
from osaca.osaca import get_unmatched_instruction_ratio
from osaca.parser import ParserAArch64, ParserX86ATT
from osaca.parser import ParserAArch64, ParserX86ATT, ParserX86Intel
from osaca.semantics import (
INSTR_FLAGS,
ArchSemantics,
@@ -32,7 +32,8 @@ class TestSemanticTools(unittest.TestCase):
@classmethod
def setUpClass(cls):
# set up parser and kernels
cls.parser_x86 = ParserX86ATT()
cls.parser_x86_att = ParserX86ATT()
cls.parser_x86_intel = ParserX86Intel()
cls.parser_AArch64 = ParserAArch64()
with open(cls._find_file("kernel_x86.s")) as f:
cls.code_x86 = f.read()
@@ -40,6 +41,10 @@ class TestSemanticTools(unittest.TestCase):
cls.code_x86_memdep = f.read()
with open(cls._find_file("kernel_x86_long_LCD.s")) as f:
cls.code_x86_long_LCD = f.read()
with open(cls._find_file("kernel_x86_intel.asm")) as f:
cls.code_x86_intel = f.read()
with open(cls._find_file("kernel_x86_intel_memdep.asm")) as f:
cls.code_x86_intel_memdep = f.read()
with open(cls._find_file("kernel_aarch64_memdep.s")) as f:
cls.code_aarch64_memdep = f.read()
with open(cls._find_file("kernel_aarch64.s")) as f:
@@ -48,24 +53,41 @@ class TestSemanticTools(unittest.TestCase):
cls.code_AArch64_SVE = f.read()
with open(cls._find_file("kernel_aarch64_deps.s")) as f:
cls.code_AArch64_deps = f.read()
cls.kernel_x86 = reduce_to_section(cls.parser_x86.parse_file(cls.code_x86), "x86")
cls.kernel_x86 = reduce_to_section(
cls.parser_x86_att.parse_file(cls.code_x86),
cls.parser_x86_att
)
cls.kernel_x86_memdep = reduce_to_section(
cls.parser_x86.parse_file(cls.code_x86_memdep), "x86"
cls.parser_x86_att.parse_file(cls.code_x86_memdep),
cls.parser_x86_att
)
cls.kernel_x86_long_LCD = reduce_to_section(
cls.parser_x86.parse_file(cls.code_x86_long_LCD), "x86"
cls.parser_x86_att.parse_file(cls.code_x86_long_LCD),
cls.parser_x86_att
)
cls.kernel_x86_intel = reduce_to_section(
cls.parser_x86_intel.parse_file(cls.code_x86_intel),
cls.parser_x86_intel
)
cls.kernel_x86_intel_memdep = reduce_to_section(
cls.parser_x86_intel.parse_file(cls.code_x86_intel_memdep),
cls.parser_x86_intel
)
cls.kernel_AArch64 = reduce_to_section(
cls.parser_AArch64.parse_file(cls.code_AArch64), "aarch64"
cls.parser_AArch64.parse_file(cls.code_AArch64),
cls.parser_AArch64
)
cls.kernel_aarch64_memdep = reduce_to_section(
cls.parser_AArch64.parse_file(cls.code_aarch64_memdep), "aarch64"
cls.parser_AArch64.parse_file(cls.code_aarch64_memdep),
cls.parser_AArch64
)
cls.kernel_aarch64_SVE = reduce_to_section(
cls.parser_AArch64.parse_file(cls.code_AArch64_SVE), "aarch64"
cls.parser_AArch64.parse_file(cls.code_AArch64_SVE),
cls.parser_AArch64
)
cls.kernel_aarch64_deps = reduce_to_section(
cls.parser_AArch64.parse_file(cls.code_AArch64_deps), "aarch64"
cls.parser_AArch64.parse_file(cls.code_AArch64_deps),
cls.parser_AArch64
)
# set up machine models
@@ -78,40 +100,64 @@ class TestSemanticTools(unittest.TestCase):
cls.machine_model_a64fx = MachineModel(
path_to_yaml=os.path.join(cls.MODULE_DATA_DIR, "a64fx.yml")
)
cls.semantics_x86 = ISASemantics("x86")
cls.semantics_x86 = ISASemantics(cls.parser_x86_att)
cls.semantics_csx = ArchSemantics(
cls.parser_x86_att,
cls.machine_model_csx,
path_to_yaml=os.path.join(cls.MODULE_DATA_DIR, "isa/x86.yml"),
)
cls.semantics_aarch64 = ISASemantics("aarch64")
cls.semantics_x86_intel = ISASemantics(cls.parser_x86_intel)
cls.semantics_csx_intel = ArchSemantics(
cls.parser_x86_intel,
cls.machine_model_csx,
path_to_yaml=os.path.join(cls.MODULE_DATA_DIR, "isa/x86.yml"),
)
cls.semantics_aarch64 = ISASemantics(cls.parser_AArch64)
cls.semantics_tx2 = ArchSemantics(
cls.parser_AArch64,
cls.machine_model_tx2,
path_to_yaml=os.path.join(cls.MODULE_DATA_DIR, "isa/aarch64.yml"),
)
cls.semantics_a64fx = ArchSemantics(
cls.parser_AArch64,
cls.machine_model_a64fx,
path_to_yaml=os.path.join(cls.MODULE_DATA_DIR, "isa/aarch64.yml"),
)
cls.machine_model_zen = MachineModel(arch="zen1")
cls.semantics_csx.normalize_instruction_forms(cls.kernel_x86)
for i in range(len(cls.kernel_x86)):
cls.semantics_csx.assign_src_dst(cls.kernel_x86[i])
cls.semantics_csx.assign_tp_lt(cls.kernel_x86[i])
cls.semantics_csx.normalize_instruction_forms(cls.kernel_x86_memdep)
for i in range(len(cls.kernel_x86_memdep)):
cls.semantics_csx.assign_src_dst(cls.kernel_x86_memdep[i])
cls.semantics_csx.assign_tp_lt(cls.kernel_x86_memdep[i])
cls.semantics_csx.normalize_instruction_forms(cls.kernel_x86_long_LCD)
for i in range(len(cls.kernel_x86_long_LCD)):
cls.semantics_csx.assign_src_dst(cls.kernel_x86_long_LCD[i])
cls.semantics_csx.assign_tp_lt(cls.kernel_x86_long_LCD[i])
cls.semantics_csx_intel.normalize_instruction_forms(cls.kernel_x86_intel)
for i in range(len(cls.kernel_x86_intel)):
cls.semantics_csx_intel.assign_src_dst(cls.kernel_x86_intel[i])
cls.semantics_csx_intel.assign_tp_lt(cls.kernel_x86_intel[i])
cls.semantics_csx_intel.normalize_instruction_forms(cls.kernel_x86_intel_memdep)
for i in range(len(cls.kernel_x86_intel_memdep)):
cls.semantics_csx_intel.assign_src_dst(cls.kernel_x86_intel_memdep[i])
cls.semantics_csx_intel.assign_tp_lt(cls.kernel_x86_intel_memdep[i])
cls.semantics_tx2.normalize_instruction_forms(cls.kernel_AArch64)
for i in range(len(cls.kernel_AArch64)):
cls.semantics_tx2.assign_src_dst(cls.kernel_AArch64[i])
cls.semantics_tx2.assign_tp_lt(cls.kernel_AArch64[i])
cls.semantics_tx2.normalize_instruction_forms(cls.kernel_aarch64_memdep)
for i in range(len(cls.kernel_aarch64_memdep)):
cls.semantics_tx2.assign_src_dst(cls.kernel_aarch64_memdep[i])
cls.semantics_tx2.assign_tp_lt(cls.kernel_aarch64_memdep[i])
cls.semantics_a64fx.normalize_instruction_forms(cls.kernel_aarch64_SVE)
for i in range(len(cls.kernel_aarch64_SVE)):
cls.semantics_a64fx.assign_src_dst(cls.kernel_aarch64_SVE[i])
cls.semantics_a64fx.assign_tp_lt(cls.kernel_aarch64_SVE[i])
cls.semantics_a64fx.normalize_instruction_forms(cls.kernel_aarch64_deps)
for i in range(len(cls.kernel_aarch64_deps)):
cls.semantics_a64fx.assign_src_dst(cls.kernel_aarch64_deps[i])
cls.semantics_a64fx.assign_tp_lt(cls.kernel_aarch64_deps[i])
@@ -123,7 +169,7 @@ class TestSemanticTools(unittest.TestCase):
def test_creation_by_name(self):
try:
tmp_mm = MachineModel(arch="CSX")
ArchSemantics(tmp_mm)
ArchSemantics(self.parser_x86_att, tmp_mm)
except ValueError:
self.fail()
@@ -254,7 +300,7 @@ class TestSemanticTools(unittest.TestCase):
test_mm_arm.add_port("dummyPort")
# test dump of DB
with open("/dev/null", "w") as dev_null:
with open(os.devnull, "w") as dev_null:
test_mm_x86.dump(stream=dev_null)
test_mm_arm.dump(stream=dev_null)
@@ -266,6 +312,14 @@ class TestSemanticTools(unittest.TestCase):
self.assertTrue("destination" in instruction_form.semantic_operands)
self.assertTrue("src_dst" in instruction_form.semantic_operands)
def test_src_dst_assignment_x86_intel(self):
for instruction_form in self.kernel_x86_intel:
with self.subTest(instruction_form=instruction_form):
if instruction_form.semantic_operands is not None:
self.assertTrue("source" in instruction_form.semantic_operands)
self.assertTrue("destination" in instruction_form.semantic_operands)
self.assertTrue("src_dst" in instruction_form.semantic_operands)
def test_src_dst_assignment_AArch64(self):
for instruction_form in self.kernel_AArch64:
with self.subTest(instruction_form=instruction_form):
@@ -284,6 +338,16 @@ class TestSemanticTools(unittest.TestCase):
self.assertIsInstance(instruction_form.port_pressure, list)
self.assertEqual(len(instruction_form.port_pressure), port_num)
def test_tp_lt_assignment_x86_intel(self):
self.assertTrue("ports" in self.machine_model_csx)
port_num = len(self.machine_model_csx["ports"])
for instruction_form in self.kernel_x86_intel:
with self.subTest(instruction_form=instruction_form):
self.assertTrue(instruction_form.throughput is not None)
self.assertTrue(instruction_form.latency is not None)
self.assertIsInstance(instruction_form.port_pressure, list)
self.assertEqual(len(instruction_form.port_pressure), port_num)
def test_tp_lt_assignment_AArch64(self):
self.assertTrue("ports" in self.machine_model_tx2)
port_num = len(self.machine_model_tx2["ports"])
@@ -294,8 +358,7 @@ class TestSemanticTools(unittest.TestCase):
self.assertIsInstance(instruction_form.port_pressure, list)
self.assertEqual(len(instruction_form.port_pressure), port_num)
def test_optimal_throughput_assignment(self):
# x86
def test_optimal_throughput_assignment_x86(self):
kernel_fixed = deepcopy(self.kernel_x86)
self.semantics_csx.add_semantics(kernel_fixed)
self.assertEqual(get_unmatched_instruction_ratio(kernel_fixed), 0)
@@ -308,11 +371,13 @@ class TestSemanticTools(unittest.TestCase):
self.assertTrue(max(tp_optimal) <= max(tp_fixed))
# test multiple port assignment options
test_mm_x86 = MachineModel(path_to_yaml=self._find_file("test_db_x86.yml"))
tmp_semantics = ArchSemantics(test_mm_x86)
tmp_semantics = ArchSemantics(self.parser_x86_att, test_mm_x86)
tmp_code_1 = "fantasyinstr1 %rax, %rax\n"
tmp_code_2 = "fantasyinstr1 %rax, %rax\nfantasyinstr2 %rbx, %rbx\n"
tmp_kernel_1 = self.parser_x86.parse_file(tmp_code_1)
tmp_kernel_2 = self.parser_x86.parse_file(tmp_code_2)
tmp_kernel_1 = self.parser_x86_att.parse_file(tmp_code_1)
tmp_kernel_2 = self.parser_x86_att.parse_file(tmp_code_2)
tmp_semantics.normalize_instruction_forms(tmp_kernel_1)
tmp_semantics.normalize_instruction_forms(tmp_kernel_2)
tmp_semantics.add_semantics(tmp_kernel_1)
tmp_semantics.add_semantics(tmp_kernel_2)
tmp_semantics.assign_optimal_throughput(tmp_kernel_1)
@@ -322,7 +387,36 @@ class TestSemanticTools(unittest.TestCase):
self.assertEqual(k1i1_pp, [0.33, 0.0, 0.33, 0.0, 0.0, 0.0, 0.0, 0.0, 0.33, 0.0, 0.0])
self.assertEqual(k2i1_pp, [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0])
# arm
def test_optimal_throughput_assignment_x86_intel(self):
kernel_fixed = deepcopy(self.kernel_x86_intel)
self.semantics_csx_intel.add_semantics(kernel_fixed)
self.assertEqual(get_unmatched_instruction_ratio(kernel_fixed), 0)
kernel_optimal = deepcopy(kernel_fixed)
self.semantics_csx_intel.assign_optimal_throughput(kernel_optimal)
tp_fixed = self.semantics_csx_intel.get_throughput_sum(kernel_fixed)
tp_optimal = self.semantics_csx_intel.get_throughput_sum(kernel_optimal)
self.assertNotEqual(tp_fixed, tp_optimal)
self.assertTrue(max(tp_optimal) <= max(tp_fixed))
# test multiple port assignment options
test_mm_x86 = MachineModel(path_to_yaml=self._find_file("test_db_x86.yml"))
tmp_semantics = ArchSemantics(self.parser_x86_intel, test_mm_x86)
tmp_code_1 = "fantasyinstr1 rax, rax\n"
tmp_code_2 = "fantasyinstr1 rax, rax\nfantasyinstr2 rbx, rbx\n"
tmp_kernel_1 = self.parser_x86_intel.parse_file(tmp_code_1)
tmp_kernel_2 = self.parser_x86_intel.parse_file(tmp_code_2)
tmp_semantics.normalize_instruction_forms(tmp_kernel_1)
tmp_semantics.normalize_instruction_forms(tmp_kernel_2)
tmp_semantics.add_semantics(tmp_kernel_1)
tmp_semantics.add_semantics(tmp_kernel_2)
tmp_semantics.assign_optimal_throughput(tmp_kernel_1)
tmp_semantics.assign_optimal_throughput(tmp_kernel_2)
k1i1_pp = [round(x, 2) for x in tmp_kernel_1[0].port_pressure]
k2i1_pp = [round(x, 2) for x in tmp_kernel_2[0].port_pressure]
self.assertEqual(k1i1_pp, [0.33, 0.0, 0.33, 0.0, 0.0, 0.0, 0.0, 0.0, 0.33, 0.0, 0.0])
self.assertEqual(k2i1_pp, [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0])
def test_optimal_throughput_assignment_AArch64(self):
kernel_fixed = deepcopy(self.kernel_AArch64)
self.semantics_tx2.add_semantics(kernel_fixed)
@@ -343,7 +437,12 @@ class TestSemanticTools(unittest.TestCase):
# 3
# 5_______>9
#
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx, self.semantics_csx)
dg = KernelDG(
self.kernel_x86,
self.parser_x86_att,
self.machine_model_csx,
self.semantics_csx
)
self.assertTrue(nx.algorithms.dag.is_directed_acyclic_graph(dg.dg))
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=3))), 1)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=3)), 6)
@@ -358,12 +457,44 @@ class TestSemanticTools(unittest.TestCase):
with self.assertRaises(ValueError):
dg.get_dependent_instruction_forms()
# test dot creation
dg.export_graph(filepath="/dev/null")
dg.export_graph(filepath=os.devnull)
def test_kernelDG_x86_intel(self):
#
# 3
# \___>5__>6
# / /
# 4 /
# /
# 5.1
#
dg = KernelDG(
self.kernel_x86_intel,
self.parser_x86_intel,
self.machine_model_csx,
self.semantics_csx_intel
)
self.assertTrue(nx.algorithms.dag.is_directed_acyclic_graph(dg.dg))
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=3))), 1)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=3)), 5)
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=4))), 1)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=4)), 5)
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=5))), 1)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=5)), 6)
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=5.1))), 1)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=5.1)), 5)
self.assertEqual(list(dg.get_dependent_instruction_forms(line_number=6)), [])
self.assertEqual(list(dg.get_dependent_instruction_forms(line_number=7)), [])
self.assertEqual(list(dg.get_dependent_instruction_forms(line_number=8)), [])
with self.assertRaises(ValueError):
dg.get_dependent_instruction_forms()
# test dot creation
dg.export_graph(filepath=os.devnull)
def test_memdependency_x86(self):
dg = KernelDG(
self.kernel_x86_memdep,
self.parser_x86,
self.parser_x86_att,
self.machine_model_csx,
self.semantics_csx,
)
@@ -373,7 +504,22 @@ class TestSemanticTools(unittest.TestCase):
with self.assertRaises(ValueError):
dg.get_dependent_instruction_forms()
# test dot creation
dg.export_graph(filepath="/dev/null")
dg.export_graph(filepath=os.devnull)
def test_memdependency_x86_intel(self):
dg = KernelDG(
self.kernel_x86_intel_memdep,
self.parser_x86_intel,
self.machine_model_csx,
self.semantics_csx_intel,
)
self.assertTrue(nx.algorithms.dag.is_directed_acyclic_graph(dg.dg))
self.assertEqual(set(dg.get_dependent_instruction_forms(line_number=3)), {6, 8})
self.assertEqual(set(dg.get_dependent_instruction_forms(line_number=5)), {10, 12})
with self.assertRaises(ValueError):
dg.get_dependent_instruction_forms()
# test dot creation
dg.export_graph(filepath=os.devnull)
def test_kernelDG_AArch64(self):
dg = KernelDG(
@@ -404,7 +550,7 @@ class TestSemanticTools(unittest.TestCase):
with self.assertRaises(ValueError):
dg.get_dependent_instruction_forms()
# test dot creation
dg.export_graph(filepath="/dev/null")
dg.export_graph(filepath=os.devnull)
def test_kernelDG_SVE(self):
KernelDG(
@@ -420,11 +566,15 @@ class TestSemanticTools(unittest.TestCase):
path_to_yaml=self._find_file("hidden_load_machine_model.yml")
)
self.assertTrue(machine_model_hld.has_hidden_loads())
semantics_hld = ArchSemantics(machine_model_hld)
kernel_hld = self.parser_x86.parse_file(self.code_x86)
kernel_hld_2 = self.parser_x86.parse_file(self.code_x86)
kernel_hld_2 = self.parser_x86.parse_file(self.code_x86)[-3:]
kernel_hld_3 = self.parser_x86.parse_file(self.code_x86)[5:8]
semantics_hld = ArchSemantics(self.parser_x86_att, machine_model_hld)
kernel_hld = self.parser_x86_att.parse_file(self.code_x86)
kernel_hld_2 = self.parser_x86_att.parse_file(self.code_x86)
kernel_hld_2 = self.parser_x86_att.parse_file(self.code_x86)[-3:]
kernel_hld_3 = self.parser_x86_att.parse_file(self.code_x86)[5:8]
semantics_hld.normalize_instruction_forms(kernel_hld)
semantics_hld.normalize_instruction_forms(kernel_hld_2)
semantics_hld.normalize_instruction_forms(kernel_hld_3)
semantics_hld.add_semantics(kernel_hld)
semantics_hld.add_semantics(kernel_hld_2)
@@ -438,7 +588,12 @@ class TestSemanticTools(unittest.TestCase):
self.assertEqual(num_hidden_loads_3, 1)
def test_cyclic_dag(self):
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx, self.semantics_csx)
dg = KernelDG(
self.kernel_x86,
self.parser_x86_att,
self.machine_model_csx,
self.semantics_csx
)
dg.dg.add_edge(100, 101, latency=1.0)
dg.dg.add_edge(101, 102, latency=2.0)
dg.dg.add_edge(102, 100, latency=3.0)
@@ -503,7 +658,45 @@ class TestSemanticTools(unittest.TestCase):
def test_loop_carried_dependency_x86(self):
lcd_id = "8"
lcd_id2 = "5"
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx, self.semantics_csx)
dg = KernelDG(
self.kernel_x86,
self.parser_x86_att,
self.machine_model_csx,
self.semantics_csx
)
lc_deps = dg.get_loopcarried_dependencies()
# self.assertEqual(len(lc_deps), 2)
# ID 8
self.assertEqual(
lc_deps[lcd_id]["root"], dg.dg.nodes(data=True)[int(lcd_id)]["instruction_form"]
)
self.assertEqual(len(lc_deps[lcd_id]["dependencies"]), 1)
self.assertEqual(
lc_deps[lcd_id]["dependencies"][0][0],
dg.dg.nodes(data=True)[int(lcd_id)]["instruction_form"],
)
# w/ flag dependencies: ID 9 w/ len=2
# w/o flag dependencies: ID 5 w/ len=1
# TODO discuss
self.assertEqual(
lc_deps[lcd_id2]["root"],
dg.dg.nodes(data=True)[int(lcd_id2)]["instruction_form"],
)
self.assertEqual(len(lc_deps[lcd_id2]["dependencies"]), 1)
self.assertEqual(
lc_deps[lcd_id2]["dependencies"][0][0],
dg.dg.nodes(data=True)[int(lcd_id2)]["instruction_form"],
)
def test_loop_carried_dependency_x86_intel(self):
lcd_id = "8"
lcd_id2 = "7"
dg = KernelDG(
self.kernel_x86_intel,
self.parser_x86_intel,
self.machine_model_csx,
self.semantics_csx_intel
)
lc_deps = dg.get_loopcarried_dependencies()
# self.assertEqual(len(lc_deps), 2)
# ID 8
@@ -532,7 +725,7 @@ class TestSemanticTools(unittest.TestCase):
start_time = time.perf_counter()
KernelDG(
self.kernel_x86_long_LCD,
self.parser_x86,
self.parser_x86_att,
self.machine_model_csx,
self.semantics_x86,
timeout=10,
@@ -542,7 +735,7 @@ class TestSemanticTools(unittest.TestCase):
start_time = time.perf_counter()
KernelDG(
self.kernel_x86_long_LCD,
self.parser_x86,
self.parser_x86_att,
self.machine_model_csx,
self.semantics_x86,
timeout=2,
@@ -556,22 +749,32 @@ class TestSemanticTools(unittest.TestCase):
def test_is_read_is_written_x86(self):
# independent form HW model
dag = KernelDG(self.kernel_x86, self.parser_x86, None, None)
dag = KernelDG(self.kernel_x86, self.parser_x86_att, None, None)
reg_rcx = RegisterOperand(name="rcx")
reg_ymm1 = RegisterOperand(name="ymm1")
instr_form_r_c = self.parser_x86.parse_line("vmovsd %xmm0, (%r15,%rcx,8)")
instr_form_r_c = self.parser_x86_att.parse_line("vmovsd %xmm0, (%r15,%rcx,8)")
self.semantics_csx.normalize_instruction_form(instr_form_r_c)
self.semantics_csx.assign_src_dst(instr_form_r_c)
instr_form_non_r_c = self.parser_x86.parse_line("movl %xmm0, (%r15,%rax,8)")
instr_form_non_r_c = self.parser_x86_att.parse_line("movl %xmm0, (%r15,%rax,8)")
self.semantics_csx.normalize_instruction_form(instr_form_non_r_c)
self.semantics_csx.assign_src_dst(instr_form_non_r_c)
instr_form_w_c = self.parser_x86.parse_line("movi $0x05ACA, %rcx")
instr_form_w_c = self.parser_x86_att.parse_line("movi $0x05ACA, %rcx")
self.semantics_csx.normalize_instruction_form(instr_form_w_c)
self.semantics_csx.assign_src_dst(instr_form_w_c)
instr_form_rw_ymm_1 = self.parser_x86.parse_line("vinsertf128 $0x1, %xmm1, %ymm0, %ymm1")
instr_form_rw_ymm_1 = self.parser_x86_att.parse_line(
"vinsertf128 $0x1, %xmm1, %ymm0, %ymm1"
)
self.semantics_csx.normalize_instruction_form(instr_form_rw_ymm_1)
self.semantics_csx.assign_src_dst(instr_form_rw_ymm_1)
instr_form_rw_ymm_2 = self.parser_x86.parse_line("vinsertf128 $0x1, %xmm0, %ymm1, %ymm1")
instr_form_rw_ymm_2 = self.parser_x86_att.parse_line(
"vinsertf128 $0x1, %xmm0, %ymm1, %ymm1"
)
self.semantics_csx.normalize_instruction_form(instr_form_rw_ymm_2)
self.semantics_csx.assign_src_dst(instr_form_rw_ymm_2)
instr_form_r_ymm = self.parser_x86.parse_line("vmovapd %ymm1, %ymm0")
instr_form_r_ymm = self.parser_x86_att.parse_line("vmovapd %ymm1, %ymm0")
self.semantics_csx.normalize_instruction_form(instr_form_r_ymm)
self.semantics_csx.assign_src_dst(instr_form_r_ymm)
self.assertTrue(dag.is_read(reg_rcx, instr_form_r_c))
self.assertFalse(dag.is_read(reg_rcx, instr_form_non_r_c))
@@ -585,6 +788,47 @@ class TestSemanticTools(unittest.TestCase):
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_x86_intel(self):
# independent form HW model
dag = KernelDG(self.kernel_x86_intel, self.parser_x86_intel, None, None)
reg_rcx = RegisterOperand(name="rcx")
reg_ymm1 = RegisterOperand(name="ymm1")
instr_form_r_c = self.parser_x86_intel.parse_line("vmovsd QWORD PTR [r15+rcx*8], xmm0")
self.semantics_csx_intel.normalize_instruction_form(instr_form_r_c)
self.semantics_csx_intel.assign_src_dst(instr_form_r_c)
instr_form_non_r_c = self.parser_x86_intel.parse_line("mov QWORD PTR [r15+rax*8], xmm0")
self.semantics_csx_intel.normalize_instruction_form(instr_form_non_r_c)
self.semantics_csx_intel.assign_src_dst(instr_form_non_r_c)
instr_form_w_c = self.parser_x86_intel.parse_line("mov rcx, H05ACA")
self.semantics_csx_intel.normalize_instruction_form(instr_form_w_c)
self.semantics_csx_intel.assign_src_dst(instr_form_w_c)
instr_form_rw_ymm_1 = self.parser_x86_intel.parse_line(
"vinsertf128 ymm1, ymm0, xmm1, 1"
)
self.semantics_csx_intel.normalize_instruction_form(instr_form_rw_ymm_1)
self.semantics_csx_intel.assign_src_dst(instr_form_rw_ymm_1)
instr_form_rw_ymm_2 = self.parser_x86_intel.parse_line(
"vinsertf128 ymm1, ymm1, xmm0, 1"
)
self.semantics_csx_intel.normalize_instruction_form(instr_form_rw_ymm_2)
self.semantics_csx_intel.assign_src_dst(instr_form_rw_ymm_2)
instr_form_r_ymm = self.parser_x86_intel.parse_line("vmovapd ymm0, ymm1")
self.semantics_csx_intel.normalize_instruction_form(instr_form_r_ymm)
self.semantics_csx_intel.assign_src_dst(instr_form_r_ymm)
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 = KernelDG(self.kernel_AArch64, self.parser_AArch64, None, None)
@@ -597,20 +841,28 @@ class TestSemanticTools(unittest.TestCase):
regs_gp = [reg_w1, reg_x1]
instr_form_r_1 = self.parser_AArch64.parse_line("stp q1, q3, [x12, #192]")
self.semantics_tx2.normalize_instruction_form(instr_form_r_1)
self.semantics_tx2.assign_src_dst(instr_form_r_1)
instr_form_r_2 = self.parser_AArch64.parse_line("fadd v2.2d, v1.2d, v0.2d")
self.semantics_tx2.normalize_instruction_form(instr_form_r_2)
self.semantics_tx2.assign_src_dst(instr_form_r_2)
instr_form_w_1 = self.parser_AArch64.parse_line("ldr d1, [x1, #:got_lo12:q2c]")
self.semantics_tx2.normalize_instruction_form(instr_form_w_1)
self.semantics_tx2.assign_src_dst(instr_form_w_1)
instr_form_non_w_1 = self.parser_AArch64.parse_line("ldr x1, [x1, #:got_lo12:q2c]")
self.semantics_tx2.normalize_instruction_form(instr_form_non_w_1)
self.semantics_tx2.assign_src_dst(instr_form_non_w_1)
instr_form_rw_1 = self.parser_AArch64.parse_line("fmul v1.2d, v1.2d, v0.2d")
self.semantics_tx2.normalize_instruction_form(instr_form_rw_1)
self.semantics_tx2.assign_src_dst(instr_form_rw_1)
instr_form_rw_2 = self.parser_AArch64.parse_line("ldp q2, q4, [x1, #64]!")
self.semantics_tx2.normalize_instruction_form(instr_form_rw_2)
self.semantics_tx2.assign_src_dst(instr_form_rw_2)
instr_form_rw_3 = self.parser_AArch64.parse_line("str x4, [x1], #64")
self.semantics_tx2.normalize_instruction_form(instr_form_rw_3)
self.semantics_tx2.assign_src_dst(instr_form_rw_3)
instr_form_non_rw_1 = self.parser_AArch64.parse_line("adds x1, x11")
self.semantics_tx2.normalize_instruction_form(instr_form_non_rw_1)
self.semantics_tx2.assign_src_dst(instr_form_non_rw_1)
for reg in regs: