diff options
-rw-r--r-- | decl.c | 1 | ||||
-rw-r--r-- | decl.h | 1 | ||||
-rw-r--r-- | expr.c | 7 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | tests/builtin-va-copy.c | 4 | ||||
-rw-r--r-- | tests/builtin-va-copy.qbe | 20 |
6 files changed, 34 insertions, 0 deletions
@@ -21,6 +21,7 @@ struct declaration builtinvalist = {.kind = DECLTYPE, .type = &typevalist}; struct declaration builtinvastart = {.kind = DECLBUILTIN}; struct declaration builtinvaarg = {.kind = DECLBUILTIN}; +struct declaration builtinvacopy = {.kind = DECLBUILTIN}; struct declaration builtinvaend = {.kind = DECLBUILTIN}; struct declaration builtinoffsetof = {.kind = DECLBUILTIN}; @@ -28,6 +28,7 @@ struct function; extern struct declaration builtinvalist; extern struct declaration builtinvastart; extern struct declaration builtinvaarg; +extern struct declaration builtinvacopy; extern struct declaration builtinvaend; extern struct declaration builtinoffsetof; @@ -453,6 +453,13 @@ postfixexpr(struct scope *s, struct expression *r) expect(TCOMMA, "after va_list"); e->type = typename(s); expect(TRPAREN, "after typename"); + } else if (r->ident.decl == &builtinvacopy) { + e = mkexpr(EXPRASSIGN, typevalist.base, 0); + e->assign.l = mkunaryexpr(TMUL, exprconvert(assignexpr(s), &typevalistptr)); + expect(TCOMMA, "after target va_list"); + e->assign.r = mkunaryexpr(TMUL, exprconvert(assignexpr(s), &typevalistptr)); + expect(TRPAREN, "after source va_list"); + e = exprconvert(e, &typevoid); } else if (r->ident.decl == &builtinvaend) { e = mkexpr(EXPRBUILTIN, &typevoid, 0); e->builtin.kind = BUILTINVAEND; @@ -55,6 +55,7 @@ main(int argc, char *argv[]) } else { scopeputdecl(&filescope, "__builtin_va_list", &builtinvalist); scopeputdecl(&filescope, "__builtin_va_start", &builtinvastart); + scopeputdecl(&filescope, "__builtin_va_copy", &builtinvacopy); scopeputdecl(&filescope, "__builtin_va_arg", &builtinvaarg); scopeputdecl(&filescope, "__builtin_va_end", &builtinvaend); scopeputdecl(&filescope, "__builtin_offsetof", &builtinoffsetof); diff --git a/tests/builtin-va-copy.c b/tests/builtin-va-copy.c new file mode 100644 index 0000000..7a69596 --- /dev/null +++ b/tests/builtin-va-copy.c @@ -0,0 +1,4 @@ +void f(void) { + static __builtin_va_list a, b; + __builtin_va_copy(a, b); +} diff --git a/tests/builtin-va-copy.qbe b/tests/builtin-va-copy.qbe new file mode 100644 index 0000000..7d88659 --- /dev/null +++ b/tests/builtin-va-copy.qbe @@ -0,0 +1,20 @@ +data $.La.2 = align 8 { z 24 } +data $.Lb.3 = align 8 { z 24 } +export +function $f() { +@start.1 +@body.2 + %.1 =l loadl $.Lb.3 + storel %.1, $.La.2 + %.2 =l add $.Lb.3, 8 + %.3 =l add $.La.2, 8 + %.4 =l loadl %.2 + storel %.4, %.3 + %.5 =l add %.2, 8 + %.6 =l add %.3, 8 + %.7 =l loadl %.5 + storel %.7, %.6 + %.8 =l add %.5, 8 + %.9 =l add %.6, 8 + ret +} |