}
// Avoid taking the address for simple enough types.
- if componentgen(n, res) {
+ if gc.Componentgen(n, res) {
return
}
regfree(&src)
regfree(&tmp)
}
-
-func cadable(n *gc.Node) bool {
- if n.Addable == 0 {
- // dont know how it happens,
- // but it does
- return false
- }
-
- switch n.Op {
- case gc.ONAME:
- return true
- }
-
- return false
-}
-
-/*
- * copy a composite value by moving its individual components.
- * Slices, strings and interfaces are supported.
- * Small structs or arrays with elements of basic type are
- * also supported.
- * nr is N when assigning a zero value.
- * return 1 if can do, 0 if cant.
- */
-func componentgen(nr *gc.Node, nl *gc.Node) bool {
- var nodl gc.Node
- var nodr gc.Node
-
- freel := 0
- freer := 0
-
- switch nl.Type.Etype {
- default:
- goto no
-
- case gc.TARRAY:
- t := nl.Type
-
- // Slices are ok.
- if gc.Isslice(t) {
- break
- }
-
- // Small arrays are ok.
- if t.Bound > 0 && t.Bound <= 3 && !gc.Isfat(t.Type) {
- break
- }
-
- goto no
-
- // Small structs with non-fat types are ok.
- // Zero-sized structs are treated separately elsewhere.
- case gc.TSTRUCT:
- fldcount := int64(0)
-
- for t := nl.Type.Type; t != nil; t = t.Down {
- if gc.Isfat(t.Type) {
- goto no
- }
- if t.Etype != gc.TFIELD {
- gc.Fatal("componentgen: not a TFIELD: %v", gc.Tconv(t, obj.FmtLong))
- }
- fldcount++
- }
-
- if fldcount == 0 || fldcount > 4 {
- goto no
- }
-
- case gc.TSTRING,
- gc.TINTER:
- break
- }
-
- nodl = *nl
- if !cadable(nl) {
- if nr != nil && !cadable(nr) {
- goto no
- }
- igen(nl, &nodl, nil)
- freel = 1
- }
-
- if nr != nil {
- nodr = *nr
- if !cadable(nr) {
- igen(nr, &nodr, nil)
- freer = 1
- }
- } else {
- // When zeroing, prepare a register containing zero.
- var tmp gc.Node
- gc.Nodconst(&tmp, nl.Type, 0)
-
- regalloc(&nodr, gc.Types[gc.TUINT], nil)
- gmove(&tmp, &nodr)
- freer = 1
- }
-
- // nl and nr are 'cadable' which basically means they are names (variables) now.
- // If they are the same variable, don't generate any code, because the
- // VARDEF we generate will mark the old value as dead incorrectly.
- // (And also the assignments are useless.)
- if nr != nil && nl.Op == gc.ONAME && nr.Op == gc.ONAME && nl == nr {
- goto yes
- }
-
- switch nl.Type.Etype {
- // componentgen for arrays.
- case gc.TARRAY:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- t := nl.Type
- if !gc.Isslice(t) {
- nodl.Type = t.Type
- nodr.Type = nodl.Type
- for fldcount := int64(0); fldcount < t.Bound; fldcount++ {
- if nr == nil {
- gc.Clearslim(&nodl)
- } else {
- gmove(&nodr, &nodl)
- }
- nodl.Xoffset += t.Type.Width
- nodr.Xoffset += t.Type.Width
- }
-
- goto yes
- }
-
- // componentgen for slices.
- nodl.Xoffset += int64(gc.Array_array)
-
- nodl.Type = gc.Ptrto(nl.Type.Type)
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_cap) - int64(gc.Array_nel)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_cap) - int64(gc.Array_nel)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TSTRING:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- nodl.Xoffset += int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TINTER:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- nodl.Xoffset += int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TSTRUCT:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- loffset := nodl.Xoffset
- roffset := nodr.Xoffset
-
- // funarg structs may not begin at offset zero.
- if nl.Type.Etype == gc.TSTRUCT && nl.Type.Funarg != 0 && nl.Type.Type != nil {
- loffset -= nl.Type.Type.Width
- }
- if nr != nil && nr.Type.Etype == gc.TSTRUCT && nr.Type.Funarg != 0 && nr.Type.Type != nil {
- roffset -= nr.Type.Type.Width
- }
-
- for t := nl.Type.Type; t != nil; t = t.Down {
- nodl.Xoffset = loffset + t.Width
- nodl.Type = t.Type
-
- if nr == nil {
- gc.Clearslim(&nodl)
- } else {
- nodr.Xoffset = roffset + t.Width
- nodr.Type = nodl.Type
- gmove(&nodr, &nodl)
- }
- }
-
- goto yes
- }
-
-no:
- if freer != 0 {
- regfree(&nodr)
- }
- if freel != 0 {
- regfree(&nodl)
- }
- return false
-
-yes:
- if freer != 0 {
- regfree(&nodr)
- }
- if freel != 0 {
- regfree(&nodl)
- }
- return true
-}
gc.Thearch.Ginit = ginit
gc.Thearch.Gins = gins
gc.Thearch.Ginscall = ginscall
+ gc.Thearch.Gmove = gmove
gc.Thearch.Igen = igen
gc.Thearch.Linkarchinit = linkarchinit
gc.Thearch.Peep = peep
w := uint32(nl.Type.Width)
// Avoid taking the address for simple enough types.
- if componentgen(nil, nl) {
+ if gc.Componentgen(nil, nl) {
return
}
}
// Avoid taking the address for simple enough types.
- if componentgen(n, ns) {
+ if gc.Componentgen(n, ns) {
return
}
restx(&cx, &oldcx)
}
-
-func cadable(n *gc.Node) bool {
- if n.Addable == 0 {
- // dont know how it happens,
- // but it does
- return false
- }
-
- switch n.Op {
- case gc.ONAME:
- return true
- }
-
- return false
-}
-
-/*
- * copy a composite value by moving its individual components.
- * Slices, strings and interfaces are supported.
- * Small structs or arrays with elements of basic type are
- * also supported.
- * nr is N when assigning a zero value.
- * return 1 if can do, 0 if can't.
- */
-func componentgen(nr *gc.Node, nl *gc.Node) bool {
- var nodl gc.Node
- var nodr gc.Node
-
- freel := 0
- freer := 0
-
- switch nl.Type.Etype {
- default:
- goto no
-
- case gc.TARRAY:
- t := nl.Type
-
- // Slices are ok.
- if gc.Isslice(t) {
- break
- }
-
- // Small arrays are ok.
- if t.Bound > 0 && t.Bound <= 3 && !gc.Isfat(t.Type) {
- break
- }
-
- goto no
-
- // Small structs with non-fat types are ok.
- // Zero-sized structs are treated separately elsewhere.
- case gc.TSTRUCT:
- fldcount := int64(0)
-
- for t := nl.Type.Type; t != nil; t = t.Down {
- if gc.Isfat(t.Type) && !gc.Isslice(t) {
- goto no
- }
- if t.Etype != gc.TFIELD {
- gc.Fatal("componentgen: not a TFIELD: %v", gc.Tconv(t, obj.FmtLong))
- }
- fldcount++
- }
-
- if fldcount == 0 || fldcount > 4 {
- goto no
- }
-
- case gc.TSTRING,
- gc.TINTER:
- break
- }
-
- nodl = *nl
- if !cadable(nl) {
- if nr != nil && !cadable(nr) {
- goto no
- }
- igen(nl, &nodl, nil)
- freel = 1
- }
-
- if nr != nil {
- nodr = *nr
- if !cadable(nr) {
- igen(nr, &nodr, nil)
- freer = 1
- }
- } else {
- // When zeroing, prepare a register containing zero.
- var tmp gc.Node
- gc.Nodconst(&tmp, nl.Type, 0)
-
- regalloc(&nodr, gc.Types[gc.TUINT], nil)
- gmove(&tmp, &nodr)
- freer = 1
- }
-
- // nl and nr are 'cadable' which basically means they are names (variables) now.
- // If they are the same variable, don't generate any code, because the
- // VARDEF we generate will mark the old value as dead incorrectly.
- // (And also the assignments are useless.)
- if nr != nil && nl.Op == gc.ONAME && nr.Op == gc.ONAME && nl == nr {
- goto yes
- }
-
- switch nl.Type.Etype {
- // componentgen for arrays.
- case gc.TARRAY:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- t := nl.Type
- if !gc.Isslice(t) {
- nodl.Type = t.Type
- nodr.Type = nodl.Type
- for fldcount := int64(0); fldcount < t.Bound; fldcount++ {
- if nr == nil {
- gc.Clearslim(&nodl)
- } else {
- gmove(&nodr, &nodl)
- }
- nodl.Xoffset += t.Type.Width
- nodr.Xoffset += t.Type.Width
- }
-
- goto yes
- }
-
- // componentgen for slices.
- nodl.Xoffset += int64(gc.Array_array)
-
- nodl.Type = gc.Ptrto(nl.Type.Type)
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_cap) - int64(gc.Array_nel)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_cap) - int64(gc.Array_nel)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TSTRING:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- nodl.Xoffset += int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TINTER:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- nodl.Xoffset += int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TSTRUCT:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- loffset := nodl.Xoffset
- roffset := nodr.Xoffset
-
- // funarg structs may not begin at offset zero.
- if nl.Type.Etype == gc.TSTRUCT && nl.Type.Funarg != 0 && nl.Type.Type != nil {
- loffset -= nl.Type.Type.Width
- }
- if nr != nil && nr.Type.Etype == gc.TSTRUCT && nr.Type.Funarg != 0 && nr.Type.Type != nil {
- roffset -= nr.Type.Type.Width
- }
-
- for t := nl.Type.Type; t != nil; t = t.Down {
- nodl.Xoffset = loffset + t.Width
- nodl.Type = t.Type
-
- if nr == nil {
- gc.Clearslim(&nodl)
- } else {
- nodr.Xoffset = roffset + t.Width
- nodr.Type = nodl.Type
- gmove(&nodr, &nodl)
- }
- }
-
- goto yes
- }
-
-no:
- if freer != 0 {
- regfree(&nodr)
- }
- if freel != 0 {
- regfree(&nodl)
- }
- return false
-
-yes:
- if freer != 0 {
- regfree(&nodr)
- }
- if freel != 0 {
- regfree(&nodl)
- }
- return true
-}
gc.Thearch.Ginit = ginit
gc.Thearch.Gins = gins
gc.Thearch.Ginscall = ginscall
+ gc.Thearch.Gmove = gmove
gc.Thearch.Igen = igen
gc.Thearch.Linkarchinit = linkarchinit
gc.Thearch.Peep = peep
w := nl.Type.Width
// Avoid taking the address for simple enough types.
- if componentgen(nil, nl) {
+ if gc.Componentgen(nil, nl) {
return
}
}
// Avoid taking the address for simple enough types.
- //if(componentgen(n, ns))
- // return;
+ //if gc.Componentgen(n, ns) {
+ // return
+ //}
+
if w == 0 {
// evaluate side effects only.
var dst gc.Node
regfree(&src)
regfree(&tmp)
}
-
-func cadable(n *gc.Node) bool {
- if n.Addable == 0 {
- // dont know how it happens,
- // but it does
- return false
- }
-
- switch n.Op {
- case gc.ONAME:
- return true
- }
-
- return false
-}
-
-/*
- * copy a composite value by moving its individual components.
- * Slices, strings and interfaces are supported.
- * Small structs or arrays with elements of basic type are
- * also supported.
- * nr is N when assigning a zero value.
- * return 1 if can do, 0 if can't.
- */
-func componentgen(nr *gc.Node, nl *gc.Node) bool {
- var nodl gc.Node
- var nodr gc.Node
-
- freel := 0
- freer := 0
-
- switch nl.Type.Etype {
- default:
- goto no
-
- case gc.TARRAY:
- t := nl.Type
-
- // Slices are ok.
- if gc.Isslice(t) {
- break
- }
-
- // Small arrays are ok.
- if t.Bound > 0 && t.Bound <= 3 && !gc.Isfat(t.Type) {
- break
- }
-
- goto no
-
- // Small structs with non-fat types are ok.
- // Zero-sized structs are treated separately elsewhere.
- case gc.TSTRUCT:
- fldcount := int64(0)
-
- for t := nl.Type.Type; t != nil; t = t.Down {
- if gc.Isfat(t.Type) {
- goto no
- }
- if t.Etype != gc.TFIELD {
- gc.Fatal("componentgen: not a TFIELD: %v", gc.Tconv(t, obj.FmtLong))
- }
- fldcount++
- }
-
- if fldcount == 0 || fldcount > 4 {
- goto no
- }
-
- case gc.TSTRING,
- gc.TINTER:
- break
- }
-
- nodl = *nl
- if !cadable(nl) {
- if nr != nil && !cadable(nr) {
- goto no
- }
- igen(nl, &nodl, nil)
- freel = 1
- }
-
- if nr != nil {
- nodr = *nr
- if !cadable(nr) {
- igen(nr, &nodr, nil)
- freer = 1
- }
- } else {
- // When zeroing, prepare a register containing zero.
- var tmp gc.Node
- gc.Nodconst(&tmp, nl.Type, 0)
-
- regalloc(&nodr, gc.Types[gc.TUINT], nil)
- gmove(&tmp, &nodr)
- freer = 1
- }
-
- // nl and nr are 'cadable' which basically means they are names (variables) now.
- // If they are the same variable, don't generate any code, because the
- // VARDEF we generate will mark the old value as dead incorrectly.
- // (And also the assignments are useless.)
- if nr != nil && nl.Op == gc.ONAME && nr.Op == gc.ONAME && nl == nr {
- goto yes
- }
-
- switch nl.Type.Etype {
- // componentgen for arrays.
- case gc.TARRAY:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- t := nl.Type
- if !gc.Isslice(t) {
- nodl.Type = t.Type
- nodr.Type = nodl.Type
- for fldcount := int64(0); fldcount < t.Bound; fldcount++ {
- if nr == nil {
- gc.Clearslim(&nodl)
- } else {
- gmove(&nodr, &nodl)
- }
- nodl.Xoffset += t.Type.Width
- nodr.Xoffset += t.Type.Width
- }
-
- goto yes
- }
-
- // componentgen for slices.
- nodl.Xoffset += int64(gc.Array_array)
-
- nodl.Type = gc.Ptrto(nl.Type.Type)
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_cap) - int64(gc.Array_nel)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_cap) - int64(gc.Array_nel)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TSTRING:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- nodl.Xoffset += int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TINTER:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- nodl.Xoffset += int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TSTRUCT:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- loffset := nodl.Xoffset
- roffset := nodr.Xoffset
-
- // funarg structs may not begin at offset zero.
- if nl.Type.Etype == gc.TSTRUCT && nl.Type.Funarg != 0 && nl.Type.Type != nil {
- loffset -= nl.Type.Type.Width
- }
- if nr != nil && nr.Type.Etype == gc.TSTRUCT && nr.Type.Funarg != 0 && nr.Type.Type != nil {
- roffset -= nr.Type.Type.Width
- }
-
- for t := nl.Type.Type; t != nil; t = t.Down {
- nodl.Xoffset = loffset + t.Width
- nodl.Type = t.Type
-
- if nr == nil {
- gc.Clearslim(&nodl)
- } else {
- nodr.Xoffset = roffset + t.Width
- nodr.Type = nodl.Type
- gmove(&nodr, &nodl)
- }
- }
-
- goto yes
- }
-
-no:
- if freer != 0 {
- regfree(&nodr)
- }
- if freel != 0 {
- regfree(&nodl)
- }
- return false
-
-yes:
- if freer != 0 {
- regfree(&nodr)
- }
- if freel != 0 {
- regfree(&nodl)
- }
- return true
-}
gc.Thearch.Ginit = ginit
gc.Thearch.Gins = gins
gc.Thearch.Ginscall = ginscall
+ gc.Thearch.Gmove = gmove
gc.Thearch.Igen = igen
gc.Thearch.Linkarchinit = linkarchinit
gc.Thearch.Peep = peep
w := uint64(uint64(nl.Type.Width))
// Avoid taking the address for simple enough types.
- //if(componentgen(N, nl))
- // return;
+ //if gc.Componentgen(nil, nl) {
+ // return
+ //}
c := uint64(w % 8) // bytes
q := uint64(w / 8) // dwords
}
// Avoid taking the address for simple enough types.
- if componentgen(n, res) {
+ if gc.Componentgen(n, res) {
return
}
}
}
}
-
-func cadable(n *gc.Node) bool {
- if n.Addable == 0 {
- // dont know how it happens,
- // but it does
- return false
- }
-
- switch n.Op {
- case gc.ONAME:
- return true
- }
-
- return false
-}
-
-/*
- * copy a composite value by moving its individual components.
- * Slices, strings and interfaces are supported.
- * Small structs or arrays with elements of basic type are
- * also supported.
- * nr is N when assigning a zero value.
- * return 1 if can do, 0 if can't.
- */
-func componentgen(nr *gc.Node, nl *gc.Node) bool {
- var nodl gc.Node
- var nodr gc.Node
-
- freel := 0
- freer := 0
-
- switch nl.Type.Etype {
- default:
- goto no
-
- case gc.TARRAY:
- t := nl.Type
-
- // Slices are ok.
- if gc.Isslice(t) {
- break
- }
-
- // Small arrays are ok.
- if t.Bound > 0 && t.Bound <= 3 && !gc.Isfat(t.Type) {
- break
- }
-
- goto no
-
- // Small structs with non-fat types are ok.
- // Zero-sized structs are treated separately elsewhere.
- case gc.TSTRUCT:
- fldcount := int64(0)
-
- for t := nl.Type.Type; t != nil; t = t.Down {
- if gc.Isfat(t.Type) {
- goto no
- }
- if t.Etype != gc.TFIELD {
- gc.Fatal("componentgen: not a TFIELD: %v", gc.Tconv(t, obj.FmtLong))
- }
- fldcount++
- }
-
- if fldcount == 0 || fldcount > 4 {
- goto no
- }
-
- case gc.TSTRING,
- gc.TINTER:
- break
- }
-
- nodl = *nl
- if !cadable(nl) {
- if nr != nil && !cadable(nr) {
- goto no
- }
- igen(nl, &nodl, nil)
- freel = 1
- }
-
- if nr != nil {
- nodr = *nr
- if !cadable(nr) {
- igen(nr, &nodr, nil)
- freer = 1
- }
- } else {
- // When zeroing, prepare a register containing zero.
- var tmp gc.Node
- gc.Nodconst(&tmp, nl.Type, 0)
-
- regalloc(&nodr, gc.Types[gc.TUINT], nil)
- gmove(&tmp, &nodr)
- freer = 1
- }
-
- // nl and nr are 'cadable' which basically means they are names (variables) now.
- // If they are the same variable, don't generate any code, because the
- // VARDEF we generate will mark the old value as dead incorrectly.
- // (And also the assignments are useless.)
- if nr != nil && nl.Op == gc.ONAME && nr.Op == gc.ONAME && nl == nr {
- goto yes
- }
-
- switch nl.Type.Etype {
- // componentgen for arrays.
- case gc.TARRAY:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- t := nl.Type
- if !gc.Isslice(t) {
- nodl.Type = t.Type
- nodr.Type = nodl.Type
- for fldcount := int64(0); fldcount < t.Bound; fldcount++ {
- if nr == nil {
- gc.Clearslim(&nodl)
- } else {
- gmove(&nodr, &nodl)
- }
- nodl.Xoffset += t.Type.Width
- nodr.Xoffset += t.Type.Width
- }
-
- goto yes
- }
-
- // componentgen for slices.
- nodl.Xoffset += int64(gc.Array_array)
-
- nodl.Type = gc.Ptrto(nl.Type.Type)
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_cap) - int64(gc.Array_nel)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_cap) - int64(gc.Array_nel)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TSTRING:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- nodl.Xoffset += int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TINTER:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- nodl.Xoffset += int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TSTRUCT:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- loffset := nodl.Xoffset
- roffset := nodr.Xoffset
-
- // funarg structs may not begin at offset zero.
- if nl.Type.Etype == gc.TSTRUCT && nl.Type.Funarg != 0 && nl.Type.Type != nil {
- loffset -= nl.Type.Type.Width
- }
- if nr != nil && nr.Type.Etype == gc.TSTRUCT && nr.Type.Funarg != 0 && nr.Type.Type != nil {
- roffset -= nr.Type.Type.Width
- }
-
- for t := nl.Type.Type; t != nil; t = t.Down {
- nodl.Xoffset = loffset + t.Width
- nodl.Type = t.Type
-
- if nr == nil {
- gc.Clearslim(&nodl)
- } else {
- nodr.Xoffset = roffset + t.Width
- nodr.Type = nodl.Type
- gmove(&nodr, &nodl)
- }
- }
-
- goto yes
- }
-
-no:
- if freer != 0 {
- regfree(&nodr)
- }
- if freel != 0 {
- regfree(&nodl)
- }
- return false
-
-yes:
- if freer != 0 {
- regfree(&nodr)
- }
- if freel != 0 {
- regfree(&nodl)
- }
- return true
-}
gc.Thearch.Ginit = ginit
gc.Thearch.Gins = gins
gc.Thearch.Ginscall = ginscall
+ gc.Thearch.Gmove = gmove
gc.Thearch.Igen = igen
gc.Thearch.Linkarchinit = linkarchinit
gc.Thearch.Peep = peep
w := uint32(nl.Type.Width)
// Avoid taking the address for simple enough types.
- if componentgen(nil, nl) {
+ if gc.Componentgen(nil, nl) {
return
}
}
// Avoid taking the address for simple enough types.
- //if(componentgen(n, ns))
- // return;
+ if gc.Componentgen(n, ns) {
+ return
+ }
+
if w == 0 {
// evaluate side effects only.
var dst gc.Node
regfree(&src)
regfree(&tmp)
}
-
-func cadable(n *gc.Node) bool {
- if n.Addable == 0 {
- // dont know how it happens,
- // but it does
- return false
- }
-
- switch n.Op {
- case gc.ONAME:
- return true
- }
-
- return false
-}
-
-/*
- * copy a composite value by moving its individual components.
- * Slices, strings and interfaces are supported.
- * Small structs or arrays with elements of basic type are
- * also supported.
- * nr is N when assigning a zero value.
- * return 1 if can do, 0 if can't.
- */
-func componentgen(nr *gc.Node, nl *gc.Node) bool {
- var nodl gc.Node
- var nodr gc.Node
-
- freel := 0
- freer := 0
-
- switch nl.Type.Etype {
- default:
- goto no
-
- case gc.TARRAY:
- t := nl.Type
-
- // Slices are ok.
- if gc.Isslice(t) {
- break
- }
-
- // Small arrays are ok.
- if t.Bound > 0 && t.Bound <= 3 && !gc.Isfat(t.Type) {
- break
- }
-
- goto no
-
- // Small structs with non-fat types are ok.
- // Zero-sized structs are treated separately elsewhere.
- case gc.TSTRUCT:
- fldcount := int64(0)
-
- for t := nl.Type.Type; t != nil; t = t.Down {
- if gc.Isfat(t.Type) {
- goto no
- }
- if t.Etype != gc.TFIELD {
- gc.Fatal("componentgen: not a TFIELD: %v", gc.Tconv(t, obj.FmtLong))
- }
- fldcount++
- }
-
- if fldcount == 0 || fldcount > 4 {
- goto no
- }
-
- case gc.TSTRING,
- gc.TINTER:
- break
- }
-
- nodl = *nl
- if !cadable(nl) {
- if nr != nil && !cadable(nr) {
- goto no
- }
- igen(nl, &nodl, nil)
- freel = 1
- }
-
- if nr != nil {
- nodr = *nr
- if !cadable(nr) {
- igen(nr, &nodr, nil)
- freer = 1
- }
- } else {
- // When zeroing, prepare a register containing zero.
- var tmp gc.Node
- gc.Nodconst(&tmp, nl.Type, 0)
-
- regalloc(&nodr, gc.Types[gc.TUINT], nil)
- gmove(&tmp, &nodr)
- freer = 1
- }
-
- // nl and nr are 'cadable' which basically means they are names (variables) now.
- // If they are the same variable, don't generate any code, because the
- // VARDEF we generate will mark the old value as dead incorrectly.
- // (And also the assignments are useless.)
- if nr != nil && nl.Op == gc.ONAME && nr.Op == gc.ONAME && nl == nr {
- goto yes
- }
-
- switch nl.Type.Etype {
- // componentgen for arrays.
- case gc.TARRAY:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- t := nl.Type
- if !gc.Isslice(t) {
- nodl.Type = t.Type
- nodr.Type = nodl.Type
- for fldcount := int64(0); fldcount < t.Bound; fldcount++ {
- if nr == nil {
- gc.Clearslim(&nodl)
- } else {
- gmove(&nodr, &nodl)
- }
- nodl.Xoffset += t.Type.Width
- nodr.Xoffset += t.Type.Width
- }
-
- goto yes
- }
-
- // componentgen for slices.
- nodl.Xoffset += int64(gc.Array_array)
-
- nodl.Type = gc.Ptrto(nl.Type.Type)
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_cap) - int64(gc.Array_nel)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_cap) - int64(gc.Array_nel)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TSTRING:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- nodl.Xoffset += int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Types[gc.Simtype[gc.TUINT]]
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TINTER:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- nodl.Xoffset += int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- nodl.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodl.Type = gc.Ptrto(gc.Types[gc.TUINT8])
-
- if nr != nil {
- nodr.Xoffset += int64(gc.Array_nel) - int64(gc.Array_array)
- nodr.Type = nodl.Type
- }
-
- gmove(&nodr, &nodl)
-
- goto yes
-
- case gc.TSTRUCT:
- if nl.Op == gc.ONAME {
- gc.Gvardef(nl)
- }
- loffset := nodl.Xoffset
- roffset := nodr.Xoffset
-
- // funarg structs may not begin at offset zero.
- if nl.Type.Etype == gc.TSTRUCT && nl.Type.Funarg != 0 && nl.Type.Type != nil {
- loffset -= nl.Type.Type.Width
- }
- if nr != nil && nr.Type.Etype == gc.TSTRUCT && nr.Type.Funarg != 0 && nr.Type.Type != nil {
- roffset -= nr.Type.Type.Width
- }
-
- for t := nl.Type.Type; t != nil; t = t.Down {
- nodl.Xoffset = loffset + t.Width
- nodl.Type = t.Type
-
- if nr == nil {
- gc.Clearslim(&nodl)
- } else {
- nodr.Xoffset = roffset + t.Width
- nodr.Type = nodl.Type
- gmove(&nodr, &nodl)
- }
- }
-
- goto yes
- }
-
-no:
- if freer != 0 {
- regfree(&nodr)
- }
- if freel != 0 {
- regfree(&nodl)
- }
- return false
-
-yes:
- if freer != 0 {
- regfree(&nodr)
- }
- if freel != 0 {
- regfree(&nodl)
- }
- return true
-}
gc.Thearch.Ginit = ginit
gc.Thearch.Gins = gins
gc.Thearch.Ginscall = ginscall
+ gc.Thearch.Gmove = gmove
gc.Thearch.Igen = igen
gc.Thearch.Linkarchinit = linkarchinit
gc.Thearch.Peep = peep
w := uint64(uint64(nl.Type.Width))
// Avoid taking the address for simple enough types.
- //if(componentgen(N, nl))
- // return;
+ if gc.Componentgen(nil, nl) {
+ return
+ }
c := uint64(w % 8) // bytes
q := uint64(w / 8) // dwords
}
}
}
+
+/*
+ * copy a composite value by moving its individual components.
+ * Slices, strings and interfaces are supported.
+ * Small structs or arrays with elements of basic type are
+ * also supported.
+ * nr is N when assigning a zero value.
+ * return 1 if can do, 0 if can't.
+ */
+func Componentgen(nr *Node, nl *Node) bool {
+ var nodl Node
+ var nodr Node
+
+ freel := 0
+ freer := 0
+
+ switch nl.Type.Etype {
+ default:
+ goto no
+
+ case TARRAY:
+ t := nl.Type
+
+ // Slices are ok.
+ if Isslice(t) {
+ break
+ }
+
+ // Small arrays are ok.
+ if t.Bound > 0 && t.Bound <= 3 && !Isfat(t.Type) {
+ break
+ }
+
+ goto no
+
+ // Small structs with non-fat types are ok.
+ // Zero-sized structs are treated separately elsewhere.
+ case TSTRUCT:
+ fldcount := int64(0)
+
+ for t := nl.Type.Type; t != nil; t = t.Down {
+ if Isfat(t.Type) && !Isslice(t) {
+ goto no
+ }
+ if t.Etype != TFIELD {
+ Fatal("componentgen: not a TFIELD: %v", Tconv(t, obj.FmtLong))
+ }
+ fldcount++
+ }
+
+ if fldcount == 0 || fldcount > 4 {
+ goto no
+ }
+
+ case TSTRING,
+ TINTER:
+ break
+ }
+
+ nodl = *nl
+ if !cadable(nl) {
+ if nr != nil && !cadable(nr) {
+ goto no
+ }
+ Thearch.Igen(nl, &nodl, nil)
+ freel = 1
+ }
+
+ if nr != nil {
+ nodr = *nr
+ if !cadable(nr) {
+ Thearch.Igen(nr, &nodr, nil)
+ freer = 1
+ }
+ } else {
+ // When zeroing, prepare a register containing zero.
+ var tmp Node
+ Nodconst(&tmp, nl.Type, 0)
+
+ Thearch.Regalloc(&nodr, Types[TUINT], nil)
+ Thearch.Gmove(&tmp, &nodr)
+ freer = 1
+ }
+
+ // nl and nr are 'cadable' which basically means they are names (variables) now.
+ // If they are the same variable, don't generate any code, because the
+ // VARDEF we generate will mark the old value as dead incorrectly.
+ // (And also the assignments are useless.)
+ if nr != nil && nl.Op == ONAME && nr.Op == ONAME && nl == nr {
+ goto yes
+ }
+
+ switch nl.Type.Etype {
+ // componentgen for arrays.
+ case TARRAY:
+ if nl.Op == ONAME {
+ Gvardef(nl)
+ }
+ t := nl.Type
+ if !Isslice(t) {
+ nodl.Type = t.Type
+ nodr.Type = nodl.Type
+ for fldcount := int64(0); fldcount < t.Bound; fldcount++ {
+ if nr == nil {
+ Clearslim(&nodl)
+ } else {
+ Thearch.Gmove(&nodr, &nodl)
+ }
+ nodl.Xoffset += t.Type.Width
+ nodr.Xoffset += t.Type.Width
+ }
+
+ goto yes
+ }
+
+ // componentgen for slices.
+ nodl.Xoffset += int64(Array_array)
+
+ nodl.Type = Ptrto(nl.Type.Type)
+
+ if nr != nil {
+ nodr.Xoffset += int64(Array_array)
+ nodr.Type = nodl.Type
+ }
+
+ Thearch.Gmove(&nodr, &nodl)
+
+ nodl.Xoffset += int64(Array_nel) - int64(Array_array)
+ nodl.Type = Types[Simtype[TUINT]]
+
+ if nr != nil {
+ nodr.Xoffset += int64(Array_nel) - int64(Array_array)
+ nodr.Type = nodl.Type
+ }
+
+ Thearch.Gmove(&nodr, &nodl)
+
+ nodl.Xoffset += int64(Array_cap) - int64(Array_nel)
+ nodl.Type = Types[Simtype[TUINT]]
+
+ if nr != nil {
+ nodr.Xoffset += int64(Array_cap) - int64(Array_nel)
+ nodr.Type = nodl.Type
+ }
+
+ Thearch.Gmove(&nodr, &nodl)
+
+ goto yes
+
+ case TSTRING:
+ if nl.Op == ONAME {
+ Gvardef(nl)
+ }
+ nodl.Xoffset += int64(Array_array)
+ nodl.Type = Ptrto(Types[TUINT8])
+
+ if nr != nil {
+ nodr.Xoffset += int64(Array_array)
+ nodr.Type = nodl.Type
+ }
+
+ Thearch.Gmove(&nodr, &nodl)
+
+ nodl.Xoffset += int64(Array_nel) - int64(Array_array)
+ nodl.Type = Types[Simtype[TUINT]]
+
+ if nr != nil {
+ nodr.Xoffset += int64(Array_nel) - int64(Array_array)
+ nodr.Type = nodl.Type
+ }
+
+ Thearch.Gmove(&nodr, &nodl)
+
+ goto yes
+
+ case TINTER:
+ if nl.Op == ONAME {
+ Gvardef(nl)
+ }
+ nodl.Xoffset += int64(Array_array)
+ nodl.Type = Ptrto(Types[TUINT8])
+
+ if nr != nil {
+ nodr.Xoffset += int64(Array_array)
+ nodr.Type = nodl.Type
+ }
+
+ Thearch.Gmove(&nodr, &nodl)
+
+ nodl.Xoffset += int64(Array_nel) - int64(Array_array)
+ nodl.Type = Ptrto(Types[TUINT8])
+
+ if nr != nil {
+ nodr.Xoffset += int64(Array_nel) - int64(Array_array)
+ nodr.Type = nodl.Type
+ }
+
+ Thearch.Gmove(&nodr, &nodl)
+
+ goto yes
+
+ case TSTRUCT:
+ if nl.Op == ONAME {
+ Gvardef(nl)
+ }
+ loffset := nodl.Xoffset
+ roffset := nodr.Xoffset
+
+ // funarg structs may not begin at offset zero.
+ if nl.Type.Etype == TSTRUCT && nl.Type.Funarg != 0 && nl.Type.Type != nil {
+ loffset -= nl.Type.Type.Width
+ }
+ if nr != nil && nr.Type.Etype == TSTRUCT && nr.Type.Funarg != 0 && nr.Type.Type != nil {
+ roffset -= nr.Type.Type.Width
+ }
+
+ for t := nl.Type.Type; t != nil; t = t.Down {
+ nodl.Xoffset = loffset + t.Width
+ nodl.Type = t.Type
+
+ if nr == nil {
+ Clearslim(&nodl)
+ } else {
+ nodr.Xoffset = roffset + t.Width
+ nodr.Type = nodl.Type
+ Thearch.Gmove(&nodr, &nodl)
+ }
+ }
+
+ goto yes
+ }
+
+no:
+ if freer != 0 {
+ Thearch.Regfree(&nodr)
+ }
+ if freel != 0 {
+ Thearch.Regfree(&nodl)
+ }
+ return false
+
+yes:
+ if freer != 0 {
+ Thearch.Regfree(&nodr)
+ }
+ if freel != 0 {
+ Thearch.Regfree(&nodl)
+ }
+ return true
+}
+
+func cadable(n *Node) bool {
+ if n.Addable == 0 {
+ // dont know how it happens,
+ // but it does
+ return false
+ }
+
+ switch n.Op {
+ case ONAME:
+ return true
+ }
+
+ return false
+}
Ginit func()
Gins func(int, *Node, *Node) *obj.Prog
Ginscall func(*Node, int)
+ Gmove func(*Node, *Node)
Igen func(*Node, *Node, *Node)
Linkarchinit func()
Peep func(*obj.Prog)