コード例 #1
0
ファイル: parser_x86att.py プロジェクト: RRZE-HPC/OSACA
 def process_memory_address(self, memory_address):
     """Post-process memory address operand"""
     # Remove unecessarily created dictionary entries during memory address parsing
     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"], 0)
     if isinstance(offset, str) and base is None and index is None:
         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:
         new_dict[self.SEGMENT_EXT_ID] = memory_address[self.SEGMENT_EXT_ID]
     return AttrDict({self.MEMORY_ID: new_dict})
コード例 #2
0
ファイル: parser_AArch64.py プロジェクト: Lerking/OSACA
 def process_immediate(self, immediate):
     """Post-process immediate operand"""
     dict_name = ''
     if 'identifier' in immediate:
         # actually an identifier, change declaration
         return immediate
     if 'value' in immediate:
         # normal integer value, nothing to do
         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']) << int(
                 immediate['shift']['value'])
         return AttrDict({self.IMMEDIATE_ID: immediate})
     if 'float' in immediate:
         dict_name = 'float'
     if 'double' in immediate:
         dict_name = 'double'
     if 'exponent' in immediate[dict_name]:
         # nothing to do
         return AttrDict({self.IMMEDIATE_ID: immediate})
     else:
         # change 'mantissa' key to 'value'
         return AttrDict({
             self.IMMEDIATE_ID:
             AttrDict({'value': immediate[dict_name]['mantissa']})
         })
コード例 #3
0
ファイル: parser_AArch64.py プロジェクト: RRZE-HPC/OSACA
 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')
             range_list = []
             for reg in operand.register.list:
                 reg = deepcopy(reg)
                 if index is not None:
                     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')
             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):
                 reg = deepcopy(base_register)
                 if index is not None:
                     reg['index'] = int(index, 0)
                 reg['name'] = str(name)
                 range_list.append(AttrDict({self.REGISTER_ID: reg}))
             return range_list
     # neither register list nor range, return unmodified
     return operand
コード例 #4
0
ファイル: parser_AArch64.py プロジェクト: RRZE-HPC/OSACA
 def process_immediate(self, immediate):
     """Post-process immediate operand"""
     dict_name = ""
     if "identifier" in immediate:
         # actually an identifier, change declaration
         return immediate
     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"] = self.normalize_imd(immediate["base_immediate"]) << int(
             immediate["shift"]["value"]
         )
         immediate["type"] = "int"
         return AttrDict({self.IMMEDIATE_ID: immediate})
     if "float" in immediate:
         dict_name = "float"
     if "double" in immediate:
         dict_name = "double"
     if "exponent" in immediate[dict_name]:
         immediate["type"] = dict_name
         return AttrDict({self.IMMEDIATE_ID: immediate})
     else:
         # change 'mantissa' key to 'value'
         return AttrDict({
             self.IMMEDIATE_ID: AttrDict({
                 "value": immediate[dict_name]["mantissa"],
                 "type": dict_name})}
         )
コード例 #5
0
ファイル: parser_AArch64.py プロジェクト: RRZE-HPC/OSACA
 def process_memory_address(self, memory_address):
     """Post-process memory address operand"""
     # Remove unnecessarily created dictionary entries during parsing
     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
     if base is not None and "name" in base and base["name"] == "sp":
         base["prefix"] = "x"
     if index is not None and "name" in index and index["name"] == "sp":
         index["prefix"] = "x"
     valid_shift_ops = ["lsl", "uxtw", "sxtw"]
     if "index" in memory_address:
         if "shift" in memory_address["index"]:
             if memory_address["index"]["shift_op"].lower() in valid_shift_ops:
                 scale = 2 ** int(memory_address["index"]["shift"][0]["value"])
     new_dict = AttrDict({"offset": offset, "base": base, "index": index, "scale": scale})
     if "pre_indexed" in memory_address:
         new_dict["pre_indexed"] = True
     if "post_indexed" in memory_address:
         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})
コード例 #6
0
ファイル: parser_x86att.py プロジェクト: Lerking/OSACA
    def parse_instruction(self, instruction):
        """
        Parse instruction in asm line.

        :param str instruction: Assembly line string.
        :returns: `dict` -- parsed instruction form
        """
        result = self.instruction_parser.parseString(instruction,
                                                     parseAll=True).asDict()
        result = AttrDict.convert_dict(result)
        operands = []
        # Add operands to list
        # Check first operand
        if 'operand1' in result:
            operands.append(self.process_operand(result['operand1']))
        # Check second operand
        if 'operand2' in result:
            operands.append(self.process_operand(result['operand2']))
        # Check third operand
        if 'operand3' in result:
            operands.append(self.process_operand(result['operand3']))
        # Check fourth operand
        if 'operand4' in result:
            operands.append(self.process_operand(result['operand4']))
        return_dict = AttrDict({
            self.INSTRUCTION_ID:
            result['mnemonic'],
            self.OPERANDS_ID:
            operands,
            self.COMMENT_ID:
            ' '.join(result[self.COMMENT_ID])
            if self.COMMENT_ID in result else None,
        })
        return return_dict
コード例 #7
0
ファイル: parser_AArch64.py プロジェクト: Lerking/OSACA
 def process_memory_address(self, memory_address):
     """Post-process memory address operand"""
     # Remove unnecessarily created dictionary entries during parsing
     offset = memory_address.get('offset', None)
     if isinstance(offset, list) and len(offset) == 1:
         offset = offset[0]
     base = memory_address.get('base', None)
     index = memory_address.get('index', None)
     scale = 1
     if base is not None and 'name' in base and base['name'] == 'sp':
         base['prefix'] = 'x'
     if index is not None and 'name' in index and index['name'] == 'sp':
         index['prefix'] = 'x'
     valid_shift_ops = ['lsl', 'uxtw', 'sxtw']
     if 'index' in memory_address:
         if 'shift' in memory_address['index']:
             if memory_address['index']['shift_op'].lower(
             ) in valid_shift_ops:
                 scale = 2**int(memory_address['index']['shift']['value'])
     new_dict = AttrDict({
         'offset': offset,
         'base': base,
         'index': index,
         'scale': scale
     })
     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']
     return AttrDict({self.MEMORY_ID: new_dict})
コード例 #8
0
ファイル: isa_semantics.py プロジェクト: RRZE-HPC/OSACA
    def _apply_found_ISA_data(self, isa_data, operands):
        """
        Create operand dictionary containing src/dst operands out of the ISA data entry and
        the oeprands of an instruction form

        If breaks_pedendency_on_equal_operands is True (configuted per instruction in ISA db)
        and all operands are equal, place operand into destination only.

        :param dict isa_data: ISA DB entry
        :param list operands: operands of the instruction form
        :returns: `dict` -- operands dictionary with src/dst assignment
        """
        op_dict = {}
        op_dict["source"] = []
        op_dict["destination"] = []
        op_dict["src_dst"] = []

        # handle dependency breaking instructions
        if "breaks_pedendency_on_equal_operands" in isa_data and operands[
                1:] == operands[:-1]:
            op_dict["destination"] += operands
            if "hidden_operands" in isa_data:
                op_dict["destination"] += [
                    AttrDict.convert_dict({
                        hop["class"]: {
                            k: hop[k]
                            for k in ["class", "source", "destination"]
                        }
                    }) for hop in isa_data["hidden_operands"]
                ]
            return op_dict

        for i, op in enumerate(isa_data["operands"]):
            if op["source"] and op["destination"]:
                op_dict["src_dst"].append(operands[i])
                continue
            if op["source"]:
                op_dict["source"].append(operands[i])
                continue
            if op["destination"]:
                op_dict["destination"].append(operands[i])
                continue
        # check for hidden operands like flags or registers
        if "hidden_operands" in isa_data:
            # add operand(s) to semantic_operands of instruction form
            for op in isa_data["hidden_operands"]:
                dict_key = ("src_dst" if op["source"] and op["destination"]
                            else "source" if op["source"] else "destination")
                hidden_op = {op["class"]: {}}
                key_filter = ["class", "source", "destination"]
                for key in [k for k in op.keys() if k not in key_filter]:
                    hidden_op[op["class"]][key] = op[key]
                hidden_op = AttrDict.convert_dict(hidden_op)
                op_dict[dict_key].append(hidden_op)
        return op_dict
コード例 #9
0
    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)
コード例 #10
0
 def process_memory_address(self, memory_address):
     """Post-process memory address operand"""
     # Remove unecessarily created dictionary entries during memory address parsing
     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'])
     if isinstance(offset, str) and base is None and index is None:
         offset = {'value': offset}
     new_dict = AttrDict({'offset': offset, 'base': base, 'index': index, 'scale': scale})
     # Add segmentation extension if existing
     if self.SEGMENT_EXT_ID in memory_address:
         new_dict[self.SEGMENT_EXT_ID] = memory_address[self.SEGMENT_EXT_ID]
     return AttrDict({self.MEMORY_ID: new_dict})
コード例 #11
0
ファイル: test_base_parser.py プロジェクト: RRZE-HPC/OSACA
 def test_register_funcs(self):
     reg_a1 = AttrDict({"name": "rax"})
     reg_a2 = AttrDict({"name": "eax"})
     register_string = "v1.2d"
     with self.assertRaises(NotImplementedError):
         self.parser.is_reg_dependend_of(reg_a1, reg_a2)
     with self.assertRaises(NotImplementedError):
         self.parser.parse_register(register_string)
     with self.assertRaises(NotImplementedError):
         self.parser.is_gpr(reg_a1)
     with self.assertRaises(NotImplementedError):
         self.parser.is_vector_register(reg_a1)
     with self.assertRaises(NotImplementedError):
         self.parser.process_operand(reg_a1)
     with self.assertRaises(NotImplementedError):
         self.parser.get_full_reg_name(reg_a1)
コード例 #12
0
ファイル: parser_x86att.py プロジェクト: RRZE-HPC/OSACA
 def process_directive(self, directive):
     directive_new = {"name": directive["name"], "parameters": []}
     if "parameters" in directive:
         directive_new["parameters"] = directive["parameters"]
     if "comment" in directive:
         directive_new["comment"] = directive["comment"]
     return AttrDict({self.DIRECTIVE_ID: directive_new})
コード例 #13
0
ファイル: parser_x86att.py プロジェクト: Lerking/OSACA
 def process_immediate(self, immediate):
     """Post-process immediate operand"""
     if 'identifier' in immediate:
         # actually an identifier, change declaration
         return immediate
     # otherwise nothing to do
     return AttrDict({self.IMMEDIATE_ID: immediate})
コード例 #14
0
ファイル: parser_x86att.py プロジェクト: Lerking/OSACA
 def process_directive(self, directive):
     directive_new = {'name': directive['name'], 'parameters': []}
     if 'parameters' in directive:
         directive_new['parameters'] = directive['parameters']
     if 'comment' in directive:
         directive_new['comment'] = directive['comment']
     return AttrDict({self.DIRECTIVE_ID: directive_new})
コード例 #15
0
ファイル: parser_x86att.py プロジェクト: RRZE-HPC/OSACA
 def process_immediate(self, immediate):
     """Post-process immediate operand"""
     if "identifier" in immediate:
         # actually an identifier, change declaration
         return immediate
     # otherwise just make sure the immediate is a decimal
     immediate["value"] = int(immediate["value"], 0)
     return AttrDict({self.IMMEDIATE_ID: immediate})
コード例 #16
0
ファイル: parser_AArch64.py プロジェクト: Lerking/OSACA
 def process_register_list(self, register_list):
     """Post-process register lists (e.g., {r0,r3,r5}) and register ranges (e.g., {r0-r7})"""
     # Remove unnecessarily created dictionary entries during parsing
     rlist = []
     dict_name = ''
     if 'list' in register_list:
         dict_name = 'list'
     if 'range' in register_list:
         dict_name = 'range'
     for r in register_list[dict_name]:
         rlist.append(
             AttrDict.convert_dict(
                 self.list_element.parseString(r, parseAll=True).asDict()))
     index = register_list.get('index', None)
     new_dict = AttrDict({dict_name: rlist, 'index': index})
     if len(new_dict[dict_name]) == 1:
         return AttrDict({self.REGISTER_ID: new_dict[dict_name][0]})
     return AttrDict({self.REGISTER_ID: new_dict})
コード例 #17
0
ファイル: parser_AArch64.py プロジェクト: RRZE-HPC/OSACA
    def parse_instruction(self, instruction):
        """
        Parse instruction in asm line.

        :param str instruction: Assembly line string.
        :returns: `dict` -- parsed instruction form
        """
        result = self.instruction_parser.parseString(instruction, parseAll=True).asDict()
        result = AttrDict.convert_dict(result)
        operands = []
        # Add operands to list
        # Check first operand
        if "operand1" in result:
            operand = self.process_operand(result["operand1"])
            operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
        # Check second operand
        if "operand2" in result:
            operand = self.process_operand(result["operand2"])
            operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
        # Check third operand
        if "operand3" in result:
            operand = self.process_operand(result["operand3"])
            operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
        # Check fourth operand
        if "operand4" in result:
            operand = self.process_operand(result["operand4"])
            operands.extend(operand) if isinstance(operand, list) else operands.append(operand)
        # Check fifth operand
        if "operand5" in result:
            operand = self.process_operand(result["operand5"])
            operands.extend(operand) if isinstance(operand, list) else operands.append(operand)

        return_dict = AttrDict(
            {
                self.INSTRUCTION_ID: result.mnemonic,
                self.OPERANDS_ID: operands,
                self.COMMENT_ID: " ".join(result[self.COMMENT_ID])
                if self.COMMENT_ID in result
                else None,
            }
        )
        return return_dict
コード例 #18
0
    def test_multiple_regs(self):
        instr_range = 'PUSH {x5-x7}'
        reg_range = AttrDict({
            'register': {
                'range': [{
                    'prefix': 'x',
                    'name': '5'
                }, {
                    'prefix': 'x',
                    'name': '7'
                }],
                'index':
                None
            }
        })
        instr_list = 'POP {x5, x7, x9}'
        reg_list = AttrDict({
            'register': {
                'list': [{
                    'prefix': 'x',
                    'name': '5'
                }, {
                    'prefix': 'x',
                    'name': '7'
                }, {
                    'prefix': 'x',
                    'name': '9'
                }],
                'index':
                None
            }
        })
        prange = self.parser.parse_line(instr_range)
        plist = self.parser.parse_line(instr_list)

        self.assertEqual(prange.operands[0], reg_range)
        self.assertEqual(plist.operands[0], reg_list)
コード例 #19
0
ファイル: test_semantics.py プロジェクト: jdomke/OSACA
    def test_is_read_is_written_x86(self):
        # independent form HW model
        dag = KernelDG(self.kernel_x86, self.parser_x86, None)
        reg_rcx = AttrDict({'name': 'rcx'})
        reg_ymm1 = AttrDict({'name': 'ymm1'})

        instr_form_r_c = self.parser_x86.parse_line(
            'vmovsd  %xmm0, (%r15,%rcx,8)')
        self.semantics_csx.assign_src_dst(instr_form_r_c)
        instr_form_non_r_c = self.parser_x86.parse_line(
            'movl  %xmm0, (%r15,%rax,8)')
        self.semantics_csx.assign_src_dst(instr_form_non_r_c)
        instr_form_w_c = self.parser_x86.parse_line('movi $0x05ACA, %rcx')
        self.semantics_csx.assign_src_dst(instr_form_w_c)

        instr_form_rw_ymm_1 = self.parser_x86.parse_line(
            'vinsertf128 $0x1, %xmm1, %ymm0, %ymm1')
        self.semantics_csx.assign_src_dst(instr_form_rw_ymm_1)
        instr_form_rw_ymm_2 = self.parser_x86.parse_line(
            'vinsertf128 $0x1, %xmm0, %ymm1, %ymm1')
        self.semantics_csx.assign_src_dst(instr_form_rw_ymm_2)
        instr_form_r_ymm = self.parser_x86.parse_line('vmovapd %ymm1, %ymm0')
        self.semantics_csx.assign_src_dst(instr_form_r_ymm)

        self.assertTrue(dag.is_read(reg_rcx, instr_form_r_c))
        self.assertFalse(dag.is_read(reg_rcx, instr_form_non_r_c))
        self.assertFalse(dag.is_read(reg_rcx, instr_form_w_c))
        self.assertTrue(dag.is_written(reg_rcx, instr_form_w_c))
        self.assertFalse(dag.is_written(reg_rcx, instr_form_r_c))

        self.assertTrue(dag.is_read(reg_ymm1, instr_form_rw_ymm_1))
        self.assertTrue(dag.is_read(reg_ymm1, instr_form_rw_ymm_2))
        self.assertTrue(dag.is_read(reg_ymm1, instr_form_r_ymm))
        self.assertTrue(dag.is_written(reg_ymm1, instr_form_rw_ymm_1))
        self.assertTrue(dag.is_written(reg_ymm1, instr_form_rw_ymm_2))
        self.assertFalse(dag.is_written(reg_ymm1, instr_form_r_ymm))
コード例 #20
0
    def _apply_found_ISA_data(self, isa_data, operands):
        """
        Create operand dictionary containing src/dst operands out of the ISA data entry and
        the oeprands of an instruction form

        :param dict isa_data: ISA DB entry
        :param list operands: operands of the instruction form
        :returns: `dict` -- operands dictionary with src/dst assignment
        """
        op_dict = {}
        op_dict['source'] = []
        op_dict['destination'] = []
        op_dict['src_dst'] = []
        for i, op in enumerate(isa_data['operands']):
            if op['source'] and op['destination']:
                op_dict['src_dst'].append(operands[i])
                continue
            if op['source']:
                op_dict['source'].append(operands[i])
                continue
            if op['destination']:
                op_dict['destination'].append(operands[i])
                continue
        # check for hidden operands like flags or registers
        if 'hidden_operands' in isa_data:
            # add operand(s) to semantic_operands of instruction form
            for op in isa_data['hidden_operands']:
                dict_key = (
                    'src_dst'
                    if op['source'] and op['destination']
                    else 'source'
                    if op['source']
                    else 'destination'
                )
                hidden_op = {op['class']: {}}
                key_filter = ['class', 'source', 'destination']
                for key in [k for k in op.keys() if k not in key_filter]:
                    hidden_op[op['class']][key] = op[key]
                hidden_op = AttrDict.convert_dict(hidden_op)
                op_dict[dict_key].append(hidden_op)
        return op_dict
コード例 #21
0
 def _get_comment(self, parser, comment):
     return ' '.join(
         AttrDict.convert_dict(
             parser.process_operand(
                 parser.comment.parseString(
                     comment, parseAll=True).asDict())).comment)
コード例 #22
0
ファイル: parser_x86att.py プロジェクト: Lerking/OSACA
 def process_label(self, label):
     """Post-process label asm line"""
     # remove duplicated 'name' level due to identifier
     label['name'] = label['name'][0]['name']
     return AttrDict({self.LABEL_ID: label})
コード例 #23
0
ファイル: parser_x86att.py プロジェクト: Lerking/OSACA
    def parse_line(self, line, line_number=None):
        """
        Parse line and return instruction form.

        :param str line: line of assembly code
        :param line_number: default None, identifier of instruction form
        :type line_number: int, optional
        :return: ``dict`` -- parsed asm line (comment, label, directive or instruction form)
        """
        instruction_form = AttrDict({
            self.INSTRUCTION_ID: None,
            self.OPERANDS_ID: [],
            self.DIRECTIVE_ID: None,
            self.COMMENT_ID: None,
            self.LABEL_ID: None,
            'line': line,
            'line_number': line_number,
        })
        result = None

        # 1. Parse comment
        try:
            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:
            pass

        # 2. Parse label
        if result is None:
            try:
                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]:
                    instruction_form[self.COMMENT_ID] = ' '.join(
                        result[self.LABEL_ID][self.COMMENT_ID])
            except pp.ParseException:
                pass

        # 3. Parse directive
        if result is None:
            try:
                result = self.process_operand(
                    self.directive.parseString(line, parseAll=True).asDict())
                result = AttrDict.convert_dict(result)
                instruction_form[self.DIRECTIVE_ID] = AttrDict({
                    'name':
                    result[self.DIRECTIVE_ID]['name'],
                    'parameters':
                    result[self.DIRECTIVE_ID]['parameters'],
                })
                if self.COMMENT_ID in result[self.DIRECTIVE_ID]:
                    instruction_form[self.COMMENT_ID] = ' '.join(
                        result[self.DIRECTIVE_ID][self.COMMENT_ID])
            except pp.ParseException:
                pass

        # 4. Parse instruction
        if result is None:
            try:
                result = self.parse_instruction(line)
            except pp.ParseException:
                raise ValueError(
                    'Could not parse instruction on line {}: {!r}'.format(
                        line_number, line))
            instruction_form[self.INSTRUCTION_ID] = result[self.INSTRUCTION_ID]
            instruction_form[self.OPERANDS_ID] = result[self.OPERANDS_ID]
            instruction_form[self.COMMENT_ID] = result[self.COMMENT_ID]

        return instruction_form
コード例 #24
0
ファイル: parser_AArch64.py プロジェクト: Lerking/OSACA
 def process_identifier(self, identifier):
     """Post-process identifier operand"""
     # remove value if it consists of symbol+offset
     if 'value' in identifier:
         del identifier['value']
     return AttrDict({self.IDENTIFIER_ID: identifier})
コード例 #25
0
ファイル: parser_AArch64.py プロジェクト: Lerking/OSACA
 def process_sp_register(self, register):
     """Post-process stack pointer register"""
     reg = register
     reg['prefix'] = 'x'
     return AttrDict({self.REGISTER_ID: reg})
コード例 #26
0
ファイル: parser_AArch64.py プロジェクト: Lerking/OSACA
    def parse_line(self, line, line_number=None):
        """
        Parse line and return instruction form.

        :param str line: line of assembly code
        :param line_number: identifier of instruction form, defautls to None
        :type line_number: int, optional
        :return: `dict` -- parsed asm line (comment, label, directive or instruction form)
        """
        instruction_form = AttrDict({
            self.INSTRUCTION_ID: None,
            self.OPERANDS_ID: [],
            self.DIRECTIVE_ID: None,
            self.COMMENT_ID: None,
            self.LABEL_ID: None,
            'line': line,
            'line_number': line_number,
        })
        result = None

        # 1. Parse comment
        try:
            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:
            pass
        # 1.2 check for llvm-mca marker
        try:
            result = self.process_operand(
                self.llvm_markers.parseString(line, parseAll=True).asDict())
            result = AttrDict.convert_dict(result)
            instruction_form[self.COMMENT_ID] = ' '.join(
                result[self.COMMENT_ID])
        except pp.ParseException:
            pass
        # 2. Parse label
        if result is None:
            try:
                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]:
                    instruction_form[self.COMMENT_ID] = ' '.join(
                        result[self.LABEL_ID][self.COMMENT_ID])
            except pp.ParseException:
                pass

        # 3. Parse directive
        if result is None:
            try:
                result = self.process_operand(
                    self.directive.parseString(line, parseAll=True).asDict())
                result = AttrDict.convert_dict(result)
                instruction_form[self.DIRECTIVE_ID] = AttrDict({
                    'name':
                    result[self.DIRECTIVE_ID].name,
                    'parameters':
                    result[self.DIRECTIVE_ID].parameters,
                })
                if self.COMMENT_ID in result[self.DIRECTIVE_ID]:
                    instruction_form[self.COMMENT_ID] = ' '.join(
                        result[self.DIRECTIVE_ID][self.COMMENT_ID])
            except pp.ParseException:
                pass

        # 4. Parse instruction
        if result is None:
            try:
                result = self.parse_instruction(line)
            except (pp.ParseException, KeyError):
                print(
                    '\n\n*-*-*-*-*-*-*-*-*-*-\n{}: {}\n*-*-*-*-*-*-*-*-*-*-\n\n'
                    .format(line_number, line))
            instruction_form[self.INSTRUCTION_ID] = result[self.INSTRUCTION_ID]
            instruction_form[self.OPERANDS_ID] = result[self.OPERANDS_ID]
            instruction_form[self.COMMENT_ID] = result[self.COMMENT_ID]

        return instruction_form
コード例 #27
0
 def _get_directive(self, parser, directive):
     return AttrDict.convert_dict(
         parser.process_operand(
             parser.directive.parseString(
                 directive, parseAll=True).asDict())).directive
コード例 #28
0
    def test_reg_dependency(self):
        reg_1_1 = AttrDict({'prefix': 'b', 'name': '1'})
        reg_1_2 = AttrDict({'prefix': 'h', 'name': '1'})
        reg_1_3 = AttrDict({'prefix': 's', 'name': '1'})
        reg_1_4 = AttrDict({'prefix': 'd', 'name': '1'})
        reg_1_4 = AttrDict({'prefix': 'q', 'name': '1'})
        reg_2_1 = AttrDict({'prefix': 'w', 'name': '2'})
        reg_2_2 = AttrDict({'prefix': 'x', 'name': '2'})
        reg_v1_1 = AttrDict({
            'prefix': 'v',
            'name': '11',
            'lanes': '16',
            'shape': 'b'
        })
        reg_v1_2 = AttrDict({
            'prefix': 'v',
            'name': '11',
            'lanes': '8',
            'shape': 'h'
        })
        reg_v1_3 = AttrDict({
            'prefix': 'v',
            'name': '11',
            'lanes': '4',
            'shape': 's'
        })
        reg_v1_4 = AttrDict({
            'prefix': 'v',
            'name': '11',
            'lanes': '2',
            'shape': 'd'
        })

        reg_b5 = AttrDict({'prefix': 'b', 'name': '5'})
        reg_q15 = AttrDict({'prefix': 'q', 'name': '15'})
        reg_v10 = AttrDict({
            'prefix': 'v',
            'name': '10',
            'lanes': '2',
            'shape': 's'
        })
        reg_v20 = AttrDict({
            'prefix': 'v',
            'name': '20',
            'lanes': '2',
            'shape': 'd'
        })

        reg_1 = [reg_1_1, reg_1_2, reg_1_3, reg_1_4]
        reg_2 = [reg_2_1, reg_2_2]
        reg_v = [reg_v1_1, reg_v1_2, reg_v1_3, reg_v1_4]
        reg_others = [reg_b5, reg_q15, reg_v10, reg_v20]
        regs = reg_1 + reg_2 + reg_v + reg_others

        # test each register against each other
        for ri in reg_1:
            for rj in regs:
                assert_value = True if rj in reg_1 else False
                with self.subTest(reg_a=ri, reg_b=rj, assert_val=assert_value):
                    self.assertEqual(self.parser.is_reg_dependend_of(ri, rj),
                                     assert_value)
        for ri in reg_2:
            for rj in regs:
                assert_value = True if rj in reg_2 else False
                with self.subTest(reg_a=ri, reg_b=rj, assert_val=assert_value):
                    self.assertEqual(self.parser.is_reg_dependend_of(ri, rj),
                                     assert_value)
        for ri in reg_v:
            for rj in regs:
                assert_value = True if rj in reg_v else False
                with self.subTest(reg_a=ri, reg_b=rj, assert_val=assert_value):
                    self.assertEqual(self.parser.is_reg_dependend_of(ri, rj),
                                     assert_value)
        for ri in reg_others:
            for rj in regs:
                assert_value = True if rj == ri else False
                with self.subTest(reg_a=ri, reg_b=rj, assert_val=assert_value):
                    self.assertEqual(self.parser.is_reg_dependend_of(ri, rj),
                                     assert_value)
コード例 #29
0
ファイル: test_semantics.py プロジェクト: jdomke/OSACA
    def test_is_read_is_written_AArch64(self):
        # independent form HW model
        dag = KernelDG(self.kernel_AArch64, self.parser_AArch64, None)
        reg_x1 = AttrDict({'prefix': 'x', 'name': '1'})
        reg_w1 = AttrDict({'prefix': 'w', 'name': '1'})
        reg_d1 = AttrDict({'prefix': 'd', 'name': '1'})
        reg_q1 = AttrDict({'prefix': 'q', 'name': '1'})
        reg_v1 = AttrDict({
            'prefix': 'v',
            'name': '1',
            'lanes': '2',
            'shape': 'd'
        })
        regs = [reg_d1, reg_q1, reg_v1]
        regs_gp = [reg_w1, reg_x1]

        instr_form_r_1 = self.parser_AArch64.parse_line(
            'stp q1, q3, [x12, #192]')
        self.semantics_tx2.assign_src_dst(instr_form_r_1)
        instr_form_r_2 = self.parser_AArch64.parse_line(
            'fadd v2.2d, v1.2d, v0.2d')
        self.semantics_tx2.assign_src_dst(instr_form_r_2)
        instr_form_w_1 = self.parser_AArch64.parse_line(
            'ldr d1, [x1, #:got_lo12:q2c]')
        self.semantics_tx2.assign_src_dst(instr_form_w_1)
        instr_form_non_w_1 = self.parser_AArch64.parse_line(
            'ldr x1, [x1, #:got_lo12:q2c]')
        self.semantics_tx2.assign_src_dst(instr_form_non_w_1)
        instr_form_rw_1 = self.parser_AArch64.parse_line(
            'fmul v1.2d, v1.2d, v0.2d')
        self.semantics_tx2.assign_src_dst(instr_form_rw_1)
        instr_form_rw_2 = self.parser_AArch64.parse_line(
            'ldp q2, q4, [x1, #64]!')
        self.semantics_tx2.assign_src_dst(instr_form_rw_2)
        instr_form_rw_3 = self.parser_AArch64.parse_line('str x4, [x1], #64')
        self.semantics_tx2.assign_src_dst(instr_form_rw_3)
        instr_form_non_rw_1 = self.parser_AArch64.parse_line('adds x1, x11')
        self.semantics_tx2.assign_src_dst(instr_form_non_rw_1)

        for reg in regs:
            with self.subTest(reg=reg):
                self.assertTrue(dag.is_read(reg, instr_form_r_1))
                self.assertTrue(dag.is_read(reg, instr_form_r_2))
                self.assertTrue(dag.is_read(reg, instr_form_rw_1))
                self.assertFalse(dag.is_read(reg, instr_form_rw_2))
                self.assertFalse(dag.is_read(reg, instr_form_rw_3))
                self.assertFalse(dag.is_read(reg, instr_form_w_1))
                self.assertTrue(dag.is_written(reg, instr_form_w_1))
                self.assertTrue(dag.is_written(reg, instr_form_rw_1))
                self.assertFalse(dag.is_written(reg, instr_form_non_w_1))
                self.assertFalse(dag.is_written(reg, instr_form_rw_2))
                self.assertFalse(dag.is_written(reg, instr_form_rw_3))
                self.assertFalse(dag.is_written(reg, instr_form_non_rw_1))
                self.assertFalse(dag.is_written(reg, instr_form_non_rw_1))
        for reg in regs_gp:
            with self.subTest(reg=reg):
                self.assertFalse(dag.is_read(reg, instr_form_r_1))
                self.assertFalse(dag.is_read(reg, instr_form_r_2))
                self.assertFalse(dag.is_read(reg, instr_form_rw_1))
                self.assertTrue(dag.is_read(reg, instr_form_rw_2))
                self.assertTrue(dag.is_read(reg, instr_form_rw_3))
                self.assertTrue(dag.is_read(reg, instr_form_w_1))
                self.assertFalse(dag.is_written(reg, instr_form_w_1))
                self.assertFalse(dag.is_written(reg, instr_form_rw_1))
                self.assertTrue(dag.is_written(reg, instr_form_non_w_1))
                self.assertTrue(dag.is_written(reg, instr_form_rw_2))
                self.assertTrue(dag.is_written(reg, instr_form_rw_3))
                self.assertTrue(dag.is_written(reg, instr_form_non_rw_1))
                self.assertTrue(dag.is_written(reg, instr_form_non_rw_1))
コード例 #30
0
 def _get_label(self, parser, label):
     return AttrDict.convert_dict(
         parser.process_operand(
             parser.label.parseString(label, parseAll=True).asDict())).label