RandomRDRand.st
changeset 4925 3b6b894d2664
parent 4887 8c49f1189e7c
child 4926 0d707ba99ea5
equal deleted inserted replaced
4924:b171682381a1 4925:3b6b894d2664
    90 !RandomRDRand class methodsFor:'queries'!
    90 !RandomRDRand class methodsFor:'queries'!
    91 
    91 
    92 isSupported
    92 isSupported
    93     "true if this architecture supports hardware random numbers"
    93     "true if this architecture supports hardware random numbers"
    94 
    94 
    95     ^ OperatingSystem getCPUType = 'x86_64'
    95     ^ (OperatingSystem getSystemInfo at:#extendedInstructions ifAbsent:#())
    96 	and:[ (OperatingSystem getSystemInfo at:#extendedInstructions ifAbsent:#())
    96               includes:#rdmd
    97 	      includes:#aes ]
       
    98 
    97 
    99     "
    98     "
   100      self isSupported
    99      self isSupported
   101     "
   100     "
       
   101 
       
   102     "Modified: / 28-03-2019 / 10:59:32 / Stefan Vogel"
   102 ! !
   103 ! !
   103 
   104 
   104 !RandomRDRand methodsFor:'initialization'!
   105 !RandomRDRand methodsFor:'initialization'!
   105 
       
   106 initialize
       
   107 !
       
   108 
   106 
   109 seed:seed
   107 seed:seed
   110     "/ ignored
   108     "/ ignored
   111 ! !
   109 ! !
   112 
   110 
   131     int count = 50;
   129     int count = 50;
   132 
   130 
   133     do {
   131     do {
   134 #ifdef USE_DRAND64
   132 #ifdef USE_DRAND64
   135         cf = _rdrand64_step(&r);
   133         cf = _rdrand64_step(&r);
   136 #else
   134 #elif defined(USE_DRAND32)
   137 # ifdef USE_DRAND32
       
   138         cf = _rdrand32_step(&r);
   135         cf = _rdrand32_step(&r);
   139 # else
   136 #elif defined(__i386__) && defined(__GNUC__) && (__GNUC__ >= 2)
   140 #  if defined(__x86__) && defined(__GNUC__) && (__GNUC__ >= 2)
       
   141         // Encoding of rdrand %eax
   137         // Encoding of rdrand %eax
   142         asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1"
   138         asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1"
   143             : "=a" (r), "=r" (cf)
   139             : "=a" (r), "=r" (cf)
   144             : "0" (r), "1" (cf)
   140             : "0" (r), "1" (cf)
   145             : "cc");
   141             : "cc");
   146 
   142 
   147 #  else
   143 #elif defined(__x86_64__) && defined(__GNUC__) && (__GNUC__ >= 2)
   148 #   if defined(__x86_64__) && defined(__GNUC__) && (__GNUC__ >= 2)
       
   149         // Encoding of rdrand %rax
   144         // Encoding of rdrand %rax
   150         asm(".byte 0x48, 0x0F, 0xC7, 0xF0; adcl $0,%1"
   145         asm(".byte 0x48, 0x0F, 0xC7, 0xF0; adcl $0,%1"
   151             : "=a" (r), "=r" (cf)
   146             : "=a" (r), "=r" (cf)
   152             : "0" (r), "1" (cf)
   147             : "0" (r), "1" (cf)
   153             : "cc");
   148             : "cc");
   154 
   149 
   155 #   else
   150 #else
   156         goto unsupported;
   151         goto unsupported;
   157 #   endif
       
   158 #  endif
       
   159 # endif
       
   160 #endif
   152 #endif
   161     } while ((cf != 0) && (--count > 0));
   153     } while ((cf != 0) && (--count > 0));
   162     if (cf == 0) {
   154     if (cf == 0) {
   163         RETURN (__MKUINT(r));
   155         RETURN (__MKUINT(r));
   164     }
   156     }
   171     self primitiveFailed:'unsupported on this architecture'
   163     self primitiveFailed:'unsupported on this architecture'
   172 
   164 
   173     "
   165     "
   174      self new nextInteger
   166      self new nextInteger
   175     "
   167     "
       
   168 
       
   169     "Modified: / 28-03-2019 / 10:46:29 / Stefan Vogel"
   176 ! !
   170 ! !
   177 
   171 
   178 !RandomRDRand class methodsFor:'documentation'!
   172 !RandomRDRand class methodsFor:'documentation'!
   179 
   173 
   180 version
   174 version