Fix for bug #78: Thanks to ggn for reporting and supplying the patch.
authorShamus Hammons <jlhamm@acm.org>
Tue, 13 Sep 2016 01:37:51 +0000 (20:37 -0500)
committerShamus Hammons <jlhamm@acm.org>
Tue, 13 Sep 2016 01:37:51 +0000 (20:37 -0500)
Bug fix for .w access for alcyon target, added new optimisation that
converts 0(ax) to (ax).

eagen0.c
mach.c
object.c
parmode.h
procln.c
rmac.h
sect.c
sect.h
token.c
version.h

index c95d8b677146703d9d22354357de924cbd7c8ae5..8ac72ed3824ff3e2cd7055805d3ff276439aa590 100644 (file)
--- a/eagen0.c
+++ b/eagen0.c
@@ -39,6 +39,35 @@ int eaNgen(WORD siz)
                        if (tdb)
                                rmark(cursect, sloc, tdb, MWORD, NULL);
 
                        if (tdb)
                                rmark(cursect, sloc, tdb, MWORD, NULL);
 
+                       if ((v == 0) && optim_flag)
+                       {
+                               // If expr is 0, size optimise the opcode.
+                               // Generally the lower 6 bits of the opcode
+                               // for expr(ax) are 101rrr where rrr=the
+                               // number of the register, then followed by
+                               // a word containing 'expr'. We need to change
+                               // that to 010rrr.
+                               if ((siz & 0x8000) == 0)
+                               {
+                                       chptr_opcode[0] &= ((0xFFC7 >> 8) & 255); // mask off bits
+                                       chptr_opcode[1] &= 0xFFC7 & 255;          // mask off bits
+                                       chptr_opcode[0] |= ((0x0010 >> 8) & 255); // slap in 010 bits
+                                       chptr_opcode[1] |= 0x0010 & 255;          // slap in 010 bits
+                               }
+                               else
+                               {
+                                       // Special case for move ea,ea:
+                                       // there are two ea fields there and
+                                       // we get a signal if it's the second ea field
+                                       // from m_ea - siz's 16th bit is set
+                                       chptr_opcode[0] &= ((0xFE3F >> 8) & 255); // mask off bits
+                                       chptr_opcode[1] &= 0xFE3F & 255;          // mask off bits
+                                       chptr_opcode[0] |= ((0x0080 >> 8) & 255); // slap in 010 bits
+                                       chptr_opcode[1] |= 0x0080 & 255;          // slap in 010 bits
+                               }
+                               return OK;
+                       }
+
                        if (v + 0x8000 >= 0x18000)
                                return error(range_error);
 
                        if (v + 0x8000 >= 0x18000)
                                return error(range_error);
 
@@ -114,7 +143,7 @@ int eaNgen(WORD siz)
                        if (v + 0x80 >= 0x100)
                                return error(range_error);
 
                        if (v + 0x80 >= 0x100)
                                return error(range_error);
 
-                       w |= v & 0xff;
+                       w |= v & 0xFF;
                        D_word(w);
                }
                else
                        D_word(w);
                }
                else
diff --git a/mach.c b/mach.c
index ae5065bf87c85a5c381d72ee917ceb3b96575d0d..be17c79568aece50da2505c7f5ee65307c625e09 100644 (file)
--- a/mach.c
+++ b/mach.c
@@ -452,7 +452,7 @@ int m_move(WORD inst, WORD size)
                        ea0gen((WORD)siz);
 
                if (am1 >= ADISP)
                        ea0gen((WORD)siz);
 
                if (am1 >= ADISP)
-                       ea1gen((WORD)siz);
+                       ea1gen((WORD)siz | 0x8000);   // Tell ea1gen we're move ea,ea
        }
 
        return 0;
        }
 
        return 0;
index 590f2631fe6fabb71b1fd132b834fa2f91e588aa..4614c38d66ed373eed028d7f0ed9a849f1282017 100644 (file)
--- a/object.c
+++ b/object.c
@@ -228,12 +228,16 @@ int WriteObject(int fd)
        }
 
        // Write requested object file...
        }
 
        // Write requested object file...
-       if (obj_format==BSD || (obj_format==ALCYON && prg_flag==0))
+       if ((obj_format == BSD) || ((obj_format == ALCYON) && (prg_flag == 0)))
     {
     {
+               // Force BSD format from here onwards
+               obj_format = BSD;
+
                if (verb_flag)
                {
                        printf("Total       : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc);
                }
                if (verb_flag)
                {
                        printf("Total       : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc);
                }
+
                ssize = ((LONG)sy_assign(NULL, NULL));          // Assign index numbers to the symbols
                tds = sect[TEXT].sloc + sect[DATA].sloc;        // Get size of TEXT and DATA segment
                buf = malloc(0x600000);                                         // Allocate 6mb object file image memory
                ssize = ((LONG)sy_assign(NULL, NULL));          // Assign index numbers to the symbols
                tds = sect[TEXT].sloc + sect[DATA].sloc;        // Get size of TEXT and DATA segment
                buf = malloc(0x600000);                                         // Allocate 6mb object file image memory
index c72b47012613e6ffd4d3b15bbdcf75e221157601..521f787e9fe39897b4bfe5d7797fc79b3aabd7cd 100644 (file)
--- a/parmode.h
+++ b/parmode.h
                        }
 
                        AMn = AINDEXED;
                        }
 
                        AMn = AINDEXED;
-                       goto AMn_IX0;                                      // Handle ",Xn[.siz][*scale])"
+                       goto AMn_IX0;            // Handle ",Xn[.siz][*scale])"
                }
                else if (*tok == KW_PC)
                {                            // (PC,Xn[.siz][*scale]) 
                        tok++;
                        AMn = PCINDEXED;
 
                }
                else if (*tok == KW_PC)
                {                            // (PC,Xn[.siz][*scale]) 
                        tok++;
                        AMn = PCINDEXED;
 
-                       // Common index handler; enter here with `tok' pointing at the comma.
+                       // Common index handler; enter here with 'tok' pointing at the
+                       // comma.
 
 
-                       AMn_IX0:                                           // Handle indexed with missing expr
+                       AMn_IX0:                 // Handle indexed with missing expr
 
                        AnEXVAL = 0;
                        AnEXATTR = ABS | DEFINED;
 
 
                        AnEXVAL = 0;
                        AnEXATTR = ABS | DEFINED;
 
-                       AMn_IXN:                                           // Handle any indexed (tok -> a comma)
+                       AMn_IXN:                 // Handle any indexed (tok -> a comma)
 
                        if (*tok++ != ',')
                                goto badmode;
 
                        if (*tok++ != ',')
                                goto badmode;
@@ -97,7 +98,7 @@
                        AnIXREG = *tok++ & 15;
 
                        switch ((int)*tok)
                        AnIXREG = *tok++ & 15;
 
                        switch ((int)*tok)
-                       {                                // Index reg size: <empty> | .W | .L 
+                       {                        // Index reg size: <empty> | .W | .L 
                        case DOTW:
                                tok++;
                        default:
                        case DOTW:
                                tok++;
                        default:
                                AnIXSIZ = 0x0800;
                                tok++;
                                break;
                                AnIXSIZ = 0x0800;
                                tok++;
                                break;
-                       case DOTB:                                      // .B not allowed here...
+                       case DOTB:               // .B not allowed here...
                                goto badmode;
                        }
 
                        if (*tok == '*')
                                goto badmode;
                        }
 
                        if (*tok == '*')
-                       {                                  // scale: *1, *2, *4, *8 
+                       {                        // scale: *1, *2, *4, *8 
                                tok++;
 
                                if (*tok++ != CONST || *tok > 8)
                                tok++;
 
                                if (*tok++ != CONST || *tok > 8)
                                }
                        }
 
                                }
                        }
 
-                       if (*tok++ != ')')                                  // final ")" 
+                       if (*tok++ != ')')         // final ")" 
                                goto badmode;
 
                        goto AnOK;
                                goto badmode;
 
                        goto AnOK;
                        goto unmode;
                }
                else
                        goto unmode;
                }
                else
-               {                                              // (expr... 
+               {                              // (expr... 
                        if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
                                return ERROR;
 
                        if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
                                return ERROR;
 
                                }
                                else if (*tok == ')')
                                {
                                }
                                else if (*tok == ')')
                                {
-                                       AMn = PCDISP;                                // expr(PC) 
+                                       AMn = PCDISP;             // expr(PC) 
                                        tok++;
                                        goto AnOK;
                                }
                                        tok++;
                                        goto AnOK;
                                }
                                goto badmode;
                }
        }
                                goto badmode;
                }
        }
-       else if (*tok=='-' && tok[1]=='(' && ((tok[2]>=KW_A0) && (tok[2]<=KW_A7)) && tok[3]==')')
+       else if (*tok == '-' && tok[1] == '(' && ((tok[2] >= KW_A0) && (tok[2] <= KW_A7)) && tok[3] == ')')
        {
                AMn = APREDEC;
                AnREG = tok[2] & 7;
        {
                AMn = APREDEC;
                AnREG = tok[2] & 7;
@@ -243,6 +244,10 @@ CHK_FOR_DISPn:
                        // expr.W 
                        tok++;
                        AMn = ABSW;
                        // expr.W 
                        tok++;
                        AMn = ABSW;
+
+                       if ((AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL < 0x10000))
+                               AnEXVAL = (int32_t)(int16_t)AnEXVAL;  // Sign extend value
+
                        goto AnOK;
                }
                else if (*tok != '(')
                        goto AnOK;
                }
                else if (*tok != '(')
@@ -255,6 +260,7 @@ CHK_FOR_DISPn:
                        if (optim_flag && (AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
                        {
                                AMn = ABSW;
                        if (optim_flag && (AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
                        {
                                AMn = ABSW;
+
                                if (sbra_flag)
                                        warn("absolute value from $FFFF8000..$00007FFF optimised to absolute short");
                        }
                                if (sbra_flag)
                                        warn("absolute value from $FFFF8000..$00007FFF optimised to absolute short");
                        }
index 3b8c607db3c8c5ed40ffc6778da64bda7e36aa86..2cd1bdc3d513b6b7476d33cea3c59b0e09f8b357 100644 (file)
--- a/procln.c
+++ b/procln.c
@@ -660,6 +660,9 @@ When checking to see if it's already been equated, issue a warning.
                goto loop;
        }
 
                goto loop;
        }
 
+       // Keep a backup of chptr (used for optimisations during codegen)
+       chptr_opcode = chptr;
+
        for(;;)
        {
                if ((m->mnattr & siz) && (amsk0 & m->mn0) != 0 && (amsk1 & m->mn1) != 0)
        for(;;)
        {
                if ((m->mnattr & siz) && (amsk0 & m->mn0) != 0 && (amsk1 & m->mn1) != 0)
diff --git a/rmac.h b/rmac.h
index 337096d1ae61d1fafa8922c1ff5c445b951c459c..fdc36ea72a38bddf7a8fb483a42a4a4b02d2facb 100644 (file)
--- a/rmac.h
+++ b/rmac.h
@@ -47,6 +47,7 @@
        //this is probably going to explode spectacularly. Let's wait for the fireworks!
        #define DO_PRAGMA(x) _Pragma (#x)
        #define WARNING(desc) DO_PRAGMA(message (#desc))
        //this is probably going to explode spectacularly. Let's wait for the fireworks!
        #define DO_PRAGMA(x) _Pragma (#x)
        #define WARNING(desc) DO_PRAGMA(message (#desc))
+       #define inline __inline
 
        #endif
 
 
        #endif
 
diff --git a/sect.c b/sect.c
index 5690b1bd52c7ed8688617b4282ceb2989055d9df..619c1632b00879c72eda8bd132fa55a9c9e0a3f4 100644 (file)
--- a/sect.c
+++ b/sect.c
@@ -36,6 +36,7 @@ CHUNK * scode;                        // Current (last) code chunk
 LONG challoc;                  // # bytes alloc'd to code chunk 
 LONG ch_size;                  // # bytes used in code chunk 
 char * chptr;                  // Deposit point in code chunk buffer 
 LONG challoc;                  // # bytes alloc'd to code chunk 
 LONG ch_size;                  // # bytes used in code chunk 
 char * chptr;                  // Deposit point in code chunk buffer 
+char * chptr_opcode;   // Backup of chptr, updated before entering code generators
 
 CHUNK * sfix;                  // Current (last) fixup chunk
 LONG fchalloc;                 // # bytes alloc'd to fixup chunk
 
 CHUNK * sfix;                  // Current (last) fixup chunk
 LONG fchalloc;                 // # bytes alloc'd to fixup chunk
diff --git a/sect.h b/sect.h
index d64e130ee32b87ff30f327c5915eca60bd418190..ceeb5052a8c25823217f42de9eba57346ffb507a 100644 (file)
--- a/sect.h
+++ b/sect.h
@@ -128,6 +128,7 @@ MCHUNK {
 extern LONG sloc;
 extern WORD scattr;
 extern char * chptr;
 extern LONG sloc;
 extern WORD scattr;
 extern char * chptr;
+extern char * chptr_opcode;
 extern LONG ch_size;
 extern int cursect;
 extern SECT sect[];
 extern LONG ch_size;
 extern int cursect;
 extern SECT sect[];
diff --git a/token.c b/token.c
index 5b3d0737b02ea308f19938d86ec1ec3bfd3fcc53..4067711be2ff7ddd1dcd5e4f51fb04cc3cad6795 100644 (file)
--- a/token.c
+++ b/token.c
@@ -1278,14 +1278,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
                                        // auto-optimise? I think it's ok for now...
                                        if (*ln == '.')
                                        {
                                        // auto-optimise? I think it's ok for now...
                                        if (*ln == '.')
                                        {
-                                               if (obj_format == ALCYON)
-                                               {
-                                                       if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B') || (*(ln + 1) == 'w') || (*(ln + 1) == 'W') || (*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
-                                                       {
-                                                               ln += 2;
-                                                       }
-                                               }
-                                               else
+                                               if (obj_format == BSD)
                                                {
                                                        if ((*(ln + 1) & 0xDF) == 'B')
                                                        {
                                                {
                                                        if ((*(ln + 1) & 0xDF) == 'B')
                                                        {
@@ -1306,6 +1299,20 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
 
                                        *tk++ = CONST;
                                        *tk++ = v;
 
                                        *tk++ = CONST;
                                        *tk++ = v;
+
+                                       if (obj_format == ALCYON)
+                                       {
+                                               if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W'))
+                                               {
+                                                       *tk++ = DOTW;
+                                                       ln += 2;
+                                               }
+                                               else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
+                                               {
+                                                       *tk++ = DOTL;
+                                                       ln += 2;
+                                               }
+                                       }
                                }
                                else
                                        *tk++ = '$';
                                }
                                else
                                        *tk++ = '$';
index b4f423c29bf8d65c85484ac45d6a01c1cca3555d..098b1e7c86f755e6b3dbcd4c552d3ad52a79caba 100644 (file)
--- a/version.h
+++ b/version.h
@@ -13,6 +13,6 @@
 
 #define MAJOR   1              // Major version number
 #define MINOR   4              // Minor version number
 
 #define MAJOR   1              // Major version number
 #define MINOR   4              // Minor version number
-#define PATCH   13             // Patch release number
+#define PATCH   14             // Patch release number
 
 #endif // __VERSION_H__
 
 #endif // __VERSION_H__