]> Shamusworld >> Repos - rmac/commitdiff
Added floating point support to expression evaluator, introduced FLOAT token, fixup...
authorggn <ggn.dbug@gmail.com>
Thu, 26 Oct 2017 12:24:25 +0000 (15:24 +0300)
committerShamus Hammons <jlhamm@acm.org>
Sat, 18 Nov 2017 15:54:04 +0000 (09:54 -0600)
18 files changed:
amode.c
amode.h
direct.c
eagen0.c
expr.c
mach.c
macro.c
mark.c
mark.h
object.c
parmode.h
procln.c
riscasm.c
rmac.h
sect.h
symbol.c
token.c
token.h

diff --git a/amode.c b/amode.c
index 70b30e1311c6c58035efde25c6916517779e07dc..73f2bdaa15f19cdf0b671481eb69f59b8b939d52 100644 (file)
--- a/amode.c
+++ b/amode.c
@@ -32,7 +32,7 @@ WORD a0exattr;                                // Expression's attribute
 int a0ixreg;                           // Index register
 int a0ixsiz;                           // Index register size (and scale)
 TOKEN a0oexpr[EXPRSIZE];       // Outer displacement expression
 int a0ixreg;                           // Index register
 int a0ixsiz;                           // Index register size (and scale)
 TOKEN a0oexpr[EXPRSIZE];       // Outer displacement expression
-uint32_t a0oexval;                     // Outer displacement value
+uint64_t a0oexval;                     // Outer displacement value
 WORD a0oexattr;                                // Outer displacement attribute
 SYM * a0esym;                          // External symbol involved in expr
 TOKEN a0bexpr[EXPRSIZE];       // Base displacement expression
 WORD a0oexattr;                                // Outer displacement attribute
 SYM * a0esym;                          // External symbol involved in expr
 TOKEN a0bexpr[EXPRSIZE];       // Base displacement expression
@@ -50,7 +50,7 @@ WORD a1exattr;                                // Expression's attribute
 int a1ixreg;                           // Index register
 int a1ixsiz;                           // Index register size (and scale)
 TOKEN a1oexpr[EXPRSIZE];       // Outer displacement expression
 int a1ixreg;                           // Index register
 int a1ixsiz;                           // Index register size (and scale)
 TOKEN a1oexpr[EXPRSIZE];       // Outer displacement expression
-uint32_t a1oexval;                     // Outer displacement value
+uint64_t a1oexval;                     // Outer displacement value
 WORD a1oexattr;                                // Outer displacement attribute
 SYM * a1esym;                          // External symbol involved in expr
 TOKEN a1bexpr[EXPRSIZE];       // Base displacement expression
 WORD a1oexattr;                                // Outer displacement attribute
 SYM * a1esym;                          // External symbol involved in expr
 TOKEN a1bexpr[EXPRSIZE];       // Base displacement expression
@@ -88,7 +88,8 @@ int amode(int acount)
        a0exattr = a0oexattr = a1exattr = a1oexattr = 0;
        a0esym = a1esym = NULL;
        a0bexpr[0] = a1bexpr[0] = ENDEXPR;
        a0exattr = a0oexattr = a1exattr = a1oexattr = 0;
        a0esym = a1esym = NULL;
        a0bexpr[0] = a1bexpr[0] = ENDEXPR;
-       a0bexval = a0bsize = a0extension = a1bexval = a1bsize = a1extension = 0;
+       a0bexval = a1bexval = 0;
+       a0bsize = a0extension = a1bsize = a1extension = 0;
        am0_030 = am1_030 = 0;
        bfparam1 = bfparam2 = 0;
        bf0expr[0] = ENDEXPR;
        am0_030 = am1_030 = 0;
        bfparam1 = bfparam2 = 0;
        bf0expr[0] = ENDEXPR;
@@ -388,13 +389,13 @@ int check030bf(void)
 
        if (*tok == CONST)
        {
 
        if (*tok == CONST)
        {
-               tok++;  // Skip the HI LONG
                tok++;
                tok++;
-               bfval1 = *(int *)tok;
+               bfval1 = (int)*(uint64_t *)tok;
 
                // Do=0, offset=immediate - shift it to place
                bfparam1 = (0 << 11);
                tok++;
 
                // Do=0, offset=immediate - shift it to place
                bfparam1 = (0 << 11);
                tok++;
+               tok++;
        }
        else if (*tok == SYMBOL)
        {
        }
        else if (*tok == SYMBOL)
        {
@@ -404,7 +405,7 @@ int check030bf(void)
                if (!(bf0exattr & DEFINED))
                        return error("bfxxx offset: immediate value must evaluate");
 
                if (!(bf0exattr & DEFINED))
                        return error("bfxxx offset: immediate value must evaluate");
 
-               bfval1 = bf0exval;
+               bfval1 = (int)bf0exval;
 
                // Do=0, offset=immediate - shift it to place
                bfparam1 = (0 << 11);
 
                // Do=0, offset=immediate - shift it to place
                bfparam1 = (0 << 11);
@@ -431,20 +432,20 @@ int check030bf(void)
 
        if (*tok == CONST)
        {
 
        if (*tok == CONST)
        {
-               tok++;  // Skip the HI LONG
                tok++;
                tok++;
-               bfval2 = *(int *)tok;
+               bfval2 = (int)*(uint64_t *)tok;
 
                // Do=0, offset=immediate - shift it to place
                bfparam2 = (0 << 5);
                tok++;
 
                // Do=0, offset=immediate - shift it to place
                bfparam2 = (0 << 5);
                tok++;
+        tok++;
        }
        else if (*tok == SYMBOL)
        {
                if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
                        return ERROR;
 
        }
        else if (*tok == SYMBOL)
        {
                if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
                        return ERROR;
 
-               bfval2 = bf0exval;
+               bfval2 = (int)bf0exval;
 
                if (!(bf0exattr & DEFINED))
                        return error("bfxxx width: immediate value must evaluate");
 
                if (!(bf0exattr & DEFINED))
                        return error("bfxxx width: immediate value must evaluate");
diff --git a/amode.h b/amode.h
index 76501f7edc834842bd34e1b48ca13ab0b675b00f..3da232136c56458bff4842d85b10f8e866e33640 100644 (file)
--- a/amode.h
+++ b/amode.h
@@ -142,7 +142,7 @@ extern WORD a0exattr, a1exattr;
 extern int a0ixreg, a1ixreg;
 extern int a0ixsiz, a1ixsiz;
 extern TOKEN a0oexpr[], a1oexpr[];
 extern int a0ixreg, a1ixreg;
 extern int a0ixsiz, a1ixsiz;
 extern TOKEN a0oexpr[], a1oexpr[];
-extern uint32_t a0oexval, a1oexval;
+extern uint64_t a0oexval, a1oexval;
 extern WORD a0oexattr, a1oexattr;
 extern SYM * a0esym, * a1esym;
 extern uint64_t a0bexval, a1bexval;
 extern WORD a0oexattr, a1oexattr;
 extern SYM * a0esym, * a1esym;
 extern uint64_t a0bexval, a1bexval;
index 770fcf9958cbed8c1301b2069aed17869c44a9dc..7c480357c4e801b9420dd1ea1ad4b873a211a454 100644 (file)
--- a/direct.c
+++ b/direct.c
@@ -20,6 +20,8 @@
 #include "sect.h"
 #include "symbol.h"
 #include "token.h"
 #include "sect.h"
 #include "symbol.h"
 #include "token.h"
+#include "math.h"
+#include "sect.h"
 
 #define DEF_KW
 #include "kwtab.h"
 
 #define DEF_KW
 #include "kwtab.h"
@@ -859,7 +861,7 @@ int d_prgflags(void)
                return error("PRGFLAGS requires value");
        else if (abs_expr(&eval) == OK)
        {
                return error("PRGFLAGS requires value");
        else if (abs_expr(&eval) == OK)
        {
-               PRGFLAGS=eval;
+               PRGFLAGS = (uint32_t)eval;
                return 0;
        }
        else
                return 0;
        }
        else
@@ -887,7 +889,7 @@ int d_abs(void)
                return 0;
 
        SwitchSection(ABS);
                return 0;
 
        SwitchSection(ABS);
-       sloc = eval;
+       sloc = (uint32_t)eval;
        return 0;
 }
 
        return 0;
 }
 
@@ -976,9 +978,9 @@ int d_ds(WORD siz)
        // of zeroed memory....
        if ((scattr & SBSS) || cursect == M6502)
        {
        // of zeroed memory....
        if ((scattr & SBSS) || cursect == M6502)
        {
-               listvalue(eval);
+               listvalue((uint32_t)eval);
                eval *= siz;
                eval *= siz;
-               sloc += eval;
+               sloc += (uint32_t)eval;
 
                if (cursect == M6502)
                        chptr += eval;
 
                if (cursect == M6502)
                        chptr += eval;
@@ -1002,6 +1004,9 @@ int d_dc(WORD siz)
 {
        WORD eattr;
        uint64_t eval;
 {
        WORD eattr;
        uint64_t eval;
+       WORD tdb;
+       WORD defined;
+       uint64_t val64;
        uint8_t * p;
 
        if ((scattr & SBSS) != 0)
        uint8_t * p;
 
        if ((scattr & SBSS) != 0)
@@ -1056,14 +1061,26 @@ int d_dc(WORD siz)
                        siz = SIZL;
                }
 
                        siz = SIZL;
                }
 
+               if (siz != SIZQ)
+               {
                // dc.x <expression>
                SYM * esym = 0;
 
                if (expr(exprbuf, &eval, &eattr, &esym) != OK)
                        return 0;
                // dc.x <expression>
                SYM * esym = 0;
 
                if (expr(exprbuf, &eval, &eattr, &esym) != OK)
                        return 0;
+               }
+               else
+               {
+                       val64 = *(uint64_t *)(tok);
+                       tok = tok + 2;
+                       D_long((uint32_t)(val64 >> 32));
+                       D_long((uint32_t)val64);
+
+            goto comma;
+        }
 
 
-               uint16_t tdb = eattr & TDB;
-               uint16_t defined = eattr & DEFINED;
+               tdb = (WORD)(eattr & TDB);
+               defined = (WORD)(eattr & DEFINED);
 
                if ((challoc - ch_size) < 4)
                        chcheck(4);
 
                if ((challoc - ch_size) < 4)
                        chcheck(4);
@@ -1136,15 +1153,70 @@ int d_dc(WORD siz)
                                D_long(eval);
                        }
                        break;
                                D_long(eval);
                        }
                        break;
+               case SIZS:
+                       if (m6502)
+                               return error(in_6502mode);
+
+                       if (!defined)
+                       {
+                               float vv = 0;
+                               AddFixup(FU_FLOATSING, sloc, exprbuf);
+
+                               D_single(vv);
+                       }
+                       else
+                       {
+                               if (tdb)
+                                       MarkRelocatable(cursect, sloc, tdb, MSINGLE, NULL);
+
+                               D_single(eval);
+                       }
+                       break;
                case SIZD:
                case SIZD:
-                       // 64-bit size
-                       // N.B.: May have to come up with section/fixup markers for this;
-                       //       ATM it's only used in dc.d statements...
-                       D_long(eval >> 32);
-                       D_long(eval & 0xFFFFFFFF);
+                       if (m6502)
+                               return error(in_6502mode);
+
+                       if (!defined)
+                       {
+                               double vv = 0;
+                               AddFixup(FU_FLOATDOUB, sloc, exprbuf);
+
+                               D_double(vv);
+                       }
+                       else
+                       {
+                               double vv;
+                               if (tdb)
+                                       MarkRelocatable(cursect, sloc, tdb, MDOUBLE, NULL);
+
+                               vv = *(double *)&eval;
+                               D_double(vv);
+                       }
+                       break;
+               case SIZX:
+                       if (m6502)
+                               return error(in_6502mode);
+
+                       if (!defined)
+                       {
+                               double vv = 0;
+                               AddFixup(FU_FLOATEXT, sloc, exprbuf);
+
+                               D_extend(vv);
+                       }
+                       else
+                       {
+                               float vv;
+                               if (tdb)
+                                       MarkRelocatable(cursect, sloc, tdb, MEXTEND, NULL);
+
+                               vv = *(double *)&eval;
+                               D_extend(vv);
+                       }
                        break;
                }
 
                        break;
                }
 
+
 comma:
                if (*tok != ',')
                        break;
 comma:
                if (*tok != ',')
                        break;
@@ -1180,7 +1252,7 @@ int d_dcb(WORD siz)
        if (cursect != M6502 && (siz != SIZB) && (sloc & 1))
                auto_even();
 
        if (cursect != M6502 && (siz != SIZB) && (sloc & 1))
                auto_even();
 
-       dep_block(evalc, siz, eval, eattr, exprbuf);
+       dep_block((uint32_t)evalc, siz, (uint32_t)eval, eattr, exprbuf);
        return 0;
 }
 
        return 0;
 }
 
@@ -1239,7 +1311,7 @@ int d_init(WORD def_siz)
                        break;
                }
 
                        break;
                }
 
-               dep_block(count, siz, eval, eattr, exprbuf);
+               dep_block((uint32_t)count, siz, (uint32_t)eval, eattr, exprbuf);
 
                switch ((int)*tok)
                {
 
                switch ((int)*tok)
                {
@@ -1377,7 +1449,7 @@ int d_comm(void)
        if (abs_expr(&eval) != OK)                              // Parse size of common region
                return 0;
 
        if (abs_expr(&eval) != OK)                              // Parse size of common region
                return 0;
 
-       sym->svalue = eval;                                             // Install common symbol's size
+       sym->svalue = (uint32_t)eval;                   // Install common symbol's size
        at_eol();
        return 0;
 }
        at_eol();
        return 0;
 }
@@ -1619,7 +1691,7 @@ int d_cargs(void)
                        AddToSymbolDeclarationList(symbol);
 
                        symbol->sattr |= (ABS | DEFINED | EQUATED);
                        AddToSymbolDeclarationList(symbol);
 
                        symbol->sattr |= (ABS | DEFINED | EQUATED);
-                       symbol->svalue = eval;
+                       symbol->svalue = (uint32_t)eval;
                        tok += 2;
 
                        // What this does is eat any dot suffixes attached to a symbol. If
                        tok += 2;
 
                        // What this does is eat any dot suffixes attached to a symbol. If
@@ -1746,7 +1818,7 @@ int d_cstruct(void)
                        }
 
                        symbol->sattr |= (ABS | DEFINED | EQUATED);
                        }
 
                        symbol->sattr |= (ABS | DEFINED | EQUATED);
-                       symbol->svalue = eval;
+                       symbol->svalue = (uint32_t)eval;
 
                        // Check for dot suffixes and adjust space accordingly (longs and
                        // words on an odd boundary get bumped to the next word aligned
 
                        // Check for dot suffixes and adjust space accordingly (longs and
                        // words on an odd boundary get bumped to the next word aligned
index e7f388512ab35d48c3d588f7fd5b08b551757132..62e686c144859631a44d8f5026a84e9828d16300 100644 (file)
--- a/eagen0.c
+++ b/eagen0.c
@@ -9,10 +9,10 @@
 
 int eaNgen(WORD siz)
 {
 
 int eaNgen(WORD siz)
 {
-       uint32_t vbd, v = aNexval;
+       uint32_t vbd, v = (uint32_t)aNexval;
        WORD wbd, w = (WORD)(aNexattr & DEFINED);
        WORD tdbbd, tdb = (WORD)(aNexattr & TDB);
        WORD wbd, w = (WORD)(aNexattr & DEFINED);
        WORD tdbbd, tdb = (WORD)(aNexattr & TDB);
-       vbd = aNbdexval;
+       vbd = (uint32_t)aNbdexval;
        wbd = (WORD)(aNbdexattr & DEFINED);
        tdbbd = (WORD)(aNbdexattr & TDB);
 
        wbd = (WORD)(aNbdexattr & DEFINED);
        tdbbd = (WORD)(aNbdexattr & TDB);
 
@@ -208,6 +208,80 @@ int eaNgen(WORD siz)
                                D_long(0);
                        }
 
                                D_long(0);
                        }
 
+                       break;
+               case SIZS:
+                       // 68881/68882/68040 only
+                       if (w)
+                       {
+                               float vv;
+                               if (tdb)
+                                       MarkRelocatable(cursect, sloc, tdb, MSINGLE, NULL);
+
+                               vv = (float)v;
+
+                               D_single(vv);
+                       }
+                       else
+                       {
+                               float vv = 0;
+                               AddFixup(FU_FLOATSING, sloc, aNexpr);
+
+                               D_single(vv);
+                       }
+
+               break;
+               case SIZD:
+                       // 68881/68882/68040 only
+                       if (w)
+                       {
+                               double vv;
+                               unsigned long long vvv;
+                               if (tdb)
+                                       MarkRelocatable(cursect, sloc, tdb, MDOUBLE, NULL);
+
+                               // We want to store the IEE754 float into ram from a generic
+                               // 32-bit int. First, convert it to double float, then cast
+                               // that to 64-bit, then convert to big endian (if needed)
+                               // and then store it (phew!)
+                               vv = *(float *)&aNexval;
+                               vvv = BYTESWAP64(*(unsigned long long *)&vv);
+
+                               D_double(vvv);
+                       }
+                       else
+                       {
+                               unsigned long long vvv = 0;
+                               AddFixup(FU_FLOATDOUB, sloc, aNexpr);
+
+                               D_double(vvv);
+                       }
+
+                       break;
+               case SIZX:
+                       // 68881/68882/68040 only
+                       if (w)
+                       {
+                               long double vv;
+                               if (tdb)
+                                       MarkRelocatable(cursect, sloc, tdb, MEXTEND, NULL);
+
+                               // We want to store the IEE754 float into ram from a generic
+                               // 32-bit int. First, convert it to double float, then cast
+                               // that to 96-bit, then convert to big endian (if needed)
+                               // and then store it (phew!)
+                               vv = (double)aNexval;
+
+                               //*chptr++ = (char)((*(unsigned long long *)&vv) >> 32) | 0x80 /* assume that the number is normalised */;
+                               D_extend(vv);
+                       }
+                       else
+                       {
+                               long double vvv = 0;
+                               AddFixup(FU_FLOATDOUB, sloc, aNexpr);
+
+                               D_extend(vvv);
+                       }
+
                        break;
                default:
                        // IMMED size problem
                        break;
                default:
                        // IMMED size problem
diff --git a/expr.c b/expr.c
index dea1de9c92d679461c90f3778e3257db01d58c7c..a0f6f9f49494d8ea96f55aee4a6f831ba50a348e 100644 (file)
--- a/expr.c
+++ b/expr.c
@@ -29,7 +29,7 @@ static WORD evattr[EVSTACKSIZE];      // Evaluator attribute stack
 // Token-class initialization list
 char itokcl[] = {
        0,                                                              // END
 // Token-class initialization list
 char itokcl[] = {
        0,                                                              // END
-       CONST, SYMBOL, 0,                               // ID
+       CONST, FCONST, SYMBOL, 0,               // ID
        '(', '[', '{', 0,                               // OPAR
        ')', ']', '}', 0,                               // CPAR
        CR_DEFINED, CR_REFERENCED,              // SUNARY (special unary)
        '(', '[', '{', 0,                               // OPAR
        ')', ']', '}', 0,                               // CPAR
        CR_DEFINED, CR_REFERENCED,              // SUNARY (special unary)
@@ -133,6 +133,7 @@ int expr1(void)
        char * p, * p2;
        WORD w;
        int j;
        char * p, * p2;
        WORD w;
        int j;
+       uint64_t * evalTokenBuffer64;
 
        class = tokenClass[*tok];
 
 
        class = tokenClass[*tok];
 
@@ -146,6 +147,10 @@ int expr1(void)
                if (t == '-')
                        t = UNMINUS;
 
                if (t == '-')
                        t = UNMINUS;
 
+               // With leading + we don't have to deposit
+               // anything to the buffer because there's
+               // no unary '+' nor we have to do anything about it
+               if (t != '+')
                *evalTokenBuffer++ = t;
        }
        else if (class == SUNARY)
                *evalTokenBuffer++ = t;
        }
        else if (class == SUNARY)
@@ -154,18 +159,21 @@ int expr1(void)
                {
                case CR_ABSCOUNT:
                        *evalTokenBuffer++ = CONST;
                {
                case CR_ABSCOUNT:
                        *evalTokenBuffer++ = CONST;
-                       *evalTokenBuffer++ = 0;         // Set HI LONG to zero
-                       *evalTokenBuffer++ = (LONG)sect[ABS].sloc;
+                       evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+                       *evalTokenBuffer64++ = (LONG)sect[ABS].sloc;
+                       evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
                        break;
                case CR_TIME:
                        *evalTokenBuffer++ = CONST;
                        break;
                case CR_TIME:
                        *evalTokenBuffer++ = CONST;
-                       *evalTokenBuffer++ = 0;         // Set HI LONG to zero
-                       *evalTokenBuffer++ = dos_time();
+                       evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+                       *evalTokenBuffer64++ = dos_time();
+                       evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
                        break;
                case CR_DATE:
                        *evalTokenBuffer++ = CONST;
                        break;
                case CR_DATE:
                        *evalTokenBuffer++ = CONST;
-                       *evalTokenBuffer++ = 0;         // Set HI LONG to zero
-                       *evalTokenBuffer++ = dos_date();
+                       evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+                       *evalTokenBuffer64++ = dos_date();
+                       evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
                        break;
                case CR_MACDEF:                                    // ^^macdef <macro-name>
                        if (*tok++ != SYMBOL)
                        break;
                case CR_MACDEF:                                    // ^^macdef <macro-name>
                        if (*tok++ != SYMBOL)
@@ -173,8 +181,9 @@ int expr1(void)
 
                        p = string[*tok++];
                        w = (lookup(p, MACRO, 0) == NULL ? 0 : 1);
 
                        p = string[*tok++];
                        w = (lookup(p, MACRO, 0) == NULL ? 0 : 1);
-                       *evalTokenBuffer++ = CONST;
-                       *evalTokenBuffer++ = 0;         // Set HI LONG to zero
+                       evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+                       *evalTokenBuffer64++ = (TOKEN)w;
+                       evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
                        *evalTokenBuffer++ = (TOKEN)w;
                        break;
                case CR_DEFINED:
                        *evalTokenBuffer++ = (TOKEN)w;
                        break;
                case CR_DEFINED:
@@ -190,8 +199,9 @@ getsym:
                        j = (*p == '.' ? curenv : 0);
                        w = ((sy = lookup(p, LABEL, j)) != NULL && (sy->sattr & w) ? 1 : 0);
                        *evalTokenBuffer++ = CONST;
                        j = (*p == '.' ? curenv : 0);
                        w = ((sy = lookup(p, LABEL, j)) != NULL && (sy->sattr & w) ? 1 : 0);
                        *evalTokenBuffer++ = CONST;
-                       *evalTokenBuffer++ = 0;         // Set HI LONG to zero
-                       *evalTokenBuffer++ = (TOKEN)w;
+                       uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+                       *evalTokenBuffer64++ = (TOKEN)w;
+                       evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
                        break;
                case CR_STREQ:
                        if (*tok != SYMBOL && *tok != STRING)
                        break;
                case CR_STREQ:
                        if (*tok != SYMBOL && *tok != STRING)
@@ -211,8 +221,9 @@ getsym:
 
                        w = (WORD)(!strcmp(p, p2));
                        *evalTokenBuffer++ = CONST;
 
                        w = (WORD)(!strcmp(p, p2));
                        *evalTokenBuffer++ = CONST;
-                       *evalTokenBuffer++ = 0;         // Set HI LONG to zero
-                       *evalTokenBuffer++ = (TOKEN)w;
+                       evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+                       *evalTokenBuffer64++ = (TOKEN)w;
+                       evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
                        break;
                }
        }
                        break;
                }
        }
@@ -231,13 +242,26 @@ int expr2(void)
        char * p;
        SYM * sy;
        int j;
        char * p;
        SYM * sy;
        int j;
+       uint64_t * evalTokenBuffer64;
+       uint64_t * tok64;
 
        switch ((int)*tok++)
        {
        case CONST:
                *evalTokenBuffer++ = CONST;
 
        switch ((int)*tok++)
        {
        case CONST:
                *evalTokenBuffer++ = CONST;
-               *evalTokenBuffer++ = *tok++;    // HI LONG of constant
-               *evalTokenBuffer++ = *tok++;    // LO LONG of constant
+               evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+               tok64 = (uint64_t *)tok;
+               *evalTokenBuffer64++ = *tok64++;
+               tok = (TOKEN *)tok64;
+               evalTokenBuffer = (TOKEN *)evalTokenBuffer64;
+               break;
+       case FCONST:
+               *evalTokenBuffer++ = FCONST;
+               evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+               tok64 = (uint64_t *)tok;
+               *evalTokenBuffer64++ = *tok64++;
+               tok = (TOKEN *)tok64;
+               evalTokenBuffer = (TOKEN *)evalTokenBuffer64;
                break;
        case SYMBOL:
                p = string[*tok++];
                break;
        case SYMBOL:
                p = string[*tok++];
@@ -264,8 +288,9 @@ int expr2(void)
                break;
        case STRING:
                *evalTokenBuffer++ = CONST;
                break;
        case STRING:
                *evalTokenBuffer++ = CONST;
-               *evalTokenBuffer++ = 0;         // Set HI LONG to zero
-               *evalTokenBuffer++ = str_value(string[*tok++]);
+               uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+               *evalTokenBuffer64++ = str_value(string[*tok++]);
+               evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
                break;
        case '(':
                if (expr0() != OK)
                break;
        case '(':
                if (expr0() != OK)
@@ -343,19 +368,20 @@ int expr(TOKEN * otk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
        //         (assuming tok[1] == EOL is a single token that is)
        //         Seems that even other tokens (SUNARY type) can fuck this up too.
 //     if ((tok[1] == EOL)
        //         (assuming tok[1] == EOL is a single token that is)
        //         Seems that even other tokens (SUNARY type) can fuck this up too.
 //     if ((tok[1] == EOL)
-       if ((tok[1] == EOL && (tok[0] != CONST && tokenClass[tok[0]] != SUNARY))
-//             || (((*tok == CONST || *tok == SYMBOL) || (*tok >= KW_R0 && *tok <= KW_R31))
+       if ((tok[1] == EOL && ((tok[0] != CONST || tok[0] != FCONST) && tokenClass[tok[0]] != SUNARY))
+//             || (((*tok == CONST || *tok == FCONST || *tok == SYMBOL) || (*tok >= KW_R0 && *tok <= KW_R31))
 //             && (tokenClass[tok[2]] < UNARY)))
                || (((tok[0] == SYMBOL) || (tok[0] >= KW_R0 && tok[0] <= KW_R31))
                && (tokenClass[tok[2]] < UNARY))
 //             && (tokenClass[tok[2]] < UNARY)))
                || (((tok[0] == SYMBOL) || (tok[0] >= KW_R0 && tok[0] <= KW_R31))
                && (tokenClass[tok[2]] < UNARY))
-               || ((tok[0] == CONST) && (tokenClass[tok[3]] < UNARY))
+               || ((tok[0] == CONST || tok[0] == FCONST) && (tokenClass[tok[3]] < UNARY))
                )
        {
                if (*tok >= KW_R0 && *tok <= KW_R31)
                {
                        *evalTokenBuffer++ = CONST;
                )
        {
                if (*tok >= KW_R0 && *tok <= KW_R31)
                {
                        *evalTokenBuffer++ = CONST;
-                       *evalTokenBuffer++ = 0;         // Set HI LONG to zero
-                       *evalTokenBuffer++ = *a_value = (*tok - KW_R0);
+                       uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+                       *evalTokenBuffer64++ = *a_value = (*tok - KW_R0);
+                       evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
                        *a_attr = ABS | DEFINED;
 
                        if (a_esym != NULL)
                        *a_attr = ABS | DEFINED;
 
                        if (a_esym != NULL)
@@ -366,9 +392,11 @@ int expr(TOKEN * otk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
                else if (*tok == CONST)
                {
                        *evalTokenBuffer++ = CONST;
                else if (*tok == CONST)
                {
                        *evalTokenBuffer++ = CONST;
-                       *evalTokenBuffer++ = tok[1];
-                       *evalTokenBuffer++ = tok[2];
-                       *a_value = (((uint64_t)tok[1]) << 32) | tok[2];
+                       uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+                       uint64_t *tok64 = (uint64_t *)&tok[1];
+                       *evalTokenBuffer64++ = *tok64++;
+                       evalTokenBuffer = (TOKEN *)evalTokenBuffer64;
+                       *a_value = tok[1];
                        *a_attr = ABS | DEFINED;
 
                        if (a_esym != NULL)
                        *a_attr = ABS | DEFINED;
 
                        if (a_esym != NULL)
@@ -376,16 +404,32 @@ int expr(TOKEN * otk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
 
                        tok += 3;
 //printf("Quick eval in expr(): CONST = %i, tokenClass[tok[2]] = %i\n", *a_value, tokenClass[*tok]);
 
                        tok += 3;
 //printf("Quick eval in expr(): CONST = %i, tokenClass[tok[2]] = %i\n", *a_value, tokenClass[*tok]);
+               }
+               else if (*tok == FCONST)
+               {
+                       *evalTokenBuffer++ = FCONST;
+                       *((double *)evalTokenBuffer) = *((double *)&tok[1]);
+                       evalTokenBuffer += 2;
+                       //*(double *)evalTokenBuffer++ = tok[2];
+                       *a_value = *((uint64_t *)&tok[1]);
+                       *a_attr = ABS | DEFINED | FLOAT;
+
+                       if (a_esym != NULL)
+                               *a_esym = NULL;
+
+                       tok += 3;
+//printf("Quick eval in expr(): CONST = %i, tokenClass[tok[2]] = %i\n", *a_value, tokenClass[*tok]);
                }
                else if (*tok == '*')
                {
                        *evalTokenBuffer++ = CONST;
                }
                else if (*tok == '*')
                {
                        *evalTokenBuffer++ = CONST;
-                       *evalTokenBuffer++ = 0;         // Set HI LONG to zero
+                       uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
 
                        if (orgactive)
 
                        if (orgactive)
-                               *evalTokenBuffer++ = *a_value = orgaddr;
+                               *evalTokenBuffer64++ = *a_value = orgaddr;
                        else
                        else
-                               *evalTokenBuffer++ = *a_value = pcloc;
+                               *evalTokenBuffer64++ = *a_value = pcloc;
+                       evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
 
                        // '*' takes attributes of current section, not ABS!
                        *a_attr = cursect | DEFINED;
 
                        // '*' takes attributes of current section, not ABS!
                        *a_attr = cursect | DEFINED;
@@ -495,12 +539,13 @@ thrown away right here. What the hell is it for?
 //
 int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
 {
 //
 int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
 {
-       WORD attr;
+       WORD attr, attr2;
        SYM * sy;
        uint64_t * sval = evstk;                                // (Empty) initial stack
        WORD * sattr = evattr;
        SYM * esym = NULL;                                              // No external symbol involved
        WORD sym_seg = 0;
        SYM * sy;
        uint64_t * sval = evstk;                                // (Empty) initial stack
        WORD * sattr = evattr;
        SYM * esym = NULL;                                              // No external symbol involved
        WORD sym_seg = 0;
+    uint64_t *tk64;
 
        while (*tk != ENDEXPR)
        {
 
        while (*tk != ENDEXPR)
        {
@@ -540,11 +585,18 @@ int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
                        sym_seg = (WORD)(sy->sattr & TDB);
                        break;
                case CONST:
                        sym_seg = (WORD)(sy->sattr & TDB);
                        break;
                case CONST:
-                       *++sval = ((uint64_t)*tk++) << 32;                      // Push value
-                       *sval |= *tk++;         // & LO LONG (will this work???--should)
+                       tk64 = (uint64_t *)tk;
+                       *++sval = *tk64++;
+                       tk = (TOKEN *)tk64;
 //printf("evexpr(): CONST = %lX\n", *sval);
                        *++sattr = ABS | DEFINED;               // Push simple attribs
                        break;
 //printf("evexpr(): CONST = %lX\n", *sval);
                        *++sattr = ABS | DEFINED;               // Push simple attribs
                        break;
+               case FCONST:
+//printf("evexpr(): CONST = %i\n", *tk);
+                       *((double *)sval) = *((double *)tk);
+                       tk += 2;
+                       *++sattr = ABS | DEFINED | FLOAT; // Push simple attribs
+                       break;
                case ACONST:
 //printf("evexpr(): ACONST = %i\n", *tk);
                        *++sval = *tk++;                                // Push value
                case ACONST:
 //printf("evexpr(): ACONST = %i\n", *tk);
                        *++sval = *tk++;                                // Push value
@@ -567,11 +619,40 @@ int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
                        --sval;                                                 // Pop value
                        --sattr;                                                // Pop attrib
 //printf("--> N+N: %i + %i = ", *sval, sval[1]);
                        --sval;                                                 // Pop value
                        --sattr;                                                // Pop attrib
 //printf("--> N+N: %i + %i = ", *sval, sval[1]);
+                       // Extract float attributes from both terms and pack them
+                       // into a single value
+                       attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+                       attr2 = sattr[0] | sattr[1] & FLOAT; // Returns FLOAT if either of the two numbers are FLOAT
+
+                       if (attr == (FLOAT | (FLOAT >> 1)))
+                       {
+                               // Float + Float
+                               double * dst = (double *)sval;
+                               double * src = (double *)(sval + 1);
+                               *dst += *src;
+                       }
+                       else if (attr == FLOAT)
+                       {
+                               // Float + Int
+                               double * dst = (double *)sval;
+                               uint64_t * src = (uint64_t *)(sval + 1);
+                               *dst += *src;
+                       }
+                       else if (attr == FLOAT >> 1)
+                       {
+                               // Int + Float
+                               uint64_t * dst = (uint64_t *)sval;
+                               double * src = (double *)(sval + 1);
+                               *(double *)dst = *src + *dst;
+                       }
+                       else
+                       {
                        *sval += sval[1];                               // Compute value
                        *sval += sval[1];                               // Compute value
+                       }
 //printf("%i\n", *sval);
 
                        if (!(*sattr & TDB))
 //printf("%i\n", *sval);
 
                        if (!(*sattr & TDB))
-                               *sattr = sattr[1];
+                               *sattr = sattr[1] | attr2;
                        else if (sattr[1] & TDB)
                                return error(seg_error);
 
                        else if (sattr[1] & TDB)
                                return error(seg_error);
 
@@ -581,13 +662,44 @@ int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
                        --sval;                                                 // Pop value
                        --sattr;                                                // Pop attrib
 //printf("--> N-N: %i - %i = ", *sval, sval[1]);
                        --sval;                                                 // Pop value
                        --sattr;                                                // Pop attrib
 //printf("--> N-N: %i - %i = ", *sval, sval[1]);
+                       // Extract float attributes from both terms and pack them
+                       // into a single value
+                       attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+                       attr2 = sattr[0] | sattr[1] & FLOAT; // Returns FLOAT if either of the two numbers are FLOAT
+
+                       if (attr == (FLOAT | (FLOAT >> 1)))
+                       {
+                               // Float - Float
+                               double * dst = (double *)sval;
+                               double * src = (double *)(sval + 1);
+                               *dst -= *src;
+                       }
+                       else if (attr == FLOAT)
+                       {
+                               // Float - Int
+                               double * dst = (double *)sval;
+                               uint64_t * src = (uint64_t *)(sval + 1);
+                               *dst -= *src;
+                       }
+                       else if (attr == FLOAT >> 1)
+                       {
+                               // Int - Float
+                               uint64_t * dst = (uint64_t *)sval;
+                               double * src = (double *)(sval + 1);
+                               *(double *)dst = *dst - *src;
+                       }
+                       else
+                       {
                        *sval -= sval[1];                               // Compute value
                        *sval -= sval[1];                               // Compute value
+                       }
+
 //printf("%i\n", *sval);
 
                        attr = (WORD)(*sattr & TDB);
 #if 0
 printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
 #endif
 //printf("%i\n", *sval);
 
                        attr = (WORD)(*sattr & TDB);
 #if 0
 printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
 #endif
+                       *sattr |= attr2;                // Inherit FLOAT attribute
                        // If symbol1 is ABS, take attributes from symbol2
                        if (!attr)
                                *sattr = sattr[1];
                        // If symbol1 is ABS, take attributes from symbol2
                        if (!attr)
                                *sattr = sattr[1];
@@ -600,15 +712,27 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                case UNMINUS:
 //printf("evexpr(): UNMINUS\n");
                        if (*sattr & TDB)
                case UNMINUS:
 //printf("evexpr(): UNMINUS\n");
                        if (*sattr & TDB)
-                               error(seg_error);
+                               return error(seg_error);
 
 
+                       if (*sattr & FLOAT)
+                       {
+                               double *dst = (double *)sval;
+                               *dst = -*dst;
+                               *sattr = ABS | DEFINED | FLOAT; // Expr becomes absolute
+                       }
+                       else
+                       {
                        *sval = -(int)*sval;
                        *sattr = ABS | DEFINED;                 // Expr becomes absolute
                        *sval = -(int)*sval;
                        *sattr = ABS | DEFINED;                 // Expr becomes absolute
+                       }
                        break;
                case '!':
 //printf("evexpr(): !\n");
                        if (*sattr & TDB)
                        break;
                case '!':
 //printf("evexpr(): !\n");
                        if (*sattr & TDB)
-                               error(seg_error);
+                               return error(seg_error);
+
+                       if (*sattr & FLOAT)
+                               return error("floating point numbers not allowed with operator '!'.");
 
                        *sval = !*sval;
                        *sattr = ABS | DEFINED;                 // Expr becomes absolute
 
                        *sval = !*sval;
                        *sattr = ABS | DEFINED;                 // Expr becomes absolute
@@ -616,7 +740,10 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                case '~':
 //printf("evexpr(): ~\n");
                        if (*sattr & TDB)
                case '~':
 //printf("evexpr(): ~\n");
                        if (*sattr & TDB)
-                               error(seg_error);
+                               return error(seg_error);
+
+                       if (*sattr & FLOAT)
+                               return error("floating point numbers not allowed with operator '~'.");
 
                        *sval = ~*sval;
                        *sattr = ABS | DEFINED;                 // Expr becomes absolute
 
                        *sval = ~*sval;
                        *sattr = ABS | DEFINED;                 // Expr becomes absolute
@@ -629,10 +756,39 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
-                               error(seg_error);
+                               return error(seg_error);
 
 
-                       *sattr = ABS | DEFINED;
+                       // Extract float attributes from both terms and pack them
+                       // into a single value
+                       attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+
+                       if (attr == (FLOAT | (FLOAT >> 1)))
+                       {
+                               // Float <= Float
+                               double * dst = (double *)sval;
+                               double * src = (double *)(sval + 1);
+                               *sval = *dst <= *src;
+                       }
+                       else if (attr == FLOAT)
+                       {
+                               // Float <= Int
+                               double * dst = (double *)sval;
+                               uint64_t * src = (uint64_t *)(sval + 1);
+                               *sval = *dst <= *src;
+                       }
+                       else if (attr == FLOAT >> 1)
+                       {
+                               // Int <= Float
+                               uint64_t * dst = (uint64_t *)sval;
+                               double * src = (double *)(sval + 1);
+                               *sval = *dst <= *src;
+                       }
+                       else
+                       {
                        *sval = *sval <= sval[1];
                        *sval = *sval <= sval[1];
+                       }
+
+                       *sattr = ABS | DEFINED;
                        break;
                case GE:
 //printf("evexpr(): GE\n");
                        break;
                case GE:
 //printf("evexpr(): GE\n");
@@ -640,10 +796,41 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
-                               error(seg_error);
+                               return error(seg_error);
 
 
-                       *sattr = ABS | DEFINED;
+                       // Extract float attributes from both terms and pack them
+                       // into a single value
+                       attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+
+                       if (attr == (FLOAT | (FLOAT >> 1)))
+                       {
+                               // Float >= Float
+                               double * dst = (double *)sval;
+                               double * src = (double *)(sval + 1);
+                               *sval = *dst >= *src;
+                       }
+                       else if (attr == FLOAT)
+                       {
+                               // Float >= Int
+                               double * dst = (double *)sval;
+                               uint64_t * src = (uint64_t *)(sval + 1);
+                               *sval = *dst >= *src;
+                       }
+                       else if (attr == FLOAT >> 1)
+                       {
+                               // Int >= Float
+                               uint64_t * dst = (uint64_t *)sval;
+                               double * src = (double *)(sval + 1);
+                               *sval = *dst >= *src;
+                       }
+                       else if (attr == 0)
+                       {
                        *sval = *sval >= sval[1];
                        *sval = *sval >= sval[1];
+                       }
+                       else
+
+                       *sattr = ABS | DEFINED;
+
                        break;
                case '>':
 //printf("evexpr(): >\n");
                        break;
                case '>':
 //printf("evexpr(): >\n");
@@ -651,10 +838,40 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
-                               error(seg_error);
+                               return error(seg_error);
 
 
-                       *sattr = ABS | DEFINED;
+                       // Extract float attributes from both terms and pack them
+                       // into a single value
+                       attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+
+                       if (attr == (FLOAT | (FLOAT >> 1)))
+                       {
+                               // Float > Float
+                               double * dst = (double *)sval;
+                               double * src = (double *)(sval + 1);
+                               *sval = *dst > *src;
+                       }
+                       else if (attr == FLOAT)
+                       {
+                               // Float > Int
+                               double * dst = (double *)sval;
+                               uint64_t * src = (uint64_t *)(sval + 1);
+                               *sval = *dst > *src;
+                       }
+                       else if (attr == FLOAT >> 1)
+                       {
+                               // Int > Float
+                               uint64_t * dst = (uint64_t *)sval;
+                               double * src = (double *)(sval + 1);
+                               *sval = *dst > *src;
+                       }
+                       else
+=                      {
                        *sval = *sval > sval[1];
                        *sval = *sval > sval[1];
+                       }
+
+                       *sattr = ABS | DEFINED;
+
                        break;
                case '<':
 //printf("evexpr(): <\n");
                        break;
                case '<':
 //printf("evexpr(): <\n");
@@ -662,10 +879,40 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
-                               error(seg_error);
+                               return error(seg_error);
 
 
-                       *sattr = ABS | DEFINED;
+                       // Extract float attributes from both terms and pack them
+                       // into a single value
+                       attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) > >1);
+
+                       if (attr == (FLOAT | (FLOAT >> 1)))
+                       {
+                               // Float < Float
+                               double * dst = (double *)sval;
+                               double * src = (double *)(sval + 1);
+                               *sval = *dst < *src;
+                       }
+                       else if (attr == FLOAT)
+                       {
+                               // Float < Int
+                               double * dst = (double *)sval;
+                               uint64_t * src = (uint64_t *)(sval + 1);
+                               *sval = *dst < *src;
+                       }
+                       else if (attr == FLOAT >> 1)
+                       {
+                               // Int < Float
+                               uint64_t * dst = (uint64_t *)sval;
+                               double * src = (double *)(sval + 1);
+                               *sval = *dst < *src;
+                       }
+                       else
+                       {
                        *sval = *sval < sval[1];
                        *sval = *sval < sval[1];
+                       }
+
+                       *sattr = ABS | DEFINED;
+
                        break;
                case NE:
 //printf("evexpr(): NE\n");
                        break;
                case NE:
 //printf("evexpr(): NE\n");
@@ -673,10 +920,34 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
-                               error(seg_error);
+                               return error(seg_error);
 
 
-                       *sattr = ABS | DEFINED;
+                       // Extract float attributes from both terms and pack them
+                       // into a single value
+                       attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+
+                       if (attr == (FLOAT | (FLOAT >> 1)))
+                       {
+                               // Float <> Float
+                               return error("comparison for equality with float types not allowed.");
+                       }
+                       else if (attr == FLOAT)
+                       {
+                               // Float <> Int
+                               return error("comparison for equality with float types not allowed.");
+                       }
+                       else if (attr == FLOAT >> 1)
+                       {
+                               // Int != Float
+                               return error("comparison for equality with float types not allowed.");
+                       }
+                       else
+                       {
                        *sval = *sval != sval[1];
                        *sval = *sval != sval[1];
+                       }
+
+                       *sattr = ABS | DEFINED;
+
                        break;
                case '=':
 //printf("evexpr(): =\n");
                        break;
                case '=':
 //printf("evexpr(): =\n");
@@ -684,10 +955,38 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                        sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
-                               error(seg_error);
+                               return error(seg_error);
 
 
-                       *sattr = ABS | DEFINED;
+                       // Extract float attributes from both terms and pack them
+                       // into a single value
+                       attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+
+                       if (attr == (FLOAT | (FLOAT >> 1)))
+                       {
+                               // Float = Float
+                               double * dst = (double *)sval;
+                               double * src = (double *)(sval + 1);
+                               *sval = *src == *dst;
+                       }
+                       else if (attr == FLOAT)
+                       {
+                               // Float = Int
+                               return error("equality with float ");
+                       }
+                       else if (attr == FLOAT >> 1)
+                       {
+                               // Int == Float
+                               uint64_t * dst = (uint64_t *)sval;
+                               double * src = (double *)(sval + 1);
+                               *sval = *src == *dst;
+                       }
+                       else
+                       {
                        *sval = *sval == sval[1];
                        *sval = *sval == sval[1];
+                       }
+
+                       *sattr = ABS | DEFINED;
+
                        break;
                // All other binary operators must have two ABS items
                // to work with.  They all produce an ABS value.
                        break;
                // All other binary operators must have two ABS items
                // to work with.  They all produce an ABS value.
@@ -696,7 +995,6 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        // GH - Removed for v1.0.15 as part of the fix for indexed loads.
                        //if ((*sattr & (TEXT|DATA|BSS)) || (*--sattr & (TEXT|DATA|BSS)))
                        //error(seg_error);
                        // GH - Removed for v1.0.15 as part of the fix for indexed loads.
                        //if ((*sattr & (TEXT|DATA|BSS)) || (*--sattr & (TEXT|DATA|BSS)))
                        //error(seg_error);
-                       *sattr = ABS | DEFINED;                 // Expr becomes absolute
 
                        switch ((int)tk[-1])
                        {
 
                        switch ((int)tk[-1])
                        {
@@ -704,56 +1002,147 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                                sval--;
                                sattr--;                                        // Pop attrib
 //printf("--> NxN: %i x %i = ", *sval, sval[1]);
                                sval--;
                                sattr--;                                        // Pop attrib
 //printf("--> NxN: %i x %i = ", *sval, sval[1]);
+                               // Extract float attributes from both terms and pack them
+                               // into a single value
+                               attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+                               attr2 = sattr[0] | sattr[1] & FLOAT; // Returns FLOAT if either of the two numbers are FLOAT
+
+                               if (attr == (FLOAT | (FLOAT >> 1)))
+                               {
+                                       // Float * Float
+                                       double * dst = (double *)sval;
+                                       double * src = (double *)(sval + 1);
+                                       *dst *= *src;
+                               }
+                               else if (attr == FLOAT)
+                               {
+                                       // Float * Int
+                                       double * dst = (double *)sval;
+                                       uint64_t * src = (uint64_t *)(sval + 1);
+                                       *dst *= *src;
+                               }
+                               else if (attr == FLOAT >> 1)
+                               {
+                                       // Int * Float
+                                       uint64_t * dst = (uint64_t *)sval;
+                                       double * src = (double *)(sval + 1);
+                                       *(double *)dst = *src * *dst;
+                               }
+                               else
+                               {
                                *sval *= sval[1];
                                *sval *= sval[1];
+                               }
 //printf("%i\n", *sval);
 //printf("%i\n", *sval);
+
+                               *sattr = ABS | DEFINED;                 // Expr becomes absolute
+                               *sattr |= attr2;
+
                                break;
                        case '/':
                                sval--;
                                sattr--;                                        // Pop attrib
 
                                break;
                        case '/':
                                sval--;
                                sattr--;                                        // Pop attrib
 
-                               if (sval[1] == 0)
-                                       return error("division by zero");
 
 
+//printf("--> N/N: %i / %i = ", sval[0], sval[1]);
+                               // Extract float attributes from both terms and pack them
+                               // into a single value
+                               attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+                               attr2 = sattr[0] | sattr[1] & FLOAT; // Returns FLOAT if either of the two numbers are FLOAT
+
+                               if (attr == (FLOAT | (FLOAT >> 1)))
+                               {
+                                       // Float / Float
+                                       double * dst = (double *)sval;
+                                       double * src = (double *)(sval + 1);
+                                       if (*src == 0)
+                                               return error("divide by zero");
+                                       *dst = *dst / *src;
+                               }
+                               else if (attr == FLOAT)
+                               {
+                                       // Float / Int
+                                       double * dst = (double *)sval;
+                                       uint64_t * src = (uint64_t *)(sval + 1);
+                                       if (*src == 0)
+                                               return error("divide by zero");
+                                       *dst = *dst / *src;
+                               }
+                               else if (attr == FLOAT >> 1)
+                               {
+                                       // Int / Float
+                                       uint64_t * dst=(uint64_t *)sval;
+                                       double * src=(double *)(sval + 1);
+                                       if (*src == 0)
+                                               return error("divide by zero");
+                                       *(double *)dst = *dst / *src;
+                               }
+                               else
+                               {
+                                       if (sval[1] == 0)
+                                               return error("divide by zero");
 //printf("--> N/N: %i / %i = ", sval[0], sval[1]);
                                // Compiler is picky here: Without casting these, it discards
                                // the sign if dividing a negative # by a positive one,
                                // creating a bad result. :-/
                                // Definitely a side effect of using uint32_ts intead of ints.
                                *sval = (int32_t)sval[0] / (int32_t)sval[1];
 //printf("--> N/N: %i / %i = ", sval[0], sval[1]);
                                // Compiler is picky here: Without casting these, it discards
                                // the sign if dividing a negative # by a positive one,
                                // creating a bad result. :-/
                                // Definitely a side effect of using uint32_ts intead of ints.
                                *sval = (int32_t)sval[0] / (int32_t)sval[1];
+                               }
+
+                               *sattr = ABS | DEFINED;                 // Expr becomes absolute
+                               *sattr |= attr2;
+
 //printf("%i\n", *sval);
                                break;
                        case '%':
                                sval--;
                                sattr--;                                        // Pop attrib
 //printf("%i\n", *sval);
                                break;
                        case '%':
                                sval--;
                                sattr--;                                        // Pop attrib
+                               if ((*sattr | sattr[1]) & FLOAT)
+                                       return error("floating point numbers not allowed with operator '%'.");
 
                                if (sval[1] == 0)
                                        return error("mod (%) by zero");
 
 
                                if (sval[1] == 0)
                                        return error("mod (%) by zero");
 
+                               *sattr = ABS | DEFINED;                 // Expr becomes absolute
                                *sval %= sval[1];
                                break;
                        case SHL:
                                sval--;
                                sattr--;                                        // Pop attrib
                                *sval %= sval[1];
                                break;
                        case SHL:
                                sval--;
                                sattr--;                                        // Pop attrib
+                               if ((*sattr | sattr[1]) & FLOAT)
+                                       return error("floating point numbers not allowed with operator '<<'.");
+                               *sattr = ABS | DEFINED;                 // Expr becomes absolute
                                *sval <<= sval[1];
                                break;
                        case SHR:
                                sval--;
                                sattr--;                                        // Pop attrib
                                *sval <<= sval[1];
                                break;
                        case SHR:
                                sval--;
                                sattr--;                                        // Pop attrib
+                               if ((*sattr | sattr[1]) & FLOAT)
+                                       return error("floating point numbers not allowed with operator '>>'.");
+                               *sattr = ABS | DEFINED;                 // Expr becomes absolute
                                *sval >>= sval[1];
                                break;
                        case '&':
                                sval--;
                                sattr--;                                        // Pop attrib
                                *sval >>= sval[1];
                                break;
                        case '&':
                                sval--;
                                sattr--;                                        // Pop attrib
+                               if ((*sattr | sattr[1]) & FLOAT)
+                                       return error("floating point numbers not allowed with operator '&'.");
+                               *sattr = ABS | DEFINED;                 // Expr becomes absolute
                                *sval &= sval[1];
                                break;
                        case '^':
                                sval--;
                                sattr--;                                        // Pop attrib
                                *sval &= sval[1];
                                break;
                        case '^':
                                sval--;
                                sattr--;                                        // Pop attrib
+                               if ((*sattr | sattr[1]) & FLOAT)
+                                       return error("floating point numbers not allowed with operator '^'.");
+                               *sattr = ABS | DEFINED;                 // Expr becomes absolute
                                *sval ^= sval[1];
                                break;
                        case '|':
                                sval--;
                                sattr--;                                        // Pop attrib
                                *sval ^= sval[1];
                                break;
                        case '|':
                                sval--;
                                sattr--;                                        // Pop attrib
+                               if ((*sattr | sattr[1]) & FLOAT)
+                                       return error("floating point numbers not allowed with operator '|'.");
+                               *sattr = ABS | DEFINED;                 // Expr becomes absolute
                                *sval |= sval[1];
                                break;
                        default:
                                *sval |= sval[1];
                                break;
                        default:
diff --git a/mach.c b/mach.c
index edb5deacc7e4627790463005274687d428fb9c48..4e106da85efc34f6258bb3ddba4a71d5aaccc917 100644 (file)
--- a/mach.c
+++ b/mach.c
@@ -475,7 +475,7 @@ int m_lea(WORD inst, WORD siz)
                && ((am0 == ADISP) && (a0reg == a1reg) && (a0exattr & DEFINED))
                && ((a0exval > 0) && (a0exval <= 8)))
        {
                && ((am0 == ADISP) && (a0reg == a1reg) && (a0exattr & DEFINED))
                && ((a0exval > 0) && (a0exval <= 8)))
        {
-               inst = B16(01010000, 01001000) | ((a0exval & 7) << 9) | (a0reg);
+               inst = B16(01010000, 01001000) | (((uint16_t)a0exval & 7) << 9) | (a0reg);
                D_word(inst);
                warn("lea size(An),An converted to addq #size,An");
                return OK;
                D_word(inst);
                warn("lea size(An),An converted to addq #size,An");
                return OK;
@@ -1227,7 +1227,7 @@ int m_br30(WORD inst, WORD siz)
                if ((a0exattr & TDB) != cursect)
                        return error(rel_error);
 
                if ((a0exattr & TDB) != cursect)
                        return error(rel_error);
 
-               uint32_t v = a0exval - (sloc + 2);
+               uint32_t v = (uint32_t)a0exval - (sloc + 2);
                D_word(inst);
                D_long(v);
 
                D_word(inst);
                D_long(v);
 
@@ -1339,7 +1339,7 @@ int m_callm(WORD inst, WORD siz)
                if (a0exval > 255)
                        return error(range_error);
 
                if (a0exval > 255)
                        return error(range_error);
 
-               inst = a0exval;
+               inst = (uint16_t)a0exval;
                D_word(inst);
        }
        else
                D_word(inst);
        }
        else
@@ -1625,7 +1625,7 @@ int m_cpbr(WORD inst, WORD siz)
                if ((a0exattr & TDB) != cursect)
                        return error(rel_error);
 
                if ((a0exattr & TDB) != cursect)
                        return error(rel_error);
 
-               uint32_t v = a0exval - (sloc + 2);
+               uint32_t v = (uint32_t)a0exval - (sloc + 2);
 
                // Optimize branch instr. size
                if (siz == SIZL)
 
                // Optimize branch instr. size
                if (siz == SIZL)
@@ -1695,7 +1695,7 @@ int m_cpdbr(WORD inst, WORD siz)
         if ((a1exattr & TDB) != cursect)
             return error(rel_error);
 
         if ((a1exattr & TDB) != cursect)
             return error(rel_error);
 
-        v = a1exval - sloc;
+               v = (uint32_t)a1exval - sloc;
 
         if (v + 0x8000 > 0x10000)
             return error(range_error);
 
         if (v + 0x8000 > 0x10000)
             return error(range_error);
@@ -2092,7 +2092,7 @@ int m_move16b(WORD inst, WORD siz)
                {
                        //move16 (ax)+,(xxx).L
                        inst |= 0 << 3;
                {
                        //move16 (ax)+,(xxx).L
                        inst |= 0 << 3;
-                       v = a1exval;
+                       v = (int)a1exval;
                }
        }
        else if (am0 == ABSL)
                }
        }
        else if (am0 == ABSL)
@@ -2101,20 +2101,20 @@ int m_move16b(WORD inst, WORD siz)
                {
                        //move16 (xxx).L,(ax)+
                        inst |= 1 << 3;
                {
                        //move16 (xxx).L,(ax)+
                        inst |= 1 << 3;
-                       v = a0exval;
+                       v = (int)a0exval;
                }
                else //APOSTINC
                {
                        //move16 (xxx).L,(ax)
                        inst |= 3 << 3;
                }
                else //APOSTINC
                {
                        //move16 (xxx).L,(ax)
                        inst |= 3 << 3;
-                       v = a0exval;
+                       v = (int)a0exval;
                }
        }
        else if (am0 == AIND)
        {
                //move16 (ax),(xxx).L
                inst |= 2 << 3;
                }
        }
        else if (am0 == AIND)
        {
                //move16 (ax),(xxx).L
                inst |= 2 << 3;
-               v = a1exval;
+               v = (int)a1exval;
        }
 
        D_word(inst);
        }
 
        D_word(inst);
@@ -2483,7 +2483,7 @@ int m_pflush(WORD inst, WORD siz)
                 return error("function code immediate should be defined");
             if (a0exval > 7 && a0exval < 0)
                 return error("function code out of range (0-7)");
                 return error("function code immediate should be defined");
             if (a0exval > 7 && a0exval < 0)
                 return error("function code out of range (0-7)");
-            fc = a0exval;
+                       fc = (uint16_t)a0exval;
             break;
         case KW_D0:
         case KW_D1:
             break;
         case KW_D0:
         case KW_D1:
@@ -2520,7 +2520,7 @@ int m_pflush(WORD inst, WORD siz)
             return error("mask immediate value should be defined");
         if (a0exval > 7 && a0exval < 0)
             return error("function code out of range (0-7)");
             return error("mask immediate value should be defined");
         if (a0exval > 7 && a0exval < 0)
             return error("function code out of range (0-7)");
-        mask = a0exval << 5;
+               mask = (uint16_t)a0exval << 5;
 
         if (*tok == EOL)
         {
 
         if (*tok == EOL)
         {
@@ -2673,7 +2673,7 @@ int m_pload(WORD inst, WORD siz, WORD extension)
     case IMMED:
         if ((a0exattr & DEFINED) == 0)
             return error("constant value must be defined");
     case IMMED:
         if ((a0exattr & DEFINED) == 0)
             return error("constant value must be defined");
-        inst = (2 << 3) | a0exval;
+               inst = (2 << 3) | (uint16_t)a0exval;
         break;
     }
 
         break;
     }
 
@@ -2802,7 +2802,6 @@ int m_pmovefd(WORD inst, WORD siz)
        return m_pmove(inst | (1 << 8), siz);
 }
 
        return m_pmove(inst | (1 << 8), siz);
 }
 
-
 //
 // ptrapcc (68851)
 //
 //
 // ptrapcc (68851)
 //
@@ -3103,7 +3102,7 @@ int m_fdbcc(WORD inst, WORD siz)
                if ((a1exattr & TDB) != cursect)
                        return error(rel_error);
 
                if ((a1exattr & TDB) != cursect)
                        return error(rel_error);
 
-               uint32_t v = a1exval - sloc;
+               uint32_t v = (uint32_t)a1exval - sloc;
 
                if ((v + 0x8000) > 0x10000)
                        return error(range_error);
 
                if ((v + 0x8000) > 0x10000)
                        return error(range_error);
diff --git a/macro.c b/macro.c
index ccc93dc2f4cf84a1995b77fdbe19c81404484b71..54d34c43687b3cae932b9c7b5387e55b36a9ce99 100644 (file)
--- a/macro.c
+++ b/macro.c
@@ -264,7 +264,7 @@ int HandleRept(void)
                IREPT * irept = inobj->inobj.irept;
                irept->ir_firstln = firstrpt;
                irept->ir_nextln = NULL;
                IREPT * irept = inobj->inobj.irept;
                irept->ir_firstln = firstrpt;
                irept->ir_nextln = NULL;
-               irept->ir_count = eval;
+               irept->ir_count = (uint32_t)eval;
        }
 
        return 0;
        }
 
        return 0;
@@ -413,8 +413,11 @@ int InvokeMacro(SYM * mac, WORD siz)
                        else if (*tok == CONST)         // Constants are 64-bits
                        {
                                *p++ = *tok++;                  // Token
                        else if (*tok == CONST)         // Constants are 64-bits
                        {
                                *p++ = *tok++;                  // Token
-                               *p++ = *tok++;                  // Hi LONG
-                               *p++ = *tok++;                  // Lo LONG
+                               uint64_t *p64 = (uint64_t *)p;
+                               uint64_t *tok64 = (uint64_t *)tok;
+                               *p64++ = *tok64++;
+                               tok = (TOKEN *)tok64;
+                               p = (uint32_t *)p64;
                        }
                        else if ((*tok == STRING) || (*tok == SYMBOL))
                        {
                        }
                        else if ((*tok == STRING) || (*tok == SYMBOL))
                        {
diff --git a/mark.c b/mark.c
index 955fcab0c7a81d0535c4e06b625be8dab1fae07a..7378c8a6916aee2d8804c39901c042e39908e93b 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -483,6 +483,7 @@ uint32_t CreateELFRelocationRecord(uint8_t * buf, uint8_t * secBuf, uint16_t sec
 
        // Setup pointer for D_long/word/byte macros
        chptr = buf;
 
        // Setup pointer for D_long/word/byte macros
        chptr = buf;
+       ch_size = 0;
 
        for(MCHUNK * mch=firstmch; mch!=NULL; mch=mch->mcnext)
        {
 
        for(MCHUNK * mch=firstmch; mch!=NULL; mch=mch->mcnext)
        {
diff --git a/mark.h b/mark.h
index 895d6b0cef4bdc6506ec908fea39dde3f5367efd..3b2aa539efc76ad4202c2b66fb5a9d5e2cd89051 100644 (file)
--- a/mark.h
+++ b/mark.h
@@ -27,6 +27,9 @@ MCHUNK {
 #define MWORD        0x0000            // Marked word
 #define MLONG        0x0100            // Marked long
 #define MMOVEI       0x0200            // Mark RISC MOVEI instruction
 #define MWORD        0x0000            // Marked word
 #define MLONG        0x0100            // Marked long
 #define MMOVEI       0x0200            // Mark RISC MOVEI instruction
+#define MDOUBLE      0x0400            // Marked double float
+#define MEXTEND      0x0800            // Marked extended float
+#define MSINGLE      0x0880            // Marked single float (TODO: merge with MLONG?)
 #define MGLOBAL      0x0800            // Mark contains global
 #define MPCREL       0x1000            // Mark is PC-relative
 #define MCHEND       0x2000            // Indicates end of mark chunk
 #define MGLOBAL      0x0800            // Mark contains global
 #define MPCREL       0x1000            // Mark is PC-relative
 #define MCHEND       0x2000            // Indicates end of mark chunk
index 9294abefa8ed3431323b1e80f839f60ba912ce7a..73614f2e9c2e5df211dec678f38a80037fa35c72 100644 (file)
--- a/object.c
+++ b/object.c
@@ -477,7 +477,7 @@ int WriteObject(int fd)
 
                if (buf == NULL)
                {
 
                if (buf == NULL)
                {
-                       error("cannot allocate object file memory (in BSD mode)");
+                       error("cannot allocate object file memory (in ELF mode)");
                        return ERROR;
                }
 
                        return ERROR;
                }
 
@@ -487,7 +487,7 @@ int WriteObject(int fd)
 
                if (strtable == NULL)
                {
 
                if (strtable == NULL)
                {
-                       error("cannot allocate string table memory (in BSD mode)");
+                       error("cannot allocate string table memory (in ELF mode)");
                        return ERROR;
                }
 
                        return ERROR;
                }
 
index 4b6c7ea968c1f07a81e8d7ebedbed9a6a56efaee..e5e0b91606ed1e3256c5919e210b2d35c1ea1b91 100644 (file)
--- a/parmode.h
+++ b/parmode.h
                                // It might be (Dn[.wl][*scale],od)
                                // Maybe this is wrong and we have to write some code here
                                // instead of reusing that path...
                                // It might be (Dn[.wl][*scale],od)
                                // Maybe this is wrong and we have to write some code here
                                // instead of reusing that path...
+                               AnEXTEN |= EXT_BDSIZE0;     // Base displacement null - suppressed
                                goto CHECKODn;
                        }
                        else
                                goto CHECKODn;
                        }
                        else
 
                        if (*tok == ',')
                        {
 
                        if (*tok == ',')
                        {
+                               // If we got here we didn't get any [] stuff
+                               // so let's suppress base displacement before
+                               // branching off
                                tok++;
                                tok++;
+                               AnEXTEN |= EXT_BDSIZE0;     // Base displacement null - suppressed
                                goto CHECKODn;
                        }
                        if (*tok++ != ')')         // final ")"
                                goto CHECKODn;
                        }
                        if (*tok++ != ')')         // final ")"
                                tok++;
 
                                // Check for size
                                tok++;
 
                                // Check for size
+                               {
                                // ([bd,An/PC],Xn.W/L...)
                                switch ((int)*tok)
                                {
                                // ([bd,An/PC],Xn.W/L...)
                                switch ((int)*tok)
                                {
                                        // .B not allowed here...
                                        goto badmode;
                                }
                                        // .B not allowed here...
                                        goto badmode;
                                }
+                               }
 
                                // Check for scale
                                if (*tok == '*')                        // ([bd,An/PC],Xn*...)
 
                                // Check for scale
                                if (*tok == '*')                        // ([bd,An/PC],Xn*...)
 
                                        // Is .W forced here?
                                        if (*tok == DOTW)
 
                                        // Is .W forced here?
                                        if (*tok == DOTW)
+                                       {
                                                tok++;
                                                tok++;
+                                       }
                                }
 
                                // Check for final closing parenthesis
                                }
 
                                // Check for final closing parenthesis
@@ -717,6 +726,7 @@ IS_SUPPRESSEDn:
                                }
 
                                // Check for size
                                }
 
                                // Check for size
+                               {
                                // ([bd,An/PC],Xn.W/L...)
                                switch ((int)*tok)
                                {
                                // ([bd,An/PC],Xn.W/L...)
                                switch ((int)*tok)
                                {
@@ -734,6 +744,7 @@ IS_SUPPRESSEDn:
                                        // .B not allowed here...
                                        goto badmode;
                                }
                                        // .B not allowed here...
                                        goto badmode;
                                }
+                               }
 
                                // Check for scale
                                if (*tok == '*')                        // ([bd,An/PC],Xn*...)
 
                                // Check for scale
                                if (*tok == '*')                        // ([bd,An/PC],Xn*...)
index f5a806b0bf9bbb7c0592a313a17d17dad99b39df..37066c43471afba2efab76e2a5794aa92d7837a5 100644 (file)
--- a/procln.c
+++ b/procln.c
@@ -465,12 +465,11 @@ When checking to see if it's already been equated, issue a warning.
                                {
                                        // Advance token pointer to the constant
                                        tok += 3;
                                {
                                        // Advance token pointer to the constant
                                        tok += 3;
-                                       tok++;          // Skip the hi LONG, so pointing at lo LONG
 
                                        // Anything other than a 0 or a 1 will result in "No Bank"
 
                                        // Anything other than a 0 or a 1 will result in "No Bank"
-                                       if (*tok == 0)
+                                       if (*(uint64_t *)tok == 0)
                                                registerbank = BANK_0;
                                                registerbank = BANK_0;
-                                       else if (*tok == 1)
+                                       else if (*(uint64_t *)tok == 1)
                                                registerbank = BANK_1;
                                }
 
                                                registerbank = BANK_1;
                                }
 
@@ -577,10 +576,10 @@ When checking to see if it's already been equated, issue a warning.
                }
 
                sy->sattr |= eattr | EQUATED;   // Symbol inherits value and attributes
                }
 
                sy->sattr |= eattr | EQUATED;   // Symbol inherits value and attributes
-               sy->svalue = eval;
+               sy->svalue = (uint32_t)eval;
 
                if (list_flag)                                  // Put value in listing
 
                if (list_flag)                                  // Put value in listing
-                       listvalue(eval);
+                       listvalue((uint32_t)eval);
 
                at_eol();                                               // Must be at EOL now
                goto loop;
 
                at_eol();                                               // Must be at EOL now
                goto loop;
index 63466716173eef8ae94f8a348d3dd8981e6d479b..533eca7e41f52f75b70b39c834968bb0a97069ad 100644 (file)
--- a/riscasm.c
+++ b/riscasm.c
@@ -194,7 +194,7 @@ int GetRegister(WORD rattr)
 
        // If we got a register in range (0-31), return it
        if ((eval >= 0) && (eval <= 31))
 
        // If we got a register in range (0-31), return it
        if ((eval >= 0) && (eval <= 31))
-               return eval;
+               return (int)eval;
 
        // Otherwise, it's out of range & we flag an error
        return error(reg_err);
 
        // Otherwise, it's out of range & we flag an error
        return error(reg_err);
@@ -321,11 +321,11 @@ int GenerateRISCCode(int state)
                                return error("constant out of range");
 
                        if (parm & SUB32)
                                return error("constant out of range");
 
                        if (parm & SUB32)
-                               reg1 = 32 - eval;
+                               reg1 = 32 - (int)eval;
                        else if (type == RI_NUM_32)
                        else if (type == RI_NUM_32)
-                               reg1 = (reg1 == 32 ? 0 : eval);
+                               reg1 = (reg1 == 32 ? 0 : (int)eval);
                        else
                        else
-                               reg1 = eval;
+                               reg1 = (int)eval;
                }
 
                CHECK_COMMA;
                }
 
                CHECK_COMMA;
@@ -503,7 +503,7 @@ int GenerateRISCCode(int state)
                                        if (!(eattr & DEFINED))
                                                return error("constant expected after '+'");
 
                                        if (!(eattr & DEFINED))
                                                return error("constant expected after '+'");
 
-                                       reg1 = eval;
+                                       reg1 = (int)eval;
 
                                        if (reg1 == 0)
                                        {
 
                                        if (reg1 == 0)
                                        {
@@ -626,7 +626,7 @@ int GenerateRISCCode(int state)
                                        }
                                        else
                                        {
                                        }
                                        else
                                        {
-                                               reg2 = eval;
+                                               reg2 = (int)eval;
 
                                                if (reg2 == 0)
                                                {
 
                                                if (reg2 == 0)
                                                {
@@ -722,9 +722,9 @@ int GenerateRISCCode(int state)
                        {
                                // CC using a constant number
                                tok++;
                        {
                                // CC using a constant number
                                tok++;
-                               tok++;          // Toss hi LONG, as most likely not 64-bit number
-                               val = *tok;     // Use lo LONG
-                               tok++;
+                               uint64_t *tok64 = (uint64_t *)tok;
+                               val = (int)*tok64++;
+                               tok = (uint32_t *)tok64;
                                CHECK_COMMA;
                        }
                        else if (*tok == SYMBOL)
                                CHECK_COMMA;
                        }
                        else if (*tok == SYMBOL)
diff --git a/rmac.h b/rmac.h
index d5775cc4f0e0e4a08f23d2fa0fdd05e0ebbc18d4..0f92d796b9a6b60a2a32970d8299f9079b4e35ee 100644 (file)
--- a/rmac.h
+++ b/rmac.h
 // Byteswap crap
 #define BYTESWAP16(x) ((((x) & 0x00FF) << 8) | (((x) & 0xFF00) >> 8))
 #define BYTESWAP32(x) ((((x) & 0x000000FF) << 24) | (((x) & 0x0000FF00) << 8) | (((x) & 0x00FF0000) >> 8) | (((x) & 0xFF000000) >> 24))
 // Byteswap crap
 #define BYTESWAP16(x) ((((x) & 0x00FF) << 8) | (((x) & 0xFF00) >> 8))
 #define BYTESWAP32(x) ((((x) & 0x000000FF) << 24) | (((x) & 0x0000FF00) << 8) | (((x) & 0x00FF0000) >> 8) | (((x) & 0xFF000000) >> 24))
+#define BYTESWAP64(x) (BYTESWAP32(x>>32)|BYTESWAP32((x&0xffffffff)<<32))
 #define WORDSWAP32(x) ((((x) & 0x0000FFFF) << 16) | (((x) & 0xFFFF0000) >> 16))
 
 //
 #define WORDSWAP32(x) ((((x) & 0x0000FFFF) << 16) | (((x) & 0xFFFF0000) >> 16))
 
 //
 #define CREATMASK    0
 
 // Object code formats
 #define CREATMASK    0
 
 // Object code formats
-#define ALCYON       0                 // Alcyon/DRI C object format
-#define MWC          1                 // Mark Williams object format
-#define BSD          2                 // BSD object format
-#define ELF          3                 // ELF object format
-#define XEX          4                 // COM/EXE/XEX/whatever a8 object format
+enum
+{
+ALCYON,                        // Alcyon/DRI C object format
+MWC,                           // Mark Williams object format
+BSD,                           // BSD object format
+ELF,                           // ELF object format
+LOD,                           // DSP 56001 object format
+P56,                           // DSP 56001 object format
+XEX,                           // COM/EXE/XEX/whatever a8 object format
+};
 
 // Pointer type that can point to (almost) anything
 #define PTR union _ptr
 
 // Pointer type that can point to (almost) anything
 #define PTR union _ptr
@@ -194,6 +200,7 @@ PTR
 #define REFERENCED   0x1000            // Symbol has been referenced
 #define EQUATED      0x0800            // Symbol was equated
 #define SDECLLIST    0x0400            // Symbol is on 'sdecl'-order list
 #define REFERENCED   0x1000            // Symbol has been referenced
 #define EQUATED      0x0800            // Symbol was equated
 #define SDECLLIST    0x0400            // Symbol is on 'sdecl'-order list
+#define FLOAT        0x0200            // Symbol is a floating point value
 
 // Expression spaces, ORed with symbol and expression attributes above
 #define ABS          0x0000            // In absolute space
 
 // Expression spaces, ORed with symbol and expression attributes above
 #define ABS          0x0000            // In absolute space
@@ -212,7 +219,7 @@ PTR
 #define SIZS         0x0020            // .s (FPU single precision real)
 #define SIZX         0x0040            // .x (FPU extended precision real)
 #define SIZP         0x0080            // .p (FPU pakced decimal real)
 #define SIZS         0x0020            // .s (FPU single precision real)
 #define SIZX         0x0040            // .x (FPU extended precision real)
 #define SIZP         0x0080            // .p (FPU pakced decimal real)
-#define SIZQ         SIZD
+#define SIZQ         0x0100            // .q
 
 // RISC register bank definitions (used in extended symbol attributes also)
 #define BANK_N       0x0000            // No register bank specified
 
 // RISC register bank definitions (used in extended symbol attributes also)
 #define BANK_N       0x0000            // No register bank specified
diff --git a/sect.h b/sect.h
index 3cfbf6acee00501820814fbbe328e1d8f2ee264b..f2aee8da27ac65d4fe504a08ac4449d9a1a9f859 100644 (file)
--- a/sect.h
+++ b/sect.h
                                                sloc += 4; ch_size += 4; if(orgactive) orgaddr += 4;}
 #define D_rword(w)     {*chptr++=(uint8_t)(w); *chptr++=(uint8_t)((w)>>8); \
                                                sloc+=2; ch_size+=2;if(orgactive) orgaddr += 2;}
                                                sloc += 4; ch_size += 4; if(orgactive) orgaddr += 4;}
 #define D_rword(w)     {*chptr++=(uint8_t)(w); *chptr++=(uint8_t)((w)>>8); \
                                                sloc+=2; ch_size+=2;if(orgactive) orgaddr += 2;}
+#define D_single(w) {chcheck(4);*chptr++ = ((char *)&w)[3]; \
+                                               *chptr++ = ((char *)&w)[2]; \
+                                               *chptr++ = ((char *)&w)[1]; \
+                                               *chptr++=((char *)&w)[0]; \
+                                               sloc+=4; ch_size += 4; if(orgactive) orgaddr += 4;}
+#define D_double(w) {chcheck(8);*chptr++=(char)((*(unsigned long long *)&w)); \
+                                               *chptr++=(char)((*(unsigned long long *)&w)>>8); \
+                                               *chptr++=(char)((*(unsigned long long *)&w)>>16); \
+                                               *chptr++=(char)((*(unsigned long long *)&w)>>24); \
+                                               *chptr++=(char)((*(unsigned long long *)&w)>>32); \
+                                               *chptr++=(char)((*(unsigned long long *)&w)>>40); \
+                                               *chptr++=(char)((*(unsigned long long *)&w)>>48); \
+                                               *chptr++=(char)((*(unsigned long long *)&w)>>56); \
+                                               sloc+=8; ch_size += 8; if(orgactive) orgaddr += 8;}
+#ifdef _MSC_VER
+#define D_extend(w) {chcheck(12); *chptr++ = (char)((*(unsigned long long *)&w) >> 56); \
+*chptr++ = (char)(((*(unsigned long long *)&w) >> (52)) & 0xf); \
+*chptr++ = (char)(0); \
+*chptr++ = (char)(0); \
+*chptr++ = (char)(((*(unsigned long long *)&w) >> (48 - 3))|0x80 /* assume that the number is normalised */); \
+*chptr++ = (char)((*(unsigned long long *)&w) >> (40 - 3)); \
+*chptr++ = (char)((*(unsigned long long *)&w) >> (32 - 3)); \
+*chptr++ = (char)((*(unsigned long long *)&w) >> (24 - 3)); \
+*chptr++ = (char)((*(unsigned long long *)&w) >> (16 - 3)); \
+*chptr++ = (char)((*(unsigned long long *)&w) >> (8 - 3)); \
+*chptr++ = (char)((*(unsigned long long *)&w << 3)); \
+*chptr++=(char)(0); \
+       sloc+=12; ch_size += 12; if(orgactive) orgaddr += 12;}
+#elif defined(LITTLE_ENDIAN)
+#define D_extend(w) {chcheck(12);*chptr++=((char *)&w)[0]; \
+                                               *chptr++=((char *)&w)[1]; \
+                                               *chptr++=((char *)&w)[2]; \
+                                               *chptr++=((char *)&w)[3]; \
+                                               *chptr++=((char *)&w)[4]; \
+                                               *chptr++=((char *)&w)[5]; \
+                                               *chptr++=((char *)&w)[6]; \
+                                               *chptr++=((char *)&w)[7]; \
+                                               *chptr++=((char *)&w)[8]; \
+                                               *chptr++=((char *)&w)[9]; \
+                                               *chptr++=((char *)&w)[10]; \
+                                               *chptr++=((char *)&w)[11]; \
+                                               sloc+=12; ch_size += 12; if(orgactive) orgaddr += 12;}
+
+#else
+
+#error Please implement a non-byte swapped D_extend!
+
+#endif
 // Fill n bytes with zeroes
 #define D_ZEROFILL(n)  {memset(chptr, 0, n); chptr+=n; sloc+=n; ch_size+=n;\
                                                if (orgactive) orgaddr+=n;}
 // Fill n bytes with zeroes
 #define D_ZEROFILL(n)  {memset(chptr, 0, n); chptr+=n; sloc+=n; ch_size+=n;\
                                                if (orgactive) orgaddr+=n;}
 #define FU_LBRA      0x4000            // Long branch, for short branch detect
 #define FU_DONE      0x8000            // Fixup has been done
 
 #define FU_LBRA      0x4000            // Long branch, for short branch detect
 #define FU_DONE      0x8000            // Fixup has been done
 
+// FPU fixups
+// TODO: these are obviously bogus for now!
+#define FU_FLOATSING 0x0D0B            // Fixup 32-bit float
+#define FU_FLOATDOUB 0x0E0B            // Fixup 64-bit float
+#define FU_FLOATEXT  0x0F0B            // Fixup 96-bit float
+
 // Chunks are used to hold generated code and fixup records
 #define CHUNK  struct _chunk
 CHUNK {
 // Chunks are used to hold generated code and fixup records
 #define CHUNK  struct _chunk
 CHUNK {
index 6700f149968511a9a707660f03a9ab01ff4241af..80d2b3b52e13048f91f8c6f28cf579629659d95a 100644 (file)
--- a/symbol.c
+++ b/symbol.c
@@ -260,22 +260,6 @@ uint32_t sy_assign(uint8_t * buf, uint8_t *(* construct)())
                }
        }
 
                }
        }
 
-       // For ELF object mode run through all symbols in reference order
-       // and export all global-referenced labels. Not sure if this is
-       // required but it's here nonetheless
-/* why?? when you have sy_assign_ELF ???
-       if (obj_format == ELF)
-       {
-               for(sy=sdecl; sy!=NULL; sy=sy->sorder)
-               {
-                       if ((sy->sattr == (GLOBAL | REFERENCED)) && (buf != NULL))
-                       {
-                               buf = (*construct)(buf, sy, 0);
-                               scount++;
-                       }
-               }
-       }*/
-
        return scount;
 }
 
        return scount;
 }
 
@@ -305,27 +289,12 @@ uint32_t sy_assign_ELF(uint8_t * buf, uint8_t *(* construct)())
        // them. We also pick which symbols should be global or not here.
        for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl)
        {
        // them. We also pick which symbols should be global or not here.
        for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl)
        {
-               // Export or import external references, and export COMMON blocks.
-               //if ((sy->stype == LABEL)
-               //      && ((sy->sattr & (GLOBAL | DEFINED)) == (GLOBAL | DEFINED)
-               //      || (sy->sattr & (GLOBAL | REFERENCED)) == (GLOBAL | REFERENCED))
-               //      || (sy->sattr & COMMON))
-               //{
-               //      sy->senv = (WORD)scount++;
-        //
-               //      if (buf != NULL)
-               //              buf = (*construct)(buf, sy, 1);
-               //}
                // Export vanilla labels (but don't make them global). An exception is
                // made for equates, which are not exported unless they are referenced.
                if (sy->stype == LABEL && lsym_flag
                        && (sy->sattr & (DEFINED | REFERENCED)) != 0
                        && (*sy->sname != '.')
                        && (sy->sattr & GLOBAL) == 0)
                // Export vanilla labels (but don't make them global). An exception is
                // made for equates, which are not exported unless they are referenced.
                if (sy->stype == LABEL && lsym_flag
                        && (sy->sattr & (DEFINED | REFERENCED)) != 0
                        && (*sy->sname != '.')
                        && (sy->sattr & GLOBAL) == 0)
-               //if (sy->stype == 0)
-               //      if (lsym_flag)
-               //              if ((sy->sattr & (DEFINED | REFERENCED)) != 0)
-               //                      if ((!as68_flag || *sy->sname != 'L'))
                {
                        sy->senv = scount++;
 
                {
                        sy->senv = scount++;
 
diff --git a/token.c b/token.c
index 4ceaa579abb3e232931c1aae68533408f6ff746b..f719dc356791e84142046f6e6251afe62e2ad345 100644 (file)
--- a/token.c
+++ b/token.c
@@ -568,8 +568,8 @@ DEBUG { printf("ExM: SYMBOL=\"%s\"", d); }
 //         to choke on legitimate code... Need to investigate this further
 //         before changing anything else here!
                                                        case CONST:
 //         to choke on legitimate code... Need to investigate this further
 //         before changing anything else here!
                                                        case CONST:
-                                                               tk++;   // Skip the hi LONG...
                                                                sprintf(numbuf, "$%lx", (uint64_t)*tk++);
                                                                sprintf(numbuf, "$%lx", (uint64_t)*tk++);
+                                                               tk++;
                                                                d = numbuf;
                                                                break;
                                                        case DEQUALS:
                                                                d = numbuf;
                                                                break;
                                                        case DEQUALS:
@@ -951,10 +951,13 @@ int TokenizeLine(void)
        int j = 0;                                      // Var for keyword detector
        uint8_t c;                                      // Random char
        uint64_t v;                                     // Random value
        int j = 0;                                      // Var for keyword detector
        uint8_t c;                                      // Random char
        uint64_t v;                                     // Random value
+       uint32_t cursize = 0;           // Current line's size (.b, .w, .l, .s, .q, .d)
+       double f;                                       // Random float
        uint8_t * nullspot = NULL;      // Spot to clobber for SYMBOL termination
        int stuffnull;                          // 1:terminate SYMBOL '\0' at *nullspot
        uint8_t c1;
        int stringNum = 0;                      // Pointer to string locations in tokenized line
        uint8_t * nullspot = NULL;      // Spot to clobber for SYMBOL termination
        int stuffnull;                          // 1:terminate SYMBOL '\0' at *nullspot
        uint8_t c1;
        int stringNum = 0;                      // Pointer to string locations in tokenized line
+       uint64_t * tk64;
 
 retry:
 
 
 retry:
 
@@ -1135,6 +1138,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); }
                                        return error("[bwsl] must follow '.' in symbol");
 
                                v = (uint32_t)dotxtab[*ln++];
                                        return error("[bwsl] must follow '.' in symbol");
 
                                v = (uint32_t)dotxtab[*ln++];
+                               cursize = (uint32_t)v;
 
                                if (chrtab[*ln] & CTSYM)
                                        return error("misuse of '.'; not allowed in symbols");
 
                                if (chrtab[*ln] & CTSYM)
                                        return error("misuse of '.'; not allowed in symbols");
@@ -1316,6 +1320,19 @@ dostring:
                        case '$':               // $, hex constant
                                if (chrtab[*ln] & HDIGIT)
                                {
                        case '$':               // $, hex constant
                                if (chrtab[*ln] & HDIGIT)
                                {
+                                       if (cursize == 'q' || cursize == 'Q')
+                                       {
+                                               // Parse 64-bit integer
+                                               uint64_t v64 = 0;
+
+                                               while (hextab[*ln] >= 0)
+                                                       v64 = (v64 << 4) + (int)hextab[*ln++];
+
+                                               *(uint64_t *)tk = v64;
+                                               tk = tk + 2;
+
+                                               continue;
+                                       }
                                        v = 0;
 
                                        // Parse the hex value
                                        v = 0;
 
                                        // Parse the hex value
@@ -1345,8 +1362,9 @@ dostring:
                                        }
 
                                        *tk++ = CONST;
                                        }
 
                                        *tk++ = CONST;
-                                       *tk++ = v >> 32;                // High LONG of 64-bit value
-                                       *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value
+                                       tk64 = (uint64_t *)tk;
+                                       *tk64++ = v;
+                                       tk = (TOKEN *)tk64;
 
                                        if (obj_format == ALCYON)
                                        {
 
                                        if (obj_format == ALCYON)
                                        {
@@ -1457,8 +1475,9 @@ dostring:
                                }
 
                                *tk++ = CONST;
                                }
 
                                *tk++ = CONST;
-                               *tk++ = v >> 32;                // High LONG of 64-bit value
-                               *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value
+                               tk64 = (uint64_t *)tk;
+                               *tk64++ = v;
+                               tk = (TOKEN *)tk64;
                                continue;
                        case '@':               // @ or octal constant
                                if (*ln < '0' || *ln > '7')
                                continue;
                        case '@':               // @ or octal constant
                                if (*ln < '0' || *ln > '7')
@@ -1494,8 +1513,9 @@ dostring:
                                }
 
                                *tk++ = CONST;
                                }
 
                                *tk++ = CONST;
-                               *tk++ = v >> 32;                // High LONG of 64-bit value
-                               *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value
+                               tk64 = (uint64_t *)tk;
+                               *tk64++ = v;
+                               tk = (TOKEN *)tk64;
                                continue;
                        case '^':               // ^ or ^^ <operator-name>
                                if (*ln != '^')
                                continue;
                        case '^':               // ^ or ^^ <operator-name>
                                if (*ln != '^')
@@ -1570,8 +1590,9 @@ dostring:
                                        v &= 0x000000FF;
                                        ln += 2;
                                        *tk++ = CONST;
                                        v &= 0x000000FF;
                                        ln += 2;
                                        *tk++ = CONST;
-                                       *tk++ = 0;                      // Hi LONG of 64-bits
-                                       *tk++ = v;
+                                       tk64 = (uint64_t *)tk;
+                                       *tk64++ = v;
+                                       tk = (uint32_t *)tk64;
                                        *tk++ = DOTB;
                                }
                                else if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W'))
                                        *tk++ = DOTB;
                                }
                                else if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W'))
@@ -1579,8 +1600,10 @@ dostring:
                                        v &= 0x0000FFFF;
                                        ln += 2;
                                        *tk++ = CONST;
                                        v &= 0x0000FFFF;
                                        ln += 2;
                                        *tk++ = CONST;
-                                       *tk++ = 0;                      // Hi LONG of 64-bits
-                                       *tk++ = v;
+                                       tk64 = (uint64_t *)tk;
+                                       *tk64++ = v;
+                                       tk = (uint32_t *)tk64;
+
                                        *tk++ = DOTW;
                                }
                                else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
                                        *tk++ = DOTW;
                                }
                                else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
@@ -1588,16 +1611,38 @@ dostring:
                                        v &= 0xFFFFFFFF;
                                        ln += 2;
                                        *tk++ = CONST;
                                        v &= 0xFFFFFFFF;
                                        ln += 2;
                                        *tk++ = CONST;
-                                       *tk++ = 0;                      // Hi LONG of 64-bits
-                                       *tk++ = v;
+                                       tk64 = (uint64_t *)tk;
+                                       *tk64++ = v;
+                                       tk = (uint32_t *)tk64;
+
                                        *tk++ = DOTL;
                                }
                                        *tk++ = DOTL;
                                }
+                               else if ((int)chrtab[*(ln + 1)] & DIGIT)
+                               {
+                                       // Hey, more digits after the dot, so assume it's a
+                                       // fractional number
+                                       double fract = 10;
+                                       ln++;
+                                       f = (double)v;
+
+                                       while ((int)chrtab[*ln] & DIGIT)
+                                       {
+                                               f = f + (double)(*ln++ - '0') / fract;
+                                               fract *= 10;
+                                       }
+
+                                       *tk++ = FCONST;
+                                       *((double *)tk) = f;
+                                       tk += 2;
+                                       continue;
+                               }
                        }
                        else
                        {
                                *tk++ = CONST;
                        }
                        else
                        {
                                *tk++ = CONST;
-                               *tk++ = v >> 32;                // High LONG of 64-bit value
-                               *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value
+                               tk64 = (uint64_t *)tk;
+                               *tk64++ = v;
+                               tk = (TOKEN *)tk64;
                        }
 
 //printf("CONST: %i\n", v);
                        }
 
 //printf("CONST: %i\n", v);
diff --git a/token.h b/token.h
index cbacccf3a1ae45460e7b2ff283994085f9d4e96c..cedaa037d8ce6752fd7d80133a33fac34a5cf5e6 100644 (file)
--- a/token.h
+++ b/token.h
@@ -34,6 +34,7 @@
 // (Normally) non-printable tokens
 #define COLON           ':'                    // : (grumble: GNUmacs hates ':')
 #define CONST           'a'                    // CONST <value>
 // (Normally) non-printable tokens
 #define COLON           ':'                    // : (grumble: GNUmacs hates ':')
 #define CONST           'a'                    // CONST <value>
+#define FCONST          'r'                    // Floating CONST <value>
 #define ACONST          'A'                    // ACONST <value> <attrib>
 #define STRING          'b'                    // STRING <address>
 #define STRINGA8        'S'                    // Atari 800 internal STRING <address>
 #define ACONST          'A'                    // ACONST <value> <attrib>
 #define STRING          'b'                    // STRING <address>
 #define STRINGA8        'S'                    // Atari 800 internal STRING <address>