From: Shamus Hammons Date: Tue, 21 Nov 2017 13:54:55 +0000 (-0600) Subject: Fixes for last commit; version is now 1.10.0. X-Git-Tag: v2.1.0~100 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=commitdiff_plain;h=f3c7d186a15b89c39e360b9cc89545a0d24bd6a4;hp=582df8950c285e1746d0c4a9e3ead6545c962dc8 Fixes for last commit; version is now 1.10.0. The float changes will need some going over to ensure that we don't end up with what we had when pointers were shoved into the token stream willy-nilly. --- diff --git a/6502.c b/6502.c index 4f259f9..711435e 100644 --- a/6502.c +++ b/6502.c @@ -258,27 +258,29 @@ void m6502cg(int op) // zpreq = 0; - switch ((int)*tok) + switch (tok.u32[0]) { case EOL: amode = A65_IMPL; break; case '#': - tok++; + tok.u32++; - if (*tok == '>') + if (*tok.u32 == '>') { - tok++; + tok.u32++; + if (expr(exprbuf, &eval, &eattr, NULL) < 0) return; amode = A65_IMMEDH; break; } - else if (*tok == '<') + else if (*tok.u32 == '<') { - tok++; + tok.u32++; + if (expr(exprbuf, &eval, &eattr, NULL) < 0) return; @@ -293,41 +295,43 @@ void m6502cg(int op) break; case '(': - tok++; + tok.u32++; if (expr(exprbuf, &eval, &eattr, NULL) < 0) return; - if (*tok == ')') + if (*tok.u32 == ')') { // (foo) or (foo),y - if (*++tok == ',') + if (*++tok.u32 == ',') { // (foo),y - tok++; - p = string[tok[1]]; + tok.u32++; + p = string[tok.u32[1]]; - if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'y') // Sleazo tolower() + // Sleazo tolower() ---------------------vvvvvvvvvvv + if (*tok.u32 != SYMBOL || p[1] != EOS || (*p | 0x20) != 'y') goto badmode; - tok += 2; + tok.u32 += 2; amode = A65_INDY; } else amode = A65_IND; } - else if (*tok == ',') + else if (*tok.u32 == ',') { // (foo,x) - tok++; - p = string[tok[1]]; + tok.u32++; + p = string[tok.u32[1]]; - if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'x') // Sleazo tolower() + // Sleazo tolower() ---------------------vvvvvvvvvvv + if (*tok.u32 != SYMBOL || p[1] != EOS || (*p | 0x20) != 'x') goto badmode; - tok += 2; + tok.u32 += 2; - if (*tok++ != ')') + if (*tok.u32++ != ')') goto badmode; amode = A65_INDX; @@ -338,17 +342,17 @@ void m6502cg(int op) break; case '@': - tok++; + tok.u32++; if (expr(exprbuf, &eval, &eattr, NULL) < 0) return; - if (*tok == '(') + if (*tok.u32 == '(') { - tok++; - p = string[tok[1]]; + tok.u32++; + p = string[tok.u32[1]]; - if (*tok != SYMBOL || p[1] != EOS || tok[2] != ')' || tok[3] != EOL) + if (*tok.u32 != SYMBOL || p[1] != EOS || tok.u32[2] != ')' || tok.u32[3] != EOL) goto badmode; i = (*p | 0x20); // Sleazo tolower() @@ -360,10 +364,10 @@ void m6502cg(int op) else goto badmode; - tok += 3; // Past SYMBOL ')' EOL + tok.u32 += 3; // Past SYMBOL ')' EOL zpreq = 1; // Request zeropage optimization } - else if (*tok == EOL) + else if (*tok.u32 == EOL) amode = A65_IND; else goto badmode; @@ -376,7 +380,7 @@ void m6502cg(int op) // x,foo // y,foo // - p = string[tok[1]]; + p = string[tok.u32[1]]; // ggn: the following code is effectively disabled as it would make // single letter labels not work correctly (would not identify the // label properly). And from what I understand it's something to @@ -412,17 +416,17 @@ not_coinop: zpreq = 1; - if (*tok == EOL) + if (*tok.u32 == EOL) amode = A65_ABS; - else if (*tok == ',') + else if (*tok.u32 == ',') { - tok++; - p = string[tok[1]]; + tok.u32++; + p = string[tok.u32[1]]; - if (*tok != SYMBOL || p[1] != EOS) + if (*tok.u32 != SYMBOL || p[1] != EOS) goto badmode; - tok += 2; + tok.u32 += 2; // // Check for X or Y index register; @@ -579,7 +583,7 @@ badmode: if (sloc > 0x10000L) fatal("6502 code pointer > 64K"); - if (*tok != EOL) + if (*tok.u32 != EOL) error(extra_stuff); } diff --git a/amode.c b/amode.c index 73f2bda..2608d79 100644 --- a/amode.c +++ b/amode.c @@ -65,8 +65,8 @@ WORD mulmode; // to distinguish between 32 and 64 bit multiplications (68020+ int bfparam1; // bfxxx / fmove instruction parameter 1 int bfparam2; // bfxxx / fmove instruction parameter 2 -int bfval1; //bfxxx / fmove value 1 -int bfval2; //bfxxx / fmove value 2 +int bfval1; // bfxxx / fmove value 1 +int bfval2; // bfxxx / fmove value 2 TOKEN bf0expr[EXPRSIZE]; // Expression uint64_t bf0exval; // Expression's value WORD bf0exattr; // Expression's attribute @@ -97,7 +97,7 @@ int amode(int acount) bf0esym = NULL; // If at EOL, then no addr modes at all - if (*tok == EOL) + if (*tok.u32 == EOL) return 0; // Parse first addressing mode @@ -106,17 +106,17 @@ int amode(int acount) #define AnREG a0reg #define AnIXREG a0ixreg #define AnIXSIZ a0ixsiz - #define AnEXPR a0expr + #define AnEXPR (TOKENPTR)a0expr #define AnEXVAL a0exval #define AnEXATTR a0exattr - #define AnOEXPR a0oexpr + #define AnOEXPR (TOKENPTR)a0oexpr #define AnOEXVAL a0oexval #define AnOEXATTR a0oexattr #define AnESYM a0esym #define AMn_IX0 am0_ix0 #define AMn_IXN am0_ixn #define CHK_FOR_DISPn CheckForDisp0 - #define AnBEXPR a0bexpr + #define AnBEXPR (TOKENPTR)a0bexpr #define AnBEXVAL a0bexval #define AnBEXATTR a0bexattr #define AnBZISE a0bsize @@ -132,15 +132,15 @@ int amode(int acount) // it's a bitfield instruction--check the parameters inside the {} block // for validity - if (*tok == '{') + if (*tok.u32 == '{') if (check030bf() == ERROR) return ERROR; - if ((acount == 0) || (*tok != ',')) + if ((acount == 0) || (*tok.u32 != ',')) return 1; // Eat the comma - tok++; + tok.u32++; // Parse second addressing mode #define AnOK a1ok @@ -148,17 +148,17 @@ int amode(int acount) #define AnREG a1reg #define AnIXREG a1ixreg #define AnIXSIZ a1ixsiz - #define AnEXPR a1expr + #define AnEXPR (TOKENPTR)a1expr #define AnEXVAL a1exval #define AnEXATTR a1exattr - #define AnOEXPR a1oexpr + #define AnOEXPR (TOKENPTR)a1oexpr #define AnOEXVAL a1oexval #define AnOEXATTR a1oexattr #define AnESYM a1esym #define AMn_IX0 am1_ix0 #define AMn_IXN am1_ixn #define CHK_FOR_DISPn CheckForDisp1 - #define AnBEXPR a1bexpr + #define AnBEXPR (TOKENPTR)a1bexpr #define AnBEXVAL a1bexval #define AnBEXATTR a1bexattr #define AnBZISE a1bsize @@ -170,34 +170,34 @@ int amode(int acount) // It's a bitfield instruction--check the parameters inside the {} block // for validity - if (*tok == '{') + if (*tok.u32 == '{') if (check030bf() == ERROR) return ERROR; // At this point, it is legal for 020+ to have a ':'. For example divu.l // d0,d2:d3 - if (*tok == ':') + if (*tok.u32 == ':') { if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0) return error(unsupport); // TODO: protect this from combinations like Dx:FPx etc :) - tok++; //eat the colon + tok.u32++; //eat the colon - if ((*tok >= KW_D0) && (*tok <= KW_D7)) + if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7)) { - a2reg = (*tok - KW_D0); + a2reg = (*tok.u32 - KW_D0); mulmode = 1 << 10; } - else if ((*tok >= KW_FP0) && (*tok <= KW_FP7)) + else if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7)) { - a2reg = (*tok - KW_FP0); + a2reg = (*tok.u32 - KW_FP0); mulmode = 1 << 10; } else return error("a data or FPU register must follow a :"); - *tok++; + *tok.u32++; } else { @@ -236,17 +236,17 @@ int reglist(WORD * a_rmask) for(;;) { - if ((*tok >= KW_D0) && (*tok <= KW_A7)) - r = *tok++ & 0x0F; + if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_A7)) + r = *tok.u32++ & 0x0F; else break; - if (*tok == '-') + if (*tok.u32 == '-') { - tok++; + tok.u32++; - if ((*tok >= KW_D0) && (*tok <= KW_A7)) - cnt = *tok++ & 0x0F; + if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_A7)) + cnt = *tok.u32++ & 0x0F; else return error("register list syntax"); @@ -261,10 +261,10 @@ int reglist(WORD * a_rmask) while (cnt-- >= 0) rmask |= msktab[r++]; - if (*tok != '/') + if (*tok.u32 != '/') break; - tok++; + tok.u32++; } *a_rmask = rmask; @@ -288,17 +288,17 @@ int fpu_reglist_left(WORD * a_rmask) for(;;) { - if ((*tok >= KW_FP0) && (*tok <= KW_FP7)) - r = *tok++ & 0x07; + if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7)) + r = *tok.u32++ & 0x07; else break; - if (*tok == '-') + if (*tok.u32 == '-') { - tok++; + tok.u32++; - if ((*tok >= KW_FP0) && (*tok <= KW_FP7)) - cnt = *tok++ & 0x07; + if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7)) + cnt = *tok.u32++ & 0x07; else return error("register list syntax"); @@ -315,10 +315,10 @@ int fpu_reglist_left(WORD * a_rmask) while (cnt-- >= 0) rmask |= msktab_minus[r++]; - if (*tok != '/') + if (*tok.u32 != '/') break; - tok++; + tok.u32++; } *a_rmask = rmask; @@ -339,17 +339,17 @@ int fpu_reglist_right(WORD * a_rmask) for(;;) { - if ((*tok >= KW_FP0) && (*tok <= KW_FP7)) - r = *tok++ & 0x07; + if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7)) + r = *tok.u32++ & 0x07; else break; - if (*tok == '-') + if (*tok.u32 == '-') { - tok++; + tok.u32++; - if ((*tok >= KW_FP0) && (*tok <= KW_FP7)) - cnt = *tok++ & 0x07; + if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7)) + cnt = *tok.u32++ & 0x07; else return error("register list syntax"); @@ -364,10 +364,10 @@ int fpu_reglist_right(WORD * a_rmask) while (cnt-- >= 0) rmask |= msktab_plus[r++]; - if (*tok != '/') + if (*tok.u32 != '/') break; - tok++; + tok.u32++; } *a_rmask = rmask; @@ -385,21 +385,23 @@ int fpu_reglist_right(WORD * a_rmask) int check030bf(void) { CHECK00; - tok++; + tok.u32++; - if (*tok == CONST) + if (*tok.u32 == CONST) { - tok++; - bfval1 = (int)*(uint64_t *)tok; + tok.u32++; +// bfval1 = (int)*(uint64_t *)tok.u32; + bfval1 = (int)*tok.u64; // Do=0, offset=immediate - shift it to place bfparam1 = (0 << 11); - tok++; - tok++; +// tok.u32++; +// tok.u32++; + tok.u64++; } - else if (*tok == SYMBOL) + else if (*tok.u32 == SYMBOL) { - if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK) + if (expr((TOKENPTR)bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK) return ERROR; if (!(bf0exattr & DEFINED)) @@ -410,39 +412,42 @@ int check030bf(void) // Do=0, offset=immediate - shift it to place bfparam1 = (0 << 11); } - else if ((*tok >= KW_D0) && (*tok <= KW_D7)) + else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7)) { // Do=1, offset=data register - shift it to place bfparam1 = (1 << 11); - bfval1 = (*(int *)tok - 128); - tok++; + bfval1 = (*(int *)tok.u32 - 128); + tok.u32++; } else return ERROR; - if (*tok==':') - tok++; //eat the ':' + // Eat the ':', if any + if (*tok.u32 == ':') + tok.u32++; - if (*tok == '}' && tok[1] == EOL) + if (*tok.u32 == '}' && tok.u32[1] == EOL) { // It is ok to have }, EOL here - it might be "fmove fpn, {dx}" - tok++; + tok.u32++; return OK; } - if (*tok == CONST) + if (*tok.u32 == CONST) { - tok++; - bfval2 = (int)*(uint64_t *)tok; + tok.u32++; +// bfval2 = (int)*(uint64_t *)tok.u32; + bfval2 = (int)*tok.u64; // Do=0, offset=immediate - shift it to place bfparam2 = (0 << 5); - tok++; - tok++; +// tok.u32++; +// tok.u32++; + tok.u64++; } - else if (*tok == SYMBOL) + else if (*tok.u32 == SYMBOL) { - if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK) + if (expr((TOKENPTR)bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK) return ERROR; bfval2 = (int)bf0exval; @@ -453,17 +458,17 @@ int check030bf(void) // Do=0, offset=immediate - shift it to place bfparam2 = (0 << 5); } - else if ((*tok >= KW_D0) && (*tok <= KW_D7)) + else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7)) { // Do=1, offset=data register - shift it to place - bfval2 = ((*(int *)tok - 128)); + bfval2 = ((*(int *)tok.u32 - 128)); bfparam2 = (1 << 5); - tok++; + tok.u32++; } else return ERROR; - tok++; // Eat the '}' + tok.u32++; // Eat the '}' return OK; } diff --git a/debug.c b/debug.c index 87861b9..eac64fa 100644 --- a/debug.c +++ b/debug.c @@ -106,7 +106,7 @@ int fudump(CHUNK * ch) { uint16_t esiz = *p.wp++; printf("(%d long) ", (int)esiz); - p.tk = printexpr(p.tk); + p.tk.u32 = printexpr(p.tk.u32); } else { diff --git a/direct.c b/direct.c index 7c48035..d535c48 100644 --- a/direct.c +++ b/direct.c @@ -26,7 +26,10 @@ #define DEF_KW #include "kwtab.h" -TOKEN exprbuf[128]; // Expression buffer +// N.B.: It's perfectly fine to keep exprbuf as an array of TOKENS and to cast +// to a TOKENPTR where needed. But this works too. :-P +TOKEN _exprbuf[128]; // Expression buffer +TOKENPTR exprbuf = (TOKENPTR)_exprbuf; // Expression buffer point SYM * symbolPtr[1000000]; // Symbol pointers table static long unused; // For supressing 'write' warnings char buffer[256]; // Scratch buffer for messages @@ -173,14 +176,14 @@ void SetLargestAlignment(int size) // int d_error(char *str) { - if (*tok == EOL) + if (*tok.u32 == EOL) return error("error directive encountered - aborting assembling"); else { - switch(*tok) + switch(*tok.u32) { case STRING: - return error(string[tok[1]]); + return error(string[tok.u32[1]]); break; default: return error("error directive encountered--aborting assembly"); @@ -194,14 +197,14 @@ int d_error(char *str) // int d_warn(char *str) { - if (*tok == EOL) + if (*tok.u32 == EOL) return warn("WARNING WARNING WARNING"); else { - switch(*tok) + switch(*tok.u32) { case STRING: - return warn(string[tok[1]]); + return warn(string[tok.u32[1]]); break; default: return warn("WARNING WARNING WARNING"); @@ -273,27 +276,27 @@ int d_print(void) SYM * esym; // External symbol involved in expr. TOKEN r_expr[EXPRSIZE]; - while (*tok != EOL) + while (*tok.u32 != EOL) { - switch(*tok) + switch(*tok.u32) { case STRING: - sprintf(prntstr, "%s", string[tok[1]]); + sprintf(prntstr, "%s", string[tok.u32[1]]); printf("%s", prntstr); if (list_fd) unused = write(list_fd, prntstr, (LONG)strlen(prntstr)); - tok += 2; + tok.u32 += 2; break; case '/': formatting = 1; - if (tok[1] != SYMBOL) + if (tok.u32[1] != SYMBOL) goto token_err; -// strcpy(prntstr, (char *)tok[2]); - strcpy(prntstr, string[tok[2]]); +// strcpy(prntstr, (char *)tok.u32[2]); + strcpy(prntstr, string[tok.u32[2]]); switch(prntstr[0]) { @@ -307,13 +310,13 @@ int d_print(void) return ERROR; } - tok += 3; + tok.u32 += 3; break; case ',': - tok++; + tok.u32++; break; default: - if (expr(r_expr, &eval, &eattr, &esym) != OK) + if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK) goto token_err; else { @@ -367,13 +370,13 @@ int d_ccundef(void) return ERROR; } - if (*tok != SYMBOL) + if (*tok.u32 != SYMBOL) { error("syntax error; expected symbol"); return ERROR; } - ccname = lookup(string[tok[1]], LABEL, 0); + ccname = lookup(string[tok.u32[1]], LABEL, 0); // Make sure symbol is a valid ccdef if (!ccname || !(ccname->sattre & EQUATEDCC)) @@ -399,18 +402,18 @@ int d_equrundef(void) if (!rgpu && !rdsp) return error(".equrundef/.regundef must be defined in .gpu/.dsp section"); - while (*tok != EOL) + while (*tok.u32 != EOL) { // Skip preceeding or seperating commas (if any) - if (*tok == ',') - tok++; + if (*tok.u32 == ',') + tok.u32++; // Check we are dealing with a symbol - if (*tok != SYMBOL) + if (*tok.u32 != SYMBOL) return error("syntax error; expected symbol"); // Lookup and undef if equated register - regname = lookup(string[tok[1]], LABEL, 0); + regname = lookup(string[tok.u32[1]], LABEL, 0); if (regname && (regname->sattre & EQUATEDREG)) { @@ -421,7 +424,7 @@ int d_equrundef(void) } // Skip over symbol token and address - tok += 2; + tok.u32 += 2; } return 0; @@ -452,11 +455,11 @@ int d_incbin(void) // Check to see if we're in BSS, and, if so, throw an error if (scattr & SBSS) { - error("cannot include binary file \"%s\" in BSS section", string[tok[1]]); + error("cannot include binary file \"%s\" in BSS section", string[tok.u32[1]]); return ERROR; } - if (*tok != STRING) + if (*tok.u32 != STRING) { error("syntax error; string missing"); return ERROR; @@ -465,7 +468,7 @@ int d_incbin(void) // Attempt to open the include file in the current directory, then (if that // failed) try list of include files passed in the enviroment string or by // the "-d" option. - if ((fd = open(string[tok[1]], _OPEN_INC)) < 0) + if ((fd = open(string[tok.u32[1]], _OPEN_INC)) < 0) { for(i=0; nthpath("RMACPATH", i, buf1)!=0; i++) { @@ -475,13 +478,13 @@ int d_incbin(void) if (fd > 0 && buf1[fd - 1] != SLASHCHAR) strcat(buf1, SLASHSTRING); - strcat(buf1, string[tok[1]]); + strcat(buf1, string[tok.u32[1]]); if ((fd = open(buf1, _OPEN_INC)) >= 0) goto allright; } - return error("cannot open: \"%s\"", string[tok[1]]); + return error("cannot open: \"%s\"", string[tok.u32[1]]); } allright: @@ -490,14 +493,14 @@ allright: pos = lseek(fd, 0L, SEEK_SET); chcheck(size); - DEBUG { printf("INCBIN: File '%s' is %li bytes.\n", string[tok[1]], size); } + DEBUG { printf("INCBIN: File '%s' is %li bytes.\n", string[tok.u32[1]], size); } char * fileBuffer = (char *)malloc(size); bytesRead = read(fd, fileBuffer, size); if (bytesRead != size) { - error("was only able to read %li bytes from binary file (%s, %li bytes)", bytesRead, string[tok[1]], size); + error("was only able to read %li bytes from binary file (%s, %li bytes)", bytesRead, string[tok.u32[1]], size); return ERROR; } @@ -715,21 +718,21 @@ int symlist(int(* func)()) for(;;) { - if (*tok != SYMBOL) + if (*tok.u32 != SYMBOL) return error(em); - if ((*func)(string[tok[1]]) != OK) + if ((*func)(string[tok.u32[1]]) != OK) break; - tok += 2; + tok.u32 += 2; - if (*tok == EOL) + if (*tok.u32 == EOL) break; - if (*tok != ',') + if (*tok.u32 != ',') return error(em); - tok++; + tok.u32++; } return 0; @@ -747,11 +750,11 @@ int d_include(void) char buf[128]; char buf1[128]; - if (*tok == STRING) // Leave strings ALONE - fn = string[*++tok]; - else if (*tok == SYMBOL) // Try to append ".s" to symbols + if (*tok.u32 == STRING) // Leave strings ALONE + fn = string[*++tok.u32]; + else if (*tok.u32 == SYMBOL) // Try to append ".s" to symbols { - strcpy(buf, string[*++tok]); + strcpy(buf, string[*++tok.u32]); fext(buf, ".s", 0); fn = &buf[0]; } @@ -760,7 +763,7 @@ int d_include(void) // Make sure the user didn't try anything like: // .include equates.s - if (*++tok != EOL) + if (*++tok.u32 != EOL) return error("extra stuff after filename--enclose it in quotes"); // Attempt to open the include file in the current directory, then (if that @@ -799,7 +802,7 @@ int d_assert(void) WORD eattr; uint64_t eval; - for(; expr(exprbuf, &eval, &eattr, NULL)==OK; ++tok) + for(; expr(exprbuf, &eval, &eattr, NULL)==OK; ++tok.u32) { if (!(eattr & DEFINED)) return error("forward or undefined .assert"); @@ -807,7 +810,7 @@ int d_assert(void) if (!eval) return error("assert failure"); - if (*tok != ',') + if (*tok.u32 != ',') break; } @@ -857,7 +860,7 @@ int d_prgflags(void) { uint64_t eval; - if (*tok == EOL) + if (*tok.u32 == EOL) return error("PRGFLAGS requires value"); else if (abs_expr(&eval) == OK) { @@ -883,7 +886,7 @@ int d_abs(void) SaveSection(); - if (*tok == EOL) + if (*tok.u32 == EOL) eval = 0; else if (abs_expr(&eval) != OK) return 0; @@ -989,7 +992,7 @@ int d_ds(WORD siz) } else { - dep_block(eval, siz, 0, (WORD)(DEFINED | ABS), NULL); + dep_block(eval, siz, 0, (WORD)(DEFINED | ABS), (TOKENPTR){NULL}); } at_eol(); @@ -998,15 +1001,12 @@ int d_ds(WORD siz) // -// dc.b, dc.w / dc, dc.l, dc.i +// dc.b, dc.w / dc, dc.l, dc.i, dc.q, dc.d // int d_dc(WORD siz) { WORD eattr; uint64_t eval; - WORD tdb; - WORD defined; - uint64_t val64; uint8_t * p; if ((scattr & SBSS) != 0) @@ -1023,24 +1023,24 @@ int d_dc(WORD siz) || (rdsp && (orgaddr >= 0xF1B000) && (orgaddr <= 0xF1CFFFF)))) warn("depositing LONGs on a non-long address in local RAM"); - for(;; tok++) + for(;; tok.u32++) { // dc.b 'string' [,] ... - if (siz == SIZB && (*tok == STRING || *tok == STRINGA8) && (tok[2] == ',' || tok[2] == EOL)) + if (siz == SIZB && (*tok.u32 == STRING || *tok.u32 == STRINGA8) && (tok.u32[2] == ',' || tok.u32[2] == EOL)) { - uint32_t i = strlen(string[tok[1]]); + uint32_t i = strlen(string[tok.u32[1]]); if ((challoc - ch_size) < i) chcheck(i); - if (*tok == STRING) + if (*tok.u32 == STRING) { - for(p=string[tok[1]]; *p!=EOS; p++) + for(p=string[tok.u32[1]]; *p!=EOS; p++) D_byte(*p); } - else if(*tok == STRINGA8) + else if(*tok.u32 == STRINGA8) { - for(p=string[tok[1]]; *p!=EOS; p++) + for(p=string[tok.u32[1]]; *p!=EOS; p++) D_byte(strtoa8[*p]); } else @@ -1048,39 +1048,27 @@ int d_dc(WORD siz) error("String format not supported... yet"); } - tok += 2; + tok.u32 += 2; goto comma; } int movei = 0; // MOVEI flag for dc.i - if (*tok == DOTI) + if (*tok.u32 == DOTI) { movei = 1; - tok++; + tok.u32++; siz = SIZL; } - if (siz != SIZQ) - { // dc.x SYM * esym = 0; if (expr(exprbuf, &eval, &eattr, &esym) != OK) return 0; - } - else - { - val64 = *(uint64_t *)(tok); - tok = tok + 2; - D_long((uint32_t)(val64 >> 32)); - D_long((uint32_t)val64); - goto comma; - } - - tdb = (WORD)(eattr & TDB); - defined = (WORD)(eattr & DEFINED); + uint16_t tdb = eattr & TDB; + uint16_t defined = eattr & DEFINED; if ((challoc - ch_size) < 4) chcheck(4); @@ -1153,6 +1141,15 @@ int d_dc(WORD siz) D_long(eval); } break; + case SIZQ: + // 64-bit size + if (m6502) + return error(in_6502mode); + + // Shamus: We only handle DC.Q type stuff, will have to add fixups + // and stuff later (maybe... might not be needed...) + D_quad(eval); + break; case SIZS: if (m6502) return error(in_6502mode); @@ -1171,6 +1168,7 @@ int d_dc(WORD siz) D_single(eval); } + break; case SIZD: if (m6502) @@ -1185,13 +1183,13 @@ int d_dc(WORD siz) } else { - double vv; if (tdb) MarkRelocatable(cursect, sloc, tdb, MDOUBLE, NULL); - vv = *(double *)&eval; + double vv = *(double *)&eval; D_double(vv); } + break; case SIZX: if (m6502) @@ -1206,19 +1204,18 @@ int d_dc(WORD siz) } else { - float vv; if (tdb) MarkRelocatable(cursect, sloc, tdb, MEXTEND, NULL); - vv = *(double *)&eval; + float vv = *(double *)&eval; D_extend(vv); } + break; } - comma: - if (*tok != ',') + if (*tok.u32 != ',') break; } @@ -1243,7 +1240,7 @@ int d_dcb(WORD siz) if (abs_expr(&evalc) != OK) return 0; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); if (expr(exprbuf, &eval, &eattr, NULL) < 0) @@ -1283,14 +1280,14 @@ int d_init(WORD def_siz) for(;;) { // Get repeat count (defaults to 1) - if (*tok == '#') + if (*tok.u32 == '#') { - ++tok; + tok.u32++; if (abs_expr(&count) != OK) return 0; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error(comma_error); } else @@ -1300,25 +1297,25 @@ int d_init(WORD def_siz) if (expr(exprbuf, &eval, &eattr, NULL) < 0) return 0; - switch ((int)*tok++) + switch (*tok.u32++) { // Determine size of object to deposit case DOTB: siz = SIZB; break; case DOTW: siz = SIZB; break; case DOTL: siz = SIZL; break; default: siz = def_siz; - tok--; + tok.u32--; break; } dep_block((uint32_t)count, siz, (uint32_t)eval, eattr, exprbuf); - switch ((int)*tok) + switch (*tok.u32) { case EOL: return 0; case ',': - tok++; + tok.u32++; continue; default: return error(comma_error); @@ -1330,7 +1327,7 @@ int d_init(WORD def_siz) // // Deposit 'count' values of size 'siz' in the current (non-BSS) segment // -int dep_block(uint32_t count, WORD siz, uint32_t eval, WORD eattr, TOKEN * exprbuf) +int dep_block(uint32_t count, WORD siz, uint32_t eval, WORD eattr, TOKENPTR exprbuf) { WORD tdb; WORD defined; @@ -1424,11 +1421,11 @@ int d_comm(void) if (m6502) return error(in_6502mode); - if (*tok != SYMBOL) + if (*tok.u32 != SYMBOL) return error("missing symbol"); - p = string[tok[1]]; - tok += 2; + p = string[tok.u32[1]]; + tok.u32 += 2; if (*p == '.') // Cannot .comm a local symbol return error(locgl_error); @@ -1443,7 +1440,7 @@ int d_comm(void) sym->sattr = GLOBAL | COMMON | BSS; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error(comma_error); if (abs_expr(&eval) != OK) // Parse size of common region @@ -1593,14 +1590,12 @@ int d_gpu(void) return ERROR; } - // If previous section was dsp or 68000 then we need to reset ORG'd Addresses + // If previous section was DSP or 68000 then we need to reset ORG'd Addresses if (!rgpu) { -//printf("Resetting ORG...\n"); orgactive = 0; orgwarning = 0; } -//else printf("NOT resetting ORG!\n"); rgpu = 1; // Set GPU assembly rdsp = 0; // Unset DSP assembly @@ -1657,23 +1652,23 @@ int d_cargs(void) if (rgpu || rdsp) return error("directive forbidden in gpu/dsp mode"); - if (*tok == '#') + if (*tok.u32 == '#') { - tok++; + tok.u32++; if (abs_expr(&eval) != OK) return 0; // Eat the comma, if it's there - if (*tok == ',') - tok++; + if (*tok.u32 == ',') + tok.u32++; } for(;;) { - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { - p = string[tok[1]]; + p = string[tok.u32[1]]; // Set env to either local (dot prefixed) or global scope env = (*p == '.' ? curenv : 0); @@ -1692,23 +1687,23 @@ int d_cargs(void) symbol->sattr |= (ABS | DEFINED | EQUATED); symbol->svalue = (uint32_t)eval; - tok += 2; + tok.u32 += 2; // What this does is eat any dot suffixes attached to a symbol. If // it's a .L, it adds 4 to eval; if it's .W or .B, it adds 2. If // there is no dot suffix, it assumes a size of 2. - switch ((int)*tok) + switch ((int)*tok.u32) { case DOTL: eval += 2; case DOTB: case DOTW: - tok++; + tok.u32++; } eval += 2; } - else if (*tok >= KW_D0 && *tok <= KW_A7) + else if (*tok.u32 >= KW_D0 && *tok.u32 <= KW_A7) { if (reglist(&rlist) < 0) return 0; @@ -1721,7 +1716,7 @@ int d_cargs(void) } else { - switch ((int)*tok) + switch ((int)*tok.u32) { case KW_USP: case KW_SSP: @@ -1731,7 +1726,7 @@ int d_cargs(void) case KW_SR: case KW_CCR: eval += 2; - tok++; + tok.u32++; break; case EOL: return 0; @@ -1741,8 +1736,8 @@ int d_cargs(void) } // Eat commas in between each argument, if they exist - if (*tok == ',') - tok++; + if (*tok.u32 == ',') + tok.u32++; } } @@ -1771,23 +1766,23 @@ int d_cstruct(void) if (rgpu || rdsp) return error("directive forbidden in gpu/dsp mode"); - if (*tok == '#') + if (*tok.u32 == '#') { - tok++; + tok.u32++; if (abs_expr(&eval) != OK) return 0; // Eat the comma, if it's there - if (*tok == ',') - tok++; + if (*tok.u32 == ',') + tok.u32++; } for(;;) { - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { - symbolName = string[tok[1]]; + symbolName = string[tok.u32[1]]; // Set env to either local (dot prefixed) or global scope env = (symbolName[0] == '.' ? curenv : 0); @@ -1806,11 +1801,11 @@ int d_cstruct(void) // Put symbol in "order of definition" list AddToSymbolDeclarationList(symbol); - tok += 2; + tok.u32 += 2; // Adjust label start address if it's a word or a long, as a byte // label might have left us on an odd address. - switch ((int)*tok) + switch ((int)*tok.u32) { case DOTW: case DOTL: @@ -1823,7 +1818,7 @@ int d_cstruct(void) // Check for dot suffixes and adjust space accordingly (longs and // words on an odd boundary get bumped to the next word aligned // address). If no suffix, then throw an error. - switch ((int)*tok) + switch ((int)*tok.u32) { case DOTL: eval += 4; @@ -1838,9 +1833,9 @@ int d_cstruct(void) return error("Symbol missing dot suffix in .cstruct construct"); } - tok++; + tok.u32++; } - else if (*tok >= KW_D0 && *tok <= KW_A7) + else if (*tok.u32 >= KW_D0 && *tok.u32 <= KW_A7) { if (reglist(&rlist) < 0) return 0; @@ -1853,7 +1848,7 @@ int d_cstruct(void) } else { - switch ((int)*tok) + switch ((int)*tok.u32) { case KW_USP: case KW_SSP: @@ -1863,7 +1858,7 @@ int d_cstruct(void) case KW_SR: case KW_CCR: eval += 2; - tok++; + tok.u32++; break; case EOL: return 0; @@ -1873,8 +1868,8 @@ int d_cstruct(void) } // Eat commas in between each argument, if they exist - if (*tok == ',') - tok++; + if (*tok.u32 == ',') + tok.u32++; } } @@ -1926,12 +1921,12 @@ int d_gpumain(void) // int d_opt(void) { - while (*tok != EOL) + while (*tok.u32 != EOL) { - if (*tok == STRING) + if (*tok.u32 == STRING) { - tok++; - char * tmpstr = string[*tok++]; + tok.u32++; + char * tmpstr = string[*tok.u32++]; if (ParseOptimization(tmpstr) != OK) return error("unknown optimization flag '%s'", tmpstr); diff --git a/direct.h b/direct.h index ea1aa23..3c884dc 100644 --- a/direct.h +++ b/direct.h @@ -10,16 +10,17 @@ #define __DIRECT_H__ #include "rmac.h" +#include "token.h" // Exported variables -extern TOKEN exprbuf[]; +extern TOKENPTR exprbuf; extern SYM * symbolPtr[]; extern int (* dirtab[])(); extern int largestAlign[]; // Exported functions void auto_even(void); -int dep_block(uint32_t, WORD, uint32_t, WORD, TOKEN *); +int dep_block(uint32_t, WORD, uint32_t, WORD, TOKENPTR); int eject(void); int abs_expr(uint64_t *); int symlist(int(*)()); diff --git a/eagen.c b/eagen.c index 1f18b85..197bd4e 100644 --- a/eagen.c +++ b/eagen.c @@ -20,12 +20,12 @@ #define amN am0 #define aNexattr a0exattr #define aNexval a0exval -#define aNexpr a0expr +#define aNexpr (TOKENPTR)a0expr #define aNixreg a0ixreg #define aNixsiz a0ixsiz #define AnESYM a0esym #define aNexten a0extension -#define aNbexpr a0bexpr +#define aNbexpr (TOKENPTR)a0bexpr #define aNbdexval a0bexval #define aNbdexattr a0bexattr #include "eagen0.c" @@ -34,12 +34,12 @@ #define amN am1 #define aNexattr a1exattr #define aNexval a1exval -#define aNexpr a1expr +#define aNexpr (TOKENPTR)a1expr #define aNixreg a1ixreg #define aNixsiz a1ixsiz #define AnESYM a1esym #define aNexten a1extension -#define aNbexpr a1bexpr +#define aNbexpr (TOKENPTR)a1bexpr #define aNbdexval a1bexval #define aNbdexattr a1bexattr #include "eagen0.c" diff --git a/error.c b/error.c index 6da93e2..c279117 100644 --- a/error.c +++ b/error.c @@ -19,11 +19,19 @@ static long unused; // For supressing 'write' warnings // // Report error if not at EOL +// N.B.: Since this should *never* happen, we can feel free to add whatever +// diagnostics that will help in tracking down a problem to this function. // int at_eol(void) { - if (*tok != EOL) - error("syntax error. expected EOL, found $%X ('%c')", *tok, *tok); + if (*tok.u32 != EOL) + { + error("syntax error. expected EOL, found $%X ('%c')", *tok.u32, *tok.u32); + printf("Token = "); + DumpToken(*tok.u32); + printf("\n"); + DumpTokenBuffer(); + } return 0; } diff --git a/expr.c b/expr.c index a0f6f9f..3529f29 100644 --- a/expr.c +++ b/expr.c @@ -51,7 +51,7 @@ const char missym_error[] = "missing symbol"; const char str_error[] = "missing symbol or string"; // Convert expression to postfix -static TOKEN * evalTokenBuffer; // Deposit tokens here (this is really a +static TOKENPTR evalTokenBuffer; // Deposit tokens here (this is really a // pointer to exprbuf from direct.c) // (Can also be from others, like // riscasm.c) @@ -105,14 +105,14 @@ int expr0(void) if (expr1() != OK) return ERROR; - while (tokenClass[*tok] >= MULT) + while (tokenClass[*tok.u32] >= MULT) { - t = *tok++; + t = *tok.u32++; if (expr1() != OK) return ERROR; - *evalTokenBuffer++ = t; + *evalTokenBuffer.u32++ = t; } return OK; @@ -121,9 +121,9 @@ int expr0(void) // // Unary operators (detect unary '-') -// ggn: If expression starts with a plus then also eat it up. -// For some reason the parser gets confused when this happens and -// emits a "bad expression". +// ggn: If expression starts with a plus then also eat it up. For some reason +// the parser gets confused when this happens and emits a "bad +// expression". // int expr1(void) { @@ -133,13 +133,12 @@ int expr1(void) char * p, * p2; WORD w; int j; - uint64_t * evalTokenBuffer64; - class = tokenClass[*tok]; + class = tokenClass[*tok.u32]; - if (*tok == '-' || *tok == '+' || class == UNARY) + if (*tok.u32 == '-' || *tok.u32 == '+' || class == UNARY) { - t = *tok++; + t = *tok.u32++; if (expr2() != OK) return ERROR; @@ -147,44 +146,35 @@ int expr1(void) if (t == '-') t = UNMINUS; - // With leading + we don't have to deposit - // anything to the buffer because there's - // no unary '+' nor we have to do anything about it + // With leading + we don't have to deposit anything to the buffer + // because there's no unary '+' nor we have to do anything about it if (t != '+') - *evalTokenBuffer++ = t; + *evalTokenBuffer.u32++ = t; } else if (class == SUNARY) { - switch ((int)*tok++) + switch (*tok.u32++) { case CR_ABSCOUNT: - *evalTokenBuffer++ = CONST; - evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; - *evalTokenBuffer64++ = (LONG)sect[ABS].sloc; - evalTokenBuffer = (uint32_t *)evalTokenBuffer64; + *evalTokenBuffer.u32++ = CONST; + *evalTokenBuffer.u64++ = (uint64_t)sect[ABS].sloc; break; case CR_TIME: - *evalTokenBuffer++ = CONST; - evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; - *evalTokenBuffer64++ = dos_time(); - evalTokenBuffer = (uint32_t *)evalTokenBuffer64; + *evalTokenBuffer.u32++ = CONST; + *evalTokenBuffer.u64++ = dos_time(); break; case CR_DATE: - *evalTokenBuffer++ = CONST; - evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; - *evalTokenBuffer64++ = dos_date(); - evalTokenBuffer = (uint32_t *)evalTokenBuffer64; + *evalTokenBuffer.u32++ = CONST; + *evalTokenBuffer.u64++ = dos_date(); break; - case CR_MACDEF: // ^^macdef - if (*tok++ != SYMBOL) + case CR_MACDEF: // ^^macdef + if (*tok.u32++ != SYMBOL) return error(missym_error); - p = string[*tok++]; + p = string[*tok.u32++]; w = (lookup(p, MACRO, 0) == NULL ? 0 : 1); - evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; - *evalTokenBuffer64++ = (TOKEN)w; - evalTokenBuffer = (uint32_t *)evalTokenBuffer64; - *evalTokenBuffer++ = (TOKEN)w; + *evalTokenBuffer.u32++ = CONST; + *evalTokenBuffer.u64++ = (uint64_t)w; break; case CR_DEFINED: w = DEFINED; @@ -192,38 +182,34 @@ int expr1(void) case CR_REFERENCED: w = REFERENCED; getsym: - if (*tok++ != SYMBOL) + if (*tok.u32++ != SYMBOL) return error(missym_error); - p = string[*tok++]; + p = string[*tok.u32++]; j = (*p == '.' ? curenv : 0); w = ((sy = lookup(p, LABEL, j)) != NULL && (sy->sattr & w) ? 1 : 0); - *evalTokenBuffer++ = CONST; - uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; - *evalTokenBuffer64++ = (TOKEN)w; - evalTokenBuffer = (uint32_t *)evalTokenBuffer64; + *evalTokenBuffer.u32++ = CONST; + *evalTokenBuffer.u64++ = (uint64_t)w; break; case CR_STREQ: - if (*tok != SYMBOL && *tok != STRING) + if (*tok.u32 != SYMBOL && *tok.u32 != STRING) return error(str_error); - p = string[tok[1]]; - tok +=2; + p = string[tok.u32[1]]; + tok.u32 +=2; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error(comma_error); - if (*tok != SYMBOL && *tok != STRING) + if (*tok.u32 != SYMBOL && *tok.u32 != STRING) return error(str_error); - p2 = string[tok[1]]; - tok += 2; + p2 = string[tok.u32[1]]; + tok.u32 += 2; w = (WORD)(!strcmp(p, p2)); - *evalTokenBuffer++ = CONST; - evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; - *evalTokenBuffer64++ = (TOKEN)w; - evalTokenBuffer = (uint32_t *)evalTokenBuffer64; + *evalTokenBuffer.u32++ = CONST; + *evalTokenBuffer.u64++ = (uint64_t)w; break; } } @@ -242,29 +228,19 @@ int expr2(void) char * p; SYM * sy; int j; - uint64_t * evalTokenBuffer64; - uint64_t * tok64; - switch ((int)*tok++) + switch (*tok.u32++) { case CONST: - *evalTokenBuffer++ = CONST; - evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; - tok64 = (uint64_t *)tok; - *evalTokenBuffer64++ = *tok64++; - tok = (TOKEN *)tok64; - evalTokenBuffer = (TOKEN *)evalTokenBuffer64; + *evalTokenBuffer.u32++ = CONST; + *evalTokenBuffer.u64++ = *tok.u64++; break; case FCONST: - *evalTokenBuffer++ = FCONST; - evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; - tok64 = (uint64_t *)tok; - *evalTokenBuffer64++ = *tok64++; - tok = (TOKEN *)tok64; - evalTokenBuffer = (TOKEN *)evalTokenBuffer64; + *evalTokenBuffer.u32++ = FCONST; + *evalTokenBuffer.u64++ = *tok.u64++; break; case SYMBOL: - p = string[*tok++]; + p = string[*tok.u32++]; j = (*p == '.' ? curenv : 0); sy = lookup(p, LABEL, j); @@ -281,22 +257,20 @@ int expr2(void) warn("equated symbol \'%s\' cannot be used in register bank 1", sy->sname); } - *evalTokenBuffer++ = SYMBOL; - *evalTokenBuffer++ = symbolNum; + *evalTokenBuffer.u32++ = SYMBOL; + *evalTokenBuffer.u32++ = symbolNum; symbolPtr[symbolNum] = sy; symbolNum++; break; case STRING: - *evalTokenBuffer++ = CONST; - uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; - *evalTokenBuffer64++ = str_value(string[*tok++]); - evalTokenBuffer = (uint32_t *)evalTokenBuffer64; + *evalTokenBuffer.u32++ = CONST; + *evalTokenBuffer.u64++ = str_value(string[*tok.u32++]); break; case '(': if (expr0() != OK) return ERROR; - if (*tok++ != ')') + if (*tok.u32++ != ')') return error("missing closing parenthesis ')'"); break; @@ -304,34 +278,34 @@ int expr2(void) if (expr0() != OK) return ERROR; - if (*tok++ != ']') + if (*tok.u32++ != ']') return error("missing closing bracket ']'"); break; case '$': - *evalTokenBuffer++ = ACONST; // Attributed const - *evalTokenBuffer++ = sloc; // Current location - *evalTokenBuffer++ = cursect | DEFINED; // Store attribs + *evalTokenBuffer.u32++ = ACONST; // Attributed const + *evalTokenBuffer.u32++ = sloc; // Current location + *evalTokenBuffer.u32++ = cursect | DEFINED; // Store attribs break; case '*': - *evalTokenBuffer++ = ACONST; // Attributed const + *evalTokenBuffer.u32++ = ACONST; // Attributed const // pcloc == location at start of line - *evalTokenBuffer++ = (orgactive ? orgaddr : pcloc); + *evalTokenBuffer.u32++ = (orgactive ? orgaddr : pcloc); // '*' takes attributes of current section, not ABS! - *evalTokenBuffer++ = cursect | DEFINED; + *evalTokenBuffer.u32++ = cursect | DEFINED; break; case '{': if (expr0() != OK) // Eat up first parameter (register or immediate) return ERROR; - if (*tok++ != ':') // Demand a ':' there + if (*tok.u32++ != ':') // Demand a ':' there return error("missing colon ':'"); if (expr0() != OK) // Eat up second parameter (register or immediate) return ERROR; - if (*tok++ != '}') + if (*tok.u32++ != '}') return error("missing closing brace '}'"); break; @@ -346,7 +320,7 @@ int expr2(void) // // Recursive-descent expression analyzer (with some simple speed hacks) // -int expr(TOKEN * otk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym) +int expr(TOKENPTR 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 @@ -360,76 +334,81 @@ int expr(TOKEN * otk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym) // 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]]); +//printf("expr(): tokens 0-2: %i %i %i (%c %c %c); tc[2] = %i\n", tok.u32[0], tok.u32[1], tok.u32[2], tok.u32[0], tok.u32[1], tok.u32[2], tokenClass[tok.u32[2]]); // Optimize for single constant or single symbol. // Shamus: Subtle bug here. EOL token is 101; if you have a constant token // followed by the value 101, it will trigger a bad evaluation here. // This is probably a really bad assumption to be making here...! - // (assuming tok[1] == EOL is a single token that is) + // (assuming tok.u32[1] == EOL is a single token that is) // Seems that even other tokens (SUNARY type) can fuck this up too. -// if ((tok[1] == EOL) - if ((tok[1] == EOL && ((tok[0] != CONST || tok[0] != FCONST) && tokenClass[tok[0]] != SUNARY)) -// || (((*tok == CONST || *tok == FCONST || *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 || tok[0] == FCONST) && (tokenClass[tok[3]] < UNARY)) +#if 0 +// if ((tok.u32[1] == EOL) + if ((tok.u32[1] == EOL && ((tok.u32[0] != CONST || tok.u32[0] != FCONST) && tokenClass[tok.u32[0]] != SUNARY)) +// || (((*tok.u32 == CONST || *tok.u32 == FCONST || *tok.u32 == SYMBOL) || (*tok.u32 >= KW_R0 && *tok.u32 <= KW_R31)) +// && (tokenClass[tok.u32[2]] < UNARY))) + || (((tok.u32[0] == SYMBOL) || (tok.u32[0] >= KW_R0 && tok.u32[0] <= KW_R31)) + && (tokenClass[tok.u32[2]] < UNARY)) + || ((tok.u32[0] == CONST || tok.u32[0] == FCONST) && (tokenClass[tok.u32[3]] < UNARY)) + ) +#else +// Shamus: Seems to me that this could be greatly simplified by 1st checking if the first token is a multibyte token, *then* checking if there's an EOL after it depending on the actual length of the token (multiple vs. single). Otherwise, we have the horror show that is the following: + if ((tok.u32[1] == EOL + && (tok.u32[0] != CONST && tokenClass[tok.u32[0]] != SUNARY)) + || (((tok.u32[0] == SYMBOL) + || (tok.u32[0] >= KW_R0 && tok.u32[0] <= KW_R31)) + && (tokenClass[tok.u32[2]] < UNARY)) + || ((tok.u32[0] == CONST) && (tokenClass[tok.u32[3]] < UNARY)) ) +// Shamus: Yes, you can parse that out and make some kind of sense of it, but damn, it takes a while to get it and understand the subtle bugs that result from not being careful about what you're checking; especially vis-a-vis niavely checking tok.u32[1] for an EOL. O_o +#endif { - if (*tok >= KW_R0 && *tok <= KW_R31) + if (*tok.u32 >= KW_R0 && *tok.u32 <= KW_R31) { - *evalTokenBuffer++ = CONST; - uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; - *evalTokenBuffer64++ = *a_value = (*tok - KW_R0); - evalTokenBuffer = (uint32_t *)evalTokenBuffer64; + *evalTokenBuffer.u32++ = CONST; + *evalTokenBuffer.u64++ = *a_value = (*tok.u32 - KW_R0); *a_attr = ABS | DEFINED; if (a_esym != NULL) *a_esym = NULL; - tok++; + tok.u32++; } - else if (*tok == CONST) + else if (*tok.u32 == CONST) { - *evalTokenBuffer++ = CONST; - uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; - uint64_t *tok64 = (uint64_t *)&tok[1]; - *evalTokenBuffer64++ = *tok64++; - evalTokenBuffer = (TOKEN *)evalTokenBuffer64; - *a_value = tok[1]; + *evalTokenBuffer.u32++ = *tok.u32++; + *evalTokenBuffer.u64++ = *a_value = *tok.u64++; *a_attr = ABS | DEFINED; if (a_esym != NULL) *a_esym = NULL; - tok += 3; -//printf("Quick eval in expr(): CONST = %i, tokenClass[tok[2]] = %i\n", *a_value, tokenClass[*tok]); +//printf("Quick eval in expr(): CONST = %i, tokenClass[tok.u32[2]] = %i\n", *a_value, tokenClass[*tok.u32]); } - else if (*tok == FCONST) +// Not sure that removing float constant here is going to break anything and/or +// make things significantly slower, but having this here seems to cause the +// complexity of the check to get to this part of the parse to go through the +// roof, and dammit, I just don't feel like fighting that fight ATM. :-P +#if 0 + else if (*tok.u32 == FCONST) { - *evalTokenBuffer++ = FCONST; - *((double *)evalTokenBuffer) = *((double *)&tok[1]); - evalTokenBuffer += 2; - //*(double *)evalTokenBuffer++ = tok[2]; - *a_value = *((uint64_t *)&tok[1]); + *evalTokenBuffer.u32++ = *tok.u32++; + *evalTokenBuffer.u64++ = *a_value = *tok.u64++; *a_attr = ABS | DEFINED | FLOAT; if (a_esym != NULL) *a_esym = NULL; - tok += 3; -//printf("Quick eval in expr(): CONST = %i, tokenClass[tok[2]] = %i\n", *a_value, tokenClass[*tok]); +//printf("Quick eval in expr(): CONST = %i, tokenClass[tok.u32[2]] = %i\n", *a_value, tokenClass[*tok.u32]); } - else if (*tok == '*') +#endif + else if (*tok.u32 == '*') { - *evalTokenBuffer++ = CONST; - uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer; + *evalTokenBuffer.u32++ = CONST; if (orgactive) - *evalTokenBuffer64++ = *a_value = orgaddr; + *evalTokenBuffer.u64++ = *a_value = orgaddr; else - *evalTokenBuffer64++ = *a_value = pcloc; - evalTokenBuffer = (uint32_t *)evalTokenBuffer64; + *evalTokenBuffer.u64++ = *a_value = pcloc; // '*' takes attributes of current section, not ABS! *a_attr = cursect | DEFINED; @@ -437,11 +416,11 @@ int expr(TOKEN * otk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym) if (a_esym != NULL) *a_esym = NULL; - tok++; + tok.u32++; } - else if (*tok == STRING || *tok == SYMBOL) + else if (*tok.u32 == STRING || *tok.u32 == SYMBOL) { - p = string[tok[1]]; + p = string[tok.u32[1]]; j = (*p == '.' ? curenv : 0); symbol = lookup(p, LABEL, j); #if 0 @@ -476,7 +455,7 @@ if (symbol) warn("equated symbol '%s' cannot be used in register bank 1", symbol->sname); } - *evalTokenBuffer++ = SYMBOL; + *evalTokenBuffer.u32++ = SYMBOL; #if 0 *evalTokenBuffer++ = (TOKEN)symbol; #else @@ -485,7 +464,7 @@ While this approach works, it's wasteful. It would be better to use something that's already available, like the symbol "order defined" table (which needs to be converted from a linked list into an array). */ - *evalTokenBuffer++ = symbolNum; + *evalTokenBuffer.u32++ = symbolNum; symbolPtr[symbolNum] = symbol; symbolNum++; #endif @@ -508,25 +487,25 @@ thrown away right here. What the hell is it for? && a_esym != NULL) *a_esym = symbol; - tok += 2; + tok.u32 += 2; } else { // Unknown type here... Alert the user!, error("undefined RISC register in expression"); // Prevent spurious error reporting... - tok++; + tok.u32++; return ERROR; } - *evalTokenBuffer++ = ENDEXPR; + *evalTokenBuffer.u32++ = ENDEXPR; return OK; } if (expr0() != OK) return ERROR; - *evalTokenBuffer++ = ENDEXPR; + *evalTokenBuffer.u32++ = ENDEXPR; return evexpr(otk, a_value, a_attr, a_esym); } @@ -535,9 +514,9 @@ thrown away right here. What the hell is it for? // Evaluate expression. // If the expression involves only ONE external symbol, the expression is // UNDEFINED, but it's value includes everything but the symbol value, and -// `a_esym' is set to the external symbol. +// 'a_esym' is set to the external symbol. // -int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym) +int evexpr(TOKENPTR tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym) { WORD attr, attr2; SYM * sy; @@ -545,15 +524,14 @@ int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym) WORD * sattr = evattr; SYM * esym = NULL; // No external symbol involved WORD sym_seg = 0; - uint64_t *tk64; - while (*tk != ENDEXPR) + while (*tk.u32 != ENDEXPR) { - switch ((int)*tk++) + switch ((int)*tk.u32++) { case SYMBOL: //printf("evexpr(): SYMBOL\n"); - sy = symbolPtr[*tk++]; + sy = symbolPtr[*tk.u32++]; sy->sattr |= REFERENCED; // Set "referenced" bit if (!(sy->sattr & DEFINED)) @@ -585,22 +563,20 @@ int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym) sym_seg = (WORD)(sy->sattr & TDB); break; case CONST: - tk64 = (uint64_t *)tk; - *++sval = *tk64++; - tk = (TOKEN *)tk64; + *++sval = *tk.u64++; //printf("evexpr(): CONST = %lX\n", *sval); *++sattr = ABS | DEFINED; // Push simple attribs break; case FCONST: -//printf("evexpr(): CONST = %i\n", *tk); - *((double *)sval) = *((double *)tk); - tk += 2; +//printf("evexpr(): FCONST = %i\n", *tk.u32); + *((double *)sval) = *((double *)tk.u32); + tk.u32 += 2; *++sattr = ABS | DEFINED | FLOAT; // Push simple attribs break; case ACONST: -//printf("evexpr(): ACONST = %i\n", *tk); - *++sval = *tk++; // Push value - *++sattr = (WORD)*tk++; // Push attribs +//printf("evexpr(): ACONST = %i\n", *tk.u32); + *++sval = *tk.u32++; // Push value + *++sattr = (WORD)*tk.u32++; // Push attribs break; // Binary "+" and "-" matrix: @@ -647,7 +623,7 @@ int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym) } else { - *sval += sval[1]; // Compute value + *sval += sval[1]; // Compute value } //printf("%i\n", *sval); @@ -690,7 +666,7 @@ int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym) } else { - *sval -= sval[1]; // Compute value + *sval -= sval[1]; // Compute value } //printf("%i\n", *sval); @@ -722,8 +698,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); } else { - *sval = -(int)*sval; - *sattr = ABS | DEFINED; // Expr becomes absolute + *sval = -(int)*sval; + *sattr = ABS | DEFINED; // Expr becomes absolute } break; case '!': @@ -785,7 +761,7 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); } else { - *sval = *sval <= sval[1]; + *sval = *sval <= sval[1]; } *sattr = ABS | DEFINED; @@ -825,11 +801,10 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); } else if (attr == 0) { - *sval = *sval >= sval[1]; + *sval = *sval >= sval[1]; } else - - *sattr = ABS | DEFINED; + *sattr = ABS | DEFINED; break; case '>': @@ -866,8 +841,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); *sval = *dst > *src; } else -= { - *sval = *sval > sval[1]; + { + *sval = *sval > sval[1]; } *sattr = ABS | DEFINED; @@ -883,7 +858,7 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); // Extract float attributes from both terms and pack them // into a single value - attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) > >1); + attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1); if (attr == (FLOAT | (FLOAT >> 1))) { @@ -908,7 +883,7 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); } else { - *sval = *sval < sval[1]; + *sval = *sval < sval[1]; } *sattr = ABS | DEFINED; @@ -943,7 +918,7 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); } else { - *sval = *sval != sval[1]; + *sval = *sval != sval[1]; } *sattr = ABS | DEFINED; @@ -982,21 +957,21 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); } else { - *sval = *sval == sval[1]; + *sval = *sval == sval[1]; } *sattr = ABS | DEFINED; break; - // All other binary operators must have two ABS items - // to work with. They all produce an ABS value. + // All other binary operators must have two ABS items to work with. + // They all produce an ABS value. default: //printf("evexpr(): default\n"); // GH - Removed for v1.0.15 as part of the fix for indexed loads. //if ((*sattr & (TEXT|DATA|BSS)) || (*--sattr & (TEXT|DATA|BSS))) //error(seg_error); - switch ((int)tk[-1]) + switch ((int)tk.u32[-1]) { case '*': sval--; @@ -1030,7 +1005,7 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); } else { - *sval *= sval[1]; + *sval *= sval[1]; } //printf("%i\n", *sval); @@ -1054,8 +1029,10 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); // Float / Float double * dst = (double *)sval; double * src = (double *)(sval + 1); + if (*src == 0) return error("divide by zero"); + *dst = *dst / *src; } else if (attr == FLOAT) @@ -1063,8 +1040,10 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); // Float / Int double * dst = (double *)sval; uint64_t * src = (uint64_t *)(sval + 1); + if (*src == 0) return error("divide by zero"); + *dst = *dst / *src; } else if (attr == FLOAT >> 1) @@ -1072,8 +1051,10 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); // Int / Float uint64_t * dst=(uint64_t *)sval; double * src=(double *)(sval + 1); + if (*src == 0) return error("divide by zero"); + *(double *)dst = *dst / *src; } else @@ -1081,11 +1062,13 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); if (sval[1] == 0) return error("divide by zero"); //printf("--> N/N: %i / %i = ", sval[0], sval[1]); - // Compiler is picky here: Without casting these, it discards - // the sign if dividing a negative # by a positive one, - // creating a bad result. :-/ - // Definitely a side effect of using uint32_ts intead of ints. - *sval = (int32_t)sval[0] / (int32_t)sval[1]; + + // Compiler is picky here: Without casting these, it + // discards the sign if dividing a negative # by a + // positive one, creating a bad result. :-/ + // Definitely a side effect of using uint32_ts intead of + // ints. + *sval = (int32_t)sval[0] / (int32_t)sval[1]; } *sattr = ABS | DEFINED; // Expr becomes absolute @@ -1096,6 +1079,7 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); case '%': sval--; sattr--; // Pop attrib + if ((*sattr | sattr[1]) & FLOAT) return error("floating point numbers not allowed with operator '%'."); @@ -1108,40 +1092,50 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); case SHL: sval--; sattr--; // Pop attrib + if ((*sattr | sattr[1]) & FLOAT) return error("floating point numbers not allowed with operator '<<'."); + *sattr = ABS | DEFINED; // Expr becomes absolute *sval <<= sval[1]; break; case SHR: sval--; sattr--; // Pop attrib + if ((*sattr | sattr[1]) & FLOAT) return error("floating point numbers not allowed with operator '>>'."); + *sattr = ABS | DEFINED; // Expr becomes absolute *sval >>= sval[1]; break; case '&': sval--; sattr--; // Pop attrib + if ((*sattr | sattr[1]) & FLOAT) return error("floating point numbers not allowed with operator '&'."); + *sattr = ABS | DEFINED; // Expr becomes absolute *sval &= sval[1]; break; case '^': sval--; sattr--; // Pop attrib + if ((*sattr | sattr[1]) & FLOAT) return error("floating point numbers not allowed with operator '^'."); + *sattr = ABS | DEFINED; // Expr becomes absolute *sval ^= sval[1]; break; case '|': sval--; sattr--; // Pop attrib + if ((*sattr | sattr[1]) & FLOAT) return error("floating point numbers not allowed with operator '|'."); + *sattr = ABS | DEFINED; // Expr becomes absolute *sval |= sval[1]; break; diff --git a/expr.h b/expr.h index f03ca1e..6ebbe67 100644 --- a/expr.h +++ b/expr.h @@ -34,7 +34,7 @@ void InitExpression(void); int expr1(void); int expr2(void); -int expr(TOKEN *, uint64_t *, WORD *, SYM **); -int evexpr(TOKEN *, uint64_t *, WORD *, SYM **); +int expr(TOKENPTR, uint64_t *, WORD *, SYM **); +int evexpr(TOKENPTR, uint64_t *, WORD *, SYM **); #endif // __EXPR_H__ diff --git a/listing.c b/listing.c index 77226c7..e1fd73a 100644 --- a/listing.c +++ b/listing.c @@ -432,19 +432,19 @@ int d_subttl(void) int ejectok; ejectok = 1; - if (*tok == '-') + if (*tok.u32 == '-') { ejectok = 0; - ++tok; + ++tok.u32; } - if (*tok != STRING) + if (*tok.u32 != STRING) return error("missing string"); -// strcpy(subttl, (char *)tok[1]); - strcpy(subttl, string[tok[1]]); +// strcpy(subttl, (char *)tok.u32[1]); + strcpy(subttl, string[tok.u32[1]]); - tok += 2; + tok.u32 += 2; // Always eject on pages 2+ if (ejectok && (subflag || pageno > 1)) @@ -462,12 +462,12 @@ int d_subttl(void) // int d_title(void) { - if (*tok != STRING) + if (*tok.u32 != STRING) return error("missing string"); -// strcpy(title, (char*)tok[1]); - strcpy(title, string[tok[1]]); - tok += 2; +// strcpy(title, (char*)tok.u32[1]); + strcpy(title, string[tok.u32[1]]); + tok.u32 += 2; if (pageno > 1) { diff --git a/mach.c b/mach.c index 4e106da..78a7963 100644 --- a/mach.c +++ b/mach.c @@ -660,7 +660,7 @@ int m_shi(WORD inst, WORD siz) } else { - AddFixup(FU_QUICK, sloc, a0expr); + AddFixup(FU_QUICK, sloc, (TOKENPTR)a0expr); D_word(inst); } @@ -723,7 +723,7 @@ int m_dbra(WORD inst, WORD siz) } else { - AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr); + AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, (TOKENPTR)a1expr); D_word(0); } @@ -741,14 +741,14 @@ int m_exg(WORD inst, WORD siz) siz = siz; if (am0 == DREG && am1 == DREG) - m = 0x0040; // Dn,Dn + m = 0x0040; // Dn,Dn else if (am0 == AREG && am1 == AREG) - m = 0x0048; // An,An + m = 0x0048; // An,An else { if (am0 == AREG) - { // Dn,An or An,Dn - m = a1reg; // Get AREG into a1reg + { // Dn,An or An,Dn + m = a1reg; // Get AREG into a1reg a1reg = a0reg; a0reg = m; } @@ -870,9 +870,9 @@ int m_move(WORD inst, WORD size) int m_move30(WORD inst, WORD size) { int siz = (int)size; - // TODO: is extra_addressing necessary/correct? + // TODO: is extra_addressing necessary/correct? //inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE]; - inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg; + inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg; D_word(inst); @@ -914,7 +914,7 @@ int m_moveq(WORD inst, WORD siz) // Arrange for future fixup if (!(a0exattr & DEFINED)) { - AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr); + AddFixup(FU_BYTE | FU_SEXT, sloc + 1, (TOKENPTR)a0expr); a0exval = 0; } else if ((uint32_t)a0exval + 0x100 >= 0x200) @@ -933,7 +933,7 @@ int m_moveq(WORD inst, WORD siz) int m_movep(WORD inst, WORD siz) { // Tell ea0gen to lay off the 0(a0) optimisations on this one - movep = 1; + movep = 1; if (siz == SIZL) inst |= 0x0040; @@ -959,7 +959,7 @@ int m_movep(WORD inst, WORD siz) ea0gen(siz); } - movep = 0; + movep = 0; return 0; } @@ -1030,7 +1030,7 @@ int m_br(WORD inst, WORD siz) if (siz == SIZB || siz == SIZS) { // .B - AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr); + AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, (TOKENPTR)a0expr); D_word(inst); return OK; } @@ -1038,7 +1038,7 @@ int m_br(WORD inst, WORD siz) { // .W D_word(inst); - AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr); + AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, (TOKENPTR)a0expr); D_word(0); } @@ -1063,7 +1063,7 @@ int m_addq(WORD inst, WORD siz) } else { - AddFixup(FU_QUICK, sloc, a0expr); + AddFixup(FU_QUICK, sloc, (TOKENPTR)a0expr); D_word(inst); } @@ -1114,10 +1114,10 @@ int m_movem(WORD inst, WORD siz) if (siz == SIZL) inst |= 0x0040; - if (*tok == '#') + if (*tok.u32 == '#') { // Handle #, ea - tok++; + tok.u32++; if (abs_expr(&eval) != OK) return OK; @@ -1129,14 +1129,14 @@ int m_movem(WORD inst, WORD siz) goto immed1; } - if ((*tok >= KW_D0) && (*tok <= KW_A7)) + if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_A7)) { // , ea if (reglist(&rmask) < 0) return OK; immed1: - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); if (amode(0) < 0) @@ -1165,16 +1165,16 @@ immed1: inst |= 0x0400 | am0 | a0reg; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); - if (*tok == EOL) + if (*tok.u32 == EOL) return error("missing register list"); - if (*tok == '#') + if (*tok.u32 == '#') { // ea, # - tok++; + tok.u32++; if (abs_expr(&eval) != OK) return OK; @@ -1236,7 +1236,7 @@ int m_br30(WORD inst, WORD siz) else { // .L - AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr); + AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, (TOKENPTR)a0expr); D_word(inst); return OK; } @@ -1249,39 +1249,35 @@ int m_br30(WORD inst, WORD siz) // int m_bfop(WORD inst, WORD siz) { - if ((bfval1 > 31) || (bfval1 < 0)) - return error("bfxxx offset: immediate value must be between 0 and 31"); + if ((bfval1 > 31) || (bfval1 < 0)) + return error("bfxxx offset: immediate value must be between 0 and 31"); // First instruction word - just the opcode and first EA - // Note: both am1 is ORed because solely of bfins - maybe it's a good idea to make a dedicated function for it? + // Note: both am1 is ORed because solely of bfins - maybe it's a good idea + // to make a dedicated function for it? if (am1 == AM_NONE) - { + { am1 = 0; - } - else - { - if (bfval2 > 31 || bfval2 < 0) - return error("bfxxx width: immediate value must be between 0 and 31"); - - // For Dw both immediate and register number are stuffed - // into the same field O_o - bfparam2 = (bfval2 << 0); - } - - if (bfparam1 == 0) - { - bfparam1 = (bfval1 << 6); - } - else - { - bfparam1 = bfval1 << 12; - } + } + else + { + if (bfval2 > 31 || bfval2 < 0) + return error("bfxxx width: immediate value must be between 0 and 31"); + + // For Dw both immediate and register number are stuffed + // into the same field O_o + bfparam2 = (bfval2 << 0); + } + + if (bfparam1 == 0) + bfparam1 = (bfval1 << 6); + else + bfparam1 = bfval1 << 12; D_word((inst | am0 | a0reg | am1 | a1reg)); ea0gen(siz); // Generate EA // Second instruction word - Dest register (if exists), Do, Offset, Dw, Width - inst = bfparam1 | bfparam2; if (am1 == DREG) @@ -1345,7 +1341,7 @@ int m_callm(WORD inst, WORD siz) else return error(undef_error); - ea1gen(siz); + ea1gen(siz); return OK; @@ -1382,21 +1378,21 @@ int m_cas(WORD inst, WORD siz) } // Dc - if ((*tok < KW_D0) && (*tok > KW_D7)) + if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7)) return error("CAS accepts only data registers"); - inst2 = (*tok++) & 7; + inst2 = (*tok.u32++) & 7; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); // Du - if ((*tok < KW_D0) && (*tok > KW_D7)) + if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7)) return error("CAS accepts only data registers"); - inst2 |= ((*tok++) & 7) << 6; + inst2 |= ((*tok.u32++) & 7) << 6; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); // ea @@ -1406,7 +1402,7 @@ int m_cas(WORD inst, WORD siz) if (modes > 1) return error("too many ea fields"); - if (*tok!=EOL) + if (*tok.u32 != EOL) return error("extra (unexpected) text found"); // Reject invalud ea modes @@ -1452,71 +1448,71 @@ int m_cas2(WORD inst, WORD siz) } // Dc1 - if ((*tok < KW_D0) && (*tok > KW_D7)) + if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7)) return error("CAS2 accepts only data registers for Dx1:Dx2 pairs"); - inst2 = (*tok++) & 7; + inst2 = (*tok.u32++) & 7; - if (*tok++ != ':') + if (*tok.u32++ != ':') return error("missing colon"); // Dc2 - if ((*tok < KW_D0) && (*tok > KW_D7)) + if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7)) return error("CAS2 accepts only data registers for Dx1:Dx2 pairs"); - inst3 = (*tok++) & 7; + inst3 = (*tok.u32++) & 7; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); // Du1 - if ((*tok < KW_D0) && (*tok > KW_D7)) + if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7)) return error("CAS2 accepts only data registers for Dx1:Dx2 pairs"); - inst2 |= ((*tok++) & 7) << 6; + inst2 |= ((*tok.u32++) & 7) << 6; - if (*tok++ != ':') + if (*tok.u32++ != ':') return error("missing colon"); // Du2 - if ((*tok < KW_D0) && (*tok > KW_D7)) + if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7)) return error("CAS2 accepts only data registers for Dx1:Dx2 pairs"); - inst3 |= ((*tok++) & 7) << 6; + inst3 |= ((*tok.u32++) & 7) << 6; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); // Rn1 - if (*tok++ != '(') + if (*tok.u32++ != '(') return error("missing ("); - if ((*tok >= KW_D0) && (*tok <= KW_D7)) - inst2 |= (((*tok++) & 7) << 12) | (0 << 15); - else if ((*tok >= KW_A0) && (*tok <= KW_A7)) - inst2 |= (((*tok++) & 7) << 12) | (1 << 15); + if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7)) + inst2 |= (((*tok.u32++) & 7) << 12) | (0 << 15); + else if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7)) + inst2 |= (((*tok.u32++) & 7) << 12) | (1 << 15); else return error("CAS accepts either data or address registers for Rn1:Rn2 pair"); - if (*tok++ != ')') + if (*tok.u32++ != ')') return error("missing ("); - if (*tok++ != ':') + if (*tok.u32++ != ':') return error("missing colon"); // Rn2 - if (*tok++ != '(') + if (*tok.u32++ != '(') return error("missing ("); - if ((*tok >= KW_D0) && (*tok <= KW_D7)) - inst3 |= (((*tok++) & 7) << 12) | (0 << 15); - else if ((*tok >= KW_A0) && (*tok <= KW_A7)) - inst3 |= (((*tok++) & 7) << 12) | (1 << 15); + if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7)) + inst3 |= (((*tok.u32++) & 7) << 12) | (0 << 15); + else if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7)) + inst3 |= (((*tok.u32++) & 7) << 12) | (1 << 15); else return error("CAS accepts either data or address registers for Rn1:Rn2 pair"); - if (*tok++ != ')') + if (*tok.u32++ != ')') return error("missing ("); - if (*tok != EOL) + if (*tok.u32 != EOL) return error("extra (unexpected) text found"); D_word(inst); @@ -1655,16 +1651,16 @@ int m_cpbr(WORD inst, WORD siz) if (siz == SIZL) { // .L - D_word(inst); - AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr); - D_long(0); + D_word(inst); + AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, (TOKENPTR)a0expr); + D_long(0); return OK; } else { // .W D_word(inst); - AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr); + AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, (TOKENPTR)a0expr); D_word(0); } @@ -1677,39 +1673,38 @@ int m_cpbr(WORD inst, WORD siz) // int m_cpdbr(WORD inst, WORD siz) { - CHECK00; + CHECK00; - uint32_t v; - WORD condition = inst & 0x1f; // Grab condition sneakily placed in the lower 5 bits of inst - inst &= 0xffe0; // And then mask them out - you ain't seen me, roit? + uint32_t v; + WORD condition = inst & 0x1F; // Grab condition sneakily placed in the lower 5 bits of inst + inst &= 0xFFE0; // And then mask them out - you ain't seen me, roit? - inst |= (1 << 9); // Bolt on FPU id - inst |= a0reg; + inst |= (1 << 9); // Bolt on FPU id + inst |= a0reg; - D_word(inst); + D_word(inst); - D_word(condition); + D_word(condition); - if (a1exattr & DEFINED) - { - if ((a1exattr & TDB) != cursect) - return error(rel_error); + if (a1exattr & DEFINED) + { + if ((a1exattr & TDB) != cursect) + return error(rel_error); v = (uint32_t)a1exval - sloc; - if (v + 0x8000 > 0x10000) - return error(range_error); - - D_word(v); - } - else - { - AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr); - D_word(0); - } + if (v + 0x8000 > 0x10000) + return error(range_error); - return OK; + D_word(v); + } + else + { + AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, (TOKENPTR)a1expr); + D_word(0); + } + return OK; } @@ -2129,67 +2124,70 @@ int m_move16b(WORD inst, WORD siz) // int m_pack(WORD inst, WORD siz) { - CHECK00; + CHECK00; - if (siz != SIZN) - return error("bad size suffix"); + if (siz != SIZN) + return error("bad size suffix"); - if (*tok >= KW_D0 && *tok <= KW_D7) - { - // Dx,Dy,# - inst |= (0 << 3); // R/M - inst |= (*tok++ & 7); - if (*tok != ',' && tok[2] != ',') - return error("missing comma"); - if (tok[1] < KW_D0 && tok[1] > KW_D7) - return error(syntax_error); - inst |= ((tok[1] & 7)<<9); - tok = tok + 3; - D_word(inst); - // Fall through for adjustment (common in both valid cases) - } - else if (*tok == '-') - { - // -(Ax),-(Ay),# - inst |= (1 << 3); // R/M - tok++; // eat the minus - if ((*tok != '(') && (tok[2]!=')') && (tok[3]!=',') && (tok[4] != '-') && (tok[5] != '(') && (tok[7] != ')') && (tok[8] != ',')) - return error(syntax_error); - if (tok[1] < KW_A0 && tok[1] > KW_A7) - return error(syntax_error); - if (tok[5] < KW_A0 && tok[6] > KW_A7) - return error(syntax_error); - inst |= ((tok[1] & 7) << 0); - inst |= ((tok[6] & 7) << 9); - tok = tok + 9; - D_word(inst); - // Fall through for adjustment (common in both valid cases) - } - else - return error("invalid syntax"); + if (*tok.u32 >= KW_D0 && *tok.u32 <= KW_D7) + { + // Dx,Dy,# + inst |= (0 << 3); // R/M + inst |= (*tok.u32++ & 7); + if (*tok.u32 != ',' && tok.u32[2] != ',') + return error("missing comma"); - if ((*tok != CONST) && (*tok != SYMBOL) && (*tok != '-')) - return error(syntax_error); + if (tok.u32[1] < KW_D0 && tok.u32[1] > KW_D7) + return error(syntax_error); - if (expr(a0expr, &a0exval, &a0exattr, &a0esym)==ERROR) - return ERROR; + inst |= ((tok.u32[1] & 7)<<9); + tok.u32 = tok.u32 + 3; + D_word(inst); + // Fall through for adjustment (common in both valid cases) + } + else if (*tok.u32 == '-') + { + // -(Ax),-(Ay),# + inst |= (1 << 3); // R/M + tok.u32++; // eat the minus - if ((a0exattr & DEFINED) == 0) - return error(undef_error); + if ((*tok.u32 != '(') && (tok.u32[2]!=')') && (tok.u32[3]!=',') && (tok.u32[4] != '-') && (tok.u32[5] != '(') && (tok.u32[7] != ')') && (tok.u32[8] != ',')) + return error(syntax_error); - if (a0exval + 0x8000 > 0x10000) - return error(""); + if (tok.u32[1] < KW_A0 && tok.u32[1] > KW_A7) + return error(syntax_error); - if (*tok != EOL) - return error(extra_stuff); + if (tok.u32[5] < KW_A0 && tok.u32[6] > KW_A7) + return error(syntax_error); - D_word((a0exval & 0xffff)); + inst |= ((tok.u32[1] & 7) << 0); + inst |= ((tok.u32[6] & 7) << 9); + tok.u32 = tok.u32 + 9; + D_word(inst); + // Fall through for adjustment (common in both valid cases) + } + else + return error("invalid syntax"); + if ((*tok.u32 != CONST) && (*tok.u32 != SYMBOL) && (*tok.u32 != '-')) + return error(syntax_error); + if (expr((TOKENPTR)a0expr, &a0exval, &a0exattr, &a0esym) == ERROR) + return ERROR; - return OK; + if ((a0exattr & DEFINED) == 0) + return error(undef_error); + + if (a0exval + 0x8000 > 0x10000) + return error(""); + + if (*tok.u32 != EOL) + return error(extra_stuff); + D_word((a0exval & 0xFFFF)); + + return OK; } @@ -2289,18 +2287,18 @@ int m_cinv(WORD inst, WORD siz) if (am1 == AM_NONE) inst |= (0 << 6) | (a1reg); - switch (a0reg) - { - case 0: // KW_IC40 + switch (a0reg) + { + case 0: // KW_IC40 inst |= (2 << 6) | (a1reg); - break; - case 1: // KW_DC40 + break; + case 1: // KW_DC40 inst |= (1 << 6) | (a1reg); - break; - case 2: // KW_BC40 + break; + case 2: // KW_BC40 inst |= (3 << 6) | (a1reg); - break; - } + break; + } D_word(inst); return OK; @@ -2377,17 +2375,11 @@ int m_moves(WORD inst, WORD siz) return error(unsupport); if (siz == SIZB) - { inst |= 0 << 6; - } else if (siz == SIZL) - { inst |= 2 << 6; - } else // SIZW/SIZN - { inst |= 1 << 6; - } if (am0 == DREG) { @@ -2440,24 +2432,23 @@ int m_pbcc(WORD inst, WORD siz) // int m_pflusha(WORD inst, WORD siz) { - if (activecpu == CPU_68030) - { - D_word(inst); - inst = (1 << 13) | (1 << 10) | (0 << 5) | 0; - D_word(inst); - return OK; -} - else if (activecpu == CPU_68040) - { - inst = B16(11110101, 00011000); - D_word(inst); - return OK; - } - else - return error(unsupport); - - return OK; + if (activecpu == CPU_68030) + { + D_word(inst); + inst = (1 << 13) | (1 << 10) | (0 << 5) | 0; + D_word(inst); + return OK; + } + else if (activecpu == CPU_68040) + { + inst = B16(11110101, 00011000); + D_word(inst); + return OK; + } + else + return error(unsupport); + return OK; } @@ -2468,116 +2459,132 @@ int m_pflush(WORD inst, WORD siz) { if (activecpu == CPU_68030) { - // PFLUSH FC, MASK - // PFLUSH FC, MASK, < ea > - WORD mask, fc; - switch ((int)*tok) - { - case '#': - tok++; - if (*tok != CONST && *tok != SYMBOL) - return error("function code should be an expression"); - if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR) - return ERROR; - if ((a0exattr & DEFINED) == 0) - return error("function code immediate should be defined"); - if (a0exval > 7 && a0exval < 0) - return error("function code out of range (0-7)"); + // PFLUSH FC, MASK + // PFLUSH FC, MASK, < ea > + WORD mask, fc; + + switch ((int)*tok.u32) + { + case '#': + tok.u32++; + + if (*tok.u32 != CONST && *tok.u32 != SYMBOL) + return error("function code should be an expression"); + + if (expr((TOKENPTR)a0expr, &a0exval, &a0exattr, &a0esym) == ERROR) + return ERROR; + + if ((a0exattr & DEFINED) == 0) + return error("function code immediate should be defined"); + + if (a0exval > 7 && a0exval < 0) + return error("function code out of range (0-7)"); + fc = (uint16_t)a0exval; - break; - case KW_D0: - case KW_D1: - case KW_D2: - case KW_D3: - case KW_D4: - case KW_D5: - case KW_D6: - case KW_D7: - fc = (1 << 4) | (*tok++ & 7); - break; - case KW_SFC: - fc = 0; - tok++; - break; - case KW_DFC: - fc = 1; - tok++; - break; - default: - return error(syntax_error); - } - - if (*tok++ != ',') - return error("comma exptected"); - - if (*tok++ != '#') - return error("mask should be an immediate value"); - if (*tok != CONST && *tok != SYMBOL) - return error("mask is supposed to be immediate"); - if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR) - return ERROR; - if ((a0exattr & DEFINED) == 0) - return error("mask immediate value should be defined"); - if (a0exval > 7 && a0exval < 0) - return error("function code out of range (0-7)"); + break; + case KW_D0: + case KW_D1: + case KW_D2: + case KW_D3: + case KW_D4: + case KW_D5: + case KW_D6: + case KW_D7: + fc = (1 << 4) | (*tok.u32++ & 7); + break; + case KW_SFC: + fc = 0; + tok.u32++; + break; + case KW_DFC: + fc = 1; + tok.u32++; + break; + default: + return error(syntax_error); + } + + if (*tok.u32++ != ',') + return error("comma exptected"); + + if (*tok.u32++ != '#') + return error("mask should be an immediate value"); + + if (*tok.u32 != CONST && *tok.u32 != SYMBOL) + return error("mask is supposed to be immediate"); + + if (expr((TOKENPTR)a0expr, &a0exval, &a0exattr, &a0esym) == ERROR) + return ERROR; + + if ((a0exattr & DEFINED) == 0) + return error("mask immediate value should be defined"); + + if (a0exval > 7 && a0exval < 0) + return error("function code out of range (0-7)"); + mask = (uint16_t)a0exval << 5; - if (*tok == EOL) - { - // PFLUSH FC, MASK - D_word(inst); - inst = (1 << 13) | fc | mask | (4 << 10); - D_word(inst); - return OK; - } - else if (*tok == ',') - { - // PFLUSH FC, MASK, < ea > - tok++; - if (amode(0) == ERROR) - return ERROR; - if (*tok != EOL) - return error(extra_stuff); - if (am0 == AIND || am0 == ABSW || am0 == ABSL || am0 == ADISP || am0 == ADISP || am0 == AINDEXED || am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE) - { - inst |= am0 | a0reg; - D_word(inst); - inst = (1 << 13) | fc | mask | (6 << 10); - D_word(inst); - ea0gen(siz); - return OK; - } - else - return error("unsupported addressing mode"); - - } - else - return error(syntax_error); - - return OK; + if (*tok.u32 == EOL) + { + // PFLUSH FC, MASK + D_word(inst); + inst = (1 << 13) | fc | mask | (4 << 10); + D_word(inst); + return OK; + } + else if (*tok.u32 == ',') + { + // PFLUSH FC, MASK, < ea > + tok.u32++; + + if (amode(0) == ERROR) + return ERROR; + + if (*tok.u32 != EOL) + return error(extra_stuff); + if (am0 == AIND || am0 == ABSW || am0 == ABSL || am0 == ADISP || am0 == ADISP || am0 == AINDEXED || am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE) + { + inst |= am0 | a0reg; + D_word(inst); + inst = (1 << 13) | fc | mask | (6 << 10); + D_word(inst); + ea0gen(siz); + return OK; + } + else + return error("unsupported addressing mode"); + + } + else + return error(syntax_error); + + return OK; } else if (activecpu == CPU_68040 || activecpu == CPU_68060) { - // PFLUSH(An) - // PFLUSHN(An) - if (*tok != '(' && tok[2] != ')') - return error(syntax_error); - if (tok[1] < KW_A0 && tok[1] > KW_A7) - return error("expected (An)"); - if ((inst & 7) == 7) - // With pflushn/pflush there's no easy way to - // distinguish between the two in 68040 mode. - // Ideally the opcode bitfields would have been - // hardcoded in 68ktab but there is aliasing - // between 68030 and 68040 opcode. So we just - // set the 3 lower bits to 1 in pflushn inside - // 68ktab and detect it here. - inst = (inst & 0xff8) | 8; - inst |= (tok[1] & 7) | (5 << 8); - if (tok[3] != EOL) - return error(extra_stuff); - D_word(inst); + // PFLUSH(An) + // PFLUSHN(An) + if (*tok.u32 != '(' && tok.u32[2] != ')') + return error(syntax_error); + + if (tok.u32[1] < KW_A0 && tok.u32[1] > KW_A7) + return error("expected (An)"); + + if ((inst & 7) == 7) + // With pflushn/pflush there's no easy way to distinguish between + // the two in 68040 mode. Ideally the opcode bitfields would have + // been hardcoded in 68ktab but there is aliasing between 68030 + // and 68040 opcode. So we just set the 3 lower bits to 1 in + // pflushn inside 68ktab and detect it here. + inst = (inst & 0xff8) | 8; + + inst |= (tok.u32[1] & 7) | (5 << 8); + + if (tok.u32[3] != EOL) + return error(extra_stuff); + + D_word(inst); } else return error(unsupport); @@ -2643,56 +2650,53 @@ int m_pflushr(WORD inst, WORD siz) // int m_pload(WORD inst, WORD siz, WORD extension) { - // TODO: 68551 support is not added yet. - // None of the ST series of computers had - // a 68020 + 68551 socket and since this is - // an Atari targetted assembler.... - CHECKNO30; - - inst |= am1; - - D_word(inst); - - switch (am0) - { - case CREG: - if (a0reg == KW_SFC - KW_SFC) - { - inst = 0; - } - else if (a0reg == KW_DFC - KW_SFC) - { - inst = 1; - } - else - return error("illegal control register specified"); - break; - case DREG: - inst = (1 << 3) | a0reg; - break; - case IMMED: - if ((a0exattr & DEFINED) == 0) - return error("constant value must be defined"); + // TODO: 68551 support is not added yet. + // None of the ST series of computers had a 68020 + 68551 socket and since + // this is an Atari targetted assembler... + CHECKNO30; + + inst |= am1; + + D_word(inst); + + switch (am0) + { + case CREG: + if (a0reg == KW_SFC - KW_SFC) + inst = 0; + else if (a0reg == KW_DFC - KW_SFC) + inst = 1; + else + return error("illegal control register specified"); + + break; + case DREG: + inst = (1 << 3) | a0reg; + break; + case IMMED: + if ((a0exattr & DEFINED) == 0) + return error("constant value must be defined"); + inst = (2 << 3) | (uint16_t)a0exval; - break; - } + break; + } - inst |= extension | (1 << 13); - D_word(inst); + inst |= extension | (1 << 13); + D_word(inst); - ea1gen(siz); + ea1gen(siz); - return OK; + return OK; } int m_ploadr(WORD inst, WORD siz) { - return m_pload(inst, siz, 1 << 9); + return m_pload(inst, siz, 1 << 9); } int m_ploadw(WORD inst, WORD siz) { - return m_pload(inst, siz, 0 << 9); + return m_pload(inst, siz, 0 << 9); } // @@ -2702,12 +2706,12 @@ int m_pmove(WORD inst, WORD siz) { int inst2,reg; - // TODO: 68551 support is not added yet. - // None of the ST series of computers had - // a 68020 + 68551 socket and since this is - // an Atari targetted assembler.... - // (same for 68EC030) - CHECKNO30; + // TODO: 68551 support is not added yet. + // None of the ST series of computers had + // a 68020 + 68551 socket and since this is + // an Atari targetted assembler.... + // (same for 68EC030) + CHECKNO30; inst2 = inst & (1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd inst &= ~(1 << 8); //And mask it out @@ -2725,11 +2729,11 @@ int m_pmove(WORD inst, WORD siz) else return error("pmove sez: Wut?"); - // The instruction is a quad-word (8 byte) operation - // for the CPU root pointer and the supervisor root pointer. - // It is a long - word operation for the translation control register - // and the transparent translation registers(TT0 and TT1). - // It is a word operation for the MMU status register. + // The instruction is a quad-word (8 byte) operation + // for the CPU root pointer and the supervisor root pointer. + // It is a long - word operation for the translation control register + // and the transparent translation registers(TT0 and TT1). + // It is a word operation for the MMU status register. if (((reg == (KW_URP - KW_SFC)) || (reg == (KW_SRP - KW_SFC))) && ((siz != SIZD) && (siz != SIZN))) @@ -2745,7 +2749,7 @@ int m_pmove(WORD inst, WORD siz) if (am0 == CREG) { - inst |= am1 | a1reg; + inst |= am1 | a1reg; D_word(inst); } else if (am1 == CREG) @@ -2756,37 +2760,33 @@ int m_pmove(WORD inst, WORD siz) switch (reg + KW_SFC) { - case KW_TC: - inst2 |= (0 << 10) + (1 << 14); break; - case KW_SRP: - inst2 |= (2 << 10) + (1 << 14); break; - case KW_CRP: - inst2 |= (3 << 10) + (1 << 14); break; - case KW_TT0: + case KW_TC: + inst2 |= (0 << 10) + (1 << 14); break; + case KW_SRP: + inst2 |= (2 << 10) + (1 << 14); break; + case KW_CRP: + inst2 |= (3 << 10) + (1 << 14); break; + case KW_TT0: inst2 |= (2 << 10) + (0 << 13); break; - case KW_TT1: + case KW_TT1: inst2 |= (3 << 10) + (0 << 13); break; - case KW_MMUSR: - if (am0 == CREG) - inst2 |= (1 << 9) + (3 << 13); - else - inst2 |= (0 << 9) + (3 << 13); - break; - default: - return error("unsupported register"); - break; + case KW_MMUSR: + if (am0 == CREG) + inst2 |= (1 << 9) + (3 << 13); + else + inst2 |= (0 << 9) + (3 << 13); + break; + default: + return error("unsupported register"); + break; } D_word(inst2); - if (am0 == CREG) - { - ea1gen(siz); - } - else if (am1 == CREG) - { - ea0gen(siz); - } + if (am0 == CREG) + ea1gen(siz); + else if (am1 == CREG) + ea0gen(siz); return OK; } @@ -2808,28 +2808,28 @@ int m_pmovefd(WORD inst, WORD siz) #define gen_ptrapcc(name,opcode) \ int m_##name(WORD inst, WORD siz) \ { \ - CHECKNO20; \ - if (siz == SIZW) \ - { \ - D_word(inst); \ - D_word(B8(opcode)); \ - D_word(a0exval); \ - } \ - else \ - { \ - inst |= 3; \ - D_word(inst); \ - D_word(B8(opcode)); \ - D_long(a0exval); \ - } \ - return OK; \ + CHECKNO20; \ + if (siz == SIZW) \ + { \ + D_word(inst); \ + D_word(B8(opcode)); \ + D_word(a0exval); \ + } \ + else \ + { \ + inst |= 3; \ + D_word(inst); \ + D_word(B8(opcode)); \ + D_long(a0exval); \ + } \ + return OK; \ }\ int m_##name##n(WORD inst, WORD siz) \ { \ - CHECKNO20; \ - D_word(inst); \ - D_word(B8(opcode)); \ - return OK; \ + CHECKNO20; \ + D_word(inst); \ + D_word(B8(opcode)); \ + return OK; \ } gen_ptrapcc(ptrapbs,00000000) @@ -2923,7 +2923,7 @@ static inline int gen_fpu(WORD inst, WORD siz, WORD opmode, WORD emul) switch (siz) { - case SIZB: inst |= (6 << 10); break; + case SIZB: inst |= (6 << 10); break; case SIZW: inst |= (4 << 10); break; case SIZL: inst |= (0 << 10); break; case SIZN: @@ -3111,7 +3111,7 @@ int m_fdbcc(WORD inst, WORD siz) } else { - AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr); + AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, (TOKENPTR)a1expr); D_word(0); } @@ -3273,30 +3273,31 @@ int m_fmove(WORD inst, WORD siz) // Source specifier switch (siz) { - case SIZB: inst |= (6 << 10); break; + case SIZB: inst |= (6 << 10); break; case SIZW: inst |= (4 << 10); break; case SIZL: inst |= (0 << 10); break; case SIZN: case SIZS: inst |= (1 << 10); break; case SIZD: inst |= (5 << 10); break; case SIZX: inst |= (2 << 10); break; - case SIZP: inst |= (3 << 10); - // In P size we have 2 cases: {#k} where k is immediate - // and {Dn} where Dn=Data register + case SIZP: inst |= (3 << 10); + // In P size we have 2 cases: {#k} where k is immediate + // and {Dn} where Dn=Data register if (bfparam1) - { - // Dn + { + // Dn inst |= 1 << 12; - inst |= bfval1 << 4; - } - else - { - // #k - if (bfval1>63 && bfval1<-64) - return error("K-factor must be between -64 and 63"); - inst |= bfval1 & 127; - } + inst |= bfval1 << 4; + } + else + { + // #k + if (bfval1 > 63 && bfval1 < -64) + return error("K-factor must be between -64 and 63"); + + inst |= bfval1 & 127; + } break; default: @@ -3328,14 +3329,14 @@ int m_fmove(WORD inst, WORD siz) // Source specifier switch (siz) { - case SIZB: inst |= (6 << 10); break; + case SIZB: inst |= (6 << 10); break; case SIZW: inst |= (4 << 10); break; case SIZL: inst |= (0 << 10); break; case SIZN: case SIZS: inst |= (1 << 10); break; case SIZD: inst |= (5 << 10); break; case SIZX: inst |= (2 << 10); break; - case SIZP: inst |= (3 << 10); break; + case SIZP: inst |= (3 << 10); break; default: return error("Something bad happened, possibly."); break; @@ -3468,13 +3469,13 @@ int m_fmovem(WORD inst, WORD siz) if (siz == SIZX || siz==SIZN) { - if ((*tok >= KW_FP0) && (*tok <= KW_FP7)) + if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7)) { //fmovem.x ,ea if (fpu_reglist_left(®mask) < 0) return OK; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); if (amode(0) < 0) @@ -3491,12 +3492,12 @@ int m_fmovem(WORD inst, WORD siz) ea0gen(siz); return OK; } - else if ((*tok >= KW_D0) && (*tok <= KW_D7)) + else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7)) { // fmovem.x Dn,ea - datareg = (*tok++ & 7) << 10; + datareg = (*tok.u32++ & 7) << 10; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); if (amode(0) < 0) @@ -3521,10 +3522,10 @@ int m_fmovem(WORD inst, WORD siz) inst |= am0 | a0reg; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); - if ((*tok >= KW_FP0) && (*tok <= KW_FP7)) + if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7)) { //fmovem.x ea, if (fpu_reglist_right(®mask) < 0) @@ -3539,7 +3540,7 @@ int m_fmovem(WORD inst, WORD siz) else { // fmovem.x ea,Dn - datareg = (*tok++ & 7) << 10; + datareg = (*tok.u32++ & 7) << 10; D_word(inst); inst = (1 << 15) | (1 << 14) | (0 << 13) | (3 << 11) | (datareg << 4); D_word(inst); @@ -3550,39 +3551,39 @@ int m_fmovem(WORD inst, WORD siz) } else if (siz == SIZL) { - if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR)) + if ((*tok.u32 == KW_FPCR) || (*tok.u32 == KW_FPSR) || (*tok.u32 == KW_FPIAR)) { //fmovem.l ,ea regmask = (1 << 15) | (1 << 13); fmovem_loop_1: - if (*tok == KW_FPCR) + if (*tok.u32 == KW_FPCR) { regmask |= (1 << 12); - tok++; + tok.u32++; goto fmovem_loop_1; } - if (*tok == KW_FPSR) + if (*tok.u32 == KW_FPSR) { regmask |= (1 << 11); - tok++; + tok.u32++; goto fmovem_loop_1; } - if (*tok == KW_FPIAR) + if (*tok.u32 == KW_FPIAR) { regmask |= (1 << 10); - tok++; + tok.u32++; goto fmovem_loop_1; } - if ((*tok == '/') || (*tok == '-')) + if ((*tok.u32 == '/') || (*tok.u32 == '-')) { - tok++; + tok.u32++; goto fmovem_loop_1; } - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); if (amode(0) < 0) @@ -3601,40 +3602,40 @@ fmovem_loop_1: inst |= am0 | a0reg; - if (*tok++ != ',') + if (*tok.u32++ != ',') return error("missing comma"); regmask = (1 << 15) | (0 << 13); fmovem_loop_2: - if (*tok == KW_FPCR) + if (*tok.u32 == KW_FPCR) { regmask |= (1 << 12); - tok++; + tok.u32++; goto fmovem_loop_2; } - if (*tok == KW_FPSR) + if (*tok.u32 == KW_FPSR) { regmask |= (1 << 11); - tok++; + tok.u32++; goto fmovem_loop_2; } - if (*tok == KW_FPIAR) + if (*tok.u32 == KW_FPIAR) { regmask |= (1 << 10); - tok++; + tok.u32++; goto fmovem_loop_2; } - if ((*tok == '/') || (*tok == '-')) + if ((*tok.u32 == '/') || (*tok.u32 == '-')) { - tok++; + tok.u32++; goto fmovem_loop_2; } - if (*tok!=EOL) + if (*tok.u32 != EOL) return error("extra (unexpected) text found"); inst |= am0 | a0reg; @@ -3873,26 +3874,26 @@ gen_FScc(fssne , 00011110); #define gen_FTRAPcc(name,opcode) \ int m_##name (WORD inst, WORD siz) \ { \ - if (siz==SIZW) \ - { \ - D_word(inst); \ - D_word(B8(opcode)); \ - D_word(a0exval); \ - } \ - else \ - { \ - inst|=3; \ - D_word(inst); \ - D_word(B8(opcode)); \ - D_long(a0exval); \ - } \ - return OK;\ + if (siz==SIZW) \ + { \ + D_word(inst); \ + D_word(B8(opcode)); \ + D_word(a0exval); \ + } \ + else \ + { \ + inst|=3; \ + D_word(inst); \ + D_word(B8(opcode)); \ + D_long(a0exval); \ + } \ + return OK;\ } \ int m_##name##n (WORD inst, WORD siz) \ { \ - D_word(inst); \ - D_word(B8(opcode)); \ - return OK;\ + D_word(inst); \ + D_word(B8(opcode)); \ + return OK;\ } gen_FTRAPcc(ftrapeq ,00000001) diff --git a/macro.c b/macro.c index 54d34c4..4644346 100644 --- a/macro.c +++ b/macro.c @@ -153,10 +153,10 @@ int DefineMacro(void) // Setup entry in symbol table, make sure the macro isn't a duplicate // entry, and that it doesn't override any processor mnemonic or assembler // directive. - if (*tok++ != SYMBOL) + if (*tok.u32++ != SYMBOL) return error("missing symbol"); - char * name = string[*tok++]; + char * name = string[*tok.u32++]; if (lookup(name, MACRO, 0) != NULL) return error("duplicate macro definition"); @@ -166,7 +166,7 @@ int DefineMacro(void) curmac->sattr = (WORD)(macnum++); // Parse and define formal arguments in symbol table - if (*tok != EOL) + if (*tok.u32 != EOL) { argno = 0; symlist(defmac2); @@ -307,19 +307,19 @@ static int LNCatch(int (* lnfunc)(), char * dirlist) char * p = NULL; int k = -1; - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { // A string followed by a colon or double colon is a symbol and // *not* a directive, see if we can find the directive after it - if ((tok[2] == ':' || tok[2] == DCOLON)) + if ((tok.u32[2] == ':' || tok.u32[2] == DCOLON)) { - if (tok[3] == SYMBOL) - p = string[tok[4]]; + if (tok.u32[3] == SYMBOL) + p = string[tok.u32[4]]; } else { // Otherwise, just grab the directive - p = string[tok[1]]; + p = string[tok.u32[1]]; } } @@ -389,7 +389,7 @@ static int KWMatch(char * kw, char * kwlist) // int InvokeMacro(SYM * mac, WORD siz) { - DEBUG { printf("InvokeMacro: arguments="); DumpTokens(tok); } + DEBUG { printf("InvokeMacro: arguments="); DumpTokens(tok.u32); } INOBJ * inobj = a_inobj(SRC_IMACRO); // Alloc and init IMACRO IMACRO * imacro = inobj->inobj.imacro; @@ -397,46 +397,46 @@ int InvokeMacro(SYM * mac, WORD siz) // Chop up the arguments, if any (tok comes from token.c, which at this // point points at the macro argument token stream) - if (*tok != EOL) + if (*tok.u32 != EOL) { // Parse out the arguments and set them up correctly TOKEN * p = imacro->argument[nargs].token; int stringNum = 0; - while (*tok != EOL) + while (*tok.u32 != EOL) { - if (*tok == ACONST) + if (*tok.u32 == ACONST) { for(int i=0; i<3; i++) - *p++ = *tok++; + *p++ = *tok.u32++; } - else if (*tok == CONST) // Constants are 64-bits + else if (*tok.u32 == CONST) // Constants are 64-bits { - *p++ = *tok++; // Token + *p++ = *tok.u32++; // Token uint64_t *p64 = (uint64_t *)p; - uint64_t *tok64 = (uint64_t *)tok; + uint64_t *tok64 = (uint64_t *)tok.u32; *p64++ = *tok64++; - tok = (TOKEN *)tok64; + tok.u32 = (TOKEN *)tok64; p = (uint32_t *)p64; } - else if ((*tok == STRING) || (*tok == SYMBOL)) + else if ((*tok.u32 == STRING) || (*tok.u32 == SYMBOL)) { - *p++ = *tok++; - imacro->argument[nargs].string[stringNum] = strdup(string[*tok++]); + *p++ = *tok.u32++; + imacro->argument[nargs].string[stringNum] = strdup(string[*tok.u32++]); *p++ = stringNum++; } - else if (*tok == ',') + else if (*tok.u32 == ',') { // Comma delimiter was found, so set up for next argument *p++ = EOL; - tok++; + tok.u32++; stringNum = 0; nargs++; p = imacro->argument[nargs].token; } else { - *p++ = *tok++; + *p++ = *tok.u32++; } } diff --git a/mark.h b/mark.h index 3b2aa53..4222bbf 100644 --- a/mark.h +++ b/mark.h @@ -26,6 +26,10 @@ MCHUNK { #define MWORD 0x0000 // Marked word #define MLONG 0x0100 // Marked long +//This will have to be defined eventually. Might have to overhaul the mark +//system as 8-bits doesn't seem to be enough, at least for a bitfield (which it +//might not have to be, in which case it would be big enough...) +//#define MQUAD 0x // Marked quad word (TODO: merge with MDOUBLE?) #define MMOVEI 0x0200 // Mark RISC MOVEI instruction #define MDOUBLE 0x0400 // Marked double float #define MEXTEND 0x0800 // Marked extended float diff --git a/parmode.h b/parmode.h index e5e0b91..0c5ca2c 100644 --- a/parmode.h +++ b/parmode.h @@ -12,19 +12,19 @@ // Dn // An // # expression - if ((*tok >= KW_D0) && (*tok <= KW_D7)) + if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7)) { AMn = DREG; - AnREG = *tok++ & 7; + AnREG = *tok.u32++ & 7; } - else if ((*tok >= KW_A0) && (*tok <= KW_A7)) + else if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7)) { AMn = AREG; - AnREG = *tok++ & 7; + AnREG = *tok.u32++ & 7; } - else if (*tok == '#') + else if (*tok.u32 == '#') { - tok++; + tok.u32++; if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) return ERROR; @@ -48,21 +48,21 @@ // ([bd,An,Xn],od) // ([bd,PC],Xn,od) // ([bd,PC,Xn],od) - else if (*tok == '(') + else if (*tok.u32 == '(') { - tok++; + tok.u32++; - if ((*tok >= KW_A0) && (*tok <= KW_A7)) + if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7)) { - AnREG = *tok++ & 7; + AnREG = *tok.u32++ & 7; - if (*tok == ')') + if (*tok.u32 == ')') { - tok++; + tok.u32++; - if (*tok == '+') + if (*tok.u32 == '+') { - tok++; + tok.u32++; AMn = APOSTINC; } else @@ -74,14 +74,14 @@ AMn = AINDEXED; goto AMn_IX0; // Handle ",Xn[.siz][*scale])" } - else if ((*tok >= KW_D0) && (*tok <= KW_D7)) + else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7)) { //Since index register isn't used here, store register number in this field - AnIXREG = *tok++ & 7; // (Dn) + AnIXREG = *tok.u32++ & 7; // (Dn) - if (*tok == ')') + if (*tok.u32 == ')') { - tok++; + tok.u32++; AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8 AnEXTEN |= EXT_BS; // Base register suppressed AnEXTEN |= EXT_BDSIZE0; // Base displacement null @@ -90,21 +90,21 @@ AnREG = 6 << 3; // stuff 110 to mode field goto AnOK; } - else if (*tok == 'L') + else if (*tok.u32 == 'L') { // TODO: does DINDL gets used at all? AMn = DINDL; // (Dn.l) AnEXTEN = 1 << 1; // Long index size - tok++; + tok.u32++; } - else if (*tok == 'W') // (Dn.w) + else if (*tok.u32 == 'W') // (Dn.w) { // TODO: does DINDW gets used at all? AMn = DINDW; AnEXTEN = 1 << 1; // Word index size - tok++; + tok.u32++; } - else if (*tok == ',') + else if (*tok.u32 == ',') { // ([bd,An],Xn..) without bd, An // Base displacement is suppressed @@ -112,7 +112,7 @@ AnEXTEN |= EXT_BS; // Base register suppressed AnEXTEN |= EXT_BDSIZE0; AnREG = 6 << 3; // stuff 110 to mode field - tok++; + tok.u32++; goto CHECKODn; } else @@ -120,11 +120,11 @@ return error("(Dn) error"); } - if (*tok == '*') + if (*tok.u32 == '*') { // scale: *1, *2, *4, *8 - tok++; + tok.u32++; - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) return error("scale factor expression must evaluate"); @@ -146,11 +146,11 @@ goto badmode; } } - else if (*tok++ != CONST || *tok > 8) + else if (*tok.u32++ != CONST || *tok.u32 > 8) goto badmode; else { - switch ((int)*tok++) + switch ((int)*tok.u32++) { case 1: break; @@ -169,9 +169,9 @@ } } - if (*tok == ')') + if (*tok.u32 == ')') { - tok++; + tok.u32++; AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8 AnEXTEN |= EXT_BS; // Base register suppressed AnEXTEN |= EXT_BDSIZE0; // Base displacement null @@ -180,9 +180,9 @@ AMn = MEMPOST; goto AnOK; } - else if (*tok==',') + else if (*tok.u32 == ',') { - tok++; // eat the comma + tok.u32++; // eat the comma // It might be (Dn[.wl][*scale],od) // Maybe this is wrong and we have to write some code here // instead of reusing that path... @@ -192,9 +192,9 @@ else return error("unhandled so far"); } - else if (*tok == KW_PC) + else if (*tok.u32 == KW_PC) { // (PC,Xn[.siz][*scale]) - tok++; + tok.u32++; AMn = PCINDEXED; // Common index handler; enter here with 'tok' pointing at the @@ -207,34 +207,34 @@ AMn_IXN: // Handle any indexed (tok -> a comma) - if (*tok++ != ',') + if (*tok.u32++ != ',') goto badmode; - if (*tok < KW_D0 || *tok > KW_A7) + if (*tok.u32 < KW_D0 || *tok.u32 > KW_A7) goto badmode; - AnIXREG = *tok++ & 15; + AnIXREG = *tok.u32++ & 15; - switch ((int)*tok) + switch ((int)*tok.u32) { // Index reg size: | .W | .L case DOTW: - tok++; + tok.u32++; default: AnIXSIZ = 0; break; case DOTL: AnIXSIZ = 0x0800; - tok++; + tok.u32++; break; case DOTB: // .B not allowed here... goto badmode; } - if (*tok == '*') + if (*tok.u32 == '*') { // scale: *1, *2, *4, *8 - tok++; + tok.u32++; - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) return error("scale factor expression must evaluate"); @@ -255,11 +255,11 @@ goto badmode; } } - else if (*tok++ != CONST || *tok > 8) + else if (*tok.u32++ != CONST || *tok.u32 > 8) goto badmode; else { - switch ((int)*tok++) + switch ((int)*tok.u32++) { case 1: break; @@ -278,27 +278,27 @@ } } - if (*tok == ',') + if (*tok.u32 == ',') { // If we got here we didn't get any [] stuff // so let's suppress base displacement before // branching off - tok++; + tok.u32++; AnEXTEN |= EXT_BDSIZE0; // Base displacement null - suppressed goto CHECKODn; } - if (*tok++ != ')') // final ")" + if (*tok.u32++ != ')') // final ")" goto badmode; goto AnOK; } - else if (*tok == '[') + else if (*tok.u32 == '[') { // ([... - tok++; + tok.u32++; 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.u32 != CONST && *tok.u32 != SYMBOL) { AnEXTEN |= EXT_BDSIZE0; } @@ -310,18 +310,18 @@ // bd=0 so let's optimise it out AnEXTEN|=EXT_BDSIZE0; } - else if (*tok==DOTL) + else if (*tok.u32 == DOTL) { // ([bd.l,... AnEXTEN |= EXT_BDSIZEL; - tok++; + tok.u32++; } else { // ([bd[.w],... or ([bd,... // Is .W forced here? - if (*tok == DOTW) + if (*tok.u32 == DOTW) { AnEXTEN |= EXT_BDSIZEW; - tok++; + tok.u32++; } else { @@ -341,8 +341,8 @@ } } - if (*tok == ',') - tok++; + if (*tok.u32 == ',') + tok.u32++; //else // return error("Comma expected after base displacement"); } @@ -350,39 +350,39 @@ // Check for address register or PC, suppress base register // otherwise - if (*tok == KW_PC) + if (*tok.u32 == KW_PC) { // ([bd,PC,... AnREG = (7 << 3) | 3; // PC is special case - stuff 011 to register field and 111 to the mode field - tok++; + tok.u32++; } - else if ((*tok >= KW_A0) && (*tok <= KW_A7)) + else if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7)) { // ([bd,An,... - AnREG = (6 << 3) | *tok & 7; - tok++; + AnREG = (6 << 3) | *tok.u32 & 7; + tok.u32++; } - else if ((*tok >= KW_D0) && (*tok <= KW_D7)) + else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7)) { // ([bd,Dn,... AnREG = (6 << 3); - AnEXTEN |= ((*tok & 7) << 12); + AnEXTEN |= ((*tok.u32 & 7) << 12); AnEXTEN |= EXT_D; AnEXTEN |= EXT_BS; // Oh look, a data register! Which means that base register is suppressed - tok++; + tok.u32++; // Check for size { // ([bd,An/PC],Xn.W/L...) - switch ((int)*tok) + switch ((int)*tok.u32) { // Index reg size: | .W | .L case DOTW: - tok++; + tok.u32++; break; default: break; case DOTL: AnEXTEN |= EXT_L; - tok++; + tok.u32++; break; case DOTB: // .B not allowed here... @@ -391,11 +391,11 @@ } // Check for scale - if (*tok == '*') // ([bd,An/PC],Xn*...) + if (*tok.u32 == '*') // ([bd,An/PC],Xn*...) { // scale: *1, *2, *4, *8 - tok++; + tok.u32++; - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) return error("scale factor expression must evaluate"); @@ -417,11 +417,11 @@ goto badmode; } } - else if (*tok++ != CONST || *tok > 8) + else if (*tok.u32++ != CONST || *tok.u32 > 8) goto badmode; else { - switch ((int)*tok++) + switch ((int)*tok.u32++) { case 1: break; @@ -439,13 +439,13 @@ } } } - if (*tok == ']') // ([bd,Dn]... + if (*tok.u32 == ']') // ([bd,Dn]... { - tok++; + tok.u32++; goto IS_SUPPRESSEDn; } } - else if (*tok == ']') + else if (*tok.u32 == ']') { // PC and Xn is suppressed AnREG = 6 << 3; // stuff 110 to mode field @@ -458,59 +458,59 @@ } // At a crossroads here. We can accept either ([bd,An/PC],... or ([bd,An/PC,Xn*scale],... - if (*tok == ']') + if (*tok.u32 == ']') { //([bd,An/PC],Xn,od) // Check for Xn - tok++; + tok.u32++; - if (*tok == ')') + if (*tok.u32 == ')') { //Xn and od are non existent, get out of jail free card - tok++; + tok.u32++; AMn = MEMPRE; // ([bc,An,Xn],od) with no Xn and od AnEXTEN |= EXT_IS | EXT_IISPREN; //Suppress Xn and od goto AnOK; } - else if (*tok != ',') + else if (*tok.u32 != ',') return error("comma expected after ]"); else - tok++; // eat the comma + tok.u32++; // eat the comma - if ((*tok >= KW_A0) && (*tok <= KW_A7)) + if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7)) { - AnIXREG = ((*tok & 7) << 12); + AnIXREG = ((*tok.u32 & 7) << 12); AnEXTEN |= EXT_A; - tok++; + tok.u32++; } - else if ((*tok >= KW_D0) && (*tok <= KW_D7)) + else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7)) { - AnEXTEN |= ((*tok & 7) << 12); + AnEXTEN |= ((*tok.u32 & 7) << 12); AnEXTEN |= EXT_D; - tok++; + tok.u32++; } else { //No index found, suppress it AnEXTEN |= EXT_IS; - tok--; // Rewind tok to point to the comma + tok.u32--; // Rewind tok to point to the comma goto IS_SUPPRESSEDn; // https://xkcd.com/292/ - what does he know anyway? } // Check for size { // ([bd,An/PC],Xn.W/L...) - switch ((int)*tok) + switch ((int)*tok.u32) { // Index reg size: | .W | .L case DOTW: - tok++; + tok.u32++; break; default: break; case DOTL: AnEXTEN |= EXT_L; - tok++; + tok.u32++; break; case DOTB: // .B not allowed here... @@ -519,11 +519,11 @@ } // Check for scale - if (*tok == '*') // ([bd,An/PC],Xn*...) + if (*tok.u32 == '*') // ([bd,An/PC],Xn*...) { // scale: *1, *2, *4, *8 - tok++; + tok.u32++; - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) return error("scale factor expression must evaluate"); @@ -545,11 +545,11 @@ goto badmode; } } - else if (*tok++ != CONST || *tok > 8) + else if (*tok.u32++ != CONST || *tok.u32 > 8) goto badmode; else { - switch ((int)*tok++) + switch ((int)*tok.u32++) { case 1: break; @@ -569,18 +569,18 @@ } // Check for od - if (*tok == ')') // ([bd,An/PC],Xn) + if (*tok.u32 == ')') // ([bd,An/PC],Xn) { //od is non existant, get out of jail free card AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then AnEXTEN |= EXT_IISPOSN; // No outer displacement - tok++; + tok.u32++; goto AnOK; } - else if (*tok != ',') + else if (*tok.u32 != ',') return error("comma expected"); else - tok++; // eat the comma + tok.u32++; // eat the comma CHECKODn: if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) @@ -591,17 +591,17 @@ // od=0 so optimise it out AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then AnEXTEN |= EXT_IISPOSN; // No outer displacement - tok++; + tok.u32++; goto AnOK; } // ([bd,An/PC],Xn,od) - if (*tok == DOTL) + if (*tok.u32 == DOTL) { // expr.L AnEXTEN |= EXT_IISPOSL; // Long outer displacement AMn = MEMPOST; - tok++; + tok.u32++; // Defined, absolute values from $FFFF8000..$00007FFF get // optimized to absolute short @@ -622,16 +622,16 @@ AMn = MEMPOST; // Is .W forced here? - if (*tok == DOTW) + if (*tok.u32 == DOTW) { - tok++; + tok.u32++; } } // Check for final closing parenthesis - if (*tok == ')') + if (*tok.u32 == ')') { - tok++; + tok.u32++; goto AnOK; } else @@ -640,20 +640,20 @@ IS_SUPPRESSEDn: // Check for od - if (*tok == ')') // ([bd,An/PC],Xn) + if (*tok.u32 == ')') // ([bd,An/PC],Xn) { //od is non existant, get out of jail free card AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then AnEXTEN |= EXT_IISNOIN; // No outer displacement - tok++; + tok.u32++; goto AnOK; } - else if (*tok!=',') + else if (*tok.u32!=',') return error("comma expected"); else - tok++; // eat the comma + tok.u32++; // eat the comma - if ((*tok != CONST) && (*tok != SYMBOL)) + if ((*tok.u32 != CONST) && (*tok.u32 != SYMBOL)) goto badmode; expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM); @@ -663,15 +663,15 @@ IS_SUPPRESSEDn: // od=0 so optimise it out AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then AnEXTEN |= EXT_IISNOIN; // No outer displacement - tok++; + tok.u32++; goto AnOK; } // ([bd,An/PC],Xn,od) - if (*tok == DOTL) + if (*tok.u32 == DOTL) { // expr.L - tok++; + tok.u32++; AMn = MEMPOST; AnEXTEN |= EXT_IISNOIL; // Long outer displacement with IS suppressed } @@ -681,11 +681,11 @@ IS_SUPPRESSEDn: AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed AMn = MEMPRE; - if (*tok == DOTW) + if (*tok.u32 == DOTW) { //AnEXTEN|=EXT_IISNOIW; // Word outer displacement AMn = MEMPOST; - tok++; + tok.u32++; } // Defined, absolute values from $FFFF8000..$00007FFF get // optimized to absolute short @@ -699,45 +699,45 @@ IS_SUPPRESSEDn: } // Check for final closing parenthesis - if (*tok == ')') + if (*tok.u32 == ')') { - tok++; + tok.u32++; goto AnOK; } else return error("Closing parenthesis missing on addressing mode"); } - else if (*tok == ',') + else if (*tok.u32 == ',') { - *tok++; // ([bd,An,Xn.size*scale],od) + *tok.u32++; // ([bd,An,Xn.size*scale],od) //Check for Xn - if ((*tok >= KW_A0) && (*tok <= KW_A7)) + if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7)) { - AnEXTEN |= ((*tok & 7) << 12); + AnEXTEN |= ((*tok.u32 & 7) << 12); AnEXTEN |= EXT_A; - tok++; + tok.u32++; } - else if ((*tok >= KW_D0) && (*tok <= KW_D7)) + else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7)) { - AnEXTEN |= ((*tok & 7) << 12); + AnEXTEN |= ((*tok.u32 & 7) << 12); AnEXTEN |= EXT_D; - tok++; + tok.u32++; } // Check for size { // ([bd,An/PC],Xn.W/L...) - switch ((int)*tok) + switch ((int)*tok.u32) { // Index reg size: | .W | .L case DOTW: - tok++; + tok.u32++; break; default: break; case DOTL: - tok++; + tok.u32++; AnEXTEN |= EXT_L; break; case DOTB: @@ -747,11 +747,11 @@ IS_SUPPRESSEDn: } // Check for scale - if (*tok == '*') // ([bd,An/PC],Xn*...) + if (*tok.u32 == '*') // ([bd,An/PC],Xn*...) { // scale: *1, *2, *4, *8 - tok++; + tok.u32++; - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) return error("scale factor expression must evaluate"); @@ -772,11 +772,11 @@ IS_SUPPRESSEDn: goto badmode; } } - else if (*tok++ != CONST || *tok > 8) + else if (*tok.u32++ != CONST || *tok.u32 > 8) goto badmode; else { - switch ((int)*tok++) + switch ((int)*tok.u32++) { case 1: break; @@ -796,24 +796,24 @@ IS_SUPPRESSEDn: } //Check for ] - if (*tok != ']') + if (*tok.u32 != ']') return error("Expected closing bracket ]"); - tok++; // Eat the bracket + tok.u32++; // Eat the bracket //Check for od - if (*tok == ')') // ([bd,An/PC,Xn]... + if (*tok.u32 == ')') // ([bd,An/PC,Xn]... { //od is non existant, get out of jail free card //AnEXVAL=0; // zero outer displacement AMn = MEMPRE; // let's say it's ([bd,An,Xn],od) with od suppressed then AnEXTEN |= EXT_IISPREN; // No outer displacement - tok++; + tok.u32++; goto AnOK; } - else if (*tok++ != ',') + else if (*tok.u32++ != ',') return error("comma expected after ]"); - if (*tok == SYMBOL || *tok == CONST) + if (*tok.u32 == SYMBOL || *tok.u32 == CONST) { if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) goto badmode; @@ -823,17 +823,17 @@ IS_SUPPRESSEDn: // od=0 so optimise it out AMn = MEMPRE; // let's say it's ([bd,An],Xn,od) with od=0 then AnEXTEN |= EXT_IISPRE0; // No outer displacement - tok++; + tok.u32++; goto AnOK; } } // ([bd,An/PC,Xn],od) - if (*tok == DOTL) + if (*tok.u32 == DOTL) { // expr.L AMn = MEMPRE; - tok++; + tok.u32++; AnEXTEN |= EXT_IISPREL; } else @@ -861,9 +861,9 @@ IS_SUPPRESSEDn: AnEXTEN |= expr_size; // Assume we have a .w value // Is .W forced here? - if (*tok == DOTW) + if (*tok.u32 == DOTW) { - tok++; + tok.u32++; if (expr_size == EXT_IISPREL) return error("outer displacement value does not fit in .w size"); @@ -871,9 +871,9 @@ IS_SUPPRESSEDn: } // Check for final closing parenthesis - if (*tok == ')') + if (*tok.u32 == ')') { - tok++; + tok.u32++; goto AnOK; } else @@ -890,46 +890,46 @@ IS_SUPPRESSEDn: // It could be that this is really just an expression prefixing a // register as a displacement... - if (*tok == ')') + if (*tok.u32 == ')') { - tok++; + tok.u32++; goto CHK_FOR_DISPn; } // Otherwise, check for PC & etc displacements... - if (*tok++ != ',') + if (*tok.u32++ != ',') goto badmode; - if ((*tok >= KW_A0) && (*tok <= KW_A7)) + if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7)) { - AnREG = *tok & 7; - tok++; + AnREG = *tok.u32 & 7; + tok.u32++; - if (*tok == ',') + if (*tok.u32 == ',') { AMn = AINDEXED; goto AMn_IXN; } - else if (*tok == ')') + else if (*tok.u32 == ')') { AMn = ADISP; - tok++; + tok.u32++; goto AnOK; } else goto badmode; } - else if (*tok == KW_PC) + else if (*tok.u32 == KW_PC) { - if (*++tok == ',') + if (*++tok.u32 == ',') { // expr(PC,Xn...) AMn = PCINDEXED; goto AMn_IXN; } - else if (*tok == ')') + else if (*tok.u32 == ')') { AMn = PCDISP; // expr(PC) - tok++; + tok.u32++; goto AnOK; } else @@ -939,56 +939,56 @@ IS_SUPPRESSEDn: goto badmode; } } - else if (*tok == '-' && tok[1] == '(' && ((tok[2] >= KW_A0) && (tok[2] <= KW_A7)) && tok[3] == ')') + else if (*tok.u32 == '-' && tok.u32[1] == '(' && ((tok.u32[2] >= KW_A0) && (tok.u32[2] <= KW_A7)) && tok.u32[3] == ')') { AMn = APREDEC; - AnREG = tok[2] & 7; - tok += 4; + AnREG = tok.u32[2] & 7; + tok.u32 += 4; } - else if (*tok == KW_CCR) + else if (*tok.u32 == KW_CCR) { AMn = AM_CCR; - tok++; + tok.u32++; goto AnOK; } - else if (*tok == KW_SR) + else if (*tok.u32 == KW_SR) { AMn = AM_SR; - tok++; + tok.u32++; goto AnOK; } - else if (*tok == KW_USP) + else if (*tok.u32 == KW_USP) { AMn = AM_USP; - tok++; + tok.u32++; AnREG = 2; //Added this for the case of USP used in movec (see CREGlut in mach.c). Hopefully nothing gets broken! goto AnOK; } - else if ((*tok >= KW_IC40) && (*tok <= KW_BC40)) + else if ((*tok.u32 >= KW_IC40) && (*tok.u32 <= KW_BC40)) { AMn = CACHES; - AnREG = *tok++ - KW_IC40; + AnREG = *tok.u32++ - KW_IC40; // After a cache keyword only a comma or EOL is allowed - if ((*tok != ',') && (*tok != EOL)) + if ((*tok.u32 != ',') && (*tok.u32 != EOL)) return ERROR; goto AnOK; } - else if ((*tok >= KW_SFC) && (*tok <= KW_CRP)) + else if ((*tok.u32 >= KW_SFC) && (*tok.u32 <= KW_CRP)) { AMn = CREG; - AnREG = (*tok++) - KW_SFC; + AnREG = (*tok.u32++) - KW_SFC; goto AnOK; } - else if ((*tok >= KW_FP0) && (*tok <= KW_FP7)) + else if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7)) { AMn = FREG; - AnREG = (*tok++ & 7); + AnREG = (*tok.u32++ & 7); } - else if ((*tok >= KW_FPIAR) && (*tok <= KW_FPCR)) + else if ((*tok.u32 >= KW_FPIAR) && (*tok.u32 <= KW_FPCR)) { AMn = FPSCR; - AnREG = (1 << ((*tok++) - KW_FPIAR + 10)); + AnREG = (1 << ((*tok.u32++) - KW_FPIAR + 10)); } // expr // expr.w @@ -1003,10 +1003,10 @@ IS_SUPPRESSEDn: return ERROR; CHK_FOR_DISPn: - if (*tok == DOTW) + if (*tok.u32 == DOTW) { // expr.W - tok++; + tok.u32++; AMn = ABSW; if (((AnEXATTR & (TDB | DEFINED)) == DEFINED) && (AnEXVAL < 0x10000)) @@ -1014,7 +1014,7 @@ CHK_FOR_DISPn: goto AnOK; } - else if (*tok != '(') + else if (*tok.u32 != '(') { // expr[.L] AMn = ABSL; @@ -1032,37 +1032,37 @@ CHK_FOR_DISPn: } // Is .L forced here? - if (*tok == DOTL) + if (*tok.u32 == DOTL) { - tok++; + tok.u32++; AMn = ABSL; } goto AnOK; } - tok++; + tok.u32++; - if ((*tok >= KW_A0) && (*tok <= KW_A7)) + if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7)) { - AnREG = *tok++ & 7; + AnREG = *tok.u32++ & 7; - if (*tok == ')') + if (*tok.u32 == ')') { AMn = ADISP; - tok++; + tok.u32++; goto AnOK; } AMn = AINDEXED; goto AMn_IXN; } - else if (*tok == KW_PC) + else if (*tok.u32 == KW_PC) { - if (*++tok == ')') + if (*++tok.u32 == ')') { AMn = PCDISP; - tok++; + tok.u32++; goto AnOK; } diff --git a/procln.c b/procln.c index 37066c4..9b53926 100644 --- a/procln.c +++ b/procln.c @@ -176,18 +176,18 @@ DEBUG { printf("Assemble: Found TKEOF flag...\n"); } label = NULL; // No label lab_sym = NULL; // No (exported) label equate = NULL; // No equate - tk = tok; // Save first token in line + tk = tok.u32; // Save first token in line pcloc = (uint32_t)sloc; // Set beginning-of-line PC loop1: // Internal line processing loop - if (*tok == EOL) // Restart loop if end-of-line + if (*tok.u32 == EOL) // Restart loop if end-of-line goto loop; // First token MUST be a symbol (Shamus: not sure why :-/) - if (*tok != SYMBOL) + if (*tok.u32 != SYMBOL) { - if ((*tok >= KW_D0) && (*tok <= KW_R31)) + if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_R31)) error("cannot use reserved keyword as label name or .equ"); else error("syntax error; expected symbol"); @@ -195,13 +195,13 @@ loop1: // Internal line processing loop goto loop; } - j = (int)tok[2]; // Skip equates (normal statements) + j = (int)tok.u32[2]; // Skip equates (normal statements) if (j == '=' || j == DEQUALS || j == SET || j == REG || j == EQUREG || j == CCDEF) { - equate = string[tok[1]]; + equate = string[tok.u32[1]]; equtyp = j; - tok += 3; + tok.u32 += 3; goto normal; } @@ -209,14 +209,14 @@ loop1: // Internal line processing loop if (j == ':' || j == DCOLON) { as68label: - label = string[tok[1]]; // Get label name - labtyp = tok[2]; // Get label type - tok += 3; // Go to next line token + label = string[tok.u32[1]]; // Get label name + labtyp = tok.u32[2]; // Get label type + tok.u32 += 3; // Go to next line token // AS68 MODE: // Looks like another label follows the previous one, so handle // the previous one until there aren't any more - if (as68_flag && (*tok == SYMBOL && tok[2] == ':')) + if (as68_flag && (*tok.u32 == SYMBOL && tok.u32[2] == ':')) { if (HandleLabel(label, labtyp) != 0) goto loop; @@ -226,17 +226,17 @@ as68label: } // EOL is legal here... - if (*tok == EOL) + if (*tok.u32 == EOL) goto normal; // First token MUST be a symbol (if we get here, tok didn't advance) - if (*tok++ != SYMBOL) + if (*tok.u32++ != SYMBOL) { error("syntax error; expected symbol"); goto loop; } - opname = p = string[*tok++]; + opname = p = string[*tok.u32++]; // Check to see if the SYMBOL is a keyword (a mnemonic or directive). // On output, `state' will have one of the values: @@ -269,19 +269,18 @@ as68label: // Check for ".b" ".w" ".l" after directive, macro or mnemonic. siz = SIZN; - switch (*tok) + switch (*tok.u32) { - case DOTW: siz = SIZW, tok++; break; - case DOTL: siz = SIZL, tok++; break; - case DOTB: siz = SIZB, tok++; break; - case DOTD: siz = SIZD, tok++; break; - case DOTP: siz = SIZP, tok++; break; - case DOTQ: siz = SIZQ, tok++; break; - case DOTS: siz = SIZS, tok++; break; - case DOTX: siz = SIZX, tok++; break; + case DOTW: siz = SIZW, tok.u32++; break; + case DOTL: siz = SIZL, tok.u32++; break; + case DOTB: siz = SIZB, tok.u32++; break; + case DOTD: siz = SIZD, tok.u32++; break; + case DOTP: siz = SIZP, tok.u32++; break; + case DOTQ: siz = SIZQ, tok.u32++; break; + case DOTS: siz = SIZS, tok.u32++; break; + case DOTX: siz = SIZX, tok.u32++; break; } - // Do special directives (500..999) (These must be handled in "real time") if (state >= 500 && state < 1000) { @@ -309,7 +308,7 @@ as68label: goto loop; } - if (*tok++ != ',') + if (*tok.u32++ != ',') { error(comma_error); goto loop; @@ -441,11 +440,11 @@ When checking to see if it's already been equated, issue a warning. } // Check for register to equate to - if ((*tok >= KW_R0) && (*tok <= KW_R31)) + if ((*tok.u32 >= KW_R0) && (*tok.u32 <= KW_R31)) { // sy->sattre = EQUATEDREG | RISCSYM; // Mark as equated register sy->sattre = EQUATEDREG; // Mark as equated register - riscreg = (*tok - KW_R0); + riscreg = (*tok.u32 - KW_R0); //is there any reason to do this, since we're putting this in svalue? //i'm thinking, no. Let's test that out! :-D // sy->sattre |= (riscreg << 8); // Store register number @@ -461,15 +460,15 @@ When checking to see if it's already been equated, issue a warning. #endif // Check for "," override notation - if ((tok[1] == ',') && (tok[2] == CONST)) + if ((tok.u32[1] == ',') && (tok.u32[2] == CONST)) { // Advance token pointer to the constant - tok += 3; + tok.u32 += 3; // Anything other than a 0 or a 1 will result in "No Bank" - if (*(uint64_t *)tok == 0) + if (*(uint64_t *)tok.u32 == 0) registerbank = BANK_0; - else if (*(uint64_t *)tok == 1) + else if (*(uint64_t *)tok.u32 == 1) registerbank = BANK_1; } @@ -489,12 +488,12 @@ When checking to see if it's already been equated, issue a warning. // & what does this $80000080 constant mean??? // eval = 0x80000080 + (riscreg) + (registerbank << 8); eval = riscreg; - tok++; + tok.u32++; } // Checking for a register symbol - else if (tok[0] == SYMBOL) + else if (tok.u32[0] == SYMBOL) { - sy2 = lookup(string[tok[1]], LABEL, j); + sy2 = lookup(string[tok.u32[1]], LABEL, j); // Make sure symbol is a valid equreg if (!sy2 || !(sy2->sattre & EQUATEDREG)) @@ -507,7 +506,7 @@ When checking to see if it's already been equated, issue a warning. eattr = ABS | DEFINED | GLOBAL; // Copy symbols attributes sy->sattre = sy2->sattre; eval = (sy2->svalue & 0xFFFFF0FF); - tok += 2; + tok.u32 += 2; } } else @@ -529,9 +528,9 @@ When checking to see if it's already been equated, issue a warning. sy->sattre |= EQUATEDCC; eattr = ABS | DEFINED | GLOBAL; - if (tok[0] == SYMBOL) + if (tok.u32[0] == SYMBOL) { - sy2 = lookup(string[tok[1]], LABEL, j); + sy2 = lookup(string[tok.u32[1]], LABEL, j); if (!sy2 || !(sy2->sattre & EQUATEDCC)) { @@ -543,16 +542,16 @@ When checking to see if it's already been equated, issue a warning. eattr = ABS | DEFINED | GLOBAL; sy->sattre = sy2->sattre; eval = sy2->svalue; - tok += 2; + tok.u32 += 2; } } else if (expr(exprbuf, &eval, &eattr, &esym) != OK) goto loop; } //equ a equr - else if (*tok == SYMBOL) + else if (*tok.u32 == SYMBOL) { - sy2 = lookup(string[tok[1]], LABEL, j); + sy2 = lookup(string[tok.u32[1]], LABEL, j); if (sy2 && (sy2->sattre & EQUATEDREG)) { @@ -712,7 +711,7 @@ When checking to see if it's already been equated, issue a warning. if (amode(1) < 0) // Parse 0, 1 or 2 addr modes goto loop; - if (*tok != EOL) + if (*tok.u32 != EOL) error(extra_stuff); amsk0 = amsktab[am0]; diff --git a/riscasm.c b/riscasm.c index 533eca7..a76cb2e 100644 --- a/riscasm.c +++ b/riscasm.c @@ -180,7 +180,7 @@ int GetRegister(WORD rattr) TOKEN r_expr[EXPRSIZE]; // Expression token list // Evaluate what's in the global "tok" buffer - if (expr(r_expr, &eval, &eattr, &esym) != OK) + if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK) return ERROR; if ((challoc - ch_size) < 4) @@ -188,7 +188,7 @@ int GetRegister(WORD rattr) if (!(eattr & DEFINED)) { - AddFixup((WORD)(FU_WORD | rattr), sloc, r_expr); + AddFixup((WORD)(FU_WORD | rattr), sloc, (TOKENPTR)r_expr); return 0; } @@ -298,13 +298,13 @@ int GenerateRISCCode(int state) if (parm & SUB32) attrflg |= FU_SUB32; - if (*tok != '#') + if (*tok.u32 != '#') return MalformedOpcode(0x01); - tok++; + tok.u32++; riscImmTokenSeen = 1; - if (expr(r_expr, &eval, &eattr, &esym) != OK) + if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK) return MalformedOpcode(0x02); if ((challoc - ch_size) < 4) @@ -312,7 +312,7 @@ int GenerateRISCCode(int state) if (!(eattr & DEFINED)) { - AddFixup((WORD)(FU_WORD | attrflg), sloc, r_expr); + AddFixup((WORD)(FU_WORD | attrflg), sloc, (TOKENPTR)r_expr); reg1 = 0; } else @@ -336,22 +336,22 @@ int GenerateRISCCode(int state) // Move Immediate--n,Rn--n in Second Word case RI_MOVEI: - if (*tok != '#') + if (*tok.u32 != '#') return MalformedOpcode(0x03); - tok++; + tok.u32++; riscImmTokenSeen = 1; // Check for equated register after # and return error if so - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { - sy = lookup(string[tok[1]], LABEL, 0); + sy = lookup(string[tok.u32[1]], LABEL, 0); if (sy && (sy->sattre & EQUATEDREG)) return error("equated register in 1st operand of MOVEI instruction"); } - if (expr(r_expr, &eval, &eattr, &esym) != OK) + if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK) return MalformedOpcode(0x04); if (lastOpcode == RI_JUMP || lastOpcode == RI_JR) @@ -371,7 +371,7 @@ int GenerateRISCCode(int state) if (!(eattr & DEFINED)) { - AddFixup(FU_LONG | FU_MOVEI, sloc + 2, r_expr); + AddFixup(FU_LONG | FU_MOVEI, sloc + 2, (TOKENPTR)r_expr); eval = 0; } else @@ -394,11 +394,11 @@ int GenerateRISCCode(int state) // PC,Rd or Rs,Rd case RI_MOVE: - if (*tok == KW_PC) + if (*tok.u32 == KW_PC) { parm = 51; reg1 = 0; - tok++; + tok.u32++; } else { @@ -417,24 +417,24 @@ int GenerateRISCCode(int state) indexed = 0; parm = 41; - if (*tok != '(') + if (*tok.u32 != '(') return MalformedOpcode(0x05); - tok++; + tok.u32++; - if ((*(tok + 1) == '+') || (*(tok + 1) == '-')) { + if ((*(tok.u32 + 1) == '+') || (*(tok.u32 + 1) == '-')) { // Trying to make indexed call - if ((*tok == KW_R14 || *tok == KW_R15)) { - indexed = (*tok - KW_R0); + if ((*tok.u32 == KW_R14 || *tok.u32 == KW_R15)) { + indexed = (*tok.u32 - KW_R0); } else { - return IllegalIndexedRegister(*tok); + return IllegalIndexedRegister(*tok.u32); } } - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { -// sy = lookup((char *)tok[1], LABEL, 0); - sy = lookup(string[tok[1]], LABEL, 0); +// sy = lookup((char *)tok.u32[1], LABEL, 0); + sy = lookup(string[tok.u32[1]], LABEL, 0); if (!sy) { @@ -444,10 +444,10 @@ int GenerateRISCCode(int state) if (sy->sattre & EQUATEDREG) { - if ((*(tok + 2) == '+') || (*(tok + 2) == '-')) { + if ((*(tok.u32 + 2) == '+') || (*(tok.u32 + 2) == '-')) { if ((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15) { indexed = (sy->svalue & 0x1F); - tok++; + tok.u32++; } else { return IllegalIndexedRegisterEqur(sy); } @@ -463,20 +463,20 @@ int GenerateRISCCode(int state) { reg1 = indexed; indexed = 0; - tok++; + tok.u32++; - if (*tok == '+') + if (*tok.u32 == '+') { parm = (WORD)(reg1 - 14 + 58); - tok++; + tok.u32++; - if (*tok >= KW_R0 && *tok <= KW_R31) + if (*tok.u32 >= KW_R0 && *tok.u32 <= KW_R31) indexed = 1; - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { -// sy = lookup((char *)tok[1], LABEL, 0); - sy = lookup(string[tok[1]], LABEL, 0); +// sy = lookup((char *)tok.u32[1], LABEL, 0); + sy = lookup(string[tok.u32[1]], LABEL, 0); if (!sy) { @@ -494,7 +494,7 @@ int GenerateRISCCode(int state) } else { - if (expr(r_expr, &eval, &eattr, &esym) != OK) + if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK) return MalformedOpcode(0x06); if ((challoc - ch_size) < 4) @@ -529,10 +529,10 @@ int GenerateRISCCode(int state) } } - if (*tok != ')') + if (*tok.u32 != ')') return MalformedOpcode(0x07); - tok++; + tok.u32++; CHECK_COMMA; reg2 = GetRegister(FU_REGTWO); at_eol(); @@ -545,18 +545,18 @@ int GenerateRISCCode(int state) reg1 = GetRegister(FU_REGONE); CHECK_COMMA; - if (*tok != '(') + if (*tok.u32 != '(') return MalformedOpcode(0x08); - tok++; + tok.u32++; indexed = 0; - if ((*tok == KW_R14 || *tok == KW_R15) && (*(tok + 1) != ')')) - indexed = (*tok - KW_R0); + if ((*tok.u32 == KW_R14 || *tok.u32 == KW_R15) && (*(tok.u32 + 1) != ')')) + indexed = (*tok.u32 - KW_R0); - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { - sy = lookup(string[tok[1]], LABEL, 0); + sy = lookup(string[tok.u32[1]], LABEL, 0); if (!sy) { @@ -567,10 +567,10 @@ int GenerateRISCCode(int state) if (sy->sattre & EQUATEDREG) { if (((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15) - && (*(tok + 2) != ')')) + && (*(tok.u32 + 2) != ')')) { indexed = (sy->svalue & 0x1F); - tok++; + tok.u32++; } } } @@ -583,19 +583,19 @@ int GenerateRISCCode(int state) { reg2 = indexed; indexed = 0; - tok++; + tok.u32++; - if (*tok == '+') + if (*tok.u32 == '+') { parm = (WORD)(reg2 - 14 + 60); - tok++; + tok.u32++; - if (*tok >= KW_R0 && *tok <= KW_R31) + if (*tok.u32 >= KW_R0 && *tok.u32 <= KW_R31) indexed = 1; - if (*tok == SYMBOL) + if (*tok.u32 == SYMBOL) { - sy = lookup(string[tok[1]], LABEL, 0); + sy = lookup(string[tok.u32[1]], LABEL, 0); if (!sy) { @@ -613,7 +613,7 @@ int GenerateRISCCode(int state) } else { - if (expr(r_expr, &eval, &eattr, &esym) != OK) + if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK) return MalformedOpcode(0x09); if ((challoc - ch_size) < 4) @@ -621,7 +621,7 @@ int GenerateRISCCode(int state) if (!(eattr & DEFINED)) { - AddFixup(FU_WORD | FU_REGTWO, sloc, r_expr); + AddFixup(FU_WORD | FU_REGTWO, sloc, (TOKENPTR)r_expr); reg2 = 0; } else @@ -653,26 +653,26 @@ int GenerateRISCCode(int state) } } - if (*tok != ')') + if (*tok.u32 != ')') return MalformedOpcode(0x0A); - tok++; + tok.u32++; at_eol(); BuildRISCIntructionWord(parm, reg2, reg1); break; // LOADB/LOADP/LOADW (Rn),Rn case RI_LOADN: - if (*tok != '(') + if (*tok.u32 != '(') return MalformedOpcode(0x0B); - tok++; + tok.u32++; reg1 = GetRegister(FU_REGONE); - if (*tok != ')') + if (*tok.u32 != ')') return MalformedOpcode(0x0C); - tok++; + tok.u32++; CHECK_COMMA; reg2 = GetRegister(FU_REGTWO); at_eol(); @@ -684,16 +684,16 @@ int GenerateRISCCode(int state) reg1 = GetRegister(FU_REGONE); CHECK_COMMA; - if (*tok != '(') + if (*tok.u32 != '(') return MalformedOpcode(0x0D); - tok++; + tok.u32++; reg2 = GetRegister(FU_REGTWO); - if (*tok != ')') + if (*tok.u32 != ')') return MalformedOpcode(0x0E); - tok++; + tok.u32++; at_eol(); BuildRISCIntructionWord(parm, reg2, reg1); break; @@ -707,7 +707,7 @@ int GenerateRISCCode(int state) // the JR or JUMP should default to 0, Jump Always commaFound = 0; - for(t=tok; *t!=EOL; t++) + for(t=tok.u32; *t!=EOL; t++) { if (*t == ',') { @@ -718,20 +718,20 @@ int GenerateRISCCode(int state) if (commaFound) { - if (*tok == CONST) + if (*tok.u32 == CONST) { // CC using a constant number - tok++; - uint64_t *tok64 = (uint64_t *)tok; + tok.u32++; + uint64_t *tok64 = (uint64_t *)tok.u32; val = (int)*tok64++; - tok = (uint32_t *)tok64; + tok.u32 = (uint32_t *)tok64; CHECK_COMMA; } - else if (*tok == SYMBOL) + else if (*tok.u32 == SYMBOL) { val = 99; -// strcpy(scratch, (char *)tok[1]); - strcpy(scratch, string[tok[1]]); +// strcpy(scratch, (char *)tok.u32[1]); + strcpy(scratch, string[tok.u32[1]]); strtoupper(scratch); for(i=0; isattre & EQUATEDCC) && !(ccsym->sattre & UNDEF_CC)) val = ccsym->svalue; @@ -756,10 +756,10 @@ int GenerateRISCCode(int state) return error("unknown condition code"); } - tok += 2; + tok.u32 += 2; CHECK_COMMA; } - else if (*tok == '(') + else if (*tok.u32 == '(') { // Set CC to "Jump Always" val = 0; @@ -780,7 +780,7 @@ int GenerateRISCCode(int state) if (type == RI_JR) { // JR cc,n - if (expr(r_expr, &eval, &eattr, &esym) != OK) + if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK) return MalformedOpcode(0x0F); if ((challoc - ch_size) < 4) @@ -788,7 +788,7 @@ int GenerateRISCCode(int state) if (!(eattr & DEFINED)) { - AddFixup(FU_WORD | FU_JR, sloc, r_expr); + AddFixup(FU_WORD | FU_JR, sloc, (TOKENPTR)r_expr); reg2 = 0; } else @@ -804,16 +804,16 @@ int GenerateRISCCode(int state) else { // JUMP cc, (Rn) - if (*tok != '(') + if (*tok.u32 != '(') return MalformedOpcode(0x10); - tok++; + tok.u32++; reg2 = GetRegister(FU_REGTWO); - if (*tok != ')') + if (*tok.u32 != ')') return MalformedOpcode(0x11); - tok++; + tok.u32++; at_eol(); BuildRISCIntructionWord(parm, reg2, reg1); } diff --git a/riscasm.h b/riscasm.h index 834cf85..5b5c63b 100644 --- a/riscasm.h +++ b/riscasm.h @@ -34,7 +34,7 @@ #define GPUONLY 0x4000 // Opcode is for the GPU Only #define DSPONLY 0x8000 // Opcode is for the DSP Only -#define CHECK_COMMA if(*tok++ != ',') { error(comma_error); return(ERROR); } +#define CHECK_COMMA if(*tok.u32++ != ',') { error(comma_error); return(ERROR); } // Opcode Specific Data struct opcoderecord { diff --git a/rmac.h b/rmac.h index 0f92d79..bba14d7 100644 --- a/rmac.h +++ b/rmac.h @@ -154,7 +154,6 @@ #define SPACE ' ' // ASCII space #define SLASHCHAR '/' #define SLASHSTRING "/" -#define TOKEN uint32_t // Assembler token #define FNSIZ 128 // Maximum size of a filename #define OK 0 // OK return #define DEBUG if (debug) // Debug conditional @@ -166,7 +165,7 @@ // Object code formats enum { -ALCYON, // Alcyon/DRI C object format +ALCYON, // Alcyon/DRI C object format MWC, // Mark Williams object format BSD, // BSD object format ELF, // ELF object format @@ -175,16 +174,27 @@ P56, // DSP 56001 object format XEX, // COM/EXE/XEX/whatever a8 object format }; +// Assembler token +#define TOKEN uint32_t + +// Token pointer type is a union because we have 64-bit sized tokens now :-P +#define TOKENPTR union _tokenptr +TOKENPTR +{ + uint32_t * u32; + uint64_t * u64; +}; + // Pointer type that can point to (almost) anything #define PTR union _ptr PTR { - uint8_t * cp; // Char + uint8_t * cp; // Char uint16_t * wp; // WORD uint32_t * lp; // LONG - uint32_t lw; // LONG - SYM ** sy; // SYM - TOKEN * tk; // TOKEN + uint32_t lw; // LONG + SYM ** sy; // SYM + TOKENPTR tk; // TOKEN }; // Symbol spaces @@ -215,11 +225,11 @@ PTR #define SIZW 0x0002 // .w #define SIZL 0x0004 // .l #define SIZN 0x0008 // no .(size) specifier -#define SIZD 0x0010 // .d (quad word or FPU double precision real) +#define SIZD 0x0010 // .d (FPU double precision real) #define SIZS 0x0020 // .s (FPU single precision real) #define SIZX 0x0040 // .x (FPU extended precision real) #define SIZP 0x0080 // .p (FPU pakced decimal real) -#define SIZQ 0x0100 // .q +#define SIZQ 0x0100 // .q (quad word) // RISC register bank definitions (used in extended symbol attributes also) #define BANK_N 0x0000 // No register bank specified diff --git a/sect.c b/sect.c index 3e12765..3b2ed99 100644 --- a/sect.c +++ b/sect.c @@ -282,7 +282,7 @@ int chcheck(uint32_t amt) // // Arrange for a fixup on a location // -int AddFixup(uint16_t attr, uint32_t loc, TOKEN * fexpr) +int AddFixup(uint16_t attr, uint32_t loc, TOKENPTR fexpr) { uint32_t i = MIN_FIXUP_MEM; uint16_t len = 0; @@ -291,7 +291,7 @@ int AddFixup(uint16_t attr, uint32_t loc, TOKEN * fexpr) // Compute length of expression (could be faster); determine if it's the // single-symbol case; no expression if it's just a mark. (? is this true?) - if ((*fexpr == SYMBOL) && (fexpr[2] == ENDEXPR)) + if ((*fexpr.u32 == SYMBOL) && (fexpr.u32[2] == ENDEXPR)) { // Just a single symbol, possibly followed by a DWORD i += sizeof(SYM *); @@ -306,12 +306,12 @@ int AddFixup(uint16_t attr, uint32_t loc, TOKEN * fexpr) attr |= FU_EXPR; // Count the # of tokens in the expression - for(len=0; fexpr[len]!=ENDEXPR; len++) + for(len=0; fexpr.u32[len]!=ENDEXPR; len++) { // Add one to len for 2X tokens, two for 3X tokens - if (fexpr[len] == SYMBOL) + if (fexpr.u32[len] == SYMBOL) len++; - else if (fexpr[len] == CONST) + else if (fexpr.u32[len] == CONST) len += 2; } @@ -362,11 +362,11 @@ int AddFixup(uint16_t attr, uint32_t loc, TOKEN * fexpr) *fchptr.wp++ = len; while (len--) - *fchptr.lp++ = *fexpr++; + *fchptr.lp++ = *fexpr.u32++; } else { - *fchptr.sy++ = symbolPtr[fexpr[1]]; + *fchptr.sy++ = symbolPtr[fexpr.u32[1]]; // SCPCD: Correct bit mask for attr (else other FU_xxx will match) // NYAN ! @@ -464,7 +464,7 @@ int ResolveFixups(int sno) { i = *fup.wp++; - if (evexpr(fup.tk, &eval, &eattr, &esym) != OK) + if (evexpr((TOKENPTR)fup.tk, &eval, &eattr, &esym) != OK) { fup.lp += i; continue; diff --git a/sect.h b/sect.h index f2aee8d..4cd5db4 100644 --- a/sect.h +++ b/sect.h @@ -23,6 +23,15 @@ *chptr++=(uint8_t)((lw)>>8); \ *chptr++=(uint8_t)(lw); \ sloc += 4; ch_size += 4; if(orgactive) orgaddr += 4;} +#define D_quad(qw) {*chptr++=(uint8_t)((qw)>>56); \ + *chptr++=(uint8_t)((qw)>>48);\ + *chptr++=(uint8_t)((qw)>>40);\ + *chptr++=(uint8_t)((qw)>>32);\ + *chptr++=(uint8_t)((qw)>>24);\ + *chptr++=(uint8_t)((qw)>>16);\ + *chptr++=(uint8_t)((qw)>>8); \ + *chptr++=(uint8_t)(qw); \ + sloc += 8; ch_size += 8; if(orgactive) orgaddr += 8;} #define D_rword(w) {*chptr++=(uint8_t)(w); *chptr++=(uint8_t)((w)>>8); \ sloc+=2; ch_size+=2;if(orgactive) orgaddr += 2;} #define D_single(w) {chcheck(4);*chptr++ = ((char *)&w)[3]; \ @@ -204,7 +213,7 @@ void SwitchSection(int); void SaveSection(void); int fixtest(int, uint32_t); int chcheck(uint32_t); -int AddFixup(uint16_t, uint32_t, TOKEN *); +int AddFixup(uint16_t, uint32_t, TOKENPTR); int ResolveAllFixups(void); #endif // __SECT_H__ diff --git a/token.c b/token.c index f719dc3..2e6c456 100644 --- a/token.c +++ b/token.c @@ -32,10 +32,10 @@ char irbuf[LNSIZ]; // Text for .rept block line char lnbuf[LNSIZ]; // Text of current line WORD filecount; // Unique file number counter WORD cfileno; // Current file number -TOKEN * tok; // Ptr to current token +TOKENPTR 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 +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 @@ -206,13 +206,13 @@ void InitTokenizer(void) dotxtab['W'] = DOTW; dotxtab['l'] = DOTL; // .l .L dotxtab['L'] = DOTL; - dotxtab['i'] = DOTI; // .i .I (???) + dotxtab['i'] = DOTI; // .i .I (WTF is this???) dotxtab['I'] = DOTI; - dotxtab['D'] = DOTD; // .d .D (quad word) + dotxtab['D'] = DOTD; // .d .D (double) dotxtab['d'] = DOTD; dotxtab['S'] = DOTS; // .s .S dotxtab['s'] = DOTS; - dotxtab['Q'] = DOTQ; // .q .Q + dotxtab['Q'] = DOTQ; // .q .Q (quad word) dotxtab['q'] = DOTQ; dotxtab['X'] = DOTX; // .x .x dotxtab['x'] = DOTX; @@ -305,7 +305,7 @@ INOBJ * a_inobj(int typ) // Install INOBJ on top of input stack inobj->in_ifent = ifent; // Record .if context on entry inobj->in_type = (WORD)typ; - inobj->in_otok = tok; + inobj->in_otok = tok.u32; inobj->in_etok = etok; inobj->in_link = cur_inobj; cur_inobj = inobj; @@ -390,7 +390,7 @@ int ExpandMacro(char * src, char * dest, int destsiz) *dst++ = *s++; continue; case '?': // \? set `questmark' flag - ++s; + s++; questmark = 1; break; case '#': // \#, number of arguments @@ -791,7 +791,7 @@ int fpop(void) if (numUnmatched > 0) warn("missing %d .endif(s)", numUnmatched); - tok = inobj->in_otok; // Restore tok and otok + tok.u32 = inobj->in_otok; // Restore tok and otok etok = inobj->in_etok; switch (inobj->in_type) @@ -946,7 +946,7 @@ int TokenizeLine(void) { uint8_t * ln = NULL; // Ptr to current position in line uint8_t * p; // Random character ptr - TOKEN * tk; // Token-deposit ptr + TOKENPTR tk; // Token-deposit ptr int state = 0; // State for keyword detector int j = 0; // Var for keyword detector uint8_t c; // Random char @@ -957,11 +957,10 @@ int TokenizeLine(void) int stuffnull; // 1:terminate SYMBOL '\0' at *nullspot uint8_t c1; int stringNum = 0; // Pointer to string locations in tokenized line - uint64_t * tk64; retry: - if (cur_inobj == NULL) // Return EOF if input stack is empty + if (cur_inobj == NULL) // Return EOF if input stack is empty return TKEOF; // Get another line of input from the current input source: a file, a @@ -1048,8 +1047,8 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } strcpy(lnbuf, ln); // General housekeeping - tok = tokeol; // Set "tok" to EOL in case of error - tk = etok; // Reset token ptr + tok.u32 = tokeol; // Set "tok" to EOL in case of error + tk.u32 = etok; // Reset token ptr stuffnull = 0; // Don't stuff nulls totlines++; // Bump total #lines assembled @@ -1112,7 +1111,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } // token stream: ln++; stuffnull = 0; - *tk++ = (TOKEN)dotxtab[*ln++]; + *tk.u32++ = (TOKEN)dotxtab[*ln++]; continue; } } @@ -1130,7 +1129,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } *ln++ = EOS; // Terminate symbol stuffnull = 0; // And never try it again - // Character following the `.' must have a DOT attribute, and + // Character following the '.' must have a DOT attribute, and // the chararacter after THAT one must not have a start-symbol // attribute (to prevent symbols that look like, for example, // "zingo.barf", which might be a good idea anyway....) @@ -1195,7 +1194,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } // If not tokenized keyword OR token was not found if ((j < 0) || (state < 0)) { - *tk++ = SYMBOL; + *tk.u32++ = SYMBOL; //#warning //problem here: nullspot is a char * but TOKEN is a uint32_t. On a 64-bit //system, this will cause all kinds of mischief. @@ -1203,18 +1202,18 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } *tk++ = (TOKEN)nullspot; #else string[stringNum] = nullspot; - *tk++ = stringNum; + *tk.u32++ = stringNum; stringNum++; #endif } else { - *tk++ = (TOKEN)j; + *tk.u32++ = (TOKEN)j; stuffnull = 0; } if (v) // Record attribute token (if any) - *tk++ = (TOKEN)v; + *tk.u32++ = (TOKEN)v; if (stuffnull) // Arrange for string termination on next pass nullspot = ln; @@ -1225,7 +1224,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } // Handle identity tokens if (c & SELF) { - *tk++ = *ln++; + *tk.u32++ = *ln++; continue; } @@ -1237,27 +1236,27 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } case '!': // ! or != if (*ln == '=') { - *tk++ = NE; - ++ln; + *tk.u32++ = NE; + ln++; } else - *tk++ = '!'; + *tk.u32++ = '!'; continue; case '\'': // 'string' if (m6502) { // Hardcoded for now, maybe this will change in the future - *tk++ = STRINGA8; + *tk.u32++ = STRINGA8; goto dostring; } // Fall through case '\"': // "string" - *tk++ = STRING; + *tk.u32++ = STRING; dostring: c1 = ln[-1]; string[stringNum] = ln; - *tk++ = stringNum; + *tk.u32++ = stringNum; stringNum++; for(p=ln; *ln!=EOS && *ln!=c1;) @@ -1320,19 +1319,6 @@ dostring: case '$': // $, hex constant if (chrtab[*ln] & HDIGIT) { - if (cursize == 'q' || cursize == 'Q') - { - // Parse 64-bit integer - uint64_t v64 = 0; - - while (hextab[*ln] >= 0) - v64 = (v64 << 4) + (int)hextab[*ln++]; - - *(uint64_t *)tk = v64; - tk = tk + 2; - - continue; - } v = 0; // Parse the hex value @@ -1361,10 +1347,8 @@ dostring: } } - *tk++ = CONST; - tk64 = (uint64_t *)tk; - *tk64++ = v; - tk = (TOKEN *)tk64; + *tk.u32++ = CONST; + *tk.u64++ = v; if (obj_format == ALCYON) { @@ -1372,79 +1356,79 @@ dostring: { if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W')) { - *tk++ = DOTW; + *tk.u32++ = DOTW; ln += 2; } else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) { - *tk++ = DOTL; + *tk.u32++ = DOTL; ln += 2; } } } } else - *tk++ = '$'; + *tk.u32++ = '$'; continue; case '<': // < or << or <> or <= switch (*ln) { case '<': - *tk++ = SHL; - ++ln; + *tk.u32++ = SHL; + ln++; continue; case '>': - *tk++ = NE; - ++ln; + *tk.u32++ = NE; + ln++; continue; case '=': - *tk++ = LE; - ++ln; + *tk.u32++ = LE; + ln++; continue; default: - *tk++ = '<'; + *tk.u32++ = '<'; continue; } case ':': // : or :: if (*ln == ':') { - *tk++ = DCOLON; - ++ln; + *tk.u32++ = DCOLON; + ln++; } else - *tk++ = ':'; + *tk.u32++ = ':'; continue; case '=': // = or == if (*ln == '=') { - *tk++ = DEQUALS; - ++ln; + *tk.u32++ = DEQUALS; + ln++; } else - *tk++ = '='; + *tk.u32++ = '='; continue; case '>': // > or >> or >= switch (*ln) { case '>': - *tk++ = SHR; + *tk.u32++ = SHR; ln++; continue; case '=': - *tk++ = GE; + *tk.u32++ = GE; ln++; continue; default: - *tk++ = '>'; + *tk.u32++ = '>'; continue; } case '%': // % or binary constant if (*ln < '0' || *ln > '1') { - *tk++ = '%'; + *tk.u32++ = '%'; continue; } @@ -1474,15 +1458,13 @@ dostring: } } - *tk++ = CONST; - tk64 = (uint64_t *)tk; - *tk64++ = v; - tk = (TOKEN *)tk64; + *tk.u32++ = CONST; + *tk.u64++ = v; continue; case '@': // @ or octal constant if (*ln < '0' || *ln > '7') { - *tk++ = '@'; + *tk.u32++ = '@'; continue; } @@ -1493,34 +1475,32 @@ dostring: if (*ln == '.') { - if ((*(ln+1) == 'b') || (*(ln+1) == 'B')) + if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B')) { v &= 0x000000FF; ln += 2; } - if ((*(ln+1) == 'w') || (*(ln+1) == 'W')) + if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W')) { v &= 0x0000FFFF; ln += 2; } - if ((*(ln+1) == 'l') || (*(ln+1) == 'L')) + if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) { v &= 0xFFFFFFFF; ln += 2; } } - *tk++ = CONST; - tk64 = (uint64_t *)tk; - *tk64++ = v; - tk = (TOKEN *)tk64; + *tk.u32++ = CONST; + *tk.u64++ = v; continue; case '^': // ^ or ^^ if (*ln != '^') { - *tk++ = '^'; + *tk.u32++ = '^'; continue; } @@ -1566,7 +1546,7 @@ dostring: continue; } - *tk++ = (TOKEN)j; + *tk.u32++ = (TOKEN)j; continue; default: interror(2); // Bad MULTX entry in chrtab @@ -1577,6 +1557,7 @@ dostring: // Handle decimal constant if (c & DIGIT) { + uint8_t * numStart = ln; v = 0; while ((int)chrtab[*ln] & DIGIT) @@ -1589,38 +1570,31 @@ dostring: { v &= 0x000000FF; ln += 2; - *tk++ = CONST; - tk64 = (uint64_t *)tk; - *tk64++ = v; - tk = (uint32_t *)tk64; - *tk++ = DOTB; + *tk.u32++ = CONST; + *tk.u64++ = v; + *tk.u32++ = DOTB; } else if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W')) { v &= 0x0000FFFF; ln += 2; - *tk++ = CONST; - tk64 = (uint64_t *)tk; - *tk64++ = v; - tk = (uint32_t *)tk64; - - *tk++ = DOTW; + *tk.u32++ = CONST; + *tk.u64++ = v; + *tk.u32++ = DOTW; } else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) { v &= 0xFFFFFFFF; ln += 2; - *tk++ = CONST; - tk64 = (uint64_t *)tk; - *tk64++ = v; - tk = (uint32_t *)tk64; - - *tk++ = DOTL; + *tk.u32++ = CONST; + *tk.u64++ = v; + *tk.u32++ = DOTL; } else if ((int)chrtab[*(ln + 1)] & DIGIT) { - // Hey, more digits after the dot, so assume it's a - // fractional number + // Hey, more digits after the dot, so we assume it's a + // floating point number of some kind +#if 0 double fract = 10; ln++; f = (double)v; @@ -1630,19 +1604,28 @@ dostring: f = f + (double)(*ln++ - '0') / fract; fract *= 10; } +#else + // Here we parse the whole floating point number +#include + char * numEnd; + errno = 0; + double f = strtod(numStart, &numEnd); + ln = (uint8_t *)numEnd; + + if (errno != 0) + return error("floating point parse error"); +#endif - *tk++ = FCONST; - *((double *)tk) = f; - tk += 2; + *tk.u32++ = FCONST; +// Shamus: Well, this is all kinds of icky--not the least of which is that unlike uintNN_t types, we have no guarantees of any kind when it comes to the size of floating point numbers in C (as far as I know of). If there is, we need to use those kinds here, or else figure out at runtime what sizes we're dealing with and act accordingly. To be fair, this is OK as long as the double type is less than 64 bits wide, but again, there's no guarantee that it isn't. :-/ + *tk.u64++ = f; continue; } } else { - *tk++ = CONST; - tk64 = (uint64_t *)tk; - *tk64++ = v; - tk = (TOKEN *)tk64; + *tk.u32++ = CONST; + *tk.u64++ = v; } //printf("CONST: %i\n", v); @@ -1656,12 +1639,12 @@ dostring: // Terminate line of tokens and return "success." goteol: - tok = etok; // Set tok to beginning of line + tok.u32 = etok; // Set tok to beginning of line if (stuffnull) // Terminate last SYMBOL *nullspot = EOS; - *tk++ = EOL; + *tk.u32++ = EOL; return OK; } @@ -1685,11 +1668,11 @@ goteol: int d_goto(WORD unused) { // Setup for the search - if (*tok != SYMBOL) + if (*tok.u32 != SYMBOL) return error("missing label"); - char * sym = string[tok[1]]; - tok += 2; + char * sym = string[tok.u32[1]]; + tok.u32 += 2; if (cur_inobj->in_type != SRC_IMACRO) return error("goto not in macro"); @@ -1732,6 +1715,85 @@ int d_goto(WORD unused) } +void DumpToken(TOKEN t) +{ + if (t == COLON) + printf("[COLON]"); + else if (t == CONST) + printf("[CONST]"); + else if (t == ACONST) + printf("[ACONST]"); + else if (t == STRING) + printf("[STRING]"); + else if (t == SYMBOL) + printf("[SYMBOL]"); + else if (t == EOS) + printf("[EOS]"); + else if (t == TKEOF) + printf("[TKEOF]"); + else if (t == DEQUALS) + printf("[DEQUALS]"); + else if (t == SET) + printf("[SET]"); + else if (t == REG) + printf("[REG]"); + else if (t == DCOLON) + printf("[DCOLON]"); + else if (t == GE) + printf("[GE]"); + else if (t == LE) + printf("[LE]"); + else if (t == NE) + printf("[NE]"); + else if (t == SHR) + printf("[SHR]"); + else if (t == SHL) + printf("[SHL]"); + else if (t == UNMINUS) + printf("[UNMINUS]"); + else if (t == DOTB) + printf("[DOTB]"); + else if (t == DOTW) + printf("[DOTW]"); + else if (t == DOTL) + printf("[DOTL]"); + else if (t == DOTQ) + printf("[DOTQ]"); + else if (t == DOTS) + printf("[DOTS]"); + else if (t == DOTD) + printf("[DOTD]"); + else if (t == DOTI) + printf("[DOTI]"); + else if (t == ENDEXPR) + printf("[ENDEXPR]"); + else if (t == CR_ABSCOUNT) + printf("[CR_ABSCOUNT]"); + else if (t == CR_DEFINED) + printf("[CR_DEFINED]"); + else if (t == CR_REFERENCED) + printf("[CR_REFERENCED]"); + else if (t == CR_STREQ) + printf("[CR_STREQ]"); + else if (t == CR_MACDEF) + printf("[CR_MACDEF]"); + else if (t == CR_TIME) + printf("[CR_TIME]"); + else if (t == CR_DATE) + printf("[CR_DATE]"); + else if (t >= 0x20 && t <= 0x2F) + printf("[%c]", (char)t); + else if (t >= 0x3A && t <= 0x3F) + printf("[%c]", (char)t); + else if (t >= 0x80 && t <= 0x87) + printf("[D%u]", ((uint32_t)t) - 0x80); + else if (t >= 0x88 && t <= 0x8F) + printf("[A%u]", ((uint32_t)t) - 0x88); + else + printf("[%X:%c]", (uint32_t)t, (char)t); +} + + void DumpTokenBuffer(void) { printf("Tokens [%X]: ", sloc); @@ -1742,7 +1804,8 @@ void DumpTokenBuffer(void) printf("[COLON]"); else if (*t == CONST) { - printf("[CONST: $%lX]", ((uint64_t)t[1] << 32) | (uint64_t)t[2]); + TOKENPTR tp = (TOKENPTR)(t + 1); + printf("[CONST: $%lX]", (uint64_t)(*tp.u64)); t += 2; } else if (*t == ACONST) @@ -1790,6 +1853,12 @@ void DumpTokenBuffer(void) printf("[DOTW]"); else if (*t == DOTL) printf("[DOTL]"); + else if (*t == DOTQ) + printf("[DOTQ]"); + else if (*t == DOTS) + printf("[DOTS]"); + else if (*t == DOTD) + printf("[DOTD]"); else if (*t == DOTI) printf("[DOTI]"); else if (*t == ENDEXPR) diff --git a/token.h b/token.h index cedaa03..3867f7e 100644 --- a/token.h +++ b/token.h @@ -153,7 +153,7 @@ extern int lnsave; extern uint16_t curlineno; extern char * curfname; extern WORD cfileno; -extern TOKEN * tok; +extern TOKENPTR tok; extern char lnbuf[]; extern char lntag; extern char tolowertab[]; @@ -170,6 +170,7 @@ int TokenizeLine(void); int fpop(void); int d_goto(WORD); INOBJ * a_inobj(int); +void DumpToken(TOKEN); void DumpTokenBuffer(void); #endif // __TOKEN_H__ diff --git a/version.h b/version.h index 9193d3d..5859366 100644 --- a/version.h +++ b/version.h @@ -14,8 +14,8 @@ // Release Information #define MAJOR 1 // Major version number -#define MINOR 9 // Minor version number -#define PATCH 1 // Patch release number +#define MINOR 10 // Minor version number +#define PATCH 0 // Patch release number #endif // __VERSION_H__