/* */
/* */
/* */
-/* (C) 1998-2006 Ullrich von Bassewitz */
-/* Römerstraße 52 */
+/* (C) 1998-2008 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
#include "codegen.h"
#include "datatype.h"
#include "error.h"
+#include "fp.h"
#include "funcdesc.h"
#include "global.h"
#include "symtab.h"
/* */
/* */
/* */
-/* (C) 1998-2006 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
+/* (C) 1998-2008 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
#define UNSPECIFIED -1L /* Element count was not specified */
#define FLEXIBLE 0L /* Flexible array struct member */
-/* Sizes */
+/* Sizes. Floating point sizes come from fp.h */
#define SIZEOF_CHAR 1
#define SIZEOF_SHORT 2
#define SIZEOF_INT 2
#define SIZEOF_LONG 4
#define SIZEOF_LONGLONG 8
-#define SIZEOF_FLOAT 4
-#define SIZEOF_DOUBLE 4
+#define SIZEOF_FLOAT (FP_F_Size())
+#define SIZEOF_DOUBLE (FP_D_Size())
#define SIZEOF_PTR 2
/* Predefined type strings */
#endif
TypeCode GetQualifier (const Type* T) attribute ((const));
-/* Get the qualifier from the given type string */
+/* Get the qualifier from the given type string */
#if defined(HAVE_INLINE)
INLINE int IsQualConst (const Type* T)
/* For anthing that is not a function or typedef, check for an implicit
* int declaration.
*/
- if ((D->StorageClass & SC_FUNC) != SC_FUNC &&
+ if ((D->StorageClass & SC_FUNC) != SC_FUNC &&
(D->StorageClass & SC_TYPEDEF) != SC_TYPEDEF) {
/* If the standard was not set explicitly to C89, print a warning
* for variables with implicit int type.
case T_SCHAR:
case T_UCHAR:
- if (ED_IsConstAbsInt (&Expr)) {
- /* Make it byte sized */
- Expr.IVal &= 0xFF;
- }
- DefineData (&Expr);
+ if (ED_IsConstAbsInt (&Expr)) {
+ /* Make it byte sized */
+ Expr.IVal &= 0xFF;
+ }
+ DefineData (&Expr);
Size += SIZEOF_CHAR;
break;
case T_UINT:
case T_PTR:
case T_ARRAY:
- if (ED_IsConstAbsInt (&Expr)) {
+ if (ED_IsConstAbsInt (&Expr)) {
/* Make it word sized */
- Expr.IVal &= 0xFFFF;
- }
- DefineData (&Expr);
- Size += SIZEOF_INT;
+ Expr.IVal &= 0xFFFF;
+ }
+ DefineData (&Expr);
+ Size += SIZEOF_INT;
break;
case T_LONG:
case T_ULONG:
- if (ED_IsConstAbsInt (&Expr)) {
+ if (ED_IsConstAbsInt (&Expr)) {
/* Make it dword sized */
- Expr.IVal &= 0xFFFFFFFF;
- }
- DefineData (&Expr);
- Size += SIZEOF_LONG;
+ Expr.IVal &= 0xFFFFFFFF;
+ }
+ DefineData (&Expr);
+ Size += SIZEOF_LONG;
break;
default:
- Error ("Illegal type in initialization");
+ Error ("Illegal type in initialization");
break;
}
case T_UINT:
case T_LONG:
case T_ULONG:
+ case T_FLOAT:
+ case T_DOUBLE:
return ParseScalarInit (T);
case T_PTR:
/* */
/* */
/* */
-/* (C) 2002-2006 Ullrich von Bassewitz */
-/* Römerstraße 52 */
+/* (C) 2002-2008 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
#include "asmlabel.h"
#include "datatype.h"
#include "error.h"
+#include "exprdesc.h"
#include "stackptr.h"
#include "symentry.h"
#include "exprdesc.h"
Expr->Flags = 0;
Expr->Name = 0;
Expr->IVal = 0;
- Expr->FVal = 0.0;
+ Expr->FVal = FP_D_Make (0.0);
return Expr;
}
Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL;
Expr->Name = 0;
Expr->IVal = Value;
- Expr->FVal = 0.0;
+ Expr->FVal = FP_D_Make (0.0);
return Expr;
}
Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL;
Expr->Name = 0;
Expr->IVal = Value;
- Expr->FVal = 0.0;
+ Expr->FVal = FP_D_Make (0.0);
return Expr;
}
Expr->Flags |= (E_LOC_EXPR | E_RTYPE_RVAL);
Expr->Name = 0;
Expr->IVal = 0; /* No offset */
- Expr->FVal = 0.0;
+ Expr->FVal = FP_D_Make (0.0);
return Expr;
}
Expr->Flags |= (E_LOC_EXPR | E_RTYPE_LVAL);
Expr->Name = 0;
Expr->IVal = 0; /* No offset */
- Expr->FVal = 0.0;
+ Expr->FVal = FP_D_Make (0.0);
return Expr;
}
"Raw type: (unknown)\n");
}
fprintf (F, "IVal: 0x%08lX\n", E->IVal);
- fprintf (F, "FVal: %f\n", E->FVal);
+ fprintf (F, "FVal: %f\n", FP_D_ToFloat (E->FVal));
Flags = E->Flags;
Sep = '(';
/* */
/* */
/* */
-/* (C) 2002-2006 Ullrich von Bassewitz */
-/* Römerstraße 52 */
+/* (C) 2002-2008 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
#include <string.h>
/* common */
+#include "fp.h"
#include "inline.h"
/* cc65 */
unsigned Flags;
unsigned long Name; /* Name or label number */
long IVal; /* Integer value if expression constant */
- float FVal; /* Floating point value */
+ Double FVal; /* Floating point value */
};
/* common */
#include "chartype.h"
+#include "fp.h"
#include "tgttrans.h"
/* cc65 */
} else {
/* Float constant */
- double FVal = IVal; /* Convert to float */
+ Double FVal = FP_D_FromInt (IVal); /* Convert to double */
/* Check for a fractional part and read it */
if (CurC == '.') {
- unsigned Digits;
- unsigned long Frac;
- unsigned long Scale;
+ Double Scale;
/* Skip the dot */
NextChar ();
- /* Read fractional digits. Since we support only 32 bit floats
- * with a maximum of 7 fractional digits, we read the fractional
- * part as integer with up to 8 digits and drop the remainder.
- * This avoids an overflow of Frac and Scale.
- */
- Digits = 0;
- Frac = 0;
- Scale = 1;
+ /* Read fractional digits */
+ Scale = FP_D_Make (1.0);
while (IsXDigit (CurC) && (DigitVal = HexVal (CurC)) < Base) {
- if (Digits < 8) {
- Frac = Frac * Base + DigitVal;
- ++Digits;
- Scale *= Base;
- }
+ /* Get the value of this digit */
+ Double FracVal = FP_D_Div (FP_D_FromInt (DigitVal * Base), Scale);
+ /* Add it to the float value */
+ FVal = FP_D_Add (FVal, FracVal);
+ /* Scale base */
+ Scale = FP_D_Mul (Scale, FP_D_FromInt (DigitVal));
+ /* Skip the digit */
NextChar ();
}
-
- /* Scale the fractional part and add it */
- if (Frac) {
- FVal += ((double) Frac) / ((double) Scale);
- }
}
/* Check for an exponent and read it */
/* Scale the exponent and adjust the value accordingly */
if (Exp) {
- FVal *= pow (10, Exp);
+ FVal = FP_D_Mul (FVal, FP_D_Make (pow (10, Exp)));
}
}
+/* common */
+#include "fp.h"
+
/* cc65 */
#include "datatype.h"
#include "ident.h"
struct Token {
token_t Tok; /* The token itself */
long IVal; /* The integer attribute */
- double FVal; /* The float attribute */
+ Double FVal; /* The float attribute */
ident Ident; /* Identifier if IDENT */
LineInfo* LI; /* Source line where the token comes from */
Type* Type; /* Type if integer or float constant */
--- /dev/null
+/*****************************************************************************/
+/* */
+/* fp.c */
+/* */
+/* Floating point support */
+/* */
+/* */
+/* */
+/* (C) 2008 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+/* The compiler must use the same floating point arithmetic as the target
+ * platform, otherwise expressions will yield a different result when
+ * evaluated in the compiler or on the target platform. Since writing a target
+ * and source library is almost double the work, we will at least add the
+ * hooks here, and define functions for a plug in library that may be added
+ * at a later time. Currently we use the builtin data types of the compiler
+ * that translates cc65.
+ */
+
+
+
+#include <string.h>
+
+/* common */
+#include "fp.h"
+#include "xmalloc.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+#define F_SIZE sizeof(float)
+#define D_SIZE sizeof(float) /* NOT double! */
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+size_t FP_F_Size (void)
+/* Return the size of the data type float */
+{
+ return F_SIZE;
+}
+
+
+
+unsigned char* FP_F_Data (Float Val)
+/* Return the raw data of a float in a malloc'ed buffer. Free after use. */
+{
+ return memcpy (xmalloc (F_SIZE), &Val.V, F_SIZE);
+}
+
+
+
+Float FP_F_Make (float Val)
+/* Make a floating point variable from a float value */
+{
+ Float D;
+ D.V = Val;
+ return D;
+}
+
+
+
+Float FP_F_FromInt (long Val)
+/* Convert an integer into a floating point variable */
+{
+ Float D;
+ D.V = Val;
+ return D;
+}
+
+
+
+float FP_F_ToFloat (Float Val)
+/* Convert a Float into a native float */
+{
+ return Val.V;
+}
+
+
+
+Float FP_F_Add (Float Left, Float Right)
+/* Add two floats */
+{
+ Float D;
+ D.V = Left.V + Right.V;
+ return D;
+}
+
+
+
+Float FP_F_Sub (Float Left, Float Right)
+/* Subtract two floats */
+{
+ Float D;
+ D.V = Left.V - Right.V;
+ return D;
+}
+
+
+
+Float FP_F_Mul (Float Left, Float Right)
+/* Multiplicate two floats */
+{
+ Float D;
+ D.V = Left.V * Right.V;
+ return D;
+}
+
+
+
+Float FP_F_Div (Float Left, Float Right)
+/* Divide two floats */
+{
+ Float D;
+ D.V = Left.V / Right.V;
+ return D;
+}
+
+
+
+size_t FP_D_Size (void)
+/* Return the size of the data type double */
+{
+ return D_SIZE;
+}
+
+
+
+unsigned char* FP_D_Data (Double Val)
+/* Return the raw data of a double in a malloc'ed buffer. Free after use. */
+{
+ float F = Val.V;
+ return memcpy (xmalloc (F_SIZE), &F, F_SIZE);
+}
+
+
+
+Double FP_D_Make (double Val)
+/* Make a floating point variable from a float value */
+{
+ Double D;
+ D.V = Val;
+ return D;
+}
+
+
+
+
+Double FP_D_FromInt (long Val)
+/* Convert an integer into a floating point variable */
+{
+ Double D;
+ D.V = Val;
+ return D;
+}
+
+
+
+double FP_D_ToFloat (Double Val)
+/* Convert a Double into a native double */
+{
+ return Val.V;
+}
+
+
+
+Double FP_D_Add (Double Left, Double Right)
+/* Add two floats */
+{
+ Double D;
+ D.V = Left.V + Right.V;
+ return D;
+}
+
+
+
+Double FP_D_Sub (Double Left, Double Right)
+/* Subtract two floats */
+{
+ Double D;
+ D.V = Left.V - Right.V;
+ return D;
+}
+
+
+
+Double FP_D_Mul (Double Left, Double Right)
+/* Multiplicate two floats */
+{
+ Double D;
+ D.V = Left.V * Right.V;
+ return D;
+}
+
+
+
+Double FP_D_Div (Double Left, Double Right)
+/* Divide two floats */
+{
+ Double D;
+ D.V = Left.V / Right.V;
+ return D;
+}
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* fp.h */
+/* */
+/* Floating point support */
+/* */
+/* */
+/* */
+/* (C) 2008 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+/* The compiler must use the same floating point arithmetic as the target
+ * platform, otherwise expressions will yield a different result when
+ * evaluated in the compiler or on the target platform. Since writing a target
+ * and source library is almost double the work, we will at least add the
+ * hooks here, and define functions for a plug in library that may be added
+ * at a later time. Currently we use the builtin data types of the compiler
+ * that translates cc65.
+ *
+ * BEWARE: This code will currently only work on little endian systems!
+ *
+ */
+
+
+
+#ifndef FP_H
+#define FP_H
+
+
+
+#include <stddef.h>
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+typedef union Float Float;
+union Float {
+ float V;
+};
+
+
+
+typedef union Double Double;
+union Double {
+ double V;
+};
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+size_t FP_F_Size (void);
+/* Return the size of the data type float */
+
+unsigned char* FP_F_Data (Float Val);
+/* Return the raw data of a float in a malloc'ed buffer. Free after use. */
+
+Float FP_F_Make (float Val);
+/* Make a floating point variable from a float value */
+
+Float FP_F_FromInt (long Val);
+/* Convert an integer into a floating point variable */
+
+float FP_F_ToFloat (Float Val);
+/* Convert a Float into a native float */
+
+Float FP_F_Add (Float Left, Float Right);
+/* Add two floats */
+
+Float FP_F_Sub (Float Left, Float Right);
+/* Subtract two floats */
+
+Float FP_F_Mul (Float Left, Float Right);
+/* Multiplicate two floats */
+
+Float FP_F_Div (Float Left, Float Right);
+/* Divide two floats */
+
+size_t FP_D_Size (void);
+/* Return the size of the data type double */
+
+unsigned char* FP_D_Data (Double Val);
+/* Return the raw data of a double in a malloc'ed buffer. Free after use. */
+
+Double FP_D_Make (double Val);
+/* Make a floating point variable from a float value */
+
+Double FP_D_FromInt (long Val);
+/* Convert an integer into a floating point variable */
+
+double FP_D_ToFloat (Double Val);
+/* Convert a Double into a native double */
+
+Double FP_D_Add (Double Left, Double Right);
+/* Add two floats */
+
+Double FP_D_Sub (Double Left, Double Right);
+/* Subtract two floats */
+
+Double FP_D_Mul (Double Left, Double Right);
+/* Multiplicate two floats */
+
+Double FP_D_Div (Double Left, Double Right);
+/* Divide two floats */
+
+
+
+/* End of fp.h */
+
+#endif
+
+
+
+
+
filepos.o \
filetype.o \
fname.o \
+ fp.o \
hashstr.o \
hashtab.o \
intstack.o \
filepos.obj \
filetype.obj \
fname.obj \
+ fp.obj \
hashstr.obj \
hashtab.obj \
intstack.obj \