def generate_instructions(self, instr_list=None, flags=None): """ Generate code for a ``|`` operator if ``subtype == 'alt'``:: split L1, L2 L1: codes for e1 jmp L3 L2: codes for e2 L3: If ``subtype != 'alt'``, then this node is reduced away during parsing. """ instr_list = instr_list or [] flags = flags or {} if self.subtype == 'alt': back_jump = len(instr_list) + 1 first_split = Instruction('split', back_jump, 'TEMP') instr_list.append(first_split) instr_list = self.children[0].generate_instructions( instr_list, flags) first_jump = Instruction('jmp', 'TEMP') instr_list.append(first_jump) first_split.arg2 = len(instr_list) instr_list = self.children[1].generate_instructions( instr_list, flags) first_jump.arg1 = len(instr_list) return instr_list return super(RegexNode, self).generate_instructions(instr_list, flags)
def permute(self, perm, src, dst, indent, define): if (self.floatType != "float"): print "unpack not supported for selected precision yet." exit(-1) if (define): defineStr = "%s " % (self.registerType) else: defineStr = "" content = [] for i in perm: content.append(src.content[i]) if (perm == [1, 0, 3, 2, 5, 4, 7, 6]): ins = Instruction( "%s%s%s = _mm256_permute_%s(%s, 0xB1);\n" % (indent, defineStr, dst.name, src.name), 1) if (perm == [2, 3, 0, 1, 6, 7, 4, 5]): ins = Instruction( "%s%s%s = _mm256_castpd_%s(_mm256_permute_pd( _mm256_castps_pd(%s), 0x5));\n" % (indent, defineStr, dst.name, src.name), 1) elif (perm == [4, 5, 6, 7, 0, 1, 2, 3]): ins = Instruction( "%s%s%s = _mm256_permute2f128_%s(%s, %s, 0x01);\n" % (indent, defineStr, dst.name, src.name, src.name), 3) dst.setContent(content) return ins
def __rewrite_shift(i, instruction, block): opcode = instruction.opcode address = instruction.address if opcode not in {"DIV", "MUL"}: return if opcode == "DIV": num = instruction.reads[1] if isinstance(num, str): return if not (((num & (num - 1)) == 0) and num > 256): return exp = int(math.log(num, 2)) new_instruction = \ Instruction("SR", [instruction.reads[0], exp], instruction.writes, address) block.set_instruction(i, new_instruction) elif opcode == "MUL": num = instruction.reads[0] if isinstance(num, str): return if not (((num & (num - 1)) == 0) and num > 256): return exp = int(math.log(num, 2)) new_instruction = \ Instruction("SL", [instruction.reads[1], exp], instruction.writes, address) block.set_instruction(i, new_instruction)
def generate_instructions(self, instr_list=None, flags=None): """ Generate C{char} or C{nchar} opcode depending on whether the character is in a matching or non-matching bracket expression """ instr_list = instr_list or [] flags = flags or {} if flags['matching']: instr_list.append(Instruction('char', ord(self.data))) else: instr_list.append(Instruction('nchar', ord(self.data))) return instr_list
def generate_instructions(self, instr_list=None, flags=None): """Generates code for a character range""" instr_list = instr_list or [] flags = flags or {} if flags['matching']: instr_list.append( Instruction('char', ord(self.children[0].data), ord(self.children[1].data))) else: instr_list.append( Instruction('nchar', ord(self.children[0].data), ord(self.children[1].data))) return instr_list
def generate_instructions(self, instr_list=None, flags=None): """ Generate code for a +, *, or ? operator if ``subtype == 'dup'``. e+:: L1: codes for e split L1, L3 L3: e*:: L1: split L2, L3 L2: codes for e jmp L1 L3: e?:: split L1, L2 L1: codes for e L2: """ instr_list = instr_list or [] flags = flags or {} if self.subtype == 'dup': lchild = self.children[0] if self.data == '+': back_jump = len(instr_list) instr_list = lchild.generate_instructions(instr_list, flags) forward_jump = len(instr_list) + 1 instr_list.append(Instruction('split', back_jump, forward_jump)) return instr_list if self.data == '*' or self.data == '?': back_jump = len(instr_list) + 1 first_split = Instruction('split', back_jump, 'TEMP') instr_list.append(first_split) instr_list = lchild.generate_instructions(instr_list) if self.data == '*': instr_list.append(Instruction('jmp', back_jump - 1)) first_split.arg2 = len(instr_list) return instr_list else: return super(SimpleReNode, self).generate_instructions(instr_list, flags)
def blend(self, mask, src1, src2, dst, indent, define): if (define): defineStr = "%s " % (self.registerType) else: defineStr = "" if (self.floatType != "float"): print "unpack not supported for selected precision yet." exit(-1) content = [] verb = " //" for i in range(self.registerSize): if (mask[i]): content.append(src2.content[i]) else: content.append(src1.content[i]) verb += str(content[-1]) if (self.verbose == 0): verb = "" dst.setContent(content) ins = Instruction( "%s%s%s = _mm256_blend_%s(%s, %s, %s);%s\n" % (indent, defineStr, dst.name, self.packedPostfix, src1.name, src2.name, self.maskToHex(mask), verb), 1) return ins
def store(self, dst, offset, reg, indent): if (self.floatType != "float" and self.floatType != "double"): print "store not supported for selected precision yet." exit(-1) return Instruction( "%s_mm256_store_%s(%s + %d, %s);\n" % (indent, self.packedPostfix, dst, offset, reg.name), 0)
def generate_instructions(self, instr_list=None, flags=None): """ Use ``matching`` flag and presence of ``self.data`` in char class mapping dicts to determine what kind of instruction to return, and what its character arguments are """ instr_list = instr_list or [] flags = flags or {} if flags['matching']: # neg: [\W] = [^\w] so use nchar # And insert a BREAK because these should be separated if const.char_classes_nm.has_key(self.data): char_list = const.char_classes_nm[self.data] instr = 'nchar' if instr_list and instr_list[-1].cmd == 'nchar': instr_list.append(Instruction('BREAK')) # pos: [\w] so use char if const.char_classes_m.has_key(self.data): char_list = const.char_classes_m[self.data] instr = 'char' else: # [^\Wab\D] # neg: [^\W] = [\w] so use char. Let BrackExprListNode sort out the details. if const.char_classes_nm.has_key(self.data): char_list = const.char_classes_nm[self.data] instr = 'char' if instr_list and instr_list[-1].cmd == 'char': instr_list.append(Instruction('BREAK')) # pos: [^\w] so use nchar # But do not insert a BREAK because these should all be a global requirement if const.char_classes_m.has_key(self.data): char_list = const.char_classes_m[self.data] instr = 'nchar' # Most of char_classes_nm is just aliases to char_classes_m to save typing # An alias is indicated by a string which is a key to char_classes_m if isinstance(char_list, str): char_list = const.char_classes_m[const.char_classes_nm[self.data]] for char in char_list: if len(char) == 1: instr_list.append(Instruction(instr, ord(char[0]))) else: instr_list.append( Instruction(instr, ord(char[0]), ord(char[1]))) return instr_list
def build_paths(self): """ Create the differents paths of the car and save them in the list of paths. """ # ==================================================================== # Creation of the first path # ==================================================================== path = Path() path.add_instruction(Instruction(FORWARD, speed=50, distance=600)) self.paths.append(path) # ==================================================================== # Creation of the second path # ==================================================================== path = Path() path.add_instruction(Instruction(FORWARD, speed=50, distance=690)) path.add_instruction(Instruction(TURN_RIGHT)) path.add_instruction(Instruction(FORWARD, speed=50, distance=200)) self.paths.append(path) # ==================================================================== # Creation of the third path # ==================================================================== path = Path() path.add_instruction(Instruction(FORWARD, speed=50, distance=200)) path.add_instruction(Instruction(STOP, sleep_time=5)) path.add_instruction(Instruction(FORWARD, speed=50, distance=200)) self.paths.append(path)
def add(self, a, b, c, indent): latency = 5 content = [] for i in range(self.registerSize): content.append(a.content[i] + b.content[i]) c.setContent(content) return Instruction( "%s%s = _mm512_add_%s(%s, %s);\n" % (indent, c.name, self.packedPostfix, a.name, b.name), latency)
def generate_instructions(start_date, end_date, number_of_instructions=100): """Returns a list of random instructions Parameteres: start_date Earliest possible instruction date end_date Latest possible instruction date number_of_instructions Number of instructions to generate If no value is provided, function generates 10 instructions Possible values for instructions fields: entity Whatever value defined in a list of 9 entities buy_sell_flag Whatever value defined in the enum 'instructions.Instruction.Type' agreed_fx Whatever value in between 0.01 and 1.00 currency Whatever value defined in the enum 'common.Currency' instruction_date Whatever date settlement_date Whatever date equal or more recent than 'instruction_date' units Whatever value in between 100 and 1000 price_per_unit Whatever value in between 10.XX and 200.XX real_settlement_date if 'settlement_date' is a working day: 'settlement_date' otherwise first working day after 'settlement_date' A work week starts Monday and ends Friday, unless the currency of the trade is AED or SAR, where the work week starts Sunday and ends Thursday """ entities = [ 'ent_1', 'ent_2', 'ent_3', 'ent_4', 'ent_5', 'ent_6', 'ent_7', 'ent_8', 'ent_9' ] days = (end_date - start_date).days instructions = [] for i in range(number_of_instructions): entity = random.choice(entities) buy_sell_flag = random.choice([e.value for e in Instruction.Type]) agreed_fx = 0.01 + random.random() currency = random.choice([e.value for e in Currency]) instruction_date = start_date + datetime.timedelta( random.randint(0, days)) settlement_date = instruction_date + datetime.timedelta( random.randint(1, 2)) #FIXME: settlement_date > 2016 units = random.randint(100, 1000) price_per_unit = random.randint(10, 200) + random.random() instructions.append( Instruction(entity, buy_sell_flag, agreed_fx, currency, instruction_date, settlement_date, units, price_per_unit)) return instructions
def setzero(self, reg, indent, define): if (define): defineStr = "%s " % (self.registerType) else: defineStr = "" reg.setzero() return Instruction( "%s%s%s = _mm512_setzero_%s();\n" % (indent, defineStr, reg.name, self.packedPostfix), 1)
def test_set_real_settlement_date(self): """ Tests the correct value assignment to the field 'real_settlement_date' A work week: starts Monday and ends Friday, unless the currency of the trade is AED or SAR: where the work week starts Sunday and ends Thursday. No other holidays to be taken into account. Atrade can only be settled on a working day. """ i = Instruction( 'ent_1', Instruction.Type.Sell, agreed_fx=0.01, currency=Currency.AED, instruction_date=datetime.datetime.strptime( '2017-01-01', '%Y-%m-%d'), settlement_date=datetime.datetime.strptime( '2017-01-05', '%Y-%m-%d'), # Weekday.Thursday units=100, price_per_unit=10, real_settlement_date=None) self.assertEqual(i.real_settlement_date, i.settlement_date) i = Instruction( 'ent_1', Instruction.Type.Sell, agreed_fx=0.01, currency=Currency.AED, instruction_date=datetime.datetime.strptime( '2017-01-01', '%Y-%m-%d'), settlement_date=datetime.datetime.strptime( '2017-01-06', '%Y-%m-%d'), # Weekday.Friday units=100, price_per_unit=10, real_settlement_date=None) self.assertEqual(i.real_settlement_date, datetime.datetime.strptime('2017-01-08', '%Y-%m-%d'))
def __rewrite_negate_ops(i, instruction_0, instruction_1, block): opcode = instruction_0.opcode if instruction_0.opcode not in negate_ops or \ instruction_1.opcode != "ISZERO" or \ instruction_1.address != instruction_0.address + 1: return block.set_nop_instruction(i - 1) opcode = negate_ops[opcode] new_instruction = \ Instruction(opcode, instruction_0.reads, instruction_0.writes, instruction_0.address) block.set_instruction(i, new_instruction)
def add(self, a, b, c, indent): if (self.floatType != "float" and self.floatType != "double"): print "add not supported for selected precision yet." exit(-1) latency = 5 content = [] for i in range(self.registerSize): content.append(a.content[i] + b.content[i]) c.setContent(content) return Instruction( "%s%s = _mm256_add_%s(%s, %s);\n" % (indent, c.name, self.packedPostfix, a.name, b.name), latency)
def permute(self, perm, src, dst, indent, define): print "ERROR: arch::permute() is not implemented yet." exit(-1) content = [] for i in perm: content.append(src.content[i]) if (perm == [1, 0, 3, 2, 5, 4, 7, 6]): ins = Instruction( "%s%s%s = _mm256_permute_%s(%s, 0xB1);\n" % (indent, define, dst.name, self.packedPostfix, src.name), 1) if (perm == [2, 3, 0, 1, 6, 7, 4, 5]): ins = Instruction( "%s%s%s = _mm256_castpd_%s(_mm256_permute_pd( _mm256_castps_pd(%s), 0x5));\n" % (indent, define, dst.name, self.packedPostfix, src.name), 1) elif (perm == [4, 5, 6, 7, 0, 1, 2, 3]): ins = Instruction( "%s%s%s = _mm256_permute2f128_%s(%s, %s, 0x01);\n" % (indent, define, dst.name, self.packedPostfix, src.name, src.name), 3) dst.setContent(content) return ins
def setzero(self, reg, indent, define): if (self.floatType != "float" and self.floatType != "double"): print "setzero not supported for selected precision yet." exit(-1) if (define): defineStr = "%s " % (self.registerType) else: defineStr = "" reg.setzero() return Instruction( "%s%s%s = _mm256_setzero_%s();\n" % (indent, defineStr, reg.name, self.packedPostfix), 1)
def unpack_lo32(self, src1, src2, dst, indent, define): if (self.floatType != "float"): print "unpack not supported for selected precision yet." exit(-1) content = [] content.append(src1.content[0]) content.append(src2.content[0]) content.append(src1.content[1]) content.append(src2.content[1]) content.append(src1.content[4]) content.append(src2.content[4]) content.append(src1.content[5]) content.append(src2.content[5]) dst.setContent(content) if (define): ins = Instruction( "%s__m256 %s = _mm256_unpacklo_%s(%s,%s);\n" % (indent, dst.name, src1.name, src2.name), 1) else: ins = Instruction( "%s%s = _mm256_unpacklo_%s(%s,%s);\n" % (indent, dst.name, src1.name, src2.name), 1) return ins
def duplicate(self, perm, src, dst, indent): if (self.floatType != "float"): print "unpack not supported for selected precision yet." exit(-1) content = [] for i in perm: content.append(src.content[i]) if (perm == [0, 1, 2, 3, 0, 1, 2, 3]): ins = Instruction( "%s%s = _mm256_permute2f128_%s(%s, 0x00);\n" % (indent, dst.name, self.packedPostfix, src.name), 3) dst.setContent(content) return ins
def broadcast(self, src, offset, dst, indent, define): if (define): defineStr = "%s " % (self.registerType) else: defineStr = "" latency = 1 content = [] for i in range(self.registerSize): content.append(src + str(offset)) dst.setContent(content) return Instruction( "%s%s%s = _mm512_set1_%s(*(%s + %d));\n" % (indent, defineStr, dst.name, self.packedPostfix, src, offset), latency)
def load_l1(self, src, offset, reg, indent, define): #load from L1 if (define): defineStr = "%s " % (self.registerType) else: defineStr = "" content = [] for i in range(self.registerSize): content.append("%s%d" % (src, i + offset)) ins = Instruction( "%s%s%s = _mm512_load_%s(%s + %d);\n" % (indent, defineStr, reg.name, self.packedPostfix, src, offset), self.L1_LATENCY) reg.setContent(content) return ins
def __return_rewrites(block): local_memory = MemState() instructions = block.get_instructions() for index, instruction in enumerate(instructions): if instruction.opcode == "RETURN": begin, end = instruction.reads if begin == "$m": item = local_memory.lookup_mapping_for_return_and_log(begin) if item: value, i = item block.set_nop_instruction(i) tmp_list = [value, end] operation = Instruction("RETURN", tmp_list, instruction.writes, instruction.address) block.set_instruction(index, operation) local_memory.add_mapping_for_return_and_log(index, instruction)
def broadcast(self, src, offset, dst, indent, define): if (self.floatType != "float" and self.floatType != "double"): print "bcast not supported for selected precision yet." exit(-1) if (define): defineStr = "%s " % (self.registerType) else: defineStr = "" latency = 1 content = [] for i in range(self.registerSize): content.append(src + str(offset)) dst.setContent(content) return Instruction( "%s%s%s = _mm256_broadcast_%s(%s + %d);\n" % (indent, defineStr, dst.name, self.scalarPostfix, src, offset), latency)
def __sha3_rewrites(block): local_memory = MemState() instructions = block.get_instructions() for index, instruction in enumerate(instructions): if instruction.opcode == "SHA3": begin, end = instruction.reads if begin == 0 and not isinstance(end, str): addresses = range(begin, end, 32) items = local_memory.lookup_mapping(addresses) if len(items) != 0: values, indices = zip(*items) for i in indices: block.set_nop_instruction(i) operation = Instruction("SHA3R", list(values), instruction.writes, instruction.address) block.set_instruction(index, operation) local_memory.add_mapping(index, instruction)
def load_l1(self, src, offset, reg, indent, define): #load from L1 if (self.floatType != "float" and self.floatType != "double"): print "load_l1 not supported for selected precision yet." exit(-1) if (define): defineStr = "%s " % (self.registerType) else: defineStr = "" content = [] for i in range(self.registerSize): content.append("%s%d" % (src, i + offset)) ins = Instruction( "%s%s%s = _mm256_load_%s(%s + %d);\n" % (indent, defineStr, reg.name, self.packedPostfix, src, offset), self.L1_LATENCY) reg.setContent(content) return ins
def __log_rewrites(block): local_memory = MemState() instructions = block.get_instructions() for index, instruction in enumerate(instructions): if instruction.opcode in log_ops: begin = instruction.reads[0] if begin == "$m": item = local_memory.lookup_mapping_for_return_and_log(begin) if item: value, i = item block.set_nop_instruction(i) tmp_list = [value] if len(instruction.reads) > 2: for r in instruction.reads[2:]: tmp_list.append(r) operation = Instruction(instruction.opcode, tmp_list, instruction.writes, instruction.address) block.set_instruction(index, operation) local_memory.add_mapping_for_return_and_log(index, instruction)
def unpack_lo32(self, src1, src2, dst, indent, define): if (define): defineStr = "%s " % (self.registerType) else: defineStr = "" content = [] for i in [0, 1]: content.append(src1.content[i * 8 + 0]) content.append(src2.content[i * 8 + 0]) content.append(src1.content[i * 8 + 1]) content.append(src2.content[i * 8 + 1]) content.append(src1.content[i * 8 + 4]) content.append(src2.content[i * 8 + 4]) content.append(src1.content[i * 8 + 5]) content.append(src2.content[i * 8 + 5]) dst.setContent(content) ins = Instruction( "%s%s%s = _mm512_unpacklo_%s(%s,%s);\n" % (indent, defineStr, dst.name, self.packedPostfix, src1.name, src2.name), 1) return ins
def generate_instructions(self, instr_list=None, flags=None): """ Generate code for a character if ``subtype == 'char'``:: a char 'a' """ instr_list = instr_list or [] flags = flags or {} if self.subtype == "char": if isinstance(self.data, int): d = self.data else: d = ord(self.data) instr_list.append(Instruction('char', d)) return instr_list if self.subtype == 'group': instr_list = self.children[0].generate_instructions( instr_list, flags) return instr_list return super(NonDupReNode, self).generate_instructions(instr_list, flags)
def blend(self, mask, src1, src2, dst, indent, define): if (define): defineStr = "%s " % (self.registerType) else: defineStr = "" content = [] verb = " //" for i in range(self.registerSize): if (mask[i]): content.append(src2.content[i]) else: content.append(src1.content[i]) verb += str(content[-1]) if (self.verbose == 0): verb = "" dst.setContent(content) ins = Instruction( "%s%s%s = _mm512_blend_%s(%s, %s, %s);%s\n" % (indent, defineStr, dst.name, self.packedPostfix, src1.name, src2.name, self.maskToHex(mask), verb), 1) return ins