From: michaelh Date: Mon, 7 Feb 2000 01:15:25 +0000 (+0000) Subject: * Added a simple version of printf() X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=ec321d406e36bf25dda9d824dbe034741b77637d;hp=554b80355adbbbd8436bdb0dd448ef3e956c0871;p=fw%2Fsdcc * Added a simple version of printf() * Added more tests to dhrystone as it's not anywhere near working :) * Remove the signed part from genCmp - is now broken. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@72 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/device/lib/z80/Makefile b/device/lib/z80/Makefile index 41151374..edba5a51 100644 --- a/device/lib/z80/Makefile +++ b/device/lib/z80/Makefile @@ -5,7 +5,7 @@ TOPDIR = ../../.. SCC = $(TOPDIR)/bin/sdcc -mz80 SAS = as-z80 -OBJ = div.o mul.o putchar.o string.o +OBJ = div.o mul.o putchar.o string.o printf.o LIB = z80.lib CC = $(SCC) AS = $(SAS) diff --git a/device/lib/z80/printf.c b/device/lib/z80/printf.c new file mode 100644 index 00000000..b6b4fbee --- /dev/null +++ b/device/lib/z80/printf.c @@ -0,0 +1,78 @@ +/** Simple printf implementation + Again a stub - will use the std one later... +*/ + +#define NULL 0 + +/* A hack because I dont understand how va_arg works... + sdcc pushes right to left with the real sizes, not cast up + to an int. + so printf(int, char, long) + results in push long, push char, push int + On the z80 the stack grows down, so the things seem to be in + the correct order. + */ + +typedef char * va_list; +#define va_start(list, last) list = (char *)&last + sizeof(last) +#define va_arg(list, type) *(type *)list; list += sizeof(type); + +typedef void EMIT(char c, void *pData); + + +static void _printhex(unsigned u, EMIT *emitter, void *pData) +{ + const char *_hex = "0123456789ABCDEF"; + if (u >= 0x10) + _printhex(u/0x10, emitter, pData); + (*emitter)(_hex[u&0x0f], pData); +} + +static void _printf(const char *format, EMIT *emitter, void *pData, va_list va) +{ + while (*format) { + if (*format == '%') { + switch (*++format) { + case 'c': { + char c = va_arg(va, char); + (*emitter)(c, pData); + break; + } + case 'u': + case 'd': + { + unsigned u = va_arg(va, unsigned); + _printhex(u, emitter, pData); + break; + } + case 's': + { + char *s = va_arg(va, char *); + while (*s) { + (*emitter)(*s, pData); + s++; + } + } + } + } + else { + (*emitter)(*format, pData); + } + format++; + } +} + +void putchar(char c); + +static void _char_emitter(char c, void *pData) +{ + putchar(c); +} + +void printf(const char *format, ...) +{ + va_list va; + va_start(va, format); + + _printf(format, _char_emitter, NULL, va); +} diff --git a/src/z80/gen.c b/src/z80/gen.c index fef18979..a1bf75ac 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -734,6 +734,7 @@ static void aopPut (asmop *aop, char *s, int offset) if (!offset && (strcmp(s,"acc") == 0)) break; if (offset>0) { + emitcode("", "; Error aopPut AOP_ACC"); } else { @@ -1715,34 +1716,13 @@ static void genCmp (operand *left,operand *right, while (size--) { /* Do a long subtract */ MOVA(aopGet(AOP(left),offset,FALSE)); - if (sign && size == 0) { - /* Case where it's signed and we've hit the end */ - /* PENDING: This is almost certanitly wrong. - On the 8051 xrl doesnt change C, but xor does. - */ - emitcode("xor","a,#0x80"); - if (AOP_TYPE(right) == AOP_LIT){ - unsigned long lit = (unsigned long) - floatFromVal(AOP(right)->aopu.aop_lit); - emitcode("sbc","a,#0x%02x", - 0x80 ^ (unsigned int)((lit >> (offset*8)) & 0x0FFL)); - } else { - /* The bad way... */ - emitcode("push", "af"); - emitcode("ld","a,%s",aopGet(AOP(right),offset++,FALSE)); - emitcode("xor", "a,#0x80"); - emitcode("ld", "l,a"); - emitcode("pop", "af"); - emitcode("sbc","a,l"); - } - } else { - /* Subtract through, propagating the carry */ - if (offset==0) { - emitcode("sub","a,%s",aopGet(AOP(right),offset++,FALSE)); - } - else - emitcode("sbc","a,%s",aopGet(AOP(right),offset++,FALSE)); + /* PENDING: CRITICAL: support signed cmp's */ + /* Subtract through, propagating the carry */ + if (offset==0) { + emitcode("sub","a,%s",aopGet(AOP(right),offset++,FALSE)); } + else + emitcode("sbc","a,%s",aopGet(AOP(right),offset++,FALSE)); } } } @@ -2281,7 +2261,7 @@ static void genOr (iCode *ic, iCode *ifx) aopOp((right= IC_RIGHT(ic)),ic,FALSE); aopOp((result=IC_RESULT(ic)),ic,TRUE); -#ifdef DEBUG_TYPE +#if 1 emitcode("","; Type res[%d] = l[%d]&r[%d]", AOP_TYPE(result), AOP_TYPE(left), AOP_TYPE(right)); @@ -2336,17 +2316,17 @@ static void genOr (iCode *ic, iCode *ifx) if(((lit >> (offset*8)) & 0x0FFL) == 0x00L) continue; else - emitcode("or","%s,%s", + emitcode("or","%s,%s; 5", aopGet(AOP(left),offset,FALSE), aopGet(AOP(right),offset,FALSE)); } else { if (AOP_TYPE(left) == AOP_ACC) - emitcode("or","a,%s",aopGet(AOP(right),offset,FALSE)); + emitcode("or","a,%s ; 6",aopGet(AOP(right),offset,FALSE)); else { MOVA(aopGet(AOP(right),offset,FALSE)); - emitcode("or","a,%s", + emitcode("or","a,%s ; 7", aopGet(AOP(left),offset,FALSE)); - aopPut(AOP(result),"a",0); + aopPut(AOP(result),"a ; 8",0); } } } @@ -2373,9 +2353,11 @@ static void genOr (iCode *ic, iCode *ifx) MOVA(aopGet(AOP(right),offset,FALSE)); emitcode("or","a,%s", aopGet(AOP(left),offset,FALSE)); - aopPut(AOP(result),"a",0); } aopPut(AOP(result),"a",offset); + /* PENDING: something weird is going on here. Add exception. */ + if (AOP_TYPE(result) == AOP_ACC) + break; } } diff --git a/support/tests/dhrystone/Makefile b/support/tests/dhrystone/Makefile index d55569e6..a3d7d207 100644 --- a/support/tests/dhrystone/Makefile +++ b/support/tests/dhrystone/Makefile @@ -3,7 +3,7 @@ CC = /home/michaelh/projects/sdcc/bin/sdcc # -DNOENUM is here to make the results more predictable CFLAGS = -mz80 -v -CFLAGS += -DREG= -DNOSTRUCTASSIGN -DNOENUM +CFLAGS += -DREG= -DNOSTRUCTASSIGN -DNOENUM -DBROKEN_SDCC=1 LIBDIR = /home/michaelh/projects/sdcc/device/lib/z80/ LD = link-z80 diff --git a/support/tests/dhrystone/dhry.c b/support/tests/dhrystone/dhry.c index 79de20ff..b7f18104 100644 --- a/support/tests/dhrystone/dhry.c +++ b/support/tests/dhrystone/dhry.c @@ -12,6 +12,11 @@ * Removed malloc's for a couple of static arrays. * Into one file. + Notes: + * The comment at the start of Func_1 about the input being + H, R on the first call is wrong - Func_1 is first called + from Func_2 where the input is R, Y. The test still succeeds. + I couldnt find a copyright in the original - the most relevent part follows: @@ -59,6 +64,9 @@ Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val); Boolean Func_2 (char *Str_1_Par_Ref, char *Str_2_Par_Ref); Boolean Func_3 (Enumeration Enum_Par_Val); +void printf(const char *format, ...); +void exit(int val); + int _main(void) { One_Fifty Int_1_Loc; @@ -71,9 +79,7 @@ int _main(void) REG int Run_Index; REG int Number_Of_Runs; -#if !SDCC printf("[dhry]\n"); -#endif Next_Ptr_Glob = &_r[0]; Ptr_Glob = &_r[1]; @@ -82,6 +88,7 @@ int _main(void) Ptr_Glob->Discr = Ident_1; Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; Ptr_Glob->variant.var_1.Int_Comp = 40; + strcpy (Ptr_Glob->variant.var_1.Str_Comp, "DHRYSTONE PROGRAM, SOME STRING"); strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); @@ -96,6 +103,7 @@ int _main(void) /* Main test loop */ for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) { + printf("Proc_5\n"); Proc_5(); Proc_4(); /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */ @@ -103,26 +111,34 @@ int _main(void) Int_2_Loc = 3; strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING"); Enum_Loc = Ident_2; + printf("Func_2\n"); Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc); /* Bool_Glob == 1 */ while (Int_1_Loc < Int_2_Loc) /* loop body executed once */ { + printf("m.1 Executes once.\n"); Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc; /* Int_3_Loc == 7 */ + printf("Proc_7\n"); Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc); /* Int_3_Loc == 7 */ Int_1_Loc += 1; } /* while */ + printf("m.2 Check above executed once.\n"); /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ + printf("Proc_8\n"); Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc); /* Int_Glob == 5 */ + printf("Proc_1\n"); Proc_1 (Ptr_Glob); for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) /* loop body executed twice */ { + printf("Func_1\n"); if (Enum_Loc == Func_1 (Ch_Index, 'C')) /* then, not executed */ { + printf("Proc_6\n"); Proc_6 (Ident_1, &Enum_Loc); strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING"); Int_2_Loc = Run_Index; @@ -134,11 +150,13 @@ int _main(void) Int_1_Loc = Int_2_Loc / Int_3_Loc; Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc; /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */ + printf("Proc_2\n"); Proc_2 (&Int_1_Loc); /* Int_1_Loc == 5 */ - + printf("Looping.\n"); } /* loop "for Run_Index" */ + printf("Done.\n"); #if !SDCC printf ("Execution ends\n"); printf ("\n"); @@ -234,16 +252,23 @@ void Proc_2 (One_Fifty *Int_Par_Ref) One_Fifty Int_Loc; Enumeration Enum_Loc; + printf("-> Proc_2\n"); + Int_Loc = *Int_Par_Ref + 10; - do /* executed once */ + do { + printf("1\n"); + /* executed once */ if (Ch_1_Glob == 'A') /* then, executed */ { + printf("2\n"); Int_Loc -= 1; *Int_Par_Ref = Int_Loc - Int_Glob; Enum_Loc = Ident_1; } /* if */ - while (Enum_Loc != Ident_1); /* true */ + printf("3\n"); + } while (Enum_Loc != Ident_1); /* true */ + printf("Proc_2 done.\n"); } /* Proc_2 */ @@ -258,16 +283,20 @@ void Proc_3 (Rec_Pointer *Ptr_Ref_Par) Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp); } /* Proc_3 */ - void Proc_4 (void) /* without parameters */ /*******/ /* executed once */ { Boolean Bool_Loc; + printf("-> Proc_4\n"); Bool_Loc = Ch_1_Glob == 'A'; Bool_Glob = Bool_Loc | Bool_Glob; Ch_2_Glob = 'B'; + printf("Expect Ch_1_Glob '%c' == 'A'\n", (char)Ch_1_Glob); + printf(" Ch_2_Glob '%c' == 'B'\n", (char)Ch_2_Glob); + printf(" Bool_Loc %d == 1\n", (unsigned)Bool_Loc); + printf(" Bool_Glob %d == 1\n", (unsigned)Bool_Glob); } /* Proc_4 */ @@ -321,11 +350,16 @@ Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val) Capital_Letter Ch_1_Loc; Capital_Letter Ch_2_Loc; + printf("-> Func_1\n"); + printf(" Inputs: Ch_1_Par_Val '%c' == { H, A, B }\n", (char)Ch_1_Par_Val); + printf(" Ch_2_Par_Val '%c' == { R, C, C }\n", (char)Ch_2_Par_Val); + Ch_1_Loc = Ch_1_Par_Val; Ch_2_Loc = Ch_1_Loc; - if (Ch_2_Loc != Ch_2_Par_Val) + if (Ch_2_Loc != Ch_2_Par_Val) { /* then, executed */ return (Ident_1); + } else /* not executed */ { Ch_1_Glob = Ch_1_Loc; @@ -396,15 +430,34 @@ Boolean Func_2 (char *Str_1_Par_Ref, char *Str_2_Par_Ref) REG One_Thirty Int_Loc; Capital_Letter Ch_Loc; + printf("-> Func_2\n"); + printf(" Inputs Str_1_Par_Ref \"%s\" = \"DHRYSTONE PROGRAM, 1'ST STRING\"\n", Str_1_Par_Ref); + printf(" Str_2_Par_Ref \"%s\" = \"DHRYSTONE PROGRAM, 2'ND STRING\"\n", Str_2_Par_Ref); + Int_Loc = 2; - while (Int_Loc <= 2) /* loop body executed once */ + + while (Int_Loc <= 2) { +#if BROKEN_SDCC + char a, b; + printf(" 2.1 Runs once Int_Loc %u = 2.\n", (unsigned)Int_Loc); + /* loop body executed once */ + a = Str_1_Par_Ref[Int_Loc]; + b = Str_2_Par_Ref[Int_Loc+1]; + if (Func_1 (a, b) == Ident_1) +#else if (Func_1 (Str_1_Par_Ref[Int_Loc], Str_2_Par_Ref[Int_Loc+1]) == Ident_1) +#endif /* then, executed */ { + printf(" 2.3 Then OK.\n"); Ch_Loc = 'A'; Int_Loc += 1; } /* if, while */ + else { + printf(" 2.2 Error.\n"); + } + } if (Ch_Loc >= 'W' && Ch_Loc < 'Z') /* then, not executed */ Int_Loc = 7;