Commit b115c35e authored by Russ Cox's avatar Russ Cox

cmd/internal/gc: move cgen, regalloc, et al to portable code

This CL moves the bulk of the code that has been copy-and-pasted
since the initial 386 port back into a shared place, cutting 5 copies to 1.

The motivation here is not cleanup per se but instead to reduce the
cost of introducing changes in shared concepts like regalloc or general
expression evaluation. For example, a change after this one will
implement x.(*T) without a call into the runtime. This CL makes that
followup work 5x easier.

The single copy still has more special cases for architecture details
than I'd like, but having them called out explicitly like this at least
opens the door to generalizing the conditions and smoothing out
the distinctions in the future.

This is a LARGE CL. I started by trying to pull in one function at a time
in a sequence of CLs and it became clear that everything was so
interrelated that it had to be moved as a whole. Apologies for the size.

It is not clear how many more releases this code will matter for;
eventually it will be replaced by Keith's SSA work. But as noted above,
the deduplication was necessary to reduce the cost of working on
the current code while we have it.

Passes tests on amd64, 386, arm, and ppc64le.
Can build arm64 binaries but not tested there.
Being able to build binaries means it is probably very close.

Change-Id: I735977f04c0614f80215fb12966dfe9bbd1f5861
Reviewed-on: https://go-review.googlesource.com/7853Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 11dba2ec
This diff is collapsed.
...@@ -26,7 +26,7 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -26,7 +26,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
var t1 gc.Node var t1 gc.Node
if l.Addable == 0 { if l.Addable == 0 {
gc.Tempname(&t1, l.Type) gc.Tempname(&t1, l.Type)
cgen(l, &t1) gc.Cgen(l, &t1)
l = &t1 l = &t1
} }
...@@ -42,11 +42,11 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -42,11 +42,11 @@ func cgen64(n *gc.Node, res *gc.Node) {
var hi2 gc.Node var hi2 gc.Node
split64(res, &lo2, &hi2) split64(res, &lo2, &hi2)
regalloc(&t1, lo1.Type, nil) gc.Regalloc(&t1, lo1.Type, nil)
var al gc.Node var al gc.Node
regalloc(&al, lo1.Type, nil) gc.Regalloc(&al, lo1.Type, nil)
var ah gc.Node var ah gc.Node
regalloc(&ah, hi1.Type, nil) gc.Regalloc(&ah, hi1.Type, nil)
gins(arm.AMOVW, &lo1, &al) gins(arm.AMOVW, &lo1, &al)
gins(arm.AMOVW, &hi1, &ah) gins(arm.AMOVW, &hi1, &ah)
...@@ -60,22 +60,22 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -60,22 +60,22 @@ func cgen64(n *gc.Node, res *gc.Node) {
gins(arm.ASBC, &ah, &t1) gins(arm.ASBC, &ah, &t1)
gins(arm.AMOVW, &t1, &hi2) gins(arm.AMOVW, &t1, &hi2)
regfree(&t1) gc.Regfree(&t1)
regfree(&al) gc.Regfree(&al)
regfree(&ah) gc.Regfree(&ah)
splitclean() splitclean()
splitclean() splitclean()
return return
case gc.OCOM: case gc.OCOM:
regalloc(&t1, lo1.Type, nil) gc.Regalloc(&t1, lo1.Type, nil)
gmove(ncon(^uint32(0)), &t1) gmove(ncon(^uint32(0)), &t1)
var lo2 gc.Node var lo2 gc.Node
var hi2 gc.Node var hi2 gc.Node
split64(res, &lo2, &hi2) split64(res, &lo2, &hi2)
var n1 gc.Node var n1 gc.Node
regalloc(&n1, lo1.Type, nil) gc.Regalloc(&n1, lo1.Type, nil)
gins(arm.AMOVW, &lo1, &n1) gins(arm.AMOVW, &lo1, &n1)
gins(arm.AEOR, &t1, &n1) gins(arm.AEOR, &t1, &n1)
...@@ -85,8 +85,8 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -85,8 +85,8 @@ func cgen64(n *gc.Node, res *gc.Node) {
gins(arm.AEOR, &t1, &n1) gins(arm.AEOR, &t1, &n1)
gins(arm.AMOVW, &n1, &hi2) gins(arm.AMOVW, &n1, &hi2)
regfree(&t1) gc.Regfree(&t1)
regfree(&n1) gc.Regfree(&n1)
splitclean() splitclean()
splitclean() splitclean()
return return
...@@ -111,7 +111,7 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -111,7 +111,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
if r != nil && r.Addable == 0 { if r != nil && r.Addable == 0 {
var t2 gc.Node var t2 gc.Node
gc.Tempname(&t2, r.Type) gc.Tempname(&t2, r.Type)
cgen(r, &t2) gc.Cgen(r, &t2)
r = &t2 r = &t2
} }
...@@ -122,9 +122,9 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -122,9 +122,9 @@ func cgen64(n *gc.Node, res *gc.Node) {
} }
var al gc.Node var al gc.Node
regalloc(&al, lo1.Type, nil) gc.Regalloc(&al, lo1.Type, nil)
var ah gc.Node var ah gc.Node
regalloc(&ah, hi1.Type, nil) gc.Regalloc(&ah, hi1.Type, nil)
// Do op. Leave result in ah:al. // Do op. Leave result in ah:al.
switch n.Op { switch n.Op {
...@@ -134,10 +134,10 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -134,10 +134,10 @@ func cgen64(n *gc.Node, res *gc.Node) {
// TODO: Constants // TODO: Constants
case gc.OADD: case gc.OADD:
var bl gc.Node var bl gc.Node
regalloc(&bl, gc.Types[gc.TPTR32], nil) gc.Regalloc(&bl, gc.Types[gc.TPTR32], nil)
var bh gc.Node var bh gc.Node
regalloc(&bh, gc.Types[gc.TPTR32], nil) gc.Regalloc(&bh, gc.Types[gc.TPTR32], nil)
gins(arm.AMOVW, &hi1, &ah) gins(arm.AMOVW, &hi1, &ah)
gins(arm.AMOVW, &lo1, &al) gins(arm.AMOVW, &lo1, &al)
gins(arm.AMOVW, &hi2, &bh) gins(arm.AMOVW, &hi2, &bh)
...@@ -145,16 +145,16 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -145,16 +145,16 @@ func cgen64(n *gc.Node, res *gc.Node) {
p1 := gins(arm.AADD, &bl, &al) p1 := gins(arm.AADD, &bl, &al)
p1.Scond |= arm.C_SBIT p1.Scond |= arm.C_SBIT
gins(arm.AADC, &bh, &ah) gins(arm.AADC, &bh, &ah)
regfree(&bl) gc.Regfree(&bl)
regfree(&bh) gc.Regfree(&bh)
// TODO: Constants. // TODO: Constants.
case gc.OSUB: case gc.OSUB:
var bl gc.Node var bl gc.Node
regalloc(&bl, gc.Types[gc.TPTR32], nil) gc.Regalloc(&bl, gc.Types[gc.TPTR32], nil)
var bh gc.Node var bh gc.Node
regalloc(&bh, gc.Types[gc.TPTR32], nil) gc.Regalloc(&bh, gc.Types[gc.TPTR32], nil)
gins(arm.AMOVW, &lo1, &al) gins(arm.AMOVW, &lo1, &al)
gins(arm.AMOVW, &hi1, &ah) gins(arm.AMOVW, &hi1, &ah)
gins(arm.AMOVW, &lo2, &bl) gins(arm.AMOVW, &lo2, &bl)
...@@ -162,20 +162,20 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -162,20 +162,20 @@ func cgen64(n *gc.Node, res *gc.Node) {
p1 := gins(arm.ASUB, &bl, &al) p1 := gins(arm.ASUB, &bl, &al)
p1.Scond |= arm.C_SBIT p1.Scond |= arm.C_SBIT
gins(arm.ASBC, &bh, &ah) gins(arm.ASBC, &bh, &ah)
regfree(&bl) gc.Regfree(&bl)
regfree(&bh) gc.Regfree(&bh)
// TODO(kaib): this can be done with 4 regs and does not need 6 // TODO(kaib): this can be done with 4 regs and does not need 6
case gc.OMUL: case gc.OMUL:
var bl gc.Node var bl gc.Node
regalloc(&bl, gc.Types[gc.TPTR32], nil) gc.Regalloc(&bl, gc.Types[gc.TPTR32], nil)
var bh gc.Node var bh gc.Node
regalloc(&bh, gc.Types[gc.TPTR32], nil) gc.Regalloc(&bh, gc.Types[gc.TPTR32], nil)
var cl gc.Node var cl gc.Node
regalloc(&cl, gc.Types[gc.TPTR32], nil) gc.Regalloc(&cl, gc.Types[gc.TPTR32], nil)
var ch gc.Node var ch gc.Node
regalloc(&ch, gc.Types[gc.TPTR32], nil) gc.Regalloc(&ch, gc.Types[gc.TPTR32], nil)
// load args into bh:bl and bh:bl. // load args into bh:bl and bh:bl.
gins(arm.AMOVW, &hi1, &bh) gins(arm.AMOVW, &hi1, &bh)
...@@ -220,11 +220,11 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -220,11 +220,11 @@ func cgen64(n *gc.Node, res *gc.Node) {
//print("%P\n", p1); //print("%P\n", p1);
regfree(&bh) gc.Regfree(&bh)
regfree(&bl) gc.Regfree(&bl)
regfree(&ch) gc.Regfree(&ch)
regfree(&cl) gc.Regfree(&cl)
// We only rotate by a constant c in [0,64). // We only rotate by a constant c in [0,64).
// if c >= 32: // if c >= 32:
...@@ -240,9 +240,9 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -240,9 +240,9 @@ func cgen64(n *gc.Node, res *gc.Node) {
v := uint64(gc.Mpgetfix(r.Val.U.Xval)) v := uint64(gc.Mpgetfix(r.Val.U.Xval))
var bl gc.Node var bl gc.Node
regalloc(&bl, lo1.Type, nil) gc.Regalloc(&bl, lo1.Type, nil)
var bh gc.Node var bh gc.Node
regalloc(&bh, hi1.Type, nil) gc.Regalloc(&bh, hi1.Type, nil)
if v >= 32 { if v >= 32 {
// reverse during load to do the first 32 bits of rotate // reverse during load to do the first 32 bits of rotate
v -= 32 v -= 32
...@@ -270,14 +270,14 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -270,14 +270,14 @@ func cgen64(n *gc.Node, res *gc.Node) {
gshift(arm.AORR, &bh, arm.SHIFT_LR, int32(32-v), &al) gshift(arm.AORR, &bh, arm.SHIFT_LR, int32(32-v), &al)
} }
regfree(&bl) gc.Regfree(&bl)
regfree(&bh) gc.Regfree(&bh)
case gc.OLSH: case gc.OLSH:
var bl gc.Node var bl gc.Node
regalloc(&bl, lo1.Type, nil) gc.Regalloc(&bl, lo1.Type, nil)
var bh gc.Node var bh gc.Node
regalloc(&bh, hi1.Type, nil) gc.Regalloc(&bh, hi1.Type, nil)
gins(arm.AMOVW, &hi1, &bh) gins(arm.AMOVW, &hi1, &bh)
gins(arm.AMOVW, &lo1, &bl) gins(arm.AMOVW, &lo1, &bl)
...@@ -323,8 +323,8 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -323,8 +323,8 @@ func cgen64(n *gc.Node, res *gc.Node) {
goto olsh_break goto olsh_break
} }
regalloc(&s, gc.Types[gc.TUINT32], nil) gc.Regalloc(&s, gc.Types[gc.TUINT32], nil)
regalloc(&creg, gc.Types[gc.TUINT32], nil) gc.Regalloc(&creg, gc.Types[gc.TUINT32], nil)
if gc.Is64(r.Type) { if gc.Is64(r.Type) {
// shift is >= 1<<32 // shift is >= 1<<32
var cl gc.Node var cl gc.Node
...@@ -355,7 +355,7 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -355,7 +355,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
gc.Nodconst(&n1, gc.Types[gc.TUINT32], 32) gc.Nodconst(&n1, gc.Types[gc.TUINT32], 32)
gmove(&n1, &creg) gmove(&n1, &creg)
gcmp(arm.ACMP, &s, &creg) gins(arm.ACMP, &s, &creg)
// MOVW.LO bl<<s, al // MOVW.LO bl<<s, al
p1 = gregshift(arm.AMOVW, &bl, arm.SHIFT_LL, &s, &al) p1 = gregshift(arm.AMOVW, &bl, arm.SHIFT_LL, &s, &al)
...@@ -392,7 +392,7 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -392,7 +392,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
gc.Nodconst(&n1, gc.Types[gc.TUINT32], 64) gc.Nodconst(&n1, gc.Types[gc.TUINT32], 64)
gmove(&n1, &creg) gmove(&n1, &creg)
gcmp(arm.ACMP, &s, &creg) gins(arm.ACMP, &s, &creg)
// EOR.LO al, al // EOR.LO al, al
p1 = gins(arm.AEOR, &al, &al) p1 = gins(arm.AEOR, &al, &al)
...@@ -427,18 +427,18 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -427,18 +427,18 @@ func cgen64(n *gc.Node, res *gc.Node) {
gc.Patch(p3, gc.Pc) gc.Patch(p3, gc.Pc)
gc.Patch(p4, gc.Pc) gc.Patch(p4, gc.Pc)
gc.Patch(p5, gc.Pc) gc.Patch(p5, gc.Pc)
regfree(&s) gc.Regfree(&s)
regfree(&creg) gc.Regfree(&creg)
olsh_break: olsh_break:
regfree(&bl) gc.Regfree(&bl)
regfree(&bh) gc.Regfree(&bh)
case gc.ORSH: case gc.ORSH:
var bl gc.Node var bl gc.Node
regalloc(&bl, lo1.Type, nil) gc.Regalloc(&bl, lo1.Type, nil)
var bh gc.Node var bh gc.Node
regalloc(&bh, hi1.Type, nil) gc.Regalloc(&bh, hi1.Type, nil)
gins(arm.AMOVW, &hi1, &bh) gins(arm.AMOVW, &hi1, &bh)
gins(arm.AMOVW, &lo1, &bl) gins(arm.AMOVW, &lo1, &bl)
...@@ -507,8 +507,8 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -507,8 +507,8 @@ func cgen64(n *gc.Node, res *gc.Node) {
goto orsh_break goto orsh_break
} }
regalloc(&s, gc.Types[gc.TUINT32], nil) gc.Regalloc(&s, gc.Types[gc.TUINT32], nil)
regalloc(&creg, gc.Types[gc.TUINT32], nil) gc.Regalloc(&creg, gc.Types[gc.TUINT32], nil)
if gc.Is64(r.Type) { if gc.Is64(r.Type) {
// shift is >= 1<<32 // shift is >= 1<<32
var ch gc.Node var ch gc.Node
...@@ -546,7 +546,7 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -546,7 +546,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
gc.Nodconst(&n1, gc.Types[gc.TUINT32], 32) gc.Nodconst(&n1, gc.Types[gc.TUINT32], 32)
gmove(&n1, &creg) gmove(&n1, &creg)
gcmp(arm.ACMP, &s, &creg) gins(arm.ACMP, &s, &creg)
// MOVW.LO bl>>s, al // MOVW.LO bl>>s, al
p1 = gregshift(arm.AMOVW, &bl, arm.SHIFT_LR, &s, &al) p1 = gregshift(arm.AMOVW, &bl, arm.SHIFT_LR, &s, &al)
...@@ -591,7 +591,7 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -591,7 +591,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
gc.Nodconst(&n1, gc.Types[gc.TUINT32], 64) gc.Nodconst(&n1, gc.Types[gc.TUINT32], 64)
gmove(&n1, &creg) gmove(&n1, &creg)
gcmp(arm.ACMP, &s, &creg) gins(arm.ACMP, &s, &creg)
// MOVW.LO creg>>1, creg // MOVW.LO creg>>1, creg
p1 = gshift(arm.AMOVW, &creg, arm.SHIFT_LR, 1, &creg) p1 = gshift(arm.AMOVW, &creg, arm.SHIFT_LR, 1, &creg)
...@@ -633,12 +633,12 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -633,12 +633,12 @@ func cgen64(n *gc.Node, res *gc.Node) {
gc.Patch(p3, gc.Pc) gc.Patch(p3, gc.Pc)
gc.Patch(p4, gc.Pc) gc.Patch(p4, gc.Pc)
gc.Patch(p5, gc.Pc) gc.Patch(p5, gc.Pc)
regfree(&s) gc.Regfree(&s)
regfree(&creg) gc.Regfree(&creg)
orsh_break: orsh_break:
regfree(&bl) gc.Regfree(&bl)
regfree(&bh) gc.Regfree(&bh)
// TODO(kaib): literal optimizations // TODO(kaib): literal optimizations
// make constant the right side (it usually is anyway). // make constant the right side (it usually is anyway).
...@@ -736,7 +736,7 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -736,7 +736,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
gc.OAND, gc.OAND,
gc.OOR: gc.OOR:
var n1 gc.Node var n1 gc.Node
regalloc(&n1, lo1.Type, nil) gc.Regalloc(&n1, lo1.Type, nil)
gins(arm.AMOVW, &lo1, &al) gins(arm.AMOVW, &lo1, &al)
gins(arm.AMOVW, &hi1, &ah) gins(arm.AMOVW, &hi1, &ah)
...@@ -744,7 +744,7 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -744,7 +744,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
gins(optoas(int(n.Op), lo1.Type), &n1, &al) gins(optoas(int(n.Op), lo1.Type), &n1, &al)
gins(arm.AMOVW, &hi2, &n1) gins(arm.AMOVW, &hi2, &n1)
gins(optoas(int(n.Op), lo1.Type), &n1, &ah) gins(optoas(int(n.Op), lo1.Type), &n1, &ah)
regfree(&n1) gc.Regfree(&n1)
} }
if gc.Is64(r.Type) { if gc.Is64(r.Type) {
...@@ -758,9 +758,9 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -758,9 +758,9 @@ func cgen64(n *gc.Node, res *gc.Node) {
splitclean() splitclean()
//out: //out:
regfree(&al) gc.Regfree(&al)
regfree(&ah) gc.Regfree(&ah)
} }
/* /*
...@@ -782,13 +782,13 @@ func cmp64(nl *gc.Node, nr *gc.Node, op int, likely int, to *obj.Prog) { ...@@ -782,13 +782,13 @@ func cmp64(nl *gc.Node, nr *gc.Node, op int, likely int, to *obj.Prog) {
// if they differ, we're done. // if they differ, we're done.
t := hi1.Type t := hi1.Type
regalloc(&r1, gc.Types[gc.TINT32], nil) gc.Regalloc(&r1, gc.Types[gc.TINT32], nil)
regalloc(&r2, gc.Types[gc.TINT32], nil) gc.Regalloc(&r2, gc.Types[gc.TINT32], nil)
gins(arm.AMOVW, &hi1, &r1) gins(arm.AMOVW, &hi1, &r1)
gins(arm.AMOVW, &hi2, &r2) gins(arm.AMOVW, &hi2, &r2)
gcmp(arm.ACMP, &r1, &r2) gins(arm.ACMP, &r1, &r2)
regfree(&r1) gc.Regfree(&r1)
regfree(&r2) gc.Regfree(&r2)
var br *obj.Prog var br *obj.Prog
switch op { switch op {
...@@ -838,13 +838,13 @@ func cmp64(nl *gc.Node, nr *gc.Node, op int, likely int, to *obj.Prog) { ...@@ -838,13 +838,13 @@ func cmp64(nl *gc.Node, nr *gc.Node, op int, likely int, to *obj.Prog) {
// compare least significant word // compare least significant word
t = lo1.Type t = lo1.Type
regalloc(&r1, gc.Types[gc.TINT32], nil) gc.Regalloc(&r1, gc.Types[gc.TINT32], nil)
regalloc(&r2, gc.Types[gc.TINT32], nil) gc.Regalloc(&r2, gc.Types[gc.TINT32], nil)
gins(arm.AMOVW, &lo1, &r1) gins(arm.AMOVW, &lo1, &r1)
gins(arm.AMOVW, &lo2, &r2) gins(arm.AMOVW, &lo2, &r2)
gcmp(arm.ACMP, &r1, &r2) gins(arm.ACMP, &r1, &r2)
regfree(&r1) gc.Regfree(&r1)
regfree(&r2) gc.Regfree(&r2)
// jump again // jump again
gc.Patch(gc.Gbranch(optoas(op, t), nil, likely), to) gc.Patch(gc.Gbranch(optoas(op, t), nil, likely), to)
......
...@@ -45,33 +45,40 @@ func main() { ...@@ -45,33 +45,40 @@ func main() {
gc.Thearch.Typedefs = typedefs gc.Thearch.Typedefs = typedefs
gc.Thearch.REGSP = arm.REGSP gc.Thearch.REGSP = arm.REGSP
gc.Thearch.REGCTXT = arm.REGCTXT gc.Thearch.REGCTXT = arm.REGCTXT
gc.Thearch.REGCALLX = arm.REG_R1
gc.Thearch.REGCALLX2 = arm.REG_R2
gc.Thearch.REGRETURN = arm.REG_R0
gc.Thearch.REGMIN = arm.REG_R0
gc.Thearch.REGMAX = arm.REGEXT
gc.Thearch.FREGMIN = arm.REG_F0
gc.Thearch.FREGMAX = arm.FREGEXT
gc.Thearch.MAXWIDTH = MAXWIDTH gc.Thearch.MAXWIDTH = MAXWIDTH
gc.Thearch.Anyregalloc = anyregalloc gc.Thearch.ReservedRegs = resvd
gc.Thearch.Betypeinit = betypeinit gc.Thearch.Betypeinit = betypeinit
gc.Thearch.Bgen = bgen gc.Thearch.Cgen64 = cgen64
gc.Thearch.Cgen = cgen gc.Thearch.Cgen_hmul = cgen_hmul
gc.Thearch.Cgen_call = cgen_call gc.Thearch.Cgen_shift = cgen_shift
gc.Thearch.Cgen_callinter = cgen_callinter
gc.Thearch.Cgen_ret = cgen_ret
gc.Thearch.Clearfat = clearfat gc.Thearch.Clearfat = clearfat
gc.Thearch.Cmp64 = cmp64
gc.Thearch.Defframe = defframe gc.Thearch.Defframe = defframe
gc.Thearch.Excise = excise gc.Thearch.Excise = excise
gc.Thearch.Expandchecks = expandchecks gc.Thearch.Expandchecks = expandchecks
gc.Thearch.Gclean = gclean
gc.Thearch.Ginit = ginit
gc.Thearch.Gins = gins gc.Thearch.Gins = gins
gc.Thearch.Ginscall = ginscall gc.Thearch.Ginscon = ginscon
gc.Thearch.Ginsnop = ginsnop
gc.Thearch.Gmove = gmove gc.Thearch.Gmove = gmove
gc.Thearch.Igen = igen gc.Thearch.Cgenindex = cgenindex
gc.Thearch.Linkarchinit = linkarchinit gc.Thearch.Linkarchinit = linkarchinit
gc.Thearch.Peep = peep gc.Thearch.Peep = peep
gc.Thearch.Proginfo = proginfo gc.Thearch.Proginfo = proginfo
gc.Thearch.Regalloc = regalloc
gc.Thearch.Regfree = regfree
gc.Thearch.Regtyp = regtyp gc.Thearch.Regtyp = regtyp
gc.Thearch.Sameaddr = sameaddr gc.Thearch.Sameaddr = sameaddr
gc.Thearch.Smallindir = smallindir gc.Thearch.Smallindir = smallindir
gc.Thearch.Stackaddr = stackaddr gc.Thearch.Stackaddr = stackaddr
gc.Thearch.Stackcopy = stackcopy
gc.Thearch.Sudoaddable = sudoaddable
gc.Thearch.Sudoclean = sudoclean
gc.Thearch.Excludedregs = excludedregs gc.Thearch.Excludedregs = excludedregs
gc.Thearch.RtoB = RtoB gc.Thearch.RtoB = RtoB
gc.Thearch.FtoB = RtoB gc.Thearch.FtoB = RtoB
......
// Copyright 2009 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
import "cmd/internal/obj/arm"
// Copyright 2009 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.
const (
REGALLOC_R0 = arm.REG_R0
REGALLOC_RMAX = arm.REGEXT
REGALLOC_F0 = arm.REG_F0
REGALLOC_FMAX = arm.FREGEXT
)
var reg [REGALLOC_FMAX + 1]uint8
/*
* cgen
*/
/*
* list.c
*/
/*
* reg.c
*/
This diff is collapsed.
This diff is collapsed.
...@@ -1330,10 +1330,10 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -1330,10 +1330,10 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
// R1 is ptr to memory, used and set, cannot be substituted. // R1 is ptr to memory, used and set, cannot be substituted.
case obj.ADUFFZERO: case obj.ADUFFZERO:
if v.Type == obj.TYPE_REG { if v.Type == obj.TYPE_REG {
if v.Reg == REGALLOC_R0 { if v.Reg == arm.REG_R0 {
return 1 return 1
} }
if v.Reg == REGALLOC_R0+1 { if v.Reg == arm.REG_R0+1 {
return 2 return 2
} }
} }
...@@ -1344,10 +1344,10 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -1344,10 +1344,10 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
// R1, R2 areptr to src, dst, used and set, cannot be substituted. // R1, R2 areptr to src, dst, used and set, cannot be substituted.
case obj.ADUFFCOPY: case obj.ADUFFCOPY:
if v.Type == obj.TYPE_REG { if v.Type == obj.TYPE_REG {
if v.Reg == REGALLOC_R0 { if v.Reg == arm.REG_R0 {
return 3 return 3
} }
if v.Reg == REGALLOC_R0+1 || v.Reg == REGALLOC_R0+2 { if v.Reg == arm.REG_R0+1 || v.Reg == arm.REG_R0+2 {
return 2 return 2
} }
} }
......
This diff is collapsed.
...@@ -64,39 +64,52 @@ func betypeinit() { ...@@ -64,39 +64,52 @@ func betypeinit() {
} }
func main() { func main() {
if obj.Getgoos() == "nacl" {
resvd = append(resvd, x86.REG_BP, x86.REG_SI)
} else if obj.Framepointer_enabled != 0 {
resvd = append(resvd, x86.REG_BP)
}
gc.Thearch.Thechar = thechar gc.Thearch.Thechar = thechar
gc.Thearch.Thestring = thestring gc.Thearch.Thestring = thestring
gc.Thearch.Thelinkarch = thelinkarch gc.Thearch.Thelinkarch = thelinkarch
gc.Thearch.Typedefs = typedefs gc.Thearch.Typedefs = typedefs
gc.Thearch.REGSP = x86.REGSP gc.Thearch.REGSP = x86.REGSP
gc.Thearch.REGCTXT = x86.REGCTXT gc.Thearch.REGCTXT = x86.REGCTXT
gc.Thearch.REGCALLX = x86.REG_BX
gc.Thearch.REGCALLX2 = x86.REG_AX
gc.Thearch.REGRETURN = x86.REG_AX
gc.Thearch.REGMIN = x86.REG_AX
gc.Thearch.REGMAX = x86.REG_R15
gc.Thearch.FREGMIN = x86.REG_X0
gc.Thearch.FREGMAX = x86.REG_X15
gc.Thearch.MAXWIDTH = MAXWIDTH gc.Thearch.MAXWIDTH = MAXWIDTH
gc.Thearch.Anyregalloc = anyregalloc gc.Thearch.ReservedRegs = resvd
gc.Thearch.AddIndex = addindex
gc.Thearch.Betypeinit = betypeinit gc.Thearch.Betypeinit = betypeinit
gc.Thearch.Bgen = bgen gc.Thearch.Cgen_bmul = cgen_bmul
gc.Thearch.Cgen = cgen gc.Thearch.Cgen_hmul = cgen_hmul
gc.Thearch.Cgen_call = cgen_call gc.Thearch.Cgen_shift = cgen_shift
gc.Thearch.Cgen_callinter = cgen_callinter
gc.Thearch.Cgen_ret = cgen_ret
gc.Thearch.Clearfat = clearfat gc.Thearch.Clearfat = clearfat
gc.Thearch.Defframe = defframe gc.Thearch.Defframe = defframe
gc.Thearch.Dodiv = dodiv
gc.Thearch.Excise = excise gc.Thearch.Excise = excise
gc.Thearch.Expandchecks = expandchecks gc.Thearch.Expandchecks = expandchecks
gc.Thearch.Gclean = gclean
gc.Thearch.Ginit = ginit
gc.Thearch.Gins = gins gc.Thearch.Gins = gins
gc.Thearch.Ginscall = ginscall gc.Thearch.Ginscon = ginscon
gc.Thearch.Ginsnop = ginsnop
gc.Thearch.Gmove = gmove gc.Thearch.Gmove = gmove
gc.Thearch.Igen = igen
gc.Thearch.Linkarchinit = linkarchinit gc.Thearch.Linkarchinit = linkarchinit
gc.Thearch.Peep = peep gc.Thearch.Peep = peep
gc.Thearch.Proginfo = proginfo gc.Thearch.Proginfo = proginfo
gc.Thearch.Regalloc = regalloc
gc.Thearch.Regfree = regfree
gc.Thearch.Regtyp = regtyp gc.Thearch.Regtyp = regtyp
gc.Thearch.Sameaddr = sameaddr gc.Thearch.Sameaddr = sameaddr
gc.Thearch.Smallindir = smallindir gc.Thearch.Smallindir = smallindir
gc.Thearch.Stackaddr = stackaddr gc.Thearch.Stackaddr = stackaddr
gc.Thearch.Stackcopy = stackcopy
gc.Thearch.Sudoaddable = sudoaddable
gc.Thearch.Sudoclean = sudoclean
gc.Thearch.Excludedregs = excludedregs gc.Thearch.Excludedregs = excludedregs
gc.Thearch.RtoB = RtoB gc.Thearch.RtoB = RtoB
gc.Thearch.FtoB = FtoB gc.Thearch.FtoB = FtoB
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -44,33 +44,38 @@ func main() { ...@@ -44,33 +44,38 @@ func main() {
gc.Thearch.Typedefs = typedefs gc.Thearch.Typedefs = typedefs
gc.Thearch.REGSP = arm64.REGSP gc.Thearch.REGSP = arm64.REGSP
gc.Thearch.REGCTXT = arm64.REGCTXT gc.Thearch.REGCTXT = arm64.REGCTXT
gc.Thearch.REGCALLX = arm64.REGRT1
gc.Thearch.REGCALLX2 = arm64.REGRT2
gc.Thearch.REGRETURN = arm64.REG_R0
gc.Thearch.REGMIN = arm64.REG_R0
gc.Thearch.REGMAX = arm64.REG_R31
gc.Thearch.FREGMIN = arm64.REG_F0
gc.Thearch.FREGMAX = arm64.REG_F31
gc.Thearch.MAXWIDTH = MAXWIDTH gc.Thearch.MAXWIDTH = MAXWIDTH
gc.Thearch.Anyregalloc = anyregalloc gc.Thearch.ReservedRegs = resvd
gc.Thearch.Betypeinit = betypeinit gc.Thearch.Betypeinit = betypeinit
gc.Thearch.Bgen = bgen gc.Thearch.Cgen_hmul = cgen_hmul
gc.Thearch.Cgen = cgen gc.Thearch.Cgen_shift = cgen_shift
gc.Thearch.Cgen_call = cgen_call
gc.Thearch.Cgen_callinter = cgen_callinter
gc.Thearch.Cgen_ret = cgen_ret
gc.Thearch.Clearfat = clearfat gc.Thearch.Clearfat = clearfat
gc.Thearch.Defframe = defframe gc.Thearch.Defframe = defframe
gc.Thearch.Dodiv = dodiv
gc.Thearch.Excise = excise gc.Thearch.Excise = excise
gc.Thearch.Expandchecks = expandchecks gc.Thearch.Expandchecks = expandchecks
gc.Thearch.Gclean = gclean
gc.Thearch.Ginit = ginit
gc.Thearch.Gins = gins gc.Thearch.Gins = gins
gc.Thearch.Ginscall = ginscall gc.Thearch.Ginscon = ginscon
gc.Thearch.Ginsnop = ginsnop
gc.Thearch.Gmove = gmove gc.Thearch.Gmove = gmove
gc.Thearch.Igen = igen
gc.Thearch.Linkarchinit = linkarchinit gc.Thearch.Linkarchinit = linkarchinit
gc.Thearch.Peep = peep gc.Thearch.Peep = peep
gc.Thearch.Proginfo = proginfo gc.Thearch.Proginfo = proginfo
gc.Thearch.Regalloc = regalloc
gc.Thearch.Regfree = regfree
gc.Thearch.Regtyp = regtyp gc.Thearch.Regtyp = regtyp
gc.Thearch.Sameaddr = sameaddr gc.Thearch.Sameaddr = sameaddr
gc.Thearch.Smallindir = smallindir gc.Thearch.Smallindir = smallindir
gc.Thearch.Stackaddr = stackaddr gc.Thearch.Stackaddr = stackaddr
gc.Thearch.Stackcopy = stackcopy
gc.Thearch.Sudoaddable = sudoaddable
gc.Thearch.Sudoclean = sudoclean
gc.Thearch.Excludedregs = excludedregs gc.Thearch.Excludedregs = excludedregs
gc.Thearch.RtoB = RtoB gc.Thearch.RtoB = RtoB
gc.Thearch.FtoB = RtoB gc.Thearch.FtoB = RtoB
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -27,7 +27,7 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -27,7 +27,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
gc.Fatal("cgen64 %v", gc.Oconv(int(n.Op), 0)) gc.Fatal("cgen64 %v", gc.Oconv(int(n.Op), 0))
case gc.OMINUS: case gc.OMINUS:
cgen(n.Left, res) gc.Cgen(n.Left, res)
var hi1 gc.Node var hi1 gc.Node
var lo1 gc.Node var lo1 gc.Node
split64(res, &lo1, &hi1) split64(res, &lo1, &hi1)
...@@ -38,7 +38,7 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -38,7 +38,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
return return
case gc.OCOM: case gc.OCOM:
cgen(n.Left, res) gc.Cgen(n.Left, res)
var lo1 gc.Node var lo1 gc.Node
var hi1 gc.Node var hi1 gc.Node
split64(res, &lo1, &hi1) split64(res, &lo1, &hi1)
...@@ -66,14 +66,14 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -66,14 +66,14 @@ func cgen64(n *gc.Node, res *gc.Node) {
if l.Addable == 0 { if l.Addable == 0 {
var t1 gc.Node var t1 gc.Node
gc.Tempname(&t1, l.Type) gc.Tempname(&t1, l.Type)
cgen(l, &t1) gc.Cgen(l, &t1)
l = &t1 l = &t1
} }
if r != nil && r.Addable == 0 { if r != nil && r.Addable == 0 {
var t2 gc.Node var t2 gc.Node
gc.Tempname(&t2, r.Type) gc.Tempname(&t2, r.Type)
cgen(r, &t2) gc.Cgen(r, &t2)
r = &t2 r = &t2
} }
...@@ -116,10 +116,10 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -116,10 +116,10 @@ func cgen64(n *gc.Node, res *gc.Node) {
// let's call the next two EX and FX. // let's call the next two EX and FX.
case gc.OMUL: case gc.OMUL:
var ex gc.Node var ex gc.Node
regalloc(&ex, gc.Types[gc.TPTR32], nil) gc.Regalloc(&ex, gc.Types[gc.TPTR32], nil)
var fx gc.Node var fx gc.Node
regalloc(&fx, gc.Types[gc.TPTR32], nil) gc.Regalloc(&fx, gc.Types[gc.TPTR32], nil)
// load args into DX:AX and EX:CX. // load args into DX:AX and EX:CX.
gins(x86.AMOVL, &lo1, &ax) gins(x86.AMOVL, &lo1, &ax)
...@@ -148,8 +148,8 @@ func cgen64(n *gc.Node, res *gc.Node) { ...@@ -148,8 +148,8 @@ func cgen64(n *gc.Node, res *gc.Node) {
gins(x86.AADDL, &fx, &dx) gins(x86.AADDL, &fx, &dx)
gc.Patch(p2, gc.Pc) gc.Patch(p2, gc.Pc)
regfree(&ex) gc.Regfree(&ex)
regfree(&fx) gc.Regfree(&fx)
// We only rotate by a constant c in [0,64). // We only rotate by a constant c in [0,64).
// if c >= 32: // if c >= 32:
...@@ -523,10 +523,10 @@ func cmp64(nl *gc.Node, nr *gc.Node, op int, likely int, to *obj.Prog) { ...@@ -523,10 +523,10 @@ func cmp64(nl *gc.Node, nr *gc.Node, op int, likely int, to *obj.Prog) {
if nl.Op == gc.OLITERAL || nr.Op == gc.OLITERAL { if nl.Op == gc.OLITERAL || nr.Op == gc.OLITERAL {
gins(x86.ACMPL, &hi1, &hi2) gins(x86.ACMPL, &hi1, &hi2)
} else { } else {
regalloc(&rr, gc.Types[gc.TINT32], nil) gc.Regalloc(&rr, gc.Types[gc.TINT32], nil)
gins(x86.AMOVL, &hi1, &rr) gins(x86.AMOVL, &hi1, &rr)
gins(x86.ACMPL, &rr, &hi2) gins(x86.ACMPL, &rr, &hi2)
regfree(&rr) gc.Regfree(&rr)
} }
var br *obj.Prog var br *obj.Prog
...@@ -580,10 +580,10 @@ func cmp64(nl *gc.Node, nr *gc.Node, op int, likely int, to *obj.Prog) { ...@@ -580,10 +580,10 @@ func cmp64(nl *gc.Node, nr *gc.Node, op int, likely int, to *obj.Prog) {
if nl.Op == gc.OLITERAL || nr.Op == gc.OLITERAL { if nl.Op == gc.OLITERAL || nr.Op == gc.OLITERAL {
gins(x86.ACMPL, &lo1, &lo2) gins(x86.ACMPL, &lo1, &lo2)
} else { } else {
regalloc(&rr, gc.Types[gc.TINT32], nil) gc.Regalloc(&rr, gc.Types[gc.TINT32], nil)
gins(x86.AMOVL, &lo1, &rr) gins(x86.AMOVL, &lo1, &rr)
gins(x86.ACMPL, &rr, &lo2) gins(x86.ACMPL, &rr, &lo2)
regfree(&rr) gc.Regfree(&rr)
} }
// jump again // jump again
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -672,7 +672,7 @@ func copyas(a *obj.Addr, v *obj.Addr) bool { ...@@ -672,7 +672,7 @@ func copyas(a *obj.Addr, v *obj.Addr) bool {
if regtyp(v) { if regtyp(v) {
return true return true
} }
if v.Type == obj.TYPE_MEM && (v.Name == obj.NAME_AUTO || v.Name == obj.NAME_PARAM) { if (v.Type == obj.TYPE_MEM || v.Type == obj.TYPE_ADDR) && (v.Name == obj.NAME_AUTO || v.Name == obj.NAME_PARAM) {
if v.Offset == a.Offset { if v.Offset == a.Offset {
return true return true
} }
...@@ -687,7 +687,7 @@ func sameaddr(a *obj.Addr, v *obj.Addr) bool { ...@@ -687,7 +687,7 @@ func sameaddr(a *obj.Addr, v *obj.Addr) bool {
if regtyp(v) { if regtyp(v) {
return true return true
} }
if v.Type == obj.TYPE_MEM && (v.Name == obj.NAME_AUTO || v.Name == obj.NAME_PARAM) { if (v.Type == obj.TYPE_MEM || v.Type == obj.TYPE_ADDR) && (v.Name == obj.NAME_AUTO || v.Name == obj.NAME_PARAM) {
if v.Offset == a.Offset { if v.Offset == a.Offset {
return true return true
} }
...@@ -703,7 +703,7 @@ func copyau(a *obj.Addr, v *obj.Addr) bool { ...@@ -703,7 +703,7 @@ func copyau(a *obj.Addr, v *obj.Addr) bool {
return true return true
} }
if regtyp(v) { if regtyp(v) {
if a.Type == obj.TYPE_MEM && a.Reg == v.Reg { if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == v.Reg {
return true return true
} }
if a.Index == v.Reg { if a.Index == v.Reg {
...@@ -732,7 +732,7 @@ func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int { ...@@ -732,7 +732,7 @@ func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int {
if regtyp(v) { if regtyp(v) {
reg := int(v.Reg) reg := int(v.Reg)
if a.Type == obj.TYPE_MEM && int(a.Reg) == reg { if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && int(a.Reg) == reg {
if (s.Reg == x86.REG_BP) && a.Index != obj.TYPE_NONE { if (s.Reg == x86.REG_BP) && a.Index != obj.TYPE_NONE {
return 1 /* can't use BP-base with index */ return 1 /* can't use BP-base with index */
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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