gc: allow taking address of out parameters

Fixes #186.

R=ken2
CC=golang-dev
https://golang.org/cl/793041
diff --git a/src/cmd/8g/ggen.c b/src/cmd/8g/ggen.c
index 23177c2..468f67a 100644
--- a/src/cmd/8g/ggen.c
+++ b/src/cmd/8g/ggen.c
@@ -7,6 +7,8 @@
 #include "gg.h"
 #include "opt.h"
 
+static Prog *pret;
+
 void
 compile(Node *fn)
 {
@@ -66,6 +68,16 @@
 
 	ginit();
 	genlist(curfn->enter);
+
+	pret = nil;
+	if(hasdefer || curfn->exit) {
+		Prog *p1;
+
+		p1 = gjmp(nil);
+		pret = gjmp(nil);
+		patch(p1, pc);
+	}
+
 	genlist(curfn->nbody);
 	gclean();
 	checklabels();
@@ -75,6 +87,14 @@
 	if(curfn->type->outtuple != 0)
 		ginscall(throwreturn, 0);
 
+	if(pret)
+		patch(pret, pc);
+	ginit();
+	if(curfn->exit)
+		genlist(curfn->exit);
+	gclean();
+	if(nerrors != 0)
+		goto ret;
 	if(hasdefer)
 		ginscall(deferreturn, 0);
 	pc->as = ARET;	// overwrite AEND
@@ -362,9 +382,10 @@
 cgen_ret(Node *n)
 {
 	genlist(n->list);		// copy out args
-	if(hasdefer)
-		ginscall(deferreturn, 0);
-	gins(ARET, N, N);
+	if(pret)
+		gjmp(pret);
+	else
+		gins(ARET, N, N);
 }
 
 /*