int a0ixreg; // Index register
int a0ixsiz; // Index register size (and scale)
TOKEN a0oexpr[EXPRSIZE]; // Outer displacement expression
-uint32_t a0oexval; // Outer displacement value
+uint64_t a0oexval; // Outer displacement value
WORD a0oexattr; // Outer displacement attribute
SYM * a0esym; // External symbol involved in expr
TOKEN a0bexpr[EXPRSIZE]; // Base displacement expression
int a1ixreg; // Index register
int a1ixsiz; // Index register size (and scale)
TOKEN a1oexpr[EXPRSIZE]; // Outer displacement expression
-uint32_t a1oexval; // Outer displacement value
+uint64_t a1oexval; // Outer displacement value
WORD a1oexattr; // Outer displacement attribute
SYM * a1esym; // External symbol involved in expr
TOKEN a1bexpr[EXPRSIZE]; // Base displacement expression
a0exattr = a0oexattr = a1exattr = a1oexattr = 0;
a0esym = a1esym = NULL;
a0bexpr[0] = a1bexpr[0] = ENDEXPR;
- a0bexval = a0bsize = a0extension = a1bexval = a1bsize = a1extension = 0;
+ a0bexval = a1bexval = 0;
+ a0bsize = a0extension = a1bsize = a1extension = 0;
am0_030 = am1_030 = 0;
bfparam1 = bfparam2 = 0;
bf0expr[0] = ENDEXPR;
if (*tok == CONST)
{
- tok++; // Skip the HI LONG
tok++;
- bfval1 = *(int *)tok;
+ bfval1 = (int)*(uint64_t *)tok;
// Do=0, offset=immediate - shift it to place
bfparam1 = (0 << 11);
tok++;
+ tok++;
}
else if (*tok == SYMBOL)
{
if (!(bf0exattr & DEFINED))
return error("bfxxx offset: immediate value must evaluate");
- bfval1 = bf0exval;
+ bfval1 = (int)bf0exval;
// Do=0, offset=immediate - shift it to place
bfparam1 = (0 << 11);
if (*tok == CONST)
{
- tok++; // Skip the HI LONG
tok++;
- bfval2 = *(int *)tok;
+ bfval2 = (int)*(uint64_t *)tok;
// Do=0, offset=immediate - shift it to place
bfparam2 = (0 << 5);
tok++;
+ tok++;
}
else if (*tok == SYMBOL)
{
if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
return ERROR;
- bfval2 = bf0exval;
+ bfval2 = (int)bf0exval;
if (!(bf0exattr & DEFINED))
return error("bfxxx width: immediate value must evaluate");
extern int a0ixreg, a1ixreg;
extern int a0ixsiz, a1ixsiz;
extern TOKEN a0oexpr[], a1oexpr[];
-extern uint32_t a0oexval, a1oexval;
+extern uint64_t a0oexval, a1oexval;
extern WORD a0oexattr, a1oexattr;
extern SYM * a0esym, * a1esym;
extern uint64_t a0bexval, a1bexval;
#include "sect.h"
#include "symbol.h"
#include "token.h"
+#include "math.h"
+#include "sect.h"
#define DEF_KW
#include "kwtab.h"
return error("PRGFLAGS requires value");
else if (abs_expr(&eval) == OK)
{
- PRGFLAGS=eval;
+ PRGFLAGS = (uint32_t)eval;
return 0;
}
else
return 0;
SwitchSection(ABS);
- sloc = eval;
+ sloc = (uint32_t)eval;
return 0;
}
// of zeroed memory....
if ((scattr & SBSS) || cursect == M6502)
{
- listvalue(eval);
+ listvalue((uint32_t)eval);
eval *= siz;
- sloc += eval;
+ sloc += (uint32_t)eval;
if (cursect == M6502)
chptr += eval;
{
WORD eattr;
uint64_t eval;
+ WORD tdb;
+ WORD defined;
+ uint64_t val64;
uint8_t * p;
if ((scattr & SBSS) != 0)
siz = SIZL;
}
+ if (siz != SIZQ)
+ {
// dc.x <expression>
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;
+ }
- uint16_t tdb = eattr & TDB;
- uint16_t defined = eattr & DEFINED;
+ tdb = (WORD)(eattr & TDB);
+ defined = (WORD)(eattr & DEFINED);
if ((challoc - ch_size) < 4)
chcheck(4);
D_long(eval);
}
break;
+ case SIZS:
+ if (m6502)
+ return error(in_6502mode);
+
+ if (!defined)
+ {
+ float vv = 0;
+ AddFixup(FU_FLOATSING, sloc, exprbuf);
+
+ D_single(vv);
+ }
+ else
+ {
+ if (tdb)
+ MarkRelocatable(cursect, sloc, tdb, MSINGLE, NULL);
+
+ D_single(eval);
+ }
+ break;
case SIZD:
- // 64-bit size
- // N.B.: May have to come up with section/fixup markers for this;
- // ATM it's only used in dc.d statements...
- D_long(eval >> 32);
- D_long(eval & 0xFFFFFFFF);
+ if (m6502)
+ return error(in_6502mode);
+
+ if (!defined)
+ {
+ double vv = 0;
+ AddFixup(FU_FLOATDOUB, sloc, exprbuf);
+
+ D_double(vv);
+ }
+ else
+ {
+ double vv;
+ if (tdb)
+ MarkRelocatable(cursect, sloc, tdb, MDOUBLE, NULL);
+
+ vv = *(double *)&eval;
+ D_double(vv);
+ }
+ break;
+ case SIZX:
+ if (m6502)
+ return error(in_6502mode);
+
+ if (!defined)
+ {
+ double vv = 0;
+ AddFixup(FU_FLOATEXT, sloc, exprbuf);
+
+ D_extend(vv);
+ }
+ else
+ {
+ float vv;
+ if (tdb)
+ MarkRelocatable(cursect, sloc, tdb, MEXTEND, NULL);
+
+ vv = *(double *)&eval;
+ D_extend(vv);
+ }
break;
}
+
comma:
if (*tok != ',')
break;
if (cursect != M6502 && (siz != SIZB) && (sloc & 1))
auto_even();
- dep_block(evalc, siz, eval, eattr, exprbuf);
+ dep_block((uint32_t)evalc, siz, (uint32_t)eval, eattr, exprbuf);
return 0;
}
break;
}
- dep_block(count, siz, eval, eattr, exprbuf);
+ dep_block((uint32_t)count, siz, (uint32_t)eval, eattr, exprbuf);
switch ((int)*tok)
{
if (abs_expr(&eval) != OK) // Parse size of common region
return 0;
- sym->svalue = eval; // Install common symbol's size
+ sym->svalue = (uint32_t)eval; // Install common symbol's size
at_eol();
return 0;
}
AddToSymbolDeclarationList(symbol);
symbol->sattr |= (ABS | DEFINED | EQUATED);
- symbol->svalue = eval;
+ symbol->svalue = (uint32_t)eval;
tok += 2;
// What this does is eat any dot suffixes attached to a symbol. If
}
symbol->sattr |= (ABS | DEFINED | EQUATED);
- symbol->svalue = eval;
+ symbol->svalue = (uint32_t)eval;
// Check for dot suffixes and adjust space accordingly (longs and
// words on an odd boundary get bumped to the next word aligned
int eaNgen(WORD siz)
{
- uint32_t vbd, v = aNexval;
+ uint32_t vbd, v = (uint32_t)aNexval;
WORD wbd, w = (WORD)(aNexattr & DEFINED);
WORD tdbbd, tdb = (WORD)(aNexattr & TDB);
- vbd = aNbdexval;
+ vbd = (uint32_t)aNbdexval;
wbd = (WORD)(aNbdexattr & DEFINED);
tdbbd = (WORD)(aNbdexattr & TDB);
D_long(0);
}
+ break;
+ case SIZS:
+ // 68881/68882/68040 only
+ if (w)
+ {
+ float vv;
+ if (tdb)
+ MarkRelocatable(cursect, sloc, tdb, MSINGLE, NULL);
+
+ vv = (float)v;
+
+ D_single(vv);
+ }
+ else
+ {
+ float vv = 0;
+ AddFixup(FU_FLOATSING, sloc, aNexpr);
+
+ D_single(vv);
+ }
+
+ break;
+ case SIZD:
+ // 68881/68882/68040 only
+ if (w)
+ {
+ double vv;
+ unsigned long long vvv;
+ if (tdb)
+ MarkRelocatable(cursect, sloc, tdb, MDOUBLE, NULL);
+
+ // We want to store the IEE754 float into ram from a generic
+ // 32-bit int. First, convert it to double float, then cast
+ // that to 64-bit, then convert to big endian (if needed)
+ // and then store it (phew!)
+ vv = *(float *)&aNexval;
+ vvv = BYTESWAP64(*(unsigned long long *)&vv);
+
+ D_double(vvv);
+ }
+ else
+ {
+ unsigned long long vvv = 0;
+ AddFixup(FU_FLOATDOUB, sloc, aNexpr);
+
+ D_double(vvv);
+ }
+
+ break;
+ case SIZX:
+ // 68881/68882/68040 only
+ if (w)
+ {
+ long double vv;
+ if (tdb)
+ MarkRelocatable(cursect, sloc, tdb, MEXTEND, NULL);
+
+ // We want to store the IEE754 float into ram from a generic
+ // 32-bit int. First, convert it to double float, then cast
+ // that to 96-bit, then convert to big endian (if needed)
+ // and then store it (phew!)
+ vv = (double)aNexval;
+
+ //*chptr++ = (char)((*(unsigned long long *)&vv) >> 32) | 0x80 /* assume that the number is normalised */;
+ D_extend(vv);
+ }
+ else
+ {
+ long double vvv = 0;
+ AddFixup(FU_FLOATDOUB, sloc, aNexpr);
+
+ D_extend(vvv);
+ }
+
break;
default:
// IMMED size problem
// Token-class initialization list
char itokcl[] = {
0, // END
- CONST, SYMBOL, 0, // ID
+ CONST, FCONST, SYMBOL, 0, // ID
'(', '[', '{', 0, // OPAR
')', ']', '}', 0, // CPAR
CR_DEFINED, CR_REFERENCED, // SUNARY (special unary)
char * p, * p2;
WORD w;
int j;
+ uint64_t * evalTokenBuffer64;
class = tokenClass[*tok];
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
+ if (t != '+')
*evalTokenBuffer++ = t;
}
else if (class == SUNARY)
{
case CR_ABSCOUNT:
*evalTokenBuffer++ = CONST;
- *evalTokenBuffer++ = 0; // Set HI LONG to zero
- *evalTokenBuffer++ = (LONG)sect[ABS].sloc;
+ evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ *evalTokenBuffer64++ = (LONG)sect[ABS].sloc;
+ evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
break;
case CR_TIME:
*evalTokenBuffer++ = CONST;
- *evalTokenBuffer++ = 0; // Set HI LONG to zero
- *evalTokenBuffer++ = dos_time();
+ evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ *evalTokenBuffer64++ = dos_time();
+ evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
break;
case CR_DATE:
*evalTokenBuffer++ = CONST;
- *evalTokenBuffer++ = 0; // Set HI LONG to zero
- *evalTokenBuffer++ = dos_date();
+ evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ *evalTokenBuffer64++ = dos_date();
+ evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
break;
case CR_MACDEF: // ^^macdef <macro-name>
if (*tok++ != SYMBOL)
p = string[*tok++];
w = (lookup(p, MACRO, 0) == NULL ? 0 : 1);
- *evalTokenBuffer++ = CONST;
- *evalTokenBuffer++ = 0; // Set HI LONG to zero
+ evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ *evalTokenBuffer64++ = (TOKEN)w;
+ evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
*evalTokenBuffer++ = (TOKEN)w;
break;
case CR_DEFINED:
j = (*p == '.' ? curenv : 0);
w = ((sy = lookup(p, LABEL, j)) != NULL && (sy->sattr & w) ? 1 : 0);
*evalTokenBuffer++ = CONST;
- *evalTokenBuffer++ = 0; // Set HI LONG to zero
- *evalTokenBuffer++ = (TOKEN)w;
+ uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ *evalTokenBuffer64++ = (TOKEN)w;
+ evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
break;
case CR_STREQ:
if (*tok != SYMBOL && *tok != STRING)
w = (WORD)(!strcmp(p, p2));
*evalTokenBuffer++ = CONST;
- *evalTokenBuffer++ = 0; // Set HI LONG to zero
- *evalTokenBuffer++ = (TOKEN)w;
+ evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ *evalTokenBuffer64++ = (TOKEN)w;
+ evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
break;
}
}
char * p;
SYM * sy;
int j;
+ uint64_t * evalTokenBuffer64;
+ uint64_t * tok64;
switch ((int)*tok++)
{
case CONST:
*evalTokenBuffer++ = CONST;
- *evalTokenBuffer++ = *tok++; // HI LONG of constant
- *evalTokenBuffer++ = *tok++; // LO LONG of constant
+ evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ tok64 = (uint64_t *)tok;
+ *evalTokenBuffer64++ = *tok64++;
+ tok = (TOKEN *)tok64;
+ evalTokenBuffer = (TOKEN *)evalTokenBuffer64;
+ break;
+ case FCONST:
+ *evalTokenBuffer++ = FCONST;
+ evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ tok64 = (uint64_t *)tok;
+ *evalTokenBuffer64++ = *tok64++;
+ tok = (TOKEN *)tok64;
+ evalTokenBuffer = (TOKEN *)evalTokenBuffer64;
break;
case SYMBOL:
p = string[*tok++];
break;
case STRING:
*evalTokenBuffer++ = CONST;
- *evalTokenBuffer++ = 0; // Set HI LONG to zero
- *evalTokenBuffer++ = str_value(string[*tok++]);
+ uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ *evalTokenBuffer64++ = str_value(string[*tok++]);
+ evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
break;
case '(':
if (expr0() != OK)
// (assuming tok[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 && tokenClass[tok[0]] != SUNARY))
-// || (((*tok == CONST || *tok == SYMBOL) || (*tok >= KW_R0 && *tok <= KW_R31))
+ 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) && (tokenClass[tok[3]] < UNARY))
+ || ((tok[0] == CONST || tok[0] == FCONST) && (tokenClass[tok[3]] < UNARY))
)
{
if (*tok >= KW_R0 && *tok <= KW_R31)
{
*evalTokenBuffer++ = CONST;
- *evalTokenBuffer++ = 0; // Set HI LONG to zero
- *evalTokenBuffer++ = *a_value = (*tok - KW_R0);
+ uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ *evalTokenBuffer64++ = *a_value = (*tok - KW_R0);
+ evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
*a_attr = ABS | DEFINED;
if (a_esym != NULL)
else if (*tok == CONST)
{
*evalTokenBuffer++ = CONST;
- *evalTokenBuffer++ = tok[1];
- *evalTokenBuffer++ = tok[2];
- *a_value = (((uint64_t)tok[1]) << 32) | tok[2];
+ uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ uint64_t *tok64 = (uint64_t *)&tok[1];
+ *evalTokenBuffer64++ = *tok64++;
+ evalTokenBuffer = (TOKEN *)evalTokenBuffer64;
+ *a_value = tok[1];
*a_attr = ABS | DEFINED;
if (a_esym != NULL)
tok += 3;
//printf("Quick eval in expr(): CONST = %i, tokenClass[tok[2]] = %i\n", *a_value, tokenClass[*tok]);
+ }
+ else if (*tok == FCONST)
+ {
+ *evalTokenBuffer++ = FCONST;
+ *((double *)evalTokenBuffer) = *((double *)&tok[1]);
+ evalTokenBuffer += 2;
+ //*(double *)evalTokenBuffer++ = tok[2];
+ *a_value = *((uint64_t *)&tok[1]);
+ *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]);
}
else if (*tok == '*')
{
*evalTokenBuffer++ = CONST;
- *evalTokenBuffer++ = 0; // Set HI LONG to zero
+ uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
if (orgactive)
- *evalTokenBuffer++ = *a_value = orgaddr;
+ *evalTokenBuffer64++ = *a_value = orgaddr;
else
- *evalTokenBuffer++ = *a_value = pcloc;
+ *evalTokenBuffer64++ = *a_value = pcloc;
+ evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
// '*' takes attributes of current section, not ABS!
*a_attr = cursect | DEFINED;
//
int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
{
- WORD attr;
+ WORD attr, attr2;
SYM * sy;
uint64_t * sval = evstk; // (Empty) initial stack
WORD * sattr = evattr;
SYM * esym = NULL; // No external symbol involved
WORD sym_seg = 0;
+ uint64_t *tk64;
while (*tk != ENDEXPR)
{
sym_seg = (WORD)(sy->sattr & TDB);
break;
case CONST:
- *++sval = ((uint64_t)*tk++) << 32; // Push value
- *sval |= *tk++; // & LO LONG (will this work???--should)
+ tk64 = (uint64_t *)tk;
+ *++sval = *tk64++;
+ tk = (TOKEN *)tk64;
//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;
+ *++sattr = ABS | DEFINED | FLOAT; // Push simple attribs
+ break;
case ACONST:
//printf("evexpr(): ACONST = %i\n", *tk);
*++sval = *tk++; // Push value
--sval; // Pop value
--sattr; // Pop attrib
//printf("--> N+N: %i + %i = ", *sval, sval[1]);
+ // Extract float attributes from both terms and pack them
+ // into a single value
+ attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+ attr2 = sattr[0] | sattr[1] & FLOAT; // Returns FLOAT if either of the two numbers are FLOAT
+
+ if (attr == (FLOAT | (FLOAT >> 1)))
+ {
+ // Float + Float
+ double * dst = (double *)sval;
+ double * src = (double *)(sval + 1);
+ *dst += *src;
+ }
+ else if (attr == FLOAT)
+ {
+ // Float + Int
+ double * dst = (double *)sval;
+ uint64_t * src = (uint64_t *)(sval + 1);
+ *dst += *src;
+ }
+ else if (attr == FLOAT >> 1)
+ {
+ // Int + Float
+ uint64_t * dst = (uint64_t *)sval;
+ double * src = (double *)(sval + 1);
+ *(double *)dst = *src + *dst;
+ }
+ else
+ {
*sval += sval[1]; // Compute value
+ }
//printf("%i\n", *sval);
if (!(*sattr & TDB))
- *sattr = sattr[1];
+ *sattr = sattr[1] | attr2;
else if (sattr[1] & TDB)
return error(seg_error);
--sval; // Pop value
--sattr; // Pop attrib
//printf("--> N-N: %i - %i = ", *sval, sval[1]);
+ // Extract float attributes from both terms and pack them
+ // into a single value
+ attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+ attr2 = sattr[0] | sattr[1] & FLOAT; // Returns FLOAT if either of the two numbers are FLOAT
+
+ if (attr == (FLOAT | (FLOAT >> 1)))
+ {
+ // Float - Float
+ double * dst = (double *)sval;
+ double * src = (double *)(sval + 1);
+ *dst -= *src;
+ }
+ else if (attr == FLOAT)
+ {
+ // Float - Int
+ double * dst = (double *)sval;
+ uint64_t * src = (uint64_t *)(sval + 1);
+ *dst -= *src;
+ }
+ else if (attr == FLOAT >> 1)
+ {
+ // Int - Float
+ uint64_t * dst = (uint64_t *)sval;
+ double * src = (double *)(sval + 1);
+ *(double *)dst = *dst - *src;
+ }
+ else
+ {
*sval -= sval[1]; // Compute value
+ }
+
//printf("%i\n", *sval);
attr = (WORD)(*sattr & TDB);
#if 0
printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
#endif
+ *sattr |= attr2; // Inherit FLOAT attribute
// If symbol1 is ABS, take attributes from symbol2
if (!attr)
*sattr = sattr[1];
case UNMINUS:
//printf("evexpr(): UNMINUS\n");
if (*sattr & TDB)
- error(seg_error);
+ return error(seg_error);
+ if (*sattr & FLOAT)
+ {
+ double *dst = (double *)sval;
+ *dst = -*dst;
+ *sattr = ABS | DEFINED | FLOAT; // Expr becomes absolute
+ }
+ else
+ {
*sval = -(int)*sval;
*sattr = ABS | DEFINED; // Expr becomes absolute
+ }
break;
case '!':
//printf("evexpr(): !\n");
if (*sattr & TDB)
- error(seg_error);
+ return error(seg_error);
+
+ if (*sattr & FLOAT)
+ return error("floating point numbers not allowed with operator '!'.");
*sval = !*sval;
*sattr = ABS | DEFINED; // Expr becomes absolute
case '~':
//printf("evexpr(): ~\n");
if (*sattr & TDB)
- error(seg_error);
+ return error(seg_error);
+
+ if (*sattr & FLOAT)
+ return error("floating point numbers not allowed with operator '~'.");
*sval = ~*sval;
*sattr = ABS | DEFINED; // Expr becomes absolute
sval--;
if ((*sattr & TDB) != (sattr[1] & TDB))
- error(seg_error);
+ return error(seg_error);
- *sattr = ABS | DEFINED;
+ // Extract float attributes from both terms and pack them
+ // into a single value
+ attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+
+ if (attr == (FLOAT | (FLOAT >> 1)))
+ {
+ // Float <= Float
+ double * dst = (double *)sval;
+ double * src = (double *)(sval + 1);
+ *sval = *dst <= *src;
+ }
+ else if (attr == FLOAT)
+ {
+ // Float <= Int
+ double * dst = (double *)sval;
+ uint64_t * src = (uint64_t *)(sval + 1);
+ *sval = *dst <= *src;
+ }
+ else if (attr == FLOAT >> 1)
+ {
+ // Int <= Float
+ uint64_t * dst = (uint64_t *)sval;
+ double * src = (double *)(sval + 1);
+ *sval = *dst <= *src;
+ }
+ else
+ {
*sval = *sval <= sval[1];
+ }
+
+ *sattr = ABS | DEFINED;
break;
case GE:
//printf("evexpr(): GE\n");
sval--;
if ((*sattr & TDB) != (sattr[1] & TDB))
- error(seg_error);
+ return error(seg_error);
- *sattr = ABS | DEFINED;
+ // Extract float attributes from both terms and pack them
+ // into a single value
+ attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+
+ if (attr == (FLOAT | (FLOAT >> 1)))
+ {
+ // Float >= Float
+ double * dst = (double *)sval;
+ double * src = (double *)(sval + 1);
+ *sval = *dst >= *src;
+ }
+ else if (attr == FLOAT)
+ {
+ // Float >= Int
+ double * dst = (double *)sval;
+ uint64_t * src = (uint64_t *)(sval + 1);
+ *sval = *dst >= *src;
+ }
+ else if (attr == FLOAT >> 1)
+ {
+ // Int >= Float
+ uint64_t * dst = (uint64_t *)sval;
+ double * src = (double *)(sval + 1);
+ *sval = *dst >= *src;
+ }
+ else if (attr == 0)
+ {
*sval = *sval >= sval[1];
+ }
+ else
+
+ *sattr = ABS | DEFINED;
+
break;
case '>':
//printf("evexpr(): >\n");
sval--;
if ((*sattr & TDB) != (sattr[1] & TDB))
- error(seg_error);
+ return error(seg_error);
- *sattr = ABS | DEFINED;
+ // Extract float attributes from both terms and pack them
+ // into a single value
+ attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+
+ if (attr == (FLOAT | (FLOAT >> 1)))
+ {
+ // Float > Float
+ double * dst = (double *)sval;
+ double * src = (double *)(sval + 1);
+ *sval = *dst > *src;
+ }
+ else if (attr == FLOAT)
+ {
+ // Float > Int
+ double * dst = (double *)sval;
+ uint64_t * src = (uint64_t *)(sval + 1);
+ *sval = *dst > *src;
+ }
+ else if (attr == FLOAT >> 1)
+ {
+ // Int > Float
+ uint64_t * dst = (uint64_t *)sval;
+ double * src = (double *)(sval + 1);
+ *sval = *dst > *src;
+ }
+ else
+= {
*sval = *sval > sval[1];
+ }
+
+ *sattr = ABS | DEFINED;
+
break;
case '<':
//printf("evexpr(): <\n");
sval--;
if ((*sattr & TDB) != (sattr[1] & TDB))
- error(seg_error);
+ return error(seg_error);
- *sattr = ABS | DEFINED;
+ // Extract float attributes from both terms and pack them
+ // into a single value
+ attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) > >1);
+
+ if (attr == (FLOAT | (FLOAT >> 1)))
+ {
+ // Float < Float
+ double * dst = (double *)sval;
+ double * src = (double *)(sval + 1);
+ *sval = *dst < *src;
+ }
+ else if (attr == FLOAT)
+ {
+ // Float < Int
+ double * dst = (double *)sval;
+ uint64_t * src = (uint64_t *)(sval + 1);
+ *sval = *dst < *src;
+ }
+ else if (attr == FLOAT >> 1)
+ {
+ // Int < Float
+ uint64_t * dst = (uint64_t *)sval;
+ double * src = (double *)(sval + 1);
+ *sval = *dst < *src;
+ }
+ else
+ {
*sval = *sval < sval[1];
+ }
+
+ *sattr = ABS | DEFINED;
+
break;
case NE:
//printf("evexpr(): NE\n");
sval--;
if ((*sattr & TDB) != (sattr[1] & TDB))
- error(seg_error);
+ return error(seg_error);
- *sattr = ABS | DEFINED;
+ // Extract float attributes from both terms and pack them
+ // into a single value
+ attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+
+ if (attr == (FLOAT | (FLOAT >> 1)))
+ {
+ // Float <> Float
+ return error("comparison for equality with float types not allowed.");
+ }
+ else if (attr == FLOAT)
+ {
+ // Float <> Int
+ return error("comparison for equality with float types not allowed.");
+ }
+ else if (attr == FLOAT >> 1)
+ {
+ // Int != Float
+ return error("comparison for equality with float types not allowed.");
+ }
+ else
+ {
*sval = *sval != sval[1];
+ }
+
+ *sattr = ABS | DEFINED;
+
break;
case '=':
//printf("evexpr(): =\n");
sval--;
if ((*sattr & TDB) != (sattr[1] & TDB))
- error(seg_error);
+ return error(seg_error);
- *sattr = ABS | DEFINED;
+ // Extract float attributes from both terms and pack them
+ // into a single value
+ attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+
+ if (attr == (FLOAT | (FLOAT >> 1)))
+ {
+ // Float = Float
+ double * dst = (double *)sval;
+ double * src = (double *)(sval + 1);
+ *sval = *src == *dst;
+ }
+ else if (attr == FLOAT)
+ {
+ // Float = Int
+ return error("equality with float ");
+ }
+ else if (attr == FLOAT >> 1)
+ {
+ // Int == Float
+ uint64_t * dst = (uint64_t *)sval;
+ double * src = (double *)(sval + 1);
+ *sval = *src == *dst;
+ }
+ else
+ {
*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.
// 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);
- *sattr = ABS | DEFINED; // Expr becomes absolute
switch ((int)tk[-1])
{
sval--;
sattr--; // Pop attrib
//printf("--> NxN: %i x %i = ", *sval, sval[1]);
+ // Extract float attributes from both terms and pack them
+ // into a single value
+ attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+ attr2 = sattr[0] | sattr[1] & FLOAT; // Returns FLOAT if either of the two numbers are FLOAT
+
+ if (attr == (FLOAT | (FLOAT >> 1)))
+ {
+ // Float * Float
+ double * dst = (double *)sval;
+ double * src = (double *)(sval + 1);
+ *dst *= *src;
+ }
+ else if (attr == FLOAT)
+ {
+ // Float * Int
+ double * dst = (double *)sval;
+ uint64_t * src = (uint64_t *)(sval + 1);
+ *dst *= *src;
+ }
+ else if (attr == FLOAT >> 1)
+ {
+ // Int * Float
+ uint64_t * dst = (uint64_t *)sval;
+ double * src = (double *)(sval + 1);
+ *(double *)dst = *src * *dst;
+ }
+ else
+ {
*sval *= sval[1];
+ }
//printf("%i\n", *sval);
+
+ *sattr = ABS | DEFINED; // Expr becomes absolute
+ *sattr |= attr2;
+
break;
case '/':
sval--;
sattr--; // Pop attrib
- if (sval[1] == 0)
- return error("division by zero");
+//printf("--> N/N: %i / %i = ", sval[0], sval[1]);
+ // Extract float attributes from both terms and pack them
+ // into a single value
+ attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
+ attr2 = sattr[0] | sattr[1] & FLOAT; // Returns FLOAT if either of the two numbers are FLOAT
+
+ if (attr == (FLOAT | (FLOAT >> 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)
+ {
+ // 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)
+ {
+ // 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
+ {
+ 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];
+ }
+
+ *sattr = ABS | DEFINED; // Expr becomes absolute
+ *sattr |= attr2;
+
//printf("%i\n", *sval);
break;
case '%':
sval--;
sattr--; // Pop attrib
+ if ((*sattr | sattr[1]) & FLOAT)
+ return error("floating point numbers not allowed with operator '%'.");
if (sval[1] == 0)
return error("mod (%) by zero");
+ *sattr = ABS | DEFINED; // Expr becomes absolute
*sval %= sval[1];
break;
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;
default:
&& ((am0 == ADISP) && (a0reg == a1reg) && (a0exattr & DEFINED))
&& ((a0exval > 0) && (a0exval <= 8)))
{
- inst = B16(01010000, 01001000) | ((a0exval & 7) << 9) | (a0reg);
+ inst = B16(01010000, 01001000) | (((uint16_t)a0exval & 7) << 9) | (a0reg);
D_word(inst);
warn("lea size(An),An converted to addq #size,An");
return OK;
if ((a0exattr & TDB) != cursect)
return error(rel_error);
- uint32_t v = a0exval - (sloc + 2);
+ uint32_t v = (uint32_t)a0exval - (sloc + 2);
D_word(inst);
D_long(v);
if (a0exval > 255)
return error(range_error);
- inst = a0exval;
+ inst = (uint16_t)a0exval;
D_word(inst);
}
else
if ((a0exattr & TDB) != cursect)
return error(rel_error);
- uint32_t v = a0exval - (sloc + 2);
+ uint32_t v = (uint32_t)a0exval - (sloc + 2);
// Optimize branch instr. size
if (siz == SIZL)
if ((a1exattr & TDB) != cursect)
return error(rel_error);
- v = a1exval - sloc;
+ v = (uint32_t)a1exval - sloc;
if (v + 0x8000 > 0x10000)
return error(range_error);
{
//move16 (ax)+,(xxx).L
inst |= 0 << 3;
- v = a1exval;
+ v = (int)a1exval;
}
}
else if (am0 == ABSL)
{
//move16 (xxx).L,(ax)+
inst |= 1 << 3;
- v = a0exval;
+ v = (int)a0exval;
}
else //APOSTINC
{
//move16 (xxx).L,(ax)
inst |= 3 << 3;
- v = a0exval;
+ v = (int)a0exval;
}
}
else if (am0 == AIND)
{
//move16 (ax),(xxx).L
inst |= 2 << 3;
- v = a1exval;
+ v = (int)a1exval;
}
D_word(inst);
return error("function code immediate should be defined");
if (a0exval > 7 && a0exval < 0)
return error("function code out of range (0-7)");
- fc = a0exval;
+ fc = (uint16_t)a0exval;
break;
case KW_D0:
case KW_D1:
return error("mask immediate value should be defined");
if (a0exval > 7 && a0exval < 0)
return error("function code out of range (0-7)");
- mask = a0exval << 5;
+ mask = (uint16_t)a0exval << 5;
if (*tok == EOL)
{
case IMMED:
if ((a0exattr & DEFINED) == 0)
return error("constant value must be defined");
- inst = (2 << 3) | a0exval;
+ inst = (2 << 3) | (uint16_t)a0exval;
break;
}
return m_pmove(inst | (1 << 8), siz);
}
-
//
// ptrapcc (68851)
//
if ((a1exattr & TDB) != cursect)
return error(rel_error);
- uint32_t v = a1exval - sloc;
+ uint32_t v = (uint32_t)a1exval - sloc;
if ((v + 0x8000) > 0x10000)
return error(range_error);
IREPT * irept = inobj->inobj.irept;
irept->ir_firstln = firstrpt;
irept->ir_nextln = NULL;
- irept->ir_count = eval;
+ irept->ir_count = (uint32_t)eval;
}
return 0;
else if (*tok == CONST) // Constants are 64-bits
{
*p++ = *tok++; // Token
- *p++ = *tok++; // Hi LONG
- *p++ = *tok++; // Lo LONG
+ uint64_t *p64 = (uint64_t *)p;
+ uint64_t *tok64 = (uint64_t *)tok;
+ *p64++ = *tok64++;
+ tok = (TOKEN *)tok64;
+ p = (uint32_t *)p64;
}
else if ((*tok == STRING) || (*tok == SYMBOL))
{
// Setup pointer for D_long/word/byte macros
chptr = buf;
+ ch_size = 0;
for(MCHUNK * mch=firstmch; mch!=NULL; mch=mch->mcnext)
{
#define MWORD 0x0000 // Marked word
#define MLONG 0x0100 // Marked long
#define MMOVEI 0x0200 // Mark RISC MOVEI instruction
+#define MDOUBLE 0x0400 // Marked double float
+#define MEXTEND 0x0800 // Marked extended float
+#define MSINGLE 0x0880 // Marked single float (TODO: merge with MLONG?)
#define MGLOBAL 0x0800 // Mark contains global
#define MPCREL 0x1000 // Mark is PC-relative
#define MCHEND 0x2000 // Indicates end of mark chunk
if (buf == NULL)
{
- error("cannot allocate object file memory (in BSD mode)");
+ error("cannot allocate object file memory (in ELF mode)");
return ERROR;
}
if (strtable == NULL)
{
- error("cannot allocate string table memory (in BSD mode)");
+ error("cannot allocate string table memory (in ELF mode)");
return ERROR;
}
// It might be (Dn[.wl][*scale],od)
// Maybe this is wrong and we have to write some code here
// instead of reusing that path...
+ AnEXTEN |= EXT_BDSIZE0; // Base displacement null - suppressed
goto CHECKODn;
}
else
if (*tok == ',')
{
+ // If we got here we didn't get any [] stuff
+ // so let's suppress base displacement before
+ // branching off
tok++;
+ AnEXTEN |= EXT_BDSIZE0; // Base displacement null - suppressed
goto CHECKODn;
}
if (*tok++ != ')') // final ")"
tok++;
// Check for size
+ {
// ([bd,An/PC],Xn.W/L...)
switch ((int)*tok)
{
// .B not allowed here...
goto badmode;
}
+ }
// Check for scale
if (*tok == '*') // ([bd,An/PC],Xn*...)
// Is .W forced here?
if (*tok == DOTW)
+ {
tok++;
+ }
}
// Check for final closing parenthesis
}
// Check for size
+ {
// ([bd,An/PC],Xn.W/L...)
switch ((int)*tok)
{
// .B not allowed here...
goto badmode;
}
+ }
// Check for scale
if (*tok == '*') // ([bd,An/PC],Xn*...)
{
// Advance token pointer to the constant
tok += 3;
- tok++; // Skip the hi LONG, so pointing at lo LONG
// Anything other than a 0 or a 1 will result in "No Bank"
- if (*tok == 0)
+ if (*(uint64_t *)tok == 0)
registerbank = BANK_0;
- else if (*tok == 1)
+ else if (*(uint64_t *)tok == 1)
registerbank = BANK_1;
}
}
sy->sattr |= eattr | EQUATED; // Symbol inherits value and attributes
- sy->svalue = eval;
+ sy->svalue = (uint32_t)eval;
if (list_flag) // Put value in listing
- listvalue(eval);
+ listvalue((uint32_t)eval);
at_eol(); // Must be at EOL now
goto loop;
// If we got a register in range (0-31), return it
if ((eval >= 0) && (eval <= 31))
- return eval;
+ return (int)eval;
// Otherwise, it's out of range & we flag an error
return error(reg_err);
return error("constant out of range");
if (parm & SUB32)
- reg1 = 32 - eval;
+ reg1 = 32 - (int)eval;
else if (type == RI_NUM_32)
- reg1 = (reg1 == 32 ? 0 : eval);
+ reg1 = (reg1 == 32 ? 0 : (int)eval);
else
- reg1 = eval;
+ reg1 = (int)eval;
}
CHECK_COMMA;
if (!(eattr & DEFINED))
return error("constant expected after '+'");
- reg1 = eval;
+ reg1 = (int)eval;
if (reg1 == 0)
{
}
else
{
- reg2 = eval;
+ reg2 = (int)eval;
if (reg2 == 0)
{
{
// CC using a constant number
tok++;
- tok++; // Toss hi LONG, as most likely not 64-bit number
- val = *tok; // Use lo LONG
- tok++;
+ uint64_t *tok64 = (uint64_t *)tok;
+ val = (int)*tok64++;
+ tok = (uint32_t *)tok64;
CHECK_COMMA;
}
else if (*tok == SYMBOL)
// Byteswap crap
#define BYTESWAP16(x) ((((x) & 0x00FF) << 8) | (((x) & 0xFF00) >> 8))
#define BYTESWAP32(x) ((((x) & 0x000000FF) << 24) | (((x) & 0x0000FF00) << 8) | (((x) & 0x00FF0000) >> 8) | (((x) & 0xFF000000) >> 24))
+#define BYTESWAP64(x) (BYTESWAP32(x>>32)|BYTESWAP32((x&0xffffffff)<<32))
#define WORDSWAP32(x) ((((x) & 0x0000FFFF) << 16) | (((x) & 0xFFFF0000) >> 16))
//
#define CREATMASK 0
// Object code formats
-#define ALCYON 0 // Alcyon/DRI C object format
-#define MWC 1 // Mark Williams object format
-#define BSD 2 // BSD object format
-#define ELF 3 // ELF object format
-#define XEX 4 // COM/EXE/XEX/whatever a8 object format
+enum
+{
+ALCYON, // Alcyon/DRI C object format
+MWC, // Mark Williams object format
+BSD, // BSD object format
+ELF, // ELF object format
+LOD, // DSP 56001 object format
+P56, // DSP 56001 object format
+XEX, // COM/EXE/XEX/whatever a8 object format
+};
// Pointer type that can point to (almost) anything
#define PTR union _ptr
#define REFERENCED 0x1000 // Symbol has been referenced
#define EQUATED 0x0800 // Symbol was equated
#define SDECLLIST 0x0400 // Symbol is on 'sdecl'-order list
+#define FLOAT 0x0200 // Symbol is a floating point value
// Expression spaces, ORed with symbol and expression attributes above
#define ABS 0x0000 // In absolute space
#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 SIZD
+#define SIZQ 0x0100 // .q
// RISC register bank definitions (used in extended symbol attributes also)
#define BANK_N 0x0000 // No register bank specified
sloc += 4; ch_size += 4; if(orgactive) orgaddr += 4;}
#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]; \
+ *chptr++ = ((char *)&w)[2]; \
+ *chptr++ = ((char *)&w)[1]; \
+ *chptr++=((char *)&w)[0]; \
+ sloc+=4; ch_size += 4; if(orgactive) orgaddr += 4;}
+#define D_double(w) {chcheck(8);*chptr++=(char)((*(unsigned long long *)&w)); \
+ *chptr++=(char)((*(unsigned long long *)&w)>>8); \
+ *chptr++=(char)((*(unsigned long long *)&w)>>16); \
+ *chptr++=(char)((*(unsigned long long *)&w)>>24); \
+ *chptr++=(char)((*(unsigned long long *)&w)>>32); \
+ *chptr++=(char)((*(unsigned long long *)&w)>>40); \
+ *chptr++=(char)((*(unsigned long long *)&w)>>48); \
+ *chptr++=(char)((*(unsigned long long *)&w)>>56); \
+ sloc+=8; ch_size += 8; if(orgactive) orgaddr += 8;}
+#ifdef _MSC_VER
+#define D_extend(w) {chcheck(12); *chptr++ = (char)((*(unsigned long long *)&w) >> 56); \
+*chptr++ = (char)(((*(unsigned long long *)&w) >> (52)) & 0xf); \
+*chptr++ = (char)(0); \
+*chptr++ = (char)(0); \
+*chptr++ = (char)(((*(unsigned long long *)&w) >> (48 - 3))|0x80 /* assume that the number is normalised */); \
+*chptr++ = (char)((*(unsigned long long *)&w) >> (40 - 3)); \
+*chptr++ = (char)((*(unsigned long long *)&w) >> (32 - 3)); \
+*chptr++ = (char)((*(unsigned long long *)&w) >> (24 - 3)); \
+*chptr++ = (char)((*(unsigned long long *)&w) >> (16 - 3)); \
+*chptr++ = (char)((*(unsigned long long *)&w) >> (8 - 3)); \
+*chptr++ = (char)((*(unsigned long long *)&w << 3)); \
+*chptr++=(char)(0); \
+ sloc+=12; ch_size += 12; if(orgactive) orgaddr += 12;}
+#elif defined(LITTLE_ENDIAN)
+#define D_extend(w) {chcheck(12);*chptr++=((char *)&w)[0]; \
+ *chptr++=((char *)&w)[1]; \
+ *chptr++=((char *)&w)[2]; \
+ *chptr++=((char *)&w)[3]; \
+ *chptr++=((char *)&w)[4]; \
+ *chptr++=((char *)&w)[5]; \
+ *chptr++=((char *)&w)[6]; \
+ *chptr++=((char *)&w)[7]; \
+ *chptr++=((char *)&w)[8]; \
+ *chptr++=((char *)&w)[9]; \
+ *chptr++=((char *)&w)[10]; \
+ *chptr++=((char *)&w)[11]; \
+ sloc+=12; ch_size += 12; if(orgactive) orgaddr += 12;}
+
+#else
+
+#error Please implement a non-byte swapped D_extend!
+
+#endif
// Fill n bytes with zeroes
#define D_ZEROFILL(n) {memset(chptr, 0, n); chptr+=n; sloc+=n; ch_size+=n;\
if (orgactive) orgaddr+=n;}
#define FU_LBRA 0x4000 // Long branch, for short branch detect
#define FU_DONE 0x8000 // Fixup has been done
+// FPU fixups
+// TODO: these are obviously bogus for now!
+#define FU_FLOATSING 0x0D0B // Fixup 32-bit float
+#define FU_FLOATDOUB 0x0E0B // Fixup 64-bit float
+#define FU_FLOATEXT 0x0F0B // Fixup 96-bit float
+
// Chunks are used to hold generated code and fixup records
#define CHUNK struct _chunk
CHUNK {
}
}
- // For ELF object mode run through all symbols in reference order
- // and export all global-referenced labels. Not sure if this is
- // required but it's here nonetheless
-/* why?? when you have sy_assign_ELF ???
- if (obj_format == ELF)
- {
- for(sy=sdecl; sy!=NULL; sy=sy->sorder)
- {
- if ((sy->sattr == (GLOBAL | REFERENCED)) && (buf != NULL))
- {
- buf = (*construct)(buf, sy, 0);
- scount++;
- }
- }
- }*/
-
return scount;
}
// them. We also pick which symbols should be global or not here.
for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl)
{
- // Export or import external references, and export COMMON blocks.
- //if ((sy->stype == LABEL)
- // && ((sy->sattr & (GLOBAL | DEFINED)) == (GLOBAL | DEFINED)
- // || (sy->sattr & (GLOBAL | REFERENCED)) == (GLOBAL | REFERENCED))
- // || (sy->sattr & COMMON))
- //{
- // sy->senv = (WORD)scount++;
- //
- // if (buf != NULL)
- // buf = (*construct)(buf, sy, 1);
- //}
// Export vanilla labels (but don't make them global). An exception is
// made for equates, which are not exported unless they are referenced.
if (sy->stype == LABEL && lsym_flag
&& (sy->sattr & (DEFINED | REFERENCED)) != 0
&& (*sy->sname != '.')
&& (sy->sattr & GLOBAL) == 0)
- //if (sy->stype == 0)
- // if (lsym_flag)
- // if ((sy->sattr & (DEFINED | REFERENCED)) != 0)
- // if ((!as68_flag || *sy->sname != 'L'))
{
sy->senv = scount++;
// to choke on legitimate code... Need to investigate this further
// before changing anything else here!
case CONST:
- tk++; // Skip the hi LONG...
sprintf(numbuf, "$%lx", (uint64_t)*tk++);
+ tk++;
d = numbuf;
break;
case DEQUALS:
int j = 0; // Var for keyword detector
uint8_t c; // Random char
uint64_t v; // Random value
+ uint32_t cursize = 0; // Current line's size (.b, .w, .l, .s, .q, .d)
+ double f; // Random float
uint8_t * nullspot = NULL; // Spot to clobber for SYMBOL termination
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:
return error("[bwsl] must follow '.' in symbol");
v = (uint32_t)dotxtab[*ln++];
+ cursize = (uint32_t)v;
if (chrtab[*ln] & CTSYM)
return error("misuse of '.'; not allowed in symbols");
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
}
*tk++ = CONST;
- *tk++ = v >> 32; // High LONG of 64-bit value
- *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value
+ tk64 = (uint64_t *)tk;
+ *tk64++ = v;
+ tk = (TOKEN *)tk64;
if (obj_format == ALCYON)
{
}
*tk++ = CONST;
- *tk++ = v >> 32; // High LONG of 64-bit value
- *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value
+ tk64 = (uint64_t *)tk;
+ *tk64++ = v;
+ tk = (TOKEN *)tk64;
continue;
case '@': // @ or octal constant
if (*ln < '0' || *ln > '7')
}
*tk++ = CONST;
- *tk++ = v >> 32; // High LONG of 64-bit value
- *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value
+ tk64 = (uint64_t *)tk;
+ *tk64++ = v;
+ tk = (TOKEN *)tk64;
continue;
case '^': // ^ or ^^ <operator-name>
if (*ln != '^')
v &= 0x000000FF;
ln += 2;
*tk++ = CONST;
- *tk++ = 0; // Hi LONG of 64-bits
- *tk++ = v;
+ tk64 = (uint64_t *)tk;
+ *tk64++ = v;
+ tk = (uint32_t *)tk64;
*tk++ = DOTB;
}
else if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W'))
v &= 0x0000FFFF;
ln += 2;
*tk++ = CONST;
- *tk++ = 0; // Hi LONG of 64-bits
- *tk++ = v;
+ tk64 = (uint64_t *)tk;
+ *tk64++ = v;
+ tk = (uint32_t *)tk64;
+
*tk++ = DOTW;
}
else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
v &= 0xFFFFFFFF;
ln += 2;
*tk++ = CONST;
- *tk++ = 0; // Hi LONG of 64-bits
- *tk++ = v;
+ tk64 = (uint64_t *)tk;
+ *tk64++ = v;
+ tk = (uint32_t *)tk64;
+
*tk++ = DOTL;
}
+ else if ((int)chrtab[*(ln + 1)] & DIGIT)
+ {
+ // Hey, more digits after the dot, so assume it's a
+ // fractional number
+ double fract = 10;
+ ln++;
+ f = (double)v;
+
+ while ((int)chrtab[*ln] & DIGIT)
+ {
+ f = f + (double)(*ln++ - '0') / fract;
+ fract *= 10;
+ }
+
+ *tk++ = FCONST;
+ *((double *)tk) = f;
+ tk += 2;
+ continue;
+ }
}
else
{
*tk++ = CONST;
- *tk++ = v >> 32; // High LONG of 64-bit value
- *tk++ = v & 0xFFFFFFFF; // Low LONG of 64-bit value
+ tk64 = (uint64_t *)tk;
+ *tk64++ = v;
+ tk = (TOKEN *)tk64;
}
//printf("CONST: %i\n", v);
// (Normally) non-printable tokens
#define COLON ':' // : (grumble: GNUmacs hates ':')
#define CONST 'a' // CONST <value>
+#define FCONST 'r' // Floating CONST <value>
#define ACONST 'A' // ACONST <value> <attrib>
#define STRING 'b' // STRING <address>
#define STRINGA8 'S' // Atari 800 internal STRING <address>