Skip to content

Commit

Permalink
cmd/compile: add AMD64 parameter register defs, Arg ops, plumb to ssa…
Browse files Browse the repository at this point in the history
….Config

This is partial plumbing recycled from the original register abi test work;
these are the parts that translate easily.  Some other bits are deferred till
later when they are ready to be used.

For #40724.

Change-Id: Ica8c55a4526793446189725a2bc3839124feb38f
Reviewed-on: https://go-review.googlesource.com/c/go/+/260539
Trust: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
  • Loading branch information
dr2chase committed Feb 23, 2021
1 parent 42cd40e commit 74cac8d
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 50 deletions.
56 changes: 33 additions & 23 deletions src/cmd/compile/internal/ssa/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package ssa

import (
"cmd/compile/internal/abi"
"cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/types"
Expand All @@ -21,29 +22,33 @@ type Config struct {
PtrSize int64 // 4 or 8; copy of cmd/internal/sys.Arch.PtrSize
RegSize int64 // 4 or 8; copy of cmd/internal/sys.Arch.RegSize
Types Types
lowerBlock blockRewriter // lowering function
lowerValue valueRewriter // lowering function
splitLoad valueRewriter // function for splitting merged load ops; only used on some architectures
registers []Register // machine registers
gpRegMask regMask // general purpose integer register mask
fpRegMask regMask // floating point register mask
fp32RegMask regMask // floating point register mask
fp64RegMask regMask // floating point register mask
specialRegMask regMask // special register mask
GCRegMap []*Register // garbage collector register map, by GC register index
FPReg int8 // register number of frame pointer, -1 if not used
LinkReg int8 // register number of link register if it is a general purpose register, -1 if not used
hasGReg bool // has hardware g register
ctxt *obj.Link // Generic arch information
optimize bool // Do optimization
noDuffDevice bool // Don't use Duff's device
useSSE bool // Use SSE for non-float operations
useAvg bool // Use optimizations that need Avg* operations
useHmul bool // Use optimizations that need Hmul* operations
SoftFloat bool //
Race bool // race detector enabled
BigEndian bool //
UseFMA bool // Use hardware FMA operation
lowerBlock blockRewriter // lowering function
lowerValue valueRewriter // lowering function
splitLoad valueRewriter // function for splitting merged load ops; only used on some architectures
registers []Register // machine registers
gpRegMask regMask // general purpose integer register mask
fpRegMask regMask // floating point register mask
fp32RegMask regMask // floating point register mask
fp64RegMask regMask // floating point register mask
specialRegMask regMask // special register mask
intParamRegs []int8 // register numbers of integer param (in/out) registers
floatParamRegs []int8 // register numbers of floating param (in/out) registers
ABI1 *abi.ABIConfig // "ABIInternal" under development // TODO change comment when this becomes current
ABI0 *abi.ABIConfig
GCRegMap []*Register // garbage collector register map, by GC register index
FPReg int8 // register number of frame pointer, -1 if not used
LinkReg int8 // register number of link register if it is a general purpose register, -1 if not used
hasGReg bool // has hardware g register
ctxt *obj.Link // Generic arch information
optimize bool // Do optimization
noDuffDevice bool // Don't use Duff's device
useSSE bool // Use SSE for non-float operations
useAvg bool // Use optimizations that need Avg* operations
useHmul bool // Use optimizations that need Hmul* operations
SoftFloat bool //
Race bool // race detector enabled
BigEndian bool //
UseFMA bool // Use hardware FMA operation
}

type (
Expand Down Expand Up @@ -195,6 +200,8 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config
c.gpRegMask = gpRegMaskAMD64
c.fpRegMask = fpRegMaskAMD64
c.specialRegMask = specialRegMaskAMD64
c.intParamRegs = paramIntRegAMD64
c.floatParamRegs = paramFloatRegAMD64
c.FPReg = framepointerRegAMD64
c.LinkReg = linkRegAMD64
c.hasGReg = base.Flag.ABIWrap
Expand Down Expand Up @@ -326,6 +333,9 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config
c.useSSE = true
c.UseFMA = true

c.ABI0 = abi.NewABIConfig(0, 0)
c.ABI1 = abi.NewABIConfig(len(c.intParamRegs), len(c.floatParamRegs))

// On Plan 9, floating point operations are not allowed in note handler.
if objabi.GOOS == "plan9" {
// Don't use FMA on Plan 9
Expand Down
25 changes: 14 additions & 11 deletions src/cmd/compile/internal/ssa/gen/AMD64Ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build ignore
// +build ignore

package main
Expand Down Expand Up @@ -929,16 +930,18 @@ func init() {
}

archs = append(archs, arch{
name: "AMD64",
pkg: "cmd/internal/obj/x86",
genfile: "../../amd64/ssa.go",
ops: AMD64ops,
blocks: AMD64blocks,
regnames: regNamesAMD64,
gpregmask: gp,
fpregmask: fp,
specialregmask: x15,
framepointerreg: int8(num["BP"]),
linkreg: -1, // not used
name: "AMD64",
pkg: "cmd/internal/obj/x86",
genfile: "../../amd64/ssa.go",
ops: AMD64ops,
blocks: AMD64blocks,
regnames: regNamesAMD64,
ParamIntRegNames: "AX BX CX DI SI R8 R9 R10 R11",
ParamFloatRegNames: "X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14",
gpregmask: gp,
fpregmask: fp,
specialregmask: x15,
framepointerreg: int8(num["BP"]),
linkreg: -1, // not used
})
}
6 changes: 6 additions & 0 deletions src/cmd/compile/internal/ssa/gen/genericOps.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build ignore
// +build ignore

package main
Expand Down Expand Up @@ -332,6 +333,11 @@ var genericOps = []opData{
{name: "InitMem", zeroWidth: true}, // memory input to the function.
{name: "Arg", aux: "SymOff", symEffect: "Read", zeroWidth: true}, // argument to the function. aux=GCNode of arg, off = offset in that arg.

// Like Arg, these are generic ops that survive lowering. AuxInt is a register index, and the actual output register for each index is defined by the architecture.
// AuxInt = integer argument index (not a register number). ABI-specified spill loc obtained from function
{name: "ArgIntReg", aux: "Int8", zeroWidth: true}, // argument to the function in an int reg.
{name: "ArgFloatReg", aux: "Int8", zeroWidth: true}, // argument to the function in a float reg.

// The address of a variable. arg0 is the base pointer.
// If the variable is a global, the base pointer will be SB and
// the Aux field will be a *obj.LSym.
Expand Down
62 changes: 47 additions & 15 deletions src/cmd/compile/internal/ssa/gen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build ignore
// +build ignore

// The gen command generates Go code (in the parent directory) for all
Expand Down Expand Up @@ -30,21 +31,23 @@ import (
// apart from type names, and avoid awkward func parameters like "arch arch".

type arch struct {
name string
pkg string // obj package to import for this arch.
genfile string // source file containing opcode code generation.
ops []opData
blocks []blockData
regnames []string
gpregmask regMask
fpregmask regMask
fp32regmask regMask
fp64regmask regMask
specialregmask regMask
framepointerreg int8
linkreg int8
generic bool
imports []string
name string
pkg string // obj package to import for this arch.
genfile string // source file containing opcode code generation.
ops []opData
blocks []blockData
regnames []string
ParamIntRegNames string
ParamFloatRegNames string
gpregmask regMask
fpregmask regMask
fp32regmask regMask
fp64regmask regMask
specialregmask regMask
framepointerreg int8
linkreg int8
generic bool
imports []string
}

type opData struct {
Expand Down Expand Up @@ -412,7 +415,9 @@ func genOp() {
}
fmt.Fprintf(w, "var registers%s = [...]Register {\n", a.name)
var gcRegN int
num := map[string]int8{}
for i, r := range a.regnames {
num[r] = int8(i)
pkg := a.pkg[len("cmd/internal/obj/"):]
var objname string // name in cmd/internal/obj/$ARCH
switch r {
Expand All @@ -435,11 +440,38 @@ func genOp() {
}
fmt.Fprintf(w, " {%d, %s, %d, \"%s\"},\n", i, objname, gcRegIdx, r)
}
parameterRegisterList := func(paramNamesString string) []int8 {
paramNamesString = strings.TrimSpace(paramNamesString)
if paramNamesString == "" {
return nil
}
paramNames := strings.Split(paramNamesString, " ")
var paramRegs []int8
for _, regName := range paramNames {
if regName == "" {
// forgive extra spaces
continue
}
if regNum, ok := num[regName]; ok {
paramRegs = append(paramRegs, regNum)
delete(num, regName)
} else {
log.Fatalf("parameter register %s for architecture %s not a register name (or repeated in parameter list)", regName, a.name)
}
}
return paramRegs
}

paramIntRegs := parameterRegisterList(a.ParamIntRegNames)
paramFloatRegs := parameterRegisterList(a.ParamFloatRegNames)

if gcRegN > 32 {
// Won't fit in a uint32 mask.
log.Fatalf("too many GC registers (%d > 32) on %s", gcRegN, a.name)
}
fmt.Fprintln(w, "}")
fmt.Fprintf(w, "var paramIntReg%s = %#v\n", a.name, paramIntRegs)
fmt.Fprintf(w, "var paramFloatReg%s = %#v\n", a.name, paramFloatRegs)
fmt.Fprintf(w, "var gpRegMask%s = regMask(%d)\n", a.name, a.gpregmask)
fmt.Fprintf(w, "var fpRegMask%s = regMask(%d)\n", a.name, a.fpregmask)
if a.fp32regmask != 0 {
Expand Down
4 changes: 4 additions & 0 deletions src/cmd/compile/internal/ssa/op.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ type AuxCall struct {
Fn *obj.LSym
args []Param // Includes receiver for method calls. Does NOT include hidden closure pointer.
results []Param
reg *regInfo // regInfo for this call // TODO for now nil means ignore
}

// ResultForOffset returns the index of the result at a particular offset among the results
Expand Down Expand Up @@ -186,16 +187,19 @@ func (a *AuxCall) String() string {

// StaticAuxCall returns an AuxCall for a static call.
func StaticAuxCall(sym *obj.LSym, args []Param, results []Param) *AuxCall {
// TODO Create regInfo for AuxCall
return &AuxCall{Fn: sym, args: args, results: results}
}

// InterfaceAuxCall returns an AuxCall for an interface call.
func InterfaceAuxCall(args []Param, results []Param) *AuxCall {
// TODO Create regInfo for AuxCall
return &AuxCall{Fn: nil, args: args, results: results}
}

// ClosureAuxCall returns an AuxCall for a closure call.
func ClosureAuxCall(args []Param, results []Param) *AuxCall {
// TODO Create regInfo for AuxCall
return &AuxCall{Fn: nil, args: args, results: results}
}

Expand Down
36 changes: 36 additions & 0 deletions src/cmd/compile/internal/ssa/opGen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/runtime/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const (
stackDebug = 0
stackFromSystem = 0 // allocate stacks from system memory instead of the heap
stackFaultOnFree = 0 // old stacks are mapped noaccess to detect use after free
stackPoisonCopy = 0 // fill stack that should not be accessed with garbage, to detect bad dereferences during copy
stackPoisonCopy = 1 // fill stack that should not be accessed with garbage, to detect bad dereferences during copy
stackNoCache = 0 // disable per-P small stack caches

// check the BP links during traceback.
Expand Down

0 comments on commit 74cac8d

Please sign in to comment.