diff options
author | H. Peter Anvin <hpa@zytor.com> | 2019-08-10 18:04:04 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2019-08-10 18:04:04 -0700 |
commit | d91519a107d276d1ba891c82550f67b5808451c7 (patch) | |
tree | ae6ef2a684809110feccd1408342523588c45101 | |
parent | 59d4ccc2b06a25e30a4ba0a62ad64905d88e562b (diff) | |
download | nasm-d91519a107d276d1ba891c82550f67b5808451c7.tar.gz |
listing: encapsulate the list_options encoding, make more comprehensive
Encapsulate the list_options() encoding in an inline function. We only
ever compute a mask with a non-constant input in two places (command
line and pragma parsing), so a slightly more complex mapping is of no
consequence; thus map a-z, A-Z and 0-9 as being the most likely
characters we may want to use as options. Space is left for two more :)
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | asm/listing.c | 5 | ||||
-rw-r--r-- | asm/listing.h | 41 | ||||
-rw-r--r-- | asm/nasm.c | 8 |
3 files changed, 36 insertions, 18 deletions
diff --git a/asm/listing.c b/asm/listing.c index 224af714..3101a258 100644 --- a/asm/listing.c +++ b/asm/listing.c @@ -412,10 +412,7 @@ static void list_update_options(const char *str) state = false; break; default: - c -= '@'; - if (c > 63) - break; - mask = UINT64_C(1) << c; + mask = list_option_mask(c); if (state) list_options |= mask; else diff --git a/asm/listing.h b/asm/listing.h index 88931556..19cdbb48 100644 --- a/asm/listing.h +++ b/asm/listing.h @@ -125,19 +125,44 @@ extern bool user_nolist; */ extern uint64_t list_options, active_list_options; -static inline bool list_option(char x) +/* + * This maps the characters a-z, A-Z and 0-9 onto a 64-bit bitmask + * (with two bits left over for future use! This isn't particularly + * efficient code, but just about every instance of it should be + * fed a constant, so the entire function can be precomputed at + * compile time. + * + * This returns 0 for invalid values, so that no bit is accessed + * for unsupported characters. + */ +static inline const_func uint64_t list_option_mask(unsigned char x) +{ + if (x >= 'a') { + if (x > 'z') + return 0; + x = x - 'a'; + } else if (x >= 'A') { + if (x > 'Z') + return 0; + x = x - 'A' + 26; + } else if (x >= '0') { + if (x > '9') + return 0; + x = x - '0' + 26*2; + } + + return UINT64_C(1) << x; +} + +static inline pure_func bool list_option(unsigned char x) { - unsigned int p = x - '@'; - if (p > 63) - return false; - return unlikely(active_list_options & (UINT64_C(1) << p)); + return unlikely(active_list_options & list_option_mask(x)); } /* We can't test this using active_list_options for obvious reasons... */ -static inline bool list_on_every_pass(void) +static inline pure_func bool list_on_every_pass(void) { - const unsigned int p = 'p' - '@'; - return unlikely(list_options & (UINT64_C(1) << p)); + return unlikely(list_options & list_option_mask('p')); } /* Pragma handler */ @@ -1011,12 +1011,8 @@ static bool process_arg(char *p, char *q, int pass) case 'L': /* listing options */ if (pass == 2) { - while (*param) { - unsigned int p = *param - '@'; - if (p <= 63) - list_options |= (UINT64_C(1) << p); - param++; - } + while (*param) + list_options |= list_option_mask(*param++); } break; |