mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: fix failure to communicate between ABIinfo producer&consumer
ABI info producer and consumer had different ideas for register order for parameters. Includes a test, includes improvements to debugging output. Updates #44816. Change-Id: I4812976f7a6c08d6fc02aac1ec0544b1f141cca6 Reviewed-on: https://go-review.googlesource.com/c/go/+/299570 Trust: David Chase <drchase@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
9f5298ca6e
commit
382851c1fd
6 changed files with 142 additions and 67 deletions
|
|
@ -477,9 +477,9 @@ func (c *RegAmounts) regString(r RegIndex) string {
|
|||
return fmt.Sprintf("<?>%d", r)
|
||||
}
|
||||
|
||||
// toString method renders an ABIParamAssignment in human-readable
|
||||
// ToString method renders an ABIParamAssignment in human-readable
|
||||
// form, suitable for debugging or unit testing.
|
||||
func (ri *ABIParamAssignment) toString(config *ABIConfig) string {
|
||||
func (ri *ABIParamAssignment) ToString(config *ABIConfig, extra bool) string {
|
||||
regs := "R{"
|
||||
offname := "spilloffset" // offset is for spill for register(s)
|
||||
if len(ri.Registers) == 0 {
|
||||
|
|
@ -487,19 +487,25 @@ func (ri *ABIParamAssignment) toString(config *ABIConfig) string {
|
|||
}
|
||||
for _, r := range ri.Registers {
|
||||
regs += " " + config.regAmounts.regString(r)
|
||||
if extra {
|
||||
regs += fmt.Sprintf("(%d)", r)
|
||||
}
|
||||
}
|
||||
if extra {
|
||||
regs += fmt.Sprintf(" | #I=%d, #F=%d", config.regAmounts.intRegs, config.regAmounts.floatRegs)
|
||||
}
|
||||
return fmt.Sprintf("%s } %s: %d typ: %v", regs, offname, ri.offset, ri.Type)
|
||||
}
|
||||
|
||||
// toString method renders an ABIParamResultInfo in human-readable
|
||||
// String method renders an ABIParamResultInfo in human-readable
|
||||
// form, suitable for debugging or unit testing.
|
||||
func (ri *ABIParamResultInfo) String() string {
|
||||
res := ""
|
||||
for k, p := range ri.inparams {
|
||||
res += fmt.Sprintf("IN %d: %s\n", k, p.toString(ri.config))
|
||||
res += fmt.Sprintf("IN %d: %s\n", k, p.ToString(ri.config, false))
|
||||
}
|
||||
for k, r := range ri.outparams {
|
||||
res += fmt.Sprintf("OUT %d: %s\n", k, r.toString(ri.config))
|
||||
res += fmt.Sprintf("OUT %d: %s\n", k, r.ToString(ri.config, false))
|
||||
}
|
||||
res += fmt.Sprintf("offsetToSpillArea: %d spillAreaSize: %d",
|
||||
ri.offsetToSpillArea, ri.spillAreaSize)
|
||||
|
|
@ -537,25 +543,54 @@ func (state *assignState) stackSlot(t *types.Type) int64 {
|
|||
return rv
|
||||
}
|
||||
|
||||
// allocateRegs returns a set of register indices for a parameter or result
|
||||
// allocateRegs returns an ordered list of register indices for a parameter or result
|
||||
// that we've just determined to be register-assignable. The number of registers
|
||||
// needed is assumed to be stored in state.pUsed.
|
||||
func (state *assignState) allocateRegs() []RegIndex {
|
||||
regs := []RegIndex{}
|
||||
|
||||
// integer
|
||||
for r := state.rUsed.intRegs; r < state.rUsed.intRegs+state.pUsed.intRegs; r++ {
|
||||
regs = append(regs, RegIndex(r))
|
||||
func (state *assignState) allocateRegs(regs []RegIndex, t *types.Type) []RegIndex {
|
||||
if t.Width == 0 {
|
||||
return regs
|
||||
}
|
||||
state.rUsed.intRegs += state.pUsed.intRegs
|
||||
|
||||
// floating
|
||||
for r := state.rUsed.floatRegs; r < state.rUsed.floatRegs+state.pUsed.floatRegs; r++ {
|
||||
regs = append(regs, RegIndex(r+state.rTotal.intRegs))
|
||||
ri := state.rUsed.intRegs
|
||||
rf := state.rUsed.floatRegs
|
||||
if t.IsScalar() || t.IsPtrShaped() {
|
||||
if t.IsComplex() {
|
||||
regs = append(regs, RegIndex(rf+state.rTotal.intRegs), RegIndex(rf+1+state.rTotal.intRegs))
|
||||
rf += 2
|
||||
} else if t.IsFloat() {
|
||||
regs = append(regs, RegIndex(rf+state.rTotal.intRegs))
|
||||
rf += 1
|
||||
} else {
|
||||
n := (int(t.Size()) + types.RegSize - 1) / types.RegSize
|
||||
for i := 0; i < n; i++ { // looking ahead to really big integers
|
||||
regs = append(regs, RegIndex(ri))
|
||||
ri += 1
|
||||
}
|
||||
}
|
||||
state.rUsed.intRegs = ri
|
||||
state.rUsed.floatRegs = rf
|
||||
return regs
|
||||
} else {
|
||||
typ := t.Kind()
|
||||
switch typ {
|
||||
case types.TARRAY:
|
||||
for i := int64(0); i < t.NumElem(); i++ {
|
||||
regs = state.allocateRegs(regs, t.Elem())
|
||||
}
|
||||
return regs
|
||||
case types.TSTRUCT:
|
||||
for _, f := range t.FieldSlice() {
|
||||
regs = state.allocateRegs(regs, f.Type)
|
||||
}
|
||||
return regs
|
||||
case types.TSLICE:
|
||||
return state.allocateRegs(regs, synthSlice)
|
||||
case types.TSTRING:
|
||||
return state.allocateRegs(regs, synthString)
|
||||
case types.TINTER:
|
||||
return state.allocateRegs(regs, synthIface)
|
||||
}
|
||||
}
|
||||
state.rUsed.floatRegs += state.pUsed.floatRegs
|
||||
|
||||
return regs
|
||||
panic(fmt.Errorf("Was not expecting type %s", t))
|
||||
}
|
||||
|
||||
// regAllocate creates a register ABIParamAssignment object for a param
|
||||
|
|
@ -571,7 +606,7 @@ func (state *assignState) regAllocate(t *types.Type, name types.Object, isReturn
|
|||
return ABIParamAssignment{
|
||||
Type: t,
|
||||
Name: name,
|
||||
Registers: state.allocateRegs(),
|
||||
Registers: state.allocateRegs([]RegIndex{}, t),
|
||||
offset: int32(spillLoc),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue