aboutsummaryrefslogtreecommitdiffhomepage
path: root/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/parse.c b/parse.c
index 9a5d99a..dc1b3e5 100644
--- a/parse.c
+++ b/parse.c
@@ -981,13 +981,12 @@ expreffects(struct function *fn, const struct expr *ex)
static void
-structcopy(struct function *fn, union ref dst, const struct expr *src)
+structcopy(struct function *fn, union type ty, union ref dst, union ref src)
{
- union ref srcref = expraddr(fn, src);
- union ref args[2] = { dst, srcref };
- union irtype typ[2] = { mkirtype(src->ty) };
- typ[1] = typ[0];
- addinstr(fn, mkintrin(fn, INstructcopy, 0, 2, args, typ));
+ union ref args[2] = { dst, src };
+ union irtype typs[2] = { mkirtype(ty) };
+ typs[1] = typs[0];
+ addinstr(fn, mkintrin(fn, INstructcopy, 0, 2, args, typs));
}
static union ref
@@ -1034,8 +1033,8 @@ expraddr(struct function *fn, const struct expr *ex)
return addinstr(fn, ins);
case ESET:
assert(isagg(ex->ty));
- r = expraddr(fn, &ex->sub[0]);
- structcopy(fn, r, &ex->sub[1]);
+ r = expraddr(fn, &ex->sub[1]);
+ structcopy(fn, ex->ty, expraddr(fn, &ex->sub[0]), r);
return r;
case ESEQ:
expreffects(fn, &ex->sub[0]);
@@ -1299,11 +1298,14 @@ compilecall(struct function *fn, const struct expr *ex)
ins.cls = type2cls[ex->ty.t];
}
ins.l = exprvalue(fn, &sub[0]);
- for (int i = 0; i < ex->narg; ++i) {
+ vresize(&args, ex->narg);
+ vresize(&typs, ex->narg);
+ /* backwards because of RTL call stack order */
+ for (int i = ex->narg - 1; i >= 0; --i) {
struct expr *arg = &sub[i+1];
union type ty = i < td->nmemb ? td->param[i] : argpromote(arg->ty);
- vpush(&args, cvt(fn, ty.t, arg->ty.t, exprvalue(fn, arg)));
- vpush(&typs, mkirtype(ty));
+ args.p[i] = cvt(fn, ty.t, arg->ty.t, exprvalue(fn, arg));
+ typs.p[i] = mkirtype(ty);
}
if (isagg(ex->ty))
vpush(&typs, mkirtype(ex->ty));
@@ -1765,7 +1767,7 @@ block(struct parser *pr, struct function *fn)
}
EMITS {
if (isagg(decl.ty))
- structcopy(fn, mkref(RTMP, decl.id), &ini);
+ structcopy(fn, decl.ty, mkref(RTMP, decl.id), expraddr(fn, &ini));
else
genstore(fn, decl.ty, mkref(RTMP, decl.id), exprvalue(fn, &ini));
}