From: Alan Cox Date: Wed, 30 Nov 2016 18:44:37 +0000 (+0000) Subject: scc: turn arguments the right way round X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=f8c9e9aefe8ab73ffdb582f117fe14f959a7a6cf;p=FUZIX.git scc: turn arguments the right way round Small C has an irritating design feature that means it stacks arguments left to right not right to left. Rather than working around this use a spool file so we can put the code fragments in right to left order. This totally changes the ABI, which is fine because we aren't using it for anything and the old ABI is a PITA. With this done we can actually write sane syscall stubs. Would benefit from optimisations to also use the internal buffer as a stack not just flush to the spool file as we stack code fragments. Needless to say all the old varargs gunge is now a) broken and b) not needed --- diff --git a/Applications/SmallC/Makefile b/Applications/SmallC/Makefile index 14870ce5..b1bd2da9 100644 --- a/Applications/SmallC/Makefile +++ b/Applications/SmallC/Makefile @@ -5,7 +5,7 @@ CFLAGS = -DTINY COPT = -O2 OBJS = initials.rel data.rel error.rel expr.rel function.rel gen.rel io.rel \ - lex.rel main.rel preproc.rel primary.rel stmt.rel struct.rel sym.rel while.rel + lex.rel main.rel outstack.rel preproc.rel primary.rel stmt.rel struct.rel sym.rel while.rel OBJ_Z80 = codez80.rel OBJ_8080 = code8080.rel diff --git a/Applications/SmallC/Makefile.linux b/Applications/SmallC/Makefile.linux index 977c5955..a607df60 100644 --- a/Applications/SmallC/Makefile.linux +++ b/Applications/SmallC/Makefile.linux @@ -3,7 +3,7 @@ CFLAGS = -DTINY -DINCDIR=\"includes/\" COPT = -O2 OBJS = initials.o data.o error.o expr.o function.o gen.o io.o \ - lex.o main.o preproc.o primary.o stmt.o struct.o sym.o while.o + lex.o main.o outstack.o preproc.o primary.o stmt.o struct.o sym.o while.o OBJ_Z80 = codez80.o OBJ_8080 = code8080.o diff --git a/Applications/SmallC/data.c b/Applications/SmallC/data.c index d6c97401..26ead77b 100644 --- a/Applications/SmallC/data.c +++ b/Applications/SmallC/data.c @@ -43,7 +43,7 @@ int nxtlab, cmode, lastst; -int input, input2, output; +int input, input2, output, target; int inclstk[INCLSIZ] = {-1, -1, -1 }; int inclsp; char fname[20]; diff --git a/Applications/SmallC/data.h b/Applications/SmallC/data.h index 2ca78fcf..799cb71a 100644 --- a/Applications/SmallC/data.h +++ b/Applications/SmallC/data.h @@ -35,7 +35,7 @@ extern int nxtlab, cmode, lastst; -extern int input, input2, output; +extern int input, input2, output, target; extern int inclstk[]; extern int inclsp; extern char fname[]; @@ -55,3 +55,5 @@ extern int uflag; // undocumented 8085 instructions extern INITIALS initials_table[NUMBER_OF_GLOBALS]; extern char initials_data_table[INITIALS_SIZE]; // 5kB space for initialisation data extern int initials_idx, initials_data_idx; + +extern char obuf[]; diff --git a/Applications/SmallC/gen.c b/Applications/SmallC/gen.c index 46584dbc..5e1bc05c 100644 --- a/Applications/SmallC/gen.c +++ b/Applications/SmallC/gen.c @@ -10,7 +10,7 @@ #include "defs.h" #include "data.h" -static char obuf[512]; +char obuf[512]; /* Shared with outstack for defer uses */ static char *optr = obuf; void oflush(void) diff --git a/Applications/SmallC/main.c b/Applications/SmallC/main.c index e8f1865a..800ff442 100644 --- a/Applications/SmallC/main.c +++ b/Applications/SmallC/main.c @@ -15,7 +15,7 @@ int main(int argc, char *argv[]) { macptr = 0; ctext = 0; errs = 0; - aflag = 1; + aflag = 0; uflag = 0; for (i=1; i +#include +#include +#include +#include +#include +#include "defs.h" +#include "data.h" + +#define MAX_DEFER 64 + +static off_t offset_stack[MAX_DEFER]; +static uint8_t next_defer; +static int defer; + +/* Stack chunks of assembler output to be pasted back into the file later. + We use this to put arguments in the right order while not having to use + tons of RAM */ + +void defer_output(void) +{ + oflush(); + if (next_defer == MAX_DEFER) + error("too many defers"); + /* Remember where our block started */ + offset_stack[next_defer++] = lseek(defer, 0L, 1); + output = defer; +} + +static void copy_block(void) +{ + /* obuf is free at this point */ + long p = offset_stack[next_defer]; + long size = lseek(defer, 0L, 1) - p; + lseek(defer, p, 0); + + while (size) { + /* Can this ever really be over 64K ?? */ + unsigned int n = size; + if (n > 512) + n = 512; + if (read(defer, obuf, n) != n) + error("rd"); + if (write(target, obuf, n) !=n) + error("wr"); + size -= n; + } + lseek(defer, p, 0); +} + +void end_defer(void) +{ + --next_defer; + /* FIXME: we should fastpath the case of all the bits being in + the buffer - in which case we can just fire it at target */ + oflush(); + /* Copy from this position to the current position into the target + file */ + copy_block(); + /* We are back into the main flow, stop outputting via the defer file */ + if (next_defer == 0) + output = target; +} + +void defer_init(void) +{ + defer = open("scc-spool", O_RDWR|O_CREAT|O_TRUNC, 0600); +// unlink("scc-spool"); +} diff --git a/Applications/SmallC/primary.c b/Applications/SmallC/primary.c index 1b443fe8..1832aac4 100644 --- a/Applications/SmallC/primary.c +++ b/Applications/SmallC/primary.c @@ -350,8 +350,10 @@ int spechar(void) { */ void callfunction(char *ptr) { int nargs; + int i; nargs = 0; + blanks (); if (ptr == 0) gen_push (HL_REG); @@ -361,19 +363,25 @@ void callfunction(char *ptr) { expression (NO); if (ptr == 0) gen_swap_stack (); + /* Worth making the first argument pass in HL ?? */ gen_push (HL_REG); - nargs = nargs + INTSIZE; + nargs++; + /* Will need to track sizes later */ if (!match (",")) break; } + /* Now paste the argument generation blocks into the output + in reverse order so the stack is right */ + for (i = 0; i < nargs; i++) + end_defer(); needbrack (")"); if (aflag) - gnargs(nargs / INTSIZE); + gnargs(nargs); if (ptr) gen_call (ptr); else callstk (); - stkp = gen_modify_stack (stkp + nargs); + stkp = gen_modify_stack (stkp + nargs * INTSIZE); } void needlval(void) { diff --git a/Applications/SmallC/prototype.h b/Applications/SmallC/prototype.h index b9334d98..641e9ae8 100644 --- a/Applications/SmallC/prototype.h +++ b/Applications/SmallC/prototype.h @@ -227,3 +227,6 @@ extern WHILE *readwhile(void); extern WHILE *findwhile(void); extern WHILE *readswitch(void); extern void addcase(int val); +extern void defer_output(void); +extern void end_defer(void); +extern void defer_init(void);