ref: 2a705d1ec0ca51b5b7600c7c98f5808951980522
parent: 6ce01bc2fccd1846db2699a8c3d45b79212a9809
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Feb 11 02:53:01 EST 2017
[cc2] Add generic support for builtins in cc2 This patch only adds the support in the parser
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -444,7 +444,7 @@
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);
}
--- a/cc2/arch/amd64-sysv/types.c
+++ b/cc2/arch/amd64-sysv/types.c
@@ -92,3 +92,8 @@
.size = 0,
.align = 0
};
+
+Type arg_type = {
+ .size = 24,
+ .align = 8
+};
--- a/cc2/arch/i386-sysv/types.c
+++ b/cc2/arch/i386-sysv/types.c
@@ -92,3 +92,9 @@
.size = 0,
.align = 0
};
+
+/* this type is not used in this architecture */
+Type arg_type = {
+ .size = 0,
+ .align = 0
+};
--- a/cc2/arch/qbe/types.c
+++ b/cc2/arch/qbe/types.c
@@ -92,3 +92,8 @@
.size = 0,
.align = 0
};
+
+Type arg_type = {
+ .size = 24,
+ .align = 8
+};
--- a/cc2/arch/z80/types.c
+++ b/cc2/arch/z80/types.c
@@ -92,3 +92,9 @@
.size = 0,
.align = 0
};
+
+/* this types is not going to be used in this arch */
+Type arg_type = {
+ .size = 0,
+ .align = 0
+};
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -97,6 +97,7 @@
OCAST = 'g',
OINC = 'i',
ODEC = 'd',
+ OBUILTIN = 'm',
/*statements */
ONOP = 'q',
OJMP = 'j',
@@ -112,6 +113,13 @@
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 @@
EWTACKO, /* switch stack overflow */
EWTACKU, /* switch stack underflow */
ENOSWTC, /* Out of switch statement */
+ EBBUILT, /* Unknown builtin */
ENUMERR
};
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -19,7 +19,8 @@
booltype,
ptrtype,
voidtype,
- elipsistype;
+ elipsistype,
+ arg_type;
Type funtype = {
.flags = FUNF
@@ -43,7 +44,7 @@
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 @@
['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 @@
['|'] = { 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},
@@ -459,6 +462,40 @@
fun->left = np;
fun->right = par;
push(fun);
+}
+
+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