]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj: move fields from obj.Link to x86.AsmBuf
authorJosh Bleecher Snyder <josharian@gmail.com>
Sun, 26 Mar 2017 14:53:06 +0000 (07:53 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Sun, 26 Mar 2017 19:48:00 +0000 (19:48 +0000)
These fields are used to encode a single instruction.
Add them to AsmBuf, which is also per-instruction,
and which is not global.

Updates #15756

Change-Id: I0e5ea22ffa641b07291e27de6e2ff23b6dc534bd
Reviewed-on: https://go-review.googlesource.com/38668
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/internal/obj/link.go
src/cmd/internal/obj/x86/asm6.go

index a38a199fc4d0d0f995229f4183b785566bcc8d15..9e926abc9ca44161c2e931df5a83d118cd6c9428 100644 (file)
@@ -735,11 +735,6 @@ type Link struct {
        Printp        *Prog
        Blitrl        *Prog
        Elitrl        *Prog
-       Rexflag       int
-       Vexflag       int
-       Rep           int
-       Repn          int
-       Lock          int
        Instoffset    int64
        Autosize      int32
        Armsize       int32
index 013c150fa7bd4512bfd53912065005f72a762525..e1de8a633ded35293d958c12bf4cddcd1358331a 100644 (file)
@@ -2568,10 +2568,16 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
        return Yxxx
 }
 
-// AsmBuf is a simple buffer to assemble variable-length x86 instructions into.
+// AsmBuf is a simple buffer to assemble variable-length x86 instructions into
+// and hold assembly state.
 type AsmBuf struct {
-       buf [100]byte
-       off int
+       buf     [100]byte
+       off     int
+       rexflag int
+       vexflag int
+       rep     int
+       repn    int
+       lock    int
 }
 
 // Put1 appends one byte to the end of the buffer.
@@ -2828,7 +2834,7 @@ func (asmbuf *AsmBuf) asmandsz(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a
        switch {
        case int64(int32(a.Offset)) == a.Offset:
                // Offset fits in sign-extended 32 bits.
-       case int64(uint32(a.Offset)) == a.Offset && ctxt.Rexflag&Rxw == 0:
+       case int64(uint32(a.Offset)) == a.Offset && asmbuf.rexflag&Rxw == 0:
                // Offset fits in zero-extended 32 bits in a 32-bit instruction.
                // This is allowed for assembly that wants to use 32-bit hex
                // constants, e.g. LEAL 0x99999999(AX), AX.
@@ -2856,7 +2862,7 @@ func (asmbuf *AsmBuf) asmandsz(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a
                        goto bad
                }
                asmbuf.Put1(byte(3<<6 | reg[a.Reg]<<0 | r<<3))
-               ctxt.Rexflag |= regrex[a.Reg]&(0x40|Rxb) | rex
+               asmbuf.rexflag |= regrex[a.Reg]&(0x40|Rxb) | rex
                return
        }
 
@@ -2887,7 +2893,7 @@ func (asmbuf *AsmBuf) asmandsz(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a
                        base = REG_SP
                }
 
-               ctxt.Rexflag |= regrex[int(a.Index)]&Rxx | regrex[base]&Rxb | rex
+               asmbuf.rexflag |= regrex[int(a.Index)]&Rxx | regrex[base]&Rxb | rex
                if base == REG_NONE {
                        asmbuf.Put1(byte(0<<6 | 4<<0 | r<<3))
                        asmbuf.asmidx(ctxt, int(a.Scale), int(a.Index), base)
@@ -2938,7 +2944,7 @@ func (asmbuf *AsmBuf) asmandsz(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a
                v = int32(vaddr(ctxt, p, a, &rel))
        }
 
-       ctxt.Rexflag |= regrex[base]&Rxb | rex
+       asmbuf.rexflag |= regrex[base]&Rxb | rex
        if base == REG_NONE || (REG_CS <= base && base <= REG_GS) || base == REG_TLS {
                if (a.Sym == nil || !isextern(a.Sym)) && base == REG_NONE && (a.Name == obj.NAME_STATIC || a.Name == obj.NAME_EXTERN || a.Name == obj.NAME_GOTREF) || p.Mode != 64 {
                        if a.Name == obj.NAME_GOTREF && (a.Offset != 0 || a.Index != 0 || a.Scale != 0) {
@@ -3271,7 +3277,7 @@ var bpduff2 = []byte{
 // For details about vex prefix see:
 // https://en.wikipedia.org/wiki/VEX_prefix#Technical_description
 func (asmbuf *AsmBuf) asmvex(ctxt *obj.Link, rm, v, r *obj.Addr, vex, opcode uint8) {
-       ctxt.Vexflag = 1
+       asmbuf.vexflag = 1
        rexR := 0
        if r != nil {
                rexR = regrex[r.Reg] & Rxr
@@ -3389,7 +3395,7 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                asmbuf.Put2(Pe, Pm)
 
                        case Pq3: /* 16 bit escape and opcode escape + REX.W */
-                               ctxt.Rexflag |= Pw
+                               asmbuf.rexflag |= Pw
                                asmbuf.Put2(Pe, Pm)
 
                        case Pq4: /*  66 0F 38 */
@@ -3403,7 +3409,7 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                asmbuf.Put3(Pe, Pf3, Pm)
 
                        case Pfw: /* xmm opcode escape + REX.W */
-                               ctxt.Rexflag |= Pw
+                               asmbuf.rexflag |= Pw
                                asmbuf.Put2(Pf3, Pm)
 
                        case Pm: /* opcode escape */
@@ -3416,14 +3422,14 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                if p.Mode != 64 {
                                        ctxt.Diag("asmins: illegal 64: %v", p)
                                }
-                               ctxt.Rexflag |= Pw
+                               asmbuf.rexflag |= Pw
 
                        case Pw8: /* 64-bit escape if z >= 8 */
                                if z >= 8 {
                                        if p.Mode != 64 {
                                                ctxt.Diag("asmins: illegal 64: %v", p)
                                        }
-                                       ctxt.Rexflag |= Pw
+                                       asmbuf.rexflag |= Pw
                                }
 
                        case Pb: /* botch */
@@ -3519,7 +3525,7 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                asmbuf.asmand(ctxt, cursym, p, &p.From, &p.To)
 
                        case Zm_r_xm_nr:
-                               ctxt.Rexflag = 0
+                               asmbuf.rexflag = 0
                                asmbuf.mediaop(ctxt, o, op, int(yt.zoffset), z)
                                asmbuf.asmand(ctxt, cursym, p, &p.From, &p.To)
 
@@ -3600,7 +3606,7 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                asmbuf.asmand(ctxt, cursym, p, &p.To, &p.From)
 
                        case Zr_m_xm_nr:
-                               ctxt.Rexflag = 0
+                               asmbuf.rexflag = 0
                                asmbuf.mediaop(ctxt, o, op, int(yt.zoffset), z)
                                asmbuf.asmand(ctxt, cursym, p, &p.To, &p.From)
 
@@ -3647,11 +3653,11 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                asmbuf.Put1(byte(vaddr(ctxt, p, a, nil)))
 
                        case Zib_rp:
-                               ctxt.Rexflag |= regrex[p.To.Reg] & (Rxb | 0x40)
+                               asmbuf.rexflag |= regrex[p.To.Reg] & (Rxb | 0x40)
                                asmbuf.Put2(byte(op+reg[p.To.Reg]), byte(vaddr(ctxt, p, &p.From, nil)))
 
                        case Zil_rp:
-                               ctxt.Rexflag |= regrex[p.To.Reg] & Rxb
+                               asmbuf.rexflag |= regrex[p.To.Reg] & Rxb
                                asmbuf.Put1(byte(op + reg[p.To.Reg]))
                                if o.prefix == Pe {
                                        v = vaddr(ctxt, p, &p.From, nil)
@@ -3673,9 +3679,9 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                if l == 0 && rel.Siz != 8 {
                                        //p->mark |= 0100;
                                        //print("zero: %llux %v\n", v, p);
-                                       ctxt.Rexflag &^= (0x40 | Rxw)
+                                       asmbuf.rexflag &^= (0x40 | Rxw)
 
-                                       ctxt.Rexflag |= regrex[p.To.Reg] & Rxb
+                                       asmbuf.rexflag |= regrex[p.To.Reg] & Rxb
                                        asmbuf.Put1(byte(0xb8 + reg[p.To.Reg]))
                                        if rel.Type != 0 {
                                                r = obj.Addrel(cursym)
@@ -3694,7 +3700,7 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                        asmbuf.PutInt32(int32(v)) // need all 8
                                } else {
                                        //print("all: %llux %v\n", v, p);
-                                       ctxt.Rexflag |= regrex[p.To.Reg] & Rxb
+                                       asmbuf.rexflag |= regrex[p.To.Reg] & Rxb
                                        asmbuf.Put1(byte(op + reg[p.To.Reg]))
                                        if rel.Type != 0 {
                                                r = obj.Addrel(cursym)
@@ -3752,15 +3758,15 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                }
 
                        case Z_rp:
-                               ctxt.Rexflag |= regrex[p.To.Reg] & (Rxb | 0x40)
+                               asmbuf.rexflag |= regrex[p.To.Reg] & (Rxb | 0x40)
                                asmbuf.Put1(byte(op + reg[p.To.Reg]))
 
                        case Zrp_:
-                               ctxt.Rexflag |= regrex[p.From.Reg] & (Rxb | 0x40)
+                               asmbuf.rexflag |= regrex[p.From.Reg] & (Rxb | 0x40)
                                asmbuf.Put1(byte(op + reg[p.From.Reg]))
 
                        case Zclr:
-                               ctxt.Rexflag &^= Pw
+                               asmbuf.rexflag &^= Pw
                                asmbuf.Put1(byte(op))
                                asmbuf.asmand(ctxt, cursym, p, &p.To, &p.To)
 
@@ -3975,12 +3981,12 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                case 3: /* r,m - 2op */
                                        asmbuf.Put2(t[0], t[1])
                                        asmbuf.asmando(ctxt, cursym, p, &p.To, int(t[2]))
-                                       ctxt.Rexflag |= regrex[p.From.Reg] & (Rxr | 0x40)
+                                       asmbuf.rexflag |= regrex[p.From.Reg] & (Rxr | 0x40)
 
                                case 4: /* m,r - 2op */
                                        asmbuf.Put2(t[0], t[1])
                                        asmbuf.asmando(ctxt, cursym, p, &p.From, int(t[2]))
-                                       ctxt.Rexflag |= regrex[p.To.Reg] & (Rxr | 0x40)
+                                       asmbuf.rexflag |= regrex[p.To.Reg] & (Rxr | 0x40)
 
                                case 5: /* load full pointer, trash heap */
                                        if t[0] != 0 {
@@ -4013,7 +4019,7 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                                if p.Mode != 64 {
                                                        ctxt.Diag("asmins: illegal 64: %v", p)
                                                }
-                                               ctxt.Rexflag |= Pw
+                                               asmbuf.rexflag |= Pw
                                                t = t[1:]
                                        } else if t[0] == Pe {
                                                asmbuf.Put1(Pe)
@@ -4147,7 +4153,7 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                                // and a R_TLS_IE reloc. This all assumes the only tls variable we access
                                                // is g, which we can't check here, but will when we assemble the second
                                                // instruction.
-                                               ctxt.Rexflag = Pw | (regrex[p.To.Reg] & Rxr)
+                                               asmbuf.rexflag = Pw | (regrex[p.To.Reg] & Rxr)
 
                                                asmbuf.Put2(0x8B, byte(0x05|(reg[p.To.Reg]<<3)))
                                                r = obj.Addrel(cursym)
@@ -4167,7 +4173,7 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                                pp.From.Sym = ctxt.Plan9privates
                                                pp.From.Offset = 0
                                                pp.From.Index = REG_NONE
-                                               ctxt.Rexflag |= Pw
+                                               asmbuf.rexflag |= Pw
                                                asmbuf.Put1(0x8B)
                                                asmbuf.asmand(ctxt, cursym, p, &pp.From, &p.To)
 
@@ -4181,7 +4187,7 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                                pp.From.Offset = 0
                                                pp.From.Index = REG_NONE
                                                pp.From.Scale = 0
-                                               ctxt.Rexflag |= Pw
+                                               asmbuf.rexflag |= Pw
                                                asmbuf.Put2(0x64, // FS
                                                        0x8B)
                                                asmbuf.asmand(ctxt, cursym, p, &pp.From, &p.To)
@@ -4196,7 +4202,7 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                                pp.From.Offset = 0x28
                                                pp.From.Index = REG_NONE
                                                pp.From.Scale = 0
-                                               ctxt.Rexflag |= Pw
+                                               asmbuf.rexflag |= Pw
                                                asmbuf.Put2(0x65, // GS
                                                        0x8B)
                                                asmbuf.asmand(ctxt, cursym, p, &pp.From, &p.To)
@@ -4461,17 +4467,17 @@ func (asmbuf *AsmBuf) asmins(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
 
        if ctxt.Headtype == obj.Hnacl && p.Mode == 64 {
                if p.As == AREP {
-                       ctxt.Rep++
+                       asmbuf.rep++
                        return
                }
 
                if p.As == AREPN {
-                       ctxt.Repn++
+                       asmbuf.repn++
                        return
                }
 
                if p.As == ALOCK {
-                       ctxt.Lock++
+                       asmbuf.lock++
                        return
                }
 
@@ -4523,27 +4529,27 @@ func (asmbuf *AsmBuf) asmins(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                        asmbuf.Put(naclmovs)
                }
 
-               if ctxt.Rep != 0 {
+               if asmbuf.rep != 0 {
                        asmbuf.Put1(0xf3)
-                       ctxt.Rep = 0
+                       asmbuf.rep = 0
                }
 
-               if ctxt.Repn != 0 {
+               if asmbuf.repn != 0 {
                        asmbuf.Put1(0xf2)
-                       ctxt.Repn = 0
+                       asmbuf.repn = 0
                }
 
-               if ctxt.Lock != 0 {
+               if asmbuf.lock != 0 {
                        asmbuf.Put1(0xf0)
-                       ctxt.Lock = 0
+                       asmbuf.lock = 0
                }
        }
 
-       ctxt.Rexflag = 0
-       ctxt.Vexflag = 0
+       asmbuf.rexflag = 0
+       asmbuf.vexflag = 0
        mark := asmbuf.Len()
        asmbuf.doasm(ctxt, cursym, p)
-       if ctxt.Rexflag != 0 && ctxt.Vexflag == 0 {
+       if asmbuf.rexflag != 0 && asmbuf.vexflag == 0 {
                /*
                 * as befits the whole approach of the architecture,
                 * the rex prefix must appear before the first opcode byte
@@ -4562,7 +4568,7 @@ func (asmbuf *AsmBuf) asmins(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                break
                        }
                }
-               asmbuf.Insert(np, byte(0x40|ctxt.Rexflag))
+               asmbuf.Insert(np, byte(0x40|asmbuf.rexflag))
        }
 
        n := asmbuf.Len()
@@ -4571,7 +4577,7 @@ func (asmbuf *AsmBuf) asmins(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                if int64(r.Off) < p.Pc {
                        break
                }
-               if ctxt.Rexflag != 0 {
+               if asmbuf.rexflag != 0 {
                        r.Off++
                }
                if r.Type == obj.R_PCREL {