scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 8433368cb88bceb2510fadea9ad5ccbae33c6f3a
parent 79bfc94dd4d53e3f66e6e96d44ca8666d7294c62
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 31 Dec 2024 16:37:01 +0100

cc2: Move switch code to a different file

The code required for switch is going to be long enough to deserve
its own file.

Diffstat:
Msrc/cmd/scc-cc/cc2/Makefile | 1+
Msrc/cmd/scc-cc/cc2/cc2.h | 4++++
Msrc/cmd/scc-cc/cc2/cfg.c | 131-------------------------------------------------------------------------------
Msrc/cmd/scc-cc/cc2/parser.c | 1+
Msrc/cmd/scc-cc/cc2/qbe/cgen.c | 11++++++-----
Msrc/cmd/scc-cc/cc2/qbe/stubs.c | 5+++++
Asrc/cmd/scc-cc/cc2/swtch.c | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/cmd/scc-cc/cc2/z80-scc/cgen.c | 7+------
8 files changed, 154 insertions(+), 142 deletions(-)

diff --git a/src/cmd/scc-cc/cc2/Makefile b/src/cmd/scc-cc/cc2/Makefile @@ -23,6 +23,7 @@ QBE_OBJS =\ OBJS =\ cfg.o\ + swtch.o\ $(QBE_OBJS)\ QBE_AMD64_SYSV_OBJS=\ diff --git a/src/cmd/scc-cc/cc2/cc2.h b/src/cmd/scc-cc/cc2/cc2.h @@ -293,7 +293,11 @@ extern void freesym(Symbol *sym); extern void gencfg(void); extern void cleancfg(void); extern Node *sethi(Node *); + +/* swtch.c */ +extern void cleanswtch(void); extern Swtch *newswitch(Swtch *); +extern Node *swtch(Node *); /* globals */ extern Symbol *curfun; diff --git a/src/cmd/scc-cc/cc2/cfg.c b/src/cmd/scc-cc/cc2/cfg.c @@ -1,10 +1,4 @@ -/* - * This file is very tied with nodes.c and the main reason why - * this is not included directly in node.c is because all this - * code is not needed in qbe targets. - */ #include <assert.h> -#include <limits.h> #include <stdlib.h> #include <string.h> @@ -28,7 +22,6 @@ struct cfg { }; static struct cfg cfg; -static Swtch *switchlist; #ifndef NDEBUG #include <stdio.h> @@ -286,132 +279,8 @@ gencfg(void) void cleancfg(void) { - Swtch *p, *next; - free(cfg.blocks); memset(&cfg, 0, sizeof(cfg)); - - for (p = switchlist; p; p = next) { - next = p; - free(p); - } -} - -static Node * -swtch_if(Node *idx) -{ - Node *tmpvar, *next, *tmp, *np; - Symbol *deflabel = NULL; - - tmpvar = tmpnode(&idx->type); - idx->right = idx->left; - idx->right = tmpvar; - idx->op = OASSIG; - - for (np = idx->next; ; np = next) { - next = np->next; - - switch (np->op) { - case OESWITCH: - if (!deflabel) - deflabel = np->u.sym; - np->op = OJMP; - np->u.sym = deflabel; - return sethi(idx); - case OCASE: - np->op = OBRANCH; - tmp = node(OEQ); - tmp->type = idx->type; - tmp->left = np->left; - tmp->right = tmpvar; - np->left = tmp; - break; - case ODEFAULT: - deflabel = np->u.sym; - delstmt(np); - break; - default: - abort(); - } - } -} - -static Node * -swtch_dir(Node *np, int n, TINT min, TINT max) -{ - Node aux, *p, *defnode; - Node **its, **zero, **ip; - Symbol *tbl; - - its = xcalloc(n, sizeof(*its)); - zero = its; - if (min < 0) - zero -= min; - - for (p = np->next; p->op != OESWITCH; p = p->next) { - if (p->op == ODEFAULT) - defnode = p; - else - its[p->left->u.i] = p; - p->type = ptrtype; - p->op = OLABEL; - } - np->next = p->next; - - for (ip = its; ip < &its[n]; ++ip) { - if (*ip == NULL) - *ip = defnode; - } - - tbl = getsym(TMPSYM); - tbl->kind = SLOCAL; - tbl->type = ptrtype; - tbl->type.flags |= INITF; - - defglobal(tbl); - for (ip = its; ip < &its[n]; ++ip) - data(*ip); - endinit(); -} - -static Node * -swtch(Node *np) -{ - int n; - TINT min, max, range, val; - Node *p, *def = NULL; - - min = TINT_MAX; - max = n = 0; - for (p = np->next; p->op != OESWITCH; p = p->next) { - if (p->op != ODEFAULT) { - val = p->left->u.i; - if (val > max) - max = val; - if (val < min) - min = val; - ++n; - } - } - - if (n < 4) - return swtch_if(np); - - range = max - min + 1; - if (range == n) - return swtch_dir(np, range, min, max); - - abort(); -} - -Swtch * -newswitch(Swtch *swt) -{ - Swtch *p = xmalloc(sizeof(*p)); - - *p = *swt; - p->next = switchlist; - return switchlist = p; } Node * diff --git a/src/cmd/scc-cc/cc2/parser.c b/src/cmd/scc-cc/cc2/parser.c @@ -704,6 +704,7 @@ void parse(void) { /* clean from previous function */ + cleanswtch(); cleancfg(); cleannodes(); popctx(); diff --git a/src/cmd/scc-cc/cc2/qbe/cgen.c b/src/cmd/scc-cc/cc2/qbe/cgen.c @@ -483,12 +483,13 @@ function(void) return NULL; } -static void -swtch(Node *swt, Node *idx) +Node * +swtch(Node *swt) { - Node aux1, aux2, *np; + Node aux1, aux2, *np, *idx; Symbol *deflabel = NULL; + idx = rhs(swt->left); for (np = swt->next; ; np = np->next) { setlabel(np->label); @@ -501,7 +502,7 @@ swtch(Node *swt, Node *idx) aux1.u.sym = deflabel; cgen(&aux1); delrange(swt->next, np); - return; + return NULL; case OCASE: aux1 = *np; aux1.op = OBRANCH; @@ -777,7 +778,7 @@ cgen(Node *np) code(ASRET, NULL, p, NULL); break; case OBSWITCH: - swtch(np, rhs(np->left)); + swtch(np); break; default: rhs(np); diff --git a/src/cmd/scc-cc/cc2/qbe/stubs.c b/src/cmd/scc-cc/cc2/qbe/stubs.c @@ -26,3 +26,8 @@ newswitch(Swtch *swt) { return NULL; } + +void +cleanswtch(void) +{ +} diff --git a/src/cmd/scc-cc/cc2/swtch.c b/src/cmd/scc-cc/cc2/swtch.c @@ -0,0 +1,136 @@ +#include <limits.h> +#include <stdlib.h> + +#include <scc/scc.h> + +#include "cc2.h" + +static Swtch *list; + +static Node * +swtch_if(Node *idx) +{ + Node *tmpvar, *next, *tmp, *np; + Symbol *deflabel = NULL; + + tmpvar = tmpnode(&idx->type); + idx->right = idx->left; + idx->right = tmpvar; + idx->op = OASSIG; + + for (np = idx->next; ; np = next) { + next = np->next; + + switch (np->op) { + case OESWITCH: + if (!deflabel) + deflabel = np->u.sym; + np->op = OJMP; + np->u.sym = deflabel; + return sethi(idx); + case OCASE: + np->op = OBRANCH; + tmp = node(OEQ); + tmp->type = idx->type; + tmp->left = np->left; + tmp->right = tmpvar; + np->left = tmp; + break; + case ODEFAULT: + deflabel = np->u.sym; + delstmt(np); + break; + default: + abort(); + } + } +} + +static Node * +swtch_dir(Node *np, int n, TINT min, TINT max) +{ + Node aux, *p, *defnode; + Node **its, **zero, **ip; + Symbol *tbl; + + its = xcalloc(n, sizeof(*its)); + zero = its; + if (min < 0) + zero -= min; + + for (p = np->next; p->op != OESWITCH; p = p->next) { + if (p->op == ODEFAULT) + defnode = p; + else + its[p->left->u.i] = p; + p->type = ptrtype; + p->op = OLABEL; + } + np->next = p->next; + + for (ip = its; ip < &its[n]; ++ip) { + if (*ip == NULL) + *ip = defnode; + } + + tbl = getsym(TMPSYM); + tbl->kind = SLOCAL; + tbl->type = ptrtype; + tbl->type.flags |= INITF; + + defglobal(tbl); + for (ip = its; ip < &its[n]; ++ip) + data(*ip); + endinit(); +} + +Node * +swtch(Node *np) +{ + int n; + TINT min, max, range, val; + Node *p, *def = NULL; + + min = TINT_MAX; + max = n = 0; + for (p = np->next; p->op != OESWITCH; p = p->next) { + if (p->op != ODEFAULT) { + val = p->left->u.i; + if (val > max) + max = val; + if (val < min) + min = val; + ++n; + } + } + + if (n < 4) + return swtch_if(np); + + range = max - min + 1; + if (range == n) + return swtch_dir(np, range, min, max); + + abort(); +} + +Swtch * +newswitch(Swtch *swt) +{ + Swtch *p = xmalloc(sizeof(*p)); + + *p = *swt; + p->next = list; + return list = p; +} + +void +cleanswtch(void) +{ + Swtch *p, *next; + + for (p = list; p; p = next) { + next = p; + free(p); + } +} diff --git a/src/cmd/scc-cc/cc2/z80-scc/cgen.c b/src/cmd/scc-cc/cc2/z80-scc/cgen.c @@ -105,11 +105,6 @@ static Node regs[] = { } }; -static void -swtch(Node *idx) -{ -} - void defpar(Symbol *sym) { @@ -549,7 +544,7 @@ cgen(Node *np) ret(np); break; case OBSWITCH: - swtch(rhs(np->left)); + /* TODO */ break; default: rhs(np);