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()
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)
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
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)