/* * generate function call; * proc=0 normal call * proc=1 goroutine run in new proc * proc=2 defer call save away stack */ func cgen_call(n *gc.Node, proc int) { if n == nil { return } var afun gc.Node if n.Left.Ullman >= gc.UINF { // if name involves a fn call // precompute the address of the fn gc.Tempname(&afun, gc.Types[gc.Tptr]) cgen(n.Left, &afun) } gc.Genlist(n.List) // assign the args t := n.Left.Type // call tempname pointer if n.Left.Ullman >= gc.UINF { var nod gc.Node regalloc(&nod, gc.Types[gc.Tptr], nil) gc.Cgen_as(&nod, &afun) nod.Type = t ginscall(&nod, proc) regfree(&nod) return } // call pointer if n.Left.Op != gc.ONAME || n.Left.Class != gc.PFUNC { var nod gc.Node regalloc(&nod, gc.Types[gc.Tptr], nil) gc.Cgen_as(&nod, n.Left) nod.Type = t ginscall(&nod, proc) regfree(&nod) return } // call direct n.Left.Method = 1 ginscall(n.Left, proc) }
/* * call to n has already been generated. * generate: * res = return value from call. */ func cgen_callret(n *gc.Node, res *gc.Node) { t := n.Left.Type if t.Etype == gc.TPTR32 || t.Etype == gc.TPTR64 { t = t.Type } var flist gc.Iter fp := gc.Structfirst(&flist, gc.Getoutarg(t)) if fp == nil { gc.Fatal("cgen_callret: nil") } var nod gc.Node nod.Op = gc.OINDREG nod.Val.U.Reg = x86.REG_SP nod.Addable = 1 nod.Xoffset = fp.Width nod.Type = fp.Type gc.Cgen_as(res, &nod) }