def __getitem__( self, idx ): if self.debug.enabled( "rf" ): print ':: RD.RF[%s] = %s' % ( pad( "%d" % idx, 2 ), pad_hex( self.regs[idx], len=self.debug_nchars ) ), return self.regs[idx]
def __setitem__(self, idx, value): value = trim_64(value) self.regs[idx] = value if self.debug.enabled("rf"): print ':: WR.RF[%s] = %s' % (pad( "%d" % idx, 2), pad_hex(self.regs[idx], len=self.debug_nchars)),
def print_regs( self, per_row=6 ): for c in xrange( 0, self.num_regs, per_row ): str = "" for r in xrange( c, min( self.num_regs, c+per_row ) ): str += "%s:%s " % ( pad( "%d" % r, 2 ), pad_hex( self.regs[r] ) ) print str
def __setitem__( self, idx, value ): value = trim_64(value) self.regs[idx] = value if self.debug.enabled( "rf" ): print ':: WR.RF[%s] = %s' % ( pad( "%d" % idx, 2 ), pad_hex( self.regs[idx], len=self.debug_nchars ) ),
def __getitem__(self, index): address, bitsize, _ = reg_memory_map[index] mask = (1 << bitsize) - 1 value = self.memory.iread(address, 4, from_core=self.coreid) & mask if (self.debug.enabled('rf') and self.logger and index < 64 and self.is_first_core): self.logger.log(' :: RD.RF[%s] = %s' % (pad('%d' % index, 2), pad_hex(value, len=self.debug_nchars))) return value
def __setitem__(self, idx, value): if idx == 15: self.state.pc = value if self.debug.enabled("rf"): print ':: WR.RF[15] = %s' % (pad_hex(value)), else: self.regs[idx] = value if self.debug.enabled("rf"): print ':: WR.RF[%s] = %s' % (pad("%d" % idx, 2), pad_hex(value)),
def __setitem__( self, idx, value ): if idx == 15: self.state.pc = value if self.debug.enabled( "rf" ): print ':: WR.RF[15] = %s' % ( pad_hex( value ) ), else: self.regs[idx] = value if self.debug.enabled( "rf" ): print ':: WR.RF[%s] = %s' % ( pad( "%d" % idx, 2 ), pad_hex( value ) ),
def __setitem__(self, index, value): if index == 0x65: # COREID register. Read only. Other Read/Write only return # registers need to be accessed by instructions. address, bitsize, _ = reg_memory_map[index] # Lower 20 bits of address. mask = (1 << bitsize) - 1 self.memory.write(self.coreid_mask | address, 4, value & mask, from_core=self.coreid, quiet=True) if (self.debug.enabled('rf') and self.logger and index < 64 and self.is_first_core): self.logger.log(' :: WR.RF[%s] = %s' % ((pad('%d' % index, 2), pad_hex(value, len=self.debug_nchars))))
def __getitem__( self, idx ): # special-case for idx = 15 which is the pc if self.debug.enabled( "rf" ): if idx == 15: rd_str = pad_hex( self.state.pc ) + "+ 8" else: rd_str = pad_hex( self.regs[idx] ) print ':: RD.RF[%s] = %s' % ( pad( "%d" % idx, 2 ), rd_str ), if idx == 15: return self.state.pc + 8 else: return self.regs[idx]
def __getitem__(self, idx): # special-case for idx = 15 which is the pc if self.debug.enabled("rf"): if idx == 15: rd_str = pad_hex(self.state.pc) + "+ 8" else: rd_str = pad_hex(self.regs[idx]) print ':: RD.RF[%s] = %s' % (pad("%d" % idx, 2), rd_str), if idx == 15: return self.state.pc + 8 else: return self.regs[idx]
def run(state, max_insts=0): s = state while s.status == 0: jitdriver.jit_merge_point( pc=s.fetch_pc(), max_insts=max_insts, state=s, ) # constant-fold pc and mem pc = hint(s.fetch_pc(), promote=True) old = pc mem = hint(s.mem, promote=True) if s.debug.enabled("insts"): print pad("%x" % pc, 6, " ", False), # the print statement in memcheck conflicts with @elidable in iread. # So we use normal read if memcheck is enabled which includes the # memory checks if s.debug.enabled("memcheck"): inst = mem.read(pc, 4) else: # we use trace elidable iread instead of just read inst = mem.iread(pc, 4) inst_str, exec_fun = decode(inst) if s.debug.enabled("insts"): print "%s %s %s" % ( pad_hex(inst), pad(inst_str, 8), pad("%d" % s.ncycles, 8), ), try: exec_fun(s, Instruction(inst)) except FatalError as error: # TODO: maybe we can add a command line arg to just give a warning # and not terminate execution print "Exception in execution, aborting!" print "Exception message: %s" % error.msg break s.ncycles += 1 # TODO: should this be done inside instruction definition? if s.stats_en: s.stat_ncycles += 1 if s.debug.enabled("insts"): print if s.debug.enabled("regdump"): s.rf.print_regs(per_row=4) print '%s%s%s%s' % ('N' if s.N else '-', 'Z' if s.Z else '-', 'C' if s.C else '-', 'V' if s.V else '-') # check if we have reached the end of the maximum instructions and # exit if necessary if max_insts != 0 and s.ncycles >= max_insts: print "Reached the max_insts (%d), exiting." % max_insts break if s.fetch_pc() < old: jitdriver.can_enter_jit( pc=s.fetch_pc(), max_insts=max_insts, state=s, ) print 'DONE! Status =', s.status print 'Instructions Executed =', s.ncycles
def run(self): self = hint(self, promote=True) s = self.state max_insts = self.max_insts jitdriver = self.jitdriver while s.running: jitdriver.jit_merge_point( pc=s.fetch_pc(), max_insts=max_insts, state=s, sim=self, ) # constant-fold pc and mem pc = hint(s.fetch_pc(), promote=True) old = pc mem = hint(s.mem, promote=True) if s.debug.enabled("insts"): print pad("%x" % pc, 8, " ", False), # the print statement in memcheck conflicts with @elidable in iread. # So we use normal read if memcheck is enabled which includes the # memory checks if s.debug.enabled("memcheck"): inst_bits = mem.read(pc, 4) else: # we use trace elidable iread instead of just read inst_bits = mem.iread(pc, 4) try: inst, exec_fun = self.decode(inst_bits) if s.debug.enabled("insts"): print "%s %s %s" % ( pad_hex(inst_bits), pad(inst.str, 12), pad("%d" % s.num_insts, 8), ), self.pre_execute() exec_fun(s, inst) except NotImplementedInstError: # re-decode instruction to get the instruction name inst, _ = self.decode(inst_bits) print "Instruction not implemented: %s (pc: 0x%s), aborting!" \ % ( inst.str, pad_hex( pc ) ) break except FatalError as error: print "Exception in execution (pc: 0x%s), aborting!" % pad_hex( pc) print "Exception message: %s" % error.msg break s.num_insts += 1 # TODO: should this be done inside instruction definition? if s.stats_en: s.stat_num_insts += 1 self.post_execute() if s.debug.enabled("insts"): print if s.debug.enabled("regdump"): s.rf.print_regs(per_row=4) # check if we have reached the end of the maximum instructions and # exit if necessary if max_insts != 0 and s.num_insts >= max_insts: print "Reached the max_insts (%d), exiting." % max_insts break if s.fetch_pc() < old: jitdriver.can_enter_jit( pc=s.fetch_pc(), max_insts=max_insts, state=s, sim=self, ) print 'DONE! Status =', s.status print 'Instructions Executed =', s.num_insts
def run(self): """Fetch, decode, execute, service interrupts loop. Override Sim.run to provide multicore and close the logger on exit. """ coreids = self.states.keys() core = coreids[0] # Key to self.states dictionary. state = self.states[core] # revelation.machine.State object. pc = state.fetch_pc() # Program counter. tick_counter = 0 # Number of instructions executed by all cores. old_pc = 0 self.start_time = time.time() while True: self.jitdriver.jit_merge_point(pc=pc, core=core, tick_counter=tick_counter, coreids=coreids, sim=self, state=state,) # Fetch next instruction. opcode = state.mem.iread(pc, 4, from_core=state.coreid) try: # Decode instruction. mnemonic, function = decode(opcode) instruction = Instruction(opcode, mnemonic) # --debug if (state.is_first_core and self.logger and state.debug.enabled('trace')): state.logger.log('%s %s %s %s' % (pad('%x' % pc, 8, ' ', False), pad_hex(opcode), pad(instruction.name, 12), pad('%d' % state.num_insts, 8))) # Check whether or not we are in a hardware loop, and set # registers after the next instruction, as appropriate. See # Section 7.9 of the Architecture Reference Rev. 14.03.11. if (state.GID and state.pc == state.rf[reg_map['LE']]): state.rf[reg_map['LC']] -= 1 state.is_in_hardware_loop = True # Execute next instruction. function(state, instruction) # --debug if (state.is_first_core and state.logger and state.debug.enabled('trace')): state.logger.log('\n') # Check hardware loop registers. if state.is_in_hardware_loop and state.rf[reg_map['LC']] > 0: state.pc = state.rf[reg_map['LS']] state.is_in_hardware_loop = False # Service interrupts. if (state.rf[reg_map['ILAT']] > 0 and not (state.GID or state.rf[reg_map['DEBUGSTATUS']] == 1)): interrupt_level = state.get_latched_interrupt() if interrupt_level > -1: # Interrupt to process. # If a pending interrupt is of a higher priority than # the latched interrupt, carry on with the pending # interrupt. pending_interrupt = state.get_pending_interrupt() if (pending_interrupt == -1 or (pending_interrupt > -1 and interrupt_level <= pending_interrupt)): state.rf[reg_map['IRET']] = state.pc state.rf[reg_map['ILAT']] &= ~(1 << interrupt_level) state.rf[reg_map['IPEND']] |= 1 << interrupt_level state.GID = True # Set global interrupt disabled bit. state.pc = IVT[interrupt_level] state.ACTIVE = 1 # Wake up IDLE cores. except (FatalError, NotImplementedInstError) as error: mnemonic, _ = decode(opcode) print ('Exception in execution of %s (pc: 0x%s), aborting!' % (mnemonic, pad_hex(pc))) print 'Exception message: %s' % error.msg return EXIT_GENERAL_ERROR, tick_counter # pragma: no cover # Update instruction counters. tick_counter += 1 state.num_insts += 1 # Halt if we have reached the maximum instruction count. if self.max_insts != 0 and state.num_insts >= self.max_insts: print 'Reached the max_insts (%d), exiting.' % self.max_insts break # Check whether state has halted. if not state.running: if len(coreids) == 1: # Last running core has halted. break old_core = core core = coreids[(coreids.index(core) + 1) % len(coreids)] state = self.states[core] coreids.remove(old_core) # Switch cores after every instruction. TODO: Honour switch interval. elif len(coreids) > 1 and tick_counter % self.switch_interval == 0: while True: core = coreids[(coreids.index(core) + 1) % len(coreids)] if self.states[core].ACTIVE == 1: break # Idle cores can be made active by interrupts. elif (self.states[core].ACTIVE == 0 and self.states[core].rf[reg_map['ILAT']] > 0): interrupt_level = self.states[core].get_latched_interrupt() self.states[core].rf[reg_map['IRET']] = self.states[core].pc self.states[core].rf[reg_map['ILAT']] &= ~(1 << interrupt_level) self.states[core].rf[reg_map['IPEND']] |= 1 << interrupt_level self.states[core].GID = True # Set global interrupt disabled bit. self.states[core].pc = IVT[interrupt_level] self.states[core].ACTIVE = 1 # Wake up IDLE cores. break state = self.states[core] # Move program counter to next instruction. old_pc = pc pc = state.fetch_pc() if pc < old_pc: self.jitdriver.can_enter_jit(pc=pc, core=core, tick_counter=tick_counter, coreids=coreids, sim=self, state=state,) return EXIT_SUCCESS, tick_counter
def print_regs(self, per_row=6): for c in xrange(0, self.num_regs, per_row): str = "" for r in xrange(c, min(self.num_regs, c + per_row)): str += "%s:%s " % (pad("%d" % r, 2), pad_hex(self.regs[r])) print str
def __getitem__(self, idx): if self.debug.enabled("rf"): print ':: RD.RF[%s] = %s' % (pad( "%d" % idx, 2), pad_hex(self.regs[idx], len=self.debug_nchars)), return self.regs[idx]
def run( self ): self = hint( self, promote=True ) s = self.state max_insts = self.max_insts jitdriver = self.jitdriver while s.running: jitdriver.jit_merge_point( pc = s.fetch_pc(), max_insts = max_insts, state = s, sim = self, ) # constant-fold pc and mem pc = hint( s.fetch_pc(), promote=True ) old = pc mem = hint( s.mem, promote=True ) if s.debug.enabled( "insts" ): print pad( "%x" % pc, 8, " ", False ), # the print statement in memcheck conflicts with @elidable in iread. # So we use normal read if memcheck is enabled which includes the # memory checks if s.debug.enabled( "memcheck" ): inst_bits = mem.read( pc, 4 ) else: # we use trace elidable iread instead of just read inst_bits = mem.iread( pc, 4 ) try: inst, exec_fun = self.decode( inst_bits ) if s.debug.enabled( "insts" ): print "%s %s %s" % ( pad_hex( inst_bits ), pad( inst.str, 12 ), pad( "%d" % s.num_insts, 8 ), ), self.pre_execute() exec_fun( s, inst ) except NotImplementedInstError: # re-decode instruction to get the instruction name inst, _ = self.decode( inst_bits ) print "Instruction not implemented: %s (pc: 0x%s), aborting!" \ % ( inst.str, pad_hex( pc ) ) break except FatalError as error: print "Exception in execution (pc: 0x%s), aborting!" % pad_hex( pc ) print "Exception message: %s" % error.msg break s.num_insts += 1 # TODO: should this be done inside instruction definition? if s.stats_en: s.stat_num_insts += 1 self.post_execute() if s.debug.enabled( "insts" ): print if s.debug.enabled( "regdump" ): s.rf.print_regs( per_row=4 ) # check if we have reached the end of the maximum instructions and # exit if necessary if max_insts != 0 and s.num_insts >= max_insts: print "Reached the max_insts (%d), exiting." % max_insts break if s.fetch_pc() < old: jitdriver.can_enter_jit( pc = s.fetch_pc(), max_insts = max_insts, state = s, sim = self, ) print 'DONE! Status =', s.status print 'Instructions Executed =', s.num_insts
def run(state, max_insts=0): s = state while s.running: jitdriver.jit_merge_point( pc=s.pc, max_insts=max_insts, state=s, ) # constant fold the pc pc = hint(s.pc, promote=True) old = pc # We constant fold the s.mem object. This is important because # otherwise the trace elidable iread doesn't work (assumes s.mem might # have changed) mem = hint(s.mem, promote=True) if s.debug.enabled("insts"): print pad("%x" % s.pc, 6, " ", False), # the print statement in memcheck conflicts with @elidable in iread. # So we use normal read if memcheck is enabled which includes the # memory checks if s.debug.enabled("memcheck"): inst = mem.read(pc, 4) else: # we use trace elidable iread instead of just read inst = mem.iread(pc, 4) inst_str, exec_fun = decode(inst) if s.debug.enabled("insts"): print "%s %s %s" % ( pad_hex(inst), pad(inst_str, 8), pad("%d" % s.ncycles, 8), ), exec_fun(s, Instruction(inst)) s.ncycles += 1 # TODO: should this be done inside instruction definition? if s.stats_en: s.stat_ncycles += 1 if s.debug.enabled("insts"): print if s.debug.enabled("regdump"): s.rf.print_regs() # check if we have reached the end of the maximum instructions and # exit if necessary if max_insts != 0 and s.ncycles >= max_insts: print "Reached the max_insts (%d), exiting." % max_insts break if s.pc < old: jitdriver.can_enter_jit( pc=s.pc, max_insts=max_insts, state=s, ) print 'DONE! Status =', s.status print 'Instructions Executed =', s.ncycles