1
0
mirror of https://github.com/cc65/cc65.git synced 2024-09-27 19:55:09 +00:00

fix conversion of float to chars

This commit is contained in:
mrdudz 2022-11-12 17:41:52 +01:00
parent 694561e917
commit 69b3659924
7 changed files with 39 additions and 58 deletions

View File

@ -39,7 +39,7 @@
#include <string.h>
#include <stdarg.h>
#define DEBUG
//#define DEBUG
/* common */
#include "addrsize.h"
@ -1326,10 +1326,15 @@ static void g_regchar (unsigned Flags)
/* Make sure, the value in the primary register is in the range of char. Truncate if necessary */
{
unsigned L;
LOG(("g_regchar flags: %04x\n", Flags));
AddCodeLine ("nop ; g_regchar flags: %04x\n", Flags); // FIXME:remove
/* FIXME: float */
if ((Flags & CF_TYPEMASK) == CF_FLOAT) {
typeerror (Flags);
// convert float to int, then fall through to char conversion
AddCodeLine ("jsr feaxint");
// typeerror (Flags);
// return;
}
AddCodeLine ("ldx #$00");
@ -1350,6 +1355,7 @@ void g_regint (unsigned Flags)
/* Make sure, the value in the primary register is an int. Convert if necessary */
{
LOG(("g_regint flags: %04x\n", Flags));
AddCodeLine ("nop ; g_regint flags: %04x\n", Flags); // FIXME:remove
switch (Flags & CF_TYPEMASK) {
case CF_CHAR:
@ -1378,6 +1384,7 @@ void g_regint (unsigned Flags)
void g_reglong (unsigned Flags)
/* Make sure, the value in the primary register a long. Convert if necessary */
{
LOG(("g_reglong flags: %04x\n", Flags));
switch (Flags & CF_TYPEMASK) {
case CF_CHAR:
@ -1627,9 +1634,9 @@ unsigned g_typecast (unsigned lhs, unsigned rhs)
** by the lhs value. Return the result value.
*/
{
LOG(("g_typecast 2 rhs: %s lhs: %s (rhs is %s)\n",
((rhs & CF_TYPEMASK) == CF_FLOAT) ? "float" : "int",
LOG(("g_typecast 2 lhs: %s <- rhs: %s (rhs is %s)\n",
((lhs & CF_TYPEMASK) == CF_FLOAT) ? "float" : "int",
((rhs & CF_TYPEMASK) == CF_FLOAT) ? "float" : "int",
((rhs & CF_CONST) == 0) ? "not const" : "const"
));
/* Check if a conversion is needed */
@ -1654,12 +1661,16 @@ unsigned g_typecast (unsigned lhs, unsigned rhs)
case CF_CHAR:
/* We must truncate the primary register to char */
g_regchar (lhs);
g_regchar (rhs);
// g_regchar (lhs); // BUG IN HEAD?
break;
default:
typeerror (lhs);
typeerror (rhs);
// typeerror (lhs); // BUG IN HEAD
}
} else {
LOG(("g_typecast 2 no conversion done\n"));
}
/* Do not need any other action. If the left type is int, and the primary

View File

@ -4,7 +4,7 @@
** 2020-11-20, Greg King
*/
#define DEBUG
//#define DEBUG
#include <stdio.h>
#include <stdlib.h>
@ -2648,15 +2648,25 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
case TOK_GT: Expr->IVal = (Val1 > Val2); break;
default: Internal ("hie_compare: got token 0x%X\n", Tok);
}
} else if (TypeOf (Expr2.Type) == CF_FLOAT) {
LOG(("FIXME: comparing non float constant with float constant\n"));
/* FIXME: compare non float vs float */
signed long Val1 = Expr2.IVal;
float Val2 = Expr->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;

View File

@ -128,7 +128,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType)
/* Value is now in primary and an rvalue */
ED_FinalizeRValLoad (Expr);
}
LOG(("DoConversion 1 done\n"));
} else if (ED_IsConstAbs (Expr)) {
LOG(("DoConversion 2 Old: %s New: %s\n",
(IsTypeFloat (OldType)) ? "float" : "int",
@ -224,14 +224,17 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType)
** impossible.
*/
{
printf("TypeConversion\n");
#if 0
/* Debugging */
printf ("Expr:\n=======================================\n");
printf ("=======================================\n");
printf ("Expr:\n---------------------------------------\n");
PrintExprDesc (stdout, Expr);
printf ("Type:\n=======================================\n");
printf ("\nType:\n---------------------------------------\n");
PrintType (stdout, NewType);
printf ("\n");
PrintRawType (stdout, NewType);
printf ("=======================================\n");
#endif
/* First, do some type checking */
typecmp_t Result = TYPECMP_INITIALIZER;

View File

@ -39,26 +39,6 @@ unsigned long var_ulong;
int result = 0;
// returns 1 if value in f matches the string
// the string is a hex value without leading "0x"
int compare(float f, char *str)
{
char temp[12];
sprintf(temp, "%08lx", *((uint32_t*)&f));
return (strcmp(temp, str) == 0) ? 1 : 0;
}
void test1(float f, char *str)
{
if (compare(f, str)) {
// printf("(ok)");
printf("\n");
} else {
printf(" (failed) !!!\n");
result++;
}
}
void test2(long n, long val)
{
if (n == val) {

View File

@ -39,26 +39,6 @@ unsigned long var_ulong;
int result = 0;
// returns 1 if value in f matches the string
// the string is a hex value without leading "0x"
int compare(float f, char *str)
{
char temp[12];
sprintf(temp, "%08lx", *((uint32_t*)&f));
return (strcmp(temp, str) == 0) ? 1 : 0;
}
void test1(float f, char *str)
{
if (compare(f, str)) {
// printf("(ok)");
printf("\n");
} else {
printf(" (failed) !!!\n");
result++;
}
}
void test2(long n, long val)
{
if (n == val) {

View File

@ -160,17 +160,14 @@ void varvar(void)
printf("\nconversions (float variable to integer variable)\n");
fp1 = -12.3f;
#if 0 // FIXME
var_schar = (signed char)fp1;
printf("fp1 0x%08lx %s (-12.3) schar:%d (exp:-12)", *((uint32_t*)&fp1), _ftostr(buf, fp1), (int)var_schar);
test2(var_schar, -12);
#endif
fp2 = 19.9f;
#if 0 // FIXME
var_uchar = (unsigned char)fp2;
printf("fp2 0x%08lx %s (19.9) uchar:%u (exp:19)", *((uint32_t*)&fp2), _ftostr(buf, fp2), (int)var_uchar);
test2(var_uchar, 19);
#endif
fp1 = 1234.5f;
var_sint = (signed short)fp1;