mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2025-12-16 17:10:06 +01:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
457ccdcf77 | ||
|
|
ff61c65d58 | ||
|
|
615c809fe3 | ||
|
|
bce837dec9 | ||
|
|
090c24ade1 |
@@ -1,10 +1,10 @@
|
||||
"""Open Source Architecture Code Analyzer"""
|
||||
name = "osaca"
|
||||
__version__ = "0.4.3"
|
||||
__version__ = "0.4.5"
|
||||
|
||||
# To trigger travis deployment to pypi, do the following:
|
||||
# 1. Increment __version___
|
||||
# 2. commit to RRZE-HPC/osaca's master branch
|
||||
# 3. wait for travis to complete successful (unless already tested)
|
||||
# 3. wait for Github Actions to complete successful (unless already tested)
|
||||
# 4. tag commit with 'v{}'.format(__version__) (`git tag vX.Y.Z`)
|
||||
# 5. push tag to github (`git push origin vX.Y.Z` or push all tags with `git push --tags`)
|
||||
|
||||
@@ -520,7 +520,7 @@ instruction_forms:
|
||||
width: '512'
|
||||
throughput: 11.5
|
||||
latency: 49.0 # 11*p0+12*p02
|
||||
port_pressure: [[10, '0'], [12, '02']]
|
||||
port_pressure: [[9, '0'], [14, '02']]
|
||||
- name: fadd
|
||||
operands:
|
||||
- class: register
|
||||
@@ -1095,7 +1095,7 @@ instruction_forms:
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [2, ['5D', '6D']]]
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1d
|
||||
operands:
|
||||
- class: register
|
||||
@@ -1113,7 +1113,7 @@ instruction_forms:
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [2, ['5D', '6D']]]
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1d
|
||||
operands:
|
||||
- class: register
|
||||
@@ -1132,6 +1132,330 @@ instruction_forms:
|
||||
throughput: 2.0
|
||||
latency: 11.0 # 1*p0+1*p3+4*p56+1*p5D6D
|
||||
port_pressure: [[1, '0'],[1, '3'],[4, '56'], [4, ['5D', '6D']]] # not sure if we also have 4 data accesses
|
||||
- name: ld1w
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: ~
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1w
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: x
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1w
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: z
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: 11.0 # 1*p0+1*p3+4*p56+1*p5D6D
|
||||
port_pressure: [[1, '0'],[1, '3'],[4, '56'], [4, ['5D', '6D']]] # not sure if we also have 4 data accesses
|
||||
- name: ld1h
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: ~
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1h
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: x
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1h
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: z
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: 11.0 # 1*p0+1*p3+4*p56+1*p5D6D
|
||||
port_pressure: [[1, '0'],[1, '3'],[4, '56'], [4, ['5D', '6D']]] # not sure if we also have 4 data accesses
|
||||
- name: ld1b
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: ~
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1b
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: x
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1b
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: z
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: 11.0 # 1*p0+1*p3+4*p56+1*p5D6D
|
||||
port_pressure: [[1, '0'],[1, '3'],[4, '56'], [4, ['5D', '6D']]] # not sure if we also have 4 data accesses
|
||||
- name: ld1sw
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: ~
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1sw
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: x
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1sw
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: z
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: 11.0 # 1*p0+1*p3+4*p56+1*p5D6D
|
||||
port_pressure: [[1, '0'],[1, '3'],[4, '56'], [4, ['5D', '6D']]] # not sure if we also have 4 data accesses
|
||||
- name: ld1sh
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: ~
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1sh
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: x
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1sh
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: z
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: 11.0 # 1*p0+1*p3+4*p56+1*p5D6D
|
||||
port_pressure: [[1, '0'],[1, '3'],[4, '56'], [4, ['5D', '6D']]] # not sure if we also have 4 data accesses
|
||||
- name: ld1sb
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: ~
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1sb
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: '*'
|
||||
index: x
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 8.0 # 1*p56+1*p5D6D
|
||||
port_pressure: [[1, '56'], [1, ['5D', '6D']]]
|
||||
- name: ld1sb
|
||||
operands:
|
||||
- class: register
|
||||
prefix: z
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: p
|
||||
predication: '*'
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: z
|
||||
scale: '*'
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: 11.0 # 1*p0+1*p3+4*p56+1*p5D6D
|
||||
port_pressure: [[1, '0'],[1, '3'],[4, '56'], [4, ['5D', '6D']]] # not sure if we also have 4 data accesses
|
||||
- name: ld2d
|
||||
operands:
|
||||
- class: register
|
||||
|
||||
@@ -62,6 +62,28 @@ instruction_forms:
|
||||
imd: int
|
||||
source: false
|
||||
destination: false
|
||||
- name: fmla
|
||||
operands:
|
||||
- class: register
|
||||
prefix: "*"
|
||||
shape: "*"
|
||||
source: true
|
||||
destination: true
|
||||
- class: register
|
||||
prefix: "*"
|
||||
shape: "*"
|
||||
source: true
|
||||
destination: false
|
||||
- class: register
|
||||
prefix: "*"
|
||||
shape: "*"
|
||||
source: true
|
||||
destination: false
|
||||
- class: register
|
||||
prefix: "*"
|
||||
shape: "*"
|
||||
source: true
|
||||
destination: false
|
||||
- name: fmla
|
||||
operands:
|
||||
- class: register
|
||||
|
||||
@@ -239,7 +239,7 @@ class ParserAArch64(BaseParser):
|
||||
|
||||
# 1. Parse comment
|
||||
try:
|
||||
result = self.process_operand(self.comment.parseString(line, parseAll=True).asDict())[0]
|
||||
result = self.process_operand(self.comment.parseString(line, parseAll=True).asDict())
|
||||
result = AttrDict.convert_dict(result)
|
||||
instruction_form[self.COMMENT_ID] = " ".join(result[self.COMMENT_ID])
|
||||
except pp.ParseException:
|
||||
@@ -248,7 +248,7 @@ class ParserAArch64(BaseParser):
|
||||
try:
|
||||
result = self.process_operand(
|
||||
self.llvm_markers.parseString(line, parseAll=True).asDict()
|
||||
)[0]
|
||||
)
|
||||
result = AttrDict.convert_dict(result)
|
||||
instruction_form[self.COMMENT_ID] = " ".join(result[self.COMMENT_ID])
|
||||
except pp.ParseException:
|
||||
@@ -258,7 +258,7 @@ class ParserAArch64(BaseParser):
|
||||
try:
|
||||
result = self.process_operand(
|
||||
self.label.parseString(line, parseAll=True).asDict()
|
||||
)[0]
|
||||
)
|
||||
result = AttrDict.convert_dict(result)
|
||||
instruction_form[self.LABEL_ID] = result[self.LABEL_ID].name
|
||||
if self.COMMENT_ID in result[self.LABEL_ID]:
|
||||
@@ -273,7 +273,7 @@ class ParserAArch64(BaseParser):
|
||||
try:
|
||||
result = self.process_operand(
|
||||
self.directive.parseString(line, parseAll=True).asDict()
|
||||
)[0]
|
||||
)
|
||||
result = AttrDict.convert_dict(result)
|
||||
instruction_form[self.DIRECTIVE_ID] = AttrDict(
|
||||
{
|
||||
@@ -313,19 +313,24 @@ class ParserAArch64(BaseParser):
|
||||
# Add operands to list
|
||||
# Check first operand
|
||||
if "operand1" in result:
|
||||
operands += self.process_operand(result["operand1"])
|
||||
operand = self.process_operand(result["operand1"])
|
||||
operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
|
||||
# Check second operand
|
||||
if "operand2" in result:
|
||||
operands += self.process_operand(result["operand2"])
|
||||
operand = self.process_operand(result["operand2"])
|
||||
operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
|
||||
# Check third operand
|
||||
if "operand3" in result:
|
||||
operands += self.process_operand(result["operand3"])
|
||||
operand = self.process_operand(result["operand3"])
|
||||
operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
|
||||
# Check fourth operand
|
||||
if "operand4" in result:
|
||||
operands += self.process_operand(result["operand4"])
|
||||
operand = self.process_operand(result["operand4"])
|
||||
operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
|
||||
# Check fifth operand
|
||||
if "operand5" in result:
|
||||
operands += self.process_operand(result["operand5"])
|
||||
operand = self.process_operand(result["operand5"])
|
||||
operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
|
||||
|
||||
return_dict = AttrDict(
|
||||
{
|
||||
@@ -342,7 +347,7 @@ class ParserAArch64(BaseParser):
|
||||
"""Post-process operand"""
|
||||
# structure memory addresses
|
||||
if self.MEMORY_ID in operand:
|
||||
return [self.process_memory_address(operand[self.MEMORY_ID])]
|
||||
return self.process_memory_address(operand[self.MEMORY_ID])
|
||||
# structure register lists
|
||||
if self.REGISTER_ID in operand and (
|
||||
"list" in operand[self.REGISTER_ID] or "range" in operand[self.REGISTER_ID]
|
||||
@@ -350,15 +355,15 @@ class ParserAArch64(BaseParser):
|
||||
# resolve ranges and lists
|
||||
return self.resolve_range_list(self.process_register_list(operand[self.REGISTER_ID]))
|
||||
if self.REGISTER_ID in operand and operand[self.REGISTER_ID]["name"] == "sp":
|
||||
return [self.process_sp_register(operand[self.REGISTER_ID])]
|
||||
return self.process_sp_register(operand[self.REGISTER_ID])
|
||||
# add value attribute to floating point immediates without exponent
|
||||
if self.IMMEDIATE_ID in operand:
|
||||
return [self.process_immediate(operand[self.IMMEDIATE_ID])]
|
||||
return self.process_immediate(operand[self.IMMEDIATE_ID])
|
||||
if self.LABEL_ID in operand:
|
||||
return [self.process_label(operand[self.LABEL_ID])]
|
||||
return self.process_label(operand[self.LABEL_ID])
|
||||
if self.IDENTIFIER_ID in operand:
|
||||
return [self.process_identifier(operand[self.IDENTIFIER_ID])]
|
||||
return [operand]
|
||||
return self.process_identifier(operand[self.IDENTIFIER_ID])
|
||||
return operand
|
||||
|
||||
def process_memory_address(self, memory_address):
|
||||
"""Post-process memory address operand"""
|
||||
@@ -426,6 +431,8 @@ class ParserAArch64(BaseParser):
|
||||
reg['name'] = str(name)
|
||||
range_list.append(AttrDict({self.REGISTER_ID: reg}))
|
||||
return range_list
|
||||
# neither register list nor range, return unmodified
|
||||
return operand
|
||||
|
||||
def process_register_list(self, register_list):
|
||||
"""Post-process register lists (e.g., {r0,r3,r5}) and register ranges (e.g., {r0-r7})"""
|
||||
|
||||
@@ -329,6 +329,7 @@ class TestParserAArch64(unittest.TestCase):
|
||||
instr_list = "POP {x5, x6, x7}"
|
||||
instr_range_with_index = "ld4 {v0.S - v3.S}[2]"
|
||||
instr_list_with_index = "ld4 {v0.S, v1.S, v2.S, v3.S}[2]"
|
||||
instr_range_single = "dummy { z1.d }"
|
||||
reg_list = [
|
||||
AttrDict({"register": {"prefix": "x", "name": "5"}}),
|
||||
AttrDict({"register": {"prefix": "x", "name": "6"}}),
|
||||
@@ -340,15 +341,19 @@ class TestParserAArch64(unittest.TestCase):
|
||||
AttrDict({"register": {"prefix": "v", "name": "2", "shape": "S", "index": 2}}),
|
||||
AttrDict({"register": {"prefix": "v", "name": "3", "shape": "S", "index": 2}}),
|
||||
]
|
||||
reg_list_single = [AttrDict({"register": {"prefix": "z", "name": "1", "shape": "d"}})]
|
||||
|
||||
prange = self.parser.parse_line(instr_range)
|
||||
plist = self.parser.parse_line(instr_list)
|
||||
p_idx_range = self.parser.parse_line(instr_range_with_index)
|
||||
p_idx_list = self.parser.parse_line(instr_list_with_index)
|
||||
p_single = self.parser.parse_line(instr_range_single)
|
||||
|
||||
self.assertEqual(prange.operands, reg_list)
|
||||
self.assertEqual(plist.operands, reg_list)
|
||||
self.assertEqual(p_idx_range.operands, reg_list_idx)
|
||||
self.assertEqual(p_idx_list.operands, reg_list_idx)
|
||||
self.assertEqual(p_single.operands, reg_list_single)
|
||||
|
||||
def test_reg_dependency(self):
|
||||
reg_1_1 = AttrDict({"prefix": "b", "name": "1"})
|
||||
@@ -402,18 +407,18 @@ class TestParserAArch64(unittest.TestCase):
|
||||
def _get_comment(self, parser, comment):
|
||||
return " ".join(
|
||||
AttrDict.convert_dict(
|
||||
parser.process_operand(parser.comment.parseString(comment, parseAll=True).asDict())[0]
|
||||
parser.process_operand(parser.comment.parseString(comment, parseAll=True).asDict())
|
||||
).comment
|
||||
)
|
||||
|
||||
def _get_label(self, parser, label):
|
||||
return AttrDict.convert_dict(
|
||||
parser.process_operand(parser.label.parseString(label, parseAll=True).asDict())[0]
|
||||
parser.process_operand(parser.label.parseString(label, parseAll=True).asDict())
|
||||
).label
|
||||
|
||||
def _get_directive(self, parser, directive):
|
||||
return AttrDict.convert_dict(
|
||||
parser.process_operand(parser.directive.parseString(directive, parseAll=True).asDict())[0]
|
||||
parser.process_operand(parser.directive.parseString(directive, parseAll=True).asDict())
|
||||
).directive
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user