// 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"
#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";
// 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
};
// 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;
//
int m_ea(WORD inst, WORD siz)
{
- WORD flg;
-
- flg = inst; // Save flag bits
- inst &= ~0x3f; // Clobber flag bits in instr
+ WORD 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);
}
int m_abcd(WORD inst, WORD siz)
{
if (inst & 1)
- { // Install size bits
- --inst;
+ {
+ // Install size bits
+ inst--;
inst |= siz_6[siz];
}
{
inst |= am0 | a0reg | lwsiz_8[siz] | reg_9[a1reg];
D_word(inst);
- ea0gen(siz); // Gen EA
+ ea0gen(siz); // Generate EA
return 0;
}
//
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;
}
else
{
- fixup(FU_QUICK, sloc, a0expr);
+ AddFixup(FU_QUICK, sloc, a0expr);
D_word(inst);
}
{
// 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
if (am0 == IMMED)
{
D_word(inst);
- ea0gen(SIZB); // Immediate bit number
+ ea0gen(SIZB); // Immediate bit number
}
else
{
D_word(inst);
}
- ea1gen(SIZB); // ea to bit-munch
+ // ea to bit-munch
+ ea1gen(SIZB);
return 0;
}
}
else
{
- fixup(FU_WORD|FU_PCREL|FU_ISBRA, sloc, a1expr);
+ AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
D_word(0);
}
//
// Optimize MOVE.L #<smalldata>,D0 to a MOVEQ
//
-int m_move(WORD inst, int siz)
+//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_flag && 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
{
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);
// 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;
//
-// 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;
D_word(inst);
if (am1 == AIND)
- {
- D_word(0);
- }
+ D_word(0)
else
ea1gen(siz);
}
D_word(inst);
if (am0 == AIND)
- {
- D_word(0);
- }
+ D_word(0)
else
ea0gen(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_flag && 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);
if (v + 0x80 >= 0x100)
return error(range_error);
- inst |= v & 0xff;
+ inst |= v & 0xFF;
D_word(inst);
}
else
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);
}
}
else
{
- fixup(FU_QUICK, sloc, a0expr);
+ AddFixup(FU_QUICK, sloc, a0expr);
D_word(inst);
}
inst |= 0x0040;
if (*tok == '#')
- { // Handle #<expr>,ea
- ++tok;
+ {
+ // Handle #<expr>, ea
+ tok++;
if (abs_expr(&eval) != OK)
return 0;
}
if (*tok >= KW_D0 && *tok <= KW_A7)
- { // <rlist>,ea
+ {
+ // <rlist>, ea
if (reglist(&rmask) < 0)
return 0;
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
}
}
else
- { // ea,<rlist>
+ {
+ // ea, <rlist>
if (amode(0) < 0)
return 0;
return error("missing register list");
if (*tok == '#')
- { // ea,#<expr>
- ++tok;
+ {
+ // ea, #<expr>
+ tok++;
if (abs_expr(&eval) != OK)
return 0;
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");
}
return 0;
}
+