nseel-cfunc.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. Expression Evaluator Library (NS-EEL) v2
  3. Copyright (C) 2004-2013 Cockos Incorporated
  4. Copyright (C) 1999-2003 Nullsoft, Inc.
  5. nseel-cfunc.c: assembly/C implementation of operator/function templates
  6. This file should be ideally compiled with optimizations towards "minimize size"
  7. This software is provided 'as-is', without any express or implied
  8. warranty. In no event will the authors be held liable for any damages
  9. arising from the use of this software.
  10. Permission is granted to anyone to use this software for any purpose,
  11. including commercial applications, and to alter it and redistribute it
  12. freely, subject to the following restrictions:
  13. 1. The origin of this software must not be misrepresented; you must not
  14. claim that you wrote the original software. If you use this software
  15. in a product, an acknowledgment in the product documentation would be
  16. appreciated but is not required.
  17. 2. Altered source versions must be plainly marked as such, and must not be
  18. misrepresented as being the original software.
  19. 3. This notice may not be removed or altered from any source distribution.
  20. */
  21. #include "ns-eel-int.h"
  22. #include <math.h>
  23. #include <stdio.h>
  24. // these are used by our assembly code
  25. #define N 624
  26. #define M 397
  27. #define MATRIX_A 0x9908b0dfUL /* constant vector a */
  28. #define UPPER_MASK 0x80000000UL /* most significant w-r bits */
  29. #define LOWER_MASK 0x7fffffffUL /* least significant r bits */
  30. static unsigned int genrand_int32(void)
  31. {
  32. unsigned int y;
  33. static unsigned int mag01[2]={0x0UL, MATRIX_A};
  34. /* mag01[x] = x * MATRIX_A for x=0,1 */
  35. static unsigned int mt[N]; /* the array for the state vector */
  36. static int mti; /* mti==N+1 means mt[N] is not initialized */
  37. if (!mti)
  38. {
  39. unsigned int s=0x4141f00d;
  40. mt[0]= s & 0xffffffffUL;
  41. for (mti=1; mti<N; mti++)
  42. {
  43. mt[mti] =
  44. (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
  45. /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
  46. /* In the previous versions, MSBs of the seed affect */
  47. /* only MSBs of the array mt[]. */
  48. /* 2002/01/09 modified by Makoto Matsumoto */
  49. mt[mti] &= 0xffffffffUL;
  50. /* for >32 bit machines */
  51. }
  52. }
  53. if (mti >= N) { /* generate N words at one time */
  54. int kk;
  55. for (kk=0;kk<N-M;kk++) {
  56. y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
  57. mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
  58. }
  59. for (;kk<N-1;kk++) {
  60. y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
  61. mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
  62. }
  63. y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
  64. mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
  65. mti = 0;
  66. }
  67. y = mt[mti++];
  68. /* Tempering */
  69. y ^= (y >> 11);
  70. y ^= (y << 7) & 0x9d2c5680UL;
  71. y ^= (y << 15) & 0xefc60000UL;
  72. y ^= (y >> 18);
  73. return y;
  74. }
  75. //---------------------------------------------------------------------------------------------------------------
  76. EEL_F NSEEL_CGEN_CALL nseel_int_rand(EEL_F f)
  77. {
  78. EEL_F x=floor(f);
  79. if (x < 1.0) x=1.0;
  80. #ifdef NSEEL_EEL1_COMPAT_MODE
  81. return (EEL_F)(genrand_int32()%(int)x);
  82. #else
  83. return (EEL_F) (genrand_int32()*(1.0/(double)0xFFFFFFFF)*x);
  84. #endif
  85. }
  86. //---------------------------------------------------------------------------------------------------------------
  87. #ifndef EEL_TARGET_PORTABLE
  88. #ifdef __ppc__
  89. #include "asm-nseel-ppc-gcc.c"
  90. #elif defined(__aarch64__)
  91. #include "asm-nseel-aarch64-gcc.c"
  92. #elif defined(__arm__)
  93. #include "asm-nseel-arm-gcc.c"
  94. #elif defined (_M_ARM) && _M_ARM == 7
  95. // vc on ARM, tbd
  96. #else
  97. #ifdef _MSC_VER
  98. #ifdef _WIN64
  99. //nasm
  100. #else
  101. #include "asm-nseel-x86-msvc.c"
  102. void eel_setfp_round()
  103. {
  104. short oldsw;
  105. __asm
  106. {
  107. fnstcw [oldsw]
  108. mov ax, [oldsw]
  109. and ax, 0xF3FF // round to nearest
  110. mov [oldsw], ax
  111. fldcw [oldsw]
  112. }
  113. }
  114. void eel_setfp_trunc()
  115. {
  116. short oldsw;
  117. __asm
  118. {
  119. fnstcw [oldsw]
  120. mov ax, [oldsw]
  121. or ax, 0xC00 // truncate
  122. mov [oldsw], ax
  123. fldcw [oldsw]
  124. }
  125. }
  126. #endif
  127. #elif !defined(__LP64__)
  128. #define FUNCTION_MARKER "\n.byte 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90\n"
  129. #include "asm-nseel-x86-gcc.c"
  130. void eel_setfp_round()
  131. {
  132. __asm__(
  133. "subl $16, %esp\n"
  134. "fnstcw (%esp)\n"
  135. "mov (%esp), %ax\n"
  136. "and $0xF3FF, %ax\n" // set round to nearest
  137. "mov %ax, 4(%esp)\n"
  138. "fldcw 4(%esp)\n"
  139. "addl $16, %esp\n"
  140. );
  141. }
  142. void eel_setfp_trunc()
  143. {
  144. __asm__(
  145. "subl $16, %esp\n"
  146. "fnstcw (%esp)\n"
  147. "mov (%esp), %ax\n"
  148. "or $0xC00, %ax\n" // set to truncate
  149. "mov %ax, 4(%esp)\n"
  150. "fldcw 4(%esp)\n"
  151. "addl $16, %esp\n"
  152. );
  153. }
  154. #endif
  155. #endif
  156. #endif