From: ggn Date: Thu, 20 Jul 2017 09:21:20 +0000 (+0300) Subject: Various 020+ fixes. In brief, this commit fixes the following: X-Git-Tag: v2.1.0~115 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=commitdiff_plain;h=da0013df9438aa14e478544307e925462d398cb3 Various 020+ fixes. In brief, this commit fixes the following: - Fix warning for \! inside string - we might be evaluating a macro so it's legal. - Handle (Dn[.w][*scale],label[.l]) ea case. - Enable scale value in ea to be expression (evaluated) besides constant. - Fix for ([address[.wl]]). It seems that undefined symbols were not stored properly in eagen0.s (it used aNexpr instead of aNbexpr when storing base displacement). - Fixes for fmove freg,freg (no size suffix) and ftst freg (no size suffix). - fmovem now defaults to .x - Fixed muls.l --- diff --git a/68ktab b/68ktab index e250bf7..f8ba190 100644 --- a/68ktab +++ b/68ktab @@ -402,7 +402,7 @@ fmod NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fmod + - NX M_FREG M_AM_NONE %1111001000eeeeee m_fmod fmove NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fmove + - NBWLSQXP M_FREG C_ALL030 %1111001000eeeeee m_fmove + -- NBWLSQXP M_FREG M_FREG %1111001000eeeeee m_fmove + +- NX M_FREG M_FREG %1111001000eeeeee m_fmove + - NL M_FPSCR C_ALL030 %1111001000eeeeee m_fmovescr + - NL C_ALL030 M_FPSCR %1111001000eeeeee m_fmovescr + fsmove NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsmove @@ -502,7 +502,7 @@ ftentox NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_ftentox + - NX M_FREG M_FREG %1111001000eeeeee m_ftentox + - NX M_FREG M_AM_NONE %1111001000eeeeee m_ftentox ftst NBWLSQXP C_ALL030 M_AM_NONE %1111001000eeeeee m_ftst + -- X M_FREG M_AM_NONE %1111001000eeeeee m_ftst +- NX M_FREG M_AM_NONE %1111001000eeeeee m_ftst ftwotox NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_ftwotox + - NX M_FREG M_FREG %1111001000eeeeee m_ftwotox + - NX M_FREG M_AM_NONE %1111001000eeeeee m_ftwotox @@ -583,7 +583,8 @@ illegal N M_AM_NONE M_AM_NONE %0100101011111100 m_self jmp N C_CTRL M_AM_NONE %0100111011eee000 m_ea + - N C_CTRL030 M_AM_NONE %0100111011eee000 m_ea030 -jsr N C_CTRL M_AM_NONE %0100111010eee000 m_ea +jsr N C_CTRL M_AM_NONE %0100111010eee000 m_ea + +- N C_CTRL030 M_AM_NONE %0100111010eee000 m_ea030 lea NL C_CTRL M_AREG %0100rrr111eR1000 m_lea diff --git a/amode.h b/amode.h index f785b87..818c711 100644 --- a/amode.h +++ b/amode.h @@ -15,6 +15,8 @@ #define DREG 000 // Dn #define AREG 010 // An #define AIND 020 // (An) +#define DINDW 0112 // (Dn.w) +#define DINDL 0113 // (Dn.l) #define APOSTINC 030 // (An)+ #define APREDEC 040 // -(An) #define ADISP 050 // (d16,An) d16(An) diff --git a/eagen.c b/eagen.c index bf1f67a..de1ecb4 100644 --- a/eagen.c +++ b/eagen.c @@ -24,6 +24,7 @@ #define aNixsiz a0ixsiz #define AnESYM a0esym #define aNexten a0extension +#define aNbexpr a0bexpr #define aNbdexval a0bexval #define aNbdexattr a0bexattr #include "eagen0.c" @@ -37,6 +38,7 @@ #define aNixsiz a1ixsiz #define AnESYM a1esym #define aNexten a1extension +#define aNbexpr a1bexpr #define aNbdexval a1bexval #define aNbdexattr a1bexattr #include "eagen0.c" diff --git a/eagen0.c b/eagen0.c index 7fe382a..f01b989 100644 --- a/eagen0.c +++ b/eagen0.c @@ -251,6 +251,12 @@ int eaNgen(WORD siz) D_long(0); } + break; + case DINDW: + D_word(0x190|(aNixreg<<12)); + break; + case DINDL: + D_word(0x990|(aNixreg<<12)); break; case ABASE: case MEMPOST: @@ -281,7 +287,7 @@ int eaNgen(WORD siz) else { // Arrange for fixup later on - AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr); + AddFixup(FU_WORD|FU_SEXT, sloc, aNbexpr); D_word(0); } } @@ -299,7 +305,7 @@ int eaNgen(WORD siz) else { // Arrange for fixup later on - AddFixup(FU_LONG|FU_SEXT, sloc, aNexpr); + AddFixup(FU_LONG, sloc, aNbexpr); D_long(0); } } @@ -369,6 +375,7 @@ int eaNgen(WORD siz) #undef aNixreg #undef aNixsiz #undef aNexten +#undef aNbexpr #undef aNbdexval #undef aNbdexattr #undef AnESYM diff --git a/mach.c b/mach.c index 12abcc2..ac800eb 100644 --- a/mach.c +++ b/mach.c @@ -1391,7 +1391,7 @@ int m_cas(WORD inst, WORD siz) // 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) + 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; @@ -1409,7 +1409,6 @@ int m_cas(WORD inst, WORD siz) int m_cas2(WORD inst, WORD siz) { WORD inst2, inst3; - LONG amsk; if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0) return error(unsupport); @@ -1614,7 +1613,6 @@ int m_cpbr(WORD inst, WORD siz) { inst |= (1 << 6); D_word(inst); - WARNING(check what s "optional coprocessor-defined extension words!") D_long(v); return OK; } @@ -1625,7 +1623,6 @@ int m_cpbr(WORD inst, WORD siz) return error(range_error); D_word(inst); - WARNING(check what s "optional coprocessor-defined extension words!") D_word(v); } @@ -1753,6 +1750,11 @@ int m_muls(WORD inst, WORD siz) inst |= am1 | a1reg; // Get ea1 into instr D_word(inst); // Deposit instr + // Extension word + inst = a1reg + (a2reg << 12) + (1 << 11); + inst |= mulmode; // add size bit + D_word(inst); + // Generate ea0 if requested if (flg & 2) ea0gen(siz); @@ -1764,6 +1766,11 @@ int m_muls(WORD inst, WORD siz) // Use am0 inst |= am0 | a0reg; // Get ea0 into instr D_word(inst); // Deposit instr + // Extension word + inst = a1reg + (a2reg << 12) + (1 << 11); + inst |= mulmode; // add size bit + D_word(inst); + ea0gen(siz); // Generate ea0 // Generate ea1 if requested @@ -1771,9 +1778,8 @@ int m_muls(WORD inst, WORD siz) ea1gen(siz); } - inst = a1reg + (a2reg << 12) + (1 << 11); - inst |= mulmode; // add size bit - D_word(inst); + //D_word(inst); + //ea0gen(siz); return OK; } @@ -2419,6 +2425,7 @@ int m_pflushr(WORD inst, WORD siz) } D_word(B16(10100000, 00000000)); + return OK; } @@ -2934,6 +2941,7 @@ int m_fmove(WORD inst, WORD siz) // EA to register if ((am0 == FREG) && (am1 < AM_USP)) { + //fpx->ea // EA inst |= am1 | a1reg; D_word(inst); @@ -2982,6 +2990,8 @@ int m_fmove(WORD inst, WORD siz) } else if ((am0 < AM_USP) && (am1 == FREG)) { + //ea->fpx + // EA inst |= am0 | a0reg; D_word(inst); @@ -3016,6 +3026,9 @@ int m_fmove(WORD inst, WORD siz) } else if ((am0 == FREG) && (am1 == FREG)) { + // register-to-register + // Essentially ea to register with R/0=0 + // EA D_word(inst); @@ -3128,11 +3141,11 @@ int m_fmovem(WORD inst, WORD siz) WORD regmask; WORD datareg; - if (siz == SIZX) + if (siz == SIZX || siz==SIZN) { if ((*tok >= KW_FP0) && (*tok <= KW_FP7)) { - // fmovem.x ,ea + //fmovem.x ,ea if (fpu_reglist_left(®mask) < 0) return OK; @@ -3210,7 +3223,7 @@ int m_fmovem(WORD inst, WORD siz) } } } - else if ((siz == SIZL) || (siz==SIZN)) + else if (siz == SIZL) { if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR)) { diff --git a/parmode.h b/parmode.h index 5ad5da9..e623084 100644 --- a/parmode.h +++ b/parmode.h @@ -92,16 +92,16 @@ else if (*tok == 'L') { // TODO: does DINDL gets used at all? - //AMn=DINDL; // (Dn.l) - //AnEXTEN = 1 << 1; // Long index size - //tok++; + AMn=DINDL; // (Dn.l) + 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++; + AMn=DINDW; + AnEXTEN = 1 << 1; // Word index size + tok++; } else if (*tok == ',') { @@ -115,7 +115,57 @@ goto CHECKODn; } else + { return error("(Dn) error"); + } + + if (*tok == '*') + { // scale: *1, *2, *4, *8 + tok++; + + if (*tok == SYMBOL) + { + if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) + return error("scale factor expression must evaluate"); + switch (AnEXVAL) + { + 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 || *tok > 8) + 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; + } + } + } if (*tok == ')') { @@ -128,6 +178,14 @@ AMn = MEMPOST; goto AnOK; } + else if (*tok==',') + { + tok++; // eat the comma + // It might be (Dn[.wl][*scale],od) + // Maybe this is wrong and we have to write some code here + // instead of reusing that path... + goto CHECKODn; + } else return error("unhandled so far"); } @@ -170,30 +228,58 @@ } if (*tok == '*') - { // scale: *1, *2, *4, *8 + { // scale: *1, *2, *4, *8 tok++; - if (*tok++ != CONST || *tok > 8) - goto badmode; - - switch ((int)*tok++) - { - case 1: - break; - case 2: - AnIXSIZ |= TIMES2; - break; - case 4: - AnIXSIZ |= TIMES4; - break; - case 8: - AnIXSIZ |= TIMES8; - break; - default: + if (*tok == SYMBOL) + { + if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) + return error("scale factor expression must evaluate"); + switch (AnEXVAL) + { + 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 || *tok > 8) 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; + } } } + if (*tok == ',') + { + tok++; + goto CHECKODn; + } if (*tok++ != ')') // final ")" goto badmode; @@ -302,30 +388,52 @@ // Check for scale if (*tok == '*') // ([bd,An/PC],Xn*...) - { + { // scale: *1, *2, *4, *8 tok++; - 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++) + if (*tok == SYMBOL) { - case 1: - break; - case 2: - AnEXTEN |= EXT_TIMES2; - break; - case 4: - AnEXTEN |= EXT_TIMES4; - break; - case 8: - AnEXTEN |= EXT_TIMES8; - break; - default: + if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) + return error("scale factor expression must evaluate"); + switch (AnEXVAL) + { + 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 || *tok > 8) 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; + } } } - if (*tok == ']') // ([bd,Dn]... { tok++; @@ -354,9 +462,9 @@ if (*tok == ')') { //Xn and od are non existent, get out of jail free card + tok++; 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 != ',') @@ -406,29 +514,51 @@ } // Check for scale - if (*tok == '*') - { - // ([bd,An/PC],Xn*...) + if (*tok == '*') // ([bd,An/PC],Xn*...) + { // scale: *1, *2, *4, *8 tok++; - 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++) + if (*tok == SYMBOL) + { + if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) + return error("scale factor expression must evaluate"); + switch (AnEXVAL) { case 1: break; case 2: - AnEXTEN |= EXT_TIMES2; + AnIXSIZ |= TIMES2; break; case 4: - AnEXTEN |= EXT_TIMES4; + AnIXSIZ |= TIMES4; break; case 8: - AnEXTEN |= EXT_TIMES8; + AnIXSIZ |= TIMES8; break; default: goto badmode; + } + } + else if (*tok++ != CONST || *tok > 8) + 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; + } } } @@ -447,7 +577,6 @@ tok++; // eat the comma CHECKODn: - if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) goto badmode; @@ -459,13 +588,13 @@ tok++; goto AnOK; } - // ([bd,An/PC],Xn,od) if (*tok == DOTL) { // expr.L AnEXTEN |= EXT_IISPOSL; // Long outer displacement AMn = MEMPOST; + tok++; // Defined, absolute values from $FFFF8000..$00007FFF get // optimized to absolute short @@ -544,7 +673,6 @@ // expr[.W][] AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed AMn = MEMPRE; - if (*tok == DOTW) { //AnEXTEN|=EXT_IISNOIW; // Word outer displacement @@ -613,34 +741,56 @@ // Check for scale if (*tok == '*') // ([bd,An/PC],Xn*...) - { + { // scale: *1, *2, *4, *8 tok++; - 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++) + if (*tok == SYMBOL) { - case 1: - break; - case 2: - AnEXTEN |= EXT_TIMES2; - break; - case 4: - AnEXTEN |= EXT_TIMES4; - break; - case 8: - AnEXTEN |= EXT_TIMES8; - break; - default: + if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) + return error("scale factor expression must evaluate"); + switch (AnEXVAL) + { + 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 || *tok > 8) 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; + } } } //Check for ] if (*tok != ']') return error("Expected closing bracket ]"); - tok++; // Eat the bracket //Check for od @@ -805,7 +955,6 @@ // After a cache keyword only a comma or EOL is allowed if ((*tok != ',') && (*tok != EOL)) return ERROR; - goto AnOK; } else if ((*tok >= KW_SFC) && (*tok <= KW_CRP))