Commit 02c1a9d8 authored by Aram Hăvărneanu's avatar Aram Hăvărneanu

cmd/7g: add ARM64 Go compiler, based on 9g

No peep optimizer yet.

Change-Id: Ifa5f993cd6ac5e34783c0df41faf772fbce96ae2
Reviewed-on: https://go-review.googlesource.com/7049Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 3d1ce27b
......@@ -7,7 +7,7 @@ package main
import (
"cmd/internal/gc"
"cmd/internal/obj"
"cmd/internal/obj/ppc64"
"cmd/internal/obj/arm64"
"fmt"
)
......@@ -250,11 +250,11 @@ func cgen(n *gc.Node, res *gc.Node) {
gc.OGE,
gc.OGT,
gc.ONOT:
p1 := gc.Gbranch(ppc64.ABR, nil, 0)
p1 := gc.Gbranch(arm64.AB, nil, 0)
p2 := gc.Pc
gmove(gc.Nodbool(true), res)
p3 := gc.Gbranch(ppc64.ABR, nil, 0)
p3 := gc.Gbranch(arm64.AB, nil, 0)
gc.Patch(p1, gc.Pc)
bgen(n, true, 0, p2)
gmove(gc.Nodbool(false), res)
......@@ -280,20 +280,10 @@ func cgen(n *gc.Node, res *gc.Node) {
return
case gc.OMINUS:
if gc.Isfloat[nl.Type.Etype] {
nr = gc.Nodintconst(-1)
gc.Convlit(&nr, n.Type)
a = optoas(gc.OMUL, nl.Type)
goto sbop
}
a := optoas(int(n.Op), nl.Type)
// unary
var n1 gc.Node
regalloc(&n1, nl.Type, res)
regalloc(&n1, nl.Type, nil)
cgen(nl, &n1)
gins(a, nil, &n1)
gins(optoas(gc.OMINUS, nl.Type), &n1, &n1)
gmove(&n1, res)
regfree(&n1)
return
......@@ -379,7 +369,7 @@ func cgen(n *gc.Node, res *gc.Node) {
if gc.Isconst(nl, gc.CTSTR) {
var n1 gc.Node
regalloc(&n1, gc.Types[gc.Tptr], res)
p1 := gins(ppc64.AMOVD, nil, &n1)
p1 := gins(arm64.AMOVD, nil, &n1)
gc.Datastring(nl.Val.U.Sval, &p1.From)
gmove(&n1, res)
regfree(&n1)
......@@ -403,7 +393,7 @@ func cgen(n *gc.Node, res *gc.Node) {
var n2 gc.Node
gc.Nodconst(&n2, gc.Types[gc.Tptr], 0)
gins(optoas(gc.OCMP, gc.Types[gc.Tptr]), &n1, &n2)
gcmp(optoas(gc.OCMP, gc.Types[gc.Tptr]), &n1, &n2)
p1 := gc.Gbranch(optoas(gc.OEQ, gc.Types[gc.Tptr]), nil, 0)
n2 = n1
......@@ -444,7 +434,7 @@ func cgen(n *gc.Node, res *gc.Node) {
var n2 gc.Node
gc.Nodconst(&n2, gc.Types[gc.Tptr], 0)
gins(optoas(gc.OCMP, gc.Types[gc.Tptr]), &n1, &n2)
gcmp(optoas(gc.OCMP, gc.Types[gc.Tptr]), &n1, &n2)
p1 := gc.Gbranch(optoas(gc.OEQ, gc.Types[gc.Tptr]), nil, 0)
n2 = n1
......@@ -690,7 +680,7 @@ func agenr(n *gc.Node, a *gc.Node, res *gc.Node) {
gc.Cgen_checknil(a)
case gc.OINDEX:
var p2 *obj.Prog // to be patched to panicindex.
p2 := (*obj.Prog)(nil) // to be patched to panicindex.
w := uint32(n.Type.Width)
//bounded = debug['B'] || n->bounded;
......@@ -796,13 +786,13 @@ func agenr(n *gc.Node, a *gc.Node, res *gc.Node) {
gc.Nodconst(&n4, gc.Types[gc.TUINT64], nl.Type.Bound)
} else {
regalloc(&n4, gc.Types[gc.TUINT64], nil)
p1 := gins(ppc64.AMOVD, nil, &n4)
p1 := gins(arm64.AMOVD, nil, &n4)
p1.From.Type = obj.TYPE_CONST
p1.From.Offset = nl.Type.Bound
}
}
gins(optoas(gc.OCMP, gc.Types[gc.TUINT64]), &n2, &n4)
gcmp(optoas(gc.OCMP, gc.Types[gc.TUINT64]), &n2, &n4)
if n4.Op == gc.OREGISTER {
regfree(&n4)
}
......@@ -816,7 +806,7 @@ func agenr(n *gc.Node, a *gc.Node, res *gc.Node) {
if gc.Isconst(nl, gc.CTSTR) {
regalloc(&n3, gc.Types[gc.Tptr], res)
p1 := gins(ppc64.AMOVD, nil, &n3)
p1 := gins(arm64.AMOVD, nil, &n3)
gc.Datastring(nl.Val.U.Sval, &p1.From)
p1.From.Type = obj.TYPE_ADDR
} else if gc.Isslice(nl.Type) || nl.Type.Etype == gc.TSTRING {
......@@ -897,7 +887,7 @@ func agen(n *gc.Node, res *gc.Node) {
var n3 gc.Node
n3.Op = gc.OADDR
n3.Left = &n1
gins(ppc64.AMOVD, &n3, &n2)
gins(arm64.AMOVD, &n3, &n2)
gmove(&n2, res)
regfree(&n2)
return
......@@ -909,7 +899,7 @@ func agen(n *gc.Node, res *gc.Node) {
n1.Left = n
var n2 gc.Node
regalloc(&n2, gc.Types[gc.Tptr], res)
gins(ppc64.AMOVD, &n1, &n2)
gins(arm64.AMOVD, &n1, &n2)
gmove(&n2, res)
regfree(&n2)
return
......@@ -1020,7 +1010,7 @@ func igen(n *gc.Node, a *gc.Node, res *gc.Node) {
// Increase the refcount of the register so that igen's caller
// has to call regfree.
case gc.OINDREG:
if n.Val.U.Reg != ppc64.REGSP {
if n.Val.U.Reg != arm64.REGSP {
reg[n.Val.U.Reg]++
}
*a = *n
......@@ -1060,7 +1050,7 @@ func igen(n *gc.Node, a *gc.Node, res *gc.Node) {
fp := gc.Structfirst(&flist, gc.Getoutarg(n.Left.Type))
*a = gc.Node{}
a.Op = gc.OINDREG
a.Val.U.Reg = ppc64.REGSP
a.Val.U.Reg = arm64.REGSP
a.Addable = 1
a.Xoffset = fp.Width + int64(gc.Widthptr) // +widthptr: saved lr at 0(SP)
a.Type = n.Type
......@@ -1149,10 +1139,10 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
cgen(n, &n1)
var n2 gc.Node
gc.Nodconst(&n2, n.Type, 0)
gins(optoas(gc.OCMP, n.Type), &n1, &n2)
a := ppc64.ABNE
gcmp(optoas(gc.OCMP, n.Type), &n1, &n2)
a := arm64.ABNE
if !true_ {
a = ppc64.ABEQ
a = arm64.ABEQ
}
gc.Patch(gc.Gbranch(a, n.Type, likely), to)
regfree(&n1)
......@@ -1161,7 +1151,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
// need to ask if it is bool?
case gc.OLITERAL:
if !true_ == (n.Val.U.Bval == 0) {
gc.Patch(gc.Gbranch(ppc64.ABR, nil, likely), to)
gc.Patch(gc.Gbranch(arm64.AB, nil, likely), to)
}
return
......@@ -1218,15 +1208,15 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
if !true_ {
if gc.Isfloat[nr.Type.Etype] {
// brcom is not valid on floats when NaN is involved.
p1 := gc.Gbranch(ppc64.ABR, nil, 0)
p1 := gc.Gbranch(arm64.AB, nil, 0)
p2 := gc.Gbranch(ppc64.ABR, nil, 0)
p2 := gc.Gbranch(arm64.AB, nil, 0)
gc.Patch(p1, gc.Pc)
ll := n.Ninit // avoid re-genning ninit
n.Ninit = nil
bgen(n, true, -likely, p2)
n.Ninit = ll
gc.Patch(gc.Gbranch(ppc64.ABR, nil, 0), to)
gc.Patch(gc.Gbranch(arm64.AB, nil, 0), to)
gc.Patch(p2, gc.Pc)
return
}
......@@ -1260,7 +1250,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
var n2 gc.Node
regalloc(&n2, gc.Types[gc.Tptr], &n1)
gmove(&n1, &n2)
gins(optoas(gc.OCMP, gc.Types[gc.Tptr]), &n2, &tmp)
gcmp(optoas(gc.OCMP, gc.Types[gc.Tptr]), &n2, &tmp)
regfree(&n2)
gc.Patch(gc.Gbranch(a, gc.Types[gc.Tptr], likely), to)
regfree(&n1)
......@@ -1283,7 +1273,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
var n2 gc.Node
regalloc(&n2, gc.Types[gc.Tptr], &n1)
gmove(&n1, &n2)
gins(optoas(gc.OCMP, gc.Types[gc.Tptr]), &n2, &tmp)
gcmp(optoas(gc.OCMP, gc.Types[gc.Tptr]), &n2, &tmp)
regfree(&n2)
gc.Patch(gc.Gbranch(a, gc.Types[gc.Tptr], likely), to)
regfree(&n1)
......@@ -1317,24 +1307,13 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
regalloc(&n1, nl.Type, nil)
cgen(nl, &n1)
// TODO(minux): cmpi does accept 16-bit signed immediate as p->to.
// and cmpli accepts 16-bit unsigned immediate.
//if(smallintconst(nr)) {
// gins(optoas(OCMP, nr->type), &n1, nr);
// patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
// regfree(&n1);
// break;
//}
regalloc(&n2, nr.Type, nil)
cgen(nr, &n2)
cmp:
l := &n1
r := &n2
gins(optoas(gc.OCMP, nr.Type), l, r)
gcmp(optoas(gc.OCMP, nr.Type), l, r)
if gc.Isfloat[nr.Type.Etype] && (a == gc.OLE || a == gc.OGE) {
// To get NaN right, must rewrite x <= y into separate x < y or x = y.
switch a {
......@@ -1470,16 +1449,16 @@ func sgen(n *gc.Node, ns *gc.Node, w int64) {
gc.Fatal("sgen: invalid alignment %d for %v", align, gc.Tconv(n.Type, 0))
case 1:
op = ppc64.AMOVBU
op = arm64.AMOVB
case 2:
op = ppc64.AMOVHU
op = arm64.AMOVH
case 4:
op = ppc64.AMOVWZU // there is no lwau, only lwaux
op = arm64.AMOVW
case 8:
op = ppc64.AMOVDU
op = arm64.AMOVD
}
if w%int64(align) != 0 {
......@@ -1521,7 +1500,7 @@ func sgen(n *gc.Node, ns *gc.Node, w int64) {
if n.Ullman >= res.Ullman {
agenr(n, &dst, res) // temporarily use dst
regalloc(&src, gc.Types[gc.Tptr], nil)
gins(ppc64.AMOVD, &dst, &src)
gins(arm64.AMOVD, &dst, &src)
if res.Op == gc.ONAME {
gc.Gvardef(res)
}
......@@ -1544,28 +1523,28 @@ func sgen(n *gc.Node, ns *gc.Node, w int64) {
if dir < 0 {
if c >= 4 {
regalloc(&nend, gc.Types[gc.Tptr], nil)
gins(ppc64.AMOVD, &src, &nend)
gins(arm64.AMOVD, &src, &nend)
}
p := gins(ppc64.AADD, nil, &src)
p := gins(arm64.AADD, nil, &src)
p.From.Type = obj.TYPE_CONST
p.From.Offset = w
p = gins(ppc64.AADD, nil, &dst)
p = gins(arm64.AADD, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = w
} else {
p := gins(ppc64.AADD, nil, &src)
p := gins(arm64.AADD, nil, &src)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-dir)
p = gins(ppc64.AADD, nil, &dst)
p = gins(arm64.AADD, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-dir)
if c >= 4 {
regalloc(&nend, gc.Types[gc.Tptr], nil)
p := gins(ppc64.AMOVD, &src, &nend)
p := gins(arm64.AMOVD, &src, &nend)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = w
}
......@@ -1577,15 +1556,17 @@ func sgen(n *gc.Node, ns *gc.Node, w int64) {
p := gins(op, &src, &tmp)
p.From.Type = obj.TYPE_MEM
p.From.Offset = int64(dir)
p.Scond = arm64.C_XPRE
ploop := p
p = gins(op, &tmp, &dst)
p.To.Type = obj.TYPE_MEM
p.To.Offset = int64(dir)
p.Scond = arm64.C_XPRE
p = gins(ppc64.ACMP, &src, &nend)
p = gcmp(arm64.ACMP, &src, &nend)
gc.Patch(gc.Gbranch(ppc64.ABNE, nil, 0), ploop)
gc.Patch(gc.Gbranch(arm64.ABNE, nil, 0), ploop)
regfree(&nend)
} else {
// TODO(austin): Instead of generating ADD $-8,R8; ADD
......@@ -1604,10 +1585,12 @@ func sgen(n *gc.Node, ns *gc.Node, w int64) {
p = gins(op, &src, &tmp)
p.From.Type = obj.TYPE_MEM
p.From.Offset = int64(dir)
p.Scond = arm64.C_XPRE
p = gins(op, &tmp, &dst)
p.To.Type = obj.TYPE_MEM
p.To.Offset = int64(dir)
p.Scond = arm64.C_XPRE
}
}
......
......@@ -7,24 +7,16 @@ package main
import (
"cmd/internal/gc"
"cmd/internal/obj"
"cmd/internal/obj/ppc64"
"cmd/internal/obj/arm64"
)
var thechar int = '9'
var thechar int = '7'
var thestring string = "ppc64"
var thestring string = "arm64"
var thelinkarch *obj.LinkArch
var thelinkarch *obj.LinkArch = &arm64.Linkarm64
func linkarchinit() {
thestring = obj.Getgoarch()
gc.Thearch.Thestring = thestring
if thestring == "ppc64le" {
thelinkarch = &ppc64.Linkppc64le
} else {
thelinkarch = &ppc64.Linkppc64
}
gc.Thearch.Thelinkarch = thelinkarch
}
var MAXWIDTH int64 = 1 << 50
......@@ -43,7 +35,6 @@ func betypeinit() {
gc.Widthptr = 8
gc.Widthint = 8
gc.Widthreg = 8
}
func main() {
......@@ -51,8 +42,8 @@ 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.REGSP = arm64.REGSP
gc.Thearch.REGCTXT = arm64.REGCTXT
gc.Thearch.MAXWIDTH = MAXWIDTH
gc.Thearch.Anyregalloc = anyregalloc
gc.Thearch.Betypeinit = betypeinit
......
......@@ -4,14 +4,14 @@
package main
import "cmd/internal/obj/ppc64"
import "cmd/internal/obj/arm64"
import "cmd/internal/gc"
// 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.
var reg [ppc64.NREG + ppc64.NFREG]uint8
var reg [arm64.NREG + arm64.NFREG]uint8
var panicdiv *gc.Node
......
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 main
// 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.
......@@ -30,8 +30,10 @@
package main
import "cmd/internal/obj/ppc64"
import "cmd/internal/gc"
import (
"cmd/internal/gc"
"cmd/internal/obj/arm64"
)
const (
NREGVAR = 64 /* 32 general + 32 floating */
......@@ -111,10 +113,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(RtoB(arm64.REGRT1) | RtoB(arm64.REGRT2) | RtoB(arm64.REGPR))
// 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(arm64.REG_F27) | RtoB(arm64.REG_F28) | RtoB(arm64.REG_F29) | RtoB(arm64.REG_F30) | RtoB(arm64.REG_F31)
return regbits
}
......@@ -136,11 +138,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 >= arm64.REG_R0 && r <= arm64.REG_R31 {
return 1 << uint(r-arm64.REG_R0)
}
if r >= ppc64.REG_F0 && r <= ppc64.REG_F31 {
return 1 << uint(32+r-ppc64.REG_F0)
if r >= arm64.REG_F0 && r <= arm64.REG_F31 {
return 1 << uint(32+r-arm64.REG_F0)
}
return 0
}
......@@ -150,7 +152,7 @@ func BtoR(b uint64) int {
if b == 0 {
return 0
}
return gc.Bitno(b) + ppc64.REG_R0
return gc.Bitno(b) + arm64.REG_R0
}
func BtoF(b uint64) int {
......@@ -158,5 +160,5 @@ func BtoF(b uint64) int {
if b == 0 {
return 0
}
return gc.Bitno(b) + ppc64.REG_F0
return gc.Bitno(b) + arm64.REG_F0
}
......@@ -80,7 +80,7 @@ func Gbranch(as int, t *Type, likely int) *obj.Prog {
p := Prog(as)
p.To.Type = obj.TYPE_BRANCH
p.To.U.Branch = nil
if as != obj.AJMP && likely != 0 && Thearch.Thechar != '9' {
if as != obj.AJMP && likely != 0 && Thearch.Thechar != '9' && Thearch.Thechar != '7' {
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(bool2int(likely > 0))
}
......@@ -423,7 +423,7 @@ func Naddr(n *Node) (a obj.Addr) {
case OADDR:
a = Naddr(n.Left)
a.Etype = uint8(Tptr)
if Thearch.Thechar != '5' && Thearch.Thechar != '9' { // TODO(rsc): Do this even for arm, ppc64.
if 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 {
......@@ -461,7 +461,7 @@ func Naddr(n *Node) (a obj.Addr) {
break // len(nil)
}
a.Etype = Simtype[TUINT]
if Thearch.Thechar == '9' {
if Thearch.Thechar == '7' || Thearch.Thechar == '9' {
a.Etype = Simtype[TINT]
}
a.Offset += int64(Array_nel)
......@@ -477,7 +477,7 @@ func Naddr(n *Node) (a obj.Addr) {
break // cap(nil)
}
a.Etype = Simtype[TUINT]
if Thearch.Thechar == '9' {
if Thearch.Thechar == '7' || Thearch.Thechar == '9' {
a.Etype = Simtype[TINT]
}
a.Offset += int64(Array_cap)
......@@ -560,7 +560,7 @@ fp:
if Thearch.Thechar == '5' {
n.Xoffset += 4
}
if Thearch.Thechar == '9' {
if Thearch.Thechar == '7' || Thearch.Thechar == '9' {
n.Xoffset += 8
}
......
......@@ -277,7 +277,7 @@ func allocauto(ptxt *obj.Prog) {
if haspointers(n.Type) {
stkptrsize = Stksize
}
if Thearch.Thechar == '5' || Thearch.Thechar == '9' {
if Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
Stksize = Rnd(Stksize, int64(Widthptr))
}
if Stksize >= 1<<31 {
......@@ -333,7 +333,7 @@ func Cgen_checknil(n *Node) {
Fatal("bad checknil")
}
if ((Thearch.Thechar == '5' || Thearch.Thechar == '9') && n.Op != OREGISTER) || n.Addable == 0 || n.Op == OLITERAL {
if ((Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9') && n.Op != OREGISTER) || n.Addable == 0 || n.Op == OLITERAL {
var reg Node
Thearch.Regalloc(&reg, Types[Tptr], n)
Thearch.Cgen(n, &reg)
......
......@@ -154,7 +154,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 == '9' || Thearch.Thechar == '5') && v.etype == TBOOL {
if (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
......@@ -209,7 +209,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 == '9' || Thearch.Thechar == '5' {
if Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
goto memcase
}
a.Type = obj.TYPE_MEM
......
......@@ -3625,7 +3625,7 @@ func samecheap(a *Node, b *Node) bool {
}
func walkrotate(np **Node) {
if Thearch.Thechar == '9' {
if Thearch.Thechar == '7' || Thearch.Thechar == '9' {
return
}
......@@ -3757,7 +3757,7 @@ func walkdiv(np **Node, init **NodeList) {
// if >= 0, nr is 1<<pow // 1 if nr is negative.
// TODO(minux)
if Thearch.Thechar == '9' {
if Thearch.Thechar == '7' || Thearch.Thechar == '9' {
return
}
......
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