# HG changeset patch # User lost # Date 1233383583 0 # Node ID b061350c17e43f368ce1e04cbadbd3affc824b1f # Parent 71561c12b20b1ca8f2ca13473de698c78014673b Added cescapes pragma and a few other compatibility pseudo ops diff -r 71561c12b20b -r b061350c17e4 lwasm/instab.c --- a/lwasm/instab.c Sat Jan 31 06:32:27 2009 +0000 +++ b/lwasm/instab.c Sat Jan 31 06:33:03 2009 +0000 @@ -389,10 +389,27 @@ { ".globl", { -1, -1, -1, -1}, pseudo_export }, { ".module", { -1, -1, -1, -1}, pseudo_noop }, + { ".4byte", { -1, -1, -1, -1}, pseudo_fqb }, + { ".quad", { -1, -1, -1, -1}, pseudo_fqb }, + { ".word", { -1, -1, -1, -1}, pseudo_fdb }, + { ".dw", { -1, -1, -1, -1}, pseudo_fdb }, + { ".byte", { -1, -1, -1, -1}, pseudo_fcb }, + { ".db", { -1, -1, -1, -1}, pseudo_fcb }, + + { ".ascii", { -1, -1, -1, -1}, pseudo_fcc }, + { ".str", { -1, -1, -1, -1}, pseudo_fcc }, + + { ".ascis", { -1, -1, -1, -1}, pseudo_fcs }, + { ".strs", { -1, -1, -1, -1}, pseudo_fcs }, + + { ".asciz", { -1, -1, -1, -1}, pseudo_fcn }, + { ".strz", { -1, -1, -1, -1}, pseudo_fcn }, { ".blkb", { -1, -1, -1, -1}, pseudo_rmb }, + { ".ds", { -1, -1, -1, -1}, pseudo_rmb }, + { ".rs", { -1, -1, -1, -1}, pseudo_rmb }, // needs to handle C escapes maybe? // { ".ascii", { -1, -1, -1, -1}, pseudo_ascii }, diff -r 71561c12b20b -r b061350c17e4 lwasm/lwasm.h --- a/lwasm/lwasm.h Sat Jan 31 06:32:27 2009 +0000 +++ b/lwasm/lwasm.h Sat Jan 31 06:33:03 2009 +0000 @@ -181,7 +181,9 @@ // do not rewrite XXX,r to ,r if XXX evaluates to 0 #define PRAGMA_NOINDEX0TONONE 1 // any undefined symbols are considered external -#define PRAGMA_UNDEFEXTERN 2 +#define PRAGMA_UNDEFEXTERN 2 +// allow C-style escapes in fcc, fcs, and fcn directives +#define PRAGMA_CESCAPES 4 #ifndef __lwasm_c_seen__ #define __lwasm_E__ extern diff -r 71561c12b20b -r b061350c17e4 lwasm/pragma.c --- a/lwasm/pragma.c Sat Jan 31 06:32:27 2009 +0000 +++ b/lwasm/pragma.c Sat Jan 31 06:33:03 2009 +0000 @@ -99,6 +99,14 @@ { as -> pragmas &= ~PRAGMA_UNDEFEXTERN; } + else if (!strcasecmp(pragma, "cescapes")) + { + as -> pragmas |= PRAGMA_CESCAPES; + } + else if (!strcasecmp(pragma, "nocescapes")) + { + as -> pragmas &= ~PRAGMA_CESCAPES; + } else { if (error) diff -r 71561c12b20b -r b061350c17e4 lwasm/pseudo.c --- a/lwasm/pseudo.c Sat Jan 31 06:32:27 2009 +0000 +++ b/lwasm/pseudo.c Sat Jan 31 06:33:03 2009 +0000 @@ -346,9 +346,120 @@ as -> dpval = v & 0xFF; } +// used to get a byte from a string +// -1 is end of line +int pseudo_fcc_fetchchar(asmstate_t *as, char **p) +{ + int c; + + // - + if (!**p) + return -1; + + c = (unsigned char)(**p); + (*p)++; + + if (as -> pragmas & PRAGMA_CESCAPES && c == '\\') + { + // decode escapes if needed + if (!**p) + return c; + + c = **p; + (*p)++; + + switch (c) + { + // octal value + // 1, 2, or 3 digits + // NOTE: \0 for NUL is included in this... + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + c -= '0'; + if (**p < '0' || **p > '9') + return c; + c = c << 3; + c |= **p - '0'; + (*p)++; + if (**p < '0' || **p > '9') + return c; + c = c << 3; + c |= **p - '0'; + (*p)++; + return c; + + // LF + case 'n': + return 10; + + // CR + case 'r': + return 13; + + // TAB + case 't': + return 9; + + // VT + case 'v': + return 11; + + // BS + case 'b': + return 8; + + // FF + case 'f': + return 12; + + // BEL + case 'a': + return 7; + + // hex char code (2 chars) + case 'x': + { + int c2; + if (!**p) + return 'x'; + c = toupper(**p); + (*p)++; + if (c < '0' || (c > '9' && c < 'A') || c > 'F') + return 0; + c -= '0'; + if (c > 9) + c -= 7; + c2 = c << 4; + if (!**p) + return 0; + c = toupper(**p); + (*p)++; + if (c < '0' || (c > '9' && c < 'A') || c > 'F') + return 0; + c -= '0'; + if (c > 9) + c -= 7; + c2 |= c; + return c2; + } + // everything else stands for itself as a fall back or legit + default: + return c; + } + } + return c; +} + OPFUNC(pseudo_fcc) { int delim = 0; + int c; delim = **p; if (!delim) @@ -357,20 +468,22 @@ return; } *p += 1; - while (**p && **p != delim) + for (;;) { - lwasm_emit(as, l, **p); - (*p)++; + c = pseudo_fcc_fetchchar(as, p); + if (c == delim || c < 0) + break; + + lwasm_emit(as, l, c); } - if (**p) - (*p)++; } OPFUNC(pseudo_fcs) { int delim = 0; - + int c, lc = -1; + delim = **p; if (!delim) { @@ -378,22 +491,26 @@ return; } *p += 1; - while (**p && **p != delim) + for (;;) { - if (!*((*p) + 1) || *((*p) + 1) == delim) - lwasm_emit(as, l, **p | 0x80); - else - lwasm_emit(as, l, **p); - (*p)++; + c = pseudo_fcc_fetchchar(as, p); + if (c == delim || c < 0) + { + if (lc >= 0) + lwasm_emit(as, l, lc | 0x80); + break; + } + if (lc >= 0) + lwasm_emit(as, l, lc); + lc = c; } - if (**p) - (*p)++; } OPFUNC(pseudo_fcn) { int delim = 0; - + int c; + delim = **p; if (!delim) { @@ -401,17 +518,17 @@ return; } *p += 1; - while (**p && **p != delim) + for (;;) { - lwasm_emit(as, l, **p); - (*p)++; + c = pseudo_fcc_fetchchar(as, p); + if (c == delim || c < 0) + break; + + lwasm_emit(as, l, c); } - if (**p) - (*p)++; lwasm_emit(as, l, 0); } -// FIXME: handle external, etc., references in a useful manner OPFUNC(pseudo_fcb) { int r, v; @@ -845,12 +962,20 @@ s -> obsize = 0; s -> rl = NULL; s -> exports = NULL; + // if name of section is "bss" or ".bss", assume bss flag + // which can be overridden with !bss flag + if (!strcasecmp(sn, "bss") || !strcasecmp(sn, ".bss")) + s -> flags = SECTION_BSS; // parse options; only one "bss" if (opts && as -> passnum == 1) { if (!strcasecmp(opts, "bss")) { - s -> flags = SECTION_BSS; + s -> flags |= SECTION_BSS; + } + else if (!strcasecmp(opts, "!bss")) + { + s -> flags &= ~SECTION_BSS; } else {