Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. shr1632a.c
  5. Abstract:
  6. Instruction fragments with common (shared) WORD, and DWORD flavors
  7. (but not BYTE).
  8. Compiled twice per flavor, once with UNALIGNED and once with ALIGNED
  9. pointers.
  10. Author:
  11. 05-Nov-1995 BarryBo
  12. Revision History:
  13. --*/
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <windows.h>
  18. #include <stdio.h>
  19. #include "shr1632a.h"
  20. FRAGCOMMON2(BtMemFrag)
  21. {
  22. UTYPE bit = 1<<(op2&LMB);
  23. op2 /= LMB+1; // compute offset of the correct WORD/DWORD
  24. SET_CFLAG_IND(GET_VAL(pop1+op2) & bit);
  25. }
  26. FRAGCOMMON2(BtsMemFrag)
  27. {
  28. DWORD NewCFlag;
  29. UTYPE bit = 1<<(op2&LMB);
  30. UTYPE op1;
  31. op2 /= LMB+1; // compute offset of the correct WORD/DWORD
  32. pop1 += op2;
  33. op1 = GET_VAL(pop1);
  34. NewCFlag = op1 & bit;
  35. // Intel docs indicate that we can safely overwrite all 2/4 bytes
  36. // when writing the value back out. (pg. 26/43)
  37. PUT_VAL(pop1, (op1|bit));
  38. SET_CFLAG_IND(NewCFlag);
  39. }
  40. FRAGCOMMON2(BtcMemFrag)
  41. {
  42. DWORD NewCFlag;
  43. UTYPE bit = 1<<(op2&LMB);
  44. UTYPE op1;
  45. op2 /= LMB+1; // compute offset of the correct WORD/DWORD
  46. pop1 += op2;
  47. op1 = GET_VAL(pop1);
  48. NewCFlag = op1 & bit;
  49. // Intel docs indicate that we can safely overwrite all 2/4 bytes
  50. // when writing the value back out. (pg. 26/43)
  51. PUT_VAL(pop1, op1 ^ bit);
  52. SET_CFLAG_IND(NewCFlag);
  53. }
  54. FRAGCOMMON2(BtrMemFrag)
  55. {
  56. DWORD NewCFlag;
  57. UTYPE bit = 1<<(op2&LMB);
  58. UTYPE op1;
  59. op2 /= LMB+1; // compute offset of the correct WORD/DWORD
  60. pop1 += op2;
  61. op1 = GET_VAL(pop1);
  62. NewCFlag = op1 & bit;
  63. // Intel docs indicate that we can safely overwrite all 2/4 bytes
  64. // when writing the value back out. (pg. 26/43)
  65. PUT_VAL(pop1, (op1&(~bit)));
  66. SET_CFLAG_IND(NewCFlag);
  67. }
  68. FRAGCOMMON2(BtRegFrag)
  69. {
  70. UTYPE bit = 1<<(op2&LMB);
  71. SET_CFLAG_IND(GET_VAL(pop1) & bit);
  72. }
  73. FRAGCOMMON2(BtsRegFrag)
  74. {
  75. DWORD NewCFlag;
  76. UTYPE bit = 1<<(op2&LMB);
  77. UTYPE op1;
  78. op1 = GET_VAL(pop1);
  79. NewCFlag = op1 & bit;
  80. // Intel docs indicate that we can safely overwrite all 2/4 bytes
  81. // when writing the value back out. (pg. 26/43)
  82. PUT_VAL(pop1, (op1|bit));
  83. SET_CFLAG_IND(NewCFlag);
  84. }
  85. FRAGCOMMON2(BtcRegFrag)
  86. {
  87. DWORD NewCFlag;
  88. UTYPE bit = 1<<(op2&LMB);
  89. UTYPE op1;
  90. op1 = GET_VAL(pop1);
  91. NewCFlag = op1 & bit;
  92. // Intel docs indicate that we can safely overwrite all 2/4 bytes
  93. // when writing the value back out. (pg. 26/43)
  94. PUT_VAL(pop1, (op1 ^ bit));
  95. SET_CFLAG_IND(NewCFlag);
  96. }
  97. FRAGCOMMON2(BtrRegFrag)
  98. {
  99. DWORD NewCFlag;
  100. UTYPE bit = 1<<(op2&LMB);
  101. UTYPE op1;
  102. op1 = GET_VAL(pop1);
  103. NewCFlag = op1 & bit;
  104. // Intel docs indicate that we can safely overwrite all 2/4 bytes
  105. // when writing the value back out. (pg. 26/43)
  106. PUT_VAL(pop1, (op1&(~bit)));
  107. SET_CFLAG_IND(NewCFlag);
  108. }
  109. FRAGCOMMON3(ShldFrag)
  110. {
  111. // pop1 = Base -- ptr to dest reg/mem
  112. // op2 = inBits -- value of register containing bits to shift into Base
  113. // op3 = count -- number of bits to shift
  114. DWORD NewCFlag;
  115. UTYPE Base;
  116. if (op3 == 0) {
  117. return; // nothing to do - nop with all flags preserved
  118. }
  119. op3 &= 0x1f; // make the count MOD 32 (now op3 = ShiftAmt)
  120. #if MSB == 0x8000
  121. if (op3 > 16) {
  122. // Bad parameters - *pop1 UNDEFINED!
  123. // - CF,OF,SF,ZF,AF,PF UNDEFINED!
  124. return;
  125. }
  126. #endif
  127. Base = GET_VAL(pop1);
  128. NewCFlag = Base & (1<<(LMB+1-op3)); // Get the new CF value
  129. Base <<= op3; // shift Base left
  130. op2 >>= LMB+1-op3; // shift the top op3 bits of op2 right
  131. Base |= op2; // merge the two together
  132. PUT_VAL(pop1, Base);
  133. SET_CFLAG_IND(NewCFlag);
  134. SET_ZFLAG(Base);
  135. SET_PFLAG(Base);
  136. SET_SFLAG(Base << (31-LMB));
  137. }
  138. FRAGCOMMON3(ShldNoFlagsFrag)
  139. {
  140. // pop1 = Base -- ptr to dest reg/mem
  141. // op2 = inBits -- value of register containing bits to shift into Base
  142. // op3 = count -- number of bits to shift
  143. UTYPE Base;
  144. if (op3 == 0) {
  145. return; // nothing to do - nop with all flags preserved
  146. }
  147. op3 &= 0x1f; // make the count MOD 32 (now op3 = ShiftAmt)
  148. #if MSB == 0x8000
  149. if (op3 > 16) {
  150. // Bad parameters - *pop1 UNDEFINED!
  151. // - CF,OF,SF,ZF,AF,PF UNDEFINED!
  152. return;
  153. }
  154. #endif
  155. Base = GET_VAL(pop1);
  156. Base <<= op3; // shift Base left
  157. op2 >>= LMB+1-op3; // shift the top op3 bits of op2 right
  158. Base |= op2; // merge the two together
  159. PUT_VAL(pop1, Base);
  160. }
  161. FRAGCOMMON3(ShrdFrag)
  162. {
  163. // pop1 = Base -- ptr to dest reg/mem
  164. // op2 = inBits -- value of register containing bits to shift into Base
  165. // op3 = count -- number of bits to shift
  166. DWORD NewCFlag;
  167. UTYPE Base;
  168. int i;
  169. if (op3 == 0) {
  170. return; // nothing to do - nop with all flags preserved
  171. }
  172. op3 &= 0x1f; // make the count MOD 32 (now op3 = ShiftAmt)
  173. #if MSB == 0x8000
  174. if (op3 > 16) {
  175. // Bad parameters - *pop1 UNDEFINED!
  176. // - CF,OF,SF,ZF,AF,PF UNDEFINED!
  177. return;
  178. }
  179. #endif
  180. Base = GET_VAL(pop1);
  181. NewCFlag = Base & (1<<(op3-1)); // Get the new CF value
  182. Base >>= op3; // shift Base right
  183. op2 <<= LMB+1-op3; // shift the low op3 bits of op2
  184. Base |= op2; // merge the two together
  185. PUT_VAL(pop1, Base);
  186. SET_CFLAG_IND(NewCFlag);
  187. SET_ZFLAG(Base);
  188. SET_PFLAG(Base);
  189. SET_SFLAG(Base << (31-LMB));
  190. }
  191. FRAGCOMMON3(ShrdNoFlagsFrag)
  192. {
  193. // pop1 = Base -- ptr to dest reg/mem
  194. // op2 = inBits -- value of register containing bits to shift into Base
  195. // op3 = count -- number of bits to shift
  196. UTYPE Base;
  197. int i;
  198. if (op3 == 0) {
  199. return; // nothing to do - nop with all flags preserved
  200. }
  201. op3 &= 0x1f; // make the count MOD 32 (now op3 = ShiftAmt)
  202. #if MSB == 0x8000
  203. if (op3 > 16) {
  204. // Bad parameters - *pop1 UNDEFINED!
  205. // - CF,OF,SF,ZF,AF,PF UNDEFINED!
  206. return;
  207. }
  208. #endif
  209. Base = GET_VAL(pop1);
  210. Base >>= op3; // shift Base right
  211. op2 <<= LMB+1-op3; // shift the low op3 bits of op2
  212. Base |= op2; // merge the two together
  213. PUT_VAL(pop1, Base);
  214. }
  215. FRAGCOMMON2(BsfFrag)
  216. {
  217. int i;
  218. if (op2 == 0) {
  219. // value is 0 - set ZFLAG and return
  220. SET_ZFLAG(0);
  221. // *pop1 = UNDEFINED
  222. return;
  223. }
  224. // scan from bit 0 forward, looking for the index of '1' bit
  225. for (i=0; (op2 & 1) == 0; ++i) {
  226. op2 >>= 1;
  227. }
  228. // write the index of the '1' bit and clear the ZFLAG
  229. PUT_VAL(pop1, i);
  230. SET_ZFLAG(op2);
  231. }
  232. FRAGCOMMON2(BsrFrag)
  233. {
  234. int i;
  235. if (op2 == 0) {
  236. // value is 0 - set ZFLAG and return
  237. SET_ZFLAG(0);
  238. // *pop1 = UNDEFINED
  239. return;
  240. }
  241. // scan from bit 31/15 downward, looking for the index of '1' bit
  242. for (i=LMB; (op2 & MSB) == 0; --i) {
  243. op2 <<= 1;
  244. }
  245. // write the index of the '1' bit and clear the ZFLAG
  246. PUT_VAL(pop1, i);
  247. SET_ZFLAG(op2);
  248. }
  249. FRAGCOMMON1(PopFrag)
  250. {
  251. POP_VAL(GET_VAL(pop1));
  252. }