]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: use ABI0 for cgo_unsafe_args functions
authorCherry Zhang <cherryyz@google.com>
Thu, 1 Apr 2021 15:11:04 +0000 (11:11 -0400)
committerCherry Zhang <cherryyz@google.com>
Fri, 2 Apr 2021 16:31:47 +0000 (16:31 +0000)
cgo_unsafe_args paragma indicates that the function (or its
callee) uses address and offsets to dispatch arguments, which
currently using ABI0 frame layout. Pin them to ABI0.

With this, "GOEXPERIMENT=regabi,regabiargs go run hello.go" works
on Darwin/AMD64.

Change-Id: I3eadd5a3646a9de8fa681fa0a7f46e7cdc217d24
Reviewed-on: https://go-review.googlesource.com/c/go/+/306609
Trust: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/compile/internal/amd64/ssa.go
src/cmd/compile/internal/ssa/gen/AMD64.rules
src/cmd/compile/internal/ssa/rewriteAMD64.go
src/cmd/compile/internal/ssagen/abi.go

index 2c767d36d7fff8e34bf11bbe0a0867a8bcfedf90..8142ba798432081ea5b6bc45d502106f04902f63 100644 (file)
@@ -824,10 +824,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                p.To.Reg = v.Args[0].Reg()
                ssagen.AddAux2(&p.To, v, sc.Off64())
        case ssa.OpAMD64MOVOstorezero:
-               if s.ABI != obj.ABIInternal {
-                       v.Fatalf("MOVOstorezero can be only used in ABIInternal functions")
-               }
-               if !objabi.Experiment.RegabiG {
+               if !objabi.Experiment.RegabiG || s.ABI != obj.ABIInternal {
                        // zero X15 manually
                        opregreg(s, x86.AXORPS, x86.REG_X15, x86.REG_X15)
                }
@@ -918,10 +915,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                p.To.Type = obj.TYPE_REG
                p.To.Reg = v.Reg()
        case ssa.OpAMD64DUFFZERO:
-               if s.ABI != obj.ABIInternal {
-                       v.Fatalf("MOVOconst can be only used in ABIInternal functions")
-               }
-               if !objabi.Experiment.RegabiG {
+               if !objabi.Experiment.RegabiG || s.ABI != obj.ABIInternal {
                        // zero X15 manually
                        opregreg(s, x86.AXORPS, x86.REG_X15, x86.REG_X15)
                }
@@ -1004,8 +998,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                // Closure pointer is DX.
                ssagen.CheckLoweredGetClosurePtr(v)
        case ssa.OpAMD64LoweredGetG:
-               if objabi.Experiment.RegabiG {
-                       v.Fatalf("LoweredGetG should not appear in new ABI")
+               if objabi.Experiment.RegabiG && s.ABI == obj.ABIInternal {
+                       v.Fatalf("LoweredGetG should not appear in ABIInternal")
                }
                r := v.Reg()
                getgFromTLS(s, r)
index 98cd865182de454311713bb0f65f002ce74e8131..839d4a330e2c610cc35bd0b41837dd8c7d59c040 100644 (file)
 (IsInBounds idx len) => (SETB (CMPQ idx len))
 (IsSliceInBounds idx len) => (SETBE (CMPQ idx len))
 (NilCheck ...) => (LoweredNilCheck ...)
-(GetG mem) && !objabi.Experiment.RegabiG => (LoweredGetG mem) // only lower in old ABI. in new ABI we have a G register.
+(GetG mem) && !(objabi.Experiment.RegabiG && v.Block.Func.OwnAux.Fn.ABI() == obj.ABIInternal) => (LoweredGetG mem) // only lower in old ABI. in new ABI we have a G register.
 (GetClosurePtr ...) => (LoweredGetClosurePtr ...)
 (GetCallerPC ...) => (LoweredGetCallerPC ...)
 (GetCallerSP ...) => (LoweredGetCallerSP ...)
index ce94fdb952e4f3f55ca9ae67e2229ee06f5f82fd..1f56b70816ff67379f6272ba1576c49505f14262 100644 (file)
@@ -4,6 +4,7 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 import "cmd/internal/objabi"
 import "cmd/compile/internal/types"
 
@@ -30465,11 +30466,11 @@ func rewriteValueAMD64_OpFloor(v *Value) bool {
 func rewriteValueAMD64_OpGetG(v *Value) bool {
        v_0 := v.Args[0]
        // match: (GetG mem)
-       // cond: !objabi.Experiment.RegabiG
+       // cond: !(objabi.Experiment.RegabiG && v.Block.Func.OwnAux.Fn.ABI() == obj.ABIInternal)
        // result: (LoweredGetG mem)
        for {
                mem := v_0
-               if !(!objabi.Experiment.RegabiG) {
+               if !(!(objabi.Experiment.RegabiG && v.Block.Func.OwnAux.Fn.ABI() == obj.ABIInternal)) {
                        break
                }
                v.reset(OpAMD64LoweredGetG)
index 9c203838a55baeb279aed98a8eda06b6f2f75983..61d065cea8327b409419ec07f7e727e938dd6ee4 100644 (file)
@@ -146,6 +146,13 @@ func (s *SymABIs) GenABIWrappers() {
                        fn.ABI = defABI
                }
 
+               if fn.Pragma&ir.CgoUnsafeArgs != 0 {
+                       // CgoUnsafeArgs indicates the function (or its callee) uses
+                       // offsets to dispatch arguments, which currently using ABI0
+                       // frame layout. Pin it to ABI0.
+                       fn.ABI = obj.ABI0
+               }
+
                // Apply references.
                if abis, ok := s.refs[symName]; ok {
                        fn.ABIRefs |= abis