aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/abi/abiutils.go
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2021-02-22 21:51:35 -0500
committerDavid Chase <drchase@google.com>2021-03-04 19:45:11 +0000
commit9d88a9e2bf89068238ed02a0c960e58f547bb102 (patch)
tree97b23a5d25fbd2f5fd3e3060b1d7b581b99c19f7 /src/cmd/compile/internal/abi/abiutils.go
parent2d30c94874c127d9028e29b77fadeb284c23e89a (diff)
downloadgo-9d88a9e2bf89068238ed02a0c960e58f547bb102.tar.gz
go-9d88a9e2bf89068238ed02a0c960e58f547bb102.zip
cmd/compile: implement simple register results
at least for ints and strings includes simple test For #40724. Change-Id: Ib8484e5b957b08f961574a67cfd93d3d26551558 Reviewed-on: https://go-review.googlesource.com/c/go/+/295309 Trust: David Chase <drchase@google.com> Run-TryBot: David Chase <drchase@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/abi/abiutils.go')
-rw-r--r--src/cmd/compile/internal/abi/abiutils.go64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/abi/abiutils.go b/src/cmd/compile/internal/abi/abiutils.go
index f84f8f8e01..ffa709965c 100644
--- a/src/cmd/compile/internal/abi/abiutils.go
+++ b/src/cmd/compile/internal/abi/abiutils.go
@@ -101,6 +101,70 @@ func (a *ABIParamAssignment) Offset() int32 {
return a.offset
}
+// RegisterTypes returns a slice of the types of the registers
+// corresponding to a slice of parameters. The returned slice
+// has capacity for one more, likely a memory type.
+func RegisterTypes(apa []ABIParamAssignment) []*types.Type {
+ rcount := 0
+ for _, pa := range apa {
+ rcount += len(pa.Registers)
+ }
+ if rcount == 0 {
+ // Note that this catches top-level struct{} and [0]Foo, which are stack allocated.
+ return make([]*types.Type, 0, 1)
+ }
+ rts := make([]*types.Type, 0, rcount+1)
+ for _, pa := range apa {
+ if len(pa.Registers) == 0 {
+ continue
+ }
+ rts = appendParamRegs(rts, pa.Type)
+ }
+ return rts
+}
+
+func appendParamRegs(rts []*types.Type, t *types.Type) []*types.Type {
+ if t.IsScalar() || t.IsPtrShaped() {
+ if t.IsComplex() {
+ c := types.FloatForComplex(t)
+ return append(rts, c, c)
+ } else {
+ if int(t.Size()) <= types.RegSize {
+ return append(rts, t)
+ }
+ // assume 64bit int on 32-bit machine
+ // TODO endianness? Should high-order (sign bits) word come first?
+ if t.IsSigned() {
+ rts = append(rts, types.Types[types.TINT32])
+ } else {
+ rts = append(rts, types.Types[types.TUINT32])
+ }
+ return append(rts, types.Types[types.TUINT32])
+ }
+ } else {
+ typ := t.Kind()
+ switch typ {
+ case types.TARRAY:
+ for i := int64(0); i < t.Size(); i++ { // 0 gets no registers, plus future-proofing.
+ rts = appendParamRegs(rts, t.Elem())
+ }
+ case types.TSTRUCT:
+ for _, f := range t.FieldSlice() {
+ if f.Type.Size() > 0 { // embedded zero-width types receive no registers
+ rts = appendParamRegs(rts, f.Type)
+ }
+ }
+ case types.TSLICE:
+ return appendParamRegs(rts, synthSlice)
+ case types.TSTRING:
+ return appendParamRegs(rts, synthString)
+ case types.TINTER:
+ return appendParamRegs(rts, synthIface)
+ }
+ }
+ return rts
+}
+
// SpillOffset returns the offset *within the spill area* for the parameter that "a" describes.
// Registers will be spilled here; if a memory home is needed (for a pointer method e.g.)
// then that will be the address.