blob: 25f378408f769c0651d3945c6125f7a3b4e63e3f [file] [log] [blame]
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001/*
2 * lbn.h - Low-level bignum header.
3 * Defines various word sizes and useful macros.
4 * TODO: Rewrite this to use <stdint.h> and/or <inttypes.h>
5 *
6 * Copyright (c) 1995 Colin Plumb. All rights reserved.
7 * For licensing and other legal details, see the file legal.c.
8 */
9#ifndef LBN_H
10#define LBN_H
11
12#ifndef HAVE_CONFIG_H
13#define HAVE_CONFIG_H 0
14#endif
15#if HAVE_CONFIG_H
16#include <bnconfig.h>
17#endif
18
19/*
20 * Some compilers complain about #if FOO if FOO isn't defined,
21 * so do the ANSI-mandated thing explicitly...
22 */
23#ifndef NO_LIMITS_H
24#define NO_LIMITS_H 0
25#endif
26
27#include <stdint.h> /* TODO: protect by configuration ifdef */
28
29/* Make sure we have 8-bit bytes */
30#if !NO_LIMITS_H
31#include <limits.h>
32#if UCHAR_MAX != 0xff || CHAR_BIT != 8
33#error The bignum library requires 8-bit unsigned characters.
34#endif
35#endif /* !NO_LIMITS_H */
36
37#ifdef BNINCLUDE /* If this is defined as, say, foo.h */
38#define STR(x) #x /* STR(BNINCLUDE) -> "BNINCLUDE" */
39#define XSTR(x) STR(x) /* XSTR(BNINCLUDE) -> STR(foo.h) -> "foo.h" */
40#include XSTR(BNINCLUDE) /* #include "foo.h" */
41#undef XSTR
42#undef STR
43#endif
44
45/* Do we want bnYield()? */
46#ifndef BNYIELD
47#define BNYIELD 0
48#endif
49
50/* Figure out the endianness */
51/* Error if more than one is defined */
52#if defined(BN_BIG_ENDIAN) && defined(BN_LITTLE_ENDIAN)
53#error Only one of BN_BIG_ENDIAN or BN_LITTLE_ENDIAN may be defined
54#endif
55
56/*
57 * If no preference is stated, little-endian C code is slightly more
58 * efficient, so prefer that. (The endianness here does NOT have to
59 * match the machine's native byte sex; the library's C code will work
60 * either way. The flexibility is allowed for assembly routines
61 * that do care.
62 */
63#if !defined(BN_BIG_ENDIAN) && !defined(BN_LITTLE_ENDIAN)
64#define BN_LITTLE_ENDIAN 1
65#endif /* !BN_BIG_ENDIAN && !BN_LITTLE_ENDIAN */
66
67/* Macros to choose between big and little endian */
68#if defined(BN_BIG_ENDIAN)
69#define BIG(b) b
70#define LITTLE(l) /*nothing*/
71#define BIGLITTLE(b,l) b
72#elif BN_LITTLE_ENDIAN
73#define BIG(b) /*nothing*/
74#define LITTLE(l) l
75#define BIGLITTLE(b,l) l
76#else
77#error One of BN_BIG_ENDIAN or BN_LITTLE_ENDIAN must be defined as 1
78#endif
79
80
81/*
82 * Define a 16-bit unsigned type if available.
83 * Unsigned short is preferred over unsigned int to make the type chosen
84 * by this file more stable on platforms (such as many 68000 compilers)
85 * which support both 16- and 32-bit ints.
86 */
87#ifndef BNWORD16
88#if !defined USHRT_MAX || USHRT_MAX == 0xffff || UINT_MAX == 0xffff
89#define BNWORD16 uint16_t
90#endif
91#endif /* BNWORD16 */
92
93/*
94 * Define a 32-bit unsigned type if available.
95 * Unsigned long is preferred over unsigned int to make the type chosen
96 * by this file more stable on platforms (such as many 68000 compilers)
97 * which support both 16- and 32-bit ints.
98 */
99#ifndef BNWORD32
100#if !defined ULONG_MAX || ULONG_MAX == 0xfffffffful || UINT_MAX == 0xffffffff || USHRT_MAX == 0xffffffff
101#define BNWORD32 uint32_t
102#endif
103#endif /* BNWORD32 */
104
105/*
106 * Find a 64-bit unsigned type.
107 * The conditions here are more complicated to avoid using numbers that
108 * will choke lesser preprocessors (like 0xffffffffffffffff) unless
109 * we're reasonably certain that they'll be acceptable.
110 */
111#if !defined(BNWORD64) && ULONG_MAX > 0xffffffffUL
112#if ULONG_MAX == 0xffffffffffffffff
113#define BNWORD64 uint64_t
114#endif
115#endif
116
117/*
118 * I would test the value of unsigned long long, but some *preprocessors*
119 * don't constants that long even if the compiler can accept them, so it
120 * doesn't work reliably. So cross our fingers and hope that it's a 64-bit
121 * type.
122 *
123 * GCC uses ULONG_LONG_MAX. Solaris uses ULLONG_MAX. IRIX uses ULONGLONG_MAX.
124 * Are there any other names for this?
125 */
126#if !defined(BNWORD64) && \
127 (defined(ULONG_LONG_MAX) || defined (ULLONG_MAX) || defined(ULONGLONG_MAX))
128#define BNWORD64 uint64_t
129#endif
130
131/* We don't even try to find a 128-bit type at the moment */
132
133#endif /* !LBN_H */