// 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++
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)
obj.Symgrow(ctxt, s, p.Pc+int64(m))
copy(s.P[p.Pc:][:m], ctxt.And[:m])
- p.Mark = uint16(m)
c += int32(m)
}
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
}
}
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 {