]> git.sur5r.net Git - cc65/commitdiff
Some more floating point support.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 11 Aug 2008 17:51:00 +0000 (17:51 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 11 Aug 2008 17:51:00 +0000 (17:51 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@3886 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/datatype.c
src/cc65/datatype.h
src/cc65/declare.c
src/cc65/exprdesc.c
src/cc65/exprdesc.h
src/cc65/scanner.c
src/cc65/scanner.h
src/common/fp.c [new file with mode: 0644]
src/common/fp.h [new file with mode: 0644]
src/common/make/gcc.mak
src/common/make/watcom.mak

index 4c7e23ff0890c047260237c2e3adefb3f80f5502..738a8afaac81951c10de2e0c384d5237b5e76e4b 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (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                                                 */
 /*                                                                           */
@@ -43,6 +43,7 @@
 #include "codegen.h"
 #include "datatype.h"
 #include "error.h"
+#include "fp.h"
 #include "funcdesc.h"
 #include "global.h"
 #include "symtab.h"
index c3467d0dc78fa00fc17e968703e9354ada033630..3b5b99245d12896d5aa5b26906b7deb9885f07df 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2006 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/* (C) 1998-2008 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -159,14 +159,14 @@ struct Type {
 #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 */
@@ -507,7 +507,7 @@ INLINE int IsSignSigned (const Type* T)
 #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)
index 6cb45dada95f52e8a1fa1a73045051d943182298..cf3521f8fcbdfcb4cbf0f42b138dc12f1951780f 100644 (file)
@@ -1208,7 +1208,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
     /* 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.
@@ -1612,11 +1612,11 @@ static unsigned ParseVoidInit (void)
 
            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;
 
@@ -1626,26 +1626,26 @@ static unsigned ParseVoidInit (void)
            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;
 
        }
@@ -1679,6 +1679,8 @@ static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers)
        case T_UINT:
        case T_LONG:
        case T_ULONG:
+        case T_FLOAT:
+        case T_DOUBLE:
             return ParseScalarInit (T);
 
        case T_PTR:
index c99125550c95beffbf1e3105b4988ff826fad94c..0d282c94a46b68d88511eaddf1d60e73ce98ecaf 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (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                                                 */
 /*                                                                           */
@@ -41,6 +41,7 @@
 #include "asmlabel.h"
 #include "datatype.h"
 #include "error.h"
+#include "exprdesc.h"
 #include "stackptr.h"
 #include "symentry.h"
 #include "exprdesc.h"
@@ -61,7 +62,7 @@ ExprDesc* ED_Init (ExprDesc* Expr)
     Expr->Flags = 0;
     Expr->Name  = 0;
     Expr->IVal  = 0;
-    Expr->FVal  = 0.0;
+    Expr->FVal  = FP_D_Make (0.0);
     return Expr;
 }
 
@@ -141,7 +142,7 @@ ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type)
     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;
 }
 
@@ -155,7 +156,7 @@ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value)
     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;
 }
 
@@ -171,7 +172,7 @@ ExprDesc* ED_MakeRValExpr (ExprDesc* 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;
 }
 
@@ -187,7 +188,7 @@ ExprDesc* ED_MakeLValExpr (ExprDesc* 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;
 }
 
@@ -253,7 +254,7 @@ void PrintExprDesc (FILE* F, ExprDesc* E)
                     "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   = '(';
index bdf3662d0d23300d24a9b6c6bf82125c896482c8..6876bfd079234053b092afdb87660a1f3bbff0f1 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (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                                                 */
 /*                                                                           */
@@ -41,6 +41,7 @@
 #include <string.h>
 
 /* common */
+#include "fp.h"
 #include "inline.h"
 
 /* cc65 */
@@ -89,7 +90,7 @@ struct ExprDesc {
     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 */
 };
 
 
index cc073e37313157786eea0c0e761245ce868ee501..2f5bfecb09216c0e23c7b6074cc818d8f54889a3 100644 (file)
@@ -42,6 +42,7 @@
 
 /* common */
 #include "chartype.h"
+#include "fp.h"
 #include "tgttrans.h"
 
 /* cc65 */
@@ -583,39 +584,28 @@ static void NumericConst (void)
     } 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 */
@@ -664,7 +654,7 @@ static void NumericConst (void)
 
             /* 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)));
             }
         }
 
index b98170697c51f7d564b2259499554213ed4f7906..0b5b19a3e30c6b674c31a58f8405bab28d6da1dc 100644 (file)
@@ -38,6 +38,9 @@
 
 
 
+/* common */
+#include "fp.h"
+
 /* cc65 */
 #include "datatype.h"
 #include "ident.h"
@@ -192,7 +195,7 @@ typedef struct Token Token;
 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 */
diff --git a/src/common/fp.c b/src/common/fp.c
new file mode 100644 (file)
index 0000000..c9300c5
--- /dev/null
@@ -0,0 +1,241 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                   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;
+}
+
+
+
diff --git a/src/common/fp.h b/src/common/fp.h
new file mode 100644 (file)
index 0000000..6886d51
--- /dev/null
@@ -0,0 +1,147 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                   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
+
+
+
+
+
index 56e90448aa053d1af9d06ef8b1483deb52ad4ea2..f2118253e7c6d0283c80d387f40726a96de877bf 100644 (file)
@@ -22,6 +22,7 @@ OBJS =        abend.o         \
        filepos.o       \
         filetype.o      \
        fname.o         \
+        fp.o            \
        hashstr.o       \
         hashtab.o       \
         intstack.o      \
index 6d428d00d8cd3b5f0e4a4ed1f73bd40b7e390322..db3c2863c92028e38a11dcb7ed43163684fdec0f 100644 (file)
@@ -68,6 +68,7 @@ OBJS =        abend.obj       \
        filepos.obj     \
         filetype.obj    \
        fname.obj       \
+        fp.obj          \
        hashstr.obj     \
         hashtab.obj     \
         intstack.obj    \