From 195c88b202695e90b2ff41b3f1a03bc19685baa6 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 8 Nov 2023 16:08:26 +0100 Subject: [PATCH 01/30] net/http: use pointers to array for copyBufPool This is inspired by CL 539915, I'm only submitting now that CL 456435 has been merged. This divide the number of objects kept alive by the heap by two and remove the slice header allocation in New and in the put back. Change-Id: Ibcd5166bac5a37f365a533e09a28f3b79f81ad58 Reviewed-on: https://go-review.googlesource.com/c/go/+/543515 Reviewed-by: Damien Neil Auto-Submit: Damien Neil Reviewed-by: qiulaidongfeng <2645477756@qq.com> LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Knyszek --- src/net/http/server.go | 22 ++++++++++++++-------- src/net/http/transfer.go | 5 ++--- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/net/http/server.go b/src/net/http/server.go index 7fa785dfee..36a03f4a32 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -575,9 +575,8 @@ type writerOnly struct { // to a *net.TCPConn with sendfile, or from a supported src type such // as a *net.TCPConn on Linux with splice. func (w *response) ReadFrom(src io.Reader) (n int64, err error) { - bufp := copyBufPool.Get().(*[]byte) - buf := *bufp - defer copyBufPool.Put(bufp) + buf := getCopyBuf() + defer putCopyBuf(buf) // Our underlying w.conn.rwc is usually a *TCPConn (with its // own ReadFrom method). If not, just fall back to the normal @@ -807,11 +806,18 @@ var ( bufioWriter4kPool sync.Pool ) -var copyBufPool = sync.Pool{ - New: func() any { - b := make([]byte, 32*1024) - return &b - }, +const copyBufPoolSize = 32 * 1024 + +var copyBufPool = sync.Pool{New: func() any { return new([copyBufPoolSize]byte) }} + +func getCopyBuf() []byte { + return copyBufPool.Get().(*[copyBufPoolSize]byte)[:] +} +func putCopyBuf(b []byte) { + if len(b) != copyBufPoolSize { + panic("trying to put back buffer of the wrong size in the copyBufPool") + } + copyBufPool.Put((*[copyBufPoolSize]byte)(b)) } func bufioWriterPool(size int) *sync.Pool { diff --git a/src/net/http/transfer.go b/src/net/http/transfer.go index dffff56b31..d787258487 100644 --- a/src/net/http/transfer.go +++ b/src/net/http/transfer.go @@ -410,9 +410,8 @@ func (t *transferWriter) writeBody(w io.Writer) (err error) { // // This function is only intended for use in writeBody. func (t *transferWriter) doBodyCopy(dst io.Writer, src io.Reader) (n int64, err error) { - bufp := copyBufPool.Get().(*[]byte) - buf := *bufp - defer copyBufPool.Put(bufp) + buf := getCopyBuf() + defer putCopyBuf(buf) n, err = io.CopyBuffer(dst, src, buf) if err != nil && err != io.EOF { From dc094f9c9613a2a8ed24ace1b5416170aa3a334b Mon Sep 17 00:00:00 2001 From: Cherry Mui Date: Mon, 20 Nov 2023 16:33:29 -0500 Subject: [PATCH 02/30] runtime: disable crash stack on Windows Apparently, on Windows, throwing an exception on a non-system- allocated crash stack causes EXCEPTION_STACK_OVERFLOW and hangs the process (see issue #63938). Disable crash stack for now, which gets us back the the behavior of Go 1.21. Fixes #63938. Change-Id: I4c090315b93b484e756b242f0de7a9e02f199261 Reviewed-on: https://go-review.googlesource.com/c/go/+/543996 Reviewed-by: Michael Knyszek TryBot-Result: Gopher Robot Run-TryBot: Cherry Mui Reviewed-by: Quim Muntal --- src/runtime/crash_test.go | 4 +--- src/runtime/proc.go | 5 ++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go index ffd99f3a87..2ed0fd8f07 100644 --- a/src/runtime/crash_test.go +++ b/src/runtime/crash_test.go @@ -795,14 +795,12 @@ func TestG0StackOverflow(t *testing.T) { if runtime.GOOS == "ios" { testenv.SkipFlaky(t, 62671) } - if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" { - testenv.SkipFlaky(t, 63938) // TODO(cherry): fix and unskip - } if os.Getenv("TEST_G0_STACK_OVERFLOW") != "1" { cmd := testenv.CleanCmdEnv(testenv.Command(t, os.Args[0], "-test.run=^TestG0StackOverflow$", "-test.v")) cmd.Env = append(cmd.Env, "TEST_G0_STACK_OVERFLOW=1") out, err := cmd.CombinedOutput() + t.Logf("output:\n%s", out) // Don't check err since it's expected to crash. if n := strings.Count(string(out), "morestack on g0\n"); n != 1 { t.Fatalf("%s\n(exit status %v)", out, err) diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 18826abb06..edf692fd1a 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -576,7 +576,10 @@ func switchToCrashStack(fn func()) { abort() } -const crashStackImplemented = GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "mips64" || GOARCH == "mips64le" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64" || GOARCH == "wasm" +// Disable crash stack on Windows for now. Apparently, throwing an exception +// on a non-system-allocated crash stack causes EXCEPTION_STACK_OVERFLOW and +// hangs the process (see issue 63938). +const crashStackImplemented = (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "mips64" || GOARCH == "mips64le" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64" || GOARCH == "wasm") && GOOS != "windows" //go:noescape func switchToCrashStack0(fn func()) // in assembly From 515f3c0da643a3c2dfcf494ac0a7cf8f65002f38 Mon Sep 17 00:00:00 2001 From: Jes Cok Date: Mon, 20 Nov 2023 13:37:33 +0000 Subject: [PATCH 03/30] reflect: tweak logic for 'case Array' in IsZero For 'case Array' in IsZero, check 'v.flag&flagIndir == 0' in the first place, rename 'array' to 'typ' for consistency, and remove stale comment. Add line breaks for long sentence in isZero. Change-Id: Id06d01fd61eefd205bf4626e6b920ae82b459455 GitHub-Last-Rev: 7225ca3f7b55cbef58387365ed8f3ff104236a06 GitHub-Pull-Request: golang/go#64270 Reviewed-on: https://go-review.googlesource.com/c/go/+/543656 TryBot-Result: Gopher Robot Reviewed-by: Keith Randall Run-TryBot: Jes Cok Reviewed-by: Keith Randall Auto-Submit: Keith Randall Reviewed-by: Cherry Mui --- src/reflect/value.go | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/reflect/value.go b/src/reflect/value.go index 2bd41f37fd..068bac0050 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -1598,24 +1598,23 @@ func (v Value) IsZero() bool { case Complex64, Complex128: return v.Complex() == 0 case Array: - array := (*abi.ArrayType)(unsafe.Pointer(v.typ())) - // Avoid performance degradation of small benchmarks. + if v.flag&flagIndir == 0 { + return v.ptr == nil + } + typ := (*abi.ArrayType)(unsafe.Pointer(v.typ())) // If the type is comparable, then compare directly with zero. - if array.Equal != nil && array.Size() <= maxZero { - if v.flag&flagIndir == 0 { - return v.ptr == nil - } + if typ.Equal != nil && typ.Size() <= maxZero { // v.ptr doesn't escape, as Equal functions are compiler generated // and never escape. The escape analysis doesn't know, as it is a // function pointer call. - return array.Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0])) + return typ.Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0])) } - if array.TFlag&abi.TFlagRegularMemory != 0 { + if typ.TFlag&abi.TFlagRegularMemory != 0 { // For some types where the zero value is a value where all bits of this type are 0 // optimize it. - return isZero(unsafe.Slice(((*byte)(v.ptr)), array.Size())) + return isZero(unsafe.Slice(((*byte)(v.ptr)), typ.Size())) } - n := int(array.Len) + n := int(typ.Len) for i := 0; i < n; i++ { if !v.Index(i).IsZero() { return false @@ -1663,7 +1662,7 @@ func isZero(b []byte) bool { return true } const n = 32 - // Align memory addresses to 8 bytes + // Align memory addresses to 8 bytes. for uintptr(unsafe.Pointer(&b[0]))%8 != 0 { if b[0] != 0 { return false @@ -1690,7 +1689,14 @@ func isZero(b []byte) bool { w = w[1:] } for len(w) >= n { - if w[0] != 0 || w[1] != 0 || w[2] != 0 || w[3] != 0 || w[4] != 0 || w[5] != 0 || w[6] != 0 || w[7] != 0 || w[8] != 0 || w[9] != 0 || w[10] != 0 || w[11] != 0 || w[12] != 0 || w[13] != 0 || w[14] != 0 || w[15] != 0 || w[16] != 0 || w[17] != 0 || w[18] != 0 || w[19] != 0 || w[20] != 0 || w[21] != 0 || w[22] != 0 || w[23] != 0 || w[24] != 0 || w[25] != 0 || w[26] != 0 || w[27] != 0 || w[28] != 0 || w[29] != 0 || w[30] != 0 || w[31] != 0 { + if w[0] != 0 || w[1] != 0 || w[2] != 0 || w[3] != 0 || + w[4] != 0 || w[5] != 0 || w[6] != 0 || w[7] != 0 || + w[8] != 0 || w[9] != 0 || w[10] != 0 || w[11] != 0 || + w[12] != 0 || w[13] != 0 || w[14] != 0 || w[15] != 0 || + w[16] != 0 || w[17] != 0 || w[18] != 0 || w[19] != 0 || + w[20] != 0 || w[21] != 0 || w[22] != 0 || w[23] != 0 || + w[24] != 0 || w[25] != 0 || w[26] != 0 || w[27] != 0 || + w[28] != 0 || w[29] != 0 || w[30] != 0 || w[31] != 0 { return false } w = w[n:] From 8be8bfeaa2e9fb9372d8507f076c6307e8237c54 Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Thu, 2 Nov 2023 11:25:07 -0400 Subject: [PATCH 04/30] cmd/compile/internal/ir: add batch-mode reassignment detection oracle Add a new helper type 'ReassignOracle', useful for doing "batch mode" reassignment analysis, e.g. deciding whether a given ir.Name or (chain of connected names) has a single definition and is never reassigned. The intended usage model is for clients to create/initialize a ReassignOracle for a given function, then make a series of queries using it (with the understanding that changing/mutating the func body IR can invalidate the info cached in the oracle). This oracle is intended to provide the same sort of analysis that ir.StaticValue and ir.Reassigned carry out, but at a much reduced cost in compile time. Notes: - the new helper isn't actually used for anything useful in this patch; it will be hooked into the inline heuristics code as part of a subsequent CL. - this is probably not an ideal long-term solution; it would be better to switch to a scheme based a flag on ir.Name, as opposed to a side table. Change-Id: I283e748e440a9f595df495f6aa48ee9c498702d9 Reviewed-on: https://go-review.googlesource.com/c/go/+/539319 Reviewed-by: Matthew Dempsky LUCI-TryBot-Result: Go LUCI --- .../compile/internal/ir/check_reassign_no.go | 9 + .../compile/internal/ir/check_reassign_yes.go | 9 + src/cmd/compile/internal/ir/expr.go | 2 + .../internal/ir/reassign_consistency_check.go | 46 ++++ src/cmd/compile/internal/ir/reassignment.go | 205 ++++++++++++++++++ 5 files changed, 271 insertions(+) create mode 100644 src/cmd/compile/internal/ir/check_reassign_no.go create mode 100644 src/cmd/compile/internal/ir/check_reassign_yes.go create mode 100644 src/cmd/compile/internal/ir/reassign_consistency_check.go create mode 100644 src/cmd/compile/internal/ir/reassignment.go diff --git a/src/cmd/compile/internal/ir/check_reassign_no.go b/src/cmd/compile/internal/ir/check_reassign_no.go new file mode 100644 index 0000000000..8290a7da7e --- /dev/null +++ b/src/cmd/compile/internal/ir/check_reassign_no.go @@ -0,0 +1,9 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !checknewoldreassignment + +package ir + +const consistencyCheckEnabled = false diff --git a/src/cmd/compile/internal/ir/check_reassign_yes.go b/src/cmd/compile/internal/ir/check_reassign_yes.go new file mode 100644 index 0000000000..30876cca20 --- /dev/null +++ b/src/cmd/compile/internal/ir/check_reassign_yes.go @@ -0,0 +1,9 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build checknewoldreassignment + +package ir + +const consistencyCheckEnabled = true diff --git a/src/cmd/compile/internal/ir/expr.go b/src/cmd/compile/internal/ir/expr.go index 1bcd648282..da5b437f99 100644 --- a/src/cmd/compile/internal/ir/expr.go +++ b/src/cmd/compile/internal/ir/expr.go @@ -923,6 +923,8 @@ FindRHS: // NB: global variables are always considered to be re-assigned. // TODO: handle initial declaration not including an assignment and // followed by a single assignment? +// NOTE: any changes made here should also be made in the corresponding +// code in the ReassignOracle.Init method. func Reassigned(name *Name) bool { if name.Op() != ONAME { base.Fatalf("reassigned %v", name) diff --git a/src/cmd/compile/internal/ir/reassign_consistency_check.go b/src/cmd/compile/internal/ir/reassign_consistency_check.go new file mode 100644 index 0000000000..e4d928d132 --- /dev/null +++ b/src/cmd/compile/internal/ir/reassign_consistency_check.go @@ -0,0 +1,46 @@ +// Copyright 2023 The Go 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 ir + +import ( + "cmd/compile/internal/base" + "cmd/internal/src" + "fmt" + "path/filepath" + "strings" +) + +// checkStaticValueResult compares the result from ReassignOracle.StaticValue +// with the corresponding result from ir.StaticValue to make sure they agree. +// This method is called only when turned on via build tag. +func checkStaticValueResult(n Node, newres Node) { + oldres := StaticValue(n) + if oldres != newres { + base.Fatalf("%s: new/old static value disagreement on %v:\nnew=%v\nold=%v", fmtFullPos(n.Pos()), n, newres, oldres) + } +} + +// checkStaticValueResult compares the result from ReassignOracle.Reassigned +// with the corresponding result from ir.Reassigned to make sure they agree. +// This method is called only when turned on via build tag. +func checkReassignedResult(n *Name, newres bool) { + origres := Reassigned(n) + if newres != origres { + base.Fatalf("%s: new/old reassigned disagreement on %v (class %s) newres=%v oldres=%v", fmtFullPos(n.Pos()), n, n.Class.String(), newres, origres) + } +} + +// fmtFullPos returns a verbose dump for pos p, including inlines. +func fmtFullPos(p src.XPos) string { + var sb strings.Builder + sep := "" + base.Ctxt.AllPos(p, func(pos src.Pos) { + fmt.Fprintf(&sb, sep) + sep = "|" + file := filepath.Base(pos.Filename()) + fmt.Fprintf(&sb, "%s:%d:%d", file, pos.Line(), pos.Col()) + }) + return sb.String() +} diff --git a/src/cmd/compile/internal/ir/reassignment.go b/src/cmd/compile/internal/ir/reassignment.go new file mode 100644 index 0000000000..9974292471 --- /dev/null +++ b/src/cmd/compile/internal/ir/reassignment.go @@ -0,0 +1,205 @@ +// Copyright 2023 The Go 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 ir + +import ( + "cmd/compile/internal/base" +) + +// A ReassignOracle efficiently answers queries about whether local +// variables are reassigned. This helper works by looking for function +// params and short variable declarations (e.g. +// https://go.dev/ref/spec#Short_variable_declarations) that are +// neither address taken nor subsequently re-assigned. It is intended +// to operate much like "ir.StaticValue" and "ir.Reassigned", but in a +// way that does just a single walk of the containing function (as +// opposed to a new walk on every call). +type ReassignOracle struct { + fn *Func + // maps candidate name to its defining assignment (or for + // for params, defining func). + singleDef map[*Name]Node +} + +// Init initializes the oracle based on the IR in function fn, laying +// the groundwork for future calls to the StaticValue and Reassigned +// methods. If the fn's IR is subsequently modified, Init must be +// called again. +func (ro *ReassignOracle) Init(fn *Func) { + ro.fn = fn + + // Collect candidate map. Start by adding function parameters + // explicitly. + ro.singleDef = make(map[*Name]Node) + sig := fn.Type() + numParams := sig.NumRecvs() + sig.NumParams() + for _, param := range fn.Dcl[:numParams] { + if IsBlank(param) { + continue + } + // For params, use func itself as defining node. + ro.singleDef[param] = fn + } + + // Walk the function body to discover any locals assigned + // via ":=" syntax (e.g. "a := "). + var findLocals func(n Node) bool + findLocals = func(n Node) bool { + if nn, ok := n.(*Name); ok { + if nn.Defn != nil && !nn.Addrtaken() && nn.Class == PAUTO { + ro.singleDef[nn] = nn.Defn + } + } else if nn, ok := n.(*ClosureExpr); ok { + Any(nn.Func, findLocals) + } + return false + } + Any(fn, findLocals) + + outerName := func(x Node) *Name { + if x == nil { + return nil + } + n, ok := OuterValue(x).(*Name) + if ok { + return n.Canonical() + } + return nil + } + + // pruneIfNeeded examines node nn appearing on the left hand side + // of assignment statement asn to see if it contains a reassignment + // to any nodes in our candidate map ro.singleDef; if a reassignment + // is found, the corresponding name is deleted from singleDef. + pruneIfNeeded := func(nn Node, asn Node) { + oname := outerName(nn) + if oname == nil { + return + } + defn, ok := ro.singleDef[oname] + if !ok { + return + } + // any assignment to a param invalidates the entry. + paramAssigned := oname.Class == PPARAM + // assignment to local ok iff assignment is its orig def. + localAssigned := (oname.Class == PAUTO && asn != defn) + if paramAssigned || localAssigned { + // We found an assignment to name N that doesn't + // correspond to its original definition; remove + // from candidates. + delete(ro.singleDef, oname) + } + } + + // Prune away anything that looks assigned. This code modeled after + // similar code in ir.Reassigned; any changes there should be made + // here as well. + var do func(n Node) bool + do = func(n Node) bool { + switch n.Op() { + case OAS: + asn := n.(*AssignStmt) + pruneIfNeeded(asn.X, n) + case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2: + asn := n.(*AssignListStmt) + for _, p := range asn.Lhs { + pruneIfNeeded(p, n) + } + case OASOP: + asn := n.(*AssignOpStmt) + pruneIfNeeded(asn.X, n) + case ORANGE: + rs := n.(*RangeStmt) + pruneIfNeeded(rs.Key, n) + pruneIfNeeded(rs.Value, n) + case OCLOSURE: + n := n.(*ClosureExpr) + Any(n.Func, do) + } + return false + } + Any(fn, do) +} + +// StaticValue method has the same semantics as the ir package function +// of the same name; see comments on [StaticValue]. +func (ro *ReassignOracle) StaticValue(n Node) Node { + arg := n + for { + if n.Op() == OCONVNOP { + n = n.(*ConvExpr).X + continue + } + + if n.Op() == OINLCALL { + n = n.(*InlinedCallExpr).SingleResult() + continue + } + + n1 := ro.staticValue1(n) + if n1 == nil { + if consistencyCheckEnabled { + checkStaticValueResult(arg, n) + } + return n + } + n = n1 + } +} + +func (ro *ReassignOracle) staticValue1(nn Node) Node { + if nn.Op() != ONAME { + return nil + } + n := nn.(*Name).Canonical() + if n.Class != PAUTO { + return nil + } + + defn := n.Defn + if defn == nil { + return nil + } + + var rhs Node +FindRHS: + switch defn.Op() { + case OAS: + defn := defn.(*AssignStmt) + rhs = defn.Y + case OAS2: + defn := defn.(*AssignListStmt) + for i, lhs := range defn.Lhs { + if lhs == n { + rhs = defn.Rhs[i] + break FindRHS + } + } + base.Fatalf("%v missing from LHS of %v", n, defn) + default: + return nil + } + if rhs == nil { + base.Fatalf("RHS is nil: %v", defn) + } + + if _, ok := ro.singleDef[n]; !ok { + return nil + } + + return rhs +} + +// Reassigned method has the same semantics as the ir package function +// of the same name; see comments on [Reassigned] for more info. +func (ro *ReassignOracle) Reassigned(n *Name) bool { + _, ok := ro.singleDef[n] + result := !ok + if consistencyCheckEnabled { + checkReassignedResult(n, result) + } + return result +} From 78d037b0e016260819f2ff1dac745eda71070a18 Mon Sep 17 00:00:00 2001 From: qiulaidongfeng <2645477756@qq.com> Date: Mon, 20 Nov 2023 23:08:53 +0000 Subject: [PATCH 05/30] os: avoid TestFileChdir fail when GOROOT is a symbolic link If GOROOT is a symbolic link, the paths obtained from the first and second Getwd of TestFileChdir are different, and this CL fixes the test failure in this situation. Fixes #64281 Change-Id: I53026b6c54a54be08833396e2c7081ca3ab8c282 GitHub-Last-Rev: 5cc418e6255f6fa530e5a43e3b4d96759e604571 GitHub-Pull-Request: golang/go#64001 Reviewed-on: https://go-review.googlesource.com/c/go/+/540521 Reviewed-by: Michael Knyszek TryBot-Result: Gopher Robot Auto-Submit: Bryan Mills Reviewed-by: Bryan Mills LUCI-TryBot-Result: Go LUCI --- src/os/os_test.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/os/os_test.go b/src/os/os_test.go index ae12b9ce1b..7e0e0b90be 100644 --- a/src/os/os_test.go +++ b/src/os/os_test.go @@ -1620,8 +1620,17 @@ func TestFileChdir(t *testing.T) { if err != nil { t.Fatalf("Getwd: %s", err) } - if !equal(wdNew, wd) { - t.Fatalf("fd.Chdir failed, got %s, want %s", wdNew, wd) + + wdInfo, err := fd.Stat() + if err != nil { + t.Fatal(err) + } + newInfo, err := Stat(wdNew) + if err != nil { + t.Fatal(err) + } + if !SameFile(wdInfo, newInfo) { + t.Fatalf("fd.Chdir failed: got %s, want %s", wdNew, wd) } } From 8eecf26e3f13192be66e908cc55646b7f71c568c Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Tue, 21 Nov 2023 16:37:07 +0100 Subject: [PATCH 06/30] crypto/tls: disable ExportKeyingMaterial without EMS Fixes #43922 Change-Id: Idaad7daa6784807ae3a5e4d944e88e13d01fd0b2 Reviewed-on: https://go-review.googlesource.com/c/go/+/544155 Reviewed-by: Michael Knyszek Reviewed-by: Roland Shoemaker LUCI-TryBot-Result: Go LUCI Auto-Submit: Filippo Valsorda --- doc/godebug.md | 6 ++++++ src/crypto/tls/common.go | 10 ++++++---- src/crypto/tls/conn.go | 13 ++++++++++++- src/crypto/tls/prf.go | 11 +++++++++-- src/internal/godebugs/table.go | 1 + src/runtime/metrics/doc.go | 4 ++++ 6 files changed, 38 insertions(+), 7 deletions(-) diff --git a/doc/godebug.md b/doc/godebug.md index 9235635bdd..50033b6f17 100644 --- a/doc/godebug.md +++ b/doc/godebug.md @@ -159,6 +159,12 @@ Go 1.22 changed the default TLS cipher suites used by clients and servers when not explicitly configured, removing the cipher suites which used RSA based key exchange. The default can be revert using the [`tlsrsakex` setting](/pkg/crypto/tls/#Config). +Go 1.22 disabled +[`ConnectionState.ExportKeyingMaterial`](/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial) +when the connection supports neither TLS 1.3 nor Extended Master Secret +(implemented in Go 1.21). It can be reenabled with the [`tlsunsafeekm` +setting](/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial). + ### Go 1.21 Go 1.21 made it a run-time error to call `panic` with a nil interface value, diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go index 6058824ded..faa460e7fa 100644 --- a/src/crypto/tls/common.go +++ b/src/crypto/tls/common.go @@ -304,11 +304,13 @@ type ConnectionState struct { // ExportKeyingMaterial returns length bytes of exported key material in a new // slice as defined in RFC 5705. If context is nil, it is not used as part of // the seed. If the connection was set to allow renegotiation via -// Config.Renegotiation, this function will return an error. +// Config.Renegotiation, or if the connections supports neither TLS 1.3 nor +// Extended Master Secret, this function will return an error. // -// There are conditions in which the returned values might not be unique to a -// connection. See the Security Considerations sections of RFC 5705 and RFC 7627, -// and https://mitls.org/pages/attacks/3SHAKE#channelbindings. +// Exporting key material without Extended Master Secret or TLS 1.3 was disabled +// in Go 1.22 due to security issues (see the Security Considerations sections +// of RFC 5705 and RFC 7627), but can be re-enabled with the GODEBUG setting +// tlsunsafeekm=1. func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) { return cs.ekm(label, context, length) } diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go index 647e5b85b6..3e8832f947 100644 --- a/src/crypto/tls/conn.go +++ b/src/crypto/tls/conn.go @@ -15,6 +15,7 @@ import ( "errors" "fmt" "hash" + "internal/godebug" "io" "net" "sync" @@ -1599,6 +1600,8 @@ func (c *Conn) ConnectionState() ConnectionState { return c.connectionStateLocked() } +var ekmgodebug = godebug.New("tlsunsafeekm") + func (c *Conn) connectionStateLocked() ConnectionState { var state ConnectionState state.HandshakeComplete = c.isHandshakeComplete.Load() @@ -1620,7 +1623,15 @@ func (c *Conn) connectionStateLocked() ConnectionState { } } if c.config.Renegotiation != RenegotiateNever { - state.ekm = noExportedKeyingMaterial + state.ekm = noEKMBecauseRenegotiation + } else if c.vers != VersionTLS13 && !c.extMasterSecret { + state.ekm = func(label string, context []byte, length int) ([]byte, error) { + if ekmgodebug.Value() == "1" { + ekmgodebug.IncNonDefault() + return c.ekm(label, context, length) + } + return noEKMBecauseNoEMS(label, context, length) + } } else { state.ekm = c.ekm } diff --git a/src/crypto/tls/prf.go b/src/crypto/tls/prf.go index 20bac96e86..a7fa3370e6 100644 --- a/src/crypto/tls/prf.go +++ b/src/crypto/tls/prf.go @@ -252,13 +252,20 @@ func (h *finishedHash) discardHandshakeBuffer() { h.buffer = nil } -// noExportedKeyingMaterial is used as a value of +// noEKMBecauseRenegotiation is used as a value of // ConnectionState.ekm when renegotiation is enabled and thus // we wish to fail all key-material export requests. -func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) { +func noEKMBecauseRenegotiation(label string, context []byte, length int) ([]byte, error) { return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled") } +// noEKMBecauseNoEMS is used as a value of ConnectionState.ekm when Extended +// Master Secret is not negotiated and thus we wish to fail all key-material +// export requests. +func noEKMBecauseNoEMS(label string, context []byte, length int) ([]byte, error) { + return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when neither TLS 1.3 nor Extended Master Secret are negotiated; override with GODEBUG=tlsunsafeekm=1") +} + // ekmFromMasterSecret generates exported keying material as defined in RFC 5705. func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) { return func(label string, context []byte, length int) ([]byte, error) { diff --git a/src/internal/godebugs/table.go b/src/internal/godebugs/table.go index 92a0d089ca..3a76214b39 100644 --- a/src/internal/godebugs/table.go +++ b/src/internal/godebugs/table.go @@ -48,6 +48,7 @@ var All = []Info{ {Name: "tls10server", Package: "crypto/tls", Changed: 22, Old: "1"}, {Name: "tlsmaxrsasize", Package: "crypto/tls"}, {Name: "tlsrsakex", Package: "crypto/tls", Changed: 22, Old: "1"}, + {Name: "tlsunsafeekm", Package: "crypto/tls", Changed: 22, Old: "1"}, {Name: "x509sha1", Package: "crypto/x509"}, {Name: "x509usefallbackroots", Package: "crypto/x509"}, {Name: "zipinsecurepath", Package: "archive/zip"}, diff --git a/src/runtime/metrics/doc.go b/src/runtime/metrics/doc.go index 5be6c32bfa..8df475666e 100644 --- a/src/runtime/metrics/doc.go +++ b/src/runtime/metrics/doc.go @@ -314,6 +314,10 @@ Below is the full list of supported metrics, ordered lexicographically. The number of non-default behaviors executed by the crypto/tls package due to a non-default GODEBUG=tlsrsakex=... setting. + /godebug/non-default-behavior/tlsunsafeekm:events + The number of non-default behaviors executed by the crypto/tls + package due to a non-default GODEBUG=tlsunsafeekm=... setting. + /godebug/non-default-behavior/x509sha1:events The number of non-default behaviors executed by the crypto/x509 package due to a non-default GODEBUG=x509sha1=... setting. From bbcd85528cbad2dca72378181cb230e59a43ef80 Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Fri, 27 Oct 2023 08:58:16 -0400 Subject: [PATCH 07/30] cmd/compile/internal/inline: rework use of ir.StaticValue When running the code to compute function properties that feed inlining heuristics, the existing heuristics implementation makes fairly extensive use of ir.StaticValue and ir.Reassigned to sharpen the analysis. These calls turn out to cause a significant compile time increase, due to the fact that each call can potentially walk every node in the IR for the function. To help with this problem, switch the heuristics code over to using the new "batch mode" reassignment helper added in the previous CL. Change-Id: Ib15a62416134386e34b7cfa1130a4b413a37b225 Reviewed-on: https://go-review.googlesource.com/c/go/+/537977 LUCI-TryBot-Result: Go LUCI Reviewed-by: Matthew Dempsky --- .../internal/inline/inlheur/analyze.go | 15 +- .../inline/inlheur/analyze_func_callsites.go | 144 ++++++++++-------- .../inline/inlheur/analyze_func_params.go | 16 +- .../inline/inlheur/analyze_func_returns.go | 122 ++++----------- .../compile/internal/inline/inlheur/names.go | 129 ++++++++++++++++ .../inline/inlheur/score_callresult_uses.go | 6 +- .../internal/inline/inlheur/scoring.go | 40 +++-- 7 files changed, 287 insertions(+), 185 deletions(-) create mode 100644 src/cmd/compile/internal/inline/inlheur/names.go diff --git a/src/cmd/compile/internal/inline/inlheur/analyze.go b/src/cmd/compile/internal/inline/inlheur/analyze.go index 6c3db92afe..93073b9851 100644 --- a/src/cmd/compile/internal/inline/inlheur/analyze.go +++ b/src/cmd/compile/internal/inline/inlheur/analyze.go @@ -98,12 +98,13 @@ func AnalyzeFunc(fn *ir.Func, canInline func(*ir.Func), budgetForFunc func(*ir.F // inlinable; if it is over the default hairyness limit and it // doesn't have any interesting properties, then we don't want // the overhead of writing out its inline body. + nameFinder := newNameFinder(fn) for i := len(funcs) - 1; i >= 0; i-- { f := funcs[i] if f.OClosure != nil && !f.InlinabilityChecked() { canInline(f) } - funcProps := analyzeFunc(f, inlineMaxBudget) + funcProps := analyzeFunc(f, inlineMaxBudget, nameFinder) revisitInlinability(f, funcProps, budgetForFunc) if f.Inl != nil { f.Inl.Properties = funcProps.SerializeToString() @@ -122,11 +123,11 @@ func TearDown() { scoreCallsCache.csl = nil } -func analyzeFunc(fn *ir.Func, inlineMaxBudget int) *FuncProps { +func analyzeFunc(fn *ir.Func, inlineMaxBudget int, nf *nameFinder) *FuncProps { if funcInlHeur, ok := fpmap[fn]; ok { return funcInlHeur.props } - funcProps, fcstab := computeFuncProps(fn, inlineMaxBudget) + funcProps, fcstab := computeFuncProps(fn, inlineMaxBudget, nf) file, line := fnFileLine(fn) entry := fnInlHeur{ fname: fn.Sym().Name, @@ -163,7 +164,7 @@ func revisitInlinability(fn *ir.Func, funcProps *FuncProps, budgetForFunc func(* // computeFuncProps examines the Go function 'fn' and computes for it // a function "properties" object, to be used to drive inlining // heuristics. See comments on the FuncProps type for more info. -func computeFuncProps(fn *ir.Func, inlineMaxBudget int) (*FuncProps, CallSiteTab) { +func computeFuncProps(fn *ir.Func, inlineMaxBudget int, nf *nameFinder) (*FuncProps, CallSiteTab) { if debugTrace&debugTraceFuncs != 0 { fmt.Fprintf(os.Stderr, "=-= starting analysis of func %v:\n%+v\n", fn, fn) @@ -171,13 +172,13 @@ func computeFuncProps(fn *ir.Func, inlineMaxBudget int) (*FuncProps, CallSiteTab funcProps := new(FuncProps) ffa := makeFuncFlagsAnalyzer(fn) analyzers := []propAnalyzer{ffa} - analyzers = addResultsAnalyzer(fn, analyzers, funcProps, inlineMaxBudget) - analyzers = addParamsAnalyzer(fn, analyzers, funcProps) + analyzers = addResultsAnalyzer(fn, analyzers, funcProps, inlineMaxBudget, nf) + analyzers = addParamsAnalyzer(fn, analyzers, funcProps, nf) runAnalyzersOnFunction(fn, analyzers) for _, a := range analyzers { a.setResults(funcProps) } - cstab := computeCallSiteTable(fn, fn.Body, nil, ffa.panicPathTable(), 0) + cstab := computeCallSiteTable(fn, fn.Body, nil, ffa.panicPathTable(), 0, nf) return funcProps, cstab } diff --git a/src/cmd/compile/internal/inline/inlheur/analyze_func_callsites.go b/src/cmd/compile/internal/inline/inlheur/analyze_func_callsites.go index 3e285d5181..36ebe18b82 100644 --- a/src/cmd/compile/internal/inline/inlheur/analyze_func_callsites.go +++ b/src/cmd/compile/internal/inline/inlheur/analyze_func_callsites.go @@ -14,23 +14,37 @@ import ( ) type callSiteAnalyzer struct { + fn *ir.Func + *nameFinder +} + +type callSiteTableBuilder struct { + fn *ir.Func + *nameFinder cstab CallSiteTab - fn *ir.Func ptab map[ir.Node]pstate nstack []ir.Node loopNest int isInit bool } -func makeCallSiteAnalyzer(fn *ir.Func, cstab CallSiteTab, ptab map[ir.Node]pstate, loopNestingLevel int) *callSiteAnalyzer { - isInit := fn.IsPackageInit() || strings.HasPrefix(fn.Sym().Name, "init.") +func makeCallSiteAnalyzer(fn *ir.Func) *callSiteAnalyzer { return &callSiteAnalyzer{ - fn: fn, - cstab: cstab, - ptab: ptab, - isInit: isInit, - loopNest: loopNestingLevel, - nstack: []ir.Node{fn}, + fn: fn, + nameFinder: newNameFinder(fn), + } +} + +func makeCallSiteTableBuilder(fn *ir.Func, cstab CallSiteTab, ptab map[ir.Node]pstate, loopNestingLevel int, nf *nameFinder) *callSiteTableBuilder { + isInit := fn.IsPackageInit() || strings.HasPrefix(fn.Sym().Name, "init.") + return &callSiteTableBuilder{ + fn: fn, + cstab: cstab, + ptab: ptab, + isInit: isInit, + loopNest: loopNestingLevel, + nstack: []ir.Node{fn}, + nameFinder: nf, } } @@ -39,22 +53,22 @@ func makeCallSiteAnalyzer(fn *ir.Func, cstab CallSiteTab, ptab map[ir.Node]pstat // specific subtree within the AST for a function. The main intended // use cases are for 'region' to be either A) an entire function body, // or B) an inlined call expression. -func computeCallSiteTable(fn *ir.Func, region ir.Nodes, cstab CallSiteTab, ptab map[ir.Node]pstate, loopNestingLevel int) CallSiteTab { - csa := makeCallSiteAnalyzer(fn, cstab, ptab, loopNestingLevel) +func computeCallSiteTable(fn *ir.Func, region ir.Nodes, cstab CallSiteTab, ptab map[ir.Node]pstate, loopNestingLevel int, nf *nameFinder) CallSiteTab { + cstb := makeCallSiteTableBuilder(fn, cstab, ptab, loopNestingLevel, nf) var doNode func(ir.Node) bool doNode = func(n ir.Node) bool { - csa.nodeVisitPre(n) + cstb.nodeVisitPre(n) ir.DoChildren(n, doNode) - csa.nodeVisitPost(n) + cstb.nodeVisitPost(n) return false } for _, n := range region { doNode(n) } - return csa.cstab + return cstb.cstab } -func (csa *callSiteAnalyzer) flagsForNode(call *ir.CallExpr) CSPropBits { +func (cstb *callSiteTableBuilder) flagsForNode(call *ir.CallExpr) CSPropBits { var r CSPropBits if debugTrace&debugTraceCalls != 0 { @@ -63,21 +77,21 @@ func (csa *callSiteAnalyzer) flagsForNode(call *ir.CallExpr) CSPropBits { } // Set a bit if this call is within a loop. - if csa.loopNest > 0 { + if cstb.loopNest > 0 { r |= CallSiteInLoop } // Set a bit if the call is within an init function (either // compiler-generated or user-written). - if csa.isInit { + if cstb.isInit { r |= CallSiteInInitFunc } // Decide whether to apply the panic path heuristic. Hack: don't // apply this heuristic in the function "main.main" (mostly just // to avoid annoying users). - if !isMainMain(csa.fn) { - r = csa.determinePanicPathBits(call, r) + if !isMainMain(cstb.fn) { + r = cstb.determinePanicPathBits(call, r) } return r @@ -88,15 +102,15 @@ func (csa *callSiteAnalyzer) flagsForNode(call *ir.CallExpr) CSPropBits { // panic/exit. Do this by walking back up the node stack to see if we // can find either A) an enclosing panic, or B) a statement node that // we've determined leads to a panic/exit. -func (csa *callSiteAnalyzer) determinePanicPathBits(call ir.Node, r CSPropBits) CSPropBits { - csa.nstack = append(csa.nstack, call) +func (cstb *callSiteTableBuilder) determinePanicPathBits(call ir.Node, r CSPropBits) CSPropBits { + cstb.nstack = append(cstb.nstack, call) defer func() { - csa.nstack = csa.nstack[:len(csa.nstack)-1] + cstb.nstack = cstb.nstack[:len(cstb.nstack)-1] }() - for ri := range csa.nstack[:len(csa.nstack)-1] { - i := len(csa.nstack) - ri - 1 - n := csa.nstack[i] + for ri := range cstb.nstack[:len(cstb.nstack)-1] { + i := len(cstb.nstack) - ri - 1 + n := cstb.nstack[i] _, isCallExpr := n.(*ir.CallExpr) _, isStmt := n.(ir.Stmt) if isCallExpr { @@ -104,7 +118,7 @@ func (csa *callSiteAnalyzer) determinePanicPathBits(call ir.Node, r CSPropBits) } if debugTrace&debugTraceCalls != 0 { - ps, inps := csa.ptab[n] + ps, inps := cstb.ptab[n] fmt.Fprintf(os.Stderr, "=-= callpar %d op=%s ps=%s inptab=%v stmt=%v\n", i, n.Op().String(), ps.String(), inps, isStmt) } @@ -112,7 +126,7 @@ func (csa *callSiteAnalyzer) determinePanicPathBits(call ir.Node, r CSPropBits) r |= CallSiteOnPanicPath break } - if v, ok := csa.ptab[n]; ok { + if v, ok := cstb.ptab[n]; ok { if v == psCallsPanic { r |= CallSiteOnPanicPath break @@ -126,16 +140,15 @@ func (csa *callSiteAnalyzer) determinePanicPathBits(call ir.Node, r CSPropBits) } // propsForArg returns property bits for a given call argument expression arg. -func (csa *callSiteAnalyzer) propsForArg(arg ir.Node) ActualExprPropBits { - _, islit := isLiteral(arg) - if islit { +func (cstb *callSiteTableBuilder) propsForArg(arg ir.Node) ActualExprPropBits { + if cval := cstb.constValue(arg); cval != nil { return ActualExprConstant } - if isConcreteConvIface(arg) { + if cstb.isConcreteConvIface(arg) { return ActualExprIsConcreteConvIface } - fname, isfunc, _ := isFuncName(arg) - if isfunc { + fname := cstb.funcName(arg) + if fname != nil { if fn := fname.Func; fn != nil && typecheck.HaveInlineBody(fn) { return ActualExprIsInlinableFunc } @@ -149,11 +162,11 @@ func (csa *callSiteAnalyzer) propsForArg(arg ir.Node) ActualExprPropBits { // expression; these will be stored in the CallSite object for a given // call and then consulted when scoring. If no arg has any interesting // properties we try to save some space and return a nil slice. -func (csa *callSiteAnalyzer) argPropsForCall(ce *ir.CallExpr) []ActualExprPropBits { +func (cstb *callSiteTableBuilder) argPropsForCall(ce *ir.CallExpr) []ActualExprPropBits { rv := make([]ActualExprPropBits, len(ce.Args)) somethingInteresting := false for idx := range ce.Args { - argProp := csa.propsForArg(ce.Args[idx]) + argProp := cstb.propsForArg(ce.Args[idx]) somethingInteresting = somethingInteresting || (argProp != 0) rv[idx] = argProp } @@ -163,9 +176,9 @@ func (csa *callSiteAnalyzer) argPropsForCall(ce *ir.CallExpr) []ActualExprPropBi return rv } -func (csa *callSiteAnalyzer) addCallSite(callee *ir.Func, call *ir.CallExpr) { - flags := csa.flagsForNode(call) - argProps := csa.argPropsForCall(call) +func (cstb *callSiteTableBuilder) addCallSite(callee *ir.Func, call *ir.CallExpr) { + flags := cstb.flagsForNode(call) + argProps := cstb.argPropsForCall(call) if debugTrace&debugTraceCalls != 0 { fmt.Fprintf(os.Stderr, "=-= props %+v for call %v\n", argProps, call) } @@ -173,12 +186,12 @@ func (csa *callSiteAnalyzer) addCallSite(callee *ir.Func, call *ir.CallExpr) { cs := &CallSite{ Call: call, Callee: callee, - Assign: csa.containingAssignment(call), + Assign: cstb.containingAssignment(call), ArgProps: argProps, Flags: flags, - ID: uint(len(csa.cstab)), + ID: uint(len(cstb.cstab)), } - if _, ok := csa.cstab[call]; ok { + if _, ok := cstb.cstab[call]; ok { fmt.Fprintf(os.Stderr, "*** cstab duplicate entry at: %s\n", fmtFullPos(call.Pos())) fmt.Fprintf(os.Stderr, "*** call: %+v\n", call) @@ -189,38 +202,38 @@ func (csa *callSiteAnalyzer) addCallSite(callee *ir.Func, call *ir.CallExpr) { // on heuristics. cs.Score = int(callee.Inl.Cost) - if csa.cstab == nil { - csa.cstab = make(CallSiteTab) + if cstb.cstab == nil { + cstb.cstab = make(CallSiteTab) } - csa.cstab[call] = cs + cstb.cstab[call] = cs if debugTrace&debugTraceCalls != 0 { fmt.Fprintf(os.Stderr, "=-= added callsite: caller=%v callee=%v n=%s\n", - csa.fn, callee, fmtFullPos(call.Pos())) + cstb.fn, callee, fmtFullPos(call.Pos())) } } -func (csa *callSiteAnalyzer) nodeVisitPre(n ir.Node) { +func (cstb *callSiteTableBuilder) nodeVisitPre(n ir.Node) { switch n.Op() { case ir.ORANGE, ir.OFOR: if !hasTopLevelLoopBodyReturnOrBreak(loopBody(n)) { - csa.loopNest++ + cstb.loopNest++ } case ir.OCALLFUNC: ce := n.(*ir.CallExpr) callee := pgo.DirectCallee(ce.Fun) if callee != nil && callee.Inl != nil { - csa.addCallSite(callee, ce) + cstb.addCallSite(callee, ce) } } - csa.nstack = append(csa.nstack, n) + cstb.nstack = append(cstb.nstack, n) } -func (csa *callSiteAnalyzer) nodeVisitPost(n ir.Node) { - csa.nstack = csa.nstack[:len(csa.nstack)-1] +func (cstb *callSiteTableBuilder) nodeVisitPost(n ir.Node) { + cstb.nstack = cstb.nstack[:len(cstb.nstack)-1] switch n.Op() { case ir.ORANGE, ir.OFOR: if !hasTopLevelLoopBodyReturnOrBreak(loopBody(n)) { - csa.loopNest-- + cstb.loopNest-- } } } @@ -281,8 +294,8 @@ func hasTopLevelLoopBodyReturnOrBreak(loopBody ir.Nodes) bool { // call to a pair of auto-temps, then the second one assigning the // auto-temps to the user-visible vars. This helper will return the // second (outer) of these two. -func (csa *callSiteAnalyzer) containingAssignment(n ir.Node) ir.Node { - parent := csa.nstack[len(csa.nstack)-1] +func (cstb *callSiteTableBuilder) containingAssignment(n ir.Node) ir.Node { + parent := cstb.nstack[len(cstb.nstack)-1] // assignsOnlyAutoTemps returns TRUE of the specified OAS2FUNC // node assigns only auto-temps. @@ -315,12 +328,12 @@ func (csa *callSiteAnalyzer) containingAssignment(n ir.Node) ir.Node { // OAS1({x,y},OCONVNOP(OAS2FUNC({auto1,auto2},OCALLFUNC(bar)))) // if assignsOnlyAutoTemps(parent) { - par2 := csa.nstack[len(csa.nstack)-2] + par2 := cstb.nstack[len(cstb.nstack)-2] if par2.Op() == ir.OAS2 { return par2 } if par2.Op() == ir.OCONVNOP { - par3 := csa.nstack[len(csa.nstack)-3] + par3 := cstb.nstack[len(cstb.nstack)-3] if par3.Op() == ir.OAS2 { return par3 } @@ -378,18 +391,23 @@ func UpdateCallsiteTable(callerfn *ir.Func, n *ir.CallExpr, ic *ir.InlinedCallEx loopNestLevel = 1 } ptab := map[ir.Node]pstate{ic: icp} - icstab := computeCallSiteTable(callerfn, ic.Body, nil, ptab, loopNestLevel) + nf := newNameFinder(nil) + icstab := computeCallSiteTable(callerfn, ic.Body, nil, ptab, loopNestLevel, nf) // Record parent callsite. This is primarily for debug output. for _, cs := range icstab { cs.parent = oldcs } - // Score the calls in the inlined body. Note the setting of "doCallResults" - // to false here: at the moment there isn't any easy way to localize - // or region-ize the work done by "rescoreBasedOnCallResultUses", which - // currently does a walk over the entire function to look for uses - // of a given set of results. + // Score the calls in the inlined body. Note the setting of + // "doCallResults" to false here: at the moment there isn't any + // easy way to localize or region-ize the work done by + // "rescoreBasedOnCallResultUses", which currently does a walk + // over the entire function to look for uses of a given set of + // results. Similarly we're passing nil to makeCallSiteAnalyzer, + // so as to run name finding without the use of static value & + // friends. + csa := makeCallSiteAnalyzer(nil) const doCallResults = false - scoreCallsRegion(callerfn, ic.Body, icstab, doCallResults, ic) + csa.scoreCallsRegion(callerfn, ic.Body, icstab, doCallResults, ic) } diff --git a/src/cmd/compile/internal/inline/inlheur/analyze_func_params.go b/src/cmd/compile/internal/inline/inlheur/analyze_func_params.go index 0ce0af43a2..5e61485532 100644 --- a/src/cmd/compile/internal/inline/inlheur/analyze_func_params.go +++ b/src/cmd/compile/internal/inline/inlheur/analyze_func_params.go @@ -19,6 +19,7 @@ type paramsAnalyzer struct { params []*ir.Name top []bool *condLevelTracker + *nameFinder } // getParams returns an *ir.Name slice containing all params for the @@ -34,8 +35,8 @@ func getParams(fn *ir.Func) []*ir.Name { // new list. If the function in question doesn't have any interesting // parameters then the analyzer list is returned unchanged, and the // params flags in "fp" are updated accordingly. -func addParamsAnalyzer(fn *ir.Func, analyzers []propAnalyzer, fp *FuncProps) []propAnalyzer { - pa, props := makeParamsAnalyzer(fn) +func addParamsAnalyzer(fn *ir.Func, analyzers []propAnalyzer, fp *FuncProps, nf *nameFinder) []propAnalyzer { + pa, props := makeParamsAnalyzer(fn, nf) if pa != nil { analyzers = append(analyzers, pa) } else { @@ -48,7 +49,7 @@ func addParamsAnalyzer(fn *ir.Func, analyzers []propAnalyzer, fp *FuncProps) []p // of function fn. If the function doesn't have any interesting // params, a nil helper is returned along with a set of default param // flags for the func. -func makeParamsAnalyzer(fn *ir.Func) (*paramsAnalyzer, []ParamPropBits) { +func makeParamsAnalyzer(fn *ir.Func, nf *nameFinder) (*paramsAnalyzer, []ParamPropBits) { params := getParams(fn) // includes receiver if applicable if len(params) == 0 { return nil, nil @@ -98,6 +99,7 @@ func makeParamsAnalyzer(fn *ir.Func) (*paramsAnalyzer, []ParamPropBits) { params: params, top: top, condLevelTracker: new(condLevelTracker), + nameFinder: nf, } return pa, nil } @@ -162,7 +164,7 @@ func (pa *paramsAnalyzer) callCheckParams(ce *ir.CallExpr) { return } sel := ce.Fun.(*ir.SelectorExpr) - r := ir.StaticValue(sel.X) + r := pa.staticValue(sel.X) if r.Op() != ir.ONAME { return } @@ -193,8 +195,8 @@ func (pa *paramsAnalyzer) callCheckParams(ce *ir.CallExpr) { return name == p, false }) } else { - cname, isFunc, _ := isFuncName(called) - if isFunc { + cname := pa.funcName(called) + if cname != nil { pa.deriveFlagsFromCallee(ce, cname.Func) } } @@ -238,7 +240,7 @@ func (pa *paramsAnalyzer) deriveFlagsFromCallee(ce *ir.CallExpr, callee *ir.Func } // See if one of the caller's parameters is flowing unmodified // into this actual expression. - r := ir.StaticValue(arg) + r := pa.staticValue(arg) if r.Op() != ir.ONAME { return } diff --git a/src/cmd/compile/internal/inline/inlheur/analyze_func_returns.go b/src/cmd/compile/internal/inline/inlheur/analyze_func_returns.go index 58b0f54697..2aaa68d1b7 100644 --- a/src/cmd/compile/internal/inline/inlheur/analyze_func_returns.go +++ b/src/cmd/compile/internal/inline/inlheur/analyze_func_returns.go @@ -20,6 +20,7 @@ type resultsAnalyzer struct { props []ResultPropBits values []resultVal inlineMaxBudget int + *nameFinder } // resultVal captures information about a specific result returned from @@ -28,7 +29,7 @@ type resultsAnalyzer struct { // the same function, etc. This container stores info on a the specific // scenarios we're looking for. type resultVal struct { - lit constant.Value + cval constant.Value fn *ir.Name fnClo bool top bool @@ -40,8 +41,8 @@ type resultVal struct { // new list. If the function in question doesn't have any returns (or // any interesting returns) then the analyzer list is left as is, and // the result flags in "fp" are updated accordingly. -func addResultsAnalyzer(fn *ir.Func, analyzers []propAnalyzer, fp *FuncProps, inlineMaxBudget int) []propAnalyzer { - ra, props := makeResultsAnalyzer(fn, inlineMaxBudget) +func addResultsAnalyzer(fn *ir.Func, analyzers []propAnalyzer, fp *FuncProps, inlineMaxBudget int, nf *nameFinder) []propAnalyzer { + ra, props := makeResultsAnalyzer(fn, inlineMaxBudget, nf) if ra != nil { analyzers = append(analyzers, ra) } else { @@ -54,7 +55,7 @@ func addResultsAnalyzer(fn *ir.Func, analyzers []propAnalyzer, fp *FuncProps, in // in function fn. If the function doesn't have any interesting // results, a nil helper is returned along with a set of default // result flags for the func. -func makeResultsAnalyzer(fn *ir.Func, inlineMaxBudget int) (*resultsAnalyzer, []ResultPropBits) { +func makeResultsAnalyzer(fn *ir.Func, inlineMaxBudget int, nf *nameFinder) (*resultsAnalyzer, []ResultPropBits) { results := fn.Type().Results() if len(results) == 0 { return nil, nil @@ -84,6 +85,7 @@ func makeResultsAnalyzer(fn *ir.Func, inlineMaxBudget int) (*resultsAnalyzer, [] props: props, values: vals, inlineMaxBudget: inlineMaxBudget, + nameFinder: nf, } return ra, nil } @@ -143,29 +145,6 @@ func (ra *resultsAnalyzer) nodeVisitPost(n ir.Node) { } } -// isFuncName returns the *ir.Name for the func or method -// corresponding to node 'n', along with a boolean indicating success, -// and another boolean indicating whether the func is closure. -func isFuncName(n ir.Node) (*ir.Name, bool, bool) { - sv := ir.StaticValue(n) - if sv.Op() == ir.ONAME { - name := sv.(*ir.Name) - if name.Sym() != nil && name.Class == ir.PFUNC { - return name, true, false - } - } - if sv.Op() == ir.OCLOSURE { - cloex := sv.(*ir.ClosureExpr) - return cloex.Func.Nname, true, true - } - if sv.Op() == ir.OMETHEXPR { - if mn := ir.MethodExprName(sv); mn != nil { - return mn, true, false - } - } - return nil, false, false -} - // analyzeResult examines the expression 'n' being returned as the // 'ii'th argument in some return statement to see whether has // interesting characteristics (for example, returns a constant), then @@ -173,18 +152,22 @@ func isFuncName(n ir.Node) (*ir.Name, bool, bool) { // previous result (for the given return slot) that we've already // processed. func (ra *resultsAnalyzer) analyzeResult(ii int, n ir.Node) { - isAllocMem := isAllocatedMem(n) - isConcConvItf := isConcreteConvIface(n) - lit, isConst := isLiteral(n) - rfunc, isFunc, isClo := isFuncName(n) + isAllocMem := ra.isAllocatedMem(n) + isConcConvItf := ra.isConcreteConvIface(n) + constVal := ra.constValue(n) + isConst := (constVal != nil) + isNil := ra.isNil(n) + rfunc := ra.funcName(n) + isFunc := (rfunc != nil) + isClo := (rfunc != nil && rfunc.Func.OClosure != nil) curp := ra.props[ii] - dprops, isDerivedFromCall := deriveReturnFlagsFromCallee(n) + dprops, isDerivedFromCall := ra.deriveReturnFlagsFromCallee(n) newp := ResultNoInfo - var newlit constant.Value + var newcval constant.Value var newfunc *ir.Name if debugTrace&debugTraceResults != 0 { - fmt.Fprintf(os.Stderr, "=-= %v: analyzeResult n=%s ismem=%v isconcconv=%v isconst=%v isfunc=%v isclo=%v\n", ir.Line(n), n.Op().String(), isAllocMem, isConcConvItf, isConst, isFunc, isClo) + fmt.Fprintf(os.Stderr, "=-= %v: analyzeResult n=%s ismem=%v isconcconv=%v isconst=%v isnil=%v isfunc=%v isclo=%v\n", ir.Line(n), n.Op().String(), isAllocMem, isConcConvItf, isConst, isNil, isFunc, isClo) } if ra.values[ii].top { @@ -201,7 +184,10 @@ func (ra *resultsAnalyzer) analyzeResult(ii int, n ir.Node) { newfunc = rfunc case isConst: newp = ResultAlwaysSameConstant - newlit = lit + newcval = constVal + case isNil: + newp = ResultAlwaysSameConstant + newcval = nil case isDerivedFromCall: newp = dprops ra.values[ii].derived = true @@ -214,17 +200,20 @@ func (ra *resultsAnalyzer) analyzeResult(ii int, n ir.Node) { // the previous returns. switch curp { case ResultIsAllocatedMem: - if isAllocatedMem(n) { + if isAllocMem { newp = ResultIsAllocatedMem } case ResultIsConcreteTypeConvertedToInterface: - if isConcreteConvIface(n) { + if isConcConvItf { newp = ResultIsConcreteTypeConvertedToInterface } case ResultAlwaysSameConstant: - if isConst && isSameLiteral(lit, ra.values[ii].lit) { + if isNil && ra.values[ii].cval == nil { newp = ResultAlwaysSameConstant - newlit = lit + newcval = nil + } else if isConst && constant.Compare(constVal, token.EQL, ra.values[ii].cval) { + newp = ResultAlwaysSameConstant + newcval = constVal } case ResultAlwaysSameFunc: if isFunc && isSameFuncName(rfunc, ra.values[ii].fn) { @@ -236,7 +225,7 @@ func (ra *resultsAnalyzer) analyzeResult(ii int, n ir.Node) { } ra.values[ii].fn = newfunc ra.values[ii].fnClo = isClo - ra.values[ii].lit = newlit + ra.values[ii].cval = newcval ra.props[ii] = newp if debugTrace&debugTraceResults != 0 { @@ -245,15 +234,6 @@ func (ra *resultsAnalyzer) analyzeResult(ii int, n ir.Node) { } } -func isAllocatedMem(n ir.Node) bool { - sv := ir.StaticValue(n) - switch sv.Op() { - case ir.OMAKESLICE, ir.ONEW, ir.OPTRLIT, ir.OSLICELIT: - return true - } - return false -} - // deriveReturnFlagsFromCallee tries to set properties for a given // return result where we're returning call expression; return value // is a return property value and a boolean indicating whether the @@ -270,7 +250,7 @@ func isAllocatedMem(n ir.Node) bool { // set foo's return property to that of bar. In the case of "two", however, // even though each return path returns a constant, we don't know // whether the constants are identical, hence we need to be conservative. -func deriveReturnFlagsFromCallee(n ir.Node) (ResultPropBits, bool) { +func (ra *resultsAnalyzer) deriveReturnFlagsFromCallee(n ir.Node) (ResultPropBits, bool) { if n.Op() != ir.OCALLFUNC { return 0, false } @@ -282,8 +262,8 @@ func deriveReturnFlagsFromCallee(n ir.Node) (ResultPropBits, bool) { if called.Op() != ir.ONAME { return 0, false } - cname, isFunc, _ := isFuncName(called) - if !isFunc { + cname := ra.funcName(called) + if cname == nil { return 0, false } calleeProps := propsForFunc(cname.Func) @@ -295,41 +275,3 @@ func deriveReturnFlagsFromCallee(n ir.Node) (ResultPropBits, bool) { } return calleeProps.ResultFlags[0], true } - -func isLiteral(n ir.Node) (constant.Value, bool) { - sv := ir.StaticValue(n) - switch sv.Op() { - case ir.ONIL: - return nil, true - case ir.OLITERAL: - return sv.Val(), true - } - return nil, false -} - -// isSameLiteral checks to see if 'v1' and 'v2' correspond to the same -// literal value, or if they are both nil. -func isSameLiteral(v1, v2 constant.Value) bool { - if v1 == nil && v2 == nil { - return true - } - if v1 == nil || v2 == nil { - return false - } - return constant.Compare(v1, token.EQL, v2) -} - -func isConcreteConvIface(n ir.Node) bool { - sv := ir.StaticValue(n) - if sv.Op() != ir.OCONVIFACE { - return false - } - return !sv.(*ir.ConvExpr).X.Type().IsInterface() -} - -func isSameFuncName(v1, v2 *ir.Name) bool { - // NB: there are a few corner cases where pointer equality - // doesn't work here, but this should be good enough for - // our purposes here. - return v1 == v2 -} diff --git a/src/cmd/compile/internal/inline/inlheur/names.go b/src/cmd/compile/internal/inline/inlheur/names.go new file mode 100644 index 0000000000..022385087b --- /dev/null +++ b/src/cmd/compile/internal/inline/inlheur/names.go @@ -0,0 +1,129 @@ +// Copyright 2023 The Go 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 inlheur + +import ( + "cmd/compile/internal/ir" + "go/constant" +) + +// nameFinder provides a set of "isXXX" query methods for clients to +// ask whether a given AST node corresponds to a function, a constant +// value, and so on. These methods use an underlying ir.ReassignOracle +// to return more precise results in cases where an "interesting" +// value is assigned to a singly-defined local temp. Example: +// +// const q = 101 +// fq := func() int { return q } +// copyOfConstant := q +// copyOfFunc := f +// interestingCall(copyOfConstant, copyOfFunc) +// +// A name finder query method invoked on the arguments being passed to +// "interestingCall" will be able detect that 'copyOfConstant' always +// evaluates to a constant (even though it is in fact a PAUTO local +// variable). A given nameFinder can also operate without using +// ir.ReassignOracle (in cases where it is not practical to look +// at the entire function); in such cases queries will still work +// for explicit constant values and functions. +type nameFinder struct { + ro *ir.ReassignOracle +} + +// newNameFinder returns a new nameFinder object with a reassignment +// oracle initialized based on the function fn, or if fn is nil, +// without an underlying ReassignOracle. +func newNameFinder(fn *ir.Func) *nameFinder { + var ro *ir.ReassignOracle + if fn != nil { + ro = &ir.ReassignOracle{} + ro.Init(fn) + } + return &nameFinder{ro: ro} +} + +// funcName returns the *ir.Name for the func or method +// corresponding to node 'n', or nil if n can't be proven +// to contain a function value. +func (nf *nameFinder) funcName(n ir.Node) *ir.Name { + sv := n + if nf.ro != nil { + sv = nf.ro.StaticValue(n) + } + if name := ir.StaticCalleeName(sv); name != nil { + return name + } + return nil +} + +// isAllocatedMem returns true if node n corresponds to a memory +// allocation expression (make, new, or equivalent). +func (nf *nameFinder) isAllocatedMem(n ir.Node) bool { + sv := n + if nf.ro != nil { + sv = nf.ro.StaticValue(n) + } + switch sv.Op() { + case ir.OMAKESLICE, ir.ONEW, ir.OPTRLIT, ir.OSLICELIT: + return true + } + return false +} + +// constValue returns the underlying constant.Value for an AST node n +// if n is itself a constant value/expr, or if n is a singly assigned +// local containing constant expr/value (or nil not constant). +func (nf *nameFinder) constValue(n ir.Node) constant.Value { + sv := n + if nf.ro != nil { + sv = nf.ro.StaticValue(n) + } + if sv.Op() == ir.OLITERAL { + return sv.Val() + } + return nil +} + +// isNil returns whether n is nil (or singly +// assigned local containing nil). +func (nf *nameFinder) isNil(n ir.Node) bool { + sv := n + if nf.ro != nil { + sv = nf.ro.StaticValue(n) + } + return sv.Op() == ir.ONIL +} + +func (nf *nameFinder) staticValue(n ir.Node) ir.Node { + if nf.ro == nil { + return n + } + return nf.ro.StaticValue(n) +} + +func (nf *nameFinder) reassigned(n *ir.Name) bool { + if nf.ro == nil { + return true + } + return nf.ro.Reassigned(n) +} + +func (nf *nameFinder) isConcreteConvIface(n ir.Node) bool { + sv := n + if nf.ro != nil { + sv = nf.ro.StaticValue(n) + } + if sv.Op() != ir.OCONVIFACE { + return false + } + return !sv.(*ir.ConvExpr).X.Type().IsInterface() +} + +func isSameFuncName(v1, v2 *ir.Name) bool { + // NB: there are a few corner cases where pointer equality + // doesn't work here, but this should be good enough for + // our purposes here. + return v1 == v2 +} diff --git a/src/cmd/compile/internal/inline/inlheur/score_callresult_uses.go b/src/cmd/compile/internal/inline/inlheur/score_callresult_uses.go index 1d31f09ac0..b95ea37d59 100644 --- a/src/cmd/compile/internal/inline/inlheur/score_callresult_uses.go +++ b/src/cmd/compile/internal/inline/inlheur/score_callresult_uses.go @@ -46,7 +46,7 @@ type resultUseAnalyzer struct { // rescoreBasedOnCallResultUses examines how call results are used, // and tries to update the scores of calls based on how their results // are used in the function. -func rescoreBasedOnCallResultUses(fn *ir.Func, resultNameTab map[*ir.Name]resultPropAndCS, cstab CallSiteTab) { +func (csa *callSiteAnalyzer) rescoreBasedOnCallResultUses(fn *ir.Func, resultNameTab map[*ir.Name]resultPropAndCS, cstab CallSiteTab) { enableDebugTraceIfEnv() rua := &resultUseAnalyzer{ resultNameTab: resultNameTab, @@ -65,7 +65,7 @@ func rescoreBasedOnCallResultUses(fn *ir.Func, resultNameTab map[*ir.Name]result disableDebugTrace() } -func examineCallResults(cs *CallSite, resultNameTab map[*ir.Name]resultPropAndCS) map[*ir.Name]resultPropAndCS { +func (csa *callSiteAnalyzer) examineCallResults(cs *CallSite, resultNameTab map[*ir.Name]resultPropAndCS) map[*ir.Name]resultPropAndCS { if debugTrace&debugTraceScoring != 0 { fmt.Fprintf(os.Stderr, "=-= examining call results for %q\n", EncodeCallSiteKey(cs)) @@ -103,7 +103,7 @@ func examineCallResults(cs *CallSite, resultNameTab map[*ir.Name]resultPropAndCS if rprop&interesting == 0 { continue } - if ir.Reassigned(n) { + if csa.nameFinder.reassigned(n) { continue } if resultNameTab == nil { diff --git a/src/cmd/compile/internal/inline/inlheur/scoring.go b/src/cmd/compile/internal/inline/inlheur/scoring.go index 2b210fce8e..efbca79ae3 100644 --- a/src/cmd/compile/internal/inline/inlheur/scoring.go +++ b/src/cmd/compile/internal/inline/inlheur/scoring.go @@ -182,13 +182,14 @@ func mustToMay(x scoreAdjustTyp) scoreAdjustTyp { return 0 } -// computeCallSiteScore takes a given call site whose ir node is 'call' and -// callee function is 'callee' and with previously computed call site -// properties 'csflags', then computes a score for the callsite that -// combines the size cost of the callee with heuristics based on -// previously parameter and function properties, then stores the score -// and the adjustment mask in the appropriate fields in 'cs' -func (cs *CallSite) computeCallSiteScore(calleeProps *FuncProps) { +// computeCallSiteScore takes a given call site whose ir node is +// 'call' and callee function is 'callee' and with previously computed +// call site properties 'csflags', then computes a score for the +// callsite that combines the size cost of the callee with heuristics +// based on previously computed argument and function properties, +// then stores the score and the adjustment mask in the appropriate +// fields in 'cs' +func (cs *CallSite) computeCallSiteScore(csa *callSiteAnalyzer, calleeProps *FuncProps) { callee := cs.Callee csflags := cs.Flags call := cs.Call @@ -438,8 +439,13 @@ type scoreCallsCacheType struct { // after foo has been analyzed, but it's conceivable that CanInline // might visit bar before foo for this SCC. func ScoreCalls(fn *ir.Func) { + if len(fn.Body) == 0 { + return + } enableDebugTraceIfEnv() + nameFinder := newNameFinder(fn) + if debugTrace&debugTraceScoring != 0 { fmt.Fprintf(os.Stderr, "=-= ScoreCalls(%v)\n", ir.FuncName(fn)) } @@ -461,21 +467,25 @@ func ScoreCalls(fn *ir.Func) { fmt.Fprintf(os.Stderr, "=-= building cstab for non-inl func %s\n", ir.FuncName(fn)) } - cstab = computeCallSiteTable(fn, fn.Body, scoreCallsCache.tab, nil, 0) + cstab = computeCallSiteTable(fn, fn.Body, scoreCallsCache.tab, nil, 0, + nameFinder) } + csa := makeCallSiteAnalyzer(fn) const doCallResults = true - scoreCallsRegion(fn, fn.Body, cstab, doCallResults, nil) + csa.scoreCallsRegion(fn, fn.Body, cstab, doCallResults, nil) + + disableDebugTrace() } // scoreCallsRegion assigns numeric scores to each of the callsites in // region 'region' within function 'fn'. This can be called on // an entire function, or with 'region' set to a chunk of // code corresponding to an inlined call. -func scoreCallsRegion(fn *ir.Func, region ir.Nodes, cstab CallSiteTab, doCallResults bool, ic *ir.InlinedCallExpr) { +func (csa *callSiteAnalyzer) scoreCallsRegion(fn *ir.Func, region ir.Nodes, cstab CallSiteTab, doCallResults bool, ic *ir.InlinedCallExpr) { if debugTrace&debugTraceScoring != 0 { - fmt.Fprintf(os.Stderr, "=-= scoreCallsRegion(%v, %s)\n", - ir.FuncName(fn), region[0].Op().String()) + fmt.Fprintf(os.Stderr, "=-= scoreCallsRegion(%v, %s) len(cstab)=%d\n", + ir.FuncName(fn), region[0].Op().String(), len(cstab)) } // Sort callsites to avoid any surprises with non deterministic @@ -510,13 +520,13 @@ func scoreCallsRegion(fn *ir.Func, region ir.Nodes, cstab CallSiteTab, doCallRes continue } } - cs.computeCallSiteScore(cprops) + cs.computeCallSiteScore(csa, cprops) if doCallResults { if debugTrace&debugTraceScoring != 0 { fmt.Fprintf(os.Stderr, "=-= examineCallResults at %s: flags=%d score=%d funcInlHeur=%v deser=%v\n", fmtFullPos(cs.Call.Pos()), cs.Flags, cs.Score, fihcprops, desercprops) } - resultNameTab = examineCallResults(cs, resultNameTab) + resultNameTab = csa.examineCallResults(cs, resultNameTab) } if debugTrace&debugTraceScoring != 0 { @@ -525,7 +535,7 @@ func scoreCallsRegion(fn *ir.Func, region ir.Nodes, cstab CallSiteTab, doCallRes } if resultNameTab != nil { - rescoreBasedOnCallResultUses(fn, resultNameTab, cstab) + csa.rescoreBasedOnCallResultUses(fn, resultNameTab, cstab) } disableDebugTrace() From 0cb45bac014715433c0110675cc4e32d871a5ff0 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Wed, 28 Jun 2023 15:04:24 -0400 Subject: [PATCH 08/30] testing: use subprocesses in TestTBHelper and TestTBHelperParallel These tests are checking the output of test functions that call the Helper methods. However, they were reaching into package internals instead of running those test functions as actual tests. That not only produced significant differences in formatting (such as indentation for subtests), but also caused test flags such as "-failfast" passed for the overall test run to interfere with the output formatting. Now, we run the test functions as real tests in a subprocess, so that we get the real output and formatting of those tests. This makes the tests not only more realistic, but also less sensitive to otherwise-irrelevant implementation details (such as the names and signatures of unexported types and functions in the testing package). Fixes #61016. Change-Id: I646fbbd7cfeb00382054677f726c05fc9d35d0dc Reviewed-on: https://go-review.googlesource.com/c/go/+/506955 Auto-Submit: Bryan Mills Reviewed-by: Alan Donovan LUCI-TryBot-Result: Go LUCI --- src/testing/helper_test.go | 151 +++++++++++++++++--------------- src/testing/helperfuncs_test.go | 40 +++++---- 2 files changed, 101 insertions(+), 90 deletions(-) diff --git a/src/testing/helper_test.go b/src/testing/helper_test.go index 6e8986a2ab..da5622f85f 100644 --- a/src/testing/helper_test.go +++ b/src/testing/helper_test.go @@ -2,98 +2,107 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package testing +package testing_test import ( + "internal/testenv" + "os" "regexp" "strings" + "testing" ) -func TestTBHelper(t *T) { - var buf strings.Builder - ctx := newTestContext(1, allMatcher()) - t1 := &T{ - common: common{ - signal: make(chan bool), - w: &buf, - }, - context: ctx, - } - t1.Run("Test", testHelper) +func TestTBHelper(t *testing.T) { + if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" { + testTestHelper(t) - want := `--- FAIL: Test (?s) -helperfuncs_test.go:12: 0 -helperfuncs_test.go:40: 1 -helperfuncs_test.go:21: 2 -helperfuncs_test.go:42: 3 -helperfuncs_test.go:49: 4 ---- FAIL: Test/sub (?s) -helperfuncs_test.go:52: 5 -helperfuncs_test.go:21: 6 -helperfuncs_test.go:51: 7 -helperfuncs_test.go:63: 8 ---- FAIL: Test/sub2 (?s) -helperfuncs_test.go:78: 11 -helperfuncs_test.go:82: recover 12 -helperfuncs_test.go:84: GenericFloat64 -helperfuncs_test.go:85: GenericInt -helperfuncs_test.go:71: 9 -helperfuncs_test.go:67: 10 + // Check that calling Helper from inside a top-level test function + // has no effect. + t.Helper() + t.Error("8") + return + } + + testenv.MustHaveExec(t) + t.Parallel() + + exe, err := os.Executable() + if err != nil { + t.Fatal(err) + } + + cmd := testenv.Command(t, exe, "-test.run=^TestTBHelper$") + cmd = testenv.CleanCmdEnv(cmd) + cmd.Env = append(cmd.Env, "GO_WANT_HELPER_PROCESS=1") + out, _ := cmd.CombinedOutput() + + want := `--- FAIL: TestTBHelper \([^)]+\) + helperfuncs_test.go:15: 0 + helperfuncs_test.go:47: 1 + helperfuncs_test.go:24: 2 + helperfuncs_test.go:49: 3 + helperfuncs_test.go:56: 4 + --- FAIL: TestTBHelper/sub \([^)]+\) + helperfuncs_test.go:59: 5 + helperfuncs_test.go:24: 6 + helperfuncs_test.go:58: 7 + --- FAIL: TestTBHelper/sub2 \([^)]+\) + helperfuncs_test.go:80: 11 + helperfuncs_test.go:84: recover 12 + helperfuncs_test.go:86: GenericFloat64 + helperfuncs_test.go:87: GenericInt + helper_test.go:22: 8 + helperfuncs_test.go:73: 9 + helperfuncs_test.go:69: 10 ` - lines := strings.Split(buf.String(), "\n") - durationRE := regexp.MustCompile(`\(.*\)$`) - for i, line := range lines { - line = strings.TrimSpace(line) - line = durationRE.ReplaceAllString(line, "(?s)") - lines[i] = line - } - got := strings.Join(lines, "\n") - if got != want { - t.Errorf("got output:\n\n%s\nwant:\n\n%s", got, want) + if !regexp.MustCompile(want).Match(out) { + t.Errorf("got output:\n\n%s\nwant matching:\n\n%s", out, want) } } -func TestTBHelperParallel(t *T) { - var buf strings.Builder - ctx := newTestContext(1, newMatcher(regexp.MatchString, "", "", "")) - t1 := &T{ - common: common{ - signal: make(chan bool), - w: &buf, - }, - context: ctx, +func TestTBHelperParallel(t *testing.T) { + if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" { + parallelTestHelper(t) + return } - t1.Run("Test", parallelTestHelper) - lines := strings.Split(strings.TrimSpace(buf.String()), "\n") - if len(lines) != 6 { - t.Fatalf("parallelTestHelper gave %d lines of output; want 6", len(lines)) + testenv.MustHaveExec(t) + t.Parallel() + + exe, err := os.Executable() + if err != nil { + t.Fatal(err) } - want := "helperfuncs_test.go:21: parallel" + + cmd := testenv.Command(t, exe, "-test.run=^TestTBHelperParallel$") + cmd = testenv.CleanCmdEnv(cmd) + cmd.Env = append(cmd.Env, "GO_WANT_HELPER_PROCESS=1") + out, _ := cmd.CombinedOutput() + + t.Logf("output:\n%s", out) + + lines := strings.Split(strings.TrimSpace(string(out)), "\n") + + // We expect to see one "--- FAIL" line at the start + // of the log, five lines of "parallel" logging, + // and a final "FAIL" line at the end of the test. + const wantLines = 7 + + if len(lines) != wantLines { + t.Fatalf("parallelTestHelper gave %d lines of output; want %d", len(lines), wantLines) + } + want := "helperfuncs_test.go:24: parallel" if got := strings.TrimSpace(lines[1]); got != want { - t.Errorf("got output line %q; want %q", got, want) + t.Errorf("got second output line %q; want %q", got, want) } } -type noopWriter int - -func (nw *noopWriter) Write(b []byte) (int, error) { return len(b), nil } - -func BenchmarkTBHelper(b *B) { - w := noopWriter(0) - ctx := newTestContext(1, allMatcher()) - t1 := &T{ - common: common{ - signal: make(chan bool), - w: &w, - }, - context: ctx, - } +func BenchmarkTBHelper(b *testing.B) { f1 := func() { - t1.Helper() + b.Helper() } f2 := func() { - t1.Helper() + b.Helper() } b.ResetTimer() b.ReportAllocs() diff --git a/src/testing/helperfuncs_test.go b/src/testing/helperfuncs_test.go index b63bc91ac2..f0295f35df 100644 --- a/src/testing/helperfuncs_test.go +++ b/src/testing/helperfuncs_test.go @@ -2,38 +2,45 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package testing +package testing_test -import "sync" +import ( + "sync" + "testing" +) // The line numbering of this file is important for TestTBHelper. -func notHelper(t *T, msg string) { +func notHelper(t *testing.T, msg string) { t.Error(msg) } -func helper(t *T, msg string) { +func helper(t *testing.T, msg string) { t.Helper() t.Error(msg) } -func notHelperCallingHelper(t *T, msg string) { +func notHelperCallingHelper(t *testing.T, msg string) { helper(t, msg) } -func helperCallingHelper(t *T, msg string) { +func helperCallingHelper(t *testing.T, msg string) { t.Helper() helper(t, msg) } -func genericHelper[G any](t *T, msg string) { +func genericHelper[G any](t *testing.T, msg string) { t.Helper() t.Error(msg) } var genericIntHelper = genericHelper[int] -func testHelper(t *T) { +func testTestHelper(t *testing.T) { + testHelper(t) +} + +func testHelper(t *testing.T) { // Check combinations of directly and indirectly // calling helper functions. notHelper(t, "0") @@ -48,7 +55,7 @@ func testHelper(t *T) { } fn("4") - t.Run("sub", func(t *T) { + t.Run("sub", func(t *testing.T) { helper(t, "5") notHelperCallingHelper(t, "6") // Check that calling Helper from inside a subtest entry function @@ -57,11 +64,6 @@ func testHelper(t *T) { t.Error("7") }) - // Check that calling Helper from inside a top-level test function - // has no effect. - t.Helper() - t.Error("8") - // Check that right caller is reported for func passed to Cleanup when // multiple cleanup functions have been registered. t.Cleanup(func() { @@ -85,7 +87,7 @@ func testHelper(t *T) { genericIntHelper(t, "GenericInt") } -func parallelTestHelper(t *T) { +func parallelTestHelper(t *testing.T) { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) @@ -97,15 +99,15 @@ func parallelTestHelper(t *T) { wg.Wait() } -func helperSubCallingHelper(t *T, msg string) { +func helperSubCallingHelper(t *testing.T, msg string) { t.Helper() - t.Run("sub2", func(t *T) { + t.Run("sub2", func(t *testing.T) { t.Helper() t.Fatal(msg) }) } -func recoverHelper(t *T, msg string) { +func recoverHelper(t *testing.T, msg string) { t.Helper() defer func() { t.Helper() @@ -116,7 +118,7 @@ func recoverHelper(t *T, msg string) { doPanic(t, msg) } -func doPanic(t *T, msg string) { +func doPanic(t *testing.T, msg string) { t.Helper() panic(msg) } From 3255fca99395bb0c0dff491f92cc85c0a859dd25 Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Mon, 30 Oct 2023 12:55:42 -0400 Subject: [PATCH 09/30] cmd/compile/internal/inline: fix bug in param flags heuristics Fix a bug in the code that analyzes how function parameters are used, which wasn't properly handling certain types of closures. The code in question has support for deriving flags for a given parameter based on whether it is passed to a call. Example: func foo(f1 func(int)) { bar(32, f1) } func bar(x int, f2 func()) { f2(x) } When analyzing "bar", we can derive the "FeedsIndirectCall" flag for parameter "f1" by virtue of the fact that it is passed directly to "bar", and bar's corresponding parameter "f2" has the flag set. For a more complex example such as func foo(f1 func(int)) func() int { return func(q int) int { <<-- HERE bar(99, f1) return q } } func bar(x int, f2 func()) { f2(x) } The heuristics code would panic when examining the closure marked above due to the fact that the call to "bar" was passing an ir.Name with class PPARAM, but no such param was present in the enclosing function. Change-Id: I30436ce716b51bfb03e42e7abe76a4514e6b9285 Reviewed-on: https://go-review.googlesource.com/c/go/+/539320 LUCI-TryBot-Result: Go LUCI Reviewed-by: Matthew Dempsky --- .../internal/inline/inlheur/analyze_func_params.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/inline/inlheur/analyze_func_params.go b/src/cmd/compile/internal/inline/inlheur/analyze_func_params.go index 5e61485532..d85d73b2ef 100644 --- a/src/cmd/compile/internal/inline/inlheur/analyze_func_params.go +++ b/src/cmd/compile/internal/inline/inlheur/analyze_func_params.go @@ -249,7 +249,13 @@ func (pa *paramsAnalyzer) deriveFlagsFromCallee(ce *ir.CallExpr, callee *ir.Func return } callerParamIdx := pa.findParamIdx(name) - if callerParamIdx == -1 || pa.params[callerParamIdx] == nil { + // note that callerParamIdx may return -1 in the case where + // the param belongs not to the current closure func we're + // analyzing but to an outer enclosing func. + if callerParamIdx == -1 { + return + } + if pa.params[callerParamIdx] == nil { panic("something went wrong") } if !pa.top[callerParamIdx] && From 5239c913510633ce9fdfaf993ab5f31d7ba7e83e Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Fri, 3 Nov 2023 14:04:57 -0400 Subject: [PATCH 10/30] cmd/compile/internal/inline: minor compile time improvements in func flags Some small changes to help reduce compile time for function flags computation. The current implementation of panic path detection adds an entry to a map for every node in the function, which is wasteful (and shows up in cpu profiles). Switch to only adding entries where they are useful. This is especially important for functions with large map literals and other constructs with many non-statement nodes. Change-Id: I9cfb2cd1cbf480f21298e6102aa99e2d77219f3d Reviewed-on: https://go-review.googlesource.com/c/go/+/539696 Reviewed-by: Matthew Dempsky LUCI-TryBot-Result: Go LUCI --- .../inline/inlheur/analyze_func_flags.go | 32 ++++++------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/cmd/compile/internal/inline/inlheur/analyze_func_flags.go b/src/cmd/compile/internal/inline/inlheur/analyze_func_flags.go index 588d2f4f59..b7403a4f8c 100644 --- a/src/cmd/compile/internal/inline/inlheur/analyze_func_flags.go +++ b/src/cmd/compile/internal/inline/inlheur/analyze_func_flags.go @@ -66,34 +66,24 @@ func (ffa *funcFlagsAnalyzer) setResults(funcProps *FuncProps) { funcProps.Flags = rv } -func (ffa *funcFlagsAnalyzer) getstate(n ir.Node) pstate { - val, ok := ffa.nstate[n] - if !ok { - base.Fatalf("funcFlagsAnalyzer: fn %q node %s line %s: internal error, no setting for node:\n%+v\n", ffa.fn.Sym().Name, n.Op().String(), ir.Line(n), n) - } - return val +func (ffa *funcFlagsAnalyzer) getState(n ir.Node) pstate { + return ffa.nstate[n] } -func (ffa *funcFlagsAnalyzer) setstate(n ir.Node, st pstate) { - if _, ok := ffa.nstate[n]; ok { - base.Fatalf("funcFlagsAnalyzer: fn %q internal error, existing setting for node:\n%+v\n", ffa.fn.Sym().Name, n) - } else { +func (ffa *funcFlagsAnalyzer) setState(n ir.Node, st pstate) { + if st != psNoInfo { ffa.nstate[n] = st } } -func (ffa *funcFlagsAnalyzer) updatestate(n ir.Node, st pstate) { - if _, ok := ffa.nstate[n]; !ok { - base.Fatalf("funcFlagsAnalyzer: fn %q internal error, expected existing setting for node:\n%+v\n", ffa.fn.Sym().Name, n) +func (ffa *funcFlagsAnalyzer) updateState(n ir.Node, st pstate) { + if st == psNoInfo { + delete(ffa.nstate, n) } else { ffa.nstate[n] = st } } -func (ffa *funcFlagsAnalyzer) setstateSoft(n ir.Node, st pstate) { - ffa.nstate[n] = st -} - func (ffa *funcFlagsAnalyzer) panicPathTable() map[ir.Node]pstate { return ffa.nstate } @@ -164,13 +154,13 @@ func (ffa *funcFlagsAnalyzer) stateForList(list ir.Nodes) pstate { // line 10 will be on a panic path). for i := len(list) - 1; i >= 0; i-- { n := list[i] - psi := ffa.getstate(n) + psi := ffa.getState(n) if debugTrace&debugTraceFuncFlags != 0 { fmt.Fprintf(os.Stderr, "=-= %v: stateForList n=%s ps=%s\n", ir.Line(n), n.Op().String(), psi.String()) } st = blockCombine(psi, st) - ffa.updatestate(n, st) + ffa.updateState(n, st) } if st == psTop { st = psNoInfo @@ -237,8 +227,6 @@ func (ffa *funcFlagsAnalyzer) nodeVisitPost(n ir.Node) { ir.Line(n), n.Op().String(), shouldVisit(n)) } if !shouldVisit(n) { - // invoke soft set, since node may be shared (e.g. ONAME) - ffa.setstateSoft(n, psNoInfo) return } var st pstate @@ -361,7 +349,7 @@ func (ffa *funcFlagsAnalyzer) nodeVisitPost(n ir.Node) { fmt.Fprintf(os.Stderr, "=-= %v: visit n=%s returns %s\n", ir.Line(n), n.Op().String(), st.String()) } - ffa.setstate(n, st) + ffa.setState(n, st) } func (ffa *funcFlagsAnalyzer) nodeVisitPre(n ir.Node) { From 4f55a5af5e5d325a534222050564766c249218aa Mon Sep 17 00:00:00 2001 From: Carlo Alberto Ferraris Date: Sun, 2 Apr 2023 23:54:35 +0900 Subject: [PATCH 11/30] sync: do not unnecessarily keep alive functions wrapped by Once(Func|Value|Values) The function passed to OnceFunc/OnceValue/OnceValues may transitively keep more allocations alive. As the passed function is guaranteed to be called at most once, it is safe to drop it after the first call is complete. This avoids keeping the passed function (and anything it transitively references) alive until the returned function is GCed. Change-Id: I2faf397b481d2f693ab3aea8e2981b02adbc7a21 Reviewed-on: https://go-review.googlesource.com/c/go/+/481515 Reviewed-by: Austin Clements Reviewed-by: David Chase TryBot-Result: Gopher Robot Run-TryBot: qiulaidongfeng <2645477756@qq.com> --- src/runtime/export_test.go | 18 +------------- src/runtime/mfinal.go | 21 ++++++++++++++++ src/sync/oncefunc.go | 5 +++- src/sync/oncefunc_test.go | 50 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 18 deletions(-) diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go index d2f3563956..2b34929ba0 100644 --- a/src/runtime/export_test.go +++ b/src/runtime/export_test.go @@ -1920,24 +1920,8 @@ func UserArenaClone[T any](s T) T { var AlignUp = alignUp -// BlockUntilEmptyFinalizerQueue blocks until either the finalizer -// queue is emptied (and the finalizers have executed) or the timeout -// is reached. Returns true if the finalizer queue was emptied. func BlockUntilEmptyFinalizerQueue(timeout int64) bool { - start := nanotime() - for nanotime()-start < timeout { - lock(&finlock) - // We know the queue has been drained when both finq is nil - // and the finalizer g has stopped executing. - empty := finq == nil - empty = empty && readgstatus(fing) == _Gwaiting && fing.waitreason == waitReasonFinalizerWait - unlock(&finlock) - if empty { - return true - } - Gosched() - } - return false + return blockUntilEmptyFinalizerQueue(timeout) } func FrameStartLine(f *Frame) int { diff --git a/src/runtime/mfinal.go b/src/runtime/mfinal.go index be501e6fca..7d9d547c0f 100644 --- a/src/runtime/mfinal.go +++ b/src/runtime/mfinal.go @@ -300,6 +300,27 @@ func isGoPointerWithoutSpan(p unsafe.Pointer) bool { return false } +// blockUntilEmptyFinalizerQueue blocks until either the finalizer +// queue is emptied (and the finalizers have executed) or the timeout +// is reached. Returns true if the finalizer queue was emptied. +// This is used by the runtime and sync tests. +func blockUntilEmptyFinalizerQueue(timeout int64) bool { + start := nanotime() + for nanotime()-start < timeout { + lock(&finlock) + // We know the queue has been drained when both finq is nil + // and the finalizer g has stopped executing. + empty := finq == nil + empty = empty && readgstatus(fing) == _Gwaiting && fing.waitreason == waitReasonFinalizerWait + unlock(&finlock) + if empty { + return true + } + Gosched() + } + return false +} + // SetFinalizer sets the finalizer associated with obj to the provided // finalizer function. When the garbage collector finds an unreachable block // with an associated finalizer, it clears the association and runs diff --git a/src/sync/oncefunc.go b/src/sync/oncefunc.go index 9ef8344132..db286283d1 100644 --- a/src/sync/oncefunc.go +++ b/src/sync/oncefunc.go @@ -25,7 +25,8 @@ func OnceFunc(f func()) func() { } }() f() - valid = true // Set only if f does not panic + f = nil // Do not keep f alive after invoking it. + valid = true // Set only if f does not panic. } return func() { once.Do(g) @@ -54,6 +55,7 @@ func OnceValue[T any](f func() T) func() T { } }() result = f() + f = nil valid = true } return func() T { @@ -85,6 +87,7 @@ func OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) { } }() r1, r2 = f() + f = nil valid = true } return func() (T1, T2) { diff --git a/src/sync/oncefunc_test.go b/src/sync/oncefunc_test.go index 3c523a5b62..5f0d564063 100644 --- a/src/sync/oncefunc_test.go +++ b/src/sync/oncefunc_test.go @@ -6,10 +6,13 @@ package sync_test import ( "bytes" + "math" "runtime" "runtime/debug" "sync" + "sync/atomic" "testing" + _ "unsafe" ) // We assume that the Once.Do tests have already covered parallelism. @@ -182,6 +185,53 @@ func onceFuncPanic() { panic("x") } +func TestOnceXGC(t *testing.T) { + fns := map[string]func([]byte) func(){ + "OnceFunc": func(buf []byte) func() { + return sync.OnceFunc(func() { buf[0] = 1 }) + }, + "OnceValue": func(buf []byte) func() { + f := sync.OnceValue(func() any { buf[0] = 1; return nil }) + return func() { f() } + }, + "OnceValues": func(buf []byte) func() { + f := sync.OnceValues(func() (any, any) { buf[0] = 1; return nil, nil }) + return func() { f() } + }, + } + for n, fn := range fns { + t.Run(n, func(t *testing.T) { + buf := make([]byte, 1024) + var gc atomic.Bool + runtime.SetFinalizer(&buf[0], func(_ *byte) { + gc.Store(true) + }) + f := fn(buf) + gcwaitfin() + if gc.Load() != false { + t.Fatal("wrapped function garbage collected too early") + } + f() + gcwaitfin() + if gc.Load() != true { + // Even if f is still alive, the function passed to Once(Func|Value|Values) + // is not kept alive after the first call to f. + t.Fatal("wrapped function should be garbage collected, but still live") + } + f() + }) + } +} + +// gcwaitfin performs garbage collection and waits for all finalizers to run. +func gcwaitfin() { + runtime.GC() + runtime_blockUntilEmptyFinalizerQueue(math.MaxInt64) +} + +//go:linkname runtime_blockUntilEmptyFinalizerQueue runtime.blockUntilEmptyFinalizerQueue +func runtime_blockUntilEmptyFinalizerQueue(int64) bool + var ( onceFunc = sync.OnceFunc(func() {}) From f43581131e96f0a4a7745250218ace6c4ea2e557 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Thu, 17 Aug 2023 03:58:10 +0800 Subject: [PATCH 12/30] cmd/compile, cmd/internal, runtime: change the registers used by the duff device for loong64 Add R21 to the allocatable registers, use R20 and R21 in duff device. This CL is in preparation for subsequent regABI support. Updates #40724 Co-authored-by: Xiaolin Zhao Change-Id: If1661adc0f766925fbe74827a369797f95fa28a9 Reviewed-on: https://go-review.googlesource.com/c/go/+/521775 Reviewed-by: David Chase Run-TryBot: David Chase Reviewed-by: Cherry Mui Reviewed-by: Meidan Li Reviewed-by: Than McIntosh TryBot-Result: Gopher Robot --- src/cmd/compile/internal/loong64/ssa.go | 2 +- .../compile/internal/ssa/_gen/LOONG64Ops.go | 44 +- src/cmd/compile/internal/ssa/opGen.go | 426 +++--- src/cmd/internal/obj/loong64/a.out.go | 8 +- src/runtime/duff_loong64.s | 1280 ++++++++--------- src/runtime/mkduff.go | 10 +- 6 files changed, 885 insertions(+), 885 deletions(-) diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go index 6e81da3ef8..ad465ba3bb 100644 --- a/src/cmd/compile/internal/loong64/ssa.go +++ b/src/cmd/compile/internal/loong64/ssa.go @@ -362,7 +362,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { p.To.Type = obj.TYPE_REG p.To.Reg = v.Reg() case ssa.OpLOONG64DUFFZERO: - // runtime.duffzero expects start address in R19 + // runtime.duffzero expects start address in R20 p := s.Prog(obj.ADUFFZERO) p.To.Type = obj.TYPE_MEM p.To.Name = obj.NAME_EXTERN diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go index 3442fc8d7c..97aa9590a7 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go @@ -123,7 +123,7 @@ func init() { // Common individual register masks var ( - gp = buildReg("R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31") // R1 is LR, R2 is thread pointer, R3 is stack pointer, R21-unused, R22 is g, R30 is REGTMP + gp = buildReg("R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31") // R1 is LR, R2 is thread pointer, R3 is stack pointer, R22 is g, R30 is REGTMP gpg = gp | buildReg("g") gpsp = gp | buildReg("SP") gpspg = gpg | buildReg("SP") @@ -283,22 +283,22 @@ func init() { // arg1 = mem // auxint = offset into duffzero code to start executing // returns mem - // R19 aka loong64.REGRT1 changed as side effect + // R20 aka loong64.REGRT1 changed as side effect { name: "DUFFZERO", aux: "Int64", argLength: 2, reg: regInfo{ - inputs: []regMask{buildReg("R19")}, - clobbers: buildReg("R19 R1"), + inputs: []regMask{buildReg("R20")}, + clobbers: buildReg("R20 R1"), }, typ: "Mem", faultOnNilArg0: true, }, // duffcopy - // arg0 = address of dst memory (in R20, changed as side effect) REGRT2 - // arg1 = address of src memory (in R19, changed as side effect) REGRT1 + // arg0 = address of dst memory (in R21, changed as side effect) + // arg1 = address of src memory (in R20, changed as side effect) // arg2 = mem // auxint = offset into duffcopy code to start executing // returns mem @@ -307,8 +307,8 @@ func init() { aux: "Int64", argLength: 3, reg: regInfo{ - inputs: []regMask{buildReg("R20"), buildReg("R19")}, - clobbers: buildReg("R19 R20 R1"), + inputs: []regMask{buildReg("R21"), buildReg("R20")}, + clobbers: buildReg("R20 R21 R1"), }, typ: "Mem", faultOnNilArg0: true, @@ -316,45 +316,45 @@ func init() { }, // large or unaligned zeroing - // arg0 = address of memory to zero (in R19, changed as side effect) + // arg0 = address of memory to zero (in R20, changed as side effect) // arg1 = address of the last element to zero // arg2 = mem // auxint = alignment // returns mem - // MOVx R0, (R19) - // ADDV $sz, R19 - // BGEU Rarg1, R19, -2(PC) + // MOVx R0, (R20) + // ADDV $sz, R20 + // BGEU Rarg1, R20, -2(PC) { name: "LoweredZero", aux: "Int64", argLength: 3, reg: regInfo{ - inputs: []regMask{buildReg("R19"), gp}, - clobbers: buildReg("R19"), + inputs: []regMask{buildReg("R20"), gp}, + clobbers: buildReg("R20"), }, typ: "Mem", faultOnNilArg0: true, }, // large or unaligned move - // arg0 = address of dst memory (in R20, changed as side effect) - // arg1 = address of src memory (in R19, changed as side effect) + // arg0 = address of dst memory (in R21, changed as side effect) + // arg1 = address of src memory (in R20, changed as side effect) // arg2 = address of the last element of src // arg3 = mem // auxint = alignment // returns mem - // MOVx (R19), Rtmp - // MOVx Rtmp, (R20) - // ADDV $sz, R19 + // MOVx (R20), Rtmp + // MOVx Rtmp, (R21) // ADDV $sz, R20 - // BGEU Rarg2, R19, -4(PC) + // ADDV $sz, R21 + // BGEU Rarg2, R20, -4(PC) { name: "LoweredMove", aux: "Int64", argLength: 4, reg: regInfo{ - inputs: []regMask{buildReg("R20"), buildReg("R19"), gp}, - clobbers: buildReg("R19 R20"), + inputs: []regMask{buildReg("R21"), buildReg("R20"), gp}, + clobbers: buildReg("R20 R21"), }, typ: "Mem", faultOnNilArg0: true, diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 80ac8e4f8b..55a50fa284 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -23193,11 +23193,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AADDVU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23208,10 +23208,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AADDVU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693244}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741820}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23221,11 +23221,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASUBVU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23236,10 +23236,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASUBVU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23250,11 +23250,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMULV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23265,11 +23265,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMULHV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23280,11 +23280,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMULHVU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23294,11 +23294,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.ADIVV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23308,11 +23308,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.ADIVVU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23322,11 +23322,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AREMV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23336,11 +23336,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AREMVU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23467,11 +23467,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AAND, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23482,10 +23482,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AAND, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23496,11 +23496,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AOR, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23511,10 +23511,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AOR, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23525,11 +23525,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AXOR, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23540,10 +23540,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AXOR, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23554,11 +23554,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.ANOR, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23569,10 +23569,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.ANOR, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23581,10 +23581,10 @@ var opcodeTable = [...]opInfo{ argLen: 1, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23646,11 +23646,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMASKEQZ, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23660,11 +23660,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMASKNEZ, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23674,11 +23674,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASLLV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23689,10 +23689,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASLLV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23702,11 +23702,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASRLV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23717,10 +23717,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASRLV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23730,11 +23730,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASRAV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23745,10 +23745,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASRAV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23758,11 +23758,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AROTR, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23772,11 +23772,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.AROTRV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23787,10 +23787,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AROTR, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23801,10 +23801,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AROTRV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23814,11 +23814,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASGT, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23829,10 +23829,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASGT, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23842,11 +23842,11 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASGTU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23857,10 +23857,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.ASGTU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23938,7 +23938,7 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVV, reg: regInfo{ outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23978,7 +23978,7 @@ var opcodeTable = [...]opInfo{ {0, 4611686018427387908}, // SP SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -23991,10 +23991,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVB, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24007,10 +24007,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVBU, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24023,10 +24023,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVH, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24039,10 +24039,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVHU, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24055,10 +24055,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVW, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24071,10 +24071,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVWU, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24087,10 +24087,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVV, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24103,7 +24103,7 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVF, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ {0, 4611686017353646080}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 @@ -24119,7 +24119,7 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVD, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ {0, 4611686017353646080}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 @@ -24135,8 +24135,8 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVB, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24149,8 +24149,8 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVH, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24163,8 +24163,8 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVW, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24177,8 +24177,8 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVV, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24191,7 +24191,7 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVF, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB {1, 4611686017353646080}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, }, @@ -24205,7 +24205,7 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVD, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB {1, 4611686017353646080}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, }, @@ -24219,7 +24219,7 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVB, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24232,7 +24232,7 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVH, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24245,7 +24245,7 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVW, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24258,7 +24258,7 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVV, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24268,10 +24268,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVB, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24281,10 +24281,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVBU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24294,10 +24294,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVH, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24307,10 +24307,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVHU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24320,10 +24320,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVW, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24333,10 +24333,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVWU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24346,10 +24346,10 @@ var opcodeTable = [...]opInfo{ asm: loong64.AMOVV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24359,10 +24359,10 @@ var opcodeTable = [...]opInfo{ resultInArg0: true, reg: regInfo{ inputs: []inputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24503,7 +24503,7 @@ var opcodeTable = [...]opInfo{ clobberFlags: true, call: true, reg: regInfo{ - clobbers: 4611686018426339320, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + clobbers: 4611686018427387896, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, }, { @@ -24514,7 +24514,7 @@ var opcodeTable = [...]opInfo{ call: true, tailCall: true, reg: regInfo{ - clobbers: 4611686018426339320, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + clobbers: 4611686018427387896, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, }, { @@ -24526,9 +24526,9 @@ var opcodeTable = [...]opInfo{ reg: regInfo{ inputs: []inputInfo{ {1, 268435456}, // R29 - {0, 1070596092}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644668}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, - clobbers: 4611686018426339320, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + clobbers: 4611686018427387896, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, }, { @@ -24539,9 +24539,9 @@ var opcodeTable = [...]opInfo{ call: true, reg: regInfo{ inputs: []inputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, - clobbers: 4611686018426339320, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + clobbers: 4611686018427387896, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, }, { @@ -24551,9 +24551,9 @@ var opcodeTable = [...]opInfo{ faultOnNilArg0: true, reg: regInfo{ inputs: []inputInfo{ - {0, 262144}, // R19 + {0, 524288}, // R20 }, - clobbers: 262146, // R1 R19 + clobbers: 524290, // R1 R20 }, }, { @@ -24564,10 +24564,10 @@ var opcodeTable = [...]opInfo{ faultOnNilArg1: true, reg: regInfo{ inputs: []inputInfo{ - {0, 524288}, // R20 - {1, 262144}, // R19 + {0, 1048576}, // R21 + {1, 524288}, // R20 }, - clobbers: 786434, // R1 R19 R20 + clobbers: 1572866, // R1 R20 R21 }, }, { @@ -24577,10 +24577,10 @@ var opcodeTable = [...]opInfo{ faultOnNilArg0: true, reg: regInfo{ inputs: []inputInfo{ - {0, 262144}, // R19 - {1, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 524288}, // R20 + {1, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, - clobbers: 262144, // R19 + clobbers: 524288, // R20 }, }, { @@ -24591,11 +24591,11 @@ var opcodeTable = [...]opInfo{ faultOnNilArg1: true, reg: regInfo{ inputs: []inputInfo{ - {0, 524288}, // R20 - {1, 262144}, // R19 - {2, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1048576}, // R21 + {1, 524288}, // R20 + {2, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, - clobbers: 786432, // R19 R20 + clobbers: 1572864, // R20 R21 }, }, { @@ -24604,10 +24604,10 @@ var opcodeTable = [...]opInfo{ faultOnNilArg0: true, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24617,10 +24617,10 @@ var opcodeTable = [...]opInfo{ faultOnNilArg0: true, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24630,10 +24630,10 @@ var opcodeTable = [...]opInfo{ faultOnNilArg0: true, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24644,8 +24644,8 @@ var opcodeTable = [...]opInfo{ hasSideEffects: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24656,8 +24656,8 @@ var opcodeTable = [...]opInfo{ hasSideEffects: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24668,8 +24668,8 @@ var opcodeTable = [...]opInfo{ hasSideEffects: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24680,7 +24680,7 @@ var opcodeTable = [...]opInfo{ hasSideEffects: true, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24691,7 +24691,7 @@ var opcodeTable = [...]opInfo{ hasSideEffects: true, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, }, }, @@ -24704,11 +24704,11 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24721,11 +24721,11 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24738,11 +24738,11 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24755,11 +24755,11 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24773,10 +24773,10 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24790,10 +24790,10 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24806,12 +24806,12 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {2, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {2, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24824,12 +24824,12 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {2, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {2, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB }, outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24840,7 +24840,7 @@ var opcodeTable = [...]opInfo{ faultOnNilArg0: true, reg: regInfo{ inputs: []inputInfo{ - {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24849,7 +24849,7 @@ var opcodeTable = [...]opInfo{ argLen: 1, reg: regInfo{ outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24858,7 +24858,7 @@ var opcodeTable = [...]opInfo{ argLen: 1, reg: regInfo{ outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24878,7 +24878,7 @@ var opcodeTable = [...]opInfo{ rematerializeable: true, reg: regInfo{ outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -24888,7 +24888,7 @@ var opcodeTable = [...]opInfo{ rematerializeable: true, reg: regInfo{ outputs: []outputInfo{ - {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, @@ -40707,16 +40707,16 @@ var registersLOONG64 = [...]Register{ {17, loong64.REG_R18, 14, "R18"}, {18, loong64.REG_R19, 15, "R19"}, {19, loong64.REG_R20, 16, "R20"}, - {20, loong64.REG_R21, -1, "R21"}, + {20, loong64.REG_R21, 17, "R21"}, {21, loong64.REGG, -1, "g"}, - {22, loong64.REG_R23, 17, "R23"}, - {23, loong64.REG_R24, 18, "R24"}, - {24, loong64.REG_R25, 19, "R25"}, - {25, loong64.REG_R26, 20, "R26"}, - {26, loong64.REG_R27, 21, "R27"}, - {27, loong64.REG_R28, 22, "R28"}, - {28, loong64.REG_R29, 23, "R29"}, - {29, loong64.REG_R31, 24, "R31"}, + {22, loong64.REG_R23, 18, "R23"}, + {23, loong64.REG_R24, 19, "R24"}, + {24, loong64.REG_R25, 20, "R25"}, + {25, loong64.REG_R26, 21, "R26"}, + {26, loong64.REG_R27, 22, "R27"}, + {27, loong64.REG_R28, 23, "R28"}, + {28, loong64.REG_R29, 24, "R29"}, + {29, loong64.REG_R31, 25, "R31"}, {30, loong64.REG_F0, -1, "F0"}, {31, loong64.REG_F1, -1, "F1"}, {32, loong64.REG_F2, -1, "F2"}, @@ -40753,7 +40753,7 @@ var registersLOONG64 = [...]Register{ } var paramIntRegLOONG64 = []int8{3, 4, 5, 6, 7, 8, 9, 10} var paramFloatRegLOONG64 = []int8{30, 31, 32, 33, 34, 35, 36, 37} -var gpRegMaskLOONG64 = regMask(1070596088) +var gpRegMaskLOONG64 = regMask(1071644664) var fpRegMaskLOONG64 = regMask(4611686017353646080) var specialRegMaskLOONG64 = regMask(0) var framepointerRegLOONG64 = int8(-1) diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go index 99a7da388f..a4bb7b40a3 100644 --- a/src/cmd/internal/obj/loong64/a.out.go +++ b/src/cmd/internal/obj/loong64/a.out.go @@ -157,14 +157,14 @@ const ( REGZERO = REG_R0 // set to zero REGLINK = REG_R1 REGSP = REG_R3 - REGRET = REG_R19 + REGRET = REG_R20 // not use REGARG = -1 // -1 disables passing the first argument in register - REGRT1 = REG_R19 // reserved for runtime, duffzero and duffcopy - REGRT2 = REG_R20 // reserved for runtime, duffcopy + REGRT1 = REG_R20 // reserved for runtime, duffzero and duffcopy + REGRT2 = REG_R21 // reserved for runtime, duffcopy REGCTXT = REG_R29 // context for closures REGG = REG_R22 // G in loong64 REGTMP = REG_R30 // used by the assembler - FREGRET = REG_F0 + FREGRET = REG_F0 // not use ) var LOONG64DWARFRegisters = map[int16]int16{} diff --git a/src/runtime/duff_loong64.s b/src/runtime/duff_loong64.s index 63fa3bcca1..df8b653965 100644 --- a/src/runtime/duff_loong64.s +++ b/src/runtime/duff_loong64.s @@ -5,903 +5,903 @@ #include "textflag.h" TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 - MOVV R0, (R19) - ADDV $8, R19 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) + ADDV $8, R20 RET TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 - MOVV (R19), R30 - ADDV $8, R19 - MOVV R30, (R20) + MOVV (R20), R30 ADDV $8, R20 + MOVV R30, (R21) + ADDV $8, R21 RET diff --git a/src/runtime/mkduff.go b/src/runtime/mkduff.go index e8d4fcc93e..77674254d4 100644 --- a/src/runtime/mkduff.go +++ b/src/runtime/mkduff.go @@ -183,8 +183,8 @@ func zeroLOONG64(w io.Writer) { // On return, R19 points to the last zeroed dword. fmt.Fprintln(w, "TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0") for i := 0; i < 128; i++ { - fmt.Fprintln(w, "\tMOVV\tR0, (R19)") - fmt.Fprintln(w, "\tADDV\t$8, R19") + fmt.Fprintln(w, "\tMOVV\tR0, (R20)") + fmt.Fprintln(w, "\tADDV\t$8, R20") } fmt.Fprintln(w, "\tRET") } @@ -192,10 +192,10 @@ func zeroLOONG64(w io.Writer) { func copyLOONG64(w io.Writer) { fmt.Fprintln(w, "TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0") for i := 0; i < 128; i++ { - fmt.Fprintln(w, "\tMOVV\t(R19), R30") - fmt.Fprintln(w, "\tADDV\t$8, R19") - fmt.Fprintln(w, "\tMOVV\tR30, (R20)") + fmt.Fprintln(w, "\tMOVV\t(R20), R30") fmt.Fprintln(w, "\tADDV\t$8, R20") + fmt.Fprintln(w, "\tMOVV\tR30, (R21)") + fmt.Fprintln(w, "\tADDV\t$8, R21") fmt.Fprintln(w) } fmt.Fprintln(w, "\tRET") From 346e06c46dd1791e924ce4fffc879747bdabedf5 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Tue, 10 Oct 2023 20:16:36 +0800 Subject: [PATCH 13/30] cmd/internal/obj,cmd/link: access global data via GOT in -dynlink mode on loong64 Updates #58784 Change-Id: Ic98d10a512fea0c3ca321ab52693d9f6775126a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/480875 Reviewed-by: David Chase Reviewed-by: Cherry Mui Reviewed-by: Meidan Li TryBot-Result: Gopher Robot Run-TryBot: WANG Xuerui Reviewed-by: WANG Xuerui --- .../compile/internal/ssa/_gen/LOONG64.rules | 79 ++------ .../compile/internal/ssa/rewriteLOONG64.go | 190 +++++++++++------- src/cmd/internal/obj/loong64/a.out.go | 1 + src/cmd/internal/obj/loong64/asm.go | 21 ++ src/cmd/internal/obj/loong64/cnames.go | 1 + src/cmd/internal/obj/loong64/obj.go | 117 +++++++++++ src/cmd/internal/objabi/reloctype.go | 5 + src/cmd/internal/objabi/reloctype_string.go | 22 +- src/cmd/link/internal/loong64/asm.go | 19 +- 9 files changed, 310 insertions(+), 145 deletions(-) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules index 4a47c4cd47..b9aaa3ff7f 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules @@ -455,66 +455,31 @@ (ADDVconst [off1] (MOVVaddr [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) => (MOVVaddr [int32(off1)+int32(off2)] {sym} ptr) // fold address into load/store -(MOVBload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBload [off1+int32(off2)] {sym} ptr mem) -(MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBUload [off1+int32(off2)] {sym} ptr mem) -(MOVHload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHload [off1+int32(off2)] {sym} ptr mem) -(MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHUload [off1+int32(off2)] {sym} ptr mem) -(MOVWload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWload [off1+int32(off2)] {sym} ptr mem) -(MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWUload [off1+int32(off2)] {sym} ptr mem) -(MOVVload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVload [off1+int32(off2)] {sym} ptr mem) -(MOVFload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVFload [off1+int32(off2)] {sym} ptr mem) -(MOVDload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVDload [off1+int32(off2)] {sym} ptr mem) +// Do not fold global variable access in -dynlink mode, where it will be rewritten +// to use the GOT via REGTMP, which currently cannot handle large offset. +(MOV(B|BU|H|HU|W|WU|V|F|D)load [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) + && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => + (MOV(B|BU|H|HU|W|WU|V|F|D)load [off1+int32(off2)] {sym} ptr mem) -(MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVBstore [off1+int32(off2)] {sym} ptr val mem) -(MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVHstore [off1+int32(off2)] {sym} ptr val mem) -(MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVWstore [off1+int32(off2)] {sym} ptr val mem) -(MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVVstore [off1+int32(off2)] {sym} ptr val mem) -(MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVFstore [off1+int32(off2)] {sym} ptr val mem) -(MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVDstore [off1+int32(off2)] {sym} ptr val mem) -(MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBstorezero [off1+int32(off2)] {sym} ptr mem) -(MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHstorezero [off1+int32(off2)] {sym} ptr mem) -(MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWstorezero [off1+int32(off2)] {sym} ptr mem) -(MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVstorezero [off1+int32(off2)] {sym} ptr mem) +(MOV(B|H|W|V|F|D)store [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) + && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => + (MOV(B|H|W|V|F|D)store [off1+int32(off2)] {sym} ptr val mem) -(MOVBload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) -(MOVBUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) -(MOVHload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) -(MOVHUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) -(MOVWload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) -(MOVWUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) -(MOVVload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) -(MOVFload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) -(MOVDload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +(MOV(B|H|W|V)storezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) + && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => + (MOV(B|H|W|V)storezero [off1+int32(off2)] {sym} ptr mem) -(MOVBstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) -(MOVHstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) -(MOVWstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) -(MOVVstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) -(MOVFstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) -(MOVDstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) -(MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) -(MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) -(MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) -(MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +(MOV(B|BU|H|HU|W|WU|V|F|D)load [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) + && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => + (MOV(B|BU|H|HU|W|WU|V|F|D)load [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + +(MOV(B|H|W|V|F|D)store [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) + && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => + (MOV(B|H|W|V|F|D)store [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) + +(MOV(B|H|W|V)storezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) + && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => + (MOV(B|H|W|V)storezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (LoweredAtomicStore(32|64) ptr (MOVVconst [0]) mem) => (LoweredAtomicStorezero(32|64) ptr mem) (LoweredAtomicAdd32 ptr (MOVVconst [c]) mem) && is32Bit(c) => (LoweredAtomicAddconst32 [int32(c)] ptr mem) diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go index e88b74cb22..757524bdbb 100644 --- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go +++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go @@ -1724,8 +1724,10 @@ func rewriteValueLOONG64_OpLOONG64MASKNEZ(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVBUload [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -1736,7 +1738,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVBUload) @@ -1746,7 +1748,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool { return true } // match: (MOVBUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -1758,7 +1760,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVBUload) @@ -1809,8 +1811,10 @@ func rewriteValueLOONG64_OpLOONG64MOVBUreg(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVBload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVBload [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVBload [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -1821,7 +1825,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBload(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVBload) @@ -1831,7 +1835,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBload(v *Value) bool { return true } // match: (MOVBload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -1843,7 +1847,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBload(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVBload) @@ -1895,8 +1899,10 @@ func rewriteValueLOONG64_OpLOONG64MOVBstore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVBstore [off1+int32(off2)] {sym} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -1908,7 +1914,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVBstore) @@ -1918,7 +1924,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstore(v *Value) bool { return true } // match: (MOVBstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -1931,7 +1937,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVBstore) @@ -2047,8 +2053,10 @@ func rewriteValueLOONG64_OpLOONG64MOVBstore(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVBstorezero(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVBstorezero [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2059,7 +2067,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstorezero(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVBstorezero) @@ -2069,7 +2077,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstorezero(v *Value) bool { return true } // match: (MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2081,7 +2089,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstorezero(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVBstorezero) @@ -2095,8 +2103,10 @@ func rewriteValueLOONG64_OpLOONG64MOVBstorezero(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVDload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVDload [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVDload [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2107,7 +2117,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDload(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVDload) @@ -2117,7 +2127,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDload(v *Value) bool { return true } // match: (MOVDload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2129,7 +2139,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDload(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVDload) @@ -2144,8 +2154,10 @@ func rewriteValueLOONG64_OpLOONG64MOVDstore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVDstore [off1+int32(off2)] {sym} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2157,7 +2169,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVDstore) @@ -2167,7 +2179,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDstore(v *Value) bool { return true } // match: (MOVDstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2180,7 +2192,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVDstore) @@ -2194,8 +2206,10 @@ func rewriteValueLOONG64_OpLOONG64MOVDstore(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVFload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVFload [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVFload [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2206,7 +2220,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFload(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVFload) @@ -2216,7 +2230,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFload(v *Value) bool { return true } // match: (MOVFload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2228,7 +2242,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFload(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVFload) @@ -2243,8 +2257,10 @@ func rewriteValueLOONG64_OpLOONG64MOVFstore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVFstore [off1+int32(off2)] {sym} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2256,7 +2272,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVFstore) @@ -2266,7 +2282,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFstore(v *Value) bool { return true } // match: (MOVFstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2279,7 +2295,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVFstore) @@ -2293,8 +2309,10 @@ func rewriteValueLOONG64_OpLOONG64MOVFstore(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVHUload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVHUload [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2305,7 +2323,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHUload(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVHUload) @@ -2315,7 +2333,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHUload(v *Value) bool { return true } // match: (MOVHUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2327,7 +2345,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHUload(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVHUload) @@ -2400,8 +2418,10 @@ func rewriteValueLOONG64_OpLOONG64MOVHUreg(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVHload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVHload [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVHload [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2412,7 +2432,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHload(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVHload) @@ -2422,7 +2442,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHload(v *Value) bool { return true } // match: (MOVHload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2434,7 +2454,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHload(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVHload) @@ -2530,8 +2550,10 @@ func rewriteValueLOONG64_OpLOONG64MOVHstore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVHstore [off1+int32(off2)] {sym} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2543,7 +2565,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVHstore) @@ -2553,7 +2575,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstore(v *Value) bool { return true } // match: (MOVHstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2566,7 +2588,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVHstore) @@ -2648,8 +2670,10 @@ func rewriteValueLOONG64_OpLOONG64MOVHstore(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVHstorezero(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVHstorezero [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2660,7 +2684,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstorezero(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVHstorezero) @@ -2670,7 +2694,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstorezero(v *Value) bool { return true } // match: (MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2682,7 +2706,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstorezero(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVHstorezero) @@ -2696,8 +2720,10 @@ func rewriteValueLOONG64_OpLOONG64MOVHstorezero(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVVload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVVload [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVVload [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2708,7 +2734,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVload(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVVload) @@ -2718,7 +2744,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVload(v *Value) bool { return true } // match: (MOVVload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2730,7 +2756,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVload(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVVload) @@ -2772,8 +2798,10 @@ func rewriteValueLOONG64_OpLOONG64MOVVstore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVVstore [off1+int32(off2)] {sym} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2785,7 +2813,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVVstore) @@ -2795,7 +2823,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstore(v *Value) bool { return true } // match: (MOVVstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2808,7 +2836,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVVstore) @@ -2822,8 +2850,10 @@ func rewriteValueLOONG64_OpLOONG64MOVVstore(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVVstorezero(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVVstorezero [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2834,7 +2864,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstorezero(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVVstorezero) @@ -2844,7 +2874,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstorezero(v *Value) bool { return true } // match: (MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2856,7 +2886,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstorezero(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVVstorezero) @@ -2870,8 +2900,10 @@ func rewriteValueLOONG64_OpLOONG64MOVVstorezero(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVWUload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVWUload [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2882,7 +2914,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWUload(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVWUload) @@ -2892,7 +2924,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWUload(v *Value) bool { return true } // match: (MOVWUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -2904,7 +2936,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWUload(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVWUload) @@ -2999,8 +3031,10 @@ func rewriteValueLOONG64_OpLOONG64MOVWUreg(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVWload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVWload [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVWload [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -3011,7 +3045,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWload(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVWload) @@ -3021,7 +3055,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWload(v *Value) bool { return true } // match: (MOVWload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -3033,7 +3067,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWload(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVWload) @@ -3162,8 +3196,10 @@ func rewriteValueLOONG64_OpLOONG64MOVWstore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVWstore [off1+int32(off2)] {sym} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -3175,7 +3211,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVWstore) @@ -3185,7 +3221,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstore(v *Value) bool { return true } // match: (MOVWstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -3198,7 +3234,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstore(v *Value) bool { ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVWstore) @@ -3246,8 +3282,10 @@ func rewriteValueLOONG64_OpLOONG64MOVWstore(v *Value) bool { func rewriteValueLOONG64_OpLOONG64MOVWstorezero(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block + config := b.Func.Config // match: (MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) - // cond: is32Bit(int64(off1)+off2) + // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVWstorezero [off1+int32(off2)] {sym} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -3258,7 +3296,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstorezero(v *Value) bool { off2 := auxIntToInt64(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(int64(off1) + off2)) { + if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVWstorezero) @@ -3268,7 +3306,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstorezero(v *Value) bool { return true } // match: (MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) + // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) // result: (MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) @@ -3280,7 +3318,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstorezero(v *Value) bool { sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { break } v.reset(OpLOONG64MOVWstorezero) diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go index a4bb7b40a3..d944fcfcb8 100644 --- a/src/cmd/internal/obj/loong64/a.out.go +++ b/src/cmd/internal/obj/loong64/a.out.go @@ -227,6 +227,7 @@ const ( C_ADDR C_TLS_LE C_TLS_IE + C_GOTADDR C_TEXTSIZE C_NCLASS // must be the last diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go index 19250c94ee..64c9226079 100644 --- a/src/cmd/internal/obj/loong64/asm.go +++ b/src/cmd/internal/obj/loong64/asm.go @@ -349,6 +349,8 @@ var optab = []Optab{ {AWORD, C_LCON, C_NONE, C_NONE, C_NONE, C_NONE, 40, 4, 0, 0}, {AWORD, C_DCON, C_NONE, C_NONE, C_NONE, C_NONE, 61, 4, 0, 0}, + {AMOVV, C_GOTADDR, C_NONE, C_NONE, C_REG, C_NONE, 65, 8, 0, 0}, + {ATEQ, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 15, 8, 0, 0}, {ATEQ, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 15, 8, 0, 0}, @@ -676,6 +678,9 @@ func (c *ctxt0) aclass(a *obj.Addr) int { return C_SOREG } return C_LOREG + + case obj.NAME_GOTREF: + return C_GOTADDR } return C_GOK @@ -1776,6 +1781,22 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { case 64: // movv c_reg, c_fcc0 ==> movgr2cf cd, rj a := OP_TEN(8, 1334) o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg)) + + case 65: // mov sym@GOT, r ==> pcalau12i + ld.d + o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg)) + rel := obj.Addrel(c.cursym) + rel.Off = int32(c.pc) + rel.Siz = 4 + rel.Sym = p.From.Sym + rel.Type = objabi.R_LOONG64_GOT_HI + rel.Add = 0x0 + o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg)) + rel2 := obj.Addrel(c.cursym) + rel2.Off = int32(c.pc + 4) + rel2.Siz = 4 + rel2.Sym = p.From.Sym + rel2.Type = objabi.R_LOONG64_GOT_LO + rel2.Add = 0x0 } out[0] = o1 diff --git a/src/cmd/internal/obj/loong64/cnames.go b/src/cmd/internal/obj/loong64/cnames.go index 8b8af6ba31..94b1b54c93 100644 --- a/src/cmd/internal/obj/loong64/cnames.go +++ b/src/cmd/internal/obj/loong64/cnames.go @@ -39,6 +39,7 @@ var cnames0 = []string{ "ADDR", "TLS_LE", "TLS_IE", + "GOTADDR", "TEXTSIZE", "NCLASS", } diff --git a/src/cmd/internal/obj/loong64/obj.go b/src/cmd/internal/obj/loong64/obj.go index d15d0dfd4c..fe98f8c11b 100644 --- a/src/cmd/internal/obj/loong64/obj.go +++ b/src/cmd/internal/obj/loong64/obj.go @@ -6,6 +6,7 @@ package loong64 import ( "cmd/internal/obj" + "cmd/internal/objabi" "cmd/internal/sys" "internal/abi" "log" @@ -84,6 +85,122 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { p.As = AADDVU } } + + if ctxt.Flag_dynlink { + rewriteToUseGot(ctxt, p, newprog) + } +} + +func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { + // ADUFFxxx $offset + // becomes + // MOVV runtime.duffxxx@GOT, REGTMP + // ADD $offset, REGTMP + // JAL REGTMP + if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { + var sym *obj.LSym + if p.As == obj.ADUFFZERO { + sym = ctxt.Lookup("runtime.duffzero") + } else { + sym = ctxt.Lookup("runtime.duffcopy") + } + offset := p.To.Offset + p.As = AMOVV + p.From.Type = obj.TYPE_MEM + p.From.Sym = sym + p.From.Name = obj.NAME_GOTREF + p.To.Type = obj.TYPE_REG + p.To.Reg = REGTMP + p.To.Name = obj.NAME_NONE + p.To.Offset = 0 + p.To.Sym = nil + p1 := obj.Appendp(p, newprog) + p1.As = AADDV + p1.From.Type = obj.TYPE_CONST + p1.From.Offset = offset + p1.To.Type = obj.TYPE_REG + p1.To.Reg = REGTMP + p2 := obj.Appendp(p1, newprog) + p2.As = AJAL + p2.To.Type = obj.TYPE_MEM + p2.To.Reg = REGTMP + } + + // We only care about global data: NAME_EXTERN means a global + // symbol in the Go sense, and p.Sym.Local is true for a few + // internally defined symbols. + if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { + // MOVV $sym, Rx becomes MOVV sym@GOT, Rx + // MOVV $sym+, Rx becomes MOVV sym@GOT, Rx; ADD , Rx + if p.As != AMOVV { + ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -shared", p) + } + if p.To.Type != obj.TYPE_REG { + ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -shared", p) + } + p.From.Type = obj.TYPE_MEM + p.From.Name = obj.NAME_GOTREF + if p.From.Offset != 0 { + q := obj.Appendp(p, newprog) + q.As = AADDV + q.From.Type = obj.TYPE_CONST + q.From.Offset = p.From.Offset + q.To = p.To + p.From.Offset = 0 + } + } + if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN { + ctxt.Diag("don't know how to handle %v with -shared", p) + } + + var source *obj.Addr + // MOVx sym, Ry becomes MOVV sym@GOT, REGTMP; MOVx (REGTMP), Ry + // MOVx Ry, sym becomes MOVV sym@GOT, REGTMP; MOVx Ry, (REGTMP) + // An addition may be inserted between the two MOVs if there is an offset. + if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { + if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { + ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -shared", p) + } + source = &p.From + } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { + source = &p.To + } else { + return + } + if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP { + return + } + if source.Sym.Type == objabi.STLSBSS { + return + } + if source.Type != obj.TYPE_MEM { + ctxt.Diag("don't know how to handle %v with -shared", p) + } + p1 := obj.Appendp(p, newprog) + p2 := obj.Appendp(p1, newprog) + p1.As = AMOVV + p1.From.Type = obj.TYPE_MEM + p1.From.Sym = source.Sym + p1.From.Name = obj.NAME_GOTREF + p1.To.Type = obj.TYPE_REG + p1.To.Reg = REGTMP + + p2.As = p.As + p2.From = p.From + p2.To = p.To + if p.From.Name == obj.NAME_EXTERN { + p2.From.Reg = REGTMP + p2.From.Name = obj.NAME_NONE + p2.From.Sym = nil + } else if p.To.Name == obj.NAME_EXTERN { + p2.To.Reg = REGTMP + p2.To.Name = obj.NAME_NONE + p2.To.Sym = nil + } else { + return + } + + obj.Nopout(p) } func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go index e3e042a511..54429840b0 100644 --- a/src/cmd/internal/objabi/reloctype.go +++ b/src/cmd/internal/objabi/reloctype.go @@ -345,6 +345,11 @@ const ( R_LOONG64_TLS_IE_PCREL_HI R_LOONG64_TLS_IE_LO + // R_LOONG64_GOT_HI and R_LOONG64_GOT_LO resolves a GOT-relative instruction sequence, + // usually an pcalau12i followed by another ld or addi instruction. + R_LOONG64_GOT_HI + R_LOONG64_GOT_LO + // R_JMPLOONG64 resolves to non-PC-relative target address of a JMP instruction, // by encoding the address into the instruction. R_JMPLOONG64 diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go index e8793dedc1..c8923c0f4a 100644 --- a/src/cmd/internal/objabi/reloctype_string.go +++ b/src/cmd/internal/objabi/reloctype_string.go @@ -89,19 +89,21 @@ func _() { _ = x[R_CALLLOONG64-79] _ = x[R_LOONG64_TLS_IE_PCREL_HI-80] _ = x[R_LOONG64_TLS_IE_LO-81] - _ = x[R_JMPLOONG64-82] - _ = x[R_ADDRMIPSU-83] - _ = x[R_ADDRMIPSTLS-84] - _ = x[R_ADDRCUOFF-85] - _ = x[R_WASMIMPORT-86] - _ = x[R_XCOFFREF-87] - _ = x[R_PEIMAGEOFF-88] - _ = x[R_INITORDER-89] + _ = x[R_LOONG64_GOT_HI-82] + _ = x[R_LOONG64_GOT_LO-83] + _ = x[R_JMPLOONG64-84] + _ = x[R_ADDRMIPSU-85] + _ = x[R_ADDRMIPSTLS-86] + _ = x[R_ADDRCUOFF-87] + _ = x[R_WASMIMPORT-88] + _ = x[R_XCOFFREF-89] + _ = x[R_PEIMAGEOFF-90] + _ = x[R_INITORDER-91] } -const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USENAMEDMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_JALR_RISCV_JAL_TRAMPR_RISCV_CALLR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IER_RISCV_TLS_LER_RISCV_GOT_HI20R_RISCV_PCREL_HI20R_RISCV_PCREL_LO12_IR_RISCV_PCREL_LO12_SR_RISCV_BRANCHR_RISCV_RVC_BRANCHR_RISCV_RVC_JUMPR_PCRELDBLR_ADDRLOONG64R_ADDRLOONG64UR_ADDRLOONG64TLSR_ADDRLOONG64TLSUR_CALLLOONG64R_LOONG64_TLS_IE_PCREL_HIR_LOONG64_TLS_IE_LOR_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDER" +const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USENAMEDMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_JALR_RISCV_JAL_TRAMPR_RISCV_CALLR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IER_RISCV_TLS_LER_RISCV_GOT_HI20R_RISCV_PCREL_HI20R_RISCV_PCREL_LO12_IR_RISCV_PCREL_LO12_SR_RISCV_BRANCHR_RISCV_RVC_BRANCHR_RISCV_RVC_JUMPR_PCRELDBLR_ADDRLOONG64R_ADDRLOONG64UR_ADDRLOONG64TLSR_ADDRLOONG64TLSUR_CALLLOONG64R_LOONG64_TLS_IE_PCREL_HIR_LOONG64_TLS_IE_LOR_LOONG64_GOT_HIR_LOONG64_GOT_LOR_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDER" -var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 226, 237, 243, 254, 264, 273, 286, 300, 314, 328, 344, 355, 368, 387, 407, 427, 447, 460, 474, 488, 502, 517, 531, 545, 556, 578, 600, 614, 629, 652, 669, 687, 708, 723, 742, 753, 770, 782, 801, 820, 834, 848, 864, 882, 902, 922, 936, 954, 970, 980, 993, 1007, 1023, 1040, 1053, 1078, 1097, 1109, 1120, 1133, 1144, 1156, 1166, 1178, 1189} +var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 226, 237, 243, 254, 264, 273, 286, 300, 314, 328, 344, 355, 368, 387, 407, 427, 447, 460, 474, 488, 502, 517, 531, 545, 556, 578, 600, 614, 629, 652, 669, 687, 708, 723, 742, 753, 770, 782, 801, 820, 834, 848, 864, 882, 902, 922, 936, 954, 970, 980, 993, 1007, 1023, 1040, 1053, 1078, 1097, 1113, 1129, 1141, 1152, 1165, 1176, 1188, 1198, 1210, 1221} func (i RelocType) String() string { i -= 1 diff --git a/src/cmd/link/internal/loong64/asm.go b/src/cmd/link/internal/loong64/asm.go index 3c58c27d82..fc7bad9039 100644 --- a/src/cmd/link/internal/loong64/asm.go +++ b/src/cmd/link/internal/loong64/asm.go @@ -78,6 +78,16 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, out.Write64(uint64(sectoff)) out.Write64(uint64(elf.R_LARCH_PCALA_HI20) | uint64(elfsym)<<32) out.Write64(uint64(r.Xadd)) + + case objabi.R_LOONG64_GOT_HI: + out.Write64(uint64(sectoff)) + out.Write64(uint64(elf.R_LARCH_GOT_PC_HI20) | uint64(elfsym)<<32) + out.Write64(uint64(0x0)) + + case objabi.R_LOONG64_GOT_LO: + out.Write64(uint64(sectoff)) + out.Write64(uint64(elf.R_LARCH_GOT_PC_LO12) | uint64(elfsym)<<32) + out.Write64(uint64(0x0)) } return true @@ -111,7 +121,9 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade objabi.R_CALLLOONG64, objabi.R_JMPLOONG64, objabi.R_LOONG64_TLS_IE_PCREL_HI, - objabi.R_LOONG64_TLS_IE_LO: + objabi.R_LOONG64_TLS_IE_LO, + objabi.R_LOONG64_GOT_HI, + objabi.R_LOONG64_GOT_LO: return val, 1, true } } @@ -156,7 +168,10 @@ func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) { switch r.Type() { case objabi.R_ADDRLOONG64, - objabi.R_ADDRLOONG64U: + objabi.R_ADDRLOONG64U, + objabi.R_LOONG64_GOT_HI, + objabi.R_LOONG64_GOT_LO: + return ld.ExtrelocViaOuterSym(ldr, r, s), true case objabi.R_ADDRLOONG64TLS, From 08b9640333af248316e168d5a8d3331200fec9e9 Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Tue, 13 Dec 2022 16:51:02 +0800 Subject: [PATCH 14/30] cmd/compile: teach regalloc to rightly do nothing on loong64 in case of dynlinking This is needed before actual support for buildmode=plugin is added. Should not affect current behavior. Change-Id: I86371d7e373fd529cb8710850d7b0fbbf1eb52ca Reviewed-on: https://go-review.googlesource.com/c/go/+/480877 Reviewed-by: David Chase Reviewed-by: Meidan Li Reviewed-by: abner chenc Reviewed-by: Cherry Mui Run-TryBot: WANG Xuerui TryBot-Result: Gopher Robot --- src/cmd/compile/internal/ssa/regalloc.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go index fcd3f5c8b5..2325b9ee45 100644 --- a/src/cmd/compile/internal/ssa/regalloc.go +++ b/src/cmd/compile/internal/ssa/regalloc.go @@ -672,6 +672,8 @@ func (s *regAllocState) init(f *Func) { s.allocatable &^= 1 << 9 // R9 case "arm64": // nothing to do + case "loong64": // R2 (aka TP) already reserved. + // nothing to do case "ppc64le": // R2 already reserved. // nothing to do case "riscv64": // X3 (aka GP) and X4 (aka TP) already reserved. From 945c2bc74e9f3f6a2a011a35b1f03e21f2ad5d4d Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Tue, 15 Aug 2023 17:11:19 +0800 Subject: [PATCH 15/30] cmd/compile: add ABI register definations for loong64 Updates #40724 Co-authored-by: Xiaolin Zhao Change-Id: I56f7382dda58a565b8c3256f1c7845a3031f67de Reviewed-on: https://go-review.googlesource.com/c/go/+/521776 Reviewed-by: Cherry Mui Run-TryBot: David Chase Auto-Submit: David Chase TryBot-Result: Gopher Robot Reviewed-by: David Chase --- src/cmd/compile/abi-internal.md | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/cmd/compile/abi-internal.md b/src/cmd/compile/abi-internal.md index 43dc39689b..eae230dc07 100644 --- a/src/cmd/compile/abi-internal.md +++ b/src/cmd/compile/abi-internal.md @@ -633,6 +633,56 @@ modifying or saving the FPCR. Functions are allowed to modify it between calls (as long as they restore it), but as of this writing Go code never does. +### loong64 architecture + +The loong64 architecture uses R4 – R19 for integer arguments and integer results. + +It uses F0 – F15 for floating-point arguments and results. + +Registers R20 - R21, R23 – R28, R30 - R31, F16 – F31 are permanent scratch registers. + +Register R2 is reserved and never used. + +Register R20, R21 is Used by runtime.duffcopy, runtime.duffzero. + +Special-purpose registers used within Go generated code and Go assembly code +are as follows: + +| Register | Call meaning | Return meaning | Body meaning | +| --- | --- | --- | --- | +| R0 | Zero value | Same | Same | +| R1 | Link register | Link register | Scratch | +| R3 | Stack pointer | Same | Same | +| R20,R21 | Scratch | Scratch | Used by duffcopy, duffzero | +| R22 | Current goroutine | Same | Same | +| R29 | Closure context pointer | Same | Same | +| R30, R31 | used by the assembler | Same | Same | + +*Rationale*: These register meanings are compatible with Go’s stack-based +calling convention. + +#### Stack layout + +The stack pointer, R3, grows down and is aligned to 8 bytes. + +A function's stack frame, after the frame is created, is laid out as +follows: + + +------------------------------+ + | ... locals ... | + | ... outgoing arguments ... | + | return PC | ← R3 points to + +------------------------------+ ↓ lower addresses + +This stack layout is used by both register-based (ABIInternal) and +stack-based (ABI0) calling conventions. + +The "return PC" is loaded to the link register, R1, as part of the +loong64 `JAL` operation. + +#### Flags +All bits in CSR are system flags and are not modified by Go. + ### ppc64 architecture The ppc64 architecture uses R3 – R10 and R14 – R17 for integer arguments From 070139a130bfd914e05dba7245a33e25b5e96399 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Tue, 15 Aug 2023 19:23:51 +0800 Subject: [PATCH 16/30] cmd/compile,cmd/internal,runtime: change registers on loong64 to avoid regABI arguments Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: Ic7e2e7fb4c1d3670e6abbfb817aa6e4e654e08d3 Reviewed-on: https://go-review.googlesource.com/c/go/+/521777 Reviewed-by: David Chase Reviewed-by: Meidan Li Reviewed-by: Cherry Mui Reviewed-by: Than McIntosh Auto-Submit: David Chase TryBot-Result: Gopher Robot Run-TryBot: David Chase --- .../compile/internal/ssa/_gen/LOONG64Ops.go | 8 +- src/cmd/compile/internal/ssa/opGen.go | 12 +-- src/cmd/internal/obj/loong64/obj.go | 68 ++++++++--------- src/runtime/asm_loong64.s | 74 +++++++++---------- 4 files changed, 81 insertions(+), 81 deletions(-) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go index 97aa9590a7..10ffcb8b97 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go @@ -130,10 +130,10 @@ func init() { gpspsbg = gpspg | buildReg("SB") fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31") callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g - r1 = buildReg("R19") - r2 = buildReg("R18") - r3 = buildReg("R17") - r4 = buildReg("R4") + r1 = buildReg("R20") + r2 = buildReg("R21") + r3 = buildReg("R23") + r4 = buildReg("R24") ) // Common regInfo var ( diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 55a50fa284..e39190aaf7 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -24911,8 +24911,8 @@ var opcodeTable = [...]opInfo{ call: true, reg: regInfo{ inputs: []inputInfo{ - {0, 65536}, // R17 - {1, 8}, // R4 + {0, 4194304}, // R23 + {1, 8388608}, // R24 }, }, }, @@ -24923,8 +24923,8 @@ var opcodeTable = [...]opInfo{ call: true, reg: regInfo{ inputs: []inputInfo{ - {0, 131072}, // R18 - {1, 65536}, // R17 + {0, 1048576}, // R21 + {1, 4194304}, // R23 }, }, }, @@ -24935,8 +24935,8 @@ var opcodeTable = [...]opInfo{ call: true, reg: regInfo{ inputs: []inputInfo{ - {0, 262144}, // R19 - {1, 131072}, // R18 + {0, 524288}, // R20 + {1, 1048576}, // R21 }, }, }, diff --git a/src/cmd/internal/obj/loong64/obj.go b/src/cmd/internal/obj/loong64/obj.go index fe98f8c11b..bc9cf2ec22 100644 --- a/src/cmd/internal/obj/loong64/obj.go +++ b/src/cmd/internal/obj/loong64/obj.go @@ -396,13 +396,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { if c.cursym.Func().Text.From.Sym.Wrapper() && c.cursym.Func().Text.Mark&LEAF == 0 { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // - // MOV g_panic(g), R1 - // BEQ R1, end - // MOV panic_argp(R1), R2 - // ADD $(autosize+FIXED_FRAME), R29, R3 - // BNE R2, R3, end - // ADD $FIXED_FRAME, R29, R2 - // MOV R2, panic_argp(R1) + // MOV g_panic(g), R20 + // BEQ R20, end + // MOV panic_argp(R20), R24 + // ADD $(autosize+FIXED_FRAME), R3, R30 + // BNE R24, R30, end + // ADD $FIXED_FRAME, R3, R24 + // MOV R24, panic_argp(R20) // end: // NOP // @@ -419,12 +419,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q.From.Reg = REGG q.From.Offset = 4 * int64(c.ctxt.Arch.PtrSize) // G.panic q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R19 + q.To.Reg = REG_R20 q = obj.Appendp(q, newprog) q.As = ABEQ q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R19 + q.From.Reg = REG_R20 q.To.Type = obj.TYPE_BRANCH q.Mark |= BRANCH p1 = q @@ -432,10 +432,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q = obj.Appendp(q, newprog) q.As = mov q.From.Type = obj.TYPE_MEM - q.From.Reg = REG_R19 + q.From.Reg = REG_R20 q.From.Offset = 0 // Panic.argp q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R4 + q.To.Reg = REG_R24 q = obj.Appendp(q, newprog) q.As = add @@ -443,13 +443,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q.From.Offset = int64(autosize) + ctxt.Arch.FixedFrameSize q.Reg = REGSP q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R5 + q.To.Reg = REG_R30 q = obj.Appendp(q, newprog) q.As = ABNE q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R4 - q.Reg = REG_R5 + q.From.Reg = REG_R24 + q.Reg = REG_R30 q.To.Type = obj.TYPE_BRANCH q.Mark |= BRANCH p2 = q @@ -460,14 +460,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q.From.Offset = ctxt.Arch.FixedFrameSize q.Reg = REGSP q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R4 + q.To.Reg = REG_R24 q = obj.Appendp(q, newprog) q.As = mov q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R4 + q.From.Reg = REG_R24 q.To.Type = obj.TYPE_MEM - q.To.Reg = REG_R19 + q.To.Reg = REG_R20 q.To.Offset = 0 // Panic.argp q = obj.Appendp(q, newprog) @@ -690,7 +690,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { // Jump back to here after morestack returns. startPred := p - // MOV g_stackguard(g), R19 + // MOV g_stackguard(g), R20 p = obj.Appendp(p, c.newprog) p.As = mov @@ -701,7 +701,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { p.From.Offset = 3 * int64(c.ctxt.Arch.PtrSize) // G.stackguard1 } p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R19 + p.To.Reg = REG_R20 // Mark the stack bound check and morestack call async nonpreemptible. // If we get preempted here, when resumed the preemption request is @@ -712,15 +712,15 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { var q *obj.Prog if framesize <= abi.StackSmall { // small stack: SP < stackguard - // AGTU SP, stackguard, R19 + // AGTU SP, stackguard, R20 p = obj.Appendp(p, c.newprog) p.As = ASGTU p.From.Type = obj.TYPE_REG p.From.Reg = REGSP - p.Reg = REG_R19 + p.Reg = REG_R20 p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R19 + p.To.Reg = REG_R20 } else { // large stack: SP-framesize < stackguard-StackSmall offset := int64(framesize) - abi.StackSmall @@ -732,8 +732,8 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { // stack guard to incorrectly succeed. We explicitly // guard against underflow. // - // SGTU $(framesize-StackSmall), SP, R4 - // BNE R4, label-of-call-to-morestack + // SGTU $(framesize-StackSmall), SP, R24 + // BNE R24, label-of-call-to-morestack p = obj.Appendp(p, c.newprog) p.As = ASGTU @@ -741,13 +741,13 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { p.From.Offset = offset p.Reg = REGSP p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 + p.To.Reg = REG_R24 p = obj.Appendp(p, c.newprog) q = p p.As = ABNE p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R4 + p.From.Reg = REG_R24 p.To.Type = obj.TYPE_BRANCH p.Mark |= BRANCH } @@ -759,35 +759,35 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { p.From.Offset = -offset p.Reg = REGSP p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 + p.To.Reg = REG_R24 p = obj.Appendp(p, c.newprog) p.As = ASGTU p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R4 - p.Reg = REG_R19 + p.From.Reg = REG_R24 + p.Reg = REG_R20 p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R19 + p.To.Reg = REG_R20 } - // q1: BNE R19, done + // q1: BNE R20, done p = obj.Appendp(p, c.newprog) q1 := p p.As = ABNE p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R19 + p.From.Reg = REG_R20 p.To.Type = obj.TYPE_BRANCH p.Mark |= BRANCH - // MOV LINK, R5 + // MOV LINK, R31 p = obj.Appendp(p, c.newprog) p.As = mov p.From.Type = obj.TYPE_REG p.From.Reg = REGLINK p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R5 + p.To.Reg = REG_R31 if q != nil { q.To.SetTarget(p) p.Mark |= LABEL diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s index 6ffa1392c4..93550b9342 100644 --- a/src/runtime/asm_loong64.s +++ b/src/runtime/asm_loong64.s @@ -214,7 +214,7 @@ noswitch: // Called during function prolog when more stack is needed. // Caller has already loaded: -// loong64: R5: LR +// loong64: R31: LR // // The traceback routines see morestack on a g0 as being // the top of a stack (for example, morestack calling newstack @@ -238,12 +238,12 @@ TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0 // Set g->sched to context in f. MOVV R3, (g_sched+gobuf_sp)(g) MOVV R1, (g_sched+gobuf_pc)(g) - MOVV R5, (g_sched+gobuf_lr)(g) + MOVV R31, (g_sched+gobuf_lr)(g) MOVV REGCTXT, (g_sched+gobuf_ctxt)(g) // Called from f. // Set m->morebuf to f's caller. - MOVV R5, (m_morebuf+gobuf_pc)(R7) // f's caller's PC + MOVV R31, (m_morebuf+gobuf_pc)(R7) // f's caller's PC MOVV R3, (m_morebuf+gobuf_sp)(R7) // f's caller's SP MOVV g, (m_morebuf+gobuf_g)(R7) @@ -775,70 +775,70 @@ TEXT runtime·gcWriteBarrier8(SB),NOSPLIT,$0 // then tail call to the corresponding runtime handler. // The tail call makes these stubs disappear in backtraces. TEXT runtime·panicIndex(SB),NOSPLIT,$0-16 - MOVV R19, x+0(FP) - MOVV R18, y+8(FP) + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) JMP runtime·goPanicIndex(SB) TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16 - MOVV R19, x+0(FP) - MOVV R18, y+8(FP) + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) JMP runtime·goPanicIndexU(SB) TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16 - MOVV R18, x+0(FP) - MOVV R17, y+8(FP) + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) JMP runtime·goPanicSliceAlen(SB) TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16 - MOVV R18, x+0(FP) - MOVV R17, y+8(FP) + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) JMP runtime·goPanicSliceAlenU(SB) TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16 - MOVV R18, x+0(FP) - MOVV R17, y+8(FP) + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) JMP runtime·goPanicSliceAcap(SB) TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16 - MOVV R18, x+0(FP) - MOVV R17, y+8(FP) + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) JMP runtime·goPanicSliceAcapU(SB) TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16 - MOVV R19, x+0(FP) - MOVV R18, y+8(FP) + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) JMP runtime·goPanicSliceB(SB) TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16 - MOVV R19, x+0(FP) - MOVV R18, y+8(FP) + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) JMP runtime·goPanicSliceBU(SB) TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16 - MOVV R17, x+0(FP) - MOVV R4, y+8(FP) + MOVV R23, x+0(FP) + MOVV R24, y+8(FP) JMP runtime·goPanicSlice3Alen(SB) TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16 - MOVV R17, x+0(FP) - MOVV R4, y+8(FP) + MOVV R23, x+0(FP) + MOVV R24, y+8(FP) JMP runtime·goPanicSlice3AlenU(SB) TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16 - MOVV R17, x+0(FP) - MOVV R4, y+8(FP) + MOVV R23, x+0(FP) + MOVV R24, y+8(FP) JMP runtime·goPanicSlice3Acap(SB) TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16 - MOVV R17, x+0(FP) - MOVV R4, y+8(FP) + MOVV R23, x+0(FP) + MOVV R24, y+8(FP) JMP runtime·goPanicSlice3AcapU(SB) TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16 - MOVV R18, x+0(FP) - MOVV R17, y+8(FP) + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) JMP runtime·goPanicSlice3B(SB) TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16 - MOVV R18, x+0(FP) - MOVV R17, y+8(FP) + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) JMP runtime·goPanicSlice3BU(SB) TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16 - MOVV R19, x+0(FP) - MOVV R18, y+8(FP) + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) JMP runtime·goPanicSlice3C(SB) TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16 - MOVV R19, x+0(FP) - MOVV R18, y+8(FP) + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) JMP runtime·goPanicSlice3CU(SB) TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16 - MOVV R17, x+0(FP) - MOVV R4, y+8(FP) + MOVV R23, x+0(FP) + MOVV R24, y+8(FP) JMP runtime·goPanicSliceConvert(SB) From 7b26cb954050291b593b36170d25214e948ceba5 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Tue, 15 Aug 2023 19:38:33 +0800 Subject: [PATCH 17/30] internal/abi: define loong64 regABI constants Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: Id580d9e22a562adee2ae02a467ac38a54949e737 Reviewed-on: https://go-review.googlesource.com/c/go/+/521778 Reviewed-by: David Chase Auto-Submit: David Chase Reviewed-by: Meidan Li Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot Run-TryBot: David Chase --- src/internal/abi/abi_loong64.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/internal/abi/abi_loong64.go diff --git a/src/internal/abi/abi_loong64.go b/src/internal/abi/abi_loong64.go new file mode 100644 index 0000000000..c2306ae8d8 --- /dev/null +++ b/src/internal/abi/abi_loong64.go @@ -0,0 +1,19 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build goexperiment.regabiargs + +package abi + +const ( + // See abi_generic.go. + + // R4 - R19 + IntArgRegs = 16 + + // F0 - F15 + FloatArgRegs = 16 + + EffectiveFloatRegSize = 8 +) From d7fcb5cf80953f1d63246f1ae9defa60c5ce2d76 Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Tue, 13 Dec 2022 16:30:45 +0800 Subject: [PATCH 18/30] cmd/dist, cmd/link, internal, runtime: implement buildmode=plugin for linux/loong64 According to review, buildmode=shared has unfixed shortcomings and should be considered legacy at this time. So only buildmode=plugin is going to be added for loong64 which is a relatively new platform. Change-Id: Iac0b9f57e4ee01755458e180bb24d1b2a146fdf0 Reviewed-on: https://go-review.googlesource.com/c/go/+/480878 TryBot-Result: Gopher Robot Reviewed-by: Michael Knyszek Run-TryBot: WANG Xuerui Reviewed-by: David Chase Reviewed-by: abner chenc Reviewed-by: Meidan Li --- src/cmd/dist/test.go | 2 +- src/cmd/link/internal/loong64/asm.go | 42 +++++++++++++++++++++++++++- src/internal/platform/supported.go | 2 +- src/runtime/asm_loong64.s | 11 ++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go index 9635c4fb61..4450129e08 100644 --- a/src/cmd/dist/test.go +++ b/src/cmd/dist/test.go @@ -1627,7 +1627,7 @@ func buildModeSupported(compiler, buildmode, goos, goarch string) bool { case "plugin": switch platform { - case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le", + case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/s390x", "linux/ppc64le", "android/amd64", "android/386", "darwin/amd64", "darwin/arm64", "freebsd/amd64": diff --git a/src/cmd/link/internal/loong64/asm.go b/src/cmd/link/internal/loong64/asm.go index fc7bad9039..6607e5dc64 100644 --- a/src/cmd/link/internal/loong64/asm.go +++ b/src/cmd/link/internal/loong64/asm.go @@ -14,7 +14,47 @@ import ( "log" ) -func gentext(ctxt *ld.Link, ldr *loader.Loader) {} +func gentext(ctxt *ld.Link, ldr *loader.Loader) { + initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt) + if initfunc == nil { + return + } + + o := func(op uint32) { + initfunc.AddUint32(ctxt.Arch, op) + } + + // Emit the following function: + // + // local.dso_init: + // la.pcrel $a0, local.moduledata + // b runtime.addmoduledata + + // 0000000000000000 : + // 0: 1a000004 pcalau12i $a0, 0 + // 0: R_LARCH_PCALA_HI20 local.moduledata + o(0x1a000004) + rel, _ := initfunc.AddRel(objabi.R_ADDRLOONG64U) + rel.SetOff(0) + rel.SetSiz(4) + rel.SetSym(ctxt.Moduledata) + + // 4: 02c00084 addi.d $a0, $a0, 0 + // 4: R_LARCH_PCALA_LO12 local.moduledata + o(0x02c00084) + rel2, _ := initfunc.AddRel(objabi.R_ADDRLOONG64) + rel2.SetOff(4) + rel2.SetSiz(4) + rel2.SetSym(ctxt.Moduledata) + + // 8: 50000000 b 0 + // 8: R_LARCH_B26 runtime.addmoduledata + o(0x50000000) + rel3, _ := initfunc.AddRel(objabi.R_CALLLOONG64) + rel3.SetOff(8) + rel3.SetSiz(4) + rel3.SetSym(addmoduledata) +} func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool { log.Fatalf("adddynrel not implemented") diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go index 4589903550..82c66e2195 100644 --- a/src/internal/platform/supported.go +++ b/src/internal/platform/supported.go @@ -206,7 +206,7 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { case "plugin": switch platform { - case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le", + case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/s390x", "linux/ppc64le", "android/amd64", "android/386", "darwin/amd64", "darwin/arm64", "freebsd/amd64": diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s index 93550b9342..8a1eae3740 100644 --- a/src/runtime/asm_loong64.s +++ b/src/runtime/asm_loong64.s @@ -642,6 +642,17 @@ TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0 // traceback from goexit1 must hit code range of goexit NOOP +// This is called from .init_array and follows the platform, not Go, ABI. +TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0 + ADDV $-0x10, R3 + MOVV R30, 8(R3) // The access to global variables below implicitly uses R30, which is callee-save + MOVV runtime·lastmoduledatap(SB), R12 + MOVV R4, moduledata_next(R12) + MOVV R4, runtime·lastmoduledatap(SB) + MOVV 8(R3), R30 + ADDV $0x10, R3 + RET + TEXT ·checkASM(SB),NOSPLIT,$0-1 MOVW $1, R19 MOVB R19, ret+0(FP) From 4bfed5ce748a2dbb3f1e35b42949dd3a53601186 Mon Sep 17 00:00:00 2001 From: Mauri de Souza Meneguzzo Date: Tue, 21 Nov 2023 01:02:31 +0000 Subject: [PATCH 19/30] runtime/internal/atomic: deduplicate And/Or code on arm Turns out after adding the generic implementation for And/Or we ended up with duplicated ops that are exactly the same for arm. Apologies for the oversight, this CL removes the redundant arm code and adds arm to the generic build flags. For #61395 Change-Id: Id5e5a5cf113774948f8e772592e898d0810ad1f6 GitHub-Last-Rev: 4d8c857d15f0267ee0c8bb88a202afd49a6075dc GitHub-Pull-Request: golang/go#64299 Reviewed-on: https://go-review.googlesource.com/c/go/+/544017 LUCI-TryBot-Result: Go LUCI Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot Reviewed-by: Michael Knyszek Run-TryBot: Cherry Mui --- .../internal/atomic/atomic_andor_generic.go | 2 +- src/runtime/internal/atomic/atomic_arm.go | 60 ------------------- 2 files changed, 1 insertion(+), 61 deletions(-) diff --git a/src/runtime/internal/atomic/atomic_andor_generic.go b/src/runtime/internal/atomic/atomic_andor_generic.go index c790e062c5..57f80ff871 100644 --- a/src/runtime/internal/atomic/atomic_andor_generic.go +++ b/src/runtime/internal/atomic/atomic_andor_generic.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build s390x || loong64 || mips || mipsle || mips64 || mips64le +//go:build arm || s390x || loong64 || mips || mipsle || mips64 || mips64le package atomic diff --git a/src/runtime/internal/atomic/atomic_arm.go b/src/runtime/internal/atomic/atomic_arm.go index ae609cf4db..567e951244 100644 --- a/src/runtime/internal/atomic/atomic_arm.go +++ b/src/runtime/internal/atomic/atomic_arm.go @@ -208,66 +208,6 @@ func And(addr *uint32, v uint32) { } } -//go:nosplit -func Or32(addr *uint32, v uint32) uint32 { - for { - old := *addr - if Cas(addr, old, old|v) { - return old - } - } -} - -//go:nosplit -func And32(addr *uint32, v uint32) uint32 { - for { - old := *addr - if Cas(addr, old, old&v) { - return old - } - } -} - -//go:nosplit -func Or64(addr *uint64, v uint64) uint64 { - for { - old := *addr - if Cas64(addr, old, old|v) { - return old - } - } -} - -//go:nosplit -func And64(addr *uint64, v uint64) uint64 { - for { - old := *addr - if Cas64(addr, old, old&v) { - return old - } - } -} - -//go:nosplit -func Oruintptr(addr *uintptr, v uintptr) uintptr { - for { - old := *addr - if Casuintptr(addr, old, old|v) { - return old - } - } -} - -//go:nosplit -func Anduintptr(addr *uintptr, v uintptr) uintptr { - for { - old := *addr - if Casuintptr(addr, old, old&v) { - return old - } - } -} - //go:nosplit func armcas(ptr *uint32, old, new uint32) bool From ebca52eeb77f24f44c9b556b99508a9a6fada743 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Tue, 15 Aug 2023 19:54:51 +0800 Subject: [PATCH 20/30] cmd/compile/internal: add register info for loong64 regABI Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: Ifd7d94147b01e4fc83978b53dca2bcc0ad1ac4e3 Reviewed-on: https://go-review.googlesource.com/c/go/+/521779 Reviewed-by: David Chase Run-TryBot: David Chase TryBot-Result: Gopher Robot Auto-Submit: David Chase Reviewed-by: Cherry Mui Reviewed-by: Meidan Li --- src/cmd/compile/internal/loong64/ssa.go | 2 ++ src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go | 4 ++-- src/cmd/compile/internal/ssa/config.go | 2 ++ src/cmd/compile/internal/ssa/opGen.go | 4 ++-- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go index ad465ba3bb..06490a7ba5 100644 --- a/src/cmd/compile/internal/loong64/ssa.go +++ b/src/cmd/compile/internal/loong64/ssa.go @@ -144,6 +144,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { p.From.Type = obj.TYPE_REG p.From.Reg = r ssagen.AddrAuto(&p.To, v) + case ssa.OpArgIntReg, ssa.OpArgFloatReg: + ssagen.CheckArgReg(v) case ssa.OpLOONG64ADDV, ssa.OpLOONG64SUBV, ssa.OpLOONG64AND, diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go index 10ffcb8b97..845d5491e2 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go @@ -476,8 +476,8 @@ func init() { blocks: blocks, regnames: regNamesLOONG64, // TODO: support register ABI on loong64 - ParamIntRegNames: "R4 R5 R6 R7 R8 R9 R10 R11", - ParamFloatRegNames: "F0 F1 F2 F3 F4 F5 F6 F7", + ParamIntRegNames: "R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19", + ParamFloatRegNames: "F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15", gpregmask: gp, fpregmask: fp, framepointerreg: -1, // not used diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go index da4294d871..c36ac4cd5d 100644 --- a/src/cmd/compile/internal/ssa/config.go +++ b/src/cmd/compile/internal/ssa/config.go @@ -283,6 +283,8 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo c.registers = registersLOONG64[:] c.gpRegMask = gpRegMaskLOONG64 c.fpRegMask = fpRegMaskLOONG64 + // c.intParamRegs = paramIntRegLOONG64 + // c.floatParamRegs = paramFloatRegLOONG64 c.FPReg = framepointerRegLOONG64 c.LinkReg = linkRegLOONG64 c.hasGReg = true diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index e39190aaf7..7ad7209366 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -40751,8 +40751,8 @@ var registersLOONG64 = [...]Register{ {61, loong64.REG_F31, -1, "F31"}, {62, 0, -1, "SB"}, } -var paramIntRegLOONG64 = []int8{3, 4, 5, 6, 7, 8, 9, 10} -var paramFloatRegLOONG64 = []int8{30, 31, 32, 33, 34, 35, 36, 37} +var paramIntRegLOONG64 = []int8{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18} +var paramFloatRegLOONG64 = []int8{30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45} var gpRegMaskLOONG64 = regMask(1071644664) var fpRegMaskLOONG64 = regMask(4611686017353646080) var specialRegMaskLOONG64 = regMask(0) From bd224fa5222ffb5f8dcbba59400d36f1f777b3ec Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Tue, 15 Aug 2023 20:10:33 +0800 Subject: [PATCH 21/30] cmd/compile/internal: add spill support for loong64 regABI Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: Ic01d59bd81420b89c6d4b90c5975bf069d08e7cc Reviewed-on: https://go-review.googlesource.com/c/go/+/521780 Reviewed-by: David Chase Auto-Submit: David Chase Reviewed-by: Cherry Mui Reviewed-by: Meidan Li TryBot-Result: Gopher Robot Run-TryBot: David Chase --- src/cmd/compile/internal/loong64/galign.go | 2 ++ src/cmd/compile/internal/loong64/ssa.go | 31 +++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/loong64/galign.go b/src/cmd/compile/internal/loong64/galign.go index 99ab7bdfb5..a613165054 100644 --- a/src/cmd/compile/internal/loong64/galign.go +++ b/src/cmd/compile/internal/loong64/galign.go @@ -20,4 +20,6 @@ func Init(arch *ssagen.ArchInfo) { arch.SSAMarkMoves = func(s *ssagen.State, b *ssa.Block) {} arch.SSAGenValue = ssaGenValue arch.SSAGenBlock = ssaGenBlock + arch.LoadRegResult = loadRegResult + arch.SpillArgReg = spillArgReg } diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go index 06490a7ba5..e7298bdb9f 100644 --- a/src/cmd/compile/internal/loong64/ssa.go +++ b/src/cmd/compile/internal/loong64/ssa.go @@ -10,6 +10,7 @@ import ( "cmd/compile/internal/base" "cmd/compile/internal/ir" "cmd/compile/internal/logopt" + "cmd/compile/internal/objw" "cmd/compile/internal/ssa" "cmd/compile/internal/ssagen" "cmd/compile/internal/types" @@ -145,6 +146,16 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { p.From.Reg = r ssagen.AddrAuto(&p.To, v) case ssa.OpArgIntReg, ssa.OpArgFloatReg: + // The assembler needs to wrap the entry safepoint/stack growth code with spill/unspill + // The loop only runs once. + for _, a := range v.Block.Func.RegArgs { + // Pass the spill/unspill information along to the assembler, offset by size of + // the saved LR slot. + addr := ssagen.SpillSlotAddr(a, loong64.REGSP, base.Ctxt.Arch.FixedFrameSize) + s.FuncInfo().AddSpill( + obj.RegSpill{Reg: a.Reg, Addr: addr, Unspill: loadByType(a.Type, a.Reg), Spill: storeByType(a.Type, a.Reg)}) + } + v.Block.Func.RegArgs = nil ssagen.CheckArgReg(v) case ssa.OpLOONG64ADDV, ssa.OpLOONG64SUBV, @@ -370,7 +381,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { p.To.Name = obj.NAME_EXTERN p.To.Sym = ir.Syms.Duffzero p.To.Offset = v.AuxInt - case ssa.OpLOONG64LoweredZero: // MOVx R0, (Rarg0) // ADDV $sz, Rarg0 @@ -799,3 +809,22 @@ func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) { b.Fatalf("branch not implemented: %s", b.LongString()) } } + +func loadRegResult(s *ssagen.State, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog { + p := s.Prog(loadByType(t, reg)) + p.From.Type = obj.TYPE_MEM + p.From.Name = obj.NAME_AUTO + p.From.Sym = n.Linksym() + p.From.Offset = n.FrameOffset() + off + p.To.Type = obj.TYPE_REG + p.To.Reg = reg + return p +} + +func spillArgReg(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog { + p = pp.Append(p, storeByType(t, reg), obj.TYPE_REG, reg, 0, obj.TYPE_MEM, 0, n.FrameOffset()+off) + p.To.Name = obj.NAME_PARAM + p.To.Sym = n.Linksym() + p.Pos = p.Pos.WithNotStmt() + return p +} From 6b77d1b73694b50f2eccc1a2e1e09cc951393cce Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Tue, 15 Aug 2023 20:23:46 +0800 Subject: [PATCH 22/30] cmd/compile: update loong64 CALL* ops allow the loong64 CALL* ops to take variable number of args Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: I4706d9651fcbf9a0f201af6820c97b1a924f14e3 Reviewed-on: https://go-review.googlesource.com/c/go/+/521781 Auto-Submit: David Chase Reviewed-by: Cherry Mui Run-TryBot: David Chase TryBot-Result: Gopher Robot Reviewed-by: Meidan Li Reviewed-by: David Chase --- src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go | 8 ++++---- src/cmd/compile/internal/ssa/opGen.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go index 845d5491e2..3fbf5be499 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go @@ -273,10 +273,10 @@ func init() { {name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"}, // float64 -> float32 // function calls - {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem - {name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true}, // tail call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem - {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R29"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem - {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + {name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). last arg=mem, auxint=argsize, returns mem + {name: "CALLtail", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true}, // tail call static function aux.(*obj.LSym). last arg=mem, auxint=argsize, returns mem + {name: "CALLclosure", argLength: -1, reg: regInfo{inputs: []regMask{gpsp, buildReg("R29"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, last arg=mem, auxint=argsize, returns mem + {name: "CALLinter", argLength: -1, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, last arg=mem, auxint=argsize, returns mem // duffzero // arg0 = address of memory to zero diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 7ad7209366..c552832520 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -24499,7 +24499,7 @@ var opcodeTable = [...]opInfo{ { name: "CALLstatic", auxType: auxCallOff, - argLen: 1, + argLen: -1, clobberFlags: true, call: true, reg: regInfo{ @@ -24509,7 +24509,7 @@ var opcodeTable = [...]opInfo{ { name: "CALLtail", auxType: auxCallOff, - argLen: 1, + argLen: -1, clobberFlags: true, call: true, tailCall: true, @@ -24520,7 +24520,7 @@ var opcodeTable = [...]opInfo{ { name: "CALLclosure", auxType: auxCallOff, - argLen: 3, + argLen: -1, clobberFlags: true, call: true, reg: regInfo{ @@ -24534,7 +24534,7 @@ var opcodeTable = [...]opInfo{ { name: "CALLinter", auxType: auxCallOff, - argLen: 2, + argLen: -1, clobberFlags: true, call: true, reg: regInfo{ From 3107fa99acdcf26394e4bd96a176622d4034b10f Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Tue, 15 Aug 2023 20:54:16 +0800 Subject: [PATCH 23/30] runtime: make duff device as ABIInternal for loong64 Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: I243e60489dc5fd162ad91d6426bf32cf0e13d9e2 Reviewed-on: https://go-review.googlesource.com/c/go/+/521782 Reviewed-by: Meidan Li Reviewed-by: David Chase Run-TryBot: David Chase Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot Auto-Submit: David Chase --- src/runtime/duff_loong64.s | 4 ++-- src/runtime/mkduff.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/runtime/duff_loong64.s b/src/runtime/duff_loong64.s index df8b653965..b05502d91d 100644 --- a/src/runtime/duff_loong64.s +++ b/src/runtime/duff_loong64.s @@ -4,7 +4,7 @@ #include "textflag.h" -TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0 +TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0 MOVV R0, (R20) ADDV $8, R20 MOVV R0, (R20) @@ -263,7 +263,7 @@ TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0 ADDV $8, R20 RET -TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0 +TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0 MOVV (R20), R30 ADDV $8, R20 MOVV R30, (R21) diff --git a/src/runtime/mkduff.go b/src/runtime/mkduff.go index 77674254d4..b7f07b5087 100644 --- a/src/runtime/mkduff.go +++ b/src/runtime/mkduff.go @@ -181,7 +181,7 @@ func zeroLOONG64(w io.Writer) { // R0: always zero // R19 (aka REGRT1): ptr to memory to be zeroed // On return, R19 points to the last zeroed dword. - fmt.Fprintln(w, "TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0") + fmt.Fprintln(w, "TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0") for i := 0; i < 128; i++ { fmt.Fprintln(w, "\tMOVV\tR0, (R20)") fmt.Fprintln(w, "\tADDV\t$8, R20") @@ -190,7 +190,7 @@ func zeroLOONG64(w io.Writer) { } func copyLOONG64(w io.Writer) { - fmt.Fprintln(w, "TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0") + fmt.Fprintln(w, "TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0") for i := 0; i < 128; i++ { fmt.Fprintln(w, "\tMOVV\t(R20), R30") fmt.Fprintln(w, "\tADDV\t$8, R20") From f6f141ab80853b0b45f7e33aa148e497ceeb7d38 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Tue, 15 Aug 2023 21:09:16 +0800 Subject: [PATCH 24/30] runtime: support regABI and add spill functions in runtime for loong64 Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: I709b818ef15c33f95251186d749ac13260ad36be Reviewed-on: https://go-review.googlesource.com/c/go/+/521783 Reviewed-by: David Chase Reviewed-by: Meidan Li Run-TryBot: David Chase Auto-Submit: David Chase Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot --- src/runtime/asm_loong64.s | 295 ++++++++++++++++++++++++++++------- src/runtime/stubs_loong64.go | 7 + 2 files changed, 243 insertions(+), 59 deletions(-) diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s index 8a1eae3740..586bd23ed4 100644 --- a/src/runtime/asm_loong64.s +++ b/src/runtime/asm_loong64.s @@ -72,7 +72,7 @@ nocgo: MOVV R0, 1(R0) RET -DATA runtime·mainPC+0(SB)/8,$runtime·main(SB) +DATA runtime·mainPC+0(SB)/8,$runtime·main(SB) GLOBL runtime·mainPC(SB),RODATA,$8 TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0 @@ -123,26 +123,31 @@ TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0 // Switch to m->g0's stack, call fn(g). // Fn must never return. It should gogo(&g->sched) // to keep running g. -TEXT runtime·mcall(SB), NOSPLIT|NOFRAME, $0-8 +TEXT runtime·mcall(SB), NOSPLIT|NOFRAME, $0-8 +#ifdef GOEXPERIMENT_regabiargs + MOVV R4, REGCTXT +#else + MOVV fn+0(FP), REGCTXT +#endif + // Save caller state in g->sched MOVV R3, (g_sched+gobuf_sp)(g) MOVV R1, (g_sched+gobuf_pc)(g) MOVV R0, (g_sched+gobuf_lr)(g) // Switch to m->g0 & its stack, call fn. - MOVV g, R19 - MOVV g_m(g), R4 - MOVV m_g0(R4), g + MOVV g, R4 // arg = g + MOVV g_m(g), R20 + MOVV m_g0(R20), g JAL runtime·save_g(SB) - BNE g, R19, 2(PC) + BNE g, R4, 2(PC) JMP runtime·badmcall(SB) - MOVV fn+0(FP), REGCTXT // context - MOVV 0(REGCTXT), R5 // code pointer + MOVV 0(REGCTXT), R20 // code pointer MOVV (g_sched+gobuf_sp)(g), R3 // sp = m->g0->sched.sp ADDV $-16, R3 - MOVV R19, 8(R3) + MOVV R4, 8(R3) MOVV R0, 0(R3) - JAL (R5) + JAL (R20) JMP runtime·badmcall2(SB) // systemstack_switch is a dummy routine that systemstack leaves at the bottom @@ -272,7 +277,7 @@ TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0 JMP runtime·morestack(SB) // reflectcall: call a function with the given argument list -// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32). +// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs). // we don't have variable-sized frames, so we use a small number // of constant-sized-frame functions to encode a few bits of size in the pc. // Caution: ugly multiline assembly macros in your future! @@ -286,7 +291,7 @@ TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0 // Note: can't just "BR NAME(SB)" - bad inlining results. TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48 - MOVWU stackArgsSize+24(FP), R19 + MOVWU frameSize+32(FP), R19 DISPATCH(runtime·call32, 32) DISPATCH(runtime·call64, 64) DISPATCH(runtime·call128, 128) @@ -317,7 +322,7 @@ TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48 JMP (R4) #define CALLFN(NAME,MAXSIZE) \ -TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \ +TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \ NO_LOCAL_POINTERS; \ /* copy arguments to stack */ \ MOVV arg+16(FP), R4; \ @@ -331,12 +336,17 @@ TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \ MOVBU R6, (R12); \ ADDV $1, R12; \ JMP -5(PC); \ + /* set up argument registers */ \ + MOVV regArgs+40(FP), R25; \ + JAL ·unspillArgs(SB); \ /* call function */ \ MOVV f+8(FP), REGCTXT; \ - MOVV (REGCTXT), R6; \ + MOVV (REGCTXT), R25; \ PCDATA $PCDATA_StackMapIndex, $0; \ - JAL (R6); \ + JAL (R25); \ /* copy return values back */ \ + MOVV regArgs+40(FP), R25; \ + JAL ·spillArgs(SB); \ MOVV argtype+0(FP), R7; \ MOVV arg+16(FP), R4; \ MOVWU n+24(FP), R5; \ @@ -352,11 +362,13 @@ TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \ // separate function so it can allocate stack space for the arguments // to reflectcallmove. It does not follow the Go ABI; it expects its // arguments in registers. -TEXT callRet<>(SB), NOSPLIT, $32-0 +TEXT callRet<>(SB), NOSPLIT, $40-0 + NO_LOCAL_POINTERS MOVV R7, 8(R3) MOVV R4, 16(R3) MOVV R12, 24(R3) MOVV R5, 32(R3) + MOVV R25, 40(R3) JAL runtime·reflectcallmove(SB) RET @@ -567,7 +579,7 @@ havem: // If the m on entry wasn't nil, // 1. the thread might be a Go thread, // 2. or it wasn't the first call from a C thread on pthread platforms, - // since then we skip dropm to reuse the m in the first call. + // since then we skip dropm to resue the m in the first call. MOVV savedm-8(SP), R12 BNE R12, droppedm @@ -604,14 +616,14 @@ TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0 UNDEF // AES hashing not implemented for loong64 -TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32 - JMP runtime·memhashFallback(SB) -TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24 - JMP runtime·strhashFallback(SB) -TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24 - JMP runtime·memhash32Fallback(SB) -TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24 - JMP runtime·memhash64Fallback(SB) +TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32 + JMP runtime·memhashFallback(SB) +TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24 + JMP runtime·strhashFallback(SB) +TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24 + JMP runtime·memhash32Fallback(SB) +TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24 + JMP runtime·memhash64Fallback(SB) TEXT runtime·return0(SB), NOSPLIT, $0 MOVW $0, R19 @@ -658,6 +670,86 @@ TEXT ·checkASM(SB),NOSPLIT,$0-1 MOVB R19, ret+0(FP) RET +#ifdef GOEXPERIMENT_regabiargs +// spillArgs stores return values from registers to a *internal/abi.RegArgs in R25. +TEXT ·spillArgs(SB),NOSPLIT,$0-0 + MOVV R4, (0*8)(R25) + MOVV R5, (1*8)(R25) + MOVV R6, (2*8)(R25) + MOVV R7, (3*8)(R25) + MOVV R8, (4*8)(R25) + MOVV R9, (5*8)(R25) + MOVV R10, (6*8)(R25) + MOVV R11, (7*8)(R25) + MOVV R12, (8*8)(R25) + MOVV R13, (9*8)(R25) + MOVV R14, (10*8)(R25) + MOVV R15, (11*8)(R25) + MOVV R16, (12*8)(R25) + MOVV R17, (13*8)(R25) + MOVV R18, (14*8)(R25) + MOVV R19, (15*8)(R25) + MOVD F0, (16*8)(R25) + MOVD F1, (17*8)(R25) + MOVD F2, (18*8)(R25) + MOVD F3, (19*8)(R25) + MOVD F4, (20*8)(R25) + MOVD F5, (21*8)(R25) + MOVD F6, (22*8)(R25) + MOVD F7, (23*8)(R25) + MOVD F8, (24*8)(R25) + MOVD F9, (25*8)(R25) + MOVD F10, (26*8)(R25) + MOVD F11, (27*8)(R25) + MOVD F12, (28*8)(R25) + MOVD F13, (29*8)(R25) + MOVD F14, (30*8)(R25) + MOVD F15, (31*8)(R25) + RET + +// unspillArgs loads args into registers from a *internal/abi.RegArgs in R25. +TEXT ·unspillArgs(SB),NOSPLIT,$0-0 + MOVV (0*8)(R25), R4 + MOVV (1*8)(R25), R5 + MOVV (2*8)(R25), R6 + MOVV (3*8)(R25), R7 + MOVV (4*8)(R25), R8 + MOVV (5*8)(R25), R9 + MOVV (6*8)(R25), R10 + MOVV (7*8)(R25), R11 + MOVV (8*8)(R25), R12 + MOVV (9*8)(R25), R13 + MOVV (10*8)(R25), R14 + MOVV (11*8)(R25), R15 + MOVV (12*8)(R25), R16 + MOVV (13*8)(R25), R17 + MOVV (14*8)(R25), R18 + MOVV (15*8)(R25), R19 + MOVD (16*8)(R25), F0 + MOVD (17*8)(R25), F1 + MOVD (18*8)(R25), F2 + MOVD (19*8)(R25), F3 + MOVD (20*8)(R25), F4 + MOVD (21*8)(R25), F5 + MOVD (22*8)(R25), F6 + MOVD (23*8)(R25), F7 + MOVD (24*8)(R25), F8 + MOVD (25*8)(R25), F9 + MOVD (26*8)(R25), F10 + MOVD (27*8)(R25), F11 + MOVD (28*8)(R25), F12 + MOVD (29*8)(R25), F13 + MOVD (30*8)(R25), F14 + MOVD (31*8)(R25), F15 + RET +#else +TEXT ·spillArgs(SB),NOSPLIT,$0-0 + RET + +TEXT ·unspillArgs(SB),NOSPLIT,$0-0 + RET +#endif + // gcWriteBarrier informs the GC about heap pointer writes. // // gcWriteBarrier does NOT follow the Go ABI. It accepts the @@ -785,71 +877,156 @@ TEXT runtime·gcWriteBarrier8(SB),NOSPLIT,$0 // in the caller's stack frame. These stubs write the args into that stack space and // then tail call to the corresponding runtime handler. // The tail call makes these stubs disappear in backtraces. -TEXT runtime·panicIndex(SB),NOSPLIT,$0-16 +TEXT runtime·panicIndex(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +#else MOVV R20, x+0(FP) MOVV R21, y+8(FP) - JMP runtime·goPanicIndex(SB) -TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicIndex(SB) +TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +#else MOVV R20, x+0(FP) MOVV R21, y+8(FP) - JMP runtime·goPanicIndexU(SB) -TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicIndexU(SB) +TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +#else MOVV R21, x+0(FP) MOVV R23, y+8(FP) - JMP runtime·goPanicSliceAlen(SB) -TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSliceAlen(SB) +TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +#else MOVV R21, x+0(FP) MOVV R23, y+8(FP) - JMP runtime·goPanicSliceAlenU(SB) -TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSliceAlenU(SB) +TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +#else MOVV R21, x+0(FP) MOVV R23, y+8(FP) - JMP runtime·goPanicSliceAcap(SB) -TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSliceAcap(SB) +TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +#else MOVV R21, x+0(FP) MOVV R23, y+8(FP) - JMP runtime·goPanicSliceAcapU(SB) -TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSliceAcapU(SB) +TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +#else MOVV R20, x+0(FP) MOVV R21, y+8(FP) - JMP runtime·goPanicSliceB(SB) -TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSliceB(SB) +TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +#else MOVV R20, x+0(FP) MOVV R21, y+8(FP) - JMP runtime·goPanicSliceBU(SB) -TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSliceBU(SB) +TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R23, R4 + MOVV R24, R5 +#else MOVV R23, x+0(FP) MOVV R24, y+8(FP) - JMP runtime·goPanicSlice3Alen(SB) -TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSlice3Alen(SB) +TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R23, R4 + MOVV R24, R5 +#else MOVV R23, x+0(FP) MOVV R24, y+8(FP) - JMP runtime·goPanicSlice3AlenU(SB) -TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSlice3AlenU(SB) +TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R23, R4 + MOVV R24, R5 +#else MOVV R23, x+0(FP) MOVV R24, y+8(FP) - JMP runtime·goPanicSlice3Acap(SB) -TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSlice3Acap(SB) +TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R23, R4 + MOVV R24, R5 +#else MOVV R23, x+0(FP) MOVV R24, y+8(FP) - JMP runtime·goPanicSlice3AcapU(SB) -TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSlice3AcapU(SB) +TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +#else MOVV R21, x+0(FP) MOVV R23, y+8(FP) - JMP runtime·goPanicSlice3B(SB) -TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSlice3B(SB) +TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +#else MOVV R21, x+0(FP) MOVV R23, y+8(FP) - JMP runtime·goPanicSlice3BU(SB) -TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSlice3BU(SB) +TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +#else MOVV R20, x+0(FP) MOVV R21, y+8(FP) - JMP runtime·goPanicSlice3C(SB) -TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSlice3C(SB) +TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +#else MOVV R20, x+0(FP) MOVV R21, y+8(FP) - JMP runtime·goPanicSlice3CU(SB) -TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16 +#endif + JMP runtime·goPanicSlice3CU(SB) +TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16 +#ifdef GOEXPERIMENT_regabiargs + MOVV R23, R4 + MOVV R24, R5 +#else MOVV R23, x+0(FP) MOVV R24, y+8(FP) - JMP runtime·goPanicSliceConvert(SB) +#endif + JMP runtime·goPanicSliceConvert(SB) diff --git a/src/runtime/stubs_loong64.go b/src/runtime/stubs_loong64.go index 556983cad1..4576089b0b 100644 --- a/src/runtime/stubs_loong64.go +++ b/src/runtime/stubs_loong64.go @@ -10,6 +10,13 @@ package runtime func load_g() func save_g() +// Used by reflectcall and the reflect package. +// +// Spills/loads arguments in registers to/from an internal/abi.RegArgs +// respectively. Does not follow the Go ABI. +func spillArgs() +func unspillArgs() + // getfp returns the frame pointer register of its caller or 0 if not implemented. // TODO: Make this a compiler intrinsic func getfp() uintptr { return 0 } From 4e6bbbe61f554dbd9ed78fcd55ff46fe59736785 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Wed, 16 Aug 2023 08:28:28 +0800 Subject: [PATCH 25/30] reflect, runtime: add reflect support for regABI on loong64 Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: I0549fd1a2192ffb041034ff41bf0cc4be0b1662c Reviewed-on: https://go-review.googlesource.com/c/go/+/521784 Reviewed-by: Cherry Mui Reviewed-by: Meidan Li Reviewed-by: David Chase Auto-Submit: David Chase Run-TryBot: David Chase TryBot-Result: Gopher Robot --- src/reflect/asm_loong64.s | 77 ++++++++++++++++++++++++++++++++------- src/runtime/stkframe.go | 2 +- 2 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/reflect/asm_loong64.s b/src/reflect/asm_loong64.s index 341a6d55c1..520f0afdd5 100644 --- a/src/reflect/asm_loong64.s +++ b/src/reflect/asm_loong64.s @@ -7,34 +7,83 @@ #define REGCTXT R29 +// The frames of each of the two functions below contain two locals, at offsets +// that are known to the runtime. +// +// The first local is a bool called retValid with a whole pointer-word reserved +// for it on the stack. The purpose of this word is so that the runtime knows +// whether the stack-allocated return space contains valid values for stack +// scanning. +// +// The second local is an abi.RegArgs value whose offset is also known to the +// runtime, so that a stack map for it can be constructed, since it contains +// pointers visible to the GC. +#define LOCAL_RETVALID 40 +#define LOCAL_REGARGS 48 + +// The frame size of the functions below is +// 32 (args of callReflect) + 8 (bool + padding) + 392 (abi.RegArgs) = 432. + // makeFuncStub is the code half of the function returned by MakeFunc. // See the comment on the declaration of makeFuncStub in makefunc.go // for more details. // No arg size here, runtime pulls arg map out of the func value. -TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$40 +TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$432 NO_LOCAL_POINTERS + ADDV $LOCAL_REGARGS, R3, R25 // spillArgs using R25 + JAL runtime·spillArgs(SB) + MOVV REGCTXT, 32(R3) // save REGCTXT > args of moveMakeFuncArgPtrs < LOCAL_REGARGS + +#ifdef GOEXPERIMENT_regabiargs + MOVV REGCTXT, R4 + MOVV R25, R5 +#else MOVV REGCTXT, 8(R3) - MOVV $argframe+0(FP), R19 - MOVV R19, 16(R3) - MOVB R0, 40(R3) - ADDV $40, R3, R19 - MOVV R19, 24(R3) - MOVV R0, 32(R3) + MOVV R25, 16(R3) +#endif + JAL ·moveMakeFuncArgPtrs(SB) + MOVV 32(R3), REGCTXT // restore REGCTXT + + MOVV REGCTXT, 8(R3) + MOVV $argframe+0(FP), R20 + MOVV R20, 16(R3) + MOVV R0, LOCAL_RETVALID(R3) + ADDV $LOCAL_RETVALID, R3, R20 + MOVV R20, 24(R3) + ADDV $LOCAL_REGARGS, R3, R20 + MOVV R20, 32(R3) JAL ·callReflect(SB) + ADDV $LOCAL_REGARGS, R3, R25 //unspillArgs using R25 + JAL runtime·unspillArgs(SB) RET // methodValueCall is the code half of the function returned by makeMethodValue. // See the comment on the declaration of methodValueCall in makefunc.go // for more details. // No arg size here; runtime pulls arg map out of the func value. -TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$40 +TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$432 NO_LOCAL_POINTERS + ADDV $LOCAL_REGARGS, R3, R25 // spillArgs using R25 + JAL runtime·spillArgs(SB) + MOVV REGCTXT, 32(R3) // save REGCTXT > args of moveMakeFuncArgPtrs < LOCAL_REGARGS +#ifdef GOEXPERIMENT_regabiargs + MOVV REGCTXT, R4 + MOVV R25, R5 +#else MOVV REGCTXT, 8(R3) - MOVV $argframe+0(FP), R19 - MOVV R19, 16(R3) - MOVB R0, 40(R3) - ADDV $40, R3, R19 - MOVV R19, 24(R3) - MOVV R0, 32(R3) + MOVV R25, 16(R3) +#endif + JAL ·moveMakeFuncArgPtrs(SB) + MOVV 32(R3), REGCTXT // restore REGCTXT + MOVV REGCTXT, 8(R3) + MOVV $argframe+0(FP), R20 + MOVV R20, 16(R3) + MOVB R0, LOCAL_RETVALID(R3) + ADDV $LOCAL_RETVALID, R3, R20 + MOVV R20, 24(R3) + ADDV $LOCAL_REGARGS, R3, R20 + MOVV R20, 32(R3) // frame size to 32+SP as callreflect args) JAL ·callMethod(SB) + ADDV $LOCAL_REGARGS, R3, R25 // unspillArgs using R25 + JAL runtime·unspillArgs(SB) RET diff --git a/src/runtime/stkframe.go b/src/runtime/stkframe.go index a2f40c92d5..becb729e59 100644 --- a/src/runtime/stkframe.go +++ b/src/runtime/stkframe.go @@ -234,7 +234,7 @@ func (frame *stkframe) getStackMap(debug bool) (locals, args bitvector, objs []s } // stack objects. - if (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64") && + if (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "loong64" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64") && unsafe.Sizeof(abi.RegArgs{}) > 0 && isReflect { // For reflect.makeFuncStub and reflect.methodValueCall, // we need to fake the stack object record. From 1052d09dd768d658bda2aa99d13ce4c032f09dc0 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Wed, 16 Aug 2023 08:55:13 +0800 Subject: [PATCH 26/30] internal/bytealg: add regABI support in bytealg functions on loong64 Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: I4a7392afd7238d44e7d09aaca7e0d733649926ac Reviewed-on: https://go-review.googlesource.com/c/go/+/521785 TryBot-Result: Gopher Robot Reviewed-by: Cherry Mui Run-TryBot: David Chase Reviewed-by: Meidan Li Reviewed-by: David Chase Auto-Submit: David Chase --- src/internal/bytealg/compare_loong64.s | 95 ++++++++++++++---------- src/internal/bytealg/equal_loong64.s | 21 +++++- src/internal/bytealg/indexbyte_loong64.s | 32 ++++++-- 3 files changed, 101 insertions(+), 47 deletions(-) diff --git a/src/internal/bytealg/compare_loong64.s b/src/internal/bytealg/compare_loong64.s index c89c5a9256..311449ab18 100644 --- a/src/internal/bytealg/compare_loong64.s +++ b/src/internal/bytealg/compare_loong64.s @@ -5,83 +5,102 @@ #include "go_asm.h" #include "textflag.h" -TEXT ·Compare(SB),NOSPLIT,$0-56 - MOVV a_base+0(FP), R6 - MOVV b_base+24(FP), R7 - MOVV a_len+8(FP), R4 - MOVV b_len+32(FP), R5 +TEXT ·Compare(SB),NOSPLIT,$0-56 +#ifndef GOEXPERIMENT_regabiargs + MOVV a_base+0(FP), R4 + MOVV a_len+8(FP), R5 + MOVV b_base+24(FP), R6 + MOVV b_len+32(FP), R7 MOVV $ret+48(FP), R13 +#else + // R4 = a_base + // R5 = a_len + // R6 = a_cap (unused) + // R7 = b_base (want in R6) + // R8 = b_len (want in R7) + // R9 = b_cap (unused) + MOVV R7, R6 + MOVV R8, R7 +#endif JMP cmpbody<>(SB) -TEXT runtime·cmpstring(SB),NOSPLIT,$0-40 - MOVV a_base+0(FP), R6 - MOVV b_base+16(FP), R7 - MOVV a_len+8(FP), R4 - MOVV b_len+24(FP), R5 +TEXT runtime·cmpstring(SB),NOSPLIT,$0-40 +#ifndef GOEXPERIMENT_regabiargs + MOVV a_base+0(FP), R4 + MOVV b_base+16(FP), R6 + MOVV a_len+8(FP), R5 + MOVV b_len+24(FP), R7 MOVV $ret+32(FP), R13 +#endif + // R4 = a_base + // R5 = a_len + // R6 = b_base + // R7 = b_len JMP cmpbody<>(SB) // On entry: -// R4 length of a -// R5 length of b -// R6 points to the start of a -// R7 points to the start of b +// R5 length of a +// R7 length of b +// R4 points to the start of a +// R6 points to the start of b // R13 points to the return value (-1/0/1) TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0 - BEQ R6, R7, samebytes // same start of a and b + BEQ R4, R6, samebytes // same start of a and b - SGTU R4, R5, R9 + SGTU R5, R7, R9 BNE R0, R9, r2_lt_r1 - MOVV R4, R14 + MOVV R5, R14 JMP entry r2_lt_r1: - MOVV R5, R14 // R14 is min(R4, R5) + MOVV R7, R14 // R14 is min(R4, R5) entry: - ADDV R6, R14, R12 // R6 start of a, R14 end of a - BEQ R6, R12, samebytes // length is 0 + ADDV R4, R14, R12 // R6 start of a, R14 end of a + BEQ R4, R12, samebytes // length is 0 SRLV $4, R14 // R14 is number of chunks BEQ R0, R14, byte_loop // make sure both a and b are aligned. - OR R6, R7, R15 + OR R4, R6, R15 AND $7, R15 BNE R0, R15, byte_loop PCALIGN $16 chunk16_loop: BEQ R0, R14, byte_loop - MOVV (R6), R8 - MOVV (R7), R9 + MOVV (R4), R8 + MOVV (R6), R9 BNE R8, R9, byte_loop - MOVV 8(R6), R16 - MOVV 8(R7), R17 + MOVV 8(R4), R16 + MOVV 8(R6), R17 + ADDV $16, R4 ADDV $16, R6 - ADDV $16, R7 SUBVU $1, R14 BEQ R16, R17, chunk16_loop + SUBV $8, R4 SUBV $8, R6 - SUBV $8, R7 byte_loop: - BEQ R6, R12, samebytes - MOVBU (R6), R8 + BEQ R4, R12, samebytes + MOVBU (R4), R8 + ADDVU $1, R4 + MOVBU (R6), R9 ADDVU $1, R6 - MOVBU (R7), R9 - ADDVU $1, R7 BEQ R8, R9, byte_loop byte_cmp: - SGTU R8, R9, R12 // R12 = 1 if (R8 > R9) - BNE R0, R12, ret - MOVV $-1, R12 + SGTU R8, R9, R4 // R12 = 1 if (R8 > R9) + BNE R0, R4, ret + MOVV $-1, R4 JMP ret samebytes: - SGTU R4, R5, R8 - SGTU R5, R4, R9 - SUBV R9, R8, R12 + SGTU R5, R7, R8 + SGTU R7, R5, R9 + SUBV R9, R8, R4 ret: - MOVV R12, (R13) +#ifndef GOEXPERIMENT_regabiargs + MOVV R4, (R13) +#endif RET diff --git a/src/internal/bytealg/equal_loong64.s b/src/internal/bytealg/equal_loong64.s index ba2a5578c3..a3ad5c1b35 100644 --- a/src/internal/bytealg/equal_loong64.s +++ b/src/internal/bytealg/equal_loong64.s @@ -8,17 +8,21 @@ #define REGCTXT R29 // memequal(a, b unsafe.Pointer, size uintptr) bool -TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25 +TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25 +#ifndef GOEXPERIMENT_regabiargs MOVV a+0(FP), R4 MOVV b+8(FP), R5 - BEQ R4, R5, eq MOVV size+16(FP), R6 +#endif + BEQ R4, R5, eq ADDV R4, R6, R7 PCALIGN $16 loop: BNE R4, R7, test MOVV $1, R4 +#ifndef GOEXPERIMENT_regabiargs MOVB R4, ret+24(FP) +#endif RET test: MOVBU (R4), R9 @@ -27,17 +31,24 @@ test: ADDV $1, R5 BEQ R9, R10, loop + MOVB R0, R4 +#ifndef GOEXPERIMENT_regabiargs MOVB R0, ret+24(FP) +#endif RET eq: MOVV $1, R4 +#ifndef GOEXPERIMENT_regabiargs MOVB R4, ret+24(FP) +#endif RET // memequal_varlen(a, b unsafe.Pointer) bool -TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 +TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 +#ifndef GOEXPERIMENT_regabiargs MOVV a+0(FP), R4 MOVV b+8(FP), R5 +#endif BEQ R4, R5, eq MOVV 8(REGCTXT), R6 // compiler stores size at offset 8 in the closure MOVV R4, 8(R3) @@ -45,9 +56,13 @@ TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 MOVV R6, 24(R3) JAL runtime·memequal(SB) MOVBU 32(R3), R4 +#ifndef GOEXPERIMENT_regabiargs MOVB R4, ret+16(FP) +#endif RET eq: MOVV $1, R4 +#ifndef GOEXPERIMENT_regabiargs MOVB R4, ret+16(FP) +#endif RET diff --git a/src/internal/bytealg/indexbyte_loong64.s b/src/internal/bytealg/indexbyte_loong64.s index 604970549f..03e0660973 100644 --- a/src/internal/bytealg/indexbyte_loong64.s +++ b/src/internal/bytealg/indexbyte_loong64.s @@ -5,11 +5,18 @@ #include "go_asm.h" #include "textflag.h" -TEXT ·IndexByte(SB),NOSPLIT,$0-40 +TEXT ·IndexByte(SB),NOSPLIT,$0-40 +#ifndef GOEXPERIMENT_regabiargs MOVV b_base+0(FP), R4 MOVV b_len+8(FP), R5 - MOVBU c+24(FP), R6 // byte to find - MOVV R4, R7 // store base for later + MOVBU c+24(FP), R7 // byte to find +#endif + // R4 = b_base + // R5 = b_len + // R6 = b_cap (unused) + // R7 = byte to find + AND $0xff, R7 + MOVV R4, R6 // store base for later ADDV R4, R5 // end ADDV $-1, R4 @@ -18,21 +25,30 @@ loop: ADDV $1, R4 BEQ R4, R5, notfound MOVBU (R4), R8 - BNE R6, R8, loop + BNE R7, R8, loop - SUBV R7, R4 // remove base + SUBV R6, R4 // remove base +#ifndef GOEXPERIMENT_regabiargs MOVV R4, ret+32(FP) +#endif RET notfound: MOVV $-1, R4 +#ifndef GOEXPERIMENT_regabiargs MOVV R4, ret+32(FP) +#endif RET -TEXT ·IndexByteString(SB),NOSPLIT,$0-32 +TEXT ·IndexByteString(SB),NOSPLIT,$0-32 +#ifndef GOEXPERIMENT_regabiargs MOVV s_base+0(FP), R4 MOVV s_len+8(FP), R5 MOVBU c+16(FP), R6 // byte to find +#endif + // R4 = s_base + // R5 = s_len + // R6 = byte to find MOVV R4, R7 // store base for later ADDV R4, R5 // end ADDV $-1, R4 @@ -45,10 +61,14 @@ loop: BNE R6, R8, loop SUBV R7, R4 // remove base +#ifndef GOEXPERIMENT_regabiargs MOVV R4, ret+24(FP) +#endif RET notfound: MOVV $-1, R4 +#ifndef GOEXPERIMENT_regabiargs MOVV R4, ret+24(FP) +#endif RET From c83b5fefabe514ce5315135621b962f120277d23 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Wed, 16 Aug 2023 09:05:30 +0800 Subject: [PATCH 27/30] runtime: add regABI support in memclr and memmove functions on loong64 Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: I55c78bab5c697ea6c30f9d81f5f8fb75abb3987c Reviewed-on: https://go-review.googlesource.com/c/go/+/521786 TryBot-Result: Gopher Robot Reviewed-by: Cherry Mui Reviewed-by: Meidan Li Run-TryBot: David Chase Auto-Submit: David Chase Reviewed-by: David Chase --- src/runtime/memclr_loong64.s | 32 +++++++++++++++++--------------- src/runtime/memmove_loong64.s | 4 +++- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/runtime/memclr_loong64.s b/src/runtime/memclr_loong64.s index 7bb6f3dfc9..313e4d4f33 100644 --- a/src/runtime/memclr_loong64.s +++ b/src/runtime/memclr_loong64.s @@ -6,37 +6,39 @@ #include "textflag.h" // func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr) -TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16 - MOVV ptr+0(FP), R6 - MOVV n+8(FP), R7 - ADDV R6, R7, R4 +TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16 +#ifndef GOEXPERIMENT_regabiargs + MOVV ptr+0(FP), R4 + MOVV n+8(FP), R5 +#endif + ADDV R4, R5, R6 // if less than 8 bytes, do one byte at a time - SGTU $8, R7, R8 + SGTU $8, R5, R8 BNE R8, out // do one byte at a time until 8-aligned - AND $7, R6, R8 + AND $7, R4, R8 BEQ R8, words - MOVB R0, (R6) - ADDV $1, R6 + MOVB R0, (R4) + ADDV $1, R4 JMP -4(PC) words: // do 8 bytes at a time if there is room - ADDV $-7, R4, R7 + ADDV $-7, R6, R5 PCALIGN $16 - SGTU R7, R6, R8 + SGTU R5, R4, R8 BEQ R8, out - MOVV R0, (R6) - ADDV $8, R6 + MOVV R0, (R4) + ADDV $8, R4 JMP -4(PC) out: - BEQ R6, R4, done - MOVB R0, (R6) - ADDV $1, R6 + BEQ R4, R6, done + MOVB R0, (R4) + ADDV $1, R4 JMP -3(PC) done: RET diff --git a/src/runtime/memmove_loong64.s b/src/runtime/memmove_loong64.s index 0f139bcc13..5b7aeba698 100644 --- a/src/runtime/memmove_loong64.s +++ b/src/runtime/memmove_loong64.s @@ -7,10 +7,12 @@ // See memmove Go doc for important implementation constraints. // func memmove(to, from unsafe.Pointer, n uintptr) -TEXT runtime·memmove(SB), NOSPLIT|NOFRAME, $0-24 +TEXT runtime·memmove(SB), NOSPLIT|NOFRAME, $0-24 +#ifndef GOEXPERIMENT_regabiargs MOVV to+0(FP), R4 MOVV from+8(FP), R5 MOVV n+16(FP), R6 +#endif BNE R6, check RET From e58c9baa9f7b708bcd6a3abf5a8426b0531ed002 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Wed, 16 Aug 2023 09:16:21 +0800 Subject: [PATCH 28/30] cmd/internal/obj: set morestack arg spilling and regabi prologue on loong64 Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: Ie92da57e29bae0e5cccb2a49a7cbeaf02cbf3a8d Reviewed-on: https://go-review.googlesource.com/c/go/+/521787 Reviewed-by: Meidan Li Run-TryBot: David Chase TryBot-Result: Gopher Robot Reviewed-by: Cherry Mui Reviewed-by: David Chase Auto-Submit: David Chase --- src/cmd/internal/obj/loong64/obj.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/cmd/internal/obj/loong64/obj.go b/src/cmd/internal/obj/loong64/obj.go index bc9cf2ec22..5fa67f3acd 100644 --- a/src/cmd/internal/obj/loong64/obj.go +++ b/src/cmd/internal/obj/loong64/obj.go @@ -620,6 +620,10 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { p = c.ctxt.StartUnsafePoint(p, c.newprog) + // Spill Arguments. This has to happen before we open + // any more frame space. + p = c.cursym.Func().SpillRegisterArgs(p, c.newprog) + // MOV REGLINK, -8/-16(SP) p = obj.Appendp(p, c.newprog) p.As = mov @@ -684,6 +688,8 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { p.To.Reg = REGSP p.Spadj = int32(-frameSize) + // Unspill arguments + p = c.cursym.Func().UnspillRegisterArgs(p, c.newprog) p = c.ctxt.EndUnsafePoint(p, c.newprog, -1) } @@ -795,6 +801,10 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { p = c.ctxt.EmitEntryStackMap(c.cursym, p, c.newprog) + // Spill the register args that could be clobbered by the + // morestack code + p = c.cursym.Func().SpillRegisterArgs(p, c.newprog) + // JAL runtime.morestack(SB) p = obj.Appendp(p, c.newprog) @@ -809,6 +819,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { } p.Mark |= BRANCH + p = c.cursym.Func().UnspillRegisterArgs(p, c.newprog) p = c.ctxt.EndUnsafePoint(p, c.newprog, -1) // JMP start From b3b442449b0b979a035b5a26b8e62d8f6158fa69 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Wed, 16 Aug 2023 10:22:13 +0800 Subject: [PATCH 29/30] cmd/compile: fix If lowering on loong64 Update #40724 Co-authored-by: Xiaolin Zhao Change-Id: I44477e32db765e0299d8361bd2b8d2c95564ed28 Reviewed-on: https://go-review.googlesource.com/c/go/+/521788 Reviewed-by: Meidan Li Reviewed-by: David Chase Auto-Submit: David Chase TryBot-Result: Gopher Robot Run-TryBot: David Chase Reviewed-by: Cherry Mui --- .../compile/internal/ssa/_gen/LOONG64.rules | 3 ++- .../compile/internal/ssa/rewriteLOONG64.go | 27 +++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules index b9aaa3ff7f..2af9519113 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules @@ -416,7 +416,7 @@ (GetCallerSP ...) => (LoweredGetCallerSP ...) (GetCallerPC ...) => (LoweredGetCallerPC ...) -(If cond yes no) => (NE cond yes no) +(If cond yes no) => (NE (MOVBUreg cond) yes no) // Write barrier. (WB ...) => (LoweredWB ...) @@ -450,6 +450,7 @@ (EQ (SGTconst [0] x) yes no) => (GEZ x yes no) (NE (SGT x (MOVVconst [0])) yes no) => (GTZ x yes no) (EQ (SGT x (MOVVconst [0])) yes no) => (LEZ x yes no) +(MOVBUreg x:((SGT|SGTU) _ _)) => x // fold offset into address (ADDVconst [off1] (MOVVaddr [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) => (MOVVaddr [int32(off1)+int32(off2)] {sym} ptr) diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go index 757524bdbb..edd3ffe6b9 100644 --- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go +++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go @@ -1773,6 +1773,26 @@ func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool { } func rewriteValueLOONG64_OpLOONG64MOVBUreg(v *Value) bool { v_0 := v.Args[0] + // match: (MOVBUreg x:(SGT _ _)) + // result: x + for { + x := v_0 + if x.Op != OpLOONG64SGT { + break + } + v.copyOf(x) + return true + } + // match: (MOVBUreg x:(SGTU _ _)) + // result: x + for { + x := v_0 + if x.Op != OpLOONG64SGTU { + break + } + v.copyOf(x) + return true + } // match: (MOVBUreg x:(MOVBUload _ _)) // result: (MOVVreg x) for { @@ -7608,6 +7628,7 @@ func rewriteValueLOONG64_OpZero(v *Value) bool { return false } func rewriteBlockLOONG64(b *Block) bool { + typ := &b.Func.Config.Types switch b.Kind { case BlockLOONG64EQ: // match: (EQ (FPFlagTrue cmp) yes no) @@ -7807,10 +7828,12 @@ func rewriteBlockLOONG64(b *Block) bool { } case BlockIf: // match: (If cond yes no) - // result: (NE cond yes no) + // result: (NE (MOVBUreg cond) yes no) for { cond := b.Controls[0] - b.resetWithControl(BlockLOONG64NE, cond) + v0 := b.NewValue0(cond.Pos, OpLOONG64MOVBUreg, typ.UInt64) + v0.AddArg(cond) + b.resetWithControl(BlockLOONG64NE, v0) return true } case BlockLOONG64LEZ: From 2e77b51df5b9f7753f500c6cbba8f0dab5bf2250 Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Tue, 22 Aug 2023 19:50:03 +0800 Subject: [PATCH 30/30] runtime/internal/syscall: use ABIInternal for Syscall6 on loong64 Updates #40724 Co-authored-by: Xiaolin Zhao Change-Id: Ifcc2de35a797fd987a10f564206b14b54d736d1d Reviewed-on: https://go-review.googlesource.com/c/go/+/521789 Auto-Submit: David Chase Reviewed-by: Meidan Li Reviewed-by: Cherry Mui Run-TryBot: David Chase Reviewed-by: David Chase TryBot-Result: Gopher Robot --- .../internal/syscall/asm_linux_loong64.s | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/runtime/internal/syscall/asm_linux_loong64.s b/src/runtime/internal/syscall/asm_linux_loong64.s index d6a33f90a7..11c5bc2468 100644 --- a/src/runtime/internal/syscall/asm_linux_loong64.s +++ b/src/runtime/internal/syscall/asm_linux_loong64.s @@ -5,7 +5,32 @@ #include "textflag.h" // func Syscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr) -TEXT ·Syscall6(SB),NOSPLIT,$0-80 +// +// We need to convert to the syscall ABI. +// +// arg | ABIInternal | Syscall +// --------------------------- +// num | R4 | R11 +// a1 | R5 | R4 +// a2 | R6 | R5 +// a3 | R7 | R6 +// a4 | R8 | R7 +// a5 | R9 | R8 +// a6 | R10 | R9 +// +// r1 | R4 | R4 +// r2 | R5 | R5 +// err | R6 | part of R4 +TEXT ·Syscall6(SB),NOSPLIT,$0-80 +#ifdef GOEXPERIMENT_regabiargs + MOVV R4, R11 // syscall entry + MOVV R5, R4 + MOVV R6, R5 + MOVV R7, R6 + MOVV R8, R7 + MOVV R9, R8 + MOVV R10, R9 +#else MOVV num+0(FP), R11 // syscall entry MOVV a1+8(FP), R4 MOVV a2+16(FP), R5 @@ -13,7 +38,15 @@ TEXT ·Syscall6(SB),NOSPLIT,$0-80 MOVV a4+32(FP), R7 MOVV a5+40(FP), R8 MOVV a6+48(FP), R9 +#endif SYSCALL +#ifdef GOEXPERIMENT_regabiargs + MOVV R0, R5 // r2 is not used. Always set to 0. + MOVW $-4096, R12 + BGEU R12, R4, ok + SUBVU R4, R0, R6 // errno + MOVV $-1, R4 // r1 +#else MOVW $-4096, R12 BGEU R12, R4, ok MOVV $-1, R12 @@ -21,9 +54,15 @@ TEXT ·Syscall6(SB),NOSPLIT,$0-80 MOVV R0, r2+64(FP) SUBVU R4, R0, R4 MOVV R4, errno+72(FP) +#endif RET ok: +#ifdef GOEXPERIMENT_regabiargs + // r1 already in R4 + MOVV R0, R6 // errno +#else MOVV R4, r1+56(FP) MOVV R0, r2+64(FP) // r2 is not used. Always set to 0. MOVV R0, errno+72(FP) +#endif RET