mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/internal/obj/mips: replace MOVD with MOVF on 32-bit to avoid unaligned memory access
This is the simplest CL that I can make for Go 1.8. For Go 1.9, we can revisit it and optimize the redundant address generation instructions or just fix #599 instead. Fixes #18140. Change-Id: Ie4804ab0e00dc6bb318da2bece8035c7c71caac3 Reviewed-on: https://go-review.googlesource.com/34193 Run-TryBot: Minux Ma <minux@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
bc61026c3f
commit
9fe2291efd
1 changed files with 38 additions and 0 deletions
|
|
@ -32,6 +32,7 @@ package mips
|
||||||
import (
|
import (
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
@ -533,6 +534,43 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctxt.Mode&Mips32 != 0 {
|
||||||
|
// rewrite MOVD into two MOVF in 32-bit mode to avoid unaligned memory access
|
||||||
|
for p = cursym.Text; p != nil; p = p1 {
|
||||||
|
p1 = p.Link
|
||||||
|
|
||||||
|
if p.As != AMOVD {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if p.From.Type != obj.TYPE_MEM && p.To.Type != obj.TYPE_MEM {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
p.As = AMOVF
|
||||||
|
q = ctxt.NewProg()
|
||||||
|
*q = *p
|
||||||
|
q.Link = p.Link
|
||||||
|
p.Link = q
|
||||||
|
p1 = q.Link
|
||||||
|
|
||||||
|
var regOff int16
|
||||||
|
if ctxt.Arch.ByteOrder == binary.BigEndian {
|
||||||
|
regOff = 1 // load odd register first
|
||||||
|
}
|
||||||
|
if p.From.Type == obj.TYPE_MEM {
|
||||||
|
reg := REG_F0 + (p.To.Reg-REG_F0)&^1
|
||||||
|
p.To.Reg = reg + regOff
|
||||||
|
q.To.Reg = reg + 1 - regOff
|
||||||
|
q.From.Offset += 4
|
||||||
|
} else if p.To.Type == obj.TYPE_MEM {
|
||||||
|
reg := REG_F0 + (p.From.Reg-REG_F0)&^1
|
||||||
|
p.From.Reg = reg + regOff
|
||||||
|
q.From.Reg = reg + 1 - regOff
|
||||||
|
q.To.Offset += 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if nosched {
|
if nosched {
|
||||||
// if we don't do instruction scheduling, simply add
|
// if we don't do instruction scheduling, simply add
|
||||||
// NOP after each branch instruction.
|
// NOP after each branch instruction.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue