mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2025-12-16 09:00:05 +01:00
Add support for the Intel syntax supported by MSVC and ICC
This commit is contained in:
@@ -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
|
||||
|
||||
227
tests/test_files/gs_x86_icc.asm
Normal file
227
tests/test_files/gs_x86_icc.asm
Normal 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
|
||||
9
tests/test_files/kernel_x86_intel.asm
Normal file
9
tests/test_files/kernel_x86_intel.asm
Normal 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
|
||||
19
tests/test_files/kernel_x86_intel_memdep.asm
Normal file
19
tests/test_files/kernel_x86_intel_memdep.asm
Normal 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]
|
||||
124
tests/test_files/triad_x86_intel.asm
Normal file
124
tests/test_files/triad_x86_intel.asm
Normal 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
|
||||
139
tests/test_files/triad_x86_intel_iaca.asm
Normal file
139
tests/test_files/triad_x86_intel_iaca.asm
Normal 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
|
||||
@@ -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,
|
||||
|
||||
@@ -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)],
|
||||
)
|
||||
|
||||
365
tests/test_parser_x86intel.py
Normal file
365
tests/test_parser_x86intel.py
Normal 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)
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user