X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=amode.c;h=c930a9695269b2787e872b82a7ceb424e599e136;hp=8a69672bb075b90184b6f983949b7763627d96f4;hb=HEAD;hpb=5f23454f7155f0c77ea1bede3f9e60b39da99fa8 diff --git a/amode.c b/amode.c index 8a69672..6fd3538 100644 --- 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 // @@ -15,27 +15,25 @@ #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 {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