]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/mips: replace MOVD with MOVF on 32-bit to avoid unaligned memory...
authorShenghou Ma <minux@golang.org>
Fri, 9 Dec 2016 05:13:43 +0000 (00:13 -0500)
committerMinux Ma <minux@golang.org>
Mon, 12 Dec 2016 23:25:06 +0000 (23:25 +0000)
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>
src/cmd/internal/obj/mips/obj0.go

index 221fd428a32f2b2540fb0bb78240575e9167d095..12cfb31377cb723959475d94e6f9ce55d5c15300 100644 (file)
@@ -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.