// Copyright 2020 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 abi

import (

// RegArgs is a struct that has space for each argument
// and return value register on the current architecture.
// Assembly code knows the layout of the first two fields
// of RegArgs.
// RegArgs also contains additional space to hold pointers
// when it may not be safe to keep them only in the integer
// register space otherwise.
type RegArgs struct {
	// Values in these slots should be precisely the bit-by-bit
	// representation of how they would appear in a register.
	// This means that on big endian arches, integer values should
	// be in the top bits of the slot. Floats are usually just
	// directly represented, but some architectures treat narrow
	// width floating point values specially (e.g. they're promoted
	// first, or they need to be NaN-boxed).
	Ints   [IntArgRegs]uintptr  // untyped integer registers
	Floats [FloatArgRegs]uint64 // untyped float registers

	// Fields above this point are known to assembly.

	// Ptrs is a space that duplicates Ints but with pointer type,
	// used to make pointers passed or returned  in registers
	// visible to the GC by making the type unsafe.Pointer.
	Ptrs [IntArgRegs]unsafe.Pointer

	// ReturnIsPtr is a bitmap that indicates which registers
	// contain or will contain pointers on the return path from
	// a reflectcall. The i'th bit indicates whether the i'th
	// register contains or will contain a valid Go pointer.
	ReturnIsPtr IntArgRegBitmap

func ( *RegArgs) () {
	for ,  := range .Ints {
		print(" ", )
	for ,  := range .Floats {
		print(" ", )
	for ,  := range .Ptrs {
		print(" ", )

// IntRegArgAddr returns a pointer inside of r.Ints[reg] that is appropriately
// offset for an argument of size argSize.
// argSize must be non-zero, fit in a register, and a power-of-two.
// This method is a helper for dealing with the endianness of different CPU
// architectures, since sub-word-sized arguments in big endian architectures
// need to be "aligned" to the upper edge of the register to be interpreted
// by the CPU correctly.
func ( *RegArgs) ( int,  uintptr) unsafe.Pointer {
	if  > goarch.PtrSize ||  == 0 || &(-1) != 0 {
		panic("invalid argSize")
	 := uintptr(0)
	if goarch.BigEndian {
		 = goarch.PtrSize - 
	return unsafe.Pointer(uintptr(unsafe.Pointer(&.Ints[])) + )

// IntArgRegBitmap is a bitmap large enough to hold one bit per
// integer argument/return register.
type IntArgRegBitmap [(IntArgRegs + 7) / 8]uint8

// Set sets the i'th bit of the bitmap to 1.
func ( *IntArgRegBitmap) ( int) {
	[/8] |= uint8(1) << ( % 8)

// Get returns whether the i'th bit of the bitmap is set.
// nosplit because it's called in extremely sensitive contexts, like
// on the reflectcall return path.
func ( *IntArgRegBitmap) ( int) bool {
	return [/8]&(uint8(1)<<(%8)) != 0

// FuncPC* intrinsics.
// CAREFUL: In programs with plugins, FuncPC* can return different values
// for the same function (because there are actually multiple copies of
// the same function in the address space). To be safe, don't use the
// results of this function in any == expression. It is only safe to
// use the result as an address at which to start executing code.

// FuncPCABI0 returns the entry PC of the function f, which must be a
// direct reference of a function defined as ABI0. Otherwise it is a
// compile-time error.
// Implemented as a compile intrinsic.
func ( any) uintptr

// FuncPCABIInternal returns the entry PC of the function f. If f is a
// direct reference of a function, it must be defined as ABIInternal.
// Otherwise it is a compile-time error. If f is not a direct reference
// of a defined function, it assumes that f is a func value. Otherwise
// the behavior is undefined.
// Implemented as a compile intrinsic.
func ( any) uintptr