"Fossies" - the Fresh Open Source Software Archive

Member "go/src/internal/abi/abi.go" (26 Apr 2023, 4231 Bytes) of package /linux/misc/go1.20.4.src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // Copyright 2020 The Go Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style
    3 // license that can be found in the LICENSE file.
    4 
    5 package abi
    6 
    7 import (
    8     "internal/goarch"
    9     "unsafe"
   10 )
   11 
   12 // RegArgs is a struct that has space for each argument
   13 // and return value register on the current architecture.
   14 //
   15 // Assembly code knows the layout of the first two fields
   16 // of RegArgs.
   17 //
   18 // RegArgs also contains additional space to hold pointers
   19 // when it may not be safe to keep them only in the integer
   20 // register space otherwise.
   21 type RegArgs struct {
   22     // Values in these slots should be precisely the bit-by-bit
   23     // representation of how they would appear in a register.
   24     //
   25     // This means that on big endian arches, integer values should
   26     // be in the top bits of the slot. Floats are usually just
   27     // directly represented, but some architectures treat narrow
   28     // width floating point values specially (e.g. they're promoted
   29     // first, or they need to be NaN-boxed).
   30     Ints   [IntArgRegs]uintptr  // untyped integer registers
   31     Floats [FloatArgRegs]uint64 // untyped float registers
   32 
   33     // Fields above this point are known to assembly.
   34 
   35     // Ptrs is a space that duplicates Ints but with pointer type,
   36     // used to make pointers passed or returned  in registers
   37     // visible to the GC by making the type unsafe.Pointer.
   38     Ptrs [IntArgRegs]unsafe.Pointer
   39 
   40     // ReturnIsPtr is a bitmap that indicates which registers
   41     // contain or will contain pointers on the return path from
   42     // a reflectcall. The i'th bit indicates whether the i'th
   43     // register contains or will contain a valid Go pointer.
   44     ReturnIsPtr IntArgRegBitmap
   45 }
   46 
   47 func (r *RegArgs) Dump() {
   48     print("Ints:")
   49     for _, x := range r.Ints {
   50         print(" ", x)
   51     }
   52     println()
   53     print("Floats:")
   54     for _, x := range r.Floats {
   55         print(" ", x)
   56     }
   57     println()
   58     print("Ptrs:")
   59     for _, x := range r.Ptrs {
   60         print(" ", x)
   61     }
   62     println()
   63 }
   64 
   65 // IntRegArgAddr returns a pointer inside of r.Ints[reg] that is appropriately
   66 // offset for an argument of size argSize.
   67 //
   68 // argSize must be non-zero, fit in a register, and a power-of-two.
   69 //
   70 // This method is a helper for dealing with the endianness of different CPU
   71 // architectures, since sub-word-sized arguments in big endian architectures
   72 // need to be "aligned" to the upper edge of the register to be interpreted
   73 // by the CPU correctly.
   74 func (r *RegArgs) IntRegArgAddr(reg int, argSize uintptr) unsafe.Pointer {
   75     if argSize > goarch.PtrSize || argSize == 0 || argSize&(argSize-1) != 0 {
   76         panic("invalid argSize")
   77     }
   78     offset := uintptr(0)
   79     if goarch.BigEndian {
   80         offset = goarch.PtrSize - argSize
   81     }
   82     return unsafe.Pointer(uintptr(unsafe.Pointer(&r.Ints[reg])) + offset)
   83 }
   84 
   85 // IntArgRegBitmap is a bitmap large enough to hold one bit per
   86 // integer argument/return register.
   87 type IntArgRegBitmap [(IntArgRegs + 7) / 8]uint8
   88 
   89 // Set sets the i'th bit of the bitmap to 1.
   90 func (b *IntArgRegBitmap) Set(i int) {
   91     b[i/8] |= uint8(1) << (i % 8)
   92 }
   93 
   94 // Get returns whether the i'th bit of the bitmap is set.
   95 //
   96 // nosplit because it's called in extremely sensitive contexts, like
   97 // on the reflectcall return path.
   98 //
   99 //go:nosplit
  100 func (b *IntArgRegBitmap) Get(i int) bool {
  101     return b[i/8]&(uint8(1)<<(i%8)) != 0
  102 }
  103 
  104 // FuncPC* intrinsics.
  105 //
  106 // CAREFUL: In programs with plugins, FuncPC* can return different values
  107 // for the same function (because there are actually multiple copies of
  108 // the same function in the address space). To be safe, don't use the
  109 // results of this function in any == expression. It is only safe to
  110 // use the result as an address at which to start executing code.
  111 
  112 // FuncPCABI0 returns the entry PC of the function f, which must be a
  113 // direct reference of a function defined as ABI0. Otherwise it is a
  114 // compile-time error.
  115 //
  116 // Implemented as a compile intrinsic.
  117 func FuncPCABI0(f any) uintptr
  118 
  119 // FuncPCABIInternal returns the entry PC of the function f. If f is a
  120 // direct reference of a function, it must be defined as ABIInternal.
  121 // Otherwise it is a compile-time error. If f is not a direct reference
  122 // of a defined function, it assumes that f is a func value. Otherwise
  123 // the behavior is undefined.
  124 //
  125 // Implemented as a compile intrinsic.
  126 func FuncPCABIInternal(f any) uintptr