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