Added missing (d16,An,Dn[.size][*scale]) addressing mode
authorggn <ggn.dbug@gmail.com>
Tue, 23 Jan 2018 11:40:49 +0000 (13:40 +0200)
committerShamus Hammons <jlhamm@acm.org>
Wed, 24 Jan 2018 02:11:52 +0000 (20:11 -0600)
68ktab
mach.c
parmode.h

diff --git a/68ktab b/68ktab
index 1c03cff76692701b53cb36a62eebb83c2ff3d414..71c5f36ae2d4c65b1cbc6cd9d6f40f2f594efb49 100644 (file)
--- a/68ktab
+++ b/68ktab
@@ -4,7 +4,8 @@ abcd  NB     M_DREG          M_DREG          %1100rrr100000rrr   m_abcd    +
 add   NBWL   C_ALL           M_DREG          %1101rrr0sseR1100   m_ea      +
 -     NBWL   M_DREG          C_ALTMEM        %1101rrr1sseR0101   m_ea      +
 adda  NWL    C_ALL           M_AREG          %1101rrrs11eeeeee   m_adda    +
-addi  NWBL   M_IMMED         C_ALTDATA       %00000110sseeeS11   m_ea
+addi  NWBL   M_IMMED         C_ALTDATA       %00000110sseeeS11   m_ea      +
+-     NWBL   M_IMMED         C_ALTDATA       %00000110sseeeS10   m_ea030
 
 addq  NBWL   M_IMMED         C_ALT           %0101ddd0sseeeeee   m_addq
 
@@ -14,6 +15,7 @@ addx  NBWL   M_DREG          M_DREG          %1101rrr1ss000rrS   m_abcd    +
 and   NBWL   C_DATA          M_DREG          %1100rrr0sseR1S00   m_ea      +
 -     NBWL   M_DREG          C_ALTMEM        %1100rrr1sseR0S01   m_ea      +
 andi  NBWL   M_IMMED         C_ALTDATA       %00000010sseeeS11   m_ea      +
+-     NBWL   M_IMMED         C_ALL030        %00000010sseeeS10   m_ea030   +
 -     NB     M_IMMED         M_AM_CCR        %0000001000111100   m_imm8    +
 -     NW     M_IMMED         M_AM_SR         %0000001001111100   m_imm
 
@@ -121,6 +123,7 @@ cmp   NWL    M_AREG          M_DREG          %1011rrr0sseR1S00   m_ea      +
 -     NBWL   C_ALL           M_DREG          %1011rrr0sseR1S00   m_ea      +
 cmpa  NWL    C_ALL           M_AREG          %1011rrrs11eeeeee   m_adda    +
 cmpi  NBWL   M_IMMED         C_ALTDATA       %00001100sseeeS11   m_ea     +
+-     NBWL   M_IMMED         C_ALL030        %00001100sseeeS10   m_ea030   +
 cmpm  NBWL   M_APOSTINC      M_APOSTINC      %1011xxx1ss001yRS   m_reg
 
 cmp2  NBWL   C_ALL030        M_DREG+M_AREG   %00000ss011eeeeee   m_cmp2
@@ -256,6 +259,7 @@ divul LN     C_DATA030       M_DREG          %0100110001eeeeee   m_muls
 
 eor   NBWL   M_DREG          C_ALTDATA       %1011rrr1sseR0S01   m_ea      +
 eori  NBWL   M_IMMED         C_ALTDATA       %00001010sseeeS11   m_ea      +
+-     NBWL   M_IMMED         C_ALL030        %00001010sseeeS10   m_ea030   +
 -     NB     M_IMMED         M_AM_CCR        %0000101000111100   m_imm8    +
 -     NW     M_IMMED         M_AM_SR         %0000101001111100   m_imm
 
@@ -629,6 +633,7 @@ not   NBWL   C_ALTDATA       M_AM_NONE       %01000110sseee100   m_ea
 or    NBWL   C_DATA          M_DREG          %1000rrr0sseR1S00   m_ea      +
 -     NBWL   M_DREG          C_MEM           %1000rrr1sseR0S01   m_ea      +
 ori   NBWL   M_IMMED         C_ALTDATA       %00000000sseeeS11   m_ea      +
+-     NBWL   M_IMMED         C_ALL030        %00000000sseeeS10   m_ea030   +
 -     NB     M_IMMED         M_AM_CCR        %0000000000111100   m_imm8    +
 -     NW     M_IMMED         M_AM_SR         %0000000001111100   m_imm
 
@@ -780,7 +785,8 @@ stop  N      M_IMMED         M_AM_NONE       %0100111001110010   m_imm
 sub   NBWL   C_ALL           M_DREG          %1001rrr0sseR1S00   m_ea      +
 -     NBWL   M_DREG          C_ALTMEM        %1001rrr1sseR0S01   m_ea      +
 suba  NWL    C_ALL           M_AREG          %1001rrrs11eeeeee   m_adda    +
-subi  NBWL   M_IMMED         C_ALTDATA       %00000100sseeeS11   m_ea
+subi  NBWL   M_IMMED         C_ALTDATA       %00000100sseeeS11   m_ea      +
+-     NBWL   M_IMMED         C_ALL030        %00000100sseeeS11   m_ea030
 
 subq  NBWL   M_IMMED         C_ALT           %0101ddd1sseeeeee   m_addq
 
diff --git a/mach.c b/mach.c
index 162757f41023d66fd18dbc99e5f25d31aab3d975..b4b410666f38f77444b16b2322cf107afdbce2f6 100644 (file)
--- a/mach.c
+++ b/mach.c
@@ -400,8 +400,13 @@ int m_ea030(WORD inst, WORD siz)
                        // a corner case, so kludge it
                        a0reg = a0reg + 8;
                else if (am0 == PCDISP)
-                       //Another corner case (possibly!), so kludge ahoy
+                       // Another corner case (possibly!), so kludge ahoy
                        inst |= am0;                            // Get ea0 into instr
+               else if (am0 == IMMED && am1 == MEMPOST)
+               {
+                       // Added for addi/andi/cmpi/eori/ori/subi #xx,(bd,An,Dm)
+                       inst |= a1reg | AINDEXED;
+               }
                else if (am0 == IMMED)
                        inst |= am0 | a0reg;            // Get ea0 into instr
                else if (am0 == AM_CCR)
@@ -676,12 +681,12 @@ int m_link(WORD inst, WORD siz)
 
 WORD extra_addressing[16]=
 {
-       0,     // 0100 (bd,An,Xn)
-       0,     // 0101 ([bd,An],Xn,od)
-       0x180, // 0102 ([bc,An,Xn],od) (111 110 110 111)
-       0,     // 0103 (bd,PC,Xn)
-       0,     // 0104 ([bd,PC],Xn,od)
-       0,     // 0105 ([bc,PC,Xn],od)
+       0x30,  // 0100 (bd,An,Xn)
+       0x30,  // 0101 ([bd,An],Xn,od)
+       0x30,  // 0102 ([bc,An,Xn],od)
+       0x30,  // 0103 (bd,PC,Xn)
+       0x30,  // 0104 ([bd,PC],Xn,od)
+       0x30,  // 0105 ([bc,PC,Xn],od)
        0,     // 0106
        0,     // 0107
        0,     // 0110
@@ -753,14 +758,12 @@ int m_move(WORD inst, WORD size)
 
 //
 // Handle MOVE <C_ALL030> <C_ALTDATA>
-//        MOVE <C_ALL030> <M_AREG>
+//             MOVE <C_ALL030> <M_AREG>
 //
 int m_move30(WORD inst, WORD size)
 {
        int siz = (int)size;
-       // TODO: is extra_addressing necessary/correct?
-       //inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE];
-       inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg;
+       inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE];
 
        D_word(inst);
 
index 20f0973becf494dc445bbc689c45cb36c28882d9..dd9c77a23728a5a159272b28c787d2dab44a458a 100644 (file)
--- a/parmode.h
+++ b/parmode.h
@@ -929,6 +929,112 @@ IS_SUPPRESSEDn:
 
                                if (*tok == ',')
                                {
+                                       // Check if we're actually doing d8(An,Dn) or (d16,An,Dn[.size][*scale])
+                                       // TODO: not a very clear cut case from what I can think. The only way
+                                       // to distinguish between the two is to check AnEXVAL and see if it's
+                                       // >127 or <-128. But this doesn't work if AnEXVAL isn't defined yet.
+                                       // For now we fall through to d8(An,Dn) but this might bite us in the
+                                       // arse during fixups...
+                                       if ((AnEXATTR & DEFINED) && (AnEXVAL + 0x80 > 0x100))
+                                       {
+                                               // We're going to treat it as a full extension format with no
+                                               // indirect access and no base displacement/index register suppression
+                                               AnEXTEN |= EXT_FULLWORD;        // Definitely using full extension format, so set bit 8
+                                               AnEXTEN |= EXT_IISPRE0;         // No Memory Indirect Action
+                                               AnEXTEN |= EXT_BDSIZEL;         // Base Displacement Size Long
+                                               tok++;                                          // Get past the comma
+
+                                               // Our expression is techically a base displacement
+                                               // so let's copy it to the relevant variables so
+                                               // eagen0.c can pick it up properly
+                                               //AnBEXPR = AnEXPR;
+                                               AnBEXVAL = AnEXVAL;
+                                               AnBEXATTR = AnEXATTR;
+
+                                               if ((*tok >= KW_D0) && (*tok <= KW_D7))
+                                               {
+                                                       AnEXTEN |= ((*tok++) & 7) << 12;
+                                                       // Check for size
+                                                       {
+                                                               switch ((int)*tok)
+                                                               {
+                                                               // Index reg size: <empty> | .W | .L
+                                                               case DOTW:
+                                                                       tok++;
+                                                                       break;
+                                                               default:
+                                                                       break;
+                                                               case DOTL:
+                                                                       tok++;
+                                                                       AnEXTEN |= EXT_L;
+                                                                       break;
+                                                               case DOTB:
+                                                                       // .B not allowed here...
+                                                                       goto badmode;
+                                                               }
+                                                       }
+                                                       // Check for scale
+                                                       if (*tok == '*')                // ([bd,An/PC],Xn*...)
+                                                       {                                               // scale: *1, *2, *4, *8 
+                                                               tok++;
+
+                                                               if (*tok == SYMBOL)
+                                                               {
+                                                                       if (expr(scaleexpr, &scaleval, &scaleattr, &scaleesym) != OK)
+                                                                               return error("scale factor expression must evaluate");
+                                                                       switch (scaleval)
+                                                                       {
+                                                                       case 1:
+                                                                               break;
+                                                                       case 2:
+                                                                               AnIXSIZ |= TIMES2;
+                                                                               break;
+                                                                       case 4:
+                                                                               AnIXSIZ |= TIMES4;
+                                                                               break;
+                                                                       case 8:
+                                                                               AnIXSIZ |= TIMES8;
+                                                                               break;
+                                                                       default:
+                                                                               goto badmode;
+                                                                       }
+                                                               }
+                                                               else if (*tok++ != CONST)
+                                                                       goto badmode;
+                                                               else
+                                                               {
+                                                                       switch ((int)*tok++)
+                                                                       {
+                                                                       case 1:
+                                                                               break;
+                                                                       case 2:
+                                                                               AnIXSIZ |= TIMES2;
+                                                                               break;
+                                                                       case 4:
+                                                                               AnIXSIZ |= TIMES4;
+                                                                               break;
+                                                                       case 8:
+                                                                               AnIXSIZ |= TIMES8;
+                                                                               break;
+                                                                       default:
+                                                                               goto badmode;
+                                                                       }
+
+                                                                       tok++;  // Take into account that constants are 64-bit
+                                                               }
+                                                       }
+
+                                                       if (*tok++ != ')')
+                                                               return error("Closing parenthesis missing on addressing mode");
+
+                                                       // Let's say that this is the closest to our case
+                                                       AMn = MEMPOST;
+                                                       goto AnOK;
+                                               }
+                                               else
+                                                       goto badmode;
+                                       }
+                                               
                                        AMn = AINDEXED;
                                        goto AMn_IXN;
                                }