summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2019-08-10 18:04:04 -0700
committerH. Peter Anvin <hpa@zytor.com>2019-08-10 18:04:04 -0700
commitd91519a107d276d1ba891c82550f67b5808451c7 (patch)
treeae6ef2a684809110feccd1408342523588c45101
parent59d4ccc2b06a25e30a4ba0a62ad64905d88e562b (diff)
downloadnasm-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.c5
-rw-r--r--asm/listing.h41
-rw-r--r--asm/nasm.c8
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 */
diff --git a/asm/nasm.c b/asm/nasm.c
index bd6ccf83..c6ff9ec8 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -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;