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-2024 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 unt 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 unt 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 A68_INT k;
137 POP_OBJECT (p, &k, A68_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), A68_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 A68_REAL x;
161 POP_OBJECT (p, &x, A68_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), A68_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 = A68_SP;
185 MP_T *z = (MP_T *) STACK_OFFSET (-size);
186 (void) entier_mp (p, z, z, digs);
187 A68_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 = A68_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 A68_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 A68_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 A68_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 A68_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 A68_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 (A68_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 int 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 int 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 int 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)), A68_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 A68_CMP_LONG(n, OP)\
605 void n (NODE_T * p) {\
606 MOID_T *mode = LHS_MODE (p);\
607 A68_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), A68_BOOL);\
614 }
615
616 A68_CMP_LONG (genie_eq_mp, eq_mp);
617 A68_CMP_LONG (genie_ne_mp, ne_mp);
618 A68_CMP_LONG (genie_lt_mp, lt_mp);
619 A68_CMP_LONG (genie_gt_mp, gt_mp);
620 A68_CMP_LONG (genie_le_mp, le_mp);
621 A68_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 A68_INT k;
630 POP_OBJECT (p, &k, A68_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 = A68_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 (A68_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 A68_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))])), A68_BOOL);
668 } else {
669 PUSH_VALUE (p, A68_FALSE, A68_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 A68_INT k;
729 POP_OBJECT (p, &k, A68_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 = A68_SP;
767 MP_T *z = (MP_T *) STACK_OFFSET (-size);
768 (void) round_mp (p, z, z, digs);
769 A68_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 = A68_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 A68_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 A68_REAL a, b;
896 POP_OBJECT (p, &b, A68_REAL);
897 POP_OBJECT (p, &a, A68_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_VALUE (p, mp_to_real (p, a, digs), A68_REAL);
915 PUSH_VALUE (p, mp_to_real (p, b, digs), A68_REAL);
916 }
917
918 //! @brief OP LENG = (LONG COMPLEX) LONG LONG COMPLEX
919
920 void genie_lengthen_mp_complex_to_long_mp_complex (NODE_T * p)
921 {
922 int digs = DIGITS (M_LONG_REAL), size = SIZE (M_LONG_REAL);
923 int gdigs = DIGITS (M_LONG_LONG_REAL), size_g = SIZE (M_LONG_LONG_REAL);
924 ADDR_T pop_sp = A68_SP;
925 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
926 MP_T *b = (MP_T *) STACK_OFFSET (-size);
927 MP_T *c = len_mp (p, a, digs, gdigs);
928 MP_T *d = len_mp (p, b, digs, gdigs);
929 (void) move_mp (a, c, gdigs);
930 (void) move_mp (&a[LEN_MP (gdigs)], d, gdigs);
931 A68_SP = pop_sp;
932 INCREMENT_STACK_POINTER (p, 2 * (size_g - size));
933 }
934
935 //! @brief OP SHORTEN = (LONG LONG COMPLEX) LONG COMPLEX
936
937 void genie_shorten_long_mp_complex_to_mp_complex (NODE_T * p)
938 {
939 int digs = DIGITS (M_LONG_REAL), size = SIZE (M_LONG_REAL);
940 int gdigs = DIGITS (M_LONG_LONG_REAL), size_g = SIZE (M_LONG_LONG_REAL);
941 ADDR_T pop_sp = A68_SP;
942 MP_T *b = (MP_T *) STACK_OFFSET (-size_g);
943 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size_g);
944 (void) shorten_mp (p, a, digs, a, gdigs);
945 (void) shorten_mp (p, &a[LEN_MP (digs)], digs, b, gdigs);
946 A68_SP = pop_sp;
947 MP_STATUS (a) = (MP_T) INIT_MASK;
948 MP_STATUS (&a[LEN_MP (digs)]) = (MP_T) INIT_MASK;
949 DECREMENT_STACK_POINTER (p, 2 * (size_g - size));
950 }
951
952 //! @brief OP RE = (LONG COMPLEX) LONG REAL
953
954 void genie_re_mp_complex (NODE_T * p)
955 {
956 int size = SIZE (SUB_MOID (p));
957 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
958 MP_STATUS (a) = (MP_T) INIT_MASK;
959 DECREMENT_STACK_POINTER (p, size);
960 }
961
962 //! @brief OP IM = (LONG COMPLEX) LONG REAL
963
964 void genie_im_mp_complex (NODE_T * p)
965 {
966 MOID_T *mode = SUB_MOID (p);
967 int digs = DIGITS (mode), size = SIZE (mode);
968 MP_T *b = (MP_T *) STACK_OFFSET (-size);
969 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
970 (void) move_mp (a, b, digs);
971 MP_STATUS (a) = (MP_T) INIT_MASK;
972 DECREMENT_STACK_POINTER (p, size);
973 }
974
975 //! @brief OP - = (LONG COMPLEX) LONG COMPLEX
976
977 void genie_minus_mp_complex (NODE_T * p)
978 {
979 int size = SIZE_COMPL (SUB_MOID (p));
980 MP_T *b = (MP_T *) STACK_OFFSET (-size);
981 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
982 MP_DIGIT (a, 1) = -MP_DIGIT (a, 1);
983 MP_DIGIT (b, 1) = -MP_DIGIT (b, 1);
984 MP_STATUS (a) = (MP_T) INIT_MASK;
985 MP_STATUS (b) = (MP_T) INIT_MASK;
986 }
987
988 //! @brief OP CONJ = (LONG COMPLEX) LONG COMPLEX
989
990 void genie_conj_mp_complex (NODE_T * p)
991 {
992 int size = SIZE_COMPL (SUB_MOID (p));
993 MP_T *b = (MP_T *) STACK_OFFSET (-size);
994 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
995 MP_DIGIT (b, 1) = -MP_DIGIT (b, 1);
996 MP_STATUS (a) = (MP_T) INIT_MASK;
997 MP_STATUS (b) = (MP_T) INIT_MASK;
998 }
999
1000 //! @brief OP ABS = (LONG COMPLEX) LONG REAL
1001
1002 void genie_abs_mp_complex (NODE_T * p)
1003 {
1004 MOID_T *mode = SUB_MOID (p);
1005 int digs = DIGITS (mode), size = SIZE (mode);
1006 ADDR_T pop_sp = A68_SP;
1007 MP_T *b = (MP_T *) STACK_OFFSET (-size);
1008 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
1009 MP_T *z = nil_mp (p, digs);
1010 errno = 0;
1011 (void) hypot_mp (p, z, a, b, digs);
1012 A68_SP = pop_sp;
1013 DECREMENT_STACK_POINTER (p, size);
1014 (void) move_mp (a, z, digs);
1015 MP_STATUS (a) = (MP_T) INIT_MASK;
1016 MATH_RTE (p, errno != 0, mode, NO_TEXT);
1017 }
1018
1019 //! @brief OP ARG = (LONG COMPLEX) LONG REAL
1020
1021 void genie_arg_mp_complex (NODE_T * p)
1022 {
1023 MOID_T *mode = SUB_MOID (p);
1024 int digs = DIGITS (mode), size = SIZE (mode);
1025 ADDR_T pop_sp = A68_SP;
1026 MP_T *b = (MP_T *) STACK_OFFSET (-size);
1027 MP_T *a = (MP_T *) STACK_OFFSET (-2 * size);
1028 MP_T *z = nil_mp (p, digs);
1029 errno = 0;
1030 (void) atan2_mp (p, z, a, b, digs);
1031 A68_SP = pop_sp;
1032 DECREMENT_STACK_POINTER (p, size);
1033 (void) move_mp (a, z, digs);
1034 MP_STATUS (a) = (MP_T) INIT_MASK;
1035 MATH_RTE (p, errno != 0, mode, NO_TEXT);
1036 }
1037
1038 //! @brief OP + = (LONG COMPLEX, LONG COMPLEX) LONG COMPLEX
1039
1040 void genie_add_mp_complex (NODE_T * p)
1041 {
1042 MOID_T *mode = SUB_MOID (p);
1043 int digs = DIGITS_COMPL (mode), size = SIZE_COMPL (mode);
1044 ADDR_T pop_sp = A68_SP;
1045 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1046 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1047 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1048 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1049 (void) add_mp (p, b, b, d, digs);
1050 (void) add_mp (p, a, a, c, digs);
1051 MP_STATUS (a) = (MP_T) INIT_MASK;
1052 MP_STATUS (b) = (MP_T) INIT_MASK;
1053 A68_SP = pop_sp;
1054 DECREMENT_STACK_POINTER (p, 2 * size);
1055 }
1056
1057 //! @brief OP - = (LONG COMPLEX, LONG COMPLEX) LONG COMPLEX
1058
1059 void genie_sub_mp_complex (NODE_T * p)
1060 {
1061 MOID_T *mode = SUB_MOID (p);
1062 int digs = DIGITS_COMPL (mode), size = SIZE_COMPL (mode);
1063 ADDR_T pop_sp = A68_SP;
1064 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1065 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1066 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1067 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1068 (void) sub_mp (p, b, b, d, digs);
1069 (void) sub_mp (p, a, a, c, digs);
1070 MP_STATUS (a) = (MP_T) INIT_MASK;
1071 MP_STATUS (b) = (MP_T) INIT_MASK;
1072 A68_SP = pop_sp;
1073 DECREMENT_STACK_POINTER (p, 2 * size);
1074 }
1075
1076 //! @brief OP * = (LONG COMPLEX, LONG COMPLEX) LONG COMPLEX
1077
1078 void genie_mul_mp_complex (NODE_T * p)
1079 {
1080 MOID_T *mode = SUB_MOID (p);
1081 int digs = DIGITS_COMPL (mode), size = SIZE_COMPL (mode);
1082 ADDR_T pop_sp = A68_SP;
1083 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1084 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1085 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1086 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1087 (void) cmul_mp (p, a, b, c, d, digs);
1088 MP_STATUS (a) = (MP_T) INIT_MASK;
1089 MP_STATUS (b) = (MP_T) INIT_MASK;
1090 A68_SP = pop_sp;
1091 DECREMENT_STACK_POINTER (p, 2 * size);
1092 }
1093
1094 //! @brief OP / = (LONG COMPLEX, LONG COMPLEX) LONG COMPLEX
1095
1096 void genie_div_mp_complex (NODE_T * p)
1097 {
1098 MOID_T *mode = SUB_MOID (p);
1099 int digs = DIGITS_COMPL (mode), size = SIZE_COMPL (mode);
1100 ADDR_T pop_sp = A68_SP;
1101 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1102 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1103 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1104 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1105 PRELUDE_ERROR (cdiv_mp (p, a, b, c, d, digs) == NaN_MP, p, ERROR_DIVISION_BY_ZERO, mode);
1106 MP_STATUS (a) = (MP_T) INIT_MASK;
1107 MP_STATUS (b) = (MP_T) INIT_MASK;
1108 A68_SP = pop_sp;
1109 DECREMENT_STACK_POINTER (p, 2 * size);
1110 }
1111
1112 //! @brief OP ** = (LONG COMPLEX, INT) LONG COMPLEX
1113
1114 void genie_pow_mp_complex_int (NODE_T * p)
1115 {
1116 MOID_T *mode = SUB_MOID (p);
1117 int digs = DIGITS_COMPL (mode), size = SIZE_COMPL (mode);
1118 A68_INT j;
1119 POP_OBJECT (p, &j, A68_INT);
1120 ADDR_T pop_sp = A68_SP;
1121 MP_T *im_x = (MP_T *) STACK_OFFSET (-size);
1122 MP_T *re_x = (MP_T *) STACK_OFFSET (-2 * size);
1123 MP_T *re_z = lit_mp (p, 1, 0, digs);
1124 MP_T *im_z = nil_mp (p, digs);
1125 MP_T *re_y = nil_mp (p, digs);
1126 MP_T *im_y = nil_mp (p, digs);
1127 (void) move_mp (re_y, re_x, digs);
1128 (void) move_mp (im_y, im_x, digs);
1129 MP_T *rea = nil_mp (p, digs);
1130 MP_T *acc = nil_mp (p, digs);
1131 int expo = 1;
1132 BOOL_T negative = (BOOL_T) (VALUE (&j) < 0);
1133 if (negative) {
1134 VALUE (&j) = -VALUE (&j);
1135 }
1136 while ((int) expo <= (int) (VALUE (&j))) {
1137 if (expo & VALUE (&j)) {
1138 (void) mul_mp (p, acc, im_z, im_y, digs);
1139 (void) mul_mp (p, rea, re_z, re_y, digs);
1140 (void) sub_mp (p, rea, rea, acc, digs);
1141 (void) mul_mp (p, acc, im_z, re_y, digs);
1142 (void) mul_mp (p, im_z, re_z, im_y, digs);
1143 (void) add_mp (p, im_z, im_z, acc, digs);
1144 (void) move_mp (re_z, rea, digs);
1145 }
1146 (void) mul_mp (p, acc, im_y, im_y, digs);
1147 (void) mul_mp (p, rea, re_y, re_y, digs);
1148 (void) sub_mp (p, rea, rea, acc, digs);
1149 (void) mul_mp (p, acc, im_y, re_y, digs);
1150 (void) mul_mp (p, im_y, re_y, im_y, digs);
1151 (void) add_mp (p, im_y, im_y, acc, digs);
1152 (void) move_mp (re_y, rea, digs);
1153 expo <<= 1;
1154 }
1155 A68_SP = pop_sp;
1156 if (negative) {
1157 SET_MP_ONE (re_x, digs);
1158 SET_MP_ZERO (im_x, digs);
1159 INCREMENT_STACK_POINTER (p, 2 * size);
1160 genie_div_mp_complex (p);
1161 } else {
1162 (void) move_mp (re_x, re_z, digs);
1163 (void) move_mp (im_x, im_z, digs);
1164 }
1165 MP_STATUS (re_x) = (MP_T) INIT_MASK;
1166 MP_STATUS (im_x) = (MP_T) INIT_MASK;
1167 }
1168
1169 //! @brief OP = = (LONG COMPLEX, LONG COMPLEX) BOOL
1170
1171 void genie_eq_mp_complex (NODE_T * p)
1172 {
1173 int digs = DIGITS_COMPL (LHS_MODE (p)), size = SIZE_COMPL (LHS_MODE (p));
1174 ADDR_T pop_sp = A68_SP;
1175 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1176 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1177 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1178 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1179 (void) sub_mp (p, b, b, d, digs);
1180 (void) sub_mp (p, a, a, c, digs);
1181 A68_SP = pop_sp;
1182 DECREMENT_STACK_POINTER (p, 4 * size);
1183 PUSH_VALUE (p, (BOOL_T) (MP_DIGIT (a, 1) == 0 && MP_DIGIT (b, 1) == 0), A68_BOOL);
1184 }
1185
1186 //! @brief OP /= = (LONG COMPLEX, LONG COMPLEX) BOOL
1187
1188 void genie_ne_mp_complex (NODE_T * p)
1189 {
1190 int digs = DIGITS_COMPL (LHS_MODE (p)), size = SIZE_COMPL (LHS_MODE (p));
1191 ADDR_T pop_sp = A68_SP;
1192 MP_T *d = (MP_T *) STACK_OFFSET (-size);
1193 MP_T *c = (MP_T *) STACK_OFFSET (-2 * size);
1194 MP_T *b = (MP_T *) STACK_OFFSET (-3 * size);
1195 MP_T *a = (MP_T *) STACK_OFFSET (-4 * size);
1196 (void) sub_mp (p, b, b, d, digs);
1197 (void) sub_mp (p, a, a, c, digs);
1198 A68_SP = pop_sp;
1199 DECREMENT_STACK_POINTER (p, 4 * size);
1200 PUSH_VALUE (p, (BOOL_T) (MP_DIGIT (a, 1) != 0 || MP_DIGIT (b, 1) != 0), A68_BOOL);
1201 }
1202
1203 //! @brief OP +:= = (REF LONG COMPLEX, LONG COMPLEX) REF LONG COMPLEX
1204
1205 void genie_plusab_mp_complex (NODE_T * p)
1206 {
1207 MOID_T *mode = LHS_MODE (p);
1208 genie_f_and_becomes (p, mode, genie_add_mp_complex);
1209 }
1210
1211 //! @brief OP -:= = (REF LONG COMPLEX, LONG COMPLEX) REF LONG COMPLEX
1212
1213 void genie_minusab_mp_complex (NODE_T * p)
1214 {
1215 MOID_T *mode = LHS_MODE (p);
1216 genie_f_and_becomes (p, mode, genie_sub_mp_complex);
1217 }
1218
1219 //! @brief OP *:= = (REF LONG COMPLEX, LONG COMPLEX) REF LONG COMPLEX
1220
1221 void genie_timesab_mp_complex (NODE_T * p)
1222 {
1223 MOID_T *mode = LHS_MODE (p);
1224 genie_f_and_becomes (p, mode, genie_mul_mp_complex);
1225 }
1226
1227 //! @brief OP /:= = (REF LONG COMPLEX, LONG COMPLEX) REF LONG COMPLEX
1228
1229 void genie_divab_mp_complex (NODE_T * p)
1230 {
1231 MOID_T *mode = LHS_MODE (p);
1232 genie_f_and_becomes (p, mode, genie_div_mp_complex);
1233 }
1234
1235 //! @brief PROC LONG REAL next long random
1236
1237 void genie_long_next_random (NODE_T * p)
1238 {
1239 // This is 'real width' precision only.
1240 genie_next_random (p);
1241 genie_lengthen_real_to_mp (p);
1242 if (MOID (p) == M_LONG_LONG_REAL) {
1243 genie_lengthen_mp_to_long_mp (p);
1244 }
1245 }
1246
1247 //! @brief PROC (LONG REAL) LONG REAL long csc
1248
1249 void genie_csc_mp (NODE_T * p)
1250 {
1251 C_L_FUNCTION (p, csc_mp);
1252 }
1253
1254 //! @brief PROC (LONG REAL) LONG REAL long acsc
1255
1256 void genie_acsc_mp (NODE_T * p)
1257 {
1258 C_L_FUNCTION (p, acsc_mp);
1259 }
1260
1261 //! @brief PROC (LONG REAL) LONG REAL long sec
1262
1263 void genie_sec_mp (NODE_T * p)
1264 {
1265 C_L_FUNCTION (p, sec_mp);
1266 }
1267
1268 //! @brief PROC (LONG REAL) LONG REAL long asec
1269
1270 void genie_asec_mp (NODE_T * p)
1271 {
1272 C_L_FUNCTION (p, asec_mp);
1273 }
1274
1275 //! @brief PROC (LONG REAL) LONG REAL long cot
1276
1277 void genie_cot_mp (NODE_T * p)
1278 {
1279 C_L_FUNCTION (p, cot_mp);
1280 }
1281
1282 //! @brief PROC (LONG REAL) LONG REAL long acot
1283
1284 void genie_acot_mp (NODE_T * p)
1285 {
1286 C_L_FUNCTION (p, acot_mp);
1287 }
1288
1289 //! @brief PROC (LONG REAL) LONG REAL long sindg
1290
1291 void genie_sindg_mp (NODE_T * p)
1292 {
1293 C_L_FUNCTION (p, sindg_mp);
1294 }
1295
1296 //! @brief PROC (LONG REAL) LONG REAL long cosdg
1297
1298 void genie_cosdg_mp (NODE_T * p)
1299 {
1300 C_L_FUNCTION (p, cosdg_mp);
1301 }
1302
1303 //! @brief PROC (LONG REAL) LONG REAL long tandg
1304
1305 void genie_tandg_mp (NODE_T * p)
1306 {
1307 C_L_FUNCTION (p, tandg_mp);
1308 }
1309
1310 //! @brief PROC (LONG REAL) LONG REAL long secdg
1311
1312 void genie_secdg_mp (NODE_T * p)
1313 {
1314 C_L_FUNCTION (p, secdg_mp);
1315 }
1316
1317 //! @brief PROC (LONG REAL) LONG REAL long asecdg
1318
1319 void genie_asecdg_mp (NODE_T * p)
1320 {
1321 C_L_FUNCTION (p, asecdg_mp);
1322 }
1323
1324 //! @brief PROC (LONG REAL) LONG REAL long cscdg
1325
1326 void genie_cscdg_mp (NODE_T * p)
1327 {
1328 C_L_FUNCTION (p, cscdg_mp);
1329 }
1330
1331 //! @brief PROC (LONG REAL) LONG REAL long acscdg
1332
1333 void genie_acscdg_mp (NODE_T * p)
1334 {
1335 C_L_FUNCTION (p, acscdg_mp);
1336 }
1337
1338 //! @brief PROC (LONG REAL) LONG REAL long cotdg
1339
1340 void genie_cotdg_mp (NODE_T * p)
1341 {
1342 C_L_FUNCTION (p, cotdg_mp);
1343 }
1344
1345 //! @brief PROC (LONG REAL) LONG REAL long asindg
1346
1347 void genie_asindg_mp (NODE_T * p)
1348 {
1349 C_L_FUNCTION (p, asindg_mp);
1350 }
1351
1352 //! @brief PROC (LONG REAL) LONG REAL long acosdg
1353
1354 void genie_acosdg_mp (NODE_T * p)
1355 {
1356 C_L_FUNCTION (p, acosdg_mp);
1357 }
1358
1359 //! @brief PROC (LONG REAL) LONG REAL long atandg
1360
1361 void genie_atandg_mp (NODE_T * p)
1362 {
1363 C_L_FUNCTION (p, atandg_mp);
1364 }
1365
1366 //! @brief PROC (LONG REAL) LONG REAL long acotdg
1367
1368 void genie_acotdg_mp (NODE_T * p)
1369 {
1370 C_L_FUNCTION (p, acotdg_mp);
1371 }
1372
1373 //! @brief PROC (LONG REAL, LONG REAL) LONG REAL long arctan2
1374
1375 void genie_atan2dg_mp (NODE_T * p)
1376 {
1377 int digs = DIGITS (MOID (p)), size = SIZE (MOID (p));
1378 MP_T *y = (MP_T *) STACK_OFFSET (-size);
1379 MP_T *x = (MP_T *) STACK_OFFSET (-2 * size);
1380 PRELUDE_ERROR (atan2dg_mp (p, x, y, x, digs) == NaN_MP, p, ERROR_INVALID_ARGUMENT, MOID (p));
1381 A68_SP -= size;
1382 MP_STATUS (x) = (MP_T) INIT_MASK;
1383 }
1384
1385 //! @brief PROC (LONG REAL) LONG REAL long
1386
1387 void genie_sinpi_mp (NODE_T * p)
1388 {
1389 C_L_FUNCTION (p, sinpi_mp);
1390 }
1391
1392 //! @brief PROC (LONG REAL) LONG REAL long
1393
1394 void genie_cospi_mp (NODE_T * p)
1395 {
1396 C_L_FUNCTION (p, cospi_mp);
1397 }
1398
1399 //! @brief PROC (LONG REAL) LONG REAL long
1400
1401 void genie_cotpi_mp (NODE_T * p)
1402 {
1403 C_L_FUNCTION (p, cotpi_mp);
1404 }
1405
1406 //! @brief PROC (LONG REAL) LONG REAL long
1407
1408 void genie_tanpi_mp (NODE_T * p)
1409 {
1410 C_L_FUNCTION (p, tanpi_mp);
1411 }
© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)
|