- 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
* 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");
}
/**
}
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);
}
/**
* 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");
}
/**
*/
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();
+ }
}
/**
*/
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 ();
+ }
}
/**
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) {
output_byte(')');
} else {
output_byte('(');
- output_string(sym->name);
+ output_label_name(sym->name);
output_byte(')');
}
}
*/
void gen_call(char *sname) {
output_with_tab ("call ");
- output_string (sname);
+ output_label_name (sname);
newline ();
}
* declare entry point
*/
void declare_entry_point(char *symbol_name) {
- output_string(symbol_name);
+ output_label_name(symbol_name);
output_label_terminator();
newline();
}
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;
{
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");
* 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) */
}
/**
* 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 ");
}
/**