Routines.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //
  2. //
  3. // Faster versions of common routines
  4. //
  5. //
  6. //---------------------------------------------------------------------------//
  7. // Copyright (C) Microsoft Corporation. All rights reserved. //
  8. //===========================================================================//
  9. #include <gameos.hpp>
  10. #include <stdlib.h>
  11. void memclear(void *Dest,int Length);
  12. void memfill(void *Dest,int Length);
  13. extern enum { CPU_UNKNOWN, CPU_PENTIUM, CPU_MMX, CPU_KATMAI } Processor;
  14. static _int64 fillnum=-1;
  15. //
  16. // Instead of using memset(x,0,x) - use this function
  17. //
  18. void memclear(void *Dest,int Len)
  19. {
  20. _asm{
  21. mov edi,Dest
  22. mov ecx,Len
  23. cmp Processor,CPU_MMX
  24. jnz mem1
  25. //memclear_mmx:
  26. mov ebx,ecx ; 8 byte align edi when possible
  27. sub ecx,edi
  28. xor eax,eax
  29. sub ecx,ebx
  30. and ecx,7
  31. sub ebx,ecx
  32. jle doalign0
  33. test ecx,ecx
  34. jz mmx0a
  35. mmx0: mov byte ptr [edi],al
  36. inc edi
  37. dec ecx
  38. jnz mmx0
  39. mmx0a: mov ecx,ebx
  40. and ebx,7
  41. shr ecx,3
  42. jz doalign0
  43. pxor mm0,mm0
  44. mmx1: movq [edi],mm0
  45. add edi,8
  46. dec ecx
  47. jnz mmx1
  48. doalign0:
  49. add ecx,ebx
  50. test ecx,ecx
  51. jz mmx0d
  52. mmx0c: mov byte ptr [edi],al
  53. inc edi
  54. dec ecx
  55. jnz mmx0c
  56. mmx0d: emms
  57. jmp done
  58. mem1:
  59. mov ebx,ecx ; DWORD align edi when possible
  60. sub ecx,edi
  61. xor eax,eax
  62. sub ecx,ebx
  63. and ecx,3
  64. sub ebx,ecx
  65. jle doalign1
  66. rep stosb
  67. mov ecx,ebx
  68. and ebx,3
  69. shr ecx,2
  70. rep stosd
  71. doalign1:
  72. add ecx,ebx
  73. rep stosb
  74. done:
  75. }
  76. };
  77. //
  78. // Instead of using memset(x,0xff,x) - use this function
  79. //
  80. void memfill(void *Dest,int Len)
  81. {
  82. _asm{
  83. mov edi,Dest
  84. mov ecx,Len
  85. cmp Processor,CPU_MMX
  86. jnz memf1
  87. //memfill_mmx:
  88. mov ebx,ecx ; 8 byte align edi when possible
  89. sub ecx,edi
  90. mov eax,-1
  91. sub ecx,ebx
  92. and ecx,7
  93. sub ebx,ecx
  94. jle doalign0
  95. test ecx,ecx
  96. jz mmx0fa
  97. mmx0f: mov byte ptr [edi],al
  98. inc edi
  99. dec ecx
  100. jnz mmx0f
  101. mmx0fa: mov ecx,ebx
  102. and ebx,7
  103. shr ecx,3
  104. jz doalign0
  105. movq mm0,fillnum
  106. mmx1: movq [edi],mm0
  107. add edi,8
  108. dec ecx
  109. jnz mmx1
  110. doalign0:
  111. add ecx,ebx
  112. test ecx,ecx
  113. jz mmx0fb
  114. mmx1f: mov byte ptr [edi],al
  115. inc edi
  116. dec ecx
  117. jnz mmx1f
  118. mmx0fb:
  119. emms
  120. jmp done
  121. memf1:
  122. mov ebx,ecx ; DWORD align edi when possible
  123. sub ecx,edi
  124. mov eax,-1
  125. sub ecx,ebx
  126. and ecx,3
  127. sub ebx,ecx
  128. jle doalign1
  129. rep stosb
  130. mov ecx,ebx
  131. and ebx,3
  132. shr ecx,2
  133. rep stosd
  134. doalign1:
  135. add ecx,ebx
  136. rep stosb
  137. done:
  138. }
  139. };
  140. //---------------------------------------------------------------------------
  141. // Random Number Functions
  142. long RandomNumber (long range)
  143. {
  144. gosASSERT( RAND_MAX==(1<<15)-1 ); // This is always TRUE in VC
  145. return( (gos_rand()*range)>>15 ); // Used to used mod (%) - which costs 40+ cycles (AG)
  146. }
  147. //---------------------------------------------------------------------------
  148. bool RollDice (long percent)
  149. {
  150. return (((rand()*100)>>15) < percent); // Optimized the % out
  151. }