Compare commits

...

7 Commits

Author SHA1 Message Date
JanLJL
457ccdcf77 version bump 2021-07-21 02:41:05 +02:00
JanLJL
ff61c65d58 added more load instrs 2021-07-21 02:34:31 +02:00
JanLJL
615c809fe3 updated a few DB entries 2021-06-02 16:37:18 +02:00
JanLJL
bce837dec9 version bump 2021-06-01 00:13:38 +02:00
JanLJL
090c24ade1 fixed parsing of reg ranges and lists 2021-06-01 00:10:05 +02:00
JanLJL
03a2a1da33 version bump 2021-05-10 12:56:35 +02:00
JanLJL
d59b100fa8 changed immediate type from str to int 2021-05-10 01:12:30 +02:00
9 changed files with 456 additions and 68 deletions

View File

@@ -1,10 +1,10 @@
"""Open Source Architecture Code Analyzer"""
name = "osaca"
__version__ = "0.4.2"
__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`)

View File

@@ -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

View File

@@ -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

View File

@@ -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:
@@ -256,7 +256,9 @@ class ParserAArch64(BaseParser):
# 2. Parse label
if result is None:
try:
result = self.process_operand(self.label.parseString(line, parseAll=True).asDict())[0]
result = self.process_operand(
self.label.parseString(line, parseAll=True).asDict()
)
result = AttrDict.convert_dict(result)
instruction_form[self.LABEL_ID] = result[self.LABEL_ID].name
if self.COMMENT_ID in result[self.LABEL_ID]:
@@ -271,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(
{
@@ -311,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(
{
@@ -340,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]
@@ -348,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"""
@@ -364,6 +371,8 @@ class ParserAArch64(BaseParser):
offset = memory_address.get("offset", None)
if isinstance(offset, list) and len(offset) == 1:
offset = offset[0]
if offset is not None and "value" in offset:
offset["value"] = int(offset["value"], 0)
base = memory_address.get("base", None)
index = memory_address.get("index", None)
scale = 1
@@ -380,7 +389,12 @@ class ParserAArch64(BaseParser):
if "pre_indexed" in memory_address:
new_dict["pre_indexed"] = True
if "post_indexed" in memory_address:
new_dict["post_indexed"] = memory_address["post_indexed"]
if "value" in memory_address["post_indexed"]:
new_dict["post_indexed"] = {"value": int(
memory_address["post_indexed"]["value"], 0
)}
else:
new_dict["post_indexed"] = memory_address["post_indexed"]
return AttrDict({self.MEMORY_ID: new_dict})
def process_sp_register(self, register):
@@ -392,32 +406,33 @@ class ParserAArch64(BaseParser):
def resolve_range_list(self, operand):
"""
Resolve range or list register operand to list of registers.
Returns None if neither list nor range
"""
if 'register' in operand:
if 'list' in operand.register:
index = operand.register.get('index')
l = []
range_list = []
for reg in operand.register.list:
reg = deepcopy(reg)
if index is not None:
reg.index = index
l.append(AttrDict({self.REGISTER_ID: reg}))
return l
reg['index'] = int(index, 0)
range_list.append(AttrDict({self.REGISTER_ID: reg}))
return range_list
elif 'range' in operand.register:
base_register = operand.register.range[0]
index = operand.register.get('index')
l = []
range_list = []
start_name = base_register.name
end_name = operand.register.range[1].name
for name in range(int(start_name), int(end_name)+1):
for name in range(int(start_name), int(end_name) + 1):
reg = deepcopy(base_register)
if index is not None:
reg['index'] = operand.register.range.index
reg['index'] = int(index, 0)
reg['name'] = str(name)
l.append(AttrDict({self.REGISTER_ID: reg}))
return l
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})"""
@@ -447,11 +462,13 @@ class ParserAArch64(BaseParser):
if "value" in immediate:
# normal integer value
immediate["type"] = "int"
# convert hex/bin immediates to dec
immediate["value"] = self.normalize_imd(immediate)
return AttrDict({self.IMMEDIATE_ID: immediate})
if "base_immediate" in immediate:
# arithmetic immediate, add calculated value as value
immediate["shift"] = immediate["shift"][0]
immediate["value"] = int(immediate["base_immediate"]["value"], 0) << int(
immediate["value"] = self.normalize_imd(immediate["base_immediate"]) << int(
immediate["shift"]["value"]
)
immediate["type"] = "int"
@@ -499,10 +516,11 @@ class ParserAArch64(BaseParser):
def normalize_imd(self, imd):
"""Normalize immediate to decimal based representation"""
if "value" in imd:
if imd["value"].lower().startswith("0x"):
# hex, return decimal
return int(imd["value"], 16)
return int(imd["value"], 10)
if isinstance(imd["value"], str):
# hex or bin, return decimal
return int(imd["value"], 0)
else:
return imd["value"]
elif "float" in imd:
return self.ieee_to_float(imd["float"])
elif "double" in imd:

View File

@@ -327,9 +327,14 @@ class ParserX86ATT(BaseParser):
offset = memory_address.get("offset", None)
base = memory_address.get("base", None)
index = memory_address.get("index", None)
scale = 1 if "scale" not in memory_address else int(memory_address["scale"])
scale = 1 if "scale" not in memory_address else int(memory_address["scale"], 0)
if isinstance(offset, str) and base is None and index is None:
offset = {"value": offset}
try:
offset = {"value": int(offset, 0)}
except ValueError:
offset = {"value": offset}
elif offset is not None and "value" in offset:
offset["value"] = int(offset["value"], 0)
new_dict = AttrDict({"offset": offset, "base": base, "index": index, "scale": scale})
# Add segmentation extension if existing
if self.SEGMENT_EXT_ID in memory_address:
@@ -347,7 +352,8 @@ class ParserX86ATT(BaseParser):
if "identifier" in immediate:
# actually an identifier, change declaration
return immediate
# otherwise nothing to do
# otherwise just make sure the immediate is a decimal
immediate["value"] = int(immediate["value"], 0)
return AttrDict({self.IMMEDIATE_ID: immediate})
def get_full_reg_name(self, register):
@@ -358,10 +364,11 @@ class ParserX86ATT(BaseParser):
def normalize_imd(self, imd):
"""Normalize immediate to decimal based representation"""
if "value" in imd:
if imd["value"].lower().startswith("0x"):
# hex, return decimal
return int(imd["value"], 16)
return int(imd["value"], 10)
if isinstance(imd["value"], str):
# return decimal
return int(imd["value"], 0)
else:
return imd["value"]
# identifier
return imd

View File

@@ -163,10 +163,10 @@ class ISASemantics(object):
if only_postindexed:
for o in instruction_form.operands:
if 'post_indexed' in o.get('memory', {}):
base_name = o.memory.base.get('prefix', '')+o.memory.base.name
base_name = o.memory.base.get('prefix', '') + o.memory.base.name
return {base_name: {
'name': o.memory.base.get('prefix', '')+o.memory.base.name,
'value': int(o.memory.post_indexed.value)
'name': o.memory.base.get('prefix', '') + o.memory.base.name,
'value': o.memory.post_indexed.value
}}
return {}
@@ -180,24 +180,24 @@ class ISASemantics(object):
raise ValueError(
"ISA information for pre-indexed instruction {!r} has operation set."
"This is currently not supprted.".format(instruction_form.line))
base_name = o.memory.base.get('prefix', '')+o.memory.base.name
base_name = o.memory.base.get('prefix', '') + o.memory.base.name
reg_operand_names = {base_name: 'op1'}
operand_state = {'op1': {
'name': base_name,
'value': int(o.memory.offset.value)
'value': o.memory.offset.value
}}
if isa_data is not None and 'operation' in isa_data:
for i, o in enumerate(instruction_form.operands):
operand_name = "op{}".format(i+1)
operand_name = "op{}".format(i + 1)
if "register" in o:
o_reg_name = o["register"].get('prefix', '')+o["register"]["name"]
o_reg_name = o["register"].get('prefix', '') + o["register"]["name"]
reg_operand_names[o_reg_name] = operand_name
operand_state[operand_name] = {
'name': o_reg_name,
'value': 0}
elif "immediate" in o:
operand_state[operand_name] = {'value': int(o["immediate"]["value"])}
operand_state[operand_name] = {'value': o["immediate"]["value"]}
elif "memory" in o:
# TODO lea needs some thinking about
pass

View File

@@ -382,9 +382,9 @@ class KernelDG(nx.DiGraph):
# determine absolute address change
addr_change = 0
if src.offset and "value" in src.offset:
addr_change += int(src.offset.value, 0)
addr_change += src.offset.value
if mem.offset:
addr_change -= int(mem.offset.value, 0)
addr_change -= mem.offset.value
if mem.base and src.base:
base_change = register_changes.get(
src.base.get('prefix', '') + src.base.name,

View File

@@ -102,7 +102,7 @@ class TestParserAArch64(unittest.TestCase):
self.assertEqual(parsed_3.instruction, "mov")
self.assertEqual(parsed_3.operands[0].register.name, "2")
self.assertEqual(parsed_3.operands[0].register.prefix, "x")
self.assertEqual(parsed_3.operands[1].immediate.value, "0x222")
self.assertEqual(parsed_3.operands[1].immediate.value, int("0x222", 0))
self.assertEqual(parsed_3.comment, "NOT IACA END")
self.assertEqual(parsed_4.instruction, "str")
@@ -208,7 +208,7 @@ class TestParserAArch64(unittest.TestCase):
{"prfop": {"type": ["PLD"], "target": ["L1"], "policy": ["KEEP"]}},
{
"memory": {
"offset": {"value": "2048"},
"offset": {"value": 2048},
"base": {"prefix": "x", "name": "26"},
"index": None,
"scale": 1,
@@ -228,7 +228,7 @@ class TestParserAArch64(unittest.TestCase):
{"register": {"prefix": "x", "name": "30"}},
{
"memory": {
"offset": {"value": "-16"},
"offset": {"value": -16},
"base": {"name": "sp", "prefix": "x"},
"index": None,
"scale": 1,
@@ -253,7 +253,7 @@ class TestParserAArch64(unittest.TestCase):
"base": {"prefix": "x", "name": "11"},
"index": None,
"scale": 1,
"post_indexed": {"value": "64"},
"post_indexed": {"value": 64},
}
},
],
@@ -270,7 +270,7 @@ class TestParserAArch64(unittest.TestCase):
{"register": {"prefix": "p", "name": "0", "predication": "m"}},
{"register": {"prefix": "z", "name": "29", "shape": "d"}},
{"register": {"prefix": "z", "name": "21", "shape": "d"}},
{"immediate": {"value": "90", "type": "int"}},
{"immediate": {"value": 90, "type": "int"}},
],
"directive": None,
"comment": None,
@@ -327,16 +327,33 @@ class TestParserAArch64(unittest.TestCase):
def test_multiple_regs(self):
instr_range = "PUSH {x5-x7}"
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"}}),
AttrDict({"register": {"prefix": "x", "name": "7"}}),
]
reg_list_idx = [
AttrDict({"register": {"prefix": "v", "name": "0", "shape": "S", "index": 2}}),
AttrDict({"register": {"prefix": "v", "name": "1", "shape": "S", "index": 2}}),
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"})
@@ -390,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

View File

@@ -120,12 +120,12 @@ class TestParserX86ATT(unittest.TestCase):
self.assertIsNone(parsed_2.comment)
self.assertEqual(parsed_3.instruction, "movl")
self.assertEqual(parsed_3.operands[0].immediate.value, "222")
self.assertEqual(parsed_3.operands[0].immediate.value, 222)
self.assertEqual(parsed_3.operands[1].register.name, "ebx")
self.assertEqual(parsed_3.comment, "IACA END")
self.assertEqual(parsed_4.instruction, "vmovss")
self.assertEqual(parsed_4.operands[1].memory.offset.value, "-4")
self.assertEqual(parsed_4.operands[1].memory.offset.value, -4)
self.assertEqual(parsed_4.operands[1].memory.base.name, "rsp")
self.assertEqual(parsed_4.operands[1].memory.index.name, "rax")
self.assertEqual(parsed_4.operands[1].memory.scale, 8)
@@ -146,7 +146,7 @@ class TestParserX86ATT(unittest.TestCase):
self.assertEqual(parsed_6.operands[0].memory.scale, 8)
self.assertEqual(parsed_6.operands[1].register.name, "rbx")
self.assertEqual(parsed_7.operands[0].immediate.value, "0x1")
self.assertEqual(parsed_7.operands[0].immediate.value, 0x1)
self.assertEqual(parsed_7.operands[1].register.name, "xmm0")
self.assertEqual(parsed_7.operands[2].register.name, "ymm1")
self.assertEqual(parsed_7.operands[3].register.name, "ymm1")
@@ -189,7 +189,7 @@ class TestParserX86ATT(unittest.TestCase):
"operands": [
{
"memory": {
"offset": {"value": "2"},
"offset": {"value": 2},
"base": {"name": "rax"},
"index": {"name": "rax"},
"scale": 1,
@@ -240,7 +240,7 @@ class TestParserX86ATT(unittest.TestCase):
imd_decimal_1 = {"value": "79"}
imd_hex_1 = {"value": "0x4f"}
imd_decimal_2 = {"value": "8"}
imd_hex_2 = {"value": "0x8"}
imd_hex_2 = {"value": "8"}
self.assertEqual(
self.parser.normalize_imd(imd_decimal_1), self.parser.normalize_imd(imd_hex_1)
)