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:
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);