// Copyright 2022 The Gc 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 gc // import "modernc.org/gc/v2"

import (
	"encoding/binary"
	"fmt"
)

var (
	byteOrders = map[string]binary.ByteOrder{
		"386":      binary.LittleEndian,
		"amd64":    binary.LittleEndian,
		"arm":      binary.LittleEndian,
		"arm64":    binary.LittleEndian,
		"loong64":  binary.LittleEndian,
		"ppc64le":  binary.LittleEndian,
		"mips64le": binary.LittleEndian,
		"riscv64":  binary.LittleEndian,
		"s390x":    binary.BigEndian,
	}

	abiTypes = map[[2]string]map[Kind]AbiType{
		// go1.19.1
		{"freebsd", "386"}: {
			Bool:          {1, 1, 1},
			Chan:          {4, 4, 4},
			Complex128:    {16, 4, 4},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 4, 4},
			Function:      {4, 4, 4},
			Int:           {4, 4, 4},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 4, 4},
			Int8:          {1, 1, 1},
			Interface:     {8, 4, 4},
			Map:           {4, 4, 4},
			Pointer:       {4, 4, 4},
			Slice:         {12, 4, 4},
			String:        {8, 4, 4},
			Uint:          {4, 4, 4},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 4, 4},
			Uint8:         {1, 1, 1},
			Uintptr:       {4, 4, 4},
			UnsafePointer: {4, 4, 4},
		},
		// go1.19.1
		{"freebsd", "amd64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.18.5
		{"freebsd", "arm"}: {
			Bool:          {1, 1, 1},
			Chan:          {4, 4, 4},
			Complex128:    {16, 4, 4},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 4, 4},
			Function:      {4, 4, 4},
			Int:           {4, 4, 4},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 4, 4},
			Int8:          {1, 1, 1},
			Interface:     {8, 4, 4},
			Map:           {4, 4, 4},
			Pointer:       {4, 4, 4},
			Slice:         {12, 4, 4},
			String:        {8, 4, 4},
			Uint:          {4, 4, 4},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 4, 4},
			Uint8:         {1, 1, 1},
			Uintptr:       {4, 4, 4},
			UnsafePointer: {4, 4, 4},
		},
		// go1.19
		{"freebsd", "arm64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.19.1
		{"darwin", "amd64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.19.1
		{"darwin", "arm64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.19.1
		{"linux", "386"}: {
			Bool:          {1, 1, 1},
			Chan:          {4, 4, 4},
			Complex128:    {16, 4, 4},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 4, 4},
			Function:      {4, 4, 4},
			Int:           {4, 4, 4},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 4, 4},
			Int8:          {1, 1, 1},
			Interface:     {8, 4, 4},
			Map:           {4, 4, 4},
			Pointer:       {4, 4, 4},
			Slice:         {12, 4, 4},
			String:        {8, 4, 4},
			Uint:          {4, 4, 4},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 4, 4},
			Uint8:         {1, 1, 1},
			Uintptr:       {4, 4, 4},
			UnsafePointer: {4, 4, 4},
		},
		// go1.19.1
		{"linux", "amd64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.19.1
		{"linux", "arm"}: {
			Bool:          {1, 1, 1},
			Chan:          {4, 4, 4},
			Complex128:    {16, 4, 4},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 4, 4},
			Function:      {4, 4, 4},
			Int:           {4, 4, 4},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 4, 4},
			Int8:          {1, 1, 1},
			Interface:     {8, 4, 4},
			Map:           {4, 4, 4},
			Pointer:       {4, 4, 4},
			Slice:         {12, 4, 4},
			String:        {8, 4, 4},
			Uint:          {4, 4, 4},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 4, 4},
			Uint8:         {1, 1, 1},
			Uintptr:       {4, 4, 4},
			UnsafePointer: {4, 4, 4},
		},
		// go1.19.1
		{"linux", "arm64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.19.1
		{"linux", "s390x"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.19.1
		{"linux", "ppc64le"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.19.1
		{"linux", "riscv64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.18.3
		{"netbsd", "386"}: {
			Bool:          {1, 1, 1},
			Chan:          {4, 4, 4},
			Complex128:    {16, 4, 4},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 4, 4},
			Function:      {4, 4, 4},
			Int:           {4, 4, 4},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 4, 4},
			Int8:          {1, 1, 1},
			Interface:     {8, 4, 4},
			Map:           {4, 4, 4},
			Pointer:       {4, 4, 4},
			Slice:         {12, 4, 4},
			String:        {8, 4, 4},
			Uint:          {4, 4, 4},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 4, 4},
			Uint8:         {1, 1, 1},
			Uintptr:       {4, 4, 4},
			UnsafePointer: {4, 4, 4},
		},
		// go1.18.3
		{"netbsd", "amd64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.18.3
		{"netbsd", "arm"}: {
			Bool:          {1, 1, 1},
			Chan:          {4, 4, 4},
			Complex128:    {16, 4, 4},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 4, 4},
			Function:      {4, 4, 4},
			Int:           {4, 4, 4},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 4, 4},
			Int8:          {1, 1, 1},
			Interface:     {8, 4, 4},
			Map:           {4, 4, 4},
			Pointer:       {4, 4, 4},
			Slice:         {12, 4, 4},
			String:        {8, 4, 4},
			Uint:          {4, 4, 4},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 4, 4},
			Uint8:         {1, 1, 1},
			Uintptr:       {4, 4, 4},
			UnsafePointer: {4, 4, 4},
		},
		// go1.19
		{"openbsd", "amd64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.19
		{"openbsd", "arm64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.19
		{"openbsd", "386"}: {
			Bool:          {1, 1, 1},
			Chan:          {4, 4, 4},
			Complex128:    {16, 4, 4},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 4, 4},
			Function:      {4, 4, 4},
			Int:           {4, 4, 4},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 4, 4},
			Int8:          {1, 1, 1},
			Interface:     {8, 4, 4},
			Map:           {4, 4, 4},
			Pointer:       {4, 4, 4},
			Slice:         {12, 4, 4},
			String:        {8, 4, 4},
			Uint:          {4, 4, 4},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 4, 4},
			Uint8:         {1, 1, 1},
			Uintptr:       {4, 4, 4},
			UnsafePointer: {4, 4, 4},
		},
		// go1.19.1
		{"windows", "386"}: {
			Bool:          {1, 1, 1},
			Chan:          {4, 4, 4},
			Complex128:    {16, 4, 4},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 4, 4},
			Function:      {4, 4, 4},
			Int:           {4, 4, 4},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 4, 4},
			Int8:          {1, 1, 1},
			Interface:     {8, 4, 4},
			Map:           {4, 4, 4},
			Pointer:       {4, 4, 4},
			Slice:         {12, 4, 4},
			String:        {8, 4, 4},
			Uint:          {4, 4, 4},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 4, 4},
			Uint8:         {1, 1, 1},
			Uintptr:       {4, 4, 4},
			UnsafePointer: {4, 4, 4},
		},
		// go1.19.1
		{"windows", "amd64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.19.1
		{"windows", "arm64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.20.4
		{"illumos", "amd64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.20.5
		{"linux", "loong64"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
		// go1.21.5
		{"linux", "mips64le"}: {
			Bool:          {1, 1, 1},
			Chan:          {8, 8, 8},
			Complex128:    {16, 8, 8},
			Complex64:     {8, 4, 4},
			Float32:       {4, 4, 4},
			Float64:       {8, 8, 8},
			Function:      {8, 8, 8},
			Int:           {8, 8, 8},
			Int16:         {2, 2, 2},
			Int32:         {4, 4, 4},
			Int64:         {8, 8, 8},
			Int8:          {1, 1, 1},
			Interface:     {16, 8, 8},
			Map:           {8, 8, 8},
			Pointer:       {8, 8, 8},
			Slice:         {24, 8, 8},
			String:        {16, 8, 8},
			Uint:          {8, 8, 8},
			Uint16:        {2, 2, 2},
			Uint32:        {4, 4, 4},
			Uint64:        {8, 8, 8},
			Uint8:         {1, 1, 1},
			Uintptr:       {8, 8, 8},
			UnsafePointer: {8, 8, 8},
		},
	}
)

// ABI describes selected parts of the Application Binary Interface.
type ABI struct {
	ByteOrder binary.ByteOrder
	goarch    string
	goos      string
	Types     map[Kind]AbiType
}

type AbiType struct {
	Size       int64
	Align      int
	FieldAlign int
}

// NewABI creates an ABI based on the os+arch pair.
func NewABI(os, arch string) (*ABI, error) {
	byteOrder, ok := byteOrders[arch]
	if !ok {
		return nil, fmt.Errorf("unsupported arch: %s", arch)
	}

	types0, ok := abiTypes[[2]string{os, arch}]
	if !ok {
		return nil, fmt.Errorf("unsupported os/arch: %s/%s", os, arch)
	}

	types := make(map[Kind]AbiType, len(types0))
	for k, v := range types0 {
		types[k] = v
	}
	return &ABI{
		ByteOrder: byteOrder,
		Types:     types,
	}, nil
}
