shithub: scc

Download patch

ref: cd137ca7a0463d165f29279b89e463c17553b32d
parent: b0fde52316fa7c33aa5045eff6ce6bfbd84a66a7
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Sep 8 13:41:54 EDT 2017

[as] Remove Bucket structure

A 2 pass assembler knows the size of the section, so we can
allocate the full buffer for it and avoid linked lists.

--- a/as/as.h
+++ b/as/as.h
@@ -10,7 +10,7 @@
 typedef struct op Op;
 typedef struct arg Arg;
 typedef void Format(Op *, Arg *);
-typedef struct sec Section;
+typedef struct section Section;
 
 enum {
 	BITS16,
@@ -34,13 +34,12 @@
 	TUINT val;
 };
 
-struct bucket;
-
-struct sec {
+struct section {
 	char *name;
-	struct bucket *mem;
+	char *mem;
 	int flags;
 	TUINT base;
+	TUINT max;
 	TUINT curpc;
 	TUINT pc;
 };
--- a/as/emit.c
+++ b/as/emit.c
@@ -5,16 +5,6 @@
 #include "../inc/scc.h"
 #include "as.h"
 
-#define BUCKETSIZ 0x100
-
-typedef struct bucket Bucket;
-
-struct bucket {
-	char mem[BUCKETSIZ];
-	TUINT base;
-	struct bucket *next;
-};
-
 Section text = (Section) {.name = "text", .flags = SRELOC|SEXEC|SFILE};
 Section data = (Section) {.name = "data", .flags = SRELOC|SREAD|SWRITE|SFILE};
 Section bss = (Section) {.name = "bss", .flags = SRELOC|SREAD|SWRITE};
@@ -22,44 +12,22 @@
 
 int pass;
 
-void
-isections(void)
+static void
+isec(Section *sec)
 {
-	text.curpc = text.pc = text.base;
-	data.curpc = data.pc = data.base;
-	bss.curpc = bss.pc = bss.base;
+	sec->curpc = sec->pc = sec->base;
+	if (sec->max > 0)
+		sec->mem = xmalloc(sec->max - sec->base);
 }
 
-static struct bucket *
-alloc(TUINT addr)
+void
+isections(void)
 {
-	struct bucket *bp;
-
-	bp = memset(xmalloc(sizeof(*bp)), 0, sizeof(*bp));
-	bp->base = addr+BUCKETSIZ & BUCKETSIZ-1;
-	return bp;
+	isec(&text);
+	isec(&data);
+	isec(&bss);
 }
 
-static void
-emitbyte(Section *sec, char byte, TUINT addr)
-{
-	struct bucket *cur, *next;
-	TUINT base;
-
-	for (cur = sec->mem; ; cur = cur->next) {
-		base = cur->base;
-		if (base <= addr && addr < base+BUCKETSIZ)
-			break;
-
-		next = cur->next;
-		if (base < addr && next->base > addr) {
-			cur->next = alloc(addr);
-			cur->next->next = next;
-		}
-	}
-	cur->mem[addr - cur->base] = byte;
-}
-
 void
 emit(Section *sec, char *bytes, int nbytes)
 {
@@ -68,13 +36,8 @@
 	if (pass == 1 || !(sec->flags & SFILE))
 		return;
 
-	if (!sec->mem) {
-		sec->mem = alloc(sec->base);
-		sec->mem->next = sec->mem;
-	}
-
-	for (addr = sec->pc; nbytes--; addr++)
-		emitbyte(sec, *bytes++, addr);
+	for (addr = sec->pc - sec->base; nbytes--; addr++)
+		sec->mem[addr] = *bytes++;
 }
 
 void
@@ -81,16 +44,11 @@
 writeout(char *name)
 {
 	FILE *fp;
-	Bucket *bp;
 
 	if ((fp = fopen(name, "wb")) == NULL)
 		die("error opening output file '%s'\n", name);
 
-	for (bp = text.mem; ; bp = bp->next) {
-		fwrite(bp->mem, BUCKETSIZ, 1, fp);
-		if (bp->next == text.mem)
-			break;
-	}
+	fwrite(text.mem, text.max - text.base, 1, fp);
 
 	if (fclose(fp))
 		die("error writing the output file");
--- a/as/main.c
+++ b/as/main.c
@@ -69,8 +69,10 @@
 		return;
 	}
 	(*op->format)(op, args);
-	cursec->pc += op->size;
 	cursec->curpc += op->size;
+	cursec->pc += op->size;
+	if (cursec->pc > cursec->max)
+		cursec->max = cursec->pc;
 }
 
 int