From: Alan Cox Date: Sun, 29 Oct 2017 18:07:14 +0000 (+0000) Subject: smallc: tidy up a bit, align Z80 with assembler and fix bogus pop bc bug X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=0a75e2fc3ecc77f3ebe1a41c6a44fb000ffae042;p=FUZIX.git smallc: tidy up a bit, align Z80 with assembler and fix bogus pop bc bug --- diff --git a/Applications/SmallC/TODO b/Applications/SmallC/TODO index c81ddccd..9a9ddde8 100644 --- a/Applications/SmallC/TODO +++ b/Applications/SmallC/TODO @@ -21,6 +21,42 @@ L1234: data .. - Proper constant typing - Type promotion +We need a post processor that does + +1. Turn error number/lines into error reporting (so we can avoid the strings + in the compiler) +2. Parses a record for each definition/use of a function checking the + prototype and doing mismatch warnings and use before defines + +In particular we need to encode prototypes very tightly in main memory so +can't afford to do all the work in the cc first pass but we can write the +full thing out and internally pack a function as + +[type|nargs][name][argbits] + +and pack each argument including return as + +0000 char +0001 short/int +0011 long int +0100 unsigned char +0101 unsigned short/int +0110 float/double +0111 unsigned long +1000 ptr (to anytbing) +1110 ...(with implied endmark) +1111 endmark + +thus representing each possible type in 4 bits with enough information for +casting and promotion. + +This lets us store functions as + +name[typelist] + +where the first typelist is the return. foo() is foo(...) and foo(void) is +zero arguments + Macro ops for bytecode form load r1 (fprel) ; with pre/post inc dec diff --git a/Applications/SmallC/code6801.c b/Applications/SmallC/code6801.c index 15e9100e..090e8506 100644 --- a/Applications/SmallC/code6801.c +++ b/Applications/SmallC/code6801.c @@ -66,6 +66,15 @@ void output_label_terminator (void) { xdirty = 1; } +/** + * Output a C label with leading _ + */ +void output_label_name(char *p) +{ + output_byte('_'); + output_string(p); +} + /** * begin a comment line for the assembler */ @@ -141,7 +150,7 @@ static void describe_access(SYMBOL *sym) } else if (sym->storage == LSTATIC) print_label(sym->offset); else - output_string(sym->name); + output_label_name(sym->name); newline(); } diff --git a/Applications/SmallC/code6809.c b/Applications/SmallC/code6809.c index 6430bdf8..5a687a55 100644 --- a/Applications/SmallC/code6809.c +++ b/Applications/SmallC/code6809.c @@ -55,6 +55,15 @@ void output_label_terminator (void) { output_byte (':'); } +/** + * Output a C label with leading _ + */ +void output_label_name(char *p) +{ + output_byte('_'); + output_string(p); +} + /** * begin a comment line for the assembler */ @@ -138,7 +147,7 @@ static void describe_access(SYMBOL *sym) output_number(sym->offset - stkp); output_string(",s"); } else - output_string(sym->name); + output_label_name(sym->name); newline(); } diff --git a/Applications/SmallC/code8080.c b/Applications/SmallC/code8080.c index 76889f4b..507e06da 100644 --- a/Applications/SmallC/code8080.c +++ b/Applications/SmallC/code8080.c @@ -63,6 +63,15 @@ void output_label_terminator (void) { output_byte (':'); } +/** + * Output a C label with leading _ + */ +void output_label_name(char *p) +{ + output_byte('_'); + output_string(p); +} + /** * begin a comment line for the assembler */ @@ -127,7 +136,7 @@ static void describe_access(SYMBOL *sym) if (sym->storage == LSTATIC) print_label(sym->offset); else - output_string(sym->name); + output_label_name(sym->name); newline(); } diff --git a/Applications/SmallC/codegeneric.c b/Applications/SmallC/codegeneric.c index 5c5c519e..6c66e7dc 100644 --- a/Applications/SmallC/codegeneric.c +++ b/Applications/SmallC/codegeneric.c @@ -57,6 +57,15 @@ void output_label_terminator (void) { output_byte (':'); } +/** + * Output a C label with leading _ + */ +void output_label_name(char *p) +{ + output_byte('_'); + output_string(p); +} + /** * begin a comment line for the assembler */ @@ -163,7 +172,7 @@ static void describe_access(SYMBOL *sym) output_number(sym->offset); output_string("+fp"); } else - output_string(sym->name); + output_label_name(sym->name); output_byte(')'); newline(); } diff --git a/Applications/SmallC/codez80.c b/Applications/SmallC/codez80.c index d7447963..7b56b9f6 100644 --- a/Applications/SmallC/codez80.c +++ b/Applications/SmallC/codez80.c @@ -21,13 +21,7 @@ static int regv[8]; * print all assembler info before any code is generated */ void header (void) { - output_string ("; Small C Z80\n;\tCoder (ac0)\n;"); - frontend_version(); - newline (); - output_line ("\t;program area SMALLC_GENERATED is RELOCATABLE"); - output_line ("\t.module SMALLC_GENERATED"); - output_line ("\t.list (err, loc, bin, eqt, cyc, lin, src, lst, md)"); - output_line ("\t.nlist (pag)"); + output_line("\t.code"); } /** @@ -39,16 +33,23 @@ void newline (void) { } void initmac(void) { - defmac("cpm\t1"); - defmac("Z80\t1"); - defmac("smallc\t1"); } /** * Output internal generated label prefix */ void output_label_prefix(void) { - output_byte('$'); + output_byte('L'); +} + +/** + * Output a label with leading _ + */ + +void output_label_name(char *p) +{ + output_byte('_'); + output_string(p); } /** @@ -76,14 +77,14 @@ void trailer(void) { * text (code) segment */ void code_segment_gtext(void) { - output_line ("\t.area SMALLC_GENERATED (REL,CON,CSEG)"); + output_line ("\t.code"); } /** * data segment */ void data_segment_gdata(void) { - output_line ("\t.area SMALLC_GENERATED_DATA (REL,CON,DSEG)"); + output_line ("\t.data"); } /** @@ -92,9 +93,11 @@ void data_segment_gdata(void) { */ void ppubext(SYMBOL *scptr) { if (symbol_table[current_symbol_table_idx].storage == STATIC) return; - output_with_tab (scptr->storage == EXTERN ? ";extrn\t" : ".globl\t"); - output_string (scptr->name); - newline(); + if (scptr->storage != EXTERN) { + output_with_tab (".export\t"); + output_label_name (scptr->name); + newline(); + } } /** @@ -103,9 +106,11 @@ void ppubext(SYMBOL *scptr) { */ void fpubext(SYMBOL *scptr) { if (scptr->storage == STATIC) return; - output_with_tab (scptr->offset == FUNCTION ? ".globl\t" : ";extrn\t"); - output_string (scptr->name); - newline (); + if (scptr->offset == FUNCTION) { + output_with_tab(".export\t"); + output_label_name (scptr->name); + newline (); + } } /** @@ -123,13 +128,6 @@ static void output_number_signed(int num) output_decimal(num); } -static void output_bracketed(char *p) -{ - output_byte('('); - output_string(p); - output_byte(')'); -} - static void describe_access(SYMBOL *sym, int s) { if (sym->storage == REGISTER) { @@ -147,7 +145,7 @@ static void describe_access(SYMBOL *sym, int s) output_byte(')'); } else { output_byte('('); - output_string(sym->name); + output_label_name(sym->name); output_byte(')'); } } @@ -355,7 +353,7 @@ void gen_swap_stack(void) { */ void gen_call(char *sname) { output_with_tab ("call "); - output_string (sname); + output_label_name (sname); newline (); } @@ -363,7 +361,7 @@ void gen_call(char *sname) { * declare entry point */ void declare_entry_point(char *symbol_name) { - output_string(symbol_name); + output_label_name(symbol_name); output_label_terminator(); newline(); } @@ -371,7 +369,7 @@ void declare_entry_point(char *symbol_name) { void gen_prologue(void) { output_line("push ix"); - output_line("ld ix,#0"); + output_line("ld ix,0"); output_line("add ix,sp"); stkp = stkp - INTSIZE; nextreg = 0; @@ -381,7 +379,8 @@ void gen_epilogue(void) { if (nextreg) gen_modify_stack(regv[0]); - output_line("pop bc"); + if (nextreg) + output_line("pop bc"); stkp += 2; output_line("ld sp,ix"); output_line("pop ix"); @@ -399,12 +398,8 @@ void gen_ret(void) { * perform subroutine call to value on top of stack */ void callstk(void) { - gen_immediate (); - output_string ("#.+5"); - newline (); - gen_swap_stack (); - output_line ("jp (hl)"); - stkp = stkp + INTSIZE; + gen_pop(); + gen_call("callhl"); /* call to a jp(hl) */ } /** @@ -439,21 +434,21 @@ void gen_test_jump(int label, int ft) * print pseudo-op to define a byte */ void gen_def_byte(void) { - output_with_tab (".db "); + output_with_tab (".byte "); } /** * print pseudo-op to define storage */ void gen_def_storage(void) { - output_with_tab (".ds "); + output_with_tab (".blkb "); } /** * print pseudo-op to define a word */ void gen_def_word(void) { - output_with_tab (".dw "); + output_with_tab (".word "); } /** diff --git a/Applications/SmallC/function.c b/Applications/SmallC/function.c index 04056745..a4f4bd88 100644 --- a/Applications/SmallC/function.c +++ b/Applications/SmallC/function.c @@ -101,7 +101,7 @@ void newfunc_typed(int storage, char *n, int type) if (symbol->offset == FUNCTION) multidef(n); symbol->offset = FUNCTION; - output_string(n); + output_label_name(n); output_label_terminator(); newline(); gen_prologue(); diff --git a/Applications/SmallC/gen.c b/Applications/SmallC/gen.c index 8e0d0ba0..b88b23fb 100644 --- a/Applications/SmallC/gen.c +++ b/Applications/SmallC/gen.c @@ -41,7 +41,7 @@ void print_label(int label) { * @param lab label number */ void glabel(char *lab) { - output_string (lab); + output_label_name(lab); output_label_terminator (); newline (); } diff --git a/Applications/SmallC/primary.c b/Applications/SmallC/primary.c index 8a139610..85617aa8 100644 --- a/Applications/SmallC/primary.c +++ b/Applications/SmallC/primary.c @@ -109,7 +109,7 @@ int primary(LVALUE *lval) { gen_get_locale(symbol); } else { gen_immediate(); - output_string(symbol->name); + output_label_name(symbol->name); newline(); } lval->indirect = symbol->type; diff --git a/Applications/SmallC/prototype.h b/Applications/SmallC/prototype.h index 711866da..de27a991 100644 --- a/Applications/SmallC/prototype.h +++ b/Applications/SmallC/prototype.h @@ -106,6 +106,7 @@ extern void glabel(char *lab); extern void generate_label(int nlab); extern int output_byte(char c); extern void output_string(char ptr[]); +extern void output_label_name(char ptr[]); extern void print_tab(void); extern void output_line(char ptr[]); extern void output_with_tab(char ptr[]);