|
|
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@algol68genie.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 }
© 2001-2026 J.M. van der Veer
jmvdveer@algol68genie.nl