diff options
Diffstat (limited to 'erts/emulator/beam/big.h')
-rw-r--r-- | erts/emulator/beam/big.h | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/erts/emulator/beam/big.h b/erts/emulator/beam/big.h new file mode 100644 index 0000000000..b8e38d482c --- /dev/null +++ b/erts/emulator/beam/big.h @@ -0,0 +1,155 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#ifndef __BIG_H__ +#define __BIG_H__ + +#ifndef __SYS_H__ +#include "sys.h" +#endif + +#ifndef __CONFIG_H__ +#include "erl_vm.h" +#endif + +#ifndef __GLOBAL_H__ +#include "global.h" +#endif + +typedef Uint ErtsDigit; + +#if (SIZEOF_VOID_P == 4) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8) +/* Assume 32-bit machine with long long support */ +typedef Uint64 ErtsDoubleDigit; +typedef Uint16 ErtsHalfDigit; +#define BIG_HAVE_DOUBLE_DIGIT 1 + +#elif (SIZEOF_VOID_P == 4) +/* Assume 32-bit machine with no long support */ +#undef BIG_HAVE_DOUBLE_DIGIT +typedef Uint16 ErtsHalfDigit; + +#elif (SIZEOF_VOID_P == 8) +/* Assume 64-bit machine, does it exist 128 bit long long long ? */ +#undef BIG_HAVE_DOUBLE_DIGIT +typedef Uint32 ErtsHalfDigit; +#else +#error "can not determine machine size" +#endif + +#define D_DECIMAL_EXP 9 +#define D_DECIMAL_BASE 1000000000 + +typedef Uint dsize_t; /* Vector size type */ + +#define D_EXP (SIZEOF_VOID_P*8) +#define D_MASK ((ErtsDigit)(-1)) /* D_BASE-1 */ + +/* macros for bignum objects */ +#define big_v(x) BIG_V(big_val(x)) +#define big_sign(x) BIG_SIGN(big_val(x)) +#define big_arity(x) BIG_ARITY(big_val(x)) +#define big_digit(x,i) BIG_DIGIT(big_val(x),i) +#define big_size(x) BIG_SIZE(big_val(x)) + + +/* macros for thing pointers */ + +#define BIG_V(xp) ((ErtsDigit*)((xp)+1)) +#define BIG_SIGN(xp) (!!bignum_header_is_neg(*xp)) +#define BIG_ARITY(xp) ((Uint)bignum_header_arity(*(xp))) +#define BIG_DIGIT(xp,i) *(BIG_V(xp)+(i)) +#define BIG_DIGITS_PER_WORD (sizeof(Uint)/sizeof(ErtsDigit)) + +#define BIG_SIZE(xp) BIG_ARITY(xp) + +/* Check for small */ +#define IS_USMALL(sgn,x) ((sgn) ? ((x) <= MAX_SMALL+1) : ((x) <= MAX_SMALL)) +#define IS_SSMALL(x) (((x) >= MIN_SMALL) && ((x) <= MAX_SMALL)) + +/* The heap size needed for a bignum */ +#define BIG_NEED_SIZE(x) ((x) + 1) + +#define BIG_UINT_HEAP_SIZE (1 + 1) /* always, since sizeof(Uint) <= sizeof(Eterm) */ + +#ifdef ARCH_32 + +#define ERTS_UINT64_BIG_HEAP_SIZE__(X) \ + ((X) >= (((Uint64) 1) << 32) ? (1 + 2) : (1 + 1)) +#define ERTS_SINT64_HEAP_SIZE(X) \ + (IS_SSMALL((X)) \ + ? 0 \ + : ERTS_UINT64_BIG_HEAP_SIZE__((X) >= 0 ? (X) : -(X))) +#define ERTS_UINT64_HEAP_SIZE(X) \ + (IS_USMALL(0, (X)) ? 0 : ERTS_UINT64_BIG_HEAP_SIZE__((X))) + +#else + +#define ERTS_SINT64_HEAP_SIZE(X) \ + (IS_SSMALL((X)) ? 0 : (1 + 1)) +#define ERTS_UINT64_HEAP_SIZE(X) \ + (IS_USMALL(0, (X)) ? 0 : (1 + 1)) + +#endif + +int big_decimal_estimate(Eterm); +Eterm erts_big_to_list(Eterm, Eterm**); +char *erts_big_to_string(Eterm x, char *buf, Uint buf_sz); + +Eterm small_times(Sint, Sint, Eterm*); + +Eterm big_plus(Eterm, Eterm, Eterm*); +Eterm big_minus(Eterm, Eterm, Eterm*); +Eterm big_times(Eterm, Eterm, Eterm*); +Eterm big_div(Eterm, Eterm, Eterm*); +Eterm big_rem(Eterm, Eterm, Eterm*); +Eterm big_neg(Eterm, Eterm*); + +Eterm big_minus_small(Eterm, Uint, Eterm*); +Eterm big_plus_small(Eterm, Uint, Eterm*); +Eterm big_times_small(Eterm, Uint, Eterm*); + +Eterm big_band(Eterm, Eterm, Eterm*); +Eterm big_bor(Eterm, Eterm, Eterm*); +Eterm big_bxor(Eterm, Eterm, Eterm*); +Eterm big_bnot(Eterm, Eterm*); + +Eterm big_lshift(Eterm, Sint, Eterm*); +int big_comp (Eterm, Eterm); +int big_ucomp (Eterm, Eterm); +int big_to_double(Eterm x, double* resp); +Eterm small_to_big(Sint, Eterm*); +Eterm uint_to_big(Uint, Eterm*); +Eterm erts_make_integer(Uint, Process *); + +dsize_t big_bytes(Eterm); +Eterm bytes_to_big(byte*, dsize_t, int, Eterm*); +byte* big_to_bytes(Eterm, byte*); + +int term_to_Uint(Eterm, Uint*); +int term_to_Sint(Eterm, Sint*); + +Uint32 big_to_uint32(Eterm b); +int term_equals_2pow32(Eterm); + +Eterm erts_uint64_to_big(Uint64, Eterm **); +Eterm erts_sint64_to_big(Sint64, Eterm **); + +#endif + |