NAME
src/utils.c - Some utility functions
DESCRIPTION
Prototypes are in src/misc.h.
Opcode helper functions that don't really fit elsewhere.
Functions
INTVAL intval_mod
NOTE: This "corrected mod" algorithm is based on the C code on page 70 of [1].
Assuming correct behavior of the built-in mod operator (%) with positive arguments,
this algorithm implements a mathematically convenient version of mod,
defined thus:
FLOATVAL floatval_mod
Returns
x mod y = x - y * floor(x / y)For more information on this definition of mod, see section 3.4 of [2], pages 81-85.References:[1] Donald E. Knuth, *MMIXware: A RISC Computer for the Third Millennium* Springer, 1999.[2] Ronald L. Graham, Donald E. Knuth and Oren Patashnik, *Concrete Mathematics*, Second Edition. Addison-Wesley, 1994.
n2 mod n3
.Includes a workaround for buggy code generation in the lcc
compiler.Random Number Generator
Based on the rand48()
family of functions.
static void next_rand
Returns the next random number in static FLOATVAL _erand48
Returns a static FLOATVAL _drand48
Returns a static long _jrand48
Returns a static long _nrand48
Returns a static long _lrand48
Returns a static long _mrand48
Returns a static void _srand48
Sets the high order 32 bits to the argument FLOATVAL Parrot_float_rand
Returns a INTVAL Parrot_uint_rand
Returns an INTVAL Parrot_int_rand
Returns an INTVAL Parrot_range_rand
Returns an void Parrot_srand
Seeds the random number generator with PMC *tm_to_array
Helper to convert a struct tm * to an Array
INTVAL Parrot_byte_index
Looks for the location of a substring within a longer string. Takes pointers to the strings and the offset within the string at which to start searching as arguments.Returns an offset value if it is found, or -1 if no match.
INTVAL Parrot_byte_rindex
Substring search (like Parrot_byte_index), but works backwards, from the rightmost end of the string.Returns offset value or -1 (if no match).
static void rec_climb_back_and_mark
Recursive function, used by Parrot_register_move to climb back the graph of register moves operations.The node must have a predecessor: it is implicit because if a node has a node_index, it must have a predecessor because the node_index are the index of registers in dest_regs[] array, so by definition they have a corrsponding src_regs register.Then it emits the move operation with its predecessor, or its backup if already used/visited.Then continues the climbing if the predecessor was not modified, anf in that case marks it, and set node_index as its backup.
static void process_cycle_without_exit
Recursive function, used by Parrot_register_move to handle the case of cycles without exits, that are cycles of move ops between registers where each register has exactly one predecessor and one successorFor instance: 1-->2, 2-->3, 3-->1
void Parrot_register_move
Move
X
.
double
in the interval [0.0, 1.0)
.
double
in the interval [0.0, 1.0)
.
long
in the interval [-2^31, 2^31)
.
long
in the interval [0, 2^31)
.
long
in the interval [0, 2^31)
.
long
in the interval [-2^31, 2^31)
.
seed
. The low order 16 bits are set to the arbitrary value 0x330e.
FLOATVAL
in the interval [0.0, 1.0)
.how_random
is ignored.
INTVAL
in the interval [0, 2^31)
.how_random
is ignored.
INTVAL
in the interval [-2^31, 2^31)
.how_random
is ignored.
INTVAL
in the range [from, to]
.how_random
is ignored.
seed
.
node_index ... the index of a destination (i.e. with a pred.) register c ... the graph and all the needed params : the context
node_index ... the index of a destination (i.e. with a pred.) register c ... the graph and all the needed params : the context
n_regs
from the given register list src_regs
to dest_regs
.
n_regs ... amount of registers to move dest_regs ... list of register numbers 0..255 src_regs ... list of register numbers 0..255 temp_reg ... a register number not in one of these lists mov ... a register move function to be called to move one register mov_alt ... a register move function to be called to move one register which triese fetching from an alternate src (or NULLfunc): (void) (mov)(interp, dest, src, info); moved = (mov_alt)(interp, dest, src, info);Some
dest_regs
might be the same as src_regs
, which makes this a bit non-trivial, because if the destination is already clobbered, using it later as source doesn"t work. E.g.
0 <- 1 1 <- 0 # register 0 already clobberedor
2 <- 0 0 <- 1 3 <- 2 # register 2 already clobbered - reorder movesTo handle such cases, we do:
a) rearrange the order of moves (not possible in the first case) and/or if that failed: b) if an alternate move function is available, it may fetch the source from a different (non-clobbered) location - call it. if the function returns 0 also use c) c) if no alternate move function is available, use the temp regThe amount of register moves should of course be minimal.TODO The current implementation will not work for following casesTalked to Leo and he said those cases are not likely (Vishal Soni). 1. I0->I1 I1->I0 I0->I3 2. I1->I2 I3->I2TODO: Add tests for the above conditions.
HISTORY
Initial version by leo 2003.09.09.