diff options
-rw-r--r-- | nasm.h | 6 | ||||
-rw-r--r-- | parser.c | 2 | ||||
-rw-r--r-- | stdscan.c | 110 | ||||
-rwxr-xr-x | tokhash.pl | 1 |
4 files changed, 54 insertions, 65 deletions
@@ -65,6 +65,7 @@ #endif #define IDLEN_MAX 4096 +#define DECOLEN_MAX 32 /* * Name pollution problems: <time.h> on Digital UNIX pulls in some @@ -421,6 +422,8 @@ extern struct preproc_ops preproc_nop; * identifier. E.g. a period may only appear at the start of an identifier * (for local labels), whereas a number may appear anywhere *but* at the * start. + * isbrcchar matches any character that may placed inside curly braces as a + * decorator. E.g. {rn-sae}, {1to8}, {k1}{z} */ #define isidstart(c) (nasm_isalpha(c) || \ @@ -435,6 +438,9 @@ extern struct preproc_ops preproc_nop; (c) == '#' || \ (c) == '~') +#define isbrcchar(c) (isidchar(c) || \ + (c) == '-') + /* Ditto for numeric constants. */ #define isnumstart(c) (nasm_isdigit(c) || (c) == '$') @@ -200,7 +200,7 @@ static void process_size_override(insn *result, operand *op) * when two or more decorators follow a register operand, * consecutive decorators are parsed here. * opmask and zeroing decorators can be placed in any order. - * e.g. zmm1 {k2}{z} or zmm2 {z,k3} + * e.g. zmm1 {k2}{z} or zmm2 {z}{k3} * decorator(s) are placed at the end of an operand. */ static bool parse_braces(decoflags_t *decoflags) @@ -53,8 +53,6 @@ static char *stdscan_bufptr = NULL; static char **stdscan_tempstorage = NULL; static int stdscan_tempsize = 0, stdscan_templen = 0; -static int brace = 0; /* nested brace counter */ -static bool brace_opened = false; /* if brace is just opened */ #define STDSCAN_TEMP_DELTA 256 void stdscan_set(char *str) @@ -110,7 +108,6 @@ static char *stdscan_copy(char *p, int len) /* * a token is enclosed with braces. proper token type will be assigned * accordingly with the token flag. - * a closing brace is treated as an ending character of corresponding token. */ static int stdscan_handle_brace(struct tokenval *tv) { @@ -126,18 +123,6 @@ static int stdscan_handle_brace(struct tokenval *tv) } } - stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); - - if (stdscan_bufptr[0] == '}') { - stdscan_bufptr ++; /* skip the closing brace */ - brace --; - } else if (stdscan_bufptr[0] != ',') { - /* treat {foo,bar} as {foo}{bar} - * by regarding ',' as a mere separator between decorators - */ - nasm_error(ERR_NONFATAL, "closing brace expected"); - tv->t_type = TOKEN_INVALID; - } return tv->t_type; } @@ -148,23 +133,16 @@ int stdscan(void *private_data, struct tokenval *tv) (void)private_data; /* Don't warn that this parameter is unused */ stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); - if (!*stdscan_bufptr) { - /* nested brace shouldn't affect following lines */ - brace = 0; + if (!*stdscan_bufptr) return tv->t_type = TOKEN_EOS; - } /* we have a token; either an id, a number or a char */ if (isidstart(*stdscan_bufptr) || - (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1])) || - (brace && isidchar(*stdscan_bufptr))) { /* because of {1to8} */ + (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1]))) { /* now we've got an identifier */ bool is_sym = false; int token_type; - /* opening brace is followed by any letter */ - brace_opened = false; - if (*stdscan_bufptr == '$') { is_sym = true; stdscan_bufptr++; @@ -172,8 +150,7 @@ int stdscan(void *private_data, struct tokenval *tv) r = stdscan_bufptr++; /* read the entire buffer to advance the buffer pointer but... */ - /* {rn-sae}, {rd-sae}, {ru-sae}, {rz-sae} contain '-' in tokens. */ - while (isidchar(*stdscan_bufptr) || (brace && *stdscan_bufptr == '-')) + while (isidchar(*stdscan_bufptr)) stdscan_bufptr++; /* ... copy only up to IDLEN_MAX-1 characters */ @@ -190,16 +167,11 @@ int stdscan(void *private_data, struct tokenval *tv) * is it actually a register or instruction name, or what? */ token_type = nasm_token_hash(ourcopy, tv); - if (likely(!brace)) { - if (likely(!(tv->t_flag & TFLAG_BRC))) { - /* most of the tokens fall into this case */ - return token_type; - } else { - return tv->t_type = TOKEN_ID; - } + if (likely(!(tv->t_flag & TFLAG_BRC))) { + /* most of the tokens fall into this case */ + return token_type; } else { - /* handle tokens inside braces */ - return stdscan_handle_brace(tv); + return tv->t_type = TOKEN_ID; } } else if (*stdscan_bufptr == '$' && !isnumchar(stdscan_bufptr[1])) { /* @@ -285,6 +257,45 @@ int stdscan(void *private_data, struct tokenval *tv) return tv->t_type = TOKEN_ERRSTR; stdscan_bufptr++; /* Skip final quote */ return tv->t_type = TOKEN_STR; + } else if (*stdscan_bufptr == '{') { + /* now we've got a decorator */ + int token_len; + + stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); + + r = ++stdscan_bufptr; + /* + * read the entire buffer to advance the buffer pointer + * {rn-sae}, {rd-sae}, {ru-sae}, {rz-sae} contain '-' in tokens. + */ + while (isbrcchar(*stdscan_bufptr)) + stdscan_bufptr++; + + token_len = stdscan_bufptr - r; + + /* ... copy only up to DECOLEN_MAX-1 characters */ + tv->t_charptr = stdscan_copy(r, token_len < DECOLEN_MAX ? + token_len : DECOLEN_MAX - 1); + + stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); + /* if brace is not closed properly or token is too long */ + if ((*stdscan_bufptr != '}') || (token_len > MAX_KEYWORD)) { + nasm_error(ERR_NONFATAL, + "invalid decorator token inside braces"); + return tv->t_type = TOKEN_INVALID; + } + + stdscan_bufptr++; /* skip closing brace */ + + for (s = tv->t_charptr, r = ourcopy; *s; s++) + *r++ = nasm_tolower(*s); + *r = '\0'; + + /* right, so we have a decorator sitting in temp storage. */ + nasm_token_hash(ourcopy, tv); + + /* handle tokens inside braces */ + return stdscan_handle_brace(tv); } else if (*stdscan_bufptr == ';') { /* a comment has happened - stay */ return tv->t_type = TOKEN_EOS; @@ -324,35 +335,6 @@ int stdscan(void *private_data, struct tokenval *tv) } else if (stdscan_bufptr[0] == '|' && stdscan_bufptr[1] == '|') { stdscan_bufptr += 2; return tv->t_type = TOKEN_DBL_OR; - } else if (stdscan_bufptr[0] == '{') { - stdscan_bufptr ++; /* skip the opening brace */ - brace ++; /* in case of nested braces */ - brace_opened = true; /* brace is just opened */ - return stdscan(private_data, tv); - } else if (stdscan_bufptr[0] == ',' && brace) { - /* - * a comma inside braces should be treated just as a separator. - * this is almost same as an opening brace except increasing counter. - */ - stdscan_bufptr ++; - brace_opened = true; /* brace is just opened */ - return stdscan(private_data, tv); - } else if (stdscan_bufptr[0] == '}') { - stdscan_bufptr ++; /* skip the closing brace */ - if (brace) { - /* unhandled nested closing brace */ - brace --; - /* if brace is closed without any content in it */ - if (brace_opened) { - brace_opened = false; - nasm_error(ERR_NONFATAL, "nothing inside braces"); - } - return stdscan(private_data, tv); - } else { - /* redundant closing brace */ - return tv->t_type = TOKEN_INVALID; - } - return stdscan(private_data, tv); } else /* just an ordinary char */ return tv->t_type = (uint8_t)(*stdscan_bufptr++); } @@ -260,6 +260,7 @@ if ($output eq 'h') { print " uint16_t ix;\n"; print " const struct tokendata *data;\n"; print "\n"; + printf " tv->t_flag = 0;\n"; printf " crc = crc64(UINT64_C(0x%08x%08x), token);\n", $$sv[0], $$sv[1]; print " k1 = (uint32_t)crc;\n"; |