X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=mach.c;h=7c91979c0a351f97fcc2b46835465fc1fc1abcff;hp=47896a9fc79d87cf1761547b71b830a5f660e325;hb=02523045dcb28c8f6ad794a84e32beff214be424;hpb=d16b8ea0ee65b2ad901ca6b0624c07e6e4930cc4 diff --git a/mach.c b/mach.c index 47896a9..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,11 +12,39 @@ #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"; @@ -31,42 +59,42 @@ 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) @@ -83,19 +111,20 @@ WORD am_6[] = { // Error messages -int m_unimp(void) +int m_unimp(WORD unused1, WORD unused2) { return (int)error("unimplemented mnemonic"); } -int m_badmode(void) +//int m_badmode(void) +int m_badmode(WORD unused1, WORD unused2) { return (int)error("inappropriate addressing mode"); } -int m_self(WORD inst) +int m_self(WORD inst, WORD usused) { D_word(inst); return 0; @@ -121,43 +150,43 @@ int m_self(WORD inst) // int m_ea(WORD inst, WORD siz) { - WORD flg; + WORD flg = inst; // Save flag bits + inst &= ~0x3F; // Clobber flag bits in instr - flg = inst; // Save flag bits - inst &= ~0x3f; // Clobber flag bits in instr - - if (flg & 4) // Install "standard" instr size bits + // Install "standard" instr size bits + if (flg & 4) inst |= siz_6[siz]; if (flg & 16) - { // OR-in register number + { + // OR-in register number if (flg & 8) - { - inst |= reg_9[a1reg]; // ea1reg in bits 9..11 - } + inst |= reg_9[a1reg]; // ea1reg in bits 9..11 else - { - inst |= reg_9[a0reg]; // ea0reg in bits 9..11 - } + 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 + { + // Use am1 + inst |= am1 | a1reg; // Get ea1 into instr + D_word(inst); // Deposit instr - if (flg & 2) // Generate ea0 if requested + // Generate ea0 if requested + if (flg & 2) ea0gen(siz); - ea1gen(siz); // Generate ea1 + ea1gen(siz); // Generate ea1 } else - { // Use am0 - inst |= am0 | a0reg; // Get ea0 into instr - D_word(inst); // Deposit instr - ea0gen(siz); // Generate ea0 + { + // 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 + // Generate ea1 if requested + if (flg & 2) ea1gen(siz); } @@ -172,8 +201,9 @@ int m_ea(WORD inst, WORD siz) int m_abcd(WORD inst, WORD siz) { if (inst & 1) - { // Install size bits - --inst; + { + // Install size bits + inst--; inst |= siz_6[siz]; } @@ -191,7 +221,7 @@ int m_adda(WORD inst, WORD siz) { inst |= am0 | a0reg | lwsiz_8[siz] | reg_9[a1reg]; D_word(inst); - ea0gen(siz); // Gen EA + ea0gen(siz); // Generate EA return 0; } @@ -203,14 +233,16 @@ int m_adda(WORD inst, WORD siz) // int m_reg(WORD inst, WORD siz) { - if (inst & 1) // Install size bits + if (inst & 1) + // Install size bits inst |= siz_6[siz]; - if (inst & 2) // Install other register (9..11) + if (inst & 2) + // Install other register (9..11) inst |= reg_9[a1reg]; - inst &= ~7; // Clear off crufty bits - inst |= a0reg; // Install first register + inst &= ~7; // Clear off crufty bits + inst |= a0reg; // Install first register D_word(inst); return 0; @@ -271,7 +303,7 @@ int m_shi(WORD inst, WORD siz) } else { - fixup(FU_QUICK, sloc, a0expr); + AddFixup(FU_QUICK, sloc, a0expr); D_word(inst); } @@ -286,11 +318,11 @@ int m_bitop(WORD inst, WORD siz) { // Enforce instruction sizes if (am1 == DREG) - { // X,Dn must be .n or .l - if (siz & (SIZB|SIZW)) + { // 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 + else if (siz & (SIZW | SIZL)) // X,ea must be .n or .b return error(siz_error); // Construct instr and EAs @@ -299,7 +331,7 @@ int m_bitop(WORD inst, WORD siz) if (am0 == IMMED) { D_word(inst); - ea0gen(SIZB); // Immediate bit number + ea0gen(SIZB); // Immediate bit number } else { @@ -307,7 +339,8 @@ int m_bitop(WORD inst, WORD siz) D_word(inst); } - ea1gen(SIZB); // ea to bit-munch + // ea to bit-munch + ea1gen(SIZB); return 0; } @@ -335,7 +368,7 @@ int m_dbra(WORD inst, WORD siz) } else { - fixup(FU_WORD|FU_PCREL|FU_ISBRA, sloc, a1expr); + AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr); D_word(0); } @@ -395,13 +428,19 @@ int m_link(WORD inst, WORD siz) // // Optimize MOVE.L #,D0 to a MOVEQ // -int m_move(WORD inst, int siz) +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 (siz == SIZL && am0 == IMMED && am1 == DREG + 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 { @@ -413,7 +452,7 @@ int m_move(WORD inst, int siz) ea0gen((WORD)siz); if (am1 >= ADISP) - ea1gen((WORD)siz); + ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea } return 0; @@ -428,9 +467,9 @@ int m_usp(WORD inst, WORD siz) siz = siz; if (am0 == AM_USP) - inst |= a1reg; // USP,An + inst |= a1reg; // USP, An else - inst |= a0reg; // An,USP + inst |= a0reg; // An, USP D_word(inst); @@ -448,13 +487,13 @@ int m_moveq(WORD inst, WORD siz) // Arrange for future fixup if (!(a0exattr & DEFINED)) { - fixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr); + AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr); a0exval = 0; } else if (a0exval + 0x100 >= 0x200) return error(range_error); - inst |= reg_9[a1reg] | (a0exval & 0xff); + inst |= reg_9[a1reg] | (a0exval & 0xFF); D_word(inst); return 0; @@ -462,12 +501,10 @@ int m_moveq(WORD inst, WORD siz) // -// 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; @@ -477,9 +514,7 @@ int m_movep(WORD inst, WORD siz) D_word(inst); if (am1 == AIND) - { - D_word(0); - } + D_word(0) else ea1gen(siz); } @@ -489,9 +524,7 @@ int m_movep(WORD inst, WORD siz) D_word(inst); if (am0 == AIND) - { - D_word(0); - } + D_word(0) else ea0gen(siz); } @@ -510,21 +543,28 @@ int m_br(WORD inst, WORD siz) 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 (v != 0 && v + 0x80 < 0x100) - { // Fits in .B - inst |= v & 0xff; + 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 + { + // Fits in .W if (v + 0x8000 > 0x10000) return error(range_error); @@ -539,7 +579,7 @@ int m_br(WORD inst, WORD siz) if (v + 0x80 >= 0x100) return error(range_error); - inst |= v & 0xff; + inst |= v & 0xFF; D_word(inst); } else @@ -557,15 +597,17 @@ int m_br(WORD inst, WORD siz) siz = SIZW; if (siz == SIZB) - { // .B - fixup(FU_BBRA|FU_PCREL|FU_SEXT, sloc, a0expr); + { + // .B + AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr); D_word(inst); return 0; } else - { // .W + { + // .W D_word(inst); - fixup(FU_WORD|FU_PCREL|FU_LBRA|FU_ISBRA, sloc, a0expr); + AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr); D_word(0); } @@ -590,7 +632,7 @@ int m_addq(WORD inst, WORD siz) } else { - fixup(FU_QUICK, sloc, a0expr); + AddFixup(FU_QUICK, sloc, a0expr); D_word(inst); } @@ -642,8 +684,9 @@ int m_movem(WORD inst, WORD siz) inst |= 0x0040; if (*tok == '#') - { // Handle #,ea - ++tok; + { + // Handle #, ea + tok++; if (abs_expr(&eval) != OK) return 0; @@ -656,7 +699,8 @@ int m_movem(WORD inst, WORD siz) } if (*tok >= KW_D0 && *tok <= KW_A7) - { // ,ea + { + // , ea if (reglist(&rmask) < 0) return 0; @@ -669,7 +713,7 @@ immed1: inst |= am0 | a0reg; - if (!(amsktab[am0] & (C_ALTCTRL|M_APREDEC))) + if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC))) return error("invalid addressing mode"); // If APREDEC, reverse register mask @@ -683,7 +727,8 @@ immed1: } } else - { // ea, + { + // ea, if (amode(0) < 0) return 0; @@ -696,8 +741,9 @@ immed1: return error("missing register list"); if (*tok == '#') - { // ea,# - ++tok; + { + // ea, # + tok++; if (abs_expr(&eval) != OK) return 0; @@ -710,7 +756,7 @@ immed1: else if (reglist(&rmask) < 0) return 0; - if (!(amsktab[am0] & (C_CTRL|M_APOSTINC))) + if (!(amsktab[am0] & (C_CTRL | M_APOSTINC))) return error("invalid addressing mode"); } @@ -732,3 +778,4 @@ int m_clra(WORD inst, WORD siz) return 0; } +