def store(self, space, n0, w_obj): """Floats are stored in big-endian (PowerPC) order""" if n0 == 0: self.high = r_uint32(space.unwrap_uint(w_obj)) elif n0 == 1: self.low = r_uint32(space.unwrap_uint(w_obj)) else: raise error.PrimitiveFailedError
def program_words(b): s = int(len(b) / 4) a = [r_uint32(0)] * s for i in range(0, s): #xrange? a[i] = r_uint32( from_endian_big(ord(b[4 * i + 0]), ord(b[4 * i + 1]), ord(b[4 * i + 2]), ord(b[4 * i + 3]))) return a
def short_at0(self, space, index0): byte_index0 = index0 * 2 byte0 = ord(self.getchar(byte_index0)) byte1 = ord(self.getchar(byte_index0 + 1)) << 8 if byte1 & 0x8000 != 0: byte1 = intmask( r_uint(r_uint32(0xffff0000)) | r_uint(r_uint32(byte1))) return space.wrap_smallint_unsafe(byte1 | byte0)
def program_words(b): s = int(len(b)/4) a = [r_uint32(0)] * s for i in range(0, s): #xrange? a[i] = r_uint32(from_endian_big(ord(b[4*i+0]), ord(b[4*i+1]), ord(b[4*i+2]), ord(b[4*i+3]))) return a
def rt_hash(self): if self._hash is None: n = r_uint32(0) hash = r_uint32(1) for x in range(self._cnt): hash = r_uint32(31) * hash + UT.hash(UT.nth(wrap_int(x)))._int_value n += 1 x = RT.next.invoke1(x) self._hash = wrap_int(int(mix_col_hash(hash, n))) return self._hash
def fetch(self, space, n0): r = float_pack(self.getvalue(), 8) # C double if n0 == 0: return space.wrap_int(r_uint32(intmask(r >> 32))) else: # bounds-check for primitive access is done in the primitive assert n0 == 1 if constants.IS_64BIT: # mask the bits above 32 return space.wrap_int(r_uint32(intmask(r & 0xffffffff))) else: return space.wrap_int(r_uint32(intmask(r)))
def rt_hash(self): if self._hash is None: n = r_uint32(0) hash = r_uint32(1) x = RT.seq.invoke1(self) while x is not nil: hash = r_uint32(31) * hash + UT.hash(UT.first(x))._int_value n += 1 x = RT.next.invoke1(x) self._hash = wrap_int(int(mix_col_hash(hash, n))) return self._hash
def rt_hash(self): if self._hash is None: n = r_uint32(0) hash = r_uint32(1) for x in range(self._cnt): hash = r_uint32(31) * hash + UT.hash(UT.nth( wrap_int(x)))._int_value n += 1 x = RT.next.invoke1(x) self._hash = wrap_int(int(mix_col_hash(hash, n))) return self._hash
def write( self, start_addr, num_bytes, value ): assert 0 < num_bytes <= 4 word = start_addr >> 2 byte = start_addr & 0b11 if self.debug.enabled( "memcheck" ): self.bounds_check( start_addr, 'WR' ) if num_bytes == 4: # TODO: byte should only be 0 (only aligned) pass # no masking needed elif num_bytes == 2: # TODO: byte should only be 0, 1, 2, not 3 mask = ~(0xFFFF << (byte * 8)) & 0xFFFFFFFF value = ( widen( self.data[ word ] ) & mask ) \ | ( (value & 0xFFFF) << (byte * 8) ) elif num_bytes == 1: mask = ~(0xFF << (byte * 8)) & 0xFFFFFFFF value = ( widen( self.data[ word ] ) & mask ) \ | ( (value & 0xFF ) << (byte * 8) ) else: raise Exception('Invalid num_bytes: %d!' % num_bytes) if self.debug.enabled( "mem" ): print ':: WR.MEM[%s] = %s' % ( pad_hex( start_addr ), pad_hex( value ) ), self.data[ word ] = r_uint32( value )
def __init__( self, data=None, size=2**10 ): self.data = data if data else [ r_uint32(0) ] * (size >> 2) self.size = (len( self.data ) << 2) self.debug = Debug() # TODO: pass data_section to memory for bounds checking self.data_section = 0x00000000
def write(self, start_addr, num_bytes, value): assert 0 < num_bytes <= 4 start_addr = r_uint(start_addr) value = r_uint(value) word = start_addr >> 2 byte = start_addr & 0b11 if self.debug.enabled("memcheck") and not self.suppress_debug: self.bounds_check(start_addr, 'WR') if num_bytes == 4: # TODO: byte should only be 0 (only aligned) pass # no masking needed elif num_bytes == 2: # TODO: byte should only be 0, 1, 2, not 3 mask = ~(0xFFFF << (byte * 8)) & r_uint(0xFFFFFFFF) value = ( widen( self.data[ word ] ) & mask ) \ | ( (value & 0xFFFF) << (byte * 8) ) elif num_bytes == 1: mask = ~(0xFF << (byte * 8)) & r_uint(0xFFFFFFFF) value = ( widen( self.data[ word ] ) & mask ) \ | ( (value & 0xFF ) << (byte * 8) ) else: raise Exception('Invalid num_bytes: %d!' % num_bytes) if self.debug.enabled("mem") and not self.suppress_debug: print ':: WR.MEM[%s] = %s' % (pad_hex(start_addr), pad_hex(value)), self.data[word] = r_uint32(value)
def __init__(self, data=None, size=2**10): self.data = data if data else [r_uint32(0)] * (size >> 2) self.size = r_uint(len(self.data) << 2) self.debug = Debug() # TODO: pass data_section to memory for bounds checking self.data_section = 0x00000000
def test_sign_when_casting_uint_to_larger_int(): from rpython.rtyper.lltypesystem import rffi from rpython.rlib.rarithmetic import r_uint32, r_uint64 # value = 0xAAAABBBB assert cast(lltype.SignedLongLong, r_uint32(value)) == value if hasattr(rffi, '__INT128_T'): value = 0xAAAABBBBCCCCDDDD assert cast(rffi.__INT128_T, r_uint64(value)) == value
def bits2float(bits): # This is a bit convoluted, but this is much faster than ieee.pack # stuff. In addition to normal casting through uint2singlefloat, we have # additional casting because integer and float types that we can do # arithmetic operations on are standard Python sizes (native machine # size). Here's the typing going on below: # Python Int (64-bit) -> r_uint32 -> r_singlefloat -> Python Float (64-bit) flt = rffi.cast(lltype.Float, uint2singlefloat(r_uint32(bits))) return flt
def adler32(space, string, start=rzlib.ADLER32_DEFAULT_START): """ adler32(string[, start]) -- Compute an Adler-32 checksum of string. An optional starting value can be specified. The returned checksum is an integer. """ ustart = r_uint(r_uint32(start)) checksum = rzlib.adler32(string, ustart) return space.newint(checksum)
def htonl(space, x): """htonl(integer) -> integer Convert a 32-bit integer from host to network byte order. """ if x < r_longlong(0): raise oefmt(space.w_OverflowError, "can't convert negative number to unsigned long") if x > LONGLONG_UINT32_MAX: raise oefmt(space.w_OverflowError, "long int larger than 32 bits") return space.newint(rsocket.htonl(r_uint32(x)))
def adler32(space, string, start=rzlib.ADLER32_DEFAULT_START): """ adler32(string[, start]) -- Compute an Adler-32 checksum of string. An optional starting value can be specified. The returned checksum is an integer. """ ustart = r_uint(r_uint32(start)) checksum = rzlib.adler32(string, ustart) # See comments in crc32() for the following line checksum = unsigned_to_signed_32bit(checksum) return space.newint(checksum)
def crc32(space, string, start = rzlib.CRC32_DEFAULT_START): """ crc32(string[, start]) -- Compute a CRC-32 checksum of string. An optional starting value can be specified. The returned checksum is an integer. """ ustart = r_uint(r_uint32(start)) checksum = rzlib.crc32(string, ustart) # This is, perhaps, a little stupid. zlib returns the checksum unsigned. # CPython exposes it as a signed value, though. -exarkun # Note that in CPython < 2.6 on 64-bit platforms the result is # actually unsigned, but it was considered to be a bug so we stick to # the 2.6 behavior and always return a number in range(-2**31, 2**31). checksum = unsigned_to_signed_32bit(checksum) return space.newint(checksum)
def __init__(self, value): assert value == 0 self.high = r_uint32(0) self.low = r_uint32(0)
def setvalue(self, v): # This will only be called if we `become' a W_MutableFloat, should be rare r = float_pack(v, 8) # just shift and mask self.high = r_uint32(r >> 32) self.low = r_uint32(r)
def _siphash24(addr_in, size, SZ=1): """Takes an address pointer and a size. Returns the hash as a r_uint64, which can then be casted to the expected type.""" if BIG_ENDIAN: index = SZ - 1 else: index = 0 if size < seed.bound_prebuilt_size: if size <= 0: return seed.hash_empty else: t = rarithmetic.intmask(llop.raw_load(rffi.UCHAR, addr_in, index)) return seed.hash_single[t] k0 = seed.k0l k1 = seed.k1l b = r_uint64(size) << 56 v0 = k0 ^ magic0 v1 = k1 ^ magic1 v2 = k0 ^ magic2 v3 = k1 ^ magic3 direct = (SZ == 1) and (misaligned_is_fine or (rffi.cast(lltype.Signed, addr_in) & 7) == 0) if direct: assert SZ == 1 while size >= 8: mi = llop.raw_load(rffi.ULONGLONG, addr_in, index) mi = _le64toh(mi) size -= 8 index += 8 v3 ^= mi v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0 ^= mi else: while size >= 8: mi = ( r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index)) | r_uint64( llop.raw_load(rffi.UCHAR, addr_in, index + 1 * SZ)) << 8 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 2 * SZ)) << 16 | r_uint64( llop.raw_load(rffi.UCHAR, addr_in, index + 3 * SZ)) << 24 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 4 * SZ)) << 32 | r_uint64( llop.raw_load(rffi.UCHAR, addr_in, index + 5 * SZ)) << 40 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 6 * SZ)) << 48 | r_uint64( llop.raw_load(rffi.UCHAR, addr_in, index + 7 * SZ)) << 56) size -= 8 index += 8 * SZ v3 ^= mi v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0 ^= mi t = r_uint64(0) if size == 7: t = r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 6 * SZ)) << 48 size = 6 if size == 6: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 5 * SZ)) << 40 size = 5 if size == 5: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 4 * SZ)) << 32 size = 4 if size == 4: if direct: v = _le32toh(r_uint32(llop.raw_load(rffi.UINT, addr_in, index))) t |= r_uint64(v) size = 0 else: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 3 * SZ)) << 24 size = 3 if size == 3: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 2 * SZ)) << 16 size = 2 if size == 2: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 1 * SZ)) << 8 size = 1 if size == 1: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index)) size = 0 assert size == 0 b |= t v3 ^= b v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0 ^= b v2 ^= 0xff v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) return (v0 ^ v1) ^ (v2 ^ v3)
def _siphash24_with_key(addr_in, size, k0, k1, SZ=1): if BIG_ENDIAN: index = SZ - 1 else: index = 0 b = r_uint64(size) << 56 v0 = k0 ^ magic0 v1 = k1 ^ magic1 v2 = k0 ^ magic2 v3 = k1 ^ magic3 direct = (SZ == 1) and (misaligned_is_fine or (rffi.cast(lltype.Signed, addr_in) & 7) == 0) if direct: assert SZ == 1 while size >= 8: mi = llop.raw_load(rffi.ULONGLONG, addr_in, index) mi = _le64toh(mi) size -= 8 index += 8 v3 ^= mi v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0 ^= mi else: while size >= 8: mi = ( r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index)) | r_uint64( llop.raw_load(rffi.UCHAR, addr_in, index + 1 * SZ)) << 8 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 2 * SZ)) << 16 | r_uint64( llop.raw_load(rffi.UCHAR, addr_in, index + 3 * SZ)) << 24 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 4 * SZ)) << 32 | r_uint64( llop.raw_load(rffi.UCHAR, addr_in, index + 5 * SZ)) << 40 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 6 * SZ)) << 48 | r_uint64( llop.raw_load(rffi.UCHAR, addr_in, index + 7 * SZ)) << 56) size -= 8 index += 8 * SZ v3 ^= mi v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0 ^= mi t = r_uint64(0) if size == 7: t = r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 6 * SZ)) << 48 size = 6 if size == 6: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 5 * SZ)) << 40 size = 5 if size == 5: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 4 * SZ)) << 32 size = 4 if size == 4: if direct: v = _le32toh(r_uint32(llop.raw_load(rffi.UINT, addr_in, index))) t |= r_uint64(v) size = 0 else: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 3 * SZ)) << 24 size = 3 if size == 3: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 2 * SZ)) << 16 size = 2 if size == 2: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 1 * SZ)) << 8 size = 1 if size == 1: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index)) size = 0 assert size == 0 b |= t v3 ^= b v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0 ^= b v2 ^= 0xff v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) return (v0 ^ v1) ^ (v2 ^ v3)
def rt_hash(self): return wrap_int(int(hash_int(r_uint32(hash(self._str_value)))))
def mainloop(program): pc = 0 reg = [r_uint32(0)] * 8 # registers arr = [program] fresh = 1 free = [] while True: p = intmask(arr[0][pc]) op = p >> (32-4) a = (p & 0b111000000) >> 6 b = (p & 0b000111000) >> 3 c = (p & 0b000000111) >> 0 #print "[", op, ",", a, ",", b, ",", c, "]" if op == 0: # Conditional Move if(intmask(reg[c]) != 0): reg[a] = reg[b] pc += 1 elif op == 1: # Array Index reg[a] = arr[reg[b]][reg[c]] pc += 1 elif op == 2: # Array Amendment arr[reg[a]][reg[b]] = reg[c] pc += 1 elif op == 3: # Addition reg[a] = r_uint32(intmask(reg[b]) + intmask(reg[c])) pc += 1 elif op == 4: # Multiplication reg[a] = r_uint32(intmask(reg[b]) * intmask(reg[c])) pc += 1 elif op == 5: # Division reg[a] = r_uint32(intmask(reg[b]) / intmask(reg[c])) pc += 1 elif op == 6: # Nand reg[a] = r_uint32(~(intmask(reg[b]) & intmask(reg[c]))) pc += 1 elif op == 7: # Halt break elif op == 8: # Allocation #if len(free) == 0: arr.append([r_uint32(0)] * reg[c]) reg[b] = r_uint32(len(arr)-1) #else: # reg[b] = free.pop() # print "reusing", reg[b] # arr[reg[b]] = [r_uint32(0)] * reg[c] pc += 1 elif op == 9: # Abandonment arr[reg[c]] = None free.append(reg[c]) pc += 1 elif op == 10: # Output os.write(1, chr(reg[c])) pc += 1 elif op == 11: #print "11" pc += 1 elif op == 12: # Load Program if intmask(reg[b]) != 0: arr[0] = list(arr[reg[b]]) pc = intmask(reg[c]) elif op == 13: # Orthography a = p >> (32-4-3) & 0b111 value = p & 0b00000001111111111111111111111111 reg[a] = value pc += 1 else: assert False
def rt_hash(self): h = hash_combine(r_uint32(UT.hash(self._name)._int_value), r_uint32(UT.hash(self._ns)._int_value)) return wrap_int(int(h))
def _siphash24(addr_in, size): """Takes an address pointer and a size. Returns the hash as a r_uint64, which can then be casted to the expected type.""" k0 = seed.k0l k1 = seed.k1l b = r_uint64(size) << 56 v0 = k0 ^ magic0 v1 = k1 ^ magic1 v2 = k0 ^ magic2 v3 = k1 ^ magic3 direct = (misaligned_is_fine or (rffi.cast(lltype.Signed, addr_in) & 7) == 0) index = 0 if direct: while size >= 8: mi = llop.raw_load(rffi.ULONGLONG, addr_in, index) mi = _le64toh(mi) size -= 8 index += 8 v3 ^= mi v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0 ^= mi else: while size >= 8: mi = ( r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index)) | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 1)) << 8 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 2)) << 16 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 3)) << 24 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 4)) << 32 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 5)) << 40 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 6)) << 48 | r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 7)) << 56) size -= 8 index += 8 v3 ^= mi v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0 ^= mi t = r_uint64(0) if size == 7: t = r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 6)) << 48 size = 6 if size == 6: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 5)) << 40 size = 5 if size == 5: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 4)) << 32 size = 4 if size == 4: if direct: v = _le32toh(r_uint32(llop.raw_load(rffi.UINT, addr_in, index))) t |= r_uint64(v) size = 0 else: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 3)) << 24 size = 3 if size == 3: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 2)) << 16 size = 2 if size == 2: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index + 1)) << 8 size = 1 if size == 1: t |= r_uint64(llop.raw_load(rffi.UCHAR, addr_in, index)) size = 0 assert size == 0 b |= t v3 ^= b v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0 ^= b v2 ^= 0xff v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) v0, v1, v2, v3 = _double_round(v0, v1, v2, v3) return (v0 ^ v1) ^ (v2 ^ v3)
def mainloop(program): pc = 0 reg = [r_uint32(0)] * 8 # registers arr = [program] fresh = 1 free = [] while True: jitdriver.jit_merge_point(pc=pc, reg=reg, arr=arr, fresh=fresh, free=free) p = intmask(arr[0][pc]) op = p >> (32 - 4) a = (p & 0b111000000) >> 6 b = (p & 0b000111000) >> 3 c = (p & 0b000000111) >> 0 #print "[", op, ",", a, ",", b, ",", c, "]" if op == 0: # Conditional Move if (intmask(reg[c]) != 0): reg[a] = reg[b] pc += 1 elif op == 1: # Array Index reg[a] = arr[reg[b]][reg[c]] pc += 1 elif op == 2: # Array Amendment arr[reg[a]][reg[b]] = reg[c] pc += 1 elif op == 3: # Addition reg[a] = r_uint32(intmask(reg[b]) + intmask(reg[c])) pc += 1 elif op == 4: # Multiplication reg[a] = r_uint32(intmask(reg[b]) * intmask(reg[c])) pc += 1 elif op == 5: # Division reg[a] = r_uint32(intmask(reg[b]) / intmask(reg[c])) pc += 1 elif op == 6: # Nand reg[a] = r_uint32(~(intmask(reg[b]) & intmask(reg[c]))) pc += 1 elif op == 7: # Halt break elif op == 8: # Allocation #if len(free) == 0: arr.append([r_uint32(0)] * reg[c]) reg[b] = r_uint32(len(arr) - 1) #else: # reg[b] = free.pop() # print "reusing", reg[b] # arr[reg[b]] = [r_uint32(0)] * reg[c] pc += 1 elif op == 9: # Abandonment arr[reg[c]] = None free.append(reg[c]) pc += 1 elif op == 10: # Output os.write(1, chr(reg[c])) pc += 1 elif op == 11: #print "11" pc += 1 elif op == 12: # Load Program if intmask(reg[b]) != 0: arr[0] = list(arr[reg[b]]) pc = intmask(reg[c]) elif op == 13: # Orthography a = p >> (32 - 4 - 3) & 0b111 value = p & 0b00000001111111111111111111111111 reg[a] = value pc += 1 else: assert False