implement some more 8g

	package main
	func main() {
		println("hello,", 123);
	}

R=ken
OCL=27043
CL=27043
diff --git a/src/cmd/8g/gen.c b/src/cmd/8g/gen.c
index 9f57464..d610dc0 100644
--- a/src/cmd/8g/gen.c
+++ b/src/cmd/8g/gen.c
@@ -84,7 +84,10 @@
 	ptxt->to.offset2 = rnd(curfn->type->argwid, maxround);
 
 	// fill in final stack size
-	ptxt->to.offset = rnd(stksize+maxarg, maxround);
+	if(stksize > maxstksize)
+		maxstksize = stksize;
+	ptxt->to.offset = rnd(maxstksize+maxarg, maxround);
+	maxstksize = 0;
 
 	if(debug['f'])
 		frame(0);
@@ -157,7 +160,115 @@
 void
 cgen_call(Node *n, int proc)
 {
-	fatal("cgen_call");
+	Type *t;
+	Node nod, afun;
+
+	if(n == N)
+		return;
+
+	if(n->left->ullman >= UINF) {
+		// if name involves a fn call
+		// precompute the address of the fn
+		tempalloc(&afun, types[tptr]);
+		cgen(n->left, &afun);
+	}
+
+	gen(n->right);		// assign the args
+	t = n->left->type;
+
+	setmaxarg(t);
+
+	// call tempname pointer
+	if(n->left->ullman >= UINF) {
+		regalloc(&nod, types[tptr], N);
+		cgen_as(&nod, &afun);
+		tempfree(&afun);
+		nod.type = t;
+		ginscall(&nod, proc);
+		regfree(&nod);
+		return;
+	}
+
+	// call pointer
+	if(n->left->op != ONAME || n->left->class != PFUNC) {
+		regalloc(&nod, types[tptr], N);
+		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.
+ */
+void
+cgen_callret(Node *n, Node *res)
+{
+	Node nod;
+	Type *fp, *t;
+	Iter flist;
+
+	t = n->left->type;
+	if(t->etype == TPTR32 || t->etype == TPTR64)
+		t = t->type;
+
+	fp = structfirst(&flist, getoutarg(t));
+	if(fp == T)
+		fatal("cgen_callret: nil");
+
+	memset(&nod, 0, sizeof(nod));
+	nod.op = OINDREG;
+	nod.val.u.reg = D_SP;
+	nod.addable = 1;
+
+	nod.xoffset = fp->width;
+	nod.type = fp->type;
+	cgen_as(res, &nod);
+}
+
+/*
+ * call to n has already been generated.
+ * generate:
+ *	res = &return value from call.
+ */
+void
+cgen_aret(Node *n, Node *res)
+{
+	Node nod1, nod2;
+	Type *fp, *t;
+	Iter flist;
+
+	t = n->left->type;
+	if(isptr[t->etype])
+		t = t->type;
+
+	fp = structfirst(&flist, getoutarg(t));
+	if(fp == T)
+		fatal("cgen_aret: nil");
+
+	memset(&nod1, 0, sizeof(nod1));
+	nod1.op = OINDREG;
+	nod1.val.u.reg = D_SP;
+	nod1.addable = 1;
+
+	nod1.xoffset = fp->width;
+	nod1.type = fp->type;
+
+	if(res->op != OREGISTER) {
+		regalloc(&nod2, types[tptr], res);
+		gins(ALEAL, &nod1, &nod2);
+		gins(AMOVL, &nod2, res);
+		regfree(&nod2);
+	} else
+		gins(ALEAL, &nod1, res);
 }
 
 /*
@@ -182,3 +293,37 @@
 	fatal("cgen_asop");
 }
 
+/*
+ * generate division according to op, one of:
+ *	res = nl / nr
+ *	res = nl % nr
+ */
+void
+cgen_div(int op, Node *nl, Node *nr, Node *res)
+{
+	fatal("cgen_div");
+}
+
+/*
+ * generate shift according to op, one of:
+ *	res = nl << nr
+ *	res = nl >> nr
+ */
+void
+cgen_shift(int op, Node *nl, Node *nr, Node *res)
+{
+	fatal("cgen_shift");
+}
+
+/*
+ * generate byte multiply:
+ *	res = nl * nr
+ * no byte multiply instruction so have to do
+ * 16-bit multiply and take bottom half.
+ */
+void
+cgen_bmul(int op, Node *nl, Node *nr, Node *res)
+{
+	fatal("cgen_bmul");
+}
+