// Copyright 2014 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package runtime import ( "unsafe" "github.com/goplus/llgo/c/sync/atomic" "github.com/goplus/llgo/c/time" "github.com/goplus/llgo/internal/runtime/math" ) //go:linkname fastrand C.rand func fastrand() uint32 //go:linkname srand C.srand func srand(uint32) func fastrand64() uint64 { n := uint64(fastrand()) n += 0xa0761d6478bd642f hi, lo := math.Mul64(n, n^0xe7037ed1a0b428db) return hi ^ lo } func init() { srand(uint32(time.Time(nil))) hashkey[0] = uintptr(fastrand()) | 1 hashkey[1] = uintptr(fastrand()) | 1 hashkey[2] = uintptr(fastrand()) | 1 hashkey[3] = uintptr(fastrand()) | 1 } /* TODO(xsw): func fastrand() uint32 { mp := getg().m // Implement wyrand: https://github.com/wangyi-fudan/wyhash // Only the platform that math.Mul64 can be lowered // by the compiler should be in this list. if goarch.IsAmd64|goarch.IsArm64|goarch.IsPpc64| goarch.IsPpc64le|goarch.IsMips64|goarch.IsMips64le| goarch.IsS390x|goarch.IsRiscv64|goarch.IsLoong64 == 1 { mp.fastrand += 0xa0761d6478bd642f hi, lo := math.Mul64(mp.fastrand, mp.fastrand^0xe7037ed1a0b428db) return uint32(hi ^ lo) } // Implement xorshift64+: 2 32-bit xorshift sequences added together. // Shift triplet [17,7,16] was calculated as indicated in Marsaglia's // Xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf // This generator passes the SmallCrush suite, part of TestU01 framework: // http://simul.iro.umontreal.ca/testu01/tu01.html t := (*[2]uint32)(unsafe.Pointer(&mp.fastrand)) s1, s0 := t[0], t[1] s1 ^= s1 << 17 s1 = s1 ^ s0 ^ s1>>7 ^ s0>>16 t[0], t[1] = s0, s1 return s0 + s1 } */ //go:nosplit func add(p unsafe.Pointer, x uintptr) unsafe.Pointer { return unsafe.Pointer(uintptr(p) + x) } // implementation of new builtin // compiler (both frontend and SSA backend) knows the signature // of this function. func newobject(typ *_type) unsafe.Pointer { return AllocZ(typ.Size_) } // TODO func roundupsize(size uintptr) uintptr { // if size < _MaxSmallSize { // if size <= smallSizeMax-8 { // return uintptr(class_to_size[size_to_class8[divRoundUp(size, smallSizeDiv)]]) // } else { // return uintptr(class_to_size[size_to_class128[divRoundUp(size-smallSizeMax, largeSizeDiv)]]) // } // } // if size+_PageSize < size { // return size // } // return alignUp(size, _PageSize) return size } // newarray allocates an array of n elements of type typ. func newarray(typ *_type, n int) unsafe.Pointer { if n == 1 { return AllocZ(typ.Size_) } mem, overflow := math.MulUintptr(typ.Size_, uintptr(n)) if overflow || mem > maxAlloc || n < 0 { panic(plainError("runtime: allocation size out of range")) } return AllocZ(mem) } const ( // _64bit = 1 on 64-bit systems, 0 on 32-bit systems _64bit = 1 << (^uintptr(0) >> 63) / 2 heapAddrBits = (_64bit)*48 + (1-_64bit)*(32) maxAlloc = (1 << heapAddrBits) - (1-_64bit)*1 ) func memclrHasPointers(ptr unsafe.Pointer, n uintptr) { // bulkBarrierPreWrite(uintptr(ptr), 0, n) // memclrNoHeapPointers(ptr, n) } func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr) { } func fatal(s string) { print("fatal error: ", s, "\n") } func throw(s string) { print("fatal error: ", s, "\n") } func atomicOr8(ptr *uint8, v uint8) uint8 { return (uint8)(atomic.Or((*uint)(unsafe.Pointer(ptr)), uint(v))) } func noescape(p unsafe.Pointer) unsafe.Pointer { x := uintptr(p) return unsafe.Pointer(x ^ 0) }