scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit a43a8ede995f69063e33713f304d5ced7b5b3edb
parent 9af861a9ca611b8b04d0cb6d7713adae1ef0494b
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  5 Aug 2014 10:41:09 +0200

Calculate addresability of statements

Every node of the tree is labeled with a small number that indicate
the addresability of the node. The algorithm is taken from [1], and
basically it has a table where all the expressions directly
addresable assign a number, and expressions that are not directly
addresable are marked.

[1] Plan 9 C Compilers: http://plan9.bell-labs.com/sys/doc/compiler.html

Diffstat:
cc2/Makefile | 4++--
cc2/cc2.h | 25+++++++++++++++++++++++++
cc2/cgen.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
cc2/parser.c | 29++++++-----------------------
cgen.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 139 insertions(+), 25 deletions(-)

diff --git a/cc2/Makefile b/cc2/Makefile @@ -1,5 +1,5 @@ -OBJS = main.o parser.o +OBJS = main.o parser.o cgen.o CPPFLAGS = -I../inc LDFLAGS = -L../lib @@ -7,7 +7,7 @@ LIBS = -lcc all: cc2 -$(OBJS): ../inc/cc.h ../inc/sizes.h +$(OBJS): ../inc/cc.h ../inc/sizes.h cc2.h cc2: $(OBJS) ../lib/libcc.a $(CC) $(LDFLAGS) $(CFLAGS) $(OBJS) $(LIBS) -o $@ diff --git a/cc2/cc2.h b/cc2/cc2.h @@ -0,0 +1,25 @@ + +typedef struct { + union { + struct { + char type; + char storage; + } v; + struct { + short addr; + } l; + } u; +} Symbol; + +typedef struct node { + char op; + char type; + int8_t sethi; + int8_t addrtype; + union { + short id; + int imm; + } u; + struct node *left, *right; +} Node; + diff --git a/cc2/cgen.c b/cc2/cgen.c @@ -0,0 +1,53 @@ + +#include <assert.h> +#include <stddef.h> +#include <stdint.h> + +#include "cc2.h" + +struct addrtype { + char op; + char left; + char right; + char addrtype; +} addrtbl[] = { + {'A', 0, 0, 1}, + {'#', 0, 0, 2}, + {'+', 1, 2, 3}, + {0}, +}; + +struct nodeattr { + char addrtype; + char sethi; +}; + +struct nodeattr +genaddr(Node *np) +{ + struct nodeattr left, right; + struct addrtype *bp; + + left = (np->left) ? genaddr(np->left) : (struct nodeattr) {0, -1}; + right = (np->right) ? genaddr(np->right) : (struct nodeattr) {0, -1}; + + for (bp = addrtbl; bp->op; ++bp) { + if (bp->op == np->op && + left.addrtype == bp->left && + right.addrtype == bp->right) { + break; + } + } + + if ((np->addrtype = bp->addrtype) == 0) { + np->sethi = 0; + } else if (right.sethi < 0) { + np->sethi = (left.sethi > 1) ? left.sethi : 1; + } else { + int8_t d = left.sethi - right.sethi; + np->sethi = ((d < 0) ? right.sethi : left.sethi) + 1; + } + + return (struct nodeattr) {np->addrtype, np->sethi}; +} + diff --git a/cc2/parser.c b/cc2/parser.c @@ -1,10 +1,13 @@ #include <ctype.h> +#include <stdint.h> #include <stdio.h> #include <cc.h> #include <sizes.h> +#include "cc2.h" + #define STR(x) XSTR(x) #define XSTR(x) #x @@ -13,28 +16,6 @@ #define NR_EXPRESSIONS 64 #define NR_SYMBOLS 1024 -typedef struct { - union { - struct { - char type; - char storage; - } v; - struct { - short addr; - } l; - } u; -} Symbol; - -typedef struct node { - char op; - char type; - union { - short id; - int imm; - } u; - struct node *left, *right; -} Node; - static Node *stack[NR_STACKSIZ], **stackp = stack; static Node *listexp[NR_EXPRESSIONS], **listp = &listexp[0]; static Node nodepool[NR_NODEPOOL], *newp = nodepool; @@ -248,10 +229,11 @@ function(void) } } -int +void parse(void) { int c; + void genaddr(Node *np); for (;;) { switch (c = getchar()) { @@ -260,6 +242,7 @@ parse(void) break; case 'X': function(); + genaddr(listexp[0]); break; case EOF: return; diff --git a/cgen.c b/cgen.c @@ -0,0 +1,53 @@ + +#include <assert.h> +#include <stddef.h> +#include <stdint.h> + +#include "cc2.h" + +struct addrtype { + char op; + char left; + char right; + char addrtype; +} addrtbl[] = { + {'A', 0, 0, 1}, + {'#', 0, 0, 2}, + {'+', 1, 2, 3}, + {0}, +}; + +struct nodeattr { + char addrtype; + char sethi; +}; + +struct nodeattr +genaddr(Node *np) +{ + struct nodeattr left, right; + struct addrtype *bp; + + left = (np->left) ? genaddr(np->left) : (struct nodeattr) {0, -1}; + right = (np->right) ? genaddr(np->right) : (struct nodeattr) {0, -1}; + + for (bp = addrtbl; bp->op; ++bp) { + if (bp->op == np->op && + left.addrtype == bp->left && + right.addrtype == bp->right) { + break; + } + } + + if ((np->addrtype = bp->addrtype) == 0) { + np->sethi = 0; + } else if (right.sethi < 0) { + np->sethi = (left.sethi > 1) ? left.sethi : 1; + } else { + int8_t d = left.sethi - right.sethi; + np->sethi = ((d < 0) ? right.sethi : left.sethi) + 1; + } + + return (struct nodeattr) {np->addrtype, np->sethi}; +} +