]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj: stop storing Text flags in From3
authorJosh Bleecher Snyder <josharian@gmail.com>
Tue, 11 Apr 2017 22:15:04 +0000 (15:15 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 12 Apr 2017 21:53:39 +0000 (21:53 +0000)
Prior to this CL, flags such as NOSPLIT
on ATEXT Progs were stored in From3.Offset.
Some but not all of those flags were also
duplicated into From.Sym.Attribute.

This CL migrates all of those flags into
From.Sym.Attribute and stops creating a From3.

A side-effect of this is that printing an
ATEXT Prog can no longer simply dump From3.Offset.
That's kind of good, since the raw flag value
wasn't very informative anyway, but it did
necessitate a bunch of updates to the cmd/asm tests.

The reason I'm doing this work now is that
avoiding storing flags in both From.Sym and From3.Offset
simplifies some other changes to fix the data
race first described in CL 40254.

This CL almost passes toolstash-check -all.
The only changes are in cases where the assembler
has decided that a function's flags may be altered,
e.g. to make a function with no calls in it NOSPLIT.
Prior to this CL, that information was not printed.

Sample before:

"".Ctz64 t=1 size=63 args=0x10 locals=0x0
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), $0-16
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)

Sample after:

"".Ctz64 t=1 nosplit size=63 args=0x10 locals=0x0
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), NOSPLIT, $0-16
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)

Observe the additional "nosplit" in the first line
and the additional "NOSPLIT" in the second line.

Updates #15756

Change-Id: I5c59bd8f3bdc7c780361f801d94a261f0aef3d13
Reviewed-on: https://go-review.googlesource.com/40495
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

22 files changed:
misc/nacl/testzip.proto
src/cmd/asm/internal/asm/asm.go
src/cmd/asm/internal/asm/endtoend_test.go
src/cmd/asm/internal/asm/testdata/386.s
src/cmd/asm/internal/asm/testdata/amd64.s
src/cmd/asm/internal/asm/testdata/amd64enc.s
src/cmd/asm/internal/asm/testdata/arm.s
src/cmd/asm/internal/asm/testdata/arm64.s
src/cmd/asm/internal/asm/testdata/mips.s
src/cmd/asm/internal/asm/testdata/mips64.s
src/cmd/asm/internal/asm/testdata/ppc64.s
src/cmd/asm/internal/asm/testdata/s390x.s
src/cmd/compile/internal/gc/gsubr.go
src/cmd/internal/obj/arm/obj5.go
src/cmd/internal/obj/arm64/obj7.go
src/cmd/internal/obj/link.go
src/cmd/internal/obj/mips/obj0.go
src/cmd/internal/obj/plist.go
src/cmd/internal/obj/ppc64/obj9.go
src/cmd/internal/obj/s390x/objz.go
src/cmd/internal/obj/util.go
src/cmd/internal/obj/x86/obj6.go

index 53151f285c82d4250c91a62cefb4f442d96063ea..8bf25400cbcc43d9767ff9380bd00f767648c32a 100644 (file)
@@ -162,6 +162,8 @@ go  src=..
                regexp
                        testdata
                                +
+               runtime
+                       textflag.h
                strconv
                        testdata
                                +
index 0e31677a3f617def58eda42a0de84b0a742136ea..7e3a8418dd43bc69be1bf37eb4cddb6faf1c5010 100644 (file)
@@ -165,10 +165,6 @@ func (p *Parser) asmText(word string, operands [][]lex.Token) {
                As:   obj.ATEXT,
                Pos:  p.pos(),
                From: nameAddr,
-               From3: &obj.Addr{
-                       Type:   obj.TYPE_CONST,
-                       Offset: flag,
-               },
                To: obj.Addr{
                        Type:   obj.TYPE_TEXTSIZE,
                        Offset: frameSize,
@@ -176,7 +172,7 @@ func (p *Parser) asmText(word string, operands [][]lex.Token) {
                },
        }
        prog.To.Val = int32(argSize)
-       p.ctxt.InitTextSym(prog)
+       p.ctxt.InitTextSym(prog, int(flag))
 
        p.append(prog, "", true)
 }
index f9d95ebc8ca63d0bf19c6dcd3d5cba0d1320884b..36aa4aedd836a24267b56e447b36146e53e88f2a 100644 (file)
@@ -62,6 +62,11 @@ Diff:
        for _, line := range lines {
                lineno++
 
+               // Ignore include of textflag.h.
+               if strings.HasPrefix(line, "#include ") {
+                       continue
+               }
+
                // The general form of a test input line is:
                //      // comment
                //      INST args [// printed form] [// hex encoding]
index 4d969d1539c880b15f3c7844bfa86f2be69588e9..ad8affd854b532dcb0d66f1717eb13e9e69e49ad 100644 (file)
@@ -2,7 +2,9 @@
 // the old assembler's (8a's) grammar and hand-writing complete
 // instructions for each rule, to guarantee we cover the same space.
 
-TEXT foo(SB), 7, $0
+#include "../../../../../runtime/textflag.h"
+
+TEXT foo(SB), DUPOK|NOSPLIT, $0
 
 // LTYPE1 nonrem       { outcode(int($1), &$2); }
        SETCC   AX
index da0144230dbad703e3b9c952f82ba009b7630325..d07cf0d21371894cf4dc58968875790949f8a5d2 100644 (file)
@@ -6,7 +6,9 @@
 // the old assembler's (6a's) grammar and hand-writing complete
 // instructions for each rule, to guarantee we cover the same space.
 
-TEXT   foo(SB), 7, $0
+#include "../../../../../runtime/textflag.h"
+
+TEXT   foo(SB), DUPOK|NOSPLIT, $0
 
 // LTYPE1 nonrem       { outcode($1, &$2); }
        NEGQ    R11
index b27faa5a360bc8e58b72652af53801dddffb7e80..3d6061f839287d56ebcdcb79398f042a9468db5b 100644 (file)
@@ -1,7 +1,9 @@
 // generated by x86test -amd64
 // DO NOT EDIT
 
-TEXT asmtest(SB),7,$0
+#include "../../../../../runtime/textflag.h"
+
+TEXT asmtest(SB),DUPOK|NOSPLIT,$0
        ADCB $7, AL                             // 1407
        ADCW $61731, AX                         // 661523f1
        ADCL $4045620583, AX                    // 15674523f1
index 0ae031ee815ba3913ee24f8e9a4b4921c2d49b08..969fb66cdfd777a01ac0affaeeacceb99cb342f6 100644 (file)
@@ -6,7 +6,9 @@
 // the old assembler's (5a's) grammar and hand-writing complete
 // instructions for each rule, to guarantee we cover the same space.
 
-TEXT   foo(SB), 7, $0
+#include "../../../../../runtime/textflag.h"
+
+TEXT   foo(SB), DUPOK|NOSPLIT, $0
 
 // ADD
 //
index 28b34e3d726de5da4557b6d9d3ab37cb6dc4c979..9dfcab5fba2c9e116fdf3193035b5ab11dc55984 100644 (file)
@@ -6,7 +6,9 @@
 // the old assembler's (7a's) grammar and hand-writing complete
 // instructions for each rule, to guarantee we cover the same space.
 
-TEXT   foo(SB), 7, $-8
+#include "../../../../../runtime/textflag.h"
+
+TEXT   foo(SB), DUPOK|NOSPLIT, $-8
 
 //
 // ADD
index f48d91885d20fc2ead1916e4c69d97556a9ca62b..0f0226de0cd44dd4635bf10d90ca227f7eaa74a6 100644 (file)
@@ -5,7 +5,9 @@
 // This input was created by taking the mips64 testcase and modified
 // by hand.
 
-TEXT foo(SB),7,$0
+#include "../../../../../runtime/textflag.h"
+
+TEXT foo(SB),DUPOK|NOSPLIT,$0
 
        //inst:
        //
index e217d35a133d9aee657b6614dffc8a2407ba724f..e3d898af8728a072d12fe2b24fb292eb5747f807 100644 (file)
@@ -5,7 +5,9 @@
 // This input was created by taking the ppc64 testcase and modified
 // by hand.
 
-TEXT foo(SB),7,$0
+#include "../../../../../runtime/textflag.h"
+
+TEXT foo(SB),DUPOK|NOSPLIT,$0
 
 //inst:
 //
index 8498f5804a05e3de9e95e39888300b628c5e6d66..14b0de127146287282668104803ddd25a6f8bbe4 100644 (file)
@@ -6,7 +6,9 @@
 // the old assembler's (9a's) grammar and hand-writing complete
 // instructions for each rule, to guarantee we cover the same space.
 
-TEXT foo(SB),7,$0
+#include "../../../../../runtime/textflag.h"
+
+TEXT foo(SB),DUPOK|NOSPLIT,$0
 
 //inst:
 //
index 55df0f953aaabead876828e12dfcaaf88e0d04bd..1ab07b65e8427f92277d8299785b942291b28021 100644 (file)
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-TEXT main·foo(SB),7,$16-0 // TEXT main.foo(SB), 7, $16-0
+#include "../../../../../runtime/textflag.h"
+
+TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-0
        MOVD    R1, R2                // b9040021
        MOVW    R3, R4                // b9140043
        MOVH    R5, R6                // b9070065
@@ -350,9 +352,9 @@ TEXT main·foo(SB),7,$16-0 // TEXT main.foo(SB), 7, $16-0
 
        RET
 
-TEXT main·init(SB),7,$0 // TEXT main.init(SB), 7, $0
+TEXT main·init(SB),DUPOK|NOSPLIT,$0 // TEXT main.init(SB), DUPOK|NOSPLIT, $0
        RET
 
-TEXT main·main(SB),7,$0 // TEXT main.main(SB), 7, $0
+TEXT main·main(SB),DUPOK|NOSPLIT,$0 // TEXT main.main(SB), DUPOK|NOSPLIT, $0
        BL      main·foo(SB)    // CALL main.foo(SB)
        RET
index 2c628a521fc2023edd09331874482df54b54b99b..f3aef208d6ae41dcdf9cd28e2ef3be5e98704c91 100644 (file)
@@ -155,24 +155,24 @@ func (pp *Progs) settext(fn *Node) {
                }
        }
 
-       ptxt.From3 = new(obj.Addr)
+       var flag int
        if fn.Func.Dupok() {
-               ptxt.From3.Offset |= obj.DUPOK
+               flag |= obj.DUPOK
        }
        if fn.Func.Wrapper() {
-               ptxt.From3.Offset |= obj.WRAPPER
+               flag |= obj.WRAPPER
        }
        if fn.Func.NoFramePointer() {
-               ptxt.From3.Offset |= obj.NOFRAME
+               flag |= obj.NOFRAME
        }
        if fn.Func.Needctxt() {
-               ptxt.From3.Offset |= obj.NEEDCTXT
+               flag |= obj.NEEDCTXT
        }
        if fn.Func.Pragma&Nosplit != 0 {
-               ptxt.From3.Offset |= obj.NOSPLIT
+               flag |= obj.NOSPLIT
        }
        if fn.Func.ReflectMethod() {
-               ptxt.From3.Offset |= obj.REFLECTMETHOD
+               flag |= obj.REFLECTMETHOD
        }
 
        // Clumsy but important.
@@ -181,11 +181,11 @@ func (pp *Progs) settext(fn *Node) {
        if myimportpath == "reflect" {
                switch fn.Func.Nname.Sym.Name {
                case "callReflect", "callMethod":
-                       ptxt.From3.Offset |= obj.WRAPPER
+                       flag |= obj.WRAPPER
                }
        }
 
-       Ctxt.InitTextSym(ptxt)
+       Ctxt.InitTextSym(ptxt, flag)
 
        pp.Text = ptxt
 }
index cec7c212d4ef4748d91370dbeb36b7b4094cddc6..fb63712918ee7ec1145c1ff4b18211146737601c 100644 (file)
@@ -357,7 +357,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                }
                        }
 
-                       if p.From3.Offset&obj.NOSPLIT == 0 {
+                       if !p.From.Sym.NoSplit() {
                                p = c.stacksplit(p, autosize) // emit split check
                        }
 
@@ -373,7 +373,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                        p.To.Reg = REGSP
                        p.Spadj = autosize
 
-                       if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
+                       if cursym.Text.From.Sym.Wrapper() {
                                // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
                                //
                                //      MOVW g_panic(g), R1
@@ -534,7 +534,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                        }
 
                case ADIV, ADIVU, AMOD, AMODU:
-                       if cursym.Text.From3.Offset&obj.NOSPLIT != 0 {
+                       if cursym.Text.From.Sym.NoSplit() {
                                ctxt.Diag("cannot divide in NOSPLIT function")
                        }
                        const debugdivmod = false
@@ -842,7 +842,7 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
        switch {
        case c.cursym.CFunc():
                morestack = "runtime.morestackc"
-       case c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0:
+       case !c.cursym.Text.From.Sym.NeedCtxt():
                morestack = "runtime.morestack_noctxt"
        }
        call.To.Sym = c.ctxt.Lookup(morestack, 0)
index 5c5670136328e811886aac1bd234f0ec38329dd7..1c8a40f9d6372dfc0b311174404aa4787cc87afc 100644 (file)
@@ -204,7 +204,7 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
        switch {
        case c.cursym.CFunc():
                morestack = "runtime.morestackc"
-       case c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0:
+       case !c.cursym.Text.From.Sym.NeedCtxt():
                morestack = "runtime.morestack_noctxt"
        }
        call.To.Sym = c.ctxt.Lookup(morestack, 0)
@@ -552,7 +552,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                c.cursym.Text.Mark |= LEAF
                        }
 
-                       if !(p.From3.Offset&obj.NOSPLIT != 0) {
+                       if !p.From.Sym.NoSplit() {
                                p = c.stacksplit(p, c.autosize) // emit split check
                        }
 
@@ -614,7 +614,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q1.Spadj = aoffset
                        }
 
-                       if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 {
+                       if c.cursym.Text.From.Sym.Wrapper() {
                                // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
                                //
                                //      MOV g_panic(g), R1
index d5d96f792ec248bc229a4324c5f0c6cdd541f5f9..fc0305344f0d0a5ab36a0cface063a1bfc599900 100644 (file)
@@ -261,14 +261,6 @@ func (p *Prog) From3Type() AddrType {
        return p.From3.Type
 }
 
-// From3Offset returns From3.Offset, or 0 when From3 is nil.
-func (p *Prog) From3Offset() int64 {
-       if p.From3 == nil {
-               return 0
-       }
-       return p.From3.Offset
-}
-
 // An As denotes an assembler opcode.
 // There are some portable opcodes, declared here in package obj,
 // that are common to all architectures.
@@ -347,6 +339,9 @@ const (
        AttrCFunc
        AttrNoSplit
        AttrLeaf
+       AttrWrapper
+       AttrNeedCtxt
+       AttrNoFrame
        AttrSeenGlobl
        AttrOnList
 
@@ -379,6 +374,9 @@ func (a Attribute) SeenGlobl() bool     { return a&AttrSeenGlobl != 0 }
 func (a Attribute) OnList() bool        { return a&AttrOnList != 0 }
 func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 }
 func (a Attribute) Local() bool         { return a&AttrLocal != 0 }
+func (a Attribute) Wrapper() bool       { return a&AttrWrapper != 0 }
+func (a Attribute) NeedCtxt() bool      { return a&AttrNeedCtxt != 0 }
+func (a Attribute) NoFrame() bool       { return a&AttrNoFrame != 0 }
 
 func (a *Attribute) Set(flag Attribute, value bool) {
        if value {
@@ -388,6 +386,45 @@ func (a *Attribute) Set(flag Attribute, value bool) {
        }
 }
 
+var textAttrStrings = [...]struct {
+       bit Attribute
+       s   string
+}{
+       {bit: AttrDuplicateOK, s: "DUPOK"},
+       {bit: AttrMakeTypelink, s: ""},
+       {bit: AttrCFunc, s: "CFUNC"},
+       {bit: AttrNoSplit, s: "NOSPLIT"},
+       {bit: AttrLeaf, s: "LEAF"},
+       {bit: AttrSeenGlobl, s: ""},
+       {bit: AttrOnList, s: ""},
+       {bit: AttrReflectMethod, s: "REFLECTMETHOD"},
+       {bit: AttrLocal, s: "LOCAL"},
+       {bit: AttrWrapper, s: "WRAPPER"},
+       {bit: AttrNeedCtxt, s: "NEEDCTXT"},
+       {bit: AttrNoFrame, s: "NOFRAME"},
+}
+
+// TextAttrString formats a for printing in as part of a TEXT prog.
+func (a Attribute) TextAttrString() string {
+       var s string
+       for _, x := range textAttrStrings {
+               if a&x.bit != 0 {
+                       if x.s != "" {
+                               s += x.s + "|"
+                       }
+                       a &^= x.bit
+               }
+       }
+       if a != 0 {
+               s += fmt.Sprintf("UnknownAttribute(%d)|", a)
+       }
+       // Chop off trailing |, if present.
+       if len(s) > 0 {
+               s = s[:len(s)-1]
+       }
+       return s
+}
+
 // The compiler needs LSym to satisfy fmt.Stringer, because it stores
 // an LSym in ssa.ExternSymbol.
 func (s *LSym) String() string {
index bef1b4d55129928dfe491eec17d7e8468c4c9a34..6ea156e32ca79206976493ee28b840aa84f3f69e 100644 (file)
@@ -286,7 +286,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
 
                        p.To.Offset = int64(autosize) - ctxt.FixedFrameSize()
 
-                       if p.From3.Offset&obj.NOSPLIT == 0 {
+                       if !p.From.Sym.NoSplit() {
                                p = c.stacksplit(p, autosize) // emit split check
                        }
 
@@ -316,7 +316,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q.To.Reg = REGSP
                                q.Spadj = +autosize
                        } else if c.cursym.Text.Mark&LEAF == 0 {
-                               if c.cursym.Text.From3.Offset&obj.NOSPLIT != 0 {
+                               if c.cursym.Text.From.Sym.NoSplit() {
                                        if ctxt.Debugvlog {
                                                ctxt.Logf("save suppressed in: %s\n", c.cursym.Name)
                                        }
@@ -330,7 +330,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                break
                        }
 
-                       if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 {
+                       if c.cursym.Text.From.Sym.Wrapper() {
                                // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
                                //
                                //      MOV     g_panic(g), R1
@@ -759,7 +759,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
        p.To.Type = obj.TYPE_BRANCH
        if c.cursym.CFunc() {
                p.To.Sym = c.ctxt.Lookup("runtime.morestackc", 0)
-       } else if c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
+       } else if !c.cursym.Text.From.Sym.NeedCtxt() {
                p.To.Sym = c.ctxt.Lookup("runtime.morestack_noctxt", 0)
        } else {
                p.To.Sym = c.ctxt.Lookup("runtime.morestack", 0)
index 6614f7d74ef0d95d0a4f9bb3dd502a31419fddc4..b2acd0f29d65f3f5b7f3ebad54f97159340e20fe 100644 (file)
@@ -112,7 +112,7 @@ func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc) {
        ctxt.Text = append(ctxt.Text, text...)
 }
 
-func (ctxt *Link) InitTextSym(p *Prog) {
+func (ctxt *Link) InitTextSym(p *Prog, flag int) {
        if p.As != ATEXT {
                ctxt.Diag("InitTextSym non-ATEXT: %v", p)
        }
@@ -132,16 +132,12 @@ func (ctxt *Link) InitTextSym(p *Prog) {
                ctxt.Diag("symbol %s listed multiple times", s.Name)
        }
        s.Set(AttrOnList, true)
-       flag := int(p.From3Offset())
-       if flag&DUPOK != 0 {
-               s.Set(AttrDuplicateOK, true)
-       }
-       if flag&NOSPLIT != 0 {
-               s.Set(AttrNoSplit, true)
-       }
-       if flag&REFLECTMETHOD != 0 {
-               s.Set(AttrReflectMethod, true)
-       }
+       s.Set(AttrDuplicateOK, flag&DUPOK != 0)
+       s.Set(AttrNoSplit, flag&NOSPLIT != 0)
+       s.Set(AttrReflectMethod, flag&REFLECTMETHOD != 0)
+       s.Set(AttrWrapper, flag&WRAPPER != 0)
+       s.Set(AttrNeedCtxt, flag&NEEDCTXT != 0)
+       s.Set(AttrNoFrame, flag&NOFRAME != 0)
        s.Type = STEXT
        s.Text = p
 }
index fb08b13fde6c34056ddffb81e288b17564735b65..3e36ed16a7b2b8e1bc3ca44bdd03e870bffb740f 100644 (file)
@@ -240,13 +240,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
        textstksiz := p.To.Offset
        if textstksiz == -8 {
                // Compatibility hack.
-               p.From3.Offset |= obj.NOFRAME
+               p.From.Sym.Set(obj.AttrNoFrame, true)
                textstksiz = 0
        }
        if textstksiz%8 != 0 {
                c.ctxt.Diag("frame size %d not a multiple of 8", textstksiz)
        }
-       if p.From3.Offset&obj.NOFRAME != 0 {
+       if p.From.Sym.NoFrame() {
                if textstksiz != 0 {
                        c.ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz)
                }
@@ -439,10 +439,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
 
                        if p.Mark&LEAF != 0 && autosize == 0 {
                                // A leaf function with no locals has no frame.
-                               p.From3.Offset |= obj.NOFRAME
+                               p.From.Sym.Set(obj.AttrNoFrame, true)
                        }
 
-                       if p.From3.Offset&obj.NOFRAME == 0 {
+                       if !p.From.Sym.NoFrame() {
                                // If there is a stack frame at all, it includes
                                // space to save the LR.
                                autosize += int32(c.ctxt.FixedFrameSize())
@@ -451,7 +451,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                        if p.Mark&LEAF != 0 && autosize < obj.StackSmall {
                                // A leaf function with a small stack can be marked
                                // NOSPLIT, avoiding a stack check.
-                               p.From3.Offset |= obj.NOSPLIT
+                               p.From.Sym.Set(obj.AttrNoSplit, true)
                        }
 
                        p.To.Offset = int64(autosize)
@@ -492,7 +492,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                rel.Type = obj.R_ADDRPOWER_PCREL
                        }
 
-                       if c.cursym.Text.From3.Offset&obj.NOSPLIT == 0 {
+                       if !c.cursym.Text.From.Sym.NoSplit() {
                                q = c.stacksplit(q, autosize) // emit split check
                        }
 
@@ -572,7 +572,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q.To.Offset = 24
                        }
 
-                       if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 {
+                       if c.cursym.Text.From.Sym.Wrapper() {
                                // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
                                //
                                //      MOVD g_panic(g), R3
@@ -950,7 +950,7 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
        var morestacksym *obj.LSym
        if c.cursym.CFunc() {
                morestacksym = c.ctxt.Lookup("runtime.morestackc", 0)
-       } else if c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
+       } else if !c.cursym.Text.From.Sym.NeedCtxt() {
                morestacksym = c.ctxt.Lookup("runtime.morestack_noctxt", 0)
        } else {
                morestacksym = c.ctxt.Lookup("runtime.morestack", 0)
index 8b86dbb4045ab5d7d2cdb9a9de7af1f1e0efedb7..99d9609e4f9070b25370dc150ef2fb107a8639f1 100644 (file)
@@ -204,13 +204,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
        textstksiz := p.To.Offset
        if textstksiz == -8 {
                // Compatibility hack.
-               p.From3.Offset |= obj.NOFRAME
+               p.From.Sym.Set(obj.AttrNoFrame, true)
                textstksiz = 0
        }
        if textstksiz%8 != 0 {
                c.ctxt.Diag("frame size %d not a multiple of 8", textstksiz)
        }
-       if p.From3.Offset&obj.NOFRAME != 0 {
+       if p.From.Sym.NoFrame() {
                if textstksiz != 0 {
                        c.ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz)
                }
@@ -293,10 +293,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
 
                        if p.Mark&LEAF != 0 && autosize == 0 {
                                // A leaf function with no locals has no frame.
-                               p.From3.Offset |= obj.NOFRAME
+                               p.From.Sym.Set(obj.AttrNoFrame, true)
                        }
 
-                       if p.From3.Offset&obj.NOFRAME == 0 {
+                       if !p.From.Sym.NoFrame() {
                                // If there is a stack frame at all, it includes
                                // space to save the LR.
                                autosize += int32(c.ctxt.FixedFrameSize())
@@ -305,14 +305,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                        if p.Mark&LEAF != 0 && autosize < obj.StackSmall {
                                // A leaf function with a small stack can be marked
                                // NOSPLIT, avoiding a stack check.
-                               p.From3.Offset |= obj.NOSPLIT
+                               p.From.Sym.Set(obj.AttrNoSplit, true)
                        }
 
                        p.To.Offset = int64(autosize)
 
                        q := p
 
-                       if p.From3.Offset&obj.NOSPLIT == 0 {
+                       if !p.From.Sym.NoSplit() {
                                p, pPreempt = c.stacksplitPre(p, autosize) // emit pre part of split check
                                pPre = p
                                wasSplit = true //need post part of split
@@ -352,7 +352,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                break
                        }
 
-                       if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 {
+                       if c.cursym.Text.From.Sym.Wrapper() {
                                // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
                                //
                                //      MOVD g_panic(g), R3
@@ -682,7 +682,7 @@ func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog,
        p.To.Type = obj.TYPE_BRANCH
        if c.cursym.CFunc() {
                p.To.Sym = c.ctxt.Lookup("runtime.morestackc", 0)
-       } else if c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
+       } else if !c.cursym.Text.From.Sym.NeedCtxt() {
                p.To.Sym = c.ctxt.Lookup("runtime.morestack_noctxt", 0)
        } else {
                p.To.Sym = c.ctxt.Lookup("runtime.morestack", 0)
index 97a3fe95bc4a95b248fdb30124c76b5bf28fa228..e800ea6efb861b909cb3ed77ca05782229b2f054 100644 (file)
@@ -143,16 +143,24 @@ func (p *Prog) String() string {
                sep = ", "
        }
        if p.From3Type() != TYPE_NONE {
-               if p.From3.Type == TYPE_CONST && p.As == ATEXT {
-                       // Special case - omit $.
-                       fmt.Fprintf(&buf, "%s%d", sep, p.From3.Offset)
-               } else if quadOpAmd64 {
+               if quadOpAmd64 {
                        fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.From3.Reg)))
                } else {
                        fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, p.From3))
                }
                sep = ", "
        }
+       if p.As == ATEXT {
+               // If there are attributes, print them. Otherwise, skip the comma.
+               // In short, print one of these two:
+               // TEXT foo(SB), DUPOK|NOSPLIT, $0
+               // TEXT foo(SB), $0
+               s := p.From.Sym.Attribute.TextAttrString()
+               if s != "" {
+                       fmt.Fprintf(&buf, "%s%s", sep, s)
+                       sep = ", "
+               }
+       }
        if p.To.Type != TYPE_NONE {
                fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.To))
        }
index fc39efeaa86f7e342e6868090b8308c6d0c0fe4d..c783bc03157e9e0a6d4badc54ac7384beb99b127 100644 (file)
@@ -609,8 +609,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
 
        var bpsize int
        if ctxt.Arch.Family == sys.AMD64 && ctxt.Framepointer_enabled &&
-               p.From3.Offset&obj.NOFRAME == 0 && // (1) below
-               !(autoffset == 0 && p.From3.Offset&obj.NOSPLIT != 0) && // (2) below
+               !p.From.Sym.NoFrame() && // (1) below
+               !(autoffset == 0 && p.From.Sym.NoSplit()) && // (2) below
                !(autoffset == 0 && !hasCall) { // (3) below
                // Make room to save a base pointer.
                // There are 2 cases we must avoid:
@@ -637,7 +637,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
        }
 
        // TODO(rsc): Remove 'ctxt.Arch.Family == sys.AMD64 &&'.
-       if ctxt.Arch.Family == sys.AMD64 && autoffset < obj.StackSmall && p.From3Offset()&obj.NOSPLIT == 0 {
+       if ctxt.Arch.Family == sys.AMD64 && autoffset < obj.StackSmall && !p.From.Sym.NoSplit() {
                leaf := true
        LeafSearch:
                for q := p; q != nil; q = q.Link {
@@ -659,16 +659,16 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                }
 
                if leaf {
-                       p.From3.Offset |= obj.NOSPLIT
+                       p.From.Sym.Set(obj.AttrNoSplit, true)
                }
        }
 
-       if p.From3Offset()&obj.NOSPLIT == 0 || p.From3Offset()&obj.WRAPPER != 0 {
+       if !p.From.Sym.NoSplit() || p.From.Sym.Wrapper() {
                p = obj.Appendp(p, newprog)
                p = load_g_cx(ctxt, p, newprog) // load g into CX
        }
 
-       if cursym.Text.From3Offset()&obj.NOSPLIT == 0 {
+       if !cursym.Text.From.Sym.NoSplit() {
                p = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg)) // emit split check
        }
 
@@ -709,7 +709,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                p.To.Reg = REG_BP
        }
 
-       if cursym.Text.From3Offset()&obj.WRAPPER != 0 {
+       if cursym.Text.From.Sym.Wrapper() {
                // if g._panic != nil && g._panic.argp == FP {
                //   g._panic.argp = bottom-of-frame
                // }
@@ -1150,7 +1150,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgA
        switch {
        case cursym.CFunc():
                morestack = "runtime.morestackc"
-       case cursym.Text.From3Offset()&obj.NEEDCTXT == 0:
+       case !cursym.Text.From.Sym.NeedCtxt():
                morestack = "runtime.morestack_noctxt"
        }
        call.To.Sym = ctxt.Lookup(morestack, 0)