package types
import (
+ "math"
"sort"
"cmd/compile/internal/base"
case TINT8, TUINT8, TBOOL:
// bool is int8
w = 1
+ t.intRegs = 1
case TINT16, TUINT16:
w = 2
+ t.intRegs = 1
- case TINT32, TUINT32, TFLOAT32:
+ case TINT32, TUINT32:
w = 4
+ t.intRegs = 1
- case TINT64, TUINT64, TFLOAT64:
+ case TINT64, TUINT64:
w = 8
t.align = uint8(RegSize)
+ t.intRegs = uint8(8 / RegSize)
+
+ case TFLOAT32:
+ w = 4
+ t.floatRegs = 1
+
+ case TFLOAT64:
+ w = 8
+ t.align = uint8(RegSize)
+ t.floatRegs = 1
case TCOMPLEX64:
w = 8
t.align = 4
+ t.floatRegs = 2
case TCOMPLEX128:
w = 16
t.align = uint8(RegSize)
+ t.floatRegs = 2
case TPTR:
w = int64(PtrSize)
+ t.intRegs = 1
CheckSize(t.Elem())
case TUNSAFEPTR:
w = int64(PtrSize)
+ t.intRegs = 1
case TINTER: // implemented as 2 pointers
w = 2 * int64(PtrSize)
t.align = uint8(PtrSize)
+ t.intRegs = 2
expandiface(t)
case TCHAN: // implemented as pointer
w = int64(PtrSize)
+ t.intRegs = 1
CheckSize(t.Elem())
case TMAP: // implemented as pointer
w = int64(PtrSize)
+ t.intRegs = 1
CheckSize(t.Elem())
CheckSize(t.Key())
case TFORW: // should have been filled in
base.Fatalf("invalid recursive type %v", t)
- w = 1 // anything will do
- case TANY:
- // not a real type; should be replaced before use.
+ case TANY: // not a real type; should be replaced before use.
base.Fatalf("CalcSize any")
case TSTRING:
}
w = StringSize
t.align = uint8(PtrSize)
+ t.intRegs = 2
case TARRAY:
if t.Elem() == nil {
w = t.NumElem() * t.Elem().width
t.align = t.Elem().align
+ // ABIInternal only allows "trivial" arrays (i.e., length 0 or 1)
+ // to be passed by register.
+ switch t.NumElem() {
+ case 0:
+ t.intRegs = 0
+ t.floatRegs = 0
+ case 1:
+ t.intRegs = t.Elem().intRegs
+ t.floatRegs = t.Elem().floatRegs
+ default:
+ t.intRegs = math.MaxUint8
+ t.floatRegs = math.MaxUint8
+ }
+
case TSLICE:
if t.Elem() == nil {
break
w = SliceSize
CheckSize(t.Elem())
t.align = uint8(PtrSize)
+ t.intRegs = 3
case TSTRUCT:
if t.IsFuncArgStruct() {
t1 := NewFuncArgs(t)
CheckSize(t1)
w = int64(PtrSize) // width of func type is pointer
+ t.intRegs = 1
// function is 3 cated structures;
// compute their widths as side-effect.
}
// CalcStructSize calculates the size of t,
-// filling in t.width and t.align,
+// filling in t.width, t.align, t.intRegs, and t.floatRegs,
// even if size calculation is otherwise disabled.
func CalcStructSize(t *Type) {
var maxAlign uint8 = 1
size++
}
- // The alignment of a struct type is the maximum alignment of its
- // field types.
+ var intRegs, floatRegs uint64
for _, field := range fields {
- if align := field.Type.align; align > maxAlign {
+ typ := field.Type
+
+ // The alignment of a struct type is the maximum alignment of its
+ // field types.
+ if align := typ.align; align > maxAlign {
maxAlign = align
}
+
+ // Each field needs its own registers.
+ // We sum in uint64 to avoid possible overflows.
+ intRegs += uint64(typ.intRegs)
+ floatRegs += uint64(typ.floatRegs)
}
// Final size includes trailing padding.
size = RoundUp(size, int64(maxAlign))
+ if intRegs > math.MaxUint8 || floatRegs > math.MaxUint8 {
+ intRegs = math.MaxUint8
+ floatRegs = math.MaxUint8
+ }
+
t.width = size
t.align = maxAlign
+ t.intRegs = uint8(intRegs)
+ t.floatRegs = uint8(floatRegs)
}
func (t *Type) widthCalculated() bool {
kind Kind // kind of type
align uint8 // the required alignment of this type, in bytes (0 means Width and Align have not yet been computed)
+ intRegs, floatRegs uint8 // registers needed for ABIInternal
+
flags bitset8
// For defined (named) generic types, a pointer to the list of type params
rparams *[]*Type
}
+// Registers returns the number of integer and floating-point
+// registers required to represent a parameter of this type under the
+// ABIInternal calling conventions.
+//
+// If t must be passed by memory, Registers returns (math.MaxUint8,
+// math.MaxUint8).
+func (t *Type) Registers() (uint8, uint8) {
+ CalcSize(t)
+ return t.intRegs, t.floatRegs
+}
+
func (*Type) CanBeAnSSAAux() {}
const (
t.extra = Ptr{Elem: elem}
t.width = int64(PtrSize)
t.align = uint8(PtrSize)
+ t.intRegs = 1
if NewPtrCacheEnabled {
elem.cache.ptr = t
}
t.extra = underlying.extra
t.width = underlying.width
t.align = underlying.align
+ t.intRegs = underlying.intRegs
+ t.floatRegs = underlying.floatRegs
t.underlying = underlying.underlying
if underlying.NotInHeap() {