if (tdb)
rmark(cursect, sloc, tdb, MWORD, NULL);
+ if ((v == 0) && optim_flag)
+ {
+ // If expr is 0, size optimise the opcode.
+ // Generally the lower 6 bits of the opcode
+ // for expr(ax) are 101rrr where rrr=the
+ // number of the register, then followed by
+ // a word containing 'expr'. We need to change
+ // that to 010rrr.
+ if ((siz & 0x8000) == 0)
+ {
+ chptr_opcode[0] &= ((0xFFC7 >> 8) & 255); // mask off bits
+ chptr_opcode[1] &= 0xFFC7 & 255; // mask off bits
+ chptr_opcode[0] |= ((0x0010 >> 8) & 255); // slap in 010 bits
+ chptr_opcode[1] |= 0x0010 & 255; // slap in 010 bits
+ }
+ else
+ {
+ // Special case for move ea,ea:
+ // there are two ea fields there and
+ // we get a signal if it's the second ea field
+ // from m_ea - siz's 16th bit is set
+ chptr_opcode[0] &= ((0xFE3F >> 8) & 255); // mask off bits
+ chptr_opcode[1] &= 0xFE3F & 255; // mask off bits
+ chptr_opcode[0] |= ((0x0080 >> 8) & 255); // slap in 010 bits
+ chptr_opcode[1] |= 0x0080 & 255; // slap in 010 bits
+ }
+ return OK;
+ }
+
if (v + 0x8000 >= 0x18000)
return error(range_error);
if (v + 0x80 >= 0x100)
return error(range_error);
- w |= v & 0xff;
+ w |= v & 0xFF;
D_word(w);
}
else
ea0gen((WORD)siz);
if (am1 >= ADISP)
- ea1gen((WORD)siz);
+ ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea
}
return 0;
}
// Write requested object file...
- if (obj_format==BSD || (obj_format==ALCYON && prg_flag==0))
+ if ((obj_format == BSD) || ((obj_format == ALCYON) && (prg_flag == 0)))
{
+ // Force BSD format from here onwards
+ obj_format = BSD;
+
if (verb_flag)
{
printf("Total : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc);
}
+
ssize = ((LONG)sy_assign(NULL, NULL)); // Assign index numbers to the symbols
tds = sect[TEXT].sloc + sect[DATA].sloc; // Get size of TEXT and DATA segment
buf = malloc(0x600000); // Allocate 6mb object file image memory
}
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])
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;
goto unmode;
}
else
- { // (expr...
+ { // (expr...
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
return ERROR;
}
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;
// 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 != '(')
if (optim_flag && (AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
{
AMn = ABSW;
+
if (sbra_flag)
warn("absolute value from $FFFF8000..$00007FFF optimised to absolute short");
}
goto loop;
}
+ // Keep a backup of chptr (used for optimisations during codegen)
+ chptr_opcode = chptr;
+
for(;;)
{
if ((m->mnattr & siz) && (amsk0 & m->mn0) != 0 && (amsk1 & m->mn1) != 0)
//this is probably going to explode spectacularly. Let's wait for the fireworks!
#define DO_PRAGMA(x) _Pragma (#x)
#define WARNING(desc) DO_PRAGMA(message (#desc))
+ #define inline __inline
#endif
LONG challoc; // # bytes alloc'd to code chunk
LONG ch_size; // # bytes used in code chunk
char * chptr; // Deposit point in code chunk buffer
+char * chptr_opcode; // Backup of chptr, updated before entering code generators
CHUNK * sfix; // Current (last) fixup chunk
LONG fchalloc; // # bytes alloc'd to fixup chunk
extern LONG sloc;
extern WORD scattr;
extern char * chptr;
+extern char * chptr_opcode;
extern LONG ch_size;
extern int cursect;
extern SECT sect[];
// auto-optimise? I think it's ok for now...
if (*ln == '.')
{
- if (obj_format == ALCYON)
- {
- if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B') || (*(ln + 1) == 'w') || (*(ln + 1) == 'W') || (*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
- {
- ln += 2;
- }
- }
- else
+ if (obj_format == BSD)
{
if ((*(ln + 1) & 0xDF) == 'B')
{
*tk++ = CONST;
*tk++ = v;
+
+ if (obj_format == ALCYON)
+ {
+ if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W'))
+ {
+ *tk++ = DOTW;
+ ln += 2;
+ }
+ else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
+ {
+ *tk++ = DOTL;
+ ln += 2;
+ }
+ }
}
else
*tk++ = '$';
#define MAJOR 1 // Major version number
#define MINOR 4 // Minor version number
-#define PATCH 13 // Patch release number
+#define PATCH 14 // Patch release number
#endif // __VERSION_H__