From bea0bbb62c9947421bc0fddcd2b58a40435e2181 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 22 Oct 2007 16:53:48 -0700 Subject: [PATCH] More consistent handling of radix letters Allow any radix letter from the set [bydtoqhx] to be used either "Intel-style" (0...x) or "C-style" (0x...). In Intel style, the leading 0 remains optional as long as the first digit is in the range 0-9. As a consequence, allow the prefix "0h" for hexadecimal floating point. --- float.c | 3 +- nasmlib.c | 46 ++++++++++----- stdscan.c | 15 ++--- test/floatx.asm | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/radix.asm | 23 ++++++++ 5 files changed, 235 insertions(+), 23 deletions(-) create mode 100644 test/radix.asm diff --git a/float.c b/float.c index 843dbdfa..a2df323d 100644 --- a/float.c +++ b/float.c @@ -656,7 +656,8 @@ static int to_float(const char *str, int sign, uint8_t * result, break; } } else { - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) + if (str[0] == '0' && + (str[1] == 'x' || str[1] == 'X' || str[1] == 'h' || str[1] == 'H')) ok = ieee_flconvert_hex(str + 2, mant, &exponent); else if (str[0] == '$') ok = ieee_flconvert_hex(str + 1, mant, &exponent); diff --git a/nasmlib.c b/nasmlib.c index 5e43daab..e368a929 100644 --- a/nasmlib.c +++ b/nasmlib.c @@ -196,6 +196,26 @@ char *nasm_strsep(char **stringp, const char *delim) #define lib_isnumchar(c) (isalnum(c) || (c) == '$' || (c) == '_') #define numvalue(c) ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0') +static int radix_letter(char c) +{ + switch (c) { + case 'b': case 'B': + case 'y': case 'Y': + return 2; /* Binary */ + case 'o': case 'O': + case 'q': case 'Q': + return 8; /* Octal */ + case 'h': case 'H': + case 'x': case 'X': + return 16; /* Hexadecimal */ + case 'd': case 'D': + case 't': case 'T': + return 10; /* Decimal */ + default: + return 0; /* Not a known radix letter */ + } +} + int64_t readnum(char *str, bool *error) { char *r = str, *q; @@ -225,24 +245,20 @@ int64_t readnum(char *str, bool *error) q++; /* find end of number */ /* - * If it begins 0x, 0X or $, or ends in H, it's in hex. if it - * ends in Q, it's octal. if it ends in B, it's binary. - * Otherwise, it's ordinary decimal. + * Handle radix formats: + * + * 0 + * $ (hexadecimal) + * */ - if (*r == '0' && (r[1] == 'x' || r[1] == 'X')) - radix = 16, r += 2; + if (*r == '0' && (radix = radix_letter(r[1]))) + r += 2; else if (*r == '$') - radix = 16, r++; - else if (q[-1] == 'H' || q[-1] == 'h') - radix = 16, q--; - else if (q[-1] == 'Q' || q[-1] == 'q' || q[-1] == 'O' || q[-1] == 'o') - radix = 8, q--; - else if (q[-1] == 'B' || q[-1] == 'b' || q[-1] == 'Y' || q[-1] == 'y') - radix = 2, q--; - else if (q[-1] == 'D' || q[-1] == 'd' || q[-1] == 'T' || q[-1] == 't') - radix = 10, q--; + radix = 16, r++; + else if ((radix = radix_letter(q[-1])) != 0) + q--; else - radix = 10; + radix = 10; /* * If this number has been found for us by something other than diff --git a/stdscan.c b/stdscan.c index 9235b08f..dda4e0a3 100644 --- a/stdscan.c +++ b/stdscan.c @@ -119,13 +119,14 @@ int stdscan(void *private_data, struct tokenval *tv) bool is_hex = false; bool is_float = false; bool has_e = false; - bool has_h = false; char c; - r = stdscan_bufptr++; + r = stdscan_bufptr; - if (r[0] == '$' || (r[0] == '0' || (r[1] == 'x' || r[1] == 'X'))) + if (*stdscan_bufptr == '$') { + stdscan_bufptr++; is_hex = true; + } for (;;) { c = *stdscan_bufptr++; @@ -138,9 +139,9 @@ int stdscan(void *private_data, struct tokenval *tv) is_float = true; stdscan_bufptr++; } - } else if (c == 'H' || c == 'h') { - has_h = true; - } else if (is_hex & (c == 'P' || c == 'p')) { + } else if (c == 'H' || c == 'h' || c == 'X' || c == 'x') { + is_hex = true; + } else if (is_hex && (c == 'P' || c == 'p')) { is_float = true; if (*stdscan_bufptr == '+' || *stdscan_bufptr == '-') stdscan_bufptr++; @@ -153,7 +154,7 @@ int stdscan(void *private_data, struct tokenval *tv) } stdscan_bufptr--; /* Point to first character beyond number */ - if (has_e && !has_h) { + if (has_e && !is_hex) { /* 1e13 is floating-point, but 1e13h is not */ is_float = true; } diff --git a/test/floatx.asm b/test/floatx.asm index 22841e6b..127f3535 100644 --- a/test/floatx.asm +++ b/test/floatx.asm @@ -179,6 +179,177 @@ ; 16-bit dw 1.0 + dw 0h1.0 + dw 2.0 + dw 0h2.0 + dw 0h1.0p+1 + dw 0h1.0p-1 + dw 0h0.0 + dw 0h1.23456789 + dw 0h0.123456789 + dw 0h0.0000123456789 + dw 0h1.23456789p10 + dw 0h1.23456789p+10 + dw 0h1.23456789p-10 + dw 0h0.123456789p10 + dw 0h0.123456789p+10 + dw 0h0.123456789abcdef0123456789abcdef012345p-10 + dw 0h0.0000123456789 + dw 0h0.0000123456789p+10 + dw 0h0.0000123456789p-10 + dw 0h1.0p-25 ; Underflow + dw 0h1.0p-24 ; Smallest denorm + dw 0h1.ffffffffffffffffffffffffffffp-16 ; Rounds to denorm + dw 0h1.0p-15 ; Denorm + dw 0h1.ffffffffffffffffffffffffffffp-15 ; Rounds to normal + dw 0h1.0p-14 ; Smallest non-denorm + dw 0h1.0p+15 ; Biggest possible exponent + dw 0h1.ffffffffffffffffffffffffffffp+15 ; Rounds to infinity + dw Inf ; Infinity + dw NaN + +; 32-bit + dd 1.0 + dd 0h1.0 + dd 2.0 + dd 0h2.0 + dd 0h1.0p+1 + dd 0h1.0p-1 + dd 0h0.0 + dd 0h1.23456789 + dd 0h0.123456789 + dd 0h0.0000123456789 + dd 0h1.23456789p10 + dd 0h1.23456789p+10 + dd 0h1.23456789p-10 + dd 0h0.123456789p10 + dd 0h0.123456789p+10 + dd 0h0.123456789abcdef0123456789abcdef012345p-10 + dd 0h0.0000123456789 + dd 0h0.0000123456789p+10 + dd 0h0.0000123456789p-10 + dd 0h123456789.0 + dd 0h0000123456789.0 + dd 0h123456789.0p+0 + dd 0h123456789.0p+64 + dd 0h1.0p-150 ; Underflow + dd 0h1.0p-149 ; Smallest denorm + dd 0h1.ffffffffffffffffffffffffffffp-128 ; Rounds to denorm + dd 0h1.0p-127 ; Denorm + dd 0h1.ffffffffffffffffffffffffffffp-127 ; Rounds to normal + dd 0h1.0p-126 ; Smallest non-denorm + dd 0h1.0p+127 ; Biggest possible exponent + dd 0h1.ffffffffffffffffffffffffffffp+127 ; Rounds to infinity + dd Inf ; Infinity + dd NaN + +; 64-bit + dq 1.0 + dq 0h1.0 + dq 2.0 + dq 0h2.0 + dq 0h1.0p+1 + dq 0h1.0p-1 + dq 0h0.0 + dq 0h1.23456789 + dq 0h0.123456789 + dq 0h0.0000123456789 + dq 0h1.23456789p10 + dq 0h1.23456789p+10 + dq 0h1.23456789p-10 + dq 0h0.123456789p10 + dq 0h0.123456789p+10 + dq 0h0.123456789abcdef0123456789abcdef012345p-10 + dq 0h0.0000123456789 + dq 0h0.0000123456789p+10 + dq 0h0.0000123456789p-10 + dq 0h123456789.0 + dq 0h0000123456789.0 + dq 0h123456789.0p+0 + dq 0h123456789.0p+300 + dq 0h1.0p-1075 ; Underflow + dq 0h1.0p-1074 ; Smallest denorm + dq 0h1.ffffffffffffffffffffffffffffp-1024 ; Rounds to denorm + dq 0h1.0p-1023 ; Denorm + dq 0h1.ffffffffffffffffffffffffffffp-1023 ; Rounds to normal + dq 0h1.0p-1022 ; Smallest non-denorm + dq 0h1.0p+1023 ; Biggest possible exponent + dq 0h1.ffffffffffffffffffffffffffffp+1023 ; Rounds to infinity + dq Inf ; Infinity + dq NaN + +; 80-bit + dt 1.0 + dt 0h1.0 + dt 2.0 + dt 0h2.0 + dt 0h1.0p+1 + dt 0h1.0p-1 + dt 0h0.0 + dt 0h1.23456789 + dt 0h0.123456789 + dt 0h0.0000123456789 + dt 0h1.23456789p10 + dt 0h1.23456789p+10 + dt 0h1.23456789p-10 + dt 0h0.123456789p10 + dt 0h0.123456789p+10 + dt 0h0.123456789abcdef0123456789abcdef012345p-10 + dt 0h0.0000123456789 + dt 0h0.0000123456789p+10 + dt 0h0.0000123456789p-10 + dt 0h123456789.0 + dt 0h0000123456789.0 + dt 0h123456789.0p+0 + dt 0h123456789.0p+1024 + dt 0h1.0p-16446 ; Underflow + dt 0h1.0p-16445 ; Smallest denorm + dt 0h1.ffffffffffffffffffffffffffffp-16384 ; Rounds to denorm + dt 0h1.0p-16383 ; Denorm + dt 0h1.ffffffffffffffffffffffffffffp-16383 ; Rounds to normal + dt 0h1.0p-16382 ; Smallest non-denorm + dt 0h1.0p+16383 ; Biggest possible exponent + dt 0h1.ffffffffffffffffffffffffffffp+16383 ; Rounds to infinity + dt Inf ; Infinity + dt NaN + +; 128-bit + do 1.0 + do 0h1.0 + do 2.0 + do 0h2.0 + do 0h1.0p+1 + do 0h1.0p-1 + do 0h0.0 + do 0h1.23456789 + do 0h0.123456789 + do 0h0.0000123456789 + do 0h1.23456789p10 + do 0h1.23456789p+10 + do 0h1.23456789p-10 + do 0h0.123456789p10 + do 0h0.123456789p+10 + do 0h0.123456789abcdef0123456789abcdef012345p-10 + do 0h0.0000123456789 + do 0h0.0000123456789p+10 + do 0h0.0000123456789p-10 + do 0h123456789.0 + do 0h0000123456789.0 + do 0h123456789.0p+0 + do 0h123456789.0p+1024 + do 0h1.0p-16495 ; Underflow + do 0h1.0p-16494 ; Smallest denorm + do 0h1.ffffffffffffffffffffffffffffffffp-16384 ; Rounds to denorm + do 0h1.0p-16383 ; Denorm + do 0h1.ffffffffffffffffffffffffffffffffp-16383 ; Rounds to normal + do 0h1.0p-16382 ; Smallest non-denorm + do 0h1.0p+16383 ; Biggest possible exponent + do 0h1.ffffffffffffffffffffffffffffffffp+16383 ; Rounds to infinity + do Inf ; Infinity + do NaN + +; 16-bit + dw 1.0 dw $1.0 dw 2.0 dw $2.0 diff --git a/test/radix.asm b/test/radix.asm new file mode 100644 index 00000000..35dbceef --- /dev/null +++ b/test/radix.asm @@ -0,0 +1,23 @@ + dd 1010_0101 ; Decimal + dd 01010_0101 ; Decimal (*not* octal!) + dd 0d1010_0101 ; Decimal + dd 0t1010_0101 ; Decimal + dd 1010_0101d ; Decimal + dd 1010_0101t ; Decimal + + dd 0b1010_0101 ; Binary + dd 0y1010_0101 ; Binary + dd 1010_0101b ; Binary + dd 1010_0101y ; Binary + + dd 0o1010_0101 ; Octal + dd 0q1010_0101 ; Octal + dd 1010_0101o ; Octal + dd 1010_0101q ; Octal + + dd 0h1010_0101 ; Hex + dd 0x1010_0101 ; Hex + dd 1010_0101h ; Hex + dd 1010_0101x ; Hex + dd $1010_0101 ; Hex + \ No newline at end of file -- 2.11.4.GIT