]> Shamusworld >> Repos - rmac/blobdiff - amode.c
Version bump for last commit. :-)
[rmac] / amode.c
diff --git a/amode.c b/amode.c
index 8a69672bb075b90184b6f983949b7763627d96f4..6fd353849b7f7acf287f28aeda2d42763a78cfa9 100644 (file)
--- a/amode.c
+++ b/amode.c
@@ -1,7 +1,7 @@
 //
-// RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
+// RMAC - Renamed Macro Assembler for all Atari computers
 // AMODE.C - Addressing Modes
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2021 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 #include "sect.h"
 #include "token.h"
 
-#define DEF_KW
-#include "kwtab.h"
+#define DEF_REG68
+#include "68kregs.h"
 #define DEF_MN
 #include "mntab.h"
 
+extern char unsupport[];
 
 // Address-mode information
 int nmodes;                                    // Number of addr'ing modes found
 int am0;                                       // Addressing mode
 int a0reg;                                     // Register
 TOKEN a0expr[EXPRSIZE];                // Expression
-VALUE a0exval;                         // Expression's value
+uint64_t a0exval;                      // Expression's value
 WORD a0exattr;                         // Expression's attribute
 int a0ixreg;                           // Index register
 int a0ixsiz;                           // Index register size (and scale)
-TOKEN a0oexpr[EXPRSIZE];       // Outer displacement expression
-VALUE a0oexval;                                // Outer displacement value
-WORD a0oexattr;                                // Outer displacement attribute
 SYM * a0esym;                          // External symbol involved in expr
 TOKEN a0bexpr[EXPRSIZE];       // Base displacement expression
-VALUE a0bexval;                                // Base displacement value
+uint64_t a0bexval;                     // Base displacement value
 WORD a0bexattr;                                // Base displacement attribute
 WORD a0bsize;                          // Base displacement size
 WORD a0extension;                      // 020+ extension address word
@@ -44,33 +42,31 @@ WORD am0_030;                               // ea bits for 020+ addressing modes
 int am1;                                       // Addressing mode
 int a1reg;                                     // Register
 TOKEN a1expr[EXPRSIZE];                // Expression
-VALUE a1exval;                         // Expression's value
+uint64_t a1exval;                      // Expression's value
 WORD a1exattr;                         // Expression's attribute
 int a1ixreg;                           // Index register
 int a1ixsiz;                           // Index register size (and scale)
-TOKEN a1oexpr[EXPRSIZE];       // Outer displacement expression
-VALUE a1oexval;                                // Outer displacement value
-WORD a1oexattr;                                // Outer displacement attribute
 SYM * a1esym;                          // External symbol involved in expr
 TOKEN a1bexpr[EXPRSIZE];       // Base displacement expression
-VALUE a1bexval;                                // Base displacement value
+uint64_t a1bexval;                     // Base displacement value
 WORD a1bexattr;                                // Base displacement attribute
 WORD a1bsize;                          // Base displacement size
 WORD a1extension;                      // 020+ extension address word
 WORD am1_030;                          // ea bits for 020+ addressing modes
 
 int a2reg;                                     // Register for div.l (68020+)
-WORD mulmode;                          // To distinguish between 32 and 64 bit multiplications (68020+)
 
-int bfparam1;                          // bfxxx instruction parameter 1
-int bfparam2;                          // bfxxx instruction parameter 2
+int bfparam1;                          // bfxxx / fmove instruction parameter 1
+int bfparam2;                          // bfxxx / fmove instruction parameter 2
+int bfval1;                                    // bfxxx / fmove value 1
+int bfval2;                                    // bfxxx / fmove value 2
 TOKEN bf0expr[EXPRSIZE];       // Expression
-VALUE bf0exval;                                // Expression's value
+uint64_t bf0exval;                     // Expression's value
 WORD bf0exattr;                                // Expression's attribute
 SYM * bf0esym;                         // External symbol involved in expr
 
 // Function prototypes
-int check030bf(void);
+int Check030Bitfield(void);
 
 
 //
@@ -81,11 +77,12 @@ int amode(int acount)
        // Initialize global return values
        nmodes = a0reg = a1reg = 0;
        am0 = am1 = AM_NONE;
-       a0expr[0] = a0oexpr[0] = a1expr[0] = a1oexpr[0] = ENDEXPR;
-       a0exattr = a0oexattr = a1exattr = a1oexattr = 0;
+       a0expr[0] = a1expr[0] = ENDEXPR;
+       a0exattr = a1exattr = 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;
@@ -105,9 +102,6 @@ int amode(int acount)
        #define AnEXPR    a0expr
        #define AnEXVAL   a0exval
        #define AnEXATTR  a0exattr
-       #define AnOEXPR   a0oexpr
-       #define AnOEXVAL  a0oexval
-       #define AnOEXATTR a0oexattr
        #define AnESYM    a0esym
        #define AMn_IX0   am0_ix0
        #define AMn_IXN   am0_ixn
@@ -128,8 +122,9 @@ int amode(int acount)
 
        // it's a bitfield instruction--check the parameters inside the {} block
        // for validity
-       if ((*tok == '{') && (check030bf() == ERROR))
-               return ERROR;
+       if (*tok == '{')
+               if (Check030Bitfield() == ERROR)
+                       return ERROR;
 
        if ((acount == 0) || (*tok != ','))
                return 1;
@@ -146,9 +141,6 @@ int amode(int acount)
        #define AnEXPR    a1expr
        #define AnEXVAL   a1exval
        #define AnEXATTR  a1exattr
-       #define AnOEXPR   a1oexpr
-       #define AnOEXVAL  a1oexval
-       #define AnOEXATTR a1oexattr
        #define AnESYM    a1esym
        #define AMn_IX0   am1_ix0
        #define AMn_IXN   am1_ixn
@@ -165,7 +157,8 @@ int amode(int acount)
 
        // It's a bitfield instruction--check the parameters inside the {} block
        // for validity
-       if ((*tok == '{') && (check030bf() == ERROR))
+       if (*tok == '{')
+        if (Check030Bitfield() == ERROR)
                return ERROR;
 
        // At this point, it is legal for 020+ to have a ':'. For example divu.l
@@ -178,27 +171,18 @@ int amode(int acount)
                // TODO: protect this from combinations like Dx:FPx etc :)
                tok++;  //eat the colon
 
-               if ((*tok >= KW_D0) && (*tok <= KW_D7))
-               {
-                       a2reg = (*tok - KW_D0);
-                       mulmode = 1 << 10;
-               }
-               else if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
-               {
-                       a2reg = (*tok - KW_FP0);
-                       mulmode = 1 << 10;
-               }
+               if ((*tok >= REG68_D0) && (*tok <= REG68_D7))
+                       a2reg = (*tok++) & 7;
+               else if ((*tok >= REG68_FP0) && (*tok <= REG68_FP7))
+                       a2reg = (*tok++) & 7;
                else
                        return error("a data or FPU register must follow a :");
-
-               *tok++;
        }
        else
        {
                // If no ':' is present then maybe we have something like divs.l d0,d1
                // which sould translate to divs.l d0,d1:d1
                a2reg = a1reg;
-               mulmode = 0;
        }
 
        nmodes = 2;
@@ -207,9 +191,6 @@ int amode(int acount)
        // Error messages:
 badmode:
        return error("addressing mode syntax");
-
-       //unmode:
-       //return error("unimplemented addressing mode");
 }
 
 
@@ -230,7 +211,7 @@ int reglist(WORD * a_rmask)
 
        for(;;)
        {
-               if ((*tok >= KW_D0) && (*tok <= KW_A7))
+               if ((*tok >= REG68_D0) && (*tok <= REG68_A7))
                        r = *tok++ & 0x0F;
                else
                        break;
@@ -239,7 +220,7 @@ int reglist(WORD * a_rmask)
                {
                        tok++;
 
-                       if ((*tok >= KW_D0) && (*tok <= KW_A7))
+                       if ((*tok >= REG68_D0) && (*tok <= REG68_A7))
                                cnt = *tok++ & 0x0F;
                        else
                                return error("register list syntax");
@@ -282,7 +263,7 @@ int fpu_reglist_left(WORD * a_rmask)
 
        for(;;)
        {
-               if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+               if ((*tok >= REG68_FP0) && (*tok <= REG68_FP7))
                        r = *tok++ & 0x07;
                else
                        break;
@@ -291,7 +272,7 @@ int fpu_reglist_left(WORD * a_rmask)
                {
                        tok++;
 
-                       if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+                       if ((*tok >= REG68_FP0) && (*tok <= REG68_FP7))
                                cnt = *tok++ & 0x07;
                        else
                                return error("register list syntax");
@@ -304,6 +285,8 @@ int fpu_reglist_left(WORD * a_rmask)
                else
                        cnt = 0;
 
+               r = 0;
+
                while (cnt-- >= 0)
                        rmask |= msktab_minus[r++];
 
@@ -322,8 +305,8 @@ int fpu_reglist_left(WORD * a_rmask)
 int fpu_reglist_right(WORD * a_rmask)
 {
        static WORD msktab_plus[] = {
-               0x0001, 0x0002, 0x0004, 0x0008,
-               0x0010, 0x0020, 0x0040, 0x0080
+               0x0080, 0x0040, 0x0020, 0x0010,
+               0x0008, 0x0004, 0x0002, 0x0001
        };
 
        WORD rmask = 0;
@@ -331,7 +314,7 @@ int fpu_reglist_right(WORD * a_rmask)
 
        for(;;)
        {
-               if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+               if ((*tok >= REG68_FP0) && (*tok <= REG68_FP7))
                        r = *tok++ & 0x07;
                else
                        break;
@@ -340,7 +323,7 @@ int fpu_reglist_right(WORD * a_rmask)
                {
                        tok++;
 
-                       if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+                       if ((*tok >= REG68_FP0) && (*tok <= REG68_FP7))
                                cnt = *tok++ & 0x07;
                        else
                                return error("register list syntax");
@@ -374,51 +357,47 @@ int fpu_reglist_right(WORD * a_rmask)
 // bfxxx <ea>{param1,param2}
 // param1/2 are either data registers or immediate values
 //
-int check030bf(void)
+int Check030Bitfield(void)
 {
-       WARNING(Add more strict checks as well as checks for non defined (yet) labels)
-
-       if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
-               return error(unsupport);
-
+       PTR tp;
+       CHECK00;
        tok++;
 
        if (*tok == CONST)
        {
-               tok++;
-               bfparam1 = *(int *)tok;
-
-               if ((bfparam1 > 31) || (bfparam1 < 0))
-                       return error("bfxxx offset: immediate value must be between 0 and 31");
+               tp.u32 = tok + 1;
+               bfval1 = (int)*tp.u64++;
+               tok = tp.u32;
 
                // Do=0, offset=immediate - shift it to place
-               bfparam1 = (bfparam1 << 6) | (0 << 11);
-               tok++;
+               bfparam1 = (0 << 11);
        }
        else if (*tok == SYMBOL)
        {
                if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
                        return ERROR;
 
-               bfparam1 = bf0exval;
+               if (!(bf0exattr & DEFINED))
+                       return error("bfxxx offset: immediate value must evaluate");
 
-               if ((bfparam1 > 31) || (bfparam1 < 0))
-                       return error("bfxxx offset: immediate value must be between 0 and 31");
+               bfval1 = (int)bf0exval;
 
                // Do=0, offset=immediate - shift it to place
-               bfparam1 = (bfparam1 << 6) | (0 << 11);
+               bfparam1 = (0 << 11);
        }
-       else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+       else if ((*tok >= REG68_D0) && (*tok <= REG68_D7))
        {
                // Do=1, offset=data register - shift it to place
-               bfparam1 = ((*(int *)tok - 128) << 6) | (1 << 11);
+               bfparam1 = (1 << 11);
+               bfval1 = (*(int *)tok - 128);
                tok++;
        }
        else
                return ERROR;
 
-       if (*tok==':')
-               tok++;  //eat the ':'
+       // Eat the ':', if any
+       if (*tok == ':')
+               tok++;
 
        if (*tok == '}' && tok[1] == EOL)
        {
@@ -429,33 +408,31 @@ int check030bf(void)
 
        if (*tok == CONST)
        {
-               tok++;
-               bfparam2 = *(int *)tok;
-
-               if (bfparam2 > 31 || bfparam2 < 0)
-                       return error("bfxxx width: immediate value must be between 0 and 31");
+               tp.u32 = tok + 1;
+               bfval2 = (int)*tp.u64++;
+               tok = tp.u32;
 
                // Do=0, offset=immediate - shift it to place
-               bfparam2 = (bfparam2 << 0) | (0 << 5);
-               tok++;
+               bfparam2 = (0 << 5);
        }
        else if (*tok == SYMBOL)
        {
                if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
                        return ERROR;
 
-               bfparam2 = bf0exval;
+               bfval2 = (int)bf0exval;
 
-               if (bfparam2 > 31 || bfparam2 < 0)
-                       return error("bfxxx width: immediate value must be between 0 and 31");
+               if (!(bf0exattr & DEFINED))
+                       return error("bfxxx width: immediate value must evaluate");
 
                // Do=0, offset=immediate - shift it to place
-               bfparam2 = (bfparam2 << 0) | (0 << 5);
+               bfparam2 = (0 << 5);
        }
-       else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+       else if ((*tok >= REG68_D0) && (*tok <= REG68_D7))
        {
                // Do=1, offset=data register - shift it to place
-               bfparam2 = ((*(int *)tok - 128) << 0) | (1 << 5);
+               bfval2 = (*(int *)tok - 128);
+               bfparam2 = (1 << 5);
                tok++;
        }
        else