[hackers] [scc] [cc1-cc2] Differentiate varadic calls || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Tue, 14 Feb 2017 15:22:32 +0100 (CET)

commit 6ab66ac2cfce3feebebaaa9ad3963abb29a10d1c
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Tue Feb 14 15:20:09 2017 +0100
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Tue Feb 14 15:20:09 2017 +0100

    [cc1-cc2] Differentiate varadic calls
    
    Qbe has a special support for variadic functions, because having this
    information saves to Qbe to use eax in all the calls.

diff --git a/cc1/cc1.h b/cc1/cc1.h
index 73ba77f..a543d7b 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -21,6 +21,7 @@ enum typeprops {
         TARITH = 1 << 3, /* the type is INT, ENUM or FLOAT */
         TAGGREG = 1 << 4, /* the type is struct or union */
         TK_R = 1 << 5, /* this is a K&R-function */
+ TELLIPSIS= 1 << 6, /* this function has an ellipsis par */
 };
 
 enum inputtype {
_AT_@ -257,6 +258,7 @@ enum op {
         OFUN,
         OPAR,
         OCALL,
+ OCALLE,
         ORET,
         ODECL,
         OBSWITCH,
diff --git a/cc1/code.c b/cc1/code.c
index 711c4df..7931c75 100644
--- a/cc1/code.c
+++ b/cc1/code.c
_AT_@ -72,6 +72,7 @@ char *optxt[] = {
         [ORET] = "\th",
         [OPAR] = "p",
         [OCALL] = "c",
+ [OCALLE] = "z",
         [OFIELD] = "."
 };
 
_AT_@ -134,6 +135,7 @@ void (*opcode[])(unsigned, void *) = {
         [OESWITCH] = emitsymid,
         [OPAR] = emitbin,
         [OCALL] = emitbin,
+ [OCALLE] = emitbin,
         [OINIT] = emitinit,
         [OBUILTIN] = emitbuilt,
         [OTYP] = emittype,
diff --git a/cc1/expr.c b/cc1/expr.c
index 6705fb9..d91ccdc 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
_AT_@ -660,7 +660,7 @@ primary(void)
 static Node *
 arguments(Node *np)
 {
- int toomany, n;
+ int toomany, n, op;
         Node *par = NULL, *arg;
         Type *argtype, **targs, *tp = np->type, *rettype;
 
_AT_@ -721,7 +721,8 @@ no_pars:
         if (n > 0 && *targs != ellipsistype)
                 errorp("too few arguments in function call");
 
- return node(OCALL, rettype, np, par);
+ op = (tp->prop&TELLIPSIS) ? OCALLE : OCALL;
+ return node(op, rettype, np, par);
 }
 
 static Node *unary(int);
diff --git a/cc1/types.c b/cc1/types.c
index 0008cd2..7d446ef 100644
--- a/cc1/types.c
+++ b/cc1/types.c
_AT_@ -298,7 +298,11 @@ mktype(Type *tp, int op, TINT nelem, Type *pars[])
         case KRFTN:
                 type.prop |= TK_R;
                 type.op = FTN;
+ type.letter = L_FUNCTION;
+ break;
         case FTN:
+ if (pars[nelem-1] == ellipsistype)
+ type.prop |= TELLIPSIS;
                 type.letter = L_FUNCTION;
                 break;
         case PTR:
diff --git a/cc2/arch/qbe/arch.h b/cc2/arch/qbe/arch.h
index 3ab8f33..ff2167c 100644
--- a/cc2/arch/qbe/arch.h
+++ b/cc2/arch/qbe/arch.h
_AT_@ -135,6 +135,7 @@ enum asmop {
         ASRET,
         ASCALL,
         ASCALLE,
+ ASCALLEX,
         ASPAR,
         ASPARE,
         ASALLOC,
diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c
index 4f3ca39..4bfa45d 100644
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
_AT_@ -249,7 +249,7 @@ call(Node *np, Node *fun, Node *ret)
                 tmpnode(&aux, &(*q)->type);
                 code(op, NULL, *q, &aux);
         }
- code(ASCALLE, NULL, NULL, NULL);
+ code((np->op == OCALL) ? ASCALLE : ASCALLEX, NULL, NULL, NULL);
 
         return ret;
 }
_AT_@ -535,6 +535,7 @@ rhs(Node *np, Node *ret)
                 code(op, ret, &aux1, &aux2);
                 return ret;
         case OCALL:
+ case OCALLE:
                 if (l->op == OPTR)
                         l = rhs(l, &aux1);
                 return call(np, l, ret);
diff --git a/cc2/arch/qbe/code.c b/cc2/arch/qbe/code.c
index d6cad6c..0a62e24 100644
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
_AT_@ -138,7 +138,8 @@ static struct opdata {
         [ASJMP] = {.fun = jmp},
         [ASRET] = {.fun = ret},
         [ASCALL] = {.fun = call},
- [ASCALLE] = {.fun = ecall},
+ [ASCALLE] = {.fun = ecall, .txt = ")"},
+ [ASCALLEX] = {.fun = ecall, .txt = ", ...)"},
         [ASPAR] = {.fun = param, .txt = "%s %s, "},
         [ASPARE] = {.fun = param, .txt = "%s %s"},
         [ASALLOC] = {.fun = alloc},
_AT_@ -461,7 +462,9 @@ param(void)
 static void
 ecall(void)
 {
- puts(")");
+ struct opdata *p = &optbl[pc->op];
+
+ puts(p->txt);
 }
 
 static void
diff --git a/cc2/cc2.h b/cc2/cc2.h
index 5a7d2ba..5b06260 100644
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
_AT_@ -84,6 +84,7 @@ enum op {
         OASSIG = ':',
         OSNEG = '_',
         OCALL = 'c',
+ OCALLE = 'z',
         OPAR = 'p',
         OFIELD = '.',
         OCOMMA = ',',
diff --git a/cc2/parser.c b/cc2/parser.c
index 301a619..e8ea893 100644
--- a/cc2/parser.c
+++ b/cc2/parser.c
_AT_@ -127,6 +127,7 @@ static struct decoc {
         [':'] = { NULL, assign, .u.op = OASSIG},
         ['?'] = { NULL, ternary, .u.op = OASK},
         ['c'] = { NULL, call, .u.op = OCALL},
+ ['z'] = { NULL, call, .u.op = OCALLE},
 
         ['#'] = { NULL,constant, .u.op = OCONST},
 
Received on Tue Feb 14 2017 - 15:22:32 CET

This archive was generated by hypermail 2.3.0 : Tue Feb 14 2017 - 15:24:20 CET