scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit bf2c6e4d7f1da97151ef509b3fd818b30298280d
parent 82da1d28e44114cbe814057feada71c47c224ccf
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 11 Feb 2017 07:53:01 +0100

[cc2] Add generic support for builtins in cc2

This patch only adds the support in the parser

Diffstat:
Mcc1/code.c | 2+-
Mcc2/arch/amd64-sysv/types.c | 5+++++
Mcc2/arch/i386-sysv/types.c | 6++++++
Mcc2/arch/qbe/types.c | 5+++++
Mcc2/arch/z80/types.c | 6++++++
Mcc2/cc2.h | 9+++++++++
Mcc2/parser.c | 41+++++++++++++++++++++++++++++++++++++++--
7 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/cc1/code.c b/cc1/code.c @@ -444,7 +444,7 @@ emitbuilt(unsigned op, void *arg) emitnode(np->left); emitnode(np->right); - fprintf(outfp, "\t\"%s\tk", np->sym->name); + fprintf(outfp, "\t\"%s\tm", np->sym->name); emitletter(np->type); } diff --git a/cc2/arch/amd64-sysv/types.c b/cc2/arch/amd64-sysv/types.c @@ -92,3 +92,8 @@ Type elipsistype = { .size = 0, .align = 0 }; + +Type arg_type = { + .size = 24, + .align = 8 +}; diff --git a/cc2/arch/i386-sysv/types.c b/cc2/arch/i386-sysv/types.c @@ -92,3 +92,9 @@ Type elipsistype = { .size = 0, .align = 0 }; + +/* this type is not used in this architecture */ +Type arg_type = { + .size = 0, + .align = 0 +}; diff --git a/cc2/arch/qbe/types.c b/cc2/arch/qbe/types.c @@ -92,3 +92,8 @@ Type elipsistype = { .size = 0, .align = 0 }; + +Type arg_type = { + .size = 24, + .align = 8 +}; diff --git a/cc2/arch/z80/types.c b/cc2/arch/z80/types.c @@ -92,3 +92,9 @@ Type elipsistype = { .size = 0, .align = 0 }; + +/* this types is not going to be used in this arch */ +Type arg_type = { + .size = 0, + .align = 0 +}; diff --git a/cc2/cc2.h b/cc2/cc2.h @@ -97,6 +97,7 @@ enum op { OCAST = 'g', OINC = 'i', ODEC = 'd', + OBUILTIN = 'm', /*statements */ ONOP = 'q', OJMP = 'j', @@ -112,6 +113,13 @@ enum op { OEFUN = 'k', }; +enum builtins { + BVA_START = 's', + BVA_END = 'e', + BVA_ARG = 'a', + BVA_COPY = 'c', +}; + enum nerrors { EEOFFUN, /* EOF while parsing function */ ENLABEL, /* label without statement */ @@ -128,6 +136,7 @@ enum nerrors { EWTACKO, /* switch stack overflow */ EWTACKU, /* switch stack underflow */ ENOSWTC, /* Out of switch statement */ + EBBUILT, /* Unknown builtin */ ENUMERR }; diff --git a/cc2/parser.c b/cc2/parser.c @@ -19,7 +19,8 @@ extern Type int8type, int16type, int32type, int64type, booltype, ptrtype, voidtype, - elipsistype; + elipsistype, + arg_type; Type funtype = { .flags = FUNF @@ -43,7 +44,7 @@ typedef void parsefun(char *, union tokenop); static parsefun type, symbol, getname, unary, binary, ternary, call, constant, composed, binit, einit, jump, oreturn, loop, assign, - ocase, bswitch, eswitch; + ocase, bswitch, eswitch, builtin; typedef void evalfun(void); static evalfun vardecl, beginfun, endfun, endpars, stmt, @@ -78,6 +79,7 @@ static struct decoc { ['B'] = { NULL, type, .u.arg = &booltype}, ['P'] = { NULL, type, .u.arg = &ptrtype}, ['E'] = { NULL, type, .u.arg = &elipsistype}, + ['1'] = { NULL, type, .u.arg = &arg_type}, ['F'] = { NULL, type, .u.arg = &funtype}, ['V'] = { array,composed, 0}, @@ -120,6 +122,7 @@ static struct decoc { ['|'] = { NULL, binary, .u.op = OBOR}, ['^'] = { NULL, binary, .u.op = OBXOR}, [','] = { NULL, binary, .u.op = OCOMMA}, + ['m'] = { NULL, builtin,.u.op = OBUILTIN}, [':'] = { NULL, assign, .u.op = OASSIG}, ['?'] = { NULL, ternary, .u.op = OASK}, @@ -462,6 +465,40 @@ call(char *token, union tokenop u) } static void +builtin(char *token, union tokenop u) +{ + Node *np = newnode(u.op); + char *name; + unsigned subop, nchilds; + + np->type = *gettype(token+1); + name = pop(); + + if (!strcmp("__builtin_va_arg", name)) { + nchilds = 1; + subop = BVA_ARG; + } else if (!strcmp("__builtin_va_start", name)) { + nchilds = 2; + subop = BVA_START; + } else if (!strcmp("__builtin_va_end", name)) { + nchilds = 1; + subop = BVA_END; + } else if (!strcmp("__builtin_va_copy", name)) { + nchilds = 2; + subop = BVA_COPY; + } else { + error(EBBUILT);; + } + + np->u.subop = subop; + np->right = (nchilds == 2) ? pop() : NULL; + np->left = (nchilds != 0) ? pop() : NULL; + + free(name); + push(np); +} + +static void binary(char *token, union tokenop u) { Node *np = newnode(u.op);