[hackers] [scc] [cc1] Add support for va_arg builtins || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Fri, 10 Feb 2017 20:03:37 +0100 (CET)

commit 1557ce048255aed8b072675b250ecdfd6a0df0ab
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Fri Feb 10 20:00:57 2017 +0100
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Fri Feb 10 20:00:57 2017 +0100

    [cc1] Add support for va_arg builtins

diff --git a/cc1/Makefile b/cc1/Makefile
index b9f73ce..bd37547 100644
--- a/cc1/Makefile
+++ b/cc1/Makefile
_AT_@ -6,7 +6,8 @@ CSTDINC = -I../inc/$(STD)
 include ../config.mk
 
 OBJS = types.o decl.o lex.o error.o symbol.o main.o expr.o \
- code.o stmt.o cpp.o fold.o init.o arch/$(ARCH)/arch.o
+ code.o stmt.o cpp.o fold.o init.o builtin.o \
+ arch/$(ARCH)/arch.o
 
 all: cc1-$(ARCH)
 
diff --git a/cc1/arch/amd64-sysv/arch.c b/cc1/arch/amd64-sysv/arch.c
index f4492b4..89bec2d 100644
--- a/cc1/arch/amd64-sysv/arch.c
+++ b/cc1/arch/amd64-sysv/arch.c
_AT_@ -183,13 +183,13 @@ static Type types[] = {
                 .align = 8,
                 .n.rank = RANK_LONG,
         },
- { /* 20 = va_list_type */
- .op = PTR,
- .letter = L_POINTER,
+ { /* 20 = va_type */
+ .op = STRUCT,
+ .letter = L_VA_ARG,
                 .prop = TDEFINED,
- .size = 8,
+ .size = 24,
                 .align = 8,
- }
+ },
 };
 
 Type *voidtype = &types[0], *pvoidtype = &types[1],
_AT_@ -202,9 +202,21 @@ Type *voidtype = &types[0], *pvoidtype = &types[1],
      *floattype = &types[14], *doubletype = &types[15],
      *ldoubletype = &types[16],
      *sizettype = &types[17], *pdifftype = &types[19],
- *ellipsistype = &types[18],
- *va_list_type = &types[20];
+ *ellipsistype = &types[18], *va_type = &types[20],
+ *va_list_type;
 
 static Symbol dummy0 = {.u.i = 0, .type = &types[9]},
               dummy1 = {.u.i = 1, .type = &types[9]};
 Symbol *zero = &dummy0, *one = &dummy1;
+
+void
+iarch(void)
+{
+ va_list_type = mktype(va_type, ARY, 1, NULL);
+}
+
+int
+valid_va_list(Type *tp)
+{
+ return tp->op == PTR && tp->type == va_type;
+}
diff --git a/cc1/arch/i386-sysv/arch.c b/cc1/arch/i386-sysv/arch.c
index f72f889..6420002 100644
--- a/cc1/arch/i386-sysv/arch.c
+++ b/cc1/arch/i386-sysv/arch.c
_AT_@ -183,13 +183,13 @@ static Type types[] = {
                 .align = 4,
                 .n.rank = RANK_INT,
         },
- { /* 20 = va_list_type */
+ { /* 20 = va_list_type */
                 .op = PTR,
                 .letter = L_POINTER,
                 .prop = TDEFINED,
- .size = 8,
- .align = 8,
- }
+ .size = 4,
+ .align = 4,
+ },
 };
 
 
_AT_@ -203,11 +203,21 @@ Type *voidtype = &types[0], *pvoidtype = &types[1],
      *floattype = &types[14], *doubletype = &types[15],
      *ldoubletype = &types[16],
      *sizettype = &types[17], *pdifftype = &types[19],
- *ellipsistype = &types[18],
- *va_list_type = &types[20];
+ *ellipsistype = &types[18], *va_list_type = &types[20];
 
 
 
 static Symbol dummy0 = {.u.i = 0, .type = &types[9]},
               dummy1 = {.u.i = 1, .type = &types[9]};
 Symbol *zero = &dummy0, *one = &dummy1;
+
+void
+iarch(void)
+{
+}
+
+int
+valid_va_list(Type *tp)
+{
+ return tp == va_list_type;
+}
diff --git a/cc1/arch/qbe/arch.c b/cc1/arch/qbe/arch.c
index 233a390..3835ed1 100644
--- a/cc1/arch/qbe/arch.c
+++ b/cc1/arch/qbe/arch.c
_AT_@ -183,13 +183,13 @@ static Type types[] = {
                 .align = 8,
                 .n.rank = RANK_LONG,
         },
- { /* 20 = va_list_type */
- .op = PTR,
- .letter = L_POINTER,
+ { /* 20 = va_type */
+ .op = STRUCT,
+ .letter = L_VA_ARG,
                 .prop = TDEFINED,
- .size = 8,
+ .size = 24,
                 .align = 8,
- }
+ },
 };
 
 Type *voidtype = &types[0], *pvoidtype = &types[1],
_AT_@ -202,9 +202,21 @@ Type *voidtype = &types[0], *pvoidtype = &types[1],
      *floattype = &types[14], *doubletype = &types[15],
      *ldoubletype = &types[16],
      *sizettype = &types[17], *pdifftype = &types[19],
- *ellipsistype = &types[18],
- *va_list_type = &types[20];
+ *ellipsistype = &types[18], *va_type = &types[20],
+ *va_list_type;
 
 static Symbol dummy0 = {.u.i = 0, .type = &types[9]},
               dummy1 = {.u.i = 1, .type = &types[9]};
 Symbol *zero = &dummy0, *one = &dummy1;
+
+void
+iarch(void)
+{
+ va_list_type = mktype(va_type, ARY, 1, NULL);
+}
+
+int
+valid_va_list(Type *tp)
+{
+ return tp->op == PTR && tp->type == va_type;
+}
diff --git a/cc1/arch/z80/arch.c b/cc1/arch/z80/arch.c
index 0c603f6..70aec61 100644
--- a/cc1/arch/z80/arch.c
+++ b/cc1/arch/z80/arch.c
_AT_@ -187,8 +187,8 @@ static Type types[] = {
                 .op = PTR,
                 .letter = L_POINTER,
                 .prop = TDEFINED,
- .size = 8,
- .align = 8,
+ .size = 2,
+ .align = 1,
         }
 };
 
_AT_@ -202,10 +202,20 @@ Type *voidtype = &types[0], *pvoidtype = &types[1],
      *floattype = &types[14], *doubletype = &types[15],
      *ldoubletype = &types[16],
      *sizettype = &types[17], *pdifftype = &types[19],
- *ellipsistype = &types[18],
- *va_list_type = &types[20];
+ *ellipsistype = &types[18], *va_list_type = &types[20];
 
 
 static Symbol dummy0 = {.u.i = 0, .type = &types[9]},
               dummy1 = {.u.i = 1, .type = &types[9]};
 Symbol *zero = &dummy0, *one = &dummy1;
+
+void
+iarch(void)
+{
+}
+
+int
+valid_va_list(Type *tp)
+{
+ return tp == va_list_type;
+}
diff --git a/cc1/builtin.c b/cc1/builtin.c
new file mode 100644
index 0000000..d2b3068
--- /dev/null
+++ b/cc1/builtin.c
_AT_@ -0,0 +1,100 @@
+/* See LICENSE file for copyright and license details. */
+static char sccsid[] = "_AT_(#) ./cc1/builtin.c";
+
+#include <stdio.h>
+
+#include "../inc/cc.h"
+#include "cc1.h"
+
+static Node *
+builtin_va_arg(Symbol *sym)
+{
+ Node *np, *ap;
+ Type *tp;
+
+ ap = assign();
+ expect(',');
+ tp = typename();
+
+ if (!valid_va_list(ap->type)) {
+ errorp("incorrect parameters for va_arg");
+ return constnode(zero);
+ }
+
+ np = node(OBUILTIN, tp, ap, NULL);
+ np->sym = sym;
+ return np;
+}
+
+static Node *
+builtin_va_copy(Symbol *sym)
+{
+ Node *np, *src, *dst;
+
+ dst = assign();
+ expect(',');
+ src = assign();
+
+ if (!valid_va_list(dst->type) || !valid_va_list(src->type)) {
+ errorp("incorrect parameters for va_copy");
+ return constnode(zero);
+ }
+
+ np = node(OBUILTIN, voidtype, dst, src);
+ np->sym = sym;
+ return np;
+}
+
+static Node *
+builtin_va_start(Symbol *sym)
+{
+ Node *np, *ap, *last;
+
+ ap = assign();
+ expect(',');
+ if (yytoken != IDEN)
+ goto error;
+ last = varnode(yylval.sym);
+ next();
+
+ if (!valid_va_list(ap->type))
+ goto error;
+
+ np = node(OBUILTIN, voidtype, ap, last);
+ np->sym = sym;
+ return np;
+
+error:
+ errorp("incorrect parameters for va_start");
+ return constnode(zero);
+}
+
+static Node *
+builtin_va_end(Symbol *sym)
+{
+ Node *ap, *np;
+
+ ap = assign();
+
+ if (!valid_va_list(ap->type)) {
+ errorp("incorrect parameters for va_end");
+ return constnode(zero);
+ }
+
+ np = node(OBUILTIN, voidtype, ap, NULL);
+ np->sym = sym;
+ return np;
+}
+
+void
+ibuilts(void)
+{
+ struct builtin built[] = {
+ {"__builtin_va_arg", builtin_va_arg},
+ {"__builtin_va_copy", builtin_va_copy},
+ {"__builtin_va_start", builtin_va_start},
+ {"__builtin_va_end", builtin_va_end},
+ {NULL}
+ };
+ builtins(built);
+}
diff --git a/cc1/cc1.h b/cc1/cc1.h
index 705e0b9..5f7f124 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -54,6 +54,7 @@ enum ns {
         L_ARRAY = 'V',
         L_UNION = 'U',
         L_STRUCT = 'S',
+ L_VA_ARG = '1',
 };
 
 /* recovery points */
_AT_@ -196,6 +197,7 @@ enum tokens {
         IFNDEF,
         UNDEF,
         ENDIF,
+ BUILTIN,
         EOFTOK
 };
 
_AT_@ -260,6 +262,7 @@ enum op {
         OBSWITCH,
         OESWITCH,
         OINIT,
+ OBUILTIN,
         OTYP,
 };
 
_AT_@ -283,6 +286,11 @@ struct limits {
         } min;
 };
 
+struct builtin {
+ char *str;
+ Node *(*fun)(Symbol *);
+};
+
 struct keyword {
         char *str;
         unsigned char token, value;
_AT_@ -327,6 +335,7 @@ struct symbol {
                 unsigned char token;
                 Node **init;
                 Symbol **pars;
+ Node *(*fun)(Symbol *);
         } u;
         struct symbol *next;
         struct symbol *hash;
_AT_@ -387,6 +396,7 @@ extern void pushctx(void), popctx(void);
 extern void killsym(Symbol *sym);
 extern Symbol *newlabel(void);
 extern void keywords(struct keyword *key, int ns);
+extern void builtins(struct builtin *builts);
 extern Symbol *newstring(char *s, size_t len);
 extern unsigned newid(void);
 
_AT_@ -417,6 +427,7 @@ extern Node *varnode(Symbol *sym);
 extern Node *constnode(Symbol *sym);
 extern Node *sizeofnode(Type *tp);
 extern void freetree(Node *np);
+extern void icode(void);
 #define BTYPE(np) ((np)->type->op)
 
 /* fold.c */
_AT_@ -444,6 +455,13 @@ extern void outcpp(void);
 extern void defdefine(char *macro, char *val, char *source);
 extern void undefmacro(char *s);
 
+/* builtin.c */
+extern void ibuilts(void);
+
+/* arch.c */
+extern void iarch(void);
+extern int valid_va_list(Type *tp);
+
 /*
  * Definition of global variables
  */
_AT_@ -470,4 +488,4 @@ extern Type *voidtype, *pvoidtype, *booltype,
             *longtype, *ulongtype,
             *ullongtype, *llongtype,
             *floattype, *doubletype, *ldoubletype,
- *ellipsistype, *va_list_type;
+ *ellipsistype, *va_list_type, *va_type;
diff --git a/cc1/code.c b/cc1/code.c
index ceea7bd..769e897 100644
--- a/cc1/code.c
+++ b/cc1/code.c
_AT_@ -17,7 +17,8 @@ static void emitbin(unsigned, void *),
             emitfun(unsigned, void *),
             emitdcl(unsigned, void *),
             emitinit(unsigned, void *),
- emittype(unsigned, void *);
+ emittype(unsigned, void *),
+ emitbuilt(unsigned, void *);
 
 char *optxt[] = {
         [OADD] = "+",
_AT_@ -134,6 +135,7 @@ void (*opcode[])(unsigned, void *) = {
         [OPAR] = emitbin,
         [OCALL] = emitbin,
         [OINIT] = emitinit,
+ [OBUILTIN] = emitbuilt,
         [OTYP] = emittype,
 };
 
_AT_@ -430,12 +432,24 @@ emitbin(unsigned op, void *arg)
         emitnode(np->left);
         emitnode(np->right);
         if ((s = optxt[op]) != NULL) { /* do not print in OCOLON case */
- fprintf(outfp, "\t%s", optxt[op]);
+ fprintf(outfp, "\t%s", s);
                 emitletter(np->type);
         }
 }
 
 static void
+emitbuilt(unsigned op, void *arg)
+{
+ Node *np = arg;
+
+ emitnode(np->left);
+ emitnode(np->right);
+ fprintf(outfp, "\t\"%s\tk", np->sym->name);
+ emitletter(np->type);
+}
+
+
+static void
 emitexp(unsigned op, void *arg)
 {
         Node *np = arg;
diff --git a/cc1/expr.c b/cc1/expr.c
index 6744511..6705fb9 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
_AT_@ -11,7 +11,7 @@ static char sccsid[] = "@(#) ./cc1/expr.c";
 
 #define XCHG(lp, rp, np) (np = lp, lp = rp, rp = np)
 
-static Node *xexpr(void);
+static Node *xexpr(void), *xassign(void);
 
 int
 cmpnode(Node *np, TUINT val)
_AT_@ -614,6 +614,7 @@ primary(void)
 {
         Node *np;
         Symbol *sym;
+ Node *(*fun)(Symbol *);
 
         sym = yylval.sym;
         switch (yytoken) {
_AT_@ -624,6 +625,15 @@ primary(void)
                 emit(OINIT, np);
                 np = varnode(sym);
                 break;
+ case BUILTIN:
+ fun = sym->u.fun;
+ next();
+ expect('(');
+ np = (*fun)(sym);
+ expect(')');
+
+ /* do not call to next */
+ return np;
         case CONSTANT:
                 np = constnode(sym);
                 break;
_AT_@ -675,7 +685,7 @@ arguments(Node *np)
         toomany = 0;
 
         do {
- arg = assign();
+ arg = xassign();
                 argtype = *targs;
                 if (argtype == ellipsistype) {
                         n = 0;
_AT_@ -1064,8 +1074,8 @@ ternary(void)
         return cond;
 }
 
-Node *
-assign(void)
+static Node *
+xassign(void)
 {
         Node *np, *(*fun)(int , Node *, Node *);
         int op;
_AT_@ -1098,15 +1108,21 @@ xexpr(void)
 {
         Node *lp, *rp;
 
- lp = assign();
+ lp = xassign();
         while (accept(',')) {
- rp = assign();
+ rp = xassign();
                 lp = node(OCOMMA, rp->type, lp, rp);
         }
         return lp;
 }
 
 Node *
+assign(void)
+{
+ return simplify(xassign());
+}
+
+Node *
 constexpr(void)
 {
         Node *np;
diff --git a/cc1/main.c b/cc1/main.c
index 6304901..e901ce0 100644
--- a/cc1/main.c
+++ b/cc1/main.c
_AT_@ -58,6 +58,7 @@ main(int argc, char *argv[])
         ilex();
         icpp();
         icode();
+ ibuilts();
 
         ARGBEGIN {
         case 'D':
_AT_@ -102,6 +103,12 @@ main(int argc, char *argv[])
                 die("error: failed to open input file '%s': %s",
                     *argv, strerror(errno));
         }
+
+ /*
+ * we cannot initialize types until we have an
+ * output stream, because we maybe want to emit new types
+ */
+ iarch();
         if (onlycpp || onlyheader) {
                 outcpp();
         } else {
diff --git a/cc1/symbol.c b/cc1/symbol.c
index 9780c07..b95c49d 100644
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
_AT_@ -296,3 +296,23 @@ keywords(struct keyword *key, int ns)
         counterid = 0;
         head = NULL;
 }
+
+void
+builtins(struct builtin *built)
+{
+ Symbol *sym;
+ struct builtin *bp;
+
+ for (bp = built; bp->str; ++bp) {
+ sym = linkhash(newsym(NS_KEYWORD, bp->str));
+ sym->token = BUILTIN;
+ sym->u.fun = bp->fun;
+ }
+ /*
+ * Remove all the predefined symbols from * the symbol list. It
+ * will make faster some operations. There is no problem of memory
+ * leakeage because this memory is not ever freed
+ */
+ counterid = 0;
+ head = NULL;
+}
Received on Fri Feb 10 2017 - 20:03:37 CET

This archive was generated by hypermail 2.3.0 : Fri Feb 10 2017 - 20:12:16 CET