8 math.ops - Mathematical Opcodes
14 Operations that perform basic mathematics. See F<src/dynoplibs/> for more
17 When making changes to any ops file, run C<make bootstrap-ops> to regenerate
18 all generated ops files.
20 =head2 Arithmetic operations
22 These operations store the results of arithmetic on other registers and
23 constants into their destination register, $1.
29 ########################################
31 =item B<abs>(inout INT)
33 =item B<abs>(inout NUM)
35 =item B<abs>(invar PMC)
37 Set $1 to its absolute value.
39 =item B<abs>(out INT, in INT)
41 =item B<abs>(out NUM, in NUM)
43 =item B<abs>(out PMC, invar PMC)
45 Set $1 to absolute value of $2.
49 inline op abs(inout INT) :base_core {
53 inline op abs(inout NUM) :base_core {
57 inline op abs(out INT, in INT) :base_core {
61 inline op abs(out NUM, in NUM) :base_core {
65 inline op abs(invar PMC) :base_core {
66 VTABLE_i_absolute(interp, $1);
69 inline op abs(out PMC, invar PMC) :base_core {
70 $1 = VTABLE_absolute(interp, $2, $1);
73 ########################################
75 =item B<add>(inout INT, in INT)
77 =item B<add>(inout NUM, in NUM)
79 =item B<add>(invar PMC, invar PMC)
81 =item B<add>(invar PMC, in INT)
83 =item B<add>(invar PMC, in NUM)
85 Increase $1 by the amount in $2.
87 =item B<add>(out INT, in INT, in INT)
89 =item B<add>(out NUM, in NUM, in NUM)
91 =item B<add>(invar PMC, invar PMC, invar PMC)
93 =item B<add>(invar PMC, invar PMC, in INT)
95 =item B<add>(invar PMC, invar PMC, in NUM)
97 Set $1 to the sum of $2 and $3.
101 inline op add(inout INT, in INT) :base_core {
105 inline op add(inout NUM, in NUM) :base_core {
109 inline op add(invar PMC, invar PMC) :base_core {
110 VTABLE_i_add(interp, $1, $2);
113 inline op add(invar PMC, in INT) :base_core {
114 VTABLE_i_add_int(interp, $1, $2);
117 inline op add(invar PMC, in NUM) :base_core {
118 VTABLE_i_add_float(interp, $1, $2);
121 inline op add(out INT, in INT, in INT) :base_core {
125 inline op add(out NUM, in NUM, in NUM) :base_core {
129 inline op add(invar PMC, invar PMC, invar PMC) :base_core {
130 $1 = VTABLE_add(interp, $2, $3, $1);
133 inline op add(invar PMC, invar PMC, in INT) :base_core {
134 $1 = VTABLE_add_int(interp, $2, $3, $1);
137 inline op add(invar PMC, invar PMC, in NUM) :base_core {
138 $1 = VTABLE_add_float(interp, $2, $3, $1);
141 ########################################
143 =item B<dec>(inout INT)
145 =item B<dec>(inout NUM)
147 =item B<dec>(invar PMC)
153 inline op dec(inout INT) :base_core {
157 inline op dec(inout NUM) :base_core {
161 inline op dec(invar PMC) :base_core {
162 VTABLE_decrement(interp, $1);
165 ########################################
167 =item B<div>(inout INT, in INT)
169 =item B<div>(inout NUM, in NUM)
171 =item B<div>(invar PMC, invar PMC)
173 =item B<div>(invar PMC, in INT)
175 =item B<div>(invar PMC, in NUM)
179 =item B<div>(out INT, in INT, in INT)
181 =item B<div>(out NUM, in NUM, in NUM)
183 =item B<div>(invar PMC, invar PMC, invar PMC)
185 =item B<div>(invar PMC, invar PMC, in INT)
187 =item B<div>(invar PMC, invar PMC, in NUM)
189 Set $1 to the quotient of $2 divided by $3. In the case of INTVAL division, the
190 result is truncated (NOT rounded or floored).
191 If the denominator is zero, a 'Divide by zero' exception is thrown.
195 inline op div(inout INT, in INT) :base_core {
198 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
199 EXCEPTION_DIV_BY_ZERO,
201 goto ADDRESS(handler);
206 inline op div(inout NUM, in NUM) :base_core {
208 if (FLOAT_IS_ZERO(den)) {
209 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
210 EXCEPTION_DIV_BY_ZERO,
212 goto ADDRESS(handler);
217 inline op div(invar PMC, invar PMC) :base_core {
218 VTABLE_i_divide(interp, $1, $2);
221 inline op div(invar PMC, in INT) :base_core {
222 VTABLE_i_divide_int(interp, $1, $2);
225 inline op div(invar PMC, in NUM) :base_core {
226 VTABLE_i_divide_float(interp, $1, $2);
228 inline op div(out INT, in INT, in INT) :base_core {
231 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
232 EXCEPTION_DIV_BY_ZERO,
234 goto ADDRESS(handler);
239 inline op div(out NUM, in NUM, in NUM) :base_core {
241 if (FLOAT_IS_ZERO(den)) {
242 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
243 EXCEPTION_DIV_BY_ZERO,
245 goto ADDRESS(handler);
250 inline op div(invar PMC, invar PMC, invar PMC) :base_core {
251 $1 = VTABLE_divide(interp, $2, $3, $1);
254 inline op div(invar PMC, invar PMC, in INT) :base_core {
255 $1 = VTABLE_divide_int(interp, $2, $3, $1);
258 inline op div(invar PMC, invar PMC, in NUM) :base_core {
259 $1 = VTABLE_divide_float(interp, $2, $3, $1);
263 =item B<fdiv>(inout INT, in INT)
265 =item B<fdiv>(inout NUM, in NUM)
267 =item B<fdiv>(invar PMC, invar PMC)
269 =item B<fdiv>(invar PMC, in INT)
271 =item B<fdiv>(invar PMC, in NUM)
273 Floor divide $1 by $2.
275 =item B<fdiv>(out INT, in INT, in INT)
277 =item B<fdiv>(out NUM, in NUM, in NUM)
279 =item B<fdiv>(invar PMC, invar PMC, invar PMC)
281 =item B<fdiv>(invar PMC, invar PMC, in INT)
283 =item B<fdiv>(invar PMC, invar PMC, in NUM)
285 Set $1 to the quotient of $2 divided by $3. The result is the floor()
286 of the division i.e. the next whole integer towards -inf.
287 If the denominator is zero, a 'Divide by zero' exception is thrown.
291 inline op fdiv(inout INT, in INT) :base_core {
296 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
297 EXCEPTION_DIV_BY_ZERO,
299 goto ADDRESS(handler);
302 f = floor(((FLOATVAL)$1) / den);
306 inline op fdiv(inout NUM, in NUM) :base_core {
308 if (FLOAT_IS_ZERO(den)) {
309 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
310 EXCEPTION_DIV_BY_ZERO,
312 goto ADDRESS(handler);
314 $1 = floor($1 / den);
317 inline op fdiv(invar PMC, invar PMC) :base_core {
318 VTABLE_i_floor_divide(interp, $1, $2);
321 inline op fdiv(invar PMC, in INT) :base_core {
322 VTABLE_i_floor_divide_int(interp, $1, $2);
325 inline op fdiv(invar PMC, in NUM) :base_core {
326 VTABLE_i_floor_divide_float(interp, $1, $2);
329 inline op fdiv(out INT, in INT, in INT) :base_core {
334 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
335 EXCEPTION_DIV_BY_ZERO,
337 goto ADDRESS(handler);
340 f = floor((FLOATVAL)$2 / den);
344 inline op fdiv(out NUM, in NUM, in NUM) :base_core {
346 if (FLOAT_IS_ZERO(den)) {
347 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
348 EXCEPTION_DIV_BY_ZERO,
350 goto ADDRESS(handler);
352 $1 = floor($2 / den);
355 inline op fdiv(invar PMC, invar PMC, invar PMC) :base_core {
356 $1 = VTABLE_floor_divide(interp, $2, $3, $1);
359 inline op fdiv(invar PMC, invar PMC, in INT) :base_core {
360 $1 = VTABLE_floor_divide_int(interp, $2, $3, $1);
363 inline op fdiv(invar PMC, invar PMC, in NUM) :base_core {
364 $1 = VTABLE_floor_divide_float(interp, $2, $3, $1);
367 ########################################
369 =item B<ceil>(inout NUM)
371 Set $1 to the smallest integral value greater than or equal to $1.
373 =item B<ceil>(out INT, in NUM)
375 =item B<ceil>(out NUM, in NUM)
377 Set $1 to the smallest integral value greater than or equal to $2.
381 inline op ceil(inout NUM) :base_core {
385 inline op ceil(out INT, in NUM) :base_core {
386 FLOATVAL f = ceil($2);
390 inline op ceil(out NUM, in NUM) :base_core {
394 ########################################
396 =item B<floor>(inout NUM)
398 Set $1 to the largest integral value less than or equal to $1.
400 =item B<floor>(out INT, in NUM)
402 =item B<floor>(out NUM, in NUM)
404 Set $1 to the largest integral value less than or equal to $2.
408 inline op floor(inout NUM) :base_core {
412 inline op floor(out INT, in NUM) :base_core {
413 FLOATVAL f = floor($2);
417 inline op floor(out NUM, in NUM) :base_core {
421 ########################################
423 =item B<inc>(inout INT)
425 =item B<inc>(inout NUM)
427 =item B<inc>(invar PMC)
433 inline op inc(inout INT) :base_core {
437 inline op inc(inout NUM) :base_core {
441 inline op inc(invar PMC) :base_core {
442 VTABLE_increment(interp, $1);
446 ########################################
448 =item B<mod>(out INT, in INT, in INT)
450 =item B<mod>(out NUM, in NUM, in NUM)
452 =item B<mod>(invar PMC, invar PMC, invar PMC)
454 =item B<mod>(invar PMC, invar PMC, in INT)
456 =item B<mod>(invar PMC, invar PMC, in NUM)
458 Sets $1 to the modulus of $2 and $3.
460 =item B<mod>(inout INT, in INT)
462 =item B<mod>(inout NUM, in NUM)
464 =item B<mod>(invar PMC, invar PMC)
466 =item B<mod>(invar PMC, in INT)
468 =item B<mod>(invar PMC, in NUM)
470 Sets $1 to the modulus of $1 and $2.
473 NOTE: This "corrected mod" algorithm is based on the C code on page 70
474 of [1]. Assuming correct behavior of the built-in mod operator (%) with
475 positive arguments, this algorithm implements a mathematically convenient
476 version of mod, defined thus:
478 x mod y = x - y * floor(x / y)
480 For more information on this definition of mod, see section 3.4 of [2],
485 [1] Donald E. Knuth, *MMIXware: A RISC Computer for the Third
486 Millennium* Springer, 1999.
488 [2] Ronald L. Graham, Donald E. Knuth and Oren Patashnik, *Concrete
489 Mathematics*, Second Edition. Addison-Wesley, 1994.
493 op mod(inout INT, in INT) :base_core {
494 $1 = intval_mod($1, $2);
497 op mod(inout NUM, in NUM) :base_core {
498 $1 = floatval_mod($1, $2);
501 inline op mod(invar PMC, invar PMC) :base_core {
502 VTABLE_i_modulus(interp, $1, $2);
505 inline op mod(invar PMC, in INT) :base_core {
506 VTABLE_i_modulus_int(interp, $1, $2);
509 inline op mod(invar PMC, in NUM) :base_core {
510 VTABLE_i_modulus_float(interp, $1, $2);
513 op mod(out INT, in INT, in INT) :base_core {
514 $1 = intval_mod($2, $3);
517 op mod(out NUM, in NUM, in NUM) :base_core {
518 $1 = floatval_mod($2, $3);
521 inline op mod(invar PMC, invar PMC, invar PMC) :base_core {
522 $1 = VTABLE_modulus(interp, $2, $3, $1);
525 inline op mod(invar PMC, invar PMC, in INT) :base_core {
526 $1 = VTABLE_modulus_int(interp, $2, $3, $1);
529 inline op mod(invar PMC, invar PMC, in NUM) :base_core {
530 $1 = VTABLE_modulus_float(interp, $2, $3, $1);
533 ########################################
535 =item B<mul>(inout INT, in INT)
537 =item B<mul>(inout NUM, in NUM)
539 =item B<mul>(invar PMC, invar PMC)
541 =item B<mul>(invar PMC, in INT)
543 =item B<mul>(invar PMC, in NUM)
545 Set $1 to the product of $1 and $2.
547 =item B<mul>(out INT, in INT, in INT)
549 =item B<mul>(out NUM, in NUM, in NUM)
551 =item B<mul>(invar PMC, invar PMC, invar PMC)
553 =item B<mul>(invar PMC, invar PMC, in INT)
555 =item B<mul>(invar PMC, invar PMC, in NUM)
557 Set $1 to the product of $2 and $3.
561 inline op mul(inout INT, in INT) :base_core {
565 inline op mul(inout NUM, in NUM) :base_core {
569 inline op mul(invar PMC, invar PMC) :base_core {
570 VTABLE_i_multiply(interp, $1, $2);
573 inline op mul(invar PMC, in INT) :base_core {
574 VTABLE_i_multiply_int(interp, $1, $2);
577 inline op mul(invar PMC, in NUM) :base_core {
578 VTABLE_i_multiply_float(interp, $1, $2);
581 inline op mul(out INT, in INT, in INT) :base_core {
585 inline op mul(out NUM, in NUM, in NUM) :base_core {
589 inline op mul(invar PMC, invar PMC, invar PMC) :base_core {
590 $1 = VTABLE_multiply(interp, $2, $3, $1);
593 inline op mul(invar PMC, invar PMC, in INT) :base_core {
594 $1 = VTABLE_multiply_int(interp, $2, $3, $1);
597 inline op mul(invar PMC, invar PMC, in NUM) :base_core {
598 $1 = VTABLE_multiply_float(interp, $2, $3, $1);
601 ########################################
603 =item B<neg>(inout INT)
605 =item B<neg>(inout NUM)
607 =item B<neg>(invar PMC)
609 Set $1 to its negative.
611 =item B<neg>(out INT, in INT)
613 =item B<neg>(out NUM, in NUM)
615 =item B<neg>(out PMC, invar PMC)
617 Set $1 to the negative of $2.
621 inline op neg(inout INT) :base_core {
625 inline op neg(inout NUM) :base_core {
629 inline op neg(invar PMC) :base_core {
630 VTABLE_i_neg(interp, $1);
633 inline op neg(out INT, in INT) :base_core {
637 inline op neg(out NUM, in NUM) :base_core {
641 inline op neg(out PMC, invar PMC) :base_core {
642 $1 = VTABLE_neg(interp, $2, $1);
645 ########################################
647 =item B<sub>(inout INT, in INT)
649 =item B<sub>(inout NUM, in NUM)
651 =item B<sub>(invar PMC, invar PMC)
653 =item B<sub>(invar PMC, in INT)
655 =item B<sub>(invar PMC, in NUM)
657 Decrease $1 by the amount in $2.
659 =item B<sub>(out INT, in INT, in INT)
661 =item B<sub>(out NUM, in NUM, in NUM)
663 =item B<sub>(invar PMC, invar PMC, invar PMC)
665 =item B<sub>(invar PMC, invar PMC, in INT)
667 =item B<sub>(invar PMC, invar PMC, in NUM)
669 Set $1 to $2 minus $3.
673 inline op sub(inout INT, in INT) :base_core {
677 inline op sub(inout NUM, in NUM) :base_core {
681 inline op sub(invar PMC, invar PMC) :base_core {
682 VTABLE_i_subtract(interp, $1, $2);
685 inline op sub(invar PMC, in INT) :base_core {
686 VTABLE_i_subtract_int(interp, $1, $2);
689 inline op sub(invar PMC, in NUM) :base_core {
690 VTABLE_i_subtract_float(interp, $1, $2);
693 inline op sub(out INT, in INT, in INT) :base_core {
697 inline op sub(out NUM, in NUM, in NUM) :base_core {
701 inline op sub(invar PMC, invar PMC, invar PMC) :base_core {
702 $1 = VTABLE_subtract(interp, $2, $3, $1);
705 inline op sub(invar PMC, invar PMC, in INT) :base_core {
706 $1 = VTABLE_subtract_int(interp, $2, $3, $1);
709 inline op sub(invar PMC, invar PMC, in NUM) :base_core {
710 $1 = VTABLE_subtract_float(interp, $2, $3, $1);
713 ########################################
715 =item B<sqrt>(out NUM, in NUM)
717 Set $1 to the square root of $2.
721 inline op sqrt(out NUM, in NUM) :base_core {
722 $1 = sqrt((FLOATVAL)$2);
729 ###############################################################################
733 Copyright (C) 2001-2009, Parrot Foundation.
737 This program is free software. It is subject to the same license
738 as the Parrot interpreter itself.
744 * c-file-style: "parrot"
746 * vim: expandtab shiftwidth=4: