Source code of Windows XP (NT5)
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.

413 lines
16 KiB

  1. /*++
  2. Copyright (c) 1995-2000 Microsoft Corporation
  3. Module Name:
  4. fragp.h
  5. Abstract:
  6. Private exports, defines for shared code fragments.
  7. Author:
  8. 12-Jun-1995 BarryBo, Created
  9. Revision History:
  10. --*/
  11. #include "cpumain.h"
  12. #ifndef FRAGP_H
  13. #define FRAGP_H
  14. #include "fraglib.h"
  15. #include "eflags.h"
  16. //
  17. // This function patches a call to pass the mips address corresponding to
  18. // intelAddr directly to the call fragments.
  19. //
  20. PULONG
  21. patchCallRoutine(
  22. IN PULONG intelAddr,
  23. IN PULONG patchAddr
  24. );
  25. //
  26. // Table mapping a byte to a 0 or 1, corresponding to the parity bit for
  27. // that byte.
  28. //
  29. extern const BYTE ParityBit[256];
  30. #if _ALPHA_
  31. // defined in fraginit.c, used in the Alpha code generator
  32. extern DWORD fByteInstructionsOK;
  33. #endif
  34. #ifdef MSCCPU
  35. #define eax cpu->GpRegs[GP_EAX].i4
  36. #define ebx cpu->GpRegs[GP_EBX].i4
  37. #define ecx cpu->GpRegs[GP_ECX].i4
  38. #define edx cpu->GpRegs[GP_EDX].i4
  39. #define esp cpu->GpRegs[GP_ESP].i4
  40. #define ebp cpu->GpRegs[GP_EBP].i4
  41. #define esi cpu->GpRegs[GP_ESI].i4
  42. #define edi cpu->GpRegs[GP_EDI].i4
  43. #define eip cpu->eipReg.i4
  44. #define eipTemp cpu->eipTempReg.i4
  45. #define ax cpu->GpRegs[GP_EAX].i2
  46. #define bx cpu->GpRegs[GP_EBX].i2
  47. #define cx cpu->GpRegs[GP_ECX].i2
  48. #define dx cpu->GpRegs[GP_EDX].i2
  49. #define sp cpu->GpRegs[GP_ESP].i2
  50. #define bp cpu->GpRegs[GP_EBP].i2
  51. #define si cpu->GpRegs[GP_ESI].i2
  52. #define di cpu->GpRegs[GP_EDI].i2
  53. #define al cpu->GpRegs[GP_EAX].i1
  54. #define bl cpu->GpRegs[GP_EBX].i1
  55. #define cl cpu->GpRegs[GP_ECX].i1
  56. #define dl cpu->GpRegs[GP_EDX].i1
  57. #define ah cpu->GpRegs[GP_EAX].hb
  58. #define bh cpu->GpRegs[GP_EBX].hb
  59. #define ch cpu->GpRegs[GP_ECX].hb
  60. #define dh cpu->GpRegs[GP_EDX].hb
  61. #define CS cpu->cs
  62. #define DS cpu->ds
  63. #define ES cpu->es
  64. #define SS cpu->ss
  65. #define FS cpu->fs
  66. #define GS cpu->gs
  67. #define CPUDATA CPUCONTEXT
  68. #define PCPUDATA PCPUCONTEXT
  69. #else //!MSCCPU
  70. #define eax cpu->GpRegs[GP_EAX].i4
  71. #define ebx cpu->GpRegs[GP_EBX].i4
  72. #define ecx cpu->GpRegs[GP_ECX].i4
  73. #define edx cpu->GpRegs[GP_EDX].i4
  74. #define esp cpu->GpRegs[GP_ESP].i4
  75. #define ebp cpu->GpRegs[GP_EBP].i4
  76. #define esi cpu->GpRegs[GP_ESI].i4
  77. #define edi cpu->GpRegs[GP_EDI].i4
  78. #define eip cpu->eipReg.i4
  79. #define eipTemp cpu->eipTempReg.i4
  80. #define ax cpu->GpRegs[GP_EAX].i2
  81. #define bx cpu->GpRegs[GP_EBX].i2
  82. #define cx cpu->GpRegs[GP_ECX].i2
  83. #define dx cpu->GpRegs[GP_EDX].i2
  84. #define sp cpu->GpRegs[GP_ESP].i2
  85. #define bp cpu->GpRegs[GP_EBP].i2
  86. #define si cpu->GpRegs[GP_ESI].i2
  87. #define di cpu->GpRegs[GP_EDI].i2
  88. #define al cpu->GpRegs[GP_EAX].i1
  89. #define bl cpu->GpRegs[GP_EBX].i1
  90. #define cl cpu->GpRegs[GP_ECX].i1
  91. #define dl cpu->GpRegs[GP_EDX].i1
  92. #define ah cpu->GpRegs[GP_EAX].hb
  93. #define bh cpu->GpRegs[GP_EBX].hb
  94. #define ch cpu->GpRegs[GP_ECX].hb
  95. #define dh cpu->GpRegs[GP_EDX].hb
  96. #define CS cpu->GpRegs[REG_CS].i2
  97. #define DS cpu->GpRegs[REG_DS].i2
  98. #define ES cpu->GpRegs[REG_ES].i2
  99. #define SS cpu->GpRegs[REG_SS].i2
  100. #define FS cpu->GpRegs[REG_FS].i2
  101. #define GS cpu->GpRegs[REG_GS].i2
  102. #define CPUDATA THREADSTATE
  103. #define PCPUDATA PTHREADSTATE
  104. #endif //!MSCCPU
  105. #define MSB32 0x80000000
  106. #define SET_FLAG(flag, b) flag = (DWORD)b
  107. #define SET_CFLAG(b) SET_FLAG(cpu->flag_cf, (b))
  108. #define SET_PFLAG(b) SET_FLAG(cpu->flag_pf, (b))
  109. #define SET_AUXFLAG(b) SET_FLAG(cpu->flag_aux,(b))
  110. #define SET_ZFLAG(b) SET_FLAG(cpu->flag_zf, (b))
  111. #define SET_SFLAG(b) SET_FLAG(cpu->flag_sf, (b))
  112. // SET_DFLAG is special
  113. #define SET_OFLAG(b) SET_FLAG(cpu->flag_of, (b))
  114. #define SET_TFLAG(b) SET_FLAG(cpu->flag_tf, (b))
  115. #define SET_RFLAG(b) //UNDONE: not used until 386 debug registers implemented
  116. #define AUX_VAL 0x10
  117. #define GET_AUXFLAG (cpu->flag_aux & AUX_VAL)
  118. #define SET_AUXFLAG_ON SET_AUXFLAG(AUX_VAL)
  119. #define SET_AUXFLAG_OFF SET_AUXFLAG(0x0)
  120. #define GET_OFLAG (cpu->flag_of & MSB32)
  121. #define GET_OFLAGZO (cpu->flag_of >> 31)
  122. #define SET_OFLAG_ON SET_OFLAG(MSB32)
  123. #define SET_OFLAG_OFF SET_OFLAG(0)
  124. #define SET_OFLAG_IND(b) SET_OFLAG(b ? MSB32 : 0)
  125. #define GET_CFLAG (cpu->flag_cf & MSB32)
  126. #define GET_CFLAGZO (cpu->flag_cf >> 31)
  127. #define SET_CFLAG_ON SET_CFLAG(MSB32)
  128. #define SET_CFLAG_OFF SET_CFLAG(0)
  129. #define SET_CFLAG_IND(b) SET_CFLAG(b ? MSB32 : 0)
  130. #define GET_SFLAG (cpu->flag_sf & MSB32)
  131. #define GET_SFLAGZO (cpu->flag_sf >> 31)
  132. #define SET_SFLAG_ON SET_SFLAG(MSB32)
  133. #define SET_SFLAG_OFF SET_SFLAG(0)
  134. #define SET_SFLAG_IND(b) SET_SFLAG(b ? MSB32 : 0)
  135. #define GET_PFLAG (ParityBit[cpu->flag_pf & 0xff])
  136. #define GET_BYTE(addr) (*(UNALIGNED unsigned char *)(addr))
  137. #define GET_SHORT(addr) (*(UNALIGNED unsigned short *)(addr))
  138. #define GET_LONG(addr) (*(UNALIGNED unsigned long *)(addr))
  139. #define PUT_BYTE(addr,dw) {GET_BYTE(addr)=dw;}
  140. #define PUT_SHORT(addr,dw) {GET_SHORT(addr)=dw;}
  141. #define PUT_LONG(addr,dw) {GET_LONG(addr)=dw;}
  142. typedef void (*pfnFrag0)(PCPUDATA);
  143. typedef void (*pfnFrag18)(PCPUDATA, BYTE *);
  144. typedef void (*pfnFrag116)(PCPUDATA, USHORT *);
  145. typedef void (*pfnFrag132)(PCPUDATA, DWORD *);
  146. typedef void (*pfnFrag28)(PCPUDATA, BYTE *, BYTE);
  147. typedef void (*pfnFrag216)(PCPUDATA, USHORT *, USHORT);
  148. typedef void (*pfnFrag232)(PCPUDATA, DWORD *, DWORD);
  149. typedef void (*pfnFrag38)(PCPUDATA, BYTE *, BYTE, BYTE);
  150. typedef void (*pfnFrag316)(PCPUDATA, USHORT *, USHORT, USHORT);
  151. typedef void (*pfnFrag332)(PCPUDATA, DWORD *, DWORD, DWORD);
  152. /*---------------------------------------------------------------------*/
  153. extern void CpupUnlockTCAndDoInterrupt(PTHREADSTATE cpu, int Interrupt);
  154. #define Int0() CpupUnlockTCAndDoInterrupt(cpu, 0) // Divide error
  155. #define Int3() CpupUnlockTCAndDoInterrupt(cpu, 3) // Breakpoint
  156. #define Int4() CpupUnlockTCAndDoInterrupt(cpu, 4) // Overflow
  157. #define Int5() CpupUnlockTCAndDoInterrupt(cpu, 5) // Bound check
  158. #define Int6() CpupUnlockTCAndDoInterrupt(cpu, 6) // Invalid opcode
  159. #define Int8() CpupUnlockTCAndDoInterrupt(cpu, 8) // Double fault
  160. #define Int13(sel) CpupUnlockTCAndDoInterrupt(cpu, 13) // General protection
  161. #define PRIVILEGED_INSTR Int13(0)
  162. #define BREAKPOINT_INSTR Int3()
  163. #define OVERFLOW_INSTR Int4()
  164. /*---------------------------------------------------------------------*/
  165. #define PUSH_LONG(dw) { \
  166. DWORD NewEsp = esp-4; \
  167. *(DWORD *)(NewEsp) = (DWORD)(dw); \
  168. esp=NewEsp; \
  169. }
  170. #define POP_LONG(dw) { \
  171. DWORD espTemp = esp; \
  172. (dw)=*(DWORD *)espTemp; \
  173. esp=espTemp+4; \
  174. }
  175. #define PUSH_SHORT(s) { \
  176. DWORD NewEsp = esp-2; \
  177. *(USHORT *)(NewEsp)=(USHORT)(s); \
  178. esp=NewEsp; \
  179. }
  180. #define POP_SHORT(s) { \
  181. DWORD espTemp = esp; \
  182. (s)=*(USHORT *)espTemp; \
  183. esp=espTemp+2; \
  184. }
  185. #define XCHG(t, r1, r2) { \
  186. t temp; \
  187. temp = r1; \
  188. r1=r2; \
  189. r2=temp; \
  190. }
  191. #define XCHG_MEM(t, m1, m2) { \
  192. t temp; \
  193. temp = *m1; \
  194. *m1 = *m2; \
  195. *m2 = temp; \
  196. }
  197. #define do_j_b(f) { \
  198. if (cpu->AdrPrefix) { \
  199. if (f) { \
  200. cpu->eipTempReg.i2+=(char)GET_BYTE(eipTemp+1)+2; \
  201. } else { \
  202. cpu->eipTempReg.i2+=2; \
  203. } \
  204. cpu->AdrPrefix = PREFIX_NONE; \
  205. } else { \
  206. if (f) { \
  207. eipTemp+=(char)GET_BYTE(eipTemp+1)+2; \
  208. } else { \
  209. eipTemp+=2; \
  210. } \
  211. } \
  212. }
  213. #define DO_J(f) { \
  214. if (cpu->AdrPrefix) { \
  215. if (f) { \
  216. cpu->eipTempReg.i2+=(STYPE)GET_VAL(eipTemp+1)+1+sizeof(UTYPE); \
  217. } else { \
  218. cpu->eipTempReg.i2+=1+sizeof(UTYPE); \
  219. } \
  220. cpu->AdrPrefix = PREFIX_NONE; \
  221. } else { \
  222. if (f) { \
  223. eipTemp+=(STYPE)GET_VAL(eipTemp+1)+1+sizeof(UTYPE); \
  224. } else { \
  225. eipTemp+=1+sizeof(UTYPE); \
  226. } \
  227. } \
  228. }
  229. #define SET_FLAGS_ADD32(r, op1, op2, msb) { \
  230. DWORD carry = (op1) ^ (op2) ^ (r); \
  231. /* next line is different for ADD/SUB */ \
  232. SET_OFLAG(~((op1) ^ (op2)) & ((op2) ^ (r))); \
  233. SET_CFLAG(carry ^ cpu->flag_of); \
  234. SET_ZFLAG((r)); \
  235. SET_SFLAG((r)); \
  236. SET_PFLAG((r)); \
  237. SET_AUXFLAG(carry); \
  238. }
  239. #define SET_FLAGS_ADD16(r, op1, op2, msb) { \
  240. DWORD carry = (op1) ^ (op2) ^ (r); \
  241. /* next line is different for ADD/SUB */ \
  242. SET_OFLAG((~((op1) ^ (op2)) & ((op2) ^ (r))) << 16); \
  243. SET_CFLAG((carry<<16) ^ cpu->flag_of); \
  244. SET_ZFLAG((r)); \
  245. SET_PFLAG((r)); \
  246. SET_SFLAG((r) << 16); \
  247. SET_AUXFLAG(carry); \
  248. }
  249. #define SET_FLAGS_ADD8(r, op1, op2, msb) { \
  250. DWORD carry = (op1) ^ (op2) ^ (r); \
  251. /* next line is different for ADD/SUB */ \
  252. SET_OFLAG((~((op1) ^ (op2)) & ((op2) ^ (r))) << 24); \
  253. SET_CFLAG((carry<<24) ^ cpu->flag_of); \
  254. SET_ZFLAG((r)); \
  255. SET_SFLAG((r) << 24); \
  256. SET_AUXFLAG(carry); \
  257. SET_PFLAG((r)); \
  258. }
  259. #define SET_FLAGS_SUB32(r, op1, op2, msb) { \
  260. DWORD carry = (op1) ^ (op2) ^ (r); \
  261. /* next line is different for ADD/SUB */ \
  262. SET_OFLAG(((op1) ^ (op2)) & ((op1) ^ (r))); \
  263. SET_CFLAG(carry ^ cpu->flag_of); \
  264. SET_ZFLAG((r)); \
  265. SET_SFLAG((r)); \
  266. SET_AUXFLAG(carry); \
  267. SET_PFLAG((r)); \
  268. }
  269. #define SET_FLAGS_SUB16(r, op1, op2, msb) { \
  270. DWORD carry = (op1) ^ (op2) ^ (r); \
  271. /* next line is different for ADD/SUB */ \
  272. SET_OFLAG((((op1) ^ (op2)) & ((op1) ^ (r))) << 16); \
  273. SET_CFLAG((carry<<16) ^ cpu->flag_of); \
  274. SET_ZFLAG((r)); \
  275. SET_SFLAG((r) << 16); \
  276. SET_AUXFLAG(carry); \
  277. SET_PFLAG((r)); \
  278. }
  279. #define SET_FLAGS_SUB8(r, op1, op2, msb) { \
  280. DWORD carry = (op1) ^ (op2) ^ (r); \
  281. /* next line is different for ADD/SUB */ \
  282. SET_OFLAG((((op1) ^ (op2)) & ((op1) ^ (r))) << 24); \
  283. SET_CFLAG((carry<<24) ^ cpu->flag_of); \
  284. SET_ZFLAG((r)); \
  285. SET_SFLAG((r) << 24); \
  286. SET_AUXFLAG(carry); \
  287. SET_PFLAG((r)); \
  288. }
  289. #define SET_FLAGS_INC32(r, op1) { \
  290. DWORD carry = (op1) ^ 1 ^ (r); \
  291. /* next line is different for INC/DEC */ \
  292. SET_OFLAG(~((op1) ^ 1) & (1 ^ (r))); \
  293. SET_ZFLAG((r)); \
  294. SET_SFLAG((r)); \
  295. SET_PFLAG((r)); \
  296. SET_AUXFLAG(carry); \
  297. }
  298. #define SET_FLAGS_INC16(r, op1) { \
  299. DWORD carry = (op1) ^ 1 ^ (r); \
  300. /* next line is different for INC/DEC */ \
  301. SET_OFLAG((~((op1) ^ 1) & (1 ^ (r))) << 16); \
  302. SET_ZFLAG((r)); \
  303. SET_PFLAG((r)); \
  304. SET_SFLAG((r) << 16); \
  305. SET_AUXFLAG(carry); \
  306. }
  307. #define SET_FLAGS_INC8(r, op1) { \
  308. DWORD carry = (op1) ^ 1 ^ (r); \
  309. /* next line is different for INC/DEC */ \
  310. SET_OFLAG((~((op1) ^ 1) & (1 ^ (r))) << 24); \
  311. SET_ZFLAG((r)); \
  312. SET_SFLAG((r) << 24); \
  313. SET_PFLAG((r)); \
  314. SET_AUXFLAG(carry); \
  315. }
  316. #define SET_FLAGS_DEC32(r, op1) { \
  317. DWORD carry = (op1) ^ 1 ^ (r); \
  318. /* next line is different for INC/DEC */ \
  319. SET_OFLAG(((op1) ^ 1) & ((op1) ^ (r))); \
  320. SET_ZFLAG((r)); \
  321. SET_SFLAG((r)); \
  322. SET_PFLAG((r)); \
  323. SET_AUXFLAG(carry); \
  324. }
  325. #define SET_FLAGS_DEC16(r, op1) { \
  326. DWORD carry = (op1) ^ 1 ^ (r); \
  327. /* next line is different for INC/DEC */ \
  328. SET_OFLAG((((op1) ^ 1) & ((op1) ^ (r))) << 16); \
  329. SET_ZFLAG((r)); \
  330. SET_SFLAG((r) << 16); \
  331. SET_PFLAG((r)); \
  332. SET_AUXFLAG(carry); \
  333. }
  334. #define SET_FLAGS_DEC8(r, op1) { \
  335. DWORD carry = (op1) ^ 1 ^ (r); \
  336. /* next line is different for INC/DEC */ \
  337. SET_OFLAG((((op1) ^ 1) & ((op1) ^ (r))) << 24); \
  338. SET_ZFLAG((r)); \
  339. SET_SFLAG((r) << 24); \
  340. SET_PFLAG((r)); \
  341. SET_AUXFLAG(carry); \
  342. }
  343. VOID CpuRaiseStatus( NTSTATUS Status );
  344. #endif //FRAGP_H