/* ----------------------------------------------------------------------- *
- *
+ *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
typedef uint32_t fp_limb;
typedef uint64_t fp_2limb;
-#define LIMB_BITS 32
+#define LIMB_BITS 32
#define LIMB_BYTES (LIMB_BITS/8)
-#define LIMB_TOP_BIT ((fp_limb)1 << (LIMB_BITS-1))
-#define LIMB_MASK ((fp_limb)(~0))
-#define LIMB_ALL_BYTES ((fp_limb)0x01010101)
-#define LIMB_BYTE(x) ((x)*LIMB_ALL_BYTES)
+#define LIMB_TOP_BIT ((fp_limb)1 << (LIMB_BITS-1))
+#define LIMB_MASK ((fp_limb)(~0))
+#define LIMB_ALL_BYTES ((fp_limb)0x01010101)
+#define LIMB_BYTE(x) ((x)*LIMB_ALL_BYTES)
/* 112 bits + 64 bits for accuracy + 16 bits for rounding */
#define MANT_LIMBS 6
#define MANT_FMT "%08x_%08x_%08x_%08x_%08x_%08x"
#define MANT_ARG SOME_ARG(mant, 0)
-#define SOME_ARG(a,i) (a)[(i)+0], (a)[(i)+1], (a)[(i)+2], (a)[(i)+3], \
- (a)[(i)+4], (a)[(i)+5]
+#define SOME_ARG(a,i) (a)[(i)+0], (a)[(i)+1], (a)[(i)+2], \
+ (a)[(i)+3], (a)[(i)+4], (a)[(i)+5]
/*
* ---------------------------------------------------------------------------
#ifdef DEBUG_FLOAT
#define dprintf(x) printf x
-#else /* */
+#else
#define dprintf(x) do { } while (0)
-#endif /* */
+#endif
/*
* ---------------------------------------------------------------------------
bool neg = false;
if (*string == '+') {
- string++;
+ string++;
} else if (*string == '-') {
- neg = true;
- string++;
+ neg = true;
+ string++;
}
while (*string) {
- if (*string >= '0' && *string <= '9') {
- i = (i * 10) + (*string - '0');
-
- /*
- * To ensure that underflows and overflows are
- * handled properly we must avoid wraparounds of
- * the signed integer value that is used to hold
- * the exponent. Therefore we cap the exponent at
- * +/-5000, which is slightly more/less than
- * what's required for normal and denormal numbers
- * in single, double, and extended precision, but
- * sufficient to avoid signed integer wraparound.
- */
- if (i > max)
- i = max;
- } else if (*string == '_') {
- /* do nothing */
- } else {
- error(ERR_NONFATAL|ERR_PASS1,
- "invalid character in floating-point constant %s: '%c'",
- "exponent", *string);
- return INT32_MAX;
- }
- string++;
+ if (*string >= '0' && *string <= '9') {
+ i = (i * 10) + (*string - '0');
+
+ /*
+ * To ensure that underflows and overflows are
+ * handled properly we must avoid wraparounds of
+ * the signed integer value that is used to hold
+ * the exponent. Therefore we cap the exponent at
+ * +/-5000, which is slightly more/less than
+ * what's required for normal and denormal numbers
+ * in single, double, and extended precision, but
+ * sufficient to avoid signed integer wraparound.
+ */
+ if (i > max)
+ i = max;
+ } else if (*string == '_') {
+ /* do nothing */
+ } else {
+ error(ERR_NONFATAL|ERR_PASS1,
+ "invalid character in floating-point constant %s: '%c'",
+ "exponent", *string);
+ return INT32_MAX;
+ }
+ string++;
}
return neg ? -i : i;
}
if (*string) {
- int32_t e;
+ int32_t e;
string++; /* eat the E */
- e = read_exponent(string, 5000);
- if (e == INT32_MAX)
- return false;
- tenpwr += e;
+ e = read_exponent(string, 5000);
+ if (e == INT32_MAX)
+ return false;
+ tenpwr += e;
}
/*
int i;
for (i = 0; i < MANT_LIMBS; i++)
- if (mant[i])
- return false;
+ if (mant[i])
+ return false;
return true;
}
* ---------------------------------------------------------------------------
*/
-#define ROUND_COLLECT_BITS \
- do { \
- m = mant[i] & (2*bit-1); \
- for (j = i+1; j < MANT_LIMBS; j++) \
- m = m | mant[j]; \
+#define ROUND_COLLECT_BITS \
+ do { \
+ m = mant[i] & (2*bit-1); \
+ for (j = i+1; j < MANT_LIMBS; j++) \
+ m = m | mant[j]; \
} while (0)
-#define ROUND_ABS_DOWN \
- do { \
- mant[i] &= ~(bit-1); \
- for (j = i+1; j < MANT_LIMBS; j++) \
- mant[j] = 0; \
- return false; \
+#define ROUND_ABS_DOWN \
+ do { \
+ mant[i] &= ~(bit-1); \
+ for (j = i+1; j < MANT_LIMBS; j++) \
+ mant[j] = 0; \
+ return false; \
} while (0)
-#define ROUND_ABS_UP \
- do { \
- mant[i] = (mant[i] & ~(bit-1)) + bit; \
- for (j = i+1; j < MANT_LIMBS; j++) \
- mant[j] = 0; \
- while (i > 0 && !mant[i]) \
- ++mant[--i]; \
- return !mant[0]; \
+#define ROUND_ABS_UP \
+ do { \
+ mant[i] = (mant[i] & ~(bit-1)) + bit; \
+ for (j = i+1; j < MANT_LIMBS; j++) \
+ mant[j] = 0; \
+ while (i > 0 && !mant[i]) \
+ ++mant[--i]; \
+ return !mant[0]; \
} while (0)
static bool ieee_round(bool minus, fp_limb *mant, int bits)
fp_limb bit = LIMB_TOP_BIT >> p;
if (rc == FLOAT_RC_NEAR) {
- if (mant[i] & bit) {
- mant[i] &= ~bit;
- ROUND_COLLECT_BITS;
- mant[i] |= bit;
- if (m) {
- ROUND_ABS_UP;
- } else {
- if (test_bit(mant, bits-1)) {
- ROUND_ABS_UP;
- } else {
- ROUND_ABS_DOWN;
- }
- }
- } else {
- ROUND_ABS_DOWN;
- }
+ if (mant[i] & bit) {
+ mant[i] &= ~bit;
+ ROUND_COLLECT_BITS;
+ mant[i] |= bit;
+ if (m) {
+ ROUND_ABS_UP;
+ } else {
+ if (test_bit(mant, bits-1)) {
+ ROUND_ABS_UP;
+ } else {
+ ROUND_ABS_DOWN;
+ }
+ }
+ } else {
+ ROUND_ABS_DOWN;
+ }
} else if (rc == FLOAT_RC_ZERO ||
- rc == (minus ? FLOAT_RC_UP : FLOAT_RC_DOWN)) {
- ROUND_ABS_DOWN;
+ rc == (minus ? FLOAT_RC_UP : FLOAT_RC_DOWN)) {
+ ROUND_ABS_DOWN;
} else {
- /* rc == (minus ? FLOAT_RC_DOWN : FLOAT_RC_UP) */
- /* Round toward +/- infinity */
- ROUND_COLLECT_BITS;
- if (m) {
- ROUND_ABS_UP;
- } else {
- ROUND_ABS_DOWN;
- }
+ /* rc == (minus ? FLOAT_RC_DOWN : FLOAT_RC_UP) */
+ /* Round toward +/- infinity */
+ ROUND_COLLECT_BITS;
+ if (m) {
+ ROUND_ABS_UP;
+ } else {
+ ROUND_ABS_DOWN;
+ }
}
return false;
}
/* Handle floating-point numbers with radix 2^bits and binary exponent */
static bool ieee_flconvert_bin(const char *string, int bits,
- fp_limb *mant, int32_t *exponent)
+ fp_limb *mant, int32_t *exponent)
{
static const int log2tbl[16] =
{ -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
twopwr -= bits;
}
} else if (c == 'p' || c == 'P') {
- int32_t e;
- e = read_exponent(string, 20000);
- if (e == INT32_MAX)
- return false;
- twopwr += e;
+ int32_t e;
+ e = read_exponent(string, 20000);
+ if (e == INT32_MAX)
+ return false;
+ twopwr += e;
break;
- } else if (c == '_') {
- /* ignore */
+ } else if (c == '_') {
+ /* ignore */
} else {
error(ERR_NONFATAL|ERR_PASS1,
"floating-point constant: `%c' is invalid character", c);
offs = i/LIMB_BITS;
if (sr == 0) {
- if (offs)
- for (j = MANT_LIMBS-1; j >= offs; j--)
- mant[j] = mant[j-offs];
+ if (offs)
+ for (j = MANT_LIMBS-1; j >= offs; j--)
+ mant[j] = mant[j-offs];
} else {
- n = mant[MANT_LIMBS-1-offs] >> sr;
- for (j = MANT_LIMBS-1; j > offs; j--) {
- m = mant[j-offs-1];
- mant[j] = (m << sl) | n;
- n = m >> sr;
- }
- mant[j--] = n;
+ n = mant[MANT_LIMBS-1-offs] >> sr;
+ for (j = MANT_LIMBS-1; j > offs; j--) {
+ m = mant[j-offs-1];
+ mant[j] = (m << sl) | n;
+ n = m >> sr;
+ }
+ mant[j--] = n;
}
while (j >= 0)
- mant[j--] = 0;
+ mant[j--] = 0;
}
/* Produce standard IEEE formats, with implicit or explicit integer
struct ieee_format {
int bytes;
int mantissa; /* Fractional bits in the mantissa */
- int explicit; /* Explicit integer */
+ int explicit; /* Explicit integer */
int exponent; /* Bits in the exponent */
};
};
static int to_packed_bcd(const char *str, const char *p,
- int s, uint8_t *result,
- const struct ieee_format *fmt)
+ int s, uint8_t *result,
+ const struct ieee_format *fmt)
{
int n = 0;
char c;
int tv = -1;
if (fmt != &ieee_80) {
- error(ERR_NONFATAL|ERR_PASS1,
- "packed BCD requires an 80-bit format");
- return 0;
+ error(ERR_NONFATAL|ERR_PASS1,
+ "packed BCD requires an 80-bit format");
+ return 0;
}
while (p >= str) {
- c = *p--;
- if (c >= '0' && c <= '9') {
- if (tv < 0) {
- if (n == 9) {
- error(ERR_WARNING|ERR_PASS1,
- "packed BCD truncated to 18 digits");
- }
- tv = c-'0';
- } else {
- if (n < 9)
- *result++ = tv + ((c-'0') << 4);
- n++;
- tv = -1;
- }
- } else if (c == '_') {
- /* do nothing */
- } else {
- error(ERR_NONFATAL|ERR_PASS1,
- "invalid character `%c' in packed BCD constant", c);
- return 0;
- }
+ c = *p--;
+ if (c >= '0' && c <= '9') {
+ if (tv < 0) {
+ if (n == 9) {
+ error(ERR_WARNING|ERR_PASS1,
+ "packed BCD truncated to 18 digits");
+ }
+ tv = c-'0';
+ } else {
+ if (n < 9)
+ *result++ = tv + ((c-'0') << 4);
+ n++;
+ tv = -1;
+ }
+ } else if (c == '_') {
+ /* do nothing */
+ } else {
+ error(ERR_NONFATAL|ERR_PASS1,
+ "invalid character `%c' in packed BCD constant", c);
+ return 0;
+ }
}
if (tv >= 0) {
- if (n < 9)
- *result++ = tv;
- n++;
+ if (n < 9)
+ *result++ = tv;
+ n++;
}
while (n < 9) {
- *result++ = 0;
- n++;
+ *result++ = 0;
+ n++;
}
*result = (s < 0) ? 0x80 : 0;
- return 1; /* success */
+ return 1; /* success */
}
static int to_float(const char *str, int s, uint8_t *result,
int32_t exponent = 0;
const int32_t expmax = 1 << (fmt->exponent - 1);
fp_limb one_mask = LIMB_TOP_BIT >>
- ((fmt->exponent+fmt->explicit) % LIMB_BITS);
+ ((fmt->exponent+fmt->explicit) % LIMB_BITS);
const int one_pos = (fmt->exponent+fmt->explicit)/LIMB_BITS;
int i;
int shift;
const char *strend;
if (!str[0]) {
- error(ERR_PANIC,
- "internal errror: empty string passed to float_const");
- return 0;
+ error(ERR_PANIC,
+ "internal errror: empty string passed to float_const");
+ return 0;
}
strend = strchr(str, '\0');
if (strend[-1] == 'P' || strend[-1] == 'p')
- return to_packed_bcd(str, strend-2, s, result, fmt);
+ return to_packed_bcd(str, strend-2, s, result, fmt);
if (str[0] == '_') {
- /* Special tokens */
+ /* Special tokens */
switch (str[2]) {
case 'n': /* __nan__ */
case 'N':
case 'q': /* __qnan__ */
case 'Q':
- type = FL_QNAN;
+ type = FL_QNAN;
break;
case 's': /* __snan__ */
case 'S':
- type = FL_SNAN;
+ type = FL_SNAN;
break;
case 'i': /* __infinity__ */
case 'I':
- type = FL_INFINITY;
+ type = FL_INFINITY;
+ break;
+ default:
+ error(ERR_NONFATAL|ERR_PASS1,
+ "internal error: unknown FP constant token `%s'\n", str);
+ type = FL_QNAN;
break;
- default:
- error(ERR_NONFATAL|ERR_PASS1,
- "internal error: unknown FP constant token `%s'\n", str);
- type = FL_QNAN;
- break;
}
} else {
if (str[0] == '0') {
- switch (str[1]) {
- case 'x': case 'X':
- case 'h': case 'H':
- ok = ieee_flconvert_bin(str+2, 4, mant, &exponent);
- break;
- case 'o': case 'O':
- case 'q': case 'Q':
- ok = ieee_flconvert_bin(str+2, 3, mant, &exponent);
- break;
- case 'b': case 'B':
- case 'y': case 'Y':
- ok = ieee_flconvert_bin(str+2, 1, mant, &exponent);
- break;
- case 'd': case 'D':
- case 't': case 'T':
- ok = ieee_flconvert(str+2, mant, &exponent);
- break;
- case 'p': case 'P':
- return to_packed_bcd(str+2, strend-1, s, result, fmt);
- default:
- /* Leading zero was just a zero? */
- ok = ieee_flconvert(str, mant, &exponent);
- break;
- }
- } else if (str[0] == '$') {
- ok = ieee_flconvert_bin(str+1, 4, mant, &exponent);
- } else {
+ switch (str[1]) {
+ case 'x': case 'X':
+ case 'h': case 'H':
+ ok = ieee_flconvert_bin(str+2, 4, mant, &exponent);
+ break;
+ case 'o': case 'O':
+ case 'q': case 'Q':
+ ok = ieee_flconvert_bin(str+2, 3, mant, &exponent);
+ break;
+ case 'b': case 'B':
+ case 'y': case 'Y':
+ ok = ieee_flconvert_bin(str+2, 1, mant, &exponent);
+ break;
+ case 'd': case 'D':
+ case 't': case 'T':
+ ok = ieee_flconvert(str+2, mant, &exponent);
+ break;
+ case 'p': case 'P':
+ return to_packed_bcd(str+2, strend-1, s, result, fmt);
+ default:
+ /* Leading zero was just a zero? */
+ ok = ieee_flconvert(str, mant, &exponent);
+ break;
+ }
+ } else if (str[0] == '$') {
+ ok = ieee_flconvert_bin(str+1, 4, mant, &exponent);
+ } else {
ok = ieee_flconvert(str, mant, &exponent);
- }
+ }
- if (!ok) {
- type = FL_QNAN;
- } else if (mant[0] & LIMB_TOP_BIT) {
+ if (!ok) {
+ type = FL_QNAN;
+ } else if (mant[0] & LIMB_TOP_BIT) {
/*
* Non-zero.
*/
exponent--;
if (exponent >= 2 - expmax && exponent <= expmax) {
- type = FL_NORMAL;
+ type = FL_NORMAL;
} else if (exponent > 0) {
- if (pass0 == 1)
- error(ERR_WARNING|ERR_WARN_FL_OVERFLOW|ERR_PASS1,
- "overflow in floating-point constant");
- type = FL_INFINITY;
- } else {
- /* underflow or denormal; the denormal code handles
- actual underflow. */
- type = FL_DENORMAL;
- }
- } else {
- /* Zero */
- type = FL_ZERO;
- }
+ if (pass0 == 1)
+ error(ERR_WARNING|ERR_WARN_FL_OVERFLOW|ERR_PASS1,
+ "overflow in floating-point constant");
+ type = FL_INFINITY;
+ } else {
+ /* underflow or denormal; the denormal code handles
+ actual underflow. */
+ type = FL_DENORMAL;
+ }
+ } else {
+ /* Zero */
+ type = FL_ZERO;
+ }
}
switch (type) {
case FL_ZERO:
zero:
- memset(mant, 0, sizeof mant);
- break;
+ memset(mant, 0, sizeof mant);
+ break;
case FL_DENORMAL:
{
- shift = -(exponent + expmax - 2 - fmt->exponent)
- + fmt->explicit;
- ieee_shr(mant, shift);
- ieee_round(minus, mant, bits);
- if (mant[one_pos] & one_mask) {
- /* One's position is set, we rounded up into normal range */
- exponent = 1;
- if (!fmt->explicit)
- mant[one_pos] &= ~one_mask; /* remove explicit one */
- mant[0] |= exponent << (LIMB_BITS-1 - fmt->exponent);
- } else {
- if (daz || is_zero(mant)) {
- /* Flush denormals to zero */
- error(ERR_WARNING|ERR_WARN_FL_UNDERFLOW|ERR_PASS1,
- "underflow in floating-point constant");
- goto zero;
- } else {
- error(ERR_WARNING|ERR_WARN_FL_DENORM|ERR_PASS1,
- "denormal floating-point constant");
- }
- }
- break;
+ shift = -(exponent + expmax - 2 - fmt->exponent)
+ + fmt->explicit;
+ ieee_shr(mant, shift);
+ ieee_round(minus, mant, bits);
+ if (mant[one_pos] & one_mask) {
+ /* One's position is set, we rounded up into normal range */
+ exponent = 1;
+ if (!fmt->explicit)
+ mant[one_pos] &= ~one_mask; /* remove explicit one */
+ mant[0] |= exponent << (LIMB_BITS-1 - fmt->exponent);
+ } else {
+ if (daz || is_zero(mant)) {
+ /* Flush denormals to zero */
+ error(ERR_WARNING|ERR_WARN_FL_UNDERFLOW|ERR_PASS1,
+ "underflow in floating-point constant");
+ goto zero;
+ } else {
+ error(ERR_WARNING|ERR_WARN_FL_DENORM|ERR_PASS1,
+ "denormal floating-point constant");
+ }
+ }
+ break;
}
case FL_NORMAL:
- exponent += expmax - 1;
- ieee_shr(mant, fmt->exponent+fmt->explicit);
- ieee_round(minus, mant, bits);
- /* did we scale up by one? */
- if (test_bit(mant, fmt->exponent+fmt->explicit-1)) {
- ieee_shr(mant, 1);
- exponent++;
- if (exponent >= (expmax << 1)-1) {
- error(ERR_WARNING|ERR_WARN_FL_OVERFLOW|ERR_PASS1,
- "overflow in floating-point constant");
- type = FL_INFINITY;
- goto overflow;
- }
- }
-
- if (!fmt->explicit)
- mant[one_pos] &= ~one_mask; /* remove explicit one */
- mant[0] |= exponent << (LIMB_BITS-1 - fmt->exponent);
- break;
+ exponent += expmax - 1;
+ ieee_shr(mant, fmt->exponent+fmt->explicit);
+ ieee_round(minus, mant, bits);
+ /* did we scale up by one? */
+ if (test_bit(mant, fmt->exponent+fmt->explicit-1)) {
+ ieee_shr(mant, 1);
+ exponent++;
+ if (exponent >= (expmax << 1)-1) {
+ error(ERR_WARNING|ERR_WARN_FL_OVERFLOW|ERR_PASS1,
+ "overflow in floating-point constant");
+ type = FL_INFINITY;
+ goto overflow;
+ }
+ }
+
+ if (!fmt->explicit)
+ mant[one_pos] &= ~one_mask; /* remove explicit one */
+ mant[0] |= exponent << (LIMB_BITS-1 - fmt->exponent);
+ break;
case FL_INFINITY:
case FL_QNAN:
case FL_SNAN:
overflow:
- memset(mant, 0, sizeof mant);
- mant[0] = (((fp_limb)1 << fmt->exponent)-1)
- << (LIMB_BITS-1 - fmt->exponent);
- if (fmt->explicit)
- mant[one_pos] |= one_mask;
- if (type == FL_QNAN)
- set_bit(mant, fmt->exponent+fmt->explicit+1);
- else if (type == FL_SNAN)
- set_bit(mant, fmt->exponent+fmt->explicit+fmt->mantissa);
- break;
+ memset(mant, 0, sizeof mant);
+ mant[0] = (((fp_limb)1 << fmt->exponent)-1)
+ << (LIMB_BITS-1 - fmt->exponent);
+ if (fmt->explicit)
+ mant[one_pos] |= one_mask;
+ if (type == FL_QNAN)
+ set_bit(mant, fmt->exponent+fmt->explicit+1);
+ else if (type == FL_SNAN)
+ set_bit(mant, fmt->exponent+fmt->explicit+fmt->mantissa);
+ break;
}
mant[0] |= minus ? LIMB_TOP_BIT : 0;
for (i = fmt->bytes - 1; i >= 0; i--)
- *result++ = mant[i/LIMB_BYTES] >> (((LIMB_BYTES-1)-(i%LIMB_BYTES))*8);
+ *result++ = mant[i/LIMB_BYTES] >> (((LIMB_BYTES-1)-(i%LIMB_BYTES))*8);
return 1; /* success */
}
int float_option(const char *option)
{
if (!nasm_stricmp(option, "daz")) {
- daz = true;
- return 0;
+ daz = true;
+ return 0;
} else if (!nasm_stricmp(option, "nodaz")) {
- daz = false;
- return 0;
+ daz = false;
+ return 0;
} else if (!nasm_stricmp(option, "near")) {
- rc = FLOAT_RC_NEAR;
- return 0;
+ rc = FLOAT_RC_NEAR;
+ return 0;
} else if (!nasm_stricmp(option, "down")) {
- rc = FLOAT_RC_DOWN;
- return 0;
+ rc = FLOAT_RC_DOWN;
+ return 0;
} else if (!nasm_stricmp(option, "up")) {
- rc = FLOAT_RC_UP;
- return 0;
+ rc = FLOAT_RC_UP;
+ return 0;
} else if (!nasm_stricmp(option, "zero")) {
- rc = FLOAT_RC_ZERO;
- return 0;
+ rc = FLOAT_RC_ZERO;
+ return 0;
} else if (!nasm_stricmp(option, "default")) {
- rc = FLOAT_RC_NEAR;
- daz = false;
- return 0;
+ rc = FLOAT_RC_NEAR;
+ daz = false;
+ return 0;
} else {
- return -1; /* Unknown option */
+ return -1; /* Unknown option */
}
}
/* ----------------------------------------------------------------------- *
- *
+ *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#include "nasm.h"
#include "hashtbl.h"
-#define HASH_MAX_LOAD 2 /* Higher = more memory-efficient, slower */
+#define HASH_MAX_LOAD 2 /* Higher = more memory-efficient, slower */
static struct hash_tbl_node *alloc_table(size_t newsize)
{
* structure.
*/
void **hash_find(struct hash_table *head, const char *key,
- struct hash_insert *insert)
+ struct hash_insert *insert)
{
struct hash_tbl_node *np;
uint64_t hash = crc64(CRC64_INIT, key);
struct hash_tbl_node *tbl = head->table;
size_t mask = head->size-1;
size_t pos = hash & mask;
- size_t inc = ((hash >> 32) & mask) | 1; /* Always odd */
+ size_t inc = ((hash >> 32) & mask) | 1; /* Always odd */
while ((np = &tbl[pos])->key) {
- if (hash == np->hash && !strcmp(key, np->key))
- return &np->data;
- pos = (pos+inc) & mask;
+ if (hash == np->hash && !strcmp(key, np->key))
+ return &np->data;
+ pos = (pos+inc) & mask;
}
/* Not found. Store info for insert if requested. */
if (insert) {
- insert->head = head;
- insert->hash = hash;
- insert->where = np;
+ insert->head = head;
+ insert->hash = hash;
+ insert->where = np;
}
return NULL;
}
* Same as hash_find, but for case-insensitive hashing.
*/
void **hash_findi(struct hash_table *head, const char *key,
- struct hash_insert *insert)
+ struct hash_insert *insert)
{
struct hash_tbl_node *np;
uint64_t hash = crc64i(CRC64_INIT, key);
struct hash_tbl_node *tbl = head->table;
size_t mask = head->size-1;
size_t pos = hash & mask;
- size_t inc = ((hash >> 32) & mask) | 1; /* Always odd */
+ size_t inc = ((hash >> 32) & mask) | 1; /* Always odd */
while ((np = &tbl[pos])->key) {
- if (hash == np->hash && !nasm_stricmp(key, np->key))
- return &np->data;
- pos = (pos+inc) & mask;
+ if (hash == np->hash && !nasm_stricmp(key, np->key))
+ return &np->data;
+ pos = (pos+inc) & mask;
}
/* Not found. Store info for insert if requested. */
if (insert) {
- insert->head = head;
- insert->hash = hash;
- insert->where = np;
+ insert->head = head;
+ insert->hash = hash;
+ insert->where = np;
}
return NULL;
}
np->data = data;
if (++head->load > head->max_load) {
- /* Need to expand the table */
- size_t newsize = head->size << 1;
- struct hash_tbl_node *newtbl = alloc_table(newsize);
- size_t mask = newsize-1;
-
- if (head->table) {
- struct hash_tbl_node *op, *xp;
- size_t i;
-
- /* Rebalance all the entries */
- for (i = 0, op = head->table; i < head->size; i++, op++) {
- if (op->key) {
- size_t pos = op->hash & mask;
- size_t inc = ((op->hash >> 32) & mask) | 1;
-
- while ((xp = &newtbl[pos])->key)
- pos = (pos+inc) & mask;
-
- *xp = *op;
- if (op == np)
- np = xp;
- }
- }
- nasm_free(head->table);
- }
-
- head->table = newtbl;
- head->size = newsize;
- head->max_load = newsize*(HASH_MAX_LOAD-1)/HASH_MAX_LOAD;
+ /* Need to expand the table */
+ size_t newsize = head->size << 1;
+ struct hash_tbl_node *newtbl = alloc_table(newsize);
+ size_t mask = newsize-1;
+
+ if (head->table) {
+ struct hash_tbl_node *op, *xp;
+ size_t i;
+
+ /* Rebalance all the entries */
+ for (i = 0, op = head->table; i < head->size; i++, op++) {
+ if (op->key) {
+ size_t pos = op->hash & mask;
+ size_t inc = ((op->hash >> 32) & mask) | 1;
+
+ while ((xp = &newtbl[pos])->key)
+ pos = (pos+inc) & mask;
+
+ *xp = *op;
+ if (op == np)
+ np = xp;
+ }
+ }
+ nasm_free(head->table);
+ }
+
+ head->table = newtbl;
+ head->size = newsize;
+ head->max_load = newsize*(HASH_MAX_LOAD-1)/HASH_MAX_LOAD;
}
return &np->data;
* or NULL on failure.
*/
void *hash_iterate(const struct hash_table *head,
- struct hash_tbl_node **iterator,
- const char **key)
+ struct hash_tbl_node **iterator,
+ const char **key)
{
struct hash_tbl_node *np = *iterator;
struct hash_tbl_node *ep = head->table + head->size;
if (!np) {
- np = head->table;
- if (!np)
- return NULL; /* Uninitialized table */
+ np = head->table;
+ if (!np)
+ return NULL; /* Uninitialized table */
}
while (np < ep) {
- if (np->key) {
- *iterator = np+1;
- if (key)
- *key = np->key;
- return np->data;
- }
- np++;
+ if (np->key) {
+ *iterator = np+1;
+ if (key)
+ *key = np->key;
+ return np->data;
+ }
+ np++;
}
*iterator = NULL;
if (key)
- *key = NULL;
+ *key = NULL;
return NULL;
}
/* ----------------------------------------------------------------------- *
- *
+ *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
*
* ----------------------------------------------------------------------- */
-/*
- * nasmlib.h header file for nasmlib.c
+/*
+ * nasmlib.h header file for nasmlib.c
*/
#ifndef NASM_NASMLIB_H
* argument to an efunc.
*/
-#define ERR_DEBUG 0x00000008 /* put out debugging message */
-#define ERR_WARNING 0x00000000 /* warn only: no further action */
-#define ERR_NONFATAL 0x00000001 /* terminate assembly after phase */
-#define ERR_FATAL 0x00000002 /* instantly fatal: exit with error */
-#define ERR_PANIC 0x00000003 /* internal error: panic instantly
+#define ERR_DEBUG 0x00000008 /* put out debugging message */
+#define ERR_WARNING 0x00000000 /* warn only: no further action */
+#define ERR_NONFATAL 0x00000001 /* terminate assembly after phase */
+#define ERR_FATAL 0x00000002 /* instantly fatal: exit with error */
+#define ERR_PANIC 0x00000003 /* internal error: panic instantly
* and dump core for reference */
-#define ERR_MASK 0x0000000F /* mask off the above codes */
-#define ERR_NOFILE 0x00000010 /* don't give source file name/line */
-#define ERR_USAGE 0x00000020 /* print a usage message */
-#define ERR_PASS1 0x00000040 /* only print this error on pass one */
-#define ERR_PASS2 0x00000080
-#define ERR_NO_SEVERITY 0x00000100 /* suppress printing severity */
+#define ERR_MASK 0x0000000F /* mask off the above codes */
+#define ERR_NOFILE 0x00000010 /* don't give source file name/line */
+#define ERR_USAGE 0x00000020 /* print a usage message */
+#define ERR_PASS1 0x00000040 /* only print this error on pass one */
+#define ERR_PASS2 0x00000080
+#define ERR_NO_SEVERITY 0x00000100 /* suppress printing severity */
/*
* These codes define specific types of suppressible warning.
*/
-#define ERR_WARN_MASK 0xFFFFF000 /* the mask for this feature */
-#define ERR_WARN_SHR 12 /* how far to shift right */
+#define ERR_WARN_MASK 0xFFFFF000 /* the mask for this feature */
+#define ERR_WARN_SHR 12 /* how far to shift right */
#define WARN(x) ((x) << ERR_WARN_SHR)
-#define ERR_WARN_MNP WARN( 1) /* macro-num-parameters warning */
-#define ERR_WARN_MSR WARN( 2) /* macro self-reference */
-#define ERR_WARN_MDP WARN( 3) /* macro default parameters check */
-#define ERR_WARN_OL WARN( 4) /* orphan label (no colon, and
+#define ERR_WARN_MNP WARN( 1) /* macro-num-parameters warning */
+#define ERR_WARN_MSR WARN( 2) /* macro self-reference */
+#define ERR_WARN_MDP WARN( 3) /* macro default parameters check */
+#define ERR_WARN_OL WARN( 4) /* orphan label (no colon, and
* alone on line) */
-#define ERR_WARN_NOV WARN( 5) /* numeric overflow */
-#define ERR_WARN_GNUELF WARN( 6) /* using GNU ELF extensions */
-#define ERR_WARN_FL_OVERFLOW WARN( 7) /* FP overflow */
-#define ERR_WARN_FL_DENORM WARN( 8) /* FP denormal */
-#define ERR_WARN_FL_UNDERFLOW WARN( 9) /* FP underflow */
-#define ERR_WARN_FL_TOOLONG WARN(10) /* FP too many digits */
-#define ERR_WARN_USER WARN(11) /* %warning directives */
-#define ERR_WARN_MAX 11 /* the highest numbered one */
+#define ERR_WARN_NOV WARN( 5) /* numeric overflow */
+#define ERR_WARN_GNUELF WARN( 6) /* using GNU ELF extensions */
+#define ERR_WARN_FL_OVERFLOW WARN( 7) /* FP overflow */
+#define ERR_WARN_FL_DENORM WARN( 8) /* FP denormal */
+#define ERR_WARN_FL_UNDERFLOW WARN( 9) /* FP underflow */
+#define ERR_WARN_FL_TOOLONG WARN(10) /* FP too many digits */
+#define ERR_WARN_USER WARN(11) /* %warning directives */
+#define ERR_WARN_MAX 11 /* the highest numbered one */
/*
* Wrappers around malloc, realloc and free. nasm_malloc will
* NASM assert failure
*/
no_return nasm_assert_failed(const char *, int, const char *);
-#define nasm_assert(x) \
- do { \
- if (unlikely(!(x))) \
- nasm_assert_failed(__FILE__,__LINE__,#x); \
+#define nasm_assert(x) \
+ do { \
+ if (unlikely(!(x))) \
+ nasm_assert_failed(__FILE__,__LINE__,#x); \
} while (0)
/*
* list_for_each - regular iterator over list
* list_for_each_safe - the same but safe against list items removal
*/
-#define list_for_each(pos, head) \
- for (pos = head; pos; pos = pos->next)
-#define list_for_each_safe(pos, n, head) \
- for (pos = head, n = (pos ? pos->next : NULL); pos; \
- pos = n, n = (n ? n->next : NULL))
+#define list_for_each(pos, head) \
+ for (pos = head; pos; pos = pos->next)
+#define list_for_each_safe(pos, n, head) \
+ for (pos = head, n = (pos ? pos->next : NULL); pos; \
+ pos = n, n = (n ? n->next : NULL))
/*
* some handy macros that will probably be of use in more than one
#if X86_MEMORY
-#define WRITECHAR(p,v) \
- do { \
- *(uint8_t *)(p) = (v); \
- (p) += 1; \
+#define WRITECHAR(p,v) \
+ do { \
+ *(uint8_t *)(p) = (v); \
+ (p) += 1; \
} while (0)
-#define WRITESHORT(p,v) \
- do { \
- *(uint16_t *)(p) = (v); \
- (p) += 2; \
+#define WRITESHORT(p,v) \
+ do { \
+ *(uint16_t *)(p) = (v); \
+ (p) += 2; \
} while (0)
-#define WRITELONG(p,v) \
- do { \
- *(uint32_t *)(p) = (v); \
- (p) += 4; \
+#define WRITELONG(p,v) \
+ do { \
+ *(uint32_t *)(p) = (v); \
+ (p) += 4; \
} while (0)
-#define WRITEDLONG(p,v) \
- do { \
- *(uint64_t *)(p) = (v); \
- (p) += 8; \
+#define WRITEDLONG(p,v) \
+ do { \
+ *(uint64_t *)(p) = (v); \
+ (p) += 8; \
} while (0)
-#define WRITEADDR(p,v,s) \
- do { \
- uint64_t _wa_v = (v); \
- memcpy((p), &_wa_v, (s)); \
- (p) += (s); \
+#define WRITEADDR(p,v,s) \
+ do { \
+ uint64_t _wa_v = (v); \
+ memcpy((p), &_wa_v, (s)); \
+ (p) += (s); \
} while (0)
#else /* !X86_MEMORY */
-#define WRITECHAR(p,v) \
- do { \
- uint8_t *_wc_p = (uint8_t *)(p); \
- uint8_t _wc_v = (v); \
- _wc_p[0] = _wc_v; \
- (p) = (void *)(_wc_p + 1); \
+#define WRITECHAR(p,v) \
+ do { \
+ uint8_t *_wc_p = (uint8_t *)(p); \
+ uint8_t _wc_v = (v); \
+ _wc_p[0] = _wc_v; \
+ (p) = (void *)(_wc_p + 1); \
} while (0)
-#define WRITESHORT(p,v) \
- do { \
- uint8_t *_ws_p = (uint8_t *)(p); \
- uint16_t _ws_v = (v); \
- _ws_p[0] = _ws_v; \
- _ws_p[1] = _ws_v >> 8; \
- (p) = (void *)(_ws_p + 2); \
+#define WRITESHORT(p,v) \
+ do { \
+ uint8_t *_ws_p = (uint8_t *)(p); \
+ uint16_t _ws_v = (v); \
+ _ws_p[0] = _ws_v; \
+ _ws_p[1] = _ws_v >> 8; \
+ (p) = (void *)(_ws_p + 2); \
} while (0)
-#define WRITELONG(p,v) \
- do { \
- uint8_t *_wl_p = (uint8_t *)(p); \
- uint32_t _wl_v = (v); \
- _wl_p[0] = _wl_v; \
- _wl_p[1] = _wl_v >> 8; \
- _wl_p[2] = _wl_v >> 16; \
- _wl_p[3] = _wl_v >> 24; \
- (p) = (void *)(_wl_p + 4); \
+#define WRITELONG(p,v) \
+ do { \
+ uint8_t *_wl_p = (uint8_t *)(p); \
+ uint32_t _wl_v = (v); \
+ _wl_p[0] = _wl_v; \
+ _wl_p[1] = _wl_v >> 8; \
+ _wl_p[2] = _wl_v >> 16; \
+ _wl_p[3] = _wl_v >> 24; \
+ (p) = (void *)(_wl_p + 4); \
} while (0)
-#define WRITEDLONG(p,v) \
- do { \
- uint8_t *_wq_p = (uint8_t *)(p); \
- uint64_t _wq_v = (v); \
- _wq_p[0] = _wq_v; \
- _wq_p[1] = _wq_v >> 8; \
- _wq_p[2] = _wq_v >> 16; \
- _wq_p[3] = _wq_v >> 24; \
- _wq_p[4] = _wq_v >> 32; \
- _wq_p[5] = _wq_v >> 40; \
- _wq_p[6] = _wq_v >> 48; \
- _wq_p[7] = _wq_v >> 56; \
- (p) = (void *)(_wq_p + 8); \
+#define WRITEDLONG(p,v) \
+ do { \
+ uint8_t *_wq_p = (uint8_t *)(p); \
+ uint64_t _wq_v = (v); \
+ _wq_p[0] = _wq_v; \
+ _wq_p[1] = _wq_v >> 8; \
+ _wq_p[2] = _wq_v >> 16; \
+ _wq_p[3] = _wq_v >> 24; \
+ _wq_p[4] = _wq_v >> 32; \
+ _wq_p[5] = _wq_v >> 40; \
+ _wq_p[6] = _wq_v >> 48; \
+ _wq_p[7] = _wq_v >> 56; \
+ (p) = (void *)(_wq_p + 8); \
} while (0)
-#define WRITEADDR(p,v,s) \
- do { \
- int _wa_s = (s); \
- uint64_t _wa_v = (v); \
- while (_wa_s--) { \
- WRITECHAR(p,_wa_v); \
- _wa_v >>= 8; \
- } \
+#define WRITEADDR(p,v,s) \
+ do { \
+ int _wa_s = (s); \
+ uint64_t _wa_v = (v); \
+ while (_wa_s--) { \
+ WRITECHAR(p,_wa_v); \
+ _wa_v >>= 8; \
+ } \
} while(0)
#endif
const char *prefix_name(int);
-#define ZERO_BUF_SIZE 4096
+#define ZERO_BUF_SIZE 4096
extern const uint8_t zero_buffer[ZERO_BUF_SIZE];
size_t fwritezero(size_t bytes, FILE *fp);