Commit 9fe2291e authored by Shenghou Ma's avatar Shenghou Ma Committed by Minux Ma

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: 's avatarCherry Zhang <cherryyz@google.com>
parent bc61026c
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment