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.

697 lines
15 KiB

  1. /*++
  2. Copyright (c) 1996-1998 Microsoft Corporation
  3. Module Name:
  4. miscfns.c
  5. Abstract:
  6. Miscellaneous instuctions
  7. Author:
  8. 29-Jun-1995 BarryBo
  9. Revision History:
  10. --*/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include "wx86.h"
  17. #include "cpuassrt.h"
  18. #include "threadst.h"
  19. #include "instr.h"
  20. #include "decoderp.h"
  21. ASSERTNAME;
  22. // table used by ProcessPrefixes
  23. pfnDispatchInstruction *DispatchTables[4] = { Dispatch32, Dispatch16, LockDispatch32, LockDispatch16 };
  24. // ---------------- single-byte functions -------------------------------
  25. DISPATCH(ProcessPrefixes)
  26. {
  27. int DataPrefix = 0;
  28. int LockPrefix = 0;
  29. int cbInstr = 0;
  30. for (;;) {
  31. switch (*(PBYTE)(eipTemp)) {
  32. case 0x64: // fs:
  33. Instr->FsOverride = TRUE;
  34. break;
  35. case 0xf3: // repz
  36. State->RepPrefix = PREFIX_REPZ;
  37. break;
  38. case 0xf2: // repnz
  39. State->RepPrefix = PREFIX_REPNZ;
  40. break;
  41. case 0xf0: // lock
  42. LockPrefix = 2; // The lock tables are in locations 2 and 3 DispatchTables
  43. break;
  44. case 0x2e: // cs:
  45. case 0x36: // ss:
  46. case 0x3e: // ds:
  47. case 0x26: // es:
  48. case 0x65: // gs:
  49. Instr->FsOverride = FALSE;
  50. break;
  51. case 0x66: // data
  52. DataPrefix = 1;
  53. break;
  54. case 0x67: // adr
  55. State->AdrPrefix=TRUE;
  56. break;
  57. default:
  58. // No more prefixes found. Set up dispatch tables based on
  59. // the prefixes seen.
  60. // Decode and execute the actual instruction
  61. ((DispatchTables[DataPrefix+LockPrefix])[GET_BYTE(eipTemp)])(State, Instr);
  62. // Adjust the Intel instruction size by the number of prefixes
  63. Instr->Size += cbInstr;
  64. #if DBG
  65. // Ensure that if we saw an ADR: prefix, the decoder had code
  66. // to handle the prefix. In the checked build, all functions which
  67. // handle the ADR: prefix clear State->AdrPrefix.
  68. if (State->AdrPrefix) {
  69. LOGPRINT((TRACELOG, "CPU Decoder: An unsupported instruction had an ADR: prefix.\r\n"
  70. "Instruction Address = 0x%x. Ignoring ADR: - this address may be data\r\n",
  71. Instr->IntelAddress
  72. ));
  73. }
  74. #endif
  75. State->AdrPrefix = FALSE;
  76. // return to the decoder
  77. return;
  78. }
  79. eipTemp++;
  80. cbInstr++;
  81. }
  82. }
  83. DISPATCH(bad)
  84. {
  85. BAD_INSTR;
  86. }
  87. DISPATCH(privileged)
  88. {
  89. PRIVILEGED_INSTR;
  90. }
  91. DISPATCH(push_es)
  92. {
  93. Instr->Operation = OP_PushEs;
  94. }
  95. DISPATCH(pop_es)
  96. {
  97. Instr->Operation = OP_PopEs;
  98. }
  99. DISPATCH(push_cs)
  100. {
  101. Instr->Operation = OP_PushCs;
  102. }
  103. DISPATCH(aas)
  104. {
  105. Instr->Operation = OP_Aas;
  106. }
  107. DISPATCH(push_ss)
  108. {
  109. Instr->Operation = OP_PushSs;
  110. }
  111. DISPATCH(pop_ss)
  112. {
  113. Instr->Operation = OP_PopSs;
  114. }
  115. DISPATCH(push_ds)
  116. {
  117. Instr->Operation = OP_PushDs;
  118. }
  119. DISPATCH(pop_ds)
  120. {
  121. Instr->Operation = OP_PopDs;
  122. }
  123. DISPATCH(daa)
  124. {
  125. Instr->Operation = OP_Daa;
  126. }
  127. DISPATCH(das)
  128. {
  129. Instr->Operation = OP_Das;
  130. }
  131. DISPATCH(aaa)
  132. {
  133. Instr->Operation = OP_Aaa;
  134. }
  135. DISPATCH(aad_ib)
  136. {
  137. Instr->Operation = OP_Aad;
  138. Instr->Operand1.Type = OPND_IMM;
  139. Instr->Operand1.Immed = GET_BYTE(eipTemp+1);
  140. Instr->Size = 2;
  141. }
  142. DISPATCH(imul_rw_m_iw16) // reg16 = rm16 * immediate word
  143. {
  144. int cbInstr = mod_rm_reg16(State, &Instr->Operand2, &Instr->Operand1);
  145. Instr->Operation = OP_Imul3Arg16;
  146. DEREF16(Instr->Operand2);
  147. Instr->Operand3.Type = OPND_IMM;
  148. Instr->Operand3.Immed = GET_SHORT(eipTemp+1+cbInstr);
  149. Instr->Size = 3+cbInstr;
  150. }
  151. DISPATCH(imul_rw_m_iw32)
  152. {
  153. int cbInstr = mod_rm_reg32(State, &Instr->Operand2, &Instr->Operand1);
  154. Instr->Operation = OP_Imul3Arg32;
  155. DEREF32(Instr->Operand2);
  156. Instr->Operand3.Type = OPND_IMM;
  157. Instr->Operand3.Immed = GET_LONG(eipTemp+1+cbInstr);
  158. Instr->Size = 5+cbInstr;
  159. }
  160. DISPATCH(imul_rw_m_ib16) // reg16 = rm16 * sign-extended immediate byte
  161. {
  162. int cbInstr = mod_rm_reg16(State, &Instr->Operand2, &Instr->Operand1);
  163. Instr->Operation = OP_Imul3Arg16;
  164. DEREF16(Instr->Operand2);
  165. Instr->Operand3.Type = OPND_IMM;
  166. Instr->Operand3.Immed = (DWORD)(short)(char)GET_BYTE(eipTemp+1+cbInstr);
  167. Instr->Size = 2+cbInstr;
  168. }
  169. DISPATCH(imul_rw_m_ib32) // reg32 = rm32 * sign-extended immediate byte
  170. {
  171. int cbInstr = mod_rm_reg32(State, &Instr->Operand2, &Instr->Operand1);
  172. Instr->Operation = OP_Imul3Arg32;
  173. DEREF32(Instr->Operand2);
  174. Instr->Operand3.Type = OPND_IMM;
  175. Instr->Operand3.Immed = (DWORD)(long)(char)GET_BYTE(eipTemp+1+cbInstr);
  176. Instr->Size = 2+cbInstr;
  177. }
  178. DISPATCH(mov_mw_seg)
  179. {
  180. int cbInstr = mod_rm_reg16(State, &Instr->Operand1, NULL);
  181. get_segreg(State, &Instr->Operand2);
  182. Instr->Operation = OP_Mov16;
  183. Instr->Size = cbInstr+1;
  184. }
  185. DISPATCH(mov_seg_mw)
  186. {
  187. int cbInstr = mod_rm_reg16(State, &Instr->Operand2, NULL);
  188. get_segreg(State, &Instr->Operand1);
  189. Instr->Operation = OP_Mov16;
  190. DEREF16(Instr->Operand2);
  191. CPUASSERT(Instr->Operand1.Type == OPND_REGVALUE);
  192. Instr->Operand1.Type = OPND_REGREF;
  193. Instr->Size = cbInstr+1;
  194. }
  195. DISPATCH(nop)
  196. {
  197. Instr->Operation = OP_Nop;
  198. }
  199. DISPATCH(call_md)
  200. {
  201. Instr->Operation = OP_CTRL_UNCOND_Callf;
  202. Instr->Operand1.Type = OPND_IMM;
  203. Instr->Operand1.Immed = eipTemp+1;
  204. Instr->Operand2.Type = OPND_IMM;
  205. Instr->Operand2.Immed = eipTemp+sizeof(ULONG)+sizeof(USHORT)+1;
  206. Instr->Size = sizeof(ULONG)+sizeof(USHORT)+1;
  207. }
  208. DISPATCH(sahf)
  209. {
  210. Instr->Operation = OP_Sahf;
  211. }
  212. DISPATCH(lahf)
  213. {
  214. Instr->Operation = OP_Lahf;
  215. }
  216. DISPATCH(mov_ah_ib)
  217. {
  218. Instr->Operation = OP_Mov8;
  219. Instr->Operand1.Type = OPND_REGREF;
  220. Instr->Operand1.Reg = GP_AH;
  221. Instr->Operand2.Type = OPND_IMM;
  222. Instr->Operand2.Immed = GET_BYTE(eipTemp+1);
  223. Instr->Size = 2;
  224. }
  225. DISPATCH(mov_ch_ib)
  226. {
  227. Instr->Operation = OP_Mov8;
  228. Instr->Operand1.Type = OPND_REGREF;
  229. Instr->Operand1.Reg = GP_CH;
  230. Instr->Operand2.Type = OPND_IMM;
  231. Instr->Operand2.Immed = GET_BYTE(eipTemp+1);
  232. Instr->Size = 2;
  233. }
  234. DISPATCH(mov_dh_ib)
  235. {
  236. Instr->Operation = OP_Mov8;
  237. Instr->Operand1.Type = OPND_REGREF;
  238. Instr->Operand1.Reg = GP_DH;
  239. Instr->Operand2.Type = OPND_IMM;
  240. Instr->Operand2.Immed = GET_BYTE(eipTemp+1);
  241. Instr->Size = 2;
  242. }
  243. DISPATCH(mov_bh_ib)
  244. {
  245. Instr->Operation = OP_Mov8;
  246. Instr->Operand1.Type = OPND_REGREF;
  247. Instr->Operand1.Reg = GP_BH;
  248. Instr->Operand2.Type = OPND_IMM;
  249. Instr->Operand2.Immed = GET_BYTE(eipTemp+1);
  250. Instr->Size = 2;
  251. }
  252. DISPATCH(int3)
  253. {
  254. Instr->Operation = OP_Int;
  255. }
  256. DISPATCH(int_ib)
  257. {
  258. Instr->Operation = OP_Int;
  259. Instr->Size = 2;
  260. }
  261. DISPATCH(into)
  262. {
  263. Instr->Operation = OP_IntO;
  264. }
  265. DISPATCH(iret)
  266. {
  267. Instr->Operation = OP_CTRL_INDIR_IRet;
  268. }
  269. DISPATCH(aam_ib)
  270. {
  271. Instr->Operation = OP_Aam;
  272. Instr->Operand1.Type = OPND_IMM;
  273. Instr->Operand1.Immed = GET_BYTE(eipTemp+1);
  274. Instr->Size = 2;
  275. }
  276. DISPATCH(xlat)
  277. {
  278. Instr->Operation = OP_Xlat;
  279. }
  280. DISPATCH(jmpf_md)
  281. {
  282. Instr->Operation = OP_CTRL_UNCOND_Jmpf;
  283. Instr->Operand1.Type = OPND_IMM;
  284. Instr->Operand1.Immed = eipTemp+1;
  285. Instr->Size = 7;
  286. }
  287. DISPATCH(jmp_jb)
  288. {
  289. Instr->Operand1.Type = OPND_NOCODEGEN;
  290. if (State->AdrPrefix) {
  291. Instr->Operand1.Immed = MAKELONG((short)(char)GET_BYTE(eipTemp+1)+2+(short)LOWORD(eipTemp), HIWORD(eipTemp));
  292. #if DBG
  293. State->AdrPrefix = FALSE;
  294. #endif
  295. } else {
  296. Instr->Operand1.Immed = (DWORD)(long)(char)GET_BYTE(eipTemp+1)+2+eipTemp;
  297. }
  298. if (Instr->Operand1.Immed > eipTemp) {
  299. Instr->Operation = OP_CTRL_UNCOND_JmpFwd;
  300. } else {
  301. Instr->Operation = OP_CTRL_UNCOND_Jmp;
  302. }
  303. Instr->Size = 2;
  304. }
  305. DISPATCH(cmc)
  306. {
  307. Instr->Operation = OP_Cmc;
  308. }
  309. DISPATCH(clc)
  310. {
  311. Instr->Operation = OP_Clc;
  312. }
  313. DISPATCH(stc)
  314. {
  315. Instr->Operation = OP_Stc;
  316. }
  317. DISPATCH(cld)
  318. {
  319. Instr->Operation = OP_Cld;
  320. }
  321. DISPATCH(std)
  322. {
  323. Instr->Operation = OP_Std;
  324. }
  325. DISPATCH(GROUP_4)
  326. {
  327. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  328. BYTE g = GET_BYTE(eipTemp+1);
  329. switch ((g >> 3) & 0x07) {
  330. case 0: // inc modrmB
  331. Instr->Operation = OP_Inc8;
  332. Instr->Size = 1+cbInstr;
  333. break;
  334. case 1: // dec modrmB
  335. Instr->Operation = OP_Dec8;
  336. Instr->Size = 1+cbInstr;
  337. break;
  338. default:
  339. BAD_INSTR;
  340. }
  341. }
  342. //-------- double-byte functions -----------------------------------------------
  343. DISPATCH(GROUP_6)
  344. {
  345. BYTE g = GET_BYTE(eipTemp+1);
  346. int cbInstr;
  347. switch ((g >> 3) & 0x07) {
  348. case 0: // sldt modrmw
  349. case 1: // str modrmw
  350. case 2: // lldt modrmw
  351. case 3: // ltr modrmw
  352. PRIVILEGED_INSTR;
  353. break;
  354. case 4: // verr modrmw
  355. cbInstr = mod_rm_reg16(State, &Instr->Operand1, NULL);
  356. Instr->Operation = OP_Verr;
  357. Instr->Size = 2+cbInstr;
  358. break;
  359. case 5: // verw modrmw
  360. cbInstr = mod_rm_reg16(State, &Instr->Operand1, NULL);
  361. Instr->Operation = OP_Verw;
  362. Instr->Size = 2+cbInstr;
  363. break;
  364. default:
  365. BAD_INSTR; // bad
  366. }
  367. }
  368. DISPATCH(GROUP_7)
  369. {
  370. BYTE g = GET_BYTE(eipTemp+1);
  371. int cbInstr;
  372. switch ((g >> 3) & 0x07) {
  373. case 0: // sgdt modrmw
  374. case 1: // sidt modrmw
  375. case 2: // lgdt modrmw
  376. case 3: // lidt modrmw
  377. case 6: // lmsw modrmw
  378. PRIVILEGED_INSTR;
  379. break;
  380. case 4: // smsw modrmw
  381. cbInstr = mod_rm_reg16(State, &Instr->Operand1, NULL);
  382. Instr->Operation = OP_Smsw;
  383. Instr->Size = 2+cbInstr;
  384. break;
  385. case 5: // bad
  386. case 7: // bad
  387. BAD_INSTR;
  388. }
  389. }
  390. DISPATCH(seto_modrmb)
  391. {
  392. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  393. Instr->Operation = OP_Seto;
  394. Instr->Size = 2+cbInstr;
  395. }
  396. DISPATCH(setno_modrmb)
  397. {
  398. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  399. Instr->Operation = OP_Setno;
  400. Instr->Size = 2+cbInstr;
  401. }
  402. DISPATCH(setb_modrmb)
  403. {
  404. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  405. Instr->Operation = OP_Setb;
  406. Instr->Size = 2+cbInstr;
  407. }
  408. DISPATCH(setae_modrmb)
  409. {
  410. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  411. Instr->Operation = OP_Setae;
  412. Instr->Size = 2+cbInstr;
  413. }
  414. DISPATCH(sete_modrmb)
  415. {
  416. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  417. Instr->Operation = OP_Sete;
  418. Instr->Size = 2+cbInstr;
  419. }
  420. DISPATCH(setne_modrmb)
  421. {
  422. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  423. Instr->Operation = OP_Setne;
  424. Instr->Size = 2+cbInstr;
  425. }
  426. DISPATCH(setbe_modrmb)
  427. {
  428. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  429. Instr->Operation = OP_Setbe;
  430. Instr->Size = 2+cbInstr;
  431. }
  432. DISPATCH(seta_modrmb)
  433. {
  434. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  435. Instr->Operation = OP_Seta;
  436. Instr->Size = 2+cbInstr;
  437. }
  438. DISPATCH(sets_modrmb)
  439. {
  440. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  441. Instr->Operation = OP_Sets;
  442. Instr->Size = 2+cbInstr;
  443. }
  444. DISPATCH(setns_modrmb)
  445. {
  446. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  447. Instr->Operation = OP_Setns;
  448. Instr->Size = 2+cbInstr;
  449. }
  450. DISPATCH(setp_modrmb)
  451. {
  452. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  453. Instr->Operation = OP_Setp;
  454. Instr->Size = 2+cbInstr;
  455. }
  456. DISPATCH(setnp_modrmb)
  457. {
  458. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  459. Instr->Operation = OP_Setnp;
  460. Instr->Size = 2+cbInstr;
  461. }
  462. DISPATCH(setl_modrmb)
  463. {
  464. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  465. Instr->Operation = OP_Setl;
  466. Instr->Size = 2+cbInstr;
  467. }
  468. DISPATCH(setge_modrmb)
  469. {
  470. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  471. Instr->Operation = OP_Setge;
  472. Instr->Size = 2+cbInstr;
  473. }
  474. DISPATCH(setle_modrmb)
  475. {
  476. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  477. Instr->Operation = OP_Setle;
  478. Instr->Size = 2+cbInstr;
  479. }
  480. DISPATCH(setg_modrmb)
  481. {
  482. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  483. Instr->Operation = OP_Setg;
  484. Instr->Size = 2+cbInstr;
  485. }
  486. DISPATCH(push_fs)
  487. {
  488. Instr->Operation = OP_PushFs;
  489. Instr->Size = 2;
  490. }
  491. DISPATCH(pop_fs)
  492. {
  493. Instr->Operation = OP_PopFs;
  494. Instr->Size = 2;
  495. }
  496. DISPATCH(push_gs)
  497. {
  498. Instr->Operation = OP_PushGs;
  499. Instr->Size = 2;
  500. }
  501. DISPATCH(pop_gs)
  502. {
  503. Instr->Operation = OP_PopGs;
  504. Instr->Size = 2;
  505. }
  506. DISPATCH(imul_regw_modrmw16) // reg16 = reg16 * mod/rm
  507. {
  508. int cbInstr = mod_rm_reg16(State, &Instr->Operand2, &Instr->Operand1);
  509. Instr->Operation = OP_Imul16;
  510. DEREF32(Instr->Operand2);
  511. Instr->Size = 2+cbInstr;
  512. }
  513. DISPATCH(imul_regw_modrmw32) // reg32 = reg32 * mod/rm
  514. {
  515. int cbInstr = mod_rm_reg32(State, &Instr->Operand2, &Instr->Operand1);
  516. Instr->Operation = OP_Imul32;
  517. DEREF32(Instr->Operand2);
  518. Instr->Size = 2+cbInstr;
  519. }
  520. DISPATCH(movzx_regw_modrmw)
  521. {
  522. int cbInstr = mod_rm_reg16(State, &Instr->Operand1, NULL);
  523. DEREF16(Instr->Operand1);
  524. Instr->Operation = OP_Movzx16To32;
  525. Instr->Operand2.Type = OPND_NOCODEGEN;
  526. Instr->Operand2.Reg = get_reg32(State);
  527. Instr->Size = 2+cbInstr;
  528. }
  529. DISPATCH(movsx_regw_modrmw)
  530. {
  531. int cbInstr = mod_rm_reg16(State, &Instr->Operand1, NULL);
  532. DEREF16(Instr->Operand1);
  533. Instr->Operation = OP_Movsx16To32;
  534. Instr->Operand2.Type = OPND_NOCODEGEN;
  535. Instr->Operand2.Reg = get_reg32(State);
  536. Instr->Size = 2+cbInstr;
  537. }
  538. DISPATCH(wait)
  539. {
  540. Instr->Operation = OP_Wait;
  541. }
  542. DISPATCH(bswap_eax)
  543. {
  544. Instr->Operation = OP_Bswap32;
  545. Instr->Operand1.Type = OPND_REGREF;
  546. Instr->Operand1.Reg = GP_EAX;
  547. Instr->Size = 2;
  548. }
  549. DISPATCH(bswap_ebx)
  550. {
  551. Instr->Operation = OP_Bswap32;
  552. Instr->Operand1.Type = OPND_REGREF;
  553. Instr->Operand1.Reg = GP_EBX;
  554. Instr->Size = 2;
  555. }
  556. DISPATCH(bswap_ecx)
  557. {
  558. Instr->Operation = OP_Bswap32;
  559. Instr->Operand1.Type = OPND_REGREF;
  560. Instr->Operand1.Reg = GP_ECX;
  561. Instr->Size = 2;
  562. }
  563. DISPATCH(bswap_edx)
  564. {
  565. Instr->Operation = OP_Bswap32;
  566. Instr->Operand1.Type = OPND_REGREF;
  567. Instr->Operand1.Reg = GP_EDX;
  568. Instr->Size = 2;
  569. }
  570. DISPATCH(bswap_esp)
  571. {
  572. Instr->Operation = OP_Bswap32;
  573. Instr->Operand1.Type = OPND_REGREF;
  574. Instr->Operand1.Reg = GP_ESP;
  575. Instr->Size = 2;
  576. }
  577. DISPATCH(bswap_ebp)
  578. {
  579. Instr->Operation = OP_Bswap32;
  580. Instr->Operand1.Type = OPND_REGREF;
  581. Instr->Operand1.Reg = GP_EBP;
  582. Instr->Size = 2;
  583. }
  584. DISPATCH(bswap_esi)
  585. {
  586. Instr->Operation = OP_Bswap32;
  587. Instr->Operand1.Type = OPND_REGREF;
  588. Instr->Operand1.Reg = GP_ESI;
  589. Instr->Size = 2;
  590. }
  591. DISPATCH(bswap_edi)
  592. {
  593. Instr->Operation = OP_Bswap32;
  594. Instr->Operand1.Type = OPND_REGREF;
  595. Instr->Operand1.Reg = GP_EDI;
  596. Instr->Size = 2;
  597. }
  598. DISPATCH(arpl)
  599. {
  600. int cbInstr = mod_rm_reg16(State, &Instr->Operand1, &Instr->Operand2);
  601. Instr->Operation = OP_Arpl;
  602. CPUASSERT(Instr->Operand2.Type == OPND_REGREF);
  603. Instr->Operand2.Type = OPND_REGVALUE;
  604. Instr->Size = 1+cbInstr;
  605. }
  606. DISPATCH(cpuid)
  607. {
  608. Instr->Operation = OP_CPUID;
  609. Instr->Size = 2;
  610. }
  611. DISPATCH(rdtsc)
  612. {
  613. Instr->Operation = OP_Rdtsc;
  614. Instr->Size = 2;
  615. }
  616. DISPATCH(cmpxchg8b)
  617. {
  618. int cbInstr = mod_rm_reg32(State, &Instr->Operand1, &Instr->Operand2);
  619. Instr->Operation = OP_CMPXCHG8B;
  620. Instr->Size = 2+cbInstr;
  621. }
  622. DISPATCH(LOCKcmpxchg8b)
  623. {
  624. int cbInstr = mod_rm_reg32(State, &Instr->Operand1, &Instr->Operand2);
  625. Instr->Operation = OP_SynchLockCMPXCHG8B;
  626. Instr->Size = 2+cbInstr;
  627. }