From cd1c07667495e7dd991cfcd0637eddf2bb65eac9 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Tue, 12 Mar 2019 18:43:14 -0700 Subject: Implement __builtin_constant_p --- decl.h | 1 + expr.c | 6 ++++++ scope.c | 19 ++++++++++--------- tests/builtin-constant-p.c | 3 +++ tests/builtin-constant-p.qbe | 2 ++ 5 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 tests/builtin-constant-p.c create mode 100644 tests/builtin-constant-p.qbe diff --git a/decl.h b/decl.h index 4abbbac..98fd768 100644 --- a/decl.h +++ b/decl.h @@ -14,6 +14,7 @@ enum linkage { enum builtinkind { BUILTINALLOCA, + BUILTINCONSTANTP, BUILTININFF, BUILTINNANF, BUILTINOFFSETOF, diff --git a/expr.c b/expr.c index 4dd16a8..b6e7bbc 100644 --- a/expr.c +++ b/expr.c @@ -405,6 +405,8 @@ primaryexpr(struct scope *s) return e; } +static struct expression *condexpr(struct scope *); + static struct expression * builtinfunc(struct scope *s, enum builtinkind kind) { @@ -419,6 +421,10 @@ builtinfunc(struct scope *s, enum builtinkind kind) e->builtin.kind = BUILTINALLOCA; e->builtin.arg = exprconvert(assignexpr(s), &typeulong); break; + case BUILTINCONSTANTP: + /* XXX: does this need to consider address constants? */ + e = mkconstexpr(&typeint, eval(condexpr(s))->kind == EXPRCONST); + break; case BUILTININFF: e = mkexpr(EXPRCONST, &typefloat, 0); /* TODO: use INFINITY here when we can handle musl's math.h */ diff --git a/scope.c b/scope.c index 1bcd31f..c557f47 100644 --- a/scope.c +++ b/scope.c @@ -17,15 +17,16 @@ scopeinit(void) char *name; struct declaration decl; } builtins[] = { - {"__builtin_alloca", {.kind = DECLBUILTIN, .builtin = BUILTINALLOCA}}, - {"__builtin_inff", {.kind = DECLBUILTIN, .builtin = BUILTININFF}}, - {"__builtin_nanf", {.kind = DECLBUILTIN, .builtin = BUILTINNANF}}, - {"__builtin_offsetof", {.kind = DECLBUILTIN, .builtin = BUILTINOFFSETOF}}, - {"__builtin_va_arg", {.kind = DECLBUILTIN, .builtin = BUILTINVAARG}}, - {"__builtin_va_copy", {.kind = DECLBUILTIN, .builtin = BUILTINVACOPY}}, - {"__builtin_va_end", {.kind = DECLBUILTIN, .builtin = BUILTINVAEND}}, - {"__builtin_va_list", {.kind = DECLTYPE, .type = &typevalist}}, - {"__builtin_va_start", {.kind = DECLBUILTIN, .builtin = BUILTINVASTART}}, + {"__builtin_alloca", {.kind = DECLBUILTIN, .builtin = BUILTINALLOCA}}, + {"__builtin_constant_p", {.kind = DECLBUILTIN, .builtin = BUILTINCONSTANTP}}, + {"__builtin_inff", {.kind = DECLBUILTIN, .builtin = BUILTININFF}}, + {"__builtin_nanf", {.kind = DECLBUILTIN, .builtin = BUILTINNANF}}, + {"__builtin_offsetof", {.kind = DECLBUILTIN, .builtin = BUILTINOFFSETOF}}, + {"__builtin_va_arg", {.kind = DECLBUILTIN, .builtin = BUILTINVAARG}}, + {"__builtin_va_copy", {.kind = DECLBUILTIN, .builtin = BUILTINVACOPY}}, + {"__builtin_va_end", {.kind = DECLBUILTIN, .builtin = BUILTINVAEND}}, + {"__builtin_va_list", {.kind = DECLTYPE, .type = &typevalist}}, + {"__builtin_va_start", {.kind = DECLBUILTIN, .builtin = BUILTINVASTART}}, }; struct builtin *b; diff --git a/tests/builtin-constant-p.c b/tests/builtin-constant-p.c new file mode 100644 index 0000000..fa16ed3 --- /dev/null +++ b/tests/builtin-constant-p.c @@ -0,0 +1,3 @@ +int f(void); +int x = __builtin_constant_p(1+2*3); +int y = __builtin_constant_p(f()); diff --git a/tests/builtin-constant-p.qbe b/tests/builtin-constant-p.qbe new file mode 100644 index 0000000..f92388f --- /dev/null +++ b/tests/builtin-constant-p.qbe @@ -0,0 +1,2 @@ +export data $x = align 4 { w 1, } +export data $y = align 4 { w 0, } -- cgit v1.2.3