added DiGraph creation and more tests

This commit is contained in:
JanLJL
2019-07-10 18:25:32 +02:00
parent 311535476a
commit a866500610
12 changed files with 511 additions and 84 deletions

View File

@@ -46,8 +46,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 0.5
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: addss
operands:
- class: "register"
@@ -55,8 +55,41 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 0.5
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: addl
operands:
- class: "register"
name: "xmm"
- class: "immediate"
name: "int"
throughput: 0.25
latency: ~ # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.25, 0.0, 0.25, 0.0, 0.0, 0.0, 0.25, 0.25, 0.0]
- name: addq
operands:
- class: "register"
name: "xmm"
- class: "immediate"
name: "int"
throughput: 0.25
latency: ~ # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.25, 0.0, 0.25, 0.0, 0.0, 0.0, 0.25, 0.25, 0.0]
- name: cmpl
operands:
- class: "register"
name: "gpr"
- class: "register"
name: "gpr"
throughput: 0.25
latency: ~ # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.25, 0.0, 0.25, 0.0, 0.0, 0.0, 0.25, 0.25, 0.0]
- name: ja
operands:
- class: 'identifier'
throughput: 0.0
latency: 0.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: mulsd
operands:
- class: "register"
@@ -64,8 +97,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 0.5
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: mulss
operands:
- class: "register"
@@ -73,8 +106,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 0.5
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: rcpss
operands:
- class: "register"
@@ -82,8 +115,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 1.0
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: sqrtsd
operands:
- class: "register"
@@ -91,8 +124,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 6.0
latency: 22.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [1.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 22.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [1.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: sqrtss
operands:
- class: "register"
@@ -100,8 +133,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 3.0
latency: 16.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [1.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 16.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [1.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: vaddsd
operands:
- class: "register"
@@ -111,8 +144,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 0.5
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: vaddss
operands:
- class: "register"
@@ -122,8 +155,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 0.5
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: vdivsd
operands:
- class: "register"
@@ -133,8 +166,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 4.0
latency: 14.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [1.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 14.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [1.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: vdivss
operands:
- class: "register"
@@ -144,8 +177,22 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 3.0
latency: 11.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [1.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 11.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [1.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: vfmadd132pd
operands:
- class: "memory"
base: "gpr"
offset: ~
index: "gpr"
scale: 1
- class: "register"
name: "ymm"
- class: "register"
name: "ymm"
throughput: 0.5
latency: ~ # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.5, 0.0, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0]
- name: vmulsd
operands:
- class: "register"
@@ -155,8 +202,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 0.5
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: vmulss
operands:
- class: "register"
@@ -166,8 +213,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 0.5
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 4.0 # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: vmovapd
operands:
- class: "memory"
@@ -178,8 +225,8 @@ instruction_forms:
- class: "register"
name: "xmm"
throughput: 0.5
latency: ~ # 0 0DV 1 2 3 4 5 6 7
port_occupation: [0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0]
latency: ~ # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0]
- name: vmovapd
operands:
- class: "register"
@@ -190,5 +237,31 @@ instruction_forms:
index: "gpr"
scale: 1
throughput: 1.0
latency: ~ # 0 0DV 1 2 3 4 5 6 7
port_occupation: [0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 0.0, 0.0, 0.0]
latency: ~ # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 0.0, 0.0, 0.0]
- name: vmovapd
operands:
- class: "memory"
base: "gpr"
offset: ~
index: "gpr"
scale: 1
- class: "register"
name: "ymm"
throughput: 0.5
latency: ~ # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0]
- name: vmovapd
operands:
- class: "register"
name: "ymm"
- class: "memory"
base: "gpr"
offset: ~
index: "gpr"
scale: 1
throughput: 1.0
latency: ~ # 0 0DV 1 2 3 4 5 6 7
port_pressure: [0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 0.0, 0.0, 0.0]

View File

@@ -57,6 +57,25 @@ instruction_forms:
pre-indexed: false
post-indexed: false
source: true
destination: false
- name: "ldp"
operands:
- class: "register"
prefix: "d"
source: false
destination: true
- class: "register"
prefix: "d"
source: false
destination: true
- class: "memory"
base: "x"
offset: ~
index: ~
scale: 1
pre-indexed: false
post-indexed: true
source: true
destination: false
- name: "ldp"
operands:
@@ -77,6 +96,44 @@ instruction_forms:
post-indexed: false
source: true
destination: false
- name: "ldp"
operands:
- class: "register"
prefix: "q"
source: false
destination: true
- class: "register"
prefix: "q"
source: false
destination: true
- class: "memory"
base: "x"
offset: ~
index: ~
scale: 1
pre-indexed: false
post-indexed: true
source: true
destination: false
- name: "stp"
operands:
- class: "register"
prefix: "d"
source: true
destination: false
- class: "register"
prefix: "d"
source: true
destination: false
- class: "memory"
base: "x"
offset: ~
index: ~
scale: 1
pre-indexed: false
post-indexed: false
source: false
destination: true
- name: "stp"
operands:
- class: "register"
@@ -96,6 +153,25 @@ instruction_forms:
post-indexed: false
source: false
destination: true
- name: "stp"
operands:
- class: "register"
prefix: "q"
source: true
destination: false
- class: "register"
prefix: "q"
source: true
destination: false
- class: "memory"
base: "x"
offset: ~
index: ~
scale: 1
pre-indexed: false
post-indexed: false
source: false
destination: true
- name: "stp"
operands:
- class: "register"

View File

@@ -1,5 +1,5 @@
osaca_version: 0.3.0
isa: "x86 AT&T"
isa: "x86"
# Contains all operand-irregular instruction forms OSACA supports for x86.
# Operand-regular for a x86 AT&T instruction form with N operands in the shape of
# mnemonic op1 ... opN
@@ -25,6 +25,21 @@ instruction_forms:
name: "xmm"
source: true
destination: false
- name: cmpl
operands:
- class: "register"
name: "gpr"
source: true
destination: false
- class: "register"
name: "gpr"
source: true
destination: false
- name: ja
operands:
- class: "identifier"
source: true
destination: false
- name: mulsd
operands:
- class: "register"
@@ -55,3 +70,21 @@ instruction_forms:
name: "xmm"
source: true
destination: false
- name: vfmadd132pd
operands:
- class: "memory"
base: "gpr"
offset: ~
index: "gpr"
scale: 1
source: true
destination: false
- class: "register"
name: "ymm"
source: true
destination: false
- class: "register"
name: "ymm"
source: true
destination: true

View File

@@ -33,8 +33,8 @@ instruction_forms:
- class: "register"
prefix: "x"
throughput: 0.33333333
latency: 1.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.33333333, 0.0, 0.33333333, 0.0, 0.33333333, 0.0, 0.0, 0.0]
latency: 1.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.33333333, 0.0, 0.33333333, 0.0, 0.33333333, 0.0, 0.0, 0.0]
- name: "add"
operands:
- class: "register"
@@ -44,8 +44,20 @@ instruction_forms:
- class: "immediate"
imd: "int"
throughput: 0.33333333
latency: 1.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.33333333, 0.0, 0.33333333, 0.0, 0.33333333, 0.0, 0.0, 0.0]
latency: 1.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.33333333, 0.0, 0.33333333, 0.0, 0.33333333, 0.0, 0.0, 0.0]
- name: "adds"
operands:
- class: "register"
prefix: "x"
- class: "register"
prefix: "x"
- class: "immediate"
imd: "int"
throughput: 0.33333333
latency: 1.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.33333333, 0.0, 0.33333333, 0.0, 0.33333333, 0.0, 0.0, 0.0]
- name: "fadd"
operands:
- class: "register"
@@ -58,8 +70,8 @@ instruction_forms:
prefix: "v"
shape: "s"
throughput: 0.5
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: "fadd"
operands:
- class: "register"
@@ -72,8 +84,8 @@ instruction_forms:
prefix: "v"
shape: "d"
throughput: 0.5
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: "fdiv"
operands:
- class: "register"
@@ -86,8 +98,8 @@ instruction_forms:
prefix: "v"
shape: "s"
throughput: 8.5
latency: 16.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [1.0, 8.5, 1.0, 8.5, 0.0, 0.0, 0.0, 0.0]
latency: 16.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [1.0, 8.5, 1.0, 8.5, 0.0, 0.0, 0.0, 0.0]
- name: "fdiv"
operands:
- class: "register"
@@ -100,8 +112,8 @@ instruction_forms:
prefix: "v"
shape: "d"
throughput: 12.0
latency: 23.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [1.0, 12.5, 1.0, 12.0, 0.0, 0.0, 0.0, 0.0]
latency: 23.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [1.0, 12.5, 1.0, 12.0, 0.0, 0.0, 0.0, 0.0]
- name: "fmla"
operands:
- class: "register"
@@ -114,8 +126,8 @@ instruction_forms:
prefix: "v"
shape: "s"
throughput: 0.5
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: "fmla"
operands:
- class: "register"
@@ -128,8 +140,8 @@ instruction_forms:
prefix: "v"
shape: "d"
throughput: 0.5
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: "fmul"
operands:
- class: "register"
@@ -142,8 +154,8 @@ instruction_forms:
prefix: "v"
shape: "s"
throughput: 0.5
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: "fmul"
operands:
- class: "register"
@@ -156,8 +168,8 @@ instruction_forms:
prefix: "v"
shape: "d"
throughput: 0.5
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: "fsub"
operands:
- class: "register"
@@ -170,8 +182,8 @@ instruction_forms:
prefix: "v"
shape: "s"
throughput: 0.5
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: "fsub"
operands:
- class: "register"
@@ -184,8 +196,8 @@ instruction_forms:
prefix: "v"
shape: "d"
throughput: 0.5
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
- name: "ldp"
operands:
- class: "register"
@@ -200,8 +212,24 @@ instruction_forms:
pre-indexed: false
post-indexed: false
throughput: 1.0
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
- name: "ldp"
operands:
- class: "register"
prefix: "d"
- class: "register"
prefix: "d"
- class: "memory"
base: "x"
offset: "imd"
index: ~
scale: 1
pre-indexed: false
post-indexed: true
throughput: 1.0
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
- name: "ldp"
operands:
- class: "register"
@@ -216,8 +244,40 @@ instruction_forms:
pre-indexed: false
post-indexed: false
throughput: 1.0
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
- name: "ldp"
operands:
- class: "register"
prefix: "q"
- class: "register"
prefix: "q"
- class: "memory"
base: "x"
offset: ~
index: ~
scale: 1
pre-indexed: false
post-indexed: true
throughput: 1.0
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
- name: "stp"
operands:
- class: "register"
prefix: "d"
- class: "register"
prefix: "d"
- class: "memory"
base: "x"
offset: ~
index: ~
scale: 1
pre-indexed: false
post-indexed: false
throughput: 2.0
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0]
- name: "stp"
operands:
- class: "register"
@@ -232,8 +292,24 @@ instruction_forms:
pre-indexed: false
post-indexed: false
throughput: 2.0
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0]
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0]
- name: "stp"
operands:
- class: "register"
prefix: "q"
- class: "register"
prefix: "q"
- class: "memory"
base: "x"
offset: ~
index: ~
scale: 1
pre-indexed: false
post-indexed: false
throughput: 2.0
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0]
- name: "stp"
operands:
- class: "register"
@@ -248,5 +324,5 @@ instruction_forms:
pre-indexed: false
post-indexed: false
throughput: 2.0
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_occupation: [0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0]
latency: ~ # 0 0DV 1 1DV 2 3 4 5
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0]

View File

@@ -182,6 +182,7 @@ class ParserAArch64v81(BaseParser):
self.DIRECTIVE_ID: None,
self.COMMENT_ID: None,
self.LABEL_ID: None,
'line': line.strip(),
'line_number': line_number,
}
)

View File

@@ -112,6 +112,7 @@ class ParserX86ATT(BaseParser):
self.DIRECTIVE_ID: None,
self.COMMENT_ID: None,
self.LABEL_ID: None,
'line': line.strip(),
'line_number': line_number,
}
)

View File

@@ -1,10 +1,11 @@
#!/usr/bin/env python3
import os
from osaca.parser import ParserX86ATT
from ruamel import yaml
from osaca.parser import ParserX86ATT
class MachineModel(object):
def __init__(self, arch=None, path_to_yaml=None):
@@ -58,6 +59,9 @@ class MachineModel(object):
)
except StopIteration:
return None
except TypeError:
print('\nname: {}\noperands: {}'.format(name, operands))
raise TypeError
def get_ISA(self):
return self._data['isa']
@@ -100,6 +104,8 @@ class MachineModel(object):
return i_operand['class'] == 'immediate' and i_operand['imd'] == 'float'
if 'double' in operand:
return i_operand['class'] == 'immediate' and i_operand['imd'] == 'double'
if 'identifier' in operand:
return i_operand['class'] == 'identifier'
# prefetch option
if 'prfop' in operand:
return i_operand['class'] == 'prfop'
@@ -120,6 +126,9 @@ class MachineModel(object):
# immediate
if 'value' in operand:
return i_operand['class'] == 'immediate' and i_operand['imd'] == 'int'
# identifier (e.g., labels)
if 'identifier' in operand:
return i_operand['class'] == 'identifier'
def _is_AArch64_reg_type(self, i_reg, reg):
if reg['prefix'] != i_reg['prefix']:
@@ -190,7 +199,10 @@ class MachineModel(object):
or (
mem['offset'] is not None
and 'value' in mem['offset']
and i_mem['offset'] == 'imd'
and (
i_mem['offset'] == 'imd'
or (i_mem['offset'] is None and mem['offset']['value'] == '0')
)
)
)
# check index

View File

@@ -2,14 +2,15 @@
import networkx as nx
from .hw_model import MachineModel
class KernelDG(nx.DiGraph):
def __init__(self, parsed_kernel, parser, hw_model):
def __init__(self, parsed_kernel, parser, hw_model: MachineModel):
self.kernel = parsed_kernel
self.parser = parser
self.model = hw_model
# self.dag = self.create_DG()
self.dg = self.create_DG()
def check_for_loop(self, kernel):
raise NotImplementedError
@@ -17,26 +18,32 @@ class KernelDG(nx.DiGraph):
def create_DG(self):
# 1. go through kernel instruction forms (as vertices)
# 2. find edges (to dependend further instruction)
# 3. get LT/TP value and set as edge weight
dag = nx.DiGraph()
for i, instruction in enumerate(self.kernel):
throughput = self.model.get_throughput(instruction)
latency = self.model.get_latency(instruction)
for dep in self.find_depending(instruction, self.kernel[i + 1:]):
dag.add_edge(
instruction.line_number,
dep.line_number,
latency=latency,
thorughput=throughput,
# 3. get LT value and set as edge weight
# 4. add instr forms as node attribute
dg = nx.DiGraph()
for i, instruction_form in enumerate(self.kernel):
for dep in self.find_depending(instruction_form, self.kernel[i + 1:]):
dg.add_edge(
instruction_form['line_number'],
dep['line_number'],
latency=instruction_form['latency'],
)
dg.nodes[instruction_form['line_number']]['instruction_form'] = instruction_form
dg.nodes[dep['line_number']]['instruction_form'] = dep
return dg
def find_depending(self, instruction_form, kernel):
for dst in instruction_form.operands.destination:
if instruction_form.operands is None:
return
for dst in instruction_form.operands.destination + instruction_form.operands.src_dst:
if 'register' in dst:
# Check for read of register until overwrite
for instr_form in kernel:
if self.is_read(dst.register, instr_form):
yield instr_form
if self.is_written(dst.register, instr_form):
# operand in src_dst list
break
elif self.is_written(dst.register, instr_form):
break
elif 'memory' in dst:
@@ -46,12 +53,26 @@ class KernelDG(nx.DiGraph):
for instr_form in kernel:
if self.is_read(dst.memory.base, instr_form):
yield instr_form
if self.is_written(dst.memory.base, instr_form):
# operand in src_dst list
break
elif self.is_written(dst.memory.base, instr_form):
break
def get_dependent_instruction_forms(self, instr_form=None, line_number=None):
"""
Returns iterator
"""
if not instr_form and not line_number:
raise ValueError('Either instruction form or line_number required.')
line_number = line_number if line_number else instr_form['line_number']
if self.dg.has_node(line_number):
return self.dg.successors(line_number)
return iter([])
def is_read(self, register, instruction_form):
is_read = False
for src in instruction_form.operands.source:
for src in instruction_form.operands.source + instruction_form.operands.src_dst:
if 'register' in src:
is_read = self.parser.is_reg_dependend_of(register, src.register) or is_read
if 'memory' in src:
@@ -62,7 +83,7 @@ class KernelDG(nx.DiGraph):
self.parser.is_reg_dependend_of(register, src.memory.index) or is_read
)
# Check also if read in destination memory address
for dst in instruction_form.operands.destination:
for dst in instruction_form.operands.destination + instruction_form.operands.src_dst:
if 'memory' in dst:
if dst.memory.base is not None:
is_read = self.parser.is_reg_dependend_of(register, dst.memory.base) or is_read
@@ -74,7 +95,7 @@ class KernelDG(nx.DiGraph):
def is_written(self, register, instruction_form):
is_written = False
for dst in instruction_form.operands.destination:
for dst in instruction_form.operands.destination + instruction_form.operands.src_dst:
if 'register' in dst:
is_written = self.parser.is_reg_dependend_of(register, dst.register) or is_written
if 'memory' in dst:
@@ -83,7 +104,7 @@ class KernelDG(nx.DiGraph):
self.parser.is_reg_dependend_of(register, dst.memory.base) or is_written
)
# Check also for possible pre- or post-indexing in memory addresses
for src in instruction_form.operands.source:
for src in instruction_form.operands.source + instruction_form.operands.src_dst:
if 'memory' in src:
if 'pre_indexed' in src.memory or 'post_indexed' in src.memory:
is_written = (

View File

@@ -1,12 +1,23 @@
#!/usr/bin/env python3
import os
import warnings
from osaca.parser import AttrDict
from .hw_model import MachineModel
class SemanticsAppender(object):
class INSTR_FLAGS:
"""
Flags used for unknown or special instructions
"""
TP_UNKWN = 'tp_unkown'
LT_UNKWN = 'lt_unkown'
NOT_BOUND = 'not_bound'
HIDDEN_LD = 'hidden_load'
def __init__(self, machine_model: MachineModel, path_to_yaml=None):
self.machine_model = machine_model
self._isa = machine_model.get_ISA()
@@ -22,6 +33,54 @@ class SemanticsAppender(object):
assert os.path.exists(name)
return name
# get parser result and assign throughput and latency value to instruction form
# mark instruction form with semantic flags
def assign_tp_lt(self, instruction_form):
flags = []
port_number = len(self.machine_model['ports'])
instruction_data = self.machine_model.get_instruction(
instruction_form['instruction'], instruction_form['operands']
)
if instruction_data:
# instruction form in DB
throughput = instruction_data['throughput']
port_pressure = instruction_data['port_pressure']
try:
assert isinstance(port_pressure, list)
assert len(port_pressure) == port_number
instruction_form['port_pressure'] = port_pressure
except AssertionError:
warnings.warn(
'Port pressure could not be imported correctly from database. '
+ 'Please check entry for:\n {}'.format(instruction_form)
)
instruction_form['port_pressure'] = [0.0 for i in range(port_number)]
flags.append(self.INSTR_FLAGS.TP_UNKWN)
if throughput is None:
# assume 0 cy and mark as unknown
throughput = 0.0
flags.append(self.INSTR_FLAGS.TP_UNKWN)
latency = instruction_data['latency']
if latency is None:
# assume 0 cy and mark as unknown
latency = 0.0
flags.append(self.INSTR_FLAGS.LT_UNKWN)
else:
# instruction could not be found in DB
# --> mark as unknown and assume 0 cy for latency/throughput
throughput = 0.0
latency = 0.0
instruction_form['port_pressure'] = [0.0 for i in range(port_number)]
flags += [self.INSTR_FLAGS.TP_UNKWN, self.INSTR_FLAGS.LT_UNKWN]
# flatten flag list
flags = list(set(flags))
if 'flags' not in instruction_form:
instruction_form['flags'] = flags
else:
instruction_form['flags'] += flags
instruction_form['throughput'] = throughput
instruction_form['latency'] = latency
# get parser result and assign operands to
# - source
# - destination

View File

@@ -146,6 +146,7 @@ class TestParserAArch64v81(unittest.TestCase):
'directive': None,
'comment': '-- Begin main',
'label': None,
'line': '// -- Begin main',
'line_number': 1,
}
@@ -155,6 +156,7 @@ class TestParserAArch64v81(unittest.TestCase):
'directive': None,
'comment': '=>This Inner Loop Header: Depth=1',
'label': '.LBB0_1',
'line': '.LBB0_1: // =>This Inner Loop Header: Depth=1',
'line_number': 2,
}
instruction_form_3 = {
@@ -163,6 +165,7 @@ class TestParserAArch64v81(unittest.TestCase):
'directive': {'name': 'cfi_def_cfa', 'parameters': ['w29', '-16']},
'comment': None,
'label': None,
'line': '.cfi_def_cfa w29, -16',
'line_number': 3,
}
instruction_form_4 = {
@@ -186,6 +189,7 @@ class TestParserAArch64v81(unittest.TestCase):
'directive': None,
'comment': '= <<2',
'label': None,
'line': 'ldr s0, [x11, w10, sxtw #2]\t\t// = <<2',
'line_number': 4,
}
instruction_form_5 = {
@@ -204,6 +208,7 @@ class TestParserAArch64v81(unittest.TestCase):
'directive': None,
'comment': 'HPL',
'label': None,
'line': 'prfm pldl1keep, [x26, #2048] //HPL',
'line_number': 5,
}
instruction_form_6 = {
@@ -224,6 +229,7 @@ class TestParserAArch64v81(unittest.TestCase):
'directive': None,
'comment': None,
'label': None,
'line': 'stp x29, x30, [sp, #-16]!',
'line_number': 6,
}
instruction_form_7 = {
@@ -244,6 +250,7 @@ class TestParserAArch64v81(unittest.TestCase):
'directive': None,
'comment': None,
'label': None,
'line': 'ldp q2, q3, [x11], #64',
'line_number': 7,
}
parsed_1 = self.parser.parse_line(line_comment, 1)

View File

@@ -139,6 +139,7 @@ class TestParserX86ATT(unittest.TestCase):
'directive': None,
'comment': '-- Begin main',
'label': None,
'line': '# -- Begin main',
'line_number': 1,
}
instruction_form_2 = {
@@ -147,6 +148,7 @@ class TestParserX86ATT(unittest.TestCase):
'directive': None,
'comment': 'Preds ..B1.6',
'label': '..B1.7',
'line': '..B1.7: # Preds ..B1.6',
'line_number': 2,
}
instruction_form_3 = {
@@ -155,6 +157,7 @@ class TestParserX86ATT(unittest.TestCase):
'directive': {'name': 'quad', 'parameters': ['.2.3_2__kmpc_loc_pack.2']},
'comment': 'qed',
'label': None,
'line': '.quad .2.3_2__kmpc_loc_pack.2 #qed',
'line_number': 3,
}
instruction_form_4 = {
@@ -175,6 +178,7 @@ class TestParserX86ATT(unittest.TestCase):
'directive': None,
'comment': '12.9',
'label': None,
'line': 'lea 2(%rax,%rax), %ecx #12.9',
'line_number': 4,
}

View File

@@ -3,6 +3,7 @@
Unit tests for Semantic Analysis
"""
import networkx as nx
import os
import unittest
@@ -44,8 +45,10 @@ class TestSemanticTools(unittest.TestCase):
)
for i in range(len(self.kernel_x86)):
self.semantics_csl.assign_src_dst(self.kernel_x86[i])
self.semantics_csl.assign_tp_lt(self.kernel_x86[i])
for i in range(len(self.kernel_AArch64)):
self.semantics_tx2.assign_src_dst(self.kernel_AArch64[i])
self.semantics_tx2.assign_tp_lt(self.kernel_AArch64[i])
###########
# Tests
@@ -67,6 +70,67 @@ class TestSemanticTools(unittest.TestCase):
self.assertTrue('destination' in instruction_form['operands'])
self.assertTrue('src_dst' in instruction_form['operands'])
def test_tp_lt_assignment_x86(self):
port_num = len(self.machine_model_csl['ports'])
for instruction_form in self.kernel_x86:
with self.subTest(instruction_form=instruction_form):
self.assertTrue('throughput' in instruction_form)
self.assertTrue('latency' in instruction_form)
self.assertIsInstance(instruction_form['port_pressure'], list)
self.assertEqual(len(instruction_form['port_pressure']), port_num)
def test_tp_lt_assignment_AArch64(self):
port_num = len(self.machine_model_tx2['ports'])
for instruction_form in self.kernel_AArch64:
with self.subTest(instruction_form=instruction_form):
self.assertTrue('throughput' in instruction_form)
self.assertTrue('latency' in instruction_form)
self.assertIsInstance(instruction_form['port_pressure'], list)
self.assertEqual(len(instruction_form['port_pressure']), port_num)
def test_kernelDG_x86(self):
#
# 3
# \___>5__>6
# /
# 2
# 4_______>8
#
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csl)
self.assertTrue(nx.algorithms.dag.is_directed_acyclic_graph(dg.dg))
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=2))), 1)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=2)), 5)
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)), 8)
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=6))), 0)
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=7))), 0)
def test_kernelDG_AArch64(self):
dg = KernelDG(self.kernel_AArch64, self.parser_AArch64, self.machine_model_tx2)
self.assertTrue(nx.algorithms.dag.is_directed_acyclic_graph(dg.dg))
self.assertEqual(list(dg.get_dependent_instruction_forms(line_number=2)), [6, 7])
self.assertEqual(list(dg.get_dependent_instruction_forms(line_number=3)), [8, 9])
self.assertEqual(list(dg.get_dependent_instruction_forms(line_number=4)), [6, 7])
self.assertEqual(list(dg.get_dependent_instruction_forms(line_number=5)), [8, 9])
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=6)), 12)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=7)), 13)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=8)), 15)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=9)), 16)
self.assertEqual(list(dg.get_dependent_instruction_forms(line_number=10)), [12, 13])
self.assertEqual(list(dg.get_dependent_instruction_forms(line_number=11)), [15, 16])
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=12)), 14)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=13)), 14)
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=14))), 0)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=15)), 17)
self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=16)), 17)
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=17))), 0)
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=18))), 0)
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=19))), 0)
def test_is_read_is_written_x86(self):
# independent form HW model
dag = KernelDG(self.kernel_x86, self.parser_x86, None)