diff options
| author | Shenghou Ma <minux@golang.org> | 2016-12-09 00:13:43 -0500 |
|---|---|---|
| committer | Minux Ma <minux@golang.org> | 2016-12-12 23:25:06 +0000 |
| commit | 9fe2291efdfd6257b97a3271b1145b67a3e7089d (patch) | |
| tree | 8a4c07802984842197bf187f05b3ac8c966e626b /src/cmd/internal/obj/mips/obj0.go | |
| parent | bc61026c3f60d0d449e1cb292ef202daa1c2d019 (diff) | |
| download | go-9fe2291efdfd6257b97a3271b1145b67a3e7089d.tar.xz | |
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>
Diffstat (limited to 'src/cmd/internal/obj/mips/obj0.go')
| -rw-r--r-- | src/cmd/internal/obj/mips/obj0.go | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/cmd/internal/obj/mips/obj0.go b/src/cmd/internal/obj/mips/obj0.go index 221fd428a3..12cfb31377 100644 --- a/src/cmd/internal/obj/mips/obj0.go +++ b/src/cmd/internal/obj/mips/obj0.go @@ -32,6 +32,7 @@ package mips import ( "cmd/internal/obj" "cmd/internal/sys" + "encoding/binary" "fmt" "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 we don't do instruction scheduling, simply add // NOP after each branch instruction. |
