diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 37ae743c6..59a1bf1d3 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -809,20 +809,11 @@ void OpAddSubAssign (const GenDesc* Gen, ExprDesc *Expr, const char* Op) /* Value on the stack */ if (IsClassFloat (Expr->Type)) { LOG(("OpAddSubAssign '%s' stack, float\n", Op)); -#if 0 - /* FIXME: what triggers this? */ if (Gen->Tok == TOK_PLUS_ASSIGN) { g_addeqlocal (lflags, Expr->IVal, FP_D_As32bitRaw(Expr2.V.FVal)); } else { g_subeqlocal (lflags, Expr->IVal, FP_D_As32bitRaw(Expr2.V.FVal)); } -#else - if (Gen->Tok == TOK_PLUS_ASSIGN) { - g_addeqlocal (lflags, Expr->IVal, Expr2.IVal); - } else { - g_subeqlocal (lflags, Expr->IVal, Expr2.IVal); - } -#endif } else { LOG(("OpAddSubAssign '%s' stack, int\n", Op)); if (Gen->Tok == TOK_PLUS_ASSIGN) { diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 64a0497f7..d8e931b1a 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -31,7 +31,7 @@ /* */ /*****************************************************************************/ - +//#define DEBUG #include #include @@ -39,8 +39,6 @@ #include #include -//#define DEBUG - /* common */ #include "addrsize.h" #include "attrib.h" @@ -2095,6 +2093,27 @@ void g_addeqlocal (unsigned flags, int Offs, unsigned long val) AddCodeLine ("jsr laddeqysp"); break; + case CF_FLOAT: + if (flags & CF_CONST) { + ASMLOG(("nop ; g_addeqlocal float const")); // FIXME: remove + g_getimmed (flags, val, 0); + } + ASMLOG(("nop ; g_addeqlocal float (Offs:%08x Val:%08x)", Offs, val)); // FIXME: remove + // value to add is in primary (a/x/sreg/sgreg+1) + + AddCodeLine ("jsr pusheax"); + + // variable to add to is at sp+y + AddCodeLine ("ldy #$%02X", Offs+4+3); + AddCodeLine ("jsr ldeaxysp"); + + AddCodeLine ("jsr ftosaddeax"); + // result is in primary + // store primary to stack offset + AddCodeLine ("ldy #$%02X", Offs); + AddCodeLine ("jsr steaxysp"); + break; + default: typeerror (flags); } @@ -2308,6 +2327,28 @@ void g_subeqlocal (unsigned flags, int Offs, unsigned long val) AddCodeLine ("jsr lsubeqysp"); break; + case CF_FLOAT: + // variable to add to is at sp+y + + if (flags & CF_CONST) { + ASMLOG(("nop ; g_subeqlocal float const")); // FIXME: remove + g_getimmed (flags, val, 0); + } + ASMLOG(("nop ; g_subeqlocal float (Offs:%08x Val:%08x)", Offs, val)); // FIXME: remove + // value to add is in primary (a/x/sreg/sgreg+1) + + AddCodeLine ("jsr pusheax"); + + AddCodeLine ("ldy #$%02X", Offs+4+3); + AddCodeLine ("jsr ldeaxysp"); + + AddCodeLine ("jsr ftosrsubeax"); + // result is in primary + // store primary to stack offset + AddCodeLine ("ldy #$%02X", Offs); + AddCodeLine ("jsr steaxysp"); + break; + default: typeerror (flags); } diff --git a/test/val/float-basic-var-const.c b/test/val/float-basic-var-const.c index da7e29815..9ba4c4557 100644 --- a/test/val/float-basic-var-const.c +++ b/test/val/float-basic-var-const.c @@ -55,6 +55,7 @@ void test1(float f, char *str) } } +#if 1 void varconst(void) { printf("\n*** variable vs constant\n\n"); @@ -138,18 +139,71 @@ void varconst2(void) printf(" fp1:0x%08lx [0x41500000] %s (exp:13.0)", *((uint32_t*)&fp1), _ftostr(buf, fp1)); test1(fp1, "41500000"); } +#endif + +void varconst3(void) +{ + float localfp3; + float localfp2; + float localfp1; + float localfp4; + float localfp5; + printf("\n*** local variable vs constant\n\n"); +#if 1 // compiles, wrong result + /* addition, variable + constant */ + localfp1 = 64.75f; + localfp1 += 2.25f; + printf("addition: %s+%s=%s\n", _ftostr(buf, 64.75f), _ftostr(buf3, 2.25f), _ftostr(buf2, localfp1)); + printf(" localfp1:0x%08lx [0x42860000] %s (exp:67.0)", *((uint32_t*)&localfp1), _ftostr(buf, localfp1)); + test1(localfp1, "42860000"); +#endif +#if 1 // compiles, wrong result + /* subtraction, variable - constant */ + localfp1 = 16.25f; + localfp1 -= 8.5f; + printf("substraction: %s-%s=%s\n", _ftostr(buf, 16.25f), _ftostr(buf2, 8.5f), _ftostr(buf3, localfp1)); + printf(" localfp1:0x%08lx [0x40f80000] %s (exp:7.75)", *((uint32_t*)&localfp1), _ftostr(buf, localfp1)); + test1(localfp1, "40f80000"); + + localfp1 = 0.3f; + localfp1 -= 0.1f; + printf("localfp1:0x%08lx [0x3e4cccce] %s (0.2)", *((uint32_t*)&localfp1), _ftostr(buf, localfp1)); + test1(localfp1, "3e4cccce"); + + localfp1 = 0.1f; + localfp1 -= 0.3f; + printf("localfp1:0x%08lx [0xbe4cccce] %s (-0.2)", *((uint32_t*)&localfp1), _ftostr(buf, localfp1)); + test1(localfp1, "be4cccce"); +#endif +#if 1 + /* multiplication, variable * constant */ + localfp1 = 16.25f; + localfp1 *= 2.5f; + printf("multiplication: %s*%s=%s\n", _ftostr(buf, 16.25f), _ftostr(buf2, 2.5f), _ftostr(buf3, localfp1)); + printf(" localfp1:0x%08lx [0x42228000] %s (exp:40.625)", *((uint32_t*)&localfp1), _ftostr(buf, localfp1)); + test1(localfp1, "42228000"); + + /* division, variable / constant */ + localfp1 = 32.5f; + localfp1 /= 2.5f; + printf("division: %s/%s=%s\n", _ftostr(buf, 32.5f), _ftostr(buf2, 2.5f), _ftostr(buf3, localfp1)); + printf(" localfp1:0x%08lx [0x41500000] %s (exp:13.0)", *((uint32_t*)&localfp1), _ftostr(buf, localfp1)); + test1(localfp1, "41500000"); +#endif +} int main(void) { float fp2 = 43.21f; printf("float-basic-var-const\n"); - + printf("fp1:0x%08lx [0x414570a4] %s (12.340000)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1)); printf("fp2:0x%08lx [0x422cd70a] %s (43.209999)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); - + varconst(); varconst2(); + varconst3(); WAIT(); printf("\nfloat-basic-var-const (res:%d)\n", result);