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.

217 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 1995-2000 Microsoft Corporation
  3. Module Name:
  4. shr1632.c
  5. Abstract:
  6. Instruction fragments with common (shared) WORD, and DWORD flavors
  7. (but not BYTE).
  8. Author:
  9. 12-Jun-1995 BarryBo
  10. Revision History:
  11. 24-Aug-1999 [askhalid] copied from 32-bit wx86 directory and make work for 64bit.
  12. --*/
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include "wx86.h"
  18. #include "wx86nt.h"
  19. #include "shr1632.h"
  20. FRAGCOMMON0(PushfFrag)
  21. {
  22. UTYPE dw;
  23. dw = ((GET_CFLAG) ? FLAG_CF : 0)
  24. | 2
  25. | ((GET_AUXFLAG) ? FLAG_AUX : 0) // The auxflag is special
  26. | ((GET_PFLAG) ? FLAG_PF : 0)
  27. | ((cpu->flag_zf) ? 0 : FLAG_ZF) // zf has inverse logic
  28. | ((GET_SFLAG) ? FLAG_SF : 0)
  29. | ((cpu->flag_tf) ? FLAG_TF : 0)
  30. | FLAG_IF
  31. | ((cpu->flag_df == -1) ? FLAG_DF : 0)
  32. | ((GET_OFLAG) ? FLAG_OF : 0)
  33. #if MSB==0x80000000
  34. | cpu->flag_ac
  35. | cpu->flag_id
  36. // VM and RF bits are both 0
  37. #endif
  38. ;
  39. PUSH_VAL(dw);
  40. }
  41. FRAGCOMMON0(PopfFrag)
  42. {
  43. UTYPE dw;
  44. POP_VAL(dw);
  45. // ignore: FLAG_NT, FLAG_RF, FLAG_VM, IOPL
  46. SET_CFLAG_IND (dw & FLAG_CF);
  47. cpu->flag_pf = (dw & FLAG_PF) ? 0 : 1; // pf is an index into the ParityBit[] array
  48. cpu->flag_aux= (dw & FLAG_AUX) ? AUX_VAL : 0;
  49. cpu->flag_zf = (dw & FLAG_ZF) ? 0 : 1; // zf has inverse logic
  50. SET_SFLAG_IND (dw & FLAG_SF);
  51. cpu->flag_tf = (dw & FLAG_TF) ? 1 : 0;
  52. cpu->flag_df = (dw & FLAG_DF) ? -1 : 1;
  53. SET_OFLAG_IND (dw & FLAG_OF);
  54. #if MSB==0x80000000
  55. cpu->flag_ac = (dw & FLAG_AC);
  56. cpu->flag_id = (dw & FLAG_ID);
  57. #endif
  58. }
  59. FRAGCOMMON0(PushAFrag)
  60. {
  61. // can't use PUSH_VAL() as ESP cannot be updated until after we're sure
  62. // things can't fault
  63. *(UTYPE *)(esp-sizeof(UTYPE)) = AREG;
  64. *(UTYPE *)(esp-2*sizeof(UTYPE)) = CREG;
  65. *(UTYPE *)(esp-3*sizeof(UTYPE)) = DREG;
  66. *(UTYPE *)(esp-4*sizeof(UTYPE)) = BREG;
  67. *(UTYPE *)(esp-5*sizeof(UTYPE)) = SPREG;
  68. *(UTYPE *)(esp-6*sizeof(UTYPE)) = BPREG;
  69. *(UTYPE *)(esp-7*sizeof(UTYPE)) = SIREG;
  70. *(UTYPE *)(esp-8*sizeof(UTYPE)) = DIREG;
  71. esp -= 8*sizeof(UTYPE);
  72. }
  73. FRAGCOMMON0(PopAFrag)
  74. {
  75. // can't use POP_VAL() as ESP cannot be updated untile after we're sure
  76. // things can't fault
  77. DIREG = *(UTYPE *)(esp);
  78. SIREG = *(UTYPE *)(esp+sizeof(UTYPE));
  79. BPREG = *(UTYPE *)(esp+2*sizeof(UTYPE));
  80. // ignore [E]SP register image on the stack
  81. BREG = *(UTYPE *)(esp+4*sizeof(UTYPE));
  82. DREG = *(UTYPE *)(esp+5*sizeof(UTYPE));
  83. CREG = *(UTYPE *)(esp+6*sizeof(UTYPE));
  84. AREG = *(UTYPE *)(esp+7*sizeof(UTYPE));
  85. esp += 8*sizeof(UTYPE);
  86. }
  87. FRAGCOMMON1IMM(PushFrag)
  88. {
  89. PUSH_VAL(op1);
  90. }
  91. FRAGCOMMON0(CwdFrag)
  92. {
  93. DREG = (AREG & MSB) ? (UTYPE)0xffffffff : 0;
  94. }
  95. FRAGCOMMON2(BoundFrag)
  96. {
  97. if ((op2 < GET_VAL(pop1)) ||
  98. (op2 > (GET_VAL( (ULONG)(ULONGLONG)(pop1) + sizeof(UTYPE))))) {
  99. Int5(); // raise BOUND exception
  100. }
  101. }
  102. FRAGCOMMON2IMM(EnterFrag)
  103. {
  104. BYTE level;
  105. DWORD frameptr;
  106. DWORD espTemp;
  107. level = (BYTE)(op1 % 32);
  108. espTemp = esp - sizeof(UTYPE);
  109. *(UTYPE *)(espTemp) = BPREG; // can't use PUSH_VAL because esp can't be changed
  110. frameptr = espTemp;
  111. if (level) {
  112. BYTE i;
  113. DWORD ebpTemp = ebp;
  114. for (i=1; i<= level-1; ++i) {
  115. ebpTemp -= sizeof(UTYPE);
  116. espTemp -= sizeof(UTYPE);
  117. *(UTYPE *)espTemp = (UTYPE)ebpTemp;
  118. }
  119. espTemp-=sizeof(UTYPE);
  120. *(DWORD *)espTemp = frameptr;
  121. }
  122. ebp = frameptr;
  123. esp = espTemp-op2;
  124. }
  125. FRAGCOMMON0(LeaveFrag)
  126. {
  127. DWORD espTemp;
  128. espTemp = ebp;
  129. BPREG = *(UTYPE *)espTemp;
  130. esp = espTemp + sizeof(UTYPE);
  131. }
  132. FRAGCOMMON2(LesFrag)
  133. {
  134. *pop1 = GET_VAL(op2); // pop1 is always a ptr to a register
  135. ES = GET_SHORT(op2+sizeof(UTYPE));
  136. //UNDONE: fault if segment register not loaded with correct value?
  137. }
  138. FRAGCOMMON2(LdsFrag)
  139. {
  140. *pop1 = GET_VAL(op2); // pop1 is always a ptr to a register
  141. DS = GET_SHORT(op2+sizeof(UTYPE));
  142. //UNDONE: fault if segment register not loaded with correct value?
  143. }
  144. FRAGCOMMON2(LssFrag)
  145. {
  146. *pop1 = GET_VAL(op2); // pop1 is always a ptr to a register
  147. SS = GET_SHORT(op2+sizeof(UTYPE));
  148. //UNDONE: fault if segment register not loaded with correct value?
  149. }
  150. FRAGCOMMON2(LfsFrag)
  151. {
  152. *pop1 = GET_VAL(op2); // pop1 is always a ptr to a register
  153. FS = GET_SHORT(op2+sizeof(UTYPE));
  154. //UNDONE: fault if segment register not loaded with correct value?
  155. //UNDONE: what about the selector base for FS?
  156. }
  157. FRAGCOMMON2(LgsFrag)
  158. {
  159. *pop1 = GET_VAL(op2); // pop1 is always a ptr to a register
  160. GS = GET_SHORT(op2+sizeof(UTYPE));
  161. //UNDONE: fault if segment register not loaded with correct value?
  162. }
  163. FRAGCOMMON2(LslFrag)
  164. {
  165. //
  166. // pop1 is a pointer to a register, so can use aligned code
  167. //
  168. op2 &= ~3; // mask off RPL bits
  169. if (op2 == KGDT_R3_CODE || // CS: selector
  170. op2 == KGDT_R3_DATA // DS:, SS:, ES: selector
  171. ) {
  172. *pop1 = (UTYPE)-1; // limit=0xffffffff
  173. SET_ZFLAG(0); // ZF=1
  174. } else if (op2 == KGDT_R3_TEB) {
  175. *pop1 = 0xfff; // limit=0xfff (1 x86 page)
  176. SET_ZFLAG(0); // ZF=1
  177. } else {
  178. SET_ZFLAG(1); // ZF=0
  179. }
  180. }
  181. FRAGCOMMON2(LarFrag)
  182. {
  183. //
  184. // pop1 is a pointer to a register, so can use aligned code
  185. //
  186. op2 &= ~3; // mask off RPL bits
  187. if (op2 == KGDT_R3_CODE) {
  188. *pop1 = (UTYPE)0xcffb00;
  189. SET_ZFLAG(0); // ZF=1
  190. } else if (op2 == KGDT_R3_DATA) {
  191. *pop1 = (UTYPE)0xcff300;
  192. SET_ZFLAG(0); // ZF=1
  193. } else if (op2 == KGDT_R3_TEB) {
  194. *pop1 = (UTYPE)0x40f300;
  195. SET_ZFLAG(0); // ZF=1
  196. } else {
  197. SET_ZFLAG(1); // ZF=0
  198. }
  199. }