shithub: scc

Download patch

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