1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-09 06:29:38 +00:00

some fixes for X=, related tests

This commit is contained in:
mrdudz 2023-08-31 00:44:03 +02:00
parent 8dfe97b1df
commit ab238c1045
9 changed files with 378 additions and 29 deletions

View File

@ -499,10 +499,14 @@ static void OpAssignArithmetic (const GenDesc* Gen, ExprDesc* Expr, const char*
/* Read the expression on the right side of the '=' or 'op=' */
MarkedExprWithCheck (hie1, &Expr2);
/* The rhs must be an integer (or a float, but we don't support that yet */
if (!IsClassInt (Expr2.Type)
// && !IsClassFloat (Expr2.Type) /* FIXME: float */
) {
LOG(("OpAssignArithmetic '%s' (!=0) 2 lhs: %s rhs: %s\n",
Op,
(TypeOf (Expr->Type) == CF_FLOAT) ? "float" : "int",
(TypeOf (Expr2.Type) == CF_FLOAT) ? "float" : "int"));
/* The rhs must be an integer or a float */
if (!IsClassInt (Expr2.Type) && !IsClassFloat (Expr2.Type)) {
Error ("Invalid right operand for binary operator '%s'", Op);
/* Continue. Wrong code will be generated, but the compiler won't
** break, so this is the best error recovery.
@ -535,9 +539,19 @@ static void OpAssignArithmetic (const GenDesc* Gen, ExprDesc* Expr, const char*
/* Special handling for add and sub - some sort of a hack, but short code */
if (Gen->Func == g_add) {
g_inc (Flags | CF_CONST, Expr2.IVal);
LOG(("OpAssignArithmetic '%s' gen g_add\n", Op));
if (IsClassFloat (Expr2.Type)) {
g_inc (Flags | CF_CONST, FP_D_As32bitRaw(Expr2.V.FVal));
} else {
g_inc (Flags | CF_CONST, Expr2.IVal);
}
} else if (Gen->Func == g_sub) {
g_dec (Flags | CF_CONST, Expr2.IVal);
LOG(("OpAssignArithmetic '%s' gen g_sub\n", Op));
if (IsClassFloat (Expr2.Type)) {
g_dec (Flags | CF_CONST, FP_D_As32bitRaw(Expr2.V.FVal));
} else {
g_dec (Flags | CF_CONST, Expr2.IVal);
}
} else {
if (!ED_IsUneval (Expr)) {
if (Expr2.IVal == 0 && !ED_IsUneval (Expr)) {
@ -691,8 +705,9 @@ void OpAddSubAssign (const GenDesc* Gen, ExprDesc *Expr, const char* Op)
return;
}
/* There must be an integer or pointer on the left side */
if (!IsClassInt (Expr->Type) && !IsTypePtr (Expr->Type)) {
LOG(("OpAddSubAssign '%s'\n", Op));
/* There must be an integer, pointer or float on the left side */
if (!IsClassInt (Expr->Type) && !IsTypePtr (Expr->Type) && !IsTypeFloat (Expr->Type)) {
Error ("Invalid left operand for binary operator '%s'", Op);
/* Continue. Wrong code will be generated, but the compiler won't
** break, so this is the best error recovery.
@ -720,11 +735,9 @@ void OpAddSubAssign (const GenDesc* Gen, ExprDesc *Expr, const char* Op)
ED_Init (&Expr2);
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
/* Evaluate the rhs. We expect an integer here, since float is not
** supported
*/
/* Evaluate the rhs. We expect an integer or float here */
hie1 (&Expr2);
if (!IsClassInt (Expr2.Type)) {
if (!IsClassInt (Expr2.Type) && !IsClassFloat (Expr2.Type)) {
Error ("Invalid right operand for binary operator '%s'", Op);
/* Continue. Wrong code will be generated, but the compiler won't
** break, so this is the best error recovery.
@ -774,19 +787,49 @@ void OpAddSubAssign (const GenDesc* Gen, ExprDesc *Expr, const char* Op)
** static variable, register variable, pooled literal or code
** label location.
*/
if (Gen->Tok == TOK_PLUS_ASSIGN) {
g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal);
if (IsClassFloat (Expr->Type)) {
LOG(("OpAddSubAssign '%s' abs, float %08x (IVal:%08lx)\n", Op, FP_D_As32bitRaw(Expr2.V.FVal), Expr2.IVal));
/* FIXME: what about the case when expr2 is NOT float? */
if (Gen->Tok == TOK_PLUS_ASSIGN) {
g_addeqstatic (lflags, Expr->Name, Expr->IVal, FP_D_As32bitRaw(Expr2.V.FVal));
} else {
g_subeqstatic (lflags, Expr->Name, Expr->IVal, FP_D_As32bitRaw(Expr2.V.FVal));
}
} else {
g_subeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal);
LOG(("OpAddSubAssign '%s' abs, int\n", Op));
if (Gen->Tok == TOK_PLUS_ASSIGN) {
g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal);
} else {
g_subeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal);
}
}
break;
case E_LOC_STACK:
/* Value on the stack */
if (Gen->Tok == TOK_PLUS_ASSIGN) {
g_addeqlocal (lflags, Expr->IVal, Expr2.IVal);
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 {
g_subeqlocal (lflags, Expr->IVal, Expr2.IVal);
LOG(("OpAddSubAssign '%s' stack, int\n", Op));
if (Gen->Tok == TOK_PLUS_ASSIGN) {
g_addeqlocal (lflags, Expr->IVal, Expr2.IVal);
} else {
g_subeqlocal (lflags, Expr->IVal, Expr2.IVal);
}
}
break;

View File

@ -2012,6 +2012,12 @@ void g_addeqstatic (unsigned flags, uintptr_t label, long offs,
}
break;
case CF_FLOAT:
g_getstatic (flags, label, offs);
g_inc (flags, val);
g_putstatic (flags, label, offs);
break;
default:
typeerror (flags);
}
@ -2237,6 +2243,12 @@ void g_subeqstatic (unsigned flags, uintptr_t label, long offs,
}
break;
case CF_FLOAT:
g_getstatic (flags, label, offs);
g_dec (flags, val);
g_putstatic (flags, label, offs);
break;
default:
typeerror (flags);
}

View File

@ -67,7 +67,7 @@ void SKIPPEDtest1(float f, char *str)
printf(" (SKIPPED:%s:%s)\n", temp, str);
}
void test(void)
void intconstvar(void)
{
var_float = 11.123f;
@ -108,7 +108,7 @@ int main(void)
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));
test();
intconstvar();
WAIT();
printf("\nfloat-basic-intconst-var (res:%d)\n", result);

View File

@ -60,6 +60,17 @@ void test1(float f, char *str)
printf("result:%d\n", result);
}
void test2(unsigned int i, unsigned int exp)
{
if (i == exp) {
// printf(" (ok)");
} else {
printf(" (failed) !!! ");
result++;
}
printf("result:%d\n", result);
}
void SKIPPEDtest1(float f, char *str)
{
char temp[12];
@ -67,7 +78,7 @@ void SKIPPEDtest1(float f, char *str)
printf(" (SKIPPED:%s:%s)\n", temp, str);
}
void test(void)
void intvarconst(void)
{
var_int = 47;
#if 1
@ -108,6 +119,48 @@ void test(void)
}
unsigned int i1;
void intvarconst2(void)
{
var_int = 47;
#if 1
i1 = var_int;
printf("i1: %d (47)\n", i1);
#endif
printf("int var X= float const\n");
/* addition */
#if 0 // gives wrong result
i1 = var_int;
i1 += 11.123f;
printf("i1: %d (58)\n", i1);
test2(i1, 58);
#endif
/* subtraction */
#if 0 // gives wrong result
i1 = var_int;
i1 -= 11.123f;
printf("i1: %d (35)\n", i1);
test2(i1, 35);
#endif
#if 0 // internal compiler error
/* multiplication */
i1 = var_int;
i1 *= 11.123f;
printf("i1: %d (522)\n", i1);
test2(i1, 522);
#endif
#if 0 // internal compiler error
/* division */
i1 = var_int;
i1 /= 11.123f;
printf("i1: %d (4)\n", i1);
test2(i1, 4);
#endif
}
int main(void)
{
float fp2 = 43.21f;
@ -116,7 +169,8 @@ int main(void)
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));
test();
intvarconst();
intvarconst2();
WAIT();
printf("\nfloat-basic-intvar-const (res:%d)\n", result);

View File

@ -60,6 +60,17 @@ void test1(float f, char *str)
printf("result:%d\n", result);
}
void test2(unsigned int i, unsigned int exp)
{
if (i == exp) {
// printf(" (ok)");
} else {
printf(" (failed) !!! ");
result++;
}
printf("result:%d\n", result);
}
void SKIPPEDtest1(float f, char *str)
{
char temp[12];
@ -67,7 +78,7 @@ void SKIPPEDtest1(float f, char *str)
printf(" (SKIPPED:%s:%s)\n", temp, str);
}
void test(void)
void intfloat(void)
{
var_int = 47;
var_float = 11.123f;
@ -98,6 +109,43 @@ void test(void)
}
unsigned int i1;
void intfloat2(void)
{
printf("int X= float var\n");
var_int = 47;
var_float = 11.123f;
i1 = var_int;
printf("i1: %d (47)\n", i1);
/* addition */
i1 = var_int;
i1 += var_float;
printf("i1: %d (58)\n", i1);
test2(i1, 58);
#if 1
i1 = var_int;
i1 -= var_float;
printf("i1: %d (36)\n", i1);
test2(i1, 36);
#endif
#if 0 // internal compiler error
i1 = var_int;
i1 *= var_float;
printf("i1: %d (522)\n", i1);
test2(i1, 522);
#endif
#if 0 // internal compiler error
i1 = var_int;
i1 /= var_float;
printf("i1: %d (4)\n", i1);
test2(i1, 4);
#endif
}
int main(void)
{
float fp2 = 43.21f;
@ -106,7 +154,8 @@ int main(void)
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));
test();
intfloat();
intfloat2();
WAIT();
printf("\nfloat-basic-intvar-var (res:%d)\n", result);

View File

@ -55,7 +55,6 @@ void test1(float f, char *str)
}
}
// when making sub tests work, remove them here and uncomment them in val/float-basic.c
void varconst(void)
{
printf("\n*** variable vs constant\n\n");
@ -97,15 +96,60 @@ void varconst(void)
test1(fp3, "41500000");
}
void varconst2(void)
{
printf("\n*** variable vs constant\n\n");
/* addition, variable + constant */
fp1 = 64.75f;
fp1 += 2.25f;
printf("addition: %s+%s=%s\n", _ftostr(buf, 64.75f), _ftostr(buf3, 2.25f), _ftostr(buf2, fp1));
printf(" fp1:0x%08lx [0x42860000] %s (exp:67.0)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "42860000");
/* subtraction, variable - constant */
fp1 = 16.25f;
fp1 -= 8.5f;
printf("substraction: %s-%s=%s\n", _ftostr(buf, 16.25f), _ftostr(buf2, 8.5f), _ftostr(buf3, fp1));
printf(" fp1:0x%08lx [0x40f80000] %s (exp:7.75)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "40f80000");
fp1 = 0.3f;
fp1 -= 0.1f;
printf("fp1:0x%08lx [0x3e4cccce] %s (0.2)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "3e4cccce");
fp1 = 0.1f;
fp1 -= 0.3f;
printf("fp1:0x%08lx [0xbe4cccce] %s (-0.2)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "be4cccce");
/* multiplication, variable * constant */
fp1 = 16.25f;
fp1 *= 2.5f;
printf("multiplication: %s*%s=%s\n", _ftostr(buf, 16.25f), _ftostr(buf2, 2.5f), _ftostr(buf3, fp1));
printf(" fp1:0x%08lx [0x42228000] %s (exp:40.625)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "42228000");
/* division, variable / constant */
fp1 = 32.5f;
fp1 /= 2.5f;
printf("division: %s/%s=%s\n", _ftostr(buf, 32.5f), _ftostr(buf2, 2.5f), _ftostr(buf3, fp1));
printf(" fp1:0x%08lx [0x41500000] %s (exp:13.0)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "41500000");
}
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();
WAIT();
printf("\nfloat-basic-var-const (res:%d)\n", result);

View File

@ -67,7 +67,7 @@ void SKIPPEDtest1(float f, char *str)
printf(" (SKIPPED:%s:%s)\n", temp, str);
}
void test(void)
void varintconst(void)
{
var_float = 11.123f;
@ -101,6 +101,46 @@ void test(void)
}
void varintconst2(void)
{
var_float = 11.123f;
printf("float *= int const\n");
fp1 = 47;
printf("fp1:0x%08lx [42687df4] %s (47)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
fp1 = var_float;
printf("fp1:0x%08lx [42687df4] %s (11.123)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
#if 0 // works but gives wrong result
/* addition */
fp1 = var_float;
fp1 += 47;
printf("fp1:0x%08lx [42687df4] %s (58.123)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "42687df4");
#endif
#if 0 // works but gives wrong result
fp1 = var_float;
fp1 -= 47;
printf("fp1:0x%08lx [42687df4] %s (-35.877)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "42687df4");
#endif
#if 0 // works but gives wrong result
fp1 = var_float;
fp1 *= 47;
printf("fp1:0x%08lx [42687df4] %s (522.781)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "42687df4");
#endif
#if 0 // works but gives wrong result
fp1 = var_float;
fp1 /= 47;
printf("fp1:0x%08lx [42687df4] %s (0.2367)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "42687df4");
#endif
}
int main(void)
{
float fp2 = 43.21f;
@ -109,7 +149,8 @@ int main(void)
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));
test();
varintconst();
varintconst2();
WAIT();
printf("\nfloat-basic-var-intconst (res:%d)\n", result);

View File

@ -67,7 +67,7 @@ void SKIPPEDtest1(float f, char *str)
printf(" (SKIPPED:%s:%s)\n", temp, str);
}
void test(void)
void intvar(void)
{
var_int = 47;
@ -100,6 +100,46 @@ void test(void)
}
void intvar2(void)
{
var_int = 47;
var_float = 11.123f;
printf("float var *= int var\n");
fp1 = var_int;
printf("fp1:0x%08lx [42687df4] %s (47)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
fp1 = var_float;
printf("fp1:0x%08lx [42687df4] %s (11.123)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
#if 0 // compiles, but wrong result
/* addition */
fp1 = var_float;
fp1 += var_int;
printf("fp1:0x%08lx [42687df4] %s (58.123)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "42687df4");
#endif
#if 0 // compiles, but wrong result
/* subtraction */
fp1 = var_float;
fp1 -= var_int;
printf("fp1:0x%08lx [42687df4] %s (-35.877)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "42687df4");
#endif
/* multiplication */
fp1 = var_float;
fp1 *= var_int;
printf("fp1:0x%08lx [4402b1fc] %s (522.781)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "4402b1fc");
/* division */
fp1 = var_float;
fp1 /= var_int;
printf("fp1:0x%08lx [3e7256e3] %s (0.2367)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "3e7256e3");
}
int main(void)
{
float fp2 = 43.21f;
@ -108,7 +148,8 @@ int main(void)
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));
test();
intvar();
intvar2();
WAIT();
printf("\nfloat-basic-var-intvar (res:%d)\n", result);

View File

@ -34,6 +34,7 @@ unsigned long var_ulong;
int result = 0;
#if 1
// returns 1 if value in f matches the string
// the string is a hex value without leading "0x"
int compare(float f, char *str)
@ -101,9 +102,69 @@ void varvar(void)
test1(fp3, "40d00000");
}
void varvar2(void)
{
printf("\nvariable vs variable\n\n");
#if 0 // compiles, but wrong result
/* addition, variable + variable */
fp1 = 16.5f;
fp2 = 64.25f;
fp1 += fp2; // = 80.75f
printf("addition: %s+%s=%s\n", _ftostr(buf, 16.5f), _ftostr(buf2, fp2), _ftostr(buf3, fp1));
printf(" fp1:0x%08lx [0x42a18000] %s (exp:80.75)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "42a18000");
#endif
#if 0 // compiles, but wrong result
/* subtraction, variable - variable */
fp1 = 64.25f;
fp2 = 16.5f;
fp1 -= fp2;
printf("substraction: %s-%s=%s\n", _ftostr(buf, 64.25f), _ftostr(buf2, fp2), _ftostr(buf3, fp1));
printf(" fp1:0x%08lx [0x423f0000] %s (exp:47.75)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "423f0000");
fp1 = 0.3f;
fp2 = 0.1f;
fp1 -= fp2;
printf("fp1:0x%08lx [0x3e4cccce] %s (0.2)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "3e4cccce");
fp1 = 0.1f;
fp2 = 0.1f;
fp1 -= fp2;
printf("fp1:0x%08lx [0xbe4cccce] %s (-0.2)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "be4cccce");
#endif
/* multiplication, variable * variable */
fp1 = 8.5f;
fp2 = 2.25f;
fp1 *= fp2;
printf("multiplication: %s*%s=%s\n", _ftostr(buf, 8.5f), _ftostr(buf2, fp2), _ftostr(buf3, fp1));
printf(" fp1:0x%08lx [0x41990000] %s (exp:19.125)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "41990000");
/* division, variable / variable */
fp1 = 16.25f;
fp2 = 2.5f;
fp1 /= fp2;
printf("division: %s/%s=%s\n", _ftostr(buf, 16.25f), _ftostr(buf2, fp2), _ftostr(buf3, fp1));
printf(" fp1:0x%08lx [0x40d00000] %s (exp:6.5)", *((uint32_t*)&fp1), _ftostr(buf, fp1));
test1(fp1, "40d00000");
}
#else
void test (void)
{
fp1 = 16.5f;
fp2 = 64.25f;
fp1 += fp2; // = 80.75f
}
#endif
int main(void)
{
#if 1
float fp2 = 43.21f;
printf("float-basic-var-var\n");
@ -111,8 +172,12 @@ int main(void)
printf("fp2:0x%08lx [0x422cd70a] %s (43.209999)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2));
varvar();
varvar2();
WAIT();
printf("\nfloat-basic-var-var (res:%d)\n", result);
#else
test();
#endif
return result;
}