- 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
- 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 +
- 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
- 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
- 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 +
- 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
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
jmp N C_CTRL M_AM_NONE %0100111011eee000 m_ea +
- N C_CTRL030 M_AM_NONE %0100111011eee000 m_ea030
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
lea NL C_CTRL M_AREG %0100rrr111eR1000 m_lea
#define DREG 000 // Dn
#define AREG 010 // An
#define AIND 020 // (An)
#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)
#define APOSTINC 030 // (An)+
#define APREDEC 040 // -(An)
#define ADISP 050 // (d16,An) d16(An)
#define aNixsiz a0ixsiz
#define AnESYM a0esym
#define aNexten a0extension
#define aNixsiz a0ixsiz
#define AnESYM a0esym
#define aNexten a0extension
#define aNbdexval a0bexval
#define aNbdexattr a0bexattr
#include "eagen0.c"
#define aNbdexval a0bexval
#define aNbdexattr a0bexattr
#include "eagen0.c"
#define aNixsiz a1ixsiz
#define AnESYM a1esym
#define aNexten a1extension
#define aNixsiz a1ixsiz
#define AnESYM a1esym
#define aNexten a1extension
#define aNbdexval a1bexval
#define aNbdexattr a1bexattr
#include "eagen0.c"
#define aNbdexval a1bexval
#define aNbdexattr a1bexattr
#include "eagen0.c"
+ break;
+ case DINDW:
+ D_word(0x190|(aNixreg<<12));
+ break;
+ case DINDL:
+ D_word(0x990|(aNixreg<<12));
break;
case ABASE:
case MEMPOST:
break;
case ABASE:
case MEMPOST:
else
{
// Arrange for fixup later on
else
{
// Arrange for fixup later on
- AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+ AddFixup(FU_WORD|FU_SEXT, sloc, aNbexpr);
else
{
// Arrange for fixup later on
else
{
// Arrange for fixup later on
- AddFixup(FU_LONG|FU_SEXT, sloc, aNexpr);
+ AddFixup(FU_LONG, sloc, aNbexpr);
#undef aNixreg
#undef aNixsiz
#undef aNexten
#undef aNixreg
#undef aNixsiz
#undef aNexten
#undef aNbdexval
#undef aNbdexattr
#undef AnESYM
#undef aNbdexval
#undef aNbdexattr
#undef AnESYM
// 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)
+ 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;
return error("unsupported addressing mode");
inst |= am0 | a0reg;
int m_cas2(WORD inst, WORD siz)
{
WORD inst2, inst3;
int m_cas2(WORD inst, WORD siz)
{
WORD inst2, inst3;
if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
return error(unsupport);
if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
return error(unsupport);
{
inst |= (1 << 6);
D_word(inst);
{
inst |= (1 << 6);
D_word(inst);
- WARNING(check what s "optional coprocessor-defined extension words!")
return error(range_error);
D_word(inst);
return error(range_error);
D_word(inst);
- WARNING(check what s "optional coprocessor-defined extension words!")
inst |= am1 | a1reg; // Get ea1 into instr
D_word(inst); // Deposit instr
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);
// Generate ea0 if requested
if (flg & 2)
ea0gen(siz);
// Use am0
inst |= am0 | a0reg; // Get ea0 into instr
D_word(inst); // Deposit instr
// 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
ea0gen(siz); // Generate ea0
// Generate ea1 if requested
- inst = a1reg + (a2reg << 12) + (1 << 11);
- inst |= mulmode; // add size bit
- D_word(inst);
+ //D_word(inst);
+ //ea0gen(siz);
}
D_word(B16(10100000, 00000000));
}
D_word(B16(10100000, 00000000));
// EA to register
if ((am0 == FREG) && (am1 < AM_USP))
{
// EA to register
if ((am0 == FREG) && (am1 < AM_USP))
{
// EA
inst |= am1 | a1reg;
D_word(inst);
// EA
inst |= am1 | a1reg;
D_word(inst);
}
else if ((am0 < AM_USP) && (am1 == FREG))
{
}
else if ((am0 < AM_USP) && (am1 == FREG))
{
// EA
inst |= am0 | a0reg;
D_word(inst);
// EA
inst |= am0 | a0reg;
D_word(inst);
}
else if ((am0 == FREG) && (am1 == FREG))
{
}
else if ((am0 == FREG) && (am1 == FREG))
{
+ // register-to-register
+ // Essentially ea to register with R/0=0
+
WORD regmask;
WORD datareg;
WORD regmask;
WORD datareg;
+ if (siz == SIZX || siz==SIZN)
{
if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
{
{
if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
{
if (fpu_reglist_left(®mask) < 0)
return OK;
if (fpu_reglist_left(®mask) < 0)
return OK;
- else if ((siz == SIZL) || (siz==SIZN))
{
if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
{
{
if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
{
else if (*tok == 'L')
{
// TODO: does DINDL gets used at all?
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?
}
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 == ',')
{
}
else if (*tok == ',')
{
return error("(Dn) error");
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;
+ }
+ }
+ }
AMn = MEMPOST;
goto AnOK;
}
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");
}
else
return error("unhandled so far");
}
- { // scale: *1, *2, *4, *8
+ { // scale: *1, *2, *4, *8
- 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)
+ 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;
if (*tok++ != ')') // final ")"
goto badmode;
// Check for scale
if (*tok == '*') // ([bd,An/PC],Xn*...)
// Check for scale
if (*tok == '*') // ([bd,An/PC],Xn*...)
+ { // scale: *1, *2, *4, *8
- 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;
- 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)
+ 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++;
if (*tok == ']') // ([bd,Dn]...
{
tok++;
if (*tok == ')')
{
//Xn and od are non existent, get out of jail free card
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
AMn = MEMPRE; // ([bc,An,Xn],od) with no Xn and od
AnEXTEN |= EXT_IS | EXT_IISPREN; //Suppress Xn and od
goto AnOK;
}
else if (*tok != ',')
goto AnOK;
}
else if (*tok != ',')
- if (*tok == '*')
- {
- // ([bd,An/PC],Xn*...)
+ if (*tok == '*') // ([bd,An/PC],Xn*...)
+ { // scale: *1, *2, *4, *8
- 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)
break;
default:
goto badmode;
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;
+ }
tok++; // eat the comma
CHECKODn:
tok++; // eat the comma
CHECKODn:
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
goto badmode;
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
goto badmode;
// ([bd,An/PC],Xn,od)
if (*tok == DOTL)
{
// expr.L
AnEXTEN |= EXT_IISPOSL; // Long outer displacement
AMn = MEMPOST;
// ([bd,An/PC],Xn,od)
if (*tok == DOTL)
{
// expr.L
AnEXTEN |= EXT_IISPOSL; // Long outer displacement
AMn = MEMPOST;
// Defined, absolute values from $FFFF8000..$00007FFF get
// optimized to absolute short
// Defined, absolute values from $FFFF8000..$00007FFF get
// optimized to absolute short
// expr[.W][]
AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed
AMn = MEMPRE;
// expr[.W][]
AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed
AMn = MEMPRE;
if (*tok == DOTW)
{
//AnEXTEN|=EXT_IISNOIW; // Word outer displacement
if (*tok == DOTW)
{
//AnEXTEN|=EXT_IISNOIW; // Word outer displacement
// Check for scale
if (*tok == '*') // ([bd,An/PC],Xn*...)
// Check for scale
if (*tok == '*') // ([bd,An/PC],Xn*...)
+ { // scale: *1, *2, *4, *8
- 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;
- 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)
+ 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 ]");
}
}
//Check for ]
if (*tok != ']')
return error("Expected closing bracket ]");
tok++; // Eat the bracket
//Check for od
tok++; // Eat the bracket
//Check for od
// After a cache keyword only a comma or EOL is allowed
if ((*tok != ',') && (*tok != EOL))
return ERROR;
// 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))
goto AnOK;
}
else if ((*tok >= KW_SFC) && (*tok <= KW_CRP))