diff options
Diffstat (limited to 'src/cmd/internal/obj/x86/asm6.go')
| -rw-r--r-- | src/cmd/internal/obj/x86/asm6.go | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go index 115350637f..9ab6615e43 100644 --- a/src/cmd/internal/obj/x86/asm6.go +++ b/src/cmd/internal/obj/x86/asm6.go @@ -1895,7 +1895,7 @@ func span6(ctxt *obj.Link, s *obj.LSym) { // process forward jumps to p for q = p.Rel; q != nil; q = q.Forwd { - v = int32(p.Pc - (q.Pc + int64(q.Mark))) + v = int32(p.Pc - (q.Pc + int64(q.Isize))) if q.Back&2 != 0 { // short if v > 127 { loop++ @@ -1908,7 +1908,7 @@ func span6(ctxt *obj.Link, s *obj.LSym) { s.P[q.Pc+1] = byte(v) } } else { - bp = s.P[q.Pc+int64(q.Mark)-4:] + bp = s.P[q.Pc+int64(q.Isize)-4:] bp[0] = byte(v) bp = bp[1:] bp[0] = byte(v >> 8) @@ -1931,7 +1931,6 @@ func span6(ctxt *obj.Link, s *obj.LSym) { obj.Symgrow(ctxt, s, p.Pc+int64(m)) copy(s.P[p.Pc:][:m], ctxt.And[:m]) - p.Mark = uint16(m) c += int32(m) } @@ -2272,8 +2271,28 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int { return Yxxx case obj.TYPE_MEM: - if a.Name != obj.NAME_NONE { - if ctxt.Asmode == 64 && (a.Reg != REG_NONE || a.Index != REG_NONE || a.Scale != 0) { + if a.Index == REG_SP { + // Can't use SP as the index register + return Yxxx + } + if ctxt.Asmode == 64 { + switch a.Name { + case obj.NAME_EXTERN, obj.NAME_STATIC, obj.NAME_GOTREF: + // Global variables can't use index registers and their + // base register is %rip (%rip is encoded as REG_NONE). + if a.Reg != REG_NONE || a.Index != REG_NONE || a.Scale != 0 { + return Yxxx + } + case obj.NAME_AUTO, obj.NAME_PARAM: + // These names must have a base of SP. The old compiler + // uses 0 for the base register. SSA uses REG_SP. + if a.Reg != REG_SP && a.Reg != 0 { + return Yxxx + } + case obj.NAME_NONE: + // everything is ok + default: + // unknown name return Yxxx } } @@ -2321,6 +2340,10 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int { v = int64(int32(v)) } if v == 0 { + if p.Mark&PRESERVEFLAGS != 0 { + // If PRESERVEFLAGS is set, avoid MOV $0, AX turning into XOR AX, AX. + return Yu7 + } return Yi0 } if v == 1 { |
