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.

228 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. lock.c
  5. Abstract:
  6. 32bit instructions with the LOCK prefix
  7. Author:
  8. 15-Aug-1995 t-orig (Ori Gershony)
  9. Revision History:
  10. 24-Aug-1999 [askhalid] copied from 32-bit wx86 directory and make work for 64bit.
  11. 20-Sept-1999[barrybo] added FRAG2REF(LockCmpXchg8bFrag32, ULONGLONG)
  12. --*/
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include <stdio.h>
  18. #include "fragp.h"
  19. #include "lock.h"
  20. // Define a macro which calls the lock helper functions
  21. #define CALLLOCKHELPER0(fn) fn ## LockHelper ()
  22. #define CALLLOCKHELPER1(fn,a1) fn ## LockHelper (a1)
  23. #define CALLLOCKHELPER2(fn,a1,a2) fn ## LockHelper (a1,a2)
  24. #define CALLLOCKHELPER3(fn,a1,a2,a3) fn ## LockHelper (a1,a2,a3)
  25. #define CALLLOCKHELPER4(fn,a1,a2,a3,a4) fn ## LockHelper (a1,a2,a3,a4)
  26. // Now define 32bit MSB
  27. #define MSB 0x80000000
  28. #define SET_FLAGS_ADD SET_FLAGS_ADD32
  29. #define SET_FLAGS_SUB SET_FLAGS_SUB32
  30. #define SET_FLAGS_INC SET_FLAGS_INC32
  31. #define SET_FLAGS_DEC SET_FLAGS_DEC32
  32. FRAG2(LockAddFrag32, ULONG)
  33. {
  34. ULONG result, op1;
  35. result = CALLLOCKHELPER3(Add, &op1, pop1, op2);
  36. SET_FLAGS_ADD(result, op1, op2, MSB);
  37. }
  38. FRAG2(LockOrFrag32, ULONG)
  39. {
  40. ULONG result;
  41. result = CALLLOCKHELPER2(Or, pop1, op2);
  42. SET_PFLAG(result);
  43. SET_ZFLAG(result);
  44. SET_SFLAG(result);
  45. SET_CFLAG_OFF;
  46. SET_OFLAG_OFF;
  47. }
  48. FRAG2(LockAdcFrag32, ULONG)
  49. {
  50. ULONG result, op1;
  51. result = CALLLOCKHELPER4(Adc, &op1, pop1, op2, cpu->flag_cf);
  52. SET_FLAGS_ADD(result, op1, op2, MSB);
  53. }
  54. FRAG2(LockSbbFrag32, ULONG)
  55. {
  56. ULONG result, op1;
  57. result = CALLLOCKHELPER4(Sbb, &op1, pop1, op2, cpu->flag_cf);
  58. SET_FLAGS_SUB(result, op1, op2, MSB);
  59. }
  60. FRAG2(LockAndFrag32, ULONG)
  61. {
  62. ULONG result;
  63. result = CALLLOCKHELPER2(And, pop1, op2);
  64. SET_ZFLAG(result);
  65. SET_PFLAG(result);
  66. SET_SFLAG(result);
  67. SET_CFLAG_OFF;
  68. SET_OFLAG_OFF;
  69. }
  70. FRAG2(LockSubFrag32, ULONG)
  71. {
  72. ULONG result, op1;
  73. result = CALLLOCKHELPER3(Sub, &op1, pop1, op2);
  74. SET_FLAGS_SUB(result, op1, op2, MSB);
  75. }
  76. FRAG2(LockXorFrag32, ULONG)
  77. {
  78. ULONG result;
  79. result = CALLLOCKHELPER2(Xor, pop1, op2);
  80. SET_ZFLAG(result);
  81. SET_PFLAG(result);
  82. SET_SFLAG(result);
  83. SET_CFLAG_OFF;
  84. SET_OFLAG_OFF;
  85. }
  86. FRAG1(LockNotFrag32, ULONG)
  87. {
  88. CALLLOCKHELPER1(Not, pop1);
  89. }
  90. FRAG1(LockNegFrag32, ULONG)
  91. {
  92. ULONG result, op1;
  93. result = CALLLOCKHELPER2(Neg, &op1, pop1);
  94. SET_CFLAG_IND(result == 0);
  95. SET_ZFLAG(result);
  96. SET_PFLAG(result);
  97. SET_SFLAG(result);
  98. SET_OFLAG_IND(op1 & result & MSB);
  99. }
  100. FRAG1(LockIncFrag32, ULONG)
  101. {
  102. ULONG result, op1;
  103. result = CALLLOCKHELPER3(Add, &op1, pop1, 1);
  104. SET_FLAGS_INC(result, op1);
  105. }
  106. FRAG1(LockDecFrag32, ULONG)
  107. {
  108. ULONG result, op1;
  109. result = CALLLOCKHELPER3(Sub, &op1, pop1, 1);
  110. SET_FLAGS_DEC(result, op1);
  111. }
  112. FRAG2(LockBtsMemFrag32, ULONG)
  113. {
  114. ULONG bit = 1<<(op2&0x1f);
  115. pop1 += (op2 >> 5);
  116. SET_CFLAG_IND(CALLLOCKHELPER2(Bts, pop1, bit));
  117. }
  118. FRAG2(LockBtsRegFrag32, ULONG)
  119. {
  120. ULONG bit = 1<<(op2&0x1f);
  121. SET_CFLAG_IND(CALLLOCKHELPER2(Bts, pop1, bit));
  122. }
  123. FRAG2(LockBtrMemFrag32, ULONG)
  124. {
  125. ULONG bit = 1<<(op2&0x1f);
  126. pop1 += (op2 >> 5);
  127. SET_CFLAG_IND(CALLLOCKHELPER2(Btr, pop1, bit));
  128. }
  129. FRAG2(LockBtrRegFrag32, ULONG)
  130. {
  131. ULONG bit = 1<<(op2&0x1f);
  132. SET_CFLAG_IND(CALLLOCKHELPER2(Btr, pop1, bit));
  133. }
  134. FRAG2(LockBtcMemFrag32, ULONG)
  135. {
  136. ULONG bit = 1<<(op2&0x1f);
  137. pop1 += (op2 >> 5);
  138. SET_CFLAG_IND(CALLLOCKHELPER2(Btc, pop1, bit));
  139. }
  140. FRAG2(LockBtcRegFrag32, ULONG)
  141. {
  142. ULONG bit = 1<<(op2&0x1f);
  143. SET_CFLAG_IND(CALLLOCKHELPER2(Btc, pop1, bit));
  144. }
  145. FRAG2REF(LockXchgFrag32, ULONG)
  146. {
  147. CALLLOCKHELPER2(Xchg, pop1, pop2);
  148. }
  149. FRAG2REF(LockXaddFrag32, ULONG)
  150. {
  151. ULONG op1, op2;
  152. op2 = CALLLOCKHELPER3(Xadd, &op1, pop1, pop2);
  153. // op1 has the original value of dest (*pop1)
  154. // op2 has the result of the XADD
  155. // so, op2-op1 is the original value of src
  156. SET_FLAGS_ADD(op2, (op2-op1), op1, MSB);
  157. }
  158. FRAG2REF(LockCmpXchgFrag32, ULONG)
  159. {
  160. ULONG op1;
  161. ULONG Value = eax;
  162. SET_ZFLAG(CALLLOCKHELPER4(CmpXchg, &eax, pop1, pop2, &op1));
  163. SET_FLAGS_SUB(Value-op1, Value, op1, MSB);
  164. }
  165. FRAG2REF(LockCmpXchg8bFrag32, ULONGLONG)
  166. {
  167. ULONGLONG op1;
  168. ULONGLONG EdxEax;
  169. ULONGLONG EcxEbx;
  170. EdxEax = (((ULONGLONG)edx) << 32) | (ULONGLONG)eax;
  171. EcxEbx = (ULONGLONG)ecx << 32 | (ULONGLONG)ebx;
  172. SET_ZFLAG(CALLLOCKHELPER3(CmpXchg8b, &EdxEax, &EcxEbx, pop1));
  173. edx = (ULONG)(EdxEax >> 32);
  174. eax = (ULONG)EdxEax;
  175. }