mp-genie.c
1 //! @file mp-genie.c
2 //! @author J. Marcel van der Veer
3
4 //! @section Copyright
5 //!
6 //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
7 //! Copyright 2001-2025 J. Marcel van der Veer [algol68g@xs4all.nl].
8
9 //! @section License
10 //!
11 //! This program is free software; you can redistribute it and/or modify it
12 //! under the terms of the GNU General Public License as published by the
13 //! Free Software Foundation; either version 3 of the License, or
14 //! (at your option) any later version.
15 //!
16 //! This program is distributed in the hope that it will be useful, but
17 //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 //! more details. You should have received a copy of the GNU General Public
20 //! License along with this program. If not, see [http://www.gnu.org/licenses/].
21
22 //! @section Synopsis
23 //!
24 //! Multi-precision interpreter routines.
25
26 #include "a68g.h"
27 #include "a68g-genie.h"
28 #include "a68g-prelude.h"
29 #include "a68g-mp.h"
30
31 //! brief LONG REAL long infinity
32
33 void genie_infinity_mp (NODE_T *p)
34 {
35 int digs = DIGITS (MOID (p));
36 MP_T *z = nil_mp (p, digs);
37 MP_STATUS (z) = (PLUS_INF_MASK | INIT_MASK);
38 }
39
40 //! brief LONG REAL long minus infinity
41
42 void genie_minus_infinity_mp (NODE_T *p)
43 {
44 int digs = DIGITS (MOID (p));
45 MP_T *z = nil_mp (p, digs);
46 MP_STATUS (z) = (MINUS_INF_MASK | INIT_MASK);
47 }
48
49 //! @brief LONG INT long max int
50
51 void genie_long_max_int (NODE_T * p)
52 {
53 int digs = DIGITS (M_LONG_INT);
54 MP_T *z = nil_mp (p, digs);
55 MP_STATUS (z) = (MP_T) INIT_MASK;
56 MP_EXPONENT (z) = (MP_T) (digs - 1);
57 for (int k = 1; k <= digs; k++) {
58 MP_DIGIT (z, k) = (MP_T) (MP_RADIX - 1);
59 }
60 }
61
62 //! @brief LONG LONG INT long long max int
63
64 void genie_long_mp_max_int (NODE_T * p)
65 {
66 int digs = DIGITS (M_LONG_LONG_INT);
67 MP_T *z = nil_mp (p, digs);
68 MP_STATUS (z) = (MP_T) INIT_MASK;
69 MP_EXPONENT (z) = (MP_T) (digs - 1);
70 for (int k = 1; k <= digs; k++) {
71 MP_DIGIT (z, k) = (MP_T) (MP_RADIX - 1);
72 }
73 }
74
75 //! @brief LONG REAL long max real
76
77 void genie_long_max_real (NODE_T * p)
78 {
79 int digs = DIGITS (M_LONG_REAL);
80 MP_T *z = nil_mp (p, digs);
81 MP_STATUS (z) = (MP_T) INIT_MASK;
82 MP_EXPONENT (z) = (MP_T) (MAX_MP_EXPONENT - 1);
83 for (int k = 1; k <= digs; k++) {
84 MP_DIGIT (z, k) = (MP_T) (MP_RADIX - 1);
85 }
86 }
87
88 //! @brief LONG LONG REAL long long max real
89
90 void genie_long_mp_max_real (NODE_T * p)
91 {
92 int digs = DIGITS (M_LONG_LONG_REAL);
93 MP_T *z = nil_mp (p, digs);
94 MP_STATUS (z) = (MP_T) INIT_MASK;
95 MP_EXPONENT (z) = (MP_T) (MAX_MP_EXPONENT - 1);
96 for (int k = 1; k <= digs; k++) {
97 MP_DIGIT (z, k) = (MP_T) (MP_RADIX - 1);
98 }
99 }
100
101 //! @brief LONG REAL min long real
102
103 void genie_long_min_real (NODE_T * p)
104 {
105 (void) lit_mp (p, 1, -MAX_MP_EXPONENT, DIGITS (M_LONG_REAL));
106 }
107
108 //! @brief LONG LONG REAL min long long real
109
110 void genie_long_mp_min_real (NODE_T * p)
111 {
112 (void) lit_mp (p, 1, -MAX_MP_EXPONENT, DIGITS (M_LONG_LONG_REAL));
113 }
114
115 //! @brief LONG REAL small long real
116
117 void genie_long_small_real (NODE_T * p)
118 {
119 int digs = DIGITS (M_LONG_REAL);
120 (void) lit_mp (p, 1, 1 - digs, digs);
121 }
122
123 //! @brief LONG LONG REAL small long long real
124
125 void genie_long_mp_small_real (NODE_T * p)
126 {
127 int digs = DIGITS (M_LONG_LONG_REAL);
128 (void) lit_mp (p, 1, 1 - digs, digs);
129 }
130
131 //! @brief OP LENG = (INT) LONG INT
132
133 void genie_lengthen_int_to_mp (NODE_T * p)
134 {
135 int digs = DIGITS (M_LONG_INT);
136 A68G_INT k;
137 POP_OBJECT (p, &k, A68G_INT);
138 MP_T *z = nil_mp (p, digs);
139 (void) int_to_mp (p, z, VALUE (&k), digs);
140 MP_STATUS (z) = (MP_T) INIT_MASK;
141 }
142
143 //! @brief OP SHORTEN = (LONG INT) INT
144
145 void genie_shorten_mp_to_int (NODE_T * p)
146 {
147 MOID_T *mode = LHS_MODE (p);
148 int digs = DIGITS (mode), size = SIZE (mode);
149 DECREMENT_STACK_POINTER (p, size);
150 MP_T *z = (MP_T *) STACK_TOP;
151 MP_STATUS (z) = (MP_T) INIT_MASK;
152 PUSH_VALUE (p, mp_to_int (p, z, digs), A68G_INT);
153 }
154
155 //! @brief OP LENG = (REAL) LONG REAL
156
157 void genie_lengthen_real_to_mp (NODE_T * p)
158 {
159 int digs = DIGITS (M_LONG_REAL);
160 A68G_REAL x;
161 POP_OBJECT (p, &x, A68G_REAL);
162 MP_T *z = nil_mp (p, digs);
163 (void) real_to_mp (p, z, VALUE (&x), digs);
164 MP_STATUS (z) = (MP_T) INIT_MASK;
165 }
166
167 //! @brief OP SHORTEN = (LONG REAL) REAL
168
169 void genie_shorten_mp_to_real (NODE_T * p)
170 {
171 MOID_T *mode = LHS_MODE (p);
172 int digs = DIGITS (mode), size = SIZE (mode);
173 DECREMENT_STACK_POINTER (p, size);
174 MP_T *z = (MP_T *) STACK_TOP;
175 MP_STATUS (z) = (MP_T) INIT_MASK;
176 PUSH_VALUE (p, mp_to_real (p, z, digs), A68G_REAL);
177 }
178
179 //! @brief OP ENTIER = (LONG REAL) LONG INT
180
181 void genie_entier_mp (NODE_T * p)
182 {
183 int digs = DIGITS (LHS_MODE (p)), size = SIZE (LHS_MODE (p));
184 ADDR_T pop_sp = A68G_SP;
185 MP_T *z = (MP_T *) STACK_OFFSET (-size);
186 (void) entier_mp (p, z, z, digs);
187 A68G_SP = pop_sp;
188 }
189
190 #define C_L_FUNCTION(p, f)\
191 int digs = DIGITS (MOID (p)), size = SIZE (MOID (p));\
192 ADDR_T pop_sp = A68G_SP;\
193 MP_T *x = (MP_T *) STACK_OFFSET (-size);\
194 errno = 0;\
195 PRELUDE_ERROR (f (p, x, x, digs) == NaN_MP || errno != 0, p, ERROR_INVALID_ARGUMENT, MOID (p));\
196 MP_STATUS (x) = (MP_T) INIT_MASK;\
197 A68G_SP = pop_sp;
198
199 //! @brief PROC (LONG REAL) LONG REAL long sqrt
200
201 void genie_sqrt_mp (NODE_T * p)
202 {
203 C_L_FUNCTION (p, sqrt_mp);
204 }
205
206 //! @brief PROC (LONG REAL) LONG REAL long curt
207
208 void genie_curt_mp (NODE_T * p)
209 {
210 C_L_FUNCTION (p, curt_mp);
211 }
212
213 //! @brief PROC (LONG REAL) LONG REAL long exp
214
215 void genie_exp_mp (NODE_T * p)
216 {
217 C_L_FUNCTION (p, exp_mp);
218 }
219
220 //! @brief PROC (LONG REAL) LONG REAL long erf
221
222 void genie_erf_mp (NODE_T * p)
223 {
224 C_L_FUNCTION (p, erf_mp);
225 }
226
227 //! @brief PROC (LONG REAL) LONG REAL long inverf
228
229 void genie_inverf_mp (NODE_T * p)
230 {
231 C_L_FUNCTION (p, inverf_mp);
232 }
233
234 //! @brief PROC (LONG REAL) LONG REAL long erfc
235
236 void genie_erfc_mp (NODE_T * p)
237 {
238 C_L_FUNCTION (p, erfc_mp);
239 }
240
241 //! @brief PROC (LONG REAL) LONG REAL long inverfc
242
243 void genie_inverfc_mp (NODE_T * p)
244 {
245 C_L_FUNCTION (p, inverfc_mp);
246 }
247
248 //! @brief PROC (LONG REAL) LONG REAL long gamma
249
250 void genie_gamma_mp (NODE_T * p)
251 {
252 C_L_FUNCTION (p, gamma_mp);
253 }
254
255 //! @brief PROC (LONG REAL) LONG REAL long ln gamma
256
257 void genie_lngamma_mp (NODE_T * p)
258 {
259 C_L_FUNCTION (p, lngamma_mp);
260 }
261
262 //! @brief PROC (LONG REAL) LONG REAL long beta
263
264 void genie_beta_mp (NODE_T * p)
265 {
266 int digs = DIGITS (MOID (p)), size = SIZE (MOID (p));
267 MP_T *b = (MP_T *) STACK_OFFSET (-size);
268 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
269 PRELUDE_ERROR (beta_mp (p, a, a, b, digs) == NaN_MP, p, ERROR_INVALID_ARGUMENT, MOID (p));
270 A68G_SP -= size;
271 MP_STATUS (a) = (MP_T) INIT_MASK;
272 }
273
274 //! @brief PROC (LONG REAL) LONG REAL long ln beta
275
276 void genie_lnbeta_mp (NODE_T * p)
277 {
278 int digs = DIGITS (MOID (p)), size = SIZE (MOID (p));
279 MP_T *b = (MP_T *) STACK_OFFSET (-size);
280 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
281 PRELUDE_ERROR (lnbeta_mp (p, a, a, b, digs) == NaN_MP, p, ERROR_INVALID_ARGUMENT, MOID (p));
282 A68G_SP -= size;
283 MP_STATUS (a) = (MP_T) INIT_MASK;
284 }
285
286 //! @brief PROC (LONG REAL) LONG REAL long beta
287
288 void genie_beta_inc_mp (NODE_T * p)
289 {
290 int digs = DIGITS (MOID (p)), size = SIZE (MOID (p));
291 MP_T *x = (MP_T *) STACK_OFFSET (-size);
292 MP_T *t = (MP_T *) STACK_OFFSET (-2 * size);
293 MP_T *s = (MP_T *) STACK_OFFSET (-3 * size);
294 PRELUDE_ERROR (beta_inc_mp (p, s, s, t, x, digs) == NaN_MP, p, ERROR_INVALID_ARGUMENT, MOID (p));
295 A68G_SP -= 2 * size;
296 MP_STATUS (s) = (MP_T) INIT_MASK;
297 }
298
299 //! @brief PROC (LONG REAL) LONG REAL long ln
300
301 void genie_ln_mp (NODE_T * p)
302 {
303 C_L_FUNCTION (p, ln_mp);
304 }
305
306 //! @brief PROC (LONG REAL) LONG REAL long log
307
308 void genie_log_mp (NODE_T * p)
309 {
310 C_L_FUNCTION (p, log_mp);
311 }
312
313 //! @brief PROC (LONG REAL) LONG REAL long sinh
314
315 void genie_sinh_mp (NODE_T * p)
316 {
317 C_L_FUNCTION (p, sinh_mp);
318 }
319
320 //! @brief PROC (LONG REAL) LONG REAL long cosh
321
322 void genie_cosh_mp (NODE_T * p)
323 {
324 C_L_FUNCTION (p, cosh_mp);
325 }
326
327 //! @brief PROC (LONG REAL) LONG REAL long tanh
328
329 void genie_tanh_mp (NODE_T * p)
330 {
331 C_L_FUNCTION (p, tanh_mp);
332 }
333
334 //! @brief PROC (LONG REAL) LONG REAL long arcsinh
335
336 void genie_asinh_mp (NODE_T * p)
337 {
338 C_L_FUNCTION (p, asinh_mp);
339 }
340
341 //! @brief PROC (LONG REAL) LONG REAL long arccosh
342
343 void genie_acosh_mp (NODE_T * p)
344 {
345 C_L_FUNCTION (p, acosh_mp);
346 }
347
348 //! @brief PROC (LONG REAL) LONG REAL long arctanh
349
350 void genie_atanh_mp (NODE_T * p)
351 {
352 C_L_FUNCTION (p, atanh_mp);
353 }
354
355 //! @brief PROC (LONG REAL) LONG REAL long sin
356
357 void genie_sin_mp (NODE_T * p)
358 {
359 C_L_FUNCTION (p, sin_mp);
360 }
361
362 //! @brief PROC (LONG REAL) LONG REAL long cas
363
364 void genie_cas_mp (NODE_T * p)
365 {
366 C_L_FUNCTION (p, cas_mp);
367 }
368
369 //! @brief PROC (LONG REAL) LONG REAL long cos
370
371 void genie_cos_mp (NODE_T * p)
372 {
373 C_L_FUNCTION (p, cos_mp);
374 }
375
376 //! @brief PROC (LONG REAL) LONG REAL long tan
377
378 void genie_tan_mp (NODE_T * p)
379 {
380 C_L_FUNCTION (p, tan_mp);
381 }
382
383 //! @brief PROC (LONG REAL) LONG REAL long arcsin
384
385 void genie_asin_mp (NODE_T * p)
386 {
387 C_L_FUNCTION (p, asin_mp);
388 }
389
390 //! @brief PROC (LONG REAL) LONG REAL long arccos
391
392 void genie_acos_mp (NODE_T * p)
393 {
394 C_L_FUNCTION (p, acos_mp);
395 }
396
397 //! @brief PROC (LONG REAL) LONG REAL long arctan
398
399 void genie_atan_mp (NODE_T * p)
400 {
401 C_L_FUNCTION (p, atan_mp);
402 }
403
404 //! @brief PROC (LONG REAL, LONG REAL) LONG REAL long arctan2
405
406 void genie_atan2_mp (NODE_T * p)
407 {
408 int digs = DIGITS (MOID (p)), size = SIZE (MOID (p));
409 MP_T *y = (MP_T *) STACK_OFFSET (-size);
410 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
411 PRELUDE_ERROR (atan2_mp (p, x, y, x, digs) == NaN_MP, p, ERROR_INVALID_ARGUMENT, MOID (p));
412 A68G_SP -= size;
413 MP_STATUS (x) = (MP_T) INIT_MASK;
414 }
415
416 // Arithmetic operations.
417
418 //! @brief OP LENG = (LONG MODE) LONG LONG MODE
419
420 void genie_lengthen_mp_to_long_mp (NODE_T * p)
421 {
422 DECREMENT_STACK_POINTER (p, (int) size_mp ());
423 MP_T *z = (MP_T *) STACK_ADDRESS (A68G_SP);
424 z = len_mp (p, z, mp_digits (), long_mp_digits ());
425 MP_STATUS (z) = (MP_T) INIT_MASK;
426 }
427
428 //! @brief OP SHORTEN = (LONG LONG MODE) LONG MODE
429
430 void genie_shorten_long_mp_to_mp (NODE_T * p)
431 {
432 MOID_T *m = SUB_MOID (p);
433 DECREMENT_STACK_POINTER (p, (int) size_long_mp ());
434 MP_T *z = empty_mp (p, mp_digits ());
435 if (m == M_LONG_INT) {
436 PRELUDE_ERROR (MP_EXPONENT (z) > LONG_MP_DIGITS - 1, p, ERROR_OUT_OF_BOUNDS, m);
437 }
438 (void) shorten_mp (p, z, mp_digits (), z, long_mp_digits ());
439 MP_STATUS (z) = (MP_T) INIT_MASK;
440 }
441
442 //! @brief OP - = (LONG MODE) LONG MODE
443
444 void genie_minus_mp (NODE_T * p)
445 {
446 size_t size = SIZE (LHS_MODE (p));
447 MP_T *z = (MP_T *) STACK_OFFSET (-size);
448 MP_STATUS (z) = (MP_T) INIT_MASK;
449 MP_DIGIT (z, 1) = -MP_DIGIT (z, 1);
450 }
451
452 //! @brief OP ABS = (LONG MODE) LONG MODE
453
454 void genie_abs_mp (NODE_T * p)
455 {
456 size_t size = SIZE (LHS_MODE (p));
457 MP_T *z = (MP_T *) STACK_OFFSET (-size);
458 MP_STATUS (z) = (MP_T) INIT_MASK;
459 MP_DIGIT (z, 1) = ABS (MP_DIGIT (z, 1));
460 }
461
462 //! @brief OP SIGN = (LONG MODE) INT
463
464 void genie_sign_mp (NODE_T * p)
465 {
466 size_t size = SIZE (LHS_MODE (p));
467 MP_T *z = (MP_T *) STACK_OFFSET (-size);
468 DECREMENT_STACK_POINTER (p, size);
469 PUSH_VALUE (p, SIGN (MP_DIGIT (z, 1)), A68G_INT);
470 }
471
472 //! @brief OP + = (LONG MODE, LONG MODE) LONG MODE
473
474 void genie_add_mp (NODE_T * p)
475 {
476 MOID_T *mode = RHS_MODE (p);
477 int digs = DIGITS (mode), size = SIZE (mode);
478 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
479 MP_T *y = (MP_T *) STACK_OFFSET (-size);
480 (void) add_mp (p, x, x, y, digs);
481 MP_STATUS (x) = (MP_T) INIT_MASK;
482 DECREMENT_STACK_POINTER (p, size);
483 }
484
485 //! @brief OP - = (LONG MODE, LONG MODE) LONG MODE
486
487 void genie_sub_mp (NODE_T * p)
488 {
489 MOID_T *mode = RHS_MODE (p);
490 int digs = DIGITS (mode), size = SIZE (mode);
491 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
492 MP_T *y = (MP_T *) STACK_OFFSET (-size);
493 (void) sub_mp (p, x, x, y, digs);
494 MP_STATUS (x) = (MP_T) INIT_MASK;
495 DECREMENT_STACK_POINTER (p, size);
496 }
497
498 //! @brief OP * = (LONG MODE, LONG MODE) LONG MODE
499
500 void genie_mul_mp (NODE_T * p)
501 {
502 MOID_T *mode = RHS_MODE (p);
503 int digs = DIGITS (mode), size = SIZE (mode);
504 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
505 MP_T *y = (MP_T *) STACK_OFFSET (-size);
506 (void) mul_mp (p, x, x, y, digs);
507 MP_STATUS (x) = (MP_T) INIT_MASK;
508 DECREMENT_STACK_POINTER (p, size);
509 }
510
511 //! @brief OP / = (LONG MODE, LONG MODE) LONG MODE
512
513 void genie_div_mp (NODE_T * p)
514 {
515 MOID_T *mode = RHS_MODE (p);
516 int digs = DIGITS (mode), size = SIZE (mode);
517 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
518 MP_T *y = (MP_T *) STACK_OFFSET (-size);
519 PRELUDE_ERROR (div_mp (p, x, x, y, digs) == NaN_MP, p, ERROR_DIVISION_BY_ZERO, mode);
520 MP_STATUS (x) = (MP_T) INIT_MASK;
521 DECREMENT_STACK_POINTER (p, size);
522 }
523
524 //! @brief OP % = (LONG MODE, LONG MODE) LONG MODE
525
526 void genie_over_mp (NODE_T * p)
527 {
528 MOID_T *mode = RHS_MODE (p);
529 int digs = DIGITS (mode), size = SIZE (mode);
530 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
531 MP_T *y = (MP_T *) STACK_OFFSET (-size);
532 PRELUDE_ERROR (over_mp (p, x, x, y, digs) == NaN_MP, p, ERROR_DIVISION_BY_ZERO, mode);
533 MP_STATUS (x) = (MP_T) INIT_MASK;
534 DECREMENT_STACK_POINTER (p, size);
535 }
536
537 //! @brief OP %* = (LONG MODE, LONG MODE) LONG MODE
538
539 void genie_mod_mp (NODE_T * p)
540 {
541 MOID_T *mode = RHS_MODE (p);
542 int digs = DIGITS (mode), size = SIZE (mode);
543 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
544 MP_T *y = (MP_T *) STACK_OFFSET (-size);
545 PRELUDE_ERROR (mod_mp (p, x, x, y, digs) == NaN_MP, p, ERROR_DIVISION_BY_ZERO, mode);
546 if (MP_DIGIT (x, 1) < 0) {
547 MP_DIGIT (y, 1) = ABS (MP_DIGIT (y, 1));
548 (void) add_mp (p, x, x, y, digs);
549 }
550 MP_STATUS (x) = (MP_T) INIT_MASK;
551 DECREMENT_STACK_POINTER (p, size);
552 }
553
554 //! @brief OP +:= = (REF LONG MODE, LONG MODE) REF LONG MODE
555
556 void genie_plusab_mp (NODE_T * p)
557 {
558 MOID_T *mode = LHS_MODE (p);
559 genie_f_and_becomes (p, mode, genie_add_mp);
560 }
561
562 //! @brief OP -:= = (REF LONG MODE, LONG MODE) REF LONG MODE
563
564 void genie_minusab_mp (NODE_T * p)
565 {
566 MOID_T *mode = LHS_MODE (p);
567 genie_f_and_becomes (p, mode, genie_sub_mp);
568 }
569
570 //! @brief OP *:= = (REF LONG MODE, LONG MODE) REF LONG MODE
571
572 void genie_timesab_mp (NODE_T * p)
573 {
574 MOID_T *mode = LHS_MODE (p);
575 genie_f_and_becomes (p, mode, genie_mul_mp);
576 }
577
578 //! @brief OP /:= = (REF LONG MODE, LONG MODE) REF LONG MODE
579
580 void genie_divab_mp (NODE_T * p)
581 {
582 MOID_T *mode = LHS_MODE (p);
583 genie_f_and_becomes (p, mode, genie_div_mp);
584 }
585
586 //! @brief OP %:= = (REF LONG MODE, LONG MODE) REF LONG MODE
587
588 void genie_overab_mp (NODE_T * p)
589 {
590 MOID_T *mode = LHS_MODE (p);
591 genie_f_and_becomes (p, mode, genie_over_mp);
592 }
593
594 //! @brief OP %*:= = (REF LONG MODE, LONG MODE) REF LONG MODE
595
596 void genie_modab_mp (NODE_T * p)
597 {
598 MOID_T *mode = LHS_MODE (p);
599 genie_f_and_becomes (p, mode, genie_mod_mp);
600 }
601
602 // OP (LONG MODE, LONG MODE) BOOL.
603
604 #define A68G_CMP_LONG(n, OP)\
605 void n (NODE_T * p) {\
606 MOID_T *mode = LHS_MODE (p);\
607 A68G_BOOL z;\
608 int digs = DIGITS (mode), size = SIZE (mode);\
609 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);\
610 MP_T *y = (MP_T *) STACK_OFFSET (-size);\
611 OP (p, &z, x, y, digs);\
612 DECREMENT_STACK_POINTER (p, 2 * size);\
613 PUSH_VALUE (p, VALUE (&z), A68G_BOOL);\
614 }
615
616 A68G_CMP_LONG (genie_eq_mp, eq_mp);
617 A68G_CMP_LONG (genie_ne_mp, ne_mp);
618 A68G_CMP_LONG (genie_lt_mp, lt_mp);
619 A68G_CMP_LONG (genie_gt_mp, gt_mp);
620 A68G_CMP_LONG (genie_le_mp, le_mp);
621 A68G_CMP_LONG (genie_ge_mp, ge_mp);
622
623 //! @brief OP ** = (LONG MODE, INT) LONG MODE
624
625 void genie_pow_mp_int (NODE_T * p)
626 {
627 MOID_T *mode = LHS_MODE (p);
628 int digs = DIGITS (mode), size = SIZE (mode);
629 A68G_INT k;
630 POP_OBJECT (p, &k, A68G_INT);
631 MP_T *x = (MP_T *) STACK_OFFSET (-size);
632 (void) pow_mp_int (p, x, x, VALUE (&k), digs);
633 MP_STATUS (x) = (MP_T) INIT_MASK;
634 }
635
636 //! @brief OP ** = (LONG MODE, LONG MODE) LONG MODE
637
638 void genie_pow_mp (NODE_T * p)
639 {
640 MOID_T *mode = LHS_MODE (p);
641 int digs = DIGITS (mode), size = SIZE (mode);
642 ADDR_T pop_sp = A68G_SP;
643 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
644 MP_T *y = (MP_T *) STACK_OFFSET (-size);
645 if (IS_ZERO_MP (x)) {
646 if (MP_DIGIT (y, 1) < (MP_T) 0) {
647 PRELUDE_ERROR (A68G_TRUE, p, ERROR_INVALID_ARGUMENT, MOID (p));
648 } else if (IS_ZERO_MP (y)) {
649 SET_MP_ONE (x, digs);
650 }
651 } else {
652 (void) pow_mp (p, x, x, y, digs);
653 }
654 A68G_SP = pop_sp - size;
655 MP_STATUS (x) = (MP_T) INIT_MASK;
656 }
657
658 //! @brief OP ODD = (LONG INT) BOOL
659
660 void genie_odd_mp (NODE_T * p)
661 {
662 MOID_T *mode = LHS_MODE (p);
663 int digs = DIGITS (mode), size = SIZE (mode);
664 MP_T *z = (MP_T *) STACK_OFFSET (-size);
665 DECREMENT_STACK_POINTER (p, size);
666 if (MP_EXPONENT (z) <= (MP_T) (digs - 1)) {
667 PUSH_VALUE (p, (BOOL_T) ! EVEN ((MP_INT_T) (z[(int) (2 + MP_EXPONENT (z))])), A68G_BOOL);
668 } else {
669 PUSH_VALUE (p, A68G_FALSE, A68G_BOOL);
670 }
671 }
672
673 //! @brief Test whether z is a valid LONG INT.
674
675 void test_mp_int_range (NODE_T * p, MP_T * z, MOID_T * m)
676 {
677 PRELUDE_ERROR (!check_mp_int (z, m), p, ERROR_OUT_OF_BOUNDS, m);
678 }
679
680 //! @brief OP + = (LONG INT, LONG INT) LONG INT
681
682 void genie_add_mp_int (NODE_T * p)
683 {
684 MOID_T *m = RHS_MODE (p);
685 int digs = DIGITS (m), size = SIZE (m);
686 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
687 MP_T *y = (MP_T *) STACK_OFFSET (-size);
688 (void) add_mp (p, x, x, y, digs);
689 test_mp_int_range (p, x, m);
690 MP_STATUS (x) = (MP_T) INIT_MASK;
691 DECREMENT_STACK_POINTER (p, size);
692 }
693
694 //! @brief OP - = (LONG INT, LONG INT) LONG INT
695
696 void genie_sub_mp_int (NODE_T * p)
697 {
698 MOID_T *m = RHS_MODE (p);
699 int digs = DIGITS (m), size = SIZE (m);
700 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
701 MP_T *y = (MP_T *) STACK_OFFSET (-size);
702 (void) sub_mp (p, x, x, y, digs);
703 test_mp_int_range (p, x, m);
704 MP_STATUS (x) = (MP_T) INIT_MASK;
705 DECREMENT_STACK_POINTER (p, size);
706 }
707
708 //! @brief OP * = (LONG INT, LONG INT) LONG INT
709
710 void genie_mul_mp_int (NODE_T * p)
711 {
712 MOID_T *m = RHS_MODE (p);
713 int digs = DIGITS (m), size = SIZE (m);
714 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
715 MP_T *y = (MP_T *) STACK_OFFSET (-size);
716 (void) mul_mp (p, x, x, y, digs);
717 test_mp_int_range (p, x, m);
718 MP_STATUS (x) = (MP_T) INIT_MASK;
719 DECREMENT_STACK_POINTER (p, size);
720 }
721
722 //! @brief OP ** = (LONG MODE, INT) LONG INT
723
724 void genie_pow_mp_int_int (NODE_T * p)
725 {
726 MOID_T *m = LHS_MODE (p);
727 int digs = DIGITS (m), size = SIZE (m);
728 A68G_INT k;
729 POP_OBJECT (p, &k, A68G_INT);
730 MP_T *x = (MP_T *) STACK_OFFSET (-size);
731 (void) pow_mp_int (p, x, x, VALUE (&k), digs);
732 test_mp_int_range (p, x, m);
733 MP_STATUS (x) = (MP_T) INIT_MASK;
734 }
735
736 //! @brief OP +:= = (REF LONG INT, LONG INT) REF LONG INT
737
738 void genie_plusab_mp_int (NODE_T * p)
739 {
740 MOID_T *mode = LHS_MODE (p);
741 genie_f_and_becomes (p, mode, genie_add_mp_int);
742 }
743
744 //! @brief OP -:= = (REF LONG INT, LONG INT) REF LONG INT
745
746 void genie_minusab_mp_int (NODE_T * p)
747 {
748 MOID_T *mode = LHS_MODE (p);
749 genie_f_and_becomes (p, mode, genie_sub_mp_int);
750 }
751
752 //! @brief OP *:= = (REF LONG INT, LONG INT) REF LONG INT
753
754 void genie_timesab_mp_int (NODE_T * p)
755 {
756 MOID_T *mode = LHS_MODE (p);
757 genie_f_and_becomes (p, mode, genie_mul_mp_int);
758 }
759
760 //! @brief OP ROUND = (LONG REAL) LONG INT
761
762 void genie_round_mp (NODE_T * p)
763 {
764 MOID_T *mode = LHS_MODE (p);
765 int digs = DIGITS (mode), size = SIZE (mode);
766 ADDR_T pop_sp = A68G_SP;
767 MP_T *z = (MP_T *) STACK_OFFSET (-size);
768 (void) round_mp (p, z, z, digs);
769 A68G_SP = pop_sp;
770 }
771
772 #define C_CL_FUNCTION(p, f)\
773 MOID_T *mode = MOID (p);\
774 int digs = DIGITS_COMPL (mode), size = SIZE_COMPL (mode);\
775 ADDR_T pop_sp = A68G_SP;\
776 MP_T *im = (MP_T *) STACK_OFFSET (-size);\
777 MP_T *re = (MP_T *) STACK_OFFSET (-2 * size);\
778 errno = 0;\
779 (void) f(p, re, im, digs);\
780 A68G_SP = pop_sp;\
781 MP_STATUS (re) = (MP_T) INIT_MASK;\
782 MP_STATUS (im) = (MP_T) INIT_MASK;\
783 MATH_RTE (p, errno != 0, mode, NO_TEXT);\
784
785 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long csqrt
786
787 void genie_sqrt_mp_complex (NODE_T * p)
788 {
789 C_CL_FUNCTION (p, csqrt_mp);
790 }
791
792 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long cexp
793
794 void genie_exp_mp_complex (NODE_T * p)
795 {
796 C_CL_FUNCTION (p, cexp_mp);
797 }
798
799 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long cln
800
801 void genie_ln_mp_complex (NODE_T * p)
802 {
803 C_CL_FUNCTION (p, cln_mp);
804 }
805
806 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long csin
807
808 void genie_sin_mp_complex (NODE_T * p)
809 {
810 C_CL_FUNCTION (p, csin_mp);
811 }
812
813 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long ccos
814
815 void genie_cos_mp_complex (NODE_T * p)
816 {
817 C_CL_FUNCTION (p, ccos_mp);
818 }
819
820 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long ctan
821
822 void genie_tan_mp_complex (NODE_T * p)
823 {
824 C_CL_FUNCTION (p, ctan_mp);
825 }
826
827 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long arcsin
828
829 void genie_asin_mp_complex (NODE_T * p)
830 {
831 C_CL_FUNCTION (p, casin_mp);
832 }
833
834 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long carccos
835
836 void genie_acos_mp_complex (NODE_T * p)
837 {
838 C_CL_FUNCTION (p, cacos_mp);
839 }
840
841 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long catan
842
843 void genie_atan_mp_complex (NODE_T * p)
844 {
845 C_CL_FUNCTION (p, catan_mp);
846 }
847
848 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long csinh
849
850 void genie_sinh_mp_complex (NODE_T * p)
851 {
852 C_CL_FUNCTION (p, csinh_mp);
853 }
854
855 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long ccosh
856
857 void genie_cosh_mp_complex (NODE_T * p)
858 {
859 C_CL_FUNCTION (p, ccosh_mp);
860 }
861
862 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long ctanh
863
864 void genie_tanh_mp_complex (NODE_T * p)
865 {
866 C_CL_FUNCTION (p, ctanh_mp);
867 }
868
869 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long carcsinh
870
871 void genie_asinh_mp_complex (NODE_T * p)
872 {
873 C_CL_FUNCTION (p, casinh_mp);
874 }
875
876 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long carccosh
877
878 void genie_acosh_mp_complex (NODE_T * p)
879 {
880 C_CL_FUNCTION (p, cacosh_mp);
881 }
882
883 //! @brief PROC (LONG COMPLEX) LONG COMPLEX long carctanh
884
885 void genie_atanh_mp_complex (NODE_T * p)
886 {
887 C_CL_FUNCTION (p, catanh_mp);
888 }
889
890 //! @brief OP LENG = (COMPLEX) LONG COMPLEX
891
892 void genie_lengthen_complex_to_mp_complex (NODE_T * p)
893 {
894 int digs = DIGITS (M_LONG_REAL);
895 A68G_REAL a, b;
896 POP_OBJECT (p, &b, A68G_REAL);
897 POP_OBJECT (p, &a, A68G_REAL);
898 MP_T *z = nil_mp (p, digs);
899 (void) real_to_mp (p, z, VALUE (&a), digs);
900 MP_STATUS (z) = (MP_T) INIT_MASK;
901 z = nil_mp (p, digs);
902 (void) real_to_mp (p, z, VALUE (&b), digs);
903 MP_STATUS (z) = (MP_T) INIT_MASK;
904 }
905
906 //! @brief OP SHORTEN = (LONG COMPLEX) COMPLEX
907
908 void genie_shorten_mp_complex_to_complex (NODE_T * p)
909 {
910 int digs = DIGITS (M_LONG_REAL), size = SIZE (M_LONG_REAL);
911 MP_T *b = (MP_T *) STACK_OFFSET (-size);
912 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
913 DECREMENT_STACK_POINTER (p, 2 * size);
914 PUSH_COMPLEX_VALUE (p, mp_to_real (p, a, digs), mp_to_real (p, b, digs));
915 }
916
917 //! @brief OP LENG = (LONG COMPLEX) LONG LONG COMPLEX
918
919 void genie_lengthen_mp_complex_to_long_mp_complex (NODE_T * p)
920 {
921 int digs = DIGITS (M_LONG_REAL), size = SIZE (M_LONG_REAL);
922 int gdigs = DIGITS (M_LONG_LONG_REAL), size_g = SIZE (M_LONG_LONG_REAL);
923 ADDR_T pop_sp = A68G_SP;
924 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
925 MP_T *b = (MP_T *) STACK_OFFSET (-size);
926 MP_T *c = len_mp (p, a, digs, gdigs);
927 MP_T *d = len_mp (p, b, digs, gdigs);
928 (void) move_mp (a, c, gdigs);
929 (void) move_mp (&a[LEN_MP (gdigs)], d, gdigs);
930 A68G_SP = pop_sp;
931 INCREMENT_STACK_POINTER (p, 2 * (size_g - size));
932 }
933
934 //! @brief OP SHORTEN = (LONG LONG COMPLEX) LONG COMPLEX
935
936 void genie_shorten_long_mp_complex_to_mp_complex (NODE_T * p)
937 {
938 int digs = DIGITS (M_LONG_REAL), size = SIZE (M_LONG_REAL);
939 int gdigs = DIGITS (M_LONG_LONG_REAL), size_g = SIZE (M_LONG_LONG_REAL);
940 ADDR_T pop_sp = A68G_SP;
941 MP_T *b = (MP_T *) STACK_OFFSET (-size_g);
942 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size_g);
943 (void) shorten_mp (p, a, digs, a, gdigs);
944 (void) shorten_mp (p, &a[LEN_MP (digs)], digs, b, gdigs);
945 A68G_SP = pop_sp;
946 MP_STATUS (a) = (MP_T) INIT_MASK;
947 MP_STATUS (&a[LEN_MP (digs)]) = (MP_T) INIT_MASK;
948 DECREMENT_STACK_POINTER (p, 2 * (size_g - size));
949 }
950
951 //! @brief OP RE = (LONG COMPLEX) LONG REAL
952
953 void genie_re_mp_complex (NODE_T * p)
954 {
955 size_t size = SIZE (SUB_MOID (p));
956 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
957 MP_STATUS (a) = (MP_T) INIT_MASK;
958 DECREMENT_STACK_POINTER (p, size);
959 }
960
961 //! @brief OP IM = (LONG COMPLEX) LONG REAL
962
963 void genie_im_mp_complex (NODE_T * p)
964 {
965 MOID_T *mode = SUB_MOID (p);
966 int digs = DIGITS (mode), size = SIZE (mode);
967 MP_T *b = (MP_T *) STACK_OFFSET (-size);
968 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
969 (void) move_mp (a, b, digs);
970 MP_STATUS (a) = (MP_T) INIT_MASK;
971 DECREMENT_STACK_POINTER (p, size);
972 }
973
974 //! @brief OP - = (LONG COMPLEX) LONG COMPLEX
975
976 void genie_minus_mp_complex (NODE_T * p)
977 {
978 size_t size = SIZE_COMPL (SUB_MOID (p));
979 MP_T *b = (MP_T *) STACK_OFFSET (-size);
980 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
981 MP_DIGIT (a, 1) = -MP_DIGIT (a, 1);
982 MP_DIGIT (b, 1) = -MP_DIGIT (b, 1);
983 MP_STATUS (a) = (MP_T) INIT_MASK;
984 MP_STATUS (b) = (MP_T) INIT_MASK;
985 }
986
987 //! @brief OP CONJ = (LONG COMPLEX) LONG COMPLEX
988
989 void genie_conj_mp_complex (NODE_T * p)
990 {
991 size_t size = SIZE_COMPL (SUB_MOID (p));
992 MP_T *b = (MP_T *) STACK_OFFSET (-size);
993 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
994 MP_DIGIT (b, 1) = -MP_DIGIT (b, 1);
995 MP_STATUS (a) = (MP_T) INIT_MASK;
996 MP_STATUS (b) = (MP_T) INIT_MASK;
997 }
998
999 //! @brief OP ABS = (LONG COMPLEX) LONG REAL
1000
1001 void genie_abs_mp_complex (NODE_T * p)
1002 {
1003 MOID_T *mode = SUB_MOID (p);
1004 int digs = DIGITS (mode), size = SIZE (mode);
1005 ADDR_T pop_sp = A68G_SP;
1006 MP_T *b = (MP_T *) STACK_OFFSET (-size);
1007 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
1008 MP_T *z = nil_mp (p, digs);
1009 errno = 0;
1010 (void) hypot_mp (p, z, a, b, digs);
1011 A68G_SP = pop_sp;
1012 DECREMENT_STACK_POINTER (p, size);
1013 (void) move_mp (a, z, digs);
1014 MP_STATUS (a) = (MP_T) INIT_MASK;
1015 MATH_RTE (p, errno != 0, mode, NO_TEXT);
1016 }
1017
1018 //! @brief OP ARG = (LONG COMPLEX) LONG REAL
1019
1020 void genie_arg_mp_complex (NODE_T * p)
1021 {
1022 MOID_T *mode = SUB_MOID (p);
1023 int digs = DIGITS (mode), size = SIZE (mode);
1024 ADDR_T pop_sp = A68G_SP;
1025 MP_T *b = (MP_T *) STACK_OFFSET (-size);
1026 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
1027 MP_T *z = nil_mp (p, digs);
1028 errno = 0;
1029 (void) atan2_mp (p, z, a, b, digs);
1030 A68G_SP = pop_sp;
1031 DECREMENT_STACK_POINTER (p, size);
1032 (void) move_mp (a, z, digs);
1033 MP_STATUS (a) = (MP_T) INIT_MASK;
1034 MATH_RTE (p, errno != 0, mode, NO_TEXT);
1035 }
1036
1037 //! @brief OP + = (LONG COMPLEX, LONG COMPLEX) LONG COMPLEX
1038
1039 void genie_add_mp_complex (NODE_T * p)
1040 {
1041 MOID_T *mode = SUB_MOID (p);
1042 int digs = DIGITS_COMPL (mode), size = SIZE_COMPL (mode);
1043 ADDR_T pop_sp = A68G_SP;
1044 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1045 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1046 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1047 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1048 (void) add_mp (p, b, b, d, digs);
1049 (void) add_mp (p, a, a, c, digs);
1050 MP_STATUS (a) = (MP_T) INIT_MASK;
1051 MP_STATUS (b) = (MP_T) INIT_MASK;
1052 A68G_SP = pop_sp;
1053 DECREMENT_STACK_POINTER (p, 2 * size);
1054 }
1055
1056 //! @brief OP - = (LONG COMPLEX, LONG COMPLEX) LONG COMPLEX
1057
1058 void genie_sub_mp_complex (NODE_T * p)
1059 {
1060 MOID_T *mode = SUB_MOID (p);
1061 int digs = DIGITS_COMPL (mode), size = SIZE_COMPL (mode);
1062 ADDR_T pop_sp = A68G_SP;
1063 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1064 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1065 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1066 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1067 (void) sub_mp (p, b, b, d, digs);
1068 (void) sub_mp (p, a, a, c, digs);
1069 MP_STATUS (a) = (MP_T) INIT_MASK;
1070 MP_STATUS (b) = (MP_T) INIT_MASK;
1071 A68G_SP = pop_sp;
1072 DECREMENT_STACK_POINTER (p, 2 * size);
1073 }
1074
1075 //! @brief OP * = (LONG COMPLEX, LONG COMPLEX) LONG COMPLEX
1076
1077 void genie_mul_mp_complex (NODE_T * p)
1078 {
1079 MOID_T *mode = SUB_MOID (p);
1080 int digs = DIGITS_COMPL (mode), size = SIZE_COMPL (mode);
1081 ADDR_T pop_sp = A68G_SP;
1082 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1083 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1084 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1085 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1086 (void) cmul_mp (p, a, b, c, d, digs);
1087 MP_STATUS (a) = (MP_T) INIT_MASK;
1088 MP_STATUS (b) = (MP_T) INIT_MASK;
1089 A68G_SP = pop_sp;
1090 DECREMENT_STACK_POINTER (p, 2 * size);
1091 }
1092
1093 //! @brief OP / = (LONG COMPLEX, LONG COMPLEX) LONG COMPLEX
1094
1095 void genie_div_mp_complex (NODE_T * p)
1096 {
1097 MOID_T *mode = SUB_MOID (p);
1098 int digs = DIGITS_COMPL (mode), size = SIZE_COMPL (mode);
1099 ADDR_T pop_sp = A68G_SP;
1100 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1101 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1102 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1103 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1104 PRELUDE_ERROR (cdiv_mp (p, a, b, c, d, digs) == NaN_MP, p, ERROR_DIVISION_BY_ZERO, mode);
1105 MP_STATUS (a) = (MP_T) INIT_MASK;
1106 MP_STATUS (b) = (MP_T) INIT_MASK;
1107 A68G_SP = pop_sp;
1108 DECREMENT_STACK_POINTER (p, 2 * size);
1109 }
1110
1111 //! @brief OP ** = (LONG COMPLEX, INT) LONG COMPLEX
1112
1113 void genie_pow_mp_complex_int (NODE_T * p)
1114 {
1115 MOID_T *mode = SUB_MOID (p);
1116 int digs = DIGITS_COMPL (mode), size = SIZE_COMPL (mode);
1117 A68G_INT j;
1118 POP_OBJECT (p, &j, A68G_INT);
1119 ADDR_T pop_sp = A68G_SP;
1120 MP_T *im_x = (MP_T *) STACK_OFFSET (-size);
1121 MP_T *re_x = (MP_T *) STACK_OFFSET (-2 * size);
1122 MP_T *re_z = lit_mp (p, 1, 0, digs);
1123 MP_T *im_z = nil_mp (p, digs);
1124 MP_T *re_y = nil_mp (p, digs);
1125 MP_T *im_y = nil_mp (p, digs);
1126 (void) move_mp (re_y, re_x, digs);
1127 (void) move_mp (im_y, im_x, digs);
1128 MP_T *rea = nil_mp (p, digs);
1129 MP_T *acc = nil_mp (p, digs);
1130 int expo = 1;
1131 BOOL_T negative = (BOOL_T) (VALUE (&j) < 0);
1132 if (negative) {
1133 VALUE (&j) = -VALUE (&j);
1134 }
1135 while ((int) expo <= (int) (VALUE (&j))) {
1136 if (expo & VALUE (&j)) {
1137 (void) mul_mp (p, acc, im_z, im_y, digs);
1138 (void) mul_mp (p, rea, re_z, re_y, digs);
1139 (void) sub_mp (p, rea, rea, acc, digs);
1140 (void) mul_mp (p, acc, im_z, re_y, digs);
1141 (void) mul_mp (p, im_z, re_z, im_y, digs);
1142 (void) add_mp (p, im_z, im_z, acc, digs);
1143 (void) move_mp (re_z, rea, digs);
1144 }
1145 (void) mul_mp (p, acc, im_y, im_y, digs);
1146 (void) mul_mp (p, rea, re_y, re_y, digs);
1147 (void) sub_mp (p, rea, rea, acc, digs);
1148 (void) mul_mp (p, acc, im_y, re_y, digs);
1149 (void) mul_mp (p, im_y, re_y, im_y, digs);
1150 (void) add_mp (p, im_y, im_y, acc, digs);
1151 (void) move_mp (re_y, rea, digs);
1152 expo <<= 1;
1153 }
1154 A68G_SP = pop_sp;
1155 if (negative) {
1156 SET_MP_ONE (re_x, digs);
1157 SET_MP_ZERO (im_x, digs);
1158 INCREMENT_STACK_POINTER (p, 2 * size);
1159 genie_div_mp_complex (p);
1160 } else {
1161 (void) move_mp (re_x, re_z, digs);
1162 (void) move_mp (im_x, im_z, digs);
1163 }
1164 MP_STATUS (re_x) = (MP_T) INIT_MASK;
1165 MP_STATUS (im_x) = (MP_T) INIT_MASK;
1166 }
1167
1168 //! @brief OP = = (LONG COMPLEX, LONG COMPLEX) BOOL
1169
1170 void genie_eq_mp_complex (NODE_T * p)
1171 {
1172 int digs = DIGITS_COMPL (LHS_MODE (p)), size = SIZE_COMPL (LHS_MODE (p));
1173 ADDR_T pop_sp = A68G_SP;
1174 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1175 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1176 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1177 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1178 (void) sub_mp (p, b, b, d, digs);
1179 (void) sub_mp (p, a, a, c, digs);
1180 A68G_SP = pop_sp;
1181 DECREMENT_STACK_POINTER (p, 4 * size);
1182 PUSH_VALUE (p, (BOOL_T) (MP_DIGIT (a, 1) == 0 && MP_DIGIT (b, 1) == 0), A68G_BOOL);
1183 }
1184
1185 //! @brief OP /= = (LONG COMPLEX, LONG COMPLEX) BOOL
1186
1187 void genie_ne_mp_complex (NODE_T * p)
1188 {
1189 int digs = DIGITS_COMPL (LHS_MODE (p)), size = SIZE_COMPL (LHS_MODE (p));
1190 ADDR_T pop_sp = A68G_SP;
1191 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1192 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1193 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1194 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1195 (void) sub_mp (p, b, b, d, digs);
1196 (void) sub_mp (p, a, a, c, digs);
1197 A68G_SP = pop_sp;
1198 DECREMENT_STACK_POINTER (p, 4 * size);
1199 PUSH_VALUE (p, (BOOL_T) (MP_DIGIT (a, 1) != 0 || MP_DIGIT (b, 1) != 0), A68G_BOOL);
1200 }
1201
1202 //! @brief OP +:= = (REF LONG COMPLEX, LONG COMPLEX) REF LONG COMPLEX
1203
1204 void genie_plusab_mp_complex (NODE_T * p)
1205 {
1206 MOID_T *mode = LHS_MODE (p);
1207 genie_f_and_becomes (p, mode, genie_add_mp_complex);
1208 }
1209
1210 //! @brief OP -:= = (REF LONG COMPLEX, LONG COMPLEX) REF LONG COMPLEX
1211
1212 void genie_minusab_mp_complex (NODE_T * p)
1213 {
1214 MOID_T *mode = LHS_MODE (p);
1215 genie_f_and_becomes (p, mode, genie_sub_mp_complex);
1216 }
1217
1218 //! @brief OP *:= = (REF LONG COMPLEX, LONG COMPLEX) REF LONG COMPLEX
1219
1220 void genie_timesab_mp_complex (NODE_T * p)
1221 {
1222 MOID_T *mode = LHS_MODE (p);
1223 genie_f_and_becomes (p, mode, genie_mul_mp_complex);
1224 }
1225
1226 //! @brief OP /:= = (REF LONG COMPLEX, LONG COMPLEX) REF LONG COMPLEX
1227
1228 void genie_divab_mp_complex (NODE_T * p)
1229 {
1230 MOID_T *mode = LHS_MODE (p);
1231 genie_f_and_becomes (p, mode, genie_div_mp_complex);
1232 }
1233
1234 //! @brief PROC LONG REAL next long random
1235
1236 void genie_long_next_random (NODE_T * p)
1237 {
1238 // This is 'real width' precision only.
1239 genie_next_random (p);
1240 genie_lengthen_real_to_mp (p);
1241 if (MOID (p) == M_LONG_LONG_REAL) {
1242 genie_lengthen_mp_to_long_mp (p);
1243 }
1244 }
1245
1246 //! @brief PROC (LONG REAL) LONG REAL long csc
1247
1248 void genie_csc_mp (NODE_T * p)
1249 {
1250 C_L_FUNCTION (p, csc_mp);
1251 }
1252
1253 //! @brief PROC (LONG REAL) LONG REAL long acsc
1254
1255 void genie_acsc_mp (NODE_T * p)
1256 {
1257 C_L_FUNCTION (p, acsc_mp);
1258 }
1259
1260 //! @brief PROC (LONG REAL) LONG REAL long sec
1261
1262 void genie_sec_mp (NODE_T * p)
1263 {
1264 C_L_FUNCTION (p, sec_mp);
1265 }
1266
1267 //! @brief PROC (LONG REAL) LONG REAL long asec
1268
1269 void genie_asec_mp (NODE_T * p)
1270 {
1271 C_L_FUNCTION (p, asec_mp);
1272 }
1273
1274 //! @brief PROC (LONG REAL) LONG REAL long cot
1275
1276 void genie_cot_mp (NODE_T * p)
1277 {
1278 C_L_FUNCTION (p, cot_mp);
1279 }
1280
1281 //! @brief PROC (LONG REAL) LONG REAL long acot
1282
1283 void genie_acot_mp (NODE_T * p)
1284 {
1285 C_L_FUNCTION (p, acot_mp);
1286 }
1287
1288 //! @brief PROC (LONG REAL) LONG REAL long sindg
1289
1290 void genie_sindg_mp (NODE_T * p)
1291 {
1292 C_L_FUNCTION (p, sindg_mp);
1293 }
1294
1295 //! @brief PROC (LONG REAL) LONG REAL long cosdg
1296
1297 void genie_cosdg_mp (NODE_T * p)
1298 {
1299 C_L_FUNCTION (p, cosdg_mp);
1300 }
1301
1302 //! @brief PROC (LONG REAL) LONG REAL long tandg
1303
1304 void genie_tandg_mp (NODE_T * p)
1305 {
1306 C_L_FUNCTION (p, tandg_mp);
1307 }
1308
1309 //! @brief PROC (LONG REAL) LONG REAL long secdg
1310
1311 void genie_secdg_mp (NODE_T * p)
1312 {
1313 C_L_FUNCTION (p, secdg_mp);
1314 }
1315
1316 //! @brief PROC (LONG REAL) LONG REAL long asecdg
1317
1318 void genie_asecdg_mp (NODE_T * p)
1319 {
1320 C_L_FUNCTION (p, asecdg_mp);
1321 }
1322
1323 //! @brief PROC (LONG REAL) LONG REAL long cscdg
1324
1325 void genie_cscdg_mp (NODE_T * p)
1326 {
1327 C_L_FUNCTION (p, cscdg_mp);
1328 }
1329
1330 //! @brief PROC (LONG REAL) LONG REAL long acscdg
1331
1332 void genie_acscdg_mp (NODE_T * p)
1333 {
1334 C_L_FUNCTION (p, acscdg_mp);
1335 }
1336
1337 //! @brief PROC (LONG REAL) LONG REAL long cotdg
1338
1339 void genie_cotdg_mp (NODE_T * p)
1340 {
1341 C_L_FUNCTION (p, cotdg_mp);
1342 }
1343
1344 //! @brief PROC (LONG REAL) LONG REAL long asindg
1345
1346 void genie_asindg_mp (NODE_T * p)
1347 {
1348 C_L_FUNCTION (p, asindg_mp);
1349 }
1350
1351 //! @brief PROC (LONG REAL) LONG REAL long acosdg
1352
1353 void genie_acosdg_mp (NODE_T * p)
1354 {
1355 C_L_FUNCTION (p, acosdg_mp);
1356 }
1357
1358 //! @brief PROC (LONG REAL) LONG REAL long atandg
1359
1360 void genie_atandg_mp (NODE_T * p)
1361 {
1362 C_L_FUNCTION (p, atandg_mp);
1363 }
1364
1365 //! @brief PROC (LONG REAL) LONG REAL long acotdg
1366
1367 void genie_acotdg_mp (NODE_T * p)
1368 {
1369 C_L_FUNCTION (p, acotdg_mp);
1370 }
1371
1372 //! @brief PROC (LONG REAL, LONG REAL) LONG REAL long arctan2
1373
1374 void genie_atan2dg_mp (NODE_T * p)
1375 {
1376 int digs = DIGITS (MOID (p)), size = SIZE (MOID (p));
1377 MP_T *y = (MP_T *) STACK_OFFSET (-size);
1378 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
1379 PRELUDE_ERROR (atan2dg_mp (p, x, y, x, digs) == NaN_MP, p, ERROR_INVALID_ARGUMENT, MOID (p));
1380 A68G_SP -= size;
1381 MP_STATUS (x) = (MP_T) INIT_MASK;
1382 }
1383
1384 //! @brief PROC (LONG REAL) LONG REAL long
1385
1386 void genie_sinpi_mp (NODE_T * p)
1387 {
1388 C_L_FUNCTION (p, sinpi_mp);
1389 }
1390
1391 //! @brief PROC (LONG REAL) LONG REAL long
1392
1393 void genie_cospi_mp (NODE_T * p)
1394 {
1395 C_L_FUNCTION (p, cospi_mp);
1396 }
1397
1398 //! @brief PROC (LONG REAL) LONG REAL long
1399
1400 void genie_cotpi_mp (NODE_T * p)
1401 {
1402 C_L_FUNCTION (p, cotpi_mp);
1403 }
1404
1405 //! @brief PROC (LONG REAL) LONG REAL long
1406
1407 void genie_tanpi_mp (NODE_T * p)
1408 {
1409 C_L_FUNCTION (p, tanpi_mp);
1410 }
|
© 2002-2025 J.M. van der Veer (jmvdveer@xs4all.nl)
|