Fix for bug #102. Thanks (blame!) go to ggn & dml for the idea. :-)
authorShamus Hammons <jlhamm@acm.org>
Thu, 20 Jul 2017 19:15:53 +0000 (14:15 -0500)
committerShamus Hammons <jlhamm@acm.org>
Thu, 20 Jul 2017 19:15:53 +0000 (14:15 -0500)
eagen.c
eagen0.c
mach.c
parmode.h
token.c
token.h

diff --git a/eagen.c b/eagen.c
index de1ecb426fb2699981f7fb31719aeeacf69e6c42..1f18b8598df87c4629b680730428df3740b5d0b1 100644 (file)
--- a/eagen.c
+++ b/eagen.c
@@ -14,6 +14,7 @@
 #include "mach.h"
 #include "riscasm.h"
 #include "sect.h"
 #include "mach.h"
 #include "riscasm.h"
 #include "sect.h"
+#include "token.h"
 
 #define eaNgen    ea0gen
 #define amN       am0
 
 #define eaNgen    ea0gen
 #define amN       am0
index f01b989a7454812538d397cdca29881e0fa2545d..1bb00ba7c6a372798f81625dccf24251cfedb49c 100644 (file)
--- a/eagen0.c
+++ b/eagen0.c
@@ -38,7 +38,7 @@ int eaNgen(WORD siz)
                        if (tdb)
                                MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
 
                        if (tdb)
                                MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
 
-                       if ((v == 0) && optim_flags[OPT_INDIRECT_DISP] && !movep)
+                       if ((v == 0) && CHECK_OPTS(OPT_INDIRECT_DISP) && !movep)
                        {
                                // If expr is 0, size optimise the opcode. Generally the lower
                                // 6 bits of the opcode for expr(ax) are 101rrr where rrr=the
                        {
                                // If expr is 0, size optimise the opcode. Generally the lower
                                // 6 bits of the opcode for expr(ax) are 101rrr where rrr=the
diff --git a/mach.c b/mach.c
index ac800eb665bdf0e77366c5adfbdd55faa3addb85..22a27273d4d2d73a1a43617f836dabb6bc3086cc 100644 (file)
--- a/mach.c
+++ b/mach.c
@@ -13,7 +13,6 @@
 #include "error.h"
 #include "procln.h"
 #include "riscasm.h"
 #include "error.h"
 #include "procln.h"
 #include "riscasm.h"
-//#include "rmac.h"
 #include "sect.h"
 #include "token.h"
 
 #include "sect.h"
 #include "token.h"
 
@@ -469,7 +468,7 @@ int m_ea(WORD inst, WORD siz)
 //
 int m_lea(WORD inst, WORD siz)
 {
 //
 int m_lea(WORD inst, WORD siz)
 {
-       if (optim_flags[OPT_LEA_ADDQ]
+       if (CHECK_OPTS(OPT_LEA_ADDQ)
                && ((am0 == ADISP) && (a0reg == a1reg) && (a0exattr & DEFINED))
                && ((a0exval > 0) && (a0exval <= 8)))
        {
                && ((am0 == ADISP) && (a0reg == a1reg) && (a0exattr & DEFINED))
                && ((a0exval > 0) && (a0exval <= 8)))
        {
@@ -820,7 +819,7 @@ int m_move(WORD inst, WORD size)
        int siz = (int)size;
 
        // Try to optimize to MOVEQ
        int siz = (int)size;
 
        // Try to optimize to MOVEQ
-       if (optim_flags[OPT_MOVEL_MOVEQ]
+       if (CHECK_OPTS(OPT_MOVEL_MOVEQ)
                && (siz == SIZL) && (am0 == IMMED) && (am1 == DREG)
                && ((a0exattr & (TDB | DEFINED)) == DEFINED)
                && (a0exval + 0x80 < 0x100))
                && (siz == SIZL) && (am0 == IMMED) && (am1 == DREG)
                && ((a0exattr & (TDB | DEFINED)) == DEFINED)
                && (a0exval + 0x80 < 0x100))
@@ -981,7 +980,7 @@ int m_br(WORD inst, WORD siz)
                // Optimize branch instr. size
                if (siz == SIZN)
                {
                // Optimize branch instr. size
                if (siz == SIZN)
                {
-                       if (optim_flags[OPT_BSR_BCC_S] && (v != 0) && ((v + 0x80) < 0x100))
+                       if (CHECK_OPTS(OPT_BSR_BCC_S) && (v != 0) && ((v + 0x80) < 0x100))
                        {
                                // Fits in .B
                                inst |= v & 0xFF;
                        {
                                // Fits in .B
                                inst |= v & 0xFF;
index 5f475dbf5a20753603b9c98b8fd2222b99ffb301..54b584e0fc4f4c58bbbb510f4f1000acef2833d1 100644 (file)
--- a/parmode.h
+++ b/parmode.h
                        else
                        {
                                expr(AnBEXPR, &AnBEXVAL, &AnBEXATTR, &AnESYM);
                        else
                        {
                                expr(AnBEXPR, &AnBEXVAL, &AnBEXATTR, &AnESYM);
-                               if (optim_flags[OPT_BASE_DISP] && AnBEXVAL==0 && AnEXATTR!=0)
+                               if (CHECK_OPTS(OPT_BASE_DISP) && AnBEXVAL==0 && AnEXATTR!=0)
                                {
                                        // bd=0 so let's optimise it out
                                        AnEXTEN|=EXT_BDSIZE0;
                                {
                                        // bd=0 so let's optimise it out
                                        AnEXTEN|=EXT_BDSIZE0;
                                        {
                                                // Defined, absolute values from $FFFF8000..$00007FFF get optimized
                                                // to absolute short
                                        {
                                                // Defined, absolute values from $FFFF8000..$00007FFF get optimized
                                                // to absolute short
-                                               if (optim_flags[OPT_ABS_SHORT]
+                                               if (CHECK_OPTS(OPT_ABS_SHORT)
                                                        && ((AnBEXATTR & (TDB | DEFINED)) == DEFINED)
                                                        && ((AnBEXVAL + 0x8000) < 0x10000))
                                                {
                                                        && ((AnBEXATTR & (TDB | DEFINED)) == DEFINED)
                                                        && ((AnBEXVAL + 0x8000) < 0x10000))
                                                {
                                if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
                                        goto badmode;
 
                                if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
                                        goto badmode;
 
-                               if (optim_flags[OPT_BASE_DISP] && (AnEXVAL == 0))
+                               if (CHECK_OPTS(OPT_BASE_DISP) && (AnEXVAL == 0))
                                {
                                        // od=0 so optimise it out
                                        AMn = MEMPOST;           // let's say it's ([bd,An],Xn,od) with od=0 then
                                {
                                        // od=0 so optimise it out
                                        AMn = MEMPOST;           // let's say it's ([bd,An],Xn,od) with od=0 then
 
                                        // Defined, absolute values from $FFFF8000..$00007FFF get
                                        // optimized to absolute short
 
                                        // Defined, absolute values from $FFFF8000..$00007FFF get
                                        // optimized to absolute short
-                                       if (optim_flags[OPT_ABS_SHORT]
+                                       if (CHECK_OPTS(OPT_ABS_SHORT)
                                                && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
                                                && ((AnEXVAL + 0x8000) < 0x10000))
                                        {
                                                && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
                                                && ((AnEXVAL + 0x8000) < 0x10000))
                                        {
 
                                expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM);
 
 
                                expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM);
 
-                               if (optim_flags[OPT_BASE_DISP] && (AnEXVAL == 0))
+                               if (CHECK_OPTS(OPT_BASE_DISP) && (AnEXVAL == 0))
                                {
                                        // od=0 so optimise it out
                                        AMn = MEMPOST;           // let's say it's ([bd,An],Xn,od) with od=0 then
                                {
                                        // od=0 so optimise it out
                                        AMn = MEMPOST;           // let's say it's ([bd,An],Xn,od) with od=0 then
 
                                        // Defined, absolute values from $FFFF8000..$00007FFF get
                                        // optimized to absolute short
 
                                        // Defined, absolute values from $FFFF8000..$00007FFF get
                                        // optimized to absolute short
-                                       else if (optim_flags[OPT_BASE_DISP]
+                                       else if (CHECK_OPTS(OPT_BASE_DISP)
                                                && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
                                                && ((AnEXVAL + 0x8000) < 0x10000))
                                        {
                                                && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
                                                && ((AnEXVAL + 0x8000) < 0x10000))
                                        {
                                if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
                                        goto badmode;
 
                                if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
                                        goto badmode;
 
-                               if (optim_flags[OPT_BASE_DISP] && (AnEXVAL == 0))
+                               if (CHECK_OPTS(OPT_BASE_DISP) && (AnEXVAL == 0))
                                {
                                        // od=0 so optimise it out
                                        AMn = MEMPRE;            // let's say it's ([bd,An],Xn,od) with od=0 then
                                {
                                        // od=0 so optimise it out
                                        AMn = MEMPRE;            // let's say it's ([bd,An],Xn,od) with od=0 then
 
                                        // Defined, absolute values from $FFFF8000..$00007FFF get optimized
                                        // to absolute short
 
                                        // Defined, absolute values from $FFFF8000..$00007FFF get optimized
                                        // to absolute short
-                                       else if (optim_flags[OPT_BASE_DISP]
+                                       else if (CHECK_OPTS(OPT_BASE_DISP)
                                                && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
                                                && ((AnEXVAL + 0x8000) < 0x10000))
                                        {
                                                && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
                                                && ((AnEXVAL + 0x8000) < 0x10000))
                                        {
@@ -1007,7 +1007,7 @@ CHK_FOR_DISPn:
 
                        // Defined, absolute values from $FFFF8000..$00007FFF get optimized
                        // to absolute short
 
                        // Defined, absolute values from $FFFF8000..$00007FFF get optimized
                        // to absolute short
-                       if (optim_flags[OPT_ABS_SHORT]
+                       if (CHECK_OPTS(OPT_ABS_SHORT)
                                && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
                                && ((AnEXVAL + 0x8000) < 0x10000))
                        {
                                && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
                                && ((AnEXVAL + 0x8000) < 0x10000))
                        {
diff --git a/token.c b/token.c
index 2a8513d899a45f3f3883aaeacf6cd6aafc31afe0..1722f63ee5bf8c4d8785fb7d551fda4528796f53 100644 (file)
--- a/token.c
+++ b/token.c
@@ -36,6 +36,7 @@ TOKEN * tok;                          // Ptr to current token
 TOKEN * etok;                          // Ptr past last token in tokbuf[]
 TOKEN tokeol[1] = {EOL};       // Bailout end-of-line token
 char * string[TOKBUFSIZE*2];   // Token buffer string pointer storage
 TOKEN * etok;                          // Ptr past last token in tokbuf[]
 TOKEN tokeol[1] = {EOL};       // Bailout end-of-line token
 char * string[TOKBUFSIZE*2];   // Token buffer string pointer storage
+int optimizeOff;                       // Optimization override flag
 
 // File record, used to maintain a list of every include file ever visited
 #define FILEREC struct _filerec
 
 // File record, used to maintain a list of every include file ever visited
 #define FILEREC struct _filerec
@@ -48,12 +49,12 @@ FILEREC
 FILEREC * filerec;
 FILEREC * last_fr;
 
 FILEREC * filerec;
 FILEREC * last_fr;
 
-INOBJ * cur_inobj;                                             // Ptr current input obj (IFILE/IMACRO)
-static INOBJ * f_inobj;                                        // Ptr list of free INOBJs
-static IFILE * f_ifile;                                        // Ptr list of free IFILEs
-static IMACRO * f_imacro;                              // Ptr list of free IMACROs
+INOBJ * cur_inobj;                     // Ptr current input obj (IFILE/IMACRO)
+static INOBJ * f_inobj;                // Ptr list of free INOBJs
+static IFILE * f_ifile;                // Ptr list of free IFILEs
+static IMACRO * f_imacro;      // Ptr list of free IMACROs
 
 
-static TOKEN tokbuf[TOKBUFSIZE];               // Token buffer (stack-like, all files)
+static TOKEN tokbuf[TOKBUFSIZE];       // Token buffer (stack-like, all files)
 
 uint8_t chrtab[0x100] = {
        ILLEG, ILLEG, ILLEG, ILLEG,                     // NUL SOH STX ETX
 
 uint8_t chrtab[0x100] = {
        ILLEG, ILLEG, ILLEG, ILLEG,                     // NUL SOH STX ETX
@@ -824,17 +825,11 @@ DEBUG { printf("[fpop: (post) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)
        case SRC_IREPT:                                         // Pop and release an IREPT
        {
                DEBUG { printf("dealloc IREPT\n"); }
        case SRC_IREPT:                                         // Pop and release an IREPT
        {
                DEBUG { printf("dealloc IREPT\n"); }
-//             LONG * p = inobj->inobj.irept->ir_firstln;
                LLIST * p = inobj->inobj.irept->ir_firstln;
 
                // Deallocate repeat lines
                while (p != NULL)
                {
                LLIST * p = inobj->inobj.irept->ir_firstln;
 
                // Deallocate repeat lines
                while (p != NULL)
                {
-// Shamus: ggn confirmed that this will cause a segfault on 64-bit versions of
-//         RMAC. This is just stupid and wrong anyway, so we need to fix crapola
-//         like this...
-//                     LONG * p1 = (LONG *)*p;
-//                     p = p1;
                        free(p->line);
                        p = p->next;
                }
                        free(p->line);
                        p = p->next;
                }
@@ -1033,7 +1028,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); }
        case SRC_IREPT:
                if ((ln = GetNextRepeatLine()) == NULL)
                {
        case SRC_IREPT:
                if ((ln = GetNextRepeatLine()) == NULL)
                {
-DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); }
+                       DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); }
                        fpop();
                        goto retry;
                }
                        fpop();
                        goto retry;
                }
@@ -1059,6 +1054,16 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); }
        if (*ln == '*' || *ln == ';' || ((*ln == '/') && (*(ln + 1) == '/')))
                goto goteol;
 
        if (*ln == '*' || *ln == ';' || ((*ln == '/') && (*(ln + 1) == '/')))
                goto goteol;
 
+       // And here we have a very ugly hack for signalling a single line 'turn off
+       // optimization'. There's really no nice way to do this, so hack it is!
+       optimizeOff = 0;                // Default is to take optimizations as they come
+
+       if (*ln == '!')
+       {
+               optimizeOff = 1;        // Signal that we don't want to optimize this line
+               ln++;                           // & skip over the darned thing
+       }
+
        // Main tokenization loop;
        //  o  skip whitespace;
        //  o  handle end-of-line;
        // Main tokenization loop;
        //  o  skip whitespace;
        //  o  handle end-of-line;
diff --git a/token.h b/token.h
index 1d824a905966bde12b0b8b7036c6e77e4ac37215..f8df49ae19cc2c50bc197790e9397d20d363638e 100644 (file)
--- a/token.h
+++ b/token.h
@@ -84,6 +84,9 @@
 #define MULTX           64                     // Multiple-character tokens
 #define DOT             128                    // [bwlsBWSL] for what follows a '.'
 
 #define MULTX           64                     // Multiple-character tokens
 #define DOT             128                    // [bwlsBWSL] for what follows a '.'
 
+// Macro to check for specific optimizations or override
+#define CHECK_OPTS(x)  (optim_flags[x] && !optimizeOff)
+
 // Conditional assembly structures
 IFENT {
        IFENT * if_prev;                // Ptr prev .if state block (or NULL)
 // Conditional assembly structures
 IFENT {
        IFENT * if_prev;                // Ptr prev .if state block (or NULL)
@@ -156,6 +159,7 @@ extern char tolowertab[];
 extern INOBJ * cur_inobj;
 extern int mjump_align;
 extern char * string[];
 extern INOBJ * cur_inobj;
 extern int mjump_align;
 extern char * string[];
+int optimizeOff;
 
 // Exported functions
 int include(int, char *);
 
 // Exported functions
 int include(int, char *);