scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 28b4043893d831ce7209dc413e7ce43047de3da0
parent e36b9e60ca5f6b0aaeca720137a70109f77025f5
Author: Roberto E. Vargas Caballero <roberto.vargas@igrid-td.com>
Date:   Mon, 26 Sep 2016 11:41:01 +0200

[cc2-qbe] Implement switch statements

This is a first implementation of switches, which uses a if-else-if
chain. At this point we cannot implement any other form of switch
because we need support for indirect jump in qbe.

Diffstat:
Mcc2/arch/qbe/cgen.c | 50+++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 45 insertions(+), 5 deletions(-)

diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c @@ -414,6 +414,47 @@ function(void) return NULL; } +static void +swtch_if(Node *idx) +{ + Node aux1, aux2, *np; + Symbol *deflabel = NULL; + + for (;;) { + np = delstmt(); + setlabel(np->label); + + switch (np->op) { + case OESWITCH: + if (deflabel) { + aux1.op = OJMP; + aux1.label = NULL; + aux1.u.sym = deflabel; + cgen(&aux1); + } + return; + case OCASE: + aux1 = *np; + aux1.op = OBRANCH; + aux1.label = NULL; + aux1.left = &aux2; + + aux2.op = OEQ; + aux2.type = idx->type; + aux2.left = np->left; + aux2.right = idx; + + cgen(&aux1); + break; + case ODEFAULT: + deflabel = np->u.sym; + break; + default: + abort(); + } + } +} + static Node * rhs(Node *np, Node *ret) { @@ -550,11 +591,6 @@ rhs(Node *np, Node *ret) return lhs(l, ret); case OFIELD: return field(np, ret, 0); - case OCASE: - case ODEFAULT: - case OESWITCH: - case OBSWITCH: - /* TODO: implement these operators */ default: abort(); } @@ -586,6 +622,10 @@ cgen(Node *np) p = (np->left) ? rhs(np->left, &ret) : NULL; code(ASRET, NULL, p, NULL); break; + case OBSWITCH: + p = rhs(np->left, &ret); + swtch_if(p); + break; default: rhs(np, &ret); break;