def execute_bl(s, inst): if condition_passed(s, inst.cond()): s.rf[LR] = trim_32(s.fetch_pc() + 4) offset = signed(sign_extend_30(inst.imm_24()) << 2) s.rf[PC] = trim_32(s.rf[PC] + offset) return s.rf[PC] = s.fetch_pc() + 4
def syscall_open(s): filename_ptr = s.rf[a0] flags = s.rf[a1] mode = s.rf[a2] # convert flags from solaris to linux (necessary?) open_flags = 0 for newlib, linux in flag_table: if flags & newlib: open_flags |= linux # get the filename filename = get_str(s, filename_ptr) try: # open vs. os.open(): http://stackoverflow.com/a/15039662 fd = os.open(filename, open_flags, mode) errno = 0 except OSError as e: print "OSError in syscall_open: errno=%d" % e.errno fd = -1 errno = e.errno if fd > 0: file_descriptors[fd] = trim_32(fd) s.rf[v0] = trim_32(fd)
def syscall_write(s): file_ptr = s.rf[a0] data_ptr = s.rf[a1] nbytes = s.rf[a2] # INST NUMBER 914 # INST NUMBER 914 if file_ptr not in file_descriptors: s.rf[v0] = -1 # TODO: return a bad file descriptor error (9)? return fd = file_descriptors[file_ptr] data = get_str(s, data_ptr, nbytes) try: nbytes_written = os.write(fd, data) errno = 0 # https://docs.python.org/2/library/os.html#os.fsync #os.fsync( fd ) # causes 'Invalid argument' error for some reason... except OSError as e: print "OSError in syscall_write: errno=%d" % e.errno nbytes_written = -1 errno = e.errno s.rf[v0] = trim_32(nbytes_written)
def syscall_lseek(s): fd = s.rf[a0] pos = s.rf[a1] how = s.rf[a2] if s.debug.enabled("syscalls"): print "syscall_lseek( fd=%x, pos=%x, how=%x )" % (fd, pos, how), if check_fd(s, fd): return errno = 0 try: # NOTE: rpython gives some weird errors in rtyping stage if we don't # explicitly cast the return value of os.lseek to int new_pos = int(os.lseek(fd, pos, how)) except OSError as e: if s.debug.enabled("syscalls"): print "OSError in syscall_lseek. errno=%d" % e.errno errno = e.errno new_pos = -1 return_from_syscall(s, trim_32(new_pos), errno)
def execute_bic(s, inst): if condition_passed(s, inst.cond()): a, (b, cout) = s.rf[inst.rn()], shifter_operand(s, inst) result = a & trim_32(~b) s.rf[inst.rd()] = trim_32(result) if inst.S(): if inst.rd() == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = cout if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def syscall_brk(s): new_brk = s.rf[a0] if new_brk != 0: s.breakpoint = new_brk s.rf[v0] = trim_32(s.breakpoint)
def execute_mvn(s, inst): if condition_passed(s, inst.cond()): a, cout = shifter_operand(s, inst) result = trim_32(~a) s.rf[inst.rd()] = result if inst.S(): if inst.rd() == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = cout s.V = s.V if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_sbc(s, inst): if condition_passed(s, inst.cond()): a, (b, _) = s.rf[inst.rn()], shifter_operand(s, inst) result = a - b - (not s.C) s.rf[inst.rd()] = trim_32(result) if inst.S(): if inst.rd() == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = not borrow_from(result) s.V = overflow_from_sub(a, b, result) if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_mov(s, inst): if condition_passed(s, inst.cond()): if inst.rd() == 15 and inst.S(): # if not CurrentModeHasSPSR(): CPSR = SPSR # else: UNPREDICTABLE raise FatalError('UNPREDICTABLE in user and system mode!') result, cout = shifter_operand(s, inst) s.rf[inst.rd()] = trim_32(result) if inst.S(): s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = cout s.V = s.V if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_blx2(s, inst): if condition_passed(s, inst.cond()): s.rf[LR] = trim_32(s.fetch_pc() + 4) s.T = s.rf[inst.rm()] & 0x00000001 s.rf[PC] = s.rf[inst.rm()] & 0xFFFFFFFE if s.T: raise FatalError("Entering THUMB mode! Unsupported!") # no pc + 4 on success else: s.rf[PC] = s.fetch_pc() + 4
def execute_umull(s, inst): if condition_passed(s, inst.cond()): if inst.rd() == 15: raise FatalError('UNPREDICTABLE') if inst.rm() == 15: raise FatalError('UNPREDICTABLE') if inst.rs() == 15: raise FatalError('UNPREDICTABLE') if inst.rn() == 15: raise FatalError('UNPREDICTABLE') RdHi, RdLo = inst.rn(), inst.rd() Rm, Rs = s.rf[inst.rm()], s.rf[inst.rs()] result = Rm * Rs if RdHi == RdLo: raise FatalError('UNPREDICTABLE') s.rf[RdHi] = trim_32(result >> 32) s.rf[RdLo] = trim_32(result) if inst.S(): s.N = (result >> 63) & 1 s.Z = (s.rf[RdHi] == s.rf[RdLo] == 0) s.rf[PC] = s.fetch_pc() + 4
def execute_tst(s, inst): if condition_passed(s, inst.cond()): a, (b, cout) = s.rf[inst.rn()], shifter_operand(s, inst) result = trim_32(a & b) if inst.S(): s.N = (result >> 31) & 1 s.Z = result == 0 s.C = cout if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_cmp(s, inst): if condition_passed(s, inst.cond()): a, (b, _) = s.rf[inst.rn()], shifter_operand(s, inst) result = a - b s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = not borrow_from(result) s.V = overflow_from_sub(a, b, result) if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_mul(s, inst): if condition_passed(s, inst.cond()): Rm, Rs = s.rf[inst.rm()], s.rf[inst.rs()] result = trim_32(Rm * Rs) s.rf[inst.rn()] = result if inst.S(): if inst.rn() == 15: raise FatalError('UNPREDICTABLE') if inst.rm() == 15: raise FatalError('UNPREDICTABLE') if inst.rs() == 15: raise FatalError('UNPREDICTABLE') s.N = (result >> 31) & 1 s.Z = result == 0 if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def syscall_unlink(s): path_ptr = s.rf[a0] #if s.debug.enabled( "syscalls" ): # print "syscall_unlink( path=%x )" % path_ptr, path = get_str(s, path_ptr) errno = 0 try: os.unlink(path) except OSError as e: if s.debug.enabled("syscalls"): print "OSError in syscall_unlink. errno=%d" % e.errno errno = e.errno s.rf[v0] = 0 if errno == 0 else trim_32(-1)
def syscall_close(s): file_ptr = s.rf[a0] if file_ptr not in file_descriptors: s.rf[v0] = -1 # TODO: return a bad file descriptor error (9)? return # TODO: hacky don't close the file for 0, 1, 2. # gem5 does this, but is there a better way? if file_ptr <= 2: s.rf[v0] = 0 return try: os.close(file_descriptors[file_ptr]) del file_descriptors[file_ptr] errno = 0 except OSError as e: print "OSError in syscall_close: errno=%d" % e.errno errno = e.errno s.rf[v0] = 0 if errno == 0 else trim_32(-1)
def syscall_link(s): src_ptr = s.rf[a0] link_ptr = s.rf[a1] #if s.debug.enabled( "syscalls" ): # print "syscall_link( src=%x, link=%x )" % \ # ( src_ptr, link_ptr ), src = get_str(s, src_ptr) link_name = get_str(s, link_ptr) errno = 0 try: os.link(src, link_name) except OSError as e: if s.debug.enabled("syscalls"): print "OSError in syscall_link. errno=%d" % e.errno errno = e.errno s.rf[v0] = 0 if errno == 0 else trim_32(-1)
def syscall_read(s): file_ptr = s.rf[a0] data_ptr = s.rf[a1] nbytes = s.rf[a2] if file_ptr not in file_descriptors: s.rf[v0] = -1 # TODO: return a bad file descriptor error (9)? return fd = file_descriptors[file_ptr] try: data = os.read(fd, nbytes) nbytes_read = len(data) errno = 0 put_str(s, data_ptr, data) except OSError as e: print "OSError in syscall_read: errno=%d" % e.errno nbytes_read = -1 errno = e.errno s.rf[v0] = trim_32(nbytes_read)
def syscall_ioctl(s): fd = s.rf[a0] req = s.rf[a1] result = -errno.ENOTTY if fd >= 0 else -errno.EBADF s.rf[v0] = trim_32(result)
def return_from_syscall(s, retval, errno): s.rf[v0] = trim_32(retval)