def generate_local_assign(self, assign: LocalAssignStmt): left = assign.left.name_list right = assign.right.expr_list # left -- add local variable # for name in left: # right -- calc value and assign to left variable for idx, name in enumerate(left): register = self.symbol_table.insert(name.value, name) # res = self.symbol_table.lookup(name.value) val = right[idx] res = self.generate_expr(register, val) if ExprEnum.BINOP == val.kind and BinOpEnum.AND == val.value.operator: self._back_path(val.false_list) elif ExprEnum.BINOP == val.kind and BinOpEnum.OR == val.value.operator: self._back_path(val.true_list) if res < 0 and (type(self.constant_pool.index(res)) == TermFalse or type(self.constant_pool.index(res)) == TermTrue): self.proto.add_instruction(Instruction(OpCode.LOADBOOL, register, 0 if type(self.constant_pool.index(res)) == TermFalse else 1)) else: # same register not generate opcode if register != res: self.proto.add_instruction(Instruction(OpCode.LOADK, register, res))
def main(): file = open("input.txt", mode="r", encoding="utf-8") wire1 = file.readline().strip().split(',') wire2 = file.readline().strip().split(',') pos = Point(1, 1) dic = {} for idx in range(len(wire1)): instr = Instruction(wire1[idx]) current = instr.count while current > 0: instr.mutatePos(pos) dic[pos.key()] = "1" current -= 1 pos = Point(1, 1) closest = -1 for idx in range(len(wire2)): instr = Instruction(wire2[idx]) current = instr.count while current > 0: current -= 1 instr.mutatePos(pos) if (pos.key() in dic): distance = abs(pos.x - 1) + abs(pos.y - 1) print('intersection distance', distance, 'on', pos.key()) if (closest == -1 or closest > distance): closest = distance print('closest intersection', closest)
def instructions_generate(self): instruction_type = ["write", "read", "calc"] index = 0 read = 0 calc = 0 write = 0 while index < 100: operation = np.random.normal(2) operation = int(np.round(operation)) if operation > 2 or operation < 0: pass else: # If operation is 0, it means that is a write. if operation == 0: flag = True while flag: address = np.random.poisson(8) if 0 <= address < 16: write_instruction = Instruction() write_instruction.set_processor_number( self.get_number()) write_instruction.set_operation( instruction_type[0]) write_instruction.set_address_bin(address) write_instruction.set_data(random.randint( 0, 65535)) self.add_instruction(write_instruction) flag = False write += 1 else: pass # If operation is 1, it means that is a read elif operation == 1: flag = True while flag: address = np.random.poisson(8) if 0 <= address < 16: read_instruction = Instruction() read_instruction.set_processor_number( self.get_number()) read_instruction.set_operation(instruction_type[1]) read_instruction.set_address_bin(address) read_instruction.set_data(0) self.add_instruction(read_instruction) flag = False read += 1 else: pass elif operation == 2: calc_instruction = Instruction() calc_instruction.set_processor_number(self.get_number()) calc_instruction.set_operation(instruction_type[2]) calc_instruction.set_address_bin(0) calc_instruction.set_data(0) self.add_instruction(calc_instruction) calc += 1 index += 1 print("Calc:" + str(calc)) print("Read:" + str(read)) print("Write:" + str(write))
def main(): file = open("input.txt", mode="r", encoding="utf-8") wire1 = file.readline().strip().split(',') wire2 = file.readline().strip().split(',') pos = Point(1, 1) steps = 0 dic = {} for idx in range(len(wire1)): instr = Instruction(wire1[idx]) current = instr.count while current > 0: steps += 1 instr.mutatePos(pos) dic[pos.key()] = steps current -= 1 pos = Point(1, 1) closest = -1 steps = 0 for idx in range(len(wire2)): instr = Instruction(wire2[idx]) current = instr.count while current > 0: steps += 1 current -= 1 instr.mutatePos(pos) if (pos.key() in dic): totalSteps = dic[pos.key()] + steps print('intersection steps, a ', dic[pos.key()], 'b ', steps, 'total', totalSteps) if (closest == -1 or closest > totalSteps): closest = totalSteps print('least steps to intersection', closest)
def __init__(self, memory_image, forwarding=False, debug=False): ''' Instantiate a new processor. ''' self.mem_image = copy.deepcopy(memory_image) self.original_mem = memory_image self.forwarding = forwarding self.debug = debug self.frwrd_dict = dict() self.regs = memory.registers() self.data_list = [ 0, Instruction(None), Instruction(None), Instruction(None), Instruction(None) ] self.pc = 0 self.arith_opcode = ['Add', 'Addi', 'Sub', 'Subi', 'Mul', 'Muli'] self.logic_opcode = ['Or', 'Ori', 'And', 'Andi', 'Xor', 'Xori'] self.ld_opcode = ['Ldw', 'Stw'] self.ctrl_opcode = ['Bz', 'Beq', 'Jr', 'Halt'] self.r_type = ['Add', 'Sub', 'Mul', 'Or', 'And', 'Xor'] self.reg_change = {} self.ari_count = 0 self.logic_count = 0 self.ctrl_count = 0 self.ld_count = 0 self.stall_cycle = 0 self.num_instructions = 0 self.hazards = 0 self.st_count = [] self.Halt = False self.cycles = 0
def Fetch(self, ): ''' Instruction Fetch stage of the processor. Fetches address of instruction from the program counter. ''' if self.debug: print("In IF stage: ", self.data_list[0]) if self.Halt: return if self.data_list[0] == None: self.data_list[1] = Instruction(None) return if self.stall_cycle > 0: self.stall_cycle = self.stall_cycle - 1 if self.debug: print('stall cycles in IF: ', self.stall_cycle) return for inst in self.data_list[1:]: if (self.data_list[0] == inst.x_addr) and inst.opcode == 'Stw': if self.forwarding: self.data_list[1] = Instruction(hex(inst.rt)[2:]) self.pc += 4 return else: self.hazards += 1 self.stall_cycle = len( self.data_list[1:]) - self.data_list[1:].index(inst) self.st_count.append(self.stall_cycle) if self.stall_cycle > 0: if self.debug: print('stall cycles in IF: ', self.stall_cycle) return instr = self.mem_image.read_word(self.data_list[0]) self.data_list[1] = Instruction(instr) self.pc += 4 return
def _generate_equal_expr(self, register, opcode: OpCode, expr: BinOpExpr): left_reg = self.symbol_table.add_temp_var() self.generate_expr(left_reg, expr.left) right_reg = self.symbol_table.add_temp_var() self.generate_expr(right_reg, expr.right) self.proto.add_instruction(Instruction(opcode, 1, left_reg, right_reg)) self.proto.add_instruction(Instruction(OpCode.JMP, 0, 1)) self.proto.add_instruction(Instruction(OpCode.LOADBOOL, register, 1, 1)) self.proto.add_instruction(Instruction(OpCode.LOADBOOL, register, 0, 0))
def _generate_equal_expr(opcode: OpCode, expr: BinOpExpr): left = generate_expr(expr.left) right = generate_expr(expr.right) tmp = FuncStat.instance().symbol_stack.add_temp_var() add_instruction(Instruction(opcode, 1, left, right)) add_instruction(Instruction(OpCode.JMP, 0, 1)) add_instruction(Instruction(OpCode.LOADBOOL, tmp, 1, 1)) add_instruction(Instruction(OpCode.LOADBOOL, tmp, 0, 0)) return tmp
def Instruction_decode(self, ): ''' Instruction Decode stage of the processor. Decodes the instruction from the IF stage. ''' instr = self.data_list[1] instr.decode() if self.debug: print("In ID stage: ", instr) if instr.opcode == None: self.data_list[2] = instr return if self.Halt: self.data_list[2] = Instruction(None) return if self.stall_cycle > 0: if self.debug: print('stall cycles in ID: ', self.stall_cycle) self.data_list[2] = Instruction(None) return self._check_target(instr) if self.stall_cycle > 0: if self.debug: print('stall cycles in ID: ', self.stall_cycle) self.hazards += 1 self.st_count.append(self.stall_cycle) self.data_list[2] = Instruction(None) return if instr.opcode in self.arith_opcode: self.ari_count += 1 elif instr.opcode in self.logic_opcode: self.logic_count += 1 elif instr.opcode in self.ctrl_opcode: self.ctrl_count += 1 elif instr.opcode in self.ld_opcode: self.ld_count += 1 if instr.opcode == 'Halt': self.Halt = True self.data_list[2] = instr return if instr.frwd_rs == False: instr.rs = self.regs.read_reg( instr.reg_rs ) if instr.opcode in self.logic_opcode else self._getSignedNum( self.regs.read_reg(instr.reg_rs), 32) if instr.opcode in ['Jr', 'Bz']: self.data_list[2] = instr return if instr.frwd_rt == False: if instr.opcode in self.r_type: instr.rt = self._getSignedNum(self.regs.read_reg(instr.reg_rt), 32) else: if instr.opcode in ['Stw', 'Beq']: instr.rt = self.regs.read_reg(instr.reg_rt) self.data_list[2] = instr return
def test_Task1(self): solver = AoC8() solver.data = [Instruction("nop", 0), Instruction("acc", 1), Instruction("jmp", 4), Instruction("acc", 3), Instruction("jmp", -3), Instruction("acc", -99), Instruction("acc", 1), Instruction("jmp", -4), Instruction("acc", 6)] count = solver.Task1() self.assertEqual(5, count)
def test_multiple_instructions(self): state = [5,2,3,1] instr1: Instruction = Instruction("R3- -> L1, L5") instr2: Instruction = Instruction("R2+ -> L1") label, state = InstructionExecutor.execute(instr1, state) label, state = InstructionExecutor.execute(instr1, state) label, state = InstructionExecutor.execute(instr2, state) label, state = InstructionExecutor.execute(instr1, state) self.assertEqual(label, 5) self.assertEqual(state, [5,2,4,0])
def generate_login_or_expr(self, register, expr: BinOpExpr): self.generate_expr(register, expr.left) # B1 or B2 => if B1 = false jump to B2 self.proto.add_instruction(Instruction(OpCode.TEST, register, 1)) # if B1 true jump to end self.proto.add_instruction(Instruction(OpCode.JMP, 0, 0)) # record left expr true list expr.left.true_list.append(self.proto.pc()) self.generate_expr(register, expr.right) # record right expr true list expr.right.true_list.append(self.proto.pc())
def generate_login_and_expr(self, register, expr: BinOpExpr): self.generate_expr(register, expr.left) # B1 AND B2 => if B1 = true jump to B2 self.proto.add_instruction(Instruction(OpCode.TEST, register, 0)) # if B1 false jump to end self.proto.add_instruction(Instruction(OpCode.JMP, 0, 0)) jump_index = self.proto.pc() # record left expr false list expr.left.false_list.append(jump_index) self.generate_expr(register, expr.right) # record right expr true list jump_index = self.proto.pc() expr.right.false_list.append(jump_index)
def disasAt(self, offset): assert offset < len(self.c_stream) opkode = self.c_stream[offset] # Invalid instruction if opkode not in list(opcode.opmap.values()): return Instruction(-1, None, 1) if opkode < opcode.HAVE_ARGUMENT: return Instruction(opkode, None, 1) if opkode >= opcode.HAVE_ARGUMENT: arg = (self.c_stream[offset + 2] << 8) | self.c_stream[offset + 1] return Instruction(opkode, arg, 3)
def branch(self, address): self.state.programCounter = address self.state.pipeline[2] = [] for i in range(self.state.numExecuteUnits): self.state.pipeline[2].append(Instruction(np.uint32(0))) self.state.instrBuffer = deque([], self.state.instrBufferSize) return
def instructions_load(instructions): with open('T2/base_instructions.txt') as f: base_instructions = f.read().split("\n") for i in range(len(base_instructions)): base_instructions[i] = base_instructions[i].split(" ") for base_instruction in base_instructions: instructions.append(Instruction(base_instruction))
def load_instructions(): file_data = get_file_data() int_codes = [] instruction = Instruction() for i in range(len(file_data)): if (i % 4 == 0): instruction = Instruction() instruction.opcode = file_data[i] elif (i % 3 == 0 and i != 0): instruction.parameters.append(file_data[i]) int_codes.append(instruction) else: instruction.parameters.append(file_data[i]) return int_codes
def generate_login_or_expr(expr: BinOpExpr): left = generate_expr(expr.left) # B1 or B2 => if B1 = false jump to B2 FuncStat.instance().instruction.append(Instruction(OpCode.TEST, left, 1)) # if B1 true jump to end FuncStat.instance().instruction.append(Instruction(OpCode.JMP, 0, 0)) # record left expr true list jump_index = FuncStat.instance().pc() expr.left.true_list.append(jump_index) right = generate_expr(expr.right) # record right expr true list jump_index = FuncStat.instance().pc() expr.right.true_list.append(jump_index) return right
def _generate_binary_common(self, opcode: OpCode, register, binop: BinOpExpr): left_reg = self.generate_expr(register, binop.left) right_reg = self.symbol_table.add_temp_var() right_reg = self.generate_expr(right_reg, binop.right) self.proto.add_instruction(Instruction(opcode, register, left_reg, right_reg)) self.symbol_table.pop_temp_var() return register
def line_to_instruction(self, s): # Conversion # remove endline words = s.replace("\n", "") words = words.split(" ") # ignore lines with less than 2 words if len(words) < 2: return None str_name = words[0].lower() str_value = words[1] num_name = str_to_name(str_name) num_value = str_to_value(str_value) # Error Checking if num_name is None: error("Invalid Instruction " + str_name) return None if num_value is None: error("Invalid Value " + str_value) return None return Instruction(num_name, num_value)
def __init__(self, numExecuteUnits, lenInstrBuffer): self.numExecuteUnits = numExecuteUnits self.instrBufferSize = max(lenInstrBuffer, numExecuteUnits * 5); self.memory = np.zeros( 256, dtype=np.uint32) self.instructions = np.zeros(4096, dtype=np.uint32) self.reg = np.zeros( 16, dtype=np.uint32) self.instrBuffer = deque([], self.instrBufferSize) self.pipeline = deque([[], [], []], 3) # Only used for Mem access, execute and writeback now. for i in range(len(self.pipeline)): self.pipeline[i] = [] for j in range(numExecuteUnits): self.pipeline[i].append(Instruction(np.uint32(0))) # Special regs self.loadDataReg = np.uint32(0) # When something comes in from memory, it goes here self.loadAddressReg = np.uint32(0) # What address in memory we're fetching from self.storeDataReg = np.uint32(0) # What to store in memory self.storeAddressReg = np.uint32(0) # Where to store it in memory self.resultRegs = np.zeros(self.numExecuteUnits, dtype=np.uint32) # Where the result of an operation is held until writeback self.programCounter = np.uint32(0) # Next instruction to be fetched self.loadFromMemory = False # Whether we need to load from memory self.storeToMemory = False # Whether we need to store to memory self.finished = False return
def test_processor(self): p = Processor() i = Instruction('add') p.AddInstruction(i) g = Group('R') g.AddInstruction(i) p.AddGroup(g) self.assertEqual(p.FindInstruction('add'), i)
def instruction_next(self): """ Grab the next Instruction to execute """ instruction = Instruction(self) return instruction.instruction
def generate_binary_expr(binop: BinOpExpr): code = None if BinOpEnum.ADD == binop.operator: code = OpCode.ADD elif BinOpEnum.SUB == binop.operator: code = OpCode.SUB elif BinOpEnum.MUL == binop.operator: code = OpCode.MUL elif BinOpEnum.DIV == binop.operator: code = OpCode.DIV elif BinOpEnum.XOR == binop.operator: code = OpCode.BXOR elif BinOpEnum.MOD == binop.operator: code = OpCode.MOD elif BinOpEnum.LT == binop.operator: code = OpCode.LT elif BinOpEnum.LTE == binop.operator: code = OpCode.LE elif BinOpEnum.GT == binop.operator: # translate to LE code = OpCode.LE reg = RegisterManager.get_instance().new() return Instruction(code, generate_expr(binop.right), generate_expr(binop.left), reg) elif BinOpEnum.GTE == binop.operator: # translate to LT code = OpCode.LT reg = RegisterManager.get_instance().new() return Instruction(code, generate_expr(binop.right), generate_expr(binop.left), reg) elif BinOpEnum.EQ == binop.operator: code = OpCode.EQ elif BinOpEnum.CONCAT == binop.operator: code = OpCode.CONCAT elif BinOpEnum.AND == binop.operator: return generate_login_and_expr(binop) elif BinOpEnum.OR == binop.operator: return generate_login_or_expr(binop) left = generate_expr(binop.left) right = generate_expr(binop.right) # reg = FuncStat.instance().symbol_stack.add_temp_var() add_instruction(Instruction(code, left, left, right)) return left
def get_instructions(filename): instructions = [] with open(filename, 'r') as f: for line in f: tokens = line[:-1].split(' ') assert len(tokens) == 2 instruction = Instruction(tokens[0], int(tokens[1])) instructions.append(instruction) return instructions
def generate_login_and_expr(expr: BinOpExpr): left = generate_expr(expr.left) tmp = FuncStat.instance().symbol_stack.add_temp_var() add_instruction(Instruction(OpCode.MOVE, tmp, left)) # B1 AND B2 => if B1 = true jump to B2 add_instruction(Instruction(OpCode.TEST, left, 0)) # if B1 false jump to end add_instruction(Instruction(OpCode.JMP, 0, 0)) jump_index = FuncStat.instance().pc() # record left expr false list expr.left.false_list.append(jump_index) right = generate_expr(expr.right) add_instruction(Instruction(OpCode.MOVE, tmp, right)) # record right expr true list jump_index = FuncStat.instance().pc() expr.right.false_list.append(jump_index) return tmp
def decode_at(self, offset): assert offset < len(self.insBytes) opcode = self.insBytes[offset] if opcode == dis.opmap['EXTENDED_ARG']: raise Exception('EXTENDED_ARG not yet implemented') # Invalid instruction if opcode not in dis.opmap.values(): return Instruction(-1, None, 1) if opcode < dis.HAVE_ARGUMENT: return Instruction(opcode, None, 1) if opcode >= dis.HAVE_ARGUMENT: arg = (self.insBytes[offset + 2] << 8) | self.insBytes[offset + 1] return Instruction(opcode, arg, 3)
def second_pass(line): i = None line = strip_line(line) if len(line) > 0: if line.startswith('('): pass else: i = Instruction(line, symbol_table) return i
def generate_if_expr(if_stmt: IfStmt): cond = if_stmt.cond test = generate_expr(cond) add_instruction(Instruction(OpCode.TEST, test, 0)) add_instruction(Instruction(OpCode.JMP, 0, 0)) cond.false_list.append(FuncStat.instance().pc()) # then S1 # M1 # _back_path(cond.true_list, FuncStat.instance().pc()) generate_block(if_stmt.block) if if_stmt.elif_arr or if_stmt.else_block: add_instruction(Instruction(OpCode.JMP, 0, 0)) if_stmt.block.next_list.append(FuncStat.instance().pc()) # M1 _back_path(cond.false_list, FuncStat.instance().pc()) cur_test = cond # elif block if if_stmt.elif_arr: for el in if_stmt.elif_arr: _back_path(cur_test.false_list, FuncStat.instance().pc()) cur_test = el.cond tes = generate_expr(cur_test) add_instruction(Instruction(OpCode.TEST, tes, 0)) add_instruction(Instruction(OpCode.JMP, 0, 0)) generate_block(el.block) el.block.next_list.append(FuncStat.instance().pc()) # elif blocks if if_stmt.elif_arr: for el in if_stmt.elif_arr: _back_path(el.block.next_list, FuncStat.instance().pc()) # else block if if_stmt.else_block: generate_block(if_stmt.else_block) _back_path(if_stmt.block.next_list, FuncStat.instance().pc()) else: # N _back_path(if_stmt.block.next_list, FuncStat.instance().pc()) _back_path(cur_test.false_list, FuncStat.instance().pc())
def instructions_executer(self): terminated = False while self.controller.pc < len(self.instruction_set): print(self.controller.reg) instruction = Instruction(self.controller) self.controller = instruction.execute() print(self.controller.reg) print() print("program terminated")