//
// RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
// PARMODE.C - Addressing Modes Parser Include
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
-// Source Utilised with the Kind Permission of Landon Dyer
+// Source utilised with the kind permission of Landon Dyer
//
// This file is included (twice) to parse two addressing modes, into slightly
AMn = IMMED;
}
+
+ // Small problem with this is that the opening parentheses might be an
+ // expression that's part of a displacement; this code will falsely flag
+ // that as an error.
+
// (An)
// (An)+
// (An,Xn[.siz][*scale])
}
AMn = AINDEXED;
- goto AMn_IX0; // Handle ",Xn[.siz][*scale])"
+ goto AMn_IX0; // Handle ",Xn[.siz][*scale])"
}
else if (*tok == KW_PC)
- { // (PC,Xn[.siz][*scale])
+ { // (PC,Xn[.siz][*scale])
tok++;
AMn = PCINDEXED;
- // Common index handler; enter here with `tok' pointing at the comma.
+ // Common index handler; enter here with 'tok' pointing at the
+ // comma.
- AMn_IX0: // Handle indexed with missing expr
+ AMn_IX0: // Handle indexed with missing expr
AnEXVAL = 0;
AnEXATTR = ABS | DEFINED;
- AMn_IXN: // Handle any indexed (tok -> a comma)
+ AMn_IXN: // Handle any indexed (tok -> a comma)
if (*tok++ != ',')
goto badmode;
AnIXREG = *tok++ & 15;
switch ((int)*tok)
- { // Index reg size: <empty> | .W | .L
+ { // Index reg size: <empty> | .W | .L
case DOTW:
tok++;
default:
AnIXSIZ = 0x0800;
tok++;
break;
- case DOTB: // .B not allowed here...
+ case DOTB: // .B not allowed here...
goto badmode;
}
if (*tok == '*')
- { // scale: *1, *2, *4, *8
+ { // scale: *1, *2, *4, *8
tok++;
if (*tok++ != CONST || *tok > 8)
}
}
- if (*tok++ != ')') // final ")"
+ if (*tok++ != ')') // final ")"
goto badmode;
goto AnOK;
}
else if (*tok == '[')
- { // ([...
+ { // ([...
goto unmode;
}
else
- { // (expr...
+ { // (expr...
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
return ERROR;
+ // It could be that this is really just an expression prefixing a
+ // register as a displacement...
+ if (*tok == ')')
+ {
+ tok++;
+ goto CHK_FOR_DISPn;
+ }
+
+ // Otherwise, check for PC & etc displacements...
if (*tok++ != ',')
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;
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
return ERROR;
+CHK_FOR_DISPn:
if (*tok == DOTW)
{
- // expr.W
+ // expr.W
tok++;
AMn = ABSW;
+
+ if ((AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL < 0x10000))
+ AnEXVAL = (int32_t)(int16_t)AnEXVAL; // Sign extend value
+
goto AnOK;
}
else if (*tok != '(')
// Defined, absolute values from $FFFF8000..$00007FFF get optimized
// to absolute short
- if ((AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
+ if (optim_flags[OPT_ABS_SHORT] && (AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
+ {
AMn = ABSW;
+ if (sbra_flag)
+ warn("absolute value from $FFFF8000..$00007FFF optimised to absolute short");
+ }
+
// Is .L forced here?
if (*tok == DOTL)
{
;
}
-// Cleanup dirty little macros
+// Clean up dirty little macros
#undef AnOK
#undef AMn
#undef AnREG
#undef AnESYM
#undef AMn_IX0
#undef AMn_IXN
+#undef CHK_FOR_DISPn