Raymond Toy pushed to branch master at cmucl / cmucl

Commits:

18 changed files:

Changes:

  • .gitlab-ci.yml
    ... ... @@ -8,7 +8,10 @@ linux-runner:
    8 8
         - mkdir snapshot
    
    9 9
         - (cd snapshot; tar xjf ../cmucl-21c-x86-linux.tar.bz2; tar xjf ../cmucl-21c-x86-linux.extra.tar.bz2)
    
    10 10
       script:
    
    11
    -    - bin/build.sh -C "" -o ./snapshot/bin/lisp
    
    11
    +    - bin/create-target.sh xtarget x86_linux x86
    
    12
    +    - bin/create-target.sh xcross x86_linux x86
    
    13
    +    - bin/cross-build-world.sh -crl xtarget xcross src/bootfiles/21c/boot-21c-cross.lisp ./snapshot/bin/lisp
    
    14
    +    - bin/build.sh -C "" -o xtarget/lisp/lisp
    
    12 15
         - bin/make-dist.sh -I dist linux-4
    
    13 16
         - bin/run-tests.sh -l dist/bin/lisp 2>&1 | tee test.log
    
    14 17
     
    
    ... ... @@ -20,6 +23,9 @@ osx-runner:
    20 23
         - mkdir snapshot
    
    21 24
         - (cd snapshot; tar xjf ../cmucl-21c-x86-darwin.tar.bz2)
    
    22 25
       script:
    
    23
    -    - bin/build.sh -C "" -o ./snapshot/bin/lisp
    
    26
    +    - bin/create-target.sh xtarget x86_darwin
    
    27
    +    - bin/create-target.sh xcross x86_darwin
    
    28
    +    - bin/cross-build-world.sh -crl xtarget xcross src/bootfiles/21c/boot-21c-cross.lisp ./snapshot/bin/lisp
    
    29
    +    - bin/build.sh -C "" -o xtarget/lisp/lisp
    
    24 30
         - bin/make-dist.sh -I dist darwin-4
    
    25 31
         - bin/run-tests.sh -l dist/bin/lisp 2>&1 | tee test.log

  • bin/build.sh
    ... ... @@ -39,7 +39,7 @@ ENABLE2="yes"
    39 39
     ENABLE3="yes"
    
    40 40
     ENABLE4="yes"
    
    41 41
     
    
    42
    -version=21b
    
    42
    +version=21c
    
    43 43
     SRCDIR=src
    
    44 44
     BINDIR=bin
    
    45 45
     TOOLDIR=$BINDIR
    

  • src/bootfiles/21c/boot-21c-cross-sparc.lisp
    1
    +(in-package :cl-user)
    
    2
    +
    
    3
    +;;; Rename the SPARC package and backend so that new-backend does the
    
    4
    +;;; right thing.
    
    5
    +(rename-package "SPARC" "OLD-SPARC" '("OLD-VM"))
    
    6
    +(setf (c:backend-name c:*native-backend*) "OLD-SPARC")
    
    7
    +
    
    8
    +(c::new-backend "SPARC"
    
    9
    +   ;; Features to add here
    
    10
    +   '(:sparc
    
    11
    +     :sparc-v9				; For Ultrasparc processors
    
    12
    +     :complex-fp-vops			; Some slightly faster FP vops on complex numbers
    
    13
    +     :linkage-table
    
    14
    +     :stack-checking			; Throw error if we run out of stack
    
    15
    +     :heap-overflow-check		; Throw error if we run out of
    
    16
    +					; heap (This requires gencgc!)
    
    17
    +     :gencgc				; Generational GC
    
    18
    +     :relative-package-names		; Relative package names from Allegro
    
    19
    +     :conservative-float-type
    
    20
    +     :hash-new
    
    21
    +     :random-xoroshiro			; xoroshiro128+ RNG
    
    22
    +     :cmu				; Announce this is CMUCL
    
    23
    +     :cmu20 :cmu20a			; Current version identifier
    
    24
    +     :modular-arith			; Modular arithmetic
    
    25
    +     :double-double			; Double-double float support
    
    26
    +     )
    
    27
    +   ;; Features to remove from current *features* here
    
    28
    +   '(:sparc-v8 :sparc-v7		; Choose only one of :sparc-v7, :sparc-v8, :sparc-v9
    
    29
    +     ;; Other architectures we aren't using.
    
    30
    +     :x86 :x86-bootstrap
    
    31
    +     :alpha :osf1 :mips
    
    32
    +     ;; Really old stuff that should have been removed long ago.
    
    33
    +     :propagate-fun-type :propagate-float-type :constrain-float-type
    
    34
    +     ;; Other OSes were not using
    
    35
    +     :openbsd :freebsd :glibc2 :linux
    
    36
    +     :pentium
    
    37
    +     :long-float
    
    38
    +     :new-random
    
    39
    +     :random-mt19937			; MT-19937 generator
    
    40
    +     :small))
    
    41
    +
    
    42
    +;;; May need to add some symbols to *features* and
    
    43
    +;;; sys::*runtime-features* as well.  This might be needed even if we
    
    44
    +;;; have those listed above, because of the code checks for things in
    
    45
    +;;; *features* and not in the backend-features..  So do that here.
    
    46
    +
    
    47
    +
    
    48
    +;;; Extern-alien-name for the new backend.
    
    49
    +(in-package :vm)
    
    50
    +(defun extern-alien-name (name)
    
    51
    +  (declare (type simple-string name))
    
    52
    +  #+(and bsd (not elf))
    
    53
    +  (concatenate 'string "_" name)
    
    54
    +  #-(and bsd (not elf))
    
    55
    +  name)
    
    56
    +;; When compiling the compiler, vm:fixup-code-object and
    
    57
    +;; vm:sanctify-for-execution are undefined.  Import these to get rid
    
    58
    +;; of that error.
    
    59
    +(import 'old-vm::fixup-code-object)
    
    60
    +(import 'old-vm::sanctify-for-execution)
    
    61
    +(export 'extern-alien-name)
    
    62
    +(export 'fixup-code-object)
    
    63
    +(export 'sanctify-for-execution)
    
    64
    +
    
    65
    +(in-package :cl-user)
    
    66
    +
    
    67
    +;;; Compile the new backend.
    
    68
    +(pushnew :bootstrap *features*)
    
    69
    +(pushnew :building-cross-compiler *features*)
    
    70
    +(load "target:tools/comcom")
    
    71
    +
    
    72
    +;;; Load the new backend.
    
    73
    +(setf (search-list "c:")
    
    74
    +      '("target:compiler/"))
    
    75
    +(setf (search-list "vm:")
    
    76
    +      '("c:sparc/" "c:generic/"))
    
    77
    +(setf (search-list "assem:")
    
    78
    +      '("target:assembly/" "target:assembly/sparc/"))
    
    79
    +
    
    80
    +;; Load the backend of the compiler.
    
    81
    +
    
    82
    +(in-package "C")
    
    83
    +
    
    84
    +(load "vm:vm-macs")
    
    85
    +(load "vm:parms")
    
    86
    +(load "vm:objdef")
    
    87
    +(load "vm:interr")
    
    88
    +(load "assem:support")
    
    89
    +
    
    90
    +(load "target:compiler/srctran")
    
    91
    +(load "vm:vm-typetran")
    
    92
    +(load "target:compiler/float-tran")
    
    93
    +(load "target:compiler/saptran")
    
    94
    +
    
    95
    +(load "vm:macros")
    
    96
    +(load "vm:utils")
    
    97
    +
    
    98
    +(load "vm:vm")
    
    99
    +(load "vm:insts")
    
    100
    +(load "vm:primtype")
    
    101
    +(load "vm:move")
    
    102
    +(load "vm:sap")
    
    103
    +(load "vm:system")
    
    104
    +(load "vm:char")
    
    105
    +(load "vm:float")
    
    106
    +
    
    107
    +(load "vm:memory")
    
    108
    +(load "vm:static-fn")
    
    109
    +(load "vm:arith")
    
    110
    +(load "vm:cell")
    
    111
    +(load "vm:subprim")
    
    112
    +(load "vm:debug")
    
    113
    +(load "vm:c-call")
    
    114
    +(load "vm:print")
    
    115
    +(load "vm:alloc")
    
    116
    +(load "vm:call")
    
    117
    +(load "vm:nlx")
    
    118
    +(load "vm:values")
    
    119
    +(load "vm:array")
    
    120
    +(load "vm:pred")
    
    121
    +(load "vm:type-vops")
    
    122
    +
    
    123
    +(load "assem:assem-rtns")
    
    124
    +
    
    125
    +(load "assem:array")
    
    126
    +(load "assem:arith")
    
    127
    +(load "assem:alloc")
    
    128
    +
    
    129
    +(load "c:pseudo-vops")
    
    130
    +
    
    131
    +(check-move-function-consistency)
    
    132
    +
    
    133
    +(load "vm:new-genesis")
    
    134
    +
    
    135
    +;;; OK, the cross compiler backend is loaded.
    
    136
    +
    
    137
    +(setf *features* (remove :building-cross-compiler *features*))
    
    138
    +
    
    139
    +;;; Info environment hacks.
    
    140
    +(macrolet ((frob (&rest syms)
    
    141
    +	     `(progn ,@(mapcar #'(lambda (sym)
    
    142
    +				   `(defconstant ,sym
    
    143
    +				      (symbol-value
    
    144
    +				       (find-symbol ,(symbol-name sym)
    
    145
    +						    :vm))))
    
    146
    +			       syms))))
    
    147
    +  (frob OLD-VM:BYTE-BITS OLD-VM:WORD-BITS
    
    148
    +	OLD-VM:CHAR-BITS
    
    149
    +	OLD-VM:CHAR-BYTES
    
    150
    +	OLD-VM:LOWTAG-BITS
    
    151
    +	#+long-float OLD-VM:SIMPLE-ARRAY-LONG-FLOAT-TYPE 
    
    152
    +	OLD-VM:SIMPLE-ARRAY-DOUBLE-FLOAT-TYPE 
    
    153
    +	OLD-VM:SIMPLE-ARRAY-SINGLE-FLOAT-TYPE
    
    154
    +	#+long-float OLD-VM:SIMPLE-ARRAY-COMPLEX-LONG-FLOAT-TYPE 
    
    155
    +	OLD-VM:SIMPLE-ARRAY-COMPLEX-DOUBLE-FLOAT-TYPE 
    
    156
    +	OLD-VM:SIMPLE-ARRAY-COMPLEX-SINGLE-FLOAT-TYPE
    
    157
    +	OLD-VM:SIMPLE-ARRAY-UNSIGNED-BYTE-2-TYPE 
    
    158
    +	OLD-VM:SIMPLE-ARRAY-UNSIGNED-BYTE-4-TYPE
    
    159
    +	OLD-VM:SIMPLE-ARRAY-UNSIGNED-BYTE-8-TYPE 
    
    160
    +	OLD-VM:SIMPLE-ARRAY-UNSIGNED-BYTE-16-TYPE 
    
    161
    +	OLD-VM:SIMPLE-ARRAY-UNSIGNED-BYTE-32-TYPE 
    
    162
    +	OLD-VM:SIMPLE-ARRAY-SIGNED-BYTE-8-TYPE 
    
    163
    +	OLD-VM:SIMPLE-ARRAY-SIGNED-BYTE-16-TYPE
    
    164
    +	OLD-VM:SIMPLE-ARRAY-SIGNED-BYTE-30-TYPE 
    
    165
    +	OLD-VM:SIMPLE-ARRAY-SIGNED-BYTE-32-TYPE
    
    166
    +	OLD-VM:SIMPLE-BIT-VECTOR-TYPE
    
    167
    +	OLD-VM:SIMPLE-STRING-TYPE OLD-VM:SIMPLE-VECTOR-TYPE 
    
    168
    +	OLD-VM:SIMPLE-ARRAY-TYPE OLD-VM:VECTOR-DATA-OFFSET
    
    169
    +	OLD-VM:DOUBLE-FLOAT-DIGITS
    
    170
    +	old-vm:single-float-digits
    
    171
    +	OLD-VM:DOUBLE-FLOAT-EXPONENT-BYTE
    
    172
    +	OLD-VM:DOUBLE-FLOAT-NORMAL-EXPONENT-MAX
    
    173
    +	OLD-VM:DOUBLE-FLOAT-SIGNIFICAND-BYTE
    
    174
    +	OLD-VM:SINGLE-FLOAT-EXPONENT-BYTE
    
    175
    +	OLD-VM:SINGLE-FLOAT-NORMAL-EXPONENT-MAX
    
    176
    +	OLD-VM:SINGLE-FLOAT-SIGNIFICAND-BYTE
    
    177
    +	)
    
    178
    +  #+double-double
    
    179
    +  (frob OLD-VM:SIMPLE-ARRAY-COMPLEX-DOUBLE-DOUBLE-FLOAT-TYPE
    
    180
    +	OLD-VM:SIMPLE-ARRAY-DOUBLE-DOUBLE-FLOAT-TYPE)
    
    181
    +  )
    
    182
    +
    
    183
    +;; Modular arith hacks.  When cross-compiling, the compiler wants to
    
    184
    +;; constant-fold some stuff, and it needs the following functions to
    
    185
    +;; do so.  This just gets rid of the hundreds of errors that happen.
    
    186
    +(setf (fdefinition 'vm::ash-left-mod32) #'old-vm::ash-left-mod32)
    
    187
    +(setf (fdefinition 'vm::lognot-mod32) #'old-vm::lognot-mod32)
    
    188
    +;; End modular arith hacks
    
    189
    +
    
    190
    +(let ((function (symbol-function 'kernel:error-number-or-lose)))
    
    191
    +  (let ((*info-environment* (c:backend-info-environment c:*target-backend*)))
    
    192
    +    (setf (symbol-function 'kernel:error-number-or-lose) function)
    
    193
    +    (setf (info function kind 'kernel:error-number-or-lose) :function)
    
    194
    +    (setf (info function where-from 'kernel:error-number-or-lose) :defined)))
    
    195
    +
    
    196
    +(defun fix-class (name)
    
    197
    +  (let* ((new-value (find-class name))
    
    198
    +	 (new-layout (kernel::%class-layout new-value))
    
    199
    +	 (new-cell (kernel::find-class-cell name))
    
    200
    +	 (*info-environment* (c:backend-info-environment c:*target-backend*)))
    
    201
    +    (remhash name kernel::*forward-referenced-layouts*)
    
    202
    +    (kernel::%note-type-defined name)
    
    203
    +    (setf (info type kind name) :instance)
    
    204
    +    (setf (info type class name) new-cell)
    
    205
    +    (setf (info type compiler-layout name) new-layout)
    
    206
    +    new-value))
    
    207
    +(fix-class 'c::vop-parse)
    
    208
    +(fix-class 'c::operand-parse)
    
    209
    +
    
    210
    +#+random-mt19937
    
    211
    +(declaim (notinline kernel:random-chunk))
    
    212
    +
    
    213
    +(setf c:*backend* c:*target-backend*)
    
    214
    +
    
    215
    +;;; Extern-alien-name for the new backend.
    
    216
    +(in-package :vm)
    
    217
    +(defun extern-alien-name (name)
    
    218
    +  (declare (type simple-string name))
    
    219
    +  name)
    
    220
    +(export 'extern-alien-name)
    
    221
    +(export 'fixup-code-object)
    
    222
    +(export 'sanctify-for-execution)
    
    223
    +(in-package :cl-user)
    
    224
    +
    
    225
    +;;; Don't load compiler parts from the target compilation
    
    226
    +
    
    227
    +(defparameter *load-stuff* nil)
    
    228
    +
    
    229
    +;; Sometimes during cross-compile sparc::any-reg isn't defined during
    
    230
    +;; cross-compile.
    
    231
    +;;
    
    232
    +;; hack, hack, hack: Make old-vm::any-reg the same as
    
    233
    +;; sparc::any-reg as an SC.  Do this by adding old-vm::any-reg
    
    234
    +;; to the hash table with the same value as sparc::any-reg.
    
    235
    +(let ((ht (c::backend-sc-names c::*target-backend*)))
    
    236
    +  (setf (gethash 'old-vm::any-reg ht)
    
    237
    +	(gethash 'vm::any-reg ht)))

  • src/bootfiles/21c/boot-21c-cross-x86.lisp
    1
    +;; Basic cross-compile script for cross-compiling from x86 to x86.
    
    2
    +;; May require tweaking for more difficult cross-compiles.
    
    3
    +
    
    4
    +(in-package :cl-user)
    
    5
    +
    
    6
    +;;; Rename the X86 package and backend so that new-backend does the
    
    7
    +;;; right thing.
    
    8
    +(rename-package "X86" "OLD-X86" '("OLD-VM"))
    
    9
    +(setf (c:backend-name c:*native-backend*) "OLD-X86")
    
    10
    +
    
    11
    +(c::new-backend "X86"
    
    12
    +   ;; Features to add here.  These are just examples.  You may not
    
    13
    +   ;; need to list anything here.  We list them here anyway as a
    
    14
    +   ;; record of typical features for all x86 ports.
    
    15
    +   '(:x86 :i486 :pentium
    
    16
    +     :stack-checking			; Catches stack overflow
    
    17
    +     :heap-overflow-check		; Catches heap overflows
    
    18
    +     :relative-package-names		; relative package names
    
    19
    +     :mp				; multiprocessing
    
    20
    +     :gencgc				; Generational GC
    
    21
    +     :conservative-float-type
    
    22
    +     :hash-new
    
    23
    +     :random-xoroshiro			; xoroshiro128+ RNG
    
    24
    +     :cmu :cmu20 :cmu20a		; Version features
    
    25
    +     :double-double			; double-double float support
    
    26
    +     )
    
    27
    +   ;; Features to remove from current *features* here.  Normally don't
    
    28
    +   ;; need to list anything here unless you are trying to remove a
    
    29
    +   ;; feature.
    
    30
    +   '(:x86-bootstrap
    
    31
    +     ;; :alpha :osf1 :mips
    
    32
    +     :propagate-fun-type :propagate-float-type :constrain-float-type
    
    33
    +     ;; :openbsd :freebsd :glibc2 :linux
    
    34
    +     :long-float :new-random :small
    
    35
    +     :random-mt19937))
    
    36
    +
    
    37
    +;;; Compile the new backend.
    
    38
    +(pushnew :bootstrap *features*)
    
    39
    +(pushnew :building-cross-compiler *features*)
    
    40
    +
    
    41
    +;; Make fixup-code-object and sanctify-for-execution in the VM package
    
    42
    +;; be the same as the original.  Needed to get rid of a compiler error
    
    43
    +;; in generic/core.lisp.  (This halts cross-compilations if the
    
    44
    +;; compiling lisp uses the -batch flag.
    
    45
    +(import 'old-vm::fixup-code-object "VM")
    
    46
    +(import 'old-vm::sanctify-for-execution "VM")
    
    47
    +(export 'vm::fixup-code-object "VM")
    
    48
    +(export 'vm::sanctify-for-execution "VM")
    
    49
    +
    
    50
    +(do-external-symbols (sym "OLD-VM")
    
    51
    +  (export (intern (symbol-name sym) "VM") "VM"))
    
    52
    +
    
    53
    +(load "target:tools/comcom")
    
    54
    +
    
    55
    +;;; Load the new backend.
    
    56
    +(setf (search-list "c:")
    
    57
    +      '("target:compiler/"))
    
    58
    +(setf (search-list "vm:")
    
    59
    +      '("c:x86/" "c:generic/"))
    
    60
    +(setf (search-list "assem:")
    
    61
    +      '("target:assembly/" "target:assembly/x86/"))
    
    62
    +
    
    63
    +;; Load the backend of the compiler.
    
    64
    +
    
    65
    +(in-package "C")
    
    66
    +
    
    67
    +(load "vm:vm-macs")
    
    68
    +(load "vm:parms")
    
    69
    +(load "vm:objdef")
    
    70
    +(load "vm:interr")
    
    71
    +(load "assem:support")
    
    72
    +
    
    73
    +(load "target:compiler/srctran")
    
    74
    +(load "vm:vm-typetran")
    
    75
    +(load "target:compiler/float-tran")
    
    76
    +(load "target:compiler/saptran")
    
    77
    +
    
    78
    +(load "vm:macros")
    
    79
    +(load "vm:utils")
    
    80
    +
    
    81
    +(load "vm:vm")
    
    82
    +(load "vm:insts")
    
    83
    +(load "vm:primtype")
    
    84
    +(load "vm:move")
    
    85
    +(load "vm:sap")
    
    86
    +(when (target-featurep :sse2)
    
    87
    +  (load "vm:sse2-sap"))
    
    88
    +(load "vm:system")
    
    89
    +(load "vm:char")
    
    90
    +(if (target-featurep :sse2)
    
    91
    +    (load "vm:float-sse2")
    
    92
    +    (load "vm:float"))
    
    93
    +
    
    94
    +(load "vm:memory")
    
    95
    +(load "vm:static-fn")
    
    96
    +(load "vm:arith")
    
    97
    +(load "vm:cell")
    
    98
    +(load "vm:subprim")
    
    99
    +(load "vm:debug")
    
    100
    +(load "vm:c-call")
    
    101
    +(if (target-featurep :sse2)
    
    102
    +    (load "vm:sse2-c-call")
    
    103
    +    (load "vm:x87-c-call"))
    
    104
    +
    
    105
    +(load "vm:print")
    
    106
    +(load "vm:alloc")
    
    107
    +(load "vm:call")
    
    108
    +(load "vm:nlx")
    
    109
    +(load "vm:values")
    
    110
    +;; These need to be loaded before array because array wants to use
    
    111
    +;; some vops as templates.
    
    112
    +(load (if (target-featurep :sse2)
    
    113
    +	  "vm:sse2-array"
    
    114
    +	  "vm:x87-array"))
    
    115
    +(load "vm:array")
    
    116
    +(load "vm:pred")
    
    117
    +(load "vm:type-vops")
    
    118
    +
    
    119
    +(load "assem:assem-rtns")
    
    120
    +
    
    121
    +(load "assem:array")
    
    122
    +(load "assem:arith")
    
    123
    +(load "assem:alloc")
    
    124
    +
    
    125
    +(load "c:pseudo-vops")
    
    126
    +
    
    127
    +(check-move-function-consistency)
    
    128
    +
    
    129
    +(load "vm:new-genesis")
    
    130
    +
    
    131
    +;;; OK, the cross compiler backend is loaded.
    
    132
    +
    
    133
    +(setf *features* (remove :building-cross-compiler *features*))
    
    134
    +
    
    135
    +;;; Info environment hacks.
    
    136
    +(macrolet ((frob (&rest syms)
    
    137
    +	     `(progn ,@(mapcar #'(lambda (sym)
    
    138
    +				   `(defconstant ,sym
    
    139
    +				      (symbol-value
    
    140
    +				       (find-symbol ,(symbol-name sym)
    
    141
    +						    :vm))))
    
    142
    +			       syms))))
    
    143
    +  (frob OLD-VM:BYTE-BITS OLD-VM:WORD-BITS
    
    144
    +	OLD-VM:CHAR-BITS
    
    145
    +	OLD-VM:CHAR-BYTES
    
    146
    +	#+long-float OLD-VM:SIMPLE-ARRAY-LONG-FLOAT-TYPE 
    
    147
    +	OLD-VM:SIMPLE-ARRAY-DOUBLE-FLOAT-TYPE 
    
    148
    +	OLD-VM:SIMPLE-ARRAY-SINGLE-FLOAT-TYPE
    
    149
    +	#+long-float OLD-VM:SIMPLE-ARRAY-COMPLEX-LONG-FLOAT-TYPE 
    
    150
    +	OLD-VM:SIMPLE-ARRAY-COMPLEX-DOUBLE-FLOAT-TYPE 
    
    151
    +	OLD-VM:SIMPLE-ARRAY-COMPLEX-SINGLE-FLOAT-TYPE
    
    152
    +	OLD-VM:SIMPLE-ARRAY-UNSIGNED-BYTE-2-TYPE 
    
    153
    +	OLD-VM:SIMPLE-ARRAY-UNSIGNED-BYTE-4-TYPE
    
    154
    +	OLD-VM:SIMPLE-ARRAY-UNSIGNED-BYTE-8-TYPE 
    
    155
    +	OLD-VM:SIMPLE-ARRAY-UNSIGNED-BYTE-16-TYPE 
    
    156
    +	OLD-VM:SIMPLE-ARRAY-UNSIGNED-BYTE-32-TYPE 
    
    157
    +	OLD-VM:SIMPLE-ARRAY-SIGNED-BYTE-8-TYPE 
    
    158
    +	OLD-VM:SIMPLE-ARRAY-SIGNED-BYTE-16-TYPE
    
    159
    +	OLD-VM:SIMPLE-ARRAY-SIGNED-BYTE-30-TYPE 
    
    160
    +	OLD-VM:SIMPLE-ARRAY-SIGNED-BYTE-32-TYPE
    
    161
    +	OLD-VM:SIMPLE-BIT-VECTOR-TYPE
    
    162
    +	OLD-VM:SIMPLE-STRING-TYPE OLD-VM:SIMPLE-VECTOR-TYPE 
    
    163
    +	OLD-VM:SIMPLE-ARRAY-TYPE OLD-VM:VECTOR-DATA-OFFSET
    
    164
    +	OLD-VM:DOUBLE-FLOAT-EXPONENT-BYTE
    
    165
    +	OLD-VM:DOUBLE-FLOAT-NORMAL-EXPONENT-MAX 
    
    166
    +	OLD-VM:DOUBLE-FLOAT-SIGNIFICAND-BYTE
    
    167
    +	OLD-VM:SINGLE-FLOAT-EXPONENT-BYTE
    
    168
    +	OLD-VM:SINGLE-FLOAT-NORMAL-EXPONENT-MAX
    
    169
    +	OLD-VM:SINGLE-FLOAT-SIGNIFICAND-BYTE
    
    170
    +	)
    
    171
    +  #+double-double
    
    172
    +  (frob OLD-VM:SIMPLE-ARRAY-COMPLEX-DOUBLE-DOUBLE-FLOAT-TYPE
    
    173
    +	OLD-VM:SIMPLE-ARRAY-DOUBLE-DOUBLE-FLOAT-TYPE))
    
    174
    +
    
    175
    +;; Modular arith hacks
    
    176
    +(setf (fdefinition 'vm::ash-left-mod32) #'old-vm::ash-left-mod32)
    
    177
    +(setf (fdefinition 'vm::lognot-mod32) #'old-vm::lognot-mod32)
    
    178
    +;; End arith hacks
    
    179
    +
    
    180
    +(let ((function (symbol-function 'kernel:error-number-or-lose)))
    
    181
    +  (let ((*info-environment* (c:backend-info-environment c:*target-backend*)))
    
    182
    +    (setf (symbol-function 'kernel:error-number-or-lose) function)
    
    183
    +    (setf (info function kind 'kernel:error-number-or-lose) :function)
    
    184
    +    (setf (info function where-from 'kernel:error-number-or-lose) :defined)))
    
    185
    +
    
    186
    +(defun fix-class (name)
    
    187
    +  (let* ((new-value (find-class name))
    
    188
    +	 (new-layout (kernel::%class-layout new-value))
    
    189
    +	 (new-cell (kernel::find-class-cell name))
    
    190
    +	 (*info-environment* (c:backend-info-environment c:*target-backend*)))
    
    191
    +    (remhash name kernel::*forward-referenced-layouts*)
    
    192
    +    (kernel::%note-type-defined name)
    
    193
    +    (setf (info type kind name) :instance)
    
    194
    +    (setf (info type class name) new-cell)
    
    195
    +    (setf (info type compiler-layout name) new-layout)
    
    196
    +    new-value))
    
    197
    +(fix-class 'c::vop-parse)
    
    198
    +(fix-class 'c::operand-parse)
    
    199
    +
    
    200
    +#+random-mt19937
    
    201
    +(declaim (notinline kernel:random-chunk))
    
    202
    +
    
    203
    +(setf c:*backend* c:*target-backend*)
    
    204
    +
    
    205
    +;;; Extern-alien-name for the new backend.
    
    206
    +(in-package :vm)
    
    207
    +(defun extern-alien-name (name)
    
    208
    +  (declare (type simple-string name))
    
    209
    +  #-elf
    
    210
    +  (concatenate 'simple-string "_" name)
    
    211
    +  #+elf
    
    212
    +  name)
    
    213
    +(export 'extern-alien-name)
    
    214
    +(in-package :cl-user)
    
    215
    +
    
    216
    +;;; Don't load compiler parts from the target compilation
    
    217
    +
    
    218
    +(defparameter *load-stuff* nil)
    
    219
    +
    
    220
    +;; hack, hack, hack: Make old-vm::any-reg the same as
    
    221
    +;; x86::any-reg as an SC.  Do this by adding old-vm::any-reg
    
    222
    +;; to the hash table with the same value as x86::any-reg.
    
    223
    +(let ((ht (c::backend-sc-names c::*target-backend*)))
    
    224
    +  (setf (gethash 'old-vm::any-reg ht)
    
    225
    +	(gethash 'vm::any-reg ht)))

  • src/bootfiles/21c/boot-21c-cross.lisp
    1
    +;; Cross-compile script to change the default random number generator
    
    2
    +;; from MT19937 to xoroshiro128+.
    
    3
    +
    
    4
    +;; The cross-script is basically the default platform script, but we
    
    5
    +;; remove :random-mt19937 and add :random-xoroshiro to the backend
    
    6
    +;; features.
    
    7
    +
    
    8
    +#+x86
    
    9
    +(load "src/bootfiles/21c/boot-21c-cross-x86.lisp")
    
    10
    +
    
    11
    +#+sparc
    
    12
    +(load "src/bootfiles/21c/boot-21c-cross-sparc.lisp")
    
    13
    +

  • src/code/exports.lisp
    ... ... @@ -2550,7 +2550,9 @@
    2550 2550
     	   "SIMPLE-ARRAY-COMPLEX-DOUBLE-DOUBLE-FLOAT-P"
    
    2551 2551
     	   "OBJECT-NOT-SIMPLE-ARRAY-COMPLEX-DOUBLE-DOUBLE-FLOAT-ERROR"
    
    2552 2552
     	   "DD-PI"
    
    2553
    -	   "INVALID-CASE"))
    
    2553
    +	   "INVALID-CASE")
    
    2554
    +  #+random-xoroshiro
    
    2555
    +  (:export "RANDOM-STATE-JUMP"))
    
    2554 2556
     
    
    2555 2557
     (dolist
    
    2556 2558
         (name
    

  • src/code/rand-xoroshiro.lisp
    1
    +;;; -*- Mode: Lisp; Package: Kernel -*-
    
    2
    +;;;
    
    3
    +;;; **********************************************************************
    
    4
    +;;; This code was written as part of CMU Common Lisp and has been
    
    5
    +;;; placed in the public domain, and is provided 'as is'.
    
    6
    +;;;
    
    7
    +(ext:file-comment
    
    8
    +  "$Header: src/code/rand-xoroshiro.lisp $")
    
    9
    +
    
    10
    +;;;
    
    11
    +;;; **********************************************************************
    
    12
    +;;;
    
    13
    +;;; Support for the xoroshiro128+ random number generator by David
    
    14
    +;;; Blackman and Sebastiano Vigna (vigna@acm.org). See
    
    15
    +;;; http://xoroshiro.di.unimi.it/.
    
    16
    +
    
    17
    +(in-package "LISP")
    
    18
    +(intl:textdomain "cmucl")
    
    19
    +
    
    20
    +(export '(random-state random-state-p random *random-state*
    
    21
    +	  make-random-state))
    
    22
    +
    
    23
    +(in-package "KERNEL")
    
    24
    +(export '(%random-single-float %random-double-float random-chunk init-random-state
    
    25
    +	  random-state-jump))
    
    26
    +
    
    27
    +(sys:register-lisp-feature :random-xoroshiro)
    
    28
    +
    
    29
    +
    
    30
    +;;;; Random state hackery:
    
    31
    +
    
    32
    +;; Generate a random seed that can be used for seeding the generator.
    
    33
    +;; If /dev/urandom is available, it is used to generate random data as
    
    34
    +;; the seed.  Otherwise, the current time is used as the seed.
    
    35
    +(defun generate-seed (&optional (nwords 1))
    
    36
    +  ;; On some systems (as reported by Ole Rohne on cmucl-imp),
    
    37
    +  ;; /dev/urandom isn't what we think it is, so if it doesn't work,
    
    38
    +  ;; silently generate the seed from the current time.
    
    39
    +  (or (ignore-errors
    
    40
    +	(let ((words (make-array nwords :element-type '(unsigned-byte 32))))
    
    41
    +	  (with-open-file (rand "/dev/urandom"
    
    42
    +				:direction :input
    
    43
    +				:element-type '(unsigned-byte 32))
    
    44
    +	    (read-sequence words rand))
    
    45
    +	  (if (= nwords 1)
    
    46
    +	      (aref words 0)
    
    47
    +	      (let ((vec (make-array (floor nwords 2) :element-type '(unsigned-byte 64))))
    
    48
    +		(do ((k 0 (+ k 1))
    
    49
    +		     (j 0 (+ j 2)))
    
    50
    +		    ((>= k (length vec))
    
    51
    +		     vec)
    
    52
    +		  (setf (aref vec k)
    
    53
    +			(logior (ash (aref words j) 32)
    
    54
    +				(aref words (+ j 1)))))))))
    
    55
    +      (logand (get-universal-time) #xffffffff)))
    
    56
    +
    
    57
    +(defun int-init-xoro-state (&optional (seed 5772156649015328606) state)
    
    58
    +  (let ((state (or state (make-array 2 :element-type 'double-float)))
    
    59
    +	(splitmix-state (ldb (byte 64 0) seed)))
    
    60
    +    (flet ((splitmix64 ()
    
    61
    +	     ;; See http://xoroshiro.di.unimi.it/splitmix64.c for the
    
    62
    +	     ;; definitive reference.  The basic algorithm, where x is
    
    63
    +	     ;; the 64-bit state of the generator, is:
    
    64
    +	     ;;
    
    65
    +	     ;;   uint64_t z = (x += 0x9e3779b97f4a7c15);
    
    66
    +	     ;;   z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
    
    67
    +	     ;;   z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
    
    68
    +	     ;;   return z ^ (z >> 31);
    
    69
    +	     ;;
    
    70
    +	     ;; This is only used occasionally for initializing the
    
    71
    +	     ;; RNG, so this is a very straight-forward
    
    72
    +	     ;; implementation.
    
    73
    +	     (let ((z (setf splitmix-state
    
    74
    +			    (ldb (byte 64 0) (+ splitmix-state #x9e3779b97f4a7c15)))))
    
    75
    +	       (declare (type (unsigned-byte 64) z))
    
    76
    +	       (setf z (ldb (byte 64 0)
    
    77
    +			    (* (logxor z (ash z -30))
    
    78
    +			       #xbf58476d1ce4e5b9)))
    
    79
    +	       (setf z (ldb (byte 64 0)
    
    80
    +			    (* (logxor z (ash z -27))
    
    81
    +			       #x94d049bb133111eb)))
    
    82
    +	       (logxor z (ash z -31))))
    
    83
    +	   (make-double (x)
    
    84
    +	     (let ((lo (ldb (byte 32 0) x))
    
    85
    +		   (hi (ldb (byte 32 32) x)))
    
    86
    +	       (kernel:make-double-float
    
    87
    +		(if (< hi #x80000000)
    
    88
    +		    hi
    
    89
    +		    (- hi #x100000000))
    
    90
    +		lo))))
    
    91
    +      (let* ((s0 (splitmix64))
    
    92
    +	     (s1 (splitmix64)))
    
    93
    +	   (setf (aref state 0) (make-double s0)
    
    94
    +		 (aref state 1) (make-double s1))
    
    95
    +	   state))))
    
    96
    +
    
    97
    +;; Initialize from an array.  The KEY is a 2-element array of unsigned
    
    98
    +;; 64-bit integers.  The state is set to the given 64-bit integer
    
    99
    +;; values.
    
    100
    +(defun vec-init-xoro-state (key &optional (state (make-array 2 :element-type 'double-float)))
    
    101
    +  (declare (type (array (unsigned-byte 64) (2)) key)
    
    102
    +	   (type (simple-array double-float (2)) state))
    
    103
    +  (flet ((make-double (x)
    
    104
    +	   (declare (type (unsigned-byte 64) x))
    
    105
    +	   (let ((hi (ldb (byte 32 32) x))
    
    106
    +		 (lo (ldb (byte 32 0) x)))
    
    107
    +	     (kernel:make-double-float
    
    108
    +	      (if (< hi #x80000000)
    
    109
    +		  hi
    
    110
    +		  (- hi #x100000000))
    
    111
    +	      lo))))
    
    112
    +    (setf (aref state 0) (make-double (aref key 0))
    
    113
    +	  (aref state 1) (make-double (aref key 1)))
    
    114
    +    state))
    
    115
    +
    
    116
    +;; The default seed is the digits of Euler's constant, 0.5772....
    
    117
    +(defun init-random-state (&optional (seed 5772156649015328606) state)
    
    118
    +  _N"Generate an random state vector from the given SEED.  The seed can be
    
    119
    +  either an integer or a vector of (unsigned-byte 64)"
    
    120
    +  (declare (type (or null integer
    
    121
    +		     (array (unsigned-byte 64) (*)))
    
    122
    +		 seed))
    
    123
    +  (let ((state (or state (make-array 2 :element-type 'double-float))))
    
    124
    +    (etypecase seed
    
    125
    +      (integer
    
    126
    +       (int-init-xoro-state (ldb (byte 64 0) seed) state))
    
    127
    +      ((array (unsigned-byte 64) (2))
    
    128
    +       (vec-init-xoro-state seed state)))))
    
    129
    +
    
    130
    +(defstruct (random-state
    
    131
    +	     (:constructor make-random-object)
    
    132
    +	     (:print-function %print-xoro-state)
    
    133
    +	     (:make-load-form-fun :just-dump-it-normally))
    
    134
    +  ;; The state of the RNG.  The actual algorithm uses 2 64-bit words
    
    135
    +  ;; of state.  To reduce consing, we use an array of double-float's
    
    136
    +  ;; since a double-float is 64 bits long.  At no point do we operate
    
    137
    +  ;; on these as floats; they're just convenient objects to hold the
    
    138
    +  ;; state we need.
    
    139
    +  (state (init-random-state)
    
    140
    +   :type (simple-array double-float (2)))
    
    141
    +  ;; The generator produces 64-bit results.  We separate the 64-bit
    
    142
    +  ;; result into two parts.  One is returned and the other is cached
    
    143
    +  ;; here for later use.
    
    144
    +  (rand 0 :type (unsigned-byte 32))
    
    145
    +  ;; Indicates if RAND holds a valid value.  If NIL, we need to
    
    146
    +  ;; generate a new 64-bit result.
    
    147
    +  (cached-p nil :type (member t nil)))
    
    148
    +
    
    149
    +(defun %print-xoro-state (rng-state stream depth)
    
    150
    +  (declare (ignore depth))
    
    151
    +  ;; Basically the same as the default structure printer, but we want
    
    152
    +  ;; to print the state as an array of integers instead of doubles,
    
    153
    +  ;; because it's a bit confusing to see the state as doubles.
    
    154
    +  (let ((state (random-state-state rng-state)))
    
    155
    +    (pprint-logical-block (stream nil :prefix "#S(" :suffix ")")
    
    156
    +      (prin1 'random-state stream)
    
    157
    +      (write-char #\space stream)
    
    158
    +      (pprint-indent :block 2 stream)
    
    159
    +      (pprint-newline :linear stream)
    
    160
    +      (prin1 :state stream)
    
    161
    +      (write-char #\space stream)
    
    162
    +      (pprint-newline :miser stream)
    
    163
    +      (pprint-logical-block (stream nil :prefix "#.(" :suffix ")")
    
    164
    +	(prin1 'init-random-state stream)
    
    165
    +	(write-char #\space stream)
    
    166
    +	(flet ((c (x)
    
    167
    +		 (multiple-value-bind (hi lo)
    
    168
    +		     (double-float-bits x)
    
    169
    +		   (logior (ash (ldb (byte 32 0) hi) 32)
    
    170
    +			   lo))))
    
    171
    +	  (write (make-array 2 :element-type '(unsigned-byte 64)
    
    172
    +			     :initial-contents (list (c (aref state 0))
    
    173
    +						     (c (aref state 1))))
    
    174
    +		 :stream stream
    
    175
    +		 :base 16
    
    176
    +		 :radix t)))
    
    177
    +      (write-char #\space stream)
    
    178
    +      (pprint-newline :linear stream)
    
    179
    +
    
    180
    +      (prin1 :rand stream)
    
    181
    +      (write-char #\space stream)
    
    182
    +      (pprint-newline :miser stream)
    
    183
    +      (prin1 (random-state-rand rng-state) stream)
    
    184
    +      (write-char #\space stream)
    
    185
    +      (pprint-newline :linear stream)
    
    186
    +
    
    187
    +      (prin1 :cached-p stream)
    
    188
    +      (write-char #\space stream)
    
    189
    +      (pprint-newline :miser stream)
    
    190
    +      (prin1 (random-state-cached-p rng-state) stream))))
    
    191
    +
    
    192
    +(defvar *random-state*
    
    193
    +  (make-random-object))
    
    194
    +
    
    195
    +(defun make-random-state (&optional state)
    
    196
    +  _N"Make a random state object.  If STATE is not supplied, return a copy
    
    197
    +  of the default random state.  If STATE is a random state, then return a
    
    198
    +  copy of it.  If STATE is T then return a random state generated from
    
    199
    +  the universal time or /dev/urandom if available."
    
    200
    +  (flet ((copy-random-state (state)
    
    201
    +	   (let ((old-state (random-state-state state))
    
    202
    +		 (new-state
    
    203
    +		  (make-array 2 :element-type 'double-float)))
    
    204
    +	     (setf (aref new-state 0) (aref old-state 0))
    
    205
    +	     (setf (aref new-state 1) (aref old-state 1))
    
    206
    +	     (make-random-object :state new-state
    
    207
    +				 :rand (random-state-rand state)
    
    208
    +				 :cached-p (random-state-cached-p state)))))
    
    209
    +    (cond ((not state)
    
    210
    +	   (copy-random-state *random-state*))
    
    211
    +	  ((random-state-p state)
    
    212
    +	   (copy-random-state state))
    
    213
    +	  ((eq state t)
    
    214
    +	   (make-random-object :state (init-random-state (generate-seed 4))
    
    215
    +			       :rand 0
    
    216
    +			       :cached-p nil))
    
    217
    +	  (t
    
    218
    +	   (error _"Argument is not a RANDOM-STATE, T, or NIL: ~S" state)))))
    
    219
    +
    
    220
    +(defun rand-initializer ()
    
    221
    +  (init-random-state (generate-seed)
    
    222
    +                     (random-state-state *random-state*)))
    
    223
    +
    
    224
    +(pushnew 'rand-initializer ext:*after-save-initializations*)
    
    225
    +
    
    226
    +;;;; Random entries:
    
    227
    +
    
    228
    +;; Sparc and x86 have vops to implement xoroshiro-gen that are much
    
    229
    +;; faster than the portable lisp version.  Use them.
    
    230
    +#+(or x86 sparc)
    
    231
    +(declaim (inline xoroshiro-gen))
    
    232
    +#+(or x86 sparc)
    
    233
    +(defun xoroshiro-gen (state)
    
    234
    +  (declare (type (simple-array double-float (2)) state)
    
    235
    +	   (optimize (speed 3) (safety 0)))
    
    236
    +  (vm::xoroshiro-next state))
    
    237
    +
    
    238
    +#-(or x86 sparc)
    
    239
    +(defun xoroshiro-gen (state)
    
    240
    +  (declare (type (simple-array double-float (2)) state)
    
    241
    +	   (optimize (speed 3) (safety 0)))
    
    242
    +  ;; Portable implementation of the xoroshiro128+ generator. See
    
    243
    +  ;; http://xoroshiro.di.unimi.it/xoroshiro128plus.c for the
    
    244
    +  ;; definitive definition.
    
    245
    +  ;;
    
    246
    +  ;; uint64_t s[2];
    
    247
    +  ;;
    
    248
    +  ;; static inline uint64_t rotl(const uint64_t x, int k) {
    
    249
    +  ;; 	return (x << k) | (x >> (64 - k));
    
    250
    +  ;; }
    
    251
    +  ;;
    
    252
    +  ;; uint64_t next(void) {
    
    253
    +  ;; 	const uint64_t s0 = s[0];
    
    254
    +  ;; 	uint64_t s1 = s[1];
    
    255
    +  ;; 	const uint64_t result = s0 + s1;
    
    256
    +  ;;
    
    257
    +  ;; 	s1 ^= s0;
    
    258
    +  ;; 	s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
    
    259
    +  ;; 	s[1] = rotl(s1, 36); // c
    
    260
    +  ;;
    
    261
    +  ;; 	return result;
    
    262
    +  ;; }
    
    263
    +  ;;
    
    264
    +  (flet ((rotl-55 (x1 x0)
    
    265
    +	   ;; Rotate [x1|x0] left 55 bits, returning the result as two
    
    266
    +	   ;; values.
    
    267
    +	   (declare (type (unsigned-byte 32) x0 x1)
    
    268
    +		    (optimize (speed 3) (safety 0)))
    
    269
    +	   ;; x << 55
    
    270
    +	   (let ((sl55-h (ldb (byte 32 0) (ash x0 (- 55 32))))
    
    271
    +		 (sl55-l 0))
    
    272
    +	     ;; x >> 9
    
    273
    +	     (let ((sr9-h (ash x1 -9))
    
    274
    +		   (sr9-l (ldb (byte 32 0)
    
    275
    +			       (logior (ash x0 -9)
    
    276
    +				       (ash x1 23)))))
    
    277
    +	       (values (logior sl55-h sr9-h)
    
    278
    +		       (logior sl55-l sr9-l)))))
    
    279
    +	 (rotl-36 (x1 x0)
    
    280
    +	   ;; Rotate [x1|x0] left 36 bits, returning the result as two
    
    281
    +	   ;; values.
    
    282
    +	   (declare (type (unsigned-byte 32) x0 x1)
    
    283
    +		    (optimize (speed 3) (safety 0)))
    
    284
    +	   ;; x << 36
    
    285
    +	   (let ((sl36-h (ldb (byte 32 0) (ash x0 4))))
    
    286
    +	     ;; x >> 28
    
    287
    +	     (let ((sr28-l (ldb (byte 32 0)
    
    288
    +				(logior (ash x0 -28)
    
    289
    +					(ash x1 4))))
    
    290
    +		   (sr28-h (ash x1 -28)))
    
    291
    +	       (values (logior sl36-h sr28-h)
    
    292
    +		       sr28-l))))
    
    293
    +	 (shl-14 (x1 x0)
    
    294
    +	   ;; Shift [x1|x0] left by 14 bits, returning the result as
    
    295
    +	   ;; two values.
    
    296
    +	   (declare (type (unsigned-byte 32) x1 x0)
    
    297
    +		    (optimize (speed 3) (safety 0)))
    
    298
    +	   (values (ldb (byte 32 0)
    
    299
    +			(logior (ash x1 14)
    
    300
    +				(ash x0 (- 14 32))))
    
    301
    +		   (ldb (byte 32 0)
    
    302
    +			(ash x0 14))))
    
    303
    +	 (make-double (hi lo)
    
    304
    +	   (kernel:make-double-float
    
    305
    +	    (if (< hi #x80000000)
    
    306
    +		hi
    
    307
    +		(- hi #x100000000))
    
    308
    +	    lo)))
    
    309
    +    (let ((s0-1 0)
    
    310
    +	  (s0-0 0)
    
    311
    +	  (s1-1 0)
    
    312
    +	  (s1-0 0))
    
    313
    +      (declare (type (unsigned-byte 32) s0-1 s0-0 s1-1 s1-0))
    
    314
    +      ;; Load the state to s0 and s1. s0-1 is the high 32-bit part and
    
    315
    +      ;; s0-0 is the low 32-bit part of the 64-bit value.  Similarly
    
    316
    +      ;; for s1.
    
    317
    +      (multiple-value-bind (x1 x0)
    
    318
    +	  (kernel:double-float-bits (aref state 0))
    
    319
    +	(setf s0-1 (ldb (byte 32 0) x1)
    
    320
    +	      s0-0 x0))
    
    321
    +      (multiple-value-bind (x1 x0)
    
    322
    +	  (kernel:double-float-bits (aref state 1))
    
    323
    +	(setf s1-1 (ldb (byte 32 0) x1)
    
    324
    +	      s1-0 x0))
    
    325
    +
    
    326
    +      ;; Compute the 64-bit random value: s0 + s1
    
    327
    +      (multiple-value-prog1
    
    328
    +	  (multiple-value-bind (sum-0 c)
    
    329
    +	      (bignum::%add-with-carry s0-0 s1-0 0)
    
    330
    +	    (values (bignum::%add-with-carry s0-1 s1-1 c)
    
    331
    +		    sum-0))
    
    332
    +	;; s1 ^= s0
    
    333
    +	(setf s1-1 (logxor s1-1 s0-1)
    
    334
    +	      s1-0 (logxor s1-0 s0-0))
    
    335
    +	;; s[0] = rotl(s0,55) ^ s1 ^ (s1 << 14)
    
    336
    +	(multiple-value-setq (s0-1 s0-0)
    
    337
    +	  (rotl-55 s0-1 s0-0))
    
    338
    +	(setf s0-1 (logxor s0-1 s1-1)
    
    339
    +	      s0-0 (logxor s0-0 s1-0))
    
    340
    +	(multiple-value-bind (s14-1 s14-0)
    
    341
    +	    (shl-14 s1-1 s1-0)
    
    342
    +	  (setf s0-1 (logxor s0-1 s14-1)
    
    343
    +		s0-0 (logxor s0-0 s14-0)))
    
    344
    +
    
    345
    +	(multiple-value-bind (r1 r0)
    
    346
    +	    (rotl-36 s1-1 s1-0)
    
    347
    +	  (setf (aref state 0) (make-double s0-1 s0-0)
    
    348
    +		(aref state 1) (make-double r1 r0)))))))
    
    349
    +
    
    350
    +;;; Size of the chunks returned by random-chunk.
    
    351
    +;;;
    
    352
    +(defconstant random-chunk-length 32)
    
    353
    +
    
    354
    +;;; random-chunk -- Internal
    
    355
    +;;;
    
    356
    +;;; This function generaters a 32bit integer between 0 and #xffffffff
    
    357
    +;;; inclusive.
    
    358
    +;;;
    
    359
    +(declaim (inline random-chunk))
    
    360
    +
    
    361
    +(defun random-chunk (rng-state)
    
    362
    +  (declare (type random-state rng-state)
    
    363
    +	   (optimize (speed 3) (safety 0)))
    
    364
    +  (let ((cached (random-state-cached-p rng-state)))
    
    365
    +    (cond (cached
    
    366
    +	   (setf (random-state-cached-p rng-state) nil)
    
    367
    +	   (random-state-rand rng-state))
    
    368
    +	  (t
    
    369
    +	   (let ((s (random-state-state rng-state)))
    
    370
    +	     (declare (type (simple-array double-float (2)) s))
    
    371
    +	     (multiple-value-bind (r1 r0)
    
    372
    +		 (xoroshiro-gen s)
    
    373
    +	       (setf (random-state-rand rng-state) r0)
    
    374
    +	       (setf (random-state-cached-p rng-state) t)
    
    375
    +	       r1))))))
    
    376
    +
    
    377
    +
    
    378
    +;;; %RANDOM-SINGLE-FLOAT, %RANDOM-DOUBLE-FLOAT  --  Interface
    
    379
    +;;;
    
    380
    +;;;    Handle the single or double float case of RANDOM.  We generate a float
    
    381
    +;;; between 0.0 and 1.0 by clobbering the significand of 1.0 with random bits,
    
    382
    +;;; then subtracting 1.0.  This hides the fact that we have a hidden bit.
    
    383
    +;;;
    
    384
    +(declaim (inline %random-single-float %random-double-float))
    
    385
    +(declaim (ftype (function ((single-float (0f0)) random-state)
    
    386
    +			  (single-float 0f0))
    
    387
    +		%random-single-float))
    
    388
    +;;;
    
    389
    +(defun %random-single-float (arg state)
    
    390
    +  (declare (type (single-float (0f0)) arg)
    
    391
    +	   (type random-state state))
    
    392
    +  (* arg
    
    393
    +     (- (make-single-float
    
    394
    +	 (dpb (ash (random-chunk state)
    
    395
    +		   (- vm:single-float-digits random-chunk-length))
    
    396
    +	      vm:single-float-significand-byte
    
    397
    +	      (single-float-bits 1.0)))
    
    398
    +	1.0)))
    
    399
    +;;;
    
    400
    +(declaim (ftype (function ((double-float (0d0)) random-state)
    
    401
    +			  (double-float 0d0))
    
    402
    +		%random-double-float))
    
    403
    +;;;
    
    404
    +;;; 53-bit version.
    
    405
    +;;;
    
    406
    +(defun %random-double-float (arg state)
    
    407
    +  (declare (type (double-float (0d0)) arg)
    
    408
    +	   (type random-state state))
    
    409
    +  ;; xoroshiro-gen produces 64-bit values.  Should we use that
    
    410
    +  ;; directly to get the random bits instead of two calls to
    
    411
    +  ;; RANDOM-CHUNK?
    
    412
    +  (* arg
    
    413
    +     (- (lisp::make-double-float
    
    414
    +	 (dpb (ash (random-chunk state)
    
    415
    +		   (- vm:double-float-digits random-chunk-length
    
    416
    +		      vm:word-bits))
    
    417
    +	      vm:double-float-significand-byte
    
    418
    +	      (lisp::double-float-high-bits 1d0))
    
    419
    +	 (random-chunk state))
    
    420
    +	1d0)))
    
    421
    +
    
    422
    +#+double-double
    
    423
    +(defun %random-double-double-float (arg state)
    
    424
    +  (declare (type (double-double-float (0w0)) arg)
    
    425
    +	   (type random-state state))
    
    426
    +  ;; Generate a 31-bit integer, scale it and sum them up
    
    427
    +  (let* ((r 0w0)
    
    428
    +	 (scale (scale-float 1d0 -31))
    
    429
    +	 (mult scale))
    
    430
    +    (declare (double-float mult)
    
    431
    +	     (type double-double-float r)
    
    432
    +	     (optimize (speed 3) (inhibit-warnings 3)))
    
    433
    +    (dotimes (k 4)
    
    434
    +      (setf r (+ r (* mult (ldb (byte 31 0) (random-chunk state)))))
    
    435
    +      (setf mult (* mult scale)))
    
    436
    +    (* arg r)))
    
    437
    +
    
    438
    +;;;; Random integers:
    
    439
    +
    
    440
    +;;; Amount we overlap chunks by when building a large integer to make up for
    
    441
    +;;; the loss of randomness in the low bits.
    
    442
    +;;;
    
    443
    +(defconstant random-integer-overlap 3)
    
    444
    +
    
    445
    +;;; Extra bits of randomness that we generate before taking the value MOD the
    
    446
    +;;; limit, to avoid loss of randomness near the limit.
    
    447
    +;;;
    
    448
    +(defconstant random-integer-extra-bits 10)
    
    449
    +
    
    450
    +;;; Largest fixnum we can compute from one chunk of bits.
    
    451
    +;;;
    
    452
    +(defconstant random-fixnum-max
    
    453
    +  (1- (ash 1 (- random-chunk-length random-integer-extra-bits))))
    
    454
    +
    
    455
    +
    
    456
    +;;; %RANDOM-INTEGER  --  Internal
    
    457
    +;;;
    
    458
    +(defun %random-integer (arg state)
    
    459
    +  (declare (type (integer 1) arg)
    
    460
    +	   (type random-state state))
    
    461
    +  (let ((shift (- random-chunk-length random-integer-overlap)))
    
    462
    +    (do ((bits (random-chunk state)
    
    463
    +	       (logxor (ash bits shift) (random-chunk state)))
    
    464
    +	 (count (+ (integer-length arg)
    
    465
    +		   (- random-integer-extra-bits shift))
    
    466
    +		(- count shift)))
    
    467
    +	((minusp count)
    
    468
    +	 (rem bits arg))
    
    469
    +      (declare (fixnum count)))))
    
    470
    +
    
    471
    +(defun random (arg &optional (state *random-state*))
    
    472
    +  _N"Generate a uniformly distributed pseudo-random number between zero
    
    473
    +  and Arg.  State, if supplied, is the random state to use."
    
    474
    +  (declare (inline %random-single-float %random-double-float))
    
    475
    +  (cond
    
    476
    +    ((typep arg '(integer 1 #x100000000))
    
    477
    +     ;; Let the compiler deftransform take care of this case.
    
    478
    +     (%random-integer arg state))
    
    479
    +    ((and (typep arg 'single-float) (> arg 0.0F0))
    
    480
    +     (%random-single-float arg state))
    
    481
    +    ((and (typep arg 'double-float) (> arg 0.0D0))
    
    482
    +     (%random-double-float arg state))
    
    483
    +    #+double-double
    
    484
    +    ((and (typep arg 'double-double-float) (> arg 0.0w0))
    
    485
    +     (%random-double-double-float arg state))
    
    486
    +    ((and (integerp arg) (> arg 0))
    
    487
    +     (%random-integer arg state))
    
    488
    +    (t
    
    489
    +     (error 'simple-type-error
    
    490
    +	    :expected-type '(or (integer 1) (float (0.0))) :datum arg
    
    491
    +	    :format-control _"Argument is not a positive integer or a positive float: ~S")
    
    492
    +	    :format-arguments (list arg)))))
    
    493
    +
    
    494
    +;; Jump function for the generator.  See the jump function in
    
    495
    +;; http://xoroshiro.di.unimi.it/xoroshiro128plus.c
    
    496
    +(defun random-state-jump (&optional (rng-state *random-state*))
    
    497
    +  _N"Jump the RNG-STATE.  This is equivalent to 2^64 calls to the
    
    498
    +  xoroshiro128+ generator.  It can be used to generate 2^64
    
    499
    +  non-overlapping subsequences for parallel computations."
    
    500
    +  (declare (type random-state rng-state))
    
    501
    +  (let ((state (random-state-state rng-state))
    
    502
    +	(s0-0 0)
    
    503
    +	(s0-1 0)
    
    504
    +	(s1-0 0)
    
    505
    +	(s1-1 0))
    
    506
    +    (declare (type (unsigned-byte 32) s0-0 s0-1 s1-0 s1-1)
    
    507
    +	     (optimize (speed 3) (safety 0)))
    
    508
    +    ;; The constants are #xbeac0467eba5facb and #xd86b048b86aa9922,
    
    509
    +    ;; and we process these numbers starting from the LSB.  We want ot
    
    510
    +    ;; process these in 32-bit chunks, so word-reverse the constants.
    
    511
    +    (dolist (jump '(#xeba5facb #xbeac0467 #x86aa9922 #xd86b048b))
    
    512
    +      (declare (type (unsigned-byte 32) jump))
    
    513
    +      (dotimes (b 32)
    
    514
    +	(declare (fixnum b))
    
    515
    +	(when (logbitp b jump)
    
    516
    +	  (multiple-value-bind (x1 x0)
    
    517
    +	      (kernel:double-float-bits (aref state 0))
    
    518
    +	    (setf s0-1 (logxor s0-1 (ldb (byte 32 0) x1))
    
    519
    +		  s0-0 (logxor s0-0 x0)))
    
    520
    +	  
    
    521
    +	  (multiple-value-bind (x1 x0)
    
    522
    +	      (kernel:double-float-bits (aref state 1))
    
    523
    +	    (setf s1-1 (logxor s1-1 (ldb (byte 32 0) x1))
    
    524
    +		  s1-0 (logxor s1-0 x0))))
    
    525
    +	(xoroshiro-gen state)))
    
    526
    +
    
    527
    +    (flet ((convert (x1 x0)
    
    528
    +	     (declare (type (unsigned-byte 32) x1 x0))
    
    529
    +	     (kernel:make-double-float
    
    530
    +	      (if (< x1 #x80000000) x1 (- x1 #x100000000))
    
    531
    +	      x0)))
    
    532
    +      (setf (aref state 0) (convert s0-1 s0-0))
    
    533
    +      (setf (aref state 1) (convert s1-1 s1-0)))
    
    534
    +      rng-state))

  • src/code/x86-vm.lisp
    ... ... @@ -413,6 +413,7 @@
    413 413
     ;;; transformed to a call to this routine allowing its use in byte
    
    414 414
     ;;; compiled code.
    
    415 415
     ;;;
    
    416
    +#+random-mt19937
    
    416 417
     (defun random-mt19937 (state)
    
    417 418
       (declare (type (simple-array (unsigned-byte 32) (627)) state))
    
    418 419
       (random-mt19937 state))
    

  • src/compiler/float-tran.lisp
    ... ... @@ -236,7 +236,7 @@
    236 236
       (frob %random-single-float single-float)
    
    237 237
       (frob %random-double-float double-float))
    
    238 238
     
    
    239
    -#-(or new-random random-mt19937)
    
    239
    +#-(or new-random random-mt19937 rand-xoroshiro)
    
    240 240
     (deftransform random ((num &optional state)
    
    241 241
     		      ((integer 1 #.random-fixnum-max) &optional *))
    
    242 242
       _N"use inline fixnum operations"
    
    ... ... @@ -259,7 +259,7 @@
    259 259
       '(values (truncate (%random-double-float (coerce num 'double-float)
    
    260 260
     		      (or state *random-state*)))))
    
    261 261
     
    
    262
    -#+random-mt19937
    
    262
    +#+(or random-mt19937)
    
    263 263
     (deftransform random ((num &optional state)
    
    264 264
     		      ((integer 1 #.(expt 2 32)) &optional *))
    
    265 265
       _N"use inline (unsigned-byte 32) operations"
    

  • src/compiler/sparc/arith.lisp
    ... ... @@ -2588,3 +2588,60 @@
    2588 2588
     		 (unsigned-byte 32))
    
    2589 2589
       "recode as shifts and adds"
    
    2590 2590
       (*-transformer y))
    
    2591
    +
    
    2592
    +(in-package "VM")
    
    2593
    +
    
    2594
    +#+random-xoroshiro
    
    2595
    +(progn
    
    2596
    +(defknown xoroshiro-next ((simple-array double-float (2)))
    
    2597
    +  (values (unsigned-byte 32) (unsigned-byte 32))
    
    2598
    +  (movable))
    
    2599
    +
    
    2600
    +(define-vop (xoroshiro-next)
    
    2601
    +  (:policy :fast-safe)
    
    2602
    +  (:translate xoroshiro-next)
    
    2603
    +  (:args (state :scs (descriptor-reg) :to (:result 3)))
    
    2604
    +  (:arg-types simple-array-double-float)
    
    2605
    +  (:results (r1 :scs (unsigned-reg))
    
    2606
    +	    (r0 :scs (unsigned-reg)))
    
    2607
    +  (:result-types unsigned-num unsigned-num)
    
    2608
    +  ;; Must be sure to use %o registers for temps because we want to use
    
    2609
    +  ;; 64-bit registers that will get preserved.
    
    2610
    +  (:temporary (:sc unsigned-reg :offset nl5-offset) s0)
    
    2611
    +  (:temporary (:sc unsigned-reg :offset nl4-offset) s1)
    
    2612
    +  (:temporary (:sc unsigned-reg :offset nl3-offset) t0)
    
    2613
    +  (:generator 10
    
    2614
    +    (let ((s0-offset (+ (* 0 double-float-bytes)
    
    2615
    +			(- (* vm:vector-data-offset vm:word-bytes)
    
    2616
    +			   vm:other-pointer-type)))
    
    2617
    +	  (s1-offset (+ (* 1 double-float-bytes)
    
    2618
    +			(- (* vm:vector-data-offset vm:word-bytes)
    
    2619
    +			   vm:other-pointer-type))))
    
    2620
    +      (inst ldx s0 state s0-offset)
    
    2621
    +      (inst ldx s1 state s1-offset)
    
    2622
    +      ;; result = s0 + s1, split into low 32-bits in r0 and high 32-bits
    
    2623
    +      ;; in r1
    
    2624
    +      (inst add r0 s0 s1)
    
    2625
    +      (inst srlx r1 r0 32)
    
    2626
    +
    
    2627
    +      ;; s1 = s1 ^ s0
    
    2628
    +      (inst xor s1 s0)
    
    2629
    +
    
    2630
    +      ;; s0 = rotl(s0,55) = s0 << 55 | s0 >> 9
    
    2631
    +      (inst sllx t0 s0 55)
    
    2632
    +      (inst srlx s0 s0 9)
    
    2633
    +      (inst or s0 t0)
    
    2634
    +
    
    2635
    +      (inst xor s0 s1)			; s0 = s0 ^ s1
    
    2636
    +      (inst sllx t0 s1 14)		; t0 = s1 << 14
    
    2637
    +      (inst xor s0 t0)			; s0 = s0 ^ t0
    
    2638
    +
    
    2639
    +      (inst stx s0 state s0-offset)
    
    2640
    +
    
    2641
    +      ;; s1 = rotl(s1, 36) = s1 << 36 | s1 >> 28, using t0 as temp
    
    2642
    +      (inst sllx t0 s1 36)
    
    2643
    +      (inst srlx s1 28)
    
    2644
    +      (inst or s1 t0)
    
    2645
    +
    
    2646
    +      (inst stx s1 state s1-offset))))
    
    2647
    +)

  • src/compiler/x86/arith.lisp
    ... ... @@ -1833,3 +1833,78 @@
    1833 1833
     		 (vm::ash-right-unsigned num (- shift)))))
    
    1834 1834
     	  (t
    
    1835 1835
     	   (give-up)))))
    
    1836
    +
    
    1837
    +(in-package "VM")
    
    1838
    +
    
    1839
    +#+random-xoroshiro
    
    1840
    +(progn
    
    1841
    +(defknown xoroshiro-next ((simple-array double-float (2)))
    
    1842
    +  (values (unsigned-byte 32) (unsigned-byte 32))
    
    1843
    +  (movable))
    
    1844
    +
    
    1845
    +(define-vop (xoroshiro-next)
    
    1846
    +  (:policy :fast-safe)
    
    1847
    +  (:translate xoroshiro-next)
    
    1848
    +  (:args (state :scs (descriptor-reg) :to (:result 3)))
    
    1849
    +  (:arg-types simple-array-double-float)
    
    1850
    +  (:results (r1 :scs (unsigned-reg))
    
    1851
    +	    (r0 :scs (unsigned-reg)))
    
    1852
    +  (:result-types unsigned-num unsigned-num)
    
    1853
    +  (:temporary (:sc double-reg) s0)
    
    1854
    +  (:temporary (:sc double-reg) s1)
    
    1855
    +  (:temporary (:sc double-reg) t0)
    
    1856
    +  (:generator 10
    
    1857
    +    ;; s0 = state[0]
    
    1858
    +    (inst movsd s0 (make-ea :dword :base state
    
    1859
    +			 :disp (- (+ (* vm:vector-data-offset
    
    1860
    +					vm:word-bytes)
    
    1861
    +				     (* 8 0))
    
    1862
    +				  vm:other-pointer-type)))
    
    1863
    +    ;; s1 = state[1]
    
    1864
    +    (inst movsd s1 (make-ea :dword :base state
    
    1865
    +			 :disp (- (+ (* vm:vector-data-offset
    
    1866
    +					vm:word-bytes)
    
    1867
    +				     (* 8 1))
    
    1868
    +				  vm:other-pointer-type)))
    
    1869
    +    ;; Compute result = s0 + s1
    
    1870
    +    (inst movapd t0 s0)
    
    1871
    +    (inst paddq t0 s1)
    
    1872
    +    ;; Save the 64-bit result as two 32-bit results
    
    1873
    +    (inst movd r0 t0)
    
    1874
    +    (inst psrlq t0 32)
    
    1875
    +    (inst movd r1 t0)
    
    1876
    +
    
    1877
    +    ;; s1 = s1 ^ s0
    
    1878
    +    (inst xorpd s1 s0)
    
    1879
    +
    
    1880
    +    ;; s0 = rotl(s0,55) = s0 << 55 | s0 >> 9
    
    1881
    +    (inst movapd t0 s0)
    
    1882
    +    (inst psllq s0 55)			; s0 = s0 << 55
    
    1883
    +    (inst psrlq t0 9)			; t0 = s0 >> 9
    
    1884
    +    (inst orpd s0 t0)			; s0 = rotl(s0, 55)
    
    1885
    +
    
    1886
    +    (inst movapd t0 s1)
    
    1887
    +    (inst xorpd s0 s1)			; s0 = s0 ^ s1
    
    1888
    +    (inst psllq t0 14)			; t0 = s1 << 14
    
    1889
    +    (inst xorpd s0 t0)			; s0 = s0 ^ t0
    
    1890
    +    (inst movsd (make-ea :dword :base state
    
    1891
    +			 :disp (- (+ (* vm:vector-data-offset
    
    1892
    +					vm:word-bytes)
    
    1893
    +				     (* 8 0))
    
    1894
    +				  vm:other-pointer-type))
    
    1895
    +	  s0)
    
    1896
    +
    
    1897
    +    ;; s1 = rotl(s1, 36) = s1 << 36 | s1 >> 28, using t0 as temp
    
    1898
    +    (inst movapd t0 s1)
    
    1899
    +    (inst psllq s1 36)
    
    1900
    +    (inst psrlq t0 28)
    
    1901
    +    (inst orpd s1 t0)
    
    1902
    +
    
    1903
    +    (inst movsd (make-ea :dword :base state
    
    1904
    +			 :disp (- (+ (* vm:vector-data-offset
    
    1905
    +					vm:word-bytes)
    
    1906
    +				     (* 8 1))
    
    1907
    +				  vm:other-pointer-type))
    
    1908
    +	  s1)))
    
    1909
    +)    
    
    1910
    +    
    \ No newline at end of file

  • src/compiler/x86/insts.lisp
    ... ... @@ -3195,7 +3195,11 @@
    3195 3195
       ;; dst[63:0] = dst[63:0]
    
    3196 3196
       ;; dst[127:64] = src[63:0]
    
    3197 3197
       (define-regular-sse-inst unpcklpd #x66 #x14 t)
    
    3198
    -  (define-regular-sse-inst unpcklps nil  #x14 t))
    
    3198
    +  (define-regular-sse-inst unpcklps nil  #x14 t)
    
    3199
    +
    
    3200
    +  ;; PADDQ 64-bit integer add
    
    3201
    +  (define-regular-sse-inst paddq #x66 #xd4)
    
    3202
    +  )
    
    3199 3203
     
    
    3200 3204
     (define-instruction popcnt (segment dst src)
    
    3201 3205
       (:printer ext-reg-reg/mem
    
    ... ... @@ -3539,4 +3543,3 @@
    3539 3543
       (packed-shift psllw #x71 #xf1 6)
    
    3540 3544
       (packed-shift psrad #x72 #xe2 4)
    
    3541 3545
       (packed-shift psraw #x71 #xe1 4))
    3542
    -

  • src/general-info/release-21d.md
    ... ... @@ -21,6 +21,11 @@ public domain.
    21 21
       * Feature enhancements
    
    22 22
         * Update to ASDF 3.3.1, fixing issues introduced in 3.3.0
    
    23 23
       * Changes
    
    24
    +    * x86 and sparc have replaced the MT19937 RNG with xoroshiro128+ RNG.
    
    25
    +      * The required state for this generator is just 4 32-bit words instead of the 600+ for MT19937.
    
    26
    +      * The generator is also faster than MT19937 (approximately 28% faster on x86 and 18% on sparc).
    
    27
    +      * The new function `KERNEL:RANDOM-STATE-JUMP` modifies the given state to jump 2^64 samples ahead, allowing 2^64 non-overlapping sequences.
    
    28
    +
    
    24 29
       * ANSI compliance fixes:
    
    25 30
       * Bug fixes:
    
    26 31
       * Gitlab tickets:
    

  • src/i18n/locale/cmucl.pot
    ... ... @@ -33,7 +33,7 @@ msgstr ""
    33 33
     #: src/code/intl.lisp src/compiler/globaldb.lisp src/code/defstruct.lisp
    
    34 34
     #: src/code/remote.lisp src/code/wire.lisp src/code/internet.lisp
    
    35 35
     #: src/code/loop.lisp src/code/run-program.lisp src/code/parse-time.lisp
    
    36
    -#: src/code/profile.lisp src/code/ntrace.lisp src/code/rand-mt19937.lisp
    
    36
    +#: src/code/profile.lisp src/code/ntrace.lisp src/code/rand-xoroshiro.lisp
    
    37 37
     #: src/code/debug.lisp src/code/debug-int.lisp src/code/debug-info.lisp
    
    38 38
     #: src/code/eval.lisp src/code/filesys.lisp src/code/pathname.lisp
    
    39 39
     #: src/code/fd-stream.lisp src/code/extfmts.lisp src/code/serve-event.lisp
    
    ... ... @@ -12105,13 +12105,13 @@ msgstr ""
    12105 12105
     msgid "Type \"yes\" for yes or \"no\" for no. "
    
    12106 12106
     msgstr ""
    
    12107 12107
     
    
    12108
    -#: src/code/rand-mt19937.lisp
    
    12108
    +#: src/code/rand-xoroshiro.lisp
    
    12109 12109
     msgid ""
    
    12110 12110
     "Generate an random state vector from the given SEED.  The seed can be\n"
    
    12111
    -"  either an integer or a vector of (unsigned-byte 32)"
    
    12111
    +"  either an integer or a vector of (unsigned-byte 64)"
    
    12112 12112
     msgstr ""
    
    12113 12113
     
    
    12114
    -#: src/code/rand-mt19937.lisp
    
    12114
    +#: src/code/rand-xoroshiro.lisp
    
    12115 12115
     msgid ""
    
    12116 12116
     "Make a random state object.  If STATE is not supplied, return a copy\n"
    
    12117 12117
     "  of the default random state.  If STATE is a random state, then return a\n"
    
    ... ... @@ -12119,20 +12119,27 @@ msgid ""
    12119 12119
     "  the universal time or /dev/urandom if available."
    
    12120 12120
     msgstr ""
    
    12121 12121
     
    
    12122
    -#: src/code/rand-mt19937.lisp
    
    12123
    -msgid "Argument is not a RANDOM-STATE, T or NIL: ~S"
    
    12122
    +#: src/code/rand-xoroshiro.lisp
    
    12123
    +msgid "Argument is not a RANDOM-STATE, T, or NIL: ~S"
    
    12124 12124
     msgstr ""
    
    12125 12125
     
    
    12126
    -#: src/code/rand-mt19937.lisp
    
    12126
    +#: src/code/rand-xoroshiro.lisp
    
    12127 12127
     msgid ""
    
    12128 12128
     "Generate a uniformly distributed pseudo-random number between zero\n"
    
    12129 12129
     "  and Arg.  State, if supplied, is the random state to use."
    
    12130 12130
     msgstr ""
    
    12131 12131
     
    
    12132
    -#: src/code/rand-mt19937.lisp
    
    12132
    +#: src/code/rand-xoroshiro.lisp
    
    12133 12133
     msgid "Argument is not a positive integer or a positive float: ~S"
    
    12134 12134
     msgstr ""
    
    12135 12135
     
    
    12136
    +#: src/code/rand-xoroshiro.lisp
    
    12137
    +msgid ""
    
    12138
    +"Jump the RNG-STATE.  This is equivalent to 2^64 calls to the\n"
    
    12139
    +"  xoroshiro128+ generator.  It can be used to generate 2^64\n"
    
    12140
    +"  non-overlapping subsequences for parallel computations."
    
    12141
    +msgstr ""
    
    12142
    +
    
    12136 12143
     #: src/code/ntrace.lisp
    
    12137 12144
     msgid ""
    
    12138 12145
     "This is bound to the returned values when evaluating :BREAK-AFTER and\n"
    
    ... ... @@ -18869,10 +18876,6 @@ msgid "use inline (unsigned-byte 32) operations"
    18869 18876
     msgstr ""
    
    18870 18877
     
    
    18871 18878
     #: src/compiler/float-tran.lisp
    
    18872
    -msgid "Shouldn't happen"
    
    18873
    -msgstr ""
    
    18874
    -
    
    18875
    -#: src/compiler/float-tran.lisp
    
    18876 18879
     msgid "Can't open-code float to rational comparison."
    
    18877 18880
     msgstr ""
    
    18878 18881
     
    

  • src/tools/worldbuild.lisp
    ... ... @@ -121,9 +121,13 @@
    121 121
         "target:code/scavhook"
    
    122 122
     
    
    123 123
         "target:code/save"
    
    124
    -    ,@(if (c:backend-featurep :random-mt19937)
    
    125
    -	  '("target:code/rand-mt19937")
    
    126
    -	  '("target:code/rand"))
    
    124
    +    ,@(cond ((c:backend-featurep :random-mt19937)
    
    125
    +	     '("target:code/rand-mt19937"))
    
    126
    +	    ((c:backend-featurep :random-xoroshiro)
    
    127
    +	     '("target:code/rand-xoroshiro"))
    
    128
    +	    (t
    
    129
    +	     '("target:code/rand")))
    
    130
    +    "target:code/rand-xoroshiro"
    
    127 131
         "target:code/alieneval"
    
    128 132
         "target:code/c-call"
    
    129 133
         "target:code/sap"
    

  • src/tools/worldcom.lisp
    ... ... @@ -268,9 +268,12 @@
    268 268
     (comf "target:code/debug" :byte-compile t)
    
    269 269
     
    
    270 270
     (comf "target:code/query" :byte-compile *byte-compile*)
    
    271
    -(if (c:backend-featurep :random-mt19937)
    
    272
    -    (comf "target:code/rand-mt19937")
    
    273
    -    (comf "target:code/rand"))
    
    271
    +(cond ((c:backend-featurep :random-mt19937)
    
    272
    +       (comf "target:code/rand-mt19937"))
    
    273
    +      ((c:backend-featurep :random-xoroshiro)
    
    274
    +       (comf "target:code/rand-xoroshiro"))
    
    275
    +      (t
    
    276
    +       (comf "target:code/rand")))
    
    274 277
     (comf "target:code/ntrace" :byte-compile *byte-compile*)
    
    275 278
     (comf "target:code/profile")
    
    276 279
     (comf "target:code/sort")
    

  • src/tools/worldload.lisp
    ... ... @@ -96,8 +96,13 @@
    96 96
     (maybe-byte-load "code:time")
    
    97 97
     (maybe-byte-load "code:tty-inspect")
    
    98 98
     (maybe-byte-load "code:describe")
    
    99
    -#+random-mt19937 (maybe-byte-load "code:rand-mt19937")
    
    100
    -#-random-mt19937 (maybe-byte-load "code:rand")
    
    99
    +#+random-mt19937
    
    100
    +(maybe-byte-load "code:rand-mt19937")
    
    101
    +#+random-xoroshiro
    
    102
    +(maybe-byte-load "code:rand-xoroshiro")
    
    103
    +#-(or random-mt19937 random-xoroshiro)
    
    104
    +(maybe-byte-load "code:rand")
    
    105
    +(maybe-byte-load "code:rand-xoroshiro")
    
    101 106
     (maybe-byte-load "target:pcl/walk")
    
    102 107
     (maybe-byte-load "code:fwrappers")
    
    103 108
     (maybe-byte-load "code:ntrace")
    

  • tests/rng.lisp
    1
    +;; Tests for RNG
    
    2
    +
    
    3
    +(defpackage :rng-tests
    
    4
    +  (:use :cl :lisp-unit))
    
    5
    +
    
    6
    +(in-package "RNG-TESTS")
    
    7
    +
    
    8
    +(defun 64-bit-rng-state (rng)
    
    9
    +  (let ((state (kernel::random-state-state rng)))
    
    10
    +    (flet ((convert (x)
    
    11
    +	     (multiple-value-bind (hi lo)
    
    12
    +		 (kernel:double-float-bits x)
    
    13
    +	       (logior (ash (ldb (byte 32 0) hi) 32)
    
    14
    +		       lo))))
    
    15
    +      (values (convert (aref state 0)) (convert (aref state 1))))))
    
    16
    +
    
    17
    +(defun 64-bit-value (rng)
    
    18
    +  (logior (ash (kernel::random-chunk rng) 32)
    
    19
    +	  (kernel::random-chunk rng)))
    
    20
    +
    
    21
    +(defvar *test-state*)
    
    22
    +  
    
    23
    +#+random-xoroshiro
    
    24
    +(define-test rng.initial-state
    
    25
    +  (setf *test-state*
    
    26
    +	(kernel::make-random-object :state (kernel::init-random-state #x12345678)
    
    27
    +				    :rand 0
    
    28
    +				    :cached-p nil))
    
    29
    +  (multiple-value-bind (s0 s1)
    
    30
    +      (64-bit-rng-state *test-state*)
    
    31
    +    (assert-equal #x38f1dc39d1906b6f s0)
    
    32
    +    (assert-equal #xdfe4142236dd9517 s1)
    
    33
    +    (assert-equal 0 (kernel::random-state-rand *test-state*))
    
    34
    +    (assert-equal nil (kernel::random-state-cached-p *test-state*))))
    
    35
    +
    
    36
    +
    
    37
    +#+random-xoroshiro
    
    38
    +(define-test rng.values-test
    
    39
    +  (assert-equal (list #x38f1dc39d1906b6f #xdfe4142236dd9517)
    
    40
    +		(multiple-value-list (64-bit-rng-state *test-state*)))
    
    41
    +  (assert-equal 0 (kernel::random-state-rand *test-state*))
    
    42
    +  (assert-equal nil (kernel::random-state-cached-p *test-state*))
    
    43
    +
    
    44
    +  (dolist (item '((#x18d5f05c086e0086 (#x228f4926843b364d #x74dfe78e715c81be))
    
    45
    +		  (#x976f30b4f597b80b (#x5b6bd4558bd96a68 #x567b7f35650aea8f))
    
    46
    +		  (#xb1e7538af0e454f7 (#x13e5253e242fac52 #xed380e70d10ab60e))
    
    47
    +		  (#x011d33aef53a6260 (#x9d0764952ca00d8a #x5251a5cfedd2b4ef))
    
    48
    +		  (#xef590a651a72c279 (#xba4ef2b425bda963 #x172b965cf56c15ac))
    
    49
    +		  (#xd17a89111b29bf0f (#x458277a5e5f0a21b #xd1bccfad6564e8d))
    
    50
    +		  (#x529e44a0bc46f0a8 (#x2becb68d5a7194c7 #x3a6ec964899bb5f3))
    
    51
    +		  (#x665b7ff1e40d4aba (#xededfd481d0a19fe #x3ea213411827fe9d))
    
    52
    +		  (#x2c9010893532189b (#xd7bb59bcd8fba26f #x52de763d34fee090))
    
    53
    +		  (#x2a99cffa0dfa82ff (#xf96e892c62d6ff2e #xc0542ff85652f81e))))
    
    54
    +    (destructuring-bind (value state)
    
    55
    +	item
    
    56
    +      (assert-equal value (64-bit-value *test-state*))
    
    57
    +      (assert-equal state (multiple-value-list (64-bit-rng-state *test-state*))))))
    
    58
    +
    
    59
    +(define-test rng.jump
    
    60
    +  (setf *test-state*
    
    61
    +	(kernel::make-random-object :state (kernel::init-random-state #x12345678)
    
    62
    +				    :rand 0
    
    63
    +				    :cached-p nil))
    
    64
    +  (dolist (result '((#x291ddf8e6f6a7b67 #x1f9018a12f9e031f)
    
    65
    +		    (#x88a7aa12158558d0 #xe264d785ab1472d9)
    
    66
    +		    (#x207e16f73c51e7ba #x999c8a0a9a8d87c0)
    
    67
    +		    (#x28f8959d3bcf5ff1 #x38091e563ab6eb98)))
    
    68
    +    (kernel:random-state-jump *test-state*)
    
    69
    +    (assert-equal result (multiple-value-list
    
    70
    +			  (64-bit-rng-state *test-state*)))))