Add support for some missing ptestr/ptestrw/fsmove/fdmove. Add DSM in directives tab
authorggn <ggn.dbug@gmail.com>
Thu, 16 Jan 2020 09:47:59 +0000 (11:47 +0200)
committerShamus Hammons <jlhamm@acm.org>
Fri, 17 Jan 2020 20:15:17 +0000 (14:15 -0600)
68k.mch
direct.tab
mach.c
procln.c
procln.h

diff --git a/68k.mch b/68k.mch
index bd36e4617d367d5c4f2e069c31bb164499424564..830df0fc2c593190578677fefc3eb8847e117ede 100644 (file)
--- a/68k.mch
+++ b/68k.mch
@@ -710,8 +710,8 @@ psgs    BN   C_MOVES         M_AM_NONE       %111100000101101    m_fscc
 pscs    BN   C_MOVES         M_AM_NONE       %111100000101110    m_fscc
 pscc    BN   C_MOVES         M_AM_NONE       %111100000101111    m_fscc
 
-ptestr N     M_FC            M_IMMED         %1111000000eeeeee   m_ptest
-ptestw N     M_FC            M_IMMED         %1111000000eeeeee   m_ptest
+ptestr N     M_FC            C_PMOVE         %1111000000eeeeee   m_ptestr
+ptestw N     M_FC            C_PMOVE         %1111000000eeeeee   m_ptestw
 
 ptrapbs WLN  M_IMMED|M_AM_NONE         M_AM_NONE       %1111000001100000   m_ptrapcc
 ptrapbc WLN  M_IMMED|M_AM_NONE         M_AM_NONE       %1111000001100001   m_ptrapcc
index 3355dfe2df2ba9fd33bd805e937357121cb34220..d05e858afe51392a8facbc76575c545c73cda5ea 100644 (file)
@@ -111,7 +111,8 @@ nofpu   65
 .opt    66
 opt     66
 .objproc       67
-
+.dsm   68
+dsm    68
 .if            500
 if             500
 .else  501
diff --git a/mach.c b/mach.c
index 6d5bcf38a8652daa7a5fd7cf96655feca9d4a8d5..1309fae048d9843349977e95a2f5fad0e5e0031f 100644 (file)
--- a/mach.c
+++ b/mach.c
@@ -85,7 +85,9 @@ int m_pflushan(WORD inst, WORD siz);
 int m_pload(WORD inst, WORD siz, WORD extension);
 int m_pmove(WORD inst, WORD siz);
 int m_pmovefd(WORD inst, WORD siz);
-int m_ptest(WORD inst, WORD siz);
+int m_ptest(WORD inst, WORD siz, WORD extension);
+int m_ptestr(WORD inste, WORD siz);
+int m_ptestw(WORD inste, WORD siz);
 int m_ptrapcc(WORD inst, WORD siz);
 int m_ploadr(WORD inst, WORD siz);
 int m_ploadw(WORD inst, WORD siz);
@@ -2400,6 +2402,9 @@ int m_pload(WORD inst, WORD siz, WORD extension)
                if ((a0exattr & DEFINED) == 0)
                        return error("constant value must be defined");
 
+               if (a0exval>7)
+               return error("constant value must be between 0 and 7");
+
                inst = (2 << 3) | (uint16_t)a0exval;
                break;
        }
@@ -2563,20 +2568,103 @@ int m_ptrapcc(WORD inst, WORD siz)
 
 
 //
-// ptestr, ptestw (68030)
+// ptestr, ptestw (68030, 68040)
+// TODO See comment on m_pmove about 68851 support
+// TODO quite a good chunk of the 030 code is copied from m_pload, perhaps merge these somehow?
 //
-int m_ptest(WORD inst, WORD siz)
+int m_ptest(WORD inst, WORD siz, WORD extension)
 {
-       CHECKNO30;
+       uint64_t eval;
+
+       if (activecpu != CPU_68030 && activecpu != CPU_68040)
+               return error(unsupport);
 
        if (activecpu == CPU_68030)
-               return error("Not implemented yet.");
-       else if (activecpu == CPU_68040)
+       {
+               inst |= am1;
+               D_word(inst);
+
+               switch (am0)
+               {
+               case CREG:
+                       if (a0reg == KW_SFC - KW_SFC)
+                               extension |= 0;
+                       else if (a0reg == KW_DFC - KW_SFC)
+                               extension |= 1;
+                       else
+                               return error("illegal control register specified");
+                       break;
+               case DREG:
+                       extension |= (1 << 3) | a0reg;
+                       break;
+               case IMMED:
+                       if ((a0exattr & DEFINED) == 0)
+                               return error("constant value must be defined");
+
+                       if (a0exval > 7)
+                               return error("constant value must be between 0 and 7");
+
+                       extension |= (2 << 3) | (uint16_t)a0exval;
+                       break;
+               }
+
+               // Operand 3 must be an immediate
+               CHECK_COMMA
+
+               if (*tok++ != '#')
+                       return error("ptest level must be immediate");
+
+               // Let's be a bit inflexible here and demand that this
+               // is fully defined at this stage. Otherwise we'd have
+               // to arrange for a bitfield fixup, which would mean
+               // polluting the bitfields and codebase with special
+               // cases that might most likely never be used.
+               // So if anyone gets bit by this: sorry for being a butt!
+               if (abs_expr(&eval) != OK)
+                       return OK;      // We're returning OK because error() has already been called and error count has been increased
+
+               if (eval > 7)
+                       return error("ptest level must be between 0 and 7");
+
+               extension |= eval << 10;
+
+               // Operand 4 is optional and must be an address register
+
+               if (*tok != EOL)
+               {
+                       CHECK_COMMA
+
+                       if ((*tok >= KW_A0) && (*tok <= KW_A7))
+                       {
+                               extension |= (1 << 8) | ((*tok++ & 7) << 4);
+                       }
+                       else
+                       {
+                               return error("fourth parameter must be an address register");
+                       }
+               }
+
+               ErrorIfNotAtEOL();
+
+               D_word(extension);
+               return OK;
+       }
+       else
                return error("Not implemented yet.");
 
        return ERROR;
 }
 
+int m_ptestr(WORD inst, WORD siz)
+{
+       return m_ptest(inst, siz, (1 << 15) | (0 << 9));
+}
+
+int m_ptestw(WORD inst, WORD siz)
+{
+       return m_ptest(inst, siz, (1 << 15) | (1 << 9));
+}
+
 //////////////////////////////////////////////////////////////////////////////
 //
 // 68020/30/40/60 instructions
@@ -3155,14 +3243,7 @@ int m_fsmove(WORD inst, WORD siz)
        if (!(activefpu & (FPU_68040 | FPU_68060)))
                return error("Unsupported in current FPU");
 
-       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
+       return gen_fpu(inst, siz, B8(01100100), FPU_FPSP);
 }
 
 
@@ -3171,14 +3252,7 @@ int m_fdmove(WORD inst, WORD siz)
        if (!(activefpu & (FPU_68040 | FPU_68060)))
                return error("Unsupported in current FPU");
 
-       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
+       return gen_fpu(inst, siz, B8(01100100), FPU_FPSP);
 }
 
 
index 9c207bfdefe8481ca71195ad1ad7c3aaaf7c3471..be57b7d7f366f53db548a34a7b16bf4d450711d5 100644 (file)
--- a/procln.c
+++ b/procln.c
@@ -845,8 +845,13 @@ When checking to see if it's already been equated, issue a warning.
        if (amode(1) < 0)                               // Parse 0, 1 or 2 addr modes
                goto loop;
 
-       if (*tok != EOL)
-               error(extra_stuff);
+       // Check that we're at EOL
+       // The only exception is ptestr/ptestw instructions
+       // that have 3 or 4 operands and are not handled by
+       // amode(). (yes, we're taking a performance hit here sadly)
+       if (m->mnfunc != m_ptestr && m->mnfunc != m_ptestw)
+               if (*tok != EOL)
+                       error(extra_stuff);
 
        amsk0 = amsktab[am0];
        amsk1 = amsktab[am1];
index f4db36e26188cf5724f3f147da42c299d6b2b55d..3dedefdd3fc9ce3d3751d09e686c499dee45e2c0 100644 (file)
--- a/procln.h
+++ b/procln.h
 #include "rmac.h"
 #include "token.h"
 
+// Imported functions
+int m_ptestr(WORD inste, WORD siz);
+int m_ptestw(WORD inste, WORD siz);
+
 // Exported variables
 extern const char comma_error[];
 extern const char locgl_error[];