1 /* biginit.c - C routines for bignumbers */
2
3 /*
4 Note: This is NOT the biginit.c file that come the standard BigNum library,
5 but is a customized version specific to Fractint. The biggest difference
6 is in the allocations of memory for the big numbers.
7 */
8
9 #include <string.h>
10 #ifdef __APPLE__
11 #include <malloc/malloc.h>
12 #elif !defined(BIG_ANSI_C)
13 #include <malloc.h>
14 #endif
15 /* see Fractint.c for a description of the "include" hierarchy */
16 #include "port.h"
17 #include "prototyp.h"
18 #include "fractype.h"
19
20 /* appears to me that avoiding the start of extraseg is unnecessary. If
21 correct, later we can eliminate ENDVID here. */
22 #ifdef ENDVID
23 #undef ENDVID
24 #endif
25 #define ENDVID 0
26
27 /* globals */
28 #ifdef BIG_BASED
29 _segment bignum_seg;
30 #endif
31 int bnstep, bnlength, intlength, rlength, padding, shiftfactor, decimals;
32 int bflength, rbflength, bfdecimals;
33
34 /* used internally by bignum.c routines */
35 static bn_t bnroot=BIG_NULL;
36 static bn_t stack_ptr; /* memory allocator base after global variables */
37 bn_t bntmp1, bntmp2, bntmp3, bntmp4, bntmp5, bntmp6; /* rlength */
38 bn_t bntmpcpy1, bntmpcpy2; /* bnlength */
39
40 /* used by other routines */
41 bn_t bnxmin, bnxmax, bnymin, bnymax, bnx3rd, bny3rd; /* bnlength */
42 bn_t bnxdel, bnydel, bnxdel2, bnydel2, bnclosenuff; /* bnlength */
43 bn_t bntmpsqrx, bntmpsqry, bntmp; /* rlength */
44 _BNCMPLX /* bnold, bnnew, */ bnparm, bnsaved; /* bnlength */
45 _BNCMPLX bnold, bnnew; /* rlength */
46 bn_t bn_pi; /* TAKES NO SPACE */
47
48 bf_t bftmp1, bftmp2, bftmp3, bftmp4, bftmp5, bftmp6; /* rbflength+2 */
49 bf_t bftmpcpy1, bftmpcpy2; /* rbflength+2 */
50 bf_t bfxdel, bfydel, bfxdel2, bfydel2, bfclosenuff; /* rbflength+2 */
51 bf_t bftmpsqrx, bftmpsqry; /* rbflength+2 */
52 _BFCMPLX /* bfold, bfnew, */ bfparm, bfsaved; /* bflength+2 */
53 _BFCMPLX bfold, bfnew; /* rbflength+2 */
54 bf_t bf_pi; /* TAKES NO SPACE */
55 bf_t big_pi; /* bflength+2 */
56
57 /* for testing only */
58
59 /* used by other routines */
60 bf_t bfxmin, bfxmax, bfymin, bfymax, bfx3rd, bfy3rd; /* bflength+2 */
61 bf_t bfsxmin, bfsxmax, bfsymin, bfsymax, bfsx3rd, bfsy3rd;/* bflength+2 */
62 bf_t bfparms[10]; /* (bflength+2)*10 */
63 bf_t bftmp;
64
65 bf_t bf10tmp; /* dec+4 */
66
67 #define LOG10_256 2.4082399653118
68 #define LOG_256 5.5451774444795
69
70 static int save_bf_vars(void);
71 static int restore_bf_vars(void);
72
73 /*********************************************************************/
74 /* given bnlength, calc_lengths will calculate all the other lengths */
calc_lengths(void)75 void calc_lengths(void)
76 {
77 #if 0
78 #ifdef USE_BIGNUM_C_CODE
79 bnstep = 2;
80 #else /* use 80x86 asm code */
81 if (cpu >= 386)
82 bnstep = 4;
83 else /* cpu <= 286 */
84 bnstep = 2;
85 #endif
86 #else
87 bnstep = 4; /* use 4 in all cases */
88 #endif
89
90 if (bnlength % bnstep != 0)
91 bnlength = (bnlength / bnstep + 1) * bnstep;
92 if (bnlength == bnstep)
93 padding = bnlength;
94 else
95 padding = 2*bnstep;
96 rlength = bnlength + padding;
97
98 /* This shiftfactor assumes non-full multiplications will be performed.*/
99 /* Change to bnlength-intlength for full multiplications. */
100 shiftfactor = padding - intlength;
101
102 bflength = bnlength+bnstep; /* one extra step for added precision */
103 rbflength = bflength + padding;
104 bfdecimals = (int)((bflength-2)*LOG10_256);
105 }
106
107 /************************************************************************/
108 /* intended only to be called from init_bf_dec() or init_bf_length(). */
109 /* initialize bignumber global variables */
110
111 long maxptr = 0;
112 long startstack = 0;
113 long maxstack = 0;
114 int bf_save_len = 0;
115
116 /* ??? for some strange reason, msc 7.0 hangs here without this pragma. ??? */
117 #ifndef XFRACT
118 #pragma optimize( "", off )
119 #endif
init_bf_2(void)120 static void init_bf_2(void)
121 {
122 int i;
123 long ptr;
124 save_bf_vars(); /* copy corners values for conversion */
125
126 calc_lengths();
127
128 /* allocate all the memory at once within the same segment (DOS) */
129 #if defined(BIG_FAR) || defined(BIG_ANSI_C)
130 bnroot = (bf_t)MK_FP(extraseg,ENDVID); /* ENDVID is to avoid videotable */
131 #else /* BASED or NEAR */
132 bnroot = (bf_t)ENDVID; /* ENDVID is to avoid videotable */
133 #endif
134 #ifdef BIG_BASED
135 bignum_seg = (_segment)extraseg;
136 #endif
137 /* at present time one call would suffice, but this logic allows
138 multiple kinds of alternate math eg long double */
139 if((i = find_alternate_math(fractype, BIGNUM)) > -1)
140 bf_math = alternatemath[i].math;
141 else if((i = find_alternate_math(fractype, BIGFLT)) > -1)
142 bf_math = alternatemath[i].math;
143 else
144 bf_math = 1; /* maybe called from cmdfiles.c and fractype not set */
145
146 floatflag=1;
147
148 /* Now split up the memory among the pointers */
149 /* internal pointers */
150 ptr = 0;
151 bntmp1 = bnroot+ptr; ptr += rlength;
152 bntmp2 = bnroot+ptr; ptr += rlength;
153 bntmp3 = bnroot+ptr; ptr += rlength;
154 bntmp4 = bnroot+ptr; ptr += rlength;
155 bntmp5 = bnroot+ptr; ptr += rlength;
156 bntmp6 = bnroot+ptr; ptr += rlength;
157
158 bftmp1 = bnroot+ptr; ptr += rbflength+2;
159 bftmp2 = bnroot+ptr; ptr += rbflength+2;
160 bftmp3 = bnroot+ptr; ptr += rbflength+2;
161 bftmp4 = bnroot+ptr; ptr += rbflength+2;
162 bftmp5 = bnroot+ptr; ptr += rbflength+2;
163 bftmp6 = bnroot+ptr; ptr += rbflength+2;
164
165 bftmpcpy1 = bnroot+ptr; ptr += (rbflength+2)*2;
166 bftmpcpy2 = bnroot+ptr; ptr += (rbflength+2)*2;
167
168 bntmpcpy1 = bnroot+ptr; ptr += (rlength*2);
169 bntmpcpy2 = bnroot+ptr; ptr += (rlength*2);
170
171 if (bf_math == BIGNUM)
172 {
173 bnxmin = bnroot+ptr; ptr += bnlength;
174 bnxmax = bnroot+ptr; ptr += bnlength;
175 bnymin = bnroot+ptr; ptr += bnlength;
176 bnymax = bnroot+ptr; ptr += bnlength;
177 bnx3rd = bnroot+ptr; ptr += bnlength;
178 bny3rd = bnroot+ptr; ptr += bnlength;
179 bnxdel = bnroot+ptr; ptr += bnlength;
180 bnydel = bnroot+ptr; ptr += bnlength;
181 bnxdel2 = bnroot+ptr; ptr += bnlength;
182 bnydel2 = bnroot+ptr; ptr += bnlength;
183 bnold.x = bnroot+ptr; ptr += rlength;
184 bnold.y = bnroot+ptr; ptr += rlength;
185 bnnew.x = bnroot+ptr; ptr += rlength;
186 bnnew.y = bnroot+ptr; ptr += rlength;
187 bnsaved.x = bnroot+ptr; ptr += bnlength;
188 bnsaved.y = bnroot+ptr; ptr += bnlength;
189 bnclosenuff= bnroot+ptr; ptr += bnlength;
190 bnparm.x = bnroot+ptr; ptr += bnlength;
191 bnparm.y = bnroot+ptr; ptr += bnlength;
192 bntmpsqrx = bnroot+ptr; ptr += rlength;
193 bntmpsqry = bnroot+ptr; ptr += rlength;
194 bntmp = bnroot+ptr; ptr += rlength;
195 }
196 if (bf_math == BIGFLT)
197 {
198 bfxdel = bnroot+ptr; ptr += bflength+2;
199 bfydel = bnroot+ptr; ptr += bflength+2;
200 bfxdel2 = bnroot+ptr; ptr += bflength+2;
201 bfydel2 = bnroot+ptr; ptr += bflength+2;
202 bfold.x = bnroot+ptr; ptr += rbflength+2;
203 bfold.y = bnroot+ptr; ptr += rbflength+2;
204 bfnew.x = bnroot+ptr; ptr += rbflength+2;
205 bfnew.y = bnroot+ptr; ptr += rbflength+2;
206 bfsaved.x = bnroot+ptr; ptr += bflength+2;
207 bfsaved.y = bnroot+ptr; ptr += bflength+2;
208 bfclosenuff= bnroot+ptr; ptr += bflength+2;
209 bfparm.x = bnroot+ptr; ptr += bflength+2;
210 bfparm.y = bnroot+ptr; ptr += bflength+2;
211 bftmpsqrx = bnroot+ptr; ptr += rbflength+2;
212 bftmpsqry = bnroot+ptr; ptr += rbflength+2;
213 bftmp = bnroot+ptr; ptr += rbflength+2;
214 }
215 big_pi = bnroot+ptr; ptr += bflength+2; /* needed by both BIGNUM & BIGFLT */
216 bf10tmp = bnroot+ptr; ptr += bfdecimals+4;
217
218 /* ptr needs to be 16-bit aligned on some systems */
219 ptr = (ptr+1)&~1;
220
221 stack_ptr = bnroot + ptr;
222 startstack = ptr;
223
224 /* max stack offset from bnroot */
225 maxstack = (long)0x10000l-(bflength+2)*22-ENDVID;
226
227 /* sanity check */
228 /* leave room for NUMVARS variables allocated from stack */
229 /* also leave room for the safe area at top of segment */
230 if(ptr + NUMVARS*(bflength+2) > maxstack)
231 {
232 char msg[80];
233 char nmsg[80];
234 static FCODE fmsg[] = {"Requested precision of %d too high, aborting"};
235 far_strcpy(nmsg,fmsg);
236 sprintf(msg,nmsg,decimals);
237 stopmsg(0,msg);
238 goodbye();
239 }
240
241 /* room for 6 corners + 6 save corners + 10 params at top of extraseg */
242 /* this area is safe - use for variables that are used outside fractal*/
243 /* generation - e.g. zoom box variables */
244 ptr = maxstack;
245 bfxmin = bnroot+ptr; ptr += bflength+2;
246 bfxmax = bnroot+ptr; ptr += bflength+2;
247 bfymin = bnroot+ptr; ptr += bflength+2;
248 bfymax = bnroot+ptr; ptr += bflength+2;
249 bfx3rd = bnroot+ptr; ptr += bflength+2;
250 bfy3rd = bnroot+ptr; ptr += bflength+2;
251 for(i=0;i<10;i++)
252 {
253 bfparms[i] = bnroot+ptr; ptr += bflength+2;
254 }
255 bfsxmin = bnroot+ptr; ptr += bflength+2;
256 bfsxmax = bnroot+ptr; ptr += bflength+2;
257 bfsymin = bnroot+ptr; ptr += bflength+2;
258 bfsymax = bnroot+ptr; ptr += bflength+2;
259 bfsx3rd = bnroot+ptr; ptr += bflength+2;
260 bfsy3rd = bnroot+ptr; ptr += bflength+2;
261 /* end safe vars */
262
263 /* good citizens initialize variables */
264 if(bf_save_len) /* leave save area */
265 far_memset(bnroot+(bf_save_len+2)*22,0,(unsigned)(startstack-(bf_save_len+2)*22));
266 else /* first time through - nothing saved */
267 {
268 /* high variables */
269 far_memset(bnroot+maxstack,0,(bflength+2)*22);
270 /* low variables */
271 far_memset(bnroot,0,(unsigned)startstack);
272 }
273
274 restore_bf_vars();
275
276 /* Initialize the value of pi. Needed for trig functions. */
277 /* init_big_pi(); */
278 /* call to init_big_pi() has been moved to fractal setup routine */
279 /* so as to use only when necessary. */
280
281 }
282
283
284 /**********************************************************/
285 /* save current corners and parameters to start of bnroot */
286 /* to preserve values across calls to init_bf() */
save_bf_vars(void)287 static int save_bf_vars(void)
288 {
289 int ret;
290 unsigned int mem;
291 if(bnroot != BIG_NULL)
292 {
293 mem = (bflength+2)*22; /* 6 corners + 6 save corners + 10 params */
294 bf_save_len = bflength;
295 far_memcpy(bnroot,bfxmin,mem);
296 /* scrub old high area */
297 far_memset(bfxmin,0,mem);
298 ret = 0;
299 }
300 else
301 {
302 bf_save_len = 0;
303 ret = -1;
304 }
305 return(ret);
306 }
307
308 /************************************************************************/
309 /* copy current corners and parameters from save location */
restore_bf_vars(void)310 static int restore_bf_vars(void)
311 {
312 bf_t ptr;
313 int i;
314 if(bf_save_len == 0)
315 return(-1);
316 ptr = bnroot;
317 convert_bf(bfxmin,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
318 convert_bf(bfxmax,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
319 convert_bf(bfymin,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
320 convert_bf(bfymax,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
321 convert_bf(bfx3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
322 convert_bf(bfy3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
323 for(i=0;i<10;i++)
324 {
325 convert_bf(bfparms[i],ptr,bflength,bf_save_len);
326 ptr += bf_save_len+2;
327 }
328 convert_bf(bfsxmin,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
329 convert_bf(bfsxmax,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
330 convert_bf(bfsymin,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
331 convert_bf(bfsymax,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
332 convert_bf(bfsx3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
333 convert_bf(bfsy3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
334
335 /* scrub save area */
336 far_memset(bnroot,0,(bf_save_len+2)*22);
337 return(0);
338 }
339
340 /*******************************************/
341 /* free corners and parameters save memory */
free_bf_vars()342 void free_bf_vars()
343 {
344 bf_save_len = bf_math = 0;
345 bnstep=bnlength=intlength=rlength=padding=shiftfactor=decimals=0;
346 bflength=rbflength=bfdecimals=0;
347 maxptr = startstack = maxstack = 0;
348 }
349
350 #ifndef XFRACT
351 #pragma optimize( "", on )
352 #endif
353
354 /************************************************************************/
355 /* Memory allocator routines start here. */
356 /************************************************************************/
357 /* Allocates a bn_t variable on stack */
alloc_stack(size_t size)358 bn_t alloc_stack(size_t size)
359 {
360 long stack_addr;
361 if(bf_math == 0)
362 {
363 static FCODE msg[] = {"alloc_stack called with bf_math==0"};
364 stopmsg(0,msg);
365 return(0);
366 }
367 stack_addr = (long)(stack_ptr-bnroot)+size; /* +ENDVID, part of bnroot */
368
369 if(stack_addr > maxstack)
370 {
371 static FCODE msg[] = {"Aborting, Out of Bignum Stack Space"};
372 stopmsg(0,msg);
373 goodbye();
374 }
375 /* keep track of max ptr */
376 if(stack_addr > maxptr)
377 maxptr = stack_addr;
378 stack_ptr += size; /* increment stack pointer */
379 return(stack_ptr - size);
380 }
381
382 /************************************************************************/
383 /* Returns stack pointer offset so it can be saved. */
save_stack(void)384 int save_stack(void)
385 {
386 return(stack_ptr - bnroot);
387 }
388
389 /************************************************************************/
390 /* Restores stack pointer, effectively freeing local variables */
391 /* allocated since save_stack() */
restore_stack(int old_offset)392 void restore_stack(int old_offset)
393 {
394 stack_ptr = bnroot+old_offset;
395 }
396
397 /************************************************************************/
398 /* Memory allocator routines end here. */
399 /************************************************************************/
400
401 /************************************************************************/
402 /* initialize bignumber global variables */
403 /* dec = decimal places after decimal point */
404 /* intl = bytes for integer part (1, 2, or 4) */
405
init_bf_dec(int dec)406 void init_bf_dec(int dec)
407 {
408 if(bfdigits)
409 decimals=bfdigits; /* blindly force */
410 else
411 decimals = dec;
412 if(bailout > 10) /* arbitrary value */
413 /* using 2 doesn't gain much and requires another test */
414 intlength = 4;
415 else if (fractype == FPMANDELZPOWER || fractype == FPJULIAZPOWER ||
416 fractype == DIVIDEBROT5)
417 intlength = 4; /* 2 leaves artifacts in the center of the lakes */
418 /* the bailout tests need greater dynamic range */
419 else if(bailoutest == Real || bailoutest == Imag || bailoutest == And ||
420 bailoutest == Manr)
421 intlength = 2;
422 else
423 intlength = 1;
424 /* conservative estimate */
425 bnlength = intlength + (int)(decimals/LOG10_256) + 1; /* round up */
426 init_bf_2();
427 }
428
429 /************************************************************************/
430 /* initialize bignumber global variables */
431 /* bnl = bignumber length */
432 /* intl = bytes for integer part (1, 2, or 4) */
init_bf_length(int bnl)433 void init_bf_length(int bnl)
434 {
435 bnlength = bnl;
436
437 if(bailout > 10) /* arbitrary value */
438 /* using 2 doesn't gain much and requires another test */
439 intlength = 4;
440 else if (fractype == FPMANDELZPOWER || fractype == FPJULIAZPOWER ||
441 fractype == DIVIDEBROT5)
442 intlength = 4; /* 2 leaves artifacts in the center of the lakes */
443 /* the bailout tests need greater dynamic range */
444 else if(bailoutest == Real || bailoutest == Imag || bailoutest == And ||
445 bailoutest == Manr)
446 intlength = 2;
447 else
448 intlength = 1;
449 /* conservative estimate */
450 decimals = (int)((bnlength-intlength)*LOG10_256);
451 init_bf_2();
452 }
453
454
init_big_pi(void)455 void init_big_pi(void)
456 {
457 /* What, don't you recognize the first 700 digits of pi, */
458 /* in base 256, in reverse order? */
459 int length, pi_offset;
460 static BFCODE pi_table[] = {
461 0x44, 0xD5, 0xDB, 0x69, 0x17, 0xDF, 0x2E, 0x56, 0x87, 0x1A,
462 0xA0, 0x8C, 0x6F, 0xCA, 0xBB, 0x57, 0x5C, 0x9E, 0x82, 0xDF,
463 0x00, 0x3E, 0x48, 0x7B, 0x31, 0x53, 0x60, 0x87, 0x23, 0xFD,
464 0xFA, 0xB5, 0x3D, 0x32, 0xAB, 0x52, 0x05, 0xAD, 0xC8, 0x1E,
465 0x50, 0x2F, 0x15, 0x6B, 0x61, 0xFD, 0xDF, 0x16, 0x75, 0x3C,
466 0xF8, 0x22, 0x32, 0xDB, 0xF8, 0xE9, 0xA5, 0x8E, 0xCC, 0xA3,
467 0x1F, 0xFB, 0xFE, 0x25, 0x9F, 0x67, 0x79, 0x72, 0x2C, 0x40,
468 0xC6, 0x00, 0xA1, 0xD6, 0x0A, 0x32, 0x60, 0x1A, 0xBD, 0xC0,
469 0x79, 0x55, 0xDB, 0xFB, 0xD3, 0xB9, 0x39, 0x5F, 0x0B, 0xD2,
470 0x0F, 0x74, 0xC8, 0x45, 0x57, 0xA8, 0xCB, 0xC0, 0xB3, 0x4B,
471 0x2E, 0x19, 0x07, 0x28, 0x0F, 0x66, 0xFD, 0x4A, 0x33, 0xDE,
472 0x04, 0xD0, 0xE3, 0xBE, 0x09, 0xBD, 0x5E, 0xAF, 0x44, 0x45,
473 0x81, 0xCC, 0x2C, 0x95, 0x30, 0x9B, 0x1F, 0x51, 0xFC, 0x6D,
474 0x6F, 0xEC, 0x52, 0x3B, 0xEB, 0xB2, 0x39, 0x13, 0xB5, 0x53,
475 0x6C, 0x3E, 0xAF, 0x6F, 0xFB, 0x68, 0x63, 0x24, 0x6A, 0x19,
476 0xC2, 0x9E, 0x5C, 0x5E, 0xC4, 0x60, 0x9F, 0x40, 0xB6, 0x4F,
477 0xA9, 0xC1, 0xBA, 0x06, 0xC0, 0x04, 0xBD, 0xE0, 0x6C, 0x97,
478 0x3B, 0x4C, 0x79, 0xB6, 0x1A, 0x50, 0xFE, 0xE3, 0xF7, 0xDE,
479 0xE8, 0xF6, 0xD8, 0x79, 0xD4, 0x25, 0x7B, 0x1B, 0x99, 0x80,
480 0xC9, 0x72, 0x53, 0x07, 0x9B, 0xC0, 0xF1, 0x49, 0xD3, 0xEA,
481 0x0F, 0xDB, 0x48, 0x12, 0x0A, 0xD0, 0x24, 0xD7, 0xD0, 0x37,
482 0x3D, 0x02, 0x9B, 0x42, 0x72, 0xDF, 0xFE, 0x1B, 0x06, 0x77,
483 0x3F, 0x36, 0x62, 0xAA, 0xD3, 0x4E, 0xA6, 0x6A, 0xC1, 0x56,
484 0x9F, 0x44, 0x1A, 0x40, 0x73, 0x20, 0xC1, 0x85, 0xD8, 0x75,
485 0x6F, 0xE0, 0xBE, 0x5E, 0x8B, 0x3B, 0xC3, 0xA5, 0x84, 0x7D,
486 0xB4, 0x9F, 0x6F, 0x45, 0x19, 0x86, 0xEE, 0x8C, 0x88, 0x0E,
487 0x43, 0x82, 0x3E, 0x59, 0xCA, 0x66, 0x76, 0x01, 0xAF, 0x39,
488 0x1D, 0x65, 0xF1, 0xA1, 0x98, 0x2A, 0xFB, 0x7E, 0x50, 0xF0,
489 0x3B, 0xBA, 0xE4, 0x3B, 0x7A, 0x13, 0x6C, 0x0B, 0xEF, 0x6E,
490 0xA3, 0x33, 0x51, 0xAB, 0x28, 0xA7, 0x0F, 0x96, 0x68, 0x2F,
491 0x54, 0xD8, 0xD2, 0xA0, 0x51, 0x6A, 0xF0, 0x88, 0xD3, 0xAB,
492 0x61, 0x9C, 0x0C, 0x67, 0x9A, 0x6C, 0xE9, 0xF6, 0x42, 0x68,
493 0xC6, 0x21, 0x5E, 0x9B, 0x1F, 0x9E, 0x4A, 0xF0, 0xC8, 0x69,
494 0x04, 0x20, 0x84, 0xA4, 0x82, 0x44, 0x0B, 0x2E, 0x39, 0x42,
495 0xF4, 0x83, 0xF3, 0x6F, 0x6D, 0x0F, 0xC5, 0xAC, 0x96, 0xD3,
496 0x81, 0x3E, 0x89, 0x23, 0x88, 0x1B, 0x65, 0xEB, 0x02, 0x23,
497 0x26, 0xDC, 0xB1, 0x75, 0x85, 0xE9, 0x5D, 0x5D, 0x84, 0xEF,
498 0x32, 0x80, 0xEC, 0x5D, 0x60, 0xAC, 0x7C, 0x48, 0x91, 0xA9,
499 0x21, 0xFB, 0xCC, 0x09, 0xD8, 0x61, 0x93, 0x21, 0x28, 0x66,
500 0x1B, 0xE8, 0xBF, 0xC4, 0xAF, 0xB9, 0x4B, 0x6B, 0x98, 0x48,
501 0x8F, 0x3B, 0x77, 0x86, 0x95, 0x28, 0x81, 0x53, 0x32, 0x7A,
502 0x5C, 0xCF, 0x24, 0x6C, 0x33, 0xBA, 0xD6, 0xAF, 0x1E, 0x93,
503 0x87, 0x9B, 0x16, 0x3E, 0x5C, 0xCE, 0xF6, 0x31, 0x18, 0x74,
504 0x5D, 0xC5, 0xA9, 0x2B, 0x2A, 0xBC, 0x6F, 0x63, 0x11, 0x14,
505 0xEE, 0xB3, 0x93, 0xE9, 0x72, 0x7C, 0xAF, 0x86, 0x54, 0xA1,
506 0xCE, 0xE8, 0x41, 0x11, 0x34, 0x5C, 0xCC, 0xB4, 0xB6, 0x10,
507 0xAB, 0x2A, 0x6A, 0x39, 0xCA, 0x55, 0x40, 0x14, 0xE8, 0x63,
508 0x62, 0x98, 0x48, 0x57, 0x94, 0xAB, 0x55, 0xAA, 0xF3, 0x25,
509 0x55, 0xE6, 0x60, 0x5C, 0x60, 0x55, 0xDA, 0x2F, 0xAF, 0x78,
510 0x27, 0x4B, 0x31, 0xBD, 0xC1, 0x77, 0x15, 0xD7, 0x3E, 0x8A,
511 0x1E, 0xB0, 0x8B, 0x0E, 0x9E, 0x6C, 0x0E, 0x18, 0x3A, 0x60,
512 0xB0, 0xDC, 0x79, 0x8E, 0xEF, 0x38, 0xDB, 0xB8, 0x18, 0x79,
513 0x41, 0xCA, 0xF0, 0x85, 0x60, 0x28, 0x23, 0xB0, 0xD1, 0xC5,
514 0x13, 0x60, 0xF2, 0x2A, 0x39, 0xD5, 0x30, 0x9C, 0xB5, 0x59,
515 0x5A, 0xC2, 0x1D, 0xA4, 0x54, 0x7B, 0xEE, 0x4A, 0x15, 0x82,
516 0x58, 0xCD, 0x8B, 0x71, 0x58, 0xB6, 0x8E, 0x72, 0x8F, 0x74,
517 0x95, 0x0D, 0x7E, 0x3D, 0x93, 0xF4, 0xA3, 0xFE, 0x58, 0xA4,
518 0x69, 0x4E, 0x57, 0x71, 0xD8, 0x20, 0x69, 0x63, 0x16, 0xFC,
519 0x8E, 0x85, 0xE2, 0xF2, 0x01, 0x08, 0xF7, 0x6C, 0x91, 0xB3,
520 0x47, 0x99, 0xA1, 0x24, 0x99, 0x7F, 0x2C, 0xF1, 0x45, 0x90,
521 0x7C, 0xBA, 0x96, 0x7E, 0x26, 0x6A, 0xED, 0xAF, 0xE1, 0xB8,
522 0xB7, 0xDF, 0x1A, 0xD0, 0xDB, 0x72, 0xFD, 0x2F, 0xAC, 0xB5,
523 0xDF, 0x98, 0xA6, 0x0B, 0x31, 0xD1, 0x1B, 0xFB, 0x79, 0x89,
524 0xD9, 0xD5, 0x16, 0x92, 0x17, 0x09, 0x47, 0xB5, 0xB5, 0xD5,
525 0x84, 0x3F, 0xDD, 0x50, 0x7C, 0xC9, 0xB7, 0x29, 0xAC, 0xC0,
526 0x6C, 0x0C, 0xE9, 0x34, 0xCF, 0x66, 0x54, 0xBE, 0x77, 0x13,
527 0xD0, 0x38, 0xE6, 0x21, 0x28, 0x45, 0x89, 0x6C, 0x4E, 0xEC,
528 0x98, 0xFA, 0x2E, 0x08, 0xD0, 0x31, 0x9F, 0x29, 0x22, 0x38,
529 0x09, 0xA4, 0x44, 0x73, 0x70, 0x03, 0x2E, 0x8A, 0x19, 0x13,
530 0xD3, 0x08, 0xA3, 0x85, 0x88, 0x6A, 0x3F, 0x24,
531 /* . */ 0x03, 0x00, 0x00, 0x00
532 /* <- up to intlength 4 -> */
533 /* or bf_t int length of 2 + 2 byte exp */
534 };
535
536 length = bflength+2; /* 2 byte exp */
537 pi_offset = sizeof pi_table - length;
538 _fmemcpy(big_pi, pi_table + pi_offset, length);
539
540 /* notice that bf_pi and bn_pi can share the same memory space */
541 bf_pi = big_pi;
542 bn_pi = big_pi + (bflength-2) - (bnlength-intlength);
543 return;
544 }
545