From ff8188b7e279f99cf11ac8a283c4146af324d26f Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Sun, 8 Oct 2017 08:40:02 -0500 Subject: [PATCH 1/1] Add support for 64-bit evaluations. Version bump to 1.9.0. Right now the only thing that supports it is dc.d; now that the infrastructure supports it, anything else that needs 64-bit support (such as FPUs and the like) can be done very easily now. --- 6502.c | 2 +- amode.c | 16 +++++---- amode.h | 6 ++-- debug.c | 10 +++--- direct.c | 38 ++++++++++++-------- direct.h | 2 +- expr.c | 42 +++++++++++++++------- expr.h | 4 +-- mach.c | 8 +++-- macro.c | 9 ++--- parmode.h | 106 +++++++++++++++++++++++++++--------------------------- procln.c | 5 +-- riscasm.c | 7 ++-- sect.c | 8 +++-- token.c | 28 ++++++++++----- version.h | 4 +-- 16 files changed, 171 insertions(+), 124 deletions(-) diff --git a/6502.c b/6502.c index f7078b8..4f259f9 100644 --- a/6502.c +++ b/6502.c @@ -247,7 +247,7 @@ void m6502cg(int op) { register int amode; // (Parsed) addressing mode register int i; - uint32_t eval; // Expression value + uint64_t eval; // Expression value WORD eattr; // Expression attributes int zpreq; // 1, optimize instr to zero-page form register char * p; // (Temp) string usage diff --git a/amode.c b/amode.c index 3d789af..70b30e1 100644 --- a/amode.c +++ b/amode.c @@ -27,16 +27,16 @@ int nmodes; // Number of addr'ing modes found int am0; // Addressing mode int a0reg; // Register TOKEN a0expr[EXPRSIZE]; // Expression -uint32_t a0exval; // Expression's value +uint64_t a0exval; // Expression's value WORD a0exattr; // Expression's attribute int a0ixreg; // Index register int a0ixsiz; // Index register size (and scale) TOKEN a0oexpr[EXPRSIZE]; // Outer displacement expression -uint32_t a0oexval; // Outer displacement value +uint32_t a0oexval; // Outer displacement value WORD a0oexattr; // Outer displacement attribute SYM * a0esym; // External symbol involved in expr TOKEN a0bexpr[EXPRSIZE]; // Base displacement expression -uint32_t a0bexval; // Base displacement value +uint64_t a0bexval; // Base displacement value WORD a0bexattr; // Base displacement attribute WORD a0bsize; // Base displacement size WORD a0extension; // 020+ extension address word @@ -45,16 +45,16 @@ WORD am0_030; // ea bits for 020+ addressing modes int am1; // Addressing mode int a1reg; // Register TOKEN a1expr[EXPRSIZE]; // Expression -uint32_t a1exval; // Expression's value +uint64_t a1exval; // Expression's value WORD a1exattr; // Expression's attribute int a1ixreg; // Index register int a1ixsiz; // Index register size (and scale) TOKEN a1oexpr[EXPRSIZE]; // Outer displacement expression -uint32_t a1oexval; // Outer displacement value +uint32_t a1oexval; // Outer displacement value WORD a1oexattr; // Outer displacement attribute SYM * a1esym; // External symbol involved in expr TOKEN a1bexpr[EXPRSIZE]; // Base displacement expression -uint32_t a1bexval; // Base displacement value +uint64_t a1bexval; // Base displacement value WORD a1bexattr; // Base displacement attribute WORD a1bsize; // Base displacement size WORD a1extension; // 020+ extension address word @@ -68,7 +68,7 @@ int bfparam2; // bfxxx / fmove instruction parameter 2 int bfval1; //bfxxx / fmove value 1 int bfval2; //bfxxx / fmove value 2 TOKEN bf0expr[EXPRSIZE]; // Expression -uint32_t bf0exval; // Expression's value +uint64_t bf0exval; // Expression's value WORD bf0exattr; // Expression's attribute SYM * bf0esym; // External symbol involved in expr @@ -388,6 +388,7 @@ int check030bf(void) if (*tok == CONST) { + tok++; // Skip the HI LONG tok++; bfval1 = *(int *)tok; @@ -430,6 +431,7 @@ int check030bf(void) if (*tok == CONST) { + tok++; // Skip the HI LONG tok++; bfval2 = *(int *)tok; diff --git a/amode.h b/amode.h index f1a47a8..76501f7 100644 --- a/amode.h +++ b/amode.h @@ -137,7 +137,7 @@ extern int nmodes; extern int am0, am1; extern int a0reg, a1reg, a2reg; extern TOKEN a0expr[], a1expr[]; -extern uint32_t a0exval, a1exval; +extern uint64_t a0exval, a1exval; extern WORD a0exattr, a1exattr; extern int a0ixreg, a1ixreg; extern int a0ixsiz, a1ixsiz; @@ -145,7 +145,7 @@ extern TOKEN a0oexpr[], a1oexpr[]; extern uint32_t a0oexval, a1oexval; extern WORD a0oexattr, a1oexattr; extern SYM * a0esym, * a1esym; -extern uint32_t a0bexval, a1bexval; +extern uint64_t a0bexval, a1bexval; extern WORD a0bexattr, a1bexattr; extern WORD a0bsize, a1bsize; extern TOKEN a0bexpr[], a1bexpr[]; @@ -155,7 +155,7 @@ extern int bfparam1; extern int bfparam2; extern int bfval1; extern int bfval2; -extern uint32_t bf0exval; +extern uint64_t bf0exval; // mnattr: #define CGSPECIAL 0x8000 // Special (don't parse addr modes) diff --git a/debug.c b/debug.c index 0488aff..87861b9 100644 --- a/debug.c +++ b/debug.c @@ -47,7 +47,8 @@ TOKEN * printexpr(TOKEN * tp) tp++; break; case CONST: - printf("$%X ", *tp++); + printf("$%lX ", ((uint64_t)tp[0] << 32) | (uint64_t)tp[1]); + tp += 2; break; case ACONST: printf("ACONST=($%X,$%X) ", *tp, tp[1]); @@ -280,7 +281,8 @@ int dumptok(TOKEN * tk) switch ((int)*tk++) { case CONST: // CONST - printf("CONST=%u", *tk++); + printf("CONST=%lu", ((uint64_t)tk[0] << 32) | (uint64_t)tk[1]); + tk += 2; break; case STRING: // STRING
printf("STRING='%s'", string[*tk++]); @@ -337,8 +339,8 @@ void DumpTokens(TOKEN * tokenBuffer) printf("[COLON]"); else if (*t == CONST) { - t++; - printf("[CONST: $%X]", (uint32_t)*t); + printf("[CONST: $%lX]", ((uint64_t)t[1] << 32) | (uint64_t)t[2]); + t += 2; } else if (*t == ACONST) { diff --git a/direct.c b/direct.c index 54c09d6..770fcf9 100644 --- a/direct.c +++ b/direct.c @@ -213,7 +213,7 @@ int d_warn(char *str) // int d_org(void) { - uint32_t address; + uint64_t address; if (!rgpu && !rdsp && !m6502) return error(".org permitted only in gpu/dsp and 6502 sections"); @@ -266,7 +266,7 @@ int d_print(void) int wordlong = 0; // WORD = 0, LONG = 1 int outtype = 0; // 0:hex, 1:decimal, 2:unsigned - uint32_t eval; // Expression value + uint64_t eval; // Expression value WORD eattr; // Expression attributes SYM * esym; // External symbol involved in expr. TOKEN r_expr[EXPRSIZE]; @@ -687,7 +687,7 @@ int d_unimpl(void) // // Return absolute (not TDB) and defined expression or return an error // -int abs_expr(uint32_t * a_eval) +int abs_expr(uint64_t * a_eval) { WORD eattr; @@ -795,7 +795,7 @@ allright: int d_assert(void) { WORD eattr; - uint32_t eval; + uint64_t eval; for(; expr(exprbuf, &eval, &eattr, NULL)==OK; ++tok) { @@ -853,7 +853,7 @@ int d_globl(void) // int d_prgflags(void) { - uint32_t eval; + uint64_t eval; if (*tok == EOL) return error("PRGFLAGS requires value"); @@ -874,7 +874,7 @@ int d_prgflags(void) // int d_abs(void) { - uint32_t eval; + uint64_t eval; if (m6502) return error(in_6502mode); @@ -953,7 +953,7 @@ int d_ds(WORD siz) { DEBUG { printf("Directive: .ds.[size] = %u, sloc = $%X\n", siz, sloc); } - uint32_t eval; + uint64_t eval; if (cursect != M6502) { @@ -1001,7 +1001,7 @@ int d_ds(WORD siz) int d_dc(WORD siz) { WORD eattr; - uint32_t eval; + uint64_t eval; uint8_t * p; if ((scattr & SBSS) != 0) @@ -1112,6 +1112,7 @@ int d_dc(WORD siz) break; case SIZL: + // Shamus: Why can't we do longs in 6502 mode? if (m6502) return error(in_6502mode); @@ -1135,6 +1136,13 @@ int d_dc(WORD siz) D_long(eval); } break; + case SIZD: + // 64-bit size + // N.B.: May have to come up with section/fixup markers for this; + // ATM it's only used in dc.d statements... + D_long(eval >> 32); + D_long(eval & 0xFFFFFFFF); + break; } comma: @@ -1152,7 +1160,7 @@ comma: // int d_dcb(WORD siz) { - uint32_t evalc, eval; + uint64_t evalc, eval; WORD eattr; DEBUG { printf("dcb: section is %s%s%s (scattr=$%X)\n", (cursect & TEXT ? "TEXT" : ""), (cursect & DATA ? " DATA" : ""), (cursect & BSS ? "BSS" : ""), scattr); } @@ -1189,8 +1197,8 @@ int d_dcb(WORD siz) // int d_init(WORD def_siz) { - uint32_t count; - uint32_t eval; + uint64_t count; + uint64_t eval; WORD eattr; WORD siz; @@ -1339,7 +1347,7 @@ int d_comm(void) { SYM * sym; char * p; - uint32_t eval; + uint64_t eval; if (m6502) return error(in_6502mode); @@ -1566,7 +1574,7 @@ int d_dsp(void) // int d_cargs(void) { - uint32_t eval = 4; // Default to 4 if no offset specified (to account for + uint64_t eval = 4; // Default to 4 if no offset specified (to account for // return address) WORD rlist; SYM * symbol; @@ -1681,7 +1689,7 @@ int d_cargs(void) // int d_cstruct(void) { - uint32_t eval = 0; // Default, if no offset specified, is zero + uint64_t eval = 0; // Default, if no offset specified, is zero WORD rlist; SYM * symbol; char * symbolName; @@ -1870,7 +1878,7 @@ int d_opt(void) int d_if(void) { WORD eattr; - uint32_t eval; + uint64_t eval; SYM * esym; IFENT * rif = f_ifent; diff --git a/direct.h b/direct.h index 0f9615e..ea1aa23 100644 --- a/direct.h +++ b/direct.h @@ -21,7 +21,7 @@ extern int largestAlign[]; void auto_even(void); int dep_block(uint32_t, WORD, uint32_t, WORD, TOKEN *); int eject(void); -int abs_expr(uint32_t *); +int abs_expr(uint64_t *); int symlist(int(*)()); int d_even(void); diff --git a/expr.c b/expr.c index 8d18a67..dea1de9 100644 --- a/expr.c +++ b/expr.c @@ -23,7 +23,7 @@ // N.B.: The size of tokenClass should be identical to the largest value of // a token; we're assuming 256 but not 100% sure! static char tokenClass[256]; // Generated table of token classes -static uint32_t evstk[EVSTACKSIZE]; // Evaluator value stack +static uint64_t evstk[EVSTACKSIZE]; // Evaluator value stack static WORD evattr[EVSTACKSIZE]; // Evaluator attribute stack // Token-class initialization list @@ -154,14 +154,17 @@ int expr1(void) { case CR_ABSCOUNT: *evalTokenBuffer++ = CONST; + *evalTokenBuffer++ = 0; // Set HI LONG to zero *evalTokenBuffer++ = (LONG)sect[ABS].sloc; break; case CR_TIME: *evalTokenBuffer++ = CONST; + *evalTokenBuffer++ = 0; // Set HI LONG to zero *evalTokenBuffer++ = dos_time(); break; case CR_DATE: *evalTokenBuffer++ = CONST; + *evalTokenBuffer++ = 0; // Set HI LONG to zero *evalTokenBuffer++ = dos_date(); break; case CR_MACDEF: // ^^macdef @@ -171,6 +174,7 @@ int expr1(void) p = string[*tok++]; w = (lookup(p, MACRO, 0) == NULL ? 0 : 1); *evalTokenBuffer++ = CONST; + *evalTokenBuffer++ = 0; // Set HI LONG to zero *evalTokenBuffer++ = (TOKEN)w; break; case CR_DEFINED: @@ -186,6 +190,7 @@ getsym: j = (*p == '.' ? curenv : 0); w = ((sy = lookup(p, LABEL, j)) != NULL && (sy->sattr & w) ? 1 : 0); *evalTokenBuffer++ = CONST; + *evalTokenBuffer++ = 0; // Set HI LONG to zero *evalTokenBuffer++ = (TOKEN)w; break; case CR_STREQ: @@ -206,6 +211,7 @@ getsym: w = (WORD)(!strcmp(p, p2)); *evalTokenBuffer++ = CONST; + *evalTokenBuffer++ = 0; // Set HI LONG to zero *evalTokenBuffer++ = (TOKEN)w; break; } @@ -230,7 +236,8 @@ int expr2(void) { case CONST: *evalTokenBuffer++ = CONST; - *evalTokenBuffer++ = *tok++; + *evalTokenBuffer++ = *tok++; // HI LONG of constant + *evalTokenBuffer++ = *tok++; // LO LONG of constant break; case SYMBOL: p = string[*tok++]; @@ -257,6 +264,7 @@ int expr2(void) break; case STRING: *evalTokenBuffer++ = CONST; + *evalTokenBuffer++ = 0; // Set HI LONG to zero *evalTokenBuffer++ = str_value(string[*tok++]); break; case '(': @@ -313,7 +321,7 @@ int expr2(void) // // Recursive-descent expression analyzer (with some simple speed hacks) // -int expr(TOKEN * otk, uint32_t * a_value, WORD * a_attr, SYM ** a_esym) +int expr(TOKEN * otk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym) { // Passed in values (once derefenced, that is) can all be zero. They are // there so that the expression analyzer can fill them in as needed. The @@ -324,7 +332,8 @@ int expr(TOKEN * otk, uint32_t * a_value, WORD * a_attr, SYM ** a_esym) int j; evalTokenBuffer = otk; // Set token pointer to 'exprbuf' (direct.c) - // Also set in various other places too (riscasm.c, e.g.) + // Also set in various other places too (riscasm.c, + // e.g.) //printf("expr(): tokens 0-2: %i %i %i (%c %c %c); tc[2] = %i\n", tok[0], tok[1], tok[2], tok[0], tok[1], tok[2], tokenClass[tok[2]]); // Optimize for single constant or single symbol. @@ -335,12 +344,17 @@ int expr(TOKEN * otk, uint32_t * a_value, WORD * a_attr, SYM ** a_esym) // Seems that even other tokens (SUNARY type) can fuck this up too. // if ((tok[1] == EOL) if ((tok[1] == EOL && (tok[0] != CONST && tokenClass[tok[0]] != SUNARY)) - || (((*tok == CONST || *tok == SYMBOL) || (*tok >= KW_R0 && *tok <= KW_R31)) - && (tokenClass[tok[2]] < UNARY))) +// || (((*tok == CONST || *tok == SYMBOL) || (*tok >= KW_R0 && *tok <= KW_R31)) +// && (tokenClass[tok[2]] < UNARY))) + || (((tok[0] == SYMBOL) || (tok[0] >= KW_R0 && tok[0] <= KW_R31)) + && (tokenClass[tok[2]] < UNARY)) + || ((tok[0] == CONST) && (tokenClass[tok[3]] < UNARY)) + ) { if (*tok >= KW_R0 && *tok <= KW_R31) { *evalTokenBuffer++ = CONST; + *evalTokenBuffer++ = 0; // Set HI LONG to zero *evalTokenBuffer++ = *a_value = (*tok - KW_R0); *a_attr = ABS | DEFINED; @@ -352,18 +366,21 @@ int expr(TOKEN * otk, uint32_t * a_value, WORD * a_attr, SYM ** a_esym) else if (*tok == CONST) { *evalTokenBuffer++ = CONST; - *evalTokenBuffer++ = *a_value = tok[1]; + *evalTokenBuffer++ = tok[1]; + *evalTokenBuffer++ = tok[2]; + *a_value = (((uint64_t)tok[1]) << 32) | tok[2]; *a_attr = ABS | DEFINED; if (a_esym != NULL) *a_esym = NULL; - tok += 2; + tok += 3; //printf("Quick eval in expr(): CONST = %i, tokenClass[tok[2]] = %i\n", *a_value, tokenClass[*tok]); } else if (*tok == '*') { *evalTokenBuffer++ = CONST; + *evalTokenBuffer++ = 0; // Set HI LONG to zero if (orgactive) *evalTokenBuffer++ = *a_value = orgaddr; @@ -476,11 +493,11 @@ thrown away right here. What the hell is it for? // UNDEFINED, but it's value includes everything but the symbol value, and // `a_esym' is set to the external symbol. // -int evexpr(TOKEN * tk, uint32_t * a_value, WORD * a_attr, SYM ** a_esym) +int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym) { WORD attr; SYM * sy; - uint32_t * sval = evstk; // (Empty) initial stack + uint64_t * sval = evstk; // (Empty) initial stack WORD * sattr = evattr; SYM * esym = NULL; // No external symbol involved WORD sym_seg = 0; @@ -523,8 +540,9 @@ int evexpr(TOKEN * tk, uint32_t * a_value, WORD * a_attr, SYM ** a_esym) sym_seg = (WORD)(sy->sattr & TDB); break; case CONST: -//printf("evexpr(): CONST = %i\n", *tk); - *++sval = *tk++; // Push value + *++sval = ((uint64_t)*tk++) << 32; // Push value + *sval |= *tk++; // & LO LONG (will this work???--should) +//printf("evexpr(): CONST = %lX\n", *sval); *++sattr = ABS | DEFINED; // Push simple attribs break; case ACONST: diff --git a/expr.h b/expr.h index 190fbe4..f03ca1e 100644 --- a/expr.h +++ b/expr.h @@ -34,7 +34,7 @@ void InitExpression(void); int expr1(void); int expr2(void); -int expr(TOKEN *, uint32_t *, WORD *, SYM **); -int evexpr(TOKEN *, uint32_t *, WORD *, SYM **); +int expr(TOKEN *, uint64_t *, WORD *, SYM **); +int evexpr(TOKEN *, uint64_t *, WORD *, SYM **); #endif // __EXPR_H__ diff --git a/mach.c b/mach.c index e01ea88..e8a719b 100644 --- a/mach.c +++ b/mach.c @@ -822,10 +822,12 @@ int m_move(WORD inst, WORD size) int siz = (int)size; // Try to optimize to MOVEQ + // N.B.: We can get away with casting the uint64_t to a 32-bit value + // because it checks for a SIZL (i.e., a 32-bit value). if (CHECK_OPTS(OPT_MOVEL_MOVEQ) && (siz == SIZL) && (am0 == IMMED) && (am1 == DREG) && ((a0exattr & (TDB | DEFINED)) == DEFINED) - && (a0exval + 0x80 < 0x100)) + && ((uint32_t)a0exval + 0x80 < 0x100)) { m_moveq((WORD)0x7000, (WORD)0); @@ -979,7 +981,7 @@ int m_br(WORD inst, WORD siz) return error(rel_error); //} - v = a0exval - (sloc + 2); + v = (uint32_t)a0exval - (sloc + 2); // Optimize branch instr. size if (siz == SIZN) @@ -1105,7 +1107,7 @@ int m_trap(WORD inst, WORD siz) // int m_movem(WORD inst, WORD siz) { - uint32_t eval; + uint64_t eval; WORD i; WORD w; WORD rmask; diff --git a/macro.c b/macro.c index 469a88c..ccc93dc 100644 --- a/macro.c +++ b/macro.c @@ -244,7 +244,7 @@ WARNING("!!! Casting (char *) as LONG !!!") // int HandleRept(void) { - uint32_t eval; + uint64_t eval; // Evaluate repeat expression if (abs_expr(&eval) != OK) @@ -410,10 +410,11 @@ int InvokeMacro(SYM * mac, WORD siz) for(int i=0; i<3; i++) *p++ = *tok++; } - else if (*tok == CONST) + else if (*tok == CONST) // Constants are 64-bits { - *p++ = *tok++; - *p++ = *tok++; + *p++ = *tok++; // Token + *p++ = *tok++; // Hi LONG + *p++ = *tok++; // Lo LONG } else if ((*tok == STRING) || (*tok == SYMBOL)) { diff --git a/parmode.h b/parmode.h index 60eca33..4b6c7ea 100644 --- a/parmode.h +++ b/parmode.h @@ -78,6 +78,7 @@ { //Since index register isn't used here, store register number in this field AnIXREG = *tok++ & 7; // (Dn) + if (*tok == ')') { tok++; @@ -85,21 +86,21 @@ AnEXTEN |= EXT_BS; // Base register suppressed AnEXTEN |= EXT_BDSIZE0; // Base displacement null AnEXTEN |= EXT_IISPOSN; // Indirect Postindexed with Null Outer Displacement - AMn= MEMPOST; + AMn = MEMPOST; AnREG = 6 << 3; // stuff 110 to mode field goto AnOK; } else if (*tok == 'L') { // TODO: does DINDL gets used at all? - AMn=DINDL; // (Dn.l) + AMn = DINDL; // (Dn.l) AnEXTEN = 1 << 1; // Long index size tok++; } else if (*tok == 'W') // (Dn.w) { // TODO: does DINDW gets used at all? - AMn=DINDW; + AMn = DINDW; AnEXTEN = 1 << 1; // Word index size tok++; } @@ -289,23 +290,24 @@ else if (*tok == '[') { // ([... tok++; - AnEXTEN|=EXT_FULLWORD; //Definitely using full extension format, so set bit 8 + AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8 + // Check to see if base displacement is present - if (*tok!=CONST && *tok !=SYMBOL) + if (*tok != CONST && *tok != SYMBOL) { - AnEXTEN|=EXT_BDSIZE0; + AnEXTEN |= EXT_BDSIZE0; } else { expr(AnBEXPR, &AnBEXVAL, &AnBEXATTR, &AnESYM); - if (CHECK_OPTS(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; } else if (*tok==DOTL) { // ([bd.l,... - AnEXTEN|=EXT_BDSIZEL; + AnEXTEN |= EXT_BDSIZEL; tok++; } else @@ -313,7 +315,7 @@ // Is .W forced here? if (*tok == DOTW) { - AnEXTEN|=EXT_BDSIZEW; + AnEXTEN |= EXT_BDSIZEW; tok++; } else @@ -322,7 +324,7 @@ // to absolute short if (CHECK_OPTS(OPT_ABS_SHORT) && ((AnBEXATTR & (TDB | DEFINED)) == DEFINED) - && ((AnBEXVAL + 0x8000) < 0x10000)) + && (((uint32_t)AnBEXVAL + 0x8000) < 0x10000)) { AnEXTEN |= EXT_BDSIZEW; warn("absolute value in base displacement ranging $FFFF8000..$00007FFF optimised to absolute short"); @@ -350,7 +352,7 @@ } else if ((*tok >= KW_A0) && (*tok <= KW_A7)) { // ([bd,An,... - AnREG = (6<<3)|*tok & 7; + AnREG = (6 << 3) | *tok & 7; tok++; } else if ((*tok >= KW_D0) && (*tok <= KW_D7)) @@ -363,24 +365,22 @@ tok++; // Check for size + // ([bd,An/PC],Xn.W/L...) + switch ((int)*tok) { - // ([bd,An/PC],Xn.W/L...) - switch ((int)*tok) - { - // Index reg size: | .W | .L - case DOTW: - tok++; - break; - default: - break; - case DOTL: - AnEXTEN |= EXT_L; - tok++; - break; - case DOTB: - // .B not allowed here... - goto badmode; - } + // Index reg size: | .W | .L + case DOTW: + tok++; + break; + default: + break; + case DOTL: + AnEXTEN |= EXT_L; + tok++; + break; + case DOTB: + // .B not allowed here... + goto badmode; } // Check for scale @@ -392,6 +392,7 @@ { if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) return error("scale factor expression must evaluate"); + switch (AnEXVAL) { case 1: @@ -569,7 +570,7 @@ tok++; goto AnOK; } - else if (*tok!=',') + else if (*tok != ',') return error("comma expected"); else tok++; // eat the comma @@ -586,6 +587,7 @@ tok++; goto AnOK; } + // ([bd,An/PC],Xn,od) if (*tok == DOTL) { @@ -598,7 +600,7 @@ // optimized to absolute short if (CHECK_OPTS(OPT_ABS_SHORT) && ((AnEXATTR & (TDB | DEFINED)) == DEFINED) - && ((AnEXVAL + 0x8000) < 0x10000)) + && (((uint32_t)AnEXVAL + 0x8000) < 0x10000)) { AnEXTEN |= EXT_IISPOSW; // Word outer displacement AMn = MEMPOST; @@ -614,9 +616,7 @@ // Is .W forced here? if (*tok == DOTW) - { tok++; - } } // Check for final closing parenthesis @@ -628,7 +628,7 @@ else return error("Closing parenthesis missing on addressing mode"); - IS_SUPPRESSEDn: +IS_SUPPRESSEDn: // Check for od if (*tok == ')') // ([bd,An/PC],Xn) @@ -671,18 +671,18 @@ // expr[.W][] AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed AMn = MEMPRE; + if (*tok == DOTW) { //AnEXTEN|=EXT_IISNOIW; // Word outer displacement AMn = MEMPOST; tok++; } - // Defined, absolute values from $FFFF8000..$00007FFF get // optimized to absolute short else if (CHECK_OPTS(OPT_BASE_DISP) && ((AnEXATTR & (TDB | DEFINED)) == DEFINED) - && ((AnEXVAL + 0x8000) < 0x10000)) + && (((uint32_t)AnEXVAL + 0x8000) < 0x10000)) { //AnEXTEN|=EXT_IISNOIW; // Word outer displacement with IS suppressed warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short"); @@ -717,24 +717,22 @@ } // Check for size + // ([bd,An/PC],Xn.W/L...) + switch ((int)*tok) { - // ([bd,An/PC],Xn.W/L...) - switch ((int)*tok) - { - // Index reg size: | .W | .L - case DOTW: - tok++; - break; - default: - break; - case DOTL: - tok++; - AnEXTEN |= EXT_L; - break; - case DOTB: - // .B not allowed here... - goto badmode; - } + // Index reg size: | .W | .L + case DOTW: + tok++; + break; + default: + break; + case DOTL: + tok++; + AnEXTEN |= EXT_L; + break; + case DOTB: + // .B not allowed here... + goto badmode; } // Check for scale @@ -842,7 +840,7 @@ // get optimized to absolute short if (CHECK_OPTS(OPT_BASE_DISP) && ((AnEXATTR & (TDB | DEFINED)) == DEFINED) - && ((AnEXVAL + 0x8000) < 0x10000)) + && (((uint32_t)AnEXVAL + 0x8000) < 0x10000)) { expr_size = EXT_IISPREW; warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short"); @@ -1014,7 +1012,7 @@ CHK_FOR_DISPn: // to absolute short if (CHECK_OPTS(OPT_ABS_SHORT) && ((AnEXATTR & (TDB | DEFINED)) == DEFINED) - && ((AnEXVAL + 0x8000) < 0x10000)) + && (((uint32_t)AnEXVAL + 0x8000) < 0x10000)) { AMn = ABSW; diff --git a/procln.c b/procln.c index 3a4aac8..f5a806b 100644 --- a/procln.c +++ b/procln.c @@ -131,7 +131,7 @@ void Assemble(void) char * equate; // Symbol (or NULL) int labtyp = 0; // Label type (':', DCOLON) int equtyp = 0; // Equ type ('=', DEQUALS) - uint32_t eval; // Expression value + uint64_t eval; // Expression value WORD eattr; // Expression attributes SYM * esym; // External symbol involved in expr. WORD siz = 0; // Size suffix to mnem/diretve/macro @@ -229,7 +229,7 @@ as68label: if (*tok == EOL) goto normal; - // Next token MUST be a symbol + // First token MUST be a symbol (if we get here, tok didn't advance) if (*tok++ != SYMBOL) { error("syntax error; expected symbol"); @@ -465,6 +465,7 @@ When checking to see if it's already been equated, issue a warning. { // Advance token pointer to the constant tok += 3; + tok++; // Skip the hi LONG, so pointing at lo LONG // Anything other than a 0 or a 1 will result in "No Bank" if (*tok == 0) diff --git a/riscasm.c b/riscasm.c index 79f9ae2..6346671 100644 --- a/riscasm.c +++ b/riscasm.c @@ -174,7 +174,7 @@ void BuildRISCIntructionWord(unsigned short opcode, int reg1, int reg2) // int GetRegister(WORD rattr) { - uint32_t eval; // Expression value + uint64_t eval; // Expression value WORD eattr; // Expression attributes SYM * esym; // External symbol involved in expr. TOKEN r_expr[EXPRSIZE]; // Expression token list @@ -217,7 +217,7 @@ int GenerateRISCCode(int state) WORD attrflg; int indexed; // Indexed register flag - uint32_t eval; // Expression value + uint64_t eval; // Expression value WORD eattr; // Expression attributes SYM * esym; // External symbol involved in expr. TOKEN r_expr[EXPRSIZE]; // Expression token list @@ -722,7 +722,8 @@ int GenerateRISCCode(int state) { // CC using a constant number tok++; - val = *tok; + tok++; // Toss hi LONG, as most likely not 64-bit number + val = *tok; // Use lo LONG tok++; CHECK_COMMA; } diff --git a/sect.c b/sect.c index e010ff2..3e12765 100644 --- a/sect.c +++ b/sect.c @@ -308,9 +308,11 @@ int AddFixup(uint16_t attr, uint32_t loc, TOKEN * fexpr) // Count the # of tokens in the expression for(len=0; fexpr[len]!=ENDEXPR; len++) { - // Add one to len for 2X tokens - if (fexpr[len] == CONST || fexpr[len] == SYMBOL) + // Add one to len for 2X tokens, two for 3X tokens + if (fexpr[len] == SYMBOL) len++; + else if (fexpr[len] == CONST) + len += 2; } // Add 1 for ENDEXPR @@ -388,7 +390,7 @@ int AddFixup(uint16_t attr, uint32_t loc, TOKEN * fexpr) int ResolveFixups(int sno) { PTR fup; // Current fixup - uint32_t eval; // Expression value + uint64_t eval; // Expression value SYM * sy; // (Temp) pointer to a symbol uint16_t i; // (Temp) word int reg2; diff --git a/token.c b/token.c index 6246a74..4ceaa57 100644 --- a/token.c +++ b/token.c @@ -568,7 +568,8 @@ DEBUG { printf("ExM: SYMBOL=\"%s\"", d); } // to choke on legitimate code... Need to investigate this further // before changing anything else here! case CONST: - sprintf(numbuf, "$%lx", (long unsigned int)*tk++); + tk++; // Skip the hi LONG... + sprintf(numbuf, "$%lx", (uint64_t)*tk++); d = numbuf; break; case DEQUALS: @@ -949,7 +950,7 @@ int TokenizeLine(void) int state = 0; // State for keyword detector int j = 0; // Var for keyword detector uint8_t c; // Random char - uint32_t v; // Random value + uint64_t v; // Random value uint8_t * nullspot = NULL; // Spot to clobber for SYMBOL termination int stuffnull; // 1:terminate SYMBOL '\0' at *nullspot uint8_t c1; @@ -1337,13 +1338,15 @@ dostring: } else if ((*(ln + 1) & 0xDF) == 'L') { + v &= 0xFFFFFFFF; ln += 2; } } } *tk++ = CONST; - *tk++ = v; + *tk++ = v >> 32; // High LONG of 64-bit value + *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value if (obj_format == ALCYON) { @@ -1448,12 +1451,14 @@ dostring: if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) { + v &= 0xFFFFFFFF; ln += 2; } } *tk++ = CONST; - *tk++ = v; + *tk++ = v >> 32; // High LONG of 64-bit value + *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value continue; case '@': // @ or octal constant if (*ln < '0' || *ln > '7') @@ -1483,12 +1488,14 @@ dostring: if ((*(ln+1) == 'l') || (*(ln+1) == 'L')) { + v &= 0xFFFFFFFF; ln += 2; } } *tk++ = CONST; - *tk++ = v; + *tk++ = v >> 32; // High LONG of 64-bit value + *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value continue; case '^': // ^ or ^^ if (*ln != '^') @@ -1563,6 +1570,7 @@ dostring: v &= 0x000000FF; ln += 2; *tk++ = CONST; + *tk++ = 0; // Hi LONG of 64-bits *tk++ = v; *tk++ = DOTB; } @@ -1571,13 +1579,16 @@ dostring: v &= 0x0000FFFF; ln += 2; *tk++ = CONST; + *tk++ = 0; // Hi LONG of 64-bits *tk++ = v; *tk++ = DOTW; } else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) { + v &= 0xFFFFFFFF; ln += 2; *tk++ = CONST; + *tk++ = 0; // Hi LONG of 64-bits *tk++ = v; *tk++ = DOTL; } @@ -1585,7 +1596,8 @@ dostring: else { *tk++ = CONST; - *tk++ = v; + *tk++ = v >> 32; // High LONG of 64-bit value + *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value } //printf("CONST: %i\n", v); @@ -1685,8 +1697,8 @@ void DumpTokenBuffer(void) printf("[COLON]"); else if (*t == CONST) { - t++; - printf("[CONST: $%X]", (uint32_t)*t); + printf("[CONST: $%lX]", ((uint64_t)t[1] << 32) | (uint64_t)t[2]); + t += 2; } else if (*t == ACONST) { diff --git a/version.h b/version.h index b5e0f1c..225ad9f 100644 --- a/version.h +++ b/version.h @@ -14,8 +14,8 @@ // Release Information #define MAJOR 1 // Major version number -#define MINOR 8 // Minor version number -#define PATCH 7 // Patch release number +#define MINOR 9 // Minor version number +#define PATCH 0 // Patch release number #endif // __VERSION_H__ -- 2.37.2