commit 79e21860ac133bb98f1dcf5a1ecf22759e6e0e26
parent 497fb0862cf20043e7f735c93b2e8f24934adf1f
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 8 Sep 2017 17:41:54 +0200
[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.
Diffstat:
3 files changed, 20 insertions(+), 61 deletions(-)
diff --git a/as/as.h b/as/as.h
@@ -10,7 +10,7 @@ typedef struct ins Ins;
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 @@ struct arg {
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;
};
diff --git 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,42 +12,20 @@ Section *cursec = &text;
int pass;
-void
-isections(void)
-{
- text.curpc = text.pc = text.base;
- data.curpc = data.pc = data.base;
- bss.curpc = bss.pc = bss.base;
-}
-
-static struct bucket *
-alloc(TUINT addr)
+static void
+isec(Section *sec)
{
- struct bucket *bp;
-
- bp = memset(xmalloc(sizeof(*bp)), 0, sizeof(*bp));
- bp->base = addr+BUCKETSIZ & BUCKETSIZ-1;
- return bp;
+ sec->curpc = sec->pc = sec->base;
+ if (sec->max > 0)
+ sec->mem = xmalloc(sec->max - sec->base);
}
-static void
-emitbyte(Section *sec, char byte, TUINT addr)
+void
+isections(void)
{
- 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;
+ isec(&text);
+ isec(&data);
+ isec(&bss);
}
void
@@ -68,29 +36,19 @@ emit(Section *sec, char *bytes, int nbytes)
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
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");
diff --git a/as/main.c b/as/main.c
@@ -69,8 +69,10 @@ as(char *text, char *xargs)
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