From: Shamus Hammons Date: Tue, 13 Sep 2016 01:37:51 +0000 (-0500) Subject: Fix for bug #78: Thanks to ggn for reporting and supplying the patch. X-Git-Tag: v2.1.0~158 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=commitdiff_plain;h=66be644c3e5fbd7446d86c79e9e51b75c0442b49;hp=171a457e86f686cf2adddc91baa9d9e703264259 Fix for bug #78: Thanks to ggn for reporting and supplying the patch. Bug fix for .w access for alcyon target, added new optimisation that converts 0(ax) to (ax). --- diff --git a/eagen0.c b/eagen0.c index c95d8b6..8ac72ed 100644 --- a/eagen0.c +++ b/eagen0.c @@ -39,6 +39,35 @@ int eaNgen(WORD siz) 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); @@ -114,7 +143,7 @@ int eaNgen(WORD siz) if (v + 0x80 >= 0x100) return error(range_error); - w |= v & 0xff; + w |= v & 0xFF; D_word(w); } else diff --git a/mach.c b/mach.c index ae5065b..be17c79 100644 --- a/mach.c +++ b/mach.c @@ -452,7 +452,7 @@ int m_move(WORD inst, WORD size) ea0gen((WORD)siz); if (am1 >= ADISP) - ea1gen((WORD)siz); + ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea } return 0; diff --git a/object.c b/object.c index 590f263..4614c38 100644 --- a/object.c +++ b/object.c @@ -228,12 +228,16 @@ int WriteObject(int fd) } // 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); } + 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 diff --git a/parmode.h b/parmode.h index c72b470..521f787 100644 --- a/parmode.h +++ b/parmode.h @@ -72,21 +72,22 @@ } 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; - // 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; - AMn_IXN: // Handle any indexed (tok -> a comma) + AMn_IXN: // Handle any indexed (tok -> a comma) if (*tok++ != ',') goto badmode; @@ -97,7 +98,7 @@ AnIXREG = *tok++ & 15; switch ((int)*tok) - { // Index reg size: | .W | .L + { // Index reg size: | .W | .L case DOTW: tok++; default: @@ -107,12 +108,12 @@ AnIXSIZ = 0x0800; tok++; break; - case DOTB: // .B not allowed here... + case DOTB: // .B not allowed here... goto badmode; } if (*tok == '*') - { // scale: *1, *2, *4, *8 + { // scale: *1, *2, *4, *8 tok++; if (*tok++ != CONST || *tok > 8) @@ -136,7 +137,7 @@ } } - if (*tok++ != ')') // final ")" + if (*tok++ != ')') // final ")" goto badmode; goto AnOK; @@ -146,7 +147,7 @@ goto unmode; } else - { // (expr... + { // (expr... if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) return ERROR; @@ -190,7 +191,7 @@ } else if (*tok == ')') { - AMn = PCDISP; // expr(PC) + AMn = PCDISP; // expr(PC) tok++; goto AnOK; } @@ -201,7 +202,7 @@ 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; @@ -243,6 +244,10 @@ CHK_FOR_DISPn: // 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 != '(') @@ -255,6 +260,7 @@ CHK_FOR_DISPn: 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"); } diff --git a/procln.c b/procln.c index 3b8c607..2cd1bdc 100644 --- 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; } + // 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) diff --git a/rmac.h b/rmac.h index 337096d..fdc36ea 100644 --- 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)) + #define inline __inline #endif diff --git a/sect.c b/sect.c index 5690b1b..619c163 100644 --- 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 +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 diff --git a/sect.h b/sect.h index d64e130..ceeb505 100644 --- a/sect.h +++ b/sect.h @@ -128,6 +128,7 @@ MCHUNK { extern LONG sloc; extern WORD scattr; extern char * chptr; +extern char * chptr_opcode; extern LONG ch_size; extern int cursect; extern SECT sect[]; diff --git a/token.c b/token.c index 5b3d073..4067711 100644 --- 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 == '.') { - 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') { @@ -1306,6 +1299,20 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); *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++ = '$'; diff --git a/version.h b/version.h index b4f423c..098b1e7 100644 --- a/version.h +++ b/version.h @@ -13,6 +13,6 @@ #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__