Browse Source

nasmtests: better rng

Fabian 7 months ago
parent
commit
677e660558
3 changed files with 118 additions and 35 deletions
  1. 14 14
      tests/nasm/create_tests.js
  2. 0 21
      tests/nasm/prand.js
  3. 104 0
      tests/nasm/rand.js

+ 14 - 14
tests/nasm/create_tests.js

@@ -9,7 +9,7 @@ const FLAGS_IGNORE = 0xFFFF3200;
 const assert = require("assert").strict;
 const fs = require("fs");
 const encodings = require("../../gen/x86_table.js");
-const Prand = require("./prand.js");
+const Rand = require("./rand.js");
 
 generate_tests();
 
@@ -184,7 +184,7 @@ function create_nasm(op, config, nth_test)
         }
     }
 
-    const op_rand = new Prand(op.opcode + nth_test * 0x10000);
+    const rng = new Rand(op.opcode + nth_test * 0x10000);
 
     const size = (op.os || op.opcode % 2 === 1) ? config.size : 8;
     const is_modrm = op.e || op.fixed_g !== undefined;
@@ -193,7 +193,7 @@ function create_nasm(op, config, nth_test)
 
     for(let reg of ["eax", "ecx", "edx", "ebx", "ebp", "esi", "edi"])
     {
-        let rand = op_rand.next();
+        let rand = rng.int32();
         codes.push("mov " + reg + ", " + rand);
     }
 
@@ -202,8 +202,8 @@ function create_nasm(op, config, nth_test)
         codes.push("sub esp, 8");
         for(let i = 0; i < 8; i++)
         {
-            codes.push("mov dword [esp], " + op_rand.next());
-            codes.push("mov dword [esp + 4], " + op_rand.next());
+            codes.push("mov dword [esp], " + rng.int32());
+            codes.push("mov dword [esp + 4], " + rng.int32());
             codes.push("movq mm" + i + ", [esp]");
         }
         codes.push("add esp, 8");
@@ -215,8 +215,8 @@ function create_nasm(op, config, nth_test)
 
         for(let i = 0; i < 8; i++)
         {
-            codes.push("mov dword [esp], " + op_rand.next());
-            codes.push("mov dword [esp + 4], " + op_rand.next());
+            codes.push("mov dword [esp], " + rng.int32());
+            codes.push("mov dword [esp + 4], " + rng.int32());
             codes.push("fld qword [esp]");
         }
 
@@ -233,10 +233,10 @@ function create_nasm(op, config, nth_test)
         codes.push("sub esp, 16");
         for(let i = 0; i < 8; i++)
         {
-            codes.push("mov dword [esp], " + op_rand.next());
-            codes.push("mov dword [esp + 4], " + op_rand.next());
-            codes.push("mov dword [esp + 8], " + op_rand.next());
-            codes.push("mov dword [esp + 12], " + op_rand.next());
+            codes.push("mov dword [esp], " + rng.int32());
+            codes.push("mov dword [esp + 4], " + rng.int32());
+            codes.push("mov dword [esp + 8], " + rng.int32());
+            codes.push("mov dword [esp + 12], " + rng.int32());
             codes.push("movdqu xmm" + i + ", [esp]");
         }
         codes.push("add esp, 16");
@@ -247,16 +247,16 @@ function create_nasm(op, config, nth_test)
         for(let i = 0; i < 8; i++)
         {
             codes.push("sub esp, 4");
-            codes.push("mov dword [esp], " + op_rand.next());
+            codes.push("mov dword [esp], " + rng.int32());
         }
     }
 
-    codes.push("push dword " + (op_rand.next() & ~(1 << 8 | 1 << 9)));
+    codes.push("push dword " + (rng.int32() & ~(1 << 8 | 1 << 9)));
     codes.push("popf");
 
     if(true)
     {
-        // generate random flags using arithmatic instruction
+        // generate random flags using arithmetic instruction
         // not well-distributed, but can trigger bugs in lazy flag calculation
         if(true)
         {

+ 0 - 21
tests/nasm/prand.js

@@ -1,21 +0,0 @@
-"use strict";
-const assert = require("assert");
-
-/**
- * Creates a pseudo-random value generator. The seed must be an integer.
- */
-function Random(seed) {
-    assert.equal(typeof seed, "number");
-    this._seed = seed % 2147483647;
-    if (this._seed <= 0) this._seed += 2147483646;
-}
-
-/**
- * Returns a 32-bit pseudo-random value.
- */
-Random.prototype.next = function () {
-    this._seed = (this._seed * 16807) & 0xffffffff;
-    return (this._seed - 1) | 0;
-};
-
-module.exports = Random;

+ 104 - 0
tests/nasm/rand.js

@@ -0,0 +1,104 @@
+"use strict";
+const assert = require("assert");
+
+// From http://baagoe.com/en/RandomMusings/javascript/
+// Johannes Baagøe <baagoe@baagoe.com>, 2010
+function Mash() {
+  var n = 0xefc8249d;
+
+  var mash = function(data) {
+    data = data.toString();
+    for (var i = 0; i < data.length; i++) {
+      n += data.charCodeAt(i);
+      var h = 0.02519603282416938 * n;
+      n = h >>> 0;
+      h -= n;
+      h *= n;
+      n = h >>> 0;
+      h -= n;
+      n += h * 0x100000000; // 2^32
+    }
+    return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
+  };
+
+  return mash;
+}
+
+// From http://baagoe.com/en/RandomMusings/javascript/
+function KISS07() {
+  return (function(args) {
+    // George Marsaglia, 2007-06-23
+    //http://groups.google.com/group/comp.lang.fortran/msg/6edb8ad6ec5421a5
+    var x = 123456789;
+    var y = 362436069;
+    var z =  21288629;
+    var w =  14921776;
+    var c = 0;
+
+    if (args.length == 0) {
+      args = [+new Date];
+    }
+    var mash = Mash();
+    for (var i = 0; i < args.length; i++) {
+      x ^= mash(args[i]) * 0x100000000; // 2^32
+      y ^= mash(args[i]) * 0x100000000;
+      z ^= mash(args[i]) * 0x100000000;
+      w ^= mash(args[i]) * 0x100000000;
+    }
+    if (y === 0) {
+      y = 1;
+    }
+    c ^= z >>> 31;
+    z &= 0x7fffffff;
+    if ((z % 7559) === 0) {
+      z++;
+    }
+    w &= 0x7fffffff;
+    if ((w % 7559) === 0) {
+      w++;
+    }
+    mash = null;
+
+    var int32 = function() {
+      var t;
+
+      x += 545925293;
+      x >>>= 0;
+
+      y ^= y << 13;
+      y ^= y >>> 17;
+      y ^= y << 5;
+
+      t = z + w + c;
+      z = w;
+      c = t >>> 31;
+      w = t & 0x7fffffff;
+
+      return x + y + w | 0;
+    };
+    var uint32 = function() {
+      var t;
+
+      x += 545925293;
+      x >>>= 0;
+
+      y ^= y << 13;
+      y ^= y >>> 17;
+      y ^= y << 5;
+
+      t = z + w + c;
+      z = w;
+      c = t >>> 31;
+      w = t & 0x7fffffff;
+
+      return x + y + w >>> 0;
+    };
+
+    return {
+        int32,
+        uint32,
+    };
+  } (Array.prototype.slice.call(arguments)));
+}
+
+module.exports = KISS07;