Ejemplo n.º 1
0
 def check_instr(self, instr):
     # Check for strange clang padding bytes
     while (instr.startswith('data32')):
         instr = instr[7:]
     # Seperate mnemonic and operands
     mnemonic = instr.split()[0]
     params = ''.join(instr.split()[1:])
     # Check if line is not only a byte
     empty_byte = re.compile(r'[0-9a-f]{2}')
     if (re.match(empty_byte, mnemonic) and len(mnemonic) == 2):
         return
     # Check if there's one or more operand and store all in a list
     param_list = self.flatten(self.separate_params(params))
     op_list = list(param_list)
     # Check operands and seperate them by IMMEDIATE (IMD), REGISTER (REG), MEMORY (MEM) or
     # LABEL (LBL)
     for i in range(len(param_list)):
         op = param_list[i]
         if (len(op) <= 0):
             op = Parameter('NONE')
         elif (op[0] == '$'):
             op = Parameter('IMD')
         elif (op[0] == '%' and '(' not in op):
             j = len(op)
             opmask = False
             if ('{' in op):
                 j = op.index('{')
                 opmask = True
             op = Register(op[1:j], opmask)
         elif ('<' in op):
             op = Parameter('LBL')
         else:
             op = MemAddr(op)
         param_list[i] = str(op) if (
             type(op) is not Register) else str(op) + str(op.size)
         op_list[i] = op
     # Join mnemonic and operand(s) to an instruction form
     if (len(mnemonic) > 7):
         tabs = '\t'
     else:
         tabs = '\t\t'
     instr_form = mnemonic + tabs + ('  '.join(param_list))
     # Check in data file for instruction form and increment the counter
     if (instr_form in self.db):
         self.db[instr_form] = self.db[instr_form] + 1
     else:
         self.db[instr_form] = 1
         # Create testcase for instruction form, since it is the first appearance of it
         # Only create benchmark if no label (LBL) is part of the operands
         do_bench = True
         for par in op_list:
             if (str(par) == 'LBL' or str(par) == ''):
                 do_bench = False
         if (do_bench):
             # Create testcase with reversed param list, due to the fact its intel syntax!
             tc = Testcase(mnemonic, list(reversed(op_list)), '64')
             tc.write_testcase()
Ejemplo n.º 2
0
    def check_instr(self, instr):
        """
        Inspect instruction for its parameters and add it to the instruction forms
        pool instr_form.

        Parameters
        ----------
        instr : str
            Instruction as string
        """
        # Check for strange clang padding bytes
        while(instr.startswith('data32')):
            instr = instr[7:]
        # Separate mnemonic and operands
        mnemonic = instr.split()[0]
        params = ''.join(instr.split()[1:])
        # Check if line is not only a byte
        empty_byte = re.compile(r'[0-9a-f]{2}')
        if(re.match(empty_byte, mnemonic) and len(mnemonic) == 2):
            return
        # Check if there's one or more operands and store all in a list
        param_list = self.flatten(self.separate_params(params))
        param_list_types = list(param_list)
        # Check operands and separate them by IMMEDIATE (IMD), REGISTER (REG),
        # MEMORY (MEM) or LABEL(LBL)
        for i in range(len(param_list)):
            op = param_list[i]
            if(len(op) <= 0):
                op = Parameter('NONE')
            elif(op[0] == '$'):
                op = Parameter('IMD')
            elif(op[0] == '%' and '(' not in op):
                j = len(op)
                opmask = False
                if('{' in op):
                    j = op.index('{')
                    opmask = True
                op = Register(op[1:j], opmask)
            elif('<' in op or op.startswith('.')):
                op = Parameter('LBL')
            else:
                op = MemAddr(op)
            param_list[i] = str(op)
            param_list_types[i] = op
        # Add to list
        instr = instr.rstrip()
        if(len(instr) > self.longestInstr):
            self.longestInstr = len(instr)
        instr_form = [mnemonic]+list(reversed(param_list_types))+[instr]
        self.instr_forms.append(instr_form)
        # If flag is set, create testcase for instruction form
        # Do this in reversed param list order, du to the fact it's intel syntax
        # Only create benchmark if no label (LBL) is part of the operands
        if('LBL' in param_list or '' in param_list):
            return
        tc = Testcase(mnemonic, list(reversed(param_list_types)), '32')
        # Only write a testcase if it not already exists or already in data file
        writeTP, writeLT = tc.is_in_dir()
        inDB = len(self.df.loc[lambda df: df.instr == tc.get_entryname()])
        if(inDB == 0):
            tc.write_testcase(not writeTP, not writeLT)
Ejemplo n.º 3
0
    def create_tp_list(self, horiz_line):
        """
        Create list of instruction forms with the proper throughput value.

        Parameter
        ---------
        horiz_line : str
            Calculated horizontal line for nice alignement

        Returns
        -------
        str
            Throughput list output for printing
        """
        warning = False
        ws = ' '*(len(horiz_line)-23)

        output = ('\n| INSTRUCTION' + ws + 'CLOCK CYCLES\n'
                  + '| ' + horiz_line + '\n|\n')
        # Check for the throughput data in CSV
        for elem in self.instr_forms:
            op_ext = []
            for i in range(1, len(elem)-1):
                optmp = ''
                if(isinstance(elem[i], Register) and elem[i].reg_type == 'GPR'):
                    optmp = 'r'+str(elem[i].size)
                elif(isinstance(elem[i], MemAddr)):
                    optmp = 'mem'
                else:
                    optmp = str(elem[i]).lower()
                op_ext.append(optmp)
            operands = '_'.join(op_ext)
            # Now look up the value in the dataframe
            # Check if there is a stored throughput value in database
            import warnings
            warnings.filterwarnings("ignore", 'This pattern has match groups')
            series = self.df['instr'].str.contains(elem[0] + '-' + operands)
            if(True in series.values):
                # It's a match!
                not_found = False
                try:
                    tp = self.df[self.df.instr == elem[0] + '-' + operands].TP.values[0]
                except IndexError:
                    # Something went wrong
                    print('Error while fetching data from data file', file=self.file_output)
                    continue
            # Did not found the exact instruction form.
            # Try to find the instruction form for register operands only
            else:
                op_ext_regs = []
                for operand in op_ext:
                    try:
                        # regTmp = Register(operand)
                        # Create Register only to see if it is one
                        Register(operand)
                        op_ext_regs.append(True)
                    except KeyError:
                        op_ext_regs.append(False)
                if(True not in op_ext_regs):
                    # No register in whole instr form. How can I find out what regsize we need?
                    print('Feature not included yet: ', end='', file=self.file_output)
                    print(elem[0]+' for '+operands, file=self.file_output)
                    tp = 0
                    not_found = True
                    warning = True
                    num_whitespaces = self.longestInstr-len(elem[-1])
                    ws = ' ' * num_whitespaces + '|  '
                    n_f = ' ' * (5 - len(str(tp))) + '*'
                    data = '| ' + elem[-1] + ws + str(tp) + n_f + '\n'
                    output += data
                    continue
                if(op_ext_regs[0] is False):
                    # Instruction stores result in memory. Check for storing in register instead.
                    if(len(op_ext) > 1):
                        if(op_ext_regs[1] is True):
                            op_ext[0] = op_ext[1]
                        elif(len(op_ext > 2)):
                            if(op_ext_regs[2] is True):
                                op_ext[0] = op_ext[2]
                if(len(op_ext_regs) == 2 and op_ext_regs[1] is False):
                    # Instruction loads value from memory and has only two operands. Check for
                    # loading from register instead
                    if(op_ext_regs[0] is True):
                        op_ext[1] = op_ext[0]
                if(len(op_ext_regs) == 3 and op_ext_regs[2] is False):
                    # Instruction loads value from memory and has three operands. Check for loading
                    # from register instead
                    op_ext[2] = op_ext[0]
                operands = '_'.join(op_ext)
                # Check for register equivalent instruction
                series = self.df['instr'].str.contains(elem[0]+'-'+operands)
                if(True in series.values):
                    # It's a match!
                    not_found = False
                    try:
                        tp = self.df[self.df.instr == elem[0]+'-'+operands].TP.values[0]
                    except IndexError:
                        # Something went wrong
                        print('Error while fetching data from data file', file=self.file_output)
                        continue
                # Did not found the register instruction form. Set warning and go on with
                # throughput 0
                else:
                    tp = 0
                    not_found = True
                    warning = True
            # Check the alignement again
            num_whitespaces = self.longestInstr - len(elem[-1])
            ws = ' ' * num_whitespaces + '|  '
            n_f = ''
            if(not_found):
                n_f = ' ' * (5 - len(str(tp))) + '*'
            data = '| ' + elem[-1] + ws + '{:3.2f}'.format(tp) + n_f + '\n'
            output += data
        # Finally end the list of  throughput values
        num_whitespaces = self.longestInstr - 27
        ws = '  ' + ' ' * num_whitespaces
        output += '| ' + horiz_line + '\n'
        if(warning):
            output += ('\n\n* There was no throughput value found '
                       'for the specific instruction form.'
                       '\n  Please create a testcase via the create_testcase-method '
                       'or add a value manually.')
        return output
Ejemplo n.º 4
0
    def check_instr(self, instr):
        """
        Inspect instruction for its parameters and add it to the instruction forms
        pool instr_form.

        Parameters
        ----------
        instr : str
            Instruction as string
        """
        # Check for strange clang padding bytes
        while instr.startswith('data32'):
            instr = instr[7:]
        # Separate mnemonic and operands
        mnemonic = instr.split()[0]
        params = instr.split()[1:]
        # Check if line is not only a byte
        empty_byte = re.compile(r'[0-9a-f]{2}')
        if re.match(empty_byte, mnemonic) and len(mnemonic) == 2:
            return
        # Check if there's one or more operands and store all in a list
        param_list = flatten(self._separate_params(params))
        param_list_types = list(param_list)
        # Check if line contains a directive and if so, add as a workaround with
        # marker in mnemonic
        directive = re.compile(r'^\.[a-zA-Z0-9]+$')
        if re.match(directive, mnemonic):
            instr = instr.rstrip()
            instr_form = ['DIRECTIVE'] + list() + [instr]
            self.instr_forms.append(instr_form)
            return
        # Check operands and separate them by IMMEDIATE (IMD), REGISTER (REG),
        # MEMORY (MEM) or LABEL(LBL)
        for i, op in enumerate(param_list):
            if len(op) <= 0:
                op = Parameter('NONE')
            elif op[0] == '$':
                op = Parameter('IMD')
            elif op[0] == '%' and '(' not in op:
                j = len(op)
                opmask = False
                if '{' in op:
                    j = op.index('{')
                    opmask = True
                op = Register(op[1:j].strip(" ,"), opmask)
            elif '<' in op or re.match(r'^([a-zA-Z\._]+[a-zA-Z0-9_\.]*)+$', op):
                op = Parameter('LBL')
            else:
                op = MemAddr(op)
            param_list[i] = str(op)
            param_list_types[i] = op
        # Add to list
        instr = instr.rstrip()
        if len(instr) > self.longestInstr:
            self.longestInstr = len(instr)
        instr_form = [mnemonic] + list(reversed(param_list_types)) + [instr]
        self.instr_forms.append(instr_form)
        # If flag is set, create testcase for instruction form
        # Do this in reversed param list order, du to the fact it's intel syntax
        # Only create benchmark if no label (LBL) is part of the operands
        if 'LBL' in param_list or '' in param_list:
            return
        tc = Testcase(mnemonic, list(reversed(param_list_types)), '32')
        # Only write a testcase if it not already exists or already in data file
        writeTP, writeLT = tc.is_in_dir()
        inDB = len(self.df.loc[lambda df: df.instr == tc.get_entryname()])
        if inDB == 0:
            tc.write_testcase(not writeTP, not writeLT)