mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-05 10:40:06 +01:00
initial upload - not functional yet
This commit is contained in:
194
osaca/data/csl.yml
Normal file
194
osaca/data/csl.yml
Normal file
@@ -0,0 +1,194 @@
|
||||
osaca_version: 0.3.0
|
||||
micro_architecture: "Cascade Lake SP"
|
||||
isa: "x86"
|
||||
port_model_scheme: |
|
||||
┌------------------------------------------------------------------------┐
|
||||
| 97 entry unified scheduler |
|
||||
└------------------------------------------------------------------------┘
|
||||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
|
||||
┌-------┐ ┌-------┐ ┌-----┐ ┌-----┐ ┌-----┐ ┌-------┐ ┌--------┐ ┌-----┐
|
||||
| ALU | | ALU | | LD | | LD | | ST | | ALU | | ALU & | | AGU |
|
||||
└-------┘ └-------┘ └-----┘ └-----┘ └-----┘ └-------┘ | Shift | └-----┘
|
||||
┌-------┐ ┌-------┐ ┌-----┐ ┌-----┐ ┌-------┐ └--------┘
|
||||
| 2ND | | Fast | | AGU | | AGU | | Fast |
|
||||
| BRANCH| | LEA | └-----┘ └-----┘ | LEA |
|
||||
└-------┘ └-------┘ └-------┘
|
||||
┌-------┐ ┌-------┐ ┌-------┐
|
||||
|AVX DIV| |AVX FMA| | AVX |
|
||||
└-------┘ └-------┘ | SHUF |
|
||||
┌-------┐ ┌-------┐ └-------┘
|
||||
|AVX FMA| |AVX MUL| ┌-------┐
|
||||
└-------┘ └-------┘ |AVX-512|
|
||||
┌-------┐ ┌-------┐ | FMA |
|
||||
|AVX MUL| |AVX ADD| └-------┘
|
||||
└-------┘ └-------┘ ┌-------┐
|
||||
┌-------┐ ┌-------┐ |AVX-512|
|
||||
|AVX ADD| |AVX ALU| | ADD |
|
||||
└-------┘ └-------┘ └-------┘
|
||||
┌-------┐ ┌-------┐ ┌-------┐
|
||||
|AVX ALU| | AVX | |AVX-512|
|
||||
└-------┘ | Shift | | MUL |
|
||||
┌-------┐ └-------┘ └-------┘
|
||||
| AVX | ┌-------┐ ┌-------┐
|
||||
| Shift | | Slow | |AVX-512|
|
||||
└-------┘ | LEA | | ALU |
|
||||
┌-------┐ └-------┘ └-------┘
|
||||
| VNNI | ┌-------┐
|
||||
└-------┘ | VNNI |
|
||||
└-------┘
|
||||
ports: ["0", "0DV", "1", "2", "3", "4", "5", "6", "7"]
|
||||
instruction_forms:
|
||||
- name: addsd
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: addss
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: mulsd
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: mulss
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: rcpss
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: sqrtsd
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: sqrtss
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: vaddsd
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: vaddss
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: vdivsd
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: vdivss
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: vmulsd
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: vmulss
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- 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]
|
||||
- name: vmovapd
|
||||
operands:
|
||||
- class: "memory"
|
||||
base: "gpr"
|
||||
offset: ~
|
||||
index: "gpr"
|
||||
scale: 1
|
||||
- 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]
|
||||
- name: vmovapd
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
- class: "memory"
|
||||
base: "gpr"
|
||||
offset: ~
|
||||
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]
|
||||
117
osaca/data/isa/AArch64.yml
Normal file
117
osaca/data/isa/AArch64.yml
Normal file
@@ -0,0 +1,117 @@
|
||||
osaca_version: 0.3.0
|
||||
isa: "AArch64"
|
||||
# Contains all operand-irregular instruction forms OSACA supports for AArch64.
|
||||
# Operand-regular for a AArch64 instruction form with N operands in the shape of
|
||||
# mnemonic op1 ... opN
|
||||
# means that op1 is the only destination operand and op2 to op(N) are source operands.
|
||||
instruction_forms:
|
||||
- name: "fmla"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
source: true
|
||||
destination: true
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
source: true
|
||||
destination: false
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
source: true
|
||||
destination: false
|
||||
- name: "fmla"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
source: true
|
||||
destination: true
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
source: true
|
||||
destination: false
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
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: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
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: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
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: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
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: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
source: false
|
||||
destination: true
|
||||
57
osaca/data/isa/x86.yml
Normal file
57
osaca/data/isa/x86.yml
Normal file
@@ -0,0 +1,57 @@
|
||||
osaca_version: 0.3.0
|
||||
isa: "x86 AT&T"
|
||||
# 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
|
||||
# means that opN is the only destination operand and op1 to op(N-1) are source operands.
|
||||
instruction_forms:
|
||||
- name: addsd
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
source: true
|
||||
destination: true
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
source: true
|
||||
destination: false
|
||||
- name: addss
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
source: true
|
||||
destination: true
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
source: true
|
||||
destination: false
|
||||
- name: mulsd
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
source: true
|
||||
destination: true
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
source: true
|
||||
destination: false
|
||||
- name: mulss
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
source: true
|
||||
destination: true
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
source: true
|
||||
destination: false
|
||||
- name: vaddsd
|
||||
operands:
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
source: true
|
||||
destination: true
|
||||
- class: "register"
|
||||
name: "xmm"
|
||||
source: true
|
||||
destination: false
|
||||
252
osaca/data/vulcan.yml
Normal file
252
osaca/data/vulcan.yml
Normal file
@@ -0,0 +1,252 @@
|
||||
osaca_version: 0.3.0
|
||||
micro_architecture: "Vulcan"
|
||||
isa: "AArch64"
|
||||
port_model_scheme: |
|
||||
┌---------------------------------------------------------------┐
|
||||
| 60 entry unified scheduler |
|
||||
└---------------------------------------------------------------┘
|
||||
0 | 1 | 2 | 3 | 4 | 5 |
|
||||
▼ ▼ ▼ ▼ ▼ ▼
|
||||
┌------┐ ┌------┐ ┌------┐ ┌-------┐ ┌-------┐ ┌---------┐
|
||||
| ALU | | ALU | | ALU/ | | LD/ST | | LD/ST | | ST Data |
|
||||
└------┘ └------┘ | BR | └-------┘ └-------┘ └---------┘
|
||||
┌------┐ ┌------┐ └------┘
|
||||
| FP/ | | FP/ |
|
||||
| NEON | | NEON |
|
||||
└------┘ └------┘
|
||||
┌------┐
|
||||
| INT |
|
||||
| MUL/ |
|
||||
| DIV |
|
||||
└------┘
|
||||
┌------┐
|
||||
|CRYPTO|
|
||||
└------┘
|
||||
ports: ["0", "0DV", "1", "1DV", "2", "3", "4", "5"]
|
||||
instruction_forms:
|
||||
- name: "add"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- 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]
|
||||
- name: "add"
|
||||
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_occupation: [0.33333333, 0.0, 0.33333333, 0.0, 0.33333333, 0.0, 0.0, 0.0]
|
||||
- name: "fadd"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
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]
|
||||
- name: "fadd"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
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]
|
||||
- name: "fdiv"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
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]
|
||||
- name: "fdiv"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
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]
|
||||
- name: "fmla"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
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]
|
||||
- name: "fmla"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
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]
|
||||
- name: "fmul"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
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]
|
||||
- name: "fmul"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
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]
|
||||
- name: "fsub"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
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]
|
||||
- name: "fsub"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
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]
|
||||
- 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: 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]
|
||||
- name: "ldp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
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]
|
||||
- name: "stp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
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]
|
||||
- name: "stp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
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]
|
||||
208
osaca/semantics/hw_model.py
Executable file
208
osaca/semantics/hw_model.py
Executable file
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
from osaca.parser.parser_x86att import ParserX86ATT
|
||||
|
||||
from ruamel import yaml
|
||||
|
||||
|
||||
class MachineModel(object):
|
||||
def __init__(self, arch=None, path_to_yaml=None):
|
||||
if not arch and not path_to_yaml:
|
||||
raise ValueError('Either arch or path_to_yaml required.')
|
||||
if arch and path_to_yaml:
|
||||
raise ValueError('Only one of arch and path_to_yaml is allowed.')
|
||||
self._path = path_to_yaml
|
||||
self._arch = arch
|
||||
if arch:
|
||||
self._arch = arch.lower()
|
||||
try:
|
||||
with open(self._find_file(self._arch), 'r') as f:
|
||||
self._data = yaml.load(f, Loader=yaml.Loader)
|
||||
except AssertionError:
|
||||
raise ValueError(
|
||||
'Cannot find specified architecture. Make sure the machine file exists.'
|
||||
)
|
||||
elif path_to_yaml:
|
||||
try:
|
||||
with open(self._path, 'r') as f:
|
||||
self._data = yaml.load(f, Loader=yaml.Loader)
|
||||
except AssertionError:
|
||||
raise ValueError(
|
||||
'Cannot find specified path to YAML file. Make sure the machine file exists.'
|
||||
)
|
||||
|
||||
def _find_file(self, name):
|
||||
data_dir = os.path.expanduser('~/.osaca/data')
|
||||
name = os.path.join(data_dir, name)
|
||||
assert os.path.exists(name)
|
||||
return name
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""Return configuration entry."""
|
||||
return self._data[key]
|
||||
|
||||
def __contains__(self, key):
|
||||
"""Return true if configuration key is present."""
|
||||
return key in self._data
|
||||
|
||||
######################################################
|
||||
|
||||
def get_instruction(self, name, operands):
|
||||
try:
|
||||
return next(
|
||||
instruction_form
|
||||
for instruction_form in self._data['instruction_forms']
|
||||
if instruction_form['name'] == name
|
||||
and self._match_operands(instruction_form['operands'], operands)
|
||||
)
|
||||
except StopIteration:
|
||||
return None
|
||||
|
||||
def get_ISA(self):
|
||||
return self._data['isa']
|
||||
|
||||
######################################################
|
||||
|
||||
def _match_operands(self, i_operands, operands):
|
||||
operands_ok = True
|
||||
if len(operands) != len(i_operands):
|
||||
return False
|
||||
for idx, operand in enumerate(operands):
|
||||
i_operand = i_operands[idx]
|
||||
operands_ok = operands_ok and self._check_operands(i_operand, operand)
|
||||
if operands_ok:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def _check_operands(self, i_operands, operands):
|
||||
if self._data['isa'] == 'AArch64':
|
||||
return self._check_AArch64_operands(i_operands, operands)
|
||||
if self._data['isa'] == 'x86':
|
||||
return self._check_x86_operands(i_operands, operands)
|
||||
|
||||
def _check_AArch64_operands(self, i_operand, operand):
|
||||
# register
|
||||
if 'register' in operand:
|
||||
if i_operand['class'] != 'register':
|
||||
return False
|
||||
return self._is_AArch64_reg_type(i_operand, operand['register'])
|
||||
# memory
|
||||
if 'memory' in operand:
|
||||
if i_operand['class'] != 'memory':
|
||||
return False
|
||||
return self._is_AArch64_mem_type(i_operand['memory'], operand['memory'])
|
||||
# immediate
|
||||
if 'value' in operand:
|
||||
return i_operand['class'] == 'immediate' and i_operand['imd'] == 'int'
|
||||
if 'float' in operand:
|
||||
return i_operand['class'] == 'immediate' and i_operand['imd'] == 'float'
|
||||
if 'double' in operand:
|
||||
return i_operand['class'] == 'immediate' and i_operand['imd'] == 'double'
|
||||
# prefetch option
|
||||
if 'prfop' in operand:
|
||||
return i_operand['class'] == 'prfop'
|
||||
# no match
|
||||
return False
|
||||
|
||||
def _check_x86_operands(self, i_operand, operand):
|
||||
# register
|
||||
if 'register' in operand:
|
||||
if i_operand['class'] != 'register':
|
||||
return False
|
||||
return self._is_x86_reg_type(i_operand['name'], operand['register'])
|
||||
# memory
|
||||
if 'memory' in operand:
|
||||
if i_operand['class'] != 'memory':
|
||||
return False
|
||||
return self._is_x86_mem_type(i_operand['memory'], operand['memory'])
|
||||
# immediate
|
||||
if 'value' in operand:
|
||||
return i_operand['class'] == 'immediate' and i_operand['imd'] == 'int'
|
||||
|
||||
def _is_AArch64_reg_type(self, i_reg, reg):
|
||||
if reg['prefix'] != i_reg['prefix']:
|
||||
return False
|
||||
if 'shape' in reg:
|
||||
if 'shape' in i_reg and reg['shape'] == i_reg['shape']:
|
||||
return True
|
||||
return False
|
||||
return True
|
||||
|
||||
def _is_x86_reg_type(self, i_reg_name, reg):
|
||||
# differentiate between vector registers (xmm, ymm, zmm) and others (gpr)
|
||||
parser_x86 = ParserX86ATT()
|
||||
if parser_x86.is_vector_register(reg):
|
||||
if reg['name'][0:3] == i_reg_name:
|
||||
return True
|
||||
else:
|
||||
if i_reg_name == 'gpr':
|
||||
return True
|
||||
return False
|
||||
|
||||
def _is_AArch64_mem_type(self, i_mem, mem):
|
||||
if (
|
||||
# check base
|
||||
mem['base']['prefix'] == i_mem['base']
|
||||
# check offset
|
||||
and (
|
||||
mem['offset'] == i_mem['offset']
|
||||
or (
|
||||
mem['offset'] is not None
|
||||
and 'identifier' in mem['offset']
|
||||
and i_mem['offset'] == 'identifier'
|
||||
)
|
||||
or (
|
||||
mem['offset'] is not None
|
||||
and 'value' in mem['offset']
|
||||
and i_mem['offset'] == 'imd'
|
||||
)
|
||||
)
|
||||
# check index
|
||||
and (
|
||||
mem['index'] == i_mem['index']
|
||||
or (
|
||||
mem['index'] is not None
|
||||
and 'prefix' in mem['index']
|
||||
and mem['index']['prefix'] == i_mem['index']
|
||||
)
|
||||
)
|
||||
and mem['scale'] == i_mem['scale']
|
||||
and (('pre_indexed' in mem) == (i_mem['pre-indexed']))
|
||||
and (('post_indexed' in mem) == (i_mem['post-indexed']))
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _is_x86_mem_type(self, i_mem, mem):
|
||||
if (
|
||||
# check base
|
||||
self._is_x86_reg_type(i_mem['base'], mem['base'])
|
||||
# check offset
|
||||
and (
|
||||
mem['offset'] == i_mem['offset']
|
||||
or (
|
||||
mem['offset'] is not None
|
||||
and 'identifier' in mem['offset']
|
||||
and i_mem['offset'] == 'identifier'
|
||||
)
|
||||
or (
|
||||
mem['offset'] is not None
|
||||
and 'value' in mem['offset']
|
||||
and i_mem['offset'] == 'imd'
|
||||
)
|
||||
)
|
||||
# check index
|
||||
and (
|
||||
mem['index'] == i_mem['index']
|
||||
or (
|
||||
mem['index'] is not None
|
||||
and 'name' in mem['index']
|
||||
and self._is_x86_reg_type(i_mem['index'], mem['index'])
|
||||
)
|
||||
)
|
||||
and mem['scale'] == i_mem['scale']
|
||||
):
|
||||
return True
|
||||
return False
|
||||
40
osaca/semantics/semanticsAppender.py
Executable file
40
osaca/semantics/semanticsAppender.py
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
|
||||
from .hw_model import MachineModel
|
||||
|
||||
|
||||
class SemanticsAppender(object):
|
||||
def __init__(self, machine_model: MachineModel):
|
||||
self.machine_model = machine_model
|
||||
self._isa = machine_model.get_ISA()
|
||||
self._isa_model = MachineModel(path_to_yaml=self._find_file(self._isa))
|
||||
|
||||
def _find_file(self, isa):
|
||||
data_dir = os.path.expanduser('~/.osaca/data/isa')
|
||||
name = os.path.join(data_dir, isa + '.yml')
|
||||
assert os.path.exists(name)
|
||||
return name
|
||||
|
||||
# get parser result and assign operands to
|
||||
# - source
|
||||
# - destination
|
||||
# - source/destination
|
||||
|
||||
# for this, have a default implementation and get exceptions from generic x86/AArch64 ISA file
|
||||
def assign_src_dst(self, instruction_form):
|
||||
# check if instruction form is in ISA yaml, otherwise apply standard operand assignment
|
||||
# (one dest, others source)
|
||||
isa_data = self._isa_model.get_instruction(
|
||||
instruction_form['name'], instruction_form['operands']
|
||||
)
|
||||
if isa_data is None:
|
||||
# no irregular operand structure, apply default
|
||||
# TODO
|
||||
pass
|
||||
else:
|
||||
# load src/dst structure from isa_data
|
||||
# TODO
|
||||
pass
|
||||
raise NotImplementedError
|
||||
Reference in New Issue
Block a user