cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit f326044f9fc4ef7e182603e8686dde3f12da42dd
parent 5e668f124cdaccb38cf2a879ccf456c971743136
Author: Michael Forney <mforney@mforney.org>
Date:   Tue, 19 Feb 2019 17:49:43 -0800

Implement __builtin_va_copy

Diffstat:
Mdecl.c | 1+
Mdecl.h | 1+
Mexpr.c | 7+++++++
Mmain.c | 1+
Atests/builtin-va-copy.c | 4++++
Atests/builtin-va-copy.qbe | 20++++++++++++++++++++
6 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/decl.c b/decl.c @@ -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}; diff --git a/decl.h b/decl.h @@ -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; diff --git a/expr.c b/expr.c @@ -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; diff --git a/main.c b/main.c @@ -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 @@ -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 @@ -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 +}