aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/cgen.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-12 11:20:43 +0200
committerlemon <lsof@mailbox.org>2022-08-12 11:20:43 +0200
commiteff929f0d323559f3b2e9272e3c1d4aa82fc5c80 (patch)
treec3dd54fe4ed4a3082f455c8fe37436f767760977 /bootstrap/cgen.c
parent19f1093f0929b989a06cdee2e7d175e6db15559c (diff)
va list, cont fix
Diffstat (limited to 'bootstrap/cgen.c')
-rw-r--r--bootstrap/cgen.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/bootstrap/cgen.c b/bootstrap/cgen.c
index 1629151..6321e92 100644
--- a/bootstrap/cgen.c
+++ b/bootstrap/cgen.c
@@ -37,6 +37,9 @@ gentype(const struct type *ty) {
case TYenum:
gentype(ty->enu.intty);
break;
+ case TYvalist:
+ pri("__builtin_va_list");
+ break;
}
if (ty->konst)
pri(" const");
@@ -168,6 +171,7 @@ geneuiniex(struct expr *ex) {
static void
genexpr(struct expr *ex) {
+ assert(ex);
const struct type *ty = unconstify(ex->ty);
struct decl *decl;
@@ -284,6 +288,15 @@ genexpr(struct expr *ex) {
geneuiniex(ex);
pri(")");
break;
+ case Evastart:
+ pri("__builtin_va_start(%e, %e)", ex->binop.lhs, ex->binop.rhs);
+ break;
+ case Evaarg:
+ pri("__builtin_va_arg(%e, %t)", ex->child, ex->ty);
+ break;
+ case Evaend:
+ pri("__builtin_va_end(%e)", ex->child);
+ break;
}
}
@@ -343,15 +356,15 @@ genstmt(struct stmt *stmt) {
}
break;
case Swhile:
- pri("while (%e) {", &stmt->loop.test);
+ pri("while (%e) {_cont%d:;", &stmt->loop.test, stmt->loop.id);
genblock(stmt->loop.body);
- pri("_cont%d:;} _brk%d:;\n", stmt->loop.id, stmt->loop.id);
+ pri("} _brk%d:;\n", stmt->loop.id);
break;
case Sdowhile:
- pri("do {");
+ pri("do {_cont%d:;",stmt->loop.id);
genblock(stmt->loop.body);
- pri("_cont%d:;} while (%e); _brk%d:;\n",
- stmt->loop.id, &stmt->loop.test, stmt->loop.id);
+ pri("} while (%e); _brk%d:;\n",
+ &stmt->loop.test, stmt->loop.id);
break;
case Sfor:
pri("{\n");
@@ -361,10 +374,12 @@ genstmt(struct stmt *stmt) {
pri("%e;", &stmt->loop.test);
if (stmt->loop.next)
pri(" %e", stmt->loop.next);
- pri(") {");
+ pri(") {goto _skip%d; _cont%d:", stmt->loop.id, stmt->loop.id);
+ if (stmt->loop.next)
+ pri(" %e;", stmt->loop.next);
+ pri("_skip%d:;", stmt->loop.id);
genblock(stmt->loop.body);
- pri("_cont%d:; }", stmt->loop.id);
- pri("} _brk%d:;\n", stmt->loop.id);
+ pri("}} _brk%d:;\n", stmt->loop.id);
break;
case Siswitch:
pri("switch (%e) {", &stmt->iswitch.test);
@@ -505,6 +520,13 @@ liftnestedex(struct expr *ex) {
case Eeuini:
liftnestedex(ex->euini.ini);
break;
+ case Evastart:
+ liftnestedex(ex->binop.lhs);
+ liftnestedex(ex->binop.rhs);
+ break;
+ case Evaarg: case Evaend:
+ liftnestedex(ex->child);
+ break;
}
}
@@ -676,7 +698,7 @@ defctype(const struct type *ty, void *_) {
if (!ty->_cname)
switch (ty->t) {
- case TYvoid: case TYbool:
+ case TYvoid: case TYbool: case TYvalist:
case TYenum: case TYint: case TYfloat:
break;
case TYptr: