#include "amode.h"
#include "error.h"
-#include "token.h"
#include "expr.h"
-#include "rmac.h"
+#include "mach.h"
#include "procln.h"
+#include "rmac.h"
#include "sect.h"
+#include "token.h"
#define DEF_KW
#include "kwtab.h"
#define DEF_MN
#include "mntab.h"
-extern int activecpu;
-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
-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
-WORD a0bexattr; // Base displacement attribute
-WORD a0bsize; // Base displacement size
-WORD a0extension; // 020+ extension address word
-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
-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
-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 nmodes; // Number of addr'ing modes found
+int am0; // Addressing mode
+int a0reg; // Register
+TOKEN a0expr[EXPRSIZE]; // Expression
+VALUE 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
+WORD a0bexattr; // Base displacement attribute
+WORD a0bsize; // Base displacement size
+WORD a0extension; // 020+ extension address word
+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
+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
+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
+TOKEN bf0expr[EXPRSIZE]; // Expression
+VALUE bf0exval; // Expression's value
+WORD bf0exattr; // Expression's attribute
+SYM * bf0esym; // External symbol involved in expr
+
+// Function prototypes
+int check030bf(void);
+
//
// Parse addressing mode
//
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;
- a0esym = a1esym = (SYM *)NULL;
- a0bexpr[0]=a1bexpr[0]= ENDEXPR;
- a0bexval=a0bsize=a0extension=a1bexval=a1bsize=a1extension=0;
- am0_030=am1_030=0;
- bfparam1=bfparam2=0;
- bf0expr[0]=ENDEXPR;
- bf0exattr=0;
- bf0esym= (SYM *)NULL;
-
- // If at EOL, then no addr modes at all
- if (*tok == EOL)
- return 0;
-
- // Parse first addressing mode
- #define AnOK a0ok
- #define AMn am0
- #define AnREG a0reg
- #define AnIXREG a0ixreg
- #define AnIXSIZ a0ixsiz
- #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
- #define CHK_FOR_DISPn CheckForDisp0
- #define AnBEXPR a0bexpr
- #define AnBEXVAL a0bexval
- #define AnBEXATTR a0bexattr
- #define AnBZISE a0bsize
- #define AnEXTEN a0extension
- #define AMn_030 am0_030
- #define IS_SUPPRESSEDn IS_SUPPRESSED0
- #define CHECKODn CHECKOD0
- #include "parmode.h"
-
- // If caller wants only one mode, return just one (ignore comma);
- // If there is no second addressing mode (no comma), then return just one anyway.
- nmodes = 1;
-
- if (*tok == '{')
- if (check030bf()==ERROR) // it's a bitfield instruction - check the parameters inside the {} block for validity
- return ERROR;
-
- if (acount == 0 || *tok != ',')
- return 1;
-
- // Eat the comma
- tok++;
-
- // Parse second addressing mode
- #define AnOK a1ok
- #define AMn am1
- #define AnREG a1reg
- #define AnIXREG a1ixreg
- #define AnIXSIZ a1ixsiz
- #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
- #define CHK_FOR_DISPn CheckForDisp1
- #define AnBEXPR a1bexpr
- #define AnBEXVAL a1bexval
- #define AnBEXATTR a1bexattr
- #define AnBZISE a1bsize
- #define AnEXTEN a1extension
- #define AMn_030 am1_030
- #define IS_SUPPRESSEDn IS_SUPPRESSED1
- #define CHECKODn CHECKOD1
- #include "parmode.h"
-
- if (*tok == '{')
- if (check030bf()==ERROR) // it's a bitfield instruction - check the parameters inside the {} block for validity
- return ERROR;
-
- // At this point, it is legal for 020+ to have a ':'. For example divu.l d0,d2:d3
- if (*tok == ':')
- {
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
- // 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;
- }
- 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;
- return 2;
-
- // Error messages:
- badmode:
- return error("addressing mode syntax");
-
- //unmode:
- //return error("unimplemented addressing mode");
+ // 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;
+ a0esym = a1esym = NULL;
+ a0bexpr[0] = a1bexpr[0] = ENDEXPR;
+ a0bexval = a0bsize = a0extension = a1bexval = a1bsize = a1extension = 0;
+ am0_030 = am1_030 = 0;
+ bfparam1 = bfparam2 = 0;
+ bf0expr[0] = ENDEXPR;
+ bf0exattr = 0;
+ bf0esym = NULL;
+
+ // If at EOL, then no addr modes at all
+ if (*tok == EOL)
+ return 0;
+
+ // Parse first addressing mode
+ #define AnOK a0ok
+ #define AMn am0
+ #define AnREG a0reg
+ #define AnIXREG a0ixreg
+ #define AnIXSIZ a0ixsiz
+ #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
+ #define CHK_FOR_DISPn CheckForDisp0
+ #define AnBEXPR a0bexpr
+ #define AnBEXVAL a0bexval
+ #define AnBEXATTR a0bexattr
+ #define AnBZISE a0bsize
+ #define AnEXTEN a0extension
+ #define AMn_030 am0_030
+ #define IS_SUPPRESSEDn IS_SUPPRESSED0
+ #define CHECKODn CHECKOD0
+ #include "parmode.h"
+
+ // If caller wants only one mode, return just one (ignore comma);. If there
+ // is no second addressing mode (no comma), then return just one anyway.
+ nmodes = 1;
+
+ // it's a bitfield instruction--check the parameters inside the {} block
+ // for validity
+ if ((*tok == '{') && (check030bf() == ERROR))
+ return ERROR;
+
+ if ((acount == 0) || (*tok != ','))
+ return 1;
+
+ // Eat the comma
+ tok++;
+
+ // Parse second addressing mode
+ #define AnOK a1ok
+ #define AMn am1
+ #define AnREG a1reg
+ #define AnIXREG a1ixreg
+ #define AnIXSIZ a1ixsiz
+ #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
+ #define CHK_FOR_DISPn CheckForDisp1
+ #define AnBEXPR a1bexpr
+ #define AnBEXVAL a1bexval
+ #define AnBEXATTR a1bexattr
+ #define AnBZISE a1bsize
+ #define AnEXTEN a1extension
+ #define AMn_030 am1_030
+ #define IS_SUPPRESSEDn IS_SUPPRESSED1
+ #define CHECKODn CHECKOD1
+ #include "parmode.h"
+
+ // It's a bitfield instruction--check the parameters inside the {} block
+ // for validity
+ if ((*tok == '{') && (check030bf() == ERROR))
+ return ERROR;
+
+ // At this point, it is legal for 020+ to have a ':'. For example divu.l
+ // d0,d2:d3
+ if (*tok == ':')
+ {
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ // 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;
+ }
+ 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;
+ return 2;
+
+ // Error messages:
+badmode:
+ return error("addressing mode syntax");
+
+ //unmode:
+ //return error("unimplemented addressing mode");
}
//
int reglist(WORD * a_rmask)
{
- static WORD msktab[] = {
- 0x0001, 0x0002, 0x0004, 0x0008,
- 0x0010, 0x0020, 0x0040, 0x0080,
- 0x0100, 0x0200, 0x0400, 0x0800,
- 0x1000, 0x2000, 0x4000, 0x8000
- };
+ static WORD msktab[] = {
+ 0x0001, 0x0002, 0x0004, 0x0008,
+ 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800,
+ 0x1000, 0x2000, 0x4000, 0x8000
+ };
- WORD rmask = 0;
- int r, cnt;
+ WORD rmask = 0;
+ int r, cnt;
- for(;;)
- {
- if (*tok >= KW_D0 && *tok <= KW_A7)
- r = *tok++ & 15;
- else
- break;
+ for(;;)
+ {
+ if ((*tok >= KW_D0) && (*tok <= KW_A7))
+ r = *tok++ & 0x0F;
+ else
+ break;
- if (*tok == '-')
- {
- tok++;
+ if (*tok == '-')
+ {
+ tok++;
- if (*tok >= KW_D0 && *tok <= KW_A7)
- cnt = *tok++ & 15;
- else
- return error("register list syntax");
+ if ((*tok >= KW_D0) && (*tok <= KW_A7))
+ cnt = *tok++ & 0x0F;
+ else
+ return error("register list syntax");
- if (cnt < r)
- return error("register list order");
+ if (cnt < r)
+ return error("register list order");
- cnt -= r;
- }
- else
- cnt = 0;
+ cnt -= r;
+ }
+ else
+ cnt = 0;
- while (cnt-- >= 0)
- rmask |= msktab[r++];
+ while (cnt-- >= 0)
+ rmask |= msktab[r++];
- if (*tok != '/')
- break;
+ if (*tok != '/')
+ break;
- tok++;
- }
+ tok++;
+ }
- *a_rmask = rmask;
+ *a_rmask = rmask;
- return OK;
+ return OK;
}
+
//
// Parse FPU register list
//
int fpu_reglist_left(WORD * a_rmask)
{
- static WORD msktab_minus[] = {
- 0x0080, 0x0040, 0x0020, 0x0010,
- 0x0008, 0x0004, 0x0002, 0x0001
- };
+ static WORD msktab_minus[] = {
+ 0x0080, 0x0040, 0x0020, 0x0010,
+ 0x0008, 0x0004, 0x0002, 0x0001
+ };
- WORD rmask = 0;
- int r, cnt;
+ WORD rmask = 0;
+ int r, cnt;
- for(;;)
- {
- if (*tok >= KW_FP0 && *tok <= KW_FP7)
- r = *tok++ & 7;
- else
- break;
+ for(;;)
+ {
+ if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+ r = *tok++ & 0x07;
+ else
+ break;
- if (*tok == '-')
- {
- tok++;
+ if (*tok == '-')
+ {
+ tok++;
- if (*tok >= KW_FP0 && *tok <= KW_FP7)
- cnt = *tok++ & 7;
- else
- return error("register list syntax");
+ if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+ cnt = *tok++ & 0x07;
+ else
+ return error("register list syntax");
- if (cnt < r)
- return error("register list order");
+ if (cnt < r)
+ return error("register list order");
- cnt -= r;
- }
- else
- cnt = 0;
+ cnt -= r;
+ }
+ else
+ cnt = 0;
- while (cnt-- >= 0)
- rmask |= msktab_minus[r++];
+ while (cnt-- >= 0)
+ rmask |= msktab_minus[r++];
- if (*tok != '/')
- break;
+ if (*tok != '/')
+ break;
- tok++;
- }
+ tok++;
+ }
- *a_rmask = rmask;
+ *a_rmask = rmask;
- return OK;
+ return OK;
}
+
+
int fpu_reglist_right(WORD * a_rmask)
{
- static WORD msktab_plus[] = {
- 0x0001, 0x0002, 0x0004, 0x0008,
- 0x0010, 0x0020, 0x0040, 0x0080
- };
+ static WORD msktab_plus[] = {
+ 0x0001, 0x0002, 0x0004, 0x0008,
+ 0x0010, 0x0020, 0x0040, 0x0080
+ };
- WORD rmask = 0;
- int r, cnt;
+ WORD rmask = 0;
+ int r, cnt;
- for(;;)
- {
- if (*tok >= KW_FP0 && *tok <= KW_FP7)
- r = *tok++ & 7;
- else
- break;
+ for(;;)
+ {
+ if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+ r = *tok++ & 0x07;
+ else
+ break;
- if (*tok == '-')
- {
- tok++;
+ if (*tok == '-')
+ {
+ tok++;
- if (*tok >= KW_FP0 && *tok <= KW_FP7)
- cnt = *tok++ & 7;
- else
- return error("register list syntax");
+ if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+ cnt = *tok++ & 0x07;
+ else
+ return error("register list syntax");
- if (cnt < r)
- return error("register list order");
+ if (cnt < r)
+ return error("register list order");
- cnt -= r;
- }
- else
- cnt = 0;
+ cnt -= r;
+ }
+ else
+ cnt = 0;
- while (cnt-- >= 0)
- rmask |= msktab_plus[r++];
+ while (cnt-- >= 0)
+ rmask |= msktab_plus[r++];
- if (*tok != '/')
- break;
+ if (*tok != '/')
+ break;
- tok++;
- }
+ tok++;
+ }
- *a_rmask = rmask;
+ *a_rmask = rmask;
- return OK;
+ return OK;
}
+
//
// Check for bitfield instructions extra params
// These are 020+ instructions and have the following syntax:
// bfxxx <ea>{param1,param2}
// param1/2 are either data registers or immediate values
//
-
int check030bf(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);
-
- 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");
- bfparam1 = (bfparam1 << 6) | (0 << 11); //Do=0, offset=immediate - shift it to place
- tok++;
- }
- else if (*tok == SYMBOL)
- {
- if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
- return ERROR;
- bfparam1 = bf0exval;
- if (bfparam1 > 31 || bfparam1 < 0)
- return error("bfxxx offset: immediate value must be between 0 and 31");
- bfparam1 = (bfparam1 << 6) | (0 << 11); //Do=0, offset=immediate - shift it to place
- }
- else if (*tok >= KW_D0 && *tok <= KW_D7)
- {
- bfparam1 = ((*(int *)tok - 128) << 6) | (1 << 11); //Do=1, offset=data register - shift it to place
- tok++;
- }
- else
- return ERROR;
-
- if (*tok==':')
- tok++; //eat the ':'
-
- if (*tok == '}' && tok[1] == EOL)
- {
- tok++;
- return OK; //It is ok to have }, EOL here - it might be "fmove fpn,<ea> {dx}"
- }
-
-
- if (*tok == CONST)
- {
- tok++;
- bfparam2 = *(int *)tok;
- if (bfparam2 > 31 || bfparam2 < 0)
- return error("bfxxx width: immediate value must be between 0 and 31");
- bfparam2 = (bfparam2 << 0) | (0 << 5); //Do=0, offset=immediate - shift it to place
- tok++;
- }
- else if (*tok == SYMBOL)
- {
- if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
- return ERROR;
- bfparam2 = bf0exval;
- if (bfparam2 > 31 || bfparam2 < 0)
- return error("bfxxx width: immediate value must be between 0 and 31");
- bfparam2 = (bfparam2 << 0) | (0 << 5); //Do=0, offset=immediate - shift it to place
- }
- else if (*tok >= KW_D0 && *tok <= KW_D7)
- {
- bfparam2 = ((*(int *)tok - 128) << 0) | (1 << 5); //Do=1, offset=data register - shift it to place
- tok++;
- }
- else
- return ERROR;
-
- tok++; //eat the '}'
-
- return OK;
+ 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);
+
+ 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");
+
+ // Do=0, offset=immediate - shift it to place
+ bfparam1 = (bfparam1 << 6) | (0 << 11);
+ tok++;
+ }
+ else if (*tok == SYMBOL)
+ {
+ if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
+ return ERROR;
+
+ bfparam1 = bf0exval;
+
+ if ((bfparam1 > 31) || (bfparam1 < 0))
+ return error("bfxxx offset: immediate value must be between 0 and 31");
+
+ // Do=0, offset=immediate - shift it to place
+ bfparam1 = (bfparam1 << 6) | (0 << 11);
+ }
+ else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ {
+ // Do=1, offset=data register - shift it to place
+ bfparam1 = ((*(int *)tok - 128) << 6) | (1 << 11);
+ tok++;
+ }
+ else
+ return ERROR;
+
+ if (*tok==':')
+ tok++; //eat the ':'
+
+ if (*tok == '}' && tok[1] == EOL)
+ {
+ // It is ok to have }, EOL here - it might be "fmove fpn,<ea> {dx}"
+ tok++;
+ return OK;
+ }
+
+ if (*tok == CONST)
+ {
+ tok++;
+ bfparam2 = *(int *)tok;
+
+ if (bfparam2 > 31 || bfparam2 < 0)
+ return error("bfxxx width: immediate value must be between 0 and 31");
+
+ // Do=0, offset=immediate - shift it to place
+ bfparam2 = (bfparam2 << 0) | (0 << 5);
+ tok++;
+ }
+ else if (*tok == SYMBOL)
+ {
+ if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
+ return ERROR;
+
+ bfparam2 = bf0exval;
+
+ if (bfparam2 > 31 || bfparam2 < 0)
+ return error("bfxxx width: immediate value must be between 0 and 31");
+
+ // Do=0, offset=immediate - shift it to place
+ bfparam2 = (bfparam2 << 0) | (0 << 5);
+ }
+ else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ {
+ // Do=1, offset=data register - shift it to place
+ bfparam2 = ((*(int *)tok - 128) << 0) | (1 << 5);
+ tok++;
+ }
+ else
+ return ERROR;
+
+ tok++; // Eat the '}'
+
+ return OK;
}
+
#include "rmac.h"
// 68000 and 68020 addressing modes
-#define DREG 000 // Dn
-#define AREG 010 // An
-#define AIND 020 // (An)
-#define APOSTINC 030 // (An)+
-#define APREDEC 040 // -(An)
-#define ADISP 050 // (d16,An) d16(An)
-#define AINDEXED 060 // (d8,An,Xn) d8(An,Xn)
-#define ABSW 070 // xxx.W
-#define ABSL 071 // xxx or xxx.L
-#define PCDISP 072 // (d16,PC) d16(PC)
-#define PCINDEXED 073 // (d16,PC,Xn) d16(PC,Xn)
-#define IMMED 074 // #data
-#define ABASE 0100 // (bd,An,Xn)
-#define MEMPOST 0101 // ([bd,An],Xn,od)
-#define MEMPRE 0102 // ([bc,An,Xn],od)
-#define PCBASE 0103 // (bd,PC,Xn)
-#define PCMPOST 0104 // ([bd,PC],Xn,od)
-#define PCMPRE 0105 // ([bc,PC,Xn],od)
+#define DREG 000 // Dn
+#define AREG 010 // An
+#define AIND 020 // (An)
+#define APOSTINC 030 // (An)+
+#define APREDEC 040 // -(An)
+#define ADISP 050 // (d16,An) d16(An)
+#define AINDEXED 060 // (d8,An,Xn) d8(An,Xn)
+#define ABSW 070 // xxx.W
+#define ABSL 071 // xxx or xxx.L
+#define PCDISP 072 // (d16,PC) d16(PC)
+#define PCINDEXED 073 // (d16,PC,Xn) d16(PC,Xn)
+#define IMMED 074 // #data
+#define ABASE 0100 // (bd,An,Xn)
+#define MEMPOST 0101 // ([bd,An],Xn,od)
+#define MEMPRE 0102 // ([bc,An,Xn],od)
+#define PCBASE 0103 // (bd,PC,Xn)
+#define PCMPOST 0104 // ([bd,PC],Xn,od)
+#define PCMPRE 0105 // ([bc,PC,Xn],od)
#define AM_USP 0106
#define AM_SR 0107
#define AM_CCR 0110
-#define AM_NONE 0111 // Nothing
-#define CACHES 0120 // Instruction/Data/Both Caches (IC/DC/BC)
-#define CREG 0121 // Control registers (see CREGlut in mach.h)
-#define FREG 0122 // FPU registers (fp0-fp7)
-#define FPSCR 0123 // FPU system control registers (fpiar, fpsr, fpcr)
+#define AM_NONE 0111 // Nothing
+#define CACHES 0120 // Instruction/Data/Both Caches (IC/DC/BC)
+#define CREG 0121 // Control registers (see CREGlut in mach.h)
+#define FREG 0122 // FPU registers (fp0-fp7)
+#define FPSCR 0123 // FPU system control registers (fpiar, fpsr, fpcr)
// Addressing-mode masks
-#define M_DREG 0x00000001L // Dn
-#define M_AREG 0x00000002L // An
-#define M_AIND 0x00000004L // (An)
-#define M_APOSTINC 0x00000008L // (An)+
-#define M_APREDEC 0x00000010L // -(An)
-#define M_ADISP 0x00000020L // (d16,An) d16(An)
-#define M_AINDEXED 0x00000040L // (d8,An,Xn) d8(An,Xn)
-#define M_ABSW 0x00000080L // xxx.W
-#define M_ABSL 0x00000100L // xxx or xxx.L
-#define M_PCDISP 0x00000200L // (d16,PC) d16(PC)
-#define M_PCINDEXED 0x00000400L // (d16,PC,Xn) d16(PC,Xn)
-#define M_IMMED 0x00000800L // #data
-#define M_ABASE 0x00001000L // (bd,An,Xn)
-#define M_MEMPOST 0x00002000L // ([bd,An],Xn,od)
-#define M_MEMPRE 0x00004000L // ([bd,An,Xn],od)
-#define M_PCBASE 0x00008000L // (bd,PC,Xn)
-#define M_PCMPOST 0x00010000L // ([bd,PC],Xn,od)
-#define M_PCMPRE 0x00020000L // ([bc,PC,Xn],od)
-#define M_AM_USP 0x00040000L // USP
-#define M_AM_SR 0x00080000L // SR
-#define M_AM_CCR 0x00100000L // CCR
-#define M_AM_NONE 0x00200000L // (nothing)
-#define M_BITFLD 0x00400000L // 68020 bitfield
-#define M_CREG 0x00800000L // Control registers
-#define M_FREG 0x01000000L // FPn
-#define M_FPSCR 0x02000000L // fpiar, fpsr, fpcr
+#define M_DREG 0x00000001L // Dn
+#define M_AREG 0x00000002L // An
+#define M_AIND 0x00000004L // (An)
+#define M_APOSTINC 0x00000008L // (An)+
+#define M_APREDEC 0x00000010L // -(An)
+#define M_ADISP 0x00000020L // (d16,An) d16(An)
+#define M_AINDEXED 0x00000040L // (d8,An,Xn) d8(An,Xn)
+#define M_ABSW 0x00000080L // xxx.W
+#define M_ABSL 0x00000100L // xxx or xxx.L
+#define M_PCDISP 0x00000200L // (d16,PC) d16(PC)
+#define M_PCINDEXED 0x00000400L // (d16,PC,Xn) d16(PC,Xn)
+#define M_IMMED 0x00000800L // #data
+#define M_ABASE 0x00001000L // (bd,An,Xn)
+#define M_MEMPOST 0x00002000L // ([bd,An],Xn,od)
+#define M_MEMPRE 0x00004000L // ([bd,An,Xn],od)
+#define M_PCBASE 0x00008000L // (bd,PC,Xn)
+#define M_PCMPOST 0x00010000L // ([bd,PC],Xn,od)
+#define M_PCMPRE 0x00020000L // ([bc,PC,Xn],od)
+#define M_AM_USP 0x00040000L // USP
+#define M_AM_SR 0x00080000L // SR
+#define M_AM_CCR 0x00100000L // CCR
+#define M_AM_NONE 0x00200000L // (nothing)
+#define M_BITFLD 0x00400000L // 68020 bitfield
+#define M_CREG 0x00800000L // Control registers
+#define M_FREG 0x01000000L // FPn
+#define M_FPSCR 0x02000000L // fpiar, fpsr, fpcr
// Addr mode categories
#define C_ALL 0x00000FFFL
#define C_ALL030 0x0003FFFFL
#define C_CTRL030 0x0003F7E4L
#define C_DATA030 0x0003FFFDL
-#define C_MOVES (M_AIND|M_APOSTINC|M_APREDEC|M_ADISP|M_AINDEXED|M_ABSW|M_ABSL|M_ABASE|M_MEMPRE|M_MEMPOST)
+#define C_MOVES (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPRE | M_MEMPOST)
-#define C_ALTDATA (C_DATA&C_ALT)
-#define C_ALTMEM (C_MEM&C_ALT)
-#define C_ALTCTRL (C_CTRL&C_ALT)
-#define C_LABEL (M_ABSW|M_ABSL)
+#define C_ALTDATA (C_DATA & C_ALT)
+#define C_ALTMEM (C_MEM & C_ALT)
+#define C_ALTCTRL (C_CTRL & C_ALT)
+#define C_LABEL (M_ABSW | M_ABSL)
#define C_NONE M_AM_NONE
-#define C_CREG (M_AM_USP|M_CREG)
+#define C_CREG (M_AM_USP | M_CREG)
// Scales
-#define TIMES1 00000 // (empty or *1)
-#define TIMES2 01000 // *2
-#define TIMES4 02000 // *4
-#define TIMES8 03000 // *8
+#define TIMES1 00000 // (empty or *1)
+#define TIMES2 01000 // *2
+#define TIMES4 02000 // *4
+#define TIMES8 03000 // *8
-#define M_FC (M_IMMED|M_DREG|M_CREG)
-#define M_MRN (M_DREG|M_AREG|M_CREG)
+#define M_FC (M_IMMED | M_DREG | M_CREG)
+#define M_MRN (M_DREG | M_AREG | M_CREG)
-//EA extension word
+// EA extension word
#define EXT_D 0x0000 // Dn
#define EXT_A 0x8000 // An
#define EXT_W 0x0000 // Index Size Sign-Extended Word
#define EXT_L 0x0800 // Index Size Long Word
-#define EXT_TIMES1 0x0000 // Scale factor 1
-#define EXT_TIMES2 0x0200 // Scale factor 2
-#define EXT_TIMES4 0x0400 // Scale factor 4
-#define EXT_TIMES8 0x0600 // Scale factor 8
+#define EXT_TIMES1 0x0000 // Scale factor 1
+#define EXT_TIMES2 0x0200 // Scale factor 2
+#define EXT_TIMES4 0x0400 // Scale factor 4
+#define EXT_TIMES8 0x0600 // Scale factor 8
#define EXT_FULLWORD 0x0100 // Use full extension word format
#define EXT_BS 0x0080 // Base Register Suppressed
#define EXT_IS 0x0040 // Index Operand Suppressed
#define EXT_BDSIZE0 0x0010 // Base Displacement Size Null (Suppressed)
#define EXT_BDSIZEW 0x0020 // Base Displacement Size Word
#define EXT_BDSIZEL 0x0030 // Base Displacement Size Long
-#define EXT_IISPRE0 0x0000 // Indirect and Indexing Operand - No Memory Indirect Action
-#define EXT_IISPREN 0x0001 // Indirect and Indexing Operand - Indirect Preindexed with Null Outer Displacement
-#define EXT_IISPREW 0x0002 // Indirect and Indexing Operand - Indirect Preindexed with Word Outer Displacement
-#define EXT_IISPREL 0x0003 // Indirect and Indexing Operand - Indirect Preindexed with Long Outer Displacement
-#define EXT_IISPOSN 0x0005 // Indirect and Indexing Operand - Indirect Postindexed with Null Outer Displacement
-#define EXT_IISPOSW 0x0006 // Indirect and Indexing Operand - Indirect Postindexed with Word Outer Displacement
-#define EXT_IISPOSL 0x0007 // Indirect and Indexing Operand - Indirect Postindexed with Long Outer Displacement
-#define EXT_IISNOI0 0x0000 // Indirect and Indexing Operand - No Memory Indirect Action
-#define EXT_IISNOIN 0x0001 // Indirect and Indexing Operand - Memory Indirect with Null Outer Displacement
-#define EXT_IISNOIW 0x0002 // Indirect and Indexing Operand - Memory Indirect with Word Outer Displacement
-#define EXT_IISNOIL 0x0003 // Indirect and Indexing Operand - Memory Indirect with Long Outer Displacement
-
-#define EXPRSIZE 128 // Maximum #tokens in an expression
+
+// Indirect and Indexing Operands
+#define EXT_IISPRE0 0x0000 // No Memory Indirect Action
+#define EXT_IISPREN 0x0001 // Indirect Preindexed with Null Outer Displacement
+#define EXT_IISPREW 0x0002 // Indirect Preindexed with Word Outer Displacement
+#define EXT_IISPREL 0x0003 // Indirect Preindexed with Long Outer Displacement
+#define EXT_IISPOSN 0x0005 // Indirect Postindexed with Null Outer Displacement
+#define EXT_IISPOSW 0x0006 // Indirect Postindexed with Word Outer Displacement
+#define EXT_IISPOSL 0x0007 // Indirect Postindexed with Long Outer Displacement
+#define EXT_IISNOI0 0x0000 // No Memory Indirect Action
+#define EXT_IISNOIN 0x0001 // Memory Indirect with Null Outer Displacement
+#define EXT_IISNOIW 0x0002 // Memory Indirect with Word Outer Displacement
+#define EXT_IISNOIL 0x0003 // Memory Indirect with Long Outer Displacement
+
+#define EXPRSIZE 128 // Maximum #tokens in an expression
// Addressing mode variables, output of amode()
extern int nmodes;
extern WORD a0bsize, a1bsize;
extern TOKEN a0bexpr[], a1bexpr[];
extern WORD a0extension, a1extension;
-
-// Mnemonic table structure
-#define MNTAB struct _mntab
-MNTAB {
- WORD mnattr; // Attributes (CGSPECIAL, SIZN, ...)
- LONG mn0, mn1; // Addressing modes
- WORD mninst; // Instruction mask
- WORD mncont; // Continuation (or -1)
- int (*mnfunc)(WORD, WORD); // Mnemonic builder
-};
+extern WORD mulmode;
+extern int bfparam1;
+extern int bfparam2;
+extern VALUE bf0exval;
// mnattr:
-#define CGSPECIAL 0x8000 // Special (don't parse addr modes)
+#define CGSPECIAL 0x8000 // Special (don't parse addr modes)
// Exported functions
int amode(int);
int reglist(WORD *);
int fpu_reglist_left(WORD *);
int fpu_reglist_right(WORD *);
-#endif // __AMODE_H__
+
+#endif // __AMODE_H__
#include "direct.h"
#include "6502.h"
+#include "amode.h"
#include "error.h"
#include "expr.h"
#include "listing.h"
// Function prototypes
int d_unimpl(void);
int d_68000(void);
+int d_68000(void);
+int d_68020(void);
+int d_68030(void);
+int d_68040(void);
+int d_68060(void);
+int d_68881(void);
+int d_68882(void);
+int d_56001(void);
+int d_nofpu(void);
int d_bss(void);
int d_data(void);
int d_text(void);
orgwarning = 0;
SaveSection();
SwitchSection(TEXT);
- activecpu=CPU_68000;
+ activecpu = CPU_68000;
return 0;
}
+
//
// .68020 - Back to 68000 TEXT segment and select 68020
//
int d_68020(void)
{
d_68000();
- activecpu=CPU_68020;
+ activecpu = CPU_68020;
return 0;
}
+
//
// .68030 - Back to 68000 TEXT segment and select 68030
//
int d_68030(void)
{
d_68000();
- activecpu=CPU_68030;
+ activecpu = CPU_68030;
return 0;
}
+
//
// .68040 - Back to 68000 TEXT segment and select 68040
//
int d_68040(void)
{
d_68000();
- activecpu=CPU_68040;
- activefpu=FPU_68040;
+ activecpu = CPU_68040;
+ activefpu = FPU_68040;
return 0;
}
+
//
// .68060 - Back to 68000 TEXT segment and select 68060
//
int d_68060(void)
{
d_68000();
- activecpu=CPU_68060;
- activefpu=FPU_68040;
+ activecpu = CPU_68060;
+ activefpu = FPU_68040;
return 0;
}
+
//
// .68881 - Back to 68000 TEXT segment and select 68881 FPU
//
int d_68881(void)
{
d_68000();
- activefpu=FPU_68881;
+ activefpu = FPU_68881;
return 0;
}
+
//
// .68882 - Back to 68000 TEXT segment and select 68882 FPU
//
int d_68882(void)
{
d_68000();
- activefpu=FPU_68881;
+ activefpu = FPU_68881;
return 0;
}
+
//
// nofpu - Deselect FPUs.
//
int d_nofpu(void)
{
- activefpu=FPU_NONE;
+ activefpu = FPU_NONE;
return 0;
}
+
//
// DSP56001
//
return error("Not yet, child. Be patient.");
}
+
//
// .gpu - Switch to GPU assembler
//
int symlist(int(*)());
int d_even(void);
-int d_6502(void);
-int d_68000(void);
-int d_68020(void);
-int d_68030(void);
-int d_68040(void);
-int d_68060(void);
-int d_68881(void);
-int d_68882(void);
-int d_56001(void);
-int d_nofpu(void);
-int d_bss(void);
-int d_data(void);
-int d_text(void);
-int d_abs(void);
-int d_comm(void);
-int d_dc(WORD);
-int d_ds(WORD);
-int d_dcb(WORD);
-int d_globl(void);
-int d_gpu(void);
-int d_dsp(void);
-int d_assert(void);
-int d_if(void);
-int d_endif(void);
-int d_include(void);
-int ExitMacro(void);
-int d_list(void);
-int d_nlist(void);
-int d_title(void);
-int d_subttl(void);
-int eject(void);
-int d_error(char *);
-int d_warn(char *);
-int d_org(void);
-int d_init(WORD);
-int d_cargs(void);
-int d_undmac(void);
-int d_regbank0(void);
-int d_regbank1(void);
int d_long(void);
int d_phrase(void);
int d_dphrase(void);
int d_qphrase(void);
-int d_incbin(void);
-int d_noclear(void);
-int d_equrundef(void);
-int d_ccundef(void);
-int d_print(void);
-int d_gpumain(void);
-int d_jpad(void);
-int d_nojpad(void);
-int d_fail(void);
-int symlist(int(*)());
-int abs_expr(VALUE *);
-int d_cstruct(void);
-int d_prgflags(void);
-int d_opt(void);
#endif // __DIRECT_H__
VALUE vbd, v = aNexval;
WORD wbd, w = (WORD)(aNexattr & DEFINED);
WORD tdbbd, tdb = (WORD)(aNexattr & TDB);
- vbd = aNbdexval;
- wbd = (WORD)(aNbdexattr & DEFINED);
- tdbbd = (WORD)(aNbdexattr & TDB);
+ vbd = aNbdexval;
+ wbd = (WORD)(aNbdexattr & DEFINED);
+ tdbbd = (WORD)(aNbdexattr & TDB);
switch (amN)
{
break;
case SIZP:
- // 68881/68882/68040 only
- return error("Sorry, .p constant format is not implemented yet!");
- break;
+ // 68881/68882/68040 only
+ return error("Sorry, .p constant format is not implemented yet!");
+ break;
case ABSW:
if (w) // Defined
{
// Deposit word bd
if (wbd)
{
- // Just deposit it
+ // Just deposit it
if (tdb)
MarkRelocatable(cursect, sloc, tdbbd, MWORD, NULL);
}
else
{
- // Arrange for fixup later on
+ // Arrange for fixup later on
AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
D_word(0);
}
// Deposit long bd
if (wbd)
{
- // Just deposit it
+ // Just deposit it
if (tdbbd)
MarkRelocatable(cursect, sloc, tdbbd, MLONG, NULL);
}
else
{
- // Arrange for fixup later on
+ // Arrange for fixup later on
AddFixup(FU_LONG|FU_SEXT, sloc, aNexpr);
D_long(0);
}
}
// Deposit od (if not suppressed)
- if ((aNexten&7)==EXT_IISPRE0 || (aNexten&7)==EXT_IISPREN
+ if ((aNexten&7)==EXT_IISPRE0 || (aNexten&7)==EXT_IISPREN
|| (aNexten&7)==EXT_IISNOIN || (aNexten&7)==EXT_IISPOSN)
{
// Don't deposit anything (suppressed)
// Deposit word od
if (w)
{
- // Just deposit it
+ // Just deposit it
if (tdb)
MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
}
else
{
- // Arrange for fixup later on
+ // Arrange for fixup later on
AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
D_word(0);
}
// Deposit long od
if (w)
{
- // Just deposit it
+ // Just deposit it
if (tdb)
MarkRelocatable(cursect, sloc, tdb, MLONG, NULL);
}
else
{
- // Arrange for fixup later on
+ // Arrange for fixup later on
AddFixup(FU_LONG|FU_SEXT, sloc, aNexpr);
D_long(0);
}
#include "rmac.h"
-#define EBUFSIZ 256 // Max size of an error message
+#define EBUFSIZ 256 // Max size of an error message
// Exported variables
extern int errcnt;
int at_eol(void);
#endif // __ERROR_H__
+
// '*' takes attributes of current section, not ABS!
*evalTokenBuffer++ = cursect | DEFINED;
break;
- case '{':
- if (expr0() != OK) // Eat up first parameter (register or immediate)
+ case '{':
+ if (expr0() != OK) // Eat up first parameter (register or immediate)
return ERROR;
- if (*tok++ != ':') // Demand a ':' there
+ if (*tok++ != ':') // Demand a ':' there
return error("missing colon ':'");
-
- if (expr0() != OK) // Eat up second parameter (register or immediate)
+
+ if (expr0() != OK) // Eat up second parameter (register or immediate)
return ERROR;
-
+
if (*tok++ != '}')
return error("missing close bracket '}'");
// nnnnn =vvvvvvvv
#include "listing.h"
-#include "version.h"
-#include "token.h"
+#include "error.h"
#include "procln.h"
#include "sect.h"
-#include "error.h"
+#include "token.h"
+#include "version.h"
char * list_fname; // Listing filename
uint8_t subttl[TITLESIZ]; // Current subtitle
//
void InitListing(void)
{
- extern VALUE dos_date(), dos_time();
-
subflag = 0;
pageno = 0;
nlines = 0;
//
#include "mach.h"
+#include "amode.h"
+#include "direct.h"
#include "eagen.h"
#include "error.h"
-#include "direct.h"
#include "procln.h"
#include "riscasm.h"
-#include "rmac.h"
+//#include "rmac.h"
#include "sect.h"
#include "token.h"
// Exported variables
int movep = 0; // Global flag to indicate we're generating a movep instruction
+// Function prototypes
+int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD);
+int m_self(WORD, WORD);
+int m_abcd(WORD, WORD);
+int m_reg(WORD, WORD);
+int m_imm(WORD, WORD);
+int m_imm8(WORD, WORD);
+int m_shi(WORD, WORD);
+int m_shr(WORD, WORD);
+int m_bitop(WORD, WORD);
+int m_exg(WORD, WORD);
+int m_ea(WORD, WORD);
+int m_lea(WORD, WORD);
+int m_br(WORD, WORD);
+int m_dbra(WORD, WORD);
+int m_link(WORD, WORD);
+int m_adda(WORD, WORD);
+int m_addq(WORD, WORD);
+//int m_move(WORD, int);
+int m_move(WORD, WORD);
+int m_moveq(WORD, WORD);
+int m_usp(WORD, WORD);
+int m_movep(WORD, WORD);
+int m_trap(WORD, WORD);
+int m_movem(WORD, WORD);
+int m_clra(WORD, WORD);
+
+int m_move30(WORD, WORD); //68020/30/40/60
+int m_br30(WORD inst, WORD siz);
+int m_ea030(WORD inst, WORD siz);
+int m_bfop(WORD inst, WORD siz);
+int m_callm(WORD inst, WORD siz);
+int m_cas(WORD inst, WORD siz);
+int m_cas2(WORD inst, WORD siz);
+int m_chk2(WORD inst, WORD siz);
+int m_cmp2(WORD inst, WORD siz);
+int m_bkpt(WORD inst, WORD siz);
+int m_cpbr(WORD inst, WORD siz);
+int m_cpdbr(WORD inst, WORD siz);
+int m_divs(WORD inst, WORD siz);
+int m_muls(WORD inst, WORD siz);
+int m_divu(WORD inst, WORD siz);
+int m_mulu(WORD inst, WORD siz);
+int m_divsl(WORD inst, WORD siz);
+int m_divul(WORD inst, WORD siz);
+int m_move16a(WORD inst, WORD siz);
+int m_move16b(WORD inst, WORD siz);
+int m_pack(WORD inst, WORD siz);
+int m_rtm(WORD inst, WORD siz);
+int m_rtd(WORD inst, WORD siz);
+int m_trapcc(WORD inst, WORD siz);
+int m_cinv(WORD inst, WORD siz);
+int m_cprest(WORD inst, WORD siz);
+int m_movec(WORD inst, WORD siz);
+int m_moves(WORD inst, WORD siz);
+
+// PMMU
+int m_pbcc(WORD inst, WORD siz);
+int m_pflusha(WORD inst, WORD siz);
+int m_pflush(WORD inst, WORD siz);
+int m_pflushr(WORD inst, WORD siz);
+int m_pload(WORD inst, WORD siz);
+int m_pmove(WORD inst, WORD siz);
+int m_pmovefd(WORD inst, WORD siz);
+int m_ptest(WORD inst, WORD siz);
+int m_ptrapbs(WORD inst, WORD siz);
+int m_ptrapbc(WORD inst, WORD siz);
+int m_ptrapls(WORD inst, WORD siz);
+int m_ptraplc(WORD inst, WORD siz);
+int m_ptrapss(WORD inst, WORD siz);
+int m_ptrapsc(WORD inst, WORD siz);
+int m_ptrapas(WORD inst, WORD siz);
+int m_ptrapac(WORD inst, WORD siz);
+int m_ptrapws(WORD inst, WORD siz);
+int m_ptrapwc(WORD inst, WORD siz);
+int m_ptrapis(WORD inst, WORD siz);
+int m_ptrapic(WORD inst, WORD siz);
+int m_ptrapgc(WORD inst, WORD siz);
+int m_ptrapgs(WORD inst, WORD siz);
+int m_ptrapcs(WORD inst, WORD siz);
+int m_ptrapcc(WORD inst, WORD siz);
+int m_ptrapbsn(WORD inst, WORD siz);
+int m_ptrapbcn(WORD inst, WORD siz);
+int m_ptraplsn(WORD inst, WORD siz);
+int m_ptraplcn(WORD inst, WORD siz);
+int m_ptrapssn(WORD inst, WORD siz);
+int m_ptrapscn(WORD inst, WORD siz);
+int m_ptrapasn(WORD inst, WORD siz);
+int m_ptrapacn(WORD inst, WORD siz);
+int m_ptrapwsn(WORD inst, WORD siz);
+int m_ptrapwcn(WORD inst, WORD siz);
+int m_ptrapisn(WORD inst, WORD siz);
+int m_ptrapicn(WORD inst, WORD siz);
+int m_ptrapgsn(WORD inst, WORD siz);
+int m_ptrapgcn(WORD inst, WORD siz);
+int m_ptrapcsn(WORD inst, WORD siz);
+int m_ptrapccn(WORD inst, WORD siz);
+
+//FPU
+int m_fabs(WORD inst, WORD siz);
+int m_facos(WORD inst, WORD siz);
+int m_fadd(WORD inst, WORD siz);
+int m_fasin(WORD inst, WORD siz);
+int m_fatan(WORD inst, WORD siz);
+int m_fatanh(WORD inst, WORD siz);
+int m_fcmp(WORD inst, WORD siz);
+int m_fcos(WORD inst, WORD siz);
+int m_fcosh(WORD inst, WORD siz);
+int m_fdabs(WORD inst, WORD siz);
+int m_fdadd(WORD inst, WORD siz);
+int m_fdbcc(WORD inst, WORD siz);
+int m_fddiv(WORD inst, WORD siz);
+int m_fdfsqrt(WORD inst, WORD siz);
+int m_fdiv(WORD inst, WORD siz);
+int m_fdmove(WORD inst, WORD siz);
+int m_fdmul(WORD inst, WORD siz);
+int m_fdneg(WORD inst, WORD siz);
+int m_fdsub(WORD inst, WORD siz);
+int m_fetox(WORD inst, WORD siz);
+int m_fetoxm1(WORD inst, WORD siz);
+int m_fgetexp(WORD inst, WORD siz);
+int m_fgetman(WORD inst, WORD siz);
+int m_fint(WORD inst, WORD siz);
+int m_fintrz(WORD inst, WORD siz);
+int m_flog10(WORD inst, WORD siz);
+int m_flog2(WORD inst, WORD siz);
+int m_flogn(WORD inst, WORD siz);
+int m_flognp1(WORD inst, WORD siz);
+int m_fmod(WORD inst, WORD siz);
+int m_fmove(WORD inst, WORD siz);
+int m_fmovescr(WORD inst, WORD siz);
+int m_fmovecr(WORD inst, WORD siz);
+int m_fmovem(WORD inst, WORD siz);
+int m_fmul(WORD inst, WORD siz);
+int m_fneg(WORD inst, WORD siz);
+int m_fnop(WORD inst, WORD siz);
+int m_frem(WORD inst, WORD siz);
+int m_fsabs(WORD inst, WORD siz);
+int m_fsadd(WORD inst, WORD siz);
+int m_fseq(WORD inst, WORD siz);
+int m_fsne(WORD inst, WORD siz);
+int m_fsgt(WORD inst, WORD siz);
+int m_fsngt(WORD inst, WORD siz);
+int m_fsge(WORD inst, WORD siz);
+int m_fsnge(WORD inst, WORD siz);
+int m_fslt(WORD inst, WORD siz);
+int m_fsnlt(WORD inst, WORD siz);
+int m_fsle(WORD inst, WORD siz);
+int m_fsnle(WORD inst, WORD siz);
+int m_fsgl(WORD inst, WORD siz);
+int m_fsngl(WORD inst, WORD siz);
+int m_fsgle(WORD inst, WORD siz);
+int m_fsngle(WORD inst, WORD siz);
+int m_fsogt(WORD inst, WORD siz);
+int m_fsule(WORD inst, WORD siz);
+int m_fsoge(WORD inst, WORD siz);
+int m_fsult(WORD inst, WORD siz);
+int m_fsolt(WORD inst, WORD siz);
+int m_fsuge(WORD inst, WORD siz);
+int m_fsole(WORD inst, WORD siz);
+int m_fsugt(WORD inst, WORD siz);
+int m_fsogl(WORD inst, WORD siz);
+int m_fsueq(WORD inst, WORD siz);
+int m_fsor(WORD inst, WORD siz);
+int m_fsun(WORD inst, WORD siz);
+int m_fsf(WORD inst, WORD siz);
+int m_fst(WORD inst, WORD siz);
+int m_fssf(WORD inst, WORD siz);
+int m_fsst(WORD inst, WORD siz);
+int m_fsseq(WORD inst, WORD siz);
+int m_fssne(WORD inst, WORD siz);
+int m_fscale(WORD inst, WORD siz);
+int m_fsdiv(WORD inst, WORD siz);
+int m_fsfsqrt(WORD inst, WORD siz);
+int m_fsfsub(WORD inst, WORD siz);
+int m_fsgldiv(WORD inst, WORD siz);
+int m_fsglmul(WORD inst, WORD siz);
+int m_fsin(WORD inst, WORD siz);
+int m_fsincos(WORD inst, WORD siz);
+int m_fsinh(WORD inst, WORD siz);
+int m_fsmove(WORD inst, WORD siz);
+int m_fsmul(WORD inst, WORD siz);
+int m_fsneg(WORD inst, WORD siz);
+int m_fsqrt(WORD inst, WORD siz);
+int m_fsub(WORD inst, WORD siz);
+int m_ftan(WORD inst, WORD siz);
+int m_ftanh(WORD inst, WORD siz);
+int m_ftentox(WORD inst, WORD siz);
+int m_ftst(WORD inst, WORD siz);
+int m_ftwotox(WORD inst, WORD siz);
+int m_ftrapeq(WORD inst, WORD siz);
+int m_ftrapne(WORD inst, WORD siz);
+int m_ftrapgt(WORD inst, WORD siz);
+int m_ftrapngt(WORD inst, WORD siz);
+int m_ftrapge(WORD inst, WORD siz);
+int m_ftrapnge(WORD inst, WORD siz);
+int m_ftraplt(WORD inst, WORD siz);
+int m_ftrapnlt(WORD inst, WORD siz);
+int m_ftraple(WORD inst, WORD siz);
+int m_ftrapnle(WORD inst, WORD siz);
+int m_ftrapgl(WORD inst, WORD siz);
+int m_ftrapngl(WORD inst, WORD siz);
+int m_ftrapgle(WORD inst, WORD siz);
+int m_ftrapngle(WORD inst, WORD siz);
+int m_ftrapogt(WORD inst, WORD siz);
+int m_ftrapule(WORD inst, WORD siz);
+int m_ftrapoge(WORD inst, WORD siz);
+int m_ftrapult(WORD inst, WORD siz);
+int m_ftrapolt(WORD inst, WORD siz);
+int m_ftrapuge(WORD inst, WORD siz);
+int m_ftrapole(WORD inst, WORD siz);
+int m_ftrapugt(WORD inst, WORD siz);
+int m_ftrapogl(WORD inst, WORD siz);
+int m_ftrapueq(WORD inst, WORD siz);
+int m_ftrapor(WORD inst, WORD siz);
+int m_ftrapun(WORD inst, WORD siz);
+int m_ftrapf(WORD inst, WORD siz);
+int m_ftrapt(WORD inst, WORD siz);
+int m_ftrapsf(WORD inst, WORD siz);
+int m_ftrapst(WORD inst, WORD siz);
+int m_ftrapseq(WORD inst, WORD siz);
+int m_ftrapsne(WORD inst, WORD siz);
+int m_ftrapeqn(WORD inst, WORD siz);
+int m_ftrapnen(WORD inst, WORD siz);
+int m_ftrapgtn(WORD inst, WORD siz);
+int m_ftrapngtn(WORD inst, WORD siz);
+int m_ftrapgen(WORD inst, WORD siz);
+int m_ftrapngen(WORD inst, WORD siz);
+int m_ftrapltn(WORD inst, WORD siz);
+int m_ftrapnltn(WORD inst, WORD siz);
+int m_ftraplen(WORD inst, WORD siz);
+int m_ftrapnlen(WORD inst, WORD siz);
+int m_ftrapgln(WORD inst, WORD siz);
+int m_ftrapngln(WORD inst, WORD siz);
+int m_ftrapglen(WORD inst, WORD siz);
+int m_ftrapnglen(WORD inst, WORD siz);
+int m_ftrapogtn(WORD inst, WORD siz);
+int m_ftrapulen(WORD inst, WORD siz);
+int m_ftrapogen(WORD inst, WORD siz);
+int m_ftrapultn(WORD inst, WORD siz);
+int m_ftrapoltn(WORD inst, WORD siz);
+int m_ftrapugen(WORD inst, WORD siz);
+int m_ftrapolen(WORD inst, WORD siz);
+int m_ftrapugtn(WORD inst, WORD siz);
+int m_ftrapogln(WORD inst, WORD siz);
+int m_ftrapueqn(WORD inst, WORD siz);
+int m_ftraporn(WORD inst, WORD siz);
+int m_ftrapunn(WORD inst, WORD siz);
+int m_ftrapfn(WORD inst, WORD siz);
+int m_ftraptn(WORD inst, WORD siz);
+int m_ftrapsfn(WORD inst, WORD siz);
+int m_ftrapstn(WORD inst, WORD siz);
+int m_ftrapseqn(WORD inst, WORD siz);
+int m_ftrapsnen(WORD inst, WORD siz);
+
// Common error messages
char range_error[] = "expression out of range";
char abs_error[] = "illegal absolute expression";
char fwd_error[] = "forward or undefined expression";
char unsupport[] = "unsupported for selected CPU";
-extern int ea0gen(WORD);
-extern int ea1gen(WORD);
-extern int mulmode;
-
// Include code tables
MNTAB machtab[] = {
-// { (WORD)-1, (unsigned long)-1L, (unsigned long)-1L, 0x0000, 0, m_badmode }, // 0
{ 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000, 0, m_badmode }, // 0
#include "68ktab.h"
{ 0, 0L, 0L, 0x0000, 0, m_unimp } // Last entry
// Byte/Word/long size (0=.w, 1=.l) in bit 9
WORD lwsiz_9[] = {
(WORD)-1,
- 0, // Byte
- 1<<9, (WORD)-1, // Word
+ 0, // Byte
+ 1<<9, (WORD)-1, // Word
1<<10, (WORD)-1, (WORD)-1, (WORD)-1, // Long
1<<9 // Word (SIZN)
};
0x006, // Data Access Control Register 0 (DACR1)
0x007, // Data Access Control Register 1 (DACR1)
// 68851 only
- 0xfff // CPU Root Pointer (CRP) - There's no movec with CRP in it, this is just a guard entry
+ 0xFFF // CPU Root Pointer (CRP) - There's no movec with CRP in it, this is just a guard entry
};
+
// Error messages
int m_unimp(WORD unused1, WORD unused2)
{
return OK;
}
+
//
-// Check if lea x(an),an can be optimised to
-// addq.w #x,an - otherwise fall back to m_ea.
+// Check if lea x(an),an can be optimised to addq.w #x,an--otherwise fall back
+// to m_ea.
//
int m_lea(WORD inst, WORD siz)
{
- if (optim_flags[OPT_LEA_ADDQ])
- if (am0==ADISP && a0reg==a1reg && (a0exattr & DEFINED))
- if (a0exval>0 && a0exval<=8)
- {
- inst=B16(01010000,01001000)|((a0exval&7)<<9)|(a0reg);
- D_word(inst);
- warn("lea size(An),An converted to addq #size,An");
- return OK;
- }
+ if (optim_flags[OPT_LEA_ADDQ]
+ && ((am0 == ADISP) && (a0reg == a1reg) && (a0exattr & DEFINED))
+ && ((a0exval > 0) && (a0exval <= 8)))
+ {
+ inst = B16(01010000, 01001000) | ((a0exval & 7) << 9) | (a0reg);
+ D_word(inst);
+ warn("lea size(An),An converted to addq #size,An");
+ return OK;
+ }
- return m_ea(inst,siz);
+ return m_ea(inst, siz);
}
+
int m_ea030(WORD inst, WORD siz)
{
- CHECK00;
-
- WORD flg = inst; // Save flag bits
- inst &= ~0x3F; // Clobber flag bits in instr
+ CHECK00;
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
- // Install "standard" instr size bits
+ // Install "standard" instr size bits
if (flg & 4)
inst |= siz_6[siz];
if (flg & 16)
{
- // OR-in register number
+ // OR-in register number
if (flg & 8)
{
- inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
}
else
{
- inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
}
}
if (flg & 1)
{
- // Use am1
- inst |= am1 | a1reg; // Get ea1 into instr
- D_word(inst); // Deposit instr
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
- // Generate ea0 if requested
+ // Generate ea0 if requested
if (flg & 2)
ea0gen(siz);
- ea1gen(siz); // Generate ea1
+ ea1gen(siz); // Generate ea1
}
else
{
- // Use am0
- //inst |= am0 | a0reg; // Get ea0 into instr
- if (am0 == AREG)
- //We get here if we're doing 020+ addressing and an address register is used.
- //For example, something like "tst a0". A bit of a corner case, so kludge it
- a0reg = a0reg + 8;
- else if (am0 == PCDISP)
- //Another corner case (possibly!), so kludge ahoy
- inst |= am0; // Get ea0 into instr
- else if (am0 == IMMED)
- inst |= am0 | a0reg; // Get ea0 into instr
- else if (am0 == AM_CCR)
- inst |= am1 | a1reg;
- else if (am0 == AIND)
- inst |= am0;
-
- inst |= a0reg; // Get ea0 into instr
- D_word(inst); // Deposit instr
- ea0gen(siz); // Generate ea0
-
- // Generate ea1 if requested
+ // Use am0
+ if (am0 == AREG)
+ // We get here if we're doing 020+ addressing and an address
+ // register is used. For example, something like "tst a0". A bit of
+ // a corner case, so kludge it
+ a0reg = a0reg + 8;
+ else if (am0 == PCDISP)
+ //Another corner case (possibly!), so kludge ahoy
+ inst |= am0; // Get ea0 into instr
+ else if (am0 == IMMED)
+ inst |= am0 | a0reg; // Get ea0 into instr
+ else if (am0 == AM_CCR)
+ inst |= am1 | a1reg;
+ else if (am0 == AIND)
+ inst |= am0;
+
+ inst |= a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
if (flg & 2)
ea1gen(siz);
}
//
int m_link(WORD inst, WORD siz)
{
- if (siz != SIZL)
- {
- }
- else
- {
- CHECK00;
- inst &= ~((3 << 9)|(1<<6)|(1<<4));
- inst |= 1 << 3;
- }
+ if (siz != SIZL)
+ {
+ // Is this an error condition???
+ }
+ else
+ {
+ CHECK00;
+ inst &= ~((3 << 9) | (1 << 6) | (1 << 4));
+ inst |= 1 << 3;
+ }
+
inst |= a0reg;
D_word(inst);
ea1gen(siz);
return OK;
}
+
WORD extra_addressing[16]=
{
0, //0100 (bd,An,Xn)
0, //0115
0, //0116
0 //0117
-
};
+
//
// Handle MOVE <C_ALL> <C_ALTDATA>
// MOVE <C_ALL> <M_AREG>
int siz = (int)size;
// Try to optimize to MOVEQ
- if (optim_flags[OPT_MOVEL_MOVEQ] && siz == SIZL && am0 == IMMED && am1 == DREG
- && (a0exattr & (TDB|DEFINED)) == DEFINED && a0exval + 0x80 < 0x100)
+ if (optim_flags[OPT_MOVEL_MOVEQ]
+ && (siz == SIZL) && (am0 == IMMED) && (am1 == DREG)
+ && ((a0exattr & (TDB | DEFINED)) == DEFINED)
+ && (a0exval + 0x80 < 0x100))
{
m_moveq((WORD)0x7000, (WORD)0);
}
else
{
- if (am0<ABASE && am1<ABASE) //68000 modes
+ if ((am0 < ABASE) && (am1 < ABASE)) //68000 modes
{
- inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
+ inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
- D_word(inst);
+ D_word(inst);
- if (am0 >= ADISP)
- ea0gen((WORD)siz);
+ if (am0 >= ADISP)
+ ea0gen((WORD)siz);
- if (am1 >= ADISP)
- ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea
- }
+ if (am1 >= ADISP)
+ ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea
+ }
else //68020+ modes
{
- inst |= siz_12[siz] | reg_9[a1reg] | extra_addressing[am0-ABASE];
+ inst |= siz_12[siz] | reg_9[a1reg] | extra_addressing[am0 - ABASE];
D_word(inst);
//
// Handle MOVE <C_ALL030> <C_ALTDATA>
// MOVE <C_ALL030> <M_AREG>
-//
+//
int m_move30(WORD inst, WORD size)
{
// Cast the passed in value to an int
int siz = (int)size;
+ inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE];
- /*if (am0<ABASE && am1<ABASE) //68000 modes
- {
- inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
-
- D_word(inst);
-
- if (am0 >= ADISP)
- ea0gen((WORD)siz);
-
- if (am1 >= ADISP)
- | 0x8000); // Tell ea1gen we're move ea,ea
- }
- else //68020+ modes
- {*/
- inst |= siz_12[siz] | reg_9[a1reg&7] | a0reg | extra_addressing[am0-ABASE];
-
- D_word(inst);
+ D_word(inst);
- if (am0 >= ADISP)
- ea0gen((WORD)siz);
+ if (am0 >= ADISP)
+ ea0gen((WORD)siz);
- if (am1 >= ADISP)
- ea1gen((WORD)siz);
- /*}*/
+ if (am1 >= ADISP)
+ ea1gen((WORD)siz);
return OK;
}
return OK;
}
+
//
// movep Dn, disp(An) -- movep disp(An), Dn
//
int m_movep(WORD inst, WORD siz)
{
- movep = 1; // Tell ea0gen to lay off the 0(a0) optimisations on this one
+ // Tell ea0gen to lay off the 0(a0) optimisations on this one
+ movep = 1;
+
if (siz == SIZL)
inst |= 0x0040;
// Optimize branch instr. size
if (siz == SIZN)
{
- if (optim_flags[OPT_BSR_BCC_S] && v != 0 && v + 0x80 < 0x100)
+ if (optim_flags[OPT_BSR_BCC_S] && (v != 0) && ((v + 0x80) < 0x100))
{
// Fits in .B
inst |= v & 0xFF;
D_word(inst);
+
if (sbra_flag)
warn("Bcc.w/BSR.w converted to .s");
+
return OK;
}
else
{
// Fits in .W
- if (v + 0x8000 > 0x10000)
+ if ((v + 0x8000) > 0x10000)
return error(range_error);
D_word(inst);
if (siz == SIZB || siz == SIZS)
{
- if (v + 0x80 >= 0x100)
+ if ((v + 0x80) >= 0x100)
return error(range_error);
inst |= v & 0xFF;
}
else
{
- if (v + 0x8000 >= 0x10000)
+ if ((v + 0x8000) >= 0x10000)
return error(range_error);
D_word(inst);
if (a0exattr & DEFINED)
{
- if (a0exval > 8 || a0exval == 0) // Range in 1..8
+ if ((a0exval > 8) || (a0exval == 0)) // Range in 1..8
return error(range_error);
inst |= (a0exval & 7) << 9;
goto immed1;
}
- if (*tok >= KW_D0 && *tok <= KW_A7)
+ if ((*tok >= KW_D0) && (*tok <= KW_A7))
{
// <rlist>, ea
if (reglist(&rmask) < 0)
return OK;
}
+
////////////////////////////////////////
//
// 68020/30/40 instructions
//
int m_br30(WORD inst, WORD siz)
{
- VALUE v;
-
- if (a0exattr & DEFINED)
- {
- if ((a0exattr & TDB) != cursect)
- //{
- //printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
- return error(rel_error);
- //}
-
- v = a0exval - (sloc + 2);
+ if (a0exattr & DEFINED)
+ {
+ if ((a0exattr & TDB) != cursect)
+ return error(rel_error);
- D_word(inst);
- D_long(v);
+ VALUE v = a0exval - (sloc + 2);
+ D_word(inst);
+ D_long(v);
- return OK;
- }
- else
- {
- // .L
- AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
- D_word(inst);
- return OK;
- }
+ return OK;
+ }
+ else
+ {
+ // .L
+ AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
+ D_word(inst);
+ return OK;
+ }
}
+
//
// bfchg, bfclr, bfexts, bfextu, bfffo, bfins, bfset
// (68020, 68030, 68040)
//First instruction word - just the opcode and first EA
//Note: both am1 is ORed because solely of bfins - maybe it's a good idea to make a dedicated function for it?
- if (am1 == AM_NONE)
- am1 = 0;
+ if (am1 == AM_NONE)
+ am1 = 0;
+
D_word((inst|am0|a0reg|am1|a1reg));
- ea0gen(siz); // Generate EA
+ ea0gen(siz); // Generate EA
//Second instruction word - Dest register (if exists), Do, Offset, Dw, Width
inst = bfparam1 | bfparam2;
+
if (am1 == DREG)
inst |= a1reg << 12;
+
if (am0 == DREG)
inst |= a0reg << 12;
+
D_word(inst);
return OK;
}
+
//
// bkpt (68EC000, 68010, 68020, 68030, 68040, CPU32)
//
int m_bkpt(WORD inst, WORD siz)
{
- CHECK00;
+ CHECK00;
if (a0exattr & DEFINED)
{
inst |= a0exval;
D_word(inst);
}
- else
+ else
return error(undef_error);
return OK;
}
+
//
// callm (68020)
//
int m_callm(WORD inst, WORD siz)
{
- CHECKNO20;
+ CHECKNO20;
- inst |= am1;
+ inst |= am1;
D_word(inst);
if (a0exattr & DEFINED)
inst = a0exval;
D_word(inst);
}
- else
+ else
return error(undef_error);
ea1gen(siz);
}
+
//
// cas (68020, 68030, 68040)
//
int m_cas(WORD inst, WORD siz)
{
- WORD inst2;
- LONG amsk;
- int modes;
+ WORD inst2;
+ LONG amsk;
+ int modes;
+
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ switch (siz)
+ {
+ case SIZB:
+ inst |= 1 << 9;
+ break;
+ case SIZW:
+ case SIZN:
+ inst |= 2 << 9;
+ break;
+ case SIZL:
+ inst |= 3 << 9;
+ break;
+ default:
+ return error("bad size suffix");
+ break;
+ }
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
+ // Dc
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS accepts only data registers");
- switch (siz)
- {
- case SIZB:
- inst |= 1 << 9;
- break;
- case SIZW:
- case SIZN:
- inst |= 2 << 9;
- break;
- case SIZL:
- inst |= 3 << 9;
- break;
- default:
- return error("bad size suffix");
- break;
- }
+ inst2 = (*tok++) & 7;
- // Dc
- if ((*tok < KW_D0) && (*tok > KW_D7))
- return error("CAS accepts only data registers");
- inst2 = (*tok++) & 7;
+ if (*tok++ != ',')
+ return error("missing comma");
- if (*tok++ != ',')
- return error("missing comma");
+ // Du
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS accepts only data registers");
- // Du
- if ((*tok < KW_D0) && (*tok > KW_D7))
- return error("CAS accepts only data registers");
- inst2 |= ((*tok++) & 7)<<6;
+ inst2 |= ((*tok++) & 7) << 6;
- if (*tok++ != ',')
- return error("missing comma");
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ // ea
+ if ((modes = amode(1)) < 0)
+ return OK;
- // ea
- if ((modes=amode(1)) < 0)
- return OK;
+ if (modes > 1)
+ return error("too many ea fields");
- if (modes > 1)
- return error("too many ea fields");
+ if (*tok!=EOL)
+ return error("extra (unexpected) text found");
- if (*tok!=EOL)
- return error("extra (unexpected) text found");
+ // Reject invalud ea modes
+ amsk = amsktab[am0];
- // Reject invalud ea modes
- amsk = amsktab[am0];
- if (amsk&(M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE) == 0)
- return error("unsupported addressing mode");
+ if (amsk & (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE) == 0)
+ return error("unsupported addressing mode");
- inst |= am0 | a0reg;
- D_word(inst);
- D_word(inst2);
- ea0gen(siz);
+ inst |= am0 | a0reg;
+ D_word(inst);
+ D_word(inst2);
+ ea0gen(siz);
- return OK;
+ return OK;
}
+
//
// cas2 (68020, 68030, 68040)
//
int m_cas2(WORD inst, WORD siz)
{
- WORD inst2, inst3;
- LONG amsk;
-
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
-
- switch (siz)
- {
- case SIZB:
- inst |= 1 << 9;
- break;
- case SIZW:
- case SIZN:
- inst |= 2 << 9;
- break;
- case SIZL:
- inst |= 3 << 9;
- break;
- default:
- return error("bad size suffix");
- break;
- }
-
- // Dc1
- if ((*tok < KW_D0) && (*tok > KW_D7))
- return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
- inst2 = (*tok++) & 7;
-
- if (*tok++ != ':')
- return error("missing colon");
-
- // Dc2
- if ((*tok < KW_D0) && (*tok > KW_D7))
- return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
- inst3 = (*tok++) & 7;
-
- if (*tok++ != ',')
- return error("missing comma");
-
- // Du1
- if ((*tok < KW_D0) && (*tok > KW_D7))
- return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
- inst2 |= ((*tok++) & 7)<<6;
-
- if (*tok++ != ':')
- return error("missing colon");
-
- // Du2
- if ((*tok < KW_D0) && (*tok > KW_D7))
- return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
- inst3 |= ((*tok++) & 7) << 6;
-
- if (*tok++ != ',')
- return error("missing comma");
-
- // Rn1
- if (*tok++ != '(')
- return error("missing (");
- if ((*tok >= KW_D0) && (*tok <= KW_D7))
- inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
- else if ((*tok >= KW_A0) && (*tok <= KW_A7))
- inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
- else
- return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
-
- if (*tok++ != ')')
- return error("missing (");
-
- if (*tok++ != ':')
- return error("missing colon");
-
- // Rn2
- if (*tok++ != '(')
- return error("missing (");
- if ((*tok >= KW_D0) && (*tok <= KW_D7))
- inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
- else if ((*tok >= KW_A0) && (*tok <= KW_A7))
- inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
- else
- return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
-
- if (*tok++ != ')')
- return error("missing (");
-
- if (*tok != EOL)
- return error("extra (unexpected) text found");
-
- D_word(inst);
- D_word(inst2);
- D_word(inst3);
-
- return OK;
+ WORD inst2, inst3;
+ LONG amsk;
+
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ switch (siz)
+ {
+ case SIZB:
+ inst |= 1 << 9;
+ break;
+ case SIZW:
+ case SIZN:
+ inst |= 2 << 9;
+ break;
+ case SIZL:
+ inst |= 3 << 9;
+ break;
+ default:
+ return error("bad size suffix");
+ break;
+ }
+
+ // Dc1
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
+
+ inst2 = (*tok++) & 7;
+
+ if (*tok++ != ':')
+ return error("missing colon");
+
+ // Dc2
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
+
+ inst3 = (*tok++) & 7;
+
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ // Du1
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
+
+ inst2 |= ((*tok++) & 7) << 6;
+
+ if (*tok++ != ':')
+ return error("missing colon");
+
+ // Du2
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
+
+ inst3 |= ((*tok++) & 7) << 6;
+
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ // Rn1
+ if (*tok++ != '(')
+ return error("missing (");
+ if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
+ else if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
+ else
+ return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
+
+ if (*tok++ != ')')
+ return error("missing (");
+
+ if (*tok++ != ':')
+ return error("missing colon");
+
+ // Rn2
+ if (*tok++ != '(')
+ return error("missing (");
+ if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
+ else if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
+ else
+ return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
+
+ if (*tok++ != ')')
+ return error("missing (");
+
+ if (*tok != EOL)
+ return error("extra (unexpected) text found");
+
+ D_word(inst);
+ D_word(inst2);
+ D_word(inst3);
+
+ return OK;
}
+
//
// cmp2 (68020, 68030, 68040, CPU32)
//
int m_cmp2(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
-
- switch (siz&15)
- {
- case SIZW:
- case SIZN:
- inst |= 1 << 9;
- break;
- case SIZL:
- inst |= 2 << 9;
- break;
- default:
- // SIZB
- break;
- }
-
- WORD flg = inst; // Save flag bits
- inst &= ~0x3F; // Clobber flag bits in instr
-
- // Install "standard" instr size bits
- if (flg & 4)
- inst |= siz_6[siz];
-
- if (flg & 16)
- {
- // OR-in register number
- if (flg & 8)
- inst |= reg_9[a1reg]; // ea1reg in bits 9..11
- else
- inst |= reg_9[a0reg]; // ea0reg in bits 9..11
- }
-
- if (flg & 1)
- {
- // Use am1
- inst |= am1 | a1reg; // Get ea1 into instr
- D_word(inst); // Deposit instr
-
- // Generate ea0 if requested
- if (flg & 2)
- ea0gen(siz);
-
- ea1gen(siz); // Generate ea1
- }
- else
- {
- // Use am0
- inst |= am0 | a0reg; // Get ea0 into instr
- D_word(inst); // Deposit instr
- ea0gen(siz); // Generate ea0
-
- // Generate ea1 if requested
- if (flg & 2)
- ea1gen(siz);
- }
-
- // If we're called from chk2 then bit 11 of size will be set.
- // This is just a dumb mechanism to pass this, required by the extension word.
- // (you might have noticed the siz&15 thing above!)
- inst = (a1reg << 12)|(siz&(1<<11));
- if (am1 == AREG)
- inst |= 1 << 15;
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ switch (siz & 0x000F)
+ {
+ case SIZW:
+ case SIZN:
+ inst |= 1 << 9;
+ break;
+ case SIZL:
+ inst |= 2 << 9;
+ break;
+ default:
+ // SIZB
+ break;
+ }
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ // If we're called from chk2 then bit 11 of size will be set. This is just
+ // a dumb mechanism to pass this, required by the extension word. (You might
+ // have noticed the siz & 15 thing above!)
+ inst = (a1reg << 12) | (siz & (1 << 11));
+
+ if (am1 == AREG)
+ inst |= 1 << 15;
D_word(inst);
return OK;
}
+
//
// chk2 (68020, 68030, 68040, CPU32)
//
int m_chk2(WORD inst, WORD siz)
{
- return m_cmp2(inst, siz | (1 << 11));
+ return m_cmp2(inst, siz | (1 << 11));
}
+
//
// cpbcc(68020, 68030)
//
int m_cpbr(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
- return error(unsupport);
-
- VALUE v;
+ if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
+ return error(unsupport);
if (a0exattr & DEFINED)
{
if ((a0exattr & TDB) != cursect)
-//{
-//printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
return error(rel_error);
-//}
- v = a0exval - (sloc + 2);
+ VALUE v = a0exval - (sloc + 2);
// Optimize branch instr. size
if (siz == SIZL)
{
- if (v != 0 && v + 0x8000 < 0x10000)
+ if ((v != 0) && ((v + 0x8000) < 0x10000))
{
- inst |= (1 << 6);
+ inst |= (1 << 6);
D_word(inst);
WARNING(check what s "optional coprocessor-defined extension words!")
D_long(v);
}
else // SIZW/SIZN
{
- if (v + 0x8000 >= 0x10000)
+ if ((v + 0x8000) >= 0x10000)
return error(range_error);
+
D_word(inst);
WARNING(check what s "optional coprocessor-defined extension words!")
D_word(v);
}
else
{
- // .W
+ // .W
D_word(inst);
AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr);
D_word(0);
return OK;
}
+
//
// cpdbcc(68020, 68030)
//
int m_cpdbr(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
- return error(unsupport);
+ if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
+ return error(unsupport);
- return error("Not implemented yet.");
+ return error("Not implemented yet.");
//return OK;
}
+
//
// divs.l
//
int m_divs(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
-
- WORD flg = inst; // Save flag bits
- inst &= ~0x3F; // Clobber flag bits in instr
-
- // Install "standard" instr size bits
- if (flg & 4)
- inst |= siz_6[siz];
-
- if (flg & 16)
- {
- // OR-in register number
- if (flg & 8)
- inst |= reg_9[a1reg]; // ea1reg in bits 9..11
- else
- inst |= reg_9[a0reg]; // ea0reg in bits 9..11
- }
-
- if (flg & 1)
- {
- // Use am1
- inst |= am1 | a1reg; // Get ea1 into instr
- D_word(inst); // Deposit instr
-
- // Generate ea0 if requested
- if (flg & 2)
- ea0gen(siz);
-
- ea1gen(siz); // Generate ea1
- }
- else
- {
- // Use am0
- inst |= am0 | a0reg; // Get ea0 into instr
- D_word(inst); // Deposit instr
- ea0gen(siz); // Generate ea0
-
- // Generate ea1 if requested
- if (flg & 2)
- ea1gen(siz);
- }
-
- //D_word(inst);
- //ea0gen(siz);
- inst=a1reg+(a2reg<<12)+(1<<11);
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ inst = a1reg + (a2reg << 12) + (1 << 11);
D_word(inst);
-
+
return OK;
}
+
+
//
// muls.l
//
int m_muls(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
-
- WORD flg = inst; // Save flag bits
- inst &= ~0x3F; // Clobber flag bits in instr
-
- // Install "standard" instr size bits
- if (flg & 4)
- inst |= siz_6[siz];
-
- if (flg & 16)
- {
- // OR-in register number
- if (flg & 8)
- inst |= reg_9[a1reg]; // ea1reg in bits 9..11
- else
- inst |= reg_9[a0reg]; // ea0reg in bits 9..11
- }
-
- if (flg & 1)
- {
- // Use am1
- inst |= am1 | a1reg; // Get ea1 into instr
- D_word(inst); // Deposit instr
-
- // Generate ea0 if requested
- if (flg & 2)
- ea0gen(siz);
-
- ea1gen(siz); // Generate ea1
- }
- else
- {
- // Use am0
- inst |= am0 | a0reg; // Get ea0 into instr
- D_word(inst); // Deposit instr
- ea0gen(siz); // Generate ea0
-
- // Generate ea1 if requested
- if (flg & 2)
- ea1gen(siz);
- }
-
- //D_word(inst);
- //ea0gen(siz);
- inst=a1reg+(a2reg<<12)+(1<<11);
- inst|=mulmode; // add size bit
- D_word(inst);
-
- return OK;
-}
-//
-// divu.l
-//
-int m_divu(WORD inst, WORD siz)
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ inst = a1reg + (a2reg << 12) + (1 << 11);
+ inst |= mulmode; // add size bit
+ D_word(inst);
+
+ return OK;
+}
+
+
+//
+// divu.l
+//
+int m_divu(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
-
- //WARNING("divu.l d0,d1 is actually divul.l d0,d1:d1!!!")
-
- WORD flg = inst; // Save flag bits
- inst &= ~0x3F; // Clobber flag bits in instr
-
- // Install "standard" instr size bits
- if (flg & 4)
- inst |= siz_6[siz];
-
- if (flg & 16)
- {
- // OR-in register number
- if (flg & 8)
- inst |= reg_9[a1reg]; // ea1reg in bits 9..11
- else
- inst |= reg_9[a0reg]; // ea0reg in bits 9..11
- }
-
- if (flg & 1)
- {
- // Use am1
- inst |= am1 | a1reg; // Get ea1 into instr
- D_word(inst); // Deposit instr
-
- // Generate ea0 if requested
- if (flg & 2)
- ea0gen(siz);
-
- ea1gen(siz); // Generate ea1
- }
- else
- {
- // Use am0
- inst |= am0 | a0reg; // Get ea0 into instr
- D_word(inst); // Deposit instr
- ea0gen(siz); // Generate ea0
-
- // Generate ea1 if requested
- if (flg & 2)
- ea1gen(siz);
- }
-
- //D_word(inst);
- //ea0gen(siz);
- inst=a1reg+(a2reg<<12);
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ //WARNING("divu.l d0,d1 is actually divul.l d0,d1:d1!!!")
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ inst = a1reg + (a2reg << 12);
D_word(inst);
-
+
return OK;
}
+
+
//
// mulu.l
//
int m_mulu(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
-
- WORD flg = inst; // Save flag bits
- inst &= ~0x3F; // Clobber flag bits in instr
-
- // Install "standard" instr size bits
- if (flg & 4)
- inst |= siz_6[siz];
-
- if (flg & 16)
- {
- // OR-in register number
- if (flg & 8)
- inst |= reg_9[a1reg]; // ea1reg in bits 9..11
- else
- inst |= reg_9[a0reg]; // ea0reg in bits 9..11
- }
-
- if (flg & 1)
- {
- // Use am1
- inst |= am1 | a1reg; // Get ea1 into instr
- D_word(inst); // Deposit instr
-
- // Generate ea0 if requested
- if (flg & 2)
- ea0gen(siz);
-
- ea1gen(siz); // Generate ea1
- }
- else
- {
- // Use am0
- inst |= am0 | a0reg; // Get ea0 into instr
- D_word(inst); // Deposit instr
- ea0gen(siz); // Generate ea0
-
- // Generate ea1 if requested
- if (flg & 2)
- ea1gen(siz);
- }
-
- //D_word(inst);
- //ea0gen(siz);
- inst=a1reg+(a2reg<<12);
- inst|=mulmode; // add size bit
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ inst = a1reg + (a2reg << 12);
+ inst |= mulmode; // add size bit
D_word(inst);
-
+
return OK;
}
+
//
// divsl.l
//
int m_divsl(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
-
- WORD flg = inst; // Save flag bits
- inst &= ~0x3F; // Clobber flag bits in instr
-
- // Install "standard" instr size bits
- if (flg & 4)
- inst |= siz_6[siz];
-
- if (flg & 16)
- {
- // OR-in register number
- if (flg & 8)
- inst |= reg_9[a1reg]; // ea1reg in bits 9..11
- else
- inst |= reg_9[a0reg]; // ea0reg in bits 9..11
- }
-
- if (flg & 1)
- {
- // Use am1
- inst |= am1 | a1reg; // Get ea1 into instr
- D_word(inst); // Deposit instr
-
- // Generate ea0 if requested
- if (flg & 2)
- ea0gen(siz);
-
- ea1gen(siz); // Generate ea1
- }
- else
- {
- // Use am0
- inst |= am0 | a0reg; // Get ea0 into instr
- D_word(inst); // Deposit instr
- ea0gen(siz); // Generate ea0
-
- // Generate ea1 if requested
- if (flg & 2)
- ea1gen(siz);
- }
-
- //D_word(inst);
- //ea0gen(siz);
- inst=a1reg+(a2reg<<12)+(1<<11)+(1<<10);
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ inst = a1reg + (a2reg << 12) + (1 << 11) + (1 << 10);
D_word(inst);
return OK;
//
int m_divul(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
-
- WORD flg = inst; // Save flag bits
- inst &= ~0x3F; // Clobber flag bits in instr
-
- // Install "standard" instr size bits
- if (flg & 4)
- inst |= siz_6[siz];
-
- if (flg & 16)
- {
- // OR-in register number
- if (flg & 8)
- inst |= reg_9[a1reg]; // ea1reg in bits 9..11
- else
- inst |= reg_9[a0reg]; // ea0reg in bits 9..11
- }
-
- if (flg & 1)
- {
- // Use am1
- inst |= am1 | a1reg; // Get ea1 into instr
- D_word(inst); // Deposit instr
-
- // Generate ea0 if requested
- if (flg & 2)
- ea0gen(siz);
-
- ea1gen(siz); // Generate ea1
- }
- else
- {
- // Use am0
- inst |= am0 | a0reg; // Get ea0 into instr
- D_word(inst); // Deposit instr
- ea0gen(siz); // Generate ea0
-
- // Generate ea1 if requested
- if (flg & 2)
- ea1gen(siz);
- }
-
- //D_word(inst);
- //ea0gen(siz);
- inst=a1reg+(a2reg<<12)+(1<<10);
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ inst = a1reg + (a2reg << 12) + (1 << 10);
D_word(inst);
return OK;
}
+
//
// move16 (ax)+,(ay)+
//
int m_move16a(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
- return error(unsupport);
+ if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
+ return error(unsupport);
- inst|=a0reg;
+ inst |= a0reg;
D_word(inst);
- inst=(1<<15)+(a1reg<<12);
+ inst = (1 << 15) + (a1reg << 12);
D_word(inst);
return OK;
}
+
//
// move16 with absolute address
//
int m_move16b(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
- return error(unsupport);
+ if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
+ return error(unsupport);
- int v;
- inst|=a1reg;
+ int v;
+ inst |= a1reg;
D_word(inst);
- if (am0==APOSTINC)
- if (am1==AIND)
+ if (am0 == APOSTINC)
+ {
+ if (am1 == AIND)
return error("Wasn't this suppose to call m_move16a???");
else
{
//move16 (ax)+,(xxx).L
- inst|=0<<3;
- v=a1exval;
+ inst |= 0 << 3;
+ v = a1exval;
}
- else if (am0==ABSL)
- if (am1==AIND)
+ }
+ else if (am0 == ABSL)
+ {
+ if (am1 == AIND)
{
//move16 (xxx).L,(ax)+
- inst|=1<<3;
- v=a0exval;
+ inst |= 1 << 3;
+ v = a0exval;
}
else //APOSTINC
{
//move16 (xxx).L,(ax)
- inst|=3<<3;
- v=a0exval;
+ inst |= 3 << 3;
+ v = a0exval;
}
- else if (am0==AIND)
+ }
+ else if (am0 == AIND)
{
//move16 (ax),(xxx).L
- inst|=2<<3;
- v=a1exval;
+ inst |= 2 << 3;
+ v = a1exval;
}
+
D_word(inst);
D_long(v);
+
return OK;
}
+
//
// pack/unpack
//
int m_pack(WORD inst, WORD siz)
{
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
- WARNING(Parsing stuff by hand here might be better)
+ WARNING(Parsing stuff by hand here might be better)
- //if (am0==DREG && am1==DREG)
- //{
- // inst|=(1<<3)+(a0reg<<9)+(a1reg);
- //}
- //else if (am0==APREDEC && am1==APREDEC)
- //{
- // inst|=(a0reg<<9)+(a1reg);
- //}
- //else
- // return error("Only allowed combinations for pack/unpack are -(ax),-(ay) and dx,dy.");
- //
- //D_word(inst);
+#if 0
+ if ((am0 == DREG) && (am1 == DREG))
+ {
+ inst |= (1 << 3) + (a0reg << 9) + (a1reg);
+ }
+ else if ((am0 == APREDEC) && (am1 == APREDEC))
+ {
+ inst |= (a0reg << 9) + (a1reg);
+ }
+ else
+ return error("Only allowed combinations for pack/unpack are -(ax),-(ay) and dx,dy.");
+
+ D_word(inst);
+#endif
return OK;
}
+
//
// rtm Rn
//
int m_rtm(WORD inst, WORD siz)
{
- CHECKNO20;
+ CHECKNO20;
- if (am0==DREG)
+ if (am0 == DREG)
{
- inst|=a0reg;
+ inst |= a0reg;
}
- else if (am0==AREG)
+ else if (am0 == AREG)
{
- inst|=(1<<3)+a0reg;
+ inst |= (1 << 3) + a0reg;
}
else
return error("rtm only allows data or address registers.");
return OK;
}
+
//
// rtd #n
//
int m_rtd(WORD inst, WORD siz)
{
- CHECK00;
+ CHECK00;
- if (a0exattr & DEFINED)
- {
- if (a0exattr & TDB)
- return error(abs_error);
+ if (a0exattr & DEFINED)
+ {
+ if (a0exattr & TDB)
+ return error(abs_error);
- if (a0exval+0x8000 <= 0x7fff)
- return error(range_error);
+ if ((a0exval + 0x8000) <= 0x7FFF)
+ return error(range_error);
- D_word(inst);
- D_word(a0exval);
- }
- else
- return error(undef_error);
+ D_word(inst);
+ D_word(a0exval);
+ }
+ else
+ return error(undef_error);
- return OK;
+ return OK;
}
//
int m_trapcc(WORD inst, WORD siz)
{
- CHECK00;
-
- if (am0==AM_NONE)
+ CHECK00;
+
+ if (am0 == AM_NONE)
{
D_word(inst);
}
- else if (am0==IMMED)
+ else if (am0 == IMMED)
{
- if (siz==SIZW)
- {
- if (a0exval<0x10000)
+ if (siz == SIZW)
{
- inst|=2;
- D_word(inst);
- D_word(a0exval);
+ if (a0exval < 0x10000)
+ {
+ inst |= 2;
+ D_word(inst);
+ D_word(a0exval);
+ }
+ else
+ return error("Immediate value too big");
}
- else
- {
- return error("Immediate value too big");
- }
- }
- else //DOTL
- {
- inst|=3;
+ else //DOTL
+ {
+ inst |= 3;
D_word(inst);
D_long(a0exval);
}
return OK;
}
+
//
// cinv (68040)
//
int m_cinv(WORD inst, WORD siz)
{
- CHECKNO40;
-
+ CHECKNO40;
WARNING("cinvl ,(an) / cinvp ,(an) / cinva should work!")
- if (am0==AM_NONE)
- inst|=(0<<6)|(a1reg);
- else if (am0==KW_IC40)
- inst|=(2<<6)|(a1reg);
- else if (am0==KW_DC40)
- inst|=(1<<6)|(a1reg);
- else if (am0==KW_BC40)
- inst|=(3<<6)|(a1reg);
+
+ if (am0 == AM_NONE)
+ inst |= (0 << 6) | (a1reg);
+ else if (am0 == KW_IC40)
+ inst |= (2 << 6) | (a1reg);
+ else if (am0 == KW_DC40)
+ inst |= (1 << 6) | (a1reg);
+ else if (am0 == KW_BC40)
+ inst |= (3 << 6) | (a1reg);
D_word(inst);
return OK;
-
}
+
//
// cpRESTORE (68020, 68030)
//
int m_cprest(WORD inst, WORD siz)
{
- if (activecpu & !(CPU_68020|CPU_68030))
- return error(unsupport);
+ if (activecpu & !(CPU_68020 | CPU_68030))
+ return error(unsupport);
- inst|=am0|a0reg;
+ inst |= am0 | a0reg;
D_word(inst);
ea0gen(siz);
return OK;
}
+
//
// movec (68010, 68020, 68030, 68040, CPU32)
//
int m_movec(WORD inst, WORD siz)
{
- CHECK00;
+ CHECK00;
- if (am0 == DREG || am0 == AREG)
+ if (am0 == DREG || am0 == AREG)
{
// movec Rn,Rc
- inst|=1;
+ inst |= 1;
D_word(inst);
+
if (am0 == DREG)
{
inst = (0 << 15) + (a0reg << 12) + CREGlut[a1reg];
{
// movec Rc,Rn
D_word(inst);
+
if (am1 == DREG)
{
inst = (0 << 15) + (a1reg << 12) + CREGlut[a0reg];
return OK;
}
+
//
// moves (68010, 68020, 68030, 68040, CPU32)
//
int m_moves(WORD inst, WORD siz)
{
- if (activecpu & !(CPU_68020 | CPU_68030 | CPU_68040))
- return error(unsupport);
-
- if (siz == SIZB)
- {
- inst |= 0 << 6;
- }
- else if (siz == SIZL)
- {
- inst |= 2 << 6;
- }
- else // SIZW/SIZN
- {
- inst |= 1 << 6;
- }
-
- if (am0 == DREG)
- {
- inst |= am1 | a1reg;
- D_word(inst);
- inst = (a0reg << 12) | (1 << 11) | (0 << 15);
- D_word(inst);
- }
- else if (am0 == AREG)
- {
- inst |= am1 | a1reg;
- D_word(inst);
- inst = (a0reg << 12) | (1 << 11) | (1 << 15);
- D_word(inst);
- }
- else
- {
- if (am1 == DREG)
- {
- inst |= am0 | a0reg;
- D_word(inst);
- inst = (a1reg << 12) | (0 << 11) | (0 << 15);
- D_word(inst);
- }
- else
- {
- inst |= am0 | a0reg;
- D_word(inst);
- inst = (a1reg << 12) | (0 << 11) | (1 << 15);
- D_word(inst);
- }
- }
-
- return OK;
-
+ if (activecpu & !(CPU_68020 | CPU_68030 | CPU_68040))
+ return error(unsupport);
+
+ if (siz == SIZB)
+ {
+ inst |= 0 << 6;
+ }
+ else if (siz == SIZL)
+ {
+ inst |= 2 << 6;
+ }
+ else // SIZW/SIZN
+ {
+ inst |= 1 << 6;
+ }
+
+ if (am0 == DREG)
+ {
+ inst |= am1 | a1reg;
+ D_word(inst);
+ inst = (a0reg << 12) | (1 << 11) | (0 << 15);
+ D_word(inst);
+ }
+ else if (am0 == AREG)
+ {
+ inst |= am1 | a1reg;
+ D_word(inst);
+ inst = (a0reg << 12) | (1 << 11) | (1 << 15);
+ D_word(inst);
+ }
+ else
+ {
+ if (am1 == DREG)
+ {
+ inst |= am0 | a0reg;
+ D_word(inst);
+ inst = (a1reg << 12) | (0 << 11) | (0 << 15);
+ D_word(inst);
+ }
+ else
+ {
+ inst |= am0 | a0reg;
+ D_word(inst);
+ inst = (a1reg << 12) | (0 << 11) | (1 << 15);
+ D_word(inst);
+ }
+ }
+
+ return OK;
}
+
//
// PBcc (MC68851)
//
int m_pbcc(WORD inst, WORD siz)
{
- CHECKNO20;
- return error("Not implemented yet.");
+ CHECKNO20;
+ return error("Not implemented yet.");
}
+
//
// pflusha (68030)
//
int m_pflusha(WORD inst, WORD siz)
{
- CHECKNO30;
+ CHECKNO30;
D_word(inst);
- inst=((1 << 13) | (1 << 10)) | (0 << 5) | 0;
+ inst = (1 << 13) | (1 << 10) | (0 << 5) | 0;
D_word(inst);
return OK;
}
+
//
// pflush (68030, 68040, 68060)
//
if (activecpu == CPU_68030)
{
D_word(inst);
- D_word(((1 << 13) | (1 << 10)) | (0 << 5) | 0);
+ D_word((1 << 13) | (1 << 10) | (0 << 5) | 0);
}
else if (activecpu == CPU_68040 || activecpu == CPU_68060)
{
return OK;
}
+
//
// pflushr (68551)
//
int m_pflushr(WORD inst, WORD siz)
{
- CHECKNO20;
+ CHECKNO20;
- WORD flg = inst; // Save flag bits
- inst &= ~0x3F; // Clobber flag bits in instr
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
- // Install "standard" instr size bits
- if (flg & 4)
- inst |= siz_6[siz];
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
- if (flg & 16)
- {
- // OR-in register number
- if (flg & 8)
- inst |= reg_9[a1reg]; // ea1reg in bits 9..11
- else
- inst |= reg_9[a0reg]; // ea0reg in bits 9..11
- }
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
- if (flg & 1)
- {
- // Use am1
- inst |= am1 | a1reg; // Get ea1 into instr
- D_word(inst); // Deposit instr
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
- // Generate ea0 if requested
- if (flg & 2)
- ea0gen(siz);
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
- ea1gen(siz); // Generate ea1
- }
- else
- {
- // Use am0
- inst |= am0 | a0reg; // Get ea0 into instr
- D_word(inst); // Deposit instr
- ea0gen(siz); // Generate ea0
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
- // Generate ea1 if requested
- if (flg & 2)
- ea1gen(siz);
- }
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
- D_word(B16(10100000, 00000000));
+ D_word(B16(10100000, 00000000));
}
+
//
// ploadr, ploadw (68030)
//
int m_pload(WORD inst, WORD siz)
{
- CHECKNO30;
- return error("Not implemented yet.");
+ CHECKNO30;
+ return error("Not implemented yet.");
}
+
//
// pmove (68030)
//
{
int inst2,reg;
- CHECKNO30;
+ CHECKNO30;
- inst2 = inst&(1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
+ inst2 = inst & (1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
inst &= ~(1 << 8); //And mask it out
+
if (am0 == CREG)
{
- reg=a0reg;
- inst2|= (1<<9);
+ reg = a0reg;
+ inst2 |= (1 << 9);
}
else if (am1 == CREG)
{
reg = a1reg;
- inst2|=0;
+ inst2 |= 0;
}
else
return error("pmove sez: Wut?");
- if ((reg == KW_URP-KW_SFC || reg == KW_SRP-KW_SFC) && ((siz != SIZD) && (siz!=SIZN)))
+ if (((reg == (KW_URP - KW_SFC)) || (reg == (KW_SRP - KW_SFC)))
+ && ((siz != SIZD) && (siz != SIZN)))
return error(siz_error);
- if ((reg == KW_TC-KW_SFC || reg == KW_TT0-KW_SFC || reg == KW_TT1-KW_SFC) && ((siz != SIZL)&&(siz!=SIZN)))
+
+ if (((reg == (KW_TC - KW_SFC)) || (reg == (KW_TT0 - KW_SFC)) || (reg == (KW_TT1 - KW_SFC)))
+ && ((siz != SIZL) && (siz != SIZN)))
return error(siz_error);
- if ((reg == KW_MMUSR-KW_SFC) && ((siz != SIZW)&&(siz!=SIZN)))
+
+ if ((reg == (KW_MMUSR - KW_SFC)) && ((siz != SIZW) && (siz != SIZN)))
return error(siz_error);
WARNING(Not all addressing modes are legal here!)
- if (am0 == CREG)
- {
- inst|=am1;
- D_word(inst);
- ea1gen(siz);
- }
- else if (am1 == CREG)
- {
- inst|=am0;
- D_word(inst);
- ea0gen(siz);
- }
+
+ if (am0 == CREG)
+ {
+ inst |= am1;
+ D_word(inst);
+ ea1gen(siz);
+ }
+ else if (am1 == CREG)
+ {
+ inst |= am0;
+ D_word(inst);
+ ea0gen(siz);
+ }
switch (reg)
{
- case (KW_URP-KW_SFC):
+ case (KW_URP - KW_SFC):
inst2 |= (3 << 10) + (2 << 13); break;
- case (KW_SRP-KW_SFC):
+ case (KW_SRP - KW_SFC):
inst2 |= (2 << 10) + (2 << 13); break;
- case (KW_TC-KW_SFC):
+ case (KW_TC - KW_SFC):
inst2 |= (0 << 10) + (2 << 13); break;
- case (KW_TT0-KW_SFC):
+ case (KW_TT0 - KW_SFC):
inst2 |= (2 << 10) + (0 << 13); break;
- case (KW_TT1-KW_SFC):
+ case (KW_TT1 - KW_SFC):
inst2 |= (3 << 10) + (0 << 13); break;
- case (KW_MMUSR-KW_SFC):
+ case (KW_MMUSR - KW_SFC):
inst2 |= (3 << 10) + (3 << 13); break;
- case (KW_CRP-KW_SFC) : //68851 only
+ case (KW_CRP - KW_SFC) : //68851 only
inst2 |= (3 << 10) + (2 << 13); break;
}
return OK;
}
+
//
// pmovefd (68030)
//
int m_pmovefd(WORD inst, WORD siz)
{
- CHECKNO30;
+ CHECKNO30;
- return m_pmove(inst|(1<<8),siz);
+ return m_pmove(inst | (1 << 8), siz);
}
+
//
// ptrapcc (68851)
//
int m_ptrapcsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001110)); return OK; }
int m_ptrapccn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001111)); return OK; }
+
//
// ptestr, ptestw (68030)
//
int m_ptest(WORD inst, WORD siz)
{
- CHECKNO30;
+ CHECKNO30;
+
if (activecpu == CPU_68030)
return error("Not implemented yet.");
else if (activecpu == CPU_68040)
return error("Not implemented yet.");
+
return ERROR;
}
+
#define FPU_NOWARN 0
#define FPU_P_EMUL 1
#define FPU_P2_EMU 2
#define FPU_FPSP 4
+
//
// Generate a FPU opcode
//
static inline int gen_fpu(WORD inst, WORD siz, WORD opmode, WORD emul)
{
- if (am0<AM_NONE) // Check first operand for ea or fp - is this right?
+ if (am0 < AM_NONE) // Check first operand for ea or fp - is this right?
{
- inst|=(1<<9); // Bolt on FPU id
- inst|=am0;
- if (am0==DREG)
- inst|=a0reg;
+ inst |= (1 << 9); // Bolt on FPU id
+ inst |= am0;
+
+ if (am0 == DREG)
+ inst |= a0reg;
+
D_word(inst);
inst = 1 << 14; // R/M field (we have ea so have to set this to 1)
+
switch (siz)
{
- case SIZB: inst |= (6<<10); break;
- case SIZW: inst |= (4<<10); break;
- case SIZL: inst |= (0<<10); break;
+ case SIZB: inst |= (6 << 10); break;
+ case SIZW: inst |= (4 << 10); break;
+ case SIZL: inst |= (0 << 10); break;
case SIZN:
- case SIZS: inst |= (1<<10); break;
- case SIZD: inst |= (5<<10); break;
- case SIZX: inst |= (2<<10); break;
+ case SIZS: inst |= (1 << 10); break;
+ case SIZD: inst |= (5 << 10); break;
+ case SIZX: inst |= (2 << 10); break;
case SIZP:
- {
- inst |= (3<<10);
+ inst |= (3 << 10);
+
if (emul)
warn("This encoding will cause an unimplemented data type exception in the MC68040 to allow emulation in software.");
+
+ break;
+ default:
+ return error("Something bad happened, possibly, in gen_fpu.");
+ break;
}
- break;
- default: return error("Something bad happened, possibly, in gen_fpu."); break;
- }
+
inst |= (a1reg << 7);
inst |= opmode;
D_word(inst);
}
else
{
- inst|=(1<<9); //Bolt on FPU id
+ inst |= (1 << 9); //Bolt on FPU id
D_word(inst);
inst = 0;
inst = a0reg << 10;
inst |= opmode;
D_word(inst);
}
- if (emul&FPU_FPSP && activefpu==FPU_68040)
+
+ if ((emul & FPU_FPSP) && (activefpu == FPU_68040))
warn("Instruction is emulated in 68040");
return OK;
}
+
//
// fabs, fsabs, fdabs (6888X, 68040)
//
{
return gen_fpu(inst, siz, B8(00011000), FPU_P_EMUL);
}
+
+
int m_fsabs(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
else
return error("Unsupported in current FPU");
}
+
+
int m_fdabs(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
return error("Unsupported in current FPU");
}
+
//
// facos (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00011100), FPU_FPSP);
}
+
//
// fadd (6888X, 68040FPSP)
//
{
return gen_fpu(inst, siz, B8(00100010), FPU_P_EMUL);
}
+
+
int m_fsadd(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
else
return error("Unsupported in current FPU");
}
+
+
int m_fdadd(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
return error("Unsupported in current FPU");
}
+
//
// fasin (6888X, 68040FPSP)f
//
return gen_fpu(inst, siz, B8(00001100), FPU_FPSP);
}
+
//
// fatan (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00001010), FPU_FPSP);
}
+
//
// fatanh (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00001101), FPU_FPSP);
}
+
//
// fcmp (6888X, 68040)
//
return gen_fpu(inst, siz, B8(00111000), FPU_P_EMUL);
}
+
//
// fcos (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00011101), FPU_FPSP);
}
+
//
// fcosh (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00011001), FPU_FPSP);
}
+
//
// fdbcc (6888X, 68040)
//
int m_fdbcc(WORD inst, WORD siz)
{
- VALUE v;
-
- WORD opcode=inst&0x3f; //Grab conditional bitfield
+ WORD opcode = inst & 0x3F; //Grab conditional bitfield
- inst&=~0x3f;
- inst|=1<<3;
+ inst &= ~0x3F;
+ inst |= 1 << 3;
siz = siz;
inst |= a0reg;
D_word(inst);
-
D_word(opcode);
if (a1exattr & DEFINED)
if ((a1exattr & TDB) != cursect)
return error(rel_error);
- v = a1exval - sloc;
+ VALUE v = a1exval - sloc;
- if (v + 0x8000 > 0x10000)
+ if ((v + 0x8000) > 0x10000)
return error(range_error);
D_word(v);
}
-
-
//
// fdiv (6888X, 68040)
//
{
return gen_fpu(inst, siz, B8(00100000), FPU_P_EMUL);
}
+
+
int m_fsdiv(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
else
return error("Unsupported in current FPU");
}
+
+
int m_fddiv(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
return error("Unsupported in current FPU");
}
+
//
// fetox (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00010000), FPU_FPSP);
}
+
//
// fetoxm1 (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00001000), FPU_FPSP);
}
+
//
// fgetexp (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00011110), FPU_FPSP);
}
+
//
// fgetman (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00011111), FPU_FPSP);
}
+
//
// fint (6888X, 68040FPSP)
//
int m_fint(WORD inst, WORD siz)
{
- if (am1==AM_NONE)
- // special case - fint fpx = fint fpx,fpx
- a1reg=a0reg;
+ if (am1 == AM_NONE)
+ // special case - fint fpx = fint fpx,fpx
+ a1reg = a0reg;
+
return gen_fpu(inst, siz, B8(00000001), FPU_FPSP);
}
+
//
// fintrz (6888X, 68040FPSP)
//
int m_fintrz(WORD inst, WORD siz)
{
- if (am1==AM_NONE)
- // special case - fintrz fpx = fintrz fpx,fpx
- a1reg=a0reg;
+ if (am1 == AM_NONE)
+ // special case - fintrz fpx = fintrz fpx,fpx
+ a1reg = a0reg;
+
return gen_fpu(inst, siz, B8(00000011), FPU_FPSP);
}
+
//
// flog10 (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00010101), FPU_FPSP);
}
+
//
// flog2 (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00010110), FPU_FPSP);
}
+
//
// flogn (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00010100), FPU_FPSP);
}
+
//
// flognp1 (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
}
+
//
// fmod (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00100001), FPU_FPSP);
}
+
//
// fmove (6888X, 68040)
//
int m_fmove(WORD inst, WORD siz)
{
- ////////////ea to register
- if (am0==FREG&&am1<AM_USP)
+ // EA to register
+ if ((am0 == FREG) && (am1 < AM_USP))
{
- //fpx->ea
-
- //ea
- inst|=am1|a1reg;
+ // EA
+ inst |= am1 | a1reg;
D_word(inst);
- //r/m
- //if (am0==DREG)
- inst=3<<13;
- //else
- // inst=0;
+ // R/M
+ inst = 3 << 13;
WARNING("K-factor logic is totally bogus - fix!")
- //source specifier
+ // Source specifier
switch (siz)
{
- case SIZB: inst |= (6<<10); break;
- case SIZW: inst |= (4<<10); break;
- case SIZL: inst |= (0<<10); break;
+ case SIZB: inst |= (6 << 10); break;
+ case SIZW: inst |= (4 << 10); break;
+ case SIZL: inst |= (0 << 10); break;
case SIZN:
- case SIZS: inst |= (1<<10); break;
- case SIZD: inst |= (5<<10); break;
- case SIZX: inst |= (2<<10); break;
- case SIZP: inst |= (3<<10); if (bfparam1) inst|=1<<12; inst|=(bfparam1&0x7ff)>>2; break;
- default: return error("Something bad happened, possibly."); break;
+ case SIZS: inst |= (1 << 10); break;
+ case SIZD: inst |= (5 << 10); break;
+ case SIZX: inst |= (2 << 10); break;
+ case SIZP: inst |= (3 << 10);
+ if (bfparam1)
+ inst |= 1 << 12;
+
+ inst |= (bfparam1 & 0x7FF) >> 2;
+ break;
+ default:
+ return error("Something bad happened, possibly.");
+ break;
}
- //immediate {} value
- if (bf0exval>=1<<6)
+ // Immediate {} value
+ if (bf0exval >= (1 << 6))
return error("K-factor must be between 0 and 31");
- if ((!bfparam1) && siz==SIZP)
- inst|=bf0exval;
- //destination specifier
- inst|=(a0reg<<7);
+ if (!bfparam1 && (siz == SIZP))
+ inst |= bf0exval;
- //opmode
- inst|=0;
+ // Destination specifier
+ inst |= (a0reg << 7);
- D_word(inst);
- ea1gen(siz);
+ // Opmode
+ inst |= 0;
+ D_word(inst);
+ ea1gen(siz);
}
- else if (am0<AM_USP&&am1==FREG)
+ else if ((am0 < AM_USP) && (am1 == FREG))
{
- //ea->fpx
-
- //ea
- inst|=am0|a0reg;
+ // EA
+ inst |= am0 | a0reg;
D_word(inst);
- //r/m
- //if (am0==DREG)
- inst=1<<14;
- //else
- // inst=0;
+ // R/M
+ inst = 1 << 14;
- //source specifier
+ // Source specifier
switch (siz)
{
- case SIZB: inst |= (6<<10); break;
- case SIZW: inst |= (4<<10); break;
- case SIZL: inst |= (0<<10); break;
+ case SIZB: inst |= (6 << 10); break;
+ case SIZW: inst |= (4 << 10); break;
+ case SIZL: inst |= (0 << 10); break;
case SIZN:
- case SIZS: inst |= (1<<10); break;
- case SIZD: inst |= (5<<10); break;
- case SIZX: inst |= (2<<10); break;
- case SIZP: inst |= (3<<10); break;
- default: return error("Something bad happened, possibly."); break;
+ case SIZS: inst |= (1 << 10); break;
+ case SIZD: inst |= (5 << 10); break;
+ case SIZX: inst |= (2 << 10); break;
+ case SIZP: inst |= (3 << 10); break;
+ default:
+ return error("Something bad happened, possibly.");
+ break;
}
- //destination specifier
- inst|=(a1reg<<7);
+ // Destination specifier
+ inst |= (a1reg << 7);
- //opmode
- inst|=0;
+ // Opmode
+ inst |= 0;
D_word(inst);
- ea0gen(siz);
-
+ ea0gen(siz);
}
- else if (am0==FREG&&am1==FREG)
+ else if ((am0 == FREG) && (am1 == FREG))
{
- //ea
+ // EA
D_word(inst);
- //r/m
- inst=0<<14;
+ // R/M
+ inst = 0 << 14;
- //source specifier
- if (siz!=SIZX)
+ // Source specifier
+ if (siz != SIZX)
return error("Invalid size");
- //source register
- inst|=(a0reg<<10);
+ // Source register
+ inst |= (a0reg << 10);
- //destination register
- inst|=(a1reg<<7);
+ // Destination register
+ inst |= (a1reg << 7);
D_word(inst);
}
- return OK;
- ///////////register to memory
- //ea
- //destination format
- //source register
- //k-factor (if required)
-
-
- //return error("Not implemented yet.");
- //return gen_fpu(inst, siz, B8(00101101), FPU_P_EMUL);
+ return OK;
}
+
//
// fmove (6888X, 68040)
//
int m_fmovescr(WORD inst, WORD siz)
{
- ///////////Move Floating-Point System Control Register (FPCR)
- //ea
- //dr
- //register select
- if (am0==FPSCR&&am1<AM_USP)
+ // Move Floating-Point System Control Register (FPCR)
+ // ea
+ // dr
+ // Register select
+ if ((am0 == FPSCR) && (am1 < AM_USP))
{
- inst|=am1|a1reg;
+ inst |= am1 | a1reg;
D_word(inst);
- inst=(1<<13)+(1<<15);
- inst|=a0reg;
+ inst = (1 << 13) + (1 << 15);
+ inst |= a0reg;
D_word(inst);
ea1gen(siz);
- return OK;
+ return OK;
}
- else if (am1==FPSCR&&am0<AM_USP)
+ else if ((am1 == FPSCR) && (am0 < AM_USP))
{
- inst|=am0|a0reg;
+ inst |= am0 | a0reg;
D_word(inst);
- inst=(0<<13)+(1<<15);
- inst|=a1reg;
+ inst = (0 << 13) + (1 << 15);
+ inst |= a1reg;
D_word(inst);
ea0gen(siz);
- return OK;
+ return OK;
}
else
- return error("m_fmovescr says: wut?");
+ return error("m_fmovescr says: wut?");
}
+
//
// fsmove/fdmove (68040)
//
int m_fsmove(WORD inst, WORD siz)
{
return error("Not implemented yet.");
+
+#if 0
if (activefpu == FPU_68040)
return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
else
return error("Unsupported in current FPU");
+#endif
}
+
+
int m_fdmove(WORD inst, WORD siz)
{
return error("Not implemented yet.");
+
+#if 0
if (activefpu == FPU_68040)
return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
else
return error("Unsupported in current FPU");
+#endif
}
+
+
//
// fmovecr (6888X, 68040FPSP)
//
inst |= a1reg << 7;
inst |= a0exval;
D_word(inst);
+
if (activefpu == FPU_68040)
warn("Instruction is emulated in 68040");
+
return OK;
}
+
//
// fmovem (6888X, 68040)
//
int m_fmovem(WORD inst, WORD siz)
{
- WORD regmask;
- WORD datareg;
-
- if (siz == SIZX)
- {
- if (*tok>=KW_FP0 && *tok<=KW_FP7)
- {
- //fmovem.x <rlist>,ea
- if (fpu_reglist_left(®mask) < 0)
- return OK;
- if (*tok++ != ',')
- return error("missing comma");
- if (amode(0) < 0)
- return OK;
- inst|=am0|a0reg;
- if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
- return error("invalid addressing mode");
- D_word(inst);
- inst=((1<<15)|(1<<14))|(1<<13)|(0<<11)|regmask;
- D_word(inst);
- ea0gen(siz);
- return OK;
- }
- else if (*tok >= KW_D0 && *tok <= KW_D7)
- {
- //fmovem.x Dn,ea
- datareg=(*tok++&7)<<10;
- if (*tok++ != ',')
- return error("missing comma");
- if (amode(0) < 0)
- return OK;
- inst|=am0|a0reg;
- if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
- return error("invalid addressing mode");
- D_word(inst);
- inst=((1<<15)|(1<<14))|(1<<13)|(1<<11)|(datareg<<4);
- D_word(inst);
- ea0gen(siz);
- return OK;
- }
- else
- {
- //fmovem.x ea,...
- if (amode(0) < 0)
- return OK;
- inst|=am0|a0reg;
- if (*tok++ != ',')
- return error("missing comma");
- if (*tok>=KW_FP0 && *tok<=KW_FP7)
- {
- //fmovem.x ea,<rlist>
- if (fpu_reglist_right(®mask) < 0)
- return OK;
- D_word(inst);
- inst=((1<<15)|(1<<14))|(0<<13)|(2<<11)|regmask;
- D_word(inst);
- ea0gen(siz);
- return OK;
- }
- else
- {
- //fmovem.x ea,Dn
- datareg=(*tok++&7)<<10;
- D_word(inst);
- inst=((1<<15)|(1<<14))|(0<<13)|(3<<11)|(datareg<<4);
- D_word(inst);
- ea0gen(siz);
- return OK;
- }
- }
- }
- else if (siz == SIZL||siz==SIZN)
- {
- if (*tok==KW_FPCR || *tok==KW_FPSR || *tok==KW_FPIAR)
- {
- //fmovem.l <rlist>,ea
- regmask=(1<<15)|(1<<13);
+ WORD regmask;
+ WORD datareg;
+
+ if (siz == SIZX)
+ {
+ if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+ {
+ // fmovem.x <rlist>,ea
+ if (fpu_reglist_left(®mask) < 0)
+ return OK;
+
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ if (amode(0) < 0)
+ return OK;
+
+ inst |= am0 | a0reg;
+
+ if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
+ return error("invalid addressing mode");
+
+ D_word(inst);
+ inst = (1 << 15) | (1 << 14) | (1 << 13) | (0 << 11) | regmask;
+ D_word(inst);
+ ea0gen(siz);
+ return OK;
+ }
+ else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ {
+ // fmovem.x Dn,ea
+ datareg = (*tok++ & 7) << 10;
+
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ if (amode(0) < 0)
+ return OK;
+
+ inst |= am0 | a0reg;
+
+ if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
+ return error("invalid addressing mode");
+
+ D_word(inst);
+ inst = (1 << 15) | (1 << 14) | (1 << 13) | (1 << 11) | (datareg << 4);
+ D_word(inst);
+ ea0gen(siz);
+ return OK;
+ }
+ else
+ {
+ // fmovem.x ea,...
+ if (amode(0) < 0)
+ return OK;
+
+ inst |= am0 | a0reg;
+
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+ {
+ //fmovem.x ea,<rlist>
+ if (fpu_reglist_right(®mask) < 0)
+ return OK;
+
+ D_word(inst);
+ inst = (1 << 15) | (1 << 14) | (0 << 13) | (2 << 11) | regmask;
+ D_word(inst);
+ ea0gen(siz);
+ return OK;
+ }
+ else
+ {
+ // fmovem.x ea,Dn
+ datareg = (*tok++ & 7) << 10;
+ D_word(inst);
+ inst = (1 << 15) | (1 << 14) | (0 << 13) | (3 << 11) | (datareg << 4);
+ D_word(inst);
+ ea0gen(siz);
+ return OK;
+ }
+ }
+ }
+ else if ((siz == SIZL) || (siz==SIZN))
+ {
+ if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
+ {
+ //fmovem.l <rlist>,ea
+ regmask = (1 << 15) | (1 << 13);
fmovem_loop_1:
- if (*tok==KW_FPCR)
- {
- regmask|=(1<<12);
- tok++;
- goto fmovem_loop_1;
- }
- if (*tok==KW_FPSR)
- {
- regmask|=(1<<11);
- tok++;
- goto fmovem_loop_1;
- }
- if (*tok==KW_FPIAR)
- {
- regmask|=(1<<10);
- tok++;
- goto fmovem_loop_1;
- }
- if (*tok=='/' || *tok=='-')
- {
- tok++;
- goto fmovem_loop_1;
- }
- if (*tok++ != ',')
- return error("missing comma");
- if (amode(0) < 0)
- return OK;
- inst|=am0|a0reg;
- D_word(inst);
- D_word(regmask);
- ea0gen(siz);
- }
- else
- {
- //fmovem.l ea,<rlist>
- if (amode(0) < 0)
- return OK;
- inst|=am0|a0reg;
- if (*tok++ != ',')
- return error("missing comma");
- regmask=(1<<15)|(0<<13);
+ if (*tok == KW_FPCR)
+ {
+ regmask |= (1 << 12);
+ tok++;
+ goto fmovem_loop_1;
+ }
+
+ if (*tok == KW_FPSR)
+ {
+ regmask |= (1 << 11);
+ tok++;
+ goto fmovem_loop_1;
+ }
+
+ if (*tok == KW_FPIAR)
+ {
+ regmask |= (1 << 10);
+ tok++;
+ goto fmovem_loop_1;
+ }
+
+ if ((*tok == '/') || (*tok == '-'))
+ {
+ tok++;
+ goto fmovem_loop_1;
+ }
+
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ if (amode(0) < 0)
+ return OK;
+
+ inst |= am0 | a0reg;
+ D_word(inst);
+ D_word(regmask);
+ ea0gen(siz);
+ }
+ else
+ {
+ //fmovem.l ea,<rlist>
+ if (amode(0) < 0)
+ return OK;
+
+ inst |= am0 | a0reg;
+
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ regmask = (1 << 15) | (0 << 13);
+
fmovem_loop_2:
- if (*tok==KW_FPCR)
- {
- regmask|=(1<<12);
- tok++;
- goto fmovem_loop_2;
- }
- if (*tok==KW_FPSR)
- {
- regmask|=(1<<11);
- tok++;
- goto fmovem_loop_2;
- }
- if (*tok==KW_FPIAR)
- {
- regmask|=(1<<10);
- tok++;
- goto fmovem_loop_2;
- }
- if (*tok=='/' || *tok=='-')
- {
- tok++;
- goto fmovem_loop_2;
- }
- if (*tok!=EOL)
- return error("extra (unexpected) text found");
- inst|=am0|a0reg;
- D_word(inst);
- D_word(regmask);
- ea0gen(siz);
- }
- }
- else
+ if (*tok == KW_FPCR)
+ {
+ regmask |= (1 << 12);
+ tok++;
+ goto fmovem_loop_2;
+ }
+
+ if (*tok == KW_FPSR)
+ {
+ regmask |= (1 << 11);
+ tok++;
+ goto fmovem_loop_2;
+ }
+
+ if (*tok == KW_FPIAR)
+ {
+ regmask |= (1 << 10);
+ tok++;
+ goto fmovem_loop_2;
+ }
+
+ if ((*tok == '/') || (*tok == '-'))
+ {
+ tok++;
+ goto fmovem_loop_2;
+ }
+
+ if (*tok!=EOL)
+ return error("extra (unexpected) text found");
+
+ inst |= am0 | a0reg;
+ D_word(inst);
+ D_word(regmask);
+ ea0gen(siz);
+ }
+ }
+ else
return error("bad size suffix");
- return OK;
+ return OK;
}
+
//
// fmul (6888X, 68040)
//
{
return gen_fpu(inst, siz, B8(00100011), FPU_P_EMUL);
}
+
+
int m_fsmul(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
else
return error("Unsupported in current FPU");
}
+
+
int m_fdmul(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
return error("Unsupported in current FPU");
}
+
//
// fneg (6888X, 68040)
//
{
return gen_fpu(inst, siz, B8(00011010), FPU_P_EMUL);
}
+
+
int m_fsneg(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
else
return error("Unsupported in current FPU");
}
+
+
int m_fdneg(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
return error("Unsupported in current FPU");
}
+
//
// fnop (6888X, 68040)
//
return gen_fpu(inst, siz, B8(00000000), FPU_P_EMUL);
}
+
//
// frem (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00100101), FPU_FPSP);
}
+
//
// fscale (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00100110), FPU_FPSP);
}
+
//
// FScc (6888X, 68040)
//
int m_fsseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010001)); return OK;}
int m_fssne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011110)); return OK;}
+
//
// FTRAPcc (6888X, 68040)
//
-
int m_ftrapeq (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000001)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000001)); D_long(a0exval); } return OK;}
int m_ftrapne (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001110)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001110)); D_long(a0exval); } return OK;}
int m_ftrapgt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010010)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010010)); D_long(a0exval); } return OK;}
return gen_fpu(inst, siz, B8(00100100), FPU_P_EMUL);
}
+
//
// fsglmul (6888X, 68040)
//
return gen_fpu(inst, siz, B8(00100111), FPU_P_EMUL);
}
+
//
// fsin (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00001110), FPU_FPSP);
}
+
//
// fsincos (6888X, 68040FPSP)
//
int m_fsincos(WORD inst, WORD siz)
{
- int temp;
- if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP)==OK)
+ if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP) == OK)
{
chptr[-1] |= a2reg;
return OK;
return ERROR;
}
+
//
// fsin (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00000010), FPU_FPSP);
}
+
//
// fsqrt (6888X, 68040)
//
{
return gen_fpu(inst, siz, B8(00000100), FPU_P_EMUL);
}
+
+
int m_fsfsqrt(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
else
return error("Unsupported in current FPU");
}
+
+
int m_fdfsqrt(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
return error("Unsupported in current FPU");
}
+
//
// fsub (6888X, 68040)
//
{
return gen_fpu(inst, siz, B8(00101000), FPU_P_EMUL);
}
+
+
int m_fsfsub(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
else
return error("Unsupported in current FPU");
}
+
+
int m_fdsub(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
return error("Unsupported in current FPU");
}
+
//
// ftan (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00001111), FPU_FPSP);
}
+
//
// ftanh (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00001001), FPU_FPSP);
}
+
//
// ftentox (6888X, 68040FPSP)
//
return gen_fpu(inst, siz, B8(00010010), FPU_FPSP);
}
+
//
// ftst (6888X, 68040)
//
return gen_fpu(inst, siz, B8(00111010), FPU_P_EMUL);
}
+
//
// ftwotox (6888X, 68040FPSP)
//
#define __MACH_H__
#include "rmac.h"
-#include "amode.h"
+
+// Mnemonic table structure
+#define MNTAB struct _mntab
+MNTAB {
+ WORD mnattr; // Attributes (CGSPECIAL, SIZN, ...)
+ LONG mn0, mn1; // Addressing modes
+ WORD mninst; // Instruction mask
+ WORD mncont; // Continuation (or -1)
+ int (* mnfunc)(WORD, WORD); // Mnemonic builder
+};
// Exported variables
extern char seg_error[];
extern char rel_error[];
extern char range_error[];
extern char abs_error[];
+extern char unsupport[];
extern MNTAB machtab[];
-extern int activecpu;
-extern int activefpu;
extern int movep;
-// Fucntion prototypes
-int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD);
-int m_self(WORD, WORD);
-int m_abcd(WORD, WORD);
-int m_reg(WORD, WORD);
-int m_imm(WORD, WORD);
-int m_imm8(WORD, WORD);
-int m_shi(WORD, WORD);
-int m_shr(WORD, WORD);
-int m_bitop(WORD, WORD);
-int m_exg(WORD, WORD);
-int m_ea(WORD, WORD);
-int m_lea(WORD, WORD);
-int m_br(WORD, WORD);
-int m_dbra(WORD, WORD);
-int m_link(WORD, WORD);
-int m_adda(WORD, WORD);
-int m_addq(WORD, WORD);
-//int m_move(WORD, int);
-int m_move(WORD, WORD);
-int m_moveq(WORD, WORD);
-int m_usp(WORD, WORD);
-int m_movep(WORD, WORD);
-int m_trap(WORD, WORD);
-int m_movem(WORD, WORD);
-int m_clra(WORD, WORD);
-
-int m_move30(WORD, WORD); //68020/30/40/60
-int m_br30(WORD inst, WORD siz);
-int m_ea030(WORD inst, WORD siz);
-int m_bfop(WORD inst, WORD siz);
-int m_callm(WORD inst, WORD siz);
-int m_cas(WORD inst, WORD siz);
-int m_cas2(WORD inst, WORD siz);
-int m_chk2(WORD inst, WORD siz);
-int m_cmp2(WORD inst, WORD siz);
-int m_bkpt(WORD inst, WORD siz);
-int m_cpbr(WORD inst, WORD siz);
-int m_cpdbr(WORD inst, WORD siz);
-int m_divs(WORD inst, WORD siz);
-int m_muls(WORD inst, WORD siz);
-int m_divu(WORD inst, WORD siz);
-int m_mulu(WORD inst, WORD siz);
-int m_divsl(WORD inst, WORD siz);
-int m_divul(WORD inst, WORD siz);
-int m_move16a(WORD inst, WORD siz);
-int m_move16b(WORD inst, WORD siz);
-int m_pack(WORD inst, WORD siz);
-int m_rtm(WORD inst, WORD siz);
-int m_rtd(WORD inst, WORD siz);
-int m_trapcc(WORD inst, WORD siz);
-int m_cinv(WORD inst, WORD siz);
-int m_cprest(WORD inst, WORD siz);
-int m_movec(WORD inst, WORD siz);
-int m_moves(WORD inst, WORD siz);
-
-// PMMU
-int m_pbcc(WORD inst, WORD siz);
-int m_pflusha(WORD inst, WORD siz);
-int m_pflush(WORD inst, WORD siz);
-int m_pflushr(WORD inst, WORD siz);
-int m_pload(WORD inst, WORD siz);
-int m_pmove(WORD inst, WORD siz);
-int m_pmovefd(WORD inst, WORD siz);
-int m_ptest(WORD inst, WORD siz);
-int m_ptrapbs(WORD inst, WORD siz);
-int m_ptrapbc(WORD inst, WORD siz);
-int m_ptrapls(WORD inst, WORD siz);
-int m_ptraplc(WORD inst, WORD siz);
-int m_ptrapss(WORD inst, WORD siz);
-int m_ptrapsc(WORD inst, WORD siz);
-int m_ptrapas(WORD inst, WORD siz);
-int m_ptrapac(WORD inst, WORD siz);
-int m_ptrapws(WORD inst, WORD siz);
-int m_ptrapwc(WORD inst, WORD siz);
-int m_ptrapis(WORD inst, WORD siz);
-int m_ptrapic(WORD inst, WORD siz);
-int m_ptrapgc(WORD inst, WORD siz);
-int m_ptrapgs(WORD inst, WORD siz);
-int m_ptrapcs(WORD inst, WORD siz);
-int m_ptrapcc(WORD inst, WORD siz);
-int m_ptrapbsn(WORD inst, WORD siz);
-int m_ptrapbcn(WORD inst, WORD siz);
-int m_ptraplsn(WORD inst, WORD siz);
-int m_ptraplcn(WORD inst, WORD siz);
-int m_ptrapssn(WORD inst, WORD siz);
-int m_ptrapscn(WORD inst, WORD siz);
-int m_ptrapasn(WORD inst, WORD siz);
-int m_ptrapacn(WORD inst, WORD siz);
-int m_ptrapwsn(WORD inst, WORD siz);
-int m_ptrapwcn(WORD inst, WORD siz);
-int m_ptrapisn(WORD inst, WORD siz);
-int m_ptrapicn(WORD inst, WORD siz);
-int m_ptrapgsn(WORD inst, WORD siz);
-int m_ptrapgcn(WORD inst, WORD siz);
-int m_ptrapcsn(WORD inst, WORD siz);
-int m_ptrapccn(WORD inst, WORD siz);
-
-//FPU
-int m_fabs(WORD inst, WORD siz);
-int m_facos(WORD inst, WORD siz);
-int m_fadd(WORD inst, WORD siz);
-int m_fasin(WORD inst, WORD siz);
-int m_fatan(WORD inst, WORD siz);
-int m_fatanh(WORD inst, WORD siz);
-int m_fcmp(WORD inst, WORD siz);
-int m_fcos(WORD inst, WORD siz);
-int m_fcosh(WORD inst, WORD siz);
-int m_fdabs(WORD inst, WORD siz);
-int m_fdadd(WORD inst, WORD siz);
-int m_fdbcc(WORD inst, WORD siz);
-int m_fddiv(WORD inst, WORD siz);
-int m_fdfsqrt(WORD inst, WORD siz);
-int m_fdiv(WORD inst, WORD siz);
-int m_fdmove(WORD inst, WORD siz);
-int m_fdmul(WORD inst, WORD siz);
-int m_fdneg(WORD inst, WORD siz);
-int m_fdsub(WORD inst, WORD siz);
-int m_fetox(WORD inst, WORD siz);
-int m_fetoxm1(WORD inst, WORD siz);
-int m_fgetexp(WORD inst, WORD siz);
-int m_fgetman(WORD inst, WORD siz);
-int m_fint(WORD inst, WORD siz);
-int m_fintrz(WORD inst, WORD siz);
-int m_flog10(WORD inst, WORD siz);
-int m_flog2(WORD inst, WORD siz);
-int m_flogn(WORD inst, WORD siz);
-int m_flognp1(WORD inst, WORD siz);
-int m_fmod(WORD inst, WORD siz);
-int m_fmove(WORD inst, WORD siz);
-int m_fmovescr(WORD inst, WORD siz);
-int m_fmovecr(WORD inst, WORD siz);
-int m_fmovem(WORD inst, WORD siz);
-int m_fmul(WORD inst, WORD siz);
-int m_fneg(WORD inst, WORD siz);
-int m_fnop(WORD inst, WORD siz);
-int m_frem(WORD inst, WORD siz);
-int m_fsabs(WORD inst, WORD siz);
-int m_fsadd(WORD inst, WORD siz);
-int m_fseq(WORD inst, WORD siz);
-int m_fsne(WORD inst, WORD siz);
-int m_fsgt(WORD inst, WORD siz);
-int m_fsngt(WORD inst, WORD siz);
-int m_fsge(WORD inst, WORD siz);
-int m_fsnge(WORD inst, WORD siz);
-int m_fslt(WORD inst, WORD siz);
-int m_fsnlt(WORD inst, WORD siz);
-int m_fsle(WORD inst, WORD siz);
-int m_fsnle(WORD inst, WORD siz);
-int m_fsgl(WORD inst, WORD siz);
-int m_fsngl(WORD inst, WORD siz);
-int m_fsgle(WORD inst, WORD siz);
-int m_fsngle(WORD inst, WORD siz);
-int m_fsogt(WORD inst, WORD siz);
-int m_fsule(WORD inst, WORD siz);
-int m_fsoge(WORD inst, WORD siz);
-int m_fsult(WORD inst, WORD siz);
-int m_fsolt(WORD inst, WORD siz);
-int m_fsuge(WORD inst, WORD siz);
-int m_fsole(WORD inst, WORD siz);
-int m_fsugt(WORD inst, WORD siz);
-int m_fsogl(WORD inst, WORD siz);
-int m_fsueq(WORD inst, WORD siz);
-int m_fsor(WORD inst, WORD siz);
-int m_fsun(WORD inst, WORD siz);
-int m_fsf(WORD inst, WORD siz);
-int m_fst(WORD inst, WORD siz);
-int m_fssf(WORD inst, WORD siz);
-int m_fsst(WORD inst, WORD siz);
-int m_fsseq(WORD inst, WORD siz);
-int m_fssne(WORD inst, WORD siz);
-int m_fscale(WORD inst, WORD siz);
-int m_fsdiv(WORD inst, WORD siz);
-int m_fsfsqrt(WORD inst, WORD siz);
-int m_fsfsub(WORD inst, WORD siz);
-int m_fsgldiv(WORD inst, WORD siz);
-int m_fsglmul(WORD inst, WORD siz);
-int m_fsin(WORD inst, WORD siz);
-int m_fsincos(WORD inst, WORD siz);
-int m_fsinh(WORD inst, WORD siz);
-int m_fsmove(WORD inst, WORD siz);
-int m_fsmul(WORD inst, WORD siz);
-int m_fsneg(WORD inst, WORD siz);
-int m_fsqrt(WORD inst, WORD siz);
-int m_fsub(WORD inst, WORD siz);
-int m_ftan(WORD inst, WORD siz);
-int m_ftanh(WORD inst, WORD siz);
-int m_ftentox(WORD inst, WORD siz);
-int m_ftst(WORD inst, WORD siz);
-int m_ftwotox(WORD inst, WORD siz);
-int m_ftrapeq(WORD inst, WORD siz);
-int m_ftrapne(WORD inst, WORD siz);
-int m_ftrapgt(WORD inst, WORD siz);
-int m_ftrapngt(WORD inst, WORD siz);
-int m_ftrapge(WORD inst, WORD siz);
-int m_ftrapnge(WORD inst, WORD siz);
-int m_ftraplt(WORD inst, WORD siz);
-int m_ftrapnlt(WORD inst, WORD siz);
-int m_ftraple(WORD inst, WORD siz);
-int m_ftrapnle(WORD inst, WORD siz);
-int m_ftrapgl(WORD inst, WORD siz);
-int m_ftrapngl(WORD inst, WORD siz);
-int m_ftrapgle(WORD inst, WORD siz);
-int m_ftrapngle(WORD inst, WORD siz);
-int m_ftrapogt(WORD inst, WORD siz);
-int m_ftrapule(WORD inst, WORD siz);
-int m_ftrapoge(WORD inst, WORD siz);
-int m_ftrapult(WORD inst, WORD siz);
-int m_ftrapolt(WORD inst, WORD siz);
-int m_ftrapuge(WORD inst, WORD siz);
-int m_ftrapole(WORD inst, WORD siz);
-int m_ftrapugt(WORD inst, WORD siz);
-int m_ftrapogl(WORD inst, WORD siz);
-int m_ftrapueq(WORD inst, WORD siz);
-int m_ftrapor(WORD inst, WORD siz);
-int m_ftrapun(WORD inst, WORD siz);
-int m_ftrapf(WORD inst, WORD siz);
-int m_ftrapt(WORD inst, WORD siz);
-int m_ftrapsf(WORD inst, WORD siz);
-int m_ftrapst(WORD inst, WORD siz);
-int m_ftrapseq(WORD inst, WORD siz);
-int m_ftrapsne(WORD inst, WORD siz);
-int m_ftrapeqn(WORD inst, WORD siz);
-int m_ftrapnen(WORD inst, WORD siz);
-int m_ftrapgtn(WORD inst, WORD siz);
-int m_ftrapngtn(WORD inst, WORD siz);
-int m_ftrapgen(WORD inst, WORD siz);
-int m_ftrapngen(WORD inst, WORD siz);
-int m_ftrapltn(WORD inst, WORD siz);
-int m_ftrapnltn(WORD inst, WORD siz);
-int m_ftraplen(WORD inst, WORD siz);
-int m_ftrapnlen(WORD inst, WORD siz);
-int m_ftrapgln(WORD inst, WORD siz);
-int m_ftrapngln(WORD inst, WORD siz);
-int m_ftrapglen(WORD inst, WORD siz);
-int m_ftrapnglen(WORD inst, WORD siz);
-int m_ftrapogtn(WORD inst, WORD siz);
-int m_ftrapulen(WORD inst, WORD siz);
-int m_ftrapogen(WORD inst, WORD siz);
-int m_ftrapultn(WORD inst, WORD siz);
-int m_ftrapoltn(WORD inst, WORD siz);
-int m_ftrapugen(WORD inst, WORD siz);
-int m_ftrapolen(WORD inst, WORD siz);
-int m_ftrapugtn(WORD inst, WORD siz);
-int m_ftrapogln(WORD inst, WORD siz);
-int m_ftrapueqn(WORD inst, WORD siz);
-int m_ftraporn(WORD inst, WORD siz);
-int m_ftrapunn(WORD inst, WORD siz);
-int m_ftrapfn(WORD inst, WORD siz);
-int m_ftraptn(WORD inst, WORD siz);
-int m_ftrapsfn(WORD inst, WORD siz);
-int m_ftrapstn(WORD inst, WORD siz);
-int m_ftrapseqn(WORD inst, WORD siz);
-int m_ftrapsnen(WORD inst, WORD siz);
-
#endif // __MACH_H__
CC = $(CROSS)gcc
HOSTCC = gcc
+#CFLAGS = -std=$(STD) -D_DEFAULT_SOURCE -g -D__GCCUNIX__ -I. -O2 -MMD
CFLAGS = -std=$(STD) -D_DEFAULT_SOURCE -g -D__GCCUNIX__ -I. -O2
SRCS = 6502.c amode.c debug.c direct.c eagen.c error.c expr.c listing.c mach.c macro.c mark.c object.c procln.c riscasm.c rmac.c sect.c symbol.c token.c
procln.o : procln.c procln.h
$(CC) $(CFLAGS) -c procln.c
-risca.o : risca.c risca.h
- $(CC) $(CFLAGS) -c risca.c
+riscasm.o : riscasm.c riscasm.h
+ $(CC) $(CFLAGS) -c riscasm.c
rmac.o : rmac.c rmac.h
$(CC) $(CFLAGS) -c rmac.c
#
# Dependencies
#
-6502.o: 6502.c direct.h rmac.h symbol.h expr.h error.h mach.h amode.h \
- procln.h token.h riscasm.h sect.h
+6502.o: 6502.c direct.h rmac.h symbol.h expr.h error.h mach.h procln.h \
+ token.h riscasm.h sect.h
68kgen.o: 68kgen.c
-amode.o: amode.c amode.h rmac.h symbol.h error.h token.h expr.h kwtab.h \
- mntab.h parmode.h
+amode.o: amode.c amode.h rmac.h symbol.h error.h expr.h mach.h procln.h \
+ token.h sect.h kwtab.h mntab.h parmode.h
debug.o: debug.c debug.h rmac.h symbol.h amode.h direct.h mark.h sect.h \
token.h
-direct.o: direct.c direct.h rmac.h symbol.h 6502.h error.h expr.h \
- listing.h mach.h amode.h macro.h mark.h procln.h token.h riscasm.h \
- sect.h kwtab.h
+direct.o: direct.c direct.h rmac.h symbol.h 6502.h amode.h error.h expr.h \
+ listing.h mach.h macro.h mark.h procln.h token.h riscasm.h sect.h \
+ kwtab.h
eagen.o: eagen.c eagen.h rmac.h symbol.h amode.h sect.h mark.h error.h \
mach.h riscasm.h eagen0.c
error.o: error.c error.h rmac.h symbol.h token.h listing.h
expr.o: expr.c expr.h rmac.h symbol.h direct.h error.h listing.h mach.h \
- amode.h procln.h token.h riscasm.h sect.h kwtab.h
+ procln.h token.h riscasm.h sect.h kwtab.h
kwgen.o: kwgen.c
-listing.o: listing.c listing.h rmac.h symbol.h version.h token.h procln.h \
- sect.h error.h
-mach.o: mach.c mach.h amode.h rmac.h symbol.h eagen.h error.h direct.h \
+listing.o: listing.c listing.h rmac.h symbol.h error.h procln.h token.h \
+ sect.h version.h
+mach.o: mach.c mach.h rmac.h symbol.h amode.h direct.h eagen.h error.h \
procln.h token.h riscasm.h sect.h kwtab.h 68ktab.h
macro.o: macro.c macro.h rmac.h symbol.h debug.h direct.h error.h expr.h \
listing.h procln.h token.h
mark.o: mark.c mark.h rmac.h symbol.h error.h object.h riscasm.h sect.h
-object.o: object.c object.h rmac.h symbol.h error.h mark.h riscasm.h \
- sect.h
+object.o: object.c object.h rmac.h symbol.h 6502.h error.h mark.h \
+ riscasm.h sect.h
procln.o: procln.c procln.h rmac.h symbol.h token.h 6502.h amode.h \
direct.h error.h expr.h listing.h mach.h macro.h riscasm.h sect.h \
kwtab.h mntab.h risckw.h 6502kw.h
listing.h mark.h macro.h object.h procln.h token.h riscasm.h sect.h \
version.h
sect.o: sect.c sect.h rmac.h symbol.h 6502.h direct.h error.h expr.h \
- listing.h mach.h amode.h mark.h riscasm.h token.h
+ listing.h mach.h mark.h riscasm.h token.h
symbol.o: symbol.c symbol.h error.h rmac.h listing.h object.h procln.h \
token.h
-token.o: token.c token.h rmac.h symbol.h error.h macro.h procln.h sect.h \
- kwtab.h
+token.o: token.c token.h rmac.h symbol.h direct.h error.h macro.h \
+ procln.h sect.h kwtab.h
//
if (prg_flag)
{
- //if ((flags & MLONG) == 0)
- // error("illegal word relocatable (in .PRG mode)");
+#if 0
+ if ((flags & MLONG) == 0)
+ error("illegal word relocatable (in .PRG mode)");
+#endif
if (symbol != NULL)
errors("illegal external reference (in .PRG mode) to '%s'",
//
#include "object.h"
+#include "6502.h"
#include "error.h"
#include "mark.h"
#include "riscasm.h"
#include "sect.h"
#include "symbol.h"
-extern void m6502obj(int ofd);
//#define DEBUG_ELF
{
//Since index register isn't used here, store register number in this field
AnIXREG = *tok++ & 7; // (Dn)
- if (*tok==')')
+ if (*tok == ')')
{
- tok++;
- AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
- AnEXTEN |= EXT_BS; // Base register suppressed
- AnEXTEN |= EXT_BDSIZE0; // Base displacement null
- AnEXTEN |= EXT_IISPOSN; // Indirect Postindexed with Null Outer Displacement
- AMn= MEMPOST;
- AnREG = 6 << 3; // stuff 110 to mode field
- goto AnOK;
+ tok++;
+ AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
+ AnEXTEN |= EXT_BS; // Base register suppressed
+ AnEXTEN |= EXT_BDSIZE0; // Base displacement null
+ AnEXTEN |= EXT_IISPOSN; // Indirect Postindexed with Null Outer Displacement
+ AMn= MEMPOST;
+ AnREG = 6 << 3; // stuff 110 to mode field
+ goto AnOK;
}
- else if (*tok=='L')
+ else if (*tok == 'L')
{
- // TODO: does DINDL gets used at all?
+ // TODO: does DINDL gets used at all?
//AMn=DINDL; // (Dn.l)
- //AnEXTEN = 1 << 1; // Long index size
+ //AnEXTEN = 1 << 1; // Long index size
+ //tok++;
+ }
+ else if (*tok == 'W') // (Dn.w)
+ {
+ // TODO: does DINDW gets used at all?
+ //AMn=DINDW;
+ //AnEXTEN = 1 << 1; // Word index size
//tok++;
}
- else if (*tok=='W') // (Dn.w)
+ else if (*tok == ',')
{
- // TODO: does DINDW gets used at all?
- //AMn=DINDW;
- //AnEXTEN = 1 << 1; // Word index size
- //tok++;
+ // ([bd,An],Xn..) without bd, An
+ // Base displacement is suppressed
+ AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
+ AnEXTEN |= EXT_BS; // Base register suppressed
+ AnEXTEN |= EXT_BDSIZE0;
+ AnREG = 6 << 3; // stuff 110 to mode field
+ tok++;
+ goto CHECKODn;
}
- else if (*tok == ',')
- {
- // ([bd,An],Xn..) without bd, An
- // Base displacement is suppressed
- AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
- AnEXTEN |= EXT_BS; // Base register suppressed
- AnEXTEN |= EXT_BDSIZE0;
- AnREG = 6 << 3; // stuff 110 to mode field
- tok++;
- goto CHECKODn;
- }
else
return error("(Dn) error");
- if (*tok == ')')
- {
- tok++;
- AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
- AnEXTEN |= EXT_BS; // Base register suppressed
- AnEXTEN |= EXT_BDSIZE0; // Base displacement null
- AnEXTEN |= EXT_IISPOSN; // Indirect Postindexed with Null Outer Displacement
- AnREG = 6 << 3; // stuff 110 to mode field
- AMn = MEMPOST;
- goto AnOK;
- }
- else
- return error("unhandled so far");
+ if (*tok == ')')
+ {
+ tok++;
+ AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
+ AnEXTEN |= EXT_BS; // Base register suppressed
+ AnEXTEN |= EXT_BDSIZE0; // Base displacement null
+ AnEXTEN |= EXT_IISPOSN; // Indirect Postindexed with Null Outer Displacement
+ AnREG = 6 << 3; // stuff 110 to mode field
+ AMn = MEMPOST;
+ goto AnOK;
+ }
+ else
+ return error("unhandled so far");
}
else if (*tok == KW_PC)
{ // (PC,Xn[.siz][*scale])
AnEXTEN|=EXT_BDSIZEW;
tok++;
}
- else
- {
- // Defined, absolute values from $FFFF8000..$00007FFF get optimized
- // to absolute short
- if (optim_flags[OPT_ABS_SHORT] && (AnBEXATTR & (TDB|DEFINED)) == DEFINED && (AnBEXVAL + 0x8000) < 0x10000)
- {
- AnEXTEN|=EXT_BDSIZEW;
+ else
+ {
+ // Defined, absolute values from $FFFF8000..$00007FFF get optimized
+ // to absolute short
+ if (optim_flags[OPT_ABS_SHORT]
+ && ((AnBEXATTR & (TDB | DEFINED)) == DEFINED)
+ && ((AnBEXVAL + 0x8000) < 0x10000))
+ {
+ AnEXTEN |= EXT_BDSIZEW;
warn("absolute value in base displacement ranging $FFFF8000..$00007FFF optimised to absolute short");
- }
- else
- {
- AnEXTEN|=EXT_BDSIZEL;
- }
- }
- }
- if (*tok==',')
+ }
+ else
+ {
+ AnEXTEN |= EXT_BDSIZEL;
+ }
+ }
+ }
+
+ if (*tok == ',')
tok++;
//else
// return error("Comma expected after base displacement");
}
+ // Check for address register or PC, suppress base register
+ // otherwise
- // Check for address register or PC, suppress base register otherwise
-
- if (*tok==KW_PC)
+ if (*tok == KW_PC)
{ // ([bd,PC,...
- AnREG=(7<<3)|3; // PC is special case - stuff 011 to register field and 111 to the mode field
+ AnREG = (7 << 3) | 3; // PC is special case - stuff 011 to register field and 111 to the mode field
tok++;
}
else if ((*tok >= KW_A0) && (*tok <= KW_A7))
tok++;
}
else if ((*tok >= KW_D0) && (*tok <= KW_D7))
- { // ([bd,Dn,...
- AnREG = (6<<3);
- AnEXTEN|=((*tok&7)<<12);
- AnEXTEN|=EXT_D;
- AnEXTEN|=EXT_BS; // Oh look, a data register! Which means that base register is suppressed
+ {
+ // ([bd,Dn,...
+ AnREG = (6 << 3);
+ AnEXTEN |= ((*tok & 7) << 12);
+ AnEXTEN |= EXT_D;
+ AnEXTEN |= EXT_BS; // Oh look, a data register! Which means that base register is suppressed
tok++;
// Check for size
- { // ([bd,An/PC],Xn.W/L...)
+ {
+ // ([bd,An/PC],Xn.W/L...)
switch ((int)*tok)
- { // Index reg size: <empty> | .W | .L
+ {
+ // Index reg size: <empty> | .W | .L
case DOTW:
tok++;
break;
AnEXTEN |= EXT_L;
tok++;
break;
- case DOTB: // .B not allowed here...
+ case DOTB:
+ // .B not allowed here...
goto badmode;
}
}
// Check for scale
- if (*tok=='*') // ([bd,An/PC],Xn*...)
+ if (*tok == '*') // ([bd,An/PC],Xn*...)
{
tok++;
- if (*tok==CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
+
+ if (*tok == CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
tok++;
+
switch ((int)*tok++)
{
case 1:
break;
default:
goto badmode;
- }
+ }
}
- if (*tok==']') // ([bd,Dn]...
+
+ if (*tok == ']') // ([bd,Dn]...
{
tok++;
goto IS_SUPPRESSEDn;
}
}
- else if (*tok==']')
+ else if (*tok == ']')
{
- // PC and Xn is suppressed
- AnREG=6<<3; // stuff 110 to mode field
+ // PC and Xn is suppressed
+ AnREG = 6 << 3; // stuff 110 to mode field
//AnEXTEN|=EXT_BS|EXT_IS;
- AnEXTEN |= EXT_BS;
- }
- else
- {
- goto badmode;
- }
+ AnEXTEN |= EXT_BS;
+ }
+ else
+ {
+ goto badmode;
+ }
// At a crossroads here. We can accept either ([bd,An/PC],... or ([bd,An/PC,Xn*scale],...
- if (*tok==']')
- { //([bd,An/PC],Xn,od)
+ if (*tok == ']')
+ {
+ //([bd,An/PC],Xn,od)
// Check for Xn
tok++;
- if (*tok==')')
- { //Xn and od are non existent, get out of jail free card
- AMn=MEMPRE; // ([bc,An,Xn],od) with no Xn and od
- AnEXTEN|=EXT_IS|EXT_IISPREN; //Suppress Xn and od
+
+ if (*tok == ')')
+ {
+ //Xn and od are non existent, get out of jail free card
+ AMn = MEMPRE; // ([bc,An,Xn],od) with no Xn and od
+ AnEXTEN |= EXT_IS | EXT_IISPREN; //Suppress Xn and od
tok++;
goto AnOK;
}
- else if (*tok!=',')
+ else if (*tok != ',')
return error("comma expected after ]");
else
tok++; // eat the comma
if ((*tok >= KW_A0) && (*tok <= KW_A7))
{
- AnIXREG=((*tok&7)<<12);
- AnEXTEN|=EXT_A;
+ AnIXREG = ((*tok & 7) << 12);
+ AnEXTEN |= EXT_A;
tok++;
}
else if ((*tok >= KW_D0) && (*tok <= KW_D7))
{
- AnEXTEN|=((*tok&7)<<12);
- AnEXTEN|=EXT_D;
+ AnEXTEN |= ((*tok & 7) << 12);
+ AnEXTEN |= EXT_D;
tok++;
}
else
{
//No index found, suppress it
- AnEXTEN|=EXT_IS;
+ AnEXTEN |= EXT_IS;
tok--; // Rewind tok to point to the comma
goto IS_SUPPRESSEDn; // https://xkcd.com/292/ - what does he know anyway?
}
// Check for size
- { // ([bd,An/PC],Xn.W/L...)
+ {
+ // ([bd,An/PC],Xn.W/L...)
switch ((int)*tok)
- { // Index reg size: <empty> | .W | .L
+ {
+ // Index reg size: <empty> | .W | .L
case DOTW:
tok++;
break;
AnEXTEN |= EXT_L;
tok++;
break;
- case DOTB: // .B not allowed here...
+ case DOTB:
+ // .B not allowed here...
goto badmode;
}
}
// Check for scale
- if (*tok=='*') // ([bd,An/PC],Xn*...)
+ if (*tok == '*')
{
+ // ([bd,An/PC],Xn*...)
tok++;
- if (*tok==CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
+
+ if (*tok == CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
tok++;
+
switch ((int)*tok++)
{
case 1:
break;
default:
goto badmode;
- }
+ }
}
// Check for od
- if (*tok==')') // ([bd,An/PC],Xn)
- { //od is non existant, get out of jail free card
- AMn=MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
- AnEXTEN|=EXT_IISPOSN; // No outer displacement
+ if (*tok == ')') // ([bd,An/PC],Xn)
+ {
+ //od is non existant, get out of jail free card
+ AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN |= EXT_IISPOSN; // No outer displacement
tok++;
goto AnOK;
}
else
tok++; // eat the comma
- CHECKODn:
+ CHECKODn:
+
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
goto badmode;
- if (optim_flags[OPT_BASE_DISP] && AnEXVAL==0)
+
+ if (optim_flags[OPT_BASE_DISP] && (AnEXVAL == 0))
{
// od=0 so optimise it out
- AMn=MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
- AnEXTEN|=EXT_IISPOSN; // No outer displacement
+ AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN |= EXT_IISPOSN; // No outer displacement
tok++;
goto AnOK;
}
+
// ([bd,An/PC],Xn,od)
if (*tok == DOTL)
{
// expr.L
- AnEXTEN|=EXT_IISPOSL; // Long outer displacement
+ AnEXTEN |= EXT_IISPOSL; // Long outer displacement
AMn = MEMPOST;
- // Defined, absolute values from $FFFF8000..$00007FFF get optimized
- // to absolute short
- if (optim_flags[OPT_ABS_SHORT] && (AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
- {
- AnEXTEN|=EXT_IISPOSW; // Word outer displacement
+ // Defined, absolute values from $FFFF8000..$00007FFF get
+ // optimized to absolute short
+ if (optim_flags[OPT_ABS_SHORT]
+ && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
+ && ((AnEXVAL + 0x8000) < 0x10000))
+ {
+ AnEXTEN |= EXT_IISPOSW; // Word outer displacement
AMn = MEMPOST;
warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
}
else
{
// expr[.W]
- AnEXTEN|=EXT_IISPOSW; // Word outer displacement
+ AnEXTEN |= EXT_IISPOSW; // Word outer displacement
AMn = MEMPOST;
// Is .W forced here?
{
tok++;
}
-
}
// Check for final closing parenthesis
- if (*tok==')')
+ if (*tok == ')')
{
tok++;
goto AnOK;
IS_SUPPRESSEDn:
// Check for od
- if (*tok==')') // ([bd,An/PC],Xn)
- { //od is non existant, get out of jail free card
- AMn=MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
- AnEXTEN|=EXT_IISNOIN; // No outer displacement
+ if (*tok == ')') // ([bd,An/PC],Xn)
+ {
+ //od is non existant, get out of jail free card
+ AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN |= EXT_IISNOIN; // No outer displacement
tok++;
goto AnOK;
}
else
tok++; // eat the comma
- if (*tok != CONST && *tok != SYMBOL)
- //if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+ if ((*tok != CONST) && (*tok != SYMBOL))
goto badmode;
- expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM);
- if (optim_flags[OPT_BASE_DISP] && AnEXVAL==0)
+
+ expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM);
+
+ if (optim_flags[OPT_BASE_DISP] && (AnEXVAL == 0))
{
// od=0 so optimise it out
- AMn=MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
- AnEXTEN|=EXT_IISNOIN; // No outer displacement
+ AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN |= EXT_IISNOIN; // No outer displacement
tok++;
goto AnOK;
}
+
// ([bd,An/PC],Xn,od)
if (*tok == DOTL)
{
// expr.L
tok++;
AMn = MEMPOST;
- AnEXTEN|=EXT_IISNOIL; // Long outer displacement with IS suppressed
- //goto AnOK;
-
+ AnEXTEN |= EXT_IISNOIL; // Long outer displacement with IS suppressed
}
else
{
// expr[.W][]
- AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed
- AMn = MEMPRE;
- if (*tok == DOTW)
- {
- //AnEXTEN|=EXT_IISNOIW; // Word outer displacement
- AMn = MEMPOST;
+ AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed
+ AMn = MEMPRE;
+
+ if (*tok == DOTW)
+ {
+ //AnEXTEN|=EXT_IISNOIW; // Word outer displacement
+ AMn = MEMPOST;
tok++;
- }
+ }
- // Defined, absolute values from $FFFF8000..$00007FFF get optimized
- // to absolute short
- else if (optim_flags[OPT_BASE_DISP] && (AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
+ // Defined, absolute values from $FFFF8000..$00007FFF get
+ // optimized to absolute short
+ else if (optim_flags[OPT_BASE_DISP]
+ && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
+ && ((AnEXVAL + 0x8000) < 0x10000))
{
//AnEXTEN|=EXT_IISNOIW; // Word outer displacement with IS suppressed
warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
}
-
-
}
// Check for final closing parenthesis
- if (*tok==')')
+ if (*tok == ')')
{
tok++;
goto AnOK;
}
else
return error("Closing parenthesis missing on addressing mode");
-
}
- else if (*tok==',')
+ else if (*tok == ',')
{
*tok++; // ([bd,An,Xn.size*scale],od)
+
//Check for Xn
if ((*tok >= KW_A0) && (*tok <= KW_A7))
{
- AnEXTEN|=((*tok&7)<<12);
- AnEXTEN|=EXT_A;
+ AnEXTEN |= ((*tok & 7) << 12);
+ AnEXTEN |= EXT_A;
tok++;
}
else if ((*tok >= KW_D0) && (*tok <= KW_D7))
{
- AnEXTEN|=((*tok&7)<<12);
- AnEXTEN|=EXT_D;
+ AnEXTEN |= ((*tok & 7) << 12);
+ AnEXTEN |= EXT_D;
tok++;
}
// Check for size
- { // ([bd,An/PC],Xn.W/L...)
+ {
+ // ([bd,An/PC],Xn.W/L...)
switch ((int)*tok)
- { // Index reg size: <empty> | .W | .L
+ {
+ // Index reg size: <empty> | .W | .L
case DOTW:
tok++;
break;
tok++;
AnEXTEN |= EXT_L;
break;
- case DOTB: // .B not allowed here...
+ case DOTB:
+ // .B not allowed here...
goto badmode;
}
-
}
-
+
// Check for scale
- if (*tok=='*') // ([bd,An/PC],Xn*...)
+ if (*tok == '*') // ([bd,An/PC],Xn*...)
{
tok++;
- if (*tok==CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
+
+ if (*tok == CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
tok++;
+
switch ((int)*tok++)
{
case 1:
break;
default:
goto badmode;
- }
+ }
}
//Check for ]
- if (*tok!=']')
+ if (*tok != ']')
return error("Expected closing bracket ]");
+
tok++; // Eat the bracket
//Check for od
- if (*tok==')') // ([bd,An/PC,Xn]...
- { //od is non existant, get out of jail free card
+ if (*tok == ')') // ([bd,An/PC,Xn]...
+ {
+ //od is non existant, get out of jail free card
//AnEXVAL=0; // zero outer displacement
- AMn=MEMPRE; // let's say it's ([bd,An,Xn],od) with od suppressed then
- AnEXTEN|=EXT_IISPREN; // No outer displacement
+ AMn = MEMPRE; // let's say it's ([bd,An,Xn],od) with od suppressed then
+ AnEXTEN |= EXT_IISPREN; // No outer displacement
tok++;
goto AnOK;
}
else if (*tok++!=',')
return error("comma expected after ]");
- WARNING(Put symbol and constant checks here!)
+
+ WARNING(Put symbol and constant checks here!)
+
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
goto badmode;
- if (optim_flags[OPT_BASE_DISP] && AnEXVAL==0)
+
+ if (optim_flags[OPT_BASE_DISP] && (AnEXVAL == 0))
{
// od=0 so optimise it out
- AMn=MEMPRE; // let's say it's ([bd,An],Xn,od) with od=0 then
- AnEXTEN|=EXT_IISPRE0; // No outer displacement
+ AMn = MEMPRE; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN |= EXT_IISPRE0; // No outer displacement
tok++;
goto AnOK;
}
+
// ([bd,An/PC,Xn],od)
if (*tok == DOTL)
{
// expr.L
AMn = MEMPRE;
tok++;
-
- AnEXTEN|=EXT_IISPREL;
-
+ AnEXTEN |= EXT_IISPREL;
}
else
{
- // expr.[W]
+ // expr.[W]
//tok++;
- AnEXTEN|=EXT_IISPREW;
+ AnEXTEN |= EXT_IISPREW;
AMn = MEMPRE;
// Is .W forced here?
// Defined, absolute values from $FFFF8000..$00007FFF get optimized
// to absolute short
- else if (optim_flags[OPT_BASE_DISP] && (AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
+ else if (optim_flags[OPT_BASE_DISP]
+ && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
+ && ((AnEXVAL + 0x8000) < 0x10000))
{
- AnEXTEN|=EXT_IISPREW;
+ AnEXTEN |= EXT_IISPREW;
warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
}
}
// Check for final closing parenthesis
- if (*tok==')')
+ if (*tok == ')')
{
tok++;
goto AnOK;
}
else
goto badmode;
-
- //goto unmode;
}
else
- { // (expr...
+ {
+ // (expr...
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
return ERROR;
goto AMn_IXN;
}
else if (*tok == ')')
- {
- AMn = ADISP;
- tok++;
- goto AnOK;
- }
+ {
+ AMn = ADISP;
+ tok++;
+ goto AnOK;
+ }
else
goto badmode;
}
}
else if (*tok == ')')
{
- AMn = PCDISP; // expr(PC)
+ AMn = PCDISP; // expr(PC)
tok++;
goto AnOK;
}
goto badmode;
}
}
- else if (*tok=='-' && tok[1]=='(' && ((tok[2]>=KW_A0) && (tok[2]<=KW_A7)) && tok[3]==')')
+ else if (*tok == '-' && tok[1] == '(' && ((tok[2] >= KW_A0) && (tok[2] <= KW_A7)) && tok[3] == ')')
{
AMn = APREDEC;
AnREG = tok[2] & 7;
{
AMn = AM_USP;
tok++;
- AnREG=2; //Added this for the case of USP used in movec (see CREGlut in mach.c). Hopefully nothing gets broken!
+ AnREG = 2; //Added this for the case of USP used in movec (see CREGlut in mach.c). Hopefully nothing gets broken!
goto AnOK;
}
- else if ((*tok>=KW_IC40) && (*tok<=KW_BC40))
+ else if ((*tok >= KW_IC40) && (*tok <= KW_BC40))
{
- AMn=CACHES;
- AnREG=*tok++-KW_IC40;
+ AMn = CACHES;
+ AnREG = *tok++ - KW_IC40;
// After a cache keyword only a comma or EOL is allowed
- if ((*tok!=',') && (*tok!=EOL))
+ if ((*tok != ',') && (*tok != EOL))
return ERROR;
+
goto AnOK;
}
- else if ((*tok>=KW_SFC) && (*tok<=KW_CRP))
+ else if ((*tok >= KW_SFC) && (*tok <= KW_CRP))
{
- AMn=CREG;
- AnREG=(*tok++)-KW_SFC;
+ AMn = CREG;
+ AnREG = (*tok++) - KW_SFC;
goto AnOK;
}
- else if ((*tok>=KW_FP0) && (*tok<=KW_FP7))
+ else if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
{
- AMn=FREG;
- AnREG=(*tok++&7);
+ AMn = FREG;
+ AnREG = (*tok++ & 7);
}
- else if ((*tok>=KW_FPIAR) && (*tok<=KW_FPCR))
+ else if ((*tok >= KW_FPIAR) && (*tok <= KW_FPCR))
{
- AMn=FPSCR;
- AnREG=(1<<((*tok++)-KW_FPIAR+10));
+ AMn = FPSCR;
+ AnREG = (1 << ((*tok++) - KW_FPIAR + 10));
}
// expr
// expr.w
CHK_FOR_DISPn:
if (*tok == DOTW)
{
- // expr.W
+ // expr.W
tok++;
AMn = ABSW;
- if ((AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL < 0x10000))
+ if (((AnEXATTR & (TDB | DEFINED)) == DEFINED) && (AnEXVAL < 0x10000))
AnEXVAL = (int32_t)(int16_t)AnEXVAL; // Sign extend value
goto AnOK;
// Defined, absolute values from $FFFF8000..$00007FFF get optimized
// to absolute short
- if (optim_flags[OPT_ABS_SHORT] && (AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
+ if (optim_flags[OPT_ABS_SHORT]
+ && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
+ && ((AnEXVAL + 0x8000) < 0x10000))
{
AMn = ABSW;
}
// Addressing mode OK
-
- AnOK:
+AnOK:
;
}
int just_bss; // 1, ds.b in microprocessor mode
VALUE pcloc; // Value of "PC" at beginning of line
SYM * lab_sym; // Label on line (or NULL)
-int bfparam1; // bfxxx instruction parameters
-int bfparam2; // bfxxx instruction parameters
const char extra_stuff[] = "extra (unexpected) text found after addressing mode";
const char comma_error[] = "missing comma";
M_AINDEXED, M_AINDEXED, M_AINDEXED, M_AINDEXED,
M_AINDEXED, M_AINDEXED, M_AINDEXED, M_AINDEXED,
- M_ABSW, // 070
- M_ABSL, // 071
- M_PCDISP, // 072
- M_PCINDEXED, // 073
- M_IMMED, // 074
- 0L, // 075
- 0L, // 076
- 0L, // 077
- M_ABASE, // 0100
- M_MEMPOST, // 0101
- M_MEMPRE, // 0102
- M_PCBASE, // 0103
- M_PCMPOST, // 0104
- M_PCMPRE, // 0105
- M_AM_USP, // 0106
- M_AM_SR, // 0107
- M_AM_CCR, // 0110
- M_AM_NONE, // 0111
- 0x30, // 0112
- 0x30, // 0113
- 0L, // 0114
- 0L, // 0115
- 0L, // 0116
- 0L, // 0117
- M_CREG, // 0120 (caches - TODO: is this correct or does it need its own bitfield?)
- M_CREG, // 0121
- M_FREG, // 0122
- M_FPSCR // 0123
-}; // 0123 length
+ M_ABSW, // 070
+ M_ABSL, // 071
+ M_PCDISP, // 072
+ M_PCINDEXED, // 073
+ M_IMMED, // 074
+ 0L, // 075
+ 0L, // 076
+ 0L, // 077
+ M_ABASE, // 0100
+ M_MEMPOST, // 0101
+ M_MEMPRE, // 0102
+ M_PCBASE, // 0103
+ M_PCMPOST, // 0104
+ M_PCMPRE, // 0105
+ M_AM_USP, // 0106
+ M_AM_SR, // 0107
+ M_AM_CCR, // 0110
+ M_AM_NONE, // 0111
+ 0x30, // 0112
+ 0x30, // 0113
+ 0L, // 0114
+ 0L, // 0115
+ 0L, // 0116
+ 0L, // 0117
+ M_CREG, // 0120 (caches - TODO: is this correct or does it need its own bitfield?)
+ M_CREG, // 0121
+ M_FREG, // 0122
+ M_FPSCR // 0123
+}; // 0123 length
// Function prototypes
#include "rmac.h"
#include "token.h"
-#include "amode.h"
// Exported variables
extern IFENT * ifent;
extern VALUE pcloc;
extern SYM * lab_sym;
extern LONG amsktab[];
-int bfparam1;
-int bfparam2;
-TOKEN bf0expr[EXPRSIZE]; // Expression
-VALUE bf0exval; // Expression's value
-WORD bf0exattr; // Expression's attribute
-SYM * bf0esym; // External symbol involved in expr
-
// Exported functions
void InitLineProcessor(void);
int d_if(void);
int d_else(void);
int d_endif(void);
-int check030bf(void);
#endif // __PROCLN_H__
char * cmdlnexec; // Executable name, pointer to ARGV[0]
char * searchpath; // Search path for include files
char defname[] = "noname.o"; // Default output filename
-int optim_flags[OPT_COUNT]; // Specific optimisations on/off matrix
-int activecpu=CPU_68000; // Active 68k CPU (68000 by default)
-int activefpu=FPU_NONE; // Active FPU (none by default)
+int optim_flags[OPT_COUNT]; // Specific optimisations on/off matrix
+int activecpu = CPU_68000; // Active 68k CPU (68000 by default)
+int activefpu = FPU_NONE; // Active FPU (none by default)
+
//
// Manipulate file extension.
"\n"
"Options:\n"
" -? or -h Display usage information\n"
- " -dsymbol[=value] Define symbol\n"
+ " -dsymbol[=value] Define symbol (with optional value, default=0)\n"
" -e[errorfile] Send error messages to file, not stdout\n"
" -f[format] Output object file format\n"
" a: ALCYON (use this for ST)\n"
" -o file Output file name\n"
" +o[value] Turn a specific optimisation on\n"
" Available optimisation values and default settings:\n"
- " o0: Absolute long adddresses to word (on)\n"
- " o1: move.l #x,dn/an to moveq (on)\n"
- " o2: Word branches to short (on)\n"
- " o3: Outer displacement 0(an) to (an) (off)\n"
- " o4: lea size(An),An to addq #size,An (off)\n"
- " o5: Absolute long base displacement to word (off)\n"
+ " o0: Absolute long adddresses to word (on)\n"
+ " o1: move.l #x,dn/an to moveq (on)\n"
+ " o2: Word branches to short (on)\n"
+ " o3: Outer displacement 0(an) to (an) (off)\n"
+ " o4: lea size(An),An to addq #size,An (off)\n"
+ " o5: Absolute long base displacement to word (off)\n"
" ~o[value] Turn a specific optimisation off\n"
" +oall Turn all optimisations on\n"
" ~oall Turn all optimisations off\n"
orgactive = 0; // Not in RISC org section
orgwarning = 0; // No ORG warning issued
segpadsize = 2; // Initialise segment padding size
- m6502 = 0; // 6502 mode off by default
+ m6502 = 0; // 6502 mode off by default
// Initialise modules
InitSymbolTable(); // Symbol table
perm_verb_flag = 0; // Clobber "permanent" verbose flag
legacy_flag = 1; // Default is legacy mode on (:-P)
- // Set legacy optimisation flags to on
- // and everything else to off
+ // Set legacy optimisation flags to on and everything else to off
memset(optim_flags, 0, OPT_COUNT * sizeof(int));
optim_flags[OPT_ABS_SHORT] =
optim_flags[OPT_MOVEL_MOVEQ] =
optim_flags[OPT_BSR_BCC_S] = 1;
cmdlnexec = argv[0]; // Obtain executable name
-
endian = GetEndianess(); // Get processor endianess
// If commands were passed in, process them
#define LONG uint32_t
#define VOID void
-#define ERROR (-1) // Generic error return
-#define EOS '\0' // End of string
-#define SPACE ' ' // ASCII space
+#define ERROR (-1) // Generic error return
+#define EOS '\0' // End of string
+#define SPACE ' ' // ASCII space
#define SLASHCHAR '/'
#define SLASHSTRING "/"
-#define VALUE uint32_t // Assembler value
-#define TOKEN uint32_t // Assembler token
-#define FNSIZ 128 // Maximum size of a filename
-#define OK 0 // OK return
-#define DEBUG if (debug) // Debug conditional
-#define MAXARGV 100 // Maximum number of commandline args
-#define STDOUT 1 // Standard output
-#define ERROUT 2 // Error output
+#define VALUE uint32_t // Assembler value
+#define TOKEN uint32_t // Assembler token
+#define FNSIZ 128 // Maximum size of a filename
+#define OK 0 // OK return
+#define DEBUG if (debug) // Debug conditional
+#define MAXARGV 100 // Maximum number of commandline args
+#define STDOUT 1 // Standard output
+#define ERROUT 2 // Error output
#define CREATMASK 0
// (Normally) non-printable tokens
-#define COLON ':' // : (grumble: GNUmacs hates ':')
-#define CONST 'a' // CONST <value>
-#define ACONST 'A' // ACONST <value> <attrib>
-#define STRING 'b' // STRING <address>
-#define STRINGA8 'S' // Atari 800 internal STRING <address>
-#define SYMBOL 'c' // SYMBOL <address>
-#define EOL 'e' // End of line
-#define TKEOF 'f' // End of file (or macro)
-#define DEQUALS 'g' // ==
-#define SET 149 // set
-#define REG 'R' // reg
-#define EQUREG 148 // equreg
-#define CCDEF 183 // ccdef
-#define DCOLON 'h' // ::
-#define GE 'i' // >=
-#define LE 'j' // <=
-#define NE 'k' // <> or !=
-#define SHR 'l' // >>
-#define SHL 'm' // <<
-#define UNMINUS 'n' // Unary '-'
-#define DOTB 'B' // .b or .B or .s or .S
-#define DOTW 'W' // .w or .W
-#define DOTL 'L' // .l or .L
-#define DOTI 'I' // .i or .I
-#define DOTD 'D' // .d or .D
-#define DOTS 'S' // .s or .S (FPU Single)
-#define DOTQ 'Q' // .q oe .Q (FPU Quad)
-#define DOTX 'X' // .x or .X (FPU Extended)
-#define DOTP 'P' // .p or .P (FPU Packed)
-#define ENDEXPR 'E' // End of expression
+#define COLON ':' // : (grumble: GNUmacs hates ':')
+#define CONST 'a' // CONST <value>
+#define ACONST 'A' // ACONST <value> <attrib>
+#define STRING 'b' // STRING <address>
+#define STRINGA8 'S' // Atari 800 internal STRING <address>
+#define SYMBOL 'c' // SYMBOL <address>
+#define EOL 'e' // End of line
+#define TKEOF 'f' // End of file (or macro)
+#define DEQUALS 'g' // ==
+#define SET 149 // set
+#define REG 'R' // reg
+#define EQUREG 148 // equreg
+#define CCDEF 183 // ccdef
+#define DCOLON 'h' // ::
+#define GE 'i' // >=
+#define LE 'j' // <=
+#define NE 'k' // <> or !=
+#define SHR 'l' // >>
+#define SHL 'm' // <<
+#define UNMINUS 'n' // Unary '-'
+#define DOTB 'B' // .b or .B or .s or .S
+#define DOTW 'W' // .w or .W
+#define DOTL 'L' // .l or .L
+#define DOTI 'I' // .i or .I
+#define DOTD 'D' // .d or .D
+#define DOTS 'S' // .s or .S (FPU Single)
+#define DOTQ 'Q' // .q oe .Q (FPU Quad)
+#define DOTX 'X' // .x or .X (FPU Extended)
+#define DOTP 'P' // .p or .P (FPU Packed)
+#define ENDEXPR 'E' // End of expression
// 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
+#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
// Pointer type that can point to (almost) anything
#define PTR union _ptr
PTR
{
- uint8_t * cp; // Char
- uint16_t * wp; // WORD
- uint32_t * lp; // LONG
- uint32_t lw; // LONG
- SYM ** sy; // SYM
- TOKEN * tk; // TOKEN
+ uint8_t * cp; // Char
+ uint16_t * wp; // WORD
+ uint32_t * lp; // LONG
+ uint32_t lw; // LONG
+ SYM ** sy; // SYM
+ TOKEN * tk; // TOKEN
};
// Symbol spaces
-#define LABEL 0 // User-defined symbol
-#define MACRO 1 // Macro definition
-#define MACARG 2 // Macro argument
-#define SY_UNDEF -1 // Undefined (lookup never matches it)
+#define LABEL 0 // User-defined symbol
+#define MACRO 1 // Macro definition
+#define MACARG 2 // Macro argument
+#define SY_UNDEF -1 // Undefined (lookup never matches it)
// Symbol and expression attributes
-#define DEFINED 0x8000 // Symbol has been defined
-#define GLOBAL 0x4000 // Symbol has been .GLOBL'd
-#define COMMON 0x2000 // Symbol has been .COMM'd
-#define REFERENCED 0x1000 // Symbol has been referenced
-#define EQUATED 0x0800 // Symbol was equated
-#define SDECLLIST 0x0400 // Symbol is on 'sdecl'-order list
+#define DEFINED 0x8000 // Symbol has been defined
+#define GLOBAL 0x4000 // Symbol has been .GLOBL'd
+#define COMMON 0x2000 // Symbol has been .COMM'd
+#define REFERENCED 0x1000 // Symbol has been referenced
+#define EQUATED 0x0800 // Symbol was equated
+#define SDECLLIST 0x0400 // Symbol is on 'sdecl'-order list
// Expression spaces, ORed with symbol and expression attributes above
-#define ABS 0x0000 // In absolute space
-#define TEXT 0x0001 // Relative to text
-#define DATA 0x0002 // Relative to data
-#define BSS 0x0004 // Relative to BSS
-#define M6502 0x0008 // 6502/microprocessor (absolute)
+#define ABS 0x0000 // In absolute space
+#define TEXT 0x0001 // Relative to text
+#define DATA 0x0002 // Relative to data
+#define BSS 0x0004 // Relative to BSS
+#define M6502 0x0008 // 6502/microprocessor (absolute)
#define TDB (TEXT|DATA|BSS) // Mask for text+data+bss
// Sizes
-#define SIZB 0x0001 // .b
-#define SIZW 0x0002 // .w
-#define SIZL 0x0004 // .l
-#define SIZN 0x0008 // no .(size) specifier
-#define SIZD 0x0010 // .d (quad word or FPU double precision 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 SIZB 0x0001 // .b
+#define SIZW 0x0002 // .w
+#define SIZL 0x0004 // .l
+#define SIZN 0x0008 // no .(size) specifier
+#define SIZD 0x0010 // .d (quad word or FPU double precision 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
// RISC register bank definitions (used in extended symbol attributes also)
-#define BANK_N 0x0000 // No register bank specified
-#define BANK_0 0x0001 // Register bank zero specified
-#define BANK_1 0x0002 // Register bank one specified
-#define EQUATEDREG 0x0008 // Equated register symbol
+#define BANK_N 0x0000 // No register bank specified
+#define BANK_0 0x0001 // Register bank zero specified
+#define BANK_1 0x0002 // Register bank one specified
+#define EQUATEDREG 0x0008 // Equated register symbol
#define UNDEF_EQUR 0x0010
#define EQUATEDCC 0x0020
#define UNDEF_CC 0x0040
OPT_MOVEL_MOVEQ = 1,
OPT_BSR_BCC_S = 2,
OPT_INDIRECT_DISP = 3,
- OPT_LEA_ADDQ = 4,
- OPT_BASE_DISP = 5,
+ OPT_LEA_ADDQ = 4,
+ OPT_BASE_DISP = 5,
OPT_COUNT // Dummy, used to count number of optimisation switches
};
extern int prg_flag; // 1 = write ".PRG" relocatable executable
extern LONG PRGFLAGS;
extern int optim_flags[OPT_COUNT];
+extern int activecpu;
+extern int activefpu;
// Exported functions
char * fext(char *, char *, int);
//
int symtable(void)
{
- extern int pagelen;
int i;
int j;
SYM * q = NULL;
STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // h i j k
(char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // l m n o
- (char)((BYTE)DOT)+STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // p q r s
- STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // t u v w
- (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z {
+ (char)((BYTE)DOT)+STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // p q r s
+ STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // t u v w
+ (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z {
SELF, SELF, SELF, ILLEG // | } ~ DEL
};
// Names of registers
static char * regname[] = {
-// "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
-// "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
-// "pc", "ssp", "usp", "sr", "ccr"
- "d0","d1","d2","d3","d4","d5","d6","d7", // 128,135
- "a0","a1","a2","a3","a4","a5","a6","sp", // 136,143
- "ssp","pc","sr","ccr","regequ","set","reg","r0", // 144,151
- "r1","r2","r3","r4","r5","r6","r7","r8", // 152,159
- "r9","r10","r11","r12","r13","r14","r15","r16", // 160,167
- "r17","r18","r19","r20","r21","r22","r23","r24", // 168,175
- "r25","r26","r27","r28","r29","r30","r31","ccdef", // 176,183
- "usp","ic40","dc40","bc40","sfc","dfc","","vbr", // 184,191
- "cacr","caar","msp","isp","tc","itt0","itt1","dtt0", // 192,199
- "dtt1","mmusr","urp","srp","iacr0","iacr1","dacr0","dacr1", // 200,207
- "tt0","tt1","crp","","","","","", // 208,215
- "","","","","fpiar","fpsr","fpcr","", // 216,223
- "fp0","fp1","fp2","fp3","fp4","fp5","fp6","fp7", // 224,231
- "","","","","","","","", // 232,239
- "","","","","","","","", // 240,247
- "","","","","","","","", // 248,255
- "","","","","x0","x1","y0","y1", // 256,263
- "","b0","","b2","","b1","a","b", // 264,271
- "mr","omr","la","lc","ssh","ssl","ss","", // 272,279
- "n0","n1","n2","n3","n4","n5","n6","n7", // 280,287
- "m0","m1","m2","m3","m4","m5","m6","m7", // 288,295
- "","","","","","","l","p", // 296,303
- "mr","omr","la","lc","ssh","ssl","ss","", // 304,311
- "a10","b10","x","y","","","ab","ba" // 312,319
+ "d0","d1","d2","d3","d4","d5","d6","d7", // 128,135
+ "a0","a1","a2","a3","a4","a5","a6","sp", // 136,143
+ "ssp","pc","sr","ccr","regequ","set","reg","r0", // 144,151
+ "r1","r2","r3","r4","r5","r6","r7","r8", // 152,159
+ "r9","r10","r11","r12","r13","r14","r15","r16", // 160,167
+ "r17","r18","r19","r20","r21","r22","r23","r24", // 168,175
+ "r25","r26","r27","r28","r29","r30","r31","ccdef", // 176,183
+ "usp","ic40","dc40","bc40","sfc","dfc","","vbr", // 184,191
+ "cacr","caar","msp","isp","tc","itt0","itt1","dtt0", // 192,199
+ "dtt1","mmusr","urp","srp","iacr0","iacr1","dacr0","dacr1", // 200,207
+ "tt0","tt1","crp","","","","","", // 208,215
+ "","","","","fpiar","fpsr","fpcr","", // 216,223
+ "fp0","fp1","fp2","fp3","fp4","fp5","fp6","fp7", // 224,231
+ "","","","","","","","", // 232,239
+ "","","","","","","","", // 240,247
+ "","","","","","","","", // 248,255
+ "","","","","x0","x1","y0","y1", // 256,263
+ "","b0","","b2","","b1","a","b", // 264,271
+ "mr","omr","la","lc","ssh","ssl","ss","", // 272,279
+ "n0","n1","n2","n3","n4","n5","n6","n7", // 280,287
+ "m0","m1","m2","m3","m4","m5","m6","m7", // 288,295
+ "","","","","","","l","p", // 296,303
+ "mr","omr","la","lc","ssh","ssl","ss","", // 304,311
+ "a10","b10","x","y","","","ab","ba" // 312,319
};
static char * riscregname[] = {
dotxtab['B'] = DOTB;
//dotxtab['s'] = DOTB;
//dotxtab['S'] = DOTB;
- dotxtab['w'] = DOTW; // .w .W
+ dotxtab['w'] = DOTW; // .w .W
dotxtab['W'] = DOTW;
- dotxtab['l'] = DOTL; // .l .L
+ dotxtab['l'] = DOTL; // .l .L
dotxtab['L'] = DOTL;
- dotxtab['i'] = DOTI; // .i .I (???)
+ dotxtab['i'] = DOTI; // .i .I (???)
dotxtab['I'] = DOTI;
dotxtab['D'] = DOTD; // .d .D (quad word)
dotxtab['d'] = DOTD;
dotxtab['S'] = DOTS; // .s .S
- dotxtab['s'] = DOTS;
+ dotxtab['s'] = DOTS;
dotxtab['Q'] = DOTQ; // .q .Q
- dotxtab['q'] = DOTQ;
+ dotxtab['q'] = DOTQ;
dotxtab['X'] = DOTX; // .x .x
- dotxtab['x'] = DOTX;
+ dotxtab['x'] = DOTX;
dotxtab['P'] = DOTP; // .p .P
- dotxtab['p'] = DOTP;
+ dotxtab['p'] = DOTP;
}
extern char lntag;
extern char tolowertab[];
extern INOBJ * cur_inobj;
-extern unsigned orgactive;
-extern unsigned orgaddr;
-extern LONG sloc;
extern int mjump_align;
extern char * string[];
// Release Information
#define MAJOR 1 // Major version number
-#define MINOR 6 // Minor version number
-#define PATCH 8 // Patch release number
+#define MINOR 7 // Minor version number
+#define PATCH 0 // Patch release number
#endif // __VERSION_H__