]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: split out package objw [generated]
authorRuss Cox <rsc@golang.org>
Wed, 23 Dec 2020 05:46:27 +0000 (00:46 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 23 Dec 2020 06:38:47 +0000 (06:38 +0000)
Object file writing routines are used not just at the end
of the compilation but also during static data layout in walk.
Split them into their own package.

[git-generate]

cd src/cmd/compile/internal/gc
rf '
# Move bit vector to new package bitvec
mv bvec.n bvec.N
mv bvec.b bvec.B
mv bvec BitVec
mv bvalloc New
mv bvbulkalloc NewBulk
mv bulkBvec.next bulkBvec.Next
mv bulkBvec Bulk
mv H0 h0
mv Hp hp

# Leave bvecSet and bitmap hashes behind - not needed as broadly.
mv bvecSet.extractUniqe bvecSet.extractUnique
mv h0 bvecSet bvecSet.grow bvecSet.add \
bvecSet.extractUnique hashbitmap bvset.go

mv bv.go cmd/compile/internal/bitvec

ex . ../arm ../arm64 ../mips ../mips64 ../ppc64 ../s390x ../riscv64 {
import "cmd/internal/obj"
var a *obj.Addr
var i int64
Addrconst(a, i) -> a.SetConst(i)
var p, to *obj.Prog
Patch(p, to) -> p.To.SetTarget(to)
}
rm Addrconst Patch

# Move object-writing API to new package objw
mv duint8 Objw_Uint8
mv duint16 Objw_Uint16
mv duint32 Objw_Uint32
mv duintptr Objw_Uintptr
mv duintxx Objw_UintN
mv dsymptr Objw_SymPtr
mv dsymptrOff Objw_SymPtrOff
mv dsymptrWeakOff Objw_SymPtrWeakOff
mv ggloblsym Objw_Global
mv dbvec Objw_BitVec
mv newProgs NewProgs
mv Progs.clearp Progs.Clear
mv Progs.settext Progs.SetText
mv Progs.next Progs.Next
mv Progs.pc Progs.PC
mv Progs.pos Progs.Pos
mv Progs.curfn Progs.CurFunc
mv Progs.progcache Progs.Cache
mv Progs.cacheidx Progs.CacheIndex
mv Progs.nextLive Progs.NextLive
mv Progs.prevLive Progs.PrevLive
mv Progs.Appendpp Progs.Append
mv LivenessIndex.stackMapIndex LivenessIndex.StackMapIndex
mv LivenessIndex.isUnsafePoint LivenessIndex.IsUnsafePoint

mv Objw_Uint8 Objw_Uint16 Objw_Uint32 Objw_Uintptr Objw_UintN \
Objw_SymPtr Objw_SymPtrOff Objw_SymPtrWeakOff Objw_Global \
Objw_BitVec \
objw.go
mv sharedProgArray NewProgs Progs \
LivenessIndex StackMapDontCare \
LivenessDontCare LivenessIndex.StackMapValid \
Progs.NewProg Progs.Flush Progs.Free Progs.Prog Progs.Clear Progs.Append Progs.SetText \
prog.go
mv prog.go objw.go cmd/compile/internal/objw

# Move ggloblnod to obj with the rest of the non-objw higher-level writing.
mv ggloblnod obj.go
'

cd ../objw
rf '
mv Objw_Uint8 Uint8
mv Objw_Uint16 Uint16
mv Objw_Uint32 Uint32
mv Objw_Uintptr Uintptr
mv Objw_UintN UintN
mv Objw_SymPtr SymPtr
mv Objw_SymPtrOff SymPtrOff
mv Objw_SymPtrWeakOff SymPtrWeakOff
mv Objw_Global Global
mv Objw_BitVec BitVec
'

Change-Id: I2b87085aa788564fb322e9c55bddd73347b4d5fd
Reviewed-on: https://go-review.googlesource.com/c/go/+/279310
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
33 files changed:
src/cmd/compile/internal/amd64/ggen.go
src/cmd/compile/internal/arm/ggen.go
src/cmd/compile/internal/arm/ssa.go
src/cmd/compile/internal/arm64/ggen.go
src/cmd/compile/internal/arm64/ssa.go
src/cmd/compile/internal/bitvec/bv.go [new file with mode: 0644]
src/cmd/compile/internal/gc/alg.go
src/cmd/compile/internal/gc/bv.go [deleted file]
src/cmd/compile/internal/gc/bvset.go [new file with mode: 0644]
src/cmd/compile/internal/gc/embed.go
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/gsubr.go
src/cmd/compile/internal/gc/init.go
src/cmd/compile/internal/gc/obj.go
src/cmd/compile/internal/gc/pgen.go
src/cmd/compile/internal/gc/plive.go
src/cmd/compile/internal/gc/reflect.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/mips/ggen.go
src/cmd/compile/internal/mips/ssa.go
src/cmd/compile/internal/mips64/ggen.go
src/cmd/compile/internal/mips64/ssa.go
src/cmd/compile/internal/objw/objw.go [new file with mode: 0644]
src/cmd/compile/internal/objw/prog.go [new file with mode: 0644]
src/cmd/compile/internal/ppc64/ggen.go
src/cmd/compile/internal/ppc64/ssa.go
src/cmd/compile/internal/riscv64/ggen.go
src/cmd/compile/internal/riscv64/gsubr.go
src/cmd/compile/internal/riscv64/ssa.go
src/cmd/compile/internal/s390x/ggen.go
src/cmd/compile/internal/s390x/ssa.go
src/cmd/compile/internal/wasm/ssa.go
src/cmd/compile/internal/x86/ggen.go

index 48b00b3da9e3282ce2e6d1a217ae5b3afaed62bd..dacdb07a3837dc5243acf8591b563105f98ca4c9 100644 (file)
@@ -6,8 +6,8 @@ package amd64
 
 import (
        "cmd/compile/internal/base"
-       "cmd/compile/internal/gc"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/obj/x86"
@@ -54,7 +54,7 @@ func dzDI(b int64) int64 {
        return -dzClearStep * (dzBlockLen - tailSteps)
 }
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Prog {
        const (
                ax = 1 << iota
                x0
@@ -70,61 +70,61 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Pr
                        base.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
                }
                if *state&ax == 0 {
-                       p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
+                       p = pp.Append(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
                        *state |= ax
                }
-               p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off)
+               p = pp.Append(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off)
                off += int64(types.PtrSize)
                cnt -= int64(types.PtrSize)
        }
 
        if cnt == 8 {
                if *state&ax == 0 {
-                       p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
+                       p = pp.Append(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
                        *state |= ax
                }
-               p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off)
+               p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off)
        } else if !isPlan9 && cnt <= int64(8*types.RegSize) {
                if *state&x0 == 0 {
-                       p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
+                       p = pp.Append(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
                        *state |= x0
                }
 
                for i := int64(0); i < cnt/16; i++ {
-                       p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, off+i*16)
+                       p = pp.Append(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, off+i*16)
                }
 
                if cnt%16 != 0 {
-                       p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, off+cnt-int64(16))
+                       p = pp.Append(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, off+cnt-int64(16))
                }
        } else if !isPlan9 && (cnt <= int64(128*types.RegSize)) {
                if *state&x0 == 0 {
-                       p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
+                       p = pp.Append(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
                        *state |= x0
                }
-               p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off+dzDI(cnt), obj.TYPE_REG, x86.REG_DI, 0)
-               p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, dzOff(cnt))
+               p = pp.Append(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off+dzDI(cnt), obj.TYPE_REG, x86.REG_DI, 0)
+               p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, dzOff(cnt))
                p.To.Sym = ir.Syms.Duffzero
 
                if cnt%16 != 0 {
-                       p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_DI, -int64(8))
+                       p = pp.Append(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_DI, -int64(8))
                }
        } else {
                if *state&ax == 0 {
-                       p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
+                       p = pp.Append(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
                        *state |= ax
                }
 
-               p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, cnt/int64(types.RegSize), obj.TYPE_REG, x86.REG_CX, 0)
-               p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
-               p = pp.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
-               p = pp.Appendpp(p, x86.ASTOSQ, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
+               p = pp.Append(p, x86.AMOVQ, obj.TYPE_CONST, 0, cnt/int64(types.RegSize), obj.TYPE_REG, x86.REG_CX, 0)
+               p = pp.Append(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
+               p = pp.Append(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
+               p = pp.Append(p, x86.ASTOSQ, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
        }
 
        return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
        // This is a hardware nop (1-byte 0x90) instruction,
        // even though we describe it as an explicit XCHGL here.
        // Particularly, this does not zero the high 32 bits
index 2363d76346e29769074576226265d82e2bc16da0..f2c676300a93a5531c2f160fb0dba7f121068683 100644 (file)
@@ -5,51 +5,51 @@
 package arm
 
 import (
-       "cmd/compile/internal/gc"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/obj/arm"
 )
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, r0 *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, r0 *uint32) *obj.Prog {
        if cnt == 0 {
                return p
        }
        if *r0 == 0 {
-               p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, arm.REG_R0, 0)
+               p = pp.Append(p, arm.AMOVW, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, arm.REG_R0, 0)
                *r0 = 1
        }
 
        if cnt < int64(4*types.PtrSize) {
                for i := int64(0); i < cnt; i += int64(types.PtrSize) {
-                       p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REGSP, 4+off+i)
+                       p = pp.Append(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REGSP, 4+off+i)
                }
        } else if cnt <= int64(128*types.PtrSize) {
-               p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, 4+off, obj.TYPE_REG, arm.REG_R1, 0)
+               p = pp.Append(p, arm.AADD, obj.TYPE_CONST, 0, 4+off, obj.TYPE_REG, arm.REG_R1, 0)
                p.Reg = arm.REGSP
-               p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
+               p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = ir.Syms.Duffzero
                p.To.Offset = 4 * (128 - cnt/int64(types.PtrSize))
        } else {
-               p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, 4+off, obj.TYPE_REG, arm.REG_R1, 0)
+               p = pp.Append(p, arm.AADD, obj.TYPE_CONST, 0, 4+off, obj.TYPE_REG, arm.REG_R1, 0)
                p.Reg = arm.REGSP
-               p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, arm.REG_R2, 0)
+               p = pp.Append(p, arm.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, arm.REG_R2, 0)
                p.Reg = arm.REG_R1
-               p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REG_R1, 4)
+               p = pp.Append(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REG_R1, 4)
                p1 := p
                p.Scond |= arm.C_PBIT
-               p = pp.Appendpp(p, arm.ACMP, obj.TYPE_REG, arm.REG_R1, 0, obj.TYPE_NONE, 0, 0)
+               p = pp.Append(p, arm.ACMP, obj.TYPE_REG, arm.REG_R1, 0, obj.TYPE_NONE, 0, 0)
                p.Reg = arm.REG_R2
-               p = pp.Appendpp(p, arm.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
-               gc.Patch(p, p1)
+               p = pp.Append(p, arm.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
+               p.To.SetTarget(p1)
        }
 
        return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
        p := pp.Prog(arm.AAND)
        p.From.Type = obj.TYPE_REG
        p.From.Reg = arm.REG_R0
index ab7ec6176b38887db7fc9cffe22db9c3990f357b..30eae59331c3a56b61dec7fbc170263a47db6fa9 100644 (file)
@@ -779,7 +779,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p2.Reg = arm.REG_R1
                p3 := s.Prog(arm.ABLE)
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
        case ssa.OpARMLoweredMove:
                // MOVW.P       4(R1), Rtmp
                // MOVW.P       Rtmp, 4(R2)
@@ -820,7 +820,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.Reg = arm.REG_R1
                p4 := s.Prog(arm.ABLE)
                p4.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p4, p)
+               p4.To.SetTarget(p)
        case ssa.OpARMEqual,
                ssa.OpARMNotEqual,
                ssa.OpARMLessThan,
index 37f11e0ff64cfd2e120aea045f6282ba3c046b50..8364535f63bb8f49882faeb8d54ff2eb82cc6562 100644 (file)
@@ -5,8 +5,8 @@
 package arm64
 
 import (
-       "cmd/compile/internal/gc"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/obj/arm64"
@@ -24,24 +24,24 @@ func padframe(frame int64) int64 {
        return frame
 }
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
        if cnt == 0 {
                return p
        }
        if cnt < int64(4*types.PtrSize) {
                for i := int64(0); i < cnt; i += int64(types.PtrSize) {
-                       p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off+i)
+                       p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off+i)
                }
        } else if cnt <= int64(128*types.PtrSize) && !darwin { // darwin ld64 cannot handle BR26 reloc with non-zero addend
                if cnt%(2*int64(types.PtrSize)) != 0 {
-                       p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off)
+                       p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off)
                        off += int64(types.PtrSize)
                        cnt -= int64(types.PtrSize)
                }
-               p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REG_R20, 0)
-               p = pp.Appendpp(p, arm64.AADD, obj.TYPE_CONST, 0, 8+off, obj.TYPE_REG, arm64.REG_R20, 0)
+               p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REG_R20, 0)
+               p = pp.Append(p, arm64.AADD, obj.TYPE_CONST, 0, 8+off, obj.TYPE_REG, arm64.REG_R20, 0)
                p.Reg = arm64.REG_R20
-               p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
+               p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = ir.Syms.Duffzero
                p.To.Offset = 4 * (64 - cnt/(2*int64(types.PtrSize)))
@@ -50,26 +50,26 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
                // We are at the function entry, where no register is live, so it is okay to clobber
                // other registers
                const rtmp = arm64.REG_R20
-               p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, rtmp, 0)
-               p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
-               p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT1, 0)
+               p = pp.Append(p, arm64.AMOVD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, rtmp, 0)
+               p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
+               p = pp.Append(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT1, 0)
                p.Reg = arm64.REGRT1
-               p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, rtmp, 0)
-               p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT2, 0)
+               p = pp.Append(p, arm64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, rtmp, 0)
+               p = pp.Append(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT2, 0)
                p.Reg = arm64.REGRT1
-               p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGRT1, int64(types.PtrSize))
+               p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGRT1, int64(types.PtrSize))
                p.Scond = arm64.C_XPRE
                p1 := p
-               p = pp.Appendpp(p, arm64.ACMP, obj.TYPE_REG, arm64.REGRT1, 0, obj.TYPE_NONE, 0, 0)
+               p = pp.Append(p, arm64.ACMP, obj.TYPE_REG, arm64.REGRT1, 0, obj.TYPE_NONE, 0, 0)
                p.Reg = arm64.REGRT2
-               p = pp.Appendpp(p, arm64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
-               gc.Patch(p, p1)
+               p = pp.Append(p, arm64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
+               p.To.SetTarget(p1)
        }
 
        return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
        p := pp.Prog(arm64.AHINT)
        p.From.Type = obj.TYPE_CONST
        return p
index bb634cc38c83a32432d45625ea4f5aa5989dee09..9bdea3ee2a4d9de13947721bbe222e80951a1091 100644 (file)
@@ -582,7 +582,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p2.From.Type = obj.TYPE_REG
                p2.From.Reg = arm64.REGTMP
                p2.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p2, p)
+               p2.To.SetTarget(p)
        case ssa.OpARM64LoweredAtomicExchange64Variant,
                ssa.OpARM64LoweredAtomicExchange32Variant:
                swap := arm64.ASWPALD
@@ -636,7 +636,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.From.Type = obj.TYPE_REG
                p3.From.Reg = arm64.REGTMP
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
        case ssa.OpARM64LoweredAtomicAdd64Variant,
                ssa.OpARM64LoweredAtomicAdd32Variant:
                // LDADDAL      Rarg1, (Rarg0), Rout
@@ -700,13 +700,13 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p4.From.Type = obj.TYPE_REG
                p4.From.Reg = arm64.REGTMP
                p4.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p4, p)
+               p4.To.SetTarget(p)
                p5 := s.Prog(arm64.ACSET)
                p5.From.Type = obj.TYPE_REG // assembler encodes conditional bits in Reg
                p5.From.Reg = arm64.COND_EQ
                p5.To.Type = obj.TYPE_REG
                p5.To.Reg = out
-               gc.Patch(p2, p5)
+               p2.To.SetTarget(p5)
        case ssa.OpARM64LoweredAtomicCas64Variant,
                ssa.OpARM64LoweredAtomicCas32Variant:
                // Rarg0: ptr
@@ -794,7 +794,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.From.Type = obj.TYPE_REG
                p3.From.Reg = arm64.REGTMP
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
        case ssa.OpARM64LoweredAtomicAnd8Variant,
                ssa.OpARM64LoweredAtomicAnd32Variant:
                atomic_clear := arm64.ALDCLRALW
@@ -982,7 +982,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p2.Reg = arm64.REG_R16
                p3 := s.Prog(arm64.ABLE)
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
        case ssa.OpARM64DUFFCOPY:
                p := s.Prog(obj.ADUFFCOPY)
                p.To.Type = obj.TYPE_MEM
@@ -1015,7 +1015,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.Reg = arm64.REG_R16
                p4 := s.Prog(arm64.ABLE)
                p4.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p4, p)
+               p4.To.SetTarget(p)
        case ssa.OpARM64CALLstatic, ssa.OpARM64CALLclosure, ssa.OpARM64CALLinter:
                s.Call(v)
        case ssa.OpARM64LoweredWB:
diff --git a/src/cmd/compile/internal/bitvec/bv.go b/src/cmd/compile/internal/bitvec/bv.go
new file mode 100644 (file)
index 0000000..1e08457
--- /dev/null
@@ -0,0 +1,190 @@
+// Copyright 2013 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 bitvec
+
+import (
+       "math/bits"
+
+       "cmd/compile/internal/base"
+)
+
+const (
+       wordBits  = 32
+       wordMask  = wordBits - 1
+       wordShift = 5
+)
+
+// A BitVec is a bit vector.
+type BitVec struct {
+       N int32    // number of bits in vector
+       B []uint32 // words holding bits
+}
+
+func New(n int32) BitVec {
+       nword := (n + wordBits - 1) / wordBits
+       return BitVec{n, make([]uint32, nword)}
+}
+
+type Bulk struct {
+       words []uint32
+       nbit  int32
+       nword int32
+}
+
+func NewBulk(nbit int32, count int32) Bulk {
+       nword := (nbit + wordBits - 1) / wordBits
+       size := int64(nword) * int64(count)
+       if int64(int32(size*4)) != size*4 {
+               base.Fatalf("bvbulkalloc too big: nbit=%d count=%d nword=%d size=%d", nbit, count, nword, size)
+       }
+       return Bulk{
+               words: make([]uint32, size),
+               nbit:  nbit,
+               nword: nword,
+       }
+}
+
+func (b *Bulk) Next() BitVec {
+       out := BitVec{b.nbit, b.words[:b.nword]}
+       b.words = b.words[b.nword:]
+       return out
+}
+
+func (bv1 BitVec) Eq(bv2 BitVec) bool {
+       if bv1.N != bv2.N {
+               base.Fatalf("bvequal: lengths %d and %d are not equal", bv1.N, bv2.N)
+       }
+       for i, x := range bv1.B {
+               if x != bv2.B[i] {
+                       return false
+               }
+       }
+       return true
+}
+
+func (dst BitVec) Copy(src BitVec) {
+       copy(dst.B, src.B)
+}
+
+func (bv BitVec) Get(i int32) bool {
+       if i < 0 || i >= bv.N {
+               base.Fatalf("bvget: index %d is out of bounds with length %d\n", i, bv.N)
+       }
+       mask := uint32(1 << uint(i%wordBits))
+       return bv.B[i>>wordShift]&mask != 0
+}
+
+func (bv BitVec) Set(i int32) {
+       if i < 0 || i >= bv.N {
+               base.Fatalf("bvset: index %d is out of bounds with length %d\n", i, bv.N)
+       }
+       mask := uint32(1 << uint(i%wordBits))
+       bv.B[i/wordBits] |= mask
+}
+
+func (bv BitVec) Unset(i int32) {
+       if i < 0 || i >= bv.N {
+               base.Fatalf("bvunset: index %d is out of bounds with length %d\n", i, bv.N)
+       }
+       mask := uint32(1 << uint(i%wordBits))
+       bv.B[i/wordBits] &^= mask
+}
+
+// bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
+// If there is no such index, bvnext returns -1.
+func (bv BitVec) Next(i int32) int32 {
+       if i >= bv.N {
+               return -1
+       }
+
+       // Jump i ahead to next word with bits.
+       if bv.B[i>>wordShift]>>uint(i&wordMask) == 0 {
+               i &^= wordMask
+               i += wordBits
+               for i < bv.N && bv.B[i>>wordShift] == 0 {
+                       i += wordBits
+               }
+       }
+
+       if i >= bv.N {
+               return -1
+       }
+
+       // Find 1 bit.
+       w := bv.B[i>>wordShift] >> uint(i&wordMask)
+       i += int32(bits.TrailingZeros32(w))
+
+       return i
+}
+
+func (bv BitVec) IsEmpty() bool {
+       for _, x := range bv.B {
+               if x != 0 {
+                       return false
+               }
+       }
+       return true
+}
+
+func (bv BitVec) Not() {
+       for i, x := range bv.B {
+               bv.B[i] = ^x
+       }
+}
+
+// union
+func (dst BitVec) Or(src1, src2 BitVec) {
+       if len(src1.B) == 0 {
+               return
+       }
+       _, _ = dst.B[len(src1.B)-1], src2.B[len(src1.B)-1] // hoist bounds checks out of the loop
+
+       for i, x := range src1.B {
+               dst.B[i] = x | src2.B[i]
+       }
+}
+
+// intersection
+func (dst BitVec) And(src1, src2 BitVec) {
+       if len(src1.B) == 0 {
+               return
+       }
+       _, _ = dst.B[len(src1.B)-1], src2.B[len(src1.B)-1] // hoist bounds checks out of the loop
+
+       for i, x := range src1.B {
+               dst.B[i] = x & src2.B[i]
+       }
+}
+
+// difference
+func (dst BitVec) AndNot(src1, src2 BitVec) {
+       if len(src1.B) == 0 {
+               return
+       }
+       _, _ = dst.B[len(src1.B)-1], src2.B[len(src1.B)-1] // hoist bounds checks out of the loop
+
+       for i, x := range src1.B {
+               dst.B[i] = x &^ src2.B[i]
+       }
+}
+
+func (bv BitVec) String() string {
+       s := make([]byte, 2+bv.N)
+       copy(s, "#*")
+       for i := int32(0); i < bv.N; i++ {
+               ch := byte('0')
+               if bv.Get(i) {
+                       ch = '1'
+               }
+               s[2+i] = ch
+       }
+       return string(s)
+}
+
+func (bv BitVec) Clear() {
+       for i := range bv.B {
+               bv.B[i] = 0
+       }
+}
index b0d46eab2feee4cb9bdd14445db805726fcddb11..4fc8cf04eff5c6d09c7736d2c06e1436dfb39106 100644 (file)
@@ -7,6 +7,7 @@ package gc
 import (
        "cmd/compile/internal/base"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/typecheck"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -110,9 +111,9 @@ func genhash(t *types.Type) *obj.LSym {
                        memhashvarlen = typecheck.LookupRuntimeFunc("memhash_varlen")
                }
                ot := 0
-               ot = dsymptr(closure, ot, memhashvarlen, 0)
-               ot = duintptr(closure, ot, uint64(t.Width)) // size encoded in closure
-               ggloblsym(closure, int32(ot), obj.DUPOK|obj.RODATA)
+               ot = objw.SymPtr(closure, ot, memhashvarlen, 0)
+               ot = objw.Uintptr(closure, ot, uint64(t.Width)) // size encoded in closure
+               objw.Global(closure, int32(ot), obj.DUPOK|obj.RODATA)
                return closure
        case types.ASPECIAL:
                break
@@ -253,8 +254,8 @@ func genhash(t *types.Type) *obj.LSym {
 
        // Build closure. It doesn't close over any variables, so
        // it contains just the function pointer.
-       dsymptr(closure, 0, sym.Linksym(), 0)
-       ggloblsym(closure, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
+       objw.SymPtr(closure, 0, sym.Linksym(), 0)
+       objw.Global(closure, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
 
        return closure
 }
@@ -302,8 +303,8 @@ func sysClosure(name string) *obj.LSym {
        s := typecheck.LookupRuntimeVar(name + "·f")
        if len(s.P) == 0 {
                f := typecheck.LookupRuntimeFunc(name)
-               dsymptr(s, 0, f, 0)
-               ggloblsym(s, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
+               objw.SymPtr(s, 0, f, 0)
+               objw.Global(s, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
        }
        return s
 }
@@ -353,9 +354,9 @@ func geneq(t *types.Type) *obj.LSym {
                        memequalvarlen = typecheck.LookupRuntimeVar("memequal_varlen") // asm func
                }
                ot := 0
-               ot = dsymptr(closure, ot, memequalvarlen, 0)
-               ot = duintptr(closure, ot, uint64(t.Width))
-               ggloblsym(closure, int32(ot), obj.DUPOK|obj.RODATA)
+               ot = objw.SymPtr(closure, ot, memequalvarlen, 0)
+               ot = objw.Uintptr(closure, ot, uint64(t.Width))
+               objw.Global(closure, int32(ot), obj.DUPOK|obj.RODATA)
                return closure
        case types.ASPECIAL:
                break
@@ -632,8 +633,8 @@ func geneq(t *types.Type) *obj.LSym {
        typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
 
        // Generate a closure which points at the function we just generated.
-       dsymptr(closure, 0, sym.Linksym(), 0)
-       ggloblsym(closure, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
+       objw.SymPtr(closure, 0, sym.Linksym(), 0)
+       objw.Global(closure, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
        return closure
 }
 
diff --git a/src/cmd/compile/internal/gc/bv.go b/src/cmd/compile/internal/gc/bv.go
deleted file mode 100644 (file)
index d82851e..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2013 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 gc
-
-import (
-       "math/bits"
-
-       "cmd/compile/internal/base"
-)
-
-const (
-       wordBits  = 32
-       wordMask  = wordBits - 1
-       wordShift = 5
-)
-
-// A bvec is a bit vector.
-type bvec struct {
-       n int32    // number of bits in vector
-       b []uint32 // words holding bits
-}
-
-func bvalloc(n int32) bvec {
-       nword := (n + wordBits - 1) / wordBits
-       return bvec{n, make([]uint32, nword)}
-}
-
-type bulkBvec struct {
-       words []uint32
-       nbit  int32
-       nword int32
-}
-
-func bvbulkalloc(nbit int32, count int32) bulkBvec {
-       nword := (nbit + wordBits - 1) / wordBits
-       size := int64(nword) * int64(count)
-       if int64(int32(size*4)) != size*4 {
-               base.Fatalf("bvbulkalloc too big: nbit=%d count=%d nword=%d size=%d", nbit, count, nword, size)
-       }
-       return bulkBvec{
-               words: make([]uint32, size),
-               nbit:  nbit,
-               nword: nword,
-       }
-}
-
-func (b *bulkBvec) next() bvec {
-       out := bvec{b.nbit, b.words[:b.nword]}
-       b.words = b.words[b.nword:]
-       return out
-}
-
-func (bv1 bvec) Eq(bv2 bvec) bool {
-       if bv1.n != bv2.n {
-               base.Fatalf("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n)
-       }
-       for i, x := range bv1.b {
-               if x != bv2.b[i] {
-                       return false
-               }
-       }
-       return true
-}
-
-func (dst bvec) Copy(src bvec) {
-       copy(dst.b, src.b)
-}
-
-func (bv bvec) Get(i int32) bool {
-       if i < 0 || i >= bv.n {
-               base.Fatalf("bvget: index %d is out of bounds with length %d\n", i, bv.n)
-       }
-       mask := uint32(1 << uint(i%wordBits))
-       return bv.b[i>>wordShift]&mask != 0
-}
-
-func (bv bvec) Set(i int32) {
-       if i < 0 || i >= bv.n {
-               base.Fatalf("bvset: index %d is out of bounds with length %d\n", i, bv.n)
-       }
-       mask := uint32(1 << uint(i%wordBits))
-       bv.b[i/wordBits] |= mask
-}
-
-func (bv bvec) Unset(i int32) {
-       if i < 0 || i >= bv.n {
-               base.Fatalf("bvunset: index %d is out of bounds with length %d\n", i, bv.n)
-       }
-       mask := uint32(1 << uint(i%wordBits))
-       bv.b[i/wordBits] &^= mask
-}
-
-// bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
-// If there is no such index, bvnext returns -1.
-func (bv bvec) Next(i int32) int32 {
-       if i >= bv.n {
-               return -1
-       }
-
-       // Jump i ahead to next word with bits.
-       if bv.b[i>>wordShift]>>uint(i&wordMask) == 0 {
-               i &^= wordMask
-               i += wordBits
-               for i < bv.n && bv.b[i>>wordShift] == 0 {
-                       i += wordBits
-               }
-       }
-
-       if i >= bv.n {
-               return -1
-       }
-
-       // Find 1 bit.
-       w := bv.b[i>>wordShift] >> uint(i&wordMask)
-       i += int32(bits.TrailingZeros32(w))
-
-       return i
-}
-
-func (bv bvec) IsEmpty() bool {
-       for _, x := range bv.b {
-               if x != 0 {
-                       return false
-               }
-       }
-       return true
-}
-
-func (bv bvec) Not() {
-       for i, x := range bv.b {
-               bv.b[i] = ^x
-       }
-}
-
-// union
-func (dst bvec) Or(src1, src2 bvec) {
-       if len(src1.b) == 0 {
-               return
-       }
-       _, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop
-
-       for i, x := range src1.b {
-               dst.b[i] = x | src2.b[i]
-       }
-}
-
-// intersection
-func (dst bvec) And(src1, src2 bvec) {
-       if len(src1.b) == 0 {
-               return
-       }
-       _, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop
-
-       for i, x := range src1.b {
-               dst.b[i] = x & src2.b[i]
-       }
-}
-
-// difference
-func (dst bvec) AndNot(src1, src2 bvec) {
-       if len(src1.b) == 0 {
-               return
-       }
-       _, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop
-
-       for i, x := range src1.b {
-               dst.b[i] = x &^ src2.b[i]
-       }
-}
-
-func (bv bvec) String() string {
-       s := make([]byte, 2+bv.n)
-       copy(s, "#*")
-       for i := int32(0); i < bv.n; i++ {
-               ch := byte('0')
-               if bv.Get(i) {
-                       ch = '1'
-               }
-               s[2+i] = ch
-       }
-       return string(s)
-}
-
-func (bv bvec) Clear() {
-       for i := range bv.b {
-               bv.b[i] = 0
-       }
-}
-
-// FNV-1 hash function constants.
-const (
-       H0 = 2166136261
-       Hp = 16777619
-)
-
-func hashbitmap(h uint32, bv bvec) uint32 {
-       n := int((bv.n + 31) / 32)
-       for i := 0; i < n; i++ {
-               w := bv.b[i]
-               h = (h * Hp) ^ (w & 0xff)
-               h = (h * Hp) ^ ((w >> 8) & 0xff)
-               h = (h * Hp) ^ ((w >> 16) & 0xff)
-               h = (h * Hp) ^ ((w >> 24) & 0xff)
-       }
-
-       return h
-}
-
-// bvecSet is a set of bvecs, in initial insertion order.
-type bvecSet struct {
-       index []int  // hash -> uniq index. -1 indicates empty slot.
-       uniq  []bvec // unique bvecs, in insertion order
-}
-
-func (m *bvecSet) grow() {
-       // Allocate new index.
-       n := len(m.index) * 2
-       if n == 0 {
-               n = 32
-       }
-       newIndex := make([]int, n)
-       for i := range newIndex {
-               newIndex[i] = -1
-       }
-
-       // Rehash into newIndex.
-       for i, bv := range m.uniq {
-               h := hashbitmap(H0, bv) % uint32(len(newIndex))
-               for {
-                       j := newIndex[h]
-                       if j < 0 {
-                               newIndex[h] = i
-                               break
-                       }
-                       h++
-                       if h == uint32(len(newIndex)) {
-                               h = 0
-                       }
-               }
-       }
-       m.index = newIndex
-}
-
-// add adds bv to the set and returns its index in m.extractUniqe.
-// The caller must not modify bv after this.
-func (m *bvecSet) add(bv bvec) int {
-       if len(m.uniq)*4 >= len(m.index) {
-               m.grow()
-       }
-
-       index := m.index
-       h := hashbitmap(H0, bv) % uint32(len(index))
-       for {
-               j := index[h]
-               if j < 0 {
-                       // New bvec.
-                       index[h] = len(m.uniq)
-                       m.uniq = append(m.uniq, bv)
-                       return len(m.uniq) - 1
-               }
-               jlive := m.uniq[j]
-               if bv.Eq(jlive) {
-                       // Existing bvec.
-                       return j
-               }
-
-               h++
-               if h == uint32(len(index)) {
-                       h = 0
-               }
-       }
-}
-
-// extractUniqe returns this slice of unique bit vectors in m, as
-// indexed by the result of bvecSet.add.
-func (m *bvecSet) extractUniqe() []bvec {
-       return m.uniq
-}
diff --git a/src/cmd/compile/internal/gc/bvset.go b/src/cmd/compile/internal/gc/bvset.go
new file mode 100644 (file)
index 0000000..7f5f41f
--- /dev/null
@@ -0,0 +1,97 @@
+// Copyright 2013 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 gc
+
+import "cmd/compile/internal/bitvec"
+
+// FNV-1 hash function constants.
+const (
+       h0 = 2166136261
+       hp = 16777619
+)
+
+// bvecSet is a set of bvecs, in initial insertion order.
+type bvecSet struct {
+       index []int           // hash -> uniq index. -1 indicates empty slot.
+       uniq  []bitvec.BitVec // unique bvecs, in insertion order
+}
+
+func (m *bvecSet) grow() {
+       // Allocate new index.
+       n := len(m.index) * 2
+       if n == 0 {
+               n = 32
+       }
+       newIndex := make([]int, n)
+       for i := range newIndex {
+               newIndex[i] = -1
+       }
+
+       // Rehash into newIndex.
+       for i, bv := range m.uniq {
+               h := hashbitmap(h0, bv) % uint32(len(newIndex))
+               for {
+                       j := newIndex[h]
+                       if j < 0 {
+                               newIndex[h] = i
+                               break
+                       }
+                       h++
+                       if h == uint32(len(newIndex)) {
+                               h = 0
+                       }
+               }
+       }
+       m.index = newIndex
+}
+
+// add adds bv to the set and returns its index in m.extractUniqe.
+// The caller must not modify bv after this.
+func (m *bvecSet) add(bv bitvec.BitVec) int {
+       if len(m.uniq)*4 >= len(m.index) {
+               m.grow()
+       }
+
+       index := m.index
+       h := hashbitmap(h0, bv) % uint32(len(index))
+       for {
+               j := index[h]
+               if j < 0 {
+                       // New bvec.
+                       index[h] = len(m.uniq)
+                       m.uniq = append(m.uniq, bv)
+                       return len(m.uniq) - 1
+               }
+               jlive := m.uniq[j]
+               if bv.Eq(jlive) {
+                       // Existing bvec.
+                       return j
+               }
+
+               h++
+               if h == uint32(len(index)) {
+                       h = 0
+               }
+       }
+}
+
+// extractUnique returns this slice of unique bit vectors in m, as
+// indexed by the result of bvecSet.add.
+func (m *bvecSet) extractUnique() []bitvec.BitVec {
+       return m.uniq
+}
+
+func hashbitmap(h uint32, bv bitvec.BitVec) uint32 {
+       n := int((bv.N + 31) / 32)
+       for i := 0; i < n; i++ {
+               w := bv.B[i]
+               h = (h * hp) ^ (w & 0xff)
+               h = (h * hp) ^ ((w >> 8) & 0xff)
+               h = (h * hp) ^ ((w >> 16) & 0xff)
+               h = (h * hp) ^ ((w >> 24) & 0xff)
+       }
+
+       return h
+}
index bcfec3cad32e78f0e3cb4cfa867de696474be0a3..282e718b29bc2ddc098716b65ea378e691576d8e 100644 (file)
@@ -7,6 +7,7 @@ package gc
 import (
        "cmd/compile/internal/base"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/syntax"
        "cmd/compile/internal/typecheck"
        "cmd/compile/internal/types"
@@ -206,19 +207,19 @@ func initEmbed(v *ir.Name) {
                }
                sym := v.Sym().Linksym()
                off := 0
-               off = dsymptr(sym, off, fsym, 0)       // data string
-               off = duintptr(sym, off, uint64(size)) // len
+               off = objw.SymPtr(sym, off, fsym, 0)       // data string
+               off = objw.Uintptr(sym, off, uint64(size)) // len
                if kind == embedBytes {
-                       duintptr(sym, off, uint64(size)) // cap for slice
+                       objw.Uintptr(sym, off, uint64(size)) // cap for slice
                }
 
        case embedFiles:
                slicedata := base.Ctxt.Lookup(`"".` + v.Sym().Name + `.files`)
                off := 0
                // []files pointed at by Files
-               off = dsymptr(slicedata, off, slicedata, 3*types.PtrSize) // []file, pointing just past slice
-               off = duintptr(slicedata, off, uint64(len(files)))
-               off = duintptr(slicedata, off, uint64(len(files)))
+               off = objw.SymPtr(slicedata, off, slicedata, 3*types.PtrSize) // []file, pointing just past slice
+               off = objw.Uintptr(slicedata, off, uint64(len(files)))
+               off = objw.Uintptr(slicedata, off, uint64(len(files)))
 
                // embed/embed.go type file is:
                //      name string
@@ -228,25 +229,25 @@ func initEmbed(v *ir.Name) {
                const hashSize = 16
                hash := make([]byte, hashSize)
                for _, file := range files {
-                       off = dsymptr(slicedata, off, stringsym(v.Pos(), file), 0) // file string
-                       off = duintptr(slicedata, off, uint64(len(file)))
+                       off = objw.SymPtr(slicedata, off, stringsym(v.Pos(), file), 0) // file string
+                       off = objw.Uintptr(slicedata, off, uint64(len(file)))
                        if strings.HasSuffix(file, "/") {
                                // entry for directory - no data
-                               off = duintptr(slicedata, off, 0)
-                               off = duintptr(slicedata, off, 0)
+                               off = objw.Uintptr(slicedata, off, 0)
+                               off = objw.Uintptr(slicedata, off, 0)
                                off += hashSize
                        } else {
                                fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], true, hash)
                                if err != nil {
                                        base.ErrorfAt(v.Pos(), "embed %s: %v", file, err)
                                }
-                               off = dsymptr(slicedata, off, fsym, 0) // data string
-                               off = duintptr(slicedata, off, uint64(size))
+                               off = objw.SymPtr(slicedata, off, fsym, 0) // data string
+                               off = objw.Uintptr(slicedata, off, uint64(size))
                                off = int(slicedata.WriteBytes(base.Ctxt, int64(off), hash))
                        }
                }
-               ggloblsym(slicedata, int32(off), obj.RODATA|obj.LOCAL)
+               objw.Global(slicedata, int32(off), obj.RODATA|obj.LOCAL)
                sym := v.Sym().Linksym()
-               dsymptr(sym, 0, slicedata, 0)
+               objw.SymPtr(sym, 0, slicedata, 0)
        }
 }
index 7648e910d57defe253a48efbee5e2f3509cd9396..c979edcdf83722a6cd1b3b13c7899d58edb3c3da 100644 (file)
@@ -5,6 +5,7 @@
 package gc
 
 import (
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -33,10 +34,10 @@ type Arch struct {
 
        // ZeroRange zeroes a range of memory on stack. It is only inserted
        // at function entry, and it is ok to clobber registers.
-       ZeroRange func(*Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
+       ZeroRange func(*objw.Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
 
-       Ginsnop      func(*Progs) *obj.Prog
-       Ginsnopdefer func(*Progs) *obj.Prog // special ginsnop for deferreturn
+       Ginsnop      func(*objw.Progs) *obj.Prog
+       Ginsnopdefer func(*objw.Progs) *obj.Prog // special ginsnop for deferreturn
 
        // SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
        SSAMarkMoves func(*SSAGenState, *ssa.Block)
index f24687ec0f34cbd6fa0f285696c52c35af2272e7..f746a358caf5b6e31928beed803cdee8c7f133cf 100644 (file)
@@ -33,164 +33,14 @@ package gc
 import (
        "cmd/compile/internal/base"
        "cmd/compile/internal/ir"
-       "cmd/compile/internal/ssa"
        "cmd/compile/internal/typecheck"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/objabi"
-       "cmd/internal/src"
        "fmt"
        "os"
 )
 
-var sharedProgArray = new([10000]obj.Prog) // *T instead of T to work around issue 19839
-
-// Progs accumulates Progs for a function and converts them into machine code.
-type Progs struct {
-       Text      *obj.Prog  // ATEXT Prog for this function
-       next      *obj.Prog  // next Prog
-       pc        int64      // virtual PC; count of Progs
-       pos       src.XPos   // position to use for new Progs
-       curfn     *ir.Func   // fn these Progs are for
-       progcache []obj.Prog // local progcache
-       cacheidx  int        // first free element of progcache
-
-       nextLive LivenessIndex // liveness index for the next Prog
-       prevLive LivenessIndex // last emitted liveness index
-}
-
-// newProgs returns a new Progs for fn.
-// worker indicates which of the backend workers will use the Progs.
-func newProgs(fn *ir.Func, worker int) *Progs {
-       pp := new(Progs)
-       if base.Ctxt.CanReuseProgs() {
-               sz := len(sharedProgArray) / base.Flag.LowerC
-               pp.progcache = sharedProgArray[sz*worker : sz*(worker+1)]
-       }
-       pp.curfn = fn
-
-       // prime the pump
-       pp.next = pp.NewProg()
-       pp.clearp(pp.next)
-
-       pp.pos = fn.Pos()
-       pp.settext(fn)
-       // PCDATA tables implicitly start with index -1.
-       pp.prevLive = LivenessIndex{-1, false}
-       pp.nextLive = pp.prevLive
-       return pp
-}
-
-func (pp *Progs) NewProg() *obj.Prog {
-       var p *obj.Prog
-       if pp.cacheidx < len(pp.progcache) {
-               p = &pp.progcache[pp.cacheidx]
-               pp.cacheidx++
-       } else {
-               p = new(obj.Prog)
-       }
-       p.Ctxt = base.Ctxt
-       return p
-}
-
-// Flush converts from pp to machine code.
-func (pp *Progs) Flush() {
-       plist := &obj.Plist{Firstpc: pp.Text, Curfn: pp.curfn}
-       obj.Flushplist(base.Ctxt, plist, pp.NewProg, base.Ctxt.Pkgpath)
-}
-
-// Free clears pp and any associated resources.
-func (pp *Progs) Free() {
-       if base.Ctxt.CanReuseProgs() {
-               // Clear progs to enable GC and avoid abuse.
-               s := pp.progcache[:pp.cacheidx]
-               for i := range s {
-                       s[i] = obj.Prog{}
-               }
-       }
-       // Clear pp to avoid abuse.
-       *pp = Progs{}
-}
-
-// Prog adds a Prog with instruction As to pp.
-func (pp *Progs) Prog(as obj.As) *obj.Prog {
-       if pp.nextLive.StackMapValid() && pp.nextLive.stackMapIndex != pp.prevLive.stackMapIndex {
-               // Emit stack map index change.
-               idx := pp.nextLive.stackMapIndex
-               pp.prevLive.stackMapIndex = idx
-               p := pp.Prog(obj.APCDATA)
-               Addrconst(&p.From, objabi.PCDATA_StackMapIndex)
-               Addrconst(&p.To, int64(idx))
-       }
-       if pp.nextLive.isUnsafePoint != pp.prevLive.isUnsafePoint {
-               // Emit unsafe-point marker.
-               pp.prevLive.isUnsafePoint = pp.nextLive.isUnsafePoint
-               p := pp.Prog(obj.APCDATA)
-               Addrconst(&p.From, objabi.PCDATA_UnsafePoint)
-               if pp.nextLive.isUnsafePoint {
-                       Addrconst(&p.To, objabi.PCDATA_UnsafePointUnsafe)
-               } else {
-                       Addrconst(&p.To, objabi.PCDATA_UnsafePointSafe)
-               }
-       }
-
-       p := pp.next
-       pp.next = pp.NewProg()
-       pp.clearp(pp.next)
-       p.Link = pp.next
-
-       if !pp.pos.IsKnown() && base.Flag.K != 0 {
-               base.Warn("prog: unknown position (line 0)")
-       }
-
-       p.As = as
-       p.Pos = pp.pos
-       if pp.pos.IsStmt() == src.PosIsStmt {
-               // Clear IsStmt for later Progs at this pos provided that as can be marked as a stmt
-               if ssa.LosesStmtMark(as) {
-                       return p
-               }
-               pp.pos = pp.pos.WithNotStmt()
-       }
-       return p
-}
-
-func (pp *Progs) clearp(p *obj.Prog) {
-       obj.Nopout(p)
-       p.As = obj.AEND
-       p.Pc = pp.pc
-       pp.pc++
-}
-
-func (pp *Progs) Appendpp(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16, foffset int64, ttype obj.AddrType, treg int16, toffset int64) *obj.Prog {
-       q := pp.NewProg()
-       pp.clearp(q)
-       q.As = as
-       q.Pos = p.Pos
-       q.From.Type = ftype
-       q.From.Reg = freg
-       q.From.Offset = foffset
-       q.To.Type = ttype
-       q.To.Reg = treg
-       q.To.Offset = toffset
-       q.Link = p.Link
-       p.Link = q
-       return q
-}
-
-func (pp *Progs) settext(fn *ir.Func) {
-       if pp.Text != nil {
-               base.Fatalf("Progs.settext called twice")
-       }
-       ptxt := pp.Prog(obj.ATEXT)
-       pp.Text = ptxt
-
-       fn.LSym.Func().Text = ptxt
-       ptxt.From.Type = obj.TYPE_MEM
-       ptxt.From.Name = obj.NAME_EXTERN
-       ptxt.From.Sym = fn.LSym
-}
-
 // makeABIWrapper creates a new function that wraps a cross-ABI call
 // to "f".  The wrapper is marked as an ABIWRAPPER.
 func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) {
@@ -426,41 +276,3 @@ func setupTextLSym(f *ir.Func, flag int) {
 
        base.Ctxt.InitTextSym(f.LSym, flag)
 }
-
-func ggloblnod(nam ir.Node) {
-       s := nam.Sym().Linksym()
-       s.Gotype = ngotype(nam).Linksym()
-       flags := 0
-       if nam.Name().Readonly() {
-               flags = obj.RODATA
-       }
-       if nam.Type() != nil && !nam.Type().HasPointers() {
-               flags |= obj.NOPTR
-       }
-       base.Ctxt.Globl(s, nam.Type().Width, flags)
-       if nam.Name().LibfuzzerExtraCounter() {
-               s.Type = objabi.SLIBFUZZER_EXTRA_COUNTER
-       }
-       if nam.Sym().Linkname != "" {
-               // Make sure linkname'd symbol is non-package. When a symbol is
-               // both imported and linkname'd, s.Pkg may not set to "_" in
-               // types.Sym.Linksym because LSym already exists. Set it here.
-               s.Pkg = "_"
-       }
-}
-
-func ggloblsym(s *obj.LSym, width int32, flags int16) {
-       if flags&obj.LOCAL != 0 {
-               s.Set(obj.AttrLocal, true)
-               flags &^= obj.LOCAL
-       }
-       base.Ctxt.Globl(s, int64(width), int(flags))
-}
-
-func Addrconst(a *obj.Addr, v int64) {
-       a.SetConst(v)
-}
-
-func Patch(p *obj.Prog, to *obj.Prog) {
-       p.To.SetTarget(to)
-}
index ed61c11522becbbb73eda86796ca550361c3945c..da3f40f4e889abea0c6b176ab2dcdb337c3a2924 100644 (file)
@@ -7,6 +7,7 @@ package gc
 import (
        "cmd/compile/internal/base"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/typecheck"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -100,17 +101,17 @@ func fninit() *ir.Name {
        sym.Def = task
        lsym := sym.Linksym()
        ot := 0
-       ot = duintptr(lsym, ot, 0) // state: not initialized yet
-       ot = duintptr(lsym, ot, uint64(len(deps)))
-       ot = duintptr(lsym, ot, uint64(len(fns)))
+       ot = objw.Uintptr(lsym, ot, 0) // state: not initialized yet
+       ot = objw.Uintptr(lsym, ot, uint64(len(deps)))
+       ot = objw.Uintptr(lsym, ot, uint64(len(fns)))
        for _, d := range deps {
-               ot = dsymptr(lsym, ot, d, 0)
+               ot = objw.SymPtr(lsym, ot, d, 0)
        }
        for _, f := range fns {
-               ot = dsymptr(lsym, ot, f, 0)
+               ot = objw.SymPtr(lsym, ot, f, 0)
        }
        // An initTask has pointers, but none into the Go heap.
        // It's not quite read only, the state field must be modifiable.
-       ggloblsym(lsym, int32(ot), obj.NOPTR)
+       objw.Global(lsym, int32(ot), obj.NOPTR)
        return task
 }
index 1b4ba50e6bb286ba8d083962749144d0be11658d..1d0a0f7a04cd9c6b63bf7927b47c95c16fb1b25a 100644 (file)
@@ -7,6 +7,7 @@ package gc
 import (
        "cmd/compile/internal/base"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/typecheck"
        "cmd/compile/internal/types"
        "cmd/internal/bio"
@@ -160,7 +161,7 @@ func dumpdata() {
 
        if zerosize > 0 {
                zero := ir.Pkgs.Map.Lookup("zero")
-               ggloblsym(zero.Linksym(), int32(zerosize), obj.DUPOK|obj.RODATA)
+               objw.Global(zero.Linksym(), int32(zerosize), obj.DUPOK|obj.RODATA)
        }
 
        addGCLocals()
@@ -281,8 +282,8 @@ func dumpfuncsyms() {
        })
        for _, s := range funcsyms {
                sf := s.Pkg.Lookup(ir.FuncSymName(s)).Linksym()
-               dsymptr(sf, 0, s.Linksym(), 0)
-               ggloblsym(sf, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
+               objw.SymPtr(sf, 0, s.Linksym(), 0)
+               objw.Global(sf, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
        }
 }
 
@@ -298,53 +299,20 @@ func addGCLocals() {
                }
                for _, gcsym := range []*obj.LSym{fn.GCArgs, fn.GCLocals} {
                        if gcsym != nil && !gcsym.OnList() {
-                               ggloblsym(gcsym, int32(len(gcsym.P)), obj.RODATA|obj.DUPOK)
+                               objw.Global(gcsym, int32(len(gcsym.P)), obj.RODATA|obj.DUPOK)
                        }
                }
                if x := fn.StackObjects; x != nil {
                        attr := int16(obj.RODATA)
-                       ggloblsym(x, int32(len(x.P)), attr)
+                       objw.Global(x, int32(len(x.P)), attr)
                        x.Set(obj.AttrStatic, true)
                }
                if x := fn.OpenCodedDeferInfo; x != nil {
-                       ggloblsym(x, int32(len(x.P)), obj.RODATA|obj.DUPOK)
+                       objw.Global(x, int32(len(x.P)), obj.RODATA|obj.DUPOK)
                }
        }
 }
 
-func duintxx(s *obj.LSym, off int, v uint64, wid int) int {
-       if off&(wid-1) != 0 {
-               base.Fatalf("duintxxLSym: misaligned: v=%d wid=%d off=%d", v, wid, off)
-       }
-       s.WriteInt(base.Ctxt, int64(off), wid, int64(v))
-       return off + wid
-}
-
-func duint8(s *obj.LSym, off int, v uint8) int {
-       return duintxx(s, off, uint64(v), 1)
-}
-
-func duint16(s *obj.LSym, off int, v uint16) int {
-       return duintxx(s, off, uint64(v), 2)
-}
-
-func duint32(s *obj.LSym, off int, v uint32) int {
-       return duintxx(s, off, uint64(v), 4)
-}
-
-func duintptr(s *obj.LSym, off int, v uint64) int {
-       return duintxx(s, off, v, types.PtrSize)
-}
-
-func dbvec(s *obj.LSym, off int, bv bvec) int {
-       // Runtime reads the bitmaps as byte arrays. Oblige.
-       for j := 0; int32(j) < bv.n; j += 8 {
-               word := bv.b[j/32]
-               off = duint8(s, off, uint8(word>>(uint(j)%32)))
-       }
-       return off
-}
-
 const (
        stringSymPrefix  = "go.string."
        stringSymPattern = ".gostring.%d.%x"
@@ -370,7 +338,7 @@ func stringsym(pos src.XPos, s string) (data *obj.LSym) {
        symdata := base.Ctxt.Lookup(stringSymPrefix + symname)
        if !symdata.OnList() {
                off := dstringdata(symdata, 0, s, pos, "string")
-               ggloblsym(symdata, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL)
+               objw.Global(symdata, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL)
                symdata.Set(obj.AttrContentAddressable, true)
        }
 
@@ -450,7 +418,7 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.
                        info := symdata.NewFileInfo()
                        info.Name = file
                        info.Size = size
-                       ggloblsym(symdata, int32(size), obj.DUPOK|obj.RODATA|obj.LOCAL)
+                       objw.Global(symdata, int32(size), obj.DUPOK|obj.RODATA|obj.LOCAL)
                        // Note: AttrContentAddressable cannot be set here,
                        // because the content-addressable-handling code
                        // does not know about file symbols.
@@ -480,7 +448,7 @@ func slicedata(pos src.XPos, s string) *ir.Name {
 
        lsym := sym.Linksym()
        off := dstringdata(lsym, 0, s, pos, "slice")
-       ggloblsym(lsym, int32(off), obj.NOPTR|obj.LOCAL)
+       objw.Global(lsym, int32(off), obj.NOPTR|obj.LOCAL)
 
        return symnode
 }
@@ -505,25 +473,6 @@ func dstringdata(s *obj.LSym, off int, t string, pos src.XPos, what string) int
        return off + len(t)
 }
 
-func dsymptr(s *obj.LSym, off int, x *obj.LSym, xoff int) int {
-       off = int(types.Rnd(int64(off), int64(types.PtrSize)))
-       s.WriteAddr(base.Ctxt, int64(off), types.PtrSize, x, int64(xoff))
-       off += types.PtrSize
-       return off
-}
-
-func dsymptrOff(s *obj.LSym, off int, x *obj.LSym) int {
-       s.WriteOff(base.Ctxt, int64(off), x, 0)
-       off += 4
-       return off
-}
-
-func dsymptrWeakOff(s *obj.LSym, off int, x *obj.LSym) int {
-       s.WriteWeakOff(base.Ctxt, int64(off), x, 0)
-       off += 4
-       return off
-}
-
 // slicesym writes a static slice symbol {&arr, lencap, lencap} to n+noff.
 // slicesym does not modify n.
 func slicesym(n *ir.Name, noff int64, arr *ir.Name, lencap int64) {
@@ -623,3 +572,25 @@ func litsym(n *ir.Name, noff int64, c ir.Node, wid int) {
                base.Fatalf("litsym unhandled OLITERAL %v", c)
        }
 }
+
+func ggloblnod(nam ir.Node) {
+       s := nam.Sym().Linksym()
+       s.Gotype = ngotype(nam).Linksym()
+       flags := 0
+       if nam.Name().Readonly() {
+               flags = obj.RODATA
+       }
+       if nam.Type() != nil && !nam.Type().HasPointers() {
+               flags |= obj.NOPTR
+       }
+       base.Ctxt.Globl(s, nam.Type().Width, flags)
+       if nam.Name().LibfuzzerExtraCounter() {
+               s.Type = objabi.SLIBFUZZER_EXTRA_COUNTER
+       }
+       if nam.Sym().Linkname != "" {
+               // Make sure linkname'd symbol is non-package. When a symbol is
+               // both imported and linkname'd, s.Pkg may not set to "_" in
+               // types.Sym.Linksym because LSym already exists. Set it here.
+               s.Pkg = "_"
+       }
+}
index c0f3326454e6bc2390b38d8c553e26afbeb6f415..40a2195a122ad94e859a74601cb20a9183f67085 100644 (file)
@@ -6,7 +6,9 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/bitvec"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/typecheck"
        "cmd/compile/internal/types"
@@ -34,13 +36,13 @@ func emitptrargsmap(fn *ir.Func) {
        }
        lsym := base.Ctxt.Lookup(fn.LSym.Name + ".args_stackmap")
        nptr := int(fn.Type().ArgWidth() / int64(types.PtrSize))
-       bv := bvalloc(int32(nptr) * 2)
+       bv := bitvec.New(int32(nptr) * 2)
        nbitmap := 1
        if fn.Type().NumResults() > 0 {
                nbitmap = 2
        }
-       off := duint32(lsym, 0, uint32(nbitmap))
-       off = duint32(lsym, off, uint32(bv.n))
+       off := objw.Uint32(lsym, 0, uint32(nbitmap))
+       off = objw.Uint32(lsym, off, uint32(bv.N))
 
        if ir.IsMethod(fn) {
                onebitwalktype1(fn.Type().Recvs(), 0, bv)
@@ -48,14 +50,14 @@ func emitptrargsmap(fn *ir.Func) {
        if fn.Type().NumParams() > 0 {
                onebitwalktype1(fn.Type().Params(), 0, bv)
        }
-       off = dbvec(lsym, off, bv)
+       off = objw.BitVec(lsym, off, bv)
 
        if fn.Type().NumResults() > 0 {
                onebitwalktype1(fn.Type().Results(), 0, bv)
-               off = dbvec(lsym, off, bv)
+               off = objw.BitVec(lsym, off, bv)
        }
 
-       ggloblsym(lsym, int32(off), obj.RODATA|obj.LOCAL)
+       objw.Global(lsym, int32(off), obj.RODATA|obj.LOCAL)
 }
 
 // cmpstackvarlt reports whether the stack variable a sorts before b.
@@ -314,7 +316,7 @@ func compileSSA(fn *ir.Func, worker int) {
                largeStackFramesMu.Unlock()
                return
        }
-       pp := newProgs(fn, worker)
+       pp := objw.NewProgs(fn, worker)
        defer pp.Free()
        genssa(f, pp)
        // Check frame size again.
index ac3b4bcd31c0c670bc3c0a5d643d1236dd93b5ba..260edda9ce7d2ee475a42587bd574792e314b807 100644 (file)
@@ -16,7 +16,9 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/bitvec"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -88,15 +90,15 @@ type BlockEffects struct {
        //
        //      uevar: upward exposed variables (used before set in block)
        //      varkill: killed variables (set in block)
-       uevar   bvec
-       varkill bvec
+       uevar   bitvec.BitVec
+       varkill bitvec.BitVec
 
        // Computed during Liveness.solve using control flow information:
        //
        //      livein: variables live at block entry
        //      liveout: variables live at block exit
-       livein  bvec
-       liveout bvec
+       livein  bitvec.BitVec
+       liveout bitvec.BitVec
 }
 
 // A collection of global state used by liveness analysis.
@@ -114,84 +116,54 @@ type Liveness struct {
        allUnsafe bool
        // unsafePoints bit i is set if Value ID i is an unsafe-point
        // (preemption is not allowed). Only valid if !allUnsafe.
-       unsafePoints bvec
+       unsafePoints bitvec.BitVec
 
        // An array with a bit vector for each safe point in the
        // current Block during Liveness.epilogue. Indexed in Value
        // order for that block. Additionally, for the entry block
        // livevars[0] is the entry bitmap. Liveness.compact moves
        // these to stackMaps.
-       livevars []bvec
+       livevars []bitvec.BitVec
 
        // livenessMap maps from safe points (i.e., CALLs) to their
        // liveness map indexes.
        livenessMap LivenessMap
        stackMapSet bvecSet
-       stackMaps   []bvec
+       stackMaps   []bitvec.BitVec
 
        cache progeffectscache
 }
 
 // LivenessMap maps from *ssa.Value to LivenessIndex.
 type LivenessMap struct {
-       vals map[ssa.ID]LivenessIndex
+       vals map[ssa.ID]objw.LivenessIndex
        // The set of live, pointer-containing variables at the deferreturn
        // call (only set when open-coded defers are used).
-       deferreturn LivenessIndex
+       deferreturn objw.LivenessIndex
 }
 
 func (m *LivenessMap) reset() {
        if m.vals == nil {
-               m.vals = make(map[ssa.ID]LivenessIndex)
+               m.vals = make(map[ssa.ID]objw.LivenessIndex)
        } else {
                for k := range m.vals {
                        delete(m.vals, k)
                }
        }
-       m.deferreturn = LivenessDontCare
+       m.deferreturn = objw.LivenessDontCare
 }
 
-func (m *LivenessMap) set(v *ssa.Value, i LivenessIndex) {
+func (m *LivenessMap) set(v *ssa.Value, i objw.LivenessIndex) {
        m.vals[v.ID] = i
 }
 
-func (m LivenessMap) Get(v *ssa.Value) LivenessIndex {
+func (m LivenessMap) Get(v *ssa.Value) objw.LivenessIndex {
        // If v isn't in the map, then it's a "don't care" and not an
        // unsafe-point.
        if idx, ok := m.vals[v.ID]; ok {
                return idx
        }
-       return LivenessIndex{StackMapDontCare, false}
-}
-
-// LivenessIndex stores the liveness map information for a Value.
-type LivenessIndex struct {
-       stackMapIndex int
-
-       // isUnsafePoint indicates that this is an unsafe-point.
-       //
-       // Note that it's possible for a call Value to have a stack
-       // map while also being an unsafe-point. This means it cannot
-       // be preempted at this instruction, but that a preemption or
-       // stack growth may happen in the called function.
-       isUnsafePoint bool
-}
-
-// LivenessDontCare indicates that the liveness information doesn't
-// matter. Currently it is used in deferreturn liveness when we don't
-// actually need it. It should never be emitted to the PCDATA stream.
-var LivenessDontCare = LivenessIndex{StackMapDontCare, true}
-
-// StackMapDontCare indicates that the stack map index at a Value
-// doesn't matter.
-//
-// This is a sentinel value that should never be emitted to the PCDATA
-// stream. We use -1000 because that's obviously never a valid stack
-// index (but -1 is).
-const StackMapDontCare = -1000
-
-func (idx LivenessIndex) StackMapValid() bool {
-       return idx.stackMapIndex != StackMapDontCare
+       return objw.LivenessIndex{StackMapIndex: objw.StackMapDontCare, IsUnsafePoint: false}
 }
 
 type progeffectscache struct {
@@ -380,7 +352,7 @@ func newliveness(fn *ir.Func, f *ssa.Func, vars []*ir.Name, idx map[*ir.Name]int
                if cap(lc.be) >= f.NumBlocks() {
                        lv.be = lc.be[:f.NumBlocks()]
                }
-               lv.livenessMap = LivenessMap{vals: lc.livenessMap.vals, deferreturn: LivenessDontCare}
+               lv.livenessMap = LivenessMap{vals: lc.livenessMap.vals, deferreturn: objw.LivenessDontCare}
                lc.livenessMap.vals = nil
        }
        if lv.be == nil {
@@ -389,14 +361,14 @@ func newliveness(fn *ir.Func, f *ssa.Func, vars []*ir.Name, idx map[*ir.Name]int
 
        nblocks := int32(len(f.Blocks))
        nvars := int32(len(vars))
-       bulk := bvbulkalloc(nvars, nblocks*7)
+       bulk := bitvec.NewBulk(nvars, nblocks*7)
        for _, b := range f.Blocks {
                be := lv.blockEffects(b)
 
-               be.uevar = bulk.next()
-               be.varkill = bulk.next()
-               be.livein = bulk.next()
-               be.liveout = bulk.next()
+               be.uevar = bulk.Next()
+               be.varkill = bulk.Next()
+               be.livein = bulk.Next()
+               be.liveout = bulk.Next()
        }
        lv.livenessMap.reset()
 
@@ -411,7 +383,7 @@ func (lv *Liveness) blockEffects(b *ssa.Block) *BlockEffects {
 // NOTE: The bitmap for a specific type t could be cached in t after
 // the first run and then simply copied into bv at the correct offset
 // on future calls with the same type t.
-func onebitwalktype1(t *types.Type, off int64, bv bvec) {
+func onebitwalktype1(t *types.Type, off int64, bv bitvec.BitVec) {
        if t.Align > 0 && off&int64(t.Align-1) != 0 {
                base.Fatalf("onebitwalktype1: invalid initial alignment: type %v has alignment %d, but offset is %v", t, t.Align, off)
        }
@@ -487,7 +459,7 @@ func onebitwalktype1(t *types.Type, off int64, bv bvec) {
 // Generates live pointer value maps for arguments and local variables. The
 // this argument and the in arguments are always assumed live. The vars
 // argument is a slice of *Nodes.
-func (lv *Liveness) pointerMap(liveout bvec, vars []*ir.Name, args, locals bvec) {
+func (lv *Liveness) pointerMap(liveout bitvec.BitVec, vars []*ir.Name, args, locals bitvec.BitVec) {
        for i := int32(0); ; i++ {
                i = liveout.Next(i)
                if i < 0 {
@@ -527,7 +499,7 @@ func (lv *Liveness) markUnsafePoints() {
                return
        }
 
-       lv.unsafePoints = bvalloc(int32(lv.f.NumValues()))
+       lv.unsafePoints = bitvec.New(int32(lv.f.NumValues()))
 
        // Mark architecture-specific unsafe points.
        for _, b := range lv.f.Blocks {
@@ -638,11 +610,11 @@ func (lv *Liveness) markUnsafePoints() {
        // nice to only flood as far as the unsafe.Pointer -> uintptr
        // conversion, but it's hard to know which argument of an Add
        // or Sub to follow.
-       var flooded bvec
+       var flooded bitvec.BitVec
        var flood func(b *ssa.Block, vi int)
        flood = func(b *ssa.Block, vi int) {
-               if flooded.n == 0 {
-                       flooded = bvalloc(int32(lv.f.NumBlocks()))
+               if flooded.N == 0 {
+                       flooded = bitvec.New(int32(lv.f.NumBlocks()))
                }
                if flooded.Get(int32(b.ID)) {
                        return
@@ -725,8 +697,8 @@ func (lv *Liveness) solve() {
        // These temporary bitvectors exist to avoid successive allocations and
        // frees within the loop.
        nvars := int32(len(lv.vars))
-       newlivein := bvalloc(nvars)
-       newliveout := bvalloc(nvars)
+       newlivein := bitvec.New(nvars)
+       newliveout := bitvec.New(nvars)
 
        // Walk blocks in postorder ordering. This improves convergence.
        po := lv.f.Postorder()
@@ -783,8 +755,8 @@ func (lv *Liveness) solve() {
 // variables at each safe point locations.
 func (lv *Liveness) epilogue() {
        nvars := int32(len(lv.vars))
-       liveout := bvalloc(nvars)
-       livedefer := bvalloc(nvars) // always-live variables
+       liveout := bitvec.New(nvars)
+       livedefer := bitvec.New(nvars) // always-live variables
 
        // If there is a defer (that could recover), then all output
        // parameters are live all the time.  In addition, any locals
@@ -838,7 +810,7 @@ func (lv *Liveness) epilogue() {
 
        {
                // Reserve an entry for function entry.
-               live := bvalloc(nvars)
+               live := bitvec.New(nvars)
                lv.livevars = append(lv.livevars, live)
        }
 
@@ -852,7 +824,7 @@ func (lv *Liveness) epilogue() {
                                continue
                        }
 
-                       live := bvalloc(nvars)
+                       live := bitvec.New(nvars)
                        lv.livevars = append(lv.livevars, live)
                }
 
@@ -910,16 +882,16 @@ func (lv *Liveness) epilogue() {
 
        // If we have an open-coded deferreturn call, make a liveness map for it.
        if lv.fn.OpenCodedDeferDisallowed() {
-               lv.livenessMap.deferreturn = LivenessDontCare
+               lv.livenessMap.deferreturn = objw.LivenessDontCare
        } else {
-               lv.livenessMap.deferreturn = LivenessIndex{
-                       stackMapIndex: lv.stackMapSet.add(livedefer),
-                       isUnsafePoint: false,
+               lv.livenessMap.deferreturn = objw.LivenessIndex{
+                       StackMapIndex: lv.stackMapSet.add(livedefer),
+                       IsUnsafePoint: false,
                }
        }
 
        // Done compacting. Throw out the stack map set.
-       lv.stackMaps = lv.stackMapSet.extractUniqe()
+       lv.stackMaps = lv.stackMapSet.extractUnique()
        lv.stackMapSet = bvecSet{}
 
        // Useful sanity check: on entry to the function,
@@ -958,9 +930,9 @@ func (lv *Liveness) compact(b *ssa.Block) {
        for _, v := range b.Values {
                hasStackMap := lv.hasStackMap(v)
                isUnsafePoint := lv.allUnsafe || lv.unsafePoints.Get(int32(v.ID))
-               idx := LivenessIndex{StackMapDontCare, isUnsafePoint}
+               idx := objw.LivenessIndex{StackMapIndex: objw.StackMapDontCare, IsUnsafePoint: isUnsafePoint}
                if hasStackMap {
-                       idx.stackMapIndex = lv.stackMapSet.add(lv.livevars[pos])
+                       idx.StackMapIndex = lv.stackMapSet.add(lv.livevars[pos])
                        pos++
                }
                if hasStackMap || isUnsafePoint {
@@ -972,7 +944,7 @@ func (lv *Liveness) compact(b *ssa.Block) {
        lv.livevars = lv.livevars[:0]
 }
 
-func (lv *Liveness) showlive(v *ssa.Value, live bvec) {
+func (lv *Liveness) showlive(v *ssa.Value, live bitvec.BitVec) {
        if base.Flag.Live == 0 || ir.FuncName(lv.fn) == "init" || strings.HasPrefix(ir.FuncName(lv.fn), ".") {
                return
        }
@@ -1012,7 +984,7 @@ func (lv *Liveness) showlive(v *ssa.Value, live bvec) {
        base.WarnfAt(pos, s)
 }
 
-func (lv *Liveness) printbvec(printed bool, name string, live bvec) bool {
+func (lv *Liveness) printbvec(printed bool, name string, live bitvec.BitVec) bool {
        if live.IsEmpty() {
                return printed
        }
@@ -1128,7 +1100,7 @@ func (lv *Liveness) printDebug() {
                                fmt.Printf("\tlive=")
                                printed = false
                                if pcdata.StackMapValid() {
-                                       live := lv.stackMaps[pcdata.stackMapIndex]
+                                       live := lv.stackMaps[pcdata.StackMapIndex]
                                        for j, n := range lv.vars {
                                                if !live.Get(int32(j)) {
                                                        continue
@@ -1143,7 +1115,7 @@ func (lv *Liveness) printDebug() {
                                fmt.Printf("\n")
                        }
 
-                       if pcdata.isUnsafePoint {
+                       if pcdata.IsUnsafePoint {
                                fmt.Printf("\tunsafe-point\n")
                        }
                }
@@ -1196,13 +1168,13 @@ func (lv *Liveness) emit() (argsSym, liveSym *obj.LSym) {
        // Temporary symbols for encoding bitmaps.
        var argsSymTmp, liveSymTmp obj.LSym
 
-       args := bvalloc(int32(maxArgs / int64(types.PtrSize)))
-       aoff := duint32(&argsSymTmp, 0, uint32(len(lv.stackMaps))) // number of bitmaps
-       aoff = duint32(&argsSymTmp, aoff, uint32(args.n))          // number of bits in each bitmap
+       args := bitvec.New(int32(maxArgs / int64(types.PtrSize)))
+       aoff := objw.Uint32(&argsSymTmp, 0, uint32(len(lv.stackMaps))) // number of bitmaps
+       aoff = objw.Uint32(&argsSymTmp, aoff, uint32(args.N))          // number of bits in each bitmap
 
-       locals := bvalloc(int32(maxLocals / int64(types.PtrSize)))
-       loff := duint32(&liveSymTmp, 0, uint32(len(lv.stackMaps))) // number of bitmaps
-       loff = duint32(&liveSymTmp, loff, uint32(locals.n))        // number of bits in each bitmap
+       locals := bitvec.New(int32(maxLocals / int64(types.PtrSize)))
+       loff := objw.Uint32(&liveSymTmp, 0, uint32(len(lv.stackMaps))) // number of bitmaps
+       loff = objw.Uint32(&liveSymTmp, loff, uint32(locals.N))        // number of bits in each bitmap
 
        for _, live := range lv.stackMaps {
                args.Clear()
@@ -1210,8 +1182,8 @@ func (lv *Liveness) emit() (argsSym, liveSym *obj.LSym) {
 
                lv.pointerMap(live, lv.vars, args, locals)
 
-               aoff = dbvec(&argsSymTmp, aoff, args)
-               loff = dbvec(&liveSymTmp, loff, locals)
+               aoff = objw.BitVec(&argsSymTmp, aoff, args)
+               loff = objw.BitVec(&liveSymTmp, loff, locals)
        }
 
        // Give these LSyms content-addressable names,
@@ -1233,7 +1205,7 @@ func (lv *Liveness) emit() (argsSym, liveSym *obj.LSym) {
 // pointer variables in the function and emits a runtime data
 // structure read by the garbage collector.
 // Returns a map from GC safe points to their corresponding stack map index.
-func liveness(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *Progs) LivenessMap {
+func liveness(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *objw.Progs) LivenessMap {
        // Construct the global liveness state.
        vars, idx := getvariables(curfn)
        lv := newliveness(curfn, f, vars, idx, stkptrsize)
@@ -1247,7 +1219,7 @@ func liveness(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *Progs) Liveness
                for _, b := range f.Blocks {
                        for _, val := range b.Values {
                                if idx := lv.livenessMap.Get(val); idx.StackMapValid() {
-                                       lv.showlive(val, lv.stackMaps[idx.stackMapIndex])
+                                       lv.showlive(val, lv.stackMaps[idx.StackMapIndex])
                                }
                        }
                }
@@ -1276,13 +1248,13 @@ func liveness(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *Progs) Liveness
        fninfo.GCArgs, fninfo.GCLocals = lv.emit()
 
        p := pp.Prog(obj.AFUNCDATA)
-       Addrconst(&p.From, objabi.FUNCDATA_ArgsPointerMaps)
+       p.From.SetConst(objabi.FUNCDATA_ArgsPointerMaps)
        p.To.Type = obj.TYPE_MEM
        p.To.Name = obj.NAME_EXTERN
        p.To.Sym = fninfo.GCArgs
 
        p = pp.Prog(obj.AFUNCDATA)
-       Addrconst(&p.From, objabi.FUNCDATA_LocalsPointerMaps)
+       p.From.SetConst(objabi.FUNCDATA_LocalsPointerMaps)
        p.To.Type = obj.TYPE_MEM
        p.To.Name = obj.NAME_EXTERN
        p.To.Sym = fninfo.GCLocals
index 7594884f9f35ef932503648ec9cf18b697d7a84e..dcb2620f1f03d3fb26a7adb6cdc8a3ccf2a8c6a9 100644 (file)
@@ -6,7 +6,9 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/bitvec"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/typecheck"
        "cmd/compile/internal/types"
        "cmd/internal/gcprog"
@@ -472,14 +474,14 @@ func dimportpath(p *types.Pkg) {
 
        s := base.Ctxt.Lookup("type..importpath." + p.Prefix + ".")
        ot := dnameData(s, 0, str, "", nil, false)
-       ggloblsym(s, int32(ot), obj.DUPOK|obj.RODATA)
+       objw.Global(s, int32(ot), obj.DUPOK|obj.RODATA)
        s.Set(obj.AttrContentAddressable, true)
        p.Pathsym = s
 }
 
 func dgopkgpath(s *obj.LSym, ot int, pkg *types.Pkg) int {
        if pkg == nil {
-               return duintptr(s, ot, 0)
+               return objw.Uintptr(s, ot, 0)
        }
 
        if pkg == types.LocalPkg && base.Ctxt.Pkgpath == "" {
@@ -489,17 +491,17 @@ func dgopkgpath(s *obj.LSym, ot int, pkg *types.Pkg) int {
                // Every package that imports this one directly defines the symbol.
                // See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
                ns := base.Ctxt.Lookup(`type..importpath."".`)
-               return dsymptr(s, ot, ns, 0)
+               return objw.SymPtr(s, ot, ns, 0)
        }
 
        dimportpath(pkg)
-       return dsymptr(s, ot, pkg.Pathsym, 0)
+       return objw.SymPtr(s, ot, pkg.Pathsym, 0)
 }
 
 // dgopkgpathOff writes an offset relocation in s at offset ot to the pkg path symbol.
 func dgopkgpathOff(s *obj.LSym, ot int, pkg *types.Pkg) int {
        if pkg == nil {
-               return duint32(s, ot, 0)
+               return objw.Uint32(s, ot, 0)
        }
        if pkg == types.LocalPkg && base.Ctxt.Pkgpath == "" {
                // If we don't know the full import path of the package being compiled
@@ -508,11 +510,11 @@ func dgopkgpathOff(s *obj.LSym, ot int, pkg *types.Pkg) int {
                // Every package that imports this one directly defines the symbol.
                // See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
                ns := base.Ctxt.Lookup(`type..importpath."".`)
-               return dsymptrOff(s, ot, ns)
+               return objw.SymPtrOff(s, ot, ns)
        }
 
        dimportpath(pkg)
-       return dsymptrOff(s, ot, pkg.Pathsym)
+       return objw.SymPtrOff(s, ot, pkg.Pathsym)
 }
 
 // dnameField dumps a reflect.name for a struct field.
@@ -521,7 +523,7 @@ func dnameField(lsym *obj.LSym, ot int, spkg *types.Pkg, ft *types.Field) int {
                base.Fatalf("package mismatch for %v", ft.Sym)
        }
        nsym := dname(ft.Sym.Name, ft.Note, nil, types.IsExported(ft.Sym.Name))
-       return dsymptr(lsym, ot, nsym, 0)
+       return objw.SymPtr(lsym, ot, nsym, 0)
 }
 
 // dnameData writes the contents of a reflect.name into s at offset ot.
@@ -600,7 +602,7 @@ func dname(name, tag string, pkg *types.Pkg, exported bool) *obj.LSym {
                return s
        }
        ot := dnameData(s, 0, name, tag, pkg, exported)
-       ggloblsym(s, int32(ot), obj.DUPOK|obj.RODATA)
+       objw.Global(s, int32(ot), obj.DUPOK|obj.RODATA)
        s.Set(obj.AttrContentAddressable, true)
        return s
 }
@@ -634,10 +636,10 @@ func dextratype(lsym *obj.LSym, ot int, t *types.Type, dataAdd int) int {
                base.Fatalf("methods are too far away on %v: %d", t, dataAdd)
        }
 
-       ot = duint16(lsym, ot, uint16(mcount))
-       ot = duint16(lsym, ot, uint16(xcount))
-       ot = duint32(lsym, ot, uint32(dataAdd))
-       ot = duint32(lsym, ot, 0)
+       ot = objw.Uint16(lsym, ot, uint16(mcount))
+       ot = objw.Uint16(lsym, ot, uint16(xcount))
+       ot = objw.Uint32(lsym, ot, uint32(dataAdd))
+       ot = objw.Uint32(lsym, ot, 0)
        return ot
 }
 
@@ -669,7 +671,7 @@ func dextratypeData(lsym *obj.LSym, ot int, t *types.Type) int {
                }
                nsym := dname(a.name.Name, "", pkg, exported)
 
-               ot = dsymptrOff(lsym, ot, nsym)
+               ot = objw.SymPtrOff(lsym, ot, nsym)
                ot = dmethodptrOff(lsym, ot, dtypesym(a.mtype))
                ot = dmethodptrOff(lsym, ot, a.isym.Linksym())
                ot = dmethodptrOff(lsym, ot, a.tsym.Linksym())
@@ -678,7 +680,7 @@ func dextratypeData(lsym *obj.LSym, ot int, t *types.Type) int {
 }
 
 func dmethodptrOff(s *obj.LSym, ot int, x *obj.LSym) int {
-       duint32(s, ot, 0)
+       objw.Uint32(s, ot, 0)
        r := obj.Addrel(s)
        r.Off = int32(ot)
        r.Siz = 4
@@ -768,9 +770,9 @@ func dcommontype(lsym *obj.LSym, t *types.Type) int {
        //              ptrToThis     typeOff
        //      }
        ot := 0
-       ot = duintptr(lsym, ot, uint64(t.Width))
-       ot = duintptr(lsym, ot, uint64(ptrdata))
-       ot = duint32(lsym, ot, types.TypeHash(t))
+       ot = objw.Uintptr(lsym, ot, uint64(t.Width))
+       ot = objw.Uintptr(lsym, ot, uint64(ptrdata))
+       ot = objw.Uint32(lsym, ot, types.TypeHash(t))
 
        var tflag uint8
        if uncommonSize(t) != 0 {
@@ -802,7 +804,7 @@ func dcommontype(lsym *obj.LSym, t *types.Type) int {
                }
        }
 
-       ot = duint8(lsym, ot, tflag)
+       ot = objw.Uint8(lsym, ot, tflag)
 
        // runtime (and common sense) expects alignment to be a power of two.
        i := int(t.Align)
@@ -813,8 +815,8 @@ func dcommontype(lsym *obj.LSym, t *types.Type) int {
        if i&(i-1) != 0 {
                base.Fatalf("invalid alignment %d for %v", t.Align, t)
        }
-       ot = duint8(lsym, ot, t.Align) // align
-       ot = duint8(lsym, ot, t.Align) // fieldAlign
+       ot = objw.Uint8(lsym, ot, t.Align) // align
+       ot = objw.Uint8(lsym, ot, t.Align) // fieldAlign
 
        i = kinds[t.Kind()]
        if types.IsDirectIface(t) {
@@ -823,23 +825,23 @@ func dcommontype(lsym *obj.LSym, t *types.Type) int {
        if useGCProg {
                i |= objabi.KindGCProg
        }
-       ot = duint8(lsym, ot, uint8(i)) // kind
+       ot = objw.Uint8(lsym, ot, uint8(i)) // kind
        if eqfunc != nil {
-               ot = dsymptr(lsym, ot, eqfunc, 0) // equality function
+               ot = objw.SymPtr(lsym, ot, eqfunc, 0) // equality function
        } else {
-               ot = duintptr(lsym, ot, 0) // type we can't do == with
+               ot = objw.Uintptr(lsym, ot, 0) // type we can't do == with
        }
-       ot = dsymptr(lsym, ot, gcsym, 0) // gcdata
+       ot = objw.SymPtr(lsym, ot, gcsym, 0) // gcdata
 
        nsym := dname(p, "", nil, exported)
-       ot = dsymptrOff(lsym, ot, nsym) // str
+       ot = objw.SymPtrOff(lsym, ot, nsym) // str
        // ptrToThis
        if sptr == nil {
-               ot = duint32(lsym, ot, 0)
+               ot = objw.Uint32(lsym, ot, 0)
        } else if sptrWeak {
-               ot = dsymptrWeakOff(lsym, ot, sptr)
+               ot = objw.SymPtrWeakOff(lsym, ot, sptr)
        } else {
-               ot = dsymptrOff(lsym, ot, sptr)
+               ot = objw.SymPtrOff(lsym, ot, sptr)
        }
 
        return ot
@@ -1029,24 +1031,24 @@ func dtypesym(t *types.Type) *obj.LSym {
                t2 := types.NewSlice(t.Elem())
                s2 := dtypesym(t2)
                ot = dcommontype(lsym, t)
-               ot = dsymptr(lsym, ot, s1, 0)
-               ot = dsymptr(lsym, ot, s2, 0)
-               ot = duintptr(lsym, ot, uint64(t.NumElem()))
+               ot = objw.SymPtr(lsym, ot, s1, 0)
+               ot = objw.SymPtr(lsym, ot, s2, 0)
+               ot = objw.Uintptr(lsym, ot, uint64(t.NumElem()))
                ot = dextratype(lsym, ot, t, 0)
 
        case types.TSLICE:
                // ../../../../runtime/type.go:/sliceType
                s1 := dtypesym(t.Elem())
                ot = dcommontype(lsym, t)
-               ot = dsymptr(lsym, ot, s1, 0)
+               ot = objw.SymPtr(lsym, ot, s1, 0)
                ot = dextratype(lsym, ot, t, 0)
 
        case types.TCHAN:
                // ../../../../runtime/type.go:/chanType
                s1 := dtypesym(t.Elem())
                ot = dcommontype(lsym, t)
-               ot = dsymptr(lsym, ot, s1, 0)
-               ot = duintptr(lsym, ot, uint64(t.ChanDir()))
+               ot = objw.SymPtr(lsym, ot, s1, 0)
+               ot = objw.Uintptr(lsym, ot, uint64(t.ChanDir()))
                ot = dextratype(lsym, ot, t, 0)
 
        case types.TFUNC:
@@ -1068,8 +1070,8 @@ func dtypesym(t *types.Type) *obj.LSym {
                if isddd {
                        outCount |= 1 << 15
                }
-               ot = duint16(lsym, ot, uint16(inCount))
-               ot = duint16(lsym, ot, uint16(outCount))
+               ot = objw.Uint16(lsym, ot, uint16(inCount))
+               ot = objw.Uint16(lsym, ot, uint16(outCount))
                if types.PtrSize == 8 {
                        ot += 4 // align for *rtype
                }
@@ -1079,13 +1081,13 @@ func dtypesym(t *types.Type) *obj.LSym {
 
                // Array of rtype pointers follows funcType.
                for _, t1 := range t.Recvs().Fields().Slice() {
-                       ot = dsymptr(lsym, ot, dtypesym(t1.Type), 0)
+                       ot = objw.SymPtr(lsym, ot, dtypesym(t1.Type), 0)
                }
                for _, t1 := range t.Params().Fields().Slice() {
-                       ot = dsymptr(lsym, ot, dtypesym(t1.Type), 0)
+                       ot = objw.SymPtr(lsym, ot, dtypesym(t1.Type), 0)
                }
                for _, t1 := range t.Results().Fields().Slice() {
-                       ot = dsymptr(lsym, ot, dtypesym(t1.Type), 0)
+                       ot = objw.SymPtr(lsym, ot, dtypesym(t1.Type), 0)
                }
 
        case types.TINTER:
@@ -1104,9 +1106,9 @@ func dtypesym(t *types.Type) *obj.LSym {
                }
                ot = dgopkgpath(lsym, ot, tpkg)
 
-               ot = dsymptr(lsym, ot, lsym, ot+3*types.PtrSize+uncommonSize(t))
-               ot = duintptr(lsym, ot, uint64(n))
-               ot = duintptr(lsym, ot, uint64(n))
+               ot = objw.SymPtr(lsym, ot, lsym, ot+3*types.PtrSize+uncommonSize(t))
+               ot = objw.Uintptr(lsym, ot, uint64(n))
+               ot = objw.Uintptr(lsym, ot, uint64(n))
                dataAdd := imethodSize() * n
                ot = dextratype(lsym, ot, t, dataAdd)
 
@@ -1119,8 +1121,8 @@ func dtypesym(t *types.Type) *obj.LSym {
                        }
                        nsym := dname(a.name.Name, "", pkg, exported)
 
-                       ot = dsymptrOff(lsym, ot, nsym)
-                       ot = dsymptrOff(lsym, ot, dtypesym(a.type_))
+                       ot = objw.SymPtrOff(lsym, ot, nsym)
+                       ot = objw.SymPtrOff(lsym, ot, dtypesym(a.type_))
                }
 
        // ../../../../runtime/type.go:/mapType
@@ -1131,27 +1133,27 @@ func dtypesym(t *types.Type) *obj.LSym {
                hasher := genhash(t.Key())
 
                ot = dcommontype(lsym, t)
-               ot = dsymptr(lsym, ot, s1, 0)
-               ot = dsymptr(lsym, ot, s2, 0)
-               ot = dsymptr(lsym, ot, s3, 0)
-               ot = dsymptr(lsym, ot, hasher, 0)
+               ot = objw.SymPtr(lsym, ot, s1, 0)
+               ot = objw.SymPtr(lsym, ot, s2, 0)
+               ot = objw.SymPtr(lsym, ot, s3, 0)
+               ot = objw.SymPtr(lsym, ot, hasher, 0)
                var flags uint32
                // Note: flags must match maptype accessors in ../../../../runtime/type.go
                // and maptype builder in ../../../../reflect/type.go:MapOf.
                if t.Key().Width > MAXKEYSIZE {
-                       ot = duint8(lsym, ot, uint8(types.PtrSize))
+                       ot = objw.Uint8(lsym, ot, uint8(types.PtrSize))
                        flags |= 1 // indirect key
                } else {
-                       ot = duint8(lsym, ot, uint8(t.Key().Width))
+                       ot = objw.Uint8(lsym, ot, uint8(t.Key().Width))
                }
 
                if t.Elem().Width > MAXELEMSIZE {
-                       ot = duint8(lsym, ot, uint8(types.PtrSize))
+                       ot = objw.Uint8(lsym, ot, uint8(types.PtrSize))
                        flags |= 2 // indirect value
                } else {
-                       ot = duint8(lsym, ot, uint8(t.Elem().Width))
+                       ot = objw.Uint8(lsym, ot, uint8(t.Elem().Width))
                }
-               ot = duint16(lsym, ot, uint16(bmap(t).Width))
+               ot = objw.Uint16(lsym, ot, uint16(bmap(t).Width))
                if types.IsReflexive(t.Key()) {
                        flags |= 4 // reflexive key
                }
@@ -1161,7 +1163,7 @@ func dtypesym(t *types.Type) *obj.LSym {
                if hashMightPanic(t.Key()) {
                        flags |= 16 // hash might panic
                }
-               ot = duint32(lsym, ot, flags)
+               ot = objw.Uint32(lsym, ot, flags)
                ot = dextratype(lsym, ot, t, 0)
 
        case types.TPTR:
@@ -1177,7 +1179,7 @@ func dtypesym(t *types.Type) *obj.LSym {
                s1 := dtypesym(t.Elem())
 
                ot = dcommontype(lsym, t)
-               ot = dsymptr(lsym, ot, s1, 0)
+               ot = objw.SymPtr(lsym, ot, s1, 0)
                ot = dextratype(lsym, ot, t, 0)
 
        // ../../../../runtime/type.go:/structType
@@ -1203,9 +1205,9 @@ func dtypesym(t *types.Type) *obj.LSym {
 
                ot = dcommontype(lsym, t)
                ot = dgopkgpath(lsym, ot, spkg)
-               ot = dsymptr(lsym, ot, lsym, ot+3*types.PtrSize+uncommonSize(t))
-               ot = duintptr(lsym, ot, uint64(len(fields)))
-               ot = duintptr(lsym, ot, uint64(len(fields)))
+               ot = objw.SymPtr(lsym, ot, lsym, ot+3*types.PtrSize+uncommonSize(t))
+               ot = objw.Uintptr(lsym, ot, uint64(len(fields)))
+               ot = objw.Uintptr(lsym, ot, uint64(len(fields)))
 
                dataAdd := len(fields) * structfieldSize()
                ot = dextratype(lsym, ot, t, dataAdd)
@@ -1213,7 +1215,7 @@ func dtypesym(t *types.Type) *obj.LSym {
                for _, f := range fields {
                        // ../../../../runtime/type.go:/structField
                        ot = dnameField(lsym, ot, spkg, f)
-                       ot = dsymptr(lsym, ot, dtypesym(f.Type), 0)
+                       ot = objw.SymPtr(lsym, ot, dtypesym(f.Type), 0)
                        offsetAnon := uint64(f.Offset) << 1
                        if offsetAnon>>1 != uint64(f.Offset) {
                                base.Fatalf("%v: bad field offset for %s", t, f.Sym.Name)
@@ -1221,12 +1223,12 @@ func dtypesym(t *types.Type) *obj.LSym {
                        if f.Embedded != 0 {
                                offsetAnon |= 1
                        }
-                       ot = duintptr(lsym, ot, offsetAnon)
+                       ot = objw.Uintptr(lsym, ot, offsetAnon)
                }
        }
 
        ot = dextratypeData(lsym, ot, t)
-       ggloblsym(lsym, int32(ot), int16(dupok|obj.RODATA))
+       objw.Global(lsym, int32(ot), int16(dupok|obj.RODATA))
 
        // The linker will leave a table of all the typelinks for
        // types in the binary, so the runtime can find them.
@@ -1396,15 +1398,15 @@ func dumptabs() {
                //   _      [4]byte
                //   fun    [1]uintptr // variable sized
                // }
-               o := dsymptr(i.lsym, 0, dtypesym(i.itype), 0)
-               o = dsymptr(i.lsym, o, dtypesym(i.t), 0)
-               o = duint32(i.lsym, o, types.TypeHash(i.t)) // copy of type hash
-               o += 4                                      // skip unused field
+               o := objw.SymPtr(i.lsym, 0, dtypesym(i.itype), 0)
+               o = objw.SymPtr(i.lsym, o, dtypesym(i.t), 0)
+               o = objw.Uint32(i.lsym, o, types.TypeHash(i.t)) // copy of type hash
+               o += 4                                          // skip unused field
                for _, fn := range genfun(i.t, i.itype) {
-                       o = dsymptr(i.lsym, o, fn, 0) // method pointer for each method
+                       o = objw.SymPtr(i.lsym, o, fn, 0) // method pointer for each method
                }
                // Nothing writes static itabs, so they are read only.
-               ggloblsym(i.lsym, int32(o), int16(obj.DUPOK|obj.RODATA))
+               objw.Global(i.lsym, int32(o), int16(obj.DUPOK|obj.RODATA))
                i.lsym.Set(obj.AttrContentAddressable, true)
        }
 
@@ -1421,20 +1423,20 @@ func dumptabs() {
                        // }
                        nsym := dname(p.s.Name, "", nil, true)
                        tsym := dtypesym(p.t)
-                       ot = dsymptrOff(s, ot, nsym)
-                       ot = dsymptrOff(s, ot, tsym)
+                       ot = objw.SymPtrOff(s, ot, nsym)
+                       ot = objw.SymPtrOff(s, ot, tsym)
                        // Plugin exports symbols as interfaces. Mark their types
                        // as UsedInIface.
                        tsym.Set(obj.AttrUsedInIface, true)
                }
-               ggloblsym(s, int32(ot), int16(obj.RODATA))
+               objw.Global(s, int32(ot), int16(obj.RODATA))
 
                ot = 0
                s = base.Ctxt.Lookup("go.plugin.exports")
                for _, p := range ptabs {
-                       ot = dsymptr(s, ot, p.s.Linksym(), 0)
+                       ot = objw.SymPtr(s, ot, p.s.Linksym(), 0)
                }
-               ggloblsym(s, int32(ot), int16(obj.RODATA))
+               objw.Global(s, int32(ot), int16(obj.RODATA))
        }
 }
 
@@ -1569,9 +1571,9 @@ func dgcptrmask(t *types.Type) *obj.LSym {
        if !sym.Uniq() {
                sym.SetUniq(true)
                for i, x := range ptrmask {
-                       duint8(lsym, i, x)
+                       objw.Uint8(lsym, i, x)
                }
-               ggloblsym(lsym, int32(len(ptrmask)), obj.DUPOK|obj.RODATA|obj.LOCAL)
+               objw.Global(lsym, int32(len(ptrmask)), obj.DUPOK|obj.RODATA|obj.LOCAL)
                lsym.Set(obj.AttrContentAddressable, true)
        }
        return lsym
@@ -1588,7 +1590,7 @@ func fillptrmask(t *types.Type, ptrmask []byte) {
                return
        }
 
-       vec := bvalloc(8 * int32(len(ptrmask)))
+       vec := bitvec.New(8 * int32(len(ptrmask)))
        onebitwalktype1(t, 0, vec)
 
        nptr := types.PtrDataSize(t) / int64(types.PtrSize)
@@ -1637,13 +1639,13 @@ func (p *GCProg) init(lsym *obj.LSym) {
 }
 
 func (p *GCProg) writeByte(x byte) {
-       p.symoff = duint8(p.lsym, p.symoff, x)
+       p.symoff = objw.Uint8(p.lsym, p.symoff, x)
 }
 
 func (p *GCProg) end() {
        p.w.End()
-       duint32(p.lsym, 0, uint32(p.symoff-4))
-       ggloblsym(p.lsym, int32(p.symoff), obj.DUPOK|obj.RODATA|obj.LOCAL)
+       objw.Uint32(p.lsym, 0, uint32(p.symoff-4))
+       objw.Global(p.lsym, int32(p.symoff), obj.DUPOK|obj.RODATA|obj.LOCAL)
        if base.Debug.GCProg > 0 {
                fmt.Fprintf(os.Stderr, "compile: end GCProg for %v\n", p.lsym)
        }
index 382e4d43200264febc1e9796dff1abb7ce104e6d..44e199abbf2688c32fad2b9c6f32d8752709ce87 100644 (file)
@@ -18,6 +18,7 @@ import (
        "bytes"
        "cmd/compile/internal/base"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/typecheck"
        "cmd/compile/internal/types"
@@ -228,22 +229,22 @@ func dvarint(x *obj.LSym, off int, v int64) int {
                panic(fmt.Sprintf("dvarint: bad offset for funcdata - %v", v))
        }
        if v < 1<<7 {
-               return duint8(x, off, uint8(v))
+               return objw.Uint8(x, off, uint8(v))
        }
-       off = duint8(x, off, uint8((v&127)|128))
+       off = objw.Uint8(x, off, uint8((v&127)|128))
        if v < 1<<14 {
-               return duint8(x, off, uint8(v>>7))
+               return objw.Uint8(x, off, uint8(v>>7))
        }
-       off = duint8(x, off, uint8(((v>>7)&127)|128))
+       off = objw.Uint8(x, off, uint8(((v>>7)&127)|128))
        if v < 1<<21 {
-               return duint8(x, off, uint8(v>>14))
+               return objw.Uint8(x, off, uint8(v>>14))
        }
-       off = duint8(x, off, uint8(((v>>14)&127)|128))
+       off = objw.Uint8(x, off, uint8(((v>>14)&127)|128))
        if v < 1<<28 {
-               return duint8(x, off, uint8(v>>21))
+               return objw.Uint8(x, off, uint8(v>>21))
        }
-       off = duint8(x, off, uint8(((v>>21)&127)|128))
-       return duint8(x, off, uint8(v>>28))
+       off = objw.Uint8(x, off, uint8(((v>>21)&127)|128))
+       return objw.Uint8(x, off, uint8(v>>28))
 }
 
 // emitOpenDeferInfo emits FUNCDATA information about the defers in a function
@@ -6281,7 +6282,7 @@ func (s *state) addNamedValue(n *ir.Name, v *ssa.Value) {
 }
 
 // Generate a disconnected call to a runtime routine and a return.
-func gencallret(pp *Progs, sym *obj.LSym) *obj.Prog {
+func gencallret(pp *objw.Progs, sym *obj.LSym) *obj.Prog {
        p := pp.Prog(obj.ACALL)
        p.To.Type = obj.TYPE_MEM
        p.To.Name = obj.NAME_EXTERN
@@ -6298,7 +6299,7 @@ type Branch struct {
 
 // SSAGenState contains state needed during Prog generation.
 type SSAGenState struct {
-       pp *Progs
+       pp *objw.Progs
 
        // Branches remembers all the branch instructions we've seen
        // and where they would like to go.
@@ -6344,12 +6345,12 @@ func (s *SSAGenState) Prog(as obj.As) *obj.Prog {
 
 // Pc returns the current Prog.
 func (s *SSAGenState) Pc() *obj.Prog {
-       return s.pp.next
+       return s.pp.Next
 }
 
 // SetPos sets the current source position.
 func (s *SSAGenState) SetPos(pos src.XPos) {
-       s.pp.pos = pos
+       s.pp.Pos = pos
 }
 
 // Br emits a single branch instruction and returns the instruction.
@@ -6385,7 +6386,7 @@ func (s *SSAGenState) DebugFriendlySetPosFrom(v *ssa.Value) {
                        }
                        s.SetPos(p)
                } else {
-                       s.SetPos(s.pp.pos.WithNotStmt())
+                       s.SetPos(s.pp.Pos.WithNotStmt())
                }
        }
 }
@@ -6397,7 +6398,7 @@ func (s byXoffset) Len() int           { return len(s) }
 func (s byXoffset) Less(i, j int) bool { return s[i].FrameOffset() < s[j].FrameOffset() }
 func (s byXoffset) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 
-func emitStackObjects(e *ssafn, pp *Progs) {
+func emitStackObjects(e *ssafn, pp *objw.Progs) {
        var vars []*ir.Name
        for _, n := range e.curfn.Dcl {
                if livenessShouldTrack(n) && n.Addrtaken() {
@@ -6415,21 +6416,21 @@ func emitStackObjects(e *ssafn, pp *Progs) {
        // Format must match runtime/stack.go:stackObjectRecord.
        x := e.curfn.LSym.Func().StackObjects
        off := 0
-       off = duintptr(x, off, uint64(len(vars)))
+       off = objw.Uintptr(x, off, uint64(len(vars)))
        for _, v := range vars {
                // Note: arguments and return values have non-negative Xoffset,
                // in which case the offset is relative to argp.
                // Locals have a negative Xoffset, in which case the offset is relative to varp.
-               off = duintptr(x, off, uint64(v.FrameOffset()))
+               off = objw.Uintptr(x, off, uint64(v.FrameOffset()))
                if !types.TypeSym(v.Type()).Siggen() {
                        e.Fatalf(v.Pos(), "stack object's type symbol not generated for type %s", v.Type())
                }
-               off = dsymptr(x, off, dtypesym(v.Type()), 0)
+               off = objw.SymPtr(x, off, dtypesym(v.Type()), 0)
        }
 
        // Emit a funcdata pointing at the stack object data.
        p := pp.Prog(obj.AFUNCDATA)
-       Addrconst(&p.From, objabi.FUNCDATA_StackObjects)
+       p.From.SetConst(objabi.FUNCDATA_StackObjects)
        p.To.Type = obj.TYPE_MEM
        p.To.Name = obj.NAME_EXTERN
        p.To.Sym = x
@@ -6442,7 +6443,7 @@ func emitStackObjects(e *ssafn, pp *Progs) {
 }
 
 // genssa appends entries to pp for each instruction in f.
-func genssa(f *ssa.Func, pp *Progs) {
+func genssa(f *ssa.Func, pp *objw.Progs) {
        var s SSAGenState
 
        e := f.Frontend().(*ssafn)
@@ -6455,7 +6456,7 @@ func genssa(f *ssa.Func, pp *Progs) {
                // This function uses open-coded defers -- write out the funcdata
                // info that we computed at the end of genssa.
                p := pp.Prog(obj.AFUNCDATA)
-               Addrconst(&p.From, objabi.FUNCDATA_OpenCodedDeferInfo)
+               p.From.SetConst(objabi.FUNCDATA_OpenCodedDeferInfo)
                p.To.Type = obj.TYPE_MEM
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = openDeferInfo
@@ -6471,7 +6472,7 @@ func genssa(f *ssa.Func, pp *Progs) {
                progToValue = make(map[*obj.Prog]*ssa.Value, f.NumValues())
                progToBlock = make(map[*obj.Prog]*ssa.Block, f.NumBlocks())
                f.Logf("genssa %s\n", f.Name)
-               progToBlock[s.pp.next] = f.Blocks[0]
+               progToBlock[s.pp.Next] = f.Blocks[0]
        }
 
        s.ScratchFpMem = e.scratchFpMem
@@ -6509,7 +6510,7 @@ func genssa(f *ssa.Func, pp *Progs) {
 
        // Emit basic blocks
        for i, b := range f.Blocks {
-               s.bstart[b.ID] = s.pp.next
+               s.bstart[b.ID] = s.pp.Next
                s.lineRunStart = nil
 
                // Attach a "default" liveness info. Normally this will be
@@ -6518,12 +6519,12 @@ func genssa(f *ssa.Func, pp *Progs) {
                // instruction. We won't use the actual liveness map on a
                // control instruction. Just mark it something that is
                // preemptible, unless this function is "all unsafe".
-               s.pp.nextLive = LivenessIndex{-1, allUnsafe(f)}
+               s.pp.NextLive = objw.LivenessIndex{StackMapIndex: -1, IsUnsafePoint: allUnsafe(f)}
 
                // Emit values in block
                thearch.SSAMarkMoves(&s, b)
                for _, v := range b.Values {
-                       x := s.pp.next
+                       x := s.pp.Next
                        s.DebugFriendlySetPosFrom(v)
 
                        switch v.Op {
@@ -6561,7 +6562,7 @@ func genssa(f *ssa.Func, pp *Progs) {
                        default:
                                // Attach this safe point to the next
                                // instruction.
-                               s.pp.nextLive = s.livenessMap.Get(v)
+                               s.pp.NextLive = s.livenessMap.Get(v)
 
                                // Special case for first line in function; move it to the start.
                                if firstPos != src.NoXPos {
@@ -6573,17 +6574,17 @@ func genssa(f *ssa.Func, pp *Progs) {
                        }
 
                        if base.Ctxt.Flag_locationlists {
-                               valueToProgAfter[v.ID] = s.pp.next
+                               valueToProgAfter[v.ID] = s.pp.Next
                        }
 
                        if f.PrintOrHtmlSSA {
-                               for ; x != s.pp.next; x = x.Link {
+                               for ; x != s.pp.Next; x = x.Link {
                                        progToValue[x] = v
                                }
                        }
                }
                // If this is an empty infinite loop, stick a hardware NOP in there so that debuggers are less confused.
-               if s.bstart[b.ID] == s.pp.next && len(b.Succs) == 1 && b.Succs[0].Block() == b {
+               if s.bstart[b.ID] == s.pp.Next && len(b.Succs) == 1 && b.Succs[0].Block() == b {
                        p := thearch.Ginsnop(s.pp)
                        p.Pos = p.Pos.WithIsStmt()
                        if b.Pos == src.NoXPos {
@@ -6603,11 +6604,11 @@ func genssa(f *ssa.Func, pp *Progs) {
                        // line numbers for otherwise empty blocks.
                        next = f.Blocks[i+1]
                }
-               x := s.pp.next
+               x := s.pp.Next
                s.SetPos(b.Pos)
                thearch.SSAGenBlock(&s, b, next)
                if f.PrintOrHtmlSSA {
-                       for ; x != s.pp.next; x = x.Link {
+                       for ; x != s.pp.Next; x = x.Link {
                                progToBlock[x] = b
                        }
                }
@@ -6623,7 +6624,7 @@ func genssa(f *ssa.Func, pp *Progs) {
                // When doing open-coded defers, generate a disconnected call to
                // deferreturn and a return. This will be used to during panic
                // recovery to unwind the stack and return back to the runtime.
-               s.pp.nextLive = s.livenessMap.deferreturn
+               s.pp.NextLive = s.livenessMap.deferreturn
                gencallret(pp, ir.Syms.Deferreturn)
        }
 
@@ -6655,7 +6656,7 @@ func genssa(f *ssa.Func, pp *Progs) {
                                // some of the inline marks.
                                // Use this instruction instead.
                                p.Pos = p.Pos.WithIsStmt() // promote position to a statement
-                               pp.curfn.LSym.Func().AddInlMark(p, inlMarks[m])
+                               pp.CurFunc.LSym.Func().AddInlMark(p, inlMarks[m])
                                // Make the inline mark a real nop, so it doesn't generate any code.
                                m.As = obj.ANOP
                                m.Pos = src.NoXPos
@@ -6667,7 +6668,7 @@ func genssa(f *ssa.Func, pp *Progs) {
                // Any unmatched inline marks now need to be added to the inlining tree (and will generate a nop instruction).
                for _, p := range inlMarkList {
                        if p.As != obj.ANOP {
-                               pp.curfn.LSym.Func().AddInlMark(p, inlMarks[p])
+                               pp.CurFunc.LSym.Func().AddInlMark(p, inlMarks[p])
                        }
                }
        }
@@ -7048,7 +7049,7 @@ func (s *SSAGenState) AddrScratch(a *obj.Addr) {
 // Call returns a new CALL instruction for the SSA value v.
 // It uses PrepareCall to prepare the call.
 func (s *SSAGenState) Call(v *ssa.Value) *obj.Prog {
-       pPosIsStmt := s.pp.pos.IsStmt() // The statement-ness fo the call comes from ssaGenState
+       pPosIsStmt := s.pp.Pos.IsStmt() // The statement-ness fo the call comes from ssaGenState
        s.PrepareCall(v)
 
        p := s.Prog(obj.ACALL)
@@ -7106,7 +7107,7 @@ func (s *SSAGenState) PrepareCall(v *ssa.Value) {
                // Record call graph information for nowritebarrierrec
                // analysis.
                if nowritebarrierrecCheck != nil {
-                       nowritebarrierrecCheck.recordCall(s.pp.curfn, call.Fn, v.Pos)
+                       nowritebarrierrecCheck.recordCall(s.pp.CurFunc, call.Fn, v.Pos)
                }
        }
 
index 9cce68821b973dac2d6cf31ab17c28592c473b6f..1a5125207dd0ea3b2fd10f582f1f81ba5e80f813 100644 (file)
@@ -6,21 +6,21 @@ package mips
 
 import (
        "cmd/compile/internal/base"
-       "cmd/compile/internal/gc"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/obj/mips"
 )
 
 // TODO(mips): implement DUFFZERO
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
 
        if cnt == 0 {
                return p
        }
        if cnt < int64(4*types.PtrSize) {
                for i := int64(0); i < cnt; i += int64(types.PtrSize) {
-                       p = pp.Appendpp(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, base.Ctxt.FixedFrameSize()+off+i)
+                       p = pp.Append(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, base.Ctxt.FixedFrameSize()+off+i)
                }
        } else {
                //fmt.Printf("zerorange frame:%v, lo: %v, hi:%v \n", frame ,lo, hi)
@@ -30,22 +30,22 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
                //      MOVW    R0, (Widthptr)r1
                //      ADD     $Widthptr, r1
                //      BNE             r1, r2, loop
-               p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-4, obj.TYPE_REG, mips.REGRT1, 0)
+               p = pp.Append(p, mips.AADD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-4, obj.TYPE_REG, mips.REGRT1, 0)
                p.Reg = mips.REGSP
-               p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
+               p = pp.Append(p, mips.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
                p.Reg = mips.REGRT1
-               p = pp.Appendpp(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(types.PtrSize))
+               p = pp.Append(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(types.PtrSize))
                p1 := p
-               p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, int64(types.PtrSize), obj.TYPE_REG, mips.REGRT1, 0)
-               p = pp.Appendpp(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0)
+               p = pp.Append(p, mips.AADD, obj.TYPE_CONST, 0, int64(types.PtrSize), obj.TYPE_REG, mips.REGRT1, 0)
+               p = pp.Append(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0)
                p.Reg = mips.REGRT2
-               gc.Patch(p, p1)
+               p.To.SetTarget(p1)
        }
 
        return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
        p := pp.Prog(mips.ANOR)
        p.From.Type = obj.TYPE_REG
        p.From.Reg = mips.REG_R0
index 10453c27d5f83b227a86b9d0d2606d52f55836f1..e46d87e17d24ac8faa2a952aaa7044e6c5e3edb3 100644 (file)
@@ -427,7 +427,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p4.From.Reg = v.Args[1].Reg()
                p4.Reg = mips.REG_R1
                p4.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p4, p2)
+               p4.To.SetTarget(p2)
        case ssa.OpMIPSLoweredMove:
                // SUBU $4, R1
                // MOVW 4(R1), Rtmp
@@ -480,7 +480,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p6.From.Reg = v.Args[2].Reg()
                p6.Reg = mips.REG_R1
                p6.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p6, p2)
+               p6.To.SetTarget(p2)
        case ssa.OpMIPSCALLstatic, ssa.OpMIPSCALLclosure, ssa.OpMIPSCALLinter:
                s.Call(v)
        case ssa.OpMIPSLoweredWB:
@@ -577,7 +577,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.From.Type = obj.TYPE_REG
                p3.From.Reg = mips.REGTMP
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
 
                s.Prog(mips.ASYNC)
        case ssa.OpMIPSLoweredAtomicAdd:
@@ -613,7 +613,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.From.Type = obj.TYPE_REG
                p3.From.Reg = mips.REGTMP
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
 
                s.Prog(mips.ASYNC)
 
@@ -657,7 +657,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.From.Type = obj.TYPE_REG
                p3.From.Reg = mips.REGTMP
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
 
                s.Prog(mips.ASYNC)
 
@@ -701,7 +701,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.From.Type = obj.TYPE_REG
                p3.From.Reg = mips.REGTMP
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
 
                s.Prog(mips.ASYNC)
 
@@ -750,12 +750,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p5.From.Type = obj.TYPE_REG
                p5.From.Reg = v.Reg0()
                p5.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p5, p1)
+               p5.To.SetTarget(p1)
 
                s.Prog(mips.ASYNC)
 
                p6 := s.Prog(obj.ANOP)
-               gc.Patch(p2, p6)
+               p2.To.SetTarget(p6)
 
        case ssa.OpMIPSLoweredNilCheck:
                // Issue a load which will fault if arg is nil.
index dc5f95960d1ec3678681cb0fb6927090ad81f8a1..37bb871958bf4e827dc6d829c4f4853951b93351 100644 (file)
@@ -5,25 +5,25 @@
 package mips64
 
 import (
-       "cmd/compile/internal/gc"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/obj/mips"
 )
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
        if cnt == 0 {
                return p
        }
        if cnt < int64(4*types.PtrSize) {
                for i := int64(0); i < cnt; i += int64(types.PtrSize) {
-                       p = pp.Appendpp(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, 8+off+i)
+                       p = pp.Append(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, 8+off+i)
                }
        } else if cnt <= int64(128*types.PtrSize) {
-               p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, mips.REGRT1, 0)
+               p = pp.Append(p, mips.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, mips.REGRT1, 0)
                p.Reg = mips.REGSP
-               p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
+               p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = ir.Syms.Duffzero
                p.To.Offset = 8 * (128 - cnt/int64(types.PtrSize))
@@ -34,22 +34,22 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
                //      MOVV    R0, (Widthptr)r1
                //      ADDV    $Widthptr, r1
                //      BNE             r1, r2, loop
-               p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, mips.REGRT1, 0)
+               p = pp.Append(p, mips.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, mips.REGRT1, 0)
                p.Reg = mips.REGSP
-               p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
+               p = pp.Append(p, mips.AADDV, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
                p.Reg = mips.REGRT1
-               p = pp.Appendpp(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(types.PtrSize))
+               p = pp.Append(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(types.PtrSize))
                p1 := p
-               p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, int64(types.PtrSize), obj.TYPE_REG, mips.REGRT1, 0)
-               p = pp.Appendpp(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0)
+               p = pp.Append(p, mips.AADDV, obj.TYPE_CONST, 0, int64(types.PtrSize), obj.TYPE_REG, mips.REGRT1, 0)
+               p = pp.Append(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0)
                p.Reg = mips.REGRT2
-               gc.Patch(p, p1)
+               p.To.SetTarget(p1)
        }
 
        return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
        p := pp.Prog(mips.ANOR)
        p.From.Type = obj.TYPE_REG
        p.From.Reg = mips.REG_R0
index 0da5eebe8d17acfe73cfdcd9278aeecc56ea494b..096e7048ce25418ee7d8a243ebed397ec4774254 100644 (file)
@@ -428,7 +428,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p4.From.Reg = v.Args[1].Reg()
                p4.Reg = mips.REG_R1
                p4.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p4, p2)
+               p4.To.SetTarget(p2)
        case ssa.OpMIPS64DUFFCOPY:
                p := s.Prog(obj.ADUFFCOPY)
                p.To.Type = obj.TYPE_MEM
@@ -490,7 +490,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p6.From.Reg = v.Args[2].Reg()
                p6.Reg = mips.REG_R1
                p6.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p6, p2)
+               p6.To.SetTarget(p2)
        case ssa.OpMIPS64CALLstatic, ssa.OpMIPS64CALLclosure, ssa.OpMIPS64CALLinter:
                s.Call(v)
        case ssa.OpMIPS64LoweredWB:
@@ -579,7 +579,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.From.Type = obj.TYPE_REG
                p3.From.Reg = mips.REGTMP
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
                s.Prog(mips.ASYNC)
        case ssa.OpMIPS64LoweredAtomicAdd32, ssa.OpMIPS64LoweredAtomicAdd64:
                // SYNC
@@ -616,7 +616,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.From.Type = obj.TYPE_REG
                p3.From.Reg = mips.REGTMP
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
                s.Prog(mips.ASYNC)
                p4 := s.Prog(mips.AADDVU)
                p4.From.Type = obj.TYPE_REG
@@ -659,7 +659,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.From.Type = obj.TYPE_REG
                p3.From.Reg = mips.REGTMP
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
                s.Prog(mips.ASYNC)
                p4 := s.Prog(mips.AADDVU)
                p4.From.Type = obj.TYPE_CONST
@@ -712,9 +712,9 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p5.From.Type = obj.TYPE_REG
                p5.From.Reg = v.Reg0()
                p5.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p5, p1)
+               p5.To.SetTarget(p1)
                p6 := s.Prog(mips.ASYNC)
-               gc.Patch(p2, p6)
+               p2.To.SetTarget(p6)
        case ssa.OpMIPS64LoweredNilCheck:
                // Issue a load which will fault if arg is nil.
                p := s.Prog(mips.AMOVB)
@@ -751,7 +751,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.To.Type = obj.TYPE_REG
                p3.To.Reg = v.Reg()
                p4 := s.Prog(obj.ANOP) // not a machine instruction, for branch to land
-               gc.Patch(p2, p4)
+               p2.To.SetTarget(p4)
        case ssa.OpMIPS64LoweredGetClosurePtr:
                // Closure pointer is R22 (mips.REGCTXT).
                gc.CheckLoweredGetClosurePtr(v)
diff --git a/src/cmd/compile/internal/objw/objw.go b/src/cmd/compile/internal/objw/objw.go
new file mode 100644 (file)
index 0000000..dfbcf51
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright 2009 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 objw
+
+import (
+       "cmd/compile/internal/base"
+       "cmd/compile/internal/bitvec"
+       "cmd/compile/internal/types"
+       "cmd/internal/obj"
+)
+
+func Uint8(s *obj.LSym, off int, v uint8) int {
+       return UintN(s, off, uint64(v), 1)
+}
+
+func Uint16(s *obj.LSym, off int, v uint16) int {
+       return UintN(s, off, uint64(v), 2)
+}
+
+func Uint32(s *obj.LSym, off int, v uint32) int {
+       return UintN(s, off, uint64(v), 4)
+}
+
+func Uintptr(s *obj.LSym, off int, v uint64) int {
+       return UintN(s, off, v, types.PtrSize)
+}
+
+func UintN(s *obj.LSym, off int, v uint64, wid int) int {
+       if off&(wid-1) != 0 {
+               base.Fatalf("duintxxLSym: misaligned: v=%d wid=%d off=%d", v, wid, off)
+       }
+       s.WriteInt(base.Ctxt, int64(off), wid, int64(v))
+       return off + wid
+}
+
+func SymPtr(s *obj.LSym, off int, x *obj.LSym, xoff int) int {
+       off = int(types.Rnd(int64(off), int64(types.PtrSize)))
+       s.WriteAddr(base.Ctxt, int64(off), types.PtrSize, x, int64(xoff))
+       off += types.PtrSize
+       return off
+}
+
+func SymPtrOff(s *obj.LSym, off int, x *obj.LSym) int {
+       s.WriteOff(base.Ctxt, int64(off), x, 0)
+       off += 4
+       return off
+}
+
+func SymPtrWeakOff(s *obj.LSym, off int, x *obj.LSym) int {
+       s.WriteWeakOff(base.Ctxt, int64(off), x, 0)
+       off += 4
+       return off
+}
+
+func Global(s *obj.LSym, width int32, flags int16) {
+       if flags&obj.LOCAL != 0 {
+               s.Set(obj.AttrLocal, true)
+               flags &^= obj.LOCAL
+       }
+       base.Ctxt.Globl(s, int64(width), int(flags))
+}
+
+func BitVec(s *obj.LSym, off int, bv bitvec.BitVec) int {
+       // Runtime reads the bitmaps as byte arrays. Oblige.
+       for j := 0; int32(j) < bv.N; j += 8 {
+               word := bv.B[j/32]
+               off = Uint8(s, off, uint8(word>>(uint(j)%32)))
+       }
+       return off
+}
diff --git a/src/cmd/compile/internal/objw/prog.go b/src/cmd/compile/internal/objw/prog.go
new file mode 100644 (file)
index 0000000..54028e4
--- /dev/null
@@ -0,0 +1,218 @@
+// Derived from Inferno utils/6c/txt.c
+// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6c/txt.c
+//
+//     Copyright Â© 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//     Portions Copyright Â© 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright Â© 1997-1999 Vita Nuova Limited
+//     Portions Copyright Â© 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright Â© 2004,2006 Bruce Ellis
+//     Portions Copyright Â© 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright Â© 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright Â© 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package objw
+
+import (
+       "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
+       "cmd/compile/internal/ssa"
+       "cmd/internal/obj"
+       "cmd/internal/objabi"
+       "cmd/internal/src"
+)
+
+var sharedProgArray = new([10000]obj.Prog) // *T instead of T to work around issue 19839
+
+// NewProgs returns a new Progs for fn.
+// worker indicates which of the backend workers will use the Progs.
+func NewProgs(fn *ir.Func, worker int) *Progs {
+       pp := new(Progs)
+       if base.Ctxt.CanReuseProgs() {
+               sz := len(sharedProgArray) / base.Flag.LowerC
+               pp.Cache = sharedProgArray[sz*worker : sz*(worker+1)]
+       }
+       pp.CurFunc = fn
+
+       // prime the pump
+       pp.Next = pp.NewProg()
+       pp.Clear(pp.Next)
+
+       pp.Pos = fn.Pos()
+       pp.SetText(fn)
+       // PCDATA tables implicitly start with index -1.
+       pp.PrevLive = LivenessIndex{-1, false}
+       pp.NextLive = pp.PrevLive
+       return pp
+}
+
+// Progs accumulates Progs for a function and converts them into machine code.
+type Progs struct {
+       Text       *obj.Prog  // ATEXT Prog for this function
+       Next       *obj.Prog  // next Prog
+       PC         int64      // virtual PC; count of Progs
+       Pos        src.XPos   // position to use for new Progs
+       CurFunc    *ir.Func   // fn these Progs are for
+       Cache      []obj.Prog // local progcache
+       CacheIndex int        // first free element of progcache
+
+       NextLive LivenessIndex // liveness index for the next Prog
+       PrevLive LivenessIndex // last emitted liveness index
+}
+
+// LivenessIndex stores the liveness map information for a Value.
+type LivenessIndex struct {
+       StackMapIndex int
+
+       // IsUnsafePoint indicates that this is an unsafe-point.
+       //
+       // Note that it's possible for a call Value to have a stack
+       // map while also being an unsafe-point. This means it cannot
+       // be preempted at this instruction, but that a preemption or
+       // stack growth may happen in the called function.
+       IsUnsafePoint bool
+}
+
+// StackMapDontCare indicates that the stack map index at a Value
+// doesn't matter.
+//
+// This is a sentinel value that should never be emitted to the PCDATA
+// stream. We use -1000 because that's obviously never a valid stack
+// index (but -1 is).
+const StackMapDontCare = -1000
+
+// LivenessDontCare indicates that the liveness information doesn't
+// matter. Currently it is used in deferreturn liveness when we don't
+// actually need it. It should never be emitted to the PCDATA stream.
+var LivenessDontCare = LivenessIndex{StackMapDontCare, true}
+
+func (idx LivenessIndex) StackMapValid() bool {
+       return idx.StackMapIndex != StackMapDontCare
+}
+
+func (pp *Progs) NewProg() *obj.Prog {
+       var p *obj.Prog
+       if pp.CacheIndex < len(pp.Cache) {
+               p = &pp.Cache[pp.CacheIndex]
+               pp.CacheIndex++
+       } else {
+               p = new(obj.Prog)
+       }
+       p.Ctxt = base.Ctxt
+       return p
+}
+
+// Flush converts from pp to machine code.
+func (pp *Progs) Flush() {
+       plist := &obj.Plist{Firstpc: pp.Text, Curfn: pp.CurFunc}
+       obj.Flushplist(base.Ctxt, plist, pp.NewProg, base.Ctxt.Pkgpath)
+}
+
+// Free clears pp and any associated resources.
+func (pp *Progs) Free() {
+       if base.Ctxt.CanReuseProgs() {
+               // Clear progs to enable GC and avoid abuse.
+               s := pp.Cache[:pp.CacheIndex]
+               for i := range s {
+                       s[i] = obj.Prog{}
+               }
+       }
+       // Clear pp to avoid abuse.
+       *pp = Progs{}
+}
+
+// Prog adds a Prog with instruction As to pp.
+func (pp *Progs) Prog(as obj.As) *obj.Prog {
+       if pp.NextLive.StackMapValid() && pp.NextLive.StackMapIndex != pp.PrevLive.StackMapIndex {
+               // Emit stack map index change.
+               idx := pp.NextLive.StackMapIndex
+               pp.PrevLive.StackMapIndex = idx
+               p := pp.Prog(obj.APCDATA)
+               p.From.SetConst(objabi.PCDATA_StackMapIndex)
+               p.To.SetConst(int64(idx))
+       }
+       if pp.NextLive.IsUnsafePoint != pp.PrevLive.IsUnsafePoint {
+               // Emit unsafe-point marker.
+               pp.PrevLive.IsUnsafePoint = pp.NextLive.IsUnsafePoint
+               p := pp.Prog(obj.APCDATA)
+               p.From.SetConst(objabi.PCDATA_UnsafePoint)
+               if pp.NextLive.IsUnsafePoint {
+                       p.To.SetConst(objabi.PCDATA_UnsafePointUnsafe)
+               } else {
+                       p.To.SetConst(objabi.PCDATA_UnsafePointSafe)
+               }
+       }
+
+       p := pp.Next
+       pp.Next = pp.NewProg()
+       pp.Clear(pp.Next)
+       p.Link = pp.Next
+
+       if !pp.Pos.IsKnown() && base.Flag.K != 0 {
+               base.Warn("prog: unknown position (line 0)")
+       }
+
+       p.As = as
+       p.Pos = pp.Pos
+       if pp.Pos.IsStmt() == src.PosIsStmt {
+               // Clear IsStmt for later Progs at this pos provided that as can be marked as a stmt
+               if ssa.LosesStmtMark(as) {
+                       return p
+               }
+               pp.Pos = pp.Pos.WithNotStmt()
+       }
+       return p
+}
+
+func (pp *Progs) Clear(p *obj.Prog) {
+       obj.Nopout(p)
+       p.As = obj.AEND
+       p.Pc = pp.PC
+       pp.PC++
+}
+
+func (pp *Progs) Append(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16, foffset int64, ttype obj.AddrType, treg int16, toffset int64) *obj.Prog {
+       q := pp.NewProg()
+       pp.Clear(q)
+       q.As = as
+       q.Pos = p.Pos
+       q.From.Type = ftype
+       q.From.Reg = freg
+       q.From.Offset = foffset
+       q.To.Type = ttype
+       q.To.Reg = treg
+       q.To.Offset = toffset
+       q.Link = p.Link
+       p.Link = q
+       return q
+}
+
+func (pp *Progs) SetText(fn *ir.Func) {
+       if pp.Text != nil {
+               base.Fatalf("Progs.settext called twice")
+       }
+       ptxt := pp.Prog(obj.ATEXT)
+       pp.Text = ptxt
+
+       fn.LSym.Func().Text = ptxt
+       ptxt.From.Type = obj.TYPE_MEM
+       ptxt.From.Name = obj.NAME_EXTERN
+       ptxt.From.Sym = fn.LSym
+}
index 9e5723186329d9189af2ad5f12957a9f06a0f961..c76962cfb811334d577ffc49b427533f0a8517b8 100644 (file)
@@ -6,46 +6,46 @@ package ppc64
 
 import (
        "cmd/compile/internal/base"
-       "cmd/compile/internal/gc"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/obj/ppc64"
 )
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
        if cnt == 0 {
                return p
        }
        if cnt < int64(4*types.PtrSize) {
                for i := int64(0); i < cnt; i += int64(types.PtrSize) {
-                       p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, base.Ctxt.FixedFrameSize()+off+i)
+                       p = pp.Append(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, base.Ctxt.FixedFrameSize()+off+i)
                }
        } else if cnt <= int64(128*types.PtrSize) {
-               p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGRT1, 0)
+               p = pp.Append(p, ppc64.AADD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGRT1, 0)
                p.Reg = ppc64.REGSP
-               p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
+               p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = ir.Syms.Duffzero
                p.To.Offset = 4 * (128 - cnt/int64(types.PtrSize))
        } else {
-               p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGTMP, 0)
-               p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0)
+               p = pp.Append(p, ppc64.AMOVD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGTMP, 0)
+               p = pp.Append(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0)
                p.Reg = ppc64.REGSP
-               p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0)
-               p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
+               p = pp.Append(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0)
+               p = pp.Append(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
                p.Reg = ppc64.REGRT1
-               p = pp.Appendpp(p, ppc64.AMOVDU, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGRT1, int64(types.PtrSize))
+               p = pp.Append(p, ppc64.AMOVDU, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGRT1, int64(types.PtrSize))
                p1 := p
-               p = pp.Appendpp(p, ppc64.ACMP, obj.TYPE_REG, ppc64.REGRT1, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
-               p = pp.Appendpp(p, ppc64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
-               gc.Patch(p, p1)
+               p = pp.Append(p, ppc64.ACMP, obj.TYPE_REG, ppc64.REGRT1, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
+               p = pp.Append(p, ppc64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
+               p.To.SetTarget(p1)
        }
 
        return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
        p := pp.Prog(ppc64.AOR)
        p.From.Type = obj.TYPE_REG
        p.From.Reg = ppc64.REG_R0
@@ -54,7 +54,7 @@ func ginsnop(pp *gc.Progs) *obj.Prog {
        return p
 }
 
-func ginsnopdefer(pp *gc.Progs) *obj.Prog {
+func ginsnopdefer(pp *objw.Progs) *obj.Prog {
        // On PPC64 two nops are required in the defer case.
        //
        // (see gc/cgen.go, gc/plive.go -- copy of comment below)
index 32e9be84175235492852678d33d4f15cf95afe42..edcaad03ecc832521aec68ae7e779f9dd7e0fd98 100644 (file)
@@ -210,7 +210,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                // BNE retry
                p3 := s.Prog(ppc64.ABNE)
                p3.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
 
        case ssa.OpPPC64LoweredAtomicAdd32,
                ssa.OpPPC64LoweredAtomicAdd64:
@@ -254,7 +254,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                // BNE retry
                p4 := s.Prog(ppc64.ABNE)
                p4.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p4, p)
+               p4.To.SetTarget(p)
 
                // Ensure a 32 bit result
                if v.Op == ssa.OpPPC64LoweredAtomicAdd32 {
@@ -300,7 +300,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                // BNE retry
                p2 := s.Prog(ppc64.ABNE)
                p2.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p2, p)
+               p2.To.SetTarget(p)
                // ISYNC
                pisync := s.Prog(ppc64.AISYNC)
                pisync.To.Type = obj.TYPE_NONE
@@ -348,7 +348,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                // ISYNC
                pisync := s.Prog(ppc64.AISYNC)
                pisync.To.Type = obj.TYPE_NONE
-               gc.Patch(p2, pisync)
+               p2.To.SetTarget(pisync)
 
        case ssa.OpPPC64LoweredAtomicStore8,
                ssa.OpPPC64LoweredAtomicStore32,
@@ -439,7 +439,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                // BNE retry
                p4 := s.Prog(ppc64.ABNE)
                p4.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p4, p)
+               p4.To.SetTarget(p)
                // LWSYNC - Assuming shared data not write-through-required nor
                // caching-inhibited. See Appendix B.2.1.1 in the ISA 2.07b.
                // If the operation is a CAS-Release, then synchronization is not necessary.
@@ -462,10 +462,10 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p7.From.Offset = 0
                p7.To.Type = obj.TYPE_REG
                p7.To.Reg = out
-               gc.Patch(p2, p7)
+               p2.To.SetTarget(p7)
                // done (label)
                p8 := s.Prog(obj.ANOP)
-               gc.Patch(p6, p8)
+               p6.To.SetTarget(p8)
 
        case ssa.OpPPC64LoweredGetClosurePtr:
                // Closure pointer is R11 (already)
@@ -539,10 +539,10 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Reg = r
                p.From.Type = obj.TYPE_REG
                p.From.Reg = r0
-               gc.Patch(pbahead, p)
+               pbahead.To.SetTarget(p)
 
                p = s.Prog(obj.ANOP)
-               gc.Patch(pbover, p)
+               pbover.To.SetTarget(p)
 
        case ssa.OpPPC64DIVW:
                // word-width version of above
@@ -574,10 +574,10 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Reg = r
                p.From.Type = obj.TYPE_REG
                p.From.Reg = r0
-               gc.Patch(pbahead, p)
+               pbahead.To.SetTarget(p)
 
                p = s.Prog(obj.ANOP)
-               gc.Patch(pbover, p)
+               pbover.To.SetTarget(p)
 
        case ssa.OpPPC64CLRLSLWI:
                r := v.Reg()
@@ -1028,7 +1028,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                        p.From.Offset = ppc64.BO_BCTR
                        p.Reg = ppc64.REG_R0
                        p.To.Type = obj.TYPE_BRANCH
-                       gc.Patch(p, top)
+                       p.To.SetTarget(top)
                }
                // When ctr == 1 the loop was not generated but
                // there are at least 64 bytes to clear, so add
@@ -1228,7 +1228,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                        p.From.Offset = ppc64.BO_BCTR
                        p.Reg = ppc64.REG_R0
                        p.To.Type = obj.TYPE_BRANCH
-                       gc.Patch(p, top)
+                       p.To.SetTarget(top)
                }
 
                // when ctr == 1 the loop was not generated but
@@ -1407,7 +1407,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                        p.From.Offset = ppc64.BO_BCTR
                        p.Reg = ppc64.REG_R0
                        p.To.Type = obj.TYPE_BRANCH
-                       gc.Patch(p, top)
+                       p.To.SetTarget(top)
 
                        // srcReg and dstReg were incremented in the loop, so
                        // later instructions start with offset 0.
@@ -1654,7 +1654,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                        p.From.Offset = ppc64.BO_BCTR
                        p.Reg = ppc64.REG_R0
                        p.To.Type = obj.TYPE_BRANCH
-                       gc.Patch(p, top)
+                       p.To.SetTarget(top)
 
                        // srcReg and dstReg were incremented in the loop, so
                        // later instructions start with offset 0.
@@ -1840,7 +1840,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
 
                        // NOP (so the BNE has somewhere to land)
                        nop := s.Prog(obj.ANOP)
-                       gc.Patch(p2, nop)
+                       p2.To.SetTarget(nop)
 
                } else {
                        // Issue a load which will fault if arg is nil.
index d18644bb1b2dd40db23a926f099f380521ace162..9df739456b9e5a50ec503fd3ccdc39d8ccec93e6 100644 (file)
@@ -6,14 +6,14 @@ package riscv64
 
 import (
        "cmd/compile/internal/base"
-       "cmd/compile/internal/gc"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/obj/riscv"
 )
 
-func zeroRange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zeroRange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
        if cnt == 0 {
                return p
        }
@@ -23,15 +23,15 @@ func zeroRange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
 
        if cnt < int64(4*types.PtrSize) {
                for i := int64(0); i < cnt; i += int64(types.PtrSize) {
-                       p = pp.Appendpp(p, riscv.AMOV, obj.TYPE_REG, riscv.REG_ZERO, 0, obj.TYPE_MEM, riscv.REG_SP, off+i)
+                       p = pp.Append(p, riscv.AMOV, obj.TYPE_REG, riscv.REG_ZERO, 0, obj.TYPE_MEM, riscv.REG_SP, off+i)
                }
                return p
        }
 
        if cnt <= int64(128*types.PtrSize) {
-               p = pp.Appendpp(p, riscv.AADDI, obj.TYPE_CONST, 0, off, obj.TYPE_REG, riscv.REG_A0, 0)
+               p = pp.Append(p, riscv.AADDI, obj.TYPE_CONST, 0, off, obj.TYPE_REG, riscv.REG_A0, 0)
                p.Reg = riscv.REG_SP
-               p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
+               p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = ir.Syms.Duffzero
                p.To.Offset = 8 * (128 - cnt/int64(types.PtrSize))
@@ -45,15 +45,15 @@ func zeroRange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
        //      MOV     ZERO, (T0)
        //      ADD     $Widthptr, T0
        //      BNE     T0, T1, loop
-       p = pp.Appendpp(p, riscv.AADD, obj.TYPE_CONST, 0, off, obj.TYPE_REG, riscv.REG_T0, 0)
+       p = pp.Append(p, riscv.AADD, obj.TYPE_CONST, 0, off, obj.TYPE_REG, riscv.REG_T0, 0)
        p.Reg = riscv.REG_SP
-       p = pp.Appendpp(p, riscv.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, riscv.REG_T1, 0)
+       p = pp.Append(p, riscv.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, riscv.REG_T1, 0)
        p.Reg = riscv.REG_T0
-       p = pp.Appendpp(p, riscv.AMOV, obj.TYPE_REG, riscv.REG_ZERO, 0, obj.TYPE_MEM, riscv.REG_T0, 0)
+       p = pp.Append(p, riscv.AMOV, obj.TYPE_REG, riscv.REG_ZERO, 0, obj.TYPE_MEM, riscv.REG_T0, 0)
        loop := p
-       p = pp.Appendpp(p, riscv.AADD, obj.TYPE_CONST, 0, int64(types.PtrSize), obj.TYPE_REG, riscv.REG_T0, 0)
-       p = pp.Appendpp(p, riscv.ABNE, obj.TYPE_REG, riscv.REG_T0, 0, obj.TYPE_BRANCH, 0, 0)
+       p = pp.Append(p, riscv.AADD, obj.TYPE_CONST, 0, int64(types.PtrSize), obj.TYPE_REG, riscv.REG_T0, 0)
+       p = pp.Append(p, riscv.ABNE, obj.TYPE_REG, riscv.REG_T0, 0, obj.TYPE_BRANCH, 0, 0)
        p.Reg = riscv.REG_T1
-       gc.Patch(p, loop)
+       p.To.SetTarget(loop)
        return p
 }
index d40bdf7a1d3627487e6a30e9d98b57a8a51989e4..74bccf8d42ab1b00cad26b7c06e79b8824bf294e 100644 (file)
@@ -5,12 +5,12 @@
 package riscv64
 
 import (
-       "cmd/compile/internal/gc"
+       "cmd/compile/internal/objw"
        "cmd/internal/obj"
        "cmd/internal/obj/riscv"
 )
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
        // Hardware nop is ADD $0, ZERO
        p := pp.Prog(riscv.AADD)
        p.From.Type = obj.TYPE_CONST
index 616b76e5f617464921ed9f5d6263b92e8955ca3b..d08cebdcf5b7654e511ffc3559456331c7da2178 100644 (file)
@@ -502,7 +502,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p4.From.Reg = riscv.REG_TMP
                p4.Reg = riscv.REG_ZERO
                p4.To.Type = obj.TYPE_BRANCH
-               gc.Patch(p4, p1)
+               p4.To.SetTarget(p1)
 
                p5 := s.Prog(riscv.AMOV)
                p5.From.Type = obj.TYPE_CONST
@@ -511,7 +511,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p5.To.Reg = out
 
                p6 := s.Prog(obj.ANOP)
-               gc.Patch(p2, p6)
+               p2.To.SetTarget(p6)
 
        case ssa.OpRISCV64LoweredZero:
                mov, sz := largestMove(v.AuxInt)
@@ -537,7 +537,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p3.Reg = v.Args[0].Reg()
                p3.From.Type = obj.TYPE_REG
                p3.From.Reg = v.Args[1].Reg()
-               gc.Patch(p3, p)
+               p3.To.SetTarget(p)
 
        case ssa.OpRISCV64LoweredMove:
                mov, sz := largestMove(v.AuxInt)
@@ -577,7 +577,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p5.Reg = v.Args[1].Reg()
                p5.From.Type = obj.TYPE_REG
                p5.From.Reg = v.Args[2].Reg()
-               gc.Patch(p5, p)
+               p5.To.SetTarget(p)
 
        case ssa.OpRISCV64LoweredNilCheck:
                // Issue a load which will fault if arg is nil.
index 0e2f48bf4cc3ea5ffbbae3c1604179889d24d199..488a080c468886db6d769269ff5387c93dc33447 100644 (file)
@@ -6,7 +6,7 @@ package s390x
 
 import (
        "cmd/compile/internal/base"
-       "cmd/compile/internal/gc"
+       "cmd/compile/internal/objw"
        "cmd/internal/obj"
        "cmd/internal/obj/s390x"
 )
@@ -18,7 +18,7 @@ import (
 const clearLoopCutoff = 1024
 
 // zerorange clears the stack in the given range.
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
        if cnt == 0 {
                return p
        }
@@ -31,7 +31,7 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
        // need to create a copy of the stack pointer that we can adjust.
        // We also need to do this if we are going to loop.
        if off < 0 || off > 4096-clearLoopCutoff || cnt > clearLoopCutoff {
-               p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, off, obj.TYPE_REG, s390x.REGRT1, 0)
+               p = pp.Append(p, s390x.AADD, obj.TYPE_CONST, 0, off, obj.TYPE_REG, s390x.REGRT1, 0)
                p.Reg = int16(s390x.REGSP)
                reg = s390x.REGRT1
                off = 0
@@ -40,12 +40,12 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
        // Generate a loop of large clears.
        if cnt > clearLoopCutoff {
                ireg := int16(s390x.REGRT2) // register holds number of remaining loop iterations
-               p = pp.Appendpp(p, s390x.AMOVD, obj.TYPE_CONST, 0, cnt/256, obj.TYPE_REG, ireg, 0)
-               p = pp.Appendpp(p, s390x.ACLEAR, obj.TYPE_CONST, 0, 256, obj.TYPE_MEM, reg, off)
+               p = pp.Append(p, s390x.AMOVD, obj.TYPE_CONST, 0, cnt/256, obj.TYPE_REG, ireg, 0)
+               p = pp.Append(p, s390x.ACLEAR, obj.TYPE_CONST, 0, 256, obj.TYPE_MEM, reg, off)
                pl := p
-               p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, 256, obj.TYPE_REG, reg, 0)
-               p = pp.Appendpp(p, s390x.ABRCTG, obj.TYPE_REG, ireg, 0, obj.TYPE_BRANCH, 0, 0)
-               gc.Patch(p, pl)
+               p = pp.Append(p, s390x.AADD, obj.TYPE_CONST, 0, 256, obj.TYPE_REG, reg, 0)
+               p = pp.Append(p, s390x.ABRCTG, obj.TYPE_REG, ireg, 0, obj.TYPE_BRANCH, 0, 0)
+               p.To.SetTarget(pl)
                cnt = cnt % 256
        }
 
@@ -70,11 +70,11 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
                        case 2:
                                ins = s390x.AMOVH
                        }
-                       p = pp.Appendpp(p, ins, obj.TYPE_CONST, 0, 0, obj.TYPE_MEM, reg, off)
+                       p = pp.Append(p, ins, obj.TYPE_CONST, 0, 0, obj.TYPE_MEM, reg, off)
 
                // Handle clears that would require multiple move instructions with CLEAR (assembled as XC).
                default:
-                       p = pp.Appendpp(p, s390x.ACLEAR, obj.TYPE_CONST, 0, n, obj.TYPE_MEM, reg, off)
+                       p = pp.Append(p, s390x.ACLEAR, obj.TYPE_CONST, 0, n, obj.TYPE_MEM, reg, off)
                }
 
                cnt -= n
@@ -84,6 +84,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
        return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
        return pp.Prog(s390x.ANOPH)
 }
index 366adffd986f6189668b10a19012b1bfaa2ead36..dc01401348be9fbec396a522ec3ba5d71518159a 100644 (file)
@@ -709,7 +709,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
 
                bne := s.Prog(s390x.ABLT)
                bne.To.Type = obj.TYPE_BRANCH
-               gc.Patch(bne, mvc)
+               bne.To.SetTarget(mvc)
 
                if v.AuxInt > 0 {
                        mvc := s.Prog(s390x.AMVC)
@@ -751,7 +751,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
 
                bne := s.Prog(s390x.ABLT)
                bne.To.Type = obj.TYPE_BRANCH
-               gc.Patch(bne, clear)
+               bne.To.SetTarget(clear)
 
                if v.AuxInt > 0 {
                        clear := s.Prog(s390x.ACLEAR)
@@ -846,7 +846,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
 
                // NOP (so the BNE has somewhere to land)
                nop := s.Prog(obj.ANOP)
-               gc.Patch(bne, nop)
+               bne.To.SetTarget(nop)
        case ssa.OpS390XLoweredAtomicExchange32, ssa.OpS390XLoweredAtomicExchange64:
                // Loop until the CS{,G} succeeds.
                //     MOV{WZ,D} arg0, ret
@@ -873,7 +873,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                // BNE cs
                bne := s.Prog(s390x.ABNE)
                bne.To.Type = obj.TYPE_BRANCH
-               gc.Patch(bne, cs)
+               bne.To.SetTarget(cs)
        case ssa.OpS390XSYNC:
                s.Prog(s390x.ASYNC)
        case ssa.OpClobber:
index 4e5aa433d970f152b9104d64502d76eb2d076e9e..ee86fc62d27a5e2d8f5b045d14b6edc844d11ff2 100644 (file)
@@ -9,6 +9,7 @@ import (
        "cmd/compile/internal/gc"
        "cmd/compile/internal/ir"
        "cmd/compile/internal/logopt"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -30,7 +31,7 @@ func Init(arch *gc.Arch) {
        arch.SSAGenBlock = ssaGenBlock
 }
 
-func zeroRange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Prog {
+func zeroRange(pp *objw.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Prog {
        if cnt == 0 {
                return p
        }
@@ -39,15 +40,15 @@ func zeroRange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Pr
        }
 
        for i := int64(0); i < cnt; i += 8 {
-               p = pp.Appendpp(p, wasm.AGet, obj.TYPE_REG, wasm.REG_SP, 0, 0, 0, 0)
-               p = pp.Appendpp(p, wasm.AI64Const, obj.TYPE_CONST, 0, 0, 0, 0, 0)
-               p = pp.Appendpp(p, wasm.AI64Store, 0, 0, 0, obj.TYPE_CONST, 0, off+i)
+               p = pp.Append(p, wasm.AGet, obj.TYPE_REG, wasm.REG_SP, 0, 0, 0, 0)
+               p = pp.Append(p, wasm.AI64Const, obj.TYPE_CONST, 0, 0, 0, 0, 0)
+               p = pp.Append(p, wasm.AI64Store, 0, 0, 0, obj.TYPE_CONST, 0, off+i)
        }
 
        return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
        return pp.Prog(wasm.ANop)
 }
 
index de43594e88d3abfa4e8aa0fbd9af465e1d2e773f..3ca479763e63a21fb4ca852d1ac211cd41a34c67 100644 (file)
@@ -5,41 +5,41 @@
 package x86
 
 import (
-       "cmd/compile/internal/gc"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/obj/x86"
 )
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, ax *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, ax *uint32) *obj.Prog {
        if cnt == 0 {
                return p
        }
        if *ax == 0 {
-               p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
+               p = pp.Append(p, x86.AMOVL, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
                *ax = 1
        }
 
        if cnt <= int64(4*types.RegSize) {
                for i := int64(0); i < cnt; i += int64(types.RegSize) {
-                       p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off+i)
+                       p = pp.Append(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off+i)
                }
        } else if cnt <= int64(128*types.RegSize) {
-               p = pp.Appendpp(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
-               p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, 1*(128-cnt/int64(types.RegSize)))
+               p = pp.Append(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
+               p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, 1*(128-cnt/int64(types.RegSize)))
                p.To.Sym = ir.Syms.Duffzero
        } else {
-               p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_CONST, 0, cnt/int64(types.RegSize), obj.TYPE_REG, x86.REG_CX, 0)
-               p = pp.Appendpp(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
-               p = pp.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
-               p = pp.Appendpp(p, x86.ASTOSL, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
+               p = pp.Append(p, x86.AMOVL, obj.TYPE_CONST, 0, cnt/int64(types.RegSize), obj.TYPE_REG, x86.REG_CX, 0)
+               p = pp.Append(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
+               p = pp.Append(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
+               p = pp.Append(p, x86.ASTOSL, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
        }
 
        return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
        // See comment in ../amd64/ggen.go.
        p := pp.Prog(x86.AXCHGL)
        p.From.Type = obj.TYPE_REG