fixed parsing of reg ranges and lists

This commit is contained in:
JanLJL
2021-06-01 00:10:05 +02:00
parent 03a2a1da33
commit 090c24ade1
2 changed files with 30 additions and 18 deletions

View File

@@ -239,7 +239,7 @@ class ParserAArch64(BaseParser):
# 1. Parse comment # 1. Parse comment
try: 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) result = AttrDict.convert_dict(result)
instruction_form[self.COMMENT_ID] = " ".join(result[self.COMMENT_ID]) instruction_form[self.COMMENT_ID] = " ".join(result[self.COMMENT_ID])
except pp.ParseException: except pp.ParseException:
@@ -248,7 +248,7 @@ class ParserAArch64(BaseParser):
try: try:
result = self.process_operand( result = self.process_operand(
self.llvm_markers.parseString(line, parseAll=True).asDict() self.llvm_markers.parseString(line, parseAll=True).asDict()
)[0] )
result = AttrDict.convert_dict(result) result = AttrDict.convert_dict(result)
instruction_form[self.COMMENT_ID] = " ".join(result[self.COMMENT_ID]) instruction_form[self.COMMENT_ID] = " ".join(result[self.COMMENT_ID])
except pp.ParseException: except pp.ParseException:
@@ -258,7 +258,7 @@ class ParserAArch64(BaseParser):
try: try:
result = self.process_operand( result = self.process_operand(
self.label.parseString(line, parseAll=True).asDict() self.label.parseString(line, parseAll=True).asDict()
)[0] )
result = AttrDict.convert_dict(result) result = AttrDict.convert_dict(result)
instruction_form[self.LABEL_ID] = result[self.LABEL_ID].name instruction_form[self.LABEL_ID] = result[self.LABEL_ID].name
if self.COMMENT_ID in result[self.LABEL_ID]: if self.COMMENT_ID in result[self.LABEL_ID]:
@@ -273,7 +273,7 @@ class ParserAArch64(BaseParser):
try: try:
result = self.process_operand( result = self.process_operand(
self.directive.parseString(line, parseAll=True).asDict() self.directive.parseString(line, parseAll=True).asDict()
)[0] )
result = AttrDict.convert_dict(result) result = AttrDict.convert_dict(result)
instruction_form[self.DIRECTIVE_ID] = AttrDict( instruction_form[self.DIRECTIVE_ID] = AttrDict(
{ {
@@ -313,19 +313,24 @@ class ParserAArch64(BaseParser):
# Add operands to list # Add operands to list
# Check first operand # Check first operand
if "operand1" in result: 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 # Check second operand
if "operand2" in result: 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 # Check third operand
if "operand3" in result: 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 # Check fourth operand
if "operand4" in result: 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 # Check fifth operand
if "operand5" in result: 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( return_dict = AttrDict(
{ {
@@ -342,7 +347,7 @@ class ParserAArch64(BaseParser):
"""Post-process operand""" """Post-process operand"""
# structure memory addresses # structure memory addresses
if self.MEMORY_ID in operand: 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 # structure register lists
if self.REGISTER_ID in operand and ( if self.REGISTER_ID in operand and (
"list" in operand[self.REGISTER_ID] or "range" in operand[self.REGISTER_ID] "list" in operand[self.REGISTER_ID] or "range" in operand[self.REGISTER_ID]
@@ -350,15 +355,15 @@ class ParserAArch64(BaseParser):
# resolve ranges and lists # resolve ranges and lists
return self.resolve_range_list(self.process_register_list(operand[self.REGISTER_ID])) 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": 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 # add value attribute to floating point immediates without exponent
if self.IMMEDIATE_ID in operand: 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: 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: if self.IDENTIFIER_ID in operand:
return [self.process_identifier(operand[self.IDENTIFIER_ID])] return self.process_identifier(operand[self.IDENTIFIER_ID])
return [operand] return operand
def process_memory_address(self, memory_address): def process_memory_address(self, memory_address):
"""Post-process memory address operand""" """Post-process memory address operand"""
@@ -426,6 +431,8 @@ class ParserAArch64(BaseParser):
reg['name'] = str(name) reg['name'] = str(name)
range_list.append(AttrDict({self.REGISTER_ID: reg})) range_list.append(AttrDict({self.REGISTER_ID: reg}))
return range_list return range_list
# neither register list nor range, return unmodified
return operand
def process_register_list(self, register_list): def process_register_list(self, register_list):
"""Post-process register lists (e.g., {r0,r3,r5}) and register ranges (e.g., {r0-r7})""" """Post-process register lists (e.g., {r0,r3,r5}) and register ranges (e.g., {r0-r7})"""

View File

@@ -329,6 +329,7 @@ class TestParserAArch64(unittest.TestCase):
instr_list = "POP {x5, x6, x7}" instr_list = "POP {x5, x6, x7}"
instr_range_with_index = "ld4 {v0.S - v3.S}[2]" 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_list_with_index = "ld4 {v0.S, v1.S, v2.S, v3.S}[2]"
instr_range_single = "dummy { z1.d }"
reg_list = [ reg_list = [
AttrDict({"register": {"prefix": "x", "name": "5"}}), AttrDict({"register": {"prefix": "x", "name": "5"}}),
AttrDict({"register": {"prefix": "x", "name": "6"}}), 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": "2", "shape": "S", "index": 2}}),
AttrDict({"register": {"prefix": "v", "name": "3", "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) prange = self.parser.parse_line(instr_range)
plist = self.parser.parse_line(instr_list) plist = self.parser.parse_line(instr_list)
p_idx_range = self.parser.parse_line(instr_range_with_index) p_idx_range = self.parser.parse_line(instr_range_with_index)
p_idx_list = self.parser.parse_line(instr_list_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(prange.operands, reg_list)
self.assertEqual(plist.operands, reg_list) self.assertEqual(plist.operands, reg_list)
self.assertEqual(p_idx_range.operands, reg_list_idx) self.assertEqual(p_idx_range.operands, reg_list_idx)
self.assertEqual(p_idx_list.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): def test_reg_dependency(self):
reg_1_1 = AttrDict({"prefix": "b", "name": "1"}) reg_1_1 = AttrDict({"prefix": "b", "name": "1"})
@@ -402,18 +407,18 @@ class TestParserAArch64(unittest.TestCase):
def _get_comment(self, parser, comment): def _get_comment(self, parser, comment):
return " ".join( return " ".join(
AttrDict.convert_dict( 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 ).comment
) )
def _get_label(self, parser, label): def _get_label(self, parser, label):
return AttrDict.convert_dict( 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 ).label
def _get_directive(self, parser, directive): def _get_directive(self, parser, directive):
return AttrDict.convert_dict( 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 ).directive
@staticmethod @staticmethod