diff --git a/misc/nacl/testzip.proto b/misc/nacl/testzip.proto index 53151f285c8..8bf25400cbc 100644 --- a/misc/nacl/testzip.proto +++ b/misc/nacl/testzip.proto @@ -162,6 +162,8 @@ go src=.. regexp testdata + + runtime + textflag.h strconv testdata + diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go index 0e31677a3f6..7e3a8418dd4 100644 --- a/src/cmd/asm/internal/asm/asm.go +++ b/src/cmd/asm/internal/asm/asm.go @@ -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) } diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go index f9d95ebc8ca..36aa4aedd83 100644 --- a/src/cmd/asm/internal/asm/endtoend_test.go +++ b/src/cmd/asm/internal/asm/endtoend_test.go @@ -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] diff --git a/src/cmd/asm/internal/asm/testdata/386.s b/src/cmd/asm/internal/asm/testdata/386.s index 4d969d1539c..ad8affd854b 100644 --- a/src/cmd/asm/internal/asm/testdata/386.s +++ b/src/cmd/asm/internal/asm/testdata/386.s @@ -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 diff --git a/src/cmd/asm/internal/asm/testdata/amd64.s b/src/cmd/asm/internal/asm/testdata/amd64.s index da0144230db..d07cf0d2137 100644 --- a/src/cmd/asm/internal/asm/testdata/amd64.s +++ b/src/cmd/asm/internal/asm/testdata/amd64.s @@ -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 diff --git a/src/cmd/asm/internal/asm/testdata/amd64enc.s b/src/cmd/asm/internal/asm/testdata/amd64enc.s index b27faa5a360..3d6061f8392 100644 --- a/src/cmd/asm/internal/asm/testdata/amd64enc.s +++ b/src/cmd/asm/internal/asm/testdata/amd64enc.s @@ -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 diff --git a/src/cmd/asm/internal/asm/testdata/arm.s b/src/cmd/asm/internal/asm/testdata/arm.s index 0ae031ee815..969fb66cdfd 100644 --- a/src/cmd/asm/internal/asm/testdata/arm.s +++ b/src/cmd/asm/internal/asm/testdata/arm.s @@ -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 // diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s index 28b34e3d726..9dfcab5fba2 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64.s +++ b/src/cmd/asm/internal/asm/testdata/arm64.s @@ -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 diff --git a/src/cmd/asm/internal/asm/testdata/mips.s b/src/cmd/asm/internal/asm/testdata/mips.s index f48d91885d2..0f0226de0cd 100644 --- a/src/cmd/asm/internal/asm/testdata/mips.s +++ b/src/cmd/asm/internal/asm/testdata/mips.s @@ -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: // diff --git a/src/cmd/asm/internal/asm/testdata/mips64.s b/src/cmd/asm/internal/asm/testdata/mips64.s index e217d35a133..e3d898af872 100644 --- a/src/cmd/asm/internal/asm/testdata/mips64.s +++ b/src/cmd/asm/internal/asm/testdata/mips64.s @@ -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: // diff --git a/src/cmd/asm/internal/asm/testdata/ppc64.s b/src/cmd/asm/internal/asm/testdata/ppc64.s index 8498f5804a0..14b0de12714 100644 --- a/src/cmd/asm/internal/asm/testdata/ppc64.s +++ b/src/cmd/asm/internal/asm/testdata/ppc64.s @@ -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: // diff --git a/src/cmd/asm/internal/asm/testdata/s390x.s b/src/cmd/asm/internal/asm/testdata/s390x.s index 55df0f953aa..1ab07b65e84 100644 --- a/src/cmd/asm/internal/asm/testdata/s390x.s +++ b/src/cmd/asm/internal/asm/testdata/s390x.s @@ -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 diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go index 2c628a521fc..f3aef208d6a 100644 --- a/src/cmd/compile/internal/gc/gsubr.go +++ b/src/cmd/compile/internal/gc/gsubr.go @@ -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 } diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go index cec7c212d4e..fb63712918e 100644 --- a/src/cmd/internal/obj/arm/obj5.go +++ b/src/cmd/internal/obj/arm/obj5.go @@ -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) diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go index 5c567013632..1c8a40f9d63 100644 --- a/src/cmd/internal/obj/arm64/obj7.go +++ b/src/cmd/internal/obj/arm64/obj7.go @@ -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 diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go index d5d96f792ec..fc0305344f0 100644 --- a/src/cmd/internal/obj/link.go +++ b/src/cmd/internal/obj/link.go @@ -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 { diff --git a/src/cmd/internal/obj/mips/obj0.go b/src/cmd/internal/obj/mips/obj0.go index bef1b4d5512..6ea156e32ca 100644 --- a/src/cmd/internal/obj/mips/obj0.go +++ b/src/cmd/internal/obj/mips/obj0.go @@ -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) diff --git a/src/cmd/internal/obj/plist.go b/src/cmd/internal/obj/plist.go index 6614f7d74ef..b2acd0f29d6 100644 --- a/src/cmd/internal/obj/plist.go +++ b/src/cmd/internal/obj/plist.go @@ -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 } diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go index fb08b13fde6..3e36ed16a7b 100644 --- a/src/cmd/internal/obj/ppc64/obj9.go +++ b/src/cmd/internal/obj/ppc64/obj9.go @@ -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) diff --git a/src/cmd/internal/obj/s390x/objz.go b/src/cmd/internal/obj/s390x/objz.go index 8b86dbb4045..99d9609e4f9 100644 --- a/src/cmd/internal/obj/s390x/objz.go +++ b/src/cmd/internal/obj/s390x/objz.go @@ -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) diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go index 97a3fe95bc4..e800ea6efb8 100644 --- a/src/cmd/internal/obj/util.go +++ b/src/cmd/internal/obj/util.go @@ -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)) } diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go index fc39efeaa86..c783bc03157 100644 --- a/src/cmd/internal/obj/x86/obj6.go +++ b/src/cmd/internal/obj/x86/obj6.go @@ -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)