smallc: tidy up a bit, align Z80 with assembler and fix bogus pop bc bug
authorAlan Cox <alan@linux.intel.com>
Sun, 29 Oct 2017 18:07:14 +0000 (18:07 +0000)
committerAlan Cox <alan@linux.intel.com>
Sun, 29 Oct 2017 18:07:14 +0000 (18:07 +0000)
Applications/SmallC/TODO
Applications/SmallC/code6801.c
Applications/SmallC/code6809.c
Applications/SmallC/code8080.c
Applications/SmallC/codegeneric.c
Applications/SmallC/codez80.c
Applications/SmallC/function.c
Applications/SmallC/gen.c
Applications/SmallC/primary.c
Applications/SmallC/prototype.h

index c81ddcc..9a9ddde 100644 (file)
@@ -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
index 15e9100..090e850 100644 (file)
@@ -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();
 }
 
index 6430bdf..5a687a5 100644 (file)
@@ -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();
 }
 
index 76889f4..507e06d 100644 (file)
@@ -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();
 }
 
index 5c5c519..6c66e7d 100644 (file)
@@ -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();
 }
index d744796..7b56b9f 100644 (file)
@@ -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 ");
 }
 
 /**
index 0405674..a4f4bd8 100644 (file)
@@ -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();
index 8e0d0ba..b88b23f 100644 (file)
@@ -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 ();
 }
index 8a13961..85617aa 100644 (file)
@@ -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;
index 711866d..de27a99 100644 (file)
@@ -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[]);