Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / lib / libkern / arch / sparc64 / random.S
blobca25a56f09e8deb64def257ba4064ad1fc00ec44
1 /*      $NetBSD: random.S,v 1.2 2009/01/04 17:10:47 pooka Exp $ */
3 /*
4  * Copyright (c) 1990,1993 The Regents of the University of California.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that: (1) source code distributions
9  * retain the above copyright notice and this paragraph in its entirety, (2)
10  * distributions including binary code include the above copyright notice and
11  * this paragraph in its entirety in the documentation or other materials
12  * provided with the distribution, and (3) all advertising materials mentioning
13  * features or use of this software display the following acknowledgement:
14  * ``This product includes software developed by the University of California,
15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16  * the University nor the names of its contributors may be used to endorse
17  * or promote products derived from this software without specific prior
18  * written permission.
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  *
23  * Here is a very good random number generator.  This implementation is
24  * based on ``Two Fast Implementations of the "Minimal Standard" Random
25  * Number Generator'', David G. Carta, Communications of the ACM, Jan 1990,
26  * Vol 33 No 1.  Do NOT modify this code unless you have a very thorough
27  * understanding of the algorithm.  It's trickier than you think.  If
28  * you do change it, make sure that its 10,000'th invocation returns
29  * 1043618065.
30  *
31  * Here is easier-to-decipher pseudocode:
32  *
33  * p = (16807*seed)<30:0>       # e.g., the low 31 bits of the product
34  * q = (16807*seed)<62:31>      # e.g., the high 31 bits starting at bit 32
35  * if (p + q < 2^31)
36  *      seed = p + q
37  * else
38  *      seed = ((p + q) & (2^31 - 1)) + 1
39  * return (seed);
40  *
41  * The result is in (0,2^31), e.g., it's always positive.
42  */
43 #include <machine/asm.h>
45         .data
46 randseed:
47         .long   1
49         .text
50 ENTRY(random)
51         sethi   %hi(16807), %o1
52         wr      %o1, %lo(16807), %y
53 #ifdef PIC
54         PIC_PROLOGUE(%o5, %o2)
55         set     randseed, %g1
56         ldx     [%o5 + %g1], %g1
57         ld      [%g1], %o0
58 #else
59         sethi   %hi(randseed), %g1
60         ld      [%g1 + %lo(randseed)], %o0
61 #endif
62         andcc   %g0, 0, %o2
63         mulscc  %o2, %o0, %o2
64         mulscc  %o2, %o0, %o2
65         mulscc  %o2, %o0, %o2
66         mulscc  %o2, %o0, %o2
67         mulscc  %o2, %o0, %o2
68         mulscc  %o2, %o0, %o2
69         mulscc  %o2, %o0, %o2
70         mulscc  %o2, %o0, %o2
71         mulscc  %o2, %o0, %o2
72         mulscc  %o2, %o0, %o2
73         mulscc  %o2, %o0, %o2
74         mulscc  %o2, %o0, %o2
75         mulscc  %o2, %o0, %o2
76         mulscc  %o2, %o0, %o2
77         mulscc  %o2, %o0, %o2
78         mulscc  %o2, %g0, %o2
79         rd      %y, %o3
80         srl     %o2, 16, %o1
81         set     0xffff, %o4
82         and     %o4, %o2, %o0
83         sll     %o0, 15, %o0
84         srl     %o3, 17, %o3
85         or      %o3, %o0, %o0
86         addcc   %o0, %o1, %o0
87         bneg    1f
88         sethi   %hi(0x7fffffff), %o1
89         retl
90 #ifdef PIC
91         st      %o0, [%g1]
92 #else
93         st      %o0, [%g1 + %lo(randseed)]
94 #endif
96         or      %o1, %lo(0x7fffffff), %o1
97         add     %o0, 1, %o0
98         and     %o1, %o0, %o0
99         retl
100 #ifdef PIC
101         st      %o0, [%g1]
102 #else
103         st      %o0, [%g1 + %lo(randseed)]
104 #endif