{
if (*AnEXVAL > 0x3F)
{
- if (optim_warn_flag)
- warn("short addressing mode forced but address is bigger than $3F - switching to long");
+ if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+ {
+ if (optim_warn_flag)
+ warn("o11: short addressing mode forced but address is bigger than $3F - switching to long");
- *am = M_DSPEA;
- *memspace = 1 << 6; // Mark we're on Y memory space
- *areg = DSP_EA_ABS;
- return OK;
+ *am = M_DSPEA;
+ *memspace = 1 << 6; // Mark we're on Y memory space
+ *areg = DSP_EA_ABS;
+ return OK;
+ }
+ else
+ {
+ return error("short addressing mode forced but address is bigger than $3F - turn opt switch o11 on to bypass");
+ }
}
}
else
{
if (dspImmedEXVAL > 0x3F)
{
- if (optim_warn_flag)
- warn("short addressing mode forced but address is bigger than $3F - switching to long");
+ if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+ {
+ if (optim_warn_flag)
+ warn("o11: short addressing mode forced but address is bigger than $3F - switching to long");
- force_imm = NUM_FORCE_LONG;
- deposit_extra_ea = DEPOSIT_EXTRA_WORD;
- ea1 = DSP_EA_ABS;
+ force_imm = NUM_FORCE_LONG;
+ deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+ ea1 = DSP_EA_ABS;
+ }
+ else
+ {
+ return error("short addressing mode forced but address is bigger than $3F - turn opt switch o11 on to bypass");
+ }
}
}
else
{
// We're in 'S1,D1 Y:ea,D2' or 'S1,D1 S1,Y:ea'
// there's no Y:aa mode here, so we'll force long
- if (optim_warn_flag)
- warn("forced short addressing in R:Y mode is not allowed - switching to long");
+ if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+ {
+ if (optim_warn_flag)
+ warn("forced short addressing in R:Y mode is not allowed - switching to long");
- if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
- return ERROR;
+ if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+ return ERROR;
- ea1 = DSP_EA_ABS;
+ ea1 = DSP_EA_ABS;
- force_imm = NUM_FORCE_LONG;
- deposit_extra_ea = DEPOSIT_EXTRA_WORD;
- goto y_check_immed;
+ force_imm = NUM_FORCE_LONG;
+ deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+ goto y_check_immed;
+ }
+ else
+ {
+ return error("forced short addressing in R:Y mode is not allowed - turn opt switch o11 on to bypass");
+ }
}
else
{
{
if (dspImmedEXVAL > 0xFFF)
{
- if (optim_warn_flag)
- warn("short addressing mode forced but address is bigger than $FFF - switching to long");
+ if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+ {
+ if (optim_warn_flag)
+ warn("short addressing mode forced but address is bigger than $FFF - switching to long");
- ea1 = DSP_EA_ABS;
- force_imm = NUM_FORCE_LONG;
- deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+ ea1 = DSP_EA_ABS;
+ force_imm = NUM_FORCE_LONG;
+ deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+ }
+ else
+ {
+ return error("short addressing mode forced but address is bigger than $FFF - turn opt switch o11 on to bypass");
+ }
}
}
else
}
else
{
- if (optim_warn_flag)
- warn("forced short immediate value doesn't fit in 8 bits - switching to long");
- force_imm = NUM_FORCE_LONG;
+ if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+ {
+ if (optim_warn_flag)
+ warn("forced short immediate value doesn't fit in 8 bits - switching to long");
+ force_imm = NUM_FORCE_LONG;
+ }
+ else
+ {
+ return error("forced short immediate value doesn't fit in 8 bits - turn opt switch o11 on to bypass");
+ }
}
}
{
double f = *(double *)&dspImmedEXVAL;
// Check direct.c for ossom comments regarding conversion!
-//N.B.: This is bogus, we need to fix this so it does this the right way... !!! FIX !!!
+ //N.B.: This is bogus, we need to fix this so it does this the right way... !!! FIX !!!
dspImmedEXVAL = ((uint32_t)(int32_t)round(f * (1 << 23))) & 0xFFFFFF;
double g;
g = f * (1 << 23);
if ((dspImmedEXVAL & 0xFFFF) == 0)
{
- // Value's 16 lower bits are not set so the value can
- // fit in a single byte (check parallel I move quoted
- // above)
- if (optim_warn_flag)
- warn("Immediate value fits inside 8 bits, so using instruction short format");
+ if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+ {
+ // Value's 16 lower bits are not set so the value can
+ // fit in a single byte (check parallel I move quoted
+ // above)
+ if (optim_warn_flag)
+ warn("o10: Immediate value fits inside 8 bits, so using instruction short format");
- dspImmedEXVAL >>= 16;
- goto deposit_immediate_short_with_register;
+ dspImmedEXVAL >>= 16;
+ goto deposit_immediate_short_with_register;
+ }
+ else
+ {
+ return error("Immediate value fits inside 8 bits, so using instruction short format - turn opt switch o11 on to bypass");
+ }
}
if (force_imm == NUM_FORCE_SHORT)
{
if ((dspImmedEXVAL & 0xFFFF) != 0)
{
- if (optim_warn_flag)
- warn("Immediate value short format forced but value does not fit inside 8 bits - switching to long format");
+ if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+ {
+ if (optim_warn_flag)
+ warn("Immediate value short format forced but value does not fit inside 8 bits - switching to long format");
- goto deposit_immediate_long_with_register;
+ goto deposit_immediate_long_with_register;
+ }
+ else
+ {
+ return error("Immediate value short format forced but value does not fit inside 8 bits - turn opt switch o11 on to bypass - turn opt switch o11 on to bypass");
+ }
}
return error("internal assembler error: we haven't implemented floating point constants in parallel mode parser yet!");
}
if (optim_warn_flag)
- warn("0(An) converted to (An)");
+ warn("o3: 0(An) converted to (An)");
return OK;
}
D_word(inst);
if (optim_warn_flag)
- warn("lea size(An),An converted to addq #size,An");
+ warn("o4: lea size(An),An converted to addq #size,An");
return OK;
}
return m_addq(B16(01010000, 00000000), siz);
if (optim_warn_flag)
- warn("adda/suba size(An),An converted to addq/subq #size,An");
+ warn("o8: adda/suba size(An),An converted to addq/subq #size,An");
}
}
optim_flags[OPT_LEA_ADDQ] = 1; // Temporarily save switch state
return_value = m_lea(B16(01000001, 11011000), SIZW);
optim_flags[OPT_LEA_ADDQ] = temp_flag; // Restore switch state
+ if (optim_warn_flag)
+ warn("o9: adda.w/l #x,Ay converted to lea x(Dy),Ay");
return return_value;
}
}
m_moveq((WORD)0x7000, (WORD)0);
if (optim_warn_flag)
- warn("move.l #size,dx converted to moveq");
+ warn("o1: move.l #size,dx converted to moveq");
}
else
{
D_word(inst);
if (optim_warn_flag)
- warn("Bcc.w/BSR.w converted to .s");
+ warn("o2: Bcc.w/BSR.w converted to .s");
return OK;
}
if (!CHECK_OPTS(OPT_CLR_DX))
inst |= a0reg;
else
+ {
inst = (a0reg << 9) | B16(01110000, 00000000);
+ if (optim_warn_flag)
+ warn("o7: clr.l Dx converted to moveq #0,Dx");
+ }
D_word(inst);
AnEXTEN |= EXT_BDSIZEW;
if (optim_warn_flag)
- warn("absolute value in base displacement ranging $FFFF8000..$00007FFF optimised to absolute short");
+ warn("o5: absolute value in base displacement ranging $FFFF8000..$00007FFF optimised to absolute short");
}
else
{
AMn = MEMPOST + ea_PC;
if (optim_warn_flag)
- warn("absolute value in outer displacement ranging $FFFF8000..$00007FFF optimised to absolute short");
+ warn("o5: absolute value in outer displacement ranging $FFFF8000..$00007FFF optimised to absolute short");
}
AnEXTEN |= od_ea;
}
{
//AnEXTEN|=EXT_IISNOIW; // Word outer displacement with IS suppressed
if (optim_warn_flag)
- warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
+ warn("o5: outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
}
}
expr_size = EXT_IISPREW;
if (optim_warn_flag)
- warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
+ warn("o5: outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
}
}
// When PC relative is enforced, check for any symbols that aren't
// EQU'd, in this case it's an illegal mode
if ((CHECK_OPTS(OPT_PC_RELATIVE)) && (AnEXATTR & (DEFINED | REFERENCED | EQUATED) == (DEFINED | REFERENCED)))
- return error("relocation not allowed when o10 is enabled9");
+ return error("relocation not allowed when o30 is enabled");
tok++;
}
AMn = ABSW;
if (optim_warn_flag)
- warn("absolute value from $FFFF8000..$00007FFF optimised to absolute short");
+ warn("o0: absolute value from $FFFF8000..$00007FFF optimised to absolute short");
}
}
char searchpatha[512] = { 0 }; // Buffer to hold searchpath when specified
char * searchpath = NULL; // Search path for include files
char defname[] = "noname.o"; // Default output filename
-int optim_flags[OPT_COUNT_ALL]; // Specific optimisations on/off matrix
+int optim_flags[OPT_COUNT_ALL] = { 0 }; // Specific optimisations on/off matrix
int activecpu = CPU_68000; // Active 68k CPU (68000 by default)
int activefpu = FPU_NONE; // Active FPU (none by default)
int org68k_active = 0; // .org switch for 68k (only with RAW output format)
" -n Don't do things behind your back in RISC assembler\n"
" -o file Output file name\n"
" +o[value] Turn a specific optimisation on\n"
- " Available optimisation values and default settings:\n"
- " o0: Absolute long addresses to word (on)\n"
- " o1: move.l #x,dn/an to moveq (on)\n"
- " o2: Word branches to short (on)\n"
- " o3: Outer displacement 0(an) to (an) (off)\n"
- " o4: lea size(An),An to addq #size,An (off)\n"
- " o5: 68020+ Absolute long base/outer disp. to word (off)\n"
- " o6: Null branches to NOP (off)\n"
- " o7: clr.l Dx to moveq #0,Dx (off)\n"
- " o8: adda.w/l #x,Dy to addq.w/l #x,Dy (off)\n"
- " o9: adda.w/l #x,Dy to lea x(Dy),Dy (off)\n"
- " o10: Enforce PC relative (alternative: op) (off)\n"
+ " Available optimisation switches:\n"
+ " o0: Absolute long addresses to word\n"
+ " o1: move.l #x,dn/an to moveq\n"
+ " o2: Word branches to short\n"
+ " o3: Outer displacement 0(an) to (an)\n"
+ " o4: lea size(An),An to addq #size,An\n"
+ " o5: 68020+ Absolute long base/outer disp. to word\n"
+ " o6: Null branches to NOP\n"
+ " o7: clr.l Dx to moveq #0,Dx\n"
+ " o8: adda.w/l #x,Dy to addq.w/l #x,Dy\n"
+ " o9: adda.w/l #x,Ay to lea x(Dy),Ay\n"
+ " o10: 56001 Use short format for immediate values if possible\n"
+ " o11: 56001 Auto convert short addressing mode to long (default: on)\n"
+ " o30: Enforce PC relative (alternative name: op)\n"
" ~o[value] Turn a specific optimisation off\n"
" +oall Turn all optimisations on\n"
" ~oall Turn all optimisations off\n"
perm_verb_flag = 0; // Clobber "permanent" verbose flag
legacy_flag = 1; // Default is legacy mode on (:-P)
- // Set all optimisation flags to off
- memset(optim_flags, 0, OPT_COUNT * sizeof(int));
-
cmdlnexec = argv[0]; // Obtain executable name
endian = GetEndianess(); // Get processor endianess
OPT_CLR_DX = 7,
OPT_ADDA_ADDQ = 8,
OPT_ADDA_LEA = 9,
+ OPT_56K_SHORT = 10,
+ OPT_56K_AUTO_LONG = 11,
OPT_COUNT, // Dummy, used to count number of optimisation switches
// These will be unaffected by "Oall"
- OPT_PC_RELATIVE = 11, // Enforce PC relative
+ OPT_PC_RELATIVE = 30, // Enforce PC relative
OPT_COUNT_ALL // Dummy, used to count all switches
};
if ((CHECK_OPTS(OPT_PC_RELATIVE)) && (eattr & (DEFINED | REFERENCED | EQUATED)) == (DEFINED | REFERENCED))
{
- error("relocation not allowed when o10 is enabled");
+ error("relocation not allowed when o30 is enabled");
continue;
}
}
if ((CHECK_OPTS(OPT_PC_RELATIVE)) && (eattr & (DEFINED | REFERENCED | EQUATED)) == (DEFINED | REFERENCED))
{
- error("relocation not allowed when o10 is enabled");
+ error("relocation not allowed when o30 is enabled");
continue;
}
*locp = 0x71;
if (optim_warn_flag)
- warn("bra.s with zero offset converted to NOP");
+ warn("o6: bra.s with zero offset converted to NOP");
continue;
}