X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=mach.c;h=7c91979c0a351f97fcc2b46835465fc1fc1abcff;hp=90f047119449a504d5d44179f796f95b0335ab4a;hb=02523045dcb28c8f6ad794a84e32beff214be424;hpb=75cce0d9eb190f6094f66ae283b5981af25e5a57 diff --git a/mach.c b/mach.c index 90f0471..7c91979 100644 --- a/mach.c +++ b/mach.c @@ -3,7 +3,7 @@ // MACH.C - Code Generation // Copyright (C) 199x Landon Dyer, 2011 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 // #include "mach.h" @@ -12,61 +12,89 @@ #include "direct.h" #include "token.h" #include "procln.h" -#include "risca.h" +#include "riscasm.h" +#include "rmac.h" #define DEF_KW #include "kwtab.h" + +// Fucntion prototypes +int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD); +int m_self(WORD, WORD); +int m_abcd(WORD, WORD); +int m_reg(WORD, WORD); +int m_imm(WORD, WORD); +int m_imm8(WORD, WORD); +int m_shi(WORD, WORD); +int m_shr(WORD, WORD); +int m_bitop(WORD, WORD); +int m_exg(WORD, WORD); +int m_ea(WORD, WORD); +int m_br(WORD, WORD); +int m_dbra(WORD, WORD); +int m_link(WORD, WORD); +int m_adda(WORD, WORD); +int m_addq(WORD, WORD); +//int m_move(WORD, int); +int m_move(WORD, WORD); +int m_moveq(WORD, WORD); +int m_usp(WORD, WORD); +int m_movep(WORD, WORD); +int m_trap(WORD, WORD); +int m_movem(WORD, WORD); +int m_clra(WORD, WORD); + // Common error messages -char * range_error = "expression out of range"; -char * abs_error = "illegal absolute expression"; -char * seg_error = "bad (section) expression"; -char * rel_error = "illegal relative address"; -char * siz_error = "bad size specified"; -char * undef_error = "undefined expression"; -char * fwd_error = "forward or undefined expression"; +char range_error[] = "expression out of range"; +char abs_error[] = "illegal absolute expression"; +char seg_error[] = "bad (section) expression"; +char rel_error[] = "illegal relative address"; +char siz_error[] = "bad size specified"; +char undef_error[] = "undefined expression"; +char fwd_error[] = "forward or undefined expression"; extern int ea0gen(WORD); extern int ea1gen(WORD); // Include code tables MNTAB machtab[] = { - { (WORD)-1, (unsigned long)-1L, (unsigned long)-1L, 0x0000, 0, m_badmode }, // 0 +// { (WORD)-1, (unsigned long)-1L, (unsigned long)-1L, 0x0000, 0, m_badmode }, // 0 + { 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000, 0, m_badmode }, // 0 #include "68ktab.h" - { 0, 0L, 0L, 0x0000, 0, m_unimp } // Last entry + { 0, 0L, 0L, 0x0000, 0, m_unimp } // Last entry }; // Register number << 9 WORD reg_9[8] = { - 0, 1<<9, 2<<9, 3<<9, - 4<<9, 5<<9, 6<<9, 7<<9 + 0, 1 << 9, 2 << 9, 3 << 9, 4 << 9, 5 << 9, 6 << 9, 7 << 9 }; // SIZB==>00, SIZW==>01, SIZL==>10, SIZN==>01 << 6 WORD siz_6[] = { - (WORD)-1, // n/a - 0, // SIZB - 1<<6, (WORD)-1, // SIZW, n/a - 2<<6, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a - 1<<6 // SIZN + (WORD)-1, // n/a + 0, // SIZB + 1<<6, (WORD)-1, // SIZW, n/a + 2<<6, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a + 1<<6 // SIZN }; // Byte/word/long size for MOVE instrs WORD siz_12[] = { (WORD)-1, - 0x1000, // Byte - 0x3000, (WORD)-1, // Word - 0x2000, (WORD)-1, (WORD)-1, (WORD)-1, // Long - 0x3000 // Word (SIZN) + 0x1000, // Byte + 0x3000, (WORD)-1, // Word + 0x2000, (WORD)-1, (WORD)-1, (WORD)-1, // Long + 0x3000 // Word (SIZN) }; // Word/long size (0=.w, 1=.l) in bit 8 WORD lwsiz_8[] = { - (WORD)-1, // n/a - (WORD)-1, // SIZB - 0, (WORD)-1, // SIZW, n/a - 1<<8, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a - 0 // SIZN + (WORD)-1, // n/a + (WORD)-1, // SIZB + 0, (WORD)-1, // SIZW, n/a + 1<<8, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a + 0 // SIZN }; // Addressing mode in bits 6..11 (register/mode fields are reversed) @@ -81,511 +109,673 @@ WORD am_6[] = { 00700, 01700, 02700, 03700, 04700, 05700, 06700, 07700 }; + // Error messages -int m_unimp(void) { return((int)error("unimplemented mnemonic")); } -int m_badmode(void) { return((int)error("inappropriate addressing mode")); } +int m_unimp(WORD unused1, WORD unused2) +{ + return (int)error("unimplemented mnemonic"); +} + + +//int m_badmode(void) +int m_badmode(WORD unused1, WORD unused2) +{ + return (int)error("inappropriate addressing mode"); +} + + +int m_self(WORD inst, WORD usused) +{ + D_word(inst); + return 0; +} -int m_self(WORD inst) { D_word(inst); return(0);} // -// ------------------------------------------------------------------------------------------------- // Do one EA in bits 0..5 // // Bits in `inst' have the following meaning: // -// Bit zero specifies which ea (ea0 or ea1) to generate in the lower six bits of the instr. +// Bit zero specifies which ea (ea0 or ea1) to generate in the lower six bits +// of the instr. // -// If bit one is set, the OTHER ea (the one that wasn't generated by bit zero) is generated after -// the instruction. Regardless of bit 0's value, ea0 is always deposited in memory before ea1. +// If bit one is set, the OTHER ea (the one that wasn't generated by bit zero) +// is generated after the instruction. Regardless of bit 0's value, ea0 is +// always deposited in memory before ea1. // // If bit two is set, standard size bits are set in the instr in bits 6 and 7. // -// If bit four is set, bit three specifies which eaXreg to place in bits 9..11 of the instr. -// ------------------------------------------------------------------------------------------------- -// - -int m_ea(WORD inst, WORD siz) { - WORD flg; - - flg = inst; // Save flag bits - inst &= ~0x3f; // Clobber flag bits in instr - - if(flg & 4) // Install "standard" instr size bits - inst |= siz_6[siz]; - - if(flg & 16) { // OR-in register number - if(flg & 8) { - inst |= reg_9[a1reg]; // ea1reg in bits 9..11 - } else { - inst |= reg_9[a0reg]; // ea0reg in bits 9..11 - } - } - - if(flg & 1) { // Use am1 - inst |= am1 | a1reg; // Get ea1 into instr - D_word(inst); // Deposit instr - if(flg & 2) // Generate ea0 if requested - ea0gen(siz); - ea1gen(siz); // Generate ea1 - } else { // Use am0 - inst |= am0 | a0reg; // Get ea0 into instr - D_word(inst); // Deposit instr - ea0gen(siz); // Generate ea0 - if(flg & 2) // Generate ea1 if requested - ea1gen(siz); - } - - return(0); +// If bit four is set, bit three specifies which eaXreg to place in bits 9..11 +// of the instr. +// +int m_ea(WORD inst, WORD siz) +{ + WORD flg = inst; // Save flag bits + inst &= ~0x3F; // Clobber flag bits in instr + + // Install "standard" instr size bits + if (flg & 4) + inst |= siz_6[siz]; + + if (flg & 16) + { + // OR-in register number + if (flg & 8) + inst |= reg_9[a1reg]; // ea1reg in bits 9..11 + else + inst |= reg_9[a0reg]; // ea0reg in bits 9..11 + } + + if (flg & 1) + { + // Use am1 + inst |= am1 | a1reg; // Get ea1 into instr + D_word(inst); // Deposit instr + + // Generate ea0 if requested + if (flg & 2) + ea0gen(siz); + + ea1gen(siz); // Generate ea1 + } + else + { + // Use am0 + inst |= am0 | a0reg; // Get ea0 into instr + D_word(inst); // Deposit instr + ea0gen(siz); // Generate ea0 + + // Generate ea1 if requested + if (flg & 2) + ea1gen(siz); + } + + return 0; } + // -// --- Dx,Dy nnnnXXXnssnnnYYY If bit 0 of `inst' is set, install size bits in bits 6..7 ------------ +// Dx,Dy nnnnXXXnssnnnYYY If bit 0 of `inst' is set, install size bits in bits +// 6..7 // - -int m_abcd(WORD inst, WORD siz) { - if(inst & 1) { // Install size bits - --inst; - inst |= siz_6[siz]; - } +int m_abcd(WORD inst, WORD siz) +{ + if (inst & 1) + { + // Install size bits + inst--; + inst |= siz_6[siz]; + } - inst |= a0reg | reg_9[a1reg]; - D_word(inst); + inst |= a0reg | reg_9[a1reg]; + D_word(inst); - return(0); + return 0; } + // -// --- {adda} ea,AREG ------------------------------------------------------------------------------ +// {adda} ea,AREG // - -int m_adda(WORD inst, WORD siz) { - inst |= am0 | a0reg | lwsiz_8[siz] | reg_9[a1reg]; - D_word(inst); - ea0gen(siz); // Gen EA +int m_adda(WORD inst, WORD siz) +{ + inst |= am0 | a0reg | lwsiz_8[siz] | reg_9[a1reg]; + D_word(inst); + ea0gen(siz); // Generate EA - return(0); + return 0; } + // -// ------------------------------------------------------------------------------------------------- // If bit 0 of `inst' is 1, install size bits in bits 6..7 of instr. // If bit 1 of `inst' is 1, install a1reg in bits 9..11 of instr. -// ------------------------------------------------------------------------------------------------- // +int m_reg(WORD inst, WORD siz) +{ + if (inst & 1) + // Install size bits + inst |= siz_6[siz]; -int m_reg(WORD inst, WORD siz) { - if(inst & 1) // Install size bits - inst |= siz_6[siz]; - if(inst & 2) // Install other register (9..11) - inst |= reg_9[a1reg]; + if (inst & 2) + // Install other register (9..11) + inst |= reg_9[a1reg]; - inst &= ~7; // Clear off crufty bits - inst |= a0reg; // Install first register - D_word(inst); + inst &= ~7; // Clear off crufty bits + inst |= a0reg; // Install first register + D_word(inst); - return(0); + return 0; } + // -// --- #expr ---------------------------------------------------------------------------------- +// #expr // - -int m_imm(WORD inst, WORD siz) { - D_word(inst); - ea0gen(siz); +int m_imm(WORD inst, WORD siz) +{ + D_word(inst); + ea0gen(siz); - return(0); + return 0; } + // -// --- .b #expr -------------------------------------------------------------------------------- +// .b #expr // - -int m_imm8(WORD inst, WORD siz) { - siz = siz; - D_word(inst); - ea0gen(SIZB); +int m_imm8(WORD inst, WORD siz) +{ + siz = siz; + D_word(inst); + ea0gen(SIZB); - return(0); + return 0; } + // -// --- Dn,Dn ------------------------------------------------------------------------------- +// Dn,Dn // - -int m_shr(WORD inst, WORD siz) { - inst |= reg_9[a0reg] | a1reg | siz_6[siz]; - D_word(inst); +int m_shr(WORD inst, WORD siz) +{ + inst |= reg_9[a0reg] | a1reg | siz_6[siz]; + D_word(inst); - return(0); + return 0; } + // -// --- #n,Dn ------------------------------------------------------------------------------- +// #n,Dn // - -int m_shi(WORD inst, WORD siz) { - inst |= a1reg | siz_6[siz]; +int m_shi(WORD inst, WORD siz) +{ + inst |= a1reg | siz_6[siz]; - if(a0exattr & DEFINED) { - if(a0exval > 8) - return(error(range_error)); - inst |= (a0exval & 7) << 9; - D_word(inst); - } else { - fixup(FU_QUICK, sloc, a0expr); - D_word(inst); - } + if (a0exattr & DEFINED) + { + if (a0exval > 8) + return error(range_error); - return(0); + inst |= (a0exval & 7) << 9; + D_word(inst); + } + else + { + AddFixup(FU_QUICK, sloc, a0expr); + D_word(inst); + } + + return 0; } + // -// --- {bset, btst, bchg, bclr} -- #immed,ea -- Dn,ea ---------------------------------------------- +// {bset, btst, bchg, bclr} -- #immed,ea -- Dn,ea // - -int m_bitop(WORD inst, WORD siz) { - // Enforce instruction sizes - if(am1 == DREG) { // X,Dn must be .n or .l - if(siz & (SIZB|SIZW)) - return(error(siz_error)); - } else - if(siz & (SIZW|SIZL)) // X,ea must be .n or .b - return error(siz_error); +int m_bitop(WORD inst, WORD siz) +{ + // Enforce instruction sizes + if (am1 == DREG) + { // X,Dn must be .n or .l + if (siz & (SIZB | SIZW)) + return error(siz_error); + } + else if (siz & (SIZW | SIZL)) // X,ea must be .n or .b + return error(siz_error); + + // Construct instr and EAs + inst |= am1 | a1reg; - // Construct instr and EAs - inst |= am1 | a1reg; - if(am0 == IMMED) { - D_word(inst); - ea0gen(SIZB); // Immediate bit number - } else { - inst |= reg_9[a0reg]; - D_word(inst); - } + if (am0 == IMMED) + { + D_word(inst); + ea0gen(SIZB); // Immediate bit number + } + else + { + inst |= reg_9[a0reg]; + D_word(inst); + } - ea1gen(SIZB); // ea to bit-munch + // ea to bit-munch + ea1gen(SIZB); - return(0); + return 0; } -int m_dbra(WORD inst, WORD siz) { - VALUE v; - - siz = siz; - inst |= a0reg; - D_word(inst); - if(a1exattr & DEFINED) { - if((a1exattr & TDB) != cursect) - return(error(rel_error)); - v = a1exval - sloc; - - if(v + 0x8000 > 0x10000) - return(error(range_error)); - D_word(v); - } else { - fixup(FU_WORD|FU_PCREL|FU_ISBRA, sloc, a1expr); - D_word(0); - } - - return(0); + +int m_dbra(WORD inst, WORD siz) +{ + VALUE v; + + siz = siz; + inst |= a0reg; + D_word(inst); + + if (a1exattr & DEFINED) + { + if ((a1exattr & TDB) != cursect) + return error(rel_error); + + v = a1exval - sloc; + + if (v + 0x8000 > 0x10000) + return error(range_error); + + D_word(v); + } + else + { + AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr); + D_word(0); + } + + return 0; } + // -// --- EXG ----------------------------------------------------------------------------------------- -// - -int m_exg(WORD inst, WORD siz) { - int m; - - siz = siz; - if(am0 == DREG && am1 == DREG) - m = 0x0040; // Dn,Dn - else if(am0 == AREG && am1 == AREG) - m = 0x0048; // An,An - else { - if(am0 == AREG) { // Dn,An or An,Dn - m = a1reg; // Get AREG into a1reg - a1reg = a0reg; - a0reg = m; - } - m = 0x0088; - } - inst |= m | reg_9[a0reg] | a1reg; - D_word(inst); - - return(0); +// EXG +// +int m_exg(WORD inst, WORD siz) +{ + int m; + + siz = siz; + + if (am0 == DREG && am1 == DREG) + m = 0x0040; // Dn,Dn + else if (am0 == AREG && am1 == AREG) + m = 0x0048; // An,An + else + { + if (am0 == AREG) + { // Dn,An or An,Dn + m = a1reg; // Get AREG into a1reg + a1reg = a0reg; + a0reg = m; + } + + m = 0x0088; + } + + inst |= m | reg_9[a0reg] | a1reg; + D_word(inst); + + return 0; } + // -// --- LINK ---------------------------------------------------------------------------------------- +// LINK // - -int m_link(WORD inst, WORD siz) { - siz = siz; - inst |= a0reg; - D_word(inst); - ea1gen(SIZW); +int m_link(WORD inst, WORD siz) +{ + siz = siz; + inst |= a0reg; + D_word(inst); + ea1gen(SIZW); - return(0); + return 0; } + // -// ------------------------------------------------------------------------------------------------- // Handle MOVE // MOVE // // Optimize MOVE.L #,D0 to a MOVEQ -// ------------------------------------------------------------------------------------------------- -// - -int m_move(WORD inst, int siz) { - // Try to optimize to MOVEQ - if(siz == SIZL && am0 == IMMED && am1 == DREG && (a0exattr & (TDB|DEFINED)) == DEFINED && - a0exval + 0x80 < 0x100) { - m_moveq((WORD)0x7000, (WORD)0); - } else { - inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg; - - D_word(inst); - if(am0 >= ADISP) ea0gen((WORD)siz); - if(am1 >= ADISP) ea1gen((WORD)siz); - } - - return(0); +// +int m_move(WORD inst, WORD size) +{ + // Cast the passed in value to an int + int siz = (int)size; + + // Try to optimize to MOVEQ + if (optim_flags[OPT_MOVEL_MOVEQ] && siz == SIZL && am0 == IMMED && am1 == DREG + && (a0exattr & (TDB|DEFINED)) == DEFINED && a0exval + 0x80 < 0x100) + { + m_moveq((WORD)0x7000, (WORD)0); + + if (sbra_flag) + warn("move.l #size,dx converted to moveq"); + } + else + { + inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg; + + D_word(inst); + + if (am0 >= ADISP) + ea0gen((WORD)siz); + + if (am1 >= ADISP) + ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea + } + + return 0; } + // -// --- move USP,An -- move An,USP ------------------------------------------------------------------ +// move USP,An -- move An,USP // - -int m_usp(WORD inst, WORD siz) { - siz = siz; - if(am0 == AM_USP) inst |= a1reg; // USP,An - else inst |= a0reg; // An,USP - D_word(inst); +int m_usp(WORD inst, WORD siz) +{ + siz = siz; - return(0); + if (am0 == AM_USP) + inst |= a1reg; // USP, An + else + inst |= a0reg; // An, USP + + D_word(inst); + + return 0; } + // -// --- moveq --------------------------------------------------------------------------------------- +// moveq // - -int m_moveq(WORD inst, WORD siz) { - siz = siz; - if(!(a0exattr & DEFINED)) { // Arrange for future fixup - fixup(FU_BYTE|FU_SEXT, sloc+1, a0expr); - a0exval = 0; - } else - if(a0exval + 0x100 >= 0x200) - return(error(range_error)); +int m_moveq(WORD inst, WORD siz) +{ + siz = siz; - inst |= reg_9[a1reg] | (a0exval & 0xff); - D_word(inst); + // Arrange for future fixup + if (!(a0exattr & DEFINED)) + { + AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr); + a0exval = 0; + } + else if (a0exval + 0x100 >= 0x200) + return error(range_error); - return(0); + inst |= reg_9[a1reg] | (a0exval & 0xFF); + D_word(inst); + + return 0; } + +// +// movep Dn, disp(An) -- movep disp(An), Dn // -// --- movep Dn,disp(An) -- movep disp(An),Dn ------------------------------------------------------ -// - -int m_movep(WORD inst, WORD siz) { - //WORD k; - - if(siz == SIZL) - inst |= 0x0040; - - if(am0 == DREG) { - inst |= reg_9[a0reg] | a1reg; - D_word(inst); - if(am1 == AIND) { - D_word(0); - } else - ea1gen(siz); - } else { - inst |= reg_9[a1reg] | a0reg; - D_word(inst); - if(am0 == AIND) { - D_word(0); - } else - ea0gen(siz); - } - - return(0); +int m_movep(WORD inst, WORD siz) +{ + if (siz == SIZL) + inst |= 0x0040; + + if (am0 == DREG) + { + inst |= reg_9[a0reg] | a1reg; + D_word(inst); + + if (am1 == AIND) + D_word(0) + else + ea1gen(siz); + } + else + { + inst |= reg_9[a1reg] | a0reg; + D_word(inst); + + if (am0 == AIND) + D_word(0) + else + ea0gen(siz); + } + + return 0; } + // -// --- Bcc -- BSR ---------------------------------------------------------------------------------- -// - -int m_br(WORD inst, WORD siz) { - VALUE v; - - if(a0exattr & DEFINED) { - if((a0exattr & TDB) != cursect) - return(error(rel_error)); - - v = a0exval - (sloc + 2); - - // Optimize branch instr. size - if(siz == SIZN) { - if(v != 0 && v + 0x80 < 0x100) { // Fits in .B - inst |= v & 0xff; - D_word(inst); - return(0); - } else { // Fits in .W - if(v + 0x8000 > 0x10000) - return(error(range_error)); - D_word(inst); - D_word(v); - return(0); - } - } - - if(siz == SIZB) { - if(v + 0x80 >= 0x100) - return(error(range_error)); - inst |= v & 0xff; - D_word(inst); - } else { - if(v + 0x8000 >= 0x10000) - return(error(range_error)); - D_word(inst); - D_word(v); - } - return(0); - } else - if(siz == SIZN) - siz = SIZW; - - if(siz == SIZB) { // .B - fixup(FU_BBRA|FU_PCREL|FU_SEXT, sloc, a0expr); - D_word(inst); - return(0); - } else { // .W - D_word(inst); - fixup(FU_WORD|FU_PCREL|FU_LBRA|FU_ISBRA, sloc, a0expr); - D_word(0); - } - - return(0); +// Bcc -- BSR +// +int m_br(WORD inst, WORD siz) +{ + VALUE v; + + if (a0exattr & DEFINED) + { + if ((a0exattr & TDB) != cursect) +//{ +//printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc); + return error(rel_error); +//} + + v = a0exval - (sloc + 2); + + // Optimize branch instr. size + if (siz == SIZN) + { + if (optim_flags[OPT_BSR_BCC_S] && v != 0 && v + 0x80 < 0x100) + { + // Fits in .B + inst |= v & 0xFF; + D_word(inst); + if (sbra_flag) + warn("Bcc.w/BSR.w converted to .s"); + return 0; + } + else + { + // Fits in .W + if (v + 0x8000 > 0x10000) + return error(range_error); + + D_word(inst); + D_word(v); + return 0; + } + } + + if (siz == SIZB) + { + if (v + 0x80 >= 0x100) + return error(range_error); + + inst |= v & 0xFF; + D_word(inst); + } + else + { + if (v + 0x8000 >= 0x10000) + return error(range_error); + + D_word(inst); + D_word(v); + } + + return 0; + } + else if (siz == SIZN) + siz = SIZW; + + if (siz == SIZB) + { + // .B + AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr); + D_word(inst); + return 0; + } + else + { + // .W + D_word(inst); + AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr); + D_word(0); + } + + return 0; } + // -// --- ADDQ -- SUBQ -------------------------------------------------------------------------------- +// ADDQ -- SUBQ // - -int m_addq(WORD inst, WORD siz) { - inst |= siz_6[siz] | am1 | a1reg; +int m_addq(WORD inst, WORD siz) +{ + inst |= siz_6[siz] | am1 | a1reg; + + if (a0exattr & DEFINED) + { + if (a0exval > 8 || a0exval == 0) // Range in 1..8 + return error(range_error); + + inst |= (a0exval & 7) << 9; + D_word(inst); + } + else + { + AddFixup(FU_QUICK, sloc, a0expr); + D_word(inst); + } - if(a0exattr & DEFINED) { - if(a0exval > 8 || a0exval == 0) // Range in 1..8 - return(error(range_error)); - inst |= (a0exval & 7) << 9; - D_word(inst); - } else { - fixup(FU_QUICK, sloc, a0expr); - D_word(inst); - } - ea1gen(siz); + ea1gen(siz); - return(0); + return 0; } + // -// --- trap #n ------------------------------------------------------------------------------------- +// trap #n // - -int m_trap(WORD inst, WORD siz) { - siz = siz; - if(a0exattr & DEFINED) { - if(a0exattr & TDB) - return(error(abs_error)); - if(a0exval >= 16) - return(error(range_error)); - inst |= a0exval; - D_word(inst); - } else - return(error(undef_error)); +int m_trap(WORD inst, WORD siz) +{ + siz = siz; + + if (a0exattr & DEFINED) + { + if (a0exattr & TDB) + return error(abs_error); + + if (a0exval >= 16) + return error(range_error); - return(0); + inst |= a0exval; + D_word(inst); + } + else + return error(undef_error); + + return 0; } + +// +// movem ,ea -- movem ea, // -// --- movem ,ea -- movem ea, -------------------------------------------------------- -// - -int m_movem(WORD inst, WORD siz) { - VALUE eval; - WORD i; - WORD w; - WORD rmask; - - if(siz & SIZB) return(error("bad size suffix")); - - if(siz == SIZL) inst |= 0x0040; - - if(*tok == '#') { // Handle #,ea - ++tok; - if(abs_expr(&eval) != OK) return(0); - if(eval >= 0x10000L) return(error(range_error)); - rmask = (WORD)eval; - goto immed1; - } - - if(*tok >= KW_D0 && *tok <= KW_A7) { // ,ea - if(reglist(&rmask) < 0) return(0); - - immed1: - - if(*tok++ != ',') return(error("missing comma")); - if(amode(0) < 0) return(0); - inst |= am0 | a0reg; - - if(!(amsktab[am0] & (C_ALTCTRL|M_APREDEC))) - return(error("invalid addressing mode")); - - // If APREDEC, reverse register mask - if(am0 == APREDEC) { - w = rmask; - rmask = 0; - for(i = 0x8000; i; i >>= 1, w >>= 1) - rmask = (WORD)((rmask << 1) | w & 1); - } - } else { // ea, - if(amode(0) < 0) return(0); - inst |= 0x0400 | am0 | a0reg; - if(*tok++ != ',') return(error("missing comma")); - if(*tok == EOL) return(error("missing register list")); - - if(*tok == '#') { // ea,# - ++tok; - if(abs_expr(&eval) != OK) return(0); - if(eval >= 0x10000) return(error(range_error)); - rmask = (WORD)eval; - } else - if(reglist(&rmask) < 0) return(0); - - if(!(amsktab[am0] & (C_CTRL|M_APOSTINC))) - return(error("invalid addressing mode")); - } - - D_word(inst); - D_word(rmask); - ea0gen(siz); - - return(0); +int m_movem(WORD inst, WORD siz) +{ + VALUE eval; + WORD i; + WORD w; + WORD rmask; + + if (siz & SIZB) + return error("bad size suffix"); + + if (siz == SIZL) + inst |= 0x0040; + + if (*tok == '#') + { + // Handle #, ea + tok++; + + if (abs_expr(&eval) != OK) + return 0; + + if (eval >= 0x10000L) + return error(range_error); + + rmask = (WORD)eval; + goto immed1; + } + + if (*tok >= KW_D0 && *tok <= KW_A7) + { + // , ea + if (reglist(&rmask) < 0) + return 0; + +immed1: + if (*tok++ != ',') + return error("missing comma"); + + if (amode(0) < 0) + return 0; + + inst |= am0 | a0reg; + + if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC))) + return error("invalid addressing mode"); + + // If APREDEC, reverse register mask + if (am0 == APREDEC) + { + w = rmask; + rmask = 0; + + for(i=0x8000; i; i>>=1, w>>=1) + rmask = (WORD)((rmask << 1) | w & 1); + } + } + else + { + // ea, + if (amode(0) < 0) + return 0; + + inst |= 0x0400 | am0 | a0reg; + + if (*tok++ != ',') + return error("missing comma"); + + if (*tok == EOL) + return error("missing register list"); + + if (*tok == '#') + { + // ea, # + tok++; + + if (abs_expr(&eval) != OK) + return 0; + + if (eval >= 0x10000) + return error(range_error); + + rmask = (WORD)eval; + } + else if (reglist(&rmask) < 0) + return 0; + + if (!(amsktab[am0] & (C_CTRL | M_APOSTINC))) + return error("invalid addressing mode"); + } + + D_word(inst); + D_word(rmask); + ea0gen(siz); + + return 0; } + // -// --- CLR.x An ==> SUBA.x An,An ------------------------------------------------------------------- +// CLR.x An ==> SUBA.x An,An // - -int m_clra(WORD inst, WORD siz) { - inst |= a0reg | reg_9[a0reg] | lwsiz_8[siz]; - D_word(inst); +int m_clra(WORD inst, WORD siz) +{ + inst |= a0reg | reg_9[a0reg] | lwsiz_8[siz]; + D_word(inst); - return(0); + return 0; }