//
-// RMAC - Reboot's Macro Assembler for all Atari computers
+// RMAC - Renamed Macro Assembler for all Atari computers
// MACH.C - Code Generation
-// Copyright (C) 199x Landon Dyer, 2011-2020 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2021 Reboot and Friends
// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
// Source utilised with the kind permission of Landon Dyer
//
&& ((am0 == ADISP) && (a0reg == a1reg) && (a0exattr & DEFINED))
&& ((a0exval > 0) && (a0exval <= 8)))
{
- inst = B16(01010000, 01001000) | (((uint16_t)a0exval & 7) << 9) | (a0reg);
+ inst = 0b0101000001001000 | (((uint16_t)a0exval & 7) << 9) | (a0reg);
D_word(inst);
- warn("lea size(An),An converted to addq #size,An");
+
+ if (optim_warn_flag)
+ warn("o4: lea size(An),An converted to addq #size,An");
+
return OK;
}
//
int m_adda(WORD inst, WORD siz)
{
- if (a0exattr & DEFINED)
+ if ((a0exattr & DEFINED) && (am0 == IMMED))
{
- if (CHECK_OPTS(OPT_ADDA_ADDQ))
- if (a0exval > 1 && a0exval <= 8)
+ if (CHECK_OPTS(OPT_ADDA_ADDQ))
+ {
+ if ((a0exval > 1) && (a0exval <= 8))
+ {
// Immediate is between 1 and 8 so let's convert to addq
- return m_addq(B16(01010000, 00000000), siz);
- if (CHECK_OPTS(OPT_ADDA_LEA))
- if (a0exval > 8)
- {
- // Immediate is larger than 8 so let's convert to lea
- am0 = ADISP; // Change addressing mode
- a0reg = a1reg; // In ADISP a0reg is used instead of a1reg!
- return m_lea(B16(01000001, 11011000), SIZW);
+ return m_addq(0b0101000000000000, siz);
+
+ if (optim_warn_flag)
+ warn("o8: adda/suba size(An),An converted to addq/subq #size,An");
+ }
+ }
+
+ if (CHECK_OPTS(OPT_ADDA_LEA))
+ {
+ if ((a0exval > 8) && ((a0exval + 0x8000) < 0x10000))
+ {
+ // Immediate is larger than 8 and word size so let's convert to lea
+ am0 = ADISP; // Change addressing mode
+ a0reg = a1reg; // In ADISP a0reg is used instead of a1reg!
+
+ if (!(inst & (1 << 14)))
+ {
+ // We have a suba #x,AREG so let's negate the value
+ a0exval = -a0exval;
+ }
+
+ // We're going to rely on +o4 for this, so let's ensure that
+ // it's on, even just for this instruction
+ int return_value;
+ int temp_flag = optim_flags[OPT_LEA_ADDQ];
+ optim_flags[OPT_LEA_ADDQ] = 1; // Temporarily save switch state
+ return_value = m_lea(0b0100000111011000, 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 (sbra_flag)
- warn("move.l #size,dx converted to moveq");
+ if (optim_warn_flag)
+ warn("o1: move.l #size,dx converted to moveq");
}
else
{
int m_move30(WORD inst, WORD size)
{
int siz = (int)size;
- inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE];
+
+ if (am0 > ABASE)
+ inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE];
+ else
+ inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am1 - ABASE] << 3;
D_word(inst);
inst |= v & 0xFF;
D_word(inst);
- if (sbra_flag)
- warn("Bcc.w/BSR.w converted to .s");
+ if (optim_warn_flag)
+ warn("o2: Bcc.w/BSR.w converted to .s");
return OK;
}
{
// .B
AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
- D_word(inst);
+ // So here we have a small issue: this bra.s could be zero offset, but
+ // we can never know. Because unless we know beforehand that the
+ // offset will be zero (i.e. "bra.s +0"), it's going to be a label
+ // below this instruction! We do have an optimisation flag that can
+ // check against this during fixups, but we cannot rely on the state
+ // of the flag after all the file(s) have been processed because its
+ // state might have changed multiple times during file parsing. (Yes,
+ // there's a very low chance that this will ever happen but it's not
+ // zero!). So, we can use the byte that is going to be filled during
+ // fixups to store the state of the optimisation flag and read it
+ // during that stage so each bra.s will have its state stored neatly.
+ // Sleazy? Eh, who cares, like this will ever happen ;)
+ // One final note: we'd better be damn sure that the flag's value is
+ // less than 256 or magical stuff will happen!
+ D_word(inst | optim_flags[OPT_NULL_BRA]);
return OK;
}
else
if (!CHECK_OPTS(OPT_CLR_DX))
inst |= a0reg;
else
- inst = (a0reg << 9) | B16(01110000, 00000000);
+ {
+ inst = (a0reg << 9) | 0b0111000000000000;
+ if (optim_warn_flag)
+ warn("o7: clr.l Dx converted to moveq #0,Dx");
+ }
D_word(inst);
bfparam1 = bfval1 << 12;
//D_word((inst | am0 | a0reg | am1 | a1reg));
- if (inst == B16(11101111, 11000000))
+ if (inst == 0b1110111111000000)
{
// bfins special case
D_word((inst | am1 | a1reg));
ea0gen(siz); // Generate EA
// Second instruction word - Dest register (if exists), Do, Offset, Dw, Width
- if (inst == B16(11101111, 11000000))
+ if (inst == 0b1110111111000000)
{
// bfins special case
inst = bfparam1 | bfparam2;
}
else if (activecpu == CPU_68040)
{
- inst = B16(11110101, 00011000);
+ inst = 0b1111010100011000;
D_word(inst);
return OK;
}
ea1gen(siz);
}
- D_word(B16(10100000, 00000000));
+ D_word(0b1010000000000000);
return OK;
}
inst = 1;
else
return error("illegal control register specified");
-
break;
case DREG:
inst = (1 << 3) | a0reg;
int m_fabs(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00011000), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00011000, FPU_NOWARN);
}
{
CHECKNO40;
if (activefpu == FPU_68040)
- return gen_fpu(inst, siz, B8(01011000), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01011000, FPU_NOWARN);
return error("Unsupported in current FPU");
}
int m_fdabs(WORD inst, WORD siz)
{
if (activefpu == FPU_68040)
- return gen_fpu(inst, siz, B8(01011100), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01011100, FPU_NOWARN);
return error("Unsupported in current FPU");
}
int m_facos(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00011100), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00011100, FPU_FPSP);
}
int m_fadd(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00100010), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00100010, FPU_NOWARN);
}
int m_fsadd(WORD inst, WORD siz)
{
if (activefpu & (FPU_68040 | FPU_68060))
- return gen_fpu(inst, siz, B8(01100010), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01100010, FPU_NOWARN);
return error("Unsupported in current FPU");
}
int m_fdadd(WORD inst, WORD siz)
{
if (activefpu & (FPU_68040 | FPU_68060))
- return gen_fpu(inst, siz, B8(01100110), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01100110, FPU_NOWARN);
return error("Unsupported in current FPU");
}
int m_fasin(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00001100), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00001100, FPU_FPSP);
}
int m_fatan(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00001010), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00001010, FPU_FPSP);
}
int m_fatanh(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00001101), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00001101, FPU_FPSP);
}
int m_fcmp(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00111000), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00111000, FPU_FPSP);
}
int m_fcos(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00011101), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00011101, FPU_FPSP);
}
int m_fcosh(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00011001), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00011001, FPU_FPSP);
}
int m_fdiv(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00100000), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00100000, FPU_NOWARN);
}
int m_fsdiv(WORD inst, WORD siz)
{
if (activefpu & (FPU_68040 | FPU_68060))
- return gen_fpu(inst, siz, B8(01100000), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01100000, FPU_NOWARN);
return error("Unsupported in current FPU");
}
int m_fddiv(WORD inst, WORD siz)
{
if (activefpu & (FPU_68040 | FPU_68060))
- return gen_fpu(inst, siz, B8(01100100), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01100100, FPU_NOWARN);
return error("Unsupported in current FPU");
}
int m_fetox(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00010000), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00010000, FPU_FPSP);
}
int m_fetoxm1(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00001000), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00001000, FPU_FPSP);
}
int m_fgetexp(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00011110), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00011110, FPU_FPSP);
}
int m_fgetman(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00011111), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00011111, FPU_FPSP);
}
if (activefpu == FPU_68040)
warn("Instruction is emulated in 68040");
- return gen_fpu(inst, siz, B8(00000001), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00000001, FPU_NOWARN);
}
if (activefpu == FPU_68040)
warn("Instruction is emulated in 68040");
- return gen_fpu(inst, siz, B8(00000011), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00000011, FPU_NOWARN);
}
int m_flog10(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00010101), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00010101, FPU_FPSP);
}
int m_flog2(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00010110), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00010110, FPU_FPSP);
}
int m_flogn(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00010100), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00010100, FPU_FPSP);
}
int m_flognp1(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00000110, FPU_FPSP);
}
int m_fmod(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00100001), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00100001, FPU_FPSP);
}
if (!(activefpu & (FPU_68040 | FPU_68060)))
return error("Unsupported in current FPU");
- return gen_fpu(inst, siz, B8(01100100), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b01100100, FPU_FPSP);
}
if (!(activefpu & (FPU_68040 | FPU_68060)))
return error("Unsupported in current FPU");
- return gen_fpu(inst, siz, B8(01100100), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b01100100, FPU_FPSP);
}
int m_fmul(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00100011), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00100011, FPU_NOWARN);
}
int m_fsmul(WORD inst, WORD siz)
{
if (activefpu & (FPU_68040 | FPU_68060))
- return gen_fpu(inst, siz, B8(01100011), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01100011, FPU_NOWARN);
return error("Unsupported in current FPU");
}
int m_fdmul(WORD inst, WORD siz)
{
if (activefpu & (FPU_68040 | FPU_68060))
- return gen_fpu(inst, siz, B8(01100111), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01100111, FPU_NOWARN);
return error("Unsupported in current FPU");
}
if (am1 == AM_NONE)
{
a1reg = a0reg;
- return gen_fpu(inst, siz, B8(00011010), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00011010, FPU_NOWARN);
}
- return gen_fpu(inst, siz, B8(00011010), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00011010, FPU_NOWARN);
}
if (am1 == AM_NONE)
{
a1reg = a0reg;
- return gen_fpu(inst, siz, B8(01011010), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01011010, FPU_NOWARN);
}
- return gen_fpu(inst, siz, B8(01011010), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01011010, FPU_NOWARN);
}
return error("Unsupported in current FPU");
if (am1 == AM_NONE)
{
a1reg = a0reg;
- return gen_fpu(inst, siz, B8(01011110), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01011110, FPU_NOWARN);
}
- return gen_fpu(inst, siz, B8(01011110), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01011110, FPU_NOWARN);
}
return error("Unsupported in current FPU");
int m_fnop(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00000000), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00000000, FPU_NOWARN);
}
int m_frem(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00100101), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00100101, FPU_FPSP);
}
int m_fscale(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00100110), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00100110, FPU_FPSP);
}
int m_fsgldiv(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00100100), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00100100, FPU_FPSP);
}
int m_fsglmul(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00100111), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00100111, FPU_FPSP);
}
int m_fsin(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00001110), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00001110, FPU_FPSP);
}
a2reg = a1reg;
a1reg = temp;
- if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP) == OK)
+ if (gen_fpu(inst, siz, 0b00110000, FPU_FPSP) == OK)
{
chptr[-1] |= a2reg;
return OK;
int m_fsinh(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00000010), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00000010, FPU_FPSP);
}
int m_fsqrt(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00000100), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00000100, FPU_NOWARN);
}
int m_fsfsqrt(WORD inst, WORD siz)
{
if (activefpu & (FPU_68040 | FPU_68060))
- return gen_fpu(inst, siz, B8(01000001), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01000001, FPU_NOWARN);
return error("Unsupported in current FPU");
}
int m_fdfsqrt(WORD inst, WORD siz)
{
if (activefpu & (FPU_68040 | FPU_68060))
- return gen_fpu(inst, siz, B8(01000101), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01000101, FPU_NOWARN);
return error("Unsupported in current FPU");
}
int m_fsub(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00101000), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00101000, FPU_NOWARN);
}
int m_fsfsub(WORD inst, WORD siz)
{
if (activefpu & (FPU_68040 | FPU_68060))
- return gen_fpu(inst, siz, B8(01101000), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01101000, FPU_NOWARN);
return error("Unsupported in current FPU");
}
int m_fdsub(WORD inst, WORD siz)
{
if (activefpu & (FPU_68040 | FPU_68060))
- return gen_fpu(inst, siz, B8(01101100), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b01101100, FPU_NOWARN);
return error("Unsupported in current FPU");
}
int m_ftan(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00001111), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00001111, FPU_FPSP);
}
int m_ftanh(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00001001), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00001001, FPU_FPSP);
}
int m_ftentox(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00010010), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00010010, FPU_FPSP);
}
int m_ftst(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00111010), FPU_NOWARN);
+ return gen_fpu(inst, siz, 0b00111010, FPU_NOWARN);
}
int m_ftwotox(WORD inst, WORD siz)
{
CHECKNOFPU;
- return gen_fpu(inst, siz, B8(00010001), FPU_FPSP);
+ return gen_fpu(inst, siz, 0b00010001, FPU_FPSP);
}
int m_lpstop(WORD inst, WORD siz)
{
CHECKNO60;
- D_word(B16(00000001, 11000000));
+ D_word(0b0000000111000000);
if (a0exattr & DEFINED)
{