1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-18 07:29:36 +00:00

fix comparing float const vs const

This commit is contained in:
mrdudz 2022-11-12 02:44:01 +01:00
parent 62e211553b
commit 694561e917
3 changed files with 73 additions and 35 deletions

View File

@ -2631,37 +2631,75 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
/* Both operands are numeric constant, remove the generated code */
RemoveCode (&Mark1);
LOG(("hie_compare (Both operands are numeric constant)\n"));
/* Determine if this is a signed or unsigned compare */
if (IsClassInt (Expr->Type) && IsSignSigned (Expr->Type) &&
IsClassInt (Expr2.Type) && IsSignSigned (Expr2.Type)) {
/* Evaluate the result for signed operands */
signed long Val1 = Expr->IVal;
signed long Val2 = Expr2.IVal;
switch (Tok) {
case TOK_EQ: Expr->IVal = (Val1 == Val2); break;
case TOK_NE: Expr->IVal = (Val1 != Val2); break;
case TOK_LT: Expr->IVal = (Val1 < Val2); break;
case TOK_LE: Expr->IVal = (Val1 <= Val2); break;
case TOK_GE: Expr->IVal = (Val1 >= Val2); break;
case TOK_GT: Expr->IVal = (Val1 > Val2); break;
default: Internal ("hie_compare: got token 0x%X\n", Tok);
if ((TypeOf (Expr->Type) == CF_FLOAT) || (TypeOf (Expr2.Type) == CF_FLOAT)) {
/* at least one of the operands is a float */
if ((TypeOf (Expr->Type) == CF_FLOAT) && (TypeOf (Expr2.Type) == CF_FLOAT)) {
/* compare float vs float */
float Val1 = Expr->V.FVal.V;
float Val2 = Expr2.V.FVal.V;
switch (Tok) {
case TOK_EQ: Expr->IVal = (Val1 == Val2); break;
case TOK_NE: Expr->IVal = (Val1 != Val2); break;
case TOK_LT: Expr->IVal = (Val1 < Val2); break;
case TOK_LE: Expr->IVal = (Val1 <= Val2); break;
case TOK_GE: Expr->IVal = (Val1 >= Val2); break;
case TOK_GT: Expr->IVal = (Val1 > Val2); break;
default: Internal ("hie_compare: got token 0x%X\n", Tok);
}
} else {
LOG(("FIXME: comparing float constant with non float constant\n"));
/* FIXME: compare float vs non float */
float Val1 = Expr->V.FVal.V;
signed long Val2 = Expr2.IVal;
if (TypeOf (Expr2.Type) == CF_FLOAT) {
Val1 = Expr2.V.FVal.V;
Val2 = Expr->IVal;
}
switch (Tok) {
case TOK_EQ: Expr->IVal = (Val1 == Val2); break;
case TOK_NE: Expr->IVal = (Val1 != Val2); break;
case TOK_LT: Expr->IVal = (Val1 < Val2); break;
case TOK_LE: Expr->IVal = (Val1 <= Val2); break;
case TOK_GE: Expr->IVal = (Val1 >= Val2); break;
case TOK_GT: Expr->IVal = (Val1 > Val2); break;
default: Internal ("hie_compare: got token 0x%X\n", Tok);
}
}
} else {
/* Evaluate the result for unsigned operands */
unsigned long Val1 = Expr->IVal;
unsigned long Val2 = Expr2.IVal;
switch (Tok) {
case TOK_EQ: Expr->IVal = (Val1 == Val2); break;
case TOK_NE: Expr->IVal = (Val1 != Val2); break;
case TOK_LT: Expr->IVal = (Val1 < Val2); break;
case TOK_LE: Expr->IVal = (Val1 <= Val2); break;
case TOK_GE: Expr->IVal = (Val1 >= Val2); break;
case TOK_GT: Expr->IVal = (Val1 > Val2); break;
default: Internal ("hie_compare: got token 0x%X\n", Tok);
/* Determine if this is a signed or unsigned compare */
if (IsClassInt (Expr->Type) && IsSignSigned (Expr->Type) &&
IsClassInt (Expr2.Type) && IsSignSigned (Expr2.Type)) {
/* Evaluate the result for signed operands */
signed long Val1 = Expr->IVal;
signed long Val2 = Expr2.IVal;
switch (Tok) {
case TOK_EQ: Expr->IVal = (Val1 == Val2); break;
case TOK_NE: Expr->IVal = (Val1 != Val2); break;
case TOK_LT: Expr->IVal = (Val1 < Val2); break;
case TOK_LE: Expr->IVal = (Val1 <= Val2); break;
case TOK_GE: Expr->IVal = (Val1 >= Val2); break;
case TOK_GT: Expr->IVal = (Val1 > Val2); break;
default: Internal ("hie_compare: got token 0x%X\n", Tok);
}
} else {
/* Evaluate the result for unsigned operands */
unsigned long Val1 = Expr->IVal;
unsigned long Val2 = Expr2.IVal;
switch (Tok) {
case TOK_EQ: Expr->IVal = (Val1 == Val2); break;
case TOK_NE: Expr->IVal = (Val1 != Val2); break;
case TOK_LT: Expr->IVal = (Val1 < Val2); break;
case TOK_LE: Expr->IVal = (Val1 <= Val2); break;
case TOK_GE: Expr->IVal = (Val1 >= Val2); break;
case TOK_GT: Expr->IVal = (Val1 > Val2); break;
default: Internal ("hie_compare: got token 0x%X\n", Tok);
}
}
}

View File

@ -45,27 +45,27 @@ void constconst(void)
// float constant vs float const
printf("const vs const\n");
// expect("1.5f == 1.6f is", 0, (1.5f == 1.6f));
// expect("1.6f == 1.5f is", 0, (1.6f == 1.5f));
expect("1.5f == 1.6f is", 0, (1.5f == 1.6f));
expect("1.6f == 1.5f is", 0, (1.6f == 1.5f));
expect("1.6f == 1.6f is", 1, (1.6f == 1.6f));
// expect("1.5f != 1.6f is", 1, (1.5f != 1.6f));
// expect("1.6f != 1.5f is", 1, (1.6f != 1.5f));
expect("1.5f != 1.6f is", 1, (1.5f != 1.6f));
expect("1.6f != 1.5f is", 1, (1.6f != 1.5f));
expect("1.6f != 1.6f is", 0, (1.6f != 1.6f));
// expect("1.5f < 1.6f is", 1, (1.5f < 1.6f));
expect("1.5f < 1.6f is", 1, (1.5f < 1.6f));
expect("1.6f < 1.5f is", 0, (1.6f < 1.5f));
expect("1.6f < 1.6f is", 0, (1.6f < 1.6f));
expect("1.5f > 1.6f is", 0, (1.5f > 1.6f));
// expect("1.6f > 1.5f is", 1, (1.6f > 1.5f));
expect("1.6f > 1.5f is", 1, (1.6f > 1.5f));
expect("1.6f > 1.6f is", 0, (1.6f > 1.6f));
expect("1.5f <= 1.6f is", 1, (1.5f <= 1.6f));
// expect("1.6f <= 1.5f is", 0, (1.6f <= 1.5f));
expect("1.6f <= 1.5f is", 0, (1.6f <= 1.5f));
expect("1.6f <= 1.6f is", 1, (1.6f <= 1.6f));
// expect("1.5f >= 1.6f is", 0, (1.5f >= 1.6f));
expect("1.5f >= 1.6f is", 0, (1.5f >= 1.6f));
expect("1.6f >= 1.5f is", 1, (1.6f >= 1.5f));
expect("1.6f >= 1.6f is", 1, (1.6f >= 1.6f));
}