shithub: scc

Download patch

ref: a43a8ede995f69063e33713f304d5ced7b5b3edb
parent: 9af861a9ca611b8b04d0cb6d7713adae1ef0494b
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Aug 5 06:41:09 EDT 2014

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

--- 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 @@
 
 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 $@
--- /dev/null
+++ b/cc2/cc2.h
@@ -1,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;
+
--- /dev/null
+++ b/cc2/cgen.c
@@ -1,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};
+}
+
--- 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 @@
 	}
 }
 
-int
+void
 parse(void)
 {
 	int c;
+	void genaddr(Node *np);
 
 	for (;;) {
 		switch (c = getchar()) {
@@ -260,6 +242,7 @@
 			break;
 		case 'X':
 			function();
+			genaddr(listexp[0]);
 			break;
 		case EOF:
 			return;
--- /dev/null
+++ b/cgen.c
@@ -1,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};
+}
+