Index: src/cmd/5c/txt.c |
=================================================================== |
--- a/src/cmd/5c/txt.c |
+++ b/src/cmd/5c/txt.c |
@@ -274,15 +274,43 @@ |
} |
void |
-regret(Node *n, Node *nn) |
+regret(Node *n, Node *nn, Type *t, int mode) |
{ |
int r; |
- r = REGRET; |
- if(typefd[nn->type->etype]) |
- r = FREGRET+NREG; |
- nodreg(n, nn, r); |
- reg[r]++; |
+ if(mode == 0 || hasdotdotdot(t) || nn->type->width == 0) { |
+ r = REGRET; |
+ if(typefd[nn->type->etype]) |
+ r = FREGRET+NREG; |
+ nodreg(n, nn, r); |
+ reg[r]++; |
+ return; |
+ } |
+ |
+ if(mode == 1) { |
+ // fetch returned value after call. |
+ // already called gargs, so curarg is set. |
+ curarg = (curarg+3) & ~3; |
+ regaalloc(n, nn); |
+ return; |
+ } |
+ |
+ if(mode == 2) { |
+ // store value to be returned. |
+ // must compute arg offset. |
+ if(t->etype != TFUNC) |
+ fatal(Z, "bad regret func %T", t); |
+ *n = *nn; |
+ n->op = ONAME; |
+ n->class = CPARAM; |
+ n->sym = slookup(".ret"); |
+ n->complex = nodret->complex; |
+ n->xoffset = argsize(0); |
+ n->addable = 20; |
+ return; |
+ } |
+ |
+ fatal(Z, "bad regret"); |
} |
int |