Commit d5cd4ab4 authored by Yao Zhang's avatar Yao Zhang Committed by Minux Ma

cmd/compile: added support for mips64{,le}

It is based on ppc64 compiler.

Change-Id: I15a101df05f2919ba5292136957ba0009227d067
Reviewed-on: https://go-review.googlesource.com/14445Reviewed-by: default avatarMinux Ma <minux@golang.org>
parent 053c7541
......@@ -251,7 +251,7 @@ func cgen_wb(n, res *Node, wb bool) {
return
}
if Ctxt.Arch.Thechar == '7' || Ctxt.Arch.Thechar == '9' {
if Ctxt.Arch.Thechar == '0' || Ctxt.Arch.Thechar == '7' || Ctxt.Arch.Thechar == '9' {
// if both are addressable, move
if n.Addable {
if n.Op == OREGISTER || res.Op == OREGISTER {
......@@ -751,14 +751,14 @@ abop: // asymmetric binary
Regalloc(&n1, nl.Type, res)
Cgen(nl, &n1)
if Smallintconst(nr) && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' { // TODO(rsc): Check opcode for arm
if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' { // TODO(rsc): Check opcode for arm
n2 = *nr
} else {
Regalloc(&n2, nr.Type, nil)
Cgen(nr, &n2)
}
} else {
if Smallintconst(nr) && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' { // TODO(rsc): Check opcode for arm
if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' { // TODO(rsc): Check opcode for arm
n2 = *nr
} else {
Regalloc(&n2, nr.Type, res)
......@@ -1829,8 +1829,8 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
// but they don't support direct generation of a bool value yet.
// We can fix that as we go.
switch Ctxt.Arch.Thechar {
case '5', '7', '9':
Fatalf("genval 5g, 7g, 9g ONAMES not fully implemented")
case '0', '5', '7', '9':
Fatalf("genval 0g, 5g, 7g, 9g ONAMES not fully implemented")
}
Cgen(n, res)
if !wantTrue {
......@@ -1839,7 +1839,7 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
return
}
if n.Addable && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' {
if n.Addable && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' {
// no need for a temporary
bgenNonZero(n, nil, wantTrue, likely, to)
return
......@@ -2023,7 +2023,7 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
Cgen(nl, &n1)
nl = &n1
if Smallintconst(nr) && Ctxt.Arch.Thechar != '9' {
if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '9' {
Thearch.Gins(Thearch.Optoas(OCMP, nr.Type), nl, nr)
bins(nr.Type, res, op, likely, to)
return
......@@ -2048,6 +2048,13 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
op = Brrev(op)
}
// MIPS does not have CMP instruction
if Ctxt.Arch.Thechar == '0' {
p := Thearch.Ginscmp(op, nr.Type, l, r, likely)
Patch(p, to)
return
}
// Do the comparison.
Thearch.Gins(Thearch.Optoas(OCMP, nr.Type), l, r)
......@@ -2133,6 +2140,15 @@ func bgenNonZero(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
if !wantTrue {
op = OEQ
}
// MIPS does not have CMP instruction
if Thearch.Thechar == '0' {
p := Gbranch(Thearch.Optoas(op, n.Type), n.Type, likely)
Naddr(&p.From, n)
Patch(p, to)
return
}
var zero Node
Nodconst(&zero, n.Type, 0)
Thearch.Gins(Thearch.Optoas(OCMP, n.Type), n, &zero)
......@@ -2597,7 +2613,7 @@ func cgen_div(op Op, nl *Node, nr *Node, res *Node) {
// in peep and optoas in order to enable this.
// TODO(rsc): ppc64 needs to support the relevant instructions
// in peep and optoas in order to enable this.
if nr.Op != OLITERAL || Ctxt.Arch.Thechar == '7' || Ctxt.Arch.Thechar == '9' {
if nr.Op != OLITERAL || Ctxt.Arch.Thechar == '0' || Ctxt.Arch.Thechar == '7' || Ctxt.Arch.Thechar == '9' {
goto longdiv
}
w = int(nl.Type.Width * 8)
......
......@@ -83,7 +83,7 @@ func Gbranch(as int, t *Type, likely int) *obj.Prog {
p := Prog(as)
p.To.Type = obj.TYPE_BRANCH
p.To.Val = nil
if as != obj.AJMP && likely != 0 && Thearch.Thechar != '9' && Thearch.Thechar != '7' {
if as != obj.AJMP && likely != 0 && Thearch.Thechar != '9' && Thearch.Thechar != '7' && Thearch.Thechar != '0' {
p.From.Type = obj.TYPE_CONST
if likely > 0 {
p.From.Offset = 1
......@@ -438,7 +438,7 @@ func Naddr(a *obj.Addr, n *Node) {
case OADDR:
Naddr(a, n.Left)
a.Etype = uint8(Tptr)
if Thearch.Thechar != '5' && Thearch.Thechar != '7' && Thearch.Thechar != '9' { // TODO(rsc): Do this even for arm, ppc64.
if Thearch.Thechar != '0' && Thearch.Thechar != '5' && Thearch.Thechar != '7' && Thearch.Thechar != '9' { // TODO(rsc): Do this even for arm, ppc64.
a.Width = int64(Widthptr)
}
if a.Type != obj.TYPE_MEM {
......
......@@ -282,7 +282,7 @@ func allocauto(ptxt *obj.Prog) {
if haspointers(n.Type) {
stkptrsize = Stksize
}
if Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
if Thearch.Thechar == '0' || Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
Stksize = Rnd(Stksize, int64(Widthptr))
}
if Stksize >= 1<<31 {
......@@ -319,7 +319,7 @@ func Cgen_checknil(n *Node) {
Fatalf("bad checknil")
}
if ((Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9') && n.Op != OREGISTER) || !n.Addable || n.Op == OLITERAL {
if ((Thearch.Thechar == '0' || Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9') && n.Op != OREGISTER) || !n.Addable || n.Op == OLITERAL {
var reg Node
Regalloc(&reg, Types[Tptr], n)
Cgen(n, &reg)
......
......@@ -249,7 +249,7 @@ func addmove(r *Flow, bn int, rn int, f int) {
p1.As = int16(Thearch.Optoas(OAS, Types[uint8(v.etype)]))
// TODO(rsc): Remove special case here.
if (Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9') && v.etype == TBOOL {
if (Thearch.Thechar == '0' || Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9') && v.etype == TBOOL {
p1.As = int16(Thearch.Optoas(OAS, Types[TUINT8]))
}
p1.From.Type = obj.TYPE_REG
......@@ -302,7 +302,7 @@ func mkvar(f *Flow, a *obj.Addr) Bits {
// TODO(rsc): Remove special case here.
case obj.TYPE_ADDR:
var bit Bits
if Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
if Thearch.Thechar == '0' || Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
goto memcase
}
a.Type = obj.TYPE_MEM
......
......@@ -3290,7 +3290,7 @@ func samecheap(a *Node, b *Node) bool {
}
func walkrotate(np **Node) {
if Thearch.Thechar == '7' || Thearch.Thechar == '9' {
if Thearch.Thechar == '0' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
return
}
......@@ -3418,7 +3418,7 @@ func walkdiv(np **Node, init **NodeList) {
// if >= 0, nr is 1<<pow // 1 if nr is negative.
// TODO(minux)
if Thearch.Thechar == '7' || Thearch.Thechar == '9' {
if Thearch.Thechar == '0' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
return
}
......
......@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ppc64
package mips64
import (
"cmd/compile/internal/gc"
"cmd/internal/obj"
"cmd/internal/obj/ppc64"
"cmd/internal/obj/mips"
)
func blockcopy(n, res *gc.Node, osrc, odst, w int64) {
......@@ -23,16 +23,16 @@ func blockcopy(n, res *gc.Node, osrc, odst, w int64) {
gc.Fatalf("sgen: invalid alignment %d for %v", align, n.Type)
case 1:
op = ppc64.AMOVBU
op = mips.AMOVB
case 2:
op = ppc64.AMOVHU
op = mips.AMOVH
case 4:
op = ppc64.AMOVWZU // there is no lwau, only lwaux
op = mips.AMOVW
case 8:
op = ppc64.AMOVDU
op = mips.AMOVV
}
if w%int64(align) != 0 {
......@@ -53,7 +53,7 @@ func blockcopy(n, res *gc.Node, osrc, odst, w int64) {
if n.Ullman >= res.Ullman {
gc.Agenr(n, &dst, res) // temporarily use dst
gc.Regalloc(&src, gc.Types[gc.Tptr], nil)
gins(ppc64.AMOVD, &dst, &src)
gins(mips.AMOVV, &dst, &src)
if res.Op == gc.ONAME {
gc.Gvardef(res)
}
......@@ -76,28 +76,28 @@ func blockcopy(n, res *gc.Node, osrc, odst, w int64) {
if dir < 0 {
if c >= 4 {
gc.Regalloc(&nend, gc.Types[gc.Tptr], nil)
gins(ppc64.AMOVD, &src, &nend)
gins(mips.AMOVV, &src, &nend)
}
p := gins(ppc64.AADD, nil, &src)
p := gins(mips.AADDV, nil, &src)
p.From.Type = obj.TYPE_CONST
p.From.Offset = w
p = gins(ppc64.AADD, nil, &dst)
p = gins(mips.AADDV, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = w
} else {
p := gins(ppc64.AADD, nil, &src)
p := gins(mips.AADDV, nil, &src)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-dir)
p = gins(ppc64.AADD, nil, &dst)
p = gins(mips.AADDV, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-dir)
if c >= 4 {
gc.Regalloc(&nend, gc.Types[gc.Tptr], nil)
p := gins(ppc64.AMOVD, &src, &nend)
p := gins(mips.AMOVV, &src, &nend)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = w
}
......@@ -111,35 +111,43 @@ func blockcopy(n, res *gc.Node, osrc, odst, w int64) {
p.From.Offset = int64(dir)
ploop := p
p = gins(mips.AADDV, nil, &src)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(dir)
p = gins(op, &tmp, &dst)
p.To.Type = obj.TYPE_MEM
p.To.Offset = int64(dir)
p = gins(ppc64.ACMP, &src, &nend)
p = gins(mips.AADDV, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(dir)
gc.Patch(gc.Gbranch(ppc64.ABNE, nil, 0), ploop)
gc.Patch(ginsbranch(mips.ABNE, nil, &src, &nend, 0), ploop)
gc.Regfree(&nend)
} else {
// TODO(austin): Instead of generating ADD $-8,R8; ADD
// $-8,R7; n*(MOVDU 8(R8),R9; MOVDU R9,8(R7);) just
// generate the offsets directly and eliminate the
// ADDs. That will produce shorter, more
// TODO: Instead of generating ADDV $-8,R8; ADDV
// $-8,R7; n*(MOVV 8(R8),R9; ADDV $8,R8; MOVV R9,8(R7);
// ADDV $8,R7;) just generate the offsets directly and
// eliminate the ADDs. That will produce shorter, more
// pipeline-able code.
var p *obj.Prog
for {
tmp14 := c
c--
if tmp14 <= 0 {
break
}
for ; c > 0; c-- {
p = gins(op, &src, &tmp)
p.From.Type = obj.TYPE_MEM
p.From.Offset = int64(dir)
p = gins(mips.AADDV, nil, &src)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(dir)
p = gins(op, &tmp, &dst)
p.To.Type = obj.TYPE_MEM
p.To.Offset = int64(dir)
p = gins(mips.AADDV, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(dir)
}
}
......
......@@ -2,27 +2,27 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ppc64
package mips64
import (
"cmd/compile/internal/gc"
"cmd/internal/obj"
"cmd/internal/obj/ppc64"
"cmd/internal/obj/mips"
)
var thechar int = '9'
var thechar int = '0'
var thestring string = "ppc64"
var thestring string = "mips64"
var thelinkarch *obj.LinkArch
func linkarchinit() {
thestring = obj.Getgoarch()
gc.Thearch.Thestring = thestring
if thestring == "ppc64le" {
thelinkarch = &ppc64.Linkppc64le
if thestring == "mips64le" {
thelinkarch = &mips.Linkmips64le
} else {
thelinkarch = &ppc64.Linkppc64
thelinkarch = &mips.Linkmips64
}
gc.Thearch.Thelinkarch = thelinkarch
}
......@@ -50,15 +50,15 @@ func Main() {
gc.Thearch.Thestring = thestring
gc.Thearch.Thelinkarch = thelinkarch
gc.Thearch.Typedefs = typedefs
gc.Thearch.REGSP = ppc64.REGSP
gc.Thearch.REGCTXT = ppc64.REGCTXT
gc.Thearch.REGCALLX = ppc64.REG_R3
gc.Thearch.REGCALLX2 = ppc64.REG_R4
gc.Thearch.REGRETURN = ppc64.REG_R3
gc.Thearch.REGMIN = ppc64.REG_R0
gc.Thearch.REGMAX = ppc64.REG_R31
gc.Thearch.FREGMIN = ppc64.REG_F0
gc.Thearch.FREGMAX = ppc64.REG_F31
gc.Thearch.REGSP = mips.REGSP
gc.Thearch.REGCTXT = mips.REGCTXT
gc.Thearch.REGCALLX = mips.REG_R1
gc.Thearch.REGCALLX2 = mips.REG_R2
gc.Thearch.REGRETURN = mips.REGRET
gc.Thearch.REGMIN = mips.REG_R0
gc.Thearch.REGMAX = mips.REG_R31
gc.Thearch.FREGMIN = mips.REG_F0
gc.Thearch.FREGMAX = mips.REG_F31
gc.Thearch.MAXWIDTH = MAXWIDTH
gc.Thearch.ReservedRegs = resvd
......
This diff is collapsed.
This diff is collapsed.
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ppc64
// Many Power ISA arithmetic and logical instructions come in four
// standard variants. These bits let us map between variants.
const (
V_CC = 1 << 0 // xCC (affect CR field 0 flags)
V_V = 1 << 1 // xV (affect SO and OV flags)
)
This diff is collapsed.
This diff is collapsed.
......@@ -28,9 +28,9 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package ppc64
package mips64
import "cmd/internal/obj/ppc64"
import "cmd/internal/obj/mips"
import "cmd/compile/internal/gc"
const (
......@@ -111,10 +111,10 @@ func regnames(n *int) []string {
func excludedregs() uint64 {
// Exclude registers with fixed functions
regbits := uint64(1<<0 | RtoB(ppc64.REGSP) | RtoB(ppc64.REGG) | RtoB(ppc64.REGTLS))
regbits := uint64(1<<0 | RtoB(mips.REGSP) | RtoB(mips.REGG) | RtoB(mips.REGTMP) | RtoB(mips.REGLINK) | RtoB(mips.REG_R26) | RtoB(mips.REG_R27))
// Also exclude floating point registers with fixed constants
regbits |= RtoB(ppc64.REG_F27) | RtoB(ppc64.REG_F28) | RtoB(ppc64.REG_F29) | RtoB(ppc64.REG_F30) | RtoB(ppc64.REG_F31)
regbits |= RtoB(mips.FREGZERO) | RtoB(mips.FREGHALF) | RtoB(mips.FREGONE) | RtoB(mips.FREGTWO)
return regbits
}
......@@ -136,11 +136,11 @@ func doregbits(r int) uint64 {
* 32+31 F31
*/
func RtoB(r int) uint64 {
if r > ppc64.REG_R0 && r <= ppc64.REG_R31 {
return 1 << uint(r-ppc64.REG_R0)
if r > mips.REG_R0 && r <= mips.REG_R31 {
return 1 << uint(r-mips.REG_R0)
}
if r >= ppc64.REG_F0 && r <= ppc64.REG_F31 {
return 1 << uint(32+r-ppc64.REG_F0)
if r >= mips.REG_F0 && r <= mips.REG_F31 {
return 1 << uint(32+r-mips.REG_F0)
}
return 0
}
......@@ -150,7 +150,7 @@ func BtoR(b uint64) int {
if b == 0 {
return 0
}
return gc.Bitno(b) + ppc64.REG_R0
return gc.Bitno(b) + mips.REG_R0
}
func BtoF(b uint64) int {
......@@ -158,5 +158,5 @@ func BtoF(b uint64) int {
if b == 0 {
return 0
}
return gc.Bitno(b) + ppc64.REG_F0
return gc.Bitno(b) + mips.REG_F0
}
......@@ -8,6 +8,7 @@ import (
"cmd/compile/internal/amd64"
"cmd/compile/internal/arm"
"cmd/compile/internal/arm64"
"cmd/compile/internal/mips64"
"cmd/compile/internal/ppc64"
"cmd/compile/internal/x86"
"cmd/internal/obj"
......@@ -28,6 +29,8 @@ func main() {
arm.Main()
case "arm64":
arm64.Main()
case "mips64", "mips64le":
mips64.Main()
case "ppc64", "ppc64le":
ppc64.Main()
}
......
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