本文整理匯總了Golang中cmd/internal/gc.Gvardef函數的典型用法代碼示例。如果您正苦於以下問題:Golang Gvardef函數的具體用法?Golang Gvardef怎麽用?Golang Gvardef使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了Gvardef函數的5個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: agen
/*
* generate:
* res = &n;
* The generated code checks that the result is not nil.
*/
func agen(n *gc.Node, res *gc.Node) {
if gc.Debug['g'] != 0 {
gc.Dump("\nagen-res", res)
gc.Dump("agen-r", n)
}
if n == nil || n.Type == nil {
return
}
for n.Op == gc.OCONVNOP {
n = n.Left
}
if gc.Isconst(n, gc.CTNIL) && n.Type.Width > int64(gc.Widthptr) {
// Use of a nil interface or nil slice.
// Create a temporary we can take the address of and read.
// The generated code is just going to panic, so it need not
// be terribly efficient. See issue 3670.
var n1 gc.Node
gc.Tempname(&n1, n.Type)
gc.Gvardef(&n1)
clearfat(&n1)
var n2 gc.Node
regalloc(&n2, gc.Types[gc.Tptr], res)
var n3 gc.Node
n3.Op = gc.OADDR
n3.Left = &n1
gins(ppc64.AMOVD, &n3, &n2)
gmove(&n2, res)
regfree(&n2)
return
}
if n.Addable != 0 {
var n1 gc.Node
n1.Op = gc.OADDR
n1.Left = n
var n2 gc.Node
regalloc(&n2, gc.Types[gc.Tptr], res)
gins(ppc64.AMOVD, &n1, &n2)
gmove(&n2, res)
regfree(&n2)
return
}
nl := n.Left
switch n.Op {
default:
gc.Fatal("agen: unknown op %v", gc.Nconv(n, obj.FmtShort|obj.FmtSign))
// TODO(minux): 5g has this: Release res so that it is available for cgen_call.
// Pick it up again after the call for OCALLMETH and OCALLFUNC.
case gc.OCALLMETH:
gc.Cgen_callmeth(n, 0)
cgen_aret(n, res)
case gc.OCALLINTER:
cgen_callinter(n, res, 0)
cgen_aret(n, res)
case gc.OCALLFUNC:
cgen_call(n, 0)
cgen_aret(n, res)
case gc.OSLICE,
gc.OSLICEARR,
gc.OSLICESTR,
gc.OSLICE3,
gc.OSLICE3ARR:
var n1 gc.Node
gc.Tempname(&n1, n.Type)
gc.Cgen_slice(n, &n1)
agen(&n1, res)
case gc.OEFACE:
var n1 gc.Node
gc.Tempname(&n1, n.Type)
gc.Cgen_eface(n, &n1)
agen(&n1, res)
case gc.OINDEX:
var n1 gc.Node
agenr(n, &n1, res)
gmove(&n1, res)
regfree(&n1)
// should only get here with names in this func.
case gc.ONAME:
if n.Funcdepth > 0 && n.Funcdepth != gc.Funcdepth {
gc.Dump("bad agen", n)
gc.Fatal("agen: bad ONAME funcdepth %d != %d", n.Funcdepth, gc.Funcdepth)
//.........這裏部分代碼省略.........
示例2: stackcopy
func stackcopy(n, ns *gc.Node, osrc, odst, w int64) {
var noddi gc.Node
gc.Nodreg(&noddi, gc.Types[gc.Tptr], x86.REG_DI)
var nodsi gc.Node
gc.Nodreg(&nodsi, gc.Types[gc.Tptr], x86.REG_SI)
var nodl gc.Node
var nodr gc.Node
if n.Ullman >= ns.Ullman {
gc.Agenr(n, &nodr, &nodsi)
if ns.Op == gc.ONAME {
gc.Gvardef(ns)
}
gc.Agenr(ns, &nodl, &noddi)
} else {
if ns.Op == gc.ONAME {
gc.Gvardef(ns)
}
gc.Agenr(ns, &nodl, &noddi)
gc.Agenr(n, &nodr, &nodsi)
}
if nodl.Val.U.Reg != x86.REG_DI {
gmove(&nodl, &noddi)
}
if nodr.Val.U.Reg != x86.REG_SI {
gmove(&nodr, &nodsi)
}
gc.Regfree(&nodl)
gc.Regfree(&nodr)
c := w % 8 // bytes
q := w / 8 // quads
var oldcx gc.Node
var cx gc.Node
savex(x86.REG_CX, &cx, &oldcx, nil, gc.Types[gc.TINT64])
// if we are copying forward on the stack and
// the src and dst overlap, then reverse direction
if osrc < odst && odst < osrc+w {
// reverse direction
gins(x86.ASTD, nil, nil) // set direction flag
if c > 0 {
gconreg(addptr, w-1, x86.REG_SI)
gconreg(addptr, w-1, x86.REG_DI)
gconreg(movptr, c, x86.REG_CX)
gins(x86.AREP, nil, nil) // repeat
gins(x86.AMOVSB, nil, nil) // MOVB *(SI)-,*(DI)-
}
if q > 0 {
if c > 0 {
gconreg(addptr, -7, x86.REG_SI)
gconreg(addptr, -7, x86.REG_DI)
} else {
gconreg(addptr, w-8, x86.REG_SI)
gconreg(addptr, w-8, x86.REG_DI)
}
gconreg(movptr, q, x86.REG_CX)
gins(x86.AREP, nil, nil) // repeat
gins(x86.AMOVSQ, nil, nil) // MOVQ *(SI)-,*(DI)-
}
// we leave with the flag clear
gins(x86.ACLD, nil, nil)
} else {
// normal direction
if q > 128 || (gc.Nacl && q >= 4) {
gconreg(movptr, q, x86.REG_CX)
gins(x86.AREP, nil, nil) // repeat
gins(x86.AMOVSQ, nil, nil) // MOVQ *(SI)+,*(DI)+
} else if q >= 4 {
p := gins(obj.ADUFFCOPY, nil, nil)
p.To.Type = obj.TYPE_ADDR
p.To.Sym = gc.Linksym(gc.Pkglookup("duffcopy", gc.Runtimepkg))
// 14 and 128 = magic constants: see ../../runtime/asm_amd64.s
p.To.Offset = 14 * (128 - q)
} else if !gc.Nacl && c == 0 {
// We don't need the MOVSQ side-effect of updating SI and DI,
// and issuing a sequence of MOVQs directly is faster.
nodsi.Op = gc.OINDREG
noddi.Op = gc.OINDREG
for q > 0 {
gmove(&nodsi, &cx) // MOVQ x+(SI),CX
gmove(&cx, &noddi) // MOVQ CX,x+(DI)
nodsi.Xoffset += 8
noddi.Xoffset += 8
q--
}
} else {
for q > 0 {
gins(x86.AMOVSQ, nil, nil) // MOVQ *(SI)+,*(DI)+
q--
}
}
//.........這裏部分代碼省略.........
示例3: sgen
/*
* block copy:
* memmove(&ns, &n, w);
*/
func sgen(n *gc.Node, ns *gc.Node, w int64) {
var res *gc.Node = ns
if gc.Debug['g'] != 0 {
fmt.Printf("\nsgen w=%d\n", w)
gc.Dump("r", n)
gc.Dump("res", ns)
}
if n.Ullman >= gc.UINF && ns.Ullman >= gc.UINF {
gc.Fatal("sgen UINF")
}
if w < 0 {
gc.Fatal("sgen copy %d", w)
}
// If copying .args, that's all the results, so record definition sites
// for them for the liveness analysis.
if ns.Op == gc.ONAME && ns.Sym.Name == ".args" {
for l := gc.Curfn.Dcl; l != nil; l = l.Next {
if l.N.Class == gc.PPARAMOUT {
gc.Gvardef(l.N)
}
}
}
// Avoid taking the address for simple enough types.
//if(componentgen(n, ns))
// return;
if w == 0 {
// evaluate side effects only.
var dst gc.Node
regalloc(&dst, gc.Types[gc.Tptr], nil)
agen(res, &dst)
agen(n, &dst)
regfree(&dst)
return
}
// determine alignment.
// want to avoid unaligned access, so have to use
// smaller operations for less aligned types.
// for example moving [4]byte must use 4 MOVB not 1 MOVW.
align := int(n.Type.Align)
var op int
switch align {
default:
gc.Fatal("sgen: invalid alignment %d for %v", align, gc.Tconv(n.Type, 0))
case 1:
op = ppc64.AMOVBU
case 2:
op = ppc64.AMOVHU
case 4:
op = ppc64.AMOVWZU // there is no lwau, only lwaux
case 8:
op = ppc64.AMOVDU
}
if w%int64(align) != 0 {
gc.Fatal("sgen: unaligned size %d (align=%d) for %v", w, align, gc.Tconv(n.Type, 0))
}
c := int32(w / int64(align))
// offset on the stack
osrc := int32(stkof(n))
odst := int32(stkof(res))
if osrc != -1000 && odst != -1000 && (osrc == 1000 || odst == 1000) {
// osrc and odst both on stack, and at least one is in
// an unknown position. Could generate code to test
// for forward/backward copy, but instead just copy
// to a temporary location first.
var tmp gc.Node
gc.Tempname(&tmp, n.Type)
sgen(n, &tmp, w)
sgen(&tmp, res, w)
return
}
if osrc%int32(align) != 0 || odst%int32(align) != 0 {
gc.Fatal("sgen: unaligned offset src %d or dst %d (align %d)", osrc, odst, align)
}
// if we are copying forward on the stack and
// the src and dst overlap, then reverse direction
dir := align
if osrc < odst && int64(odst) < int64(osrc)+w {
//.........這裏部分代碼省略.........
示例4: componentgen
/*
* 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
//.........這裏部分代碼省略.........
示例5: blockcopy
func blockcopy(n, res *gc.Node, osrc, odst, w int64) {
// determine alignment.
// want to avoid unaligned access, so have to use
// smaller operations for less aligned types.
// for example moving [4]byte must use 4 MOVB not 1 MOVW.
align := int(n.Type.Align)
var op int
switch align {
default:
gc.Fatal("sgen: invalid alignment %d for %v", align, n.Type)
case 1:
op = ppc64.AMOVBU
case 2:
op = ppc64.AMOVHU
case 4:
op = ppc64.AMOVWZU // there is no lwau, only lwaux
case 8:
op = ppc64.AMOVDU
}
if w%int64(align) != 0 {
gc.Fatal("sgen: unaligned size %d (align=%d) for %v", w, align, n.Type)
}
c := int32(w / int64(align))
// if we are copying forward on the stack and
// the src and dst overlap, then reverse direction
dir := align
if osrc < odst && int64(odst) < int64(osrc)+w {
dir = -dir
}
var dst gc.Node
var src gc.Node
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)
if res.Op == gc.ONAME {
gc.Gvardef(res)
}
gc.Agen(res, &dst)
} else {
if res.Op == gc.ONAME {
gc.Gvardef(res)
}
gc.Agenr(res, &dst, res)
gc.Agenr(n, &src, nil)
}
var tmp gc.Node
gc.Regalloc(&tmp, gc.Types[gc.Tptr], nil)
// set up end marker
var nend gc.Node
// move src and dest to the end of block if necessary
if dir < 0 {
if c >= 4 {
gc.Regalloc(&nend, gc.Types[gc.Tptr], nil)
gins(ppc64.AMOVD, &src, &nend)
}
p := gins(ppc64.AADD, nil, &src)
p.From.Type = obj.TYPE_CONST
p.From.Offset = w
p = gins(ppc64.AADD, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = w
} else {
p := gins(ppc64.AADD, nil, &src)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-dir)
p = gins(ppc64.AADD, 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.From.Type = obj.TYPE_ADDR
p.From.Offset = w
}
}
// move
// TODO: enable duffcopy for larger copies.
if c >= 4 {
p := gins(op, &src, &tmp)
p.From.Type = obj.TYPE_MEM
p.From.Offset = int64(dir)
ploop := p
//.........這裏部分代碼省略.........