mirror of
https://github.com/cc65/cc65.git
synced 2024-12-25 02:29:52 +00:00
Some more floating point support.
git-svn-id: svn://svn.cc65.org/cc65/trunk@3886 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
0b60ac4716
commit
0b4f6426e2
@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2006 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* Römerstraße 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@ -43,6 +43,7 @@
|
|||||||
#include "codegen.h"
|
#include "codegen.h"
|
||||||
#include "datatype.h"
|
#include "datatype.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "fp.h"
|
||||||
#include "funcdesc.h"
|
#include "funcdesc.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2006 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@ -159,14 +159,14 @@ struct Type {
|
|||||||
#define UNSPECIFIED -1L /* Element count was not specified */
|
#define UNSPECIFIED -1L /* Element count was not specified */
|
||||||
#define FLEXIBLE 0L /* Flexible array struct member */
|
#define FLEXIBLE 0L /* Flexible array struct member */
|
||||||
|
|
||||||
/* Sizes */
|
/* Sizes. Floating point sizes come from fp.h */
|
||||||
#define SIZEOF_CHAR 1
|
#define SIZEOF_CHAR 1
|
||||||
#define SIZEOF_SHORT 2
|
#define SIZEOF_SHORT 2
|
||||||
#define SIZEOF_INT 2
|
#define SIZEOF_INT 2
|
||||||
#define SIZEOF_LONG 4
|
#define SIZEOF_LONG 4
|
||||||
#define SIZEOF_LONGLONG 8
|
#define SIZEOF_LONGLONG 8
|
||||||
#define SIZEOF_FLOAT 4
|
#define SIZEOF_FLOAT (FP_F_Size())
|
||||||
#define SIZEOF_DOUBLE 4
|
#define SIZEOF_DOUBLE (FP_D_Size())
|
||||||
#define SIZEOF_PTR 2
|
#define SIZEOF_PTR 2
|
||||||
|
|
||||||
/* Predefined type strings */
|
/* Predefined type strings */
|
||||||
@ -507,7 +507,7 @@ INLINE int IsSignSigned (const Type* T)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
TypeCode GetQualifier (const Type* T) attribute ((const));
|
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)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE int IsQualConst (const Type* T)
|
INLINE int IsQualConst (const Type* T)
|
||||||
|
@ -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
|
/* For anthing that is not a function or typedef, check for an implicit
|
||||||
* int declaration.
|
* int declaration.
|
||||||
*/
|
*/
|
||||||
if ((D->StorageClass & SC_FUNC) != SC_FUNC &&
|
if ((D->StorageClass & SC_FUNC) != SC_FUNC &&
|
||||||
(D->StorageClass & SC_TYPEDEF) != SC_TYPEDEF) {
|
(D->StorageClass & SC_TYPEDEF) != SC_TYPEDEF) {
|
||||||
/* If the standard was not set explicitly to C89, print a warning
|
/* If the standard was not set explicitly to C89, print a warning
|
||||||
* for variables with implicit int type.
|
* for variables with implicit int type.
|
||||||
@ -1612,11 +1612,11 @@ static unsigned ParseVoidInit (void)
|
|||||||
|
|
||||||
case T_SCHAR:
|
case T_SCHAR:
|
||||||
case T_UCHAR:
|
case T_UCHAR:
|
||||||
if (ED_IsConstAbsInt (&Expr)) {
|
if (ED_IsConstAbsInt (&Expr)) {
|
||||||
/* Make it byte sized */
|
/* Make it byte sized */
|
||||||
Expr.IVal &= 0xFF;
|
Expr.IVal &= 0xFF;
|
||||||
}
|
}
|
||||||
DefineData (&Expr);
|
DefineData (&Expr);
|
||||||
Size += SIZEOF_CHAR;
|
Size += SIZEOF_CHAR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1626,26 +1626,26 @@ static unsigned ParseVoidInit (void)
|
|||||||
case T_UINT:
|
case T_UINT:
|
||||||
case T_PTR:
|
case T_PTR:
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
if (ED_IsConstAbsInt (&Expr)) {
|
if (ED_IsConstAbsInt (&Expr)) {
|
||||||
/* Make it word sized */
|
/* Make it word sized */
|
||||||
Expr.IVal &= 0xFFFF;
|
Expr.IVal &= 0xFFFF;
|
||||||
}
|
}
|
||||||
DefineData (&Expr);
|
DefineData (&Expr);
|
||||||
Size += SIZEOF_INT;
|
Size += SIZEOF_INT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
case T_ULONG:
|
case T_ULONG:
|
||||||
if (ED_IsConstAbsInt (&Expr)) {
|
if (ED_IsConstAbsInt (&Expr)) {
|
||||||
/* Make it dword sized */
|
/* Make it dword sized */
|
||||||
Expr.IVal &= 0xFFFFFFFF;
|
Expr.IVal &= 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
DefineData (&Expr);
|
DefineData (&Expr);
|
||||||
Size += SIZEOF_LONG;
|
Size += SIZEOF_LONG;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Error ("Illegal type in initialization");
|
Error ("Illegal type in initialization");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1679,6 +1679,8 @@ static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers)
|
|||||||
case T_UINT:
|
case T_UINT:
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
case T_ULONG:
|
case T_ULONG:
|
||||||
|
case T_FLOAT:
|
||||||
|
case T_DOUBLE:
|
||||||
return ParseScalarInit (T);
|
return ParseScalarInit (T);
|
||||||
|
|
||||||
case T_PTR:
|
case T_PTR:
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2002-2006 Ullrich von Bassewitz */
|
/* (C) 2002-2008 Ullrich von Bassewitz */
|
||||||
/* Römerstraße 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@ -41,6 +41,7 @@
|
|||||||
#include "asmlabel.h"
|
#include "asmlabel.h"
|
||||||
#include "datatype.h"
|
#include "datatype.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "exprdesc.h"
|
||||||
#include "stackptr.h"
|
#include "stackptr.h"
|
||||||
#include "symentry.h"
|
#include "symentry.h"
|
||||||
#include "exprdesc.h"
|
#include "exprdesc.h"
|
||||||
@ -61,7 +62,7 @@ ExprDesc* ED_Init (ExprDesc* Expr)
|
|||||||
Expr->Flags = 0;
|
Expr->Flags = 0;
|
||||||
Expr->Name = 0;
|
Expr->Name = 0;
|
||||||
Expr->IVal = 0;
|
Expr->IVal = 0;
|
||||||
Expr->FVal = 0.0;
|
Expr->FVal = FP_D_Make (0.0);
|
||||||
return Expr;
|
return Expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +142,7 @@ ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type)
|
|||||||
Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL;
|
Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL;
|
||||||
Expr->Name = 0;
|
Expr->Name = 0;
|
||||||
Expr->IVal = Value;
|
Expr->IVal = Value;
|
||||||
Expr->FVal = 0.0;
|
Expr->FVal = FP_D_Make (0.0);
|
||||||
return Expr;
|
return Expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +156,7 @@ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value)
|
|||||||
Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL;
|
Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL;
|
||||||
Expr->Name = 0;
|
Expr->Name = 0;
|
||||||
Expr->IVal = Value;
|
Expr->IVal = Value;
|
||||||
Expr->FVal = 0.0;
|
Expr->FVal = FP_D_Make (0.0);
|
||||||
return Expr;
|
return Expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +172,7 @@ ExprDesc* ED_MakeRValExpr (ExprDesc* Expr)
|
|||||||
Expr->Flags |= (E_LOC_EXPR | E_RTYPE_RVAL);
|
Expr->Flags |= (E_LOC_EXPR | E_RTYPE_RVAL);
|
||||||
Expr->Name = 0;
|
Expr->Name = 0;
|
||||||
Expr->IVal = 0; /* No offset */
|
Expr->IVal = 0; /* No offset */
|
||||||
Expr->FVal = 0.0;
|
Expr->FVal = FP_D_Make (0.0);
|
||||||
return Expr;
|
return Expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +188,7 @@ ExprDesc* ED_MakeLValExpr (ExprDesc* Expr)
|
|||||||
Expr->Flags |= (E_LOC_EXPR | E_RTYPE_LVAL);
|
Expr->Flags |= (E_LOC_EXPR | E_RTYPE_LVAL);
|
||||||
Expr->Name = 0;
|
Expr->Name = 0;
|
||||||
Expr->IVal = 0; /* No offset */
|
Expr->IVal = 0; /* No offset */
|
||||||
Expr->FVal = 0.0;
|
Expr->FVal = FP_D_Make (0.0);
|
||||||
return Expr;
|
return Expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +254,7 @@ void PrintExprDesc (FILE* F, ExprDesc* E)
|
|||||||
"Raw type: (unknown)\n");
|
"Raw type: (unknown)\n");
|
||||||
}
|
}
|
||||||
fprintf (F, "IVal: 0x%08lX\n", E->IVal);
|
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;
|
Flags = E->Flags;
|
||||||
Sep = '(';
|
Sep = '(';
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2002-2006 Ullrich von Bassewitz */
|
/* (C) 2002-2008 Ullrich von Bassewitz */
|
||||||
/* Römerstraße 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@ -41,6 +41,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "fp.h"
|
||||||
#include "inline.h"
|
#include "inline.h"
|
||||||
|
|
||||||
/* cc65 */
|
/* cc65 */
|
||||||
@ -89,7 +90,7 @@ struct ExprDesc {
|
|||||||
unsigned Flags;
|
unsigned Flags;
|
||||||
unsigned long Name; /* Name or label number */
|
unsigned long Name; /* Name or label number */
|
||||||
long IVal; /* Integer value if expression constant */
|
long IVal; /* Integer value if expression constant */
|
||||||
float FVal; /* Floating point value */
|
Double FVal; /* Floating point value */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "chartype.h"
|
#include "chartype.h"
|
||||||
|
#include "fp.h"
|
||||||
#include "tgttrans.h"
|
#include "tgttrans.h"
|
||||||
|
|
||||||
/* cc65 */
|
/* cc65 */
|
||||||
@ -583,39 +584,28 @@ static void NumericConst (void)
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Float constant */
|
/* 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 */
|
/* Check for a fractional part and read it */
|
||||||
if (CurC == '.') {
|
if (CurC == '.') {
|
||||||
|
|
||||||
unsigned Digits;
|
Double Scale;
|
||||||
unsigned long Frac;
|
|
||||||
unsigned long Scale;
|
|
||||||
|
|
||||||
/* Skip the dot */
|
/* Skip the dot */
|
||||||
NextChar ();
|
NextChar ();
|
||||||
|
|
||||||
/* Read fractional digits. Since we support only 32 bit floats
|
/* Read fractional digits */
|
||||||
* with a maximum of 7 fractional digits, we read the fractional
|
Scale = FP_D_Make (1.0);
|
||||||
* 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;
|
|
||||||
while (IsXDigit (CurC) && (DigitVal = HexVal (CurC)) < Base) {
|
while (IsXDigit (CurC) && (DigitVal = HexVal (CurC)) < Base) {
|
||||||
if (Digits < 8) {
|
/* Get the value of this digit */
|
||||||
Frac = Frac * Base + DigitVal;
|
Double FracVal = FP_D_Div (FP_D_FromInt (DigitVal * Base), Scale);
|
||||||
++Digits;
|
/* Add it to the float value */
|
||||||
Scale *= Base;
|
FVal = FP_D_Add (FVal, FracVal);
|
||||||
}
|
/* Scale base */
|
||||||
|
Scale = FP_D_Mul (Scale, FP_D_FromInt (DigitVal));
|
||||||
|
/* Skip the digit */
|
||||||
NextChar ();
|
NextChar ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scale the fractional part and add it */
|
|
||||||
if (Frac) {
|
|
||||||
FVal += ((double) Frac) / ((double) Scale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for an exponent and read it */
|
/* Check for an exponent and read it */
|
||||||
@ -664,7 +654,7 @@ static void NumericConst (void)
|
|||||||
|
|
||||||
/* Scale the exponent and adjust the value accordingly */
|
/* Scale the exponent and adjust the value accordingly */
|
||||||
if (Exp) {
|
if (Exp) {
|
||||||
FVal *= pow (10, Exp);
|
FVal = FP_D_Mul (FVal, FP_D_Make (pow (10, Exp)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "fp.h"
|
||||||
|
|
||||||
/* cc65 */
|
/* cc65 */
|
||||||
#include "datatype.h"
|
#include "datatype.h"
|
||||||
#include "ident.h"
|
#include "ident.h"
|
||||||
@ -192,7 +195,7 @@ typedef struct Token Token;
|
|||||||
struct Token {
|
struct Token {
|
||||||
token_t Tok; /* The token itself */
|
token_t Tok; /* The token itself */
|
||||||
long IVal; /* The integer attribute */
|
long IVal; /* The integer attribute */
|
||||||
double FVal; /* The float attribute */
|
Double FVal; /* The float attribute */
|
||||||
ident Ident; /* Identifier if IDENT */
|
ident Ident; /* Identifier if IDENT */
|
||||||
LineInfo* LI; /* Source line where the token comes from */
|
LineInfo* LI; /* Source line where the token comes from */
|
||||||
Type* Type; /* Type if integer or float constant */
|
Type* Type; /* Type if integer or float constant */
|
||||||
|
241
src/common/fp.c
Normal file
241
src/common/fp.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
147
src/common/fp.h
Normal file
147
src/common/fp.h
Normal file
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -22,6 +22,7 @@ OBJS = abend.o \
|
|||||||
filepos.o \
|
filepos.o \
|
||||||
filetype.o \
|
filetype.o \
|
||||||
fname.o \
|
fname.o \
|
||||||
|
fp.o \
|
||||||
hashstr.o \
|
hashstr.o \
|
||||||
hashtab.o \
|
hashtab.o \
|
||||||
intstack.o \
|
intstack.o \
|
||||||
|
@ -68,6 +68,7 @@ OBJS = abend.obj \
|
|||||||
filepos.obj \
|
filepos.obj \
|
||||||
filetype.obj \
|
filetype.obj \
|
||||||
fname.obj \
|
fname.obj \
|
||||||
|
fp.obj \
|
||||||
hashstr.obj \
|
hashstr.obj \
|
||||||
hashtab.obj \
|
hashtab.obj \
|
||||||
intstack.obj \
|
intstack.obj \
|
||||||
|
Loading…
Reference in New Issue
Block a user