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:
M | cc2/Makefile | | | 4 | ++-- |
A | cc2/cc2.h | | | 25 | +++++++++++++++++++++++++ |
A | cc2/cgen.c | | | 53 | +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | cc2/parser.c | | | 29 | ++++++----------------------- |
A | 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};
+}
+